diff options
Diffstat (limited to 'arch/powerpc/platforms/pasemi')
-rw-r--r-- | arch/powerpc/platforms/pasemi/Kconfig | 12 | ||||
-rw-r--r-- | arch/powerpc/platforms/pasemi/Makefile | 1 | ||||
-rw-r--r-- | arch/powerpc/platforms/pasemi/cpufreq.c | 19 | ||||
-rw-r--r-- | arch/powerpc/platforms/pasemi/electra_ide.c | 96 | ||||
-rw-r--r-- | arch/powerpc/platforms/pasemi/gpio_mdio.c | 96 | ||||
-rw-r--r-- | arch/powerpc/platforms/pasemi/idle.c | 5 | ||||
-rw-r--r-- | arch/powerpc/platforms/pasemi/pasemi.h | 6 | ||||
-rw-r--r-- | arch/powerpc/platforms/pasemi/powersave.S | 11 | ||||
-rw-r--r-- | arch/powerpc/platforms/pasemi/setup.c | 61 |
9 files changed, 140 insertions, 167 deletions
diff --git a/arch/powerpc/platforms/pasemi/Kconfig b/arch/powerpc/platforms/pasemi/Kconfig index 735e1536cbfc..348e0619e3e5 100644 --- a/arch/powerpc/platforms/pasemi/Kconfig +++ b/arch/powerpc/platforms/pasemi/Kconfig | |||
@@ -3,6 +3,7 @@ config PPC_PASEMI | |||
3 | bool "PA Semi SoC-based platforms" | 3 | bool "PA Semi SoC-based platforms" |
4 | default n | 4 | default n |
5 | select MPIC | 5 | select MPIC |
6 | select PCI | ||
6 | select PPC_UDBG_16550 | 7 | select PPC_UDBG_16550 |
7 | select PPC_NATIVE | 8 | select PPC_NATIVE |
8 | select MPIC_BROKEN_REGREAD | 9 | select MPIC_BROKEN_REGREAD |
@@ -17,7 +18,7 @@ config PPC_PASEMI_IOMMU | |||
17 | bool "PA Semi IOMMU support" | 18 | bool "PA Semi IOMMU support" |
18 | depends on PPC_PASEMI | 19 | depends on PPC_PASEMI |
19 | help | 20 | help |
20 | IOMMU support for PA6T-1682M | 21 | IOMMU support for PA Semi PWRficient |
21 | 22 | ||
22 | config PPC_PASEMI_IOMMU_DMA_FORCE | 23 | config PPC_PASEMI_IOMMU_DMA_FORCE |
23 | bool "Force DMA engine to use IOMMU" | 24 | bool "Force DMA engine to use IOMMU" |
@@ -36,13 +37,4 @@ config PPC_PASEMI_MDIO | |||
36 | help | 37 | help |
37 | Driver for MDIO via GPIO on PWRficient platforms | 38 | Driver for MDIO via GPIO on PWRficient platforms |
38 | 39 | ||
39 | config ELECTRA_IDE | ||
40 | tristate "Electra IDE driver" | ||
41 | default y | ||
42 | depends on PPC_PASEMI && ATA | ||
43 | select PATA_PLATFORM | ||
44 | help | ||
45 | This includes driver support for the Electra on-board IDE | ||
46 | interface. | ||
47 | |||
48 | endmenu | 40 | endmenu |
diff --git a/arch/powerpc/platforms/pasemi/Makefile b/arch/powerpc/platforms/pasemi/Makefile index e636daa7a80e..8f52d7515793 100644 --- a/arch/powerpc/platforms/pasemi/Makefile +++ b/arch/powerpc/platforms/pasemi/Makefile | |||
@@ -1,4 +1,3 @@ | |||
1 | obj-y += setup.o pci.o time.o idle.o powersave.o iommu.o dma_lib.o | 1 | obj-y += setup.o pci.o time.o idle.o powersave.o iommu.o dma_lib.o |
2 | obj-$(CONFIG_PPC_PASEMI_MDIO) += gpio_mdio.o | 2 | obj-$(CONFIG_PPC_PASEMI_MDIO) += gpio_mdio.o |
3 | obj-$(CONFIG_ELECTRA_IDE) += electra_ide.o | ||
4 | obj-$(CONFIG_PPC_PASEMI_CPUFREQ) += cpufreq.o | 3 | obj-$(CONFIG_PPC_PASEMI_CPUFREQ) += cpufreq.o |
diff --git a/arch/powerpc/platforms/pasemi/cpufreq.c b/arch/powerpc/platforms/pasemi/cpufreq.c index 1cfb8b0c8fec..58556b028a4c 100644 --- a/arch/powerpc/platforms/pasemi/cpufreq.c +++ b/arch/powerpc/platforms/pasemi/cpufreq.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <asm/io.h> | 32 | #include <asm/io.h> |
33 | #include <asm/prom.h> | 33 | #include <asm/prom.h> |
34 | #include <asm/time.h> | 34 | #include <asm/time.h> |
35 | #include <asm/smp.h> | ||
35 | 36 | ||
36 | #define SDCASR_REG 0x0100 | 37 | #define SDCASR_REG 0x0100 |
37 | #define SDCASR_REG_STRIDE 0x1000 | 38 | #define SDCASR_REG_STRIDE 0x1000 |
@@ -124,6 +125,11 @@ static void set_astate(int cpu, unsigned int astate) | |||
124 | local_irq_restore(flags); | 125 | local_irq_restore(flags); |
125 | } | 126 | } |
126 | 127 | ||
128 | int check_astate(void) | ||
129 | { | ||
130 | return get_cur_astate(hard_smp_processor_id()); | ||
131 | } | ||
132 | |||
127 | void restore_astate(int cpu) | 133 | void restore_astate(int cpu) |
128 | { | 134 | { |
129 | set_astate(cpu, current_astate); | 135 | set_astate(cpu, current_astate); |
@@ -147,7 +153,10 @@ static int pas_cpufreq_cpu_init(struct cpufreq_policy *policy) | |||
147 | if (!cpu) | 153 | if (!cpu) |
148 | goto out; | 154 | goto out; |
149 | 155 | ||
150 | dn = of_find_compatible_node(NULL, "sdc", "1682m-sdc"); | 156 | dn = of_find_compatible_node(NULL, NULL, "1682m-sdc"); |
157 | if (!dn) | ||
158 | dn = of_find_compatible_node(NULL, NULL, | ||
159 | "pasemi,pwrficient-sdc"); | ||
151 | if (!dn) | 160 | if (!dn) |
152 | goto out; | 161 | goto out; |
153 | err = of_address_to_resource(dn, 0, &res); | 162 | err = of_address_to_resource(dn, 0, &res); |
@@ -160,7 +169,10 @@ static int pas_cpufreq_cpu_init(struct cpufreq_policy *policy) | |||
160 | goto out; | 169 | goto out; |
161 | } | 170 | } |
162 | 171 | ||
163 | dn = of_find_compatible_node(NULL, "gizmo", "1682m-gizmo"); | 172 | dn = of_find_compatible_node(NULL, NULL, "1682m-gizmo"); |
173 | if (!dn) | ||
174 | dn = of_find_compatible_node(NULL, NULL, | ||
175 | "pasemi,pwrficient-gizmo"); | ||
164 | if (!dn) { | 176 | if (!dn) { |
165 | err = -ENODEV; | 177 | err = -ENODEV; |
166 | goto out_unmap_sdcasr; | 178 | goto out_unmap_sdcasr; |
@@ -292,7 +304,8 @@ static struct cpufreq_driver pas_cpufreq_driver = { | |||
292 | 304 | ||
293 | static int __init pas_cpufreq_init(void) | 305 | static int __init pas_cpufreq_init(void) |
294 | { | 306 | { |
295 | if (!machine_is_compatible("PA6T-1682M")) | 307 | if (!machine_is_compatible("PA6T-1682M") && |
308 | !machine_is_compatible("pasemi,pwrficient")) | ||
296 | return -ENODEV; | 309 | return -ENODEV; |
297 | 310 | ||
298 | return cpufreq_register_driver(&pas_cpufreq_driver); | 311 | return cpufreq_register_driver(&pas_cpufreq_driver); |
diff --git a/arch/powerpc/platforms/pasemi/electra_ide.c b/arch/powerpc/platforms/pasemi/electra_ide.c deleted file mode 100644 index 12fb0c949263..000000000000 --- a/arch/powerpc/platforms/pasemi/electra_ide.c +++ /dev/null | |||
@@ -1,96 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2007 PA Semi, Inc | ||
3 | * | ||
4 | * Maintained by: Olof Johansson <olof@lixom.net> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
18 | */ | ||
19 | |||
20 | #include <linux/platform_device.h> | ||
21 | |||
22 | #include <asm/prom.h> | ||
23 | #include <asm/system.h> | ||
24 | |||
25 | /* The electra IDE interface is incredibly simple: Just a device on the localbus | ||
26 | * with interrupts hooked up to one of the GPIOs. The device tree contains the | ||
27 | * address window and interrupt mappings already, and the pata_platform driver handles | ||
28 | * the rest. We just need to hook the two up. | ||
29 | */ | ||
30 | |||
31 | #define MAX_IFS 4 /* really, we have only one */ | ||
32 | |||
33 | static struct platform_device *pdevs[MAX_IFS]; | ||
34 | |||
35 | static int __devinit electra_ide_init(void) | ||
36 | { | ||
37 | struct device_node *np; | ||
38 | struct resource r[3]; | ||
39 | int ret = 0; | ||
40 | int i; | ||
41 | |||
42 | np = of_find_compatible_node(NULL, "ide", "electra-ide"); | ||
43 | i = 0; | ||
44 | |||
45 | while (np && i < MAX_IFS) { | ||
46 | memset(r, 0, sizeof(r)); | ||
47 | |||
48 | /* pata_platform wants two address ranges: one for the base registers, | ||
49 | * another for the control (altstatus). It's located at offset 0x3f6 in | ||
50 | * the window, but the device tree only has one large register window | ||
51 | * that covers both ranges. So we need to split it up by hand here: | ||
52 | */ | ||
53 | |||
54 | ret = of_address_to_resource(np, 0, &r[0]); | ||
55 | if (ret) | ||
56 | goto out; | ||
57 | ret = of_address_to_resource(np, 0, &r[1]); | ||
58 | if (ret) | ||
59 | goto out; | ||
60 | |||
61 | r[1].start += 0x3f6; | ||
62 | r[0].end = r[1].start-1; | ||
63 | |||
64 | r[2].start = irq_of_parse_and_map(np, 0); | ||
65 | r[2].end = irq_of_parse_and_map(np, 0); | ||
66 | r[2].flags = IORESOURCE_IRQ; | ||
67 | |||
68 | pr_debug("registering platform device at 0x%lx/0x%lx, irq is %ld\n", | ||
69 | r[0].start, r[1].start, r[2].start); | ||
70 | pdevs[i] = platform_device_register_simple("pata_platform", i, r, 3); | ||
71 | if (IS_ERR(pdevs[i])) { | ||
72 | ret = PTR_ERR(pdevs[i]); | ||
73 | pdevs[i] = NULL; | ||
74 | goto out; | ||
75 | } | ||
76 | np = of_find_compatible_node(np, "ide", "electra-ide"); | ||
77 | } | ||
78 | out: | ||
79 | return ret; | ||
80 | } | ||
81 | module_init(electra_ide_init); | ||
82 | |||
83 | static void __devexit electra_ide_exit(void) | ||
84 | { | ||
85 | int i; | ||
86 | |||
87 | for (i = 0; i < MAX_IFS; i++) | ||
88 | if (pdevs[i]) | ||
89 | platform_device_unregister(pdevs[i]); | ||
90 | } | ||
91 | module_exit(electra_ide_exit); | ||
92 | |||
93 | |||
94 | MODULE_LICENSE("GPL"); | ||
95 | MODULE_AUTHOR ("Olof Johansson <olof@lixom.net>"); | ||
96 | MODULE_DESCRIPTION("PA Semi Electra IDE driver"); | ||
diff --git a/arch/powerpc/platforms/pasemi/gpio_mdio.c b/arch/powerpc/platforms/pasemi/gpio_mdio.c index dae9f658122e..b46542990cf8 100644 --- a/arch/powerpc/platforms/pasemi/gpio_mdio.c +++ b/arch/powerpc/platforms/pasemi/gpio_mdio.c | |||
@@ -30,7 +30,7 @@ | |||
30 | #include <linux/interrupt.h> | 30 | #include <linux/interrupt.h> |
31 | #include <linux/phy.h> | 31 | #include <linux/phy.h> |
32 | #include <linux/platform_device.h> | 32 | #include <linux/platform_device.h> |
33 | #include <asm/of_platform.h> | 33 | #include <linux/of_platform.h> |
34 | 34 | ||
35 | #define DELAY 1 | 35 | #define DELAY 1 |
36 | 36 | ||
@@ -218,45 +218,27 @@ static int __devinit gpio_mdio_probe(struct of_device *ofdev, | |||
218 | const struct of_device_id *match) | 218 | const struct of_device_id *match) |
219 | { | 219 | { |
220 | struct device *dev = &ofdev->dev; | 220 | struct device *dev = &ofdev->dev; |
221 | struct device_node *np = ofdev->node; | 221 | struct device_node *phy_dn, *np = ofdev->node; |
222 | struct device_node *gpio_np; | ||
223 | struct mii_bus *new_bus; | 222 | struct mii_bus *new_bus; |
224 | struct resource res; | ||
225 | struct gpio_priv *priv; | 223 | struct gpio_priv *priv; |
226 | const unsigned int *prop; | 224 | const unsigned int *prop; |
227 | int err = 0; | 225 | int err; |
228 | int i; | 226 | int i; |
229 | 227 | ||
230 | gpio_np = of_find_compatible_node(NULL, "gpio", "1682m-gpio"); | 228 | err = -ENOMEM; |
231 | |||
232 | if (!gpio_np) | ||
233 | return -ENODEV; | ||
234 | |||
235 | err = of_address_to_resource(gpio_np, 0, &res); | ||
236 | of_node_put(gpio_np); | ||
237 | |||
238 | if (err) | ||
239 | return -EINVAL; | ||
240 | |||
241 | if (!gpio_regs) | ||
242 | gpio_regs = ioremap(res.start, 0x100); | ||
243 | |||
244 | if (!gpio_regs) | ||
245 | return -EPERM; | ||
246 | |||
247 | priv = kzalloc(sizeof(struct gpio_priv), GFP_KERNEL); | 229 | priv = kzalloc(sizeof(struct gpio_priv), GFP_KERNEL); |
248 | if (priv == NULL) | 230 | if (!priv) |
249 | return -ENOMEM; | 231 | goto out; |
250 | 232 | ||
251 | new_bus = kzalloc(sizeof(struct mii_bus), GFP_KERNEL); | 233 | new_bus = kzalloc(sizeof(struct mii_bus), GFP_KERNEL); |
252 | 234 | ||
253 | if (new_bus == NULL) | 235 | if (!new_bus) |
254 | return -ENOMEM; | 236 | goto out_free_priv; |
255 | 237 | ||
256 | new_bus->name = "pasemi gpio mdio bus", | 238 | new_bus->name = "pasemi gpio mdio bus"; |
257 | new_bus->read = &gpio_mdio_read, | 239 | new_bus->read = &gpio_mdio_read; |
258 | new_bus->write = &gpio_mdio_write, | 240 | new_bus->write = &gpio_mdio_write; |
259 | new_bus->reset = &gpio_mdio_reset, | 241 | new_bus->reset = &gpio_mdio_reset; |
260 | 242 | ||
261 | prop = of_get_property(np, "reg", NULL); | 243 | prop = of_get_property(np, "reg", NULL); |
262 | new_bus->id = *prop; | 244 | new_bus->id = *prop; |
@@ -265,9 +247,24 @@ static int __devinit gpio_mdio_probe(struct of_device *ofdev, | |||
265 | new_bus->phy_mask = 0; | 247 | new_bus->phy_mask = 0; |
266 | 248 | ||
267 | new_bus->irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL); | 249 | new_bus->irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL); |
268 | for(i = 0; i < PHY_MAX_ADDR; ++i) | ||
269 | new_bus->irq[i] = irq_create_mapping(NULL, 10); | ||
270 | 250 | ||
251 | if (!new_bus->irq) | ||
252 | goto out_free_bus; | ||
253 | |||
254 | for (i = 0; i < PHY_MAX_ADDR; i++) | ||
255 | new_bus->irq[i] = NO_IRQ; | ||
256 | |||
257 | for (phy_dn = of_get_next_child(np, NULL); | ||
258 | phy_dn != NULL; | ||
259 | phy_dn = of_get_next_child(np, phy_dn)) { | ||
260 | const unsigned int *ip, *regp; | ||
261 | |||
262 | ip = of_get_property(phy_dn, "interrupts", NULL); | ||
263 | regp = of_get_property(phy_dn, "reg", NULL); | ||
264 | if (!ip || !regp || *regp >= PHY_MAX_ADDR) | ||
265 | continue; | ||
266 | new_bus->irq[*regp] = irq_create_mapping(NULL, *ip); | ||
267 | } | ||
271 | 268 | ||
272 | prop = of_get_property(np, "mdc-pin", NULL); | 269 | prop = of_get_property(np, "mdc-pin", NULL); |
273 | priv->mdc_pin = *prop; | 270 | priv->mdc_pin = *prop; |
@@ -280,17 +277,21 @@ static int __devinit gpio_mdio_probe(struct of_device *ofdev, | |||
280 | 277 | ||
281 | err = mdiobus_register(new_bus); | 278 | err = mdiobus_register(new_bus); |
282 | 279 | ||
283 | if (0 != err) { | 280 | if (err != 0) { |
284 | printk(KERN_ERR "%s: Cannot register as MDIO bus, err %d\n", | 281 | printk(KERN_ERR "%s: Cannot register as MDIO bus, err %d\n", |
285 | new_bus->name, err); | 282 | new_bus->name, err); |
286 | goto bus_register_fail; | 283 | goto out_free_irq; |
287 | } | 284 | } |
288 | 285 | ||
289 | return 0; | 286 | return 0; |
290 | 287 | ||
291 | bus_register_fail: | 288 | out_free_irq: |
289 | kfree(new_bus->irq); | ||
290 | out_free_bus: | ||
292 | kfree(new_bus); | 291 | kfree(new_bus); |
293 | 292 | out_free_priv: | |
293 | kfree(priv); | ||
294 | out: | ||
294 | return err; | 295 | return err; |
295 | } | 296 | } |
296 | 297 | ||
@@ -317,6 +318,7 @@ static struct of_device_id gpio_mdio_match[] = | |||
317 | }, | 318 | }, |
318 | {}, | 319 | {}, |
319 | }; | 320 | }; |
321 | MODULE_DEVICE_TABLE(of, gpio_mdio_match); | ||
320 | 322 | ||
321 | static struct of_platform_driver gpio_mdio_driver = | 323 | static struct of_platform_driver gpio_mdio_driver = |
322 | { | 324 | { |
@@ -330,12 +332,32 @@ static struct of_platform_driver gpio_mdio_driver = | |||
330 | 332 | ||
331 | int gpio_mdio_init(void) | 333 | int gpio_mdio_init(void) |
332 | { | 334 | { |
335 | struct device_node *np; | ||
336 | |||
337 | np = of_find_compatible_node(NULL, NULL, "1682m-gpio"); | ||
338 | if (!np) | ||
339 | np = of_find_compatible_node(NULL, NULL, | ||
340 | "pasemi,pwrficient-gpio"); | ||
341 | if (!np) | ||
342 | return -ENODEV; | ||
343 | gpio_regs = of_iomap(np, 0); | ||
344 | of_node_put(np); | ||
345 | |||
346 | if (!gpio_regs) | ||
347 | return -ENODEV; | ||
348 | |||
333 | return of_register_platform_driver(&gpio_mdio_driver); | 349 | return of_register_platform_driver(&gpio_mdio_driver); |
334 | } | 350 | } |
351 | module_init(gpio_mdio_init); | ||
335 | 352 | ||
336 | void gpio_mdio_exit(void) | 353 | void gpio_mdio_exit(void) |
337 | { | 354 | { |
338 | of_unregister_platform_driver(&gpio_mdio_driver); | 355 | of_unregister_platform_driver(&gpio_mdio_driver); |
356 | if (gpio_regs) | ||
357 | iounmap(gpio_regs); | ||
339 | } | 358 | } |
340 | device_initcall(gpio_mdio_init); | 359 | module_exit(gpio_mdio_exit); |
341 | 360 | ||
361 | MODULE_LICENSE("GPL"); | ||
362 | MODULE_AUTHOR("Olof Johansson <olof@lixom.net>"); | ||
363 | MODULE_DESCRIPTION("Driver for MDIO over GPIO on PA Semi PWRficient-based boards"); | ||
diff --git a/arch/powerpc/platforms/pasemi/idle.c b/arch/powerpc/platforms/pasemi/idle.c index d8e1fcc78513..43911d8b0206 100644 --- a/arch/powerpc/platforms/pasemi/idle.c +++ b/arch/powerpc/platforms/pasemi/idle.c | |||
@@ -74,9 +74,6 @@ static int pasemi_system_reset_exception(struct pt_regs *regs) | |||
74 | 74 | ||
75 | static int __init pasemi_idle_init(void) | 75 | static int __init pasemi_idle_init(void) |
76 | { | 76 | { |
77 | if (!machine_is(pasemi)) | ||
78 | return -ENODEV; | ||
79 | |||
80 | #ifndef CONFIG_PPC_PASEMI_CPUFREQ | 77 | #ifndef CONFIG_PPC_PASEMI_CPUFREQ |
81 | printk(KERN_WARNING "No cpufreq driver, powersavings modes disabled\n"); | 78 | printk(KERN_WARNING "No cpufreq driver, powersavings modes disabled\n"); |
82 | current_mode = 0; | 79 | current_mode = 0; |
@@ -88,7 +85,7 @@ static int __init pasemi_idle_init(void) | |||
88 | 85 | ||
89 | return 0; | 86 | return 0; |
90 | } | 87 | } |
91 | late_initcall(pasemi_idle_init); | 88 | machine_late_initcall(pasemi, pasemi_idle_init); |
92 | 89 | ||
93 | static int __init idle_param(char *p) | 90 | static int __init idle_param(char *p) |
94 | { | 91 | { |
diff --git a/arch/powerpc/platforms/pasemi/pasemi.h b/arch/powerpc/platforms/pasemi/pasemi.h index 58b344c6fc38..b1e524f7489d 100644 --- a/arch/powerpc/platforms/pasemi/pasemi.h +++ b/arch/powerpc/platforms/pasemi/pasemi.h | |||
@@ -17,8 +17,14 @@ extern void idle_doze(void); | |||
17 | 17 | ||
18 | /* Restore astate to last set */ | 18 | /* Restore astate to last set */ |
19 | #ifdef CONFIG_PPC_PASEMI_CPUFREQ | 19 | #ifdef CONFIG_PPC_PASEMI_CPUFREQ |
20 | extern int check_astate(void); | ||
20 | extern void restore_astate(int cpu); | 21 | extern void restore_astate(int cpu); |
21 | #else | 22 | #else |
23 | static inline int check_astate(void) | ||
24 | { | ||
25 | /* Always return >0 so we never power save */ | ||
26 | return 1; | ||
27 | } | ||
22 | static inline void restore_astate(int cpu) | 28 | static inline void restore_astate(int cpu) |
23 | { | 29 | { |
24 | } | 30 | } |
diff --git a/arch/powerpc/platforms/pasemi/powersave.S b/arch/powerpc/platforms/pasemi/powersave.S index 6d0fba6aab17..56f45adcd089 100644 --- a/arch/powerpc/platforms/pasemi/powersave.S +++ b/arch/powerpc/platforms/pasemi/powersave.S | |||
@@ -62,7 +62,16 @@ sleep_common: | |||
62 | mflr r0 | 62 | mflr r0 |
63 | std r0, 16(r1) | 63 | std r0, 16(r1) |
64 | stdu r1,-64(r1) | 64 | stdu r1,-64(r1) |
65 | #ifdef CONFIG_PPC_PASEMI_CPUFREQ | ||
66 | std r3, 48(r1) | ||
65 | 67 | ||
68 | /* Only do power savings when in astate 0 */ | ||
69 | bl .check_astate | ||
70 | cmpwi r3,0 | ||
71 | bne 1f | ||
72 | |||
73 | ld r3, 48(r1) | ||
74 | #endif | ||
66 | LOAD_REG_IMMEDIATE(r6,MSR_DR|MSR_IR|MSR_ME|MSR_EE) | 75 | LOAD_REG_IMMEDIATE(r6,MSR_DR|MSR_IR|MSR_ME|MSR_EE) |
67 | mfmsr r4 | 76 | mfmsr r4 |
68 | andc r5,r4,r6 | 77 | andc r5,r4,r6 |
@@ -73,7 +82,7 @@ sleep_common: | |||
73 | 82 | ||
74 | mtmsrd r4,0 | 83 | mtmsrd r4,0 |
75 | 84 | ||
76 | addi r1,r1,64 | 85 | 1: addi r1,r1,64 |
77 | ld r0,16(r1) | 86 | ld r0,16(r1) |
78 | mtlr r0 | 87 | mtlr r0 |
79 | blr | 88 | blr |
diff --git a/arch/powerpc/platforms/pasemi/setup.c b/arch/powerpc/platforms/pasemi/setup.c index 3d62060498b4..c64fb5bfb37e 100644 --- a/arch/powerpc/platforms/pasemi/setup.c +++ b/arch/powerpc/platforms/pasemi/setup.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/delay.h> | 27 | #include <linux/delay.h> |
28 | #include <linux/console.h> | 28 | #include <linux/console.h> |
29 | #include <linux/pci.h> | 29 | #include <linux/pci.h> |
30 | #include <linux/of_platform.h> | ||
30 | 31 | ||
31 | #include <asm/prom.h> | 32 | #include <asm/prom.h> |
32 | #include <asm/system.h> | 33 | #include <asm/system.h> |
@@ -35,7 +36,7 @@ | |||
35 | #include <asm/mpic.h> | 36 | #include <asm/mpic.h> |
36 | #include <asm/smp.h> | 37 | #include <asm/smp.h> |
37 | #include <asm/time.h> | 38 | #include <asm/time.h> |
38 | #include <asm/of_platform.h> | 39 | #include <asm/mmu.h> |
39 | 40 | ||
40 | #include <pcmcia/ss.h> | 41 | #include <pcmcia/ss.h> |
41 | #include <pcmcia/cistpl.h> | 42 | #include <pcmcia/cistpl.h> |
@@ -43,6 +44,10 @@ | |||
43 | 44 | ||
44 | #include "pasemi.h" | 45 | #include "pasemi.h" |
45 | 46 | ||
47 | #if !defined(CONFIG_SMP) | ||
48 | static void smp_send_stop(void) {} | ||
49 | #endif | ||
50 | |||
46 | /* SDC reset register, must be pre-mapped at reset time */ | 51 | /* SDC reset register, must be pre-mapped at reset time */ |
47 | static void __iomem *reset_reg; | 52 | static void __iomem *reset_reg; |
48 | 53 | ||
@@ -56,10 +61,14 @@ struct mce_regs { | |||
56 | 61 | ||
57 | static struct mce_regs mce_regs[MAX_MCE_REGS]; | 62 | static struct mce_regs mce_regs[MAX_MCE_REGS]; |
58 | static int num_mce_regs; | 63 | static int num_mce_regs; |
64 | static int nmi_virq = NO_IRQ; | ||
59 | 65 | ||
60 | 66 | ||
61 | static void pas_restart(char *cmd) | 67 | static void pas_restart(char *cmd) |
62 | { | 68 | { |
69 | /* Need to put others cpu in hold loop so they're not sleeping */ | ||
70 | smp_send_stop(); | ||
71 | udelay(10000); | ||
63 | printk("Restarting...\n"); | 72 | printk("Restarting...\n"); |
64 | while (1) | 73 | while (1) |
65 | out_le32(reset_reg, 0x6000000); | 74 | out_le32(reset_reg, 0x6000000); |
@@ -126,9 +135,6 @@ static int __init pas_setup_mce_regs(void) | |||
126 | struct pci_dev *dev; | 135 | struct pci_dev *dev; |
127 | int reg; | 136 | int reg; |
128 | 137 | ||
129 | if (!machine_is(pasemi)) | ||
130 | return -ENODEV; | ||
131 | |||
132 | /* Remap various SoC status registers for use by the MCE handler */ | 138 | /* Remap various SoC status registers for use by the MCE handler */ |
133 | 139 | ||
134 | reg = 0; | 140 | reg = 0; |
@@ -172,7 +178,7 @@ static int __init pas_setup_mce_regs(void) | |||
172 | 178 | ||
173 | return 0; | 179 | return 0; |
174 | } | 180 | } |
175 | device_initcall(pas_setup_mce_regs); | 181 | machine_device_initcall(pasemi, pas_setup_mce_regs); |
176 | 182 | ||
177 | static __init void pas_init_IRQ(void) | 183 | static __init void pas_init_IRQ(void) |
178 | { | 184 | { |
@@ -181,6 +187,8 @@ static __init void pas_init_IRQ(void) | |||
181 | unsigned long openpic_addr; | 187 | unsigned long openpic_addr; |
182 | const unsigned int *opprop; | 188 | const unsigned int *opprop; |
183 | int naddr, opplen; | 189 | int naddr, opplen; |
190 | int mpic_flags; | ||
191 | const unsigned int *nmiprop; | ||
184 | struct mpic *mpic; | 192 | struct mpic *mpic; |
185 | 193 | ||
186 | mpic_node = NULL; | 194 | mpic_node = NULL; |
@@ -213,13 +221,26 @@ static __init void pas_init_IRQ(void) | |||
213 | openpic_addr = of_read_number(opprop, naddr); | 221 | openpic_addr = of_read_number(opprop, naddr); |
214 | printk(KERN_DEBUG "OpenPIC addr: %lx\n", openpic_addr); | 222 | printk(KERN_DEBUG "OpenPIC addr: %lx\n", openpic_addr); |
215 | 223 | ||
224 | mpic_flags = MPIC_PRIMARY | MPIC_LARGE_VECTORS | MPIC_NO_BIAS; | ||
225 | |||
226 | nmiprop = of_get_property(mpic_node, "nmi-source", NULL); | ||
227 | if (nmiprop) | ||
228 | mpic_flags |= MPIC_ENABLE_MCK; | ||
229 | |||
216 | mpic = mpic_alloc(mpic_node, openpic_addr, | 230 | mpic = mpic_alloc(mpic_node, openpic_addr, |
217 | MPIC_PRIMARY|MPIC_LARGE_VECTORS, | 231 | mpic_flags, 0, 0, "PASEMI-OPIC"); |
218 | 0, 0, " PAS-OPIC "); | ||
219 | BUG_ON(!mpic); | 232 | BUG_ON(!mpic); |
220 | 233 | ||
221 | mpic_assign_isu(mpic, 0, openpic_addr + 0x10000); | 234 | mpic_assign_isu(mpic, 0, openpic_addr + 0x10000); |
222 | mpic_init(mpic); | 235 | mpic_init(mpic); |
236 | /* The NMI/MCK source needs to be prio 15 */ | ||
237 | if (nmiprop) { | ||
238 | nmi_virq = irq_create_mapping(NULL, *nmiprop); | ||
239 | mpic_irq_set_priority(nmi_virq, 15); | ||
240 | set_irq_type(nmi_virq, IRQ_TYPE_EDGE_RISING); | ||
241 | mpic_unmask_irq(nmi_virq); | ||
242 | } | ||
243 | |||
223 | of_node_put(mpic_node); | 244 | of_node_put(mpic_node); |
224 | of_node_put(root); | 245 | of_node_put(root); |
225 | } | 246 | } |
@@ -239,6 +260,14 @@ static int pas_machine_check_handler(struct pt_regs *regs) | |||
239 | 260 | ||
240 | srr0 = regs->nip; | 261 | srr0 = regs->nip; |
241 | srr1 = regs->msr; | 262 | srr1 = regs->msr; |
263 | |||
264 | if (nmi_virq != NO_IRQ && mpic_get_mcirq() == nmi_virq) { | ||
265 | printk(KERN_ERR "NMI delivered\n"); | ||
266 | debugger(regs); | ||
267 | mpic_end_irq(nmi_virq); | ||
268 | goto out; | ||
269 | } | ||
270 | |||
242 | dsisr = mfspr(SPRN_DSISR); | 271 | dsisr = mfspr(SPRN_DSISR); |
243 | printk(KERN_ERR "Machine Check on CPU %d\n", cpu); | 272 | printk(KERN_ERR "Machine Check on CPU %d\n", cpu); |
244 | printk(KERN_ERR "SRR0 0x%016lx SRR1 0x%016lx\n", srr0, srr1); | 273 | printk(KERN_ERR "SRR0 0x%016lx SRR1 0x%016lx\n", srr0, srr1); |
@@ -295,14 +324,14 @@ static int pas_machine_check_handler(struct pt_regs *regs) | |||
295 | int i; | 324 | int i; |
296 | 325 | ||
297 | printk(KERN_ERR "slb contents:\n"); | 326 | printk(KERN_ERR "slb contents:\n"); |
298 | for (i = 0; i < SLB_NUM_ENTRIES; i++) { | 327 | for (i = 0; i < mmu_slb_size; i++) { |
299 | asm volatile("slbmfee %0,%1" : "=r" (e) : "r" (i)); | 328 | asm volatile("slbmfee %0,%1" : "=r" (e) : "r" (i)); |
300 | asm volatile("slbmfev %0,%1" : "=r" (v) : "r" (i)); | 329 | asm volatile("slbmfev %0,%1" : "=r" (v) : "r" (i)); |
301 | printk(KERN_ERR "%02d %016lx %016lx\n", i, e, v); | 330 | printk(KERN_ERR "%02d %016lx %016lx\n", i, e, v); |
302 | } | 331 | } |
303 | } | 332 | } |
304 | 333 | ||
305 | 334 | out: | |
306 | /* SRR1[62] is from MSR[62] if recoverable, so pass that back */ | 335 | /* SRR1[62] is from MSR[62] if recoverable, so pass that back */ |
307 | return !!(srr1 & 0x2); | 336 | return !!(srr1 & 0x2); |
308 | } | 337 | } |
@@ -362,16 +391,17 @@ static inline void pasemi_pcmcia_init(void) | |||
362 | 391 | ||
363 | 392 | ||
364 | static struct of_device_id pasemi_bus_ids[] = { | 393 | static struct of_device_id pasemi_bus_ids[] = { |
394 | /* Unfortunately needed for legacy firmwares */ | ||
365 | { .type = "localbus", }, | 395 | { .type = "localbus", }, |
366 | { .type = "sdc", }, | 396 | { .type = "sdc", }, |
397 | /* These are the proper entries, which newer firmware uses */ | ||
398 | { .compatible = "pasemi,localbus", }, | ||
399 | { .compatible = "pasemi,sdc", }, | ||
367 | {}, | 400 | {}, |
368 | }; | 401 | }; |
369 | 402 | ||
370 | static int __init pasemi_publish_devices(void) | 403 | static int __init pasemi_publish_devices(void) |
371 | { | 404 | { |
372 | if (!machine_is(pasemi)) | ||
373 | return 0; | ||
374 | |||
375 | pasemi_pcmcia_init(); | 405 | pasemi_pcmcia_init(); |
376 | 406 | ||
377 | /* Publish OF platform devices for SDC and other non-PCI devices */ | 407 | /* Publish OF platform devices for SDC and other non-PCI devices */ |
@@ -379,7 +409,7 @@ static int __init pasemi_publish_devices(void) | |||
379 | 409 | ||
380 | return 0; | 410 | return 0; |
381 | } | 411 | } |
382 | device_initcall(pasemi_publish_devices); | 412 | machine_device_initcall(pasemi, pasemi_publish_devices); |
383 | 413 | ||
384 | 414 | ||
385 | /* | 415 | /* |
@@ -389,7 +419,8 @@ static int __init pas_probe(void) | |||
389 | { | 419 | { |
390 | unsigned long root = of_get_flat_dt_root(); | 420 | unsigned long root = of_get_flat_dt_root(); |
391 | 421 | ||
392 | if (!of_flat_dt_is_compatible(root, "PA6T-1682M")) | 422 | if (!of_flat_dt_is_compatible(root, "PA6T-1682M") && |
423 | !of_flat_dt_is_compatible(root, "pasemi,pwrficient")) | ||
393 | return 0; | 424 | return 0; |
394 | 425 | ||
395 | hpte_init_native(); | 426 | hpte_init_native(); |
@@ -400,7 +431,7 @@ static int __init pas_probe(void) | |||
400 | } | 431 | } |
401 | 432 | ||
402 | define_machine(pasemi) { | 433 | define_machine(pasemi) { |
403 | .name = "PA Semi PA6T-1682M", | 434 | .name = "PA Semi PWRficient", |
404 | .probe = pas_probe, | 435 | .probe = pas_probe, |
405 | .setup_arch = pas_setup_arch, | 436 | .setup_arch = pas_setup_arch, |
406 | .init_early = pas_init_early, | 437 | .init_early = pas_init_early, |