Skip to content

Commit 2526112

Browse files
committed
Merge tag 'scmi-fixes-5.14' of git://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux into arm/fixes
ARM SCMI fixes for v5.14 A small set of fixes: - adding check for presence of probe while registering the driver to prevent NULL pointer access - dropping the duplicate check as the driver core already takes care of it - fix for possible scmi_linux_errmap buffer overflow - fix to avoid sensor message structure padding - fix the range check for the maximum number of pending SCMI messages - fix for various kernel-doc warnings * tag 'scmi-fixes-5.14' of git://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux: firmware: arm_scmi: Fix range check for the maximum number of pending messages firmware: arm_scmi: Avoid padding in sensor message structure firmware: arm_scmi: Fix kernel doc warnings about return values firmware: arm_scpi: Fix kernel doc warnings firmware: arm_scmi: Fix kernel doc warnings firmware: arm_scmi: Fix possible scmi_linux_errmap buffer overflow firmware: arm_scmi: Ensure drivers provide a probe function firmware: arm_scmi: Simplify device probe function on the bus Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Arnd Bergmann <[email protected]>
2 parents d28912d + bdb8742 commit 2526112

File tree

6 files changed

+37
-17
lines changed

6 files changed

+37
-17
lines changed

drivers/firmware/arm_scmi/bus.c

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -104,11 +104,6 @@ static int scmi_dev_probe(struct device *dev)
104104
{
105105
struct scmi_driver *scmi_drv = to_scmi_driver(dev->driver);
106106
struct scmi_device *scmi_dev = to_scmi_dev(dev);
107-
const struct scmi_device_id *id;
108-
109-
id = scmi_dev_match_id(scmi_dev, scmi_drv);
110-
if (!id)
111-
return -ENODEV;
112107

113108
if (!scmi_dev->handle)
114109
return -EPROBE_DEFER;
@@ -139,6 +134,9 @@ int scmi_driver_register(struct scmi_driver *driver, struct module *owner,
139134
{
140135
int retval;
141136

137+
if (!driver->probe)
138+
return -EINVAL;
139+
142140
retval = scmi_protocol_device_request(driver->id_table);
143141
if (retval)
144142
return retval;

drivers/firmware/arm_scmi/driver.c

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ enum scmi_error_codes {
4747
SCMI_ERR_GENERIC = -8, /* Generic Error */
4848
SCMI_ERR_HARDWARE = -9, /* Hardware Error */
4949
SCMI_ERR_PROTOCOL = -10,/* Protocol Error */
50-
SCMI_ERR_MAX
5150
};
5251

5352
/* List of all SCMI devices active in system */
@@ -166,8 +165,10 @@ static const int scmi_linux_errmap[] = {
166165

167166
static inline int scmi_to_linux_errno(int errno)
168167
{
169-
if (errno < SCMI_SUCCESS && errno > SCMI_ERR_MAX)
170-
return scmi_linux_errmap[-errno];
168+
int err_idx = -errno;
169+
170+
if (err_idx >= SCMI_SUCCESS && err_idx < ARRAY_SIZE(scmi_linux_errmap))
171+
return scmi_linux_errmap[err_idx];
171172
return -EIO;
172173
}
173174

@@ -1025,8 +1026,9 @@ static int __scmi_xfer_info_init(struct scmi_info *sinfo,
10251026
const struct scmi_desc *desc = sinfo->desc;
10261027

10271028
/* Pre-allocated messages, no more than what hdr.seq can support */
1028-
if (WARN_ON(desc->max_msg >= MSG_TOKEN_MAX)) {
1029-
dev_err(dev, "Maximum message of %d exceeds supported %ld\n",
1029+
if (WARN_ON(!desc->max_msg || desc->max_msg > MSG_TOKEN_MAX)) {
1030+
dev_err(dev,
1031+
"Invalid maximum messages %d, not in range [1 - %lu]\n",
10301032
desc->max_msg, MSG_TOKEN_MAX);
10311033
return -EINVAL;
10321034
}
@@ -1137,6 +1139,8 @@ scmi_txrx_setup(struct scmi_info *info, struct device *dev, int prot_id)
11371139
* @proto_id and @name: if device was still not existent it is created as a
11381140
* child of the specified SCMI instance @info and its transport properly
11391141
* initialized as usual.
1142+
*
1143+
* Return: A properly initialized scmi device, NULL otherwise.
11401144
*/
11411145
static inline struct scmi_device *
11421146
scmi_get_protocol_device(struct device_node *np, struct scmi_info *info,

drivers/firmware/arm_scmi/notify.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1457,6 +1457,8 @@ static void scmi_devm_release_notifier(struct device *dev, void *res)
14571457
*
14581458
* Generic devres managed helper to register a notifier_block against a
14591459
* protocol event.
1460+
*
1461+
* Return: 0 on Success
14601462
*/
14611463
static int scmi_devm_notifier_register(struct scmi_device *sdev,
14621464
u8 proto_id, u8 evt_id,
@@ -1523,6 +1525,8 @@ static int scmi_devm_notifier_match(struct device *dev, void *res, void *data)
15231525
* Generic devres managed helper to explicitly un-register a notifier_block
15241526
* against a protocol event, which was previously registered using the above
15251527
* @scmi_devm_notifier_register.
1528+
*
1529+
* Return: 0 on Success
15261530
*/
15271531
static int scmi_devm_notifier_unregister(struct scmi_device *sdev,
15281532
u8 proto_id, u8 evt_id,

drivers/firmware/arm_scmi/sensors.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,8 @@ struct scmi_msg_sensor_reading_get {
166166

167167
struct scmi_resp_sensor_reading_complete {
168168
__le32 id;
169-
__le64 readings;
169+
__le32 readings_low;
170+
__le32 readings_high;
170171
};
171172

172173
struct scmi_sensor_reading_resp {
@@ -717,7 +718,8 @@ static int scmi_sensor_reading_get(const struct scmi_protocol_handle *ph,
717718

718719
resp = t->rx.buf;
719720
if (le32_to_cpu(resp->id) == sensor_id)
720-
*value = get_unaligned_le64(&resp->readings);
721+
*value =
722+
get_unaligned_le64(&resp->readings_low);
721723
else
722724
ret = -EPROTO;
723725
}

include/linux/scmi_protocol.h

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,10 @@ struct scmi_clk_proto_ops {
101101
* to sustained performance level mapping
102102
* @est_power_get: gets the estimated power cost for a given performance domain
103103
* at a given frequency
104+
* @fast_switch_possible: indicates if fast DVFS switching is possible or not
105+
* for a given device
106+
* @power_scale_mw_get: indicates if the power values provided are in milliWatts
107+
* or in some other (abstract) scale
104108
*/
105109
struct scmi_perf_proto_ops {
106110
int (*limits_set)(const struct scmi_protocol_handle *ph, u32 domain,
@@ -153,7 +157,7 @@ struct scmi_power_proto_ops {
153157
};
154158

155159
/**
156-
* scmi_sensor_reading - represent a timestamped read
160+
* struct scmi_sensor_reading - represent a timestamped read
157161
*
158162
* Used by @reading_get_timestamped method.
159163
*
@@ -167,7 +171,7 @@ struct scmi_sensor_reading {
167171
};
168172

169173
/**
170-
* scmi_range_attrs - specifies a sensor or axis values' range
174+
* struct scmi_range_attrs - specifies a sensor or axis values' range
171175
* @min_range: The minimum value which can be represented by the sensor/axis.
172176
* @max_range: The maximum value which can be represented by the sensor/axis.
173177
*/
@@ -177,7 +181,7 @@ struct scmi_range_attrs {
177181
};
178182

179183
/**
180-
* scmi_sensor_axis_info - describes one sensor axes
184+
* struct scmi_sensor_axis_info - describes one sensor axes
181185
* @id: The axes ID.
182186
* @type: Axes type. Chosen amongst one of @enum scmi_sensor_class.
183187
* @scale: Power-of-10 multiplier applied to the axis unit.
@@ -205,8 +209,8 @@ struct scmi_sensor_axis_info {
205209
};
206210

207211
/**
208-
* scmi_sensor_intervals_info - describes number and type of available update
209-
* intervals
212+
* struct scmi_sensor_intervals_info - describes number and type of available
213+
* update intervals
210214
* @segmented: Flag for segmented intervals' representation. When True there
211215
* will be exactly 3 intervals in @desc, with each entry
212216
* representing a member of a segment in this order:

include/linux/scpi_protocol.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,14 @@ struct scpi_sensor_info {
5151
* OPP is an index to the list return by @dvfs_get_info
5252
* @dvfs_get_info: returns the DVFS capabilities of the given power
5353
* domain. It includes the OPP list and the latency information
54+
* @device_domain_id: gets the scpi domain id for a given device
55+
* @get_transition_latency: gets the DVFS transition latency for a given device
56+
* @add_opps_to_device: adds all the OPPs for a given device
57+
* @sensor_get_capability: get the list of capabilities for the sensors
58+
* @sensor_get_info: get the information of the specified sensor
59+
* @sensor_get_value: gets the current value of the sensor
60+
* @device_get_power_state: gets the power state of a power domain
61+
* @device_set_power_state: sets the power state of a power domain
5462
*/
5563
struct scpi_ops {
5664
u32 (*get_version)(void);

0 commit comments

Comments
 (0)