soc: qcom: Add RPM SMD Driver

This is a snapshot of the RPM-SMD driver functionality as of
'commit 9c23726ad4df ("leds: qpnp-flash: Fix 11
Use-after-free(UAF) for debugfs")' on msm-4.4 branch.

Change-Id: I502300cf26b67679a9344a89b2feaa0dbcc5fb59
Signed-off-by: Raju P.L.S.S.S.N <rplsssn@codeaurora.org>
This commit is contained in:
Raju P.L.S.S.S.N 2017-10-31 16:50:30 +05:30 • committed by Raghavendra Kakarla
commit 43c1be7e52
9 changed files with 3012 additions and 0 deletions

View file

@ -0,0 +1,157 @@
Introduction
============
Resource Power Manager (RPM)
RPM is a dedicated hardware engine for managing shared SoC resources,
which includes buses, clocks, power rails, etc. The goal of RPM is
to achieve the maximum power savings while satisfying the SoC's
operational and performance requirements. RPM accepts resource
requests from multiple RPM masters. It arbitrates and aggregates the
requests, and configures the shared resources. The RPM masters are
the application processor, the modem processor, as well as some
hardware accelerators.
The RPM driver provides an API for interacting with RPM. Kernel code
calls the RPM driver to request RPM-managed, shared resources.
Kernel code can also register with the driver for RPM notifications,
which are sent when the status of shared resources change.
Hardware description
====================
RPM exposes a separate region of registers to each of the RPM masters.
In general, each register represents some shared resource(s). At a
very basic level, a master requests resources by writing to the
registers, then generating an interrupt to RPM. RPM processes the
request, writes acknowledgment to the registers, then generates an
interrupt to the master.
In addition to the master-specific regions, RPM also exposes a shared
region that contains the current status of the shared resources. Only
RPM can write to the status region, but every master can read from it.
RPM contains internal logics that aggregate and arbitrate among
requests from the various RPM masters. It interfaces with the PMIC,
the bus arbitration block, and the clock controller block in order to
configure the shared resources.
Software description
====================
The RPM driver encapsulates the low level RPM interactions, which
rely on reading/writing registers and generating/processing
interrupts, and provides a higher level synchronuous set/clear/get
interface. Most functions take an array of id-value pairs.
The ids identify the RPM registers which would correspond to some
RPM resources, the values specify the new resource values.
The RPM driver synchronizes accesses to RPM. It protects against
simultaneous accesses from multiple tasks, on SMP cores, in task
contexts, and in atomic contexts.
Design
======
Design goals:
- Encapsulate low level RPM interactions.
- Provide a synchronuous set/clear/get interface.
- Synchronize simultaneous software accesses to RPM.
Power Management
================
RPM is part of the power management architecture for MSM 8660. RPM
manages shared system resources to lower system power.
SMP/multi-core
==============
The RPM driver uses mutex to synchronize client accesses among tasks.
It uses spinlocks to synchronize accesses from atomic contexts and
SMP cores.
Security
========
None.
Performance
===========
None.
Interface
=========
msm_rpm_get_status():
The function reads the shared status region and returns the current
resource values, which are the arbitrated/aggregated results across
all RPM masters.
msm_rpm_set():
The function makes a resource request to RPM.
msm_rpm_set_noirq():
The function is similar to msm_rpm_set() except that it must be
called with interrupts masked. If possible, use msm_rpm_set()
instead, to maximize CPU throughput.
msm_rpm_clear():
The function makes a resource request to RPM to clear resource values.
Once the values are cleared, the resources revert back to their default
values for this RPM master. RPM internally uses the default values as
the requests from this RPM master when arbitrating and aggregating with
requests from other RPM masters.
msm_rpm_clear_noirq():
The function is similar to msm_rpm_clear() except that it must be
called with interrupts masked. If possible, use msm_rpm_clear()
instead, to maximize CPU throughput.
msm_rpm_register_notification():
The function registers for RPM notification. When the specified
resources change their status on RPM, RPM sends out notifications
and the driver will "up" the semaphore in struct
msm_rpm_notification.
msm_rpm_unregister_notification():
The function unregisters a notification.
msm_rpm_init():
The function initializes the RPM driver with platform specific data.
Driver parameters
=================
None.
Config options
==============
MSM_RPM
Dependencies
============
None.
User space utilities
====================
None.
Other
=====
None.
Known issues
============
None.
To do
=====
None.

View file

