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:
parent
d9961b39a1
commit
43c1be7e52
9 changed files with 3012 additions and 0 deletions
157
Documentation/arm/msm/rpm.txt
Normal file
157
Documentation/arm/msm/rpm.txt
Normal 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.
|
||||
41
Documentation/devicetree/bindings/arm/msm/rpm-smd.txt
Normal file
41
Documentation/devicetree/bindings/arm/msm/rpm-smd.txt
Normal 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";
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
151
drivers/soc/qcom/rpm-smd-debug.c
Normal file
151
drivers/soc/qcom/rpm-smd-debug.c
Normal 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
2168
drivers/soc/qcom/rpm-smd.c
Normal file
File diff suppressed because it is too large
Load diff
63
include/soc/qcom/rpm-notifier.h
Normal file
63
include/soc/qcom/rpm-notifier.h
Normal 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
308
include/soc/qcom/rpm-smd.h
Normal 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*/
|
||||
111
include/trace/events/trace_rpm_smd.h
Normal file
111
include/trace/events/trace_rpm_smd.h
Normal 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>
|
||||
Loading…
Reference in a new issue