summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/firmware/ti_sci.c341
-rw-r--r--drivers/gpio/Kconfig10
-rw-r--r--drivers/gpio/Makefile2
-rw-r--r--drivers/gpio/msm_gpio.c10
-rw-r--r--drivers/gpio/pm8916_gpio.c303
-rw-r--r--drivers/gpio/qcom_pmic_gpio.c359
-rw-r--r--drivers/phy/Kconfig15
-rw-r--r--drivers/phy/Makefile3
-rw-r--r--drivers/phy/qcom/Kconfig29
-rw-r--r--drivers/phy/qcom/Makefile4
-rw-r--r--drivers/phy/qcom/msm8916-usbh-phy.c (renamed from drivers/phy/msm8916-usbh-phy.c)0
-rw-r--r--drivers/phy/qcom/phy-qcom-ipq4019-usb.c (renamed from drivers/phy/phy-qcom-ipq4019-usb.c)0
-rw-r--r--drivers/phy/qcom/phy-qcom-usb-hs-28nm.c250
-rw-r--r--drivers/phy/qcom/phy-qcom-usb-ss.c154
-rw-r--r--drivers/power/pmic/Kconfig8
-rw-r--r--drivers/power/pmic/Makefile2
-rw-r--r--drivers/power/pmic/pmic_qcom.c (renamed from drivers/power/pmic/pm8916.c)42
-rw-r--r--drivers/reset/Kconfig9
-rw-r--r--drivers/reset/Makefile2
-rw-r--r--drivers/reset/reset-qcom.c (renamed from drivers/reset/reset-ipq4019.c)76
20 files changed, 955 insertions, 664 deletions
diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c
index 0b6ba35b596..727e090e8ab 100644
--- a/drivers/firmware/ti_sci.c
+++ b/drivers/firmware/ti_sci.c
@@ -134,8 +134,11 @@ static struct ti_sci_xfer *ti_sci_setup_one_xfer(struct ti_sci_info *info,
if (rx_message_size > info->desc->max_msg_size ||
tx_message_size > info->desc->max_msg_size ||
(rx_message_size > 0 && rx_message_size < sizeof(*hdr)) ||
- tx_message_size < sizeof(*hdr))
+ tx_message_size < sizeof(*hdr)) {
+ dev_err(info->dev, "TI-SCI message transfer size not sane\n");
return ERR_PTR(-ERANGE);
+ }
+
info->seq = ~info->seq;
xfer->tx_message.buf = buf;
@@ -161,7 +164,7 @@ static struct ti_sci_xfer *ti_sci_setup_one_xfer(struct ti_sci_info *info,
* return corresponding error, else if all goes well,
* return 0.
*/
-static inline int ti_sci_get_response(struct ti_sci_info *info,
+static int ti_sci_get_response(struct ti_sci_info *info,
struct ti_sci_xfer *xfer,
struct mbox_chan *chan)
{
@@ -209,13 +212,26 @@ static inline int ti_sci_get_response(struct ti_sci_info *info,
}
/**
+ * ti_sci_is_response_ack() - Generic ACK/NACK message checkup
+ * @r: pointer to response buffer
+ *
+ * Return: true if the response was an ACK, else returns false.
+ */
+static bool ti_sci_is_response_ack(void *r)
+{
+ struct ti_sci_msg_hdr *hdr = r;
+
+ return hdr->flags & TI_SCI_FLAG_RESP_GENERIC_ACK ? true : false;
+}
+
+/**
* ti_sci_do_xfer() - Do one transfer
* @info: Pointer to SCI entity information
* @xfer: Transfer to initiate and wait for response
*
* Return: 0 if all went fine, else return appropriate error.
*/
-static inline int ti_sci_do_xfer(struct ti_sci_info *info,
+static int ti_sci_do_xfer(struct ti_sci_info *info,
struct ti_sci_xfer *xfer)
{
struct k3_sec_proxy_msg *msg = &xfer->tx_message;
@@ -246,8 +262,13 @@ static inline int ti_sci_do_xfer(struct ti_sci_info *info,
}
/* Get response if requested */
- if (xfer->rx_len)
+ if (xfer->rx_len) {
ret = ti_sci_get_response(info, xfer, &info->chan_rx);
+ if (!ti_sci_is_response_ack(xfer->tx_message.buf)) {
+ dev_err(info->dev, "Message not acknowledged");
+ ret = -ENODEV;
+ }
+ }
return ret;
}
@@ -282,15 +303,12 @@ static int ti_sci_cmd_get_revision(struct ti_sci_handle *handle)
sizeof(*rev_info));
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(info->dev, "Mbox communication fail %d\n", ret);
+ if (ret)
return ret;
- }
rev_info = (struct ti_sci_msg_resp_version *)xfer->tx_message.buf;
@@ -305,19 +323,6 @@ static int ti_sci_cmd_get_revision(struct ti_sci_handle *handle)
}
/**
- * ti_sci_is_response_ack() - Generic ACK/NACK message checkup
- * @r: pointer to response buffer
- *
- * Return: true if the response was an ACK, else returns false.
- */
-static inline bool ti_sci_is_response_ack(void *r)
-{
- struct ti_sci_msg_hdr *hdr = r;
-
- return hdr->flags & TI_SCI_FLAG_RESP_GENERIC_ACK ? true : false;
-}
-
-/**
* cmd_set_board_config_using_msg() - Common command to send board configuration
* message
* @handle: pointer to TI SCI handle
@@ -348,7 +353,6 @@ static int cmd_set_board_config_using_msg(const struct ti_sci_handle *handle,
(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;
}
req.boardcfgp_high = (addr >> 32) & 0xffffffff;
@@ -356,15 +360,8 @@ static int cmd_set_board_config_using_msg(const struct ti_sci_handle *handle,
req.boardcfg_size = size;
ret = ti_sci_do_xfer(info, xfer);
- if (ret) {
- dev_err(info->dev, "Mbox send fail %d\n", ret);
+ if (ret)
return ret;
- }
-
- resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
-
- if (!ti_sci_is_response_ack(resp))
- return -ENODEV;
return ret;
}
@@ -509,22 +506,14 @@ static int ti_sci_set_device_state(const struct ti_sci_handle *handle,
(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;
}
req.id = id;
req.state = state;
ret = ti_sci_do_xfer(info, xfer);
- if (ret) {
- dev_err(info->dev, "Mbox send fail %d\n", ret);
+ if (ret)
return ret;
- }
-
- resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
-
- if (!ti_sci_is_response_ack(resp))
- return -ENODEV;
if (state == MSG_DEVICE_SW_STATE_AUTO_OFF)
ti_sci_delete_exclusive_dev(info, id);
@@ -564,7 +553,6 @@ static int ti_sci_set_device_state_no_wait(const struct ti_sci_handle *handle,
(u32 *)&req, sizeof(req), 0);
if (IS_ERR(xfer)) {
ret = PTR_ERR(xfer);
- dev_err(info->dev, "Message alloc failed(%d)\n", ret);
return ret;
}
req.id = id;
@@ -572,7 +560,7 @@ static int ti_sci_set_device_state_no_wait(const struct ti_sci_handle *handle,
ret = ti_sci_do_xfer(info, xfer);
if (ret)
- dev_err(info->dev, "Mbox send fail %d\n", ret);
+ return ret;
return ret;
}
@@ -613,20 +601,15 @@ static int ti_sci_get_device_state(const struct ti_sci_handle *handle,
(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;
}
req.id = id;
ret = ti_sci_do_xfer(info, xfer);
- if (ret) {
- dev_err(info->dev, "Mbox send fail %d\n", ret);
+ if (ret)
return ret;
- }
resp = (struct ti_sci_msg_resp_get_device_state *)xfer->tx_message.buf;
- if (!ti_sci_is_response_ack(resp))
- return -ENODEV;
if (clcnt)
*clcnt = resp->context_loss_count;
@@ -901,22 +884,14 @@ static int ti_sci_cmd_set_device_resets(const struct ti_sci_handle *handle,
(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;
}
req.id = id;
req.resets = reset_state;
ret = ti_sci_do_xfer(info, xfer);
- if (ret) {
- dev_err(info->dev, "Mbox send fail %d\n", ret);
+ if (ret)
return ret;
- }
-
- resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
-
- if (!ti_sci_is_response_ack(resp))
- return -ENODEV;
return ret;
}
@@ -971,7 +946,6 @@ static int ti_sci_set_clock_state(const struct ti_sci_handle *handle,
(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;
}
req.dev_id = dev_id;
@@ -979,15 +953,8 @@ static int ti_sci_set_clock_state(const struct ti_sci_handle *handle,
req.request_state = state;
ret = ti_sci_do_xfer(info, xfer);
- if (ret) {
- dev_err(info->dev, "Mbox send fail %d\n", ret);
+ if (ret)
return ret;
- }
-
- resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
-
- if (!ti_sci_is_response_ack(resp))
- return -ENODEV;
return ret;
}
@@ -1029,23 +996,17 @@ static int ti_sci_cmd_get_clock_state(const struct ti_sci_handle *handle,
(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;
}
req.dev_id = dev_id;
req.clk_id = clk_id;
ret = ti_sci_do_xfer(info, xfer);
- if (ret) {
- dev_err(info->dev, "Mbox send fail %d\n", ret);
+ if (ret)
return ret;
- }
resp = (struct ti_sci_msg_resp_get_clock_state *)xfer->tx_message.buf;
- if (!ti_sci_is_response_ack(resp))
- return -ENODEV;
-
if (programmed_state)
*programmed_state = resp->programmed_state;
if (current_state)
@@ -1245,7 +1206,6 @@ static int ti_sci_cmd_clk_set_parent(const struct ti_sci_handle *handle,
(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;
}
req.dev_id = dev_id;
@@ -1253,15 +1213,8 @@ static int ti_sci_cmd_clk_set_parent(const struct ti_sci_handle *handle,
req.parent_id = parent_id;
ret = ti_sci_do_xfer(info, xfer);
- if (ret) {
- dev_err(info->dev, "Mbox send fail %d\n", ret);
+ if (ret)
return ret;
- }
-
- resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
-
- if (!ti_sci_is_response_ack(resp))
- return -ENODEV;
return ret;
}
@@ -1298,24 +1251,16 @@ static int ti_sci_cmd_clk_get_parent(const struct ti_sci_handle *handle,
(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;
}
req.dev_id = dev_id;
req.clk_id = clk_id;
ret = ti_sci_do_xfer(info, xfer);
- if (ret) {
- dev_err(info->dev, "Mbox send fail %d\n", ret);
+ if (ret)
return ret;
- }
-
- resp = (struct ti_sci_msg_resp_get_clock_parent *)xfer->tx_message.buf;
- if (!ti_sci_is_response_ack(resp))
- ret = -ENODEV;
- else
- *parent_id = resp->parent_id;
+ *parent_id = resp->parent_id;
return ret;
}
@@ -1353,25 +1298,19 @@ static int ti_sci_cmd_clk_get_num_parents(const struct ti_sci_handle *handle,
(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;
}
req.dev_id = dev_id;
req.clk_id = clk_id;
ret = ti_sci_do_xfer(info, xfer);
- if (ret) {
- dev_err(info->dev, "Mbox send fail %d\n", ret);
+ if (ret)
return ret;
- }
resp = (struct ti_sci_msg_resp_get_clock_num_parents *)
xfer->tx_message.buf;
- if (!ti_sci_is_response_ack(resp))
- ret = -ENODEV;
- else
- *num_parents = resp->num_parents;
+ *num_parents = resp->num_parents;
return ret;
}
@@ -1418,7 +1357,6 @@ static int ti_sci_cmd_clk_get_match_freq(const struct ti_sci_handle *handle,
(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;
}
req.dev_id = dev_id;
@@ -1428,17 +1366,12 @@ static int ti_sci_cmd_clk_get_match_freq(const struct ti_sci_handle *handle,
req.max_freq_hz = max_freq;
ret = ti_sci_do_xfer(info, xfer);
- if (ret) {
- dev_err(info->dev, "Mbox send fail %d\n", ret);
+ if (ret)
return ret;
- }
resp = (struct ti_sci_msg_resp_query_clock_freq *)xfer->tx_message.buf;
- if (!ti_sci_is_response_ack(resp))
- ret = -ENODEV;
- else
- *match_freq = resp->freq_hz;
+ *match_freq = resp->freq_hz;
return ret;
}
@@ -1483,7 +1416,6 @@ static int ti_sci_cmd_clk_set_freq(const struct ti_sci_handle *handle,
(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;
}
req.dev_id = dev_id;
@@ -1493,15 +1425,8 @@ static int ti_sci_cmd_clk_set_freq(const struct ti_sci_handle *handle,
req.max_freq_hz = max_freq;
ret = ti_sci_do_xfer(info, xfer);
- if (ret) {
- dev_err(info->dev, "Mbox send fail %d\n", ret);
+ if (ret)
return ret;
- }
-
- resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
-
- if (!ti_sci_is_response_ack(resp))
- return -ENODEV;
return ret;
}
@@ -1538,24 +1463,18 @@ static int ti_sci_cmd_clk_get_freq(const struct ti_sci_handle *handle,
(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;
}
req.dev_id = dev_id;
req.clk_id = clk_id;
ret = ti_sci_do_xfer(info, xfer);
- if (ret) {
- dev_err(info->dev, "Mbox send fail %d\n", ret);
+ if (ret)
return ret;
- }
resp = (struct ti_sci_msg_resp_get_clock_freq *)xfer->tx_message.buf;
- if (!ti_sci_is_response_ack(resp))
- ret = -ENODEV;
- else
- *freq = resp->freq_hz;
+ *freq = resp->freq_hz;
return ret;
}
@@ -1586,21 +1505,13 @@ static int ti_sci_cmd_core_reboot(const struct ti_sci_handle *handle)
(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;
}
req.domain = 0;
ret = ti_sci_do_xfer(info, xfer);
- if (ret) {
- dev_err(info->dev, "Mbox send fail %d\n", ret);
+ if (ret)
return ret;
- }
-
- resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
-
- if (!ti_sci_is_response_ack(resp))
- return -ENODEV;
return ret;
}
@@ -1641,7 +1552,6 @@ static int ti_sci_get_resource_range(const struct ti_sci_handle *handle,
(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;
}
@@ -1650,15 +1560,11 @@ static int ti_sci_get_resource_range(const struct ti_sci_handle *handle,
req.subtype = subtype & MSG_RM_RESOURCE_SUBTYPE_MASK;
ret = ti_sci_do_xfer(info, xfer);
- if (ret) {
- dev_err(info->dev, "Mbox send fail %d\n", ret);
+ if (ret)
goto fail;
- }
resp = (struct ti_sci_msg_resp_get_resource_range *)xfer->tx_message.buf;
- if (!ti_sci_is_response_ack(resp)) {
- ret = -ENODEV;
- } else if (!resp->range_start && !resp->range_num) {
+ if (!resp->range_start && !resp->range_num) {
ret = -ENODEV;
} else {
*range_start = resp->range_start;
@@ -1769,21 +1675,15 @@ static int ti_sci_cmd_query_msmc(const struct ti_sci_handle *handle,
(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(info->dev, "Mbox send fail %d\n", ret);
+ if (ret)
return ret;
- }
resp = (struct ti_sci_msg_resp_query_msmc *)xfer->tx_message.buf;
- if (!ti_sci_is_response_ack(resp))
- return -ENODEV;
-
*msmc_start = ((u64)resp->msmc_start_high << TISCI_ADDR_HIGH_SHIFT) |
resp->msmc_start_low;
*msmc_end = ((u64)resp->msmc_end_high << TISCI_ADDR_HIGH_SHIFT) |
@@ -1820,21 +1720,13 @@ static int ti_sci_cmd_proc_request(const struct ti_sci_handle *handle,
(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;
}
req.processor_id = proc_id;
ret = ti_sci_do_xfer(info, xfer);
- if (ret) {
- dev_err(info->dev, "Mbox send fail %d\n", ret);
+ if (ret)
return ret;
- }
-
- resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
-
- if (!ti_sci_is_response_ack(resp))
- ret = -ENODEV;
return ret;
}
@@ -1867,21 +1759,13 @@ static int ti_sci_cmd_proc_release(const struct ti_sci_handle *handle,
(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;
}
req.processor_id = proc_id;
ret = ti_sci_do_xfer(info, xfer);
- if (ret) {
- dev_err(info->dev, "Mbox send fail %d\n", ret);
+ if (ret)
return ret;
- }
-
- resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
-
- if (!ti_sci_is_response_ack(resp))
- ret = -ENODEV;
return ret;
}
@@ -1917,22 +1801,14 @@ static int ti_sci_cmd_proc_handover(const struct ti_sci_handle *handle,
(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;
}
req.processor_id = proc_id;
req.host_id = host_id;
ret = ti_sci_do_xfer(info, xfer);
- if (ret) {
- dev_err(info->dev, "Mbox send fail %d\n", ret);
+ if (ret)
return ret;
- }
-
- resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
-
- if (!ti_sci_is_response_ack(resp))
- ret = -ENODEV;
return ret;
}
@@ -1970,7 +1846,6 @@ static int ti_sci_cmd_set_proc_boot_cfg(const struct ti_sci_handle *handle,
(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;
}
req.processor_id = proc_id;
@@ -1981,15 +1856,8 @@ static int ti_sci_cmd_set_proc_boot_cfg(const struct ti_sci_handle *handle,
req.config_flags_clear = config_flags_clear;
ret = ti_sci_do_xfer(info, xfer);
- if (ret) {
- dev_err(info->dev, "Mbox send fail %d\n", ret);
+ if (ret)
return ret;
- }
-
- resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
-
- if (!ti_sci_is_response_ack(resp))
- ret = -ENODEV;
return ret;
}
@@ -2026,7 +1894,6 @@ static int ti_sci_cmd_set_proc_boot_ctrl(const struct ti_sci_handle *handle,
(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;
}
req.processor_id = proc_id;
@@ -2034,15 +1901,8 @@ static int ti_sci_cmd_set_proc_boot_ctrl(const struct ti_sci_handle *handle,
req.control_flags_clear = control_flags_clear;
ret = ti_sci_do_xfer(info, xfer);
- if (ret) {
- dev_err(info->dev, "Mbox send fail %d\n", ret);
+ if (ret)
return ret;
- }
-
- resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
-
- if (!ti_sci_is_response_ack(resp))
- ret = -ENODEV;
return ret;
}
@@ -2080,7 +1940,6 @@ static int ti_sci_cmd_proc_auth_boot_image(const struct ti_sci_handle *handle,
(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;
}
req.cert_addr_low = *image_addr & TISCI_ADDR_LOW_MASK;
@@ -2088,16 +1947,11 @@ static int ti_sci_cmd_proc_auth_boot_image(const struct ti_sci_handle *handle,
TISCI_ADDR_HIGH_SHIFT;
ret = ti_sci_do_xfer(info, xfer);
- if (ret) {
- dev_err(info->dev, "Mbox send fail %d\n", ret);
+ if (ret)
return ret;
- }
resp = (struct ti_sci_msg_resp_proc_auth_boot_image *)xfer->tx_message.buf;
- if (!ti_sci_is_response_ack(resp))
- return -ENODEV;
-
*image_addr = (resp->image_addr_low & TISCI_ADDR_LOW_MASK) |
(((u64)resp->image_addr_high <<
TISCI_ADDR_HIGH_SHIFT) & TISCI_ADDR_HIGH_MASK);
@@ -2135,22 +1989,17 @@ static int ti_sci_cmd_get_proc_boot_status(const struct ti_sci_handle *handle,
(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;
}
req.processor_id = proc_id;
ret = ti_sci_do_xfer(info, xfer);
- if (ret) {
- dev_err(info->dev, "Mbox send fail %d\n", ret);
+ if (ret)
return ret;
- }
resp = (struct ti_sci_msg_resp_get_proc_boot_status *)
xfer->tx_message.buf;
- if (!ti_sci_is_response_ack(resp))
- return -ENODEV;
*bv = (resp->bootvector_low & TISCI_ADDR_LOW_MASK) |
(((u64)resp->bootvector_high <<
TISCI_ADDR_HIGH_SHIFT) & TISCI_ADDR_HIGH_MASK);
@@ -2225,7 +2074,6 @@ ti_sci_proc_wait_boot_status_no_wait(const struct ti_sci_handle *handle,
(u32 *)&req, sizeof(req), 0);
if (IS_ERR(xfer)) {
ret = PTR_ERR(xfer);
- dev_err(info->dev, "Message alloc failed(%d)\n", ret);
return ret;
}
req.processor_id = proc_id;
@@ -2240,7 +2088,7 @@ ti_sci_proc_wait_boot_status_no_wait(const struct ti_sci_handle *handle,
ret = ti_sci_do_xfer(info, xfer);
if (ret)
- dev_err(info->dev, "Mbox send fail %d\n", ret);
+ return ret;
return ret;
}
@@ -2340,7 +2188,6 @@ static int ti_sci_cmd_ring_config(const struct ti_sci_handle *handle,
(u32 *)&req, sizeof(req), sizeof(*resp));
if (IS_ERR(xfer)) {
ret = PTR_ERR(xfer);
- dev_err(info->dev, "RM_RA:Message config failed(%d)\n", ret);
return ret;
}
req.valid_params = valid_params;
@@ -2354,14 +2201,8 @@ static int ti_sci_cmd_ring_config(const struct ti_sci_handle *handle,
req.order_id = order_id;
ret = ti_sci_do_xfer(info, xfer);
- if (ret) {
- dev_err(info->dev, "RM_RA:Mbox config send fail %d\n", ret);
+ if (ret)
goto fail;
- }
-
- resp = (struct ti_sci_msg_rm_ring_cfg_resp *)xfer->tx_message.buf;
-
- ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV;
fail:
dev_dbg(info->dev, "RM_RA:config ring %u ret:%d\n", index, ret);
@@ -2389,7 +2230,6 @@ static int ti_sci_cmd_rm_psil_pair(const struct ti_sci_handle *handle,
(u32 *)&req, sizeof(req), sizeof(*resp));
if (IS_ERR(xfer)) {
ret = PTR_ERR(xfer);
- dev_err(info->dev, "RM_PSIL:Message alloc failed(%d)\n", ret);
return ret;
}
req.nav_id = nav_id;
@@ -2397,13 +2237,8 @@ static int ti_sci_cmd_rm_psil_pair(const struct ti_sci_handle *handle,
req.dst_thread = dst_thread;
ret = ti_sci_do_xfer(info, xfer);
- if (ret) {
- dev_err(info->dev, "RM_PSIL:Mbox send fail %d\n", ret);
+ if (ret)
goto fail;
- }
-
- resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
- ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV;
fail:
dev_dbg(info->dev, "RM_PSIL: nav: %u link pair %u->%u ret:%u\n",
@@ -2432,7 +2267,6 @@ static int ti_sci_cmd_rm_psil_unpair(const struct ti_sci_handle *handle,
(u32 *)&req, sizeof(req), sizeof(*resp));
if (IS_ERR(xfer)) {
ret = PTR_ERR(xfer);
- dev_err(info->dev, "RM_PSIL:Message alloc failed(%d)\n", ret);
return ret;
}
req.nav_id = nav_id;
@@ -2440,13 +2274,8 @@ static int ti_sci_cmd_rm_psil_unpair(const struct ti_sci_handle *handle,
req.dst_thread = dst_thread;
ret = ti_sci_do_xfer(info, xfer);
- if (ret) {
- dev_err(info->dev, "RM_PSIL:Mbox send fail %d\n", ret);
+ if (ret)
goto fail;
- }
-
- resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
- ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV;
fail:
dev_dbg(info->dev, "RM_PSIL: link unpair %u->%u ret:%u\n",
@@ -2476,7 +2305,6 @@ static int ti_sci_cmd_rm_udmap_tx_ch_cfg(
(u32 *)&req, sizeof(req), sizeof(*resp));
if (IS_ERR(xfer)) {
ret = PTR_ERR(xfer);
- dev_err(info->dev, "Message TX_CH_CFG alloc failed(%d)\n", ret);
return ret;
}
req.valid_params = params->valid_params;
@@ -2501,14 +2329,8 @@ static int ti_sci_cmd_rm_udmap_tx_ch_cfg(
req.extended_ch_type = params->extended_ch_type;
ret = ti_sci_do_xfer(info, xfer);
- if (ret) {
- dev_err(info->dev, "Mbox send TX_CH_CFG fail %d\n", ret);
+ if (ret)
goto fail;
- }
-
- resp =
- (struct ti_sci_msg_rm_udmap_tx_ch_cfg_resp *)xfer->tx_message.buf;
- ret = ti_sci_is_response_ack(resp) ? 0 : -EINVAL;
fail:
dev_dbg(info->dev, "TX_CH_CFG: chn %u ret:%u\n", params->index, ret);
@@ -2537,7 +2359,6 @@ static int ti_sci_cmd_rm_udmap_rx_ch_cfg(
(u32 *)&req, sizeof(req), sizeof(*resp));
if (IS_ERR(xfer)) {
ret = PTR_ERR(xfer);
- dev_err(info->dev, "Message RX_CH_CFG alloc failed(%d)\n", ret);
return ret;
}
@@ -2559,14 +2380,8 @@ static int ti_sci_cmd_rm_udmap_rx_ch_cfg(
req.rx_ignore_long = params->rx_ignore_long;
ret = ti_sci_do_xfer(info, xfer);
- if (ret) {
- dev_err(info->dev, "Mbox send RX_CH_CFG fail %d\n", ret);
+ if (ret)
goto fail;
- }
-
- resp =
- (struct ti_sci_msg_rm_udmap_rx_ch_cfg_resp *)xfer->tx_message.buf;
- ret = ti_sci_is_response_ack(resp) ? 0 : -EINVAL;
fail:
dev_dbg(info->dev, "RX_CH_CFG: chn %u ret:%d\n", params->index, ret);
@@ -2595,8 +2410,6 @@ static int ti_sci_cmd_rm_udmap_rx_flow_cfg(
(u32 *)&req, sizeof(req), sizeof(*resp));
if (IS_ERR(xfer)) {
ret = PTR_ERR(xfer);
- dev_err(info->dev, "RX_FL_CFG: Message alloc failed(%d)\n",
- ret);
return ret;
}
@@ -2624,14 +2437,8 @@ static int ti_sci_cmd_rm_udmap_rx_flow_cfg(
req.rx_ps_location = params->rx_ps_location;
ret = ti_sci_do_xfer(info, xfer);
- if (ret) {
- dev_err(info->dev, "RX_FL_CFG: Mbox send fail %d\n", ret);
+ if (ret)
goto fail;
- }
-
- resp =
- (struct ti_sci_msg_rm_udmap_flow_cfg_resp *)xfer->tx_message.buf;
- ret = ti_sci_is_response_ack(resp) ? 0 : -EINVAL;
fail:
dev_dbg(info->dev, "RX_FL_CFG: %u ret:%d\n", params->flow_index, ret);
@@ -2666,7 +2473,6 @@ static int ti_sci_cmd_set_fwl_region(const struct ti_sci_handle *handle,
(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;
}
@@ -2681,15 +2487,8 @@ static int ti_sci_cmd_set_fwl_region(const struct ti_sci_handle *handle,
req.end_address = region->end_address;
ret = ti_sci_do_xfer(info, xfer);
- if (ret) {
- dev_err(info->dev, "Mbox send fail %d\n", ret);
+ if (ret)
return ret;
- }
-
- resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
-
- if (!ti_sci_is_response_ack(resp))
- return -ENODEV;
return 0;
}
@@ -2722,7 +2521,6 @@ static int ti_sci_cmd_get_fwl_region(const struct ti_sci_handle *handle,
(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;
}
@@ -2731,16 +2529,11 @@ static int ti_sci_cmd_get_fwl_region(const struct ti_sci_handle *handle,
req.n_permission_regs = region->n_permission_regs;
ret = ti_sci_do_xfer(info, xfer);
- if (ret) {
- dev_err(info->dev, "Mbox send fail %d\n", ret);
+ if (ret)
return ret;
- }
resp = (struct ti_sci_msg_fwl_get_firewall_region_resp *)xfer->tx_message.buf;
- if (!ti_sci_is_response_ack(resp))
- return -ENODEV;
-
region->fwl_id = resp->fwl_id;
region->region = resp->region;
region->n_permission_regs = resp->n_permission_regs;
@@ -2782,7 +2575,6 @@ static int ti_sci_cmd_change_fwl_owner(const struct ti_sci_handle *handle,
(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;
}
@@ -2791,16 +2583,11 @@ static int ti_sci_cmd_change_fwl_owner(const struct ti_sci_handle *handle,
req.owner_index = owner->owner_index;
ret = ti_sci_do_xfer(info, xfer);
- if (ret) {
- dev_err(info->dev, "Mbox send fail %d\n", ret);
+ if (ret)
return ret;
- }
resp = (struct ti_sci_msg_fwl_change_owner_info_resp *)xfer->tx_message.buf;
- if (!ti_sci_is_response_ack(resp))
- return -ENODEV;
-
owner->fwl_id = resp->fwl_id;
owner->region = resp->region;
owner->owner_index = resp->owner_index;
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 7e4c3577b36..c949f9d2f7c 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -303,14 +303,14 @@ config CMD_PCA953X
legacy GPIO interface. Several subcommands are provided which mirror
the standard 'gpio' command. It should use that instead.
-config PM8916_GPIO
- bool "Qualcomm PM8916 PMIC GPIO/keypad driver"
- depends on DM_GPIO && PMIC_PM8916
+config QCOM_PMIC_GPIO
+ bool "Qualcomm generic PMIC GPIO/keypad driver"
+ depends on DM_GPIO && PMIC_QCOM
help
Support for GPIO pins and power/reset buttons found on
- Qualcomm PM8916 PMIC.
+ Qualcomm SoCs PMIC.
Default name for GPIO bank is "pm8916".
- Power and reset buttons are placed in "pm8916_key" bank and
+ Power and reset buttons are placed in "pwkey_qcom" bank and
have gpio numbers 0 and 1 respectively.
config PCF8575_GPIO
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 39762fa06ce..9d718a554e5 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -63,7 +63,7 @@ obj-$(CONFIG_OCTEON_GPIO) += octeon_gpio.o
obj-$(CONFIG_MVEBU_GPIO) += mvebu_gpio.o
obj-$(CONFIG_MSM_GPIO) += msm_gpio.o
obj-$(CONFIG_$(SPL_)PCF8575_GPIO) += pcf8575_gpio.o
-obj-$(CONFIG_$(SPL_TPL_)PM8916_GPIO) += pm8916_gpio.o
+obj-$(CONFIG_$(SPL_TPL_)QCOM_PMIC_GPIO) += qcom_pmic_gpio.o
obj-$(CONFIG_MT7620_GPIO) += mt7620_gpio.o
obj-$(CONFIG_MT7621_GPIO) += mt7621_gpio.o
obj-$(CONFIG_MSCC_SGPIO) += mscc_sgpio.o
diff --git a/drivers/gpio/msm_gpio.c b/drivers/gpio/msm_gpio.c
index a3c3cd7824c..51670f26371 100644
--- a/drivers/gpio/msm_gpio.c
+++ b/drivers/gpio/msm_gpio.c
@@ -116,20 +116,12 @@ static int msm_gpio_of_to_plat(struct udevice *dev)
return 0;
}
-static const struct udevice_id msm_gpio_ids[] = {
- { .compatible = "qcom,msm8916-pinctrl" },
- { .compatible = "qcom,apq8016-pinctrl" },
- { .compatible = "qcom,ipq4019-pinctrl" },
- { .compatible = "qcom,sdm845-pinctrl" },
- { }
-};
-
U_BOOT_DRIVER(gpio_msm) = {
.name = "gpio_msm",
.id = UCLASS_GPIO,
- .of_match = msm_gpio_ids,
.of_to_plat = msm_gpio_of_to_plat,
.probe = msm_gpio_probe,
.ops = &gpio_msm_ops,
+ .flags = DM_UC_FLAG_SEQ_ALIAS,
.priv_auto = sizeof(struct msm_gpio_bank),
};
diff --git a/drivers/gpio/pm8916_gpio.c b/drivers/gpio/pm8916_gpio.c
deleted file mode 100644
index 7ad95784a89..00000000000
--- a/drivers/gpio/pm8916_gpio.c
+++ /dev/null
@@ -1,303 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Qualcomm pm8916 pmic gpio driver - part of Qualcomm PM8916 PMIC
- *
- * (C) Copyright 2015 Mateusz Kulikowski <mateusz.kulikowski@gmail.com>
- */
-
-#include <common.h>
-#include <dm.h>
-#include <log.h>
-#include <power/pmic.h>
-#include <spmi/spmi.h>
-#include <asm/io.h>
-#include <asm/gpio.h>
-#include <linux/bitops.h>
-
-/* Register offset for each gpio */
-#define REG_OFFSET(x) ((x) * 0x100)
-
-/* Register maps */
-
-/* Type and subtype are shared for all pm8916 peripherals */
-#define REG_TYPE 0x4
-#define REG_SUBTYPE 0x5
-
-#define REG_STATUS 0x08
-#define REG_STATUS_VAL_MASK 0x1
-
-/* MODE_CTL */
-#define REG_CTL 0x40
-#define REG_CTL_MODE_MASK 0x70
-#define REG_CTL_MODE_INPUT 0x00
-#define REG_CTL_MODE_INOUT 0x20
-#define REG_CTL_MODE_OUTPUT 0x10
-#define REG_CTL_OUTPUT_MASK 0x0F
-
-#define REG_DIG_VIN_CTL 0x41
-#define REG_DIG_VIN_VIN0 0
-
-#define REG_DIG_PULL_CTL 0x42
-#define REG_DIG_PULL_NO_PU 0x5
-
-#define REG_DIG_OUT_CTL 0x45
-#define REG_DIG_OUT_CTL_CMOS (0x0 << 4)
-#define REG_DIG_OUT_CTL_DRIVE_L 0x1
-
-#define REG_EN_CTL 0x46
-#define REG_EN_CTL_ENABLE (1 << 7)
-
-struct pm8916_gpio_bank {
- uint32_t pid; /* Peripheral ID on SPMI bus */
-};
-
-static int pm8916_gpio_set_direction(struct udevice *dev, unsigned offset,
- bool input, int value)
-{
- struct pm8916_gpio_bank *priv = dev_get_priv(dev);
- uint32_t gpio_base = priv->pid + REG_OFFSET(offset);
- int ret;
-
- /* Disable the GPIO */
- ret = pmic_clrsetbits(dev->parent, gpio_base + REG_EN_CTL,
- REG_EN_CTL_ENABLE, 0);
- if (ret < 0)
- return ret;
-
- /* Select the mode */
- if (input)
- ret = pmic_reg_write(dev->parent, gpio_base + REG_CTL,
- REG_CTL_MODE_INPUT);
- else
- ret = pmic_reg_write(dev->parent, gpio_base + REG_CTL,
- REG_CTL_MODE_INOUT | (value ? 1 : 0));
- if (ret < 0)
- return ret;
-
- /* Set the right pull (no pull) */
- ret = pmic_reg_write(dev->parent, gpio_base + REG_DIG_PULL_CTL,
- REG_DIG_PULL_NO_PU);
- if (ret < 0)
- return ret;
-
- /* Configure output pin drivers if needed */
- if (!input) {
- /* Select the VIN - VIN0, pin is input so it doesn't matter */
- ret = pmic_reg_write(dev->parent, gpio_base + REG_DIG_VIN_CTL,
- REG_DIG_VIN_VIN0);
- if (ret < 0)
- return ret;
-
- /* Set the right dig out control */
- ret = pmic_reg_write(dev->parent, gpio_base + REG_DIG_OUT_CTL,
- REG_DIG_OUT_CTL_CMOS |
- REG_DIG_OUT_CTL_DRIVE_L);
- if (ret < 0)
- return ret;
- }
-
- /* Enable the GPIO */
- return pmic_clrsetbits(dev->parent, gpio_base + REG_EN_CTL, 0,
- REG_EN_CTL_ENABLE);
-}
-
-static int pm8916_gpio_direction_input(struct udevice *dev, unsigned offset)
-{
- return pm8916_gpio_set_direction(dev, offset, true, 0);
-}
-
-static int pm8916_gpio_direction_output(struct udevice *dev, unsigned offset,
- int value)
-{
- return pm8916_gpio_set_direction(dev, offset, false, value);
-}
-
-static int pm8916_gpio_get_function(struct udevice *dev, unsigned offset)
-{
- struct pm8916_gpio_bank *priv = dev_get_priv(dev);
- uint32_t gpio_base = priv->pid + REG_OFFSET(offset);
- int reg;
-
- /* Set the output value of the gpio */
- reg = pmic_reg_read(dev->parent, gpio_base + REG_CTL);
- if (reg < 0)
- return reg;
-
- switch (reg & REG_CTL_MODE_MASK) {
- case REG_CTL_MODE_INPUT:
- return GPIOF_INPUT;
- case REG_CTL_MODE_INOUT: /* Fallthrough */
- case REG_CTL_MODE_OUTPUT:
- return GPIOF_OUTPUT;
- default:
- return GPIOF_UNKNOWN;
- }
-}
-
-static int pm8916_gpio_get_value(struct udevice *dev, unsigned offset)
-{
- struct pm8916_gpio_bank *priv = dev_get_priv(dev);
- uint32_t gpio_base = priv->pid + REG_OFFSET(offset);
- int reg;
-
- reg = pmic_reg_read(dev->parent, gpio_base + REG_STATUS);
- if (reg < 0)
- return reg;
-
- return !!(reg & REG_STATUS_VAL_MASK);
-}
-
-static int pm8916_gpio_set_value(struct udevice *dev, unsigned offset,
- int value)
-{
- struct pm8916_gpio_bank *priv = dev_get_priv(dev);
- uint32_t gpio_base = priv->pid + REG_OFFSET(offset);
-
- /* Set the output value of the gpio */
- return pmic_clrsetbits(dev->parent, gpio_base + REG_CTL,
- REG_CTL_OUTPUT_MASK, !!value);
-}
-
-static const struct dm_gpio_ops pm8916_gpio_ops = {
- .direction_input = pm8916_gpio_direction_input,
- .direction_output = pm8916_gpio_direction_output,
- .get_value = pm8916_gpio_get_value,
- .set_value = pm8916_gpio_set_value,
- .get_function = pm8916_gpio_get_function,
-};
-
-static int pm8916_gpio_probe(struct udevice *dev)
-{
- struct pm8916_gpio_bank *priv = dev_get_priv(dev);
- int reg;
-
- priv->pid = dev_read_addr(dev);
- if (priv->pid == FDT_ADDR_T_NONE)
- return log_msg_ret("bad address", -EINVAL);
-
- /* Do a sanity check */
- reg = pmic_reg_read(dev->parent, priv->pid + REG_TYPE);
- if (reg != 0x10)
- return log_msg_ret("bad type", -ENXIO);
-
- reg = pmic_reg_read(dev->parent, priv->pid + REG_SUBTYPE);
- if (reg != 0x5 && reg != 0x1)
- return log_msg_ret("bad subtype", -ENXIO);
-
- return 0;
-}
-
-static int pm8916_gpio_of_to_plat(struct udevice *dev)
-{
- struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
-
- uc_priv->gpio_count = dev_read_u32_default(dev, "gpio-count", 0);
- uc_priv->bank_name = dev_read_string(dev, "gpio-bank-name");
- if (uc_priv->bank_name == NULL)
- uc_priv->bank_name = "pm8916";
-
- return 0;
-}
-
-static const struct udevice_id pm8916_gpio_ids[] = {
- { .compatible = "qcom,pm8916-gpio" },
- { .compatible = "qcom,pm8994-gpio" }, /* 22 GPIO's */
- { .compatible = "qcom,pm8998-gpio" },
- { }
-};
-
-U_BOOT_DRIVER(gpio_pm8916) = {
- .name = "gpio_pm8916",
- .id = UCLASS_GPIO,
- .of_match = pm8916_gpio_ids,
- .of_to_plat = pm8916_gpio_of_to_plat,
- .probe = pm8916_gpio_probe,
- .ops = &pm8916_gpio_ops,
- .priv_auto = sizeof(struct pm8916_gpio_bank),
-};
-
-
-/* Add pmic buttons as GPIO as well - there is no generic way for now */
-#define PON_INT_RT_STS 0x10
-#define KPDPWR_ON_INT_BIT 0
-#define RESIN_ON_INT_BIT 1
-
-static int pm8941_pwrkey_get_function(struct udevice *dev, unsigned offset)
-{
- return GPIOF_INPUT;
-}
-
-static int pm8941_pwrkey_get_value(struct udevice *dev, unsigned offset)
-{
- struct pm8916_gpio_bank *priv = dev_get_priv(dev);
-
- int reg = pmic_reg_read(dev->parent, priv->pid + PON_INT_RT_STS);
-
- if (reg < 0)
- return 0;
-
- switch (offset) {
- case 0: /* Power button */
- return (reg & BIT(KPDPWR_ON_INT_BIT)) != 0;
- break;
- case 1: /* Reset button */
- default:
- return (reg & BIT(RESIN_ON_INT_BIT)) != 0;
- break;
- }
-}
-
-static const struct dm_gpio_ops pm8941_pwrkey_ops = {
- .get_value = pm8941_pwrkey_get_value,
- .get_function = pm8941_pwrkey_get_function,
-};
-
-static int pm8941_pwrkey_probe(struct udevice *dev)
-{
- struct pm8916_gpio_bank *priv = dev_get_priv(dev);
- int reg;
-
- priv->pid = dev_read_addr(dev);
- if (priv->pid == FDT_ADDR_T_NONE)
- return log_msg_ret("bad address", -EINVAL);
-
- /* Do a sanity check */
- reg = pmic_reg_read(dev->parent, priv->pid + REG_TYPE);
- if (reg != 0x1)
- return log_msg_ret("bad type", -ENXIO);
-
- reg = pmic_reg_read(dev->parent, priv->pid + REG_SUBTYPE);
- if ((reg & 0x5) == 0)
- return log_msg_ret("bad subtype", -ENXIO);
-
- return 0;
-}
-
-static int pm8941_pwrkey_of_to_plat(struct udevice *dev)
-{
- struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
-
- uc_priv->gpio_count = 2;
- uc_priv->bank_name = dev_read_string(dev, "gpio-bank-name");
- if (uc_priv->bank_name == NULL)
- uc_priv->bank_name = "pm8916_key";
-
- return 0;
-}
-
-static const struct udevice_id pm8941_pwrkey_ids[] = {
- { .compatible = "qcom,pm8916-pwrkey" },
- { .compatible = "qcom,pm8994-pwrkey" },
- { .compatible = "qcom,pm8998-pwrkey" },
- { }
-};
-
-U_BOOT_DRIVER(pwrkey_pm89xx) = {
- .name = "pwrkey_pm89xx",
- .id = UCLASS_GPIO,
- .of_match = pm8941_pwrkey_ids,
- .of_to_plat = pm8941_pwrkey_of_to_plat,
- .probe = pm8941_pwrkey_probe,
- .ops = &pm8941_pwrkey_ops,
- .priv_auto = sizeof(struct pm8916_gpio_bank),
-};
diff --git a/drivers/gpio/qcom_pmic_gpio.c b/drivers/gpio/qcom_pmic_gpio.c
new file mode 100644
index 00000000000..3be1be8692c
--- /dev/null
+++ b/drivers/gpio/qcom_pmic_gpio.c
@@ -0,0 +1,359 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Qualcomm generic pmic gpio driver
+ *
+ * (C) Copyright 2015 Mateusz Kulikowski <mateusz.kulikowski@gmail.com>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <log.h>
+#include <power/pmic.h>
+#include <spmi/spmi.h>
+#include <asm/io.h>
+#include <asm/gpio.h>
+#include <linux/bitops.h>
+
+/* Register offset for each gpio */
+#define REG_OFFSET(x) ((x) * 0x100)
+
+/* Register maps */
+
+/* Type and subtype are shared for all PMIC peripherals */
+#define REG_TYPE 0x4
+#define REG_SUBTYPE 0x5
+
+/* GPIO peripheral type and subtype out_values */
+#define REG_TYPE_VAL 0x10
+#define REG_SUBTYPE_GPIO_4CH 0x1
+#define REG_SUBTYPE_GPIOC_4CH 0x5
+#define REG_SUBTYPE_GPIO_8CH 0x9
+#define REG_SUBTYPE_GPIOC_8CH 0xd
+#define REG_SUBTYPE_GPIO_LV 0x10
+#define REG_SUBTYPE_GPIO_MV 0x11
+
+#define REG_STATUS 0x08
+#define REG_STATUS_VAL_MASK 0x1
+
+/* MODE_CTL */
+#define REG_CTL 0x40
+#define REG_CTL_MODE_MASK 0x70
+#define REG_CTL_MODE_INPUT 0x00
+#define REG_CTL_MODE_INOUT 0x20
+#define REG_CTL_MODE_OUTPUT 0x10
+#define REG_CTL_OUTPUT_MASK 0x0F
+#define REG_CTL_LV_MV_MODE_MASK 0x3
+#define REG_CTL_LV_MV_MODE_INPUT 0x0
+#define REG_CTL_LV_MV_MODE_INOUT 0x2
+#define REG_CTL_LV_MV_MODE_OUTPUT 0x1
+
+#define REG_DIG_VIN_CTL 0x41
+#define REG_DIG_VIN_VIN0 0
+
+#define REG_DIG_PULL_CTL 0x42
+#define REG_DIG_PULL_NO_PU 0x5
+
+#define REG_LV_MV_OUTPUT_CTL 0x44
+#define REG_LV_MV_OUTPUT_CTL_MASK 0x80
+#define REG_LV_MV_OUTPUT_CTL_SHIFT 7
+
+#define REG_DIG_OUT_CTL 0x45
+#define REG_DIG_OUT_CTL_CMOS (0x0 << 4)
+#define REG_DIG_OUT_CTL_DRIVE_L 0x1
+
+#define REG_EN_CTL 0x46
+#define REG_EN_CTL_ENABLE (1 << 7)
+
+struct qcom_gpio_bank {
+ uint32_t pid; /* Peripheral ID on SPMI bus */
+ bool lv_mv_type; /* If subtype is GPIO_LV(0x10) or GPIO_MV(0x11) */
+};
+
+static int qcom_gpio_set_direction(struct udevice *dev, unsigned offset,
+ bool input, int value)
+{
+ struct qcom_gpio_bank *priv = dev_get_priv(dev);
+ uint32_t gpio_base = priv->pid + REG_OFFSET(offset);
+ uint32_t reg_ctl_val;
+ int ret;
+
+ /* Disable the GPIO */
+ ret = pmic_clrsetbits(dev->parent, gpio_base + REG_EN_CTL,
+ REG_EN_CTL_ENABLE, 0);
+ if (ret < 0)
+ return ret;
+
+ /* Select the mode and output */
+ if (priv->lv_mv_type) {
+ if (input)
+ reg_ctl_val = REG_CTL_LV_MV_MODE_INPUT;
+ else
+ reg_ctl_val = REG_CTL_LV_MV_MODE_INOUT;
+ } else {
+ if (input)
+ reg_ctl_val = REG_CTL_MODE_INPUT;
+ else
+ reg_ctl_val = REG_CTL_MODE_INOUT | !!value;
+ }
+
+ ret = pmic_reg_write(dev->parent, gpio_base + REG_CTL, reg_ctl_val);
+ if (ret < 0)
+ return ret;
+
+ if (priv->lv_mv_type && !input) {
+ ret = pmic_reg_write(dev->parent,
+ gpio_base + REG_LV_MV_OUTPUT_CTL,
+ !!value << REG_LV_MV_OUTPUT_CTL_SHIFT);
+ if (ret < 0)
+ return ret;
+ }
+
+ /* Set the right pull (no pull) */
+ ret = pmic_reg_write(dev->parent, gpio_base + REG_DIG_PULL_CTL,
+ REG_DIG_PULL_NO_PU);
+ if (ret < 0)
+ return ret;
+
+ /* Configure output pin drivers if needed */
+ if (!input) {
+ /* Select the VIN - VIN0, pin is input so it doesn't matter */
+ ret = pmic_reg_write(dev->parent, gpio_base + REG_DIG_VIN_CTL,
+ REG_DIG_VIN_VIN0);
+ if (ret < 0)
+ return ret;
+
+ /* Set the right dig out control */
+ ret = pmic_reg_write(dev->parent, gpio_base + REG_DIG_OUT_CTL,
+ REG_DIG_OUT_CTL_CMOS |
+ REG_DIG_OUT_CTL_DRIVE_L);
+ if (ret < 0)
+ return ret;
+ }
+
+ /* Enable the GPIO */
+ return pmic_clrsetbits(dev->parent, gpio_base + REG_EN_CTL, 0,
+ REG_EN_CTL_ENABLE);
+}
+
+static int qcom_gpio_direction_input(struct udevice *dev, unsigned offset)
+{
+ return qcom_gpio_set_direction(dev, offset, true, 0);
+}
+
+static int qcom_gpio_direction_output(struct udevice *dev, unsigned offset,
+ int value)
+{
+ return qcom_gpio_set_direction(dev, offset, false, value);
+}
+
+static int qcom_gpio_get_function(struct udevice *dev, unsigned offset)
+{
+ struct qcom_gpio_bank *priv = dev_get_priv(dev);
+ uint32_t gpio_base = priv->pid + REG_OFFSET(offset);
+ int reg;
+
+ reg = pmic_reg_read(dev->parent, gpio_base + REG_CTL);
+ if (reg < 0)
+ return reg;
+
+ if (priv->lv_mv_type) {
+ switch (reg & REG_CTL_LV_MV_MODE_MASK) {
+ case REG_CTL_LV_MV_MODE_INPUT:
+ return GPIOF_INPUT;
+ case REG_CTL_LV_MV_MODE_INOUT: /* Fallthrough */
+ case REG_CTL_LV_MV_MODE_OUTPUT:
+ return GPIOF_OUTPUT;
+ default:
+ return GPIOF_UNKNOWN;
+ }
+ } else {
+ switch (reg & REG_CTL_MODE_MASK) {
+ case REG_CTL_MODE_INPUT:
+ return GPIOF_INPUT;
+ case REG_CTL_MODE_INOUT: /* Fallthrough */
+ case REG_CTL_MODE_OUTPUT:
+ return GPIOF_OUTPUT;
+ default:
+ return GPIOF_UNKNOWN;
+ }
+ }
+}
+
+static int qcom_gpio_get_value(struct udevice *dev, unsigned offset)
+{
+ struct qcom_gpio_bank *priv = dev_get_priv(dev);
+ uint32_t gpio_base = priv->pid + REG_OFFSET(offset);
+ int reg;
+
+ reg = pmic_reg_read(dev->parent, gpio_base + REG_STATUS);
+ if (reg < 0)
+ return reg;
+
+ return !!(reg & REG_STATUS_VAL_MASK);
+}
+
+static int qcom_gpio_set_value(struct udevice *dev, unsigned offset,
+ int value)
+{
+ struct qcom_gpio_bank *priv = dev_get_priv(dev);
+ uint32_t gpio_base = priv->pid + REG_OFFSET(offset);
+
+ /* Set the output value of the gpio */
+ if (priv->lv_mv_type)
+ return pmic_clrsetbits(dev->parent,
+ gpio_base + REG_LV_MV_OUTPUT_CTL,
+ REG_LV_MV_OUTPUT_CTL_MASK,
+ !!value << REG_LV_MV_OUTPUT_CTL_SHIFT);
+ else
+ return pmic_clrsetbits(dev->parent, gpio_base + REG_CTL,
+ REG_CTL_OUTPUT_MASK, !!value);
+}
+
+static const struct dm_gpio_ops qcom_gpio_ops = {
+ .direction_input = qcom_gpio_direction_input,
+ .direction_output = qcom_gpio_direction_output,
+ .get_value = qcom_gpio_get_value,
+ .set_value = qcom_gpio_set_value,
+ .get_function = qcom_gpio_get_function,
+};
+
+static int qcom_gpio_probe(struct udevice *dev)
+{
+ struct qcom_gpio_bank *priv = dev_get_priv(dev);
+ int reg;
+
+ priv->pid = dev_read_addr(dev);
+ if (priv->pid == FDT_ADDR_T_NONE)
+ return log_msg_ret("bad address", -EINVAL);
+
+ /* Do a sanity check */
+ reg = pmic_reg_read(dev->parent, priv->pid + REG_TYPE);
+ if (reg != REG_TYPE_VAL)
+ return log_msg_ret("bad type", -ENXIO);
+
+ reg = pmic_reg_read(dev->parent, priv->pid + REG_SUBTYPE);
+ if (reg != REG_SUBTYPE_GPIO_4CH && reg != REG_SUBTYPE_GPIOC_4CH &&
+ reg != REG_SUBTYPE_GPIO_LV && reg != REG_SUBTYPE_GPIO_MV)
+ return log_msg_ret("bad subtype", -ENXIO);
+
+ priv->lv_mv_type = reg == REG_SUBTYPE_GPIO_LV ||
+ reg == REG_SUBTYPE_GPIO_MV;
+
+ return 0;
+}
+
+static int qcom_gpio_of_to_plat(struct udevice *dev)
+{
+ struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
+
+ uc_priv->gpio_count = dev_read_u32_default(dev, "gpio-count", 0);
+ uc_priv->bank_name = dev_read_string(dev, "gpio-bank-name");
+ if (uc_priv->bank_name == NULL)
+ uc_priv->bank_name = "qcom_pmic";
+
+ return 0;
+}
+
+static const struct udevice_id qcom_gpio_ids[] = {
+ { .compatible = "qcom,pm8916-gpio" },
+ { .compatible = "qcom,pm8994-gpio" }, /* 22 GPIO's */
+ { .compatible = "qcom,pm8998-gpio" },
+ { .compatible = "qcom,pms405-gpio" },
+ { }
+};
+
+U_BOOT_DRIVER(qcom_pmic_gpio) = {
+ .name = "qcom_pmic_gpio",
+ .id = UCLASS_GPIO,
+ .of_match = qcom_gpio_ids,
+ .of_to_plat = qcom_gpio_of_to_plat,
+ .probe = qcom_gpio_probe,
+ .ops = &qcom_gpio_ops,
+ .priv_auto = sizeof(struct qcom_gpio_bank),
+};
+
+
+/* Add pmic buttons as GPIO as well - there is no generic way for now */
+#define PON_INT_RT_STS 0x10
+#define KPDPWR_ON_INT_BIT 0
+#define RESIN_ON_INT_BIT 1
+
+static int qcom_pwrkey_get_function(struct udevice *dev, unsigned offset)
+{
+ return GPIOF_INPUT;
+}
+
+static int qcom_pwrkey_get_value(struct udevice *dev, unsigned offset)
+{
+ struct qcom_gpio_bank *priv = dev_get_priv(dev);
+
+ int reg = pmic_reg_read(dev->parent, priv->pid + PON_INT_RT_STS);
+
+ if (reg < 0)
+ return 0;
+
+ switch (offset) {
+ case 0: /* Power button */
+ return (reg & BIT(KPDPWR_ON_INT_BIT)) != 0;
+ break;
+ case 1: /* Reset button */
+ default:
+ return (reg & BIT(RESIN_ON_INT_BIT)) != 0;
+ break;
+ }
+}
+
+static const struct dm_gpio_ops qcom_pwrkey_ops = {
+ .get_value = qcom_pwrkey_get_value,
+ .get_function = qcom_pwrkey_get_function,
+};
+
+static int qcom_pwrkey_probe(struct udevice *dev)
+{
+ struct qcom_gpio_bank *priv = dev_get_priv(dev);
+ int reg;
+
+ priv->pid = dev_read_addr(dev);
+ if (priv->pid == FDT_ADDR_T_NONE)
+ return log_msg_ret("bad address", -EINVAL);
+
+ /* Do a sanity check */
+ reg = pmic_reg_read(dev->parent, priv->pid + REG_TYPE);
+ if (reg != 0x1)
+ return log_msg_ret("bad type", -ENXIO);
+
+ reg = pmic_reg_read(dev->parent, priv->pid + REG_SUBTYPE);
+ if ((reg & 0x5) == 0)
+ return log_msg_ret("bad subtype", -ENXIO);
+
+ return 0;
+}
+
+static int qcom_pwrkey_of_to_plat(struct udevice *dev)
+{
+ struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
+
+ uc_priv->gpio_count = 2;
+ uc_priv->bank_name = dev_read_string(dev, "gpio-bank-name");
+ if (uc_priv->bank_name == NULL)
+ uc_priv->bank_name = "pwkey_qcom";
+
+ return 0;
+}
+
+static const struct udevice_id qcom_pwrkey_ids[] = {
+ { .compatible = "qcom,pm8916-pwrkey" },
+ { .compatible = "qcom,pm8994-pwrkey" },
+ { .compatible = "qcom,pm8998-pwrkey" },
+ { }
+};
+
+U_BOOT_DRIVER(pwrkey_qcom) = {
+ .name = "pwrkey_qcom",
+ .id = UCLASS_GPIO,
+ .of_match = qcom_pwrkey_ids,
+ .of_to_plat = qcom_pwrkey_of_to_plat,
+ .probe = qcom_pwrkey_probe,
+ .ops = &qcom_pwrkey_ops,
+ .priv_auto = sizeof(struct qcom_gpio_bank),
+};
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index c25b42c68f5..cf4d5908d73 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -143,12 +143,6 @@ config STI_USB_PHY
used by USB2 and USB3 Host controllers available on
STiH407 SoC families.
-config PHY_QCOM_IPQ4019_USB
- tristate "Qualcomm IPQ4019 USB PHY driver"
- depends on PHY && ARCH_IPQ40XX
- help
- Support for the USB PHY-s on Qualcomm IPQ40xx SoC-s.
-
config PHY_RCAR_GEN2
tristate "Renesas R-Car Gen2 USB PHY"
depends on PHY && RCAR_GEN2
@@ -220,14 +214,6 @@ config MESON_AXG_MIPI_PCIE_ANALOG_PHY
This is the generic phy driver for the Amlogic Meson AXG
MIPI PCIe Analog PHY.
-config MSM8916_USB_PHY
- bool "Qualcomm MSM8916 USB PHY support"
- depends on PHY
- help
- Support the USB PHY in msm8916
-
- This PHY is found on qualcomm dragonboard410c development board.
-
config OMAP_USB2_PHY
bool "Support OMAP's USB2 PHY"
depends on PHY
@@ -298,5 +284,6 @@ config PHY_XILINX_ZYNQMP
source "drivers/phy/rockchip/Kconfig"
source "drivers/phy/cadence/Kconfig"
source "drivers/phy/ti/Kconfig"
+source "drivers/phy/qcom/Kconfig"
endmenu
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
index d95439c4257..a3b9f3c5b18 100644
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -21,7 +21,6 @@ obj-$(CONFIG_PHY_SANDBOX) += sandbox-phy.o
obj-$(CONFIG_$(SPL_)PIPE3_PHY) += ti-pipe3-phy.o
obj-$(CONFIG_AM654_PHY) += phy-ti-am654.o
obj-$(CONFIG_STI_USB_PHY) += sti_usb_phy.o
-obj-$(CONFIG_PHY_QCOM_IPQ4019_USB) += phy-qcom-ipq4019-usb.o
obj-$(CONFIG_PHY_RCAR_GEN2) += phy-rcar-gen2.o
obj-$(CONFIG_PHY_RCAR_GEN3) += phy-rcar-gen3.o
obj-$(CONFIG_PHY_STM32_USBPHYC) += phy-stm32-usbphyc.o
@@ -30,7 +29,6 @@ obj-$(CONFIG_MESON_GXL_USB_PHY) += meson-gxl-usb2.o
obj-$(CONFIG_MESON_G12A_USB_PHY) += meson-g12a-usb2.o meson-g12a-usb3-pcie.o
obj-$(CONFIG_MESON_AXG_MIPI_DPHY) += meson-axg-mipi-dphy.o
obj-$(CONFIG_MESON_AXG_MIPI_PCIE_ANALOG_PHY) += meson-axg-mipi-pcie-analog.o
-obj-$(CONFIG_MSM8916_USB_PHY) += msm8916-usbh-phy.o
obj-$(CONFIG_OMAP_USB2_PHY) += omap-usb2-phy.o
obj-$(CONFIG_KEYSTONE_USB_PHY) += keystone-usb-phy.o
obj-$(CONFIG_MT7620_USB_PHY) += mt7620-usb-phy.o
@@ -42,3 +40,4 @@ obj-$(CONFIG_PHY_IMX8MQ_USB) += phy-imx8mq-usb.o
obj-$(CONFIG_PHY_XILINX_ZYNQMP) += phy-zynqmp.o
obj-y += cadence/
obj-y += ti/
+obj-y += qcom/
diff --git a/drivers/phy/qcom/Kconfig b/drivers/phy/qcom/Kconfig
new file mode 100644
index 00000000000..f4ca174805a
--- /dev/null
+++ b/drivers/phy/qcom/Kconfig
@@ -0,0 +1,29 @@
+config MSM8916_USB_PHY
+ bool "Qualcomm MSM8916 USB PHY support"
+ depends on PHY
+ help
+ Support the USB PHY in msm8916
+
+ This PHY is found on qualcomm dragonboard410c development board.
+
+config PHY_QCOM_IPQ4019_USB
+ tristate "Qualcomm IPQ4019 USB PHY driver"
+ depends on PHY && ARCH_IPQ40XX
+ help
+ Support for the USB PHY-s on Qualcomm IPQ40xx SoC-s.
+
+config PHY_QCOM_USB_HS_28NM
+ tristate "Qualcomm 28nm High-Speed PHY"
+ depends on PHY && ARCH_SNAPDRAGON
+ help
+ Enable this to support the Qualcomm Synopsys DesignWare Core 28nm
+ High-Speed PHY driver. This driver supports the Hi-Speed PHY which
+ is usually paired with either the ChipIdea or Synopsys DWC3 USB
+ IPs on MSM SOCs.
+
+config PHY_QCOM_USB_SS
+ tristate "Qualcomm USB Super-Speed PHY driver"
+ depends on PHY && ARCH_SNAPDRAGON
+ help
+ Enable this to support the Super-Speed USB transceiver on various
+ Qualcomm chipsets.
diff --git a/drivers/phy/qcom/Makefile b/drivers/phy/qcom/Makefile
new file mode 100644
index 00000000000..2113f178c0c
--- /dev/null
+++ b/drivers/phy/qcom/Makefile
@@ -0,0 +1,4 @@
+obj-$(CONFIG_PHY_QCOM_IPQ4019_USB) += phy-qcom-ipq4019-usb.o
+obj-$(CONFIG_MSM8916_USB_PHY) += msm8916-usbh-phy.o
+obj-$(CONFIG_PHY_QCOM_USB_HS_28NM) += phy-qcom-usb-hs-28nm.o
+obj-$(CONFIG_PHY_QCOM_USB_SS) += phy-qcom-usb-ss.o
diff --git a/drivers/phy/msm8916-usbh-phy.c b/drivers/phy/qcom/msm8916-usbh-phy.c
index 7c9d030a4d8..7c9d030a4d8 100644
--- a/drivers/phy/msm8916-usbh-phy.c
+++ b/drivers/phy/qcom/msm8916-usbh-phy.c
diff --git a/drivers/phy/phy-qcom-ipq4019-usb.c b/drivers/phy/qcom/phy-qcom-ipq4019-usb.c
index 5808489249f..5808489249f 100644
--- a/drivers/phy/phy-qcom-ipq4019-usb.c
+++ b/drivers/phy/qcom/phy-qcom-ipq4019-usb.c
diff --git a/drivers/phy/qcom/phy-qcom-usb-hs-28nm.c b/drivers/phy/qcom/phy-qcom-usb-hs-28nm.c
new file mode 100644
index 00000000000..14c3d8394df
--- /dev/null
+++ b/drivers/phy/qcom/phy-qcom-usb-hs-28nm.c
@@ -0,0 +1,250 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2022 Sumit Garg <sumit.garg@linaro.org>
+ *
+ * Based on Linux driver
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <generic-phy.h>
+#include <reset.h>
+#include <clk.h>
+#include <asm/io.h>
+#include <linux/delay.h>
+
+/* PHY register and bit definitions */
+#define PHY_CTRL_COMMON0 0x078
+#define SIDDQ BIT(2)
+
+struct hsphy_init_seq {
+ int offset;
+ int val;
+ int delay;
+};
+
+struct hsphy_data {
+ const struct hsphy_init_seq *init_seq;
+ unsigned int init_seq_num;
+};
+
+struct hsphy_priv {
+ void __iomem *base;
+ struct clk_bulk clks;
+ struct reset_ctl phy_rst;
+ struct reset_ctl por_rst;
+ const struct hsphy_data *data;
+};
+
+static int hsphy_power_on(struct phy *phy)
+{
+ struct hsphy_priv *priv = dev_get_priv(phy->dev);
+ u32 val;
+
+ val = readb(priv->base + PHY_CTRL_COMMON0);
+ val &= ~SIDDQ;
+ writeb(val, priv->base + PHY_CTRL_COMMON0);
+
+ return 0;
+}
+
+static int hsphy_power_off(struct phy *phy)
+{
+ struct hsphy_priv *priv = dev_get_priv(phy->dev);
+ u32 val;
+
+ val = readb(priv->base + PHY_CTRL_COMMON0);
+ val |= SIDDQ;
+ writeb(val, priv->base + PHY_CTRL_COMMON0);
+
+ return 0;
+}
+
+static int hsphy_reset(struct hsphy_priv *priv)
+{
+ int ret;
+
+ ret = reset_assert(&priv->phy_rst);
+ if (ret)
+ return ret;
+
+ udelay(10);
+
+ ret = reset_deassert(&priv->phy_rst);
+ if (ret)
+ return ret;
+
+ udelay(80);
+
+ return 0;
+}
+
+static void hsphy_init_sequence(struct hsphy_priv *priv)
+{
+ const struct hsphy_data *data = priv->data;
+ const struct hsphy_init_seq *seq;
+ int i;
+
+ /* Device match data is optional. */
+ if (!data)
+ return;
+
+ seq = data->init_seq;
+
+ for (i = 0; i < data->init_seq_num; i++, seq++) {
+ writeb(seq->val, priv->base + seq->offset);
+ if (seq->delay)
+ udelay(seq->delay);
+ }
+}
+
+static int hsphy_por_reset(struct hsphy_priv *priv)
+{
+ int ret;
+ u32 val;
+
+ ret = reset_assert(&priv->por_rst);
+ if (ret)
+ return ret;
+
+ /*
+ * The Femto PHY is POR reset in the following scenarios.
+ *
+ * 1. After overriding the parameter registers.
+ * 2. Low power mode exit from PHY retention.
+ *
+ * Ensure that SIDDQ is cleared before bringing the PHY
+ * out of reset.
+ */
+ val = readb(priv->base + PHY_CTRL_COMMON0);
+ val &= ~SIDDQ;
+ writeb(val, priv->base + PHY_CTRL_COMMON0);
+
+ /*
+ * As per databook, 10 usec delay is required between
+ * PHY POR assert and de-assert.
+ */
+ udelay(10);
+ ret = reset_deassert(&priv->por_rst);
+ if (ret)
+ return ret;
+
+ /*
+ * As per databook, it takes 75 usec for PHY to stabilize
+ * after the reset.
+ */
+ udelay(80);
+
+ return 0;
+}
+
+static int hsphy_clk_init(struct udevice *dev, struct hsphy_priv *priv)
+{
+ int ret;
+
+ ret = clk_get_bulk(dev, &priv->clks);
+ if (ret == -ENOSYS || ret == -ENOENT)
+ return 0;
+ if (ret)
+ return ret;
+
+ ret = clk_enable_bulk(&priv->clks);
+ if (ret) {
+ clk_release_bulk(&priv->clks);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int hsphy_init(struct phy *phy)
+{
+ struct hsphy_priv *priv = dev_get_priv(phy->dev);
+ int ret;
+
+ ret = hsphy_clk_init(phy->dev, priv);
+ if (ret)
+ return ret;
+
+ ret = hsphy_reset(priv);
+ if (ret)
+ return ret;
+
+ hsphy_init_sequence(priv);
+
+ hsphy_por_reset(priv);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static int hsphy_probe(struct udevice *dev)
+{
+ struct hsphy_priv *priv = dev_get_priv(dev);
+ int ret;
+
+ priv->base = (void *)dev_read_addr(dev);
+ if ((ulong)priv->base == FDT_ADDR_T_NONE)
+ return -EINVAL;
+
+ ret = reset_get_by_name(dev, "phy", &priv->phy_rst);
+ if (ret)
+ return ret;
+
+ ret = reset_get_by_name(dev, "por", &priv->por_rst);
+ if (ret)
+ return ret;
+
+ priv->data = (const struct hsphy_data *)dev_get_driver_data(dev);
+
+ return 0;
+}
+
+static struct phy_ops hsphy_ops = {
+ .power_on = hsphy_power_on,
+ .power_off = hsphy_power_off,
+ .init = hsphy_init,
+};
+
+/*
+ * The macro is used to define an initialization sequence. Each tuple
+ * is meant to program 'value' into phy register at 'offset' with 'delay'
+ * in us followed.
+ */
+#define HSPHY_INIT_CFG(o, v, d) { .offset = o, .val = v, .delay = d, }
+
+static const struct hsphy_init_seq init_seq_femtophy[] = {
+ HSPHY_INIT_CFG(0xc0, 0x01, 0),
+ HSPHY_INIT_CFG(0xe8, 0x0d, 0),
+ HSPHY_INIT_CFG(0x74, 0x12, 0),
+ HSPHY_INIT_CFG(0x98, 0x63, 0),
+ HSPHY_INIT_CFG(0x9c, 0x03, 0),
+ HSPHY_INIT_CFG(0xa0, 0x1d, 0),
+ HSPHY_INIT_CFG(0xa4, 0x03, 0),
+ HSPHY_INIT_CFG(0x8c, 0x23, 0),
+ HSPHY_INIT_CFG(0x78, 0x08, 0),
+ HSPHY_INIT_CFG(0x7c, 0xdc, 0),
+ HSPHY_INIT_CFG(0x90, 0xe0, 20),
+ HSPHY_INIT_CFG(0x74, 0x10, 0),
+ HSPHY_INIT_CFG(0x90, 0x60, 0),
+};
+
+static const struct hsphy_data data_femtophy = {
+ .init_seq = init_seq_femtophy,
+ .init_seq_num = ARRAY_SIZE(init_seq_femtophy),
+};
+
+static const struct udevice_id hsphy_ids[] = {
+ { .compatible = "qcom,usb-hs-28nm-femtophy", .data = (ulong)&data_femtophy },
+ { }
+};
+
+U_BOOT_DRIVER(qcom_usb_hs_28nm) = {
+ .name = "qcom-usb-hs-28nm",
+ .id = UCLASS_PHY,
+ .of_match = hsphy_ids,
+ .ops = &hsphy_ops,
+ .probe = hsphy_probe,
+ .priv_auto = sizeof(struct hsphy_priv),
+};
diff --git a/drivers/phy/qcom/phy-qcom-usb-ss.c b/drivers/phy/qcom/phy-qcom-usb-ss.c
new file mode 100644
index 00000000000..4e816879c6a
--- /dev/null
+++ b/drivers/phy/qcom/phy-qcom-usb-ss.c
@@ -0,0 +1,154 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2022 Sumit Garg <sumit.garg@linaro.org>
+ *
+ * Based on Linux driver
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <generic-phy.h>
+#include <linux/bitops.h>
+#include <asm/io.h>
+#include <reset.h>
+#include <clk.h>
+#include <linux/delay.h>
+
+#define PHY_CTRL0 0x6C
+#define PHY_CTRL1 0x70
+#define PHY_CTRL2 0x74
+#define PHY_CTRL4 0x7C
+
+/* PHY_CTRL bits */
+#define REF_PHY_EN BIT(0)
+#define LANE0_PWR_ON BIT(2)
+#define SWI_PCS_CLK_SEL BIT(4)
+#define TST_PWR_DOWN BIT(4)
+#define PHY_RESET BIT(7)
+
+struct ssphy_priv {
+ void __iomem *base;
+ struct clk_bulk clks;
+ struct reset_ctl com_rst;
+ struct reset_ctl phy_rst;
+};
+
+static inline void ssphy_updatel(void __iomem *addr, u32 mask, u32 val)
+{
+ writel((readl(addr) & ~mask) | val, addr);
+}
+
+static int ssphy_do_reset(struct ssphy_priv *priv)
+{
+ int ret;
+
+ ret = reset_assert(&priv->com_rst);
+ if (ret)
+ return ret;
+
+ ret = reset_assert(&priv->phy_rst);
+ if (ret)
+ return ret;
+
+ udelay(10);
+
+ ret = reset_deassert(&priv->com_rst);
+ if (ret)
+ return ret;
+
+ ret = reset_deassert(&priv->phy_rst);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static int ssphy_power_on(struct phy *phy)
+{
+ struct ssphy_priv *priv = dev_get_priv(phy->dev);
+ int ret;
+
+ ret = ssphy_do_reset(priv);
+ if (ret)
+ return ret;
+
+ writeb(SWI_PCS_CLK_SEL, priv->base + PHY_CTRL0);
+ ssphy_updatel(priv->base + PHY_CTRL4, LANE0_PWR_ON, LANE0_PWR_ON);
+ ssphy_updatel(priv->base + PHY_CTRL2, REF_PHY_EN, REF_PHY_EN);
+ ssphy_updatel(priv->base + PHY_CTRL4, TST_PWR_DOWN, 0);
+
+ return 0;
+}
+
+static int ssphy_power_off(struct phy *phy)
+{
+ struct ssphy_priv *priv = dev_get_priv(phy->dev);
+
+ ssphy_updatel(priv->base + PHY_CTRL4, LANE0_PWR_ON, 0);
+ ssphy_updatel(priv->base + PHY_CTRL2, REF_PHY_EN, 0);
+ ssphy_updatel(priv->base + PHY_CTRL4, TST_PWR_DOWN, TST_PWR_DOWN);
+
+ return 0;
+}
+
+static int ssphy_clk_init(struct udevice *dev, struct ssphy_priv *priv)
+{
+ int ret;
+
+ ret = clk_get_bulk(dev, &priv->clks);
+ if (ret == -ENOSYS || ret == -ENOENT)
+ return 0;
+ if (ret)
+ return ret;
+
+ ret = clk_enable_bulk(&priv->clks);
+ if (ret) {
+ clk_release_bulk(&priv->clks);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int ssphy_probe(struct udevice *dev)
+{
+ struct ssphy_priv *priv = dev_get_priv(dev);
+ int ret;
+
+ priv->base = (void *)dev_read_addr(dev);
+ if ((ulong)priv->base == FDT_ADDR_T_NONE)
+ return -EINVAL;
+
+ ret = ssphy_clk_init(dev, priv);
+ if (ret)
+ return ret;
+
+ ret = reset_get_by_name(dev, "com", &priv->com_rst);
+ if (ret)
+ return ret;
+
+ ret = reset_get_by_name(dev, "phy", &priv->phy_rst);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static struct phy_ops ssphy_ops = {
+ .power_on = ssphy_power_on,
+ .power_off = ssphy_power_off,
+};
+
+static const struct udevice_id ssphy_ids[] = {
+ { .compatible = "qcom,usb-ss-28nm-phy" },
+ { }
+};
+
+U_BOOT_DRIVER(qcom_usb_ss) = {
+ .name = "qcom-usb-ss",
+ .id = UCLASS_PHY,
+ .of_match = ssphy_ids,
+ .ops = &ssphy_ops,
+ .probe = ssphy_probe,
+ .priv_auto = sizeof(struct ssphy_priv),
+};
diff --git a/drivers/power/pmic/Kconfig b/drivers/power/pmic/Kconfig
index 66b16b06e0b..0478f2aa1d4 100644
--- a/drivers/power/pmic/Kconfig
+++ b/drivers/power/pmic/Kconfig
@@ -216,10 +216,10 @@ config PMIC_MAX8997
- MUIC
- Others
-config PMIC_PM8916
- bool "Enable Driver Model for Qualcomm PM8916 PMIC"
+config PMIC_QCOM
+ bool "Enable Driver Model for Qualcomm generic PMIC"
---help---
- The PM8916 is a PMIC connected to one (or several) processors
+ The Qcom PMIC is connected to one (or several) processors
with SPMI bus. It has 2 slaves with several peripherals:
- 18x LDO
- 4x GPIO
@@ -229,7 +229,7 @@ config PMIC_PM8916
- Vibrator drivers
- Others
- Driver binding info: doc/device-tree-bindings/pmic/pm8916.txt
+ Driver binding info: doc/device-tree-bindings/pmic/qcom,spmi-pmic.txt
config PMIC_RK8XX
bool "Enable support for Rockchip PMIC RK8XX"
diff --git a/drivers/power/pmic/Makefile b/drivers/power/pmic/Makefile
index f73b3262559..e1d35454904 100644
--- a/drivers/power/pmic/Makefile
+++ b/drivers/power/pmic/Makefile
@@ -20,7 +20,7 @@ obj-$(CONFIG_PMIC_ACT8846) += act8846.o
obj-$(CONFIG_PMIC_AS3722) += as3722.o as3722_gpio.o
obj-$(CONFIG_$(SPL_)PMIC_AXP) += axp.o
obj-$(CONFIG_PMIC_MAX8997) += max8997.o
-obj-$(CONFIG_PMIC_PM8916) += pm8916.o
+obj-$(CONFIG_PMIC_QCOM) += pmic_qcom.o
obj-$(CONFIG_$(SPL_TPL_)PMIC_RK8XX) += rk8xx.o
obj-$(CONFIG_PMIC_RN5T567) += rn5t567.o
obj-$(CONFIG_PMIC_TPS65090) += tps65090.o
diff --git a/drivers/power/pmic/pm8916.c b/drivers/power/pmic/pmic_qcom.c
index 5f4386d4adf..ad8daf43f06 100644
--- a/drivers/power/pmic/pm8916.c
+++ b/drivers/power/pmic/pmic_qcom.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0+
/*
- * Qualcomm pm8916 pmic driver
+ * Qualcomm generic pmic driver
*
* (C) Copyright 2015 Mateusz Kulikowski <mateusz.kulikowski@gmail.com>
*/
@@ -13,19 +13,19 @@
#define PID_MASK (0xFF << PID_SHIFT)
#define REG_MASK 0xFF
-struct pm8916_priv {
+struct pmic_qcom_priv {
uint32_t usid; /* Slave ID on SPMI bus */
};
-static int pm8916_reg_count(struct udevice *dev)
+static int pmic_qcom_reg_count(struct udevice *dev)
{
return 0xFFFF;
}
-static int pm8916_write(struct udevice *dev, uint reg, const uint8_t *buff,
- int len)
+static int pmic_qcom_write(struct udevice *dev, uint reg, const uint8_t *buff,
+ int len)
{
- struct pm8916_priv *priv = dev_get_priv(dev);
+ struct pmic_qcom_priv *priv = dev_get_priv(dev);
if (len != 1)
return -EINVAL;
@@ -35,9 +35,9 @@ static int pm8916_write(struct udevice *dev, uint reg, const uint8_t *buff,
*buff);
}
-static int pm8916_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
+static int pmic_qcom_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
{
- struct pm8916_priv *priv = dev_get_priv(dev);
+ struct pmic_qcom_priv *priv = dev_get_priv(dev);
int val;
if (len != 1)
@@ -52,20 +52,20 @@ static int pm8916_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
return 0;
}
-static struct dm_pmic_ops pm8916_ops = {
- .reg_count = pm8916_reg_count,
- .read = pm8916_read,
- .write = pm8916_write,
+static struct dm_pmic_ops pmic_qcom_ops = {
+ .reg_count = pmic_qcom_reg_count,
+ .read = pmic_qcom_read,
+ .write = pmic_qcom_write,
};
-static const struct udevice_id pm8916_ids[] = {
+static const struct udevice_id pmic_qcom_ids[] = {
{ .compatible = "qcom,spmi-pmic" },
{ }
};
-static int pm8916_probe(struct udevice *dev)
+static int pmic_qcom_probe(struct udevice *dev)
{
- struct pm8916_priv *priv = dev_get_priv(dev);
+ struct pmic_qcom_priv *priv = dev_get_priv(dev);
priv->usid = dev_read_addr(dev);
@@ -75,12 +75,12 @@ static int pm8916_probe(struct udevice *dev)
return 0;
}
-U_BOOT_DRIVER(pmic_pm8916) = {
- .name = "pmic_pm8916",
+U_BOOT_DRIVER(pmic_qcom) = {
+ .name = "pmic_qcom",
.id = UCLASS_PMIC,
- .of_match = pm8916_ids,
+ .of_match = pmic_qcom_ids,
.bind = dm_scan_fdt_dev,
- .probe = pm8916_probe,
- .ops = &pm8916_ops,
- .priv_auto = sizeof(struct pm8916_priv),
+ .probe = pmic_qcom_probe,
+ .ops = &pmic_qcom_ops,
+ .priv_auto = sizeof(struct pmic_qcom_priv),
};
diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
index 69a7b4ccbad..4cb0ba08508 100644
--- a/drivers/reset/Kconfig
+++ b/drivers/reset/Kconfig
@@ -156,13 +156,12 @@ config RESET_IMX7
help
Support for reset controller on i.MX7/8 SoCs.
-config RESET_IPQ419
- bool "Reset driver for Qualcomm IPQ40xx SoCs"
- depends on DM_RESET && ARCH_IPQ40XX
+config RESET_QCOM
+ bool "Reset driver for Qualcomm SoCs"
+ depends on DM_RESET && (ARCH_SNAPDRAGON || ARCH_IPQ40XX)
default y
help
- Support for reset controller on Qualcomm
- IPQ40xx SoCs.
+ Support for reset controller on Qualcomm SoCs.
config RESET_SIFIVE
bool "Reset Driver for SiFive SoC's"
diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
index 97e3a782c0d..0620b628090 100644
--- a/drivers/reset/Makefile
+++ b/drivers/reset/Makefile
@@ -24,7 +24,7 @@ obj-$(CONFIG_RESET_MTMIPS) += reset-mtmips.o
obj-$(CONFIG_RESET_SUNXI) += reset-sunxi.o
obj-$(CONFIG_RESET_HISILICON) += reset-hisilicon.o
obj-$(CONFIG_RESET_IMX7) += reset-imx7.o
-obj-$(CONFIG_RESET_IPQ419) += reset-ipq4019.o
+obj-$(CONFIG_RESET_QCOM) += reset-qcom.o
obj-$(CONFIG_RESET_SIFIVE) += reset-sifive.o
obj-$(CONFIG_RESET_SYSCON) += reset-syscon.o
obj-$(CONFIG_RESET_RASPBERRYPI) += reset-raspberrypi.o
diff --git a/drivers/reset/reset-ipq4019.c b/drivers/reset/reset-qcom.c
index 7f0bd85ad68..94315e76d54 100644
--- a/drivers/reset/reset-ipq4019.c
+++ b/drivers/reset/reset-qcom.c
@@ -1,8 +1,10 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2020 Sartura Ltd.
+ * Copyright (c) 2022 Linaro Ltd.
*
* Author: Robert Marko <robert.marko@sartura.hr>
+ * Sumit Garg <sumit.garg@linaro.org>
*
* Based on Linux driver
*/
@@ -10,12 +12,11 @@
#include <asm/io.h>
#include <common.h>
#include <dm.h>
-#include <dt-bindings/reset/qcom,ipq4019-reset.h>
#include <reset-uclass.h>
#include <linux/bitops.h>
#include <malloc.h>
-struct ipq4019_reset_priv {
+struct qcom_reset_priv {
phys_addr_t base;
};
@@ -24,7 +25,9 @@ struct qcom_reset_map {
u8 bit;
};
-static const struct qcom_reset_map gcc_ipq4019_resets[] = {
+#ifdef CONFIG_ARCH_IPQ40XX
+#include <dt-bindings/reset/qcom,ipq4019-reset.h>
+static const struct qcom_reset_map gcc_qcom_resets[] = {
[WIFI0_CPU_INIT_RESET] = { 0x1f008, 5 },
[WIFI0_RADIO_SRIF_RESET] = { 0x1f008, 4 },
[WIFI0_RADIO_WARM_RESET] = { 0x1f008, 3 },
@@ -97,11 +100,41 @@ static const struct qcom_reset_map gcc_ipq4019_resets[] = {
[GCC_MPM_BCR] = {0x24000, 0},
[GCC_SPDM_BCR] = {0x25000, 0},
};
+#endif
+
+#ifdef CONFIG_TARGET_QCS404EVB
+#include <dt-bindings/clock/qcom,gcc-qcs404.h>
+static const struct qcom_reset_map gcc_qcom_resets[] = {
+ [GCC_GENI_IR_BCR] = { 0x0F000 },
+ [GCC_CDSP_RESTART] = { 0x18000 },
+ [GCC_USB_HS_BCR] = { 0x41000 },
+ [GCC_USB2_HS_PHY_ONLY_BCR] = { 0x41034 },
+ [GCC_QUSB2_PHY_BCR] = { 0x4103c },
+ [GCC_USB_HS_PHY_CFG_AHB_BCR] = { 0x0000c, 1 },
+ [GCC_USB2A_PHY_BCR] = { 0x0000c, 0 },
+ [GCC_USB3_PHY_BCR] = { 0x39004 },
+ [GCC_USB_30_BCR] = { 0x39000 },
+ [GCC_USB3PHY_PHY_BCR] = { 0x39008 },
+ [GCC_PCIE_0_BCR] = { 0x3e000 },
+ [GCC_PCIE_0_PHY_BCR] = { 0x3e004 },
+ [GCC_PCIE_0_LINK_DOWN_BCR] = { 0x3e038 },
+ [GCC_PCIEPHY_0_PHY_BCR] = { 0x3e03c },
+ [GCC_PCIE_0_AXI_MASTER_STICKY_ARES] = { 0x3e040, 6},
+ [GCC_PCIE_0_AHB_ARES] = { 0x3e040, 5 },
+ [GCC_PCIE_0_AXI_SLAVE_ARES] = { 0x3e040, 4 },
+ [GCC_PCIE_0_AXI_MASTER_ARES] = { 0x3e040, 3 },
+ [GCC_PCIE_0_CORE_STICKY_ARES] = { 0x3e040, 2 },
+ [GCC_PCIE_0_SLEEP_ARES] = { 0x3e040, 1 },
+ [GCC_PCIE_0_PIPE_ARES] = { 0x3e040, 0 },
+ [GCC_EMAC_BCR] = { 0x4e000 },
+ [GCC_WDSP_RESTART] = {0x19000},
+};
+#endif
-static int ipq4019_reset_assert(struct reset_ctl *rst)
+static int qcom_reset_assert(struct reset_ctl *rst)
{
- struct ipq4019_reset_priv *priv = dev_get_priv(rst->dev);
- const struct qcom_reset_map *reset_map = gcc_ipq4019_resets;
+ struct qcom_reset_priv *priv = dev_get_priv(rst->dev);
+ const struct qcom_reset_map *reset_map = gcc_qcom_resets;
const struct qcom_reset_map *map;
u32 value;
@@ -114,10 +147,10 @@ static int ipq4019_reset_assert(struct reset_ctl *rst)
return 0;
}
-static int ipq4019_reset_deassert(struct reset_ctl *rst)
+static int qcom_reset_deassert(struct reset_ctl *rst)
{
- struct ipq4019_reset_priv *priv = dev_get_priv(rst->dev);
- const struct qcom_reset_map *reset_map = gcc_ipq4019_resets;
+ struct qcom_reset_priv *priv = dev_get_priv(rst->dev);
+ const struct qcom_reset_map *reset_map = gcc_qcom_resets;
const struct qcom_reset_map *map;
u32 value;
@@ -130,19 +163,20 @@ static int ipq4019_reset_deassert(struct reset_ctl *rst)
return 0;
}
-static const struct reset_ops ipq4019_reset_ops = {
- .rst_assert = ipq4019_reset_assert,
- .rst_deassert = ipq4019_reset_deassert,
+static const struct reset_ops qcom_reset_ops = {
+ .rst_assert = qcom_reset_assert,
+ .rst_deassert = qcom_reset_deassert,
};
-static const struct udevice_id ipq4019_reset_ids[] = {
+static const struct udevice_id qcom_reset_ids[] = {
{ .compatible = "qcom,gcc-reset-ipq4019" },
+ { .compatible = "qcom,gcc-reset-qcs404" },
{ }
};
-static int ipq4019_reset_probe(struct udevice *dev)
+static int qcom_reset_probe(struct udevice *dev)
{
- struct ipq4019_reset_priv *priv = dev_get_priv(dev);
+ struct qcom_reset_priv *priv = dev_get_priv(dev);
priv->base = dev_read_addr(dev);
if (priv->base == FDT_ADDR_T_NONE)
@@ -151,11 +185,11 @@ static int ipq4019_reset_probe(struct udevice *dev)
return 0;
}
-U_BOOT_DRIVER(ipq4019_reset) = {
- .name = "ipq4019_reset",
+U_BOOT_DRIVER(qcom_reset) = {
+ .name = "qcom_reset",
.id = UCLASS_RESET,
- .of_match = ipq4019_reset_ids,
- .ops = &ipq4019_reset_ops,
- .probe = ipq4019_reset_probe,
- .priv_auto = sizeof(struct ipq4019_reset_priv),
+ .of_match = qcom_reset_ids,
+ .ops = &qcom_reset_ops,
+ .probe = qcom_reset_probe,
+ .priv_auto = sizeof(struct qcom_reset_priv),
};