mirror of
https://github.com/torvalds/linux.git
synced 2026-06-03 12:03:54 +02:00
Merge branch '20260518-qcom-ice-fix-v7-0-2a595382185b@oss.qualcomm.com' into drivers-for-7.2
Merge the fixes for ICE driver race condition through a topic branch, to allow sharing it with other subsystems as well.
This commit is contained in:
commit
06b2e78c45
|
|
@ -1918,13 +1918,13 @@ static int sdhci_msm_ice_init(struct sdhci_msm_host *msm_host,
|
|||
return 0;
|
||||
|
||||
ice = devm_of_qcom_ice_get(dev);
|
||||
if (ice == ERR_PTR(-EOPNOTSUPP)) {
|
||||
dev_warn(dev, "Disabling inline encryption support\n");
|
||||
ice = NULL;
|
||||
}
|
||||
if (IS_ERR(ice)) {
|
||||
if (ice != ERR_PTR(-EOPNOTSUPP))
|
||||
return PTR_ERR(ice);
|
||||
|
||||
if (IS_ERR_OR_NULL(ice))
|
||||
return PTR_ERR_OR_ZERO(ice);
|
||||
dev_warn(dev, "Disabling inline encryption support\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
msm_host->ice = ice;
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
#include <linux/of.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/xarray.h>
|
||||
|
||||
#include <linux/firmware/qcom/qcom_scm.h>
|
||||
|
||||
|
|
@ -114,6 +115,9 @@ struct qcom_ice {
|
|||
u8 hwkm_version;
|
||||
};
|
||||
|
||||
static DEFINE_XARRAY(ice_handles);
|
||||
static DEFINE_MUTEX(ice_mutex);
|
||||
|
||||
static bool qcom_ice_check_supported(struct qcom_ice *ice)
|
||||
{
|
||||
u32 regval = qcom_ice_readl(ice, QCOM_ICE_REG_VERSION);
|
||||
|
|
@ -566,7 +570,7 @@ static struct qcom_ice *qcom_ice_create(struct device *dev,
|
|||
|
||||
if (!qcom_scm_ice_available()) {
|
||||
dev_warn(dev, "ICE SCM interface not found\n");
|
||||
return NULL;
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
}
|
||||
|
||||
engine = devm_kzalloc(dev, sizeof(*engine), GFP_KERNEL);
|
||||
|
|
@ -644,6 +648,8 @@ static struct qcom_ice *of_qcom_ice_get(struct device *dev)
|
|||
return qcom_ice_create(&pdev->dev, base);
|
||||
}
|
||||
|
||||
guard(mutex)(&ice_mutex);
|
||||
|
||||
/*
|
||||
* If the consumer node does not provider an 'ice' reg range
|
||||
* (legacy DT binding), then it must at least provide a phandle
|
||||
|
|
@ -652,20 +658,21 @@ static struct qcom_ice *of_qcom_ice_get(struct device *dev)
|
|||
struct device_node *node __free(device_node) = of_parse_phandle(dev->of_node,
|
||||
"qcom,ice", 0);
|
||||
if (!node)
|
||||
return NULL;
|
||||
return ERR_PTR(-ENODEV);
|
||||
|
||||
pdev = of_find_device_by_node(node);
|
||||
if (!pdev) {
|
||||
dev_err(dev, "Cannot find device node %s\n", node->name);
|
||||
return ERR_PTR(-EPROBE_DEFER);
|
||||
return ERR_PTR(-ENODEV);
|
||||
}
|
||||
|
||||
ice = platform_get_drvdata(pdev);
|
||||
if (!ice) {
|
||||
dev_err(dev, "Cannot get ice instance from %s\n",
|
||||
dev_name(&pdev->dev));
|
||||
ice = xa_load(&ice_handles, pdev->dev.of_node->phandle);
|
||||
if (IS_ERR_OR_NULL(ice)) {
|
||||
platform_device_put(pdev);
|
||||
return ERR_PTR(-EPROBE_DEFER);
|
||||
if (!ice)
|
||||
return ERR_PTR(-EPROBE_DEFER);
|
||||
else
|
||||
return ice;
|
||||
}
|
||||
|
||||
link = device_link_add(dev, &pdev->dev, DL_FLAG_AUTOREMOVE_SUPPLIER);
|
||||
|
|
@ -704,8 +711,7 @@ static void devm_of_qcom_ice_put(struct device *dev, void *res)
|
|||
* phandle via 'qcom,ice' property to an ICE DT, the ICE instance will already
|
||||
* be created and so this function will return that instead.
|
||||
*
|
||||
* Return: ICE pointer on success, NULL if there is no ICE data provided by the
|
||||
* consumer or ERR_PTR() on error.
|
||||
* Return: ICE pointer on success, ERR_PTR() on error.
|
||||
*/
|
||||
struct qcom_ice *devm_of_qcom_ice_get(struct device *dev)
|
||||
{
|
||||
|
|
@ -716,7 +722,7 @@ struct qcom_ice *devm_of_qcom_ice_get(struct device *dev)
|
|||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
ice = of_qcom_ice_get(dev);
|
||||
if (!IS_ERR_OR_NULL(ice)) {
|
||||
if (!IS_ERR(ice)) {
|
||||
*dr = ice;
|
||||
devres_add(dev, dr);
|
||||
} else {
|
||||
|
|
@ -729,24 +735,40 @@ EXPORT_SYMBOL_GPL(devm_of_qcom_ice_get);
|
|||
|
||||
static int qcom_ice_probe(struct platform_device *pdev)
|
||||
{
|
||||
unsigned long phandle = pdev->dev.of_node->phandle;
|
||||
struct qcom_ice *engine;
|
||||
void __iomem *base;
|
||||
|
||||
guard(mutex)(&ice_mutex);
|
||||
|
||||
base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(base)) {
|
||||
dev_warn(&pdev->dev, "ICE registers not found\n");
|
||||
/* Store the error pointer for devm_of_qcom_ice_get() */
|
||||
xa_store(&ice_handles, phandle, (__force void *)base, GFP_KERNEL);
|
||||
return PTR_ERR(base);
|
||||
}
|
||||
|
||||
engine = qcom_ice_create(&pdev->dev, base);
|
||||
if (IS_ERR(engine))
|
||||
if (IS_ERR(engine)) {
|
||||
/* Store the error pointer for devm_of_qcom_ice_get() */
|
||||
xa_store(&ice_handles, phandle, engine, GFP_KERNEL);
|
||||
return PTR_ERR(engine);
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, engine);
|
||||
xa_store(&ice_handles, phandle, engine, GFP_KERNEL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void qcom_ice_remove(struct platform_device *pdev)
|
||||
{
|
||||
unsigned long phandle = pdev->dev.of_node->phandle;
|
||||
|
||||
guard(mutex)(&ice_mutex);
|
||||
xa_store(&ice_handles, phandle, NULL, GFP_KERNEL);
|
||||
}
|
||||
|
||||
static const struct of_device_id qcom_ice_of_match_table[] = {
|
||||
{ .compatible = "qcom,inline-crypto-engine" },
|
||||
{ },
|
||||
|
|
@ -755,6 +777,7 @@ MODULE_DEVICE_TABLE(of, qcom_ice_of_match_table);
|
|||
|
||||
static struct platform_driver qcom_ice_driver = {
|
||||
.probe = qcom_ice_probe,
|
||||
.remove = qcom_ice_remove,
|
||||
.driver = {
|
||||
.name = "qcom-ice",
|
||||
.of_match_table = qcom_ice_of_match_table,
|
||||
|
|
|
|||
|
|
@ -177,13 +177,13 @@ static int ufs_qcom_ice_init(struct ufs_qcom_host *host)
|
|||
int i;
|
||||
|
||||
ice = devm_of_qcom_ice_get(dev);
|
||||
if (ice == ERR_PTR(-EOPNOTSUPP)) {
|
||||
dev_warn(dev, "Disabling inline encryption support\n");
|
||||
ice = NULL;
|
||||
}
|
||||
if (IS_ERR(ice)) {
|
||||
if (ice != ERR_PTR(-EOPNOTSUPP))
|
||||
return PTR_ERR(ice);
|
||||
|
||||
if (IS_ERR_OR_NULL(ice))
|
||||
return PTR_ERR_OR_ZERO(ice);
|
||||
dev_warn(dev, "Disabling inline encryption support\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
host->ice = ice;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user