[PATCH 12/13] powerpc/fsl_rio: apply changes for RIO spec rev 3

2016-07-21 Thread Alexandre Bounine
- Remove check for parallel PHY
- Set LP-Serial Register Map type

Signed-off-by: Alexandre Bounine 
Cc: Matt Porter 
Cc: Benjamin Herrenschmidt 
Cc: Michael Ellerman 
Cc: Andre van Herk 
Cc: Barry Wood 
Cc: linux-ker...@vger.kernel.org
Cc: linuxppc-dev@lists.ozlabs.org
---
 arch/powerpc/sysdev/fsl_rio.c |   12 ++--
 1 files changed, 2 insertions(+), 10 deletions(-)

diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c
index 1958838..ee5b9f1 100644
--- a/arch/powerpc/sysdev/fsl_rio.c
+++ b/arch/powerpc/sysdev/fsl_rio.c
@@ -643,19 +643,11 @@ int fsl_rio_setup(struct platform_device *dev)
port->ops = ops;
port->priv = priv;
port->phys_efptr = 0x100;
+   port->phys_rmap = 1;
priv->regs_win = rio_regs_win;
 
-   /* Probe the master port phy type */
ccsr = in_be32(priv->regs_win + RIO_CCSR + i*0x20);
-   port->phy_type = (ccsr & 1) ? RIO_PHY_SERIAL : RIO_PHY_PARALLEL;
-   if (port->phy_type == RIO_PHY_PARALLEL) {
-   dev_err(&dev->dev, "RIO: Parallel PHY type, unsupported 
port type!\n");
-   release_resource(&port->iores);
-   kfree(priv);
-   kfree(port);
-   continue;
-   }
-   dev_info(&dev->dev, "RapidIO PHY type: Serial\n");
+
/* Checking the port training status */
if (in_be32((priv->regs_win + RIO_ESCSR + i*0x20)) & 1) {
dev_err(&dev->dev, "Port %d is not ready. "
-- 
1.7.8.4

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH 10/13] rapidio: change inbound window size type to u64

2016-07-21 Thread Alexandre Bounine
Current definition of map_inb() mport operations callback uses u32 type to
specify required inbound window (IBW) size. This is limiting factor
because existing hardware - tsi721 and fsl_rio, both support IBW size
up to 16GB.

Changing type of size parameter to u64 to allow IBW size configurations
larger than 4GB.

Signed-off-by: Alexandre Bounine 
Cc: Matt Porter 
Cc: Benjamin Herrenschmidt 
Cc: Michael Ellerman 
Cc: Andre van Herk 
Cc: Barry Wood 
Cc: linux-ker...@vger.kernel.org
Cc: linuxppc-dev@lists.ozlabs.org
---
 arch/powerpc/sysdev/fsl_rio.c|4 ++--
 drivers/rapidio/devices/tsi721.c |   14 +-
 include/linux/rio.h  |2 +-
 3 files changed, 12 insertions(+), 8 deletions(-)

diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c
index f5bf38b9..1958838 100644
--- a/arch/powerpc/sysdev/fsl_rio.c
+++ b/arch/powerpc/sysdev/fsl_rio.c
@@ -289,7 +289,7 @@ static void fsl_rio_inbound_mem_init(struct rio_priv *priv)
 }
 
 int fsl_map_inb_mem(struct rio_mport *mport, dma_addr_t lstart,
-   u64 rstart, u32 size, u32 flags)
+   u64 rstart, u64 size, u32 flags)
 {
struct rio_priv *priv = mport->priv;
u32 base_size;
@@ -298,7 +298,7 @@ int fsl_map_inb_mem(struct rio_mport *mport, dma_addr_t 
lstart,
u32 riwar;
int i;
 
-   if ((size & (size - 1)) != 0)
+   if ((size & (size - 1)) != 0 || size > 0x4UL)
return -EINVAL;
 
base_size_log = ilog2(size);
diff --git a/drivers/rapidio/devices/tsi721.c b/drivers/rapidio/devices/tsi721.c
index 8e07cd5..53daf63 100644
--- a/drivers/rapidio/devices/tsi721.c
+++ b/drivers/rapidio/devices/tsi721.c
@@ -1090,7 +1090,7 @@ static void tsi721_init_pc2sr_mapping(struct 
tsi721_device *priv)
  * from rstart to lstart.
  */
 static int tsi721_rio_map_inb_mem(struct rio_mport *mport, dma_addr_t lstart,
-   u64 rstart, u32 size, u32 flags)
+   u64 rstart, u64 size, u32 flags)
 {
struct tsi721_device *priv = mport->priv;
int i, avail = -1;
@@ -1103,6 +1103,10 @@ static int tsi721_rio_map_inb_mem(struct rio_mport 
*mport, dma_addr_t lstart,
struct tsi721_ib_win_mapping *map = NULL;
int ret = -EBUSY;
 
+   /* Max IBW size supported by HW is 16GB */
+   if (size > 0x4UL)
+   return -EINVAL;
+
if (direct) {
/* Calculate minimal acceptable window size and base address */
 
@@ -1110,15 +1114,15 @@ static int tsi721_rio_map_inb_mem(struct rio_mport 
*mport, dma_addr_t lstart,
ibw_start = lstart & ~(ibw_size - 1);
 
tsi_debug(IBW, &priv->pdev->dev,
-   "Direct (RIO_0x%llx -> PCIe_%pad), size=0x%x, ibw_start 
= 0x%llx",
+   "Direct (RIO_0x%llx -> PCIe_%pad), size=0x%llx, 
ibw_start = 0x%llx",
rstart, &lstart, size, ibw_start);
 
while ((lstart + size) > (ibw_start + ibw_size)) {
ibw_size *= 2;
ibw_start = lstart & ~(ibw_size - 1);
-   if (ibw_size > 0x8000) { /* Limit max size to 2GB */
+   /* Check for crossing IBW max size 16GB */
+   if (ibw_size > 0x4UL)
return -EBUSY;
-   }
}
 
loc_start = ibw_start;
@@ -1129,7 +1133,7 @@ static int tsi721_rio_map_inb_mem(struct rio_mport 
*mport, dma_addr_t lstart,
 
} else {
tsi_debug(IBW, &priv->pdev->dev,
-   "Translated (RIO_0x%llx -> PCIe_%pad), size=0x%x",
+   "Translated (RIO_0x%llx -> PCIe_%pad), size=0x%llx",
rstart, &lstart, size);
 
if (!is_power_of_2(size) || size < 0x1000 ||
diff --git a/include/linux/rio.h b/include/linux/rio.h
index aa23238..f7ec35b 100644
--- a/include/linux/rio.h
+++ b/include/linux/rio.h
@@ -425,7 +425,7 @@ struct rio_ops {
int (*add_inb_buffer)(struct rio_mport *mport, int mbox, void *buf);
void *(*get_inb_message)(struct rio_mport *mport, int mbox);
int (*map_inb)(struct rio_mport *mport, dma_addr_t lstart,
-   u64 rstart, u32 size, u32 flags);
+   u64 rstart, u64 size, u32 flags);
void (*unmap_inb)(struct rio_mport *mport, dma_addr_t lstart);
int (*query_mport)(struct rio_mport *mport,
   struct rio_mport_attr *attr);
-- 
1.7.8.4

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH] powerpc/fsl_rio: update for port-write interface change

2016-02-11 Thread Alexandre Bounine
Platform-specific update following changes in port-write handler interface.

This is a follow-up patch for
[PATCH 22/30] rapidio: add global inbound port write interfaces

Signed-off-by: Alexandre Bounine 
Cc: Matt Porter 
Cc: Benjamin Herrenschmidt 
Cc: Aurelien Jacquiot 
Cc: Andre van Herk 
Cc: linux-ker...@vger.kernel.org
Cc: linuxppc-dev@lists.ozlabs.org
---
 arch/powerpc/sysdev/fsl_rio.c |1 +
 arch/powerpc/sysdev/fsl_rio.h |1 +
 arch/powerpc/sysdev/fsl_rmu.c |   16 ++--
 3 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c
index 385371a..f5bf38b9 100644
--- a/arch/powerpc/sysdev/fsl_rio.c
+++ b/arch/powerpc/sysdev/fsl_rio.c
@@ -726,6 +726,7 @@ int fsl_rio_setup(struct platform_device *dev)
fsl_rio_inbound_mem_init(priv);
 
dbell->mport[i] = port;
+   pw->mport[i] = port;
 
if (rio_register_mport(port)) {
release_resource(&port->iores);
diff --git a/arch/powerpc/sysdev/fsl_rio.h b/arch/powerpc/sysdev/fsl_rio.h
index d53407a..12dd18f 100644
--- a/arch/powerpc/sysdev/fsl_rio.h
+++ b/arch/powerpc/sysdev/fsl_rio.h
@@ -97,6 +97,7 @@ struct fsl_rio_dbell {
 };
 
 struct fsl_rio_pw {
+   struct rio_mport *mport[MAX_PORT_NUM];
struct device *dev;
struct rio_pw_regs __iomem *pw_regs;
struct rio_port_write_msg port_write_msg;
diff --git a/arch/powerpc/sysdev/fsl_rmu.c b/arch/powerpc/sysdev/fsl_rmu.c
index b48197a..176acfc 100644
--- a/arch/powerpc/sysdev/fsl_rmu.c
+++ b/arch/powerpc/sysdev/fsl_rmu.c
@@ -481,14 +481,14 @@ pw_done:
 static void fsl_pw_dpc(struct work_struct *work)
 {
struct fsl_rio_pw *pw = container_of(work, struct fsl_rio_pw, pw_work);
-   u32 msg_buffer[RIO_PW_MSG_SIZE/sizeof(u32)];
+   union rio_pw_msg msg_buffer;
+   int i;
 
/*
 * Process port-write messages
 */
-   while (kfifo_out_spinlocked(&pw->pw_fifo, (unsigned char *)msg_buffer,
+   while (kfifo_out_spinlocked(&pw->pw_fifo, (unsigned char *)&msg_buffer,
 RIO_PW_MSG_SIZE, &pw->pw_fifo_lock)) {
-   /* Process one message */
 #ifdef DEBUG_PW
{
u32 i;
@@ -496,15 +496,19 @@ static void fsl_pw_dpc(struct work_struct *work)
for (i = 0; i < RIO_PW_MSG_SIZE/sizeof(u32); i++) {
if ((i%4) == 0)
pr_debug("\n0x%02x: 0x%08x", i*4,
-msg_buffer[i]);
+msg_buffer.raw[i]);
else
-   pr_debug(" 0x%08x", msg_buffer[i]);
+   pr_debug(" 0x%08x", msg_buffer.raw[i]);
}
pr_debug("\n");
}
 #endif
/* Pass the port-write message to RIO core for processing */
-   rio_inb_pwrite_handler((union rio_pw_msg *)msg_buffer);
+   for (i = 0; i < MAX_PORT_NUM; i++) {
+   if (pw->mport[i])
+   rio_inb_pwrite_handler(pw->mport[i],
+  &msg_buffer);
+   }
}
 }
 
-- 
1.7.8.4

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH 16/30] powerpc/fsl_rio: changes to mport registration

2016-02-05 Thread Alexandre Bounine
Change mport object initialization/registration sequence to match reworked
version of rio_register_mport() in the core code.

Signed-off-by: Alexandre Bounine 
Cc: Matt Porter 
Cc: Benjamin Herrenschmidt 
Cc: Aurelien Jacquiot 
Cc: Andre van Herk 
Cc: linux-ker...@vger.kernel.org
Cc: linuxppc-dev@lists.ozlabs.org
---
 arch/powerpc/sysdev/fsl_rio.c |   18 --
 1 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c
index c1cd369..385371a 100644
--- a/arch/powerpc/sysdev/fsl_rio.c
+++ b/arch/powerpc/sysdev/fsl_rio.c
@@ -606,6 +606,12 @@ int fsl_rio_setup(struct platform_device *dev)
if (!port)
continue;
 
+   rc = rio_mport_initialize(port);
+   if (rc) {
+   kfree(port);
+   continue;
+   }
+
i = *port_index - 1;
port->index = (unsigned char)i;
 
@@ -682,12 +688,6 @@ int fsl_rio_setup(struct platform_device *dev)
dev_info(&dev->dev, "RapidIO Common Transport System size: 
%d\n",
port->sys_size ? 65536 : 256);
 
-   if (rio_register_mport(port)) {
-   release_resource(&port->iores);
-   kfree(priv);
-   kfree(port);
-   continue;
-   }
if (port->host_deviceid >= 0)
out_be32(priv->regs_win + RIO_GCCSR, RIO_PORT_GEN_HOST |
RIO_PORT_GEN_MASTER | RIO_PORT_GEN_DISCOVERED);
@@ -727,6 +727,12 @@ int fsl_rio_setup(struct platform_device *dev)
 
dbell->mport[i] = port;
 
+   if (rio_register_mport(port)) {
+   release_resource(&port->iores);
+   kfree(priv);
+   kfree(port);
+   continue;
+   }
active_ports++;
}
 
-- 
1.7.8.4

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[RESEND PATCH] rapidio: add new RapidIO DMA interface routines

2014-07-23 Thread Alexandre Bounine
Resending because the original email was rejected by some gateways.

Add RapidIO DMA interface routines that directly use reference to the mport
device object and/or target device destination ID as parameters.
This allows to perform RapidIO DMA transfer requests by modules that do not
have an access to the RapidIO device list.

Signed-off-by: Alexandre Bounine 
Cc: Matt Porter 
Cc: Andre van Herk 
Cc: Stef van Os 
Cc: linux-ker...@vger.kernel.org
Cc: linuxppc-dev@lists.ozlabs.org
---
 drivers/rapidio/rio.c   | 66 +++--
 include/linux/rio_drv.h |  5 
 2 files changed, 52 insertions(+), 19 deletions(-)

diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c
index a54ba04..d7b87c6 100644
--- a/drivers/rapidio/rio.c
+++ b/drivers/rapidio/rio.c
@@ -1509,30 +1509,39 @@ EXPORT_SYMBOL_GPL(rio_route_clr_table);
 
 static bool rio_chan_filter(struct dma_chan *chan, void *arg)
 {
-   struct rio_dev *rdev = arg;
+   struct rio_mport *mport = arg;
 
/* Check that DMA device belongs to the right MPORT */
-   return (rdev->net->hport ==
-   container_of(chan->device, struct rio_mport, dma));
+   return mport == container_of(chan->device, struct rio_mport, dma);
 }
 
 /**
- * rio_request_dma - request RapidIO capable DMA channel that supports
- *   specified target RapidIO device.
- * @rdev: RIO device control structure
+ * rio_request_mport_dma - request RapidIO capable DMA channel associated
+ *   with specified local RapidIO mport device.
+ * @mport: RIO mport to perform DMA data transfers
  *
  * Returns pointer to allocated DMA channel or NULL if failed.
  */
-struct dma_chan *rio_request_dma(struct rio_dev *rdev)
+struct dma_chan *rio_request_mport_dma(struct rio_mport *mport)
 {
dma_cap_mask_t mask;
-   struct dma_chan *dchan;
 
dma_cap_zero(mask);
dma_cap_set(DMA_SLAVE, mask);
-   dchan = dma_request_channel(mask, rio_chan_filter, rdev);
+   return dma_request_channel(mask, rio_chan_filter, mport);
+}
+EXPORT_SYMBOL_GPL(rio_request_mport_dma);
 
-   return dchan;
+/**
+ * rio_request_dma - request RapidIO capable DMA channel that supports
+ *   specified target RapidIO device.
+ * @rdev: RIO device associated with DMA transfer
+ *
+ * Returns pointer to allocated DMA channel or NULL if failed.
+ */
+struct dma_chan *rio_request_dma(struct rio_dev *rdev)
+{
+   return rio_request_mport_dma(rdev->net->hport);
 }
 EXPORT_SYMBOL_GPL(rio_request_dma);
 
@@ -1547,10 +1556,10 @@ void rio_release_dma(struct dma_chan *dchan)
 EXPORT_SYMBOL_GPL(rio_release_dma);
 
 /**
- * rio_dma_prep_slave_sg - RapidIO specific wrapper
+ * rio_dma_prep_xfer - RapidIO specific wrapper
  *   for device_prep_slave_sg callback defined by DMAENGINE.
- * @rdev: RIO device control structure
  * @dchan: DMA channel to configure
+ * @destid: target RapidIO device destination ID
  * @data: RIO specific data descriptor
  * @direction: DMA data transfer direction (TO or FROM the device)
  * @flags: dmaengine defined flags
@@ -1560,11 +1569,10 @@ EXPORT_SYMBOL_GPL(rio_release_dma);
  * target RIO device.
  * Returns pointer to DMA transaction descriptor or NULL if failed.
  */
-struct dma_async_tx_descriptor *rio_dma_prep_slave_sg(struct rio_dev *rdev,
-   struct dma_chan *dchan, struct rio_dma_data *data,
+struct dma_async_tx_descriptor *rio_dma_prep_xfer(struct dma_chan *dchan,
+   u16 destid, struct rio_dma_data *data,
enum dma_transfer_direction direction, unsigned long flags)
 {
-   struct dma_async_tx_descriptor *txd = NULL;
struct rio_dma_ext rio_ext;
 
if (dchan->device->device_prep_slave_sg == NULL) {
@@ -1572,15 +1580,35 @@ struct dma_async_tx_descriptor 
*rio_dma_prep_slave_sg(struct rio_dev *rdev,
return NULL;
}
 
-   rio_ext.destid = rdev->destid;
+   rio_ext.destid = destid;
rio_ext.rio_addr_u = data->rio_addr_u;
rio_ext.rio_addr = data->rio_addr;
rio_ext.wr_type = data->wr_type;
 
-   txd = dmaengine_prep_rio_sg(dchan, data->sg, data->sg_len,
-   direction, flags, &rio_ext);
+   return dmaengine_prep_rio_sg(dchan, data->sg, data->sg_len,
+direction, flags, &rio_ext);
+}
+EXPORT_SYMBOL_GPL(rio_dma_prep_xfer);
 
-   return txd;
+/**
+ * rio_dma_prep_slave_sg - RapidIO specific wrapper
+ *   for device_prep_slave_sg callback defined by DMAENGINE.
+ * @rdev: RIO device control structure
+ * @dchan: DMA channel to configure
+ * @data: RIO specific data descriptor
+ * @direction: DMA data transfer direction (TO or FROM the device)
+ * @flags: dmaengine defined flags
+ *
+ * Initializes RapidIO capable DMA channel for the specified data transfer.
+ * Uses DMA channel private extension to pass information related to remote
+ * target RIO device.
+ * Returns pointer to DM

[PATCH] rapidio: rework device hierarchy and introduce mport class of devices

2014-02-25 Thread Alexandre Bounine
This patch removes an artificial RapidIO bus root device and establishes actual
device hierarchy by providing reference to real parent devices.
It also introduces device class for RapidIO controller devices (on-chip or
an eternal bridge, known as "mport").

Existing implementation was sufficient for SoC-based platforms that have
a single RapidIO controller. With introduction of devices using multiple RapidIO
controllers and PCIe-to-RapidIO bridges the old scheme is very limiting or does
not work at all. The implemented changes allow to properly reference platform's
local RapidIO mport devices and provide device details needed for upper layers.

This change to RapidIO device hierarchy does not break any known existing kernel
or user space interfaces.

Signed-off-by: Alexandre Bounine 
Cc: Matt Porter 
Cc: Li Yang 
Cc: Kumar Gala 
Cc: Andre van Herk 
Cc: Stef van Os 
Cc: Jerry Jacobs 
Cc: Arno Tiemersma 
Cc: Rob Landley 
Cc: linux-ker...@vger.kernel.org
Cc: linuxppc-dev@lists.ozlabs.org
---
 Documentation/rapidio/sysfs.txt  |   66 +
 arch/powerpc/sysdev/fsl_rio.c|1 +
 drivers/net/rionet.c |1 +
 drivers/rapidio/devices/tsi721.c |1 +
 drivers/rapidio/rio-driver.c |   22 
 drivers/rapidio/rio-scan.c   |1 +
 drivers/rapidio/rio-sysfs.c  |   40 +++
 drivers/rapidio/rio.c|   11 ++
 drivers/rapidio/rio.h|1 +
 include/linux/rio.h  |5 ++-
 10 files changed, 133 insertions(+), 16 deletions(-)

diff --git a/Documentation/rapidio/sysfs.txt b/Documentation/rapidio/sysfs.txt
index 271438c..47ce9a5 100644
--- a/Documentation/rapidio/sysfs.txt
+++ b/Documentation/rapidio/sysfs.txt
@@ -2,8 +2,8 @@
 
 

 
-1. Device Subdirectories
-
+1. RapidIO Device Subdirectories
+
 
 For each RapidIO device, the RapidIO subsystem creates files in an individual
 subdirectory with the following name, /sys/bus/rapidio/devices/.
@@ -25,8 +25,8 @@ seen by the enumerating host (destID = 1):
 NOTE: An enumerating or discovering endpoint does not create a sysfs entry for
 itself, this is why an endpoint with destID=1 is not shown in the list.
 
-2. Attributes Common for All Devices
-
+2. Attributes Common for All RapidIO Devices
+
 
 Each device subdirectory contains the following informational read-only files:
 
@@ -52,16 +52,16 @@ This attribute is similar in behavior to the "config" 
attribute of PCI devices
 and provides an access to the RapidIO device registers using standard file read
 and write operations.
 
-3. Endpoint Device Attributes
--
+3. RapidIO Endpoint Device Attributes
+-
 
 Currently Linux RapidIO subsystem does not create any endpoint specific sysfs
 attributes. It is possible that RapidIO master port drivers and endpoint device
 drivers will add their device-specific sysfs attributes but such attributes are
 outside the scope of this document.
 
-4. Switch Device Attributes

+4. RapidIO Switch Device Attributes
+---
 
 RapidIO switches have additional attributes in sysfs. RapidIO subsystem 
supports
 common and device-specific sysfs attributes for switches. Because switches are
@@ -106,3 +106,53 @@ attribute:
 for that controller always will be 0.
 To initiate RapidIO enumeration/discovery on all available mports
 a user must write '-1' (or RIO_MPORT_ANY) into this attribute file.
+
+
+6. RapidIO Bus Controllers/Ports
+
+
+On-chip RapidIO controllers and PCIe-to-RapidIO bridges (referenced as
+"Master Port" or "mport") are presented in sysfs as the special class of
+devices: "rapidio_port".
+
+The /sys/class/rapidio_port subdirectory contains individual subdirectories
+named as "rapidioN" where N = mport ID registered with RapidIO subsystem.
+
+NOTE: An mport ID is not a RapidIO destination ID assigned to a given local
+mport device.
+
+Each mport device subdirectory in addition to standard entries contains the
+following device-specific attributes:
+
+   port_destid - reports RapidIO destination ID assigned to the given RapidIO
+ mport device. If value 0x is returned this means that
+ no valid destination ID have been assigned to the mport (yet).
+ Normally, before enumeration/discovery have been executed only
+ fabric enumerating mports have a valid destination ID assigned
+ to them using "hdid=..." rapidio module parameter.
+  sys_size - reports RapidIO common transport system size:
+   

[PATCH] rapidio/tsi721: fix tasklet termination in dma channel release

2014-02-21 Thread Alexandre Bounine

This patch is a modification of the patch originally proposed
by Xiaotian Feng : https://lkml.org/lkml/2012/11/5/413
This new version disables DMA channel interrupts and ensures that the tasklet
wil not be scheduled again before calling tasklet_kill().

Unfortunately the updated patch was not released at that time due to planned
rework of Tsi721 mport driver to use threaded interrupts (which has yet to
happen).
Recently the issue was reported again: https://lkml.org/lkml/2014/2/19/762.

Description from the original Xiaotian's patch:

"Some drivers use tasklet_disable in device remove/release process, 
tasklet_disable will inc tasklet->count and return. If the tasklet is 
not handled yet under some softirq pressure, the tasklet will be 
placed on the tasklet_vec, never have a chance to be excuted. This 
might lead to a heavy loaded ksoftirqd, wakeup with pending_softirq, 
but tasklet is disabled. tasklet_kill should be used in this case."

This patch is applicable to kernel versions starting from v3.5.

Signed-off-by: Alexandre Bounine 
Cc: Matt Porter 
Cc: Xiaotian Feng 
Cc: Thomas Gleixner 
Cc: Mike Galbraith 
Cc: 
---
 drivers/rapidio/devices/tsi721.h |1 +
 drivers/rapidio/devices/tsi721_dma.c |   25 ++---
 2 files changed, 19 insertions(+), 7 deletions(-)

diff --git a/drivers/rapidio/devices/tsi721.h b/drivers/rapidio/devices/tsi721.h
index b4b0d83..7061ac0 100644
--- a/drivers/rapidio/devices/tsi721.h
+++ b/drivers/rapidio/devices/tsi721.h
@@ -678,6 +678,7 @@ struct tsi721_bdma_chan {
struct list_headfree_list;
dma_cookie_tcompleted_cookie;
struct tasklet_struct   tasklet;
+   boolactive;
 };
 
 #endif /* CONFIG_RAPIDIO_DMA_ENGINE */
diff --git a/drivers/rapidio/devices/tsi721_dma.c 
b/drivers/rapidio/devices/tsi721_dma.c
index 502663f..b57f650 100644
--- a/drivers/rapidio/devices/tsi721_dma.c
+++ b/drivers/rapidio/devices/tsi721_dma.c
@@ -206,8 +206,8 @@ void tsi721_bdma_handler(struct tsi721_bdma_chan *bdma_chan)
 {
/* Disable BDMA channel interrupts */
iowrite32(0, bdma_chan->regs + TSI721_DMAC_INTE);
-
-   tasklet_schedule(&bdma_chan->tasklet);
+   if (bdma_chan->active)
+   tasklet_schedule(&bdma_chan->tasklet);
 }
 
 #ifdef CONFIG_PCI_MSI
@@ -562,7 +562,7 @@ static int tsi721_alloc_chan_resources(struct dma_chan 
*dchan)
}
 #endif /* CONFIG_PCI_MSI */
 
-   tasklet_enable(&bdma_chan->tasklet);
+   bdma_chan->active = true;
tsi721_bdma_interrupt_enable(bdma_chan, 1);
 
return bdma_chan->bd_num - 1;
@@ -589,14 +589,25 @@ static void tsi721_free_chan_resources(struct dma_chan 
*dchan)
BUG_ON(!list_empty(&bdma_chan->active_list));
BUG_ON(!list_empty(&bdma_chan->queue));
 
-   tasklet_disable(&bdma_chan->tasklet);
+   tsi721_bdma_interrupt_enable(bdma_chan, 0);
+   bdma_chan->active = false;
+
+#ifdef CONFIG_PCI_MSI
+   if (priv->flags & TSI721_USING_MSIX) {
+   synchronize_irq(priv->msix[TSI721_VECT_DMA0_DONE +
+  bdma_chan->id].vector);
+   synchronize_irq(priv->msix[TSI721_VECT_DMA0_INT +
+  bdma_chan->id].vector);
+   } else
+#endif
+   synchronize_irq(priv->pdev->irq);
+
+   tasklet_kill(&bdma_chan->tasklet);
 
spin_lock_bh(&bdma_chan->lock);
list_splice_init(&bdma_chan->free_list, &list);
spin_unlock_bh(&bdma_chan->lock);
 
-   tsi721_bdma_interrupt_enable(bdma_chan, 0);
-
 #ifdef CONFIG_PCI_MSI
if (priv->flags & TSI721_USING_MSIX) {
free_irq(priv->msix[TSI721_VECT_DMA0_DONE +
@@ -790,6 +801,7 @@ int tsi721_register_dma(struct tsi721_device *priv)
bdma_chan->dchan.cookie = 1;
bdma_chan->dchan.chan_id = i;
bdma_chan->id = i;
+   bdma_chan->active = false;
 
spin_lock_init(&bdma_chan->lock);
 
@@ -799,7 +811,6 @@ int tsi721_register_dma(struct tsi721_device *priv)
 
tasklet_init(&bdma_chan->tasklet, tsi721_dma_tasklet,
 (unsigned long)bdma_chan);
-   tasklet_disable(&bdma_chan->tasklet);
list_add_tail(&bdma_chan->dchan.device_node,
  &mport->dma.channels);
}
-- 
1.7.8.4

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH] rapidio: add modular rapidio core build into powerpc and mips branches

2013-12-18 Thread Alexandre Bounine
Allow modular build option for RapidIO subsystem core in MIPS and PowerPC
architectural branches.

At this moment modular RapidIO subsystem build is enabled only for platforms
that use PCI/PCIe based RapidIO controllers (e.g. Tsi721).

Signed-off-by: Alexandre Bounine 
Cc: Matt Porter 
Cc: Jean Delvare 
Cc: Ralf Baechle 
Cc: Benjamin Herrenschmidt 
Cc: Li Yang 
Cc: linux-m...@linux-mips.org
---
 arch/mips/Kconfig|2 +-
 arch/powerpc/Kconfig |4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 650de39..e6a8a7a 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -2442,7 +2442,7 @@ source "drivers/pcmcia/Kconfig"
 source "drivers/pci/hotplug/Kconfig"
 
 config RAPIDIO
-   bool "RapidIO support"
+   tristate "RapidIO support"
depends on PCI
default n
help
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index b44b52c..992531f 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -790,7 +790,7 @@ config HAS_RAPIDIO
default n
 
 config RAPIDIO
-   bool "RapidIO support"
+   tristate "RapidIO support"
depends on HAS_RAPIDIO || PCI
help
  If you say Y here, the kernel will include drivers and
@@ -798,7 +798,7 @@ config RAPIDIO
 
 config FSL_RIO
bool "Freescale Embedded SRIO Controller support"
-   depends on RAPIDIO && HAS_RAPIDIO
+   depends on RAPIDIO = y && HAS_RAPIDIO
default "n"
---help---
  Include support for RapidIO controller on Freescale embedded
-- 
1.7.8.4

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH] rapidio: change endpoint device name format

2013-07-03 Thread Alexandre Bounine
Change endpoint device name format to use a component tag value instead of
device destination ID.

RapidIO specification defines a component tag to be a unique identifier
for devices in a network. RapidIO switches already use component tag as
part of their device name and also use it for device identification when
processing error management event notifications.

Forming an endpoint's device name using its component tag instead of 
destination ID
allows to keep sysfs device directories unchanged in case if a routing
process dynamically changes endpoint's destination ID as a result of route
optimization.

This change should not affect any existing users because a valid device
destination ID always should be obtained by reading "destid" attribute and
not by parsing device name.

This patch also removes switchid member from struct rio_switch because it
simply duplicates the component tag and does not have other use than in
device name generation.

Signed-off-by: Alexandre Bounine 
Cc: Matt Porter 
Cc: Li Yang 
Cc: Kumar Gala 
Cc: Andre van Herk 
Cc: Micha Nelissen 
Cc: Stef van Os 
---
 drivers/rapidio/rio-scan.c |5 ++---
 include/linux/rio.h|2 --
 2 files changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c
index 0e86569..c744800 100644
--- a/drivers/rapidio/rio-scan.c
+++ b/drivers/rapidio/rio-scan.c
@@ -433,7 +433,6 @@ static struct rio_dev *rio_setup_device(struct rio_net *net,
/* If a PE has both switch and other functions, show it as a switch */
if (rio_is_switch(rdev)) {
rswitch = rdev->rswitch;
-   rswitch->switchid = rdev->comp_tag & RIO_CTAG_UDEVID;
rswitch->port_ok = 0;
spin_lock_init(&rswitch->lock);
rswitch->route_table = kzalloc(sizeof(u8)*
@@ -446,7 +445,7 @@ static struct rio_dev *rio_setup_device(struct rio_net *net,
rdid++)
rswitch->route_table[rdid] = RIO_INVALID_ROUTE;
dev_set_name(&rdev->dev, "%02x:s:%04x", rdev->net->id,
-rswitch->switchid);
+rdev->comp_tag & RIO_CTAG_UDEVID);
 
if (do_enum)
rio_route_clr_table(rdev, RIO_GLOBAL_TABLE, 0);
@@ -459,7 +458,7 @@ static struct rio_dev *rio_setup_device(struct rio_net *net,
rio_enable_rx_tx_port(port, 0, destid, hopcount, 0);
 
dev_set_name(&rdev->dev, "%02x:e:%04x", rdev->net->id,
-rdev->destid);
+rdev->comp_tag & RIO_CTAG_UDEVID);
}
 
rio_attach_device(rdev);
diff --git a/include/linux/rio.h b/include/linux/rio.h
index e2faf7b..b71d573 100644
--- a/include/linux/rio.h
+++ b/include/linux/rio.h
@@ -92,7 +92,6 @@ union rio_pw_msg;
 /**
  * struct rio_switch - RIO switch info
  * @node: Node in global list of switches
- * @switchid: Switch ID that is unique across a network
  * @route_table: Copy of switch routing table
  * @port_ok: Status of each port (one bit per port) - OK=1 or UNINIT=0
  * @ops: pointer to switch-specific operations
@@ -101,7 +100,6 @@ union rio_pw_msg;
  */
 struct rio_switch {
struct list_head node;
-   u16 switchid;
u8 *route_table;
u32 port_ok;
struct rio_switch_ops *ops;
-- 
1.7.8.4

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH 1/7] rapidio: convert switch drivers to modules

2013-06-28 Thread Alexandre Bounine
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 
Cc: Matt Porter 
Cc: Li Yang 
Cc: Kumar Gala 
Cc: Andre van Herk 
Cc: Micha Nelissen 
Cc: Stef van Os 
Cc: Jean Delvare 
---
 drivers/rapidio/Kconfig |5 +
 drivers/rapidio/rio-scan.c  |  171 +
 drivers/rapidio/rio-sysfs.c |4 -
 drivers/rapidio/rio.c   |  286 +--
 drivers/rapidio/rio.h   |   41 +
 drivers/rapidio/switches/Kconfig|   12 +-
 drivers/rapidio/switches/idt_gen2.c |   98 ++---
 drivers/rapidio/switches/idtcps.c   |   86 +--
 drivers/rapidio/switches/tsi568.c   |   71 -
 drivers/rapidio/switches/tsi57x.c   |   81 --
 include/asm-generic/vmlinux.lds.h   |7 -
 include/linux/rio.h |   51 +++
 12 files changed, 568 insertions(+), 345 deletions(-)

diff --git a/drivers/rapidio/Kconfig b/drivers/rapidio/Kconfig
index 5ab0564..3e3be57 100644
--- a/drivers/rapidio/Kconfig
+++ b/drivers/rapidio/Kconfig
@@ -67,4 +67,9 @@ config RAPIDIO_ENUM_BASIC
 
 endchoice
 
+menu "RapidIO Switch drivers"
+   depends on RAPIDIO
+
 source "drivers/rapidio/switches/Kconfig"
+
+endmenu
diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c
index 4c15dbf..61c913f 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,
rio_mport_write_config_32(port, destid, hopcount,
  RIO_COMPONENT_TAG_CSR, next_comptag);
rdev->comp_tag = next_comptag++;
+   rdev->do_enum = true;
}  else {
rio_mport_read_config_32(port, destid, hopcount,
 RIO_COMPONENT_TAG_CSR,
@@ -434,6 +435,7 @@ static struct rio_dev *rio_setup_device(struct rio_net *net,
rswitch = rdev->rswitch;
rswitch->switchid = rdev->comp_tag & RIO_CTAG_UDEVID;
rswitch->port_ok = 0;
+   spin_lock_init(&rswitch->lock);
rswitch->route_table = kzalloc(sizeof(u8)*
RIO_MAX_ROUTE_ENTRIES(port->sys_size),
GFP_KERNEL);
@@ -445,11 +447,9 @@ static struct rio_dev *rio_setup_device(struct rio_net 
*net,
rswitch->route_table[rdid] = RIO_INVALID_ROUTE;
dev_set_name(&rdev->dev, "%02x:s:%04x", rdev->net->id,
 rswitch->switchid);
-   rio_switch_init(rdev, do_enum);
 
-   if (do_enum && rswitch->clr_table)
-   rswitch->clr_table(port, destid, hopcount,
-  RIO_GLOBAL_TABLE);
+   if (do_enum)
+   rio_route_clr_table(rdev, RIO_GLOBAL_TABLE, 0);
 
list_add_tail(&rswitch->node, &net->switches);
 
@@ -533,156 +533,6 @@ rio_sport_is_active(struct rio_mport *port, u16 destid, 
u8 hopcount, int sport)
 }
 
 /**
- * rio_lock_device - Acquires host device lock for specified device
- * @port: Master port to send transaction
- * @destid: Destination ID for device/switch
- * @hopcount: Hopcount to reach switch
- * @wait_ms: Max wait time in msec (0 = no timeout)
- *
- * Attepts to acquire host device lock for specified device
- * Returns 0 if device lock acquired or EINVAL if timeout expires.
- */
-static int
-rio_lock_device(struct rio_mport *port, u16 destid, u8 hopcount, int wait_ms)
-{
-   u32 result;
-   int tcnt = 0;
-
-   /* Attempt to acquire device lock */
-   rio_mport_write_config_32(port, destid, hopcount,
-

[PATCH 2/7] rapidio/rionet: rework driver initialization and removal

2013-06-28 Thread Alexandre Bounine
Rework probe/remove routines to prevent rionet driver from monopolizing
target RapidIO devices. Fix conflict with modular RapidIO switch drivers.

Using one of RapidIO messaging channels rionet driver provides a service layer
common to all endpoint devices in a system's RapidIO network. These devices may
also require their own specific device driver which will be blocked from
attaching to the target device by rionet (or block rionet if loaded earlier).
To avoid conflict with device-specific drivers, the rionet driver is reworked
to be registered as a subsystem interface on the RapidIO bus.

The reworked rio_remove_dev() and rionet_exit() routines also include handling
of individual rionet peer device removal which was not supported before.

Signed-off-by: Alexandre Bounine 
Cc: Matt Porter 
Cc: Li Yang 
Cc: Kumar Gala 
Cc: "David S. Miller" 
Cc: Andre van Herk 
Cc: Micha Nelissen 
Cc: Stef van Os 
Cc: Jean Delvare 
---
 drivers/net/rionet.c |  103 +
 1 files changed, 78 insertions(+), 25 deletions(-)

diff --git a/drivers/net/rionet.c b/drivers/net/rionet.c
index f433b59..6d1f6ed 100644
--- a/drivers/net/rionet.c
+++ b/drivers/net/rionet.c
@@ -208,6 +208,17 @@ static int rionet_start_xmit(struct sk_buff *skb, struct 
net_device *ndev)
if (nets[rnet->mport->id].active[destid])
rionet_queue_tx_msg(skb, ndev,
nets[rnet->mport->id].active[destid]);
+   else {
+   /*
+* If the target device was removed from the list of
+* active peers but we still have TX packets targeting
+* it just report sending a packet to the target
+* (without actual packet transfer).
+*/
+   dev_kfree_skb_any(skb);
+   ndev->stats.tx_packets++;
+   ndev->stats.tx_bytes += skb->len;
+   }
}
 
spin_unlock_irqrestore(&rnet->tx_lock, flags);
@@ -385,24 +396,28 @@ static int rionet_close(struct net_device *ndev)
return 0;
 }
 
-static void rionet_remove(struct rio_dev *rdev)
+static int rionet_remove_dev(struct device *dev, struct subsys_interface *sif)
 {
-   struct net_device *ndev = rio_get_drvdata(rdev);
+   struct rio_dev *rdev = to_rio_dev(dev);
unsigned char netid = rdev->net->hport->id;
struct rionet_peer *peer, *tmp;
 
-   unregister_netdev(ndev);
-
-   free_pages((unsigned long)nets[netid].active, get_order(sizeof(void *) *
-   RIO_MAX_ROUTE_ENTRIES(rdev->net->hport->sys_size)));
-   nets[netid].active = NULL;
+   if (dev_rionet_capable(rdev)) {
+   list_for_each_entry_safe(peer, tmp, &nets[netid].peers, node) {
+   if (peer->rdev == rdev) {
+   if (nets[netid].active[rdev->destid]) {
+   nets[netid].active[rdev->destid] = NULL;
+   nets[netid].nact--;
+   }
 
-   list_for_each_entry_safe(peer, tmp, &nets[netid].peers, node) {
-   list_del(&peer->node);
-   kfree(peer);
+   list_del(&peer->node);
+   kfree(peer);
+   break;
+   }
+   }
}
 
-   free_netdev(ndev);
+   return 0;
 }
 
 static void rionet_get_drvinfo(struct net_device *ndev,
@@ -503,12 +518,13 @@ static int rionet_setup_netdev(struct rio_mport *mport, 
struct net_device *ndev)
 
 static unsigned long net_table[RIONET_MAX_NETS/sizeof(unsigned long) + 1];
 
-static int rionet_probe(struct rio_dev *rdev, const struct rio_device_id *id)
+static int rionet_add_dev(struct device *dev, struct subsys_interface *sif)
 {
int rc = -ENODEV;
u32 lsrc_ops, ldst_ops;
struct rionet_peer *peer;
struct net_device *ndev = NULL;
+   struct rio_dev *rdev = to_rio_dev(dev);
unsigned char netid = rdev->net->hport->id;
int oldnet;
 
@@ -518,8 +534,9 @@ static int rionet_probe(struct rio_dev *rdev, const struct 
rio_device_id *id)
oldnet = test_and_set_bit(netid, net_table);
 
/*
-* First time through, make sure local device is rionet
-* capable, setup netdev (will be skipped on later probes)
+* If first time through this net, make sure local device is rionet
+* capable and setup netdev (this step will be skipped in later probes
+* on the same net).
 */
if (!oldnet) {
rio_local_read_config_32(rdev->net->hport, RIO_SRC_OPS_CAR,
@@ -541,6 +558,12 @@ static int rionet_probe(struct rio_dev *rdev, con

[PATCH 7/7] rapidio: documentation update

2013-06-28 Thread Alexandre Bounine
Update RapidIO documentation files to reflect modularization changes.

Signed-off-by: Alexandre Bounine 
Cc: Matt Porter 
Cc: Li Yang 
Cc: Kumar Gala 
Cc: Andre van Herk 
Cc: Micha Nelissen 
Cc: Stef van Os 
Cc: Jean Delvare 
---
 Documentation/rapidio/rapidio.txt |   98 -
 Documentation/rapidio/sysfs.txt   |1 +
 2 files changed, 86 insertions(+), 13 deletions(-)

diff --git a/Documentation/rapidio/rapidio.txt 
b/Documentation/rapidio/rapidio.txt
index a9c16c9..717f5aa 100644
--- a/Documentation/rapidio/rapidio.txt
+++ b/Documentation/rapidio/rapidio.txt
@@ -73,28 +73,44 @@ data structure. This structure includes lists of all 
devices and local master
 ports that form the same network. It also contains a pointer to the default
 master port that is used to communicate with devices within the network.
 
+2.5 Device Drivers
+
+RapidIO device-specific drivers follow Linux Kernel Driver Model and are
+intended to support specific RapidIO devices attached to the RapidIO network.
+
+2.6 Subsystem Interfaces
+
+RapidIO interconnect specification defines features that may be used to provide
+one or more common service layers for all participating RapidIO devices. These
+common services may act separately from device-specific drivers or be used by
+device-specific drivers. Example of such service provider is the RIONET driver
+which implements Ethernet-over-RapidIO interface. Because only one driver can 
be
+registered for a device, all common RapidIO services have to be registered as
+subsystem interfaces. This allows to have multiple common services attached to
+the same device without blocking attachment of a device-specific driver.
+
 3. Subsystem Initialization
 ---
 
 In order to initialize the RapidIO subsystem, a platform must initialize and
 register at least one master port within the RapidIO network. To register mport
-within the subsystem controller driver initialization code calls function
+within the subsystem controller driver's initialization code calls function
 rio_register_mport() for each available master port.
 
-RapidIO subsystem uses subsys_initcall() or device_initcall() to perform
-controller initialization (depending on controller device type).
-
 After all active master ports are registered with a RapidIO subsystem,
 an enumeration and/or discovery routine may be called automatically or
 by user-space command.
 
+RapidIO subsystem can be configured to be built as a statically linked or
+modular component of the kernel (see details below).
+
 4. Enumeration and Discovery
 
 
 4.1 Overview
 
 
-RapidIO subsystem configuration options allow users to specify enumeration and
+RapidIO subsystem configuration options allow users to build enumeration and
 discovery methods as statically linked components or loadable modules.
 An enumeration/discovery method implementation and available input parameters
 define how any given method can be attached to available RapidIO mports:
@@ -115,8 +131,8 @@ several methods to initiate an enumeration and/or discovery 
process:
   endpoint waits for enumeration to be completed. If the specified timeout
   expires the discovery process is terminated without obtaining RapidIO network
   information. NOTE: a timed out discovery process may be restarted later using
-  a user-space command as it is described later if the given endpoint was
-  enumerated successfully.
+  a user-space command as it is described below (if the given endpoint was
+  enumerated successfully).
 
   (b) Statically linked enumeration and discovery process can be started by
   a command from user space. This initiation method provides more flexibility
@@ -138,15 +154,42 @@ When a network scan process is started it calls an 
enumeration or discovery
 routine depending on the configured role of a master port: host or agent.
 
 Enumeration is performed by a master port if it is configured as a host port by
-assigning a host device ID greater than or equal to zero. A host device ID is
-assigned to a master port through the kernel command line parameter "riohdid=",
-or can be configured in a platform-specific manner. If the host device ID for
-a specific master port is set to -1, the discovery process will be performed
-for it.
+assigning a host destination ID greater than or equal to zero. The host
+destination ID can be assigned to a master port using various methods depending
+on RapidIO subsystem build configuration:
+
+  (a) For a statically linked RapidIO subsystem core use command line parameter
+  "rapidio.hdid=" with a list of destination ID assignments in order of mport
+  device registration. For example, in a system with two RapidIO controllers
+  the command line parameter "rapidio.hdid=-1,7" will result in assignment of
+  the host destination ID=7 to the second RapidIO controller, while the first
+  one will be assigned destination ID=-1.
+
+  (

[PATCH 3/7] rapidio: update enumerator registration mechanism

2013-06-28 Thread Alexandre Bounine
Update enumeration/discovery method registration mechanism to allow loading
enumeration/discovery methods before all mports are registered.

Existing statically linked RapidIO subsystem expects that all available RapidIO
mport devices are initialized and registered before the enumeration/discovery
method is registered. Switching to loadable mport device drivers creates
situation when mport device driver can be loaded after enumeration/discovery
method is attached (e.g., loadable mport driver in a system with statically
linked RapidIO core and enumerator). This also will happen in a system with
hot-pluggable RapidIO controllers.

To remove the dependency on the initialization/registration order this patch
introduces enumeration/discovery registration mechanism that supports arbitrary
registration order of mports and enumerator/discovery methods.

The following registration rules are implemented:
- only one enumeration/discovery method can be registered for given mport ID
  (including RIO_MPORT_ANY);
- when new enumeration/discovery methods tries to attach to the registered mport
  device, method with matching mport ID will replace a default method previously
  registered for given mport (if any);
- enumeration/discovery method with target ID=RIO_MPORT_ANY will be attached
  only to mports that do not have another enumerator attached to them;
- when new mport device is registered with RapidIO subsystem, registration
  routine searches for the enumeration/discovery method with the best matching
  mport ID;
  
Signed-off-by: Alexandre Bounine 
Cc: Matt Porter 
Cc: Li Yang 
Cc: Kumar Gala 
Cc: Andre van Herk 
Cc: Micha Nelissen 
Cc: Stef van Os 
Cc: Jean Delvare 
---
 drivers/rapidio/rio-scan.c  |1 +
 drivers/rapidio/rio-sysfs.c |   17 +
 drivers/rapidio/rio.c   |  176 +++
 drivers/rapidio/rio.h   |3 +-
 include/linux/rio.h |   15 
 5 files changed, 164 insertions(+), 48 deletions(-)

diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c
index 61c913f..0e86569 100644
--- a/drivers/rapidio/rio-scan.c
+++ b/drivers/rapidio/rio-scan.c
@@ -1162,6 +1162,7 @@ bail:
 }
 
 static struct rio_scan rio_scan_ops = {
+   .owner = THIS_MODULE,
.enumerate = rio_enum_mport,
.discover = rio_disc_mport,
 };
diff --git a/drivers/rapidio/rio-sysfs.c b/drivers/rapidio/rio-sysfs.c
index 864e52f..0c4473e 100644
--- a/drivers/rapidio/rio-sysfs.c
+++ b/drivers/rapidio/rio-sysfs.c
@@ -286,7 +286,6 @@ static ssize_t bus_scan_store(struct bus_type *bus, const 
char *buf,
size_t count)
 {
long val;
-   struct rio_mport *port = NULL;
int rc;
 
if (kstrtol(buf, 0, &val) < 0)
@@ -300,21 +299,7 @@ static ssize_t bus_scan_store(struct bus_type *bus, const 
char *buf,
if (val < 0 || val >= RIO_MAX_MPORTS)
return -EINVAL;
 
-   port = rio_find_mport((int)val);
-
-   if (!port) {
-   pr_debug("RIO: %s: mport_%d not available\n",
-__func__, (int)val);
-   return -EINVAL;
-   }
-
-   if (!port->nscan)
-   return -EINVAL;
-
-   if (port->host_deviceid >= 0)
-   rc = port->nscan->enumerate(port, 0);
-   else
-   rc = port->nscan->discover(port, RIO_SCAN_ENUM_NO_WAIT);
+   rc = rio_mport_scan((int)val);
 exit:
if (!rc)
rc = count;
diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c
index b17d521..5eb727c 100644
--- a/drivers/rapidio/rio.c
+++ b/drivers/rapidio/rio.c
@@ -34,6 +34,7 @@ static LIST_HEAD(rio_devices);
 static DEFINE_SPINLOCK(rio_global_list_lock);
 
 static LIST_HEAD(rio_mports);
+static LIST_HEAD(rio_scans);
 static DEFINE_MUTEX(rio_mport_list_lock);
 static unsigned char next_portid;
 static DEFINE_SPINLOCK(rio_mmap_lock);
@@ -1602,34 +1603,73 @@ found:
  * rio_register_scan - enumeration/discovery method registration interface
  * @mport_id: mport device ID for which fabric scan routine has to be set
  *(RIO_MPORT_ANY = set for all available mports)
- * @scan_ops: enumeration/discovery control structure
+ * @scan_ops: enumeration/discovery operations structure
+ *
+ * Registers enumeration/discovery operations with RapidIO subsystem and
+ * attaches it to the specified mport device (or all available mports
+ * if RIO_MPORT_ANY is specified).
  *
- * Assigns enumeration or discovery method to the specified mport device (or 
all
- * available mports if RIO_MPORT_ANY is specified).
  * Returns error if the mport already has an enumerator attached to it.
- * In case of RIO_MPORT_ANY ignores ports with valid scan routines and returns
- * an error if was unable to find at least one available mport.
+ * In case of RIO_MPORT_ANY skips mports with valid scan routines (no error).
  */
 int rio_register_scan(int mport_id, struct rio_scan *scan_ops)
 {
str

[PATCH 5/7] rapidio: add modular build option for the subsystem core

2013-06-28 Thread Alexandre Bounine
Add a configuration option to build RapidIO subsystem core code as a loadable
kernel module. Currently this option is available only for x86-based platforms,
with the additional patch for PowerPC planned to be provided later.

This patch replaces kernel command line parameter "riohdid=" with its
module-specific analog "rapidio.hdid=".  

Signed-off-by: Alexandre Bounine 
Cc: Matt Porter 
Cc: Li Yang 
Cc: Kumar Gala 
Cc: Andre van Herk 
Cc: Micha Nelissen 
Cc: Stef van Os 
Cc: Jean Delvare 
---
 arch/x86/Kconfig |4 ++--
 drivers/rapidio/Makefile |4 +++-
 drivers/rapidio/rio.c|   27 ++-
 3 files changed, 19 insertions(+), 16 deletions(-)

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index fe120da..583ac42 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -2246,11 +2246,11 @@ source "drivers/pcmcia/Kconfig"
 source "drivers/pci/hotplug/Kconfig"
 
 config RAPIDIO
-   bool "RapidIO support"
+   tristate "RapidIO support"
depends on PCI
default n
help
- If you say Y here, the kernel will include drivers and
+ If enabled this option will include drivers and the core
  infrastructure code to support RapidIO interconnect devices.
 
 source "drivers/rapidio/Kconfig"
diff --git a/drivers/rapidio/Makefile b/drivers/rapidio/Makefile
index 3036702..6271ada 100644
--- a/drivers/rapidio/Makefile
+++ b/drivers/rapidio/Makefile
@@ -1,7 +1,9 @@
 #
 # Makefile for RapidIO interconnect services
 #
-obj-y += rio.o rio-access.o rio-driver.o rio-sysfs.o
+obj-$(CONFIG_RAPIDIO) += rapidio.o
+rapidio-y := rio.o rio-access.o rio-driver.o rio-sysfs.o
+
 obj-$(CONFIG_RAPIDIO_ENUM_BASIC) += rio-scan.o
 
 obj-$(CONFIG_RAPIDIO)  += switches/
diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c
index 2054b62..f4f30af 100644
--- a/drivers/rapidio/rio.c
+++ b/drivers/rapidio/rio.c
@@ -5,7 +5,7 @@
  * Copyright 2005 MontaVista Software, Inc.
  * Matt Porter 
  *
- * Copyright 2009 Integrated Device Technology, Inc.
+ * Copyright 2009 - 2013 Integrated Device Technology, Inc.
  * Alex Bounine 
  *
  * This program is free software; you can redistribute  it and/or modify it
@@ -30,6 +30,17 @@
 
 #include "rio.h"
 
+MODULE_DESCRIPTION("RapidIO Subsystem Core");
+MODULE_AUTHOR("Matt Porter ");
+MODULE_AUTHOR("Alexandre Bounine ");
+MODULE_LICENSE("GPL");
+
+static int hdid[RIO_MAX_MPORTS];
+static int ids_num;
+module_param_array(hdid, int, &ids_num, 0);
+MODULE_PARM_DESC(hdid,
+   "Destination ID assignment to local RapidIO controllers");
+
 static LIST_HEAD(rio_devices);
 static DEFINE_SPINLOCK(rio_global_list_lock);
 
@@ -1860,24 +1871,14 @@ no_disc:
return 0;
 }
 
-static int hdids[RIO_MAX_MPORTS + 1];
-
 static int rio_get_hdid(int index)
 {
-   if (!hdids[0] || hdids[0] <= index || index >= RIO_MAX_MPORTS)
+   if (ids_num == 0 || ids_num <= index || index >= RIO_MAX_MPORTS)
return -1;
 
-   return hdids[index + 1];
+   return hdid[index];
 }
 
-static int rio_hdid_setup(char *str)
-{
-   (void)get_options(str, ARRAY_SIZE(hdids), hdids);
-   return 1;
-}
-
-__setup("riohdid=", rio_hdid_setup);
-
 int rio_register_mport(struct rio_mport *port)
 {
struct rio_scan_node *scan = NULL;
-- 
1.7.8.4

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH 6/7] rapidio: add udev notification

2013-06-28 Thread Alexandre Bounine
Add RapidIO-specific modalias generation to enable udev notifications about
RapidIO-specific events.

The RapidIO modalias string format is shown below:

"rapidio:vdavad"

Where:
v  - Device Vendor ID (16 bit),
d  - Device ID (16 bit),
av - Assembly Vendor ID (16 bit),
ad - Assembly ID (16 bit),

as they are reported in corresponding Capability Registers (CARs)
of each RapidIO device.

Signed-off-by: Alexandre Bounine 
Cc: Matt Porter 
Cc: Li Yang 
Cc: Kumar Gala 
Cc: Andre van Herk 
Cc: Micha Nelissen 
Cc: Stef van Os 
Cc: Jean Delvare 
---
 drivers/rapidio/rio-driver.c  |   18 ++
 drivers/rapidio/rio-sysfs.c   |   10 ++
 include/linux/mod_devicetable.h   |   19 +++
 include/linux/rio.h   |   16 +---
 include/linux/rio_ids.h   |2 --
 scripts/mod/devicetable-offsets.c |6 ++
 scripts/mod/file2alias.c  |   20 
 7 files changed, 74 insertions(+), 17 deletions(-)

diff --git a/drivers/rapidio/rio-driver.c b/drivers/rapidio/rio-driver.c
index a0c8755..3e9b6a7 100644
--- a/drivers/rapidio/rio-driver.c
+++ b/drivers/rapidio/rio-driver.c
@@ -199,6 +199,23 @@ static int rio_match_bus(struct device *dev, struct 
device_driver *drv)
   out:return 0;
 }
 
+static int rio_uevent(struct device *dev, struct kobj_uevent_env *env)
+{
+   struct rio_dev *rdev;
+
+   if (!dev)
+   return -ENODEV;
+
+   rdev = to_rio_dev(dev);
+   if (!rdev)
+   return -ENODEV;
+
+   if (add_uevent_var(env, "MODALIAS=rapidio:v%04Xd%04Xav%04Xad%04X",
+  rdev->vid, rdev->did, rdev->asm_vid, rdev->asm_did))
+   return -ENOMEM;
+   return 0;
+}
+
 struct device rio_bus = {
.init_name = "rapidio",
 };
@@ -210,6 +227,7 @@ struct bus_type rio_bus_type = {
.bus_attrs = rio_bus_attrs,
.probe = rio_device_probe,
.remove = rio_device_remove,
+   .uevent = rio_uevent,
 };
 
 /**
diff --git a/drivers/rapidio/rio-sysfs.c b/drivers/rapidio/rio-sysfs.c
index 0c4473e..9331be6 100644
--- a/drivers/rapidio/rio-sysfs.c
+++ b/drivers/rapidio/rio-sysfs.c
@@ -84,6 +84,15 @@ static ssize_t lnext_show(struct device *dev,
return str - buf;
 }
 
+static ssize_t modalias_show(struct device *dev,
+struct device_attribute *attr, char *buf)
+{
+   struct rio_dev *rdev = to_rio_dev(dev);
+
+   return sprintf(buf, "rapidio:v%04Xd%04Xav%04Xad%04X\n",
+  rdev->vid, rdev->did, rdev->asm_vid, rdev->asm_did);
+}
+
 struct device_attribute rio_dev_attrs[] = {
__ATTR_RO(did),
__ATTR_RO(vid),
@@ -93,6 +102,7 @@ struct device_attribute rio_dev_attrs[] = {
__ATTR_RO(asm_rev),
__ATTR_RO(lprev),
__ATTR_RO(destid),
+   __ATTR_RO(modalias),
__ATTR_NULL,
 };
 
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
index b508016..4b0ac9c 100644
--- a/include/linux/mod_devicetable.h
+++ b/include/linux/mod_devicetable.h
@@ -577,4 +577,23 @@ struct mei_cl_device_id {
kernel_ulong_t driver_info;
 };
 
+/* RapidIO */
+
+#define RIO_ANY_ID 0x
+
+/**
+ * struct rio_device_id - RIO device identifier
+ * @did: RapidIO device ID
+ * @vid: RapidIO vendor ID
+ * @asm_did: RapidIO assembly device ID
+ * @asm_vid: RapidIO assembly vendor ID
+ *
+ * Identifies a RapidIO device based on both the device/vendor IDs and
+ * the assembly device/vendor IDs.
+ */
+struct rio_device_id {
+   __u16 did, vid;
+   __u16 asm_did, asm_vid;
+};
+
 #endif /* LINUX_MOD_DEVICETABLE_H */
diff --git a/include/linux/rio.h b/include/linux/rio.h
index 8d3db1b..e2faf7b 100644
--- a/include/linux/rio.h
+++ b/include/linux/rio.h
@@ -20,6 +20,7 @@
 #include 
 #include 
 #include 
+#include 
 #ifdef CONFIG_RAPIDIO_DMA_ENGINE
 #include 
 #endif
@@ -396,21 +397,6 @@ struct rio_driver {
 
 #defineto_rio_driver(drv) container_of(drv,struct rio_driver, driver)
 
-/**
- * struct rio_device_id - RIO device identifier
- * @did: RIO device ID
- * @vid: RIO vendor ID
- * @asm_did: RIO assembly device ID
- * @asm_vid: RIO assembly vendor ID
- *
- * Identifies a RIO device based on both the device/vendor IDs and
- * the assembly device/vendor IDs.
- */
-struct rio_device_id {
-   u16 did, vid;
-   u16 asm_did, asm_vid;
-};
-
 union rio_pw_msg {
struct {
u32 comptag;/* Component Tag CSR */
diff --git a/include/linux/rio_ids.h b/include/linux/rio_ids.h
index b66d13d..2543bc1 100644
--- a/include/linux/rio_ids.h
+++ b/include/linux/rio_ids.h
@@ -13,8 +13,6 @@
 #ifndef LINUX_RIO_IDS_H
 #define LINUX_RIO_IDS_H
 
-#define RIO_ANY_ID 0x
-
 #define RIO_VID_FREESCALE  0x0002
 #define RIO_DID_MPC85600x0003
 
diff --git a/scripts/mod/devicetable-offsets.c 
b/scripts/mod/d

[PATCH 4/7] rapidio/tsi721: convert to modular mport driver

2013-06-28 Thread Alexandre Bounine
This patch adds an option to build device driver for Tsi721 PCIe-to-SRIO bridge
device as a kernel module.

Currently this module cannot be unloaded because the existing RapidIO subsystem
code does not support dynamic removal of local RapidIO controllers (TODO).

Signed-off-by: Alexandre Bounine 
Cc: Matt Porter 
Cc: Li Yang 
Cc: Kumar Gala 
Cc: Andre van Herk 
Cc: Micha Nelissen 
Cc: Stef van Os 
Cc: Jean Delvare 
---
 drivers/rapidio/devices/Kconfig  |2 +-
 drivers/rapidio/devices/Makefile |7 +++
 drivers/rapidio/devices/tsi721.c |9 -
 drivers/rapidio/rio.c|1 +
 4 files changed, 9 insertions(+), 10 deletions(-)

diff --git a/drivers/rapidio/devices/Kconfig b/drivers/rapidio/devices/Kconfig
index 12a9d7f..c4cb087 100644
--- a/drivers/rapidio/devices/Kconfig
+++ b/drivers/rapidio/devices/Kconfig
@@ -3,7 +3,7 @@
 #
 
 config RAPIDIO_TSI721
-   bool "IDT Tsi721 PCI Express SRIO Controller support"
+   tristate "IDT Tsi721 PCI Express SRIO Controller support"
depends on RAPIDIO && PCIEPORTBUS
default "n"
---help---
diff --git a/drivers/rapidio/devices/Makefile b/drivers/rapidio/devices/Makefile
index 7b62860..9432c49 100644
--- a/drivers/rapidio/devices/Makefile
+++ b/drivers/rapidio/devices/Makefile
@@ -2,7 +2,6 @@
 # Makefile for RapidIO devices
 #
 
-obj-$(CONFIG_RAPIDIO_TSI721)   += tsi721.o
-ifeq ($(CONFIG_RAPIDIO_DMA_ENGINE),y)
-obj-$(CONFIG_RAPIDIO_TSI721)   += tsi721_dma.o
-endif
+obj-$(CONFIG_RAPIDIO_TSI721)   += tsi721_mport.o
+tsi721_mport-y := tsi721.o
+tsi721_mport-$(CONFIG_RAPIDIO_DMA_ENGINE) += tsi721_dma.o
diff --git a/drivers/rapidio/devices/tsi721.c b/drivers/rapidio/devices/tsi721.c
index a8b2c23..ff7cbf2 100644
--- a/drivers/rapidio/devices/tsi721.c
+++ b/drivers/rapidio/devices/tsi721.c
@@ -2515,9 +2515,8 @@ static int __init tsi721_init(void)
return pci_register_driver(&tsi721_driver);
 }
 
-static void __exit tsi721_exit(void)
-{
-   pci_unregister_driver(&tsi721_driver);
-}
-
 device_initcall(tsi721_init);
+
+MODULE_DESCRIPTION("IDT Tsi721 PCIExpress-to-SRIO bridge driver");
+MODULE_AUTHOR("Integrated Device Technology, Inc.");
+MODULE_LICENSE("GPL");
diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c
index 5eb727c..2054b62 100644
--- a/drivers/rapidio/rio.c
+++ b/drivers/rapidio/rio.c
@@ -1911,6 +1911,7 @@ int rio_register_mport(struct rio_mport *port)
pr_debug("RIO: %s %s id=%d\n", __func__, port->name, port->id);
return 0;
 }
+EXPORT_SYMBOL_GPL(rio_register_mport);
 
 EXPORT_SYMBOL_GPL(rio_local_get_device_id);
 EXPORT_SYMBOL_GPL(rio_get_device);
-- 
1.7.8.4

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH 0/7] rapidio: modularize rapidio subsystem

2013-06-28 Thread Alexandre Bounine
The following set of patches modifies kernel RapidIO subsystem to enable build
and use of its components as loadable kernel modules. Combinations of statically
linked and modular components are also supported.

For this release full RapidIO subsystem modularization is implemented for
x86-based platforms. For PowerPC platforms (mostly MPC85xx) RapidIO core and
the mport driver (fsl_rio.c) still have only statically linked build option
while other components (enumerator and switch drivers) can be built as kernel
modules. This is not a significant limitation for embedded PowerPC platforms
because they use on-chip RapidIO controllers. For PowerPC platforms that may use
an external PCIe RapidIO controller (e.g. Tsi721) an additional patch will be
provided later.

This set of patches is based on the current linux-next code tree that contains
previously submitted patches for modularized enumeration/discovery method.

Cc: Matt Porter 
Cc: Li Yang 
Cc: Kumar Gala 
Cc: Andre van Herk 
Cc: Micha Nelissen 
Cc: Stef van Os 
Cc: Jean Delvare 

Alexandre Bounine (7):
  rapidio: convert switch drivers to modules
  rapidio/rionet: rework driver initialization and removal
  rapidio: update enumerator registration mechanism
  rapidio/tsi721: convert to modular mport driver
  rapidio: add modular build option for the subsystem core
  rapidio: add udev notification
  rapidio: documentation update

 Documentation/rapidio/rapidio.txt   |   98 ++-
 Documentation/rapidio/sysfs.txt |1 +
 arch/x86/Kconfig|4 +-
 drivers/net/rionet.c|  103 ++--
 drivers/rapidio/Kconfig |5 +
 drivers/rapidio/Makefile|4 +-
 drivers/rapidio/devices/Kconfig |2 +-
 drivers/rapidio/devices/Makefile|7 +-
 drivers/rapidio/devices/tsi721.c|9 +-
 drivers/rapidio/rio-driver.c|   18 ++
 drivers/rapidio/rio-scan.c  |  172 +
 drivers/rapidio/rio-sysfs.c |   31 +--
 drivers/rapidio/rio.c   |  490 ---
 drivers/rapidio/rio.h   |   44 +---
 drivers/rapidio/switches/Kconfig|   12 +-
 drivers/rapidio/switches/idt_gen2.c |   98 ++--
 drivers/rapidio/switches/idtcps.c   |   86 +--
 drivers/rapidio/switches/tsi568.c   |   71 +-
 drivers/rapidio/switches/tsi57x.c   |   81 +-
 include/asm-generic/vmlinux.lds.h   |7 -
 include/linux/mod_devicetable.h |   19 ++
 include/linux/rio.h |   82 +++---
 include/linux/rio_ids.h |2 -
 scripts/mod/devicetable-offsets.c   |6 +
 scripts/mod/file2alias.c|   20 ++
 25 files changed, 998 insertions(+), 474 deletions(-)

-- 
1.7.8.4

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH] rapidio/switches: remove tsi500 driver

2013-05-09 Thread Alexandre Bounine
Remove the driver for Tsi500 Parallel RapidIO switch because this device is
not available for several years. Since the first introduction of Tsi500,
the parallel RapidIO interface was replaced by the serial RapidIO (sRIO)
and therefore there is no value in keeping this driver.

Signed-off-by: Alexandre Bounine 
Cc: Matt Porter 
Cc: Li Yang 
Cc: Kumar Gala 
---
 drivers/rapidio/switches/Kconfig  |7 ---
 drivers/rapidio/switches/Makefile |1 -
 drivers/rapidio/switches/tsi500.c |   78 -
 3 files changed, 0 insertions(+), 86 deletions(-)
 delete mode 100644 drivers/rapidio/switches/tsi500.c

diff --git a/drivers/rapidio/switches/Kconfig b/drivers/rapidio/switches/Kconfig
index f47fee5..62d4a06 100644
--- a/drivers/rapidio/switches/Kconfig
+++ b/drivers/rapidio/switches/Kconfig
@@ -26,10 +26,3 @@ config RAPIDIO_CPS_GEN2
default n
---help---
  Includes support for ITD CPS Gen.2 serial RapidIO switches.
-
-config RAPIDIO_TSI500
-   bool "Tsi500 Parallel RapidIO switch support"
-   depends on RAPIDIO
-   default n
-   ---help---
- Includes support for IDT Tsi500 parallel RapidIO switch.
diff --git a/drivers/rapidio/switches/Makefile 
b/drivers/rapidio/switches/Makefile
index c4d3acc..051cc6b 100644
--- a/drivers/rapidio/switches/Makefile
+++ b/drivers/rapidio/switches/Makefile
@@ -5,5 +5,4 @@
 obj-$(CONFIG_RAPIDIO_TSI57X)   += tsi57x.o
 obj-$(CONFIG_RAPIDIO_CPS_XX)   += idtcps.o
 obj-$(CONFIG_RAPIDIO_TSI568)   += tsi568.o
-obj-$(CONFIG_RAPIDIO_TSI500)   += tsi500.o
 obj-$(CONFIG_RAPIDIO_CPS_GEN2) += idt_gen2.o
diff --git a/drivers/rapidio/switches/tsi500.c 
b/drivers/rapidio/switches/tsi500.c
deleted file mode 100644
index 914eddd..000
--- a/drivers/rapidio/switches/tsi500.c
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * RapidIO Tsi500 switch support
- *
- * Copyright 2009-2010 Integrated Device Technology, Inc.
- * Alexandre Bounine 
- *  - Modified switch operations initialization.
- *
- * Copyright 2005 MontaVista Software, Inc.
- * Matt Porter 
- *
- * 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 
-#include 
-#include 
-#include "../rio.h"
-
-static int
-tsi500_route_add_entry(struct rio_mport *mport, u16 destid, u8 hopcount, u16 
table, u16 route_destid, u8 route_port)
-{
-   int i;
-   u32 offset = 0x1 + 0xa00 + ((route_destid / 2)&~0x3);
-   u32 result;
-
-   if (table == 0xff) {
-   rio_mport_read_config_32(mport, destid, hopcount, offset, 
&result);
-   result &= ~(0xf << (4*(route_destid & 0x7)));
-   for (i=0;i<4;i++)
-   rio_mport_write_config_32(mport, destid, hopcount, 
offset + (0x2*i), result | (route_port << (4*(route_destid & 0x7;
-   }
-   else {
-   rio_mport_read_config_32(mport, destid, hopcount, offset + 
(0x2*table), &result);
-   result &= ~(0xf << (4*(route_destid & 0x7)));
-   rio_mport_write_config_32(mport, destid, hopcount, offset + 
(0x2*table), result | (route_port << (4*(route_destid & 0x7;
-   }
-
-   return 0;
-}
-
-static int
-tsi500_route_get_entry(struct rio_mport *mport, u16 destid, u8 hopcount, u16 
table, u16 route_destid, u8 *route_port)
-{
-   int ret = 0;
-   u32 offset = 0x1 + 0xa00 + ((route_destid / 2)&~0x3);
-   u32 result;
-
-   if (table == 0xff)
-   rio_mport_read_config_32(mport, destid, hopcount, offset, 
&result);
-   else
-   rio_mport_read_config_32(mport, destid, hopcount, offset + 
(0x2*table), &result);
-
-   result &= 0xf << (4*(route_destid & 0x7));
-   *route_port = result >> (4*(route_destid & 0x7));
-   if (*route_port > 3)
-   ret = -1;
-
-   return ret;
-}
-
-static int tsi500_switch_init(struct rio_dev *rdev, int do_enum)
-{
-   pr_debug("RIO: %s for %s\n", __func__, rio_name(rdev));
-   rdev->rswitch->add_entry = tsi500_route_add_entry;
-   rdev->rswitch->get_entry = tsi500_route_get_entry;
-   rdev->rswitch->clr_table = NULL;
-   rdev->rswitch->set_domain = NULL;
-   rdev->rswitch->get_domain = NULL;
-   rdev->rswitch->em_init = NULL;
-   rdev->rswitch->em_handle = NULL;
-
-   return 0;
-}
-
-DECLARE_RIO_SWITCH_INIT(RIO_VID_TUNDRA, RIO_DID_TSI500, tsi500_switch_init);
-- 
1.7.8.4

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH] rapidio/tsi721: fix bug in MSI interrupt handling

2013-05-08 Thread Alexandre Bounine
Fix bug in MSI interrupt handling which causes loss of event notifications.

Typical indication of lost MSI interrupts are stalled message and doorbell
transfers between RapidIO endpoints. To avoid loss of MSI interrupts all
interrupts from the device must be disabled on entering the interrupt handler
routine and re-enabled when exiting it. Re-enabling device interrupts will
trigger new MSI message(s) if Tsi721 registered new events since entering
interrupt handler routine.

This patch is applicable to kernel versions starting from v3.2.

Signed-off-by: Alexandre Bounine 
Cc: Matt Porter 
---
 drivers/rapidio/devices/tsi721.c |   12 
 1 files changed, 12 insertions(+), 0 deletions(-)

diff --git a/drivers/rapidio/devices/tsi721.c b/drivers/rapidio/devices/tsi721.c
index 6faba40..a8b2c23 100644
--- a/drivers/rapidio/devices/tsi721.c
+++ b/drivers/rapidio/devices/tsi721.c
@@ -471,6 +471,10 @@ static irqreturn_t tsi721_irqhandler(int irq, void *ptr)
u32 intval;
u32 ch_inte;
 
+   /* For MSI mode disable all device-level interrupts */
+   if (priv->flags & TSI721_USING_MSI)
+   iowrite32(0, priv->regs + TSI721_DEV_INTE);
+
dev_int = ioread32(priv->regs + TSI721_DEV_INT);
if (!dev_int)
return IRQ_NONE;
@@ -560,6 +564,14 @@ static irqreturn_t tsi721_irqhandler(int irq, void *ptr)
}
}
 #endif
+
+   /* For MSI mode re-enable device-level interrupts */
+   if (priv->flags & TSI721_USING_MSI) {
+   dev_int = TSI721_DEV_INT_SR2PC_CH | TSI721_DEV_INT_SRIO |
+   TSI721_DEV_INT_SMSG_CH | TSI721_DEV_INT_BDMA_CH;
+   iowrite32(dev_int, priv->regs + TSI721_DEV_INTE);
+   }
+
return IRQ_HANDLED;
 }
 
-- 
1.7.8.4

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH v2 1/3] rapidio: make enumeration/discovery configurable

2013-04-30 Thread Alexandre Bounine
Rework to implement RapidIO enumeration/discovery method selection
combined with ability to use enumeration/discovery as a kernel module.

This patch adds ability to introduce new RapidIO enumeration/discovery methods
using kernel configuration options. Configuration option mechanism allows to 
select
statically linked or modular enumeration/discovery method from the list of 
existing
methods or use external modules.
If a modular enumeration/discovery is selected each RapidIO mport device can
have its own method attached to it.

The existing enumeration/discovery code was updated to be used as statically
linked or modular method. This configuration option is named "Basic
enumeration/discovery" method.

Several common routines have been moved from rio-scan.c to make them available
to other enumeration methods and reduce number of exported symbols.

Signed-off-by: Alexandre Bounine 
Cc: Matt Porter 
Cc: Li Yang 
Cc: Kumar Gala 
Cc: Andre van Herk 
Cc: Micha Nelissen 
---
 drivers/rapidio/Kconfig  |   20 
 drivers/rapidio/Makefile |3 +-
 drivers/rapidio/rio-driver.c |7 ++
 drivers/rapidio/rio-scan.c   |  166 
 drivers/rapidio/rio.c|  222 --
 drivers/rapidio/rio.h|   11 ++-
 include/linux/rio.h  |   13 +++-
 include/linux/rio_drv.h  |1 +
 8 files changed, 304 insertions(+), 139 deletions(-)

diff --git a/drivers/rapidio/Kconfig b/drivers/rapidio/Kconfig
index 6194d35..5ab0564 100644
--- a/drivers/rapidio/Kconfig
+++ b/drivers/rapidio/Kconfig
@@ -47,4 +47,24 @@ config RAPIDIO_DEBUG
 
  If you are unsure about this, say N here.
 
+choice
+   prompt "Enumeration method"
+   depends on RAPIDIO
+   default RAPIDIO_ENUM_BASIC
+   help
+ There are different enumeration and discovery mechanisms offered
+ for RapidIO subsystem. You may select single built-in method or
+ or any number of methods to be built as modules.
+ Selecting a built-in method disables use of loadable methods.
+
+ If unsure, select Basic built-in.
+
+config RAPIDIO_ENUM_BASIC
+   tristate "Basic"
+   help
+ This option includes basic RapidIO fabric enumeration and discovery
+ mechanism similar to one described in RapidIO specification Annex 1.
+
+endchoice
+
 source "drivers/rapidio/switches/Kconfig"
diff --git a/drivers/rapidio/Makefile b/drivers/rapidio/Makefile
index ec3fb81..3036702 100644
--- a/drivers/rapidio/Makefile
+++ b/drivers/rapidio/Makefile
@@ -1,7 +1,8 @@
 #
 # Makefile for RapidIO interconnect services
 #
-obj-y += rio.o rio-access.o rio-driver.o rio-scan.o rio-sysfs.o
+obj-y += rio.o rio-access.o rio-driver.o rio-sysfs.o
+obj-$(CONFIG_RAPIDIO_ENUM_BASIC) += rio-scan.o
 
 obj-$(CONFIG_RAPIDIO)  += switches/
 obj-$(CONFIG_RAPIDIO)  += devices/
diff --git a/drivers/rapidio/rio-driver.c b/drivers/rapidio/rio-driver.c
index 0f4a53b..55850bb 100644
--- a/drivers/rapidio/rio-driver.c
+++ b/drivers/rapidio/rio-driver.c
@@ -164,6 +164,13 @@ void rio_unregister_driver(struct rio_driver *rdrv)
driver_unregister(&rdrv->driver);
 }
 
+void rio_attach_device(struct rio_dev *rdev)
+{
+   rdev->dev.bus = &rio_bus_type;
+   rdev->dev.parent = &rio_bus;
+}
+EXPORT_SYMBOL_GPL(rio_attach_device);
+
 /**
  *  rio_match_bus - Tell if a RIO device structure has a matching RIO driver 
device id structure
  *  @dev: the standard device structure to match against
diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c
index a965acd..7bdc674 100644
--- a/drivers/rapidio/rio-scan.c
+++ b/drivers/rapidio/rio-scan.c
@@ -37,12 +37,8 @@
 
 #include "rio.h"
 
-LIST_HEAD(rio_devices);
-
 static void rio_init_em(struct rio_dev *rdev);
 
-DEFINE_SPINLOCK(rio_global_list_lock);
-
 static int next_destid = 0;
 static int next_comptag = 1;
 
@@ -327,127 +323,6 @@ static int rio_is_switch(struct rio_dev *rdev)
 }
 
 /**
- * rio_switch_init - Sets switch operations for a particular vendor switch
- * @rdev: RIO device
- * @do_enum: Enumeration/Discovery mode flag
- *
- * Searches the RIO switch ops table for known switch types. If the vid
- * and did match a switch table entry, then call switch initialization
- * routine to setup switch-specific routines.
- */
-static void rio_switch_init(struct rio_dev *rdev, int do_enum)
-{
-   struct rio_switch_ops *cur = __start_rio_switch_ops;
-   struct rio_switch_ops *end = __end_rio_switch_ops;
-
-   while (cur < end) {
-   if ((cur->vid == rdev->vid) && (cur->did == rdev->did)) {
-   pr_debug("RIO: calling init routine for %s\n",
-rio_name(rdev));
-   cur->init_hook(rdev, do_enum);
-   break;
-   }
-   cur++;
-   }
-
-   if ((

[PATCH v2 2/3] rapidio: add enumeration/discovery start from user space

2013-04-30 Thread Alexandre Bounine
Add RapidIO enumeration/discovery start from user space.
User space start allows to defer RapidIO fabric scan until the moment when all
participating endpoints are initialized avoiding mandatory synchronized start
of all endpoints (which may be challenging in systems with large number of
RapidIO endpoints).

Signed-off-by: Alexandre Bounine 
Cc: Matt Porter 
Cc: Li Yang 
Cc: Kumar Gala 
Cc: Andre van Herk 
Cc: Micha Nelissen 
---
 drivers/rapidio/rio-driver.c |1 +
 drivers/rapidio/rio-scan.c   |   24 +++--
 drivers/rapidio/rio-sysfs.c  |   45 ++
 drivers/rapidio/rio.c|   28 -
 drivers/rapidio/rio.h|2 +
 include/linux/rio.h  |9 ++-
 6 files changed, 102 insertions(+), 7 deletions(-)

diff --git a/drivers/rapidio/rio-driver.c b/drivers/rapidio/rio-driver.c
index 55850bb..a0c8755 100644
--- a/drivers/rapidio/rio-driver.c
+++ b/drivers/rapidio/rio-driver.c
@@ -207,6 +207,7 @@ struct bus_type rio_bus_type = {
.name = "rapidio",
.match = rio_match_bus,
.dev_attrs = rio_dev_attrs,
+   .bus_attrs = rio_bus_attrs,
.probe = rio_device_probe,
.remove = rio_device_remove,
 };
diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c
index 7bdc674..4c15dbf 100644
--- a/drivers/rapidio/rio-scan.c
+++ b/drivers/rapidio/rio-scan.c
@@ -1134,19 +1134,30 @@ static void rio_pw_enable(struct rio_mport *port, int 
enable)
 /**
  * rio_enum_mport- Start enumeration through a master port
  * @mport: Master port to send transactions
+ * @flags: Enumeration control flags
  *
  * Starts the enumeration process. If somebody has enumerated our
  * master port device, then give up. If not and we have an active
  * link, then start recursive peer enumeration. Returns %0 if
  * enumeration succeeds or %-EBUSY if enumeration fails.
  */
-int rio_enum_mport(struct rio_mport *mport)
+int rio_enum_mport(struct rio_mport *mport, u32 flags)
 {
struct rio_net *net = NULL;
int rc = 0;
 
printk(KERN_INFO "RIO: enumerate master port %d, %s\n", mport->id,
   mport->name);
+
+   /*
+* To avoid multiple start requests (repeat enumeration is not supported
+* by this method) check if enumeration/discovery was performed for this
+* mport: if mport was added into the list of mports for a net exit
+* with error.
+*/
+   if (mport->nnode.next || mport->nnode.prev)
+   return -EBUSY;
+
/* If somebody else enumerated our master port device, bail. */
if (rio_enum_host(mport) < 0) {
printk(KERN_INFO
@@ -1236,14 +1247,16 @@ static void rio_build_route_tables(struct rio_net *net)
 /**
  * rio_disc_mport- Start discovery through a master port
  * @mport: Master port to send transactions
+ * @flags: discovery control flags
  *
  * Starts the discovery process. If we have an active link,
- * then wait for the signal that enumeration is complete.
+ * then wait for the signal that enumeration is complete (if wait
+ * is allowed).
  * When enumeration completion is signaled, start recursive
  * peer discovery. Returns %0 if discovery succeeds or %-EBUSY
  * on failure.
  */
-int rio_disc_mport(struct rio_mport *mport)
+int rio_disc_mport(struct rio_mport *mport, u32 flags)
 {
struct rio_net *net = NULL;
unsigned long to_end;
@@ -1253,6 +1266,11 @@ int rio_disc_mport(struct rio_mport *mport)
 
/* If master port has an active link, allocate net and discover peers */
if (rio_mport_is_active(mport)) {
+   if (rio_enum_complete(mport))
+   goto enum_done;
+   else if (flags & RIO_SCAN_ENUM_NO_WAIT)
+   return -EAGAIN;
+
pr_debug("RIO: wait for enumeration to complete...\n");
 
to_end = jiffies + CONFIG_RAPIDIO_DISC_TIMEOUT * HZ;
diff --git a/drivers/rapidio/rio-sysfs.c b/drivers/rapidio/rio-sysfs.c
index 4dbe360..66d4acd 100644
--- a/drivers/rapidio/rio-sysfs.c
+++ b/drivers/rapidio/rio-sysfs.c
@@ -285,3 +285,48 @@ void rio_remove_sysfs_dev_files(struct rio_dev *rdev)
rdev->rswitch->sw_sysfs(rdev, RIO_SW_SYSFS_REMOVE);
}
 }
+
+static ssize_t bus_scan_store(struct bus_type *bus, const char *buf,
+   size_t count)
+{
+   long val;
+   struct rio_mport *port = NULL;
+   int rc;
+
+   if (kstrtol(buf, 0, &val) < 0)
+   return -EINVAL;
+
+   if (val == RIO_MPORT_ANY) {
+   rc = rio_init_mports();
+   goto exit;
+   }
+
+   if (val < 0 || val >= RIO_MAX_MPORTS)
+   return -EINVAL;
+
+   port = rio_find_mport((int)val);
+
+   if (!port) {
+   pr_debug("RIO: %s: mport_%d not available\n",
+__func__, (

[PATCH v2 3/3] rapidio: documentation update for enumeration changes

2013-04-30 Thread Alexandre Bounine
Update RapidIO documentation to reflect changes made to enumeration/discovery
build configuration and user space triggering mechanism.

Signed-off-by: Alexandre Bounine 
Cc: Matt Porter 
Cc: Li Yang 
Cc: Kumar Gala 
Cc: Andre van Herk 
Cc: Micha Nelissen 
---
 Documentation/rapidio/rapidio.txt |  128 +---
 Documentation/rapidio/sysfs.txt   |   17 +
 2 files changed, 134 insertions(+), 11 deletions(-)

diff --git a/Documentation/rapidio/rapidio.txt 
b/Documentation/rapidio/rapidio.txt
index c75694b..a9c16c9 100644
--- a/Documentation/rapidio/rapidio.txt
+++ b/Documentation/rapidio/rapidio.txt
@@ -79,20 +79,63 @@ master port that is used to communicate with devices within 
the network.
 In order to initialize the RapidIO subsystem, a platform must initialize and
 register at least one master port within the RapidIO network. To register mport
 within the subsystem controller driver initialization code calls function
-rio_register_mport() for each available master port. After all active master
-ports are registered with a RapidIO subsystem, the rio_init_mports() routine
-is called to perform enumeration and discovery.
+rio_register_mport() for each available master port.
 
-In the current PowerPC-based implementation a subsys_initcall() is specified to
-perform controller initialization and mport registration. At the end it 
directly
-calls rio_init_mports() to execute RapidIO enumeration and discovery.
+RapidIO subsystem uses subsys_initcall() or device_initcall() to perform
+controller initialization (depending on controller device type).
+
+After all active master ports are registered with a RapidIO subsystem,
+an enumeration and/or discovery routine may be called automatically or
+by user-space command.
 
 4. Enumeration and Discovery
 
 
-When rio_init_mports() is called it scans a list of registered master ports and
-calls an enumeration or discovery routine depending on the configured role of a
-master port: host or agent.
+4.1 Overview
+
+
+RapidIO subsystem configuration options allow users to specify enumeration and
+discovery methods as statically linked components or loadable modules.
+An enumeration/discovery method implementation and available input parameters
+define how any given method can be attached to available RapidIO mports:
+simply to all available mports OR individually to the specified mport device.
+
+Depending on selected enumeration/discovery build configuration, there are
+several methods to initiate an enumeration and/or discovery process:
+
+  (a) Statically linked enumeration and discovery process can be started
+  automatically during kernel initialization time using corresponding module
+  parameters. This was the original method used since introduction of RapidIO
+  subsystem. Now this method relies on enumerator module parameter which is
+  'rio-scan.scan' for existing basic enumeration/discovery method.
+  When automatic start of enumeration/discovery is used a user has to ensure
+  that all discovering endpoints are started before the enumerating endpoint
+  and are waiting for enumeration to be completed.
+  Configuration option CONFIG_RAPIDIO_DISC_TIMEOUT defines time that 
discovering
+  endpoint waits for enumeration to be completed. If the specified timeout
+  expires the discovery process is terminated without obtaining RapidIO network
+  information. NOTE: a timed out discovery process may be restarted later using
+  a user-space command as it is described later if the given endpoint was
+  enumerated successfully.
+
+  (b) Statically linked enumeration and discovery process can be started by
+  a command from user space. This initiation method provides more flexibility
+  for a system startup compared to the option (a) above. After all 
participating
+  endpoints have been successfully booted, an enumeration process shall be
+  started first by issuing a user-space command, after an enumeration is
+  completed a discovery process can be started on all remaining endpoints.
+
+  (c) Modular enumeration and discovery process can be started by a command 
from
+  user space. After an enumeration/discovery module is loaded, a network scan
+  process can be started by issuing a user-space command.
+  Similar to the option (b) above, an enumerator has to be started first.
+
+  (d) Modular enumeration and discovery process can be started by a module
+  initialization routine. In this case an enumerating module shall be loaded
+  first.
+
+When a network scan process is started it calls an enumeration or discovery
+routine depending on the configured role of a master port: host or agent.
 
 Enumeration is performed by a master port if it is configured as a host port by
 assigning a host device ID greater than or equal to zero. A host device ID is
@@ -104,8 +147,58 @@ for it.
 The enumeration and discovery routines use RapidIO maintenance transactions
 to access the configuration space 

[PATCH v2 0/3] rapidio: changes to enumeration/discovery

2013-04-30 Thread Alexandre Bounine
Systems that use RapidIO fabric may need to implement their own enumeration
and discovery methods which are better suitable for needs of a target
application.

The following set of patches is intended to simplify process of introduction of
new RapidIO fabric enumeration/discovery methods.

The first patch offers ability to add new RapidIO enumeration/discovery methods
using kernel configuration options. This new configuration option mechanism
allows to select statically linked or modular enumeration/discovery method(s)
from the list of existing methods or use external module(s).

This patch also updates the currently existing enumeration/discovery code to be
used as a statically linked or modular method. The corresponding configuration
option is named "Basic enumeration/discovery" method. This is the only one
configuration option available today but new methods are expected to be
introduced after adoption of provided patches.

The second patch address a long time complaint of RapidIO subsystem users
regarding fabric enumeration/discovery start sequence. Existing implementation
offers only a boot-time enumeration/discovery start which requires synchronized
boot of all endpoints in RapidIO network. While it works for small closed
configurations with limited number of endpoints, using this approach in systems
with large number of endpoints is quite challenging.

To eliminate requirement for synchronized start the second patch introduces
RapidIO enumeration/discovery start from user space.

For compatibility with the existing RapidIO subsystem implementation, automatic
boot time enumeration/discovery start can be configured in by specifying
"rio-scan.scan=1" command line parameter if statically linked basic enumeration
method is selected.

Changes since v1:
(1) Addressed comments made by Andrew Morton for v1:
  - reworked enumeration/discovery module initialization
  - added locking for list of mport devices
  - made mport list static
  - removed CONFIG_RAPIDIO_ENUM_AUTO option: not needed with new
module initialization
  - added default value for "Enumeration method" choice in Kconfig

Cc: Matt Porter 
Cc: Li Yang 
Cc: Kumar Gala 
Cc: Andre van Herk 
Cc: Micha Nelissen 

Alexandre Bounine (3):
  rapidio: make enumeration/discovery configurable
  rapidio: add enumeration/discovery start from user space
  rapidio: documentation update for enumeration changes

 Documentation/rapidio/rapidio.txt |  128 ++--
 Documentation/rapidio/sysfs.txt   |   17 +++
 drivers/rapidio/Kconfig   |   20 +++
 drivers/rapidio/Makefile  |3 +-
 drivers/rapidio/rio-driver.c  |8 ++
 drivers/rapidio/rio-scan.c|  190 +---
 drivers/rapidio/rio-sysfs.c   |   45 +++
 drivers/rapidio/rio.c |  246 +++-
 drivers/rapidio/rio.h |   13 ++-
 include/linux/rio.h   |   18 +++-
 include/linux/rio_drv.h   |1 +
 11 files changed, 536 insertions(+), 153 deletions(-)

-- 
1.7.8.4

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH 1/3] rapidio: make enumeration/discovery configurable

2013-04-24 Thread Alexandre Bounine
Rework to implement RapidIO enumeration/discovery method selection
combined with ability to use enumeration/discovery as a kernel module.

This patch adds ability to introduce new RapidIO enumeration/discovery methods
using kernel configuration options or loadable modules. Configuration option
mechanism allows to select built-in or modular enumeration/discovery method from
the list of existing methods or use external modules.
If a modular enumeration/discovery is selected each RapidIO mport device can
have its own method attached to it.

The currently existing enumeration/discovery code was updated to be used
as built-in or modular method. This configuration option is named "Basic
enumeration/discovery" method.

Several common routines have been moved from rio-scan.c to make them available
to other enumeration methods and reduce number of exported symbols.

Signed-off-by: Alexandre Bounine 
Cc: Matt Porter 
Cc: Li Yang 
Cc: Kumar Gala 
Cc: Andre van Herk 
Cc: Micha Nelissen 
---
 drivers/rapidio/Kconfig  |   19 
 drivers/rapidio/Makefile |3 +-
 drivers/rapidio/rio-driver.c |7 ++
 drivers/rapidio/rio-scan.c   |  171 +-
 drivers/rapidio/rio.c|  212 +-
 drivers/rapidio/rio.h|   10 ++-
 include/linux/rio.h  |   12 +++
 include/linux/rio_drv.h  |1 +
 8 files changed, 300 insertions(+), 135 deletions(-)

diff --git a/drivers/rapidio/Kconfig b/drivers/rapidio/Kconfig
index 6194d35..e392cab 100644
--- a/drivers/rapidio/Kconfig
+++ b/drivers/rapidio/Kconfig
@@ -47,4 +47,23 @@ config RAPIDIO_DEBUG
 
  If you are unsure about this, say N here.
 
+choice
+   prompt "Enumeration method"
+   depends on RAPIDIO
+   help
+ There are different enumeration and discovery mechanisms offered
+ for RapidIO subsystem. You may select single built-in method or
+ or any number of methods to be built as modules.
+ Selecting a built-in method disables use of loadable methods.
+
+ If unsure, select Basic built-in.
+
+config RAPIDIO_ENUM_BASIC
+   tristate "Basic"
+   help
+ This option includes basic RapidIO fabric enumeration and discovery
+ mechanism similar to one described in RapidIO specification Annex 1.
+
+endchoice
+
 source "drivers/rapidio/switches/Kconfig"
diff --git a/drivers/rapidio/Makefile b/drivers/rapidio/Makefile
index ec3fb81..3036702 100644
--- a/drivers/rapidio/Makefile
+++ b/drivers/rapidio/Makefile
@@ -1,7 +1,8 @@
 #
 # Makefile for RapidIO interconnect services
 #
-obj-y += rio.o rio-access.o rio-driver.o rio-scan.o rio-sysfs.o
+obj-y += rio.o rio-access.o rio-driver.o rio-sysfs.o
+obj-$(CONFIG_RAPIDIO_ENUM_BASIC) += rio-scan.o
 
 obj-$(CONFIG_RAPIDIO)  += switches/
 obj-$(CONFIG_RAPIDIO)  += devices/
diff --git a/drivers/rapidio/rio-driver.c b/drivers/rapidio/rio-driver.c
index 0f4a53b..55850bb 100644
--- a/drivers/rapidio/rio-driver.c
+++ b/drivers/rapidio/rio-driver.c
@@ -164,6 +164,13 @@ void rio_unregister_driver(struct rio_driver *rdrv)
driver_unregister(&rdrv->driver);
 }
 
+void rio_attach_device(struct rio_dev *rdev)
+{
+   rdev->dev.bus = &rio_bus_type;
+   rdev->dev.parent = &rio_bus;
+}
+EXPORT_SYMBOL_GPL(rio_attach_device);
+
 /**
  *  rio_match_bus - Tell if a RIO device structure has a matching RIO driver 
device id structure
  *  @dev: the standard device structure to match against
diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c
index a965acd..33fc332 100644
--- a/drivers/rapidio/rio-scan.c
+++ b/drivers/rapidio/rio-scan.c
@@ -37,12 +37,8 @@
 
 #include "rio.h"
 
-LIST_HEAD(rio_devices);
-
 static void rio_init_em(struct rio_dev *rdev);
 
-DEFINE_SPINLOCK(rio_global_list_lock);
-
 static int next_destid = 0;
 static int next_comptag = 1;
 
@@ -327,127 +323,6 @@ static int rio_is_switch(struct rio_dev *rdev)
 }
 
 /**
- * rio_switch_init - Sets switch operations for a particular vendor switch
- * @rdev: RIO device
- * @do_enum: Enumeration/Discovery mode flag
- *
- * Searches the RIO switch ops table for known switch types. If the vid
- * and did match a switch table entry, then call switch initialization
- * routine to setup switch-specific routines.
- */
-static void rio_switch_init(struct rio_dev *rdev, int do_enum)
-{
-   struct rio_switch_ops *cur = __start_rio_switch_ops;
-   struct rio_switch_ops *end = __end_rio_switch_ops;
-
-   while (cur < end) {
-   if ((cur->vid == rdev->vid) && (cur->did == rdev->did)) {
-   pr_debug("RIO: calling init routine for %s\n",
-rio_name(rdev));
-   cur->init_hook(rdev, do_enum);
-   break;
-   }
-   cur++;
-   }
-
-   if ((cu

[PATCH 3/3] rapidio: documentation update for enumeration changes

2013-04-24 Thread Alexandre Bounine
Update RapidIO documentation to reflect changes made to enumeration/discovery
build configuration and user space triggering mechanism.

Signed-off-by: Alexandre Bounine 
Cc: Matt Porter 
Cc: Li Yang 
Cc: Kumar Gala 
Cc: Andre van Herk 
Cc: Micha Nelissen 
---
 Documentation/rapidio/rapidio.txt |  137 ++---
 Documentation/rapidio/sysfs.txt   |   17 +
 2 files changed, 143 insertions(+), 11 deletions(-)

diff --git a/Documentation/rapidio/rapidio.txt 
b/Documentation/rapidio/rapidio.txt
index c75694b..d97576f 100644
--- a/Documentation/rapidio/rapidio.txt
+++ b/Documentation/rapidio/rapidio.txt
@@ -79,20 +79,64 @@ master port that is used to communicate with devices within 
the network.
 In order to initialize the RapidIO subsystem, a platform must initialize and
 register at least one master port within the RapidIO network. To register mport
 within the subsystem controller driver initialization code calls function
-rio_register_mport() for each available master port. After all active master
-ports are registered with a RapidIO subsystem, the rio_init_mports() routine
-is called to perform enumeration and discovery.
+rio_register_mport() for each available master port.
 
-In the current PowerPC-based implementation a subsys_initcall() is specified to
-perform controller initialization and mport registration. At the end it 
directly
-calls rio_init_mports() to execute RapidIO enumeration and discovery.
+RapidIO subsystem uses subsys_initcall() or device_initcall() to perform
+controller initialization (depending on controller device type).
+
+After all active master ports are registered with a RapidIO subsystem,
+an enumeration and/or discovery routine may be called automatically or
+by user-space command.
 
 4. Enumeration and Discovery
 
 
-When rio_init_mports() is called it scans a list of registered master ports and
-calls an enumeration or discovery routine depending on the configured role of a
-master port: host or agent.
+4.1 Overview
+
+
+RapidIO subsystem configuration options allow users to specify enumeration and
+discovery methods as built-in components or loadable modules.
+For built-in options only one method can be selected for all mports in a 
system.
+Selecting a modular build option for enumeration/discovery allows to use
+different enumerators attached to available mport device individually.
+
+Depending on selected enumeration/discovery build configuration, there are
+several methods to initiate enumeration and/or discovery process:
+
+  (a) Built-in enumeration and discovery process can be started automatically
+  during kernel initialization time. This is the original method used since
+  introduction of RapidIO subsystem. This method relieson kernel 
initcall that
+  calls rio_init_mports() routine after all available mports have been
+  registered. When automatic start of enumeration/discovery is used a user has
+  to ensure that all discovering endpoints are started before the enumerating
+  endpoint and are waiting for enumeration to be completed.
+  Configuration option CONFIG_RAPIDIO_DISC_TIMEOUT defines time that 
discovering
+  endpoint waits for enumeration to be completed. If the specified timeout
+  expires the discovery process is terminated without obtaining RapidIO network
+  information. NOTE: a timed out discovery process may be restarted later using
+  a user-space command as it is described later if the given endpoint was
+  enumerated successfully.
+
+  (b) Built-in enumeration and discovery process can be started by a command
+  from user space. This initiation method provides more freedom for system
+  startup compared to the option (a) above. After all participating endpoints
+  have been successfully booted, an enumeration process shall be started first
+  by issuing a user-space command, as soon as enumeration is completed
+  a discovery process can be started on all remaining endpoints.
+  Configuration option CONFIG_RAPIDIO_ENUM_AUTO defines which method will be
+  used to start a built-in enumeration and discovery process.
+
+  (c) Modular enumeration and discovery process can be started by a command 
from
+  user space. After an enumeration/discovery module is loaded, a network scan
+  process can be started by issuing a user-space command.
+  Similar to the option (b) above, an enumerator has to be started first.
+
+  (d) Modular enumeration and discovery process can be started by a module
+  initialization routine. As in the cases above an enumerating module shall be
+  loaded first.
+
+When a network scan process is started it calls an enumeration or discovery
+routine depending on the configured role of a master port: host or agent.
 
 Enumeration is performed by a master port if it is configured as a host port by
 assigning a host device ID greater than or equal to zero. A host device ID is
@@ -104,8 +148,57 @@ for it.
 The enumeration and discovery routines use RapidIO

[PATCH 2/3] rapidio: add enumeration/discovery start from user space

2013-04-24 Thread Alexandre Bounine
Add RapidIO enumeration/discovery start from user space.
User space start allows to defer RapidIO fabric scan until the moment when all
participating endpoints are initialized avoiding mandatory synchronized start
of all endpoints (which may be challenging in systems with large number of
RapidIO endpoints).

For compatibility with the existing RapidIO subsystem implementation, automatic
boot time enumeration/discovery start can be configured in by selecting
CONFIG_RAPIDIO_ENUM_AUTO option.

Signed-off-by: Alexandre Bounine 
Cc: Matt Porter 
Cc: Li Yang 
Cc: Kumar Gala 
Cc: Andre van Herk 
Cc: Micha Nelissen 
---
 drivers/rapidio/Kconfig  |9 
 drivers/rapidio/rio-driver.c |1 +
 drivers/rapidio/rio-scan.c   |   24 +++--
 drivers/rapidio/rio-sysfs.c  |   45 ++
 drivers/rapidio/rio.c|   26 ++-
 drivers/rapidio/rio.h|2 +
 include/linux/rio.h  |9 ++-
 7 files changed, 109 insertions(+), 7 deletions(-)

diff --git a/drivers/rapidio/Kconfig b/drivers/rapidio/Kconfig
index e392cab..8b7f92d 100644
--- a/drivers/rapidio/Kconfig
+++ b/drivers/rapidio/Kconfig
@@ -66,4 +66,13 @@ config RAPIDIO_ENUM_BASIC
 
 endchoice
 
+config RAPIDIO_ENUM_AUTO
+   bool "Automatic RapidIO enumeration/discovery start"
+   depends on RAPIDIO && RAPIDIO_ENUM_BASIC = y
+   help
+ Say Y if you want RapidIO subsystem to start fabric enumeration and
+ discovery automatically during kernel initialization time.
+ If you are unsure, say N here. You will be able to start RapidIO
+ fabric enumeration or discovery later by a user request.
+
 source "drivers/rapidio/switches/Kconfig"
diff --git a/drivers/rapidio/rio-driver.c b/drivers/rapidio/rio-driver.c
index 55850bb..a0c8755 100644
--- a/drivers/rapidio/rio-driver.c
+++ b/drivers/rapidio/rio-driver.c
@@ -207,6 +207,7 @@ struct bus_type rio_bus_type = {
.name = "rapidio",
.match = rio_match_bus,
.dev_attrs = rio_dev_attrs,
+   .bus_attrs = rio_bus_attrs,
.probe = rio_device_probe,
.remove = rio_device_remove,
 };
diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c
index 33fc332..3e371b1 100644
--- a/drivers/rapidio/rio-scan.c
+++ b/drivers/rapidio/rio-scan.c
@@ -1134,19 +1134,30 @@ static void rio_pw_enable(struct rio_mport *port, int 
enable)
 /**
  * rio_enum_mport- Start enumeration through a master port
  * @mport: Master port to send transactions
+ * @flags: Enumeration control flags
  *
  * Starts the enumeration process. If somebody has enumerated our
  * master port device, then give up. If not and we have an active
  * link, then start recursive peer enumeration. Returns %0 if
  * enumeration succeeds or %-EBUSY if enumeration fails.
  */
-int rio_enum_mport(struct rio_mport *mport)
+int rio_enum_mport(struct rio_mport *mport, u32 flags)
 {
struct rio_net *net = NULL;
int rc = 0;
 
printk(KERN_INFO "RIO: enumerate master port %d, %s\n", mport->id,
   mport->name);
+
+   /*
+* To avoid multiple start requests (repeat enumeration is not supported
+* by this method) check if enumeration/discovery was performed for this
+* mport: if mport was added into the list of mports for a net exit
+* with error.
+*/
+   if (mport->nnode.next || mport->nnode.prev)
+   return -EBUSY;
+
/* If somebody else enumerated our master port device, bail. */
if (rio_enum_host(mport) < 0) {
printk(KERN_INFO
@@ -1236,14 +1247,16 @@ static void rio_build_route_tables(struct rio_net *net)
 /**
  * rio_disc_mport- Start discovery through a master port
  * @mport: Master port to send transactions
+ * @flags: discovery control flags
  *
  * Starts the discovery process. If we have an active link,
- * then wait for the signal that enumeration is complete.
+ * then wait for the signal that enumeration is complete (if wait
+ * is allowed).
  * When enumeration completion is signaled, start recursive
  * peer discovery. Returns %0 if discovery succeeds or %-EBUSY
  * on failure.
  */
-int rio_disc_mport(struct rio_mport *mport)
+int rio_disc_mport(struct rio_mport *mport, u32 flags)
 {
struct rio_net *net = NULL;
unsigned long to_end;
@@ -1253,6 +1266,11 @@ int rio_disc_mport(struct rio_mport *mport)
 
/* If master port has an active link, allocate net and discover peers */
if (rio_mport_is_active(mport)) {
+   if (rio_enum_complete(mport))
+   goto enum_done;
+   else if (flags & RIO_SCAN_ENUM_NO_WAIT)
+   return -EAGAIN;
+
pr_debug("RIO: wait for enumeration to complete...\n");
 
to_end = jiffies + CONFIG_RAPIDIO_DISC_TIMEOUT * HZ;
diff --git a/drivers/rapidio/

[PATCH 0/3] rapidio: changes to enumeration/discovery

2013-04-24 Thread Alexandre Bounine
Systems that use RapidIO fabric may need to implement their own enumeration
and discovery methods which are better suitable for needs of a target
application.

The following set of patches is intended to simplify process of introduction of
new RapidIO fabric enumeration/discovery methods.

The first patch offers ability to add new RapidIO enumeration/discovery methods
using kernel configuration options or loadable modules. The new configuration
option mechanism allows to select built-in or modular enumeration/discovery
method from the list of existing methods or use external module(s).

This patch also updates the currently existing enumeration/discovery code to be
used as built-in or modular method. The corresponding configuration option is
named "Basic enumeration/discovery" method. This is the only one built-in
configuration option available today but new methods are expected to be
introduced after adoption of provided patches.

The second patch address a long time complaint of RapidIO subsystem users
regarding fabric enumeration/discovery start sequence. Existing implementation
offers only a boot-time enumeration/discovery start which requires synchronized
boot of all endpoints in RapidIO network. While it works for small closed
configurations with limited number of endpoints, using this approach in systems
with large number of endpoints is quite challenging.

To eliminate requirement for synchronized start the second patch introduces
RapidIO enumeration/discovery start from user space.

For compatibility with the existing RapidIO subsystem implementation, automatic
boot time enumeration/discovery start can be configured in by selecting
CONFIG_RAPIDIO_ENUM_AUTO option.

Cc: Matt Porter 
Cc: Li Yang 
Cc: Kumar Gala 
Cc: Andre van Herk 
Cc: Micha Nelissen 

Alexandre Bounine (3):
  rapidio: make enumeration/discovery configurable
  rapidio: add enumeration/discovery start from user space
  rapidio: documentation update for enumeration changes

 Documentation/rapidio/rapidio.txt |  137 --
 Documentation/rapidio/sysfs.txt   |   17 +++
 drivers/rapidio/Kconfig   |   28 +
 drivers/rapidio/Makefile  |3 +-
 drivers/rapidio/rio-driver.c  |8 ++
 drivers/rapidio/rio-scan.c|  195 ++
 drivers/rapidio/rio-sysfs.c   |   45 +++
 drivers/rapidio/rio.c |  234 -
 drivers/rapidio/rio.h |   12 ++-
 include/linux/rio.h   |   17 +++
 include/linux/rio_drv.h   |1 +
 11 files changed, 548 insertions(+), 149 deletions(-)

-- 
1.7.8.4

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH 2/3] rapidio: update asynchronous discovery initialization

2012-10-09 Thread Alexandre Bounine
Update discovery process initialization based on Andrew Morton's comments:
https://lkml.org/lkml/2012/10/3/552.

This update processes all enumerating mports first and schedules discovery
work after that. If the initialization routine fails to allocate resources
needed to execute discovery, it abandons discovery for all ports. 

Signed-off-by: Alexandre Bounine 
Cc: Matt Porter 
Cc: Li Yang 
---
 drivers/rapidio/rio.c |   75 ++--
 1 files changed, 47 insertions(+), 28 deletions(-)

diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c
index d4bd690..c17ae22 100644
--- a/drivers/rapidio/rio.c
+++ b/drivers/rapidio/rio.c
@@ -1275,49 +1275,68 @@ static void __devinit disc_work_handler(struct 
work_struct *_work)
pr_debug("RIO: discovery work for mport %d %s\n",
 work->mport->id, work->mport->name);
rio_disc_mport(work->mport);
-
-   kfree(work);
 }
 
 int __devinit rio_init_mports(void)
 {
struct rio_mport *port;
struct rio_disc_work *work;
-   int no_disc = 0;
+   int n = 0;
+
+   if (!next_portid)
+   return -ENODEV;
 
+   /*
+* First, run enumerations and check if we need to perform discovery
+* on any of the registered mports.
+*/
list_for_each_entry(port, &rio_mports, node) {
if (port->host_deviceid >= 0)
rio_enum_mport(port);
-   else if (!no_disc) {
-   if (!rio_wq) {
-   rio_wq = alloc_workqueue("riodisc", 0, 0);
-   if (!rio_wq) {
-   pr_err("RIO: unable allocate rio_wq\n");
-   no_disc = 1;
-   continue;
-   }
-   }
-
-   work = kzalloc(sizeof *work, GFP_KERNEL);
-   if (!work) {
-   pr_err("RIO: no memory for work struct\n");
-   no_disc = 1;
-   continue;
-   }
-
-   work->mport = port;
-   INIT_WORK(&work->work, disc_work_handler);
-   queue_work(rio_wq, &work->work);
-   }
+   else
+   n++;
+   }
+
+   if (!n)
+   goto no_disc;
+
+   /*
+* If we have mports that require discovery schedule a discovery work
+* for each of them. If the code below fails to allocate needed
+* resources, exit without error to keep results of enumeration
+* process (if any).
+* TODO: Implement restart of dicovery process for all or
+* individual discovering mports.
+*/
+   rio_wq = alloc_workqueue("riodisc", 0, 0);
+   if (!rio_wq) {
+   pr_err("RIO: unable allocate rio_wq\n");
+   goto no_disc;
}
 
-   if (rio_wq) {
-   pr_debug("RIO: flush discovery workqueue\n");
-   flush_workqueue(rio_wq);
-   pr_debug("RIO: flush discovery workqueue finished\n");
+   work = kcalloc(n, sizeof *work, GFP_KERNEL);
+   if (!work) {
+   pr_err("RIO: no memory for work struct\n");
destroy_workqueue(rio_wq);
+   goto no_disc;
}
 
+   n = 0;
+   list_for_each_entry(port, &rio_mports, node) {
+   if (port->host_deviceid < 0) {
+   work[n].mport = port;
+   INIT_WORK(&work[n].work, disc_work_handler);
+   queue_work(rio_wq, &work[n].work);
+   n++;
+   }
+   }
+
+   flush_workqueue(rio_wq);
+   pr_debug("RIO: destroy discovery workqueue\n");
+   destroy_workqueue(rio_wq);
+   kfree(work);
+
+no_disc:
rio_init();
 
return 0;
-- 
1.7.8.4

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH 1/3] rapidio: use msleep in discovery wait

2012-10-09 Thread Alexandre Bounine
Use msleep() routine for code clarity as suggested by Andrew Morton in his
comments for the original patch: https://lkml.org/lkml/2012/10/3/546.

Signed-off-by: Alexandre Bounine 
Cc: Matt Porter 
Cc: Li Yang 
---
 drivers/rapidio/rio-scan.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c
index 48e9041..05f0ed9 100644
--- a/drivers/rapidio/rio-scan.c
+++ b/drivers/rapidio/rio-scan.c
@@ -1391,7 +1391,7 @@ int __devinit rio_disc_mport(struct rio_mport *mport)
while (time_before(jiffies, to_end)) {
if (rio_enum_complete(mport))
goto enum_done;
-   schedule_timeout_uninterruptible(msecs_to_jiffies(10));
+   msleep(10);
}
 
pr_debug("RIO: discovery timeout on mport %d %s\n",
-- 
1.7.8.4

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH 0/3] rapidio: updates for multiple mport patches

2012-10-09 Thread Alexandre Bounine
This is a set of updates for patches submitted earlier:
https://lkml.org/lkml/2012/10/3/460.

Alexandre Bounine (3):
  rapidio: use msleep in discovery wait
  rapidio: update asynchronous discovery initialization
  rapidio: update for destination ID allocation

 drivers/rapidio/rio-scan.c |   40 ++-
 drivers/rapidio/rio.c  |   75 +++
 include/linux/rio.h|1 -
 3 files changed, 64 insertions(+), 52 deletions(-)

-- 
1.7.8.4

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH 3/3] rapidio: update for destination ID allocation

2012-10-09 Thread Alexandre Bounine
This patch address comments provided by Andrew Morton:
https://lkml.org/lkml/2012/10/3/550

- Keeps consistent kerneldoc compatible comments style for new static functions.
- Removes unnecessary complexity from destination ID allocation routine.
- Uses kcalloc() for code clarity. 

Signed-off-by: Alexandre Bounine 
Cc: Matt Porter 
Cc: Li Yang 
---
 drivers/rapidio/rio-scan.c |   38 --
 include/linux/rio.h|1 -
 2 files changed, 16 insertions(+), 23 deletions(-)

diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c
index 05f0ed9..07da58b 100644
--- a/drivers/rapidio/rio-scan.c
+++ b/drivers/rapidio/rio-scan.c
@@ -55,9 +55,9 @@ static int rio_mport_phys_table[] = {
 };
 
 
-/*
+/**
  * rio_destid_alloc - Allocate next available destID for given network
- * net: RIO network
+ * @net: RIO network
  *
  * Returns next available device destination ID for the specified RIO network.
  * Marks allocated ID as one in use.
@@ -69,14 +69,9 @@ static u16 rio_destid_alloc(struct rio_net *net)
struct rio_id_table *idtab = &net->destid_table;
 
spin_lock(&idtab->lock);
-   destid = find_next_zero_bit(idtab->table, idtab->max, idtab->next);
-   if (destid >= idtab->max)
-   destid = find_first_zero_bit(idtab->table, idtab->max);
+   destid = find_first_zero_bit(idtab->table, idtab->max);
 
if (destid < idtab->max) {
-   idtab->next = destid + 1;
-   if (idtab->next >= idtab->max)
-   idtab->next = 0;
set_bit(destid, idtab->table);
destid += idtab->start;
} else
@@ -86,10 +81,10 @@ static u16 rio_destid_alloc(struct rio_net *net)
return (u16)destid;
 }
 
-/*
+/**
  * rio_destid_reserve - Reserve the specivied destID
- * net: RIO network
- * destid: destID to reserve
+ * @net: RIO network
+ * @destid: destID to reserve
  *
  * Tries to reserve the specified destID.
  * Returns 0 if successfull.
@@ -106,10 +101,10 @@ static int rio_destid_reserve(struct rio_net *net, u16 
destid)
return oldbit;
 }
 
-/*
+/**
  * rio_destid_free - free a previously allocated destID
- * net: RIO network
- * destid: destID to free
+ * @net: RIO network
+ * @destid: destID to free
  *
  * Makes the specified destID available for use.
  */
@@ -123,9 +118,9 @@ static void rio_destid_free(struct rio_net *net, u16 destid)
spin_unlock(&idtab->lock);
 }
 
-/*
+/**
  * rio_destid_first - return first destID in use
- * net: RIO network
+ * @net: RIO network
  */
 static u16 rio_destid_first(struct rio_net *net)
 {
@@ -142,10 +137,10 @@ static u16 rio_destid_first(struct rio_net *net)
return (u16)destid;
 }
 
-/*
+/**
  * rio_destid_next - return next destID in use
- * net: RIO network
- * from: destination ID from which search shall continue
+ * @net: RIO network
+ * @from: destination ID from which search shall continue
  */
 static u16 rio_destid_next(struct rio_net *net, u16 from)
 {
@@ -1163,8 +1158,8 @@ static struct rio_net __devinit *rio_alloc_net(struct 
rio_mport *port,
 
net = kzalloc(sizeof(struct rio_net), GFP_KERNEL);
if (net && do_enum) {
-   net->destid_table.table = kzalloc(
-   BITS_TO_LONGS(RIO_MAX_ROUTE_ENTRIES(port->sys_size)) *
+   net->destid_table.table = kcalloc(
+   BITS_TO_LONGS(RIO_MAX_ROUTE_ENTRIES(port->sys_size)),
sizeof(long),
GFP_KERNEL);
 
@@ -1174,7 +1169,6 @@ static struct rio_net __devinit *rio_alloc_net(struct 
rio_mport *port,
net = NULL;
} else {
net->destid_table.start = start;
-   net->destid_table.next = 0;
net->destid_table.max =
RIO_MAX_ROUTE_ENTRIES(port->sys_size);
spin_lock_init(&net->destid_table.lock);
diff --git a/include/linux/rio.h b/include/linux/rio.h
index d2dff22..ac21ac6 100644
--- a/include/linux/rio.h
+++ b/include/linux/rio.h
@@ -266,7 +266,6 @@ struct rio_mport {
 
 struct rio_id_table {
u16 start;  /* logical minimal id */
-   u16 next;   /* hint for find */
u32 max;/* max number of IDs in table */
spinlock_t lock;
unsigned long *table;
-- 
1.7.8.4

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH 4/5] rapidio/rionet: rework to support multiple RIO master ports

2012-10-03 Thread Alexandre Bounine
Make RIONET driver multi-net safe/capable by introducing per-net lists of
RapidIO network peers. Rework registration of network adapters to support
all available RIO master port devices.

Signed-off-by: Alexandre Bounine 
Cc: Matt Porter 
Cc: Li Yang 
Cc: David S. Miller 
---
 drivers/net/rionet.c |  133 ++
 1 files changed, 70 insertions(+), 63 deletions(-)

diff --git a/drivers/net/rionet.c b/drivers/net/rionet.c
index 1470d3e..d8b9b1e 100644
--- a/drivers/net/rionet.c
+++ b/drivers/net/rionet.c
@@ -26,7 +26,7 @@
 #include 
 
 #define DRV_NAME"rionet"
-#define DRV_VERSION "0.2"
+#define DRV_VERSION "0.3"
 #define DRV_AUTHOR  "Matt Porter "
 #define DRV_DESC"Ethernet over RapidIO"
 
@@ -47,8 +47,7 @@ MODULE_LICENSE("GPL");
 
 #define RIONET_TX_RING_SIZECONFIG_RIONET_TX_SIZE
 #define RIONET_RX_RING_SIZECONFIG_RIONET_RX_SIZE
-
-static LIST_HEAD(rionet_peers);
+#define RIONET_MAX_NETS8
 
 struct rionet_private {
struct rio_mport *mport;
@@ -69,17 +68,14 @@ struct rionet_peer {
struct resource *res;
 };
 
-static int rionet_check = 0;
-static int rionet_capable = 1;
+struct rionet_net {
+   struct net_device *ndev;
+   struct list_head peers;
+   struct rio_dev **active;
+   int nact;   /* number of active peers */
+};
 
-/*
- * This is a fast lookup table for translating TX
- * Ethernet packets into a destination RIO device. It
- * could be made into a hash table to save memory depending
- * on system trade-offs.
- */
-static struct rio_dev **rionet_active;
-static int nact;   /* total number of active rionet peers */
+static struct rionet_net nets[RIONET_MAX_NETS];
 
 #define is_rionet_capable(src_ops, dst_ops)\
((src_ops & RIO_SRC_OPS_DATA_MSG) &&\
@@ -185,7 +181,7 @@ static int rionet_start_xmit(struct sk_buff *skb, struct 
net_device *ndev)
}
 
if (is_multicast_ether_addr(eth->h_dest))
-   add_num = nact;
+   add_num = nets[rnet->mport->id].nact;
 
if ((rnet->tx_cnt + add_num) > RIONET_TX_RING_SIZE) {
netif_stop_queue(ndev);
@@ -197,19 +193,21 @@ static int rionet_start_xmit(struct sk_buff *skb, struct 
net_device *ndev)
 
if (is_multicast_ether_addr(eth->h_dest)) {
int count = 0;
+
for (i = 0; i < RIO_MAX_ROUTE_ENTRIES(rnet->mport->sys_size);
i++)
-   if (rionet_active[i]) {
+   if (nets[rnet->mport->id].active[i]) {
rionet_queue_tx_msg(skb, ndev,
-   rionet_active[i]);
+   nets[rnet->mport->id].active[i]);
if (count)
atomic_inc(&skb->users);
count++;
}
} else if (RIONET_MAC_MATCH(eth->h_dest)) {
destid = RIONET_GET_DESTID(eth->h_dest);
-   if (rionet_active[destid])
-   rionet_queue_tx_msg(skb, ndev, rionet_active[destid]);
+   if (nets[rnet->mport->id].active[destid])
+   rionet_queue_tx_msg(skb, ndev,
+   nets[rnet->mport->id].active[destid]);
}
 
spin_unlock_irqrestore(&rnet->tx_lock, flags);
@@ -228,19 +226,21 @@ static void rionet_dbell_event(struct rio_mport *mport, 
void *dev_id, u16 sid, u
printk(KERN_INFO "%s: doorbell sid %4.4x tid %4.4x info %4.4x",
   DRV_NAME, sid, tid, info);
if (info == RIONET_DOORBELL_JOIN) {
-   if (!rionet_active[sid]) {
-   list_for_each_entry(peer, &rionet_peers, node) {
+   if (!nets[rnet->mport->id].active[sid]) {
+   list_for_each_entry(peer,
+  &nets[rnet->mport->id].peers, node) {
if (peer->rdev->destid == sid) {
-   rionet_active[sid] = peer->rdev;
-   nact++;
+   nets[rnet->mport->id].active[sid] =
+   peer->rdev;
+   nets[rnet->mport->id].nact++;
}
}
rio_mport_send_doorbell(mport, sid,
RIONET_DOORBELL_JOIN);
}
} else if (info == RIONET_DOORBELL_LEAVE) {
-   rionet_active[

[PATCH 5/5] rapidio: add destination ID allocation mechanism

2012-10-03 Thread Alexandre Bounine
Replace the single global destination ID counter with per-net allocation
mechanism to allow independent destID management for each available RapidIO
network. Using bitmap based mechanism instead of counters allows
destination ID release and reuse in systems that support hot-swap.

Signed-off-by: Alexandre Bounine 
Cc: Matt Porter 
Cc: Li Yang 
---
 drivers/rapidio/rio-scan.c |  205 
 include/linux/rio.h|9 ++
 2 files changed, 179 insertions(+), 35 deletions(-)

diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c
index 745670f..48e9041 100644
--- a/drivers/rapidio/rio-scan.c
+++ b/drivers/rapidio/rio-scan.c
@@ -54,6 +54,114 @@ static int rio_mport_phys_table[] = {
-1,
 };
 
+
+/*
+ * rio_destid_alloc - Allocate next available destID for given network
+ * net: RIO network
+ *
+ * Returns next available device destination ID for the specified RIO network.
+ * Marks allocated ID as one in use.
+ * Returns RIO_INVALID_DESTID if new destID is not available.
+ */
+static u16 rio_destid_alloc(struct rio_net *net)
+{
+   int destid;
+   struct rio_id_table *idtab = &net->destid_table;
+
+   spin_lock(&idtab->lock);
+   destid = find_next_zero_bit(idtab->table, idtab->max, idtab->next);
+   if (destid >= idtab->max)
+   destid = find_first_zero_bit(idtab->table, idtab->max);
+
+   if (destid < idtab->max) {
+   idtab->next = destid + 1;
+   if (idtab->next >= idtab->max)
+   idtab->next = 0;
+   set_bit(destid, idtab->table);
+   destid += idtab->start;
+   } else
+   destid = RIO_INVALID_DESTID;
+
+   spin_unlock(&idtab->lock);
+   return (u16)destid;
+}
+
+/*
+ * rio_destid_reserve - Reserve the specivied destID
+ * net: RIO network
+ * destid: destID to reserve
+ *
+ * Tries to reserve the specified destID.
+ * Returns 0 if successfull.
+ */
+static int rio_destid_reserve(struct rio_net *net, u16 destid)
+{
+   int oldbit;
+   struct rio_id_table *idtab = &net->destid_table;
+
+   destid -= idtab->start;
+   spin_lock(&idtab->lock);
+   oldbit = test_and_set_bit(destid, idtab->table);
+   spin_unlock(&idtab->lock);
+   return oldbit;
+}
+
+/*
+ * rio_destid_free - free a previously allocated destID
+ * net: RIO network
+ * destid: destID to free
+ *
+ * Makes the specified destID available for use.
+ */
+static void rio_destid_free(struct rio_net *net, u16 destid)
+{
+   struct rio_id_table *idtab = &net->destid_table;
+
+   destid -= idtab->start;
+   spin_lock(&idtab->lock);
+   clear_bit(destid, idtab->table);
+   spin_unlock(&idtab->lock);
+}
+
+/*
+ * rio_destid_first - return first destID in use
+ * net: RIO network
+ */
+static u16 rio_destid_first(struct rio_net *net)
+{
+   int destid;
+   struct rio_id_table *idtab = &net->destid_table;
+
+   spin_lock(&idtab->lock);
+   destid = find_first_bit(idtab->table, idtab->max);
+   if (destid >= idtab->max)
+   destid = RIO_INVALID_DESTID;
+   else
+   destid += idtab->start;
+   spin_unlock(&idtab->lock);
+   return (u16)destid;
+}
+
+/*
+ * rio_destid_next - return next destID in use
+ * net: RIO network
+ * from: destination ID from which search shall continue
+ */
+static u16 rio_destid_next(struct rio_net *net, u16 from)
+{
+   int destid;
+   struct rio_id_table *idtab = &net->destid_table;
+
+   spin_lock(&idtab->lock);
+   destid = find_next_bit(idtab->table, idtab->max, from);
+   if (destid >= idtab->max)
+   destid = RIO_INVALID_DESTID;
+   else
+   destid += idtab->start;
+   spin_unlock(&idtab->lock);
+   return (u16)destid;
+}
+
 /**
  * rio_get_device_id - Get the base/extended device id for a device
  * @port: RIO master port
@@ -171,10 +279,6 @@ static int rio_enum_host(struct rio_mport *port)
 
/* Set master port destid and init destid ctr */
rio_local_set_device_id(port, port->host_deviceid);
-
-   if (next_destid == port->host_deviceid)
-   next_destid++;
-
return 0;
 }
 
@@ -441,9 +545,8 @@ static struct rio_dev __devinit *rio_setup_device(struct 
rio_net *net,
if (rio_device_has_destid(port, rdev->src_ops, rdev->dst_ops)) {
if (do_enum) {
rio_set_device_id(port, destid, hopcount, next_destid);
-   rdev->destid = next_destid++;
-   if (next_destid == port->host_deviceid)
-   next_destid++;
+   rdev->destid = next_destid;
+   next_destid = rio_destid_alloc(net);
  

[PATCH 2/5] rapidio: use device lists handling on per-net basis

2012-10-03 Thread Alexandre Bounine
Modify handling of device lists to resolve issues caused by using single global
list of RIO devices during enumeration/discovery. The most common sign of
existing issue is incorrect contents of switch routing tables in systems with
multiple mport controllers while single-port configuration performs as expected.

Signed-off-by: Alexandre Bounine 
Cc: Matt Porter 
Cc: Li Yang 
---
 drivers/rapidio/rio-scan.c |   60 ++-
 include/linux/rio.h|1 +
 2 files changed, 32 insertions(+), 29 deletions(-)

diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c
index 0a27253..8b7c4bc 100644
--- a/drivers/rapidio/rio-scan.c
+++ b/drivers/rapidio/rio-scan.c
@@ -38,7 +38,6 @@
 #include "rio.h"
 
 LIST_HEAD(rio_devices);
-static LIST_HEAD(rio_switches);
 
 static void rio_init_em(struct rio_dev *rdev);
 
@@ -104,14 +103,15 @@ static void rio_local_set_device_id(struct rio_mport 
*port, u16 did)
 
 /**
  * rio_clear_locks- Release all host locks and signal enumeration complete
- * @port: Master port to issue transaction
+ * @net: RIO network to run on
  *
  * Marks the component tag CSR on each device with the enumeration
  * complete flag. When complete, it then release the host locks on
  * each device. Returns 0 on success or %-EINVAL on failure.
  */
-static int rio_clear_locks(struct rio_mport *port)
+static int rio_clear_locks(struct rio_net *net)
 {
+   struct rio_mport *port = net->hport;
struct rio_dev *rdev;
u32 result;
int ret = 0;
@@ -126,7 +126,7 @@ static int rio_clear_locks(struct rio_mport *port)
   result);
ret = -EINVAL;
}
-   list_for_each_entry(rdev, &rio_devices, global_list) {
+   list_for_each_entry(rdev, &net->devices, net_list) {
rio_write_config_32(rdev, RIO_HOST_DID_LOCK_CSR,
port->host_deviceid);
rio_read_config_32(rdev, RIO_HOST_DID_LOCK_CSR, &result);
@@ -479,7 +479,7 @@ static struct rio_dev __devinit *rio_setup_device(struct 
rio_net *net,
rswitch->clr_table(port, destid, hopcount,
   RIO_GLOBAL_TABLE);
 
-   list_add_tail(&rswitch->node, &rio_switches);
+   list_add_tail(&rswitch->node, &net->switches);
 
} else {
if (do_enum)
@@ -1058,6 +1058,7 @@ static struct rio_net __devinit *rio_alloc_net(struct 
rio_mport *port)
if (net) {
INIT_LIST_HEAD(&net->node);
INIT_LIST_HEAD(&net->devices);
+   INIT_LIST_HEAD(&net->switches);
INIT_LIST_HEAD(&net->mports);
list_add_tail(&port->nnode, &net->mports);
net->hport = port;
@@ -1068,24 +1069,24 @@ static struct rio_net __devinit *rio_alloc_net(struct 
rio_mport *port)
 
 /**
  * rio_update_route_tables- Updates route tables in switches
- * @port: Master port associated with the RIO network
+ * @net: RIO network to run update on
  *
  * For each enumerated device, ensure that each switch in a system
  * has correct routing entries. Add routes for devices that where
  * unknown dirung the first enumeration pass through the switch.
  */
-static void rio_update_route_tables(struct rio_mport *port)
+static void rio_update_route_tables(struct rio_net *net)
 {
struct rio_dev *rdev, *swrdev;
struct rio_switch *rswitch;
u8 sport;
u16 destid;
 
-   list_for_each_entry(rdev, &rio_devices, global_list) {
+   list_for_each_entry(rdev, &net->devices, net_list) {
 
destid = rdev->destid;
 
-   list_for_each_entry(rswitch, &rio_switches, node) {
+   list_for_each_entry(rswitch, &net->switches, node) {
 
if (rio_is_switch(rdev) && (rdev->rswitch == rswitch))
continue;
@@ -1181,12 +1182,12 @@ int __devinit rio_enum_mport(struct rio_mport *mport)
printk(KERN_INFO
   "RIO: master port %d device has lost enumeration 
to a remote host\n",
   mport->id);
-   rio_clear_locks(mport);
+   rio_clear_locks(net);
rc = -EBUSY;
goto out;
}
-   rio_update_route_tables(mport);
-   rio_clear_locks(mport);
+   rio_update_route_tables(net);
+   rio_clear_locks(net);
rio_pw_enable(mport, 1);
} else {
printk(KERN_INFO "RIO: master port %d link inactive\n",
@@ -1200,33 +1201,34 @@ int __devinit rio_enum_mport(struct rio_mport *mport)
 
 /**
  * rio_build_route_tables- Generate route tables from switch route ent

[PATCH 0/5] rapidio: patches to support multiple master ports

2012-10-03 Thread Alexandre Bounine
The following set of patches provides modifications targeting support of 
multiple
RapidIO master port (mport) devices on a CPU-side of RapidIO-capable board.
While the RapidIO subsystem code has definitions suitable for
multi-controller/multi-net support, the existing implementation cannot be
considered ready for multiple mport configurations.   

=== NOTES: =
a) The patches below do not address RapidIO side view of multiport processing
elements defined in Part 6 of RapidIO spec Rev.2.1 (section 6.4.1).
These devices have Base Device ID CSR (0x60) and Component Tag CSR (0x6C) shared
by all SRIO ports. For example, Freescale's P4080, P3041 and P5020 have a
dual-port SRIO controller implemented according the specification.
Enumeration/discovery of such devices from RapidIO side may require
device-specific fixups.
b) Devices referenced above may also require implementation specific code to 
setup
a host device ID for mport device. These operations are not addressed by patches
in this package. 
=

Details about provided patches:

1. Fix blocking wait for discovery ready

While it does not happen on PowerPC based platforms, there is possibility of
stalled CPU warning dump on x86 based platforms that run RapidIO discovery
process if they wait too long for being enumerated.
Currently users can avoid it by disabling the soft-lockup detector using
"nosoftlockup" kernel parameter OR by ensuring that enumeration is completed
before soft-lockup is detected.

This patch eliminates blocking wait and keeps a scheduler running.
It also is required for patch 3 below which introduces asynchronous discovery
process.

2. Use device lists handling on per-net basis

This patch allows to correctly support multiple RapidIO nets and resolves 
possible
issues caused by using single global list of devices during RapidIO system
enumeration/discovery. The most common sign of existing issue is incorrect
contents of switch routing tables in systems with multiple mport controllers
while single-port configuration performs as expected.

The patch does not eliminate the global RapidIO device list but changes some
routines in enumeration/discovery to use per-net device lists instead. This way
compatibility with upper layer RIO routines is preserved.
 
3. Run discovery as an asynchronous process

This patch modifies RapidIO initialization routine to asynchronously run the
discovery process for each corresponding mport. This allows having an arbitrary
order of enumerating and discovering mports without creating a deadlock 
situation
if an enumerator port was registered after a discovering one.

On boards with multiple discovering mports it also eliminates order dependency
between mports and may reduce total time of RapidIO subsystem initialization.

Making netID matching to mportID ensures consistent netID assignment in
multiport RapidIO systems with asynchronous discovery process (global counter
implementation is affected by race between threads).

4. Rework RIONET to support multiple RIO master ports

In the current version of the driver rionet_probe() has comment
"XXX Make multi-net safe". Now it is a good time to address this comment.

This patch makes RIONET driver multi-net safe/capable by introducing per-net
lists of RapidIO network peers. It also enables to register network adapters for
all available mport devices.

5. Add destination ID allocation mechanism

The patch replaces a single global destination ID counter with per-net 
allocation
mechanism to allow independent destID management for each available RapidIO
network. Using bitmap based mechanism instead of counters allows destination ID
release and reuse in systems that support hot-swap.


Alexandre Bounine (5):
  rapidio: fix blocking wait for discovery ready
  rapidio: use device lists handling on per-net basis
  rapidio: run discovery as an asynchronous process
  rapidio/rionet: rework to support multiple RIO master ports
  rapidio: add destination ID allocation mechanism

 drivers/net/rionet.c   |  133 ++-
 drivers/rapidio/rio-scan.c |  326 +--
 drivers/rapidio/rio.c  |   51 +++-
 include/linux/rio.h|   10 ++
 4 files changed, 349 insertions(+), 171 deletions(-)

-- 
1.7.8.4
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH 1/5] rapidio: fix blocking wait for discovery ready

2012-10-03 Thread Alexandre Bounine
Fix blocking wait loop in the RapidIO discovery routine to avoid warning
dumps about stalled CPU on x86 platforms.

Signed-off-by: Alexandre Bounine 
Cc: Matt Porter 
Cc: Li Yang 
---
 drivers/rapidio/rio-scan.c |   62 ++-
 1 files changed, 20 insertions(+), 42 deletions(-)

diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c
index 02e686b..0a27253 100644
--- a/drivers/rapidio/rio-scan.c
+++ b/drivers/rapidio/rio-scan.c
@@ -31,6 +31,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -39,8 +40,6 @@
 LIST_HEAD(rio_devices);
 static LIST_HEAD(rio_switches);
 
-static void rio_enum_timeout(unsigned long);
-
 static void rio_init_em(struct rio_dev *rdev);
 
 DEFINE_SPINLOCK(rio_global_list_lock);
@@ -49,9 +48,6 @@ static int next_destid = 0;
 static int next_net = 0;
 static int next_comptag = 1;
 
-static struct timer_list rio_enum_timer =
-TIMER_INITIALIZER(rio_enum_timeout, 0, 0);
-
 static int rio_mport_phys_table[] = {
RIO_EFB_PAR_EP_ID,
RIO_EFB_PAR_EP_REC_ID,
@@ -1234,20 +1230,6 @@ static void rio_build_route_tables(void)
 }
 
 /**
- * rio_enum_timeout- Signal that enumeration timed out
- * @data: Address of timeout flag.
- *
- * When the enumeration complete timer expires, set a flag that
- * signals to the discovery process that enumeration did not
- * complete in a sane amount of time.
- */
-static void rio_enum_timeout(unsigned long data)
-{
-   /* Enumeration timed out, set flag */
-   *(int *)data = 1;
-}
-
-/**
  * rio_disc_mport- Start discovery through a master port
  * @mport: Master port to send transactions
  *
@@ -1260,34 +1242,33 @@ static void rio_enum_timeout(unsigned long data)
 int __devinit rio_disc_mport(struct rio_mport *mport)
 {
struct rio_net *net = NULL;
-   int enum_timeout_flag = 0;
+   unsigned long to_end;
 
printk(KERN_INFO "RIO: discover master port %d, %s\n", mport->id,
   mport->name);
 
/* If master port has an active link, allocate net and discover peers */
if (rio_mport_is_active(mport)) {
-   if (!(net = rio_alloc_net(mport))) {
-   printk(KERN_ERR "RIO: Failed to allocate new net\n");
-   goto bail;
-   }
+   pr_debug("RIO: wait for enumeration to complete...\n");
 
-   pr_debug("RIO: wait for enumeration complete...");
-
-   rio_enum_timer.expires =
-   jiffies + CONFIG_RAPIDIO_DISC_TIMEOUT * HZ;
-   rio_enum_timer.data = (unsigned long)&enum_timeout_flag;
-   add_timer(&rio_enum_timer);
-   while (!rio_enum_complete(mport)) {
-   mdelay(1);
-   if (enum_timeout_flag) {
-   del_timer_sync(&rio_enum_timer);
-   goto timeout;
-   }
+   to_end = jiffies + CONFIG_RAPIDIO_DISC_TIMEOUT * HZ;
+   while (time_before(jiffies, to_end)) {
+   if (rio_enum_complete(mport))
+   goto enum_done;
+   schedule_timeout_uninterruptible(msecs_to_jiffies(10));
}
-   del_timer_sync(&rio_enum_timer);
 
-   pr_debug("done\n");
+   pr_debug("RIO: discovery timeout on mport %d %s\n",
+mport->id, mport->name);
+   goto bail;
+enum_done:
+   pr_debug("RIO: ... enumeration done\n");
+
+   net = rio_alloc_net(mport);
+   if (!net) {
+   printk(KERN_ERR "RIO: Failed to allocate new net\n");
+   goto bail;
+   }
 
/* Read DestID assigned by enumerator */
rio_local_read_config_32(mport, RIO_DID_CSR,
@@ -1307,9 +1288,6 @@ int __devinit rio_disc_mport(struct rio_mport *mport)
}
 
return 0;
-
-  timeout:
-   pr_debug("timeout\n");
-  bail:
+bail:
return -EBUSY;
 }
-- 
1.7.8.4

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH 3/5] rapidio: run discovery as an asynchronous process

2012-10-03 Thread Alexandre Bounine
Modify mport initialization routine to run the RapidIO discovery process
asynchronously. This allows to have an arbitrary order of enumerating and
discovering ports in systems with multiple RapidIO controllers without
creating a deadlock situation if enumerator port is registered after a
discovering one.

Making netID matching to mportID ensures consistent net ID assignment in
multiport RapidIO systems with asynchronous discovery process (global counter
implementation is affected by race between threads).

Signed-off-by: Alexandre Bounine 
Cc: Matt Porter 
Cc: Li Yang 
---
 drivers/rapidio/rio-scan.c |3 +-
 drivers/rapidio/rio.c  |   51 ++-
 2 files changed, 50 insertions(+), 4 deletions(-)

diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c
index 8b7c4bc..745670f 100644
--- a/drivers/rapidio/rio-scan.c
+++ b/drivers/rapidio/rio-scan.c
@@ -44,7 +44,6 @@ static void rio_init_em(struct rio_dev *rdev);
 DEFINE_SPINLOCK(rio_global_list_lock);
 
 static int next_destid = 0;
-static int next_net = 0;
 static int next_comptag = 1;
 
 static int rio_mport_phys_table[] = {
@@ -1062,7 +1061,7 @@ static struct rio_net __devinit *rio_alloc_net(struct 
rio_mport *port)
INIT_LIST_HEAD(&net->mports);
list_add_tail(&port->nnode, &net->mports);
net->hport = port;
-   net->id = next_net++;
+   net->id = port->id;
}
return net;
 }
diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c
index d7b68cc..7cdc3e6d 100644
--- a/drivers/rapidio/rio.c
+++ b/drivers/rapidio/rio.c
@@ -1260,15 +1260,62 @@ static int __devinit rio_init(void)
return 0;
 }
 
+static struct workqueue_struct *rio_wq;
+
+struct rio_disc_work {
+   struct work_struct  work;
+   struct rio_mport*mport;
+};
+
+static void __devinit disc_work_handler(struct work_struct *_work)
+{
+   struct rio_disc_work *work = container_of(_work,
+ struct rio_disc_work, work);
+
+   pr_debug("RIO: discovery work for mport %d %s\n",
+work->mport->id, work->mport->name);
+   rio_disc_mport(work->mport);
+
+   kfree(work);
+}
+
 int __devinit rio_init_mports(void)
 {
struct rio_mport *port;
+   struct rio_disc_work *work;
+   int no_disc = 0;
 
list_for_each_entry(port, &rio_mports, node) {
if (port->host_deviceid >= 0)
rio_enum_mport(port);
-   else
-   rio_disc_mport(port);
+   else if (!no_disc) {
+   if (!rio_wq) {
+   rio_wq = alloc_workqueue("riodisc", 0, 0);
+   if (!rio_wq) {
+   pr_err("RIO: unable allocate rio_wq\n");
+   no_disc = 1;
+   continue;
+   }
+   }
+
+   work = kzalloc(sizeof *work, GFP_KERNEL);
+   if (!work) {
+   pr_err("RIO: no memory for work struct\n");
+   no_disc = 1;
+   continue;
+   }
+
+   work->mport = port;
+   INIT_WORK(&work->work, disc_work_handler);
+   queue_work(rio_wq, &work->work);
+   }
+   }
+
+   if (rio_wq) {
+   pr_debug("RIO: flush discovery workqueue\n");
+   flush_workqueue(rio_wq);
+   pr_debug("RIO: flush discovery workqueue finished\n");
+   destroy_workqueue(rio_wq);
}
 
rio_init();
-- 
1.7.8.4

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH] rapidio/rionet: fix multicast packet transmit logic

2012-09-26 Thread Alexandre Bounine
Fix multicast packet transmit logic to account for repetitive transmission
of single skb:
- correct check for available buffers (this bug may produce NULL pointer
  crash dump in case of heavy traffic);
- update skb user count (incorrect user counter causes a warning dump from
  net_tx_action routine during multicast transfers in systems with three or
  more rionet participants).

Signed-off-by: Alexandre Bounine 
Cc: Matt Porter 
Cc: David S. Miller 
Cc: net...@vger.kernel.org
---
 drivers/net/rionet.c |   20 +---
 1 files changed, 17 insertions(+), 3 deletions(-)

diff --git a/drivers/net/rionet.c b/drivers/net/rionet.c
index 91d2588..1470d3e 100644
--- a/drivers/net/rionet.c
+++ b/drivers/net/rionet.c
@@ -79,6 +79,7 @@ static int rionet_capable = 1;
  * on system trade-offs.
  */
 static struct rio_dev **rionet_active;
+static int nact;   /* total number of active rionet peers */
 
 #define is_rionet_capable(src_ops, dst_ops)\
((src_ops & RIO_SRC_OPS_DATA_MSG) &&\
@@ -175,6 +176,7 @@ static int rionet_start_xmit(struct sk_buff *skb, struct 
net_device *ndev)
struct ethhdr *eth = (struct ethhdr *)skb->data;
u16 destid;
unsigned long flags;
+   int add_num = 1;
 
local_irq_save(flags);
if (!spin_trylock(&rnet->tx_lock)) {
@@ -182,7 +184,10 @@ static int rionet_start_xmit(struct sk_buff *skb, struct 
net_device *ndev)
return NETDEV_TX_LOCKED;
}
 
-   if ((rnet->tx_cnt + 1) > RIONET_TX_RING_SIZE) {
+   if (is_multicast_ether_addr(eth->h_dest))
+   add_num = nact;
+
+   if ((rnet->tx_cnt + add_num) > RIONET_TX_RING_SIZE) {
netif_stop_queue(ndev);
spin_unlock_irqrestore(&rnet->tx_lock, flags);
printk(KERN_ERR "%s: BUG! Tx Ring full when queue awake!\n",
@@ -191,11 +196,16 @@ static int rionet_start_xmit(struct sk_buff *skb, struct 
net_device *ndev)
}
 
if (is_multicast_ether_addr(eth->h_dest)) {
+   int count = 0;
for (i = 0; i < RIO_MAX_ROUTE_ENTRIES(rnet->mport->sys_size);
i++)
-   if (rionet_active[i])
+   if (rionet_active[i]) {
rionet_queue_tx_msg(skb, ndev,
rionet_active[i]);
+   if (count)
+   atomic_inc(&skb->users);
+   count++;
+   }
} else if (RIONET_MAC_MATCH(eth->h_dest)) {
destid = RIONET_GET_DESTID(eth->h_dest);
if (rionet_active[destid])
@@ -220,14 +230,17 @@ static void rionet_dbell_event(struct rio_mport *mport, 
void *dev_id, u16 sid, u
if (info == RIONET_DOORBELL_JOIN) {
if (!rionet_active[sid]) {
list_for_each_entry(peer, &rionet_peers, node) {
-   if (peer->rdev->destid == sid)
+   if (peer->rdev->destid == sid) {
rionet_active[sid] = peer->rdev;
+   nact++;
+   }
}
rio_mport_send_doorbell(mport, sid,
RIONET_DOORBELL_JOIN);
}
} else if (info == RIONET_DOORBELL_LEAVE) {
rionet_active[sid] = NULL;
+   nact--;
} else {
if (netif_msg_intr(rnet))
printk(KERN_WARNING "%s: unhandled doorbell\n",
@@ -523,6 +536,7 @@ static int rionet_probe(struct rio_dev *rdev, const struct 
rio_device_id *id)
 
rc = rionet_setup_netdev(rdev->net->hport, ndev);
rionet_check = 1;
+   nact = 0;
}
 
/*
-- 
1.7.8.4

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH RESEND] rapidio: apply RX/TX enable to active switch ports only

2012-09-18 Thread Alexandre Bounine
Apply port RX/TX enable operations only to active switch ports.

RapidIO specification (Part 6: LP-Serial Physical Layer)
recommends to keep Output Port Enable (TX) and Input Port Enable (RX)
control bits in disabled state (0b0) after device reset. It also allows
to have implementation specific reset state for these bits.

This patch ensures that TX/RX enable action is applied only to active
switch's ports while preserving an initial state of inactive ones.

Signed-off-by: Alexandre Bounine 
Cc: Matt Porter 
---

RESEND: Initial submission of this patch was dropped due to feedback
comment which raised concern about some RapidIO switch implementations
that may be affected by the change. After specification and device details
review this patch declared to be safe because it preserves any combination
of initial states of RX/TX enable for inactive port. 

 drivers/rapidio/rio-scan.c |9 +
 1 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c
index 2bebd79..02e686b 100644
--- a/drivers/rapidio/rio-scan.c
+++ b/drivers/rapidio/rio-scan.c
@@ -839,12 +839,10 @@ static int __devinit rio_enum_peer(struct rio_net *net, 
struct rio_mport *port,
for (port_num = 0;
 port_num < RIO_GET_TOTAL_PORTS(rdev->swpinfo);
 port_num++) {
-   /*Enable Input Output Port (transmitter reviever)*/
-   rio_enable_rx_tx_port(port, 0,
+   if (sw_inport == port_num) {
+   rio_enable_rx_tx_port(port, 0,
  RIO_ANY_DESTID(port->sys_size),
  hopcount, port_num);
-
-   if (sw_inport == port_num) {
rdev->rswitch->port_ok |= (1 << port_num);
continue;
}
@@ -857,6 +855,9 @@ static int __devinit rio_enum_peer(struct rio_net *net, 
struct rio_mport *port,
pr_debug(
"RIO: scanning device on port %d\n",
port_num);
+   rio_enable_rx_tx_port(port, 0,
+ RIO_ANY_DESTID(port->sys_size),
+ hopcount, port_num);
rdev->rswitch->port_ok |= (1 << port_num);
rio_route_add_entry(rdev, RIO_GLOBAL_TABLE,
RIO_ANY_DESTID(port->sys_size),
-- 
1.7.8.4

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH 2/2] rapidio/tsi721: add inbound memory mapping callbacks

2012-09-18 Thread Alexandre Bounine
Add Tsi721 routines to support RapidIO subsystem's inbound memory mapping
interface (RapidIO to system's local memory). 

Signed-off-by: Alexandre Bounine 
Cc: Matt Porter 
Cc: Li Yang 
Cc: Kumar Gala 
---
 drivers/rapidio/devices/tsi721.c |   88 +-
 drivers/rapidio/devices/tsi721.h |   15 +-
 2 files changed, 99 insertions(+), 4 deletions(-)

diff --git a/drivers/rapidio/devices/tsi721.c b/drivers/rapidio/devices/tsi721.c
index 1974359..961dc7a 100644
--- a/drivers/rapidio/devices/tsi721.c
+++ b/drivers/rapidio/devices/tsi721.c
@@ -862,6 +862,90 @@ static void tsi721_init_pc2sr_mapping(struct tsi721_device 
*priv)
 }
 
 /**
+ * tsi721_rio_map_inb_mem -- Mapping inbound memory region.
+ * @mport: RapidIO master port
+ * @lstart: Local memory space start address.
+ * @rstart: RapidIO space start address.
+ * @size: The mapping region size.
+ * @flags: Flags for mapping. 0 for using default flags.
+ *
+ * Return: 0 -- Success.
+ *
+ * This function will create the inbound mapping
+ * from rstart to lstart.
+ */
+static int tsi721_rio_map_inb_mem(struct rio_mport *mport, dma_addr_t lstart,
+   u64 rstart, u32 size, u32 flags)
+{
+   struct tsi721_device *priv = mport->priv;
+   int i;
+   u32 regval;
+
+   if (!is_power_of_2(size) || size < 0x1000 ||
+   ((u64)lstart & (size - 1)) || (rstart & (size - 1)))
+   return -EINVAL;
+
+   /* Search for free inbound translation window */
+   for (i = 0; i < TSI721_IBWIN_NUM; i++) {
+   regval = ioread32(priv->regs + TSI721_IBWIN_LB(i));
+   if (!(regval & TSI721_IBWIN_LB_WEN))
+   break;
+   }
+
+   if (i >= TSI721_IBWIN_NUM) {
+   dev_err(&priv->pdev->dev,
+   "Unable to find free inbound window\n");
+   return -EBUSY;
+   }
+
+   iowrite32(TSI721_IBWIN_SIZE(size) << 8,
+   priv->regs + TSI721_IBWIN_SZ(i));
+
+   iowrite32(((u64)lstart >> 32), priv->regs + TSI721_IBWIN_TUA(i));
+   iowrite32(((u64)lstart & TSI721_IBWIN_TLA_ADD),
+ priv->regs + TSI721_IBWIN_TLA(i));
+
+   iowrite32(rstart >> 32, priv->regs + TSI721_IBWIN_UB(i));
+   iowrite32((rstart & TSI721_IBWIN_LB_BA) | TSI721_IBWIN_LB_WEN,
+   priv->regs + TSI721_IBWIN_LB(i));
+   dev_dbg(&priv->pdev->dev,
+   "Configured IBWIN%d mapping (RIO_0x%llx -> PCIe_0x%llx)\n",
+   i, rstart, (unsigned long long)lstart);
+
+   return 0;
+}
+
+/**
+ * fsl_rio_unmap_inb_mem -- Unmapping inbound memory region.
+ * @mport: RapidIO master port
+ * @lstart: Local memory space start address.
+ */
+static void tsi721_rio_unmap_inb_mem(struct rio_mport *mport,
+   dma_addr_t lstart)
+{
+   struct tsi721_device *priv = mport->priv;
+   int i;
+   u64 addr;
+   u32 regval;
+
+   /* Search for matching active inbound translation window */
+   for (i = 0; i < TSI721_IBWIN_NUM; i++) {
+   regval = ioread32(priv->regs + TSI721_IBWIN_LB(i));
+   if (regval & TSI721_IBWIN_LB_WEN) {
+   regval = ioread32(priv->regs + TSI721_IBWIN_TUA(i));
+   addr = (u64)regval << 32;
+   regval = ioread32(priv->regs + TSI721_IBWIN_TLA(i));
+   addr |= regval & TSI721_IBWIN_TLA_ADD;
+
+   if (addr == (u64)lstart) {
+   iowrite32(0, priv->regs + TSI721_IBWIN_LB(i));
+   break;
+   }
+   }
+   }
+}
+
+/**
  * tsi721_init_sr2pc_mapping - initializes inbound (SRIO->PCIe)
  * translation regions.
  * @priv: pointer to tsi721 private data
@@ -874,7 +958,7 @@ static void tsi721_init_sr2pc_mapping(struct tsi721_device 
*priv)
 
/* Disable all SR2PC inbound windows */
for (i = 0; i < TSI721_IBWIN_NUM; i++)
-   iowrite32(0, priv->regs + TSI721_IBWINLB(i));
+   iowrite32(0, priv->regs + TSI721_IBWIN_LB(i));
 }
 
 /**
@@ -2144,6 +2228,8 @@ static int __devinit tsi721_setup_mport(struct 
tsi721_device *priv)
ops->add_outb_message = tsi721_add_outb_message;
ops->add_inb_buffer = tsi721_add_inb_buffer;
ops->get_inb_message = tsi721_get_inb_message;
+   ops->map_inb = tsi721_rio_map_inb_mem;
+   ops->unmap_inb = tsi721_rio_unmap_inb_mem;
 
mport = kzalloc(sizeof(struct rio_mport), GFP_KERNEL);
if (!mport) {
diff --git a/drivers/rapidio/devices/tsi721.h b/drivers/rapidio/devices/tsi721.h
index 59de9d7..7d5b13b 100644
--- a/drivers/rapidio/devices/tsi721.h
+++ b/drivers/rapidio/devices/tsi721.h
@@ -156,9 +156,18 @@
 
 #define TSI721_IBWIN_NUM   8
 
-

[PATCH 0/2] rapidio: add inbound memory mapping API

2012-09-18 Thread Alexandre Bounine
Add RapidIO subsystem interface to support mapping of RapidIO memory space into
system's local memory. 

RapidIO specification defines memory mapped read (NREAD) and write (NWRITE,
NWRITE_R and SWRITE) requests that allow to access memory space on remote target
device. Existing RapidIO controllers/bridges provide hardware mechanism
to map addresses on RapidIO side into system's local memory. Patches provided in
this package define common interface that has to be supported by RIO master port
devices and hardware dependent implementation for IDT Tsi721 PCIe-to-SRIO 
bridge.

These patches are based on the work submitted by Li Yang 
(https://lists.ozlabs.org/pipermail/linuxppc-dev/2009-April/071210.html) but
implement only the inbound mapping portion of it.

Combined with RapidIO DMA engine interface support these patches allow to 
perform
memory mapped data transfers between devices connected to a RapidIO network.  

Cc: Matt Porter 
Cc: Li Yang 
Cc: Kumar Gala 
---
Alexandre Bounine (2):
  rapidio: add inbound memory mapping interface
  rapidio/tsi721: add inbound memory mapping callbacks

 drivers/rapidio/devices/tsi721.c |   88 +-
 drivers/rapidio/devices/tsi721.h |   15 +-
 drivers/rapidio/rio.c|   44 +++
 include/linux/rio.h  |5 ++
 include/linux/rio_drv.h  |5 ++
 5 files changed, 153 insertions(+), 4 deletions(-)

-- 
1.7.8.4

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH 1/2] rapidio: add inbound memory mapping interface

2012-09-18 Thread Alexandre Bounine
Add common inbound memory mapping/unmapping interface. This allows to make
local memory space accessible from the RapidIO side using hardware mapping
capabilities of RapidIO bridging devices. The new interface is intended to
enable data transfers between RapidIO devices in combination with DMA engine
support. 

This patch is based on patch submitted by Li Yang 
(https://lists.ozlabs.org/pipermail/linuxppc-dev/2009-April/071210.html)

Signed-off-by: Alexandre Bounine 
Cc: Matt Porter 
Cc: Li Yang 
Cc: Kumar Gala 
---
 drivers/rapidio/rio.c   |   44 
 include/linux/rio.h |5 +
 include/linux/rio_drv.h |5 +
 3 files changed, 54 insertions(+), 0 deletions(-)

diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c
index c40665a..d7b68cc 100644
--- a/drivers/rapidio/rio.c
+++ b/drivers/rapidio/rio.c
@@ -33,6 +33,7 @@
 
 static LIST_HEAD(rio_mports);
 static unsigned char next_portid;
+static DEFINE_SPINLOCK(rio_mmap_lock);
 
 /**
  * rio_local_get_device_id - Get the base/extended device id for a port
@@ -398,6 +399,49 @@ int rio_release_inb_pwrite(struct rio_dev *rdev)
 EXPORT_SYMBOL_GPL(rio_release_inb_pwrite);
 
 /**
+ * rio_map_inb_region -- Map inbound memory region.
+ * @mport: Master port.
+ * @lstart: physical address of memory region to be mapped
+ * @rbase: RIO base address assigned to this window
+ * @size: Size of the memory region
+ * @rflags: Flags for mapping.
+ *
+ * Return: 0 -- Success.
+ *
+ * This function will create the mapping from RIO space to local memory.
+ */
+int rio_map_inb_region(struct rio_mport *mport, dma_addr_t local,
+   u64 rbase, u32 size, u32 rflags)
+{
+   int rc = 0;
+   unsigned long flags;
+
+   if (!mport->ops->map_inb)
+   return -1;
+   spin_lock_irqsave(&rio_mmap_lock, flags);
+   rc = mport->ops->map_inb(mport, local, rbase, size, rflags);
+   spin_unlock_irqrestore(&rio_mmap_lock, flags);
+   return rc;
+}
+EXPORT_SYMBOL_GPL(rio_map_inb_region);
+
+/**
+ * rio_unmap_inb_region -- Unmap the inbound memory region
+ * @mport: Master port
+ * @lstart: physical address of memory region to be unmapped
+ */
+void rio_unmap_inb_region(struct rio_mport *mport, dma_addr_t lstart)
+{
+   unsigned long flags;
+   if (!mport->ops->unmap_inb)
+   return;
+   spin_lock_irqsave(&rio_mmap_lock, flags);
+   mport->ops->unmap_inb(mport, lstart);
+   spin_unlock_irqrestore(&rio_mmap_lock, flags);
+}
+EXPORT_SYMBOL_GPL(rio_unmap_inb_region);
+
+/**
  * rio_mport_get_physefb - Helper function that returns register offset
  *  for Physical Layer Extended Features Block.
  * @port: Master port to issue transaction
diff --git a/include/linux/rio.h b/include/linux/rio.h
index ba382f2..4d1a104 100644
--- a/include/linux/rio.h
+++ b/include/linux/rio.h
@@ -301,6 +301,8 @@ struct rio_net {
  * @add_outb_message: Callback to add a message to an outbound mailbox queue.
  * @add_inb_buffer: Callback toadd a buffer to an inbound mailbox 
queue.
  * @get_inb_message: Callback to get a message from an inbound mailbox queue.
+ * @map_inb: Callback to map RapidIO address region into local memory space.
+ * @unmap_inb: Callback to unmap RapidIO address region mapped with map_inb().
  */
 struct rio_ops {
int (*lcread) (struct rio_mport *mport, int index, u32 offset, int len,
@@ -323,6 +325,9 @@ struct rio_ops {
 int mbox, void *buffer, size_t len);
int (*add_inb_buffer)(struct rio_mport *mport, int mbox, void *buf);
void *(*get_inb_message)(struct rio_mport *mport, int mbox);
+   int (*map_inb)(struct rio_mport *mport, dma_addr_t lstart,
+   u64 rstart, u32 size, u32 flags);
+   void (*unmap_inb)(struct rio_mport *mport, dma_addr_t lstart);
 };
 
 #define RIO_RESOURCE_MEM   0x0100
diff --git a/include/linux/rio_drv.h b/include/linux/rio_drv.h
index 31ad146..b75c059 100644
--- a/include/linux/rio_drv.h
+++ b/include/linux/rio_drv.h
@@ -365,6 +365,11 @@ void rio_release_regions(struct rio_dev *);
 int rio_request_region(struct rio_dev *, int, char *);
 void rio_release_region(struct rio_dev *, int);
 
+/* Memory mapping functions */
+extern int rio_map_inb_region(struct rio_mport *mport, dma_addr_t local,
+   u64 rbase, u32 size, u32 rflags);
+extern void rio_unmap_inb_region(struct rio_mport *mport, dma_addr_t lstart);
+
 /* Port-Write management */
 extern int rio_request_inb_pwrite(struct rio_dev *,
int (*)(struct rio_dev *, union rio_pw_msg*, int));
-- 
1.7.8.4

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH] rapidio: fix kerneldoc warnings after DMA support was added

2012-09-14 Thread Alexandre Bounine
Signed-off-by: Alexandre Bounine 
Reported-by: Robert P. J. Day 
Cc: Robert P. J. Day 
---
 include/linux/rio.h |3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/include/linux/rio.h b/include/linux/rio.h
index 1a7b6c7..ba382f2 100644
--- a/include/linux/rio.h
+++ b/include/linux/rio.h
@@ -236,6 +236,7 @@ enum rio_phy_type {
  * @phys_efptr: RIO port extended features pointer
  * @name: Port name string
  * @priv: Master port private data
+ * @dma: DMA device associated with mport
  */
 struct rio_mport {
struct list_head dbells;/* list of doorbell events */
@@ -404,7 +405,7 @@ union rio_pw_msg {
 
 #ifdef CONFIG_RAPIDIO_DMA_ENGINE
 
-/**
+/*
  * enum rio_write_type - RIO write transaction types used in DMA transfers
  *
  * Note: RapidIO specification defines write (NWRITE) and
-- 
1.7.8.4

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH] rapidio/tsi721: modify mport name assignment

2012-08-21 Thread Alexandre Bounine
Modify mport device name assignment to provide clear reference to devices
in systems with multiple Tsi721 bridges.

This patch is applicable to kernel versions starting from v3.2.

Signed-off-by: Alexandre Bounine 
Cc: Matt Porter 
---
 drivers/rapidio/devices/tsi721.c |3 ++-
 include/linux/rio.h  |3 ++-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/rapidio/devices/tsi721.c b/drivers/rapidio/devices/tsi721.c
index 5d44252..8533f36 100644
--- a/drivers/rapidio/devices/tsi721.c
+++ b/drivers/rapidio/devices/tsi721.c
@@ -2165,7 +2165,8 @@ static int __devinit tsi721_setup_mport(struct 
tsi721_device *priv)
rio_init_dbell_res(&mport->riores[RIO_DOORBELL_RESOURCE], 0, 0x);
rio_init_mbox_res(&mport->riores[RIO_INB_MBOX_RESOURCE], 0, 3);
rio_init_mbox_res(&mport->riores[RIO_OUTB_MBOX_RESOURCE], 0, 3);
-   strcpy(mport->name, "Tsi721 mport");
+   snprintf(mport->name, RIO_MAX_MPORT_NAME, "%s(%s)",
+dev_driver_string(&pdev->dev), dev_name(&pdev->dev));
 
/* Hook up interrupt handler */
 
diff --git a/include/linux/rio.h b/include/linux/rio.h
index a90ebad..1a7b6c7 100644
--- a/include/linux/rio.h
+++ b/include/linux/rio.h
@@ -30,6 +30,7 @@
 #define RIO_MAX_MPORTS 8
 #define RIO_MAX_MPORT_RESOURCES16
 #define RIO_MAX_DEV_RESOURCES  16
+#define RIO_MAX_MPORT_NAME 40
 
 #define RIO_GLOBAL_TABLE   0xff/* Indicates access of a switch's
   global routing table if it
@@ -255,7 +256,7 @@ struct rio_mport {
 */
enum rio_phy_type phy_type; /* RapidIO phy type */
u32 phys_efptr;
-   unsigned char name[40];
+   unsigned char name[RIO_MAX_MPORT_NAME];
void *priv; /* Master port private data */
 #ifdef CONFIG_RAPIDIO_DMA_ENGINE
struct dma_device   dma;
-- 
1.7.8.4

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH] rapidio: apply RX/TX enable to active switch ports only

2012-08-21 Thread Alexandre Bounine
Modify RIO enumeration to apply RX/TX enable operations only to active
switch ports. This will leave inactive ports in condition consistent with
their state.

This patch is applicable to kernel versions starting from v2.6.35.

Signed-off-by: Alexandre Bounine 
Cc: Matt Porter 
---
 drivers/rapidio/rio-scan.c |9 +
 1 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c
index 2bebd79..02e686b 100644
--- a/drivers/rapidio/rio-scan.c
+++ b/drivers/rapidio/rio-scan.c
@@ -839,12 +839,10 @@ static int __devinit rio_enum_peer(struct rio_net *net, 
struct rio_mport *port,
for (port_num = 0;
 port_num < RIO_GET_TOTAL_PORTS(rdev->swpinfo);
 port_num++) {
-   /*Enable Input Output Port (transmitter reviever)*/
-   rio_enable_rx_tx_port(port, 0,
+   if (sw_inport == port_num) {
+   rio_enable_rx_tx_port(port, 0,
  RIO_ANY_DESTID(port->sys_size),
  hopcount, port_num);
-
-   if (sw_inport == port_num) {
rdev->rswitch->port_ok |= (1 << port_num);
continue;
}
@@ -857,6 +855,9 @@ static int __devinit rio_enum_peer(struct rio_net *net, 
struct rio_mport *port,
pr_debug(
"RIO: scanning device on port %d\n",
port_num);
+   rio_enable_rx_tx_port(port, 0,
+ RIO_ANY_DESTID(port->sys_size),
+ hopcount, port_num);
rdev->rswitch->port_ok |= (1 << port_num);
rio_route_add_entry(rdev, RIO_GLOBAL_TABLE,
RIO_ANY_DESTID(port->sys_size),
-- 
1.7.8.4

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH] rapidio/tsi721: fix unused variable compiler warning

2012-08-15 Thread Alexandre Bounine
Fix unused variable compiler warning when built with CONFIG_RAPIDIO_DEBUG
option off.

This patch is applicable to kernel versions starting from v3.2

Signed-off-by: Alexandre Bounine 
Cc: Matt Porter 
---
 drivers/rapidio/devices/tsi721.c |5 -
 1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/drivers/rapidio/devices/tsi721.c b/drivers/rapidio/devices/tsi721.c
index c0d6a04..5d44252 100644
--- a/drivers/rapidio/devices/tsi721.c
+++ b/drivers/rapidio/devices/tsi721.c
@@ -2219,7 +2219,7 @@ static int __devinit tsi721_probe(struct pci_dev *pdev,
  const struct pci_device_id *id)
 {
struct tsi721_device *priv;
-   int i, cap;
+   int cap;
int err;
u32 regval;
 
@@ -2239,12 +2239,15 @@ static int __devinit tsi721_probe(struct pci_dev *pdev,
priv->pdev = pdev;
 
 #ifdef DEBUG
+   {
+   int i;
for (i = 0; i <= PCI_STD_RESOURCE_END; i++) {
dev_dbg(&pdev->dev, "res[%d] @ 0x%llx (0x%lx, 0x%lx)\n",
i, (unsigned long long)pci_resource_start(pdev, i),
(unsigned long)pci_resource_len(pdev, i),
pci_resource_flags(pdev, i));
}
+   }
 #endif
/*
 * Verify BAR configuration
-- 
1.7.8.4

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH] rapidio/tsi721: fix inbound doorbell interrupt handling

2012-08-15 Thread Alexandre Bounine
Make sure that there is no doorbell messages left behind due to disabled
interrupts during inbound doorbell processing.

The most common case for this bug is loss of rionet JOIN messages in
systems with three or more rionet participants and MSI or MSI-X enabled.
As result, requests for packet transfers may finish with
"destination unreachable" error message.

This patch is applicable to kernel versions starting from v3.2.

Signed-off-by: Alexandre Bounine 
Cc: Matt Porter 
---
 drivers/rapidio/devices/tsi721.c |7 +++
 1 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/drivers/rapidio/devices/tsi721.c b/drivers/rapidio/devices/tsi721.c
index 722246c..c0d6a04 100644
--- a/drivers/rapidio/devices/tsi721.c
+++ b/drivers/rapidio/devices/tsi721.c
@@ -435,6 +435,9 @@ static void tsi721_db_dpc(struct work_struct *work)
" info %4.4x\n", DBELL_SID(idb.bytes),
DBELL_TID(idb.bytes), DBELL_INF(idb.bytes));
}
+
+   wr_ptr = ioread32(priv->regs +
+ TSI721_IDQ_WP(IDB_QUEUE)) % IDB_QSIZE;
}
 
iowrite32(rd_ptr & (IDB_QSIZE - 1),
@@ -445,6 +448,10 @@ static void tsi721_db_dpc(struct work_struct *work)
regval |= TSI721_SR_CHINT_IDBQRCV;
iowrite32(regval,
priv->regs + TSI721_SR_CHINTE(IDB_QUEUE));
+
+   wr_ptr = ioread32(priv->regs + TSI721_IDQ_WP(IDB_QUEUE)) % IDB_QSIZE;
+   if (wr_ptr != rd_ptr)
+   schedule_work(&priv->idb_work);
 }
 
 /**
-- 
1.7.8.4

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH V2 2/2] rapidio/tsi721: add DMA engine support

2012-03-26 Thread Alexandre Bounine
Adds support for DMA Engine API into Tsi721 mport driver.

Includes following changes for Tsi721 driver:
- Modifies BDMA register offset definitions to support per-channel handling
- Separates BDMA channel reserved for RIO Maintenance requests
- Adds DMA Engine callback routines

Signed-off-by: Alexandre Bounine 
---

This patch is applicable to linux-next-20120326 and after.

v2: Address review comments,
Switched to use dma_zalloc_coherent,
Switched to use dma_transfer_direction enumerator,
Uses updated prep_slave_sg() interface. 

 drivers/rapidio/devices/Makefile |3 +
 drivers/rapidio/devices/tsi721.c |  211 ++
 drivers/rapidio/devices/tsi721.h |  105 -
 drivers/rapidio/devices/tsi721_dma.c |  823 ++
 4 files changed, 1050 insertions(+), 92 deletions(-)
 create mode 100644 drivers/rapidio/devices/tsi721_dma.c

diff --git a/drivers/rapidio/devices/Makefile b/drivers/rapidio/devices/Makefile
index 3b7b4e2..7b62860 100644
--- a/drivers/rapidio/devices/Makefile
+++ b/drivers/rapidio/devices/Makefile
@@ -3,3 +3,6 @@
 #
 
 obj-$(CONFIG_RAPIDIO_TSI721)   += tsi721.o
+ifeq ($(CONFIG_RAPIDIO_DMA_ENGINE),y)
+obj-$(CONFIG_RAPIDIO_TSI721)   += tsi721_dma.o
+endif
diff --git a/drivers/rapidio/devices/tsi721.c b/drivers/rapidio/devices/tsi721.c
index 30d2072..722246c 100644
--- a/drivers/rapidio/devices/tsi721.c
+++ b/drivers/rapidio/devices/tsi721.c
@@ -108,6 +108,7 @@ static int tsi721_maint_dma(struct tsi721_device *priv, u32 
sys_size,
u16 destid, u8 hopcount, u32 offset, int len,
u32 *data, int do_wr)
 {
+   void __iomem *regs = priv->regs + TSI721_DMAC_BASE(priv->mdma.ch_id);
struct tsi721_dma_desc *bd_ptr;
u32 rd_count, swr_ptr, ch_stat;
int i, err = 0;
@@ -116,10 +117,9 @@ static int tsi721_maint_dma(struct tsi721_device *priv, 
u32 sys_size,
if (offset > (RIO_MAINT_SPACE_SZ - len) || (len != sizeof(u32)))
return -EINVAL;
 
-   bd_ptr = priv->bdma[TSI721_DMACH_MAINT].bd_base;
+   bd_ptr = priv->mdma.bd_base;
 
-   rd_count = ioread32(
-   priv->regs + TSI721_DMAC_DRDCNT(TSI721_DMACH_MAINT));
+   rd_count = ioread32(regs + TSI721_DMAC_DRDCNT);
 
/* Initialize DMA descriptor */
bd_ptr[0].type_id = cpu_to_le32((DTYPE2 << 29) | (op << 19) | destid);
@@ -134,19 +134,18 @@ static int tsi721_maint_dma(struct tsi721_device *priv, 
u32 sys_size,
mb();
 
/* Start DMA operation */
-   iowrite32(rd_count + 2,
-   priv->regs + TSI721_DMAC_DWRCNT(TSI721_DMACH_MAINT));
-   ioread32(priv->regs + TSI721_DMAC_DWRCNT(TSI721_DMACH_MAINT));
+   iowrite32(rd_count + 2, regs + TSI721_DMAC_DWRCNT);
+   ioread32(regs + TSI721_DMAC_DWRCNT);
i = 0;
 
/* Wait until DMA transfer is finished */
-   while ((ch_stat = ioread32(priv->regs +
-   TSI721_DMAC_STS(TSI721_DMACH_MAINT))) & TSI721_DMAC_STS_RUN) {
+   while ((ch_stat = ioread32(regs + TSI721_DMAC_STS))
+   & TSI721_DMAC_STS_RUN) {
udelay(1);
if (++i >= 500) {
dev_dbg(&priv->pdev->dev,
"%s : DMA[%d] read timeout ch_status=%x\n",
-   __func__, TSI721_DMACH_MAINT, ch_stat);
+   __func__, priv->mdma.ch_id, ch_stat);
if (!do_wr)
*data = 0x;
err = -EIO;
@@ -162,13 +161,10 @@ static int tsi721_maint_dma(struct tsi721_device *priv, 
u32 sys_size,
__func__, ch_stat);
dev_dbg(&priv->pdev->dev, "OP=%d : destid=%x hc=%x off=%x\n",
do_wr ? MAINT_WR : MAINT_RD, destid, hopcount, offset);
-   iowrite32(TSI721_DMAC_INT_ALL,
-   priv->regs + TSI721_DMAC_INT(TSI721_DMACH_MAINT));
-   iowrite32(TSI721_DMAC_CTL_INIT,
-   priv->regs + TSI721_DMAC_CTL(TSI721_DMACH_MAINT));
+   iowrite32(TSI721_DMAC_INT_ALL, regs + TSI721_DMAC_INT);
+   iowrite32(TSI721_DMAC_CTL_INIT, regs + TSI721_DMAC_CTL);
udelay(10);
-   iowrite32(0, priv->regs +
-   TSI721_DMAC_DWRCNT(TSI721_DMACH_MAINT));
+   iowrite32(0, regs + TSI721_DMAC_DWRCNT);
udelay(1);
if (!do_wr)
*data = 0x;
@@ -184,8 +180,8 @@ static int tsi721_maint_dma(struct tsi721_device *priv, u32 
sys_size,
 * NOTE: Skipping check and clear FIFO entries because we are waiting
 * for transfer to be completed.
 */
-   swr_ptr = ioread32(priv->regs + TSI721_DMAC_DSWP(TSI721_DMAC

[PATCH V2 1/2] rapidio: add DMA engine support for RIO data transfers

2012-03-26 Thread Alexandre Bounine
Adds DMA Engine framework support into RapidIO subsystem.
Uses DMA Engine DMA_SLAVE interface to generate data transfers to/from
remote RapidIO target devices.
Introduces RapidIO-specific wrapper for prep_slave_sg() interface
with an extra parameter to pass target specific information.
Uses scatterlist to describe local data buffer. Address flat data buffer
on a remote side.

Signed-off-by: Alexandre Bounine 
---

This patch is applicable to linux-next-20120326 and after.

v2: Uses updated DMA engine prep_slave_sg() interface.
See https://lkml.org/lkml/2012/3/8/373 for more details.

 drivers/rapidio/Kconfig   |   14 
 drivers/rapidio/rio.c |   81 +
 include/linux/dmaengine.h |   12 +++
 include/linux/rio.h   |   47 ++
 include/linux/rio_drv.h   |9 +
 5 files changed, 163 insertions(+), 0 deletions(-)

diff --git a/drivers/rapidio/Kconfig b/drivers/rapidio/Kconfig
index bc87192..6194d35 100644
--- a/drivers/rapidio/Kconfig
+++ b/drivers/rapidio/Kconfig
@@ -22,6 +22,20 @@ config RAPIDIO_ENABLE_RX_TX_PORTS
  ports for Input/Output direction to allow other traffic
  than Maintenance transfers.
 
+config RAPIDIO_DMA_ENGINE
+   bool "DMA Engine support for RapidIO"
+   depends on RAPIDIO
+   select DMADEVICES
+   select DMA_ENGINE
+   help
+ Say Y here if you want to use DMA Engine frameork for RapidIO data
+ transfers to/from target RIO devices. RapidIO uses NREAD and
+ NWRITE (NWRITE_R, SWRITE) requests to transfer data between local
+ memory and memory on remote target device. You need a DMA controller
+ capable to perform data transfers to/from RapidIO.
+
+ If you are unsure about this, say Y here.
+
 config RAPIDIO_DEBUG
bool "RapidIO subsystem debug messages"
depends on RAPIDIO
diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c
index 86c9a09..c40665a 100644
--- a/drivers/rapidio/rio.c
+++ b/drivers/rapidio/rio.c
@@ -1121,6 +1121,87 @@ int rio_std_route_clr_table(struct rio_mport *mport, u16 
destid, u8 hopcount,
return 0;
 }
 
+#ifdef CONFIG_RAPIDIO_DMA_ENGINE
+
+static bool rio_chan_filter(struct dma_chan *chan, void *arg)
+{
+   struct rio_dev *rdev = arg;
+
+   /* Check that DMA device belongs to the right MPORT */
+   return (rdev->net->hport ==
+   container_of(chan->device, struct rio_mport, dma));
+}
+
+/**
+ * rio_request_dma - request RapidIO capable DMA channel that supports
+ *   specified target RapidIO device.
+ * @rdev: RIO device control structure
+ *
+ * Returns pointer to allocated DMA channel or NULL if failed.
+ */
+struct dma_chan *rio_request_dma(struct rio_dev *rdev)
+{
+   dma_cap_mask_t mask;
+   struct dma_chan *dchan;
+
+   dma_cap_zero(mask);
+   dma_cap_set(DMA_SLAVE, mask);
+   dchan = dma_request_channel(mask, rio_chan_filter, rdev);
+
+   return dchan;
+}
+EXPORT_SYMBOL_GPL(rio_request_dma);
+
+/**
+ * rio_release_dma - release specified DMA channel
+ * @dchan: DMA channel to release
+ */
+void rio_release_dma(struct dma_chan *dchan)
+{
+   dma_release_channel(dchan);
+}
+EXPORT_SYMBOL_GPL(rio_release_dma);
+
+/**
+ * rio_dma_prep_slave_sg - RapidIO specific wrapper
+ *   for device_prep_slave_sg callback defined by DMAENGINE.
+ * @rdev: RIO device control structure
+ * @dchan: DMA channel to configure
+ * @data: RIO specific data descriptor
+ * @direction: DMA data transfer direction (TO or FROM the device)
+ * @flags: dmaengine defined flags
+ *
+ * Initializes RapidIO capable DMA channel for the specified data transfer.
+ * Uses DMA channel private extension to pass information related to remote
+ * target RIO device.
+ * Returns pointer to DMA transaction descriptor or NULL if failed.
+ */
+struct dma_async_tx_descriptor *rio_dma_prep_slave_sg(struct rio_dev *rdev,
+   struct dma_chan *dchan, struct rio_dma_data *data,
+   enum dma_transfer_direction direction, unsigned long flags)
+{
+   struct dma_async_tx_descriptor *txd = NULL;
+   struct rio_dma_ext rio_ext;
+
+   if (dchan->device->device_prep_slave_sg == NULL) {
+   pr_err("%s: prep_rio_sg == NULL\n", __func__);
+   return NULL;
+   }
+
+   rio_ext.destid = rdev->destid;
+   rio_ext.rio_addr_u = data->rio_addr_u;
+   rio_ext.rio_addr = data->rio_addr;
+   rio_ext.wr_type = data->wr_type;
+
+   txd = dmaengine_prep_rio_sg(dchan, data->sg, data->sg_len,
+   direction, flags, &rio_ext);
+
+   return txd;
+}
+EXPORT_SYMBOL_GPL(rio_dma_prep_slave_sg);
+
+#endif /* CONFIG_RAPIDIO_DMA_ENGINE */
+
 static void rio_fixup_device(struct rio_dev *dev)
 {
 }
diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
index 676f967..3596a3a 100644
--- a/include/linux/dmaengine.h
+++ b/

[PATCH] rapidio/tsi721: fix bug in inbound doorbell handler

2012-03-05 Thread Alexandre Bounine
Fixes queue wrapping bug in Inbound Doorbell handling routine.

Signed-off-by: Alexandre Bounine 
Cc: Chul Kim 
Cc: Matt Porter 
---
 This patch is applicable to kernel version 3.2 and after.

 drivers/rapidio/devices/tsi721.c |5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/rapidio/devices/tsi721.c b/drivers/rapidio/devices/tsi721.c
index babbede..c746e26 100644
--- a/drivers/rapidio/devices/tsi721.c
+++ b/drivers/rapidio/devices/tsi721.c
@@ -406,13 +406,14 @@ static void tsi721_db_dpc(struct work_struct *work)
 */
mport = priv->mport;
 
-   wr_ptr = ioread32(priv->regs + TSI721_IDQ_WP(IDB_QUEUE));
-   rd_ptr = ioread32(priv->regs + TSI721_IDQ_RP(IDB_QUEUE));
+   wr_ptr = ioread32(priv->regs + TSI721_IDQ_WP(IDB_QUEUE)) % IDB_QSIZE;
+   rd_ptr = ioread32(priv->regs + TSI721_IDQ_RP(IDB_QUEUE)) % IDB_QSIZE;
 
while (wr_ptr != rd_ptr) {
idb_entry = (u64 *)(priv->idb_base +
(TSI721_IDB_ENTRY_SIZE * rd_ptr));
rd_ptr++;
+   rd_ptr %= IDB_QSIZE;
idb.msg = *idb_entry;
*idb_entry = 0;
 
-- 
1.7.8.4

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[RFC] dmaengine/dma_slave: add context parameter to prep_slave_sg callback

2012-01-26 Thread Alexandre Bounine
As we agreed during our discussion about adding DMA Engine support for RapidIO
subsystem, RapidIO and similar clients may benefit from adding an extra context
parameter to device_prep_slave_sg() callback.
See https://lkml.org/lkml/2011/10/24/275 for more details.

Adding the context parameter will allow to pass client/target specific
information associated with an individual data transfer request.

In the case of RapidIO support this additional information consists of target
destination ID and its buffer address (which is not mapped into the local CPU
memory space). Because a single RapidIO-capable DMA channel may queue data
transfer requests to different target devices, the per-request configuration
is required.

The proposed change eliminates need for new subsystem-specific API.
Existing DMA_SLAVE clients will ignore the new parameter.

This RFC only demonstrates the API change and does not include corresponding
changes to existing DMA_SLAVE clients. Complete set of patches will be provided
after (if) this API change is accepted.

Signed-off-by: Alexandre Bounine 
Cc: Jassi Brar 
Cc: Russell King  
Cc: Kumar Gala 
Cc: Matt Porter 
Cc: Li Yang 
---
 include/linux/dmaengine.h |7 ---
 1 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
index 679b349..79d71bb 100644
--- a/include/linux/dmaengine.h
+++ b/include/linux/dmaengine.h
@@ -575,7 +575,7 @@ struct dma_device {
struct dma_async_tx_descriptor *(*device_prep_slave_sg)(
struct dma_chan *chan, struct scatterlist *sgl,
unsigned int sg_len, enum dma_transfer_direction direction,
-   unsigned long flags);
+   unsigned long flags, void *context);
struct dma_async_tx_descriptor *(*device_prep_dma_cyclic)(
struct dma_chan *chan, dma_addr_t buf_addr, size_t buf_len,
size_t period_len, enum dma_transfer_direction direction);
@@ -607,12 +607,13 @@ static inline int dmaengine_slave_config(struct dma_chan 
*chan,
 
 static inline struct dma_async_tx_descriptor *dmaengine_prep_slave_single(
struct dma_chan *chan, void *buf, size_t len,
-   enum dma_transfer_direction dir, unsigned long flags)
+   enum dma_transfer_direction dir, unsigned long flags, void *context)
 {
struct scatterlist sg;
sg_init_one(&sg, buf, len);
 
-   return chan->device->device_prep_slave_sg(chan, &sg, 1, dir, flags);
+   return chan->device->device_prep_slave_sg(chan, &sg, 1, dir, flags,
+ context);
 }
 
 static inline int dmaengine_terminate_all(struct dma_chan *chan)
-- 
1.7.8.4

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH RESEND] rapidio/tsi721: modify PCIe capability settings

2011-12-07 Thread Alexandre Bounine
Modify initialization of PCIe capability registers in Tsi721 mport driver:
- change Completion Timeout value to avoid unexpected data transfer aborts
  during intensive traffic.
- replace hardcoded offset of PCIe capability block by getting it using
  the common function.

This patch is applicable to kernel versions starting from 3.2-rc1.

Signed-off-by: Alexandre Bounine 
---

[Resending this patch with updated commit comment]

 drivers/rapidio/devices/tsi721.c |   20 +++-
 drivers/rapidio/devices/tsi721.h |2 ++
 2 files changed, 17 insertions(+), 5 deletions(-)

diff --git a/drivers/rapidio/devices/tsi721.c b/drivers/rapidio/devices/tsi721.c
index 83ac8728..691b1ab 100644
--- a/drivers/rapidio/devices/tsi721.c
+++ b/drivers/rapidio/devices/tsi721.c
@@ -2154,7 +2154,7 @@ static int __devinit tsi721_probe(struct pci_dev *pdev,
  const struct pci_device_id *id)
 {
struct tsi721_device *priv;
-   int i;
+   int i, cap;
int err;
u32 regval;
 
@@ -2262,10 +2262,20 @@ static int __devinit tsi721_probe(struct pci_dev *pdev,
dev_info(&pdev->dev, "Unable to set consistent DMA 
mask\n");
}
 
-   /* Clear "no snoop" and "relaxed ordering" bits. */
-   pci_read_config_dword(pdev, 0x40 + PCI_EXP_DEVCTL, ®val);
-   regval &= ~(PCI_EXP_DEVCTL_RELAX_EN | PCI_EXP_DEVCTL_NOSNOOP_EN);
-   pci_write_config_dword(pdev, 0x40 + PCI_EXP_DEVCTL, regval);
+   cap = pci_pcie_cap(pdev);
+   BUG_ON(cap == 0);
+
+   /* Clear "no snoop" and "relaxed ordering" bits, use default MRRS. */
+   pci_read_config_dword(pdev, cap + PCI_EXP_DEVCTL, ®val);
+   regval &= ~(PCI_EXP_DEVCTL_READRQ | PCI_EXP_DEVCTL_RELAX_EN |
+   PCI_EXP_DEVCTL_NOSNOOP_EN);
+   regval |= 0x2 << MAX_READ_REQUEST_SZ_SHIFT;
+   pci_write_config_dword(pdev, cap + PCI_EXP_DEVCTL, regval);
+
+   /* Adjust PCIe completion timeout. */
+   pci_read_config_dword(pdev, cap + PCI_EXP_DEVCTL2, ®val);
+   regval &= ~(0x0f);
+   pci_write_config_dword(pdev, cap + PCI_EXP_DEVCTL2, regval | 0x2);
 
/*
 * FIXUP: correct offsets of MSI-X tables in the MSI-X Capability Block
diff --git a/drivers/rapidio/devices/tsi721.h b/drivers/rapidio/devices/tsi721.h
index 58be4de..822e54c 100644
--- a/drivers/rapidio/devices/tsi721.h
+++ b/drivers/rapidio/devices/tsi721.h
@@ -72,6 +72,8 @@
 #define TSI721_MSIXPBA_OFFSET  0x2a000
 #define TSI721_PCIECFG_EPCTL   0x400
 
+#define MAX_READ_REQUEST_SZ_SHIFT  12
+
 /*
  * Event Management Registers
  */
-- 
1.7.6

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH RESEND] rapidio/tsi721: Fix mailbox resource reporting

2011-12-07 Thread Alexandre Bounine
Bug fix for Tsi721 RapidIO mport driver:
Tsi721 supports four RapidIO mailboxes (MBOX0 - MBOX3) as defined by RapidIO
specification. Mailbox resources has to be properly reported to allow use
of all available mailboxes (initial version reports only MBOX0).

This patch is applicable to kernel versions staring from 3.2-rc1.

Signed-off-by: Alexandre Bounine 
---

[Resending this patch with updated commit comment]

 drivers/rapidio/devices/tsi721.c |4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/rapidio/devices/tsi721.c b/drivers/rapidio/devices/tsi721.c
index 514c28c..83ac8728 100644
--- a/drivers/rapidio/devices/tsi721.c
+++ b/drivers/rapidio/devices/tsi721.c
@@ -2107,8 +2107,8 @@ static int __devinit tsi721_setup_mport(struct 
tsi721_device *priv)
INIT_LIST_HEAD(&mport->dbells);
 
rio_init_dbell_res(&mport->riores[RIO_DOORBELL_RESOURCE], 0, 0x);
-   rio_init_mbox_res(&mport->riores[RIO_INB_MBOX_RESOURCE], 0, 0);
-   rio_init_mbox_res(&mport->riores[RIO_OUTB_MBOX_RESOURCE], 0, 0);
+   rio_init_mbox_res(&mport->riores[RIO_INB_MBOX_RESOURCE], 0, 3);
+   rio_init_mbox_res(&mport->riores[RIO_OUTB_MBOX_RESOURCE], 0, 3);
strcpy(mport->name, "Tsi721 mport");
 
/* Hook up interrupt handler */
-- 
1.7.6

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH] rapidio/tsi721: Fix mailbox resource reporting

2011-12-06 Thread Alexandre Bounine
Report support of four RapidIO mailboxes (MBOX0 - MBOX3) instead of MBOX0
only.

Signed-off-by: Alexandre Bounine 
---
 drivers/rapidio/devices/tsi721.c |4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/rapidio/devices/tsi721.c b/drivers/rapidio/devices/tsi721.c
index 514c28c..83ac8728 100644
--- a/drivers/rapidio/devices/tsi721.c
+++ b/drivers/rapidio/devices/tsi721.c
@@ -2107,8 +2107,8 @@ static int __devinit tsi721_setup_mport(struct 
tsi721_device *priv)
INIT_LIST_HEAD(&mport->dbells);
 
rio_init_dbell_res(&mport->riores[RIO_DOORBELL_RESOURCE], 0, 0x);
-   rio_init_mbox_res(&mport->riores[RIO_INB_MBOX_RESOURCE], 0, 0);
-   rio_init_mbox_res(&mport->riores[RIO_OUTB_MBOX_RESOURCE], 0, 0);
+   rio_init_mbox_res(&mport->riores[RIO_INB_MBOX_RESOURCE], 0, 3);
+   rio_init_mbox_res(&mport->riores[RIO_OUTB_MBOX_RESOURCE], 0, 3);
strcpy(mport->name, "Tsi721 mport");
 
/* Hook up interrupt handler */
-- 
1.7.6

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH] rapidio/tsi721: modify PCIe capability settings

2011-12-06 Thread Alexandre Bounine
Change Completion Timeout Value to avoid data transfer aborts during
intensive data transfers.
Remove hardcoded offset for PCIe capability registers.

Signed-off-by: Alexandre Bounine 
---
 drivers/rapidio/devices/tsi721.c |   20 +++-
 drivers/rapidio/devices/tsi721.h |2 ++
 2 files changed, 17 insertions(+), 5 deletions(-)

diff --git a/drivers/rapidio/devices/tsi721.c b/drivers/rapidio/devices/tsi721.c
index 83ac8728..691b1ab 100644
--- a/drivers/rapidio/devices/tsi721.c
+++ b/drivers/rapidio/devices/tsi721.c
@@ -2154,7 +2154,7 @@ static int __devinit tsi721_probe(struct pci_dev *pdev,
  const struct pci_device_id *id)
 {
struct tsi721_device *priv;
-   int i;
+   int i, cap;
int err;
u32 regval;
 
@@ -2262,10 +2262,20 @@ static int __devinit tsi721_probe(struct pci_dev *pdev,
dev_info(&pdev->dev, "Unable to set consistent DMA 
mask\n");
}
 
-   /* Clear "no snoop" and "relaxed ordering" bits. */
-   pci_read_config_dword(pdev, 0x40 + PCI_EXP_DEVCTL, ®val);
-   regval &= ~(PCI_EXP_DEVCTL_RELAX_EN | PCI_EXP_DEVCTL_NOSNOOP_EN);
-   pci_write_config_dword(pdev, 0x40 + PCI_EXP_DEVCTL, regval);
+   cap = pci_pcie_cap(pdev);
+   BUG_ON(cap == 0);
+
+   /* Clear "no snoop" and "relaxed ordering" bits, use default MRRS. */
+   pci_read_config_dword(pdev, cap + PCI_EXP_DEVCTL, ®val);
+   regval &= ~(PCI_EXP_DEVCTL_READRQ | PCI_EXP_DEVCTL_RELAX_EN |
+   PCI_EXP_DEVCTL_NOSNOOP_EN);
+   regval |= 0x2 << MAX_READ_REQUEST_SZ_SHIFT;
+   pci_write_config_dword(pdev, cap + PCI_EXP_DEVCTL, regval);
+
+   /* Adjust PCIe completion timeout. */
+   pci_read_config_dword(pdev, cap + PCI_EXP_DEVCTL2, ®val);
+   regval &= ~(0x0f);
+   pci_write_config_dword(pdev, cap + PCI_EXP_DEVCTL2, regval | 0x2);
 
/*
 * FIXUP: correct offsets of MSI-X tables in the MSI-X Capability Block
diff --git a/drivers/rapidio/devices/tsi721.h b/drivers/rapidio/devices/tsi721.h
index 58be4de..822e54c 100644
--- a/drivers/rapidio/devices/tsi721.h
+++ b/drivers/rapidio/devices/tsi721.h
@@ -72,6 +72,8 @@
 #define TSI721_MSIXPBA_OFFSET  0x2a000
 #define TSI721_PCIECFG_EPCTL   0x400
 
+#define MAX_READ_REQUEST_SZ_SHIFT  12
+
 /*
  * Event Management Registers
  */
-- 
1.7.6

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH] rapidio/tsi721: switch to dma_zalloc_coherent

2011-12-05 Thread Alexandre Bounine
Replaces pair dma_alloc_coherent()+memset() with new dma_zalloc_coherent()
added by Andrew Morton for kernel version 3.2

Signed-off-by: Alexandre Bounine 
---
 drivers/rapidio/devices/tsi721.c |   17 -
 1 files changed, 4 insertions(+), 13 deletions(-)

diff --git a/drivers/rapidio/devices/tsi721.c b/drivers/rapidio/devices/tsi721.c
index 5225930..514c28c 100644
--- a/drivers/rapidio/devices/tsi721.c
+++ b/drivers/rapidio/devices/tsi721.c
@@ -851,14 +851,12 @@ static int tsi721_doorbell_init(struct tsi721_device 
*priv)
INIT_WORK(&priv->idb_work, tsi721_db_dpc);
 
/* Allocate buffer for inbound doorbells queue */
-   priv->idb_base = dma_alloc_coherent(&priv->pdev->dev,
+   priv->idb_base = dma_zalloc_coherent(&priv->pdev->dev,
IDB_QSIZE * TSI721_IDB_ENTRY_SIZE,
&priv->idb_dma, GFP_KERNEL);
if (!priv->idb_base)
return -ENOMEM;
 
-   memset(priv->idb_base, 0, IDB_QSIZE * TSI721_IDB_ENTRY_SIZE);
-
dev_dbg(&priv->pdev->dev, "Allocated IDB buffer @ %p (phys = %llx)\n",
priv->idb_base, (unsigned long long)priv->idb_dma);
 
@@ -904,7 +902,7 @@ static int tsi721_bdma_ch_init(struct tsi721_device *priv, 
int chnum)
 */
 
/* Allocate space for DMA descriptors */
-   bd_ptr = dma_alloc_coherent(&priv->pdev->dev,
+   bd_ptr = dma_zalloc_coherent(&priv->pdev->dev,
bd_num * sizeof(struct tsi721_dma_desc),
&bd_phys, GFP_KERNEL);
if (!bd_ptr)
@@ -913,8 +911,6 @@ static int tsi721_bdma_ch_init(struct tsi721_device *priv, 
int chnum)
priv->bdma[chnum].bd_phys = bd_phys;
priv->bdma[chnum].bd_base = bd_ptr;
 
-   memset(bd_ptr, 0, bd_num * sizeof(struct tsi721_dma_desc));
-
dev_dbg(&priv->pdev->dev, "DMA descriptors @ %p (phys = %llx)\n",
bd_ptr, (unsigned long long)bd_phys);
 
@@ -922,7 +918,7 @@ static int tsi721_bdma_ch_init(struct tsi721_device *priv, 
int chnum)
sts_size = (bd_num >= TSI721_DMA_MINSTSSZ) ?
bd_num : TSI721_DMA_MINSTSSZ;
sts_size = roundup_pow_of_two(sts_size);
-   sts_ptr = dma_alloc_coherent(&priv->pdev->dev,
+   sts_ptr = dma_zalloc_coherent(&priv->pdev->dev,
 sts_size * sizeof(struct tsi721_dma_sts),
 &sts_phys, GFP_KERNEL);
if (!sts_ptr) {
@@ -938,8 +934,6 @@ static int tsi721_bdma_ch_init(struct tsi721_device *priv, 
int chnum)
priv->bdma[chnum].sts_base = sts_ptr;
priv->bdma[chnum].sts_size = sts_size;
 
-   memset(sts_ptr, 0, sts_size);
-
dev_dbg(&priv->pdev->dev,
"desc status FIFO @ %p (phys = %llx) size=0x%x\n",
sts_ptr, (unsigned long long)sts_phys, sts_size);
@@ -1400,7 +1394,7 @@ static int tsi721_open_outb_mbox(struct rio_mport *mport, 
void *dev_id,
 
/* Outbound message descriptor status FIFO allocation */
priv->omsg_ring[mbox].sts_size = roundup_pow_of_two(entries + 1);
-   priv->omsg_ring[mbox].sts_base = dma_alloc_coherent(&priv->pdev->dev,
+   priv->omsg_ring[mbox].sts_base = dma_zalloc_coherent(&priv->pdev->dev,
priv->omsg_ring[mbox].sts_size *
sizeof(struct tsi721_dma_sts),
&priv->omsg_ring[mbox].sts_phys, GFP_KERNEL);
@@ -1412,9 +1406,6 @@ static int tsi721_open_outb_mbox(struct rio_mport *mport, 
void *dev_id,
goto out_desc;
}
 
-   memset(priv->omsg_ring[mbox].sts_base, 0,
-   entries * sizeof(struct tsi721_dma_sts));
-
/*
 * Configure Outbound Messaging Engine
 */
-- 
1.7.6

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[RFC PATCH 2/2 -mm] RapidIO: TSI721 Add DMA Engine support

2011-09-30 Thread Alexandre Bounine
Adds support for DMA Engine API.

Includes following changes:
- Modifies BDMA register offset definitions to support per-channel handling
- Separates BDMA channel reserved for RIO Maintenance requests
- Adds DMA Engine callback routines

Signed-off-by: Alexandre Bounine 
Cc: Vinod Koul 
Cc: Kumar Gala 
Cc: Matt Porter 
Cc: Li Yang 
---
 drivers/rapidio/devices/Kconfig  |8 +
 drivers/rapidio/devices/Makefile |1 +
 drivers/rapidio/devices/tsi721.c |  201 ++
 drivers/rapidio/devices/tsi721.h |  107 -
 drivers/rapidio/devices/tsi721_dma.c |  802 ++
 5 files changed, 1029 insertions(+), 90 deletions(-)
 create mode 100644 drivers/rapidio/devices/tsi721_dma.c

diff --git a/drivers/rapidio/devices/Kconfig b/drivers/rapidio/devices/Kconfig
index 12a9d7f..3a2db3d 100644
--- a/drivers/rapidio/devices/Kconfig
+++ b/drivers/rapidio/devices/Kconfig
@@ -8,3 +8,11 @@ config RAPIDIO_TSI721
default "n"
---help---
  Include support for IDT Tsi721 PCI Express Serial RapidIO controller.
+
+config TSI721_DMA
+   bool "IDT Tsi721 RapidIO DMA support"
+   depends on RAPIDIO_TSI721
+   default "n"
+   select RAPIDIO_DMA_ENGINE
+   help
+ Enable DMA support for IDT Tsi721 PCIe-to-SRIO controller.
diff --git a/drivers/rapidio/devices/Makefile b/drivers/rapidio/devices/Makefile
index 3b7b4e2..8cbce45 100644
--- a/drivers/rapidio/devices/Makefile
+++ b/drivers/rapidio/devices/Makefile
@@ -3,3 +3,4 @@
 #
 
 obj-$(CONFIG_RAPIDIO_TSI721)   += tsi721.o
+obj-$(CONFIG_TSI721_DMA) += tsi721_dma.o
diff --git a/drivers/rapidio/devices/tsi721.c b/drivers/rapidio/devices/tsi721.c
index 5225930..5e893a6 100644
--- a/drivers/rapidio/devices/tsi721.c
+++ b/drivers/rapidio/devices/tsi721.c
@@ -108,6 +108,7 @@ static int tsi721_maint_dma(struct tsi721_device *priv, u32 
sys_size,
u16 destid, u8 hopcount, u32 offset, int len,
u32 *data, int do_wr)
 {
+   void __iomem *regs = priv->regs + TSI721_DMAC_BASE(priv->mdma.ch_id);
struct tsi721_dma_desc *bd_ptr;
u32 rd_count, swr_ptr, ch_stat;
int i, err = 0;
@@ -116,10 +117,9 @@ static int tsi721_maint_dma(struct tsi721_device *priv, 
u32 sys_size,
if (offset > (RIO_MAINT_SPACE_SZ - len) || (len != sizeof(u32)))
return -EINVAL;
 
-   bd_ptr = priv->bdma[TSI721_DMACH_MAINT].bd_base;
+   bd_ptr = priv->mdma.bd_base;
 
-   rd_count = ioread32(
-   priv->regs + TSI721_DMAC_DRDCNT(TSI721_DMACH_MAINT));
+   rd_count = ioread32(regs + TSI721_DMAC_DRDCNT);
 
/* Initialize DMA descriptor */
bd_ptr[0].type_id = cpu_to_le32((DTYPE2 << 29) | (op << 19) | destid);
@@ -134,19 +134,18 @@ static int tsi721_maint_dma(struct tsi721_device *priv, 
u32 sys_size,
mb();
 
/* Start DMA operation */
-   iowrite32(rd_count + 2,
-   priv->regs + TSI721_DMAC_DWRCNT(TSI721_DMACH_MAINT));
-   ioread32(priv->regs + TSI721_DMAC_DWRCNT(TSI721_DMACH_MAINT));
+   iowrite32(rd_count + 2, regs + TSI721_DMAC_DWRCNT);
+   ioread32(regs + TSI721_DMAC_DWRCNT);
i = 0;
 
/* Wait until DMA transfer is finished */
-   while ((ch_stat = ioread32(priv->regs +
-   TSI721_DMAC_STS(TSI721_DMACH_MAINT))) & TSI721_DMAC_STS_RUN) {
+   while ((ch_stat = ioread32(regs + TSI721_DMAC_STS))
+   & TSI721_DMAC_STS_RUN) {
udelay(1);
if (++i >= 500) {
dev_dbg(&priv->pdev->dev,
"%s : DMA[%d] read timeout ch_status=%x\n",
-   __func__, TSI721_DMACH_MAINT, ch_stat);
+   __func__, priv->mdma.ch_id, ch_stat);
if (!do_wr)
*data = 0x;
err = -EIO;
@@ -162,13 +161,10 @@ static int tsi721_maint_dma(struct tsi721_device *priv, 
u32 sys_size,
__func__, ch_stat);
dev_dbg(&priv->pdev->dev, "OP=%d : destid=%x hc=%x off=%x\n",
do_wr ? MAINT_WR : MAINT_RD, destid, hopcount, offset);
-   iowrite32(TSI721_DMAC_INT_ALL,
-   priv->regs + TSI721_DMAC_INT(TSI721_DMACH_MAINT));
-   iowrite32(TSI721_DMAC_CTL_INIT,
-   priv->regs + TSI721_DMAC_CTL(TSI721_DMACH_MAINT));
+   iowrite32(TSI721_DMAC_INT_ALL, regs + TSI721_DMAC_INT);
+   iowrite32(TSI721_DMAC_CTL_INIT, regs + TSI721_DMAC_CTL);
udelay(10);
-   iowrite32(0, priv->regs +
-   TSI721_DMAC_DWRCNT(TSI721_DMACH_MAINT));
+   iowrite32(0, regs + TSI721_DMAC_DWRCNT

[RFC PATCH 1/2] RapidIO: Add DMA Engine support for RIO data transfers

2011-09-30 Thread Alexandre Bounine
Adds DMA Engine framework support into RapidIO subsystem.
Uses DMA Engine DMA_SLAVE interface to generate data transfers to/from remote
RapidIO target devices. Uses scatterlist to describe local data buffer and
dma_chan.private member to pass target specific information. Supports flat
data buffer only for a remote side.

Signed-off-by: Alexandre Bounine 
Cc: Vinod Koul 
Cc: Kumar Gala 
Cc: Matt Porter 
Cc: Li Yang 
---
 drivers/dma/dmaengine.c   |4 ++
 drivers/rapidio/Kconfig   |6 +++
 drivers/rapidio/rio.c |   79 +
 include/linux/dmaengine.h |1 +
 include/linux/rio.h   |   47 ++
 include/linux/rio_drv.h   |9 +
 6 files changed, 146 insertions(+), 0 deletions(-)

diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
index b48967b..11fdc2c 100644
--- a/drivers/dma/dmaengine.c
+++ b/drivers/dma/dmaengine.c
@@ -699,6 +699,10 @@ int dma_async_device_register(struct dma_device *device)
!device->device_prep_dma_cyclic);
BUG_ON(dma_has_cap(DMA_SLAVE, device->cap_mask) &&
!device->device_control);
+   BUG_ON(dma_has_cap(DMA_RAPIDIO, device->cap_mask) &&
+   !device->device_prep_slave_sg);
+   BUG_ON(dma_has_cap(DMA_RAPIDIO, device->cap_mask) &&
+   !device->device_control);
 
BUG_ON(!device->device_alloc_chan_resources);
BUG_ON(!device->device_free_chan_resources);
diff --git a/drivers/rapidio/Kconfig b/drivers/rapidio/Kconfig
index bc87192..c4aa279 100644
--- a/drivers/rapidio/Kconfig
+++ b/drivers/rapidio/Kconfig
@@ -34,3 +34,9 @@ config RAPIDIO_DEBUG
  If you are unsure about this, say N here.
 
 source "drivers/rapidio/switches/Kconfig"
+
+# This option to be turned on by a device selection
+config RAPIDIO_DMA_ENGINE
+   bool
+   select DMADEVICES
+   select DMA_ENGINE
diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c
index 86c9a09..e5905fc 100644
--- a/drivers/rapidio/rio.c
+++ b/drivers/rapidio/rio.c
@@ -1121,6 +1121,85 @@ int rio_std_route_clr_table(struct rio_mport *mport, u16 
destid, u8 hopcount,
return 0;
 }
 
+#ifdef CONFIG_RAPIDIO_DMA_ENGINE
+
+#include 
+
+static bool rio_chan_filter(struct dma_chan *chan, void *arg)
+{
+   struct rio_dev *rdev = arg;
+
+   /* Check that DMA device belongs to the right MPORT */
+   return (rdev->net->hport ==
+   container_of(chan->device, struct rio_mport, dma));
+}
+
+/**
+ * rio_request_dma - request RapidIO capable DMA channel that supports
+ *   specified target RapidIO device.
+ * @rdev: RIO device control structure
+ *
+ * Returns pointer to allocated DMA channel or NULL if failed.
+ */
+struct dma_chan *rio_request_dma(struct rio_dev *rdev)
+{
+   dma_cap_mask_t mask;
+   struct dma_chan *dchan;
+
+   dma_cap_zero(mask);
+   dma_cap_set(DMA_RAPIDIO, mask);
+   dchan = dma_request_channel(mask, rio_chan_filter, rdev);
+
+   return dchan;
+}
+EXPORT_SYMBOL_GPL(rio_request_dma);
+
+/**
+ * rio_release_dma - release specified DMA channel
+ * @dchan: DMA channel to release
+ */
+void rio_release_dma(struct dma_chan *dchan)
+{
+   dma_release_channel(dchan);
+}
+EXPORT_SYMBOL_GPL(rio_release_dma);
+
+/**
+ * rio_dma_prep_slave_sg - RapidIO specific wrapper
+ *   for device_prep_slave_sg callback defined by DMAENGINE.
+ * @rdev: RIO device control structure
+ * @dchan: DMA channel to configure
+ * @data: RIO specific data descriptor
+ * @direction: DMA data transfer direction (TO or FROM the device)
+ * @flags: dmaengine defined flags
+ *
+ * Initializes RapidIO capable DMA channel for the specified data transfer.
+ * Uses DMA channel private extension to pass information related to remote
+ * target RIO device.
+ * Returns pointer to DMA transaction descriptor or NULL if failed.
+ */
+struct dma_async_tx_descriptor *rio_dma_prep_slave_sg(struct rio_dev *rdev,
+   struct dma_chan *dchan, struct rio_dma_data *data,
+   enum dma_data_direction direction, unsigned long flags)
+{
+   struct dma_async_tx_descriptor *txd = NULL;
+   struct rio_dma_ext rio_ext;
+
+   rio_ext.destid = rdev->destid;
+   rio_ext.rio_addr_u = data->rio_addr_u;
+   rio_ext.rio_addr = data->rio_addr;
+   rio_ext.wr_type = data->wr_type;
+   dchan->private = &rio_ext;
+
+   txd = dchan->device->device_prep_slave_sg(dchan, data->sg, data->sg_len,
+ direction, flags);
+
+   return txd;
+}
+EXPORT_SYMBOL_GPL(rio_dma_prep_slave_sg);
+
+#endif /* CONFIG_RAPIDIO_DMA_ENGINE */
+
 static void rio_fixup_device(struct rio_dev *dev)
 {
 }
diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
index 8fbf40e..867b685 100644
--- a/include/linux/dmaengine.h
+++ b/include/linux/dmaengine.h
@@ -70,6 +70,7 @@ enum dma

[PATCH] RapidIO: documentation update

2011-09-15 Thread Alexandre Bounine
Update rapidio.txt to reflect changes from recent patch.
See http://marc.info/?l=linux-kernel&m=131285620113589&w=2 for details.

Signed-off-by: Alexandre Bounine 
Cc: Liu Gang 
---
 Documentation/rapidio/rapidio.txt |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/Documentation/rapidio/rapidio.txt 
b/Documentation/rapidio/rapidio.txt
index be70ee1..c75694b 100644
--- a/Documentation/rapidio/rapidio.txt
+++ b/Documentation/rapidio/rapidio.txt
@@ -144,7 +144,7 @@ and the default device ID in order to access the device on 
the active port.
 
 After the host has completed enumeration of the entire network it releases
 devices by clearing device ID locks (calls rio_clear_locks()). For each 
endpoint
-in the system, it sets the Master Enable bit in the Port General Control CSR
+in the system, it sets the Discovered bit in the Port General Control CSR
 to indicate that enumeration is completed and agents are allowed to execute
 passive discovery of the network.
 
-- 
1.7.6

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH] RapidIO, rionet: Fix ethernet address macros for LE platforms

2011-09-06 Thread Alexandre Bounine
Modify Ethernet addess macros to be compatible with BE/LE platforms
(applicable to kernel versions starting from 2.6.39).

Signed-off-by: Alexandre Bounine 
Cc: Chul Kim 
Cc: Kumar Gala 
Cc: Matt Porter 
Cc: Li Yang 
---
 drivers/net/rionet.c |4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/rionet.c b/drivers/net/rionet.c
index 3bb1311..7145714 100644
--- a/drivers/net/rionet.c
+++ b/drivers/net/rionet.c
@@ -88,8 +88,8 @@ static struct rio_dev **rionet_active;
 #define dev_rionet_capable(dev) \
is_rionet_capable(dev->src_ops, dev->dst_ops)
 
-#define RIONET_MAC_MATCH(x)(*(u32 *)x == 0x00010001)
-#define RIONET_GET_DESTID(x)   (*(u16 *)(x + 4))
+#define RIONET_MAC_MATCH(x)(!memcmp((x), "\00\01\00\01", 4))
+#define RIONET_GET_DESTID(x)   ((*((u8 *)x + 4) << 8) | *((u8 *)x + 5))
 
 static int rionet_rx_clean(struct net_device *ndev)
 {
-- 
1.7.6

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH] RapidIO: fix potential null deref in rio_setup_device()

2011-09-06 Thread Alexandre Bounine
The "goto cleanup" path can deference "rswitch" when it is NULL.

Reported-by: Dan Carpenter 
Signed-off-by: Alexandre Bounine 
Cc: Dan Carpenter 
Cc: Kumar Gala 
Cc: Matt Porter 
Cc: Chul Kim 
---
 drivers/rapidio/rio-scan.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c
index ebe77dd..5b2cb53 100644
--- a/drivers/rapidio/rio-scan.c
+++ b/drivers/rapidio/rio-scan.c
@@ -516,7 +516,7 @@ static struct rio_dev __devinit *rio_setup_device(struct 
rio_net *net,
return rdev;
 
 cleanup:
-   if (rio_is_switch(rdev))
+   if (rswitch)
kfree(rswitch->route_table);
 
kfree(rdev);
-- 
1.7.6

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH -mm] RapidIO: Tsi721 driver - fixes for the initial release

2011-09-06 Thread Alexandre Bounine
- address comments made by Andrew Morton,
  see http://marc.info/?l=linux-kernel&m=131361256714116&w=2
- add spinlock for IB_MSG handler
- rename private BDMA channel structure to avoid conflict with DMA engine
- fix endianess bug in outbound message interrupt handler

Signed-off-by: Alexandre Bounine 
Cc: Chul Kim 
Cc: Kumar Gala 
Cc: Matt Porter 
Cc: Li Yang 
---
 drivers/rapidio/devices/Kconfig  |2 +-
 drivers/rapidio/devices/tsi721.c |  273 -
 drivers/rapidio/devices/tsi721.h |   20 ++-
 3 files changed, 161 insertions(+), 134 deletions(-)

diff --git a/drivers/rapidio/devices/Kconfig b/drivers/rapidio/devices/Kconfig
index df0b0c5..12a9d7f 100644
--- a/drivers/rapidio/devices/Kconfig
+++ b/drivers/rapidio/devices/Kconfig
@@ -4,7 +4,7 @@
 
 config RAPIDIO_TSI721
bool "IDT Tsi721 PCI Express SRIO Controller support"
-   depends on RAPIDIO && PCI && PCIEPORTBUS
+   depends on RAPIDIO && PCIEPORTBUS
default "n"
---help---
  Include support for IDT Tsi721 PCI Express Serial RapidIO controller.
diff --git a/drivers/rapidio/devices/tsi721.c b/drivers/rapidio/devices/tsi721.c
index dafedc8..5225930 100644
--- a/drivers/rapidio/devices/tsi721.c
+++ b/drivers/rapidio/devices/tsi721.c
@@ -136,21 +136,20 @@ static int tsi721_maint_dma(struct tsi721_device *priv, 
u32 sys_size,
/* Start DMA operation */
iowrite32(rd_count + 2,
priv->regs + TSI721_DMAC_DWRCNT(TSI721_DMACH_MAINT));
-   (void)ioread32(priv->regs + TSI721_DMAC_DWRCNT(TSI721_DMACH_MAINT));
+   ioread32(priv->regs + TSI721_DMAC_DWRCNT(TSI721_DMACH_MAINT));
i = 0;
 
/* Wait until DMA transfer is finished */
while ((ch_stat = ioread32(priv->regs +
TSI721_DMAC_STS(TSI721_DMACH_MAINT))) & TSI721_DMAC_STS_RUN) {
-   udelay(10);
-   i++;
-   if (i >= 500) {
+   udelay(1);
+   if (++i >= 500) {
dev_dbg(&priv->pdev->dev,
"%s : DMA[%d] read timeout ch_status=%x\n",
__func__, TSI721_DMACH_MAINT, ch_stat);
if (!do_wr)
*data = 0x;
-   err = -EFAULT;
+   err = -EIO;
goto err_out;
}
}
@@ -173,7 +172,7 @@ static int tsi721_maint_dma(struct tsi721_device *priv, u32 
sys_size,
udelay(1);
if (!do_wr)
*data = 0x;
-   err = -EFAULT;
+   err = -EIO;
goto err_out;
}
 
@@ -288,18 +287,15 @@ static void tsi721_pw_dpc(struct work_struct *work)
 {
struct tsi721_device *priv = container_of(work, struct tsi721_device,
pw_work);
-   unsigned long flags;
u32 msg_buffer[RIO_PW_MSG_SIZE/sizeof(u32)]; /* Use full size PW message
buffer for RIO layer */
 
/*
 * Process port-write messages
 */
-   spin_lock_irqsave(&priv->pw_fifo_lock, flags);
-   while (kfifo_out(&priv->pw_fifo, (unsigned char *)msg_buffer,
-TSI721_RIO_PW_MSG_SIZE)) {
+   while (kfifo_out_spinlocked(&priv->pw_fifo, (unsigned char *)msg_buffer,
+TSI721_RIO_PW_MSG_SIZE, &priv->pw_fifo_lock)) {
/* Process one message */
-   spin_unlock_irqrestore(&priv->pw_fifo_lock, flags);
 #ifdef DEBUG_PW
{
u32 i;
@@ -315,9 +311,7 @@ static void tsi721_pw_dpc(struct work_struct *work)
 #endif
/* Pass the port-write message to RIO core for processing */
rio_inb_pwrite_handler((union rio_pw_msg *)msg_buffer);
-   spin_lock_irqsave(&priv->pw_fifo_lock, flags);
}
-   spin_unlock_irqrestore(&priv->pw_fifo_lock, flags);
 }
 
 /**
@@ -457,87 +451,6 @@ static void tsi721_db_dpc(struct work_struct *work)
 }
 
 /**
- * tsi721_srio_msix - Tsi721 MSI-X SRIO MAC interrupt handler
- * @irq: Linux interrupt number
- * @ptr: Pointer to interrupt-specific data (mport structure)
- *
- * Handles Tsi721 interrupts from SRIO MAC.
- */
-static irqreturn_t tsi721_srio_msix(int irq, void *ptr)
-{
-   struct tsi721_device *priv = ((struct rio_mport *)ptr)->priv;
-   u32 srio_int;
-
-   /* Service SRIO MAC interrupts */
-   srio_int = ioread32(priv->regs + TSI721_RIO_EM_INT_STAT);
-   if (srio_int & TSI721_RIO_EM_INT_STAT_PW_RX)
-   tsi721_pw_handler((struct rio_mport *)ptr);
-
-   return IRQ_HANDLED;
-}
-
-/**
- * tsi721_sr2pc_ch_msix - Tsi721 MSI-X SR2PC Channel interrupt han

[PATCH] RapidIO: Fix use of non-compatible registers

2011-07-26 Thread Alexandre Bounine
Replace/remove use of RIO v.1.2 registers/bits that are not forward-compatible
with newer versions of RapidIO specification.

RapidIO specification v. 1.3 removed Write Port CSR, Doorbell CSR,
Mailbox CSR and Mailbox and Doorbell bits of the PEF CAR.

Signed-off-by: Alexandre Bounine 
Cc: Kumar Gala 
Cc: Matt Porter 
Cc: Li Yang 
Cc: Thomas Moll 
Cc: Chul Kim 
Cc: 
---
 drivers/net/rionet.c   |   23 ---
 drivers/rapidio/rio-scan.c |3 +--
 include/linux/rio_regs.h   |   18 +-
 3 files changed, 18 insertions(+), 26 deletions(-)

diff --git a/drivers/net/rionet.c b/drivers/net/rionet.c
index 86ac38c..3bb1311 100644
--- a/drivers/net/rionet.c
+++ b/drivers/net/rionet.c
@@ -80,13 +80,13 @@ static int rionet_capable = 1;
  */
 static struct rio_dev **rionet_active;
 
-#define is_rionet_capable(pef, src_ops, dst_ops)   \
-   ((pef & RIO_PEF_INB_MBOX) &&\
-(pef & RIO_PEF_INB_DOORBELL) &&\
+#define is_rionet_capable(src_ops, dst_ops)\
+   ((src_ops & RIO_SRC_OPS_DATA_MSG) &&\
+(dst_ops & RIO_DST_OPS_DATA_MSG) &&\
 (src_ops & RIO_SRC_OPS_DOORBELL) &&\
 (dst_ops & RIO_DST_OPS_DOORBELL))
 #define dev_rionet_capable(dev) \
-   is_rionet_capable(dev->pef, dev->src_ops, dev->dst_ops)
+   is_rionet_capable(dev->src_ops, dev->dst_ops)
 
 #define RIONET_MAC_MATCH(x)(*(u32 *)x == 0x00010001)
 #define RIONET_GET_DESTID(x)   (*(u16 *)(x + 4))
@@ -282,7 +282,6 @@ static int rionet_open(struct net_device *ndev)
 {
int i, rc = 0;
struct rionet_peer *peer, *tmp;
-   u32 pwdcsr;
struct rionet_private *rnet = netdev_priv(ndev);
 
if (netif_msg_ifup(rnet))
@@ -332,13 +331,8 @@ static int rionet_open(struct net_device *ndev)
continue;
}
 
-   /*
-* If device has initialized inbound doorbells,
-* send a join message
-*/
-   rio_read_config_32(peer->rdev, RIO_WRITE_PORT_CSR, &pwdcsr);
-   if (pwdcsr & RIO_DOORBELL_AVAIL)
-   rio_send_doorbell(peer->rdev, RIONET_DOORBELL_JOIN);
+   /* Send a join message */
+   rio_send_doorbell(peer->rdev, RIONET_DOORBELL_JOIN);
}
 
   out:
@@ -492,7 +486,7 @@ static int rionet_setup_netdev(struct rio_mport *mport, 
struct net_device *ndev)
 static int rionet_probe(struct rio_dev *rdev, const struct rio_device_id *id)
 {
int rc = -ENODEV;
-   u32 lpef, lsrc_ops, ldst_ops;
+   u32 lsrc_ops, ldst_ops;
struct rionet_peer *peer;
struct net_device *ndev = NULL;
 
@@ -515,12 +509,11 @@ static int rionet_probe(struct rio_dev *rdev, const 
struct rio_device_id *id)
 * on later probes
 */
if (!rionet_check) {
-   rio_local_read_config_32(rdev->net->hport, RIO_PEF_CAR, &lpef);
rio_local_read_config_32(rdev->net->hport, RIO_SRC_OPS_CAR,
 &lsrc_ops);
rio_local_read_config_32(rdev->net->hport, RIO_DST_OPS_CAR,
 &ldst_ops);
-   if (!is_rionet_capable(lpef, lsrc_ops, ldst_ops)) {
+   if (!is_rionet_capable(lsrc_ops, ldst_ops)) {
printk(KERN_ERR
   "%s: local device is not network capable\n",
   DRV_NAME);
diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c
index ee89358..ebe77dd 100644
--- a/drivers/rapidio/rio-scan.c
+++ b/drivers/rapidio/rio-scan.c
@@ -505,8 +505,7 @@ static struct rio_dev __devinit *rio_setup_device(struct 
rio_net *net,
rdev->dev.dma_mask = &rdev->dma_mask;
rdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
 
-   if ((rdev->pef & RIO_PEF_INB_DOORBELL) &&
-   (rdev->dst_ops & RIO_DST_OPS_DOORBELL))
+   if (rdev->dst_ops & RIO_DST_OPS_DOORBELL)
rio_init_dbell_res(&rdev->riores[RIO_DOORBELL_RESOURCE],
   0, 0x);
 
diff --git a/include/linux/rio_regs.h b/include/linux/rio_regs.h
index 9026b30..218168a 100644
--- a/include/linux/rio_regs.h
+++ b/include/linux/rio_regs.h
@@ -36,12 +36,12 @@
 #define  RIO_PEF_PROCESSOR 0x2000  /* [I] Processor */
 #define  RIO_PEF_SWITCH0x1000  /* [I] Switch */
 #define  RIO_PEF_MULTIPORT 0x0800  /* [VI, 2.1] Multiport 
*/
-#define  RIO_PEF_INB_MBOX  0x00f0  /* [II] Mailboxes */
-#define  RIO_PEF_INB_MBOX0 0x0080  /* [II] Mailbox 0

[PATCH] RapidIO: Fix default routing initialization

2011-05-11 Thread Alexandre Bounine
Fix switch initialization to ensure that all switches have default
routing disabled. This guarantees that no unexpected RapidIO packets
arrive to the default port set by reset and there is no default routing
destination until it is properly configured by software.

This update also unifies handling of unmapped destinations by tsi57x,
IDT Gen1 and IDT Gen2 switches.

Signed-off-by: Alexandre Bounine 
Cc: Kumar Gala 
Cc: Matt Porter 
Cc: Li Yang 
Cc: Thomas Moll 
---
 drivers/rapidio/switches/idt_gen2.c |9 +
 drivers/rapidio/switches/idtcps.c   |6 ++
 drivers/rapidio/switches/tsi57x.c   |6 ++
 3 files changed, 21 insertions(+), 0 deletions(-)

diff --git a/drivers/rapidio/switches/idt_gen2.c 
b/drivers/rapidio/switches/idt_gen2.c
index ac2701b..043ee31 100644
--- a/drivers/rapidio/switches/idt_gen2.c
+++ b/drivers/rapidio/switches/idt_gen2.c
@@ -95,6 +95,9 @@ idtg2_route_add_entry(struct rio_mport *mport, u16 destid, u8 
hopcount,
else
table++;
 
+   if (route_port == RIO_INVALID_ROUTE)
+   route_port = IDT_DEFAULT_ROUTE;
+
rio_mport_write_config_32(mport, destid, hopcount,
  LOCAL_RTE_CONF_DESTID_SEL, table);
 
@@ -411,6 +414,12 @@ static int idtg2_switch_init(struct rio_dev *rdev, int 
do_enum)
rdev->rswitch->em_handle = idtg2_em_handler;
rdev->rswitch->sw_sysfs = idtg2_sysfs;
 
+   if (do_enum) {
+   /* Ensure that default routing is disabled on startup */
+   rio_write_config_32(rdev,
+   RIO_STD_RTE_DEFAULT_PORT, IDT_NO_ROUTE);
+   }
+
return 0;
 }
 
diff --git a/drivers/rapidio/switches/idtcps.c 
b/drivers/rapidio/switches/idtcps.c
index 3a97107..d06ee2d 100644
--- a/drivers/rapidio/switches/idtcps.c
+++ b/drivers/rapidio/switches/idtcps.c
@@ -26,6 +26,9 @@ idtcps_route_add_entry(struct rio_mport *mport, u16 destid, 
u8 hopcount,
 {
u32 result;
 
+   if (route_port == RIO_INVALID_ROUTE)
+   route_port = CPS_DEFAULT_ROUTE;
+
if (table == RIO_GLOBAL_TABLE) {
rio_mport_write_config_32(mport, destid, hopcount,
RIO_STD_RTE_CONF_DESTID_SEL_CSR, route_destid);
@@ -130,6 +133,9 @@ static int idtcps_switch_init(struct rio_dev *rdev, int 
do_enum)
/* set TVAL = ~50us */
rio_write_config_32(rdev,
rdev->phys_efptr + RIO_PORT_LINKTO_CTL_CSR, 0x8e << 8);
+   /* Ensure that default routing is disabled on startup */
+   rio_write_config_32(rdev,
+   RIO_STD_RTE_DEFAULT_PORT, CPS_NO_ROUTE);
}
 
return 0;
diff --git a/drivers/rapidio/switches/tsi57x.c 
b/drivers/rapidio/switches/tsi57x.c
index d322fa0..10e7ddc 100644
--- a/drivers/rapidio/switches/tsi57x.c
+++ b/drivers/rapidio/switches/tsi57x.c
@@ -303,6 +303,12 @@ static int tsi57x_switch_init(struct rio_dev *rdev, int 
do_enum)
rdev->rswitch->em_init = tsi57x_em_init;
rdev->rswitch->em_handle = tsi57x_em_handler;
 
+   if (do_enum) {
+   /* Ensure that default routing is disabled on startup */
+   rio_write_config_32(rdev, RIO_STD_RTE_DEFAULT_PORT,
+   RIO_INVALID_ROUTE);
+   }
+
return 0;
 }
 
-- 
1.7.3.1

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH] RapidIO/mpc85xx: Fix possible mport registration problems.

2011-04-06 Thread Alexandre Bounine
Fix possible problem with mport registration left non cleared after
fsl_rio_setup() exits on link error. Abort mport initialization
if registration failed.

This patch is applicable to 2.6.39-rc1 only. The problem does not exists
for earlier versions.

Signed-off-by: Alexandre Bounine 
Cc: Kumar Gala 
Cc: Matt Porter 
Cc: Li Yang 
Cc: Thomas Moll 
---
 arch/powerpc/sysdev/fsl_rio.c |4 +++-
 drivers/rapidio/rio.c |5 +++--
 include/linux/rio.h   |2 +-
 3 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c
index 14232d5..4979853 100644
--- a/arch/powerpc/sysdev/fsl_rio.c
+++ b/arch/powerpc/sysdev/fsl_rio.c
@@ -1457,7 +1457,6 @@ int fsl_rio_setup(struct platform_device *dev)
port->ops = ops;
port->priv = priv;
port->phys_efptr = 0x100;
-   rio_register_mport(port);
 
priv->regs_win = ioremap(regs.start, regs.end - regs.start + 1);
rio_regs_win = priv->regs_win;
@@ -1504,6 +1503,9 @@ int fsl_rio_setup(struct platform_device *dev)
dev_info(&dev->dev, "RapidIO Common Transport System size: %d\n",
port->sys_size ? 65536 : 256);
 
+   if (rio_register_mport(port))
+   goto err;
+
if (port->host_deviceid >= 0)
out_be32(priv->regs_win + RIO_GCCSR, RIO_PORT_GEN_HOST |
RIO_PORT_GEN_MASTER | RIO_PORT_GEN_DISCOVERED);
diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c
index c29719c..86c9a09 100644
--- a/drivers/rapidio/rio.c
+++ b/drivers/rapidio/rio.c
@@ -1171,16 +1171,17 @@ static int rio_hdid_setup(char *str)
 
 __setup("riohdid=", rio_hdid_setup);
 
-void rio_register_mport(struct rio_mport *port)
+int rio_register_mport(struct rio_mport *port)
 {
if (next_portid >= RIO_MAX_MPORTS) {
pr_err("RIO: reached specified max number of mports\n");
-   return;
+   return 1;
}
 
port->id = next_portid++;
port->host_deviceid = rio_get_hdid(port->id);
list_add_tail(&port->node, &rio_mports);
+   return 0;
 }
 
 EXPORT_SYMBOL_GPL(rio_local_get_device_id);
diff --git a/include/linux/rio.h b/include/linux/rio.h
index 4e37a7c..4d50611 100644
--- a/include/linux/rio.h
+++ b/include/linux/rio.h
@@ -396,7 +396,7 @@ union rio_pw_msg {
 };
 
 /* Architecture and hardware-specific functions */
-extern void rio_register_mport(struct rio_mport *);
+extern int rio_register_mport(struct rio_mport *);
 extern int rio_open_inb_mbox(struct rio_mport *, void *, int, int);
 extern void rio_close_inb_mbox(struct rio_mport *, int);
 extern int rio_open_outb_mbox(struct rio_mport *, void *, int, int);
-- 
1.7.3.1

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH 1/1] RapidIO: Add IDT CPS-1432 switch definitions

2011-04-06 Thread Alexandre Bounine

Signed-off-by: Alexandre Bounine 
Cc: Matt Porter 
Cc: Kumar Gala 
---
 drivers/rapidio/switches/idt_gen2.c |1 +
 include/linux/rio_ids.h |1 +
 2 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/drivers/rapidio/switches/idt_gen2.c 
b/drivers/rapidio/switches/idt_gen2.c
index 095016a..ac2701b 100644
--- a/drivers/rapidio/switches/idt_gen2.c
+++ b/drivers/rapidio/switches/idt_gen2.c
@@ -418,3 +418,4 @@ 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);
diff --git a/include/linux/rio_ids.h b/include/linux/rio_ids.h
index 7410d33..0cee015 100644
--- a/include/linux/rio_ids.h
+++ b/include/linux/rio_ids.h
@@ -35,6 +35,7 @@
 #define RIO_DID_IDTCPS6Q   0x035f
 #define RIO_DID_IDTCPS10Q  0x035e
 #define RIO_DID_IDTCPS1848 0x0374
+#define RIO_DID_IDTCPS1432 0x0375
 #define RIO_DID_IDTCPS1616 0x0379
 #define RIO_DID_IDTVPS1616 0x0377
 #define RIO_DID_IDTSPS1616 0x0378
-- 
1.7.3.1

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH -mm] RapidIO,powerpc/85xx: Fix configuration option

2011-03-18 Thread Alexandre Bounine
Follows set of patches in -mm tree. Replaces configuration option
missed in previous patches.

Signed-off-by: Alexandre Bounine 
---
 arch/powerpc/kernel/cpu_setup_fsl_booke.S |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/arch/powerpc/kernel/cpu_setup_fsl_booke.S 
b/arch/powerpc/kernel/cpu_setup_fsl_booke.S
index 5c518ad..9136111 100644
--- a/arch/powerpc/kernel/cpu_setup_fsl_booke.S
+++ b/arch/powerpc/kernel/cpu_setup_fsl_booke.S
@@ -64,7 +64,7 @@ _GLOBAL(__setup_cpu_e500v2)
bl  __e500_icache_setup
bl  __e500_dcache_setup
bl  __setup_e500_ivors
-#ifdef CONFIG_RAPIDIO
+#ifdef CONFIG_FSL_RIO
/* Ensure that RFXE is set */
mfspr   r3,SPRN_HID1
orisr3,r3,HID1_RFXE@h
-- 
1.7.3.1

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH] RapidIO: Update MAINTAINERS

2011-03-03 Thread Alexandre Bounine

Signed-off-by: Alexandre Bounine 
Cc: Matt Porter 
---
 MAINTAINERS |1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 6f99e12..f9630d6 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -5164,6 +5164,7 @@ F:drivers/char/random.c
 
 RAPIDIO SUBSYSTEM
 M: Matt Porter 
+M: Alexandre Bounine 
 S: Maintained
 F: drivers/rapidio/
 
-- 
1.7.3.1

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH 2/5] RapidIO: Modify configuration to support PCI-SRIO controller

2011-02-28 Thread Alexandre Bounine
1. Add an option to include RapidIO support if the PCI is available.
2. Add FSL_RIO configuration option to enable controller selection.
3. Add RapidIO support option into x86 and MIPS architectures.

Signed-off-by: Alexandre Bounine 
---
 arch/mips/Kconfig|   10 ++
 arch/powerpc/Kconfig |   10 +-
 arch/powerpc/sysdev/Makefile |2 +-
 arch/x86/Kconfig |   10 ++
 drivers/net/rionet.c |4 ++--
 drivers/rapidio/rio-sysfs.c  |1 +
 6 files changed, 33 insertions(+), 4 deletions(-)

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index f5ecc05..c451163 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -2336,6 +2336,16 @@ source "drivers/pcmcia/Kconfig"
 
 source "drivers/pci/hotplug/Kconfig"
 
+config RAPIDIO
+   bool "RapidIO support"
+   depends on PCI
+   default n
+   help
+ If you say Y here, the kernel will include drivers and
+ infrastructure code to support RapidIO interconnect devices.
+
+source "drivers/rapidio/Kconfig"
+
 endmenu
 
 menu "Executable file formats"
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 7d69e9b..9a7628a 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -767,11 +767,19 @@ config HAS_RAPIDIO
 
 config RAPIDIO
bool "RapidIO support"
-   depends on HAS_RAPIDIO
+   depends on HAS_RAPIDIO || PCI
help
  If you say Y here, the kernel will include drivers and
  infrastructure code to support RapidIO interconnect devices.
 
+config FSL_RIO
+   bool "Freescale Embedded SRIO Controller support"
+   depends on RAPIDIO && HAS_RAPIDIO
+   default "n"
+   ---help---
+ Include support for RapidIO controller on Freescale embedded
+ processors (MPC8548, MPC8641, etc).
+
 source "drivers/rapidio/Kconfig"
 
 endmenu
diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile
index 9c29734..1e0c933 100644
--- a/arch/powerpc/sysdev/Makefile
+++ b/arch/powerpc/sysdev/Makefile
@@ -20,7 +20,7 @@ obj-$(CONFIG_FSL_GTM) += fsl_gtm.o
 obj-$(CONFIG_MPC8xxx_GPIO) += mpc8xxx_gpio.o
 obj-$(CONFIG_FSL_85XX_CACHE_SRAM)  += fsl_85xx_l2ctlr.o 
fsl_85xx_cache_sram.o
 obj-$(CONFIG_SIMPLE_GPIO)  += simple_gpio.o
-obj-$(CONFIG_RAPIDIO)  += fsl_rio.o
+obj-$(CONFIG_FSL_RIO)  += fsl_rio.o
 obj-$(CONFIG_TSI108_BRIDGE)+= tsi108_pci.o tsi108_dev.o
 obj-$(CONFIG_QUICC_ENGINE) += qe_lib/
 obj-$(CONFIG_PPC_BESTCOMM) += bestcomm/
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index d5ed94d..11c1dc5 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -2104,6 +2104,16 @@ source "drivers/pcmcia/Kconfig"
 
 source "drivers/pci/hotplug/Kconfig"
 
+config RAPIDIO
+   bool "RapidIO support"
+   depends on PCI
+   default n
+   help
+ If you say Y here, the kernel will include drivers and
+ infrastructure code to support RapidIO interconnect devices.
+
+source "drivers/rapidio/Kconfig"
+
 endmenu
 
 
diff --git a/drivers/net/rionet.c b/drivers/net/rionet.c
index 44150f2..678e577 100644
--- a/drivers/net/rionet.c
+++ b/drivers/net/rionet.c
@@ -382,7 +382,7 @@ static void rionet_remove(struct rio_dev *rdev)
struct rionet_peer *peer, *tmp;
 
free_pages((unsigned long)rionet_active, rdev->net->hport->sys_size ?
-   __ilog2(sizeof(void *)) + 4 : 0);
+   __fls(sizeof(void *)) + 4 : 0);
unregister_netdev(ndev);
free_netdev(ndev);
 
@@ -450,7 +450,7 @@ static int rionet_setup_netdev(struct rio_mport *mport)
}
 
rionet_active = (struct rio_dev **)__get_free_pages(GFP_KERNEL,
-   mport->sys_size ? __ilog2(sizeof(void *)) + 4 : 0);
+   mport->sys_size ? __fls(sizeof(void *)) + 4 : 0);
if (!rionet_active) {
rc = -ENOMEM;
goto out;
diff --git a/drivers/rapidio/rio-sysfs.c b/drivers/rapidio/rio-sysfs.c
index 76b4185..e3ebfec 100644
--- a/drivers/rapidio/rio-sysfs.c
+++ b/drivers/rapidio/rio-sysfs.c
@@ -14,6 +14,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "rio.h"
 
-- 
1.7.3.1

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH 5/5] RapidIO: remove mport resource reservation from common RIO code

2011-02-28 Thread Alexandre Bounine
Removes resource reservation from the common sybsystem initialization code
and make it part of mport driver initialization. This resolves conflict
with resource reservation by device specific mport drivers.

Signed-off-by: Alexandre Bounine 
---
 arch/powerpc/sysdev/fsl_rio.c |9 +
 drivers/rapidio/rio.c |   14 +-
 2 files changed, 10 insertions(+), 13 deletions(-)

diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c
index 7d35a12..f25ad15 100644
--- a/arch/powerpc/sysdev/fsl_rio.c
+++ b/arch/powerpc/sysdev/fsl_rio.c
@@ -1432,6 +1432,14 @@ int fsl_rio_setup(struct platform_device *dev)
port->iores.flags = IORESOURCE_MEM;
port->iores.name = "rio_io_win";
 
+   if (request_resource(&iomem_resource, &port->iores) < 0) {
+   dev_err(&dev->dev, "RIO: Error requesting master port region"
+   " 0x%016llx-0x%016llx\n",
+   (u64)port->iores.start, (u64)port->iores.end);
+   rc = -ENOMEM;
+   goto err_res;
+   }
+
priv->pwirq   = irq_of_parse_and_map(dev->dev.of_node, 0);
priv->bellirq = irq_of_parse_and_map(dev->dev.of_node, 2);
priv->txirq = irq_of_parse_and_map(dev->dev.of_node, 3);
@@ -1536,6 +1544,7 @@ int fsl_rio_setup(struct platform_device *dev)
return 0;
 err:
iounmap(priv->regs_win);
+err_res:
kfree(priv);
 err_priv:
kfree(port);
diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c
index 9a7b216..c29719c 100644
--- a/drivers/rapidio/rio.c
+++ b/drivers/rapidio/rio.c
@@ -1137,20 +1137,9 @@ static int __devinit rio_init(void)
 
 int __devinit rio_init_mports(void)
 {
-   int rc = 0;
struct rio_mport *port;
 
list_for_each_entry(port, &rio_mports, node) {
-   if (!request_mem_region(port->iores.start,
-   resource_size(&port->iores),
-   port->name)) {
-   printk(KERN_ERR
-  "RIO: Error requesting master port region 
0x%016llx-0x%016llx\n",
-  (u64)port->iores.start, (u64)port->iores.end);
-   rc = -ENOMEM;
-   goto out;
-   }
-
if (port->host_deviceid >= 0)
rio_enum_mport(port);
else
@@ -1159,8 +1148,7 @@ int __devinit rio_init_mports(void)
 
rio_init();
 
-  out:
-   return rc;
+   return 0;
 }
 
 device_initcall_sync(rio_init_mports);
-- 
1.7.3.1

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH 4/5] RapidIO: Modify mport ID assignment

2011-02-28 Thread Alexandre Bounine
Changes mport ID and host destination ID assignment to implement unified
method common to all mport drivers. Makes "riohdid=" kernel command line
parameter common for all architectures with support for more that one
host destination ID assignment.

Signed-off-by: Alexandre Bounine 
---
 arch/powerpc/sysdev/fsl_rio.c |   25 -
 drivers/rapidio/rio.c |   26 ++
 include/linux/rio.h   |1 +
 3 files changed, 27 insertions(+), 25 deletions(-)

diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c
index 6995907..7d35a12 100644
--- a/arch/powerpc/sysdev/fsl_rio.c
+++ b/arch/powerpc/sysdev/fsl_rio.c
@@ -1288,28 +1288,6 @@ err_out:
return rc;
 }
 
-static char *cmdline = NULL;
-
-static int fsl_rio_get_hdid(int index)
-{
-   /* XXX Need to parse multiple entries in some format */
-   if (!cmdline)
-   return -1;
-
-   return simple_strtol(cmdline, NULL, 0);
-}
-
-static int fsl_rio_get_cmdline(char *s)
-{
-   if (!s)
-   return 0;
-
-   cmdline = s;
-   return 1;
-}
-
-__setup("riohdid=", fsl_rio_get_cmdline);
-
 static inline void fsl_rio_info(struct device *dev, u32 ccsr)
 {
const char *str;
@@ -1439,7 +1417,6 @@ int fsl_rio_setup(struct platform_device *dev)
rc = -ENOMEM;
goto err_port;
}
-   port->id = 0;
port->index = 0;
 
priv = kzalloc(sizeof(struct rio_priv), GFP_KERNEL);
@@ -1470,8 +1447,6 @@ int fsl_rio_setup(struct platform_device *dev)
priv->dev = &dev->dev;
 
port->ops = ops;
-   port->host_deviceid = fsl_rio_get_hdid(port->id);
-
port->priv = priv;
port->phys_efptr = 0x100;
rio_register_mport(port);
diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c
index f861b72..9a7b216 100644
--- a/drivers/rapidio/rio.c
+++ b/drivers/rapidio/rio.c
@@ -32,6 +32,7 @@
 #include "rio.h"
 
 static LIST_HEAD(rio_mports);
+static unsigned char next_portid;
 
 /**
  * rio_local_get_device_id - Get the base/extended device id for a port
@@ -1164,8 +1165,33 @@ int __devinit rio_init_mports(void)
 
 device_initcall_sync(rio_init_mports);
 
+static int hdids[RIO_MAX_MPORTS + 1];
+
+static int rio_get_hdid(int index)
+{
+   if (!hdids[0] || hdids[0] <= index || index >= RIO_MAX_MPORTS)
+   return -1;
+
+   return hdids[index + 1];
+}
+
+static int rio_hdid_setup(char *str)
+{
+   (void)get_options(str, ARRAY_SIZE(hdids), hdids);
+   return 1;
+}
+
+__setup("riohdid=", rio_hdid_setup);
+
 void rio_register_mport(struct rio_mport *port)
 {
+   if (next_portid >= RIO_MAX_MPORTS) {
+   pr_err("RIO: reached specified max number of mports\n");
+   return;
+   }
+
+   port->id = next_portid++;
+   port->host_deviceid = rio_get_hdid(port->id);
list_add_tail(&port->node, &rio_mports);
 }
 
diff --git a/include/linux/rio.h b/include/linux/rio.h
index b6bcb16..4e37a7c 100644
--- a/include/linux/rio.h
+++ b/include/linux/rio.h
@@ -24,6 +24,7 @@
 #define RIO_NO_HOPCOUNT-1
 #define RIO_INVALID_DESTID 0x
 
+#define RIO_MAX_MPORTS 8
 #define RIO_MAX_MPORT_RESOURCES16
 #define RIO_MAX_DEV_RESOURCES  16
 
-- 
1.7.3.1

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH 3/5] RapidIO: Modify subsystem and driver initialization sequence

2011-02-28 Thread Alexandre Bounine
Subsystem initialization sequence modified to support presence of multiple
RapidIO controllers in the system. The new sequence is compatible with
initialization of PCI devices.

Signed-off-by: Alexandre Bounine 
---
 arch/powerpc/sysdev/fsl_rio.c |   10 +-
 drivers/net/rionet.c  |2 +-
 drivers/rapidio/rio.c |6 --
 include/linux/rio.h   |1 -
 4 files changed, 6 insertions(+), 13 deletions(-)

diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c
index 4c28226..6995907 100644
--- a/arch/powerpc/sysdev/fsl_rio.c
+++ b/arch/powerpc/sysdev/fsl_rio.c
@@ -1575,18 +1575,10 @@ err_ops:
 static int __devinit fsl_of_rio_rpn_probe(struct platform_device *dev,
 const struct of_device_id *match)
 {
-   int rc;
printk(KERN_INFO "Setting up RapidIO peer-to-peer network %s\n",
dev->dev.of_node->full_name);
 
-   rc = fsl_rio_setup(dev);
-   if (rc)
-   goto out;
-
-   /* Enumerate all registered ports */
-   rc = rio_init_mports();
-out:
-   return rc;
+   return fsl_rio_setup(dev);
 };
 
 static const struct of_device_id fsl_of_rio_rpn_ids[] = {
diff --git a/drivers/net/rionet.c b/drivers/net/rionet.c
index 678e577..26afbaa 100644
--- a/drivers/net/rionet.c
+++ b/drivers/net/rionet.c
@@ -571,5 +571,5 @@ static void __exit rionet_exit(void)
rio_unregister_driver(&rionet_driver);
 }
 
-module_init(rionet_init);
+late_initcall(rionet_init);
 module_exit(rionet_exit);
diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c
index d520dba..f861b72 100644
--- a/drivers/rapidio/rio.c
+++ b/drivers/rapidio/rio.c
@@ -1134,8 +1134,6 @@ static int __devinit rio_init(void)
return 0;
 }
 
-device_initcall(rio_init);
-
 int __devinit rio_init_mports(void)
 {
int rc = 0;
@@ -1158,10 +1156,14 @@ int __devinit rio_init_mports(void)
rio_disc_mport(port);
}
 
+   rio_init();
+
   out:
return rc;
 }
 
+device_initcall_sync(rio_init_mports);
+
 void rio_register_mport(struct rio_mport *port)
 {
list_add_tail(&port->node, &rio_mports);
diff --git a/include/linux/rio.h b/include/linux/rio.h
index efed116..b6bcb16 100644
--- a/include/linux/rio.h
+++ b/include/linux/rio.h
@@ -395,7 +395,6 @@ union rio_pw_msg {
 };
 
 /* Architecture and hardware-specific functions */
-extern int rio_init_mports(void);
 extern void rio_register_mport(struct rio_mport *);
 extern int rio_open_inb_mbox(struct rio_mport *, void *, int, int);
 extern void rio_close_inb_mbox(struct rio_mport *, int);
-- 
1.7.3.1

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH 1/5] RapidIO: Add architecture specific callbacks

2011-02-28 Thread Alexandre Bounine
Extend number of mport callback functions to eliminate direct linking of
architecture specific mport operations.

Signed-off-by: Alexandre Bounine 
---
 arch/powerpc/sysdev/fsl_rio.c |   52 +---
 drivers/rapidio/rio.c |   38 -
 include/linux/rio.h   |   23 ++
 include/linux/rio_drv.h   |7 +++--
 4 files changed, 75 insertions(+), 45 deletions(-)

diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c
index 8c6cab0..4c28226 100644
--- a/arch/powerpc/sysdev/fsl_rio.c
+++ b/arch/powerpc/sysdev/fsl_rio.c
@@ -482,7 +482,7 @@ fsl_rio_config_write(struct rio_mport *mport, int index, 
u16 destid,
 }
 
 /**
- * rio_hw_add_outb_message - Add message to the MPC85xx outbound message queue
+ * fsl_add_outb_message - Add message to the MPC85xx outbound message queue
  * @mport: Master port with outbound message queue
  * @rdev: Target of outbound message
  * @mbox: Outbound mailbox
@@ -492,8 +492,8 @@ fsl_rio_config_write(struct rio_mport *mport, int index, 
u16 destid,
  * Adds the @buffer message to the MPC85xx outbound message queue. Returns
  * %0 on success or %-EINVAL on failure.
  */
-int
-rio_hw_add_outb_message(struct rio_mport *mport, struct rio_dev *rdev, int 
mbox,
+static int
+fsl_add_outb_message(struct rio_mport *mport, struct rio_dev *rdev, int mbox,
void *buffer, size_t len)
 {
struct rio_priv *priv = mport->priv;
@@ -502,9 +502,8 @@ rio_hw_add_outb_message(struct rio_mport *mport, struct 
rio_dev *rdev, int mbox,
+ priv->msg_tx_ring.tx_slot;
int ret = 0;
 
-   pr_debug
-   ("RIO: rio_hw_add_outb_message(): destid %4.4x mbox %d buffer %8.8x 
len %8.8x\n",
-rdev->destid, mbox, (int)buffer, len);
+   pr_debug("RIO: fsl_add_outb_message(): destid %4.4x mbox %d buffer " \
+"%8.8x len %8.8x\n", rdev->destid, mbox, (int)buffer, len);
 
if ((len < 8) || (len > RIO_MAX_MSG_SIZE)) {
ret = -EINVAL;
@@ -554,8 +553,6 @@ rio_hw_add_outb_message(struct rio_mport *mport, struct 
rio_dev *rdev, int mbox,
return ret;
 }
 
-EXPORT_SYMBOL_GPL(rio_hw_add_outb_message);
-
 /**
  * fsl_rio_tx_handler - MPC85xx outbound message interrupt handler
  * @irq: Linux interrupt number
@@ -600,7 +597,7 @@ fsl_rio_tx_handler(int irq, void *dev_instance)
 }
 
 /**
- * rio_open_outb_mbox - Initialize MPC85xx outbound mailbox
+ * fsl_open_outb_mbox - Initialize MPC85xx outbound mailbox
  * @mport: Master port implementing the outbound message unit
  * @dev_id: Device specific pointer to pass on event
  * @mbox: Mailbox to open
@@ -610,7 +607,8 @@ fsl_rio_tx_handler(int irq, void *dev_instance)
  * and enables the outbound message unit. Returns %0 on success and
  * %-EINVAL or %-ENOMEM on failure.
  */
-int rio_open_outb_mbox(struct rio_mport *mport, void *dev_id, int mbox, int 
entries)
+static int
+fsl_open_outb_mbox(struct rio_mport *mport, void *dev_id, int mbox, int 
entries)
 {
int i, j, rc = 0;
struct rio_priv *priv = mport->priv;
@@ -706,14 +704,14 @@ int rio_open_outb_mbox(struct rio_mport *mport, void 
*dev_id, int mbox, int entr
 }
 
 /**
- * rio_close_outb_mbox - Shut down MPC85xx outbound mailbox
+ * fsl_close_outb_mbox - Shut down MPC85xx outbound mailbox
  * @mport: Master port implementing the outbound message unit
  * @mbox: Mailbox to close
  *
  * Disables the outbound message unit, free all buffers, and
  * frees the outbound message interrupt.
  */
-void rio_close_outb_mbox(struct rio_mport *mport, int mbox)
+static void fsl_close_outb_mbox(struct rio_mport *mport, int mbox)
 {
struct rio_priv *priv = mport->priv;
/* Disable inbound message unit */
@@ -770,7 +768,7 @@ fsl_rio_rx_handler(int irq, void *dev_instance)
 }
 
 /**
- * rio_open_inb_mbox - Initialize MPC85xx inbound mailbox
+ * fsl_open_inb_mbox - Initialize MPC85xx inbound mailbox
  * @mport: Master port implementing the inbound message unit
  * @dev_id: Device specific pointer to pass on event
  * @mbox: Mailbox to open
@@ -780,7 +778,8 @@ fsl_rio_rx_handler(int irq, void *dev_instance)
  * and enables the inbound message unit. Returns %0 on success
  * and %-EINVAL or %-ENOMEM on failure.
  */
-int rio_open_inb_mbox(struct rio_mport *mport, void *dev_id, int mbox, int 
entries)
+static int
+fsl_open_inb_mbox(struct rio_mport *mport, void *dev_id, int mbox, int entries)
 {
int i, rc = 0;
struct rio_priv *priv = mport->priv;
@@ -844,14 +843,14 @@ int rio_open_inb_mbox(struct rio_mport *mport, void 
*dev_id, int mbox, int entri
 }
 
 /**
- * rio_close_inb_mbox - Shut down MPC85xx inbound mailbox
+ * fsl_close_inb_mbox - Shut down MPC85xx inbound mailbox
  * @mport: Master port implementing the inbound message unit
  * @mbox: Mailbox to close
  *
  * Disables the inbound message 

[PATCH 0/5] RapidIO: configuration and initialization changes

2011-02-28 Thread Alexandre Bounine

This set of patches eliminates RapidIO dependency on PowerPC architecture and
makes it available to other architectures (x86 and MIPS).
It also enables support of new platform independent RapidIO controllers such
as PCI-to-SRIO and PCI Express-to-SRIO.

Alexandre Bounine (5):
  RapidIO: Add architecture specific callbacks
  RapidIO: Modify configuration to support PCI-SRIO controller
  RapidIO: Modify subsystem and driver initialization sequence
  RapidIO: Modify mport ID assignment
  RapidIO: remove mport resource reservation from common RIO code

 arch/mips/Kconfig |   10 
 arch/powerpc/Kconfig  |   10 -
 arch/powerpc/sysdev/Makefile  |2 +-
 arch/powerpc/sysdev/fsl_rio.c |   96 -
 arch/x86/Kconfig  |   10 
 drivers/net/rionet.c  |6 +-
 drivers/rapidio/rio-sysfs.c   |1 +
 drivers/rapidio/rio.c |   84 ---
 include/linux/rio.h   |   25 ---
 include/linux/rio_drv.h   |7 ++-
 10 files changed, 151 insertions(+), 100 deletions(-)

-- 
1.7.3.1

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH -mm V2] rapidio: Add new sysfs attributes

2011-02-25 Thread Alexandre Bounine
Add new sysfs attributes.

1. Routing information required to to reach the RIO device:
destid - device destination ID (real for for endpoint, route for switch)
hopcount - hopcount for maintenance requests (switches only)

2. device linking information:
lprev - name of device that precedes the given device in the enumeration
or discovery order (displayed along with of the port to which it
is attached).
lnext - names of devices (with corresponding port numbers) that are
attached to the given device as next in the enumeration or
discovery order (switches only)

Signed-off-by: Alexandre Bounine 
Cc: Kumar Gala 
Cc: Matt Porter 
Cc: Li Yang 
Cc: Thomas Moll 
Cc: Micha Nelissen 
---
 Documentation/rapidio/sysfs.txt |   17 +--
 drivers/rapidio/rio-sysfs.c |   41 ++-
 2 files changed, 54 insertions(+), 4 deletions(-)

diff --git a/Documentation/rapidio/sysfs.txt b/Documentation/rapidio/sysfs.txt
index d6d986e..97f71ce 100755
--- a/Documentation/rapidio/sysfs.txt
+++ b/Documentation/rapidio/sysfs.txt
@@ -36,6 +36,10 @@ device_rev - returns the device revision level
asm_did - returns identifier for the assembly containing the device
asm_rev - returns revision level of the assembly containing the device
asm_vid - returns vendor identifier of the assembly containing the device
+   destid  - returns device destination ID assigned by the enumeration routine
+ (see 4.1 for switch specific details)
+   lprev   - returns name of previous device (switch) on the path to the device
+ that that owns this attribute
 
 In addition to the files listed above, each device has a binary attribute file
 that allows read/write access to the device configuration registers using
@@ -66,9 +70,16 @@ set by the switch initialization routine during enumeration 
or discovery process
 
 4.1 Common Switch Attributes
 
- routes - reports switch routing information in "destID port" format. This
-  attribute reports only valid routing table entries, one line for
-  each entry.
+   routes - reports switch routing information in "destID port" format. This
+attribute reports only valid routing table entries, one line for
+each entry.
+   destid - device destination ID that defines a route to the switch
+ hopcount - number of hops on the path to the switch
+lnext - returns names of devices linked to the switch except one of a 
device
+linked to the ingress port (reported as "lprev"). This is an array
+names with number of lines equal to number of ports in switch. If
+a switch port has no attached device, returns "null" instead of
+a device name.
 
 4.2 Device-specific Switch Attributes
 
diff --git a/drivers/rapidio/rio-sysfs.c b/drivers/rapidio/rio-sysfs.c
index c04dbc7..4dbe360 100644
--- a/drivers/rapidio/rio-sysfs.c
+++ b/drivers/rapidio/rio-sysfs.c
@@ -34,6 +34,8 @@ rio_config_attr(device_rev, "0x%08x\n");
 rio_config_attr(asm_did, "0x%04x\n");
 rio_config_attr(asm_vid, "0x%04x\n");
 rio_config_attr(asm_rev, "0x%04x\n");
+rio_config_attr(destid, "0x%04x\n");
+rio_config_attr(hopcount, "0x%02x\n");
 
 static ssize_t routes_show(struct device *dev, struct device_attribute *attr, 
char *buf)
 {
@@ -53,6 +55,35 @@ static ssize_t routes_show(struct device *dev, struct 
device_attribute *attr, ch
return (str - buf);
 }
 
+static ssize_t lprev_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+   struct rio_dev *rdev = to_rio_dev(dev);
+
+   return sprintf(buf, "%s\n",
+   (rdev->prev) ? rio_name(rdev->prev) : "root");
+}
+
+static ssize_t lnext_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+   struct rio_dev *rdev = to_rio_dev(dev);
+   char *str = buf;
+   int i;
+
+   if (rdev->pef & RIO_PEF_SWITCH) {
+   for (i = 0; i < RIO_GET_TOTAL_PORTS(rdev->swpinfo); i++) {
+   if (rdev->rswitch->nextdev[i])
+   str += sprintf(str, "%s\n",
+   rio_name(rdev->rswitch->nextdev[i]));
+   else
+   str += sprintf(str, "null\n");
+   }
+   }
+
+   return str - buf;
+}
+
 struct device_attribute rio_dev_attrs[] = {
__ATTR_RO(did),
__ATTR_RO(vid),
@@ -60,10 +91,14 @@ struct device_attribute rio_dev_attrs[] = {
__ATTR_RO(asm_did),
__ATTR_RO(asm_vid),
__ATTR_RO(asm_rev),
+   __ATTR_RO(lprev),
+   __ATTR_RO(destid),
__ATTR_NULL,
 };
 
 static DEVICE_ATTR(routes, S_IRUGO, routes_show, NULL);
+static DEVICE_ATTR(lnext, S_IRUGO, lnext_sh

[PATCH] rapidio: Fix sysfs config attribute to access 16MB of maint space

2011-02-25 Thread Alexandre Bounine
Fixes sysfs config attribute to allow access to entire 16MB maintenance
space of RapidIO devices.

Signed-off-by: Alexandre Bounine 
Cc: Kumar Gala 
Cc: Matt Porter 
Cc: Li Yang 
Cc: Thomas Moll 
Cc: Micha Nelissen 
---
 drivers/rapidio/rio-sysfs.c |   12 ++--
 include/linux/rio_regs.h|4 +++-
 2 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/drivers/rapidio/rio-sysfs.c b/drivers/rapidio/rio-sysfs.c
index e3ebfec..c04dbc7 100644
--- a/drivers/rapidio/rio-sysfs.c
+++ b/drivers/rapidio/rio-sysfs.c
@@ -78,9 +78,9 @@ rio_read_config(struct file *filp, struct kobject *kobj,
 
/* Several chips lock up trying to read undefined config space */
if (capable(CAP_SYS_ADMIN))
-   size = 0x20;
+   size = RIO_MAINT_SPACE_SZ;
 
-   if (off > size)
+   if (off >= size)
return 0;
if (off + count > size) {
size -= off;
@@ -148,10 +148,10 @@ rio_write_config(struct file *filp, struct kobject *kobj,
loff_t init_off = off;
u8 *data = (u8 *) buf;
 
-   if (off > 0x20)
+   if (off >= RIO_MAINT_SPACE_SZ)
return 0;
-   if (off + count > 0x20) {
-   size = 0x20 - off;
+   if (off + count > RIO_MAINT_SPACE_SZ) {
+   size = RIO_MAINT_SPACE_SZ - off;
count = size;
}
 
@@ -201,7 +201,7 @@ static struct bin_attribute rio_config_attr = {
 .name = "config",
 .mode = S_IRUGO | S_IWUSR,
 },
-   .size = 0x20,
+   .size = RIO_MAINT_SPACE_SZ,
.read = rio_read_config,
.write = rio_write_config,
 };
diff --git a/include/linux/rio_regs.h b/include/linux/rio_regs.h
index d63dcba..9026b30 100644
--- a/include/linux/rio_regs.h
+++ b/include/linux/rio_regs.h
@@ -14,10 +14,12 @@
 #define LINUX_RIO_REGS_H
 
 /*
- * In RapidIO, each device has a 2MB configuration space that is
+ * In RapidIO, each device has a 16MB configuration space that is
  * accessed via maintenance transactions.  Portions of configuration
  * space are standardized and/or reserved.
  */
+#define RIO_MAINT_SPACE_SZ 0x100 /* 16MB of RapidIO mainenance space */
+
 #define RIO_DEV_ID_CAR 0x00/* [I] Device Identity CAR */
 #define RIO_DEV_INFO_CAR   0x04/* [I] Device Information CAR */
 #define RIO_ASM_ID_CAR 0x08/* [I] Assembly Identity CAR */
-- 
1.7.3.1

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH] RapidIO: Add new IDT sRIO switches

2010-12-10 Thread Alexandre Bounine
Add new sRIO switch device IDs and enable a basic support for them.

Signed-off-by: Alexandre Bounine 
Cc: Kumar Gala 
Cc: Matt Porter 
Cc: Li Yang 
Cc: Thomas Moll 
Cc: Micha Nelissen 
---
 drivers/rapidio/switches/idt_gen2.c |2 ++
 include/linux/rio_ids.h |2 ++
 2 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/drivers/rapidio/switches/idt_gen2.c 
b/drivers/rapidio/switches/idt_gen2.c
index dd4b2b7..095016a 100644
--- a/drivers/rapidio/switches/idt_gen2.c
+++ b/drivers/rapidio/switches/idt_gen2.c
@@ -416,3 +416,5 @@ static int idtg2_switch_init(struct rio_dev *rdev, int 
do_enum)
 
 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);
diff --git a/include/linux/rio_ids.h b/include/linux/rio_ids.h
index ee7b6ad..7410d33 100644
--- a/include/linux/rio_ids.h
+++ b/include/linux/rio_ids.h
@@ -36,5 +36,7 @@
 #define RIO_DID_IDTCPS10Q  0x035e
 #define RIO_DID_IDTCPS1848 0x0374
 #define RIO_DID_IDTCPS1616 0x0379
+#define RIO_DID_IDTVPS1616 0x0377
+#define RIO_DID_IDTSPS1616 0x0378
 
 #endif /* LINUX_RIO_IDS_H */
-- 
1.7.3.1

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH -mm 3/4] RapidIO: Use Component Tag for unified switch identification

2010-12-10 Thread Alexandre Bounine
Change the way how switchid value is set. Local counter variable does not
provide unified way to identify switch devices in a system with multiple
processors. Using local counter leads to the situation when the same RIO
switch has different switch ID for each processor. Replacing local counter
with unique portion of the Component Tag provides unified reference to the
switch by every processor in the system.

Signed-off-by: Alexandre Bounine 
Cc: Kumar Gala 
Cc: Matt Porter 
Cc: Li Yang 
Cc: Thomas Moll 
Cc: Micha Nelissen 
---
 drivers/rapidio/rio-scan.c |   10 +-
 1 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c
index e655756..467e82b 100644
--- a/drivers/rapidio/rio-scan.c
+++ b/drivers/rapidio/rio-scan.c
@@ -46,7 +46,6 @@ static void rio_init_em(struct rio_dev *rdev);
 DEFINE_SPINLOCK(rio_global_list_lock);
 
 static int next_destid = 0;
-static int next_switchid = 0;
 static int next_net = 0;
 static int next_comptag = 1;
 
@@ -438,6 +437,10 @@ static struct rio_dev __devinit *rio_setup_device(struct 
rio_net *net,
rio_mport_write_config_32(port, destid, hopcount,
  RIO_COMPONENT_TAG_CSR, next_comptag);
rdev->comp_tag = next_comptag++;
+   }  else {
+   rio_mport_read_config_32(port, destid, hopcount,
+RIO_COMPONENT_TAG_CSR,
+&rdev->comp_tag);
}
 
if (rio_device_has_destid(port, rdev->src_ops, rdev->dst_ops)) {
@@ -461,7 +464,7 @@ static struct rio_dev __devinit *rio_setup_device(struct 
rio_net *net,
/* If a PE has both switch and other functions, show it as a switch */
if (rio_is_switch(rdev)) {
rswitch = rdev->rswitch;
-   rswitch->switchid = next_switchid;
+   rswitch->switchid = rdev->comp_tag & RIO_CTAG_UDEVID;
rswitch->port_ok = 0;
rswitch->route_table = kzalloc(sizeof(u8)*
RIO_MAX_ROUTE_ENTRIES(port->sys_size),
@@ -816,7 +819,6 @@ static int __devinit rio_enum_peer(struct rio_net *net, 
struct rio_mport *port,
return -1;
 
if (rio_is_switch(rdev)) {
-   next_switchid++;
sw_inport = RIO_GET_PORT_NUM(rdev->swpinfo);
rio_route_add_entry(rdev, RIO_GLOBAL_TABLE,
port->host_deviceid, sw_inport, 0);
@@ -964,8 +966,6 @@ rio_disc_peer(struct rio_net *net, struct rio_mport *port, 
u16 destid,
return -1;
 
if (rio_is_switch(rdev)) {
-   next_switchid++;
-
/* Associated destid is how we accessed this switch */
rdev->destid = destid;
 
-- 
1.7.3.1

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH -mm 1/4] RapidIO: Add definitions of Component Tag fields

2010-12-10 Thread Alexandre Bounine
Add definition of the unique device identifier field in the component tag.
RIO_CTAG_UDEVID does not take all 32 bits of the component tag value to
allow future extensions to the component tag use.

Selected size of the RIO_CTAG_UDEVID field (17 bits) is sufficient to 
accommodate
maximum number of endpoints in large RIO network (16-bit id) plus switches.

Signed-off-by: Alexandre Bounine 
Cc: Kumar Gala 
Cc: Matt Porter 
Cc: Li Yang 
Cc: Thomas Moll 
Cc: Micha Nelissen 
---
 drivers/rapidio/rio.c |2 +-
 include/linux/rio.h   |   10 ++
 2 files changed, 11 insertions(+), 1 deletions(-)

diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c
index c13289e..cc2a3b7 100644
--- a/drivers/rapidio/rio.c
+++ b/drivers/rapidio/rio.c
@@ -710,7 +710,7 @@ int rio_inb_pwrite_handler(union rio_pw_msg *pw_msg)
u32 err_status, em_perrdet, em_ltlerrdet;
int rc, portnum;
 
-   rdev = rio_get_comptag(pw_msg->em.comptag, NULL);
+   rdev = rio_get_comptag((pw_msg->em.comptag & RIO_CTAG_UDEVID), NULL);
if (rdev == NULL) {
/* Device removed or enumeration error */
pr_debug("RIO: %s No matching device for CTag 0x%08x\n",
diff --git a/include/linux/rio.h b/include/linux/rio.h
index 9b55885..ff681eb 100644
--- a/include/linux/rio.h
+++ b/include/linux/rio.h
@@ -66,6 +66,16 @@
 
 #define RIO_PW_MSG_SIZE64
 
+/*
+ * A component tag value (stored in the component tag CSR) is used as device's
+ * unique identifier assigned during enumeration. Besides being used for
+ * identifying switches (which do not have device ID register), it also is used
+ * by error management notification and therefore has to be assigned
+ * to endpoints as well.
+ */
+#define RIO_CTAG_RESRVD0xfffe /* Reserved */
+#define RIO_CTAG_UDEVID0x0001 /* Unique device identifier */
+
 extern struct bus_type rio_bus_type;
 extern struct device rio_bus;
 extern struct list_head rio_devices;   /* list of all devices */
-- 
1.7.3.1

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH -mm 0/4] RapidIO: Misc updates

2010-12-10 Thread Alexandre Bounine
The following four patches are follow-up to two RapidIO patches
that are in the -mm tree now.

Alexandre Bounine (4):
  RapidIO: Add definitions of Component Tag fields
  RapidIO: Add device object linking into discovery
  RapidIO: Use Component Tag for unified switch identification
  RapidIO: Add new sysfs attributes

 drivers/rapidio/rio-scan.c  |   21 -
 drivers/rapidio/rio-sysfs.c |   39 ++-
 drivers/rapidio/rio.c   |2 +-
 include/linux/rio.h |   10 ++
 4 files changed, 61 insertions(+), 11 deletions(-)

-- 
1.7.3.1

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH -mm 4/4] RapidIO: Add new sysfs attributes

2010-12-10 Thread Alexandre Bounine
Add new sysfs attributes.

1. Routing information required to to reach the RIO device:
destid - device destination ID (real for for endpoint, route for switch)
hopcount - hopcount for maintenance requests (switches only)

2. device linking information:
lprev - name of device that precedes the given device in the enumeration
or discovery order (displayed along with of the port to which it
is attached).
lnext - names of devices (with corresponding port numbers) that are
attached to the given device as next in the enumeration or
discovery order (switches only)

Signed-off-by: Alexandre Bounine 
Cc: Kumar Gala 
Cc: Matt Porter 
Cc: Li Yang 
Cc: Thomas Moll 
Cc: Micha Nelissen 
---
 drivers/rapidio/rio-sysfs.c |   39 ++-
 1 files changed, 38 insertions(+), 1 deletions(-)

diff --git a/drivers/rapidio/rio-sysfs.c b/drivers/rapidio/rio-sysfs.c
index 76b4185..b8d9eaf 100644
--- a/drivers/rapidio/rio-sysfs.c
+++ b/drivers/rapidio/rio-sysfs.c
@@ -33,6 +33,8 @@ rio_config_attr(device_rev, "0x%08x\n");
 rio_config_attr(asm_did, "0x%04x\n");
 rio_config_attr(asm_vid, "0x%04x\n");
 rio_config_attr(asm_rev, "0x%04x\n");
+rio_config_attr(destid, "0x%04x\n");
+rio_config_attr(hopcount, "0x%02x\n");
 
 static ssize_t routes_show(struct device *dev, struct device_attribute *attr, 
char *buf)
 {
@@ -52,6 +54,33 @@ static ssize_t routes_show(struct device *dev, struct 
device_attribute *attr, ch
return (str - buf);
 }
 
+static ssize_t lprev_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+   struct rio_dev *rdev = to_rio_dev(dev);
+
+   return sprintf(buf, "%02d %s\n", RIO_GET_PORT_NUM(rdev->swpinfo),
+  (rdev->prev) ? rio_name(rdev->prev) : "host");
+}
+
+static ssize_t lnext_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+   struct rio_dev *rdev = to_rio_dev(dev);
+   char *str = buf;
+   int i;
+
+   if (rdev->pef & RIO_PEF_SWITCH) {
+   for (i = 0; i < RIO_GET_TOTAL_PORTS(rdev->swpinfo); i++) {
+   if (rdev->rswitch->nextdev[i])
+   str += sprintf(str, "%02d %s\n", i,
+   rio_name(rdev->rswitch->nextdev[i]));
+   }
+   }
+
+   return str - buf;
+}
+
 struct device_attribute rio_dev_attrs[] = {
__ATTR_RO(did),
__ATTR_RO(vid),
@@ -59,10 +88,14 @@ struct device_attribute rio_dev_attrs[] = {
__ATTR_RO(asm_did),
__ATTR_RO(asm_vid),
__ATTR_RO(asm_rev),
+   __ATTR_RO(lprev),
+   __ATTR_RO(destid),
__ATTR_NULL,
 };
 
 static DEVICE_ATTR(routes, S_IRUGO, routes_show, NULL);
+static DEVICE_ATTR(lnext, S_IRUGO, lnext_show, NULL);
+static DEVICE_ATTR(hopcount, S_IRUGO, hopcount_show, NULL);
 
 static ssize_t
 rio_read_config(struct file *filp, struct kobject *kobj,
@@ -218,7 +251,9 @@ int rio_create_sysfs_dev_files(struct rio_dev *rdev)
err = device_create_bin_file(&rdev->dev, &rio_config_attr);
 
if (!err && (rdev->pef & RIO_PEF_SWITCH)) {
-   err = device_create_file(&rdev->dev, &dev_attr_routes);
+   err |= device_create_file(&rdev->dev, &dev_attr_routes);
+   err |= device_create_file(&rdev->dev, &dev_attr_lnext);
+   err |= device_create_file(&rdev->dev, &dev_attr_hopcount);
if (!err && rdev->rswitch->sw_sysfs)
err = rdev->rswitch->sw_sysfs(rdev, 
RIO_SW_SYSFS_CREATE);
}
@@ -241,6 +276,8 @@ void rio_remove_sysfs_dev_files(struct rio_dev *rdev)
device_remove_bin_file(&rdev->dev, &rio_config_attr);
if (rdev->pef & RIO_PEF_SWITCH) {
device_remove_file(&rdev->dev, &dev_attr_routes);
+   device_remove_file(&rdev->dev, &dev_attr_lnext);
+   device_remove_file(&rdev->dev, &dev_attr_hopcount);
if (rdev->rswitch->sw_sysfs)
rdev->rswitch->sw_sysfs(rdev, RIO_SW_SYSFS_REMOVE);
}
-- 
1.7.3.1

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH -mm 2/4] RapidIO: Add device object linking into discovery

2010-12-10 Thread Alexandre Bounine
Add setting links between rio_dev objects into the discovery process.
This needed to report device connections on agent (non-host) processors
that perform RIO discovery. Originally, these links have been introduced
for enumerating host only to support error management.

Signed-off-by: Alexandre Bounine 
Cc: Kumar Gala 
Cc: Matt Porter 
Cc: Li Yang 
Cc: Thomas Moll 
Cc: Micha Nelissen 
---
 drivers/rapidio/rio-scan.c |   11 +++
 1 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c
index 45d14cd..e655756 100644
--- a/drivers/rapidio/rio-scan.c
+++ b/drivers/rapidio/rio-scan.c
@@ -947,7 +947,7 @@ static int rio_enum_complete(struct rio_mport *port)
  */
 static int __devinit
 rio_disc_peer(struct rio_net *net, struct rio_mport *port, u16 destid,
- u8 hopcount)
+ u8 hopcount, struct rio_dev *prev, int prev_port)
 {
u8 port_num, route_port;
struct rio_dev *rdev;
@@ -957,6 +957,9 @@ rio_disc_peer(struct rio_net *net, struct rio_mport *port, 
u16 destid,
if ((rdev = rio_setup_device(net, port, destid, hopcount, 0))) {
/* Add device to the global and bus/net specific list. */
list_add_tail(&rdev->net_list, &net->devices);
+   rdev->prev = prev;
+   if (prev && rio_is_switch(prev))
+   prev->rswitch->nextdev[prev_port] = rdev;
} else
return -1;
 
@@ -998,8 +1001,8 @@ rio_disc_peer(struct rio_net *net, struct rio_mport *port, 
u16 destid,
if (ndestid == RIO_ANY_DESTID(port->sys_size))
continue;
rio_unlock_device(port, destid, hopcount);
-   if (rio_disc_peer
-   (net, port, ndestid, hopcount + 1) < 0)
+   if (rio_disc_peer(net, port, ndestid,
+   hopcount + 1, rdev, port_num) < 0)
return -1;
}
}
@@ -1291,7 +1294,7 @@ int __devinit rio_disc_mport(struct rio_mport *mport)
   mport->host_deviceid);
 
if (rio_disc_peer(net, mport, RIO_ANY_DESTID(mport->sys_size),
-   0) < 0) {
+   0, NULL, 0) < 0) {
printk(KERN_INFO
   "RIO: master port %d device has failed 
discovery\n",
   mport->id);
-- 
1.7.3.1

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH -mm 1/2] RapidIO: Use common destid storage for endpoints and switches

2010-10-21 Thread Alexandre Bounine
Changes code to use one storage location common for switches and endpoints.
This eliminates unnecessary device type checks during basic access
operations. Logic that assigns destid to RIO devices stays unchanged - as
before, switches use an associated destid because they do not have their own.

Signed-off-by: Alexandre Bounine 
Cc: Kumar Gala 
Cc: Matt Porter 
Cc: Li Yang 
Cc: Thomas Moll 
Cc: Micha Nelissen 
---
 drivers/rapidio/rio-scan.c  |   84 ---
 drivers/rapidio/rio.c   |   74 ---
 drivers/rapidio/switches/idt_gen2.c |   93 ---
 drivers/rapidio/switches/idtcps.c   |6 +--
 drivers/rapidio/switches/tsi568.c   |   13 ++---
 drivers/rapidio/switches/tsi57x.c   |   56 +
 include/linux/rio.h |8 +--
 include/linux/rio_drv.h |   72 +--
 8 files changed, 141 insertions(+), 265 deletions(-)

diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c
index 1eb82c4..51f0af2 100644
--- a/drivers/rapidio/rio-scan.c
+++ b/drivers/rapidio/rio-scan.c
@@ -437,9 +437,15 @@ static struct rio_dev __devinit *rio_setup_device(struct 
rio_net *net,
next_destid++;
} else
rdev->destid = rio_get_device_id(port, destid, 
hopcount);
-   } else
-   /* Switch device has an associated destID */
-   rdev->destid = RIO_INVALID_DESTID;
+
+   rdev->hopcount = 0xff;
+   } else {
+   /* Switch device has an associated destID which
+* will be adjusted later
+*/
+   rdev->destid = destid;
+   rdev->hopcount = hopcount;
+   }
 
/* If a PE has both switch and other functions, show it as a switch */
if (rio_is_switch(rdev)) {
@@ -450,8 +456,6 @@ static struct rio_dev __devinit *rio_setup_device(struct 
rio_net *net,
if (!rswitch)
goto cleanup;
rswitch->switchid = next_switchid;
-   rswitch->hopcount = hopcount;
-   rswitch->destid = destid;
rswitch->port_ok = 0;
rswitch->route_table = kzalloc(sizeof(u8)*
RIO_MAX_ROUTE_ENTRIES(port->sys_size),
@@ -632,8 +636,7 @@ rio_unlock_device(struct rio_mport *port, u16 destid, u8 
hopcount)
 
 /**
  * rio_route_add_entry- Add a route entry to a switch routing table
- * @mport: Master port to send transaction
- * @rswitch: Switch device
+ * @rdev: RIO device
  * @table: Routing table ID
  * @route_destid: Destination ID to be routed
  * @route_port: Port number to be routed
@@ -647,31 +650,31 @@ rio_unlock_device(struct rio_mport *port, u16 destid, u8 
hopcount)
  * on failure.
  */
 static int
-rio_route_add_entry(struct rio_mport *mport, struct rio_switch *rswitch,
+rio_route_add_entry(struct rio_dev *rdev,
u16 table, u16 route_destid, u8 route_port, int lock)
 {
int rc;
 
if (lock) {
-   rc = rio_lock_device(mport, rswitch->destid,
-rswitch->hopcount, 1000);
+   rc = rio_lock_device(rdev->net->hport, rdev->destid,
+rdev->hopcount, 1000);
if (rc)
return rc;
}
 
-   rc = rswitch->add_entry(mport, rswitch->destid,
-   rswitch->hopcount, table,
-   route_destid, route_port);
+   rc = rdev->rswitch->add_entry(rdev->net->hport, rdev->destid,
+ rdev->hopcount, table,
+ route_destid, route_port);
if (lock)
-   rio_unlock_device(mport, rswitch->destid, rswitch->hopcount);
+   rio_unlock_device(rdev->net->hport, rdev->destid,
+ rdev->hopcount);
 
return rc;
 }
 
 /**
  * rio_route_get_entry- Read a route entry in a switch routing table
- * @mport: Master port to send transaction
- * @rswitch: Switch device
+ * @rdev: RIO device
  * @table: Routing table ID
  * @route_destid: Destination ID to be routed
  * @route_port: Pointer to read port number into
@@ -685,23 +688,24 @@ rio_route_add_entry(struct rio_mport *mport, struct 
rio_switch *rswitch,
  * on failure.
  */
 static int
-rio_route_get_entry(struct rio_mport *mport, struct rio_switch *rswitch, u16 
table,
+rio_route_get_entry(struct rio_dev *rdev, u16 table,
u16 route_destid, u8 *route_port, int lock)
 {
int rc;
 
if (lock) {
-   rc = rio_lock_device(mport, rswitch->destid,
-rswitch->hopcount, 1000);
+   rc = rio

[PATCH -mm 2/2] RapidIO: Integrate rio_switch into rio_dev

2010-10-21 Thread Alexandre Bounine
Convert RIO switches device structures (rio_dev + rio_switch) into
a single allocation unit.

This change is based on the fact that RIO switches are using
common RIO device objects anyway. Allocating RIO switch objects
as RIO devices with added space for switch information simplifies handling
of RIO switch devices.

Signed-off-by: Alexandre Bounine 
Cc: Kumar Gala 
Cc: Matt Porter 
Cc: Li Yang 
Cc: Thomas Moll 
Cc: Micha Nelissen 
---
 drivers/rapidio/rio-scan.c  |   59 +--
 drivers/rapidio/rio-sysfs.c |4 +-
 include/linux/rio.h |   82 +-
 3 files changed, 75 insertions(+), 70 deletions(-)

diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c
index 51f0af2..45d14cd 100644
--- a/drivers/rapidio/rio-scan.c
+++ b/drivers/rapidio/rio-scan.c
@@ -378,12 +378,30 @@ static struct rio_dev __devinit *rio_setup_device(struct 
rio_net *net,
struct rio_dev *rdev;
struct rio_switch *rswitch = NULL;
int result, rdid;
+   size_t size;
+   u32 swpinfo = 0;
 
-   rdev = kzalloc(sizeof(struct rio_dev), GFP_KERNEL);
+   size = sizeof(struct rio_dev);
+   if (rio_mport_read_config_32(port, destid, hopcount,
+RIO_PEF_CAR, &result))
+   return NULL;
+
+   if (result & (RIO_PEF_SWITCH | RIO_PEF_MULTIPORT)) {
+   rio_mport_read_config_32(port, destid, hopcount,
+RIO_SWP_INFO_CAR, &swpinfo);
+   if (result & RIO_PEF_SWITCH) {
+   size += (RIO_GET_TOTAL_PORTS(swpinfo) *
+   sizeof(rswitch->nextdev[0])) + sizeof(*rswitch);
+   }
+   }
+
+   rdev = kzalloc(size, GFP_KERNEL);
if (!rdev)
return NULL;
 
rdev->net = net;
+   rdev->pef = result;
+   rdev->swpinfo = swpinfo;
rio_mport_read_config_32(port, destid, hopcount, RIO_DEV_ID_CAR,
 &result);
rdev->did = result >> 16;
@@ -397,8 +415,6 @@ static struct rio_dev __devinit *rio_setup_device(struct 
rio_net *net,
rio_mport_read_config_32(port, destid, hopcount, RIO_ASM_INFO_CAR,
 &result);
rdev->asm_rev = result >> 16;
-   rio_mport_read_config_32(port, destid, hopcount, RIO_PEF_CAR,
-&rdev->pef);
if (rdev->pef & RIO_PEF_EXT_FEATURES) {
rdev->efptr = result & 0x;
rdev->phys_efptr = rio_mport_get_physefb(port, 0, destid,
@@ -408,11 +424,6 @@ static struct rio_dev __devinit *rio_setup_device(struct 
rio_net *net,
hopcount, RIO_EFB_ERR_MGMNT);
}
 
-   if (rdev->pef & (RIO_PEF_SWITCH | RIO_PEF_MULTIPORT)) {
-   rio_mport_read_config_32(port, destid, hopcount,
-RIO_SWP_INFO_CAR, &rdev->swpinfo);
-   }
-
rio_mport_read_config_32(port, destid, hopcount, RIO_SRC_OPS_CAR,
 &rdev->src_ops);
rio_mport_read_config_32(port, destid, hopcount, RIO_DST_OPS_CAR,
@@ -449,12 +460,7 @@ static struct rio_dev __devinit *rio_setup_device(struct 
rio_net *net,
 
/* If a PE has both switch and other functions, show it as a switch */
if (rio_is_switch(rdev)) {
-   rswitch = kzalloc(sizeof(*rswitch) +
- RIO_GET_TOTAL_PORTS(rdev->swpinfo) *
- sizeof(rswitch->nextdev[0]),
- GFP_KERNEL);
-   if (!rswitch)
-   goto cleanup;
+   rswitch = rdev->rswitch;
rswitch->switchid = next_switchid;
rswitch->port_ok = 0;
rswitch->route_table = kzalloc(sizeof(u8)*
@@ -466,15 +472,13 @@ static struct rio_dev __devinit *rio_setup_device(struct 
rio_net *net,
for (rdid = 0; rdid < RIO_MAX_ROUTE_ENTRIES(port->sys_size);
rdid++)
rswitch->route_table[rdid] = RIO_INVALID_ROUTE;
-   rdev->rswitch = rswitch;
-   rswitch->rdev = rdev;
dev_set_name(&rdev->dev, "%02x:s:%04x", rdev->net->id,
-rdev->rswitch->switchid);
+rswitch->switchid);
rio_switch_init(rdev, do_enum);
 
-   if (do_enum && rdev->rswitch->clr_table)
-   rdev->rswitch->clr_table(port, destid, hopcount,
-RIO_GLOBAL_TABLE);
+   if (do_enum && rswitch->clr_table)
+   rswitch->clr_table(port, 

[PATCH -mm 0/2] RapidIO: Changes to handling of RIO switches

2010-10-21 Thread Alexandre Bounine
The following two patches are produced as result of the discussion
referenced below:

http://lists.ozlabs.org/pipermail/linuxppc-dev/2010-September/085829.html
http://lists.ozlabs.org/pipermail/linuxppc-dev/2010-October/086226.html

Switches in RapidIO subsystem are presented the same way as endpoints - by
using rio_dev structure plus an additional switch-specific extension allocated
separately. This separation between two objects describing a RIO switch device
also is reflected in the way how RIO address is stored for endpoints and
switches. Proposed patches are attempt to address issues brought by differences
in endpoint and switch handling in RapidIO subsystem.  

1. Using one storage location common for switches and endpoints eliminates
unnecessary device type checks during maintenance access operations.
While destination IDs and hop counts have different meaning for endpoints and
switches, this does not prevent us from storing them in the primary RIO device
structure (rio_dev) for both types.
The logic that assigns destination IDs to RIO devices stays unchanged - as
before, switches use an associated destination ID because they do not have
their own physical ID. The hop_count is set to 0xff for endpoints and to the
actual value for switches. 

2. Convert RIO switch device structures (rio_dev + rio_switch) into single
allocation unit. This change is based on the fact that RIO switches are using
common RIO device objects anyway. Allocating RIO switch objects as RIO devices
with added space for switch information simplifies handling of RIO switch device
objects.


Alexandre Bounine (2):
  RapidIO: Use common destid storage for endpoints and switches
  RapidIO: Integrate rio_switch into rio_dev

 drivers/rapidio/rio-scan.c  |  139 ++-
 drivers/rapidio/rio-sysfs.c |4 +-
 drivers/rapidio/rio.c   |   74 ++-
 drivers/rapidio/switches/idt_gen2.c |   93 ---
 drivers/rapidio/switches/idtcps.c   |6 +-
 drivers/rapidio/switches/tsi568.c   |   13 +--
 drivers/rapidio/switches/tsi57x.c   |   56 ++
 include/linux/rio.h |   90 +++
 include/linux/rio_drv.h |   72 +++---
 9 files changed, 214 insertions(+), 333 deletions(-)

-- 
1.7.3.1

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH -mm 2/2] RapidIO: Fix destructive port EM initialization for Tsi568

2010-10-18 Thread Alexandre Bounine
Replaces possibly damaging broadcast writes into the per-port SP_MODE
registers with individual writes for each port. This will preserve
individual port configurations in case if ports are configured differently.

Signed-off-by: Alexandre Bounine 
Cc: Kumar Gala 
Cc: Matt Porter 
Cc: Li Yang 
Cc: Thomas Moll 
Cc: Micha Nelissen 
---
 drivers/rapidio/switches/tsi568.c |   15 ++-
 1 files changed, 10 insertions(+), 5 deletions(-)

diff --git a/drivers/rapidio/switches/tsi568.c 
b/drivers/rapidio/switches/tsi568.c
index f7fd789..b9a389b 100644
--- a/drivers/rapidio/switches/tsi568.c
+++ b/drivers/rapidio/switches/tsi568.c
@@ -29,7 +29,7 @@
 #define SPP_ROUTE_CFG_DESTID(n)(0x11070 + 0x100*n)
 #define SPP_ROUTE_CFG_PORT(n)  (0x11074 + 0x100*n)
 
-#define TSI568_SP_MODE_BC  0x10004
+#define TSI568_SP_MODE(n)  (0x11004 + 0x100*n)
 #define  TSI568_SP_MODE_PW_DIS 0x0800
 
 static int
@@ -117,14 +117,19 @@ tsi568_em_init(struct rio_dev *rdev)
u16 destid = rdev->rswitch->destid;
u8 hopcount = rdev->rswitch->hopcount;
u32 regval;
+   int portnum;
 
pr_debug("TSI568 %s [%d:%d]\n", __func__, destid, hopcount);
 
/* Make sure that Port-Writes are disabled (for all ports) */
-   rio_mport_read_config_32(mport, destid, hopcount,
-   TSI568_SP_MODE_BC, ®val);
-   rio_mport_write_config_32(mport, destid, hopcount,
-   TSI568_SP_MODE_BC, regval | TSI568_SP_MODE_PW_DIS);
+   for (portnum = 0;
+portnum < RIO_GET_TOTAL_PORTS(rdev->swpinfo); portnum++) {
+   rio_mport_read_config_32(mport, destid, hopcount,
+   TSI568_SP_MODE(portnum), ®val);
+   rio_mport_write_config_32(mport, destid, hopcount,
+   TSI568_SP_MODE(portnum),
+   regval | TSI568_SP_MODE_PW_DIS);
+   }
 
return 0;
 }
-- 
1.7.3.1

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH -mm 1/2] RapidIO: Fix maximum port number in tsi57x EM initialization

2010-10-18 Thread Alexandre Bounine
Replace hardcoded maximum port number with actual reported number of
switch ports.

Signed-off-by: Alexandre Bounine 
Cc: Kumar Gala 
Cc: Matt Porter 
Cc: Li Yang 
Cc: Thomas Moll 
Cc: Micha Nelissen 
---
 drivers/rapidio/switches/tsi57x.c |3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/drivers/rapidio/switches/tsi57x.c 
b/drivers/rapidio/switches/tsi57x.c
index d9e9492..2003fb6 100644
--- a/drivers/rapidio/switches/tsi57x.c
+++ b/drivers/rapidio/switches/tsi57x.c
@@ -166,7 +166,8 @@ tsi57x_em_init(struct rio_dev *rdev)
 
pr_debug("TSI578 %s [%d:%d]\n", __func__, destid, hopcount);
 
-   for (portnum = 0; portnum < 16; portnum++) {
+   for (portnum = 0;
+portnum < RIO_GET_TOTAL_PORTS(rdev->swpinfo); portnum++) {
/* Make sure that Port-Writes are enabled (for all ports) */
rio_mport_read_config_32(mport, destid, hopcount,
TSI578_SP_MODE(portnum), ®val);
-- 
1.7.3.1

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH -mm] RapidIO: fix IDLE2 bits corruption

2010-10-01 Thread Alexandre Bounine
RapidIO spec v.2.1 adds Idle Sequence 2 into LP-Serial Physical
Layer. The fix ensures that corresponding bits are not corrupted during
error handling.

Signed-off-by: Alexandre Bounine 
Cc: Thomas Moll 
Cc: Matt Porter 
Cc: Li Yang 
Cc: Kumar Gala 
Cc: Micha Nelissen 
---
 drivers/rapidio/rio.c|9 ++---
 include/linux/rio_regs.h |3 +--
 2 files changed, 3 insertions(+), 9 deletions(-)

diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c
index 7f18a65..68cf0c9 100644
--- a/drivers/rapidio/rio.c
+++ b/drivers/rapidio/rio.c
@@ -871,15 +871,10 @@ int rio_inb_pwrite_handler(union rio_pw_msg *pw_msg)
rdev->em_efptr + RIO_EM_LTL_ERR_DETECT, 0);
}
 
-   /* Clear remaining error bits */
+   /* Clear remaining error bits and Port-Write Pending bit */
rio_mport_write_config_32(mport, destid, hopcount,
rdev->phys_efptr + RIO_PORT_N_ERR_STS_CSR(portnum),
-   err_status & RIO_PORT_N_ERR_STS_CLR_MASK);
-
-   /* Clear Port-Write Pending bit */
-   rio_mport_write_config_32(mport, destid, hopcount,
-   rdev->phys_efptr + RIO_PORT_N_ERR_STS_CSR(portnum),
-   RIO_PORT_N_ERR_STS_PW_PEND);
+   err_status);
 
return 0;
 }
diff --git a/include/linux/rio_regs.h b/include/linux/rio_regs.h
index a18b2e2..d63dcba 100644
--- a/include/linux/rio_regs.h
+++ b/include/linux/rio_regs.h
@@ -229,7 +229,7 @@
 #define  RIO_MNT_REQ_CMD_IS0x04/* Input-status command */
 #define RIO_PORT_N_MNT_RSP_CSR(x)  (0x0044 + x*0x20)   /* 0x0002 */
 #define  RIO_PORT_N_MNT_RSP_RVAL   0x8000 /* Response Valid */
-#define  RIO_PORT_N_MNT_RSP_ASTAT  0x03e0 /* ackID Status */
+#define  RIO_PORT_N_MNT_RSP_ASTAT  0x07e0 /* ackID Status */
 #define  RIO_PORT_N_MNT_RSP_LSTAT  0x001f /* Link Status */
 #define RIO_PORT_N_ACK_STS_CSR(x)  (0x0048 + x*0x20)   /* 0x0002 */
 #define  RIO_PORT_N_ACK_CLEAR  0x8000
@@ -243,7 +243,6 @@
 #define  RIO_PORT_N_ERR_STS_PORT_ERR   0x0004
 #define  RIO_PORT_N_ERR_STS_PORT_OK0x0002
 #define  RIO_PORT_N_ERR_STS_PORT_UNINIT0x0001
-#define  RIO_PORT_N_ERR_STS_CLR_MASK   0x07120204
 #define RIO_PORT_N_CTL_CSR(x)  (0x005c + x*0x20)
 #define  RIO_PORT_N_CTL_PWIDTH 0xc000
 #define  RIO_PORT_N_CTL_PWIDTH_1   0x
-- 
1.7.3.1

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH v2 09/10] RapidIO: Add support for IDT CPS Gen2 switches

2010-09-14 Thread Alexandre Bounine
Add the RIO switch driver and definitions for IDT CPS-1848 and CPS-1616 Gen2
devices.

Signed-off-by: Alexandre Bounine 
Cc: Thomas Moll 
Cc: Matt Porter 
Cc: Li Yang 
Cc: Kumar Gala 
Cc: Micha Nelissen 
---
 drivers/rapidio/switches/Kconfig|7 +
 drivers/rapidio/switches/Makefile   |1 +
 drivers/rapidio/switches/idt_gen2.c |  447 +++
 include/linux/rio_ids.h |2 +
 include/linux/rio_regs.h|5 +
 5 files changed, 462 insertions(+), 0 deletions(-)
 create mode 100644 drivers/rapidio/switches/idt_gen2.c

diff --git a/drivers/rapidio/switches/Kconfig b/drivers/rapidio/switches/Kconfig
index 2b4e9b2..f47fee5 100644
--- a/drivers/rapidio/switches/Kconfig
+++ b/drivers/rapidio/switches/Kconfig
@@ -20,6 +20,13 @@ config RAPIDIO_TSI568
---help---
  Includes support for IDT Tsi568 serial RapidIO switch.
 
+config RAPIDIO_CPS_GEN2
+   bool "IDT CPS Gen.2 SRIO switch support"
+   depends on RAPIDIO
+   default n
+   ---help---
+ Includes support for ITD CPS Gen.2 serial RapidIO switches.
+
 config RAPIDIO_TSI500
bool "Tsi500 Parallel RapidIO switch support"
depends on RAPIDIO
diff --git a/drivers/rapidio/switches/Makefile 
b/drivers/rapidio/switches/Makefile
index fe4adc3..48d67a6 100644
--- a/drivers/rapidio/switches/Makefile
+++ b/drivers/rapidio/switches/Makefile
@@ -6,6 +6,7 @@ obj-$(CONFIG_RAPIDIO_TSI57X)+= tsi57x.o
 obj-$(CONFIG_RAPIDIO_CPS_XX)   += idtcps.o
 obj-$(CONFIG_RAPIDIO_TSI568)   += tsi568.o
 obj-$(CONFIG_RAPIDIO_TSI500)   += tsi500.o
+obj-$(CONFIG_RAPIDIO_CPS_GEN2) += idt_gen2.o
 
 ifeq ($(CONFIG_RAPIDIO_DEBUG),y)
 EXTRA_CFLAGS += -DDEBUG
diff --git a/drivers/rapidio/switches/idt_gen2.c 
b/drivers/rapidio/switches/idt_gen2.c
new file mode 100644
index 000..0bb871c
--- /dev/null
+++ b/drivers/rapidio/switches/idt_gen2.c
@@ -0,0 +1,447 @@
+/*
+ * IDT CPS Gen.2 Serial RapidIO switch family support
+ *
+ * Copyright 2010 Integrated Device Technology, Inc.
+ * Alexandre Bounine 
+ *
+ * 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 
+#include 
+#include 
+#include 
+#include "../rio.h"
+
+#define LOCAL_RTE_CONF_DESTID_SEL  0x010070
+#define LOCAL_RTE_CONF_DESTID_SEL_PSEL 0x001f
+
+#define IDT_LT_ERR_REPORT_EN   0x03100c
+
+#define IDT_PORT_ERR_REPORT_EN(n)  (0x031044 + (n)*0x40)
+#define IDT_PORT_ERR_REPORT_EN_BC  0x03ff04
+
+#define IDT_PORT_ISERR_REPORT_EN(n)(0x03104C + (n)*0x40)
+#define IDT_PORT_ISERR_REPORT_EN_BC0x03ff0c
+#define IDT_PORT_INIT_TX_ACQUIRED  0x0020
+
+#define IDT_LANE_ERR_REPORT_EN(n)  (0x038010 + (n)*0x100)
+#define IDT_LANE_ERR_REPORT_EN_BC  0x03ff10
+
+#define IDT_DEV_CTRL_1 0xf2000c
+#define IDT_DEV_CTRL_1_GENPW   0x0200
+#define IDT_DEV_CTRL_1_PRSTBEH 0x0001
+
+#define IDT_CFGBLK_ERR_CAPTURE_EN  0x020008
+#define IDT_CFGBLK_ERR_REPORT  0xf20014
+#define IDT_CFGBLK_ERR_REPORT_GENPW0x0002
+
+#define IDT_AUX_PORT_ERR_CAP_EN0x02
+#define IDT_AUX_ERR_REPORT_EN  0xf20018
+#define IDT_AUX_PORT_ERR_LOG_I2C   0x0002
+#define IDT_AUX_PORT_ERR_LOG_JTAG  0x0001
+
+#defineIDT_ISLTL_ADDRESS_CAP   0x021014
+
+#define IDT_RIO_DOMAIN 0xf20020
+#define IDT_RIO_DOMAIN_MASK0x00ff
+
+#define IDT_PW_INFO_CSR0xf20024
+
+#define IDT_SOFT_RESET 0xf20040
+#define IDT_SOFT_RESET_REQ 0x00030097
+
+#define IDT_I2C_MCTRL  0xf20050
+#define IDT_I2C_MCTRL_GENPW0x0400
+
+#define IDT_JTAG_CTRL  0xf2005c
+#define IDT_JTAG_CTRL_GENPW0x0002
+
+#define IDT_LANE_CTRL(n)   (0xff8000 + (n)*0x100)
+#define IDT_LANE_CTRL_BC   0x00
+#define IDT_LANE_CTRL_GENPW0x0020
+#define IDT_LANE_DFE_1_BC  0x18
+#define IDT_LANE_DFE_2_BC  0x1c
+
+#define IDT_PORT_OPS(n)(0xf40004 + (n)*0x100)
+#define IDT_PORT_OPS_GENPW 0x0800
+#define IDT_PORT_OPS_PL_ELOG   0x0040
+#define IDT_PORT_OPS_LL_ELOG   0x0020
+#define IDT_PORT_OPS_LT_ELOG   0x0010
+#define IDT_PORT_OPS_BC0xf4ff04
+
+#define IDT_PORT_ISERR_DET(n)  (0xf40008 + (n)*0x100)
+
+#define IDT_ERR_CAP0xfd
+#define IDT_ERR_CAP_LOG_OVERWR 0x0004
+
+#define IDT_ERR_RD 0xfd0004
+
+#define IDT_DEFAULT_ROUTE  0xde
+#define IDT_NO_ROUTE   0xdf
+
+static int
+idtg2_route_add_entry(struct rio_mport *mport, u16 destid, u8 hopcount,
+  u16 table, u16 route_destid, u8 route_port)
+{
+   /*
+* Select routing table to update
+*/
+  

[PATCH v2 05/10] RapidIO: Add default handler for error-stopped state

2010-09-14 Thread Alexandre Bounine
The default error-stopped state handler provides recovery mechanism as defined
by RIO specification.

Signed-off-by: Alexandre Bounine 
Cc: Thomas Moll 
Cc: Matt Porter 
Cc: Li Yang 
Cc: Kumar Gala 
Cc: Micha Nelissen 
---
 drivers/rapidio/rio.c |  218 +++-
 drivers/rapidio/switches/idtcps.c |   10 ++
 drivers/rapidio/switches/tsi57x.c |4 +
 include/linux/rio_regs.h  |8 +-
 4 files changed, 206 insertions(+), 34 deletions(-)

diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c
index 74e9d22..77bd416 100644
--- a/drivers/rapidio/rio.c
+++ b/drivers/rapidio/rio.c
@@ -495,6 +495,148 @@ int rio_set_port_lockout(struct rio_dev *rdev, u32 pnum, 
int lock)
 }
 
 /**
+ * rio_get_input_status - Sends a Link-Request/Input-Status control symbol and
+ *returns link-response (if requested).
+ * @rdev: RIO devive to issue Input-status command
+ * @pnum: Device port number to issue the command
+ * @lnkresp: Response from a link partner
+ */
+static int
+rio_get_input_status(struct rio_dev *rdev, int pnum, u32 *lnkresp)
+{
+   struct rio_mport *mport = rdev->net->hport;
+   u16 destid = rdev->rswitch->destid;
+   u8 hopcount = rdev->rswitch->hopcount;
+   u32 regval;
+   int checkcount;
+
+   if (lnkresp) {
+   /* Read from link maintenance response register
+* to clear valid bit */
+   rio_mport_read_config_32(mport, destid, hopcount,
+   rdev->phys_efptr + RIO_PORT_N_MNT_RSP_CSR(pnum),
+   ®val);
+   udelay(50);
+   }
+
+   /* Issue Input-status command */
+   rio_mport_write_config_32(mport, destid, hopcount,
+   rdev->phys_efptr + RIO_PORT_N_MNT_REQ_CSR(pnum),
+   RIO_MNT_REQ_CMD_IS);
+
+   /* Exit if the response is not expected */
+   if (lnkresp == NULL)
+   return 0;
+
+   checkcount = 3;
+   while (checkcount--) {
+   udelay(50);
+   rio_mport_read_config_32(mport, destid, hopcount,
+   rdev->phys_efptr + RIO_PORT_N_MNT_RSP_CSR(pnum),
+   ®val);
+   if (regval & RIO_PORT_N_MNT_RSP_RVAL) {
+   *lnkresp = regval;
+   return 0;
+   }
+   }
+
+   return -EIO;
+}
+
+/**
+ * rio_clr_err_stopped - Clears port Error-stopped states.
+ * @rdev: Pointer to RIO device control structure
+ * @pnum: Switch port number to clear errors
+ * @err_status: port error status (if 0 reads register from device)
+ */
+static int rio_clr_err_stopped(struct rio_dev *rdev, u32 pnum, u32 err_status)
+{
+   struct rio_mport *mport = rdev->net->hport;
+   u16 destid = rdev->rswitch->destid;
+   u8 hopcount = rdev->rswitch->hopcount;
+   struct rio_dev *nextdev = rdev->rswitch->nextdev[pnum];
+   u32 regval;
+   u32 far_ackid, far_linkstat, near_ackid;
+
+   if (err_status == 0)
+   rio_mport_read_config_32(mport, destid, hopcount,
+   rdev->phys_efptr + RIO_PORT_N_ERR_STS_CSR(pnum),
+   &err_status);
+
+   if (err_status & RIO_PORT_N_ERR_STS_PW_OUT_ES) {
+   pr_debug("RIO_EM: servicing Output Error-Stopped state\n");
+   /*
+* Send a Link-Request/Input-Status control symbol
+*/
+   if (rio_get_input_status(rdev, pnum, ®val)) {
+   pr_debug("RIO_EM: Input-status response timeout\n");
+   goto rd_err;
+   }
+
+   pr_debug("RIO_EM: SP%d Input-status response=0x%08x\n",
+pnum, regval);
+   far_ackid = (regval & RIO_PORT_N_MNT_RSP_ASTAT) >> 5;
+   far_linkstat = regval & RIO_PORT_N_MNT_RSP_LSTAT;
+   rio_mport_read_config_32(mport, destid, hopcount,
+   rdev->phys_efptr + RIO_PORT_N_ACK_STS_CSR(pnum),
+   ®val);
+   pr_debug("RIO_EM: SP%d_ACK_STS_CSR=0x%08x\n", pnum, regval);
+   near_ackid = (regval & RIO_PORT_N_ACK_INBOUND) >> 24;
+   pr_debug("RIO_EM: SP%d far_ackID=0x%02x far_linkstat=0x%02x" \
+" near_ackID=0x%02x\n",
+   pnum, far_ackid, far_linkstat, near_ackid);
+
+   /*
+* If required, synchronize ackIDs of near and
+* far sides.
+*/
+   if ((far_ackid != ((regval & RIO_PORT_N_ACK_OUTSTAND) >> 8)) ||
+   (far_ackid != (regval & RIO_PORT_N_ACK_OUTBOUND))) {
+   /* Align near outstanding/outbound ackIDs with
+   

[PATCH v2 10/10] RapidIO: Add handling of redundant routes

2010-09-14 Thread Alexandre Bounine
Detects RIO link to the already enumerated device and properly sets links
between device objects. Changes to the enumeration/discovery logic:
1. Use Master Enable bit to signal end of the enumeration - agents may
start their discovery process as soon as they see this bit set (Component
Tag register was used before for this purpose).
2. Enumerator sets Component Tag (!= 0) immediately during device setup.
This allows to identify the device if the redundant route exists in a RIO
system.

Signed-off-by: Alexandre Bounine 
Cc: Thomas Moll 
Cc: Matt Porter 
Cc: Li Yang 
Cc: Kumar Gala 
Cc: Micha Nelissen 
---
 arch/powerpc/sysdev/fsl_rio.c |8 
 drivers/rapidio/rio-scan.c|   88 +---
 drivers/rapidio/rio.c |   16 +++
 drivers/rapidio/rio.h |1 +
 include/linux/rio.h   |2 +
 5 files changed, 64 insertions(+), 51 deletions(-)

diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c
index 551e8e2..91b7b89 100644
--- a/arch/powerpc/sysdev/fsl_rio.c
+++ b/arch/powerpc/sysdev/fsl_rio.c
@@ -50,6 +50,7 @@
 #define RIO_ATMU_REGS_OFFSET   0x10c00
 #define RIO_P_MSG_REGS_OFFSET  0x11000
 #define RIO_S_MSG_REGS_OFFSET  0x13000
+#define RIO_GCCSR  0x13c
 #define RIO_ESCSR  0x158
 #define RIO_CCSR   0x15c
 #define RIO_LTLEDCSR   0x0608
@@ -1456,6 +1457,7 @@ int fsl_rio_setup(struct platform_device *dev)
port->host_deviceid = fsl_rio_get_hdid(port->id);
 
port->priv = priv;
+   port->phys_efptr = 0x100;
rio_register_mport(port);
 
priv->regs_win = ioremap(regs.start, regs.end - regs.start + 1);
@@ -1503,6 +1505,12 @@ int fsl_rio_setup(struct platform_device *dev)
dev_info(&dev->dev, "RapidIO Common Transport System size: %d\n",
port->sys_size ? 65536 : 256);
 
+   if (port->host_deviceid >= 0)
+   out_be32(priv->regs_win + RIO_GCCSR, RIO_PORT_GEN_HOST |
+   RIO_PORT_GEN_MASTER | RIO_PORT_GEN_DISCOVERED);
+   else
+   out_be32(priv->regs_win + RIO_GCCSR, 0x);
+
priv->atmu_regs = (struct rio_atmu_regs *)(priv->regs_win
+ RIO_ATMU_REGS_OFFSET);
priv->maint_atmu_regs = priv->atmu_regs + 1;
diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c
index e3efdf9..1eb82c4 100644
--- a/drivers/rapidio/rio-scan.c
+++ b/drivers/rapidio/rio-scan.c
@@ -48,7 +48,7 @@ DEFINE_SPINLOCK(rio_global_list_lock);
 static int next_destid = 0;
 static int next_switchid = 0;
 static int next_net = 0;
-static int next_comptag;
+static int next_comptag = 1;
 
 static struct timer_list rio_enum_timer =
 TIMER_INITIALIZER(rio_enum_timeout, 0, 0);
@@ -121,27 +121,6 @@ static int rio_clear_locks(struct rio_mport *port)
u32 result;
int ret = 0;
 
-   /* Assign component tag to all devices */
-   next_comptag = 1;
-   rio_local_write_config_32(port, RIO_COMPONENT_TAG_CSR, next_comptag++);
-
-   list_for_each_entry(rdev, &rio_devices, global_list) {
-   /* Mark device as discovered */
-   rio_read_config_32(rdev,
-  rdev->phys_efptr + RIO_PORT_GEN_CTL_CSR,
-  &result);
-   rio_write_config_32(rdev,
-   rdev->phys_efptr + RIO_PORT_GEN_CTL_CSR,
-   result | RIO_PORT_GEN_DISCOVERED);
-
-   rio_write_config_32(rdev, RIO_COMPONENT_TAG_CSR, next_comptag);
-   rdev->comp_tag = next_comptag++;
-   if (next_comptag >= 0x1) {
-   pr_err("RIO: Component Tag Counter Overflow\n");
-   break;
-   }
-   }
-
/* Release host device id locks */
rio_local_write_config_32(port, RIO_HOST_DID_LOCK_CSR,
  port->host_deviceid);
@@ -162,6 +141,15 @@ static int rio_clear_locks(struct rio_mport *port)
   rdev->vid, rdev->did);
ret = -EINVAL;
}
+
+   /* Mark device as discovered and enable master */
+   rio_read_config_32(rdev,
+  rdev->phys_efptr + RIO_PORT_GEN_CTL_CSR,
+  &result);
+   result |= RIO_PORT_GEN_DISCOVERED | RIO_PORT_GEN_MASTER;
+   rio_write_config_32(rdev,
+   rdev->phys_efptr + RIO_PORT_GEN_CTL_CSR,
+   result);
}
 
return ret;
@@ -430,6 +418,17 @@ static struct rio_dev __devinit *rio_setup_device(struct 
rio_net *net,
rio_mport_read_config_32(port, destid, hopcount, RIO_DST_OPS_CAR,
 &

[PATCH v2 04/10] RapidIO: Add relation links between RIO device structures

2010-09-14 Thread Alexandre Bounine
Create back and forward links between RIO devices. These links are intended for
use by error management and hot-plug extensions. Links for redundant RIO
connections between switches are not set (will be fixed in a separate patch).

Signed-off-by: Alexandre Bounine 
Cc: Thomas Moll 
Cc: Matt Porter 
Cc: Li Yang 
Cc: Kumar Gala 
Cc: Micha Nelissen 
---
 drivers/rapidio/rio-scan.c |   56 ++--
 include/linux/rio.h|4 +++
 2 files changed, 27 insertions(+), 33 deletions(-)

diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c
index d09c359..d2ea018 100644
--- a/drivers/rapidio/rio-scan.c
+++ b/drivers/rapidio/rio-scan.c
@@ -444,7 +444,10 @@ static struct rio_dev __devinit *rio_setup_device(struct 
rio_net *net,
 
/* If a PE has both switch and other functions, show it as a switch */
if (rio_is_switch(rdev)) {
-   rswitch = kzalloc(sizeof(struct rio_switch), GFP_KERNEL);
+   rswitch = kzalloc(sizeof(*rswitch) +
+ RIO_GET_TOTAL_PORTS(rdev->swpinfo) *
+ sizeof(rswitch->nextdev[0]),
+ GFP_KERNEL);
if (!rswitch)
goto cleanup;
rswitch->switchid = next_switchid;
@@ -723,25 +726,6 @@ static u16 rio_get_host_deviceid_lock(struct rio_mport 
*port, u8 hopcount)
 }
 
 /**
- * rio_get_swpinfo_tports- Gets total number of ports on the switch
- * @mport: Master port to send transaction
- * @destid: Destination ID associated with the switch
- * @hopcount: Number of hops to the device
- *
- * Returns total numbers of ports implemented by the switch device.
- */
-static u8 rio_get_swpinfo_tports(struct rio_mport *mport, u16 destid,
-u8 hopcount)
-{
-   u32 result;
-
-   rio_mport_read_config_32(mport, destid, hopcount, RIO_SWP_INFO_CAR,
-&result);
-
-   return RIO_GET_TOTAL_PORTS(result);
-}
-
-/**
  * rio_net_add_mport- Add a master port to a RIO network
  * @net: RIO network
  * @port: Master port to add
@@ -761,15 +745,16 @@ static void rio_net_add_mport(struct rio_net *net, struct 
rio_mport *port)
  * @net: RIO network being enumerated
  * @port: Master port to send transactions
  * @hopcount: Number of hops into the network
+ * @prev: Previous RIO device connected to the enumerated one
+ * @prev_port: Port on previous RIO device
  *
  * Recursively enumerates a RIO network.  Transactions are sent via the
  * master port passed in @port.
  */
 static int __devinit rio_enum_peer(struct rio_net *net, struct rio_mport *port,
-u8 hopcount)
+u8 hopcount, struct rio_dev *prev, int prev_port)
 {
int port_num;
-   int num_ports;
int cur_destid;
int sw_destid;
int sw_inport;
@@ -814,6 +799,9 @@ static int __devinit rio_enum_peer(struct rio_net *net, 
struct rio_mport *port,
if (rdev) {
/* Add device to the global and bus/net specific list. */
list_add_tail(&rdev->net_list, &net->devices);
+   rdev->prev = prev;
+   if (prev && rio_is_switch(prev))
+   prev->rswitch->nextdev[prev_port] = rdev;
} else
return -1;
 
@@ -832,14 +820,14 @@ static int __devinit rio_enum_peer(struct rio_net *net, 
struct rio_mport *port,
rdev->rswitch->route_table[destid] = sw_inport;
}
 
-   num_ports =
-   rio_get_swpinfo_tports(port, RIO_ANY_DESTID(port->sys_size),
-   hopcount);
pr_debug(
"RIO: found %s (vid %4.4x did %4.4x) with %d ports\n",
-   rio_name(rdev), rdev->vid, rdev->did, num_ports);
+   rio_name(rdev), rdev->vid, rdev->did,
+   RIO_GET_TOTAL_PORTS(rdev->swpinfo));
sw_destid = next_destid;
-   for (port_num = 0; port_num < num_ports; port_num++) {
+   for (port_num = 0;
+port_num < RIO_GET_TOTAL_PORTS(rdev->swpinfo);
+port_num++) {
/*Enable Input Output Port (transmitter reviever)*/
rio_enable_rx_tx_port(port, 0,
  RIO_ANY_DESTID(port->sys_size),
@@ -864,7 +852,8 @@ static int __devinit rio_enum_peer(struct rio_net *net, 
struct rio_mport *port,
RIO_ANY_DESTID(port->sys_size),
port_num, 0);
 
-   if (rio_enum_peer(net, port, hopcount + 1) < 0)
+   if (rio_enum_peer(net, port, hopcount + 1,
+   

[PATCH v2 03/10] RapidIO: Use stored ingress port number instead of register read

2010-09-14 Thread Alexandre Bounine
A switch port information is obtained and stored during RIO device setup.
Therefore repeated reads from Switch Port Information CAR may be removed.

Signed-off-by: Alexandre Bounine 
Cc: Thomas Moll 
Cc: Matt Porter 
Cc: Li Yang 
Cc: Kumar Gala 
Cc: Micha Nelissen 
---
 drivers/rapidio/rio-scan.c |   36 +---
 include/linux/rio.h|4 +++-
 include/linux/rio_regs.h   |2 ++
 3 files changed, 14 insertions(+), 28 deletions(-)

diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c
index 1123be8..d09c359 100644
--- a/drivers/rapidio/rio-scan.c
+++ b/drivers/rapidio/rio-scan.c
@@ -420,6 +420,11 @@ static struct rio_dev __devinit *rio_setup_device(struct 
rio_net *net,
hopcount, RIO_EFB_ERR_MGMNT);
}
 
+   if (rdev->pef & (RIO_PEF_SWITCH | RIO_PEF_MULTIPORT)) {
+   rio_mport_read_config_32(port, destid, hopcount,
+RIO_SWP_INFO_CAR, &rdev->swpinfo);
+   }
+
rio_mport_read_config_32(port, destid, hopcount, RIO_SRC_OPS_CAR,
 &rdev->src_ops);
rio_mport_read_config_32(port, destid, hopcount, RIO_DST_OPS_CAR,
@@ -439,8 +444,6 @@ static struct rio_dev __devinit *rio_setup_device(struct 
rio_net *net,
 
/* If a PE has both switch and other functions, show it as a switch */
if (rio_is_switch(rdev)) {
-   rio_mport_read_config_32(port, destid, hopcount,
-RIO_SWP_INFO_CAR, &rdev->swpinfo);
rswitch = kzalloc(sizeof(struct rio_switch), GFP_KERNEL);
if (!rswitch)
goto cleanup;
@@ -458,6 +461,7 @@ static struct rio_dev __devinit *rio_setup_device(struct 
rio_net *net,
rdid++)
rswitch->route_table[rdid] = RIO_INVALID_ROUTE;
rdev->rswitch = rswitch;
+   rswitch->rdev = rdev;
dev_set_name(&rdev->dev, "%02x:s:%04x", rdev->net->id,
 rdev->rswitch->switchid);
rio_switch_init(rdev, do_enum);
@@ -719,25 +723,6 @@ static u16 rio_get_host_deviceid_lock(struct rio_mport 
*port, u8 hopcount)
 }
 
 /**
- * rio_get_swpinfo_inport- Gets the ingress port number
- * @mport: Master port to send transaction
- * @destid: Destination ID associated with the switch
- * @hopcount: Number of hops to the device
- *
- * Returns port number being used to access the switch device.
- */
-static u8
-rio_get_swpinfo_inport(struct rio_mport *mport, u16 destid, u8 hopcount)
-{
-   u32 result;
-
-   rio_mport_read_config_32(mport, destid, hopcount, RIO_SWP_INFO_CAR,
-&result);
-
-   return (u8) (result & 0xff);
-}
-
-/**
  * rio_get_swpinfo_tports- Gets total number of ports on the switch
  * @mport: Master port to send transaction
  * @destid: Destination ID associated with the switch
@@ -834,8 +819,7 @@ static int __devinit rio_enum_peer(struct rio_net *net, 
struct rio_mport *port,
 
if (rio_is_switch(rdev)) {
next_switchid++;
-   sw_inport = rio_get_swpinfo_inport(port,
-   RIO_ANY_DESTID(port->sys_size), hopcount);
+   sw_inport = RIO_GET_PORT_NUM(rdev->swpinfo);
rio_route_add_entry(port, rdev->rswitch, RIO_GLOBAL_TABLE,
port->host_deviceid, sw_inport, 0);
rdev->rswitch->route_table[port->host_deviceid] = sw_inport;
@@ -989,8 +973,7 @@ rio_disc_peer(struct rio_net *net, struct rio_mport *port, 
u16 destid,
"RIO: found %s (vid %4.4x did %4.4x) with %d ports\n",
rio_name(rdev), rdev->vid, rdev->did, num_ports);
for (port_num = 0; port_num < num_ports; port_num++) {
-   if (rio_get_swpinfo_inport(port, destid, hopcount) ==
-   port_num)
+   if (RIO_GET_PORT_NUM(rdev->swpinfo) == port_num)
continue;
 
if (rio_sport_is_active
@@ -1109,8 +1092,7 @@ static void rio_update_route_tables(struct rio_mport 
*port)
if (rswitch->destid == destid)
continue;
 
-   sport = rio_get_swpinfo_inport(port,
-   rswitch->destid, 
rswitch->hopcount);
+   sport = 
RIO_GET_PORT_NUM(rswitch->rdev->swpinfo);
 
if (rswitch->add_entry) {
rio_route_add_entry(port, rswitch,
diff --git a/include/linux/rio.h b/include/linux/rio.h
index 84c9f8c..ffdfe5a 100644
--- a/inc

[PATCH v2 07/10] RapidIO: Add handling of orphan port-write message

2010-09-14 Thread Alexandre Bounine
Add check for access to port-write (PW) message source device before processing
the PW message. If source RIO device is not available (power down or RIO link
failure) trace back to a last available switch/port on the PW message route
and service failure at that point.

Signed-off-by: Alexandre Bounine 
Cc: Thomas Moll 
Cc: Matt Porter 
Cc: Li Yang 
Cc: Kumar Gala 
Cc: Micha Nelissen 
---
 drivers/rapidio/rio.c |  113 ++--
 drivers/rapidio/rio.h |2 +
 2 files changed, 110 insertions(+), 5 deletions(-)

diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c
index 77bd416..aefc2a0 100644
--- a/drivers/rapidio/rio.c
+++ b/drivers/rapidio/rio.c
@@ -495,6 +495,92 @@ int rio_set_port_lockout(struct rio_dev *rdev, u32 pnum, 
int lock)
 }
 
 /**
+ * rio_chk_dev_route - Validate route to the specified device.
+ * @rdev:  RIO device failed to respond
+ * @nrdev: Last active device on the route to rdev
+ * @npnum: nrdev's port number on the route to rdev
+ *
+ * Follows a route to the specified RIO device to determine the last available
+ * device (and corresponding RIO port) on the route.
+ */
+static int
+rio_chk_dev_route(struct rio_dev *rdev, struct rio_dev **nrdev, int *npnum)
+{
+   u32 result;
+   int p_port, rc = -EIO;
+   struct rio_dev *prev = NULL;
+
+   /* Find switch with failed RIO link */
+   while (rdev->prev && (rdev->prev->pef & RIO_PEF_SWITCH)) {
+   if (!rio_read_config_32(rdev->prev, RIO_DEV_ID_CAR, &result)) {
+   prev = rdev->prev;
+   break;
+   }
+   rdev = rdev->prev;
+   }
+
+   if (prev == NULL)
+   goto err_out;
+
+   /* Find port with failed RIO link */
+   for (p_port = 0;
+p_port < RIO_GET_TOTAL_PORTS(prev->swpinfo); p_port++)
+   if (prev->rswitch->nextdev[p_port] == rdev)
+   break;
+
+   if (p_port < RIO_GET_TOTAL_PORTS(prev->swpinfo)) {
+   pr_debug("RIO: link failed on [%s]-P%d\n",
+rio_name(prev), p_port);
+   *nrdev = prev;
+   *npnum = p_port;
+   rc = 0;
+   } else
+   pr_debug("RIO: failed to trace route to %s\n", rio_name(prev));
+err_out:
+   return rc;
+}
+
+/**
+ * rio_mport_chk_dev_access - Validate access to the specified device.
+ * @mport: Master port to send transactions
+ * @destid: Device destination ID in network
+ * @hopcount: Number of hops into the network
+ */
+static int
+rio_mport_chk_dev_access(struct rio_mport *mport, u16 destid, u8 hopcount)
+{
+   int i = 0;
+   u32 tmp;
+
+   while (rio_mport_read_config_32(mport, destid, hopcount,
+   RIO_DEV_ID_CAR, &tmp)) {
+   i++;
+   if (i == RIO_MAX_CHK_RETRY)
+   return -EIO;
+   mdelay(1);
+   }
+
+   return 0;
+}
+
+/**
+ * rio_chk_dev_access - Validate access to the specified device.
+ * @rdev: Pointer to RIO device control structure
+ */
+static int rio_chk_dev_access(struct rio_dev *rdev)
+{
+   u8 hopcount = 0xff;
+   u16 destid = rdev->destid;
+
+   if (rdev->rswitch) {
+   destid = rdev->rswitch->destid;
+   hopcount = rdev->rswitch->hopcount;
+   }
+
+   return rio_mport_chk_dev_access(rdev->net->hport, destid, hopcount);
+}
+
+/**
  * rio_get_input_status - Sends a Link-Request/Input-Status control symbol and
  *returns link-response (if requested).
  * @rdev: RIO devive to issue Input-status command
@@ -654,8 +740,8 @@ int rio_inb_pwrite_handler(union rio_pw_msg *pw_msg)
 
rdev = rio_get_comptag(pw_msg->em.comptag, NULL);
if (rdev == NULL) {
-   /* Someting bad here (probably enumeration error) */
-   pr_err("RIO: %s No matching device for CTag 0x%08x\n",
+   /* Device removed or enumeration error */
+   pr_debug("RIO: %s No matching device for CTag 0x%08x\n",
__func__, pw_msg->em.comptag);
return -EIO;
}
@@ -686,6 +772,26 @@ int rio_inb_pwrite_handler(union rio_pw_msg *pw_msg)
return 0;
}
 
+   portnum = pw_msg->em.is_port & 0xFF;
+
+   /* Check if device and route to it are functional:
+* Sometimes devices may send PW message(s) just before being
+* powered down (or link being lost).
+*/
+   if (rio_chk_dev_access(rdev)) {
+   pr_debug("RIO: device access failed - get link partner\n");
+   /* Scan route to the device and identify failed link.
+* This will replace device and port reported in PW message.
+* PW message should not be u

[PATCH v2 02/10] RapidIO:powerpc/85xx: Modify RIO port-write interrupt handler

2010-09-14 Thread Alexandre Bounine
- Rearranged RIO port-write interrupt handling to perform message buffering
as soon as possible.
- Modified to disable port-write controller when clearing Transaction Error (TE)
bit.

Signed-off-by: Alexandre Bounine 
Cc: Thomas Moll 
Cc: Matt Porter 
Cc: Li Yang 
Cc: Kumar Gala 
Cc: Micha Nelissen 
---
 arch/powerpc/sysdev/fsl_rio.c |   68 +++-
 1 files changed, 39 insertions(+), 29 deletions(-)

diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c
index 3017532..551e8e2 100644
--- a/arch/powerpc/sysdev/fsl_rio.c
+++ b/arch/powerpc/sysdev/fsl_rio.c
@@ -87,6 +87,9 @@
 #define RIO_IPWSR_PWD  0x0008
 #define RIO_IPWSR_PWB  0x0004
 
+#define RIO_EPWISR_PINT0x8000
+#define RIO_EPWISR_PW  0x0001
+
 #define RIO_MSG_DESC_SIZE  32
 #define RIO_MSG_BUFFER_SIZE4096
 #define RIO_MIN_TX_RING_SIZE   2
@@ -1067,18 +1070,12 @@ fsl_rio_port_write_handler(int irq, void *dev_instance)
struct rio_priv *priv = port->priv;
u32 epwisr, tmp;
 
-   ipwmr = in_be32(&priv->msg_regs->pwmr);
-   ipwsr = in_be32(&priv->msg_regs->pwsr);
-
epwisr = in_be32(priv->regs_win + RIO_EPWISR);
-   if (epwisr & 0x8000) {
-   tmp = in_be32(priv->regs_win + RIO_LTLEDCSR);
-   pr_info("RIO_LTLEDCSR = 0x%x\n", tmp);
-   out_be32(priv->regs_win + RIO_LTLEDCSR, 0);
-   }
+   if (!(epwisr & RIO_EPWISR_PW))
+   goto pw_done;
 
-   if (!(epwisr & 0x0001))
-   return IRQ_HANDLED;
+   ipwmr = in_be32(&priv->msg_regs->pwmr);
+   ipwsr = in_be32(&priv->msg_regs->pwsr);
 
 #ifdef DEBUG_PW
pr_debug("PW Int->IPWMR: 0x%08x IPWSR: 0x%08x (", ipwmr, ipwsr);
@@ -1094,20 +1091,6 @@ fsl_rio_port_write_handler(int irq, void *dev_instance)
pr_debug(" PWB");
pr_debug(" )\n");
 #endif
-   out_be32(&priv->msg_regs->pwsr,
-ipwsr & (RIO_IPWSR_TE | RIO_IPWSR_QFI | RIO_IPWSR_PWD));
-
-   if ((ipwmr & RIO_IPWMR_EIE) && (ipwsr & RIO_IPWSR_TE)) {
-   priv->port_write_msg.err_count++;
-   pr_info("RIO: Port-Write Transaction Err (%d)\n",
-priv->port_write_msg.err_count);
-   }
-   if (ipwsr & RIO_IPWSR_PWD) {
-   priv->port_write_msg.discard_count++;
-   pr_info("RIO: Port Discarded Port-Write Msg(s) (%d)\n",
-priv->port_write_msg.discard_count);
-   }
-
/* Schedule deferred processing if PW was received */
if (ipwsr & RIO_IPWSR_QFI) {
/* Save PW message (if there is room in FIFO),
@@ -1119,16 +1102,43 @@ fsl_rio_port_write_handler(int irq, void *dev_instance)
 RIO_PW_MSG_SIZE);
} else {
priv->port_write_msg.discard_count++;
-   pr_info("RIO: ISR Discarded Port-Write Msg(s) (%d)\n",
+   pr_debug("RIO: ISR Discarded Port-Write Msg(s) (%d)\n",
 priv->port_write_msg.discard_count);
}
+   /* Clear interrupt and issue Clear Queue command. This allows
+* another port-write to be received.
+*/
+   out_be32(&priv->msg_regs->pwsr, RIO_IPWSR_QFI);
+   out_be32(&priv->msg_regs->pwmr, ipwmr | RIO_IPWMR_CQ);
+
schedule_work(&priv->pw_work);
}
 
-   /* Issue Clear Queue command. This allows another
-* port-write to be received.
-*/
-   out_be32(&priv->msg_regs->pwmr, ipwmr | RIO_IPWMR_CQ);
+   if ((ipwmr & RIO_IPWMR_EIE) && (ipwsr & RIO_IPWSR_TE)) {
+   priv->port_write_msg.err_count++;
+   pr_debug("RIO: Port-Write Transaction Err (%d)\n",
+priv->port_write_msg.err_count);
+   /* Clear Transaction Error: port-write controller should be
+* disabled when clearing this error
+*/
+   out_be32(&priv->msg_regs->pwmr, ipwmr & ~RIO_IPWMR_PWE);
+   out_be32(&priv->msg_regs->pwsr, RIO_IPWSR_TE);
+   out_be32(&priv->msg_regs->pwmr, ipwmr);
+   }
+
+   if (ipwsr & RIO_IPWSR_PWD) {
+   priv->port_write_msg.discard_count++;
+   pr_debug("RIO: Port Discarded Port-Write Msg(s) (%d)\n",
+priv->port_write_msg.discard_count);
+   out_be32(&priv->msg_regs->pwsr, RIO_IPWSR_PWD);
+   }
+
+pw_done:
+   if (epwisr & RIO_EPWISR_PINT) {
+   tmp = in_be32(p

[PATCH v2 06/10] RapidIO: Modify sysfs initialization for switches

2010-09-14 Thread Alexandre Bounine
1. Change to create attribute "routes" only for switches.
2. Add a switch-specific callback to create/remove proprietary attributes.

Signed-off-by: Alexandre Bounine 
Cc: Thomas Moll 
Cc: Matt Porter 
Cc: Li Yang 
Cc: Kumar Gala 
Cc: Micha Nelissen 
---
 drivers/rapidio/rio-sysfs.c |   26 +++---
 include/linux/rio.h |6 ++
 2 files changed, 25 insertions(+), 7 deletions(-)

diff --git a/drivers/rapidio/rio-sysfs.c b/drivers/rapidio/rio-sysfs.c
index 00b4756..137ed93 100644
--- a/drivers/rapidio/rio-sysfs.c
+++ b/drivers/rapidio/rio-sysfs.c
@@ -40,9 +40,6 @@ static ssize_t routes_show(struct device *dev, struct 
device_attribute *attr, ch
char *str = buf;
int i;
 
-   if (!rdev->rswitch)
-   goto out;
-
for (i = 0; i < RIO_MAX_ROUTE_ENTRIES(rdev->net->hport->sys_size);
i++) {
if (rdev->rswitch->route_table[i] == RIO_INVALID_ROUTE)
@@ -52,7 +49,6 @@ static ssize_t routes_show(struct device *dev, struct 
device_attribute *attr, ch
rdev->rswitch->route_table[i]);
}
 
-  out:
return (str - buf);
 }
 
@@ -63,10 +59,11 @@ struct device_attribute rio_dev_attrs[] = {
__ATTR_RO(asm_did),
__ATTR_RO(asm_vid),
__ATTR_RO(asm_rev),
-   __ATTR_RO(routes),
__ATTR_NULL,
 };
 
+static DEVICE_ATTR(routes, S_IRUGO, routes_show, NULL);
+
 static ssize_t
 rio_read_config(struct file *filp, struct kobject *kobj,
struct bin_attribute *bin_attr,
@@ -218,7 +215,17 @@ int rio_create_sysfs_dev_files(struct rio_dev *rdev)
 {
int err = 0;
 
-   err = sysfs_create_bin_file(&rdev->dev.kobj, &rio_config_attr);
+   err = device_create_bin_file(&rdev->dev, &rio_config_attr);
+
+   if (!err && rdev->rswitch) {
+   err = device_create_file(&rdev->dev, &dev_attr_routes);
+   if (!err && rdev->rswitch->sw_sysfs)
+   err = rdev->rswitch->sw_sysfs(rdev, 
RIO_SW_SYSFS_CREATE);
+   }
+
+   if (err)
+   pr_warning("RIO: Failed to create attribute file(s) for %s\n",
+  rio_name(rdev));
 
return err;
 }
@@ -231,5 +238,10 @@ int rio_create_sysfs_dev_files(struct rio_dev *rdev)
  */
 void rio_remove_sysfs_dev_files(struct rio_dev *rdev)
 {
-   sysfs_remove_bin_file(&rdev->dev.kobj, &rio_config_attr);
+   device_remove_bin_file(&rdev->dev, &rio_config_attr);
+   if (rdev->rswitch) {
+   device_remove_file(&rdev->dev, &dev_attr_routes);
+   if (rdev->rswitch->sw_sysfs)
+   rdev->rswitch->sw_sysfs(rdev, RIO_SW_SYSFS_REMOVE);
+   }
 }
diff --git a/include/linux/rio.h b/include/linux/rio.h
index 8d9e66d..4fa5e3d 100644
--- a/include/linux/rio.h
+++ b/include/linux/rio.h
@@ -218,6 +218,10 @@ struct rio_net {
unsigned char id;   /* RIO network ID */
 };
 
+/* Definitions used by switch sysfs initialization callback */
+#define RIO_SW_SYSFS_CREATE1   /* Create switch attributes */
+#define RIO_SW_SYSFS_REMOVE0   /* Remove switch attributes */
+
 /**
  * struct rio_switch - RIO switch info
  * @node: Node in global list of switches
@@ -234,6 +238,7 @@ struct rio_net {
  * @get_domain: Callback for switch-specific domain get function
  * @em_init: Callback for switch-specific error management initialization 
function
  * @em_handle: Callback for switch-specific error management handler function
+ * @sw_sysfs: Callback that initializes switch-specific sysfs attributes
  * @nextdev: Array of per-port pointers to the next attached device
  */
 struct rio_switch {
@@ -256,6 +261,7 @@ struct rio_switch {
   u8 *sw_domain);
int (*em_init) (struct rio_dev *dev);
int (*em_handle) (struct rio_dev *dev, u8 swport);
+   int (*sw_sysfs) (struct rio_dev *dev, int create);
struct rio_dev *nextdev[0];
 };
 
-- 
1.7.0.5

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH v2 08/10] RapidIO: Add device access check into the enumeration

2010-09-14 Thread Alexandre Bounine
Add explicit device access check before performing device enumeration.
This gives a chance to clear possible link error conditions by issuing safe
maintenance read request(s).

Signed-off-by: Alexandre Bounine 
Cc: Thomas Moll 
Cc: Matt Porter 
Cc: Li Yang 
Cc: Kumar Gala 
Cc: Micha Nelissen 
---
 drivers/rapidio/rio-scan.c |6 ++
 drivers/rapidio/rio.c  |2 +-
 drivers/rapidio/rio.h  |2 ++
 3 files changed, 9 insertions(+), 1 deletions(-)

diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c
index d2ea018..e3efdf9 100644
--- a/drivers/rapidio/rio-scan.c
+++ b/drivers/rapidio/rio-scan.c
@@ -762,6 +762,12 @@ static int __devinit rio_enum_peer(struct rio_net *net, 
struct rio_mport *port,
u16 destid;
int tmp;
 
+   if (rio_mport_chk_dev_access(port,
+   RIO_ANY_DESTID(port->sys_size), hopcount)) {
+   pr_debug("RIO: device access check failed\n");
+   return -1;
+   }
+
if (rio_get_host_deviceid_lock(port, hopcount) == port->host_deviceid) {
pr_debug("RIO: PE already discovered by this host\n");
/*
diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c
index aefc2a0..fa5e3cb 100644
--- a/drivers/rapidio/rio.c
+++ b/drivers/rapidio/rio.c
@@ -546,7 +546,7 @@ err_out:
  * @destid: Device destination ID in network
  * @hopcount: Number of hops into the network
  */
-static int
+int
 rio_mport_chk_dev_access(struct rio_mport *mport, u16 destid, u8 hopcount)
 {
int i = 0;
diff --git a/drivers/rapidio/rio.h b/drivers/rapidio/rio.h
index bc71ba1..d249a12 100644
--- a/drivers/rapidio/rio.h
+++ b/drivers/rapidio/rio.h
@@ -24,6 +24,8 @@ extern u32 rio_mport_get_physefb(struct rio_mport *port, int 
local,
 u16 destid, u8 hopcount);
 extern u32 rio_mport_get_efb(struct rio_mport *port, int local, u16 destid,
 u8 hopcount, u32 from);
+extern int rio_mport_chk_dev_access(struct rio_mport *mport, u16 destid,
+   u8 hopcount);
 extern int rio_create_sysfs_dev_files(struct rio_dev *rdev);
 extern int rio_enum_mport(struct rio_mport *mport);
 extern int rio_disc_mport(struct rio_mport *mport);
-- 
1.7.0.5

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH v2 01/10] RapidIO: Fix RapidIO sysfs hierarchy

2010-09-14 Thread Alexandre Bounine
Make RapidIO devices appear in /sys/devices/rapidio directory instead of top
of /sys/devices directory.

Signed-off-by: Alexandre Bounine 
Cc: Thomas Moll 
Cc: Matt Porter 
Cc: Li Yang 
Cc: Kumar Gala 
Cc: Micha Nelissen 
---
 drivers/rapidio/rio-driver.c |2 +-
 drivers/rapidio/rio-scan.c   |1 +
 include/linux/rio.h  |1 +
 3 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/drivers/rapidio/rio-driver.c b/drivers/rapidio/rio-driver.c
index 3222fa3..0f4a53b 100644
--- a/drivers/rapidio/rio-driver.c
+++ b/drivers/rapidio/rio-driver.c
@@ -192,7 +192,7 @@ static int rio_match_bus(struct device *dev, struct 
device_driver *drv)
   out:return 0;
 }
 
-static struct device rio_bus = {
+struct device rio_bus = {
.init_name = "rapidio",
 };
 
diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c
index 8070e07..1123be8 100644
--- a/drivers/rapidio/rio-scan.c
+++ b/drivers/rapidio/rio-scan.c
@@ -478,6 +478,7 @@ static struct rio_dev __devinit *rio_setup_device(struct 
rio_net *net,
}
 
rdev->dev.bus = &rio_bus_type;
+   rdev->dev.parent = &rio_bus;
 
device_initialize(&rdev->dev);
rdev->dev.release = rio_release_dev;
diff --git a/include/linux/rio.h b/include/linux/rio.h
index bd6eb0e..84c9f8c 100644
--- a/include/linux/rio.h
+++ b/include/linux/rio.h
@@ -67,6 +67,7 @@
 #define RIO_PW_MSG_SIZE64
 
 extern struct bus_type rio_bus_type;
+extern struct device rio_bus;
 extern struct list_head rio_devices;   /* list of all devices */
 
 struct rio_mport;
-- 
1.7.0.5

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH v2 0/10] RapidIO: Set of patches to add Gen2 switches

2010-09-14 Thread Alexandre Bounine
This set of RapidIO patches extends support for standard error recovery
mechanism and adds new IDT Gen2 sRIO switch devices - CPS-1848 and CPS-1616.
Implementation of the standard error-stopped state recovery mechanism (as
defined by the RapidIO specification) is required for the new switches.

The version 2 of this set of patches addresses received comments and fixes
an error notification setup issue found in the idt_gen2.c after the first
version was released.
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH 9/9] RapidIO: Add support for IDT CPS Gen2 switches

2010-08-13 Thread Alexandre Bounine
Add the RIO switch driver and definitions for IDT CPS-1848 and CPS-1616 Gen2
devices.

Signed-off-by: Alexandre Bounine 
Reviewed-by: Thomas Moll 
Cc: Matt Porter 
Cc: Li Yang 
Cc: Kumar Gala 
---
 drivers/rapidio/switches/Kconfig|7 +
 drivers/rapidio/switches/Makefile   |1 +
 drivers/rapidio/switches/idt_gen2.c |  439 +++
 include/linux/rio_ids.h |2 +
 include/linux/rio_regs.h|4 +
 5 files changed, 453 insertions(+), 0 deletions(-)
 create mode 100644 drivers/rapidio/switches/idt_gen2.c

diff --git a/drivers/rapidio/switches/Kconfig b/drivers/rapidio/switches/Kconfig
index 2b4e9b2..f47fee5 100644
--- a/drivers/rapidio/switches/Kconfig
+++ b/drivers/rapidio/switches/Kconfig
@@ -20,6 +20,13 @@ config RAPIDIO_TSI568
---help---
  Includes support for IDT Tsi568 serial RapidIO switch.
 
+config RAPIDIO_CPS_GEN2
+   bool "IDT CPS Gen.2 SRIO switch support"
+   depends on RAPIDIO
+   default n
+   ---help---
+ Includes support for ITD CPS Gen.2 serial RapidIO switches.
+
 config RAPIDIO_TSI500
bool "Tsi500 Parallel RapidIO switch support"
depends on RAPIDIO
diff --git a/drivers/rapidio/switches/Makefile 
b/drivers/rapidio/switches/Makefile
index fe4adc3..48d67a6 100644
--- a/drivers/rapidio/switches/Makefile
+++ b/drivers/rapidio/switches/Makefile
@@ -6,6 +6,7 @@ obj-$(CONFIG_RAPIDIO_TSI57X)+= tsi57x.o
 obj-$(CONFIG_RAPIDIO_CPS_XX)   += idtcps.o
 obj-$(CONFIG_RAPIDIO_TSI568)   += tsi568.o
 obj-$(CONFIG_RAPIDIO_TSI500)   += tsi500.o
+obj-$(CONFIG_RAPIDIO_CPS_GEN2) += idt_gen2.o
 
 ifeq ($(CONFIG_RAPIDIO_DEBUG),y)
 EXTRA_CFLAGS += -DDEBUG
diff --git a/drivers/rapidio/switches/idt_gen2.c 
b/drivers/rapidio/switches/idt_gen2.c
new file mode 100644
index 000..0de4a9c
--- /dev/null
+++ b/drivers/rapidio/switches/idt_gen2.c
@@ -0,0 +1,439 @@
+/*
+ * IDT CPS Gen.2 Serial RapidIO switch family support
+ *
+ * Copyright 2010 Integrated Device Technology, Inc.
+ * Alexandre Bounine 
+ *
+ * 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 
+#include 
+#include 
+#include 
+#include "../rio.h"
+
+#define LOCAL_RTE_CONF_DESTID_SEL  0x010070
+#define LOCAL_RTE_CONF_DESTID_SEL_PSEL 0x001f
+
+#define IDT_LT_ERR_REPORT_EN   0x03100c
+
+#define IDT_PORT_ERR_REPORT_EN(n)  (0x031044 + (n)*0x40)
+#define IDT_PORT_ERR_REPORT_EN_BC  0x03ff04
+
+#define IDT_PORT_ISERR_REPORT_EN(n)(0x03104C + (n)*0x40)
+#define IDT_PORT_ISERR_REPORT_EN_BC0x03ff0c
+#define IDT_PORT_INIT_TX_ACQUIRED  0x0020
+
+#define IDT_LANE_ERR_REPORT_EN(n)  (0x038010 + (n)*0x100)
+#define IDT_LANE_ERR_REPORT_EN_BC  0x03ff10
+
+#define IDT_DEV_CTRL_1 0xf2000c
+#define IDT_DEV_CTRL_1_GENPW   0x0200
+#define IDT_DEV_CTRL_1_PRSTBEH 0x0001
+
+#define IDT_CFGBLK_ERR_CAPTURE_EN  0x020008
+#define IDT_CFGBLK_ERR_REPORT  0xf20014
+#define IDT_CFGBLK_ERR_REPORT_GENPW0x0002
+
+#define IDT_AUX_PORT_ERR_CAP_EN0x02
+#define IDT_AUX_ERR_REPORT_EN  0xf20018
+#define IDT_AUX_PORT_ERR_LOG_I2C   0x0002
+#define IDT_AUX_PORT_ERR_LOG_JTAG  0x0001
+
+#defineIDT_ISLTL_ADDRESS_CAP   0x021014
+
+#define IDT_RIO_DOMAIN 0xf20020
+#define IDT_RIO_DOMAIN_MASK0x00ff
+
+#define IDT_PW_INFO_CSR0xf20024
+
+#define IDT_SOFT_RESET 0xf20040
+#define IDT_SOFT_RESET_REQ 0x00030097
+
+#define IDT_I2C_MCTRL  0xf20050
+#define IDT_I2C_MCTRL_GENPW0x0400
+
+#define IDT_JTAG_CTRL  0xf2005c
+#define IDT_JTAG_CTRL_GENPW0x0002
+
+#define IDT_LANE_CTRL(n)   (0xff8000 + (n)*0x100)
+#define IDT_LANE_CTRL_BC   0x00
+#define IDT_LANE_CTRL_GENPW0x0020
+#define IDT_LANE_DFE_1_BC  0x18
+#define IDT_LANE_DFE_2_BC  0x1c
+
+#define IDT_PORT_OPS(n)(0xf40004 + (n)*0x100)
+#define IDT_PORT_OPS_GENPW 0x0800
+#define IDT_PORT_OPS_PL_ELOG   0x0040
+#define IDT_PORT_OPS_LL_ELOG   0x0020
+#define IDT_PORT_OPS_LT_ELOG   0x0010
+#define IDT_PORT_OPS_BC0xf4ff04
+
+#define IDT_PORT_ISERR_DET(n)  (0xf40008 + (n)*0x100)
+
+#define IDT_ERR_CAP0xfd
+#define IDT_ERR_CAP_LOG_OVERWR 0x0004
+
+#define IDT_ERR_RD 0xfd0004
+
+#define IDT_DEFAULT_ROUTE  0xde
+#define IDT_NO_ROUTE   0xdf
+
+static int
+idtg2_route_add_entry(struct rio_mport *mport, u16 destid, u8 hopcount,
+  u16 table, u16 route_destid, u8 route_port)
+{
+   /*
+* Select routing table to update
+*/
+   if (table == RIO_GLOBAL_TA

  1   2   >