root/arch/powerpc/platforms/44x/warp.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. warp_device_probe
  2. warp_probe
  3. define_machine
  4. warp_post_info
  5. pika_dtm_register_shutdown
  6. pika_dtm_unregister_shutdown
  7. temp_isr
  8. pika_setup_leds
  9. pika_setup_critical_temp
  10. pika_dtm_check_fan
  11. pika_dtm_thread
  12. pika_dtm_start
  13. pika_dtm_register_shutdown
  14. pika_dtm_unregister_shutdown

   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);

/* [<][>][^][v][top][bottom][index][help] */