19ea393d8SAlexander Shishkin // SPDX-License-Identifier: GPL-2.0 27bd1d409SAlexander Shishkin /* 37bd1d409SAlexander Shishkin * System Trace Module (STM) infrastructure apis 47bd1d409SAlexander Shishkin * Copyright (C) 2014 Intel Corporation. 57bd1d409SAlexander Shishkin */ 67bd1d409SAlexander Shishkin 77bd1d409SAlexander Shishkin #ifndef _STM_H_ 87bd1d409SAlexander Shishkin #define _STM_H_ 97bd1d409SAlexander Shishkin 107bd1d409SAlexander Shishkin #include <linux/device.h> 117bd1d409SAlexander Shishkin 127bd1d409SAlexander Shishkin /** 137bd1d409SAlexander Shishkin * enum stp_packet_type - STP packets that an STM driver sends 147bd1d409SAlexander Shishkin */ 157bd1d409SAlexander Shishkin enum stp_packet_type { 167bd1d409SAlexander Shishkin STP_PACKET_DATA = 0, 177bd1d409SAlexander Shishkin STP_PACKET_FLAG, 187bd1d409SAlexander Shishkin STP_PACKET_USER, 197bd1d409SAlexander Shishkin STP_PACKET_MERR, 207bd1d409SAlexander Shishkin STP_PACKET_GERR, 217bd1d409SAlexander Shishkin STP_PACKET_TRIG, 227bd1d409SAlexander Shishkin STP_PACKET_XSYNC, 237bd1d409SAlexander Shishkin }; 247bd1d409SAlexander Shishkin 257bd1d409SAlexander Shishkin /** 267bd1d409SAlexander Shishkin * enum stp_packet_flags - STP packet modifiers 277bd1d409SAlexander Shishkin */ 287bd1d409SAlexander Shishkin enum stp_packet_flags { 297bd1d409SAlexander Shishkin STP_PACKET_MARKED = 0x1, 307bd1d409SAlexander Shishkin STP_PACKET_TIMESTAMPED = 0x2, 317bd1d409SAlexander Shishkin }; 327bd1d409SAlexander Shishkin 337bd1d409SAlexander Shishkin struct stp_policy; 347bd1d409SAlexander Shishkin 357bd1d409SAlexander Shishkin struct stm_device; 367bd1d409SAlexander Shishkin 377bd1d409SAlexander Shishkin /** 387bd1d409SAlexander Shishkin * struct stm_data - STM device description and callbacks 397bd1d409SAlexander Shishkin * @name: device name 407bd1d409SAlexander Shishkin * @stm: internal structure, only used by stm class code 417bd1d409SAlexander Shishkin * @sw_start: first STP master available to software 427bd1d409SAlexander Shishkin * @sw_end: last STP master available to software 437bd1d409SAlexander Shishkin * @sw_nchannels: number of STP channels per master 447bd1d409SAlexander Shishkin * @sw_mmiosz: size of one channel's IO space, for mmap, optional 458e996a28SAlexander Shishkin * @hw_override: masters in the STP stream will not match the ones 468e996a28SAlexander Shishkin * assigned by software, but are up to the STM hardware 477bd1d409SAlexander Shishkin * @packet: callback that sends an STP packet 487bd1d409SAlexander Shishkin * @mmio_addr: mmap callback, optional 497bd1d409SAlexander Shishkin * @link: called when a new stm_source gets linked to us, optional 507bd1d409SAlexander Shishkin * @unlink: likewise for unlinking, again optional 517bd1d409SAlexander Shishkin * @set_options: set device-specific options on a channel 527bd1d409SAlexander Shishkin * 537bd1d409SAlexander Shishkin * Fill out this structure before calling stm_register_device() to create 547bd1d409SAlexander Shishkin * an STM device and stm_unregister_device() to destroy it. It will also be 557bd1d409SAlexander Shishkin * passed back to @packet(), @mmio_addr(), @link(), @unlink() and @set_options() 567bd1d409SAlexander Shishkin * callbacks. 577bd1d409SAlexander Shishkin * 587bd1d409SAlexander Shishkin * Normally, an STM device will have a range of masters available to software 597bd1d409SAlexander Shishkin * and the rest being statically assigned to various hardware trace sources. 60*d0b371e5SRandy Dunlap * The former is defined by the range [@sw_start..@sw_end] of the device 617bd1d409SAlexander Shishkin * description. That is, the lowest master that can be allocated to software 627bd1d409SAlexander Shishkin * writers is @sw_start and data from this writer will appear is @sw_start 637bd1d409SAlexander Shishkin * master in the STP stream. 64f8560a9bSAlexander Shishkin * 65f8560a9bSAlexander Shishkin * The @packet callback should adhere to the following rules: 66f8560a9bSAlexander Shishkin * 1) it must return the number of bytes it consumed from the payload; 67f8560a9bSAlexander Shishkin * 2) therefore, if it sent a packet that does not have payload (like FLAG), 68f8560a9bSAlexander Shishkin * it must return zero; 69f8560a9bSAlexander Shishkin * 3) if it does not support the requested packet type/flag combination, 70f8560a9bSAlexander Shishkin * it must return -ENOTSUPP. 71cc842407SAlexander Shishkin * 72cc842407SAlexander Shishkin * The @unlink callback is called when there are no more active writers so 73cc842407SAlexander Shishkin * that the master/channel can be quiesced. 747bd1d409SAlexander Shishkin */ 757bd1d409SAlexander Shishkin struct stm_data { 767bd1d409SAlexander Shishkin const char *name; 777bd1d409SAlexander Shishkin struct stm_device *stm; 787bd1d409SAlexander Shishkin unsigned int sw_start; 797bd1d409SAlexander Shishkin unsigned int sw_end; 807bd1d409SAlexander Shishkin unsigned int sw_nchannels; 817bd1d409SAlexander Shishkin unsigned int sw_mmiosz; 828e996a28SAlexander Shishkin unsigned int hw_override; 837bd1d409SAlexander Shishkin ssize_t (*packet)(struct stm_data *, unsigned int, 847bd1d409SAlexander Shishkin unsigned int, unsigned int, 857bd1d409SAlexander Shishkin unsigned int, unsigned int, 867bd1d409SAlexander Shishkin const unsigned char *); 877bd1d409SAlexander Shishkin phys_addr_t (*mmio_addr)(struct stm_data *, unsigned int, 887bd1d409SAlexander Shishkin unsigned int, unsigned int); 897bd1d409SAlexander Shishkin int (*link)(struct stm_data *, unsigned int, 907bd1d409SAlexander Shishkin unsigned int); 917bd1d409SAlexander Shishkin void (*unlink)(struct stm_data *, unsigned int, 927bd1d409SAlexander Shishkin unsigned int); 937bd1d409SAlexander Shishkin long (*set_options)(struct stm_data *, unsigned int, 947bd1d409SAlexander Shishkin unsigned int, unsigned int, 957bd1d409SAlexander Shishkin unsigned long); 967bd1d409SAlexander Shishkin }; 977bd1d409SAlexander Shishkin 987bd1d409SAlexander Shishkin int stm_register_device(struct device *parent, struct stm_data *stm_data, 997bd1d409SAlexander Shishkin struct module *owner); 1007bd1d409SAlexander Shishkin void stm_unregister_device(struct stm_data *stm_data); 1017bd1d409SAlexander Shishkin 1027bd1d409SAlexander Shishkin struct stm_source_device; 1037bd1d409SAlexander Shishkin 1047bd1d409SAlexander Shishkin /** 1057bd1d409SAlexander Shishkin * struct stm_source_data - STM source device description and callbacks 1067bd1d409SAlexander Shishkin * @name: device name, will be used for policy lookup 1077bd1d409SAlexander Shishkin * @src: internal structure, only used by stm class code 1087bd1d409SAlexander Shishkin * @nr_chans: number of channels to allocate 1097bd1d409SAlexander Shishkin * @link: called when this source gets linked to an STM device 1107bd1d409SAlexander Shishkin * @unlink: called when this source is about to get unlinked from its STM 1117bd1d409SAlexander Shishkin * 1127bd1d409SAlexander Shishkin * Fill in this structure before calling stm_source_register_device() to 1137bd1d409SAlexander Shishkin * register a source device. Also pass it to unregister and write calls. 1147bd1d409SAlexander Shishkin */ 1157bd1d409SAlexander Shishkin struct stm_source_data { 1167bd1d409SAlexander Shishkin const char *name; 1177bd1d409SAlexander Shishkin struct stm_source_device *src; 1187bd1d409SAlexander Shishkin unsigned int percpu; 1197bd1d409SAlexander Shishkin unsigned int nr_chans; 1207bd1d409SAlexander Shishkin int (*link)(struct stm_source_data *data); 1217bd1d409SAlexander Shishkin void (*unlink)(struct stm_source_data *data); 1227bd1d409SAlexander Shishkin }; 1237bd1d409SAlexander Shishkin 1247bd1d409SAlexander Shishkin int stm_source_register_device(struct device *parent, 1257bd1d409SAlexander Shishkin struct stm_source_data *data); 1267bd1d409SAlexander Shishkin void stm_source_unregister_device(struct stm_source_data *data); 1277bd1d409SAlexander Shishkin 1289dfed80dSChunyan Zhang int notrace stm_source_write(struct stm_source_data *data, unsigned int chan, 1297bd1d409SAlexander Shishkin const char *buf, size_t count); 1307bd1d409SAlexander Shishkin 1317bd1d409SAlexander Shishkin #endif /* _STM_H_ */ 132