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