Unverified Commit 720d813b authored by Arnd Bergmann's avatar Arnd Bergmann
Browse files

Merge tag 'scmi-updates-7.1' of...

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: default avatarArnd Bergmann <arnd@arndb.de>
parents a0ac82cb 0a7ec808
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -146,6 +146,13 @@ properties:
      this platform. If set, the value should be non-zero.
    minimum: 1

  arm,no-completion-irq:
    type: boolean
    description:
      This optional property is intended for hardware that does not generate
      completion interrupts and can be used to unconditionally enable forced
      polling mode of operation.

  arm,smc-id:
    $ref: /schemas/types.yaml#/definitions/uint32
    description:
@@ -379,6 +386,9 @@ then:
    - shmem

else:
  properties:
    arm,no-completion-irq: false

  if:
    properties:
      compatible:
+2 −2
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@

#define pr_fmt(fmt) "SCMI Notifications BASE - " fmt

#include <linux/math.h>
#include <linux/module.h>
#include <linux/scmi_protocol.h>

@@ -219,8 +220,7 @@ scmi_base_implementation_list_get(const struct scmi_protocol_handle *ph,
		}

		real_list_sz = t->rx.len - sizeof(u32);
		calc_list_sz = (1 + (loop_num_ret - 1) / sizeof(u32)) *
				sizeof(u32);
		calc_list_sz = round_up(loop_num_ret, sizeof(u32));
		if (calc_list_sz != real_list_sz) {
			dev_warn(dev,
				 "Malformed reply - real_sz:%zd  calc_sz:%u  (loop_num_ret:%d)\n",
+4 −0
Original line number Diff line number Diff line
@@ -235,6 +235,9 @@ struct scmi_transport_ops {
 *		      to have an execution latency lesser-equal to the threshold
 *		      should be considered for atomic mode operation: such
 *		      decision is finally left up to the SCMI drivers.
 * @no_completion_irq: Flag to indicate that this transport has no completion
 *		       interrupt and has to be polled. This is similar to the
 *		       force_polling below, except this is set via DT property.
 * @force_polling: Flag to force this whole transport to use SCMI core polling
 *		   mechanism instead of completion interrupts even if available.
 * @sync_cmds_completed_on_ret: Flag to indicate that the transport assures
@@ -254,6 +257,7 @@ struct scmi_desc {
	int max_msg;
	int max_msg_size;
	unsigned int atomic_threshold;
	bool no_completion_irq;
	const bool force_polling;
	const bool sync_cmds_completed_on_ret;
	const bool atomic_enabled;
+4 −0
Original line number Diff line number Diff line
@@ -2735,6 +2735,7 @@ static int scmi_chan_setup(struct scmi_info *info, struct device_node *of_node,
	cinfo->is_p2a = !tx;
	cinfo->rx_timeout_ms = info->desc->max_rx_timeout_ms;
	cinfo->max_msg_size = info->desc->max_msg_size;
	cinfo->no_completion_irq = info->desc->no_completion_irq;

	/* Create a unique name for this transport device */
	snprintf(name, 32, "__scmi_transport_device_%s_%02X",
@@ -3150,6 +3151,9 @@ static const struct scmi_desc *scmi_transport_setup(struct device *dev)
	if (ret && ret != -EINVAL)
		dev_err(dev, "Malformed arm,max-msg DT property.\n");

	trans->desc.no_completion_irq = of_property_read_bool(dev->of_node,
							      "arm,no-completion-irq");

	dev_info(dev,
		 "SCMI max-rx-timeout: %dms / max-msg-size: %dbytes / max-msg: %d\n",
		 trans->desc.max_rx_timeout_ms, trans->desc.max_msg_size,
+4 −4
Original line number Diff line number Diff line
@@ -20,10 +20,10 @@
 * named as _qn.
 */
#define SCMI_QUIRK(_qn, _blk)						\
	do {								\
	({								\
		if (static_branch_unlikely(&(scmi_quirk_ ## _qn)))	\
			(_blk);						\
	} while (0)
	})

void scmi_quirks_initialize(void);
void scmi_quirks_enable(struct device *dev, const char *vend,
@@ -34,10 +34,10 @@ void scmi_quirks_enable(struct device *dev, const char *vend,
#define DECLARE_SCMI_QUIRK(_qn)
/* Force quirks compilation even when SCMI Quirks are disabled */
#define SCMI_QUIRK(_qn, _blk)						\
	do {								\
	({								\
		if (0)							\
			(_blk);						\
	} while (0)
	})

static inline void scmi_quirks_initialize(void) { }
static inline void scmi_quirks_enable(struct device *dev, const char *vend,