MediaTek IOMMU block diagram always like below:
M4U
|
smi-common
|
-------------
| | ...
| |
larb1 larb2
| |
vdec venc
All the consumer connect with smi-larb, then connect with smi-common.
MediaTek IOMMU don't have its power-domain. When the consumer works,
it should enable the smi-larb's power which also need enable the smi-common's
power firstly.
Thus, Firstly, use the device link connect the consumer and the
smi-larbs. then add device link between the smi-larb and smi-common.
The ref_count of the device_link normally is over 1, when the consumer
device driver is removed, we should remove all the device_link, Hence,
I add the patch "driver core: xxx" at the beginning of this patchset.
After adding the device_link, then "mediatek,larb" property can be removed.
the iommu consumer don't need call the mtk_smi_larb_get/put to enable
the power and clock of smi-larb and smi-common.
This patchset depends on "MT8183 IOMMU SUPPORT"[1].
[1] https://lists.linuxfoundation.org/pipermail/iommu/2019-January/032387.html
Yong Wu (13):
dt-binding: mediatek: Get rid of mediatek,larb for multimedia HW
driver core: Remove the link if there is no driver with AUTO flag
iommu/mediatek: Add probe_defer for smi-larb
iommu/mediatek: Add device_link between the consumer and the larb
devices
memory: mtk-smi: Add device-link between smi-larb and smi-common
media: mtk-jpeg: Get rid of mtk_smi_larb_get/put
media: mtk-mdp: Get rid of mtk_smi_larb_get/put
media: mtk-vcodec: Get rid of mtk_smi_larb_get/put
drm/mediatek: Get rid of mtk_smi_larb_get/put
memory: mtk-smi: Get rid of mtk_smi_larb_get/put
iommu/mediatek: Use builtin_platform_driver
arm: dts: mediatek: Get rid of mediatek,larb for MM nodes
arm64: dts: mediatek: Get rid of mediatek,larb for MM nodes
.../bindings/display/mediatek/mediatek,disp.txt | 9 -----
.../bindings/media/mediatek-jpeg-decoder.txt | 4 ---
.../devicetree/bindings/media/mediatek-mdp.txt | 8 -----
.../devicetree/bindings/media/mediatek-vcodec.txt | 4 ---
arch/arm/boot/dts/mt2701.dtsi | 1 -
arch/arm/boot/dts/mt7623.dtsi | 1 -
arch/arm64/boot/dts/mediatek/mt8173.dtsi | 15 --------
drivers/base/core.c | 4 +--
drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 11 ------
drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 26 --------------
drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 1 -
drivers/iommu/mtk_iommu.c | 40 +++++++++-------------
drivers/iommu/mtk_iommu_v1.c | 32 ++++++++---------
drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c | 22 ------------
drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h | 2 --
drivers/media/platform/mtk-mdp/mtk_mdp_comp.c | 38 --------------------
drivers/media/platform/mtk-mdp/mtk_mdp_comp.h | 2 --
drivers/media/platform/mtk-mdp/mtk_mdp_core.c | 1 -
.../media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c | 19 ----------
drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h | 3 --
drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c | 1 -
.../media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c | 38 --------------------
drivers/memory/mtk-smi.c | 30 ++++------------
include/soc/mediatek/smi.h | 20 -----------
24 files changed, 40 insertions(+), 292 deletions(-)
--
1.9.1
MediaTek IOMMU has already added device_link between the consumer
and smi-larb device. If the jpg device call the pm_runtime_get_sync,
the smi-larb's pm_runtime_get_sync also be called automatically.
CC: Rick Chang <[email protected]>
Signed-off-by: Yong Wu <[email protected]>
---
drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c | 22 ----------------------
drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h | 2 --
2 files changed, 24 deletions(-)
diff --git a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c
index 2a5d500..23da32c 100644
--- a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c
+++ b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c
@@ -29,7 +29,6 @@
#include <media/v4l2-ioctl.h>
#include <media/videobuf2-core.h>
#include <media/videobuf2-dma-contig.h>
-#include <soc/mediatek/smi.h>
#include "mtk_jpeg_hw.h"
#include "mtk_jpeg_core.h"
@@ -901,11 +900,6 @@ static int mtk_jpeg_queue_init(void *priv, struct vb2_queue *src_vq,
static void mtk_jpeg_clk_on(struct mtk_jpeg_dev *jpeg)
{
- int ret;
-
- ret = mtk_smi_larb_get(jpeg->larb);
- if (ret)
- dev_err(jpeg->dev, "mtk_smi_larb_get larbvdec fail %d\n", ret);
clk_prepare_enable(jpeg->clk_jdec_smi);
clk_prepare_enable(jpeg->clk_jdec);
}
@@ -914,7 +908,6 @@ static void mtk_jpeg_clk_off(struct mtk_jpeg_dev *jpeg)
{
clk_disable_unprepare(jpeg->clk_jdec);
clk_disable_unprepare(jpeg->clk_jdec_smi);
- mtk_smi_larb_put(jpeg->larb);
}
static irqreturn_t mtk_jpeg_dec_irq(int irq, void *priv)
@@ -1059,21 +1052,6 @@ static int mtk_jpeg_release(struct file *file)
static int mtk_jpeg_clk_init(struct mtk_jpeg_dev *jpeg)
{
- struct device_node *node;
- struct platform_device *pdev;
-
- node = of_parse_phandle(jpeg->dev->of_node, "mediatek,larb", 0);
- if (!node)
- return -EINVAL;
- pdev = of_find_device_by_node(node);
- if (WARN_ON(!pdev)) {
- of_node_put(node);
- return -EINVAL;
- }
- of_node_put(node);
-
- jpeg->larb = &pdev->dev;
-
jpeg->clk_jdec = devm_clk_get(jpeg->dev, "jpgdec");
if (IS_ERR(jpeg->clk_jdec))
return PTR_ERR(jpeg->clk_jdec);
diff --git a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h
index 1a6cdfd..e35fb79 100644
--- a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h
+++ b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h
@@ -55,7 +55,6 @@ enum mtk_jpeg_ctx_state {
* @dec_reg_base: JPEG registers mapping
* @clk_jdec: JPEG hw working clock
* @clk_jdec_smi: JPEG SMI bus clock
- * @larb: SMI device
*/
struct mtk_jpeg_dev {
struct mutex lock;
@@ -69,7 +68,6 @@ struct mtk_jpeg_dev {
void __iomem *dec_reg_base;
struct clk *clk_jdec;
struct clk *clk_jdec_smi;
- struct device *larb;
};
/**
--
1.9.1
DL_FLAG_AUTOREMOVE_CONSUMER/SUPPLIER means "Remove the link
automatically on consumer/supplier driver unbind", that means we should
remove whole the device_link when there is no this driver no matter what
the ref_count of the link is.
CC: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Yong Wu <[email protected]>
---
The ref_count of our device_link normally is over 1. When the consumer
device driver is removed, whole the device_link should be removed.
Thus, I add this patch.
---
drivers/base/core.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 04bbcd7..4f3c5bc 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -511,7 +511,7 @@ static void __device_links_no_driver(struct device *dev)
continue;
if (link->flags & DL_FLAG_AUTOREMOVE_CONSUMER)
- kref_put(&link->kref, __device_link_del);
+ __device_link_del(&link->kref);
else if (link->status != DL_STATE_SUPPLIER_UNBIND)
WRITE_ONCE(link->status, DL_STATE_AVAILABLE);
}
@@ -556,7 +556,7 @@ void device_links_driver_cleanup(struct device *dev)
*/
if (link->status == DL_STATE_SUPPLIER_UNBIND &&
link->flags & DL_FLAG_AUTOREMOVE_SUPPLIER)
- kref_put(&link->kref, __device_link_del);
+ __device_link_del(&link->kref);
WRITE_ONCE(link->status, DL_STATE_DORMANT);
}
--
1.9.1
Normally, If the smi-larb HW need work, we should enable the smi-common
HW power and clock firstly.
This patch adds device-link between the smi-larb dev and the smi-common
dev. then If pm_runtime_get_sync(smi-larb-dev), the pm_runtime_get_sync
(smi-common-dev) will be called automatically.
Since smi is built-in driver like IOMMU and never unbound,
DL_FLAG_AUTOREMOVE_* is not needed.
CC: Matthias Brugger <[email protected]>
Suggested-by: Tomasz Figa <[email protected]>
Signed-off-by: Yong Wu <[email protected]>
---
drivers/memory/mtk-smi.c | 16 +++++++---------
1 file changed, 7 insertions(+), 9 deletions(-)
diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c
index 9688341..30930e4 100644
--- a/drivers/memory/mtk-smi.c
+++ b/drivers/memory/mtk-smi.c
@@ -271,6 +271,7 @@ static int mtk_smi_larb_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct device_node *smi_node;
struct platform_device *smi_pdev;
+ struct device_link *link;
larb = devm_kzalloc(dev, sizeof(*larb), GFP_KERNEL);
if (!larb)
@@ -310,6 +311,12 @@ static int mtk_smi_larb_probe(struct platform_device *pdev)
if (!platform_get_drvdata(smi_pdev))
return -EPROBE_DEFER;
larb->smi_common_dev = &smi_pdev->dev;
+ link = device_link_add(dev, larb->smi_common_dev,
+ DL_FLAG_PM_RUNTIME);
+ if (!link) {
+ dev_err(dev, "Unable to link smi-common dev\n");
+ return -ENODEV;
+ }
} else {
dev_err(dev, "Failed to get the smi_common device\n");
return -EINVAL;
@@ -333,17 +340,9 @@ static int __maybe_unused mtk_smi_larb_resume(struct device *dev)
const struct mtk_smi_larb_gen *larb_gen = larb->larb_gen;
int ret;
- /* Power on smi-common. */
- ret = pm_runtime_get_sync(larb->smi_common_dev);
- if (ret < 0) {
- dev_err(dev, "Failed to pm get for smi-common(%d).\n", ret);
- return ret;
- }
-
ret = mtk_smi_clk_enable(&larb->smi);
if (ret < 0) {
dev_err(dev, "Failed to enable clock(%d).\n", ret);
- pm_runtime_put_sync(larb->smi_common_dev);
return ret;
}
@@ -358,7 +357,6 @@ static int __maybe_unused mtk_smi_larb_suspend(struct device *dev)
struct mtk_smi_larb *larb = dev_get_drvdata(dev);
mtk_smi_clk_disable(&larb->smi);
- pm_runtime_put_sync(larb->smi_common_dev);
return 0;
}
--
1.9.1
MediaTek IOMMU don't have its power-domain. all the consumer connect
with smi-larb, then connect with smi-common.
M4U
|
smi-common
|
-------------
| | ...
| |
larb1 larb2
| |
vdec venc
When the consumer works, it should enable the smi-larb's power which
also need enable the smi-common's power firstly.
Thus, First of all, use the device link connect the consumer and the
smi-larbs. then add device link between the smi-larb and smi-common.
This patch adds device_link between the consumer and the larbs.
Suggested-by: Tomasz Figa <[email protected]>
Signed-off-by: Yong Wu <[email protected]>
---
drivers/iommu/mtk_iommu.c | 15 +++++++++++++--
drivers/iommu/mtk_iommu_v1.c | 14 ++++++++++++--
2 files changed, 25 insertions(+), 4 deletions(-)
diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 202e41b..735ae8d 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -247,6 +247,7 @@ static void mtk_iommu_config(struct mtk_iommu_data *data,
struct mtk_smi_larb_iommu *larb_mmu;
unsigned int larbid, portid;
struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
+ struct device_link *link;
int i;
for (i = 0; i < fwspec->num_ids; ++i) {
@@ -257,10 +258,20 @@ static void mtk_iommu_config(struct mtk_iommu_data *data,
dev_dbg(dev, "%s iommu port: %d\n",
enable ? "enable" : "disable", portid);
- if (enable)
+ if (enable) {
larb_mmu->mmu |= MTK_SMI_MMU_EN(portid);
- else
+ /* Link the consumer with the larb device(supplier) */
+ link = device_link_add(dev, larb_mmu->dev,
+ DL_FLAG_PM_RUNTIME |
+ DL_FLAG_AUTOREMOVE_CONSUMER);
+ if (!link) {
+ dev_err(dev, "Unable to link %s\n",
+ dev_name(larb_mmu->dev));
+ return;
+ }
+ } else {
larb_mmu->mmu &= ~MTK_SMI_MMU_EN(portid);
+ }
}
}
diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c
index 9386aee..022bad9 100644
--- a/drivers/iommu/mtk_iommu_v1.c
+++ b/drivers/iommu/mtk_iommu_v1.c
@@ -201,6 +201,7 @@ static void mtk_iommu_config(struct mtk_iommu_data *data,
struct mtk_smi_larb_iommu *larb_mmu;
unsigned int larbid, portid;
struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
+ struct device_link *link;
int i;
for (i = 0; i < fwspec->num_ids; ++i) {
@@ -211,10 +212,19 @@ static void mtk_iommu_config(struct mtk_iommu_data *data,
dev_dbg(dev, "%s iommu port: %d\n",
enable ? "enable" : "disable", portid);
- if (enable)
+ if (enable) {
larb_mmu->mmu |= MTK_SMI_MMU_EN(portid);
- else
+ link = device_link_add(dev, larb_mmu->dev,
+ DL_FLAG_PM_RUNTIME |
+ DL_FLAG_AUTOREMOVE_CONSUMER);
+ if (!link) {
+ dev_err(dev, "Unable to link %s\n",
+ dev_name(larb_mmu->dev));
+ return;
+ }
+ } else {
larb_mmu->mmu &= ~MTK_SMI_MMU_EN(portid);
+ }
}
}
--
1.9.1
MediaTek IOMMU has already added the device_link between the consumer
and smi-larb device. If the mdp device call the pm_runtime_get_sync,
the smi-larb's pm_runtime_get_sync also be called automatically.
CC: Minghsiu Tsai <[email protected]>
Signed-off-by: Yong Wu <[email protected]>
---
drivers/media/platform/mtk-mdp/mtk_mdp_comp.c | 38 ---------------------------
drivers/media/platform/mtk-mdp/mtk_mdp_comp.h | 2 --
drivers/media/platform/mtk-mdp/mtk_mdp_core.c | 1 -
3 files changed, 41 deletions(-)
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
index 03aba03..4f7cbc4 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
@@ -17,7 +17,6 @@
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_platform.h>
-#include <soc/mediatek/smi.h>
#include "mtk_mdp_comp.h"
@@ -66,14 +65,6 @@ void mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp)
{
int i, err;
- if (comp->larb_dev) {
- err = mtk_smi_larb_get(comp->larb_dev);
- if (err)
- dev_err(dev,
- "failed to get larb, err %d. type:%d id:%d\n",
- err, comp->type, comp->id);
- }
-
for (i = 0; i < ARRAY_SIZE(comp->clk); i++) {
if (IS_ERR(comp->clk[i]))
continue;
@@ -94,16 +85,11 @@ void mtk_mdp_comp_clock_off(struct device *dev, struct mtk_mdp_comp *comp)
continue;
clk_disable_unprepare(comp->clk[i]);
}
-
- if (comp->larb_dev)
- mtk_smi_larb_put(comp->larb_dev);
}
int mtk_mdp_comp_init(struct device *dev, struct device_node *node,
struct mtk_mdp_comp *comp, enum mtk_mdp_comp_id comp_id)
{
- struct device_node *larb_node;
- struct platform_device *larb_pdev;
int i;
if (comp_id < 0 || comp_id >= MTK_MDP_COMP_ID_MAX) {
@@ -124,30 +110,6 @@ int mtk_mdp_comp_init(struct device *dev, struct device_node *node,
break;
}
- /* Only DMA capable components need the LARB property */
- comp->larb_dev = NULL;
- if (comp->type != MTK_MDP_RDMA &&
- comp->type != MTK_MDP_WDMA &&
- comp->type != MTK_MDP_WROT)
- return 0;
-
- larb_node = of_parse_phandle(node, "mediatek,larb", 0);
- if (!larb_node) {
- dev_err(dev,
- "Missing mediadek,larb phandle in %pOF node\n", node);
- return -EINVAL;
- }
-
- larb_pdev = of_find_device_by_node(larb_node);
- if (!larb_pdev) {
- dev_warn(dev, "Waiting for larb device %pOF\n", larb_node);
- of_node_put(larb_node);
- return -EPROBE_DEFER;
- }
- of_node_put(larb_node);
-
- comp->larb_dev = &larb_pdev->dev;
-
return 0;
}
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
index 63b3983..602d577 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
@@ -47,7 +47,6 @@ enum mtk_mdp_comp_id {
* @dev_node: component device node
* @clk: clocks required for component
* @regs: Mapped address of component registers.
- * @larb_dev: SMI device required for component
* @type: component type
* @id: component ID
*/
@@ -55,7 +54,6 @@ struct mtk_mdp_comp {
struct device_node *dev_node;
struct clk *clk[2];
void __iomem *regs;
- struct device *larb_dev;
enum mtk_mdp_comp_type type;
enum mtk_mdp_comp_id id;
};
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
index bbb24fb..adb098d 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
@@ -25,7 +25,6 @@
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/workqueue.h>
-#include <soc/mediatek/smi.h>
#include "mtk_mdp_core.h"
#include "mtk_mdp_m2m.h"
--
1.9.1
After adding device_link between the consumer with the smi-larbs,
if the consumer call its owner pm_runtime_get(_sync), the
pm_runtime_get(_sync) of smi-larb and smi-common will be called
automatically. Thus, the consumer don't need the property.
And IOMMU also know which larb this consumer connects with from
iommu id in the "iommus=" property.
Signed-off-by: Yong Wu <[email protected]>
---
I guess it should go through Matthias's tree if the patch is ok,
thus I don't separate to different patches. If it's really needed,
please feel free to tell me.
---
.../devicetree/bindings/display/mediatek/mediatek,disp.txt | 9 ---------
.../devicetree/bindings/media/mediatek-jpeg-decoder.txt | 4 ----
Documentation/devicetree/bindings/media/mediatek-mdp.txt | 8 --------
Documentation/devicetree/bindings/media/mediatek-vcodec.txt | 4 ----
4 files changed, 25 deletions(-)
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt b/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt
index 8469de5..464b92f 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt
@@ -56,8 +56,6 @@ Required properties (DMA function blocks):
"mediatek,<chip>-disp-rdma"
"mediatek,<chip>-disp-wdma"
the supported chips are mt2701 and mt8173.
-- larb: Should contain a phandle pointing to the local arbiter device as defined
- in Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt
- iommus: Should point to the respective IOMMU block with master port as
argument, see Documentation/devicetree/bindings/iommu/mediatek,iommu.txt
for details.
@@ -78,7 +76,6 @@ ovl0: ovl@1400c000 {
power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
clocks = <&mmsys CLK_MM_DISP_OVL0>;
iommus = <&iommu M4U_PORT_DISP_OVL0>;
- mediatek,larb = <&larb0>;
};
ovl1: ovl@1400d000 {
@@ -88,7 +85,6 @@ ovl1: ovl@1400d000 {
power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
clocks = <&mmsys CLK_MM_DISP_OVL1>;
iommus = <&iommu M4U_PORT_DISP_OVL1>;
- mediatek,larb = <&larb4>;
};
rdma0: rdma@1400e000 {
@@ -98,7 +94,6 @@ rdma0: rdma@1400e000 {
power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
clocks = <&mmsys CLK_MM_DISP_RDMA0>;
iommus = <&iommu M4U_PORT_DISP_RDMA0>;
- mediatek,larb = <&larb0>;
};
rdma1: rdma@1400f000 {
@@ -108,7 +103,6 @@ rdma1: rdma@1400f000 {
power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
clocks = <&mmsys CLK_MM_DISP_RDMA1>;
iommus = <&iommu M4U_PORT_DISP_RDMA1>;
- mediatek,larb = <&larb4>;
};
rdma2: rdma@14010000 {
@@ -118,7 +112,6 @@ rdma2: rdma@14010000 {
power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
clocks = <&mmsys CLK_MM_DISP_RDMA2>;
iommus = <&iommu M4U_PORT_DISP_RDMA2>;
- mediatek,larb = <&larb4>;
};
wdma0: wdma@14011000 {
@@ -128,7 +121,6 @@ wdma0: wdma@14011000 {
power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
clocks = <&mmsys CLK_MM_DISP_WDMA0>;
iommus = <&iommu M4U_PORT_DISP_WDMA0>;
- mediatek,larb = <&larb0>;
};
wdma1: wdma@14012000 {
@@ -138,7 +130,6 @@ wdma1: wdma@14012000 {
power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
clocks = <&mmsys CLK_MM_DISP_WDMA1>;
iommus = <&iommu M4U_PORT_DISP_WDMA1>;
- mediatek,larb = <&larb4>;
};
color0: color@14013000 {
diff --git a/Documentation/devicetree/bindings/media/mediatek-jpeg-decoder.txt b/Documentation/devicetree/bindings/media/mediatek-jpeg-decoder.txt
index 044b119..7978f21 100644
--- a/Documentation/devicetree/bindings/media/mediatek-jpeg-decoder.txt
+++ b/Documentation/devicetree/bindings/media/mediatek-jpeg-decoder.txt
@@ -15,9 +15,6 @@ Required properties:
- clock-names: must contain "jpgdec-smi" and "jpgdec".
- power-domains: a phandle to the power domain, see
Documentation/devicetree/bindings/power/power_domain.txt for details.
-- mediatek,larb: must contain the local arbiters in the current Socs, see
- Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt
- for details.
- iommus: should point to the respective IOMMU block with master port as
argument, see Documentation/devicetree/bindings/iommu/mediatek,iommu.txt
for details.
@@ -32,7 +29,6 @@ Example:
clock-names = "jpgdec-smi",
"jpgdec";
power-domains = <&scpsys MT2701_POWER_DOMAIN_ISP>;
- mediatek,larb = <&larb2>;
iommus = <&iommu MT2701_M4U_PORT_JPGDEC_WDMA>,
<&iommu MT2701_M4U_PORT_JPGDEC_BSDMA>;
};
diff --git a/Documentation/devicetree/bindings/media/mediatek-mdp.txt b/Documentation/devicetree/bindings/media/mediatek-mdp.txt
index 0d03e3a..df69c5a 100644
--- a/Documentation/devicetree/bindings/media/mediatek-mdp.txt
+++ b/Documentation/devicetree/bindings/media/mediatek-mdp.txt
@@ -27,9 +27,6 @@ Required properties (DMA function blocks, child node):
- iommus: should point to the respective IOMMU block with master port as
argument, see Documentation/devicetree/bindings/iommu/mediatek,iommu.txt
for details.
-- mediatek,larb: must contain the local arbiters in the current Socs, see
- Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt
- for details.
Example:
mdp_rdma0: rdma@14001000 {
@@ -40,7 +37,6 @@ Example:
<&mmsys CLK_MM_MUTEX_32K>;
power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
iommus = <&iommu M4U_PORT_MDP_RDMA0>;
- mediatek,larb = <&larb0>;
mediatek,vpu = <&vpu>;
};
@@ -51,7 +47,6 @@ Example:
<&mmsys CLK_MM_MUTEX_32K>;
power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
iommus = <&iommu M4U_PORT_MDP_RDMA1>;
- mediatek,larb = <&larb4>;
};
mdp_rsz0: rsz@14003000 {
@@ -81,7 +76,6 @@ Example:
clocks = <&mmsys CLK_MM_MDP_WDMA>;
power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
iommus = <&iommu M4U_PORT_MDP_WDMA>;
- mediatek,larb = <&larb0>;
};
mdp_wrot0: wrot@14007000 {
@@ -90,7 +84,6 @@ Example:
clocks = <&mmsys CLK_MM_MDP_WROT0>;
power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
iommus = <&iommu M4U_PORT_MDP_WROT0>;
- mediatek,larb = <&larb0>;
};
mdp_wrot1: wrot@14008000 {
@@ -99,5 +92,4 @@ Example:
clocks = <&mmsys CLK_MM_MDP_WROT1>;
power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
iommus = <&iommu M4U_PORT_MDP_WROT1>;
- mediatek,larb = <&larb4>;
};
diff --git a/Documentation/devicetree/bindings/media/mediatek-vcodec.txt b/Documentation/devicetree/bindings/media/mediatek-vcodec.txt
index 2a615d8..a5d82a7 100644
--- a/Documentation/devicetree/bindings/media/mediatek-vcodec.txt
+++ b/Documentation/devicetree/bindings/media/mediatek-vcodec.txt
@@ -9,7 +9,6 @@ Required properties:
- reg : Physical base address of the video codec registers and length of
memory mapped region.
- interrupts : interrupt number to the cpu.
-- mediatek,larb : must contain the local arbiters in the current Socs.
- clocks : list of clock specifiers, corresponding to entries in
the clock-names property.
- clock-names: encoder must contain "venc_sel_src", "venc_sel",,
@@ -39,7 +38,6 @@ vcodec_dec: vcodec@16000000 {
<0 0x16027800 0 0x800>, /*VP8_VL*/
<0 0x16028400 0 0x400>; /*VP9_VD*/
interrupts = <GIC_SPI 204 IRQ_TYPE_LEVEL_LOW>;
- mediatek,larb = <&larb1>;
iommus = <&iommu M4U_PORT_HW_VDEC_MC_EXT>,
<&iommu M4U_PORT_HW_VDEC_PP_EXT>,
<&iommu M4U_PORT_HW_VDEC_AVC_MV_EXT>,
@@ -74,8 +72,6 @@ vcodec_dec: vcodec@16000000 {
<0 0x19002000 0 0x1000>; /*VENC_LT_SYS*/
interrupts = <GIC_SPI 198 IRQ_TYPE_LEVEL_LOW>,
<GIC_SPI 202 IRQ_TYPE_LEVEL_LOW>;
- mediatek,larb = <&larb3>,
- <&larb5>;
iommus = <&iommu M4U_PORT_VENC_RCPU>,
<&iommu M4U_PORT_VENC_REC>,
<&iommu M4U_PORT_VENC_BSDMA>,
--
1.9.1
The iommu consumer should use device_link to connect with the
smi-larb(supplier). then the smi-larb should run before the iommu
consumer. Here we delay the iommu driver until the smi driver is
ready, then all the iommu consumer always is after the smi driver.
When there is no this patch, if some consumer drivers run before
smi-larb, the supplier link_status is DL_DEV_NO_DRIVER(0) in the
device_link_add, then device_links_driver_bound will use WARN_ON
to complain that the link_status of supplier is not right.
This is a preparing patch for adding device_link.
Signed-off-by: Yong Wu <[email protected]>
---
drivers/iommu/mtk_iommu.c | 2 +-
drivers/iommu/mtk_iommu_v1.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 36526c9..202e41b 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -645,7 +645,7 @@ static int mtk_iommu_probe(struct platform_device *pdev)
id = i;
plarbdev = of_find_device_by_node(larbnode);
- if (!plarbdev)
+ if (!plarbdev || !plarbdev->dev.driver)
return -EPROBE_DEFER;
data->smi_imu.larb_imu[id].dev = &plarbdev->dev;
diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c
index f8b8275..9386aee 100644
--- a/drivers/iommu/mtk_iommu_v1.c
+++ b/drivers/iommu/mtk_iommu_v1.c
@@ -601,7 +601,7 @@ static int mtk_iommu_probe(struct platform_device *pdev)
plarbdev = of_platform_device_create(
larb_spec.np, NULL,
platform_bus_type.dev_root);
- if (!plarbdev) {
+ if (!plarbdev || !plarbdev->dev.driver) {
of_node_put(larb_spec.np);
return -EPROBE_DEFER;
}
--
1.9.1
MediaTek IOMMU has already added the device_link between the consumer
and smi-larb device. If the vcodec device call the pm_runtime_get_sync,
the smi-larb's pm_runtime_get_sync also be called automatically.
CC: Tiffany Lin <[email protected]>
Signed-off-by: Yong Wu <[email protected]>
---
.../media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c | 19 -----------
drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h | 3 --
drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c | 1 -
.../media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c | 38 ----------------------
4 files changed, 61 deletions(-)
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
index 79ca03a..90e1641 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
@@ -16,7 +16,6 @@
#include <linux/of_address.h>
#include <linux/of_platform.h>
#include <linux/pm_runtime.h>
-#include <soc/mediatek/smi.h>
#include "mtk_vcodec_dec_pm.h"
#include "mtk_vcodec_util.h"
@@ -24,7 +23,6 @@
int mtk_vcodec_init_dec_pm(struct mtk_vcodec_dev *mtkdev)
{
- struct device_node *node;
struct platform_device *pdev;
struct mtk_vcodec_pm *pm;
int ret = 0;
@@ -32,18 +30,7 @@ int mtk_vcodec_init_dec_pm(struct mtk_vcodec_dev *mtkdev)
pdev = mtkdev->plat_dev;
pm = &mtkdev->pm;
pm->mtkdev = mtkdev;
- node = of_parse_phandle(pdev->dev.of_node, "mediatek,larb", 0);
- if (!node) {
- mtk_v4l2_err("of_parse_phandle mediatek,larb fail!");
- return -1;
- }
- pdev = of_find_device_by_node(node);
- if (WARN_ON(!pdev)) {
- of_node_put(node);
- return -1;
- }
- pm->larbvdec = &pdev->dev;
pdev = mtkdev->plat_dev;
pm->dev = &pdev->dev;
@@ -181,16 +168,10 @@ void mtk_vcodec_dec_clock_on(struct mtk_vcodec_pm *pm)
ret = clk_set_parent(pm->vdec_sel, pm->vdecpll);
if (ret)
mtk_v4l2_err("clk_set_parent vdec_sel vdecpll fail %d", ret);
-
- ret = mtk_smi_larb_get(pm->larbvdec);
- if (ret)
- mtk_v4l2_err("mtk_smi_larb_get larbvdec fail %d", ret);
-
}
void mtk_vcodec_dec_clock_off(struct mtk_vcodec_pm *pm)
{
- mtk_smi_larb_put(pm->larbvdec);
clk_disable_unprepare(pm->vdec_sel);
clk_disable_unprepare(pm->vdecpll);
clk_disable_unprepare(pm->univpll_d2);
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index 3cffb38..2696e14 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -191,9 +191,6 @@ struct mtk_vcodec_pm {
struct clk *venc_sel;
struct clk *univpll1_d2;
struct clk *venc_lt_sel;
- struct device *larbvdec;
- struct device *larbvenc;
- struct device *larbvenclt;
struct device *dev;
struct mtk_vcodec_dev *mtkdev;
};
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c
index 54631ad..7401619 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c
@@ -16,7 +16,6 @@
#include <media/v4l2-event.h>
#include <media/v4l2-mem2mem.h>
#include <media/videobuf2-dma-contig.h>
-#include <soc/mediatek/smi.h>
#include "mtk_vcodec_drv.h"
#include "mtk_vcodec_enc.h"
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c
index 3e73e9d..a3abd3d 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c
@@ -16,7 +16,6 @@
#include <linux/of_address.h>
#include <linux/of_platform.h>
#include <linux/pm_runtime.h>
-#include <soc/mediatek/smi.h>
#include "mtk_vcodec_enc_pm.h"
#include "mtk_vcodec_util.h"
@@ -25,7 +24,6 @@
int mtk_vcodec_init_enc_pm(struct mtk_vcodec_dev *mtkdev)
{
- struct device_node *node;
struct platform_device *pdev;
struct device *dev;
struct mtk_vcodec_pm *pm;
@@ -38,31 +36,6 @@ int mtk_vcodec_init_enc_pm(struct mtk_vcodec_dev *mtkdev)
pm->dev = &pdev->dev;
dev = &pdev->dev;
- node = of_parse_phandle(dev->of_node, "mediatek,larb", 0);
- if (!node) {
- mtk_v4l2_err("no mediatek,larb found");
- return -1;
- }
- pdev = of_find_device_by_node(node);
- if (!pdev) {
- mtk_v4l2_err("no mediatek,larb device found");
- return -1;
- }
- pm->larbvenc = &pdev->dev;
-
- node = of_parse_phandle(dev->of_node, "mediatek,larb", 1);
- if (!node) {
- mtk_v4l2_err("no mediatek,larb found");
- return -1;
- }
-
- pdev = of_find_device_by_node(node);
- if (!pdev) {
- mtk_v4l2_err("no mediatek,larb device found");
- return -1;
- }
-
- pm->larbvenclt = &pdev->dev;
pdev = mtkdev->plat_dev;
pm->dev = &pdev->dev;
@@ -117,21 +90,10 @@ void mtk_vcodec_enc_clock_on(struct mtk_vcodec_pm *pm)
ret = clk_set_parent(pm->venc_lt_sel, pm->univpll1_d2);
if (ret)
mtk_v4l2_err("clk_set_parent fail %d", ret);
-
- ret = mtk_smi_larb_get(pm->larbvenc);
- if (ret)
- mtk_v4l2_err("mtk_smi_larb_get larb3 fail %d", ret);
-
- ret = mtk_smi_larb_get(pm->larbvenclt);
- if (ret)
- mtk_v4l2_err("mtk_smi_larb_get larb4 fail %d", ret);
-
}
void mtk_vcodec_enc_clock_off(struct mtk_vcodec_pm *pm)
{
- mtk_smi_larb_put(pm->larbvenc);
- mtk_smi_larb_put(pm->larbvenclt);
clk_disable_unprepare(pm->venc_lt_sel);
clk_disable_unprepare(pm->venc_sel);
}
--
1.9.1
After adding device_link between the iommu consumer and smi-larb,
the pm_runtime_get(_sync) of smi-larb and smi-common will be called
automatically. we can get rid of mtk_smi_larb_get/put.
CC: Matthias Brugger <[email protected]>
Signed-off-by: Yong Wu <[email protected]>
---
drivers/memory/mtk-smi.c | 14 --------------
include/soc/mediatek/smi.h | 20 --------------------
2 files changed, 34 deletions(-)
diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c
index 30930e4..a1dc34b 100644
--- a/drivers/memory/mtk-smi.c
+++ b/drivers/memory/mtk-smi.c
@@ -123,20 +123,6 @@ static void mtk_smi_clk_disable(const struct mtk_smi *smi)
clk_disable_unprepare(smi->clk_apb);
}
-int mtk_smi_larb_get(struct device *larbdev)
-{
- int ret = pm_runtime_get_sync(larbdev);
-
- return (ret < 0) ? ret : 0;
-}
-EXPORT_SYMBOL_GPL(mtk_smi_larb_get);
-
-void mtk_smi_larb_put(struct device *larbdev)
-{
- pm_runtime_put_sync(larbdev);
-}
-EXPORT_SYMBOL_GPL(mtk_smi_larb_put);
-
static int
mtk_smi_larb_bind(struct device *dev, struct device *master, void *data)
{
diff --git a/include/soc/mediatek/smi.h b/include/soc/mediatek/smi.h
index 2b410d2..b993aa2 100644
--- a/include/soc/mediatek/smi.h
+++ b/include/soc/mediatek/smi.h
@@ -25,26 +25,6 @@ struct mtk_smi_iommu {
struct mtk_smi_larb_iommu larb_imu[MTK_LARB_NR_MAX];
};
-/*
- * mtk_smi_larb_get: Enable the power domain and clocks for this local arbiter.
- * It also initialize some basic setting(like iommu).
- * mtk_smi_larb_put: Disable the power domain and clocks for this local arbiter.
- * Both should be called in non-atomic context.
- *
- * Returns 0 if successful, negative on failure.
- */
-int mtk_smi_larb_get(struct device *larbdev);
-void mtk_smi_larb_put(struct device *larbdev);
-
-#else
-
-static inline int mtk_smi_larb_get(struct device *larbdev)
-{
- return 0;
-}
-
-static inline void mtk_smi_larb_put(struct device *larbdev) { }
-
#endif
#endif
--
1.9.1
After adding device_link between the IOMMU consumer and smi,
the mediatek,larb is unnecessary now.
CC: Matthias Brugger <[email protected]>
Signed-off-by: Yong Wu <[email protected]>
---
arch/arm64/boot/dts/mediatek/mt8173.dtsi | 15 ---------------
1 file changed, 15 deletions(-)
diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
index abd2f15..8babd71 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
@@ -895,7 +895,6 @@
<&mmsys CLK_MM_MUTEX_32K>;
power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
iommus = <&iommu M4U_PORT_MDP_RDMA0>;
- mediatek,larb = <&larb0>;
mediatek,vpu = <&vpu>;
};
@@ -906,7 +905,6 @@
<&mmsys CLK_MM_MUTEX_32K>;
power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
iommus = <&iommu M4U_PORT_MDP_RDMA1>;
- mediatek,larb = <&larb4>;
};
mdp_rsz0: rsz@14003000 {
@@ -936,7 +934,6 @@
clocks = <&mmsys CLK_MM_MDP_WDMA>;
power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
iommus = <&iommu M4U_PORT_MDP_WDMA>;
- mediatek,larb = <&larb0>;
};
mdp_wrot0: wrot@14007000 {
@@ -945,7 +942,6 @@
clocks = <&mmsys CLK_MM_MDP_WROT0>;
power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
iommus = <&iommu M4U_PORT_MDP_WROT0>;
- mediatek,larb = <&larb0>;
};
mdp_wrot1: wrot@14008000 {
@@ -954,7 +950,6 @@
clocks = <&mmsys CLK_MM_MDP_WROT1>;
power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
iommus = <&iommu M4U_PORT_MDP_WROT1>;
- mediatek,larb = <&larb4>;
};
ovl0: ovl@1400c000 {
@@ -964,7 +959,6 @@
power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
clocks = <&mmsys CLK_MM_DISP_OVL0>;
iommus = <&iommu M4U_PORT_DISP_OVL0>;
- mediatek,larb = <&larb0>;
};
ovl1: ovl@1400d000 {
@@ -974,7 +968,6 @@
power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
clocks = <&mmsys CLK_MM_DISP_OVL1>;
iommus = <&iommu M4U_PORT_DISP_OVL1>;
- mediatek,larb = <&larb4>;
};
rdma0: rdma@1400e000 {
@@ -984,7 +977,6 @@
power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
clocks = <&mmsys CLK_MM_DISP_RDMA0>;
iommus = <&iommu M4U_PORT_DISP_RDMA0>;
- mediatek,larb = <&larb0>;
};
rdma1: rdma@1400f000 {
@@ -994,7 +986,6 @@
power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
clocks = <&mmsys CLK_MM_DISP_RDMA1>;
iommus = <&iommu M4U_PORT_DISP_RDMA1>;
- mediatek,larb = <&larb4>;
};
rdma2: rdma@14010000 {
@@ -1004,7 +995,6 @@
power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
clocks = <&mmsys CLK_MM_DISP_RDMA2>;
iommus = <&iommu M4U_PORT_DISP_RDMA2>;
- mediatek,larb = <&larb4>;
};
wdma0: wdma@14011000 {
@@ -1014,7 +1004,6 @@
power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
clocks = <&mmsys CLK_MM_DISP_WDMA0>;
iommus = <&iommu M4U_PORT_DISP_WDMA0>;
- mediatek,larb = <&larb0>;
};
wdma1: wdma@14012000 {
@@ -1024,7 +1013,6 @@
power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
clocks = <&mmsys CLK_MM_DISP_WDMA1>;
iommus = <&iommu M4U_PORT_DISP_WDMA1>;
- mediatek,larb = <&larb4>;
};
color0: color@14013000 {
@@ -1268,7 +1256,6 @@
<0 0x16027800 0 0x800>, /* VDEC_HWB */
<0 0x16028400 0 0x400>; /* VDEC_HWG */
interrupts = <GIC_SPI 204 IRQ_TYPE_LEVEL_LOW>;
- mediatek,larb = <&larb1>;
iommus = <&iommu M4U_PORT_HW_VDEC_MC_EXT>,
<&iommu M4U_PORT_HW_VDEC_PP_EXT>,
<&iommu M4U_PORT_HW_VDEC_AVC_MV_EXT>,
@@ -1329,8 +1316,6 @@
<0 0x19002000 0 0x1000>; /* VENC_LT_SYS */
interrupts = <GIC_SPI 198 IRQ_TYPE_LEVEL_LOW>,
<GIC_SPI 202 IRQ_TYPE_LEVEL_LOW>;
- mediatek,larb = <&larb3>,
- <&larb5>;
iommus = <&iommu M4U_PORT_VENC_RCPU>,
<&iommu M4U_PORT_VENC_REC>,
<&iommu M4U_PORT_VENC_BSDMA>,
--
1.9.1
After adding device_link between the IOMMU consumer and smi,
the mediatek,larb is unnecessary now.
CC: Matthias Brugger <[email protected]>
Signed-off-by: Yong Wu <[email protected]>
---
arch/arm/boot/dts/mt2701.dtsi | 1 -
arch/arm/boot/dts/mt7623.dtsi | 1 -
2 files changed, 2 deletions(-)
diff --git a/arch/arm/boot/dts/mt2701.dtsi b/arch/arm/boot/dts/mt2701.dtsi
index 180377e..938fa31 100644
--- a/arch/arm/boot/dts/mt2701.dtsi
+++ b/arch/arm/boot/dts/mt2701.dtsi
@@ -563,7 +563,6 @@
clock-names = "jpgdec-smi",
"jpgdec";
power-domains = <&scpsys MT2701_POWER_DOMAIN_ISP>;
- mediatek,larb = <&larb2>;
iommus = <&iommu MT2701_M4U_PORT_JPGDEC_WDMA>,
<&iommu MT2701_M4U_PORT_JPGDEC_BSDMA>;
};
diff --git a/arch/arm/boot/dts/mt7623.dtsi b/arch/arm/boot/dts/mt7623.dtsi
index d01bdee..c831398 100644
--- a/arch/arm/boot/dts/mt7623.dtsi
+++ b/arch/arm/boot/dts/mt7623.dtsi
@@ -774,7 +774,6 @@
clock-names = "jpgdec-smi",
"jpgdec";
power-domains = <&scpsys MT2701_POWER_DOMAIN_ISP>;
- mediatek,larb = <&larb2>;
iommus = <&iommu MT2701_M4U_PORT_JPGDEC_WDMA>,
<&iommu MT2701_M4U_PORT_JPGDEC_BSDMA>;
};
--
1.9.1
MediaTek IOMMU has already added the device_link between the consumer
and smi-larb device. If the drm device call the pm_runtime_get_sync,
the smi-larb's pm_runtime_get_sync also be called automatically.
CC: CK Hu <[email protected]>
CC: Philipp Zabel <[email protected]>
Signed-off-by: Yong Wu <[email protected]>
---
drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 11 -----------
drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 26 --------------------------
drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 1 -
3 files changed, 38 deletions(-)
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
index 92ecb9b..fbf859e 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
@@ -18,7 +18,6 @@
#include <drm/drm_plane_helper.h>
#include <linux/clk.h>
#include <linux/pm_runtime.h>
-#include <soc/mediatek/smi.h>
#include "mtk_drm_drv.h"
#include "mtk_drm_crtc.h"
@@ -371,20 +370,12 @@ static void mtk_drm_crtc_atomic_enable(struct drm_crtc *crtc,
struct drm_crtc_state *old_state)
{
struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
- struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[0];
int ret;
DRM_DEBUG_DRIVER("%s %d\n", __func__, crtc->base.id);
- ret = mtk_smi_larb_get(comp->larb_dev);
- if (ret) {
- DRM_ERROR("Failed to get larb: %d\n", ret);
- return;
- }
-
ret = mtk_crtc_ddp_hw_init(mtk_crtc);
if (ret) {
- mtk_smi_larb_put(comp->larb_dev);
return;
}
@@ -396,7 +387,6 @@ static void mtk_drm_crtc_atomic_disable(struct drm_crtc *crtc,
struct drm_crtc_state *old_state)
{
struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
- struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[0];
int i;
DRM_DEBUG_DRIVER("%s %d\n", __func__, crtc->base.id);
@@ -419,7 +409,6 @@ static void mtk_drm_crtc_atomic_disable(struct drm_crtc *crtc,
drm_crtc_vblank_off(crtc);
mtk_crtc_ddp_hw_fini(mtk_crtc);
- mtk_smi_larb_put(comp->larb_dev);
mtk_crtc->enabled = false;
}
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
index 54ca794..ede15c9 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
@@ -265,8 +265,6 @@ int mtk_ddp_comp_init(struct device *dev, struct device_node *node,
const struct mtk_ddp_comp_funcs *funcs)
{
enum mtk_ddp_comp_type type;
- struct device_node *larb_node;
- struct platform_device *larb_pdev;
if (comp_id < 0 || comp_id >= DDP_COMPONENT_ID_MAX)
return -EINVAL;
@@ -296,30 +294,6 @@ int mtk_ddp_comp_init(struct device *dev, struct device_node *node,
if (IS_ERR(comp->clk))
return PTR_ERR(comp->clk);
- /* Only DMA capable components need the LARB property */
- comp->larb_dev = NULL;
- if (type != MTK_DISP_OVL &&
- type != MTK_DISP_RDMA &&
- type != MTK_DISP_WDMA)
- return 0;
-
- larb_node = of_parse_phandle(node, "mediatek,larb", 0);
- if (!larb_node) {
- dev_err(dev,
- "Missing mediadek,larb phandle in %pOF node\n", node);
- return -EINVAL;
- }
-
- larb_pdev = of_find_device_by_node(larb_node);
- if (!larb_pdev) {
- dev_warn(dev, "Waiting for larb device %pOF\n", larb_node);
- of_node_put(larb_node);
- return -EPROBE_DEFER;
- }
- of_node_put(larb_node);
-
- comp->larb_dev = &larb_pdev->dev;
-
return 0;
}
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
index 8399229..b8dc17e 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
@@ -91,7 +91,6 @@ struct mtk_ddp_comp {
struct clk *clk;
void __iomem *regs;
int irq;
- struct device *larb_dev;
enum mtk_ddp_comp_id id;
const struct mtk_ddp_comp_funcs *funcs;
};
--
1.9.1
MediaTek IOMMU should wait for smi larb which need wait for the
power domain(mtk-scpsys.c) and the multimedia ccf who both are
module init. Thus, subsys_initcall for MediaTek IOMMU is not helpful.
Switch to builtin_platform_driver.
Meanwhile, the ".remove" can be removed. Move its content to
".shutdown".
Signed-off-by: Yong Wu <[email protected]>
---
drivers/iommu/mtk_iommu.c | 23 ++---------------------
drivers/iommu/mtk_iommu_v1.c | 16 ++--------------
2 files changed, 4 insertions(+), 35 deletions(-)
diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 735ae8d..2798b12 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -690,7 +690,7 @@ static int mtk_iommu_probe(struct platform_device *pdev)
return component_master_add_with_match(dev, &mtk_iommu_com_ops, match);
}
-static int mtk_iommu_remove(struct platform_device *pdev)
+static void mtk_iommu_shutdown(struct platform_device *pdev)
{
struct mtk_iommu_data *data = platform_get_drvdata(pdev);
@@ -703,12 +703,6 @@ static int mtk_iommu_remove(struct platform_device *pdev)
clk_disable_unprepare(data->bclk);
devm_free_irq(&pdev->dev, data->irq, data);
component_master_del(&pdev->dev, &mtk_iommu_com_ops);
- return 0;
-}
-
-static void mtk_iommu_shutdown(struct platform_device *pdev)
-{
- mtk_iommu_remove(pdev);
}
static int __maybe_unused mtk_iommu_suspend(struct device *dev)
@@ -791,7 +785,6 @@ static int __maybe_unused mtk_iommu_resume(struct device *dev)
static struct platform_driver mtk_iommu_driver = {
.probe = mtk_iommu_probe,
- .remove = mtk_iommu_remove,
.shutdown = mtk_iommu_shutdown,
.driver = {
.name = "mtk-iommu",
@@ -799,16 +792,4 @@ static int __maybe_unused mtk_iommu_resume(struct device *dev)
.pm = &mtk_iommu_pm_ops,
}
};
-
-static int __init mtk_iommu_init(void)
-{
- int ret;
-
- ret = platform_driver_register(&mtk_iommu_driver);
- if (ret != 0)
- pr_err("Failed to register MTK IOMMU driver\n");
-
- return ret;
-}
-
-subsys_initcall(mtk_iommu_init)
+builtin_platform_driver(mtk_iommu_driver);
diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c
index 022bad9..5464918 100644
--- a/drivers/iommu/mtk_iommu_v1.c
+++ b/drivers/iommu/mtk_iommu_v1.c
@@ -648,7 +648,7 @@ static int mtk_iommu_probe(struct platform_device *pdev)
return component_master_add_with_match(dev, &mtk_iommu_com_ops, match);
}
-static int mtk_iommu_remove(struct platform_device *pdev)
+static void mtk_iommu_shutdown(struct platform_device *pdev)
{
struct mtk_iommu_data *data = platform_get_drvdata(pdev);
@@ -661,12 +661,6 @@ static int mtk_iommu_remove(struct platform_device *pdev)
clk_disable_unprepare(data->bclk);
devm_free_irq(&pdev->dev, data->irq, data);
component_master_del(&pdev->dev, &mtk_iommu_com_ops);
- return 0;
-}
-
-static void mtk_iommu_shutdown(struct platform_device *pdev)
-{
- mtk_iommu_remove(pdev);
}
static int __maybe_unused mtk_iommu_suspend(struct device *dev)
@@ -705,7 +699,6 @@ static int __maybe_unused mtk_iommu_resume(struct device *dev)
static struct platform_driver mtk_iommu_driver = {
.probe = mtk_iommu_probe,
- .remove = mtk_iommu_remove,
.shutdown = mtk_iommu_shutdown,
.driver = {
.name = "mtk-iommu-v1",
@@ -713,9 +706,4 @@ static int __maybe_unused mtk_iommu_resume(struct device *dev)
.pm = &mtk_iommu_pm_ops,
}
};
-
-static int __init m4u_init(void)
-{
- return platform_driver_register(&mtk_iommu_driver);
-}
-subsys_initcall(m4u_init);
+builtin_platform_driver(mtk_iommu_driver);
--
1.9.1
On Tue, 1 Jan 2019 12:51:04 +0800, Yong Wu wrote:
> After adding device_link between the consumer with the smi-larbs,
> if the consumer call its owner pm_runtime_get(_sync), the
> pm_runtime_get(_sync) of smi-larb and smi-common will be called
> automatically. Thus, the consumer don't need the property.
>
> And IOMMU also know which larb this consumer connects with from
> iommu id in the "iommus=" property.
>
> Signed-off-by: Yong Wu <[email protected]>
> ---
> I guess it should go through Matthias's tree if the patch is ok,
> thus I don't separate to different patches. If it's really needed,
> please feel free to tell me.
> ---
> .../devicetree/bindings/display/mediatek/mediatek,disp.txt | 9 ---------
> .../devicetree/bindings/media/mediatek-jpeg-decoder.txt | 4 ----
> Documentation/devicetree/bindings/media/mediatek-mdp.txt | 8 --------
> Documentation/devicetree/bindings/media/mediatek-vcodec.txt | 4 ----
> 4 files changed, 25 deletions(-)
>
Reviewed-by: Rob Herring <[email protected]>
On Mon, Dec 31, 2018 at 8:52 PM Yong Wu <[email protected]> wrote:
>
> MediaTek IOMMU don't have its power-domain. all the consumer connect
> with smi-larb, then connect with smi-common.
>
> M4U
> |
> smi-common
> |
> -------------
> | | ...
> | |
> larb1 larb2
> | |
> vdec venc
>
> When the consumer works, it should enable the smi-larb's power which
> also need enable the smi-common's power firstly.
>
> Thus, First of all, use the device link connect the consumer and the
> smi-larbs. then add device link between the smi-larb and smi-common.
>
> This patch adds device_link between the consumer and the larbs.
>
> Suggested-by: Tomasz Figa <[email protected]>
> Signed-off-by: Yong Wu <[email protected]>
> ---
> drivers/iommu/mtk_iommu.c | 15 +++++++++++++--
> drivers/iommu/mtk_iommu_v1.c | 14 ++++++++++++--
> 2 files changed, 25 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
> index 202e41b..735ae8d 100644
> --- a/drivers/iommu/mtk_iommu.c
> +++ b/drivers/iommu/mtk_iommu.c
> @@ -247,6 +247,7 @@ static void mtk_iommu_config(struct mtk_iommu_data *data,
> struct mtk_smi_larb_iommu *larb_mmu;
> unsigned int larbid, portid;
> struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
> + struct device_link *link;
> int i;
>
> for (i = 0; i < fwspec->num_ids; ++i) {
> @@ -257,10 +258,20 @@ static void mtk_iommu_config(struct mtk_iommu_data *data,
> dev_dbg(dev, "%s iommu port: %d\n",
> enable ? "enable" : "disable", portid);
>
> - if (enable)
> + if (enable) {
> larb_mmu->mmu |= MTK_SMI_MMU_EN(portid);
> - else
> + /* Link the consumer with the larb device(supplier) */
> + link = device_link_add(dev, larb_mmu->dev,
> + DL_FLAG_PM_RUNTIME |
> + DL_FLAG_AUTOREMOVE_CONSUMER);
> + if (!link) {
> + dev_err(dev, "Unable to link %s\n",
> + dev_name(larb_mmu->dev));
> + return;
The return is a little odd here, given that you don't return an error
and this function doesn't do anything else. If it's non-fatal that
this link didn't get set up, then remove the return. If it is fatal,
then return an error code.
> + }
> + } else {
> larb_mmu->mmu &= ~MTK_SMI_MMU_EN(portid);
> + }
> }
> }
>
> diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c
> index 9386aee..022bad9 100644
> --- a/drivers/iommu/mtk_iommu_v1.c
> +++ b/drivers/iommu/mtk_iommu_v1.c
> @@ -201,6 +201,7 @@ static void mtk_iommu_config(struct mtk_iommu_data *data,
> struct mtk_smi_larb_iommu *larb_mmu;
> unsigned int larbid, portid;
> struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
> + struct device_link *link;
> int i;
>
> for (i = 0; i < fwspec->num_ids; ++i) {
> @@ -211,10 +212,19 @@ static void mtk_iommu_config(struct mtk_iommu_data *data,
> dev_dbg(dev, "%s iommu port: %d\n",
> enable ? "enable" : "disable", portid);
>
> - if (enable)
> + if (enable) {
> larb_mmu->mmu |= MTK_SMI_MMU_EN(portid);
> - else
> + link = device_link_add(dev, larb_mmu->dev,
> + DL_FLAG_PM_RUNTIME |
> + DL_FLAG_AUTOREMOVE_CONSUMER);
> + if (!link) {
> + dev_err(dev, "Unable to link %s\n",
> + dev_name(larb_mmu->dev));
> + return;
Same for this one.
> + }
> + } else {
> larb_mmu->mmu &= ~MTK_SMI_MMU_EN(portid);
> + }
> }
> }
>
> --
> 1.9.1
>
On Mon, Dec 31, 2018 at 8:51 PM Yong Wu <[email protected]> wrote:
>
> After adding device_link between the consumer with the smi-larbs,
> if the consumer call its owner pm_runtime_get(_sync), the
> pm_runtime_get(_sync) of smi-larb and smi-common will be called
> automatically. Thus, the consumer don't need the property.
>
> And IOMMU also know which larb this consumer connects with from
> iommu id in the "iommus=" property.
>
> Signed-off-by: Yong Wu <[email protected]>
Reviewed-by: Evan Green <[email protected]>
On Mon, Dec 31, 2018 at 8:52 PM Yong Wu <[email protected]> wrote:
>
> Normally, If the smi-larb HW need work, we should enable the smi-common
> HW power and clock firstly.
> This patch adds device-link between the smi-larb dev and the smi-common
> dev. then If pm_runtime_get_sync(smi-larb-dev), the pm_runtime_get_sync
> (smi-common-dev) will be called automatically.
>
> Since smi is built-in driver like IOMMU and never unbound,
> DL_FLAG_AUTOREMOVE_* is not needed.
>
> CC: Matthias Brugger <[email protected]>
> Suggested-by: Tomasz Figa <[email protected]>
> Signed-off-by: Yong Wu <[email protected]>
> ---
> drivers/memory/mtk-smi.c | 16 +++++++---------
> 1 file changed, 7 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c
> index 9688341..30930e4 100644
> --- a/drivers/memory/mtk-smi.c
> +++ b/drivers/memory/mtk-smi.c
> @@ -271,6 +271,7 @@ static int mtk_smi_larb_probe(struct platform_device *pdev)
> struct device *dev = &pdev->dev;
> struct device_node *smi_node;
> struct platform_device *smi_pdev;
> + struct device_link *link;
>
> larb = devm_kzalloc(dev, sizeof(*larb), GFP_KERNEL);
> if (!larb)
> @@ -310,6 +311,12 @@ static int mtk_smi_larb_probe(struct platform_device *pdev)
> if (!platform_get_drvdata(smi_pdev))
> return -EPROBE_DEFER;
> larb->smi_common_dev = &smi_pdev->dev;
> + link = device_link_add(dev, larb->smi_common_dev,
> + DL_FLAG_PM_RUNTIME);
Doesn't this need to be torn down in remove()? You mention that it's
built-in and never removed, but it does seem to have a remove()
function that tears down everything else, so it seemed a shame to
start leaking now. Maybe the AUTOREMOVE flag would do it.
On Mon, Dec 31, 2018 at 8:52 PM Yong Wu <[email protected]> wrote:
>
> The iommu consumer should use device_link to connect with the
> smi-larb(supplier). then the smi-larb should run before the iommu
> consumer. Here we delay the iommu driver until the smi driver is
> ready, then all the iommu consumer always is after the smi driver.
>
> When there is no this patch, if some consumer drivers run before
> smi-larb, the supplier link_status is DL_DEV_NO_DRIVER(0) in the
> device_link_add, then device_links_driver_bound will use WARN_ON
> to complain that the link_status of supplier is not right.
>
I don't quite have enough knowledge of device links to figure out if
this is a) the right fix, b) a deficiency in the device_links code, or
c) neither.
Perhaps someone else could chime in on this one.
-Evan
On Mon, Dec 31, 2018 at 8:52 PM Yong Wu <[email protected]> wrote:
>
> DL_FLAG_AUTOREMOVE_CONSUMER/SUPPLIER means "Remove the link
> automatically on consumer/supplier driver unbind", that means we should
> remove whole the device_link when there is no this driver no matter what
> the ref_count of the link is.
>
> CC: Greg Kroah-Hartman <[email protected]>
> Signed-off-by: Yong Wu <[email protected]>
> ---
> The ref_count of our device_link normally is over 1. When the consumer
> device driver is removed, whole the device_link should be removed.
> Thus, I add this patch.
> ---
I will admit to reading about device links for the first time while
reviewing this patch, but I don't really get this. Why use a kref at
all if we're just going to ignore its value? For instance, I see that
if you call device_link_add() with the same supplier and consumer, it
uses the kref to return the same link. That machinery is broken with
your change. Although I don't see any uses of it, you might also
expect a supplier or consumer could do a kref_get() on the link it got
back from device_link_add(), and have a reasonable expectation that
the link wouldn't be freed out from under it. This would also be
broken.
Can you explain why your device_links normally have a reference count
>1, and why those additional references can't be cleaned up in an
orderly fashion?
(To be honest, I don't really understand the case for the AUTOREMOVE
flags at all. Is there some case where the party that set up the link
can't tear it down? Or is this a way to devm_ify the link, where devm
itself doesn't work because the links themselves stall out that
mechanism?)
On Mon, Dec 31, 2018 at 8:53 PM Yong Wu <[email protected]> wrote:
>
> After adding device_link between the iommu consumer and smi-larb,
> the pm_runtime_get(_sync) of smi-larb and smi-common will be called
> automatically. we can get rid of mtk_smi_larb_get/put.
>
> CC: Matthias Brugger <[email protected]>
> Signed-off-by: Yong Wu <[email protected]>
It's possible that there's so little left in mediatek/smi.h that it
could be deleted entirely and its last remaining bits absorbed into
other locations. But maybe it's nice to keep those last little bits
used by mtk-smi.c away from the iommu definitions. So it seems fine
as-is to me.
Reviewed-by: Evan Green <[email protected]>
On Mon, Dec 31, 2018 at 8:52 PM Yong Wu <[email protected]> wrote:
>
> MediaTek IOMMU has already added the device_link between the consumer
> and smi-larb device. If the mdp device call the pm_runtime_get_sync,
> the smi-larb's pm_runtime_get_sync also be called automatically.
>
> CC: Minghsiu Tsai <[email protected]>
> Signed-off-by: Yong Wu <[email protected]>
Reviewed-by: Evan Green <[email protected]>
On Mon, Dec 31, 2018 at 8:52 PM Yong Wu <[email protected]> wrote:
>
> MediaTek IOMMU has already added device_link between the consumer
> and smi-larb device. If the jpg device call the pm_runtime_get_sync,
> the smi-larb's pm_runtime_get_sync also be called automatically.
>
> CC: Rick Chang <[email protected]>
> Signed-off-by: Yong Wu <[email protected]>
Reviewed-by: Evan Green <[email protected]>
On Mon, Dec 31, 2018 at 8:52 PM Yong Wu <[email protected]> wrote:
>
> MediaTek IOMMU has already added the device_link between the consumer
> and smi-larb device. If the vcodec device call the pm_runtime_get_sync,
> the smi-larb's pm_runtime_get_sync also be called automatically.
>
> CC: Tiffany Lin <[email protected]>
> Signed-off-by: Yong Wu <[email protected]>
Reviewed-by: Evan Green <[email protected]>
On Mon, Dec 31, 2018 at 8:53 PM Yong Wu <[email protected]> wrote:
>
> After adding device_link between the IOMMU consumer and smi,
> the mediatek,larb is unnecessary now.
>
> CC: Matthias Brugger <[email protected]>
> Signed-off-by: Yong Wu <[email protected]>
Reviewed-by: Evan Green <[email protected]>
On Mon, Dec 31, 2018 at 8:53 PM Yong Wu <[email protected]> wrote:
>
> MediaTek IOMMU should wait for smi larb which need wait for the
> power domain(mtk-scpsys.c) and the multimedia ccf who both are
> module init. Thus, subsys_initcall for MediaTek IOMMU is not helpful.
> Switch to builtin_platform_driver.
>
> Meanwhile, the ".remove" can be removed. Move its content to
> ".shutdown".
>
> Signed-off-by: Yong Wu <[email protected]>
> ---
> drivers/iommu/mtk_iommu.c | 23 ++---------------------
> drivers/iommu/mtk_iommu_v1.c | 16 ++--------------
> 2 files changed, 4 insertions(+), 35 deletions(-)
>
> diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
> index 735ae8d..2798b12 100644
> --- a/drivers/iommu/mtk_iommu.c
> +++ b/drivers/iommu/mtk_iommu.c
> @@ -690,7 +690,7 @@ static int mtk_iommu_probe(struct platform_device *pdev)
> return component_master_add_with_match(dev, &mtk_iommu_com_ops, match);
> }
>
> -static int mtk_iommu_remove(struct platform_device *pdev)
> +static void mtk_iommu_shutdown(struct platform_device *pdev)
> {
> struct mtk_iommu_data *data = platform_get_drvdata(pdev);
>
> @@ -703,12 +703,6 @@ static int mtk_iommu_remove(struct platform_device *pdev)
> clk_disable_unprepare(data->bclk);
> devm_free_irq(&pdev->dev, data->irq, data);
> component_master_del(&pdev->dev, &mtk_iommu_com_ops);
> - return 0;
> -}
> -
> -static void mtk_iommu_shutdown(struct platform_device *pdev)
> -{
> - mtk_iommu_remove(pdev);
Is there a reason all these things are happening in shutdown()? Don't
we normally just not clean things up and let the machine turn off?
Normally I'm a big advocate of proper symmetric teardown, so it hurts
a little to ask.
On Mon, Dec 31, 2018 at 8:52 PM Yong Wu <[email protected]> wrote:
>
> MediaTek IOMMU has already added the device_link between the consumer
> and smi-larb device. If the drm device call the pm_runtime_get_sync,
> the smi-larb's pm_runtime_get_sync also be called automatically.
>
> CC: CK Hu <[email protected]>
> CC: Philipp Zabel <[email protected]>
> Signed-off-by: Yong Wu <[email protected]>
Nice cleanup.
Reviewed-by: Evan Green <[email protected]>
On Mon, Dec 31, 2018 at 8:53 PM Yong Wu <[email protected]> wrote:
>
> After adding device_link between the IOMMU consumer and smi,
> the mediatek,larb is unnecessary now.
>
> CC: Matthias Brugger <[email protected]>
> Signed-off-by: Yong Wu <[email protected]>
Reviewed-by: Evan Green <[email protected]>
On Mon, 2019-02-25 at 15:54 -0800, Evan Green wrote:
> On Mon, Dec 31, 2018 at 8:52 PM Yong Wu <[email protected]> wrote:
> >
> > MediaTek IOMMU don't have its power-domain. all the consumer connect
> > with smi-larb, then connect with smi-common.
> >
> > M4U
> > |
> > smi-common
> > |
> > -------------
> > | | ...
> > | |
> > larb1 larb2
> > | |
> > vdec venc
> >
> > When the consumer works, it should enable the smi-larb's power which
> > also need enable the smi-common's power firstly.
> >
> > Thus, First of all, use the device link connect the consumer and the
> > smi-larbs. then add device link between the smi-larb and smi-common.
> >
> > This patch adds device_link between the consumer and the larbs.
> >
> > Suggested-by: Tomasz Figa <[email protected]>
> > Signed-off-by: Yong Wu <[email protected]>
> > ---
> > drivers/iommu/mtk_iommu.c | 15 +++++++++++++--
> > drivers/iommu/mtk_iommu_v1.c | 14 ++++++++++++--
> > 2 files changed, 25 insertions(+), 4 deletions(-)
> >
> > diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
> > index 202e41b..735ae8d 100644
> > --- a/drivers/iommu/mtk_iommu.c
> > +++ b/drivers/iommu/mtk_iommu.c
> > @@ -247,6 +247,7 @@ static void mtk_iommu_config(struct mtk_iommu_data *data,
> > struct mtk_smi_larb_iommu *larb_mmu;
> > unsigned int larbid, portid;
> > struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
> > + struct device_link *link;
> > int i;
> >
> > for (i = 0; i < fwspec->num_ids; ++i) {
> > @@ -257,10 +258,20 @@ static void mtk_iommu_config(struct mtk_iommu_data *data,
> > dev_dbg(dev, "%s iommu port: %d\n",
> > enable ? "enable" : "disable", portid);
> >
> > - if (enable)
> > + if (enable) {
> > larb_mmu->mmu |= MTK_SMI_MMU_EN(portid);
> > - else
> > + /* Link the consumer with the larb device(supplier) */
> > + link = device_link_add(dev, larb_mmu->dev,
> > + DL_FLAG_PM_RUNTIME |
> > + DL_FLAG_AUTOREMOVE_CONSUMER);
> > + if (!link) {
> > + dev_err(dev, "Unable to link %s\n",
> > + dev_name(larb_mmu->dev));
> > + return;
>
> The return is a little odd here, given that you don't return an error
> and this function doesn't do anything else. If it's non-fatal that
> this link didn't get set up, then remove the return. If it is fatal,
> then return an error code.
I will remove the "return". Thanks.
>
> > + }
> > + } else {
> > larb_mmu->mmu &= ~MTK_SMI_MMU_EN(portid);
> > + }
> > }
> > }
> >
> > diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c
> > index 9386aee..022bad9 100644
> > --- a/drivers/iommu/mtk_iommu_v1.c
> > +++ b/drivers/iommu/mtk_iommu_v1.c
> > @@ -201,6 +201,7 @@ static void mtk_iommu_config(struct mtk_iommu_data *data,
> > struct mtk_smi_larb_iommu *larb_mmu;
> > unsigned int larbid, portid;
> > struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
> > + struct device_link *link;
> > int i;
> >
> > for (i = 0; i < fwspec->num_ids; ++i) {
> > @@ -211,10 +212,19 @@ static void mtk_iommu_config(struct mtk_iommu_data *data,
> > dev_dbg(dev, "%s iommu port: %d\n",
> > enable ? "enable" : "disable", portid);
> >
> > - if (enable)
> > + if (enable) {
> > larb_mmu->mmu |= MTK_SMI_MMU_EN(portid);
> > - else
> > + link = device_link_add(dev, larb_mmu->dev,
> > + DL_FLAG_PM_RUNTIME |
> > + DL_FLAG_AUTOREMOVE_CONSUMER);
> > + if (!link) {
> > + dev_err(dev, "Unable to link %s\n",
> > + dev_name(larb_mmu->dev));
> > + return;
>
> Same for this one.
>
> > + }
> > + } else {
> > larb_mmu->mmu &= ~MTK_SMI_MMU_EN(portid);
> > + }
> > }
> > }
> >
> > --
> > 1.9.1
> >
>
> _______________________________________________
> Linux-mediatek mailing list
> [email protected]
> http://lists.infradead.org/mailman/listinfo/linux-mediatek
On Mon, 2019-02-25 at 15:54 -0800, Evan Green wrote:
> On Mon, Dec 31, 2018 at 8:52 PM Yong Wu <[email protected]> wrote:
> >
> > Normally, If the smi-larb HW need work, we should enable the smi-common
> > HW power and clock firstly.
> > This patch adds device-link between the smi-larb dev and the smi-common
> > dev. then If pm_runtime_get_sync(smi-larb-dev), the pm_runtime_get_sync
> > (smi-common-dev) will be called automatically.
> >
> > Since smi is built-in driver like IOMMU and never unbound,
> > DL_FLAG_AUTOREMOVE_* is not needed.
> >
> > CC: Matthias Brugger <[email protected]>
> > Suggested-by: Tomasz Figa <[email protected]>
> > Signed-off-by: Yong Wu <[email protected]>
> > ---
> > drivers/memory/mtk-smi.c | 16 +++++++---------
> > 1 file changed, 7 insertions(+), 9 deletions(-)
> >
> > diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c
> > index 9688341..30930e4 100644
> > --- a/drivers/memory/mtk-smi.c
> > +++ b/drivers/memory/mtk-smi.c
> > @@ -271,6 +271,7 @@ static int mtk_smi_larb_probe(struct platform_device *pdev)
> > struct device *dev = &pdev->dev;
> > struct device_node *smi_node;
> > struct platform_device *smi_pdev;
> > + struct device_link *link;
> >
> > larb = devm_kzalloc(dev, sizeof(*larb), GFP_KERNEL);
> > if (!larb)
> > @@ -310,6 +311,12 @@ static int mtk_smi_larb_probe(struct platform_device *pdev)
> > if (!platform_get_drvdata(smi_pdev))
> > return -EPROBE_DEFER;
> > larb->smi_common_dev = &smi_pdev->dev;
> > + link = device_link_add(dev, larb->smi_common_dev,
> > + DL_FLAG_PM_RUNTIME);
>
> Doesn't this need to be torn down in remove()? You mention that it's
> built-in and never removed, but it does seem to have a remove()
The MTK IOMMU driver need depend on this SMI driver. the IOMMU is a
builtin driver, thus the SMI also should be a builtin driver.
Technically, If the driver is builtin, then the "remove" function can be
removed? If yes, I could use a new patch do it.
It looks the MACRO(builtin_platform_driver) only support one driver, but
we have two driver(smi-common and smi-larb) here.
> function that tears down everything else, so it seemed a shame to
> start leaking now. Maybe the AUTOREMOVE flag would do it.
On Mon, 2019-02-25 at 15:54 -0800, Evan Green wrote:
> On Mon, Dec 31, 2018 at 8:52 PM Yong Wu <[email protected]> wrote:
> >
> > The iommu consumer should use device_link to connect with the
> > smi-larb(supplier). then the smi-larb should run before the iommu
> > consumer. Here we delay the iommu driver until the smi driver is
> > ready, then all the iommu consumer always is after the smi driver.
> >
> > When there is no this patch, if some consumer drivers run before
> > smi-larb, the supplier link_status is DL_DEV_NO_DRIVER(0) in the
> > device_link_add, then device_links_driver_bound will use WARN_ON
> > to complain that the link_status of supplier is not right.
> >
>
> I don't quite have enough knowledge of device links to figure out if
> this is a) the right fix, b) a deficiency in the device_links code, or
> c) neither.
I can not say more about the device link, But from the MTK iommu point
of view, it looks a right fix. As the comment above, we should make sure
the probe sequence, SMI-larb should be before MTK IOMMU which need be
before iommu-consumer. this patch help SMI-larb always is before
MTK_IOMMU.
Then if there is no this patchset, what the MTK_IOMMU will happen?.
The MTK_IOMMU is subsys_initcall, all the consume only need after the
MTK_IOMMU and don't need wait for SMI-larb driver. If some consume run
before SMI-larb driver, It also is OK while it don't call
mtk_smi_larb_get in this probe.(Of course it will abort if it call this
while smi-driver don't probe at that time). the consumer and smi-larb
normally are module_init, we can not guarantee the the sequence. it is a
potential issue.
Some consume know it should wait for SMI-larb like [1], but It don't
work.
[1]
https://elixir.bootlin.com/linux/v5.0-rc1/source/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c#L145
>
> Perhaps someone else could chime in on this one.
> -Evan
>
> _______________________________________________
> Linux-mediatek mailing list
> [email protected]
> http://lists.infradead.org/mailman/listinfo/linux-mediatek
On Mon, 2019-02-25 at 15:53 -0800, Evan Green wrote:
> On Mon, Dec 31, 2018 at 8:52 PM Yong Wu <[email protected]> wrote:
> >
> > DL_FLAG_AUTOREMOVE_CONSUMER/SUPPLIER means "Remove the link
> > automatically on consumer/supplier driver unbind", that means we should
> > remove whole the device_link when there is no this driver no matter what
> > the ref_count of the link is.
> >
> > CC: Greg Kroah-Hartman <[email protected]>
> > Signed-off-by: Yong Wu <[email protected]>
> > ---
> > The ref_count of our device_link normally is over 1. When the consumer
> > device driver is removed, whole the device_link should be removed.
> > Thus, I add this patch.
> > ---
>
> I will admit to reading about device links for the first time while
> reviewing this patch, but I don't really get this. Why use a kref at
> all if we're just going to ignore its value? For instance, I see that
> if you call device_link_add() with the same supplier and consumer, it
> uses the kref to return the same link. That machinery is broken with
> your change. Although I don't see any uses of it, you might also
> expect a supplier or consumer could do a kref_get() on the link it got
> back from device_link_add(), and have a reasonable expectation that
> the link wouldn't be freed out from under it. This would also be
> broken.
>
> Can you explain why your device_links normally have a reference count
> >1,
I use device link between the smi-larb device and the iommu-consumer
device. Take a example, smi-larb1 have 4 VDEC ports. From 4/13 in this
patchset, we use device_link to link the VDEC device and the smi-larb1
device in the function(mtk_iommu_config). since there are 4 ports, it
will call device_link_add 4 times.
>
> and why those additional references can't be cleaned up in an
> orderly fashion?
If the iommu-consume device(like VDEC above) is removed, It should enter
device_links_driver_cleanup which only ref_put one time. I guess whole
the link should be removed at that time.
>
> (To be honest, I don't really understand the case for the AUTOREMOVE
> flags at all. Is there some case where the party that set up the link
> can't tear it down? Or is this a way to devm_ify the link, where devm
> itself doesn't work because the links themselves stall out that
> mechanism?)
On Mon, 2019-02-25 at 15:56 -0800, Evan Green wrote:
> On Mon, Dec 31, 2018 at 8:53 PM Yong Wu <[email protected]> wrote:
> >
> > MediaTek IOMMU should wait for smi larb which need wait for the
> > power domain(mtk-scpsys.c) and the multimedia ccf who both are
> > module init. Thus, subsys_initcall for MediaTek IOMMU is not helpful.
> > Switch to builtin_platform_driver.
> >
> > Meanwhile, the ".remove" can be removed. Move its content to
> > ".shutdown".
> >
> > Signed-off-by: Yong Wu <[email protected]>
> > ---
> > drivers/iommu/mtk_iommu.c | 23 ++---------------------
> > drivers/iommu/mtk_iommu_v1.c | 16 ++--------------
> > 2 files changed, 4 insertions(+), 35 deletions(-)
> >
> > diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
> > index 735ae8d..2798b12 100644
> > --- a/drivers/iommu/mtk_iommu.c
> > +++ b/drivers/iommu/mtk_iommu.c
> > @@ -690,7 +690,7 @@ static int mtk_iommu_probe(struct platform_device *pdev)
> > return component_master_add_with_match(dev, &mtk_iommu_com_ops, match);
> > }
> >
> > -static int mtk_iommu_remove(struct platform_device *pdev)
> > +static void mtk_iommu_shutdown(struct platform_device *pdev)
> > {
> > struct mtk_iommu_data *data = platform_get_drvdata(pdev);
> >
> > @@ -703,12 +703,6 @@ static int mtk_iommu_remove(struct platform_device *pdev)
> > clk_disable_unprepare(data->bclk);
> > devm_free_irq(&pdev->dev, data->irq, data);
> > component_master_del(&pdev->dev, &mtk_iommu_com_ops);
> > - return 0;
> > -}
> > -
> > -static void mtk_iommu_shutdown(struct platform_device *pdev)
> > -{
> > - mtk_iommu_remove(pdev);
>
> Is there a reason all these things are happening in shutdown()? Don't
> we normally just not clean things up and let the machine turn off?
> Normally I'm a big advocate of proper symmetric teardown, so it hurts
> a little to ask.
In this patch I change the driver to builtin driver. I guess the
"_remove" is not helpful now. thus I remove it.
About the shutdown, I don't have a special reason for it. I only want to
mute the m4u log when something go wrong in the shutdown flow.
>
> _______________________________________________
> Linux-mediatek mailing list
> [email protected]
> http://lists.infradead.org/mailman/listinfo/linux-mediatek
On 01/01/2019 04:51, Yong Wu wrote:
> MediaTek IOMMU don't have its power-domain. all the consumer connect
> with smi-larb, then connect with smi-common.
>
> M4U
> |
> smi-common
> |
> -------------
> | | ...
> | |
> larb1 larb2
> | |
> vdec venc
>
> When the consumer works, it should enable the smi-larb's power which
> also need enable the smi-common's power firstly.
>
> Thus, First of all, use the device link connect the consumer and the
> smi-larbs. then add device link between the smi-larb and smi-common.
>
> This patch adds device_link between the consumer and the larbs.
>
> Suggested-by: Tomasz Figa <[email protected]>
> Signed-off-by: Yong Wu <[email protected]>
> ---
> drivers/iommu/mtk_iommu.c | 15 +++++++++++++--
> drivers/iommu/mtk_iommu_v1.c | 14 ++++++++++++--
> 2 files changed, 25 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
> index 202e41b..735ae8d 100644
> --- a/drivers/iommu/mtk_iommu.c
> +++ b/drivers/iommu/mtk_iommu.c
> @@ -247,6 +247,7 @@ static void mtk_iommu_config(struct mtk_iommu_data *data,
> struct mtk_smi_larb_iommu *larb_mmu;
> unsigned int larbid, portid;
> struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
> + struct device_link *link;
> int i;
>
> for (i = 0; i < fwspec->num_ids; ++i) {
> @@ -257,10 +258,20 @@ static void mtk_iommu_config(struct mtk_iommu_data *data,
> dev_dbg(dev, "%s iommu port: %d\n",
> enable ? "enable" : "disable", portid);
>
> - if (enable)
> + if (enable) {
> larb_mmu->mmu |= MTK_SMI_MMU_EN(portid);
> - else
> + /* Link the consumer with the larb device(supplier) */
> + link = device_link_add(dev, larb_mmu->dev,
> + DL_FLAG_PM_RUNTIME |
> + DL_FLAG_AUTOREMOVE_CONSUMER);
This looks technically wrong, since we get here from
mtk_iommu_attach_device(), and in theory a device could get attached to
any number of domains over its lifetime, so adding a link at this point
when there's no corresponding cleanup on detach is definitely
unbalanced. If you want this layer to manage the link on behalf of the
consumer, it would probably be better to do it at the point of
mtk_iommu_add_device(), and either track it for manual cleanup in
mtk_iommu_remove_device() or rely on AUTOREMOVE_SUPPLIER.
Robin.
> + if (!link) {
> + dev_err(dev, "Unable to link %s\n",
> + dev_name(larb_mmu->dev));
> + return;
> + }
> + } else {
> larb_mmu->mmu &= ~MTK_SMI_MMU_EN(portid);
> + }
> }
> }
>
> diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c
> index 9386aee..022bad9 100644
> --- a/drivers/iommu/mtk_iommu_v1.c
> +++ b/drivers/iommu/mtk_iommu_v1.c
> @@ -201,6 +201,7 @@ static void mtk_iommu_config(struct mtk_iommu_data *data,
> struct mtk_smi_larb_iommu *larb_mmu;
> unsigned int larbid, portid;
> struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
> + struct device_link *link;
> int i;
>
> for (i = 0; i < fwspec->num_ids; ++i) {
> @@ -211,10 +212,19 @@ static void mtk_iommu_config(struct mtk_iommu_data *data,
> dev_dbg(dev, "%s iommu port: %d\n",
> enable ? "enable" : "disable", portid);
>
> - if (enable)
> + if (enable) {
> larb_mmu->mmu |= MTK_SMI_MMU_EN(portid);
> - else
> + link = device_link_add(dev, larb_mmu->dev,
> + DL_FLAG_PM_RUNTIME |
> + DL_FLAG_AUTOREMOVE_CONSUMER);
> + if (!link) {
> + dev_err(dev, "Unable to link %s\n",
> + dev_name(larb_mmu->dev));
> + return;
> + }
> + } else {
> larb_mmu->mmu &= ~MTK_SMI_MMU_EN(portid);
> + }
> }
> }
>
>
On Wed, Feb 27, 2019 at 6:34 AM Yong Wu <[email protected]> wrote:
>
> On Mon, 2019-02-25 at 15:54 -0800, Evan Green wrote:
> > On Mon, Dec 31, 2018 at 8:52 PM Yong Wu <[email protected]> wrote:
> > >
> > > The iommu consumer should use device_link to connect with the
> > > smi-larb(supplier). then the smi-larb should run before the iommu
> > > consumer. Here we delay the iommu driver until the smi driver is
> > > ready, then all the iommu consumer always is after the smi driver.
> > >
> > > When there is no this patch, if some consumer drivers run before
> > > smi-larb, the supplier link_status is DL_DEV_NO_DRIVER(0) in the
> > > device_link_add, then device_links_driver_bound will use WARN_ON
> > > to complain that the link_status of supplier is not right.
> > >
> >
> > I don't quite have enough knowledge of device links to figure out if
> > this is a) the right fix, b) a deficiency in the device_links code, or
> > c) neither.
>
> I can not say more about the device link, But from the MTK iommu point
> of view, it looks a right fix. As the comment above, we should make sure
> the probe sequence, SMI-larb should be before MTK IOMMU which need be
> before iommu-consumer. this patch help SMI-larb always is before
> MTK_IOMMU.
>
> Then if there is no this patchset, what the MTK_IOMMU will happen?.
>
> The MTK_IOMMU is subsys_initcall, all the consume only need after the
> MTK_IOMMU and don't need wait for SMI-larb driver. If some consume run
> before SMI-larb driver, It also is OK while it don't call
> mtk_smi_larb_get in this probe.(Of course it will abort if it call this
> while smi-driver don't probe at that time). the consumer and smi-larb
> normally are module_init, we can not guarantee the the sequence. it is a
> potential issue.
>
> Some consume know it should wait for SMI-larb like [1], but It don't
> work.
>
> [1]
> https://elixir.bootlin.com/linux/v5.0-rc1/source/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c#L145
Ok, I think I get it now. The device_links that get created are
enforcing a probe order dependency, but in cases where this driver
probes before those device links are even created, then this extra
check defers so that the probe order stays correct. Then the
device_links were correct to WARN because they're basically saying,
"hey, you asked us to enforce a particular dependency, but I can
already see probe is happening in an order that violates that
dependency".
Is that right?
-Evan
On Wed, Feb 27, 2019 at 6:33 AM Yong Wu <[email protected]> wrote:
>
> On Mon, 2019-02-25 at 15:53 -0800, Evan Green wrote:
> > On Mon, Dec 31, 2018 at 8:52 PM Yong Wu <[email protected]> wrote:
> > >
> > > DL_FLAG_AUTOREMOVE_CONSUMER/SUPPLIER means "Remove the link
> > > automatically on consumer/supplier driver unbind", that means we should
> > > remove whole the device_link when there is no this driver no matter what
> > > the ref_count of the link is.
> > >
> > > CC: Greg Kroah-Hartman <[email protected]>
> > > Signed-off-by: Yong Wu <[email protected]>
> > > ---
> > > The ref_count of our device_link normally is over 1. When the consumer
> > > device driver is removed, whole the device_link should be removed.
> > > Thus, I add this patch.
> > > ---
> >
> > I will admit to reading about device links for the first time while
> > reviewing this patch, but I don't really get this. Why use a kref at
> > all if we're just going to ignore its value? For instance, I see that
> > if you call device_link_add() with the same supplier and consumer, it
> > uses the kref to return the same link. That machinery is broken with
> > your change. Although I don't see any uses of it, you might also
> > expect a supplier or consumer could do a kref_get() on the link it got
> > back from device_link_add(), and have a reasonable expectation that
> > the link wouldn't be freed out from under it. This would also be
> > broken.
> >
> > Can you explain why your device_links normally have a reference count
> > >1,
>
> I use device link between the smi-larb device and the iommu-consumer
> device. Take a example, smi-larb1 have 4 VDEC ports. From 4/13 in this
> patchset, we use device_link to link the VDEC device and the smi-larb1
> device in the function(mtk_iommu_config). since there are 4 ports, it
> will call device_link_add 4 times.
>
> >
> > and why those additional references can't be cleaned up in an
> > orderly fashion?
>
> If the iommu-consume device(like VDEC above) is removed, It should enter
> device_links_driver_cleanup which only ref_put one time. I guess whole
> the link should be removed at that time.
It seems like Robin had some suggestions about using
mtk_iommu_add_device() rather than the attach_dev() to set the links
up, and then track them for removal in the corresponding
remove_device() callback. Then you wouldn't need this change, right?
On Wed, Feb 27, 2019 at 6:33 AM Yong Wu <[email protected]> wrote:
>
> On Mon, 2019-02-25 at 15:56 -0800, Evan Green wrote:
> > On Mon, Dec 31, 2018 at 8:53 PM Yong Wu <[email protected]> wrote:
> > >
> > > MediaTek IOMMU should wait for smi larb which need wait for the
> > > power domain(mtk-scpsys.c) and the multimedia ccf who both are
> > > module init. Thus, subsys_initcall for MediaTek IOMMU is not helpful.
> > > Switch to builtin_platform_driver.
> > >
> > > Meanwhile, the ".remove" can be removed. Move its content to
> > > ".shutdown".
> > >
> > > Signed-off-by: Yong Wu <[email protected]>
> > > ---
> > > drivers/iommu/mtk_iommu.c | 23 ++---------------------
> > > drivers/iommu/mtk_iommu_v1.c | 16 ++--------------
> > > 2 files changed, 4 insertions(+), 35 deletions(-)
> > >
> > > diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
> > > index 735ae8d..2798b12 100644
> > > --- a/drivers/iommu/mtk_iommu.c
> > > +++ b/drivers/iommu/mtk_iommu.c
> > > @@ -690,7 +690,7 @@ static int mtk_iommu_probe(struct platform_device *pdev)
> > > return component_master_add_with_match(dev, &mtk_iommu_com_ops, match);
> > > }
> > >
> > > -static int mtk_iommu_remove(struct platform_device *pdev)
> > > +static void mtk_iommu_shutdown(struct platform_device *pdev)
> > > {
> > > struct mtk_iommu_data *data = platform_get_drvdata(pdev);
> > >
> > > @@ -703,12 +703,6 @@ static int mtk_iommu_remove(struct platform_device *pdev)
> > > clk_disable_unprepare(data->bclk);
> > > devm_free_irq(&pdev->dev, data->irq, data);
> > > component_master_del(&pdev->dev, &mtk_iommu_com_ops);
> > > - return 0;
> > > -}
> > > -
> > > -static void mtk_iommu_shutdown(struct platform_device *pdev)
> > > -{
> > > - mtk_iommu_remove(pdev);
> >
> > Is there a reason all these things are happening in shutdown()? Don't
> > we normally just not clean things up and let the machine turn off?
> > Normally I'm a big advocate of proper symmetric teardown, so it hurts
> > a little to ask.
>
> In this patch I change the driver to builtin driver. I guess the
> "_remove" is not helpful now. thus I remove it.
>
> About the shutdown, I don't have a special reason for it. I only want to
> mute the m4u log when something go wrong in the shutdown flow.
>
Wouldn't you want to see the logs when something goes wrong in
shutdown? Or is there a lot of noise that gets generated if you don't
do this during a graceful shutdown? I guess if there's some real
reason you're doing all this stuff in shutdown then it's fine, but if
it was just a default shuttling of code from remove to shutdown
because remove was going away then it could be deleted.
-Evan
On Wed, Feb 27, 2019 at 6:33 AM Yong Wu <[email protected]> wrote:
>
> On Mon, 2019-02-25 at 15:54 -0800, Evan Green wrote:
> > On Mon, Dec 31, 2018 at 8:52 PM Yong Wu <[email protected]> wrote:
> > >
> > > Normally, If the smi-larb HW need work, we should enable the smi-common
> > > HW power and clock firstly.
> > > This patch adds device-link between the smi-larb dev and the smi-common
> > > dev. then If pm_runtime_get_sync(smi-larb-dev), the pm_runtime_get_sync
> > > (smi-common-dev) will be called automatically.
> > >
> > > Since smi is built-in driver like IOMMU and never unbound,
> > > DL_FLAG_AUTOREMOVE_* is not needed.
> > >
> > > CC: Matthias Brugger <[email protected]>
> > > Suggested-by: Tomasz Figa <[email protected]>
> > > Signed-off-by: Yong Wu <[email protected]>
> > > ---
> > > drivers/memory/mtk-smi.c | 16 +++++++---------
> > > 1 file changed, 7 insertions(+), 9 deletions(-)
> > >
> > > diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c
> > > index 9688341..30930e4 100644
> > > --- a/drivers/memory/mtk-smi.c
> > > +++ b/drivers/memory/mtk-smi.c
> > > @@ -271,6 +271,7 @@ static int mtk_smi_larb_probe(struct platform_device *pdev)
> > > struct device *dev = &pdev->dev;
> > > struct device_node *smi_node;
> > > struct platform_device *smi_pdev;
> > > + struct device_link *link;
> > >
> > > larb = devm_kzalloc(dev, sizeof(*larb), GFP_KERNEL);
> > > if (!larb)
> > > @@ -310,6 +311,12 @@ static int mtk_smi_larb_probe(struct platform_device *pdev)
> > > if (!platform_get_drvdata(smi_pdev))
> > > return -EPROBE_DEFER;
> > > larb->smi_common_dev = &smi_pdev->dev;
> > > + link = device_link_add(dev, larb->smi_common_dev,
> > > + DL_FLAG_PM_RUNTIME);
> >
> > Doesn't this need to be torn down in remove()? You mention that it's
> > built-in and never removed, but it does seem to have a remove()
>
> The MTK IOMMU driver need depend on this SMI driver. the IOMMU is a
> builtin driver, thus the SMI also should be a builtin driver.
>
> Technically, If the driver is builtin, then the "remove" function can be
> removed? If yes, I could use a new patch do it.
Yeah, I guess so. It's always sad to see cleanup code getting removed,
but it makes sense to me.
>
> It looks the MACRO(builtin_platform_driver) only support one driver, but
> we have two driver(smi-common and smi-larb) here.
>
> > function that tears down everything else, so it seemed a shame to
> > start leaking now. Maybe the AUTOREMOVE flag would do it.
>
>
On 05/03/2019 20:03, Evan Green wrote:
> On Wed, Feb 27, 2019 at 6:33 AM Yong Wu <[email protected]> wrote:
>>
>> On Mon, 2019-02-25 at 15:53 -0800, Evan Green wrote:
>>> On Mon, Dec 31, 2018 at 8:52 PM Yong Wu <[email protected]> wrote:
>>>>
>>>> DL_FLAG_AUTOREMOVE_CONSUMER/SUPPLIER means "Remove the link
>>>> automatically on consumer/supplier driver unbind", that means we should
>>>> remove whole the device_link when there is no this driver no matter what
>>>> the ref_count of the link is.
>>>>
>>>> CC: Greg Kroah-Hartman <[email protected]>
>>>> Signed-off-by: Yong Wu <[email protected]>
>>>> ---
>>>> The ref_count of our device_link normally is over 1. When the consumer
>>>> device driver is removed, whole the device_link should be removed.
>>>> Thus, I add this patch.
>>>> ---
>>>
>>> I will admit to reading about device links for the first time while
>>> reviewing this patch, but I don't really get this. Why use a kref at
>>> all if we're just going to ignore its value? For instance, I see that
>>> if you call device_link_add() with the same supplier and consumer, it
>>> uses the kref to return the same link. That machinery is broken with
>>> your change. Although I don't see any uses of it, you might also
>>> expect a supplier or consumer could do a kref_get() on the link it got
>>> back from device_link_add(), and have a reasonable expectation that
>>> the link wouldn't be freed out from under it. This would also be
>>> broken.
>>>
>>> Can you explain why your device_links normally have a reference count
>>>> 1,
>>
>> I use device link between the smi-larb device and the iommu-consumer
>> device. Take a example, smi-larb1 have 4 VDEC ports. From 4/13 in this
>> patchset, we use device_link to link the VDEC device and the smi-larb1
>> device in the function(mtk_iommu_config). since there are 4 ports, it
>> will call device_link_add 4 times.
>>
>>>
>>> and why those additional references can't be cleaned up in an
>>> orderly fashion?
>>
>> If the iommu-consume device(like VDEC above) is removed, It should enter
>> device_links_driver_cleanup which only ref_put one time. I guess whole
>> the link should be removed at that time.
>
> It seems like Robin had some suggestions about using
> mtk_iommu_add_device() rather than the attach_dev() to set the links
> up, and then track them for removal in the corresponding
> remove_device() callback. Then you wouldn't need this change, right?
>
FYI, Evan the patch is queued for v5.1-rc1 as
0fe6f7874d46 ("driver core: Remove the link if there is no driver with AUTO flag")
So if you think there is something wrong with it, then please provide a fix or
raise awareness :)
On Tue, Mar 12, 2019 at 7:21 AM Matthias Brugger <[email protected]> wrote:
>
>
>
> On 05/03/2019 20:03, Evan Green wrote:
> > On Wed, Feb 27, 2019 at 6:33 AM Yong Wu <[email protected]> wrote:
> >>
> >> On Mon, 2019-02-25 at 15:53 -0800, Evan Green wrote:
> >>> On Mon, Dec 31, 2018 at 8:52 PM Yong Wu <[email protected]> wrote:
> >>>>
> >>>> DL_FLAG_AUTOREMOVE_CONSUMER/SUPPLIER means "Remove the link
> >>>> automatically on consumer/supplier driver unbind", that means we should
> >>>> remove whole the device_link when there is no this driver no matter what
> >>>> the ref_count of the link is.
> >>>>
> >>>> CC: Greg Kroah-Hartman <[email protected]>
> >>>> Signed-off-by: Yong Wu <[email protected]>
> >>>> ---
> >>>> The ref_count of our device_link normally is over 1. When the consumer
> >>>> device driver is removed, whole the device_link should be removed.
> >>>> Thus, I add this patch.
> >>>> ---
> >>>
> >>> I will admit to reading about device links for the first time while
> >>> reviewing this patch, but I don't really get this. Why use a kref at
> >>> all if we're just going to ignore its value? For instance, I see that
> >>> if you call device_link_add() with the same supplier and consumer, it
> >>> uses the kref to return the same link. That machinery is broken with
> >>> your change. Although I don't see any uses of it, you might also
> >>> expect a supplier or consumer could do a kref_get() on the link it got
> >>> back from device_link_add(), and have a reasonable expectation that
> >>> the link wouldn't be freed out from under it. This would also be
> >>> broken.
> >>>
> >>> Can you explain why your device_links normally have a reference count
> >>>> 1,
> >>
> >> I use device link between the smi-larb device and the iommu-consumer
> >> device. Take a example, smi-larb1 have 4 VDEC ports. From 4/13 in this
> >> patchset, we use device_link to link the VDEC device and the smi-larb1
> >> device in the function(mtk_iommu_config). since there are 4 ports, it
> >> will call device_link_add 4 times.
> >>
> >>>
> >>> and why those additional references can't be cleaned up in an
> >>> orderly fashion?
> >>
> >> If the iommu-consume device(like VDEC above) is removed, It should enter
> >> device_links_driver_cleanup which only ref_put one time. I guess whole
> >> the link should be removed at that time.
> >
> > It seems like Robin had some suggestions about using
> > mtk_iommu_add_device() rather than the attach_dev() to set the links
> > up, and then track them for removal in the corresponding
> > remove_device() callback. Then you wouldn't need this change, right?
> >
>
> FYI, Evan the patch is queued for v5.1-rc1 as
> 0fe6f7874d46 ("driver core: Remove the link if there is no driver with AUTO flag")
>
> So if you think there is something wrong with it, then please provide a fix or
> raise awareness :)
Oh. Thanks for the heads-up Matthias. It's pretty weird that we have
the kref there whose count we just completely ignore. I'll try to find
some time to submit a patch.
-Evan
On Tue, 2019-03-12 at 16:17 -0700, Evan Green wrote:
> On Tue, Mar 12, 2019 at 7:21 AM Matthias Brugger <[email protected]> wrote:
> >
> >
> >
> > On 05/03/2019 20:03, Evan Green wrote:
> > > On Wed, Feb 27, 2019 at 6:33 AM Yong Wu <[email protected]> wrote:
> > >>
> > >> On Mon, 2019-02-25 at 15:53 -0800, Evan Green wrote:
> > >>> On Mon, Dec 31, 2018 at 8:52 PM Yong Wu <[email protected]> wrote:
> > >>>>
> > >>>> DL_FLAG_AUTOREMOVE_CONSUMER/SUPPLIER means "Remove the link
> > >>>> automatically on consumer/supplier driver unbind", that means we should
> > >>>> remove whole the device_link when there is no this driver no matter what
> > >>>> the ref_count of the link is.
> > >>>>
> > >>>> CC: Greg Kroah-Hartman <[email protected]>
> > >>>> Signed-off-by: Yong Wu <[email protected]>
> > >>>> ---
> > >>>> The ref_count of our device_link normally is over 1. When the consumer
> > >>>> device driver is removed, whole the device_link should be removed.
> > >>>> Thus, I add this patch.
> > >>>> ---
> > >>>
> > >>> I will admit to reading about device links for the first time while
> > >>> reviewing this patch, but I don't really get this. Why use a kref at
> > >>> all if we're just going to ignore its value? For instance, I see that
> > >>> if you call device_link_add() with the same supplier and consumer, it
> > >>> uses the kref to return the same link. That machinery is broken with
> > >>> your change. Although I don't see any uses of it, you might also
> > >>> expect a supplier or consumer could do a kref_get() on the link it got
> > >>> back from device_link_add(), and have a reasonable expectation that
> > >>> the link wouldn't be freed out from under it. This would also be
> > >>> broken.
> > >>>
> > >>> Can you explain why your device_links normally have a reference count
> > >>>> 1,
> > >>
> > >> I use device link between the smi-larb device and the iommu-consumer
> > >> device. Take a example, smi-larb1 have 4 VDEC ports. From 4/13 in this
> > >> patchset, we use device_link to link the VDEC device and the smi-larb1
> > >> device in the function(mtk_iommu_config). since there are 4 ports, it
> > >> will call device_link_add 4 times.
> > >>
> > >>>
> > >>> and why those additional references can't be cleaned up in an
> > >>> orderly fashion?
> > >>
> > >> If the iommu-consume device(like VDEC above) is removed, It should enter
> > >> device_links_driver_cleanup which only ref_put one time. I guess whole
> > >> the link should be removed at that time.
> > >
> > > It seems like Robin had some suggestions about using
> > > mtk_iommu_add_device() rather than the attach_dev() to set the links
> > > up, and then track them for removal in the corresponding
> > > remove_device() callback. Then you wouldn't need this change, right?
Hi Evan, sorry for reply you so late. I have not got time to try
this(Put it in the add_device), But I guess it works.
At that time the ref_cnt here should be 1, then this patch is
unnecessary.
> > >
> >
> > FYI, Evan the patch is queued for v5.1-rc1 as
> > 0fe6f7874d46 ("driver core: Remove the link if there is no driver with AUTO flag")
> >
> > So if you think there is something wrong with it, then please provide a fix or
> > raise awareness :)
>
> Oh. Thanks for the heads-up Matthias. It's pretty weird that we have
> the kref there whose count we just completely ignore. I'll try to find
> some time to submit a patch.
Thanks very much if you improve this.
> -Evan
Hi Robin,
sorry for reply so late.
On Wed, 2019-02-27 at 19:30 +0000, Robin Murphy wrote:
> On 01/01/2019 04:51, Yong Wu wrote:
> > MediaTek IOMMU don't have its power-domain. all the consumer connect
> > with smi-larb, then connect with smi-common.
> >
> > M4U
> > |
> > smi-common
> > |
> > -------------
> > | | ...
> > | |
> > larb1 larb2
> > | |
> > vdec venc
> >
> > When the consumer works, it should enable the smi-larb's power which
> > also need enable the smi-common's power firstly.
> >
> > Thus, First of all, use the device link connect the consumer and the
> > smi-larbs. then add device link between the smi-larb and smi-common.
> >
> > This patch adds device_link between the consumer and the larbs.
> >
> > Suggested-by: Tomasz Figa <[email protected]>
> > Signed-off-by: Yong Wu <[email protected]>
> > ---
> > drivers/iommu/mtk_iommu.c | 15 +++++++++++++--
> > drivers/iommu/mtk_iommu_v1.c | 14 ++++++++++++--
> > 2 files changed, 25 insertions(+), 4 deletions(-)
> >
> > diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
> > index 202e41b..735ae8d 100644
> > --- a/drivers/iommu/mtk_iommu.c
> > +++ b/drivers/iommu/mtk_iommu.c
> > @@ -247,6 +247,7 @@ static void mtk_iommu_config(struct mtk_iommu_data *data,
> > struct mtk_smi_larb_iommu *larb_mmu;
> > unsigned int larbid, portid;
> > struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
> > + struct device_link *link;
> > int i;
> >
> > for (i = 0; i < fwspec->num_ids; ++i) {
> > @@ -257,10 +258,20 @@ static void mtk_iommu_config(struct mtk_iommu_data *data,
> > dev_dbg(dev, "%s iommu port: %d\n",
> > enable ? "enable" : "disable", portid);
> >
> > - if (enable)
> > + if (enable) {
> > larb_mmu->mmu |= MTK_SMI_MMU_EN(portid);
> > - else
> > + /* Link the consumer with the larb device(supplier) */
> > + link = device_link_add(dev, larb_mmu->dev,
> > + DL_FLAG_PM_RUNTIME |
> > + DL_FLAG_AUTOREMOVE_CONSUMER);
>
> This looks technically wrong, since we get here from
> mtk_iommu_attach_device(), and in theory a device could get attached to
> any number of domains over its lifetime, so adding a link at this point
> when there's no corresponding cleanup on detach is definitely
> unbalanced. If you want this layer to manage the link on behalf of the
> consumer, it would probably be better to do it at the point of
> mtk_iommu_add_device(), and either track it for manual cleanup in
> mtk_iommu_remove_device() or rely on AUTOREMOVE_SUPPLIER.
Thanks. I will try to move the "device_link_add" in add_device in next
version.
>
> Robin.
>
> > + if (!link) {
> > + dev_err(dev, "Unable to link %s\n",
> > + dev_name(larb_mmu->dev));
> > + return;
> > + }
> > + } else {
> > larb_mmu->mmu &= ~MTK_SMI_MMU_EN(portid);
> > + }
> > }
> > }
> >
> > diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c
> > index 9386aee..022bad9 100644
> > --- a/drivers/iommu/mtk_iommu_v1.c
> > +++ b/drivers/iommu/mtk_iommu_v1.c
> > @@ -201,6 +201,7 @@ static void mtk_iommu_config(struct mtk_iommu_data *data,
> > struct mtk_smi_larb_iommu *larb_mmu;
> > unsigned int larbid, portid;
> > struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
> > + struct device_link *link;
> > int i;
> >
> > for (i = 0; i < fwspec->num_ids; ++i) {
> > @@ -211,10 +212,19 @@ static void mtk_iommu_config(struct mtk_iommu_data *data,
> > dev_dbg(dev, "%s iommu port: %d\n",
> > enable ? "enable" : "disable", portid);
> >
> > - if (enable)
> > + if (enable) {
> > larb_mmu->mmu |= MTK_SMI_MMU_EN(portid);
> > - else
> > + link = device_link_add(dev, larb_mmu->dev,
> > + DL_FLAG_PM_RUNTIME |
> > + DL_FLAG_AUTOREMOVE_CONSUMER);
> > + if (!link) {
> > + dev_err(dev, "Unable to link %s\n",
> > + dev_name(larb_mmu->dev));
> > + return;
> > + }
> > + } else {
> > larb_mmu->mmu &= ~MTK_SMI_MMU_EN(portid);
> > + }
> > }
> > }
> >
> >