Merge branches 'release', 'asus', 'sony-laptop' and 'thinkpad' into release
[pandora-kernel.git] / arch / powerpc / platforms / 44x / warp.c
1 /*
2  * PIKA Warp(tm) board specific routines
3  *
4  * Copyright (c) 2008 PIKA Technologies
5  *   Sean MacLennan <smaclennan@pikatech.com>
6  *
7  * This program is free software; you can redistribute  it and/or modify it
8  * under  the terms of  the GNU General  Public License as published by the
9  * Free Software Foundation;  either version 2 of the  License, or (at your
10  * option) any later version.
11  */
12 #include <linux/init.h>
13 #include <linux/of_platform.h>
14 #include <linux/kthread.h>
15
16 #include <asm/machdep.h>
17 #include <asm/prom.h>
18 #include <asm/udbg.h>
19 #include <asm/time.h>
20 #include <asm/uic.h>
21
22 #include "44x.h"
23
24
25 static __initdata struct of_device_id warp_of_bus[] = {
26         { .compatible = "ibm,plb4", },
27         { .compatible = "ibm,opb", },
28         { .compatible = "ibm,ebc", },
29         {},
30 };
31
32 static int __init warp_device_probe(void)
33 {
34         of_platform_bus_probe(NULL, warp_of_bus, NULL);
35         return 0;
36 }
37 machine_device_initcall(warp, warp_device_probe);
38
39 static int __init warp_probe(void)
40 {
41         unsigned long root = of_get_flat_dt_root();
42
43         return of_flat_dt_is_compatible(root, "pika,warp");
44 }
45
46 define_machine(warp) {
47         .name           = "Warp",
48         .probe          = warp_probe,
49         .progress       = udbg_progress,
50         .init_IRQ       = uic_init_tree,
51         .get_irq        = uic_get_irq,
52         .restart        = ppc44x_reset_system,
53         .calibrate_decr = generic_calibrate_decr,
54 };
55
56
57 #define LED_GREEN (0x80000000 >> 0)
58 #define LED_RED   (0x80000000 >> 1)
59
60
61 /* This is for the power LEDs 1 = on, 0 = off, -1 = leave alone */
62 void warp_set_power_leds(int green, int red)
63 {
64         static void __iomem *gpio_base = NULL;
65         unsigned leds;
66
67         if (gpio_base == NULL) {
68                 struct device_node *np;
69
70                 /* Power LEDS are on the second GPIO controller */
71                 np = of_find_compatible_node(NULL, NULL, "ibm,gpio-440EP");
72                 if (np)
73                         np = of_find_compatible_node(np, NULL, "ibm,gpio-440EP");
74                 if (np == NULL) {
75                         printk(KERN_ERR __FILE__ ": Unable to find gpio\n");
76                         return;
77                 }
78
79                 gpio_base = of_iomap(np, 0);
80                 of_node_put(np);
81                 if (gpio_base == NULL) {
82                         printk(KERN_ERR __FILE__ ": Unable to map gpio");
83                         return;
84                 }
85         }
86
87         leds = in_be32(gpio_base);
88
89         switch (green) {
90         case 0: leds &= ~LED_GREEN; break;
91         case 1: leds |=  LED_GREEN; break;
92         }
93         switch (red) {
94         case 0: leds &= ~LED_RED; break;
95         case 1: leds |=  LED_RED; break;
96         }
97
98         out_be32(gpio_base, leds);
99 }
100 EXPORT_SYMBOL(warp_set_power_leds);
101
102
103 #ifdef CONFIG_SENSORS_AD7414
104 static int pika_dtm_thread(void __iomem *fpga)
105 {
106         extern int ad7414_get_temp(int index);
107
108         while (!kthread_should_stop()) {
109                 int temp = ad7414_get_temp(0);
110
111                 out_be32(fpga, temp);
112
113                 set_current_state(TASK_INTERRUPTIBLE);
114                 schedule_timeout(HZ);
115         }
116
117         return 0;
118 }
119
120 static int __init pika_dtm_start(void)
121 {
122         struct task_struct *dtm_thread;
123         struct device_node *np;
124         struct resource res;
125         void __iomem *fpga;
126
127         np = of_find_compatible_node(NULL, NULL, "pika,fpga");
128         if (np == NULL)
129                 return -ENOENT;
130
131         /* We do not call of_iomap here since it would map in the entire
132          * fpga space, which is over 8k.
133          */
134         if (of_address_to_resource(np, 0, &res)) {
135                 of_node_put(np);
136                 return -ENOENT;
137         }
138         of_node_put(np);
139
140         fpga = ioremap(res.start + 0x20, 4);
141         if (fpga == NULL)
142                 return -ENOENT;
143
144         dtm_thread = kthread_run(pika_dtm_thread, fpga + 0x20, "pika-dtm");
145         if (IS_ERR(dtm_thread)) {
146                 iounmap(fpga);
147                 return PTR_ERR(dtm_thread);
148         }
149
150         return 0;
151 }
152 device_initcall(pika_dtm_start);
153 #endif