linux/drivers/hwtracing/stm/core.c

// SPDX-License-Identifier: GPL-2.0
/*
 * System Trace Module (STM) infrastructure
 * Copyright (c) 2014, Intel Corporation.
 *
 * STM class implements generic infrastructure for  System Trace Module devices
 * as defined in MIPI STPv2 specification.
 */

#include <linux/pm_runtime.h>
#include <linux/uaccess.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/compat.h>
#include <linux/kdev_t.h>
#include <linux/srcu.h>
#include <linux/slab.h>
#include <linux/stm.h>
#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/vmalloc.h>
#include "stm.h"

#include <uapi/linux/stm.h>

static unsigned int stm_core_up;

/*
 * The SRCU here makes sure that STM device doesn't disappear from under a
 * stm_source_write() caller, which may want to have as little overhead as
 * possible.
 */
static struct srcu_struct stm_source_srcu;

static ssize_t masters_show(struct device *dev,
			    struct device_attribute *attr,
			    char *buf)
{}

static DEVICE_ATTR_RO(masters);

static ssize_t channels_show(struct device *dev,
			     struct device_attribute *attr,
			     char *buf)
{}

static DEVICE_ATTR_RO(channels);

static ssize_t hw_override_show(struct device *dev,
				struct device_attribute *attr,
				char *buf)
{}

static DEVICE_ATTR_RO(hw_override);

static struct attribute *stm_attrs[] =;

ATTRIBUTE_GROUPS();

static struct class stm_class =;

/**
 * stm_find_device() - find stm device by name
 * @buf:	character buffer containing the name
 *
 * This is called when either policy gets assigned to an stm device or an
 * stm_source device gets linked to an stm device.
 *
 * This grabs device's reference (get_device()) and module reference, both
 * of which the calling path needs to make sure to drop with stm_put_device().
 *
 * Return:	stm device pointer or null if lookup failed.
 */
struct stm_device *stm_find_device(const char *buf)
{}

/**
 * stm_put_device() - drop references on the stm device
 * @stm:	stm device, previously acquired by stm_find_device()
 *
 * This drops the module reference and device reference taken by
 * stm_find_device() or stm_char_open().
 */
void stm_put_device(struct stm_device *stm)
{}

/*
 * Internally we only care about software-writable masters here, that is the
 * ones in the range [stm_data->sw_start..stm_data..sw_end], however we need
 * original master numbers to be visible externally, since they are the ones
 * that will appear in the STP stream. Thus, the internal bookkeeping uses
 * $master - stm_data->sw_start to reference master descriptors and such.
 */

#define __stm_master(_s, _m)

static inline struct stp_master *
stm_master(struct stm_device *stm, unsigned int idx)
{}

static int stp_master_alloc(struct stm_device *stm, unsigned int idx)
{}

static void stp_master_free(struct stm_device *stm, unsigned int idx)
{}

static void stm_output_claim(struct stm_device *stm, struct stm_output *output)
{}

static void
stm_output_disclaim(struct stm_device *stm, struct stm_output *output)
{}

/*
 * This is like bitmap_find_free_region(), except it can ignore @start bits
 * at the beginning.
 */
static int find_free_channels(unsigned long *bitmap, unsigned int start,
			      unsigned int end, unsigned int width)
{}

static int
stm_find_master_chan(struct stm_device *stm, unsigned int width,
		     unsigned int *mstart, unsigned int mend,
		     unsigned int *cstart, unsigned int cend)
{}

static int stm_output_assign(struct stm_device *stm, unsigned int width,
			     struct stp_policy_node *policy_node,
			     struct stm_output *output)
{}

static void stm_output_free(struct stm_device *stm, struct stm_output *output)
{}

static void stm_output_init(struct stm_output *output)
{}

static int major_match(struct device *dev, const void *data)
{}

/*
 * Framing protocol management
 * Modules can implement STM protocol drivers and (un-)register them
 * with the STM class framework.
 */
static struct list_head stm_pdrv_head;
static struct mutex stm_pdrv_mutex;

struct stm_pdrv_entry {};

static const struct stm_pdrv_entry *
__stm_lookup_protocol(const char *name)
{}

int stm_register_protocol(const struct stm_protocol_driver *pdrv)
{}
EXPORT_SYMBOL_GPL();

void stm_unregister_protocol(const struct stm_protocol_driver *pdrv)
{}
EXPORT_SYMBOL_GPL();

static bool stm_get_protocol(const struct stm_protocol_driver *pdrv)
{}

void stm_put_protocol(const struct stm_protocol_driver *pdrv)
{}

int stm_lookup_protocol(const char *name,
			const struct stm_protocol_driver **pdrv,
			const struct config_item_type **node_type)
{}

static int stm_char_open(struct inode *inode, struct file *file)
{}

static int stm_char_release(struct inode *inode, struct file *file)
{}

