From f369b0f26cf77921e2a3b8c5ad7dab7e82b246ee Mon Sep 17 00:00:00 2001 From: Andreas Dannenberg Date: Mon, 27 Aug 2018 15:57:36 +0530 Subject: firmware: ti_sci: Add support for reboot core service Since system controller now has control over SoC power management, it needs to be explicitly requested to reboot the SoC. Add support for it. Reviewed-by: Tom Rini Signed-off-by: Andreas Dannenberg Signed-off-by: Lokesh Vutla Signed-off-by: Nishanth Menon --- drivers/firmware/ti_sci.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) (limited to 'drivers/firmware/ti_sci.c') diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c index 7741fed..1a78b7d 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; } /** -- cgit v1.1