diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2026-06-22 12:20:21 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2026-06-22 12:20:21 -0700 |
| commit | 0000d9ccbcfa90411c88f70850501723389312b9 (patch) | |
| tree | d68ce425419c158d3a89cc04ba068057187997fe /drivers/firmware | |
| parent | 364f4a55c661641c02c86a849f0608d8fc3c0006 (diff) | |
| parent | b232fc005aec5fa5346d970f8986b8f0046f328b (diff) | |
| download | linux-next-0000d9ccbcfa90411c88f70850501723389312b9.tar.gz linux-next-0000d9ccbcfa90411c88f70850501723389312b9.zip | |
Merge tag 'char-misc-7.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc
Pull misc driver updates from Greg KH:
"Here is the big set of char, misc, iio, fpga, and other small driver
subsystems changes for 7.2-rc1.
Lots of little stuff in here, the majority being of course the IIO
driver updates, as a list they are:
- IIO driver updates and additions
- GPIB driver bugfixes and cleanups
- Android binder driver updates (rust and C version)
- counter driver updates
- MHI driver updates
- mei driver updates
- w1 driver updates
- interconnect driver updates
- Comedi driver fixes and updates
- some obsolete char drivers removed (applicom and dtlk)
- hwtracing driver updates
- other tiny driver updates
All of these have been in linux-next for a while with no reported
issues"
* tag 'char-misc-7.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: (406 commits)
w1: ds2482: Use named initializers for arrays of i2c_device_data
firmware: stratix10-svc: Add support to query Arm Trusted Firmware (ATF) version
firmware: stratix10-rsu: avoid blocking reboot_image sysfs when busy
coresight: ultrasoc-smb: Fix OOB write in smb_sync_perf_buffer()
iio: adc: nxp-sar-adc: harden buffer ISR against per-channel read failure
iio: chemical: scd30: Replace manual locking with RAII locking
iio: light: tsl2591: remove unneeded tsl2591_compatible_als_persist_cycle()
iio: dac: ad5686: create bus ops struct
iio: dac: ad5686: cleanup doc header of local structs
iio: dac: ad5686: add control_sync() for single-channel devices
iio: dac: ad5686: add helpers to handle powerdown masks
iio: dac: ad5686: add of_match table to the spi driver
iio: dac: ad5686: drop enum id
iio: dac: ad5686: remove redundant register definition
iio: dac: ad5686: refactor include headers
iio: adc: ad4080: fix AD4880 chip ID
iio: light: veml3328: add support for new device
dt-bindings: iio: light: veml6030: add veml3328
fpga: microchip-spi: fix zero header_size OOB read in mpf_ops_parse_header()
fpga: dfl-afu: validate DMA mapping length in afu_dma_map_region()
...
Diffstat (limited to 'drivers/firmware')
| -rw-r--r-- | drivers/firmware/stratix10-rsu.c | 85 | ||||
| -rw-r--r-- | drivers/firmware/stratix10-svc.c | 98 |
2 files changed, 124 insertions, 59 deletions
diff --git a/drivers/firmware/stratix10-rsu.c b/drivers/firmware/stratix10-rsu.c index 2a7a0f774389..daddb5224794 100644 --- a/drivers/firmware/stratix10-rsu.c +++ b/drivers/firmware/stratix10-rsu.c @@ -244,27 +244,26 @@ static void rsu_async_get_spt_table_callback(struct device *dev, } /** - * rsu_send_msg() - send a message to Intel service layer + * __rsu_send_msg_locked() - send a message to Intel service layer * @priv: pointer to rsu private data * @command: RSU status or update command * @arg: the request argument, the bitstream address or notify status * @callback: function pointer for the callback (status or update) * - * Start an Intel service layer transaction to perform the SMC call that - * is necessary to get RSU boot log or set the address of bitstream to - * boot after reboot. + * Perform the actual SMC transaction. The caller must hold @priv->lock. * - * Returns 0 on success or -ETIMEDOUT on error. + * Returns 0 on success or a negative errno on failure. */ -static int rsu_send_msg(struct stratix10_rsu_priv *priv, - enum stratix10_svc_command_code command, - unsigned long arg, - rsu_callback callback) +static int __rsu_send_msg_locked(struct stratix10_rsu_priv *priv, + enum stratix10_svc_command_code command, + unsigned long arg, + rsu_callback callback) { struct stratix10_svc_client_msg msg; int ret; - mutex_lock(&priv->lock); + lockdep_assert_held(&priv->lock); + reinit_completion(&priv->completion); priv->client.receive_cb = callback; @@ -293,6 +292,59 @@ static int rsu_send_msg(struct stratix10_rsu_priv *priv, status_done: stratix10_svc_done(priv->chan); + return ret; +} + +/** + * rsu_send_msg() - send a message to Intel service layer + * @priv: pointer to rsu private data + * @command: RSU status or update command + * @arg: the request argument, the bitstream address or notify status + * @callback: function pointer for the callback (status or update) + * + * Start an Intel service layer transaction to perform the SMC call that + * is necessary to get RSU boot log or set the address of bitstream to + * boot after reboot. This call will block until the RSU lock can be + * acquired. + * + * Returns 0 on success or a negative errno on failure. + */ +static int rsu_send_msg(struct stratix10_rsu_priv *priv, + enum stratix10_svc_command_code command, + unsigned long arg, + rsu_callback callback) +{ + int ret; + + mutex_lock(&priv->lock); + ret = __rsu_send_msg_locked(priv, command, arg, callback); + mutex_unlock(&priv->lock); + return ret; +} + +/** + * rsu_try_send_msg() - non-blocking variant of rsu_send_msg() + * @priv: pointer to rsu private data + * @command: RSU status or update command + * @arg: the request argument, the bitstream address or notify status + * @callback: function pointer for the callback (status or update) + * + * Same as rsu_send_msg() but returns -EBUSY immediately when another + * RSU operation is already in flight, instead of waiting for the lock. + * + * Returns 0 on success, -EBUSY if the RSU is busy, or another negative + * errno on failure. + */ +static int rsu_try_send_msg(struct stratix10_rsu_priv *priv, + enum stratix10_svc_command_code command, + unsigned long arg, + rsu_callback callback) +{ + int ret; + + if (!mutex_trylock(&priv->lock)) + return -EBUSY; + ret = __rsu_send_msg_locked(priv, command, arg, callback); mutex_unlock(&priv->lock); return ret; } @@ -595,8 +647,17 @@ static ssize_t reboot_image_store(struct device *dev, if (ret) return ret; - ret = rsu_send_msg(priv, COMMAND_RSU_UPDATE, - address, rsu_command_callback); + /* + * Use the non-blocking variant so a write to this sysfs attribute + * does not stall the caller while another RSU operation is in + * flight. Userspace can retry on -EBUSY. + */ + ret = rsu_try_send_msg(priv, COMMAND_RSU_UPDATE, + address, rsu_command_callback); + if (ret == -EBUSY) { + dev_dbg(dev, "RSU busy, reboot_image write rejected\n"); + return ret; + } if (ret) { dev_err(dev, "Error, RSU update returned %i\n", ret); return ret; diff --git a/drivers/firmware/stratix10-svc.c b/drivers/firmware/stratix10-svc.c index 39eb78f5905b..c24ca5823078 100644 --- a/drivers/firmware/stratix10-svc.c +++ b/drivers/firmware/stratix10-svc.c @@ -243,9 +243,33 @@ struct stratix10_async_ctrl { }; /** + * struct stratix10_svc_chan - service communication channel + * @ctrl: pointer to service controller which is the provider of this channel + * @scl: pointer to service client which owns the channel + * @name: service client name associated with the channel + * @task: pointer to the thread task which handles SMC or HVC call + * @svc_fifo: a queue for storing service message data (separate fifo for every channel) + * @svc_fifo_lock: protect access to service message data queue (locking pending fifo) + * @lock: protect access to the channel + * @async_chan: reference to asynchronous channel object for this channel + * + * This struct is used by service client to communicate with service layer. + * Each service client has its own channel created by service controller. + */ +struct stratix10_svc_chan { + struct stratix10_svc_controller *ctrl; + struct stratix10_svc_client *scl; + char *name; + struct task_struct *task; + struct kfifo svc_fifo; + spinlock_t svc_fifo_lock; + spinlock_t lock; + struct stratix10_async_chan *async_chan; +}; + +/** * struct stratix10_svc_controller - service controller * @dev: device - * @chans: array of service channels * @num_chans: number of channels in 'chans' array * @num_active_client: number of active service client * @node: list management @@ -255,13 +279,13 @@ struct stratix10_async_ctrl { * @svc: manages the list of client svc drivers * @sdm_lock: only allows a single command single response to SDM * @actrl: async control structure + * @chans: array of service channels * * This struct is used to create communication channels for service clients, to * handle secure monitor or hypervisor call. */ struct stratix10_svc_controller { struct device *dev; - struct stratix10_svc_chan *chans; int num_chans; int num_active_client; struct list_head node; @@ -271,31 +295,7 @@ struct stratix10_svc_controller { struct stratix10_svc *svc; struct mutex sdm_lock; struct stratix10_async_ctrl actrl; -}; - -/** - * struct stratix10_svc_chan - service communication channel - * @ctrl: pointer to service controller which is the provider of this channel - * @scl: pointer to service client which owns the channel - * @name: service client name associated with the channel - * @task: pointer to the thread task which handles SMC or HVC call - * @svc_fifo: a queue for storing service message data (separate fifo for every channel) - * @svc_fifo_lock: protect access to service message data queue (locking pending fifo) - * @lock: protect access to the channel - * @async_chan: reference to asynchronous channel object for this channel - * - * This struct is used by service client to communicate with service layer. - * Each service client has its own channel created by service controller. - */ -struct stratix10_svc_chan { - struct stratix10_svc_controller *ctrl; - struct stratix10_svc_client *scl; - char *name; - struct task_struct *task; - struct kfifo svc_fifo; - spinlock_t svc_fifo_lock; - spinlock_t lock; - struct stratix10_async_chan *async_chan; + struct stratix10_svc_chan chans[] __counted_by(num_chans); }; static LIST_HEAD(svc_ctrl); @@ -465,6 +465,7 @@ static void svc_thread_recv_status_ok(struct stratix10_svc_data *p_data, case COMMAND_FCS_SEND_CERTIFICATE: case COMMAND_FCS_DATA_ENCRYPTION: case COMMAND_FCS_DATA_DECRYPTION: + case COMMAND_FCS_GET_PROVISION_DATA: cb_data->status = BIT(SVC_STATUS_OK); break; case COMMAND_RECONFIG_DATA_SUBMIT: @@ -487,13 +488,18 @@ static void svc_thread_recv_status_ok(struct stratix10_svc_data *p_data, cb_data->kaddr1 = &res.a1; cb_data->kaddr2 = &res.a2; break; + case COMMAND_SMC_ATF_BUILD_VER: + cb_data->status = BIT(SVC_STATUS_OK); + cb_data->kaddr1 = &res.a1; + cb_data->kaddr2 = &res.a2; + cb_data->kaddr3 = &res.a3; + break; case COMMAND_RSU_DCMF_VERSION: cb_data->status = BIT(SVC_STATUS_OK); cb_data->kaddr1 = &res.a1; cb_data->kaddr2 = &res.a2; break; case COMMAND_FCS_RANDOM_NUMBER_GEN: - case COMMAND_FCS_GET_PROVISION_DATA: case COMMAND_POLL_SERVICE_STATUS: cb_data->status = BIT(SVC_STATUS_OK); cb_data->kaddr1 = &res.a1; @@ -676,7 +682,7 @@ static int svc_normal_to_secure_thread(void *data) break; case COMMAND_FCS_GET_PROVISION_DATA: a0 = INTEL_SIP_SMC_FCS_GET_PROVISION_DATA; - a1 = (unsigned long)pdata->paddr; + a1 = 0; a2 = 0; break; /* for HWMON */ @@ -706,6 +712,12 @@ static int svc_normal_to_secure_thread(void *data) a1 = 0; a2 = 0; break; + case COMMAND_SMC_ATF_BUILD_VER: + a0 = INTEL_SIP_SMC_ATF_BUILD_VER; + a1 = 0; + a2 = 0; + a3 = 0; + break; case COMMAND_MBOX_SEND_CMD: a0 = INTEL_SIP_SMC_MBOX_SEND_CMD; a1 = pdata->arg[0]; @@ -1910,7 +1922,6 @@ static int stratix10_svc_drv_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct stratix10_svc_controller *controller; - struct stratix10_svc_chan *chans; struct gen_pool *genpool; struct stratix10_svc_sh_memory *sh_memory; struct stratix10_svc *svc = NULL; @@ -1938,23 +1949,16 @@ static int stratix10_svc_drv_probe(struct platform_device *pdev) return PTR_ERR(genpool); /* allocate service controller and supporting channel */ - controller = devm_kzalloc(dev, sizeof(*controller), GFP_KERNEL); + controller = devm_kzalloc(dev, struct_size(controller, chans, SVC_NUM_CHANNEL), + GFP_KERNEL); if (!controller) { ret = -ENOMEM; goto err_destroy_pool; } - chans = devm_kmalloc_array(dev, SVC_NUM_CHANNEL, - sizeof(*chans), GFP_KERNEL | __GFP_ZERO); - if (!chans) { - ret = -ENOMEM; - goto err_destroy_pool; - } - - controller->dev = dev; controller->num_chans = SVC_NUM_CHANNEL; + controller->dev = dev; controller->num_active_client = 0; - controller->chans = chans; controller->genpool = genpool; controller->invoke_fn = invoke_fn; INIT_LIST_HEAD(&controller->node); @@ -1975,16 +1979,16 @@ static int stratix10_svc_drv_probe(struct platform_device *pdev) mutex_init(&controller->sdm_lock); for (i = 0; i < SVC_NUM_CHANNEL; i++) { - chans[i].scl = NULL; - chans[i].ctrl = controller; - chans[i].name = (char *)chan_names[i]; - spin_lock_init(&chans[i].lock); - ret = kfifo_alloc(&chans[i].svc_fifo, fifo_size, GFP_KERNEL); + controller->chans[i].scl = NULL; + controller->chans[i].ctrl = controller; + controller->chans[i].name = (char *)chan_names[i]; + spin_lock_init(&controller->chans[i].lock); + ret = kfifo_alloc(&controller->chans[i].svc_fifo, fifo_size, GFP_KERNEL); if (ret) { dev_err(dev, "failed to allocate FIFO %d\n", i); goto err_free_fifos; } - spin_lock_init(&chans[i].svc_fifo_lock); + spin_lock_init(&controller->chans[i].svc_fifo_lock); } list_add_tail(&controller->node, &svc_ctrl); @@ -2028,7 +2032,7 @@ err_free_fifos: list_del(&controller->node); /* free only the FIFOs that were successfully allocated */ while (i--) - kfifo_free(&chans[i].svc_fifo); + kfifo_free(&controller->chans[i].svc_fifo); stratix10_svc_async_exit(controller); err_destroy_pool: gen_pool_destroy(genpool); |