@ -0,0 +1,41 @@
Resource Power Manager(RPM)
RPM is a dedicated hardware engine for managing shared SoC resources,
which includes buses, clocks, power rails, etc. The goal of RPM is
to achieve the maximum power savings while satisfying the SoC's
operational and performance requirements. RPM accepts resource
requests from multiple RPM masters. It arbitrates and aggregates the
requests, and configures the shared resources. The RPM masters are
the application processor, the modem processor, as well as hardware
accelerators. The RPM driver communicates with the hardware engine using
SMD.
The devicetree representation of the SPM block should be:
Required properties
- compatible: "qcom,rpm-smd" or "qcom,rpm-glink"
- rpm-channel-name: The string corresponding to the channel name of the
peripheral subsystem. Required for both smd and
glink transports.
- rpm-channel-type: The interal SMD edge for this subsystem found in
<soc/qcom/smd.h>
- qcom,glink-edge: Logical name of the remote subsystem. This is a required
property when rpm-smd driver using glink as trasport.
Optional properties
- rpm-standalone: Allow RPM driver to run in standalone mode irrespective of RPM
channel presence.
- reg: Contains the memory address at which rpm messaging format version is
stored. If this field is not present, the target only supports v0 format.
Example:
qcom,rpm-smd@68150 {
compatible = "qcom,rpm-smd", "qcom,rpm-glink";
reg = <0x68150 0x3200>;
qcom,rpm-channel-name = "rpm_requests";
qcom,rpm-channel-type = 15; /* SMD_APPS_RPM */
qcom,glink-edge = "rpm";
}
}

View file

@ -268,6 +268,15 @@ config MINIDUMP_MAX_ENTRIES
This defines maximum number of entries to be allocated for application
subsytem in Minidump table.
config MSM_RPM_SMD
bool "RPM driver using SMD protocol"
help
RPM is the dedicated hardware engine for managing shared SoC
resources. This config adds driver support for using SMD as a
transport layer communication with RPM hardware. It also selects
the MSM_MPM config that programs the MPM module to monitor interrupts
during sleep modes.
config QCOM_BUS_SCALING
bool "Bus scaling driver"
help

View file

@ -42,6 +42,10 @@ obj-$(CONFIG_MSM_SPSS_UTILS) += spss_utils.o
obj-$(CONFIG_TRACER_PKT) += tracer_pkt.o
obj-$(CONFIG_QCOM_BUS_SCALING) += msm_bus/
obj-$(CONFIG_QTI_RPMH_API) += rpmh.o
obj-$(CONFIG_MSM_RPM_SMD) += rpm-smd.o
ifdef CONFIG_DEBUG_FS
obj-$(CONFIG_MSM_RPM_SMD) += rpm-smd-debug.o
endif
obj-$(CONFIG_QTI_SYSTEM_PM) += system_pm.o
obj-$(CONFIG_MSM_SERVICE_NOTIFIER) += service-notifier.o
obj-$(CONFIG_MSM_SERVICE_LOCATOR) += service-locator.o

View file

