diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2024-05-22 22:26:46 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2024-05-22 22:26:46 +0300 |
commit | 5f16eb0549ab502906fb2a10147dad4b9dc185c4 (patch) | |
tree | 285bcf9df768d58f9aa5dbda8418f1ec961bd22b /drivers/hwtracing/stm | |
parent | d90be6e4aaf23cd4a2c202891399cbafe669aaab (diff) | |
parent | f5b335dc025cfee90957efa90dc72fada0d5abb4 (diff) | |
download | linux-5f16eb0549ab502906fb2a10147dad4b9dc185c4.tar.xz |
Merge tag 'char-misc-6.10-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc
Pull char/misc and other driver subsystem updates from Greg KH:
"Here is the big set of char/misc and other driver subsystem updates
for 6.10-rc1. Nothing major here, just lots of new drivers and updates
for apis and new hardware types. Included in here are:
- big IIO driver updates with more devices and drivers added
- fpga driver updates
- hyper-v driver updates
- uio_pruss driver removal, no one uses it, other drivers control the
same hardware now
- binder minor updates
- mhi driver updates
- excon driver updates
- counter driver updates
- accessability driver updates
- coresight driver updates
- other hwtracing driver updates
- nvmem driver updates
- slimbus driver updates
- spmi driver updates
- other smaller misc and char driver updates
All of these have been in linux-next for a while with no reported
issues"
* tag 'char-misc-6.10-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: (319 commits)
misc: ntsync: mark driver as "broken" to prevent from building
spmi: pmic-arb: Add multi bus support
spmi: pmic-arb: Register controller for bus instead of arbiter
spmi: pmic-arb: Make core resources acquiring a version operation
spmi: pmic-arb: Make the APID init a version operation
spmi: pmic-arb: Fix some compile warnings about members not being described
dt-bindings: spmi: Deprecate qcom,bus-id
dt-bindings: spmi: Add X1E80100 SPMI PMIC ARB schema
spmi: pmic-arb: Replace three IS_ERR() calls by null pointer checks in spmi_pmic_arb_probe()
spmi: hisi-spmi-controller: Do not override device identifier
dt-bindings: spmi: hisilicon,hisi-spmi-controller: clean up example
dt-bindings: spmi: hisilicon,hisi-spmi-controller: fix binding references
spmi: make spmi_bus_type const
extcon: adc-jack: Document missing struct members
extcon: realtek: Remove unused of_gpio.h
extcon: usbc-cros-ec: Convert to platform remove callback returning void
extcon: usb-gpio: Convert to platform remove callback returning void
extcon: max77843: Convert to platform remove callback returning void
extcon: max3355: Convert to platform remove callback returning void
extcon: intel-mrfld: Convert to platform remove callback returning void
...
Diffstat (limited to 'drivers/hwtracing/stm')
-rw-r--r-- | drivers/hwtracing/stm/console.c | 1 | ||||
-rw-r--r-- | drivers/hwtracing/stm/core.c | 19 | ||||
-rw-r--r-- | drivers/hwtracing/stm/ftrace.c | 1 | ||||
-rw-r--r-- | drivers/hwtracing/stm/heartbeat.c | 1 | ||||
-rw-r--r-- | drivers/hwtracing/stm/p_basic.c | 3 | ||||
-rw-r--r-- | drivers/hwtracing/stm/p_sys-t.c | 93 | ||||
-rw-r--r-- | drivers/hwtracing/stm/stm.h | 2 |
7 files changed, 101 insertions, 19 deletions
diff --git a/drivers/hwtracing/stm/console.c b/drivers/hwtracing/stm/console.c index a00f65e21747..097a00ac43a7 100644 --- a/drivers/hwtracing/stm/console.c +++ b/drivers/hwtracing/stm/console.c @@ -22,6 +22,7 @@ static struct stm_console { .data = { .name = "console", .nr_chans = 1, + .type = STM_USER, .link = stm_console_link, .unlink = stm_console_unlink, }, diff --git a/drivers/hwtracing/stm/core.c b/drivers/hwtracing/stm/core.c index 534fbefc7f6a..ccf39a80dc4f 100644 --- a/drivers/hwtracing/stm/core.c +++ b/drivers/hwtracing/stm/core.c @@ -600,7 +600,7 @@ EXPORT_SYMBOL_GPL(stm_data_write); static ssize_t notrace stm_write(struct stm_device *stm, struct stm_output *output, - unsigned int chan, const char *buf, size_t count) + unsigned int chan, const char *buf, size_t count, struct stm_source_data *source) { int err; @@ -608,7 +608,7 @@ stm_write(struct stm_device *stm, struct stm_output *output, if (!stm->pdrv) return -ENODEV; - err = stm->pdrv->write(stm->data, output, chan, buf, count); + err = stm->pdrv->write(stm->data, output, chan, buf, count, source); if (err < 0) return err; @@ -657,7 +657,7 @@ static ssize_t stm_char_write(struct file *file, const char __user *buf, pm_runtime_get_sync(&stm->dev); - count = stm_write(stm, &stmf->output, 0, kbuf, count); + count = stm_write(stm, &stmf->output, 0, kbuf, count, NULL); pm_runtime_mark_last_busy(&stm->dev); pm_runtime_put_autosuspend(&stm->dev); @@ -868,8 +868,11 @@ int stm_register_device(struct device *parent, struct stm_data *stm_data, return -ENOMEM; stm->major = register_chrdev(0, stm_data->name, &stm_fops); - if (stm->major < 0) - goto err_free; + if (stm->major < 0) { + err = stm->major; + vfree(stm); + return err; + } device_initialize(&stm->dev); stm->dev.devt = MKDEV(stm->major, 0); @@ -913,10 +916,8 @@ int stm_register_device(struct device *parent, struct stm_data *stm_data, err_device: unregister_chrdev(stm->major, stm_data->name); - /* matches device_initialize() above */ + /* calls stm_device_release() */ put_device(&stm->dev); -err_free: - vfree(stm); return err; } @@ -1298,7 +1299,7 @@ int notrace stm_source_write(struct stm_source_data *data, stm = srcu_dereference(src->link, &stm_source_srcu); if (stm) - count = stm_write(stm, &src->output, chan, buf, count); + count = stm_write(stm, &src->output, chan, buf, count, data); else count = -ENODEV; diff --git a/drivers/hwtracing/stm/ftrace.c b/drivers/hwtracing/stm/ftrace.c index 3bb606dfa634..a7cea7ea0163 100644 --- a/drivers/hwtracing/stm/ftrace.c +++ b/drivers/hwtracing/stm/ftrace.c @@ -23,6 +23,7 @@ static struct stm_ftrace { .data = { .name = "ftrace", .nr_chans = STM_FTRACE_NR_CHANNELS, + .type = STM_FTRACE, .link = stm_ftrace_link, .unlink = stm_ftrace_unlink, }, diff --git a/drivers/hwtracing/stm/heartbeat.c b/drivers/hwtracing/stm/heartbeat.c index 81d7b21d31ec..e9496fe97baa 100644 --- a/drivers/hwtracing/stm/heartbeat.c +++ b/drivers/hwtracing/stm/heartbeat.c @@ -78,6 +78,7 @@ static int stm_heartbeat_init(void) } stm_heartbeat[i].data.nr_chans = 1; + stm_heartbeat[i].data.type = STM_USER; stm_heartbeat[i].data.link = stm_heartbeat_link; stm_heartbeat[i].data.unlink = stm_heartbeat_unlink; hrtimer_init(&stm_heartbeat[i].hrtimer, CLOCK_MONOTONIC, diff --git a/drivers/hwtracing/stm/p_basic.c b/drivers/hwtracing/stm/p_basic.c index 8980a6a5fd6c..5525c975cc6f 100644 --- a/drivers/hwtracing/stm/p_basic.c +++ b/drivers/hwtracing/stm/p_basic.c @@ -10,7 +10,8 @@ #include "stm.h" static ssize_t basic_write(struct stm_data *data, struct stm_output *output, - unsigned int chan, const char *buf, size_t count) + unsigned int chan, const char *buf, size_t count, + struct stm_source_data *source) { unsigned int c = output->channel + chan; unsigned int m = output->master; diff --git a/drivers/hwtracing/stm/p_sys-t.c b/drivers/hwtracing/stm/p_sys-t.c index 8254971c02e7..1e75aa0025a3 100644 --- a/drivers/hwtracing/stm/p_sys-t.c +++ b/drivers/hwtracing/stm/p_sys-t.c @@ -20,6 +20,7 @@ enum sys_t_message_type { MIPI_SYST_TYPE_RAW = 6, MIPI_SYST_TYPE_SHORT64, MIPI_SYST_TYPE_CLOCK, + MIPI_SYST_TYPE_SBD, }; enum sys_t_message_severity { @@ -53,6 +54,19 @@ enum sys_t_message_string_subtype { MIPI_SYST_STRING_PRINTF_64 = 12, }; +/** + * enum sys_t_message_sbd_subtype - SyS-T SBD message subtypes + * @MIPI_SYST_SBD_ID32: SBD message with 32-bit message ID + * @MIPI_SYST_SBD_ID64: SBD message with 64-bit message ID + * + * Structured Binary Data messages can send information of arbitrary length, + * together with ID's that describe BLOB's content and layout. + */ +enum sys_t_message_sbd_subtype { + MIPI_SYST_SBD_ID32 = 0, + MIPI_SYST_SBD_ID64 = 1, +}; + #define MIPI_SYST_TYPE(t) ((u32)(MIPI_SYST_TYPE_ ## t)) #define MIPI_SYST_SEVERITY(s) ((u32)(MIPI_SYST_SEVERITY_ ## s) << 4) #define MIPI_SYST_OPT_LOC BIT(8) @@ -75,6 +89,20 @@ enum sys_t_message_string_subtype { #define CLOCK_SYNC_HEADER (MIPI_SYST_TYPES(CLOCK, TRANSPORT_SYNC) | \ MIPI_SYST_SEVERITY(MAX)) +/* + * SyS-T and ftrace headers are compatible to an extent that ftrace event ID + * and args can be treated as SyS-T SBD message with 64-bit ID and arguments + * BLOB right behind the header without modification. Bits [16:63] coming + * together with message ID from ftrace aren't used by SBD and must be zeroed. + * + * 0 15 16 23 24 31 32 39 40 63 + * ftrace: <event_id> <flags> <preempt> <-pid-> <----> <args> + * SBD: <------- msg_id ------------------------------> <BLOB> + */ +#define SBD_HEADER (MIPI_SYST_TYPES(SBD, ID64) | \ + MIPI_SYST_SEVERITY(INFO) | \ + MIPI_SYST_OPT_GUID) + struct sys_t_policy_node { uuid_t uuid; bool do_len; @@ -284,14 +312,67 @@ sys_t_clock_sync(struct stm_data *data, unsigned int m, unsigned int c) return sizeof(header) + sizeof(payload); } +static inline u32 sys_t_header(struct stm_source_data *source) +{ + if (source && source->type == STM_FTRACE) + return SBD_HEADER; + return DATA_HEADER; +} + +static ssize_t sys_t_write_data(struct stm_data *data, + struct stm_source_data *source, + unsigned int master, unsigned int channel, + bool ts_first, const void *buf, size_t count) +{ + ssize_t sz; + const unsigned char nil = 0; + + /* + * Ftrace is zero-copy compatible with SyS-T SBD, but requires + * special handling of first 64 bits. Trim and send them separately + * to avoid damage on original ftrace buffer. + */ + if (source && source->type == STM_FTRACE) { + u64 compat_ftrace_header; + ssize_t header_sz; + ssize_t buf_sz; + + if (count < sizeof(compat_ftrace_header)) + return -EINVAL; + + /* SBD only makes use of low 16 bits (event ID) from ftrace event */ + compat_ftrace_header = *(u64 *)buf & 0xffff; + header_sz = stm_data_write(data, master, channel, false, + &compat_ftrace_header, + sizeof(compat_ftrace_header)); + if (header_sz != sizeof(compat_ftrace_header)) + return header_sz; + + buf_sz = stm_data_write(data, master, channel, false, + buf + header_sz, count - header_sz); + if (buf_sz != count - header_sz) + return buf_sz; + sz = header_sz + buf_sz; + } else { + sz = stm_data_write(data, master, channel, false, buf, count); + } + + if (sz <= 0) + return sz; + + data->packet(data, master, channel, STP_PACKET_FLAG, 0, 0, &nil); + + return sz; +} + static ssize_t sys_t_write(struct stm_data *data, struct stm_output *output, - unsigned int chan, const char *buf, size_t count) + unsigned int chan, const char *buf, size_t count, + struct stm_source_data *source) { struct sys_t_output *op = output->pdrv_private; unsigned int c = output->channel + chan; unsigned int m = output->master; - const unsigned char nil = 0; - u32 header = DATA_HEADER; + u32 header = sys_t_header(source); u8 uuid[UUID_SIZE]; ssize_t sz; @@ -348,11 +429,7 @@ static ssize_t sys_t_write(struct stm_data *data, struct stm_output *output, } /* DATA */ - sz = stm_data_write(data, m, c, false, buf, count); - if (sz > 0) - data->packet(data, m, c, STP_PACKET_FLAG, 0, 0, &nil); - - return sz; + return sys_t_write_data(data, source, m, c, false, buf, count); } static const struct stm_protocol_driver sys_t_pdrv = { diff --git a/drivers/hwtracing/stm/stm.h b/drivers/hwtracing/stm/stm.h index a9be49fc7a6b..85dda6e0d10c 100644 --- a/drivers/hwtracing/stm/stm.h +++ b/drivers/hwtracing/stm/stm.h @@ -96,7 +96,7 @@ struct stm_protocol_driver { const char *name; ssize_t (*write)(struct stm_data *data, struct stm_output *output, unsigned int chan, - const char *buf, size_t count); + const char *buf, size_t count, struct stm_source_data *source); void (*policy_node_init)(void *arg); int (*output_open)(void *priv, struct stm_output *output); void (*output_close)(struct stm_output *output); |