aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms
diff options
context:
space:
mode:
authorGrant Likely <grant.likely@secretlab.ca>2010-01-28 16:38:25 -0500
committerGrant Likely <grant.likely@secretlab.ca>2010-01-28 16:38:25 -0500
commit0ada0a73120c28cc432bcdbac061781465c2f48f (patch)
treed17cadd4ea47e25d9e48e7d409a39c84268fbd27 /arch/powerpc/platforms
parent6016a363f6b56b46b24655bcfc0499b715851cf3 (diff)
parent92dcffb916d309aa01778bf8963a6932e4014d07 (diff)
Merge commit 'v2.6.33-rc5' into secretlab/test-devicetree
Diffstat (limited to 'arch/powerpc/platforms')
-rw-r--r--arch/powerpc/platforms/512x/mpc5121_ads_cpld.c4
-rw-r--r--arch/powerpc/platforms/52xx/Kconfig5
-rw-r--r--arch/powerpc/platforms/52xx/Makefile1
-rw-r--r--arch/powerpc/platforms/52xx/efika.c2
-rw-r--r--arch/powerpc/platforms/52xx/media5200.c14
-rw-r--r--arch/powerpc/platforms/52xx/mpc52xx_gpt.c432
-rw-r--r--arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c560
-rw-r--r--arch/powerpc/platforms/52xx/mpc52xx_pci.c2
-rw-r--r--arch/powerpc/platforms/52xx/mpc52xx_pic.c10
-rw-r--r--arch/powerpc/platforms/82xx/pq2ads-pci-pic.c3
-rw-r--r--arch/powerpc/platforms/83xx/mpc832x_rdb.c2
-rw-r--r--arch/powerpc/platforms/83xx/suspend.c53
-rw-r--r--arch/powerpc/platforms/85xx/Kconfig23
-rw-r--r--arch/powerpc/platforms/85xx/Makefile1
-rw-r--r--arch/powerpc/platforms/85xx/corenet_ds.c125
-rw-r--r--arch/powerpc/platforms/85xx/corenet_ds.h19
-rw-r--r--arch/powerpc/platforms/85xx/mpc85xx_mds.c3
-rw-r--r--arch/powerpc/platforms/85xx/mpc85xx_rdb.c34
-rw-r--r--arch/powerpc/platforms/85xx/p4080_ds.c74
-rw-r--r--arch/powerpc/platforms/85xx/socrates_fpga_pic.c6
-rw-r--r--arch/powerpc/platforms/86xx/Kconfig3
-rw-r--r--arch/powerpc/platforms/86xx/gef_pic.c6
-rw-r--r--arch/powerpc/platforms/86xx/gef_ppc9a.c5
-rw-r--r--arch/powerpc/platforms/86xx/gef_sbc310.c5
-rw-r--r--arch/powerpc/platforms/86xx/gef_sbc610.c5
-rw-r--r--arch/powerpc/platforms/86xx/mpc8610_hpcd.c48
-rw-r--r--arch/powerpc/platforms/8xx/m8xx_setup.c2
-rw-r--r--arch/powerpc/platforms/Kconfig9
-rw-r--r--arch/powerpc/platforms/Kconfig.cputype19
-rw-r--r--arch/powerpc/platforms/Makefile2
-rw-r--r--arch/powerpc/platforms/amigaone/setup.c2
-rw-r--r--arch/powerpc/platforms/cell/axon_msi.c2
-rw-r--r--arch/powerpc/platforms/cell/beat_interrupt.c8
-rw-r--r--arch/powerpc/platforms/cell/interrupt.c28
-rw-r--r--arch/powerpc/platforms/cell/spider-pic.c8
-rw-r--r--arch/powerpc/platforms/cell/spufs/Makefile6
-rw-r--r--arch/powerpc/platforms/cell/spufs/coredump.c2
-rw-r--r--arch/powerpc/platforms/cell/spufs/file.c2
-rw-r--r--arch/powerpc/platforms/chrp/Kconfig2
-rw-r--r--arch/powerpc/platforms/chrp/setup.c52
-rw-r--r--arch/powerpc/platforms/embedded6xx/Kconfig33
-rw-r--r--arch/powerpc/platforms/embedded6xx/Makefile4
-rw-r--r--arch/powerpc/platforms/embedded6xx/flipper-pic.c263
-rw-r--r--arch/powerpc/platforms/embedded6xx/flipper-pic.h25
-rw-r--r--arch/powerpc/platforms/embedded6xx/gamecube.c118
-rw-r--r--arch/powerpc/platforms/embedded6xx/hlwd-pic.c241
-rw-r--r--arch/powerpc/platforms/embedded6xx/hlwd-pic.h22
-rw-r--r--arch/powerpc/platforms/embedded6xx/usbgecko_udbg.c328
-rw-r--r--arch/powerpc/platforms/embedded6xx/usbgecko_udbg.h32
-rw-r--r--arch/powerpc/platforms/embedded6xx/wii.c268
-rw-r--r--arch/powerpc/platforms/iseries/htab.c8
-rw-r--r--arch/powerpc/platforms/iseries/irq.c8
-rw-r--r--arch/powerpc/platforms/iseries/mf.c147
-rw-r--r--arch/powerpc/platforms/iseries/vio.c2
-rw-r--r--arch/powerpc/platforms/iseries/viopath.c2
-rw-r--r--arch/powerpc/platforms/pasemi/setup.c10
-rw-r--r--arch/powerpc/platforms/powermac/bootx_init.c2
-rw-r--r--arch/powerpc/platforms/powermac/low_i2c.c25
-rw-r--r--arch/powerpc/platforms/powermac/pci.c2
-rw-r--r--arch/powerpc/platforms/powermac/pic.c12
-rw-r--r--arch/powerpc/platforms/ps3/interrupt.c2
-rw-r--r--arch/powerpc/platforms/ps3/mm.c2
-rw-r--r--arch/powerpc/platforms/pseries/Kconfig5
-rw-r--r--arch/powerpc/platforms/pseries/Makefile4
-rw-r--r--arch/powerpc/platforms/pseries/cmm.c283
-rw-r--r--arch/powerpc/platforms/pseries/dlpar.c548
-rw-r--r--arch/powerpc/platforms/pseries/dtl.c4
-rw-r--r--arch/powerpc/platforms/pseries/eeh_driver.c18
-rw-r--r--arch/powerpc/platforms/pseries/hotplug-cpu.c182
-rw-r--r--arch/powerpc/platforms/pseries/hvCall.S132
-rw-r--r--arch/powerpc/platforms/pseries/hvCall_inst.c38
-rw-r--r--arch/powerpc/platforms/pseries/lpar.c33
-rw-r--r--arch/powerpc/platforms/pseries/offline_states.h18
-rw-r--r--arch/powerpc/platforms/pseries/plpar_wrappers.h22
-rw-r--r--arch/powerpc/platforms/pseries/reconfig.c8
-rw-r--r--arch/powerpc/platforms/pseries/rtasd.c519
-rw-r--r--arch/powerpc/platforms/pseries/scanlog.c4
-rw-r--r--arch/powerpc/platforms/pseries/smp.c19
-rw-r--r--arch/powerpc/platforms/pseries/xics.c84
79 files changed, 4168 insertions, 898 deletions
diff --git a/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c b/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c
index a6ce80566625..da9b20a63769 100644
--- a/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c
+++ b/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c
@@ -79,7 +79,7 @@ cpld_unmask_irq(unsigned int irq)
79} 79}
80 80
81static struct irq_chip cpld_pic = { 81static struct irq_chip cpld_pic = {
82 .typename = " CPLD PIC ", 82 .name = " CPLD PIC ",
83 .mask = cpld_mask_irq, 83 .mask = cpld_mask_irq,
84 .ack = cpld_mask_irq, 84 .ack = cpld_mask_irq,
85 .unmask = cpld_unmask_irq, 85 .unmask = cpld_unmask_irq,
@@ -132,7 +132,7 @@ static int
132cpld_pic_host_map(struct irq_host *h, unsigned int virq, 132cpld_pic_host_map(struct irq_host *h, unsigned int virq,
133 irq_hw_number_t hw) 133 irq_hw_number_t hw)
134{ 134{
135 get_irq_desc(virq)->status |= IRQ_LEVEL; 135 irq_to_desc(virq)->status |= IRQ_LEVEL;
136 set_irq_chip_and_handler(virq, &cpld_pic, handle_level_irq); 136 set_irq_chip_and_handler(virq, &cpld_pic, handle_level_irq);
137 return 0; 137 return 0;
138} 138}
diff --git a/arch/powerpc/platforms/52xx/Kconfig b/arch/powerpc/platforms/52xx/Kconfig
index 8b8e9560a315..47ea1be1481b 100644
--- a/arch/powerpc/platforms/52xx/Kconfig
+++ b/arch/powerpc/platforms/52xx/Kconfig
@@ -62,3 +62,8 @@ config PPC_MPC5200_GPIO
62 select GENERIC_GPIO 62 select GENERIC_GPIO
63 help 63 help
64 Enable gpiolib support for mpc5200 based boards 64 Enable gpiolib support for mpc5200 based boards
65
66config PPC_MPC5200_LPBFIFO
67 tristate "MPC5200 LocalPlus bus FIFO driver"
68 depends on PPC_MPC52xx
69 select PPC_BESTCOMM_GEN_BD
diff --git a/arch/powerpc/platforms/52xx/Makefile b/arch/powerpc/platforms/52xx/Makefile
index bfd4f52cf3dd..2bc8cd0c5cfc 100644
--- a/arch/powerpc/platforms/52xx/Makefile
+++ b/arch/powerpc/platforms/52xx/Makefile
@@ -15,3 +15,4 @@ ifeq ($(CONFIG_PPC_LITE5200),y)
15endif 15endif
16 16
17obj-$(CONFIG_PPC_MPC5200_GPIO) += mpc52xx_gpio.o 17obj-$(CONFIG_PPC_MPC5200_GPIO) += mpc52xx_gpio.o
18obj-$(CONFIG_PPC_MPC5200_LPBFIFO) += mpc52xx_lpbfifo.o
diff --git a/arch/powerpc/platforms/52xx/efika.c b/arch/powerpc/platforms/52xx/efika.c
index bcc69e1f77c1..45c0cb9b67e6 100644
--- a/arch/powerpc/platforms/52xx/efika.c
+++ b/arch/powerpc/platforms/52xx/efika.c
@@ -10,7 +10,7 @@
10 */ 10 */
11 11
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/utsrelease.h> 13#include <generated/utsrelease.h>
14#include <linux/pci.h> 14#include <linux/pci.h>
15#include <linux/of.h> 15#include <linux/of.h>
16#include <asm/prom.h> 16#include <asm/prom.h>
diff --git a/arch/powerpc/platforms/52xx/media5200.c b/arch/powerpc/platforms/52xx/media5200.c
index 68e4f1696d14..0bac3a3dbecf 100644
--- a/arch/powerpc/platforms/52xx/media5200.c
+++ b/arch/powerpc/platforms/52xx/media5200.c
@@ -74,7 +74,7 @@ static void media5200_irq_mask(unsigned int virq)
74} 74}
75 75
76static struct irq_chip media5200_irq_chip = { 76static struct irq_chip media5200_irq_chip = {
77 .typename = "Media5200 FPGA", 77 .name = "Media5200 FPGA",
78 .unmask = media5200_irq_unmask, 78 .unmask = media5200_irq_unmask,
79 .mask = media5200_irq_mask, 79 .mask = media5200_irq_mask,
80 .mask_ack = media5200_irq_mask, 80 .mask_ack = media5200_irq_mask,
@@ -86,9 +86,9 @@ void media5200_irq_cascade(unsigned int virq, struct irq_desc *desc)
86 u32 status, enable; 86 u32 status, enable;
87 87
88 /* Mask off the cascaded IRQ */ 88 /* Mask off the cascaded IRQ */
89 spin_lock(&desc->lock); 89 raw_spin_lock(&desc->lock);
90 desc->chip->mask(virq); 90 desc->chip->mask(virq);
91 spin_unlock(&desc->lock); 91 raw_spin_unlock(&desc->lock);
92 92
93 /* Ask the FPGA for IRQ status. If 'val' is 0, then no irqs 93 /* Ask the FPGA for IRQ status. If 'val' is 0, then no irqs
94 * are pending. 'ffs()' is 1 based */ 94 * are pending. 'ffs()' is 1 based */
@@ -104,17 +104,17 @@ void media5200_irq_cascade(unsigned int virq, struct irq_desc *desc)
104 } 104 }
105 105
106 /* Processing done; can reenable the cascade now */ 106 /* Processing done; can reenable the cascade now */
107 spin_lock(&desc->lock); 107 raw_spin_lock(&desc->lock);
108 desc->chip->ack(virq); 108 desc->chip->ack(virq);
109 if (!(desc->status & IRQ_DISABLED)) 109 if (!(desc->status & IRQ_DISABLED))
110 desc->chip->unmask(virq); 110 desc->chip->unmask(virq);
111 spin_unlock(&desc->lock); 111 raw_spin_unlock(&desc->lock);
112} 112}
113 113
114static int media5200_irq_map(struct irq_host *h, unsigned int virq, 114static int media5200_irq_map(struct irq_host *h, unsigned int virq,
115 irq_hw_number_t hw) 115 irq_hw_number_t hw)
116{ 116{
117 struct irq_desc *desc = get_irq_desc(virq); 117 struct irq_desc *desc = irq_to_desc(virq);
118 118
119 pr_debug("%s: h=%p, virq=%i, hwirq=%i\n", __func__, h, virq, (int)hw); 119 pr_debug("%s: h=%p, virq=%i, hwirq=%i\n", __func__, h, virq, (int)hw);
120 set_irq_chip_data(virq, &media5200_irq); 120 set_irq_chip_data(virq, &media5200_irq);
@@ -127,7 +127,7 @@ static int media5200_irq_map(struct irq_host *h, unsigned int virq,
127} 127}
128 128
129static int media5200_irq_xlate(struct irq_host *h, struct device_node *ct, 129static int media5200_irq_xlate(struct irq_host *h, struct device_node *ct,
130 u32 *intspec, unsigned int intsize, 130 const u32 *intspec, unsigned int intsize,
131 irq_hw_number_t *out_hwirq, 131 irq_hw_number_t *out_hwirq,
132 unsigned int *out_flags) 132 unsigned int *out_flags)
133{ 133{
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
index bfbcd418e690..6f8ebe1085b3 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
@@ -16,8 +16,14 @@
16 * output signals or measure input signals. 16 * output signals or measure input signals.
17 * 17 *
18 * This driver supports the GPIO and IRQ controller functions of the GPT 18 * This driver supports the GPIO and IRQ controller functions of the GPT
19 * device. Timer functions are not yet supported, nor is the watchdog 19 * device. Timer functions are not yet supported.
20 * timer. 20 *
21 * The timer gpt0 can be used as watchdog (wdt). If the wdt mode is used,
22 * this prevents the use of any gpt0 gpt function (i.e. they will fail with
23 * -EBUSY). Thus, the safety wdt function always has precedence over the gpt
24 * function. If the kernel has been compiled with CONFIG_WATCHDOG_NOWAYOUT,
25 * this means that gpt0 is locked in wdt mode until the next reboot - this
26 * may be a requirement in safety applications.
21 * 27 *
22 * To use the GPIO function, the following two properties must be added 28 * To use the GPIO function, the following two properties must be added
23 * to the device tree node for the gpt device (typically in the .dts file 29 * to the device tree node for the gpt device (typically in the .dts file
@@ -46,17 +52,24 @@
46 * the output mode. This driver does not change the output mode setting. 52 * the output mode. This driver does not change the output mode setting.
47 */ 53 */
48 54
55#include <linux/device.h>
49#include <linux/irq.h> 56#include <linux/irq.h>
50#include <linux/interrupt.h> 57#include <linux/interrupt.h>
51#include <linux/io.h> 58#include <linux/io.h>
59#include <linux/list.h>
60#include <linux/mutex.h>
52#include <linux/of.h> 61#include <linux/of.h>
53#include <linux/of_platform.h> 62#include <linux/of_platform.h>
54#include <linux/of_gpio.h> 63#include <linux/of_gpio.h>
55#include <linux/kernel.h> 64#include <linux/kernel.h>
65#include <linux/watchdog.h>
66#include <linux/miscdevice.h>
67#include <linux/uaccess.h>
68#include <asm/div64.h>
56#include <asm/mpc52xx.h> 69#include <asm/mpc52xx.h>
57 70
58MODULE_DESCRIPTION("Freescale MPC52xx gpt driver"); 71MODULE_DESCRIPTION("Freescale MPC52xx gpt driver");
59MODULE_AUTHOR("Sascha Hauer, Grant Likely"); 72MODULE_AUTHOR("Sascha Hauer, Grant Likely, Albrecht Dreß");
60MODULE_LICENSE("GPL"); 73MODULE_LICENSE("GPL");
61 74
62/** 75/**
@@ -66,18 +79,27 @@ MODULE_LICENSE("GPL");
66 * @lock: spinlock to coordinate between different functions. 79 * @lock: spinlock to coordinate between different functions.
67 * @of_gc: of_gpio_chip instance structure; used when GPIO is enabled 80 * @of_gc: of_gpio_chip instance structure; used when GPIO is enabled
68 * @irqhost: Pointer to irq_host instance; used when IRQ mode is supported 81 * @irqhost: Pointer to irq_host instance; used when IRQ mode is supported
82 * @wdt_mode: only relevant for gpt0: bit 0 (MPC52xx_GPT_CAN_WDT) indicates
83 * if the gpt may be used as wdt, bit 1 (MPC52xx_GPT_IS_WDT) indicates
84 * if the timer is actively used as wdt which blocks gpt functions
69 */ 85 */
70struct mpc52xx_gpt_priv { 86struct mpc52xx_gpt_priv {
87 struct list_head list; /* List of all GPT devices */
71 struct device *dev; 88 struct device *dev;
72 struct mpc52xx_gpt __iomem *regs; 89 struct mpc52xx_gpt __iomem *regs;
73 spinlock_t lock; 90 spinlock_t lock;
74 struct irq_host *irqhost; 91 struct irq_host *irqhost;
92 u32 ipb_freq;
93 u8 wdt_mode;
75 94
76#if defined(CONFIG_GPIOLIB) 95#if defined(CONFIG_GPIOLIB)
77 struct of_gpio_chip of_gc; 96 struct of_gpio_chip of_gc;
78#endif 97#endif
79}; 98};
80 99
100LIST_HEAD(mpc52xx_gpt_list);
101DEFINE_MUTEX(mpc52xx_gpt_list_mutex);
102
81#define MPC52xx_GPT_MODE_MS_MASK (0x07) 103#define MPC52xx_GPT_MODE_MS_MASK (0x07)
82#define MPC52xx_GPT_MODE_MS_IC (0x01) 104#define MPC52xx_GPT_MODE_MS_IC (0x01)
83#define MPC52xx_GPT_MODE_MS_OC (0x02) 105#define MPC52xx_GPT_MODE_MS_OC (0x02)
@@ -88,15 +110,25 @@ struct mpc52xx_gpt_priv {
88#define MPC52xx_GPT_MODE_GPIO_OUT_LOW (0x20) 110#define MPC52xx_GPT_MODE_GPIO_OUT_LOW (0x20)
89#define MPC52xx_GPT_MODE_GPIO_OUT_HIGH (0x30) 111#define MPC52xx_GPT_MODE_GPIO_OUT_HIGH (0x30)
90 112
113#define MPC52xx_GPT_MODE_COUNTER_ENABLE (0x1000)
114#define MPC52xx_GPT_MODE_CONTINUOUS (0x0400)
115#define MPC52xx_GPT_MODE_OPEN_DRAIN (0x0200)
91#define MPC52xx_GPT_MODE_IRQ_EN (0x0100) 116#define MPC52xx_GPT_MODE_IRQ_EN (0x0100)
117#define MPC52xx_GPT_MODE_WDT_EN (0x8000)
92 118
93#define MPC52xx_GPT_MODE_ICT_MASK (0x030000) 119#define MPC52xx_GPT_MODE_ICT_MASK (0x030000)
94#define MPC52xx_GPT_MODE_ICT_RISING (0x010000) 120#define MPC52xx_GPT_MODE_ICT_RISING (0x010000)
95#define MPC52xx_GPT_MODE_ICT_FALLING (0x020000) 121#define MPC52xx_GPT_MODE_ICT_FALLING (0x020000)
96#define MPC52xx_GPT_MODE_ICT_TOGGLE (0x030000) 122#define MPC52xx_GPT_MODE_ICT_TOGGLE (0x030000)
97 123
124#define MPC52xx_GPT_MODE_WDT_PING (0xa5)
125
98#define MPC52xx_GPT_STATUS_IRQMASK (0x000f) 126#define MPC52xx_GPT_STATUS_IRQMASK (0x000f)
99 127
128#define MPC52xx_GPT_CAN_WDT (1 << 0)
129#define MPC52xx_GPT_IS_WDT (1 << 1)
130
131
100/* --------------------------------------------------------------------- 132/* ---------------------------------------------------------------------
101 * Cascaded interrupt controller hooks 133 * Cascaded interrupt controller hooks
102 */ 134 */
@@ -149,7 +181,7 @@ static int mpc52xx_gpt_irq_set_type(unsigned int virq, unsigned int flow_type)
149} 181}
150 182
151static struct irq_chip mpc52xx_gpt_irq_chip = { 183static struct irq_chip mpc52xx_gpt_irq_chip = {
152 .typename = "MPC52xx GPT", 184 .name = "MPC52xx GPT",
153 .unmask = mpc52xx_gpt_irq_unmask, 185 .unmask = mpc52xx_gpt_irq_unmask,
154 .mask = mpc52xx_gpt_irq_mask, 186 .mask = mpc52xx_gpt_irq_mask,
155 .ack = mpc52xx_gpt_irq_ack, 187 .ack = mpc52xx_gpt_irq_ack,
@@ -182,7 +214,7 @@ static int mpc52xx_gpt_irq_map(struct irq_host *h, unsigned int virq,
182} 214}
183 215
184static int mpc52xx_gpt_irq_xlate(struct irq_host *h, struct device_node *ct, 216static int mpc52xx_gpt_irq_xlate(struct irq_host *h, struct device_node *ct,
185 u32 *intspec, unsigned int intsize, 217 const u32 *intspec, unsigned int intsize,
186 irq_hw_number_t *out_hwirq, 218 irq_hw_number_t *out_hwirq,
187 unsigned int *out_flags) 219 unsigned int *out_flags)
188{ 220{
@@ -190,7 +222,7 @@ static int mpc52xx_gpt_irq_xlate(struct irq_host *h, struct device_node *ct,
190 222
191 dev_dbg(gpt->dev, "%s: flags=%i\n", __func__, intspec[0]); 223 dev_dbg(gpt->dev, "%s: flags=%i\n", __func__, intspec[0]);
192 224
193 if ((intsize < 1) || (intspec[0] < 1) || (intspec[0] > 3)) { 225 if ((intsize < 1) || (intspec[0] > 3)) {
194 dev_err(gpt->dev, "bad irq specifier in %s\n", ct->full_name); 226 dev_err(gpt->dev, "bad irq specifier in %s\n", ct->full_name);
195 return -EINVAL; 227 return -EINVAL;
196 } 228 }
@@ -211,13 +243,11 @@ mpc52xx_gpt_irq_setup(struct mpc52xx_gpt_priv *gpt, struct device_node *node)
211{ 243{
212 int cascade_virq; 244 int cascade_virq;
213 unsigned long flags; 245 unsigned long flags;
214 246 u32 mode;
215 /* Only setup cascaded IRQ if device tree claims the GPT is
216 * an interrupt controller */
217 if (!of_find_property(node, "interrupt-controller", NULL))
218 return;
219 247
220 cascade_virq = irq_of_parse_and_map(node, 0); 248 cascade_virq = irq_of_parse_and_map(node, 0);
249 if (!cascade_virq)
250 return;
221 251
222 gpt->irqhost = irq_alloc_host(node, IRQ_HOST_MAP_LINEAR, 1, 252 gpt->irqhost = irq_alloc_host(node, IRQ_HOST_MAP_LINEAR, 1,
223 &mpc52xx_gpt_irq_ops, -1); 253 &mpc52xx_gpt_irq_ops, -1);
@@ -227,14 +257,16 @@ mpc52xx_gpt_irq_setup(struct mpc52xx_gpt_priv *gpt, struct device_node *node)
227 } 257 }
228 258
229 gpt->irqhost->host_data = gpt; 259 gpt->irqhost->host_data = gpt;
230
231 set_irq_data(cascade_virq, gpt); 260 set_irq_data(cascade_virq, gpt);
232 set_irq_chained_handler(cascade_virq, mpc52xx_gpt_irq_cascade); 261 set_irq_chained_handler(cascade_virq, mpc52xx_gpt_irq_cascade);
233 262
234 /* Set to Input Capture mode */ 263 /* If the GPT is currently disabled, then change it to be in Input
264 * Capture mode. If the mode is non-zero, then the pin could be
265 * already in use for something. */
235 spin_lock_irqsave(&gpt->lock, flags); 266 spin_lock_irqsave(&gpt->lock, flags);
236 clrsetbits_be32(&gpt->regs->mode, MPC52xx_GPT_MODE_MS_MASK, 267 mode = in_be32(&gpt->regs->mode);
237 MPC52xx_GPT_MODE_MS_IC); 268 if ((mode & MPC52xx_GPT_MODE_MS_MASK) == 0)
269 out_be32(&gpt->regs->mode, mode | MPC52xx_GPT_MODE_MS_IC);
238 spin_unlock_irqrestore(&gpt->lock, flags); 270 spin_unlock_irqrestore(&gpt->lock, flags);
239 271
240 dev_dbg(gpt->dev, "%s() complete. virq=%i\n", __func__, cascade_virq); 272 dev_dbg(gpt->dev, "%s() complete. virq=%i\n", __func__, cascade_virq);
@@ -335,6 +367,354 @@ static void
335mpc52xx_gpt_gpio_setup(struct mpc52xx_gpt_priv *p, struct device_node *np) { } 367mpc52xx_gpt_gpio_setup(struct mpc52xx_gpt_priv *p, struct device_node *np) { }
336#endif /* defined(CONFIG_GPIOLIB) */ 368#endif /* defined(CONFIG_GPIOLIB) */
337 369
370/***********************************************************************
371 * Timer API
372 */
373
374/**
375 * mpc52xx_gpt_from_irq - Return the GPT device associated with an IRQ number
376 * @irq: irq of timer.
377 */
378struct mpc52xx_gpt_priv *mpc52xx_gpt_from_irq(int irq)
379{
380 struct mpc52xx_gpt_priv *gpt;
381 struct list_head *pos;
382
383 /* Iterate over the list of timers looking for a matching device */
384 mutex_lock(&mpc52xx_gpt_list_mutex);
385 list_for_each(pos, &mpc52xx_gpt_list) {
386 gpt = container_of(pos, struct mpc52xx_gpt_priv, list);
387 if (gpt->irqhost && irq == irq_linear_revmap(gpt->irqhost, 0)) {
388 mutex_unlock(&mpc52xx_gpt_list_mutex);
389 return gpt;
390 }
391 }
392 mutex_unlock(&mpc52xx_gpt_list_mutex);
393
394 return NULL;
395}
396EXPORT_SYMBOL(mpc52xx_gpt_from_irq);
397
398static int mpc52xx_gpt_do_start(struct mpc52xx_gpt_priv *gpt, u64 period,
399 int continuous, int as_wdt)
400{
401 u32 clear, set;
402 u64 clocks;
403 u32 prescale;
404 unsigned long flags;
405
406 clear = MPC52xx_GPT_MODE_MS_MASK | MPC52xx_GPT_MODE_CONTINUOUS;
407 set = MPC52xx_GPT_MODE_MS_GPIO | MPC52xx_GPT_MODE_COUNTER_ENABLE;
408 if (as_wdt) {
409 clear |= MPC52xx_GPT_MODE_IRQ_EN;
410 set |= MPC52xx_GPT_MODE_WDT_EN;
411 } else if (continuous)
412 set |= MPC52xx_GPT_MODE_CONTINUOUS;
413
414 /* Determine the number of clocks in the requested period. 64 bit
415 * arithmatic is done here to preserve the precision until the value
416 * is scaled back down into the u32 range. Period is in 'ns', bus
417 * frequency is in Hz. */
418 clocks = period * (u64)gpt->ipb_freq;
419 do_div(clocks, 1000000000); /* Scale it down to ns range */
420
421 /* This device cannot handle a clock count greater than 32 bits */
422 if (clocks > 0xffffffff)
423 return -EINVAL;
424
425 /* Calculate the prescaler and count values from the clocks value.
426 * 'clocks' is the number of clock ticks in the period. The timer
427 * has 16 bit precision and a 16 bit prescaler. Prescaler is
428 * calculated by integer dividing the clocks by 0x10000 (shifting
429 * down 16 bits) to obtain the smallest possible divisor for clocks
430 * to get a 16 bit count value.
431 *
432 * Note: the prescale register is '1' based, not '0' based. ie. a
433 * value of '1' means divide the clock by one. 0xffff divides the
434 * clock by 0xffff. '0x0000' does not divide by zero, but wraps
435 * around and divides by 0x10000. That is why prescale must be
436 * a u32 variable, not a u16, for this calculation. */
437 prescale = (clocks >> 16) + 1;
438 do_div(clocks, prescale);
439 if (clocks > 0xffff) {
440 pr_err("calculation error; prescale:%x clocks:%llx\n",
441 prescale, clocks);
442 return -EINVAL;
443 }
444
445 /* Set and enable the timer, reject an attempt to use a wdt as gpt */
446 spin_lock_irqsave(&gpt->lock, flags);
447 if (as_wdt)
448 gpt->wdt_mode |= MPC52xx_GPT_IS_WDT;
449 else if ((gpt->wdt_mode & MPC52xx_GPT_IS_WDT) != 0) {
450 spin_unlock_irqrestore(&gpt->lock, flags);
451 return -EBUSY;
452 }
453 out_be32(&gpt->regs->count, prescale << 16 | clocks);
454 clrsetbits_be32(&gpt->regs->mode, clear, set);
455 spin_unlock_irqrestore(&gpt->lock, flags);
456
457 return 0;
458}
459
460/**
461 * mpc52xx_gpt_start_timer - Set and enable the GPT timer
462 * @gpt: Pointer to gpt private data structure
463 * @period: period of timer in ns; max. ~130s @ 33MHz IPB clock
464 * @continuous: set to 1 to make timer continuous free running
465 *
466 * An interrupt will be generated every time the timer fires
467 */
468int mpc52xx_gpt_start_timer(struct mpc52xx_gpt_priv *gpt, u64 period,
469 int continuous)
470{
471 return mpc52xx_gpt_do_start(gpt, period, continuous, 0);
472}
473EXPORT_SYMBOL(mpc52xx_gpt_start_timer);
474
475/**
476 * mpc52xx_gpt_stop_timer - Stop a gpt
477 * @gpt: Pointer to gpt private data structure
478 *
479 * Returns an error if attempting to stop a wdt
480 */
481int mpc52xx_gpt_stop_timer(struct mpc52xx_gpt_priv *gpt)
482{
483 unsigned long flags;
484
485 /* reject the operation if the timer is used as watchdog (gpt 0 only) */
486 spin_lock_irqsave(&gpt->lock, flags);
487 if ((gpt->wdt_mode & MPC52xx_GPT_IS_WDT) != 0) {
488 spin_unlock_irqrestore(&gpt->lock, flags);
489 return -EBUSY;
490 }
491
492 clrbits32(&gpt->regs->mode, MPC52xx_GPT_MODE_COUNTER_ENABLE);
493 spin_unlock_irqrestore(&gpt->lock, flags);
494 return 0;
495}
496EXPORT_SYMBOL(mpc52xx_gpt_stop_timer);
497
498/**
499 * mpc52xx_gpt_timer_period - Read the timer period
500 * @gpt: Pointer to gpt private data structure
501 *
502 * Returns the timer period in ns
503 */
504u64 mpc52xx_gpt_timer_period(struct mpc52xx_gpt_priv *gpt)
505{
506 u64 period;
507 u64 prescale;
508 unsigned long flags;
509
510 spin_lock_irqsave(&gpt->lock, flags);
511 period = in_be32(&gpt->regs->count);
512 spin_unlock_irqrestore(&gpt->lock, flags);
513
514 prescale = period >> 16;
515 period &= 0xffff;
516 if (prescale == 0)
517 prescale = 0x10000;
518 period = period * prescale * 1000000000ULL;
519 do_div(period, (u64)gpt->ipb_freq);
520 return period;
521}
522EXPORT_SYMBOL(mpc52xx_gpt_timer_period);
523
524#if defined(CONFIG_MPC5200_WDT)
525/***********************************************************************
526 * Watchdog API for gpt0
527 */
528
529#define WDT_IDENTITY "mpc52xx watchdog on GPT0"
530
531/* wdt_is_active stores wether or not the /dev/watchdog device is opened */
532static unsigned long wdt_is_active;
533
534/* wdt-capable gpt */
535static struct mpc52xx_gpt_priv *mpc52xx_gpt_wdt;
536
537/* low-level wdt functions */
538static inline void mpc52xx_gpt_wdt_ping(struct mpc52xx_gpt_priv *gpt_wdt)
539{
540 unsigned long flags;
541
542 spin_lock_irqsave(&gpt_wdt->lock, flags);
543 out_8((u8 *) &gpt_wdt->regs->mode, MPC52xx_GPT_MODE_WDT_PING);
544 spin_unlock_irqrestore(&gpt_wdt->lock, flags);
545}
546
547/* wdt misc device api */
548static ssize_t mpc52xx_wdt_write(struct file *file, const char __user *data,
549 size_t len, loff_t *ppos)
550{
551 struct mpc52xx_gpt_priv *gpt_wdt = file->private_data;
552 mpc52xx_gpt_wdt_ping(gpt_wdt);
553 return 0;
554}
555
556static struct watchdog_info mpc5200_wdt_info = {
557 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
558 .identity = WDT_IDENTITY,
559};
560
561static long mpc52xx_wdt_ioctl(struct file *file, unsigned int cmd,
562 unsigned long arg)
563{
564 struct mpc52xx_gpt_priv *gpt_wdt = file->private_data;
565 int __user *data = (int __user *)arg;
566 int timeout;
567 u64 real_timeout;
568 int ret = 0;
569
570 switch (cmd) {
571 case WDIOC_GETSUPPORT:
572 ret = copy_to_user(data, &mpc5200_wdt_info,
573 sizeof(mpc5200_wdt_info));
574 if (ret)
575 ret = -EFAULT;
576 break;
577
578 case WDIOC_GETSTATUS:
579 case WDIOC_GETBOOTSTATUS:
580 ret = put_user(0, data);
581 break;
582
583 case WDIOC_KEEPALIVE:
584 mpc52xx_gpt_wdt_ping(gpt_wdt);
585 break;
586
587 case WDIOC_SETTIMEOUT:
588 ret = get_user(timeout, data);
589 if (ret)
590 break;
591 real_timeout = (u64) timeout * 1000000000ULL;
592 ret = mpc52xx_gpt_do_start(gpt_wdt, real_timeout, 0, 1);
593 if (ret)
594 break;
595 /* fall through and return the timeout */
596
597 case WDIOC_GETTIMEOUT:
598 /* we need to round here as to avoid e.g. the following
599 * situation:
600 * - timeout requested is 1 second;
601 * - real timeout @33MHz is 999997090ns
602 * - the int divide by 10^9 will return 0.
603 */
604 real_timeout =
605 mpc52xx_gpt_timer_period(gpt_wdt) + 500000000ULL;
606 do_div(real_timeout, 1000000000ULL);
607 timeout = (int) real_timeout;
608 ret = put_user(timeout, data);
609 break;
610
611 default:
612 ret = -ENOTTY;
613 }
614 return ret;
615}
616
617static int mpc52xx_wdt_open(struct inode *inode, struct file *file)
618{
619 int ret;
620
621 /* sanity check */
622 if (!mpc52xx_gpt_wdt)
623 return -ENODEV;
624
625 /* /dev/watchdog can only be opened once */
626 if (test_and_set_bit(0, &wdt_is_active))
627 return -EBUSY;
628
629 /* Set and activate the watchdog with 30 seconds timeout */
630 ret = mpc52xx_gpt_do_start(mpc52xx_gpt_wdt, 30ULL * 1000000000ULL,
631 0, 1);
632 if (ret) {
633 clear_bit(0, &wdt_is_active);
634 return ret;
635 }
636
637 file->private_data = mpc52xx_gpt_wdt;
638 return nonseekable_open(inode, file);
639}
640
641static int mpc52xx_wdt_release(struct inode *inode, struct file *file)
642{
643 /* note: releasing the wdt in NOWAYOUT-mode does not stop it */
644#if !defined(CONFIG_WATCHDOG_NOWAYOUT)
645 struct mpc52xx_gpt_priv *gpt_wdt = file->private_data;
646 unsigned long flags;
647
648 spin_lock_irqsave(&gpt_wdt->lock, flags);
649 clrbits32(&gpt_wdt->regs->mode,
650 MPC52xx_GPT_MODE_COUNTER_ENABLE | MPC52xx_GPT_MODE_WDT_EN);
651 gpt_wdt->wdt_mode &= ~MPC52xx_GPT_IS_WDT;
652 spin_unlock_irqrestore(&gpt_wdt->lock, flags);
653#endif
654 clear_bit(0, &wdt_is_active);
655 return 0;
656}
657
658
659static const struct file_operations mpc52xx_wdt_fops = {
660 .owner = THIS_MODULE,
661 .llseek = no_llseek,
662 .write = mpc52xx_wdt_write,
663 .unlocked_ioctl = mpc52xx_wdt_ioctl,
664 .open = mpc52xx_wdt_open,
665 .release = mpc52xx_wdt_release,
666};
667
668static struct miscdevice mpc52xx_wdt_miscdev = {
669 .minor = WATCHDOG_MINOR,
670 .name = "watchdog",
671 .fops = &mpc52xx_wdt_fops,
672};
673
674static int __devinit mpc52xx_gpt_wdt_init(void)
675{
676 int err;
677
678 /* try to register the watchdog misc device */
679 err = misc_register(&mpc52xx_wdt_miscdev);
680 if (err)
681 pr_err("%s: cannot register watchdog device\n", WDT_IDENTITY);
682 else
683 pr_info("%s: watchdog device registered\n", WDT_IDENTITY);
684 return err;
685}
686
687static int mpc52xx_gpt_wdt_setup(struct mpc52xx_gpt_priv *gpt,
688 const u32 *period)
689{
690 u64 real_timeout;
691
692 /* remember the gpt for the wdt operation */
693 mpc52xx_gpt_wdt = gpt;
694
695 /* configure the wdt if the device tree contained a timeout */
696 if (!period || *period == 0)
697 return 0;
698
699 real_timeout = (u64) *period * 1000000000ULL;
700 if (mpc52xx_gpt_do_start(gpt, real_timeout, 0, 1))
701 dev_warn(gpt->dev, "starting as wdt failed\n");
702 else
703 dev_info(gpt->dev, "watchdog set to %us timeout\n", *period);
704 return 0;
705}
706
707#else
708
709static int __devinit mpc52xx_gpt_wdt_init(void)
710{
711 return 0;
712}
713
714#define mpc52xx_gpt_wdt_setup(x, y) (0)
715
716#endif /* CONFIG_MPC5200_WDT */
717
338/* --------------------------------------------------------------------- 718/* ---------------------------------------------------------------------
339 * of_platform bus binding code 719 * of_platform bus binding code
340 */ 720 */
@@ -349,6 +729,7 @@ static int __devinit mpc52xx_gpt_probe(struct of_device *ofdev,
349 729
350 spin_lock_init(&gpt->lock); 730 spin_lock_init(&gpt->lock);
351 gpt->dev = &ofdev->dev; 731 gpt->dev = &ofdev->dev;
732 gpt->ipb_freq = mpc5xxx_get_bus_frequency(ofdev->node);
352 gpt->regs = of_iomap(ofdev->node, 0); 733 gpt->regs = of_iomap(ofdev->node, 0);
353 if (!gpt->regs) { 734 if (!gpt->regs) {
354 kfree(gpt); 735 kfree(gpt);
@@ -360,6 +741,26 @@ static int __devinit mpc52xx_gpt_probe(struct of_device *ofdev,
360 mpc52xx_gpt_gpio_setup(gpt, ofdev->node); 741 mpc52xx_gpt_gpio_setup(gpt, ofdev->node);
361 mpc52xx_gpt_irq_setup(gpt, ofdev->node); 742 mpc52xx_gpt_irq_setup(gpt, ofdev->node);
362 743
744 mutex_lock(&mpc52xx_gpt_list_mutex);
745 list_add(&gpt->list, &mpc52xx_gpt_list);
746 mutex_unlock(&mpc52xx_gpt_list_mutex);
747
748 /* check if this device could be a watchdog */
749 if (of_get_property(ofdev->node, "fsl,has-wdt", NULL) ||
750 of_get_property(ofdev->node, "has-wdt", NULL)) {
751 const u32 *on_boot_wdt;
752
753 gpt->wdt_mode = MPC52xx_GPT_CAN_WDT;
754 on_boot_wdt = of_get_property(ofdev->node, "fsl,wdt-on-boot",
755 NULL);
756 if (on_boot_wdt) {
757 dev_info(gpt->dev, "used as watchdog\n");
758 gpt->wdt_mode |= MPC52xx_GPT_IS_WDT;
759 } else
760 dev_info(gpt->dev, "can function as watchdog\n");
761 mpc52xx_gpt_wdt_setup(gpt, on_boot_wdt);
762 }
763
363 return 0; 764 return 0;
364} 765}
365 766
@@ -394,3 +795,4 @@ static int __init mpc52xx_gpt_init(void)
394 795
395/* Make sure GPIOs and IRQs get set up before anyone tries to use them */ 796/* Make sure GPIOs and IRQs get set up before anyone tries to use them */
396subsys_initcall(mpc52xx_gpt_init); 797subsys_initcall(mpc52xx_gpt_init);
798device_initcall(mpc52xx_gpt_wdt_init);
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c b/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c
new file mode 100644
index 000000000000..929d017535a3
--- /dev/null
+++ b/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c
@@ -0,0 +1,560 @@
1/*
2 * LocalPlus Bus FIFO driver for the Freescale MPC52xx.
3 *
4 * Copyright (C) 2009 Secret Lab Technologies Ltd.
5 *
6 * This file is released under the GPLv2
7 *
8 * Todo:
9 * - Add support for multiple requests to be queued.
10 */
11
12#include <linux/interrupt.h>
13#include <linux/kernel.h>
14#include <linux/of.h>
15#include <linux/of_platform.h>
16#include <linux/spinlock.h>
17#include <asm/io.h>
18#include <asm/prom.h>
19#include <asm/mpc52xx.h>
20#include <asm/time.h>
21
22#include <sysdev/bestcomm/bestcomm.h>
23#include <sysdev/bestcomm/bestcomm_priv.h>
24#include <sysdev/bestcomm/gen_bd.h>
25
26MODULE_AUTHOR("Grant Likely <grant.likely@secretlab.ca>");
27MODULE_DESCRIPTION("MPC5200 LocalPlus FIFO device driver");
28MODULE_LICENSE("GPL");
29
30#define LPBFIFO_REG_PACKET_SIZE (0x00)
31#define LPBFIFO_REG_START_ADDRESS (0x04)
32#define LPBFIFO_REG_CONTROL (0x08)
33#define LPBFIFO_REG_ENABLE (0x0C)
34#define LPBFIFO_REG_BYTES_DONE_STATUS (0x14)
35#define LPBFIFO_REG_FIFO_DATA (0x40)
36#define LPBFIFO_REG_FIFO_STATUS (0x44)
37#define LPBFIFO_REG_FIFO_CONTROL (0x48)
38#define LPBFIFO_REG_FIFO_ALARM (0x4C)
39
40struct mpc52xx_lpbfifo {
41 struct device *dev;
42 phys_addr_t regs_phys;
43 void __iomem *regs;
44 int irq;
45 spinlock_t lock;
46
47 struct bcom_task *bcom_tx_task;
48 struct bcom_task *bcom_rx_task;
49 struct bcom_task *bcom_cur_task;
50
51 /* Current state data */
52 struct mpc52xx_lpbfifo_request *req;
53 int dma_irqs_enabled;
54};
55
56/* The MPC5200 has only one fifo, so only need one instance structure */
57static struct mpc52xx_lpbfifo lpbfifo;
58
59/**
60 * mpc52xx_lpbfifo_kick - Trigger the next block of data to be transfered
61 */
62static void mpc52xx_lpbfifo_kick(struct mpc52xx_lpbfifo_request *req)
63{
64 size_t transfer_size = req->size - req->pos;
65 struct bcom_bd *bd;
66 void __iomem *reg;
67 u32 *data;
68 int i;
69 int bit_fields;
70 int dma = !(req->flags & MPC52XX_LPBFIFO_FLAG_NO_DMA);
71 int write = req->flags & MPC52XX_LPBFIFO_FLAG_WRITE;
72 int poll_dma = req->flags & MPC52XX_LPBFIFO_FLAG_POLL_DMA;
73
74 /* Set and clear the reset bits; is good practice in User Manual */
75 out_be32(lpbfifo.regs + LPBFIFO_REG_ENABLE, 0x01010000);
76
77 /* set master enable bit */
78 out_be32(lpbfifo.regs + LPBFIFO_REG_ENABLE, 0x00000001);
79 if (!dma) {
80 /* While the FIFO can be setup for transfer sizes as large as
81 * 16M-1, the FIFO itself is only 512 bytes deep and it does
82 * not generate interrupts for FIFO full events (only transfer
83 * complete will raise an IRQ). Therefore when not using
84 * Bestcomm to drive the FIFO it needs to either be polled, or
85 * transfers need to constrained to the size of the fifo.
86 *
87 * This driver restricts the size of the transfer
88 */
89 if (transfer_size > 512)
90 transfer_size = 512;
91
92 /* Load the FIFO with data */
93 if (write) {
94 reg = lpbfifo.regs + LPBFIFO_REG_FIFO_DATA;
95 data = req->data + req->pos;
96 for (i = 0; i < transfer_size; i += 4)
97 out_be32(reg, *data++);
98 }
99
100 /* Unmask both error and completion irqs */
101 out_be32(lpbfifo.regs + LPBFIFO_REG_ENABLE, 0x00000301);
102 } else {
103 /* Choose the correct direction
104 *
105 * Configure the watermarks so DMA will always complete correctly.
106 * It may be worth experimenting with the ALARM value to see if
107 * there is a performance impacit. However, if it is wrong there
108 * is a risk of DMA not transferring the last chunk of data
109 */
110 if (write) {
111 out_be32(lpbfifo.regs + LPBFIFO_REG_FIFO_ALARM, 0x1e4);
112 out_8(lpbfifo.regs + LPBFIFO_REG_FIFO_CONTROL, 7);
113 lpbfifo.bcom_cur_task = lpbfifo.bcom_tx_task;
114 } else {
115 out_be32(lpbfifo.regs + LPBFIFO_REG_FIFO_ALARM, 0x1ff);
116 out_8(lpbfifo.regs + LPBFIFO_REG_FIFO_CONTROL, 0);
117 lpbfifo.bcom_cur_task = lpbfifo.bcom_rx_task;
118
119 if (poll_dma) {
120 if (lpbfifo.dma_irqs_enabled) {
121 disable_irq(bcom_get_task_irq(lpbfifo.bcom_rx_task));
122 lpbfifo.dma_irqs_enabled = 0;
123 }
124 } else {
125 if (!lpbfifo.dma_irqs_enabled) {
126 enable_irq(bcom_get_task_irq(lpbfifo.bcom_rx_task));
127 lpbfifo.dma_irqs_enabled = 1;
128 }
129 }
130 }
131
132 bd = bcom_prepare_next_buffer(lpbfifo.bcom_cur_task);
133 bd->status = transfer_size;
134 if (!write) {
135 /*
136 * In the DMA read case, the DMA doesn't complete,
137 * possibly due to incorrect watermarks in the ALARM
138 * and CONTROL regs. For now instead of trying to
139 * determine the right watermarks that will make this
140 * work, just increase the number of bytes the FIFO is
141 * expecting.
142 *
143 * When submitting another operation, the FIFO will get
144 * reset, so the condition of the FIFO waiting for a
145 * non-existent 4 bytes will get cleared.
146 */
147 transfer_size += 4; /* BLECH! */
148 }
149 bd->data[0] = req->data_phys + req->pos;
150 bcom_submit_next_buffer(lpbfifo.bcom_cur_task, NULL);
151
152 /* error irq & master enabled bit */
153 bit_fields = 0x00000201;
154
155 /* Unmask irqs */
156 if (write && (!poll_dma))
157 bit_fields |= 0x00000100; /* completion irq too */
158 out_be32(lpbfifo.regs + LPBFIFO_REG_ENABLE, bit_fields);
159 }
160
161 /* Set transfer size, width, chip select and READ mode */
162 out_be32(lpbfifo.regs + LPBFIFO_REG_START_ADDRESS,
163 req->offset + req->pos);
164 out_be32(lpbfifo.regs + LPBFIFO_REG_PACKET_SIZE, transfer_size);
165
166 bit_fields = req->cs << 24 | 0x000008;
167 if (!write)
168 bit_fields |= 0x010000; /* read mode */
169 out_be32(lpbfifo.regs + LPBFIFO_REG_CONTROL, bit_fields);
170
171 /* Kick it off */
172 out_8(lpbfifo.regs + LPBFIFO_REG_PACKET_SIZE, 0x01);
173 if (dma)
174 bcom_enable(lpbfifo.bcom_cur_task);
175}
176
177/**
178 * mpc52xx_lpbfifo_irq - IRQ handler for LPB FIFO
179 *
180 * On transmit, the dma completion irq triggers before the fifo completion
181 * triggers. Handle the dma completion here instead of the LPB FIFO Bestcomm
182 * task completion irq becuase everyting is not really done until the LPB FIFO
183 * completion irq triggers.
184 *
185 * In other words:
186 * For DMA, on receive, the "Fat Lady" is the bestcom completion irq. on
187 * transmit, the fifo completion irq is the "Fat Lady". The opera (or in this
188 * case the DMA/FIFO operation) is not finished until the "Fat Lady" sings.
189 *
190 * Reasons for entering this routine:
191 * 1) PIO mode rx and tx completion irq
192 * 2) DMA interrupt mode tx completion irq
193 * 3) DMA polled mode tx
194 *
195 * Exit conditions:
196 * 1) Transfer aborted
197 * 2) FIFO complete without DMA; more data to do
198 * 3) FIFO complete without DMA; all data transfered
199 * 4) FIFO complete using DMA
200 *
201 * Condition 1 can occur regardless of whether or not DMA is used.
202 * It requires executing the callback to report the error and exiting
203 * immediately.
204 *
205 * Condition 2 requires programming the FIFO with the next block of data
206 *
207 * Condition 3 requires executing the callback to report completion
208 *
209 * Condition 4 means the same as 3, except that we also retrieve the bcom
210 * buffer so DMA doesn't get clogged up.
211 *
212 * To make things trickier, the spinlock must be dropped before
213 * executing the callback, otherwise we could end up with a deadlock
214 * or nested spinlock condition. The out path is non-trivial, so
215 * extra fiddling is done to make sure all paths lead to the same
216 * outbound code.
217 */
218static irqreturn_t mpc52xx_lpbfifo_irq(int irq, void *dev_id)
219{
220 struct mpc52xx_lpbfifo_request *req;
221 u32 status = in_8(lpbfifo.regs + LPBFIFO_REG_BYTES_DONE_STATUS);
222 void __iomem *reg;
223 u32 *data;
224 int count, i;
225 int do_callback = 0;
226 u32 ts;
227 unsigned long flags;
228 int dma, write, poll_dma;
229
230 spin_lock_irqsave(&lpbfifo.lock, flags);
231 ts = get_tbl();
232
233 req = lpbfifo.req;
234 if (!req) {
235 spin_unlock_irqrestore(&lpbfifo.lock, flags);
236 pr_err("bogus LPBFIFO IRQ\n");
237 return IRQ_HANDLED;
238 }
239
240 dma = !(req->flags & MPC52XX_LPBFIFO_FLAG_NO_DMA);
241 write = req->flags & MPC52XX_LPBFIFO_FLAG_WRITE;
242 poll_dma = req->flags & MPC52XX_LPBFIFO_FLAG_POLL_DMA;
243
244 if (dma && !write) {
245 spin_unlock_irqrestore(&lpbfifo.lock, flags);
246 pr_err("bogus LPBFIFO IRQ (dma and not writting)\n");
247 return IRQ_HANDLED;
248 }
249
250 if ((status & 0x01) == 0) {
251 goto out;
252 }
253
254 /* check abort bit */
255 if (status & 0x10) {
256 out_be32(lpbfifo.regs + LPBFIFO_REG_ENABLE, 0x01010000);
257 do_callback = 1;
258 goto out;
259 }
260
261 /* Read result from hardware */
262 count = in_be32(lpbfifo.regs + LPBFIFO_REG_BYTES_DONE_STATUS);
263 count &= 0x00ffffff;
264
265 if (!dma && !write) {
266 /* copy the data out of the FIFO */
267 reg = lpbfifo.regs + LPBFIFO_REG_FIFO_DATA;
268 data = req->data + req->pos;
269 for (i = 0; i < count; i += 4)
270 *data++ = in_be32(reg);
271 }
272
273 /* Update transfer position and count */
274 req->pos += count;
275
276 /* Decide what to do next */
277 if (req->size - req->pos)
278 mpc52xx_lpbfifo_kick(req); /* more work to do */
279 else
280 do_callback = 1;
281
282 out:
283 /* Clear the IRQ */
284 out_8(lpbfifo.regs + LPBFIFO_REG_BYTES_DONE_STATUS, 0x01);
285
286 if (dma && (status & 0x11)) {
287 /*
288 * Count the DMA as complete only when the FIFO completion
289 * status or abort bits are set.
290 *
291 * (status & 0x01) should always be the case except sometimes
292 * when using polled DMA.
293 *
294 * (status & 0x10) {transfer aborted}: This case needs more
295 * testing.
296 */
297 bcom_retrieve_buffer(lpbfifo.bcom_cur_task, &status, NULL);
298 }
299 req->last_byte = ((u8 *)req->data)[req->size - 1];
300
301 /* When the do_callback flag is set; it means the transfer is finished
302 * so set the FIFO as idle */
303 if (do_callback)
304 lpbfifo.req = NULL;
305
306 if (irq != 0) /* don't increment on polled case */
307 req->irq_count++;
308
309 req->irq_ticks += get_tbl() - ts;
310 spin_unlock_irqrestore(&lpbfifo.lock, flags);
311
312 /* Spinlock is released; it is now safe to call the callback */
313 if (do_callback && req->callback)
314 req->callback(req);
315
316 return IRQ_HANDLED;
317}
318
319/**
320 * mpc52xx_lpbfifo_bcom_irq - IRQ handler for LPB FIFO Bestcomm task
321 *
322 * Only used when receiving data.
323 */
324static irqreturn_t mpc52xx_lpbfifo_bcom_irq(int irq, void *dev_id)
325{
326 struct mpc52xx_lpbfifo_request *req;
327 unsigned long flags;
328 u32 status;
329 u32 ts;
330
331 spin_lock_irqsave(&lpbfifo.lock, flags);
332 ts = get_tbl();
333
334 req = lpbfifo.req;
335 if (!req || (req->flags & MPC52XX_LPBFIFO_FLAG_NO_DMA)) {
336 spin_unlock_irqrestore(&lpbfifo.lock, flags);
337 return IRQ_HANDLED;
338 }
339
340 if (irq != 0) /* don't increment on polled case */
341 req->irq_count++;
342
343 if (!bcom_buffer_done(lpbfifo.bcom_cur_task)) {
344 spin_unlock_irqrestore(&lpbfifo.lock, flags);
345
346 req->buffer_not_done_cnt++;
347 if ((req->buffer_not_done_cnt % 1000) == 0)
348 pr_err("transfer stalled\n");
349
350 return IRQ_HANDLED;
351 }
352
353 bcom_retrieve_buffer(lpbfifo.bcom_cur_task, &status, NULL);
354
355 req->last_byte = ((u8 *)req->data)[req->size - 1];
356
357 req->pos = status & 0x00ffffff;
358
359 /* Mark the FIFO as idle */
360 lpbfifo.req = NULL;
361
362 /* Release the lock before calling out to the callback. */
363 req->irq_ticks += get_tbl() - ts;
364 spin_unlock_irqrestore(&lpbfifo.lock, flags);
365
366 if (req->callback)
367 req->callback(req);
368
369 return IRQ_HANDLED;
370}
371
372/**
373 * mpc52xx_lpbfifo_bcom_poll - Poll for DMA completion
374 */
375void mpc52xx_lpbfifo_poll(void)
376{
377 struct mpc52xx_lpbfifo_request *req = lpbfifo.req;
378 int dma = !(req->flags & MPC52XX_LPBFIFO_FLAG_NO_DMA);
379 int write = req->flags & MPC52XX_LPBFIFO_FLAG_WRITE;
380
381 /*
382 * For more information, see comments on the "Fat Lady"
383 */
384 if (dma && write)
385 mpc52xx_lpbfifo_irq(0, NULL);
386 else
387 mpc52xx_lpbfifo_bcom_irq(0, NULL);
388}
389EXPORT_SYMBOL(mpc52xx_lpbfifo_poll);
390
391/**
392 * mpc52xx_lpbfifo_submit - Submit an LPB FIFO transfer request.
393 * @req: Pointer to request structure
394 */
395int mpc52xx_lpbfifo_submit(struct mpc52xx_lpbfifo_request *req)
396{
397 unsigned long flags;
398
399 if (!lpbfifo.regs)
400 return -ENODEV;
401
402 spin_lock_irqsave(&lpbfifo.lock, flags);
403
404 /* If the req pointer is already set, then a transfer is in progress */
405 if (lpbfifo.req) {
406 spin_unlock_irqrestore(&lpbfifo.lock, flags);
407 return -EBUSY;
408 }
409
410 /* Setup the transfer */
411 lpbfifo.req = req;
412 req->irq_count = 0;
413 req->irq_ticks = 0;
414 req->buffer_not_done_cnt = 0;
415 req->pos = 0;
416
417 mpc52xx_lpbfifo_kick(req);
418 spin_unlock_irqrestore(&lpbfifo.lock, flags);
419 return 0;
420}
421EXPORT_SYMBOL(mpc52xx_lpbfifo_submit);
422
423void mpc52xx_lpbfifo_abort(struct mpc52xx_lpbfifo_request *req)
424{
425 unsigned long flags;
426
427 spin_lock_irqsave(&lpbfifo.lock, flags);
428 if (lpbfifo.req == req) {
429 /* Put it into reset and clear the state */
430 bcom_gen_bd_rx_reset(lpbfifo.bcom_rx_task);
431 bcom_gen_bd_tx_reset(lpbfifo.bcom_tx_task);
432 out_be32(lpbfifo.regs + LPBFIFO_REG_ENABLE, 0x01010000);
433 lpbfifo.req = NULL;
434 }
435 spin_unlock_irqrestore(&lpbfifo.lock, flags);
436}
437EXPORT_SYMBOL(mpc52xx_lpbfifo_abort);
438
439static int __devinit
440mpc52xx_lpbfifo_probe(struct of_device *op, const struct of_device_id *match)
441{
442 struct resource res;
443 int rc = -ENOMEM;
444
445 if (lpbfifo.dev != NULL)
446 return -ENOSPC;
447
448 lpbfifo.irq = irq_of_parse_and_map(op->node, 0);
449 if (!lpbfifo.irq)
450 return -ENODEV;
451
452 if (of_address_to_resource(op->node, 0, &res))
453 return -ENODEV;
454 lpbfifo.regs_phys = res.start;
455 lpbfifo.regs = of_iomap(op->node, 0);
456 if (!lpbfifo.regs)
457 return -ENOMEM;
458
459 spin_lock_init(&lpbfifo.lock);
460
461 /* Put FIFO into reset */
462 out_be32(lpbfifo.regs + LPBFIFO_REG_ENABLE, 0x01010000);
463
464 /* Register the interrupt handler */
465 rc = request_irq(lpbfifo.irq, mpc52xx_lpbfifo_irq, 0,
466 "mpc52xx-lpbfifo", &lpbfifo);
467 if (rc)
468 goto err_irq;
469
470 /* Request the Bestcomm receive (fifo --> memory) task and IRQ */
471 lpbfifo.bcom_rx_task =
472 bcom_gen_bd_rx_init(2, res.start + LPBFIFO_REG_FIFO_DATA,
473 BCOM_INITIATOR_SCLPC, BCOM_IPR_SCLPC,
474 16*1024*1024);
475 if (!lpbfifo.bcom_rx_task)
476 goto err_bcom_rx;
477
478 rc = request_irq(bcom_get_task_irq(lpbfifo.bcom_rx_task),
479 mpc52xx_lpbfifo_bcom_irq, 0,
480 "mpc52xx-lpbfifo-rx", &lpbfifo);
481 if (rc)
482 goto err_bcom_rx_irq;
483
484 /* Request the Bestcomm transmit (memory --> fifo) task and IRQ */
485 lpbfifo.bcom_tx_task =
486 bcom_gen_bd_tx_init(2, res.start + LPBFIFO_REG_FIFO_DATA,
487 BCOM_INITIATOR_SCLPC, BCOM_IPR_SCLPC);
488 if (!lpbfifo.bcom_tx_task)
489 goto err_bcom_tx;
490
491 lpbfifo.dev = &op->dev;
492 return 0;
493
494 err_bcom_tx:
495 free_irq(bcom_get_task_irq(lpbfifo.bcom_rx_task), &lpbfifo);
496 err_bcom_rx_irq:
497 bcom_gen_bd_rx_release(lpbfifo.bcom_rx_task);
498 err_bcom_rx:
499 err_irq:
500 iounmap(lpbfifo.regs);
501 lpbfifo.regs = NULL;
502
503 dev_err(&op->dev, "mpc52xx_lpbfifo_probe() failed\n");
504 return -ENODEV;
505}
506
507
508static int __devexit mpc52xx_lpbfifo_remove(struct of_device *op)
509{
510 if (lpbfifo.dev != &op->dev)
511 return 0;
512
513 /* Put FIFO in reset */
514 out_be32(lpbfifo.regs + LPBFIFO_REG_ENABLE, 0x01010000);
515
516 /* Release the bestcomm transmit task */
517 free_irq(bcom_get_task_irq(lpbfifo.bcom_tx_task), &lpbfifo);
518 bcom_gen_bd_tx_release(lpbfifo.bcom_tx_task);
519
520 /* Release the bestcomm receive task */
521 free_irq(bcom_get_task_irq(lpbfifo.bcom_rx_task), &lpbfifo);
522 bcom_gen_bd_rx_release(lpbfifo.bcom_rx_task);
523
524 free_irq(lpbfifo.irq, &lpbfifo);
525 iounmap(lpbfifo.regs);
526 lpbfifo.regs = NULL;
527 lpbfifo.dev = NULL;
528
529 return 0;
530}
531
532static struct of_device_id mpc52xx_lpbfifo_match[] __devinitconst = {
533 { .compatible = "fsl,mpc5200-lpbfifo", },
534 {},
535};
536
537static struct of_platform_driver mpc52xx_lpbfifo_driver = {
538 .owner = THIS_MODULE,
539 .name = "mpc52xx-lpbfifo",
540 .match_table = mpc52xx_lpbfifo_match,
541 .probe = mpc52xx_lpbfifo_probe,
542 .remove = __devexit_p(mpc52xx_lpbfifo_remove),
543};
544
545/***********************************************************************
546 * Module init/exit
547 */
548static int __init mpc52xx_lpbfifo_init(void)
549{
550 pr_debug("Registering LocalPlus bus FIFO driver\n");
551 return of_register_platform_driver(&mpc52xx_lpbfifo_driver);
552}
553module_init(mpc52xx_lpbfifo_init);
554
555static void __exit mpc52xx_lpbfifo_exit(void)
556{
557 pr_debug("Unregistering LocalPlus bus FIFO driver\n");
558 of_unregister_platform_driver(&mpc52xx_lpbfifo_driver);
559}
560module_exit(mpc52xx_lpbfifo_exit);
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pci.c b/arch/powerpc/platforms/52xx/mpc52xx_pci.c
index dd43114e9684..da110bd88346 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_pci.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_pci.c
@@ -100,7 +100,7 @@ const struct of_device_id mpc52xx_pci_ids[] __initdata = {
100}; 100};
101 101
102/* ======================================================================== */ 102/* ======================================================================== */
103/* PCI configuration acess */ 103/* PCI configuration access */
104/* ======================================================================== */ 104/* ======================================================================== */
105 105
106static int 106static int
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pic.c b/arch/powerpc/platforms/52xx/mpc52xx_pic.c
index 480f806fd0a9..4bf4bf7b063e 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_pic.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_pic.c
@@ -220,7 +220,7 @@ static int mpc52xx_extirq_set_type(unsigned int virq, unsigned int flow_type)
220} 220}
221 221
222static struct irq_chip mpc52xx_extirq_irqchip = { 222static struct irq_chip mpc52xx_extirq_irqchip = {
223 .typename = "MPC52xx External", 223 .name = "MPC52xx External",
224 .mask = mpc52xx_extirq_mask, 224 .mask = mpc52xx_extirq_mask,
225 .unmask = mpc52xx_extirq_unmask, 225 .unmask = mpc52xx_extirq_unmask,
226 .ack = mpc52xx_extirq_ack, 226 .ack = mpc52xx_extirq_ack,
@@ -258,7 +258,7 @@ static void mpc52xx_main_unmask(unsigned int virq)
258} 258}
259 259
260static struct irq_chip mpc52xx_main_irqchip = { 260static struct irq_chip mpc52xx_main_irqchip = {
261 .typename = "MPC52xx Main", 261 .name = "MPC52xx Main",
262 .mask = mpc52xx_main_mask, 262 .mask = mpc52xx_main_mask,
263 .mask_ack = mpc52xx_main_mask, 263 .mask_ack = mpc52xx_main_mask,
264 .unmask = mpc52xx_main_unmask, 264 .unmask = mpc52xx_main_unmask,
@@ -291,7 +291,7 @@ static void mpc52xx_periph_unmask(unsigned int virq)
291} 291}
292 292
293static struct irq_chip mpc52xx_periph_irqchip = { 293static struct irq_chip mpc52xx_periph_irqchip = {
294 .typename = "MPC52xx Peripherals", 294 .name = "MPC52xx Peripherals",
295 .mask = mpc52xx_periph_mask, 295 .mask = mpc52xx_periph_mask,
296 .mask_ack = mpc52xx_periph_mask, 296 .mask_ack = mpc52xx_periph_mask,
297 .unmask = mpc52xx_periph_unmask, 297 .unmask = mpc52xx_periph_unmask,
@@ -335,7 +335,7 @@ static void mpc52xx_sdma_ack(unsigned int virq)
335} 335}
336 336
337static struct irq_chip mpc52xx_sdma_irqchip = { 337static struct irq_chip mpc52xx_sdma_irqchip = {
338 .typename = "MPC52xx SDMA", 338 .name = "MPC52xx SDMA",
339 .mask = mpc52xx_sdma_mask, 339 .mask = mpc52xx_sdma_mask,
340 .unmask = mpc52xx_sdma_unmask, 340 .unmask = mpc52xx_sdma_unmask,
341 .ack = mpc52xx_sdma_ack, 341 .ack = mpc52xx_sdma_ack,
@@ -355,7 +355,7 @@ static int mpc52xx_is_extirq(int l1, int l2)
355 * mpc52xx_irqhost_xlate - translate virq# from device tree interrupts property 355 * mpc52xx_irqhost_xlate - translate virq# from device tree interrupts property
356 */ 356 */
357static int mpc52xx_irqhost_xlate(struct irq_host *h, struct device_node *ct, 357static int mpc52xx_irqhost_xlate(struct irq_host *h, struct device_node *ct,
358 u32 *intspec, unsigned int intsize, 358 const u32 *intspec, unsigned int intsize,
359 irq_hw_number_t *out_hwirq, 359 irq_hw_number_t *out_hwirq,
360 unsigned int *out_flags) 360 unsigned int *out_flags)
361{ 361{
diff --git a/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c b/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c
index 7ee979f323d1..9d962d7c72c1 100644
--- a/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c
+++ b/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c
@@ -69,7 +69,6 @@ static void pq2ads_pci_unmask_irq(unsigned int virq)
69} 69}
70 70
71static struct irq_chip pq2ads_pci_ic = { 71static struct irq_chip pq2ads_pci_ic = {
72 .typename = "PQ2 ADS PCI",
73 .name = "PQ2 ADS PCI", 72 .name = "PQ2 ADS PCI",
74 .end = pq2ads_pci_unmask_irq, 73 .end = pq2ads_pci_unmask_irq,
75 .mask = pq2ads_pci_mask_irq, 74 .mask = pq2ads_pci_mask_irq,
@@ -107,7 +106,7 @@ static void pq2ads_pci_irq_demux(unsigned int irq, struct irq_desc *desc)
107static int pci_pic_host_map(struct irq_host *h, unsigned int virq, 106static int pci_pic_host_map(struct irq_host *h, unsigned int virq,
108 irq_hw_number_t hw) 107 irq_hw_number_t hw)
109{ 108{
110 get_irq_desc(virq)->status |= IRQ_LEVEL; 109 irq_to_desc(virq)->status |= IRQ_LEVEL;
111 set_irq_chip_data(virq, h->host_data); 110 set_irq_chip_data(virq, h->host_data);
112 set_irq_chip_and_handler(virq, &pq2ads_pci_ic, handle_level_irq); 111 set_irq_chip_and_handler(virq, &pq2ads_pci_ic, handle_level_irq);
113 return 0; 112 return 0;
diff --git a/arch/powerpc/platforms/83xx/mpc832x_rdb.c b/arch/powerpc/platforms/83xx/mpc832x_rdb.c
index 567ded7c3b9b..17f99745f0e4 100644
--- a/arch/powerpc/platforms/83xx/mpc832x_rdb.c
+++ b/arch/powerpc/platforms/83xx/mpc832x_rdb.c
@@ -74,7 +74,7 @@ static int __init of_fsl_spi_probe(char *type, char *compatible, u32 sysclk,
74 74
75 prop = of_get_property(np, "mode", NULL); 75 prop = of_get_property(np, "mode", NULL);
76 if (prop && !strcmp(prop, "cpu-qe")) 76 if (prop && !strcmp(prop, "cpu-qe"))
77 pdata.qe_mode = 1; 77 pdata.flags = SPI_QE_CPU_MODE;
78 78
79 for (j = 0; j < num_board_infos; j++) { 79 for (j = 0; j < num_board_infos; j++) {
80 if (board_infos[j].bus_num == pdata.bus_num) 80 if (board_infos[j].bus_num == pdata.bus_num)
diff --git a/arch/powerpc/platforms/83xx/suspend.c b/arch/powerpc/platforms/83xx/suspend.c
index 08e65fc8b98c..43805348b81e 100644
--- a/arch/powerpc/platforms/83xx/suspend.c
+++ b/arch/powerpc/platforms/83xx/suspend.c
@@ -32,6 +32,7 @@
32#define PMCCR1_NEXT_STATE 0x0C /* Next state for power management */ 32#define PMCCR1_NEXT_STATE 0x0C /* Next state for power management */
33#define PMCCR1_NEXT_STATE_SHIFT 2 33#define PMCCR1_NEXT_STATE_SHIFT 2
34#define PMCCR1_CURR_STATE 0x03 /* Current state for power management*/ 34#define PMCCR1_CURR_STATE 0x03 /* Current state for power management*/
35#define IMMR_SYSCR_OFFSET 0x100
35#define IMMR_RCW_OFFSET 0x900 36#define IMMR_RCW_OFFSET 0x900
36#define RCW_PCI_HOST 0x80000000 37#define RCW_PCI_HOST 0x80000000
37 38
@@ -78,6 +79,22 @@ struct mpc83xx_clock {
78 u32 sccr; 79 u32 sccr;
79}; 80};
80 81
82struct mpc83xx_syscr {
83 __be32 sgprl;
84 __be32 sgprh;
85 __be32 spridr;
86 __be32 :32;
87 __be32 spcr;
88 __be32 sicrl;
89 __be32 sicrh;
90};
91
92struct mpc83xx_saved {
93 u32 sicrl;
94 u32 sicrh;
95 u32 sccr;
96};
97
81struct pmc_type { 98struct pmc_type {
82 int has_deep_sleep; 99 int has_deep_sleep;
83}; 100};
@@ -87,6 +104,8 @@ static int has_deep_sleep, deep_sleeping;
87static int pmc_irq; 104static int pmc_irq;
88static struct mpc83xx_pmc __iomem *pmc_regs; 105static struct mpc83xx_pmc __iomem *pmc_regs;
89static struct mpc83xx_clock __iomem *clock_regs; 106static struct mpc83xx_clock __iomem *clock_regs;
107static struct mpc83xx_syscr __iomem *syscr_regs;
108static struct mpc83xx_saved saved_regs;
90static int is_pci_agent, wake_from_pci; 109static int is_pci_agent, wake_from_pci;
91static phys_addr_t immrbase; 110static phys_addr_t immrbase;
92static int pci_pm_state; 111static int pci_pm_state;
@@ -96,6 +115,7 @@ int fsl_deep_sleep(void)
96{ 115{
97 return deep_sleeping; 116 return deep_sleeping;
98} 117}
118EXPORT_SYMBOL(fsl_deep_sleep);
99 119
100static int mpc83xx_change_state(void) 120static int mpc83xx_change_state(void)
101{ 121{
@@ -136,6 +156,20 @@ static irqreturn_t pmc_irq_handler(int irq, void *dev_id)
136 return ret; 156 return ret;
137} 157}
138 158
159static void mpc83xx_suspend_restore_regs(void)
160{
161 out_be32(&syscr_regs->sicrl, saved_regs.sicrl);
162 out_be32(&syscr_regs->sicrh, saved_regs.sicrh);
163 out_be32(&clock_regs->sccr, saved_regs.sccr);
164}
165
166static void mpc83xx_suspend_save_regs(void)
167{
168 saved_regs.sicrl = in_be32(&syscr_regs->sicrl);
169 saved_regs.sicrh = in_be32(&syscr_regs->sicrh);
170 saved_regs.sccr = in_be32(&clock_regs->sccr);
171}
172
139static int mpc83xx_suspend_enter(suspend_state_t state) 173static int mpc83xx_suspend_enter(suspend_state_t state)
140{ 174{
141 int ret = -EAGAIN; 175 int ret = -EAGAIN;
@@ -165,6 +199,8 @@ static int mpc83xx_suspend_enter(suspend_state_t state)
165 */ 199 */
166 200
167 if (deep_sleeping) { 201 if (deep_sleeping) {
202 mpc83xx_suspend_save_regs();
203
168 out_be32(&pmc_regs->mask, PMCER_ALL); 204 out_be32(&pmc_regs->mask, PMCER_ALL);
169 205
170 out_be32(&pmc_regs->config1, 206 out_be32(&pmc_regs->config1,
@@ -178,6 +214,8 @@ static int mpc83xx_suspend_enter(suspend_state_t state)
178 in_be32(&pmc_regs->config1) & ~PMCCR1_POWER_OFF); 214 in_be32(&pmc_regs->config1) & ~PMCCR1_POWER_OFF);
179 215
180 out_be32(&pmc_regs->mask, PMCER_PMCI); 216 out_be32(&pmc_regs->mask, PMCER_PMCI);
217
218 mpc83xx_suspend_restore_regs();
181 } else { 219 } else {
182 out_be32(&pmc_regs->mask, PMCER_PMCI); 220 out_be32(&pmc_regs->mask, PMCER_PMCI);
183 221
@@ -193,7 +231,7 @@ out:
193 return ret; 231 return ret;
194} 232}
195 233
196static void mpc83xx_suspend_finish(void) 234static void mpc83xx_suspend_end(void)
197{ 235{
198 deep_sleeping = 0; 236 deep_sleeping = 0;
199} 237}
@@ -277,7 +315,7 @@ static struct platform_suspend_ops mpc83xx_suspend_ops = {
277 .valid = mpc83xx_suspend_valid, 315 .valid = mpc83xx_suspend_valid,
278 .begin = mpc83xx_suspend_begin, 316 .begin = mpc83xx_suspend_begin,
279 .enter = mpc83xx_suspend_enter, 317 .enter = mpc83xx_suspend_enter,
280 .finish = mpc83xx_suspend_finish, 318 .end = mpc83xx_suspend_end,
281}; 319};
282 320
283static int pmc_probe(struct of_device *ofdev, 321static int pmc_probe(struct of_device *ofdev,
@@ -332,12 +370,23 @@ static int pmc_probe(struct of_device *ofdev,
332 goto out_pmc; 370 goto out_pmc;
333 } 371 }
334 372
373 if (has_deep_sleep) {
374 syscr_regs = ioremap(immrbase + IMMR_SYSCR_OFFSET,
375 sizeof(*syscr_regs));
376 if (!syscr_regs) {
377 ret = -ENOMEM;
378 goto out_syscr;
379 }
380 }
381
335 if (is_pci_agent) 382 if (is_pci_agent)
336 mpc83xx_set_agent(); 383 mpc83xx_set_agent();
337 384
338 suspend_set_ops(&mpc83xx_suspend_ops); 385 suspend_set_ops(&mpc83xx_suspend_ops);
339 return 0; 386 return 0;
340 387
388out_syscr:
389 iounmap(clock_regs);
341out_pmc: 390out_pmc:
342 iounmap(pmc_regs); 391 iounmap(pmc_regs);
343out: 392out:
diff --git a/arch/powerpc/platforms/85xx/Kconfig b/arch/powerpc/platforms/85xx/Kconfig
index d3a975e8fd3e..d95121894eb7 100644
--- a/arch/powerpc/platforms/85xx/Kconfig
+++ b/arch/powerpc/platforms/85xx/Kconfig
@@ -1,6 +1,7 @@
1menuconfig MPC85xx 1menuconfig FSL_SOC_BOOKE
2 bool "Machine Type" 2 bool "Freescale Book-E Machine Type"
3 depends on PPC_85xx 3 depends on PPC_85xx || PPC_BOOK3E
4 select FSL_SOC
4 select PPC_UDBG_16550 5 select PPC_UDBG_16550
5 select MPIC 6 select MPIC
6 select PPC_PCI_CHOICE 7 select PPC_PCI_CHOICE
@@ -8,7 +9,7 @@ menuconfig MPC85xx
8 select SERIAL_8250_SHARE_IRQ if SERIAL_8250 9 select SERIAL_8250_SHARE_IRQ if SERIAL_8250
9 default y 10 default y
10 11
11if MPC85xx 12if FSL_SOC_BOOKE
12 13
13config MPC8540_ADS 14config MPC8540_ADS
14 bool "Freescale MPC8540 ADS" 15 bool "Freescale MPC8540 ADS"
@@ -144,7 +145,19 @@ config SBC8560
144 help 145 help
145 This option enables support for the Wind River SBC8560 board 146 This option enables support for the Wind River SBC8560 board
146 147
147endif # MPC85xx 148config P4080_DS
149 bool "Freescale P4080 DS"
150 select DEFAULT_UIMAGE
151 select PPC_FSL_BOOK3E
152 select PPC_E500MC
153 select PHYS_64BIT
154 select SWIOTLB
155 select MPC8xxx_GPIO
156 select HAS_RAPIDIO
157 help
158 This option enables support for the P4080 DS board
159
160endif # FSL_SOC_BOOKE
148 161
149config TQM85xx 162config TQM85xx
150 bool 163 bool
diff --git a/arch/powerpc/platforms/85xx/Makefile b/arch/powerpc/platforms/85xx/Makefile
index 9098aea0cf32..387c128f2c8c 100644
--- a/arch/powerpc/platforms/85xx/Makefile
+++ b/arch/powerpc/platforms/85xx/Makefile
@@ -10,6 +10,7 @@ obj-$(CONFIG_MPC8536_DS) += mpc8536_ds.o
10obj-$(CONFIG_MPC85xx_DS) += mpc85xx_ds.o 10obj-$(CONFIG_MPC85xx_DS) += mpc85xx_ds.o
11obj-$(CONFIG_MPC85xx_MDS) += mpc85xx_mds.o 11obj-$(CONFIG_MPC85xx_MDS) += mpc85xx_mds.o
12obj-$(CONFIG_MPC85xx_RDB) += mpc85xx_rdb.o 12obj-$(CONFIG_MPC85xx_RDB) += mpc85xx_rdb.o
13obj-$(CONFIG_P4080_DS) += p4080_ds.o corenet_ds.o
13obj-$(CONFIG_STX_GP3) += stx_gp3.o 14obj-$(CONFIG_STX_GP3) += stx_gp3.o
14obj-$(CONFIG_TQM85xx) += tqm85xx.o 15obj-$(CONFIG_TQM85xx) += tqm85xx.o
15obj-$(CONFIG_SBC8560) += sbc8560.o 16obj-$(CONFIG_SBC8560) += sbc8560.o
diff --git a/arch/powerpc/platforms/85xx/corenet_ds.c b/arch/powerpc/platforms/85xx/corenet_ds.c
new file mode 100644
index 000000000000..534c2ecc89d9
--- /dev/null
+++ b/arch/powerpc/platforms/85xx/corenet_ds.c
@@ -0,0 +1,125 @@
1/*
2 * Corenet based SoC DS Setup
3 *
4 * Maintained by Kumar Gala (see MAINTAINERS for contact information)
5 *
6 * Copyright 2009 Freescale Semiconductor Inc.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 */
13
14#include <linux/kernel.h>
15#include <linux/pci.h>
16#include <linux/kdev_t.h>
17#include <linux/delay.h>
18#include <linux/interrupt.h>
19#include <linux/lmb.h>
20
21#include <asm/system.h>
22#include <asm/time.h>
23#include <asm/machdep.h>
24#include <asm/pci-bridge.h>
25#include <mm/mmu_decl.h>
26#include <asm/prom.h>
27#include <asm/udbg.h>
28#include <asm/mpic.h>
29
30#include <linux/of_platform.h>
31#include <sysdev/fsl_soc.h>
32#include <sysdev/fsl_pci.h>
33
34void __init corenet_ds_pic_init(void)
35{
36 struct mpic *mpic;
37 struct resource r;
38 struct device_node *np = NULL;
39 unsigned int flags = MPIC_PRIMARY | MPIC_BIG_ENDIAN |
40 MPIC_BROKEN_FRR_NIRQS | MPIC_SINGLE_DEST_CPU;
41
42 np = of_find_node_by_type(np, "open-pic");
43
44 if (np == NULL) {
45 printk(KERN_ERR "Could not find open-pic node\n");
46 return;
47 }
48
49 if (of_address_to_resource(np, 0, &r)) {
50 printk(KERN_ERR "Failed to map mpic register space\n");
51 of_node_put(np);
52 return;
53 }
54
55 if (ppc_md.get_irq == mpic_get_coreint_irq)
56 flags |= MPIC_ENABLE_COREINT;
57
58 mpic = mpic_alloc(np, r.start, flags, 0, 256, " OpenPIC ");
59 BUG_ON(mpic == NULL);
60
61 mpic_init(mpic);
62}
63
64#ifdef CONFIG_PCI
65static int primary_phb_addr;
66#endif
67
68/*
69 * Setup the architecture
70 */
71#ifdef CONFIG_SMP
72void __init mpc85xx_smp_init(void);
73#endif
74
75void __init corenet_ds_setup_arch(void)
76{
77#ifdef CONFIG_PCI
78 struct device_node *np;
79 struct pci_controller *hose;
80#endif
81 dma_addr_t max = 0xffffffff;
82
83#ifdef CONFIG_SMP
84 mpc85xx_smp_init();
85#endif
86
87#ifdef CONFIG_PCI
88 for_each_compatible_node(np, "pci", "fsl,p4080-pcie") {
89 struct resource rsrc;
90 of_address_to_resource(np, 0, &rsrc);
91 if ((rsrc.start & 0xfffff) == primary_phb_addr)
92 fsl_add_bridge(np, 1);
93 else
94 fsl_add_bridge(np, 0);
95
96 hose = pci_find_hose_for_OF_device(np);
97 max = min(max, hose->dma_window_base_cur +
98 hose->dma_window_size);
99 }
100#endif
101
102#ifdef CONFIG_SWIOTLB
103 if (lmb_end_of_DRAM() > max) {
104 ppc_swiotlb_enable = 1;
105 set_pci_dma_ops(&swiotlb_dma_ops);
106 ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb;
107 }
108#endif
109 pr_info("%s board from Freescale Semiconductor\n", ppc_md.name);
110}
111
112static const struct of_device_id of_device_ids[] __devinitconst = {
113 {
114 .compatible = "simple-bus"
115 },
116 {
117 .compatible = "fsl,rapidio-delta",
118 },
119 {}
120};
121
122int __init corenet_ds_publish_devices(void)
123{
124 return of_platform_bus_probe(NULL, of_device_ids, NULL);
125}
diff --git a/arch/powerpc/platforms/85xx/corenet_ds.h b/arch/powerpc/platforms/85xx/corenet_ds.h
new file mode 100644
index 000000000000..ddd700b23031
--- /dev/null
+++ b/arch/powerpc/platforms/85xx/corenet_ds.h
@@ -0,0 +1,19 @@
1/*
2 * Corenet based SoC DS Setup
3 *
4 * Copyright 2009 Freescale Semiconductor Inc.
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 */
11
12#ifndef CORENET_DS_H
13#define CORENET_DS_H
14
15extern void __init corenet_ds_pic_init(void);
16extern void __init corenet_ds_setup_arch(void);
17extern int __init corenet_ds_publish_devices(void);
18
19#endif
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_mds.c b/arch/powerpc/platforms/85xx/mpc85xx_mds.c
index 3909d57b86e3..21f61b8c445b 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_mds.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_mds.c
@@ -86,7 +86,7 @@ static int mpc8568_fixup_125_clock(struct phy_device *phydev)
86 scr = phy_read(phydev, MV88E1111_SCR); 86 scr = phy_read(phydev, MV88E1111_SCR);
87 87
88 if (scr < 0) 88 if (scr < 0)
89 return err; 89 return scr;
90 90
91 err = phy_write(phydev, MV88E1111_SCR, scr | 0x0008); 91 err = phy_write(phydev, MV88E1111_SCR, scr | 0x0008);
92 92
@@ -301,6 +301,7 @@ static struct of_device_id mpc85xx_ids[] = {
301 { .compatible = "fsl,qe", }, 301 { .compatible = "fsl,qe", },
302 { .compatible = "gianfar", }, 302 { .compatible = "gianfar", },
303 { .compatible = "fsl,rapidio-delta", }, 303 { .compatible = "fsl,rapidio-delta", },
304 { .compatible = "fsl,mpc8548-guts", },
304 {}, 305 {},
305}; 306};
306 307
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_rdb.c b/arch/powerpc/platforms/85xx/mpc85xx_rdb.c
index c8468de4acf6..088f30b0c088 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_rdb.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_rdb.c
@@ -44,6 +44,7 @@ void __init mpc85xx_rdb_pic_init(void)
44 struct mpic *mpic; 44 struct mpic *mpic;
45 struct resource r; 45 struct resource r;
46 struct device_node *np; 46 struct device_node *np;
47 unsigned long root = of_get_flat_dt_root();
47 48
48 np = of_find_node_by_type(NULL, "open-pic"); 49 np = of_find_node_by_type(NULL, "open-pic");
49 if (np == NULL) { 50 if (np == NULL) {
@@ -57,11 +58,18 @@ void __init mpc85xx_rdb_pic_init(void)
57 return; 58 return;
58 } 59 }
59 60
60 mpic = mpic_alloc(np, r.start, 61 if (of_flat_dt_is_compatible(root, "fsl,85XXRDB-CAMP")) {
62 mpic = mpic_alloc(np, r.start,
63 MPIC_PRIMARY |
64 MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS,
65 0, 256, " OpenPIC ");
66 } else {
67 mpic = mpic_alloc(np, r.start,
61 MPIC_PRIMARY | MPIC_WANTS_RESET | 68 MPIC_PRIMARY | MPIC_WANTS_RESET |
62 MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS | 69 MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS |
63 MPIC_SINGLE_DEST_CPU, 70 MPIC_SINGLE_DEST_CPU,
64 0, 256, " OpenPIC "); 71 0, 256, " OpenPIC ");
72 }
65 73
66 BUG_ON(mpic == NULL); 74 BUG_ON(mpic == NULL);
67 of_node_put(np); 75 of_node_put(np);
@@ -113,6 +121,7 @@ static int __init mpc85xxrdb_publish_devices(void)
113 return of_platform_bus_probe(NULL, mpc85xxrdb_ids, NULL); 121 return of_platform_bus_probe(NULL, mpc85xxrdb_ids, NULL);
114} 122}
115machine_device_initcall(p2020_rdb, mpc85xxrdb_publish_devices); 123machine_device_initcall(p2020_rdb, mpc85xxrdb_publish_devices);
124machine_device_initcall(p1020_rdb, mpc85xxrdb_publish_devices);
116 125
117/* 126/*
118 * Called very early, device-tree isn't unflattened 127 * Called very early, device-tree isn't unflattened
@@ -126,6 +135,15 @@ static int __init p2020_rdb_probe(void)
126 return 0; 135 return 0;
127} 136}
128 137
138static int __init p1020_rdb_probe(void)
139{
140 unsigned long root = of_get_flat_dt_root();
141
142 if (of_flat_dt_is_compatible(root, "fsl,P1020RDB"))
143 return 1;
144 return 0;
145}
146
129define_machine(p2020_rdb) { 147define_machine(p2020_rdb) {
130 .name = "P2020 RDB", 148 .name = "P2020 RDB",
131 .probe = p2020_rdb_probe, 149 .probe = p2020_rdb_probe,
@@ -139,3 +157,17 @@ define_machine(p2020_rdb) {
139 .calibrate_decr = generic_calibrate_decr, 157 .calibrate_decr = generic_calibrate_decr,
140 .progress = udbg_progress, 158 .progress = udbg_progress,
141}; 159};
160
161define_machine(p1020_rdb) {
162 .name = "P1020 RDB",
163 .probe = p1020_rdb_probe,
164 .setup_arch = mpc85xx_rdb_setup_arch,
165 .init_IRQ = mpc85xx_rdb_pic_init,
166#ifdef CONFIG_PCI
167 .pcibios_fixup_bus = fsl_pcibios_fixup_bus,
168#endif
169 .get_irq = mpic_get_irq,
170 .restart = fsl_rstcr_restart,
171 .calibrate_decr = generic_calibrate_decr,
172 .progress = udbg_progress,
173};
diff --git a/arch/powerpc/platforms/85xx/p4080_ds.c b/arch/powerpc/platforms/85xx/p4080_ds.c
new file mode 100644
index 000000000000..84170460497b
--- /dev/null
+++ b/arch/powerpc/platforms/85xx/p4080_ds.c
@@ -0,0 +1,74 @@
1/*
2 * P4080 DS Setup
3 *
4 * Maintained by Kumar Gala (see MAINTAINERS for contact information)
5 *
6 * Copyright 2009 Freescale Semiconductor Inc.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 */
13
14#include <linux/kernel.h>
15#include <linux/pci.h>
16#include <linux/kdev_t.h>
17#include <linux/delay.h>
18#include <linux/interrupt.h>
19
20#include <asm/system.h>
21#include <asm/time.h>
22#include <asm/machdep.h>
23#include <asm/pci-bridge.h>
24#include <mm/mmu_decl.h>
25#include <asm/prom.h>
26#include <asm/udbg.h>
27#include <asm/mpic.h>
28
29#include <linux/of_platform.h>
30#include <sysdev/fsl_soc.h>
31#include <sysdev/fsl_pci.h>
32
33#include "corenet_ds.h"
34
35#ifdef CONFIG_PCI
36static int primary_phb_addr;
37#endif
38
39/*
40 * Called very early, device-tree isn't unflattened
41 */
42static int __init p4080_ds_probe(void)
43{
44 unsigned long root = of_get_flat_dt_root();
45
46 if (of_flat_dt_is_compatible(root, "fsl,P4080DS")) {
47#ifdef CONFIG_PCI
48 /* treat PCIe1 as primary,
49 * shouldn't matter as we have no ISA on the board
50 */
51 primary_phb_addr = 0x0000;
52#endif
53 return 1;
54 } else {
55 return 0;
56 }
57}
58
59define_machine(p4080_ds) {
60 .name = "P4080 DS",
61 .probe = p4080_ds_probe,
62 .setup_arch = corenet_ds_setup_arch,
63 .init_IRQ = corenet_ds_pic_init,
64#ifdef CONFIG_PCI
65 .pcibios_fixup_bus = fsl_pcibios_fixup_bus,
66#endif
67 .get_irq = mpic_get_coreint_irq,
68 .restart = fsl_rstcr_restart,
69 .calibrate_decr = generic_calibrate_decr,
70 .progress = udbg_progress,
71};
72
73machine_device_initcall(p4080_ds, corenet_ds_publish_devices);
74machine_arch_initcall(p4080_ds, swiotlb_setup_bus_notifier);
diff --git a/arch/powerpc/platforms/85xx/socrates_fpga_pic.c b/arch/powerpc/platforms/85xx/socrates_fpga_pic.c
index 60edf63d0157..e5da5f62b24a 100644
--- a/arch/powerpc/platforms/85xx/socrates_fpga_pic.c
+++ b/arch/powerpc/platforms/85xx/socrates_fpga_pic.c
@@ -232,7 +232,7 @@ static int socrates_fpga_pic_set_type(unsigned int virq,
232} 232}
233 233
234static struct irq_chip socrates_fpga_pic_chip = { 234static struct irq_chip socrates_fpga_pic_chip = {
235 .typename = " FPGA-PIC ", 235 .name = " FPGA-PIC ",
236 .ack = socrates_fpga_pic_ack, 236 .ack = socrates_fpga_pic_ack,
237 .mask = socrates_fpga_pic_mask, 237 .mask = socrates_fpga_pic_mask,
238 .mask_ack = socrates_fpga_pic_mask_ack, 238 .mask_ack = socrates_fpga_pic_mask_ack,
@@ -245,7 +245,7 @@ static int socrates_fpga_pic_host_map(struct irq_host *h, unsigned int virq,
245 irq_hw_number_t hwirq) 245 irq_hw_number_t hwirq)
246{ 246{
247 /* All interrupts are LEVEL sensitive */ 247 /* All interrupts are LEVEL sensitive */
248 get_irq_desc(virq)->status |= IRQ_LEVEL; 248 irq_to_desc(virq)->status |= IRQ_LEVEL;
249 set_irq_chip_and_handler(virq, &socrates_fpga_pic_chip, 249 set_irq_chip_and_handler(virq, &socrates_fpga_pic_chip,
250 handle_fasteoi_irq); 250 handle_fasteoi_irq);
251 251
@@ -253,7 +253,7 @@ static int socrates_fpga_pic_host_map(struct irq_host *h, unsigned int virq,
253} 253}
254 254
255static int socrates_fpga_pic_host_xlate(struct irq_host *h, 255static int socrates_fpga_pic_host_xlate(struct irq_host *h,
256 struct device_node *ct, u32 *intspec, unsigned int intsize, 256 struct device_node *ct, const u32 *intspec, unsigned int intsize,
257 irq_hw_number_t *out_hwirq, unsigned int *out_flags) 257 irq_hw_number_t *out_hwirq, unsigned int *out_flags)
258{ 258{
259 struct socrates_fpga_irq_info *fpga_irq = &fpga_irqs[intspec[0]]; 259 struct socrates_fpga_irq_info *fpga_irq = &fpga_irqs[intspec[0]];
diff --git a/arch/powerpc/platforms/86xx/Kconfig b/arch/powerpc/platforms/86xx/Kconfig
index 9c7b64a3402b..2bbfd530d6d8 100644
--- a/arch/powerpc/platforms/86xx/Kconfig
+++ b/arch/powerpc/platforms/86xx/Kconfig
@@ -35,6 +35,7 @@ config MPC8610_HPCD
35config GEF_PPC9A 35config GEF_PPC9A
36 bool "GE Fanuc PPC9A" 36 bool "GE Fanuc PPC9A"
37 select DEFAULT_UIMAGE 37 select DEFAULT_UIMAGE
38 select MMIO_NVRAM
38 select GENERIC_GPIO 39 select GENERIC_GPIO
39 select ARCH_REQUIRE_GPIOLIB 40 select ARCH_REQUIRE_GPIOLIB
40 help 41 help
@@ -43,6 +44,7 @@ config GEF_PPC9A
43config GEF_SBC310 44config GEF_SBC310
44 bool "GE Fanuc SBC310" 45 bool "GE Fanuc SBC310"
45 select DEFAULT_UIMAGE 46 select DEFAULT_UIMAGE
47 select MMIO_NVRAM
46 select GENERIC_GPIO 48 select GENERIC_GPIO
47 select ARCH_REQUIRE_GPIOLIB 49 select ARCH_REQUIRE_GPIOLIB
48 help 50 help
@@ -51,6 +53,7 @@ config GEF_SBC310
51config GEF_SBC610 53config GEF_SBC610
52 bool "GE Fanuc SBC610" 54 bool "GE Fanuc SBC610"
53 select DEFAULT_UIMAGE 55 select DEFAULT_UIMAGE
56 select MMIO_NVRAM
54 select GENERIC_GPIO 57 select GENERIC_GPIO
55 select ARCH_REQUIRE_GPIOLIB 58 select ARCH_REQUIRE_GPIOLIB
56 select HAS_RAPIDIO 59 select HAS_RAPIDIO
diff --git a/arch/powerpc/platforms/86xx/gef_pic.c b/arch/powerpc/platforms/86xx/gef_pic.c
index 50d0a2b63809..0110a8736d33 100644
--- a/arch/powerpc/platforms/86xx/gef_pic.c
+++ b/arch/powerpc/platforms/86xx/gef_pic.c
@@ -149,7 +149,7 @@ static void gef_pic_unmask(unsigned int virq)
149} 149}
150 150
151static struct irq_chip gef_pic_chip = { 151static struct irq_chip gef_pic_chip = {
152 .typename = "gefp", 152 .name = "gefp",
153 .mask = gef_pic_mask, 153 .mask = gef_pic_mask,
154 .mask_ack = gef_pic_mask_ack, 154 .mask_ack = gef_pic_mask_ack,
155 .unmask = gef_pic_unmask, 155 .unmask = gef_pic_unmask,
@@ -163,14 +163,14 @@ static int gef_pic_host_map(struct irq_host *h, unsigned int virq,
163 irq_hw_number_t hwirq) 163 irq_hw_number_t hwirq)
164{ 164{
165 /* All interrupts are LEVEL sensitive */ 165 /* All interrupts are LEVEL sensitive */
166 get_irq_desc(virq)->status |= IRQ_LEVEL; 166 irq_to_desc(virq)->status |= IRQ_LEVEL;
167 set_irq_chip_and_handler(virq, &gef_pic_chip, handle_level_irq); 167 set_irq_chip_and_handler(virq, &gef_pic_chip, handle_level_irq);
168 168
169 return 0; 169 return 0;
170} 170}
171 171
172static int gef_pic_host_xlate(struct irq_host *h, struct device_node *ct, 172static int gef_pic_host_xlate(struct irq_host *h, struct device_node *ct,
173 u32 *intspec, unsigned int intsize, 173 const u32 *intspec, unsigned int intsize,
174 irq_hw_number_t *out_hwirq, unsigned int *out_flags) 174 irq_hw_number_t *out_hwirq, unsigned int *out_flags)
175{ 175{
176 176
diff --git a/arch/powerpc/platforms/86xx/gef_ppc9a.c b/arch/powerpc/platforms/86xx/gef_ppc9a.c
index 287f7bd17dd9..a792e5d85813 100644
--- a/arch/powerpc/platforms/86xx/gef_ppc9a.c
+++ b/arch/powerpc/platforms/86xx/gef_ppc9a.c
@@ -33,6 +33,7 @@
33#include <asm/udbg.h> 33#include <asm/udbg.h>
34 34
35#include <asm/mpic.h> 35#include <asm/mpic.h>
36#include <asm/nvram.h>
36 37
37#include <sysdev/fsl_pci.h> 38#include <sysdev/fsl_pci.h>
38#include <sysdev/fsl_soc.h> 39#include <sysdev/fsl_soc.h>
@@ -95,6 +96,10 @@ static void __init gef_ppc9a_setup_arch(void)
95 printk(KERN_WARNING "Unable to map board registers\n"); 96 printk(KERN_WARNING "Unable to map board registers\n");
96 of_node_put(regs); 97 of_node_put(regs);
97 } 98 }
99
100#if defined(CONFIG_MMIO_NVRAM)
101 mmio_nvram_init();
102#endif
98} 103}
99 104
100/* Return the PCB revision */ 105/* Return the PCB revision */
diff --git a/arch/powerpc/platforms/86xx/gef_sbc310.c b/arch/powerpc/platforms/86xx/gef_sbc310.c
index 90754e752bd8..6a1a613836c2 100644
--- a/arch/powerpc/platforms/86xx/gef_sbc310.c
+++ b/arch/powerpc/platforms/86xx/gef_sbc310.c
@@ -33,6 +33,7 @@
33#include <asm/udbg.h> 33#include <asm/udbg.h>
34 34
35#include <asm/mpic.h> 35#include <asm/mpic.h>
36#include <asm/nvram.h>
36 37
37#include <sysdev/fsl_pci.h> 38#include <sysdev/fsl_pci.h>
38#include <sysdev/fsl_soc.h> 39#include <sysdev/fsl_soc.h>
@@ -95,6 +96,10 @@ static void __init gef_sbc310_setup_arch(void)
95 printk(KERN_WARNING "Unable to map board registers\n"); 96 printk(KERN_WARNING "Unable to map board registers\n");
96 of_node_put(regs); 97 of_node_put(regs);
97 } 98 }
99
100#if defined(CONFIG_MMIO_NVRAM)
101 mmio_nvram_init();
102#endif
98} 103}
99 104
100/* Return the PCB revision */ 105/* Return the PCB revision */
diff --git a/arch/powerpc/platforms/86xx/gef_sbc610.c b/arch/powerpc/platforms/86xx/gef_sbc610.c
index 72b31a6010a0..e10688a0fc4e 100644
--- a/arch/powerpc/platforms/86xx/gef_sbc610.c
+++ b/arch/powerpc/platforms/86xx/gef_sbc610.c
@@ -33,6 +33,7 @@
33#include <asm/udbg.h> 33#include <asm/udbg.h>
34 34
35#include <asm/mpic.h> 35#include <asm/mpic.h>
36#include <asm/nvram.h>
36 37
37#include <sysdev/fsl_pci.h> 38#include <sysdev/fsl_pci.h>
38#include <sysdev/fsl_soc.h> 39#include <sysdev/fsl_soc.h>
@@ -95,6 +96,10 @@ static void __init gef_sbc610_setup_arch(void)
95 printk(KERN_WARNING "Unable to map board registers\n"); 96 printk(KERN_WARNING "Unable to map board registers\n");
96 of_node_put(regs); 97 of_node_put(regs);
97 } 98 }
99
100#if defined(CONFIG_MMIO_NVRAM)
101 mmio_nvram_init();
102#endif
98} 103}
99 104
100/* Return the PCB revision */ 105/* Return the PCB revision */
diff --git a/arch/powerpc/platforms/86xx/mpc8610_hpcd.c b/arch/powerpc/platforms/86xx/mpc8610_hpcd.c
index 627908a4cd77..5abe137f6309 100644
--- a/arch/powerpc/platforms/86xx/mpc8610_hpcd.c
+++ b/arch/powerpc/platforms/86xx/mpc8610_hpcd.c
@@ -19,6 +19,7 @@
19#include <linux/stddef.h> 19#include <linux/stddef.h>
20#include <linux/kernel.h> 20#include <linux/kernel.h>
21#include <linux/pci.h> 21#include <linux/pci.h>
22#include <linux/interrupt.h>
22#include <linux/kdev_t.h> 23#include <linux/kdev_t.h>
23#include <linux/delay.h> 24#include <linux/delay.h>
24#include <linux/seq_file.h> 25#include <linux/seq_file.h>
@@ -41,10 +42,46 @@
41 42
42#include "mpc86xx.h" 43#include "mpc86xx.h"
43 44
45static struct device_node *pixis_node;
44static unsigned char *pixis_bdcfg0, *pixis_arch; 46static unsigned char *pixis_bdcfg0, *pixis_arch;
45 47
48#ifdef CONFIG_SUSPEND
49static irqreturn_t mpc8610_sw9_irq(int irq, void *data)
50{
51 pr_debug("%s: PIXIS' event (sw9/wakeup) IRQ handled\n", __func__);
52 return IRQ_HANDLED;
53}
54
55static void __init mpc8610_suspend_init(void)
56{
57 int irq;
58 int ret;
59
60 if (!pixis_node)
61 return;
62
63 irq = irq_of_parse_and_map(pixis_node, 0);
64 if (!irq) {
65 pr_err("%s: can't map pixis event IRQ.\n", __func__);
66 return;
67 }
68
69 ret = request_irq(irq, mpc8610_sw9_irq, 0, "sw9/wakeup", NULL);
70 if (ret) {
71 pr_err("%s: can't request pixis event IRQ: %d\n",
72 __func__, ret);
73 irq_dispose_mapping(irq);
74 }
75
76 enable_irq_wake(irq);
77}
78#else
79static inline void mpc8610_suspend_init(void) { }
80#endif /* CONFIG_SUSPEND */
81
46static struct of_device_id __initdata mpc8610_ids[] = { 82static struct of_device_id __initdata mpc8610_ids[] = {
47 { .compatible = "fsl,mpc8610-immr", }, 83 { .compatible = "fsl,mpc8610-immr", },
84 { .compatible = "fsl,mpc8610-guts", },
48 { .compatible = "simple-bus", }, 85 { .compatible = "simple-bus", },
49 { .compatible = "gianfar", }, 86 { .compatible = "gianfar", },
50 {} 87 {}
@@ -55,6 +92,9 @@ static int __init mpc8610_declare_of_platform_devices(void)
55 /* Firstly, register PIXIS GPIOs. */ 92 /* Firstly, register PIXIS GPIOs. */
56 simple_gpiochip_init("fsl,fpga-pixis-gpio-bank"); 93 simple_gpiochip_init("fsl,fpga-pixis-gpio-bank");
57 94
95 /* Enable wakeup on PIXIS' event IRQ. */
96 mpc8610_suspend_init();
97
58 /* Without this call, the SSI device driver won't get probed. */ 98 /* Without this call, the SSI device driver won't get probed. */
59 of_platform_bus_probe(NULL, mpc8610_ids, NULL); 99 of_platform_bus_probe(NULL, mpc8610_ids, NULL);
60 100
@@ -250,10 +290,10 @@ static void __init mpc86xx_hpcd_setup_arch(void)
250 diu_ops.set_sysfs_monitor_port = mpc8610hpcd_set_sysfs_monitor_port; 290 diu_ops.set_sysfs_monitor_port = mpc8610hpcd_set_sysfs_monitor_port;
251#endif 291#endif
252 292
253 np = of_find_compatible_node(NULL, NULL, "fsl,fpga-pixis"); 293 pixis_node = of_find_compatible_node(NULL, NULL, "fsl,fpga-pixis");
254 if (np) { 294 if (pixis_node) {
255 of_address_to_resource(np, 0, &r); 295 of_address_to_resource(pixis_node, 0, &r);
256 of_node_put(np); 296 of_node_put(pixis_node);
257 pixis = ioremap(r.start, 32); 297 pixis = ioremap(r.start, 32);
258 if (!pixis) { 298 if (!pixis) {
259 printk(KERN_ERR "Err: can't map FPGA cfg register!\n"); 299 printk(KERN_ERR "Err: can't map FPGA cfg register!\n");
diff --git a/arch/powerpc/platforms/8xx/m8xx_setup.c b/arch/powerpc/platforms/8xx/m8xx_setup.c
index 385acfc48397..242954c4293f 100644
--- a/arch/powerpc/platforms/8xx/m8xx_setup.c
+++ b/arch/powerpc/platforms/8xx/m8xx_setup.c
@@ -222,7 +222,7 @@ static void cpm_cascade(unsigned int irq, struct irq_desc *desc)
222 int cascade_irq; 222 int cascade_irq;
223 223
224 if ((cascade_irq = cpm_get_irq()) >= 0) { 224 if ((cascade_irq = cpm_get_irq()) >= 0) {
225 struct irq_desc *cdesc = irq_desc + cascade_irq; 225 struct irq_desc *cdesc = irq_to_desc(cascade_irq);
226 226
227 generic_handle_irq(cascade_irq); 227 generic_handle_irq(cascade_irq);
228 cdesc->chip->eoi(cascade_irq); 228 cdesc->chip->eoi(cascade_irq);
diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig
index 04a8061045c4..d1663db7810f 100644
--- a/arch/powerpc/platforms/Kconfig
+++ b/arch/powerpc/platforms/Kconfig
@@ -86,6 +86,11 @@ config RTAS_ERROR_LOGGING
86 depends on PPC_RTAS 86 depends on PPC_RTAS
87 default n 87 default n
88 88
89config PPC_RTAS_DAEMON
90 bool
91 depends on PPC_RTAS
92 default n
93
89config RTAS_PROC 94config RTAS_PROC
90 bool "Proc interface to RTAS" 95 bool "Proc interface to RTAS"
91 depends on PPC_RTAS 96 depends on PPC_RTAS
@@ -255,7 +260,7 @@ config QE_GPIO
255 260
256config CPM2 261config CPM2
257 bool "Enable support for the CPM2 (Communications Processor Module)" 262 bool "Enable support for the CPM2 (Communications Processor Module)"
258 depends on MPC85xx || 8260 263 depends on (FSL_SOC_BOOKE && PPC32) || 8260
259 select CPM 264 select CPM
260 select PPC_LIB_RHEAP 265 select PPC_LIB_RHEAP
261 select PPC_PCI_CHOICE 266 select PPC_PCI_CHOICE
@@ -300,7 +305,7 @@ source "arch/powerpc/sysdev/bestcomm/Kconfig"
300 305
301config MPC8xxx_GPIO 306config MPC8xxx_GPIO
302 bool "MPC8xxx GPIO support" 307 bool "MPC8xxx GPIO support"
303 depends on PPC_MPC831x || PPC_MPC834x || PPC_MPC837x || PPC_85xx || PPC_86xx 308 depends on PPC_MPC831x || PPC_MPC834x || PPC_MPC837x || FSL_SOC_BOOKE || PPC_86xx
304 select GENERIC_GPIO 309 select GENERIC_GPIO
305 select ARCH_REQUIRE_GPIOLIB 310 select ARCH_REQUIRE_GPIOLIB
306 help 311 help
diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype
index e382cae678b8..fa0f690d3867 100644
--- a/arch/powerpc/platforms/Kconfig.cputype
+++ b/arch/powerpc/platforms/Kconfig.cputype
@@ -28,8 +28,6 @@ config PPC_BOOK3S_32
28config PPC_85xx 28config PPC_85xx
29 bool "Freescale 85xx" 29 bool "Freescale 85xx"
30 select E500 30 select E500
31 select FSL_SOC
32 select MPC85xx
33 31
34config PPC_8xx 32config PPC_8xx
35 bool "Freescale 8xx" 33 bool "Freescale 8xx"
@@ -138,6 +136,14 @@ config PPC_FPU
138 bool 136 bool
139 default y if PPC64 137 default y if PPC64
140 138
139config FSL_EMB_PERFMON
140 bool "Freescale Embedded Perfmon"
141 depends on E500 || PPC_83xx
142 help
143 This is the Performance Monitor support found on the e500 core
144 and some e300 cores (c3 and c4). Select this only if your
145 core supports the Embedded Performance Monitor APU
146
141config 4xx 147config 4xx
142 bool 148 bool
143 depends on 40x || 44x 149 depends on 40x || 44x
@@ -153,13 +159,6 @@ config FSL_BOOKE
153 depends on E200 || E500 159 depends on E200 || E500
154 default y 160 default y
155 161
156config FSL_EMB_PERFMON
157 bool "Freescale Embedded Perfmon"
158 depends on E500 || PPC_83xx
159 help
160 This is the Performance Monitor support found on the e500 core
161 and some e300 cores (c3 and c4). Select this only if your
162 core supports the Embedded Performance Monitor APU
163 162
164config PTE_64BIT 163config PTE_64BIT
165 bool 164 bool
@@ -312,7 +311,7 @@ config NR_CPUS
312 311
313config NOT_COHERENT_CACHE 312config NOT_COHERENT_CACHE
314 bool 313 bool
315 depends on 4xx || 8xx || E200 || PPC_MPC512x 314 depends on 4xx || 8xx || E200 || PPC_MPC512x || GAMECUBE_COMMON
316 default y 315 default y
317 316
318config CHECK_CACHE_COHERENCY 317config CHECK_CACHE_COHERENCY
diff --git a/arch/powerpc/platforms/Makefile b/arch/powerpc/platforms/Makefile
index a6812ee00100..fdb9f0b0d7a8 100644
--- a/arch/powerpc/platforms/Makefile
+++ b/arch/powerpc/platforms/Makefile
@@ -12,7 +12,7 @@ obj-$(CONFIG_PPC_MPC52xx) += 52xx/
12obj-$(CONFIG_PPC_8xx) += 8xx/ 12obj-$(CONFIG_PPC_8xx) += 8xx/
13obj-$(CONFIG_PPC_82xx) += 82xx/ 13obj-$(CONFIG_PPC_82xx) += 82xx/
14obj-$(CONFIG_PPC_83xx) += 83xx/ 14obj-$(CONFIG_PPC_83xx) += 83xx/
15obj-$(CONFIG_PPC_85xx) += 85xx/ 15obj-$(CONFIG_FSL_SOC_BOOKE) += 85xx/
16obj-$(CONFIG_PPC_86xx) += 86xx/ 16obj-$(CONFIG_PPC_86xx) += 86xx/
17obj-$(CONFIG_PPC_PSERIES) += pseries/ 17obj-$(CONFIG_PPC_PSERIES) += pseries/
18obj-$(CONFIG_PPC_ISERIES) += iseries/ 18obj-$(CONFIG_PPC_ISERIES) += iseries/
diff --git a/arch/powerpc/platforms/amigaone/setup.c b/arch/powerpc/platforms/amigaone/setup.c
index 9290a7a442d0..fb4eb0df054c 100644
--- a/arch/powerpc/platforms/amigaone/setup.c
+++ b/arch/powerpc/platforms/amigaone/setup.c
@@ -14,7 +14,7 @@
14 14
15#include <linux/kernel.h> 15#include <linux/kernel.h>
16#include <linux/seq_file.h> 16#include <linux/seq_file.h>
17#include <linux/utsrelease.h> 17#include <generated/utsrelease.h>
18 18
19#include <asm/machdep.h> 19#include <asm/machdep.h>
20#include <asm/cputable.h> 20#include <asm/cputable.h>
diff --git a/arch/powerpc/platforms/cell/axon_msi.c b/arch/powerpc/platforms/cell/axon_msi.c
index a86c34b3bb84..96fe896f6df3 100644
--- a/arch/powerpc/platforms/cell/axon_msi.c
+++ b/arch/powerpc/platforms/cell/axon_msi.c
@@ -312,7 +312,7 @@ static struct irq_chip msic_irq_chip = {
312 .mask = mask_msi_irq, 312 .mask = mask_msi_irq,
313 .unmask = unmask_msi_irq, 313 .unmask = unmask_msi_irq,
314 .shutdown = unmask_msi_irq, 314 .shutdown = unmask_msi_irq,
315 .typename = "AXON-MSI", 315 .name = "AXON-MSI",
316}; 316};
317 317
318static int msic_host_map(struct irq_host *h, unsigned int virq, 318static int msic_host_map(struct irq_host *h, unsigned int virq,
diff --git a/arch/powerpc/platforms/cell/beat_interrupt.c b/arch/powerpc/platforms/cell/beat_interrupt.c
index 72254848a228..36052a9ebcda 100644
--- a/arch/powerpc/platforms/cell/beat_interrupt.c
+++ b/arch/powerpc/platforms/cell/beat_interrupt.c
@@ -110,7 +110,7 @@ static void beatic_end_irq(unsigned int irq_plug)
110} 110}
111 111
112static struct irq_chip beatic_pic = { 112static struct irq_chip beatic_pic = {
113 .typename = " CELL-BEAT ", 113 .name = " CELL-BEAT ",
114 .unmask = beatic_unmask_irq, 114 .unmask = beatic_unmask_irq,
115 .mask = beatic_mask_irq, 115 .mask = beatic_mask_irq,
116 .eoi = beatic_end_irq, 116 .eoi = beatic_end_irq,
@@ -136,7 +136,7 @@ static void beatic_pic_host_unmap(struct irq_host *h, unsigned int virq)
136static int beatic_pic_host_map(struct irq_host *h, unsigned int virq, 136static int beatic_pic_host_map(struct irq_host *h, unsigned int virq,
137 irq_hw_number_t hw) 137 irq_hw_number_t hw)
138{ 138{
139 struct irq_desc *desc = get_irq_desc(virq); 139 struct irq_desc *desc = irq_to_desc(virq);
140 int64_t err; 140 int64_t err;
141 141
142 err = beat_construct_and_connect_irq_plug(virq, hw); 142 err = beat_construct_and_connect_irq_plug(virq, hw);
@@ -166,11 +166,11 @@ static void beatic_pic_host_remap(struct irq_host *h, unsigned int virq,
166 * Note: We have only 1 entry to translate. 166 * Note: We have only 1 entry to translate.
167 */ 167 */
168static int beatic_pic_host_xlate(struct irq_host *h, struct device_node *ct, 168static int beatic_pic_host_xlate(struct irq_host *h, struct device_node *ct,
169 u32 *intspec, unsigned int intsize, 169 const u32 *intspec, unsigned int intsize,
170 irq_hw_number_t *out_hwirq, 170 irq_hw_number_t *out_hwirq,
171 unsigned int *out_flags) 171 unsigned int *out_flags)
172{ 172{
173 u64 *intspec2 = (u64 *)intspec; 173 const u64 *intspec2 = (const u64 *)intspec;
174 174
175 *out_hwirq = *intspec2; 175 *out_hwirq = *intspec2;
176 *out_flags |= IRQ_TYPE_LEVEL_LOW; 176 *out_flags |= IRQ_TYPE_LEVEL_LOW;
diff --git a/arch/powerpc/platforms/cell/interrupt.c b/arch/powerpc/platforms/cell/interrupt.c
index 882e47080e74..6829cf7e2bda 100644
--- a/arch/powerpc/platforms/cell/interrupt.c
+++ b/arch/powerpc/platforms/cell/interrupt.c
@@ -54,7 +54,7 @@ struct iic {
54 struct device_node *node; 54 struct device_node *node;
55}; 55};
56 56
57static DEFINE_PER_CPU(struct iic, iic); 57static DEFINE_PER_CPU(struct iic, cpu_iic);
58#define IIC_NODE_COUNT 2 58#define IIC_NODE_COUNT 2
59static struct irq_host *iic_host; 59static struct irq_host *iic_host;
60 60
@@ -82,13 +82,13 @@ static void iic_unmask(unsigned int irq)
82 82
83static void iic_eoi(unsigned int irq) 83static void iic_eoi(unsigned int irq)
84{ 84{
85 struct iic *iic = &__get_cpu_var(iic); 85 struct iic *iic = &__get_cpu_var(cpu_iic);
86 out_be64(&iic->regs->prio, iic->eoi_stack[--iic->eoi_ptr]); 86 out_be64(&iic->regs->prio, iic->eoi_stack[--iic->eoi_ptr]);
87 BUG_ON(iic->eoi_ptr < 0); 87 BUG_ON(iic->eoi_ptr < 0);
88} 88}
89 89
90static struct irq_chip iic_chip = { 90static struct irq_chip iic_chip = {
91 .typename = " CELL-IIC ", 91 .name = " CELL-IIC ",
92 .mask = iic_mask, 92 .mask = iic_mask,
93 .unmask = iic_unmask, 93 .unmask = iic_unmask,
94 .eoi = iic_eoi, 94 .eoi = iic_eoi,
@@ -133,7 +133,7 @@ static void iic_ioexc_cascade(unsigned int irq, struct irq_desc *desc)
133 133
134 134
135static struct irq_chip iic_ioexc_chip = { 135static struct irq_chip iic_ioexc_chip = {
136 .typename = " CELL-IOEX", 136 .name = " CELL-IOEX",
137 .mask = iic_mask, 137 .mask = iic_mask,
138 .unmask = iic_unmask, 138 .unmask = iic_unmask,
139 .eoi = iic_ioexc_eoi, 139 .eoi = iic_ioexc_eoi,
@@ -146,7 +146,7 @@ static unsigned int iic_get_irq(void)
146 struct iic *iic; 146 struct iic *iic;
147 unsigned int virq; 147 unsigned int virq;
148 148
149 iic = &__get_cpu_var(iic); 149 iic = &__get_cpu_var(cpu_iic);
150 *(unsigned long *) &pending = 150 *(unsigned long *) &pending =
151 in_be64((u64 __iomem *) &iic->regs->pending_destr); 151 in_be64((u64 __iomem *) &iic->regs->pending_destr);
152 if (!(pending.flags & CBE_IIC_IRQ_VALID)) 152 if (!(pending.flags & CBE_IIC_IRQ_VALID))
@@ -161,12 +161,12 @@ static unsigned int iic_get_irq(void)
161 161
162void iic_setup_cpu(void) 162void iic_setup_cpu(void)
163{ 163{
164 out_be64(&__get_cpu_var(iic).regs->prio, 0xff); 164 out_be64(&__get_cpu_var(cpu_iic).regs->prio, 0xff);
165} 165}
166 166
167u8 iic_get_target_id(int cpu) 167u8 iic_get_target_id(int cpu)
168{ 168{
169 return per_cpu(iic, cpu).target_id; 169 return per_cpu(cpu_iic, cpu).target_id;
170} 170}
171 171
172EXPORT_SYMBOL_GPL(iic_get_target_id); 172EXPORT_SYMBOL_GPL(iic_get_target_id);
@@ -181,7 +181,7 @@ static inline int iic_ipi_to_irq(int ipi)
181 181
182void iic_cause_IPI(int cpu, int mesg) 182void iic_cause_IPI(int cpu, int mesg)
183{ 183{
184 out_be64(&per_cpu(iic, cpu).regs->generate, (0xf - mesg) << 4); 184 out_be64(&per_cpu(cpu_iic, cpu).regs->generate, (0xf - mesg) << 4);
185} 185}
186 186
187struct irq_host *iic_get_irq_host(int node) 187struct irq_host *iic_get_irq_host(int node)
@@ -237,7 +237,7 @@ extern int noirqdebug;
237 237
238static void handle_iic_irq(unsigned int irq, struct irq_desc *desc) 238static void handle_iic_irq(unsigned int irq, struct irq_desc *desc)
239{ 239{
240 spin_lock(&desc->lock); 240 raw_spin_lock(&desc->lock);
241 241
242 desc->status &= ~(IRQ_REPLAY | IRQ_WAITING); 242 desc->status &= ~(IRQ_REPLAY | IRQ_WAITING);
243 243
@@ -265,18 +265,18 @@ static void handle_iic_irq(unsigned int irq, struct irq_desc *desc)
265 goto out_eoi; 265 goto out_eoi;
266 266
267 desc->status &= ~IRQ_PENDING; 267 desc->status &= ~IRQ_PENDING;
268 spin_unlock(&desc->lock); 268 raw_spin_unlock(&desc->lock);
269 action_ret = handle_IRQ_event(irq, action); 269 action_ret = handle_IRQ_event(irq, action);
270 if (!noirqdebug) 270 if (!noirqdebug)
271 note_interrupt(irq, desc, action_ret); 271 note_interrupt(irq, desc, action_ret);
272 spin_lock(&desc->lock); 272 raw_spin_lock(&desc->lock);
273 273
274 } while ((desc->status & (IRQ_PENDING | IRQ_DISABLED)) == IRQ_PENDING); 274 } while ((desc->status & (IRQ_PENDING | IRQ_DISABLED)) == IRQ_PENDING);
275 275
276 desc->status &= ~IRQ_INPROGRESS; 276 desc->status &= ~IRQ_INPROGRESS;
277out_eoi: 277out_eoi:
278 desc->chip->eoi(irq); 278 desc->chip->eoi(irq);
279 spin_unlock(&desc->lock); 279 raw_spin_unlock(&desc->lock);
280} 280}
281 281
282static int iic_host_map(struct irq_host *h, unsigned int virq, 282static int iic_host_map(struct irq_host *h, unsigned int virq,
@@ -297,7 +297,7 @@ static int iic_host_map(struct irq_host *h, unsigned int virq,
297} 297}
298 298
299static int iic_host_xlate(struct irq_host *h, struct device_node *ct, 299static int iic_host_xlate(struct irq_host *h, struct device_node *ct,
300 u32 *intspec, unsigned int intsize, 300 const u32 *intspec, unsigned int intsize,
301 irq_hw_number_t *out_hwirq, unsigned int *out_flags) 301 irq_hw_number_t *out_hwirq, unsigned int *out_flags)
302 302
303{ 303{
@@ -348,7 +348,7 @@ static void __init init_one_iic(unsigned int hw_cpu, unsigned long addr,
348 /* XXX FIXME: should locate the linux CPU number from the HW cpu 348 /* XXX FIXME: should locate the linux CPU number from the HW cpu
349 * number properly. We are lucky for now 349 * number properly. We are lucky for now
350 */ 350 */
351 struct iic *iic = &per_cpu(iic, hw_cpu); 351 struct iic *iic = &per_cpu(cpu_iic, hw_cpu);
352 352
353 iic->regs = ioremap(addr, sizeof(struct cbe_iic_thread_regs)); 353 iic->regs = ioremap(addr, sizeof(struct cbe_iic_thread_regs));
354 BUG_ON(iic->regs == NULL); 354 BUG_ON(iic->regs == NULL);
diff --git a/arch/powerpc/platforms/cell/spider-pic.c b/arch/powerpc/platforms/cell/spider-pic.c
index 4e5655624ae8..01244f254a11 100644
--- a/arch/powerpc/platforms/cell/spider-pic.c
+++ b/arch/powerpc/platforms/cell/spider-pic.c
@@ -102,7 +102,7 @@ static void spider_ack_irq(unsigned int virq)
102 102
103 /* Reset edge detection logic if necessary 103 /* Reset edge detection logic if necessary
104 */ 104 */
105 if (get_irq_desc(virq)->status & IRQ_LEVEL) 105 if (irq_to_desc(virq)->status & IRQ_LEVEL)
106 return; 106 return;
107 107
108 /* Only interrupts 47 to 50 can be set to edge */ 108 /* Only interrupts 47 to 50 can be set to edge */
@@ -119,7 +119,7 @@ static int spider_set_irq_type(unsigned int virq, unsigned int type)
119 struct spider_pic *pic = spider_virq_to_pic(virq); 119 struct spider_pic *pic = spider_virq_to_pic(virq);
120 unsigned int hw = irq_map[virq].hwirq; 120 unsigned int hw = irq_map[virq].hwirq;
121 void __iomem *cfg = spider_get_irq_config(pic, hw); 121 void __iomem *cfg = spider_get_irq_config(pic, hw);
122 struct irq_desc *desc = get_irq_desc(virq); 122 struct irq_desc *desc = irq_to_desc(virq);
123 u32 old_mask; 123 u32 old_mask;
124 u32 ic; 124 u32 ic;
125 125
@@ -168,7 +168,7 @@ static int spider_set_irq_type(unsigned int virq, unsigned int type)
168} 168}
169 169
170static struct irq_chip spider_pic = { 170static struct irq_chip spider_pic = {
171 .typename = " SPIDER ", 171 .name = " SPIDER ",
172 .unmask = spider_unmask_irq, 172 .unmask = spider_unmask_irq,
173 .mask = spider_mask_irq, 173 .mask = spider_mask_irq,
174 .ack = spider_ack_irq, 174 .ack = spider_ack_irq,
@@ -187,7 +187,7 @@ static int spider_host_map(struct irq_host *h, unsigned int virq,
187} 187}
188 188
189static int spider_host_xlate(struct irq_host *h, struct device_node *ct, 189static int spider_host_xlate(struct irq_host *h, struct device_node *ct,
190 u32 *intspec, unsigned int intsize, 190 const u32 *intspec, unsigned int intsize,
191 irq_hw_number_t *out_hwirq, unsigned int *out_flags) 191 irq_hw_number_t *out_hwirq, unsigned int *out_flags)
192 192
193{ 193{
diff --git a/arch/powerpc/platforms/cell/spufs/Makefile b/arch/powerpc/platforms/cell/spufs/Makefile
index b93f877ba504..b9d5d678aa44 100644
--- a/arch/powerpc/platforms/cell/spufs/Makefile
+++ b/arch/powerpc/platforms/cell/spufs/Makefile
@@ -13,10 +13,8 @@ SPU_CC := $(SPU_CROSS)gcc
13SPU_AS := $(SPU_CROSS)gcc 13SPU_AS := $(SPU_CROSS)gcc
14SPU_LD := $(SPU_CROSS)ld 14SPU_LD := $(SPU_CROSS)ld
15SPU_OBJCOPY := $(SPU_CROSS)objcopy 15SPU_OBJCOPY := $(SPU_CROSS)objcopy
16SPU_CFLAGS := -O2 -Wall -I$(srctree)/include \ 16SPU_CFLAGS := -O2 -Wall -I$(srctree)/include -D__KERNEL__
17 -I$(objtree)/include2 -D__KERNEL__ 17SPU_AFLAGS := -c -D__ASSEMBLY__ -I$(srctree)/include -D__KERNEL__
18SPU_AFLAGS := -c -D__ASSEMBLY__ -I$(srctree)/include \
19 -I$(objtree)/include2 -D__KERNEL__
20SPU_LDFLAGS := -N -Ttext=0x0 18SPU_LDFLAGS := -N -Ttext=0x0
21 19
22$(obj)/switch.o: $(obj)/spu_save_dump.h $(obj)/spu_restore_dump.h 20$(obj)/switch.o: $(obj)/spu_save_dump.h $(obj)/spu_restore_dump.h
diff --git a/arch/powerpc/platforms/cell/spufs/coredump.c b/arch/powerpc/platforms/cell/spufs/coredump.c
index c4d4a19235e0..eea120229cdb 100644
--- a/arch/powerpc/platforms/cell/spufs/coredump.c
+++ b/arch/powerpc/platforms/cell/spufs/coredump.c
@@ -54,7 +54,7 @@ static ssize_t do_coredump_read(int num, struct spu_context *ctx, void *buffer,
54 */ 54 */
55static int spufs_dump_write(struct file *file, const void *addr, int nr, loff_t *foffset) 55static int spufs_dump_write(struct file *file, const void *addr, int nr, loff_t *foffset)
56{ 56{
57 unsigned long limit = current->signal->rlim[RLIMIT_CORE].rlim_cur; 57 unsigned long limit = rlimit(RLIMIT_CORE);
58 ssize_t written; 58 ssize_t written;
59 59
60 if (*foffset + nr > limit) 60 if (*foffset + nr > limit)
diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c
index 884e8bcec499..64a4c2d85f7c 100644
--- a/arch/powerpc/platforms/cell/spufs/file.c
+++ b/arch/powerpc/platforms/cell/spufs/file.c
@@ -2494,7 +2494,7 @@ static ssize_t spufs_switch_log_read(struct file *file, char __user *buf,
2494 struct spu_context *ctx = SPUFS_I(inode)->i_ctx; 2494 struct spu_context *ctx = SPUFS_I(inode)->i_ctx;
2495 int error = 0, cnt = 0; 2495 int error = 0, cnt = 0;
2496 2496
2497 if (!buf || len < 0) 2497 if (!buf)
2498 return -EINVAL; 2498 return -EINVAL;
2499 2499
2500 error = spu_acquire(ctx); 2500 error = spu_acquire(ctx);
diff --git a/arch/powerpc/platforms/chrp/Kconfig b/arch/powerpc/platforms/chrp/Kconfig
index 37d438bd5b7a..bc0b0efdc5fe 100644
--- a/arch/powerpc/platforms/chrp/Kconfig
+++ b/arch/powerpc/platforms/chrp/Kconfig
@@ -5,6 +5,8 @@ config PPC_CHRP
5 select PPC_I8259 5 select PPC_I8259
6 select PPC_INDIRECT_PCI 6 select PPC_INDIRECT_PCI
7 select PPC_RTAS 7 select PPC_RTAS
8 select PPC_RTAS_DAEMON
9 select RTAS_ERROR_LOGGING
8 select PPC_MPC106 10 select PPC_MPC106
9 select PPC_UDBG_16550 11 select PPC_UDBG_16550
10 select PPC_NATIVE 12 select PPC_NATIVE
diff --git a/arch/powerpc/platforms/chrp/setup.c b/arch/powerpc/platforms/chrp/setup.c
index cd4ad9aea760..8f41685d8f42 100644
--- a/arch/powerpc/platforms/chrp/setup.c
+++ b/arch/powerpc/platforms/chrp/setup.c
@@ -23,7 +23,7 @@
23#include <linux/reboot.h> 23#include <linux/reboot.h>
24#include <linux/init.h> 24#include <linux/init.h>
25#include <linux/pci.h> 25#include <linux/pci.h>
26#include <linux/utsrelease.h> 26#include <generated/utsrelease.h>
27#include <linux/adb.h> 27#include <linux/adb.h>
28#include <linux/module.h> 28#include <linux/module.h>
29#include <linux/delay.h> 29#include <linux/delay.h>
@@ -364,19 +364,6 @@ void __init chrp_setup_arch(void)
364 if (ppc_md.progress) ppc_md.progress("Linux/PPC "UTS_RELEASE"\n", 0x0); 364 if (ppc_md.progress) ppc_md.progress("Linux/PPC "UTS_RELEASE"\n", 0x0);
365} 365}
366 366
367void
368chrp_event_scan(unsigned long unused)
369{
370 unsigned char log[1024];
371 int ret = 0;
372
373 /* XXX: we should loop until the hardware says no more error logs -- Cort */
374 rtas_call(rtas_token("event-scan"), 4, 1, &ret, 0xffffffff, 0,
375 __pa(log), 1024);
376 mod_timer(&__get_cpu_var(heartbeat_timer),
377 jiffies + event_scan_interval);
378}
379
380static void chrp_8259_cascade(unsigned int irq, struct irq_desc *desc) 367static void chrp_8259_cascade(unsigned int irq, struct irq_desc *desc)
381{ 368{
382 unsigned int cascade_irq = i8259_irq(); 369 unsigned int cascade_irq = i8259_irq();
@@ -568,9 +555,6 @@ void __init chrp_init_IRQ(void)
568void __init 555void __init
569chrp_init2(void) 556chrp_init2(void)
570{ 557{
571 struct device_node *device;
572 const unsigned int *p = NULL;
573
574#ifdef CONFIG_NVRAM 558#ifdef CONFIG_NVRAM
575 chrp_nvram_init(); 559 chrp_nvram_init();
576#endif 560#endif
@@ -582,40 +566,6 @@ chrp_init2(void)
582 request_region(0x80,0x10,"dma page reg"); 566 request_region(0x80,0x10,"dma page reg");
583 request_region(0xc0,0x20,"dma2"); 567 request_region(0xc0,0x20,"dma2");
584 568
585 /* Get the event scan rate for the rtas so we know how
586 * often it expects a heartbeat. -- Cort
587 */
588 device = of_find_node_by_name(NULL, "rtas");
589 if (device)
590 p = of_get_property(device, "rtas-event-scan-rate", NULL);
591 if (p && *p) {
592 /*
593 * Arrange to call chrp_event_scan at least *p times
594 * per minute. We use 59 rather than 60 here so that
595 * the rate will be slightly higher than the minimum.
596 * This all assumes we don't do hotplug CPU on any
597 * machine that needs the event scans done.
598 */
599 unsigned long interval, offset;
600 int cpu, ncpus;
601 struct timer_list *timer;
602
603 interval = HZ * 59 / *p;
604 offset = HZ;
605 ncpus = num_online_cpus();
606 event_scan_interval = ncpus * interval;
607 for (cpu = 0; cpu < ncpus; ++cpu) {
608 timer = &per_cpu(heartbeat_timer, cpu);
609 setup_timer(timer, chrp_event_scan, 0);
610 timer->expires = jiffies + offset;
611 add_timer_on(timer, cpu);
612 offset += interval;
613 }
614 printk("RTAS Event Scan Rate: %u (%lu jiffies)\n",
615 *p, interval);
616 }
617 of_node_put(device);
618
619 if (ppc_md.progress) 569 if (ppc_md.progress)
620 ppc_md.progress(" Have fun! ", 0x7777); 570 ppc_md.progress(" Have fun! ", 0x7777);
621} 571}
diff --git a/arch/powerpc/platforms/embedded6xx/Kconfig b/arch/powerpc/platforms/embedded6xx/Kconfig
index 291ac9d8cbee..524d971a1478 100644
--- a/arch/powerpc/platforms/embedded6xx/Kconfig
+++ b/arch/powerpc/platforms/embedded6xx/Kconfig
@@ -90,3 +90,36 @@ config MPC10X_OPENPIC
90config MPC10X_STORE_GATHERING 90config MPC10X_STORE_GATHERING
91 bool "Enable MPC10x store gathering" 91 bool "Enable MPC10x store gathering"
92 depends on MPC10X_BRIDGE 92 depends on MPC10X_BRIDGE
93
94config GAMECUBE_COMMON
95 bool
96
97config USBGECKO_UDBG
98 bool "USB Gecko udbg console for the Nintendo GameCube/Wii"
99 depends on GAMECUBE_COMMON
100 help
101 If you say yes to this option, support will be included for the
102 USB Gecko adapter as an udbg console.
103 The USB Gecko is a EXI to USB Serial converter that can be plugged
104 into a memcard slot in the Nintendo GameCube/Wii.
105
106 This driver bypasses the EXI layer completely.
107
108 If in doubt, say N here.
109
110config GAMECUBE
111 bool "Nintendo-GameCube"
112 depends on EMBEDDED6xx
113 select GAMECUBE_COMMON
114 help
115 Select GAMECUBE if configuring for the Nintendo GameCube.
116 More information at: <http://gc-linux.sourceforge.net/>
117
118config WII
119 bool "Nintendo-Wii"
120 depends on EMBEDDED6xx
121 select GAMECUBE_COMMON
122 help
123 Select WII if configuring for the Nintendo Wii.
124 More information at: <http://gc-linux.sourceforge.net/>
125
diff --git a/arch/powerpc/platforms/embedded6xx/Makefile b/arch/powerpc/platforms/embedded6xx/Makefile
index 0773c08bd444..66c23e423f40 100644
--- a/arch/powerpc/platforms/embedded6xx/Makefile
+++ b/arch/powerpc/platforms/embedded6xx/Makefile
@@ -7,3 +7,7 @@ obj-$(CONFIG_STORCENTER) += storcenter.o
7obj-$(CONFIG_PPC_HOLLY) += holly.o 7obj-$(CONFIG_PPC_HOLLY) += holly.o
8obj-$(CONFIG_PPC_PRPMC2800) += prpmc2800.o 8obj-$(CONFIG_PPC_PRPMC2800) += prpmc2800.o
9obj-$(CONFIG_PPC_C2K) += c2k.o 9obj-$(CONFIG_PPC_C2K) += c2k.o
10obj-$(CONFIG_USBGECKO_UDBG) += usbgecko_udbg.o
11obj-$(CONFIG_GAMECUBE_COMMON) += flipper-pic.o
12obj-$(CONFIG_GAMECUBE) += gamecube.o
13obj-$(CONFIG_WII) += wii.o hlwd-pic.o
diff --git a/arch/powerpc/platforms/embedded6xx/flipper-pic.c b/arch/powerpc/platforms/embedded6xx/flipper-pic.c
new file mode 100644
index 000000000000..c278bd3a8fec
--- /dev/null
+++ b/arch/powerpc/platforms/embedded6xx/flipper-pic.c
@@ -0,0 +1,263 @@
1/*
2 * arch/powerpc/platforms/embedded6xx/flipper-pic.c
3 *
4 * Nintendo GameCube/Wii "Flipper" interrupt controller support.
5 * Copyright (C) 2004-2009 The GameCube Linux Team
6 * Copyright (C) 2007,2008,2009 Albert Herranz
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 */
14#define DRV_MODULE_NAME "flipper-pic"
15#define pr_fmt(fmt) DRV_MODULE_NAME ": " fmt
16
17#include <linux/kernel.h>
18#include <linux/init.h>
19#include <linux/irq.h>
20#include <linux/of.h>
21#include <asm/io.h>
22
23#include "flipper-pic.h"
24
25#define FLIPPER_NR_IRQS 32
26
27/*
28 * Each interrupt has a corresponding bit in both
29 * the Interrupt Cause (ICR) and Interrupt Mask (IMR) registers.
30 *
31 * Enabling/disabling an interrupt line involves setting/clearing
32 * the corresponding bit in IMR.
33 * Except for the RSW interrupt, all interrupts get deasserted automatically
34 * when the source deasserts the interrupt.
35 */
36#define FLIPPER_ICR 0x00
37#define FLIPPER_ICR_RSS (1<<16) /* reset switch state */
38
39#define FLIPPER_IMR 0x04
40
41#define FLIPPER_RESET 0x24
42
43
44/*
45 * IRQ chip hooks.
46 *
47 */
48
49static void flipper_pic_mask_and_ack(unsigned int virq)
50{
51 int irq = virq_to_hw(virq);
52 void __iomem *io_base = get_irq_chip_data(virq);
53 u32 mask = 1 << irq;
54
55 clrbits32(io_base + FLIPPER_IMR, mask);
56 /* this is at least needed for RSW */
57 out_be32(io_base + FLIPPER_ICR, mask);
58}
59
60static void flipper_pic_ack(unsigned int virq)
61{
62 int irq = virq_to_hw(virq);
63 void __iomem *io_base = get_irq_chip_data(virq);
64
65 /* this is at least needed for RSW */
66 out_be32(io_base + FLIPPER_ICR, 1 << irq);
67}
68
69static void flipper_pic_mask(unsigned int virq)
70{
71 int irq = virq_to_hw(virq);
72 void __iomem *io_base = get_irq_chip_data(virq);
73
74 clrbits32(io_base + FLIPPER_IMR, 1 << irq);
75}
76
77static void flipper_pic_unmask(unsigned int virq)
78{
79 int irq = virq_to_hw(virq);
80 void __iomem *io_base = get_irq_chip_data(virq);
81
82 setbits32(io_base + FLIPPER_IMR, 1 << irq);
83}
84
85
86static struct irq_chip flipper_pic = {
87 .name = "flipper-pic",
88 .ack = flipper_pic_ack,
89 .mask_ack = flipper_pic_mask_and_ack,
90 .mask = flipper_pic_mask,
91 .unmask = flipper_pic_unmask,
92};
93
94/*
95 * IRQ host hooks.
96 *
97 */
98
99static struct irq_host *flipper_irq_host;
100
101static int flipper_pic_map(struct irq_host *h, unsigned int virq,
102 irq_hw_number_t hwirq)
103{
104 set_irq_chip_data(virq, h->host_data);
105 irq_to_desc(virq)->status |= IRQ_LEVEL;
106 set_irq_chip_and_handler(virq, &flipper_pic, handle_level_irq);
107 return 0;
108}
109
110static void flipper_pic_unmap(struct irq_host *h, unsigned int irq)
111{
112 set_irq_chip_data(irq, NULL);
113 set_irq_chip(irq, NULL);
114}
115
116static int flipper_pic_match(struct irq_host *h, struct device_node *np)
117{
118 return 1;
119}
120
121
122static struct irq_host_ops flipper_irq_host_ops = {
123 .map = flipper_pic_map,
124 .unmap = flipper_pic_unmap,
125 .match = flipper_pic_match,
126};
127
128/*
129 * Platform hooks.
130 *
131 */
132
133static void __flipper_quiesce(void __iomem *io_base)
134{
135 /* mask and ack all IRQs */
136 out_be32(io_base + FLIPPER_IMR, 0x00000000);
137 out_be32(io_base + FLIPPER_ICR, 0xffffffff);
138}
139
140struct irq_host * __init flipper_pic_init(struct device_node *np)
141{
142 struct device_node *pi;
143 struct irq_host *irq_host = NULL;
144 struct resource res;
145 void __iomem *io_base;
146 int retval;
147
148 pi = of_get_parent(np);
149 if (!pi) {
150 pr_err("no parent found\n");
151 goto out;
152 }
153 if (!of_device_is_compatible(pi, "nintendo,flipper-pi")) {
154 pr_err("unexpected parent compatible\n");
155 goto out;
156 }
157
158 retval = of_address_to_resource(pi, 0, &res);
159 if (retval) {
160 pr_err("no io memory range found\n");
161 goto out;
162 }
163 io_base = ioremap(res.start, resource_size(&res));
164
165 pr_info("controller at 0x%08x mapped to 0x%p\n", res.start, io_base);
166
167 __flipper_quiesce(io_base);
168
169 irq_host = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR, FLIPPER_NR_IRQS,
170 &flipper_irq_host_ops, -1);
171 if (!irq_host) {
172 pr_err("failed to allocate irq_host\n");
173 return NULL;
174 }
175
176 irq_host->host_data = io_base;
177
178out:
179 return irq_host;
180}
181
182unsigned int flipper_pic_get_irq(void)
183{
184 void __iomem *io_base = flipper_irq_host->host_data;
185 int irq;
186 u32 irq_status;
187
188 irq_status = in_be32(io_base + FLIPPER_ICR) &
189 in_be32(io_base + FLIPPER_IMR);
190 if (irq_status == 0)
191 return NO_IRQ; /* no more IRQs pending */
192
193 irq = __ffs(irq_status);
194 return irq_linear_revmap(flipper_irq_host, irq);
195}
196
197/*
198 * Probe function.
199 *
200 */
201
202void __init flipper_pic_probe(void)
203{
204 struct device_node *np;
205
206 np = of_find_compatible_node(NULL, NULL, "nintendo,flipper-pic");
207 BUG_ON(!np);
208
209 flipper_irq_host = flipper_pic_init(np);
210 BUG_ON(!flipper_irq_host);
211
212 irq_set_default_host(flipper_irq_host);
213
214 of_node_put(np);
215}
216
217/*
218 * Misc functions related to the flipper chipset.
219 *
220 */
221
222/**
223 * flipper_quiesce() - quiesce flipper irq controller
224 *
225 * Mask and ack all interrupt sources.
226 *
227 */
228void flipper_quiesce(void)
229{
230 void __iomem *io_base = flipper_irq_host->host_data;
231
232 __flipper_quiesce(io_base);
233}
234
235/*
236 * Resets the platform.
237 */
238void flipper_platform_reset(void)
239{
240 void __iomem *io_base;
241
242 if (flipper_irq_host && flipper_irq_host->host_data) {
243 io_base = flipper_irq_host->host_data;
244 out_8(io_base + FLIPPER_RESET, 0x00);
245 }
246}
247
248/*
249 * Returns non-zero if the reset button is pressed.
250 */
251int flipper_is_reset_button_pressed(void)
252{
253 void __iomem *io_base;
254 u32 icr;
255
256 if (flipper_irq_host && flipper_irq_host->host_data) {
257 io_base = flipper_irq_host->host_data;
258 icr = in_be32(io_base + FLIPPER_ICR);
259 return !(icr & FLIPPER_ICR_RSS);
260 }
261 return 0;
262}
263
diff --git a/arch/powerpc/platforms/embedded6xx/flipper-pic.h b/arch/powerpc/platforms/embedded6xx/flipper-pic.h
new file mode 100644
index 000000000000..e339186b5663
--- /dev/null
+++ b/arch/powerpc/platforms/embedded6xx/flipper-pic.h
@@ -0,0 +1,25 @@
1/*
2 * arch/powerpc/platforms/embedded6xx/flipper-pic.h
3 *
4 * Nintendo GameCube/Wii "Flipper" interrupt controller support.
5 * Copyright (C) 2004-2009 The GameCube Linux Team
6 * Copyright (C) 2007,2008,2009 Albert Herranz
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 */
14
15#ifndef __FLIPPER_PIC_H
16#define __FLIPPER_PIC_H
17
18unsigned int flipper_pic_get_irq(void);
19void __init flipper_pic_probe(void);
20
21void flipper_quiesce(void);
22void flipper_platform_reset(void);
23int flipper_is_reset_button_pressed(void);
24
25#endif
diff --git a/arch/powerpc/platforms/embedded6xx/gamecube.c b/arch/powerpc/platforms/embedded6xx/gamecube.c
new file mode 100644
index 000000000000..1106fd99627f
--- /dev/null
+++ b/arch/powerpc/platforms/embedded6xx/gamecube.c
@@ -0,0 +1,118 @@
1/*
2 * arch/powerpc/platforms/embedded6xx/gamecube.c
3 *
4 * Nintendo GameCube board-specific support
5 * Copyright (C) 2004-2009 The GameCube Linux Team
6 * Copyright (C) 2007,2008,2009 Albert Herranz
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 */
14
15#include <linux/kernel.h>
16#include <linux/init.h>
17#include <linux/irq.h>
18#include <linux/kexec.h>
19#include <linux/seq_file.h>
20#include <linux/of_platform.h>
21
22#include <asm/io.h>
23#include <asm/machdep.h>
24#include <asm/prom.h>
25#include <asm/time.h>
26#include <asm/udbg.h>
27
28#include "flipper-pic.h"
29#include "usbgecko_udbg.h"
30
31
32static void gamecube_spin(void)
33{
34 /* spin until power button pressed */
35 for (;;)
36 cpu_relax();
37}
38
39static void gamecube_restart(char *cmd)
40{
41 local_irq_disable();
42 flipper_platform_reset();
43 gamecube_spin();
44}
45
46static void gamecube_power_off(void)
47{
48 local_irq_disable();
49 gamecube_spin();
50}
51
52static void gamecube_halt(void)
53{
54 gamecube_restart(NULL);
55}
56
57static void __init gamecube_init_early(void)
58{
59 ug_udbg_init();
60}
61
62static int __init gamecube_probe(void)
63{
64 unsigned long dt_root;
65
66 dt_root = of_get_flat_dt_root();
67 if (!of_flat_dt_is_compatible(dt_root, "nintendo,gamecube"))
68 return 0;
69
70 return 1;
71}
72
73static void gamecube_shutdown(void)
74{
75 flipper_quiesce();
76}
77
78#ifdef CONFIG_KEXEC
79static int gamecube_kexec_prepare(struct kimage *image)
80{
81 return 0;
82}
83#endif /* CONFIG_KEXEC */
84
85
86define_machine(gamecube) {
87 .name = "gamecube",
88 .probe = gamecube_probe,
89 .init_early = gamecube_init_early,
90 .restart = gamecube_restart,
91 .power_off = gamecube_power_off,
92 .halt = gamecube_halt,
93 .init_IRQ = flipper_pic_probe,
94 .get_irq = flipper_pic_get_irq,
95 .calibrate_decr = generic_calibrate_decr,
96 .progress = udbg_progress,
97 .machine_shutdown = gamecube_shutdown,
98#ifdef CONFIG_KEXEC
99 .machine_kexec_prepare = gamecube_kexec_prepare,
100#endif
101};
102
103
104static struct of_device_id gamecube_of_bus[] = {
105 { .compatible = "nintendo,flipper", },
106 { },
107};
108
109static int __init gamecube_device_probe(void)
110{
111 if (!machine_is(gamecube))
112 return 0;
113
114 of_platform_bus_probe(NULL, gamecube_of_bus, NULL);
115 return 0;
116}
117device_initcall(gamecube_device_probe);
118
diff --git a/arch/powerpc/platforms/embedded6xx/hlwd-pic.c b/arch/powerpc/platforms/embedded6xx/hlwd-pic.c
new file mode 100644
index 000000000000..a771f91e215b
--- /dev/null
+++ b/arch/powerpc/platforms/embedded6xx/hlwd-pic.c
@@ -0,0 +1,241 @@
1/*
2 * arch/powerpc/platforms/embedded6xx/hlwd-pic.c
3 *
4 * Nintendo Wii "Hollywood" interrupt controller support.
5 * Copyright (C) 2009 The GameCube Linux Team
6 * Copyright (C) 2009 Albert Herranz
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 */
14#define DRV_MODULE_NAME "hlwd-pic"
15#define pr_fmt(fmt) DRV_MODULE_NAME ": " fmt
16
17#include <linux/kernel.h>
18#include <linux/init.h>
19#include <linux/irq.h>
20#include <linux/of.h>
21#include <asm/io.h>
22
23#include "hlwd-pic.h"
24
25#define HLWD_NR_IRQS 32
26
27/*
28 * Each interrupt has a corresponding bit in both
29 * the Interrupt Cause (ICR) and Interrupt Mask (IMR) registers.
30 *
31 * Enabling/disabling an interrupt line involves asserting/clearing
32 * the corresponding bit in IMR. ACK'ing a request simply involves
33 * asserting the corresponding bit in ICR.
34 */
35#define HW_BROADWAY_ICR 0x00
36#define HW_BROADWAY_IMR 0x04
37
38
39/*
40 * IRQ chip hooks.
41 *
42 */
43
44static void hlwd_pic_mask_and_ack(unsigned int virq)
45{
46 int irq = virq_to_hw(virq);
47 void __iomem *io_base = get_irq_chip_data(virq);
48 u32 mask = 1 << irq;
49
50 clrbits32(io_base + HW_BROADWAY_IMR, mask);
51 out_be32(io_base + HW_BROADWAY_ICR, mask);
52}
53
54static void hlwd_pic_ack(unsigned int virq)
55{
56 int irq = virq_to_hw(virq);
57 void __iomem *io_base = get_irq_chip_data(virq);
58
59 out_be32(io_base + HW_BROADWAY_ICR, 1 << irq);
60}
61
62static void hlwd_pic_mask(unsigned int virq)
63{
64 int irq = virq_to_hw(virq);
65 void __iomem *io_base = get_irq_chip_data(virq);
66
67 clrbits32(io_base + HW_BROADWAY_IMR, 1 << irq);
68}
69
70static void hlwd_pic_unmask(unsigned int virq)
71{
72 int irq = virq_to_hw(virq);
73 void __iomem *io_base = get_irq_chip_data(virq);
74
75 setbits32(io_base + HW_BROADWAY_IMR, 1 << irq);
76}
77
78
79static struct irq_chip hlwd_pic = {
80 .name = "hlwd-pic",
81 .ack = hlwd_pic_ack,
82 .mask_ack = hlwd_pic_mask_and_ack,
83 .mask = hlwd_pic_mask,
84 .unmask = hlwd_pic_unmask,
85};
86
87/*
88 * IRQ host hooks.
89 *
90 */
91
92static struct irq_host *hlwd_irq_host;
93
94static int hlwd_pic_map(struct irq_host *h, unsigned int virq,
95 irq_hw_number_t hwirq)
96{
97 set_irq_chip_data(virq, h->host_data);
98 irq_to_desc(virq)->status |= IRQ_LEVEL;
99 set_irq_chip_and_handler(virq, &hlwd_pic, handle_level_irq);
100 return 0;
101}
102
103static void hlwd_pic_unmap(struct irq_host *h, unsigned int irq)
104{
105 set_irq_chip_data(irq, NULL);
106 set_irq_chip(irq, NULL);
107}
108
109static struct irq_host_ops hlwd_irq_host_ops = {
110 .map = hlwd_pic_map,
111 .unmap = hlwd_pic_unmap,
112};
113
114static unsigned int __hlwd_pic_get_irq(struct irq_host *h)
115{
116 void __iomem *io_base = h->host_data;
117 int irq;
118 u32 irq_status;
119
120 irq_status = in_be32(io_base + HW_BROADWAY_ICR) &
121 in_be32(io_base + HW_BROADWAY_IMR);
122 if (irq_status == 0)
123 return NO_IRQ; /* no more IRQs pending */
124
125 irq = __ffs(irq_status);
126 return irq_linear_revmap(h, irq);
127}
128
129static void hlwd_pic_irq_cascade(unsigned int cascade_virq,
130 struct irq_desc *desc)
131{
132 struct irq_host *irq_host = get_irq_data(cascade_virq);
133 unsigned int virq;
134
135 raw_spin_lock(&desc->lock);
136 desc->chip->mask(cascade_virq); /* IRQ_LEVEL */
137 raw_spin_unlock(&desc->lock);
138
139 virq = __hlwd_pic_get_irq(irq_host);
140 if (virq != NO_IRQ)
141 generic_handle_irq(virq);
142 else
143 pr_err("spurious interrupt!\n");
144
145 raw_spin_lock(&desc->lock);
146 desc->chip->ack(cascade_virq); /* IRQ_LEVEL */
147 if (!(desc->status & IRQ_DISABLED) && desc->chip->unmask)
148 desc->chip->unmask(cascade_virq);
149 raw_spin_unlock(&desc->lock);
150}
151
152/*
153 * Platform hooks.
154 *
155 */
156
157static void __hlwd_quiesce(void __iomem *io_base)
158{
159 /* mask and ack all IRQs */
160 out_be32(io_base + HW_BROADWAY_IMR, 0);
161 out_be32(io_base + HW_BROADWAY_ICR, 0xffffffff);
162}
163
164struct irq_host *hlwd_pic_init(struct device_node *np)
165{
166 struct irq_host *irq_host;
167 struct resource res;
168 void __iomem *io_base;
169 int retval;
170
171 retval = of_address_to_resource(np, 0, &res);
172 if (retval) {
173 pr_err("no io memory range found\n");
174 return NULL;
175 }
176 io_base = ioremap(res.start, resource_size(&res));
177 if (!io_base) {
178 pr_err("ioremap failed\n");
179 return NULL;
180 }
181
182 pr_info("controller at 0x%08x mapped to 0x%p\n", res.start, io_base);
183
184 __hlwd_quiesce(io_base);
185
186 irq_host = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR, HLWD_NR_IRQS,
187 &hlwd_irq_host_ops, -1);
188 if (!irq_host) {
189 pr_err("failed to allocate irq_host\n");
190 return NULL;
191 }
192 irq_host->host_data = io_base;
193
194 return irq_host;
195}
196
197unsigned int hlwd_pic_get_irq(void)
198{
199 return __hlwd_pic_get_irq(hlwd_irq_host);
200}
201
202/*
203 * Probe function.
204 *
205 */
206
207void hlwd_pic_probe(void)
208{
209 struct irq_host *host;
210 struct device_node *np;
211 const u32 *interrupts;
212 int cascade_virq;
213
214 for_each_compatible_node(np, NULL, "nintendo,hollywood-pic") {
215 interrupts = of_get_property(np, "interrupts", NULL);
216 if (interrupts) {
217 host = hlwd_pic_init(np);
218 BUG_ON(!host);
219 cascade_virq = irq_of_parse_and_map(np, 0);
220 set_irq_data(cascade_virq, host);
221 set_irq_chained_handler(cascade_virq,
222 hlwd_pic_irq_cascade);
223 hlwd_irq_host = host;
224 break;
225 }
226 }
227}
228
229/**
230 * hlwd_quiesce() - quiesce hollywood irq controller
231 *
232 * Mask and ack all interrupt sources.
233 *
234 */
235void hlwd_quiesce(void)
236{
237 void __iomem *io_base = hlwd_irq_host->host_data;
238
239 __hlwd_quiesce(io_base);
240}
241
diff --git a/arch/powerpc/platforms/embedded6xx/hlwd-pic.h b/arch/powerpc/platforms/embedded6xx/hlwd-pic.h
new file mode 100644
index 000000000000..d2e5a092761e
--- /dev/null
+++ b/arch/powerpc/platforms/embedded6xx/hlwd-pic.h
@@ -0,0 +1,22 @@
1/*
2 * arch/powerpc/platforms/embedded6xx/hlwd-pic.h
3 *
4 * Nintendo Wii "Hollywood" interrupt controller support.
5 * Copyright (C) 2009 The GameCube Linux Team
6 * Copyright (C) 2009 Albert Herranz
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 */
14
15#ifndef __HLWD_PIC_H
16#define __HLWD_PIC_H
17
18extern unsigned int hlwd_pic_get_irq(void);
19extern void hlwd_pic_probe(void);
20extern void hlwd_quiesce(void);
21
22#endif
diff --git a/arch/powerpc/platforms/embedded6xx/usbgecko_udbg.c b/arch/powerpc/platforms/embedded6xx/usbgecko_udbg.c
new file mode 100644
index 000000000000..20a8ed91962e
--- /dev/null
+++ b/arch/powerpc/platforms/embedded6xx/usbgecko_udbg.c
@@ -0,0 +1,328 @@
1/*
2 * arch/powerpc/platforms/embedded6xx/usbgecko_udbg.c
3 *
4 * udbg serial input/output routines for the USB Gecko adapter.
5 * Copyright (C) 2008-2009 The GameCube Linux Team
6 * Copyright (C) 2008,2009 Albert Herranz
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 */
14
15#include <mm/mmu_decl.h>
16
17#include <asm/io.h>
18#include <asm/prom.h>
19#include <asm/udbg.h>
20#include <asm/fixmap.h>
21
22#include "usbgecko_udbg.h"
23
24
25#define EXI_CLK_32MHZ 5
26
27#define EXI_CSR 0x00
28#define EXI_CSR_CLKMASK (0x7<<4)
29#define EXI_CSR_CLK_32MHZ (EXI_CLK_32MHZ<<4)
30#define EXI_CSR_CSMASK (0x7<<7)
31#define EXI_CSR_CS_0 (0x1<<7) /* Chip Select 001 */
32
33#define EXI_CR 0x0c
34#define EXI_CR_TSTART (1<<0)
35#define EXI_CR_WRITE (1<<2)
36#define EXI_CR_READ_WRITE (2<<2)
37#define EXI_CR_TLEN(len) (((len)-1)<<4)
38
39#define EXI_DATA 0x10
40
41#define UG_READ_ATTEMPTS 100
42#define UG_WRITE_ATTEMPTS 100
43
44
45static void __iomem *ug_io_base;
46
47/*
48 * Performs one input/output transaction between the exi host and the usbgecko.
49 */
50static u32 ug_io_transaction(u32 in)
51{
52 u32 __iomem *csr_reg = ug_io_base + EXI_CSR;
53 u32 __iomem *data_reg = ug_io_base + EXI_DATA;
54 u32 __iomem *cr_reg = ug_io_base + EXI_CR;
55 u32 csr, data, cr;
56
57 /* select */
58 csr = EXI_CSR_CLK_32MHZ | EXI_CSR_CS_0;
59 out_be32(csr_reg, csr);
60
61 /* read/write */
62 data = in;
63 out_be32(data_reg, data);
64 cr = EXI_CR_TLEN(2) | EXI_CR_READ_WRITE | EXI_CR_TSTART;
65 out_be32(cr_reg, cr);
66
67 while (in_be32(cr_reg) & EXI_CR_TSTART)
68 barrier();
69
70 /* deselect */
71 out_be32(csr_reg, 0);
72
73 /* result */
74 data = in_be32(data_reg);
75
76 return data;
77}
78
79/*
80 * Returns true if an usbgecko adapter is found.
81 */
82static int ug_is_adapter_present(void)
83{
84 if (!ug_io_base)
85 return 0;
86
87 return ug_io_transaction(0x90000000) == 0x04700000;
88}
89
90/*
91 * Returns true if the TX fifo is ready for transmission.
92 */
93static int ug_is_txfifo_ready(void)
94{
95 return ug_io_transaction(0xc0000000) & 0x04000000;
96}
97
98/*
99 * Tries to transmit a character.
100 * If the TX fifo is not ready the result is undefined.
101 */
102static void ug_raw_putc(char ch)
103{
104 ug_io_transaction(0xb0000000 | (ch << 20));
105}
106
107/*
108 * Transmits a character.
109 * It silently fails if the TX fifo is not ready after a number of retries.
110 */
111static void ug_putc(char ch)
112{
113 int count = UG_WRITE_ATTEMPTS;
114
115 if (!ug_io_base)
116 return;
117
118 if (ch == '\n')
119 ug_putc('\r');
120
121 while (!ug_is_txfifo_ready() && count--)
122 barrier();
123 if (count >= 0)
124 ug_raw_putc(ch);
125}
126
127/*
128 * Returns true if the RX fifo is ready for transmission.
129 */
130static int ug_is_rxfifo_ready(void)
131{
132 return ug_io_transaction(0xd0000000) & 0x04000000;
133}
134
135/*
136 * Tries to receive a character.
137 * If a character is unavailable the function returns -1.
138 */
139static int ug_raw_getc(void)
140{
141 u32 data = ug_io_transaction(0xa0000000);
142 if (data & 0x08000000)
143 return (data >> 16) & 0xff;
144 else
145 return -1;
146}
147
148/*
149 * Receives a character.
150 * It fails if the RX fifo is not ready after a number of retries.
151 */
152static int ug_getc(void)
153{
154 int count = UG_READ_ATTEMPTS;
155
156 if (!ug_io_base)
157 return -1;
158
159 while (!ug_is_rxfifo_ready() && count--)
160 barrier();
161 return ug_raw_getc();
162}
163
164/*
165 * udbg functions.
166 *
167 */
168
169/*
170 * Transmits a character.
171 */
172void ug_udbg_putc(char ch)
173{
174 ug_putc(ch);
175}
176
177/*
178 * Receives a character. Waits until a character is available.
179 */
180static int ug_udbg_getc(void)
181{
182 int ch;
183
184 while ((ch = ug_getc()) == -1)
185 barrier();
186 return ch;
187}
188
189/*
190 * Receives a character. If a character is not available, returns -1.
191 */
192static int ug_udbg_getc_poll(void)
193{
194 if (!ug_is_rxfifo_ready())
195 return -1;
196 return ug_getc();
197}
198
199/*
200 * Retrieves and prepares the virtual address needed to access the hardware.
201 */
202static void __iomem *ug_udbg_setup_exi_io_base(struct device_node *np)
203{
204 void __iomem *exi_io_base = NULL;
205 phys_addr_t paddr;
206 const unsigned int *reg;
207
208 reg = of_get_property(np, "reg", NULL);
209 if (reg) {
210 paddr = of_translate_address(np, reg);
211 if (paddr)
212 exi_io_base = ioremap(paddr, reg[1]);
213 }
214 return exi_io_base;
215}
216
217/*
218 * Checks if a USB Gecko adapter is inserted in any memory card slot.
219 */
220static void __iomem *ug_udbg_probe(void __iomem *exi_io_base)
221{
222 int i;
223
224 /* look for a usbgecko on memcard slots A and B */
225 for (i = 0; i < 2; i++) {
226 ug_io_base = exi_io_base + 0x14 * i;
227 if (ug_is_adapter_present())
228 break;
229 }
230 if (i == 2)
231 ug_io_base = NULL;
232 return ug_io_base;
233
234}
235
236/*
237 * USB Gecko udbg support initialization.
238 */
239void __init ug_udbg_init(void)
240{
241 struct device_node *np;
242 void __iomem *exi_io_base;
243
244 if (ug_io_base)
245 udbg_printf("%s: early -> final\n", __func__);
246
247 np = of_find_compatible_node(NULL, NULL, "nintendo,flipper-exi");
248 if (!np) {
249 udbg_printf("%s: EXI node not found\n", __func__);
250 goto done;
251 }
252
253 exi_io_base = ug_udbg_setup_exi_io_base(np);
254 if (!exi_io_base) {
255 udbg_printf("%s: failed to setup EXI io base\n", __func__);
256 goto done;
257 }
258
259 if (!ug_udbg_probe(exi_io_base)) {
260 udbg_printf("usbgecko_udbg: not found\n");
261 iounmap(exi_io_base);
262 } else {
263 udbg_putc = ug_udbg_putc;
264 udbg_getc = ug_udbg_getc;
265 udbg_getc_poll = ug_udbg_getc_poll;
266 udbg_printf("usbgecko_udbg: ready\n");
267 }
268
269done:
270 if (np)
271 of_node_put(np);
272 return;
273}
274
275#ifdef CONFIG_PPC_EARLY_DEBUG_USBGECKO
276
277static phys_addr_t __init ug_early_grab_io_addr(void)
278{
279#if defined(CONFIG_GAMECUBE)
280 return 0x0c000000;
281#elif defined(CONFIG_WII)
282 return 0x0d000000;
283#else
284#error Invalid platform for USB Gecko based early debugging.
285#endif
286}
287
288/*
289 * USB Gecko early debug support initialization for udbg.
290 */
291void __init udbg_init_usbgecko(void)
292{
293 void __iomem *early_debug_area;
294 void __iomem *exi_io_base;
295
296 /*
297 * At this point we have a BAT already setup that enables I/O
298 * to the EXI hardware.
299 *
300 * The BAT uses a virtual address range reserved at the fixmap.
301 * This must match the virtual address configured in
302 * head_32.S:setup_usbgecko_bat().
303 */
304 early_debug_area = (void __iomem *)__fix_to_virt(FIX_EARLY_DEBUG_BASE);
305 exi_io_base = early_debug_area + 0x00006800;
306
307 /* try to detect a USB Gecko */
308 if (!ug_udbg_probe(exi_io_base))
309 return;
310
311 /* we found a USB Gecko, load udbg hooks */
312 udbg_putc = ug_udbg_putc;
313 udbg_getc = ug_udbg_getc;
314 udbg_getc_poll = ug_udbg_getc_poll;
315
316 /*
317 * Prepare again the same BAT for MMU_init.
318 * This allows udbg I/O to continue working after the MMU is
319 * turned on for real.
320 * It is safe to continue using the same virtual address as it is
321 * a reserved fixmap area.
322 */
323 setbat(1, (unsigned long)early_debug_area,
324 ug_early_grab_io_addr(), 128*1024, PAGE_KERNEL_NCG);
325}
326
327#endif /* CONFIG_PPC_EARLY_DEBUG_USBGECKO */
328
diff --git a/arch/powerpc/platforms/embedded6xx/usbgecko_udbg.h b/arch/powerpc/platforms/embedded6xx/usbgecko_udbg.h
new file mode 100644
index 000000000000..bb6cde4ad764
--- /dev/null
+++ b/arch/powerpc/platforms/embedded6xx/usbgecko_udbg.h
@@ -0,0 +1,32 @@
1/*
2 * arch/powerpc/platforms/embedded6xx/usbgecko_udbg.h
3 *
4 * udbg serial input/output routines for the USB Gecko adapter.
5 * Copyright (C) 2008-2009 The GameCube Linux Team
6 * Copyright (C) 2008,2009 Albert Herranz
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 */
14
15#ifndef __USBGECKO_UDBG_H
16#define __USBGECKO_UDBG_H
17
18#ifdef CONFIG_USBGECKO_UDBG
19
20extern void __init ug_udbg_init(void);
21
22#else
23
24static inline void __init ug_udbg_init(void)
25{
26}
27
28#endif /* CONFIG_USBGECKO_UDBG */
29
30void __init udbg_init_usbgecko(void);
31
32#endif /* __USBGECKO_UDBG_H */
diff --git a/arch/powerpc/platforms/embedded6xx/wii.c b/arch/powerpc/platforms/embedded6xx/wii.c
new file mode 100644
index 000000000000..57e5b608fa1a
--- /dev/null
+++ b/arch/powerpc/platforms/embedded6xx/wii.c
@@ -0,0 +1,268 @@
1/*
2 * arch/powerpc/platforms/embedded6xx/wii.c
3 *
4 * Nintendo Wii board-specific support
5 * Copyright (C) 2008-2009 The GameCube Linux Team
6 * Copyright (C) 2008,2009 Albert Herranz
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 */
14#define DRV_MODULE_NAME "wii"
15#define pr_fmt(fmt) DRV_MODULE_NAME ": " fmt
16
17#include <linux/kernel.h>
18#include <linux/init.h>
19#include <linux/irq.h>
20#include <linux/seq_file.h>
21#include <linux/kexec.h>
22#include <linux/of_platform.h>
23#include <linux/lmb.h>
24#include <mm/mmu_decl.h>
25
26#include <asm/io.h>
27#include <asm/machdep.h>
28#include <asm/prom.h>
29#include <asm/time.h>
30#include <asm/udbg.h>
31
32#include "flipper-pic.h"
33#include "hlwd-pic.h"
34#include "usbgecko_udbg.h"
35
36/* control block */
37#define HW_CTRL_COMPATIBLE "nintendo,hollywood-control"
38
39#define HW_CTRL_RESETS 0x94
40#define HW_CTRL_RESETS_SYS (1<<0)
41
42/* gpio */
43#define HW_GPIO_COMPATIBLE "nintendo,hollywood-gpio"
44
45#define HW_GPIO_BASE(idx) (idx * 0x20)
46#define HW_GPIO_OUT(idx) (HW_GPIO_BASE(idx) + 0)
47#define HW_GPIO_DIR(idx) (HW_GPIO_BASE(idx) + 4)
48
49#define HW_GPIO_SHUTDOWN (1<<1)
50#define HW_GPIO_SLOT_LED (1<<5)
51#define HW_GPIO_SENSOR_BAR (1<<8)
52
53
54static void __iomem *hw_ctrl;
55static void __iomem *hw_gpio;
56
57unsigned long wii_hole_start;
58unsigned long wii_hole_size;
59
60
61static int __init page_aligned(unsigned long x)
62{
63 return !(x & (PAGE_SIZE-1));
64}
65
66void __init wii_memory_fixups(void)
67{
68 struct lmb_property *p = lmb.memory.region;
69
70 /*
71 * This is part of a workaround to allow the use of two
72 * discontiguous RAM ranges on the Wii, even if this is
73 * currently unsupported on 32-bit PowerPC Linux.
74 *
75 * We coealesce the two memory ranges of the Wii into a
76 * single range, then create a reservation for the "hole"
77 * between both ranges.
78 */
79
80 BUG_ON(lmb.memory.cnt != 2);
81 BUG_ON(!page_aligned(p[0].base) || !page_aligned(p[1].base));
82
83 p[0].size = _ALIGN_DOWN(p[0].size, PAGE_SIZE);
84 p[1].size = _ALIGN_DOWN(p[1].size, PAGE_SIZE);
85
86 wii_hole_start = p[0].base + p[0].size;
87 wii_hole_size = p[1].base - wii_hole_start;
88
89 pr_info("MEM1: <%08llx %08llx>\n", p[0].base, p[0].size);
90 pr_info("HOLE: <%08lx %08lx>\n", wii_hole_start, wii_hole_size);
91 pr_info("MEM2: <%08llx %08llx>\n", p[1].base, p[1].size);
92
93 p[0].size += wii_hole_size + p[1].size;
94
95 lmb.memory.cnt = 1;
96 lmb_analyze();
97
98 /* reserve the hole */
99 lmb_reserve(wii_hole_start, wii_hole_size);
100
101 /* allow ioremapping the address space in the hole */
102 __allow_ioremap_reserved = 1;
103}
104
105unsigned long __init wii_mmu_mapin_mem2(unsigned long top)
106{
107 unsigned long delta, size, bl;
108 unsigned long max_size = (256<<20);
109
110 /* MEM2 64MB@0x10000000 */
111 delta = wii_hole_start + wii_hole_size;
112 size = top - delta;
113 for (bl = 128<<10; bl < max_size; bl <<= 1) {
114 if (bl * 2 > size)
115 break;
116 }
117 setbat(4, PAGE_OFFSET+delta, delta, bl, PAGE_KERNEL_X);
118 return delta + bl;
119}
120
121static void wii_spin(void)
122{
123 local_irq_disable();
124 for (;;)
125 cpu_relax();
126}
127
128static void __iomem *wii_ioremap_hw_regs(char *name, char *compatible)
129{
130 void __iomem *hw_regs = NULL;
131 struct device_node *np;
132 struct resource res;
133 int error = -ENODEV;
134
135 np = of_find_compatible_node(NULL, NULL, compatible);
136 if (!np) {
137 pr_err("no compatible node found for %s\n", compatible);
138 goto out;
139 }
140 error = of_address_to_resource(np, 0, &res);
141 if (error) {
142 pr_err("no valid reg found for %s\n", np->name);
143 goto out_put;
144 }
145
146 hw_regs = ioremap(res.start, resource_size(&res));
147 if (hw_regs) {
148 pr_info("%s at 0x%08x mapped to 0x%p\n", name,
149 res.start, hw_regs);
150 }
151
152out_put:
153 of_node_put(np);
154out:
155 return hw_regs;
156}
157
158static void __init wii_setup_arch(void)
159{
160 hw_ctrl = wii_ioremap_hw_regs("hw_ctrl", HW_CTRL_COMPATIBLE);
161 hw_gpio = wii_ioremap_hw_regs("hw_gpio", HW_GPIO_COMPATIBLE);
162 if (hw_gpio) {
163 /* turn off the front blue led and IR light */
164 clrbits32(hw_gpio + HW_GPIO_OUT(0),
165 HW_GPIO_SLOT_LED | HW_GPIO_SENSOR_BAR);
166 }
167}
168
169static void wii_restart(char *cmd)
170{
171 local_irq_disable();
172
173 if (hw_ctrl) {
174 /* clear the system reset pin to cause a reset */
175 clrbits32(hw_ctrl + HW_CTRL_RESETS, HW_CTRL_RESETS_SYS);
176 }
177 wii_spin();
178}
179
180static void wii_power_off(void)
181{
182 local_irq_disable();
183
184 if (hw_gpio) {
185 /* make sure that the poweroff GPIO is configured as output */
186 setbits32(hw_gpio + HW_GPIO_DIR(1), HW_GPIO_SHUTDOWN);
187
188 /* drive the poweroff GPIO high */
189 setbits32(hw_gpio + HW_GPIO_OUT(1), HW_GPIO_SHUTDOWN);
190 }
191 wii_spin();
192}
193
194static void wii_halt(void)
195{
196 if (ppc_md.restart)
197 ppc_md.restart(NULL);
198 wii_spin();
199}
200
201static void __init wii_init_early(void)
202{
203 ug_udbg_init();
204}
205
206static void __init wii_pic_probe(void)
207{
208 flipper_pic_probe();
209 hlwd_pic_probe();
210}
211
212static int __init wii_probe(void)
213{
214 unsigned long dt_root;
215
216 dt_root = of_get_flat_dt_root();
217 if (!of_flat_dt_is_compatible(dt_root, "nintendo,wii"))
218 return 0;
219
220 return 1;
221}
222
223static void wii_shutdown(void)
224{
225 hlwd_quiesce();
226 flipper_quiesce();
227}
228
229#ifdef CONFIG_KEXEC
230static int wii_machine_kexec_prepare(struct kimage *image)
231{
232 return 0;
233}
234#endif /* CONFIG_KEXEC */
235
236define_machine(wii) {
237 .name = "wii",
238 .probe = wii_probe,
239 .init_early = wii_init_early,
240 .setup_arch = wii_setup_arch,
241 .restart = wii_restart,
242 .power_off = wii_power_off,
243 .halt = wii_halt,
244 .init_IRQ = wii_pic_probe,
245 .get_irq = flipper_pic_get_irq,
246 .calibrate_decr = generic_calibrate_decr,
247 .progress = udbg_progress,
248 .machine_shutdown = wii_shutdown,
249#ifdef CONFIG_KEXEC
250 .machine_kexec_prepare = wii_machine_kexec_prepare,
251#endif
252};
253
254static struct of_device_id wii_of_bus[] = {
255 { .compatible = "nintendo,hollywood", },
256 { },
257};
258
259static int __init wii_device_probe(void)
260{
261 if (!machine_is(wii))
262 return 0;
263
264 of_platform_bus_probe(NULL, wii_of_bus, NULL);
265 return 0;
266}
267device_initcall(wii_device_probe);
268
diff --git a/arch/powerpc/platforms/iseries/htab.c b/arch/powerpc/platforms/iseries/htab.c
index f99c6c4b6985..3ae66ab9d5e7 100644
--- a/arch/powerpc/platforms/iseries/htab.c
+++ b/arch/powerpc/platforms/iseries/htab.c
@@ -19,8 +19,7 @@
19 19
20#include "call_hpt.h" 20#include "call_hpt.h"
21 21
22static spinlock_t iSeries_hlocks[64] __cacheline_aligned_in_smp = 22static spinlock_t iSeries_hlocks[64] __cacheline_aligned_in_smp;
23 { [0 ... 63] = SPIN_LOCK_UNLOCKED};
24 23
25/* 24/*
26 * Very primitive algorithm for picking up a lock 25 * Very primitive algorithm for picking up a lock
@@ -245,6 +244,11 @@ static void iSeries_hpte_invalidate(unsigned long slot, unsigned long va,
245 244
246void __init hpte_init_iSeries(void) 245void __init hpte_init_iSeries(void)
247{ 246{
247 int i;
248
249 for (i = 0; i < ARRAY_SIZE(iSeries_hlocks); i++)
250 spin_lock_init(&iSeries_hlocks[i]);
251
248 ppc_md.hpte_invalidate = iSeries_hpte_invalidate; 252 ppc_md.hpte_invalidate = iSeries_hpte_invalidate;
249 ppc_md.hpte_updatepp = iSeries_hpte_updatepp; 253 ppc_md.hpte_updatepp = iSeries_hpte_updatepp;
250 ppc_md.hpte_updateboltedpp = iSeries_hpte_updateboltedpp; 254 ppc_md.hpte_updateboltedpp = iSeries_hpte_updateboltedpp;
diff --git a/arch/powerpc/platforms/iseries/irq.c b/arch/powerpc/platforms/iseries/irq.c
index 94f444758836..86c4b29eea89 100644
--- a/arch/powerpc/platforms/iseries/irq.c
+++ b/arch/powerpc/platforms/iseries/irq.c
@@ -214,12 +214,12 @@ void __init iSeries_activate_IRQs()
214 unsigned long flags; 214 unsigned long flags;
215 215
216 for_each_irq (irq) { 216 for_each_irq (irq) {
217 struct irq_desc *desc = get_irq_desc(irq); 217 struct irq_desc *desc = irq_to_desc(irq);
218 218
219 if (desc && desc->chip && desc->chip->startup) { 219 if (desc && desc->chip && desc->chip->startup) {
220 spin_lock_irqsave(&desc->lock, flags); 220 raw_spin_lock_irqsave(&desc->lock, flags);
221 desc->chip->startup(irq); 221 desc->chip->startup(irq);
222 spin_unlock_irqrestore(&desc->lock, flags); 222 raw_spin_unlock_irqrestore(&desc->lock, flags);
223 } 223 }
224 } 224 }
225} 225}
@@ -273,7 +273,7 @@ static void iseries_end_IRQ(unsigned int irq)
273} 273}
274 274
275static struct irq_chip iseries_pic = { 275static struct irq_chip iseries_pic = {
276 .typename = "iSeries irq controller", 276 .name = "iSeries irq controller",
277 .startup = iseries_startup_IRQ, 277 .startup = iseries_startup_IRQ,
278 .shutdown = iseries_shutdown_IRQ, 278 .shutdown = iseries_shutdown_IRQ,
279 .unmask = iseries_enable_IRQ, 279 .unmask = iseries_enable_IRQ,
diff --git a/arch/powerpc/platforms/iseries/mf.c b/arch/powerpc/platforms/iseries/mf.c
index 0d9343df35bc..6617915bcb1a 100644
--- a/arch/powerpc/platforms/iseries/mf.c
+++ b/arch/powerpc/platforms/iseries/mf.c
@@ -855,59 +855,58 @@ static int mf_get_boot_rtc(struct rtc_time *tm)
855} 855}
856 856
857#ifdef CONFIG_PROC_FS 857#ifdef CONFIG_PROC_FS
858 858static int mf_cmdline_proc_show(struct seq_file *m, void *v)
859static int proc_mf_dump_cmdline(char *page, char **start, off_t off,
860 int count, int *eof, void *data)
861{ 859{
862 int len; 860 char *page, *p;
863 char *p;
864 struct vsp_cmd_data vsp_cmd; 861 struct vsp_cmd_data vsp_cmd;
865 int rc; 862 int rc;
866 dma_addr_t dma_addr; 863 dma_addr_t dma_addr;
867 864
868 /* The HV appears to return no more than 256 bytes of command line */ 865 /* The HV appears to return no more than 256 bytes of command line */
869 if (off >= 256) 866 page = kmalloc(256, GFP_KERNEL);
870 return 0; 867 if (!page)
871 if ((off + count) > 256) 868 return -ENOMEM;
872 count = 256 - off;
873 869
874 dma_addr = iseries_hv_map(page, off + count, DMA_FROM_DEVICE); 870 dma_addr = iseries_hv_map(page, 256, DMA_FROM_DEVICE);
875 if (dma_addr == DMA_ERROR_CODE) 871 if (dma_addr == DMA_ERROR_CODE) {
872 kfree(page);
876 return -ENOMEM; 873 return -ENOMEM;
877 memset(page, 0, off + count); 874 }
875 memset(page, 0, 256);
878 memset(&vsp_cmd, 0, sizeof(vsp_cmd)); 876 memset(&vsp_cmd, 0, sizeof(vsp_cmd));
879 vsp_cmd.cmd = 33; 877 vsp_cmd.cmd = 33;
880 vsp_cmd.sub_data.kern.token = dma_addr; 878 vsp_cmd.sub_data.kern.token = dma_addr;
881 vsp_cmd.sub_data.kern.address_type = HvLpDma_AddressType_TceIndex; 879 vsp_cmd.sub_data.kern.address_type = HvLpDma_AddressType_TceIndex;
882 vsp_cmd.sub_data.kern.side = (u64)data; 880 vsp_cmd.sub_data.kern.side = (u64)m->private;
883 vsp_cmd.sub_data.kern.length = off + count; 881 vsp_cmd.sub_data.kern.length = 256;
884 mb(); 882 mb();
885 rc = signal_vsp_instruction(&vsp_cmd); 883 rc = signal_vsp_instruction(&vsp_cmd);
886 iseries_hv_unmap(dma_addr, off + count, DMA_FROM_DEVICE); 884 iseries_hv_unmap(dma_addr, 256, DMA_FROM_DEVICE);
887 if (rc) 885 if (rc) {
886 kfree(page);
888 return rc; 887 return rc;
889 if (vsp_cmd.result_code != 0) 888 }
889 if (vsp_cmd.result_code != 0) {
890 kfree(page);
890 return -ENOMEM; 891 return -ENOMEM;
892 }
891 p = page; 893 p = page;
892 len = 0; 894 while (p - page < 256) {
893 while (len < (off + count)) { 895 if (*p == '\0' || *p == '\n') {
894 if ((*p == '\0') || (*p == '\n')) { 896 *p = '\n';
895 if (*p == '\0')
896 *p = '\n';
897 p++;
898 len++;
899 *eof = 1;
900 break; 897 break;
901 } 898 }
902 p++; 899 p++;
903 len++;
904 }
905 900
906 if (len < off) {
907 *eof = 1;
908 len = 0;
909 } 901 }
910 return len; 902 seq_write(m, page, p - page);
903 kfree(page);
904 return 0;
905}
906
907static int mf_cmdline_proc_open(struct inode *inode, struct file *file)
908{
909 return single_open(file, mf_cmdline_proc_show, PDE(inode)->data);
911} 910}
912 911
913#if 0 912#if 0
@@ -962,10 +961,8 @@ static int proc_mf_dump_vmlinux(char *page, char **start, off_t off,
962} 961}
963#endif 962#endif
964 963
965static int proc_mf_dump_side(char *page, char **start, off_t off, 964static int mf_side_proc_show(struct seq_file *m, void *v)
966 int count, int *eof, void *data)
967{ 965{
968 int len;
969 char mf_current_side = ' '; 966 char mf_current_side = ' ';
970 struct vsp_cmd_data vsp_cmd; 967 struct vsp_cmd_data vsp_cmd;
971 968
@@ -989,21 +986,17 @@ static int proc_mf_dump_side(char *page, char **start, off_t off,
989 } 986 }
990 } 987 }
991 988
992 len = sprintf(page, "%c\n", mf_current_side); 989 seq_printf(m, "%c\n", mf_current_side);
990 return 0;
991}
993 992
994 if (len <= (off + count)) 993static int mf_side_proc_open(struct inode *inode, struct file *file)
995 *eof = 1; 994{
996 *start = page + off; 995 return single_open(file, mf_side_proc_show, NULL);
997 len -= off;
998 if (len > count)
999 len = count;
1000 if (len < 0)
1001 len = 0;
1002 return len;
1003} 996}
1004 997
1005static int proc_mf_change_side(struct file *file, const char __user *buffer, 998static ssize_t mf_side_proc_write(struct file *file, const char __user *buffer,
1006 unsigned long count, void *data) 999 size_t count, loff_t *pos)
1007{ 1000{
1008 char side; 1001 char side;
1009 u64 newSide; 1002 u64 newSide;
@@ -1041,6 +1034,15 @@ static int proc_mf_change_side(struct file *file, const char __user *buffer,
1041 return count; 1034 return count;
1042} 1035}
1043 1036
1037static const struct file_operations mf_side_proc_fops = {
1038 .owner = THIS_MODULE,
1039 .open = mf_side_proc_open,
1040 .read = seq_read,
1041 .llseek = seq_lseek,
1042 .release = single_release,
1043 .write = mf_side_proc_write,
1044};
1045
1044#if 0 1046#if 0
1045static void mf_getSrcHistory(char *buffer, int size) 1047static void mf_getSrcHistory(char *buffer, int size)
1046{ 1048{
@@ -1087,8 +1089,7 @@ static void mf_getSrcHistory(char *buffer, int size)
1087} 1089}
1088#endif 1090#endif
1089 1091
1090static int proc_mf_dump_src(char *page, char **start, off_t off, 1092static int mf_src_proc_show(struct seq_file *m, void *v)
1091 int count, int *eof, void *data)
1092{ 1093{
1093#if 0 1094#if 0
1094 int len; 1095 int len;
@@ -1109,8 +1110,13 @@ static int proc_mf_dump_src(char *page, char **start, off_t off,
1109#endif 1110#endif
1110} 1111}
1111 1112
1112static int proc_mf_change_src(struct file *file, const char __user *buffer, 1113static int mf_src_proc_open(struct inode *inode, struct file *file)
1113 unsigned long count, void *data) 1114{
1115 return single_open(file, mf_src_proc_show, NULL);
1116}
1117
1118static ssize_t mf_src_proc_write(struct file *file, const char __user *buffer,
1119 size_t count, loff_t *pos)
1114{ 1120{
1115 char stkbuf[10]; 1121 char stkbuf[10];
1116 1122
@@ -1135,9 +1141,19 @@ static int proc_mf_change_src(struct file *file, const char __user *buffer,
1135 return count; 1141 return count;
1136} 1142}
1137 1143
1138static int proc_mf_change_cmdline(struct file *file, const char __user *buffer, 1144static const struct file_operations mf_src_proc_fops = {
1139 unsigned long count, void *data) 1145 .owner = THIS_MODULE,
1146 .open = mf_src_proc_open,
1147 .read = seq_read,
1148 .llseek = seq_lseek,
1149 .release = single_release,
1150 .write = mf_src_proc_write,
1151};
1152
1153static ssize_t mf_cmdline_proc_write(struct file *file, const char __user *buffer,
1154 size_t count, loff_t *pos)
1140{ 1155{
1156 void *data = PDE(file->f_path.dentry->d_inode)->data;
1141 struct vsp_cmd_data vsp_cmd; 1157 struct vsp_cmd_data vsp_cmd;
1142 dma_addr_t dma_addr; 1158 dma_addr_t dma_addr;
1143 char *page; 1159 char *page;
@@ -1172,6 +1188,15 @@ out:
1172 return ret; 1188 return ret;
1173} 1189}
1174 1190
1191static const struct file_operations mf_cmdline_proc_fops = {
1192 .owner = THIS_MODULE,
1193 .open = mf_cmdline_proc_open,
1194 .read = seq_read,
1195 .llseek = seq_lseek,
1196 .release = single_release,
1197 .write = mf_cmdline_proc_write,
1198};
1199
1175static ssize_t proc_mf_change_vmlinux(struct file *file, 1200static ssize_t proc_mf_change_vmlinux(struct file *file,
1176 const char __user *buf, 1201 const char __user *buf,
1177 size_t count, loff_t *ppos) 1202 size_t count, loff_t *ppos)
@@ -1246,12 +1271,10 @@ static int __init mf_proc_init(void)
1246 if (!mf) 1271 if (!mf)
1247 return 1; 1272 return 1;
1248 1273
1249 ent = create_proc_entry("cmdline", S_IFREG|S_IRUSR|S_IWUSR, mf); 1274 ent = proc_create_data("cmdline", S_IRUSR|S_IWUSR, mf,
1275 &mf_cmdline_proc_fops, (void *)(long)i);
1250 if (!ent) 1276 if (!ent)
1251 return 1; 1277 return 1;
1252 ent->data = (void *)(long)i;
1253 ent->read_proc = proc_mf_dump_cmdline;
1254 ent->write_proc = proc_mf_change_cmdline;
1255 1278
1256 if (i == 3) /* no vmlinux entry for 'D' */ 1279 if (i == 3) /* no vmlinux entry for 'D' */
1257 continue; 1280 continue;
@@ -1263,19 +1286,15 @@ static int __init mf_proc_init(void)
1263 return 1; 1286 return 1;
1264 } 1287 }
1265 1288
1266 ent = create_proc_entry("side", S_IFREG|S_IRUSR|S_IWUSR, mf_proc_root); 1289 ent = proc_create("side", S_IFREG|S_IRUSR|S_IWUSR, mf_proc_root,
1290 &mf_side_proc_fops);
1267 if (!ent) 1291 if (!ent)
1268 return 1; 1292 return 1;
1269 ent->data = (void *)0;
1270 ent->read_proc = proc_mf_dump_side;
1271 ent->write_proc = proc_mf_change_side;
1272 1293
1273 ent = create_proc_entry("src", S_IFREG|S_IRUSR|S_IWUSR, mf_proc_root); 1294 ent = proc_create("src", S_IFREG|S_IRUSR|S_IWUSR, mf_proc_root,
1295 &mf_src_proc_fops);
1274 if (!ent) 1296 if (!ent)
1275 return 1; 1297 return 1;
1276 ent->data = (void *)0;
1277 ent->read_proc = proc_mf_dump_src;
1278 ent->write_proc = proc_mf_change_src;
1279 1298
1280 return 0; 1299 return 0;
1281} 1300}
diff --git a/arch/powerpc/platforms/iseries/vio.c b/arch/powerpc/platforms/iseries/vio.c
index 657b72f68493..2aa8b5631beb 100644
--- a/arch/powerpc/platforms/iseries/vio.c
+++ b/arch/powerpc/platforms/iseries/vio.c
@@ -474,6 +474,8 @@ static void __init get_viotape_info(struct device_node *vio_root)
474 struct vio_waitevent we; 474 struct vio_waitevent we;
475 int ret; 475 int ret;
476 476
477 init_completion(&we.com);
478
477 ret = viopath_open(viopath_hostLp, viomajorsubtype_tape, 2); 479 ret = viopath_open(viopath_hostLp, viomajorsubtype_tape, 2);
478 if (ret) { 480 if (ret) {
479 printk(KERN_WARNING "get_viotape_info: " 481 printk(KERN_WARNING "get_viotape_info: "
diff --git a/arch/powerpc/platforms/iseries/viopath.c b/arch/powerpc/platforms/iseries/viopath.c
index 49ff4dc422b7..5aea94f30836 100644
--- a/arch/powerpc/platforms/iseries/viopath.c
+++ b/arch/powerpc/platforms/iseries/viopath.c
@@ -116,7 +116,7 @@ static int proc_viopath_show(struct seq_file *m, void *v)
116 u16 vlanMap; 116 u16 vlanMap;
117 dma_addr_t handle; 117 dma_addr_t handle;
118 HvLpEvent_Rc hvrc; 118 HvLpEvent_Rc hvrc;
119 DECLARE_COMPLETION(done); 119 DECLARE_COMPLETION_ONSTACK(done);
120 struct device_node *node; 120 struct device_node *node;
121 const char *sysid; 121 const char *sysid;
122 122
diff --git a/arch/powerpc/platforms/pasemi/setup.c b/arch/powerpc/platforms/pasemi/setup.c
index a4619347aa7e..242f8095c2df 100644
--- a/arch/powerpc/platforms/pasemi/setup.c
+++ b/arch/powerpc/platforms/pasemi/setup.c
@@ -71,7 +71,7 @@ static void pas_restart(char *cmd)
71} 71}
72 72
73#ifdef CONFIG_SMP 73#ifdef CONFIG_SMP
74static raw_spinlock_t timebase_lock; 74static arch_spinlock_t timebase_lock;
75static unsigned long timebase; 75static unsigned long timebase;
76 76
77static void __devinit pas_give_timebase(void) 77static void __devinit pas_give_timebase(void)
@@ -80,11 +80,11 @@ static void __devinit pas_give_timebase(void)
80 80
81 local_irq_save(flags); 81 local_irq_save(flags);
82 hard_irq_disable(); 82 hard_irq_disable();
83 __raw_spin_lock(&timebase_lock); 83 arch_spin_lock(&timebase_lock);
84 mtspr(SPRN_TBCTL, TBCTL_FREEZE); 84 mtspr(SPRN_TBCTL, TBCTL_FREEZE);
85 isync(); 85 isync();
86 timebase = get_tb(); 86 timebase = get_tb();
87 __raw_spin_unlock(&timebase_lock); 87 arch_spin_unlock(&timebase_lock);
88 88
89 while (timebase) 89 while (timebase)
90 barrier(); 90 barrier();
@@ -97,10 +97,10 @@ static void __devinit pas_take_timebase(void)
97 while (!timebase) 97 while (!timebase)
98 smp_rmb(); 98 smp_rmb();
99 99
100 __raw_spin_lock(&timebase_lock); 100 arch_spin_lock(&timebase_lock);
101 set_tb(timebase >> 32, timebase & 0xffffffff); 101 set_tb(timebase >> 32, timebase & 0xffffffff);
102 timebase = 0; 102 timebase = 0;
103 __raw_spin_unlock(&timebase_lock); 103 arch_spin_unlock(&timebase_lock);
104} 104}
105 105
106struct smp_ops_t pas_smp_ops = { 106struct smp_ops_t pas_smp_ops = {
diff --git a/arch/powerpc/platforms/powermac/bootx_init.c b/arch/powerpc/platforms/powermac/bootx_init.c
index cf660916ae0b..9dd789a7370d 100644
--- a/arch/powerpc/platforms/powermac/bootx_init.c
+++ b/arch/powerpc/platforms/powermac/bootx_init.c
@@ -12,7 +12,7 @@
12#include <linux/kernel.h> 12#include <linux/kernel.h>
13#include <linux/string.h> 13#include <linux/string.h>
14#include <linux/init.h> 14#include <linux/init.h>
15#include <linux/utsrelease.h> 15#include <generated/utsrelease.h>
16#include <asm/sections.h> 16#include <asm/sections.h>
17#include <asm/prom.h> 17#include <asm/prom.h>
18#include <asm/page.h> 18#include <asm/page.h>
diff --git a/arch/powerpc/platforms/powermac/low_i2c.c b/arch/powerpc/platforms/powermac/low_i2c.c
index 414ca9849f23..345e2da56767 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/timer.h> 43#include <linux/timer.h>
44#include <linux/mutex.h> 44#include <linux/mutex.h>
45#include <linux/i2c.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>
@@ -80,7 +81,7 @@ struct pmac_i2c_bus
80 struct device_node *busnode; 81 struct device_node *busnode;
81 int type; 82 int type;
82 int flags; 83 int flags;
83 struct i2c_adapter *adapter; 84 struct i2c_adapter adapter;
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 */
@@ -1014,25 +1015,9 @@ int pmac_i2c_get_channel(struct pmac_i2c_bus *bus)
1014EXPORT_SYMBOL_GPL(pmac_i2c_get_channel); 1015EXPORT_SYMBOL_GPL(pmac_i2c_get_channel);
1015 1016
1016 1017
1017void pmac_i2c_attach_adapter(struct pmac_i2c_bus *bus,
1018 struct i2c_adapter *adapter)
1019{
1020 WARN_ON(bus->adapter != NULL);
1021 bus->adapter = adapter;
1022}
1023EXPORT_SYMBOL_GPL(pmac_i2c_attach_adapter);
1024
1025void pmac_i2c_detach_adapter(struct pmac_i2c_bus *bus,
1026 struct i2c_adapter *adapter)
1027{
1028 WARN_ON(bus->adapter != adapter);
1029 bus->adapter = NULL;
1030}
1031EXPORT_SYMBOL_GPL(pmac_i2c_detach_adapter);
1032
1033struct i2c_adapter *pmac_i2c_get_adapter(struct pmac_i2c_bus *bus) 1018struct i2c_adapter *pmac_i2c_get_adapter(struct pmac_i2c_bus *bus)
1034{ 1019{
1035 return bus->adapter; 1020 return &bus->adapter;
1036} 1021}
1037EXPORT_SYMBOL_GPL(pmac_i2c_get_adapter); 1022EXPORT_SYMBOL_GPL(pmac_i2c_get_adapter);
1038 1023
@@ -1041,7 +1026,7 @@ struct pmac_i2c_bus *pmac_i2c_adapter_to_bus(struct i2c_adapter *adapter)
1041 struct pmac_i2c_bus *bus; 1026 struct pmac_i2c_bus *bus;
1042 1027
1043 list_for_each_entry(bus, &pmac_i2c_busses, link) 1028 list_for_each_entry(bus, &pmac_i2c_busses, link)
1044 if (bus->adapter == adapter) 1029 if (&bus->adapter == adapter)
1045 return bus; 1030 return bus;
1046 return NULL; 1031 return NULL;
1047} 1032}
@@ -1053,7 +1038,7 @@ int pmac_i2c_match_adapter(struct device_node *dev, struct i2c_adapter *adapter)
1053 1038
1054 if (bus == NULL) 1039 if (bus == NULL)
1055 return 0; 1040 return 0;
1056 return (bus->adapter == adapter); 1041 return (&bus->adapter == adapter);
1057} 1042}
1058EXPORT_SYMBOL_GPL(pmac_i2c_match_adapter); 1043EXPORT_SYMBOL_GPL(pmac_i2c_match_adapter);
1059 1044
diff --git a/arch/powerpc/platforms/powermac/pci.c b/arch/powerpc/platforms/powermac/pci.c
index e81403b245b5..ab2027cdf893 100644
--- a/arch/powerpc/platforms/powermac/pci.c
+++ b/arch/powerpc/platforms/powermac/pci.c
@@ -302,7 +302,7 @@ static void __init setup_chaos(struct pci_controller *hose,
302 * 1 -> Skip the device but act as if the access was successfull 302 * 1 -> Skip the device but act as if the access was successfull
303 * (return 0xff's on reads, eventually, cache config space 303 * (return 0xff's on reads, eventually, cache config space
304 * accesses in a later version) 304 * accesses in a later version)
305 * -1 -> Hide the device (unsuccessful acess) 305 * -1 -> Hide the device (unsuccessful access)
306 */ 306 */
307static int u3_ht_skip_device(struct pci_controller *hose, 307static int u3_ht_skip_device(struct pci_controller *hose,
308 struct pci_bus *bus, unsigned int devfn) 308 struct pci_bus *bus, unsigned int devfn)
diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c
index d212006a5b3c..09e827296276 100644
--- a/arch/powerpc/platforms/powermac/pic.c
+++ b/arch/powerpc/platforms/powermac/pic.c
@@ -152,12 +152,12 @@ static unsigned int pmac_startup_irq(unsigned int virq)
152 unsigned long bit = 1UL << (src & 0x1f); 152 unsigned long bit = 1UL << (src & 0x1f);
153 int i = src >> 5; 153 int i = src >> 5;
154 154
155 spin_lock_irqsave(&pmac_pic_lock, flags); 155 spin_lock_irqsave(&pmac_pic_lock, flags);
156 if ((irq_desc[virq].status & IRQ_LEVEL) == 0) 156 if ((irq_to_desc(virq)->status & IRQ_LEVEL) == 0)
157 out_le32(&pmac_irq_hw[i]->ack, bit); 157 out_le32(&pmac_irq_hw[i]->ack, bit);
158 __set_bit(src, ppc_cached_irq_mask); 158 __set_bit(src, ppc_cached_irq_mask);
159 __pmac_set_irq_mask(src, 0); 159 __pmac_set_irq_mask(src, 0);
160 spin_unlock_irqrestore(&pmac_pic_lock, flags); 160 spin_unlock_irqrestore(&pmac_pic_lock, flags);
161 161
162 return 0; 162 return 0;
163} 163}
@@ -195,7 +195,7 @@ static int pmac_retrigger(unsigned int virq)
195} 195}
196 196
197static struct irq_chip pmac_pic = { 197static struct irq_chip pmac_pic = {
198 .typename = " PMAC-PIC ", 198 .name = " PMAC-PIC ",
199 .startup = pmac_startup_irq, 199 .startup = pmac_startup_irq,
200 .mask = pmac_mask_irq, 200 .mask = pmac_mask_irq,
201 .ack = pmac_ack_irq, 201 .ack = pmac_ack_irq,
@@ -285,7 +285,7 @@ static int pmac_pic_host_match(struct irq_host *h, struct device_node *node)
285static int pmac_pic_host_map(struct irq_host *h, unsigned int virq, 285static int pmac_pic_host_map(struct irq_host *h, unsigned int virq,
286 irq_hw_number_t hw) 286 irq_hw_number_t hw)
287{ 287{
288 struct irq_desc *desc = get_irq_desc(virq); 288 struct irq_desc *desc = irq_to_desc(virq);
289 int level; 289 int level;
290 290
291 if (hw >= max_irqs) 291 if (hw >= max_irqs)
@@ -303,7 +303,7 @@ static int pmac_pic_host_map(struct irq_host *h, unsigned int virq,
303} 303}
304 304
305static int pmac_pic_host_xlate(struct irq_host *h, struct device_node *ct, 305static int pmac_pic_host_xlate(struct irq_host *h, struct device_node *ct,
306 u32 *intspec, unsigned int intsize, 306 const u32 *intspec, unsigned int intsize,
307 irq_hw_number_t *out_hwirq, 307 irq_hw_number_t *out_hwirq,
308 unsigned int *out_flags) 308 unsigned int *out_flags)
309 309
diff --git a/arch/powerpc/platforms/ps3/interrupt.c b/arch/powerpc/platforms/ps3/interrupt.c
index 8ec5ccf76b19..59d9712d7364 100644
--- a/arch/powerpc/platforms/ps3/interrupt.c
+++ b/arch/powerpc/platforms/ps3/interrupt.c
@@ -152,7 +152,7 @@ static void ps3_chip_eoi(unsigned int virq)
152 */ 152 */
153 153
154static struct irq_chip ps3_irq_chip = { 154static struct irq_chip ps3_irq_chip = {
155 .typename = "ps3", 155 .name = "ps3",
156 .mask = ps3_chip_mask, 156 .mask = ps3_chip_mask,
157 .unmask = ps3_chip_unmask, 157 .unmask = ps3_chip_unmask,
158 .eoi = ps3_chip_eoi, 158 .eoi = ps3_chip_eoi,
diff --git a/arch/powerpc/platforms/ps3/mm.c b/arch/powerpc/platforms/ps3/mm.c
index 189a25b80735..e81b028a2a48 100644
--- a/arch/powerpc/platforms/ps3/mm.c
+++ b/arch/powerpc/platforms/ps3/mm.c
@@ -34,7 +34,7 @@
34#if defined(DEBUG) 34#if defined(DEBUG)
35#define DBG udbg_printf 35#define DBG udbg_printf
36#else 36#else
37#define DBG pr_debug 37#define DBG pr_devel
38#endif 38#endif
39 39
40enum { 40enum {
diff --git a/arch/powerpc/platforms/pseries/Kconfig b/arch/powerpc/platforms/pseries/Kconfig
index f0e6f28427bd..c667f0f02c34 100644
--- a/arch/powerpc/platforms/pseries/Kconfig
+++ b/arch/powerpc/platforms/pseries/Kconfig
@@ -2,8 +2,11 @@ config PPC_PSERIES
2 depends on PPC64 && PPC_BOOK3S 2 depends on PPC64 && PPC_BOOK3S
3 bool "IBM pSeries & new (POWER5-based) iSeries" 3 bool "IBM pSeries & new (POWER5-based) iSeries"
4 select MPIC 4 select MPIC
5 select PCI_MSI
6 select XICS
5 select PPC_I8259 7 select PPC_I8259
6 select PPC_RTAS 8 select PPC_RTAS
9 select PPC_RTAS_DAEMON
7 select RTAS_ERROR_LOGGING 10 select RTAS_ERROR_LOGGING
8 select PPC_UDBG_16550 11 select PPC_UDBG_16550
9 select PPC_NATIVE 12 select PPC_NATIVE
@@ -59,7 +62,7 @@ config PPC_SMLPAR
59 62
60config CMM 63config CMM
61 tristate "Collaborative memory management" 64 tristate "Collaborative memory management"
62 depends on PPC_SMLPAR && !CRASH_DUMP 65 depends on PPC_SMLPAR
63 default y 66 default y
64 help 67 help
65 Select this option, if you want to enable the kernel interface 68 Select this option, if you want to enable the kernel interface
diff --git a/arch/powerpc/platforms/pseries/Makefile b/arch/powerpc/platforms/pseries/Makefile
index 790c0b872d4f..0ff5174ae4f5 100644
--- a/arch/powerpc/platforms/pseries/Makefile
+++ b/arch/powerpc/platforms/pseries/Makefile
@@ -7,8 +7,8 @@ EXTRA_CFLAGS += -DDEBUG
7endif 7endif
8 8
9obj-y := lpar.o hvCall.o nvram.o reconfig.o \ 9obj-y := lpar.o hvCall.o nvram.o reconfig.o \
10 setup.o iommu.o ras.o rtasd.o \ 10 setup.o iommu.o ras.o \
11 firmware.o power.o 11 firmware.o power.o dlpar.o
12obj-$(CONFIG_SMP) += smp.o 12obj-$(CONFIG_SMP) += smp.o
13obj-$(CONFIG_XICS) += xics.o 13obj-$(CONFIG_XICS) += xics.o
14obj-$(CONFIG_SCANLOG) += scanlog.o 14obj-$(CONFIG_SCANLOG) += scanlog.o
diff --git a/arch/powerpc/platforms/pseries/cmm.c b/arch/powerpc/platforms/pseries/cmm.c
index 6567439fe78d..a277f2e28dbc 100644
--- a/arch/powerpc/platforms/pseries/cmm.c
+++ b/arch/powerpc/platforms/pseries/cmm.c
@@ -38,19 +38,28 @@
38#include <asm/mmu.h> 38#include <asm/mmu.h>
39#include <asm/pgalloc.h> 39#include <asm/pgalloc.h>
40#include <asm/uaccess.h> 40#include <asm/uaccess.h>
41#include <linux/memory.h>
41 42
42#include "plpar_wrappers.h" 43#include "plpar_wrappers.h"
43 44
44#define CMM_DRIVER_VERSION "1.0.0" 45#define CMM_DRIVER_VERSION "1.0.0"
45#define CMM_DEFAULT_DELAY 1 46#define CMM_DEFAULT_DELAY 1
47#define CMM_HOTPLUG_DELAY 5
46#define CMM_DEBUG 0 48#define CMM_DEBUG 0
47#define CMM_DISABLE 0 49#define CMM_DISABLE 0
48#define CMM_OOM_KB 1024 50#define CMM_OOM_KB 1024
49#define CMM_MIN_MEM_MB 256 51#define CMM_MIN_MEM_MB 256
50#define KB2PAGES(_p) ((_p)>>(PAGE_SHIFT-10)) 52#define KB2PAGES(_p) ((_p)>>(PAGE_SHIFT-10))
51#define PAGES2KB(_p) ((_p)<<(PAGE_SHIFT-10)) 53#define PAGES2KB(_p) ((_p)<<(PAGE_SHIFT-10))
54/*
55 * The priority level tries to ensure that this notifier is called as
56 * late as possible to reduce thrashing in the shared memory pool.
57 */
58#define CMM_MEM_HOTPLUG_PRI 1
59#define CMM_MEM_ISOLATE_PRI 15
52 60
53static unsigned int delay = CMM_DEFAULT_DELAY; 61static unsigned int delay = CMM_DEFAULT_DELAY;
62static unsigned int hotplug_delay = CMM_HOTPLUG_DELAY;
54static unsigned int oom_kb = CMM_OOM_KB; 63static unsigned int oom_kb = CMM_OOM_KB;
55static unsigned int cmm_debug = CMM_DEBUG; 64static unsigned int cmm_debug = CMM_DEBUG;
56static unsigned int cmm_disabled = CMM_DISABLE; 65static unsigned int cmm_disabled = CMM_DISABLE;
@@ -65,6 +74,10 @@ MODULE_VERSION(CMM_DRIVER_VERSION);
65module_param_named(delay, delay, uint, S_IRUGO | S_IWUSR); 74module_param_named(delay, delay, uint, S_IRUGO | S_IWUSR);
66MODULE_PARM_DESC(delay, "Delay (in seconds) between polls to query hypervisor paging requests. " 75MODULE_PARM_DESC(delay, "Delay (in seconds) between polls to query hypervisor paging requests. "
67 "[Default=" __stringify(CMM_DEFAULT_DELAY) "]"); 76 "[Default=" __stringify(CMM_DEFAULT_DELAY) "]");
77module_param_named(hotplug_delay, hotplug_delay, uint, S_IRUGO | S_IWUSR);
78MODULE_PARM_DESC(delay, "Delay (in seconds) after memory hotplug remove "
79 "before loaning resumes. "
80 "[Default=" __stringify(CMM_HOTPLUG_DELAY) "]");
68module_param_named(oom_kb, oom_kb, uint, S_IRUGO | S_IWUSR); 81module_param_named(oom_kb, oom_kb, uint, S_IRUGO | S_IWUSR);
69MODULE_PARM_DESC(oom_kb, "Amount of memory in kb to free on OOM. " 82MODULE_PARM_DESC(oom_kb, "Amount of memory in kb to free on OOM. "
70 "[Default=" __stringify(CMM_OOM_KB) "]"); 83 "[Default=" __stringify(CMM_OOM_KB) "]");
@@ -92,6 +105,9 @@ static unsigned long oom_freed_pages;
92static struct cmm_page_array *cmm_page_list; 105static struct cmm_page_array *cmm_page_list;
93static DEFINE_SPINLOCK(cmm_lock); 106static DEFINE_SPINLOCK(cmm_lock);
94 107
108static DEFINE_MUTEX(hotplug_mutex);
109static int hotplug_occurred; /* protected by the hotplug mutex */
110
95static struct task_struct *cmm_thread_ptr; 111static struct task_struct *cmm_thread_ptr;
96 112
97/** 113/**
@@ -110,6 +126,17 @@ static long cmm_alloc_pages(long nr)
110 cmm_dbg("Begin request for %ld pages\n", nr); 126 cmm_dbg("Begin request for %ld pages\n", nr);
111 127
112 while (nr) { 128 while (nr) {
129 /* Exit if a hotplug operation is in progress or occurred */
130 if (mutex_trylock(&hotplug_mutex)) {
131 if (hotplug_occurred) {
132 mutex_unlock(&hotplug_mutex);
133 break;
134 }
135 mutex_unlock(&hotplug_mutex);
136 } else {
137 break;
138 }
139
113 addr = __get_free_page(GFP_NOIO | __GFP_NOWARN | 140 addr = __get_free_page(GFP_NOIO | __GFP_NOWARN |
114 __GFP_NORETRY | __GFP_NOMEMALLOC); 141 __GFP_NORETRY | __GFP_NOMEMALLOC);
115 if (!addr) 142 if (!addr)
@@ -119,8 +146,9 @@ static long cmm_alloc_pages(long nr)
119 if (!pa || pa->index >= CMM_NR_PAGES) { 146 if (!pa || pa->index >= CMM_NR_PAGES) {
120 /* Need a new page for the page list. */ 147 /* Need a new page for the page list. */
121 spin_unlock(&cmm_lock); 148 spin_unlock(&cmm_lock);
122 npa = (struct cmm_page_array *)__get_free_page(GFP_NOIO | __GFP_NOWARN | 149 npa = (struct cmm_page_array *)__get_free_page(
123 __GFP_NORETRY | __GFP_NOMEMALLOC); 150 GFP_NOIO | __GFP_NOWARN |
151 __GFP_NORETRY | __GFP_NOMEMALLOC);
124 if (!npa) { 152 if (!npa) {
125 pr_info("%s: Can not allocate new page list\n", __func__); 153 pr_info("%s: Can not allocate new page list\n", __func__);
126 free_page(addr); 154 free_page(addr);
@@ -229,8 +257,9 @@ static void cmm_get_mpp(void)
229{ 257{
230 int rc; 258 int rc;
231 struct hvcall_mpp_data mpp_data; 259 struct hvcall_mpp_data mpp_data;
232 unsigned long active_pages_target; 260 signed long active_pages_target, page_loan_request, target;
233 signed long page_loan_request; 261 signed long total_pages = totalram_pages + loaned_pages;
262 signed long min_mem_pages = (min_mem_mb * 1024 * 1024) / PAGE_SIZE;
234 263
235 rc = h_get_mpp(&mpp_data); 264 rc = h_get_mpp(&mpp_data);
236 265
@@ -238,17 +267,25 @@ static void cmm_get_mpp(void)
238 return; 267 return;
239 268
240 page_loan_request = div_s64((s64)mpp_data.loan_request, PAGE_SIZE); 269 page_loan_request = div_s64((s64)mpp_data.loan_request, PAGE_SIZE);
241 loaned_pages_target = page_loan_request + loaned_pages; 270 target = page_loan_request + (signed long)loaned_pages;
242 if (loaned_pages_target > oom_freed_pages) 271
243 loaned_pages_target -= oom_freed_pages; 272 if (target < 0 || total_pages < min_mem_pages)
273 target = 0;
274
275 if (target > oom_freed_pages)
276 target -= oom_freed_pages;
244 else 277 else
245 loaned_pages_target = 0; 278 target = 0;
279
280 active_pages_target = total_pages - target;
246 281
247 active_pages_target = totalram_pages + loaned_pages - loaned_pages_target; 282 if (min_mem_pages > active_pages_target)
283 target = total_pages - min_mem_pages;
248 284
249 if ((min_mem_mb * 1024 * 1024) > (active_pages_target * PAGE_SIZE)) 285 if (target < 0)
250 loaned_pages_target = totalram_pages + loaned_pages - 286 target = 0;
251 ((min_mem_mb * 1024 * 1024) / PAGE_SIZE); 287
288 loaned_pages_target = target;
252 289
253 cmm_dbg("delta = %ld, loaned = %lu, target = %lu, oom = %lu, totalram = %lu\n", 290 cmm_dbg("delta = %ld, loaned = %lu, target = %lu, oom = %lu, totalram = %lu\n",
254 page_loan_request, loaned_pages, loaned_pages_target, 291 page_loan_request, loaned_pages, loaned_pages_target,
@@ -273,9 +310,28 @@ static int cmm_thread(void *dummy)
273 while (1) { 310 while (1) {
274 timeleft = msleep_interruptible(delay * 1000); 311 timeleft = msleep_interruptible(delay * 1000);
275 312
276 if (kthread_should_stop() || timeleft) { 313 if (kthread_should_stop() || timeleft)
277 loaned_pages_target = loaned_pages;
278 break; 314 break;
315
316 if (mutex_trylock(&hotplug_mutex)) {
317 if (hotplug_occurred) {
318 hotplug_occurred = 0;
319 mutex_unlock(&hotplug_mutex);
320 cmm_dbg("Hotplug operation has occurred, "
321 "loaning activity suspended "
322 "for %d seconds.\n",
323 hotplug_delay);
324 timeleft = msleep_interruptible(hotplug_delay *
325 1000);
326 if (kthread_should_stop() || timeleft)
327 break;
328 continue;
329 }
330 mutex_unlock(&hotplug_mutex);
331 } else {
332 cmm_dbg("Hotplug operation in progress, activity "
333 "suspended\n");
334 continue;
279 } 335 }
280 336
281 cmm_get_mpp(); 337 cmm_get_mpp();
@@ -405,6 +461,193 @@ static struct notifier_block cmm_reboot_nb = {
405}; 461};
406 462
407/** 463/**
464 * cmm_count_pages - Count the number of pages loaned in a particular range.
465 *
466 * @arg: memory_isolate_notify structure with address range and count
467 *
468 * Return value:
469 * 0 on success
470 **/
471static unsigned long cmm_count_pages(void *arg)
472{
473 struct memory_isolate_notify *marg = arg;
474 struct cmm_page_array *pa;
475 unsigned long start = (unsigned long)pfn_to_kaddr(marg->start_pfn);
476 unsigned long end = start + (marg->nr_pages << PAGE_SHIFT);
477 unsigned long idx;
478
479 spin_lock(&cmm_lock);
480 pa = cmm_page_list;
481 while (pa) {
482 if ((unsigned long)pa >= start && (unsigned long)pa < end)
483 marg->pages_found++;
484 for (idx = 0; idx < pa->index; idx++)
485 if (pa->page[idx] >= start && pa->page[idx] < end)
486 marg->pages_found++;
487 pa = pa->next;
488 }
489 spin_unlock(&cmm_lock);
490 return 0;
491}
492
493/**
494 * cmm_memory_isolate_cb - Handle memory isolation notifier calls
495 * @self: notifier block struct
496 * @action: action to take
497 * @arg: struct memory_isolate_notify data for handler
498 *
499 * Return value:
500 * NOTIFY_OK or notifier error based on subfunction return value
501 **/
502static int cmm_memory_isolate_cb(struct notifier_block *self,
503 unsigned long action, void *arg)
504{
505 int ret = 0;
506
507 if (action == MEM_ISOLATE_COUNT)
508 ret = cmm_count_pages(arg);
509
510 if (ret)
511 ret = notifier_from_errno(ret);
512 else
513 ret = NOTIFY_OK;
514
515 return ret;
516}
517
518static struct notifier_block cmm_mem_isolate_nb = {
519 .notifier_call = cmm_memory_isolate_cb,
520 .priority = CMM_MEM_ISOLATE_PRI
521};
522
523/**
524 * cmm_mem_going_offline - Unloan pages where memory is to be removed
525 * @arg: memory_notify structure with page range to be offlined
526 *
527 * Return value:
528 * 0 on success
529 **/
530static int cmm_mem_going_offline(void *arg)
531{
532 struct memory_notify *marg = arg;
533 unsigned long start_page = (unsigned long)pfn_to_kaddr(marg->start_pfn);
534 unsigned long end_page = start_page + (marg->nr_pages << PAGE_SHIFT);
535 struct cmm_page_array *pa_curr, *pa_last, *npa;
536 unsigned long idx;
537 unsigned long freed = 0;
538
539 cmm_dbg("Memory going offline, searching 0x%lx (%ld pages).\n",
540 start_page, marg->nr_pages);
541 spin_lock(&cmm_lock);
542
543 /* Search the page list for pages in the range to be offlined */
544 pa_last = pa_curr = cmm_page_list;
545 while (pa_curr) {
546 for (idx = (pa_curr->index - 1); (idx + 1) > 0; idx--) {
547 if ((pa_curr->page[idx] < start_page) ||
548 (pa_curr->page[idx] >= end_page))
549 continue;
550
551 plpar_page_set_active(__pa(pa_curr->page[idx]));
552 free_page(pa_curr->page[idx]);
553 freed++;
554 loaned_pages--;
555 totalram_pages++;
556 pa_curr->page[idx] = pa_last->page[--pa_last->index];
557 if (pa_last->index == 0) {
558 if (pa_curr == pa_last)
559 pa_curr = pa_last->next;
560 pa_last = pa_last->next;
561 free_page((unsigned long)cmm_page_list);
562 cmm_page_list = pa_last;
563 continue;
564 }
565 }
566 pa_curr = pa_curr->next;
567 }
568
569 /* Search for page list structures in the range to be offlined */
570 pa_last = NULL;
571 pa_curr = cmm_page_list;
572 while (pa_curr) {
573 if (((unsigned long)pa_curr >= start_page) &&
574 ((unsigned long)pa_curr < end_page)) {
575 npa = (struct cmm_page_array *)__get_free_page(
576 GFP_NOIO | __GFP_NOWARN |
577 __GFP_NORETRY | __GFP_NOMEMALLOC);
578 if (!npa) {
579 spin_unlock(&cmm_lock);
580 cmm_dbg("Failed to allocate memory for list "
581 "management. Memory hotplug "
582 "failed.\n");
583 return ENOMEM;
584 }
585 memcpy(npa, pa_curr, PAGE_SIZE);
586 if (pa_curr == cmm_page_list)
587 cmm_page_list = npa;
588 if (pa_last)
589 pa_last->next = npa;
590 free_page((unsigned long) pa_curr);
591 freed++;
592 pa_curr = npa;
593 }
594
595 pa_last = pa_curr;
596 pa_curr = pa_curr->next;
597 }
598
599 spin_unlock(&cmm_lock);
600 cmm_dbg("Released %ld pages in the search range.\n", freed);
601
602 return 0;
603}
604
605/**
606 * cmm_memory_cb - Handle memory hotplug notifier calls
607 * @self: notifier block struct
608 * @action: action to take
609 * @arg: struct memory_notify data for handler
610 *
611 * Return value:
612 * NOTIFY_OK or notifier error based on subfunction return value
613 *
614 **/
615static int cmm_memory_cb(struct notifier_block *self,
616 unsigned long action, void *arg)
617{
618 int ret = 0;
619
620 switch (action) {
621 case MEM_GOING_OFFLINE:
622 mutex_lock(&hotplug_mutex);
623 hotplug_occurred = 1;
624 ret = cmm_mem_going_offline(arg);
625 break;
626 case MEM_OFFLINE:
627 case MEM_CANCEL_OFFLINE:
628 mutex_unlock(&hotplug_mutex);
629 cmm_dbg("Memory offline operation complete.\n");
630 break;
631 case MEM_GOING_ONLINE:
632 case MEM_ONLINE:
633 case MEM_CANCEL_ONLINE:
634 break;
635 }
636
637 if (ret)
638 ret = notifier_from_errno(ret);
639 else
640 ret = NOTIFY_OK;
641
642 return ret;
643}
644
645static struct notifier_block cmm_mem_nb = {
646 .notifier_call = cmm_memory_cb,
647 .priority = CMM_MEM_HOTPLUG_PRI
648};
649
650/**
408 * cmm_init - Module initialization 651 * cmm_init - Module initialization
409 * 652 *
410 * Return value: 653 * Return value:
@@ -426,18 +669,24 @@ static int cmm_init(void)
426 if ((rc = cmm_sysfs_register(&cmm_sysdev))) 669 if ((rc = cmm_sysfs_register(&cmm_sysdev)))
427 goto out_reboot_notifier; 670 goto out_reboot_notifier;
428 671
672 if (register_memory_notifier(&cmm_mem_nb) ||
673 register_memory_isolate_notifier(&cmm_mem_isolate_nb))
674 goto out_unregister_notifier;
675
429 if (cmm_disabled) 676 if (cmm_disabled)
430 return rc; 677 return rc;
431 678
432 cmm_thread_ptr = kthread_run(cmm_thread, NULL, "cmmthread"); 679 cmm_thread_ptr = kthread_run(cmm_thread, NULL, "cmmthread");
433 if (IS_ERR(cmm_thread_ptr)) { 680 if (IS_ERR(cmm_thread_ptr)) {
434 rc = PTR_ERR(cmm_thread_ptr); 681 rc = PTR_ERR(cmm_thread_ptr);
435 goto out_unregister_sysfs; 682 goto out_unregister_notifier;
436 } 683 }
437 684
438 return rc; 685 return rc;
439 686
440out_unregister_sysfs: 687out_unregister_notifier:
688 unregister_memory_notifier(&cmm_mem_nb);
689 unregister_memory_isolate_notifier(&cmm_mem_isolate_nb);
441 cmm_unregister_sysfs(&cmm_sysdev); 690 cmm_unregister_sysfs(&cmm_sysdev);
442out_reboot_notifier: 691out_reboot_notifier:
443 unregister_reboot_notifier(&cmm_reboot_nb); 692 unregister_reboot_notifier(&cmm_reboot_nb);
@@ -458,6 +707,8 @@ static void cmm_exit(void)
458 kthread_stop(cmm_thread_ptr); 707 kthread_stop(cmm_thread_ptr);
459 unregister_oom_notifier(&cmm_oom_nb); 708 unregister_oom_notifier(&cmm_oom_nb);
460 unregister_reboot_notifier(&cmm_reboot_nb); 709 unregister_reboot_notifier(&cmm_reboot_nb);
710 unregister_memory_notifier(&cmm_mem_nb);
711 unregister_memory_isolate_notifier(&cmm_mem_isolate_nb);
461 cmm_free_pages(loaned_pages); 712 cmm_free_pages(loaned_pages);
462 cmm_unregister_sysfs(&cmm_sysdev); 713 cmm_unregister_sysfs(&cmm_sysdev);
463} 714}
diff --git a/arch/powerpc/platforms/pseries/dlpar.c b/arch/powerpc/platforms/pseries/dlpar.c
new file mode 100644
index 000000000000..37bce52526da
--- /dev/null
+++ b/arch/powerpc/platforms/pseries/dlpar.c
@@ -0,0 +1,548 @@
1/*
2 * Support for dynamic reconfiguration for PCI, Memory, and CPU
3 * Hotplug and Dynamic Logical Partitioning on RPA platforms.
4 *
5 * Copyright (C) 2009 Nathan Fontenot
6 * Copyright (C) 2009 IBM Corporation
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License version
10 * 2 as published by the Free Software Foundation.
11 */
12
13#include <linux/kernel.h>
14#include <linux/kref.h>
15#include <linux/notifier.h>
16#include <linux/proc_fs.h>
17#include <linux/spinlock.h>
18#include <linux/cpu.h>
19#include "offline_states.h"
20
21#include <asm/prom.h>
22#include <asm/machdep.h>
23#include <asm/uaccess.h>
24#include <asm/rtas.h>
25#include <asm/pSeries_reconfig.h>
26
27struct cc_workarea {
28 u32 drc_index;
29 u32 zero;
30 u32 name_offset;
31 u32 prop_length;
32 u32 prop_offset;
33};
34
35static void dlpar_free_cc_property(struct property *prop)
36{
37 kfree(prop->name);
38 kfree(prop->value);
39 kfree(prop);
40}
41
42static struct property *dlpar_parse_cc_property(struct cc_workarea *ccwa)
43{
44 struct property *prop;
45 char *name;
46 char *value;
47
48 prop = kzalloc(sizeof(*prop), GFP_KERNEL);
49 if (!prop)
50 return NULL;
51
52 name = (char *)ccwa + ccwa->name_offset;
53 prop->name = kstrdup(name, GFP_KERNEL);
54
55 prop->length = ccwa->prop_length;
56 value = (char *)ccwa + ccwa->prop_offset;
57 prop->value = kzalloc(prop->length, GFP_KERNEL);
58 if (!prop->value) {
59 dlpar_free_cc_property(prop);
60 return NULL;
61 }
62
63 memcpy(prop->value, value, prop->length);
64 return prop;
65}
66
67static struct device_node *dlpar_parse_cc_node(struct cc_workarea *ccwa)
68{
69 struct device_node *dn;
70 char *name;
71
72 dn = kzalloc(sizeof(*dn), GFP_KERNEL);
73 if (!dn)
74 return NULL;
75
76 /* The configure connector reported name does not contain a
77 * preceeding '/', so we allocate a buffer large enough to
78 * prepend this to the full_name.
79 */
80 name = (char *)ccwa + ccwa->name_offset;
81 dn->full_name = kmalloc(strlen(name) + 2, GFP_KERNEL);
82 if (!dn->full_name) {
83 kfree(dn);
84 return NULL;
85 }
86
87 sprintf(dn->full_name, "/%s", name);
88 return dn;
89}
90
91static void dlpar_free_one_cc_node(struct device_node *dn)
92{
93 struct property *prop;
94
95 while (dn->properties) {
96 prop = dn->properties;
97 dn->properties = prop->next;
98 dlpar_free_cc_property(prop);
99 }
100
101 kfree(dn->full_name);
102 kfree(dn);
103}
104
105static void dlpar_free_cc_nodes(struct device_node *dn)
106{
107 if (dn->child)
108 dlpar_free_cc_nodes(dn->child);
109
110 if (dn->sibling)
111 dlpar_free_cc_nodes(dn->sibling);
112
113 dlpar_free_one_cc_node(dn);
114}
115
116#define NEXT_SIBLING 1
117#define NEXT_CHILD 2
118#define NEXT_PROPERTY 3
119#define PREV_PARENT 4
120#define MORE_MEMORY 5
121#define CALL_AGAIN -2
122#define ERR_CFG_USE -9003
123
124struct device_node *dlpar_configure_connector(u32 drc_index)
125{
126 struct device_node *dn;
127 struct device_node *first_dn = NULL;
128 struct device_node *last_dn = NULL;
129 struct property *property;
130 struct property *last_property = NULL;
131 struct cc_workarea *ccwa;
132 int cc_token;
133 int rc;
134
135 cc_token = rtas_token("ibm,configure-connector");
136 if (cc_token == RTAS_UNKNOWN_SERVICE)
137 return NULL;
138
139 spin_lock(&rtas_data_buf_lock);
140 ccwa = (struct cc_workarea *)&rtas_data_buf[0];
141 ccwa->drc_index = drc_index;
142 ccwa->zero = 0;
143
144 rc = rtas_call(cc_token, 2, 1, NULL, rtas_data_buf, NULL);
145 while (rc) {
146 switch (rc) {
147 case NEXT_SIBLING:
148 dn = dlpar_parse_cc_node(ccwa);
149 if (!dn)
150 goto cc_error;
151
152 dn->parent = last_dn->parent;
153 last_dn->sibling = dn;
154 last_dn = dn;
155 break;
156
157 case NEXT_CHILD:
158 dn = dlpar_parse_cc_node(ccwa);
159 if (!dn)
160 goto cc_error;
161
162 if (!first_dn)
163 first_dn = dn;
164 else {
165 dn->parent = last_dn;
166 if (last_dn)
167 last_dn->child = dn;
168 }
169
170 last_dn = dn;
171 break;
172
173 case NEXT_PROPERTY:
174 property = dlpar_parse_cc_property(ccwa);
175 if (!property)
176 goto cc_error;
177
178 if (!last_dn->properties)
179 last_dn->properties = property;
180 else
181 last_property->next = property;
182
183 last_property = property;
184 break;
185
186 case PREV_PARENT:
187 last_dn = last_dn->parent;
188 break;
189
190 case CALL_AGAIN:
191 break;
192
193 case MORE_MEMORY:
194 case ERR_CFG_USE:
195 default:
196 printk(KERN_ERR "Unexpected Error (%d) "
197 "returned from configure-connector\n", rc);
198 goto cc_error;
199 }
200
201 rc = rtas_call(cc_token, 2, 1, NULL, rtas_data_buf, NULL);
202 }
203
204 spin_unlock(&rtas_data_buf_lock);
205 return first_dn;
206
207cc_error:
208 if (first_dn)
209 dlpar_free_cc_nodes(first_dn);
210 spin_unlock(&rtas_data_buf_lock);
211 return NULL;
212}
213
214static struct device_node *derive_parent(const char *path)
215{
216 struct device_node *parent;
217 char *last_slash;
218
219 last_slash = strrchr(path, '/');
220 if (last_slash == path) {
221 parent = of_find_node_by_path("/");
222 } else {
223 char *parent_path;
224 int parent_path_len = last_slash - path + 1;
225 parent_path = kmalloc(parent_path_len, GFP_KERNEL);
226 if (!parent_path)
227 return NULL;
228
229 strlcpy(parent_path, path, parent_path_len);
230 parent = of_find_node_by_path(parent_path);
231 kfree(parent_path);
232 }
233
234 return parent;
235}
236
237int dlpar_attach_node(struct device_node *dn)
238{
239#ifdef CONFIG_PROC_DEVICETREE
240 struct proc_dir_entry *ent;
241#endif
242 int rc;
243
244 of_node_set_flag(dn, OF_DYNAMIC);
245 kref_init(&dn->kref);
246 dn->parent = derive_parent(dn->full_name);
247 if (!dn->parent)
248 return -ENOMEM;
249
250 rc = blocking_notifier_call_chain(&pSeries_reconfig_chain,
251 PSERIES_RECONFIG_ADD, dn);
252 if (rc == NOTIFY_BAD) {
253 printk(KERN_ERR "Failed to add device node %s\n",
254 dn->full_name);
255 return -ENOMEM; /* For now, safe to assume kmalloc failure */
256 }
257
258 of_attach_node(dn);
259
260#ifdef CONFIG_PROC_DEVICETREE
261 ent = proc_mkdir(strrchr(dn->full_name, '/') + 1, dn->parent->pde);
262 if (ent)
263 proc_device_tree_add_node(dn, ent);
264#endif
265
266 of_node_put(dn->parent);
267 return 0;
268}
269
270int dlpar_detach_node(struct device_node *dn)
271{
272#ifdef CONFIG_PROC_DEVICETREE
273 struct device_node *parent = dn->parent;
274 struct property *prop = dn->properties;
275
276 while (prop) {
277 remove_proc_entry(prop->name, dn->pde);
278 prop = prop->next;
279 }
280
281 if (dn->pde)
282 remove_proc_entry(dn->pde->name, parent->pde);
283#endif
284
285 blocking_notifier_call_chain(&pSeries_reconfig_chain,
286 PSERIES_RECONFIG_REMOVE, dn);
287 of_detach_node(dn);
288 of_node_put(dn); /* Must decrement the refcount */
289
290 return 0;
291}
292
293#define DR_ENTITY_SENSE 9003
294#define DR_ENTITY_PRESENT 1
295#define DR_ENTITY_UNUSABLE 2
296#define ALLOCATION_STATE 9003
297#define ALLOC_UNUSABLE 0
298#define ALLOC_USABLE 1
299#define ISOLATION_STATE 9001
300#define ISOLATE 0
301#define UNISOLATE 1
302
303int dlpar_acquire_drc(u32 drc_index)
304{
305 int dr_status, rc;
306
307 rc = rtas_call(rtas_token("get-sensor-state"), 2, 2, &dr_status,
308 DR_ENTITY_SENSE, drc_index);
309 if (rc || dr_status != DR_ENTITY_UNUSABLE)
310 return -1;
311
312 rc = rtas_set_indicator(ALLOCATION_STATE, drc_index, ALLOC_USABLE);
313 if (rc)
314 return rc;
315
316 rc = rtas_set_indicator(ISOLATION_STATE, drc_index, UNISOLATE);
317 if (rc) {
318 rtas_set_indicator(ALLOCATION_STATE, drc_index, ALLOC_UNUSABLE);
319 return rc;
320 }
321
322 return 0;
323}
324
325int dlpar_release_drc(u32 drc_index)
326{
327 int dr_status, rc;
328
329 rc = rtas_call(rtas_token("get-sensor-state"), 2, 2, &dr_status,
330 DR_ENTITY_SENSE, drc_index);
331 if (rc || dr_status != DR_ENTITY_PRESENT)
332 return -1;
333
334 rc = rtas_set_indicator(ISOLATION_STATE, drc_index, ISOLATE);
335 if (rc)
336 return rc;
337
338 rc = rtas_set_indicator(ALLOCATION_STATE, drc_index, ALLOC_UNUSABLE);
339 if (rc) {
340 rtas_set_indicator(ISOLATION_STATE, drc_index, UNISOLATE);
341 return rc;
342 }
343
344 return 0;
345}
346
347#ifdef CONFIG_ARCH_CPU_PROBE_RELEASE
348
349static int dlpar_online_cpu(struct device_node *dn)
350{
351 int rc = 0;
352 unsigned int cpu;
353 int len, nthreads, i;
354 const u32 *intserv;
355
356 intserv = of_get_property(dn, "ibm,ppc-interrupt-server#s", &len);
357 if (!intserv)
358 return -EINVAL;
359
360 nthreads = len / sizeof(u32);
361
362 cpu_maps_update_begin();
363 for (i = 0; i < nthreads; i++) {
364 for_each_present_cpu(cpu) {
365 if (get_hard_smp_processor_id(cpu) != intserv[i])
366 continue;
367 BUG_ON(get_cpu_current_state(cpu)
368 != CPU_STATE_OFFLINE);
369 cpu_maps_update_done();
370 rc = cpu_up(cpu);
371 if (rc)
372 goto out;
373 cpu_maps_update_begin();
374
375 break;
376 }
377 if (cpu == num_possible_cpus())
378 printk(KERN_WARNING "Could not find cpu to online "
379 "with physical id 0x%x\n", intserv[i]);
380 }
381 cpu_maps_update_done();
382
383out:
384 return rc;
385
386}
387
388static ssize_t dlpar_cpu_probe(const char *buf, size_t count)
389{
390 struct device_node *dn;
391 unsigned long drc_index;
392 char *cpu_name;
393 int rc;
394
395 cpu_hotplug_driver_lock();
396 rc = strict_strtoul(buf, 0, &drc_index);
397 if (rc) {
398 rc = -EINVAL;
399 goto out;
400 }
401
402 dn = dlpar_configure_connector(drc_index);
403 if (!dn) {
404 rc = -EINVAL;
405 goto out;
406 }
407
408 /* configure-connector reports cpus as living in the base
409 * directory of the device tree. CPUs actually live in the
410 * cpus directory so we need to fixup the full_name.
411 */
412 cpu_name = kzalloc(strlen(dn->full_name) + strlen("/cpus") + 1,
413 GFP_KERNEL);
414 if (!cpu_name) {
415 dlpar_free_cc_nodes(dn);
416 rc = -ENOMEM;
417 goto out;
418 }
419
420 sprintf(cpu_name, "/cpus%s", dn->full_name);
421 kfree(dn->full_name);
422 dn->full_name = cpu_name;
423
424 rc = dlpar_acquire_drc(drc_index);
425 if (rc) {
426 dlpar_free_cc_nodes(dn);
427 rc = -EINVAL;
428 goto out;
429 }
430
431 rc = dlpar_attach_node(dn);
432 if (rc) {
433 dlpar_release_drc(drc_index);
434 dlpar_free_cc_nodes(dn);
435 }
436
437 rc = dlpar_online_cpu(dn);
438out:
439 cpu_hotplug_driver_unlock();
440
441 return rc ? rc : count;
442}
443
444static int dlpar_offline_cpu(struct device_node *dn)
445{
446 int rc = 0;
447 unsigned int cpu;
448 int len, nthreads, i;
449 const u32 *intserv;
450
451 intserv = of_get_property(dn, "ibm,ppc-interrupt-server#s", &len);
452 if (!intserv)
453 return -EINVAL;
454
455 nthreads = len / sizeof(u32);
456
457 cpu_maps_update_begin();
458 for (i = 0; i < nthreads; i++) {
459 for_each_present_cpu(cpu) {
460 if (get_hard_smp_processor_id(cpu) != intserv[i])
461 continue;
462
463 if (get_cpu_current_state(cpu) == CPU_STATE_OFFLINE)
464 break;
465
466 if (get_cpu_current_state(cpu) == CPU_STATE_ONLINE) {
467 cpu_maps_update_done();
468 rc = cpu_down(cpu);
469 if (rc)
470 goto out;
471 cpu_maps_update_begin();
472 break;
473
474 }
475
476 /*
477 * The cpu is in CPU_STATE_INACTIVE.
478 * Upgrade it's state to CPU_STATE_OFFLINE.
479 */
480 set_preferred_offline_state(cpu, CPU_STATE_OFFLINE);
481 BUG_ON(plpar_hcall_norets(H_PROD, intserv[i])
482 != H_SUCCESS);
483 __cpu_die(cpu);
484 break;
485 }
486 if (cpu == num_possible_cpus())
487 printk(KERN_WARNING "Could not find cpu to offline "
488 "with physical id 0x%x\n", intserv[i]);
489 }
490 cpu_maps_update_done();
491
492out:
493 return rc;
494
495}
496
497static ssize_t dlpar_cpu_release(const char *buf, size_t count)
498{
499 struct device_node *dn;
500 const u32 *drc_index;
501 int rc;
502
503 dn = of_find_node_by_path(buf);
504 if (!dn)
505 return -EINVAL;
506
507 drc_index = of_get_property(dn, "ibm,my-drc-index", NULL);
508 if (!drc_index) {
509 of_node_put(dn);
510 return -EINVAL;
511 }
512
513 cpu_hotplug_driver_lock();
514 rc = dlpar_offline_cpu(dn);
515 if (rc) {
516 of_node_put(dn);
517 rc = -EINVAL;
518 goto out;
519 }
520
521 rc = dlpar_release_drc(*drc_index);
522 if (rc) {
523 of_node_put(dn);
524 goto out;
525 }
526
527 rc = dlpar_detach_node(dn);
528 if (rc) {
529 dlpar_acquire_drc(*drc_index);
530 goto out;
531 }
532
533 of_node_put(dn);
534out:
535 cpu_hotplug_driver_unlock();
536 return rc ? rc : count;
537}
538
539static int __init pseries_dlpar_init(void)
540{
541 ppc_md.cpu_probe = dlpar_cpu_probe;
542 ppc_md.cpu_release = dlpar_cpu_release;
543
544 return 0;
545}
546machine_device_initcall(pseries, pseries_dlpar_init);
547
548#endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */
diff --git a/arch/powerpc/platforms/pseries/dtl.c b/arch/powerpc/platforms/pseries/dtl.c
index 937a544a236d..c5f3116b6ca5 100644
--- a/arch/powerpc/platforms/pseries/dtl.c
+++ b/arch/powerpc/platforms/pseries/dtl.c
@@ -54,7 +54,7 @@ struct dtl {
54 int buf_entries; 54 int buf_entries;
55 u64 last_idx; 55 u64 last_idx;
56}; 56};
57static DEFINE_PER_CPU(struct dtl, dtl); 57static DEFINE_PER_CPU(struct dtl, cpu_dtl);
58 58
59/* 59/*
60 * Dispatch trace log event mask: 60 * Dispatch trace log event mask:
@@ -261,7 +261,7 @@ static int dtl_init(void)
261 261
262 /* set up the per-cpu log structures */ 262 /* set up the per-cpu log structures */
263 for_each_possible_cpu(i) { 263 for_each_possible_cpu(i) {
264 struct dtl *dtl = &per_cpu(dtl, i); 264 struct dtl *dtl = &per_cpu(cpu_dtl, i);
265 dtl->cpu = i; 265 dtl->cpu = i;
266 266
267 rc = dtl_setup_file(dtl); 267 rc = dtl_setup_file(dtl);
diff --git a/arch/powerpc/platforms/pseries/eeh_driver.c b/arch/powerpc/platforms/pseries/eeh_driver.c
index 0e8db6771252..ef8e45448480 100644
--- a/arch/powerpc/platforms/pseries/eeh_driver.c
+++ b/arch/powerpc/platforms/pseries/eeh_driver.c
@@ -63,22 +63,6 @@ static void print_device_node_tree(struct pci_dn *pdn, int dent)
63} 63}
64#endif 64#endif
65 65
66/**
67 * irq_in_use - return true if this irq is being used
68 */
69static int irq_in_use(unsigned int irq)
70{
71 int rc = 0;
72 unsigned long flags;
73 struct irq_desc *desc = irq_desc + irq;
74
75 spin_lock_irqsave(&desc->lock, flags);
76 if (desc->action)
77 rc = 1;
78 spin_unlock_irqrestore(&desc->lock, flags);
79 return rc;
80}
81
82/** 66/**
83 * eeh_disable_irq - disable interrupt for the recovering device 67 * eeh_disable_irq - disable interrupt for the recovering device
84 */ 68 */
@@ -93,7 +77,7 @@ static void eeh_disable_irq(struct pci_dev *dev)
93 if (dev->msi_enabled || dev->msix_enabled) 77 if (dev->msi_enabled || dev->msix_enabled)
94 return; 78 return;
95 79
96 if (!irq_in_use(dev->irq)) 80 if (!irq_has_action(dev->irq))
97 return; 81 return;
98 82
99 PCI_DN(dn)->eeh_mode |= EEH_MODE_IRQ_DISABLED; 83 PCI_DN(dn)->eeh_mode |= EEH_MODE_IRQ_DISABLED;
diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c
index ebff6d9a4e39..6ea4698d9176 100644
--- a/arch/powerpc/platforms/pseries/hotplug-cpu.c
+++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c
@@ -30,6 +30,7 @@
30#include <asm/pSeries_reconfig.h> 30#include <asm/pSeries_reconfig.h>
31#include "xics.h" 31#include "xics.h"
32#include "plpar_wrappers.h" 32#include "plpar_wrappers.h"
33#include "offline_states.h"
33 34
34/* This version can't take the spinlock, because it never returns */ 35/* This version can't take the spinlock, because it never returns */
35static struct rtas_args rtas_stop_self_args = { 36static struct rtas_args rtas_stop_self_args = {
@@ -39,6 +40,55 @@ static struct rtas_args rtas_stop_self_args = {
39 .rets = &rtas_stop_self_args.args[0], 40 .rets = &rtas_stop_self_args.args[0],
40}; 41};
41 42
43static DEFINE_PER_CPU(enum cpu_state_vals, preferred_offline_state) =
44 CPU_STATE_OFFLINE;
45static DEFINE_PER_CPU(enum cpu_state_vals, current_state) = CPU_STATE_OFFLINE;
46
47static enum cpu_state_vals default_offline_state = CPU_STATE_OFFLINE;
48
49static int cede_offline_enabled __read_mostly = 1;
50
51/*
52 * Enable/disable cede_offline when available.
53 */
54static int __init setup_cede_offline(char *str)
55{
56 if (!strcmp(str, "off"))
57 cede_offline_enabled = 0;
58 else if (!strcmp(str, "on"))
59 cede_offline_enabled = 1;
60 else
61 return 0;
62 return 1;
63}
64
65__setup("cede_offline=", setup_cede_offline);
66
67enum cpu_state_vals get_cpu_current_state(int cpu)
68{
69 return per_cpu(current_state, cpu);
70}
71
72void set_cpu_current_state(int cpu, enum cpu_state_vals state)
73{
74 per_cpu(current_state, cpu) = state;
75}
76
77enum cpu_state_vals get_preferred_offline_state(int cpu)
78{
79 return per_cpu(preferred_offline_state, cpu);
80}
81
82void set_preferred_offline_state(int cpu, enum cpu_state_vals state)
83{
84 per_cpu(preferred_offline_state, cpu) = state;
85}
86
87void set_default_offline_state(int cpu)
88{
89 per_cpu(preferred_offline_state, cpu) = default_offline_state;
90}
91
42static void rtas_stop_self(void) 92static void rtas_stop_self(void)
43{ 93{
44 struct rtas_args *args = &rtas_stop_self_args; 94 struct rtas_args *args = &rtas_stop_self_args;
@@ -56,11 +106,61 @@ static void rtas_stop_self(void)
56 106
57static void pseries_mach_cpu_die(void) 107static void pseries_mach_cpu_die(void)
58{ 108{
109 unsigned int cpu = smp_processor_id();
110 unsigned int hwcpu = hard_smp_processor_id();
111 u8 cede_latency_hint = 0;
112
59 local_irq_disable(); 113 local_irq_disable();
60 idle_task_exit(); 114 idle_task_exit();
61 xics_teardown_cpu(); 115 xics_teardown_cpu();
62 unregister_slb_shadow(hard_smp_processor_id(), __pa(get_slb_shadow())); 116
63 rtas_stop_self(); 117 if (get_preferred_offline_state(cpu) == CPU_STATE_INACTIVE) {
118 set_cpu_current_state(cpu, CPU_STATE_INACTIVE);
119 cede_latency_hint = 2;
120
121 get_lppaca()->idle = 1;
122 if (!get_lppaca()->shared_proc)
123 get_lppaca()->donate_dedicated_cpu = 1;
124
125 printk(KERN_INFO
126 "cpu %u (hwid %u) ceding for offline with hint %d\n",
127 cpu, hwcpu, cede_latency_hint);
128 while (get_preferred_offline_state(cpu) == CPU_STATE_INACTIVE) {
129 extended_cede_processor(cede_latency_hint);
130 printk(KERN_INFO "cpu %u (hwid %u) returned from cede.\n",
131 cpu, hwcpu);
132 printk(KERN_INFO
133 "Decrementer value = %x Timebase value = %llx\n",
134 get_dec(), get_tb());
135 }
136
137 printk(KERN_INFO "cpu %u (hwid %u) got prodded to go online\n",
138 cpu, hwcpu);
139
140 if (!get_lppaca()->shared_proc)
141 get_lppaca()->donate_dedicated_cpu = 0;
142 get_lppaca()->idle = 0;
143 }
144
145 if (get_preferred_offline_state(cpu) == CPU_STATE_ONLINE) {
146 unregister_slb_shadow(hwcpu, __pa(get_slb_shadow()));
147
148 /*
149 * NOTE: Calling start_secondary() here for now to
150 * start new context.
151 * However, need to do it cleanly by resetting the
152 * stack pointer.
153 */
154 start_secondary();
155
156 } else if (get_preferred_offline_state(cpu) == CPU_STATE_OFFLINE) {
157
158 set_cpu_current_state(cpu, CPU_STATE_OFFLINE);
159 unregister_slb_shadow(hard_smp_processor_id(),
160 __pa(get_slb_shadow()));
161 rtas_stop_self();
162 }
163
64 /* Should never get here... */ 164 /* Should never get here... */
65 BUG(); 165 BUG();
66 for(;;); 166 for(;;);
@@ -106,18 +206,43 @@ static int pseries_cpu_disable(void)
106 return 0; 206 return 0;
107} 207}
108 208
209/*
210 * pseries_cpu_die: Wait for the cpu to die.
211 * @cpu: logical processor id of the CPU whose death we're awaiting.
212 *
213 * This function is called from the context of the thread which is performing
214 * the cpu-offline. Here we wait for long enough to allow the cpu in question
215 * to self-destroy so that the cpu-offline thread can send the CPU_DEAD
216 * notifications.
217 *
218 * OTOH, pseries_mach_cpu_die() is called by the @cpu when it wants to
219 * self-destruct.
220 */
109static void pseries_cpu_die(unsigned int cpu) 221static void pseries_cpu_die(unsigned int cpu)
110{ 222{
111 int tries; 223 int tries;
112 int cpu_status; 224 int cpu_status = 1;
113 unsigned int pcpu = get_hard_smp_processor_id(cpu); 225 unsigned int pcpu = get_hard_smp_processor_id(cpu);
114 226
115 for (tries = 0; tries < 25; tries++) { 227 if (get_preferred_offline_state(cpu) == CPU_STATE_INACTIVE) {
116 cpu_status = query_cpu_stopped(pcpu); 228 cpu_status = 1;
117 if (cpu_status == 0 || cpu_status == -1) 229 for (tries = 0; tries < 1000; tries++) {
118 break; 230 if (get_cpu_current_state(cpu) == CPU_STATE_INACTIVE) {
119 cpu_relax(); 231 cpu_status = 0;
232 break;
233 }
234 cpu_relax();
235 }
236 } else if (get_preferred_offline_state(cpu) == CPU_STATE_OFFLINE) {
237
238 for (tries = 0; tries < 25; tries++) {
239 cpu_status = query_cpu_stopped(pcpu);
240 if (cpu_status == 0 || cpu_status == -1)
241 break;
242 cpu_relax();
243 }
120 } 244 }
245
121 if (cpu_status != 0) { 246 if (cpu_status != 0) {
122 printk("Querying DEAD? cpu %i (%i) shows %i\n", 247 printk("Querying DEAD? cpu %i (%i) shows %i\n",
123 cpu, pcpu, cpu_status); 248 cpu, pcpu, cpu_status);
@@ -252,10 +377,41 @@ static struct notifier_block pseries_smp_nb = {
252 .notifier_call = pseries_smp_notifier, 377 .notifier_call = pseries_smp_notifier,
253}; 378};
254 379
380#define MAX_CEDE_LATENCY_LEVELS 4
381#define CEDE_LATENCY_PARAM_LENGTH 10
382#define CEDE_LATENCY_PARAM_MAX_LENGTH \
383 (MAX_CEDE_LATENCY_LEVELS * CEDE_LATENCY_PARAM_LENGTH * sizeof(char))
384#define CEDE_LATENCY_TOKEN 45
385
386static char cede_parameters[CEDE_LATENCY_PARAM_MAX_LENGTH];
387
388static int parse_cede_parameters(void)
389{
390 int call_status;
391
392 memset(cede_parameters, 0, CEDE_LATENCY_PARAM_MAX_LENGTH);
393 call_status = rtas_call(rtas_token("ibm,get-system-parameter"), 3, 1,
394 NULL,
395 CEDE_LATENCY_TOKEN,
396 __pa(cede_parameters),
397 CEDE_LATENCY_PARAM_MAX_LENGTH);
398
399 if (call_status != 0)
400 printk(KERN_INFO "CEDE_LATENCY: \
401 %s %s Error calling get-system-parameter(0x%x)\n",
402 __FILE__, __func__, call_status);
403 else
404 printk(KERN_INFO "CEDE_LATENCY: \
405 get-system-parameter successful.\n");
406
407 return call_status;
408}
409
255static int __init pseries_cpu_hotplug_init(void) 410static int __init pseries_cpu_hotplug_init(void)
256{ 411{
257 struct device_node *np; 412 struct device_node *np;
258 const char *typep; 413 const char *typep;
414 int cpu;
259 415
260 for_each_node_by_name(np, "interrupt-controller") { 416 for_each_node_by_name(np, "interrupt-controller") {
261 typep = of_get_property(np, "compatible", NULL); 417 typep = of_get_property(np, "compatible", NULL);
@@ -283,8 +439,16 @@ static int __init pseries_cpu_hotplug_init(void)
283 smp_ops->cpu_die = pseries_cpu_die; 439 smp_ops->cpu_die = pseries_cpu_die;
284 440
285 /* Processors can be added/removed only on LPAR */ 441 /* Processors can be added/removed only on LPAR */
286 if (firmware_has_feature(FW_FEATURE_LPAR)) 442 if (firmware_has_feature(FW_FEATURE_LPAR)) {
287 pSeries_reconfig_notifier_register(&pseries_smp_nb); 443 pSeries_reconfig_notifier_register(&pseries_smp_nb);
444 cpu_maps_update_begin();
445 if (cede_offline_enabled && parse_cede_parameters() == 0) {
446 default_offline_state = CPU_STATE_INACTIVE;
447 for_each_online_cpu(cpu)
448 set_default_offline_state(cpu);
449 }
450 cpu_maps_update_done();
451 }
288 452
289 return 0; 453 return 0;
290} 454}
diff --git a/arch/powerpc/platforms/pseries/hvCall.S b/arch/powerpc/platforms/pseries/hvCall.S
index c1427b3634ec..383a5d0e9818 100644
--- a/arch/powerpc/platforms/pseries/hvCall.S
+++ b/arch/powerpc/platforms/pseries/hvCall.S
@@ -14,68 +14,94 @@
14 14
15#define STK_PARM(i) (48 + ((i)-3)*8) 15#define STK_PARM(i) (48 + ((i)-3)*8)
16 16
17#ifdef CONFIG_HCALL_STATS 17#ifdef CONFIG_TRACEPOINTS
18
19 .section ".toc","aw"
20
21 .globl hcall_tracepoint_refcount
22hcall_tracepoint_refcount:
23 .llong 0
24
25 .section ".text"
26
18/* 27/*
19 * precall must preserve all registers. use unused STK_PARM() 28 * precall must preserve all registers. use unused STK_PARM()
20 * areas to save snapshots and opcode. 29 * areas to save snapshots and opcode. We branch around this
30 * in early init (eg when populating the MMU hashtable) by using an
31 * unconditional cpu feature.
21 */ 32 */
22#define HCALL_INST_PRECALL \ 33#define HCALL_INST_PRECALL(FIRST_REG) \
23 std r3,STK_PARM(r3)(r1); /* save opcode */ \
24 mftb r0; /* get timebase and */ \
25 std r0,STK_PARM(r5)(r1); /* save for later */ \
26BEGIN_FTR_SECTION; \ 34BEGIN_FTR_SECTION; \
27 mfspr r0,SPRN_PURR; /* get PURR and */ \ 35 b 1f; \
28 std r0,STK_PARM(r6)(r1); /* save for later */ \ 36END_FTR_SECTION(0, 1); \
29END_FTR_SECTION_IFSET(CPU_FTR_PURR); 37 ld r12,hcall_tracepoint_refcount@toc(r2); \
30 38 cmpdi r12,0; \
39 beq+ 1f; \
40 mflr r0; \
41 std r3,STK_PARM(r3)(r1); \
42 std r4,STK_PARM(r4)(r1); \
43 std r5,STK_PARM(r5)(r1); \
44 std r6,STK_PARM(r6)(r1); \
45 std r7,STK_PARM(r7)(r1); \
46 std r8,STK_PARM(r8)(r1); \
47 std r9,STK_PARM(r9)(r1); \
48 std r10,STK_PARM(r10)(r1); \
49 std r0,16(r1); \
50 addi r4,r1,STK_PARM(FIRST_REG); \
51 stdu r1,-STACK_FRAME_OVERHEAD(r1); \
52 bl .__trace_hcall_entry; \
53 addi r1,r1,STACK_FRAME_OVERHEAD; \
54 ld r0,16(r1); \
55 ld r3,STK_PARM(r3)(r1); \
56 ld r4,STK_PARM(r4)(r1); \
57 ld r5,STK_PARM(r5)(r1); \
58 ld r6,STK_PARM(r6)(r1); \
59 ld r7,STK_PARM(r7)(r1); \
60 ld r8,STK_PARM(r8)(r1); \
61 ld r9,STK_PARM(r9)(r1); \
62 ld r10,STK_PARM(r10)(r1); \
63 mtlr r0; \
641:
65
31/* 66/*
32 * postcall is performed immediately before function return which 67 * postcall is performed immediately before function return which
33 * allows liberal use of volatile registers. We branch around this 68 * allows liberal use of volatile registers. We branch around this
34 * in early init (eg when populating the MMU hashtable) by using an 69 * in early init (eg when populating the MMU hashtable) by using an
35 * unconditional cpu feature. 70 * unconditional cpu feature.
36 */ 71 */
37#define HCALL_INST_POSTCALL \ 72#define __HCALL_INST_POSTCALL \
38BEGIN_FTR_SECTION; \ 73BEGIN_FTR_SECTION; \
39 b 1f; \ 74 b 1f; \
40END_FTR_SECTION(0, 1); \ 75END_FTR_SECTION(0, 1); \
41 ld r4,STK_PARM(r3)(r1); /* validate opcode */ \ 76 ld r12,hcall_tracepoint_refcount@toc(r2); \
42 cmpldi cr7,r4,MAX_HCALL_OPCODE; \ 77 cmpdi r12,0; \
43 bgt- cr7,1f; \ 78 beq+ 1f; \
44 \ 79 mflr r0; \
45 /* get time and PURR snapshots after hcall */ \ 80 ld r6,STK_PARM(r3)(r1); \
46 mftb r7; /* timebase after */ \ 81 std r3,STK_PARM(r3)(r1); \
47BEGIN_FTR_SECTION; \ 82 mr r4,r3; \
48 mfspr r8,SPRN_PURR; /* PURR after */ \ 83 mr r3,r6; \
49 ld r6,STK_PARM(r6)(r1); /* PURR before */ \ 84 std r0,16(r1); \
50 subf r6,r6,r8; /* delta */ \ 85 stdu r1,-STACK_FRAME_OVERHEAD(r1); \
51END_FTR_SECTION_IFSET(CPU_FTR_PURR); \ 86 bl .__trace_hcall_exit; \
52 ld r5,STK_PARM(r5)(r1); /* timebase before */ \ 87 addi r1,r1,STACK_FRAME_OVERHEAD; \
53 subf r5,r5,r7; /* time delta */ \ 88 ld r0,16(r1); \
54 \ 89 ld r3,STK_PARM(r3)(r1); \
55 /* calculate address of stat structure r4 = opcode */ \ 90 mtlr r0; \
56 srdi r4,r4,2; /* index into array */ \
57 mulli r4,r4,HCALL_STAT_SIZE; \
58 LOAD_REG_ADDR(r7, per_cpu__hcall_stats); \
59 add r4,r4,r7; \
60 ld r7,PACA_DATA_OFFSET(r13); /* per cpu offset */ \
61 add r4,r4,r7; \
62 \
63 /* update stats */ \
64 ld r7,HCALL_STAT_CALLS(r4); /* count */ \
65 addi r7,r7,1; \
66 std r7,HCALL_STAT_CALLS(r4); \
67 ld r7,HCALL_STAT_TB(r4); /* timebase */ \
68 add r7,r7,r5; \
69 std r7,HCALL_STAT_TB(r4); \
70BEGIN_FTR_SECTION; \
71 ld r7,HCALL_STAT_PURR(r4); /* PURR */ \
72 add r7,r7,r6; \
73 std r7,HCALL_STAT_PURR(r4); \
74END_FTR_SECTION_IFSET(CPU_FTR_PURR); \
751: 911:
92
93#define HCALL_INST_POSTCALL_NORETS \
94 li r5,0; \
95 __HCALL_INST_POSTCALL
96
97#define HCALL_INST_POSTCALL(BUFREG) \
98 mr r5,BUFREG; \
99 __HCALL_INST_POSTCALL
100
76#else 101#else
77#define HCALL_INST_PRECALL 102#define HCALL_INST_PRECALL(FIRST_ARG)
78#define HCALL_INST_POSTCALL 103#define HCALL_INST_POSTCALL_NORETS
104#define HCALL_INST_POSTCALL(BUFREG)
79#endif 105#endif
80 106
81 .text 107 .text
@@ -86,11 +112,11 @@ _GLOBAL(plpar_hcall_norets)
86 mfcr r0 112 mfcr r0
87 stw r0,8(r1) 113 stw r0,8(r1)
88 114
89 HCALL_INST_PRECALL 115 HCALL_INST_PRECALL(r4)
90 116
91 HVSC /* invoke the hypervisor */ 117 HVSC /* invoke the hypervisor */
92 118
93 HCALL_INST_POSTCALL 119 HCALL_INST_POSTCALL_NORETS
94 120
95 lwz r0,8(r1) 121 lwz r0,8(r1)
96 mtcrf 0xff,r0 122 mtcrf 0xff,r0
@@ -102,7 +128,7 @@ _GLOBAL(plpar_hcall)
102 mfcr r0 128 mfcr r0
103 stw r0,8(r1) 129 stw r0,8(r1)
104 130
105 HCALL_INST_PRECALL 131 HCALL_INST_PRECALL(r5)
106 132
107 std r4,STK_PARM(r4)(r1) /* Save ret buffer */ 133 std r4,STK_PARM(r4)(r1) /* Save ret buffer */
108 134
@@ -121,7 +147,7 @@ _GLOBAL(plpar_hcall)
121 std r6, 16(r12) 147 std r6, 16(r12)
122 std r7, 24(r12) 148 std r7, 24(r12)
123 149
124 HCALL_INST_POSTCALL 150 HCALL_INST_POSTCALL(r12)
125 151
126 lwz r0,8(r1) 152 lwz r0,8(r1)
127 mtcrf 0xff,r0 153 mtcrf 0xff,r0
@@ -168,7 +194,7 @@ _GLOBAL(plpar_hcall9)
168 mfcr r0 194 mfcr r0
169 stw r0,8(r1) 195 stw r0,8(r1)
170 196
171 HCALL_INST_PRECALL 197 HCALL_INST_PRECALL(r5)
172 198
173 std r4,STK_PARM(r4)(r1) /* Save ret buffer */ 199 std r4,STK_PARM(r4)(r1) /* Save ret buffer */
174 200
@@ -196,7 +222,7 @@ _GLOBAL(plpar_hcall9)
196 std r11,56(r12) 222 std r11,56(r12)
197 std r0, 64(r12) 223 std r0, 64(r12)
198 224
199 HCALL_INST_POSTCALL 225 HCALL_INST_POSTCALL(r12)
200 226
201 lwz r0,8(r1) 227 lwz r0,8(r1)
202 mtcrf 0xff,r0 228 mtcrf 0xff,r0
diff --git a/arch/powerpc/platforms/pseries/hvCall_inst.c b/arch/powerpc/platforms/pseries/hvCall_inst.c
index 3631a4f277eb..2f58c71b7259 100644
--- a/arch/powerpc/platforms/pseries/hvCall_inst.c
+++ b/arch/powerpc/platforms/pseries/hvCall_inst.c
@@ -26,6 +26,7 @@
26#include <asm/hvcall.h> 26#include <asm/hvcall.h>
27#include <asm/firmware.h> 27#include <asm/firmware.h>
28#include <asm/cputable.h> 28#include <asm/cputable.h>
29#include <asm/trace.h>
29 30
30DEFINE_PER_CPU(struct hcall_stats[HCALL_STAT_ARRAY_SIZE], hcall_stats); 31DEFINE_PER_CPU(struct hcall_stats[HCALL_STAT_ARRAY_SIZE], hcall_stats);
31 32
@@ -100,6 +101,35 @@ static const struct file_operations hcall_inst_seq_fops = {
100#define HCALL_ROOT_DIR "hcall_inst" 101#define HCALL_ROOT_DIR "hcall_inst"
101#define CPU_NAME_BUF_SIZE 32 102#define CPU_NAME_BUF_SIZE 32
102 103
104
105static void probe_hcall_entry(unsigned long opcode, unsigned long *args)
106{
107 struct hcall_stats *h;
108
109 if (opcode > MAX_HCALL_OPCODE)
110 return;
111
112 h = &get_cpu_var(hcall_stats)[opcode / 4];
113 h->tb_start = mftb();
114 h->purr_start = mfspr(SPRN_PURR);
115}
116
117static void probe_hcall_exit(unsigned long opcode, unsigned long retval,
118 unsigned long *retbuf)
119{
120 struct hcall_stats *h;
121
122 if (opcode > MAX_HCALL_OPCODE)
123 return;
124
125 h = &__get_cpu_var(hcall_stats)[opcode / 4];
126 h->num_calls++;
127 h->tb_total = mftb() - h->tb_start;
128 h->purr_total = mfspr(SPRN_PURR) - h->purr_start;
129
130 put_cpu_var(hcall_stats);
131}
132
103static int __init hcall_inst_init(void) 133static int __init hcall_inst_init(void)
104{ 134{
105 struct dentry *hcall_root; 135 struct dentry *hcall_root;
@@ -110,6 +140,14 @@ static int __init hcall_inst_init(void)
110 if (!firmware_has_feature(FW_FEATURE_LPAR)) 140 if (!firmware_has_feature(FW_FEATURE_LPAR))
111 return 0; 141 return 0;
112 142
143 if (register_trace_hcall_entry(probe_hcall_entry))
144 return -EINVAL;
145
146 if (register_trace_hcall_exit(probe_hcall_exit)) {
147 unregister_trace_hcall_entry(probe_hcall_entry);
148 return -EINVAL;
149 }
150
113 hcall_root = debugfs_create_dir(HCALL_ROOT_DIR, NULL); 151 hcall_root = debugfs_create_dir(HCALL_ROOT_DIR, NULL);
114 if (!hcall_root) 152 if (!hcall_root)
115 return -ENOMEM; 153 return -ENOMEM;
diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c
index 903eb9eec687..0707653612ba 100644
--- a/arch/powerpc/platforms/pseries/lpar.c
+++ b/arch/powerpc/platforms/pseries/lpar.c
@@ -39,6 +39,7 @@
39#include <asm/cputable.h> 39#include <asm/cputable.h>
40#include <asm/udbg.h> 40#include <asm/udbg.h>
41#include <asm/smp.h> 41#include <asm/smp.h>
42#include <asm/trace.h>
42 43
43#include "plpar_wrappers.h" 44#include "plpar_wrappers.h"
44#include "pseries.h" 45#include "pseries.h"
@@ -661,3 +662,35 @@ void arch_free_page(struct page *page, int order)
661EXPORT_SYMBOL(arch_free_page); 662EXPORT_SYMBOL(arch_free_page);
662 663
663#endif 664#endif
665
666#ifdef CONFIG_TRACEPOINTS
667/*
668 * We optimise our hcall path by placing hcall_tracepoint_refcount
669 * directly in the TOC so we can check if the hcall tracepoints are
670 * enabled via a single load.
671 */
672
673/* NB: reg/unreg are called while guarded with the tracepoints_mutex */
674extern long hcall_tracepoint_refcount;
675
676void hcall_tracepoint_regfunc(void)
677{
678 hcall_tracepoint_refcount++;
679}
680
681void hcall_tracepoint_unregfunc(void)
682{
683 hcall_tracepoint_refcount--;
684}
685
686void __trace_hcall_entry(unsigned long opcode, unsigned long *args)
687{
688 trace_hcall_entry(opcode, args);
689}
690
691void __trace_hcall_exit(long opcode, unsigned long retval,
692 unsigned long *retbuf)
693{
694 trace_hcall_exit(opcode, retval, retbuf);
695}
696#endif
diff --git a/arch/powerpc/platforms/pseries/offline_states.h b/arch/powerpc/platforms/pseries/offline_states.h
new file mode 100644
index 000000000000..22574e0d9d91
--- /dev/null
+++ b/arch/powerpc/platforms/pseries/offline_states.h
@@ -0,0 +1,18 @@
1#ifndef _OFFLINE_STATES_H_
2#define _OFFLINE_STATES_H_
3
4/* Cpu offline states go here */
5enum cpu_state_vals {
6 CPU_STATE_OFFLINE,
7 CPU_STATE_INACTIVE,
8 CPU_STATE_ONLINE,
9 CPU_MAX_OFFLINE_STATES
10};
11
12extern enum cpu_state_vals get_cpu_current_state(int cpu);
13extern void set_cpu_current_state(int cpu, enum cpu_state_vals state);
14extern enum cpu_state_vals get_preferred_offline_state(int cpu);
15extern void set_preferred_offline_state(int cpu, enum cpu_state_vals state);
16extern void set_default_offline_state(int cpu);
17extern int start_secondary(void);
18#endif
diff --git a/arch/powerpc/platforms/pseries/plpar_wrappers.h b/arch/powerpc/platforms/pseries/plpar_wrappers.h
index a24a6b2333b2..0603c91538ae 100644
--- a/arch/powerpc/platforms/pseries/plpar_wrappers.h
+++ b/arch/powerpc/platforms/pseries/plpar_wrappers.h
@@ -9,11 +9,33 @@ static inline long poll_pending(void)
9 return plpar_hcall_norets(H_POLL_PENDING); 9 return plpar_hcall_norets(H_POLL_PENDING);
10} 10}
11 11
12static inline u8 get_cede_latency_hint(void)
13{
14 return get_lppaca()->gpr5_dword.fields.cede_latency_hint;
15}
16
17static inline void set_cede_latency_hint(u8 latency_hint)
18{
19 get_lppaca()->gpr5_dword.fields.cede_latency_hint = latency_hint;
20}
21
12static inline long cede_processor(void) 22static inline long cede_processor(void)
13{ 23{
14 return plpar_hcall_norets(H_CEDE); 24 return plpar_hcall_norets(H_CEDE);
15} 25}
16 26
27static inline long extended_cede_processor(unsigned long latency_hint)
28{
29 long rc;
30 u8 old_latency_hint = get_cede_latency_hint();
31
32 set_cede_latency_hint(latency_hint);
33 rc = cede_processor();
34 set_cede_latency_hint(old_latency_hint);
35
36 return rc;
37}
38
17static inline long vpa_call(unsigned long flags, unsigned long cpu, 39static inline long vpa_call(unsigned long flags, unsigned long cpu,
18 unsigned long vpa) 40 unsigned long vpa)
19{ 41{
diff --git a/arch/powerpc/platforms/pseries/reconfig.c b/arch/powerpc/platforms/pseries/reconfig.c
index 2e2bbe120b90..a2305d29bbbd 100644
--- a/arch/powerpc/platforms/pseries/reconfig.c
+++ b/arch/powerpc/platforms/pseries/reconfig.c
@@ -96,7 +96,7 @@ static struct device_node *derive_parent(const char *path)
96 return parent; 96 return parent;
97} 97}
98 98
99static BLOCKING_NOTIFIER_HEAD(pSeries_reconfig_chain); 99BLOCKING_NOTIFIER_HEAD(pSeries_reconfig_chain);
100 100
101int pSeries_reconfig_notifier_register(struct notifier_block *nb) 101int pSeries_reconfig_notifier_register(struct notifier_block *nb)
102{ 102{
@@ -184,7 +184,7 @@ static int pSeries_reconfig_remove_node(struct device_node *np)
184} 184}
185 185
186/* 186/*
187 * /proc/ppc64/ofdt - yucky binary interface for adding and removing 187 * /proc/powerpc/ofdt - yucky binary interface for adding and removing
188 * OF device nodes. Should be deprecated as soon as we get an 188 * OF device nodes. Should be deprecated as soon as we get an
189 * in-kernel wrapper for the RTAS ibm,configure-connector call. 189 * in-kernel wrapper for the RTAS ibm,configure-connector call.
190 */ 190 */
@@ -543,7 +543,7 @@ static const struct file_operations ofdt_fops = {
543 .write = ofdt_write 543 .write = ofdt_write
544}; 544};
545 545
546/* create /proc/ppc64/ofdt write-only by root */ 546/* create /proc/powerpc/ofdt write-only by root */
547static int proc_ppc64_create_ofdt(void) 547static int proc_ppc64_create_ofdt(void)
548{ 548{
549 struct proc_dir_entry *ent; 549 struct proc_dir_entry *ent;
@@ -551,7 +551,7 @@ static int proc_ppc64_create_ofdt(void)
551 if (!machine_is(pseries)) 551 if (!machine_is(pseries))
552 return 0; 552 return 0;
553 553
554 ent = proc_create("ppc64/ofdt", S_IWUSR, NULL, &ofdt_fops); 554 ent = proc_create("powerpc/ofdt", S_IWUSR, NULL, &ofdt_fops);
555 if (ent) 555 if (ent)
556 ent->size = 0; 556 ent->size = 0;
557 557
diff --git a/arch/powerpc/platforms/pseries/rtasd.c b/arch/powerpc/platforms/pseries/rtasd.c
deleted file mode 100644
index b3cbac855924..000000000000
--- a/arch/powerpc/platforms/pseries/rtasd.c
+++ /dev/null
@@ -1,519 +0,0 @@
1/*
2 * Copyright (C) 2001 Anton Blanchard <anton@au.ibm.com>, IBM
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 *
9 * Communication to userspace based on kernel/printk.c
10 */
11
12#include <linux/types.h>
13#include <linux/errno.h>
14#include <linux/sched.h>
15#include <linux/kernel.h>
16#include <linux/poll.h>
17#include <linux/proc_fs.h>
18#include <linux/init.h>
19#include <linux/vmalloc.h>
20#include <linux/spinlock.h>
21#include <linux/cpu.h>
22#include <linux/workqueue.h>
23
24#include <asm/uaccess.h>
25#include <asm/io.h>
26#include <asm/rtas.h>
27#include <asm/prom.h>
28#include <asm/nvram.h>
29#include <asm/atomic.h>
30#include <asm/machdep.h>
31
32
33static DEFINE_SPINLOCK(rtasd_log_lock);
34
35static DECLARE_WAIT_QUEUE_HEAD(rtas_log_wait);
36
37static char *rtas_log_buf;
38static unsigned long rtas_log_start;
39static unsigned long rtas_log_size;
40
41static int surveillance_timeout = -1;
42static unsigned int rtas_error_log_max;
43static unsigned int rtas_error_log_buffer_max;
44
45/* RTAS service tokens */
46static unsigned int event_scan;
47static unsigned int rtas_event_scan_rate;
48
49static int full_rtas_msgs = 0;
50
51/* Stop logging to nvram after first fatal error */
52static int logging_enabled; /* Until we initialize everything,
53 * make sure we don't try logging
54 * anything */
55static int error_log_cnt;
56
57/*
58 * Since we use 32 bit RTAS, the physical address of this must be below
59 * 4G or else bad things happen. Allocate this in the kernel data and
60 * make it big enough.
61 */
62static unsigned char logdata[RTAS_ERROR_LOG_MAX];
63
64static char *rtas_type[] = {
65 "Unknown", "Retry", "TCE Error", "Internal Device Failure",
66 "Timeout", "Data Parity", "Address Parity", "Cache Parity",
67 "Address Invalid", "ECC Uncorrected", "ECC Corrupted",
68};
69
70static char *rtas_event_type(int type)
71{
72 if ((type > 0) && (type < 11))
73 return rtas_type[type];
74
75 switch (type) {
76 case RTAS_TYPE_EPOW:
77 return "EPOW";
78 case RTAS_TYPE_PLATFORM:
79 return "Platform Error";
80 case RTAS_TYPE_IO:
81 return "I/O Event";
82 case RTAS_TYPE_INFO:
83 return "Platform Information Event";
84 case RTAS_TYPE_DEALLOC:
85 return "Resource Deallocation Event";
86 case RTAS_TYPE_DUMP:
87 return "Dump Notification Event";
88 }
89
90 return rtas_type[0];
91}
92
93/* To see this info, grep RTAS /var/log/messages and each entry
94 * will be collected together with obvious begin/end.
95 * There will be a unique identifier on the begin and end lines.
96 * This will persist across reboots.
97 *
98 * format of error logs returned from RTAS:
99 * bytes (size) : contents
100 * --------------------------------------------------------
101 * 0-7 (8) : rtas_error_log
102 * 8-47 (40) : extended info
103 * 48-51 (4) : vendor id
104 * 52-1023 (vendor specific) : location code and debug data
105 */
106static void printk_log_rtas(char *buf, int len)
107{
108
109 int i,j,n = 0;
110 int perline = 16;
111 char buffer[64];
112 char * str = "RTAS event";
113
114 if (full_rtas_msgs) {
115 printk(RTAS_DEBUG "%d -------- %s begin --------\n",
116 error_log_cnt, str);
117
118 /*
119 * Print perline bytes on each line, each line will start
120 * with RTAS and a changing number, so syslogd will
121 * print lines that are otherwise the same. Separate every
122 * 4 bytes with a space.
123 */
124 for (i = 0; i < len; i++) {
125 j = i % perline;
126 if (j == 0) {
127 memset(buffer, 0, sizeof(buffer));
128 n = sprintf(buffer, "RTAS %d:", i/perline);
129 }
130
131 if ((i % 4) == 0)
132 n += sprintf(buffer+n, " ");
133
134 n += sprintf(buffer+n, "%02x", (unsigned char)buf[i]);
135
136 if (j == (perline-1))
137 printk(KERN_DEBUG "%s\n", buffer);
138 }
139 if ((i % perline) != 0)
140 printk(KERN_DEBUG "%s\n", buffer);
141
142 printk(RTAS_DEBUG "%d -------- %s end ----------\n",
143 error_log_cnt, str);
144 } else {
145 struct rtas_error_log *errlog = (struct rtas_error_log *)buf;
146
147 printk(RTAS_DEBUG "event: %d, Type: %s, Severity: %d\n",
148 error_log_cnt, rtas_event_type(errlog->type),
149 errlog->severity);
150 }
151}
152
153static int log_rtas_len(char * buf)
154{
155 int len;
156 struct rtas_error_log *err;
157
158 /* rtas fixed header */
159 len = 8;
160 err = (struct rtas_error_log *)buf;
161 if (err->extended_log_length) {
162
163 /* extended header */
164 len += err->extended_log_length;
165 }
166
167 if (rtas_error_log_max == 0)
168 rtas_error_log_max = rtas_get_error_log_max();
169
170 if (len > rtas_error_log_max)
171 len = rtas_error_log_max;
172
173 return len;
174}
175
176/*
177 * First write to nvram, if fatal error, that is the only
178 * place we log the info. The error will be picked up
179 * on the next reboot by rtasd. If not fatal, run the
180 * method for the type of error. Currently, only RTAS
181 * errors have methods implemented, but in the future
182 * there might be a need to store data in nvram before a
183 * call to panic().
184 *
185 * XXX We write to nvram periodically, to indicate error has
186 * been written and sync'd, but there is a possibility
187 * that if we don't shutdown correctly, a duplicate error
188 * record will be created on next reboot.
189 */
190void pSeries_log_error(char *buf, unsigned int err_type, int fatal)
191{
192 unsigned long offset;
193 unsigned long s;
194 int len = 0;
195
196 pr_debug("rtasd: logging event\n");
197 if (buf == NULL)
198 return;
199
200 spin_lock_irqsave(&rtasd_log_lock, s);
201
202 /* get length and increase count */
203 switch (err_type & ERR_TYPE_MASK) {
204 case ERR_TYPE_RTAS_LOG:
205 len = log_rtas_len(buf);
206 if (!(err_type & ERR_FLAG_BOOT))
207 error_log_cnt++;
208 break;
209 case ERR_TYPE_KERNEL_PANIC:
210 default:
211 WARN_ON_ONCE(!irqs_disabled()); /* @@@ DEBUG @@@ */
212 spin_unlock_irqrestore(&rtasd_log_lock, s);
213 return;
214 }
215
216 /* Write error to NVRAM */
217 if (logging_enabled && !(err_type & ERR_FLAG_BOOT))
218 nvram_write_error_log(buf, len, err_type, error_log_cnt);
219
220 /*
221 * rtas errors can occur during boot, and we do want to capture
222 * those somewhere, even if nvram isn't ready (why not?), and even
223 * if rtasd isn't ready. Put them into the boot log, at least.
224 */
225 if ((err_type & ERR_TYPE_MASK) == ERR_TYPE_RTAS_LOG)
226 printk_log_rtas(buf, len);
227
228 /* Check to see if we need to or have stopped logging */
229 if (fatal || !logging_enabled) {
230 logging_enabled = 0;
231 WARN_ON_ONCE(!irqs_disabled()); /* @@@ DEBUG @@@ */
232 spin_unlock_irqrestore(&rtasd_log_lock, s);
233 return;
234 }
235
236 /* call type specific method for error */
237 switch (err_type & ERR_TYPE_MASK) {
238 case ERR_TYPE_RTAS_LOG:
239 offset = rtas_error_log_buffer_max *
240 ((rtas_log_start+rtas_log_size) & LOG_NUMBER_MASK);
241
242 /* First copy over sequence number */
243 memcpy(&rtas_log_buf[offset], (void *) &error_log_cnt, sizeof(int));
244
245 /* Second copy over error log data */
246 offset += sizeof(int);
247 memcpy(&rtas_log_buf[offset], buf, len);
248
249 if (rtas_log_size < LOG_NUMBER)
250 rtas_log_size += 1;
251 else
252 rtas_log_start += 1;
253
254 WARN_ON_ONCE(!irqs_disabled()); /* @@@ DEBUG @@@ */
255 spin_unlock_irqrestore(&rtasd_log_lock, s);
256 wake_up_interruptible(&rtas_log_wait);
257 break;
258 case ERR_TYPE_KERNEL_PANIC:
259 default:
260 WARN_ON_ONCE(!irqs_disabled()); /* @@@ DEBUG @@@ */
261 spin_unlock_irqrestore(&rtasd_log_lock, s);
262 return;
263 }
264
265}
266
267
268static int rtas_log_open(struct inode * inode, struct file * file)
269{
270 return 0;
271}
272
273static int rtas_log_release(struct inode * inode, struct file * file)
274{
275 return 0;
276}
277
278/* This will check if all events are logged, if they are then, we
279 * know that we can safely clear the events in NVRAM.
280 * Next we'll sit and wait for something else to log.
281 */
282static ssize_t rtas_log_read(struct file * file, char __user * buf,
283 size_t count, loff_t *ppos)
284{
285 int error;
286 char *tmp;
287 unsigned long s;
288 unsigned long offset;
289
290 if (!buf || count < rtas_error_log_buffer_max)
291 return -EINVAL;
292
293 count = rtas_error_log_buffer_max;
294
295 if (!access_ok(VERIFY_WRITE, buf, count))
296 return -EFAULT;
297
298 tmp = kmalloc(count, GFP_KERNEL);
299 if (!tmp)
300 return -ENOMEM;
301
302 spin_lock_irqsave(&rtasd_log_lock, s);
303 /* if it's 0, then we know we got the last one (the one in NVRAM) */
304 while (rtas_log_size == 0) {
305 if (file->f_flags & O_NONBLOCK) {
306 spin_unlock_irqrestore(&rtasd_log_lock, s);
307 error = -EAGAIN;
308 goto out;
309 }
310
311 if (!logging_enabled) {
312 spin_unlock_irqrestore(&rtasd_log_lock, s);
313 error = -ENODATA;
314 goto out;
315 }
316 nvram_clear_error_log();
317
318 spin_unlock_irqrestore(&rtasd_log_lock, s);
319 error = wait_event_interruptible(rtas_log_wait, rtas_log_size);
320 if (error)
321 goto out;
322 spin_lock_irqsave(&rtasd_log_lock, s);
323 }
324
325 offset = rtas_error_log_buffer_max * (rtas_log_start & LOG_NUMBER_MASK);
326 memcpy(tmp, &rtas_log_buf[offset], count);
327
328 rtas_log_start += 1;
329 rtas_log_size -= 1;
330 spin_unlock_irqrestore(&rtasd_log_lock, s);
331
332 error = copy_to_user(buf, tmp, count) ? -EFAULT : count;
333out:
334 kfree(tmp);
335 return error;
336}
337
338static unsigned int rtas_log_poll(struct file *file, poll_table * wait)
339{
340 poll_wait(file, &rtas_log_wait, wait);
341 if (rtas_log_size)
342 return POLLIN | POLLRDNORM;
343 return 0;
344}
345
346static const struct file_operations proc_rtas_log_operations = {
347 .read = rtas_log_read,
348 .poll = rtas_log_poll,
349 .open = rtas_log_open,
350 .release = rtas_log_release,
351};
352
353static int enable_surveillance(int timeout)
354{
355 int error;
356
357 error = rtas_set_indicator(SURVEILLANCE_TOKEN, 0, timeout);
358
359 if (error == 0)
360 return 0;
361
362 if (error == -EINVAL) {
363 printk(KERN_DEBUG "rtasd: surveillance not supported\n");
364 return 0;
365 }
366
367 printk(KERN_ERR "rtasd: could not update surveillance\n");
368 return -1;
369}
370
371static void do_event_scan(void)
372{
373 int error;
374 do {
375 memset(logdata, 0, rtas_error_log_max);
376 error = rtas_call(event_scan, 4, 1, NULL,
377 RTAS_EVENT_SCAN_ALL_EVENTS, 0,
378 __pa(logdata), rtas_error_log_max);
379 if (error == -1) {
380 printk(KERN_ERR "event-scan failed\n");
381 break;
382 }
383
384 if (error == 0)
385 pSeries_log_error(logdata, ERR_TYPE_RTAS_LOG, 0);
386
387 } while(error == 0);
388}
389
390static void rtas_event_scan(struct work_struct *w);
391DECLARE_DELAYED_WORK(event_scan_work, rtas_event_scan);
392
393/*
394 * Delay should be at least one second since some machines have problems if
395 * we call event-scan too quickly.
396 */
397static unsigned long event_scan_delay = 1*HZ;
398static int first_pass = 1;
399
400static void rtas_event_scan(struct work_struct *w)
401{
402 unsigned int cpu;
403
404 do_event_scan();
405
406 get_online_cpus();
407
408 cpu = next_cpu(smp_processor_id(), cpu_online_map);
409 if (cpu == NR_CPUS) {
410 cpu = first_cpu(cpu_online_map);
411
412 if (first_pass) {
413 first_pass = 0;
414 event_scan_delay = 30*HZ/rtas_event_scan_rate;
415
416 if (surveillance_timeout != -1) {
417 pr_debug("rtasd: enabling surveillance\n");
418 enable_surveillance(surveillance_timeout);
419 pr_debug("rtasd: surveillance enabled\n");
420 }
421 }
422 }
423
424 schedule_delayed_work_on(cpu, &event_scan_work,
425 __round_jiffies_relative(event_scan_delay, cpu));
426
427 put_online_cpus();
428}
429
430static void start_event_scan(void)
431{
432 unsigned int err_type;
433 int rc;
434
435 printk(KERN_DEBUG "RTAS daemon started\n");
436 pr_debug("rtasd: will sleep for %d milliseconds\n",
437 (30000 / rtas_event_scan_rate));
438
439 /* See if we have any error stored in NVRAM */
440 memset(logdata, 0, rtas_error_log_max);
441 rc = nvram_read_error_log(logdata, rtas_error_log_max,
442 &err_type, &error_log_cnt);
443 /* We can use rtas_log_buf now */
444 logging_enabled = 1;
445
446 if (!rc) {
447 if (err_type != ERR_FLAG_ALREADY_LOGGED) {
448 pSeries_log_error(logdata, err_type | ERR_FLAG_BOOT, 0);
449 }
450 }
451
452 schedule_delayed_work_on(first_cpu(cpu_online_map), &event_scan_work,
453 event_scan_delay);
454}
455
456static int __init rtas_init(void)
457{
458 struct proc_dir_entry *entry;
459
460 if (!machine_is(pseries))
461 return 0;
462
463 /* No RTAS */
464 event_scan = rtas_token("event-scan");
465 if (event_scan == RTAS_UNKNOWN_SERVICE) {
466 printk(KERN_DEBUG "rtasd: no event-scan on system\n");
467 return -ENODEV;
468 }
469
470 rtas_event_scan_rate = rtas_token("rtas-event-scan-rate");
471 if (rtas_event_scan_rate == RTAS_UNKNOWN_SERVICE) {
472 printk(KERN_ERR "rtasd: no rtas-event-scan-rate on system\n");
473 return -ENODEV;
474 }
475
476 /* Make room for the sequence number */
477 rtas_error_log_max = rtas_get_error_log_max();
478 rtas_error_log_buffer_max = rtas_error_log_max + sizeof(int);
479
480 rtas_log_buf = vmalloc(rtas_error_log_buffer_max*LOG_NUMBER);
481 if (!rtas_log_buf) {
482 printk(KERN_ERR "rtasd: no memory\n");
483 return -ENOMEM;
484 }
485
486 entry = proc_create("ppc64/rtas/error_log", S_IRUSR, NULL,
487 &proc_rtas_log_operations);
488 if (!entry)
489 printk(KERN_ERR "Failed to create error_log proc entry\n");
490
491 start_event_scan();
492
493 return 0;
494}
495
496static int __init surveillance_setup(char *str)
497{
498 int i;
499
500 if (get_option(&str,&i)) {
501 if (i >= 0 && i <= 255)
502 surveillance_timeout = i;
503 }
504
505 return 1;
506}
507
508static int __init rtasmsgs_setup(char *str)
509{
510 if (strcmp(str, "on") == 0)
511 full_rtas_msgs = 1;
512 else if (strcmp(str, "off") == 0)
513 full_rtas_msgs = 0;
514
515 return 1;
516}
517__initcall(rtas_init);
518__setup("surveillance=", surveillance_setup);
519__setup("rtasmsgs=", rtasmsgs_setup);
diff --git a/arch/powerpc/platforms/pseries/scanlog.c b/arch/powerpc/platforms/pseries/scanlog.c
index 417eca79df69..1b45c458f952 100644
--- a/arch/powerpc/platforms/pseries/scanlog.c
+++ b/arch/powerpc/platforms/pseries/scanlog.c
@@ -13,7 +13,7 @@
13 * of this data using this driver. A dump exists if the device-tree 13 * of this data using this driver. A dump exists if the device-tree
14 * /chosen/ibm,scan-log-data property exists. 14 * /chosen/ibm,scan-log-data property exists.
15 * 15 *
16 * This driver exports /proc/ppc64/scan-log-dump which can be read. 16 * This driver exports /proc/powerpc/scan-log-dump which can be read.
17 * The driver supports only sequential reads. 17 * The driver supports only sequential reads.
18 * 18 *
19 * The driver looks at a write to the driver for the single word "reset". 19 * The driver looks at a write to the driver for the single word "reset".
@@ -186,7 +186,7 @@ static int __init scanlog_init(void)
186 if (!data) 186 if (!data)
187 goto err; 187 goto err;
188 188
189 ent = proc_create_data("ppc64/rtas/scan-log-dump", S_IRUSR, NULL, 189 ent = proc_create_data("powerpc/rtas/scan-log-dump", S_IRUSR, NULL,
190 &scanlog_fops, data); 190 &scanlog_fops, data);
191 if (!ent) 191 if (!ent)
192 goto err; 192 goto err;
diff --git a/arch/powerpc/platforms/pseries/smp.c b/arch/powerpc/platforms/pseries/smp.c
index 440000cc7130..b4886635972c 100644
--- a/arch/powerpc/platforms/pseries/smp.c
+++ b/arch/powerpc/platforms/pseries/smp.c
@@ -48,6 +48,7 @@
48#include "plpar_wrappers.h" 48#include "plpar_wrappers.h"
49#include "pseries.h" 49#include "pseries.h"
50#include "xics.h" 50#include "xics.h"
51#include "offline_states.h"
51 52
52 53
53/* 54/*
@@ -84,6 +85,9 @@ static inline int __devinit smp_startup_cpu(unsigned int lcpu)
84 /* Fixup atomic count: it exited inside IRQ handler. */ 85 /* Fixup atomic count: it exited inside IRQ handler. */
85 task_thread_info(paca[lcpu].__current)->preempt_count = 0; 86 task_thread_info(paca[lcpu].__current)->preempt_count = 0;
86 87
88 if (get_cpu_current_state(lcpu) == CPU_STATE_INACTIVE)
89 goto out;
90
87 /* 91 /*
88 * If the RTAS start-cpu token does not exist then presume the 92 * If the RTAS start-cpu token does not exist then presume the
89 * cpu is already spinning. 93 * cpu is already spinning.
@@ -98,6 +102,7 @@ static inline int __devinit smp_startup_cpu(unsigned int lcpu)
98 return 0; 102 return 0;
99 } 103 }
100 104
105out:
101 return 1; 106 return 1;
102} 107}
103 108
@@ -111,12 +116,16 @@ static void __devinit smp_xics_setup_cpu(int cpu)
111 vpa_init(cpu); 116 vpa_init(cpu);
112 117
113 cpu_clear(cpu, of_spin_map); 118 cpu_clear(cpu, of_spin_map);
119 set_cpu_current_state(cpu, CPU_STATE_ONLINE);
120 set_default_offline_state(cpu);
114 121
115} 122}
116#endif /* CONFIG_XICS */ 123#endif /* CONFIG_XICS */
117 124
118static void __devinit smp_pSeries_kick_cpu(int nr) 125static void __devinit smp_pSeries_kick_cpu(int nr)
119{ 126{
127 long rc;
128 unsigned long hcpuid;
120 BUG_ON(nr < 0 || nr >= NR_CPUS); 129 BUG_ON(nr < 0 || nr >= NR_CPUS);
121 130
122 if (!smp_startup_cpu(nr)) 131 if (!smp_startup_cpu(nr))
@@ -128,6 +137,16 @@ static void __devinit smp_pSeries_kick_cpu(int nr)
128 * the processor will continue on to secondary_start 137 * the processor will continue on to secondary_start
129 */ 138 */
130 paca[nr].cpu_start = 1; 139 paca[nr].cpu_start = 1;
140
141 set_preferred_offline_state(nr, CPU_STATE_ONLINE);
142
143 if (get_cpu_current_state(nr) == CPU_STATE_INACTIVE) {
144 hcpuid = get_hard_smp_processor_id(nr);
145 rc = plpar_hcall_norets(H_PROD, hcpuid);
146 if (rc != H_SUCCESS)
147 printk(KERN_ERR "Error: Prod to wake up processor %d\
148 Ret= %ld\n", nr, rc);
149 }
131} 150}
132 151
133static int smp_pSeries_cpu_bootable(unsigned int nr) 152static int smp_pSeries_cpu_bootable(unsigned int nr)
diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c
index b9bf0eedccf2..d80f193cd871 100644
--- a/arch/powerpc/platforms/pseries/xics.c
+++ b/arch/powerpc/platforms/pseries/xics.c
@@ -20,6 +20,7 @@
20#include <linux/cpu.h> 20#include <linux/cpu.h>
21#include <linux/msi.h> 21#include <linux/msi.h>
22#include <linux/of.h> 22#include <linux/of.h>
23#include <linux/percpu.h>
23 24
24#include <asm/firmware.h> 25#include <asm/firmware.h>
25#include <asm/io.h> 26#include <asm/io.h>
@@ -46,6 +47,12 @@ static struct irq_host *xics_host;
46 */ 47 */
47#define IPI_PRIORITY 4 48#define IPI_PRIORITY 4
48 49
50/* The least favored priority */
51#define LOWEST_PRIORITY 0xFF
52
53/* The number of priorities defined above */
54#define MAX_NUM_PRIORITIES 3
55
49static unsigned int default_server = 0xFF; 56static unsigned int default_server = 0xFF;
50static unsigned int default_distrib_server = 0; 57static unsigned int default_distrib_server = 0;
51static unsigned int interrupt_server_size = 8; 58static unsigned int interrupt_server_size = 8;
@@ -56,6 +63,12 @@ static int ibm_set_xive;
56static int ibm_int_on; 63static int ibm_int_on;
57static int ibm_int_off; 64static int ibm_int_off;
58 65
66struct xics_cppr {
67 unsigned char stack[MAX_NUM_PRIORITIES];
68 int index;
69};
70
71static DEFINE_PER_CPU(struct xics_cppr, xics_cppr);
59 72
60/* Direct hardware low level accessors */ 73/* Direct hardware low level accessors */
61 74
@@ -150,14 +163,13 @@ static inline void lpar_qirr_info(int n_cpu , u8 value)
150/* Interface to generic irq subsystem */ 163/* Interface to generic irq subsystem */
151 164
152#ifdef CONFIG_SMP 165#ifdef CONFIG_SMP
153static int get_irq_server(unsigned int virq, unsigned int strict_check) 166static int get_irq_server(unsigned int virq, cpumask_t cpumask,
167 unsigned int strict_check)
154{ 168{
155 int server; 169 int server;
156 /* For the moment only implement delivery to all cpus or one cpu */ 170 /* For the moment only implement delivery to all cpus or one cpu */
157 cpumask_t cpumask;
158 cpumask_t tmp = CPU_MASK_NONE; 171 cpumask_t tmp = CPU_MASK_NONE;
159 172
160 cpumask_copy(&cpumask, irq_desc[virq].affinity);
161 if (!distribute_irqs) 173 if (!distribute_irqs)
162 return default_server; 174 return default_server;
163 175
@@ -179,7 +191,8 @@ static int get_irq_server(unsigned int virq, unsigned int strict_check)
179 return default_server; 191 return default_server;
180} 192}
181#else 193#else
182static int get_irq_server(unsigned int virq, unsigned int strict_check) 194static int get_irq_server(unsigned int virq, cpumask_t cpumask,
195 unsigned int strict_check)
183{ 196{
184 return default_server; 197 return default_server;
185} 198}
@@ -198,7 +211,7 @@ static void xics_unmask_irq(unsigned int virq)
198 if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS) 211 if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS)
199 return; 212 return;
200 213
201 server = get_irq_server(virq, 0); 214 server = get_irq_server(virq, *(irq_to_desc(virq)->affinity), 0);
202 215
203 call_status = rtas_call(ibm_set_xive, 3, 1, NULL, irq, server, 216 call_status = rtas_call(ibm_set_xive, 3, 1, NULL, irq, server,
204 DEFAULT_PRIORITY); 217 DEFAULT_PRIORITY);
@@ -284,6 +297,19 @@ static inline unsigned int xics_xirr_vector(unsigned int xirr)
284 return xirr & 0x00ffffff; 297 return xirr & 0x00ffffff;
285} 298}
286 299
300static void push_cppr(unsigned int vec)
301{
302 struct xics_cppr *os_cppr = &__get_cpu_var(xics_cppr);
303
304 if (WARN_ON(os_cppr->index >= MAX_NUM_PRIORITIES - 1))
305 return;
306
307 if (vec == XICS_IPI)
308 os_cppr->stack[++os_cppr->index] = IPI_PRIORITY;
309 else
310 os_cppr->stack[++os_cppr->index] = DEFAULT_PRIORITY;
311}
312
287static unsigned int xics_get_irq_direct(void) 313static unsigned int xics_get_irq_direct(void)
288{ 314{
289 unsigned int xirr = direct_xirr_info_get(); 315 unsigned int xirr = direct_xirr_info_get();
@@ -294,8 +320,10 @@ static unsigned int xics_get_irq_direct(void)
294 return NO_IRQ; 320 return NO_IRQ;
295 321
296 irq = irq_radix_revmap_lookup(xics_host, vec); 322 irq = irq_radix_revmap_lookup(xics_host, vec);
297 if (likely(irq != NO_IRQ)) 323 if (likely(irq != NO_IRQ)) {
324 push_cppr(vec);
298 return irq; 325 return irq;
326 }
299 327
300 /* We don't have a linux mapping, so have rtas mask it. */ 328 /* We don't have a linux mapping, so have rtas mask it. */
301 xics_mask_unknown_vec(vec); 329 xics_mask_unknown_vec(vec);
@@ -315,8 +343,10 @@ static unsigned int xics_get_irq_lpar(void)
315 return NO_IRQ; 343 return NO_IRQ;
316 344
317 irq = irq_radix_revmap_lookup(xics_host, vec); 345 irq = irq_radix_revmap_lookup(xics_host, vec);
318 if (likely(irq != NO_IRQ)) 346 if (likely(irq != NO_IRQ)) {
347 push_cppr(vec);
319 return irq; 348 return irq;
349 }
320 350
321 /* We don't have a linux mapping, so have RTAS mask it. */ 351 /* We don't have a linux mapping, so have RTAS mask it. */
322 xics_mask_unknown_vec(vec); 352 xics_mask_unknown_vec(vec);
@@ -326,12 +356,22 @@ static unsigned int xics_get_irq_lpar(void)
326 return NO_IRQ; 356 return NO_IRQ;
327} 357}
328 358
359static unsigned char pop_cppr(void)
360{
361 struct xics_cppr *os_cppr = &__get_cpu_var(xics_cppr);
362
363 if (WARN_ON(os_cppr->index < 1))
364 return LOWEST_PRIORITY;
365
366 return os_cppr->stack[--os_cppr->index];
367}
368
329static void xics_eoi_direct(unsigned int virq) 369static void xics_eoi_direct(unsigned int virq)
330{ 370{
331 unsigned int irq = (unsigned int)irq_map[virq].hwirq; 371 unsigned int irq = (unsigned int)irq_map[virq].hwirq;
332 372
333 iosync(); 373 iosync();
334 direct_xirr_info_set((0xff << 24) | irq); 374 direct_xirr_info_set((pop_cppr() << 24) | irq);
335} 375}
336 376
337static void xics_eoi_lpar(unsigned int virq) 377static void xics_eoi_lpar(unsigned int virq)
@@ -339,7 +379,7 @@ static void xics_eoi_lpar(unsigned int virq)
339 unsigned int irq = (unsigned int)irq_map[virq].hwirq; 379 unsigned int irq = (unsigned int)irq_map[virq].hwirq;
340 380
341 iosync(); 381 iosync();
342 lpar_xirr_info_set((0xff << 24) | irq); 382 lpar_xirr_info_set((pop_cppr() << 24) | irq);
343} 383}
344 384
345static int xics_set_affinity(unsigned int virq, const struct cpumask *cpumask) 385static int xics_set_affinity(unsigned int virq, const struct cpumask *cpumask)
@@ -365,7 +405,7 @@ static int xics_set_affinity(unsigned int virq, const struct cpumask *cpumask)
365 * For the moment only implement delivery to all cpus or one cpu. 405 * For the moment only implement delivery to all cpus or one cpu.
366 * Get current irq_server for the given irq 406 * Get current irq_server for the given irq
367 */ 407 */
368 irq_server = get_irq_server(virq, 1); 408 irq_server = get_irq_server(virq, *cpumask, 1);
369 if (irq_server == -1) { 409 if (irq_server == -1) {
370 char cpulist[128]; 410 char cpulist[128];
371 cpumask_scnprintf(cpulist, sizeof(cpulist), cpumask); 411 cpumask_scnprintf(cpulist, sizeof(cpulist), cpumask);
@@ -388,7 +428,7 @@ static int xics_set_affinity(unsigned int virq, const struct cpumask *cpumask)
388} 428}
389 429
390static struct irq_chip xics_pic_direct = { 430static struct irq_chip xics_pic_direct = {
391 .typename = " XICS ", 431 .name = " XICS ",
392 .startup = xics_startup, 432 .startup = xics_startup,
393 .mask = xics_mask_irq, 433 .mask = xics_mask_irq,
394 .unmask = xics_unmask_irq, 434 .unmask = xics_unmask_irq,
@@ -397,7 +437,7 @@ static struct irq_chip xics_pic_direct = {
397}; 437};
398 438
399static struct irq_chip xics_pic_lpar = { 439static struct irq_chip xics_pic_lpar = {
400 .typename = " XICS ", 440 .name = " XICS ",
401 .startup = xics_startup, 441 .startup = xics_startup,
402 .mask = xics_mask_irq, 442 .mask = xics_mask_irq,
403 .unmask = xics_unmask_irq, 443 .unmask = xics_unmask_irq,
@@ -428,13 +468,13 @@ static int xics_host_map(struct irq_host *h, unsigned int virq,
428 /* Insert the interrupt mapping into the radix tree for fast lookup */ 468 /* Insert the interrupt mapping into the radix tree for fast lookup */
429 irq_radix_revmap_insert(xics_host, virq, hw); 469 irq_radix_revmap_insert(xics_host, virq, hw);
430 470
431 get_irq_desc(virq)->status |= IRQ_LEVEL; 471 irq_to_desc(virq)->status |= IRQ_LEVEL;
432 set_irq_chip_and_handler(virq, xics_irq_chip, handle_fasteoi_irq); 472 set_irq_chip_and_handler(virq, xics_irq_chip, handle_fasteoi_irq);
433 return 0; 473 return 0;
434} 474}
435 475
436static int xics_host_xlate(struct irq_host *h, struct device_node *ct, 476static int xics_host_xlate(struct irq_host *h, struct device_node *ct,
437 u32 *intspec, unsigned int intsize, 477 const u32 *intspec, unsigned int intsize,
438 irq_hw_number_t *out_hwirq, unsigned int *out_flags) 478 irq_hw_number_t *out_hwirq, unsigned int *out_flags)
439 479
440{ 480{
@@ -746,6 +786,12 @@ void __init xics_init_IRQ(void)
746 786
747static void xics_set_cpu_priority(unsigned char cppr) 787static void xics_set_cpu_priority(unsigned char cppr)
748{ 788{
789 struct xics_cppr *os_cppr = &__get_cpu_var(xics_cppr);
790
791 BUG_ON(os_cppr->index != 0);
792
793 os_cppr->stack[os_cppr->index] = cppr;
794
749 if (firmware_has_feature(FW_FEATURE_LPAR)) 795 if (firmware_has_feature(FW_FEATURE_LPAR))
750 lpar_cppr_info(cppr); 796 lpar_cppr_info(cppr);
751 else 797 else
@@ -772,7 +818,7 @@ static void xics_set_cpu_giq(unsigned int gserver, unsigned int join)
772 818
773void xics_setup_cpu(void) 819void xics_setup_cpu(void)
774{ 820{
775 xics_set_cpu_priority(0xff); 821 xics_set_cpu_priority(LOWEST_PRIORITY);
776 822
777 xics_set_cpu_giq(default_distrib_server, 1); 823 xics_set_cpu_giq(default_distrib_server, 1);
778} 824}
@@ -852,7 +898,7 @@ void xics_migrate_irqs_away(void)
852 /* We need to get IPIs still. */ 898 /* We need to get IPIs still. */
853 if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS) 899 if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS)
854 continue; 900 continue;
855 desc = get_irq_desc(virq); 901 desc = irq_to_desc(virq);
856 902
857 /* We only need to migrate enabled IRQS */ 903 /* We only need to migrate enabled IRQS */
858 if (desc == NULL || desc->chip == NULL 904 if (desc == NULL || desc->chip == NULL
@@ -860,7 +906,7 @@ void xics_migrate_irqs_away(void)
860 || desc->chip->set_affinity == NULL) 906 || desc->chip->set_affinity == NULL)
861 continue; 907 continue;
862 908
863 spin_lock_irqsave(&desc->lock, flags); 909 raw_spin_lock_irqsave(&desc->lock, flags);
864 910
865 status = rtas_call(ibm_get_xive, 1, 3, xics_status, irq); 911 status = rtas_call(ibm_get_xive, 1, 3, xics_status, irq);
866 if (status) { 912 if (status) {
@@ -881,10 +927,10 @@ void xics_migrate_irqs_away(void)
881 virq, cpu); 927 virq, cpu);
882 928
883 /* Reset affinity to all cpus */ 929 /* Reset affinity to all cpus */
884 cpumask_setall(irq_desc[virq].affinity); 930 cpumask_setall(irq_to_desc(virq)->affinity);
885 desc->chip->set_affinity(virq, cpu_all_mask); 931 desc->chip->set_affinity(virq, cpu_all_mask);
886unlock: 932unlock:
887 spin_unlock_irqrestore(&desc->lock, flags); 933 raw_spin_unlock_irqrestore(&desc->lock, flags);
888 } 934 }
889} 935}
890#endif 936#endif