Commit f938b29d authored by Arnd Bergmann's avatar Arnd Bergmann

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

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

Arm SCMI updates for v6.3

The main addition is a unified userspace interface for SCMI irrespective
of the underlying transport and along with some changed to refactor the
SCMI stack probing sequence.

1. SCMI unified userspace interface

   This is to have a unified way of testing an SCMI platform firmware
   implementation for compliance, fuzzing etc., from the perspective of
   the non-secure OSPM irrespective of the underlying transport supporting
   SCMI. It is just for testing/development and not a feature intended fo
   use in production.

   Currently an SCMI Compliance Suite[1] can only work by injecting SCMI
   messages using the mailbox test driver only which makes it transport
   specific and can't be used with any other transport like virtio,
   smc/hvc, optee, etc. Also the shared memory can be transport specific
   and it is better to even abstract/hide those details while providing
   the userspace access. So in order to scale with any transport, we need
   a unified interface for the same.

   In order to achieve that, SCMI "raw mode support" is being added through
   debugfs which is more configurable as well. A userspace application
   can inject bare SCMI binary messages into the SCMI core stack; such
   messages will be routed by the SCMI regular kernel stack to the backend
   platform firmware using the configured transport transparently. This
   eliminates the to know about the specific underlying transport
   internals that will be taken care of by the SCMI core stack itself.
   Further no additional changes needed in the device tree like in the
   mailbox-test driver.

[1] https://gitlab.arm.com/tests/scmi-tests

2. Refactoring of the SCMI stack probing sequence

   On some platforms, SCMI transport can be provide by OPTEE/TEE which
   introduces certain dependency in the probe ordering. In order to address
   the same, the SCMI bus is split into its own module which continues to
   be initialized at subsys_initcall, while the SCMI core stack, including
   its various transport backends (like optee, mailbox, virtio, smc), is
   now moved into a separate module at module_init level.

   This allows the other possibly dependent subsystems to register and/or
   access SCMI bus well before the core SCMI stack and its dependent
   transport backends.

* tag 'scmi-updates-6.3' of git://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux: (31 commits)
  firmware: arm_scmi: Clarify raw per-channel ABI documentation
  firmware: arm_scmi: Add per-channel raw injection support
  firmware: arm_scmi: Add the raw mode co-existence support
  firmware: arm_scmi: Call raw mode hooks from the core stack
  firmware: arm_scmi: Reject SCMI drivers when configured in raw mode
  firmware: arm_scmi: Add debugfs ABI documentation for raw mode
  firmware: arm_scmi: Add core raw transmission support
  firmware: arm_scmi: Add debugfs ABI documentation for common entries
  firmware: arm_scmi: Populate a common SCMI debugfs root
  debugfs: Export debugfs_create_str symbol
  include: trace: Add platform and channel instance references
  firmware: arm_scmi: Add internal platform/channel identifiers
  firmware: arm_scmi: Move errors defs and code to common.h
  firmware: arm_scmi: Add xfer helpers to provide raw access
  firmware: arm_scmi: Add flags field to xfer
  firmware: arm_scmi: Refactor scmi_wait_for_message_response
  firmware: arm_scmi: Refactor polling helpers
  firmware: arm_scmi: Refactor xfer in-flight registration routines
  firmware: arm_scmi: Split bus and driver into distinct modules
  firmware: arm_scmi: Introduce a new lifecycle for protocol devices
  ...

