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