aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rapidio/rio.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/rapidio/rio.c')
-rw-r--r--drivers/rapidio/rio.c84
1 files changed, 57 insertions, 27 deletions
diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c
index cc2a3b74d0f0..c29719cacbca 100644
--- a/drivers/rapidio/rio.c
+++ b/drivers/rapidio/rio.c
@@ -32,6 +32,7 @@
32#include "rio.h" 32#include "rio.h"
33 33
34static LIST_HEAD(rio_mports); 34static LIST_HEAD(rio_mports);
35static unsigned char next_portid;
35 36
36/** 37/**
37 * rio_local_get_device_id - Get the base/extended device id for a port 38 * rio_local_get_device_id - Get the base/extended device id for a port
@@ -68,9 +69,13 @@ int rio_request_inb_mbox(struct rio_mport *mport,
68 void (*minb) (struct rio_mport * mport, void *dev_id, int mbox, 69 void (*minb) (struct rio_mport * mport, void *dev_id, int mbox,
69 int slot)) 70 int slot))
70{ 71{
71 int rc = 0; 72 int rc = -ENOSYS;
73 struct resource *res;
72 74
73 struct resource *res = kmalloc(sizeof(struct resource), GFP_KERNEL); 75 if (mport->ops->open_inb_mbox == NULL)
76 goto out;
77
78 res = kmalloc(sizeof(struct resource), GFP_KERNEL);
74 79
75 if (res) { 80 if (res) {
76 rio_init_mbox_res(res, mbox, mbox); 81 rio_init_mbox_res(res, mbox, mbox);
@@ -88,7 +93,7 @@ int rio_request_inb_mbox(struct rio_mport *mport,
88 /* Hook the inbound message callback */ 93 /* Hook the inbound message callback */
89 mport->inb_msg[mbox].mcback = minb; 94 mport->inb_msg[mbox].mcback = minb;
90 95
91 rc = rio_open_inb_mbox(mport, dev_id, mbox, entries); 96 rc = mport->ops->open_inb_mbox(mport, dev_id, mbox, entries);
92 } else 97 } else
93 rc = -ENOMEM; 98 rc = -ENOMEM;
94 99
@@ -106,10 +111,13 @@ int rio_request_inb_mbox(struct rio_mport *mport,
106 */ 111 */
107int rio_release_inb_mbox(struct rio_mport *mport, int mbox) 112int rio_release_inb_mbox(struct rio_mport *mport, int mbox)
108{ 113{
109 rio_close_inb_mbox(mport, mbox); 114 if (mport->ops->close_inb_mbox) {
115 mport->ops->close_inb_mbox(mport, mbox);
110 116
111 /* Release the mailbox resource */ 117 /* Release the mailbox resource */
112 return release_resource(mport->inb_msg[mbox].res); 118 return release_resource(mport->inb_msg[mbox].res);
119 } else
120 return -ENOSYS;
113} 121}
114 122
115/** 123/**
@@ -129,9 +137,13 @@ int rio_request_outb_mbox(struct rio_mport *mport,
129 int entries, 137 int entries,
130 void (*moutb) (struct rio_mport * mport, void *dev_id, int mbox, int slot)) 138 void (*moutb) (struct rio_mport * mport, void *dev_id, int mbox, int slot))
131{ 139{
132 int rc = 0; 140 int rc = -ENOSYS;
141 struct resource *res;
133 142
134 struct resource *res = kmalloc(sizeof(struct resource), GFP_KERNEL); 143 if (mport->ops->open_outb_mbox == NULL)
144 goto out;
145
146 res = kmalloc(sizeof(struct resource), GFP_KERNEL);
135 147
136 if (res) { 148 if (res) {
137 rio_init_mbox_res(res, mbox, mbox); 149 rio_init_mbox_res(res, mbox, mbox);
@@ -149,7 +161,7 @@ int rio_request_outb_mbox(struct rio_mport *mport,
149 /* Hook the inbound message callback */ 161 /* Hook the inbound message callback */
150 mport->outb_msg[mbox].mcback = moutb; 162 mport->outb_msg[mbox].mcback = moutb;
151 163
152 rc = rio_open_outb_mbox(mport, dev_id, mbox, entries); 164 rc = mport->ops->open_outb_mbox(mport, dev_id, mbox, entries);
153 } else 165 } else
154 rc = -ENOMEM; 166 rc = -ENOMEM;
155 167
@@ -167,10 +179,13 @@ int rio_request_outb_mbox(struct rio_mport *mport,
167 */ 179 */
168int rio_release_outb_mbox(struct rio_mport *mport, int mbox) 180int rio_release_outb_mbox(struct rio_mport *mport, int mbox)
169{ 181{
170 rio_close_outb_mbox(mport, mbox); 182 if (mport->ops->close_outb_mbox) {
183 mport->ops->close_outb_mbox(mport, mbox);
171 184
172 /* Release the mailbox resource */ 185 /* Release the mailbox resource */
173 return release_resource(mport->outb_msg[mbox].res); 186 return release_resource(mport->outb_msg[mbox].res);
187 } else
188 return -ENOSYS;
174} 189}
175 190
176/** 191/**
@@ -1120,36 +1135,51 @@ static int __devinit rio_init(void)
1120 return 0; 1135 return 0;
1121} 1136}
1122 1137
1123device_initcall(rio_init);
1124
1125int __devinit rio_init_mports(void) 1138int __devinit rio_init_mports(void)
1126{ 1139{
1127 int rc = 0;
1128 struct rio_mport *port; 1140 struct rio_mport *port;
1129 1141
1130 list_for_each_entry(port, &rio_mports, node) { 1142 list_for_each_entry(port, &rio_mports, node) {
1131 if (!request_mem_region(port->iores.start,
1132 resource_size(&port->iores),
1133 port->name)) {
1134 printk(KERN_ERR
1135 "RIO: Error requesting master port region 0x%016llx-0x%016llx\n",
1136 (u64)port->iores.start, (u64)port->iores.end);
1137 rc = -ENOMEM;
1138 goto out;
1139 }
1140
1141 if (port->host_deviceid >= 0) 1143 if (port->host_deviceid >= 0)
1142 rio_enum_mport(port); 1144 rio_enum_mport(port);
1143 else 1145 else
1144 rio_disc_mport(port); 1146 rio_disc_mport(port);
1145 } 1147 }
1146 1148
1147 out: 1149 rio_init();
1148 return rc; 1150
1151 return 0;
1149} 1152}
1150 1153
1154device_initcall_sync(rio_init_mports);
1155
1156static int hdids[RIO_MAX_MPORTS + 1];
1157
1158static int rio_get_hdid(int index)
1159{
1160 if (!hdids[0] || hdids[0] <= index || index >= RIO_MAX_MPORTS)
1161 return -1;
1162
1163 return hdids[index + 1];
1164}
1165
1166static int rio_hdid_setup(char *str)
1167{
1168 (void)get_options(str, ARRAY_SIZE(hdids), hdids);
1169 return 1;
1170}
1171
1172__setup("riohdid=", rio_hdid_setup);
1173
1151void rio_register_mport(struct rio_mport *port) 1174void rio_register_mport(struct rio_mport *port)
1152{ 1175{
1176 if (next_portid >= RIO_MAX_MPORTS) {
1177 pr_err("RIO: reached specified max number of mports\n");
1178 return;
1179 }
1180
1181 port->id = next_portid++;
1182 port->host_deviceid = rio_get_hdid(port->id);
1153 list_add_tail(&port->node, &rio_mports); 1183 list_add_tail(&port->node, &rio_mports);
1154} 1184}
1155 1185