2008-01-30 10:20:32

by Zhang Wei

[permalink] [raw]
Subject: [PATCH 1/6] Change RIO function mpc85xx_ to fsl_ .

The driver is also fit for Freescale MPC8641 processor.

Signed-off-by: Zhang Wei <[email protected]>
---
arch/powerpc/sysdev/fsl_rio.c | 80 ++++++++++++++++++++--------------------
1 files changed, 40 insertions(+), 40 deletions(-)

diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c
index af2425e..36c4be4 100644
--- a/arch/powerpc/sysdev/fsl_rio.c
+++ b/arch/powerpc/sysdev/fsl_rio.c
@@ -1,5 +1,5 @@
/*
- * MPC85xx RapidIO support
+ * Freescale MPC85xx/MPC86xx RapidIO support
*
* Copyright 2005 MontaVista Software, Inc.
* Matt Porter <[email protected]>
@@ -145,7 +145,7 @@ static struct rio_msg_rx_ring {
} msg_rx_ring;

/**
- * mpc85xx_rio_doorbell_send - Send a MPC85xx doorbell message
+ * fsl_rio_doorbell_send - Send a MPC85xx doorbell message
* @index: ID of RapidIO interface
* @destid: Destination ID of target device
* @data: 16-bit info field of RapidIO doorbell message
@@ -153,9 +153,9 @@ static struct rio_msg_rx_ring {
* Sends a MPC85xx doorbell message. Returns %0 on success or
* %-EINVAL on failure.
*/
-static int mpc85xx_rio_doorbell_send(int index, u16 destid, u16 data)
+static int fsl_rio_doorbell_send(int index, u16 destid, u16 data)
{
- pr_debug("mpc85xx_doorbell_send: index %d destid %4.4x data %4.4x\n",
+ pr_debug("fsl_doorbell_send: index %d destid %4.4x data %4.4x\n",
index, destid, data);
out_be32((void *)&dbell_atmu_regs->rowtar, destid << 22);
out_be16((void *)(dbell_win), data);
@@ -164,7 +164,7 @@ static int mpc85xx_rio_doorbell_send(int index, u16 destid, u16 data)
}

/**
- * mpc85xx_local_config_read - Generate a MPC85xx local config space read
+ * fsl_local_config_read - Generate a MPC85xx local config space read
* @index: ID of RapdiIO interface
* @offset: Offset into configuration space
* @len: Length (in bytes) of the maintenance transaction
@@ -173,9 +173,9 @@ static int mpc85xx_rio_doorbell_send(int index, u16 destid, u16 data)
* Generates a MPC85xx local configuration space read. Returns %0 on
* success or %-EINVAL on failure.
*/
-static int mpc85xx_local_config_read(int index, u32 offset, int len, u32 * data)
+static int fsl_local_config_read(int index, u32 offset, int len, u32 * data)
{
- pr_debug("mpc85xx_local_config_read: index %d offset %8.8x\n", index,
+ pr_debug("fsl_local_config_read: index %d offset %8.8x\n", index,
offset);
*data = in_be32((void *)(regs_win + offset));

@@ -183,7 +183,7 @@ static int mpc85xx_local_config_read(int index, u32 offset, int len, u32 * data)
}

/**
- * mpc85xx_local_config_write - Generate a MPC85xx local config space write
+ * fsl_local_config_write - Generate a MPC85xx local config space write
* @index: ID of RapdiIO interface
* @offset: Offset into configuration space
* @len: Length (in bytes) of the maintenance transaction
@@ -192,10 +192,10 @@ static int mpc85xx_local_config_read(int index, u32 offset, int len, u32 * data)
* Generates a MPC85xx local configuration space write. Returns %0 on
* success or %-EINVAL on failure.
*/
-static int mpc85xx_local_config_write(int index, u32 offset, int len, u32 data)
+static int fsl_local_config_write(int index, u32 offset, int len, u32 data)
{
pr_debug
- ("mpc85xx_local_config_write: index %d offset %8.8x data %8.8x\n",
+ ("fsl_local_config_write: index %d offset %8.8x data %8.8x\n",
index, offset, data);
out_be32((void *)(regs_win + offset), data);

@@ -203,7 +203,7 @@ static int mpc85xx_local_config_write(int index, u32 offset, int len, u32 data)
}

/**
- * mpc85xx_rio_config_read - Generate a MPC85xx read maintenance transaction
+ * fsl_rio_config_read - Generate a MPC85xx read maintenance transaction
* @index: ID of RapdiIO interface
* @destid: Destination ID of transaction
* @hopcount: Number of hops to target device
@@ -215,13 +215,13 @@ static int mpc85xx_local_config_write(int index, u32 offset, int len, u32 data)
* success or %-EINVAL on failure.
*/
static int
-mpc85xx_rio_config_read(int index, u16 destid, u8 hopcount, u32 offset, int len,
+fsl_rio_config_read(int index, u16 destid, u8 hopcount, u32 offset, int len,
u32 * val)
{
u8 *data;

pr_debug
- ("mpc85xx_rio_config_read: index %d destid %d hopcount %d offset %8.8x len %d\n",
+ ("fsl_rio_config_read: index %d destid %d hopcount %d offset %8.8x len %d\n",
index, destid, hopcount, offset, len);
out_be32((void *)&maint_atmu_regs->rowtar,
(destid << 22) | (hopcount << 12) | ((offset & ~0x3) >> 9));
@@ -243,7 +243,7 @@ mpc85xx_rio_config_read(int index, u16 destid, u8 hopcount, u32 offset, int len,
}

/**
- * mpc85xx_rio_config_write - Generate a MPC85xx write maintenance transaction
+ * fsl_rio_config_write - Generate a MPC85xx write maintenance transaction
* @index: ID of RapdiIO interface
* @destid: Destination ID of transaction
* @hopcount: Number of hops to target device
@@ -255,12 +255,12 @@ mpc85xx_rio_config_read(int index, u16 destid, u8 hopcount, u32 offset, int len,
* success or %-EINVAL on failure.
*/
static int
-mpc85xx_rio_config_write(int index, u16 destid, u8 hopcount, u32 offset,
+fsl_rio_config_write(int index, u16 destid, u8 hopcount, u32 offset,
int len, u32 val)
{
u8 *data;
pr_debug
- ("mpc85xx_rio_config_write: index %d destid %d hopcount %d offset %8.8x len %d val %8.8x\n",
+ ("fsl_rio_config_write: index %d destid %d hopcount %d offset %8.8x len %d val %8.8x\n",
index, destid, hopcount, offset, len, val);
out_be32((void *)&maint_atmu_regs->rowtar,
(destid << 22) | (hopcount << 12) | ((offset & ~0x3) >> 9));
@@ -344,7 +344,7 @@ rio_hw_add_outb_message(struct rio_mport *mport, struct rio_dev *rdev, int mbox,
EXPORT_SYMBOL_GPL(rio_hw_add_outb_message);

/**
- * mpc85xx_rio_tx_handler - MPC85xx outbound message interrupt handler
+ * fsl_rio_tx_handler - MPC85xx outbound message interrupt handler
* @irq: Linux interrupt number
* @dev_instance: Pointer to interrupt-specific data
*
@@ -352,7 +352,7 @@ EXPORT_SYMBOL_GPL(rio_hw_add_outb_message);
* mailbox event handler and acks the interrupt occurrence.
*/
static irqreturn_t
-mpc85xx_rio_tx_handler(int irq, void *dev_instance)
+fsl_rio_tx_handler(int irq, void *dev_instance)
{
int osr;
struct rio_mport *port = (struct rio_mport *)dev_instance;
@@ -452,7 +452,7 @@ int rio_open_outb_mbox(struct rio_mport *mport, void *dev_id, int mbox, int entr

/* Hook up outbound message handler */
if ((rc =
- request_irq(MPC85xx_IRQ_RIO_TX, mpc85xx_rio_tx_handler, 0,
+ request_irq(MPC85xx_IRQ_RIO_TX, fsl_rio_tx_handler, 0,
"msg_tx", (void *)mport)) < 0)
goto out_irq;

@@ -511,7 +511,7 @@ void rio_close_outb_mbox(struct rio_mport *mport, int mbox)
}

/**
- * mpc85xx_rio_rx_handler - MPC85xx inbound message interrupt handler
+ * fsl_rio_rx_handler - MPC85xx inbound message interrupt handler
* @irq: Linux interrupt number
* @dev_instance: Pointer to interrupt-specific data
*
@@ -519,7 +519,7 @@ void rio_close_outb_mbox(struct rio_mport *mport, int mbox)
* mailbox event handler and acks the interrupt occurrence.
*/
static irqreturn_t
-mpc85xx_rio_rx_handler(int irq, void *dev_instance)
+fsl_rio_rx_handler(int irq, void *dev_instance)
{
int isr;
struct rio_mport *port = (struct rio_mport *)dev_instance;
@@ -597,7 +597,7 @@ int rio_open_inb_mbox(struct rio_mport *mport, void *dev_id, int mbox, int entri

/* Hook up inbound message handler */
if ((rc =
- request_irq(MPC85xx_IRQ_RIO_RX, mpc85xx_rio_rx_handler, 0,
+ request_irq(MPC85xx_IRQ_RIO_RX, fsl_rio_rx_handler, 0,
"msg_rx", (void *)mport)) < 0) {
dma_free_coherent(NULL, RIO_MSG_BUFFER_SIZE,
msg_tx_ring.virt_buffer[i],
@@ -729,7 +729,7 @@ void *rio_hw_get_inb_message(struct rio_mport *mport, int mbox)
EXPORT_SYMBOL_GPL(rio_hw_get_inb_message);

/**
- * mpc85xx_rio_dbell_handler - MPC85xx doorbell interrupt handler
+ * fsl_rio_dbell_handler - MPC85xx doorbell interrupt handler
* @irq: Linux interrupt number
* @dev_instance: Pointer to interrupt-specific data
*
@@ -737,7 +737,7 @@ EXPORT_SYMBOL_GPL(rio_hw_get_inb_message);
* doorbell event handlers and executes a matching event handler.
*/
static irqreturn_t
-mpc85xx_rio_dbell_handler(int irq, void *dev_instance)
+fsl_rio_dbell_handler(int irq, void *dev_instance)
{
int dsr;
struct rio_mport *port = (struct rio_mport *)dev_instance;
@@ -794,14 +794,14 @@ mpc85xx_rio_dbell_handler(int irq, void *dev_instance)
}

/**
- * mpc85xx_rio_doorbell_init - MPC85xx doorbell interface init
+ * fsl_rio_doorbell_init - MPC85xx doorbell interface init
* @mport: Master port implementing the inbound doorbell unit
*
* Initializes doorbell unit hardware and inbound DMA buffer
- * ring. Called from mpc85xx_rio_setup(). Returns %0 on success
+ * ring. Called from fsl_rio_setup(). Returns %0 on success
* or %-ENOMEM on failure.
*/
-static int mpc85xx_rio_doorbell_init(struct rio_mport *mport)
+static int fsl_rio_doorbell_init(struct rio_mport *mport)
{
int rc = 0;

@@ -835,7 +835,7 @@ static int mpc85xx_rio_doorbell_init(struct rio_mport *mport)

/* Hook up doorbell handler */
if ((rc =
- request_irq(MPC85xx_IRQ_RIO_BELL, mpc85xx_rio_dbell_handler, 0,
+ request_irq(MPC85xx_IRQ_RIO_BELL, fsl_rio_dbell_handler, 0,
"dbell_rx", (void *)mport) < 0)) {
iounmap((void *)dbell_win);
dma_free_coherent(NULL, 512 * DOORBELL_MESSAGE_SIZE,
@@ -854,7 +854,7 @@ static int mpc85xx_rio_doorbell_init(struct rio_mport *mport)

static char *cmdline = NULL;

-static int mpc85xx_rio_get_hdid(int index)
+static int fsl_rio_get_hdid(int index)
{
/* XXX Need to parse multiple entries in some format */
if (!cmdline)
@@ -863,7 +863,7 @@ static int mpc85xx_rio_get_hdid(int index)
return simple_strtol(cmdline, NULL, 0);
}

-static int mpc85xx_rio_get_cmdline(char *s)
+static int fsl_rio_get_cmdline(char *s)
{
if (!s)
return 0;
@@ -872,10 +872,10 @@ static int mpc85xx_rio_get_cmdline(char *s)
return 1;
}

-__setup("riohdid=", mpc85xx_rio_get_cmdline);
+__setup("riohdid=", fsl_rio_get_cmdline);

/**
- * mpc85xx_rio_setup - Setup MPC85xx RapidIO interface
+ * fsl_rio_setup - Setup MPC85xx RapidIO interface
* @law_start: Starting physical address of RapidIO LAW
* @law_size: Size of RapidIO LAW
*
@@ -883,17 +883,17 @@ __setup("riohdid=", mpc85xx_rio_get_cmdline);
* master port with system-specific info, and registers the
* master port with the RapidIO subsystem.
*/
-void mpc85xx_rio_setup(int law_start, int law_size)
+void fsl_rio_setup(int law_start, int law_size)
{
struct rio_ops *ops;
struct rio_mport *port;

ops = kmalloc(sizeof(struct rio_ops), GFP_KERNEL);
- ops->lcread = mpc85xx_local_config_read;
- ops->lcwrite = mpc85xx_local_config_write;
- ops->cread = mpc85xx_rio_config_read;
- ops->cwrite = mpc85xx_rio_config_write;
- ops->dsend = mpc85xx_rio_doorbell_send;
+ ops->lcread = fsl_local_config_read;
+ ops->lcwrite = fsl_local_config_write;
+ ops->cread = fsl_rio_config_read;
+ ops->cwrite = fsl_rio_config_write;
+ ops->dsend = fsl_rio_doorbell_send;

port = kmalloc(sizeof(struct rio_mport), GFP_KERNEL);
port->id = 0;
@@ -909,7 +909,7 @@ void mpc85xx_rio_setup(int law_start, int law_size)
strcpy(port->name, "RIO0 mport");

port->ops = ops;
- port->host_deviceid = mpc85xx_rio_get_hdid(port->id);
+ port->host_deviceid = fsl_rio_get_hdid(port->id);

rio_register_mport(port);

@@ -928,5 +928,5 @@ void mpc85xx_rio_setup(int law_start, int law_size)
/* Configure outbound doorbell window */
out_be32((void *)&dbell_atmu_regs->rowbar, 0x000c0400);
out_be32((void *)&dbell_atmu_regs->rowar, 0x8004200b);
- mpc85xx_rio_doorbell_init(port);
+ fsl_rio_doorbell_init(port);
}
--
1.5.2


2008-01-30 10:20:58

by Zhang Wei

[permalink] [raw]
Subject: [PATCH 2/6] Add RapidIO option to kernel configuration.

Signed-off-by: Zhang Wei <[email protected]>
---
arch/powerpc/Kconfig | 13 +++++++++++++
arch/powerpc/platforms/86xx/Kconfig | 1 +
2 files changed, 14 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 47fe256..ad07964 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -535,6 +535,19 @@ source "drivers/pcmcia/Kconfig"

source "drivers/pci/hotplug/Kconfig"

+config HAS_RAPIDIO
+ bool
+ default n
+
+config RAPIDIO
+ bool "RapidIO support"
+ depends on HAS_RAPIDIO
+ 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 "Advanced setup"
diff --git a/arch/powerpc/platforms/86xx/Kconfig b/arch/powerpc/platforms/86xx/Kconfig
index 21d1135..8c7c5ff 100644
--- a/arch/powerpc/platforms/86xx/Kconfig
+++ b/arch/powerpc/platforms/86xx/Kconfig
@@ -8,6 +8,7 @@ config MPC8641_HPCN
select PPC_I8259
select DEFAULT_UIMAGE
select FSL_ULI1575
+ select HAS_RAPIDIO
help
This option enables support for the MPC8641 HPCN board.

--
1.5.2

2008-01-30 10:21:42

by Zhang Wei

[permalink] [raw]
Subject: [PATCH 6/6] Change the kernel configurated RapidIO system size to auto-probing.

The RapidIO system size will auto probe in RIO setup. The route
table and rionet_active in rionet.c are changed to be allocated
dynamically according the system size.

Signed-off-by: Zhang Wei <[email protected]>
---
arch/powerpc/sysdev/fsl_rio.c | 6 +++++
drivers/net/rionet.c | 16 +++++++++++-
drivers/rapidio/Kconfig | 8 ------
drivers/rapidio/rio-scan.c | 51 +++++++++++++++++++++++++++++------------
drivers/rapidio/rio-sysfs.c | 3 +-
drivers/rapidio/rio.c | 2 +-
drivers/rapidio/rio.h | 9 +-----
include/linux/rio.h | 14 +++++-----
8 files changed, 68 insertions(+), 41 deletions(-)

diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c
index 36b43ec..4877203 100644
--- a/arch/powerpc/sysdev/fsl_rio.c
+++ b/arch/powerpc/sysdev/fsl_rio.c
@@ -1001,6 +1001,12 @@ int fsl_rio_setup(struct of_device *dev)
rio_register_mport(port);

priv->regs_win = (u32) ioremap(regs.start, regs.end - regs.start + 1);
+
+ port->sys_size = (in_be32((priv->regs_win + RIO_PEF_CAR))
+ & RIO_PEF_CTLS) >> 4;
+ dev_info(&dev->dev, "RapidIO Common Transport System size: %d\n",
+ port->sys_size ? 65536 : 256);
+
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/net/rionet.c b/drivers/net/rionet.c
index e7fd08a..f2c103b 100644
--- a/drivers/net/rionet.c
+++ b/drivers/net/rionet.c
@@ -77,7 +77,7 @@ static int rionet_capable = 1;
* could be made into a hash table to save memory depending
* on system trade-offs.
*/
-static struct rio_dev *rionet_active[RIO_MAX_ROUTE_ENTRIES];
+static struct rio_dev **rionet_active;

#define is_rionet_capable(pef, src_ops, dst_ops) \
((pef & RIO_PEF_INB_MBOX) && \
@@ -195,7 +195,8 @@ static int rionet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
}

if (eth->h_dest[0] & 0x01) {
- for (i = 0; i < RIO_MAX_ROUTE_ENTRIES; i++)
+ for (i = 0; i < RIO_MAX_ROUTE_ENTRIES(rnet->mport->syssize);
+ i++)
if (rionet_active[i])
rionet_queue_tx_msg(skb, ndev,
rionet_active[i]);
@@ -385,6 +386,8 @@ static void rionet_remove(struct rio_dev *rdev)
struct net_device *ndev = NULL;
struct rionet_peer *peer, *tmp;

+ free_pages((unsigned long)rionet_active, rdev->net->hport->sys_size ?
+ __ilog2(sizeof(void *)) + 4 : 0);
unregister_netdev(ndev);
kfree(ndev);

@@ -443,6 +446,15 @@ static int rionet_setup_netdev(struct rio_mport *mport)
goto out;
}

+ if (!(rionet_active = (struct rio_dev **)__get_free_pages(GFP_KERNEL,
+ mport->sys_size ? __ilog2(sizeof(void *)) + 4
+ : 0))) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ memset((void *)rionet_active, 0, sizeof(void *) *
+ RIO_MAX_ROUTE_ENTRIES(mport->sys_size));
+
/* Set up private area */
rnet = (struct rionet_private *)ndev->priv;
rnet->mport = mport;
diff --git a/drivers/rapidio/Kconfig b/drivers/rapidio/Kconfig
index 4142115..c32822a 100644
--- a/drivers/rapidio/Kconfig
+++ b/drivers/rapidio/Kconfig
@@ -1,14 +1,6 @@
#
# RapidIO configuration
#
-config RAPIDIO_8_BIT_TRANSPORT
- bool "8-bit transport addressing"
- depends on RAPIDIO
- ---help---
- By default, the kernel assumes a 16-bit addressed RapidIO
- network. By selecting this option, the kernel will support
- an 8-bit addressed network.
-
config RAPIDIO_DISC_TIMEOUT
int "Discovery timeout duration (seconds)"
depends on RAPIDIO
diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c
index 4442072..ca895d1 100644
--- a/drivers/rapidio/rio-scan.c
+++ b/drivers/rapidio/rio-scan.c
@@ -73,7 +73,7 @@ static u16 rio_get_device_id(struct rio_mport *port, u16 destid, u8 hopcount)

rio_mport_read_config_32(port, destid, hopcount, RIO_DID_CSR, &result);

- return RIO_GET_DID(result);
+ return RIO_GET_DID(port->sys_size, result);
}

/**
@@ -88,7 +88,7 @@ static u16 rio_get_device_id(struct rio_mport *port, u16 destid, u8 hopcount)
static void rio_set_device_id(struct rio_mport *port, u16 destid, u8 hopcount, u16 did)
{
rio_mport_write_config_32(port, destid, hopcount, RIO_DID_CSR,
- RIO_SET_DID(did));
+ RIO_SET_DID(port->sys_size, did));
}

/**
@@ -100,7 +100,8 @@ static void rio_set_device_id(struct rio_mport *port, u16 destid, u8 hopcount, u
*/
static void rio_local_set_device_id(struct rio_mport *port, u16 did)
{
- rio_local_write_config_32(port, RIO_DID_CSR, RIO_SET_DID(did));
+ rio_local_write_config_32(port, RIO_DID_CSR, RIO_SET_DID(port->sys_size,
+ did));
}

/**
@@ -350,8 +351,17 @@ static struct rio_dev *rio_setup_device(struct rio_net *net,
rswitch->switchid = next_switchid;
rswitch->hopcount = hopcount;
rswitch->destid = destid;
+ if (!(rswitch->route_table = kzalloc(sizeof(u8)*
+ RIO_MAX_ROUTE_ENTRIES(port->sys_size),
+ GFP_KERNEL))) {
+ kfree(rdev);
+ rdev = NULL;
+ kfree(rswitch);
+ goto out;
+ }
/* Initialize switch route table */
- for (rdid = 0; rdid < RIO_MAX_ROUTE_ENTRIES; rdid++)
+ for (rdid = 0; rdid < RIO_MAX_ROUTE_ENTRIES(port->sys_size);
+ rdid++)
rswitch->route_table[rdid] = RIO_INVALID_ROUTE;
rdev->rswitch = rswitch;
sprintf(rio_name(rdev), "%02x:s:%04x", rdev->net->id,
@@ -480,7 +490,7 @@ static u16 rio_get_host_deviceid_lock(struct rio_mport *port, u8 hopcount)
{
u32 result;

- rio_mport_read_config_32(port, RIO_ANY_DESTID, hopcount,
+ rio_mport_read_config_32(port, RIO_ANY_DESTID(port->sys_size), hopcount,
RIO_HOST_DID_LOCK_CSR, &result);

return (u16) (result & 0xffff);
@@ -571,14 +581,16 @@ static int rio_enum_peer(struct rio_net *net, struct rio_mport *port,
}

/* Attempt to acquire device lock */
- rio_mport_write_config_32(port, RIO_ANY_DESTID, hopcount,
+ rio_mport_write_config_32(port, RIO_ANY_DESTID(port->sys_size),
+ hopcount,
RIO_HOST_DID_LOCK_CSR, port->host_deviceid);
while ((tmp = rio_get_host_deviceid_lock(port, hopcount))
< port->host_deviceid) {
/* Delay a bit */
mdelay(1);
/* Attempt to acquire device lock again */
- rio_mport_write_config_32(port, RIO_ANY_DESTID, hopcount,
+ rio_mport_write_config_32(port, RIO_ANY_DESTID(port->sys_size),
+ hopcount,
RIO_HOST_DID_LOCK_CSR,
port->host_deviceid);
}
@@ -590,7 +602,8 @@ static int rio_enum_peer(struct rio_net *net, struct rio_mport *port,
}

/* Setup new RIO device */
- if ((rdev = rio_setup_device(net, port, RIO_ANY_DESTID, hopcount, 1))) {
+ if ((rdev = rio_setup_device(net, port, RIO_ANY_DESTID(port->sys_size),
+ hopcount, 1))) {
/* Add device to the global and bus/net specific list. */
list_add_tail(&rdev->net_list, &net->devices);
} else
@@ -598,7 +611,8 @@ static int 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, hopcount);
+ sw_inport = rio_get_swpinfo_inport(port,
+ RIO_ANY_DESTID(port->sys_size), hopcount);
rio_route_add_entry(port, rdev->rswitch, RIO_GLOBAL_TABLE,
port->host_deviceid, sw_inport);
rdev->rswitch->route_table[port->host_deviceid] = sw_inport;
@@ -612,7 +626,8 @@ static int rio_enum_peer(struct rio_net *net, struct rio_mport *port,
}

num_ports =
- rio_get_swpinfo_tports(port, RIO_ANY_DESTID, hopcount);
+ 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);
@@ -624,13 +639,15 @@ static int rio_enum_peer(struct rio_net *net, struct rio_mport *port,
cur_destid = next_destid;

if (rio_sport_is_active
- (port, RIO_ANY_DESTID, hopcount, port_num)) {
+ (port, RIO_ANY_DESTID(port->sys_size), hopcount,
+ port_num)) {
pr_debug(
"RIO: scanning device on port %d\n",
port_num);
rio_route_add_entry(port, rdev->rswitch,
RIO_GLOBAL_TABLE,
- RIO_ANY_DESTID, port_num);
+ RIO_ANY_DESTID(port->sys_size),
+ port_num);

if (rio_enum_peer(net, port, hopcount + 1) < 0)
return -1;
@@ -735,7 +752,8 @@ rio_disc_peer(struct rio_net *net, struct rio_mport *port, u16 destid,
pr_debug(
"RIO: scanning device on port %d\n",
port_num);
- for (ndestid = 0; ndestid < RIO_ANY_DESTID;
+ for (ndestid = 0;
+ ndestid < RIO_ANY_DESTID(port->sys_size);
ndestid++) {
rio_route_get_entry(port, rdev->rswitch,
RIO_GLOBAL_TABLE,
@@ -917,7 +935,9 @@ static void rio_build_route_tables(void)

list_for_each_entry(rdev, &rio_devices, global_list)
if (rio_is_switch(rdev))
- for (i = 0; i < RIO_MAX_ROUTE_ENTRIES; i++) {
+ for (i = 0;
+ i < RIO_MAX_ROUTE_ENTRIES(rdev->net->hport->sys_size);
+ i++) {
if (rio_route_get_entry
(rdev->net->hport, rdev->rswitch, RIO_GLOBAL_TABLE,
i, &sport) < 0)
@@ -981,7 +1001,8 @@ int rio_disc_mport(struct rio_mport *mport)
del_timer_sync(&rio_enum_timer);

pr_debug("done\n");
- if (rio_disc_peer(net, mport, RIO_ANY_DESTID, 0) < 0) {
+ if (rio_disc_peer(net, mport, RIO_ANY_DESTID(mport->sys_size),
+ 0) < 0) {
printk(KERN_INFO
"RIO: master port %d device has failed discovery\n",
mport->id);
diff --git a/drivers/rapidio/rio-sysfs.c b/drivers/rapidio/rio-sysfs.c
index 659e311..97a147f 100644
--- a/drivers/rapidio/rio-sysfs.c
+++ b/drivers/rapidio/rio-sysfs.c
@@ -43,7 +43,8 @@ static ssize_t routes_show(struct device *dev, struct device_attribute *attr, ch
if (!rdev->rswitch)
goto out;

- for (i = 0; i < RIO_MAX_ROUTE_ENTRIES; i++) {
+ for (i = 0; i < RIO_MAX_ROUTE_ENTRIES(rdev->net->hport->sys_size);
+ i++) {
if (rdev->rswitch->route_table[i] == RIO_INVALID_ROUTE)
continue;
str +=
diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c
index 80c5f1b..680661a 100644
--- a/drivers/rapidio/rio.c
+++ b/drivers/rapidio/rio.c
@@ -43,7 +43,7 @@ u16 rio_local_get_device_id(struct rio_mport *port)

rio_local_read_config_32(port, RIO_DID_CSR, &result);

- return (RIO_GET_DID(result));
+ return (RIO_GET_DID(port->sys_size, result));
}

/**
diff --git a/drivers/rapidio/rio.h b/drivers/rapidio/rio.h
index b242cee..7a3b62e 100644
--- a/drivers/rapidio/rio.h
+++ b/drivers/rapidio/rio.h
@@ -51,10 +51,5 @@ extern struct rio_route_ops __end_rio_route_ops[];
DECLARE_RIO_ROUTE_SECTION(.rio_route_ops, \
vid, did, add_hook, get_hook)

-#ifdef CONFIG_RAPIDIO_8_BIT_TRANSPORT
-#define RIO_GET_DID(x) ((x & 0x00ff0000) >> 16)
-#define RIO_SET_DID(x) ((x & 0x000000ff) << 16)
-#else
-#define RIO_GET_DID(x) (x & 0xffff)
-#define RIO_SET_DID(x) (x & 0xffff)
-#endif
+#define RIO_GET_DID(size, x) (size ? (x & 0xffff) : ((x & 0x00ff0000) >> 16))
+#define RIO_SET_DID(size, x) (size ? (x & 0xffff) : ((x & 0x000000ff) << 16))
diff --git a/include/linux/rio.h b/include/linux/rio.h
index 9ed78dc..4b0156d 100644
--- a/include/linux/rio.h
+++ b/include/linux/rio.h
@@ -23,7 +23,6 @@
#include <linux/device.h>
#include <linux/rio_regs.h>

-#define RIO_ANY_DESTID 0xff
#define RIO_NO_HOPCOUNT -1
#define RIO_INVALID_DESTID 0xffff

@@ -39,11 +38,8 @@
entry is invalid (no route
exists for the device ID) */

-#ifdef CONFIG_RAPIDIO_8_BIT_TRANSPORT
-#define RIO_MAX_ROUTE_ENTRIES (1 << 8)
-#else
-#define RIO_MAX_ROUTE_ENTRIES (1 << 16)
-#endif
+#define RIO_MAX_ROUTE_ENTRIES(size) (size ? (1 << 16) : (1 << 8))
+#define RIO_ANY_DESTID(size) (size ? 0xffff : 0xff)

#define RIO_MAX_MBOX 4
#define RIO_MAX_MSG_SIZE 0x1000
@@ -178,6 +174,10 @@ struct rio_mport {
unsigned char id; /* port ID, unique among all ports */
unsigned char index; /* port index, unique among all port
interfaces of the same type */
+ unsigned int sys_size; /* RapidIO common transport system size.
+ * 0 - Small size. 256 devices.
+ * 1 - Large size, 65536 devices.
+ */
unsigned char name[40];
void *priv; /* Master port private data */
};
@@ -213,7 +213,7 @@ struct rio_switch {
u16 switchid;
u16 hopcount;
u16 destid;
- u8 route_table[RIO_MAX_ROUTE_ENTRIES];
+ u8 *route_table;
int (*add_entry) (struct rio_mport * mport, u16 destid, u8 hopcount,
u16 table, u16 route_destid, u8 route_port);
int (*get_entry) (struct rio_mport * mport, u16 destid, u8 hopcount,
--
1.5.2

2008-01-30 10:22:01

by Zhang Wei

[permalink] [raw]
Subject: [PATCH 4/6] Add multi mport support.

Change lots of static variable to mport private. And add mport to some
function declaration.

Signed-off-by: Zhang Wei <[email protected]>
---
arch/powerpc/sysdev/fsl_rio.c | 353 +++++++++++++++++++++++------------------
drivers/rapidio/rio-access.c | 10 +-
include/linux/rio.h | 18 ++-
3 files changed, 218 insertions(+), 163 deletions(-)

diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c
index 36c4be4..3907a2c 100644
--- a/arch/powerpc/sysdev/fsl_rio.c
+++ b/arch/powerpc/sysdev/fsl_rio.c
@@ -1,6 +1,9 @@
/*
* Freescale MPC85xx/MPC86xx RapidIO support
*
+ * Copyright (C) 2007, 2008 Freescale Semiconductor, Inc.
+ * Zhang Wei <[email protected]>
+ *
* Copyright 2005 MontaVista Software, Inc.
* Matt Porter <[email protected]>
*
@@ -20,6 +23,11 @@

#include <asm/io.h>

+/* RapidIO definition irq, which read from OF-tree */
+#define IRQ_RIO_BELL(m) (((struct rio_priv *)(m->priv))->bellirq)
+#define IRQ_RIO_TX(m) (((struct rio_priv *)(m->priv))->txirq)
+#define IRQ_RIO_RX(m) (((struct rio_priv *)(m->priv))->rxirq)
+
#define RIO_REGS_BASE (CCSRBAR + 0xc0000)
#define RIO_ATMU_REGS_OFFSET 0x10c00
#define RIO_MSG_REGS_OFFSET 0x11000
@@ -112,20 +120,12 @@ struct rio_tx_desc {
u32 res4;
};

-static u32 regs_win;
-static struct rio_atmu_regs *atmu_regs;
-static struct rio_atmu_regs *maint_atmu_regs;
-static struct rio_atmu_regs *dbell_atmu_regs;
-static u32 dbell_win;
-static u32 maint_win;
-static struct rio_msg_regs *msg_regs;
-
-static struct rio_dbell_ring {
+struct rio_dbell_ring {
void *virt;
dma_addr_t phys;
-} dbell_ring;
+};

-static struct rio_msg_tx_ring {
+struct rio_msg_tx_ring {
void *virt;
dma_addr_t phys;
void *virt_buffer[RIO_MAX_TX_RING_SIZE];
@@ -133,16 +133,32 @@ static struct rio_msg_tx_ring {
int tx_slot;
int size;
void *dev_id;
-} msg_tx_ring;
+};

-static struct rio_msg_rx_ring {
+struct rio_msg_rx_ring {
void *virt;
dma_addr_t phys;
void *virt_buffer[RIO_MAX_RX_RING_SIZE];
int rx_slot;
int size;
void *dev_id;
-} msg_rx_ring;
+};
+
+struct rio_priv {
+ void __iomem *regs_win;
+ struct rio_atmu_regs __iomem *atmu_regs;
+ struct rio_atmu_regs __iomem *maint_atmu_regs;
+ struct rio_atmu_regs __iomem *dbell_atmu_regs;
+ void __iomem *dbell_win;
+ void __iomem *maint_win;
+ struct rio_msg_regs __iomem *msg_regs;
+ struct rio_dbell_ring dbell_ring;
+ struct rio_msg_tx_ring msg_tx_ring;
+ struct rio_msg_rx_ring msg_rx_ring;
+ int bellirq;
+ int txirq;
+ int rxirq;
+};

/**
* fsl_rio_doorbell_send - Send a MPC85xx doorbell message
@@ -153,12 +169,14 @@ static struct rio_msg_rx_ring {
* Sends a MPC85xx doorbell message. Returns %0 on success or
* %-EINVAL on failure.
*/
-static int fsl_rio_doorbell_send(int index, u16 destid, u16 data)
+static int fsl_rio_doorbell_send(struct rio_mport *mport,
+ int index, u16 destid, u16 data)
{
+ struct rio_priv *priv = mport->priv;
pr_debug("fsl_doorbell_send: index %d destid %4.4x data %4.4x\n",
index, destid, data);
- out_be32((void *)&dbell_atmu_regs->rowtar, destid << 22);
- out_be16((void *)(dbell_win), data);
+ out_be32(&priv->dbell_atmu_regs->rowtar, destid << 22);
+ out_be16(priv->dbell_win, data);

return 0;
}
@@ -173,11 +191,13 @@ static int fsl_rio_doorbell_send(int index, u16 destid, u16 data)
* Generates a MPC85xx local configuration space read. Returns %0 on
* success or %-EINVAL on failure.
*/
-static int fsl_local_config_read(int index, u32 offset, int len, u32 * data)
+static int fsl_local_config_read(struct rio_mport *mport,
+ int index, u32 offset, int len, u32 * data)
{
+ struct rio_priv *priv = mport->priv;
pr_debug("fsl_local_config_read: index %d offset %8.8x\n", index,
offset);
- *data = in_be32((void *)(regs_win + offset));
+ *data = in_be32(priv->regs_win + offset);

return 0;
}
@@ -192,12 +212,14 @@ static int fsl_local_config_read(int index, u32 offset, int len, u32 * data)
* Generates a MPC85xx local configuration space write. Returns %0 on
* success or %-EINVAL on failure.
*/
-static int fsl_local_config_write(int index, u32 offset, int len, u32 data)
+static int fsl_local_config_write(struct rio_mport *mport,
+ int index, u32 offset, int len, u32 data)
{
+ struct rio_priv *priv = mport->priv;
pr_debug
("fsl_local_config_write: index %d offset %8.8x data %8.8x\n",
index, offset, data);
- out_be32((void *)(regs_win + offset), data);
+ out_be32(priv->regs_win + offset, data);

return 0;
}
@@ -215,18 +237,19 @@ static int fsl_local_config_write(int index, u32 offset, int len, u32 data)
* success or %-EINVAL on failure.
*/
static int
-fsl_rio_config_read(int index, u16 destid, u8 hopcount, u32 offset, int len,
- u32 * val)
+fsl_rio_config_read(struct rio_mport *mport, int index, u16 destid,
+ u8 hopcount, u32 offset, int len, u32 * val)
{
+ struct rio_priv *priv = mport->priv;
u8 *data;

pr_debug
("fsl_rio_config_read: index %d destid %d hopcount %d offset %8.8x len %d\n",
index, destid, hopcount, offset, len);
- out_be32((void *)&maint_atmu_regs->rowtar,
+ out_be32(&priv->maint_atmu_regs->rowtar,
(destid << 22) | (hopcount << 12) | ((offset & ~0x3) >> 9));

- data = (u8 *) maint_win + offset;
+ data = (u8 *) priv->maint_win + offset;
switch (len) {
case 1:
*val = in_8((u8 *) data);
@@ -255,17 +278,18 @@ fsl_rio_config_read(int index, u16 destid, u8 hopcount, u32 offset, int len,
* success or %-EINVAL on failure.
*/
static int
-fsl_rio_config_write(int index, u16 destid, u8 hopcount, u32 offset,
- int len, u32 val)
+fsl_rio_config_write(struct rio_mport *mport, int index, u16 destid,
+ u8 hopcount, u32 offset, int len, u32 val)
{
+ struct rio_priv *priv = mport->priv;
u8 *data;
pr_debug
("fsl_rio_config_write: index %d destid %d hopcount %d offset %8.8x len %d val %8.8x\n",
index, destid, hopcount, offset, len, val);
- out_be32((void *)&maint_atmu_regs->rowtar,
+ out_be32(&priv->maint_atmu_regs->rowtar,
(destid << 22) | (hopcount << 12) | ((offset & ~0x3) >> 9));

- data = (u8 *) maint_win + offset;
+ data = (u8 *) priv->maint_win + offset;
switch (len) {
case 1:
out_8((u8 *) data, val);
@@ -296,9 +320,10 @@ int
rio_hw_add_outb_message(struct rio_mport *mport, struct rio_dev *rdev, int mbox,
void *buffer, size_t len)
{
+ struct rio_priv *priv = mport->priv;
u32 omr;
- struct rio_tx_desc *desc =
- (struct rio_tx_desc *)msg_tx_ring.virt + msg_tx_ring.tx_slot;
+ struct rio_tx_desc *desc = (struct rio_tx_desc *)priv->msg_tx_ring.virt
+ + priv->msg_tx_ring.tx_slot;
int ret = 0;

pr_debug
@@ -311,11 +336,11 @@ rio_hw_add_outb_message(struct rio_mport *mport, struct rio_dev *rdev, int mbox,
}

/* Copy and clear rest of buffer */
- memcpy(msg_tx_ring.virt_buffer[msg_tx_ring.tx_slot], buffer, len);
+ memcpy(priv->msg_tx_ring.virt_buffer[priv->msg_tx_ring.tx_slot], buffer,
+ len);
if (len < (RIO_MAX_MSG_SIZE - 4))
- memset((void *)((u32) msg_tx_ring.
- virt_buffer[msg_tx_ring.tx_slot] + len), 0,
- RIO_MAX_MSG_SIZE - len);
+ memset(priv->msg_tx_ring.virt_buffer[priv->msg_tx_ring.tx_slot]
+ + len, 0, RIO_MAX_MSG_SIZE - len);

/* Set mbox field for message */
desc->dport = mbox & 0x3;
@@ -327,15 +352,16 @@ rio_hw_add_outb_message(struct rio_mport *mport, struct rio_dev *rdev, int mbox,
desc->dwcnt = is_power_of_2(len) ? len : 1 << get_bitmask_order(len);

/* Set snooping and source buffer address */
- desc->saddr = 0x00000004 | msg_tx_ring.phys_buffer[msg_tx_ring.tx_slot];
+ desc->saddr = 0x00000004
+ | priv->msg_tx_ring.phys_buffer[priv->msg_tx_ring.tx_slot];

/* Increment enqueue pointer */
- omr = in_be32((void *)&msg_regs->omr);
- out_be32((void *)&msg_regs->omr, omr | RIO_MSG_OMR_MUI);
+ omr = in_be32(&priv->msg_regs->omr);
+ out_be32(&priv->msg_regs->omr, omr | RIO_MSG_OMR_MUI);

/* Go to next descriptor */
- if (++msg_tx_ring.tx_slot == msg_tx_ring.size)
- msg_tx_ring.tx_slot = 0;
+ if (++priv->msg_tx_ring.tx_slot == priv->msg_tx_ring.size)
+ priv->msg_tx_ring.tx_slot = 0;

out:
return ret;
@@ -356,28 +382,30 @@ fsl_rio_tx_handler(int irq, void *dev_instance)
{
int osr;
struct rio_mport *port = (struct rio_mport *)dev_instance;
+ struct rio_priv *priv = port->priv;

- osr = in_be32((void *)&msg_regs->osr);
+ osr = in_be32(&priv->msg_regs->osr);

if (osr & RIO_MSG_OSR_TE) {
pr_info("RIO: outbound message transmission error\n");
- out_be32((void *)&msg_regs->osr, RIO_MSG_OSR_TE);
+ out_be32(&priv->msg_regs->osr, RIO_MSG_OSR_TE);
goto out;
}

if (osr & RIO_MSG_OSR_QOI) {
pr_info("RIO: outbound message queue overflow\n");
- out_be32((void *)&msg_regs->osr, RIO_MSG_OSR_QOI);
+ out_be32(&priv->msg_regs->osr, RIO_MSG_OSR_QOI);
goto out;
}

if (osr & RIO_MSG_OSR_EOMI) {
- u32 dqp = in_be32((void *)&msg_regs->odqdpar);
- int slot = (dqp - msg_tx_ring.phys) >> 5;
- port->outb_msg[0].mcback(port, msg_tx_ring.dev_id, -1, slot);
+ u32 dqp = in_be32(&priv->msg_regs->odqdpar);
+ int slot = (dqp - priv->msg_tx_ring.phys) >> 5;
+ port->outb_msg[0].mcback(port, priv->msg_tx_ring.dev_id, -1,
+ slot);

/* Ack the end-of-message interrupt */
- out_be32((void *)&msg_regs->osr, RIO_MSG_OSR_EOMI);
+ out_be32(&priv->msg_regs->osr, RIO_MSG_OSR_EOMI);
}

out:
@@ -398,6 +426,7 @@ fsl_rio_tx_handler(int irq, void *dev_instance)
int rio_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;

if ((entries < RIO_MIN_TX_RING_SIZE) ||
(entries > RIO_MAX_TX_RING_SIZE) || (!is_power_of_2(entries))) {
@@ -406,53 +435,54 @@ int rio_open_outb_mbox(struct rio_mport *mport, void *dev_id, int mbox, int entr
}

/* Initialize shadow copy ring */
- msg_tx_ring.dev_id = dev_id;
- msg_tx_ring.size = entries;
+ priv->msg_tx_ring.dev_id = dev_id;
+ priv->msg_tx_ring.size = entries;

- for (i = 0; i < msg_tx_ring.size; i++) {
+ for (i = 0; i < priv->msg_tx_ring.size; i++) {
if (!
- (msg_tx_ring.virt_buffer[i] =
+ (priv->msg_tx_ring.virt_buffer[i] =
dma_alloc_coherent(NULL, RIO_MSG_BUFFER_SIZE,
- &msg_tx_ring.phys_buffer[i],
+ &priv->msg_tx_ring.phys_buffer[i],
GFP_KERNEL))) {
rc = -ENOMEM;
- for (j = 0; j < msg_tx_ring.size; j++)
- if (msg_tx_ring.virt_buffer[j])
+ for (j = 0; j < priv->msg_tx_ring.size; j++)
+ if (priv->msg_tx_ring.virt_buffer[j])
dma_free_coherent(NULL,
RIO_MSG_BUFFER_SIZE,
- msg_tx_ring.
+ priv->msg_tx_ring.
virt_buffer[j],
- msg_tx_ring.
+ priv->msg_tx_ring.
phys_buffer[j]);
goto out;
}
}

/* Initialize outbound message descriptor ring */
- if (!(msg_tx_ring.virt = dma_alloc_coherent(NULL,
- msg_tx_ring.size *
+ if (!(priv->msg_tx_ring.virt = dma_alloc_coherent(NULL,
+ priv->msg_tx_ring.size *
RIO_MSG_DESC_SIZE,
- &msg_tx_ring.phys,
+ &priv->msg_tx_ring.phys,
GFP_KERNEL))) {
rc = -ENOMEM;
goto out_dma;
}
- memset(msg_tx_ring.virt, 0, msg_tx_ring.size * RIO_MSG_DESC_SIZE);
- msg_tx_ring.tx_slot = 0;
+ memset(priv->msg_tx_ring.virt, 0,
+ priv->msg_tx_ring.size * RIO_MSG_DESC_SIZE);
+ priv->msg_tx_ring.tx_slot = 0;

/* Point dequeue/enqueue pointers at first entry in ring */
- out_be32((void *)&msg_regs->odqdpar, msg_tx_ring.phys);
- out_be32((void *)&msg_regs->odqepar, msg_tx_ring.phys);
+ out_be32(&priv->msg_regs->odqdpar, priv->msg_tx_ring.phys);
+ out_be32(&priv->msg_regs->odqepar, priv->msg_tx_ring.phys);

/* Configure for snooping */
- out_be32((void *)&msg_regs->osar, 0x00000004);
+ out_be32(&priv->msg_regs->osar, 0x00000004);

/* Clear interrupt status */
- out_be32((void *)&msg_regs->osr, 0x000000b3);
+ out_be32(&priv->msg_regs->osr, 0x000000b3);

/* Hook up outbound message handler */
if ((rc =
- request_irq(MPC85xx_IRQ_RIO_TX, fsl_rio_tx_handler, 0,
+ request_irq(IRQ_RIO_TX(mport), fsl_rio_tx_handler, 0,
"msg_tx", (void *)mport)) < 0)
goto out_irq;

@@ -463,28 +493,28 @@ int rio_open_outb_mbox(struct rio_mport *mport, void *dev_id, int mbox, int entr
* Chaining mode
* Disable
*/
- out_be32((void *)&msg_regs->omr, 0x00100220);
+ out_be32(&priv->msg_regs->omr, 0x00100220);

/* Set number of entries */
- out_be32((void *)&msg_regs->omr,
- in_be32((void *)&msg_regs->omr) |
+ out_be32(&priv->msg_regs->omr,
+ in_be32(&priv->msg_regs->omr) |
((get_bitmask_order(entries) - 2) << 12));

/* Now enable the unit */
- out_be32((void *)&msg_regs->omr, in_be32((void *)&msg_regs->omr) | 0x1);
+ out_be32(&priv->msg_regs->omr, in_be32(&priv->msg_regs->omr) | 0x1);

out:
return rc;

out_irq:
- dma_free_coherent(NULL, msg_tx_ring.size * RIO_MSG_DESC_SIZE,
- msg_tx_ring.virt, msg_tx_ring.phys);
+ dma_free_coherent(NULL, priv->msg_tx_ring.size * RIO_MSG_DESC_SIZE,
+ priv->msg_tx_ring.virt, priv->msg_tx_ring.phys);

out_dma:
- for (i = 0; i < msg_tx_ring.size; i++)
+ for (i = 0; i < priv->msg_tx_ring.size; i++)
dma_free_coherent(NULL, RIO_MSG_BUFFER_SIZE,
- msg_tx_ring.virt_buffer[i],
- msg_tx_ring.phys_buffer[i]);
+ priv->msg_tx_ring.virt_buffer[i],
+ priv->msg_tx_ring.phys_buffer[i]);

return rc;
}
@@ -499,15 +529,16 @@ int rio_open_outb_mbox(struct rio_mport *mport, void *dev_id, int mbox, int entr
*/
void rio_close_outb_mbox(struct rio_mport *mport, int mbox)
{
+ struct rio_priv *priv = mport->priv;
/* Disable inbound message unit */
- out_be32((void *)&msg_regs->omr, 0);
+ out_be32(&priv->msg_regs->omr, 0);

/* Free ring */
- dma_free_coherent(NULL, msg_tx_ring.size * RIO_MSG_DESC_SIZE,
- msg_tx_ring.virt, msg_tx_ring.phys);
+ dma_free_coherent(NULL, priv->msg_tx_ring.size * RIO_MSG_DESC_SIZE,
+ priv->msg_tx_ring.virt, priv->msg_tx_ring.phys);

/* Free interrupt */
- free_irq(MPC85xx_IRQ_RIO_TX, (void *)mport);
+ free_irq(IRQ_RIO_TX(mport), (void *)mport);
}

/**
@@ -523,12 +554,13 @@ fsl_rio_rx_handler(int irq, void *dev_instance)
{
int isr;
struct rio_mport *port = (struct rio_mport *)dev_instance;
+ struct rio_priv *priv = port->priv;

- isr = in_be32((void *)&msg_regs->isr);
+ isr = in_be32(&priv->msg_regs->isr);

if (isr & RIO_MSG_ISR_TE) {
pr_info("RIO: inbound message reception error\n");
- out_be32((void *)&msg_regs->isr, RIO_MSG_ISR_TE);
+ out_be32((void *)&priv->msg_regs->isr, RIO_MSG_ISR_TE);
goto out;
}

@@ -540,10 +572,10 @@ fsl_rio_rx_handler(int irq, void *dev_instance)
* make the callback with an unknown/invalid mailbox number
* argument.
*/
- port->inb_msg[0].mcback(port, msg_rx_ring.dev_id, -1, -1);
+ port->inb_msg[0].mcback(port, priv->msg_rx_ring.dev_id, -1, -1);

/* Ack the queueing interrupt */
- out_be32((void *)&msg_regs->isr, RIO_MSG_ISR_DIQI);
+ out_be32(&priv->msg_regs->isr, RIO_MSG_ISR_DIQI);
}

out:
@@ -564,6 +596,7 @@ fsl_rio_rx_handler(int irq, void *dev_instance)
int rio_open_inb_mbox(struct rio_mport *mport, void *dev_id, int mbox, int entries)
{
int i, rc = 0;
+ struct rio_priv *priv = mport->priv;

if ((entries < RIO_MIN_RX_RING_SIZE) ||
(entries > RIO_MAX_RX_RING_SIZE) || (!is_power_of_2(entries))) {
@@ -572,36 +605,36 @@ int rio_open_inb_mbox(struct rio_mport *mport, void *dev_id, int mbox, int entri
}

/* Initialize client buffer ring */
- msg_rx_ring.dev_id = dev_id;
- msg_rx_ring.size = entries;
- msg_rx_ring.rx_slot = 0;
- for (i = 0; i < msg_rx_ring.size; i++)
- msg_rx_ring.virt_buffer[i] = NULL;
+ priv->msg_rx_ring.dev_id = dev_id;
+ priv->msg_rx_ring.size = entries;
+ priv->msg_rx_ring.rx_slot = 0;
+ for (i = 0; i < priv->msg_rx_ring.size; i++)
+ priv->msg_rx_ring.virt_buffer[i] = NULL;

/* Initialize inbound message ring */
- if (!(msg_rx_ring.virt = dma_alloc_coherent(NULL,
- msg_rx_ring.size *
+ if (!(priv->msg_rx_ring.virt = dma_alloc_coherent(NULL,
+ priv->msg_rx_ring.size *
RIO_MAX_MSG_SIZE,
- &msg_rx_ring.phys,
+ &priv->msg_rx_ring.phys,
GFP_KERNEL))) {
rc = -ENOMEM;
goto out;
}

/* Point dequeue/enqueue pointers at first entry in ring */
- out_be32((void *)&msg_regs->ifqdpar, (u32) msg_rx_ring.phys);
- out_be32((void *)&msg_regs->ifqepar, (u32) msg_rx_ring.phys);
+ out_be32(&priv->msg_regs->ifqdpar, (u32) priv->msg_rx_ring.phys);
+ out_be32(&priv->msg_regs->ifqepar, (u32) priv->msg_rx_ring.phys);

/* Clear interrupt status */
- out_be32((void *)&msg_regs->isr, 0x00000091);
+ out_be32(&priv->msg_regs->isr, 0x00000091);

/* Hook up inbound message handler */
if ((rc =
- request_irq(MPC85xx_IRQ_RIO_RX, fsl_rio_rx_handler, 0,
+ request_irq(IRQ_RIO_RX(mport), fsl_rio_rx_handler, 0,
"msg_rx", (void *)mport)) < 0) {
dma_free_coherent(NULL, RIO_MSG_BUFFER_SIZE,
- msg_tx_ring.virt_buffer[i],
- msg_tx_ring.phys_buffer[i]);
+ priv->msg_tx_ring.virt_buffer[i],
+ priv->msg_tx_ring.phys_buffer[i]);
goto out;
}

@@ -612,15 +645,13 @@ int rio_open_inb_mbox(struct rio_mport *mport, void *dev_id, int mbox, int entri
* Unmask all interrupt sources
* Disable
*/
- out_be32((void *)&msg_regs->imr, 0x001b0060);
+ out_be32(&priv->msg_regs->imr, 0x001b0060);

/* Set number of queue entries */
- out_be32((void *)&msg_regs->imr,
- in_be32((void *)&msg_regs->imr) |
- ((get_bitmask_order(entries) - 2) << 12));
+ setbits32(&priv->msg_regs->imr, (get_bitmask_order(entries) - 2) << 12);

/* Now enable the unit */
- out_be32((void *)&msg_regs->imr, in_be32((void *)&msg_regs->imr) | 0x1);
+ setbits32(&priv->msg_regs->imr, 0x1);

out:
return rc;
@@ -636,15 +667,16 @@ int rio_open_inb_mbox(struct rio_mport *mport, void *dev_id, int mbox, int entri
*/
void rio_close_inb_mbox(struct rio_mport *mport, int mbox)
{
+ struct rio_priv *priv = mport->priv;
/* Disable inbound message unit */
- out_be32((void *)&msg_regs->imr, 0);
+ out_be32(&priv->msg_regs->imr, 0);

/* Free ring */
- dma_free_coherent(NULL, msg_rx_ring.size * RIO_MAX_MSG_SIZE,
- msg_rx_ring.virt, msg_rx_ring.phys);
+ dma_free_coherent(NULL, priv->msg_rx_ring.size * RIO_MAX_MSG_SIZE,
+ priv->msg_rx_ring.virt, priv->msg_rx_ring.phys);

/* Free interrupt */
- free_irq(MPC85xx_IRQ_RIO_RX, (void *)mport);
+ free_irq(IRQ_RIO_RX(mport), (void *)mport);
}

/**
@@ -659,21 +691,22 @@ void rio_close_inb_mbox(struct rio_mport *mport, int mbox)
int rio_hw_add_inb_buffer(struct rio_mport *mport, int mbox, void *buf)
{
int rc = 0;
+ struct rio_priv *priv = mport->priv;

pr_debug("RIO: rio_hw_add_inb_buffer(), msg_rx_ring.rx_slot %d\n",
- msg_rx_ring.rx_slot);
+ priv->msg_rx_ring.rx_slot);

- if (msg_rx_ring.virt_buffer[msg_rx_ring.rx_slot]) {
+ if (priv->msg_rx_ring.virt_buffer[priv->msg_rx_ring.rx_slot]) {
printk(KERN_ERR
"RIO: error adding inbound buffer %d, buffer exists\n",
- msg_rx_ring.rx_slot);
+ priv->msg_rx_ring.rx_slot);
rc = -EINVAL;
goto out;
}

- msg_rx_ring.virt_buffer[msg_rx_ring.rx_slot] = buf;
- if (++msg_rx_ring.rx_slot == msg_rx_ring.size)
- msg_rx_ring.rx_slot = 0;
+ priv->msg_rx_ring.virt_buffer[priv->msg_rx_ring.rx_slot] = buf;
+ if (++priv->msg_rx_ring.rx_slot == priv->msg_rx_ring.size)
+ priv->msg_rx_ring.rx_slot = 0;

out:
return rc;
@@ -691,20 +724,20 @@ EXPORT_SYMBOL_GPL(rio_hw_add_inb_buffer);
*/
void *rio_hw_get_inb_message(struct rio_mport *mport, int mbox)
{
- u32 imr;
+ struct rio_priv *priv = mport->priv;
u32 phys_buf, virt_buf;
void *buf = NULL;
int buf_idx;

- phys_buf = in_be32((void *)&msg_regs->ifqdpar);
+ phys_buf = in_be32(&priv->msg_regs->ifqdpar);

/* If no more messages, then bail out */
- if (phys_buf == in_be32((void *)&msg_regs->ifqepar))
+ if (phys_buf == in_be32(&priv->msg_regs->ifqepar))
goto out2;

- virt_buf = (u32) msg_rx_ring.virt + (phys_buf - msg_rx_ring.phys);
- buf_idx = (phys_buf - msg_rx_ring.phys) / RIO_MAX_MSG_SIZE;
- buf = msg_rx_ring.virt_buffer[buf_idx];
+ virt_buf = (u32) priv->msg_rx_ring.virt + (phys_buf - priv->msg_rx_ring.phys);
+ buf_idx = (phys_buf - priv->msg_rx_ring.phys) / RIO_MAX_MSG_SIZE;
+ buf = priv->msg_rx_ring.virt_buffer[buf_idx];

if (!buf) {
printk(KERN_ERR
@@ -716,11 +749,10 @@ void *rio_hw_get_inb_message(struct rio_mport *mport, int mbox)
memcpy(buf, (void *)virt_buf, RIO_MAX_MSG_SIZE);

/* Clear the available buffer */
- msg_rx_ring.virt_buffer[buf_idx] = NULL;
+ priv->msg_rx_ring.virt_buffer[buf_idx] = NULL;

out1:
- imr = in_be32((void *)&msg_regs->imr);
- out_be32((void *)&msg_regs->imr, imr | RIO_MSG_IMR_MI);
+ setbits32(&priv->msg_regs->imr, RIO_MSG_IMR_MI);

out2:
return buf;
@@ -741,27 +773,27 @@ fsl_rio_dbell_handler(int irq, void *dev_instance)
{
int dsr;
struct rio_mport *port = (struct rio_mport *)dev_instance;
+ struct rio_priv *priv = port->priv;

- dsr = in_be32((void *)&msg_regs->dsr);
+ dsr = in_be32(&priv->msg_regs->dsr);

if (dsr & DOORBELL_DSR_TE) {
pr_info("RIO: doorbell reception error\n");
- out_be32((void *)&msg_regs->dsr, DOORBELL_DSR_TE);
+ out_be32(&priv->msg_regs->dsr, DOORBELL_DSR_TE);
goto out;
}

if (dsr & DOORBELL_DSR_QFI) {
pr_info("RIO: doorbell queue full\n");
- out_be32((void *)&msg_regs->dsr, DOORBELL_DSR_QFI);
+ out_be32(&priv->msg_regs->dsr, DOORBELL_DSR_QFI);
goto out;
}

/* XXX Need to check/dispatch until queue empty */
if (dsr & DOORBELL_DSR_DIQI) {
u32 dmsg =
- (u32) dbell_ring.virt +
- (in_be32((void *)&msg_regs->dqdpar) & 0xfff);
- u32 dmr;
+ (u32) priv->dbell_ring.virt +
+ (in_be32(&priv->msg_regs->dqdpar) & 0xfff);
struct rio_dbell *dbell;
int found = 0;

@@ -784,9 +816,8 @@ fsl_rio_dbell_handler(int irq, void *dev_instance)
("RIO: spurious doorbell, sid %2.2x tid %2.2x info %4.4x\n",
DBELL_SID(dmsg), DBELL_TID(dmsg), DBELL_INF(dmsg));
}
- dmr = in_be32((void *)&msg_regs->dmr);
- out_be32((void *)&msg_regs->dmr, dmr | DOORBELL_DMR_DI);
- out_be32((void *)&msg_regs->dsr, DOORBELL_DSR_DIQI);
+ setbits32(&priv->msg_regs->dmr, DOORBELL_DMR_DI);
+ out_be32(&priv->msg_regs->dsr, DOORBELL_DSR_DIQI);
}

out:
@@ -803,10 +834,11 @@ fsl_rio_dbell_handler(int irq, void *dev_instance)
*/
static int fsl_rio_doorbell_init(struct rio_mport *mport)
{
+ struct rio_priv *priv = mport->priv;
int rc = 0;

/* Map outbound doorbell window immediately after maintenance window */
- if (!(dbell_win =
+ if (!(priv->dbell_win =
(u32) ioremap(mport->iores.start + RIO_MAINT_WIN_SIZE,
RIO_DBELL_WIN_SIZE))) {
printk(KERN_ERR
@@ -816,37 +848,37 @@ static int fsl_rio_doorbell_init(struct rio_mport *mport)
}

/* Initialize inbound doorbells */
- if (!(dbell_ring.virt = dma_alloc_coherent(NULL,
+ if (!(priv->dbell_ring.virt = dma_alloc_coherent(NULL,
512 * DOORBELL_MESSAGE_SIZE,
- &dbell_ring.phys,
+ &priv->dbell_ring.phys,
GFP_KERNEL))) {
printk(KERN_ERR "RIO: unable allocate inbound doorbell ring\n");
rc = -ENOMEM;
- iounmap((void *)dbell_win);
+ iounmap(priv->dbell_win);
goto out;
}

/* Point dequeue/enqueue pointers at first entry in ring */
- out_be32((void *)&msg_regs->dqdpar, (u32) dbell_ring.phys);
- out_be32((void *)&msg_regs->dqepar, (u32) dbell_ring.phys);
+ out_be32(&priv->msg_regs->dqdpar, (u32) priv->dbell_ring.phys);
+ out_be32(&priv->msg_regs->dqepar, (u32) priv->dbell_ring.phys);

/* Clear interrupt status */
- out_be32((void *)&msg_regs->dsr, 0x00000091);
+ out_be32(&priv->msg_regs->dsr, 0x00000091);

/* Hook up doorbell handler */
if ((rc =
- request_irq(MPC85xx_IRQ_RIO_BELL, fsl_rio_dbell_handler, 0,
+ request_irq(IRQ_RIO_BELL(mport), fsl_rio_dbell_handler, 0,
"dbell_rx", (void *)mport) < 0)) {
- iounmap((void *)dbell_win);
+ iounmap(priv->dbell_win);
dma_free_coherent(NULL, 512 * DOORBELL_MESSAGE_SIZE,
- dbell_ring.virt, dbell_ring.phys);
+ priv->dbell_ring.virt, priv->dbell_ring.phys);
printk(KERN_ERR
"MPC85xx RIO: unable to request inbound doorbell irq");
goto out;
}

/* Configure doorbells for snooping, 512 entries, and enable */
- out_be32((void *)&msg_regs->dmr, 0x00108161);
+ out_be32(&priv->msg_regs->dmr, 0x00108161);

out:
return rc;
@@ -887,6 +919,8 @@ void fsl_rio_setup(int law_start, int law_size)
{
struct rio_ops *ops;
struct rio_mport *port;
+ struct rio_priv *priv = NULL;
+ int rc;

ops = kmalloc(sizeof(struct rio_ops), GFP_KERNEL);
ops->lcread = fsl_local_config_read;
@@ -898,6 +932,14 @@ void fsl_rio_setup(int law_start, int law_size)
port = kmalloc(sizeof(struct rio_mport), GFP_KERNEL);
port->id = 0;
port->index = 0;
+
+ priv = kzalloc(sizeof(struct rio_priv), GFP_KERNEL);
+ if (!priv) {
+ printk(KERN_ERR "Can't alloc memory for 'priv'\n");
+ rc = -ENOMEM;
+ goto err;
+ }
+
INIT_LIST_HEAD(&port->dbells);
port->iores.start = law_start;
port->iores.end = law_start + law_size;
@@ -911,22 +953,31 @@ void fsl_rio_setup(int law_start, int law_size)
port->ops = ops;
port->host_deviceid = fsl_rio_get_hdid(port->id);

+ port->priv = priv;
rio_register_mport(port);

- regs_win = (u32) ioremap(RIO_REGS_BASE, 0x20000);
- atmu_regs = (struct rio_atmu_regs *)(regs_win + RIO_ATMU_REGS_OFFSET);
- maint_atmu_regs = atmu_regs + 1;
- dbell_atmu_regs = atmu_regs + 2;
- msg_regs = (struct rio_msg_regs *)(regs_win + RIO_MSG_REGS_OFFSET);
+ priv->regs_win = (u32) ioremap(RIO_REGS_BASE, 0x20000);
+ priv->atmu_regs = (struct rio_atmu_regs *)(priv->regs_win
+ + RIO_ATMU_REGS_OFFSET);
+ priv->maint_atmu_regs = priv->atmu_regs + 1;
+ priv->dbell_atmu_regs = priv->atmu_regs + 2;
+ priv->msg_regs = (struct rio_msg_regs *)(priv->regs_win + RIO_MSG_REGS_OFFSET);

/* Configure maintenance transaction window */
- out_be32((void *)&maint_atmu_regs->rowbar, 0x000c0000);
- out_be32((void *)&maint_atmu_regs->rowar, 0x80077015);
+ out_be32(&priv->maint_atmu_regs->rowbar, 0x000c0000);
+ out_be32(&priv->maint_atmu_regs->rowar, 0x80077015);

- maint_win = (u32) ioremap(law_start, RIO_MAINT_WIN_SIZE);
+ priv->maint_win = (u32) ioremap(law_start, RIO_MAINT_WIN_SIZE);

/* Configure outbound doorbell window */
- out_be32((void *)&dbell_atmu_regs->rowbar, 0x000c0400);
- out_be32((void *)&dbell_atmu_regs->rowar, 0x8004200b);
+ out_be32(&priv->dbell_atmu_regs->rowbar, 0x000c0400);
+ out_be32(&priv->dbell_atmu_regs->rowar, 0x8004200b);
fsl_rio_doorbell_init(port);
+
+ return;
+err:
+ if (priv)
+ iounmap(priv->regs_win);
+ kfree(priv);
+ kfree(port);
}
diff --git a/drivers/rapidio/rio-access.c b/drivers/rapidio/rio-access.c
index 8b56bbd..a3824ba 100644
--- a/drivers/rapidio/rio-access.c
+++ b/drivers/rapidio/rio-access.c
@@ -48,7 +48,7 @@ int __rio_local_read_config_##size \
u32 data = 0; \
if (RIO_##size##_BAD) return RIO_BAD_SIZE; \
spin_lock_irqsave(&rio_config_lock, flags); \
- res = mport->ops->lcread(mport->id, offset, len, &data); \
+ res = mport->ops->lcread(mport, mport->id, offset, len, &data); \
*value = (type)data; \
spin_unlock_irqrestore(&rio_config_lock, flags); \
return res; \
@@ -71,7 +71,7 @@ int __rio_local_write_config_##size \
unsigned long flags; \
if (RIO_##size##_BAD) return RIO_BAD_SIZE; \
spin_lock_irqsave(&rio_config_lock, flags); \
- res = mport->ops->lcwrite(mport->id, offset, len, value); \
+ res = mport->ops->lcwrite(mport, mport->id, offset, len, value);\
spin_unlock_irqrestore(&rio_config_lock, flags); \
return res; \
}
@@ -108,7 +108,7 @@ int rio_mport_read_config_##size \
u32 data = 0; \
if (RIO_##size##_BAD) return RIO_BAD_SIZE; \
spin_lock_irqsave(&rio_config_lock, flags); \
- res = mport->ops->cread(mport->id, destid, hopcount, offset, len, &data); \
+ res = mport->ops->cread(mport, mport->id, destid, hopcount, offset, len, &data); \
*value = (type)data; \
spin_unlock_irqrestore(&rio_config_lock, flags); \
return res; \
@@ -131,7 +131,7 @@ int rio_mport_write_config_##size \
unsigned long flags; \
if (RIO_##size##_BAD) return RIO_BAD_SIZE; \
spin_lock_irqsave(&rio_config_lock, flags); \
- res = mport->ops->cwrite(mport->id, destid, hopcount, offset, len, value); \
+ res = mport->ops->cwrite(mport, mport->id, destid, hopcount, offset, len, value); \
spin_unlock_irqrestore(&rio_config_lock, flags); \
return res; \
}
@@ -166,7 +166,7 @@ int rio_mport_send_doorbell(struct rio_mport *mport, u16 destid, u16 data)
unsigned long flags;

spin_lock_irqsave(&rio_doorbell_lock, flags);
- res = mport->ops->dsend(mport->id, destid, data);
+ res = mport->ops->dsend(mport, mport->id, destid, data);
spin_unlock_irqrestore(&rio_doorbell_lock, flags);

return res;
diff --git a/include/linux/rio.h b/include/linux/rio.h
index 68e3f68..9ed78dc 100644
--- a/include/linux/rio.h
+++ b/include/linux/rio.h
@@ -163,6 +163,7 @@ struct rio_dbell {
* @id: Port ID, unique among all ports
* @index: Port index, unique among all port interfaces of the same type
* @name: Port name string
+ * @priv: Master port private data
*/
struct rio_mport {
struct list_head dbells; /* list of doorbell events */
@@ -178,6 +179,7 @@ struct rio_mport {
unsigned char index; /* port index, unique among all port
interfaces of the same type */
unsigned char name[40];
+ void *priv; /* Master port private data */
};

/**
@@ -229,13 +231,15 @@ struct rio_switch {
* @dsend: Callback to send a doorbell message.
*/
struct rio_ops {
- int (*lcread) (int index, u32 offset, int len, u32 * data);
- int (*lcwrite) (int index, u32 offset, int len, u32 data);
- int (*cread) (int index, u16 destid, u8 hopcount, u32 offset, int len,
- u32 * data);
- int (*cwrite) (int index, u16 destid, u8 hopcount, u32 offset, int len,
- u32 data);
- int (*dsend) (int index, u16 destid, u16 data);
+ int (*lcread) (struct rio_mport *mport, int index, u32 offset, int len,
+ u32 * data);
+ int (*lcwrite) (struct rio_mport *mport, int index, u32 offset, int len,
+ u32 data);
+ int (*cread) (struct rio_mport *mport, int index, u16 destid,
+ u8 hopcount, u32 offset, int len, u32 * data);
+ int (*cwrite) (struct rio_mport *mport, int index, u16 destid,
+ u8 hopcount, u32 offset, int len, u32 data);
+ int (*dsend) (struct rio_mport *mport, int index, u16 destid, u16 data);
};

#define RIO_RESOURCE_MEM 0x00000100
--
1.5.2

2008-01-30 10:22:28

by Zhang Wei

[permalink] [raw]
Subject: [PATCH 5/6] Add OF-tree support to RapidIO controller driver.

Now, RapidIO driver for powerpc architecture is also support OF-device.

Signed-off-by: Zhang Wei <[email protected]>
---
arch/powerpc/kernel/Makefile | 1 -
arch/powerpc/kernel/rio.c | 52 ---------------------
arch/powerpc/sysdev/fsl_rio.c | 101 +++++++++++++++++++++++++++++++++++++---
arch/powerpc/sysdev/fsl_rio.h | 20 --------
4 files changed, 93 insertions(+), 81 deletions(-)
delete mode 100644 arch/powerpc/kernel/rio.c
delete mode 100644 arch/powerpc/sysdev/fsl_rio.h

diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index 58dbfef..d9b3770 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -70,7 +70,6 @@ pci64-$(CONFIG_PPC64) += pci_dn.o isa-bridge.o
obj-$(CONFIG_PCI) += pci_$(CONFIG_WORD_SIZE).o $(pci64-y) \
pci-common.o
obj-$(CONFIG_PCI_MSI) += msi.o
-obj-$(CONFIG_RAPIDIO) += rio.o
obj-$(CONFIG_KEXEC) += machine_kexec.o crash.o \
machine_kexec_$(CONFIG_WORD_SIZE).o
obj-$(CONFIG_AUDIT) += audit.o
diff --git a/arch/powerpc/kernel/rio.c b/arch/powerpc/kernel/rio.c
deleted file mode 100644
index 29487fe..0000000
--- a/arch/powerpc/kernel/rio.c
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * RapidIO PPC32 support
- *
- * Copyright 2005 MontaVista Software, Inc.
- * Matt Porter <[email protected]>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/rio.h>
-
-#include <asm/rio.h>
-
-/**
- * platform_rio_init - Do platform specific RIO init
- *
- * Any platform specific initialization of RapdIO
- * hardware is done here as well as registration
- * of any active master ports in the system.
- */
-void __attribute__ ((weak))
- platform_rio_init(void)
-{
- printk(KERN_WARNING "RIO: No platform_rio_init() present\n");
-}
-
-/**
- * ppc_rio_init - Do PPC32 RIO init
- *
- * Calls platform-specific RIO init code and then calls
- * rio_init_mports() to initialize any master ports that
- * have been registered with the RIO subsystem.
- */
-static int __init ppc_rio_init(void)
-{
- printk(KERN_INFO "RIO: RapidIO init\n");
-
- /* Platform specific initialization */
- platform_rio_init();
-
- /* Enumerate all registered ports */
- rio_init_mports();
-
- return 0;
-}
-
-subsys_initcall(ppc_rio_init);
diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c
index 3907a2c..36b43ec 100644
--- a/arch/powerpc/sysdev/fsl_rio.c
+++ b/arch/powerpc/sysdev/fsl_rio.c
@@ -20,6 +20,7 @@
#include <linux/interrupt.h>
#include <linux/rio.h>
#include <linux/rio_drv.h>
+#include <linux/of_platform.h>

#include <asm/io.h>

@@ -28,7 +29,6 @@
#define IRQ_RIO_TX(m) (((struct rio_priv *)(m->priv))->txirq)
#define IRQ_RIO_RX(m) (((struct rio_priv *)(m->priv))->rxirq)

-#define RIO_REGS_BASE (CCSRBAR + 0xc0000)
#define RIO_ATMU_REGS_OFFSET 0x10c00
#define RIO_MSG_REGS_OFFSET 0x11000
#define RIO_MAINT_WIN_SIZE 0x400000
@@ -908,19 +908,57 @@ __setup("riohdid=", fsl_rio_get_cmdline);

/**
* fsl_rio_setup - Setup MPC85xx RapidIO interface
- * @law_start: Starting physical address of RapidIO LAW
- * @law_size: Size of RapidIO LAW
+ * @fsl_rio_setup - Setup Freescale PowerPC RapidIO interface
*
* Initializes MPC85xx RapidIO hardware interface, configures
* master port with system-specific info, and registers the
* master port with the RapidIO subsystem.
*/
-void fsl_rio_setup(int law_start, int law_size)
+int fsl_rio_setup(struct of_device *dev)
{
struct rio_ops *ops;
struct rio_mport *port;
- struct rio_priv *priv = NULL;
- int rc;
+ struct rio_priv *priv;
+ int rc = 0;
+ const u32 *dt_range;
+ struct resource regs;
+ int rlen;
+ u64 law_start, law_size;
+ int paw, aw, sw;
+
+ if (!dev->node) {
+ dev_err(&dev->dev, "Device OF-Node is NULL");
+ return -EFAULT;
+ }
+
+ rc = of_address_to_resource(dev->node, 0, &regs);
+ if (rc) {
+ dev_err(&dev->dev, "Can't get %s property 'reg'\n",
+ dev->node->full_name);
+ return -EFAULT;
+ }
+ dev_info(&dev->dev, "Of-device full name %s\n", dev->node->full_name);
+ dev_info(&dev->dev, "Regs start 0x%08x size 0x%08x\n", regs.start,
+ regs.end - regs.start + 1);
+
+ dt_range = of_get_property(dev->node, "ranges", &rlen);
+ if (!dt_range) {
+ dev_err(&dev->dev, "Can't get %s property 'ranges'\n",
+ dev->node->full_name);
+ return -EFAULT;
+ }
+
+ /* Get node address wide */
+ aw = *(u32 *)of_get_property(dev->node, "#address-cells", NULL);
+ sw = *(u32 *)of_get_property(dev->node, "#size-cells", NULL);
+ /* Get parent address wide and size wide */
+ paw = of_n_addr_cells(dev->node);
+
+ law_start = of_read_number(dt_range + aw, paw);
+ law_size = of_read_number(dt_range + aw + paw, sw);
+
+ dev_info(&dev->dev, "LAW start 0x%016llx, size 0x%016llx.\n",
+ law_start, law_size);

ops = kmalloc(sizeof(struct rio_ops), GFP_KERNEL);
ops->lcread = fsl_local_config_read;
@@ -945,6 +983,12 @@ void fsl_rio_setup(int law_start, int law_size)
port->iores.end = law_start + law_size;
port->iores.flags = IORESOURCE_MEM;

+ priv->bellirq = irq_of_parse_and_map(dev->node, 2);
+ priv->txirq = irq_of_parse_and_map(dev->node, 3);
+ priv->rxirq = irq_of_parse_and_map(dev->node, 4);
+ dev_info(&dev->dev, "bellirq: %d, txirq: %d, rxirq %d\n", priv->bellirq,
+ priv->txirq, priv->rxirq);
+
rio_init_dbell_res(&port->riores[RIO_DOORBELL_RESOURCE], 0, 0xffff);
rio_init_mbox_res(&port->riores[RIO_INB_MBOX_RESOURCE], 0, 0);
rio_init_mbox_res(&port->riores[RIO_OUTB_MBOX_RESOURCE], 0, 0);
@@ -956,7 +1000,7 @@ void fsl_rio_setup(int law_start, int law_size)
port->priv = priv;
rio_register_mport(port);

- priv->regs_win = (u32) ioremap(RIO_REGS_BASE, 0x20000);
+ priv->regs_win = (u32) ioremap(regs.start, regs.end - regs.start + 1);
priv->atmu_regs = (struct rio_atmu_regs *)(priv->regs_win
+ RIO_ATMU_REGS_OFFSET);
priv->maint_atmu_regs = priv->atmu_regs + 1;
@@ -974,10 +1018,51 @@ void fsl_rio_setup(int law_start, int law_size)
out_be32(&priv->dbell_atmu_regs->rowar, 0x8004200b);
fsl_rio_doorbell_init(port);

- return;
+ return 0;
err:
if (priv)
iounmap(priv->regs_win);
+ kfree(ops);
kfree(priv);
kfree(port);
+ return rc;
}
+
+/* The probe function for RapidIO peer-to-peer network.
+ */
+static int __devinit fsl_of_rio_rpn_probe(struct of_device *dev,
+ const struct of_device_id *match)
+{
+ int rc;
+ printk(KERN_INFO "Setting up RapidIO peer-to-peer network %s\n",
+ dev->node->full_name);
+
+ rc = fsl_rio_setup(dev);
+ if (rc)
+ goto out;
+
+ /* Enumerate all registered ports */
+ rc = rio_init_mports();
+out:
+ return rc;
+};
+
+static struct of_device_id fsl_of_rio_rpn_ids[] = {
+ {
+ .compatible = "fsl,rapidio-delta",
+ },
+ {},
+};
+
+static struct of_platform_driver fsl_of_rio_rpn_driver = {
+ .name = "fsl-of-rio",
+ .match_table = fsl_of_rio_rpn_ids,
+ .probe = fsl_of_rio_rpn_probe,
+};
+
+static __init int fsl_of_rio_rpn_init(void)
+{
+ return of_register_platform_driver(&fsl_of_rio_rpn_driver);
+}
+
+subsys_initcall(fsl_of_rio_rpn_init);
diff --git a/arch/powerpc/sysdev/fsl_rio.h b/arch/powerpc/sysdev/fsl_rio.h
deleted file mode 100644
index 6d3ff30..0000000
--- a/arch/powerpc/sysdev/fsl_rio.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * MPC85xx RapidIO definitions
- *
- * Copyright 2005 MontaVista Software, Inc.
- * Matt Porter <[email protected]>
- *
- * 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.
- */
-
-#ifndef __PPC_SYSLIB_PPC85XX_RIO_H
-#define __PPC_SYSLIB_PPC85XX_RIO_H
-
-#include <linux/init.h>
-
-extern void mpc85xx_rio_setup(int law_start, int law_size);
-
-#endif /* __PPC_SYSLIB_PPC85XX_RIO_H */
--
1.5.2

2008-01-30 10:22:43

by Zhang Wei

[permalink] [raw]
Subject: [PATCH 3/6] Move include/asm-ppc/rio.h to include/asm-powerpc/rio.h

Signed-off-by: Zhang Wei <[email protected]>
---
include/asm-powerpc/rio.h | 18 ++++++++++++++++++
include/asm-ppc/rio.h | 18 ------------------
2 files changed, 18 insertions(+), 18 deletions(-)
create mode 100644 include/asm-powerpc/rio.h
delete mode 100644 include/asm-ppc/rio.h

diff --git a/include/asm-powerpc/rio.h b/include/asm-powerpc/rio.h
new file mode 100644
index 0000000..0018bf8
--- /dev/null
+++ b/include/asm-powerpc/rio.h
@@ -0,0 +1,18 @@
+/*
+ * RapidIO architecture support
+ *
+ * Copyright 2005 MontaVista Software, Inc.
+ * Matt Porter <[email protected]>
+ *
+ * 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.
+ */
+
+#ifndef ASM_PPC_RIO_H
+#define ASM_PPC_RIO_H
+
+extern void platform_rio_init(void);
+
+#endif /* ASM_PPC_RIO_H */
diff --git a/include/asm-ppc/rio.h b/include/asm-ppc/rio.h
deleted file mode 100644
index 0018bf8..0000000
--- a/include/asm-ppc/rio.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * RapidIO architecture support
- *
- * Copyright 2005 MontaVista Software, Inc.
- * Matt Porter <[email protected]>
- *
- * 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.
- */
-
-#ifndef ASM_PPC_RIO_H
-#define ASM_PPC_RIO_H
-
-extern void platform_rio_init(void);
-
-#endif /* ASM_PPC_RIO_H */
--
1.5.2

2008-01-30 14:21:55

by Kumar Gala

[permalink] [raw]
Subject: Re: [PATCH 3/6] Move include/asm-ppc/rio.h to include/asm-powerpc/rio.h


On Jan 30, 2008, at 4:30 AM, Zhang Wei wrote:

> Signed-off-by: Zhang Wei <[email protected]>
> ---
> include/asm-powerpc/rio.h | 18 ++++++++++++++++++
> include/asm-ppc/rio.h | 18 ------------------
> 2 files changed, 18 insertions(+), 18 deletions(-)
> create mode 100644 include/asm-powerpc/rio.h
> delete mode 100644 include/asm-ppc/rio.h

it seems with OF we can just git rid of this?

-k

2008-01-30 14:28:07

by Kumar Gala

[permalink] [raw]
Subject: Re: [PATCH 4/6] Add multi mport support.


On Jan 30, 2008, at 4:30 AM, Zhang Wei wrote:

> Change lots of static variable to mport private. And add mport to some
> function declaration.

Can you explain this patch further. Its not clear exactly from this
commit message why we are doing this.

- k

2008-01-30 14:44:23

by Kumar Gala

[permalink] [raw]
Subject: Re: [PATCH 1/6] Change RIO function mpc85xx_ to fsl_ .

Can you post a device tree update as well.

The older patches on the list for the 86xx .dts should NOT put the rio
node under the soc. It should be at the same level as PCI.

- k

2008-01-31 03:36:46

by Zhang Wei

[permalink] [raw]
Subject: RE: [PATCH 3/6] Move include/asm-ppc/rio.h to include/asm-powerpc/rio.h



> -----Original Message-----
> From: Kumar Gala [mailto:[email protected]]
> On Jan 30, 2008, at 4:30 AM, Zhang Wei wrote:
>
> > Signed-off-by: Zhang Wei <[email protected]>
> > ---
> > include/asm-powerpc/rio.h | 18 ++++++++++++++++++
> > include/asm-ppc/rio.h | 18 ------------------
> > 2 files changed, 18 insertions(+), 18 deletions(-)
> > create mode 100644 include/asm-powerpc/rio.h
> > delete mode 100644 include/asm-ppc/rio.h
>
> it seems with OF we can just git rid of this?
>

Aha, yep :), The change just make the RIO driver in arch/powerpc can be
compiled with RapidIO OF patch.

If we have OF patch, you can drop this patch.

Thanks!
Wei.

2008-01-31 05:58:21

by Zhang Wei

[permalink] [raw]
Subject: RE: [PATCH 4/6] Add multi mport support.



> -----Original Message-----
> From: Kumar Gala [mailto:[email protected]]
>
> On Jan 30, 2008, at 4:30 AM, Zhang Wei wrote:
>
> > Change lots of static variable to mport private. And add
> mport to some
> > function declaration.
>
> Can you explain this patch further. Its not clear exactly from this
> commit message why we are doing this.
>
> - k

Sorry about I have a little hurry about it.

The original RapidIO driver suppose there is only one mpc85xx RIO
controller
in system. So, some data structures are defined as mpc85xx_rio global,
such as 'regs_win', 'dbell_ring', 'msg_tx_ring'. Now, I changed them to
mport's private members. And you can define multi RIO OF-nodes in dts
file
for multi RapidIO controller in one processor, such as PCI/PCI-Ex host
controllers
in Freescale's silicon. And the mport operation function declaration
should be changed
to know which RapidIO controller is target.

Thanks!
Wei

2008-01-31 06:04:54

by Zhang Wei

[permalink] [raw]
Subject: RE: [PATCH 1/6] Change RIO function mpc85xx_ to fsl_ .

All right, I'll give you another patch for 86xx dts file. :)

Btw: Why the PCI and other nodes were moved from SOC? Just for clear?
If they are moved out, their register address must use full address not
offset address.

Thanks!
Wei.

> -----Original Message-----
> From: Kumar Gala [mailto:[email protected]]
> Sent: Wednesday, January 30, 2008 10:44 PM
> To: Zhang Wei
> Cc: [email protected];
> [email protected]; [email protected]
> Subject: Re: [PATCH 1/6] Change RIO function mpc85xx_ to fsl_ .
>
> Can you post a device tree update as well.
>
> The older patches on the list for the 86xx .dts should NOT
> put the rio
> node under the soc. It should be at the same level as PCI.
>
> - k
>

2008-01-31 06:16:49

by Kumar Gala

[permalink] [raw]
Subject: Re: [PATCH 1/6] Change RIO function mpc85xx_ to fsl_ .


On Jan 31, 2008, at 12:04 AM, Zhang Wei wrote:

> All right, I'll give you another patch for 86xx dts file. :)
>
> Btw: Why the PCI and other nodes were moved from SOC? Just for clear?
> If they are moved out, their register address must use full address
> not
> offset address.

we did this because the feeling was the SOC node just represented the
IMMR/CCSBAR registers, and not the address space used by the various
busses.

(this is why pci, rio, and local bus all exist outside of the soc node).

- k

2008-01-31 06:19:33

by Kumar Gala

[permalink] [raw]
Subject: Re: [PATCH 4/6] Add multi mport support.


On Jan 30, 2008, at 11:57 PM, Zhang Wei wrote:

>
>
>> -----Original Message-----
>> From: Kumar Gala [mailto:[email protected]]
>>
>> On Jan 30, 2008, at 4:30 AM, Zhang Wei wrote:
>>
>>> Change lots of static variable to mport private. And add
>> mport to some
>>> function declaration.
>>
>> Can you explain this patch further. Its not clear exactly from this
>> commit message why we are doing this.
>>
>> - k
>
> Sorry about I have a little hurry about it.
>
> The original RapidIO driver suppose there is only one mpc85xx RIO
> controller
> in system. So, some data structures are defined as mpc85xx_rio global,
> such as 'regs_win', 'dbell_ring', 'msg_tx_ring'. Now, I changed them
> to
> mport's private members. And you can define multi RIO OF-nodes in dts
> file
> for multi RapidIO controller in one processor, such as PCI/PCI-Ex host
> controllers
> in Freescale's silicon. And the mport operation function declaration
> should be changed
> to know which RapidIO controller is target.

thanks, this makes a lot of sense and now reviewing the patch will
make some sense to me :)

- k

2008-01-31 06:23:18

by Kumar Gala

[permalink] [raw]
Subject: Re: [PATCH 4/6] Add multi mport support.


On Jan 31, 2008, at 12:15 AM, Kumar Gala wrote:

>
> On Jan 30, 2008, at 11:57 PM, Zhang Wei wrote:
>
>>
>>
>>> -----Original Message-----
>>> From: Kumar Gala [mailto:[email protected]]
>>>
>>> On Jan 30, 2008, at 4:30 AM, Zhang Wei wrote:
>>>
>>>> Change lots of static variable to mport private. And add
>>> mport to some
>>>> function declaration.
>>>
>>> Can you explain this patch further. Its not clear exactly from this
>>> commit message why we are doing this.
>>>
>>> - k
>>
>> Sorry about I have a little hurry about it.
>>
>> The original RapidIO driver suppose there is only one mpc85xx RIO
>> controller
>> in system. So, some data structures are defined as mpc85xx_rio
>> global,
>> such as 'regs_win', 'dbell_ring', 'msg_tx_ring'. Now, I changed them
>> to
>> mport's private members. And you can define multi RIO OF-nodes in dts
>> file
>> for multi RapidIO controller in one processor, such as PCI/PCI-Ex
>> host
>> controllers
>> in Freescale's silicon. And the mport operation function declaration
>> should be changed
>> to know which RapidIO controller is target.
>
> thanks, this makes a lot of sense and now reviewing the patch will
> make some sense to me :)

when we have multiple ports are the device IDs on the ports intended
to be unique only to a port or unique across all ports?

- k

2008-01-31 06:31:27

by Zhang Wei

[permalink] [raw]
Subject: RE: [PATCH 4/6] Add multi mport support.



> -----Original Message-----
> From: Kumar Gala [mailto:[email protected]]
>
> On Jan 31, 2008, at 12:15 AM, Kumar Gala wrote:
>
> >
> > On Jan 30, 2008, at 11:57 PM, Zhang Wei wrote:
> >
> >>
> >>
> >>> -----Original Message-----
> >>> From: Kumar Gala [mailto:[email protected]]
> >>>
> >>> On Jan 30, 2008, at 4:30 AM, Zhang Wei wrote:
> >>>
> >>>> Change lots of static variable to mport private. And add
> >>> mport to some
> >>>> function declaration.
> >>>
> >>> Can you explain this patch further. Its not clear
> exactly from this
> >>> commit message why we are doing this.
> >>>
> >>> - k
> >>
> >> Sorry about I have a little hurry about it.
> >>
> >> The original RapidIO driver suppose there is only one mpc85xx RIO
> >> controller
> >> in system. So, some data structures are defined as mpc85xx_rio
> >> global,
> >> such as 'regs_win', 'dbell_ring', 'msg_tx_ring'. Now, I
> changed them
> >> to
> >> mport's private members. And you can define multi RIO
> OF-nodes in dts
> >> file
> >> for multi RapidIO controller in one processor, such as PCI/PCI-Ex
> >> host
> >> controllers
> >> in Freescale's silicon. And the mport operation function
> declaration
> >> should be changed
> >> to know which RapidIO controller is target.
> >
> > thanks, this makes a lot of sense and now reviewing the patch will
> > make some sense to me :)
>
> when we have multiple ports are the device IDs on the ports intended
> to be unique only to a port or unique across all ports?
>
I consider each RIO controller will has its own network, the device IDs
should be
unique only in its port network.

Cheers!
Wei

2008-01-31 18:43:33

by Phil Terry

[permalink] [raw]
Subject: RE: [PATCH 4/6] Add multi mport support.

On Thu, 2008-01-31 at 14:30 +0800, Zhang Wei wrote:
>
> > -----Original Message-----
> > From: Kumar Gala [mailto:[email protected]]
> >
> > On Jan 31, 2008, at 12:15 AM, Kumar Gala wrote:
> >
> > >
> > > On Jan 30, 2008, at 11:57 PM, Zhang Wei wrote:
> > >
> > >>
> > >>
> > >>> -----Original Message-----
> > >>> From: Kumar Gala [mailto:[email protected]]
> > >>>
> > >>> On Jan 30, 2008, at 4:30 AM, Zhang Wei wrote:
> > >>>
> > >>>> Change lots of static variable to mport private. And add
> > >>> mport to some
> > >>>> function declaration.
> > >>>
> > >>> Can you explain this patch further. Its not clear
> > exactly from this
> > >>> commit message why we are doing this.
> > >>>
> > >>> - k
> > >>
> > >> Sorry about I have a little hurry about it.
> > >>
> > >> The original RapidIO driver suppose there is only one mpc85xx RIO
> > >> controller
> > >> in system. So, some data structures are defined as mpc85xx_rio
> > >> global,
> > >> such as 'regs_win', 'dbell_ring', 'msg_tx_ring'. Now, I
> > changed them
> > >> to
> > >> mport's private members. And you can define multi RIO
> > OF-nodes in dts
> > >> file
> > >> for multi RapidIO controller in one processor, such as PCI/PCI-Ex
> > >> host
> > >> controllers
> > >> in Freescale's silicon. And the mport operation function
> > declaration
> > >> should be changed
> > >> to know which RapidIO controller is target.
> > >
> > > thanks, this makes a lot of sense and now reviewing the patch will
> > > make some sense to me :)
> >
> > when we have multiple ports are the device IDs on the ports intended
> > to be unique only to a port or unique across all ports?
> >
> I consider each RIO controller will has its own network, the device IDs
> should be
> unique only in its port network.
Hmmm, I see two cases:

1. I have two mport to two controllers each connected to different
physical fabrics. This system can act as an application bridge between
the two fabrics.

2. I have two mports to two controllers each connected directly or
indirectly to the same fabric. I want to use the extra bandwidth and
load balance and/or have a fall back redundant connection via an
alternate physical connection to the fabric etc.

What should be the rules for allocating the initial IDs to the two
mports to allow system wide enumeration to work in both of the above
cases?

What do you expect the semantics of higher level addressing to be:
a pair <mport,id>, where <x,n> is a different device from <y,n>,
a pair <mport,id>, where <x,n> is the same device as <y,n>,or
a singleton n, where n is unique and identifies the first routing step
of which controller, x or y, to use.

I smell a can of worms.... :-)

Cheers
Phil

>
> Cheers!
> Wei
> _______________________________________________
> Linuxppc-dev mailing list
> [email protected]
> https://ozlabs.org/mailman/listinfo/linuxppc-dev
>
>

2008-02-01 04:06:45

by Zhang Wei

[permalink] [raw]
Subject: RE: [PATCH 4/6] Add multi mport support.

Hi, Phil,

> -----Original Message-----
> From: Phil Terry [mailto:[email protected]]
>
> On Thu, 2008-01-31 at 14:30 +0800, Zhang Wei wrote:
> >
> > > >
> > I consider each RIO controller will has its own network,
> the device IDs
> > should be
> > unique only in its port network.
> Hmmm, I see two cases:

Good questions! They are very important and also my concern now.

>
> 1. I have two mport to two controllers each connected to different
> physical fabrics. This system can act as an application bridge between
> the two fabrics.
>

The current driver just looks two mport as two independent fabrics.
We can add bridge driver to implement your idea.

> 2. I have two mports to two controllers each connected directly or
> indirectly to the same fabric. I want to use the extra bandwidth and
> load balance and/or have a fall back redundant connection via an
> alternate physical connection to the fabric etc.
>

That's a terrible thing in the current driver. Two mports get the same
ID in one fabric. About the port bound, it's a good idea, I also need
a new driver to support it.

In fact, our first mission is to make the RapidIO driver ported from ppc
to powerpc can
be compiled and run. Fortunately, there is no more than one port in
processor now,
we have time to implement it.

> What should be the rules for allocating the initial IDs to the two
> mports to allow system wide enumeration to work in both of the above
> cases?
>

A choice is add ID option into dts node. I have some ideas about RapidIO
driver in u-boot. U-boot can assign ID in dts and tell kernel.

> What do you expect the semantics of higher level addressing to be:
> a pair <mport,id>, where <x,n> is a different device from <y,n>,
> a pair <mport,id>, where <x,n> is the same device as <y,n>,or
> a singleton n, where n is unique and identifies the first
> routing step
> of which controller, x or y, to use.

It seems the address pair is a must-be selection as pci bus.
But now, no connection between ports. Every operations in only
in its own port view.

> I smell a can of worms.... :-)

A good nose! Thanks! :)

Cheers!
Wei

2008-02-05 05:44:44

by Stephen Rothwell

[permalink] [raw]
Subject: Re: [PATCH 5/6] Add OF-tree support to RapidIO controller driver.

On Wed, 30 Jan 2008 18:30:52 +0800 Zhang Wei <[email protected]> wrote:
>
> -void fsl_rio_setup(int law_start, int law_size)
> +int fsl_rio_setup(struct of_device *dev)
> {

> + if (!dev->node) {
> + dev_err(&dev->dev, "Device OF-Node is NULL");
> + return -EFAULT;

Probably -EINVAL would be better. Here and all the other -EFAULTs.

> + aw = *(u32 *)of_get_property(dev->node, "#address-cells", NULL);
> + sw = *(u32 *)of_get_property(dev->node, "#size-cells", NULL);

What happens if either of these properties is missing?

> +static struct of_device_id fsl_of_rio_rpn_ids[] = {

This should be "const" please.

--
Cheers,
Stephen Rothwell [email protected]
http://www.canb.auug.org.au/~sfr/


Attachments:
(No filename) (727.00 B)
(No filename) (189.00 B)
Download all attachments

2008-02-05 16:07:05

by Kumar Gala

[permalink] [raw]
Subject: Re: [PATCH 5/6] Add OF-tree support to RapidIO controller driver.


On Feb 4, 2008, at 11:44 PM, Stephen Rothwell wrote:

>>
>> + aw = *(u32 *)of_get_property(dev->node, "#address-cells", NULL);
>> + sw = *(u32 *)of_get_property(dev->node, "#size-cells", NULL);
>
> What happens if either of these properties is missing?

Should we add __must_check to of_get_property?

- k

2008-02-05 16:25:10

by Matt Porter

[permalink] [raw]
Subject: Re: [PATCH 4/6] Add multi mport support.

On Thu, Jan 31, 2008 at 01:57:25PM +0800, Zhang Wei wrote:
>
>
> > -----Original Message-----
> > From: Kumar Gala [mailto:[email protected]]
> >
> > On Jan 30, 2008, at 4:30 AM, Zhang Wei wrote:
> >
> > > Change lots of static variable to mport private. And add
> > mport to some
> > > function declaration.
> >
> > Can you explain this patch further. Its not clear exactly from this
> > commit message why we are doing this.
> >
> > - k
>
> Sorry about I have a little hurry about it.
>
> The original RapidIO driver suppose there is only one mpc85xx RIO
> controller
> in system. So, some data structures are defined as mpc85xx_rio global,
> such as 'regs_win', 'dbell_ring', 'msg_tx_ring'. Now, I changed them to
> mport's private members. And you can define multi RIO OF-nodes in dts
> file
> for multi RapidIO controller in one processor, such as PCI/PCI-Ex host
> controllers
> in Freescale's silicon. And the mport operation function declaration
> should be changed
> to know which RapidIO controller is target.

Right, the RapidIO subsystem itself has had the concept of multiple
master ports from the beginning. However, when I did the MPC85xx
support I chose to just implement it for the known silicon available
at the time. I'm not surprised there's new silicon with multiple
controllers now.

-Matt

2008-02-05 16:31:27

by Matt Porter

[permalink] [raw]
Subject: Re: [PATCH 4/6] Add multi mport support.

On Thu, Jan 31, 2008 at 02:30:13PM +0800, Zhang Wei wrote:
> > -----Original Message-----
> > From: Kumar Gala [mailto:[email protected]]
> > when we have multiple ports are the device IDs on the ports intended
> > to be unique only to a port or unique across all ports?
> >
> I consider each RIO controller will has its own network, the device IDs
> should be
> unique only in its port network.

This is a bad assumption IMHO. It pushes policy on to the system
designer of a RapidIO network.

It is very possible to use multiple controllers as entry points
in a single RapidIO network fabric space. The reason one would do this
is to provide optimized paths to some endpoints in the system.

If possible, there should never be a policy assumption like this in
kernel space. It's much better to assume that one may or may not
have a unique id space.

-Matt

2008-02-05 16:43:38

by Matt Porter

[permalink] [raw]
Subject: Re: [PATCH 6/6] Change the kernel configurated RapidIO system size to auto-probing.

On Wed, Jan 30, 2008 at 06:30:53PM +0800, Zhang Wei wrote:
> The RapidIO system size will auto probe in RIO setup. The route
> table and rionet_active in rionet.c are changed to be allocated
> dynamically according the system size.

<snip>

> + port->sys_size = (in_be32((priv->regs_win + RIO_PEF_CAR))
> + & RIO_PEF_CTLS) >> 4;
> + dev_info(&dev->dev, "RapidIO Common Transport System size: %d\n",
> + port->sys_size ? 65536 : 256);
> +

This is much nicer than the original hardcoded transport size
implementation.

-Matt

2008-02-18 07:24:47

by Zhang Wei

[permalink] [raw]
Subject: RE: [PATCH 5/6] Add OF-tree support to RapidIO controller driver.



> -----Original Message-----
> From: Kumar Gala [mailto:[email protected]]
>
>
> On Feb 4, 2008, at 11:44 PM, Stephen Rothwell wrote:
>
> >>
> >> + aw = *(u32 *)of_get_property(dev->node, "#address-cells", NULL);
> >> + sw = *(u32 *)of_get_property(dev->node, "#size-cells", NULL);
> >
> > What happens if either of these properties is missing?
>
> Should we add __must_check to of_get_property?
>

You are right, I'll add the checking here.

Thanks!
Wei.

2008-02-18 07:33:47

by Zhang Wei

[permalink] [raw]
Subject: RE: [PATCH 4/6] Add multi mport support.

Hi, Matt,

So glad to see you again!

> -----Original Message-----
> From: Matt Porter [mailto:[email protected]]
> On Thu, Jan 31, 2008 at 02:30:13PM +0800, Zhang Wei wrote:
> > > -----Original Message-----
> > > From: Kumar Gala [mailto:[email protected]]
> > > when we have multiple ports are the device IDs on the
> ports intended
> > > to be unique only to a port or unique across all ports?
> > >
> > I consider each RIO controller will has its own network,
> the device IDs
> > should be
> > unique only in its port network.
>
> This is a bad assumption IMHO. It pushes policy on to the system
> designer of a RapidIO network.

I know it is a real bad assumption. However, the RIO initial ID is only
transported to
driver by kernel parameter "riohdid", which can not distinguish the
multi
rio controllers. It may be more better add a "rio-id" property in RIO
dts node, but
the u-boot need some changes to support the rio-id assignment.

Cheers!
Wei.