@ -0,0 +1,151 @@
/* Copyright (c) 2013-2014, 2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#define pr_fmt(fmt) "rpm-smd-debug: %s(): " fmt, __func__
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/debugfs.h>
#include <linux/list.h>
#include <linux/io.h>
#include <linux/uaccess.h>
#include <linux/slab.h>
#include <soc/qcom/rpm-smd.h>
#define MAX_MSG_BUFFER 350
#define MAX_KEY_VALUE_PAIRS 20
static struct dentry *rpm_debugfs_dir;
static u32 string_to_uint(const u8 *str)
{
int i, len;
u32 output = 0;
len = strnlen(str, sizeof(u32));
for (i = 0; i < len; i++)
output |= str[i] << (i * 8);
return output;
}
static ssize_t rsc_ops_write(struct file *fp, const char __user *user_buffer,
size_t count, loff_t *position)
{
char buf[MAX_MSG_BUFFER], rsc_type_str[6] = {}, rpm_set[8] = {},
key_str[6] = {};
int i, pos = -1, set = -1, nelems = -1;
char *cmp;
uint32_t rsc_type = 0, rsc_id = 0, key = 0, data = 0;
struct msm_rpm_request *req;
count = min(count, sizeof(buf) - 1);
if (copy_from_user(&buf, user_buffer, count))
return -EFAULT;
buf[count] = '\0';
cmp = strstrip(buf);
if (sscanf(cmp, "%7s %5s %u %d %n", rpm_set, rsc_type_str,
&rsc_id, &nelems, &pos) != 4) {
pr_err("Invalid number of arguments passed\n");
goto err;
}
if (strlen(rpm_set) > 6 || strlen(rsc_type_str) > 4) {
pr_err("Invalid value of set or resource type\n");
goto err;
}
if (!strcmp(rpm_set, "active"))
set = 0;
else if (!strcmp(rpm_set, "sleep"))
set = 1;
rsc_type = string_to_uint(rsc_type_str);
if (set < 0 || nelems < 0) {
pr_err("Invalid value of set or nelems\n");
goto err;
}
if (nelems > MAX_KEY_VALUE_PAIRS) {
pr_err("Exceeded max no of key-value entries\n");
goto err;
}
req = msm_rpm_create_request(set, rsc_type, rsc_id, nelems);
if (!req)
return -ENOMEM;
for (i = 0; i < nelems; i++) {
cmp += pos;
if (sscanf(cmp, "%5s %n", key_str, &pos) != 1) {
pr_err("Invalid number of arguments passed\n");
goto err;
}
if (strlen(key_str) > 4) {
pr_err("Key value cannot be more than 4 charecters");
goto err;
}
key = string_to_uint(key_str);
if (!key) {
pr_err("Key values entered incorrectly\n");
goto err;
}
cmp += pos;
if (sscanf(cmp, "%u %n", &data, &pos) != 1) {
pr_err("Invalid number of arguments passed\n");
goto err;
}
if (msm_rpm_add_kvp_data(req, key,
(void *)&data, sizeof(data)))
goto err_request;
}
if (msm_rpm_wait_for_ack(msm_rpm_send_request(req)))
pr_err("Sending the RPM message failed\n");
err_request:
msm_rpm_free_request(req);
err:
return count;
}
static const struct file_operations rsc_ops = {
.write = rsc_ops_write,
};
static int __init rpm_smd_debugfs_init(void)
{
rpm_debugfs_dir = debugfs_create_dir("rpm_send_msg", NULL);
if (!rpm_debugfs_dir)
return -ENOMEM;
if (!debugfs_create_file("message", 0200, rpm_debugfs_dir, NULL,
&rsc_ops))
return -ENOMEM;
return 0;
}
late_initcall(rpm_smd_debugfs_init);
static void __exit rpm_smd_debugfs_exit(void)
{
debugfs_remove_recursive(rpm_debugfs_dir);
}
module_exit(rpm_smd_debugfs_exit);
MODULE_DESCRIPTION("RPM SMD Debug Driver");
MODULE_LICENSE("GPL v2");

2168
drivers/soc/qcom/rpm-smd.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,63 @@
/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#ifndef __ARCH_ARM_MACH_MSM_RPM_NOTIF_H
#define __ARCH_ARM_MACH_MSM_RPM_NOTIF_H
struct msm_rpm_notifier_data {
uint32_t rsc_type;
uint32_t rsc_id;
uint32_t key;
uint32_t size;
uint8_t *value;
};
/**
* msm_rpm_register_notifier - Register for sleep set notifications
*
* @nb - notifier block to register
*
* return 0 on success, errno on failure.
*/
int msm_rpm_register_notifier(struct notifier_block *nb);
/**
* msm_rpm_unregister_notifier - Unregister previously registered notifications
*
* @nb - notifier block to unregister
*
* return 0 on success, errno on failure.
*/
int msm_rpm_unregister_notifier(struct notifier_block *nb);
/**
* msm_rpm_enter_sleep - Notify RPM driver to prepare for entering sleep
*
* @bool - flag to enable print contents of sleep buffer.
* @cpumask - cpumask of next wakeup cpu
*
* return 0 on success errno on failure.
*/
int msm_rpm_enter_sleep(bool print, const struct cpumask *cpumask);
/**
* msm_rpm_exit_sleep - Notify RPM driver about resuming from power collapse
*/
void msm_rpm_exit_sleep(void);
/**
* msm_rpm_waiting_for_ack - Indicate if there is RPM message
* pending acknowledgment.
* returns true for pending messages and false otherwise
*/
bool msm_rpm_waiting_for_ack(void);
#endif /*__ARCH_ARM_MACH_MSM_RPM_NOTIF_H */

308
include/soc/qcom/rpm-smd.h Normal file
View file

