Skip to content

Commit

Permalink
iommu/mediatek: Add device link for smi-common and m4u
Browse files Browse the repository at this point in the history
In the lastest SoC, M4U has its special power domain. thus, If the engine
begin to work, it should help enable the power for M4U firstly.
Currently if the engine work, it always enable the power/clocks for
smi-larbs/smi-common. This patch adds device_link for smi-common and M4U.
then, if smi-common power is enabled, the M4U power also is powered on
automatically.

Normally M4U connect with several smi-larbs and their smi-common always
are the same, In this patch it get smi-common dev from the last smi-larb
device, then add the device_link.

Signed-off-by: Yong Wu <yong.wu@mediatek.com>
Reviewed-by: Tomasz Figa <tfiga@chromium.org>
Link: https://lore.kernel.org/r/20210111111914.22211-19-yong.wu@mediatek.com
Signed-off-by: Will Deacon <will@kernel.org>
  • Loading branch information
Yong Wu authored and Will Deacon committed Feb 1, 2021
1 parent 986d9ec commit baf94e6
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 3 deletions.
27 changes: 24 additions & 3 deletions drivers/iommu/mtk_iommu.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include <linux/of_irq.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
Expand Down Expand Up @@ -633,6 +634,9 @@ static int mtk_iommu_probe(struct platform_device *pdev)
{
struct mtk_iommu_data *data;
struct device *dev = &pdev->dev;
struct device_node *larbnode, *smicomm_node;
struct platform_device *plarbdev;
struct device_link *link;
struct resource *res;
resource_size_t ioaddr;
struct component_match *match = NULL;
Expand Down Expand Up @@ -699,8 +703,6 @@ static int mtk_iommu_probe(struct platform_device *pdev)
return larb_nr;

for (i = 0; i < larb_nr; i++) {
struct device_node *larbnode;
struct platform_device *plarbdev;
u32 id;

larbnode = of_parse_phandle(dev->of_node, "mediatek,larbs", i);
Expand All @@ -727,12 +729,28 @@ static int mtk_iommu_probe(struct platform_device *pdev)
compare_of, larbnode);
}

/* Get smi-common dev from the last larb. */
smicomm_node = of_parse_phandle(larbnode, "mediatek,smi", 0);
if (!smicomm_node)
return -EINVAL;

plarbdev = of_find_device_by_node(smicomm_node);
of_node_put(smicomm_node);
data->smicomm_dev = &plarbdev->dev;

link = device_link_add(data->smicomm_dev, dev,
DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME);
if (!link) {
dev_err(dev, "Unable link %s.\n", dev_name(data->smicomm_dev));
return -EINVAL;
}

platform_set_drvdata(pdev, data);

ret = iommu_device_sysfs_add(&data->iommu, dev, NULL,
"mtk-iommu.%pa", &ioaddr);
if (ret)
return ret;
goto out_link_remove;

iommu_device_set_ops(&data->iommu, &mtk_iommu_ops);
iommu_device_set_fwnode(&data->iommu, &pdev->dev.of_node->fwnode);
Expand Down Expand Up @@ -762,6 +780,8 @@ static int mtk_iommu_probe(struct platform_device *pdev)
iommu_device_unregister(&data->iommu);
out_sysfs_remove:
iommu_device_sysfs_remove(&data->iommu);
out_link_remove:
device_link_remove(data->smicomm_dev, dev);
return ret;
}

Expand All @@ -776,6 +796,7 @@ static int mtk_iommu_remove(struct platform_device *pdev)
bus_set_iommu(&platform_bus_type, NULL);

clk_disable_unprepare(data->bclk);
device_link_remove(data->smicomm_dev, &pdev->dev);
devm_free_irq(&pdev->dev, data->irq, data);
component_master_del(&pdev->dev, &mtk_iommu_com_ops);
return 0;
Expand Down
1 change: 1 addition & 0 deletions drivers/iommu/mtk_iommu.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ struct mtk_iommu_data {

struct iommu_device iommu;
const struct mtk_iommu_plat_data *plat_data;
struct device *smicomm_dev;

struct dma_iommu_mapping *mapping; /* For mtk_iommu_v1.c */

Expand Down

0 comments on commit baf94e6

Please sign in to comment.