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/init.h> 9 #include <linux/of_platform.h> 10 #include <linux/kthread.h> 11 #include <linux/i2c.h> 12 #include <linux/interrupt.h> 13 #include <linux/delay.h> 14 #include <linux/of_gpio.h> 15 #include <linux/slab.h> 16 #include <linux/export.h> 17 18 #include <asm/machdep.h> 19 #include <asm/prom.h> 20 #include <asm/udbg.h> 21 #include <asm/time.h> 22 #include <asm/uic.h> 23 #include <asm/ppc4xx.h> 24 #include <asm/dma.h> 25 26 27 static const struct of_device_id warp_of_bus[] __initconst = { 28 { .compatible = "ibm,plb4", }, 29 { .compatible = "ibm,opb", }, 30 { .compatible = "ibm,ebc", }, 31 {}, 32 }; 33 34 static int __init warp_device_probe(void) 35 { 36 of_platform_bus_probe(NULL, warp_of_bus, NULL); 37 return 0; 38 } 39 machine_device_initcall(warp, warp_device_probe); 40 41 static int __init warp_probe(void) 42 { 43 if (!of_machine_is_compatible("pika,warp")) 44 return 0; 45 46 return 1; 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 int __init warp_post_info(void) 61 { 62 struct device_node *np; 63 void __iomem *fpga; 64 u32 post1, post2; 65 66 /* Sighhhh... POST information is in the sd area. */ 67 np = of_find_compatible_node(NULL, NULL, "pika,fpga-sd"); 68 if (np == NULL) 69 return -ENOENT; 70 71 fpga = of_iomap(np, 0); 72 of_node_put(np); 73 if (fpga == NULL) 74 return -ENOENT; 75 76 post1 = in_be32(fpga + 0x40); 77 post2 = in_be32(fpga + 0x44); 78 79 iounmap(fpga); 80 81 if (post1 || post2) 82 printk(KERN_INFO "Warp POST %08x %08x\n", post1, post2); 83 else 84 printk(KERN_INFO "Warp POST OK\n"); 85 86 return 0; 87 } 88 89 90 #ifdef CONFIG_SENSORS_AD7414 91 92 static LIST_HEAD(dtm_shutdown_list); 93 static void __iomem *dtm_fpga; 94 static unsigned green_led, red_led; 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 int value = 1; 138 139 local_irq_disable(); 140 141 gpio_set_value(green_led, 0); 142 143 /* Run through the shutdown list. */ 144 list_for_each_entry(shutdown, &dtm_shutdown_list, list) 145 shutdown->func(shutdown->arg); 146 147 printk(KERN_EMERG "\n\nCritical Temperature Shutdown\n\n"); 148 149 while (1) { 150 if (dtm_fpga) { 151 unsigned reset = in_be32(dtm_fpga + 0x14); 152 out_be32(dtm_fpga + 0x14, reset); 153 } 154 155 gpio_set_value(red_led, value); 156 value ^= 1; 157 mdelay(500); 158 } 159 160 /* Not reached */ 161 return IRQ_HANDLED; 162 } 163 164 static int pika_setup_leds(void) 165 { 166 struct device_node *np, *child; 167 168 np = of_find_compatible_node(NULL, NULL, "gpio-leds"); 169 if (!np) { 170 printk(KERN_ERR __FILE__ ": Unable to find leds\n"); 171 return -ENOENT; 172 } 173 174 for_each_child_of_node(np, child) 175 if (of_node_name_eq(child, "green")) 176 green_led = of_get_gpio(child, 0); 177 else if (of_node_name_eq(child, "red")) 178 red_led = of_get_gpio(child, 0); 179 180 of_node_put(np); 181 182 return 0; 183 } 184 185 static void pika_setup_critical_temp(struct device_node *np, 186 struct i2c_client *client) 187 { 188 int irq, rc; 189 190 /* Do this before enabling critical temp interrupt since we 191 * may immediately interrupt. 192 */ 193 pika_setup_leds(); 194 195 /* These registers are in 1 degree increments. */ 196 i2c_smbus_write_byte_data(client, 2, 65); /* Thigh */ 197 i2c_smbus_write_byte_data(client, 3, 0); /* Tlow */ 198 199 irq = irq_of_parse_and_map(np, 0); 200 if (!irq) { 201 printk(KERN_ERR __FILE__ ": Unable to get ad7414 irq\n"); 202 return; 203 } 204 205 rc = request_irq(irq, temp_isr, 0, "ad7414", NULL); 206 if (rc) { 207 printk(KERN_ERR __FILE__ 208 ": Unable to request ad7414 irq %d = %d\n", irq, rc); 209 return; 210 } 211 } 212 213 static inline void pika_dtm_check_fan(void __iomem *fpga) 214 { 215 static int fan_state; 216 u32 fan = in_be32(fpga + 0x34) & (1 << 14); 217 218 if (fan_state != fan) { 219 fan_state = fan; 220 if (fan) 221 printk(KERN_WARNING "Fan rotation error detected." 222 " Please check hardware.\n"); 223 } 224 } 225 226 static int pika_dtm_thread(void __iomem *fpga) 227 { 228 struct device_node *np; 229 struct i2c_client *client; 230 231 np = of_find_compatible_node(NULL, NULL, "adi,ad7414"); 232 if (np == NULL) 233 return -ENOENT; 234 235 client = of_find_i2c_device_by_node(np); 236 if (client == NULL) { 237 of_node_put(np); 238 return -ENOENT; 239 } 240 241 pika_setup_critical_temp(np, client); 242 243 of_node_put(np); 244 245 printk(KERN_INFO "Warp DTM thread running.\n"); 246 247 while (!kthread_should_stop()) { 248 int val; 249 250 val = i2c_smbus_read_word_data(client, 0); 251 if (val < 0) 252 dev_dbg(&client->dev, "DTM read temp failed.\n"); 253 else { 254 s16 temp = swab16(val); 255 out_be32(fpga + 0x20, temp); 256 } 257 258 pika_dtm_check_fan(fpga); 259 260 set_current_state(TASK_INTERRUPTIBLE); 261 schedule_timeout(HZ); 262 } 263 264 return 0; 265 } 266 267 static int __init pika_dtm_start(void) 268 { 269 struct task_struct *dtm_thread; 270 struct device_node *np; 271 272 np = of_find_compatible_node(NULL, NULL, "pika,fpga"); 273 if (np == NULL) 274 return -ENOENT; 275 276 dtm_fpga = of_iomap(np, 0); 277 of_node_put(np); 278 if (dtm_fpga == NULL) 279 return -ENOENT; 280 281 /* Must get post info before thread starts. */ 282 warp_post_info(); 283 284 dtm_thread = kthread_run(pika_dtm_thread, dtm_fpga, "pika-dtm"); 285 if (IS_ERR(dtm_thread)) { 286 iounmap(dtm_fpga); 287 return PTR_ERR(dtm_thread); 288 } 289 290 return 0; 291 } 292 machine_late_initcall(warp, pika_dtm_start); 293 294 #else /* !CONFIG_SENSORS_AD7414 */ 295 296 int pika_dtm_register_shutdown(void (*func)(void *arg), void *arg) 297 { 298 return 0; 299 } 300 301 int pika_dtm_unregister_shutdown(void (*func)(void *arg), void *arg) 302 { 303 return 0; 304 } 305 306 machine_late_initcall(warp, warp_post_info); 307 308 #endif 309 310 EXPORT_SYMBOL(pika_dtm_register_shutdown); 311 EXPORT_SYMBOL(pika_dtm_unregister_shutdown); 312