From f8f0626989c85b3d8bd67eff29d9dd3d14a5e71f Mon Sep 17 00:00:00 2001 From: Alexandre Bounine Date: Wed, 23 Mar 2011 16:43:02 -0700 Subject: rapidio: add architecture specific callbacks 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. This patch: Extend number of mport callback functions to eliminate direct linking of architecture specific mport operations. Signed-off-by: Alexandre Bounine Cc: Kumar Gala Cc: Matt Porter Cc: Li Yang Cc: Thomas Moll Cc: Micha Nelissen Cc: Benjamin Herrenschmidt Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/rio.h | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) (limited to 'include/linux/rio.h') diff --git a/include/linux/rio.h b/include/linux/rio.h index ff681ebba58..efed116efe9 100644 --- a/include/linux/rio.h +++ b/include/linux/rio.h @@ -241,7 +241,7 @@ struct rio_mport { struct rio_msg inb_msg[RIO_MAX_MBOX]; struct rio_msg outb_msg[RIO_MAX_MBOX]; int host_deviceid; /* Host device ID */ - struct rio_ops *ops; /* maintenance transaction functions */ + struct rio_ops *ops; /* low-level architecture-dependent routines */ unsigned char id; /* port ID, unique among all ports */ unsigned char index; /* port index, unique among all port interfaces of the same type */ @@ -285,6 +285,13 @@ struct rio_net { * @cwrite: Callback to perform network write of config space. * @dsend: Callback to send a doorbell message. * @pwenable: Callback to enable/disable port-write message handling. + * @open_outb_mbox: Callback to initialize outbound mailbox. + * @close_outb_mbox: Callback to shut down outbound mailbox. + * @open_inb_mbox: Callback to initialize inbound mailbox. + * @close_inb_mbox: Callback to shut down inbound mailbox. + * @add_outb_message: Callback to add a message to an outbound mailbox queue. + * @add_inb_buffer: Callback to add a buffer to an inbound mailbox queue. + * @get_inb_message: Callback to get a message from an inbound mailbox queue. */ struct rio_ops { int (*lcread) (struct rio_mport *mport, int index, u32 offset, int len, @@ -297,6 +304,16 @@ struct rio_ops { u8 hopcount, u32 offset, int len, u32 data); int (*dsend) (struct rio_mport *mport, int index, u16 destid, u16 data); int (*pwenable) (struct rio_mport *mport, int enable); + int (*open_outb_mbox)(struct rio_mport *mport, void *dev_id, + int mbox, int entries); + void (*close_outb_mbox)(struct rio_mport *mport, int mbox); + int (*open_inb_mbox)(struct rio_mport *mport, void *dev_id, + int mbox, int entries); + void (*close_inb_mbox)(struct rio_mport *mport, int mbox); + int (*add_outb_message)(struct rio_mport *mport, struct rio_dev *rdev, + 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); }; #define RIO_RESOURCE_MEM 0x00000100 @@ -380,10 +397,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_hw_add_outb_message(struct rio_mport *, struct rio_dev *, int, - void *, size_t); -extern int rio_hw_add_inb_buffer(struct rio_mport *, int, void *); -extern void *rio_hw_get_inb_message(struct rio_mport *, int); 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); -- cgit v1.2.3-70-g09d2 From 2f809985d2cbc78078b8da1cbed1f1ce1f4a0d5f Mon Sep 17 00:00:00 2001 From: Alexandre Bounine Date: Wed, 23 Mar 2011 16:43:04 -0700 Subject: rapidio: modify subsystem and driver initialization sequence 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 Cc: Kumar Gala Cc: Matt Porter Cc: Li Yang Cc: Thomas Moll Cc: Micha Nelissen Cc: Benjamin Herrenschmidt Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- 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(-) (limited to 'include/linux/rio.h') diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c index f95cb5636d1..576b8066089 100644 --- a/arch/powerpc/sysdev/fsl_rio.c +++ b/arch/powerpc/sysdev/fsl_rio.c @@ -1574,18 +1574,10 @@ err_ops: */ static int __devinit fsl_of_rio_rpn_probe(struct platform_device *dev) { - 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 678e5777da8..26afbaae23f 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 d520dbaede8..f861b728f80 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 efed116efe9..b6bcb163274 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); -- cgit v1.2.3-70-g09d2 From 569fccb6b48878d654310e1ffaf9a5a6e46b3144 Mon Sep 17 00:00:00 2001 From: Alexandre Bounine Date: Wed, 23 Mar 2011 16:43:05 -0700 Subject: rapidio: modify mport ID assignment 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 Cc: Kumar Gala Cc: Matt Porter Cc: Li Yang Cc: Thomas Moll Cc: Micha Nelissen Cc: Benjamin Herrenschmidt Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/powerpc/sysdev/fsl_rio.c | 25 ------------------------- drivers/rapidio/rio.c | 26 ++++++++++++++++++++++++++ include/linux/rio.h | 1 + 3 files changed, 27 insertions(+), 25 deletions(-) (limited to 'include/linux/rio.h') diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c index 576b8066089..8d26533ba98 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 f861b728f80..9a7b2168d1d 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 b6bcb163274..4e37a7cfa72 100644 --- a/include/linux/rio.h +++ b/include/linux/rio.h @@ -24,6 +24,7 @@ #define RIO_NO_HOPCOUNT -1 #define RIO_INVALID_DESTID 0xffff +#define RIO_MAX_MPORTS 8 #define RIO_MAX_MPORT_RESOURCES 16 #define RIO_MAX_DEV_RESOURCES 16 -- cgit v1.2.3-70-g09d2