@ -0,0 +1,308 @@
/* Copyright (c) 2012, 2014-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#ifndef __ARCH_ARM_MACH_MSM_RPM_SMD_H
#define __ARCH_ARM_MACH_MSM_RPM_SMD_H
/**
* enum msm_rpm_set - RPM enumerations for sleep/active set
* %MSM_RPM_CTX_SET_0: Set resource parameters for active mode.
* %MSM_RPM_CTX_SET_SLEEP: Set resource parameters for sleep.
*/
enum msm_rpm_set {
MSM_RPM_CTX_ACTIVE_SET,
MSM_RPM_CTX_SLEEP_SET,
};
struct msm_rpm_request;
struct msm_rpm_kvp {
uint32_t key;
uint32_t length;
uint8_t *data;
};
#ifdef CONFIG_MSM_RPM_SMD
/**
* msm_rpm_request() - Creates a parent element to identify the
* resource on the RPM, that stores the KVPs for different fields modified
* for a hardware resource
*
* @set: if the device is setting the active/sleep set parameter
* for the resource
* @rsc_type: unsigned 32 bit integer that identifies the type of the resource
* @rsc_id: unsigned 32 bit that uniquely identifies a resource within a type
* @num_elements: number of KVPs pairs associated with the resource
*
* returns pointer to a msm_rpm_request on success, NULL on error
*/
struct msm_rpm_request *msm_rpm_create_request(
enum msm_rpm_set set, uint32_t rsc_type,
uint32_t rsc_id, int num_elements);
/**
* msm_rpm_request_noirq() - Creates a parent element to identify the
* resource on the RPM, that stores the KVPs for different fields modified
* for a hardware resource. This function is similar to msm_rpm_create_request
* except that it has to be called with interrupts masked.
*
* @set: if the device is setting the active/sleep set parameter
* for the resource
* @rsc_type: unsigned 32 bit integer that identifies the type of the resource
* @rsc_id: unsigned 32 bit that uniquely identifies a resource within a type
* @num_elements: number of KVPs pairs associated with the resource
*
* returns pointer to a msm_rpm_request on success, NULL on error
*/
struct msm_rpm_request *msm_rpm_create_request_noirq(
enum msm_rpm_set set, uint32_t rsc_type,
uint32_t rsc_id, int num_elements);
/**
* msm_rpm_add_kvp_data() - Adds a Key value pair to a existing RPM resource.
*
* @handle: RPM resource handle to which the data should be appended
* @key: unsigned integer identify the parameter modified
* @data: byte array that contains the value corresponding to key.
* @size: size of data in bytes.
*
* returns 0 on success or errno
*/
int msm_rpm_add_kvp_data(struct msm_rpm_request *handle,
uint32_t key, const uint8_t *data, int size);
/**
* msm_rpm_add_kvp_data_noirq() - Adds a Key value pair to a existing RPM
* resource. This function is similar to msm_rpm_add_kvp_data except that it
* has to be called with interrupts masked.
*
* @handle: RPM resource handle to which the data should be appended
* @key: unsigned integer identify the parameter modified
* @data: byte array that contains the value corresponding to key.
* @size: size of data in bytes.
*
* returns 0 on success or errno
*/
int msm_rpm_add_kvp_data_noirq(struct msm_rpm_request *handle,
uint32_t key, const uint8_t *data, int size);
/** msm_rpm_free_request() - clean up the RPM request handle created with
* msm_rpm_create_request
*
* @handle: RPM resource handle to be cleared.
*/
void msm_rpm_free_request(struct msm_rpm_request *handle);
/**
* msm_rpm_send_request() - Send the RPM messages using SMD. The function
* assigns a message id before sending the data out to the RPM. RPM hardware
* uses the message id to acknowledge the messages.
*
* @handle: pointer to the msm_rpm_request for the resource being modified.
*
* returns non-zero message id on success and zero on a failed transaction.
* The drivers use message id to wait for ACK from RPM.
*/
int msm_rpm_send_request(struct msm_rpm_request *handle);
/**
* msm_rpm_send_request_noack() - Send the RPM messages using SMD. The function
* assigns a message id before sending the data out to the RPM. RPM hardware
* uses the message id to acknowledge the messages, but this API does not wait
* on the ACK for this message id and it does not add the message id to the wait
* list.
*
* @handle: pointer to the msm_rpm_request for the resource being modified.
*
* returns NULL on success and PTR_ERR on a failed transaction.
*/
void *msm_rpm_send_request_noack(struct msm_rpm_request *handle);
/**
* msm_rpm_send_request_noirq() - Send the RPM messages using SMD. The
* function assigns a message id before sending the data out to the RPM.
* RPM hardware uses the message id to acknowledge the messages. This function
* is similar to msm_rpm_send_request except that it has to be called with
* interrupts masked.
*
* @handle: pointer to the msm_rpm_request for the resource being modified.
*
* returns non-zero message id on success and zero on a failed transaction.
* The drivers use message id to wait for ACK from RPM.
*/
int msm_rpm_send_request_noirq(struct msm_rpm_request *handle);
/**
* msm_rpm_wait_for_ack() - A blocking call that waits for acknowledgment of
* a message from RPM.
*
* @msg_id: the return from msm_rpm_send_requests
*
* returns 0 on success or errno
*/
int msm_rpm_wait_for_ack(uint32_t msg_id);
/**
* msm_rpm_wait_for_ack_noirq() - A blocking call that waits for acknowledgment
* of a message from RPM. This function is similar to msm_rpm_wait_for_ack
* except that it has to be called with interrupts masked.
*
* @msg_id: the return from msm_rpm_send_request
*
* returns 0 on success or errno
*/
int msm_rpm_wait_for_ack_noirq(uint32_t msg_id);
/**
* msm_rpm_send_message() -Wrapper function for clients to send data given an
* array of key value pairs.
*
* @set: if the device is setting the active/sleep set parameter
* for the resource
* @rsc_type: unsigned 32 bit integer that identifies the type of the resource
* @rsc_id: unsigned 32 bit that uniquely identifies a resource within a type
* @kvp: array of KVP data.
* @nelem: number of KVPs pairs associated with the message.
*
* returns 0 on success and errno on failure.
*/
int msm_rpm_send_message(enum msm_rpm_set set, uint32_t rsc_type,
uint32_t rsc_id, struct msm_rpm_kvp *kvp, int nelems);
/**
* msm_rpm_send_message_noack() -Wrapper function for clients to send data
* given an array of key value pairs without waiting for ack.
*
* @set: if the device is setting the active/sleep set parameter
* for the resource
* @rsc_type: unsigned 32 bit integer that identifies the type of the resource
* @rsc_id: unsigned 32 bit that uniquely identifies a resource within a type
* @kvp: array of KVP data.
* @nelem: number of KVPs pairs associated with the message.
*
* returns NULL on success and PTR_ERR(errno) on failure.
*/
void *msm_rpm_send_message_noack(enum msm_rpm_set set, uint32_t rsc_type,
uint32_t rsc_id, struct msm_rpm_kvp *kvp, int nelems);
/**
* msm_rpm_send_message_noirq() -Wrapper function for clients to send data
* given an array of key value pairs. This function is similar to the
* msm_rpm_send_message() except that it has to be called with interrupts
* disabled. Clients should choose the irq version when possible for system
* performance.
*
* @set: if the device is setting the active/sleep set parameter
* for the resource
* @rsc_type: unsigned 32 bit integer that identifies the type of the resource
* @rsc_id: unsigned 32 bit that uniquely identifies a resource within a type
* @kvp: array of KVP data.
* @nelem: number of KVPs pairs associated with the message.
*
* returns 0 on success and errno on failure.
*/
int msm_rpm_send_message_noirq(enum msm_rpm_set set, uint32_t rsc_type,
uint32_t rsc_id, struct msm_rpm_kvp *kvp, int nelems);
/**
* msm_rpm_driver_init() - Initialization function that registers for a
* rpm platform driver.
*
* returns 0 on success.
*/
int __init msm_rpm_driver_init(void);
#else
static inline struct msm_rpm_request *msm_rpm_create_request(
enum msm_rpm_set set, uint32_t rsc_type,
uint32_t rsc_id, int num_elements)
{
return NULL;
}
static inline struct msm_rpm_request *msm_rpm_create_request_noirq(
enum msm_rpm_set set, uint32_t rsc_type,
uint32_t rsc_id, int num_elements)
{
return NULL;
}
static inline uint32_t msm_rpm_add_kvp_data(struct msm_rpm_request *handle,
uint32_t key, const uint8_t *data, int count)
{
return 0;
}
static inline uint32_t msm_rpm_add_kvp_data_noirq(
struct msm_rpm_request *handle, uint32_t key,
const uint8_t *data, int count)
{
return 0;
}
static inline void msm_rpm_free_request(struct msm_rpm_request *handle)
{
}
static inline int msm_rpm_send_request(struct msm_rpm_request *handle)
{
return 0;
}
static inline int msm_rpm_send_request_noirq(struct msm_rpm_request *handle)
{
return 0;
}
static inline void *msm_rpm_send_request_noack(struct msm_rpm_request *handle)
{
return NULL;
}
static inline int msm_rpm_send_message(enum msm_rpm_set set, uint32_t rsc_type,
uint32_t rsc_id, struct msm_rpm_kvp *kvp, int nelems)
{
return 0;
}
static inline int msm_rpm_send_message_noirq(enum msm_rpm_set set,
uint32_t rsc_type, uint32_t rsc_id, struct msm_rpm_kvp *kvp,
int nelems)
{
return 0;
}
static inline void *msm_rpm_send_message_noack(enum msm_rpm_set set,
uint32_t rsc_type, uint32_t rsc_id, struct msm_rpm_kvp *kvp,
int nelems)
{
return NULL;
}
static inline int msm_rpm_wait_for_ack(uint32_t msg_id)
{
return 0;
}
static inline int msm_rpm_wait_for_ack_noirq(uint32_t msg_id)
{
return 0;
}
static inline int __init msm_rpm_driver_init(void)
{
return 0;
}
#endif
#endif /*__ARCH_ARM_MACH_MSM_RPM_SMD_H*/

