diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2023-09-01 19:53:54 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2023-09-01 19:53:54 +0300 |
commit | 1c9f8dff62d85ce00b0e99f774a84bd783af7cac (patch) | |
tree | cd1fcbc26856dfd1981ef1f81396eb67dde993bd /drivers/firmware/stratix10-rsu.c | |
parent | 28a4f91f5f251689c69155bc6a0b1afc9916c874 (diff) | |
parent | 704e2c6107f1a5353a1038bac137dda0df2a6dd0 (diff) | |
download | linux-1c9f8dff62d85ce00b0e99f774a84bd783af7cac.tar.xz |
Merge tag 'char-misc-6.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc
Pull char/misc driver updates from Greg KH:
"Here is the big set of char/misc and other small driver subsystem
changes for 6.6-rc1.
Stuff all over the place here, lots of driver updates and changes and
new additions. Short summary is:
- new IIO drivers and updates
- Interconnect driver updates
- fpga driver updates and additions
- fsi driver updates
- mei driver updates
- coresight driver updates
- nvmem driver updates
- counter driver updates
- lots of smaller misc and char driver updates and additions
All of these have been in linux-next for a long time with no reported
problems"
* tag 'char-misc-6.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: (267 commits)
nvmem: core: Notify when a new layout is registered
nvmem: core: Do not open-code existing functions
nvmem: core: Return NULL when no nvmem layout is found
nvmem: core: Create all cells before adding the nvmem device
nvmem: u-boot-env:: Replace zero-length array with DECLARE_FLEX_ARRAY() helper
nvmem: sec-qfprom: Add Qualcomm secure QFPROM support
dt-bindings: nvmem: sec-qfprom: Add bindings for secure qfprom
dt-bindings: nvmem: Add compatible for QCM2290
nvmem: Kconfig: Fix typo "drive" -> "driver"
nvmem: Explicitly include correct DT includes
nvmem: add new NXP QorIQ eFuse driver
dt-bindings: nvmem: Add t1023-sfp efuse support
dt-bindings: nvmem: qfprom: Add compatible for MSM8226
nvmem: uniphier: Use devm_platform_get_and_ioremap_resource()
nvmem: qfprom: do some cleanup
nvmem: stm32-romem: Use devm_platform_get_and_ioremap_resource()
nvmem: rockchip-efuse: Use devm_platform_get_and_ioremap_resource()
nvmem: meson-mx-efuse: Convert to devm_platform_ioremap_resource()
nvmem: lpc18xx_otp: Convert to devm_platform_ioremap_resource()
nvmem: brcm_nvram: Use devm_platform_get_and_ioremap_resource()
...
Diffstat (limited to 'drivers/firmware/stratix10-rsu.c')
-rw-r--r-- | drivers/firmware/stratix10-rsu.c | 100 |
1 files changed, 99 insertions, 1 deletions
diff --git a/drivers/firmware/stratix10-rsu.c b/drivers/firmware/stratix10-rsu.c index ab3074705380..4f7a7abada48 100644 --- a/drivers/firmware/stratix10-rsu.c +++ b/drivers/firmware/stratix10-rsu.c @@ -33,6 +33,10 @@ #define INVALID_RETRY_COUNTER 0xFF #define INVALID_DCMF_VERSION 0xFF #define INVALID_DCMF_STATUS 0xFFFFFFFF +#define INVALID_SPT_ADDRESS 0x0 + +#define RSU_GET_SPT_CMD 0x5A +#define RSU_GET_SPT_RESP_LEN (4 * sizeof(unsigned int)) typedef void (*rsu_callback)(struct stratix10_svc_client *client, struct stratix10_svc_cb_data *data); @@ -58,6 +62,9 @@ typedef void (*rsu_callback)(struct stratix10_svc_client *client, * @dcmf_status.dcmf3: dcmf3 status * @retry_counter: the current image's retry counter * @max_retry: the preset max retry value + * @spt0_address: address of spt0 + * @spt1_address: address of spt1 + * @get_spt_response_buf: response from sdm for get_spt command */ struct stratix10_rsu_priv { struct stratix10_svc_chan *chan; @@ -89,6 +96,11 @@ struct stratix10_rsu_priv { unsigned int retry_counter; unsigned int max_retry; + + unsigned long spt0_address; + unsigned long spt1_address; + + unsigned int *get_spt_response_buf; }; /** @@ -258,6 +270,36 @@ static void rsu_dcmf_status_callback(struct stratix10_svc_client *client, complete(&priv->completion); } +static void rsu_get_spt_callback(struct stratix10_svc_client *client, + struct stratix10_svc_cb_data *data) +{ + struct stratix10_rsu_priv *priv = client->priv; + unsigned long *mbox_err = (unsigned long *)data->kaddr1; + unsigned long *resp_len = (unsigned long *)data->kaddr2; + + if (data->status != BIT(SVC_STATUS_OK) || (*mbox_err) || + (*resp_len != RSU_GET_SPT_RESP_LEN)) + goto error; + + priv->spt0_address = priv->get_spt_response_buf[0]; + priv->spt0_address <<= 32; + priv->spt0_address |= priv->get_spt_response_buf[1]; + + priv->spt1_address = priv->get_spt_response_buf[2]; + priv->spt1_address <<= 32; + priv->spt1_address |= priv->get_spt_response_buf[3]; + + goto complete; + +error: + dev_err(client->dev, "failed to get SPTs\n"); + +complete: + stratix10_svc_free_memory(priv->chan, priv->get_spt_response_buf); + priv->get_spt_response_buf = NULL; + complete(&priv->completion); +} + /** * rsu_send_msg() - send a message to Intel service layer * @priv: pointer to rsu private data @@ -287,6 +329,14 @@ static int rsu_send_msg(struct stratix10_rsu_priv *priv, if (arg) msg.arg[0] = arg; + if (command == COMMAND_MBOX_SEND_CMD) { + msg.arg[1] = 0; + msg.payload = NULL; + msg.payload_length = 0; + msg.payload_output = priv->get_spt_response_buf; + msg.payload_length_output = RSU_GET_SPT_RESP_LEN; + } + ret = stratix10_svc_send(priv->chan, &msg); if (ret < 0) goto status_done; @@ -571,6 +621,34 @@ static ssize_t notify_store(struct device *dev, return count; } +static ssize_t spt0_address_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct stratix10_rsu_priv *priv = dev_get_drvdata(dev); + + if (!priv) + return -ENODEV; + + if (priv->spt0_address == INVALID_SPT_ADDRESS) + return -EIO; + + return scnprintf(buf, PAGE_SIZE, "0x%08lx\n", priv->spt0_address); +} + +static ssize_t spt1_address_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct stratix10_rsu_priv *priv = dev_get_drvdata(dev); + + if (!priv) + return -ENODEV; + + if (priv->spt1_address == INVALID_SPT_ADDRESS) + return -EIO; + + return scnprintf(buf, PAGE_SIZE, "0x%08lx\n", priv->spt1_address); +} + static DEVICE_ATTR_RO(current_image); static DEVICE_ATTR_RO(fail_image); static DEVICE_ATTR_RO(state); @@ -589,6 +667,8 @@ static DEVICE_ATTR_RO(dcmf2_status); static DEVICE_ATTR_RO(dcmf3_status); static DEVICE_ATTR_WO(reboot_image); static DEVICE_ATTR_WO(notify); +static DEVICE_ATTR_RO(spt0_address); +static DEVICE_ATTR_RO(spt1_address); static struct attribute *rsu_attrs[] = { &dev_attr_current_image.attr, @@ -609,6 +689,8 @@ static struct attribute *rsu_attrs[] = { &dev_attr_dcmf3_status.attr, &dev_attr_reboot_image.attr, &dev_attr_notify.attr, + &dev_attr_spt0_address.attr, + &dev_attr_spt1_address.attr, NULL }; @@ -638,11 +720,13 @@ static int stratix10_rsu_probe(struct platform_device *pdev) priv->dcmf_version.dcmf1 = INVALID_DCMF_VERSION; priv->dcmf_version.dcmf2 = INVALID_DCMF_VERSION; priv->dcmf_version.dcmf3 = INVALID_DCMF_VERSION; - priv->max_retry = INVALID_RETRY_COUNTER; priv->dcmf_status.dcmf0 = INVALID_DCMF_STATUS; priv->dcmf_status.dcmf1 = INVALID_DCMF_STATUS; priv->dcmf_status.dcmf2 = INVALID_DCMF_STATUS; priv->dcmf_status.dcmf3 = INVALID_DCMF_STATUS; + priv->max_retry = INVALID_RETRY_COUNTER; + priv->spt0_address = INVALID_SPT_ADDRESS; + priv->spt1_address = INVALID_SPT_ADDRESS; mutex_init(&priv->lock); priv->chan = stratix10_svc_request_channel_byname(&priv->client, @@ -692,6 +776,20 @@ static int stratix10_rsu_probe(struct platform_device *pdev) stratix10_svc_free_channel(priv->chan); } + priv->get_spt_response_buf = + stratix10_svc_allocate_memory(priv->chan, RSU_GET_SPT_RESP_LEN); + + if (IS_ERR(priv->get_spt_response_buf)) { + dev_err(dev, "failed to allocate get spt buffer\n"); + } else { + ret = rsu_send_msg(priv, COMMAND_MBOX_SEND_CMD, + RSU_GET_SPT_CMD, rsu_get_spt_callback); + if (ret) { + dev_err(dev, "Error, getting SPT table %i\n", ret); + stratix10_svc_free_channel(priv->chan); + } + } + return ret; } |