firmware: ti_sci: Add support for reboot core service
[oweals/u-boot.git] / drivers / firmware / ti_sci.c
index 7741fed4164c509d3651d6431948fbf4082bfeee..1a78b7d0dc4f83458f9e2c0b59ce781a384abcc4 100644 (file)
@@ -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;
 }
 
 /**