Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'scmi-updates-7.1' of git://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux into soc/drivers

Arm SCMI updates for v7.1

This batch mainly improves SCMI robustness on systems where the SCP does
not generate completion interrupts, and includes two small follow-up
cleanups in the SCMI core.

The main functional change adds support for the new DT property
'arm,no-completion-irq'. When present for mailbox/shared-memory based
SCMI implementations, the driver forces SCMI operations into polling
mode so affected platforms can continue to operate even with broken
firmware interrupt behavior.

In addition, it
- replaces open-coded size rounding in the base protocol path with
round_up() for clarity, with no functional change
- updates the SCMI quirk snippet macro implementation so quirk handlers
can use break and continue directly when invoked inside loop contexts

* tag 'scmi-updates-7.1' of git://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux:
firmware: arm_scmi: Support loop control in quirk code snippets
firmware: arm_scmi: Use round_up() for base protocol list size calculation
firmware: arm_scmi: Implement arm,no-completion-irq property
dt-bindings: firmware: arm,scmi: Document arm,no-completion-irq property

Signed-off-by: Arnd Bergmann <arnd@arndb.de>

+24 -6
+10
Documentation/devicetree/bindings/firmware/arm,scmi.yaml
··· 146 146 this platform. If set, the value should be non-zero. 147 147 minimum: 1 148 148 149 + arm,no-completion-irq: 150 + type: boolean 151 + description: 152 + This optional property is intended for hardware that does not generate 153 + completion interrupts and can be used to unconditionally enable forced 154 + polling mode of operation. 155 + 149 156 arm,smc-id: 150 157 $ref: /schemas/types.yaml#/definitions/uint32 151 158 description: ··· 386 379 - shmem 387 380 388 381 else: 382 + properties: 383 + arm,no-completion-irq: false 384 + 389 385 if: 390 386 properties: 391 387 compatible:
+2 -2
drivers/firmware/arm_scmi/base.c
··· 7 7 8 8 #define pr_fmt(fmt) "SCMI Notifications BASE - " fmt 9 9 10 + #include <linux/math.h> 10 11 #include <linux/module.h> 11 12 #include <linux/scmi_protocol.h> 12 13 ··· 220 219 } 221 220 222 221 real_list_sz = t->rx.len - sizeof(u32); 223 - calc_list_sz = (1 + (loop_num_ret - 1) / sizeof(u32)) * 224 - sizeof(u32); 222 + calc_list_sz = round_up(loop_num_ret, sizeof(u32)); 225 223 if (calc_list_sz != real_list_sz) { 226 224 dev_warn(dev, 227 225 "Malformed reply - real_sz:%zd calc_sz:%u (loop_num_ret:%d)\n",
+4
drivers/firmware/arm_scmi/common.h
··· 235 235 * to have an execution latency lesser-equal to the threshold 236 236 * should be considered for atomic mode operation: such 237 237 * decision is finally left up to the SCMI drivers. 238 + * @no_completion_irq: Flag to indicate that this transport has no completion 239 + * interrupt and has to be polled. This is similar to the 240 + * force_polling below, except this is set via DT property. 238 241 * @force_polling: Flag to force this whole transport to use SCMI core polling 239 242 * mechanism instead of completion interrupts even if available. 240 243 * @sync_cmds_completed_on_ret: Flag to indicate that the transport assures ··· 257 254 int max_msg; 258 255 int max_msg_size; 259 256 unsigned int atomic_threshold; 257 + bool no_completion_irq; 260 258 const bool force_polling; 261 259 const bool sync_cmds_completed_on_ret; 262 260 const bool atomic_enabled;
+4
drivers/firmware/arm_scmi/driver.c
··· 2735 2735 cinfo->is_p2a = !tx; 2736 2736 cinfo->rx_timeout_ms = info->desc->max_rx_timeout_ms; 2737 2737 cinfo->max_msg_size = info->desc->max_msg_size; 2738 + cinfo->no_completion_irq = info->desc->no_completion_irq; 2738 2739 2739 2740 /* Create a unique name for this transport device */ 2740 2741 snprintf(name, 32, "__scmi_transport_device_%s_%02X", ··· 3150 3149 &trans->desc.max_msg); 3151 3150 if (ret && ret != -EINVAL) 3152 3151 dev_err(dev, "Malformed arm,max-msg DT property.\n"); 3152 + 3153 + trans->desc.no_completion_irq = of_property_read_bool(dev->of_node, 3154 + "arm,no-completion-irq"); 3153 3155 3154 3156 dev_info(dev, 3155 3157 "SCMI max-rx-timeout: %dms / max-msg-size: %dbytes / max-msg: %d\n",
+4 -4
drivers/firmware/arm_scmi/quirks.h
··· 20 20 * named as _qn. 21 21 */ 22 22 #define SCMI_QUIRK(_qn, _blk) \ 23 - do { \ 23 + ({ \ 24 24 if (static_branch_unlikely(&(scmi_quirk_ ## _qn))) \ 25 25 (_blk); \ 26 - } while (0) 26 + }) 27 27 28 28 void scmi_quirks_initialize(void); 29 29 void scmi_quirks_enable(struct device *dev, const char *vend, ··· 34 34 #define DECLARE_SCMI_QUIRK(_qn) 35 35 /* Force quirks compilation even when SCMI Quirks are disabled */ 36 36 #define SCMI_QUIRK(_qn, _blk) \ 37 - do { \ 37 + ({ \ 38 38 if (0) \ 39 39 (_blk); \ 40 - } while (0) 40 + }) 41 41 42 42 static inline void scmi_quirks_initialize(void) { } 43 43 static inline void scmi_quirks_enable(struct device *dev, const char *vend,