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 /* For arch_dma_alloc */ 47 ISA_DMA_THRESHOLD = ~0L; 48 49 return 1; 50 } 51 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 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 static unsigned green_led, red_led; 98 99 100 struct dtm_shutdown { 101 struct list_head list; 102 void (*func)(void *arg); 103 void *arg; 104 }; 105 106 107 int pika_dtm_register_shutdown(void (*func)(void *arg), void *arg) 108 { 109 struct dtm_shutdown *shutdown; 110 111 shutdown = kmalloc(sizeof(struct dtm_shutdown), GFP_KERNEL); 112 if (shutdown == NULL) 113 return -ENOMEM; 114 115 shutdown->func = func; 116 shutdown->arg = arg; 117 118 list_add(&shutdown->list, &dtm_shutdown_list); 119 120 return 0; 121 } 122 123 int pika_dtm_unregister_shutdown(void (*func)(void *arg), void *arg) 124 { 125 struct dtm_shutdown *shutdown; 126 127 list_for_each_entry(shutdown, &dtm_shutdown_list, list) 128 if (shutdown->func == func && shutdown->arg == arg) { 129 list_del(&shutdown->list); 130 kfree(shutdown); 131 return 0; 132 } 133 134 return -EINVAL; 135 } 136 137 static irqreturn_t temp_isr(int irq, void *context) 138 { 139 struct dtm_shutdown *shutdown; 140 int value = 1; 141 142 local_irq_disable(); 143 144 gpio_set_value(green_led, 0); 145 146 /* Run through the shutdown list. */ 147 list_for_each_entry(shutdown, &dtm_shutdown_list, list) 148 shutdown->func(shutdown->arg); 149 150 printk(KERN_EMERG "\n\nCritical Temperature Shutdown\n\n"); 151 152 while (1) { 153 if (dtm_fpga) { 154 unsigned reset = in_be32(dtm_fpga + 0x14); 155 out_be32(dtm_fpga + 0x14, reset); 156 } 157 158 gpio_set_value(red_led, value); 159 value ^= 1; 160 mdelay(500); 161 } 162 163 /* Not reached */ 164 return IRQ_HANDLED; 165 } 166 167 static int pika_setup_leds(void) 168 { 169 struct device_node *np, *child; 170 171 np = of_find_compatible_node(NULL, NULL, "gpio-leds"); 172 if (!np) { 173 printk(KERN_ERR __FILE__ ": Unable to find leds\n"); 174 return -ENOENT; 175 } 176 177 for_each_child_of_node(np, child) 178 if (of_node_name_eq(child, "green")) 179 green_led = of_get_gpio(child, 0); 180 else if (of_node_name_eq(child, "red")) 181 red_led = of_get_gpio(child, 0); 182 183 of_node_put(np); 184 185 return 0; 186 } 187 188 static void pika_setup_critical_temp(struct device_node *np, 189 struct i2c_client *client) 190 { 191 int irq, rc; 192 193 /* Do this before enabling critical temp interrupt since we 194 * may immediately interrupt. 195 */ 196 pika_setup_leds(); 197 198 /* These registers are in 1 degree increments. */ 199 i2c_smbus_write_byte_data(client, 2, 65); /* Thigh */ 200 i2c_smbus_write_byte_data(client, 3, 0); /* Tlow */ 201 202 irq = irq_of_parse_and_map(np, 0); 203 if (!irq) { 204 printk(KERN_ERR __FILE__ ": Unable to get ad7414 irq\n"); 205 return; 206 } 207 208 rc = request_irq(irq, temp_isr, 0, "ad7414", NULL); 209 if (rc) { 210 printk(KERN_ERR __FILE__ 211 ": Unable to request ad7414 irq %d = %d\n", irq, rc); 212 return; 213 } 214 } 215 216 static inline void pika_dtm_check_fan(void __iomem *fpga) 217 { 218 static int fan_state; 219 u32 fan = in_be32(fpga + 0x34) & (1 << 14); 220 221 if (fan_state != fan) { 222 fan_state = fan; 223 if (fan) 224 printk(KERN_WARNING "Fan rotation error detected." 225 " Please check hardware.\n"); 226 } 227 } 228 229 static int pika_dtm_thread(void __iomem *fpga) 230 { 231 struct device_node *np; 232 struct i2c_client *client; 233 234 np = of_find_compatible_node(NULL, NULL, "adi,ad7414"); 235 if (np == NULL) 236 return -ENOENT; 237 238 client = of_find_i2c_device_by_node(np); 239 if (client == NULL) { 240 of_node_put(np); 241 return -ENOENT; 242 } 243 244 pika_setup_critical_temp(np, client); 245 246 of_node_put(np); 247 248 printk(KERN_INFO "Warp DTM thread running.\n"); 249 250 while (!kthread_should_stop()) { 251 int val; 252 253 val = i2c_smbus_read_word_data(client, 0); 254 if (val < 0) 255 dev_dbg(&client->dev, "DTM read temp failed.\n"); 256 else { 257 s16 temp = swab16(val); 258 out_be32(fpga + 0x20, temp); 259 } 260 261 pika_dtm_check_fan(fpga); 262 263 set_current_state(TASK_INTERRUPTIBLE); 264 schedule_timeout(HZ); 265 } 266 267 return 0; 268 } 269 270 static int __init pika_dtm_start(void) 271 { 272 struct task_struct *dtm_thread; 273 struct device_node *np; 274 275 np = of_find_compatible_node(NULL, NULL, "pika,fpga"); 276 if (np == NULL) 277 return -ENOENT; 278 279 dtm_fpga = of_iomap(np, 0); 280 of_node_put(np); 281 if (dtm_fpga == NULL) 282 return -ENOENT; 283 284 /* Must get post info before thread starts. */ 285 warp_post_info(); 286 287 dtm_thread = kthread_run(pika_dtm_thread, dtm_fpga, "pika-dtm"); 288 if (IS_ERR(dtm_thread)) { 289 iounmap(dtm_fpga); 290 return PTR_ERR(dtm_thread); 291 } 292 293 return 0; 294 } 295 machine_late_initcall(warp, pika_dtm_start); 296 297 #else /* !CONFIG_SENSORS_AD7414 */ 298 299 int pika_dtm_register_shutdown(void (*func)(void *arg), void *arg) 300 { 301 return 0; 302 } 303 304 int pika_dtm_unregister_shutdown(void (*func)(void *arg), void *arg) 305 { 306 return 0; 307 } 308 309 machine_late_initcall(warp, warp_post_info); 310 311 #endif 312 313 EXPORT_SYMBOL(pika_dtm_register_shutdown); 314 EXPORT_SYMBOL(pika_dtm_unregister_shutdown); 315