summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2021-04-08 18:38:20 +0300
committerArnd Bergmann <arnd@arndb.de>2021-04-08 18:38:20 +0300
commit4be3f47e1bd5c9be4c4b95de5f3531f062a28a66 (patch)
tree8313eebb115927d91cde7e1e433426145c09f953 /include
parentba87f2009edb69fa81d344c55bcee518b0707c98 (diff)
parentd4f9dddd21f39395c62ea12d3d91239637d4805f (diff)
downloadlinux-4be3f47e1bd5c9be4c4b95de5f3531f062a28a66.tar.xz
Merge tag 'scmi-updates-5.13' of git://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux into arm/drivers
ARM SCMI updates for v5.13 The major and big addition this time is to support modularisation of individual SCMI protocols thus enabling to add support for vendors' custom SCMI protocol. This changes the interface provided by the SCMI driver to all the users of SCMI and hence involved changes in various other subsystem SCMI drivers. The change has been split with a bit of transient code to preserve bisectability and avoiding one big patch bomb changing all the users. This also includes SCMI IIO driver(pulled from IIO tree) and support for per-cpu DVFS. * tag 'scmi-updates-5.13' of git://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux: (41 commits) firmware: arm_scmi: Add dynamic scmi devices creation firmware: arm_scmi: Add protocol modularization support firmware: arm_scmi: Rename non devres notify_ops firmware: arm_scmi: Make notify_priv really private firmware: arm_scmi: Cleanup events registration transient code firmware: arm_scmi: Cleanup unused core transfer helper wrappers firmware: arm_scmi: Cleanup legacy protocol init code firmware: arm_scmi: Make references to handle const firmware: arm_scmi: Remove legacy scmi_voltage_ops protocol interface regulator: scmi: Port driver to the new scmi_voltage_proto_ops interface firmware: arm_scmi: Port voltage protocol to new protocols interface firmware: arm_scmi: Port systempower protocol to new protocols interface firmware: arm_scmi: Remove legacy scmi_sensor_ops protocol interface iio/scmi: Port driver to the new scmi_sensor_proto_ops interface hwmon: (scmi) port driver to the new scmi_sensor_proto_ops interface firmware: arm_scmi: Port sensor protocol to new protocols interface firmware: arm_scmi: Remove legacy scmi_reset_ops protocol interface reset: reset-scmi: Port driver to the new scmi_reset_proto_ops interface firmware: arm_scmi: Port reset protocol to new protocols interface firmware: arm_scmi: Remove legacy scmi_clk_ops protocol interface ... Link: https://lore.kernel.org/r/20210331100657.ilu63i4swnr3zp4e@bogus Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'include')
-rw-r--r--include/linux/scmi_protocol.h200
1 files changed, 102 insertions, 98 deletions
diff --git a/include/linux/scmi_protocol.h b/include/linux/scmi_protocol.h
index ecb3aad1a964..79d0a1237e6c 100644
--- a/include/linux/scmi_protocol.h
+++ b/include/linux/scmi_protocol.h
@@ -2,7 +2,7 @@
/*
* SCMI Message Protocol driver header
*
- * Copyright (C) 2018 ARM Ltd.
+ * Copyright (C) 2018-2021 ARM Ltd.
*/
#ifndef _LINUX_SCMI_PROTOCOL_H
@@ -57,9 +57,11 @@ struct scmi_clock_info {
};
struct scmi_handle;
+struct scmi_device;
+struct scmi_protocol_handle;
/**
- * struct scmi_clk_ops - represents the various operations provided
+ * struct scmi_clk_proto_ops - represents the various operations provided
* by SCMI Clock Protocol
*
* @count_get: get the count of clocks provided by SCMI
@@ -69,21 +71,21 @@ struct scmi_handle;
* @enable: enables the specified clock
* @disable: disables the specified clock
*/
-struct scmi_clk_ops {
- int (*count_get)(const struct scmi_handle *handle);
+struct scmi_clk_proto_ops {
+ int (*count_get)(const struct scmi_protocol_handle *ph);
const struct scmi_clock_info *(*info_get)
- (const struct scmi_handle *handle, u32 clk_id);
- int (*rate_get)(const struct scmi_handle *handle, u32 clk_id,
+ (const struct scmi_protocol_handle *ph, u32 clk_id);
+ int (*rate_get)(const struct scmi_protocol_handle *ph, u32 clk_id,
u64 *rate);
- int (*rate_set)(const struct scmi_handle *handle, u32 clk_id,
+ int (*rate_set)(const struct scmi_protocol_handle *ph, u32 clk_id,
u64 rate);
- int (*enable)(const struct scmi_handle *handle, u32 clk_id);
- int (*disable)(const struct scmi_handle *handle, u32 clk_id);
+ int (*enable)(const struct scmi_protocol_handle *ph, u32 clk_id);
+ int (*disable)(const struct scmi_protocol_handle *ph, u32 clk_id);
};
/**
- * struct scmi_perf_ops - represents the various operations provided
+ * struct scmi_perf_proto_ops - represents the various operations provided
* by SCMI Performance Protocol
*
* @limits_set: sets limits on the performance level of a domain
@@ -100,33 +102,33 @@ struct scmi_clk_ops {
* @est_power_get: gets the estimated power cost for a given performance domain
* at a given frequency
*/
-struct scmi_perf_ops {
- int (*limits_set)(const struct scmi_handle *handle, u32 domain,
+struct scmi_perf_proto_ops {
+ int (*limits_set)(const struct scmi_protocol_handle *ph, u32 domain,
u32 max_perf, u32 min_perf);
- int (*limits_get)(const struct scmi_handle *handle, u32 domain,
+ int (*limits_get)(const struct scmi_protocol_handle *ph, u32 domain,
u32 *max_perf, u32 *min_perf);
- int (*level_set)(const struct scmi_handle *handle, u32 domain,
+ int (*level_set)(const struct scmi_protocol_handle *ph, u32 domain,
u32 level, bool poll);
- int (*level_get)(const struct scmi_handle *handle, u32 domain,
+ int (*level_get)(const struct scmi_protocol_handle *ph, u32 domain,
u32 *level, bool poll);
int (*device_domain_id)(struct device *dev);
- int (*transition_latency_get)(const struct scmi_handle *handle,
+ int (*transition_latency_get)(const struct scmi_protocol_handle *ph,
struct device *dev);
- int (*device_opps_add)(const struct scmi_handle *handle,
+ int (*device_opps_add)(const struct scmi_protocol_handle *ph,
struct device *dev);
- int (*freq_set)(const struct scmi_handle *handle, u32 domain,
+ int (*freq_set)(const struct scmi_protocol_handle *ph, u32 domain,
unsigned long rate, bool poll);
- int (*freq_get)(const struct scmi_handle *handle, u32 domain,
+ int (*freq_get)(const struct scmi_protocol_handle *ph, u32 domain,
unsigned long *rate, bool poll);
- int (*est_power_get)(const struct scmi_handle *handle, u32 domain,
+ int (*est_power_get)(const struct scmi_protocol_handle *ph, u32 domain,
unsigned long *rate, unsigned long *power);
- bool (*fast_switch_possible)(const struct scmi_handle *handle,
+ bool (*fast_switch_possible)(const struct scmi_protocol_handle *ph,
struct device *dev);
- bool (*power_scale_mw_get)(const struct scmi_handle *handle);
+ bool (*power_scale_mw_get)(const struct scmi_protocol_handle *ph);
};
/**
- * struct scmi_power_ops - represents the various operations provided
+ * struct scmi_power_proto_ops - represents the various operations provided
* by SCMI Power Protocol
*
* @num_domains_get: get the count of power domains provided by SCMI
@@ -134,9 +136,9 @@ struct scmi_perf_ops {
* @state_set: sets the power state of a power domain
* @state_get: gets the power state of a power domain
*/
-struct scmi_power_ops {
- int (*num_domains_get)(const struct scmi_handle *handle);
- char *(*name_get)(const struct scmi_handle *handle, u32 domain);
+struct scmi_power_proto_ops {
+ int (*num_domains_get)(const struct scmi_protocol_handle *ph);
+ char *(*name_get)(const struct scmi_protocol_handle *ph, u32 domain);
#define SCMI_POWER_STATE_TYPE_SHIFT 30
#define SCMI_POWER_STATE_ID_MASK (BIT(28) - 1)
#define SCMI_POWER_STATE_PARAM(type, id) \
@@ -144,9 +146,9 @@ struct scmi_power_ops {
((id) & SCMI_POWER_STATE_ID_MASK))
#define SCMI_POWER_STATE_GENERIC_ON SCMI_POWER_STATE_PARAM(0, 0)
#define SCMI_POWER_STATE_GENERIC_OFF SCMI_POWER_STATE_PARAM(1, 0)
- int (*state_set)(const struct scmi_handle *handle, u32 domain,
+ int (*state_set)(const struct scmi_protocol_handle *ph, u32 domain,
u32 state);
- int (*state_get)(const struct scmi_handle *handle, u32 domain,
+ int (*state_get)(const struct scmi_protocol_handle *ph, u32 domain,
u32 *state);
};
@@ -429,7 +431,7 @@ enum scmi_sensor_class {
};
/**
- * struct scmi_sensor_ops - represents the various operations provided
+ * struct scmi_sensor_proto_ops - represents the various operations provided
* by SCMI Sensor Protocol
*
* @count_get: get the count of sensors provided by SCMI
@@ -444,25 +446,25 @@ enum scmi_sensor_class {
* @config_get: Get sensor current configuration
* @config_set: Set sensor current configuration
*/
-struct scmi_sensor_ops {
- int (*count_get)(const struct scmi_handle *handle);
+struct scmi_sensor_proto_ops {
+ int (*count_get)(const struct scmi_protocol_handle *ph);
const struct scmi_sensor_info *(*info_get)
- (const struct scmi_handle *handle, u32 sensor_id);
- int (*trip_point_config)(const struct scmi_handle *handle,
+ (const struct scmi_protocol_handle *ph, u32 sensor_id);
+ int (*trip_point_config)(const struct scmi_protocol_handle *ph,
u32 sensor_id, u8 trip_id, u64 trip_value);
- int (*reading_get)(const struct scmi_handle *handle, u32 sensor_id,
+ int (*reading_get)(const struct scmi_protocol_handle *ph, u32 sensor_id,
u64 *value);
- int (*reading_get_timestamped)(const struct scmi_handle *handle,
+ int (*reading_get_timestamped)(const struct scmi_protocol_handle *ph,
u32 sensor_id, u8 count,
struct scmi_sensor_reading *readings);
- int (*config_get)(const struct scmi_handle *handle,
+ int (*config_get)(const struct scmi_protocol_handle *ph,
u32 sensor_id, u32 *sensor_config);
- int (*config_set)(const struct scmi_handle *handle,
+ int (*config_set)(const struct scmi_protocol_handle *ph,
u32 sensor_id, u32 sensor_config);
};
/**
- * struct scmi_reset_ops - represents the various operations provided
+ * struct scmi_reset_proto_ops - represents the various operations provided
* by SCMI Reset Protocol
*
* @num_domains_get: get the count of reset domains provided by SCMI
@@ -472,13 +474,13 @@ struct scmi_sensor_ops {
* @assert: explicitly assert reset signal of the specified reset domain
* @deassert: explicitly deassert reset signal of the specified reset domain
*/
-struct scmi_reset_ops {
- int (*num_domains_get)(const struct scmi_handle *handle);
- char *(*name_get)(const struct scmi_handle *handle, u32 domain);
- int (*latency_get)(const struct scmi_handle *handle, u32 domain);
- int (*reset)(const struct scmi_handle *handle, u32 domain);
- int (*assert)(const struct scmi_handle *handle, u32 domain);
- int (*deassert)(const struct scmi_handle *handle, u32 domain);
+struct scmi_reset_proto_ops {
+ int (*num_domains_get)(const struct scmi_protocol_handle *ph);
+ char *(*name_get)(const struct scmi_protocol_handle *ph, u32 domain);
+ int (*latency_get)(const struct scmi_protocol_handle *ph, u32 domain);
+ int (*reset)(const struct scmi_protocol_handle *ph, u32 domain);
+ int (*assert)(const struct scmi_protocol_handle *ph, u32 domain);
+ int (*deassert)(const struct scmi_protocol_handle *ph, u32 domain);
};
/**
@@ -513,7 +515,7 @@ struct scmi_voltage_info {
};
/**
- * struct scmi_voltage_ops - represents the various operations provided
+ * struct scmi_voltage_proto_ops - represents the various operations provided
* by SCMI Voltage Protocol
*
* @num_domains_get: get the count of voltage domains provided by SCMI
@@ -523,27 +525,31 @@ struct scmi_voltage_info {
* @level_set: set the voltage level for the specified domain
* @level_get: get the voltage level of the specified domain
*/
-struct scmi_voltage_ops {
- int (*num_domains_get)(const struct scmi_handle *handle);
+struct scmi_voltage_proto_ops {
+ int (*num_domains_get)(const struct scmi_protocol_handle *ph);
const struct scmi_voltage_info __must_check *(*info_get)
- (const struct scmi_handle *handle, u32 domain_id);
- int (*config_set)(const struct scmi_handle *handle, u32 domain_id,
+ (const struct scmi_protocol_handle *ph, u32 domain_id);
+ int (*config_set)(const struct scmi_protocol_handle *ph, u32 domain_id,
u32 config);
#define SCMI_VOLTAGE_ARCH_STATE_OFF 0x0
#define SCMI_VOLTAGE_ARCH_STATE_ON 0x7
- int (*config_get)(const struct scmi_handle *handle, u32 domain_id,
+ int (*config_get)(const struct scmi_protocol_handle *ph, u32 domain_id,
u32 *config);
- int (*level_set)(const struct scmi_handle *handle, u32 domain_id,
+ int (*level_set)(const struct scmi_protocol_handle *ph, u32 domain_id,
u32 flags, s32 volt_uV);
- int (*level_get)(const struct scmi_handle *handle, u32 domain_id,
+ int (*level_get)(const struct scmi_protocol_handle *ph, u32 domain_id,
s32 *volt_uV);
};
/**
* struct scmi_notify_ops - represents notifications' operations provided by
* SCMI core
- * @register_event_notifier: Register a notifier_block for the requested event
- * @unregister_event_notifier: Unregister a notifier_block for the requested
+ * @devm_event_notifier_register: Managed registration of a notifier_block for
+ * the requested event
+ * @devm_event_notifier_unregister: Managed unregistration of a notifier_block
+ * for the requested event
+ * @event_notifier_register: Register a notifier_block for the requested event
+ * @event_notifier_unregister: Unregister a notifier_block for the requested
* event
*
* A user can register/unregister its own notifier_block against the wanted
@@ -551,7 +557,9 @@ struct scmi_voltage_ops {
* tuple: (proto_id, evt_id, src_id) using the provided register/unregister
* interface where:
*
- * @handle: The handle identifying the platform instance to use
+ * @sdev: The scmi_device to use when calling the devres managed ops devm_
+ * @handle: The handle identifying the platform instance to use, when not
+ * calling the managed ops devm_
* @proto_id: The protocol ID as in SCMI Specification
* @evt_id: The message ID of the desired event as in SCMI Specification
* @src_id: A pointer to the desired source ID if different sources are
@@ -574,11 +582,21 @@ struct scmi_voltage_ops {
* @report: A custom struct describing the specific event delivered
*/
struct scmi_notify_ops {
- int (*register_event_notifier)(const struct scmi_handle *handle,
- u8 proto_id, u8 evt_id, u32 *src_id,
+ int (*devm_event_notifier_register)(struct scmi_device *sdev,
+ u8 proto_id, u8 evt_id,
+ const u32 *src_id,
+ struct notifier_block *nb);
+ int (*devm_event_notifier_unregister)(struct scmi_device *sdev,
+ u8 proto_id, u8 evt_id,
+ const u32 *src_id,
+ struct notifier_block *nb);
+ int (*event_notifier_register)(const struct scmi_handle *handle,
+ u8 proto_id, u8 evt_id,
+ const u32 *src_id,
struct notifier_block *nb);
- int (*unregister_event_notifier)(const struct scmi_handle *handle,
- u8 proto_id, u8 evt_id, u32 *src_id,
+ int (*event_notifier_unregister)(const struct scmi_handle *handle,
+ u8 proto_id, u8 evt_id,
+ const u32 *src_id,
struct notifier_block *nb);
};
@@ -587,47 +605,21 @@ struct scmi_notify_ops {
*
* @dev: pointer to the SCMI device
* @version: pointer to the structure containing SCMI version information
- * @power_ops: pointer to set of power protocol operations
- * @perf_ops: pointer to set of performance protocol operations
- * @clk_ops: pointer to set of clock protocol operations
- * @sensor_ops: pointer to set of sensor protocol operations
- * @reset_ops: pointer to set of reset protocol operations
- * @voltage_ops: pointer to set of voltage protocol operations
+ * @devm_protocol_get: devres managed method to acquire a protocol and get specific
+ * operations and a dedicated protocol handler
+ * @devm_protocol_put: devres managed method to release a protocol
* @notify_ops: pointer to set of notifications related operations
- * @perf_priv: pointer to private data structure specific to performance
- * protocol(for internal use only)
- * @clk_priv: pointer to private data structure specific to clock
- * protocol(for internal use only)
- * @power_priv: pointer to private data structure specific to power
- * protocol(for internal use only)
- * @sensor_priv: pointer to private data structure specific to sensors
- * protocol(for internal use only)
- * @reset_priv: pointer to private data structure specific to reset
- * protocol(for internal use only)
- * @voltage_priv: pointer to private data structure specific to voltage
- * protocol(for internal use only)
- * @notify_priv: pointer to private data structure specific to notifications
- * (for internal use only)
*/
struct scmi_handle {
struct device *dev;
struct scmi_revision_info *version;
- const struct scmi_perf_ops *perf_ops;
- const struct scmi_clk_ops *clk_ops;
- const struct scmi_power_ops *power_ops;
- const struct scmi_sensor_ops *sensor_ops;
- const struct scmi_reset_ops *reset_ops;
- const struct scmi_voltage_ops *voltage_ops;
+
+ const void __must_check *
+ (*devm_protocol_get)(struct scmi_device *sdev, u8 proto,
+ struct scmi_protocol_handle **ph);
+ void (*devm_protocol_put)(struct scmi_device *sdev, u8 proto);
+
const struct scmi_notify_ops *notify_ops;
- /* for protocol internal use */
- void *perf_priv;
- void *clk_priv;
- void *power_priv;
- void *sensor_priv;
- void *reset_priv;
- void *voltage_priv;
- void *notify_priv;
- void *system_priv;
};
enum scmi_std_protocol {
@@ -712,9 +704,21 @@ static inline void scmi_driver_unregister(struct scmi_driver *driver) {}
#define module_scmi_driver(__scmi_driver) \
module_driver(__scmi_driver, scmi_register, scmi_unregister)
-typedef int (*scmi_prot_init_fn_t)(struct scmi_handle *);
-int scmi_protocol_register(int protocol_id, scmi_prot_init_fn_t fn);
-void scmi_protocol_unregister(int protocol_id);
+/**
+ * module_scmi_protocol() - Helper macro for registering a scmi protocol
+ * @__scmi_protocol: scmi_protocol structure
+ *
+ * Helper macro for scmi drivers to set up proper module init / exit
+ * functions. Replaces module_init() and module_exit() and keeps people from
+ * printing pointless things to the kernel log when their driver is loaded.
+ */
+#define module_scmi_protocol(__scmi_protocol) \
+ module_driver(__scmi_protocol, \
+ scmi_protocol_register, scmi_protocol_unregister)
+
+struct scmi_protocol;
+int scmi_protocol_register(const struct scmi_protocol *proto);
+void scmi_protocol_unregister(const struct scmi_protocol *proto);
/* SCMI Notification API - Custom Event Reports */
enum scmi_notification_events {