Lines Matching +full:pm +full:- +full:api
1 // SPDX-License-Identifier: GPL-2.0
5 * Copyright (C) 2014-2019 Xilinx, Inc.
19 #include <linux/firmware/xlnx-zynqmp.h>
20 #include <linux/firmware/xlnx-event-manager.h>
21 #include <linux/mailbox/zynqmp-ipi-message.h>
24 * struct zynqmp_pm_work_struct - Wrapper for struct work_struct
34 * struct zynqmp_pm_event_info - event related information
37 * PM_NOTIFY_CB - for Error Events,
38 * PM_INIT_SUSPEND_CB - for suspend callback.
39 * @node_id: Node-Id related to event.
65 [PM_SUSPEND_MODE_POWER_OFF] = "power-off",
77 /* First element is callback API ID, others are callback arguments */ in subsystem_restart_event_callback()
78 if (work_pending(&zynqmp_pm_init_restart_work->callback_work)) in subsystem_restart_event_callback()
82 memcpy(zynqmp_pm_init_restart_work->args, &payload[0], in subsystem_restart_event_callback()
83 sizeof(zynqmp_pm_init_restart_work->args)); in subsystem_restart_event_callback()
85 queue_work(system_unbound_wq, &zynqmp_pm_init_restart_work->callback_work); in subsystem_restart_event_callback()
90 /* First element is callback API ID, others are callback arguments */ in suspend_event_callback()
91 if (work_pending(&zynqmp_pm_init_suspend_work->callback_work)) in suspend_event_callback()
95 memcpy(zynqmp_pm_init_suspend_work->args, &payload[1], in suspend_event_callback()
96 sizeof(zynqmp_pm_init_suspend_work->args)); in suspend_event_callback()
98 queue_work(system_unbound_wq, &zynqmp_pm_init_suspend_work->callback_work); in suspend_event_callback()
107 /* First element is callback API ID, others are callback arguments */ in zynqmp_pm_isr()
133 memcpy(payload, msg->data, sizeof(msg->len)); in ipi_receive_callback()
134 /* First element is callback API ID, others are callback arguments */ in ipi_receive_callback()
136 if (work_pending(&zynqmp_pm_init_suspend_work->callback_work)) in ipi_receive_callback()
140 memcpy(zynqmp_pm_init_suspend_work->args, &payload[1], in ipi_receive_callback()
141 sizeof(zynqmp_pm_init_suspend_work->args)); in ipi_receive_callback()
144 &zynqmp_pm_init_suspend_work->callback_work); in ipi_receive_callback()
154 * zynqmp_pm_subsystem_restart_work_fn - Initiate Subsystem restart
157 * Bottom-half of PM callback IRQ handler.
165 /* First element is callback API ID, others are callback arguments */ in zynqmp_pm_subsystem_restart_work_fn()
166 if (pm_work->args[0] == PM_NOTIFY_CB) { in zynqmp_pm_subsystem_restart_work_fn()
167 if (pm_work->args[2] == EVENT_SUBSYSTEM_RESTART) { in zynqmp_pm_subsystem_restart_work_fn()
177 pr_err("%s Unsupported Event - %d\n", __func__, pm_work->args[2]); in zynqmp_pm_subsystem_restart_work_fn()
180 pr_err("%s() Unsupported Callback %d\n", __func__, pm_work->args[0]); in zynqmp_pm_subsystem_restart_work_fn()
185 * zynqmp_pm_init_suspend_work_fn - Initialize suspend
188 * Bottom-half of PM callback IRQ handler.
195 if (pm_work->args[0] == SUSPEND_SYSTEM_SHUTDOWN) { in zynqmp_pm_init_suspend_work_fn()
197 } else if (pm_work->args[0] == SUSPEND_POWER_REQUEST) { in zynqmp_pm_init_suspend_work_fn()
201 __func__, pm_work->args[0]); in zynqmp_pm_init_suspend_work_fn()
221 *(s - 1) = '\n'; in suspend_mode_show()
222 return (s - buf); in suspend_mode_show()
229 int md, ret = -EINVAL; in suspend_mode_store()
253 xlnx_unregister_event(event_info->cb_type, event_info->node_id, in unregister_event()
254 event_info->event, event_info->cb_fun, NULL); in unregister_event()
266 return -ENOMEM; in register_event()
268 event_info->cb_type = cb_type; in register_event()
269 event_info->node_id = node_id; in register_event()
270 event_info->event = event; in register_event()
271 event_info->wake = wake; in register_event()
272 event_info->cb_fun = cb_fun; in register_event()
274 ret = xlnx_register_event(event_info->cb_type, event_info->node_id, in register_event()
275 event_info->event, event_info->wake, event_info->cb_fun, NULL); in register_event()
295 /* Check PM API version number */ in zynqmp_pm_probe()
297 return -ENODEV; in zynqmp_pm_probe()
302 * If xlnx_register_event() returns -EACCES (Xilinx Event Manager in zynqmp_pm_probe()
303 * is not available to use) or -ENODEV(Xilinx Event Manager not compiled), in zynqmp_pm_probe()
304 * then use ipi-mailbox or interrupt method. in zynqmp_pm_probe()
306 ret = register_event(&pdev->dev, PM_INIT_SUSPEND_CB, 0, 0, false, in zynqmp_pm_probe()
309 zynqmp_pm_init_suspend_work = devm_kzalloc(&pdev->dev, in zynqmp_pm_probe()
313 return -ENOMEM; in zynqmp_pm_probe()
315 INIT_WORK(&zynqmp_pm_init_suspend_work->callback_work, in zynqmp_pm_probe()
327 ret = register_event(&pdev->dev, PM_NOTIFY_CB, node_id, EVENT_SUBSYSTEM_RESTART, in zynqmp_pm_probe()
330 dev_err(&pdev->dev, "Failed to Register with Xilinx Event manager %d\n", in zynqmp_pm_probe()
335 zynqmp_pm_init_restart_work = devm_kzalloc(&pdev->dev, in zynqmp_pm_probe()
339 return -ENOMEM; in zynqmp_pm_probe()
341 INIT_WORK(&zynqmp_pm_init_restart_work->callback_work, in zynqmp_pm_probe()
343 } else if (ret != -EACCES && ret != -ENODEV) { in zynqmp_pm_probe()
344 dev_err(&pdev->dev, "Failed to Register with Xilinx Event manager %d\n", ret); in zynqmp_pm_probe()
346 } else if (of_property_present(pdev->dev.of_node, "mboxes")) { in zynqmp_pm_probe()
348 devm_kzalloc(&pdev->dev, in zynqmp_pm_probe()
352 return -ENOMEM; in zynqmp_pm_probe()
354 INIT_WORK(&zynqmp_pm_init_suspend_work->callback_work, in zynqmp_pm_probe()
356 client = devm_kzalloc(&pdev->dev, sizeof(*client), GFP_KERNEL); in zynqmp_pm_probe()
358 return -ENOMEM; in zynqmp_pm_probe()
360 client->dev = &pdev->dev; in zynqmp_pm_probe()
361 client->rx_callback = ipi_receive_callback; in zynqmp_pm_probe()
365 dev_err(&pdev->dev, "Failed to request rx channel\n"); in zynqmp_pm_probe()
368 } else if (of_property_present(pdev->dev.of_node, "interrupts")) { in zynqmp_pm_probe()
373 ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, in zynqmp_pm_probe()
376 dev_name(&pdev->dev), in zynqmp_pm_probe()
377 &pdev->dev); in zynqmp_pm_probe()
379 dev_err(&pdev->dev, "devm_request_threaded_irq '%d' failed with %d\n", in zynqmp_pm_probe()
384 dev_err(&pdev->dev, "Required property not found in DT node\n"); in zynqmp_pm_probe()
385 return -ENOENT; in zynqmp_pm_probe()
388 ret = sysfs_create_file(&pdev->dev.kobj, &dev_attr_suspend_mode.attr); in zynqmp_pm_probe()
397 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_suspend_mode.attr); in zynqmp_pm_remove()
404 { .compatible = "xlnx,zynqmp-power", },