static int
stm_assign_first_policy(struct stm_device *stm, struct stm_output *output,
			char **ids, unsigned int width)
{}

/**
 * stm_data_write() - send the given payload as data packets
 * @data:	stm driver's data
 * @m:		STP master
 * @c:		STP channel
 * @ts_first:	timestamp the first packet
 * @buf:	data payload buffer
 * @count:	data payload size
 */
ssize_t notrace stm_data_write(struct stm_data *data, unsigned int m,
			       unsigned int c, bool ts_first, const void *buf,
			       size_t count)
{}
EXPORT_SYMBOL_GPL();

static ssize_t notrace
stm_write(struct stm_device *stm, struct stm_output *output,
	  unsigned int chan, const char *buf, size_t count, struct stm_source_data *source)
{}

static ssize_t stm_char_write(struct file *file, const char __user *buf,
			      size_t count, loff_t *ppos)
{}

static void stm_mmap_open(struct vm_area_struct *vma)
{}

static void stm_mmap_close(struct vm_area_struct *vma)
{}

static const struct vm_operations_struct stm_mmap_vmops =;

static int stm_char_mmap(struct file *file, struct vm_area_struct *vma)
{}

static int stm_char_policy_set_ioctl(struct stm_file *stmf, void __user *arg)
{}

static int stm_char_policy_get_ioctl(struct stm_file *stmf, void __user *arg)
{}

static long
stm_char_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{}

static const struct file_operations stm_fops =;

static void stm_device_release(struct device *dev)
{}

int stm_register_device(struct device *parent, struct stm_data *stm_data,
			struct module *owner)
{}
EXPORT_SYMBOL_GPL();

static int __stm_source_link_drop(struct stm_source_device *src,
				  struct stm_device *stm);

void stm_unregister_device(struct stm_data *stm_data)
{}
EXPORT_SYMBOL_GPL();

/*
 * stm::link_list access serialization uses a spinlock and a mutex; holding
 * either of them guarantees that the list is stable; modification requires
 * holding both of them.
 *
 * Lock ordering is as follows:
 *   stm::link_mutex
 *     stm::link_lock
 *       src::link_lock
 */

/**
 * stm_source_link_add() - connect an stm_source device to an stm device
 * @src:	stm_source device
 * @stm:	stm device
 *
 * This function establishes a link from stm_source to an stm device so that
 * the former can send out trace data to the latter.
 *
 * Return:	0 on success, -errno otherwise.
 */
static int stm_source_link_add(struct stm_source_device *src,
			       struct stm_device *stm)
{}

/**
 * __stm_source_link_drop() - detach stm_source from an stm device
 * @src:	stm_source device
 * @stm:	stm device
 *
 * If @stm is @src::link, disconnect them from one another and put the
 * reference on the @stm device.
 *
 * Caller must hold stm::link_mutex.
 */
static int __stm_source_link_drop(struct stm_source_device *src,
				  struct stm_device *stm)
{}

/**
 * stm_source_link_drop() - detach stm_source from its stm device
 * @src:	stm_source device
 *
 * Unlinking means disconnecting from source's STM device; after this
 * writes will be unsuccessful until it is linked to a new STM device.
 *
 * This will happen on "stm_source_link" sysfs attribute write to undo
 * the existing link (if any), or on linked STM device's de-registration.
 */
static void stm_source_link_drop(struct stm_source_device *src)
{}

static ssize_t stm_source_link_show(struct device *dev,
				    struct device_attribute *attr,
				    char *buf)
{}

static ssize_t stm_source_link_store(struct device *dev,
				     struct device_attribute *attr,
				     const char *buf, size_t count)
{}

static DEVICE_ATTR_RW(stm_source_link);

static struct attribute *stm_source_attrs[] =;

ATTRIBUTE_GROUPS();

static struct class stm_source_class =;

static void stm_source_device_release(struct device *dev)
{}

/**
 * stm_source_register_device() - register an stm_source device
 * @parent:	parent device
 * @data:	device description structure
 *
 * This will create a device of stm_source class that can write
 * data to an stm device once linked.
 *
 * Return:	0 on success, -errno otherwise.
 */
int stm_source_register_device(struct device *parent,
			       struct stm_source_data *data)
{}
EXPORT_SYMBOL_GPL();

/**
 * stm_source_unregister_device() - unregister an stm_source device
 * @data:	device description that was used to register the device
 *
 * This will remove a previously created stm_source device from the system.
 */
void stm_source_unregister_device(struct stm_source_data *data)
{}
EXPORT_SYMBOL_GPL();

int notrace stm_source_write(struct stm_source_data *data,
			     unsigned int chan,
			     const char *buf, size_t count)
{}
EXPORT_SYMBOL_GPL();

static int __init stm_core_init(void)
{}

module_init();

static void __exit stm_core_exit(void)
{}

module_exit(stm_core_exit);

MODULE_LICENSE();
MODULE_DESCRIPTION();
MODULE_AUTHOR();