Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394...
[pandora-kernel.git] / arch / powerpc / platforms / 44x / warp.c
1 /*
2  * PIKA Warp(tm) board specific routines
3  *
4  * Copyright (c) 2008-2009 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 #include <linux/i2c.h>
16 #include <linux/interrupt.h>
17 #include <linux/delay.h>
18 #include <linux/of_gpio.h>
19
20 #include <asm/machdep.h>
21 #include <asm/prom.h>
22 #include <asm/udbg.h>
23 #include <asm/time.h>
24 #include <asm/uic.h>
25 #include <asm/ppc4xx.h>
26
27
28 static __initdata struct of_device_id warp_of_bus[] = {
29         { .compatible = "ibm,plb4", },
30         { .compatible = "ibm,opb", },
31         { .compatible = "ibm,ebc", },
32         {},
33 };
34
35 static int __init warp_device_probe(void)
36 {
37         of_platform_bus_probe(NULL, warp_of_bus, NULL);
38         return 0;
39 }
40 machine_device_initcall(warp, warp_device_probe);
41
42 static int __init warp_probe(void)
43 {
44         unsigned long root = of_get_flat_dt_root();
45
46         return of_flat_dt_is_compatible(root, "pika,warp");
47 }
48
49 define_machine(warp) {
50         .name           = "Warp",
51         .probe          = warp_probe,
52         .progress       = udbg_progress,
53         .init_IRQ       = uic_init_tree,
54         .get_irq        = uic_get_irq,
55         .restart        = ppc4xx_reset_system,
56         .calibrate_decr = generic_calibrate_decr,
57 };
58
59
60 static u32 post_info;
61
62 /* I am not sure this is the best place for this... */
63 static int __init warp_post_info(void)
64 {
65         struct device_node *np;
66         void __iomem *fpga;
67         u32 post1, post2;
68
69         /* Sighhhh... POST information is in the sd area. */
70         np = of_find_compatible_node(NULL, NULL, "pika,fpga-sd");
71         if (np == NULL)
72                 return -ENOENT;
73
74         fpga = of_iomap(np, 0);
75         of_node_put(np);
76         if (fpga == NULL)
77                 return -ENOENT;
78
79         post1 = in_be32(fpga + 0x40);
80         post2 = in_be32(fpga + 0x44);
81
82         iounmap(fpga);
83
84         if (post1 || post2) {
85                 printk(KERN_INFO "Warp POST %08x %08x\n", post1, post2);
86                 post_info = 1;
87         } else
88                 printk(KERN_INFO "Warp POST OK\n");
89
90         return 0;
91 }
92
93
94 #ifdef CONFIG_SENSORS_AD7414
95
96 static LIST_HEAD(dtm_shutdown_list);
97 static void __iomem *dtm_fpga;
98 static unsigned green_led, red_led;
99
100
101 struct dtm_shutdown {
102         struct list_head list;
103         void (*func)(void *arg);
104         void *arg;
105 };
106
107
108 int pika_dtm_register_shutdown(void (*func)(void *arg), void *arg)
109 {
110         struct dtm_shutdown *shutdown;
111
112         shutdown = kmalloc(sizeof(struct dtm_shutdown), GFP_KERNEL);
113         if (shutdown == NULL)
114                 return -ENOMEM;
115
116         shutdown->func = func;
117         shutdown->arg = arg;
118
119         list_add(&shutdown->list, &dtm_shutdown_list);
120
121         return 0;
122 }
123
124 int pika_dtm_unregister_shutdown(void (*func)(void *arg), void *arg)
125 {
126         struct dtm_shutdown *shutdown;
127
128         list_for_each_entry(shutdown, &dtm_shutdown_list, list)
129                 if (shutdown->func == func && shutdown->arg == arg) {
130                         list_del(&shutdown->list);
131                         kfree(shutdown);
132                         return 0;
133                 }
134
135         return -EINVAL;
136 }
137
138 static irqreturn_t temp_isr(int irq, void *context)
139 {
140         struct dtm_shutdown *shutdown;
141         int value = 1;
142
143         local_irq_disable();
144
145         gpio_set_value(green_led, 0);
146
147         /* Run through the shutdown list. */
148         list_for_each_entry(shutdown, &dtm_shutdown_list, list)
149                 shutdown->func(shutdown->arg);
150
151         printk(KERN_EMERG "\n\nCritical Temperature Shutdown\n\n");
152
153         while (1) {
154                 if (dtm_fpga) {
155                         unsigned reset = in_be32(dtm_fpga + 0x14);
156                         out_be32(dtm_fpga + 0x14, reset);
157                 }
158
159                 gpio_set_value(red_led, value);
160                 value ^= 1;
161                 mdelay(500);
162         }
163 }
164
165 static int pika_setup_leds(void)
166 {
167         struct device_node *np, *child;
168
169         np = of_find_compatible_node(NULL, NULL, "gpio-leds");
170         if (!np) {
171                 printk(KERN_ERR __FILE__ ": Unable to find leds\n");
172                 return -ENOENT;
173         }
174
175         for_each_child_of_node(np, child)
176                 if (strcmp(child->name, "green") == 0) {
177                         green_led = of_get_gpio(child, 0);
178                         /* Turn back on the green LED */
179                         gpio_set_value(green_led, 1);
180                 } else if (strcmp(child->name, "red") == 0) {
181                         red_led = of_get_gpio(child, 0);
182                         /* Set based on post */
183                         gpio_set_value(red_led, post_info);
184                 }
185
186         of_node_put(np);
187
188         return 0;
189 }
190
191 static void pika_setup_critical_temp(struct i2c_client *client)
192 {
193         struct device_node *np;
194         int irq, rc;
195
196         /* Do this before enabling critical temp interrupt since we
197          * may immediately interrupt.
198          */
199         pika_setup_leds();
200
201         /* These registers are in 1 degree increments. */
202         i2c_smbus_write_byte_data(client, 2, 65); /* Thigh */
203         i2c_smbus_write_byte_data(client, 3,  0); /* Tlow */
204
205         np = of_find_compatible_node(NULL, NULL, "adi,ad7414");
206         if (np == NULL) {
207                 printk(KERN_ERR __FILE__ ": Unable to find ad7414\n");
208                 return;
209         }
210
211         irq = irq_of_parse_and_map(np, 0);
212         of_node_put(np);
213         if (irq  == NO_IRQ) {
214                 printk(KERN_ERR __FILE__ ": Unable to get ad7414 irq\n");
215                 return;
216         }
217
218         rc = request_irq(irq, temp_isr, 0, "ad7414", NULL);
219         if (rc) {
220                 printk(KERN_ERR __FILE__
221                        ": Unable to request ad7414 irq %d = %d\n", irq, rc);
222                 return;
223         }
224 }
225
226 static inline void pika_dtm_check_fan(void __iomem *fpga)
227 {
228         static int fan_state;
229         u32 fan = in_be32(fpga + 0x34) & (1 << 14);
230
231         if (fan_state != fan) {
232                 fan_state = fan;
233                 if (fan)
234                         printk(KERN_WARNING "Fan rotation error detected."
235                                    " Please check hardware.\n");
236         }
237 }
238
239 static int pika_dtm_thread(void __iomem *fpga)
240 {
241         struct i2c_adapter *adap;
242         struct i2c_client *client;
243
244         /* We loop in case either driver was compiled as a module and
245          * has not been insmoded yet.
246          */
247         while (!(adap = i2c_get_adapter(0))) {
248                 set_current_state(TASK_INTERRUPTIBLE);
249                 schedule_timeout(HZ);
250         }
251
252         while (1) {
253                 list_for_each_entry(client, &adap->clients, list)
254                         if (client->addr == 0x4a)
255                                 goto found_it;
256
257                 set_current_state(TASK_INTERRUPTIBLE);
258                 schedule_timeout(HZ);
259         }
260
261 found_it:
262         pika_setup_critical_temp(client);
263
264         i2c_put_adapter(adap);
265
266         printk(KERN_INFO "PIKA DTM thread running.\n");
267
268         while (!kthread_should_stop()) {
269                 int val;
270
271                 val = i2c_smbus_read_word_data(client, 0);
272                 if (val < 0)
273                         dev_dbg(&client->dev, "DTM read temp failed.\n");
274                 else {
275                         s16 temp = swab16(val);
276                         out_be32(fpga + 0x20, temp);
277                 }
278
279                 pika_dtm_check_fan(fpga);
280
281                 set_current_state(TASK_INTERRUPTIBLE);
282                 schedule_timeout(HZ);
283         }
284
285         return 0;
286 }
287
288
289 static int __init pika_dtm_start(void)
290 {
291         struct task_struct *dtm_thread;
292         struct device_node *np;
293
294         np = of_find_compatible_node(NULL, NULL, "pika,fpga");
295         if (np == NULL)
296                 return -ENOENT;
297
298         dtm_fpga = of_iomap(np, 0);
299         of_node_put(np);
300         if (dtm_fpga == NULL)
301                 return -ENOENT;
302
303         /* Must get post info before thread starts. */
304         warp_post_info();
305
306         dtm_thread = kthread_run(pika_dtm_thread, dtm_fpga, "pika-dtm");
307         if (IS_ERR(dtm_thread)) {
308                 iounmap(dtm_fpga);
309                 return PTR_ERR(dtm_thread);
310         }
311
312         return 0;
313 }
314 machine_late_initcall(warp, pika_dtm_start);
315
316 #else /* !CONFIG_SENSORS_AD7414 */
317
318 int pika_dtm_register_shutdown(void (*func)(void *arg), void *arg)
319 {
320         return 0;
321 }
322
323 int pika_dtm_unregister_shutdown(void (*func)(void *arg), void *arg)
324 {
325         return 0;
326 }
327
328 machine_late_initcall(warp, warp_post_info);
329
330 #endif
331
332 EXPORT_SYMBOL(pika_dtm_register_shutdown);
333 EXPORT_SYMBOL(pika_dtm_unregister_shutdown);