summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Dannenberg <dannenberg@ti.com>2018-08-27 13:27:36 +0300
committerTom Rini <trini@konsulko.com>2018-09-11 15:32:55 +0300
commitf369b0f26cf77921e2a3b8c5ad7dab7e82b246ee (patch)
tree6f34e2083ba4bca422b69d32751a2afb38d6f70d
parent9b87181fd297f38bd52b597a31dc64ba959afdfd (diff)
downloadu-boot-f369b0f26cf77921e2a3b8c5ad7dab7e82b246ee.tar.xz
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 <trini@konsulko.com> Signed-off-by: Andreas Dannenberg <dannenberg@ti.com> Signed-off-by: Lokesh Vutla <lokeshvutla@ti.com> Signed-off-by: Nishanth Menon <nm@ti.com>
-rw-r--r--drivers/firmware/ti_sci.c47
-rw-r--r--drivers/firmware/ti_sci.h11
-rw-r--r--include/linux/soc/ti/ti_sci_protocol.h12
3 files changed, 70 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;
}
/**
diff --git a/drivers/firmware/ti_sci.h b/drivers/firmware/ti_sci.h
index 83431a884d..2fc9063ff5 100644
--- a/drivers/firmware/ti_sci.h
+++ b/drivers/firmware/ti_sci.h
@@ -96,6 +96,17 @@ struct ti_sci_msg_resp_version {
} __packed;
/**
+ * struct ti_sci_msg_req_reboot - Reboot the SoC
+ * @hdr: Generic Header
+ *
+ * Request type is TI_SCI_MSG_SYS_RESET, responded with a generic
+ * ACK/NACK message.
+ */
+struct ti_sci_msg_req_reboot {
+ struct ti_sci_msg_hdr hdr;
+} __packed;
+
+/**
* struct ti_sci_msg_board_config - Board configuration message
* @hdr: Generic Header
* @boardcfgp_low: Lower 32 bit of the pointer pointing to the board
diff --git a/include/linux/soc/ti/ti_sci_protocol.h b/include/linux/soc/ti/ti_sci_protocol.h
index 30300bcef2..acc02d38e1 100644
--- a/include/linux/soc/ti/ti_sci_protocol.h
+++ b/include/linux/soc/ti/ti_sci_protocol.h
@@ -213,15 +213,27 @@ struct ti_sci_clk_ops {
};
/**
+ * struct ti_sci_core_ops - SoC Core Operations
+ * @reboot_device: Reboot the SoC
+ * Returns 0 for successful request(ideally should never return),
+ * else returns corresponding error value.
+ */
+struct ti_sci_core_ops {
+ int (*reboot_device)(const struct ti_sci_handle *handle);
+};
+
+/**
* struct ti_sci_ops - Function support for TI SCI
* @board_ops: Miscellaneous operations
* @dev_ops: Device specific operations
* @clk_ops: Clock specific operations
+ * @core_ops: Core specific operations
*/
struct ti_sci_ops {
struct ti_sci_board_ops board_ops;
struct ti_sci_dev_ops dev_ops;
struct ti_sci_clk_ops clk_ops;
+ struct ti_sci_core_ops core_ops;
};
/**