aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-16 20:58:08 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-16 20:58:08 -0400
commit489de30259e667d7bc47da9da44a0270b050cd97 (patch)
tree6807814f443fe2c5d041c3bc3fe3ca8d22a955ca /arch/powerpc/platforms
parent1f1c2881f673671539b25686df463518d69c4649 (diff)
parentbf22f6fe2d72b4d7e9035be8ceb340414cf490e3 (diff)
Merge branch 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc
* 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc: (209 commits) [POWERPC] Create add_rtc() function to enable the RTC CMOS driver [POWERPC] Add H_ILLAN_ATTRIBUTES hcall number [POWERPC] xilinxfb: Parameterize xilinxfb platform device registration [POWERPC] Oprofile support for Power 5++ [POWERPC] Enable arbitary speed tty ioctls and split input/output speed [POWERPC] Make drivers/char/hvc_console.c:khvcd() static [POWERPC] Remove dead code for preventing pread() and pwrite() calls [POWERPC] Remove unnecessary #undef printk from prom.c [POWERPC] Fix typo in Ebony default DTS [POWERPC] Check for NULL ppc_md.init_IRQ() before calling [POWERPC] Remove extra return statement [POWERPC] pasemi: Don't auto-select CONFIG_EMBEDDED [POWERPC] pasemi: Rename platform [POWERPC] arch/powerpc/kernel/sysfs.c: Move NUMA exports [POWERPC] Add __read_mostly support for powerpc [POWERPC] Modify sched_clock() to make CONFIG_PRINTK_TIME more sane [POWERPC] Create a dummy zImage if no valid platform has been selected [POWERPC] PS3: Bootwrapper support. [POWERPC] powermac i2c: Use mutex [POWERPC] Schedule removal of arch/ppc ... Fixed up conflicts manually in: Documentation/feature-removal-schedule.txt arch/powerpc/kernel/pci_32.c arch/powerpc/kernel/pci_64.c include/asm-powerpc/pci.h and asked the powerpc people to double-check the result..
Diffstat (limited to 'arch/powerpc/platforms')
-rw-r--r--arch/powerpc/platforms/52xx/efika.c13
-rw-r--r--arch/powerpc/platforms/52xx/lite5200.c2
-rw-r--r--arch/powerpc/platforms/52xx/mpc52xx_pci.c18
-rw-r--r--arch/powerpc/platforms/52xx/mpc52xx_pm.c8
-rw-r--r--arch/powerpc/platforms/82xx/Kconfig2
-rw-r--r--arch/powerpc/platforms/82xx/mpc82xx_ads.c17
-rw-r--r--arch/powerpc/platforms/83xx/Kconfig2
-rw-r--r--arch/powerpc/platforms/83xx/Makefile2
-rw-r--r--arch/powerpc/platforms/83xx/mpc8313_rdb.c8
-rw-r--r--arch/powerpc/platforms/83xx/mpc832x_mds.c7
-rw-r--r--arch/powerpc/platforms/83xx/mpc832x_rdb.c7
-rw-r--r--arch/powerpc/platforms/83xx/mpc834x_itx.c9
-rw-r--r--arch/powerpc/platforms/83xx/mpc834x_mds.c56
-rw-r--r--arch/powerpc/platforms/83xx/mpc836x_mds.c7
-rw-r--r--arch/powerpc/platforms/83xx/mpc83xx.h34
-rw-r--r--arch/powerpc/platforms/83xx/pci.c18
-rw-r--r--arch/powerpc/platforms/83xx/usb.c181
-rw-r--r--arch/powerpc/platforms/85xx/misc.c32
-rw-r--r--arch/powerpc/platforms/85xx/mpc8544_ds.c15
-rw-r--r--arch/powerpc/platforms/85xx/mpc85xx.h2
-rw-r--r--arch/powerpc/platforms/85xx/mpc85xx_ads.c32
-rw-r--r--arch/powerpc/platforms/85xx/mpc85xx_cds.c116
-rw-r--r--arch/powerpc/platforms/85xx/mpc85xx_mds.c28
-rw-r--r--arch/powerpc/platforms/85xx/pci.c11
-rw-r--r--arch/powerpc/platforms/86xx/Kconfig2
-rw-r--r--arch/powerpc/platforms/86xx/mpc86xx.h11
-rw-r--r--arch/powerpc/platforms/86xx/mpc86xx_hpcn.c27
-rw-r--r--arch/powerpc/platforms/86xx/pci.c67
-rw-r--r--arch/powerpc/platforms/8xx/m8xx_setup.c5
-rw-r--r--arch/powerpc/platforms/8xx/mpc885ads_setup.c71
-rw-r--r--arch/powerpc/platforms/Kconfig29
-rw-r--r--arch/powerpc/platforms/Kconfig.cputype221
-rw-r--r--arch/powerpc/platforms/apus/Kconfig130
-rw-r--r--arch/powerpc/platforms/cell/io-workarounds.c2
-rw-r--r--arch/powerpc/platforms/cell/spu_base.c59
-rw-r--r--arch/powerpc/platforms/cell/spufs/backing_ops.c6
-rw-r--r--arch/powerpc/platforms/cell/spufs/context.c15
-rw-r--r--arch/powerpc/platforms/cell/spufs/fault.c29
-rw-r--r--arch/powerpc/platforms/cell/spufs/file.c149
-rw-r--r--arch/powerpc/platforms/cell/spufs/inode.c10
-rw-r--r--arch/powerpc/platforms/cell/spufs/run.c45
-rw-r--r--arch/powerpc/platforms/cell/spufs/sched.c476
-rw-r--r--arch/powerpc/platforms/cell/spufs/spu_restore.c2
-rw-r--r--arch/powerpc/platforms/cell/spufs/spu_save.c2
-rw-r--r--arch/powerpc/platforms/cell/spufs/spufs.h84
-rw-r--r--arch/powerpc/platforms/cell/spufs/switch.c18
-rw-r--r--arch/powerpc/platforms/chrp/Kconfig1
-rw-r--r--arch/powerpc/platforms/chrp/Makefile3
-rw-r--r--arch/powerpc/platforms/chrp/pci.c7
-rw-r--r--arch/powerpc/platforms/embedded6xx/Kconfig2
-rw-r--r--arch/powerpc/platforms/embedded6xx/holly.c2
-rw-r--r--arch/powerpc/platforms/embedded6xx/linkstation.c10
-rw-r--r--arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c9
-rw-r--r--arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.h5
-rw-r--r--arch/powerpc/platforms/iseries/call_hpt.h9
-rw-r--r--arch/powerpc/platforms/iseries/htab.c8
-rw-r--r--arch/powerpc/platforms/iseries/pci.c7
-rw-r--r--arch/powerpc/platforms/iseries/setup.c6
-rw-r--r--arch/powerpc/platforms/maple/pci.c41
-rw-r--r--arch/powerpc/platforms/pasemi/Kconfig9
-rw-r--r--arch/powerpc/platforms/pasemi/Makefile1
-rw-r--r--arch/powerpc/platforms/pasemi/electra_ide.c96
-rw-r--r--arch/powerpc/platforms/pasemi/pci.c24
-rw-r--r--arch/powerpc/platforms/pasemi/setup.c2
-rw-r--r--arch/powerpc/platforms/powermac/Kconfig1
-rw-r--r--arch/powerpc/platforms/powermac/low_i2c.c23
-rw-r--r--arch/powerpc/platforms/powermac/pci.c46
-rw-r--r--arch/powerpc/platforms/ps3/Kconfig26
-rw-r--r--arch/powerpc/platforms/ps3/Makefile1
-rw-r--r--arch/powerpc/platforms/ps3/device-init.c785
-rw-r--r--arch/powerpc/platforms/ps3/htab.c31
-rw-r--r--arch/powerpc/platforms/ps3/interrupt.c272
-rw-r--r--arch/powerpc/platforms/ps3/mm.c632
-rw-r--r--arch/powerpc/platforms/ps3/os-area.c4
-rw-r--r--arch/powerpc/platforms/ps3/platform.h43
-rw-r--r--arch/powerpc/platforms/ps3/repository.c586
-rw-r--r--arch/powerpc/platforms/ps3/setup.c105
-rw-r--r--arch/powerpc/platforms/ps3/smp.c18
-rw-r--r--arch/powerpc/platforms/ps3/spu.c13
-rw-r--r--arch/powerpc/platforms/ps3/system-bus.c562
-rw-r--r--arch/powerpc/platforms/ps3/time.c2
-rw-r--r--arch/powerpc/platforms/pseries/Makefile2
-rw-r--r--arch/powerpc/platforms/pseries/eeh.c19
-rw-r--r--arch/powerpc/platforms/pseries/eeh_cache.c5
-rw-r--r--arch/powerpc/platforms/pseries/eeh_driver.c6
-rw-r--r--arch/powerpc/platforms/pseries/eeh_sysfs.c87
-rw-r--r--arch/powerpc/platforms/pseries/lpar.c17
-rw-r--r--arch/powerpc/platforms/pseries/pci_dlpar.c9
-rw-r--r--arch/powerpc/platforms/pseries/plpar_wrappers.h15
-rw-r--r--arch/powerpc/platforms/pseries/pseries.h2
-rw-r--r--arch/powerpc/platforms/pseries/reconfig.c2
-rw-r--r--arch/powerpc/platforms/pseries/setup.c2
-rw-r--r--arch/powerpc/platforms/pseries/xics.c53
93 files changed, 4214 insertions, 1484 deletions
diff --git a/arch/powerpc/platforms/52xx/efika.c b/arch/powerpc/platforms/52xx/efika.c
index f591a9fc19b9..4be6e7a17b66 100644
--- a/arch/powerpc/platforms/52xx/efika.c
+++ b/arch/powerpc/platforms/52xx/efika.c
@@ -54,7 +54,7 @@ static int rtas_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
54 struct pci_controller *hose = bus->sysdata; 54 struct pci_controller *hose = bus->sysdata;
55 unsigned long addr = (offset & 0xff) | ((devfn & 0xff) << 8) 55 unsigned long addr = (offset & 0xff) | ((devfn & 0xff) << 8)
56 | (((bus->number - hose->first_busno) & 0xff) << 16) 56 | (((bus->number - hose->first_busno) & 0xff) << 16)
57 | (hose->index << 24); 57 | (hose->global_number << 24);
58 int ret = -1; 58 int ret = -1;
59 int rval; 59 int rval;
60 60
@@ -69,7 +69,7 @@ static int rtas_write_config(struct pci_bus *bus, unsigned int devfn,
69 struct pci_controller *hose = bus->sysdata; 69 struct pci_controller *hose = bus->sysdata;
70 unsigned long addr = (offset & 0xff) | ((devfn & 0xff) << 8) 70 unsigned long addr = (offset & 0xff) | ((devfn & 0xff) << 8)
71 | (((bus->number - hose->first_busno) & 0xff) << 16) 71 | (((bus->number - hose->first_busno) & 0xff) << 16)
72 | (hose->index << 24); 72 | (hose->global_number << 24);
73 int rval; 73 int rval;
74 74
75 rval = rtas_call(rtas_token("write-pci-config"), 3, 1, NULL, 75 rval = rtas_call(rtas_token("write-pci-config"), 3, 1, NULL,
@@ -83,7 +83,7 @@ static struct pci_ops rtas_pci_ops = {
83}; 83};
84 84
85 85
86void __init efika_pcisetup(void) 86static void __init efika_pcisetup(void)
87{ 87{
88 const int *bus_range; 88 const int *bus_range;
89 int len; 89 int len;
@@ -128,7 +128,7 @@ void __init efika_pcisetup(void)
128 printk(" controlled by %s\n", pcictrl->full_name); 128 printk(" controlled by %s\n", pcictrl->full_name);
129 printk("\n"); 129 printk("\n");
130 130
131 hose = pcibios_alloc_controller(); 131 hose = pcibios_alloc_controller(of_node_get(pcictrl));
132 if (!hose) { 132 if (!hose) {
133 printk(KERN_WARNING EFIKA_PLATFORM_NAME 133 printk(KERN_WARNING EFIKA_PLATFORM_NAME
134 ": Can't allocate PCI controller structure for %s\n", 134 ": Can't allocate PCI controller structure for %s\n",
@@ -136,7 +136,6 @@ void __init efika_pcisetup(void)
136 return; 136 return;
137 } 137 }
138 138
139 hose->arch_data = of_node_get(pcictrl);
140 hose->first_busno = bus_range[0]; 139 hose->first_busno = bus_range[0];
141 hose->last_busno = bus_range[1]; 140 hose->last_busno = bus_range[1];
142 hose->ops = &rtas_pci_ops; 141 hose->ops = &rtas_pci_ops;
@@ -145,7 +144,7 @@ void __init efika_pcisetup(void)
145} 144}
146 145
147#else 146#else
148void __init efika_pcisetup(void) 147static void __init efika_pcisetup(void)
149{} 148{}
150#endif 149#endif
151 150
@@ -252,6 +251,8 @@ define_machine(efika)
252 .progress = rtas_progress, 251 .progress = rtas_progress,
253 .get_boot_time = rtas_get_boot_time, 252 .get_boot_time = rtas_get_boot_time,
254 .calibrate_decr = generic_calibrate_decr, 253 .calibrate_decr = generic_calibrate_decr,
254#ifdef CONFIG_PCI
255 .phys_mem_access_prot = pci_phys_mem_access_prot, 255 .phys_mem_access_prot = pci_phys_mem_access_prot,
256#endif
256}; 257};
257 258
diff --git a/arch/powerpc/platforms/52xx/lite5200.c b/arch/powerpc/platforms/52xx/lite5200.c
index 1cfc00dfb99a..5c46e898fd45 100644
--- a/arch/powerpc/platforms/52xx/lite5200.c
+++ b/arch/powerpc/platforms/52xx/lite5200.c
@@ -156,7 +156,7 @@ static void __init lite5200_setup_arch(void)
156 156
157} 157}
158 158
159void lite5200_show_cpuinfo(struct seq_file *m) 159static void lite5200_show_cpuinfo(struct seq_file *m)
160{ 160{
161 struct device_node* np = of_find_all_nodes(NULL); 161 struct device_node* np = of_find_all_nodes(NULL);
162 const char *model = NULL; 162 const char *model = NULL;
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pci.c b/arch/powerpc/platforms/52xx/mpc52xx_pci.c
index 34d34a26d305..4c6c82a684b1 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_pci.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_pci.c
@@ -112,18 +112,18 @@ mpc52xx_pci_read_config(struct pci_bus *bus, unsigned int devfn,
112 u32 value; 112 u32 value;
113 113
114 if (ppc_md.pci_exclude_device) 114 if (ppc_md.pci_exclude_device)
115 if (ppc_md.pci_exclude_device(bus->number, devfn)) 115 if (ppc_md.pci_exclude_device(hose, bus->number, devfn))
116 return PCIBIOS_DEVICE_NOT_FOUND; 116 return PCIBIOS_DEVICE_NOT_FOUND;
117 117
118 out_be32(hose->cfg_addr, 118 out_be32(hose->cfg_addr,
119 (1 << 31) | 119 (1 << 31) |
120 ((bus->number - hose->bus_offset) << 16) | 120 (bus->number << 16) |
121 (devfn << 8) | 121 (devfn << 8) |
122 (offset & 0xfc)); 122 (offset & 0xfc));
123 mb(); 123 mb();
124 124
125#if defined(CONFIG_PPC_MPC5200_BUGFIX) 125#if defined(CONFIG_PPC_MPC5200_BUGFIX)
126 if (bus->number != hose->bus_offset) { 126 if (bus->number) {
127 /* workaround for the bug 435 of the MPC5200 (L25R); 127 /* workaround for the bug 435 of the MPC5200 (L25R);
128 * Don't do 32 bits config access during type-1 cycles */ 128 * Don't do 32 bits config access during type-1 cycles */
129 switch (len) { 129 switch (len) {
@@ -169,18 +169,18 @@ mpc52xx_pci_write_config(struct pci_bus *bus, unsigned int devfn,
169 u32 value, mask; 169 u32 value, mask;
170 170
171 if (ppc_md.pci_exclude_device) 171 if (ppc_md.pci_exclude_device)
172 if (ppc_md.pci_exclude_device(bus->number, devfn)) 172 if (ppc_md.pci_exclude_device(hose, bus->number, devfn))
173 return PCIBIOS_DEVICE_NOT_FOUND; 173 return PCIBIOS_DEVICE_NOT_FOUND;
174 174
175 out_be32(hose->cfg_addr, 175 out_be32(hose->cfg_addr,
176 (1 << 31) | 176 (1 << 31) |
177 ((bus->number - hose->bus_offset) << 16) | 177 (bus->number << 16) |
178 (devfn << 8) | 178 (devfn << 8) |
179 (offset & 0xfc)); 179 (offset & 0xfc));
180 mb(); 180 mb();
181 181
182#if defined(CONFIG_PPC_MPC5200_BUGFIX) 182#if defined(CONFIG_PPC_MPC5200_BUGFIX)
183 if (bus->number != hose->bus_offset) { 183 if (bus->number) {
184 /* workaround for the bug 435 of the MPC5200 (L25R); 184 /* workaround for the bug 435 of the MPC5200 (L25R);
185 * Don't do 32 bits config access during type-1 cycles */ 185 * Don't do 32 bits config access during type-1 cycles */
186 switch (len) { 186 switch (len) {
@@ -385,17 +385,13 @@ mpc52xx_add_bridge(struct device_node *node)
385 * tree are needed to configure the 52xx PCI controller. Rather 385 * tree are needed to configure the 52xx PCI controller. Rather
386 * than parse the tree here, let pci_process_bridge_OF_ranges() 386 * than parse the tree here, let pci_process_bridge_OF_ranges()
387 * do it for us and extract the values after the fact */ 387 * do it for us and extract the values after the fact */
388 hose = pcibios_alloc_controller(); 388 hose = pcibios_alloc_controller(node);
389 if (!hose) 389 if (!hose)
390 return -ENOMEM; 390 return -ENOMEM;
391 391
392 hose->arch_data = node;
393 hose->set_cfg_type = 1;
394
395 hose->first_busno = bus_range ? bus_range[0] : 0; 392 hose->first_busno = bus_range ? bus_range[0] : 0;
396 hose->last_busno = bus_range ? bus_range[1] : 0xff; 393 hose->last_busno = bus_range ? bus_range[1] : 0xff;
397 394
398 hose->bus_offset = 0;
399 hose->ops = &mpc52xx_pci_ops; 395 hose->ops = &mpc52xx_pci_ops;
400 396
401 pci_regs = ioremap(rsrc.start, rsrc.end - rsrc.start + 1); 397 pci_regs = ioremap(rsrc.start, rsrc.end - rsrc.start + 1);
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pm.c b/arch/powerpc/platforms/52xx/mpc52xx_pm.c
index fd40044d16cd..ee2e7639c63e 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_pm.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_pm.c
@@ -9,8 +9,8 @@
9 9
10 10
11/* these are defined in mpc52xx_sleep.S, and only used here */ 11/* these are defined in mpc52xx_sleep.S, and only used here */
12extern void mpc52xx_deep_sleep(void *sram, void *sdram_regs, 12extern void mpc52xx_deep_sleep(void __iomem *sram, void __iomem *sdram_regs,
13 struct mpc52xx_cdm *, struct mpc52xx_intr *); 13 struct mpc52xx_cdm __iomem *, struct mpc52xx_intr __iomem*);
14extern void mpc52xx_ds_sram(void); 14extern void mpc52xx_ds_sram(void);
15extern const long mpc52xx_ds_sram_size; 15extern const long mpc52xx_ds_sram_size;
16extern void mpc52xx_ds_cached(void); 16extern void mpc52xx_ds_cached(void);
@@ -21,7 +21,7 @@ static void __iomem *sdram;
21static struct mpc52xx_cdm __iomem *cdm; 21static struct mpc52xx_cdm __iomem *cdm;
22static struct mpc52xx_intr __iomem *intr; 22static struct mpc52xx_intr __iomem *intr;
23static struct mpc52xx_gpio_wkup __iomem *gpiow; 23static struct mpc52xx_gpio_wkup __iomem *gpiow;
24static void *sram; 24static void __iomem *sram;
25static int sram_size; 25static int sram_size;
26 26
27struct mpc52xx_suspend mpc52xx_suspend; 27struct mpc52xx_suspend mpc52xx_suspend;
@@ -100,7 +100,7 @@ int mpc52xx_pm_enter(suspend_state_t state)
100 u32 clk_enables; 100 u32 clk_enables;
101 u32 msr, hid0; 101 u32 msr, hid0;
102 u32 intr_main_mask; 102 u32 intr_main_mask;
103 void __iomem * irq_0x500 = (void *)CONFIG_KERNEL_START + 0x500; 103 void __iomem * irq_0x500 = (void __iomem *)CONFIG_KERNEL_START + 0x500;
104 unsigned long irq_0x500_stop = (unsigned long)irq_0x500 + mpc52xx_ds_cached_size; 104 unsigned long irq_0x500_stop = (unsigned long)irq_0x500 + mpc52xx_ds_cached_size;
105 char saved_0x500[mpc52xx_ds_cached_size]; 105 char saved_0x500[mpc52xx_ds_cached_size];
106 106
diff --git a/arch/powerpc/platforms/82xx/Kconfig b/arch/powerpc/platforms/82xx/Kconfig
index de7fce9cb6eb..89fde43895c5 100644
--- a/arch/powerpc/platforms/82xx/Kconfig
+++ b/arch/powerpc/platforms/82xx/Kconfig
@@ -1,5 +1,5 @@
1choice 1choice
2 prompt "Machine Type" 2 prompt "82xx Board Type"
3 depends on PPC_82xx 3 depends on PPC_82xx
4 default MPC82xx_ADS 4 default MPC82xx_ADS
5 5
diff --git a/arch/powerpc/platforms/82xx/mpc82xx_ads.c b/arch/powerpc/platforms/82xx/mpc82xx_ads.c
index 47cb09f08052..da20832b27f1 100644
--- a/arch/powerpc/platforms/82xx/mpc82xx_ads.c
+++ b/arch/powerpc/platforms/82xx/mpc82xx_ads.c
@@ -49,7 +49,7 @@
49#include <linux/fs_enet_pd.h> 49#include <linux/fs_enet_pd.h>
50 50
51#include <sysdev/fsl_soc.h> 51#include <sysdev/fsl_soc.h>
52#include <../sysdev/cpm2_pic.h> 52#include <sysdev/cpm2_pic.h>
53 53
54#include "pq2ads.h" 54#include "pq2ads.h"
55 55
@@ -507,7 +507,8 @@ void m82xx_pci_init_irq(void)
507 return; 507 return;
508} 508}
509 509
510static int m82xx_pci_exclude_device(u_char bus, u_char devfn) 510static int m82xx_pci_exclude_device(struct pci_controller *hose,
511 u_char bus, u_char devfn)
511{ 512{
512 if (bus == 0 && PCI_SLOT(devfn) == 0) 513 if (bus == 0 && PCI_SLOT(devfn) == 0)
513 return PCIBIOS_DEVICE_NOT_FOUND; 514 return PCIBIOS_DEVICE_NOT_FOUND;
@@ -515,7 +516,7 @@ static int m82xx_pci_exclude_device(u_char bus, u_char devfn)
515 return PCIBIOS_SUCCESSFUL; 516 return PCIBIOS_SUCCESSFUL;
516} 517}
517 518
518void __init add_bridge(struct device_node *np) 519static void __init mpc82xx_add_bridge(struct device_node *np)
519{ 520{
520 int len; 521 int len;
521 struct pci_controller *hose; 522 struct pci_controller *hose;
@@ -542,19 +543,13 @@ void __init add_bridge(struct device_node *np)
542 543
543 pci_assign_all_buses = 1; 544 pci_assign_all_buses = 1;
544 545
545 hose = pcibios_alloc_controller(); 546 hose = pcibios_alloc_controller(np);
546 547
547 if (!hose) 548 if (!hose)
548 return; 549 return;
549 550
550 hose->arch_data = np;
551 hose->set_cfg_type = 1;
552
553 hose->first_busno = bus_range ? bus_range[0] : 0; 551 hose->first_busno = bus_range ? bus_range[0] : 0;
554 hose->last_busno = bus_range ? bus_range[1] : 0xff; 552 hose->last_busno = bus_range ? bus_range[1] : 0xff;
555 hose->bus_offset = 0;
556
557 hose->set_cfg_type = 1;
558 553
559 setup_indirect_pci(hose, 554 setup_indirect_pci(hose,
560 r.start + offsetof(pci_cpm2_t, pci_cfg_addr), 555 r.start + offsetof(pci_cpm2_t, pci_cfg_addr),
@@ -584,7 +579,7 @@ static void __init mpc82xx_ads_setup_arch(void)
584#ifdef CONFIG_PCI 579#ifdef CONFIG_PCI
585 ppc_md.pci_exclude_device = m82xx_pci_exclude_device; 580 ppc_md.pci_exclude_device = m82xx_pci_exclude_device;
586 for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;) 581 for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
587 add_bridge(np); 582 mpc82xx_add_bridge(np);
588 583
589 of_node_put(np); 584 of_node_put(np);
590#endif 585#endif
diff --git a/arch/powerpc/platforms/83xx/Kconfig b/arch/powerpc/platforms/83xx/Kconfig
index 19cafdf6df93..ec305f18abd8 100644
--- a/arch/powerpc/platforms/83xx/Kconfig
+++ b/arch/powerpc/platforms/83xx/Kconfig
@@ -1,5 +1,5 @@
1choice 1choice
2 prompt "Machine Type" 2 prompt "83xx Board Type"
3 depends on PPC_83xx 3 depends on PPC_83xx
4 default MPC834x_MDS 4 default MPC834x_MDS
5 5
diff --git a/arch/powerpc/platforms/83xx/Makefile b/arch/powerpc/platforms/83xx/Makefile
index 31a91b53f528..5a98f885779f 100644
--- a/arch/powerpc/platforms/83xx/Makefile
+++ b/arch/powerpc/platforms/83xx/Makefile
@@ -1,7 +1,7 @@
1# 1#
2# Makefile for the PowerPC 83xx linux kernel. 2# Makefile for the PowerPC 83xx linux kernel.
3# 3#
4obj-y := misc.o 4obj-y := misc.o usb.o
5obj-$(CONFIG_PCI) += pci.o 5obj-$(CONFIG_PCI) += pci.o
6obj-$(CONFIG_MPC8313_RDB) += mpc8313_rdb.o 6obj-$(CONFIG_MPC8313_RDB) += mpc8313_rdb.o
7obj-$(CONFIG_MPC832x_RDB) += mpc832x_rdb.o 7obj-$(CONFIG_MPC832x_RDB) += mpc832x_rdb.o
diff --git a/arch/powerpc/platforms/83xx/mpc8313_rdb.c b/arch/powerpc/platforms/83xx/mpc8313_rdb.c
index 96970ac887ee..3edfe170a03b 100644
--- a/arch/powerpc/platforms/83xx/mpc8313_rdb.c
+++ b/arch/powerpc/platforms/83xx/mpc8313_rdb.c
@@ -28,11 +28,6 @@
28#define DBG(fmt...) 28#define DBG(fmt...)
29#endif 29#endif
30 30
31#ifndef CONFIG_PCI
32unsigned long isa_io_base = 0;
33unsigned long isa_mem_base = 0;
34#endif
35
36/* ************************************************************************ 31/* ************************************************************************
37 * 32 *
38 * Setup the architecture 33 * Setup the architecture
@@ -49,10 +44,11 @@ static void __init mpc8313_rdb_setup_arch(void)
49 44
50#ifdef CONFIG_PCI 45#ifdef CONFIG_PCI
51 for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;) 46 for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
52 add_bridge(np); 47 mpc83xx_add_bridge(np);
53 48
54 ppc_md.pci_exclude_device = mpc83xx_exclude_device; 49 ppc_md.pci_exclude_device = mpc83xx_exclude_device;
55#endif 50#endif
51 mpc831x_usb_cfg();
56} 52}
57 53
58void __init mpc8313_rdb_init_IRQ(void) 54void __init mpc8313_rdb_init_IRQ(void)
diff --git a/arch/powerpc/platforms/83xx/mpc832x_mds.c b/arch/powerpc/platforms/83xx/mpc832x_mds.c
index 94843ed52a93..b39cb52c6fb9 100644
--- a/arch/powerpc/platforms/83xx/mpc832x_mds.c
+++ b/arch/powerpc/platforms/83xx/mpc832x_mds.c
@@ -49,11 +49,6 @@
49#define DBG(fmt...) 49#define DBG(fmt...)
50#endif 50#endif
51 51
52#ifndef CONFIG_PCI
53unsigned long isa_io_base = 0;
54unsigned long isa_mem_base = 0;
55#endif
56
57static u8 *bcsr_regs = NULL; 52static u8 *bcsr_regs = NULL;
58 53
59/* ************************************************************************ 54/* ************************************************************************
@@ -80,7 +75,7 @@ static void __init mpc832x_sys_setup_arch(void)
80 75
81#ifdef CONFIG_PCI 76#ifdef CONFIG_PCI
82 for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;) 77 for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
83 add_bridge(np); 78 mpc83xx_add_bridge(np);
84 ppc_md.pci_exclude_device = mpc83xx_exclude_device; 79 ppc_md.pci_exclude_device = mpc83xx_exclude_device;
85#endif 80#endif
86 81
diff --git a/arch/powerpc/platforms/83xx/mpc832x_rdb.c b/arch/powerpc/platforms/83xx/mpc832x_rdb.c
index 3db68b73fc32..b2b28a44738c 100644
--- a/arch/powerpc/platforms/83xx/mpc832x_rdb.c
+++ b/arch/powerpc/platforms/83xx/mpc832x_rdb.c
@@ -32,11 +32,6 @@
32#define DBG(fmt...) 32#define DBG(fmt...)
33#endif 33#endif
34 34
35#ifndef CONFIG_PCI
36unsigned long isa_io_base = 0;
37unsigned long isa_mem_base = 0;
38#endif
39
40/* ************************************************************************ 35/* ************************************************************************
41 * 36 *
42 * Setup the architecture 37 * Setup the architecture
@@ -53,7 +48,7 @@ static void __init mpc832x_rdb_setup_arch(void)
53 48
54#ifdef CONFIG_PCI 49#ifdef CONFIG_PCI
55 for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;) 50 for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
56 add_bridge(np); 51 mpc83xx_add_bridge(np);
57 52
58 ppc_md.pci_exclude_device = mpc83xx_exclude_device; 53 ppc_md.pci_exclude_device = mpc83xx_exclude_device;
59#endif 54#endif
diff --git a/arch/powerpc/platforms/83xx/mpc834x_itx.c b/arch/powerpc/platforms/83xx/mpc834x_itx.c
index 40a01947d684..47ba5446f63c 100644
--- a/arch/powerpc/platforms/83xx/mpc834x_itx.c
+++ b/arch/powerpc/platforms/83xx/mpc834x_itx.c
@@ -38,11 +38,6 @@
38 38
39#include "mpc83xx.h" 39#include "mpc83xx.h"
40 40
41#ifndef CONFIG_PCI
42unsigned long isa_io_base = 0;
43unsigned long isa_mem_base = 0;
44#endif
45
46/* ************************************************************************ 41/* ************************************************************************
47 * 42 *
48 * Setup the architecture 43 * Setup the architecture
@@ -59,10 +54,12 @@ static void __init mpc834x_itx_setup_arch(void)
59 54
60#ifdef CONFIG_PCI 55#ifdef CONFIG_PCI
61 for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;) 56 for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
62 add_bridge(np); 57 mpc83xx_add_bridge(np);
63 58
64 ppc_md.pci_exclude_device = mpc83xx_exclude_device; 59 ppc_md.pci_exclude_device = mpc83xx_exclude_device;
65#endif 60#endif
61
62 mpc834x_usb_cfg();
66} 63}
67 64
68static void __init mpc834x_itx_init_IRQ(void) 65static void __init mpc834x_itx_init_IRQ(void)
diff --git a/arch/powerpc/platforms/83xx/mpc834x_mds.c b/arch/powerpc/platforms/83xx/mpc834x_mds.c
index 10394b2d7e7a..4c9ff9cadfe4 100644
--- a/arch/powerpc/platforms/83xx/mpc834x_mds.c
+++ b/arch/powerpc/platforms/83xx/mpc834x_mds.c
@@ -38,61 +38,17 @@
38 38
39#include "mpc83xx.h" 39#include "mpc83xx.h"
40 40
41#ifndef CONFIG_PCI
42unsigned long isa_io_base = 0;
43unsigned long isa_mem_base = 0;
44#endif
45
46#define BCSR5_INT_USB 0x02 41#define BCSR5_INT_USB 0x02
47/* Note: This is only for PB, not for PB+PIB 42static int mpc834xemds_usb_cfg(void)
48 * On PB only port0 is connected using ULPI */
49static int mpc834x_usb_cfg(void)
50{ 43{
51 unsigned long sccr, sicrl; 44 struct device_node *np;
52 void __iomem *immap;
53 void __iomem *bcsr_regs = NULL; 45 void __iomem *bcsr_regs = NULL;
54 u8 bcsr5; 46 u8 bcsr5;
55 struct device_node *np = NULL;
56 int port0_is_dr = 0;
57
58 if ((np = of_find_compatible_node(NULL, "usb", "fsl-usb2-dr")) != NULL)
59 port0_is_dr = 1;
60 if ((np = of_find_compatible_node(NULL, "usb", "fsl-usb2-mph")) != NULL){
61 if (port0_is_dr) {
62 printk(KERN_WARNING
63 "There is only one USB port on PB board! \n");
64 return -1;
65 } else if (!port0_is_dr)
66 /* No usb port enabled */
67 return -1;
68 }
69
70 immap = ioremap(get_immrbase(), 0x1000);
71 if (!immap)
72 return -1;
73
74 /* Configure clock */
75 sccr = in_be32(immap + MPC83XX_SCCR_OFFS);
76 if (port0_is_dr)
77 sccr |= MPC83XX_SCCR_USB_DRCM_11; /* 1:3 */
78 else
79 sccr |= MPC83XX_SCCR_USB_MPHCM_11; /* 1:3 */
80 out_be32(immap + MPC83XX_SCCR_OFFS, sccr);
81
82 /* Configure Pin */
83 sicrl = in_be32(immap + MPC83XX_SICRL_OFFS);
84 /* set port0 only */
85 if (port0_is_dr)
86 sicrl |= MPC83XX_SICRL_USB0;
87 else
88 sicrl &= ~(MPC83XX_SICRL_USB0);
89 out_be32(immap + MPC83XX_SICRL_OFFS, sicrl);
90
91 iounmap(immap);
92 47
48 mpc834x_usb_cfg();
93 /* Map BCSR area */ 49 /* Map BCSR area */
94 np = of_find_node_by_name(NULL, "bcsr"); 50 np = of_find_node_by_name(NULL, "bcsr");
95 if (np != 0) { 51 if (np) {
96 struct resource res; 52 struct resource res;
97 53
98 of_address_to_resource(np, 0, &res); 54 of_address_to_resource(np, 0, &res);
@@ -129,12 +85,12 @@ static void __init mpc834x_mds_setup_arch(void)
129 85
130#ifdef CONFIG_PCI 86#ifdef CONFIG_PCI
131 for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;) 87 for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
132 add_bridge(np); 88 mpc83xx_add_bridge(np);
133 89
134 ppc_md.pci_exclude_device = mpc83xx_exclude_device; 90 ppc_md.pci_exclude_device = mpc83xx_exclude_device;
135#endif 91#endif
136 92
137 mpc834x_usb_cfg(); 93 mpc834xemds_usb_cfg();
138} 94}
139 95
140static void __init mpc834x_mds_init_IRQ(void) 96static void __init mpc834x_mds_init_IRQ(void)
diff --git a/arch/powerpc/platforms/83xx/mpc836x_mds.c b/arch/powerpc/platforms/83xx/mpc836x_mds.c
index bceeff8bbfd2..0e615fd65c1f 100644
--- a/arch/powerpc/platforms/83xx/mpc836x_mds.c
+++ b/arch/powerpc/platforms/83xx/mpc836x_mds.c
@@ -55,11 +55,6 @@
55#define DBG(fmt...) 55#define DBG(fmt...)
56#endif 56#endif
57 57
58#ifndef CONFIG_PCI
59unsigned long isa_io_base = 0;
60unsigned long isa_mem_base = 0;
61#endif
62
63static u8 *bcsr_regs = NULL; 58static u8 *bcsr_regs = NULL;
64 59
65/* ************************************************************************ 60/* ************************************************************************
@@ -86,7 +81,7 @@ static void __init mpc836x_mds_setup_arch(void)
86 81
87#ifdef CONFIG_PCI 82#ifdef CONFIG_PCI
88 for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;) 83 for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
89 add_bridge(np); 84 mpc83xx_add_bridge(np);
90 ppc_md.pci_exclude_device = mpc83xx_exclude_device; 85 ppc_md.pci_exclude_device = mpc83xx_exclude_device;
91#endif 86#endif
92 87
diff --git a/arch/powerpc/platforms/83xx/mpc83xx.h b/arch/powerpc/platforms/83xx/mpc83xx.h
index 9cd03b59c8f4..589ee55730f3 100644
--- a/arch/powerpc/platforms/83xx/mpc83xx.h
+++ b/arch/powerpc/platforms/83xx/mpc83xx.h
@@ -3,9 +3,11 @@
3 3
4#include <linux/init.h> 4#include <linux/init.h>
5#include <linux/device.h> 5#include <linux/device.h>
6#include <asm/pci-bridge.h>
6 7
7/* System Clock Control Register */ 8/* System Clock Control Register */
8#define MPC83XX_SCCR_OFFS 0xA08 9#define MPC83XX_SCCR_OFFS 0xA08
10#define MPC83XX_SCCR_USB_MASK 0x00f00000
9#define MPC83XX_SCCR_USB_MPHCM_11 0x00c00000 11#define MPC83XX_SCCR_USB_MPHCM_11 0x00c00000
10#define MPC83XX_SCCR_USB_MPHCM_01 0x00400000 12#define MPC83XX_SCCR_USB_MPHCM_01 0x00400000
11#define MPC83XX_SCCR_USB_MPHCM_10 0x00800000 13#define MPC83XX_SCCR_USB_MPHCM_10 0x00800000
@@ -15,21 +17,43 @@
15 17
16/* system i/o configuration register low */ 18/* system i/o configuration register low */
17#define MPC83XX_SICRL_OFFS 0x114 19#define MPC83XX_SICRL_OFFS 0x114
18#define MPC83XX_SICRL_USB0 0x40000000 20#define MPC834X_SICRL_USB_MASK 0x60000000
19#define MPC83XX_SICRL_USB1 0x20000000 21#define MPC834X_SICRL_USB0 0x40000000
22#define MPC834X_SICRL_USB1 0x20000000
23#define MPC831X_SICRL_USB_MASK 0x00000c00
24#define MPC831X_SICRL_USB_ULPI 0x00000800
20 25
21/* system i/o configuration register high */ 26/* system i/o configuration register high */
22#define MPC83XX_SICRH_OFFS 0x118 27#define MPC83XX_SICRH_OFFS 0x118
23#define MPC83XX_SICRH_USB_UTMI 0x00020000 28#define MPC834X_SICRH_USB_UTMI 0x00020000
29#define MPC831X_SICRH_USB_MASK 0x000000e0
30#define MPC831X_SICRH_USB_ULPI 0x000000a0
31
32/* USB Control Register */
33#define FSL_USB2_CONTROL_OFFS 0x500
34#define CONTROL_UTMI_PHY_EN 0x00000200
35#define CONTROL_REFSEL_48MHZ 0x00000080
36#define CONTROL_PHY_CLK_SEL_ULPI 0x00000400
37#define CONTROL_OTG_PORT 0x00000020
38
39/* USB PORTSC Registers */
40#define FSL_USB2_PORTSC1_OFFS 0x184
41#define FSL_USB2_PORTSC2_OFFS 0x188
42#define PORTSCX_PTW_16BIT 0x10000000
43#define PORTSCX_PTS_UTMI 0x00000000
44#define PORTSCX_PTS_ULPI 0x80000000
24 45
25/* 46/*
26 * Declaration for the various functions exported by the 47 * Declaration for the various functions exported by the
27 * mpc83xx_* files. Mostly for use by mpc83xx_setup 48 * mpc83xx_* files. Mostly for use by mpc83xx_setup
28 */ 49 */
29 50
30extern int add_bridge(struct device_node *dev); 51extern int mpc83xx_add_bridge(struct device_node *dev);
31extern int mpc83xx_exclude_device(u_char bus, u_char devfn); 52extern int mpc83xx_exclude_device(struct pci_controller *hose,
53 u_char bus, u_char devfn);
32extern void mpc83xx_restart(char *cmd); 54extern void mpc83xx_restart(char *cmd);
33extern long mpc83xx_time_init(void); 55extern long mpc83xx_time_init(void);
56extern int mpc834x_usb_cfg(void);
57extern int mpc831x_usb_cfg(void);
34 58
35#endif /* __MPC83XX_H__ */ 59#endif /* __MPC83XX_H__ */
diff --git a/arch/powerpc/platforms/83xx/pci.c b/arch/powerpc/platforms/83xx/pci.c
index 774457d09e94..c0e2b89154e5 100644
--- a/arch/powerpc/platforms/83xx/pci.c
+++ b/arch/powerpc/platforms/83xx/pci.c
@@ -33,19 +33,14 @@
33#define DBG(x...) 33#define DBG(x...)
34#endif 34#endif
35 35
36int mpc83xx_pci2_busno; 36int mpc83xx_exclude_device(struct pci_controller *hose, u_char bus, u_char devfn)
37
38int mpc83xx_exclude_device(u_char bus, u_char devfn)
39{ 37{
40 if (bus == 0 && PCI_SLOT(devfn) == 0) 38 if ((bus == hose->first_busno) && PCI_SLOT(devfn) == 0)
41 return PCIBIOS_DEVICE_NOT_FOUND; 39 return PCIBIOS_DEVICE_NOT_FOUND;
42 if (mpc83xx_pci2_busno)
43 if (bus == (mpc83xx_pci2_busno) && PCI_SLOT(devfn) == 0)
44 return PCIBIOS_DEVICE_NOT_FOUND;
45 return PCIBIOS_SUCCESSFUL; 40 return PCIBIOS_SUCCESSFUL;
46} 41}
47 42
48int __init add_bridge(struct device_node *dev) 43int __init mpc83xx_add_bridge(struct device_node *dev)
49{ 44{
50 int len; 45 int len;
51 struct pci_controller *hose; 46 struct pci_controller *hose;
@@ -66,11 +61,10 @@ int __init add_bridge(struct device_node *dev)
66 " bus 0\n", dev->full_name); 61 " bus 0\n", dev->full_name);
67 } 62 }
68 63
69 hose = pcibios_alloc_controller(); 64 pci_assign_all_buses = 1;
65 hose = pcibios_alloc_controller(dev);
70 if (!hose) 66 if (!hose)
71 return -ENOMEM; 67 return -ENOMEM;
72 hose->arch_data = dev;
73 hose->set_cfg_type = 1;
74 68
75 hose->first_busno = bus_range ? bus_range[0] : 0; 69 hose->first_busno = bus_range ? bus_range[0] : 0;
76 hose->last_busno = bus_range ? bus_range[1] : 0xff; 70 hose->last_busno = bus_range ? bus_range[1] : 0xff;
@@ -86,8 +80,6 @@ int __init add_bridge(struct device_node *dev)
86 if ((rsrc.start & 0xfffff) == 0x8600) { 80 if ((rsrc.start & 0xfffff) == 0x8600) {
87 setup_indirect_pci(hose, immr + 0x8380, immr + 0x8384); 81 setup_indirect_pci(hose, immr + 0x8380, immr + 0x8384);
88 primary = 0; 82 primary = 0;
89 hose->bus_offset = hose->first_busno;
90 mpc83xx_pci2_busno = hose->first_busno;
91 } 83 }
92 84
93 printk(KERN_INFO "Found MPC83xx PCI host bridge at 0x%016llx. " 85 printk(KERN_INFO "Found MPC83xx PCI host bridge at 0x%016llx. "
diff --git a/arch/powerpc/platforms/83xx/usb.c b/arch/powerpc/platforms/83xx/usb.c
new file mode 100644
index 000000000000..e7fdf013cd39
--- /dev/null
+++ b/arch/powerpc/platforms/83xx/usb.c
@@ -0,0 +1,181 @@
1/*
2 * Freescale 83xx USB SOC setup code
3 *
4 * Copyright (C) 2007 Freescale Semiconductor, Inc.
5 * Author: Li Yang
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 by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12
13
14#include <linux/stddef.h>
15#include <linux/kernel.h>
16#include <linux/errno.h>
17
18#include <asm/io.h>
19#include <asm/prom.h>
20#include <sysdev/fsl_soc.h>
21
22#include "mpc83xx.h"
23
24
25#ifdef CONFIG_MPC834x
26int mpc834x_usb_cfg(void)
27{
28 unsigned long sccr, sicrl, sicrh;
29 void __iomem *immap;
30 struct device_node *np = NULL;
31 int port0_is_dr = 0, port1_is_dr = 0;
32 const void *prop, *dr_mode;
33
34 immap = ioremap(get_immrbase(), 0x1000);
35 if (!immap)
36 return -ENOMEM;
37
38 /* Read registers */
39 /* Note: DR and MPH must use the same clock setting in SCCR */
40 sccr = in_be32(immap + MPC83XX_SCCR_OFFS) & ~MPC83XX_SCCR_USB_MASK;
41 sicrl = in_be32(immap + MPC83XX_SICRL_OFFS) & ~MPC834X_SICRL_USB_MASK;
42 sicrh = in_be32(immap + MPC83XX_SICRH_OFFS) & ~MPC834X_SICRH_USB_UTMI;
43
44 np = of_find_compatible_node(NULL, "usb", "fsl-usb2-dr");
45 if (np) {
46 sccr |= MPC83XX_SCCR_USB_DRCM_11; /* 1:3 */
47
48 prop = of_get_property(np, "phy_type", NULL);
49 if (prop && (!strcmp(prop, "utmi") ||
50 !strcmp(prop, "utmi_wide"))) {
51 sicrl |= MPC834X_SICRL_USB0 | MPC834X_SICRL_USB1;
52 sicrh |= MPC834X_SICRH_USB_UTMI;
53 port1_is_dr = 1;
54 } else if (prop && !strcmp(prop, "serial")) {
55 dr_mode = of_get_property(np, "dr_mode", NULL);
56 if (dr_mode && !strcmp(dr_mode, "otg")) {
57 sicrl |= MPC834X_SICRL_USB0 | MPC834X_SICRL_USB1;
58 port1_is_dr = 1;
59 } else {
60 sicrl |= MPC834X_SICRL_USB0;
61 }
62 } else if (prop && !strcmp(prop, "ulpi")) {
63 sicrl |= MPC834X_SICRL_USB0;
64 } else {
65 printk(KERN_WARNING "834x USB PHY type not supported\n");
66 }
67 port0_is_dr = 1;
68 of_node_put(np);
69 }
70 np = of_find_compatible_node(NULL, "usb", "fsl-usb2-mph");
71 if (np) {
72 sccr |= MPC83XX_SCCR_USB_MPHCM_11; /* 1:3 */
73
74 prop = of_get_property(np, "port0", NULL);
75 if (prop) {
76 if (port0_is_dr)
77 printk(KERN_WARNING
78 "834x USB port0 can't be used by both DR and MPH!\n");
79 sicrl |= MPC834X_SICRL_USB0;
80 }
81 prop = of_get_property(np, "port1", NULL);
82 if (prop) {
83 if (port1_is_dr)
84 printk(KERN_WARNING
85 "834x USB port1 can't be used by both DR and MPH!\n");
86 sicrl |= MPC834X_SICRL_USB1;
87 }
88 of_node_put(np);
89 }
90
91 /* Write back */
92 out_be32(immap + MPC83XX_SCCR_OFFS, sccr);
93 out_be32(immap + MPC83XX_SICRL_OFFS, sicrl);
94 out_be32(immap + MPC83XX_SICRH_OFFS, sicrh);
95
96 iounmap(immap);
97 return 0;
98}
99#endif /* CONFIG_MPC834x */
100
101#ifdef CONFIG_PPC_MPC831x
102int mpc831x_usb_cfg(void)
103{
104 u32 temp;
105 void __iomem *immap, *usb_regs;
106 struct device_node *np = NULL;
107 const void *prop;
108 struct resource res;
109 int ret = 0;
110#ifdef CONFIG_USB_OTG
111 const void *dr_mode;
112#endif
113
114 np = of_find_compatible_node(NULL, "usb", "fsl-usb2-dr");
115 if (!np)
116 return -ENODEV;
117 prop = of_get_property(np, "phy_type", NULL);
118
119 /* Map IMMR space for pin and clock settings */
120 immap = ioremap(get_immrbase(), 0x1000);
121 if (!immap) {
122 of_node_put(np);
123 return -ENOMEM;
124 }
125
126 /* Configure clock */
127 temp = in_be32(immap + MPC83XX_SCCR_OFFS);
128 temp &= ~MPC83XX_SCCR_USB_MASK;
129 temp |= MPC83XX_SCCR_USB_DRCM_11; /* 1:3 */
130 out_be32(immap + MPC83XX_SCCR_OFFS, temp);
131
132 /* Configure pin mux for ULPI. There is no pin mux for UTMI */
133 if (!strcmp(prop, "ulpi")) {
134 temp = in_be32(immap + MPC83XX_SICRL_OFFS);
135 temp &= ~MPC831X_SICRL_USB_MASK;
136 temp |= MPC831X_SICRL_USB_ULPI;
137 out_be32(immap + MPC83XX_SICRL_OFFS, temp);
138
139 temp = in_be32(immap + MPC83XX_SICRH_OFFS);
140 temp &= ~MPC831X_SICRH_USB_MASK;
141 temp |= MPC831X_SICRH_USB_ULPI;
142 out_be32(immap + MPC83XX_SICRH_OFFS, temp);
143 }
144
145 iounmap(immap);
146
147 /* Map USB SOC space */
148 ret = of_address_to_resource(np, 0, &res);
149 if (ret) {
150 of_node_put(np);
151 return ret;
152 }
153 usb_regs = ioremap(res.start, res.end - res.start + 1);
154
155 /* Using on-chip PHY */
156 if (!strcmp(prop, "utmi_wide") ||
157 !strcmp(prop, "utmi")) {
158 /* Set UTMI_PHY_EN, REFSEL to 48MHZ */
159 out_be32(usb_regs + FSL_USB2_CONTROL_OFFS,
160 CONTROL_UTMI_PHY_EN | CONTROL_REFSEL_48MHZ);
161 /* Using external UPLI PHY */
162 } else if (!strcmp(prop, "ulpi")) {
163 /* Set PHY_CLK_SEL to ULPI */
164 temp = CONTROL_PHY_CLK_SEL_ULPI;
165#ifdef CONFIG_USB_OTG
166 /* Set OTG_PORT */
167 dr_mode = of_get_property(np, "dr_mode", NULL);
168 if (dr_mode && !strcmp(dr_mode, "otg"))
169 temp |= CONTROL_OTG_PORT;
170#endif /* CONFIG_USB_OTG */
171 out_be32(usb_regs + FSL_USB2_CONTROL_OFFS, temp);
172 } else {
173 printk(KERN_WARNING "831x USB PHY type not supported\n");
174 ret = -EINVAL;
175 }
176
177 iounmap(usb_regs);
178 of_node_put(np);
179 return ret;
180}
181#endif /* CONFIG_PPC_MPC831x */
diff --git a/arch/powerpc/platforms/85xx/misc.c b/arch/powerpc/platforms/85xx/misc.c
index 3e62fcb04c1c..4fe376e9c3b6 100644
--- a/arch/powerpc/platforms/85xx/misc.c
+++ b/arch/powerpc/platforms/85xx/misc.c
@@ -13,11 +13,43 @@
13#include <linux/irq.h> 13#include <linux/irq.h>
14#include <linux/module.h> 14#include <linux/module.h>
15#include <asm/irq.h> 15#include <asm/irq.h>
16#include <asm/io.h>
17#include <asm/prom.h>
18#include <sysdev/fsl_soc.h>
19
20static __be32 __iomem *rstcr;
16 21
17extern void abort(void); 22extern void abort(void);
18 23
24static int __init mpc85xx_rstcr(void)
25{
26 struct device_node *np;
27 np = of_find_node_by_name(NULL, "global-utilities");
28 if ((np && of_get_property(np, "fsl,has-rstcr", NULL))) {
29 const u32 *prop = of_get_property(np, "reg", NULL);
30 if (prop) {
31 /* map reset control register
32 * 0xE00B0 is offset of reset control register
33 */
34 rstcr = ioremap(get_immrbase() + *prop + 0xB0, 0xff);
35 if (!rstcr)
36 printk (KERN_EMERG "Error: reset control "
37 "register not mapped!\n");
38 }
39 } else
40 printk (KERN_INFO "rstcr compatible register does not exist!\n");
41 if (np)
42 of_node_put(np);
43 return 0;
44}
45
46arch_initcall(mpc85xx_rstcr);
47
19void mpc85xx_restart(char *cmd) 48void mpc85xx_restart(char *cmd)
20{ 49{
21 local_irq_disable(); 50 local_irq_disable();
51 if (rstcr)
52 /* set reset control register */
53 out_be32(rstcr, 0x2); /* HRESET_REQ */
22 abort(); 54 abort();
23} 55}
diff --git a/arch/powerpc/platforms/85xx/mpc8544_ds.c b/arch/powerpc/platforms/85xx/mpc8544_ds.c
index bec84ffe708e..6fb90aab879f 100644
--- a/arch/powerpc/platforms/85xx/mpc8544_ds.c
+++ b/arch/powerpc/platforms/85xx/mpc8544_ds.c
@@ -61,24 +61,11 @@ void __init mpc8544_ds_pic_init(void)
61 return; 61 return;
62 } 62 }
63 63
64 /* Alloc mpic structure and per isu has 16 INT entries. */
65 mpic = mpic_alloc(np, r.start, 64 mpic = mpic_alloc(np, r.start,
66 MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, 65 MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN,
67 16, 64, " OPENPIC "); 66 0, 256, " OpenPIC ");
68 BUG_ON(mpic == NULL); 67 BUG_ON(mpic == NULL);
69 68
70 /*
71 * 48 Internal Interrupts
72 */
73 mpic_assign_isu(mpic, 0, r.start + 0x10200);
74 mpic_assign_isu(mpic, 1, r.start + 0x10400);
75 mpic_assign_isu(mpic, 2, r.start + 0x10600);
76
77 /*
78 * 16 External interrupts
79 */
80 mpic_assign_isu(mpic, 3, r.start + 0x10000);
81
82 mpic_init(mpic); 69 mpic_init(mpic);
83 70
84#ifdef CONFIG_PPC_I8259 71#ifdef CONFIG_PPC_I8259
diff --git a/arch/powerpc/platforms/85xx/mpc85xx.h b/arch/powerpc/platforms/85xx/mpc85xx.h
index 83415db33378..7286ffac2c1d 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx.h
+++ b/arch/powerpc/platforms/85xx/mpc85xx.h
@@ -15,4 +15,4 @@
15 */ 15 */
16 16
17extern void mpc85xx_restart(char *); 17extern void mpc85xx_restart(char *);
18extern int add_bridge(struct device_node *dev); 18extern int mpc85xx_add_bridge(struct device_node *dev);
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ads.c b/arch/powerpc/platforms/85xx/mpc85xx_ads.c
index 5d27621f0927..7235f702394c 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_ads.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_ads.c
@@ -38,13 +38,9 @@
38#include <asm/fs_pd.h> 38#include <asm/fs_pd.h>
39#endif 39#endif
40 40
41#ifndef CONFIG_PCI
42unsigned long isa_io_base = 0;
43unsigned long isa_mem_base = 0;
44#endif
45
46#ifdef CONFIG_PCI 41#ifdef CONFIG_PCI
47static int mpc85xx_exclude_device(u_char bus, u_char devfn) 42static int mpc85xx_exclude_device(struct pci_controller *hose,
43 u_char bus, u_char devfn)
48{ 44{
49 if (bus == 0 && PCI_SLOT(devfn) == 0) 45 if (bus == 0 && PCI_SLOT(devfn) == 0)
50 return PCIBIOS_DEVICE_NOT_FOUND; 46 return PCIBIOS_DEVICE_NOT_FOUND;
@@ -91,30 +87,10 @@ static void __init mpc85xx_ads_pic_init(void)
91 87
92 mpic = mpic_alloc(np, r.start, 88 mpic = mpic_alloc(np, r.start,
93 MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, 89 MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN,
94 4, 0, " OpenPIC "); 90 0, 256, " OpenPIC ");
95 BUG_ON(mpic == NULL); 91 BUG_ON(mpic == NULL);
96 of_node_put(np); 92 of_node_put(np);
97 93
98 mpic_assign_isu(mpic, 0, r.start + 0x10200);
99 mpic_assign_isu(mpic, 1, r.start + 0x10280);
100 mpic_assign_isu(mpic, 2, r.start + 0x10300);
101 mpic_assign_isu(mpic, 3, r.start + 0x10380);
102 mpic_assign_isu(mpic, 4, r.start + 0x10400);
103 mpic_assign_isu(mpic, 5, r.start + 0x10480);
104 mpic_assign_isu(mpic, 6, r.start + 0x10500);
105 mpic_assign_isu(mpic, 7, r.start + 0x10580);
106
107 /* Unused on this platform (leave room for 8548) */
108 mpic_assign_isu(mpic, 8, r.start + 0x10600);
109 mpic_assign_isu(mpic, 9, r.start + 0x10680);
110 mpic_assign_isu(mpic, 10, r.start + 0x10700);
111 mpic_assign_isu(mpic, 11, r.start + 0x10780);
112
113 /* External Interrupts */
114 mpic_assign_isu(mpic, 12, r.start + 0x10000);
115 mpic_assign_isu(mpic, 13, r.start + 0x10080);
116 mpic_assign_isu(mpic, 14, r.start + 0x10100);
117
118 mpic_init(mpic); 94 mpic_init(mpic);
119 95
120#ifdef CONFIG_CPM2 96#ifdef CONFIG_CPM2
@@ -241,7 +217,7 @@ static void __init mpc85xx_ads_setup_arch(void)
241 217
242#ifdef CONFIG_PCI 218#ifdef CONFIG_PCI
243 for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;) 219 for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
244 add_bridge(np); 220 mpc85xx_add_bridge(np);
245 ppc_md.pci_exclude_device = mpc85xx_exclude_device; 221 ppc_md.pci_exclude_device = mpc85xx_exclude_device;
246#endif 222#endif
247} 223}
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_cds.c b/arch/powerpc/platforms/85xx/mpc85xx_cds.c
index 1490eb3ce0d3..50c8d6458362 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_cds.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_cds.c
@@ -47,11 +47,6 @@
47#include <sysdev/fsl_soc.h> 47#include <sysdev/fsl_soc.h>
48#include "mpc85xx.h" 48#include "mpc85xx.h"
49 49
50#ifndef CONFIG_PCI
51unsigned long isa_io_base = 0;
52unsigned long isa_mem_base = 0;
53#endif
54
55static int cds_pci_slot = 2; 50static int cds_pci_slot = 2;
56static volatile u8 *cadmus; 51static volatile u8 *cadmus;
57 52
@@ -60,15 +55,11 @@ static volatile u8 *cadmus;
60#define ARCADIA_HOST_BRIDGE_IDSEL 17 55#define ARCADIA_HOST_BRIDGE_IDSEL 17
61#define ARCADIA_2ND_BRIDGE_IDSEL 3 56#define ARCADIA_2ND_BRIDGE_IDSEL 3
62 57
63extern int mpc85xx_pci2_busno; 58static int mpc85xx_exclude_device(struct pci_controller *hose,
64 59 u_char bus, u_char devfn)
65static int mpc85xx_exclude_device(u_char bus, u_char devfn)
66{ 60{
67 if (bus == 0 && PCI_SLOT(devfn) == 0) 61 if ((bus == hose->first_busno) && PCI_SLOT(devfn) == 0)
68 return PCIBIOS_DEVICE_NOT_FOUND; 62 return PCIBIOS_DEVICE_NOT_FOUND;
69 if (mpc85xx_pci2_busno)
70 if (bus == (mpc85xx_pci2_busno) && PCI_SLOT(devfn) == 0)
71 return PCIBIOS_DEVICE_NOT_FOUND;
72 /* We explicitly do not go past the Tundra 320 Bridge */ 63 /* We explicitly do not go past the Tundra 320 Bridge */
73 if ((bus == 1) && (PCI_SLOT(devfn) == ARCADIA_2ND_BRIDGE_IDSEL)) 64 if ((bus == 1) && (PCI_SLOT(devfn) == ARCADIA_2ND_BRIDGE_IDSEL))
74 return PCIBIOS_DEVICE_NOT_FOUND; 65 return PCIBIOS_DEVICE_NOT_FOUND;
@@ -78,52 +69,44 @@ static int mpc85xx_exclude_device(u_char bus, u_char devfn)
78 return PCIBIOS_SUCCESSFUL; 69 return PCIBIOS_SUCCESSFUL;
79} 70}
80 71
81static void __init mpc85xx_cds_pcibios_fixup(void) 72static void __init mpc85xx_cds_pci_irq_fixup(struct pci_dev *dev)
82{ 73{
83 struct pci_dev *dev; 74 u_char c;
84 u_char c; 75 if (dev->vendor == PCI_VENDOR_ID_VIA) {
85 76 switch (dev->device) {
86 if ((dev = pci_get_device(PCI_VENDOR_ID_VIA, 77 case PCI_DEVICE_ID_VIA_82C586_1:
87 PCI_DEVICE_ID_VIA_82C586_1, NULL))) { 78 /*
79 * U-Boot does not set the enable bits
80 * for the IDE device. Force them on here.
81 */
82 pci_read_config_byte(dev, 0x40, &c);
83 c |= 0x03; /* IDE: Chip Enable Bits */
84 pci_write_config_byte(dev, 0x40, c);
85
86 /*
87 * Since only primary interface works, force the
88 * IDE function to standard primary IDE interrupt
89 * w/ 8259 offset
90 */
91 dev->irq = 14;
92 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
93 break;
88 /* 94 /*
89 * U-Boot does not set the enable bits 95 * Force legacy USB interrupt routing
90 * for the IDE device. Force them on here.
91 */ 96 */
92 pci_read_config_byte(dev, 0x40, &c); 97 case PCI_DEVICE_ID_VIA_82C586_2:
93 c |= 0x03; /* IDE: Chip Enable Bits */ 98 /* There are two USB controllers.
94 pci_write_config_byte(dev, 0x40, c); 99 * Identify them by functon number
95
96 /*
97 * Since only primary interface works, force the
98 * IDE function to standard primary IDE interrupt
99 * w/ 8259 offset
100 */ 100 */
101 dev->irq = 14; 101 if (PCI_FUNC(dev->devfn))
102 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); 102 dev->irq = 11;
103 pci_dev_put(dev); 103 else
104 } 104 dev->irq = 10;
105 105 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
106 /* 106 default:
107 * Force legacy USB interrupt routing 107 break;
108 */ 108 }
109 if ((dev = pci_get_device(PCI_VENDOR_ID_VIA,
110 PCI_DEVICE_ID_VIA_82C586_2, NULL))) {
111 dev->irq = 10;
112 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 10);
113 pci_dev_put(dev);
114 }
115
116 if ((dev = pci_get_device(PCI_VENDOR_ID_VIA,
117 PCI_DEVICE_ID_VIA_82C586_2, dev))) {
118 dev->irq = 11;
119 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 11);
120 pci_dev_put(dev);
121 } 109 }
122
123 /* Now map all the PCI irqs */
124 dev = NULL;
125 for_each_pci_dev(dev)
126 pci_read_irq_line(dev);
127} 110}
128 111
129#ifdef CONFIG_PPC_I8259 112#ifdef CONFIG_PPC_I8259
@@ -165,33 +148,12 @@ static void __init mpc85xx_cds_pic_init(void)
165 148
166 mpic = mpic_alloc(np, r.start, 149 mpic = mpic_alloc(np, r.start,
167 MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, 150 MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN,
168 4, 0, " OpenPIC "); 151 0, 256, " OpenPIC ");
169 BUG_ON(mpic == NULL); 152 BUG_ON(mpic == NULL);
170 153
171 /* Return the mpic node */ 154 /* Return the mpic node */
172 of_node_put(np); 155 of_node_put(np);
173 156
174 mpic_assign_isu(mpic, 0, r.start + 0x10200);
175 mpic_assign_isu(mpic, 1, r.start + 0x10280);
176 mpic_assign_isu(mpic, 2, r.start + 0x10300);
177 mpic_assign_isu(mpic, 3, r.start + 0x10380);
178 mpic_assign_isu(mpic, 4, r.start + 0x10400);
179 mpic_assign_isu(mpic, 5, r.start + 0x10480);
180 mpic_assign_isu(mpic, 6, r.start + 0x10500);
181 mpic_assign_isu(mpic, 7, r.start + 0x10580);
182
183 /* Used only for 8548 so far, but no harm in
184 * allocating them for everyone */
185 mpic_assign_isu(mpic, 8, r.start + 0x10600);
186 mpic_assign_isu(mpic, 9, r.start + 0x10680);
187 mpic_assign_isu(mpic, 10, r.start + 0x10700);
188 mpic_assign_isu(mpic, 11, r.start + 0x10780);
189
190 /* External Interrupts */
191 mpic_assign_isu(mpic, 12, r.start + 0x10000);
192 mpic_assign_isu(mpic, 13, r.start + 0x10080);
193 mpic_assign_isu(mpic, 14, r.start + 0x10100);
194
195 mpic_init(mpic); 157 mpic_init(mpic);
196 158
197#ifdef CONFIG_PPC_I8259 159#ifdef CONFIG_PPC_I8259
@@ -257,9 +219,9 @@ static void __init mpc85xx_cds_setup_arch(void)
257 219
258#ifdef CONFIG_PCI 220#ifdef CONFIG_PCI
259 for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;) 221 for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
260 add_bridge(np); 222 mpc85xx_add_bridge(np);
261 223
262 ppc_md.pcibios_fixup = mpc85xx_cds_pcibios_fixup; 224 ppc_md.pci_irq_fixup = mpc85xx_cds_pci_irq_fixup;
263 ppc_md.pci_exclude_device = mpc85xx_exclude_device; 225 ppc_md.pci_exclude_device = mpc85xx_exclude_device;
264#endif 226#endif
265} 227}
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_mds.c b/arch/powerpc/platforms/85xx/mpc85xx_mds.c
index e3dddbfe66ff..004b80bd0b84 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_mds.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_mds.c
@@ -59,11 +59,6 @@
59#define DBG(fmt...) 59#define DBG(fmt...)
60#endif 60#endif
61 61
62#ifndef CONFIG_PCI
63unsigned long isa_io_base = 0;
64unsigned long isa_mem_base = 0;
65#endif
66
67/* ************************************************************************ 62/* ************************************************************************
68 * 63 *
69 * Setup the architecture 64 * Setup the architecture
@@ -100,7 +95,7 @@ static void __init mpc85xx_mds_setup_arch(void)
100 95
101#ifdef CONFIG_PCI 96#ifdef CONFIG_PCI
102 for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;) { 97 for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;) {
103 add_bridge(np); 98 mpc85xx_add_bridge(np);
104 } 99 }
105 of_node_put(np); 100 of_node_put(np);
106#endif 101#endif
@@ -181,29 +176,10 @@ static void __init mpc85xx_mds_pic_init(void)
181 176
182 mpic = mpic_alloc(np, r.start, 177 mpic = mpic_alloc(np, r.start,
183 MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, 178 MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN,
184 4, 0, " OpenPIC "); 179 0, 256, " OpenPIC ");
185 BUG_ON(mpic == NULL); 180 BUG_ON(mpic == NULL);
186 of_node_put(np); 181 of_node_put(np);
187 182
188 /* Internal Interrupts */
189 mpic_assign_isu(mpic, 0, r.start + 0x10200);
190 mpic_assign_isu(mpic, 1, r.start + 0x10280);
191 mpic_assign_isu(mpic, 2, r.start + 0x10300);
192 mpic_assign_isu(mpic, 3, r.start + 0x10380);
193 mpic_assign_isu(mpic, 4, r.start + 0x10400);
194 mpic_assign_isu(mpic, 5, r.start + 0x10480);
195 mpic_assign_isu(mpic, 6, r.start + 0x10500);
196 mpic_assign_isu(mpic, 7, r.start + 0x10580);
197 mpic_assign_isu(mpic, 8, r.start + 0x10600);
198 mpic_assign_isu(mpic, 9, r.start + 0x10680);
199 mpic_assign_isu(mpic, 10, r.start + 0x10700);
200 mpic_assign_isu(mpic, 11, r.start + 0x10780);
201
202 /* External Interrupts */
203 mpic_assign_isu(mpic, 12, r.start + 0x10000);
204 mpic_assign_isu(mpic, 13, r.start + 0x10080);
205 mpic_assign_isu(mpic, 14, r.start + 0x10100);
206
207 mpic_init(mpic); 183 mpic_init(mpic);
208 184
209#ifdef CONFIG_QUICC_ENGINE 185#ifdef CONFIG_QUICC_ENGINE
diff --git a/arch/powerpc/platforms/85xx/pci.c b/arch/powerpc/platforms/85xx/pci.c
index 48f17e23d771..8118417b7364 100644
--- a/arch/powerpc/platforms/85xx/pci.c
+++ b/arch/powerpc/platforms/85xx/pci.c
@@ -33,10 +33,8 @@
33#define DBG(x...) 33#define DBG(x...)
34#endif 34#endif
35 35
36int mpc85xx_pci2_busno = 0;
37
38#ifdef CONFIG_PCI 36#ifdef CONFIG_PCI
39int __init add_bridge(struct device_node *dev) 37int __init mpc85xx_add_bridge(struct device_node *dev)
40{ 38{
41 int len; 39 int len;
42 struct pci_controller *hose; 40 struct pci_controller *hose;
@@ -57,11 +55,10 @@ int __init add_bridge(struct device_node *dev)
57 " bus 0\n", dev->full_name); 55 " bus 0\n", dev->full_name);
58 } 56 }
59 57
60 hose = pcibios_alloc_controller(); 58 pci_assign_all_buses = 1;
59 hose = pcibios_alloc_controller(dev);
61 if (!hose) 60 if (!hose)
62 return -ENOMEM; 61 return -ENOMEM;
63 hose->arch_data = dev;
64 hose->set_cfg_type = 1;
65 62
66 hose->first_busno = bus_range ? bus_range[0] : 0; 63 hose->first_busno = bus_range ? bus_range[0] : 0;
67 hose->last_busno = bus_range ? bus_range[1] : 0xff; 64 hose->last_busno = bus_range ? bus_range[1] : 0xff;
@@ -74,8 +71,6 @@ int __init add_bridge(struct device_node *dev)
74 if ((rsrc.start & 0xfffff) == 0x9000) { 71 if ((rsrc.start & 0xfffff) == 0x9000) {
75 setup_indirect_pci(hose, immr + 0x9000, immr + 0x9004); 72 setup_indirect_pci(hose, immr + 0x9000, immr + 0x9004);
76 primary = 0; 73 primary = 0;
77 hose->bus_offset = hose->first_busno;
78 mpc85xx_pci2_busno = hose->first_busno;
79 } 74 }
80 75
81 printk(KERN_INFO "Found MPC85xx PCI host bridge at 0x%016llx. " 76 printk(KERN_INFO "Found MPC85xx PCI host bridge at 0x%016llx. "
diff --git a/arch/powerpc/platforms/86xx/Kconfig b/arch/powerpc/platforms/86xx/Kconfig
index d1bcff500464..0faebfdc1596 100644
--- a/arch/powerpc/platforms/86xx/Kconfig
+++ b/arch/powerpc/platforms/86xx/Kconfig
@@ -1,5 +1,5 @@
1choice 1choice
2 prompt "Machine Type" 2 prompt "86xx Board Type"
3 depends on PPC_86xx 3 depends on PPC_86xx
4 default MPC8641_HPCN 4 default MPC8641_HPCN
5 5
diff --git a/arch/powerpc/platforms/86xx/mpc86xx.h b/arch/powerpc/platforms/86xx/mpc86xx.h
index 2834462590b8..23f7ed2a7f88 100644
--- a/arch/powerpc/platforms/86xx/mpc86xx.h
+++ b/arch/powerpc/platforms/86xx/mpc86xx.h
@@ -15,15 +15,10 @@
15 * mpc86xx_* files. Mostly for use by mpc86xx_setup(). 15 * mpc86xx_* files. Mostly for use by mpc86xx_setup().
16 */ 16 */
17 17
18extern int add_bridge(struct device_node *dev); 18extern int mpc86xx_add_bridge(struct device_node *dev);
19 19
20extern int mpc86xx_exclude_device(u_char bus, u_char devfn); 20extern int mpc86xx_exclude_device(struct pci_controller *hose,
21 21 u_char bus, u_char devfn);
22extern void setup_indirect_pcie(struct pci_controller *hose,
23 u32 cfg_addr, u32 cfg_data);
24extern void setup_indirect_pcie_nomap(struct pci_controller *hose,
25 void __iomem *cfg_addr,
26 void __iomem *cfg_data);
27 22
28extern void __init mpc86xx_smp_init(void); 23extern void __init mpc86xx_smp_init(void);
29 24
diff --git a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
index 1051702c8d4f..5b01ec7c13dc 100644
--- a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
+++ b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
@@ -44,13 +44,6 @@
44#define DBG(fmt...) do { } while(0) 44#define DBG(fmt...) do { } while(0)
45#endif 45#endif
46 46
47#ifndef CONFIG_PCI
48unsigned long isa_io_base = 0;
49unsigned long isa_mem_base = 0;
50unsigned long pci_dram_offset = 0;
51#endif
52
53
54#ifdef CONFIG_PCI 47#ifdef CONFIG_PCI
55static void mpc86xx_8259_cascade(unsigned int irq, struct irq_desc *desc) 48static void mpc86xx_8259_cascade(unsigned int irq, struct irq_desc *desc)
56{ 49{
@@ -81,22 +74,9 @@ mpc86xx_hpcn_init_irq(void)
81 /* Alloc mpic structure and per isu has 16 INT entries. */ 74 /* Alloc mpic structure and per isu has 16 INT entries. */
82 mpic1 = mpic_alloc(np, res.start, 75 mpic1 = mpic_alloc(np, res.start,
83 MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, 76 MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN,
84 16, NR_IRQS - 4, 77 0, 256, " MPIC ");
85 " MPIC ");
86 BUG_ON(mpic1 == NULL); 78 BUG_ON(mpic1 == NULL);
87 79
88 mpic_assign_isu(mpic1, 0, res.start + 0x10000);
89
90 /* 48 Internal Interrupts */
91 mpic_assign_isu(mpic1, 1, res.start + 0x10200);
92 mpic_assign_isu(mpic1, 2, res.start + 0x10400);
93 mpic_assign_isu(mpic1, 3, res.start + 0x10600);
94
95 /* 16 External interrupts
96 * Moving them from [0 - 15] to [64 - 79]
97 */
98 mpic_assign_isu(mpic1, 4, res.start + 0x10000);
99
100 mpic_init(mpic1); 80 mpic_init(mpic1);
101 81
102#ifdef CONFIG_PCI 82#ifdef CONFIG_PCI
@@ -319,6 +299,7 @@ static void __devinit quirk_uli5229(struct pci_dev *dev)
319{ 299{
320 unsigned short temp; 300 unsigned short temp;
321 pci_write_config_word(dev, 0x04, 0x0405); 301 pci_write_config_word(dev, 0x04, 0x0405);
302 dev->class &= ~0x5;
322 pci_read_config_word(dev, 0x4a, &temp); 303 pci_read_config_word(dev, 0x4a, &temp);
323 temp |= 0x1000; 304 temp |= 0x1000;
324 pci_write_config_word(dev, 0x4a, temp); 305 pci_write_config_word(dev, 0x4a, temp);
@@ -364,9 +345,7 @@ mpc86xx_hpcn_setup_arch(void)
364 345
365#ifdef CONFIG_PCI 346#ifdef CONFIG_PCI
366 for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;) 347 for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
367 add_bridge(np); 348 mpc86xx_add_bridge(np);
368
369 ppc_md.pci_exclude_device = mpc86xx_exclude_device;
370#endif 349#endif
371 350
372 printk("MPC86xx HPCN board from Freescale Semiconductor\n"); 351 printk("MPC86xx HPCN board from Freescale Semiconductor\n");
diff --git a/arch/powerpc/platforms/86xx/pci.c b/arch/powerpc/platforms/86xx/pci.c
index 8235c562661f..73cd5b05a84e 100644
--- a/arch/powerpc/platforms/86xx/pci.c
+++ b/arch/powerpc/platforms/86xx/pci.c
@@ -122,7 +122,6 @@ static void __init
122mpc86xx_setup_pcie(struct pci_controller *hose, u32 pcie_offset, u32 pcie_size) 122mpc86xx_setup_pcie(struct pci_controller *hose, u32 pcie_offset, u32 pcie_size)
123{ 123{
124 u16 cmd; 124 u16 cmd;
125 unsigned int temps;
126 125
127 DBG("PCIE host controller register offset 0x%08x, size 0x%08x.\n", 126 DBG("PCIE host controller register offset 0x%08x, size 0x%08x.\n",
128 pcie_offset, pcie_size); 127 pcie_offset, pcie_size);
@@ -133,22 +132,49 @@ mpc86xx_setup_pcie(struct pci_controller *hose, u32 pcie_offset, u32 pcie_size)
133 early_write_config_word(hose, 0, 0, PCI_COMMAND, cmd); 132 early_write_config_word(hose, 0, 0, PCI_COMMAND, cmd);
134 133
135 early_write_config_byte(hose, 0, 0, PCI_LATENCY_TIMER, 0x80); 134 early_write_config_byte(hose, 0, 0, PCI_LATENCY_TIMER, 0x80);
136
137 /* PCIE Bus, Fix the MPC8641D host bridge's location to bus 0xFF. */
138 early_read_config_dword(hose, 0, 0, PCI_PRIMARY_BUS, &temps);
139 temps = (temps & 0xff000000) | (0xff) | (0x0 << 8) | (0xfe << 16);
140 early_write_config_dword(hose, 0, 0, PCI_PRIMARY_BUS, temps);
141} 135}
142 136
143int mpc86xx_exclude_device(u_char bus, u_char devfn) 137static void __devinit quirk_fsl_pcie_transparent(struct pci_dev *dev)
144{ 138{
145 if (bus == 0 && PCI_SLOT(devfn) == 0) 139 struct resource *res;
146 return PCIBIOS_DEVICE_NOT_FOUND; 140 int i, res_idx = PCI_BRIDGE_RESOURCES;
141 struct pci_controller *hose;
147 142
148 return PCIBIOS_SUCCESSFUL; 143 /*
144 * Make the bridge be transparent.
145 */
146 dev->transparent = 1;
147
148 hose = pci_bus_to_host(dev->bus);
149 if (!hose) {
150 printk(KERN_ERR "Can't find hose for bus %d\n",
151 dev->bus->number);
152 return;
153 }
154
155 if (hose->io_resource.flags) {
156 res = &dev->resource[res_idx++];
157 res->start = hose->io_resource.start;
158 res->end = hose->io_resource.end;
159 res->flags = hose->io_resource.flags;
160 }
161
162 for (i = 0; i < 3; i++) {
163 res = &dev->resource[res_idx + i];
164 res->start = hose->mem_resources[i].start;
165 res->end = hose->mem_resources[i].end;
166 res->flags = hose->mem_resources[i].flags;
167 }
149} 168}
150 169
151int __init add_bridge(struct device_node *dev) 170
171DECLARE_PCI_FIXUP_EARLY(0x1957, 0x7010, quirk_fsl_pcie_transparent);
172DECLARE_PCI_FIXUP_EARLY(0x1957, 0x7011, quirk_fsl_pcie_transparent);
173
174#define PCIE_LTSSM 0x404 /* PCIe Link Training and Status */
175#define PCIE_LTSSM_L0 0x16 /* L0 state */
176
177int __init mpc86xx_add_bridge(struct device_node *dev)
152{ 178{
153 int len; 179 int len;
154 struct pci_controller *hose; 180 struct pci_controller *hose;
@@ -156,6 +182,7 @@ int __init add_bridge(struct device_node *dev)
156 const int *bus_range; 182 const int *bus_range;
157 int has_address = 0; 183 int has_address = 0;
158 int primary = 0; 184 int primary = 0;
185 u16 val;
159 186
160 DBG("Adding PCIE host bridge %s\n", dev->full_name); 187 DBG("Adding PCIE host bridge %s\n", dev->full_name);
161 188
@@ -168,17 +195,23 @@ int __init add_bridge(struct device_node *dev)
168 printk(KERN_WARNING "Can't get bus-range for %s, assume" 195 printk(KERN_WARNING "Can't get bus-range for %s, assume"
169 " bus 0\n", dev->full_name); 196 " bus 0\n", dev->full_name);
170 197
171 hose = pcibios_alloc_controller(); 198 pci_assign_all_buses = 1;
199 hose = pcibios_alloc_controller(dev);
172 if (!hose) 200 if (!hose)
173 return -ENOMEM; 201 return -ENOMEM;
174 hose->arch_data = dev;
175 hose->set_cfg_type = 1;
176 202
177 /* last_busno = 0xfe cause by MPC8641 PCIE bug */ 203 hose->indirect_type = PPC_INDIRECT_TYPE_EXT_REG |
204 PPC_INDIRECT_TYPE_SURPRESS_PRIMARY_BUS;
205
178 hose->first_busno = bus_range ? bus_range[0] : 0x0; 206 hose->first_busno = bus_range ? bus_range[0] : 0x0;
179 hose->last_busno = bus_range ? bus_range[1] : 0xfe; 207 hose->last_busno = bus_range ? bus_range[1] : 0xff;
208
209 setup_indirect_pci(hose, rsrc.start, rsrc.start + 0x4);
180 210
181 setup_indirect_pcie(hose, rsrc.start, rsrc.start + 0x4); 211 /* Probe the hose link training status */
212 early_read_config_word(hose, 0, 0, PCIE_LTSSM, &val);
213 if (val < PCIE_LTSSM_L0)
214 return -ENXIO;
182 215
183 /* Setup the PCIE host controller. */ 216 /* Setup the PCIE host controller. */
184 mpc86xx_setup_pcie(hose, rsrc.start, rsrc.end - rsrc.start + 1); 217 mpc86xx_setup_pcie(hose, rsrc.start, rsrc.end - rsrc.start + 1);
diff --git a/arch/powerpc/platforms/8xx/m8xx_setup.c b/arch/powerpc/platforms/8xx/m8xx_setup.c
index 0901dbada350..f1693550c70c 100644
--- a/arch/powerpc/platforms/8xx/m8xx_setup.c
+++ b/arch/powerpc/platforms/8xx/m8xx_setup.c
@@ -32,6 +32,7 @@
32#include <linux/root_dev.h> 32#include <linux/root_dev.h>
33#include <linux/time.h> 33#include <linux/time.h>
34#include <linux/rtc.h> 34#include <linux/rtc.h>
35#include <linux/fsl_devices.h>
35 36
36#include <asm/mmu.h> 37#include <asm/mmu.h>
37#include <asm/reg.h> 38#include <asm/reg.h>
@@ -49,6 +50,10 @@
49 50
50#include "sysdev/mpc8xx_pic.h" 51#include "sysdev/mpc8xx_pic.h"
51 52
53#ifdef CONFIG_PCMCIA_M8XX
54struct mpc8xx_pcmcia_ops m8xx_pcmcia_ops;
55#endif
56
52void m8xx_calibrate_decr(void); 57void m8xx_calibrate_decr(void);
53extern void m8xx_wdt_handler_install(bd_t *bp); 58extern void m8xx_wdt_handler_install(bd_t *bp);
54extern int cpm_pic_init(void); 59extern int cpm_pic_init(void);
diff --git a/arch/powerpc/platforms/8xx/mpc885ads_setup.c b/arch/powerpc/platforms/8xx/mpc885ads_setup.c
index c36e475d93dc..dc27dab48df0 100644
--- a/arch/powerpc/platforms/8xx/mpc885ads_setup.c
+++ b/arch/powerpc/platforms/8xx/mpc885ads_setup.c
@@ -22,6 +22,7 @@
22 22
23#include <linux/fs_enet_pd.h> 23#include <linux/fs_enet_pd.h>
24#include <linux/fs_uart_pd.h> 24#include <linux/fs_uart_pd.h>
25#include <linux/fsl_devices.h>
25#include <linux/mii.h> 26#include <linux/mii.h>
26 27
27#include <asm/delay.h> 28#include <asm/delay.h>
@@ -51,6 +52,70 @@ static void init_smc1_uart_ioports(struct fs_uart_platform_info* fpi);
51static void init_smc2_uart_ioports(struct fs_uart_platform_info* fpi); 52static void init_smc2_uart_ioports(struct fs_uart_platform_info* fpi);
52static void init_scc3_ioports(struct fs_platform_info* ptr); 53static void init_scc3_ioports(struct fs_platform_info* ptr);
53 54
55#ifdef CONFIG_PCMCIA_M8XX
56static void pcmcia_hw_setup(int slot, int enable)
57{
58 unsigned *bcsr_io;
59
60 bcsr_io = ioremap(BCSR1, sizeof(unsigned long));
61 if (enable)
62 clrbits32(bcsr_io, BCSR1_PCCEN);
63 else
64 setbits32(bcsr_io, BCSR1_PCCEN);
65
66 iounmap(bcsr_io);
67}
68
69static int pcmcia_set_voltage(int slot, int vcc, int vpp)
70{
71 u32 reg = 0;
72 unsigned *bcsr_io;
73
74 bcsr_io = ioremap(BCSR1, sizeof(unsigned long));
75
76 switch(vcc) {
77 case 0:
78 break;
79 case 33:
80 reg |= BCSR1_PCCVCC0;
81 break;
82 case 50:
83 reg |= BCSR1_PCCVCC1;
84 break;
85 default:
86 return 1;
87 }
88
89 switch(vpp) {
90 case 0:
91 break;
92 case 33:
93 case 50:
94 if(vcc == vpp)
95 reg |= BCSR1_PCCVPP1;
96 else
97 return 1;
98 break;
99 case 120:
100 if ((vcc == 33) || (vcc == 50))
101 reg |= BCSR1_PCCVPP0;
102 else
103 return 1;
104 default:
105 return 1;
106 }
107
108 /* first, turn off all power */
109 clrbits32(bcsr_io, 0x00610000);
110
111 /* enable new powersettings */
112 setbits32(bcsr_io, reg);
113
114 iounmap(bcsr_io);
115 return 0;
116}
117#endif
118
54void __init mpc885ads_board_setup(void) 119void __init mpc885ads_board_setup(void)
55{ 120{
56 cpm8xx_t *cp; 121 cpm8xx_t *cp;
@@ -115,6 +180,12 @@ void __init mpc885ads_board_setup(void)
115 immr_unmap(io_port); 180 immr_unmap(io_port);
116 181
117#endif 182#endif
183
184#ifdef CONFIG_PCMCIA_M8XX
185 /*Set up board specific hook-ups*/
186 m8xx_pcmcia_ops.hw_ctrl = pcmcia_hw_setup;
187 m8xx_pcmcia_ops.voltage_set = pcmcia_set_voltage;
188#endif
118} 189}
119 190
120 191
diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig
index 361acfa2894c..33545d352e92 100644
--- a/arch/powerpc/platforms/Kconfig
+++ b/arch/powerpc/platforms/Kconfig
@@ -2,7 +2,7 @@ menu "Platform support"
2 2
3choice 3choice
4 prompt "Machine type" 4 prompt "Machine type"
5 depends on PPC64 || CLASSIC32 5 depends on PPC64 || 6xx
6 default PPC_MULTIPLATFORM 6 default PPC_MULTIPLATFORM
7 7
8config PPC_MULTIPLATFORM 8config PPC_MULTIPLATFORM
@@ -16,15 +16,30 @@ config EMBEDDED6xx
16 bool "Embedded 6xx/7xx/7xxx-based board" 16 bool "Embedded 6xx/7xx/7xxx-based board"
17 depends on PPC32 && (BROKEN||BROKEN_ON_SMP) 17 depends on PPC32 && (BROKEN||BROKEN_ON_SMP)
18 18
19config APUS 19config PPC_82xx
20 bool "Amiga-APUS" 20 bool "Freescale 82xx"
21 depends on PPC32 && BROKEN 21 depends on 6xx
22
23config PPC_83xx
24 bool "Freescale 83xx"
25 depends on 6xx
26 select FSL_SOC
27 select 83xx
28 select WANT_DEVICE_TREE
29
30config PPC_86xx
31 bool "Freescale 86xx"
32 depends on 6xx
33 select FSL_SOC
34 select ALTIVEC
22 help 35 help
23 Select APUS if configuring for a PowerUP Amiga. 36 The Freescale E600 SoCs have 74xx cores.
24 More information is available at:
25 <http://linux-apus.sourceforge.net/>.
26endchoice 37endchoice
27 38
39config CLASSIC32
40 def_bool y
41 depends on 6xx && PPC_MULTIPLATFORM
42
28source "arch/powerpc/platforms/pseries/Kconfig" 43source "arch/powerpc/platforms/pseries/Kconfig"
29source "arch/powerpc/platforms/iseries/Kconfig" 44source "arch/powerpc/platforms/iseries/Kconfig"
30source "arch/powerpc/platforms/chrp/Kconfig" 45source "arch/powerpc/platforms/chrp/Kconfig"
diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype
new file mode 100644
index 000000000000..b8b5fde94668
--- /dev/null
+++ b/arch/powerpc/platforms/Kconfig.cputype
@@ -0,0 +1,221 @@
1config PPC64
2 bool "64-bit kernel"
3 default n
4 help
5 This option selects whether a 32-bit or a 64-bit kernel
6 will be built.
7
8menu "Processor support"
9choice
10 prompt "Processor Type"
11 depends on PPC32
12 default 6xx
13 help
14 There are five families of 32 bit PowerPC chips supported.
15 The most common ones are the desktop and server CPUs (601, 603,
16 604, 740, 750, 74xx) CPUs from Freescale and IBM, with their
17 embedded 52xx/82xx/83xx/86xx counterparts.
18 The other embeeded parts, namely 4xx, 8xx, e200 (55xx) and e500
19 (85xx) each form a family of their own that is not compatible
20 with the others.
21
22 If unsure, select 52xx/6xx/7xx/74xx/82xx/83xx/86xx.
23
24config 6xx
25 bool "52xx/6xx/7xx/74xx/82xx/83xx/86xx"
26 select PPC_FPU
27
28config PPC_85xx
29 bool "Freescale 85xx"
30 select E500
31 select FSL_SOC
32 select 85xx
33 select WANT_DEVICE_TREE
34
35config PPC_8xx
36 bool "Freescale 8xx"
37 select FSL_SOC
38 select 8xx
39
40config 40x
41 bool "AMCC 40x"
42 select PPC_DCR_NATIVE
43
44config 44x
45 bool "AMCC 44x"
46 select PPC_DCR_NATIVE
47 select WANT_DEVICE_TREE
48
49config E200
50 bool "Freescale e200"
51
52endchoice
53
54config POWER4_ONLY
55 bool "Optimize for POWER4"
56 depends on PPC64
57 default n
58 ---help---
59 Cause the compiler to optimize for POWER4/POWER5/PPC970 processors.
60 The resulting binary will not work on POWER3 or RS64 processors
61 when compiled with binutils 2.15 or later.
62
63config POWER3
64 bool
65 depends on PPC64
66 default y if !POWER4_ONLY
67
68config POWER4
69 depends on PPC64
70 def_bool y
71
72config 6xx
73 bool
74
75# this is temp to handle compat with arch=ppc
76config 8xx
77 bool
78
79# this is temp to handle compat with arch=ppc
80config 83xx
81 bool
82
83# this is temp to handle compat with arch=ppc
84config 85xx
85 bool
86
87config E500
88 bool
89
90config PPC_FPU
91 bool
92 default y if PPC64
93
94config 4xx
95 bool
96 depends on 40x || 44x
97 default y
98
99config BOOKE
100 bool
101 depends on E200 || E500 || 44x
102 default y
103
104config FSL_BOOKE
105 bool
106 depends on E200 || E500
107 default y
108
109config PTE_64BIT
110 bool
111 depends on 44x || E500
112 default y if 44x
113 default y if E500 && PHYS_64BIT
114
115config PHYS_64BIT
116 bool 'Large physical address support' if E500
117 depends on 44x || E500
118 select RESOURCES_64BIT
119 default y if 44x
120 ---help---
121 This option enables kernel support for larger than 32-bit physical
122 addresses. This features is not be available on all e500 cores.
123
124 If in doubt, say N here.
125
126config ALTIVEC
127 bool "AltiVec Support"
128 depends on CLASSIC32 || POWER4
129 ---help---
130 This option enables kernel support for the Altivec extensions to the
131 PowerPC processor. The kernel currently supports saving and restoring
132 altivec registers, and turning on the 'altivec enable' bit so user
133 processes can execute altivec instructions.
134
135 This option is only usefully if you have a processor that supports
136 altivec (G4, otherwise known as 74xx series), but does not have
137 any affect on a non-altivec cpu (it does, however add code to the
138 kernel).
139
140 If in doubt, say Y here.
141
142config SPE
143 bool "SPE Support"
144 depends on E200 || E500
145 default y
146 ---help---
147 This option enables kernel support for the Signal Processing
148 Extensions (SPE) to the PowerPC processor. The kernel currently
149 supports saving and restoring SPE registers, and turning on the
150 'spe enable' bit so user processes can execute SPE instructions.
151
152 This option is only useful if you have a processor that supports
153 SPE (e500, otherwise known as 85xx series), but does not have any
154 effect on a non-spe cpu (it does, however add code to the kernel).
155
156 If in doubt, say Y here.
157
158config PPC_STD_MMU
159 bool
160 depends on 6xx || POWER3 || POWER4 || PPC64
161 default y
162
163config PPC_STD_MMU_32
164 def_bool y
165 depends on PPC_STD_MMU && PPC32
166
167config PPC_MM_SLICES
168 bool
169 default y if HUGETLB_PAGE
170 default n
171
172config VIRT_CPU_ACCOUNTING
173 bool "Deterministic task and CPU time accounting"
174 depends on PPC64
175 default y
176 help
177 Select this option to enable more accurate task and CPU time
178 accounting. This is done by reading a CPU counter on each
179 kernel entry and exit and on transitions within the kernel
180 between system, softirq and hardirq state, so there is a
181 small performance impact. This also enables accounting of
182 stolen time on logically-partitioned systems running on
183 IBM POWER5-based machines.
184
185 If in doubt, say Y here.
186
187config SMP
188 depends on PPC_STD_MMU
189 bool "Symmetric multi-processing support"
190 ---help---
191 This enables support for systems with more than one CPU. If you have
192 a system with only one CPU, say N. If you have a system with more
193 than one CPU, say Y. Note that the kernel does not currently
194 support SMP machines with 603/603e/603ev or PPC750 ("G3") processors
195 since they have inadequate hardware support for multiprocessor
196 operation.
197
198 If you say N here, the kernel will run on single and multiprocessor
199 machines, but will use only one CPU of a multiprocessor machine. If
200 you say Y here, the kernel will run on single-processor machines.
201 On a single-processor machine, the kernel will run faster if you say
202 N here.
203
204 If you don't know what to do here, say N.
205
206config NR_CPUS
207 int "Maximum number of CPUs (2-128)"
208 range 2 128
209 depends on SMP
210 default "32" if PPC64
211 default "4"
212
213config NOT_COHERENT_CACHE
214 bool
215 depends on 4xx || 8xx || E200
216 default y
217
218config CONFIG_CHECK_CACHE_COHERENCY
219 bool
220
221endmenu
diff --git a/arch/powerpc/platforms/apus/Kconfig b/arch/powerpc/platforms/apus/Kconfig
deleted file mode 100644
index 6bde3bffed86..000000000000
--- a/arch/powerpc/platforms/apus/Kconfig
+++ /dev/null
@@ -1,130 +0,0 @@
1
2config AMIGA
3 bool
4 depends on APUS
5 default y
6 help
7 This option enables support for the Amiga series of computers.
8
9config ZORRO
10 bool
11 depends on APUS
12 default y
13 help
14 This enables support for the Zorro bus in the Amiga. If you have
15 expansion cards in your Amiga that conform to the Amiga
16 AutoConfig(tm) specification, say Y, otherwise N. Note that even
17 expansion cards that do not fit in the Zorro slots but fit in e.g.
18 the CPU slot may fall in this category, so you have to say Y to let
19 Linux use these.
20
21config ABSTRACT_CONSOLE
22 bool
23 depends on APUS
24 default y
25
26config APUS_FAST_EXCEPT
27 bool
28 depends on APUS
29 default y
30
31config AMIGA_PCMCIA
32 bool "Amiga 1200/600 PCMCIA support"
33 depends on APUS && EXPERIMENTAL
34 help
35 Include support in the kernel for pcmcia on Amiga 1200 and Amiga
36 600. If you intend to use pcmcia cards say Y; otherwise say N.
37
38config AMIGA_BUILTIN_SERIAL
39 tristate "Amiga builtin serial support"
40 depends on APUS
41 help
42 If you want to use your Amiga's built-in serial port in Linux,
43 answer Y.
44
45 To compile this driver as a module, choose M here.
46
47config GVPIOEXT
48 tristate "GVP IO-Extender support"
49 depends on APUS
50 help
51 If you want to use a GVP IO-Extender serial card in Linux, say Y.
52 Otherwise, say N.
53
54config GVPIOEXT_LP
55 tristate "GVP IO-Extender parallel printer support"
56 depends on GVPIOEXT
57 help
58 Say Y to enable driving a printer from the parallel port on your
59 GVP IO-Extender card, N otherwise.
60
61config GVPIOEXT_PLIP
62 tristate "GVP IO-Extender PLIP support"
63 depends on GVPIOEXT
64 help
65 Say Y to enable doing IP over the parallel port on your GVP
66 IO-Extender card, N otherwise.
67
68config MULTIFACE_III_TTY
69 tristate "Multiface Card III serial support"
70 depends on APUS
71 help
72 If you want to use a Multiface III card's serial port in Linux,
73 answer Y.
74
75 To compile this driver as a module, choose M here.
76
77config A2232
78 tristate "Commodore A2232 serial support (EXPERIMENTAL)"
79 depends on EXPERIMENTAL && APUS
80 ---help---
81 This option supports the 2232 7-port serial card shipped with the
82 Amiga 2000 and other Zorro-bus machines, dating from 1989. At
83 a max of 19,200 bps, the ports are served by a 6551 ACIA UART chip
84 each, plus a 8520 CIA, and a master 6502 CPU and buffer as well. The
85 ports were connected with 8 pin DIN connectors on the card bracket,
86 for which 8 pin to DB25 adapters were supplied. The card also had
87 jumpers internally to toggle various pinning configurations.
88
89 This driver can be built as a module; but then "generic_serial"
90 will also be built as a module. This has to be loaded before
91 "ser_a2232". If you want to do this, answer M here.
92
93config WHIPPET_SERIAL
94 tristate "Hisoft Whippet PCMCIA serial support"
95 depends on AMIGA_PCMCIA
96 help
97 HiSoft has a web page at <http://www.hisoft.co.uk/>, but there
98 is no listing for the Whippet in their Amiga section.
99
100config APNE
101 tristate "PCMCIA NE2000 support"
102 depends on AMIGA_PCMCIA
103 help
104 If you have a PCMCIA NE2000 compatible adapter, say Y. Otherwise,
105 say N.
106
107 To compile this driver as a module, choose M here: the
108 module will be called apne.
109
110config SERIAL_CONSOLE
111 bool "Support for serial port console"
112 depends on APUS && (AMIGA_BUILTIN_SERIAL=y || GVPIOEXT=y || MULTIFACE_III_TTY=y)
113
114config HEARTBEAT
115 bool "Use power LED as a heartbeat"
116 depends on APUS
117 help
118 Use the power-on LED on your machine as a load meter. The exact
119 behavior is platform-dependent, but normally the flash frequency is
120 a hyperbolic function of the 5-minute load average.
121
122config PROC_HARDWARE
123 bool "/proc/hardware support"
124 depends on APUS
125
126source "drivers/zorro/Kconfig"
127
128config PCI_PERMEDIA
129 bool "PCI for Permedia2"
130 depends on !4xx && !8xx && APUS
diff --git a/arch/powerpc/platforms/cell/io-workarounds.c b/arch/powerpc/platforms/cell/io-workarounds.c
index 7fb92f23f380..9d7c2ef940a8 100644
--- a/arch/powerpc/platforms/cell/io-workarounds.c
+++ b/arch/powerpc/platforms/cell/io-workarounds.c
@@ -102,7 +102,7 @@ static void spider_io_flush(const volatile void __iomem *addr)
102 vaddr = (unsigned long)PCI_FIX_ADDR(addr); 102 vaddr = (unsigned long)PCI_FIX_ADDR(addr);
103 103
104 /* Check if it's in allowed range for PIO */ 104 /* Check if it's in allowed range for PIO */
105 if (vaddr < PHBS_IO_BASE || vaddr >= IMALLOC_BASE) 105 if (vaddr < PHB_IO_BASE || vaddr > PHB_IO_END)
106 return; 106 return;
107 107
108 /* Try to find a PTE. If not, clear the paddr, we'll do 108 /* Try to find a PTE. If not, clear the paddr, we'll do
diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c
index a7f5a7653c62..e4d0c9f42abd 100644
--- a/arch/powerpc/platforms/cell/spu_base.c
+++ b/arch/powerpc/platforms/cell/spu_base.c
@@ -183,7 +183,7 @@ static int __spu_trap_data_seg(struct spu *spu, unsigned long ea)
183 spu->slb_replace = 0; 183 spu->slb_replace = 0;
184 184
185 spu_restart_dma(spu); 185 spu_restart_dma(spu);
186 186 spu->stats.slb_flt++;
187 return 0; 187 return 0;
188} 188}
189 189
@@ -332,6 +332,7 @@ spu_irq_class_2(int irq, void *data)
332 if (stat & 0x10) /* SPU mailbox threshold */ 332 if (stat & 0x10) /* SPU mailbox threshold */
333 spu->wbox_callback(spu); 333 spu->wbox_callback(spu);
334 334
335 spu->stats.class2_intr++;
335 return stat ? IRQ_HANDLED : IRQ_NONE; 336 return stat ? IRQ_HANDLED : IRQ_NONE;
336} 337}
337 338
@@ -462,8 +463,18 @@ void spu_free(struct spu *spu)
462} 463}
463EXPORT_SYMBOL_GPL(spu_free); 464EXPORT_SYMBOL_GPL(spu_free);
464 465
466static int spu_shutdown(struct sys_device *sysdev)
467{
468 struct spu *spu = container_of(sysdev, struct spu, sysdev);
469
470 spu_free_irqs(spu);
471 spu_destroy_spu(spu);
472 return 0;
473}
474
465struct sysdev_class spu_sysdev_class = { 475struct sysdev_class spu_sysdev_class = {
466 set_kset_name("spu") 476 set_kset_name("spu"),
477 .shutdown = spu_shutdown,
467}; 478};
468 479
469int spu_add_sysdev_attr(struct sysdev_attribute *attr) 480int spu_add_sysdev_attr(struct sysdev_attribute *attr)
@@ -574,6 +585,9 @@ static int __init create_spu(void *data)
574 spin_unlock_irqrestore(&spu_list_lock, flags); 585 spin_unlock_irqrestore(&spu_list_lock, flags);
575 mutex_unlock(&spu_mutex); 586 mutex_unlock(&spu_mutex);
576 587
588 spu->stats.utilization_state = SPU_UTIL_IDLE;
589 spu->stats.tstamp = jiffies;
590
577 goto out; 591 goto out;
578 592
579out_free_irqs: 593out_free_irqs:
@@ -586,6 +600,45 @@ out:
586 return ret; 600 return ret;
587} 601}
588 602
603static const char *spu_state_names[] = {
604 "user", "system", "iowait", "idle"
605};
606
607static unsigned long long spu_acct_time(struct spu *spu,
608 enum spu_utilization_state state)
609{
610 unsigned long long time = spu->stats.times[state];
611
612 if (spu->stats.utilization_state == state)
613 time += jiffies - spu->stats.tstamp;
614
615 return jiffies_to_msecs(time);
616}
617
618
619static ssize_t spu_stat_show(struct sys_device *sysdev, char *buf)
620{
621 struct spu *spu = container_of(sysdev, struct spu, sysdev);
622
623 return sprintf(buf, "%s %llu %llu %llu %llu "
624 "%llu %llu %llu %llu %llu %llu %llu %llu\n",
625 spu_state_names[spu->stats.utilization_state],
626 spu_acct_time(spu, SPU_UTIL_USER),
627 spu_acct_time(spu, SPU_UTIL_SYSTEM),
628 spu_acct_time(spu, SPU_UTIL_IOWAIT),
629 spu_acct_time(spu, SPU_UTIL_IDLE),
630 spu->stats.vol_ctx_switch,
631 spu->stats.invol_ctx_switch,
632 spu->stats.slb_flt,
633 spu->stats.hash_flt,
634 spu->stats.min_flt,
635 spu->stats.maj_flt,
636 spu->stats.class2_intr,
637 spu->stats.libassist);
638}
639
640static SYSDEV_ATTR(stat, 0644, spu_stat_show, NULL);
641
589static int __init init_spu_base(void) 642static int __init init_spu_base(void)
590{ 643{
591 int i, ret = 0; 644 int i, ret = 0;
@@ -611,6 +664,8 @@ static int __init init_spu_base(void)
611 664
612 xmon_register_spus(&spu_full_list); 665 xmon_register_spus(&spu_full_list);
613 666
667 spu_add_sysdev_attr(&attr_stat);
668
614 return 0; 669 return 0;
615 670
616 out_unregister_sysdev_class: 671 out_unregister_sysdev_class:
diff --git a/arch/powerpc/platforms/cell/spufs/backing_ops.c b/arch/powerpc/platforms/cell/spufs/backing_ops.c
index d32db9ffc6eb..07a0e815abf5 100644
--- a/arch/powerpc/platforms/cell/spufs/backing_ops.c
+++ b/arch/powerpc/platforms/cell/spufs/backing_ops.c
@@ -320,6 +320,12 @@ static int spu_backing_set_mfc_query(struct spu_context * ctx, u32 mask,
320 /* FIXME: what are the side-effects of this? */ 320 /* FIXME: what are the side-effects of this? */
321 prob->dma_querymask_RW = mask; 321 prob->dma_querymask_RW = mask;
322 prob->dma_querytype_RW = mode; 322 prob->dma_querytype_RW = mode;
323 /* In the current implementation, the SPU context is always
324 * acquired in runnable state when new bits are added to the
325 * mask (tagwait), so it's sufficient just to mask
326 * dma_tagstatus_R with the 'mask' parameter here.
327 */
328 ctx->csa.prob.dma_tagstatus_R &= mask;
323out: 329out:
324 spin_unlock(&ctx->csa.register_lock); 330 spin_unlock(&ctx->csa.register_lock);
325 331
diff --git a/arch/powerpc/platforms/cell/spufs/context.c b/arch/powerpc/platforms/cell/spufs/context.c
index 7c51cb54bca1..6d7bd60f5380 100644
--- a/arch/powerpc/platforms/cell/spufs/context.c
+++ b/arch/powerpc/platforms/cell/spufs/context.c
@@ -23,10 +23,14 @@
23#include <linux/fs.h> 23#include <linux/fs.h>
24#include <linux/mm.h> 24#include <linux/mm.h>
25#include <linux/slab.h> 25#include <linux/slab.h>
26#include <asm/atomic.h>
26#include <asm/spu.h> 27#include <asm/spu.h>
27#include <asm/spu_csa.h> 28#include <asm/spu_csa.h>
28#include "spufs.h" 29#include "spufs.h"
29 30
31
32atomic_t nr_spu_contexts = ATOMIC_INIT(0);
33
30struct spu_context *alloc_spu_context(struct spu_gang *gang) 34struct spu_context *alloc_spu_context(struct spu_gang *gang)
31{ 35{
32 struct spu_context *ctx; 36 struct spu_context *ctx;
@@ -53,10 +57,12 @@ struct spu_context *alloc_spu_context(struct spu_gang *gang)
53 INIT_LIST_HEAD(&ctx->rq); 57 INIT_LIST_HEAD(&ctx->rq);
54 if (gang) 58 if (gang)
55 spu_gang_add_ctx(gang, ctx); 59 spu_gang_add_ctx(gang, ctx);
56 ctx->rt_priority = current->rt_priority; 60 ctx->cpus_allowed = current->cpus_allowed;
57 ctx->policy = current->policy; 61 spu_set_timeslice(ctx);
58 ctx->prio = current->prio; 62 ctx->stats.execution_state = SPUCTX_UTIL_USER;
59 INIT_DELAYED_WORK(&ctx->sched_work, spu_sched_tick); 63 ctx->stats.tstamp = jiffies;
64
65 atomic_inc(&nr_spu_contexts);
60 goto out; 66 goto out;
61out_free: 67out_free:
62 kfree(ctx); 68 kfree(ctx);
@@ -76,6 +82,7 @@ void destroy_spu_context(struct kref *kref)
76 if (ctx->gang) 82 if (ctx->gang)
77 spu_gang_remove_ctx(ctx->gang, ctx); 83 spu_gang_remove_ctx(ctx->gang, ctx);
78 BUG_ON(!list_empty(&ctx->rq)); 84 BUG_ON(!list_empty(&ctx->rq));
85 atomic_dec(&nr_spu_contexts);
79 kfree(ctx); 86 kfree(ctx);
80} 87}
81 88
diff --git a/arch/powerpc/platforms/cell/spufs/fault.c b/arch/powerpc/platforms/cell/spufs/fault.c
index 0f75c07e29d8..e064d0c0d80e 100644
--- a/arch/powerpc/platforms/cell/spufs/fault.c
+++ b/arch/powerpc/platforms/cell/spufs/fault.c
@@ -33,7 +33,8 @@
33 * function. Currently, there are a few corner cases that we haven't had 33 * function. Currently, there are a few corner cases that we haven't had
34 * to handle fortunately. 34 * to handle fortunately.
35 */ 35 */
36static int spu_handle_mm_fault(struct mm_struct *mm, unsigned long ea, unsigned long dsisr) 36static int spu_handle_mm_fault(struct mm_struct *mm, unsigned long ea,
37 unsigned long dsisr, unsigned *flt)
37{ 38{
38 struct vm_area_struct *vma; 39 struct vm_area_struct *vma;
39 unsigned long is_write; 40 unsigned long is_write;
@@ -73,7 +74,8 @@ good_area:
73 goto bad_area; 74 goto bad_area;
74 } 75 }
75 ret = 0; 76 ret = 0;
76 switch (handle_mm_fault(mm, vma, ea, is_write)) { 77 *flt = handle_mm_fault(mm, vma, ea, is_write);
78 switch (*flt) {
77 case VM_FAULT_MINOR: 79 case VM_FAULT_MINOR:
78 current->min_flt++; 80 current->min_flt++;
79 break; 81 break;
@@ -153,6 +155,7 @@ int spufs_handle_class1(struct spu_context *ctx)
153{ 155{
154 u64 ea, dsisr, access; 156 u64 ea, dsisr, access;
155 unsigned long flags; 157 unsigned long flags;
158 unsigned flt = 0;
156 int ret; 159 int ret;
157 160
158 /* 161 /*
@@ -178,9 +181,17 @@ int spufs_handle_class1(struct spu_context *ctx)
178 if (!(dsisr & (MFC_DSISR_PTE_NOT_FOUND | MFC_DSISR_ACCESS_DENIED))) 181 if (!(dsisr & (MFC_DSISR_PTE_NOT_FOUND | MFC_DSISR_ACCESS_DENIED)))
179 return 0; 182 return 0;
180 183
184 spuctx_switch_state(ctx, SPUCTX_UTIL_IOWAIT);
185
181 pr_debug("ctx %p: ea %016lx, dsisr %016lx state %d\n", ctx, ea, 186 pr_debug("ctx %p: ea %016lx, dsisr %016lx state %d\n", ctx, ea,
182 dsisr, ctx->state); 187 dsisr, ctx->state);
183 188
189 ctx->stats.hash_flt++;
190 if (ctx->state == SPU_STATE_RUNNABLE) {
191 ctx->spu->stats.hash_flt++;
192 spu_switch_state(ctx->spu, SPU_UTIL_IOWAIT);
193 }
194
184 /* we must not hold the lock when entering spu_handle_mm_fault */ 195 /* we must not hold the lock when entering spu_handle_mm_fault */
185 spu_release(ctx); 196 spu_release(ctx);
186 197
@@ -192,7 +203,7 @@ int spufs_handle_class1(struct spu_context *ctx)
192 203
193 /* hashing failed, so try the actual fault handler */ 204 /* hashing failed, so try the actual fault handler */
194 if (ret) 205 if (ret)
195 ret = spu_handle_mm_fault(current->mm, ea, dsisr); 206 ret = spu_handle_mm_fault(current->mm, ea, dsisr, &flt);
196 207
197 spu_acquire(ctx); 208 spu_acquire(ctx);
198 /* 209 /*
@@ -201,11 +212,23 @@ int spufs_handle_class1(struct spu_context *ctx)
201 * In case of unhandled error report the problem to user space. 212 * In case of unhandled error report the problem to user space.
202 */ 213 */
203 if (!ret) { 214 if (!ret) {
215 if (flt == VM_FAULT_MINOR)
216 ctx->stats.min_flt++;
217 else
218 ctx->stats.maj_flt++;
219 if (ctx->state == SPU_STATE_RUNNABLE) {
220 if (flt == VM_FAULT_MINOR)
221 ctx->spu->stats.min_flt++;
222 else
223 ctx->spu->stats.maj_flt++;
224 }
225
204 if (ctx->spu) 226 if (ctx->spu)
205 ctx->ops->restart_dma(ctx); 227 ctx->ops->restart_dma(ctx);
206 } else 228 } else
207 spufs_handle_dma_error(ctx, ea, SPE_EVENT_SPE_DATA_STORAGE); 229 spufs_handle_dma_error(ctx, ea, SPE_EVENT_SPE_DATA_STORAGE);
208 230
231 spuctx_switch_state(ctx, SPUCTX_UTIL_SYSTEM);
209 return ret; 232 return ret;
210} 233}
211EXPORT_SYMBOL_GPL(spufs_handle_class1); 234EXPORT_SYMBOL_GPL(spufs_handle_class1);
diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c
index b1e7e2f8a2e9..c2814ea96af2 100644
--- a/arch/powerpc/platforms/cell/spufs/file.c
+++ b/arch/powerpc/platforms/cell/spufs/file.c
@@ -28,6 +28,7 @@
28#include <linux/pagemap.h> 28#include <linux/pagemap.h>
29#include <linux/poll.h> 29#include <linux/poll.h>
30#include <linux/ptrace.h> 30#include <linux/ptrace.h>
31#include <linux/seq_file.h>
31 32
32#include <asm/io.h> 33#include <asm/io.h>
33#include <asm/semaphore.h> 34#include <asm/semaphore.h>
@@ -39,6 +40,7 @@
39 40
40#define SPUFS_MMAP_4K (PAGE_SIZE == 0x1000) 41#define SPUFS_MMAP_4K (PAGE_SIZE == 0x1000)
41 42
43
42static int 44static int
43spufs_mem_open(struct inode *inode, struct file *file) 45spufs_mem_open(struct inode *inode, struct file *file)
44{ 46{
@@ -216,12 +218,12 @@ unsigned long spufs_get_unmapped_area(struct file *file, unsigned long addr,
216#endif /* CONFIG_SPU_FS_64K_LS */ 218#endif /* CONFIG_SPU_FS_64K_LS */
217 219
218static const struct file_operations spufs_mem_fops = { 220static const struct file_operations spufs_mem_fops = {
219 .open = spufs_mem_open, 221 .open = spufs_mem_open,
220 .release = spufs_mem_release, 222 .release = spufs_mem_release,
221 .read = spufs_mem_read, 223 .read = spufs_mem_read,
222 .write = spufs_mem_write, 224 .write = spufs_mem_write,
223 .llseek = generic_file_llseek, 225 .llseek = generic_file_llseek,
224 .mmap = spufs_mem_mmap, 226 .mmap = spufs_mem_mmap,
225#ifdef CONFIG_SPU_FS_64K_LS 227#ifdef CONFIG_SPU_FS_64K_LS
226 .get_unmapped_area = spufs_get_unmapped_area, 228 .get_unmapped_area = spufs_get_unmapped_area,
227#endif 229#endif
@@ -1497,14 +1499,15 @@ static ssize_t spufs_mfc_write(struct file *file, const char __user *buffer,
1497 if (status) 1499 if (status)
1498 ret = status; 1500 ret = status;
1499 } 1501 }
1500 spu_release(ctx);
1501 1502
1502 if (ret) 1503 if (ret)
1503 goto out; 1504 goto out_unlock;
1504 1505
1505 ctx->tagwait |= 1 << cmd.tag; 1506 ctx->tagwait |= 1 << cmd.tag;
1506 ret = size; 1507 ret = size;
1507 1508
1509out_unlock:
1510 spu_release(ctx);
1508out: 1511out:
1509 return ret; 1512 return ret;
1510} 1513}
@@ -1515,14 +1518,14 @@ static unsigned int spufs_mfc_poll(struct file *file,poll_table *wait)
1515 u32 free_elements, tagstatus; 1518 u32 free_elements, tagstatus;
1516 unsigned int mask; 1519 unsigned int mask;
1517 1520
1521 poll_wait(file, &ctx->mfc_wq, wait);
1522
1518 spu_acquire(ctx); 1523 spu_acquire(ctx);
1519 ctx->ops->set_mfc_query(ctx, ctx->tagwait, 2); 1524 ctx->ops->set_mfc_query(ctx, ctx->tagwait, 2);
1520 free_elements = ctx->ops->get_mfc_free_elements(ctx); 1525 free_elements = ctx->ops->get_mfc_free_elements(ctx);
1521 tagstatus = ctx->ops->read_mfc_tagstatus(ctx); 1526 tagstatus = ctx->ops->read_mfc_tagstatus(ctx);
1522 spu_release(ctx); 1527 spu_release(ctx);
1523 1528
1524 poll_wait(file, &ctx->mfc_wq, wait);
1525
1526 mask = 0; 1529 mask = 0;
1527 if (free_elements & 0xffff) 1530 if (free_elements & 0xffff)
1528 mask |= POLLOUT | POLLWRNORM; 1531 mask |= POLLOUT | POLLWRNORM;
@@ -1797,6 +1800,29 @@ static int spufs_info_open(struct inode *inode, struct file *file)
1797 return 0; 1800 return 0;
1798} 1801}
1799 1802
1803static int spufs_caps_show(struct seq_file *s, void *private)
1804{
1805 struct spu_context *ctx = s->private;
1806
1807 if (!(ctx->flags & SPU_CREATE_NOSCHED))
1808 seq_puts(s, "sched\n");
1809 if (!(ctx->flags & SPU_CREATE_ISOLATE))
1810 seq_puts(s, "step\n");
1811 return 0;
1812}
1813
1814static int spufs_caps_open(struct inode *inode, struct file *file)
1815{
1816 return single_open(file, spufs_caps_show, SPUFS_I(inode)->i_ctx);
1817}
1818
1819static const struct file_operations spufs_caps_fops = {
1820 .open = spufs_caps_open,
1821 .read = seq_read,
1822 .llseek = seq_lseek,
1823 .release = single_release,
1824};
1825
1800static ssize_t __spufs_mbox_info_read(struct spu_context *ctx, 1826static ssize_t __spufs_mbox_info_read(struct spu_context *ctx,
1801 char __user *buf, size_t len, loff_t *pos) 1827 char __user *buf, size_t len, loff_t *pos)
1802{ 1828{
@@ -2014,7 +2040,105 @@ static const struct file_operations spufs_proxydma_info_fops = {
2014 .read = spufs_proxydma_info_read, 2040 .read = spufs_proxydma_info_read,
2015}; 2041};
2016 2042
2043static int spufs_show_tid(struct seq_file *s, void *private)
2044{
2045 struct spu_context *ctx = s->private;
2046
2047 seq_printf(s, "%d\n", ctx->tid);
2048 return 0;
2049}
2050
2051static int spufs_tid_open(struct inode *inode, struct file *file)
2052{
2053 return single_open(file, spufs_show_tid, SPUFS_I(inode)->i_ctx);
2054}
2055
2056static const struct file_operations spufs_tid_fops = {
2057 .open = spufs_tid_open,
2058 .read = seq_read,
2059 .llseek = seq_lseek,
2060 .release = single_release,
2061};
2062
2063static const char *ctx_state_names[] = {
2064 "user", "system", "iowait", "loaded"
2065};
2066
2067static unsigned long long spufs_acct_time(struct spu_context *ctx,
2068 enum spuctx_execution_state state)
2069{
2070 unsigned long time = ctx->stats.times[state];
2071
2072 if (ctx->stats.execution_state == state)
2073 time += jiffies - ctx->stats.tstamp;
2074
2075 return jiffies_to_msecs(time);
2076}
2077
2078static unsigned long long spufs_slb_flts(struct spu_context *ctx)
2079{
2080 unsigned long long slb_flts = ctx->stats.slb_flt;
2081
2082 if (ctx->state == SPU_STATE_RUNNABLE) {
2083 slb_flts += (ctx->spu->stats.slb_flt -
2084 ctx->stats.slb_flt_base);
2085 }
2086
2087 return slb_flts;
2088}
2089
2090static unsigned long long spufs_class2_intrs(struct spu_context *ctx)
2091{
2092 unsigned long long class2_intrs = ctx->stats.class2_intr;
2093
2094 if (ctx->state == SPU_STATE_RUNNABLE) {
2095 class2_intrs += (ctx->spu->stats.class2_intr -
2096 ctx->stats.class2_intr_base);
2097 }
2098
2099 return class2_intrs;
2100}
2101
2102
2103static int spufs_show_stat(struct seq_file *s, void *private)
2104{
2105 struct spu_context *ctx = s->private;
2106
2107 spu_acquire(ctx);
2108 seq_printf(s, "%s %llu %llu %llu %llu "
2109 "%llu %llu %llu %llu %llu %llu %llu %llu\n",
2110 ctx_state_names[ctx->stats.execution_state],
2111 spufs_acct_time(ctx, SPUCTX_UTIL_USER),
2112 spufs_acct_time(ctx, SPUCTX_UTIL_SYSTEM),
2113 spufs_acct_time(ctx, SPUCTX_UTIL_IOWAIT),
2114 spufs_acct_time(ctx, SPUCTX_UTIL_LOADED),
2115 ctx->stats.vol_ctx_switch,
2116 ctx->stats.invol_ctx_switch,
2117 spufs_slb_flts(ctx),
2118 ctx->stats.hash_flt,
2119 ctx->stats.min_flt,
2120 ctx->stats.maj_flt,
2121 spufs_class2_intrs(ctx),
2122 ctx->stats.libassist);
2123 spu_release(ctx);
2124 return 0;
2125}
2126
2127static int spufs_stat_open(struct inode *inode, struct file *file)
2128{
2129 return single_open(file, spufs_show_stat, SPUFS_I(inode)->i_ctx);
2130}
2131
2132static const struct file_operations spufs_stat_fops = {
2133 .open = spufs_stat_open,
2134 .read = seq_read,
2135 .llseek = seq_lseek,
2136 .release = single_release,
2137};
2138
2139
2017struct tree_descr spufs_dir_contents[] = { 2140struct tree_descr spufs_dir_contents[] = {
2141 { "capabilities", &spufs_caps_fops, 0444, },
2018 { "mem", &spufs_mem_fops, 0666, }, 2142 { "mem", &spufs_mem_fops, 0666, },
2019 { "regs", &spufs_regs_fops, 0666, }, 2143 { "regs", &spufs_regs_fops, 0666, },
2020 { "mbox", &spufs_mbox_fops, 0444, }, 2144 { "mbox", &spufs_mbox_fops, 0444, },
@@ -2046,10 +2170,13 @@ struct tree_descr spufs_dir_contents[] = {
2046 { "wbox_info", &spufs_wbox_info_fops, 0444, }, 2170 { "wbox_info", &spufs_wbox_info_fops, 0444, },
2047 { "dma_info", &spufs_dma_info_fops, 0444, }, 2171 { "dma_info", &spufs_dma_info_fops, 0444, },
2048 { "proxydma_info", &spufs_proxydma_info_fops, 0444, }, 2172 { "proxydma_info", &spufs_proxydma_info_fops, 0444, },
2173 { "tid", &spufs_tid_fops, 0444, },
2174 { "stat", &spufs_stat_fops, 0444, },
2049 {}, 2175 {},
2050}; 2176};
2051 2177
2052struct tree_descr spufs_dir_nosched_contents[] = { 2178struct tree_descr spufs_dir_nosched_contents[] = {
2179 { "capabilities", &spufs_caps_fops, 0444, },
2053 { "mem", &spufs_mem_fops, 0666, }, 2180 { "mem", &spufs_mem_fops, 0666, },
2054 { "mbox", &spufs_mbox_fops, 0444, }, 2181 { "mbox", &spufs_mbox_fops, 0444, },
2055 { "ibox", &spufs_ibox_fops, 0444, }, 2182 { "ibox", &spufs_ibox_fops, 0444, },
@@ -2068,6 +2195,8 @@ struct tree_descr spufs_dir_nosched_contents[] = {
2068 { "psmap", &spufs_psmap_fops, 0666, }, 2195 { "psmap", &spufs_psmap_fops, 0666, },
2069 { "phys-id", &spufs_id_ops, 0666, }, 2196 { "phys-id", &spufs_id_ops, 0666, },
2070 { "object-id", &spufs_object_id_ops, 0666, }, 2197 { "object-id", &spufs_object_id_ops, 0666, },
2198 { "tid", &spufs_tid_fops, 0444, },
2199 { "stat", &spufs_stat_fops, 0444, },
2071 {}, 2200 {},
2072}; 2201};
2073 2202
diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c
index 9807206e0219..f37460e5bfd2 100644
--- a/arch/powerpc/platforms/cell/spufs/inode.c
+++ b/arch/powerpc/platforms/cell/spufs/inode.c
@@ -232,10 +232,6 @@ static int spufs_dir_close(struct inode *inode, struct file *file)
232 return dcache_dir_close(inode, file); 232 return dcache_dir_close(inode, file);
233} 233}
234 234
235const struct inode_operations spufs_dir_inode_operations = {
236 .lookup = simple_lookup,
237};
238
239const struct file_operations spufs_context_fops = { 235const struct file_operations spufs_context_fops = {
240 .open = dcache_dir_open, 236 .open = dcache_dir_open,
241 .release = spufs_dir_close, 237 .release = spufs_dir_close,
@@ -269,7 +265,7 @@ spufs_mkdir(struct inode *dir, struct dentry *dentry, unsigned int flags,
269 goto out_iput; 265 goto out_iput;
270 266
271 ctx->flags = flags; 267 ctx->flags = flags;
272 inode->i_op = &spufs_dir_inode_operations; 268 inode->i_op = &simple_dir_inode_operations;
273 inode->i_fop = &simple_dir_operations; 269 inode->i_fop = &simple_dir_operations;
274 if (flags & SPU_CREATE_NOSCHED) 270 if (flags & SPU_CREATE_NOSCHED)
275 ret = spufs_fill_dir(dentry, spufs_dir_nosched_contents, 271 ret = spufs_fill_dir(dentry, spufs_dir_nosched_contents,
@@ -386,7 +382,7 @@ spufs_mkgang(struct inode *dir, struct dentry *dentry, int mode)
386 if (!gang) 382 if (!gang)
387 goto out_iput; 383 goto out_iput;
388 384
389 inode->i_op = &spufs_dir_inode_operations; 385 inode->i_op = &simple_dir_inode_operations;
390 inode->i_fop = &simple_dir_operations; 386 inode->i_fop = &simple_dir_operations;
391 387
392 d_instantiate(dentry, inode); 388 d_instantiate(dentry, inode);
@@ -593,7 +589,7 @@ spufs_create_root(struct super_block *sb, void *data)
593 if (!inode) 589 if (!inode)
594 goto out; 590 goto out;
595 591
596 inode->i_op = &spufs_dir_inode_operations; 592 inode->i_op = &simple_dir_inode_operations;
597 inode->i_fop = &simple_dir_operations; 593 inode->i_fop = &simple_dir_operations;
598 SPUFS_I(inode)->i_ctx = NULL; 594 SPUFS_I(inode)->i_ctx = NULL;
599 595
diff --git a/arch/powerpc/platforms/cell/spufs/run.c b/arch/powerpc/platforms/cell/spufs/run.c
index 57626600b1a4..58ae13b7de84 100644
--- a/arch/powerpc/platforms/cell/spufs/run.c
+++ b/arch/powerpc/platforms/cell/spufs/run.c
@@ -29,7 +29,8 @@ static inline int spu_stopped(struct spu_context *ctx, u32 * stat)
29 spu = ctx->spu; 29 spu = ctx->spu;
30 pte_fault = spu->dsisr & 30 pte_fault = spu->dsisr &
31 (MFC_DSISR_PTE_NOT_FOUND | MFC_DSISR_ACCESS_DENIED); 31 (MFC_DSISR_PTE_NOT_FOUND | MFC_DSISR_ACCESS_DENIED);
32 return (!(*stat & 0x1) || pte_fault || spu->class_0_pending) ? 1 : 0; 32 return (!(*stat & SPU_STATUS_RUNNING) || pte_fault || spu->class_0_pending) ?
33 1 : 0;
33} 34}
34 35
35static int spu_setup_isolated(struct spu_context *ctx) 36static int spu_setup_isolated(struct spu_context *ctx)
@@ -142,8 +143,11 @@ static int spu_run_init(struct spu_context *ctx, u32 * npc)
142 runcntl = SPU_RUNCNTL_RUNNABLE; 143 runcntl = SPU_RUNCNTL_RUNNABLE;
143 ctx->ops->runcntl_write(ctx, runcntl); 144 ctx->ops->runcntl_write(ctx, runcntl);
144 } else { 145 } else {
145 spu_start_tick(ctx); 146 unsigned long mode = SPU_PRIVCNTL_MODE_NORMAL;
146 ctx->ops->npc_write(ctx, *npc); 147 ctx->ops->npc_write(ctx, *npc);
148 if (test_thread_flag(TIF_SINGLESTEP))
149 mode = SPU_PRIVCNTL_MODE_SINGLE_STEP;
150 out_be64(&ctx->spu->priv2->spu_privcntl_RW, mode);
147 ctx->ops->runcntl_write(ctx, SPU_RUNCNTL_RUNNABLE); 151 ctx->ops->runcntl_write(ctx, SPU_RUNCNTL_RUNNABLE);
148 } 152 }
149 153
@@ -155,7 +159,6 @@ static int spu_run_fini(struct spu_context *ctx, u32 * npc,
155{ 159{
156 int ret = 0; 160 int ret = 0;
157 161
158 spu_stop_tick(ctx);
159 *status = ctx->ops->status_read(ctx); 162 *status = ctx->ops->status_read(ctx);
160 *npc = ctx->ops->npc_read(ctx); 163 *npc = ctx->ops->npc_read(ctx);
161 spu_release(ctx); 164 spu_release(ctx);
@@ -298,9 +301,22 @@ long spufs_run_spu(struct file *file, struct spu_context *ctx,
298 ctx->ops->master_start(ctx); 301 ctx->ops->master_start(ctx);
299 ctx->event_return = 0; 302 ctx->event_return = 0;
300 303
301 ret = spu_acquire_runnable(ctx, 0); 304 spu_acquire(ctx);
302 if (ret) 305 if (ctx->state == SPU_STATE_SAVED) {
303 return ret; 306 __spu_update_sched_info(ctx);
307
308 ret = spu_activate(ctx, 0);
309 if (ret) {
310 spu_release(ctx);
311 goto out;
312 }
313 } else {
314 /*
315 * We have to update the scheduling priority under active_mutex
316 * to protect against find_victim().
317 */
318 spu_update_sched_info(ctx);
319 }
304 320
305 ret = spu_run_init(ctx, npc); 321 ret = spu_run_init(ctx, npc);
306 if (ret) { 322 if (ret) {
@@ -325,16 +341,20 @@ long spufs_run_spu(struct file *file, struct spu_context *ctx,
325 341
326 if (unlikely(ctx->state != SPU_STATE_RUNNABLE)) { 342 if (unlikely(ctx->state != SPU_STATE_RUNNABLE)) {
327 ret = spu_reacquire_runnable(ctx, npc, &status); 343 ret = spu_reacquire_runnable(ctx, npc, &status);
328 if (ret) { 344 if (ret)
329 spu_stop_tick(ctx);
330 goto out2; 345 goto out2;
331 }
332 continue; 346 continue;
333 } 347 }
334 ret = spu_process_events(ctx); 348 ret = spu_process_events(ctx);
335 349
336 } while (!ret && !(status & (SPU_STATUS_STOPPED_BY_STOP | 350 } while (!ret && !(status & (SPU_STATUS_STOPPED_BY_STOP |
337 SPU_STATUS_STOPPED_BY_HALT))); 351 SPU_STATUS_STOPPED_BY_HALT |
352 SPU_STATUS_SINGLE_STEP)));
353
354 if ((status & SPU_STATUS_STOPPED_BY_STOP) &&
355 (((status >> SPU_STOP_STATUS_SHIFT) & 0x3f00) == 0x2100) &&
356 (ctx->state == SPU_STATE_RUNNABLE))
357 ctx->stats.libassist++;
338 358
339 ctx->ops->master_stop(ctx); 359 ctx->ops->master_stop(ctx);
340 ret = spu_run_fini(ctx, npc, &status); 360 ret = spu_run_fini(ctx, npc, &status);
@@ -344,10 +364,15 @@ out2:
344 if ((ret == 0) || 364 if ((ret == 0) ||
345 ((ret == -ERESTARTSYS) && 365 ((ret == -ERESTARTSYS) &&
346 ((status & SPU_STATUS_STOPPED_BY_HALT) || 366 ((status & SPU_STATUS_STOPPED_BY_HALT) ||
367 (status & SPU_STATUS_SINGLE_STEP) ||
347 ((status & SPU_STATUS_STOPPED_BY_STOP) && 368 ((status & SPU_STATUS_STOPPED_BY_STOP) &&
348 (status >> SPU_STOP_STATUS_SHIFT != 0x2104))))) 369 (status >> SPU_STOP_STATUS_SHIFT != 0x2104)))))
349 ret = status; 370 ret = status;
350 371
372 /* Note: we don't need to force_sig SIGTRAP on single-step
373 * since we have TIF_SINGLESTEP set, thus the kernel will do
374 * it upon return from the syscall anyawy
375 */
351 if ((status & SPU_STATUS_STOPPED_BY_STOP) 376 if ((status & SPU_STATUS_STOPPED_BY_STOP)
352 && (status >> SPU_STOP_STATUS_SHIFT) == 0x3fff) { 377 && (status >> SPU_STOP_STATUS_SHIFT) == 0x3fff) {
353 force_sig(SIGTRAP, current); 378 force_sig(SIGTRAP, current);
diff --git a/arch/powerpc/platforms/cell/spufs/sched.c b/arch/powerpc/platforms/cell/spufs/sched.c
index 3b831e07f1ed..e5b4dd1db286 100644
--- a/arch/powerpc/platforms/cell/spufs/sched.c
+++ b/arch/powerpc/platforms/cell/spufs/sched.c
@@ -35,6 +35,10 @@
35#include <linux/numa.h> 35#include <linux/numa.h>
36#include <linux/mutex.h> 36#include <linux/mutex.h>
37#include <linux/notifier.h> 37#include <linux/notifier.h>
38#include <linux/kthread.h>
39#include <linux/pid_namespace.h>
40#include <linux/proc_fs.h>
41#include <linux/seq_file.h>
38 42
39#include <asm/io.h> 43#include <asm/io.h>
40#include <asm/mmu_context.h> 44#include <asm/mmu_context.h>
@@ -43,54 +47,126 @@
43#include <asm/spu_priv1.h> 47#include <asm/spu_priv1.h>
44#include "spufs.h" 48#include "spufs.h"
45 49
46#define SPU_TIMESLICE (HZ)
47
48struct spu_prio_array { 50struct spu_prio_array {
49 DECLARE_BITMAP(bitmap, MAX_PRIO); 51 DECLARE_BITMAP(bitmap, MAX_PRIO);
50 struct list_head runq[MAX_PRIO]; 52 struct list_head runq[MAX_PRIO];
51 spinlock_t runq_lock; 53 spinlock_t runq_lock;
52 struct list_head active_list[MAX_NUMNODES]; 54 struct list_head active_list[MAX_NUMNODES];
53 struct mutex active_mutex[MAX_NUMNODES]; 55 struct mutex active_mutex[MAX_NUMNODES];
56 int nr_active[MAX_NUMNODES];
57 int nr_waiting;
54}; 58};
55 59
60static unsigned long spu_avenrun[3];
56static struct spu_prio_array *spu_prio; 61static struct spu_prio_array *spu_prio;
57static struct workqueue_struct *spu_sched_wq; 62static struct task_struct *spusched_task;
63static struct timer_list spusched_timer;
64
65/*
66 * Priority of a normal, non-rt, non-niced'd process (aka nice level 0).
67 */
68#define NORMAL_PRIO 120
69
70/*
71 * Frequency of the spu scheduler tick. By default we do one SPU scheduler
72 * tick for every 10 CPU scheduler ticks.
73 */
74#define SPUSCHED_TICK (10)
58 75
59static inline int node_allowed(int node) 76/*
77 * These are the 'tuning knobs' of the scheduler:
78 *
79 * Minimum timeslice is 5 msecs (or 1 spu scheduler tick, whichever is
80 * larger), default timeslice is 100 msecs, maximum timeslice is 800 msecs.
81 */
82#define MIN_SPU_TIMESLICE max(5 * HZ / (1000 * SPUSCHED_TICK), 1)
83#define DEF_SPU_TIMESLICE (100 * HZ / (1000 * SPUSCHED_TICK))
84
85#define MAX_USER_PRIO (MAX_PRIO - MAX_RT_PRIO)
86#define SCALE_PRIO(x, prio) \
87 max(x * (MAX_PRIO - prio) / (MAX_USER_PRIO / 2), MIN_SPU_TIMESLICE)
88
89/*
90 * scale user-nice values [ -20 ... 0 ... 19 ] to time slice values:
91 * [800ms ... 100ms ... 5ms]
92 *
93 * The higher a thread's priority, the bigger timeslices
94 * it gets during one round of execution. But even the lowest
95 * priority thread gets MIN_TIMESLICE worth of execution time.
96 */
97void spu_set_timeslice(struct spu_context *ctx)
60{ 98{
61 cpumask_t mask; 99 if (ctx->prio < NORMAL_PRIO)
100 ctx->time_slice = SCALE_PRIO(DEF_SPU_TIMESLICE * 4, ctx->prio);
101 else
102 ctx->time_slice = SCALE_PRIO(DEF_SPU_TIMESLICE, ctx->prio);
103}
62 104
63 if (!nr_cpus_node(node)) 105/*
64 return 0; 106 * Update scheduling information from the owning thread.
65 mask = node_to_cpumask(node); 107 */
66 if (!cpus_intersects(mask, current->cpus_allowed)) 108void __spu_update_sched_info(struct spu_context *ctx)
67 return 0; 109{
68 return 1; 110 /*
111 * 32-Bit assignment are atomic on powerpc, and we don't care about
112 * memory ordering here because retriving the controlling thread is
113 * per defintion racy.
114 */
115 ctx->tid = current->pid;
116
117 /*
118 * We do our own priority calculations, so we normally want
119 * ->static_prio to start with. Unfortunately thies field
120 * contains junk for threads with a realtime scheduling
121 * policy so we have to look at ->prio in this case.
122 */
123 if (rt_prio(current->prio))
124 ctx->prio = current->prio;
125 else
126 ctx->prio = current->static_prio;
127 ctx->policy = current->policy;
128
129 /*
130 * A lot of places that don't hold active_mutex poke into
131 * cpus_allowed, including grab_runnable_context which
132 * already holds the runq_lock. So abuse runq_lock
133 * to protect this field aswell.
134 */
135 spin_lock(&spu_prio->runq_lock);
136 ctx->cpus_allowed = current->cpus_allowed;
137 spin_unlock(&spu_prio->runq_lock);
69} 138}
70 139
71void spu_start_tick(struct spu_context *ctx) 140void spu_update_sched_info(struct spu_context *ctx)
72{ 141{
73 if (ctx->policy == SCHED_RR) { 142 int node = ctx->spu->node;
74 /* 143
75 * Make sure the exiting bit is cleared. 144 mutex_lock(&spu_prio->active_mutex[node]);
76 */ 145 __spu_update_sched_info(ctx);
77 clear_bit(SPU_SCHED_EXITING, &ctx->sched_flags); 146 mutex_unlock(&spu_prio->active_mutex[node]);
78 mb();
79 queue_delayed_work(spu_sched_wq, &ctx->sched_work, SPU_TIMESLICE);
80 }
81} 147}
82 148
83void spu_stop_tick(struct spu_context *ctx) 149static int __node_allowed(struct spu_context *ctx, int node)
84{ 150{
85 if (ctx->policy == SCHED_RR) { 151 if (nr_cpus_node(node)) {
86 /* 152 cpumask_t mask = node_to_cpumask(node);
87 * While the work can be rearming normally setting this flag 153
88 * makes sure it does not rearm itself anymore. 154 if (cpus_intersects(mask, ctx->cpus_allowed))
89 */ 155 return 1;
90 set_bit(SPU_SCHED_EXITING, &ctx->sched_flags);
91 mb();
92 cancel_delayed_work(&ctx->sched_work);
93 } 156 }
157
158 return 0;
159}
160
161static int node_allowed(struct spu_context *ctx, int node)
162{
163 int rval;
164
165 spin_lock(&spu_prio->runq_lock);
166 rval = __node_allowed(ctx, node);
167 spin_unlock(&spu_prio->runq_lock);
168
169 return rval;
94} 170}
95 171
96/** 172/**
@@ -99,9 +175,18 @@ void spu_stop_tick(struct spu_context *ctx)
99 */ 175 */
100static void spu_add_to_active_list(struct spu *spu) 176static void spu_add_to_active_list(struct spu *spu)
101{ 177{
102 mutex_lock(&spu_prio->active_mutex[spu->node]); 178 int node = spu->node;
103 list_add_tail(&spu->list, &spu_prio->active_list[spu->node]); 179
104 mutex_unlock(&spu_prio->active_mutex[spu->node]); 180 mutex_lock(&spu_prio->active_mutex[node]);
181 spu_prio->nr_active[node]++;
182 list_add_tail(&spu->list, &spu_prio->active_list[node]);
183 mutex_unlock(&spu_prio->active_mutex[node]);
184}
185
186static void __spu_remove_from_active_list(struct spu *spu)
187{
188 list_del_init(&spu->list);
189 spu_prio->nr_active[spu->node]--;
105} 190}
106 191
107/** 192/**
@@ -113,7 +198,7 @@ static void spu_remove_from_active_list(struct spu *spu)
113 int node = spu->node; 198 int node = spu->node;
114 199
115 mutex_lock(&spu_prio->active_mutex[node]); 200 mutex_lock(&spu_prio->active_mutex[node]);
116 list_del_init(&spu->list); 201 __spu_remove_from_active_list(spu);
117 mutex_unlock(&spu_prio->active_mutex[node]); 202 mutex_unlock(&spu_prio->active_mutex[node]);
118} 203}
119 204
@@ -144,6 +229,10 @@ static void spu_bind_context(struct spu *spu, struct spu_context *ctx)
144{ 229{
145 pr_debug("%s: pid=%d SPU=%d NODE=%d\n", __FUNCTION__, current->pid, 230 pr_debug("%s: pid=%d SPU=%d NODE=%d\n", __FUNCTION__, current->pid,
146 spu->number, spu->node); 231 spu->number, spu->node);
232
233 ctx->stats.slb_flt_base = spu->stats.slb_flt;
234 ctx->stats.class2_intr_base = spu->stats.class2_intr;
235
147 spu->ctx = ctx; 236 spu->ctx = ctx;
148 spu->flags = 0; 237 spu->flags = 0;
149 ctx->spu = spu; 238 ctx->spu = spu;
@@ -161,8 +250,8 @@ static void spu_bind_context(struct spu *spu, struct spu_context *ctx)
161 spu->timestamp = jiffies; 250 spu->timestamp = jiffies;
162 spu_cpu_affinity_set(spu, raw_smp_processor_id()); 251 spu_cpu_affinity_set(spu, raw_smp_processor_id());
163 spu_switch_notify(spu, ctx); 252 spu_switch_notify(spu, ctx);
164 spu_add_to_active_list(spu);
165 ctx->state = SPU_STATE_RUNNABLE; 253 ctx->state = SPU_STATE_RUNNABLE;
254 spu_switch_state(spu, SPU_UTIL_SYSTEM);
166} 255}
167 256
168/** 257/**
@@ -175,7 +264,8 @@ static void spu_unbind_context(struct spu *spu, struct spu_context *ctx)
175 pr_debug("%s: unbind pid=%d SPU=%d NODE=%d\n", __FUNCTION__, 264 pr_debug("%s: unbind pid=%d SPU=%d NODE=%d\n", __FUNCTION__,
176 spu->pid, spu->number, spu->node); 265 spu->pid, spu->number, spu->node);
177 266
178 spu_remove_from_active_list(spu); 267 spu_switch_state(spu, SPU_UTIL_IDLE);
268
179 spu_switch_notify(spu, NULL); 269 spu_switch_notify(spu, NULL);
180 spu_unmap_mappings(ctx); 270 spu_unmap_mappings(ctx);
181 spu_save(&ctx->csa, spu); 271 spu_save(&ctx->csa, spu);
@@ -192,6 +282,11 @@ static void spu_unbind_context(struct spu *spu, struct spu_context *ctx)
192 ctx->spu = NULL; 282 ctx->spu = NULL;
193 spu->flags = 0; 283 spu->flags = 0;
194 spu->ctx = NULL; 284 spu->ctx = NULL;
285
286 ctx->stats.slb_flt +=
287 (spu->stats.slb_flt - ctx->stats.slb_flt_base);
288 ctx->stats.class2_intr +=
289 (spu->stats.class2_intr - ctx->stats.class2_intr_base);
195} 290}
196 291
197/** 292/**
@@ -200,20 +295,39 @@ static void spu_unbind_context(struct spu *spu, struct spu_context *ctx)
200 */ 295 */
201static void __spu_add_to_rq(struct spu_context *ctx) 296static void __spu_add_to_rq(struct spu_context *ctx)
202{ 297{
203 int prio = ctx->prio; 298 /*
204 299 * Unfortunately this code path can be called from multiple threads
205 list_add_tail(&ctx->rq, &spu_prio->runq[prio]); 300 * on behalf of a single context due to the way the problem state
206 set_bit(prio, spu_prio->bitmap); 301 * mmap support works.
302 *
303 * Fortunately we need to wake up all these threads at the same time
304 * and can simply skip the runqueue addition for every but the first
305 * thread getting into this codepath.
306 *
307 * It's still quite hacky, and long-term we should proxy all other
308 * threads through the owner thread so that spu_run is in control
309 * of all the scheduling activity for a given context.
310 */
311 if (list_empty(&ctx->rq)) {
312 list_add_tail(&ctx->rq, &spu_prio->runq[ctx->prio]);
313 set_bit(ctx->prio, spu_prio->bitmap);
314 if (!spu_prio->nr_waiting++)
315 __mod_timer(&spusched_timer, jiffies + SPUSCHED_TICK);
316 }
207} 317}
208 318
209static void __spu_del_from_rq(struct spu_context *ctx) 319static void __spu_del_from_rq(struct spu_context *ctx)
210{ 320{
211 int prio = ctx->prio; 321 int prio = ctx->prio;
212 322
213 if (!list_empty(&ctx->rq)) 323 if (!list_empty(&ctx->rq)) {
324 if (!--spu_prio->nr_waiting)
325 del_timer(&spusched_timer);
214 list_del_init(&ctx->rq); 326 list_del_init(&ctx->rq);
215 if (list_empty(&spu_prio->runq[prio])) 327
216 clear_bit(prio, spu_prio->bitmap); 328 if (list_empty(&spu_prio->runq[prio]))
329 clear_bit(prio, spu_prio->bitmap);
330 }
217} 331}
218 332
219static void spu_prio_wait(struct spu_context *ctx) 333static void spu_prio_wait(struct spu_context *ctx)
@@ -244,7 +358,7 @@ static struct spu *spu_get_idle(struct spu_context *ctx)
244 358
245 for (n = 0; n < MAX_NUMNODES; n++, node++) { 359 for (n = 0; n < MAX_NUMNODES; n++, node++) {
246 node = (node < MAX_NUMNODES) ? node : 0; 360 node = (node < MAX_NUMNODES) ? node : 0;
247 if (!node_allowed(node)) 361 if (!node_allowed(ctx, node))
248 continue; 362 continue;
249 spu = spu_alloc_node(node); 363 spu = spu_alloc_node(node);
250 if (spu) 364 if (spu)
@@ -276,15 +390,15 @@ static struct spu *find_victim(struct spu_context *ctx)
276 node = cpu_to_node(raw_smp_processor_id()); 390 node = cpu_to_node(raw_smp_processor_id());
277 for (n = 0; n < MAX_NUMNODES; n++, node++) { 391 for (n = 0; n < MAX_NUMNODES; n++, node++) {
278 node = (node < MAX_NUMNODES) ? node : 0; 392 node = (node < MAX_NUMNODES) ? node : 0;
279 if (!node_allowed(node)) 393 if (!node_allowed(ctx, node))
280 continue; 394 continue;
281 395
282 mutex_lock(&spu_prio->active_mutex[node]); 396 mutex_lock(&spu_prio->active_mutex[node]);
283 list_for_each_entry(spu, &spu_prio->active_list[node], list) { 397 list_for_each_entry(spu, &spu_prio->active_list[node], list) {
284 struct spu_context *tmp = spu->ctx; 398 struct spu_context *tmp = spu->ctx;
285 399
286 if (tmp->rt_priority < ctx->rt_priority && 400 if (tmp->prio > ctx->prio &&
287 (!victim || tmp->rt_priority < victim->rt_priority)) 401 (!victim || tmp->prio > victim->prio))
288 victim = spu->ctx; 402 victim = spu->ctx;
289 } 403 }
290 mutex_unlock(&spu_prio->active_mutex[node]); 404 mutex_unlock(&spu_prio->active_mutex[node]);
@@ -312,7 +426,10 @@ static struct spu *find_victim(struct spu_context *ctx)
312 victim = NULL; 426 victim = NULL;
313 goto restart; 427 goto restart;
314 } 428 }
429 spu_remove_from_active_list(spu);
315 spu_unbind_context(spu, victim); 430 spu_unbind_context(spu, victim);
431 victim->stats.invol_ctx_switch++;
432 spu->stats.invol_ctx_switch++;
316 mutex_unlock(&victim->state_mutex); 433 mutex_unlock(&victim->state_mutex);
317 /* 434 /*
318 * We need to break out of the wait loop in spu_run 435 * We need to break out of the wait loop in spu_run
@@ -338,22 +455,30 @@ static struct spu *find_victim(struct spu_context *ctx)
338 */ 455 */
339int spu_activate(struct spu_context *ctx, unsigned long flags) 456int spu_activate(struct spu_context *ctx, unsigned long flags)
340{ 457{
341 458 spuctx_switch_state(ctx, SPUCTX_UTIL_SYSTEM);
342 if (ctx->spu)
343 return 0;
344 459
345 do { 460 do {
346 struct spu *spu; 461 struct spu *spu;
347 462
463 /*
464 * If there are multiple threads waiting for a single context
465 * only one actually binds the context while the others will
466 * only be able to acquire the state_mutex once the context
467 * already is in runnable state.
468 */
469 if (ctx->spu)
470 return 0;
471
348 spu = spu_get_idle(ctx); 472 spu = spu_get_idle(ctx);
349 /* 473 /*
350 * If this is a realtime thread we try to get it running by 474 * If this is a realtime thread we try to get it running by
351 * preempting a lower priority thread. 475 * preempting a lower priority thread.
352 */ 476 */
353 if (!spu && ctx->rt_priority) 477 if (!spu && rt_prio(ctx->prio))
354 spu = find_victim(ctx); 478 spu = find_victim(ctx);
355 if (spu) { 479 if (spu) {
356 spu_bind_context(spu, ctx); 480 spu_bind_context(spu, ctx);
481 spu_add_to_active_list(spu);
357 return 0; 482 return 0;
358 } 483 }
359 484
@@ -369,23 +494,28 @@ int spu_activate(struct spu_context *ctx, unsigned long flags)
369 * Remove the highest priority context on the runqueue and return it 494 * Remove the highest priority context on the runqueue and return it
370 * to the caller. Returns %NULL if no runnable context was found. 495 * to the caller. Returns %NULL if no runnable context was found.
371 */ 496 */
372static struct spu_context *grab_runnable_context(int prio) 497static struct spu_context *grab_runnable_context(int prio, int node)
373{ 498{
374 struct spu_context *ctx = NULL; 499 struct spu_context *ctx;
375 int best; 500 int best;
376 501
377 spin_lock(&spu_prio->runq_lock); 502 spin_lock(&spu_prio->runq_lock);
378 best = sched_find_first_bit(spu_prio->bitmap); 503 best = sched_find_first_bit(spu_prio->bitmap);
379 if (best < prio) { 504 while (best < prio) {
380 struct list_head *rq = &spu_prio->runq[best]; 505 struct list_head *rq = &spu_prio->runq[best];
381 506
382 BUG_ON(list_empty(rq)); 507 list_for_each_entry(ctx, rq, rq) {
383 508 /* XXX(hch): check for affinity here aswell */
384 ctx = list_entry(rq->next, struct spu_context, rq); 509 if (__node_allowed(ctx, node)) {
385 __spu_del_from_rq(ctx); 510 __spu_del_from_rq(ctx);
511 goto found;
512 }
513 }
514 best++;
386 } 515 }
516 ctx = NULL;
517 found:
387 spin_unlock(&spu_prio->runq_lock); 518 spin_unlock(&spu_prio->runq_lock);
388
389 return ctx; 519 return ctx;
390} 520}
391 521
@@ -395,9 +525,12 @@ static int __spu_deactivate(struct spu_context *ctx, int force, int max_prio)
395 struct spu_context *new = NULL; 525 struct spu_context *new = NULL;
396 526
397 if (spu) { 527 if (spu) {
398 new = grab_runnable_context(max_prio); 528 new = grab_runnable_context(max_prio, spu->node);
399 if (new || force) { 529 if (new || force) {
530 spu_remove_from_active_list(spu);
400 spu_unbind_context(spu, ctx); 531 spu_unbind_context(spu, ctx);
532 ctx->stats.vol_ctx_switch++;
533 spu->stats.vol_ctx_switch++;
401 spu_free(spu); 534 spu_free(spu);
402 if (new) 535 if (new)
403 wake_up(&new->stop_wq); 536 wake_up(&new->stop_wq);
@@ -417,7 +550,17 @@ static int __spu_deactivate(struct spu_context *ctx, int force, int max_prio)
417 */ 550 */
418void spu_deactivate(struct spu_context *ctx) 551void spu_deactivate(struct spu_context *ctx)
419{ 552{
553 /*
554 * We must never reach this for a nosched context,
555 * but handle the case gracefull instead of panicing.
556 */
557 if (ctx->flags & SPU_CREATE_NOSCHED) {
558 WARN_ON(1);
559 return;
560 }
561
420 __spu_deactivate(ctx, 1, MAX_PRIO); 562 __spu_deactivate(ctx, 1, MAX_PRIO);
563 spuctx_switch_state(ctx, SPUCTX_UTIL_USER);
421} 564}
422 565
423/** 566/**
@@ -432,56 +575,178 @@ void spu_yield(struct spu_context *ctx)
432{ 575{
433 if (!(ctx->flags & SPU_CREATE_NOSCHED)) { 576 if (!(ctx->flags & SPU_CREATE_NOSCHED)) {
434 mutex_lock(&ctx->state_mutex); 577 mutex_lock(&ctx->state_mutex);
435 __spu_deactivate(ctx, 0, MAX_PRIO); 578 if (__spu_deactivate(ctx, 0, MAX_PRIO))
579 spuctx_switch_state(ctx, SPUCTX_UTIL_USER);
580 else {
581 spuctx_switch_state(ctx, SPUCTX_UTIL_LOADED);
582 spu_switch_state(ctx->spu, SPU_UTIL_USER);
583 }
436 mutex_unlock(&ctx->state_mutex); 584 mutex_unlock(&ctx->state_mutex);
437 } 585 }
438} 586}
439 587
440void spu_sched_tick(struct work_struct *work) 588static void spusched_tick(struct spu_context *ctx)
441{ 589{
442 struct spu_context *ctx = 590 if (ctx->flags & SPU_CREATE_NOSCHED)
443 container_of(work, struct spu_context, sched_work.work); 591 return;
444 int preempted; 592 if (ctx->policy == SCHED_FIFO)
593 return;
594
595 if (--ctx->time_slice)
596 return;
445 597
446 /* 598 /*
447 * If this context is being stopped avoid rescheduling from the 599 * Unfortunately active_mutex ranks outside of state_mutex, so
448 * scheduler tick because we would block on the state_mutex. 600 * we have to trylock here. If we fail give the context another
449 * The caller will yield the spu later on anyway. 601 * tick and try again.
450 */ 602 */
451 if (test_bit(SPU_SCHED_EXITING, &ctx->sched_flags)) 603 if (mutex_trylock(&ctx->state_mutex)) {
452 return; 604 struct spu *spu = ctx->spu;
605 struct spu_context *new;
453 606
454 mutex_lock(&ctx->state_mutex); 607 new = grab_runnable_context(ctx->prio + 1, spu->node);
455 preempted = __spu_deactivate(ctx, 0, ctx->prio + 1); 608 if (new) {
456 mutex_unlock(&ctx->state_mutex);
457 609
458 if (preempted) { 610 __spu_remove_from_active_list(spu);
459 /* 611 spu_unbind_context(spu, ctx);
460 * We need to break out of the wait loop in spu_run manually 612 ctx->stats.invol_ctx_switch++;
461 * to ensure this context gets put on the runqueue again 613 spu->stats.invol_ctx_switch++;
462 * ASAP. 614 spu_free(spu);
463 */ 615 wake_up(&new->stop_wq);
464 wake_up(&ctx->stop_wq); 616 /*
617 * We need to break out of the wait loop in
618 * spu_run manually to ensure this context
619 * gets put on the runqueue again ASAP.
620 */
621 wake_up(&ctx->stop_wq);
622 }
623 spu_set_timeslice(ctx);
624 mutex_unlock(&ctx->state_mutex);
465 } else { 625 } else {
466 spu_start_tick(ctx); 626 ctx->time_slice++;
467 } 627 }
468} 628}
469 629
470int __init spu_sched_init(void) 630/**
631 * count_active_contexts - count nr of active tasks
632 *
633 * Return the number of tasks currently running or waiting to run.
634 *
635 * Note that we don't take runq_lock / active_mutex here. Reading
636 * a single 32bit value is atomic on powerpc, and we don't care
637 * about memory ordering issues here.
638 */
639static unsigned long count_active_contexts(void)
471{ 640{
472 int i; 641 int nr_active = 0, node;
473 642
474 spu_sched_wq = create_singlethread_workqueue("spusched"); 643 for (node = 0; node < MAX_NUMNODES; node++)
475 if (!spu_sched_wq) 644 nr_active += spu_prio->nr_active[node];
476 return 1; 645 nr_active += spu_prio->nr_waiting;
477 646
478 spu_prio = kzalloc(sizeof(struct spu_prio_array), GFP_KERNEL); 647 return nr_active;
479 if (!spu_prio) { 648}
480 printk(KERN_WARNING "%s: Unable to allocate priority queue.\n", 649
481 __FUNCTION__); 650/**
482 destroy_workqueue(spu_sched_wq); 651 * spu_calc_load - given tick count, update the avenrun load estimates.
483 return 1; 652 * @tick: tick count
653 *
654 * No locking against reading these values from userspace, as for
655 * the CPU loadavg code.
656 */
657static void spu_calc_load(unsigned long ticks)
658{
659 unsigned long active_tasks; /* fixed-point */
660 static int count = LOAD_FREQ;
661
662 count -= ticks;
663
664 if (unlikely(count < 0)) {
665 active_tasks = count_active_contexts() * FIXED_1;
666 do {
667 CALC_LOAD(spu_avenrun[0], EXP_1, active_tasks);
668 CALC_LOAD(spu_avenrun[1], EXP_5, active_tasks);
669 CALC_LOAD(spu_avenrun[2], EXP_15, active_tasks);
670 count += LOAD_FREQ;
671 } while (count < 0);
484 } 672 }
673}
674
675static void spusched_wake(unsigned long data)
676{
677 mod_timer(&spusched_timer, jiffies + SPUSCHED_TICK);
678 wake_up_process(spusched_task);
679 spu_calc_load(SPUSCHED_TICK);
680}
681
682static int spusched_thread(void *unused)
683{
684 struct spu *spu, *next;
685 int node;
686
687 while (!kthread_should_stop()) {
688 set_current_state(TASK_INTERRUPTIBLE);
689 schedule();
690 for (node = 0; node < MAX_NUMNODES; node++) {
691 mutex_lock(&spu_prio->active_mutex[node]);
692 list_for_each_entry_safe(spu, next,
693 &spu_prio->active_list[node],
694 list)
695 spusched_tick(spu->ctx);
696 mutex_unlock(&spu_prio->active_mutex[node]);
697 }
698 }
699
700 return 0;
701}
702
703#define LOAD_INT(x) ((x) >> FSHIFT)
704#define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1-1)) * 100)
705
706static int show_spu_loadavg(struct seq_file *s, void *private)
707{
708 int a, b, c;
709
710 a = spu_avenrun[0] + (FIXED_1/200);
711 b = spu_avenrun[1] + (FIXED_1/200);
712 c = spu_avenrun[2] + (FIXED_1/200);
713
714 /*
715 * Note that last_pid doesn't really make much sense for the
716 * SPU loadavg (it even seems very odd on the CPU side..),
717 * but we include it here to have a 100% compatible interface.
718 */
719 seq_printf(s, "%d.%02d %d.%02d %d.%02d %ld/%d %d\n",
720 LOAD_INT(a), LOAD_FRAC(a),
721 LOAD_INT(b), LOAD_FRAC(b),
722 LOAD_INT(c), LOAD_FRAC(c),
723 count_active_contexts(),
724 atomic_read(&nr_spu_contexts),
725 current->nsproxy->pid_ns->last_pid);
726 return 0;
727}
728
729static int spu_loadavg_open(struct inode *inode, struct file *file)
730{
731 return single_open(file, show_spu_loadavg, NULL);
732}
733
734static const struct file_operations spu_loadavg_fops = {
735 .open = spu_loadavg_open,
736 .read = seq_read,
737 .llseek = seq_lseek,
738 .release = single_release,
739};
740
741int __init spu_sched_init(void)
742{
743 struct proc_dir_entry *entry;
744 int err = -ENOMEM, i;
745
746 spu_prio = kzalloc(sizeof(struct spu_prio_array), GFP_KERNEL);
747 if (!spu_prio)
748 goto out;
749
485 for (i = 0; i < MAX_PRIO; i++) { 750 for (i = 0; i < MAX_PRIO; i++) {
486 INIT_LIST_HEAD(&spu_prio->runq[i]); 751 INIT_LIST_HEAD(&spu_prio->runq[i]);
487 __clear_bit(i, spu_prio->bitmap); 752 __clear_bit(i, spu_prio->bitmap);
@@ -492,7 +757,30 @@ int __init spu_sched_init(void)
492 INIT_LIST_HEAD(&spu_prio->active_list[i]); 757 INIT_LIST_HEAD(&spu_prio->active_list[i]);
493 } 758 }
494 spin_lock_init(&spu_prio->runq_lock); 759 spin_lock_init(&spu_prio->runq_lock);
760
761 setup_timer(&spusched_timer, spusched_wake, 0);
762
763 spusched_task = kthread_run(spusched_thread, NULL, "spusched");
764 if (IS_ERR(spusched_task)) {
765 err = PTR_ERR(spusched_task);
766 goto out_free_spu_prio;
767 }
768
769 entry = create_proc_entry("spu_loadavg", 0, NULL);
770 if (!entry)
771 goto out_stop_kthread;
772 entry->proc_fops = &spu_loadavg_fops;
773
774 pr_debug("spusched: tick: %d, min ticks: %d, default ticks: %d\n",
775 SPUSCHED_TICK, MIN_SPU_TIMESLICE, DEF_SPU_TIMESLICE);
495 return 0; 776 return 0;
777
778 out_stop_kthread:
779 kthread_stop(spusched_task);
780 out_free_spu_prio:
781 kfree(spu_prio);
782 out:
783 return err;
496} 784}
497 785
498void __exit spu_sched_exit(void) 786void __exit spu_sched_exit(void)
@@ -500,6 +788,11 @@ void __exit spu_sched_exit(void)
500 struct spu *spu, *tmp; 788 struct spu *spu, *tmp;
501 int node; 789 int node;
502 790
791 remove_proc_entry("spu_loadavg", NULL);
792
793 del_timer_sync(&spusched_timer);
794 kthread_stop(spusched_task);
795
503 for (node = 0; node < MAX_NUMNODES; node++) { 796 for (node = 0; node < MAX_NUMNODES; node++) {
504 mutex_lock(&spu_prio->active_mutex[node]); 797 mutex_lock(&spu_prio->active_mutex[node]);
505 list_for_each_entry_safe(spu, tmp, &spu_prio->active_list[node], 798 list_for_each_entry_safe(spu, tmp, &spu_prio->active_list[node],
@@ -510,5 +803,4 @@ void __exit spu_sched_exit(void)
510 mutex_unlock(&spu_prio->active_mutex[node]); 803 mutex_unlock(&spu_prio->active_mutex[node]);
511 } 804 }
512 kfree(spu_prio); 805 kfree(spu_prio);
513 destroy_workqueue(spu_sched_wq);
514} 806}
diff --git a/arch/powerpc/platforms/cell/spufs/spu_restore.c b/arch/powerpc/platforms/cell/spufs/spu_restore.c
index 0bf723dcd677..4e19ed7a0756 100644
--- a/arch/powerpc/platforms/cell/spufs/spu_restore.c
+++ b/arch/powerpc/platforms/cell/spufs/spu_restore.c
@@ -296,7 +296,7 @@ static inline void restore_complete(void)
296 * This code deviates from the documented sequence in the 296 * This code deviates from the documented sequence in the
297 * following aspects: 297 * following aspects:
298 * 298 *
299 * 1. The EA for LSCSA is passed from PPE in the 299 * 1. The EA for LSCSA is passed from PPE in the
300 * signal notification channels. 300 * signal notification channels.
301 * 2. The register spill area is pulled by SPU 301 * 2. The register spill area is pulled by SPU
302 * into LS, rather than pushed by PPE. 302 * into LS, rather than pushed by PPE.
diff --git a/arch/powerpc/platforms/cell/spufs/spu_save.c b/arch/powerpc/platforms/cell/spufs/spu_save.c
index 196033b8a579..ae95cc1701e9 100644
--- a/arch/powerpc/platforms/cell/spufs/spu_save.c
+++ b/arch/powerpc/platforms/cell/spufs/spu_save.c
@@ -44,7 +44,7 @@ static inline void save_event_mask(void)
44 * Read the SPU_RdEventMsk channel and save to the LSCSA. 44 * Read the SPU_RdEventMsk channel and save to the LSCSA.
45 */ 45 */
46 offset = LSCSA_QW_OFFSET(event_mask); 46 offset = LSCSA_QW_OFFSET(event_mask);
47 regs_spill[offset].slot[0] = spu_readch(SPU_RdEventStatMask); 47 regs_spill[offset].slot[0] = spu_readch(SPU_RdEventMask);
48} 48}
49 49
50static inline void save_tag_mask(void) 50static inline void save_tag_mask(void)
diff --git a/arch/powerpc/platforms/cell/spufs/spufs.h b/arch/powerpc/platforms/cell/spufs/spufs.h
index 47617e8014a5..08b3530288ac 100644
--- a/arch/powerpc/platforms/cell/spufs/spufs.h
+++ b/arch/powerpc/platforms/cell/spufs/spufs.h
@@ -26,6 +26,7 @@
26#include <linux/mutex.h> 26#include <linux/mutex.h>
27#include <linux/spinlock.h> 27#include <linux/spinlock.h>
28#include <linux/fs.h> 28#include <linux/fs.h>
29#include <linux/cpumask.h>
29 30
30#include <asm/spu.h> 31#include <asm/spu.h>
31#include <asm/spu_csa.h> 32#include <asm/spu_csa.h>
@@ -39,9 +40,17 @@ enum {
39struct spu_context_ops; 40struct spu_context_ops;
40struct spu_gang; 41struct spu_gang;
41 42
42/* ctx->sched_flags */ 43/*
43enum { 44 * This is the state for spu utilization reporting to userspace.
44 SPU_SCHED_EXITING = 0, 45 * Because this state is visible to userspace it must never change and needs
46 * to be kept strictly separate from any internal state kept by the kernel.
47 */
48enum spuctx_execution_state {
49 SPUCTX_UTIL_USER = 0,
50 SPUCTX_UTIL_SYSTEM,
51 SPUCTX_UTIL_IOWAIT,
52 SPUCTX_UTIL_LOADED,
53 SPUCTX_UTIL_MAX
45}; 54};
46 55
47struct spu_context { 56struct spu_context {
@@ -81,13 +90,34 @@ struct spu_context {
81 struct list_head gang_list; 90 struct list_head gang_list;
82 struct spu_gang *gang; 91 struct spu_gang *gang;
83 92
93 /* owner thread */
94 pid_t tid;
95
84 /* scheduler fields */ 96 /* scheduler fields */
85 struct list_head rq; 97 struct list_head rq;
86 struct delayed_work sched_work; 98 unsigned int time_slice;
87 unsigned long sched_flags; 99 unsigned long sched_flags;
88 unsigned long rt_priority; 100 cpumask_t cpus_allowed;
89 int policy; 101 int policy;
90 int prio; 102 int prio;
103
104 /* statistics */
105 struct {
106 /* updates protected by ctx->state_mutex */
107 enum spuctx_execution_state execution_state;
108 unsigned long tstamp; /* time of last ctx switch */
109 unsigned long times[SPUCTX_UTIL_MAX];
110 unsigned long long vol_ctx_switch;
111 unsigned long long invol_ctx_switch;
112 unsigned long long min_flt;
113 unsigned long long maj_flt;
114 unsigned long long hash_flt;
115 unsigned long long slb_flt;
116 unsigned long long slb_flt_base; /* # at last ctx switch */
117 unsigned long long class2_intr;
118 unsigned long long class2_intr_base; /* # at last ctx switch */
119 unsigned long long libassist;
120 } stats;
91}; 121};
92 122
93struct spu_gang { 123struct spu_gang {
@@ -177,6 +207,7 @@ void spu_gang_add_ctx(struct spu_gang *gang, struct spu_context *ctx);
177int spufs_handle_class1(struct spu_context *ctx); 207int spufs_handle_class1(struct spu_context *ctx);
178 208
179/* context management */ 209/* context management */
210extern atomic_t nr_spu_contexts;
180static inline void spu_acquire(struct spu_context *ctx) 211static inline void spu_acquire(struct spu_context *ctx)
181{ 212{
182 mutex_lock(&ctx->state_mutex); 213 mutex_lock(&ctx->state_mutex);
@@ -200,9 +231,9 @@ void spu_acquire_saved(struct spu_context *ctx);
200int spu_activate(struct spu_context *ctx, unsigned long flags); 231int spu_activate(struct spu_context *ctx, unsigned long flags);
201void spu_deactivate(struct spu_context *ctx); 232void spu_deactivate(struct spu_context *ctx);
202void spu_yield(struct spu_context *ctx); 233void spu_yield(struct spu_context *ctx);
203void spu_start_tick(struct spu_context *ctx); 234void spu_set_timeslice(struct spu_context *ctx);
204void spu_stop_tick(struct spu_context *ctx); 235void spu_update_sched_info(struct spu_context *ctx);
205void spu_sched_tick(struct work_struct *work); 236void __spu_update_sched_info(struct spu_context *ctx);
206int __init spu_sched_init(void); 237int __init spu_sched_init(void);
207void __exit spu_sched_exit(void); 238void __exit spu_sched_exit(void);
208 239
@@ -210,7 +241,7 @@ extern char *isolated_loader;
210 241
211/* 242/*
212 * spufs_wait 243 * spufs_wait
213 * Same as wait_event_interruptible(), except that here 244 * Same as wait_event_interruptible(), except that here
214 * we need to call spu_release(ctx) before sleeping, and 245 * we need to call spu_release(ctx) before sleeping, and
215 * then spu_acquire(ctx) when awoken. 246 * then spu_acquire(ctx) when awoken.
216 */ 247 */
@@ -256,4 +287,37 @@ struct spufs_coredump_reader {
256extern struct spufs_coredump_reader spufs_coredump_read[]; 287extern struct spufs_coredump_reader spufs_coredump_read[];
257extern int spufs_coredump_num_notes; 288extern int spufs_coredump_num_notes;
258 289
290/*
291 * This function is a little bit too large for an inline, but
292 * as fault.c is built into the kernel we can't move it out of
293 * line.
294 */
295static inline void spuctx_switch_state(struct spu_context *ctx,
296 enum spuctx_execution_state new_state)
297{
298 WARN_ON(!mutex_is_locked(&ctx->state_mutex));
299
300 if (ctx->stats.execution_state != new_state) {
301 unsigned long curtime = jiffies;
302
303 ctx->stats.times[ctx->stats.execution_state] +=
304 curtime - ctx->stats.tstamp;
305 ctx->stats.tstamp = curtime;
306 ctx->stats.execution_state = new_state;
307 }
308}
309
310static inline void spu_switch_state(struct spu *spu,
311 enum spuctx_execution_state new_state)
312{
313 if (spu->stats.utilization_state != new_state) {
314 unsigned long curtime = jiffies;
315
316 spu->stats.times[spu->stats.utilization_state] +=
317 curtime - spu->stats.tstamp;
318 spu->stats.tstamp = curtime;
319 spu->stats.utilization_state = new_state;
320 }
321}
322
259#endif 323#endif
diff --git a/arch/powerpc/platforms/cell/spufs/switch.c b/arch/powerpc/platforms/cell/spufs/switch.c
index 71a0b41adb8c..9c506ba08cdc 100644
--- a/arch/powerpc/platforms/cell/spufs/switch.c
+++ b/arch/powerpc/platforms/cell/spufs/switch.c
@@ -70,7 +70,7 @@
70 } 70 }
71#endif /* debug */ 71#endif /* debug */
72 72
73#define POLL_WHILE_FALSE(_c) POLL_WHILE_TRUE(!(_c)) 73#define POLL_WHILE_FALSE(_c) POLL_WHILE_TRUE(!(_c))
74 74
75static inline void acquire_spu_lock(struct spu *spu) 75static inline void acquire_spu_lock(struct spu *spu)
76{ 76{
@@ -387,6 +387,19 @@ static inline void save_ppu_querytype(struct spu_state *csa, struct spu *spu)
387 csa->prob.dma_querytype_RW = in_be32(&prob->dma_querytype_RW); 387 csa->prob.dma_querytype_RW = in_be32(&prob->dma_querytype_RW);
388} 388}
389 389
390static inline void save_ppu_tagstatus(struct spu_state *csa, struct spu *spu)
391{
392 struct spu_problem __iomem *prob = spu->problem;
393
394 /* Save the Prxy_TagStatus register in the CSA.
395 *
396 * It is unnecessary to restore dma_tagstatus_R, however,
397 * dma_tagstatus_R in the CSA is accessed via backing_ops, so
398 * we must save it.
399 */
400 csa->prob.dma_tagstatus_R = in_be32(&prob->dma_tagstatus_R);
401}
402
390static inline void save_mfc_csr_tsq(struct spu_state *csa, struct spu *spu) 403static inline void save_mfc_csr_tsq(struct spu_state *csa, struct spu *spu)
391{ 404{
392 struct spu_priv2 __iomem *priv2 = spu->priv2; 405 struct spu_priv2 __iomem *priv2 = spu->priv2;
@@ -1812,6 +1825,7 @@ static void save_csa(struct spu_state *prev, struct spu *spu)
1812 save_mfc_queues(prev, spu); /* Step 19. */ 1825 save_mfc_queues(prev, spu); /* Step 19. */
1813 save_ppu_querymask(prev, spu); /* Step 20. */ 1826 save_ppu_querymask(prev, spu); /* Step 20. */
1814 save_ppu_querytype(prev, spu); /* Step 21. */ 1827 save_ppu_querytype(prev, spu); /* Step 21. */
1828 save_ppu_tagstatus(prev, spu); /* NEW. */
1815 save_mfc_csr_tsq(prev, spu); /* Step 22. */ 1829 save_mfc_csr_tsq(prev, spu); /* Step 22. */
1816 save_mfc_csr_cmd(prev, spu); /* Step 23. */ 1830 save_mfc_csr_cmd(prev, spu); /* Step 23. */
1817 save_mfc_csr_ato(prev, spu); /* Step 24. */ 1831 save_mfc_csr_ato(prev, spu); /* Step 24. */
@@ -1930,7 +1944,7 @@ static void harvest(struct spu_state *prev, struct spu *spu)
1930 reset_spu_privcntl(prev, spu); /* Step 16. */ 1944 reset_spu_privcntl(prev, spu); /* Step 16. */
1931 reset_spu_lslr(prev, spu); /* Step 17. */ 1945 reset_spu_lslr(prev, spu); /* Step 17. */
1932 setup_mfc_sr1(prev, spu); /* Step 18. */ 1946 setup_mfc_sr1(prev, spu); /* Step 18. */
1933 spu_invalidate_slbs(spu); /* Step 19. */ 1947 spu_invalidate_slbs(spu); /* Step 19. */
1934 reset_ch_part1(prev, spu); /* Step 20. */ 1948 reset_ch_part1(prev, spu); /* Step 20. */
1935 reset_ch_part2(prev, spu); /* Step 21. */ 1949 reset_ch_part2(prev, spu); /* Step 21. */
1936 enable_interrupts(prev, spu); /* Step 22. */ 1950 enable_interrupts(prev, spu); /* Step 22. */
diff --git a/arch/powerpc/platforms/chrp/Kconfig b/arch/powerpc/platforms/chrp/Kconfig
index d2c690531963..22b4b4e3b6f0 100644
--- a/arch/powerpc/platforms/chrp/Kconfig
+++ b/arch/powerpc/platforms/chrp/Kconfig
@@ -8,4 +8,5 @@ config PPC_CHRP
8 select PPC_MPC106 8 select PPC_MPC106
9 select PPC_UDBG_16550 9 select PPC_UDBG_16550
10 select PPC_NATIVE 10 select PPC_NATIVE
11 select PCI
11 default y 12 default y
diff --git a/arch/powerpc/platforms/chrp/Makefile b/arch/powerpc/platforms/chrp/Makefile
index 902feb1ac431..4b3bfadc70fa 100644
--- a/arch/powerpc/platforms/chrp/Makefile
+++ b/arch/powerpc/platforms/chrp/Makefile
@@ -1,4 +1,3 @@
1obj-y += setup.o time.o pegasos_eth.o 1obj-y += setup.o time.o pegasos_eth.o pci.o
2obj-$(CONFIG_PCI) += pci.o
3obj-$(CONFIG_SMP) += smp.o 2obj-$(CONFIG_SMP) += smp.o
4obj-$(CONFIG_NVRAM) += nvram.o 3obj-$(CONFIG_NVRAM) += nvram.o
diff --git a/arch/powerpc/platforms/chrp/pci.c b/arch/powerpc/platforms/chrp/pci.c
index d32fedc991d3..3690624e49d4 100644
--- a/arch/powerpc/platforms/chrp/pci.c
+++ b/arch/powerpc/platforms/chrp/pci.c
@@ -99,7 +99,7 @@ int rtas_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
99 struct pci_controller *hose = bus->sysdata; 99 struct pci_controller *hose = bus->sysdata;
100 unsigned long addr = (offset & 0xff) | ((devfn & 0xff) << 8) 100 unsigned long addr = (offset & 0xff) | ((devfn & 0xff) << 8)
101 | (((bus->number - hose->first_busno) & 0xff) << 16) 101 | (((bus->number - hose->first_busno) & 0xff) << 16)
102 | (hose->index << 24); 102 | (hose->global_number << 24);
103 int ret = -1; 103 int ret = -1;
104 int rval; 104 int rval;
105 105
@@ -114,7 +114,7 @@ int rtas_write_config(struct pci_bus *bus, unsigned int devfn, int offset,
114 struct pci_controller *hose = bus->sysdata; 114 struct pci_controller *hose = bus->sysdata;
115 unsigned long addr = (offset & 0xff) | ((devfn & 0xff) << 8) 115 unsigned long addr = (offset & 0xff) | ((devfn & 0xff) << 8)
116 | (((bus->number - hose->first_busno) & 0xff) << 16) 116 | (((bus->number - hose->first_busno) & 0xff) << 16)
117 | (hose->index << 24); 117 | (hose->global_number << 24);
118 int rval; 118 int rval;
119 119
120 rval = rtas_call(rtas_token("write-pci-config"), 3, 1, NULL, 120 rval = rtas_call(rtas_token("write-pci-config"), 3, 1, NULL,
@@ -254,13 +254,12 @@ chrp_find_bridges(void)
254 printk(" at %llx", (unsigned long long)r.start); 254 printk(" at %llx", (unsigned long long)r.start);
255 printk("\n"); 255 printk("\n");
256 256
257 hose = pcibios_alloc_controller(); 257 hose = pcibios_alloc_controller(dev);
258 if (!hose) { 258 if (!hose) {
259 printk("Can't allocate PCI controller structure for %s\n", 259 printk("Can't allocate PCI controller structure for %s\n",
260 dev->full_name); 260 dev->full_name);
261 continue; 261 continue;
262 } 262 }
263 hose->arch_data = dev;
264 hose->first_busno = bus_range[0]; 263 hose->first_busno = bus_range[0];
265 hose->last_busno = bus_range[1]; 264 hose->last_busno = bus_range[1];
266 265
diff --git a/arch/powerpc/platforms/embedded6xx/Kconfig b/arch/powerpc/platforms/embedded6xx/Kconfig
index f2d26268ca6f..bec772674e40 100644
--- a/arch/powerpc/platforms/embedded6xx/Kconfig
+++ b/arch/powerpc/platforms/embedded6xx/Kconfig
@@ -28,6 +28,7 @@ config PPC_HOLLY
28 bool "PPC750GX/CL with TSI10x bridge (Hickory/Holly)" 28 bool "PPC750GX/CL with TSI10x bridge (Hickory/Holly)"
29 select TSI108_BRIDGE 29 select TSI108_BRIDGE
30 select PPC_UDBG_16550 30 select PPC_UDBG_16550
31 select WANT_DEVICE_TREE
31 help 32 help
32 Select PPC_HOLLY if configuring for an IBM 750GX/CL Eval 33 Select PPC_HOLLY if configuring for an IBM 750GX/CL Eval
33 Board with TSI108/9 bridge (Hickory/Holly) 34 Board with TSI108/9 bridge (Hickory/Holly)
@@ -44,6 +45,7 @@ endchoice
44config TSI108_BRIDGE 45config TSI108_BRIDGE
45 bool 46 bool
46 depends on MPC7448HPC2 || PPC_HOLLY 47 depends on MPC7448HPC2 || PPC_HOLLY
48 select PCI
47 select MPIC 49 select MPIC
48 select MPIC_WEIRD 50 select MPIC_WEIRD
49 default y 51 default y
diff --git a/arch/powerpc/platforms/embedded6xx/holly.c b/arch/powerpc/platforms/embedded6xx/holly.c
index 3a0b4a01401c..6292e36dc577 100644
--- a/arch/powerpc/platforms/embedded6xx/holly.c
+++ b/arch/powerpc/platforms/embedded6xx/holly.c
@@ -45,7 +45,7 @@
45 45
46#define HOLLY_PCI_CFG_PHYS 0x7c000000 46#define HOLLY_PCI_CFG_PHYS 0x7c000000
47 47
48int holly_exclude_device(u_char bus, u_char devfn) 48int holly_exclude_device(struct pci_controller *hose, u_char bus, u_char devfn)
49{ 49{
50 if (bus == 0 && PCI_SLOT(devfn) == 0) 50 if (bus == 0 && PCI_SLOT(devfn) == 0)
51 return PCIBIOS_DEVICE_NOT_FOUND; 51 return PCIBIOS_DEVICE_NOT_FOUND;
diff --git a/arch/powerpc/platforms/embedded6xx/linkstation.c b/arch/powerpc/platforms/embedded6xx/linkstation.c
index b412f006a9c5..f4d0a7a603f5 100644
--- a/arch/powerpc/platforms/embedded6xx/linkstation.c
+++ b/arch/powerpc/platforms/embedded6xx/linkstation.c
@@ -54,8 +54,9 @@ static struct mtd_partition linkstation_physmap_partitions[] = {
54 }, 54 },
55}; 55};
56 56
57static int __init add_bridge(struct device_node *dev) 57static int __init linkstation_add_bridge(struct device_node *dev)
58{ 58{
59#ifdef CONFIG_PCI
59 int len; 60 int len;
60 struct pci_controller *hose; 61 struct pci_controller *hose;
61 const int *bus_range; 62 const int *bus_range;
@@ -67,18 +68,17 @@ static int __init add_bridge(struct device_node *dev)
67 printk(KERN_WARNING "Can't get bus-range for %s, assume" 68 printk(KERN_WARNING "Can't get bus-range for %s, assume"
68 " bus 0\n", dev->full_name); 69 " bus 0\n", dev->full_name);
69 70
70 hose = pcibios_alloc_controller(); 71 hose = pcibios_alloc_controller(dev);
71 if (hose == NULL) 72 if (hose == NULL)
72 return -ENOMEM; 73 return -ENOMEM;
73 hose->first_busno = bus_range ? bus_range[0] : 0; 74 hose->first_busno = bus_range ? bus_range[0] : 0;
74 hose->last_busno = bus_range ? bus_range[1] : 0xff; 75 hose->last_busno = bus_range ? bus_range[1] : 0xff;
75 hose->arch_data = dev;
76 setup_indirect_pci(hose, 0xfec00000, 0xfee00000); 76 setup_indirect_pci(hose, 0xfec00000, 0xfee00000);
77 77
78 /* Interpret the "ranges" property */ 78 /* Interpret the "ranges" property */
79 /* This also maps the I/O region and sets isa_io/mem_base */ 79 /* This also maps the I/O region and sets isa_io/mem_base */
80 pci_process_bridge_OF_ranges(hose, dev, 1); 80 pci_process_bridge_OF_ranges(hose, dev, 1);
81 81#endif
82 return 0; 82 return 0;
83} 83}
84 84
@@ -92,7 +92,7 @@ static void __init linkstation_setup_arch(void)
92 92
93 /* Lookup PCI host bridges */ 93 /* Lookup PCI host bridges */
94 for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;) 94 for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
95 add_bridge(np); 95 linkstation_add_bridge(np);
96 96
97 printk(KERN_INFO "BUFFALO Network Attached Storage Series\n"); 97 printk(KERN_INFO "BUFFALO Network Attached Storage Series\n");
98 printk(KERN_INFO "(C) 2002-2005 BUFFALO INC.\n"); 98 printk(KERN_INFO "(C) 2002-2005 BUFFALO INC.\n");
diff --git a/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c b/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c
index 4542e0c837c0..1e3cc69487b5 100644
--- a/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c
+++ b/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c
@@ -54,15 +54,10 @@
54 54
55#define MPC7448HPC2_PCI_CFG_PHYS 0xfb000000 55#define MPC7448HPC2_PCI_CFG_PHYS 0xfb000000
56 56
57#ifndef CONFIG_PCI
58isa_io_base = MPC7448_HPC2_ISA_IO_BASE;
59isa_mem_base = MPC7448_HPC2_ISA_MEM_BASE;
60pci_dram_offset = MPC7448_HPC2_PCI_MEM_OFFSET;
61#endif
62
63extern void _nmask_and_or_msr(unsigned long nmask, unsigned long or_val); 57extern void _nmask_and_or_msr(unsigned long nmask, unsigned long or_val);
64 58
65int mpc7448_hpc2_exclude_device(u_char bus, u_char devfn) 59int mpc7448_hpc2_exclude_device(struct pci_controller *hose,
60 u_char bus, u_char devfn)
66{ 61{
67 if (bus == 0 && PCI_SLOT(devfn) == 0) 62 if (bus == 0 && PCI_SLOT(devfn) == 0)
68 return PCIBIOS_DEVICE_NOT_FOUND; 63 return PCIBIOS_DEVICE_NOT_FOUND;
diff --git a/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.h b/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.h
index a543a5242e34..f7e0e0c7f8d8 100644
--- a/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.h
+++ b/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.h
@@ -18,9 +18,4 @@
18 18
19#include <asm/ppcboot.h> 19#include <asm/ppcboot.h>
20 20
21/* Base Addresses for the PCI bus
22 */
23#define MPC7448_HPC2_PCI_MEM_OFFSET (0x00000000)
24#define MPC7448_HPC2_ISA_IO_BASE (0x00000000)
25#define MPC7448_HPC2_ISA_MEM_BASE (0x00000000)
26#endif /* __PPC_PLATFORMS_MPC7448_HPC2_H */ 21#endif /* __PPC_PLATFORMS_MPC7448_HPC2_H */
diff --git a/arch/powerpc/platforms/iseries/call_hpt.h b/arch/powerpc/platforms/iseries/call_hpt.h
index a843b0f87b72..8d95fe4b554e 100644
--- a/arch/powerpc/platforms/iseries/call_hpt.h
+++ b/arch/powerpc/platforms/iseries/call_hpt.h
@@ -76,24 +76,25 @@ static inline u64 HvCallHpt_invalidateSetSwBitsGet(u32 hpteIndex, u8 bitson,
76 return compressedStatus; 76 return compressedStatus;
77} 77}
78 78
79static inline u64 HvCallHpt_findValid(hpte_t *hpte, u64 vpn) 79static inline u64 HvCallHpt_findValid(struct hash_pte *hpte, u64 vpn)
80{ 80{
81 return HvCall3Ret16(HvCallHptFindValid, hpte, vpn, 0, 0); 81 return HvCall3Ret16(HvCallHptFindValid, hpte, vpn, 0, 0);
82} 82}
83 83
84static inline u64 HvCallHpt_findNextValid(hpte_t *hpte, u32 hpteIndex, 84static inline u64 HvCallHpt_findNextValid(struct hash_pte *hpte, u32 hpteIndex,
85 u8 bitson, u8 bitsoff) 85 u8 bitson, u8 bitsoff)
86{ 86{
87 return HvCall3Ret16(HvCallHptFindNextValid, hpte, hpteIndex, 87 return HvCall3Ret16(HvCallHptFindNextValid, hpte, hpteIndex,
88 bitson, bitsoff); 88 bitson, bitsoff);
89} 89}
90 90
91static inline void HvCallHpt_get(hpte_t *hpte, u32 hpteIndex) 91static inline void HvCallHpt_get(struct hash_pte *hpte, u32 hpteIndex)
92{ 92{
93 HvCall2Ret16(HvCallHptGet, hpte, hpteIndex, 0); 93 HvCall2Ret16(HvCallHptGet, hpte, hpteIndex, 0);
94} 94}
95 95
96static inline void HvCallHpt_addValidate(u32 hpteIndex, u32 hBit, hpte_t *hpte) 96static inline void HvCallHpt_addValidate(u32 hpteIndex, u32 hBit,
97 struct hash_pte *hpte)
97{ 98{
98 HvCall4(HvCallHptAddValidate, hpteIndex, hBit, hpte->v, hpte->r); 99 HvCall4(HvCallHptAddValidate, hpteIndex, hBit, hpte->v, hpte->r);
99} 100}
diff --git a/arch/powerpc/platforms/iseries/htab.c b/arch/powerpc/platforms/iseries/htab.c
index ed44dfceaa45..b4e2c7a038e1 100644
--- a/arch/powerpc/platforms/iseries/htab.c
+++ b/arch/powerpc/platforms/iseries/htab.c
@@ -44,7 +44,7 @@ long iSeries_hpte_insert(unsigned long hpte_group, unsigned long va,
44 unsigned long vflags, int psize) 44 unsigned long vflags, int psize)
45{ 45{
46 long slot; 46 long slot;
47 hpte_t lhpte; 47 struct hash_pte lhpte;
48 int secondary = 0; 48 int secondary = 0;
49 49
50 BUG_ON(psize != MMU_PAGE_4K); 50 BUG_ON(psize != MMU_PAGE_4K);
@@ -99,7 +99,7 @@ long iSeries_hpte_insert(unsigned long hpte_group, unsigned long va,
99 99
100static unsigned long iSeries_hpte_getword0(unsigned long slot) 100static unsigned long iSeries_hpte_getword0(unsigned long slot)
101{ 101{
102 hpte_t hpte; 102 struct hash_pte hpte;
103 103
104 HvCallHpt_get(&hpte, slot); 104 HvCallHpt_get(&hpte, slot);
105 return hpte.v; 105 return hpte.v;
@@ -144,7 +144,7 @@ static long iSeries_hpte_remove(unsigned long hpte_group)
144static long iSeries_hpte_updatepp(unsigned long slot, unsigned long newpp, 144static long iSeries_hpte_updatepp(unsigned long slot, unsigned long newpp,
145 unsigned long va, int psize, int local) 145 unsigned long va, int psize, int local)
146{ 146{
147 hpte_t hpte; 147 struct hash_pte hpte;
148 unsigned long want_v; 148 unsigned long want_v;
149 149
150 iSeries_hlock(slot); 150 iSeries_hlock(slot);
@@ -176,7 +176,7 @@ static long iSeries_hpte_updatepp(unsigned long slot, unsigned long newpp,
176 */ 176 */
177static long iSeries_hpte_find(unsigned long vpn) 177static long iSeries_hpte_find(unsigned long vpn)
178{ 178{
179 hpte_t hpte; 179 struct hash_pte hpte;
180 long slot; 180 long slot;
181 181
182 /* 182 /*
diff --git a/arch/powerpc/platforms/iseries/pci.c b/arch/powerpc/platforms/iseries/pci.c
index 9c974227155e..da87162000f0 100644
--- a/arch/powerpc/platforms/iseries/pci.c
+++ b/arch/powerpc/platforms/iseries/pci.c
@@ -742,6 +742,11 @@ void __init iSeries_pcibios_init(void)
742 /* Install IO hooks */ 742 /* Install IO hooks */
743 ppc_pci_io = iseries_pci_io; 743 ppc_pci_io = iseries_pci_io;
744 744
745 /* iSeries has no IO space in the common sense, it needs to set
746 * the IO base to 0
747 */
748 pci_io_base = 0;
749
745 if (root == NULL) { 750 if (root == NULL) {
746 printk(KERN_CRIT "iSeries_pcibios_init: can't find root " 751 printk(KERN_CRIT "iSeries_pcibios_init: can't find root "
747 "of device tree\n"); 752 "of device tree\n");
@@ -763,7 +768,7 @@ void __init iSeries_pcibios_init(void)
763 if (phb == NULL) 768 if (phb == NULL)
764 continue; 769 continue;
765 770
766 phb->pci_mem_offset = phb->local_number = bus; 771 phb->pci_mem_offset = bus;
767 phb->first_busno = bus; 772 phb->first_busno = bus;
768 phb->last_busno = bus; 773 phb->last_busno = bus;
769 phb->ops = &iSeries_pci_ops; 774 phb->ops = &iSeries_pci_ops;
diff --git a/arch/powerpc/platforms/iseries/setup.c b/arch/powerpc/platforms/iseries/setup.c
index 7f5dcee814d4..13a8b1908ded 100644
--- a/arch/powerpc/platforms/iseries/setup.c
+++ b/arch/powerpc/platforms/iseries/setup.c
@@ -79,8 +79,6 @@ extern void iSeries_pci_final_fixup(void);
79static void iSeries_pci_final_fixup(void) { } 79static void iSeries_pci_final_fixup(void) { }
80#endif 80#endif
81 81
82extern unsigned long iSeries_recal_tb;
83extern unsigned long iSeries_recal_titan;
84 82
85struct MemoryBlock { 83struct MemoryBlock {
86 unsigned long absStart; 84 unsigned long absStart;
@@ -292,8 +290,8 @@ static void __init iSeries_init_early(void)
292{ 290{
293 DBG(" -> iSeries_init_early()\n"); 291 DBG(" -> iSeries_init_early()\n");
294 292
295 iSeries_recal_tb = get_tb(); 293 /* Snapshot the timebase, for use in later recalibration */
296 iSeries_recal_titan = HvCallXm_loadTod(); 294 iSeries_time_init_early();
297 295
298 /* 296 /*
299 * Initialize the DMA/TCE management 297 * Initialize the DMA/TCE management
diff --git a/arch/powerpc/platforms/maple/pci.c b/arch/powerpc/platforms/maple/pci.c
index 7aaa5bbc9363..fceaae40fe70 100644
--- a/arch/powerpc/platforms/maple/pci.c
+++ b/arch/powerpc/platforms/maple/pci.c
@@ -444,7 +444,7 @@ static void __init setup_u3_ht(struct pci_controller* hose)
444 u3_ht = hose; 444 u3_ht = hose;
445} 445}
446 446
447static int __init add_bridge(struct device_node *dev) 447static int __init maple_add_bridge(struct device_node *dev)
448{ 448{
449 int len; 449 int len;
450 struct pci_controller *hose; 450 struct pci_controller *hose;
@@ -519,23 +519,6 @@ void __devinit maple_pci_irq_fixup(struct pci_dev *dev)
519 DBG(" <- maple_pci_irq_fixup\n"); 519 DBG(" <- maple_pci_irq_fixup\n");
520} 520}
521 521
522static void __init maple_fixup_phb_resources(void)
523{
524 struct pci_controller *hose, *tmp;
525
526 list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
527 unsigned long offset = (unsigned long)hose->io_base_virt - pci_io_base;
528
529 hose->io_resource.start += offset;
530 hose->io_resource.end += offset;
531
532 printk(KERN_INFO "PCI Host %d, io start: %llx; io end: %llx\n",
533 hose->global_number,
534 (unsigned long long)hose->io_resource.start,
535 (unsigned long long)hose->io_resource.end);
536 }
537}
538
539void __init maple_pci_init(void) 522void __init maple_pci_init(void)
540{ 523{
541 struct device_node *np, *root; 524 struct device_node *np, *root;
@@ -558,7 +541,7 @@ void __init maple_pci_init(void)
558 continue; 541 continue;
559 if ((of_device_is_compatible(np, "u4-pcie") || 542 if ((of_device_is_compatible(np, "u4-pcie") ||
560 of_device_is_compatible(np, "u3-agp")) && 543 of_device_is_compatible(np, "u3-agp")) &&
561 add_bridge(np) == 0) 544 maple_add_bridge(np) == 0)
562 of_node_get(np); 545 of_node_get(np);
563 546
564 if (of_device_is_compatible(np, "u3-ht")) { 547 if (of_device_is_compatible(np, "u3-ht")) {
@@ -570,27 +553,9 @@ void __init maple_pci_init(void)
570 553
571 /* Now setup the HyperTransport host if we found any 554 /* Now setup the HyperTransport host if we found any
572 */ 555 */
573 if (ht && add_bridge(ht) != 0) 556 if (ht && maple_add_bridge(ht) != 0)
574 of_node_put(ht); 557 of_node_put(ht);
575 558
576 /*
577 * We need to call pci_setup_phb_io for the HT bridge first
578 * so it gets the I/O port numbers starting at 0, and we
579 * need to call it for the AGP bridge after that so it gets
580 * small positive I/O port numbers.
581 */
582 if (u3_ht)
583 pci_setup_phb_io(u3_ht, 1);
584 if (u3_agp)
585 pci_setup_phb_io(u3_agp, 0);
586 if (u4_pcie)
587 pci_setup_phb_io(u4_pcie, 0);
588
589 /* Fixup the IO resources on our host bridges as the common code
590 * does it only for childs of the host bridges
591 */
592 maple_fixup_phb_resources();
593
594 /* Setup the linkage between OF nodes and PHBs */ 559 /* Setup the linkage between OF nodes and PHBs */
595 pci_devs_phb_init(); 560 pci_devs_phb_init();
596 561
diff --git a/arch/powerpc/platforms/pasemi/Kconfig b/arch/powerpc/platforms/pasemi/Kconfig
index 7c5076e38ea1..95cd90fd81c7 100644
--- a/arch/powerpc/platforms/pasemi/Kconfig
+++ b/arch/powerpc/platforms/pasemi/Kconfig
@@ -25,4 +25,13 @@ config PPC_PASEMI_MDIO
25 help 25 help
26 Driver for MDIO via GPIO on PWRficient platforms 26 Driver for MDIO via GPIO on PWRficient platforms
27 27
28config ELECTRA_IDE
29 tristate "Electra IDE driver"
30 default y
31 depends on PPC_PASEMI && ATA
32 select PATA_PLATFORM
33 help
34 This includes driver support for the Electra on-board IDE
35 interface.
36
28endmenu 37endmenu
diff --git a/arch/powerpc/platforms/pasemi/Makefile b/arch/powerpc/platforms/pasemi/Makefile
index 2cd2a4f26a48..f47fcac7e581 100644
--- a/arch/powerpc/platforms/pasemi/Makefile
+++ b/arch/powerpc/platforms/pasemi/Makefile
@@ -1,3 +1,4 @@
1obj-y += setup.o pci.o time.o idle.o powersave.o iommu.o 1obj-y += setup.o pci.o time.o idle.o powersave.o iommu.o
2obj-$(CONFIG_PPC_PASEMI_MDIO) += gpio_mdio.o 2obj-$(CONFIG_PPC_PASEMI_MDIO) += gpio_mdio.o
3obj-$(CONFIG_ELECTRA_IDE) += electra_ide.o
3obj-$(CONFIG_PPC_PASEMI_CPUFREQ) += cpufreq.o 4obj-$(CONFIG_PPC_PASEMI_CPUFREQ) += cpufreq.o
diff --git a/arch/powerpc/platforms/pasemi/electra_ide.c b/arch/powerpc/platforms/pasemi/electra_ide.c
new file mode 100644
index 000000000000..12fb0c949263
--- /dev/null
+++ b/arch/powerpc/platforms/pasemi/electra_ide.c
@@ -0,0 +1,96 @@
1/*
2 * Copyright (C) 2007 PA Semi, Inc
3 *
4 * Maintained by: Olof Johansson <olof@lixom.net>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20#include <linux/platform_device.h>
21
22#include <asm/prom.h>
23#include <asm/system.h>
24
25/* The electra IDE interface is incredibly simple: Just a device on the localbus
26 * with interrupts hooked up to one of the GPIOs. The device tree contains the
27 * address window and interrupt mappings already, and the pata_platform driver handles
28 * the rest. We just need to hook the two up.
29 */
30
31#define MAX_IFS 4 /* really, we have only one */
32
33static struct platform_device *pdevs[MAX_IFS];
34
35static int __devinit electra_ide_init(void)
36{
37 struct device_node *np;
38 struct resource r[3];
39 int ret = 0;
40 int i;
41
42 np = of_find_compatible_node(NULL, "ide", "electra-ide");
43 i = 0;
44
45 while (np && i < MAX_IFS) {
46 memset(r, 0, sizeof(r));
47
48 /* pata_platform wants two address ranges: one for the base registers,
49 * another for the control (altstatus). It's located at offset 0x3f6 in
50 * the window, but the device tree only has one large register window
51 * that covers both ranges. So we need to split it up by hand here:
52 */
53
54 ret = of_address_to_resource(np, 0, &r[0]);
55 if (ret)
56 goto out;
57 ret = of_address_to_resource(np, 0, &r[1]);
58 if (ret)
59 goto out;
60
61 r[1].start += 0x3f6;
62 r[0].end = r[1].start-1;
63
64 r[2].start = irq_of_parse_and_map(np, 0);
65 r[2].end = irq_of_parse_and_map(np, 0);
66 r[2].flags = IORESOURCE_IRQ;
67
68 pr_debug("registering platform device at 0x%lx/0x%lx, irq is %ld\n",
69 r[0].start, r[1].start, r[2].start);
70 pdevs[i] = platform_device_register_simple("pata_platform", i, r, 3);
71 if (IS_ERR(pdevs[i])) {
72 ret = PTR_ERR(pdevs[i]);
73 pdevs[i] = NULL;
74 goto out;
75 }
76 np = of_find_compatible_node(np, "ide", "electra-ide");
77 }
78out:
79 return ret;
80}
81module_init(electra_ide_init);
82
83static void __devexit electra_ide_exit(void)
84{
85 int i;
86
87 for (i = 0; i < MAX_IFS; i++)
88 if (pdevs[i])
89 platform_device_unregister(pdevs[i]);
90}
91module_exit(electra_ide_exit);
92
93
94MODULE_LICENSE("GPL");
95MODULE_AUTHOR ("Olof Johansson <olof@lixom.net>");
96MODULE_DESCRIPTION("PA Semi Electra IDE driver");
diff --git a/arch/powerpc/platforms/pasemi/pci.c b/arch/powerpc/platforms/pasemi/pci.c
index bbc6dfcfaa91..ab1f5f62bcd8 100644
--- a/arch/powerpc/platforms/pasemi/pci.c
+++ b/arch/powerpc/platforms/pasemi/pci.c
@@ -132,7 +132,7 @@ static void __init setup_pa_pxp(struct pci_controller *hose)
132 hose->cfg_data = ioremap(0xe0000000, 0x10000000); 132 hose->cfg_data = ioremap(0xe0000000, 0x10000000);
133} 133}
134 134
135static int __init add_bridge(struct device_node *dev) 135static int __init pas_add_bridge(struct device_node *dev)
136{ 136{
137 struct pci_controller *hose; 137 struct pci_controller *hose;
138 138
@@ -150,29 +150,11 @@ static int __init add_bridge(struct device_node *dev)
150 printk(KERN_INFO "Found PA-PXP PCI host bridge.\n"); 150 printk(KERN_INFO "Found PA-PXP PCI host bridge.\n");
151 151
152 /* Interpret the "ranges" property */ 152 /* Interpret the "ranges" property */
153 /* This also maps the I/O region and sets isa_io/mem_base */
154 pci_process_bridge_OF_ranges(hose, dev, 1); 153 pci_process_bridge_OF_ranges(hose, dev, 1);
155 pci_setup_phb_io(hose, 1);
156 154
157 return 0; 155 return 0;
158} 156}
159 157
160
161static void __init pas_fixup_phb_resources(void)
162{
163 struct pci_controller *hose, *tmp;
164
165 list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
166 unsigned long offset = (unsigned long)hose->io_base_virt - pci_io_base;
167 hose->io_resource.start += offset;
168 hose->io_resource.end += offset;
169 printk(KERN_INFO "PCI Host %d, io start: %lx; io end: %lx\n",
170 hose->global_number,
171 hose->io_resource.start, hose->io_resource.end);
172 }
173}
174
175
176void __init pas_pci_init(void) 158void __init pas_pci_init(void)
177{ 159{
178 struct device_node *np, *root; 160 struct device_node *np, *root;
@@ -185,13 +167,11 @@ void __init pas_pci_init(void)
185 } 167 }
186 168
187 for (np = NULL; (np = of_get_next_child(root, np)) != NULL;) 169 for (np = NULL; (np = of_get_next_child(root, np)) != NULL;)
188 if (np->name && !strcmp(np->name, "pxp") && !add_bridge(np)) 170 if (np->name && !strcmp(np->name, "pxp") && !pas_add_bridge(np))
189 of_node_get(np); 171 of_node_get(np);
190 172
191 of_node_put(root); 173 of_node_put(root);
192 174
193 pas_fixup_phb_resources();
194
195 /* Setup the linkage between OF nodes and PHBs */ 175 /* Setup the linkage between OF nodes and PHBs */
196 pci_devs_phb_init(); 176 pci_devs_phb_init();
197 177
diff --git a/arch/powerpc/platforms/pasemi/setup.c b/arch/powerpc/platforms/pasemi/setup.c
index c5a3f61f8d85..ffe6528048b5 100644
--- a/arch/powerpc/platforms/pasemi/setup.c
+++ b/arch/powerpc/platforms/pasemi/setup.c
@@ -239,7 +239,7 @@ static int __init pas_probe(void)
239 return 1; 239 return 1;
240} 240}
241 241
242define_machine(pas) { 242define_machine(pasemi) {
243 .name = "PA Semi PA6T-1682M", 243 .name = "PA Semi PA6T-1682M",
244 .probe = pas_probe, 244 .probe = pas_probe,
245 .setup_arch = pas_setup_arch, 245 .setup_arch = pas_setup_arch,
diff --git a/arch/powerpc/platforms/powermac/Kconfig b/arch/powerpc/platforms/powermac/Kconfig
index 5b7afe50039a..055990ca8ce6 100644
--- a/arch/powerpc/platforms/powermac/Kconfig
+++ b/arch/powerpc/platforms/powermac/Kconfig
@@ -2,6 +2,7 @@ config PPC_PMAC
2 bool "Apple PowerMac based machines" 2 bool "Apple PowerMac based machines"
3 depends on PPC_MULTIPLATFORM 3 depends on PPC_MULTIPLATFORM
4 select MPIC 4 select MPIC
5 select PCI
5 select PPC_INDIRECT_PCI if PPC32 6 select PPC_INDIRECT_PCI if PPC32
6 select PPC_MPC106 if PPC32 7 select PPC_MPC106 if PPC32
7 select PPC_NATIVE 8 select PPC_NATIVE
diff --git a/arch/powerpc/platforms/powermac/low_i2c.c b/arch/powerpc/platforms/powermac/low_i2c.c
index 3f507ab9c5e5..efdf5eb81ecc 100644
--- a/arch/powerpc/platforms/powermac/low_i2c.c
+++ b/arch/powerpc/platforms/powermac/low_i2c.c
@@ -42,6 +42,7 @@
42#include <linux/interrupt.h> 42#include <linux/interrupt.h>
43#include <linux/completion.h> 43#include <linux/completion.h>
44#include <linux/timer.h> 44#include <linux/timer.h>
45#include <linux/mutex.h>
45#include <asm/keylargo.h> 46#include <asm/keylargo.h>
46#include <asm/uninorth.h> 47#include <asm/uninorth.h>
47#include <asm/io.h> 48#include <asm/io.h>
@@ -84,7 +85,7 @@ struct pmac_i2c_bus
84 void *hostdata; 85 void *hostdata;
85 int channel; /* some hosts have multiple */ 86 int channel; /* some hosts have multiple */
86 int mode; /* current mode */ 87 int mode; /* current mode */
87 struct semaphore sem; 88 struct mutex mutex;
88 int opened; 89 int opened;
89 int polled; /* open mode */ 90 int polled; /* open mode */
90 struct platform_device *platform_dev; 91 struct platform_device *platform_dev;
@@ -104,7 +105,7 @@ static LIST_HEAD(pmac_i2c_busses);
104 105
105struct pmac_i2c_host_kw 106struct pmac_i2c_host_kw
106{ 107{
107 struct semaphore mutex; /* Access mutex for use by 108 struct mutex mutex; /* Access mutex for use by
108 * i2c-keywest */ 109 * i2c-keywest */
109 void __iomem *base; /* register base address */ 110 void __iomem *base; /* register base address */
110 int bsteps; /* register stepping */ 111 int bsteps; /* register stepping */
@@ -375,14 +376,14 @@ static void kw_i2c_timeout(unsigned long data)
375static int kw_i2c_open(struct pmac_i2c_bus *bus) 376static int kw_i2c_open(struct pmac_i2c_bus *bus)
376{ 377{
377 struct pmac_i2c_host_kw *host = bus->hostdata; 378 struct pmac_i2c_host_kw *host = bus->hostdata;
378 down(&host->mutex); 379 mutex_lock(&host->mutex);
379 return 0; 380 return 0;
380} 381}
381 382
382static void kw_i2c_close(struct pmac_i2c_bus *bus) 383static void kw_i2c_close(struct pmac_i2c_bus *bus)
383{ 384{
384 struct pmac_i2c_host_kw *host = bus->hostdata; 385 struct pmac_i2c_host_kw *host = bus->hostdata;
385 up(&host->mutex); 386 mutex_unlock(&host->mutex);
386} 387}
387 388
388static int kw_i2c_xfer(struct pmac_i2c_bus *bus, u8 addrdir, int subsize, 389static int kw_i2c_xfer(struct pmac_i2c_bus *bus, u8 addrdir, int subsize,
@@ -498,7 +499,7 @@ static struct pmac_i2c_host_kw *__init kw_i2c_host_init(struct device_node *np)
498 kfree(host); 499 kfree(host);
499 return NULL; 500 return NULL;
500 } 501 }
501 init_MUTEX(&host->mutex); 502 mutex_init(&host->mutex);
502 init_completion(&host->complete); 503 init_completion(&host->complete);
503 spin_lock_init(&host->lock); 504 spin_lock_init(&host->lock);
504 init_timer(&host->timeout_timer); 505 init_timer(&host->timeout_timer);
@@ -571,7 +572,7 @@ static void __init kw_i2c_add(struct pmac_i2c_host_kw *host,
571 bus->open = kw_i2c_open; 572 bus->open = kw_i2c_open;
572 bus->close = kw_i2c_close; 573 bus->close = kw_i2c_close;
573 bus->xfer = kw_i2c_xfer; 574 bus->xfer = kw_i2c_xfer;
574 init_MUTEX(&bus->sem); 575 mutex_init(&bus->mutex);
575 if (controller == busnode) 576 if (controller == busnode)
576 bus->flags = pmac_i2c_multibus; 577 bus->flags = pmac_i2c_multibus;
577 list_add(&bus->link, &pmac_i2c_busses); 578 list_add(&bus->link, &pmac_i2c_busses);
@@ -798,7 +799,7 @@ static void __init pmu_i2c_probe(void)
798 bus->mode = pmac_i2c_mode_std; 799 bus->mode = pmac_i2c_mode_std;
799 bus->hostdata = bus + 1; 800 bus->hostdata = bus + 1;
800 bus->xfer = pmu_i2c_xfer; 801 bus->xfer = pmu_i2c_xfer;
801 init_MUTEX(&bus->sem); 802 mutex_init(&bus->mutex);
802 bus->flags = pmac_i2c_multibus; 803 bus->flags = pmac_i2c_multibus;
803 list_add(&bus->link, &pmac_i2c_busses); 804 list_add(&bus->link, &pmac_i2c_busses);
804 805
@@ -921,7 +922,7 @@ static void __init smu_i2c_probe(void)
921 bus->mode = pmac_i2c_mode_std; 922 bus->mode = pmac_i2c_mode_std;
922 bus->hostdata = bus + 1; 923 bus->hostdata = bus + 1;
923 bus->xfer = smu_i2c_xfer; 924 bus->xfer = smu_i2c_xfer;
924 init_MUTEX(&bus->sem); 925 mutex_init(&bus->mutex);
925 bus->flags = 0; 926 bus->flags = 0;
926 list_add(&bus->link, &pmac_i2c_busses); 927 list_add(&bus->link, &pmac_i2c_busses);
927 928
@@ -1093,13 +1094,13 @@ int pmac_i2c_open(struct pmac_i2c_bus *bus, int polled)
1093{ 1094{
1094 int rc; 1095 int rc;
1095 1096
1096 down(&bus->sem); 1097 mutex_lock(&bus->mutex);
1097 bus->polled = polled || pmac_i2c_force_poll; 1098 bus->polled = polled || pmac_i2c_force_poll;
1098 bus->opened = 1; 1099 bus->opened = 1;
1099 bus->mode = pmac_i2c_mode_std; 1100 bus->mode = pmac_i2c_mode_std;
1100 if (bus->open && (rc = bus->open(bus)) != 0) { 1101 if (bus->open && (rc = bus->open(bus)) != 0) {
1101 bus->opened = 0; 1102 bus->opened = 0;
1102 up(&bus->sem); 1103 mutex_unlock(&bus->mutex);
1103 return rc; 1104 return rc;
1104 } 1105 }
1105 return 0; 1106 return 0;
@@ -1112,7 +1113,7 @@ void pmac_i2c_close(struct pmac_i2c_bus *bus)
1112 if (bus->close) 1113 if (bus->close)
1113 bus->close(bus); 1114 bus->close(bus);
1114 bus->opened = 0; 1115 bus->opened = 0;
1115 up(&bus->sem); 1116 mutex_unlock(&bus->mutex);
1116} 1117}
1117EXPORT_SYMBOL_GPL(pmac_i2c_close); 1118EXPORT_SYMBOL_GPL(pmac_i2c_close);
1118 1119
diff --git a/arch/powerpc/platforms/powermac/pci.c b/arch/powerpc/platforms/powermac/pci.c
index c4af9e21ac93..92586db19754 100644
--- a/arch/powerpc/platforms/powermac/pci.c
+++ b/arch/powerpc/platforms/powermac/pci.c
@@ -35,8 +35,6 @@
35#define DBG(x...) 35#define DBG(x...)
36#endif 36#endif
37 37
38static int add_bridge(struct device_node *dev);
39
40/* XXX Could be per-controller, but I don't think we risk anything by 38/* XXX Could be per-controller, but I don't think we risk anything by
41 * assuming we won't have both UniNorth and Bandit */ 39 * assuming we won't have both UniNorth and Bandit */
42static int has_uninorth; 40static int has_uninorth;
@@ -897,7 +895,7 @@ static void __init setup_u3_ht(struct pci_controller* hose)
897 * "pci" (a MPC106) and no bandit or chaos bridges, and contrariwise, 895 * "pci" (a MPC106) and no bandit or chaos bridges, and contrariwise,
898 * if we have one or more bandit or chaos bridges, we don't have a MPC106. 896 * if we have one or more bandit or chaos bridges, we don't have a MPC106.
899 */ 897 */
900static int __init add_bridge(struct device_node *dev) 898static int __init pmac_add_bridge(struct device_node *dev)
901{ 899{
902 int len; 900 int len;
903 struct pci_controller *hose; 901 struct pci_controller *hose;
@@ -918,15 +916,9 @@ static int __init add_bridge(struct device_node *dev)
918 " bus 0\n", dev->full_name); 916 " bus 0\n", dev->full_name);
919 } 917 }
920 918
921 /* XXX Different prototypes, to be merged */
922#ifdef CONFIG_PPC64
923 hose = pcibios_alloc_controller(dev); 919 hose = pcibios_alloc_controller(dev);
924#else
925 hose = pcibios_alloc_controller();
926#endif
927 if (!hose) 920 if (!hose)
928 return -ENOMEM; 921 return -ENOMEM;
929 hose->arch_data = dev;
930 hose->first_busno = bus_range ? bus_range[0] : 0; 922 hose->first_busno = bus_range ? bus_range[0] : 0;
931 hose->last_busno = bus_range ? bus_range[1] : 0xff; 923 hose->last_busno = bus_range ? bus_range[1] : 0xff;
932 924
@@ -1006,19 +998,6 @@ void __devinit pmac_pci_irq_fixup(struct pci_dev *dev)
1006#endif /* CONFIG_PPC32 */ 998#endif /* CONFIG_PPC32 */
1007} 999}
1008 1000
1009#ifdef CONFIG_PPC64
1010static void __init pmac_fixup_phb_resources(void)
1011{
1012 struct pci_controller *hose, *tmp;
1013
1014 list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
1015 printk(KERN_INFO "PCI Host %d, io start: %lx; io end: %lx\n",
1016 hose->global_number,
1017 hose->io_resource.start, hose->io_resource.end);
1018 }
1019}
1020#endif
1021
1022void __init pmac_pci_init(void) 1001void __init pmac_pci_init(void)
1023{ 1002{
1024 struct device_node *np, *root; 1003 struct device_node *np, *root;
@@ -1036,7 +1015,7 @@ void __init pmac_pci_init(void)
1036 if (strcmp(np->name, "bandit") == 0 1015 if (strcmp(np->name, "bandit") == 0
1037 || strcmp(np->name, "chaos") == 0 1016 || strcmp(np->name, "chaos") == 0
1038 || strcmp(np->name, "pci") == 0) { 1017 || strcmp(np->name, "pci") == 0) {
1039 if (add_bridge(np) == 0) 1018 if (pmac_add_bridge(np) == 0)
1040 of_node_get(np); 1019 of_node_get(np);
1041 } 1020 }
1042 if (strcmp(np->name, "ht") == 0) { 1021 if (strcmp(np->name, "ht") == 0) {
@@ -1050,28 +1029,9 @@ void __init pmac_pci_init(void)
1050 /* Probe HT last as it relies on the agp resources to be already 1029 /* Probe HT last as it relies on the agp resources to be already
1051 * setup 1030 * setup
1052 */ 1031 */
1053 if (ht && add_bridge(ht) != 0) 1032 if (ht && pmac_add_bridge(ht) != 0)
1054 of_node_put(ht); 1033 of_node_put(ht);
1055 1034
1056 /*
1057 * We need to call pci_setup_phb_io for the HT bridge first
1058 * so it gets the I/O port numbers starting at 0, and we
1059 * need to call it for the AGP bridge after that so it gets
1060 * small positive I/O port numbers.
1061 */
1062 if (u3_ht)
1063 pci_setup_phb_io(u3_ht, 1);
1064 if (u3_agp)
1065 pci_setup_phb_io(u3_agp, 0);
1066 if (u4_pcie)
1067 pci_setup_phb_io(u4_pcie, 0);
1068
1069 /*
1070 * On ppc64, fixup the IO resources on our host bridges as
1071 * the common code does it only for children of the host bridges
1072 */
1073 pmac_fixup_phb_resources();
1074
1075 /* Setup the linkage between OF nodes and PHBs */ 1035 /* Setup the linkage between OF nodes and PHBs */
1076 pci_devs_phb_init(); 1036 pci_devs_phb_init();
1077 1037
diff --git a/arch/powerpc/platforms/ps3/Kconfig b/arch/powerpc/platforms/ps3/Kconfig
index 40f0008af4d1..a05079b07696 100644
--- a/arch/powerpc/platforms/ps3/Kconfig
+++ b/arch/powerpc/platforms/ps3/Kconfig
@@ -7,6 +7,7 @@ config PPC_PS3
7 select USB_OHCI_BIG_ENDIAN_MMIO 7 select USB_OHCI_BIG_ENDIAN_MMIO
8 select USB_ARCH_HAS_EHCI 8 select USB_ARCH_HAS_EHCI
9 select USB_EHCI_BIG_ENDIAN_MMIO 9 select USB_EHCI_BIG_ENDIAN_MMIO
10 select MEMORY_HOTPLUG
10 help 11 help
11 This option enables support for the Sony PS3 game console 12 This option enables support for the Sony PS3 game console
12 and other platforms using the PS3 hypervisor. 13 and other platforms using the PS3 hypervisor.
@@ -73,18 +74,12 @@ config PS3_USE_LPAR_ADDR
73 74
74config PS3_VUART 75config PS3_VUART
75 depends on PPC_PS3 76 depends on PPC_PS3
76 bool "PS3 Virtual UART support" if PS3_ADVANCED 77 tristate
77 default y
78 help
79 Include support for the PS3 Virtual UART.
80
81 This support is required for several system services
82 including the System Manager and AV Settings. In
83 general, all users will say Y.
84 78
85config PS3_PS3AV 79config PS3_PS3AV
80 depends on PPC_PS3
86 tristate "PS3 AV settings driver" if PS3_ADVANCED 81 tristate "PS3 AV settings driver" if PS3_ADVANCED
87 depends on PS3_VUART 82 select PS3_VUART
88 default y 83 default y
89 help 84 help
90 Include support for the PS3 AV Settings driver. 85 Include support for the PS3 AV Settings driver.
@@ -93,13 +88,18 @@ config PS3_PS3AV
93 general, all users will say Y or M. 88 general, all users will say Y or M.
94 89
95config PS3_SYS_MANAGER 90config PS3_SYS_MANAGER
96 bool "PS3 System Manager driver" if PS3_ADVANCED 91 depends on PPC_PS3
97 depends on PS3_VUART 92 tristate "PS3 System Manager driver" if PS3_ADVANCED
98 default y 93 select PS3_VUART
94 default m
99 help 95 help
100 Include support for the PS3 System Manager. 96 Include support for the PS3 System Manager.
101 97
102 This support is required for system control. In 98 This support is required for system control. In
103 general, all users will say Y. 99 general, all users will say Y or M.
100
101config PS3_STORAGE
102 depends on PPC_PS3
103 tristate
104 104
105endmenu 105endmenu
diff --git a/arch/powerpc/platforms/ps3/Makefile b/arch/powerpc/platforms/ps3/Makefile
index a0048fcf0866..ac1bdf844eca 100644
--- a/arch/powerpc/platforms/ps3/Makefile
+++ b/arch/powerpc/platforms/ps3/Makefile
@@ -4,3 +4,4 @@ obj-y += system-bus.o
4 4
5obj-$(CONFIG_SMP) += smp.o 5obj-$(CONFIG_SMP) += smp.o
6obj-$(CONFIG_SPU_BASE) += spu.o 6obj-$(CONFIG_SPU_BASE) += spu.o
7obj-y += device-init.o
diff --git a/arch/powerpc/platforms/ps3/device-init.c b/arch/powerpc/platforms/ps3/device-init.c
new file mode 100644
index 000000000000..825ebb2cbc2a
--- /dev/null
+++ b/arch/powerpc/platforms/ps3/device-init.c
@@ -0,0 +1,785 @@
1/*
2 * PS3 device registration routines.
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/delay.h>
22#include <linux/freezer.h>
23#include <linux/kernel.h>
24#include <linux/kthread.h>
25#include <linux/init.h>
26
27#include <asm/firmware.h>
28#include <asm/lv1call.h>
29#include <asm/ps3stor.h>
30
31#include "platform.h"
32
33/**
34 * ps3_setup_gelic_device - Setup and register a gelic device instance.
35 *
36 * Allocates memory for a struct ps3_system_bus_device instance, initialises the
37 * structure members, and registers the device instance with the system bus.
38 */
39
40static int __init ps3_setup_gelic_device(
41 const struct ps3_repository_device *repo)
42{
43 int result;
44 struct layout {
45 struct ps3_system_bus_device dev;
46 struct ps3_dma_region d_region;
47 } *p;
48
49 pr_debug(" -> %s:%d\n", __func__, __LINE__);
50
51 BUG_ON(repo->bus_type != PS3_BUS_TYPE_SB);
52 BUG_ON(repo->dev_type != PS3_DEV_TYPE_SB_GELIC);
53
54 p = kzalloc(sizeof(struct layout), GFP_KERNEL);
55
56 if (!p) {
57 result = -ENOMEM;
58 goto fail_malloc;
59 }
60
61 p->dev.match_id = PS3_MATCH_ID_GELIC;
62 p->dev.dev_type = PS3_DEVICE_TYPE_SB;
63 p->dev.bus_id = repo->bus_id;
64 p->dev.dev_id = repo->dev_id;
65 p->dev.d_region = &p->d_region;
66
67 result = ps3_repository_find_interrupt(repo,
68 PS3_INTERRUPT_TYPE_EVENT_PORT, &p->dev.interrupt_id);
69
70 if (result) {
71 pr_debug("%s:%d ps3_repository_find_interrupt failed\n",
72 __func__, __LINE__);
73 goto fail_find_interrupt;
74 }
75
76 BUG_ON(p->dev.interrupt_id != 0);
77
78 result = ps3_dma_region_init(&p->dev, p->dev.d_region, PS3_DMA_64K,
79 PS3_DMA_OTHER, NULL, 0);
80
81 if (result) {
82 pr_debug("%s:%d ps3_dma_region_init failed\n",
83 __func__, __LINE__);
84 goto fail_dma_init;
85 }
86
87 result = ps3_system_bus_device_register(&p->dev);
88
89 if (result) {
90 pr_debug("%s:%d ps3_system_bus_device_register failed\n",
91 __func__, __LINE__);
92 goto fail_device_register;
93 }
94
95 pr_debug(" <- %s:%d\n", __func__, __LINE__);
96 return result;
97
98fail_device_register:
99fail_dma_init:
100fail_find_interrupt:
101 kfree(p);
102fail_malloc:
103 pr_debug(" <- %s:%d: fail.\n", __func__, __LINE__);
104 return result;
105}
106
107static int __init_refok ps3_setup_uhc_device(
108 const struct ps3_repository_device *repo, enum ps3_match_id match_id,
109 enum ps3_interrupt_type interrupt_type, enum ps3_reg_type reg_type)
110{
111 int result;
112 struct layout {
113 struct ps3_system_bus_device dev;
114 struct ps3_dma_region d_region;
115 struct ps3_mmio_region m_region;
116 } *p;
117 u64 bus_addr;
118 u64 len;
119
120 pr_debug(" -> %s:%d\n", __func__, __LINE__);
121
122 BUG_ON(repo->bus_type != PS3_BUS_TYPE_SB);
123 BUG_ON(repo->dev_type != PS3_DEV_TYPE_SB_USB);
124
125 p = kzalloc(sizeof(struct layout), GFP_KERNEL);
126
127 if (!p) {
128 result = -ENOMEM;
129 goto fail_malloc;
130 }
131
132 p->dev.match_id = match_id;
133 p->dev.dev_type = PS3_DEVICE_TYPE_SB;
134 p->dev.bus_id = repo->bus_id;
135 p->dev.dev_id = repo->dev_id;
136 p->dev.d_region = &p->d_region;
137 p->dev.m_region = &p->m_region;
138
139 result = ps3_repository_find_interrupt(repo,
140 interrupt_type, &p->dev.interrupt_id);
141
142 if (result) {
143 pr_debug("%s:%d ps3_repository_find_interrupt failed\n",
144 __func__, __LINE__);
145 goto fail_find_interrupt;
146 }
147
148 result = ps3_repository_find_reg(repo, reg_type,
149 &bus_addr, &len);
150
151 if (result) {
152 pr_debug("%s:%d ps3_repository_find_reg failed\n",
153 __func__, __LINE__);
154 goto fail_find_reg;
155 }
156
157 result = ps3_dma_region_init(&p->dev, p->dev.d_region, PS3_DMA_64K,
158 PS3_DMA_INTERNAL, NULL, 0);
159
160 if (result) {
161 pr_debug("%s:%d ps3_dma_region_init failed\n",
162 __func__, __LINE__);
163 goto fail_dma_init;
164 }
165
166 result = ps3_mmio_region_init(&p->dev, p->dev.m_region, bus_addr, len,
167 PS3_MMIO_4K);
168
169 if (result) {
170 pr_debug("%s:%d ps3_mmio_region_init failed\n",
171 __func__, __LINE__);
172 goto fail_mmio_init;
173 }
174
175 result = ps3_system_bus_device_register(&p->dev);
176
177 if (result) {
178 pr_debug("%s:%d ps3_system_bus_device_register failed\n",
179 __func__, __LINE__);
180 goto fail_device_register;
181 }
182
183 pr_debug(" <- %s:%d\n", __func__, __LINE__);
184 return result;
185
186fail_device_register:
187fail_mmio_init:
188fail_dma_init:
189fail_find_reg:
190fail_find_interrupt:
191 kfree(p);
192fail_malloc:
193 pr_debug(" <- %s:%d: fail.\n", __func__, __LINE__);
194 return result;
195}
196
197static int __init ps3_setup_ehci_device(
198 const struct ps3_repository_device *repo)
199{
200 return ps3_setup_uhc_device(repo, PS3_MATCH_ID_EHCI,
201 PS3_INTERRUPT_TYPE_SB_EHCI, PS3_REG_TYPE_SB_EHCI);
202}
203
204static int __init ps3_setup_ohci_device(
205 const struct ps3_repository_device *repo)
206{
207 return ps3_setup_uhc_device(repo, PS3_MATCH_ID_OHCI,
208 PS3_INTERRUPT_TYPE_SB_OHCI, PS3_REG_TYPE_SB_OHCI);
209}
210
211static int __init ps3_setup_vuart_device(enum ps3_match_id match_id,
212 unsigned int port_number)
213{
214 int result;
215 struct layout {
216 struct ps3_system_bus_device dev;
217 } *p;
218
219 pr_debug(" -> %s:%d: match_id %u, port %u\n", __func__, __LINE__,
220 match_id, port_number);
221
222 p = kzalloc(sizeof(struct layout), GFP_KERNEL);
223
224 if (!p)
225 return -ENOMEM;
226
227 p->dev.match_id = match_id;
228 p->dev.dev_type = PS3_DEVICE_TYPE_VUART;
229 p->dev.port_number = port_number;
230
231 result = ps3_system_bus_device_register(&p->dev);
232
233 if (result)
234 pr_debug("%s:%d ps3_system_bus_device_register failed\n",
235 __func__, __LINE__);
236
237 pr_debug(" <- %s:%d\n", __func__, __LINE__);
238 return result;
239}
240
241static int ps3stor_wait_for_completion(u64 dev_id, u64 tag,
242 unsigned int timeout)
243{
244 int result = -1;
245 unsigned int retries = 0;
246 u64 status;
247
248 for (retries = 0; retries < timeout; retries++) {
249 result = lv1_storage_check_async_status(dev_id, tag, &status);
250 if (!result)
251 break;
252
253 msleep(1);
254 }
255
256 if (result)
257 pr_debug("%s:%u: check_async_status: %s, status %lx\n",
258 __func__, __LINE__, ps3_result(result), status);
259
260 return result;
261}
262
263/**
264 * ps3_storage_wait_for_device - Wait for a storage device to become ready.
265 * @repo: The repository device to wait for.
266 *
267 * Uses the hypervisor's storage device notification mechanism to wait until
268 * a storage device is ready. The device notification mechanism uses a
269 * psuedo device (id = -1) to asynchronously notify the guest when storage
270 * devices become ready. The notification device has a block size of 512
271 * bytes.
272 */
273
274static int ps3_storage_wait_for_device(const struct ps3_repository_device *repo)
275{
276 int result;
277 const u64 notification_dev_id = (u64)-1LL;
278 const unsigned int timeout = HZ;
279 u64 lpar;
280 u64 tag;
281 struct {
282 u64 operation_code; /* must be zero */
283 u64 event_mask; /* 1 = device ready */
284 } *notify_cmd;
285 struct {
286 u64 event_type; /* notify_device_ready */
287 u64 bus_id;
288 u64 dev_id;
289 u64 dev_type;
290 u64 dev_port;
291 } *notify_event;
292 enum {
293 notify_device_ready = 1
294 };
295
296 pr_debug(" -> %s:%u: bus_id %u, dev_id %u, dev_type %u\n", __func__,
297 __LINE__, repo->bus_id, repo->dev_id, repo->dev_type);
298
299 notify_cmd = kzalloc(512, GFP_KERNEL);
300 notify_event = (void *)notify_cmd;
301 if (!notify_cmd)
302 return -ENOMEM;
303
304 lpar = ps3_mm_phys_to_lpar(__pa(notify_cmd));
305
306 result = lv1_open_device(repo->bus_id, notification_dev_id, 0);
307 if (result) {
308 printk(KERN_ERR "%s:%u: lv1_open_device %s\n", __func__,
309 __LINE__, ps3_result(result));
310 result = -ENODEV;
311 goto fail_free;
312 }
313
314 /* Setup and write the request for device notification. */
315
316 notify_cmd->operation_code = 0; /* must be zero */
317 notify_cmd->event_mask = 0x01; /* device ready */
318
319 result = lv1_storage_write(notification_dev_id, 0, 0, 1, 0, lpar,
320 &tag);
321 if (result) {
322 printk(KERN_ERR "%s:%u: write failed %s\n", __func__, __LINE__,
323 ps3_result(result));
324 result = -ENODEV;
325 goto fail_close;
326 }
327
328 /* Wait for the write completion */
329
330 result = ps3stor_wait_for_completion(notification_dev_id, tag,
331 timeout);
332 if (result) {
333 printk(KERN_ERR "%s:%u: write not completed %s\n", __func__,
334 __LINE__, ps3_result(result));
335 result = -ENODEV;
336 goto fail_close;
337 }
338
339 /* Loop here processing the requested notification events. */
340
341 result = -ENODEV;
342 while (1) {
343 memset(notify_event, 0, sizeof(*notify_event));
344
345 result = lv1_storage_read(notification_dev_id, 0, 0, 1, 0,
346 lpar, &tag);
347 if (result) {
348 printk(KERN_ERR "%s:%u: write failed %s\n", __func__,
349 __LINE__, ps3_result(result));
350 break;
351 }
352
353 result = ps3stor_wait_for_completion(notification_dev_id, tag,
354 timeout);
355 if (result) {
356 printk(KERN_ERR "%s:%u: read not completed %s\n",
357 __func__, __LINE__, ps3_result(result));
358 break;
359 }
360
361 if (notify_event->event_type != notify_device_ready ||
362 notify_event->bus_id != repo->bus_id) {
363 pr_debug("%s:%u: bad notify_event: event %lu, "
364 "dev_id %lu, dev_type %lu\n",
365 __func__, __LINE__, notify_event->event_type,
366 notify_event->dev_id, notify_event->dev_type);
367 break;
368 }
369
370 if (notify_event->dev_id == repo->dev_id &&
371 notify_event->dev_type == repo->dev_type) {
372 pr_debug("%s:%u: device ready: dev_id %u\n", __func__,
373 __LINE__, repo->dev_id);
374 result = 0;
375 break;
376 }
377
378 if (notify_event->dev_id == repo->dev_id &&
379 notify_event->dev_type == PS3_DEV_TYPE_NOACCESS) {
380 pr_debug("%s:%u: no access: dev_id %u\n", __func__,
381 __LINE__, repo->dev_id);
382 break;
383 }
384 }
385
386fail_close:
387 lv1_close_device(repo->bus_id, notification_dev_id);
388fail_free:
389 kfree(notify_cmd);
390 pr_debug(" <- %s:%u\n", __func__, __LINE__);
391 return result;
392}
393
394static int ps3_setup_storage_dev(const struct ps3_repository_device *repo,
395 enum ps3_match_id match_id)
396{
397 int result;
398 struct ps3_storage_device *p;
399 u64 port, blk_size, num_blocks;
400 unsigned int num_regions, i;
401
402 pr_debug(" -> %s:%u: match_id %u\n", __func__, __LINE__, match_id);
403
404 result = ps3_repository_read_stor_dev_info(repo->bus_index,
405 repo->dev_index, &port,
406 &blk_size, &num_blocks,
407 &num_regions);
408 if (result) {
409 printk(KERN_ERR "%s:%u: _read_stor_dev_info failed %d\n",
410 __func__, __LINE__, result);
411 return -ENODEV;
412 }
413
414 pr_debug("%s:%u: index %u:%u: port %lu blk_size %lu num_blocks %lu "
415 "num_regions %u\n", __func__, __LINE__, repo->bus_index,
416 repo->dev_index, port, blk_size, num_blocks, num_regions);
417
418 p = kzalloc(sizeof(struct ps3_storage_device) +
419 num_regions * sizeof(struct ps3_storage_region),
420 GFP_KERNEL);
421 if (!p) {
422 result = -ENOMEM;
423 goto fail_malloc;
424 }
425
426 p->sbd.match_id = match_id;
427 p->sbd.dev_type = PS3_DEVICE_TYPE_SB;
428 p->sbd.bus_id = repo->bus_id;
429 p->sbd.dev_id = repo->dev_id;
430 p->sbd.d_region = &p->dma_region;
431 p->blk_size = blk_size;
432 p->num_regions = num_regions;
433
434 result = ps3_repository_find_interrupt(repo,
435 PS3_INTERRUPT_TYPE_EVENT_PORT,
436 &p->sbd.interrupt_id);
437 if (result) {
438 printk(KERN_ERR "%s:%u: find_interrupt failed %d\n", __func__,
439 __LINE__, result);
440 result = -ENODEV;
441 goto fail_find_interrupt;
442 }
443
444 /* FIXME: Arrange to only do this on a 'cold' boot */
445
446 result = ps3_storage_wait_for_device(repo);
447 if (result) {
448 printk(KERN_ERR "%s:%u: storage_notification failed %d\n",
449 __func__, __LINE__, result);
450 result = -ENODEV;
451 goto fail_probe_notification;
452 }
453
454 for (i = 0; i < num_regions; i++) {
455 unsigned int id;
456 u64 start, size;
457
458 result = ps3_repository_read_stor_dev_region(repo->bus_index,
459 repo->dev_index,
460 i, &id, &start,
461 &size);
462 if (result) {
463 printk(KERN_ERR
464 "%s:%u: read_stor_dev_region failed %d\n",
465 __func__, __LINE__, result);
466 result = -ENODEV;
467 goto fail_read_region;
468 }
469 pr_debug("%s:%u: region %u: id %u start %lu size %lu\n",
470 __func__, __LINE__, i, id, start, size);
471
472 p->regions[i].id = id;
473 p->regions[i].start = start;
474 p->regions[i].size = size;
475 }
476
477 result = ps3_system_bus_device_register(&p->sbd);
478 if (result) {
479 pr_debug("%s:%u ps3_system_bus_device_register failed\n",
480 __func__, __LINE__);
481 goto fail_device_register;
482 }
483
484 pr_debug(" <- %s:%u\n", __func__, __LINE__);
485 return 0;
486
487fail_device_register:
488fail_read_region:
489fail_probe_notification:
490fail_find_interrupt:
491 kfree(p);
492fail_malloc:
493 pr_debug(" <- %s:%u: fail.\n", __func__, __LINE__);
494 return result;
495}
496
497static int __init ps3_register_vuart_devices(void)
498{
499 int result;
500 unsigned int port_number;
501
502 pr_debug(" -> %s:%d\n", __func__, __LINE__);
503
504 result = ps3_repository_read_vuart_av_port(&port_number);
505 if (result)
506 port_number = 0; /* av default */
507
508 result = ps3_setup_vuart_device(PS3_MATCH_ID_AV_SETTINGS, port_number);
509 WARN_ON(result);
510
511 result = ps3_repository_read_vuart_sysmgr_port(&port_number);
512 if (result)
513 port_number = 2; /* sysmgr default */
514
515 result = ps3_setup_vuart_device(PS3_MATCH_ID_SYSTEM_MANAGER,
516 port_number);
517 WARN_ON(result);
518
519 pr_debug(" <- %s:%d\n", __func__, __LINE__);
520 return result;
521}
522
523static int __init ps3_register_sound_devices(void)
524{
525 int result;
526 struct layout {
527 struct ps3_system_bus_device dev;
528 struct ps3_dma_region d_region;
529 struct ps3_mmio_region m_region;
530 } *p;
531
532 pr_debug(" -> %s:%d\n", __func__, __LINE__);
533
534 p = kzalloc(sizeof(*p), GFP_KERNEL);
535 if (!p)
536 return -ENOMEM;
537
538 p->dev.match_id = PS3_MATCH_ID_SOUND;
539 p->dev.dev_type = PS3_DEVICE_TYPE_IOC0;
540 p->dev.d_region = &p->d_region;
541 p->dev.m_region = &p->m_region;
542
543 result = ps3_system_bus_device_register(&p->dev);
544
545 if (result)
546 pr_debug("%s:%d ps3_system_bus_device_register failed\n",
547 __func__, __LINE__);
548
549 pr_debug(" <- %s:%d\n", __func__, __LINE__);
550 return result;
551}
552
553static int __init ps3_register_graphics_devices(void)
554{
555 int result;
556 struct layout {
557 struct ps3_system_bus_device dev;
558 } *p;
559
560 pr_debug(" -> %s:%d\n", __func__, __LINE__);
561
562 p = kzalloc(sizeof(struct layout), GFP_KERNEL);
563
564 if (!p)
565 return -ENOMEM;
566
567 p->dev.match_id = PS3_MATCH_ID_GRAPHICS;
568 p->dev.dev_type = PS3_DEVICE_TYPE_IOC0;
569
570 result = ps3_system_bus_device_register(&p->dev);
571
572 if (result)
573 pr_debug("%s:%d ps3_system_bus_device_register failed\n",
574 __func__, __LINE__);
575
576 pr_debug(" <- %s:%d\n", __func__, __LINE__);
577 return result;
578}
579
580/**
581 * ps3_register_repository_device - Register a device from the repositiory info.
582 *
583 */
584
585static int ps3_register_repository_device(
586 const struct ps3_repository_device *repo)
587{
588 int result;
589
590 switch (repo->dev_type) {
591 case PS3_DEV_TYPE_SB_GELIC:
592 result = ps3_setup_gelic_device(repo);
593 if (result) {
594 pr_debug("%s:%d ps3_setup_gelic_device failed\n",
595 __func__, __LINE__);
596 }
597 break;
598 case PS3_DEV_TYPE_SB_USB:
599
600 /* Each USB device has both an EHCI and an OHCI HC */
601
602 result = ps3_setup_ehci_device(repo);
603
604 if (result) {
605 pr_debug("%s:%d ps3_setup_ehci_device failed\n",
606 __func__, __LINE__);
607 }
608
609 result = ps3_setup_ohci_device(repo);
610
611 if (result) {
612 pr_debug("%s:%d ps3_setup_ohci_device failed\n",
613 __func__, __LINE__);
614 }
615 break;
616 case PS3_DEV_TYPE_STOR_DISK:
617 result = ps3_setup_storage_dev(repo, PS3_MATCH_ID_STOR_DISK);
618
619 /* Some devices are not accessable from the Other OS lpar. */
620 if (result == -ENODEV) {
621 result = 0;
622 pr_debug("%s:%u: not accessable\n", __func__,
623 __LINE__);
624 }
625
626 if (result)
627 pr_debug("%s:%u ps3_setup_storage_dev failed\n",
628 __func__, __LINE__);
629 break;
630
631 case PS3_DEV_TYPE_STOR_ROM:
632 result = ps3_setup_storage_dev(repo, PS3_MATCH_ID_STOR_ROM);
633 if (result)
634 pr_debug("%s:%u ps3_setup_storage_dev failed\n",
635 __func__, __LINE__);
636 break;
637
638 case PS3_DEV_TYPE_STOR_FLASH:
639 result = ps3_setup_storage_dev(repo, PS3_MATCH_ID_STOR_FLASH);
640 if (result)
641 pr_debug("%s:%u ps3_setup_storage_dev failed\n",
642 __func__, __LINE__);
643 break;
644
645 default:
646 result = 0;
647 pr_debug("%s:%u: unsupported dev_type %u\n", __func__, __LINE__,
648 repo->dev_type);
649 }
650
651 return result;
652}
653
654/**
655 * ps3_probe_thread - Background repository probing at system startup.
656 *
657 * This implementation only supports background probing on a single bus.
658 */
659
660static int ps3_probe_thread(void *data)
661{
662 struct ps3_repository_device *repo = data;
663 int result;
664 unsigned int ms = 250;
665
666 pr_debug(" -> %s:%u: kthread started\n", __func__, __LINE__);
667
668 do {
669 try_to_freeze();
670
671 pr_debug("%s:%u: probing...\n", __func__, __LINE__);
672
673 do {
674 result = ps3_repository_find_device(repo);
675
676 if (result == -ENODEV)
677 pr_debug("%s:%u: nothing new\n", __func__,
678 __LINE__);
679 else if (result)
680 pr_debug("%s:%u: find device error.\n",
681 __func__, __LINE__);
682 else {
683 pr_debug("%s:%u: found device\n", __func__,
684 __LINE__);
685 ps3_register_repository_device(repo);
686 ps3_repository_bump_device(repo);
687 ms = 250;
688 }
689 } while (!result);
690
691 pr_debug("%s:%u: ms %u\n", __func__, __LINE__, ms);
692
693 if ( ms > 60000)
694 break;
695
696 msleep_interruptible(ms);
697
698 /* An exponential backoff. */
699 ms <<= 1;
700
701 } while (!kthread_should_stop());
702
703 pr_debug(" <- %s:%u: kthread finished\n", __func__, __LINE__);
704
705 return 0;
706}
707
708/**
709 * ps3_start_probe_thread - Starts the background probe thread.
710 *
711 */
712
713static int __init ps3_start_probe_thread(enum ps3_bus_type bus_type)
714{
715 int result;
716 struct task_struct *task;
717 static struct ps3_repository_device repo; /* must be static */
718
719 pr_debug(" -> %s:%d\n", __func__, __LINE__);
720
721 memset(&repo, 0, sizeof(repo));
722
723 repo.bus_type = bus_type;
724
725 result = ps3_repository_find_bus(repo.bus_type, 0, &repo.bus_index);
726
727 if (result) {
728 printk(KERN_ERR "%s: Cannot find bus (%d)\n", __func__, result);
729 return -ENODEV;
730 }
731
732 result = ps3_repository_read_bus_id(repo.bus_index, &repo.bus_id);
733
734 if (result) {
735 printk(KERN_ERR "%s: read_bus_id failed %d\n", __func__,
736 result);
737 return -ENODEV;
738 }
739
740 task = kthread_run(ps3_probe_thread, &repo, "ps3-probe-%u", bus_type);
741
742 if (IS_ERR(task)) {
743 result = PTR_ERR(task);
744 printk(KERN_ERR "%s: kthread_run failed %d\n", __func__,
745 result);
746 return result;
747 }
748
749 pr_debug(" <- %s:%d\n", __func__, __LINE__);
750 return 0;
751}
752
753/**
754 * ps3_register_devices - Probe the system and register devices found.
755 *
756 * A device_initcall() routine.
757 */
758
759static int __init ps3_register_devices(void)
760{
761 int result;
762
763 if (!firmware_has_feature(FW_FEATURE_PS3_LV1))
764 return -ENODEV;
765
766 pr_debug(" -> %s:%d\n", __func__, __LINE__);
767
768 /* ps3_repository_dump_bus_info(); */
769
770 result = ps3_start_probe_thread(PS3_BUS_TYPE_STORAGE);
771
772 ps3_register_vuart_devices();
773
774 ps3_register_graphics_devices();
775
776 ps3_repository_find_devices(PS3_BUS_TYPE_SB,
777 ps3_register_repository_device);
778
779 ps3_register_sound_devices();
780
781 pr_debug(" <- %s:%d\n", __func__, __LINE__);
782 return 0;
783}
784
785device_initcall(ps3_register_devices);
diff --git a/arch/powerpc/platforms/ps3/htab.c b/arch/powerpc/platforms/ps3/htab.c
index a1409e450c70..5d2e176a1b18 100644
--- a/arch/powerpc/platforms/ps3/htab.c
+++ b/arch/powerpc/platforms/ps3/htab.c
@@ -29,12 +29,12 @@
29#include "platform.h" 29#include "platform.h"
30 30
31#if defined(DEBUG) 31#if defined(DEBUG)
32#define DBG(fmt...) udbg_printf(fmt) 32#define DBG udbg_printf
33#else 33#else
34#define DBG(fmt...) do{if(0)printk(fmt);}while(0) 34#define DBG pr_debug
35#endif 35#endif
36 36
37static hpte_t *htab; 37static struct hash_pte *htab;
38static unsigned long htab_addr; 38static unsigned long htab_addr;
39static unsigned char *bolttab; 39static unsigned char *bolttab;
40static unsigned char *inusetab; 40static unsigned char *inusetab;
@@ -44,8 +44,8 @@ static DEFINE_SPINLOCK(ps3_bolttab_lock);
44#define debug_dump_hpte(_a, _b, _c, _d, _e, _f, _g) \ 44#define debug_dump_hpte(_a, _b, _c, _d, _e, _f, _g) \
45 _debug_dump_hpte(_a, _b, _c, _d, _e, _f, _g, __func__, __LINE__) 45 _debug_dump_hpte(_a, _b, _c, _d, _e, _f, _g, __func__, __LINE__)
46static void _debug_dump_hpte(unsigned long pa, unsigned long va, 46static void _debug_dump_hpte(unsigned long pa, unsigned long va,
47 unsigned long group, unsigned long bitmap, hpte_t lhpte, int psize, 47 unsigned long group, unsigned long bitmap, struct hash_pte lhpte,
48 unsigned long slot, const char* func, int line) 48 int psize, unsigned long slot, const char* func, int line)
49{ 49{
50 DBG("%s:%d: pa = %lxh\n", func, line, pa); 50 DBG("%s:%d: pa = %lxh\n", func, line, pa);
51 DBG("%s:%d: lpar = %lxh\n", func, line, 51 DBG("%s:%d: lpar = %lxh\n", func, line,
@@ -63,7 +63,7 @@ static long ps3_hpte_insert(unsigned long hpte_group, unsigned long va,
63 unsigned long pa, unsigned long rflags, unsigned long vflags, int psize) 63 unsigned long pa, unsigned long rflags, unsigned long vflags, int psize)
64{ 64{
65 unsigned long slot; 65 unsigned long slot;
66 hpte_t lhpte; 66 struct hash_pte lhpte;
67 int secondary = 0; 67 int secondary = 0;
68 unsigned long result; 68 unsigned long result;
69 unsigned long bitmap; 69 unsigned long bitmap;
@@ -234,10 +234,17 @@ static void ps3_hpte_invalidate(unsigned long slot, unsigned long va,
234 234
235static void ps3_hpte_clear(void) 235static void ps3_hpte_clear(void)
236{ 236{
237 /* Make sure to clean up the frame buffer device first */ 237 int result;
238 ps3fb_cleanup();
239 238
240 lv1_unmap_htab(htab_addr); 239 DBG(" -> %s:%d\n", __func__, __LINE__);
240
241 result = lv1_unmap_htab(htab_addr);
242 BUG_ON(result);
243
244 ps3_mm_shutdown();
245 ps3_mm_vas_destroy();
246
247 DBG(" <- %s:%d\n", __func__, __LINE__);
241} 248}
242 249
243void __init ps3_hpte_init(unsigned long htab_size) 250void __init ps3_hpte_init(unsigned long htab_size)
@@ -255,7 +262,7 @@ void __init ps3_hpte_init(unsigned long htab_size)
255 262
256 ppc64_pft_size = __ilog2(htab_size); 263 ppc64_pft_size = __ilog2(htab_size);
257 264
258 bitmap_size = htab_size / sizeof(hpte_t) / 8; 265 bitmap_size = htab_size / sizeof(struct hash_pte) / 8;
259 266
260 bolttab = __va(lmb_alloc(bitmap_size, 1)); 267 bolttab = __va(lmb_alloc(bitmap_size, 1));
261 inusetab = __va(lmb_alloc(bitmap_size, 1)); 268 inusetab = __va(lmb_alloc(bitmap_size, 1));
@@ -273,8 +280,8 @@ void __init ps3_map_htab(void)
273 280
274 result = lv1_map_htab(0, &htab_addr); 281 result = lv1_map_htab(0, &htab_addr);
275 282
276 htab = (hpte_t *)__ioremap(htab_addr, htab_size, 283 htab = (__force struct hash_pte *)ioremap_flags(htab_addr, htab_size,
277 pgprot_val(PAGE_READONLY_X)); 284 pgprot_val(PAGE_READONLY_X));
278 285
279 DBG("%s:%d: lpar %016lxh, virt %016lxh\n", __func__, __LINE__, 286 DBG("%s:%d: lpar %016lxh, virt %016lxh\n", __func__, __LINE__,
280 htab_addr, (unsigned long)htab); 287 htab_addr, (unsigned long)htab);
diff --git a/arch/powerpc/platforms/ps3/interrupt.c b/arch/powerpc/platforms/ps3/interrupt.c
index ec9030dbb5f1..67e32ec9b37e 100644
--- a/arch/powerpc/platforms/ps3/interrupt.c
+++ b/arch/powerpc/platforms/ps3/interrupt.c
@@ -30,9 +30,9 @@
30#include "platform.h" 30#include "platform.h"
31 31
32#if defined(DEBUG) 32#if defined(DEBUG)
33#define DBG(fmt...) udbg_printf(fmt) 33#define DBG udbg_printf
34#else 34#else
35#define DBG(fmt...) do{if(0)printk(fmt);}while(0) 35#define DBG pr_debug
36#endif 36#endif
37 37
38/** 38/**
@@ -78,19 +78,85 @@ struct ps3_bmp {
78/** 78/**
79 * struct ps3_private - a per cpu data structure 79 * struct ps3_private - a per cpu data structure
80 * @bmp: ps3_bmp structure 80 * @bmp: ps3_bmp structure
81 * @node: HV logical_ppe_id 81 * @ppe_id: HV logical_ppe_id
82 * @cpu: HV thread_id 82 * @thread_id: HV thread_id
83 */ 83 */
84 84
85struct ps3_private { 85struct ps3_private {
86 struct ps3_bmp bmp __attribute__ ((aligned (PS3_BMP_MINALIGN))); 86 struct ps3_bmp bmp __attribute__ ((aligned (PS3_BMP_MINALIGN)));
87 u64 node; 87 u64 ppe_id;
88 unsigned int cpu; 88 u64 thread_id;
89}; 89};
90 90
91static DEFINE_PER_CPU(struct ps3_private, ps3_private); 91static DEFINE_PER_CPU(struct ps3_private, ps3_private);
92 92
93/** 93/**
94 * ps3_chip_mask - Set an interrupt mask bit in ps3_bmp.
95 * @virq: The assigned Linux virq.
96 *
97 * Sets ps3_bmp.mask and calls lv1_did_update_interrupt_mask().
98 */
99
100static void ps3_chip_mask(unsigned int virq)
101{
102 struct ps3_private *pd = get_irq_chip_data(virq);
103 unsigned long flags;
104
105 pr_debug("%s:%d: thread_id %lu, virq %d\n", __func__, __LINE__,
106 pd->thread_id, virq);
107
108 local_irq_save(flags);
109 clear_bit(63 - virq, &pd->bmp.mask);
110 lv1_did_update_interrupt_mask(pd->ppe_id, pd->thread_id);
111 local_irq_restore(flags);
112}
113
114/**
115 * ps3_chip_unmask - Clear an interrupt mask bit in ps3_bmp.
116 * @virq: The assigned Linux virq.
117 *
118 * Clears ps3_bmp.mask and calls lv1_did_update_interrupt_mask().
119 */
120
121static void ps3_chip_unmask(unsigned int virq)
122{
123 struct ps3_private *pd = get_irq_chip_data(virq);
124 unsigned long flags;
125
126 pr_debug("%s:%d: thread_id %lu, virq %d\n", __func__, __LINE__,
127 pd->thread_id, virq);
128
129 local_irq_save(flags);
130 set_bit(63 - virq, &pd->bmp.mask);
131 lv1_did_update_interrupt_mask(pd->ppe_id, pd->thread_id);
132 local_irq_restore(flags);
133}
134
135/**
136 * ps3_chip_eoi - HV end-of-interrupt.
137 * @virq: The assigned Linux virq.
138 *
139 * Calls lv1_end_of_interrupt_ext().
140 */
141
142static void ps3_chip_eoi(unsigned int virq)
143{
144 const struct ps3_private *pd = get_irq_chip_data(virq);
145 lv1_end_of_interrupt_ext(pd->ppe_id, pd->thread_id, virq);
146}
147
148/**
149 * ps3_irq_chip - Represents the ps3_bmp as a Linux struct irq_chip.
150 */
151
152static struct irq_chip ps3_irq_chip = {
153 .typename = "ps3",
154 .mask = ps3_chip_mask,
155 .unmask = ps3_chip_unmask,
156 .eoi = ps3_chip_eoi,
157};
158
159/**
94 * ps3_virq_setup - virq related setup. 160 * ps3_virq_setup - virq related setup.
95 * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be 161 * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be
96 * serviced on. 162 * serviced on.
@@ -134,6 +200,8 @@ int ps3_virq_setup(enum ps3_cpu_binding cpu, unsigned long outlet,
134 goto fail_set; 200 goto fail_set;
135 } 201 }
136 202
203 ps3_chip_mask(*virq);
204
137 return result; 205 return result;
138 206
139fail_set: 207fail_set:
@@ -153,8 +221,8 @@ int ps3_virq_destroy(unsigned int virq)
153{ 221{
154 const struct ps3_private *pd = get_irq_chip_data(virq); 222 const struct ps3_private *pd = get_irq_chip_data(virq);
155 223
156 pr_debug("%s:%d: node %lu, cpu %d, virq %u\n", __func__, __LINE__, 224 pr_debug("%s:%d: ppe_id %lu, thread_id %lu, virq %u\n", __func__,
157 pd->node, pd->cpu, virq); 225 __LINE__, pd->ppe_id, pd->thread_id, virq);
158 226
159 set_irq_chip_data(virq, NULL); 227 set_irq_chip_data(virq, NULL);
160 irq_dispose_mapping(virq); 228 irq_dispose_mapping(virq);
@@ -190,7 +258,8 @@ int ps3_irq_plug_setup(enum ps3_cpu_binding cpu, unsigned long outlet,
190 258
191 /* Binds outlet to cpu + virq. */ 259 /* Binds outlet to cpu + virq. */
192 260
193 result = lv1_connect_irq_plug_ext(pd->node, pd->cpu, *virq, outlet, 0); 261 result = lv1_connect_irq_plug_ext(pd->ppe_id, pd->thread_id, *virq,
262 outlet, 0);
194 263
195 if (result) { 264 if (result) {
196 pr_info("%s:%d: lv1_connect_irq_plug_ext failed: %s\n", 265 pr_info("%s:%d: lv1_connect_irq_plug_ext failed: %s\n",
@@ -222,10 +291,12 @@ int ps3_irq_plug_destroy(unsigned int virq)
222 int result; 291 int result;
223 const struct ps3_private *pd = get_irq_chip_data(virq); 292 const struct ps3_private *pd = get_irq_chip_data(virq);
224 293
225 pr_debug("%s:%d: node %lu, cpu %d, virq %u\n", __func__, __LINE__, 294 pr_debug("%s:%d: ppe_id %lu, thread_id %lu, virq %u\n", __func__,
226 pd->node, pd->cpu, virq); 295 __LINE__, pd->ppe_id, pd->thread_id, virq);
296
297 ps3_chip_mask(virq);
227 298
228 result = lv1_disconnect_irq_plug_ext(pd->node, pd->cpu, virq); 299 result = lv1_disconnect_irq_plug_ext(pd->ppe_id, pd->thread_id, virq);
229 300
230 if (result) 301 if (result)
231 pr_info("%s:%d: lv1_disconnect_irq_plug_ext failed: %s\n", 302 pr_info("%s:%d: lv1_disconnect_irq_plug_ext failed: %s\n",
@@ -282,7 +353,9 @@ int ps3_event_receive_port_destroy(unsigned int virq)
282{ 353{
283 int result; 354 int result;
284 355
285 pr_debug(" -> %s:%d virq: %u\n", __func__, __LINE__, virq); 356 pr_debug(" -> %s:%d virq %u\n", __func__, __LINE__, virq);
357
358 ps3_chip_mask(virq);
286 359
287 result = lv1_destruct_event_receive_port(virq_to_hw(virq)); 360 result = lv1_destruct_event_receive_port(virq_to_hw(virq));
288 361
@@ -290,17 +363,14 @@ int ps3_event_receive_port_destroy(unsigned int virq)
290 pr_debug("%s:%d: lv1_destruct_event_receive_port failed: %s\n", 363 pr_debug("%s:%d: lv1_destruct_event_receive_port failed: %s\n",
291 __func__, __LINE__, ps3_result(result)); 364 __func__, __LINE__, ps3_result(result));
292 365
293 /* lv1_destruct_event_receive_port() destroys the IRQ plug, 366 /*
294 * so don't call ps3_irq_plug_destroy() here. 367 * Don't call ps3_virq_destroy() here since ps3_smp_cleanup_cpu()
368 * calls from interrupt context (smp_call_function) when kexecing.
295 */ 369 */
296 370
297 result = ps3_virq_destroy(virq);
298 BUG_ON(result);
299
300 pr_debug(" <- %s:%d\n", __func__, __LINE__); 371 pr_debug(" <- %s:%d\n", __func__, __LINE__);
301 return result; 372 return result;
302} 373}
303EXPORT_SYMBOL_GPL(ps3_event_receive_port_destroy);
304 374
305int ps3_send_event_locally(unsigned int virq) 375int ps3_send_event_locally(unsigned int virq)
306{ 376{
@@ -311,17 +381,15 @@ int ps3_send_event_locally(unsigned int virq)
311 * ps3_sb_event_receive_port_setup - Setup a system bus event receive port. 381 * ps3_sb_event_receive_port_setup - Setup a system bus event receive port.
312 * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be 382 * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be
313 * serviced on. 383 * serviced on.
314 * @did: The HV device identifier read from the system repository. 384 * @dev: The system bus device instance.
315 * @interrupt_id: The device interrupt id read from the system repository.
316 * @virq: The assigned Linux virq. 385 * @virq: The assigned Linux virq.
317 * 386 *
318 * An event irq represents a virtual device interrupt. The interrupt_id 387 * An event irq represents a virtual device interrupt. The interrupt_id
319 * coresponds to the software interrupt number. 388 * coresponds to the software interrupt number.
320 */ 389 */
321 390
322int ps3_sb_event_receive_port_setup(enum ps3_cpu_binding cpu, 391int ps3_sb_event_receive_port_setup(struct ps3_system_bus_device *dev,
323 const struct ps3_device_id *did, unsigned int interrupt_id, 392 enum ps3_cpu_binding cpu, unsigned int *virq)
324 unsigned int *virq)
325{ 393{
326 /* this should go in system-bus.c */ 394 /* this should go in system-bus.c */
327 395
@@ -332,8 +400,8 @@ int ps3_sb_event_receive_port_setup(enum ps3_cpu_binding cpu,
332 if (result) 400 if (result)
333 return result; 401 return result;
334 402
335 result = lv1_connect_interrupt_event_receive_port(did->bus_id, 403 result = lv1_connect_interrupt_event_receive_port(dev->bus_id,
336 did->dev_id, virq_to_hw(*virq), interrupt_id); 404 dev->dev_id, virq_to_hw(*virq), dev->interrupt_id);
337 405
338 if (result) { 406 if (result) {
339 pr_debug("%s:%d: lv1_connect_interrupt_event_receive_port" 407 pr_debug("%s:%d: lv1_connect_interrupt_event_receive_port"
@@ -345,24 +413,24 @@ int ps3_sb_event_receive_port_setup(enum ps3_cpu_binding cpu,
345 } 413 }
346 414
347 pr_debug("%s:%d: interrupt_id %u, virq %u\n", __func__, __LINE__, 415 pr_debug("%s:%d: interrupt_id %u, virq %u\n", __func__, __LINE__,
348 interrupt_id, *virq); 416 dev->interrupt_id, *virq);
349 417
350 return 0; 418 return 0;
351} 419}
352EXPORT_SYMBOL(ps3_sb_event_receive_port_setup); 420EXPORT_SYMBOL(ps3_sb_event_receive_port_setup);
353 421
354int ps3_sb_event_receive_port_destroy(const struct ps3_device_id *did, 422int ps3_sb_event_receive_port_destroy(struct ps3_system_bus_device *dev,
355 unsigned int interrupt_id, unsigned int virq) 423 unsigned int virq)
356{ 424{
357 /* this should go in system-bus.c */ 425 /* this should go in system-bus.c */
358 426
359 int result; 427 int result;
360 428
361 pr_debug(" -> %s:%d: interrupt_id %u, virq %u\n", __func__, __LINE__, 429 pr_debug(" -> %s:%d: interrupt_id %u, virq %u\n", __func__, __LINE__,
362 interrupt_id, virq); 430 dev->interrupt_id, virq);
363 431
364 result = lv1_disconnect_interrupt_event_receive_port(did->bus_id, 432 result = lv1_disconnect_interrupt_event_receive_port(dev->bus_id,
365 did->dev_id, virq_to_hw(virq), interrupt_id); 433 dev->dev_id, virq_to_hw(virq), dev->interrupt_id);
366 434
367 if (result) 435 if (result)
368 pr_debug("%s:%d: lv1_disconnect_interrupt_event_receive_port" 436 pr_debug("%s:%d: lv1_disconnect_interrupt_event_receive_port"
@@ -372,6 +440,14 @@ int ps3_sb_event_receive_port_destroy(const struct ps3_device_id *did,
372 result = ps3_event_receive_port_destroy(virq); 440 result = ps3_event_receive_port_destroy(virq);
373 BUG_ON(result); 441 BUG_ON(result);
374 442
443 /*
444 * ps3_event_receive_port_destroy() destroys the IRQ plug,
445 * so don't call ps3_irq_plug_destroy() here.
446 */
447
448 result = ps3_virq_destroy(virq);
449 BUG_ON(result);
450
375 pr_debug(" <- %s:%d\n", __func__, __LINE__); 451 pr_debug(" <- %s:%d\n", __func__, __LINE__);
376 return result; 452 return result;
377} 453}
@@ -412,16 +488,24 @@ EXPORT_SYMBOL_GPL(ps3_io_irq_setup);
412int ps3_io_irq_destroy(unsigned int virq) 488int ps3_io_irq_destroy(unsigned int virq)
413{ 489{
414 int result; 490 int result;
491 unsigned long outlet = virq_to_hw(virq);
415 492
416 result = lv1_destruct_io_irq_outlet(virq_to_hw(virq)); 493 ps3_chip_mask(virq);
417 494
418 if (result) 495 /*
419 pr_debug("%s:%d: lv1_destruct_io_irq_outlet failed: %s\n", 496 * lv1_destruct_io_irq_outlet() will destroy the IRQ plug,
420 __func__, __LINE__, ps3_result(result)); 497 * so call ps3_irq_plug_destroy() first.
498 */
421 499
422 result = ps3_irq_plug_destroy(virq); 500 result = ps3_irq_plug_destroy(virq);
423 BUG_ON(result); 501 BUG_ON(result);
424 502
503 result = lv1_destruct_io_irq_outlet(outlet);
504
505 if (result)
506 pr_debug("%s:%d: lv1_destruct_io_irq_outlet failed: %s\n",
507 __func__, __LINE__, ps3_result(result));
508
425 return result; 509 return result;
426} 510}
427EXPORT_SYMBOL_GPL(ps3_io_irq_destroy); 511EXPORT_SYMBOL_GPL(ps3_io_irq_destroy);
@@ -461,11 +545,13 @@ int ps3_vuart_irq_setup(enum ps3_cpu_binding cpu, void* virt_addr_bmp,
461 545
462 return result; 546 return result;
463} 547}
548EXPORT_SYMBOL_GPL(ps3_vuart_irq_setup);
464 549
465int ps3_vuart_irq_destroy(unsigned int virq) 550int ps3_vuart_irq_destroy(unsigned int virq)
466{ 551{
467 int result; 552 int result;
468 553
554 ps3_chip_mask(virq);
469 result = lv1_deconfigure_virtual_uart_irq(); 555 result = lv1_deconfigure_virtual_uart_irq();
470 556
471 if (result) { 557 if (result) {
@@ -479,6 +565,7 @@ int ps3_vuart_irq_destroy(unsigned int virq)
479 565
480 return result; 566 return result;
481} 567}
568EXPORT_SYMBOL_GPL(ps3_vuart_irq_destroy);
482 569
483/** 570/**
484 * ps3_spe_irq_setup - Setup an spe virq. 571 * ps3_spe_irq_setup - Setup an spe virq.
@@ -514,9 +601,14 @@ int ps3_spe_irq_setup(enum ps3_cpu_binding cpu, unsigned long spe_id,
514 601
515int ps3_spe_irq_destroy(unsigned int virq) 602int ps3_spe_irq_destroy(unsigned int virq)
516{ 603{
517 int result = ps3_irq_plug_destroy(virq); 604 int result;
605
606 ps3_chip_mask(virq);
607
608 result = ps3_irq_plug_destroy(virq);
518 BUG_ON(result); 609 BUG_ON(result);
519 return 0; 610
611 return result;
520} 612}
521 613
522 614
@@ -533,7 +625,7 @@ static void _dump_64_bmp(const char *header, const u64 *p, unsigned cpu,
533 *p & 0xffff); 625 *p & 0xffff);
534} 626}
535 627
536static void __attribute__ ((unused)) _dump_256_bmp(const char *header, 628static void __maybe_unused _dump_256_bmp(const char *header,
537 const u64 *p, unsigned cpu, const char* func, int line) 629 const u64 *p, unsigned cpu, const char* func, int line)
538{ 630{
539 pr_debug("%s:%d: %s %u {%016lx:%016lx:%016lx:%016lx}\n", 631 pr_debug("%s:%d: %s %u {%016lx:%016lx:%016lx:%016lx}\n",
@@ -546,86 +638,25 @@ static void _dump_bmp(struct ps3_private* pd, const char* func, int line)
546 unsigned long flags; 638 unsigned long flags;
547 639
548 spin_lock_irqsave(&pd->bmp.lock, flags); 640 spin_lock_irqsave(&pd->bmp.lock, flags);
549 _dump_64_bmp("stat", &pd->bmp.status, pd->cpu, func, line); 641 _dump_64_bmp("stat", &pd->bmp.status, pd->thread_id, func, line);
550 _dump_64_bmp("mask", &pd->bmp.mask, pd->cpu, func, line); 642 _dump_64_bmp("mask", &pd->bmp.mask, pd->thread_id, func, line);
551 spin_unlock_irqrestore(&pd->bmp.lock, flags); 643 spin_unlock_irqrestore(&pd->bmp.lock, flags);
552} 644}
553 645
554#define dump_mask(_x) _dump_mask(_x, __func__, __LINE__) 646#define dump_mask(_x) _dump_mask(_x, __func__, __LINE__)
555static void __attribute__ ((unused)) _dump_mask(struct ps3_private* pd, 647static void __maybe_unused _dump_mask(struct ps3_private *pd,
556 const char* func, int line) 648 const char* func, int line)
557{ 649{
558 unsigned long flags; 650 unsigned long flags;
559 651
560 spin_lock_irqsave(&pd->bmp.lock, flags); 652 spin_lock_irqsave(&pd->bmp.lock, flags);
561 _dump_64_bmp("mask", &pd->bmp.mask, pd->cpu, func, line); 653 _dump_64_bmp("mask", &pd->bmp.mask, pd->thread_id, func, line);
562 spin_unlock_irqrestore(&pd->bmp.lock, flags); 654 spin_unlock_irqrestore(&pd->bmp.lock, flags);
563} 655}
564#else 656#else
565static void dump_bmp(struct ps3_private* pd) {}; 657static void dump_bmp(struct ps3_private* pd) {};
566#endif /* defined(DEBUG) */ 658#endif /* defined(DEBUG) */
567 659
568static void ps3_chip_mask(unsigned int virq)
569{
570 struct ps3_private *pd = get_irq_chip_data(virq);
571 u64 bit = 0x8000000000000000UL >> virq;
572 u64 *p = &pd->bmp.mask;
573 u64 old;
574 unsigned long flags;
575
576 pr_debug("%s:%d: cpu %u, virq %d\n", __func__, __LINE__, pd->cpu, virq);
577
578 local_irq_save(flags);
579 asm volatile(
580 "1: ldarx %0,0,%3\n"
581 "andc %0,%0,%2\n"
582 "stdcx. %0,0,%3\n"
583 "bne- 1b"
584 : "=&r" (old), "+m" (*p)
585 : "r" (bit), "r" (p)
586 : "cc" );
587
588 lv1_did_update_interrupt_mask(pd->node, pd->cpu);
589 local_irq_restore(flags);
590}
591
592static void ps3_chip_unmask(unsigned int virq)
593{
594 struct ps3_private *pd = get_irq_chip_data(virq);
595 u64 bit = 0x8000000000000000UL >> virq;
596 u64 *p = &pd->bmp.mask;
597 u64 old;
598 unsigned long flags;
599
600 pr_debug("%s:%d: cpu %u, virq %d\n", __func__, __LINE__, pd->cpu, virq);
601
602 local_irq_save(flags);
603 asm volatile(
604 "1: ldarx %0,0,%3\n"
605 "or %0,%0,%2\n"
606 "stdcx. %0,0,%3\n"
607 "bne- 1b"
608 : "=&r" (old), "+m" (*p)
609 : "r" (bit), "r" (p)
610 : "cc" );
611
612 lv1_did_update_interrupt_mask(pd->node, pd->cpu);
613 local_irq_restore(flags);
614}
615
616static void ps3_chip_eoi(unsigned int virq)
617{
618 const struct ps3_private *pd = get_irq_chip_data(virq);
619 lv1_end_of_interrupt_ext(pd->node, pd->cpu, virq);
620}
621
622static struct irq_chip irq_chip = {
623 .typename = "ps3",
624 .mask = ps3_chip_mask,
625 .unmask = ps3_chip_unmask,
626 .eoi = ps3_chip_eoi,
627};
628
629static void ps3_host_unmap(struct irq_host *h, unsigned int virq) 660static void ps3_host_unmap(struct irq_host *h, unsigned int virq)
630{ 661{
631 set_irq_chip_data(virq, NULL); 662 set_irq_chip_data(virq, NULL);
@@ -637,7 +668,7 @@ static int ps3_host_map(struct irq_host *h, unsigned int virq,
637 pr_debug("%s:%d: hwirq %lu, virq %u\n", __func__, __LINE__, hwirq, 668 pr_debug("%s:%d: hwirq %lu, virq %u\n", __func__, __LINE__, hwirq,
638 virq); 669 virq);
639 670
640 set_irq_chip_and_handler(virq, &irq_chip, handle_fasteoi_irq); 671 set_irq_chip_and_handler(virq, &ps3_irq_chip, handle_fasteoi_irq);
641 672
642 return 0; 673 return 0;
643} 674}
@@ -657,7 +688,7 @@ void __init ps3_register_ipi_debug_brk(unsigned int cpu, unsigned int virq)
657 cpu, virq, pd->bmp.ipi_debug_brk_mask); 688 cpu, virq, pd->bmp.ipi_debug_brk_mask);
658} 689}
659 690
660unsigned int ps3_get_irq(void) 691static unsigned int ps3_get_irq(void)
661{ 692{
662 struct ps3_private *pd = &__get_cpu_var(ps3_private); 693 struct ps3_private *pd = &__get_cpu_var(ps3_private);
663 u64 x = (pd->bmp.status & pd->bmp.mask); 694 u64 x = (pd->bmp.status & pd->bmp.mask);
@@ -672,8 +703,8 @@ unsigned int ps3_get_irq(void)
672 plug &= 0x3f; 703 plug &= 0x3f;
673 704
674 if (unlikely(plug) == NO_IRQ) { 705 if (unlikely(plug) == NO_IRQ) {
675 pr_debug("%s:%d: no plug found: cpu %u\n", __func__, __LINE__, 706 pr_debug("%s:%d: no plug found: thread_id %lu\n", __func__,
676 pd->cpu); 707 __LINE__, pd->thread_id);
677 dump_bmp(&per_cpu(ps3_private, 0)); 708 dump_bmp(&per_cpu(ps3_private, 0));
678 dump_bmp(&per_cpu(ps3_private, 1)); 709 dump_bmp(&per_cpu(ps3_private, 1));
679 return NO_IRQ; 710 return NO_IRQ;
@@ -703,16 +734,16 @@ void __init ps3_init_IRQ(void)
703 for_each_possible_cpu(cpu) { 734 for_each_possible_cpu(cpu) {
704 struct ps3_private *pd = &per_cpu(ps3_private, cpu); 735 struct ps3_private *pd = &per_cpu(ps3_private, cpu);
705 736
706 lv1_get_logical_ppe_id(&pd->node); 737 lv1_get_logical_ppe_id(&pd->ppe_id);
707 pd->cpu = get_hard_smp_processor_id(cpu); 738 pd->thread_id = get_hard_smp_processor_id(cpu);
708 spin_lock_init(&pd->bmp.lock); 739 spin_lock_init(&pd->bmp.lock);
709 740
710 pr_debug("%s:%d: node %lu, cpu %d, bmp %lxh\n", __func__, 741 pr_debug("%s:%d: ppe_id %lu, thread_id %lu, bmp %lxh\n",
711 __LINE__, pd->node, pd->cpu, 742 __func__, __LINE__, pd->ppe_id, pd->thread_id,
712 ps3_mm_phys_to_lpar(__pa(&pd->bmp))); 743 ps3_mm_phys_to_lpar(__pa(&pd->bmp)));
713 744
714 result = lv1_configure_irq_state_bitmap(pd->node, pd->cpu, 745 result = lv1_configure_irq_state_bitmap(pd->ppe_id,
715 ps3_mm_phys_to_lpar(__pa(&pd->bmp))); 746 pd->thread_id, ps3_mm_phys_to_lpar(__pa(&pd->bmp)));
716 747
717 if (result) 748 if (result)
718 pr_debug("%s:%d: lv1_configure_irq_state_bitmap failed:" 749 pr_debug("%s:%d: lv1_configure_irq_state_bitmap failed:"
@@ -722,3 +753,16 @@ void __init ps3_init_IRQ(void)
722 753
723 ppc_md.get_irq = ps3_get_irq; 754 ppc_md.get_irq = ps3_get_irq;
724} 755}
756
757void ps3_shutdown_IRQ(int cpu)
758{
759 int result;
760 u64 ppe_id;
761 u64 thread_id = get_hard_smp_processor_id(cpu);
762
763 lv1_get_logical_ppe_id(&ppe_id);
764 result = lv1_configure_irq_state_bitmap(ppe_id, thread_id, 0);
765
766 DBG("%s:%d: lv1_configure_irq_state_bitmap (%lu:%lu/%d) %s\n", __func__,
767 __LINE__, ppe_id, thread_id, cpu, ps3_result(result));
768}
diff --git a/arch/powerpc/platforms/ps3/mm.c b/arch/powerpc/platforms/ps3/mm.c
index f8a3e206c584..7bb3e1620974 100644
--- a/arch/powerpc/platforms/ps3/mm.c
+++ b/arch/powerpc/platforms/ps3/mm.c
@@ -30,9 +30,9 @@
30#include "platform.h" 30#include "platform.h"
31 31
32#if defined(DEBUG) 32#if defined(DEBUG)
33#define DBG(fmt...) udbg_printf(fmt) 33#define DBG udbg_printf
34#else 34#else
35#define DBG(fmt...) do{if(0)printk(fmt);}while(0) 35#define DBG pr_debug
36#endif 36#endif
37 37
38enum { 38enum {
@@ -115,7 +115,8 @@ struct map {
115}; 115};
116 116
117#define debug_dump_map(x) _debug_dump_map(x, __func__, __LINE__) 117#define debug_dump_map(x) _debug_dump_map(x, __func__, __LINE__)
118static void _debug_dump_map(const struct map* m, const char* func, int line) 118static void __maybe_unused _debug_dump_map(const struct map *m,
119 const char *func, int line)
119{ 120{
120 DBG("%s:%d: map.total = %lxh\n", func, line, m->total); 121 DBG("%s:%d: map.total = %lxh\n", func, line, m->total);
121 DBG("%s:%d: map.rm.size = %lxh\n", func, line, m->rm.size); 122 DBG("%s:%d: map.rm.size = %lxh\n", func, line, m->rm.size);
@@ -212,9 +213,15 @@ fail:
212 213
213void ps3_mm_vas_destroy(void) 214void ps3_mm_vas_destroy(void)
214{ 215{
216 int result;
217
218 DBG("%s:%d: map.vas_id = %lu\n", __func__, __LINE__, map.vas_id);
219
215 if (map.vas_id) { 220 if (map.vas_id) {
216 lv1_select_virtual_address_space(0); 221 result = lv1_select_virtual_address_space(0);
217 lv1_destruct_virtual_address_space(map.vas_id); 222 BUG_ON(result);
223 result = lv1_destruct_virtual_address_space(map.vas_id);
224 BUG_ON(result);
218 map.vas_id = 0; 225 map.vas_id = 0;
219 } 226 }
220} 227}
@@ -232,7 +239,7 @@ void ps3_mm_vas_destroy(void)
232 * @size is rounded down to a multiple of the vas large page size. 239 * @size is rounded down to a multiple of the vas large page size.
233 */ 240 */
234 241
235int ps3_mm_region_create(struct mem_region *r, unsigned long size) 242static int ps3_mm_region_create(struct mem_region *r, unsigned long size)
236{ 243{
237 int result; 244 int result;
238 unsigned long muid; 245 unsigned long muid;
@@ -273,10 +280,14 @@ zero_region:
273 * @r: pointer to struct mem_region 280 * @r: pointer to struct mem_region
274 */ 281 */
275 282
276void ps3_mm_region_destroy(struct mem_region *r) 283static void ps3_mm_region_destroy(struct mem_region *r)
277{ 284{
285 int result;
286
287 DBG("%s:%d: r->base = %lxh\n", __func__, __LINE__, r->base);
278 if (r->base) { 288 if (r->base) {
279 lv1_release_memory(r->base); 289 result = lv1_release_memory(r->base);
290 BUG_ON(result);
280 r->size = r->base = r->offset = 0; 291 r->size = r->base = r->offset = 0;
281 map.total = map.rm.size; 292 map.total = map.rm.size;
282 } 293 }
@@ -329,31 +340,34 @@ core_initcall(ps3_mm_add_memory);
329/*============================================================================*/ 340/*============================================================================*/
330 341
331/** 342/**
332 * dma_lpar_to_bus - Translate an lpar address to ioc mapped bus address. 343 * dma_sb_lpar_to_bus - Translate an lpar address to ioc mapped bus address.
333 * @r: pointer to dma region structure 344 * @r: pointer to dma region structure
334 * @lpar_addr: HV lpar address 345 * @lpar_addr: HV lpar address
335 */ 346 */
336 347
337static unsigned long dma_lpar_to_bus(struct ps3_dma_region *r, 348static unsigned long dma_sb_lpar_to_bus(struct ps3_dma_region *r,
338 unsigned long lpar_addr) 349 unsigned long lpar_addr)
339{ 350{
340 BUG_ON(lpar_addr >= map.r1.base + map.r1.size); 351 if (lpar_addr >= map.rm.size)
341 return r->bus_addr + (lpar_addr <= map.rm.size ? lpar_addr 352 lpar_addr -= map.r1.offset;
342 : lpar_addr - map.r1.offset); 353 BUG_ON(lpar_addr < r->offset);
354 BUG_ON(lpar_addr >= r->offset + r->len);
355 return r->bus_addr + lpar_addr - r->offset;
343} 356}
344 357
345#define dma_dump_region(_a) _dma_dump_region(_a, __func__, __LINE__) 358#define dma_dump_region(_a) _dma_dump_region(_a, __func__, __LINE__)
346static void _dma_dump_region(const struct ps3_dma_region *r, const char* func, 359static void __maybe_unused _dma_dump_region(const struct ps3_dma_region *r,
347 int line) 360 const char *func, int line)
348{ 361{
349 DBG("%s:%d: dev %u:%u\n", func, line, r->did.bus_id, 362 DBG("%s:%d: dev %u:%u\n", func, line, r->dev->bus_id,
350 r->did.dev_id); 363 r->dev->dev_id);
351 DBG("%s:%d: page_size %u\n", func, line, r->page_size); 364 DBG("%s:%d: page_size %u\n", func, line, r->page_size);
352 DBG("%s:%d: bus_addr %lxh\n", func, line, r->bus_addr); 365 DBG("%s:%d: bus_addr %lxh\n", func, line, r->bus_addr);
353 DBG("%s:%d: len %lxh\n", func, line, r->len); 366 DBG("%s:%d: len %lxh\n", func, line, r->len);
367 DBG("%s:%d: offset %lxh\n", func, line, r->offset);
354} 368}
355 369
356/** 370 /**
357 * dma_chunk - A chunk of dma pages mapped by the io controller. 371 * dma_chunk - A chunk of dma pages mapped by the io controller.
358 * @region - The dma region that owns this chunk. 372 * @region - The dma region that owns this chunk.
359 * @lpar_addr: Starting lpar address of the area to map. 373 * @lpar_addr: Starting lpar address of the area to map.
@@ -381,10 +395,11 @@ static void _dma_dump_chunk (const struct dma_chunk* c, const char* func,
381 int line) 395 int line)
382{ 396{
383 DBG("%s:%d: r.dev %u:%u\n", func, line, 397 DBG("%s:%d: r.dev %u:%u\n", func, line,
384 c->region->did.bus_id, c->region->did.dev_id); 398 c->region->dev->bus_id, c->region->dev->dev_id);
385 DBG("%s:%d: r.bus_addr %lxh\n", func, line, c->region->bus_addr); 399 DBG("%s:%d: r.bus_addr %lxh\n", func, line, c->region->bus_addr);
386 DBG("%s:%d: r.page_size %u\n", func, line, c->region->page_size); 400 DBG("%s:%d: r.page_size %u\n", func, line, c->region->page_size);
387 DBG("%s:%d: r.len %lxh\n", func, line, c->region->len); 401 DBG("%s:%d: r.len %lxh\n", func, line, c->region->len);
402 DBG("%s:%d: r.offset %lxh\n", func, line, c->region->offset);
388 DBG("%s:%d: c.lpar_addr %lxh\n", func, line, c->lpar_addr); 403 DBG("%s:%d: c.lpar_addr %lxh\n", func, line, c->lpar_addr);
389 DBG("%s:%d: c.bus_addr %lxh\n", func, line, c->bus_addr); 404 DBG("%s:%d: c.bus_addr %lxh\n", func, line, c->bus_addr);
390 DBG("%s:%d: c.len %lxh\n", func, line, c->len); 405 DBG("%s:%d: c.len %lxh\n", func, line, c->len);
@@ -395,39 +410,68 @@ static struct dma_chunk * dma_find_chunk(struct ps3_dma_region *r,
395{ 410{
396 struct dma_chunk *c; 411 struct dma_chunk *c;
397 unsigned long aligned_bus = _ALIGN_DOWN(bus_addr, 1 << r->page_size); 412 unsigned long aligned_bus = _ALIGN_DOWN(bus_addr, 1 << r->page_size);
398 unsigned long aligned_len = _ALIGN_UP(len, 1 << r->page_size); 413 unsigned long aligned_len = _ALIGN_UP(len+bus_addr-aligned_bus,
414 1 << r->page_size);
399 415
400 list_for_each_entry(c, &r->chunk_list.head, link) { 416 list_for_each_entry(c, &r->chunk_list.head, link) {
401 /* intersection */ 417 /* intersection */
402 if (aligned_bus >= c->bus_addr 418 if (aligned_bus >= c->bus_addr &&
403 && aligned_bus < c->bus_addr + c->len 419 aligned_bus + aligned_len <= c->bus_addr + c->len)
404 && aligned_bus + aligned_len <= c->bus_addr + c->len) {
405 return c; 420 return c;
406 } 421
407 /* below */ 422 /* below */
408 if (aligned_bus + aligned_len <= c->bus_addr) { 423 if (aligned_bus + aligned_len <= c->bus_addr)
409 continue; 424 continue;
410 } 425
411 /* above */ 426 /* above */
412 if (aligned_bus >= c->bus_addr + c->len) { 427 if (aligned_bus >= c->bus_addr + c->len)
413 continue; 428 continue;
414 }
415 429
416 /* we don't handle the multi-chunk case for now */ 430 /* we don't handle the multi-chunk case for now */
417
418 dma_dump_chunk(c); 431 dma_dump_chunk(c);
419 BUG(); 432 BUG();
420 } 433 }
421 return NULL; 434 return NULL;
422} 435}
423 436
424static int dma_free_chunk(struct dma_chunk *c) 437static struct dma_chunk *dma_find_chunk_lpar(struct ps3_dma_region *r,
438 unsigned long lpar_addr, unsigned long len)
439{
440 struct dma_chunk *c;
441 unsigned long aligned_lpar = _ALIGN_DOWN(lpar_addr, 1 << r->page_size);
442 unsigned long aligned_len = _ALIGN_UP(len + lpar_addr - aligned_lpar,
443 1 << r->page_size);
444
445 list_for_each_entry(c, &r->chunk_list.head, link) {
446 /* intersection */
447 if (c->lpar_addr <= aligned_lpar &&
448 aligned_lpar < c->lpar_addr + c->len) {
449 if (aligned_lpar + aligned_len <= c->lpar_addr + c->len)
450 return c;
451 else {
452 dma_dump_chunk(c);
453 BUG();
454 }
455 }
456 /* below */
457 if (aligned_lpar + aligned_len <= c->lpar_addr) {
458 continue;
459 }
460 /* above */
461 if (c->lpar_addr + c->len <= aligned_lpar) {
462 continue;
463 }
464 }
465 return NULL;
466}
467
468static int dma_sb_free_chunk(struct dma_chunk *c)
425{ 469{
426 int result = 0; 470 int result = 0;
427 471
428 if (c->bus_addr) { 472 if (c->bus_addr) {
429 result = lv1_unmap_device_dma_region(c->region->did.bus_id, 473 result = lv1_unmap_device_dma_region(c->region->dev->bus_id,
430 c->region->did.dev_id, c->bus_addr, c->len); 474 c->region->dev->dev_id, c->bus_addr, c->len);
431 BUG_ON(result); 475 BUG_ON(result);
432 } 476 }
433 477
@@ -435,8 +479,39 @@ static int dma_free_chunk(struct dma_chunk *c)
435 return result; 479 return result;
436} 480}
437 481
482static int dma_ioc0_free_chunk(struct dma_chunk *c)
483{
484 int result = 0;
485 int iopage;
486 unsigned long offset;
487 struct ps3_dma_region *r = c->region;
488
489 DBG("%s:start\n", __func__);
490 for (iopage = 0; iopage < (c->len >> r->page_size); iopage++) {
491 offset = (1 << r->page_size) * iopage;
492 /* put INVALID entry */
493 result = lv1_put_iopte(0,
494 c->bus_addr + offset,
495 c->lpar_addr + offset,
496 r->ioid,
497 0);
498 DBG("%s: bus=%#lx, lpar=%#lx, ioid=%d\n", __func__,
499 c->bus_addr + offset,
500 c->lpar_addr + offset,
501 r->ioid);
502
503 if (result) {
504 DBG("%s:%d: lv1_put_iopte failed: %s\n", __func__,
505 __LINE__, ps3_result(result));
506 }
507 }
508 kfree(c);
509 DBG("%s:end\n", __func__);
510 return result;
511}
512
438/** 513/**
439 * dma_map_pages - Maps dma pages into the io controller bus address space. 514 * dma_sb_map_pages - Maps dma pages into the io controller bus address space.
440 * @r: Pointer to a struct ps3_dma_region. 515 * @r: Pointer to a struct ps3_dma_region.
441 * @phys_addr: Starting physical address of the area to map. 516 * @phys_addr: Starting physical address of the area to map.
442 * @len: Length in bytes of the area to map. 517 * @len: Length in bytes of the area to map.
@@ -446,8 +521,8 @@ static int dma_free_chunk(struct dma_chunk *c)
446 * make the HV call to add the pages into the io controller address space. 521 * make the HV call to add the pages into the io controller address space.
447 */ 522 */
448 523
449static int dma_map_pages(struct ps3_dma_region *r, unsigned long phys_addr, 524static int dma_sb_map_pages(struct ps3_dma_region *r, unsigned long phys_addr,
450 unsigned long len, struct dma_chunk **c_out) 525 unsigned long len, struct dma_chunk **c_out, u64 iopte_flag)
451{ 526{
452 int result; 527 int result;
453 struct dma_chunk *c; 528 struct dma_chunk *c;
@@ -461,13 +536,13 @@ static int dma_map_pages(struct ps3_dma_region *r, unsigned long phys_addr,
461 536
462 c->region = r; 537 c->region = r;
463 c->lpar_addr = ps3_mm_phys_to_lpar(phys_addr); 538 c->lpar_addr = ps3_mm_phys_to_lpar(phys_addr);
464 c->bus_addr = dma_lpar_to_bus(r, c->lpar_addr); 539 c->bus_addr = dma_sb_lpar_to_bus(r, c->lpar_addr);
465 c->len = len; 540 c->len = len;
466 541
467 result = lv1_map_device_dma_region(c->region->did.bus_id, 542 BUG_ON(iopte_flag != 0xf800000000000000UL);
468 c->region->did.dev_id, c->lpar_addr, c->bus_addr, c->len, 543 result = lv1_map_device_dma_region(c->region->dev->bus_id,
469 0xf800000000000000UL); 544 c->region->dev->dev_id, c->lpar_addr,
470 545 c->bus_addr, c->len, iopte_flag);
471 if (result) { 546 if (result) {
472 DBG("%s:%d: lv1_map_device_dma_region failed: %s\n", 547 DBG("%s:%d: lv1_map_device_dma_region failed: %s\n",
473 __func__, __LINE__, ps3_result(result)); 548 __func__, __LINE__, ps3_result(result));
@@ -487,26 +562,120 @@ fail_alloc:
487 return result; 562 return result;
488} 563}
489 564
565static int dma_ioc0_map_pages(struct ps3_dma_region *r, unsigned long phys_addr,
566 unsigned long len, struct dma_chunk **c_out,
567 u64 iopte_flag)
568{
569 int result;
570 struct dma_chunk *c, *last;
571 int iopage, pages;
572 unsigned long offset;
573
574 DBG(KERN_ERR "%s: phy=%#lx, lpar%#lx, len=%#lx\n", __func__,
575 phys_addr, ps3_mm_phys_to_lpar(phys_addr), len);
576 c = kzalloc(sizeof(struct dma_chunk), GFP_ATOMIC);
577
578 if (!c) {
579 result = -ENOMEM;
580 goto fail_alloc;
581 }
582
583 c->region = r;
584 c->len = len;
585 c->lpar_addr = ps3_mm_phys_to_lpar(phys_addr);
586 /* allocate IO address */
587 if (list_empty(&r->chunk_list.head)) {
588 /* first one */
589 c->bus_addr = r->bus_addr;
590 } else {
591 /* derive from last bus addr*/
592 last = list_entry(r->chunk_list.head.next,
593 struct dma_chunk, link);
594 c->bus_addr = last->bus_addr + last->len;
595 DBG("%s: last bus=%#lx, len=%#lx\n", __func__,
596 last->bus_addr, last->len);
597 }
598
599 /* FIXME: check whether length exceeds region size */
600
601 /* build ioptes for the area */
602 pages = len >> r->page_size;
603 DBG("%s: pgsize=%#x len=%#lx pages=%#x iopteflag=%#lx\n", __func__,
604 r->page_size, r->len, pages, iopte_flag);
605 for (iopage = 0; iopage < pages; iopage++) {
606 offset = (1 << r->page_size) * iopage;
607 result = lv1_put_iopte(0,
608 c->bus_addr + offset,
609 c->lpar_addr + offset,
610 r->ioid,
611 iopte_flag);
612 if (result) {
613 printk(KERN_WARNING "%s:%d: lv1_map_device_dma_region "
614 "failed: %s\n", __func__, __LINE__,
615 ps3_result(result));
616 goto fail_map;
617 }
618 DBG("%s: pg=%d bus=%#lx, lpar=%#lx, ioid=%#x\n", __func__,
619 iopage, c->bus_addr + offset, c->lpar_addr + offset,
620 r->ioid);
621 }
622
623 /* be sure that last allocated one is inserted at head */
624 list_add(&c->link, &r->chunk_list.head);
625
626 *c_out = c;
627 DBG("%s: end\n", __func__);
628 return 0;
629
630fail_map:
631 for (iopage--; 0 <= iopage; iopage--) {
632 lv1_put_iopte(0,
633 c->bus_addr + offset,
634 c->lpar_addr + offset,
635 r->ioid,
636 0);
637 }
638 kfree(c);
639fail_alloc:
640 *c_out = NULL;
641 return result;
642}
643
490/** 644/**
491 * dma_region_create - Create a device dma region. 645 * dma_sb_region_create - Create a device dma region.
492 * @r: Pointer to a struct ps3_dma_region. 646 * @r: Pointer to a struct ps3_dma_region.
493 * 647 *
494 * This is the lowest level dma region create routine, and is the one that 648 * This is the lowest level dma region create routine, and is the one that
495 * will make the HV call to create the region. 649 * will make the HV call to create the region.
496 */ 650 */
497 651
498static int dma_region_create(struct ps3_dma_region* r) 652static int dma_sb_region_create(struct ps3_dma_region *r)
499{ 653{
500 int result; 654 int result;
501 655
502 r->len = _ALIGN_UP(map.total, 1 << r->page_size); 656 pr_info(" -> %s:%d:\n", __func__, __LINE__);
657
658 BUG_ON(!r);
659
660 if (!r->dev->bus_id) {
661 pr_info("%s:%d: %u:%u no dma\n", __func__, __LINE__,
662 r->dev->bus_id, r->dev->dev_id);
663 return 0;
664 }
665
666 DBG("%s:%u: len = 0x%lx, page_size = %u, offset = 0x%lx\n", __func__,
667 __LINE__, r->len, r->page_size, r->offset);
668
669 BUG_ON(!r->len);
670 BUG_ON(!r->page_size);
671 BUG_ON(!r->region_ops);
672
503 INIT_LIST_HEAD(&r->chunk_list.head); 673 INIT_LIST_HEAD(&r->chunk_list.head);
504 spin_lock_init(&r->chunk_list.lock); 674 spin_lock_init(&r->chunk_list.lock);
505 675
506 result = lv1_allocate_device_dma_region(r->did.bus_id, r->did.dev_id, 676 result = lv1_allocate_device_dma_region(r->dev->bus_id, r->dev->dev_id,
507 r->len, r->page_size, r->region_type, &r->bus_addr); 677 roundup_pow_of_two(r->len), r->page_size, r->region_type,
508 678 &r->bus_addr);
509 dma_dump_region(r);
510 679
511 if (result) { 680 if (result) {
512 DBG("%s:%d: lv1_allocate_device_dma_region failed: %s\n", 681 DBG("%s:%d: lv1_allocate_device_dma_region failed: %s\n",
@@ -517,6 +686,27 @@ static int dma_region_create(struct ps3_dma_region* r)
517 return result; 686 return result;
518} 687}
519 688
689static int dma_ioc0_region_create(struct ps3_dma_region *r)
690{
691 int result;
692
693 INIT_LIST_HEAD(&r->chunk_list.head);
694 spin_lock_init(&r->chunk_list.lock);
695
696 result = lv1_allocate_io_segment(0,
697 r->len,
698 r->page_size,
699 &r->bus_addr);
700 if (result) {
701 DBG("%s:%d: lv1_allocate_io_segment failed: %s\n",
702 __func__, __LINE__, ps3_result(result));
703 r->len = r->bus_addr = 0;
704 }
705 DBG("%s: len=%#lx, pg=%d, bus=%#lx\n", __func__,
706 r->len, r->page_size, r->bus_addr);
707 return result;
708}
709
520/** 710/**
521 * dma_region_free - Free a device dma region. 711 * dma_region_free - Free a device dma region.
522 * @r: Pointer to a struct ps3_dma_region. 712 * @r: Pointer to a struct ps3_dma_region.
@@ -525,31 +715,62 @@ static int dma_region_create(struct ps3_dma_region* r)
525 * will make the HV call to free the region. 715 * will make the HV call to free the region.
526 */ 716 */
527 717
528static int dma_region_free(struct ps3_dma_region* r) 718static int dma_sb_region_free(struct ps3_dma_region *r)
529{ 719{
530 int result; 720 int result;
531 struct dma_chunk *c; 721 struct dma_chunk *c;
532 struct dma_chunk *tmp; 722 struct dma_chunk *tmp;
533 723
724 BUG_ON(!r);
725
726 if (!r->dev->bus_id) {
727 pr_info("%s:%d: %u:%u no dma\n", __func__, __LINE__,
728 r->dev->bus_id, r->dev->dev_id);
729 return 0;
730 }
731
534 list_for_each_entry_safe(c, tmp, &r->chunk_list.head, link) { 732 list_for_each_entry_safe(c, tmp, &r->chunk_list.head, link) {
535 list_del(&c->link); 733 list_del(&c->link);
536 dma_free_chunk(c); 734 dma_sb_free_chunk(c);
537 } 735 }
538 736
539 result = lv1_free_device_dma_region(r->did.bus_id, r->did.dev_id, 737 result = lv1_free_device_dma_region(r->dev->bus_id, r->dev->dev_id,
540 r->bus_addr); 738 r->bus_addr);
541 739
542 if (result) 740 if (result)
543 DBG("%s:%d: lv1_free_device_dma_region failed: %s\n", 741 DBG("%s:%d: lv1_free_device_dma_region failed: %s\n",
544 __func__, __LINE__, ps3_result(result)); 742 __func__, __LINE__, ps3_result(result));
545 743
546 r->len = r->bus_addr = 0; 744 r->bus_addr = 0;
745
746 return result;
747}
748
749static int dma_ioc0_region_free(struct ps3_dma_region *r)
750{
751 int result;
752 struct dma_chunk *c, *n;
753
754 DBG("%s: start\n", __func__);
755 list_for_each_entry_safe(c, n, &r->chunk_list.head, link) {
756 list_del(&c->link);
757 dma_ioc0_free_chunk(c);
758 }
759
760 result = lv1_release_io_segment(0, r->bus_addr);
761
762 if (result)
763 DBG("%s:%d: lv1_free_device_dma_region failed: %s\n",
764 __func__, __LINE__, ps3_result(result));
765
766 r->bus_addr = 0;
767 DBG("%s: end\n", __func__);
547 768
548 return result; 769 return result;
549} 770}
550 771
551/** 772/**
552 * dma_map_area - Map an area of memory into a device dma region. 773 * dma_sb_map_area - Map an area of memory into a device dma region.
553 * @r: Pointer to a struct ps3_dma_region. 774 * @r: Pointer to a struct ps3_dma_region.
554 * @virt_addr: Starting virtual address of the area to map. 775 * @virt_addr: Starting virtual address of the area to map.
555 * @len: Length in bytes of the area to map. 776 * @len: Length in bytes of the area to map.
@@ -559,16 +780,19 @@ static int dma_region_free(struct ps3_dma_region* r)
559 * This is the common dma mapping routine. 780 * This is the common dma mapping routine.
560 */ 781 */
561 782
562static int dma_map_area(struct ps3_dma_region *r, unsigned long virt_addr, 783static int dma_sb_map_area(struct ps3_dma_region *r, unsigned long virt_addr,
563 unsigned long len, unsigned long *bus_addr) 784 unsigned long len, unsigned long *bus_addr,
785 u64 iopte_flag)
564{ 786{
565 int result; 787 int result;
566 unsigned long flags; 788 unsigned long flags;
567 struct dma_chunk *c; 789 struct dma_chunk *c;
568 unsigned long phys_addr = is_kernel_addr(virt_addr) ? __pa(virt_addr) 790 unsigned long phys_addr = is_kernel_addr(virt_addr) ? __pa(virt_addr)
569 : virt_addr; 791 : virt_addr;
570 792 unsigned long aligned_phys = _ALIGN_DOWN(phys_addr, 1 << r->page_size);
571 *bus_addr = dma_lpar_to_bus(r, ps3_mm_phys_to_lpar(phys_addr)); 793 unsigned long aligned_len = _ALIGN_UP(len + phys_addr - aligned_phys,
794 1 << r->page_size);
795 *bus_addr = dma_sb_lpar_to_bus(r, ps3_mm_phys_to_lpar(phys_addr));
572 796
573 if (!USE_DYNAMIC_DMA) { 797 if (!USE_DYNAMIC_DMA) {
574 unsigned long lpar_addr = ps3_mm_phys_to_lpar(phys_addr); 798 unsigned long lpar_addr = ps3_mm_phys_to_lpar(phys_addr);
@@ -588,17 +812,18 @@ static int dma_map_area(struct ps3_dma_region *r, unsigned long virt_addr,
588 c = dma_find_chunk(r, *bus_addr, len); 812 c = dma_find_chunk(r, *bus_addr, len);
589 813
590 if (c) { 814 if (c) {
815 DBG("%s:%d: reusing mapped chunk", __func__, __LINE__);
816 dma_dump_chunk(c);
591 c->usage_count++; 817 c->usage_count++;
592 spin_unlock_irqrestore(&r->chunk_list.lock, flags); 818 spin_unlock_irqrestore(&r->chunk_list.lock, flags);
593 return 0; 819 return 0;
594 } 820 }
595 821
596 result = dma_map_pages(r, _ALIGN_DOWN(phys_addr, 1 << r->page_size), 822 result = dma_sb_map_pages(r, aligned_phys, aligned_len, &c, iopte_flag);
597 _ALIGN_UP(len, 1 << r->page_size), &c);
598 823
599 if (result) { 824 if (result) {
600 *bus_addr = 0; 825 *bus_addr = 0;
601 DBG("%s:%d: dma_map_pages failed (%d)\n", 826 DBG("%s:%d: dma_sb_map_pages failed (%d)\n",
602 __func__, __LINE__, result); 827 __func__, __LINE__, result);
603 spin_unlock_irqrestore(&r->chunk_list.lock, flags); 828 spin_unlock_irqrestore(&r->chunk_list.lock, flags);
604 return result; 829 return result;
@@ -610,8 +835,57 @@ static int dma_map_area(struct ps3_dma_region *r, unsigned long virt_addr,
610 return result; 835 return result;
611} 836}
612 837
838static int dma_ioc0_map_area(struct ps3_dma_region *r, unsigned long virt_addr,
839 unsigned long len, unsigned long *bus_addr,
840 u64 iopte_flag)
841{
842 int result;
843 unsigned long flags;
844 struct dma_chunk *c;
845 unsigned long phys_addr = is_kernel_addr(virt_addr) ? __pa(virt_addr)
846 : virt_addr;
847 unsigned long aligned_phys = _ALIGN_DOWN(phys_addr, 1 << r->page_size);
848 unsigned long aligned_len = _ALIGN_UP(len + phys_addr - aligned_phys,
849 1 << r->page_size);
850
851 DBG(KERN_ERR "%s: vaddr=%#lx, len=%#lx\n", __func__,
852 virt_addr, len);
853 DBG(KERN_ERR "%s: ph=%#lx a_ph=%#lx a_l=%#lx\n", __func__,
854 phys_addr, aligned_phys, aligned_len);
855
856 spin_lock_irqsave(&r->chunk_list.lock, flags);
857 c = dma_find_chunk_lpar(r, ps3_mm_phys_to_lpar(phys_addr), len);
858
859 if (c) {
860 /* FIXME */
861 BUG();
862 *bus_addr = c->bus_addr + phys_addr - aligned_phys;
863 c->usage_count++;
864 spin_unlock_irqrestore(&r->chunk_list.lock, flags);
865 return 0;
866 }
867
868 result = dma_ioc0_map_pages(r, aligned_phys, aligned_len, &c,
869 iopte_flag);
870
871 if (result) {
872 *bus_addr = 0;
873 DBG("%s:%d: dma_ioc0_map_pages failed (%d)\n",
874 __func__, __LINE__, result);
875 spin_unlock_irqrestore(&r->chunk_list.lock, flags);
876 return result;
877 }
878 *bus_addr = c->bus_addr + phys_addr - aligned_phys;
879 DBG("%s: va=%#lx pa=%#lx a_pa=%#lx bus=%#lx\n", __func__,
880 virt_addr, phys_addr, aligned_phys, *bus_addr);
881 c->usage_count = 1;
882
883 spin_unlock_irqrestore(&r->chunk_list.lock, flags);
884 return result;
885}
886
613/** 887/**
614 * dma_unmap_area - Unmap an area of memory from a device dma region. 888 * dma_sb_unmap_area - Unmap an area of memory from a device dma region.
615 * @r: Pointer to a struct ps3_dma_region. 889 * @r: Pointer to a struct ps3_dma_region.
616 * @bus_addr: The starting ioc bus address of the area to unmap. 890 * @bus_addr: The starting ioc bus address of the area to unmap.
617 * @len: Length in bytes of the area to unmap. 891 * @len: Length in bytes of the area to unmap.
@@ -619,7 +893,7 @@ static int dma_map_area(struct ps3_dma_region *r, unsigned long virt_addr,
619 * This is the common dma unmap routine. 893 * This is the common dma unmap routine.
620 */ 894 */
621 895
622int dma_unmap_area(struct ps3_dma_region *r, unsigned long bus_addr, 896static int dma_sb_unmap_area(struct ps3_dma_region *r, unsigned long bus_addr,
623 unsigned long len) 897 unsigned long len)
624{ 898{
625 unsigned long flags; 899 unsigned long flags;
@@ -631,7 +905,8 @@ int dma_unmap_area(struct ps3_dma_region *r, unsigned long bus_addr,
631 if (!c) { 905 if (!c) {
632 unsigned long aligned_bus = _ALIGN_DOWN(bus_addr, 906 unsigned long aligned_bus = _ALIGN_DOWN(bus_addr,
633 1 << r->page_size); 907 1 << r->page_size);
634 unsigned long aligned_len = _ALIGN_UP(len, 1 << r->page_size); 908 unsigned long aligned_len = _ALIGN_UP(len + bus_addr
909 - aligned_bus, 1 << r->page_size);
635 DBG("%s:%d: not found: bus_addr %lxh\n", 910 DBG("%s:%d: not found: bus_addr %lxh\n",
636 __func__, __LINE__, bus_addr); 911 __func__, __LINE__, bus_addr);
637 DBG("%s:%d: not found: len %lxh\n", 912 DBG("%s:%d: not found: len %lxh\n",
@@ -647,94 +922,166 @@ int dma_unmap_area(struct ps3_dma_region *r, unsigned long bus_addr,
647 922
648 if (!c->usage_count) { 923 if (!c->usage_count) {
649 list_del(&c->link); 924 list_del(&c->link);
650 dma_free_chunk(c); 925 dma_sb_free_chunk(c);
651 } 926 }
652 927
653 spin_unlock_irqrestore(&r->chunk_list.lock, flags); 928 spin_unlock_irqrestore(&r->chunk_list.lock, flags);
654 return 0; 929 return 0;
655} 930}
656 931
932static int dma_ioc0_unmap_area(struct ps3_dma_region *r,
933 unsigned long bus_addr, unsigned long len)
934{
935 unsigned long flags;
936 struct dma_chunk *c;
937
938 DBG("%s: start a=%#lx l=%#lx\n", __func__, bus_addr, len);
939 spin_lock_irqsave(&r->chunk_list.lock, flags);
940 c = dma_find_chunk(r, bus_addr, len);
941
942 if (!c) {
943 unsigned long aligned_bus = _ALIGN_DOWN(bus_addr,
944 1 << r->page_size);
945 unsigned long aligned_len = _ALIGN_UP(len + bus_addr
946 - aligned_bus,
947 1 << r->page_size);
948 DBG("%s:%d: not found: bus_addr %lxh\n",
949 __func__, __LINE__, bus_addr);
950 DBG("%s:%d: not found: len %lxh\n",
951 __func__, __LINE__, len);
952 DBG("%s:%d: not found: aligned_bus %lxh\n",
953 __func__, __LINE__, aligned_bus);
954 DBG("%s:%d: not found: aligned_len %lxh\n",
955 __func__, __LINE__, aligned_len);
956 BUG();
957 }
958
959 c->usage_count--;
960
961 if (!c->usage_count) {
962 list_del(&c->link);
963 dma_ioc0_free_chunk(c);
964 }
965
966 spin_unlock_irqrestore(&r->chunk_list.lock, flags);
967 DBG("%s: end\n", __func__);
968 return 0;
969}
970
657/** 971/**
658 * dma_region_create_linear - Setup a linear dma maping for a device. 972 * dma_sb_region_create_linear - Setup a linear dma mapping for a device.
659 * @r: Pointer to a struct ps3_dma_region. 973 * @r: Pointer to a struct ps3_dma_region.
660 * 974 *
661 * This routine creates an HV dma region for the device and maps all available 975 * This routine creates an HV dma region for the device and maps all available
662 * ram into the io controller bus address space. 976 * ram into the io controller bus address space.
663 */ 977 */
664 978
665static int dma_region_create_linear(struct ps3_dma_region *r) 979static int dma_sb_region_create_linear(struct ps3_dma_region *r)
666{ 980{
667 int result; 981 int result;
668 unsigned long tmp; 982 unsigned long virt_addr, len, tmp;
669 983
670 /* force 16M dma pages for linear mapping */ 984 if (r->len > 16*1024*1024) { /* FIXME: need proper fix */
671 985 /* force 16M dma pages for linear mapping */
672 if (r->page_size != PS3_DMA_16M) { 986 if (r->page_size != PS3_DMA_16M) {
673 pr_info("%s:%d: forcing 16M pages for linear map\n", 987 pr_info("%s:%d: forcing 16M pages for linear map\n",
674 __func__, __LINE__); 988 __func__, __LINE__);
675 r->page_size = PS3_DMA_16M; 989 r->page_size = PS3_DMA_16M;
990 r->len = _ALIGN_UP(r->len, 1 << r->page_size);
991 }
676 } 992 }
677 993
678 result = dma_region_create(r); 994 result = dma_sb_region_create(r);
679 BUG_ON(result); 995 BUG_ON(result);
680 996
681 result = dma_map_area(r, map.rm.base, map.rm.size, &tmp); 997 if (r->offset < map.rm.size) {
682 BUG_ON(result); 998 /* Map (part of) 1st RAM chunk */
683 999 virt_addr = map.rm.base + r->offset;
684 if (USE_LPAR_ADDR) 1000 len = map.rm.size - r->offset;
685 result = dma_map_area(r, map.r1.base, map.r1.size, 1001 if (len > r->len)
686 &tmp); 1002 len = r->len;
687 else 1003 result = dma_sb_map_area(r, virt_addr, len, &tmp,
688 result = dma_map_area(r, map.rm.size, map.r1.size, 1004 IOPTE_PP_W | IOPTE_PP_R | IOPTE_SO_RW | IOPTE_M);
689 &tmp); 1005 BUG_ON(result);
1006 }
690 1007
691 BUG_ON(result); 1008 if (r->offset + r->len > map.rm.size) {
1009 /* Map (part of) 2nd RAM chunk */
1010 virt_addr = USE_LPAR_ADDR ? map.r1.base : map.rm.size;
1011 len = r->len;
1012 if (r->offset >= map.rm.size)
1013 virt_addr += r->offset - map.rm.size;
1014 else
1015 len -= map.rm.size - r->offset;
1016 result = dma_sb_map_area(r, virt_addr, len, &tmp,
1017 IOPTE_PP_W | IOPTE_PP_R | IOPTE_SO_RW | IOPTE_M);
1018 BUG_ON(result);
1019 }
692 1020
693 return result; 1021 return result;
694} 1022}
695 1023
696/** 1024/**
697 * dma_region_free_linear - Free a linear dma mapping for a device. 1025 * dma_sb_region_free_linear - Free a linear dma mapping for a device.
698 * @r: Pointer to a struct ps3_dma_region. 1026 * @r: Pointer to a struct ps3_dma_region.
699 * 1027 *
700 * This routine will unmap all mapped areas and free the HV dma region. 1028 * This routine will unmap all mapped areas and free the HV dma region.
701 */ 1029 */
702 1030
703static int dma_region_free_linear(struct ps3_dma_region *r) 1031static int dma_sb_region_free_linear(struct ps3_dma_region *r)
704{ 1032{
705 int result; 1033 int result;
1034 unsigned long bus_addr, len, lpar_addr;
1035
1036 if (r->offset < map.rm.size) {
1037 /* Unmap (part of) 1st RAM chunk */
1038 lpar_addr = map.rm.base + r->offset;
1039 len = map.rm.size - r->offset;
1040 if (len > r->len)
1041 len = r->len;
1042 bus_addr = dma_sb_lpar_to_bus(r, lpar_addr);
1043 result = dma_sb_unmap_area(r, bus_addr, len);
1044 BUG_ON(result);
1045 }
706 1046
707 result = dma_unmap_area(r, dma_lpar_to_bus(r, 0), map.rm.size); 1047 if (r->offset + r->len > map.rm.size) {
708 BUG_ON(result); 1048 /* Unmap (part of) 2nd RAM chunk */
709 1049 lpar_addr = map.r1.base;
710 result = dma_unmap_area(r, dma_lpar_to_bus(r, map.r1.base), 1050 len = r->len;
711 map.r1.size); 1051 if (r->offset >= map.rm.size)
712 BUG_ON(result); 1052 lpar_addr += r->offset - map.rm.size;
1053 else
1054 len -= map.rm.size - r->offset;
1055 bus_addr = dma_sb_lpar_to_bus(r, lpar_addr);
1056 result = dma_sb_unmap_area(r, bus_addr, len);
1057 BUG_ON(result);
1058 }
713 1059
714 result = dma_region_free(r); 1060 result = dma_sb_region_free(r);
715 BUG_ON(result); 1061 BUG_ON(result);
716 1062
717 return result; 1063 return result;
718} 1064}
719 1065
720/** 1066/**
721 * dma_map_area_linear - Map an area of memory into a device dma region. 1067 * dma_sb_map_area_linear - Map an area of memory into a device dma region.
722 * @r: Pointer to a struct ps3_dma_region. 1068 * @r: Pointer to a struct ps3_dma_region.
723 * @virt_addr: Starting virtual address of the area to map. 1069 * @virt_addr: Starting virtual address of the area to map.
724 * @len: Length in bytes of the area to map. 1070 * @len: Length in bytes of the area to map.
725 * @bus_addr: A pointer to return the starting ioc bus address of the area to 1071 * @bus_addr: A pointer to return the starting ioc bus address of the area to
726 * map. 1072 * map.
727 * 1073 *
728 * This routine just returns the coresponding bus address. Actual mapping 1074 * This routine just returns the corresponding bus address. Actual mapping
729 * occurs in dma_region_create_linear(). 1075 * occurs in dma_region_create_linear().
730 */ 1076 */
731 1077
732static int dma_map_area_linear(struct ps3_dma_region *r, 1078static int dma_sb_map_area_linear(struct ps3_dma_region *r,
733 unsigned long virt_addr, unsigned long len, unsigned long *bus_addr) 1079 unsigned long virt_addr, unsigned long len, unsigned long *bus_addr,
1080 u64 iopte_flag)
734{ 1081{
735 unsigned long phys_addr = is_kernel_addr(virt_addr) ? __pa(virt_addr) 1082 unsigned long phys_addr = is_kernel_addr(virt_addr) ? __pa(virt_addr)
736 : virt_addr; 1083 : virt_addr;
737 *bus_addr = dma_lpar_to_bus(r, ps3_mm_phys_to_lpar(phys_addr)); 1084 *bus_addr = dma_sb_lpar_to_bus(r, ps3_mm_phys_to_lpar(phys_addr));
738 return 0; 1085 return 0;
739} 1086}
740 1087
@@ -744,42 +1091,98 @@ static int dma_map_area_linear(struct ps3_dma_region *r,
744 * @bus_addr: The starting ioc bus address of the area to unmap. 1091 * @bus_addr: The starting ioc bus address of the area to unmap.
745 * @len: Length in bytes of the area to unmap. 1092 * @len: Length in bytes of the area to unmap.
746 * 1093 *
747 * This routine does nothing. Unmapping occurs in dma_region_free_linear(). 1094 * This routine does nothing. Unmapping occurs in dma_sb_region_free_linear().
748 */ 1095 */
749 1096
750static int dma_unmap_area_linear(struct ps3_dma_region *r, 1097static int dma_sb_unmap_area_linear(struct ps3_dma_region *r,
751 unsigned long bus_addr, unsigned long len) 1098 unsigned long bus_addr, unsigned long len)
752{ 1099{
753 return 0; 1100 return 0;
1101};
1102
1103static const struct ps3_dma_region_ops ps3_dma_sb_region_ops = {
1104 .create = dma_sb_region_create,
1105 .free = dma_sb_region_free,
1106 .map = dma_sb_map_area,
1107 .unmap = dma_sb_unmap_area
1108};
1109
1110static const struct ps3_dma_region_ops ps3_dma_sb_region_linear_ops = {
1111 .create = dma_sb_region_create_linear,
1112 .free = dma_sb_region_free_linear,
1113 .map = dma_sb_map_area_linear,
1114 .unmap = dma_sb_unmap_area_linear
1115};
1116
1117static const struct ps3_dma_region_ops ps3_dma_ioc0_region_ops = {
1118 .create = dma_ioc0_region_create,
1119 .free = dma_ioc0_region_free,
1120 .map = dma_ioc0_map_area,
1121 .unmap = dma_ioc0_unmap_area
1122};
1123
1124int ps3_dma_region_init(struct ps3_system_bus_device *dev,
1125 struct ps3_dma_region *r, enum ps3_dma_page_size page_size,
1126 enum ps3_dma_region_type region_type, void *addr, unsigned long len)
1127{
1128 unsigned long lpar_addr;
1129
1130 lpar_addr = addr ? ps3_mm_phys_to_lpar(__pa(addr)) : 0;
1131
1132 r->dev = dev;
1133 r->page_size = page_size;
1134 r->region_type = region_type;
1135 r->offset = lpar_addr;
1136 if (r->offset >= map.rm.size)
1137 r->offset -= map.r1.offset;
1138 r->len = len ? len : _ALIGN_UP(map.total, 1 << r->page_size);
1139
1140 switch (dev->dev_type) {
1141 case PS3_DEVICE_TYPE_SB:
1142 r->region_ops = (USE_DYNAMIC_DMA)
1143 ? &ps3_dma_sb_region_ops
1144 : &ps3_dma_sb_region_linear_ops;
1145 break;
1146 case PS3_DEVICE_TYPE_IOC0:
1147 r->region_ops = &ps3_dma_ioc0_region_ops;
1148 break;
1149 default:
1150 BUG();
1151 return -EINVAL;
1152 }
1153 return 0;
754} 1154}
1155EXPORT_SYMBOL(ps3_dma_region_init);
755 1156
756int ps3_dma_region_create(struct ps3_dma_region *r) 1157int ps3_dma_region_create(struct ps3_dma_region *r)
757{ 1158{
758 return (USE_DYNAMIC_DMA) 1159 BUG_ON(!r);
759 ? dma_region_create(r) 1160 BUG_ON(!r->region_ops);
760 : dma_region_create_linear(r); 1161 BUG_ON(!r->region_ops->create);
1162 return r->region_ops->create(r);
761} 1163}
1164EXPORT_SYMBOL(ps3_dma_region_create);
762 1165
763int ps3_dma_region_free(struct ps3_dma_region *r) 1166int ps3_dma_region_free(struct ps3_dma_region *r)
764{ 1167{
765 return (USE_DYNAMIC_DMA) 1168 BUG_ON(!r);
766 ? dma_region_free(r) 1169 BUG_ON(!r->region_ops);
767 : dma_region_free_linear(r); 1170 BUG_ON(!r->region_ops->free);
1171 return r->region_ops->free(r);
768} 1172}
1173EXPORT_SYMBOL(ps3_dma_region_free);
769 1174
770int ps3_dma_map(struct ps3_dma_region *r, unsigned long virt_addr, 1175int ps3_dma_map(struct ps3_dma_region *r, unsigned long virt_addr,
771 unsigned long len, unsigned long *bus_addr) 1176 unsigned long len, unsigned long *bus_addr,
1177 u64 iopte_flag)
772{ 1178{
773 return (USE_DYNAMIC_DMA) 1179 return r->region_ops->map(r, virt_addr, len, bus_addr, iopte_flag);
774 ? dma_map_area(r, virt_addr, len, bus_addr)
775 : dma_map_area_linear(r, virt_addr, len, bus_addr);
776} 1180}
777 1181
778int ps3_dma_unmap(struct ps3_dma_region *r, unsigned long bus_addr, 1182int ps3_dma_unmap(struct ps3_dma_region *r, unsigned long bus_addr,
779 unsigned long len) 1183 unsigned long len)
780{ 1184{
781 return (USE_DYNAMIC_DMA) ? dma_unmap_area(r, bus_addr, len) 1185 return r->region_ops->unmap(r, bus_addr, len);
782 : dma_unmap_area_linear(r, bus_addr, len);
783} 1186}
784 1187
785/*============================================================================*/ 1188/*============================================================================*/
@@ -810,12 +1213,13 @@ void __init ps3_mm_init(void)
810 BUG_ON(map.rm.base); 1213 BUG_ON(map.rm.base);
811 BUG_ON(!map.rm.size); 1214 BUG_ON(!map.rm.size);
812 1215
813 lmb_add(map.rm.base, map.rm.size);
814 lmb_analyze();
815 1216
816 /* arrange to do this in ps3_mm_add_memory */ 1217 /* arrange to do this in ps3_mm_add_memory */
817 ps3_mm_region_create(&map.r1, map.total - map.rm.size); 1218 ps3_mm_region_create(&map.r1, map.total - map.rm.size);
818 1219
1220 /* correct map.total for the real total amount of memory we use */
1221 map.total = map.rm.size + map.r1.size;
1222
819 DBG(" <- %s:%d\n", __func__, __LINE__); 1223 DBG(" <- %s:%d\n", __func__, __LINE__);
820} 1224}
821 1225
diff --git a/arch/powerpc/platforms/ps3/os-area.c b/arch/powerpc/platforms/ps3/os-area.c
index 5c3da08bc0c4..b70e474014f0 100644
--- a/arch/powerpc/platforms/ps3/os-area.c
+++ b/arch/powerpc/platforms/ps3/os-area.c
@@ -133,7 +133,7 @@ struct saved_params {
133} static saved_params; 133} static saved_params;
134 134
135#define dump_header(_a) _dump_header(_a, __func__, __LINE__) 135#define dump_header(_a) _dump_header(_a, __func__, __LINE__)
136static void _dump_header(const struct os_area_header __iomem *h, const char* func, 136static void _dump_header(const struct os_area_header *h, const char *func,
137 int line) 137 int line)
138{ 138{
139 pr_debug("%s:%d: h.magic_num: '%s'\n", func, line, 139 pr_debug("%s:%d: h.magic_num: '%s'\n", func, line,
@@ -151,7 +151,7 @@ static void _dump_header(const struct os_area_header __iomem *h, const char* fun
151} 151}
152 152
153#define dump_params(_a) _dump_params(_a, __func__, __LINE__) 153#define dump_params(_a) _dump_params(_a, __func__, __LINE__)
154static void _dump_params(const struct os_area_params __iomem *p, const char* func, 154static void _dump_params(const struct os_area_params *p, const char *func,
155 int line) 155 int line)
156{ 156{
157 pr_debug("%s:%d: p.boot_flag: %u\n", func, line, p->boot_flag); 157 pr_debug("%s:%d: p.boot_flag: %u\n", func, line, p->boot_flag);
diff --git a/arch/powerpc/platforms/ps3/platform.h b/arch/powerpc/platforms/ps3/platform.h
index ca04f03305c7..87d52060fec0 100644
--- a/arch/powerpc/platforms/ps3/platform.h
+++ b/arch/powerpc/platforms/ps3/platform.h
@@ -41,6 +41,7 @@ void ps3_mm_shutdown(void);
41/* irq */ 41/* irq */
42 42
43void ps3_init_IRQ(void); 43void ps3_init_IRQ(void);
44void ps3_shutdown_IRQ(int cpu);
44void __init ps3_register_ipi_debug_brk(unsigned int cpu, unsigned int virq); 45void __init ps3_register_ipi_debug_brk(unsigned int cpu, unsigned int virq);
45 46
46/* smp */ 47/* smp */
@@ -82,6 +83,7 @@ enum ps3_dev_type {
82 PS3_DEV_TYPE_STOR_ROM = TYPE_ROM, /* 5 */ 83 PS3_DEV_TYPE_STOR_ROM = TYPE_ROM, /* 5 */
83 PS3_DEV_TYPE_SB_GPIO = 6, 84 PS3_DEV_TYPE_SB_GPIO = 6,
84 PS3_DEV_TYPE_STOR_FLASH = TYPE_RBC, /* 14 */ 85 PS3_DEV_TYPE_STOR_FLASH = TYPE_RBC, /* 14 */
86 PS3_DEV_TYPE_NOACCESS = 255,
85}; 87};
86 88
87int ps3_repository_read_bus_str(unsigned int bus_index, const char *bus_str, 89int ps3_repository_read_bus_str(unsigned int bus_index, const char *bus_str,
@@ -129,24 +131,28 @@ int ps3_repository_read_dev_reg(unsigned int bus_index,
129/* repository bus enumerators */ 131/* repository bus enumerators */
130 132
131struct ps3_repository_device { 133struct ps3_repository_device {
134 enum ps3_bus_type bus_type;
132 unsigned int bus_index; 135 unsigned int bus_index;
136 unsigned int bus_id;
137 enum ps3_dev_type dev_type;
133 unsigned int dev_index; 138 unsigned int dev_index;
134 struct ps3_device_id did; 139 unsigned int dev_id;
135}; 140};
136 141
137int ps3_repository_find_device(enum ps3_bus_type bus_type, 142static inline struct ps3_repository_device *ps3_repository_bump_device(
138 enum ps3_dev_type dev_type, 143 struct ps3_repository_device *repo)
139 const struct ps3_repository_device *start_dev,
140 struct ps3_repository_device *dev);
141static inline int ps3_repository_find_first_device(
142 enum ps3_bus_type bus_type, enum ps3_dev_type dev_type,
143 struct ps3_repository_device *dev)
144{ 144{
145 return ps3_repository_find_device(bus_type, dev_type, NULL, dev); 145 repo->dev_index++;
146 return repo;
146} 147}
147int ps3_repository_find_interrupt(const struct ps3_repository_device *dev, 148int ps3_repository_find_device(struct ps3_repository_device *repo);
149int ps3_repository_find_devices(enum ps3_bus_type bus_type,
150 int (*callback)(const struct ps3_repository_device *repo));
151int ps3_repository_find_bus(enum ps3_bus_type bus_type, unsigned int from,
152 unsigned int *bus_index);
153int ps3_repository_find_interrupt(const struct ps3_repository_device *repo,
148 enum ps3_interrupt_type intr_type, unsigned int *interrupt_id); 154 enum ps3_interrupt_type intr_type, unsigned int *interrupt_id);
149int ps3_repository_find_reg(const struct ps3_repository_device *dev, 155int ps3_repository_find_reg(const struct ps3_repository_device *repo,
150 enum ps3_reg_type reg_type, u64 *bus_addr, u64 *len); 156 enum ps3_reg_type reg_type, u64 *bus_addr, u64 *len);
151 157
152/* repository block device info */ 158/* repository block device info */
@@ -216,4 +222,19 @@ int ps3_repository_read_num_spu_resource_id(unsigned int *num_resource_id);
216int ps3_repository_read_spu_resource_id(unsigned int res_index, 222int ps3_repository_read_spu_resource_id(unsigned int res_index,
217 enum ps3_spu_resource_type* resource_type, unsigned int *resource_id); 223 enum ps3_spu_resource_type* resource_type, unsigned int *resource_id);
218 224
225/* repository vuart info */
226
227int ps3_repository_read_vuart_av_port(unsigned int *port);
228int ps3_repository_read_vuart_sysmgr_port(unsigned int *port);
229
230/* Page table entries */
231#define IOPTE_PP_W 0x8000000000000000ul /* protection: write */
232#define IOPTE_PP_R 0x4000000000000000ul /* protection: read */
233#define IOPTE_M 0x2000000000000000ul /* coherency required */
234#define IOPTE_SO_R 0x1000000000000000ul /* ordering: writes */
235#define IOPTE_SO_RW 0x1800000000000000ul /* ordering: r & w */
236#define IOPTE_RPN_Mask 0x07fffffffffff000ul /* RPN */
237#define IOPTE_H 0x0000000000000800ul /* cache hint */
238#define IOPTE_IOID_Mask 0x00000000000007fful /* ioid */
239
219#endif 240#endif
diff --git a/arch/powerpc/platforms/ps3/repository.c b/arch/powerpc/platforms/ps3/repository.c
index ae586a0e5d3f..8cc37cfea0f2 100644
--- a/arch/powerpc/platforms/ps3/repository.c
+++ b/arch/powerpc/platforms/ps3/repository.c
@@ -138,7 +138,7 @@ static int read_node(unsigned int lpar_id, u64 n1, u64 n2, u64 n3, u64 n4,
138 pr_debug("%s:%d: lv1_get_repository_node_value failed: %s\n", 138 pr_debug("%s:%d: lv1_get_repository_node_value failed: %s\n",
139 __func__, __LINE__, ps3_result(result)); 139 __func__, __LINE__, ps3_result(result));
140 dump_node_name(lpar_id, n1, n2, n3, n4); 140 dump_node_name(lpar_id, n1, n2, n3, n4);
141 return result; 141 return -ENOENT;
142 } 142 }
143 143
144 dump_node(lpar_id, n1, n2, n3, n4, v1, v2); 144 dump_node(lpar_id, n1, n2, n3, n4, v1, v2);
@@ -155,7 +155,7 @@ static int read_node(unsigned int lpar_id, u64 n1, u64 n2, u64 n3, u64 n4,
155 pr_debug("%s:%d: warning: discarding non-zero v2: %016lx\n", 155 pr_debug("%s:%d: warning: discarding non-zero v2: %016lx\n",
156 __func__, __LINE__, v2); 156 __func__, __LINE__, v2);
157 157
158 return result; 158 return 0;
159} 159}
160 160
161int ps3_repository_read_bus_str(unsigned int bus_index, const char *bus_str, 161int ps3_repository_read_bus_str(unsigned int bus_index, const char *bus_str,
@@ -314,324 +314,140 @@ int ps3_repository_read_dev_reg(unsigned int bus_index,
314 reg_index, bus_addr, len); 314 reg_index, bus_addr, len);
315} 315}
316 316
317#if defined(DEBUG)
318int ps3_repository_dump_resource_info(unsigned int bus_index,
319 unsigned int dev_index)
320{
321 int result = 0;
322 unsigned int res_index;
323 317
324 pr_debug(" -> %s:%d: (%u:%u)\n", __func__, __LINE__,
325 bus_index, dev_index);
326 318
327 for (res_index = 0; res_index < 10; res_index++) { 319int ps3_repository_find_device(struct ps3_repository_device *repo)
328 enum ps3_interrupt_type intr_type; 320{
329 unsigned int interrupt_id; 321 int result;
322 struct ps3_repository_device tmp = *repo;
323 unsigned int num_dev;
330 324
331 result = ps3_repository_read_dev_intr(bus_index, dev_index, 325 BUG_ON(repo->bus_index > 10);
332 res_index, &intr_type, &interrupt_id); 326 BUG_ON(repo->dev_index > 10);
333 327
334 if (result) { 328 result = ps3_repository_read_bus_num_dev(tmp.bus_index, &num_dev);
335 if (result != LV1_NO_ENTRY)
336 pr_debug("%s:%d ps3_repository_read_dev_intr"
337 " (%u:%u) failed\n", __func__, __LINE__,
338 bus_index, dev_index);
339 break;
340 }
341 329
342 pr_debug("%s:%d (%u:%u) intr_type %u, interrupt_id %u\n", 330 if (result) {
343 __func__, __LINE__, bus_index, dev_index, intr_type, 331 pr_debug("%s:%d read_bus_num_dev failed\n", __func__, __LINE__);
344 interrupt_id); 332 return result;
345 } 333 }
346 334
347 for (res_index = 0; res_index < 10; res_index++) { 335 pr_debug("%s:%d: bus_type %u, bus_index %u, bus_id %u, num_dev %u\n",
348 enum ps3_reg_type reg_type; 336 __func__, __LINE__, tmp.bus_type, tmp.bus_index, tmp.bus_id,
349 u64 bus_addr; 337 num_dev);
350 u64 len;
351
352 result = ps3_repository_read_dev_reg(bus_index, dev_index,
353 res_index, &reg_type, &bus_addr, &len);
354 338
355 if (result) { 339 if (tmp.dev_index >= num_dev) {
356 if (result != LV1_NO_ENTRY) 340 pr_debug("%s:%d: no device found\n", __func__, __LINE__);
357 pr_debug("%s:%d ps3_repository_read_dev_reg" 341 return -ENODEV;
358 " (%u:%u) failed\n", __func__, __LINE__,
359 bus_index, dev_index);
360 break;
361 }
362
363 pr_debug("%s:%d (%u:%u) reg_type %u, bus_addr %lxh, len %lxh\n",
364 __func__, __LINE__, bus_index, dev_index, reg_type,
365 bus_addr, len);
366 } 342 }
367 343
368 pr_debug(" <- %s:%d\n", __func__, __LINE__); 344 result = ps3_repository_read_dev_type(tmp.bus_index, tmp.dev_index,
369 return result; 345 &tmp.dev_type);
370}
371
372static int dump_stor_dev_info(unsigned int bus_index, unsigned int dev_index)
373{
374 int result = 0;
375 unsigned int num_regions, region_index;
376 u64 port, blk_size, num_blocks;
377
378 pr_debug(" -> %s:%d: (%u:%u)\n", __func__, __LINE__,
379 bus_index, dev_index);
380 346
381 result = ps3_repository_read_stor_dev_info(bus_index, dev_index, &port,
382 &blk_size, &num_blocks, &num_regions);
383 if (result) { 347 if (result) {
384 pr_debug("%s:%d ps3_repository_read_stor_dev_info" 348 pr_debug("%s:%d read_dev_type failed\n", __func__, __LINE__);
385 " (%u:%u) failed\n", __func__, __LINE__, 349 return result;
386 bus_index, dev_index);
387 goto out;
388 } 350 }
389 351
390 pr_debug("%s:%d (%u:%u): port %lu, blk_size %lu, num_blocks " 352 result = ps3_repository_read_dev_id(tmp.bus_index, tmp.dev_index,
391 "%lu, num_regions %u\n", 353 &tmp.dev_id);
392 __func__, __LINE__, bus_index, dev_index, port,
393 blk_size, num_blocks, num_regions);
394
395 for (region_index = 0; region_index < num_regions; region_index++) {
396 unsigned int region_id;
397 u64 region_start, region_size;
398
399 result = ps3_repository_read_stor_dev_region(bus_index,
400 dev_index, region_index, &region_id, &region_start,
401 &region_size);
402 if (result) {
403 pr_debug("%s:%d ps3_repository_read_stor_dev_region"
404 " (%u:%u) failed\n", __func__, __LINE__,
405 bus_index, dev_index);
406 break;
407 }
408 354
409 pr_debug("%s:%d (%u:%u) region_id %u, start %lxh, size %lxh\n", 355 if (result) {
410 __func__, __LINE__, bus_index, dev_index, region_id, 356 pr_debug("%s:%d ps3_repository_read_dev_id failed\n", __func__,
411 region_start, region_size); 357 __LINE__);
358 return result;
412 } 359 }
413 360
414out: 361 pr_debug("%s:%d: found: dev_type %u, dev_index %u, dev_id %u\n",
415 pr_debug(" <- %s:%d\n", __func__, __LINE__); 362 __func__, __LINE__, tmp.dev_type, tmp.dev_index, tmp.dev_id);
416 return result;
417}
418
419static int dump_device_info(unsigned int bus_index, enum ps3_bus_type bus_type,
420 unsigned int num_dev)
421{
422 int result = 0;
423 unsigned int dev_index;
424
425 pr_debug(" -> %s:%d: bus_%u\n", __func__, __LINE__, bus_index);
426
427 for (dev_index = 0; dev_index < num_dev; dev_index++) {
428 enum ps3_dev_type dev_type;
429 unsigned int dev_id;
430
431 result = ps3_repository_read_dev_type(bus_index, dev_index,
432 &dev_type);
433
434 if (result) {
435 pr_debug("%s:%d ps3_repository_read_dev_type"
436 " (%u:%u) failed\n", __func__, __LINE__,
437 bus_index, dev_index);
438 break;
439 }
440
441 result = ps3_repository_read_dev_id(bus_index, dev_index,
442 &dev_id);
443
444 if (result) {
445 pr_debug("%s:%d ps3_repository_read_dev_id"
446 " (%u:%u) failed\n", __func__, __LINE__,
447 bus_index, dev_index);
448 continue;
449 }
450 363
451 pr_debug("%s:%d (%u:%u): dev_type %u, dev_id %u\n", __func__, 364 *repo = tmp;
452 __LINE__, bus_index, dev_index, dev_type, dev_id); 365 return 0;
453
454 ps3_repository_dump_resource_info(bus_index, dev_index);
455
456 if (bus_type == PS3_BUS_TYPE_STORAGE)
457 dump_stor_dev_info(bus_index, dev_index);
458 }
459
460 pr_debug(" <- %s:%d\n", __func__, __LINE__);
461 return result;
462} 366}
463 367
464int ps3_repository_dump_bus_info(void) 368int __devinit ps3_repository_find_devices(enum ps3_bus_type bus_type,
369 int (*callback)(const struct ps3_repository_device *repo))
465{ 370{
466 int result = 0; 371 int result = 0;
467 unsigned int bus_index; 372 struct ps3_repository_device repo;
468 373
469 pr_debug(" -> %s:%d\n", __func__, __LINE__); 374 pr_debug(" -> %s:%d: find bus_type %u\n", __func__, __LINE__, bus_type);
470 375
471 for (bus_index = 0; bus_index < 10; bus_index++) { 376 for (repo.bus_index = 0; repo.bus_index < 10; repo.bus_index++) {
472 enum ps3_bus_type bus_type;
473 unsigned int bus_id;
474 unsigned int num_dev;
475 377
476 result = ps3_repository_read_bus_type(bus_index, &bus_type); 378 result = ps3_repository_read_bus_type(repo.bus_index,
379 &repo.bus_type);
477 380
478 if (result) { 381 if (result) {
479 pr_debug("%s:%d read_bus_type(%u) failed\n", 382 pr_debug("%s:%d read_bus_type(%u) failed\n",
480 __func__, __LINE__, bus_index); 383 __func__, __LINE__, repo.bus_index);
481 break; 384 break;
482 } 385 }
483 386
484 result = ps3_repository_read_bus_id(bus_index, &bus_id); 387 if (repo.bus_type != bus_type) {
485 388 pr_debug("%s:%d: skip, bus_type %u\n", __func__,
486 if (result) { 389 __LINE__, repo.bus_type);
487 pr_debug("%s:%d read_bus_id(%u) failed\n",
488 __func__, __LINE__, bus_index);
489 continue; 390 continue;
490 } 391 }
491 392
492 if (bus_index != bus_id) 393 result = ps3_repository_read_bus_id(repo.bus_index,
493 pr_debug("%s:%d bus_index != bus_id\n", 394 &repo.bus_id);
494 __func__, __LINE__);
495
496 result = ps3_repository_read_bus_num_dev(bus_index, &num_dev);
497 395
498 if (result) { 396 if (result) {
499 pr_debug("%s:%d read_bus_num_dev(%u) failed\n", 397 pr_debug("%s:%d read_bus_id(%u) failed\n",
500 __func__, __LINE__, bus_index); 398 __func__, __LINE__, repo.bus_index);
501 continue; 399 continue;
502 } 400 }
503 401
504 pr_debug("%s:%d bus_%u: bus_type %u, bus_id %u, num_dev %u\n", 402 for (repo.dev_index = 0; ; repo.dev_index++) {
505 __func__, __LINE__, bus_index, bus_type, bus_id, 403 result = ps3_repository_find_device(&repo);
506 num_dev);
507 404
508 dump_device_info(bus_index, bus_type, num_dev); 405 if (result == -ENODEV) {
509 } 406 result = 0;
407 break;
408 } else if (result)
409 break;
510 410
511 pr_debug(" <- %s:%d\n", __func__, __LINE__); 411 result = callback(&repo);
512 return result;
513}
514#endif /* defined(DEBUG) */
515
516static int find_device(unsigned int bus_index, unsigned int num_dev,
517 unsigned int start_dev_index, enum ps3_dev_type dev_type,
518 struct ps3_repository_device *dev)
519{
520 int result = 0;
521 unsigned int dev_index;
522 412
523 pr_debug("%s:%d: find dev_type %u\n", __func__, __LINE__, dev_type); 413 if (result) {
524 414 pr_debug("%s:%d: abort at callback\n", __func__,
525 dev->dev_index = UINT_MAX; 415 __LINE__);
526 416 break;
527 for (dev_index = start_dev_index; dev_index < num_dev; dev_index++) { 417 }
528 enum ps3_dev_type x;
529
530 result = ps3_repository_read_dev_type(bus_index, dev_index,
531 &x);
532
533 if (result) {
534 pr_debug("%s:%d read_dev_type failed\n",
535 __func__, __LINE__);
536 return result;
537 } 418 }
538 419 break;
539 if (x == dev_type)
540 break;
541 }
542
543 if (dev_index == num_dev)
544 return -1;
545
546 pr_debug("%s:%d: found dev_type %u at dev_index %u\n",
547 __func__, __LINE__, dev_type, dev_index);
548
549 result = ps3_repository_read_dev_id(bus_index, dev_index,
550 &dev->did.dev_id);
551
552 if (result) {
553 pr_debug("%s:%d read_dev_id failed\n",
554 __func__, __LINE__);
555 return result;
556 } 420 }
557 421
558 dev->dev_index = dev_index; 422 pr_debug(" <- %s:%d\n", __func__, __LINE__);
559
560 pr_debug("%s:%d found: dev_id %u\n", __func__, __LINE__,
561 dev->did.dev_id);
562
563 return result; 423 return result;
564} 424}
565 425
566int ps3_repository_find_device (enum ps3_bus_type bus_type, 426int ps3_repository_find_bus(enum ps3_bus_type bus_type, unsigned int from,
567 enum ps3_dev_type dev_type, 427 unsigned int *bus_index)
568 const struct ps3_repository_device *start_dev,
569 struct ps3_repository_device *dev)
570{ 428{
571 int result = 0; 429 unsigned int i;
572 unsigned int bus_index; 430 enum ps3_bus_type type;
573 unsigned int num_dev; 431 int error;
574
575 pr_debug("%s:%d: find bus_type %u, dev_type %u\n", __func__, __LINE__,
576 bus_type, dev_type);
577
578 BUG_ON(start_dev && start_dev->bus_index > 10);
579
580 for (bus_index = start_dev ? start_dev->bus_index : 0; bus_index < 10;
581 bus_index++) {
582 enum ps3_bus_type x;
583
584 result = ps3_repository_read_bus_type(bus_index, &x);
585 432
586 if (result) { 433 for (i = from; i < 10; i++) {
434 error = ps3_repository_read_bus_type(i, &type);
435 if (error) {
587 pr_debug("%s:%d read_bus_type failed\n", 436 pr_debug("%s:%d read_bus_type failed\n",
588 __func__, __LINE__); 437 __func__, __LINE__);
589 dev->bus_index = UINT_MAX; 438 *bus_index = UINT_MAX;
590 return result; 439 return error;
440 }
441 if (type == bus_type) {
442 *bus_index = i;
443 return 0;
591 } 444 }
592 if (x == bus_type)
593 break;
594 }
595
596 if (bus_index >= 10)
597 return -ENODEV;
598
599 pr_debug("%s:%d: found bus_type %u at bus_index %u\n",
600 __func__, __LINE__, bus_type, bus_index);
601
602 result = ps3_repository_read_bus_num_dev(bus_index, &num_dev);
603
604 if (result) {
605 pr_debug("%s:%d read_bus_num_dev failed\n",
606 __func__, __LINE__);
607 return result;
608 }
609
610 result = find_device(bus_index, num_dev, start_dev
611 ? start_dev->dev_index + 1 : 0, dev_type, dev);
612
613 if (result) {
614 pr_debug("%s:%d get_did failed\n", __func__, __LINE__);
615 return result;
616 }
617
618 result = ps3_repository_read_bus_id(bus_index, &dev->did.bus_id);
619
620 if (result) {
621 pr_debug("%s:%d read_bus_id failed\n",
622 __func__, __LINE__);
623 return result;
624 } 445 }
625 446 *bus_index = UINT_MAX;
626 dev->bus_index = bus_index; 447 return -ENODEV;
627
628 pr_debug("%s:%d found: bus_id %u, dev_id %u\n",
629 __func__, __LINE__, dev->did.bus_id, dev->did.dev_id);
630
631 return result;
632} 448}
633 449
634int ps3_repository_find_interrupt(const struct ps3_repository_device *dev, 450int ps3_repository_find_interrupt(const struct ps3_repository_device *repo,
635 enum ps3_interrupt_type intr_type, unsigned int *interrupt_id) 451 enum ps3_interrupt_type intr_type, unsigned int *interrupt_id)
636{ 452{
637 int result = 0; 453 int result = 0;
@@ -645,8 +461,8 @@ int ps3_repository_find_interrupt(const struct ps3_repository_device *dev,
645 enum ps3_interrupt_type t; 461 enum ps3_interrupt_type t;
646 unsigned int id; 462 unsigned int id;
647 463
648 result = ps3_repository_read_dev_intr(dev->bus_index, 464 result = ps3_repository_read_dev_intr(repo->bus_index,
649 dev->dev_index, res_index, &t, &id); 465 repo->dev_index, res_index, &t, &id);
650 466
651 if (result) { 467 if (result) {
652 pr_debug("%s:%d read_dev_intr failed\n", 468 pr_debug("%s:%d read_dev_intr failed\n",
@@ -669,7 +485,7 @@ int ps3_repository_find_interrupt(const struct ps3_repository_device *dev,
669 return result; 485 return result;
670} 486}
671 487
672int ps3_repository_find_reg(const struct ps3_repository_device *dev, 488int ps3_repository_find_reg(const struct ps3_repository_device *repo,
673 enum ps3_reg_type reg_type, u64 *bus_addr, u64 *len) 489 enum ps3_reg_type reg_type, u64 *bus_addr, u64 *len)
674{ 490{
675 int result = 0; 491 int result = 0;
@@ -684,8 +500,8 @@ int ps3_repository_find_reg(const struct ps3_repository_device *dev,
684 u64 a; 500 u64 a;
685 u64 l; 501 u64 l;
686 502
687 result = ps3_repository_read_dev_reg(dev->bus_index, 503 result = ps3_repository_read_dev_reg(repo->bus_index,
688 dev->dev_index, res_index, &t, &a, &l); 504 repo->dev_index, res_index, &t, &a, &l);
689 505
690 if (result) { 506 if (result) {
691 pr_debug("%s:%d read_dev_reg failed\n", 507 pr_debug("%s:%d read_dev_reg failed\n",
@@ -965,6 +781,36 @@ int ps3_repository_read_boot_dat_size(unsigned int *size)
965 return result; 781 return result;
966} 782}
967 783
784int ps3_repository_read_vuart_av_port(unsigned int *port)
785{
786 int result;
787 u64 v1;
788
789 result = read_node(PS3_LPAR_ID_CURRENT,
790 make_first_field("bi", 0),
791 make_field("vir_uart", 0),
792 make_field("port", 0),
793 make_field("avset", 0),
794 &v1, 0);
795 *port = v1;
796 return result;
797}
798
799int ps3_repository_read_vuart_sysmgr_port(unsigned int *port)
800{
801 int result;
802 u64 v1;
803
804 result = read_node(PS3_LPAR_ID_CURRENT,
805 make_first_field("bi", 0),
806 make_field("vir_uart", 0),
807 make_field("port", 0),
808 make_field("sysmgr", 0),
809 &v1, 0);
810 *port = v1;
811 return result;
812}
813
968/** 814/**
969 * ps3_repository_read_boot_dat_info - Get address and size of cell_ext_os_area. 815 * ps3_repository_read_boot_dat_info - Get address and size of cell_ext_os_area.
970 * address: lpar address of cell_ext_os_area 816 * address: lpar address of cell_ext_os_area
@@ -1026,3 +872,205 @@ int ps3_repository_read_be_tb_freq(unsigned int be_index, u64 *tb_freq)
1026 return result ? result 872 return result ? result
1027 : ps3_repository_read_tb_freq(node_id, tb_freq); 873 : ps3_repository_read_tb_freq(node_id, tb_freq);
1028} 874}
875
876#if defined(DEBUG)
877
878int ps3_repository_dump_resource_info(const struct ps3_repository_device *repo)
879{
880 int result = 0;
881 unsigned int res_index;
882
883 pr_debug(" -> %s:%d: (%u:%u)\n", __func__, __LINE__,
884 repo->bus_index, repo->dev_index);
885
886 for (res_index = 0; res_index < 10; res_index++) {
887 enum ps3_interrupt_type intr_type;
888 unsigned int interrupt_id;
889
890 result = ps3_repository_read_dev_intr(repo->bus_index,
891 repo->dev_index, res_index, &intr_type, &interrupt_id);
892
893 if (result) {
894 if (result != LV1_NO_ENTRY)
895 pr_debug("%s:%d ps3_repository_read_dev_intr"
896 " (%u:%u) failed\n", __func__, __LINE__,
897 repo->bus_index, repo->dev_index);
898 break;
899 }
900
901 pr_debug("%s:%d (%u:%u) intr_type %u, interrupt_id %u\n",
902 __func__, __LINE__, repo->bus_index, repo->dev_index,
903 intr_type, interrupt_id);
904 }
905
906 for (res_index = 0; res_index < 10; res_index++) {
907 enum ps3_reg_type reg_type;
908 u64 bus_addr;
909 u64 len;
910
911 result = ps3_repository_read_dev_reg(repo->bus_index,
912 repo->dev_index, res_index, &reg_type, &bus_addr, &len);
913
914 if (result) {
915 if (result != LV1_NO_ENTRY)
916 pr_debug("%s:%d ps3_repository_read_dev_reg"
917 " (%u:%u) failed\n", __func__, __LINE__,
918 repo->bus_index, repo->dev_index);
919 break;
920 }
921
922 pr_debug("%s:%d (%u:%u) reg_type %u, bus_addr %lxh, len %lxh\n",
923 __func__, __LINE__, repo->bus_index, repo->dev_index,
924 reg_type, bus_addr, len);
925 }
926
927 pr_debug(" <- %s:%d\n", __func__, __LINE__);
928 return result;
929}
930
931static int dump_stor_dev_info(struct ps3_repository_device *repo)
932{
933 int result = 0;
934 unsigned int num_regions, region_index;
935 u64 port, blk_size, num_blocks;
936
937 pr_debug(" -> %s:%d: (%u:%u)\n", __func__, __LINE__,
938 repo->bus_index, repo->dev_index);
939
940 result = ps3_repository_read_stor_dev_info(repo->bus_index,
941 repo->dev_index, &port, &blk_size, &num_blocks, &num_regions);
942 if (result) {
943 pr_debug("%s:%d ps3_repository_read_stor_dev_info"
944 " (%u:%u) failed\n", __func__, __LINE__,
945 repo->bus_index, repo->dev_index);
946 goto out;
947 }
948
949 pr_debug("%s:%d (%u:%u): port %lu, blk_size %lu, num_blocks "
950 "%lu, num_regions %u\n",
951 __func__, __LINE__, repo->bus_index, repo->dev_index, port,
952 blk_size, num_blocks, num_regions);
953
954 for (region_index = 0; region_index < num_regions; region_index++) {
955 unsigned int region_id;
956 u64 region_start, region_size;
957
958 result = ps3_repository_read_stor_dev_region(repo->bus_index,
959 repo->dev_index, region_index, &region_id,
960 &region_start, &region_size);
961 if (result) {
962 pr_debug("%s:%d ps3_repository_read_stor_dev_region"
963 " (%u:%u) failed\n", __func__, __LINE__,
964 repo->bus_index, repo->dev_index);
965 break;
966 }
967
968 pr_debug("%s:%d (%u:%u) region_id %u, start %lxh, size %lxh\n",
969 __func__, __LINE__, repo->bus_index, repo->dev_index,
970 region_id, region_start, region_size);
971 }
972
973out:
974 pr_debug(" <- %s:%d\n", __func__, __LINE__);
975 return result;
976}
977
978static int dump_device_info(struct ps3_repository_device *repo,
979 unsigned int num_dev)
980{
981 int result = 0;
982
983 pr_debug(" -> %s:%d: bus_%u\n", __func__, __LINE__, repo->bus_index);
984
985 for (repo->dev_index = 0; repo->dev_index < num_dev;
986 repo->dev_index++) {
987
988 result = ps3_repository_read_dev_type(repo->bus_index,
989 repo->dev_index, &repo->dev_type);
990
991 if (result) {
992 pr_debug("%s:%d ps3_repository_read_dev_type"
993 " (%u:%u) failed\n", __func__, __LINE__,
994 repo->bus_index, repo->dev_index);
995 break;
996 }
997
998 result = ps3_repository_read_dev_id(repo->bus_index,
999 repo->dev_index, &repo->dev_id);
1000
1001 if (result) {
1002 pr_debug("%s:%d ps3_repository_read_dev_id"
1003 " (%u:%u) failed\n", __func__, __LINE__,
1004 repo->bus_index, repo->dev_index);
1005 continue;
1006 }
1007
1008 pr_debug("%s:%d (%u:%u): dev_type %u, dev_id %u\n", __func__,
1009 __LINE__, repo->bus_index, repo->dev_index,
1010 repo->dev_type, repo->dev_id);
1011
1012 ps3_repository_dump_resource_info(repo);
1013
1014 if (repo->bus_type == PS3_BUS_TYPE_STORAGE)
1015 dump_stor_dev_info(repo);
1016 }
1017
1018 pr_debug(" <- %s:%d\n", __func__, __LINE__);
1019 return result;
1020}
1021
1022int ps3_repository_dump_bus_info(void)
1023{
1024 int result = 0;
1025 struct ps3_repository_device repo;
1026
1027 pr_debug(" -> %s:%d\n", __func__, __LINE__);
1028
1029 memset(&repo, 0, sizeof(repo));
1030
1031 for (repo.bus_index = 0; repo.bus_index < 10; repo.bus_index++) {
1032 unsigned int num_dev;
1033
1034 result = ps3_repository_read_bus_type(repo.bus_index,
1035 &repo.bus_type);
1036
1037 if (result) {
1038 pr_debug("%s:%d read_bus_type(%u) failed\n",
1039 __func__, __LINE__, repo.bus_index);
1040 break;
1041 }
1042
1043 result = ps3_repository_read_bus_id(repo.bus_index,
1044 &repo.bus_id);
1045
1046 if (result) {
1047 pr_debug("%s:%d read_bus_id(%u) failed\n",
1048 __func__, __LINE__, repo.bus_index);
1049 continue;
1050 }
1051
1052 if (repo.bus_index != repo.bus_id)
1053 pr_debug("%s:%d bus_index != bus_id\n",
1054 __func__, __LINE__);
1055
1056 result = ps3_repository_read_bus_num_dev(repo.bus_index,
1057 &num_dev);
1058
1059 if (result) {
1060 pr_debug("%s:%d read_bus_num_dev(%u) failed\n",
1061 __func__, __LINE__, repo.bus_index);
1062 continue;
1063 }
1064
1065 pr_debug("%s:%d bus_%u: bus_type %u, bus_id %u, num_dev %u\n",
1066 __func__, __LINE__, repo.bus_index, repo.bus_type,
1067 repo.bus_id, num_dev);
1068
1069 dump_device_info(&repo, num_dev);
1070 }
1071
1072 pr_debug(" <- %s:%d\n", __func__, __LINE__);
1073 return result;
1074}
1075
1076#endif /* defined(DEBUG) */
diff --git a/arch/powerpc/platforms/ps3/setup.c b/arch/powerpc/platforms/ps3/setup.c
index 935396766621..aa05288de64e 100644
--- a/arch/powerpc/platforms/ps3/setup.c
+++ b/arch/powerpc/platforms/ps3/setup.c
@@ -37,27 +37,35 @@
37#include "platform.h" 37#include "platform.h"
38 38
39#if defined(DEBUG) 39#if defined(DEBUG)
40#define DBG(fmt...) udbg_printf(fmt) 40#define DBG udbg_printf
41#else 41#else
42#define DBG(fmt...) do{if(0)printk(fmt);}while(0) 42#define DBG pr_debug
43#endif 43#endif
44 44
45#if !defined(CONFIG_SMP) 45#if !defined(CONFIG_SMP)
46static void smp_send_stop(void) {} 46static void smp_send_stop(void) {}
47#endif 47#endif
48 48
49int ps3_get_firmware_version(union ps3_firmware_version *v) 49static union ps3_firmware_version ps3_firmware_version;
50
51void ps3_get_firmware_version(union ps3_firmware_version *v)
50{ 52{
51 int result = lv1_get_version_info(&v->raw); 53 *v = ps3_firmware_version;
54}
55EXPORT_SYMBOL_GPL(ps3_get_firmware_version);
52 56
53 if (result) { 57int ps3_compare_firmware_version(u16 major, u16 minor, u16 rev)
54 v->raw = 0; 58{
55 return -1; 59 union ps3_firmware_version x;
56 } 60
61 x.pad = 0;
62 x.major = major;
63 x.minor = minor;
64 x.rev = rev;
57 65
58 return result; 66 return (ps3_firmware_version.raw - x.raw);
59} 67}
60EXPORT_SYMBOL_GPL(ps3_get_firmware_version); 68EXPORT_SYMBOL_GPL(ps3_compare_firmware_version);
61 69
62static void ps3_power_save(void) 70static void ps3_power_save(void)
63{ 71{
@@ -99,7 +107,8 @@ static void ps3_panic(char *str)
99 while(1); 107 while(1);
100} 108}
101 109
102#ifdef CONFIG_FB_PS3 110#if defined(CONFIG_FB_PS3) || defined(CONFIG_FB_PS3_MODULE) || \
111 defined(CONFIG_PS3_FLASH) || defined(CONFIG_PS3_FLASH_MODULE)
103static void prealloc(struct ps3_prealloc *p) 112static void prealloc(struct ps3_prealloc *p)
104{ 113{
105 if (!p->size) 114 if (!p->size)
@@ -115,12 +124,15 @@ static void prealloc(struct ps3_prealloc *p)
115 printk(KERN_INFO "%s: %lu bytes at %p\n", p->name, p->size, 124 printk(KERN_INFO "%s: %lu bytes at %p\n", p->name, p->size,
116 p->address); 125 p->address);
117} 126}
127#endif
118 128
129#if defined(CONFIG_FB_PS3) || defined(CONFIG_FB_PS3_MODULE)
119struct ps3_prealloc ps3fb_videomemory = { 130struct ps3_prealloc ps3fb_videomemory = {
120 .name = "ps3fb videomemory", 131 .name = "ps3fb videomemory",
121 .size = CONFIG_FB_PS3_DEFAULT_SIZE_M*1024*1024, 132 .size = CONFIG_FB_PS3_DEFAULT_SIZE_M*1024*1024,
122 .align = 1024*1024 /* the GPU requires 1 MiB alignment */ 133 .align = 1024*1024 /* the GPU requires 1 MiB alignment */
123}; 134};
135EXPORT_SYMBOL_GPL(ps3fb_videomemory);
124#define prealloc_ps3fb_videomemory() prealloc(&ps3fb_videomemory) 136#define prealloc_ps3fb_videomemory() prealloc(&ps3fb_videomemory)
125 137
126static int __init early_parse_ps3fb(char *p) 138static int __init early_parse_ps3fb(char *p)
@@ -137,6 +149,30 @@ early_param("ps3fb", early_parse_ps3fb);
137#define prealloc_ps3fb_videomemory() do { } while (0) 149#define prealloc_ps3fb_videomemory() do { } while (0)
138#endif 150#endif
139 151
152#if defined(CONFIG_PS3_FLASH) || defined(CONFIG_PS3_FLASH_MODULE)
153struct ps3_prealloc ps3flash_bounce_buffer = {
154 .name = "ps3flash bounce buffer",
155 .size = 256*1024,
156 .align = 256*1024
157};
158EXPORT_SYMBOL_GPL(ps3flash_bounce_buffer);
159#define prealloc_ps3flash_bounce_buffer() prealloc(&ps3flash_bounce_buffer)
160
161static int __init early_parse_ps3flash(char *p)
162{
163 if (!p)
164 return 1;
165
166 if (!strcmp(p, "off"))
167 ps3flash_bounce_buffer.size = 0;
168
169 return 0;
170}
171early_param("ps3flash", early_parse_ps3flash);
172#else
173#define prealloc_ps3flash_bounce_buffer() do { } while (0)
174#endif
175
140static int ps3_set_dabr(u64 dabr) 176static int ps3_set_dabr(u64 dabr)
141{ 177{
142 enum {DABR_USER = 1, DABR_KERNEL = 2,}; 178 enum {DABR_USER = 1, DABR_KERNEL = 2,};
@@ -146,13 +182,13 @@ static int ps3_set_dabr(u64 dabr)
146 182
147static void __init ps3_setup_arch(void) 183static void __init ps3_setup_arch(void)
148{ 184{
149 union ps3_firmware_version v;
150 185
151 DBG(" -> %s:%d\n", __func__, __LINE__); 186 DBG(" -> %s:%d\n", __func__, __LINE__);
152 187
153 ps3_get_firmware_version(&v); 188 lv1_get_version_info(&ps3_firmware_version.raw);
154 printk(KERN_INFO "PS3 firmware version %u.%u.%u\n", v.major, v.minor, 189 printk(KERN_INFO "PS3 firmware version %u.%u.%u\n",
155 v.rev); 190 ps3_firmware_version.major, ps3_firmware_version.minor,
191 ps3_firmware_version.rev);
156 192
157 ps3_spu_set_platform(); 193 ps3_spu_set_platform();
158 ps3_map_htab(); 194 ps3_map_htab();
@@ -166,6 +202,8 @@ static void __init ps3_setup_arch(void)
166#endif 202#endif
167 203
168 prealloc_ps3fb_videomemory(); 204 prealloc_ps3fb_videomemory();
205 prealloc_ps3flash_bounce_buffer();
206
169 ppc_md.power_save = ps3_power_save; 207 ppc_md.power_save = ps3_power_save;
170 208
171 DBG(" <- %s:%d\n", __func__, __LINE__); 209 DBG(" <- %s:%d\n", __func__, __LINE__);
@@ -184,7 +222,7 @@ static int __init ps3_probe(void)
184 DBG(" -> %s:%d\n", __func__, __LINE__); 222 DBG(" -> %s:%d\n", __func__, __LINE__);
185 223
186 dt_root = of_get_flat_dt_root(); 224 dt_root = of_get_flat_dt_root();
187 if (!of_flat_dt_is_compatible(dt_root, "PS3")) 225 if (!of_flat_dt_is_compatible(dt_root, "sony,ps3"))
188 return 0; 226 return 0;
189 227
190 powerpc_firmware_features |= FW_FEATURE_PS3_POSSIBLE; 228 powerpc_firmware_features |= FW_FEATURE_PS3_POSSIBLE;
@@ -201,31 +239,12 @@ static int __init ps3_probe(void)
201#if defined(CONFIG_KEXEC) 239#if defined(CONFIG_KEXEC)
202static void ps3_kexec_cpu_down(int crash_shutdown, int secondary) 240static void ps3_kexec_cpu_down(int crash_shutdown, int secondary)
203{ 241{
204 DBG(" -> %s:%d\n", __func__, __LINE__); 242 int cpu = smp_processor_id();
205
206 if (secondary) {
207 int cpu;
208 for_each_online_cpu(cpu)
209 if (cpu)
210 ps3_smp_cleanup_cpu(cpu);
211 } else
212 ps3_smp_cleanup_cpu(0);
213
214 DBG(" <- %s:%d\n", __func__, __LINE__);
215}
216
217static void ps3_machine_kexec(struct kimage *image)
218{
219 unsigned long ppe_id;
220
221 DBG(" -> %s:%d\n", __func__, __LINE__);
222 243
223 lv1_get_logical_ppe_id(&ppe_id); 244 DBG(" -> %s:%d: (%d)\n", __func__, __LINE__, cpu);
224 lv1_configure_irq_state_bitmap(ppe_id, 0, 0);
225 ps3_mm_shutdown();
226 ps3_mm_vas_destroy();
227 245
228 default_machine_kexec(image); 246 ps3_smp_cleanup_cpu(cpu);
247 ps3_shutdown_IRQ(cpu);
229 248
230 DBG(" <- %s:%d\n", __func__, __LINE__); 249 DBG(" <- %s:%d\n", __func__, __LINE__);
231} 250}
@@ -247,7 +266,7 @@ define_machine(ps3) {
247 .power_off = ps3_power_off, 266 .power_off = ps3_power_off,
248#if defined(CONFIG_KEXEC) 267#if defined(CONFIG_KEXEC)
249 .kexec_cpu_down = ps3_kexec_cpu_down, 268 .kexec_cpu_down = ps3_kexec_cpu_down,
250 .machine_kexec = ps3_machine_kexec, 269 .machine_kexec = default_machine_kexec,
251 .machine_kexec_prepare = default_machine_kexec_prepare, 270 .machine_kexec_prepare = default_machine_kexec_prepare,
252 .machine_crash_shutdown = default_machine_crash_shutdown, 271 .machine_crash_shutdown = default_machine_crash_shutdown,
253#endif 272#endif
diff --git a/arch/powerpc/platforms/ps3/smp.c b/arch/powerpc/platforms/ps3/smp.c
index 53416ec5198b..f0b12f212363 100644
--- a/arch/powerpc/platforms/ps3/smp.c
+++ b/arch/powerpc/platforms/ps3/smp.c
@@ -27,9 +27,9 @@
27#include "platform.h" 27#include "platform.h"
28 28
29#if defined(DEBUG) 29#if defined(DEBUG)
30#define DBG(fmt...) udbg_printf(fmt) 30#define DBG udbg_printf
31#else 31#else
32#define DBG(fmt...) do{if(0)printk(fmt);}while(0) 32#define DBG pr_debug
33#endif 33#endif
34 34
35static irqreturn_t ipi_function_handler(int irq, void *msg) 35static irqreturn_t ipi_function_handler(int irq, void *msg)
@@ -39,11 +39,11 @@ static irqreturn_t ipi_function_handler(int irq, void *msg)
39} 39}
40 40
41/** 41/**
42 * virqs - a per cpu array of virqs for ipi use 42 * ps3_ipi_virqs - a per cpu array of virqs for ipi use
43 */ 43 */
44 44
45#define MSG_COUNT 4 45#define MSG_COUNT 4
46static DEFINE_PER_CPU(unsigned int, virqs[MSG_COUNT]); 46static DEFINE_PER_CPU(unsigned int, ps3_ipi_virqs[MSG_COUNT]);
47 47
48static const char *names[MSG_COUNT] = { 48static const char *names[MSG_COUNT] = {
49 "ipi call", 49 "ipi call",
@@ -62,7 +62,7 @@ static void do_message_pass(int target, int msg)
62 return; 62 return;
63 } 63 }
64 64
65 virq = per_cpu(virqs, target)[msg]; 65 virq = per_cpu(ps3_ipi_virqs, target)[msg];
66 result = ps3_send_event_locally(virq); 66 result = ps3_send_event_locally(virq);
67 67
68 if (result) 68 if (result)
@@ -94,13 +94,13 @@ static int ps3_smp_probe(void)
94static void __init ps3_smp_setup_cpu(int cpu) 94static void __init ps3_smp_setup_cpu(int cpu)
95{ 95{
96 int result; 96 int result;
97 unsigned int *virqs = per_cpu(virqs, cpu); 97 unsigned int *virqs = per_cpu(ps3_ipi_virqs, cpu);
98 int i; 98 int i;
99 99
100 DBG(" -> %s:%d: (%d)\n", __func__, __LINE__, cpu); 100 DBG(" -> %s:%d: (%d)\n", __func__, __LINE__, cpu);
101 101
102 /* 102 /*
103 * Check assumptions on virqs[] indexing. If this 103 * Check assumptions on ps3_ipi_virqs[] indexing. If this
104 * check fails, then a different mapping of PPC_MSG_ 104 * check fails, then a different mapping of PPC_MSG_
105 * to index needs to be setup. 105 * to index needs to be setup.
106 */ 106 */
@@ -132,13 +132,13 @@ static void __init ps3_smp_setup_cpu(int cpu)
132 132
133void ps3_smp_cleanup_cpu(int cpu) 133void ps3_smp_cleanup_cpu(int cpu)
134{ 134{
135 unsigned int *virqs = per_cpu(virqs, cpu); 135 unsigned int *virqs = per_cpu(ps3_ipi_virqs, cpu);
136 int i; 136 int i;
137 137
138 DBG(" -> %s:%d: (%d)\n", __func__, __LINE__, cpu); 138 DBG(" -> %s:%d: (%d)\n", __func__, __LINE__, cpu);
139 139
140 for (i = 0; i < MSG_COUNT; i++) { 140 for (i = 0; i < MSG_COUNT; i++) {
141 free_irq(virqs[i], (void*)(long)i); 141 /* Can't call free_irq from interrupt context. */
142 ps3_event_receive_port_destroy(virqs[i]); 142 ps3_event_receive_port_destroy(virqs[i]);
143 virqs[i] = NO_IRQ; 143 virqs[i] = NO_IRQ;
144 } 144 }
diff --git a/arch/powerpc/platforms/ps3/spu.c b/arch/powerpc/platforms/ps3/spu.c
index 651437cb2c18..c7f734c89462 100644
--- a/arch/powerpc/platforms/ps3/spu.c
+++ b/arch/powerpc/platforms/ps3/spu.c
@@ -182,15 +182,18 @@ static int __init setup_areas(struct spu *spu)
182{ 182{
183 struct table {char* name; unsigned long addr; unsigned long size;}; 183 struct table {char* name; unsigned long addr; unsigned long size;};
184 184
185 spu_pdata(spu)->shadow = __ioremap( 185 spu_pdata(spu)->shadow = ioremap_flags(spu_pdata(spu)->shadow_addr,
186 spu_pdata(spu)->shadow_addr, sizeof(struct spe_shadow), 186 sizeof(struct spe_shadow),
187 pgprot_val(PAGE_READONLY) | _PAGE_NO_CACHE | _PAGE_GUARDED); 187 pgprot_val(PAGE_READONLY) |
188 _PAGE_NO_CACHE);
188 if (!spu_pdata(spu)->shadow) { 189 if (!spu_pdata(spu)->shadow) {
189 pr_debug("%s:%d: ioremap shadow failed\n", __func__, __LINE__); 190 pr_debug("%s:%d: ioremap shadow failed\n", __func__, __LINE__);
190 goto fail_ioremap; 191 goto fail_ioremap;
191 } 192 }
192 193
193 spu->local_store = ioremap(spu->local_store_phys, LS_SIZE); 194 spu->local_store = (__force void *)ioremap_flags(spu->local_store_phys,
195 LS_SIZE, _PAGE_NO_CACHE);
196
194 if (!spu->local_store) { 197 if (!spu->local_store) {
195 pr_debug("%s:%d: ioremap local_store failed\n", 198 pr_debug("%s:%d: ioremap local_store failed\n",
196 __func__, __LINE__); 199 __func__, __LINE__);
@@ -199,6 +202,7 @@ static int __init setup_areas(struct spu *spu)
199 202
200 spu->problem = ioremap(spu->problem_phys, 203 spu->problem = ioremap(spu->problem_phys,
201 sizeof(struct spu_problem)); 204 sizeof(struct spu_problem));
205
202 if (!spu->problem) { 206 if (!spu->problem) {
203 pr_debug("%s:%d: ioremap problem failed\n", __func__, __LINE__); 207 pr_debug("%s:%d: ioremap problem failed\n", __func__, __LINE__);
204 goto fail_ioremap; 208 goto fail_ioremap;
@@ -206,6 +210,7 @@ static int __init setup_areas(struct spu *spu)
206 210
207 spu->priv2 = ioremap(spu_pdata(spu)->priv2_addr, 211 spu->priv2 = ioremap(spu_pdata(spu)->priv2_addr,
208 sizeof(struct spu_priv2)); 212 sizeof(struct spu_priv2));
213
209 if (!spu->priv2) { 214 if (!spu->priv2) {
210 pr_debug("%s:%d: ioremap priv2 failed\n", __func__, __LINE__); 215 pr_debug("%s:%d: ioremap priv2 failed\n", __func__, __LINE__);
211 goto fail_ioremap; 216 goto fail_ioremap;
diff --git a/arch/powerpc/platforms/ps3/system-bus.c b/arch/powerpc/platforms/ps3/system-bus.c
index 6bda51027cc6..4bb634a17e43 100644
--- a/arch/powerpc/platforms/ps3/system-bus.c
+++ b/arch/powerpc/platforms/ps3/system-bus.c
@@ -30,22 +30,228 @@
30 30
31#include "platform.h" 31#include "platform.h"
32 32
33static struct device ps3_system_bus = {
34 .bus_id = "ps3_system",
35};
36
37/* FIXME: need device usage counters! */
38struct {
39 struct mutex mutex;
40 int sb_11; /* usb 0 */
41 int sb_12; /* usb 0 */
42 int gpu;
43} static usage_hack;
44
45static int ps3_is_device(struct ps3_system_bus_device *dev,
46 unsigned int bus_id, unsigned int dev_id)
47{
48 return dev->bus_id == bus_id && dev->dev_id == dev_id;
49}
50
51static int ps3_open_hv_device_sb(struct ps3_system_bus_device *dev)
52{
53 int result;
54
55 BUG_ON(!dev->bus_id);
56 mutex_lock(&usage_hack.mutex);
57
58 if (ps3_is_device(dev, 1, 1)) {
59 usage_hack.sb_11++;
60 if (usage_hack.sb_11 > 1) {
61 result = 0;
62 goto done;
63 }
64 }
65
66 if (ps3_is_device(dev, 1, 2)) {
67 usage_hack.sb_12++;
68 if (usage_hack.sb_12 > 1) {
69 result = 0;
70 goto done;
71 }
72 }
73
74 result = lv1_open_device(dev->bus_id, dev->dev_id, 0);
75
76 if (result) {
77 pr_debug("%s:%d: lv1_open_device failed: %s\n", __func__,
78 __LINE__, ps3_result(result));
79 result = -EPERM;
80 }
81
82done:
83 mutex_unlock(&usage_hack.mutex);
84 return result;
85}
86
87static int ps3_close_hv_device_sb(struct ps3_system_bus_device *dev)
88{
89 int result;
90
91 BUG_ON(!dev->bus_id);
92 mutex_lock(&usage_hack.mutex);
93
94 if (ps3_is_device(dev, 1, 1)) {
95 usage_hack.sb_11--;
96 if (usage_hack.sb_11) {
97 result = 0;
98 goto done;
99 }
100 }
101
102 if (ps3_is_device(dev, 1, 2)) {
103 usage_hack.sb_12--;
104 if (usage_hack.sb_12) {
105 result = 0;
106 goto done;
107 }
108 }
109
110 result = lv1_close_device(dev->bus_id, dev->dev_id);
111 BUG_ON(result);
112
113done:
114 mutex_unlock(&usage_hack.mutex);
115 return result;
116}
117
118static int ps3_open_hv_device_gpu(struct ps3_system_bus_device *dev)
119{
120 int result;
121
122 mutex_lock(&usage_hack.mutex);
123
124 usage_hack.gpu++;
125 if (usage_hack.gpu > 1) {
126 result = 0;
127 goto done;
128 }
129
130 result = lv1_gpu_open(0);
131
132 if (result) {
133 pr_debug("%s:%d: lv1_gpu_open failed: %s\n", __func__,
134 __LINE__, ps3_result(result));
135 result = -EPERM;
136 }
137
138done:
139 mutex_unlock(&usage_hack.mutex);
140 return result;
141}
142
143static int ps3_close_hv_device_gpu(struct ps3_system_bus_device *dev)
144{
145 int result;
146
147 mutex_lock(&usage_hack.mutex);
148
149 usage_hack.gpu--;
150 if (usage_hack.gpu) {
151 result = 0;
152 goto done;
153 }
154
155 result = lv1_gpu_close();
156 BUG_ON(result);
157
158done:
159 mutex_unlock(&usage_hack.mutex);
160 return result;
161}
162
163int ps3_open_hv_device(struct ps3_system_bus_device *dev)
164{
165 BUG_ON(!dev);
166 pr_debug("%s:%d: match_id: %u\n", __func__, __LINE__, dev->match_id);
167
168 switch (dev->match_id) {
169 case PS3_MATCH_ID_EHCI:
170 case PS3_MATCH_ID_OHCI:
171 case PS3_MATCH_ID_GELIC:
172 case PS3_MATCH_ID_STOR_DISK:
173 case PS3_MATCH_ID_STOR_ROM:
174 case PS3_MATCH_ID_STOR_FLASH:
175 return ps3_open_hv_device_sb(dev);
176
177 case PS3_MATCH_ID_SOUND:
178 case PS3_MATCH_ID_GRAPHICS:
179 return ps3_open_hv_device_gpu(dev);
180
181 case PS3_MATCH_ID_AV_SETTINGS:
182 case PS3_MATCH_ID_SYSTEM_MANAGER:
183 pr_debug("%s:%d: unsupported match_id: %u\n", __func__,
184 __LINE__, dev->match_id);
185 pr_debug("%s:%d: bus_id: %u\n", __func__,
186 __LINE__, dev->bus_id);
187 BUG();
188 return -EINVAL;
189
190 default:
191 break;
192 }
193
194 pr_debug("%s:%d: unknown match_id: %u\n", __func__, __LINE__,
195 dev->match_id);
196 BUG();
197 return -ENODEV;
198}
199EXPORT_SYMBOL_GPL(ps3_open_hv_device);
200
201int ps3_close_hv_device(struct ps3_system_bus_device *dev)
202{
203 BUG_ON(!dev);
204 pr_debug("%s:%d: match_id: %u\n", __func__, __LINE__, dev->match_id);
205
206 switch (dev->match_id) {
207 case PS3_MATCH_ID_EHCI:
208 case PS3_MATCH_ID_OHCI:
209 case PS3_MATCH_ID_GELIC:
210 case PS3_MATCH_ID_STOR_DISK:
211 case PS3_MATCH_ID_STOR_ROM:
212 case PS3_MATCH_ID_STOR_FLASH:
213 return ps3_close_hv_device_sb(dev);
214
215 case PS3_MATCH_ID_SOUND:
216 case PS3_MATCH_ID_GRAPHICS:
217 return ps3_close_hv_device_gpu(dev);
218
219 case PS3_MATCH_ID_AV_SETTINGS:
220 case PS3_MATCH_ID_SYSTEM_MANAGER:
221 pr_debug("%s:%d: unsupported match_id: %u\n", __func__,
222 __LINE__, dev->match_id);
223 pr_debug("%s:%d: bus_id: %u\n", __func__,
224 __LINE__, dev->bus_id);
225 BUG();
226 return -EINVAL;
227
228 default:
229 break;
230 }
231
232 pr_debug("%s:%d: unknown match_id: %u\n", __func__, __LINE__,
233 dev->match_id);
234 BUG();
235 return -ENODEV;
236}
237EXPORT_SYMBOL_GPL(ps3_close_hv_device);
238
33#define dump_mmio_region(_a) _dump_mmio_region(_a, __func__, __LINE__) 239#define dump_mmio_region(_a) _dump_mmio_region(_a, __func__, __LINE__)
34static void _dump_mmio_region(const struct ps3_mmio_region* r, 240static void _dump_mmio_region(const struct ps3_mmio_region* r,
35 const char* func, int line) 241 const char* func, int line)
36{ 242{
37 pr_debug("%s:%d: dev %u:%u\n", func, line, r->did.bus_id, 243 pr_debug("%s:%d: dev %u:%u\n", func, line, r->dev->bus_id,
38 r->did.dev_id); 244 r->dev->dev_id);
39 pr_debug("%s:%d: bus_addr %lxh\n", func, line, r->bus_addr); 245 pr_debug("%s:%d: bus_addr %lxh\n", func, line, r->bus_addr);
40 pr_debug("%s:%d: len %lxh\n", func, line, r->len); 246 pr_debug("%s:%d: len %lxh\n", func, line, r->len);
41 pr_debug("%s:%d: lpar_addr %lxh\n", func, line, r->lpar_addr); 247 pr_debug("%s:%d: lpar_addr %lxh\n", func, line, r->lpar_addr);
42} 248}
43 249
44int ps3_mmio_region_create(struct ps3_mmio_region *r) 250static int ps3_sb_mmio_region_create(struct ps3_mmio_region *r)
45{ 251{
46 int result; 252 int result;
47 253
48 result = lv1_map_device_mmio_region(r->did.bus_id, r->did.dev_id, 254 result = lv1_map_device_mmio_region(r->dev->bus_id, r->dev->dev_id,
49 r->bus_addr, r->len, r->page_size, &r->lpar_addr); 255 r->bus_addr, r->len, r->page_size, &r->lpar_addr);
50 256
51 if (result) { 257 if (result) {
@@ -57,13 +263,26 @@ int ps3_mmio_region_create(struct ps3_mmio_region *r)
57 dump_mmio_region(r); 263 dump_mmio_region(r);
58 return result; 264 return result;
59} 265}
266
267static int ps3_ioc0_mmio_region_create(struct ps3_mmio_region *r)
268{
269 /* device specific; do nothing currently */
270 return 0;
271}
272
273int ps3_mmio_region_create(struct ps3_mmio_region *r)
274{
275 return r->mmio_ops->create(r);
276}
60EXPORT_SYMBOL_GPL(ps3_mmio_region_create); 277EXPORT_SYMBOL_GPL(ps3_mmio_region_create);
61 278
62int ps3_free_mmio_region(struct ps3_mmio_region *r) 279static int ps3_sb_free_mmio_region(struct ps3_mmio_region *r)
63{ 280{
64 int result; 281 int result;
65 282
66 result = lv1_unmap_device_mmio_region(r->did.bus_id, r->did.dev_id, 283 dump_mmio_region(r);
284;
285 result = lv1_unmap_device_mmio_region(r->dev->bus_id, r->dev->dev_id,
67 r->lpar_addr); 286 r->lpar_addr);
68 287
69 if (result) 288 if (result)
@@ -73,14 +292,60 @@ int ps3_free_mmio_region(struct ps3_mmio_region *r)
73 r->lpar_addr = 0; 292 r->lpar_addr = 0;
74 return result; 293 return result;
75} 294}
295
296static int ps3_ioc0_free_mmio_region(struct ps3_mmio_region *r)
297{
298 /* device specific; do nothing currently */
299 return 0;
300}
301
302
303int ps3_free_mmio_region(struct ps3_mmio_region *r)
304{
305 return r->mmio_ops->free(r);
306}
307
76EXPORT_SYMBOL_GPL(ps3_free_mmio_region); 308EXPORT_SYMBOL_GPL(ps3_free_mmio_region);
77 309
310static const struct ps3_mmio_region_ops ps3_mmio_sb_region_ops = {
311 .create = ps3_sb_mmio_region_create,
312 .free = ps3_sb_free_mmio_region
313};
314
315static const struct ps3_mmio_region_ops ps3_mmio_ioc0_region_ops = {
316 .create = ps3_ioc0_mmio_region_create,
317 .free = ps3_ioc0_free_mmio_region
318};
319
320int ps3_mmio_region_init(struct ps3_system_bus_device *dev,
321 struct ps3_mmio_region *r, unsigned long bus_addr, unsigned long len,
322 enum ps3_mmio_page_size page_size)
323{
324 r->dev = dev;
325 r->bus_addr = bus_addr;
326 r->len = len;
327 r->page_size = page_size;
328 switch (dev->dev_type) {
329 case PS3_DEVICE_TYPE_SB:
330 r->mmio_ops = &ps3_mmio_sb_region_ops;
331 break;
332 case PS3_DEVICE_TYPE_IOC0:
333 r->mmio_ops = &ps3_mmio_ioc0_region_ops;
334 break;
335 default:
336 BUG();
337 return -EINVAL;
338 }
339 return 0;
340}
341EXPORT_SYMBOL_GPL(ps3_mmio_region_init);
342
78static int ps3_system_bus_match(struct device *_dev, 343static int ps3_system_bus_match(struct device *_dev,
79 struct device_driver *_drv) 344 struct device_driver *_drv)
80{ 345{
81 int result; 346 int result;
82 struct ps3_system_bus_driver *drv = to_ps3_system_bus_driver(_drv); 347 struct ps3_system_bus_driver *drv = ps3_drv_to_system_bus_drv(_drv);
83 struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev); 348 struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
84 349
85 result = dev->match_id == drv->match_id; 350 result = dev->match_id == drv->match_id;
86 351
@@ -92,32 +357,14 @@ static int ps3_system_bus_match(struct device *_dev,
92 357
93static int ps3_system_bus_probe(struct device *_dev) 358static int ps3_system_bus_probe(struct device *_dev)
94{ 359{
95 int result; 360 int result = 0;
96 struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev); 361 struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
97 struct ps3_system_bus_driver *drv = 362 struct ps3_system_bus_driver *drv;
98 to_ps3_system_bus_driver(_dev->driver);
99
100 result = lv1_open_device(dev->did.bus_id, dev->did.dev_id, 0);
101
102 if (result) {
103 pr_debug("%s:%d: lv1_open_device failed (%d)\n",
104 __func__, __LINE__, result);
105 result = -EACCES;
106 goto clean_none;
107 }
108
109 if (dev->d_region->did.bus_id) {
110 result = ps3_dma_region_create(dev->d_region);
111 363
112 if (result) { 364 BUG_ON(!dev);
113 pr_debug("%s:%d: ps3_dma_region_create failed (%d)\n", 365 pr_info(" -> %s:%d: %s\n", __func__, __LINE__, _dev->bus_id);
114 __func__, __LINE__, result);
115 BUG_ON("check region type");
116 result = -EINVAL;
117 goto clean_device;
118 }
119 }
120 366
367 drv = ps3_system_bus_dev_to_system_bus_drv(dev);
121 BUG_ON(!drv); 368 BUG_ON(!drv);
122 369
123 if (drv->probe) 370 if (drv->probe)
@@ -126,56 +373,127 @@ static int ps3_system_bus_probe(struct device *_dev)
126 pr_info("%s:%d: %s no probe method\n", __func__, __LINE__, 373 pr_info("%s:%d: %s no probe method\n", __func__, __LINE__,
127 dev->core.bus_id); 374 dev->core.bus_id);
128 375
129 if (result) { 376 pr_info(" <- %s:%d: %s\n", __func__, __LINE__, dev->core.bus_id);
130 pr_debug("%s:%d: drv->probe failed\n", __func__, __LINE__);
131 goto clean_dma;
132 }
133
134 return result;
135
136clean_dma:
137 ps3_dma_region_free(dev->d_region);
138clean_device:
139 lv1_close_device(dev->did.bus_id, dev->did.dev_id);
140clean_none:
141 return result; 377 return result;
142} 378}
143 379
144static int ps3_system_bus_remove(struct device *_dev) 380static int ps3_system_bus_remove(struct device *_dev)
145{ 381{
146 struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev); 382 int result = 0;
147 struct ps3_system_bus_driver *drv = 383 struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
148 to_ps3_system_bus_driver(_dev->driver); 384 struct ps3_system_bus_driver *drv;
385
386 BUG_ON(!dev);
387 pr_info(" -> %s:%d: %s\n", __func__, __LINE__, _dev->bus_id);
388
389 drv = ps3_system_bus_dev_to_system_bus_drv(dev);
390 BUG_ON(!drv);
149 391
150 if (drv->remove) 392 if (drv->remove)
151 drv->remove(dev); 393 result = drv->remove(dev);
152 else 394 else
153 pr_info("%s:%d: %s no remove method\n", __func__, __LINE__, 395 dev_dbg(&dev->core, "%s:%d %s: no remove method\n",
154 dev->core.bus_id); 396 __func__, __LINE__, drv->core.name);
397
398 pr_info(" <- %s:%d: %s\n", __func__, __LINE__, dev->core.bus_id);
399 return result;
400}
401
402static void ps3_system_bus_shutdown(struct device *_dev)
403{
404 struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
405 struct ps3_system_bus_driver *drv;
406
407 BUG_ON(!dev);
408
409 dev_dbg(&dev->core, " -> %s:%d: match_id %d\n", __func__, __LINE__,
410 dev->match_id);
411
412 if (!dev->core.driver) {
413 dev_dbg(&dev->core, "%s:%d: no driver bound\n", __func__,
414 __LINE__);
415 return;
416 }
417
418 drv = ps3_system_bus_dev_to_system_bus_drv(dev);
419
420 BUG_ON(!drv);
421
422 dev_dbg(&dev->core, "%s:%d: %s -> %s\n", __func__, __LINE__,
423 dev->core.bus_id, drv->core.name);
424
425 if (drv->shutdown)
426 drv->shutdown(dev);
427 else if (drv->remove) {
428 dev_dbg(&dev->core, "%s:%d %s: no shutdown, calling remove\n",
429 __func__, __LINE__, drv->core.name);
430 drv->remove(dev);
431 } else {
432 dev_dbg(&dev->core, "%s:%d %s: no shutdown method\n",
433 __func__, __LINE__, drv->core.name);
434 BUG();
435 }
436
437 dev_dbg(&dev->core, " <- %s:%d\n", __func__, __LINE__);
438}
439
440static int ps3_system_bus_uevent(struct device *_dev, char **envp,
441 int num_envp, char *buffer, int buffer_size)
442{
443 struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
444 int i = 0, length = 0;
155 445
156 ps3_dma_region_free(dev->d_region); 446 if (add_uevent_var(envp, num_envp, &i, buffer, buffer_size,
157 ps3_free_mmio_region(dev->m_region); 447 &length, "MODALIAS=ps3:%d",
158 lv1_close_device(dev->did.bus_id, dev->did.dev_id); 448 dev->match_id))
449 return -ENOMEM;
159 450
451 envp[i] = NULL;
160 return 0; 452 return 0;
161} 453}
162 454
455static ssize_t modalias_show(struct device *_dev, struct device_attribute *a,
456 char *buf)
457{
458 struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
459 int len = snprintf(buf, PAGE_SIZE, "ps3:%d\n", dev->match_id);
460
461 return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len;
462}
463
464static struct device_attribute ps3_system_bus_dev_attrs[] = {
465 __ATTR_RO(modalias),
466 __ATTR_NULL,
467};
468
163struct bus_type ps3_system_bus_type = { 469struct bus_type ps3_system_bus_type = {
164 .name = "ps3_system_bus", 470 .name = "ps3_system_bus",
165 .match = ps3_system_bus_match, 471 .match = ps3_system_bus_match,
472 .uevent = ps3_system_bus_uevent,
166 .probe = ps3_system_bus_probe, 473 .probe = ps3_system_bus_probe,
167 .remove = ps3_system_bus_remove, 474 .remove = ps3_system_bus_remove,
475 .shutdown = ps3_system_bus_shutdown,
476 .dev_attrs = ps3_system_bus_dev_attrs,
168}; 477};
169 478
170int __init ps3_system_bus_init(void) 479static int __init ps3_system_bus_init(void)
171{ 480{
172 int result; 481 int result;
173 482
174 if (!firmware_has_feature(FW_FEATURE_PS3_LV1)) 483 if (!firmware_has_feature(FW_FEATURE_PS3_LV1))
175 return -ENODEV; 484 return -ENODEV;
176 485
486 pr_debug(" -> %s:%d\n", __func__, __LINE__);
487
488 mutex_init(&usage_hack.mutex);
489
490 result = device_register(&ps3_system_bus);
491 BUG_ON(result);
492
177 result = bus_register(&ps3_system_bus_type); 493 result = bus_register(&ps3_system_bus_type);
178 BUG_ON(result); 494 BUG_ON(result);
495
496 pr_debug(" <- %s:%d\n", __func__, __LINE__);
179 return result; 497 return result;
180} 498}
181 499
@@ -185,16 +503,13 @@ core_initcall(ps3_system_bus_init);
185 * Returns the virtual address of the buffer and sets dma_handle 503 * Returns the virtual address of the buffer and sets dma_handle
186 * to the dma address (mapping) of the first page. 504 * to the dma address (mapping) of the first page.
187 */ 505 */
188
189static void * ps3_alloc_coherent(struct device *_dev, size_t size, 506static void * ps3_alloc_coherent(struct device *_dev, size_t size,
190 dma_addr_t *dma_handle, gfp_t flag) 507 dma_addr_t *dma_handle, gfp_t flag)
191{ 508{
192 int result; 509 int result;
193 struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev); 510 struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
194 unsigned long virt_addr; 511 unsigned long virt_addr;
195 512
196 BUG_ON(!dev->d_region->bus_addr);
197
198 flag &= ~(__GFP_DMA | __GFP_HIGHMEM); 513 flag &= ~(__GFP_DMA | __GFP_HIGHMEM);
199 flag |= __GFP_ZERO; 514 flag |= __GFP_ZERO;
200 515
@@ -205,7 +520,8 @@ static void * ps3_alloc_coherent(struct device *_dev, size_t size,
205 goto clean_none; 520 goto clean_none;
206 } 521 }
207 522
208 result = ps3_dma_map(dev->d_region, virt_addr, size, dma_handle); 523 result = ps3_dma_map(dev->d_region, virt_addr, size, dma_handle,
524 IOPTE_PP_W | IOPTE_PP_R | IOPTE_SO_RW | IOPTE_M);
209 525
210 if (result) { 526 if (result) {
211 pr_debug("%s:%d: ps3_dma_map failed (%d)\n", 527 pr_debug("%s:%d: ps3_dma_map failed (%d)\n",
@@ -226,7 +542,7 @@ clean_none:
226static void ps3_free_coherent(struct device *_dev, size_t size, void *vaddr, 542static void ps3_free_coherent(struct device *_dev, size_t size, void *vaddr,
227 dma_addr_t dma_handle) 543 dma_addr_t dma_handle)
228{ 544{
229 struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev); 545 struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
230 546
231 ps3_dma_unmap(dev->d_region, dma_handle, size); 547 ps3_dma_unmap(dev->d_region, dma_handle, size);
232 free_pages((unsigned long)vaddr, get_order(size)); 548 free_pages((unsigned long)vaddr, get_order(size));
@@ -239,15 +555,16 @@ static void ps3_free_coherent(struct device *_dev, size_t size, void *vaddr,
239 * byte within the page as vaddr. 555 * byte within the page as vaddr.
240 */ 556 */
241 557
242static dma_addr_t ps3_map_single(struct device *_dev, void *ptr, size_t size, 558static dma_addr_t ps3_sb_map_single(struct device *_dev, void *ptr, size_t size,
243 enum dma_data_direction direction) 559 enum dma_data_direction direction)
244{ 560{
245 struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev); 561 struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
246 int result; 562 int result;
247 unsigned long bus_addr; 563 unsigned long bus_addr;
248 564
249 result = ps3_dma_map(dev->d_region, (unsigned long)ptr, size, 565 result = ps3_dma_map(dev->d_region, (unsigned long)ptr, size,
250 &bus_addr); 566 &bus_addr,
567 IOPTE_PP_R | IOPTE_PP_W | IOPTE_SO_RW | IOPTE_M);
251 568
252 if (result) { 569 if (result) {
253 pr_debug("%s:%d: ps3_dma_map failed (%d)\n", 570 pr_debug("%s:%d: ps3_dma_map failed (%d)\n",
@@ -257,10 +574,44 @@ static dma_addr_t ps3_map_single(struct device *_dev, void *ptr, size_t size,
257 return bus_addr; 574 return bus_addr;
258} 575}
259 576
577static dma_addr_t ps3_ioc0_map_single(struct device *_dev, void *ptr,
578 size_t size,
579 enum dma_data_direction direction)
580{
581 struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
582 int result;
583 unsigned long bus_addr;
584 u64 iopte_flag;
585
586 iopte_flag = IOPTE_M;
587 switch (direction) {
588 case DMA_BIDIRECTIONAL:
589 iopte_flag |= IOPTE_PP_R | IOPTE_PP_W | IOPTE_SO_RW;
590 break;
591 case DMA_TO_DEVICE:
592 iopte_flag |= IOPTE_PP_R | IOPTE_SO_R;
593 break;
594 case DMA_FROM_DEVICE:
595 iopte_flag |= IOPTE_PP_W | IOPTE_SO_RW;
596 break;
597 default:
598 /* not happned */
599 BUG();
600 };
601 result = ps3_dma_map(dev->d_region, (unsigned long)ptr, size,
602 &bus_addr, iopte_flag);
603
604 if (result) {
605 pr_debug("%s:%d: ps3_dma_map failed (%d)\n",
606 __func__, __LINE__, result);
607 }
608 return bus_addr;
609}
610
260static void ps3_unmap_single(struct device *_dev, dma_addr_t dma_addr, 611static void ps3_unmap_single(struct device *_dev, dma_addr_t dma_addr,
261 size_t size, enum dma_data_direction direction) 612 size_t size, enum dma_data_direction direction)
262{ 613{
263 struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev); 614 struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
264 int result; 615 int result;
265 616
266 result = ps3_dma_unmap(dev->d_region, dma_addr, size); 617 result = ps3_dma_unmap(dev->d_region, dma_addr, size);
@@ -271,20 +622,20 @@ static void ps3_unmap_single(struct device *_dev, dma_addr_t dma_addr,
271 } 622 }
272} 623}
273 624
274static int ps3_map_sg(struct device *_dev, struct scatterlist *sg, int nents, 625static int ps3_sb_map_sg(struct device *_dev, struct scatterlist *sg, int nents,
275 enum dma_data_direction direction) 626 enum dma_data_direction direction)
276{ 627{
277#if defined(CONFIG_PS3_DYNAMIC_DMA) 628#if defined(CONFIG_PS3_DYNAMIC_DMA)
278 BUG_ON("do"); 629 BUG_ON("do");
279 return -EPERM; 630 return -EPERM;
280#else 631#else
281 struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev); 632 struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
282 int i; 633 int i;
283 634
284 for (i = 0; i < nents; i++, sg++) { 635 for (i = 0; i < nents; i++, sg++) {
285 int result = ps3_dma_map(dev->d_region, 636 int result = ps3_dma_map(dev->d_region,
286 page_to_phys(sg->page) + sg->offset, sg->length, 637 page_to_phys(sg->page) + sg->offset, sg->length,
287 &sg->dma_address); 638 &sg->dma_address, 0);
288 639
289 if (result) { 640 if (result) {
290 pr_debug("%s:%d: ps3_dma_map failed (%d)\n", 641 pr_debug("%s:%d: ps3_dma_map failed (%d)\n",
@@ -299,7 +650,15 @@ static int ps3_map_sg(struct device *_dev, struct scatterlist *sg, int nents,
299#endif 650#endif
300} 651}
301 652
302static void ps3_unmap_sg(struct device *_dev, struct scatterlist *sg, 653static int ps3_ioc0_map_sg(struct device *_dev, struct scatterlist *sg,
654 int nents,
655 enum dma_data_direction direction)
656{
657 BUG();
658 return 0;
659}
660
661static void ps3_sb_unmap_sg(struct device *_dev, struct scatterlist *sg,
303 int nents, enum dma_data_direction direction) 662 int nents, enum dma_data_direction direction)
304{ 663{
305#if defined(CONFIG_PS3_DYNAMIC_DMA) 664#if defined(CONFIG_PS3_DYNAMIC_DMA)
@@ -307,18 +666,34 @@ static void ps3_unmap_sg(struct device *_dev, struct scatterlist *sg,
307#endif 666#endif
308} 667}
309 668
669static void ps3_ioc0_unmap_sg(struct device *_dev, struct scatterlist *sg,
670 int nents, enum dma_data_direction direction)
671{
672 BUG();
673}
674
310static int ps3_dma_supported(struct device *_dev, u64 mask) 675static int ps3_dma_supported(struct device *_dev, u64 mask)
311{ 676{
312 return mask >= DMA_32BIT_MASK; 677 return mask >= DMA_32BIT_MASK;
313} 678}
314 679
315static struct dma_mapping_ops ps3_dma_ops = { 680static struct dma_mapping_ops ps3_sb_dma_ops = {
316 .alloc_coherent = ps3_alloc_coherent, 681 .alloc_coherent = ps3_alloc_coherent,
317 .free_coherent = ps3_free_coherent, 682 .free_coherent = ps3_free_coherent,
318 .map_single = ps3_map_single, 683 .map_single = ps3_sb_map_single,
319 .unmap_single = ps3_unmap_single, 684 .unmap_single = ps3_unmap_single,
320 .map_sg = ps3_map_sg, 685 .map_sg = ps3_sb_map_sg,
321 .unmap_sg = ps3_unmap_sg, 686 .unmap_sg = ps3_sb_unmap_sg,
687 .dma_supported = ps3_dma_supported
688};
689
690static struct dma_mapping_ops ps3_ioc0_dma_ops = {
691 .alloc_coherent = ps3_alloc_coherent,
692 .free_coherent = ps3_free_coherent,
693 .map_single = ps3_ioc0_map_single,
694 .unmap_single = ps3_unmap_single,
695 .map_sg = ps3_ioc0_map_sg,
696 .unmap_sg = ps3_ioc0_unmap_sg,
322 .dma_supported = ps3_dma_supported 697 .dma_supported = ps3_dma_supported
323}; 698};
324 699
@@ -328,7 +703,7 @@ static struct dma_mapping_ops ps3_dma_ops = {
328 703
329static void ps3_system_bus_release_device(struct device *_dev) 704static void ps3_system_bus_release_device(struct device *_dev)
330{ 705{
331 struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev); 706 struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
332 kfree(dev); 707 kfree(dev);
333} 708}
334 709
@@ -343,19 +718,38 @@ static void ps3_system_bus_release_device(struct device *_dev)
343int ps3_system_bus_device_register(struct ps3_system_bus_device *dev) 718int ps3_system_bus_device_register(struct ps3_system_bus_device *dev)
344{ 719{
345 int result; 720 int result;
346 static unsigned int dev_count = 1; 721 static unsigned int dev_ioc0_count;
722 static unsigned int dev_sb_count;
723 static unsigned int dev_vuart_count;
347 724
348 dev->core.parent = NULL; 725 if (!dev->core.parent)
726 dev->core.parent = &ps3_system_bus;
349 dev->core.bus = &ps3_system_bus_type; 727 dev->core.bus = &ps3_system_bus_type;
350 dev->core.release = ps3_system_bus_release_device; 728 dev->core.release = ps3_system_bus_release_device;
351 729
730 switch (dev->dev_type) {
731 case PS3_DEVICE_TYPE_IOC0:
732 dev->core.archdata.dma_ops = &ps3_ioc0_dma_ops;
733 snprintf(dev->core.bus_id, sizeof(dev->core.bus_id),
734 "ioc0_%02x", ++dev_ioc0_count);
735 break;
736 case PS3_DEVICE_TYPE_SB:
737 dev->core.archdata.dma_ops = &ps3_sb_dma_ops;
738 snprintf(dev->core.bus_id, sizeof(dev->core.bus_id),
739 "sb_%02x", ++dev_sb_count);
740
741 break;
742 case PS3_DEVICE_TYPE_VUART:
743 snprintf(dev->core.bus_id, sizeof(dev->core.bus_id),
744 "vuart_%02x", ++dev_vuart_count);
745 break;
746 default:
747 BUG();
748 };
749
352 dev->core.archdata.of_node = NULL; 750 dev->core.archdata.of_node = NULL;
353 dev->core.archdata.dma_ops = &ps3_dma_ops;
354 dev->core.archdata.numa_node = 0; 751 dev->core.archdata.numa_node = 0;
355 752
356 snprintf(dev->core.bus_id, sizeof(dev->core.bus_id), "sb_%02x",
357 dev_count++);
358
359 pr_debug("%s:%d add %s\n", __func__, __LINE__, dev->core.bus_id); 753 pr_debug("%s:%d add %s\n", __func__, __LINE__, dev->core.bus_id);
360 754
361 result = device_register(&dev->core); 755 result = device_register(&dev->core);
@@ -368,9 +762,15 @@ int ps3_system_bus_driver_register(struct ps3_system_bus_driver *drv)
368{ 762{
369 int result; 763 int result;
370 764
765 pr_debug(" -> %s:%d: %s\n", __func__, __LINE__, drv->core.name);
766
767 if (!firmware_has_feature(FW_FEATURE_PS3_LV1))
768 return -ENODEV;
769
371 drv->core.bus = &ps3_system_bus_type; 770 drv->core.bus = &ps3_system_bus_type;
372 771
373 result = driver_register(&drv->core); 772 result = driver_register(&drv->core);
773 pr_debug(" <- %s:%d: %s\n", __func__, __LINE__, drv->core.name);
374 return result; 774 return result;
375} 775}
376 776
@@ -378,7 +778,9 @@ EXPORT_SYMBOL_GPL(ps3_system_bus_driver_register);
378 778
379void ps3_system_bus_driver_unregister(struct ps3_system_bus_driver *drv) 779void ps3_system_bus_driver_unregister(struct ps3_system_bus_driver *drv)
380{ 780{
781 pr_debug(" -> %s:%d: %s\n", __func__, __LINE__, drv->core.name);
381 driver_unregister(&drv->core); 782 driver_unregister(&drv->core);
783 pr_debug(" <- %s:%d: %s\n", __func__, __LINE__, drv->core.name);
382} 784}
383 785
384EXPORT_SYMBOL_GPL(ps3_system_bus_driver_unregister); 786EXPORT_SYMBOL_GPL(ps3_system_bus_driver_unregister);
diff --git a/arch/powerpc/platforms/ps3/time.c b/arch/powerpc/platforms/ps3/time.c
index 1bae8b19b363..802a9ccacb5e 100644
--- a/arch/powerpc/platforms/ps3/time.c
+++ b/arch/powerpc/platforms/ps3/time.c
@@ -39,7 +39,7 @@ static void _dump_tm(const struct rtc_time *tm, const char* func, int line)
39} 39}
40 40
41#define dump_time(_a) _dump_time(_a, __func__, __LINE__) 41#define dump_time(_a) _dump_time(_a, __func__, __LINE__)
42static void __attribute__ ((unused)) _dump_time(int time, const char* func, 42static void __maybe_unused _dump_time(int time, const char *func,
43 int line) 43 int line)
44{ 44{
45 struct rtc_time tm; 45 struct rtc_time tm;
diff --git a/arch/powerpc/platforms/pseries/Makefile b/arch/powerpc/platforms/pseries/Makefile
index ae1fc92dc1c9..992ba6753cf2 100644
--- a/arch/powerpc/platforms/pseries/Makefile
+++ b/arch/powerpc/platforms/pseries/Makefile
@@ -8,7 +8,7 @@ obj-y := lpar.o hvCall.o nvram.o reconfig.o \
8obj-$(CONFIG_SMP) += smp.o 8obj-$(CONFIG_SMP) += smp.o
9obj-$(CONFIG_XICS) += xics.o 9obj-$(CONFIG_XICS) += xics.o
10obj-$(CONFIG_SCANLOG) += scanlog.o 10obj-$(CONFIG_SCANLOG) += scanlog.o
11obj-$(CONFIG_EEH) += eeh.o eeh_cache.o eeh_driver.o eeh_event.o 11obj-$(CONFIG_EEH) += eeh.o eeh_cache.o eeh_driver.o eeh_event.o eeh_sysfs.o
12obj-$(CONFIG_KEXEC) += kexec.o 12obj-$(CONFIG_KEXEC) += kexec.o
13obj-$(CONFIG_PCI) += pci.o pci_dlpar.o 13obj-$(CONFIG_PCI) += pci.o pci_dlpar.o
14obj-$(CONFIG_PCI_MSI) += msi.o 14obj-$(CONFIG_PCI_MSI) += msi.o
diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c
index 5f3e6d8659fe..b8770395013d 100644
--- a/arch/powerpc/platforms/pseries/eeh.c
+++ b/arch/powerpc/platforms/pseries/eeh.c
@@ -1,6 +1,8 @@
1/* 1/*
2 * eeh.c 2 * eeh.c
3 * Copyright (C) 2001 Dave Engebretsen & Todd Inglett IBM Corporation 3 * Copyright IBM Corporation 2001, 2005, 2006
4 * Copyright Dave Engebretsen & Todd Inglett 2001
5 * Copyright Linas Vepstas 2005, 2006
4 * 6 *
5 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by 8 * it under the terms of the GNU General Public License as published by
@@ -15,6 +17,8 @@
15 * You should have received a copy of the GNU General Public License 17 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software 18 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 * Please address comments and feedback to Linas Vepstas <linas@austin.ibm.com>
18 */ 22 */
19 23
20#include <linux/delay.h> 24#include <linux/delay.h>
@@ -117,7 +121,6 @@ static unsigned long no_cfg_addr;
117static unsigned long ignored_check; 121static unsigned long ignored_check;
118static unsigned long total_mmio_ffs; 122static unsigned long total_mmio_ffs;
119static unsigned long false_positives; 123static unsigned long false_positives;
120static unsigned long ignored_failures;
121static unsigned long slot_resets; 124static unsigned long slot_resets;
122 125
123#define IS_BRIDGE(class_code) (((class_code)<<16) == PCI_BASE_CLASS_BRIDGE) 126#define IS_BRIDGE(class_code) (((class_code)<<16) == PCI_BASE_CLASS_BRIDGE)
@@ -505,6 +508,7 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev)
505 printk(KERN_WARNING "EEH: read_slot_reset_state() failed; rc=%d dn=%s\n", 508 printk(KERN_WARNING "EEH: read_slot_reset_state() failed; rc=%d dn=%s\n",
506 ret, dn->full_name); 509 ret, dn->full_name);
507 false_positives++; 510 false_positives++;
511 pdn->eeh_false_positives ++;
508 rc = 0; 512 rc = 0;
509 goto dn_unlock; 513 goto dn_unlock;
510 } 514 }
@@ -513,6 +517,7 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev)
513 * they are empty when they don't have children. */ 517 * they are empty when they don't have children. */
514 if ((rets[0] == 5) && (dn->child == NULL)) { 518 if ((rets[0] == 5) && (dn->child == NULL)) {
515 false_positives++; 519 false_positives++;
520 pdn->eeh_false_positives ++;
516 rc = 0; 521 rc = 0;
517 goto dn_unlock; 522 goto dn_unlock;
518 } 523 }
@@ -522,6 +527,7 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev)
522 printk(KERN_WARNING "EEH: event on unsupported device, rc=%d dn=%s\n", 527 printk(KERN_WARNING "EEH: event on unsupported device, rc=%d dn=%s\n",
523 ret, dn->full_name); 528 ret, dn->full_name);
524 false_positives++; 529 false_positives++;
530 pdn->eeh_false_positives ++;
525 rc = 0; 531 rc = 0;
526 goto dn_unlock; 532 goto dn_unlock;
527 } 533 }
@@ -529,6 +535,7 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev)
529 /* If not the kind of error we know about, punt. */ 535 /* If not the kind of error we know about, punt. */
530 if (rets[0] != 1 && rets[0] != 2 && rets[0] != 4 && rets[0] != 5) { 536 if (rets[0] != 1 && rets[0] != 2 && rets[0] != 4 && rets[0] != 5) {
531 false_positives++; 537 false_positives++;
538 pdn->eeh_false_positives ++;
532 rc = 0; 539 rc = 0;
533 goto dn_unlock; 540 goto dn_unlock;
534 } 541 }
@@ -921,6 +928,7 @@ static void *early_enable_eeh(struct device_node *dn, void *data)
921 pdn->eeh_mode = 0; 928 pdn->eeh_mode = 0;
922 pdn->eeh_check_count = 0; 929 pdn->eeh_check_count = 0;
923 pdn->eeh_freeze_count = 0; 930 pdn->eeh_freeze_count = 0;
931 pdn->eeh_false_positives = 0;
924 932
925 if (status && strcmp(status, "ok") != 0) 933 if (status && strcmp(status, "ok") != 0)
926 return NULL; /* ignore devices with bad status */ 934 return NULL; /* ignore devices with bad status */
@@ -1139,7 +1147,8 @@ static void eeh_add_device_late(struct pci_dev *dev)
1139 pdn = PCI_DN(dn); 1147 pdn = PCI_DN(dn);
1140 pdn->pcidev = dev; 1148 pdn->pcidev = dev;
1141 1149
1142 pci_addr_cache_insert_device (dev); 1150 pci_addr_cache_insert_device(dev);
1151 eeh_sysfs_add_device(dev);
1143} 1152}
1144 1153
1145void eeh_add_device_tree_late(struct pci_bus *bus) 1154void eeh_add_device_tree_late(struct pci_bus *bus)
@@ -1178,6 +1187,7 @@ static void eeh_remove_device(struct pci_dev *dev)
1178 printk(KERN_DEBUG "EEH: remove device %s\n", pci_name(dev)); 1187 printk(KERN_DEBUG "EEH: remove device %s\n", pci_name(dev));
1179#endif 1188#endif
1180 pci_addr_cache_remove_device(dev); 1189 pci_addr_cache_remove_device(dev);
1190 eeh_sysfs_remove_device(dev);
1181 1191
1182 dn = pci_device_to_OF_node(dev); 1192 dn = pci_device_to_OF_node(dev);
1183 if (PCI_DN(dn)->pcidev) { 1193 if (PCI_DN(dn)->pcidev) {
@@ -1214,11 +1224,10 @@ static int proc_eeh_show(struct seq_file *m, void *v)
1214 "check not wanted=%ld\n" 1224 "check not wanted=%ld\n"
1215 "eeh_total_mmio_ffs=%ld\n" 1225 "eeh_total_mmio_ffs=%ld\n"
1216 "eeh_false_positives=%ld\n" 1226 "eeh_false_positives=%ld\n"
1217 "eeh_ignored_failures=%ld\n"
1218 "eeh_slot_resets=%ld\n", 1227 "eeh_slot_resets=%ld\n",
1219 no_device, no_dn, no_cfg_addr, 1228 no_device, no_dn, no_cfg_addr,
1220 ignored_check, total_mmio_ffs, 1229 ignored_check, total_mmio_ffs,
1221 false_positives, ignored_failures, 1230 false_positives,
1222 slot_resets); 1231 slot_resets);
1223 } 1232 }
1224 1233
diff --git a/arch/powerpc/platforms/pseries/eeh_cache.c b/arch/powerpc/platforms/pseries/eeh_cache.c
index f2bae04424f8..e49c815eae23 100644
--- a/arch/powerpc/platforms/pseries/eeh_cache.c
+++ b/arch/powerpc/platforms/pseries/eeh_cache.c
@@ -2,7 +2,8 @@
2 * eeh_cache.c 2 * eeh_cache.c
3 * PCI address cache; allows the lookup of PCI devices based on I/O address 3 * PCI address cache; allows the lookup of PCI devices based on I/O address
4 * 4 *
5 * Copyright (C) 2004 Linas Vepstas <linas@austin.ibm.com> IBM Corporation 5 * Copyright IBM Corporation 2004
6 * Copyright Linas Vepstas <linas@austin.ibm.com> 2004
6 * 7 *
7 * This program is free software; you can redistribute it and/or modify 8 * 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 * it under the terms of the GNU General Public License as published by
@@ -295,6 +296,8 @@ void __init pci_addr_cache_build(void)
295 continue; 296 continue;
296 pci_dev_get (dev); /* matching put is in eeh_remove_device() */ 297 pci_dev_get (dev); /* matching put is in eeh_remove_device() */
297 PCI_DN(dn)->pcidev = dev; 298 PCI_DN(dn)->pcidev = dev;
299
300 eeh_sysfs_add_device(dev);
298 } 301 }
299 302
300#ifdef DEBUG 303#ifdef DEBUG
diff --git a/arch/powerpc/platforms/pseries/eeh_driver.c b/arch/powerpc/platforms/pseries/eeh_driver.c
index 161a5844ab6c..15e015ef6865 100644
--- a/arch/powerpc/platforms/pseries/eeh_driver.c
+++ b/arch/powerpc/platforms/pseries/eeh_driver.c
@@ -1,6 +1,7 @@
1/* 1/*
2 * PCI Error Recovery Driver for RPA-compliant PPC64 platform. 2 * PCI Error Recovery Driver for RPA-compliant PPC64 platform.
3 * Copyright (C) 2004, 2005 Linas Vepstas <linas@linas.org> 3 * Copyright IBM Corp. 2004 2005
4 * Copyright Linas Vepstas <linas@linas.org> 2004, 2005
4 * 5 *
5 * All rights reserved. 6 * All rights reserved.
6 * 7 *
@@ -19,8 +20,7 @@
19 * along with this program; if not, write to the Free Software 20 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 * 22 *
22 * Send feedback to <linas@us.ibm.com> 23 * Send comments and feedback to Linas Vepstas <linas@austin.ibm.com>
23 *
24 */ 24 */
25#include <linux/delay.h> 25#include <linux/delay.h>
26#include <linux/interrupt.h> 26#include <linux/interrupt.h>
diff --git a/arch/powerpc/platforms/pseries/eeh_sysfs.c b/arch/powerpc/platforms/pseries/eeh_sysfs.c
new file mode 100644
index 000000000000..15e13b568904
--- /dev/null
+++ b/arch/powerpc/platforms/pseries/eeh_sysfs.c
@@ -0,0 +1,87 @@
1/*
2 * Sysfs entries for PCI Error Recovery for PAPR-compliant platform.
3 * Copyright IBM Corporation 2007
4 * Copyright Linas Vepstas <linas@austin.ibm.com> 2007
5 *
6 * All rights reserved.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or (at
11 * your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
16 * NON INFRINGEMENT. See the GNU General Public License for more
17 * details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 *
23 * Send comments and feedback to Linas Vepstas <linas@austin.ibm.com>
24 */
25#include <linux/pci.h>
26#include <asm/ppc-pci.h>
27#include <asm/pci-bridge.h>
28#include <linux/kobject.h>
29
30/**
31 * EEH_SHOW_ATTR -- create sysfs entry for eeh statistic
32 * @_name: name of file in sysfs directory
33 * @_memb: name of member in struct pci_dn to access
34 * @_format: printf format for display
35 *
36 * All of the attributes look very similar, so just
37 * auto-gen a cut-n-paste routine to display them.
38 */
39#define EEH_SHOW_ATTR(_name,_memb,_format) \
40static ssize_t eeh_show_##_name(struct device *dev, \
41 struct device_attribute *attr, char *buf) \
42{ \
43 struct pci_dev *pdev = to_pci_dev(dev); \
44 struct device_node *dn = pci_device_to_OF_node(pdev); \
45 struct pci_dn *pdn; \
46 \
47 if (!dn || PCI_DN(dn) == NULL) \
48 return 0; \
49 \
50 pdn = PCI_DN(dn); \
51 return sprintf(buf, _format "\n", pdn->_memb); \
52} \
53static DEVICE_ATTR(_name, S_IRUGO, eeh_show_##_name, NULL);
54
55
56EEH_SHOW_ATTR(eeh_mode, eeh_mode, "0x%x");
57EEH_SHOW_ATTR(eeh_config_addr, eeh_config_addr, "0x%x");
58EEH_SHOW_ATTR(eeh_pe_config_addr, eeh_pe_config_addr, "0x%x");
59EEH_SHOW_ATTR(eeh_check_count, eeh_check_count, "%d");
60EEH_SHOW_ATTR(eeh_freeze_count, eeh_freeze_count, "%d");
61EEH_SHOW_ATTR(eeh_false_positives, eeh_false_positives, "%d");
62
63void eeh_sysfs_add_device(struct pci_dev *pdev)
64{
65 int rc=0;
66
67 rc += device_create_file(&pdev->dev, &dev_attr_eeh_mode);
68 rc += device_create_file(&pdev->dev, &dev_attr_eeh_config_addr);
69 rc += device_create_file(&pdev->dev, &dev_attr_eeh_pe_config_addr);
70 rc += device_create_file(&pdev->dev, &dev_attr_eeh_check_count);
71 rc += device_create_file(&pdev->dev, &dev_attr_eeh_false_positives);
72 rc += device_create_file(&pdev->dev, &dev_attr_eeh_freeze_count);
73
74 if (rc)
75 printk(KERN_WARNING "EEH: Unable to create sysfs entries\n");
76}
77
78void eeh_sysfs_remove_device(struct pci_dev *pdev)
79{
80 device_remove_file(&pdev->dev, &dev_attr_eeh_mode);
81 device_remove_file(&pdev->dev, &dev_attr_eeh_config_addr);
82 device_remove_file(&pdev->dev, &dev_attr_eeh_pe_config_addr);
83 device_remove_file(&pdev->dev, &dev_attr_eeh_check_count);
84 device_remove_file(&pdev->dev, &dev_attr_eeh_false_positives);
85 device_remove_file(&pdev->dev, &dev_attr_eeh_freeze_count);
86}
87
diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c
index 362dfbc260a6..8cc6eeeaae2f 100644
--- a/arch/powerpc/platforms/pseries/lpar.c
+++ b/arch/powerpc/platforms/pseries/lpar.c
@@ -373,12 +373,23 @@ static void pSeries_lpar_hptab_clear(void)
373{ 373{
374 unsigned long size_bytes = 1UL << ppc64_pft_size; 374 unsigned long size_bytes = 1UL << ppc64_pft_size;
375 unsigned long hpte_count = size_bytes >> 4; 375 unsigned long hpte_count = size_bytes >> 4;
376 unsigned long dummy1, dummy2; 376 unsigned long dummy1, dummy2, dword0;
377 long lpar_rc;
377 int i; 378 int i;
378 379
379 /* TODO: Use bulk call */ 380 /* TODO: Use bulk call */
380 for (i = 0; i < hpte_count; i++) 381 for (i = 0; i < hpte_count; i++) {
381 plpar_pte_remove_raw(0, i, 0, &dummy1, &dummy2); 382 /* dont remove HPTEs with VRMA mappings */
383 lpar_rc = plpar_pte_remove_raw(H_ANDCOND, i, HPTE_V_1TB_SEG,
384 &dummy1, &dummy2);
385 if (lpar_rc == H_NOT_FOUND) {
386 lpar_rc = plpar_pte_read_raw(0, i, &dword0, &dummy1);
387 if (!lpar_rc && ((dword0 & HPTE_V_VRMA_MASK)
388 != HPTE_V_VRMA_MASK))
389 /* Can be hpte for 1TB Seg. So remove it */
390 plpar_pte_remove_raw(0, i, 0, &dummy1, &dummy2);
391 }
392 }
382} 393}
383 394
384/* 395/*
diff --git a/arch/powerpc/platforms/pseries/pci_dlpar.c b/arch/powerpc/platforms/pseries/pci_dlpar.c
index ffaf6c5c517b..47f0e0857f0e 100644
--- a/arch/powerpc/platforms/pseries/pci_dlpar.c
+++ b/arch/powerpc/platforms/pseries/pci_dlpar.c
@@ -110,8 +110,6 @@ pcibios_fixup_new_pci_devices(struct pci_bus *bus, int fix_bus)
110 } 110 }
111 } 111 }
112 } 112 }
113
114 eeh_add_device_tree_late(bus);
115} 113}
116EXPORT_SYMBOL_GPL(pcibios_fixup_new_pci_devices); 114EXPORT_SYMBOL_GPL(pcibios_fixup_new_pci_devices);
117 115
@@ -139,6 +137,8 @@ pcibios_pci_config_bridge(struct pci_dev *dev)
139 137
140 /* Make the discovered devices available */ 138 /* Make the discovered devices available */
141 pci_bus_add_devices(child_bus); 139 pci_bus_add_devices(child_bus);
140
141 eeh_add_device_tree_late(child_bus);
142 return 0; 142 return 0;
143} 143}
144 144
@@ -171,6 +171,7 @@ pcibios_add_pci_devices(struct pci_bus * bus)
171 if (!list_empty(&bus->devices)) { 171 if (!list_empty(&bus->devices)) {
172 pcibios_fixup_new_pci_devices(bus, 0); 172 pcibios_fixup_new_pci_devices(bus, 0);
173 pci_bus_add_devices(bus); 173 pci_bus_add_devices(bus);
174 eeh_add_device_tree_late(bus);
174 } 175 }
175 } else if (mode == PCI_PROBE_NORMAL) { 176 } else if (mode == PCI_PROBE_NORMAL) {
176 /* use legacy probe */ 177 /* use legacy probe */
@@ -179,6 +180,7 @@ pcibios_add_pci_devices(struct pci_bus * bus)
179 if (num) { 180 if (num) {
180 pcibios_fixup_new_pci_devices(bus, 1); 181 pcibios_fixup_new_pci_devices(bus, 1);
181 pci_bus_add_devices(bus); 182 pci_bus_add_devices(bus);
183 eeh_add_device_tree_late(bus);
182 } 184 }
183 185
184 list_for_each_entry(dev, &bus->devices, bus_list) 186 list_for_each_entry(dev, &bus->devices, bus_list)
@@ -200,8 +202,6 @@ struct pci_controller * __devinit init_phb_dynamic(struct device_node *dn)
200 rtas_setup_phb(phb); 202 rtas_setup_phb(phb);
201 pci_process_bridge_OF_ranges(phb, dn, 0); 203 pci_process_bridge_OF_ranges(phb, dn, 0);
202 204
203 pci_setup_phb_io_dynamic(phb, primary);
204
205 pci_devs_phb_init_dynamic(phb); 205 pci_devs_phb_init_dynamic(phb);
206 206
207 if (dn->child) 207 if (dn->child)
@@ -210,6 +210,7 @@ struct pci_controller * __devinit init_phb_dynamic(struct device_node *dn)
210 scan_phb(phb); 210 scan_phb(phb);
211 pcibios_fixup_new_pci_devices(phb->bus, 0); 211 pcibios_fixup_new_pci_devices(phb->bus, 0);
212 pci_bus_add_devices(phb->bus); 212 pci_bus_add_devices(phb->bus);
213 eeh_add_device_tree_late(phb->bus);
213 214
214 return phb; 215 return phb;
215} 216}
diff --git a/arch/powerpc/platforms/pseries/plpar_wrappers.h b/arch/powerpc/platforms/pseries/plpar_wrappers.h
index 2e4d10c9eea8..d003c80fa31d 100644
--- a/arch/powerpc/platforms/pseries/plpar_wrappers.h
+++ b/arch/powerpc/platforms/pseries/plpar_wrappers.h
@@ -108,6 +108,21 @@ static inline long plpar_pte_read(unsigned long flags, unsigned long ptex,
108 return rc; 108 return rc;
109} 109}
110 110
111/* plpar_pte_read_raw can be called in real mode. It calls plpar_hcall_raw */
112static inline long plpar_pte_read_raw(unsigned long flags, unsigned long ptex,
113 unsigned long *old_pteh_ret, unsigned long *old_ptel_ret)
114{
115 long rc;
116 unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
117
118 rc = plpar_hcall_raw(H_READ, retbuf, flags, ptex);
119
120 *old_pteh_ret = retbuf[0];
121 *old_ptel_ret = retbuf[1];
122
123 return rc;
124}
125
111static inline long plpar_pte_protect(unsigned long flags, unsigned long ptex, 126static inline long plpar_pte_protect(unsigned long flags, unsigned long ptex,
112 unsigned long avpn) 127 unsigned long avpn)
113{ 128{
diff --git a/arch/powerpc/platforms/pseries/pseries.h b/arch/powerpc/platforms/pseries/pseries.h
index 2729d559fd91..61e19f78b923 100644
--- a/arch/powerpc/platforms/pseries/pseries.h
+++ b/arch/powerpc/platforms/pseries/pseries.h
@@ -33,6 +33,8 @@ static inline void setup_kexec_cpu_down_xics(void) { }
33static inline void setup_kexec_cpu_down_mpic(void) { } 33static inline void setup_kexec_cpu_down_mpic(void) { }
34#endif 34#endif
35 35
36extern void pSeries_final_fixup(void);
37
36/* Poweron flag used for enabling auto ups restart */ 38/* Poweron flag used for enabling auto ups restart */
37extern unsigned long rtas_poweron_auto; 39extern unsigned long rtas_poweron_auto;
38 40
diff --git a/arch/powerpc/platforms/pseries/reconfig.c b/arch/powerpc/platforms/pseries/reconfig.c
index 5aa97aff3391..c02f8742c54d 100644
--- a/arch/powerpc/platforms/pseries/reconfig.c
+++ b/arch/powerpc/platforms/pseries/reconfig.c
@@ -123,7 +123,7 @@ static int pSeries_reconfig_add_node(const char *path, struct property *proplist
123 strcpy(np->full_name, path); 123 strcpy(np->full_name, path);
124 124
125 np->properties = proplist; 125 np->properties = proplist;
126 OF_MARK_DYNAMIC(np); 126 of_node_set_flag(np, OF_DYNAMIC);
127 kref_init(&np->kref); 127 kref_init(&np->kref);
128 128
129 np->parent = derive_parent(path); 129 np->parent = derive_parent(path);
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index a031d99becb7..59e69f085cb4 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -399,6 +399,7 @@ static void pseries_dedicated_idle_sleep(void)
399 * a good time to find other work to dispatch. 399 * a good time to find other work to dispatch.
400 */ 400 */
401 get_lppaca()->idle = 1; 401 get_lppaca()->idle = 1;
402 get_lppaca()->donate_dedicated_cpu = 1;
402 403
403 /* 404 /*
404 * We come in with interrupts disabled, and need_resched() 405 * We come in with interrupts disabled, and need_resched()
@@ -431,6 +432,7 @@ static void pseries_dedicated_idle_sleep(void)
431 432
432out: 433out:
433 HMT_medium(); 434 HMT_medium();
435 get_lppaca()->donate_dedicated_cpu = 0;
434 get_lppaca()->idle = 0; 436 get_lppaca()->idle = 0;
435} 437}
436 438
diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c
index f1df942072bb..5bd90a7eb763 100644
--- a/arch/powerpc/platforms/pseries/xics.c
+++ b/arch/powerpc/platforms/pseries/xics.c
@@ -156,9 +156,9 @@ static inline void lpar_qirr_info(int n_cpu , u8 value)
156 156
157 157
158#ifdef CONFIG_SMP 158#ifdef CONFIG_SMP
159static int get_irq_server(unsigned int virq) 159static int get_irq_server(unsigned int virq, unsigned int strict_check)
160{ 160{
161 unsigned int server; 161 int server;
162 /* For the moment only implement delivery to all cpus or one cpu */ 162 /* For the moment only implement delivery to all cpus or one cpu */
163 cpumask_t cpumask = irq_desc[virq].affinity; 163 cpumask_t cpumask = irq_desc[virq].affinity;
164 cpumask_t tmp = CPU_MASK_NONE; 164 cpumask_t tmp = CPU_MASK_NONE;
@@ -166,22 +166,25 @@ static int get_irq_server(unsigned int virq)
166 if (!distribute_irqs) 166 if (!distribute_irqs)
167 return default_server; 167 return default_server;
168 168
169 if (cpus_equal(cpumask, CPU_MASK_ALL)) { 169 if (!cpus_equal(cpumask, CPU_MASK_ALL)) {
170 server = default_distrib_server;
171 } else {
172 cpus_and(tmp, cpu_online_map, cpumask); 170 cpus_and(tmp, cpu_online_map, cpumask);
173 171
174 if (cpus_empty(tmp)) 172 server = first_cpu(tmp);
175 server = default_distrib_server; 173
176 else 174 if (server < NR_CPUS)
177 server = get_hard_smp_processor_id(first_cpu(tmp)); 175 return get_hard_smp_processor_id(server);
176
177 if (strict_check)
178 return -1;
178 } 179 }
179 180
180 return server; 181 if (cpus_equal(cpu_online_map, cpu_present_map))
182 return default_distrib_server;
181 183
184 return default_server;
182} 185}
183#else 186#else
184static int get_irq_server(unsigned int virq) 187static int get_irq_server(unsigned int virq, unsigned int strict_check)
185{ 188{
186 return default_server; 189 return default_server;
187} 190}
@@ -192,7 +195,7 @@ static void xics_unmask_irq(unsigned int virq)
192{ 195{
193 unsigned int irq; 196 unsigned int irq;
194 int call_status; 197 int call_status;
195 unsigned int server; 198 int server;
196 199
197 pr_debug("xics: unmask virq %d\n", virq); 200 pr_debug("xics: unmask virq %d\n", virq);
198 201
@@ -201,7 +204,7 @@ static void xics_unmask_irq(unsigned int virq)
201 if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS) 204 if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS)
202 return; 205 return;
203 206
204 server = get_irq_server(virq); 207 server = get_irq_server(virq, 0);
205 208
206 call_status = rtas_call(ibm_set_xive, 3, 1, NULL, irq, server, 209 call_status = rtas_call(ibm_set_xive, 3, 1, NULL, irq, server,
207 DEFAULT_PRIORITY); 210 DEFAULT_PRIORITY);
@@ -398,8 +401,7 @@ static void xics_set_affinity(unsigned int virq, cpumask_t cpumask)
398 unsigned int irq; 401 unsigned int irq;
399 int status; 402 int status;
400 int xics_status[2]; 403 int xics_status[2];
401 unsigned long newmask; 404 int irq_server;
402 cpumask_t tmp = CPU_MASK_NONE;
403 405
404 irq = (unsigned int)irq_map[virq].hwirq; 406 irq = (unsigned int)irq_map[virq].hwirq;
405 if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS) 407 if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS)
@@ -413,18 +415,21 @@ static void xics_set_affinity(unsigned int virq, cpumask_t cpumask)
413 return; 415 return;
414 } 416 }
415 417
416 /* For the moment only implement delivery to all cpus or one cpu */ 418 /*
417 if (cpus_equal(cpumask, CPU_MASK_ALL)) { 419 * For the moment only implement delivery to all cpus or one cpu.
418 newmask = default_distrib_server; 420 * Get current irq_server for the given irq
419 } else { 421 */
420 cpus_and(tmp, cpu_online_map, cpumask); 422 irq_server = get_irq_server(irq, 1);
421 if (cpus_empty(tmp)) 423 if (irq_server == -1) {
422 return; 424 char cpulist[128];
423 newmask = get_hard_smp_processor_id(first_cpu(tmp)); 425 cpumask_scnprintf(cpulist, sizeof(cpulist), cpumask);
426 printk(KERN_WARNING "xics_set_affinity: No online cpus in "
427 "the mask %s for irq %d\n", cpulist, virq);
428 return;
424 } 429 }
425 430
426 status = rtas_call(ibm_set_xive, 3, 1, NULL, 431 status = rtas_call(ibm_set_xive, 3, 1, NULL,
427 irq, newmask, xics_status[1]); 432 irq, irq_server, xics_status[1]);
428 433
429 if (status) { 434 if (status) {
430 printk(KERN_ERR "xics_set_affinity: irq=%u ibm,set-xive " 435 printk(KERN_ERR "xics_set_affinity: irq=%u ibm,set-xive "