mirror of
https://github.com/torvalds/linux.git
synced 2026-05-22 22:22:08 +02:00
Arm SCMI firmware driver fixes for v5.19
Few more fixes to address:
1. Issue reported on Juno with HDLCD clock which turned out to be yet
another firmware issue. The firmware is not conformant to the spec and
we now have to workaround as this may be copied to other platforms as
well. The spec expects to return size of 3 for a range clock rate
description while the firmware returns 1. We have other ways to validate
all the 3 entries the driver reads are polpulated and we use the same
to workaround this firmware bug.
2. Optee transport not setting the correct reponse length which is similar
to the one reported earlier on Rockchip platform.
3. Drop the usage of the deprecated ida_simple_{get,remove} and migrate to the
ida_{alloc,free}
-----BEGIN PGP SIGNATURE-----
iQIzBAABCAAdFiEEunHlEgbzHrJD3ZPhAEG6vDF+4pgFAmK6/jsACgkQAEG6vDF+
4phDrBAAqGFJUmb34QqfKBhc9JtPIUUNvdHaxTDXotiokcGQXXZ7Ckx+F5sRTcYE
xgFijjc80Rl5YpwTCCoSK5Kp9zmAAGycaZjKpxoHyNoXmctewS71pzZix+JLzJgG
YZnQdHhdeXntH/7cKeJzE08BqzJDKeh2e3tMi3uCfZi+Uj5X4qMBj547in30E0BX
lDxviE85xnKQYEGP7nbTZGjMrLjqpjehfj6CQrN3TbtIoAcad7lCEXY5l0cE9PF+
N4x7kEGnlzUbi1dtLiyVBYU9OkA0wo3m4KAnughipvzfUm5RXKRTacaVsOGB2Mm4
fesGnlC812XPSEcMnqqaY/ruPnVbPE8RtXx2FV1xoVlAQuyQqc97cDr/s7INX8aG
FaPUHXBH63rga0zD6I8xVJ7zbzYZdZfhFY3WSO9ntONZtcL9F5YSrokthmlV0mWq
+mmqb1fbvkb6Ym+rCtVCrgmsqJTgMDNYspDPl79EuycmH/eh1KzSPRrlQckrSbgK
2KkryADrmbD0d3nQLb/AgWyfSbXFF+fbEh3oZm1xhSCL+bE+8qjVsIOVTfnz6jo/
OdensXXdF43OsDQPPNSHijPe0LYexpSR3hVHphywZ/+aNOJ6h9e98O6DH93mdMqQ
gmSbw16afKZpmfwyn95k1O6sBXj+b428CIodPoWPHkTC4S0v6T4=
=xRfp
-----END PGP SIGNATURE-----
gpgsig -----BEGIN PGP SIGNATURE-----
iQIzBAABCgAdFiEEo6/YBQwIrVS28WGKmmx57+YAGNkFAmK/WEgACgkQmmx57+YA
GNnx9g/+O3D/doxMRf6l3jRzG65tHU7IDiMt0yiTq1MOxl8LNDPfN4bC33+ehrLz
4QkHZOpN65wrWt4lRsK1wyUFLCNxFrUu0slOaX0YxikgUq+MSRjSl4mf9+WePGf7
dm7p1CzAxD33iNz5FvdHqu29SQ+gWFkIX0f34+q8xDwd+YhlXYWDIgZinDjWJhvp
nuBqJ6vjT3HkMqemKc2XE3HY38bGpT1GSdh7DUNtJxZUG5hMCw5+j8OSJI3GQiYh
W0f8KvWVnFMXP953EwNjL6C5QTahm+CxPne04k0yuo9MdVGmr3tHkNy3PyTZKYqK
b/GjaLvvtdj5+7GfgPWFCIP3gcHX7WoJWI07xqN5Xrj04CTW/6I3QnleVn5g24h2
ao5h/fX+u6Zed+SPPiLfemrOQRZK/h31vok1Oh6l9UALqYjvmzaG6rsKDp6JXNB4
1wzc/1Gy2RLaI4QZhM7ypCrBpbiHiA3utz8j7/42eO267yN3FhqMgeFsSrcdC3iE
ubexX23Tbu6yK9BsL5QDjF8b18SHR4NKxofTKAayTa/CELTWmDQ8ZSpWGZ5h4MwF
N/UhtCAXYOSYyZox31hzc47zc4iFq0StgMlElZpa76jb3zNqmctBnYTRjQOFEBIm
0U5128TphuBZF+a08/T6nIEIHhY4T7EcnHo6A6vkVPwWTmEwsDY=
=sgSb
-----END PGP SIGNATURE-----
Merge tag 'scmi-fixes-5.19-2' of git://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux into arm/fixes
Arm SCMI firmware driver fixes for v5.19
Few more fixes to address:
1. Issue reported on Juno with HDLCD clock which turned out to be yet
another firmware issue. The firmware is not conformant to the spec and
we now have to workaround as this may be copied to other platforms as
well. The spec expects to return size of 3 for a range clock rate
description while the firmware returns 1. We have other ways to validate
all the 3 entries the driver reads are polpulated and we use the same
to workaround this firmware bug.
2. Optee transport not setting the correct reponse length which is similar
to the one reported earlier on Rockchip platform.
3. Drop the usage of the deprecated ida_simple_{get,remove} and migrate to the
ida_{alloc,free}
* tag 'scmi-fixes-5.19-2' of git://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux:
firmware: arm_scmi: Remove usage of the deprecated ida_simple_xxx API
firmware: arm_scmi: Fix response size warning for OPTEE transport
firmware: arm_scmi: Relax CLOCK_DESCRIBE_RATES out-of-spec checks
Link: https://lore.kernel.org/r/20220628133315.699803-1-sudeep.holla@arm.com
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
This commit is contained in:
commit
d95ce66d4c
|
|
@ -181,7 +181,7 @@ scmi_device_create(struct device_node *np, struct device *parent, int protocol,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
id = ida_simple_get(&scmi_bus_id, 1, 0, GFP_KERNEL);
|
||||
id = ida_alloc_min(&scmi_bus_id, 1, GFP_KERNEL);
|
||||
if (id < 0) {
|
||||
kfree_const(scmi_dev->name);
|
||||
kfree(scmi_dev);
|
||||
|
|
@ -204,7 +204,7 @@ scmi_device_create(struct device_node *np, struct device *parent, int protocol,
|
|||
put_dev:
|
||||
kfree_const(scmi_dev->name);
|
||||
put_device(&scmi_dev->dev);
|
||||
ida_simple_remove(&scmi_bus_id, id);
|
||||
ida_free(&scmi_bus_id, id);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -212,7 +212,7 @@ void scmi_device_destroy(struct scmi_device *scmi_dev)
|
|||
{
|
||||
kfree_const(scmi_dev->name);
|
||||
scmi_handle_put(scmi_dev->handle);
|
||||
ida_simple_remove(&scmi_bus_id, scmi_dev->id);
|
||||
ida_free(&scmi_bus_id, scmi_dev->id);
|
||||
device_unregister(&scmi_dev->dev);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -194,6 +194,7 @@ static int rate_cmp_func(const void *_r1, const void *_r2)
|
|||
}
|
||||
|
||||
struct scmi_clk_ipriv {
|
||||
struct device *dev;
|
||||
u32 clk_id;
|
||||
struct scmi_clock_info *clk;
|
||||
};
|
||||
|
|
@ -223,6 +224,29 @@ iter_clk_describe_update_state(struct scmi_iterator_state *st,
|
|||
st->num_returned = NUM_RETURNED(flags);
|
||||
p->clk->rate_discrete = RATE_DISCRETE(flags);
|
||||
|
||||
/* Warn about out of spec replies ... */
|
||||
if (!p->clk->rate_discrete &&
|
||||
(st->num_returned != 3 || st->num_remaining != 0)) {
|
||||
dev_warn(p->dev,
|
||||
"Out-of-spec CLOCK_DESCRIBE_RATES reply for %s - returned:%d remaining:%d rx_len:%zd\n",
|
||||
p->clk->name, st->num_returned, st->num_remaining,
|
||||
st->rx_len);
|
||||
|
||||
/*
|
||||
* A known quirk: a triplet is returned but num_returned != 3
|
||||
* Check for a safe payload size and fix.
|
||||
*/
|
||||
if (st->num_returned != 3 && st->num_remaining == 0 &&
|
||||
st->rx_len == sizeof(*r) + sizeof(__le32) * 2 * 3) {
|
||||
st->num_returned = 3;
|
||||
st->num_remaining = 0;
|
||||
} else {
|
||||
dev_err(p->dev,
|
||||
"Cannot fix out-of-spec reply !\n");
|
||||
return -EPROTO;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -255,7 +279,6 @@ iter_clk_describe_process_response(const struct scmi_protocol_handle *ph,
|
|||
|
||||
*rate = RATE_TO_U64(r->rate[st->loop_idx]);
|
||||
p->clk->list.num_rates++;
|
||||
//XXX dev_dbg(ph->dev, "Rate %llu Hz\n", *rate);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
@ -275,6 +298,7 @@ scmi_clock_describe_rates_get(const struct scmi_protocol_handle *ph, u32 clk_id,
|
|||
struct scmi_clk_ipriv cpriv = {
|
||||
.clk_id = clk_id,
|
||||
.clk = clk,
|
||||
.dev = ph->dev,
|
||||
};
|
||||
|
||||
iter = ph->hops->iter_response_init(ph, &ops, SCMI_MAX_NUM_RATES,
|
||||
|
|
|
|||
|
|
@ -1223,6 +1223,7 @@ static int scmi_iterator_run(void *iter)
|
|||
if (ret)
|
||||
break;
|
||||
|
||||
st->rx_len = i->t->rx.len;
|
||||
ret = iops->update_state(st, i->resp, i->priv);
|
||||
if (ret)
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -117,6 +117,7 @@ struct scmi_optee_channel {
|
|||
u32 channel_id;
|
||||
u32 tee_session;
|
||||
u32 caps;
|
||||
u32 rx_len;
|
||||
struct mutex mu;
|
||||
struct scmi_chan_info *cinfo;
|
||||
union {
|
||||
|
|
@ -302,6 +303,9 @@ static int invoke_process_msg_channel(struct scmi_optee_channel *channel, size_t
|
|||
return -EIO;
|
||||
}
|
||||
|
||||
/* Save response size */
|
||||
channel->rx_len = param[2].u.memref.size;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -353,6 +357,7 @@ static int setup_dynamic_shmem(struct device *dev, struct scmi_optee_channel *ch
|
|||
shbuf = tee_shm_get_va(channel->tee_shm, 0);
|
||||
memset(shbuf, 0, msg_size);
|
||||
channel->req.msg = shbuf;
|
||||
channel->rx_len = msg_size;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -508,7 +513,7 @@ static void scmi_optee_fetch_response(struct scmi_chan_info *cinfo,
|
|||
struct scmi_optee_channel *channel = cinfo->transport_info;
|
||||
|
||||
if (channel->tee_shm)
|
||||
msg_fetch_response(channel->req.msg, SCMI_OPTEE_MAX_MSG_SIZE, xfer);
|
||||
msg_fetch_response(channel->req.msg, channel->rx_len, xfer);
|
||||
else
|
||||
shmem_fetch_response(channel->req.shmem, xfer);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -179,6 +179,8 @@ struct scmi_protocol_handle {
|
|||
* @max_resources: Maximum acceptable number of items, configured by the caller
|
||||
* depending on the underlying resources that it is querying.
|
||||
* @loop_idx: The iterator loop index in the current multi-part reply.
|
||||
* @rx_len: Size in bytes of the currenly processed message; it can be used by
|
||||
* the user of the iterator to verify a reply size.
|
||||
* @priv: Optional pointer to some additional state-related private data setup
|
||||
* by the caller during the iterations.
|
||||
*/
|
||||
|
|
@ -188,6 +190,7 @@ struct scmi_iterator_state {
|
|||
unsigned int num_remaining;
|
||||
unsigned int max_resources;
|
||||
unsigned int loop_idx;
|
||||
size_t rx_len;
|
||||
void *priv;
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user