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 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 44 define_machine(warp) { 45 .name = "Warp", 46 .compatible = "pika,warp", 47 .progress = udbg_progress, 48 .init_IRQ = uic_init_tree, 49 .get_irq = uic_get_irq, 50 .restart = ppc4xx_reset_system, 51 .calibrate_decr = generic_calibrate_decr, 52 }; 53 54 55 static int __init warp_post_info(void) 56 { 57 struct device_node *np; 58 void __iomem *fpga; 59 u32 post1, post2; 60 61 /* Sighhhh... POST information is in the sd area. */ 62 np = of_find_compatible_node(NULL, NULL, "pika,fpga-sd"); 63 if (np == NULL) 64 return -ENOENT; 65 66 fpga = of_iomap(np, 0); 67 of_node_put(np); 68 if (fpga == NULL) 69 return -ENOENT; 70 71 post1 = in_be32(fpga + 0x40); 72 post2 = in_be32(fpga + 0x44); 73 74 iounmap(fpga); 75 76 if (post1 || post2) 77 printk(KERN_INFO "Warp POST %08x %08x\n", post1, post2); 78 else 79 printk(KERN_INFO "Warp POST OK\n"); 80 81 return 0; 82 } 83 84 85 #ifdef CONFIG_SENSORS_AD7414 86 87 static LIST_HEAD(dtm_shutdown_list); 88 static void __iomem *dtm_fpga; 89 90 struct dtm_shutdown { 91 struct list_head list; 92 void (*func)(void *arg); 93 void *arg; 94 }; 95 96 int pika_dtm_register_shutdown(void (*func)(void *arg), void *arg) 97 { 98 struct dtm_shutdown *shutdown; 99 100 shutdown = kmalloc(sizeof(struct dtm_shutdown), GFP_KERNEL); 101 if (shutdown == NULL) 102 return -ENOMEM; 103 104 shutdown->func = func; 105 shutdown->arg = arg; 106 107 list_add(&shutdown->list, &dtm_shutdown_list); 108 109 return 0; 110 } 111 112 int pika_dtm_unregister_shutdown(void (*func)(void *arg), void *arg) 113 { 114 struct dtm_shutdown *shutdown; 115 116 list_for_each_entry(shutdown, &dtm_shutdown_list, list) 117 if (shutdown->func == func && shutdown->arg == arg) { 118 list_del(&shutdown->list); 119 kfree(shutdown); 120 return 0; 121 } 122 123 return -EINVAL; 124 } 125 126 #define WARP_GREEN_LED 0 127 #define WARP_RED_LED 1 128 129 static struct gpio_led warp_gpio_led_pins[] = { 130 [WARP_GREEN_LED] = { 131 .name = "green", 132 .default_state = LEDS_DEFSTATE_KEEP, 133 .gpiod = NULL, /* to be filled by pika_setup_leds() */ 134 }, 135 [WARP_RED_LED] = { 136 .name = "red", 137 .default_state = LEDS_DEFSTATE_KEEP, 138 .gpiod = NULL, /* to be filled by pika_setup_leds() */ 139 }, 140 }; 141 142 static struct gpio_led_platform_data warp_gpio_led_data = { 143 .leds = warp_gpio_led_pins, 144 .num_leds = ARRAY_SIZE(warp_gpio_led_pins), 145 }; 146 147 static struct platform_device warp_gpio_leds = { 148 .name = "leds-gpio", 149 .id = -1, 150 .dev = { 151 .platform_data = &warp_gpio_led_data, 152 }, 153 }; 154 155 static irqreturn_t temp_isr(int irq, void *context) 156 { 157 struct dtm_shutdown *shutdown; 158 int value = 1; 159 160 local_irq_disable(); 161 162 gpiod_set_value(warp_gpio_led_pins[WARP_GREEN_LED].gpiod, 0); 163 164 /* Run through the shutdown list. */ 165 list_for_each_entry(shutdown, &dtm_shutdown_list, list) 166 shutdown->func(shutdown->arg); 167 168 printk(KERN_EMERG "\n\nCritical Temperature Shutdown\n\n"); 169 170 while (1) { 171 if (dtm_fpga) { 172 unsigned reset = in_be32(dtm_fpga + 0x14); 173 out_be32(dtm_fpga + 0x14, reset); 174 } 175 176 gpiod_set_value(warp_gpio_led_pins[WARP_RED_LED].gpiod, value); 177 value ^= 1; 178 mdelay(500); 179 } 180 181 /* Not reached */ 182 return IRQ_HANDLED; 183 } 184 185 /* 186 * Because green and red power LEDs are normally driven by leds-gpio driver, 187 * but in case of critical temperature shutdown we want to drive them 188 * ourselves, we acquire both and then create leds-gpio platform device 189 * ourselves, instead of doing it through device tree. This way we can still 190 * keep access to the gpios and use them when needed. 191 */ 192 static int pika_setup_leds(void) 193 { 194 struct device_node *np, *child; 195 struct gpio_desc *gpio; 196 struct gpio_led *led; 197 int led_count = 0; 198 int error; 199 int i; 200 201 np = of_find_compatible_node(NULL, NULL, "warp-power-leds"); 202 if (!np) { 203 printk(KERN_ERR __FILE__ ": Unable to find leds\n"); 204 return -ENOENT; 205 } 206 207 for_each_child_of_node(np, child) { 208 for (i = 0; i < ARRAY_SIZE(warp_gpio_led_pins); i++) { 209 led = &warp_gpio_led_pins[i]; 210 211 if (!of_node_name_eq(child, led->name)) 212 continue; 213 214 if (led->gpiod) { 215 printk(KERN_ERR __FILE__ ": %s led has already been defined\n", 216 led->name); 217 continue; 218 } 219 220 gpio = fwnode_gpiod_get_index(of_fwnode_handle(child), 221 NULL, 0, GPIOD_ASIS, 222 led->name); 223 error = PTR_ERR_OR_ZERO(gpio); 224 if (error) { 225 printk(KERN_ERR __FILE__ ": Failed to get %s led gpio: %d\n", 226 led->name, error); 227 of_node_put(child); 228 goto err_cleanup_pins; 229 } 230 231 led->gpiod = gpio; 232 led_count++; 233 } 234 } 235 236 of_node_put(np); 237 238 /* Skip device registration if no leds have been defined */ 239 if (led_count) { 240 error = platform_device_register(&warp_gpio_leds); 241 if (error) { 242 printk(KERN_ERR __FILE__ ": Unable to add leds-gpio: %d\n", 243 error); 244 goto err_cleanup_pins; 245 } 246 } 247 248 return 0; 249 250 err_cleanup_pins: 251 for (i = 0; i < ARRAY_SIZE(warp_gpio_led_pins); i++) { 252 led = &warp_gpio_led_pins[i]; 253 gpiod_put(led->gpiod); 254 led->gpiod = NULL; 255 } 256 return error; 257 } 258 259 static void pika_setup_critical_temp(struct device_node *np, 260 struct i2c_client *client) 261 { 262 int irq, rc; 263 264 /* Do this before enabling critical temp interrupt since we 265 * may immediately interrupt. 266 */ 267 pika_setup_leds(); 268 269 /* These registers are in 1 degree increments. */ 270 i2c_smbus_write_byte_data(client, 2, 65); /* Thigh */ 271 i2c_smbus_write_byte_data(client, 3, 0); /* Tlow */ 272 273 irq = irq_of_parse_and_map(np, 0); 274 if (!irq) { 275 printk(KERN_ERR __FILE__ ": Unable to get ad7414 irq\n"); 276 return; 277 } 278 279 rc = request_irq(irq, temp_isr, 0, "ad7414", NULL); 280 if (rc) { 281 printk(KERN_ERR __FILE__ 282 ": Unable to request ad7414 irq %d = %d\n", irq, rc); 283 return; 284 } 285 } 286 287 static inline void pika_dtm_check_fan(void __iomem *fpga) 288 { 289 static int fan_state; 290 u32 fan = in_be32(fpga + 0x34) & (1 << 14); 291 292 if (fan_state != fan) { 293 fan_state = fan; 294 if (fan) 295 printk(KERN_WARNING "Fan rotation error detected." 296 " Please check hardware.\n"); 297 } 298 } 299 300 static int pika_dtm_thread(void __iomem *fpga) 301 { 302 struct device_node *np; 303 struct i2c_client *client; 304 305 np = of_find_compatible_node(NULL, NULL, "adi,ad7414"); 306 if (np == NULL) 307 return -ENOENT; 308 309 client = of_find_i2c_device_by_node(np); 310 if (client == NULL) { 311 of_node_put(np); 312 return -ENOENT; 313 } 314 315 pika_setup_critical_temp(np, client); 316 317 of_node_put(np); 318 319 printk(KERN_INFO "Warp DTM thread running.\n"); 320 321 while (!kthread_should_stop()) { 322 int val; 323 324 val = i2c_smbus_read_word_data(client, 0); 325 if (val < 0) 326 dev_dbg(&client->dev, "DTM read temp failed.\n"); 327 else { 328 s16 temp = swab16(val); 329 out_be32(fpga + 0x20, temp); 330 } 331 332 pika_dtm_check_fan(fpga); 333 334 set_current_state(TASK_INTERRUPTIBLE); 335 schedule_timeout(HZ); 336 } 337 338 return 0; 339 } 340 341 static int __init pika_dtm_start(void) 342 { 343 struct task_struct *dtm_thread; 344 struct device_node *np; 345 346 np = of_find_compatible_node(NULL, NULL, "pika,fpga"); 347 if (np == NULL) 348 return -ENOENT; 349 350 dtm_fpga = of_iomap(np, 0); 351 of_node_put(np); 352 if (dtm_fpga == NULL) 353 return -ENOENT; 354 355 /* Must get post info before thread starts. */ 356 warp_post_info(); 357 358 dtm_thread = kthread_run(pika_dtm_thread, dtm_fpga, "pika-dtm"); 359 if (IS_ERR(dtm_thread)) { 360 iounmap(dtm_fpga); 361 return PTR_ERR(dtm_thread); 362 } 363 364 return 0; 365 } 366 machine_late_initcall(warp, pika_dtm_start); 367 368 #else /* !CONFIG_SENSORS_AD7414 */ 369 370 int pika_dtm_register_shutdown(void (*func)(void *arg), void *arg) 371 { 372 return 0; 373 } 374 375 int pika_dtm_unregister_shutdown(void (*func)(void *arg), void *arg) 376 { 377 return 0; 378 } 379 380 machine_late_initcall(warp, warp_post_info); 381 382 #endif 383 384 EXPORT_SYMBOL(pika_dtm_register_shutdown); 385 EXPORT_SYMBOL(pika_dtm_unregister_shutdown); 386