View file

@ -0,0 +1,111 @@
/* Copyright (c) 2012, 2014-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#undef TRACE_SYSTEM
#define TRACE_SYSTEM rpm_smd
#if !defined(_TRACE_RPM_SMD_H) || defined(TRACE_HEADER_MULTI_READ)
#define _TRACE_RPM_SMD_H
#include <linux/tracepoint.h>
TRACE_EVENT(rpm_smd_ack_recvd,
TP_PROTO(unsigned int irq, unsigned int msg_id, int errno),
TP_ARGS(irq, msg_id, errno),
TP_STRUCT__entry(
__field(int, irq)
__field(int, msg_id)
__field(int, errno)
),
TP_fast_assign(
__entry->irq = irq;
__entry->msg_id = msg_id;
__entry->errno = errno;
),
TP_printk("ctx:%s msg_id:%d errno:%08x",
__entry->irq ? "noslp" : "sleep",
__entry->msg_id,
__entry->errno)
);
TRACE_EVENT(rpm_smd_interrupt_notify,
TP_PROTO(char *dummy),
TP_ARGS(dummy),
TP_STRUCT__entry(
__field(char *, dummy)
),
TP_fast_assign(
__entry->dummy = dummy;
),
TP_printk("%s", __entry->dummy)
);
DECLARE_EVENT_CLASS(rpm_send_msg,
TP_PROTO(unsigned int msg_id, unsigned int rsc_type,
unsigned int rsc_id),
TP_ARGS(msg_id, rsc_type, rsc_id),
TP_STRUCT__entry(
__field(u32, msg_id)
__field(u32, rsc_type)
__field(u32, rsc_id)
__array(char, name, 5)
),
TP_fast_assign(
__entry->msg_id = msg_id;
__entry->name[4] = 0;
__entry->rsc_type = rsc_type;
__entry->rsc_id = rsc_id;
memcpy(__entry->name, &rsc_type, sizeof(uint32_t));
),
TP_printk("msg_id:%d, rsc_type:0x%08x(%s), rsc_id:0x%08x",
__entry->msg_id,
__entry->rsc_type, __entry->name,
__entry->rsc_id)
);
DEFINE_EVENT(rpm_send_msg, rpm_smd_sleep_set,
TP_PROTO(unsigned int msg_id, unsigned int rsc_type,
unsigned int rsc_id),
TP_ARGS(msg_id, rsc_type, rsc_id)
);
DEFINE_EVENT(rpm_send_msg, rpm_smd_send_sleep_set,
TP_PROTO(unsigned int msg_id, unsigned int rsc_type,
unsigned int rsc_id),
TP_ARGS(msg_id, rsc_type, rsc_id)
);
DEFINE_EVENT(rpm_send_msg, rpm_smd_send_active_set,
TP_PROTO(unsigned int msg_id, unsigned int rsc_type,
unsigned int rsc_id),
TP_ARGS(msg_id, rsc_type, rsc_id)
);
#endif
#define TRACE_INCLUDE_FILE trace_rpm_smd
#include <trace/define_trace.h>