warp.c (14e77332e74603efab8347c89d3cda447c3b97c9) | warp.c (1892e87a3e9170146549779622cb844582f1e2bb) |
---|---|
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 */ | 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> |
|
8#include <linux/init.h> 9#include <linux/of_platform.h> 10#include <linux/kthread.h> | 9#include <linux/init.h> 10#include <linux/of_platform.h> 11#include <linux/kthread.h> |
12#include <linux/leds.h> |
|
11#include <linux/i2c.h> 12#include <linux/interrupt.h> 13#include <linux/delay.h> 14#include <linux/of_address.h> 15#include <linux/of_irq.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> |
16#include <linux/of_gpio.h> | 18#include <linux/gpio/consumer.h> |
17#include <linux/slab.h> 18#include <linux/export.h> 19 20#include <asm/machdep.h> 21#include <asm/udbg.h> 22#include <asm/time.h> 23#include <asm/uic.h> 24#include <asm/ppc4xx.h> --- 62 unchanged lines hidden (view full) --- 87 return 0; 88} 89 90 91#ifdef CONFIG_SENSORS_AD7414 92 93static LIST_HEAD(dtm_shutdown_list); 94static void __iomem *dtm_fpga; | 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> --- 62 unchanged lines hidden (view full) --- 89 return 0; 90} 91 92 93#ifdef CONFIG_SENSORS_AD7414 94 95static LIST_HEAD(dtm_shutdown_list); 96static void __iomem *dtm_fpga; |
95static unsigned green_led, red_led; | |
96 | 97 |
97 | |
98struct dtm_shutdown { 99 struct list_head list; 100 void (*func)(void *arg); 101 void *arg; 102}; 103 | 98struct dtm_shutdown { 99 struct list_head list; 100 void (*func)(void *arg); 101 void *arg; 102}; 103 |
104 | |
105int pika_dtm_register_shutdown(void (*func)(void *arg), void *arg) 106{ 107 struct dtm_shutdown *shutdown; 108 109 shutdown = kmalloc(sizeof(struct dtm_shutdown), GFP_KERNEL); 110 if (shutdown == NULL) 111 return -ENOMEM; 112 --- 14 unchanged lines hidden (view full) --- 127 list_del(&shutdown->list); 128 kfree(shutdown); 129 return 0; 130 } 131 132 return -EINVAL; 133} 134 | 104int 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 --- 14 unchanged lines hidden (view full) --- 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 137static 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 150static 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 155static 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 |
|
135static irqreturn_t temp_isr(int irq, void *context) 136{ 137 struct dtm_shutdown *shutdown; 138 int value = 1; 139 140 local_irq_disable(); 141 | 163static irqreturn_t temp_isr(int irq, void *context) 164{ 165 struct dtm_shutdown *shutdown; 166 int value = 1; 167 168 local_irq_disable(); 169 |
142 gpio_set_value(green_led, 0); | 170 gpiod_set_value(warp_gpio_led_pins[WARP_GREEN_LED].gpiod, 0); |
143 144 /* Run through the shutdown list. */ 145 list_for_each_entry(shutdown, &dtm_shutdown_list, list) 146 shutdown->func(shutdown->arg); 147 148 printk(KERN_EMERG "\n\nCritical Temperature Shutdown\n\n"); 149 150 while (1) { 151 if (dtm_fpga) { 152 unsigned reset = in_be32(dtm_fpga + 0x14); 153 out_be32(dtm_fpga + 0x14, reset); 154 } 155 | 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 |
156 gpio_set_value(red_led, value); | 184 gpiod_set_value(warp_gpio_led_pins[WARP_RED_LED].gpiod, value); |
157 value ^= 1; 158 mdelay(500); 159 } 160 161 /* Not reached */ 162 return IRQ_HANDLED; 163} 164 | 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 */ |
|
165static int pika_setup_leds(void) 166{ 167 struct device_node *np, *child; | 200static 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; |
|
168 | 208 |
169 np = of_find_compatible_node(NULL, NULL, "gpio-leds"); | 209 np = of_find_compatible_node(NULL, NULL, "warp-power-leds"); |
170 if (!np) { 171 printk(KERN_ERR __FILE__ ": Unable to find leds\n"); 172 return -ENOENT; 173 } 174 | 210 if (!np) { 211 printk(KERN_ERR __FILE__ ": Unable to find leds\n"); 212 return -ENOENT; 213 } 214 |
175 for_each_child_of_node(np, child) 176 if (of_node_name_eq(child, "green")) 177 green_led = of_get_gpio(child, 0); 178 else if (of_node_name_eq(child, "red")) 179 red_led = of_get_gpio(child, 0); | 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]; |
180 | 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 |
|
181 of_node_put(np); 182 | 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 |
|
183 return 0; | 256 return 0; |
257 258err_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; |
|
184} 185 186static void pika_setup_critical_temp(struct device_node *np, 187 struct i2c_client *client) 188{ 189 int irq, rc; 190 191 /* Do this before enabling critical temp interrupt since we --- 121 unchanged lines hidden --- | 265} 266 267static 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 --- 121 unchanged lines hidden --- |