mirror of
https://github.com/torvalds/linux.git
synced 2024-11-10 14:11:52 +00:00
Char/Misc driver fixes for 6.3-rc3.
Here are a few small char/misc/other driver subsystem patches to resolve reported problems for 6.3-rc3. Included in here are: - Interconnect driver fixes for reported problems - Memory driver fixes for reported problems. - nvmem core fix - firmware driver fix for reported problem. All of these have been in linux-next for a while with no reported issues. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -----BEGIN PGP SIGNATURE----- iG0EABECAC0WIQT0tgzFv3jCIUoxPcsxR9QN2y37KQUCZBchKw8cZ3JlZ0Brcm9h aC5jb20ACgkQMUfUDdst+ylYVQCfbQtOMjbfxCNvmBCZbC8GWaanLloAn243V7vJ oxfPCUa6+BYLFWweKydG =tuC/ -----END PGP SIGNATURE----- Merge tag 'char-misc-6.3-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc Pull char/misc driver fixes from Greg KH: "Here are a few small char/misc/other driver subsystem patches to resolve reported problems for 6.3-rc3. Included in here are: - Interconnect driver fixes for reported problems - Memory driver fixes for reported problems - nvmem core fix - firmware driver fix for reported problem All of these have been in linux-next for a while with no reported issues" * tag 'char-misc-6.3-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: (23 commits) memory: tegra30-emc: fix interconnect registration race memory: tegra20-emc: fix interconnect registration race memory: tegra124-emc: fix interconnect registration race memory: tegra: fix interconnect registration race interconnect: exynos: drop redundant link destroy interconnect: exynos: fix registration race interconnect: exynos: fix node leak in probe PM QoS error path interconnect: qcom: msm8974: fix registration race interconnect: qcom: rpmh: fix registration race interconnect: qcom: rpmh: fix probe child-node error handling interconnect: qcom: rpm: fix registration race nvmem: core: return -ENOENT if nvmem cell is not found firmware: xilinx: don't make a sleepable memory allocation from an atomic context interconnect: qcom: rpm: fix probe child-node error handling interconnect: qcom: osm-l3: fix registration race interconnect: imx: fix registration race interconnect: fix provider registration API interconnect: fix icc_provider_del() error handling interconnect: fix mem leak when freeing nodes interconnect: qcom: qcm2290: Fix MASTER_SNOC_BIMC_NRT ...
This commit is contained in:
commit
ce86beb43e
@ -206,7 +206,7 @@ static int do_feature_check_call(const u32 api_id)
|
||||
}
|
||||
|
||||
/* Add new entry if not present */
|
||||
feature_data = kmalloc(sizeof(*feature_data), GFP_KERNEL);
|
||||
feature_data = kmalloc(sizeof(*feature_data), GFP_ATOMIC);
|
||||
if (!feature_data)
|
||||
return -ENOMEM;
|
||||
|
||||
|
@ -850,6 +850,10 @@ void icc_node_destroy(int id)
|
||||
|
||||
mutex_unlock(&icc_lock);
|
||||
|
||||
if (!node)
|
||||
return;
|
||||
|
||||
kfree(node->links);
|
||||
kfree(node);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(icc_node_destroy);
|
||||
@ -1029,54 +1033,68 @@ int icc_nodes_remove(struct icc_provider *provider)
|
||||
EXPORT_SYMBOL_GPL(icc_nodes_remove);
|
||||
|
||||
/**
|
||||
* icc_provider_add() - add a new interconnect provider
|
||||
* @provider: the interconnect provider that will be added into topology
|
||||
* icc_provider_init() - initialize a new interconnect provider
|
||||
* @provider: the interconnect provider to initialize
|
||||
*
|
||||
* Must be called before adding nodes to the provider.
|
||||
*/
|
||||
void icc_provider_init(struct icc_provider *provider)
|
||||
{
|
||||
WARN_ON(!provider->set);
|
||||
|
||||
INIT_LIST_HEAD(&provider->nodes);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(icc_provider_init);
|
||||
|
||||
/**
|
||||
* icc_provider_register() - register a new interconnect provider
|
||||
* @provider: the interconnect provider to register
|
||||
*
|
||||
* Return: 0 on success, or an error code otherwise
|
||||
*/
|
||||
int icc_provider_add(struct icc_provider *provider)
|
||||
int icc_provider_register(struct icc_provider *provider)
|
||||
{
|
||||
if (WARN_ON(!provider->set))
|
||||
return -EINVAL;
|
||||
if (WARN_ON(!provider->xlate && !provider->xlate_extended))
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&icc_lock);
|
||||
|
||||
INIT_LIST_HEAD(&provider->nodes);
|
||||
list_add_tail(&provider->provider_list, &icc_providers);
|
||||
|
||||
mutex_unlock(&icc_lock);
|
||||
|
||||
dev_dbg(provider->dev, "interconnect provider added to topology\n");
|
||||
dev_dbg(provider->dev, "interconnect provider registered\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(icc_provider_add);
|
||||
EXPORT_SYMBOL_GPL(icc_provider_register);
|
||||
|
||||
/**
|
||||
* icc_provider_del() - delete previously added interconnect provider
|
||||
* @provider: the interconnect provider that will be removed from topology
|
||||
* icc_provider_deregister() - deregister an interconnect provider
|
||||
* @provider: the interconnect provider to deregister
|
||||
*/
|
||||
void icc_provider_del(struct icc_provider *provider)
|
||||
void icc_provider_deregister(struct icc_provider *provider)
|
||||
{
|
||||
mutex_lock(&icc_lock);
|
||||
if (provider->users) {
|
||||
pr_warn("interconnect provider still has %d users\n",
|
||||
provider->users);
|
||||
mutex_unlock(&icc_lock);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!list_empty(&provider->nodes)) {
|
||||
pr_warn("interconnect provider still has nodes\n");
|
||||
mutex_unlock(&icc_lock);
|
||||
return;
|
||||
}
|
||||
WARN_ON(provider->users);
|
||||
|
||||
list_del(&provider->provider_list);
|
||||
mutex_unlock(&icc_lock);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(icc_provider_deregister);
|
||||
|
||||
int icc_provider_add(struct icc_provider *provider)
|
||||
{
|
||||
icc_provider_init(provider);
|
||||
|
||||
return icc_provider_register(provider);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(icc_provider_add);
|
||||
|
||||
void icc_provider_del(struct icc_provider *provider)
|
||||
{
|
||||
WARN_ON(!list_empty(&provider->nodes));
|
||||
|
||||
icc_provider_deregister(provider);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(icc_provider_del);
|
||||
|
||||
static const struct of_device_id __maybe_unused ignore_list[] = {
|
||||
|
@ -295,6 +295,9 @@ int imx_icc_register(struct platform_device *pdev,
|
||||
provider->xlate = of_icc_xlate_onecell;
|
||||
provider->data = data;
|
||||
provider->dev = dev->parent;
|
||||
|
||||
icc_provider_init(provider);
|
||||
|
||||
platform_set_drvdata(pdev, imx_provider);
|
||||
|
||||
if (settings) {
|
||||
@ -306,20 +309,18 @@ int imx_icc_register(struct platform_device *pdev,
|
||||
}
|
||||
}
|
||||
|
||||
ret = icc_provider_add(provider);
|
||||
if (ret) {
|
||||
dev_err(dev, "error adding interconnect provider: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = imx_icc_register_nodes(imx_provider, nodes, nodes_count, settings);
|
||||
if (ret)
|
||||
goto provider_del;
|
||||
return ret;
|
||||
|
||||
ret = icc_provider_register(provider);
|
||||
if (ret)
|
||||
goto err_unregister_nodes;
|
||||
|
||||
return 0;
|
||||
|
||||
provider_del:
|
||||
icc_provider_del(provider);
|
||||
err_unregister_nodes:
|
||||
imx_icc_unregister_nodes(&imx_provider->provider);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(imx_icc_register);
|
||||
@ -328,9 +329,8 @@ void imx_icc_unregister(struct platform_device *pdev)
|
||||
{
|
||||
struct imx_icc_provider *imx_provider = platform_get_drvdata(pdev);
|
||||
|
||||
icc_provider_deregister(&imx_provider->provider);
|
||||
imx_icc_unregister_nodes(&imx_provider->provider);
|
||||
|
||||
icc_provider_del(&imx_provider->provider);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(imx_icc_unregister);
|
||||
|
||||
|
@ -503,7 +503,6 @@ regmap_done:
|
||||
}
|
||||
|
||||
provider = &qp->provider;
|
||||
INIT_LIST_HEAD(&provider->nodes);
|
||||
provider->dev = dev;
|
||||
provider->set = qcom_icc_set;
|
||||
provider->pre_aggregate = qcom_icc_pre_bw_aggregate;
|
||||
@ -511,12 +510,7 @@ regmap_done:
|
||||
provider->xlate_extended = qcom_icc_xlate_extended;
|
||||
provider->data = data;
|
||||
|
||||
ret = icc_provider_add(provider);
|
||||
if (ret) {
|
||||
dev_err(dev, "error adding interconnect provider: %d\n", ret);
|
||||
clk_bulk_disable_unprepare(qp->num_clks, qp->bus_clks);
|
||||
return ret;
|
||||
}
|
||||
icc_provider_init(provider);
|
||||
|
||||
for (i = 0; i < num_nodes; i++) {
|
||||
size_t j;
|
||||
@ -524,7 +518,7 @@ regmap_done:
|
||||
node = icc_node_create(qnodes[i]->id);
|
||||
if (IS_ERR(node)) {
|
||||
ret = PTR_ERR(node);
|
||||
goto err;
|
||||
goto err_remove_nodes;
|
||||
}
|
||||
|
||||
node->name = qnodes[i]->name;
|
||||
@ -538,17 +532,26 @@ regmap_done:
|
||||
}
|
||||
data->num_nodes = num_nodes;
|
||||
|
||||
ret = icc_provider_register(provider);
|
||||
if (ret)
|
||||
goto err_remove_nodes;
|
||||
|
||||
platform_set_drvdata(pdev, qp);
|
||||
|
||||
/* Populate child NoC devices if any */
|
||||
if (of_get_child_count(dev->of_node) > 0)
|
||||
return of_platform_populate(dev->of_node, NULL, NULL, dev);
|
||||
if (of_get_child_count(dev->of_node) > 0) {
|
||||
ret = of_platform_populate(dev->of_node, NULL, NULL, dev);
|
||||
if (ret)
|
||||
goto err_deregister_provider;
|
||||
}
|
||||
|
||||
return 0;
|
||||
err:
|
||||
|
||||
err_deregister_provider:
|
||||
icc_provider_deregister(provider);
|
||||
err_remove_nodes:
|
||||
icc_nodes_remove(provider);
|
||||
clk_bulk_disable_unprepare(qp->num_clks, qp->bus_clks);
|
||||
icc_provider_del(provider);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -558,9 +561,9 @@ int qnoc_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct qcom_icc_provider *qp = platform_get_drvdata(pdev);
|
||||
|
||||
icc_provider_deregister(&qp->provider);
|
||||
icc_nodes_remove(&qp->provider);
|
||||
clk_bulk_disable_unprepare(qp->num_clks, qp->bus_clks);
|
||||
icc_provider_del(&qp->provider);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -192,9 +192,10 @@ int qcom_icc_rpmh_probe(struct platform_device *pdev)
|
||||
provider->pre_aggregate = qcom_icc_pre_aggregate;
|
||||
provider->aggregate = qcom_icc_aggregate;
|
||||
provider->xlate_extended = qcom_icc_xlate_extended;
|
||||
INIT_LIST_HEAD(&provider->nodes);
|
||||
provider->data = data;
|
||||
|
||||
icc_provider_init(provider);
|
||||
|
||||
qp->dev = dev;
|
||||
qp->bcms = desc->bcms;
|
||||
qp->num_bcms = desc->num_bcms;
|
||||
@ -203,10 +204,6 @@ int qcom_icc_rpmh_probe(struct platform_device *pdev)
|
||||
if (IS_ERR(qp->voter))
|
||||
return PTR_ERR(qp->voter);
|
||||
|
||||
ret = icc_provider_add(provider);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
for (i = 0; i < qp->num_bcms; i++)
|
||||
qcom_icc_bcm_init(qp->bcms[i], dev);
|
||||
|
||||
@ -218,7 +215,7 @@ int qcom_icc_rpmh_probe(struct platform_device *pdev)
|
||||
node = icc_node_create(qn->id);
|
||||
if (IS_ERR(node)) {
|
||||
ret = PTR_ERR(node);
|
||||
goto err;
|
||||
goto err_remove_nodes;
|
||||
}
|
||||
|
||||
node->name = qn->name;
|
||||
@ -232,16 +229,27 @@ int qcom_icc_rpmh_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
data->num_nodes = num_nodes;
|
||||
|
||||
ret = icc_provider_register(provider);
|
||||
if (ret)
|
||||
goto err_remove_nodes;
|
||||
|
||||
platform_set_drvdata(pdev, qp);
|
||||
|
||||
/* Populate child NoC devices if any */
|
||||
if (of_get_child_count(dev->of_node) > 0)
|
||||
return of_platform_populate(dev->of_node, NULL, NULL, dev);
|
||||
if (of_get_child_count(dev->of_node) > 0) {
|
||||
ret = of_platform_populate(dev->of_node, NULL, NULL, dev);
|
||||
if (ret)
|
||||
goto err_deregister_provider;
|
||||
}
|
||||
|
||||
return 0;
|
||||
err:
|
||||
|
||||
err_deregister_provider:
|
||||
icc_provider_deregister(provider);
|
||||
err_remove_nodes:
|
||||
icc_nodes_remove(provider);
|
||||
icc_provider_del(provider);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(qcom_icc_rpmh_probe);
|
||||
@ -250,8 +258,8 @@ int qcom_icc_rpmh_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct qcom_icc_provider *qp = platform_get_drvdata(pdev);
|
||||
|
||||
icc_provider_deregister(&qp->provider);
|
||||
icc_nodes_remove(&qp->provider);
|
||||
icc_provider_del(&qp->provider);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -692,7 +692,6 @@ static int msm8974_icc_probe(struct platform_device *pdev)
|
||||
return ret;
|
||||
|
||||
provider = &qp->provider;
|
||||
INIT_LIST_HEAD(&provider->nodes);
|
||||
provider->dev = dev;
|
||||
provider->set = msm8974_icc_set;
|
||||
provider->aggregate = icc_std_aggregate;
|
||||
@ -700,11 +699,7 @@ static int msm8974_icc_probe(struct platform_device *pdev)
|
||||
provider->data = data;
|
||||
provider->get_bw = msm8974_get_bw;
|
||||
|
||||
ret = icc_provider_add(provider);
|
||||
if (ret) {
|
||||
dev_err(dev, "error adding interconnect provider: %d\n", ret);
|
||||
goto err_disable_clks;
|
||||
}
|
||||
icc_provider_init(provider);
|
||||
|
||||
for (i = 0; i < num_nodes; i++) {
|
||||
size_t j;
|
||||
@ -712,7 +707,7 @@ static int msm8974_icc_probe(struct platform_device *pdev)
|
||||
node = icc_node_create(qnodes[i]->id);
|
||||
if (IS_ERR(node)) {
|
||||
ret = PTR_ERR(node);
|
||||
goto err_del_icc;
|
||||
goto err_remove_nodes;
|
||||
}
|
||||
|
||||
node->name = qnodes[i]->name;
|
||||
@ -729,15 +724,16 @@ static int msm8974_icc_probe(struct platform_device *pdev)
|
||||
}
|
||||
data->num_nodes = num_nodes;
|
||||
|
||||
ret = icc_provider_register(provider);
|
||||
if (ret)
|
||||
goto err_remove_nodes;
|
||||
|
||||
platform_set_drvdata(pdev, qp);
|
||||
|
||||
return 0;
|
||||
|
||||
err_del_icc:
|
||||
err_remove_nodes:
|
||||
icc_nodes_remove(provider);
|
||||
icc_provider_del(provider);
|
||||
|
||||
err_disable_clks:
|
||||
clk_bulk_disable_unprepare(qp->num_clks, qp->bus_clks);
|
||||
|
||||
return ret;
|
||||
@ -747,9 +743,9 @@ static int msm8974_icc_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct msm8974_icc_provider *qp = platform_get_drvdata(pdev);
|
||||
|
||||
icc_provider_deregister(&qp->provider);
|
||||
icc_nodes_remove(&qp->provider);
|
||||
clk_bulk_disable_unprepare(qp->num_clks, qp->bus_clks);
|
||||
icc_provider_del(&qp->provider);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -158,8 +158,8 @@ static int qcom_osm_l3_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct qcom_osm_l3_icc_provider *qp = platform_get_drvdata(pdev);
|
||||
|
||||
icc_provider_deregister(&qp->provider);
|
||||
icc_nodes_remove(&qp->provider);
|
||||
icc_provider_del(&qp->provider);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -236,7 +236,7 @@ static int qcom_osm_l3_probe(struct platform_device *pdev)
|
||||
qnodes = desc->nodes;
|
||||
num_nodes = desc->num_nodes;
|
||||
|
||||
data = devm_kcalloc(&pdev->dev, num_nodes, sizeof(*node), GFP_KERNEL);
|
||||
data = devm_kzalloc(&pdev->dev, struct_size(data, nodes, num_nodes), GFP_KERNEL);
|
||||
if (!data)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -245,14 +245,9 @@ static int qcom_osm_l3_probe(struct platform_device *pdev)
|
||||
provider->set = qcom_osm_l3_set;
|
||||
provider->aggregate = icc_std_aggregate;
|
||||
provider->xlate = of_icc_xlate_onecell;
|
||||
INIT_LIST_HEAD(&provider->nodes);
|
||||
provider->data = data;
|
||||
|
||||
ret = icc_provider_add(provider);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "error adding interconnect provider\n");
|
||||
return ret;
|
||||
}
|
||||
icc_provider_init(provider);
|
||||
|
||||
for (i = 0; i < num_nodes; i++) {
|
||||
size_t j;
|
||||
@ -275,12 +270,15 @@ static int qcom_osm_l3_probe(struct platform_device *pdev)
|
||||
}
|
||||
data->num_nodes = num_nodes;
|
||||
|
||||
ret = icc_provider_register(provider);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
platform_set_drvdata(pdev, qp);
|
||||
|
||||
return 0;
|
||||
err:
|
||||
icc_nodes_remove(provider);
|
||||
icc_provider_del(provider);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -147,9 +147,9 @@ static struct qcom_icc_node mas_snoc_bimc_nrt = {
|
||||
.name = "mas_snoc_bimc_nrt",
|
||||
.buswidth = 16,
|
||||
.qos.ap_owned = true,
|
||||
.qos.qos_port = 2,
|
||||
.qos.qos_port = 3,
|
||||
.qos.qos_mode = NOC_QOS_MODE_BYPASS,
|
||||
.mas_rpm_id = 163,
|
||||
.mas_rpm_id = 164,
|
||||
.slv_rpm_id = -1,
|
||||
.num_links = ARRAY_SIZE(mas_snoc_bimc_nrt_links),
|
||||
.links = mas_snoc_bimc_nrt_links,
|
||||
|
@ -1844,100 +1844,6 @@ static const struct qcom_icc_desc sm8450_system_noc = {
|
||||
.num_bcms = ARRAY_SIZE(system_noc_bcms),
|
||||
};
|
||||
|
||||
static int qnoc_probe(struct platform_device *pdev)
|
||||
{
|
||||
const struct qcom_icc_desc *desc;
|
||||
struct icc_onecell_data *data;
|
||||
struct icc_provider *provider;
|
||||
struct qcom_icc_node * const *qnodes;
|
||||
struct qcom_icc_provider *qp;
|
||||
struct icc_node *node;
|
||||
size_t num_nodes, i;
|
||||
int ret;
|
||||
|
||||
desc = device_get_match_data(&pdev->dev);
|
||||
if (!desc)
|
||||
return -EINVAL;
|
||||
|
||||
qnodes = desc->nodes;
|
||||
num_nodes = desc->num_nodes;
|
||||
|
||||
qp = devm_kzalloc(&pdev->dev, sizeof(*qp), GFP_KERNEL);
|
||||
if (!qp)
|
||||
return -ENOMEM;
|
||||
|
||||
data = devm_kcalloc(&pdev->dev, num_nodes, sizeof(*node), GFP_KERNEL);
|
||||
if (!data)
|
||||
return -ENOMEM;
|
||||
|
||||
provider = &qp->provider;
|
||||
provider->dev = &pdev->dev;
|
||||
provider->set = qcom_icc_set;
|
||||
provider->pre_aggregate = qcom_icc_pre_aggregate;
|
||||
provider->aggregate = qcom_icc_aggregate;
|
||||
provider->xlate_extended = qcom_icc_xlate_extended;
|
||||
INIT_LIST_HEAD(&provider->nodes);
|
||||
provider->data = data;
|
||||
|
||||
qp->dev = &pdev->dev;
|
||||
qp->bcms = desc->bcms;
|
||||
qp->num_bcms = desc->num_bcms;
|
||||
|
||||
qp->voter = of_bcm_voter_get(qp->dev, NULL);
|
||||
if (IS_ERR(qp->voter))
|
||||
return PTR_ERR(qp->voter);
|
||||
|
||||
ret = icc_provider_add(provider);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "error adding interconnect provider\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
for (i = 0; i < qp->num_bcms; i++)
|
||||
qcom_icc_bcm_init(qp->bcms[i], &pdev->dev);
|
||||
|
||||
for (i = 0; i < num_nodes; i++) {
|
||||
size_t j;
|
||||
|
||||
if (!qnodes[i])
|
||||
continue;
|
||||
|
||||
node = icc_node_create(qnodes[i]->id);
|
||||
if (IS_ERR(node)) {
|
||||
ret = PTR_ERR(node);
|
||||
goto err;
|
||||
}
|
||||
|
||||
node->name = qnodes[i]->name;
|
||||
node->data = qnodes[i];
|
||||
icc_node_add(node, provider);
|
||||
|
||||
for (j = 0; j < qnodes[i]->num_links; j++)
|
||||
icc_link_create(node, qnodes[i]->links[j]);
|
||||
|
||||
data->nodes[i] = node;
|
||||
}
|
||||
data->num_nodes = num_nodes;
|
||||
|
||||
platform_set_drvdata(pdev, qp);
|
||||
|
||||
return 0;
|
||||
err:
|
||||
icc_nodes_remove(provider);
|
||||
icc_provider_del(provider);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int qnoc_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct qcom_icc_provider *qp = platform_get_drvdata(pdev);
|
||||
|
||||
icc_nodes_remove(&qp->provider);
|
||||
icc_provider_del(&qp->provider);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id qnoc_of_match[] = {
|
||||
{ .compatible = "qcom,sm8450-aggre1-noc",
|
||||
.data = &sm8450_aggre1_noc},
|
||||
@ -1966,8 +1872,8 @@ static const struct of_device_id qnoc_of_match[] = {
|
||||
MODULE_DEVICE_TABLE(of, qnoc_of_match);
|
||||
|
||||
static struct platform_driver qnoc_driver = {
|
||||
.probe = qnoc_probe,
|
||||
.remove = qnoc_remove,
|
||||
.probe = qcom_icc_rpmh_probe,
|
||||
.remove = qcom_icc_rpmh_remove,
|
||||
.driver = {
|
||||
.name = "qnoc-sm8450",
|
||||
.of_match_table = qnoc_of_match,
|
||||
|
@ -2165,101 +2165,6 @@ static const struct qcom_icc_desc sm8550_system_noc = {
|
||||
.num_bcms = ARRAY_SIZE(system_noc_bcms),
|
||||
};
|
||||
|
||||
static int qnoc_probe(struct platform_device *pdev)
|
||||
{
|
||||
const struct qcom_icc_desc *desc;
|
||||
struct icc_onecell_data *data;
|
||||
struct icc_provider *provider;
|
||||
struct qcom_icc_node * const *qnodes;
|
||||
struct qcom_icc_provider *qp;
|
||||
struct icc_node *node;
|
||||
size_t num_nodes, i;
|
||||
int ret;
|
||||
|
||||
desc = device_get_match_data(&pdev->dev);
|
||||
if (!desc)
|
||||
return -EINVAL;
|
||||
|
||||
qnodes = desc->nodes;
|
||||
num_nodes = desc->num_nodes;
|
||||
|
||||
qp = devm_kzalloc(&pdev->dev, sizeof(*qp), GFP_KERNEL);
|
||||
if (!qp)
|
||||
return -ENOMEM;
|
||||
|
||||
data = devm_kcalloc(&pdev->dev, num_nodes, sizeof(*node), GFP_KERNEL);
|
||||
if (!data)
|
||||
return -ENOMEM;
|
||||
|
||||
provider = &qp->provider;
|
||||
provider->dev = &pdev->dev;
|
||||
provider->set = qcom_icc_set;
|
||||
provider->pre_aggregate = qcom_icc_pre_aggregate;
|
||||
provider->aggregate = qcom_icc_aggregate;
|
||||
provider->xlate_extended = qcom_icc_xlate_extended;
|
||||
INIT_LIST_HEAD(&provider->nodes);
|
||||
provider->data = data;
|
||||
|
||||
qp->dev = &pdev->dev;
|
||||
qp->bcms = desc->bcms;
|
||||
qp->num_bcms = desc->num_bcms;
|
||||
|
||||
qp->voter = of_bcm_voter_get(qp->dev, NULL);
|
||||
if (IS_ERR(qp->voter))
|
||||
return PTR_ERR(qp->voter);
|
||||
|
||||
ret = icc_provider_add(provider);
|
||||
if (ret) {
|
||||
dev_err_probe(&pdev->dev, ret,
|
||||
"error adding interconnect provider\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
for (i = 0; i < qp->num_bcms; i++)
|
||||
qcom_icc_bcm_init(qp->bcms[i], &pdev->dev);
|
||||
|
||||
for (i = 0; i < num_nodes; i++) {
|
||||
size_t j;
|
||||
|
||||
if (!qnodes[i])
|
||||
continue;
|
||||
|
||||
node = icc_node_create(qnodes[i]->id);
|
||||
if (IS_ERR(node)) {
|
||||
ret = PTR_ERR(node);
|
||||
goto err;
|
||||
}
|
||||
|
||||
node->name = qnodes[i]->name;
|
||||
node->data = qnodes[i];
|
||||
icc_node_add(node, provider);
|
||||
|
||||
for (j = 0; j < qnodes[i]->num_links; j++)
|
||||
icc_link_create(node, qnodes[i]->links[j]);
|
||||
|
||||
data->nodes[i] = node;
|
||||
}
|
||||
data->num_nodes = num_nodes;
|
||||
|
||||
platform_set_drvdata(pdev, qp);
|
||||
|
||||
return 0;
|
||||
err:
|
||||
icc_nodes_remove(provider);
|
||||
icc_provider_del(provider);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int qnoc_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct qcom_icc_provider *qp = platform_get_drvdata(pdev);
|
||||
|
||||
icc_nodes_remove(&qp->provider);
|
||||
icc_provider_del(&qp->provider);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id qnoc_of_match[] = {
|
||||
{ .compatible = "qcom,sm8550-aggre1-noc",
|
||||
.data = &sm8550_aggre1_noc},
|
||||
@ -2294,8 +2199,8 @@ static const struct of_device_id qnoc_of_match[] = {
|
||||
MODULE_DEVICE_TABLE(of, qnoc_of_match);
|
||||
|
||||
static struct platform_driver qnoc_driver = {
|
||||
.probe = qnoc_probe,
|
||||
.remove = qnoc_remove,
|
||||
.probe = qcom_icc_rpmh_probe,
|
||||
.remove = qcom_icc_rpmh_remove,
|
||||
.driver = {
|
||||
.name = "qnoc-sm8550",
|
||||
.of_match_table = qnoc_of_match,
|
||||
|
@ -96,14 +96,9 @@ static struct icc_node *exynos_generic_icc_xlate(struct of_phandle_args *spec,
|
||||
static int exynos_generic_icc_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct exynos_icc_priv *priv = platform_get_drvdata(pdev);
|
||||
struct icc_node *parent_node, *node = priv->node;
|
||||
|
||||
parent_node = exynos_icc_get_parent(priv->dev->parent->of_node);
|
||||
if (parent_node && !IS_ERR(parent_node))
|
||||
icc_link_destroy(node, parent_node);
|
||||
|
||||
icc_provider_deregister(&priv->provider);
|
||||
icc_nodes_remove(&priv->provider);
|
||||
icc_provider_del(&priv->provider);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -132,15 +127,11 @@ static int exynos_generic_icc_probe(struct platform_device *pdev)
|
||||
provider->inter_set = true;
|
||||
provider->data = priv;
|
||||
|
||||
ret = icc_provider_add(provider);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
icc_provider_init(provider);
|
||||
|
||||
icc_node = icc_node_create(pdev->id);
|
||||
if (IS_ERR(icc_node)) {
|
||||
ret = PTR_ERR(icc_node);
|
||||
goto err_prov_del;
|
||||
}
|
||||
if (IS_ERR(icc_node))
|
||||
return PTR_ERR(icc_node);
|
||||
|
||||
priv->node = icc_node;
|
||||
icc_node->name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%pOFn",
|
||||
@ -149,6 +140,9 @@ static int exynos_generic_icc_probe(struct platform_device *pdev)
|
||||
&priv->bus_clk_ratio))
|
||||
priv->bus_clk_ratio = EXYNOS_ICC_DEFAULT_BUS_CLK_RATIO;
|
||||
|
||||
icc_node->data = priv;
|
||||
icc_node_add(icc_node, provider);
|
||||
|
||||
/*
|
||||
* Register a PM QoS request for the parent (devfreq) device.
|
||||
*/
|
||||
@ -157,9 +151,6 @@ static int exynos_generic_icc_probe(struct platform_device *pdev)
|
||||
if (ret < 0)
|
||||
goto err_node_del;
|
||||
|
||||
icc_node->data = priv;
|
||||
icc_node_add(icc_node, provider);
|
||||
|
||||
icc_parent_node = exynos_icc_get_parent(bus_dev->of_node);
|
||||
if (IS_ERR(icc_parent_node)) {
|
||||
ret = PTR_ERR(icc_parent_node);
|
||||
@ -171,14 +162,17 @@ static int exynos_generic_icc_probe(struct platform_device *pdev)
|
||||
goto err_pmqos_del;
|
||||
}
|
||||
|
||||
ret = icc_provider_register(provider);
|
||||
if (ret < 0)
|
||||
goto err_pmqos_del;
|
||||
|
||||
return 0;
|
||||
|
||||
err_pmqos_del:
|
||||
dev_pm_qos_remove_request(&priv->qos_req);
|
||||
err_node_del:
|
||||
icc_nodes_remove(provider);
|
||||
err_prov_del:
|
||||
icc_provider_del(provider);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -794,16 +794,12 @@ static int tegra_mc_interconnect_setup(struct tegra_mc *mc)
|
||||
mc->provider.aggregate = mc->soc->icc_ops->aggregate;
|
||||
mc->provider.xlate_extended = mc->soc->icc_ops->xlate_extended;
|
||||
|
||||
err = icc_provider_add(&mc->provider);
|
||||
if (err)
|
||||
return err;
|
||||
icc_provider_init(&mc->provider);
|
||||
|
||||
/* create Memory Controller node */
|
||||
node = icc_node_create(TEGRA_ICC_MC);
|
||||
if (IS_ERR(node)) {
|
||||
err = PTR_ERR(node);
|
||||
goto del_provider;
|
||||
}
|
||||
if (IS_ERR(node))
|
||||
return PTR_ERR(node);
|
||||
|
||||
node->name = "Memory Controller";
|
||||
icc_node_add(node, &mc->provider);
|
||||
@ -830,12 +826,14 @@ static int tegra_mc_interconnect_setup(struct tegra_mc *mc)
|
||||
goto remove_nodes;
|
||||
}
|
||||
|
||||
err = icc_provider_register(&mc->provider);
|
||||
if (err)
|
||||
goto remove_nodes;
|
||||
|
||||
return 0;
|
||||
|
||||
remove_nodes:
|
||||
icc_nodes_remove(&mc->provider);
|
||||
del_provider:
|
||||
icc_provider_del(&mc->provider);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
@ -1351,15 +1351,13 @@ static int tegra_emc_interconnect_init(struct tegra_emc *emc)
|
||||
emc->provider.aggregate = soc->icc_ops->aggregate;
|
||||
emc->provider.xlate_extended = emc_of_icc_xlate_extended;
|
||||
|
||||
err = icc_provider_add(&emc->provider);
|
||||
if (err)
|
||||
goto err_msg;
|
||||
icc_provider_init(&emc->provider);
|
||||
|
||||
/* create External Memory Controller node */
|
||||
node = icc_node_create(TEGRA_ICC_EMC);
|
||||
if (IS_ERR(node)) {
|
||||
err = PTR_ERR(node);
|
||||
goto del_provider;
|
||||
goto err_msg;
|
||||
}
|
||||
|
||||
node->name = "External Memory Controller";
|
||||
@ -1380,12 +1378,14 @@ static int tegra_emc_interconnect_init(struct tegra_emc *emc)
|
||||
node->name = "External Memory (DRAM)";
|
||||
icc_node_add(node, &emc->provider);
|
||||
|
||||
err = icc_provider_register(&emc->provider);
|
||||
if (err)
|
||||
goto remove_nodes;
|
||||
|
||||
return 0;
|
||||
|
||||
remove_nodes:
|
||||
icc_nodes_remove(&emc->provider);
|
||||
del_provider:
|
||||
icc_provider_del(&emc->provider);
|
||||
err_msg:
|
||||
dev_err(emc->dev, "failed to initialize ICC: %d\n", err);
|
||||
|
||||
|
@ -1021,15 +1021,13 @@ static int tegra_emc_interconnect_init(struct tegra_emc *emc)
|
||||
emc->provider.aggregate = soc->icc_ops->aggregate;
|
||||
emc->provider.xlate_extended = emc_of_icc_xlate_extended;
|
||||
|
||||
err = icc_provider_add(&emc->provider);
|
||||
if (err)
|
||||
goto err_msg;
|
||||
icc_provider_init(&emc->provider);
|
||||
|
||||
/* create External Memory Controller node */
|
||||
node = icc_node_create(TEGRA_ICC_EMC);
|
||||
if (IS_ERR(node)) {
|
||||
err = PTR_ERR(node);
|
||||
goto del_provider;
|
||||
goto err_msg;
|
||||
}
|
||||
|
||||
node->name = "External Memory Controller";
|
||||
@ -1050,12 +1048,14 @@ static int tegra_emc_interconnect_init(struct tegra_emc *emc)
|
||||
node->name = "External Memory (DRAM)";
|
||||
icc_node_add(node, &emc->provider);
|
||||
|
||||
err = icc_provider_register(&emc->provider);
|
||||
if (err)
|
||||
goto remove_nodes;
|
||||
|
||||
return 0;
|
||||
|
||||
remove_nodes:
|
||||
icc_nodes_remove(&emc->provider);
|
||||
del_provider:
|
||||
icc_provider_del(&emc->provider);
|
||||
err_msg:
|
||||
dev_err(emc->dev, "failed to initialize ICC: %d\n", err);
|
||||
|
||||
|
@ -1533,15 +1533,13 @@ static int tegra_emc_interconnect_init(struct tegra_emc *emc)
|
||||
emc->provider.aggregate = soc->icc_ops->aggregate;
|
||||
emc->provider.xlate_extended = emc_of_icc_xlate_extended;
|
||||
|
||||
err = icc_provider_add(&emc->provider);
|
||||
if (err)
|
||||
goto err_msg;
|
||||
icc_provider_init(&emc->provider);
|
||||
|
||||
/* create External Memory Controller node */
|
||||
node = icc_node_create(TEGRA_ICC_EMC);
|
||||
if (IS_ERR(node)) {
|
||||
err = PTR_ERR(node);
|
||||
goto del_provider;
|
||||
goto err_msg;
|
||||
}
|
||||
|
||||
node->name = "External Memory Controller";
|
||||
@ -1562,12 +1560,14 @@ static int tegra_emc_interconnect_init(struct tegra_emc *emc)
|
||||
node->name = "External Memory (DRAM)";
|
||||
icc_node_add(node, &emc->provider);
|
||||
|
||||
err = icc_provider_register(&emc->provider);
|
||||
if (err)
|
||||
goto remove_nodes;
|
||||
|
||||
return 0;
|
||||
|
||||
remove_nodes:
|
||||
icc_nodes_remove(&emc->provider);
|
||||
del_provider:
|
||||
icc_provider_del(&emc->provider);
|
||||
err_msg:
|
||||
dev_err(emc->dev, "failed to initialize ICC: %d\n", err);
|
||||
|
||||
|
@ -1231,7 +1231,7 @@ struct nvmem_cell *of_nvmem_cell_get(struct device_node *np, const char *id)
|
||||
"#nvmem-cell-cells",
|
||||
index, &cell_spec);
|
||||
if (ret)
|
||||
return ERR_PTR(ret);
|
||||
return ERR_PTR(-ENOENT);
|
||||
|
||||
if (cell_spec.args_count > 1)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
@ -122,6 +122,9 @@ int icc_link_destroy(struct icc_node *src, struct icc_node *dst);
|
||||
void icc_node_add(struct icc_node *node, struct icc_provider *provider);
|
||||
void icc_node_del(struct icc_node *node);
|
||||
int icc_nodes_remove(struct icc_provider *provider);
|
||||
void icc_provider_init(struct icc_provider *provider);
|
||||
int icc_provider_register(struct icc_provider *provider);
|
||||
void icc_provider_deregister(struct icc_provider *provider);
|
||||
int icc_provider_add(struct icc_provider *provider);
|
||||
void icc_provider_del(struct icc_provider *provider);
|
||||
struct icc_node_data *of_icc_get_from_provider(struct of_phandle_args *spec);
|
||||
@ -167,6 +170,15 @@ static inline int icc_nodes_remove(struct icc_provider *provider)
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
static inline void icc_provider_init(struct icc_provider *provider) { }
|
||||
|
||||
static inline int icc_provider_register(struct icc_provider *provider)
|
||||
{
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
static inline void icc_provider_deregister(struct icc_provider *provider) { }
|
||||
|
||||
static inline int icc_provider_add(struct icc_provider *provider)
|
||||
{
|
||||
return -ENOTSUPP;
|
||||
|
Loading…
Reference in New Issue
Block a user