aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/block/viodasd.c4
-rw-r--r--drivers/char/briq_panel.c10
-rw-r--r--drivers/char/hvc_console.c2
-rw-r--r--drivers/char/viotape.c12
-rw-r--r--drivers/pci/hotplug/rpadlpar_core.c6
-rw-r--r--drivers/pcmcia/Kconfig17
-rw-r--r--drivers/pcmcia/m8xx_pcmcia.c351
-rw-r--r--drivers/ps3/Makefile5
-rw-r--r--drivers/ps3/ps3av.c372
-rw-r--r--drivers/ps3/ps3av_cmd.c51
-rw-r--r--drivers/ps3/ps3stor_lib.c302
-rw-r--r--drivers/ps3/sys-manager-core.c68
-rw-r--r--drivers/ps3/sys-manager.c290
-rw-r--r--drivers/ps3/vuart.c817
-rw-r--r--drivers/ps3/vuart.h71
-rw-r--r--drivers/rtc/Kconfig2
-rw-r--r--drivers/serial/cpm_uart/cpm_uart_core.c2
-rw-r--r--drivers/serial/of_serial.c33
-rw-r--r--drivers/video/Kconfig4
-rw-r--r--drivers/video/ps3fb.c290
20 files changed, 1638 insertions, 1071 deletions
diff --git a/drivers/block/viodasd.c b/drivers/block/viodasd.c
index 68592c336011..dae39911a11d 100644
--- a/drivers/block/viodasd.c
+++ b/drivers/block/viodasd.c
@@ -252,10 +252,10 @@ static int viodasd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
252 struct gendisk *disk = bdev->bd_disk; 252 struct gendisk *disk = bdev->bd_disk;
253 struct viodasd_device *d = disk->private_data; 253 struct viodasd_device *d = disk->private_data;
254 254
255 geo->sectors = d->sectors ? d->sectors : 0; 255 geo->sectors = d->sectors ? d->sectors : 32;
256 geo->heads = d->tracks ? d->tracks : 64; 256 geo->heads = d->tracks ? d->tracks : 64;
257 geo->cylinders = d->cylinders ? d->cylinders : 257 geo->cylinders = d->cylinders ? d->cylinders :
258 get_capacity(disk) / (geo->cylinders * geo->heads); 258 get_capacity(disk) / (geo->sectors * geo->heads);
259 259
260 return 0; 260 return 0;
261} 261}
diff --git a/drivers/char/briq_panel.c b/drivers/char/briq_panel.c
index ed53f541d9e8..b6f2639f903d 100644
--- a/drivers/char/briq_panel.c
+++ b/drivers/char/briq_panel.c
@@ -91,11 +91,6 @@ static ssize_t briq_panel_read(struct file *file, char __user *buf, size_t count
91 unsigned short c; 91 unsigned short c;
92 unsigned char cp; 92 unsigned char cp;
93 93
94#if 0 /* Can't seek (pread) on this device */
95 if (ppos != &file->f_pos)
96 return -ESPIPE;
97#endif
98
99 if (!vfd_is_open) 94 if (!vfd_is_open)
100 return -ENODEV; 95 return -ENODEV;
101 96
@@ -139,11 +134,6 @@ static ssize_t briq_panel_write(struct file *file, const char __user *buf, size_
139 size_t indx = len; 134 size_t indx = len;
140 int i, esc = 0; 135 int i, esc = 0;
141 136
142#if 0 /* Can't seek (pwrite) on this device */
143 if (ppos != &file->f_pos)
144 return -ESPIPE;
145#endif
146
147 if (!vfd_is_open) 137 if (!vfd_is_open)
148 return -EBUSY; 138 return -EBUSY;
149 139
diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c
index 322bc5f7d86b..b3ab42e0dd4a 100644
--- a/drivers/char/hvc_console.c
+++ b/drivers/char/hvc_console.c
@@ -674,7 +674,7 @@ static const cpumask_t cpus_in_xmon = CPU_MASK_NONE;
674 * calling hvc_poll() who determines whether a console adapter support 674 * calling hvc_poll() who determines whether a console adapter support
675 * interrupts. 675 * interrupts.
676 */ 676 */
677int khvcd(void *unused) 677static int khvcd(void *unused)
678{ 678{
679 int poll_mask; 679 int poll_mask;
680 struct hvc_struct *hp; 680 struct hvc_struct *hp;
diff --git a/drivers/char/viotape.c b/drivers/char/viotape.c
index 13faf8d17482..db57277117bb 100644
--- a/drivers/char/viotape.c
+++ b/drivers/char/viotape.c
@@ -873,12 +873,12 @@ free_op:
873} 873}
874 874
875const struct file_operations viotap_fops = { 875const struct file_operations viotap_fops = {
876 owner: THIS_MODULE, 876 .owner = THIS_MODULE,
877 read: viotap_read, 877 .read = viotap_read,
878 write: viotap_write, 878 .write = viotap_write,
879 ioctl: viotap_ioctl, 879 .ioctl = viotap_ioctl,
880 open: viotap_open, 880 .open = viotap_open,
881 release: viotap_release, 881 .release = viotap_release,
882}; 882};
883 883
884/* Handle interrupt events for tape */ 884/* Handle interrupt events for tape */
diff --git a/drivers/pci/hotplug/rpadlpar_core.c b/drivers/pci/hotplug/rpadlpar_core.c
index bb3c101c2c5a..deb6b5e35feb 100644
--- a/drivers/pci/hotplug/rpadlpar_core.c
+++ b/drivers/pci/hotplug/rpadlpar_core.c
@@ -159,8 +159,8 @@ static void dlpar_pci_add_bus(struct device_node *dn)
159 /* Claim new bus resources */ 159 /* Claim new bus resources */
160 pcibios_claim_one_bus(dev->bus); 160 pcibios_claim_one_bus(dev->bus);
161 161
162 /* ioremap() for child bus, which may or may not succeed */ 162 /* Map IO space for child bus, which may or may not succeed */
163 remap_bus_range(dev->subordinate); 163 pcibios_map_io_space(dev->subordinate);
164 164
165 /* Add new devices to global lists. Register in proc, sysfs. */ 165 /* Add new devices to global lists. Register in proc, sysfs. */
166 pci_bus_add_devices(phb->bus); 166 pci_bus_add_devices(phb->bus);
@@ -390,7 +390,7 @@ int dlpar_remove_pci_slot(char *drc_name, struct device_node *dn)
390 } else 390 } else
391 pcibios_remove_pci_devices(bus); 391 pcibios_remove_pci_devices(bus);
392 392
393 if (unmap_bus_range(bus)) { 393 if (pcibios_unmap_io_space(bus)) {
394 printk(KERN_ERR "%s: failed to unmap bus range\n", 394 printk(KERN_ERR "%s: failed to unmap bus range\n",
395 __FUNCTION__); 395 __FUNCTION__);
396 return -ERANGE; 396 return -ERANGE;
diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig
index 35f88649d3b7..c0c77f82d051 100644
--- a/drivers/pcmcia/Kconfig
+++ b/drivers/pcmcia/Kconfig
@@ -180,14 +180,15 @@ config TCIC
180 PCMCIA cards are plugged into. If unsure, say N. 180 PCMCIA cards are plugged into. If unsure, say N.
181 181
182config PCMCIA_M8XX 182config PCMCIA_M8XX
183 tristate "MPC8xx PCMCIA support" 183 tristate "MPC8xx PCMCIA support"
184 depends on PCMCIA && PPC && 8xx 184 depends on PCMCIA && PPC && 8xx
185 select PCCARD_IODYN 185 select PCCARD_IODYN
186 help 186 select PCCARD_NONSTATIC
187 Say Y here to include support for PowerPC 8xx series PCMCIA 187 help
188 controller. 188 Say Y here to include support for PowerPC 8xx series PCMCIA
189 189 controller.
190 This driver is also available as a module called m8xx_pcmcia. 190
191 This driver is also available as a module called m8xx_pcmcia.
191 192
192config HD64465_PCMCIA 193config HD64465_PCMCIA
193 tristate "HD64465 host bridge support" 194 tristate "HD64465 host bridge support"
diff --git a/drivers/pcmcia/m8xx_pcmcia.c b/drivers/pcmcia/m8xx_pcmcia.c
index 9721ed7bf502..3b40f9623cc9 100644
--- a/drivers/pcmcia/m8xx_pcmcia.c
+++ b/drivers/pcmcia/m8xx_pcmcia.c
@@ -10,7 +10,7 @@
10 * Further fixes, v2.6 kernel port 10 * Further fixes, v2.6 kernel port
11 * <marcelo.tosatti@cyclades.com> 11 * <marcelo.tosatti@cyclades.com>
12 * 12 *
13 * Some fixes, additions (C) 2005 Montavista Software, Inc. 13 * Some fixes, additions (C) 2005-2007 Montavista Software, Inc.
14 * <vbordug@ru.mvista.com> 14 * <vbordug@ru.mvista.com>
15 * 15 *
16 * "The ExCA standard specifies that socket controllers should provide 16 * "The ExCA standard specifies that socket controllers should provide
@@ -40,10 +40,6 @@
40#include <linux/fcntl.h> 40#include <linux/fcntl.h>
41#include <linux/string.h> 41#include <linux/string.h>
42 42
43#include <asm/io.h>
44#include <asm/bitops.h>
45#include <asm/system.h>
46
47#include <linux/kernel.h> 43#include <linux/kernel.h>
48#include <linux/errno.h> 44#include <linux/errno.h>
49#include <linux/slab.h> 45#include <linux/slab.h>
@@ -51,11 +47,18 @@
51#include <linux/ioport.h> 47#include <linux/ioport.h>
52#include <linux/delay.h> 48#include <linux/delay.h>
53#include <linux/interrupt.h> 49#include <linux/interrupt.h>
54#include <linux/platform_device.h> 50#include <linux/fsl_devices.h>
55 51
52#include <asm/io.h>
53#include <asm/bitops.h>
54#include <asm/system.h>
55#include <asm/time.h>
56#include <asm/mpc8xx.h> 56#include <asm/mpc8xx.h>
57#include <asm/8xx_immap.h> 57#include <asm/8xx_immap.h>
58#include <asm/irq.h> 58#include <asm/irq.h>
59#include <asm/fs_pd.h>
60#include <asm/of_device.h>
61#include <asm/of_platform.h>
59 62
60#include <pcmcia/version.h> 63#include <pcmcia/version.h>
61#include <pcmcia/cs_types.h> 64#include <pcmcia/cs_types.h>
@@ -146,27 +149,17 @@ MODULE_LICENSE("Dual MPL/GPL");
146#define PCMCIA_MEM_WIN_BASE 0xe0000000 /* base address for memory window 0 */ 149#define PCMCIA_MEM_WIN_BASE 0xe0000000 /* base address for memory window 0 */
147#define PCMCIA_MEM_WIN_SIZE 0x04000000 /* each memory window is 64 MByte */ 150#define PCMCIA_MEM_WIN_SIZE 0x04000000 /* each memory window is 64 MByte */
148#define PCMCIA_IO_WIN_BASE _IO_BASE /* base address for io window 0 */ 151#define PCMCIA_IO_WIN_BASE _IO_BASE /* base address for io window 0 */
149
150#define PCMCIA_SCHLVL PCMCIA_INTERRUPT /* Status Change Interrupt Level */
151
152/* ------------------------------------------------------------------------- */ 152/* ------------------------------------------------------------------------- */
153 153
154/* 2.4.x and newer has this always in HZ */ 154static int pcmcia_schlvl;
155#define M8XX_BUSFREQ ((((bd_t *)&(__res))->bi_busfreq))
156
157static int pcmcia_schlvl = PCMCIA_SCHLVL;
158 155
159static DEFINE_SPINLOCK(events_lock); 156static DEFINE_SPINLOCK(events_lock);
160 157
161
162#define PCMCIA_SOCKET_KEY_5V 1 158#define PCMCIA_SOCKET_KEY_5V 1
163#define PCMCIA_SOCKET_KEY_LV 2 159#define PCMCIA_SOCKET_KEY_LV 2
164 160
165/* look up table for pgcrx registers */ 161/* look up table for pgcrx registers */
166static u32 *m8xx_pgcrx[2] = { 162static u32 *m8xx_pgcrx[2];
167 &((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pgcra,
168 &((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pgcrb
169};
170 163
171/* 164/*
172 * This structure is used to address each window in the PCMCIA controller. 165 * This structure is used to address each window in the PCMCIA controller.
@@ -228,11 +221,16 @@ struct event_table {
228 u32 eventbit; 221 u32 eventbit;
229}; 222};
230 223
224static const char driver_name[] = "m8xx-pcmcia";
225
231struct socket_info { 226struct socket_info {
232 void (*handler)(void *info, u32 events); 227 void (*handler)(void *info, u32 events);
233 void *info; 228 void *info;
234 229
235 u32 slot; 230 u32 slot;
231 pcmconf8xx_t *pcmcia;
232 u32 bus_freq;
233 int hwirq;
236 234
237 socket_state_t state; 235 socket_state_t state;
238 struct pccard_mem_map mem_win[PCMCIA_MEM_WIN_NO]; 236 struct pccard_mem_map mem_win[PCMCIA_MEM_WIN_NO];
@@ -408,78 +406,21 @@ static void hardware_disable(int slot)
408#if defined(CONFIG_MPC885ADS) 406#if defined(CONFIG_MPC885ADS)
409 407
410#define PCMCIA_BOARD_MSG "MPC885ADS" 408#define PCMCIA_BOARD_MSG "MPC885ADS"
409#define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
411 410
412static int voltage_set(int slot, int vcc, int vpp) 411static inline void hardware_enable(int slot)
413{ 412{
414 u32 reg = 0; 413 m8xx_pcmcia_ops.hw_ctrl(slot, 1);
415 unsigned *bcsr_io;
416
417 bcsr_io = ioremap(BCSR1, sizeof(unsigned long));
418
419 switch(vcc) {
420 case 0:
421 break;
422 case 33:
423 reg |= BCSR1_PCCVCC0;
424 break;
425 case 50:
426 reg |= BCSR1_PCCVCC1;
427 break;
428 default:
429 goto out_unmap;
430 }
431
432 switch(vpp) {
433 case 0:
434 break;
435 case 33:
436 case 50:
437 if(vcc == vpp)
438 reg |= BCSR1_PCCVPP1;
439 else
440 goto out_unmap;
441 break;
442 case 120:
443 if ((vcc == 33) || (vcc == 50))
444 reg |= BCSR1_PCCVPP0;
445 else
446 goto out_unmap;
447 default:
448 goto out_unmap;
449 }
450
451 /* first, turn off all power */
452 out_be32(bcsr_io, in_be32(bcsr_io) & ~(BCSR1_PCCVCC_MASK | BCSR1_PCCVPP_MASK));
453
454 /* enable new powersettings */
455 out_be32(bcsr_io, in_be32(bcsr_io) | reg);
456
457 iounmap(bcsr_io);
458 return 0;
459
460out_unmap:
461 iounmap(bcsr_io);
462 return 1;
463} 414}
464 415
465#define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V 416static inline void hardware_disable(int slot)
466
467static void hardware_enable(int slot)
468{ 417{
469 unsigned *bcsr_io; 418 m8xx_pcmcia_ops.hw_ctrl(slot, 0);
470
471 bcsr_io = ioremap(BCSR1, sizeof(unsigned long));
472 out_be32(bcsr_io, in_be32(bcsr_io) & ~BCSR1_PCCEN);
473 iounmap(bcsr_io);
474} 419}
475 420
476static void hardware_disable(int slot) 421static inline int voltage_set(int slot, int vcc, int vpp)
477{ 422{
478 unsigned *bcsr_io; 423 return m8xx_pcmcia_ops.voltage_set(slot, vcc, vpp);
479
480 bcsr_io = ioremap(BCSR1, sizeof(unsigned long));
481 out_be32(bcsr_io, in_be32(bcsr_io) | BCSR1_PCCEN);
482 iounmap(bcsr_io);
483} 424}
484 425
485#endif 426#endif
@@ -604,48 +545,6 @@ static int voltage_set(int slot, int vcc, int vpp)
604 545
605#endif /* CONFIG_PRxK */ 546#endif /* CONFIG_PRxK */
606 547
607static void m8xx_shutdown(void)
608{
609 u32 m, i;
610 struct pcmcia_win *w;
611
612 for(i = 0; i < PCMCIA_SOCKETS_NO; i++){
613 w = (void *) &((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pbr0;
614
615 out_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pscr, M8XX_PCMCIA_MASK(i));
616 out_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per, in_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per) & ~M8XX_PCMCIA_MASK(i));
617
618 /* turn off interrupt and disable CxOE */
619 out_be32(M8XX_PGCRX(i), M8XX_PGCRX_CXOE);
620
621 /* turn off memory windows */
622 for(m = 0; m < PCMCIA_MEM_WIN_NO; m++) {
623 out_be32(&w->or, 0); /* set to not valid */
624 w++;
625 }
626
627 /* turn off voltage */
628 voltage_set(i, 0, 0);
629
630 /* disable external hardware */
631 hardware_disable(i);
632 }
633
634 free_irq(pcmcia_schlvl, NULL);
635}
636
637static struct device_driver m8xx_driver = {
638 .name = "m8xx-pcmcia",
639 .bus = &platform_bus_type,
640 .suspend = pcmcia_socket_dev_suspend,
641 .resume = pcmcia_socket_dev_resume,
642};
643
644static struct platform_device m8xx_device = {
645 .name = "m8xx-pcmcia",
646 .id = 0,
647};
648
649static u32 pending_events[PCMCIA_SOCKETS_NO]; 548static u32 pending_events[PCMCIA_SOCKETS_NO];
650static DEFINE_SPINLOCK(pending_event_lock); 549static DEFINE_SPINLOCK(pending_event_lock);
651 550
@@ -654,13 +553,14 @@ static irqreturn_t m8xx_interrupt(int irq, void *dev)
654 struct socket_info *s; 553 struct socket_info *s;
655 struct event_table *e; 554 struct event_table *e;
656 unsigned int i, events, pscr, pipr, per; 555 unsigned int i, events, pscr, pipr, per;
556 pcmconf8xx_t *pcmcia = socket[0].pcmcia;
657 557
658 dprintk("Interrupt!\n"); 558 dprintk("Interrupt!\n");
659 /* get interrupt sources */ 559 /* get interrupt sources */
660 560
661 pscr = in_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pscr); 561 pscr = in_be32(&pcmcia->pcmc_pscr);
662 pipr = in_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pipr); 562 pipr = in_be32(&pcmcia->pcmc_pipr);
663 per = in_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per); 563 per = in_be32(&pcmcia->pcmc_per);
664 564
665 for(i = 0; i < PCMCIA_SOCKETS_NO; i++) { 565 for(i = 0; i < PCMCIA_SOCKETS_NO; i++) {
666 s = &socket[i]; 566 s = &socket[i];
@@ -724,7 +624,7 @@ static irqreturn_t m8xx_interrupt(int irq, void *dev)
724 per &= ~M8XX_PCMCIA_RDY_L(0); 624 per &= ~M8XX_PCMCIA_RDY_L(0);
725 per &= ~M8XX_PCMCIA_RDY_L(1); 625 per &= ~M8XX_PCMCIA_RDY_L(1);
726 626
727 out_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per, per); 627 out_be32(&pcmcia->pcmc_per, per);
728 628
729 if (events) 629 if (events)
730 pcmcia_parse_events(&socket[i].socket, events); 630 pcmcia_parse_events(&socket[i].socket, events);
@@ -732,7 +632,7 @@ static irqreturn_t m8xx_interrupt(int irq, void *dev)
732 } 632 }
733 633
734 /* clear the interrupt sources */ 634 /* clear the interrupt sources */
735 out_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pscr, pscr); 635 out_be32(&pcmcia->pcmc_pscr, pscr);
736 636
737 dprintk("Interrupt done.\n"); 637 dprintk("Interrupt done.\n");
738 638
@@ -753,7 +653,7 @@ static u32 m8xx_get_graycode(u32 size)
753 return k; 653 return k;
754} 654}
755 655
756static u32 m8xx_get_speed(u32 ns, u32 is_io) 656static u32 m8xx_get_speed(u32 ns, u32 is_io, u32 bus_freq)
757{ 657{
758 u32 reg, clocks, psst, psl, psht; 658 u32 reg, clocks, psst, psl, psht;
759 659
@@ -781,7 +681,7 @@ static u32 m8xx_get_speed(u32 ns, u32 is_io)
781 681
782#define ADJ 180 /* 80 % longer accesstime - to be sure */ 682#define ADJ 180 /* 80 % longer accesstime - to be sure */
783 683
784 clocks = ((M8XX_BUSFREQ / 1000) * ns) / 1000; 684 clocks = ((bus_freq / 1000) * ns) / 1000;
785 clocks = (clocks * ADJ) / (100*1000); 685 clocks = (clocks * ADJ) / (100*1000);
786 if(clocks >= PCMCIA_BMT_LIMIT) { 686 if(clocks >= PCMCIA_BMT_LIMIT) {
787 printk( "Max access time limit reached\n"); 687 printk( "Max access time limit reached\n");
@@ -806,8 +706,9 @@ static int m8xx_get_status(struct pcmcia_socket *sock, unsigned int *value)
806 int lsock = container_of(sock, struct socket_info, socket)->slot; 706 int lsock = container_of(sock, struct socket_info, socket)->slot;
807 struct socket_info *s = &socket[lsock]; 707 struct socket_info *s = &socket[lsock];
808 unsigned int pipr, reg; 708 unsigned int pipr, reg;
709 pcmconf8xx_t *pcmcia = s->pcmcia;
809 710
810 pipr = in_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pipr); 711 pipr = in_be32(&pcmcia->pcmc_pipr);
811 712
812 *value = ((pipr & (M8XX_PCMCIA_CD1(lsock) 713 *value = ((pipr & (M8XX_PCMCIA_CD1(lsock)
813 | M8XX_PCMCIA_CD2(lsock))) == 0) ? SS_DETECT : 0; 714 | M8XX_PCMCIA_CD2(lsock))) == 0) ? SS_DETECT : 0;
@@ -918,6 +819,7 @@ static int m8xx_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
918 struct event_table *e; 819 struct event_table *e;
919 unsigned int reg; 820 unsigned int reg;
920 unsigned long flags; 821 unsigned long flags;
822 pcmconf8xx_t *pcmcia = socket[0].pcmcia;
921 823
922 dprintk( "SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, " 824 dprintk( "SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
923 "io_irq %d, csc_mask %#2.2x)\n", lsock, state->flags, 825 "io_irq %d, csc_mask %#2.2x)\n", lsock, state->flags,
@@ -927,6 +829,7 @@ static int m8xx_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
927 if(voltage_set(lsock, state->Vcc, state->Vpp)) 829 if(voltage_set(lsock, state->Vcc, state->Vpp))
928 return -EINVAL; 830 return -EINVAL;
929 831
832
930 /* Take care of reset... */ 833 /* Take care of reset... */
931 if(state->flags & SS_RESET) 834 if(state->flags & SS_RESET)
932 out_be32(M8XX_PGCRX(lsock), in_be32(M8XX_PGCRX(lsock)) | M8XX_PGCRX_CXRESET); /* active high */ 835 out_be32(M8XX_PGCRX(lsock), in_be32(M8XX_PGCRX(lsock)) | M8XX_PGCRX_CXRESET); /* active high */
@@ -982,7 +885,8 @@ static int m8xx_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
982 * If io_irq is non-zero we should enable irq. 885 * If io_irq is non-zero we should enable irq.
983 */ 886 */
984 if(state->io_irq) { 887 if(state->io_irq) {
985 out_be32(M8XX_PGCRX(lsock), in_be32(M8XX_PGCRX(lsock)) | mk_int_int_mask(state->io_irq) << 24); 888 out_be32(M8XX_PGCRX(lsock),
889 in_be32(M8XX_PGCRX(lsock)) | mk_int_int_mask(s->hwirq) << 24);
986 /* 890 /*
987 * Strange thing here: 891 * Strange thing here:
988 * The manual does not tell us which interrupt 892 * The manual does not tell us which interrupt
@@ -1027,7 +931,7 @@ static int m8xx_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
1027 * Writing ones will clear the bits. 931 * Writing ones will clear the bits.
1028 */ 932 */
1029 933
1030 out_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pscr, reg); 934 out_be32(&pcmcia->pcmc_pscr, reg);
1031 935
1032 /* 936 /*
1033 * Write the mask. 937 * Write the mask.
@@ -1036,15 +940,8 @@ static int m8xx_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
1036 * Ones will enable the interrupt. 940 * Ones will enable the interrupt.
1037 */ 941 */
1038 942
1039 /* 943 reg |= in_be32(&pcmcia->pcmc_per) & (M8XX_PCMCIA_MASK(0) | M8XX_PCMCIA_MASK(1));
1040 reg |= ((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per 944 out_be32(&pcmcia->pcmc_per, reg);
1041 & M8XX_PCMCIA_MASK(lsock);
1042 */
1043
1044 reg |= in_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per) &
1045 (M8XX_PCMCIA_MASK(0) | M8XX_PCMCIA_MASK(1));
1046
1047 out_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per, reg);
1048 945
1049 spin_unlock_irqrestore(&events_lock, flags); 946 spin_unlock_irqrestore(&events_lock, flags);
1050 947
@@ -1062,6 +959,8 @@ static int m8xx_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *io)
1062 struct socket_info *s = &socket[lsock]; 959 struct socket_info *s = &socket[lsock];
1063 struct pcmcia_win *w; 960 struct pcmcia_win *w;
1064 unsigned int reg, winnr; 961 unsigned int reg, winnr;
962 pcmconf8xx_t *pcmcia = s->pcmcia;
963
1065 964
1066#define M8XX_SIZE (io->stop - io->start + 1) 965#define M8XX_SIZE (io->stop - io->start + 1)
1067#define M8XX_BASE (PCMCIA_IO_WIN_BASE + io->start) 966#define M8XX_BASE (PCMCIA_IO_WIN_BASE + io->start)
@@ -1086,7 +985,7 @@ static int m8xx_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *io)
1086 985
1087 /* setup registers */ 986 /* setup registers */
1088 987
1089 w = (void *) &((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pbr0; 988 w = (void *) &pcmcia->pcmc_pbr0;
1090 w += winnr; 989 w += winnr;
1091 990
1092 out_be32(&w->or, 0); /* turn off window first */ 991 out_be32(&w->or, 0); /* turn off window first */
@@ -1095,12 +994,13 @@ static int m8xx_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *io)
1095 reg <<= 27; 994 reg <<= 27;
1096 reg |= M8XX_PCMCIA_POR_IO |(lsock << 2); 995 reg |= M8XX_PCMCIA_POR_IO |(lsock << 2);
1097 996
1098 reg |= m8xx_get_speed(io->speed, 1); 997 reg |= m8xx_get_speed(io->speed, 1, s->bus_freq);
1099 998
1100 if(io->flags & MAP_WRPROT) 999 if(io->flags & MAP_WRPROT)
1101 reg |= M8XX_PCMCIA_POR_WRPROT; 1000 reg |= M8XX_PCMCIA_POR_WRPROT;
1102 1001
1103 if(io->flags & (MAP_16BIT | MAP_AUTOSZ)) 1002 /*if(io->flags & (MAP_16BIT | MAP_AUTOSZ))*/
1003 if(io->flags & MAP_16BIT)
1104 reg |= M8XX_PCMCIA_POR_16BIT; 1004 reg |= M8XX_PCMCIA_POR_16BIT;
1105 1005
1106 if(io->flags & MAP_ACTIVE) 1006 if(io->flags & MAP_ACTIVE)
@@ -1117,7 +1017,7 @@ static int m8xx_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *io)
1117 1017
1118 /* setup registers */ 1018 /* setup registers */
1119 1019
1120 w = (void *) &((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pbr0; 1020 w = (void *) &pcmcia->pcmc_pbr0;
1121 w += winnr; 1021 w += winnr;
1122 1022
1123 out_be32(&w->or, 0); /* turn off window */ 1023 out_be32(&w->or, 0); /* turn off window */
@@ -1144,6 +1044,7 @@ static int m8xx_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map *m
1144 struct pcmcia_win *w; 1044 struct pcmcia_win *w;
1145 struct pccard_mem_map *old; 1045 struct pccard_mem_map *old;
1146 unsigned int reg, winnr; 1046 unsigned int reg, winnr;
1047 pcmconf8xx_t *pcmcia = s->pcmcia;
1147 1048
1148 dprintk( "SetMemMap(%d, %d, %#2.2x, %d ns, " 1049 dprintk( "SetMemMap(%d, %d, %#2.2x, %d ns, "
1149 "%#5.5lx, %#5.5x)\n", lsock, mem->map, mem->flags, 1050 "%#5.5lx, %#5.5x)\n", lsock, mem->map, mem->flags,
@@ -1166,12 +1067,12 @@ static int m8xx_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map *m
1166 1067
1167 /* Setup the window in the pcmcia controller */ 1068 /* Setup the window in the pcmcia controller */
1168 1069
1169 w = (void *) &((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pbr0; 1070 w = (void *) &pcmcia->pcmc_pbr0;
1170 w += winnr; 1071 w += winnr;
1171 1072
1172 reg |= lsock << 2; 1073 reg |= lsock << 2;
1173 1074
1174 reg |= m8xx_get_speed(mem->speed, 0); 1075 reg |= m8xx_get_speed(mem->speed, 0, s->bus_freq);
1175 1076
1176 if(mem->flags & MAP_ATTRIB) 1077 if(mem->flags & MAP_ATTRIB)
1177 reg |= M8XX_PCMCIA_POR_ATTRMEM; 1078 reg |= M8XX_PCMCIA_POR_ATTRMEM;
@@ -1236,60 +1137,69 @@ static int m8xx_sock_init(struct pcmcia_socket *sock)
1236 1137
1237} 1138}
1238 1139
1239static int m8xx_suspend(struct pcmcia_socket *sock) 1140static int m8xx_sock_suspend(struct pcmcia_socket *sock)
1240{ 1141{
1241 return m8xx_set_socket(sock, &dead_socket); 1142 return m8xx_set_socket(sock, &dead_socket);
1242} 1143}
1243 1144
1244static struct pccard_operations m8xx_services = { 1145static struct pccard_operations m8xx_services = {
1245 .init = m8xx_sock_init, 1146 .init = m8xx_sock_init,
1246 .suspend = m8xx_suspend, 1147 .suspend = m8xx_sock_suspend,
1247 .get_status = m8xx_get_status, 1148 .get_status = m8xx_get_status,
1248 .set_socket = m8xx_set_socket, 1149 .set_socket = m8xx_set_socket,
1249 .set_io_map = m8xx_set_io_map, 1150 .set_io_map = m8xx_set_io_map,
1250 .set_mem_map = m8xx_set_mem_map, 1151 .set_mem_map = m8xx_set_mem_map,
1251}; 1152};
1252 1153
1253static int __init m8xx_init(void) 1154static int __init m8xx_probe(struct of_device *ofdev, const struct of_device_id *match)
1254{ 1155{
1255 struct pcmcia_win *w; 1156 struct pcmcia_win *w;
1256 unsigned int i,m; 1157 unsigned int i, m, hwirq;
1158 pcmconf8xx_t *pcmcia;
1159 int status;
1160 struct device_node *np = ofdev->node;
1257 1161
1258 pcmcia_info("%s\n", version); 1162 pcmcia_info("%s\n", version);
1259 1163
1260 if (driver_register(&m8xx_driver)) 1164 pcmcia = of_iomap(np, 0);
1261 return -1; 1165 if(pcmcia == NULL)
1166 return -EINVAL;
1167
1168 pcmcia_schlvl = irq_of_parse_and_map(np, 0);
1169 hwirq = irq_map[pcmcia_schlvl].hwirq;
1170 if (pcmcia_schlvl < 0)
1171 return -EINVAL;
1172
1173 m8xx_pgcrx[0] = &pcmcia->pcmc_pgcra;
1174 m8xx_pgcrx[1] = &pcmcia->pcmc_pgcrb;
1175
1262 1176
1263 pcmcia_info(PCMCIA_BOARD_MSG " using " PCMCIA_SLOT_MSG 1177 pcmcia_info(PCMCIA_BOARD_MSG " using " PCMCIA_SLOT_MSG
1264 " with IRQ %u.\n", pcmcia_schlvl); 1178 " with IRQ %u (%d). \n", pcmcia_schlvl, hwirq);
1265 1179
1266 /* Configure Status change interrupt */ 1180 /* Configure Status change interrupt */
1267 1181
1268 if(request_irq(pcmcia_schlvl, m8xx_interrupt, 0, 1182 if(request_irq(pcmcia_schlvl, m8xx_interrupt, IRQF_SHARED,
1269 "m8xx_pcmcia", NULL)) { 1183 driver_name, socket)) {
1270 pcmcia_error("Cannot allocate IRQ %u for SCHLVL!\n", 1184 pcmcia_error("Cannot allocate IRQ %u for SCHLVL!\n",
1271 pcmcia_schlvl); 1185 pcmcia_schlvl);
1272 return -1; 1186 return -1;
1273 } 1187 }
1274 1188
1275 w = (void *) &((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pbr0; 1189 w = (void *) &pcmcia->pcmc_pbr0;
1276
1277 out_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pscr,
1278 M8XX_PCMCIA_MASK(0)| M8XX_PCMCIA_MASK(1));
1279 1190
1280 out_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per, 1191 out_be32(&pcmcia->pcmc_pscr, M8XX_PCMCIA_MASK(0)| M8XX_PCMCIA_MASK(1));
1281 in_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per) & 1192 clrbits32(&pcmcia->pcmc_per, M8XX_PCMCIA_MASK(0) | M8XX_PCMCIA_MASK(1));
1282 ~(M8XX_PCMCIA_MASK(0)| M8XX_PCMCIA_MASK(1)));
1283 1193
1284/* connect interrupt and disable CxOE */ 1194 /* connect interrupt and disable CxOE */
1285 1195
1286 out_be32(M8XX_PGCRX(0), M8XX_PGCRX_CXOE | (mk_int_int_mask(pcmcia_schlvl) << 16)); 1196 out_be32(M8XX_PGCRX(0), M8XX_PGCRX_CXOE | (mk_int_int_mask(hwirq) << 16));
1287 out_be32(M8XX_PGCRX(1), M8XX_PGCRX_CXOE | (mk_int_int_mask(pcmcia_schlvl) << 16)); 1197 out_be32(M8XX_PGCRX(1), M8XX_PGCRX_CXOE | (mk_int_int_mask(hwirq) << 16));
1288 1198
1289/* intialize the fixed memory windows */ 1199 /* intialize the fixed memory windows */
1290 1200
1291 for(i = 0; i < PCMCIA_SOCKETS_NO; i++){ 1201 for(i = 0; i < PCMCIA_SOCKETS_NO; i++){
1292 for(m = 0; m < PCMCIA_MEM_WIN_NO; m++) { 1202 for (m = 0; m < PCMCIA_MEM_WIN_NO; m++) {
1293 out_be32(&w->br, PCMCIA_MEM_WIN_BASE + 1203 out_be32(&w->br, PCMCIA_MEM_WIN_BASE +
1294 (PCMCIA_MEM_WIN_SIZE 1204 (PCMCIA_MEM_WIN_SIZE
1295 * (m + i * PCMCIA_MEM_WIN_NO))); 1205 * (m + i * PCMCIA_MEM_WIN_NO)));
@@ -1300,16 +1210,14 @@ static int __init m8xx_init(void)
1300 } 1210 }
1301 } 1211 }
1302 1212
1303/* turn off voltage */ 1213 /* turn off voltage */
1304 voltage_set(0, 0, 0); 1214 voltage_set(0, 0, 0);
1305 voltage_set(1, 0, 0); 1215 voltage_set(1, 0, 0);
1306 1216
1307/* Enable external hardware */ 1217 /* Enable external hardware */
1308 hardware_enable(0); 1218 hardware_enable(0);
1309 hardware_enable(1); 1219 hardware_enable(1);
1310 1220
1311 platform_device_register(&m8xx_device);
1312
1313 for (i = 0 ; i < PCMCIA_SOCKETS_NO; i++) { 1221 for (i = 0 ; i < PCMCIA_SOCKETS_NO; i++) {
1314 socket[i].slot = i; 1222 socket[i].slot = i;
1315 socket[i].socket.owner = THIS_MODULE; 1223 socket[i].socket.owner = THIS_MODULE;
@@ -1317,30 +1225,105 @@ static int __init m8xx_init(void)
1317 socket[i].socket.irq_mask = 0x000; 1225 socket[i].socket.irq_mask = 0x000;
1318 socket[i].socket.map_size = 0x1000; 1226 socket[i].socket.map_size = 0x1000;
1319 socket[i].socket.io_offset = 0; 1227 socket[i].socket.io_offset = 0;
1320 socket[i].socket.pci_irq = i ? 7 : 9; 1228 socket[i].socket.pci_irq = pcmcia_schlvl;
1321 socket[i].socket.ops = &m8xx_services; 1229 socket[i].socket.ops = &m8xx_services;
1322 socket[i].socket.resource_ops = &pccard_iodyn_ops; 1230 socket[i].socket.resource_ops = &pccard_nonstatic_ops;
1323 socket[i].socket.cb_dev = NULL; 1231 socket[i].socket.cb_dev = NULL;
1324 socket[i].socket.dev.parent = &m8xx_device.dev; 1232 socket[i].socket.dev.parent = &ofdev->dev;
1233 socket[i].pcmcia = pcmcia;
1234 socket[i].bus_freq = ppc_proc_freq;
1235 socket[i].hwirq = hwirq;
1236
1237
1325 } 1238 }
1326 1239
1327 for (i = 0; i < PCMCIA_SOCKETS_NO; i++) 1240 for (i = 0; i < PCMCIA_SOCKETS_NO; i++) {
1328 pcmcia_register_socket(&socket[i].socket); 1241 status = pcmcia_register_socket(&socket[i].socket);
1242 if (status < 0)
1243 pcmcia_error("Socket register failed\n");
1244 }
1329 1245
1330 return 0; 1246 return 0;
1331} 1247}
1332 1248
1333static void __exit m8xx_exit(void) 1249static int m8xx_remove(struct of_device* ofdev)
1334{ 1250{
1335 int i; 1251 u32 m, i;
1252 struct pcmcia_win *w;
1253 pcmconf8xx_t *pcmcia = socket[0].pcmcia;
1254
1255 for (i = 0; i < PCMCIA_SOCKETS_NO; i++) {
1256 w = (void *) &pcmcia->pcmc_pbr0;
1257
1258 out_be32(&pcmcia->pcmc_pscr, M8XX_PCMCIA_MASK(i));
1259 out_be32(&pcmcia->pcmc_per,
1260 in_be32(&pcmcia->pcmc_per) & ~M8XX_PCMCIA_MASK(i));
1336 1261
1262 /* turn off interrupt and disable CxOE */
1263 out_be32(M8XX_PGCRX(i), M8XX_PGCRX_CXOE);
1264
1265 /* turn off memory windows */
1266 for (m = 0; m < PCMCIA_MEM_WIN_NO; m++) {
1267 out_be32(&w->or, 0); /* set to not valid */
1268 w++;
1269 }
1270
1271 /* turn off voltage */
1272 voltage_set(i, 0, 0);
1273
1274 /* disable external hardware */
1275 hardware_disable(i);
1276 }
1337 for (i = 0; i < PCMCIA_SOCKETS_NO; i++) 1277 for (i = 0; i < PCMCIA_SOCKETS_NO; i++)
1338 pcmcia_unregister_socket(&socket[i].socket); 1278 pcmcia_unregister_socket(&socket[i].socket);
1339 1279
1340 m8xx_shutdown(); 1280 free_irq(pcmcia_schlvl, NULL);
1341 1281
1342 platform_device_unregister(&m8xx_device); 1282 return 0;
1343 driver_unregister(&m8xx_driver); 1283}
1284
1285#ifdef CONFIG_PM
1286static int m8xx_suspend(struct platform_device *pdev, pm_message_t state)
1287{
1288 return pcmcia_socket_dev_suspend(&pdev->dev, state);
1289}
1290
1291static int m8xx_resume(struct platform_device *pdev)
1292{
1293 return pcmcia_socket_dev_resume(&pdev->dev);
1294}
1295#else
1296#define m8xx_suspend NULL
1297#define m8xx_resume NULL
1298#endif
1299
1300static struct of_device_id m8xx_pcmcia_match[] = {
1301 {
1302 .type = "pcmcia",
1303 .compatible = "fsl,pq-pcmcia",
1304 },
1305 {},
1306};
1307
1308MODULE_DEVICE_TABLE(of, m8xx_pcmcia_match);
1309
1310static struct of_platform_driver m8xx_pcmcia_driver = {
1311 .name = (char *) driver_name,
1312 .match_table = m8xx_pcmcia_match,
1313 .probe = m8xx_probe,
1314 .remove = m8xx_remove,
1315 .suspend = m8xx_suspend,
1316 .resume = m8xx_resume,
1317};
1318
1319static int __init m8xx_init(void)
1320{
1321 return of_register_platform_driver(&m8xx_pcmcia_driver);
1322}
1323
1324static void __exit m8xx_exit(void)
1325{
1326 of_unregister_platform_driver(&m8xx_pcmcia_driver);
1344} 1327}
1345 1328
1346module_init(m8xx_init); 1329module_init(m8xx_init);
diff --git a/drivers/ps3/Makefile b/drivers/ps3/Makefile
index e251d1c1171c..746031de2195 100644
--- a/drivers/ps3/Makefile
+++ b/drivers/ps3/Makefile
@@ -1,3 +1,6 @@
1obj-$(CONFIG_PS3_VUART) += vuart.o 1obj-$(CONFIG_PS3_VUART) += vuart.o
2obj-$(CONFIG_PS3_PS3AV) += ps3av.o ps3av_cmd.o 2obj-$(CONFIG_PS3_PS3AV) += ps3av_mod.o
3ps3av_mod-objs += ps3av.o ps3av_cmd.o
4obj-$(CONFIG_PPC_PS3) += sys-manager-core.o
3obj-$(CONFIG_PS3_SYS_MANAGER) += sys-manager.o 5obj-$(CONFIG_PS3_SYS_MANAGER) += sys-manager.o
6obj-$(CONFIG_PS3_STORAGE) += ps3stor_lib.o
diff --git a/drivers/ps3/ps3av.c b/drivers/ps3/ps3av.c
index 1393e64335f9..85e21614f868 100644
--- a/drivers/ps3/ps3av.c
+++ b/drivers/ps3/ps3av.c
@@ -1,32 +1,30 @@
1/* 1/*
2 * Copyright (C) 2006 Sony Computer Entertainment Inc. 2 * PS3 AV backend support.
3 * Copyright 2006, 2007 Sony Corporation
4 * 3 *
5 * AV backend support for PS3 4 * Copyright (C) 2007 Sony Computer Entertainment Inc.
5 * Copyright 2007 Sony Corp.
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify it 7 * This program is free software; you can redistribute it and/or modify
8 * under the terms of the GNU General Public License as published 8 * it under the terms of the GNU General Public License as published by
9 * by the Free Software Foundation; version 2 of the License. 9 * the Free Software Foundation; version 2 of the License.
10 * 10 *
11 * This program is distributed in the hope that it will be useful, but 11 * This program is distributed in the hope that it will be useful,
12 * WITHOUT ANY WARRANTY; without even the implied warranty of 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * General Public License for more details. 14 * GNU General Public License for more details.
15 * 15 *
16 * You should have received a copy of the GNU General Public License along 16 * You should have received a copy of the GNU General Public License
17 * with this program; if not, write to the Free Software Foundation, Inc., 17 * along with this program; if not, write to the Free Software
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */ 19 */
20 20
21#include <linux/kernel.h>
21#include <linux/module.h> 22#include <linux/module.h>
22#include <linux/delay.h> 23#include <linux/delay.h>
23#include <linux/notifier.h> 24#include <linux/notifier.h>
24#include <linux/reboot.h>
25#include <linux/kernel.h>
26#include <linux/ioctl.h> 25#include <linux/ioctl.h>
27 26
28#include <asm/firmware.h> 27#include <asm/firmware.h>
29#include <asm/lv1call.h>
30#include <asm/ps3av.h> 28#include <asm/ps3av.h>
31#include <asm/ps3.h> 29#include <asm/ps3.h>
32 30
@@ -39,13 +37,12 @@ static int timeout = 5000; /* in msec ( 5 sec ) */
39module_param(timeout, int, 0644); 37module_param(timeout, int, 0644);
40 38
41static struct ps3av { 39static struct ps3av {
42 int available;
43 struct mutex mutex; 40 struct mutex mutex;
44 struct work_struct work; 41 struct work_struct work;
45 struct completion done; 42 struct completion done;
46 struct workqueue_struct *wq; 43 struct workqueue_struct *wq;
47 int open_count; 44 int open_count;
48 struct ps3_vuart_port_device *dev; 45 struct ps3_system_bus_device *dev;
49 46
50 int region; 47 int region;
51 struct ps3av_pkt_av_get_hw_conf av_hw_conf; 48 struct ps3av_pkt_av_get_hw_conf av_hw_conf;
@@ -55,11 +52,13 @@ static struct ps3av {
55 u32 audio_port; 52 u32 audio_port;
56 int ps3av_mode; 53 int ps3av_mode;
57 int ps3av_mode_old; 54 int ps3av_mode_old;
58} ps3av; 55 union {
59 56 struct ps3av_reply_hdr reply_hdr;
60static struct ps3_vuart_port_device ps3av_dev = { 57 u8 raw[PS3AV_BUF_SIZE];
61 .match_id = PS3_MATCH_ID_AV_SETTINGS 58 } recv_buf;
62}; 59 void (*flip_ctl)(int on, void *data);
60 void *flip_data;
61} *ps3av;
63 62
64/* color space */ 63/* color space */
65#define YUV444 PS3AV_CMD_VIDEO_CS_YUV444_8 64#define YUV444 PS3AV_CMD_VIDEO_CS_YUV444_8
@@ -169,7 +168,7 @@ static int ps3av_parse_event_packet(const struct ps3av_reply_hdr *hdr)
169 if (hdr->cid & PS3AV_EVENT_CMD_MASK) { 168 if (hdr->cid & PS3AV_EVENT_CMD_MASK) {
170 table = ps3av_search_cmd_table(hdr->cid, PS3AV_EVENT_CMD_MASK); 169 table = ps3av_search_cmd_table(hdr->cid, PS3AV_EVENT_CMD_MASK);
171 if (table) 170 if (table)
172 dev_dbg(&ps3av_dev.core, 171 dev_dbg(&ps3av->dev->core,
173 "recv event packet cid:%08x port:0x%x size:%d\n", 172 "recv event packet cid:%08x port:0x%x size:%d\n",
174 hdr->cid, ps3av_event_get_port_id(hdr->cid), 173 hdr->cid, ps3av_event_get_port_id(hdr->cid),
175 hdr->size); 174 hdr->size);
@@ -182,6 +181,41 @@ static int ps3av_parse_event_packet(const struct ps3av_reply_hdr *hdr)
182 return 0; 181 return 0;
183} 182}
184 183
184
185#define POLLING_INTERVAL 25 /* in msec */
186
187static int ps3av_vuart_write(struct ps3_system_bus_device *dev,
188 const void *buf, unsigned long size)
189{
190 int error;
191 dev_dbg(&dev->core, " -> %s:%d\n", __func__, __LINE__);
192 error = ps3_vuart_write(dev, buf, size);
193 dev_dbg(&dev->core, " <- %s:%d\n", __func__, __LINE__);
194 return error ? error : size;
195}
196
197static int ps3av_vuart_read(struct ps3_system_bus_device *dev, void *buf,
198 unsigned long size, int timeout)
199{
200 int error;
201 int loopcnt = 0;
202
203 dev_dbg(&dev->core, " -> %s:%d\n", __func__, __LINE__);
204 timeout = (timeout + POLLING_INTERVAL - 1) / POLLING_INTERVAL;
205 while (loopcnt++ <= timeout) {
206 error = ps3_vuart_read(dev, buf, size);
207 if (!error)
208 return size;
209 if (error != -EAGAIN) {
210 printk(KERN_ERR "%s: ps3_vuart_read failed %d\n",
211 __func__, error);
212 return error;
213 }
214 msleep(POLLING_INTERVAL);
215 }
216 return -EWOULDBLOCK;
217}
218
185static int ps3av_send_cmd_pkt(const struct ps3av_send_hdr *send_buf, 219static int ps3av_send_cmd_pkt(const struct ps3av_send_hdr *send_buf,
186 struct ps3av_reply_hdr *recv_buf, int write_len, 220 struct ps3av_reply_hdr *recv_buf, int write_len,
187 int read_len) 221 int read_len)
@@ -190,13 +224,13 @@ static int ps3av_send_cmd_pkt(const struct ps3av_send_hdr *send_buf,
190 u32 cmd; 224 u32 cmd;
191 int event; 225 int event;
192 226
193 if (!ps3av.available) 227 if (!ps3av)
194 return -ENODEV; 228 return -ENODEV;
195 229
196 /* send pkt */ 230 /* send pkt */
197 res = ps3av_vuart_write(ps3av.dev, send_buf, write_len); 231 res = ps3av_vuart_write(ps3av->dev, send_buf, write_len);
198 if (res < 0) { 232 if (res < 0) {
199 dev_dbg(&ps3av_dev.core, 233 dev_dbg(&ps3av->dev->core,
200 "%s: ps3av_vuart_write() failed (result=%d)\n", 234 "%s: ps3av_vuart_write() failed (result=%d)\n",
201 __func__, res); 235 __func__, res);
202 return res; 236 return res;
@@ -206,20 +240,20 @@ static int ps3av_send_cmd_pkt(const struct ps3av_send_hdr *send_buf,
206 cmd = send_buf->cid; 240 cmd = send_buf->cid;
207 do { 241 do {
208 /* read header */ 242 /* read header */
209 res = ps3av_vuart_read(ps3av.dev, recv_buf, PS3AV_HDR_SIZE, 243 res = ps3av_vuart_read(ps3av->dev, recv_buf, PS3AV_HDR_SIZE,
210 timeout); 244 timeout);
211 if (res != PS3AV_HDR_SIZE) { 245 if (res != PS3AV_HDR_SIZE) {
212 dev_dbg(&ps3av_dev.core, 246 dev_dbg(&ps3av->dev->core,
213 "%s: ps3av_vuart_read() failed (result=%d)\n", 247 "%s: ps3av_vuart_read() failed (result=%d)\n",
214 __func__, res); 248 __func__, res);
215 return res; 249 return res;
216 } 250 }
217 251
218 /* read body */ 252 /* read body */
219 res = ps3av_vuart_read(ps3av.dev, &recv_buf->cid, 253 res = ps3av_vuart_read(ps3av->dev, &recv_buf->cid,
220 recv_buf->size, timeout); 254 recv_buf->size, timeout);
221 if (res < 0) { 255 if (res < 0) {
222 dev_dbg(&ps3av_dev.core, 256 dev_dbg(&ps3av->dev->core,
223 "%s: ps3av_vuart_read() failed (result=%d)\n", 257 "%s: ps3av_vuart_read() failed (result=%d)\n",
224 __func__, res); 258 __func__, res);
225 return res; 259 return res;
@@ -230,7 +264,7 @@ static int ps3av_send_cmd_pkt(const struct ps3av_send_hdr *send_buf,
230 } while (event); 264 } while (event);
231 265
232 if ((cmd | PS3AV_REPLY_BIT) != recv_buf->cid) { 266 if ((cmd | PS3AV_REPLY_BIT) != recv_buf->cid) {
233 dev_dbg(&ps3av_dev.core, "%s: reply err (result=%x)\n", 267 dev_dbg(&ps3av->dev->core, "%s: reply err (result=%x)\n",
234 __func__, recv_buf->cid); 268 __func__, recv_buf->cid);
235 return -EINVAL; 269 return -EINVAL;
236 } 270 }
@@ -245,7 +279,7 @@ static int ps3av_process_reply_packet(struct ps3av_send_hdr *cmd_buf,
245 int return_len; 279 int return_len;
246 280
247 if (recv_buf->version != PS3AV_VERSION) { 281 if (recv_buf->version != PS3AV_VERSION) {
248 dev_dbg(&ps3av_dev.core, "reply_packet invalid version:%x\n", 282 dev_dbg(&ps3av->dev->core, "reply_packet invalid version:%x\n",
249 recv_buf->version); 283 recv_buf->version);
250 return -EFAULT; 284 return -EFAULT;
251 } 285 }
@@ -267,16 +301,11 @@ int ps3av_do_pkt(u32 cid, u16 send_len, size_t usr_buf_size,
267 struct ps3av_send_hdr *buf) 301 struct ps3av_send_hdr *buf)
268{ 302{
269 int res = 0; 303 int res = 0;
270 static union {
271 struct ps3av_reply_hdr reply_hdr;
272 u8 raw[PS3AV_BUF_SIZE];
273 } recv_buf;
274
275 u32 *table; 304 u32 *table;
276 305
277 BUG_ON(!ps3av.available); 306 BUG_ON(!ps3av);
278 307
279 mutex_lock(&ps3av.mutex); 308 mutex_lock(&ps3av->mutex);
280 309
281 table = ps3av_search_cmd_table(cid, PS3AV_CID_MASK); 310 table = ps3av_search_cmd_table(cid, PS3AV_CID_MASK);
282 BUG_ON(!table); 311 BUG_ON(!table);
@@ -288,7 +317,7 @@ int ps3av_do_pkt(u32 cid, u16 send_len, size_t usr_buf_size,
288 ps3av_set_hdr(cid, send_len, buf); 317 ps3av_set_hdr(cid, send_len, buf);
289 318
290 /* send packet via vuart */ 319 /* send packet via vuart */
291 res = ps3av_send_cmd_pkt(buf, &recv_buf.reply_hdr, send_len, 320 res = ps3av_send_cmd_pkt(buf, &ps3av->recv_buf.reply_hdr, send_len,
292 usr_buf_size); 321 usr_buf_size);
293 if (res < 0) { 322 if (res < 0) {
294 printk(KERN_ERR 323 printk(KERN_ERR
@@ -298,7 +327,7 @@ int ps3av_do_pkt(u32 cid, u16 send_len, size_t usr_buf_size,
298 } 327 }
299 328
300 /* process reply packet */ 329 /* process reply packet */
301 res = ps3av_process_reply_packet(buf, &recv_buf.reply_hdr, 330 res = ps3av_process_reply_packet(buf, &ps3av->recv_buf.reply_hdr,
302 usr_buf_size); 331 usr_buf_size);
303 if (res < 0) { 332 if (res < 0) {
304 printk(KERN_ERR "%s: put_return_status() failed (result=%d)\n", 333 printk(KERN_ERR "%s: put_return_status() failed (result=%d)\n",
@@ -306,11 +335,11 @@ int ps3av_do_pkt(u32 cid, u16 send_len, size_t usr_buf_size,
306 goto err; 335 goto err;
307 } 336 }
308 337
309 mutex_unlock(&ps3av.mutex); 338 mutex_unlock(&ps3av->mutex);
310 return 0; 339 return 0;
311 340
312 err: 341 err:
313 mutex_unlock(&ps3av.mutex); 342 mutex_unlock(&ps3av->mutex);
314 printk(KERN_ERR "%s: failed cid:%x res:%d\n", __func__, cid, res); 343 printk(KERN_ERR "%s: failed cid:%x res:%d\n", __func__, cid, res);
315 return res; 344 return res;
316} 345}
@@ -319,11 +348,11 @@ static int ps3av_set_av_video_mute(u32 mute)
319{ 348{
320 int i, num_of_av_port, res; 349 int i, num_of_av_port, res;
321 350
322 num_of_av_port = ps3av.av_hw_conf.num_of_hdmi + 351 num_of_av_port = ps3av->av_hw_conf.num_of_hdmi +
323 ps3av.av_hw_conf.num_of_avmulti; 352 ps3av->av_hw_conf.num_of_avmulti;
324 /* video mute on */ 353 /* video mute on */
325 for (i = 0; i < num_of_av_port; i++) { 354 for (i = 0; i < num_of_av_port; i++) {
326 res = ps3av_cmd_av_video_mute(1, &ps3av.av_port[i], mute); 355 res = ps3av_cmd_av_video_mute(1, &ps3av->av_port[i], mute);
327 if (res < 0) 356 if (res < 0)
328 return -1; 357 return -1;
329 } 358 }
@@ -335,13 +364,13 @@ static int ps3av_set_video_disable_sig(void)
335{ 364{
336 int i, num_of_hdmi_port, num_of_av_port, res; 365 int i, num_of_hdmi_port, num_of_av_port, res;
337 366
338 num_of_hdmi_port = ps3av.av_hw_conf.num_of_hdmi; 367 num_of_hdmi_port = ps3av->av_hw_conf.num_of_hdmi;
339 num_of_av_port = ps3av.av_hw_conf.num_of_hdmi + 368 num_of_av_port = ps3av->av_hw_conf.num_of_hdmi +
340 ps3av.av_hw_conf.num_of_avmulti; 369 ps3av->av_hw_conf.num_of_avmulti;
341 370
342 /* tv mute */ 371 /* tv mute */
343 for (i = 0; i < num_of_hdmi_port; i++) { 372 for (i = 0; i < num_of_hdmi_port; i++) {
344 res = ps3av_cmd_av_tv_mute(ps3av.av_port[i], 373 res = ps3av_cmd_av_tv_mute(ps3av->av_port[i],
345 PS3AV_CMD_MUTE_ON); 374 PS3AV_CMD_MUTE_ON);
346 if (res < 0) 375 if (res < 0)
347 return -1; 376 return -1;
@@ -350,11 +379,11 @@ static int ps3av_set_video_disable_sig(void)
350 379
351 /* video mute on */ 380 /* video mute on */
352 for (i = 0; i < num_of_av_port; i++) { 381 for (i = 0; i < num_of_av_port; i++) {
353 res = ps3av_cmd_av_video_disable_sig(ps3av.av_port[i]); 382 res = ps3av_cmd_av_video_disable_sig(ps3av->av_port[i]);
354 if (res < 0) 383 if (res < 0)
355 return -1; 384 return -1;
356 if (i < num_of_hdmi_port) { 385 if (i < num_of_hdmi_port) {
357 res = ps3av_cmd_av_tv_mute(ps3av.av_port[i], 386 res = ps3av_cmd_av_tv_mute(ps3av->av_port[i],
358 PS3AV_CMD_MUTE_OFF); 387 PS3AV_CMD_MUTE_OFF);
359 if (res < 0) 388 if (res < 0)
360 return -1; 389 return -1;
@@ -369,17 +398,17 @@ static int ps3av_set_audio_mute(u32 mute)
369{ 398{
370 int i, num_of_av_port, num_of_opt_port, res; 399 int i, num_of_av_port, num_of_opt_port, res;
371 400
372 num_of_av_port = ps3av.av_hw_conf.num_of_hdmi + 401 num_of_av_port = ps3av->av_hw_conf.num_of_hdmi +
373 ps3av.av_hw_conf.num_of_avmulti; 402 ps3av->av_hw_conf.num_of_avmulti;
374 num_of_opt_port = ps3av.av_hw_conf.num_of_spdif; 403 num_of_opt_port = ps3av->av_hw_conf.num_of_spdif;
375 404
376 for (i = 0; i < num_of_av_port; i++) { 405 for (i = 0; i < num_of_av_port; i++) {
377 res = ps3av_cmd_av_audio_mute(1, &ps3av.av_port[i], mute); 406 res = ps3av_cmd_av_audio_mute(1, &ps3av->av_port[i], mute);
378 if (res < 0) 407 if (res < 0)
379 return -1; 408 return -1;
380 } 409 }
381 for (i = 0; i < num_of_opt_port; i++) { 410 for (i = 0; i < num_of_opt_port; i++) {
382 res = ps3av_cmd_audio_mute(1, &ps3av.opt_port[i], mute); 411 res = ps3av_cmd_audio_mute(1, &ps3av->opt_port[i], mute);
383 if (res < 0) 412 if (res < 0)
384 return -1; 413 return -1;
385 } 414 }
@@ -394,40 +423,40 @@ int ps3av_set_audio_mode(u32 ch, u32 fs, u32 word_bits, u32 format, u32 source)
394 struct ps3av_pkt_audio_mode audio_mode; 423 struct ps3av_pkt_audio_mode audio_mode;
395 u32 len = 0; 424 u32 len = 0;
396 425
397 num_of_audio = ps3av.av_hw_conf.num_of_hdmi + 426 num_of_audio = ps3av->av_hw_conf.num_of_hdmi +
398 ps3av.av_hw_conf.num_of_avmulti + 427 ps3av->av_hw_conf.num_of_avmulti +
399 ps3av.av_hw_conf.num_of_spdif; 428 ps3av->av_hw_conf.num_of_spdif;
400 429
401 avb_param.num_of_video_pkt = 0; 430 avb_param.num_of_video_pkt = 0;
402 avb_param.num_of_audio_pkt = PS3AV_AVB_NUM_AUDIO; /* always 0 */ 431 avb_param.num_of_audio_pkt = PS3AV_AVB_NUM_AUDIO; /* always 0 */
403 avb_param.num_of_av_video_pkt = 0; 432 avb_param.num_of_av_video_pkt = 0;
404 avb_param.num_of_av_audio_pkt = ps3av.av_hw_conf.num_of_hdmi; 433 avb_param.num_of_av_audio_pkt = ps3av->av_hw_conf.num_of_hdmi;
405 434
406 vid = video_mode_table[ps3av.ps3av_mode].vid; 435 vid = video_mode_table[ps3av->ps3av_mode].vid;
407 436
408 /* audio mute */ 437 /* audio mute */
409 ps3av_set_audio_mute(PS3AV_CMD_MUTE_ON); 438 ps3av_set_audio_mute(PS3AV_CMD_MUTE_ON);
410 439
411 /* audio inactive */ 440 /* audio inactive */
412 res = ps3av_cmd_audio_active(0, ps3av.audio_port); 441 res = ps3av_cmd_audio_active(0, ps3av->audio_port);
413 if (res < 0) 442 if (res < 0)
414 dev_dbg(&ps3av_dev.core, 443 dev_dbg(&ps3av->dev->core,
415 "ps3av_cmd_audio_active OFF failed\n"); 444 "ps3av_cmd_audio_active OFF failed\n");
416 445
417 /* audio_pkt */ 446 /* audio_pkt */
418 for (i = 0; i < num_of_audio; i++) { 447 for (i = 0; i < num_of_audio; i++) {
419 ps3av_cmd_set_audio_mode(&audio_mode, ps3av.av_port[i], ch, fs, 448 ps3av_cmd_set_audio_mode(&audio_mode, ps3av->av_port[i], ch,
420 word_bits, format, source); 449 fs, word_bits, format, source);
421 if (i < ps3av.av_hw_conf.num_of_hdmi) { 450 if (i < ps3av->av_hw_conf.num_of_hdmi) {
422 /* hdmi only */ 451 /* hdmi only */
423 len += ps3av_cmd_set_av_audio_param(&avb_param.buf[len], 452 len += ps3av_cmd_set_av_audio_param(&avb_param.buf[len],
424 ps3av.av_port[i], 453 ps3av->av_port[i],
425 &audio_mode, vid); 454 &audio_mode, vid);
426 } 455 }
427 /* audio_mode pkt should be sent separately */ 456 /* audio_mode pkt should be sent separately */
428 res = ps3av_cmd_audio_mode(&audio_mode); 457 res = ps3av_cmd_audio_mode(&audio_mode);
429 if (res < 0) 458 if (res < 0)
430 dev_dbg(&ps3av_dev.core, 459 dev_dbg(&ps3av->dev->core,
431 "ps3av_cmd_audio_mode failed, port:%x\n", i); 460 "ps3av_cmd_audio_mode failed, port:%x\n", i);
432 } 461 }
433 462
@@ -435,15 +464,16 @@ int ps3av_set_audio_mode(u32 ch, u32 fs, u32 word_bits, u32 format, u32 source)
435 len += offsetof(struct ps3av_pkt_avb_param, buf); 464 len += offsetof(struct ps3av_pkt_avb_param, buf);
436 res = ps3av_cmd_avb_param(&avb_param, len); 465 res = ps3av_cmd_avb_param(&avb_param, len);
437 if (res < 0) 466 if (res < 0)
438 dev_dbg(&ps3av_dev.core, "ps3av_cmd_avb_param failed\n"); 467 dev_dbg(&ps3av->dev->core, "ps3av_cmd_avb_param failed\n");
439 468
440 /* audio mute */ 469 /* audio mute */
441 ps3av_set_audio_mute(PS3AV_CMD_MUTE_OFF); 470 ps3av_set_audio_mute(PS3AV_CMD_MUTE_OFF);
442 471
443 /* audio active */ 472 /* audio active */
444 res = ps3av_cmd_audio_active(1, ps3av.audio_port); 473 res = ps3av_cmd_audio_active(1, ps3av->audio_port);
445 if (res < 0) 474 if (res < 0)
446 dev_dbg(&ps3av_dev.core, "ps3av_cmd_audio_active ON failed\n"); 475 dev_dbg(&ps3av->dev->core,
476 "ps3av_cmd_audio_active ON failed\n");
447 477
448 return 0; 478 return 0;
449} 479}
@@ -456,7 +486,7 @@ static int ps3av_set_videomode(void)
456 ps3av_set_av_video_mute(PS3AV_CMD_MUTE_ON); 486 ps3av_set_av_video_mute(PS3AV_CMD_MUTE_ON);
457 487
458 /* wake up ps3avd to do the actual video mode setting */ 488 /* wake up ps3avd to do the actual video mode setting */
459 queue_work(ps3av.wq, &ps3av.work); 489 queue_work(ps3av->wq, &ps3av->work);
460 490
461 return 0; 491 return 0;
462} 492}
@@ -473,8 +503,8 @@ static void ps3av_set_videomode_cont(u32 id, u32 old_id)
473 503
474 avb_param.num_of_video_pkt = PS3AV_AVB_NUM_VIDEO; /* num of head */ 504 avb_param.num_of_video_pkt = PS3AV_AVB_NUM_VIDEO; /* num of head */
475 avb_param.num_of_audio_pkt = 0; 505 avb_param.num_of_audio_pkt = 0;
476 avb_param.num_of_av_video_pkt = ps3av.av_hw_conf.num_of_hdmi + 506 avb_param.num_of_av_video_pkt = ps3av->av_hw_conf.num_of_hdmi +
477 ps3av.av_hw_conf.num_of_avmulti; 507 ps3av->av_hw_conf.num_of_avmulti;
478 avb_param.num_of_av_audio_pkt = 0; 508 avb_param.num_of_av_audio_pkt = 0;
479 509
480 /* video signal off */ 510 /* video signal off */
@@ -484,21 +514,21 @@ static void ps3av_set_videomode_cont(u32 id, u32 old_id)
484 if (id & PS3AV_MODE_HDCP_OFF) { 514 if (id & PS3AV_MODE_HDCP_OFF) {
485 res = ps3av_cmd_av_hdmi_mode(PS3AV_CMD_AV_HDMI_HDCP_OFF); 515 res = ps3av_cmd_av_hdmi_mode(PS3AV_CMD_AV_HDMI_HDCP_OFF);
486 if (res == PS3AV_STATUS_UNSUPPORTED_HDMI_MODE) 516 if (res == PS3AV_STATUS_UNSUPPORTED_HDMI_MODE)
487 dev_dbg(&ps3av_dev.core, "Not supported\n"); 517 dev_dbg(&ps3av->dev->core, "Not supported\n");
488 else if (res) 518 else if (res)
489 dev_dbg(&ps3av_dev.core, 519 dev_dbg(&ps3av->dev->core,
490 "ps3av_cmd_av_hdmi_mode failed\n"); 520 "ps3av_cmd_av_hdmi_mode failed\n");
491 } else if (old_id & PS3AV_MODE_HDCP_OFF) { 521 } else if (old_id & PS3AV_MODE_HDCP_OFF) {
492 res = ps3av_cmd_av_hdmi_mode(PS3AV_CMD_AV_HDMI_MODE_NORMAL); 522 res = ps3av_cmd_av_hdmi_mode(PS3AV_CMD_AV_HDMI_MODE_NORMAL);
493 if (res < 0 && res != PS3AV_STATUS_UNSUPPORTED_HDMI_MODE) 523 if (res < 0 && res != PS3AV_STATUS_UNSUPPORTED_HDMI_MODE)
494 dev_dbg(&ps3av_dev.core, 524 dev_dbg(&ps3av->dev->core,
495 "ps3av_cmd_av_hdmi_mode failed\n"); 525 "ps3av_cmd_av_hdmi_mode failed\n");
496 } 526 }
497 527
498 /* video_pkt */ 528 /* video_pkt */
499 for (i = 0; i < avb_param.num_of_video_pkt; i++) 529 for (i = 0; i < avb_param.num_of_video_pkt; i++)
500 len += ps3av_cmd_set_video_mode(&avb_param.buf[len], 530 len += ps3av_cmd_set_video_mode(&avb_param.buf[len],
501 ps3av.head[i], video_mode->vid, 531 ps3av->head[i], video_mode->vid,
502 video_mode->fmt, id); 532 video_mode->fmt, id);
503 /* av_video_pkt */ 533 /* av_video_pkt */
504 for (i = 0; i < avb_param.num_of_av_video_pkt; i++) { 534 for (i = 0; i < avb_param.num_of_av_video_pkt; i++) {
@@ -507,12 +537,12 @@ static void ps3av_set_videomode_cont(u32 id, u32 old_id)
507 else 537 else
508 av_video_cs = video_mode->cs; 538 av_video_cs = video_mode->cs;
509#ifndef PS3AV_HDMI_YUV 539#ifndef PS3AV_HDMI_YUV
510 if (ps3av.av_port[i] == PS3AV_CMD_AVPORT_HDMI_0 || 540 if (ps3av->av_port[i] == PS3AV_CMD_AVPORT_HDMI_0 ||
511 ps3av.av_port[i] == PS3AV_CMD_AVPORT_HDMI_1) 541 ps3av->av_port[i] == PS3AV_CMD_AVPORT_HDMI_1)
512 av_video_cs = RGB8; /* use RGB for HDMI */ 542 av_video_cs = RGB8; /* use RGB for HDMI */
513#endif 543#endif
514 len += ps3av_cmd_set_av_video_cs(&avb_param.buf[len], 544 len += ps3av_cmd_set_av_video_cs(&avb_param.buf[len],
515 ps3av.av_port[i], 545 ps3av->av_port[i],
516 video_mode->vid, av_video_cs, 546 video_mode->vid, av_video_cs,
517 video_mode->aspect, id); 547 video_mode->aspect, id);
518 } 548 }
@@ -524,7 +554,7 @@ static void ps3av_set_videomode_cont(u32 id, u32 old_id)
524 "%s: Command failed. Please try your request again. \n", 554 "%s: Command failed. Please try your request again. \n",
525 __func__); 555 __func__);
526 else if (res) 556 else if (res)
527 dev_dbg(&ps3av_dev.core, "ps3av_cmd_avb_param failed\n"); 557 dev_dbg(&ps3av->dev->core, "ps3av_cmd_avb_param failed\n");
528 558
529 msleep(1500); 559 msleep(1500);
530 /* av video mute */ 560 /* av video mute */
@@ -533,8 +563,8 @@ static void ps3av_set_videomode_cont(u32 id, u32 old_id)
533 563
534static void ps3avd(struct work_struct *work) 564static void ps3avd(struct work_struct *work)
535{ 565{
536 ps3av_set_videomode_cont(ps3av.ps3av_mode, ps3av.ps3av_mode_old); 566 ps3av_set_videomode_cont(ps3av->ps3av_mode, ps3av->ps3av_mode_old);
537 complete(&ps3av.done); 567 complete(&ps3av->done);
538} 568}
539 569
540static int ps3av_vid2table_id(int vid) 570static int ps3av_vid2table_id(int vid)
@@ -601,7 +631,7 @@ static int ps3av_hdmi_get_vid(struct ps3av_info_monitor *info)
601 return vid; 631 return vid;
602 } 632 }
603 633
604 if (ps3av.region & PS3AV_REGION_60) 634 if (ps3av->region & PS3AV_REGION_60)
605 vid = PS3AV_DEFAULT_HDMI_VID_REG_60; 635 vid = PS3AV_DEFAULT_HDMI_VID_REG_60;
606 else 636 else
607 vid = PS3AV_DEFAULT_HDMI_VID_REG_50; 637 vid = PS3AV_DEFAULT_HDMI_VID_REG_50;
@@ -643,16 +673,16 @@ static int ps3av_auto_videomode(struct ps3av_pkt_av_get_hw_conf *av_hw_conf,
643 vid = PS3AV_DEFAULT_DVI_VID; 673 vid = PS3AV_DEFAULT_DVI_VID;
644 } else if (vid == -1) { 674 } else if (vid == -1) {
645 /* no HDMI interface or HDMI is off */ 675 /* no HDMI interface or HDMI is off */
646 if (ps3av.region & PS3AV_REGION_60) 676 if (ps3av->region & PS3AV_REGION_60)
647 vid = PS3AV_DEFAULT_AVMULTI_VID_REG_60; 677 vid = PS3AV_DEFAULT_AVMULTI_VID_REG_60;
648 else 678 else
649 vid = PS3AV_DEFAULT_AVMULTI_VID_REG_50; 679 vid = PS3AV_DEFAULT_AVMULTI_VID_REG_50;
650 if (ps3av.region & PS3AV_REGION_RGB) 680 if (ps3av->region & PS3AV_REGION_RGB)
651 rgb = PS3AV_MODE_RGB; 681 rgb = PS3AV_MODE_RGB;
652 } else if (boot) { 682 } else if (boot) {
653 /* HDMI: using DEFAULT HDMI_VID while booting up */ 683 /* HDMI: using DEFAULT HDMI_VID while booting up */
654 info = &monitor_info.info; 684 info = &monitor_info.info;
655 if (ps3av.region & PS3AV_REGION_60) { 685 if (ps3av->region & PS3AV_REGION_60) {
656 if (info->res_60.res_bits & PS3AV_RESBIT_720x480P) 686 if (info->res_60.res_bits & PS3AV_RESBIT_720x480P)
657 vid = PS3AV_DEFAULT_HDMI_VID_REG_60; 687 vid = PS3AV_DEFAULT_HDMI_VID_REG_60;
658 else if (info->res_50.res_bits & PS3AV_RESBIT_720x576P) 688 else if (info->res_50.res_bits & PS3AV_RESBIT_720x576P)
@@ -715,14 +745,14 @@ int ps3av_set_video_mode(u32 id, int boot)
715 745
716 size = ARRAY_SIZE(video_mode_table); 746 size = ARRAY_SIZE(video_mode_table);
717 if ((id & PS3AV_MODE_MASK) > size - 1 || id < 0) { 747 if ((id & PS3AV_MODE_MASK) > size - 1 || id < 0) {
718 dev_dbg(&ps3av_dev.core, "%s: error id :%d\n", __func__, id); 748 dev_dbg(&ps3av->dev->core, "%s: error id :%d\n", __func__, id);
719 return -EINVAL; 749 return -EINVAL;
720 } 750 }
721 751
722 /* auto mode */ 752 /* auto mode */
723 option = id & ~PS3AV_MODE_MASK; 753 option = id & ~PS3AV_MODE_MASK;
724 if ((id & PS3AV_MODE_MASK) == 0) { 754 if ((id & PS3AV_MODE_MASK) == 0) {
725 id = ps3av_auto_videomode(&ps3av.av_hw_conf, boot); 755 id = ps3av_auto_videomode(&ps3av->av_hw_conf, boot);
726 if (id < 1) { 756 if (id < 1) {
727 printk(KERN_ERR "%s: invalid id :%d\n", __func__, id); 757 printk(KERN_ERR "%s: invalid id :%d\n", __func__, id);
728 return -EINVAL; 758 return -EINVAL;
@@ -731,11 +761,11 @@ int ps3av_set_video_mode(u32 id, int boot)
731 } 761 }
732 762
733 /* set videomode */ 763 /* set videomode */
734 wait_for_completion(&ps3av.done); 764 wait_for_completion(&ps3av->done);
735 ps3av.ps3av_mode_old = ps3av.ps3av_mode; 765 ps3av->ps3av_mode_old = ps3av->ps3av_mode;
736 ps3av.ps3av_mode = id; 766 ps3av->ps3av_mode = id;
737 if (ps3av_set_videomode()) 767 if (ps3av_set_videomode())
738 ps3av.ps3av_mode = ps3av.ps3av_mode_old; 768 ps3av->ps3av_mode = ps3av->ps3av_mode_old;
739 769
740 return 0; 770 return 0;
741} 771}
@@ -744,7 +774,7 @@ EXPORT_SYMBOL_GPL(ps3av_set_video_mode);
744 774
745int ps3av_get_auto_mode(int boot) 775int ps3av_get_auto_mode(int boot)
746{ 776{
747 return ps3av_auto_videomode(&ps3av.av_hw_conf, boot); 777 return ps3av_auto_videomode(&ps3av->av_hw_conf, boot);
748} 778}
749 779
750EXPORT_SYMBOL_GPL(ps3av_get_auto_mode); 780EXPORT_SYMBOL_GPL(ps3av_get_auto_mode);
@@ -772,7 +802,7 @@ EXPORT_SYMBOL_GPL(ps3av_set_mode);
772 802
773int ps3av_get_mode(void) 803int ps3av_get_mode(void)
774{ 804{
775 return ps3av.ps3av_mode; 805 return ps3av ? ps3av->ps3av_mode : 0;
776} 806}
777 807
778EXPORT_SYMBOL_GPL(ps3av_get_mode); 808EXPORT_SYMBOL_GPL(ps3av_get_mode);
@@ -842,82 +872,65 @@ int ps3av_audio_mute(int mute)
842 872
843EXPORT_SYMBOL_GPL(ps3av_audio_mute); 873EXPORT_SYMBOL_GPL(ps3av_audio_mute);
844 874
845int ps3av_dev_open(void) 875void ps3av_register_flip_ctl(void (*flip_ctl)(int on, void *data),
876 void *flip_data)
846{ 877{
847 int status = 0; 878 mutex_lock(&ps3av->mutex);
848 879 ps3av->flip_ctl = flip_ctl;
849 mutex_lock(&ps3av.mutex); 880 ps3av->flip_data = flip_data;
850 if (!ps3av.open_count++) { 881 mutex_unlock(&ps3av->mutex);
851 status = lv1_gpu_open(0);
852 if (status) {
853 printk(KERN_ERR "%s: lv1_gpu_open failed %d\n",
854 __func__, status);
855 ps3av.open_count--;
856 }
857 }
858 mutex_unlock(&ps3av.mutex);
859
860 return status;
861} 882}
883EXPORT_SYMBOL_GPL(ps3av_register_flip_ctl);
862 884
863EXPORT_SYMBOL_GPL(ps3av_dev_open); 885void ps3av_flip_ctl(int on)
864
865int ps3av_dev_close(void)
866{ 886{
867 int status = 0; 887 mutex_lock(&ps3av->mutex);
868 888 if (ps3av->flip_ctl)
869 mutex_lock(&ps3av.mutex); 889 ps3av->flip_ctl(on, ps3av->flip_data);
870 if (ps3av.open_count <= 0) { 890 mutex_unlock(&ps3av->mutex);
871 printk(KERN_ERR "%s: GPU already closed\n", __func__);
872 status = -1;
873 } else if (!--ps3av.open_count) {
874 status = lv1_gpu_close();
875 if (status)
876 printk(KERN_WARNING "%s: lv1_gpu_close failed %d\n",
877 __func__, status);
878 }
879 mutex_unlock(&ps3av.mutex);
880
881 return status;
882} 891}
883 892
884EXPORT_SYMBOL_GPL(ps3av_dev_close); 893static int ps3av_probe(struct ps3_system_bus_device *dev)
885
886static int ps3av_probe(struct ps3_vuart_port_device *dev)
887{ 894{
888 int res; 895 int res;
889 u32 id; 896 u32 id;
890 897
891 dev_dbg(&ps3av_dev.core, "init ...\n"); 898 dev_dbg(&dev->core, " -> %s:%d\n", __func__, __LINE__);
892 dev_dbg(&ps3av_dev.core, " timeout=%d\n", timeout); 899 dev_dbg(&dev->core, " timeout=%d\n", timeout);
893 900
894 memset(&ps3av, 0, sizeof(ps3av)); 901 if (ps3av) {
895 902 dev_err(&dev->core, "Only one ps3av device is supported\n");
896 mutex_init(&ps3av.mutex); 903 return -EBUSY;
897 ps3av.ps3av_mode = 0; 904 }
898 ps3av.dev = dev;
899 905
900 INIT_WORK(&ps3av.work, ps3avd); 906 ps3av = kzalloc(sizeof(*ps3av), GFP_KERNEL);
901 init_completion(&ps3av.done); 907 if (!ps3av)
902 complete(&ps3av.done);
903 ps3av.wq = create_singlethread_workqueue("ps3avd");
904 if (!ps3av.wq)
905 return -ENOMEM; 908 return -ENOMEM;
906 909
907 ps3av.available = 1; 910 mutex_init(&ps3av->mutex);
911 ps3av->ps3av_mode = 0;
912 ps3av->dev = dev;
913
914 INIT_WORK(&ps3av->work, ps3avd);
915 init_completion(&ps3av->done);
916 complete(&ps3av->done);
917 ps3av->wq = create_singlethread_workqueue("ps3avd");
918 if (!ps3av->wq)
919 goto fail;
920
908 switch (ps3_os_area_get_av_multi_out()) { 921 switch (ps3_os_area_get_av_multi_out()) {
909 case PS3_PARAM_AV_MULTI_OUT_NTSC: 922 case PS3_PARAM_AV_MULTI_OUT_NTSC:
910 ps3av.region = PS3AV_REGION_60; 923 ps3av->region = PS3AV_REGION_60;
911 break; 924 break;
912 case PS3_PARAM_AV_MULTI_OUT_PAL_YCBCR: 925 case PS3_PARAM_AV_MULTI_OUT_PAL_YCBCR:
913 case PS3_PARAM_AV_MULTI_OUT_SECAM: 926 case PS3_PARAM_AV_MULTI_OUT_SECAM:
914 ps3av.region = PS3AV_REGION_50; 927 ps3av->region = PS3AV_REGION_50;
915 break; 928 break;
916 case PS3_PARAM_AV_MULTI_OUT_PAL_RGB: 929 case PS3_PARAM_AV_MULTI_OUT_PAL_RGB:
917 ps3av.region = PS3AV_REGION_50 | PS3AV_REGION_RGB; 930 ps3av->region = PS3AV_REGION_50 | PS3AV_REGION_RGB;
918 break; 931 break;
919 default: 932 default:
920 ps3av.region = PS3AV_REGION_60; 933 ps3av->region = PS3AV_REGION_60;
921 break; 934 break;
922 } 935 }
923 936
@@ -927,39 +940,47 @@ static int ps3av_probe(struct ps3_vuart_port_device *dev)
927 printk(KERN_ERR "%s: ps3av_cmd_init failed %d\n", __func__, 940 printk(KERN_ERR "%s: ps3av_cmd_init failed %d\n", __func__,
928 res); 941 res);
929 942
930 ps3av_get_hw_conf(&ps3av); 943 ps3av_get_hw_conf(ps3av);
931 id = ps3av_auto_videomode(&ps3av.av_hw_conf, 1); 944 id = ps3av_auto_videomode(&ps3av->av_hw_conf, 1);
932 mutex_lock(&ps3av.mutex); 945 mutex_lock(&ps3av->mutex);
933 ps3av.ps3av_mode = id; 946 ps3av->ps3av_mode = id;
934 mutex_unlock(&ps3av.mutex); 947 mutex_unlock(&ps3av->mutex);
935 948
936 dev_dbg(&ps3av_dev.core, "init...done\n"); 949 dev_dbg(&dev->core, " <- %s:%d\n", __func__, __LINE__);
937 950
938 return 0; 951 return 0;
952
953fail:
954 kfree(ps3av);
955 ps3av = NULL;
956 return -ENOMEM;
939} 957}
940 958
941static int ps3av_remove(struct ps3_vuart_port_device *dev) 959static int ps3av_remove(struct ps3_system_bus_device *dev)
942{ 960{
943 if (ps3av.available) { 961 dev_dbg(&dev->core, " -> %s:%d\n", __func__, __LINE__);
962 if (ps3av) {
944 ps3av_cmd_fin(); 963 ps3av_cmd_fin();
945 if (ps3av.wq) 964 if (ps3av->wq)
946 destroy_workqueue(ps3av.wq); 965 destroy_workqueue(ps3av->wq);
947 ps3av.available = 0; 966 kfree(ps3av);
967 ps3av = NULL;
948 } 968 }
949 969
970 dev_dbg(&dev->core, " <- %s:%d\n", __func__, __LINE__);
950 return 0; 971 return 0;
951} 972}
952 973
953static void ps3av_shutdown(struct ps3_vuart_port_device *dev) 974static void ps3av_shutdown(struct ps3_system_bus_device *dev)
954{ 975{
976 dev_dbg(&dev->core, " -> %s:%d\n", __func__, __LINE__);
955 ps3av_remove(dev); 977 ps3av_remove(dev);
978 dev_dbg(&dev->core, " <- %s:%d\n", __func__, __LINE__);
956} 979}
957 980
958static struct ps3_vuart_port_driver ps3av_driver = { 981static struct ps3_vuart_port_driver ps3av_driver = {
959 .match_id = PS3_MATCH_ID_AV_SETTINGS, 982 .core.match_id = PS3_MATCH_ID_AV_SETTINGS,
960 .core = { 983 .core.core.name = "ps3_av",
961 .name = "ps3_av",
962 },
963 .probe = ps3av_probe, 984 .probe = ps3av_probe,
964 .remove = ps3av_remove, 985 .remove = ps3av_remove,
965 .shutdown = ps3av_shutdown, 986 .shutdown = ps3av_shutdown,
@@ -972,6 +993,8 @@ static int ps3av_module_init(void)
972 if (!firmware_has_feature(FW_FEATURE_PS3_LV1)) 993 if (!firmware_has_feature(FW_FEATURE_PS3_LV1))
973 return -ENODEV; 994 return -ENODEV;
974 995
996 pr_debug(" -> %s:%d\n", __func__, __LINE__);
997
975 error = ps3_vuart_port_driver_register(&ps3av_driver); 998 error = ps3_vuart_port_driver_register(&ps3av_driver);
976 if (error) { 999 if (error) {
977 printk(KERN_ERR 1000 printk(KERN_ERR
@@ -980,20 +1003,21 @@ static int ps3av_module_init(void)
980 return error; 1003 return error;
981 } 1004 }
982 1005
983 error = ps3_vuart_port_device_register(&ps3av_dev); 1006 pr_debug(" <- %s:%d\n", __func__, __LINE__);
984 if (error)
985 printk(KERN_ERR
986 "%s: ps3_vuart_port_device_register failed %d\n",
987 __func__, error);
988
989 return error; 1007 return error;
990} 1008}
991 1009
992static void __exit ps3av_module_exit(void) 1010static void __exit ps3av_module_exit(void)
993{ 1011{
994 device_unregister(&ps3av_dev.core); 1012 pr_debug(" -> %s:%d\n", __func__, __LINE__);
995 ps3_vuart_port_driver_unregister(&ps3av_driver); 1013 ps3_vuart_port_driver_unregister(&ps3av_driver);
1014 pr_debug(" <- %s:%d\n", __func__, __LINE__);
996} 1015}
997 1016
998subsys_initcall(ps3av_module_init); 1017subsys_initcall(ps3av_module_init);
999module_exit(ps3av_module_exit); 1018module_exit(ps3av_module_exit);
1019
1020MODULE_LICENSE("GPL v2");
1021MODULE_DESCRIPTION("PS3 AV Settings Driver");
1022MODULE_AUTHOR("Sony Computer Entertainment Inc.");
1023MODULE_ALIAS(PS3_MODULE_ALIAS_AV_SETTINGS);
diff --git a/drivers/ps3/ps3av_cmd.c b/drivers/ps3/ps3av_cmd.c
index 0145ea173c42..f72f5ddf18e4 100644
--- a/drivers/ps3/ps3av_cmd.c
+++ b/drivers/ps3/ps3av_cmd.c
@@ -143,6 +143,14 @@ static u32 ps3av_vid_video2av(int vid)
143 return PS3AV_CMD_AV_VID_480P; 143 return PS3AV_CMD_AV_VID_480P;
144} 144}
145 145
146static int ps3av_hdmi_range(void)
147{
148 if (ps3_compare_firmware_version(1, 8, 0) < 0)
149 return 0;
150 else
151 return 1; /* supported */
152}
153
146int ps3av_cmd_init(void) 154int ps3av_cmd_init(void)
147{ 155{
148 int res; 156 int res;
@@ -350,6 +358,10 @@ u32 ps3av_cmd_set_av_video_cs(void *p, u32 avport, int video_vid, int cs_out,
350 /* should be same as video_mode.video_cs_out */ 358 /* should be same as video_mode.video_cs_out */
351 av_video_cs->av_cs_in = ps3av_cs_video2av(PS3AV_CMD_VIDEO_CS_RGB_8); 359 av_video_cs->av_cs_in = ps3av_cs_video2av(PS3AV_CMD_VIDEO_CS_RGB_8);
352 av_video_cs->bitlen_out = ps3av_cs_video2av_bitlen(cs_out); 360 av_video_cs->bitlen_out = ps3av_cs_video2av_bitlen(cs_out);
361 if ((id & PS3AV_MODE_WHITE) && ps3av_hdmi_range())
362 av_video_cs->super_white = PS3AV_CMD_AV_SUPER_WHITE_ON;
363 else /* default off */
364 av_video_cs->super_white = PS3AV_CMD_AV_SUPER_WHITE_OFF;
353 av_video_cs->aspect = aspect; 365 av_video_cs->aspect = aspect;
354 if (id & PS3AV_MODE_DITHER) { 366 if (id & PS3AV_MODE_DITHER) {
355 av_video_cs->dither = PS3AV_CMD_AV_DITHER_ON 367 av_video_cs->dither = PS3AV_CMD_AV_DITHER_ON
@@ -392,6 +404,10 @@ u32 ps3av_cmd_set_video_mode(void *p, u32 head, int video_vid, int video_fmt,
392 video_mode->pitch = video_mode->width * 4; /* line_length */ 404 video_mode->pitch = video_mode->width * 4; /* line_length */
393 video_mode->video_out_format = PS3AV_CMD_VIDEO_OUT_FORMAT_RGB_12BIT; 405 video_mode->video_out_format = PS3AV_CMD_VIDEO_OUT_FORMAT_RGB_12BIT;
394 video_mode->video_format = ps3av_video_fmt_table[video_fmt].format; 406 video_mode->video_format = ps3av_video_fmt_table[video_fmt].format;
407 if ((id & PS3AV_MODE_COLOR) && ps3av_hdmi_range())
408 video_mode->video_cl_cnv = PS3AV_CMD_VIDEO_CL_CNV_DISABLE_LUT;
409 else /* default enable */
410 video_mode->video_cl_cnv = PS3AV_CMD_VIDEO_CL_CNV_ENABLE_LUT;
395 video_mode->video_order = ps3av_video_fmt_table[video_fmt].order; 411 video_mode->video_order = ps3av_video_fmt_table[video_fmt].order;
396 412
397 pr_debug("%s: video_mode:vid:%x width:%d height:%d pitch:%d out_format:%d format:%x order:%x\n", 413 pr_debug("%s: video_mode:vid:%x width:%d height:%d pitch:%d out_format:%d format:%x order:%x\n",
@@ -852,7 +868,7 @@ int ps3av_cmd_avb_param(struct ps3av_pkt_avb_param *avb, u32 send_len)
852{ 868{
853 int res; 869 int res;
854 870
855 ps3fb_flip_ctl(0); /* flip off */ 871 ps3av_flip_ctl(0); /* flip off */
856 872
857 /* avb packet */ 873 /* avb packet */
858 res = ps3av_do_pkt(PS3AV_CID_AVB_PARAM, send_len, sizeof(*avb), 874 res = ps3av_do_pkt(PS3AV_CID_AVB_PARAM, send_len, sizeof(*avb),
@@ -866,7 +882,7 @@ int ps3av_cmd_avb_param(struct ps3av_pkt_avb_param *avb, u32 send_len)
866 res); 882 res);
867 883
868 out: 884 out:
869 ps3fb_flip_ctl(1); /* flip on */ 885 ps3av_flip_ctl(1); /* flip on */
870 return res; 886 return res;
871} 887}
872 888
@@ -987,34 +1003,3 @@ void ps3av_cmd_av_monitor_info_dump(const struct ps3av_pkt_av_get_monitor_info *
987 | PS3AV_CMD_AV_LAYOUT_176 \ 1003 | PS3AV_CMD_AV_LAYOUT_176 \
988 | PS3AV_CMD_AV_LAYOUT_192) 1004 | PS3AV_CMD_AV_LAYOUT_192)
989 1005
990/************************* vuart ***************************/
991
992#define POLLING_INTERVAL 25 /* in msec */
993
994int ps3av_vuart_write(struct ps3_vuart_port_device *dev, const void *buf,
995 unsigned long size)
996{
997 int error = ps3_vuart_write(dev, buf, size);
998 return error ? error : size;
999}
1000
1001int ps3av_vuart_read(struct ps3_vuart_port_device *dev, void *buf,
1002 unsigned long size, int timeout)
1003{
1004 int error;
1005 int loopcnt = 0;
1006
1007 timeout = (timeout + POLLING_INTERVAL - 1) / POLLING_INTERVAL;
1008 while (loopcnt++ <= timeout) {
1009 error = ps3_vuart_read(dev, buf, size);
1010 if (!error)
1011 return size;
1012 if (error != -EAGAIN) {
1013 printk(KERN_ERR "%s: ps3_vuart_read failed %d\n",
1014 __func__, error);
1015 return error;
1016 }
1017 msleep(POLLING_INTERVAL);
1018 }
1019 return -EWOULDBLOCK;
1020}
diff --git a/drivers/ps3/ps3stor_lib.c b/drivers/ps3/ps3stor_lib.c
new file mode 100644
index 000000000000..3a9824e3b251
--- /dev/null
+++ b/drivers/ps3/ps3stor_lib.c
@@ -0,0 +1,302 @@
1/*
2 * PS3 Storage Library
3 *
4 * Copyright (C) 2007 Sony Computer Entertainment Inc.
5 * Copyright 2007 Sony Corp.
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published
9 * by the Free Software Foundation; version 2 of the License.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21#include <linux/dma-mapping.h>
22
23#include <asm/lv1call.h>
24#include <asm/ps3stor.h>
25
26
27static int ps3stor_probe_access(struct ps3_storage_device *dev)
28{
29 int res, error;
30 unsigned int i;
31 unsigned long n;
32
33 if (dev->sbd.match_id == PS3_MATCH_ID_STOR_ROM) {
34 /* special case: CD-ROM is assumed always accessible */
35 dev->accessible_regions = 1;
36 return 0;
37 }
38
39 error = -EPERM;
40 for (i = 0; i < dev->num_regions; i++) {
41 dev_dbg(&dev->sbd.core,
42 "%s:%u: checking accessibility of region %u\n",
43 __func__, __LINE__, i);
44
45 dev->region_idx = i;
46 res = ps3stor_read_write_sectors(dev, dev->bounce_lpar, 0, 1,
47 0);
48 if (res) {
49 dev_dbg(&dev->sbd.core, "%s:%u: read failed, "
50 "region %u is not accessible\n", __func__,
51 __LINE__, i);
52 continue;
53 }
54
55 dev_dbg(&dev->sbd.core, "%s:%u: region %u is accessible\n",
56 __func__, __LINE__, i);
57 set_bit(i, &dev->accessible_regions);
58
59 /* We can access at least one region */
60 error = 0;
61 }
62 if (error)
63 return error;
64
65 n = hweight_long(dev->accessible_regions);
66 if (n > 1)
67 dev_info(&dev->sbd.core,
68 "%s:%u: %lu accessible regions found. Only the first "
69 "one will be used",
70 __func__, __LINE__, n);
71 dev->region_idx = __ffs(dev->accessible_regions);
72 dev_info(&dev->sbd.core,
73 "First accessible region has index %u start %lu size %lu\n",
74 dev->region_idx, dev->regions[dev->region_idx].start,
75 dev->regions[dev->region_idx].size);
76
77 return 0;
78}
79
80
81/**
82 * ps3stor_setup - Setup a storage device before use
83 * @dev: Pointer to a struct ps3_storage_device
84 * @handler: Pointer to an interrupt handler
85 *
86 * Returns 0 for success, or an error code
87 */
88int ps3stor_setup(struct ps3_storage_device *dev, irq_handler_t handler)
89{
90 int error, res, alignment;
91 enum ps3_dma_page_size page_size;
92
93 error = ps3_open_hv_device(&dev->sbd);
94 if (error) {
95 dev_err(&dev->sbd.core,
96 "%s:%u: ps3_open_hv_device failed %d\n", __func__,
97 __LINE__, error);
98 goto fail;
99 }
100
101 error = ps3_sb_event_receive_port_setup(&dev->sbd, PS3_BINDING_CPU_ANY,
102 &dev->irq);
103 if (error) {
104 dev_err(&dev->sbd.core,
105 "%s:%u: ps3_sb_event_receive_port_setup failed %d\n",
106 __func__, __LINE__, error);
107 goto fail_close_device;
108 }
109
110 error = request_irq(dev->irq, handler, IRQF_DISABLED,
111 dev->sbd.core.driver->name, dev);
112 if (error) {
113 dev_err(&dev->sbd.core, "%s:%u: request_irq failed %d\n",
114 __func__, __LINE__, error);
115 goto fail_sb_event_receive_port_destroy;
116 }
117
118 alignment = min(__ffs(dev->bounce_size),
119 __ffs((unsigned long)dev->bounce_buf));
120 if (alignment < 12) {
121 dev_err(&dev->sbd.core,
122 "%s:%u: bounce buffer not aligned (%lx at 0x%p)\n",
123 __func__, __LINE__, dev->bounce_size, dev->bounce_buf);
124 error = -EINVAL;
125 goto fail_free_irq;
126 } else if (alignment < 16)
127 page_size = PS3_DMA_4K;
128 else
129 page_size = PS3_DMA_64K;
130 dev->sbd.d_region = &dev->dma_region;
131 ps3_dma_region_init(&dev->sbd, &dev->dma_region, page_size,
132 PS3_DMA_OTHER, dev->bounce_buf, dev->bounce_size);
133 res = ps3_dma_region_create(&dev->dma_region);
134 if (res) {
135 dev_err(&dev->sbd.core, "%s:%u: cannot create DMA region\n",
136 __func__, __LINE__);
137 error = -ENOMEM;
138 goto fail_free_irq;
139 }
140
141 dev->bounce_lpar = ps3_mm_phys_to_lpar(__pa(dev->bounce_buf));
142 dev->bounce_dma = dma_map_single(&dev->sbd.core, dev->bounce_buf,
143 dev->bounce_size, DMA_BIDIRECTIONAL);
144 if (!dev->bounce_dma) {
145 dev_err(&dev->sbd.core, "%s:%u: map DMA region failed\n",
146 __func__, __LINE__);
147 error = -ENODEV;
148 goto fail_free_dma;
149 }
150
151 error = ps3stor_probe_access(dev);
152 if (error) {
153 dev_err(&dev->sbd.core, "%s:%u: No accessible regions found\n",
154 __func__, __LINE__);
155 goto fail_unmap_dma;
156 }
157 return 0;
158
159fail_unmap_dma:
160 dma_unmap_single(&dev->sbd.core, dev->bounce_dma, dev->bounce_size,
161 DMA_BIDIRECTIONAL);
162fail_free_dma:
163 ps3_dma_region_free(&dev->dma_region);
164fail_free_irq:
165 free_irq(dev->irq, dev);
166fail_sb_event_receive_port_destroy:
167 ps3_sb_event_receive_port_destroy(&dev->sbd, dev->irq);
168fail_close_device:
169 ps3_close_hv_device(&dev->sbd);
170fail:
171 return error;
172}
173EXPORT_SYMBOL_GPL(ps3stor_setup);
174
175
176/**
177 * ps3stor_teardown - Tear down a storage device after use
178 * @dev: Pointer to a struct ps3_storage_device
179 */
180void ps3stor_teardown(struct ps3_storage_device *dev)
181{
182 int error;
183
184 dma_unmap_single(&dev->sbd.core, dev->bounce_dma, dev->bounce_size,
185 DMA_BIDIRECTIONAL);
186 ps3_dma_region_free(&dev->dma_region);
187
188 free_irq(dev->irq, dev);
189
190 error = ps3_sb_event_receive_port_destroy(&dev->sbd, dev->irq);
191 if (error)
192 dev_err(&dev->sbd.core,
193 "%s:%u: destroy event receive port failed %d\n",
194 __func__, __LINE__, error);
195
196 error = ps3_close_hv_device(&dev->sbd);
197 if (error)
198 dev_err(&dev->sbd.core,
199 "%s:%u: ps3_close_hv_device failed %d\n", __func__,
200 __LINE__, error);
201}
202EXPORT_SYMBOL_GPL(ps3stor_teardown);
203
204
205/**
206 * ps3stor_read_write_sectors - read/write from/to a storage device
207 * @dev: Pointer to a struct ps3_storage_device
208 * @lpar: HV logical partition address
209 * @start_sector: First sector to read/write
210 * @sectors: Number of sectors to read/write
211 * @write: Flag indicating write (non-zero) or read (zero)
212 *
213 * Returns 0 for success, -1 in case of failure to submit the command, or
214 * an LV1 status value in case of other errors
215 */
216u64 ps3stor_read_write_sectors(struct ps3_storage_device *dev, u64 lpar,
217 u64 start_sector, u64 sectors, int write)
218{
219 unsigned int region_id = dev->regions[dev->region_idx].id;
220 const char *op = write ? "write" : "read";
221 int res;
222
223 dev_dbg(&dev->sbd.core, "%s:%u: %s %lu sectors starting at %lu\n",
224 __func__, __LINE__, op, sectors, start_sector);
225
226 init_completion(&dev->done);
227 res = write ? lv1_storage_write(dev->sbd.dev_id, region_id,
228 start_sector, sectors, 0, lpar,
229 &dev->tag)
230 : lv1_storage_read(dev->sbd.dev_id, region_id,
231 start_sector, sectors, 0, lpar,
232 &dev->tag);
233 if (res) {
234 dev_dbg(&dev->sbd.core, "%s:%u: %s failed %d\n", __func__,
235 __LINE__, op, res);
236 return -1;
237 }
238
239 wait_for_completion(&dev->done);
240 if (dev->lv1_status) {
241 dev_dbg(&dev->sbd.core, "%s:%u: %s failed 0x%lx\n", __func__,
242 __LINE__, op, dev->lv1_status);
243 return dev->lv1_status;
244 }
245
246 dev_dbg(&dev->sbd.core, "%s:%u: %s completed\n", __func__, __LINE__,
247 op);
248
249 return 0;
250}
251EXPORT_SYMBOL_GPL(ps3stor_read_write_sectors);
252
253
254/**
255 * ps3stor_send_command - send a device command to a storage device
256 * @dev: Pointer to a struct ps3_storage_device
257 * @cmd: Command number
258 * @arg1: First command argument
259 * @arg2: Second command argument
260 * @arg3: Third command argument
261 * @arg4: Fourth command argument
262 *
263 * Returns 0 for success, -1 in case of failure to submit the command, or
264 * an LV1 status value in case of other errors
265 */
266u64 ps3stor_send_command(struct ps3_storage_device *dev, u64 cmd, u64 arg1,
267 u64 arg2, u64 arg3, u64 arg4)
268{
269 int res;
270
271 dev_dbg(&dev->sbd.core, "%s:%u: send device command 0x%lx\n", __func__,
272 __LINE__, cmd);
273
274 init_completion(&dev->done);
275
276 res = lv1_storage_send_device_command(dev->sbd.dev_id, cmd, arg1,
277 arg2, arg3, arg4, &dev->tag);
278 if (res) {
279 dev_err(&dev->sbd.core,
280 "%s:%u: send_device_command 0x%lx failed %d\n",
281 __func__, __LINE__, cmd, res);
282 return -1;
283 }
284
285 wait_for_completion(&dev->done);
286 if (dev->lv1_status) {
287 dev_dbg(&dev->sbd.core, "%s:%u: command 0x%lx failed 0x%lx\n",
288 __func__, __LINE__, cmd, dev->lv1_status);
289 return dev->lv1_status;
290 }
291
292 dev_dbg(&dev->sbd.core, "%s:%u: command 0x%lx completed\n", __func__,
293 __LINE__, cmd);
294
295 return 0;
296}
297EXPORT_SYMBOL_GPL(ps3stor_send_command);
298
299
300MODULE_LICENSE("GPL");
301MODULE_DESCRIPTION("PS3 Storage Bus Library");
302MODULE_AUTHOR("Sony Corporation");
diff --git a/drivers/ps3/sys-manager-core.c b/drivers/ps3/sys-manager-core.c
new file mode 100644
index 000000000000..31648f7d9ae1
--- /dev/null
+++ b/drivers/ps3/sys-manager-core.c
@@ -0,0 +1,68 @@
1/*
2 * PS3 System Manager core.
3 *
4 * Copyright (C) 2007 Sony Computer Entertainment Inc.
5 * Copyright 2007 Sony Corp.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include <linux/kernel.h>
22#include <asm/ps3.h>
23
24/**
25 * Staticly linked routines that allow late binding of a loaded sys-manager
26 * module.
27 */
28
29static struct ps3_sys_manager_ops ps3_sys_manager_ops;
30
31/**
32 * ps3_register_sys_manager_ops - Bind ps3_sys_manager_ops to a module.
33 * @ops: struct ps3_sys_manager_ops.
34 *
35 * To be called from ps3_sys_manager_probe() and ps3_sys_manager_remove() to
36 * register call back ops for power control. Copies data to the static
37 * variable ps3_sys_manager_ops.
38 */
39
40void ps3_sys_manager_register_ops(const struct ps3_sys_manager_ops *ops)
41{
42 BUG_ON(!ops);
43 BUG_ON(!ops->dev);
44 ps3_sys_manager_ops = ops ? *ops : ps3_sys_manager_ops;
45}
46EXPORT_SYMBOL_GPL(ps3_sys_manager_register_ops);
47
48void ps3_sys_manager_power_off(void)
49{
50 if (ps3_sys_manager_ops.power_off)
51 ps3_sys_manager_ops.power_off(ps3_sys_manager_ops.dev);
52
53 printk(KERN_EMERG "System Halted, OK to turn off power\n");
54 local_irq_disable();
55 while (1)
56 (void)0;
57}
58
59void ps3_sys_manager_restart(void)
60{
61 if (ps3_sys_manager_ops.restart)
62 ps3_sys_manager_ops.restart(ps3_sys_manager_ops.dev);
63
64 printk(KERN_EMERG "System Halted, OK to turn off power\n");
65 local_irq_disable();
66 while (1)
67 (void)0;
68}
diff --git a/drivers/ps3/sys-manager.c b/drivers/ps3/sys-manager.c
index 3aa2b0dcc369..8461b08ab9fb 100644
--- a/drivers/ps3/sys-manager.c
+++ b/drivers/ps3/sys-manager.c
@@ -35,7 +35,7 @@ MODULE_DESCRIPTION("PS3 System Manager");
35/** 35/**
36 * ps3_sys_manager - PS3 system manager driver. 36 * ps3_sys_manager - PS3 system manager driver.
37 * 37 *
38 * The system manager provides an asyncronous system event notification 38 * The system manager provides an asynchronous system event notification
39 * mechanism for reporting events like thermal alert and button presses to 39 * mechanism for reporting events like thermal alert and button presses to
40 * guests. It also provides support to control system shutdown and startup. 40 * guests. It also provides support to control system shutdown and startup.
41 * 41 *
@@ -52,6 +52,7 @@ MODULE_DESCRIPTION("PS3 System Manager");
52 * @size: Header size in bytes, curently 16. 52 * @size: Header size in bytes, curently 16.
53 * @payload_size: Message payload size in bytes. 53 * @payload_size: Message payload size in bytes.
54 * @service_id: Message type, one of enum ps3_sys_manager_service_id. 54 * @service_id: Message type, one of enum ps3_sys_manager_service_id.
55 * @request_tag: Unique number to identify reply.
55 */ 56 */
56 57
57struct ps3_sys_manager_header { 58struct ps3_sys_manager_header {
@@ -61,29 +62,49 @@ struct ps3_sys_manager_header {
61 u16 reserved_1; 62 u16 reserved_1;
62 u32 payload_size; 63 u32 payload_size;
63 u16 service_id; 64 u16 service_id;
64 u16 reserved_2[3]; 65 u16 reserved_2;
66 u32 request_tag;
65}; 67};
66 68
69#define dump_sm_header(_h) _dump_sm_header(_h, __func__, __LINE__)
70static void __maybe_unused _dump_sm_header(
71 const struct ps3_sys_manager_header *h, const char *func, int line)
72{
73 pr_debug("%s:%d: version: %xh\n", func, line, h->version);
74 pr_debug("%s:%d: size: %xh\n", func, line, h->size);
75 pr_debug("%s:%d: payload_size: %xh\n", func, line, h->payload_size);
76 pr_debug("%s:%d: service_id: %xh\n", func, line, h->service_id);
77 pr_debug("%s:%d: request_tag: %xh\n", func, line, h->request_tag);
78}
79
67/** 80/**
68 * @PS3_SM_RX_MSG_LEN - System manager received message length. 81 * @PS3_SM_RX_MSG_LEN_MIN - Shortest received message length.
82 * @PS3_SM_RX_MSG_LEN_MAX - Longest received message length.
69 * 83 *
70 * Currently all messages received from the system manager are the same length 84 * Currently all messages received from the system manager are either
71 * (16 bytes header + 16 bytes payload = 32 bytes). This knowlege is used to 85 * (16 bytes header + 8 bytes payload = 24 bytes) or (16 bytes header
72 * simplify the logic. 86 * + 16 bytes payload = 32 bytes). This knowlege is used to simplify
87 * the logic.
73 */ 88 */
74 89
75enum { 90enum {
76 PS3_SM_RX_MSG_LEN = 32, 91 PS3_SM_RX_MSG_LEN_MIN = 24,
92 PS3_SM_RX_MSG_LEN_MAX = 32,
77}; 93};
78 94
79/** 95/**
80 * enum ps3_sys_manager_service_id - Message header service_id. 96 * enum ps3_sys_manager_service_id - Message header service_id.
81 * @PS3_SM_SERVICE_ID_REQUEST: guest --> sys_manager. 97 * @PS3_SM_SERVICE_ID_REQUEST: guest --> sys_manager.
82 * @PS3_SM_SERVICE_ID_COMMAND: guest <-- sys_manager. 98 * @PS3_SM_SERVICE_ID_REQUEST_ERROR: guest <-- sys_manager.
83 * @PS3_SM_SERVICE_ID_RESPONSE: guest --> sys_manager. 99 * @PS3_SM_SERVICE_ID_COMMAND: guest <-- sys_manager.
84 * @PS3_SM_SERVICE_ID_SET_ATTR: guest --> sys_manager. 100 * @PS3_SM_SERVICE_ID_RESPONSE: guest --> sys_manager.
85 * @PS3_SM_SERVICE_ID_EXTERN_EVENT: guest <-- sys_manager. 101 * @PS3_SM_SERVICE_ID_SET_ATTR: guest --> sys_manager.
86 * @PS3_SM_SERVICE_ID_SET_NEXT_OP: guest --> sys_manager. 102 * @PS3_SM_SERVICE_ID_EXTERN_EVENT: guest <-- sys_manager.
103 * @PS3_SM_SERVICE_ID_SET_NEXT_OP: guest --> sys_manager.
104 *
105 * PS3_SM_SERVICE_ID_REQUEST_ERROR is returned for invalid data values in a
106 * a PS3_SM_SERVICE_ID_REQUEST message. It also seems to be returned when
107 * a REQUEST message is sent at the wrong time.
87 */ 108 */
88 109
89enum ps3_sys_manager_service_id { 110enum ps3_sys_manager_service_id {
@@ -93,6 +114,7 @@ enum ps3_sys_manager_service_id {
93 PS3_SM_SERVICE_ID_COMMAND = 3, 114 PS3_SM_SERVICE_ID_COMMAND = 3,
94 PS3_SM_SERVICE_ID_EXTERN_EVENT = 4, 115 PS3_SM_SERVICE_ID_EXTERN_EVENT = 4,
95 PS3_SM_SERVICE_ID_SET_NEXT_OP = 5, 116 PS3_SM_SERVICE_ID_SET_NEXT_OP = 5,
117 PS3_SM_SERVICE_ID_REQUEST_ERROR = 6,
96 PS3_SM_SERVICE_ID_SET_ATTR = 8, 118 PS3_SM_SERVICE_ID_SET_ATTR = 8,
97}; 119};
98 120
@@ -185,11 +207,21 @@ enum ps3_sys_manager_cmd {
185}; 207};
186 208
187/** 209/**
210 * ps3_sm_force_power_off - Poweroff helper.
211 *
212 * A global variable used to force a poweroff when the power button has
213 * been pressed irrespective of how init handles the ctrl_alt_del signal.
214 *
215 */
216
217static unsigned int ps3_sm_force_power_off;
218
219/**
188 * ps3_sys_manager_write - Helper to write a two part message to the vuart. 220 * ps3_sys_manager_write - Helper to write a two part message to the vuart.
189 * 221 *
190 */ 222 */
191 223
192static int ps3_sys_manager_write(struct ps3_vuart_port_device *dev, 224static int ps3_sys_manager_write(struct ps3_system_bus_device *dev,
193 const struct ps3_sys_manager_header *header, const void *payload) 225 const struct ps3_sys_manager_header *header, const void *payload)
194{ 226{
195 int result; 227 int result;
@@ -213,15 +245,10 @@ static int ps3_sys_manager_write(struct ps3_vuart_port_device *dev,
213 * 245 *
214 */ 246 */
215 247
216static int ps3_sys_manager_send_attr(struct ps3_vuart_port_device *dev, 248static int ps3_sys_manager_send_attr(struct ps3_system_bus_device *dev,
217 enum ps3_sys_manager_attr attr) 249 enum ps3_sys_manager_attr attr)
218{ 250{
219 static const struct ps3_sys_manager_header header = { 251 struct ps3_sys_manager_header header;
220 .version = 1,
221 .size = 16,
222 .payload_size = 16,
223 .service_id = PS3_SM_SERVICE_ID_SET_ATTR,
224 };
225 struct { 252 struct {
226 u8 version; 253 u8 version;
227 u8 reserved_1[3]; 254 u8 reserved_1[3];
@@ -232,6 +259,12 @@ static int ps3_sys_manager_send_attr(struct ps3_vuart_port_device *dev,
232 259
233 dev_dbg(&dev->core, "%s:%d: %xh\n", __func__, __LINE__, attr); 260 dev_dbg(&dev->core, "%s:%d: %xh\n", __func__, __LINE__, attr);
234 261
262 memset(&header, 0, sizeof(header));
263 header.version = 1;
264 header.size = 16;
265 header.payload_size = 16;
266 header.service_id = PS3_SM_SERVICE_ID_SET_ATTR;
267
235 memset(&payload, 0, sizeof(payload)); 268 memset(&payload, 0, sizeof(payload));
236 payload.version = 1; 269 payload.version = 1;
237 payload.attribute = attr; 270 payload.attribute = attr;
@@ -245,16 +278,11 @@ static int ps3_sys_manager_send_attr(struct ps3_vuart_port_device *dev,
245 * Tell the system manager what to do after this lpar is destroyed. 278 * Tell the system manager what to do after this lpar is destroyed.
246 */ 279 */
247 280
248static int ps3_sys_manager_send_next_op(struct ps3_vuart_port_device *dev, 281static int ps3_sys_manager_send_next_op(struct ps3_system_bus_device *dev,
249 enum ps3_sys_manager_next_op op, 282 enum ps3_sys_manager_next_op op,
250 enum ps3_sys_manager_wake_source wake_source) 283 enum ps3_sys_manager_wake_source wake_source)
251{ 284{
252 static const struct ps3_sys_manager_header header = { 285 struct ps3_sys_manager_header header;
253 .version = 1,
254 .size = 16,
255 .payload_size = 16,
256 .service_id = PS3_SM_SERVICE_ID_SET_NEXT_OP,
257 };
258 struct { 286 struct {
259 u8 version; 287 u8 version;
260 u8 type; 288 u8 type;
@@ -268,6 +296,12 @@ static int ps3_sys_manager_send_next_op(struct ps3_vuart_port_device *dev,
268 296
269 dev_dbg(&dev->core, "%s:%d: (%xh)\n", __func__, __LINE__, op); 297 dev_dbg(&dev->core, "%s:%d: (%xh)\n", __func__, __LINE__, op);
270 298
299 memset(&header, 0, sizeof(header));
300 header.version = 1;
301 header.size = 16;
302 header.payload_size = 16;
303 header.service_id = PS3_SM_SERVICE_ID_SET_NEXT_OP;
304
271 memset(&payload, 0, sizeof(payload)); 305 memset(&payload, 0, sizeof(payload));
272 payload.version = 3; 306 payload.version = 3;
273 payload.type = op; 307 payload.type = op;
@@ -286,32 +320,35 @@ static int ps3_sys_manager_send_next_op(struct ps3_vuart_port_device *dev,
286 * the command is then communicated back to the system manager with a response 320 * the command is then communicated back to the system manager with a response
287 * message. 321 * message.
288 * 322 *
289 * Currently, the only supported request it the 'shutdown self' request. 323 * Currently, the only supported request is the 'shutdown self' request.
290 */ 324 */
291 325
292static int ps3_sys_manager_send_request_shutdown(struct ps3_vuart_port_device *dev) 326static int ps3_sys_manager_send_request_shutdown(
327 struct ps3_system_bus_device *dev)
293{ 328{
294 static const struct ps3_sys_manager_header header = { 329 struct ps3_sys_manager_header header;
295 .version = 1,
296 .size = 16,
297 .payload_size = 16,
298 .service_id = PS3_SM_SERVICE_ID_REQUEST,
299 };
300 struct { 330 struct {
301 u8 version; 331 u8 version;
302 u8 type; 332 u8 type;
303 u8 gos_id; 333 u8 gos_id;
304 u8 reserved_1[13]; 334 u8 reserved_1[13];
305 } static const payload = { 335 } payload;
306 .version = 1,
307 .type = 1, /* shutdown */
308 .gos_id = 0, /* self */
309 };
310 336
311 BUILD_BUG_ON(sizeof(payload) != 16); 337 BUILD_BUG_ON(sizeof(payload) != 16);
312 338
313 dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__); 339 dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__);
314 340
341 memset(&header, 0, sizeof(header));
342 header.version = 1;
343 header.size = 16;
344 header.payload_size = 16;
345 header.service_id = PS3_SM_SERVICE_ID_REQUEST;
346
347 memset(&payload, 0, sizeof(payload));
348 payload.version = 1;
349 payload.type = 1; /* shutdown */
350 payload.gos_id = 0; /* self */
351
315 return ps3_sys_manager_write(dev, &header, &payload); 352 return ps3_sys_manager_write(dev, &header, &payload);
316} 353}
317 354
@@ -323,15 +360,10 @@ static int ps3_sys_manager_send_request_shutdown(struct ps3_vuart_port_device *d
323 * failure of a command sent by the system manager. 360 * failure of a command sent by the system manager.
324 */ 361 */
325 362
326static int ps3_sys_manager_send_response(struct ps3_vuart_port_device *dev, 363static int ps3_sys_manager_send_response(struct ps3_system_bus_device *dev,
327 u64 status) 364 u64 status)
328{ 365{
329 static const struct ps3_sys_manager_header header = { 366 struct ps3_sys_manager_header header;
330 .version = 1,
331 .size = 16,
332 .payload_size = 16,
333 .service_id = PS3_SM_SERVICE_ID_RESPONSE,
334 };
335 struct { 367 struct {
336 u8 version; 368 u8 version;
337 u8 reserved_1[3]; 369 u8 reserved_1[3];
@@ -344,6 +376,12 @@ static int ps3_sys_manager_send_response(struct ps3_vuart_port_device *dev,
344 dev_dbg(&dev->core, "%s:%d: (%s)\n", __func__, __LINE__, 376 dev_dbg(&dev->core, "%s:%d: (%s)\n", __func__, __LINE__,
345 (status ? "nak" : "ack")); 377 (status ? "nak" : "ack"));
346 378
379 memset(&header, 0, sizeof(header));
380 header.version = 1;
381 header.size = 16;
382 header.payload_size = 16;
383 header.service_id = PS3_SM_SERVICE_ID_RESPONSE;
384
347 memset(&payload, 0, sizeof(payload)); 385 memset(&payload, 0, sizeof(payload));
348 payload.version = 1; 386 payload.version = 1;
349 payload.status = status; 387 payload.status = status;
@@ -356,7 +394,7 @@ static int ps3_sys_manager_send_response(struct ps3_vuart_port_device *dev,
356 * 394 *
357 */ 395 */
358 396
359static int ps3_sys_manager_handle_event(struct ps3_vuart_port_device *dev) 397static int ps3_sys_manager_handle_event(struct ps3_system_bus_device *dev)
360{ 398{
361 int result; 399 int result;
362 struct { 400 struct {
@@ -370,7 +408,7 @@ static int ps3_sys_manager_handle_event(struct ps3_vuart_port_device *dev)
370 BUILD_BUG_ON(sizeof(event) != 16); 408 BUILD_BUG_ON(sizeof(event) != 16);
371 409
372 result = ps3_vuart_read(dev, &event, sizeof(event)); 410 result = ps3_vuart_read(dev, &event, sizeof(event));
373 BUG_ON(result); 411 BUG_ON(result && "need to retry here");
374 412
375 if (event.version != 1) { 413 if (event.version != 1) {
376 dev_dbg(&dev->core, "%s:%d: unsupported event version (%u)\n", 414 dev_dbg(&dev->core, "%s:%d: unsupported event version (%u)\n",
@@ -382,11 +420,34 @@ static int ps3_sys_manager_handle_event(struct ps3_vuart_port_device *dev)
382 case PS3_SM_EVENT_POWER_PRESSED: 420 case PS3_SM_EVENT_POWER_PRESSED:
383 dev_dbg(&dev->core, "%s:%d: POWER_PRESSED\n", 421 dev_dbg(&dev->core, "%s:%d: POWER_PRESSED\n",
384 __func__, __LINE__); 422 __func__, __LINE__);
423 ps3_sm_force_power_off = 1;
424 /*
425 * A memory barrier is use here to sync memory since
426 * ps3_sys_manager_final_restart() could be called on
427 * another cpu.
428 */
429 wmb();
430 kill_cad_pid(SIGINT, 1); /* ctrl_alt_del */
385 break; 431 break;
386 case PS3_SM_EVENT_POWER_RELEASED: 432 case PS3_SM_EVENT_POWER_RELEASED:
387 dev_dbg(&dev->core, "%s:%d: POWER_RELEASED (%u ms)\n", 433 dev_dbg(&dev->core, "%s:%d: POWER_RELEASED (%u ms)\n",
388 __func__, __LINE__, event.value); 434 __func__, __LINE__, event.value);
389 kill_cad_pid(SIGINT, 1); 435 break;
436 case PS3_SM_EVENT_RESET_PRESSED:
437 dev_dbg(&dev->core, "%s:%d: RESET_PRESSED\n",
438 __func__, __LINE__);
439 ps3_sm_force_power_off = 0;
440 /*
441 * A memory barrier is use here to sync memory since
442 * ps3_sys_manager_final_restart() could be called on
443 * another cpu.
444 */
445 wmb();
446 kill_cad_pid(SIGINT, 1); /* ctrl_alt_del */
447 break;
448 case PS3_SM_EVENT_RESET_RELEASED:
449 dev_dbg(&dev->core, "%s:%d: RESET_RELEASED (%u ms)\n",
450 __func__, __LINE__, event.value);
390 break; 451 break;
391 case PS3_SM_EVENT_THERMAL_ALERT: 452 case PS3_SM_EVENT_THERMAL_ALERT:
392 dev_dbg(&dev->core, "%s:%d: THERMAL_ALERT (zone %u)\n", 453 dev_dbg(&dev->core, "%s:%d: THERMAL_ALERT (zone %u)\n",
@@ -411,7 +472,7 @@ static int ps3_sys_manager_handle_event(struct ps3_vuart_port_device *dev)
411 * The system manager sends this in reply to a 'request' message from the guest. 472 * The system manager sends this in reply to a 'request' message from the guest.
412 */ 473 */
413 474
414static int ps3_sys_manager_handle_cmd(struct ps3_vuart_port_device *dev) 475static int ps3_sys_manager_handle_cmd(struct ps3_system_bus_device *dev)
415{ 476{
416 int result; 477 int result;
417 struct { 478 struct {
@@ -425,6 +486,7 @@ static int ps3_sys_manager_handle_cmd(struct ps3_vuart_port_device *dev)
425 dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__); 486 dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__);
426 487
427 result = ps3_vuart_read(dev, &cmd, sizeof(cmd)); 488 result = ps3_vuart_read(dev, &cmd, sizeof(cmd));
489 BUG_ON(result && "need to retry here");
428 490
429 if(result) 491 if(result)
430 return result; 492 return result;
@@ -448,9 +510,10 @@ static int ps3_sys_manager_handle_cmd(struct ps3_vuart_port_device *dev)
448/** 510/**
449 * ps3_sys_manager_handle_msg - First stage msg handler. 511 * ps3_sys_manager_handle_msg - First stage msg handler.
450 * 512 *
513 * Can be called directly to manually poll vuart and pump message handler.
451 */ 514 */
452 515
453static int ps3_sys_manager_handle_msg(struct ps3_vuart_port_device *dev) 516static int ps3_sys_manager_handle_msg(struct ps3_system_bus_device *dev)
454{ 517{
455 int result; 518 int result;
456 struct ps3_sys_manager_header header; 519 struct ps3_sys_manager_header header;
@@ -464,12 +527,17 @@ static int ps3_sys_manager_handle_msg(struct ps3_vuart_port_device *dev)
464 if (header.version != 1) { 527 if (header.version != 1) {
465 dev_dbg(&dev->core, "%s:%d: unsupported header version (%u)\n", 528 dev_dbg(&dev->core, "%s:%d: unsupported header version (%u)\n",
466 __func__, __LINE__, header.version); 529 __func__, __LINE__, header.version);
530 dump_sm_header(&header);
467 goto fail_header; 531 goto fail_header;
468 } 532 }
469 533
470 BUILD_BUG_ON(sizeof(header) != 16); 534 BUILD_BUG_ON(sizeof(header) != 16);
471 BUG_ON(header.size != 16); 535
472 BUG_ON(header.payload_size != 16); 536 if (header.size != 16 || (header.payload_size != 8
537 && header.payload_size != 16)) {
538 dump_sm_header(&header);
539 BUG();
540 }
473 541
474 switch (header.service_id) { 542 switch (header.service_id) {
475 case PS3_SM_SERVICE_ID_EXTERN_EVENT: 543 case PS3_SM_SERVICE_ID_EXTERN_EVENT:
@@ -478,6 +546,11 @@ static int ps3_sys_manager_handle_msg(struct ps3_vuart_port_device *dev)
478 case PS3_SM_SERVICE_ID_COMMAND: 546 case PS3_SM_SERVICE_ID_COMMAND:
479 dev_dbg(&dev->core, "%s:%d: COMMAND\n", __func__, __LINE__); 547 dev_dbg(&dev->core, "%s:%d: COMMAND\n", __func__, __LINE__);
480 return ps3_sys_manager_handle_cmd(dev); 548 return ps3_sys_manager_handle_cmd(dev);
549 case PS3_SM_SERVICE_ID_REQUEST_ERROR:
550 dev_dbg(&dev->core, "%s:%d: REQUEST_ERROR\n", __func__,
551 __LINE__);
552 dump_sm_header(&header);
553 break;
481 default: 554 default:
482 dev_dbg(&dev->core, "%s:%d: unknown service_id (%u)\n", 555 dev_dbg(&dev->core, "%s:%d: unknown service_id (%u)\n",
483 __func__, __LINE__, header.service_id); 556 __func__, __LINE__, header.service_id);
@@ -494,45 +567,25 @@ fail_id:
494} 567}
495 568
496/** 569/**
497 * ps3_sys_manager_work - Asyncronous read handler. 570 * ps3_sys_manager_final_power_off - The final platform machine_power_off routine.
498 *
499 * Signaled when a complete message arrives at the vuart port.
500 */
501
502static void ps3_sys_manager_work(struct work_struct *work)
503{
504 struct ps3_vuart_port_device *dev = ps3_vuart_work_to_port_device(work);
505
506 ps3_sys_manager_handle_msg(dev);
507 ps3_vuart_read_async(dev, ps3_sys_manager_work, PS3_SM_RX_MSG_LEN);
508}
509
510struct {
511 struct ps3_vuart_port_device *dev;
512} static drv_priv;
513
514/**
515 * ps3_sys_manager_restart - The final platform machine_restart routine.
516 * 571 *
517 * This routine never returns. The routine disables asyncronous vuart reads 572 * This routine never returns. The routine disables asynchronous vuart reads
518 * then spins calling ps3_sys_manager_handle_msg() to receive and acknowledge 573 * then spins calling ps3_sys_manager_handle_msg() to receive and acknowledge
519 * the shutdown command sent from the system manager. Soon after the 574 * the shutdown command sent from the system manager. Soon after the
520 * acknowledgement is sent the lpar is destroyed by the HV. This routine 575 * acknowledgement is sent the lpar is destroyed by the HV. This routine
521 * should only be called from ps3_restart(). 576 * should only be called from ps3_power_off() through
577 * ps3_sys_manager_ops.power_off.
522 */ 578 */
523 579
524void ps3_sys_manager_restart(void) 580static void ps3_sys_manager_final_power_off(struct ps3_system_bus_device *dev)
525{ 581{
526 struct ps3_vuart_port_device *dev = drv_priv.dev; 582 BUG_ON(!dev);
527
528 BUG_ON(!drv_priv.dev);
529 583
530 dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__); 584 dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__);
531 585
532 ps3_vuart_cancel_async(dev); 586 ps3_vuart_cancel_async(dev);
533 587
534 ps3_sys_manager_send_attr(dev, 0); 588 ps3_sys_manager_send_next_op(dev, PS3_SM_NEXT_OP_SYS_SHUTDOWN,
535 ps3_sys_manager_send_next_op(dev, PS3_SM_NEXT_OP_LPAR_REBOOT,
536 PS3_SM_WAKE_DEFAULT); 589 PS3_SM_WAKE_DEFAULT);
537 ps3_sys_manager_send_request_shutdown(dev); 590 ps3_sys_manager_send_request_shutdown(dev);
538 591
@@ -543,26 +596,33 @@ void ps3_sys_manager_restart(void)
543} 596}
544 597
545/** 598/**
546 * ps3_sys_manager_power_off - The final platform machine_power_off routine. 599 * ps3_sys_manager_final_restart - The final platform machine_restart routine.
547 * 600 *
548 * This routine never returns. The routine disables asyncronous vuart reads 601 * This routine never returns. The routine disables asynchronous vuart reads
549 * then spins calling ps3_sys_manager_handle_msg() to receive and acknowledge 602 * then spins calling ps3_sys_manager_handle_msg() to receive and acknowledge
550 * the shutdown command sent from the system manager. Soon after the 603 * the shutdown command sent from the system manager. Soon after the
551 * acknowledgement is sent the lpar is destroyed by the HV. This routine 604 * acknowledgement is sent the lpar is destroyed by the HV. This routine
552 * should only be called from ps3_power_off(). 605 * should only be called from ps3_restart() through ps3_sys_manager_ops.restart.
553 */ 606 */
554 607
555void ps3_sys_manager_power_off(void) 608static void ps3_sys_manager_final_restart(struct ps3_system_bus_device *dev)
556{ 609{
557 struct ps3_vuart_port_device *dev = drv_priv.dev; 610 BUG_ON(!dev);
558
559 BUG_ON(!drv_priv.dev);
560 611
561 dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__); 612 dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__);
562 613
614 /* Check if we got here via a power button event. */
615
616 if (ps3_sm_force_power_off) {
617 dev_dbg(&dev->core, "%s:%d: forcing poweroff\n",
618 __func__, __LINE__);
619 ps3_sys_manager_final_power_off(dev);
620 }
621
563 ps3_vuart_cancel_async(dev); 622 ps3_vuart_cancel_async(dev);
564 623
565 ps3_sys_manager_send_next_op(dev, PS3_SM_NEXT_OP_SYS_SHUTDOWN, 624 ps3_sys_manager_send_attr(dev, 0);
625 ps3_sys_manager_send_next_op(dev, PS3_SM_NEXT_OP_LPAR_REBOOT,
566 PS3_SM_WAKE_DEFAULT); 626 PS3_SM_WAKE_DEFAULT);
567 ps3_sys_manager_send_request_shutdown(dev); 627 ps3_sys_manager_send_request_shutdown(dev);
568 628
@@ -572,31 +632,60 @@ void ps3_sys_manager_power_off(void)
572 ps3_sys_manager_handle_msg(dev); 632 ps3_sys_manager_handle_msg(dev);
573} 633}
574 634
575static int ps3_sys_manager_probe(struct ps3_vuart_port_device *dev) 635/**
636 * ps3_sys_manager_work - Asynchronous read handler.
637 *
638 * Signaled when PS3_SM_RX_MSG_LEN_MIN bytes arrive at the vuart port.
639 */
640
641static void ps3_sys_manager_work(struct ps3_system_bus_device *dev)
642{
643 ps3_sys_manager_handle_msg(dev);
644 ps3_vuart_read_async(dev, PS3_SM_RX_MSG_LEN_MIN);
645}
646
647static int ps3_sys_manager_probe(struct ps3_system_bus_device *dev)
576{ 648{
577 int result; 649 int result;
650 struct ps3_sys_manager_ops ops;
578 651
579 dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__); 652 dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__);
580 653
581 BUG_ON(drv_priv.dev); 654 ops.power_off = ps3_sys_manager_final_power_off;
582 drv_priv.dev = dev; 655 ops.restart = ps3_sys_manager_final_restart;
656 ops.dev = dev;
657
658 /* ps3_sys_manager_register_ops copies ops. */
659
660 ps3_sys_manager_register_ops(&ops);
583 661
584 result = ps3_sys_manager_send_attr(dev, PS3_SM_ATTR_ALL); 662 result = ps3_sys_manager_send_attr(dev, PS3_SM_ATTR_ALL);
585 BUG_ON(result); 663 BUG_ON(result);
586 664
587 result = ps3_vuart_read_async(dev, ps3_sys_manager_work, 665 result = ps3_vuart_read_async(dev, PS3_SM_RX_MSG_LEN_MIN);
588 PS3_SM_RX_MSG_LEN);
589 BUG_ON(result); 666 BUG_ON(result);
590 667
591 return result; 668 return result;
592} 669}
593 670
671static int ps3_sys_manager_remove(struct ps3_system_bus_device *dev)
672{
673 dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__);
674 return 0;
675}
676
677static void ps3_sys_manager_shutdown(struct ps3_system_bus_device *dev)
678{
679 dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__);
680}
681
594static struct ps3_vuart_port_driver ps3_sys_manager = { 682static struct ps3_vuart_port_driver ps3_sys_manager = {
595 .match_id = PS3_MATCH_ID_SYSTEM_MANAGER, 683 .core.match_id = PS3_MATCH_ID_SYSTEM_MANAGER,
596 .core = { 684 .core.core.name = "ps3_sys_manager",
597 .name = "ps3_sys_manager",
598 },
599 .probe = ps3_sys_manager_probe, 685 .probe = ps3_sys_manager_probe,
686 .remove = ps3_sys_manager_remove,
687 .shutdown = ps3_sys_manager_shutdown,
688 .work = ps3_sys_manager_work,
600}; 689};
601 690
602static int __init ps3_sys_manager_init(void) 691static int __init ps3_sys_manager_init(void)
@@ -608,3 +697,6 @@ static int __init ps3_sys_manager_init(void)
608} 697}
609 698
610module_init(ps3_sys_manager_init); 699module_init(ps3_sys_manager_init);
700/* Module remove not supported. */
701
702MODULE_ALIAS(PS3_MODULE_ALIAS_SYSTEM_MANAGER);
diff --git a/drivers/ps3/vuart.c b/drivers/ps3/vuart.c
index ec2d36a1bc67..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
@@ -83,31 +111,14 @@ struct ports_bmp {
83} __attribute__ ((aligned (32))); 111} __attribute__ ((aligned (32)));
84 112
85#define dump_ports_bmp(_b) _dump_ports_bmp(_b, __func__, __LINE__) 113#define dump_ports_bmp(_b) _dump_ports_bmp(_b, __func__, __LINE__)
86static void __attribute__ ((unused)) _dump_ports_bmp( 114static void __maybe_unused _dump_ports_bmp(
87 const struct ports_bmp* bmp, const char* func, int line) 115 const struct ports_bmp* bmp, const char* func, int line)
88{ 116{
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 __attribute__ ((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)
112{ 123{
113#if defined(DEBUG) 124#if defined(DEBUG)
@@ -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/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 4e4c10a7fd3a..83b071b6ece4 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -246,7 +246,7 @@ comment "Platform RTC drivers"
246config RTC_DRV_CMOS 246config RTC_DRV_CMOS
247 tristate "PC-style 'CMOS'" 247 tristate "PC-style 'CMOS'"
248 depends on RTC_CLASS && (X86 || ALPHA || ARM26 || ARM \ 248 depends on RTC_CLASS && (X86 || ALPHA || ARM26 || ARM \
249 || M32R || ATARI || POWERPC || MIPS) 249 || M32R || ATARI || PPC || MIPS)
250 help 250 help
251 Say "yes" here to get direct support for the real time clock 251 Say "yes" here to get direct support for the real time clock
252 found in every PC or ACPI-based system, and some other boards. 252 found in every PC or ACPI-based system, and some other boards.
diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c
index b63ff8dd7304..cefde58dbad2 100644
--- a/drivers/serial/cpm_uart/cpm_uart_core.c
+++ b/drivers/serial/cpm_uart/cpm_uart_core.c
@@ -678,7 +678,7 @@ static int cpm_uart_tx_pump(struct uart_port *port)
678 } 678 }
679 bdp->cbd_datlen = count; 679 bdp->cbd_datlen = count;
680 bdp->cbd_sc |= BD_SC_READY; 680 bdp->cbd_sc |= BD_SC_READY;
681 __asm__("eieio"); 681 eieio();
682 /* Get next BD. */ 682 /* Get next BD. */
683 if (bdp->cbd_sc & BD_SC_WRAP) 683 if (bdp->cbd_sc & BD_SC_WRAP)
684 bdp = pinfo->tx_bd_base; 684 bdp = pinfo->tx_bd_base;
diff --git a/drivers/serial/of_serial.c b/drivers/serial/of_serial.c
index 7ffdaeaf0545..a64d85821996 100644
--- a/drivers/serial/of_serial.c
+++ b/drivers/serial/of_serial.c
@@ -17,6 +17,11 @@
17#include <asm/of_platform.h> 17#include <asm/of_platform.h>
18#include <asm/prom.h> 18#include <asm/prom.h>
19 19
20struct of_serial_info {
21 int type;
22 int line;
23};
24
20/* 25/*
21 * Fill a struct uart_port for a given device node 26 * Fill a struct uart_port for a given device node
22 */ 27 */
@@ -62,6 +67,7 @@ static int __devinit of_platform_serial_setup(struct of_device *ofdev,
62static int __devinit of_platform_serial_probe(struct of_device *ofdev, 67static int __devinit of_platform_serial_probe(struct of_device *ofdev,
63 const struct of_device_id *id) 68 const struct of_device_id *id)
64{ 69{
70 struct of_serial_info *info;
65 struct uart_port port; 71 struct uart_port port;
66 int port_type; 72 int port_type;
67 int ret; 73 int ret;
@@ -69,30 +75,35 @@ static int __devinit of_platform_serial_probe(struct of_device *ofdev,
69 if (of_find_property(ofdev->node, "used-by-rtas", NULL)) 75 if (of_find_property(ofdev->node, "used-by-rtas", NULL))
70 return -EBUSY; 76 return -EBUSY;
71 77
78 info = kmalloc(sizeof(*info), GFP_KERNEL);
79 if (info == NULL)
80 return -ENOMEM;
81
72 port_type = (unsigned long)id->data; 82 port_type = (unsigned long)id->data;
73 ret = of_platform_serial_setup(ofdev, port_type, &port); 83 ret = of_platform_serial_setup(ofdev, port_type, &port);
74 if (ret) 84 if (ret)
75 goto out; 85 goto out;
76 86
77 switch (port_type) { 87 switch (port_type) {
78 case PORT_UNKNOWN:
79 dev_info(&ofdev->dev, "Unknown serial port found, "
80 "attempting to use 8250 driver\n");
81 /* fallthrough */
82 case PORT_8250 ... PORT_MAX_8250: 88 case PORT_8250 ... PORT_MAX_8250:
83 ret = serial8250_register_port(&port); 89 ret = serial8250_register_port(&port);
84 break; 90 break;
85 default: 91 default:
86 /* need to add code for these */ 92 /* need to add code for these */
93 case PORT_UNKNOWN:
94 dev_info(&ofdev->dev, "Unknown serial port found, ignored\n");
87 ret = -ENODEV; 95 ret = -ENODEV;
88 break; 96 break;
89 } 97 }
90 if (ret < 0) 98 if (ret < 0)
91 goto out; 99 goto out;
92 100
93 ofdev->dev.driver_data = (void *)(unsigned long)ret; 101 info->type = port_type;
102 info->line = ret;
103 ofdev->dev.driver_data = info;
94 return 0; 104 return 0;
95out: 105out:
106 kfree(info);
96 irq_dispose_mapping(port.irq); 107 irq_dispose_mapping(port.irq);
97 return ret; 108 return ret;
98} 109}
@@ -102,8 +113,16 @@ out:
102 */ 113 */
103static int of_platform_serial_remove(struct of_device *ofdev) 114static int of_platform_serial_remove(struct of_device *ofdev)
104{ 115{
105 int line = (unsigned long)ofdev->dev.driver_data; 116 struct of_serial_info *info = ofdev->dev.driver_data;
106 serial8250_unregister_port(line); 117 switch (info->type) {
118 case PORT_8250 ... PORT_MAX_8250:
119 serial8250_unregister_port(info->line);
120 break;
121 default:
122 /* need to add code for these */
123 break;
124 }
125 kfree(info);
107 return 0; 126 return 0;
108} 127}
109 128
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 403dac787ebf..9b7a76be36a0 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -1790,8 +1790,8 @@ config FB_IBM_GXT4500
1790 adaptor, found on some IBM System P (pSeries) machines. 1790 adaptor, found on some IBM System P (pSeries) machines.
1791 1791
1792config FB_PS3 1792config FB_PS3
1793 bool "PS3 GPU framebuffer driver" 1793 tristate "PS3 GPU framebuffer driver"
1794 depends on (FB = y) && PS3_PS3AV 1794 depends on FB && PS3_PS3AV
1795 select FB_SYS_FILLRECT 1795 select FB_SYS_FILLRECT
1796 select FB_SYS_COPYAREA 1796 select FB_SYS_COPYAREA
1797 select FB_SYS_IMAGEBLIT 1797 select FB_SYS_IMAGEBLIT
diff --git a/drivers/video/ps3fb.c b/drivers/video/ps3fb.c
index 9cf92ba5d6e3..08b7ffbbbbd8 100644
--- a/drivers/video/ps3fb.c
+++ b/drivers/video/ps3fb.c
@@ -27,7 +27,6 @@
27#include <linux/vmalloc.h> 27#include <linux/vmalloc.h>
28#include <linux/delay.h> 28#include <linux/delay.h>
29#include <linux/interrupt.h> 29#include <linux/interrupt.h>
30#include <linux/platform_device.h>
31#include <linux/console.h> 30#include <linux/console.h>
32#include <linux/ioctl.h> 31#include <linux/ioctl.h>
33#include <linux/notifier.h> 32#include <linux/notifier.h>
@@ -46,6 +45,9 @@
46#include <asm/ps3fb.h> 45#include <asm/ps3fb.h>
47#include <asm/ps3.h> 46#include <asm/ps3.h>
48 47
48
49#define DEVICE_NAME "ps3fb"
50
49#ifdef PS3FB_DEBUG 51#ifdef PS3FB_DEBUG
50#define DPRINTK(fmt, args...) printk("%s: " fmt, __func__ , ##args) 52#define DPRINTK(fmt, args...) printk("%s: " fmt, __func__ , ##args)
51#else 53#else
@@ -126,7 +128,6 @@ struct gpu_driver_info {
126 128
127struct ps3fb_priv { 129struct ps3fb_priv {
128 unsigned int irq_no; 130 unsigned int irq_no;
129 void *dev;
130 131
131 u64 context_handle, memory_handle; 132 u64 context_handle, memory_handle;
132 void *xdr_ea; 133 void *xdr_ea;
@@ -171,7 +172,7 @@ static const struct ps3fb_res_table ps3fb_res[] = {
171 { 0, 0, 0, 0 , 0} }; 172 { 0, 0, 0, 0 , 0} };
172 173
173/* default resolution */ 174/* default resolution */
174#define GPU_RES_INDEX 0 /* 720 x 480 */ 175#define GPU_RES_INDEX 0 /* 720 x 480 */
175 176
176static const struct fb_videomode ps3fb_modedb[] = { 177static const struct fb_videomode ps3fb_modedb[] = {
177 /* 60 Hz broadcast modes (modes "1" to "5") */ 178 /* 60 Hz broadcast modes (modes "1" to "5") */
@@ -298,10 +299,9 @@ static const struct fb_videomode ps3fb_modedb[] = {
298#define FB_OFF(i) (GPU_OFFSET - VP_OFF(i) % GPU_OFFSET) 299#define FB_OFF(i) (GPU_OFFSET - VP_OFF(i) % GPU_OFFSET)
299 300
300static int ps3fb_mode; 301static int ps3fb_mode;
301module_param(ps3fb_mode, bool, 0); 302module_param(ps3fb_mode, int, 0);
302
303static char *mode_option __initdata;
304 303
304static char *mode_option __devinitdata;
305 305
306static int ps3fb_get_res_table(u32 xres, u32 yres) 306static int ps3fb_get_res_table(u32 xres, u32 yres)
307{ 307{
@@ -681,15 +681,15 @@ int ps3fb_wait_for_vsync(u32 crtc)
681 681
682EXPORT_SYMBOL_GPL(ps3fb_wait_for_vsync); 682EXPORT_SYMBOL_GPL(ps3fb_wait_for_vsync);
683 683
684void ps3fb_flip_ctl(int on) 684void ps3fb_flip_ctl(int on, void *data)
685{ 685{
686 struct ps3fb_priv *priv = data;
686 if (on) 687 if (on)
687 atomic_dec_if_positive(&ps3fb.ext_flip); 688 atomic_dec_if_positive(&priv->ext_flip);
688 else 689 else
689 atomic_inc(&ps3fb.ext_flip); 690 atomic_inc(&priv->ext_flip);
690} 691}
691 692
692EXPORT_SYMBOL_GPL(ps3fb_flip_ctl);
693 693
694 /* 694 /*
695 * ioctl 695 * ioctl
@@ -851,37 +851,9 @@ static irqreturn_t ps3fb_vsync_interrupt(int irq, void *ptr)
851 return IRQ_HANDLED; 851 return IRQ_HANDLED;
852} 852}
853 853
854#ifndef MODULE
855static int __init ps3fb_setup(char *options)
856{
857 char *this_opt;
858 int mode = 0;
859
860 if (!options || !*options)
861 return 0; /* no options */
862
863 while ((this_opt = strsep(&options, ",")) != NULL) {
864 if (!*this_opt)
865 continue;
866 if (!strncmp(this_opt, "mode:", 5))
867 mode = simple_strtoul(this_opt + 5, NULL, 0);
868 else
869 mode_option = this_opt;
870 }
871 return mode;
872}
873#endif /* MODULE */
874
875 /*
876 * Initialisation
877 */
878 854
879static void ps3fb_platform_release(struct device *device) 855static int ps3fb_vsync_settings(struct gpu_driver_info *dinfo,
880{ 856 struct ps3_system_bus_device *dev)
881 /* This is called when the reference count goes to zero. */
882}
883
884static int ps3fb_vsync_settings(struct gpu_driver_info *dinfo, void *dev)
885{ 857{
886 int error; 858 int error;
887 859
@@ -897,7 +869,6 @@ static int ps3fb_vsync_settings(struct gpu_driver_info *dinfo, void *dev)
897 return -EINVAL; 869 return -EINVAL;
898 } 870 }
899 871
900 ps3fb.dev = dev;
901 error = ps3_irq_plug_setup(PS3_BINDING_CPU_ANY, dinfo->irq.irq_outlet, 872 error = ps3_irq_plug_setup(PS3_BINDING_CPU_ANY, dinfo->irq.irq_outlet,
902 &ps3fb.irq_no); 873 &ps3fb.irq_no);
903 if (error) { 874 if (error) {
@@ -907,7 +878,7 @@ static int ps3fb_vsync_settings(struct gpu_driver_info *dinfo, void *dev)
907 } 878 }
908 879
909 error = request_irq(ps3fb.irq_no, ps3fb_vsync_interrupt, IRQF_DISABLED, 880 error = request_irq(ps3fb.irq_no, ps3fb_vsync_interrupt, IRQF_DISABLED,
910 "ps3fb vsync", ps3fb.dev); 881 DEVICE_NAME, dev);
911 if (error) { 882 if (error) {
912 printk(KERN_ERR "%s: request_irq failed %d\n", __func__, 883 printk(KERN_ERR "%s: request_irq failed %d\n", __func__,
913 error); 884 error);
@@ -966,16 +937,45 @@ static struct fb_ops ps3fb_ops = {
966}; 937};
967 938
968static struct fb_fix_screeninfo ps3fb_fix __initdata = { 939static struct fb_fix_screeninfo ps3fb_fix __initdata = {
969 .id = "PS3 FB", 940 .id = DEVICE_NAME,
970 .type = FB_TYPE_PACKED_PIXELS, 941 .type = FB_TYPE_PACKED_PIXELS,
971 .visual = FB_VISUAL_TRUECOLOR, 942 .visual = FB_VISUAL_TRUECOLOR,
972 .accel = FB_ACCEL_NONE, 943 .accel = FB_ACCEL_NONE,
973}; 944};
974 945
975static int __init ps3fb_probe(struct platform_device *dev) 946static int ps3fb_set_sync(void)
947{
948 int status;
949
950#ifdef HEAD_A
951 status = lv1_gpu_context_attribute(0x0,
952 L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC,
953 0, L1GPU_DISPLAY_SYNC_VSYNC, 0, 0);
954 if (status) {
955 printk(KERN_ERR "%s: lv1_gpu_context_attribute DISPLAY_SYNC "
956 "failed: %d\n", __func__, status);
957 return -1;
958 }
959#endif
960#ifdef HEAD_B
961 status = lv1_gpu_context_attribute(0x0,
962 L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC,
963 1, L1GPU_DISPLAY_SYNC_VSYNC, 0, 0);
964
965 if (status) {
966 printk(KERN_ERR "%s: lv1_gpu_context_attribute DISPLAY_MODE "
967 "failed: %d\n", __func__, status);
968 return -1;
969 }
970#endif
971 return 0;
972}
973
974static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev)
976{ 975{
977 struct fb_info *info; 976 struct fb_info *info;
978 int retval = -ENOMEM; 977 int retval = -ENOMEM;
978 u32 xres, yres;
979 u64 ddr_lpar = 0; 979 u64 ddr_lpar = 0;
980 u64 lpar_dma_control = 0; 980 u64 lpar_dma_control = 0;
981 u64 lpar_driver_info = 0; 981 u64 lpar_driver_info = 0;
@@ -986,6 +986,30 @@ static int __init ps3fb_probe(struct platform_device *dev)
986 unsigned long offset; 986 unsigned long offset;
987 struct task_struct *task; 987 struct task_struct *task;
988 988
989 status = ps3_open_hv_device(dev);
990 if (status) {
991 printk(KERN_ERR "%s: ps3_open_hv_device failed\n", __func__);
992 goto err;
993 }
994
995 if (!ps3fb_mode)
996 ps3fb_mode = ps3av_get_mode();
997 DPRINTK("ps3av_mode:%d\n", ps3fb_mode);
998
999 if (ps3fb_mode > 0 &&
1000 !ps3av_video_mode2res(ps3fb_mode, &xres, &yres)) {
1001 ps3fb.res_index = ps3fb_get_res_table(xres, yres);
1002 DPRINTK("res_index:%d\n", ps3fb.res_index);
1003 } else
1004 ps3fb.res_index = GPU_RES_INDEX;
1005
1006 atomic_set(&ps3fb.f_count, -1); /* fbcon opens ps3fb */
1007 atomic_set(&ps3fb.ext_flip, 0); /* for flip with vsync */
1008 init_waitqueue_head(&ps3fb.wait_vsync);
1009 ps3fb.num_frames = 1;
1010
1011 ps3fb_set_sync();
1012
989 /* get gpu context handle */ 1013 /* get gpu context handle */
990 status = lv1_gpu_memory_allocate(DDR_SIZE, 0, 0, 0, 0, 1014 status = lv1_gpu_memory_allocate(DDR_SIZE, 0, 0, 0, 0,
991 &ps3fb.memory_handle, &ddr_lpar); 1015 &ps3fb.memory_handle, &ddr_lpar);
@@ -1029,7 +1053,7 @@ static int __init ps3fb_probe(struct platform_device *dev)
1029 * leakage into userspace 1053 * leakage into userspace
1030 */ 1054 */
1031 memset(ps3fb.xdr_ea, 0, ps3fb_videomemory.size); 1055 memset(ps3fb.xdr_ea, 0, ps3fb_videomemory.size);
1032 info = framebuffer_alloc(sizeof(u32) * 16, &dev->dev); 1056 info = framebuffer_alloc(sizeof(u32) * 16, &dev->core);
1033 if (!info) 1057 if (!info)
1034 goto err_free_irq; 1058 goto err_free_irq;
1035 1059
@@ -1061,19 +1085,20 @@ static int __init ps3fb_probe(struct platform_device *dev)
1061 if (retval < 0) 1085 if (retval < 0)
1062 goto err_fb_dealloc; 1086 goto err_fb_dealloc;
1063 1087
1064 platform_set_drvdata(dev, info); 1088 dev->core.driver_data = info;
1065 1089
1066 printk(KERN_INFO 1090 printk(KERN_INFO
1067 "fb%d: PS3 frame buffer device, using %ld KiB of video memory\n", 1091 "fb%d: PS3 frame buffer device, using %ld KiB of video memory\n",
1068 info->node, ps3fb_videomemory.size >> 10); 1092 info->node, ps3fb_videomemory.size >> 10);
1069 1093
1070 task = kthread_run(ps3fbd, info, "ps3fbd"); 1094 task = kthread_run(ps3fbd, info, DEVICE_NAME);
1071 if (IS_ERR(task)) { 1095 if (IS_ERR(task)) {
1072 retval = PTR_ERR(task); 1096 retval = PTR_ERR(task);
1073 goto err_unregister_framebuffer; 1097 goto err_unregister_framebuffer;
1074 } 1098 }
1075 1099
1076 ps3fb.task = task; 1100 ps3fb.task = task;
1101 ps3av_register_flip_ctl(ps3fb_flip_ctl, &ps3fb);
1077 1102
1078 return 0; 1103 return 0;
1079 1104
@@ -1084,7 +1109,7 @@ err_fb_dealloc:
1084err_framebuffer_release: 1109err_framebuffer_release:
1085 framebuffer_release(info); 1110 framebuffer_release(info);
1086err_free_irq: 1111err_free_irq:
1087 free_irq(ps3fb.irq_no, ps3fb.dev); 1112 free_irq(ps3fb.irq_no, dev);
1088 ps3_irq_plug_destroy(ps3fb.irq_no); 1113 ps3_irq_plug_destroy(ps3fb.irq_no);
1089err_iounmap_dinfo: 1114err_iounmap_dinfo:
1090 iounmap((u8 __iomem *)ps3fb.dinfo); 1115 iounmap((u8 __iomem *)ps3fb.dinfo);
@@ -1096,26 +1121,30 @@ err:
1096 return retval; 1121 return retval;
1097} 1122}
1098 1123
1099static void ps3fb_shutdown(struct platform_device *dev) 1124static int ps3fb_shutdown(struct ps3_system_bus_device *dev)
1100{ 1125{
1101 ps3fb_flip_ctl(0); /* flip off */ 1126 int status;
1127 struct fb_info *info = dev->core.driver_data;
1128
1129 DPRINTK(" -> %s:%d\n", __func__, __LINE__);
1130
1131 ps3fb_flip_ctl(0, &ps3fb); /* flip off */
1102 ps3fb.dinfo->irq.mask = 0; 1132 ps3fb.dinfo->irq.mask = 0;
1103 free_irq(ps3fb.irq_no, ps3fb.dev);
1104 ps3_irq_plug_destroy(ps3fb.irq_no);
1105 iounmap((u8 __iomem *)ps3fb.dinfo);
1106}
1107 1133
1108void ps3fb_cleanup(void) 1134 if (info) {
1109{ 1135 unregister_framebuffer(info);
1110 int status; 1136 fb_dealloc_cmap(&info->cmap);
1137 framebuffer_release(info);
1138 }
1111 1139
1140 ps3av_register_flip_ctl(NULL, NULL);
1112 if (ps3fb.task) { 1141 if (ps3fb.task) {
1113 struct task_struct *task = ps3fb.task; 1142 struct task_struct *task = ps3fb.task;
1114 ps3fb.task = NULL; 1143 ps3fb.task = NULL;
1115 kthread_stop(task); 1144 kthread_stop(task);
1116 } 1145 }
1117 if (ps3fb.irq_no) { 1146 if (ps3fb.irq_no) {
1118 free_irq(ps3fb.irq_no, ps3fb.dev); 1147 free_irq(ps3fb.irq_no, dev);
1119 ps3_irq_plug_destroy(ps3fb.irq_no); 1148 ps3_irq_plug_destroy(ps3fb.irq_no);
1120 } 1149 }
1121 iounmap((u8 __iomem *)ps3fb.dinfo); 1150 iounmap((u8 __iomem *)ps3fb.dinfo);
@@ -1128,134 +1157,69 @@ void ps3fb_cleanup(void)
1128 if (status) 1157 if (status)
1129 DPRINTK("lv1_gpu_memory_free failed: %d\n", status); 1158 DPRINTK("lv1_gpu_memory_free failed: %d\n", status);
1130 1159
1131 ps3av_dev_close(); 1160 ps3_close_hv_device(dev);
1132} 1161 DPRINTK(" <- %s:%d\n", __func__, __LINE__);
1133 1162
1134EXPORT_SYMBOL_GPL(ps3fb_cleanup);
1135
1136static int ps3fb_remove(struct platform_device *dev)
1137{
1138 struct fb_info *info = platform_get_drvdata(dev);
1139
1140 if (info) {
1141 unregister_framebuffer(info);
1142 fb_dealloc_cmap(&info->cmap);
1143 framebuffer_release(info);
1144 }
1145 ps3fb_cleanup();
1146 return 0; 1163 return 0;
1147} 1164}
1148 1165
1149static struct platform_driver ps3fb_driver = { 1166static struct ps3_system_bus_driver ps3fb_driver = {
1150 .probe = ps3fb_probe, 1167 .match_id = PS3_MATCH_ID_GRAPHICS,
1151 .remove = ps3fb_remove, 1168 .core.name = DEVICE_NAME,
1152 .shutdown = ps3fb_shutdown, 1169 .core.owner = THIS_MODULE,
1153 .driver = { .name = "ps3fb" } 1170 .probe = ps3fb_probe,
1154}; 1171 .remove = ps3fb_shutdown,
1155 1172 .shutdown = ps3fb_shutdown,
1156static struct platform_device ps3fb_device = {
1157 .name = "ps3fb",
1158 .id = 0,
1159 .dev = { .release = ps3fb_platform_release }
1160}; 1173};
1161 1174
1162int ps3fb_set_sync(void) 1175static int __init ps3fb_setup(void)
1163{ 1176{
1164 int status; 1177 char *options;
1165 1178
1166#ifdef HEAD_A 1179#ifdef MODULE
1167 status = lv1_gpu_context_attribute(0x0,
1168 L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC,
1169 0, L1GPU_DISPLAY_SYNC_VSYNC, 0, 0);
1170 if (status) {
1171 printk(KERN_ERR
1172 "%s: lv1_gpu_context_attribute DISPLAY_SYNC failed: %d\n",
1173 __func__, status);
1174 return -1;
1175 }
1176#endif
1177#ifdef HEAD_B
1178 status = lv1_gpu_context_attribute(0x0,
1179 L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC,
1180 1, L1GPU_DISPLAY_SYNC_VSYNC, 0, 0);
1181
1182 if (status) {
1183 printk(KERN_ERR
1184 "%s: lv1_gpu_context_attribute DISPLAY_MODE failed: %d\n",
1185 __func__, status);
1186 return -1;
1187 }
1188#endif
1189 return 0; 1180 return 0;
1190}
1191
1192EXPORT_SYMBOL_GPL(ps3fb_set_sync);
1193
1194static int __init ps3fb_init(void)
1195{
1196 int error;
1197#ifndef MODULE
1198 int mode;
1199 char *option = NULL;
1200
1201 if (fb_get_options("ps3fb", &option))
1202 goto err;
1203#endif 1181#endif
1204 1182
1205 if (!ps3fb_videomemory.address) 1183 if (fb_get_options(DEVICE_NAME, &options))
1206 goto err; 1184 return -ENXIO;
1207
1208 error = ps3av_dev_open();
1209 if (error) {
1210 printk(KERN_ERR "%s: ps3av_dev_open failed\n", __func__);
1211 goto err;
1212 }
1213 1185
1214 ps3fb_mode = ps3av_get_mode(); 1186 if (!options || !*options)
1215 DPRINTK("ps3av_mode:%d\n", ps3fb_mode); 1187 return 0;
1216#ifndef MODULE
1217 mode = ps3fb_setup(option); /* check boot option */
1218 if (mode)
1219 ps3fb_mode = mode;
1220#endif
1221 if (ps3fb_mode > 0) {
1222 u32 xres, yres;
1223 ps3av_video_mode2res(ps3fb_mode, &xres, &yres);
1224 ps3fb.res_index = ps3fb_get_res_table(xres, yres);
1225 DPRINTK("res_index:%d\n", ps3fb.res_index);
1226 } else
1227 ps3fb.res_index = GPU_RES_INDEX;
1228 1188
1229 atomic_set(&ps3fb.f_count, -1); /* fbcon opens ps3fb */ 1189 while (1) {
1230 atomic_set(&ps3fb.ext_flip, 0); /* for flip with vsync */ 1190 char *this_opt = strsep(&options, ",");
1231 init_waitqueue_head(&ps3fb.wait_vsync);
1232 ps3fb.num_frames = 1;
1233 1191
1234 error = platform_driver_register(&ps3fb_driver); 1192 if (!this_opt)
1235 if (!error) { 1193 break;
1236 error = platform_device_register(&ps3fb_device); 1194 if (!*this_opt)
1237 if (error) 1195 continue;
1238 platform_driver_unregister(&ps3fb_driver); 1196 if (!strncmp(this_opt, "mode:", 5))
1197 ps3fb_mode = simple_strtoul(this_opt + 5, NULL, 0);
1198 else
1199 mode_option = this_opt;
1239 } 1200 }
1201 return 0;
1202}
1240 1203
1241 ps3fb_set_sync(); 1204static int __init ps3fb_init(void)
1242 1205{
1243 return error; 1206 if (!ps3fb_videomemory.address || ps3fb_setup())
1207 return -ENXIO;
1244 1208
1245err: 1209 return ps3_system_bus_driver_register(&ps3fb_driver);
1246 return -ENXIO;
1247} 1210}
1248 1211
1249module_init(ps3fb_init);
1250
1251#ifdef MODULE
1252static void __exit ps3fb_exit(void) 1212static void __exit ps3fb_exit(void)
1253{ 1213{
1254 platform_device_unregister(&ps3fb_device); 1214 DPRINTK(" -> %s:%d\n", __func__, __LINE__);
1255 platform_driver_unregister(&ps3fb_driver); 1215 ps3_system_bus_driver_unregister(&ps3fb_driver);
1216 DPRINTK(" <- %s:%d\n", __func__, __LINE__);
1256} 1217}
1257 1218
1219module_init(ps3fb_init);
1258module_exit(ps3fb_exit); 1220module_exit(ps3fb_exit);
1259 1221
1260MODULE_LICENSE("GPL"); 1222MODULE_LICENSE("GPL");
1261#endif /* MODULE */ 1223MODULE_DESCRIPTION("PS3 GPU Frame Buffer Driver");
1224MODULE_AUTHOR("Sony Computer Entertainment Inc.");
1225MODULE_ALIAS(PS3_MODULE_ALIAS_GRAPHICS);