Link: https://lore.kernel.org/r/20230120162152.1438456-1-sudeep.holla@arm.comSigned-off-by: default avatarArnd Bergmann <arnd@arndb.de>
parents faa4cd06 32a55bbd
What: /sys/kernel/debug/scmi/<n>/instance_name
Date: March 2023
KernelVersion: 6.3
Contact: cristian.marussi@arm.com
Description: The name of the underlying SCMI instance <n> described by
all the debugfs accessors rooted at /sys/kernel/debug/scmi/<n>,
expressed as the full name of the top DT SCMI node under which
this SCMI instance is rooted.
Users: Debugging, any userspace test suite
What: /sys/kernel/debug/scmi/<n>/atomic_threshold_us
Date: March 2023
KernelVersion: 6.3
Contact: cristian.marussi@arm.com
Description: An optional time value, expressed in microseconds, representing,
on this SCMI instance <n>, the threshold above which any SCMI
command, advertised to have an higher-than-threshold execution
latency, should not be considered for atomic mode of operation,
even if requested.
Users: Debugging, any userspace test suite
What: /sys/kernel/debug/scmi/<n>/transport/type
Date: March 2023
KernelVersion: 6.3
Contact: cristian.marussi@arm.com
Description: A string representing the type of transport configured for this
SCMI instance <n>.
Users: Debugging, any userspace test suite
What: /sys/kernel/debug/scmi/<n>/transport/is_atomic
Date: March 2023
KernelVersion: 6.3
Contact: cristian.marussi@arm.com
Description: A boolean stating if the transport configured on the underlying
SCMI instance <n> is capable of atomic mode of operation.
Users: Debugging, any userspace test suite
What: /sys/kernel/debug/scmi/<n>/transport/max_rx_timeout_ms
Date: March 2023
KernelVersion: 6.3
Contact: cristian.marussi@arm.com
Description: Timeout in milliseconds allowed for SCMI synchronous replies
for the currently configured SCMI transport for instance <n>.
Users: Debugging, any userspace test suite
What: /sys/kernel/debug/scmi/<n>/transport/max_msg_size
Date: March 2023
KernelVersion: 6.3
Contact: cristian.marussi@arm.com
Description: Max message size of allowed SCMI messages for the currently
configured SCMI transport for instance <n>.
Users: Debugging, any userspace test suite
What: /sys/kernel/debug/scmi/<n>/transport/tx_max_msg
Date: March 2023
KernelVersion: 6.3
Contact: cristian.marussi@arm.com
Description: Max number of concurrently allowed in-flight SCMI messages for
the currently configured SCMI transport for instance <n> on the
TX channels.
Users: Debugging, any userspace test suite
What: /sys/kernel/debug/scmi/<n>/transport/rx_max_msg
Date: March 2023
KernelVersion: 6.3
Contact: cristian.marussi@arm.com
Description: Max number of concurrently allowed in-flight SCMI messages for
the currently configured SCMI transport for instance <n> on the
RX channels.
Users: Debugging, any userspace test suite
What: /sys/kernel/debug/scmi/<n>/raw/message
Date: March 2023
KernelVersion: 6.3
Contact: cristian.marussi@arm.com
Description: SCMI Raw synchronous message injection/snooping facility; write
a complete SCMI synchronous command message (header included)
in little-endian binary format to have it sent to the configured
backend SCMI server for instance <n>.
Any subsequently received response can be read from this same
entry if it arrived within the configured timeout.
Each write to the entry causes one command request to be built
and sent while the replies are read back one message at time
(receiving an EOF at each message boundary).
Users: Debugging, any userspace test suite
What: /sys/kernel/debug/scmi/<n>/raw/message_async
Date: March 2023
KernelVersion: 6.3
Contact: cristian.marussi@arm.com
Description: SCMI Raw asynchronous message injection/snooping facility; write
a complete SCMI asynchronous command message (header included)
in little-endian binary format to have it sent to the configured
backend SCMI server for instance <n>.
Any subsequently received response can be read from this same
entry if it arrived within the configured timeout.
Any additional delayed response received afterwards can be read
from this same entry too if it arrived within the configured
timeout.
Each write to the entry causes one command request to be built
and sent while the replies are read back one message at time
(receiving an EOF at each message boundary).
Users: Debugging, any userspace test suite
What: /sys/kernel/debug/scmi/<n>/raw/errors
Date: March 2023
KernelVersion: 6.3
Contact: cristian.marussi@arm.com
Description: SCMI Raw message errors facility; any kind of timed-out or
generally unexpectedly received SCMI message, for instance <n>,
can be read from this entry.
Each read gives back one message at time (receiving an EOF at
each message boundary).
Users: Debugging, any userspace test suite
What: /sys/kernel/debug/scmi/<n>/raw/notification
Date: March 2023
KernelVersion: 6.3
Contact: cristian.marussi@arm.com
Description: SCMI Raw notification snooping facility; any notification
emitted by the backend SCMI server, for instance <n>, can be
read from this entry.
Each read gives back one message at time (receiving an EOF at
each message boundary).
Users: Debugging, any userspace test suite
What: /sys/kernel/debug/scmi/<n>/raw/reset
Date: March 2023
KernelVersion: 6.3
Contact: cristian.marussi@arm.com
Description: SCMI Raw stack reset facility; writing a value to this entry
causes the internal queues of any kind of received message,
still pending to be read out for instance <n>, to be immediately
flushed.
Can be used to reset and clean the SCMI Raw stack between to
different test-run.
Users: Debugging, any userspace test suite
What: /sys/kernel/debug/scmi/<n>/raw/channels/<m>/message
Date: March 2023
KernelVersion: 6.3
Contact: cristian.marussi@arm.com
Description: SCMI Raw synchronous message injection/snooping facility; write
a complete SCMI synchronous command message (header included)
in little-endian binary format to have it sent to the configured
backend SCMI server for instance <n> through the <m> transport
channel.
Any subsequently received response can be read from this same
entry if it arrived on channel <m> within the configured
timeout.
Each write to the entry causes one command request to be built
and sent while the replies are read back one message at time
(receiving an EOF at each message boundary).
Channel identifier <m> matches the SCMI protocol number which
has been associated with this transport channel in the DT
description, with base protocol number 0x10 being the default
channel for this instance.
Note that these per-channel entries rooted at <..>/channels
exist only if the transport is configured to have more than
one default channel.
Users: Debugging, any userspace test suite
What: /sys/kernel/debug/scmi/<n>/raw/channels/<m>/message_async
Date: March 2023
KernelVersion: 6.3
Contact: cristian.marussi@arm.com
Description: SCMI Raw asynchronous message injection/snooping facility; write
a complete SCMI asynchronous command message (header included)
in little-endian binary format to have it sent to the configured
backend SCMI server for instance <n> through the <m> transport
channel.
Any subsequently received response can be read from this same
entry if it arrived on channel <m> within the configured
timeout.
Any additional delayed response received afterwards can be read
from this same entry too if it arrived within the configured
timeout.
Each write to the entry causes one command request to be built
and sent while the replies are read back one message at time
(receiving an EOF at each message boundary).
Channel identifier <m> matches the SCMI protocol number which
has been associated with this transport channel in the DT
description, with base protocol number 0x10 being the default
channel for this instance.
Note that these per-channel entries rooted at <..>/channels
exist only if the transport is configured to have more than
one default channel.
Users: Debugging, any userspace test suite
......@@ -23,6 +23,38 @@ config ARM_SCMI_PROTOCOL
if ARM_SCMI_PROTOCOL
config ARM_SCMI_NEED_DEBUGFS
bool
help
This declares whether at least one SCMI facility is configured
which needs debugfs support. When selected causess the creation
of a common SCMI debugfs root directory.
config ARM_SCMI_RAW_MODE_SUPPORT
bool "Enable support for SCMI Raw transmission mode"
depends on DEBUG_FS
select ARM_SCMI_NEED_DEBUGFS
help
Enable support for SCMI Raw transmission mode.
If enabled allows the direct injection and snooping of SCMI bare
messages through a dedicated debugfs interface.
It is meant to be used by SCMI compliance/testing suites.
When enabled regular SCMI drivers interactions are inhibited in
order to avoid unexpected interactions with the SCMI Raw message
flow. If unsure say N.
config ARM_SCMI_RAW_MODE_SUPPORT_COEX
bool "Allow SCMI Raw mode coexistence with normal SCMI stack"
depends on ARM_SCMI_RAW_MODE_SUPPORT
help
Allow SCMI Raw transmission mode to coexist with normal SCMI stack.
This will allow regular SCMI drivers to register with the core and
operate normally, thing which could make an SCMI test suite using the
SCMI Raw mode support unreliable. If unsure, say N.
config ARM_SCMI_HAVE_TRANSPORT
bool
help
......
# SPDX-License-Identifier: GPL-2.0-only
scmi-bus-y = bus.o
scmi-core-objs := $(scmi-bus-y)
scmi-driver-y = driver.o notify.o
scmi-driver-$(CONFIG_ARM_SCMI_RAW_MODE_SUPPORT) += raw_mode.o
scmi-transport-$(CONFIG_ARM_SCMI_HAVE_SHMEM) = shmem.o
scmi-transport-$(CONFIG_ARM_SCMI_TRANSPORT_MAILBOX) += mailbox.o
scmi-transport-$(CONFIG_ARM_SCMI_TRANSPORT_SMC) += smc.o
......@@ -8,9 +11,11 @@ scmi-transport-$(CONFIG_ARM_SCMI_HAVE_MSG) += msg.o
scmi-transport-$(CONFIG_ARM_SCMI_TRANSPORT_VIRTIO) += virtio.o
scmi-transport-$(CONFIG_ARM_SCMI_TRANSPORT_OPTEE) += optee.o
scmi-protocols-y = base.o clock.o perf.o power.o reset.o sensors.o system.o voltage.o powercap.o
scmi-module-objs := $(scmi-bus-y) $(scmi-driver-y) $(scmi-protocols-y) \
$(scmi-transport-y)
scmi-module-objs := $(scmi-driver-y) $(scmi-protocols-y) $(scmi-transport-y)
obj-$(CONFIG_ARM_SCMI_PROTOCOL) += scmi-core.o
obj-$(CONFIG_ARM_SCMI_PROTOCOL) += scmi-module.o
obj-$(CONFIG_ARM_SCMI_POWER_DOMAIN) += scmi_pm_domain.o
obj-$(CONFIG_ARM_SCMI_POWER_CONTROL) += scmi_power_control.o
......
This diff is collapsed.
......@@ -27,6 +27,48 @@
#include "protocols.h"
#include "notify.h"
#define SCMI_MAX_CHANNELS 256
#define SCMI_MAX_RESPONSE_TIMEOUT (2 * MSEC_PER_SEC)
enum scmi_error_codes {
SCMI_SUCCESS = 0, /* Success */
SCMI_ERR_SUPPORT = -1, /* Not supported */
SCMI_ERR_PARAMS = -2, /* Invalid Parameters */
SCMI_ERR_ACCESS = -3, /* Invalid access/permission denied */
SCMI_ERR_ENTRY = -4, /* Not found */
SCMI_ERR_RANGE = -5, /* Value out of range */
SCMI_ERR_BUSY = -6, /* Device busy */
SCMI_ERR_COMMS = -7, /* Communication Error */
SCMI_ERR_GENERIC = -8, /* Generic Error */
SCMI_ERR_HARDWARE = -9, /* Hardware Error */
SCMI_ERR_PROTOCOL = -10,/* Protocol Error */
};
static const int scmi_linux_errmap[] = {
/* better than switch case as long as return value is continuous */
0, /* SCMI_SUCCESS */
-EOPNOTSUPP, /* SCMI_ERR_SUPPORT */
-EINVAL, /* SCMI_ERR_PARAM */
-EACCES, /* SCMI_ERR_ACCESS */
-ENOENT, /* SCMI_ERR_ENTRY */
-ERANGE, /* SCMI_ERR_RANGE */
-EBUSY, /* SCMI_ERR_BUSY */
-ECOMM, /* SCMI_ERR_COMMS */
-EIO, /* SCMI_ERR_GENERIC */
-EREMOTEIO, /* SCMI_ERR_HARDWARE */
-EPROTO, /* SCMI_ERR_PROTOCOL */
};
static inline int scmi_to_linux_errno(int errno)
{
int err_idx = -errno;
if (err_idx >= SCMI_SUCCESS && err_idx < ARRAY_SIZE(scmi_linux_errmap))
return scmi_linux_errmap[err_idx];
return -EIO;
}
#define MSG_ID_MASK GENMASK(7, 0)
#define MSG_XTRACT_ID(hdr) FIELD_GET(MSG_ID_MASK, (hdr))
#define MSG_TYPE_MASK GENMASK(9, 8)
......@@ -96,18 +138,19 @@ static inline void unpack_scmi_header(u32 msg_hdr, struct scmi_msg_hdr *hdr)
struct scmi_revision_info *
scmi_revision_area_get(const struct scmi_protocol_handle *ph);
int scmi_handle_put(const struct scmi_handle *handle);
void scmi_device_link_add(struct device *consumer, struct device *supplier);
struct scmi_handle *scmi_handle_get(struct device *dev);
void scmi_set_handle(struct scmi_device *scmi_dev);
void scmi_setup_protocol_implemented(const struct scmi_protocol_handle *ph,
u8 *prot_imp);
int __init scmi_bus_init(void);
void __exit scmi_bus_exit(void);
extern struct bus_type scmi_bus_type;
#define SCMI_BUS_NOTIFY_DEVICE_REQUEST 0
#define SCMI_BUS_NOTIFY_DEVICE_UNREQUEST 1
extern struct blocking_notifier_head scmi_requested_devices_nh;
const struct scmi_protocol *scmi_protocol_get(int protocol_id);
void scmi_protocol_put(int protocol_id);
struct scmi_device *scmi_device_create(struct device_node *np,
struct device *parent, int protocol,
const char *name);
void scmi_device_destroy(struct device *parent, int protocol, const char *name);
int scmi_protocol_acquire(const struct scmi_handle *handle, u8 protocol_id);
void scmi_protocol_release(const struct scmi_handle *handle, u8 protocol_id);
......@@ -116,6 +159,8 @@ void scmi_protocol_release(const struct scmi_handle *handle, u8 protocol_id);
/**
* struct scmi_chan_info - Structure representing a SCMI channel information
*
* @id: An identifier for this channel: this matches the protocol number
* used to initialize this channel
* @dev: Reference to device in the SCMI hierarchy corresponding to this
* channel
* @rx_timeout_ms: The configured RX timeout in milliseconds.
......@@ -127,6 +172,7 @@ void scmi_protocol_release(const struct scmi_handle *handle, u8 protocol_id);
* @transport_info: Transport layer related information
*/
struct scmi_chan_info {
int id;
struct device *dev;
unsigned int rx_timeout_ms;
struct scmi_handle *handle;
......@@ -153,7 +199,7 @@ struct scmi_chan_info {
*/
struct scmi_transport_ops {
int (*link_supplier)(struct device *dev);
bool (*chan_available)(struct device *dev, int idx);
bool (*chan_available)(struct device_node *of_node, int idx);
int (*chan_setup)(struct scmi_chan_info *cinfo, struct device *dev,
bool tx);
int (*chan_free)(int id, void *p, void *data);
......@@ -170,11 +216,6 @@ struct scmi_transport_ops {
bool (*poll_done)(struct scmi_chan_info *cinfo, struct scmi_xfer *xfer);
};
int scmi_protocol_device_request(const struct scmi_device_id *id_table);
void scmi_protocol_device_unrequest(const struct scmi_device_id *id_table);
struct scmi_device *scmi_child_dev_find(struct device *parent,
int prot_id, const char *name);
/**
* struct scmi_desc - Description of SoC integration
*
......@@ -215,6 +256,36 @@ struct scmi_desc {
const bool atomic_enabled;
};
static inline bool is_polling_required(struct scmi_chan_info *cinfo,
const struct scmi_desc *desc)
{
return cinfo->no_completion_irq || desc->force_polling;
}
static inline bool is_transport_polling_capable(const struct scmi_desc *desc)
{
return desc->ops->poll_done || desc->sync_cmds_completed_on_ret;
}
static inline bool is_polling_enabled(struct scmi_chan_info *cinfo,
const struct scmi_desc *desc)
{
return is_polling_required(cinfo, desc) &&
is_transport_polling_capable(desc);
}
void scmi_xfer_raw_put(const struct scmi_handle *handle,
struct scmi_xfer *xfer);
struct scmi_xfer *scmi_xfer_raw_get(const struct scmi_handle *handle);
struct scmi_chan_info *
scmi_xfer_raw_channel_get(const struct scmi_handle *handle, u8 protocol_id);
int scmi_xfer_raw_inflight_register(const struct scmi_handle *handle,
struct scmi_xfer *xfer);
int scmi_xfer_raw_wait_for_message_response(struct scmi_chan_info *cinfo,
struct scmi_xfer *xfer,
unsigned int timeout_ms);
#ifdef CONFIG_ARM_SCMI_TRANSPORT_MAILBOX
extern const struct scmi_desc scmi_mailbox_desc;
#endif
......@@ -229,7 +300,6 @@ extern const struct scmi_desc scmi_optee_desc;
#endif
void scmi_rx_callback(struct scmi_chan_info *cinfo, u32 msg_hdr, void *priv);
void scmi_free_channel(struct scmi_chan_info *cinfo, struct idr *idr, int id);
/* shmem related declarations */
struct scmi_shared_mem;
......
This diff is collapsed.
......@@ -46,9 +46,9 @@ static void rx_callback(struct mbox_client *cl, void *m)
scmi_rx_callback(smbox->cinfo, shmem_read_header(smbox->shmem), NULL);
}
static bool mailbox_chan_available(struct device *dev, int idx)
static bool mailbox_chan_available(struct device_node *of_node, int idx)
{
return !of_parse_phandle_with_args(dev->of_node, "mboxes",
return !of_parse_phandle_with_args(of_node, "mboxes",
"#mbox-cells", idx, NULL);
}
......@@ -120,8 +120,6 @@ static int mailbox_chan_free(int id, void *p, void *data)
smbox->cinfo = NULL;
}
scmi_free_channel(cinfo, data, id);
return 0;
}
......
......@@ -328,11 +328,11 @@ static int scmi_optee_link_supplier(struct device *dev)
return 0;
}
static bool scmi_optee_chan_available(struct device *dev, int idx)
static bool scmi_optee_chan_available(struct device_node *of_node, int idx)
{
u32 channel_id;
return !of_property_read_u32_index(dev->of_node, "linaro,optee-channel-id",
return !of_property_read_u32_index(of_node, "linaro,optee-channel-id",
idx, &channel_id);
}
......@@ -481,8 +481,6 @@ static int scmi_optee_chan_free(int id, void *p, void *data)
cinfo->transport_info = NULL;
channel->cinfo = NULL;
scmi_free_channel(cinfo, data, id);
return 0;
}
......
......@@ -115,6 +115,7 @@ struct scmi_msg_hdr {
* - SCMI_XFER_SENT_OK -> SCMI_XFER_RESP_OK [ -> SCMI_XFER_DRESP_OK ]
* - SCMI_XFER_SENT_OK -> SCMI_XFER_DRESP_OK
* (Missing synchronous response is assumed OK and ignored)
* @flags: Optional flags associated to this xfer.
* @lock: A spinlock to protect state and busy fields.
* @priv: A pointer for transport private usage.
*/
......@@ -135,6 +136,12 @@ struct scmi_xfer {
#define SCMI_XFER_RESP_OK 1
#define SCMI_XFER_DRESP_OK 2
int state;
#define SCMI_XFER_FLAG_IS_RAW BIT(0)
#define SCMI_XFER_IS_RAW(x) ((x)->flags & SCMI_XFER_FLAG_IS_RAW)
#define SCMI_XFER_FLAG_CHAN_SET BIT(1)
#define SCMI_XFER_IS_CHAN_SET(x) \
((x)->flags & SCMI_XFER_FLAG_CHAN_SET)
int flags;
/* A lock to protect state and busy fields */
spinlock_t lock;
void *priv;
......
This diff is collapsed.
/* SPDX-License-Identifier: GPL-2.0 */
/*
* System Control and Management Interface (SCMI) Message Protocol
* Raw mode support header.
*
* Copyright (C) 2022 ARM Ltd.
*/
#ifndef _SCMI_RAW_MODE_H
#define _SCMI_RAW_MODE_H
#include "common.h"
enum {
SCMI_RAW_REPLY_QUEUE,
SCMI_RAW_NOTIF_QUEUE,
SCMI_RAW_ERRS_QUEUE,
SCMI_RAW_MAX_QUEUE
};
void *scmi_raw_mode_init(const struct scmi_handle *handle,
struct dentry *top_dentry, int instance_id,
u8 *channels, int num_chans,
const struct scmi_desc *desc, int tx_max_msg);
void scmi_raw_mode_cleanup(void *raw);
void scmi_raw_message_report(void *raw, struct scmi_xfer *xfer,
unsigned int idx, unsigned int chan_id);
void scmi_raw_error_report(void *raw, struct scmi_chan_info *cinfo,
u32 msg_hdr, void *priv);
#endif /* _SCMI_RAW_MODE_H */
......@@ -81,10 +81,11 @@ u32 shmem_read_header(struct scmi_shared_mem __iomem *shmem)
void shmem_fetch_response(struct scmi_shared_mem __iomem *shmem,
struct scmi_xfer *xfer)
{
size_t len = ioread32(&shmem->length);
xfer->hdr.status = ioread32(shmem->msg_payload);
/* Skip the length of header and status in shmem area i.e 8 bytes */
xfer->rx.len = min_t(size_t, xfer->rx.len,
ioread32(&shmem->length) - 8);
xfer->rx.len = min_t(size_t, xfer->rx.len, len > 8 ? len - 8 : 0);
/* Take a copy to the rx buffer.. */
memcpy_fromio(xfer->rx.buf, shmem->msg_payload + 4, xfer->rx.len);
......@@ -93,8 +94,10 @@ void shmem_fetch_response(struct scmi_shared_mem __iomem *shmem,
void shmem_fetch_notification(struct scmi_shared_mem __iomem *shmem,
size_t max_len, struct scmi_xfer *xfer)
{
size_t len = ioread32(&shmem->length);
/* Skip only the length of header in shmem area i.e 4 bytes */
xfer->rx.len = min_t(size_t, max_len, ioread32(&shmem->length) - 4);
xfer->rx.len = min_t(size_t, max_len, len > 4 ? len - 4 : 0);
/* Take a copy to the rx buffer.. */
memcpy_fromio(xfer->rx.buf, shmem->msg_payload, xfer->rx.len);
......
......@@ -52,9 +52,9 @@ static irqreturn_t smc_msg_done_isr(int irq, void *data)
return IRQ_HANDLED;
}
static bool smc_chan_available(struct device *dev, int idx)
static bool smc_chan_available(struct device_node *of_node, int idx)
{
struct device_node *np = of_parse_phandle(dev->of_node, "shmem", 0);
struct device_node *np = of_parse_phandle(of_node, "shmem", 0);
if (!np)
return false;
......@@ -171,8 +171,6 @@ static int smc_chan_free(int id, void *p, void *data)
cinfo->transport_info = NULL;
scmi_info->cinfo = NULL;
scmi_free_channel(cinfo, data, id);
return 0;
}
......
......@@ -160,7 +160,6 @@ static void scmi_vio_channel_cleanup_sync(struct scmi_vio_channel *vioch)
}
vioch->shutdown_done = &vioch_shutdown_done;
virtio_break_device(vioch->vqueue->vdev);
if (!vioch->is_rx && vioch->deferred_tx_wq)
/* Cannot be kicked anymore after this...*/
vioch->deferred_tx_wq = NULL;
......@@ -386,7 +385,7 @@ static int virtio_link_supplier(struct device *dev)
return 0;
}
static bool virtio_chan_available(struct device *dev, int idx)
static bool virtio_chan_available(struct device_node *of_node, int idx)
{
struct scmi_vio_channel *channels, *vioch = NULL;
......@@ -482,10 +481,14 @@ static int virtio_chan_free(int id, void *p, void *data)
struct scmi_chan_info *cinfo = p;
struct scmi_vio_channel *vioch = cinfo->transport_info;
/*
* Break device to inhibit further traffic flowing while shutting down
* the channels: doing it later holding vioch->lock creates unsafe
* locking dependency chains as reported by LOCKDEP.
*/
virtio_break_device(vioch->vqueue->vdev);
scmi_vio_channel_cleanup_sync(vioch);
scmi_free_channel(cinfo, data, id);
return 0;
}
......
......@@ -899,6 +899,7 @@ ssize_t debugfs_read_file_str(struct file *file, char __user *user_buf,
return ret;
}
EXPORT_SYMBOL_GPL(debugfs_create_str);
static ssize_t debugfs_write_file_str(struct file *file, const char __user *user_buf,
size_t count, loff_t *ppos)
......
......@@ -804,11 +804,6 @@ struct scmi_device {
#define to_scmi_dev(d) container_of(d, struct scmi_device, dev)
struct scmi_device *
scmi_device_create(struct device_node *np, struct device *parent, int protocol,
const char *name);
void scmi_device_destroy(struct scmi_device *scmi_dev);
struct scmi_device_id {
u8 protocol_id;
const char *name;
......
......@@ -139,11 +139,15 @@ TRACE_EVENT(scmi_rx_done,
);
TRACE_EVENT(scmi_msg_dump,
TP_PROTO(u8 protocol_id, u8 msg_id, unsigned char *tag, u16 seq,
int status, void *buf, size_t len),
TP_ARGS(protocol_id, msg_id, tag, seq, status, buf, len),
TP_PROTO(int id, u8 channel_id, u8 protocol_id, u8 msg_id,
unsigned char *tag, u16 seq, int status,
void *buf, size_t len),
TP_ARGS(id, channel_id, protocol_id, msg_id, tag, seq, status,
buf, len),
TP_STRUCT__entry(
__field(int, id)
__field(u8, channel_id)
__field(u8, protocol_id)
__field(u8, msg_id)
__array(char, tag, 5)
......@@ -154,6 +158,8 @@ TRACE_EVENT(scmi_msg_dump,
),
TP_fast_assign(
__entry->id = id;
__entry->channel_id = channel_id;
__entry->protocol_id = protocol_id;
__entry->msg_id = msg_id;
strscpy(__entry->tag, tag, 5);
......@@ -163,9 +169,9 @@ TRACE_EVENT(scmi_msg_dump,
memcpy(__get_dynamic_array(cmd), buf, __entry->len);
),
TP_printk("pt=%02X t=%s msg_id=%02X seq=%04X s=%d pyld=%s",
__entry->protocol_id, __entry->tag, __entry->msg_id,
__entry->seq, __entry->status,
TP_printk("id=%d ch=%02X pt=%02X t=%s msg_id=%02X seq=%04X s=%d pyld=%s",
__entry->id, __entry->channel_id, __entry->protocol_id,
__entry->tag, __entry->msg_id, __entry->seq, __entry->status,
__print_hex_str(__get_dynamic_array(cmd), __entry->len))
);
#endif /* _TRACE_SCMI_H */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment