1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * PIKA Warp(tm) board specific routines
4 *
5 * Copyright (c) 2008-2009 PIKA Technologies
6 * Sean MacLennan <smaclennan@pikatech.com>
7 */
8 #include <linux/err.h>
9 #include <linux/init.h>
10 #include <linux/of_platform.h>
11 #include <linux/kthread.h>
12 #include <linux/leds.h>
13 #include <linux/i2c.h>
14 #include <linux/interrupt.h>
15 #include <linux/delay.h>
16 #include <linux/of_address.h>
17 #include <linux/of_irq.h>
18 #include <linux/gpio/consumer.h>
19 #include <linux/slab.h>
20 #include <linux/export.h>
21
22 #include <asm/machdep.h>
23 #include <asm/udbg.h>
24 #include <asm/time.h>
25 #include <asm/uic.h>
26 #include <asm/ppc4xx.h>
27 #include <asm/dma.h>
28
29
30 static const struct of_device_id warp_of_bus[] __initconst = {
31 { .compatible = "ibm,plb4", },
32 { .compatible = "ibm,opb", },
33 { .compatible = "ibm,ebc", },
34 {},
35 };
36
warp_device_probe(void)37 static int __init warp_device_probe(void)
38 {
39 of_platform_bus_probe(NULL, warp_of_bus, NULL);
40 return 0;
41 }
42 machine_device_initcall(warp, warp_device_probe);
43
warp_probe(void)44 static int __init warp_probe(void)
45 {
46 if (!of_machine_is_compatible("pika,warp"))
47 return 0;
48
49 return 1;
50 }
51
define_machine(warp)52 define_machine(warp) {
53 .name = "Warp",
54 .probe = warp_probe,
55 .progress = udbg_progress,
56 .init_IRQ = uic_init_tree,
57 .get_irq = uic_get_irq,
58 .restart = ppc4xx_reset_system,
59 .calibrate_decr = generic_calibrate_decr,
60 };
61
62
warp_post_info(void)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 else
87 printk(KERN_INFO "Warp POST OK\n");
88
89 return 0;
90 }
91
92
93 #ifdef CONFIG_SENSORS_AD7414
94
95 static LIST_HEAD(dtm_shutdown_list);
96 static void __iomem *dtm_fpga;
97
98 struct dtm_shutdown {
99 struct list_head list;
100 void (*func)(void *arg);
101 void *arg;
102 };
103
pika_dtm_register_shutdown(void (* func)(void * arg),void * arg)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
pika_dtm_unregister_shutdown(void (* func)(void * arg),void * arg)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 #define WARP_GREEN_LED 0
135 #define WARP_RED_LED 1
136
137 static struct gpio_led warp_gpio_led_pins[] = {
138 [WARP_GREEN_LED] = {
139 .name = "green",
140 .default_state = LEDS_DEFSTATE_KEEP,
141 .gpiod = NULL, /* to be filled by pika_setup_leds() */
142 },
143 [WARP_RED_LED] = {
144 .name = "red",
145 .default_state = LEDS_DEFSTATE_KEEP,
146 .gpiod = NULL, /* to be filled by pika_setup_leds() */
147 },
148 };
149
150 static struct gpio_led_platform_data warp_gpio_led_data = {
151 .leds = warp_gpio_led_pins,
152 .num_leds = ARRAY_SIZE(warp_gpio_led_pins),
153 };
154
155 static struct platform_device warp_gpio_leds = {
156 .name = "leds-gpio",
157 .id = -1,
158 .dev = {
159 .platform_data = &warp_gpio_led_data,
160 },
161 };
162
temp_isr(int irq,void * context)163 static irqreturn_t temp_isr(int irq, void *context)
164 {
165 struct dtm_shutdown *shutdown;
166 int value = 1;
167
168 local_irq_disable();
169
170 gpiod_set_value(warp_gpio_led_pins[WARP_GREEN_LED].gpiod, 0);
171
172 /* Run through the shutdown list. */
173 list_for_each_entry(shutdown, &dtm_shutdown_list, list)
174 shutdown->func(shutdown->arg);
175
176 printk(KERN_EMERG "\n\nCritical Temperature Shutdown\n\n");
177
178 while (1) {
179 if (dtm_fpga) {
180 unsigned reset = in_be32(dtm_fpga + 0x14);
181 out_be32(dtm_fpga + 0x14, reset);
182 }
183
184 gpiod_set_value(warp_gpio_led_pins[WARP_RED_LED].gpiod, value);
185 value ^= 1;
186 mdelay(500);
187 }
188
189 /* Not reached */
190 return IRQ_HANDLED;
191 }
192
193 /*
194 * Because green and red power LEDs are normally driven by leds-gpio driver,
195 * but in case of critical temperature shutdown we want to drive them
196 * ourselves, we acquire both and then create leds-gpio platform device
197 * ourselves, instead of doing it through device tree. This way we can still
198 * keep access to the gpios and use them when needed.
199 */
pika_setup_leds(void)200 static int pika_setup_leds(void)
201 {
202 struct device_node *np, *child;
203 struct gpio_desc *gpio;
204 struct gpio_led *led;
205 int led_count = 0;
206 int error;
207 int i;
208
209 np = of_find_compatible_node(NULL, NULL, "warp-power-leds");
210 if (!np) {
211 printk(KERN_ERR __FILE__ ": Unable to find leds\n");
212 return -ENOENT;
213 }
214
215 for_each_child_of_node(np, child) {
216 for (i = 0; i < ARRAY_SIZE(warp_gpio_led_pins); i++) {
217 led = &warp_gpio_led_pins[i];
218
219 if (!of_node_name_eq(child, led->name))
220 continue;
221
222 if (led->gpiod) {
223 printk(KERN_ERR __FILE__ ": %s led has already been defined\n",
224 led->name);
225 continue;
226 }
227
228 gpio = fwnode_gpiod_get_index(of_fwnode_handle(child),
229 NULL, 0, GPIOD_ASIS,
230 led->name);
231 error = PTR_ERR_OR_ZERO(gpio);
232 if (error) {
233 printk(KERN_ERR __FILE__ ": Failed to get %s led gpio: %d\n",
234 led->name, error);
235 of_node_put(child);
236 goto err_cleanup_pins;
237 }
238
239 led->gpiod = gpio;
240 led_count++;
241 }
242 }
243
244 of_node_put(np);
245
246 /* Skip device registration if no leds have been defined */
247 if (led_count) {
248 error = platform_device_register(&warp_gpio_leds);
249 if (error) {
250 printk(KERN_ERR __FILE__ ": Unable to add leds-gpio: %d\n",
251 error);
252 goto err_cleanup_pins;
253 }
254 }
255
256 return 0;
257
258 err_cleanup_pins:
259 for (i = 0; i < ARRAY_SIZE(warp_gpio_led_pins); i++) {
260 led = &warp_gpio_led_pins[i];
261 gpiod_put(led->gpiod);
262 led->gpiod = NULL;
263 }
264 return error;
265 }
266
pika_setup_critical_temp(struct device_node * np,struct i2c_client * client)267 static void pika_setup_critical_temp(struct device_node *np,
268 struct i2c_client *client)
269 {
270 int irq, rc;
271
272 /* Do this before enabling critical temp interrupt since we
273 * may immediately interrupt.
274 */
275 pika_setup_leds();
276
277 /* These registers are in 1 degree increments. */
278 i2c_smbus_write_byte_data(client, 2, 65); /* Thigh */
279 i2c_smbus_write_byte_data(client, 3, 0); /* Tlow */
280
281 irq = irq_of_parse_and_map(np, 0);
282 if (!irq) {
283 printk(KERN_ERR __FILE__ ": Unable to get ad7414 irq\n");
284 return;
285 }
286
287 rc = request_irq(irq, temp_isr, 0, "ad7414", NULL);
288 if (rc) {
289 printk(KERN_ERR __FILE__
290 ": Unable to request ad7414 irq %d = %d\n", irq, rc);
291 return;
292 }
293 }
294
pika_dtm_check_fan(void __iomem * fpga)295 static inline void pika_dtm_check_fan(void __iomem *fpga)
296 {
297 static int fan_state;
298 u32 fan = in_be32(fpga + 0x34) & (1 << 14);
299
300 if (fan_state != fan) {
301 fan_state = fan;
302 if (fan)
303 printk(KERN_WARNING "Fan rotation error detected."
304 " Please check hardware.\n");
305 }
306 }
307
pika_dtm_thread(void __iomem * fpga)308 static int pika_dtm_thread(void __iomem *fpga)
309 {
310 struct device_node *np;
311 struct i2c_client *client;
312
313 np = of_find_compatible_node(NULL, NULL, "adi,ad7414");
314 if (np == NULL)
315 return -ENOENT;
316
317 client = of_find_i2c_device_by_node(np);
318 if (client == NULL) {
319 of_node_put(np);
320 return -ENOENT;
321 }
322
323 pika_setup_critical_temp(np, client);
324
325 of_node_put(np);
326
327 printk(KERN_INFO "Warp DTM thread running.\n");
328
329 while (!kthread_should_stop()) {
330 int val;
331
332 val = i2c_smbus_read_word_data(client, 0);
333 if (val < 0)
334 dev_dbg(&client->dev, "DTM read temp failed.\n");
335 else {
336 s16 temp = swab16(val);
337 out_be32(fpga + 0x20, temp);
338 }
339
340 pika_dtm_check_fan(fpga);
341
342 set_current_state(TASK_INTERRUPTIBLE);
343 schedule_timeout(HZ);
344 }
345
346 return 0;
347 }
348
pika_dtm_start(void)349 static int __init pika_dtm_start(void)
350 {
351 struct task_struct *dtm_thread;
352 struct device_node *np;
353
354 np = of_find_compatible_node(NULL, NULL, "pika,fpga");
355 if (np == NULL)
356 return -ENOENT;
357
358 dtm_fpga = of_iomap(np, 0);
359 of_node_put(np);
360 if (dtm_fpga == NULL)
361 return -ENOENT;
362
363 /* Must get post info before thread starts. */
364 warp_post_info();
365
366 dtm_thread = kthread_run(pika_dtm_thread, dtm_fpga, "pika-dtm");
367 if (IS_ERR(dtm_thread)) {
368 iounmap(dtm_fpga);
369 return PTR_ERR(dtm_thread);
370 }
371
372 return 0;
373 }
374 machine_late_initcall(warp, pika_dtm_start);
375
376 #else /* !CONFIG_SENSORS_AD7414 */
377
pika_dtm_register_shutdown(void (* func)(void * arg),void * arg)378 int pika_dtm_register_shutdown(void (*func)(void *arg), void *arg)
379 {
380 return 0;
381 }
382
pika_dtm_unregister_shutdown(void (* func)(void * arg),void * arg)383 int pika_dtm_unregister_shutdown(void (*func)(void *arg), void *arg)
384 {
385 return 0;
386 }
387
388 machine_late_initcall(warp, warp_post_info);
389
390 #endif
391
392 EXPORT_SYMBOL(pika_dtm_register_shutdown);
393 EXPORT_SYMBOL(pika_dtm_unregister_shutdown);
394