diff options
Diffstat (limited to 'drivers/firmware/ti_sci.c')
-rw-r--r-- | drivers/firmware/ti_sci.c | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c index 7741fed416..1a78b7d0dc 100644 --- a/drivers/firmware/ti_sci.c +++ b/drivers/firmware/ti_sci.c @@ -1397,6 +1397,50 @@ static int ti_sci_cmd_clk_get_freq(const struct ti_sci_handle *handle, return ret; } +/** + * ti_sci_cmd_core_reboot() - Command to request system reset + * @handle: pointer to TI SCI handle + * + * Return: 0 if all went well, else returns appropriate error value. + */ +static int ti_sci_cmd_core_reboot(const struct ti_sci_handle *handle) +{ + struct ti_sci_msg_req_reboot req; + struct ti_sci_msg_hdr *resp; + struct ti_sci_info *info; + struct ti_sci_xfer *xfer; + int ret = 0; + + if (IS_ERR(handle)) + return PTR_ERR(handle); + if (!handle) + return -EINVAL; + + info = handle_to_ti_sci_info(handle); + + xfer = ti_sci_setup_one_xfer(info, TI_SCI_MSG_SYS_RESET, + TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, + (u32 *)&req, sizeof(req), sizeof(*resp)); + if (IS_ERR(xfer)) { + ret = PTR_ERR(xfer); + dev_err(info->dev, "Message alloc failed(%d)\n", ret); + return ret; + } + + ret = ti_sci_do_xfer(info, xfer); + if (ret) { + dev_err(dev, "Mbox send fail %d\n", ret); + return ret; + } + + resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; + + if (!ti_sci_is_response_ack(resp)) + return -ENODEV; + + return ret; +} + /* * ti_sci_setup_ops() - Setup the operations structures * @info: pointer to TISCI pointer @@ -1407,6 +1451,7 @@ static void ti_sci_setup_ops(struct ti_sci_info *info) struct ti_sci_board_ops *bops = &ops->board_ops; struct ti_sci_dev_ops *dops = &ops->dev_ops; struct ti_sci_clk_ops *cops = &ops->clk_ops; + struct ti_sci_core_ops *core_ops = &ops->core_ops; bops->board_config = ti_sci_cmd_set_board_config; bops->board_config_rm = ti_sci_cmd_set_board_config_rm; @@ -1439,6 +1484,8 @@ static void ti_sci_setup_ops(struct ti_sci_info *info) cops->get_best_match_freq = ti_sci_cmd_clk_get_match_freq; cops->set_freq = ti_sci_cmd_clk_set_freq; cops->get_freq = ti_sci_cmd_clk_get_freq; + + core_ops->reboot_device = ti_sci_cmd_core_reboot; } /** |