Lines Matching +full:hardware +full:- +full:triggered

1 // SPDX-License-Identifier: GPL-2.0-or-later
6 * Maintainer: René Moll <linux@r-moll.nl>
8 * ----------------------------------------
9 * - Description
10 * ----------------------------------------
13 * Its function is to determine when a external shut down is triggered
18 * ----------------------------------------
19 * - GPIO
20 * ----------------------------------------
23 * - trigger (input)
24 * A level change indicates the shut-down trigger. If it's state reverts
25 * within the time-out defined by trigger_delay, the shut down is not
30 * - watchdog (output)
31 * Once a shut down is triggered, the driver will toggle this signal,
32 * with an internal (wde_interval) to stall the hardware shut down.
34 * - kill (output)
36 * that the PowerPath Control will power down the hardware.
38 * ----------------------------------------
39 * - Interrupts
40 * ----------------------------------------
42 * The driver requires a non-shared, edge-triggered interrupt on the trigger
85 * ltc2952_poweroff_timer_wde - Timer callback
99 if (data->kernel_panic) in ltc2952_poweroff_timer_wde()
102 state = gpiod_get_value(data->gpio_watchdog); in ltc2952_poweroff_timer_wde()
103 gpiod_set_value(data->gpio_watchdog, !state); in ltc2952_poweroff_timer_wde()
106 hrtimer_forward(timer, now, data->wde_interval); in ltc2952_poweroff_timer_wde()
113 hrtimer_start(&data->timer_wde, data->wde_interval, HRTIMER_MODE_REL); in ltc2952_poweroff_start_wde()
122 dev_info(data->dev, "executing shutdown\n"); in ltc2952_poweroff_timer_trigger()
129 * ltc2952_poweroff_handler - Interrupt handler
130 * Triggered each time the trigger signal changes state and (de)activates a
131 * time-out (timer_trigger). Once the time-out is actually reached the shut
141 if (data->kernel_panic || hrtimer_active(&data->timer_wde)) { in ltc2952_poweroff_handler()
142 /* shutdown is already triggered, nothing to do any more */ in ltc2952_poweroff_handler()
146 if (gpiod_get_value(data->gpio_trigger)) { in ltc2952_poweroff_handler()
147 hrtimer_start(&data->timer_trigger, data->trigger_delay, in ltc2952_poweroff_handler()
150 hrtimer_cancel(&data->timer_trigger); in ltc2952_poweroff_handler()
157 gpiod_set_value(ltc2952_data->gpio_kill, 1); in ltc2952_poweroff_kill()
162 data->wde_interval = 300L * 1E6L; in ltc2952_poweroff_default()
163 data->trigger_delay = ktime_set(2, 500L*1E6L); in ltc2952_poweroff_default()
165 hrtimer_init(&data->timer_trigger, CLOCK_MONOTONIC, HRTIMER_MODE_REL); in ltc2952_poweroff_default()
166 data->timer_trigger.function = ltc2952_poweroff_timer_trigger; in ltc2952_poweroff_default()
168 hrtimer_init(&data->timer_wde, CLOCK_MONOTONIC, HRTIMER_MODE_REL); in ltc2952_poweroff_default()
169 data->timer_wde.function = ltc2952_poweroff_timer_wde; in ltc2952_poweroff_default()
179 data->gpio_watchdog = devm_gpiod_get(&pdev->dev, "watchdog", in ltc2952_poweroff_init()
181 if (IS_ERR(data->gpio_watchdog)) { in ltc2952_poweroff_init()
182 ret = PTR_ERR(data->gpio_watchdog); in ltc2952_poweroff_init()
183 dev_err(&pdev->dev, "unable to claim gpio \"watchdog\"\n"); in ltc2952_poweroff_init()
187 data->gpio_kill = devm_gpiod_get(&pdev->dev, "kill", GPIOD_OUT_LOW); in ltc2952_poweroff_init()
188 if (IS_ERR(data->gpio_kill)) { in ltc2952_poweroff_init()
189 ret = PTR_ERR(data->gpio_kill); in ltc2952_poweroff_init()
190 dev_err(&pdev->dev, "unable to claim gpio \"kill\"\n"); in ltc2952_poweroff_init()
194 data->gpio_trigger = devm_gpiod_get_optional(&pdev->dev, "trigger", in ltc2952_poweroff_init()
196 if (IS_ERR(data->gpio_trigger)) { in ltc2952_poweroff_init()
202 dev_err(&pdev->dev, "unable to claim gpio \"trigger\"\n"); in ltc2952_poweroff_init()
203 data->gpio_trigger = NULL; in ltc2952_poweroff_init()
206 if (devm_request_irq(&pdev->dev, gpiod_to_irq(data->gpio_trigger), in ltc2952_poweroff_init()
209 "ltc2952-poweroff", in ltc2952_poweroff_init()
213 * - No trigger input was defined in ltc2952_poweroff_init()
214 * - Claiming the GPIO failed in ltc2952_poweroff_init()
215 * - We could not map to an IRQ in ltc2952_poweroff_init()
216 * - We couldn't register an interrupt handler in ltc2952_poweroff_init()
226 if (data->gpio_trigger) { in ltc2952_poweroff_init()
227 dev_warn(&pdev->dev, in ltc2952_poweroff_init()
229 devm_gpiod_put(&pdev->dev, data->gpio_trigger); in ltc2952_poweroff_init()
230 data->gpio_trigger = NULL; in ltc2952_poweroff_init()
232 dev_info(&pdev->dev, in ltc2952_poweroff_init()
245 data->kernel_panic = true; in ltc2952_poweroff_notify_panic()
255 dev_err(&pdev->dev, "pm_power_off already registered"); in ltc2952_poweroff_probe()
256 return -EBUSY; in ltc2952_poweroff_probe()
259 data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); in ltc2952_poweroff_probe()
261 return -ENOMEM; in ltc2952_poweroff_probe()
263 data->dev = &pdev->dev; in ltc2952_poweroff_probe()
274 data->panic_notifier.notifier_call = ltc2952_poweroff_notify_panic; in ltc2952_poweroff_probe()
276 &data->panic_notifier); in ltc2952_poweroff_probe()
277 dev_info(&pdev->dev, "probe successful\n"); in ltc2952_poweroff_probe()
287 hrtimer_cancel(&data->timer_trigger); in ltc2952_poweroff_remove()
288 hrtimer_cancel(&data->timer_wde); in ltc2952_poweroff_remove()
290 &data->panic_notifier); in ltc2952_poweroff_remove()
304 .name = "ltc2952-poweroff",
312 MODULE_DESCRIPTION("LTC PowerPath power-off driver");