aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGeoff Levand <geoffrey.levand@am.sony.com>2007-06-15 18:01:06 -0400
committerPaul Mackerras <paulus@samba.org>2007-06-28 05:16:40 -0400
commit7626e78d29651d3075e88f233c0632867ea6a35c (patch)
tree0f1d4b26d6597b9a81af2e2009ce2dae6aaabbc7
parenta3323d1a52ec5b70821590e4beaaf13c466fd396 (diff)
[POWERPC] PS3: Vuart rework
PS3 vuart updates to reflect the new PS3 unified device support. - Move vuart devices to the PS3 system bus. - Replace use of ps3_vuart_port_device with ps3_system_bus_device. - Make the PS3 vuart bus driver a loadable module. - Add remove() and shutdown() routines. - Move ps3_vuart_work into ps3_vuart_port_priv.tx_list. - Remove redundant spinlock ps3_vuart_work.lock. - No longer free ps3_vuart_port_device.priv on shutdown. - Cleanup Kconfig defs. - Export symbols needed for modular port drivers. - Arrange to use port numbers found in repository. - Fix bugs in ps3_vuart_read_async() and polled reading - Cleanup handling of shared interrupt with ps3_vuart_bus_interrupt_get() and ps3_vuart_bus_interrupt_put() - Add more comments to vuart.c. Signed-off-by: Geoff Levand <geoffrey.levand@am.sony.com> Signed-off-by: Paul Mackerras <paulus@samba.org>
-rw-r--r--arch/powerpc/platforms/ps3/Kconfig21
-rw-r--r--arch/powerpc/platforms/ps3/interrupt.c2
-rw-r--r--drivers/ps3/vuart.c813
-rw-r--r--drivers/ps3/vuart.h71
-rw-r--r--include/asm-powerpc/ps3.h17
5 files changed, 520 insertions, 404 deletions
diff --git a/arch/powerpc/platforms/ps3/Kconfig b/arch/powerpc/platforms/ps3/Kconfig
index 40f0008af4d1..b5122a764813 100644
--- a/arch/powerpc/platforms/ps3/Kconfig
+++ b/arch/powerpc/platforms/ps3/Kconfig
@@ -73,18 +73,12 @@ config PS3_USE_LPAR_ADDR
73 73
74config PS3_VUART 74config PS3_VUART
75 depends on PPC_PS3 75 depends on PPC_PS3
76 bool "PS3 Virtual UART support" if PS3_ADVANCED 76 tristate
77 default y
78 help
79 Include support for the PS3 Virtual UART.
80
81 This support is required for several system services
82 including the System Manager and AV Settings. In
83 general, all users will say Y.
84 77
85config PS3_PS3AV 78config PS3_PS3AV
79 depends on PPC_PS3
86 tristate "PS3 AV settings driver" if PS3_ADVANCED 80 tristate "PS3 AV settings driver" if PS3_ADVANCED
87 depends on PS3_VUART 81 select PS3_VUART
88 default y 82 default y
89 help 83 help
90 Include support for the PS3 AV Settings driver. 84 Include support for the PS3 AV Settings driver.
@@ -93,13 +87,14 @@ config PS3_PS3AV
93 general, all users will say Y or M. 87 general, all users will say Y or M.
94 88
95config PS3_SYS_MANAGER 89config PS3_SYS_MANAGER
96 bool "PS3 System Manager driver" if PS3_ADVANCED 90 depends on PPC_PS3
97 depends on PS3_VUART 91 tristate "PS3 System Manager driver" if PS3_ADVANCED
98 default y 92 select PS3_VUART
93 default m
99 help 94 help
100 Include support for the PS3 System Manager. 95 Include support for the PS3 System Manager.
101 96
102 This support is required for system control. In 97 This support is required for system control. In
103 general, all users will say Y. 98 general, all users will say Y or M.
104 99
105endmenu 100endmenu
diff --git a/arch/powerpc/platforms/ps3/interrupt.c b/arch/powerpc/platforms/ps3/interrupt.c
index 51141dc06f91..99a0826c8d90 100644
--- a/arch/powerpc/platforms/ps3/interrupt.c
+++ b/arch/powerpc/platforms/ps3/interrupt.c
@@ -564,6 +564,7 @@ int ps3_vuart_irq_setup(enum ps3_cpu_binding cpu, void* virt_addr_bmp,
564 564
565 return result; 565 return result;
566} 566}
567EXPORT_SYMBOL_GPL(ps3_vuart_irq_setup);
567 568
568int ps3_vuart_irq_destroy(unsigned int virq) 569int ps3_vuart_irq_destroy(unsigned int virq)
569{ 570{
@@ -583,6 +584,7 @@ int ps3_vuart_irq_destroy(unsigned int virq)
583 584
584 return result; 585 return result;
585} 586}
587EXPORT_SYMBOL_GPL(ps3_vuart_irq_destroy);
586 588
587/** 589/**
588 * ps3_spe_irq_setup - Setup an spe virq. 590 * ps3_spe_irq_setup - Setup an spe virq.
diff --git a/drivers/ps3/vuart.c b/drivers/ps3/vuart.c
index 5333fb2f0d86..bea25a1391ee 100644
--- a/drivers/ps3/vuart.c
+++ b/drivers/ps3/vuart.c
@@ -71,6 +71,34 @@ enum vuart_interrupt_mask {
71}; 71};
72 72
73/** 73/**
74 * struct ps3_vuart_port_priv - private vuart device data.
75 */
76
77struct ps3_vuart_port_priv {
78 u64 interrupt_mask;
79
80 struct {
81 spinlock_t lock;
82 struct list_head head;
83 } tx_list;
84 struct {
85 struct ps3_vuart_work work;
86 unsigned long bytes_held;
87 spinlock_t lock;
88 struct list_head head;
89 } rx_list;
90 struct ps3_vuart_stats stats;
91};
92
93static struct ps3_vuart_port_priv *to_port_priv(
94 struct ps3_system_bus_device *dev)
95{
96 BUG_ON(!dev);
97 BUG_ON(!dev->driver_priv);
98 return (struct ps3_vuart_port_priv *)dev->driver_priv;
99}
100
101/**
74 * struct ports_bmp - bitmap indicating ports needing service. 102 * struct ports_bmp - bitmap indicating ports needing service.
75 * 103 *
76 * A 256 bit read only bitmap indicating ports needing service. Do not write 104 * A 256 bit read only bitmap indicating ports needing service. Do not write
@@ -89,23 +117,6 @@ static void __maybe_unused _dump_ports_bmp(
89 pr_debug("%s:%d: ports_bmp: %016lxh\n", func, line, bmp->status); 117 pr_debug("%s:%d: ports_bmp: %016lxh\n", func, line, bmp->status);
90} 118}
91 119
92static int ps3_vuart_match_id_to_port(enum ps3_match_id match_id,
93 unsigned int *port_number)
94{
95 switch(match_id) {
96 case PS3_MATCH_ID_AV_SETTINGS:
97 *port_number = 0;
98 return 0;
99 case PS3_MATCH_ID_SYSTEM_MANAGER:
100 *port_number = 2;
101 return 0;
102 default:
103 WARN_ON(1);
104 *port_number = UINT_MAX;
105 return -EINVAL;
106 };
107}
108
109#define dump_port_params(_b) _dump_port_params(_b, __func__, __LINE__) 120#define dump_port_params(_b) _dump_port_params(_b, __func__, __LINE__)
110static void __maybe_unused _dump_port_params(unsigned int port_number, 121static void __maybe_unused _dump_port_params(unsigned int port_number,
111 const char* func, int line) 122 const char* func, int line)
@@ -144,14 +155,14 @@ struct vuart_triggers {
144 unsigned long tx; 155 unsigned long tx;
145}; 156};
146 157
147int ps3_vuart_get_triggers(struct ps3_vuart_port_device *dev, 158int ps3_vuart_get_triggers(struct ps3_system_bus_device *dev,
148 struct vuart_triggers *trig) 159 struct vuart_triggers *trig)
149{ 160{
150 int result; 161 int result;
151 unsigned long size; 162 unsigned long size;
152 unsigned long val; 163 unsigned long val;
153 164
154 result = lv1_get_virtual_uart_param(dev->priv->port_number, 165 result = lv1_get_virtual_uart_param(dev->port_number,
155 PARAM_TX_TRIGGER, &trig->tx); 166 PARAM_TX_TRIGGER, &trig->tx);
156 167
157 if (result) { 168 if (result) {
@@ -160,7 +171,7 @@ int ps3_vuart_get_triggers(struct ps3_vuart_port_device *dev,
160 return result; 171 return result;
161 } 172 }
162 173
163 result = lv1_get_virtual_uart_param(dev->priv->port_number, 174 result = lv1_get_virtual_uart_param(dev->port_number,
164 PARAM_RX_BUF_SIZE, &size); 175 PARAM_RX_BUF_SIZE, &size);
165 176
166 if (result) { 177 if (result) {
@@ -169,7 +180,7 @@ int ps3_vuart_get_triggers(struct ps3_vuart_port_device *dev,
169 return result; 180 return result;
170 } 181 }
171 182
172 result = lv1_get_virtual_uart_param(dev->priv->port_number, 183 result = lv1_get_virtual_uart_param(dev->port_number,
173 PARAM_RX_TRIGGER, &val); 184 PARAM_RX_TRIGGER, &val);
174 185
175 if (result) { 186 if (result) {
@@ -186,13 +197,13 @@ int ps3_vuart_get_triggers(struct ps3_vuart_port_device *dev,
186 return result; 197 return result;
187} 198}
188 199
189int ps3_vuart_set_triggers(struct ps3_vuart_port_device *dev, unsigned int tx, 200int ps3_vuart_set_triggers(struct ps3_system_bus_device *dev, unsigned int tx,
190 unsigned int rx) 201 unsigned int rx)
191{ 202{
192 int result; 203 int result;
193 unsigned long size; 204 unsigned long size;
194 205
195 result = lv1_set_virtual_uart_param(dev->priv->port_number, 206 result = lv1_set_virtual_uart_param(dev->port_number,
196 PARAM_TX_TRIGGER, tx); 207 PARAM_TX_TRIGGER, tx);
197 208
198 if (result) { 209 if (result) {
@@ -201,7 +212,7 @@ int ps3_vuart_set_triggers(struct ps3_vuart_port_device *dev, unsigned int tx,
201 return result; 212 return result;
202 } 213 }
203 214
204 result = lv1_get_virtual_uart_param(dev->priv->port_number, 215 result = lv1_get_virtual_uart_param(dev->port_number,
205 PARAM_RX_BUF_SIZE, &size); 216 PARAM_RX_BUF_SIZE, &size);
206 217
207 if (result) { 218 if (result) {
@@ -210,7 +221,7 @@ int ps3_vuart_set_triggers(struct ps3_vuart_port_device *dev, unsigned int tx,
210 return result; 221 return result;
211 } 222 }
212 223
213 result = lv1_set_virtual_uart_param(dev->priv->port_number, 224 result = lv1_set_virtual_uart_param(dev->port_number,
214 PARAM_RX_TRIGGER, size - rx); 225 PARAM_RX_TRIGGER, size - rx);
215 226
216 if (result) { 227 if (result) {
@@ -225,10 +236,12 @@ int ps3_vuart_set_triggers(struct ps3_vuart_port_device *dev, unsigned int tx,
225 return result; 236 return result;
226} 237}
227 238
228static int ps3_vuart_get_rx_bytes_waiting(struct ps3_vuart_port_device *dev, 239static int ps3_vuart_get_rx_bytes_waiting(struct ps3_system_bus_device *dev,
229 u64 *bytes_waiting) 240 u64 *bytes_waiting)
230{ 241{
231 int result = lv1_get_virtual_uart_param(dev->priv->port_number, 242 int result;
243
244 result = lv1_get_virtual_uart_param(dev->port_number,
232 PARAM_RX_BYTES, bytes_waiting); 245 PARAM_RX_BYTES, bytes_waiting);
233 246
234 if (result) 247 if (result)
@@ -240,17 +253,24 @@ static int ps3_vuart_get_rx_bytes_waiting(struct ps3_vuart_port_device *dev,
240 return result; 253 return result;
241} 254}
242 255
243static int ps3_vuart_set_interrupt_mask(struct ps3_vuart_port_device *dev, 256/**
257 * ps3_vuart_set_interrupt_mask - Enable/disable the port interrupt sources.
258 * @dev: The struct ps3_system_bus_device instance.
259 * @bmp: Logical OR of enum vuart_interrupt_mask values. A zero bit disables.
260 */
261
262static int ps3_vuart_set_interrupt_mask(struct ps3_system_bus_device *dev,
244 unsigned long mask) 263 unsigned long mask)
245{ 264{
246 int result; 265 int result;
266 struct ps3_vuart_port_priv *priv = to_port_priv(dev);
247 267
248 dev_dbg(&dev->core, "%s:%d: %lxh\n", __func__, __LINE__, mask); 268 dev_dbg(&dev->core, "%s:%d: %lxh\n", __func__, __LINE__, mask);
249 269
250 dev->priv->interrupt_mask = mask; 270 priv->interrupt_mask = mask;
251 271
252 result = lv1_set_virtual_uart_param(dev->priv->port_number, 272 result = lv1_set_virtual_uart_param(dev->port_number,
253 PARAM_INTERRUPT_MASK, dev->priv->interrupt_mask); 273 PARAM_INTERRUPT_MASK, priv->interrupt_mask);
254 274
255 if (result) 275 if (result)
256 dev_dbg(&dev->core, "%s:%d: interrupt_mask failed: %s\n", 276 dev_dbg(&dev->core, "%s:%d: interrupt_mask failed: %s\n",
@@ -259,79 +279,96 @@ static int ps3_vuart_set_interrupt_mask(struct ps3_vuart_port_device *dev,
259 return result; 279 return result;
260} 280}
261 281
262static int ps3_vuart_get_interrupt_status(struct ps3_vuart_port_device *dev, 282static int ps3_vuart_get_interrupt_status(struct ps3_system_bus_device *dev,
263 unsigned long *status) 283 unsigned long *status)
264{ 284{
285 int result;
286 struct ps3_vuart_port_priv *priv = to_port_priv(dev);
265 u64 tmp; 287 u64 tmp;
266 int result = lv1_get_virtual_uart_param(dev->priv->port_number, 288
289 result = lv1_get_virtual_uart_param(dev->port_number,
267 PARAM_INTERRUPT_STATUS, &tmp); 290 PARAM_INTERRUPT_STATUS, &tmp);
268 291
269 if (result) 292 if (result)
270 dev_dbg(&dev->core, "%s:%d: interrupt_status failed: %s\n", 293 dev_dbg(&dev->core, "%s:%d: interrupt_status failed: %s\n",
271 __func__, __LINE__, ps3_result(result)); 294 __func__, __LINE__, ps3_result(result));
272 295
273 *status = tmp & dev->priv->interrupt_mask; 296 *status = tmp & priv->interrupt_mask;
274 297
275 dev_dbg(&dev->core, "%s:%d: m %lxh, s %lxh, m&s %lxh\n", 298 dev_dbg(&dev->core, "%s:%d: m %lxh, s %lxh, m&s %lxh\n",
276 __func__, __LINE__, dev->priv->interrupt_mask, tmp, *status); 299 __func__, __LINE__, priv->interrupt_mask, tmp, *status);
277 300
278 return result; 301 return result;
279} 302}
280 303
281int ps3_vuart_enable_interrupt_tx(struct ps3_vuart_port_device *dev) 304int ps3_vuart_enable_interrupt_tx(struct ps3_system_bus_device *dev)
282{ 305{
283 return (dev->priv->interrupt_mask & INTERRUPT_MASK_TX) ? 0 306 struct ps3_vuart_port_priv *priv = to_port_priv(dev);
284 : ps3_vuart_set_interrupt_mask(dev, dev->priv->interrupt_mask 307
308 return (priv->interrupt_mask & INTERRUPT_MASK_TX) ? 0
309 : ps3_vuart_set_interrupt_mask(dev, priv->interrupt_mask
285 | INTERRUPT_MASK_TX); 310 | INTERRUPT_MASK_TX);
286} 311}
287 312
288int ps3_vuart_enable_interrupt_rx(struct ps3_vuart_port_device *dev) 313int ps3_vuart_enable_interrupt_rx(struct ps3_system_bus_device *dev)
289{ 314{
290 return (dev->priv->interrupt_mask & INTERRUPT_MASK_RX) ? 0 315 struct ps3_vuart_port_priv *priv = to_port_priv(dev);
291 : ps3_vuart_set_interrupt_mask(dev, dev->priv->interrupt_mask 316
317 return (priv->interrupt_mask & INTERRUPT_MASK_RX) ? 0
318 : ps3_vuart_set_interrupt_mask(dev, priv->interrupt_mask
292 | INTERRUPT_MASK_RX); 319 | INTERRUPT_MASK_RX);
293} 320}
294 321
295int ps3_vuart_enable_interrupt_disconnect(struct ps3_vuart_port_device *dev) 322int ps3_vuart_enable_interrupt_disconnect(struct ps3_system_bus_device *dev)
296{ 323{
297 return (dev->priv->interrupt_mask & INTERRUPT_MASK_DISCONNECT) ? 0 324 struct ps3_vuart_port_priv *priv = to_port_priv(dev);
298 : ps3_vuart_set_interrupt_mask(dev, dev->priv->interrupt_mask 325
326 return (priv->interrupt_mask & INTERRUPT_MASK_DISCONNECT) ? 0
327 : ps3_vuart_set_interrupt_mask(dev, priv->interrupt_mask
299 | INTERRUPT_MASK_DISCONNECT); 328 | INTERRUPT_MASK_DISCONNECT);
300} 329}
301 330
302int ps3_vuart_disable_interrupt_tx(struct ps3_vuart_port_device *dev) 331int ps3_vuart_disable_interrupt_tx(struct ps3_system_bus_device *dev)
303{ 332{
304 return (dev->priv->interrupt_mask & INTERRUPT_MASK_TX) 333 struct ps3_vuart_port_priv *priv = to_port_priv(dev);
305 ? ps3_vuart_set_interrupt_mask(dev, dev->priv->interrupt_mask 334
335 return (priv->interrupt_mask & INTERRUPT_MASK_TX)
336 ? ps3_vuart_set_interrupt_mask(dev, priv->interrupt_mask
306 & ~INTERRUPT_MASK_TX) : 0; 337 & ~INTERRUPT_MASK_TX) : 0;
307} 338}
308 339
309int ps3_vuart_disable_interrupt_rx(struct ps3_vuart_port_device *dev) 340int ps3_vuart_disable_interrupt_rx(struct ps3_system_bus_device *dev)
310{ 341{
311 return (dev->priv->interrupt_mask & INTERRUPT_MASK_RX) 342 struct ps3_vuart_port_priv *priv = to_port_priv(dev);
312 ? ps3_vuart_set_interrupt_mask(dev, dev->priv->interrupt_mask 343
344 return (priv->interrupt_mask & INTERRUPT_MASK_RX)
345 ? ps3_vuart_set_interrupt_mask(dev, priv->interrupt_mask
313 & ~INTERRUPT_MASK_RX) : 0; 346 & ~INTERRUPT_MASK_RX) : 0;
314} 347}
315 348
316int ps3_vuart_disable_interrupt_disconnect(struct ps3_vuart_port_device *dev) 349int ps3_vuart_disable_interrupt_disconnect(struct ps3_system_bus_device *dev)
317{ 350{
318 return (dev->priv->interrupt_mask & INTERRUPT_MASK_DISCONNECT) 351 struct ps3_vuart_port_priv *priv = to_port_priv(dev);
319 ? ps3_vuart_set_interrupt_mask(dev, dev->priv->interrupt_mask 352
353 return (priv->interrupt_mask & INTERRUPT_MASK_DISCONNECT)
354 ? ps3_vuart_set_interrupt_mask(dev, priv->interrupt_mask
320 & ~INTERRUPT_MASK_DISCONNECT) : 0; 355 & ~INTERRUPT_MASK_DISCONNECT) : 0;
321} 356}
322 357
323/** 358/**
324 * ps3_vuart_raw_write - Low level write helper. 359 * ps3_vuart_raw_write - Low level write helper.
360 * @dev: The struct ps3_system_bus_device instance.
325 * 361 *
326 * Do not call ps3_vuart_raw_write directly, use ps3_vuart_write. 362 * Do not call ps3_vuart_raw_write directly, use ps3_vuart_write.
327 */ 363 */
328 364
329static int ps3_vuart_raw_write(struct ps3_vuart_port_device *dev, 365static int ps3_vuart_raw_write(struct ps3_system_bus_device *dev,
330 const void* buf, unsigned int bytes, unsigned long *bytes_written) 366 const void* buf, unsigned int bytes, unsigned long *bytes_written)
331{ 367{
332 int result; 368 int result;
369 struct ps3_vuart_port_priv *priv = to_port_priv(dev);
333 370
334 result = lv1_write_virtual_uart(dev->priv->port_number, 371 result = lv1_write_virtual_uart(dev->port_number,
335 ps3_mm_phys_to_lpar(__pa(buf)), bytes, bytes_written); 372 ps3_mm_phys_to_lpar(__pa(buf)), bytes, bytes_written);
336 373
337 if (result) { 374 if (result) {
@@ -340,28 +377,30 @@ static int ps3_vuart_raw_write(struct ps3_vuart_port_device *dev,
340 return result; 377 return result;
341 } 378 }
342 379
343 dev->priv->stats.bytes_written += *bytes_written; 380 priv->stats.bytes_written += *bytes_written;
344 381
345 dev_dbg(&dev->core, "%s:%d: wrote %lxh/%xh=>%lxh\n", __func__, __LINE__, 382 dev_dbg(&dev->core, "%s:%d: wrote %lxh/%xh=>%lxh\n", __func__, __LINE__,
346 *bytes_written, bytes, dev->priv->stats.bytes_written); 383 *bytes_written, bytes, priv->stats.bytes_written);
347 384
348 return result; 385 return result;
349} 386}
350 387
351/** 388/**
352 * ps3_vuart_raw_read - Low level read helper. 389 * ps3_vuart_raw_read - Low level read helper.
390 * @dev: The struct ps3_system_bus_device instance.
353 * 391 *
354 * Do not call ps3_vuart_raw_read directly, use ps3_vuart_read. 392 * Do not call ps3_vuart_raw_read directly, use ps3_vuart_read.
355 */ 393 */
356 394
357static int ps3_vuart_raw_read(struct ps3_vuart_port_device *dev, void* buf, 395static int ps3_vuart_raw_read(struct ps3_system_bus_device *dev, void *buf,
358 unsigned int bytes, unsigned long *bytes_read) 396 unsigned int bytes, unsigned long *bytes_read)
359{ 397{
360 int result; 398 int result;
399 struct ps3_vuart_port_priv *priv = to_port_priv(dev);
361 400
362 dev_dbg(&dev->core, "%s:%d: %xh\n", __func__, __LINE__, bytes); 401 dev_dbg(&dev->core, "%s:%d: %xh\n", __func__, __LINE__, bytes);
363 402
364 result = lv1_read_virtual_uart(dev->priv->port_number, 403 result = lv1_read_virtual_uart(dev->port_number,
365 ps3_mm_phys_to_lpar(__pa(buf)), bytes, bytes_read); 404 ps3_mm_phys_to_lpar(__pa(buf)), bytes, bytes_read);
366 405
367 if (result) { 406 if (result) {
@@ -370,25 +409,27 @@ static int ps3_vuart_raw_read(struct ps3_vuart_port_device *dev, void* buf,
370 return result; 409 return result;
371 } 410 }
372 411
373 dev->priv->stats.bytes_read += *bytes_read; 412 priv->stats.bytes_read += *bytes_read;
374 413
375 dev_dbg(&dev->core, "%s:%d: read %lxh/%xh=>%lxh\n", __func__, __LINE__, 414 dev_dbg(&dev->core, "%s:%d: read %lxh/%xh=>%lxh\n", __func__, __LINE__,
376 *bytes_read, bytes, dev->priv->stats.bytes_read); 415 *bytes_read, bytes, priv->stats.bytes_read);
377 416
378 return result; 417 return result;
379} 418}
380 419
381/** 420/**
382 * ps3_vuart_clear_rx_bytes - Discard bytes received. 421 * ps3_vuart_clear_rx_bytes - Discard bytes received.
422 * @dev: The struct ps3_system_bus_device instance.
383 * @bytes: Max byte count to discard, zero = all pending. 423 * @bytes: Max byte count to discard, zero = all pending.
384 * 424 *
385 * Used to clear pending rx interrupt source. Will not block. 425 * Used to clear pending rx interrupt source. Will not block.
386 */ 426 */
387 427
388void ps3_vuart_clear_rx_bytes(struct ps3_vuart_port_device *dev, 428void ps3_vuart_clear_rx_bytes(struct ps3_system_bus_device *dev,
389 unsigned int bytes) 429 unsigned int bytes)
390{ 430{
391 int result; 431 int result;
432 struct ps3_vuart_port_priv *priv = to_port_priv(dev);
392 u64 bytes_waiting; 433 u64 bytes_waiting;
393 void* tmp; 434 void* tmp;
394 435
@@ -418,8 +459,9 @@ void ps3_vuart_clear_rx_bytes(struct ps3_vuart_port_device *dev,
418 459
419 /* Don't include these bytes in the stats. */ 460 /* Don't include these bytes in the stats. */
420 461
421 dev->priv->stats.bytes_read -= bytes_waiting; 462 priv->stats.bytes_read -= bytes_waiting;
422} 463}
464EXPORT_SYMBOL_GPL(ps3_vuart_clear_rx_bytes);
423 465
424/** 466/**
425 * struct list_buffer - An element for a port device fifo buffer list. 467 * struct list_buffer - An element for a port device fifo buffer list.
@@ -435,6 +477,7 @@ struct list_buffer {
435 477
436/** 478/**
437 * ps3_vuart_write - the entry point for writing data to a port 479 * ps3_vuart_write - the entry point for writing data to a port
480 * @dev: The struct ps3_system_bus_device instance.
438 * 481 *
439 * If the port is idle on entry as much of the incoming data is written to 482 * If the port is idle on entry as much of the incoming data is written to
440 * the port as the port will accept. Otherwise a list buffer is created 483 * the port as the port will accept. Otherwise a list buffer is created
@@ -442,25 +485,26 @@ struct list_buffer {
442 * then enqueued for transmision via the transmit interrupt. 485 * then enqueued for transmision via the transmit interrupt.
443 */ 486 */
444 487
445int ps3_vuart_write(struct ps3_vuart_port_device *dev, const void* buf, 488int ps3_vuart_write(struct ps3_system_bus_device *dev, const void *buf,
446 unsigned int bytes) 489 unsigned int bytes)
447{ 490{
448 static unsigned long dbg_number; 491 static unsigned long dbg_number;
449 int result; 492 int result;
493 struct ps3_vuart_port_priv *priv = to_port_priv(dev);
450 unsigned long flags; 494 unsigned long flags;
451 struct list_buffer *lb; 495 struct list_buffer *lb;
452 496
453 dev_dbg(&dev->core, "%s:%d: %u(%xh) bytes\n", __func__, __LINE__, 497 dev_dbg(&dev->core, "%s:%d: %u(%xh) bytes\n", __func__, __LINE__,
454 bytes, bytes); 498 bytes, bytes);
455 499
456 spin_lock_irqsave(&dev->priv->tx_list.lock, flags); 500 spin_lock_irqsave(&priv->tx_list.lock, flags);
457 501
458 if (list_empty(&dev->priv->tx_list.head)) { 502 if (list_empty(&priv->tx_list.head)) {
459 unsigned long bytes_written; 503 unsigned long bytes_written;
460 504
461 result = ps3_vuart_raw_write(dev, buf, bytes, &bytes_written); 505 result = ps3_vuart_raw_write(dev, buf, bytes, &bytes_written);
462 506
463 spin_unlock_irqrestore(&dev->priv->tx_list.lock, flags); 507 spin_unlock_irqrestore(&priv->tx_list.lock, flags);
464 508
465 if (result) { 509 if (result) {
466 dev_dbg(&dev->core, 510 dev_dbg(&dev->core,
@@ -478,7 +522,7 @@ int ps3_vuart_write(struct ps3_vuart_port_device *dev, const void* buf,
478 bytes -= bytes_written; 522 bytes -= bytes_written;
479 buf += bytes_written; 523 buf += bytes_written;
480 } else 524 } else
481 spin_unlock_irqrestore(&dev->priv->tx_list.lock, flags); 525 spin_unlock_irqrestore(&priv->tx_list.lock, flags);
482 526
483 lb = kmalloc(sizeof(struct list_buffer) + bytes, GFP_KERNEL); 527 lb = kmalloc(sizeof(struct list_buffer) + bytes, GFP_KERNEL);
484 528
@@ -491,29 +535,86 @@ int ps3_vuart_write(struct ps3_vuart_port_device *dev, const void* buf,
491 lb->tail = lb->data + bytes; 535 lb->tail = lb->data + bytes;
492 lb->dbg_number = ++dbg_number; 536 lb->dbg_number = ++dbg_number;
493 537
494 spin_lock_irqsave(&dev->priv->tx_list.lock, flags); 538 spin_lock_irqsave(&priv->tx_list.lock, flags);
495 list_add_tail(&lb->link, &dev->priv->tx_list.head); 539 list_add_tail(&lb->link, &priv->tx_list.head);
496 ps3_vuart_enable_interrupt_tx(dev); 540 ps3_vuart_enable_interrupt_tx(dev);
497 spin_unlock_irqrestore(&dev->priv->tx_list.lock, flags); 541 spin_unlock_irqrestore(&priv->tx_list.lock, flags);
498 542
499 dev_dbg(&dev->core, "%s:%d: queued buf_%lu, %xh bytes\n", 543 dev_dbg(&dev->core, "%s:%d: queued buf_%lu, %xh bytes\n",
500 __func__, __LINE__, lb->dbg_number, bytes); 544 __func__, __LINE__, lb->dbg_number, bytes);
501 545
502 return 0; 546 return 0;
503} 547}
548EXPORT_SYMBOL_GPL(ps3_vuart_write);
549
550/**
551 * ps3_vuart_queue_rx_bytes - Queue waiting bytes into the buffer list.
552 * @dev: The struct ps3_system_bus_device instance.
553 * @bytes_queued: Number of bytes queued to the buffer list.
554 *
555 * Must be called with priv->rx_list.lock held.
556 */
557
558static int ps3_vuart_queue_rx_bytes(struct ps3_system_bus_device *dev,
559 u64 *bytes_queued)
560{
561 static unsigned long dbg_number;
562 int result;
563 struct ps3_vuart_port_priv *priv = to_port_priv(dev);
564 struct list_buffer *lb;
565 u64 bytes;
566
567 *bytes_queued = 0;
568
569 result = ps3_vuart_get_rx_bytes_waiting(dev, &bytes);
570 BUG_ON(result);
571
572 if (result)
573 return -EIO;
574
575 if (!bytes)
576 return 0;
577
578 /* Add some extra space for recently arrived data. */
579
580 bytes += 128;
581
582 lb = kmalloc(sizeof(struct list_buffer) + bytes, GFP_ATOMIC);
583
584 if (!lb)
585 return -ENOMEM;
586
587 ps3_vuart_raw_read(dev, lb->data, bytes, &bytes);
588
589 lb->head = lb->data;
590 lb->tail = lb->data + bytes;
591 lb->dbg_number = ++dbg_number;
592
593 list_add_tail(&lb->link, &priv->rx_list.head);
594 priv->rx_list.bytes_held += bytes;
595
596 dev_dbg(&dev->core, "%s:%d: buf_%lu: queued %lxh bytes\n",
597 __func__, __LINE__, lb->dbg_number, bytes);
598
599 *bytes_queued = bytes;
600
601 return 0;
602}
504 603
505/** 604/**
506 * ps3_vuart_read - the entry point for reading data from a port 605 * ps3_vuart_read - The entry point for reading data from a port.
507 * 606 *
508 * If enough bytes to satisfy the request are held in the buffer list those 607 * Queue data waiting at the port, and if enough bytes to satisfy the request
509 * bytes are dequeued and copied to the caller's buffer. Emptied list buffers 608 * are held in the buffer list those bytes are dequeued and copied to the
510 * are retiered. If the request cannot be statified by bytes held in the list 609 * caller's buffer. Emptied list buffers are retiered. If the request cannot
511 * buffers -EAGAIN is returned. 610 * be statified by bytes held in the list buffers -EAGAIN is returned.
512 */ 611 */
513 612
514int ps3_vuart_read(struct ps3_vuart_port_device *dev, void* buf, 613int ps3_vuart_read(struct ps3_system_bus_device *dev, void *buf,
515 unsigned int bytes) 614 unsigned int bytes)
516{ 615{
616 int result;
617 struct ps3_vuart_port_priv *priv = to_port_priv(dev);
517 unsigned long flags; 618 unsigned long flags;
518 struct list_buffer *lb, *n; 619 struct list_buffer *lb, *n;
519 unsigned long bytes_read; 620 unsigned long bytes_read;
@@ -521,30 +622,37 @@ int ps3_vuart_read(struct ps3_vuart_port_device *dev, void* buf,
521 dev_dbg(&dev->core, "%s:%d: %u(%xh) bytes\n", __func__, __LINE__, 622 dev_dbg(&dev->core, "%s:%d: %u(%xh) bytes\n", __func__, __LINE__,
522 bytes, bytes); 623 bytes, bytes);
523 624
524 spin_lock_irqsave(&dev->priv->rx_list.lock, flags); 625 spin_lock_irqsave(&priv->rx_list.lock, flags);
525 626
526 if (dev->priv->rx_list.bytes_held < bytes) { 627 /* Queue rx bytes here for polled reads. */
527 spin_unlock_irqrestore(&dev->priv->rx_list.lock, flags); 628
528 dev_dbg(&dev->core, "%s:%d: starved for %lxh bytes\n", 629 while (priv->rx_list.bytes_held < bytes) {
529 __func__, __LINE__, 630 u64 tmp;
530 bytes - dev->priv->rx_list.bytes_held); 631
531 return -EAGAIN; 632 result = ps3_vuart_queue_rx_bytes(dev, &tmp);
633 if (result || !tmp) {
634 dev_dbg(&dev->core, "%s:%d: starved for %lxh bytes\n",
635 __func__, __LINE__,
636 bytes - priv->rx_list.bytes_held);
637 spin_unlock_irqrestore(&priv->rx_list.lock, flags);
638 return -EAGAIN;
639 }
532 } 640 }
533 641
534 list_for_each_entry_safe(lb, n, &dev->priv->rx_list.head, link) { 642 list_for_each_entry_safe(lb, n, &priv->rx_list.head, link) {
535 bytes_read = min((unsigned int)(lb->tail - lb->head), bytes); 643 bytes_read = min((unsigned int)(lb->tail - lb->head), bytes);
536 644
537 memcpy(buf, lb->head, bytes_read); 645 memcpy(buf, lb->head, bytes_read);
538 buf += bytes_read; 646 buf += bytes_read;
539 bytes -= bytes_read; 647 bytes -= bytes_read;
540 dev->priv->rx_list.bytes_held -= bytes_read; 648 priv->rx_list.bytes_held -= bytes_read;
541 649
542 if (bytes_read < lb->tail - lb->head) { 650 if (bytes_read < lb->tail - lb->head) {
543 lb->head += bytes_read; 651 lb->head += bytes_read;
544 dev_dbg(&dev->core, "%s:%d: buf_%lu: dequeued %lxh " 652 dev_dbg(&dev->core, "%s:%d: buf_%lu: dequeued %lxh "
545 "bytes\n", __func__, __LINE__, lb->dbg_number, 653 "bytes\n", __func__, __LINE__, lb->dbg_number,
546 bytes_read); 654 bytes_read);
547 spin_unlock_irqrestore(&dev->priv->rx_list.lock, flags); 655 spin_unlock_irqrestore(&priv->rx_list.lock, flags);
548 return 0; 656 return 0;
549 } 657 }
550 658
@@ -556,16 +664,32 @@ int ps3_vuart_read(struct ps3_vuart_port_device *dev, void* buf,
556 kfree(lb); 664 kfree(lb);
557 } 665 }
558 666
559 spin_unlock_irqrestore(&dev->priv->rx_list.lock, flags); 667 spin_unlock_irqrestore(&priv->rx_list.lock, flags);
560 return 0; 668 return 0;
561} 669}
670EXPORT_SYMBOL_GPL(ps3_vuart_read);
562 671
563int ps3_vuart_read_async(struct ps3_vuart_port_device *dev, work_func_t func, 672/**
564 unsigned int bytes) 673 * ps3_vuart_work - Asynchronous read handler.
674 */
675
676static void ps3_vuart_work(struct work_struct *work)
677{
678 struct ps3_system_bus_device *dev =
679 ps3_vuart_work_to_system_bus_dev(work);
680 struct ps3_vuart_port_driver *drv =
681 ps3_system_bus_dev_to_vuart_drv(dev);
682
683 BUG_ON(!drv);
684 drv->work(dev);
685}
686
687int ps3_vuart_read_async(struct ps3_system_bus_device *dev, unsigned int bytes)
565{ 688{
689 struct ps3_vuart_port_priv *priv = to_port_priv(dev);
566 unsigned long flags; 690 unsigned long flags;
567 691
568 if(dev->priv->work.trigger) { 692 if (priv->rx_list.work.trigger) {
569 dev_dbg(&dev->core, "%s:%d: warning, multiple calls\n", 693 dev_dbg(&dev->core, "%s:%d: warning, multiple calls\n",
570 __func__, __LINE__); 694 __func__, __LINE__);
571 return -EAGAIN; 695 return -EAGAIN;
@@ -573,30 +697,32 @@ int ps3_vuart_read_async(struct ps3_vuart_port_device *dev, work_func_t func,
573 697
574 BUG_ON(!bytes); 698 BUG_ON(!bytes);
575 699
576 PREPARE_WORK(&dev->priv->work.work, func); 700 PREPARE_WORK(&priv->rx_list.work.work, ps3_vuart_work);
577 701
578 spin_lock_irqsave(&dev->priv->work.lock, flags); 702 spin_lock_irqsave(&priv->rx_list.lock, flags);
579 if(dev->priv->rx_list.bytes_held >= bytes) { 703 if (priv->rx_list.bytes_held >= bytes) {
580 dev_dbg(&dev->core, "%s:%d: schedule_work %xh bytes\n", 704 dev_dbg(&dev->core, "%s:%d: schedule_work %xh bytes\n",
581 __func__, __LINE__, bytes); 705 __func__, __LINE__, bytes);
582 schedule_work(&dev->priv->work.work); 706 schedule_work(&priv->rx_list.work.work);
583 spin_unlock_irqrestore(&dev->priv->work.lock, flags); 707 spin_unlock_irqrestore(&priv->rx_list.lock, flags);
584 return 0; 708 return 0;
585 } 709 }
586 710
587 dev->priv->work.trigger = bytes; 711 priv->rx_list.work.trigger = bytes;
588 spin_unlock_irqrestore(&dev->priv->work.lock, flags); 712 spin_unlock_irqrestore(&priv->rx_list.lock, flags);
589 713
590 dev_dbg(&dev->core, "%s:%d: waiting for %u(%xh) bytes\n", __func__, 714 dev_dbg(&dev->core, "%s:%d: waiting for %u(%xh) bytes\n", __func__,
591 __LINE__, bytes, bytes); 715 __LINE__, bytes, bytes);
592 716
593 return 0; 717 return 0;
594} 718}
719EXPORT_SYMBOL_GPL(ps3_vuart_read_async);
595 720
596void ps3_vuart_cancel_async(struct ps3_vuart_port_device *dev) 721void ps3_vuart_cancel_async(struct ps3_system_bus_device *dev)
597{ 722{
598 dev->priv->work.trigger = 0; 723 to_port_priv(dev)->rx_list.work.trigger = 0;
599} 724}
725EXPORT_SYMBOL_GPL(ps3_vuart_cancel_async);
600 726
601/** 727/**
602 * ps3_vuart_handle_interrupt_tx - third stage transmit interrupt handler 728 * ps3_vuart_handle_interrupt_tx - third stage transmit interrupt handler
@@ -606,18 +732,19 @@ void ps3_vuart_cancel_async(struct ps3_vuart_port_device *dev)
606 * adjusts the final list buffer state for a partial write. 732 * adjusts the final list buffer state for a partial write.
607 */ 733 */
608 734
609static int ps3_vuart_handle_interrupt_tx(struct ps3_vuart_port_device *dev) 735static int ps3_vuart_handle_interrupt_tx(struct ps3_system_bus_device *dev)
610{ 736{
611 int result = 0; 737 int result = 0;
738 struct ps3_vuart_port_priv *priv = to_port_priv(dev);
612 unsigned long flags; 739 unsigned long flags;
613 struct list_buffer *lb, *n; 740 struct list_buffer *lb, *n;
614 unsigned long bytes_total = 0; 741 unsigned long bytes_total = 0;
615 742
616 dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__); 743 dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__);
617 744
618 spin_lock_irqsave(&dev->priv->tx_list.lock, flags); 745 spin_lock_irqsave(&priv->tx_list.lock, flags);
619 746
620 list_for_each_entry_safe(lb, n, &dev->priv->tx_list.head, link) { 747 list_for_each_entry_safe(lb, n, &priv->tx_list.head, link) {
621 748
622 unsigned long bytes_written; 749 unsigned long bytes_written;
623 750
@@ -651,7 +778,7 @@ static int ps3_vuart_handle_interrupt_tx(struct ps3_vuart_port_device *dev)
651 778
652 ps3_vuart_disable_interrupt_tx(dev); 779 ps3_vuart_disable_interrupt_tx(dev);
653port_full: 780port_full:
654 spin_unlock_irqrestore(&dev->priv->tx_list.lock, flags); 781 spin_unlock_irqrestore(&priv->tx_list.lock, flags);
655 dev_dbg(&dev->core, "%s:%d wrote %lxh bytes total\n", 782 dev_dbg(&dev->core, "%s:%d wrote %lxh bytes total\n",
656 __func__, __LINE__, bytes_total); 783 __func__, __LINE__, bytes_total);
657 return result; 784 return result;
@@ -665,60 +792,37 @@ port_full:
665 * buffer list. Buffer list data is dequeued via ps3_vuart_read. 792 * buffer list. Buffer list data is dequeued via ps3_vuart_read.
666 */ 793 */
667 794
668static int ps3_vuart_handle_interrupt_rx(struct ps3_vuart_port_device *dev) 795static int ps3_vuart_handle_interrupt_rx(struct ps3_system_bus_device *dev)
669{ 796{
670 static unsigned long dbg_number; 797 int result;
671 int result = 0; 798 struct ps3_vuart_port_priv *priv = to_port_priv(dev);
672 unsigned long flags; 799 unsigned long flags;
673 struct list_buffer *lb; 800 u64 bytes;
674 unsigned long bytes;
675 801
676 dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__); 802 dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__);
677 803
678 result = ps3_vuart_get_rx_bytes_waiting(dev, &bytes); 804 spin_lock_irqsave(&priv->rx_list.lock, flags);
679 805 result = ps3_vuart_queue_rx_bytes(dev, &bytes);
680 if (result)
681 return -EIO;
682
683 BUG_ON(!bytes);
684
685 /* Add some extra space for recently arrived data. */
686
687 bytes += 128;
688
689 lb = kmalloc(sizeof(struct list_buffer) + bytes, GFP_ATOMIC);
690 806
691 if (!lb) 807 if (result) {
692 return -ENOMEM; 808 spin_unlock_irqrestore(&priv->rx_list.lock, flags);
693 809 return result;
694 ps3_vuart_raw_read(dev, lb->data, bytes, &bytes); 810 }
695
696 lb->head = lb->data;
697 lb->tail = lb->data + bytes;
698 lb->dbg_number = ++dbg_number;
699
700 spin_lock_irqsave(&dev->priv->rx_list.lock, flags);
701 list_add_tail(&lb->link, &dev->priv->rx_list.head);
702 dev->priv->rx_list.bytes_held += bytes;
703 spin_unlock_irqrestore(&dev->priv->rx_list.lock, flags);
704
705 dev_dbg(&dev->core, "%s:%d: buf_%lu: queued %lxh bytes\n",
706 __func__, __LINE__, lb->dbg_number, bytes);
707 811
708 spin_lock_irqsave(&dev->priv->work.lock, flags); 812 if (priv->rx_list.work.trigger && priv->rx_list.bytes_held
709 if(dev->priv->work.trigger 813 >= priv->rx_list.work.trigger) {
710 && dev->priv->rx_list.bytes_held >= dev->priv->work.trigger) {
711 dev_dbg(&dev->core, "%s:%d: schedule_work %lxh bytes\n", 814 dev_dbg(&dev->core, "%s:%d: schedule_work %lxh bytes\n",
712 __func__, __LINE__, dev->priv->work.trigger); 815 __func__, __LINE__, priv->rx_list.work.trigger);
713 dev->priv->work.trigger = 0; 816 priv->rx_list.work.trigger = 0;
714 schedule_work(&dev->priv->work.work); 817 schedule_work(&priv->rx_list.work.work);
715 } 818 }
716 spin_unlock_irqrestore(&dev->priv->work.lock, flags); 819
717 return 0; 820 spin_unlock_irqrestore(&priv->rx_list.lock, flags);
821 return result;
718} 822}
719 823
720static int ps3_vuart_handle_interrupt_disconnect( 824static int ps3_vuart_handle_interrupt_disconnect(
721 struct ps3_vuart_port_device *dev) 825 struct ps3_system_bus_device *dev)
722{ 826{
723 dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__); 827 dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__);
724 BUG_ON("no support"); 828 BUG_ON("no support");
@@ -733,9 +837,10 @@ static int ps3_vuart_handle_interrupt_disconnect(
733 * stage handler after one iteration. 837 * stage handler after one iteration.
734 */ 838 */
735 839
736static int ps3_vuart_handle_port_interrupt(struct ps3_vuart_port_device *dev) 840static int ps3_vuart_handle_port_interrupt(struct ps3_system_bus_device *dev)
737{ 841{
738 int result; 842 int result;
843 struct ps3_vuart_port_priv *priv = to_port_priv(dev);
739 unsigned long status; 844 unsigned long status;
740 845
741 result = ps3_vuart_get_interrupt_status(dev, &status); 846 result = ps3_vuart_get_interrupt_status(dev, &status);
@@ -747,21 +852,21 @@ static int ps3_vuart_handle_port_interrupt(struct ps3_vuart_port_device *dev)
747 status); 852 status);
748 853
749 if (status & INTERRUPT_MASK_DISCONNECT) { 854 if (status & INTERRUPT_MASK_DISCONNECT) {
750 dev->priv->stats.disconnect_interrupts++; 855 priv->stats.disconnect_interrupts++;
751 result = ps3_vuart_handle_interrupt_disconnect(dev); 856 result = ps3_vuart_handle_interrupt_disconnect(dev);
752 if (result) 857 if (result)
753 ps3_vuart_disable_interrupt_disconnect(dev); 858 ps3_vuart_disable_interrupt_disconnect(dev);
754 } 859 }
755 860
756 if (status & INTERRUPT_MASK_TX) { 861 if (status & INTERRUPT_MASK_TX) {
757 dev->priv->stats.tx_interrupts++; 862 priv->stats.tx_interrupts++;
758 result = ps3_vuart_handle_interrupt_tx(dev); 863 result = ps3_vuart_handle_interrupt_tx(dev);
759 if (result) 864 if (result)
760 ps3_vuart_disable_interrupt_tx(dev); 865 ps3_vuart_disable_interrupt_tx(dev);
761 } 866 }
762 867
763 if (status & INTERRUPT_MASK_RX) { 868 if (status & INTERRUPT_MASK_RX) {
764 dev->priv->stats.rx_interrupts++; 869 priv->stats.rx_interrupts++;
765 result = ps3_vuart_handle_interrupt_rx(dev); 870 result = ps3_vuart_handle_interrupt_rx(dev);
766 if (result) 871 if (result)
767 ps3_vuart_disable_interrupt_rx(dev); 872 ps3_vuart_disable_interrupt_rx(dev);
@@ -771,11 +876,11 @@ static int ps3_vuart_handle_port_interrupt(struct ps3_vuart_port_device *dev)
771} 876}
772 877
773struct vuart_bus_priv { 878struct vuart_bus_priv {
774 const struct ports_bmp bmp; 879 struct ports_bmp *bmp;
775 unsigned int virq; 880 unsigned int virq;
776 struct semaphore probe_mutex; 881 struct semaphore probe_mutex;
777 int use_count; 882 int use_count;
778 struct ps3_vuart_port_device *devices[PORT_COUNT]; 883 struct ps3_system_bus_device *devices[PORT_COUNT];
779} static vuart_bus_priv; 884} static vuart_bus_priv;
780 885
781/** 886/**
@@ -788,17 +893,16 @@ struct vuart_bus_priv {
788 893
789static irqreturn_t ps3_vuart_irq_handler(int irq, void *_private) 894static irqreturn_t ps3_vuart_irq_handler(int irq, void *_private)
790{ 895{
791 struct vuart_bus_priv *bus_priv; 896 struct vuart_bus_priv *bus_priv = _private;
792 897
793 BUG_ON(!_private); 898 BUG_ON(!bus_priv);
794 bus_priv = (struct vuart_bus_priv *)_private;
795 899
796 while (1) { 900 while (1) {
797 unsigned int port; 901 unsigned int port;
798 902
799 dump_ports_bmp(&bus_priv->bmp); 903 dump_ports_bmp(bus_priv->bmp);
800 904
801 port = (BITS_PER_LONG - 1) - __ilog2(bus_priv->bmp.status); 905 port = (BITS_PER_LONG - 1) - __ilog2(bus_priv->bmp->status);
802 906
803 if (port == BITS_PER_LONG) 907 if (port == BITS_PER_LONG)
804 break; 908 break;
@@ -812,100 +916,144 @@ static irqreturn_t ps3_vuart_irq_handler(int irq, void *_private)
812 return IRQ_HANDLED; 916 return IRQ_HANDLED;
813} 917}
814 918
815static int ps3_vuart_match(struct device *_dev, struct device_driver *_drv) 919static int ps3_vuart_bus_interrupt_get(void)
816{ 920{
817 int result; 921 int result;
818 struct ps3_vuart_port_driver *drv = to_ps3_vuart_port_driver(_drv);
819 struct ps3_vuart_port_device *dev = to_ps3_vuart_port_device(_dev);
820 922
821 result = dev->match_id == drv->match_id; 923 pr_debug(" -> %s:%d\n", __func__, __LINE__);
924
925 vuart_bus_priv.use_count++;
926
927 BUG_ON(vuart_bus_priv.use_count > 2);
928
929 if (vuart_bus_priv.use_count != 1) {
930 return 0;
931 }
932
933 BUG_ON(vuart_bus_priv.bmp);
934
935 vuart_bus_priv.bmp = kzalloc(sizeof(struct ports_bmp), GFP_KERNEL);
936
937 if (!vuart_bus_priv.bmp) {
938 pr_debug("%s:%d: kzalloc failed.\n", __func__, __LINE__);
939 result = -ENOMEM;
940 goto fail_bmp_malloc;
941 }
942
943 result = ps3_vuart_irq_setup(PS3_BINDING_CPU_ANY, vuart_bus_priv.bmp,
944 &vuart_bus_priv.virq);
945
946 if (result) {
947 pr_debug("%s:%d: ps3_vuart_irq_setup failed (%d)\n",
948 __func__, __LINE__, result);
949 result = -EPERM;
950 goto fail_alloc_irq;
951 }
952
953 result = request_irq(vuart_bus_priv.virq, ps3_vuart_irq_handler,
954 IRQF_DISABLED, "vuart", &vuart_bus_priv);
822 955
823 dev_info(&dev->core, "%s:%d: dev=%u(%s), drv=%u(%s): %s\n", __func__, 956 if (result) {
824 __LINE__, dev->match_id, dev->core.bus_id, drv->match_id, 957 pr_debug("%s:%d: request_irq failed (%d)\n",
825 drv->core.name, (result ? "match" : "miss")); 958 __func__, __LINE__, result);
959 goto fail_request_irq;
960 }
826 961
962 pr_debug(" <- %s:%d: ok\n", __func__, __LINE__);
827 return result; 963 return result;
964
965fail_request_irq:
966 ps3_vuart_irq_destroy(vuart_bus_priv.virq);
967 vuart_bus_priv.virq = NO_IRQ;
968fail_alloc_irq:
969 kfree(vuart_bus_priv.bmp);
970 vuart_bus_priv.bmp = NULL;
971fail_bmp_malloc:
972 vuart_bus_priv.use_count--;
973 pr_debug(" <- %s:%d: failed\n", __func__, __LINE__);
974 return result;
975}
976
977static int ps3_vuart_bus_interrupt_put(void)
978{
979 pr_debug(" -> %s:%d\n", __func__, __LINE__);
980
981 vuart_bus_priv.use_count--;
982
983 BUG_ON(vuart_bus_priv.use_count < 0);
984
985 if (vuart_bus_priv.use_count != 0)
986 return 0;
987
988 free_irq(vuart_bus_priv.virq, &vuart_bus_priv);
989
990 ps3_vuart_irq_destroy(vuart_bus_priv.virq);
991 vuart_bus_priv.virq = NO_IRQ;
992
993 kfree(vuart_bus_priv.bmp);
994 vuart_bus_priv.bmp = NULL;
995
996 pr_debug(" <- %s:%d\n", __func__, __LINE__);
997 return 0;
828} 998}
829 999
830static int ps3_vuart_probe(struct device *_dev) 1000static int ps3_vuart_probe(struct ps3_system_bus_device *dev)
831{ 1001{
832 int result; 1002 int result;
833 unsigned int port_number; 1003 struct ps3_vuart_port_driver *drv;
834 struct ps3_vuart_port_device *dev = to_ps3_vuart_port_device(_dev); 1004 struct ps3_vuart_port_priv *priv = NULL;
835 struct ps3_vuart_port_driver *drv =
836 to_ps3_vuart_port_driver(_dev->driver);
837 1005
838 dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__); 1006 dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__);
839 1007
1008 drv = ps3_system_bus_dev_to_vuart_drv(dev);
1009
1010 dev_dbg(&dev->core, "%s:%d: (%s)\n", __func__, __LINE__,
1011 drv->core.core.name);
1012
840 BUG_ON(!drv); 1013 BUG_ON(!drv);
841 1014
842 down(&vuart_bus_priv.probe_mutex); 1015 if (dev->port_number >= PORT_COUNT) {
1016 BUG();
1017 return -EINVAL;
1018 }
843 1019
844 /* Setup vuart_bus_priv.devices[]. */ 1020 down(&vuart_bus_priv.probe_mutex);
845 1021
846 result = ps3_vuart_match_id_to_port(dev->match_id, 1022 result = ps3_vuart_bus_interrupt_get();
847 &port_number);
848 1023
849 if (result) { 1024 if (result)
850 dev_dbg(&dev->core, "%s:%d: unknown match_id (%d)\n", 1025 goto fail_setup_interrupt;
851 __func__, __LINE__, dev->match_id);
852 result = -EINVAL;
853 goto fail_match;
854 }
855 1026
856 if (vuart_bus_priv.devices[port_number]) { 1027 if (vuart_bus_priv.devices[dev->port_number]) {
857 dev_dbg(&dev->core, "%s:%d: port busy (%d)\n", __func__, 1028 dev_dbg(&dev->core, "%s:%d: port busy (%d)\n", __func__,
858 __LINE__, port_number); 1029 __LINE__, dev->port_number);
859 result = -EBUSY; 1030 result = -EBUSY;
860 goto fail_match; 1031 goto fail_busy;
861 } 1032 }
862 1033
863 vuart_bus_priv.devices[port_number] = dev; 1034 vuart_bus_priv.devices[dev->port_number] = dev;
864 1035
865 /* Setup dev->priv. */ 1036 /* Setup dev->driver_priv. */
866 1037
867 dev->priv = kzalloc(sizeof(struct ps3_vuart_port_priv), GFP_KERNEL); 1038 dev->driver_priv = kzalloc(sizeof(struct ps3_vuart_port_priv),
1039 GFP_KERNEL);
868 1040
869 if (!dev->priv) { 1041 if (!dev->driver_priv) {
870 result = -ENOMEM; 1042 result = -ENOMEM;
871 goto fail_alloc; 1043 goto fail_dev_malloc;
872 } 1044 }
873 1045
874 dev->priv->port_number = port_number; 1046 priv = to_port_priv(dev);
875
876 INIT_LIST_HEAD(&dev->priv->tx_list.head);
877 spin_lock_init(&dev->priv->tx_list.lock);
878 1047
879 INIT_LIST_HEAD(&dev->priv->rx_list.head); 1048 INIT_LIST_HEAD(&priv->tx_list.head);
880 spin_lock_init(&dev->priv->rx_list.lock); 1049 spin_lock_init(&priv->tx_list.lock);
881 1050
882 INIT_WORK(&dev->priv->work.work, NULL); 1051 INIT_LIST_HEAD(&priv->rx_list.head);
883 spin_lock_init(&dev->priv->work.lock); 1052 spin_lock_init(&priv->rx_list.lock);
884 dev->priv->work.trigger = 0;
885 dev->priv->work.dev = dev;
886 1053
887 if (++vuart_bus_priv.use_count == 1) { 1054 INIT_WORK(&priv->rx_list.work.work, NULL);
888 1055 priv->rx_list.work.trigger = 0;
889 result = ps3_vuart_irq_setup(PS3_BINDING_CPU_ANY, 1056 priv->rx_list.work.dev = dev;
890 (void*)&vuart_bus_priv.bmp.status, &vuart_bus_priv.virq);
891
892 if (result) {
893 dev_dbg(&dev->core,
894 "%s:%d: ps3_vuart_irq_setup failed (%d)\n",
895 __func__, __LINE__, result);
896 result = -EPERM;
897 goto fail_alloc_irq;
898 }
899
900 result = request_irq(vuart_bus_priv.virq, ps3_vuart_irq_handler,
901 IRQF_DISABLED, "vuart", &vuart_bus_priv);
902
903 if (result) {
904 dev_info(&dev->core, "%s:%d: request_irq failed (%d)\n",
905 __func__, __LINE__, result);
906 goto fail_request_irq;
907 }
908 }
909 1057
910 /* clear stale pending interrupts */ 1058 /* clear stale pending interrupts */
911 1059
@@ -936,150 +1084,158 @@ static int ps3_vuart_probe(struct device *_dev)
936 1084
937fail_probe: 1085fail_probe:
938 ps3_vuart_set_interrupt_mask(dev, 0); 1086 ps3_vuart_set_interrupt_mask(dev, 0);
939fail_request_irq: 1087 kfree(dev->driver_priv);
940 ps3_vuart_irq_destroy(vuart_bus_priv.virq); 1088 dev->driver_priv = NULL;
941 vuart_bus_priv.virq = NO_IRQ; 1089fail_dev_malloc:
942fail_alloc_irq: 1090 vuart_bus_priv.devices[dev->port_number] = NULL;
943 --vuart_bus_priv.use_count; 1091fail_busy:
944 kfree(dev->priv); 1092 ps3_vuart_bus_interrupt_put();
945 dev->priv = NULL; 1093fail_setup_interrupt:
946fail_alloc:
947 vuart_bus_priv.devices[port_number] = NULL;
948fail_match:
949 up(&vuart_bus_priv.probe_mutex); 1094 up(&vuart_bus_priv.probe_mutex);
950 dev_dbg(&dev->core, "%s:%d failed\n", __func__, __LINE__); 1095 dev_dbg(&dev->core, "%s:%d: failed\n", __func__, __LINE__);
951 return result; 1096 return result;
952} 1097}
953 1098
954static int ps3_vuart_remove(struct device *_dev) 1099/**
1100 * ps3_vuart_cleanup - common cleanup helper.
1101 * @dev: The struct ps3_system_bus_device instance.
1102 *
1103 * Cleans interrupts and HV resources. Must be called with
1104 * vuart_bus_priv.probe_mutex held. Used by ps3_vuart_remove and
1105 * ps3_vuart_shutdown. After this call, polled reading will still work.
1106 */
1107
1108static int ps3_vuart_cleanup(struct ps3_system_bus_device *dev)
955{ 1109{
956 struct ps3_vuart_port_device *dev = to_ps3_vuart_port_device(_dev); 1110 dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__);
957 struct ps3_vuart_port_driver *drv = 1111
958 to_ps3_vuart_port_driver(_dev->driver); 1112 ps3_vuart_cancel_async(dev);
1113 ps3_vuart_set_interrupt_mask(dev, 0);
1114 ps3_vuart_bus_interrupt_put();
1115 return 0;
1116}
1117
1118/**
1119 * ps3_vuart_remove - Completely clean the device instance.
1120 * @dev: The struct ps3_system_bus_device instance.
1121 *
1122 * Cleans all memory, interrupts and HV resources. After this call the
1123 * device can no longer be used.
1124 */
1125
1126static int ps3_vuart_remove(struct ps3_system_bus_device *dev)
1127{
1128 struct ps3_vuart_port_priv *priv = to_port_priv(dev);
1129 struct ps3_vuart_port_driver *drv;
1130
1131 BUG_ON(!dev);
959 1132
960 down(&vuart_bus_priv.probe_mutex); 1133 down(&vuart_bus_priv.probe_mutex);
961 1134
962 dev_dbg(&dev->core, "%s:%d: %s\n", __func__, __LINE__, 1135 dev_dbg(&dev->core, " -> %s:%d: match_id %d\n", __func__, __LINE__,
963 dev->core.bus_id); 1136 dev->match_id);
964 1137
965 BUG_ON(vuart_bus_priv.use_count < 1); 1138 if (!dev->core.driver) {
1139 dev_dbg(&dev->core, "%s:%d: no driver bound\n", __func__,
1140 __LINE__);
1141 up(&vuart_bus_priv.probe_mutex);
1142 return 0;
1143 }
966 1144
967 if (drv->remove) 1145 drv = ps3_system_bus_dev_to_vuart_drv(dev);
968 drv->remove(dev);
969 else
970 dev_dbg(&dev->core, "%s:%d: %s no remove method\n", __func__,
971 __LINE__, dev->core.bus_id);
972 1146
973 vuart_bus_priv.devices[dev->priv->port_number] = NULL; 1147 BUG_ON(!drv);
974 1148
975 if (--vuart_bus_priv.use_count == 0) { 1149 if (drv->remove) {
1150 drv->remove(dev);
1151 } else {
1152 dev_dbg(&dev->core, "%s:%d: no remove method\n", __func__,
1153 __LINE__);
976 BUG(); 1154 BUG();
977 free_irq(vuart_bus_priv.virq, &vuart_bus_priv);
978 ps3_vuart_irq_destroy(vuart_bus_priv.virq);
979 vuart_bus_priv.virq = NO_IRQ;
980 } 1155 }
981 1156
982 kfree(dev->priv); 1157 ps3_vuart_cleanup(dev);
983 dev->priv = NULL; 1158
1159 vuart_bus_priv.devices[dev->port_number] = NULL;
1160 kfree(priv);
1161 priv = NULL;
984 1162
1163 dev_dbg(&dev->core, " <- %s:%d\n", __func__, __LINE__);
985 up(&vuart_bus_priv.probe_mutex); 1164 up(&vuart_bus_priv.probe_mutex);
986 return 0; 1165 return 0;
987} 1166}
988 1167
989static void ps3_vuart_shutdown(struct device *_dev)
990{
991 struct ps3_vuart_port_device *dev = to_ps3_vuart_port_device(_dev);
992 struct ps3_vuart_port_driver *drv =
993 to_ps3_vuart_port_driver(_dev->driver);
994
995 dev_dbg(&dev->core, "%s:%d: %s\n", __func__, __LINE__,
996 dev->core.bus_id);
997
998 if (drv->shutdown)
999 drv->shutdown(dev);
1000 else
1001 dev_dbg(&dev->core, "%s:%d: %s no shutdown method\n", __func__,
1002 __LINE__, dev->core.bus_id);
1003}
1004
1005/** 1168/**
1006 * ps3_vuart_bus - The vuart bus instance. 1169 * ps3_vuart_shutdown - Cleans interrupts and HV resources.
1170 * @dev: The struct ps3_system_bus_device instance.
1007 * 1171 *
1008 * The vuart is managed as a bus that port devices connect to. 1172 * Cleans interrupts and HV resources. After this call the
1173 * device can still be used in polling mode. This behavior required
1174 * by sys-manager to be able to complete the device power operation
1175 * sequence.
1009 */ 1176 */
1010 1177
1011struct bus_type ps3_vuart_bus = { 1178static int ps3_vuart_shutdown(struct ps3_system_bus_device *dev)
1012 .name = "ps3_vuart",
1013 .match = ps3_vuart_match,
1014 .probe = ps3_vuart_probe,
1015 .remove = ps3_vuart_remove,
1016 .shutdown = ps3_vuart_shutdown,
1017};
1018
1019int __init ps3_vuart_bus_init(void)
1020{ 1179{
1021 int result; 1180 struct ps3_vuart_port_driver *drv;
1022 1181
1023 pr_debug("%s:%d:\n", __func__, __LINE__); 1182 BUG_ON(!dev);
1024 1183
1025 if (!firmware_has_feature(FW_FEATURE_PS3_LV1)) 1184 down(&vuart_bus_priv.probe_mutex);
1026 return -ENODEV;
1027 1185
1028 init_MUTEX(&vuart_bus_priv.probe_mutex); 1186 dev_dbg(&dev->core, " -> %s:%d: match_id %d\n", __func__, __LINE__,
1029 result = bus_register(&ps3_vuart_bus); 1187 dev->match_id);
1030 BUG_ON(result);
1031 1188
1032 return result; 1189 if (!dev->core.driver) {
1033} 1190 dev_dbg(&dev->core, "%s:%d: no driver bound\n", __func__,
1191 __LINE__);
1192 up(&vuart_bus_priv.probe_mutex);
1193 return 0;
1194 }
1034 1195
1035void __exit ps3_vuart_bus_exit(void) 1196 drv = ps3_system_bus_dev_to_vuart_drv(dev);
1036{
1037 pr_debug("%s:%d:\n", __func__, __LINE__);
1038 bus_unregister(&ps3_vuart_bus);
1039}
1040 1197
1041core_initcall(ps3_vuart_bus_init); 1198 BUG_ON(!drv);
1042module_exit(ps3_vuart_bus_exit);
1043 1199
1044/** 1200 if (drv->shutdown)
1045 * ps3_vuart_port_release_device - Remove a vuart port device. 1201 drv->shutdown(dev);
1046 */ 1202 else if (drv->remove) {
1203 dev_dbg(&dev->core, "%s:%d: no shutdown, calling remove\n",
1204 __func__, __LINE__);
1205 drv->remove(dev);
1206 } else {
1207 dev_dbg(&dev->core, "%s:%d: no shutdown method\n", __func__,
1208 __LINE__);
1209 BUG();
1210 }
1047 1211
1048static void ps3_vuart_port_release_device(struct device *_dev) 1212 ps3_vuart_cleanup(dev);
1049{
1050#if defined(DEBUG)
1051 struct ps3_vuart_port_device *dev = to_ps3_vuart_port_device(_dev);
1052 1213
1053 dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__); 1214 dev_dbg(&dev->core, " <- %s:%d\n", __func__, __LINE__);
1054 1215
1055 BUG_ON(dev->priv && "forgot to free"); 1216 up(&vuart_bus_priv.probe_mutex);
1056 memset(&dev->core, 0, sizeof(dev->core)); 1217 return 0;
1057#endif
1058} 1218}
1059 1219
1060/** 1220static int __init ps3_vuart_bus_init(void)
1061 * ps3_vuart_port_device_register - Add a vuart port device.
1062 */
1063
1064int ps3_vuart_port_device_register(struct ps3_vuart_port_device *dev)
1065{ 1221{
1066 static unsigned int dev_count = 1; 1222 pr_debug("%s:%d:\n", __func__, __LINE__);
1067
1068 BUG_ON(dev->priv && "forgot to free");
1069 1223
1070 dev->core.parent = NULL; 1224 if (!firmware_has_feature(FW_FEATURE_PS3_LV1))
1071 dev->core.bus = &ps3_vuart_bus; 1225 return -ENODEV;
1072 dev->core.release = ps3_vuart_port_release_device;
1073 1226
1074 snprintf(dev->core.bus_id, sizeof(dev->core.bus_id), "vuart_%02x", 1227 init_MUTEX(&vuart_bus_priv.probe_mutex);
1075 dev_count++);
1076 1228
1077 dev_dbg(&dev->core, "%s:%d register\n", __func__, __LINE__); 1229 return 0;
1230}
1078 1231
1079 return device_register(&dev->core); 1232static void __exit ps3_vuart_bus_exit(void)
1233{
1234 pr_debug("%s:%d:\n", __func__, __LINE__);
1080} 1235}
1081 1236
1082EXPORT_SYMBOL_GPL(ps3_vuart_port_device_register); 1237core_initcall(ps3_vuart_bus_init);
1238module_exit(ps3_vuart_bus_exit);
1083 1239
1084/** 1240/**
1085 * ps3_vuart_port_driver_register - Add a vuart port device driver. 1241 * ps3_vuart_port_driver_register - Add a vuart port device driver.
@@ -1089,12 +1245,18 @@ int ps3_vuart_port_driver_register(struct ps3_vuart_port_driver *drv)
1089{ 1245{
1090 int result; 1246 int result;
1091 1247
1092 pr_debug("%s:%d: (%s)\n", __func__, __LINE__, drv->core.name); 1248 pr_debug("%s:%d: (%s)\n", __func__, __LINE__, drv->core.core.name);
1093 drv->core.bus = &ps3_vuart_bus; 1249
1094 result = driver_register(&drv->core); 1250 BUG_ON(!drv->core.match_id);
1251 BUG_ON(!drv->core.core.name);
1252
1253 drv->core.probe = ps3_vuart_probe;
1254 drv->core.remove = ps3_vuart_remove;
1255 drv->core.shutdown = ps3_vuart_shutdown;
1256
1257 result = ps3_system_bus_driver_register(&drv->core);
1095 return result; 1258 return result;
1096} 1259}
1097
1098EXPORT_SYMBOL_GPL(ps3_vuart_port_driver_register); 1260EXPORT_SYMBOL_GPL(ps3_vuart_port_driver_register);
1099 1261
1100/** 1262/**
@@ -1103,8 +1265,7 @@ EXPORT_SYMBOL_GPL(ps3_vuart_port_driver_register);
1103 1265
1104void ps3_vuart_port_driver_unregister(struct ps3_vuart_port_driver *drv) 1266void ps3_vuart_port_driver_unregister(struct ps3_vuart_port_driver *drv)
1105{ 1267{
1106 pr_debug("%s:%d: (%s)\n", __func__, __LINE__, drv->core.name); 1268 pr_debug("%s:%d: (%s)\n", __func__, __LINE__, drv->core.core.name);
1107 driver_unregister(&drv->core); 1269 ps3_system_bus_driver_unregister(&drv->core);
1108} 1270}
1109
1110EXPORT_SYMBOL_GPL(ps3_vuart_port_driver_unregister); 1271EXPORT_SYMBOL_GPL(ps3_vuart_port_driver_unregister);
diff --git a/drivers/ps3/vuart.h b/drivers/ps3/vuart.h
index 1be992d568c8..eb7f6d94a890 100644
--- a/drivers/ps3/vuart.h
+++ b/drivers/ps3/vuart.h
@@ -34,29 +34,7 @@ struct ps3_vuart_stats {
34struct ps3_vuart_work { 34struct ps3_vuart_work {
35 struct work_struct work; 35 struct work_struct work;
36 unsigned long trigger; 36 unsigned long trigger;
37 spinlock_t lock; 37 struct ps3_system_bus_device *dev; /* to convert work to device */
38 struct ps3_vuart_port_device* dev; /* to convert work to device */
39};
40
41/**
42 * struct ps3_vuart_port_priv - private vuart device data.
43 */
44
45struct ps3_vuart_port_priv {
46 unsigned int port_number;
47 u64 interrupt_mask;
48
49 struct {
50 spinlock_t lock;
51 struct list_head head;
52 } tx_list;
53 struct {
54 unsigned long bytes_held;
55 spinlock_t lock;
56 struct list_head head;
57 } rx_list;
58 struct ps3_vuart_stats stats;
59 struct ps3_vuart_work work;
60}; 38};
61 39
62/** 40/**
@@ -64,32 +42,30 @@ struct ps3_vuart_port_priv {
64 */ 42 */
65 43
66struct ps3_vuart_port_driver { 44struct ps3_vuart_port_driver {
67 enum ps3_match_id match_id; 45 struct ps3_system_bus_driver core;
68 struct device_driver core; 46 int (*probe)(struct ps3_system_bus_device *);
69 int (*probe)(struct ps3_vuart_port_device *); 47 int (*remove)(struct ps3_system_bus_device *);
70 int (*remove)(struct ps3_vuart_port_device *); 48 void (*shutdown)(struct ps3_system_bus_device *);
71 void (*shutdown)(struct ps3_vuart_port_device *); 49 void (*work)(struct ps3_system_bus_device *);
72 int (*tx_event)(struct ps3_vuart_port_device *dev); 50 /* int (*tx_event)(struct ps3_system_bus_device *dev); */
73 int (*rx_event)(struct ps3_vuart_port_device *dev); 51 /* int (*rx_event)(struct ps3_system_bus_device *dev); */
74 int (*disconnect_event)(struct ps3_vuart_port_device *dev); 52 /* int (*disconnect_event)(struct ps3_system_bus_device *dev); */
75 /* int (*suspend)(struct ps3_vuart_port_device *, pm_message_t); */ 53 /* int (*suspend)(struct ps3_system_bus_device *, pm_message_t); */
76 /* int (*resume)(struct ps3_vuart_port_device *); */ 54 /* int (*resume)(struct ps3_system_bus_device *); */
77}; 55};
78 56
79int ps3_vuart_port_driver_register(struct ps3_vuart_port_driver *drv); 57int ps3_vuart_port_driver_register(struct ps3_vuart_port_driver *drv);
80void ps3_vuart_port_driver_unregister(struct ps3_vuart_port_driver *drv); 58void ps3_vuart_port_driver_unregister(struct ps3_vuart_port_driver *drv);
81 59
82static inline struct ps3_vuart_port_driver *to_ps3_vuart_port_driver( 60static inline struct ps3_vuart_port_driver *
83 struct device_driver *_drv) 61 ps3_system_bus_dev_to_vuart_drv(struct ps3_system_bus_device *_dev)
84{
85 return container_of(_drv, struct ps3_vuart_port_driver, core);
86}
87static inline struct ps3_vuart_port_device *to_ps3_vuart_port_device(
88 struct device *_dev)
89{ 62{
90 return container_of(_dev, struct ps3_vuart_port_device, core); 63 struct ps3_system_bus_driver *sbd =
64 ps3_system_bus_dev_to_system_bus_drv(_dev);
65 BUG_ON(!sbd);
66 return container_of(sbd, struct ps3_vuart_port_driver, core);
91} 67}
92static inline struct ps3_vuart_port_device *ps3_vuart_work_to_port_device( 68static inline struct ps3_system_bus_device *ps3_vuart_work_to_system_bus_dev(
93 struct work_struct *_work) 69 struct work_struct *_work)
94{ 70{
95 struct ps3_vuart_work *vw = container_of(_work, struct ps3_vuart_work, 71 struct ps3_vuart_work *vw = container_of(_work, struct ps3_vuart_work,
@@ -97,14 +73,13 @@ static inline struct ps3_vuart_port_device *ps3_vuart_work_to_port_device(
97 return vw->dev; 73 return vw->dev;
98} 74}
99 75
100int ps3_vuart_write(struct ps3_vuart_port_device *dev, const void* buf, 76int ps3_vuart_write(struct ps3_system_bus_device *dev, const void *buf,
101 unsigned int bytes);
102int ps3_vuart_read(struct ps3_vuart_port_device *dev, void* buf,
103 unsigned int bytes); 77 unsigned int bytes);
104int ps3_vuart_read_async(struct ps3_vuart_port_device *dev, work_func_t func, 78int ps3_vuart_read(struct ps3_system_bus_device *dev, void *buf,
105 unsigned int bytes); 79 unsigned int bytes);
106void ps3_vuart_cancel_async(struct ps3_vuart_port_device *dev); 80int ps3_vuart_read_async(struct ps3_system_bus_device *dev, unsigned int bytes);
107void ps3_vuart_clear_rx_bytes(struct ps3_vuart_port_device *dev, 81void ps3_vuart_cancel_async(struct ps3_system_bus_device *dev);
82void ps3_vuart_clear_rx_bytes(struct ps3_system_bus_device *dev,
108 unsigned int bytes); 83 unsigned int bytes);
109 84
110#endif 85#endif
diff --git a/include/asm-powerpc/ps3.h b/include/asm-powerpc/ps3.h
index 4f753907bbf9..433c38eb61ae 100644
--- a/include/asm-powerpc/ps3.h
+++ b/include/asm-powerpc/ps3.h
@@ -407,23 +407,6 @@ static inline void *ps3_system_bus_get_driver_data(
407 407
408extern struct bus_type ps3_system_bus_type; 408extern struct bus_type ps3_system_bus_type;
409 409
410/* vuart routines */
411
412struct ps3_vuart_port_priv;
413
414/**
415 * struct ps3_vuart_port_device - a device on a vuart port
416 */
417
418struct ps3_vuart_port_device {
419 enum ps3_match_id match_id;
420 struct device core;
421 struct ps3_vuart_port_priv* priv; /* private driver variables */
422
423};
424
425int ps3_vuart_port_device_register(struct ps3_vuart_port_device *dev);
426
427/* system manager */ 410/* system manager */
428 411
429#ifdef CONFIG_PS3_SYS_MANAGER 412#ifdef CONFIG_PS3_SYS_MANAGER