From 75487860a874a79aaa286c600989249aa9fe8fdc Mon Sep 17 00:00:00 2001 From: Honghui Zhang Date: Fri, 4 Aug 2017 09:32:25 +0800 Subject: memory: mtk-smi: Use of_device_get_match_data helper Replace custom code with generic helper to retrieve driver data. Signed-off-by: Honghui Zhang Signed-off-by: Joerg Roedel --- drivers/memory/mtk-smi.c | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) (limited to 'drivers/memory') diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c index 4afbc412f959..2b798bb48b74 100644 --- a/drivers/memory/mtk-smi.c +++ b/drivers/memory/mtk-smi.c @@ -240,20 +240,15 @@ 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; - const struct of_device_id *of_id; if (!dev->pm_domain) return -EPROBE_DEFER; - of_id = of_match_node(mtk_smi_larb_of_ids, pdev->dev.of_node); - if (!of_id) - return -EINVAL; - larb = devm_kzalloc(dev, sizeof(*larb), GFP_KERNEL); if (!larb) return -ENOMEM; - larb->larb_gen = of_id->data; + larb->larb_gen = of_device_get_match_data(dev); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); larb->base = devm_ioremap_resource(dev, res); if (IS_ERR(larb->base)) @@ -319,7 +314,6 @@ static int mtk_smi_common_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct mtk_smi *common; struct resource *res; - const struct of_device_id *of_id; enum mtk_smi_gen smi_gen; if (!dev->pm_domain) @@ -338,17 +332,13 @@ static int mtk_smi_common_probe(struct platform_device *pdev) if (IS_ERR(common->clk_smi)) return PTR_ERR(common->clk_smi); - of_id = of_match_node(mtk_smi_common_of_ids, pdev->dev.of_node); - if (!of_id) - return -EINVAL; - /* * for mtk smi gen 1, we need to get the ao(always on) base to config * m4u port, and we need to enable the aync clock for transform the smi * clock into emi clock domain, but for mtk smi gen2, there's no smi ao * base. */ - smi_gen = (enum mtk_smi_gen)of_id->data; + smi_gen = (enum mtk_smi_gen)of_device_get_match_data(dev); if (smi_gen == MTK_SMI_GEN1) { res = platform_get_resource(pdev, IORESOURCE_MEM, 0); common->smi_ao_base = devm_ioremap_resource(dev, res); -- cgit v1.2.3 From 363932cdef4ba4e359ffd544d5b31d3eb31b358a Mon Sep 17 00:00:00 2001 From: Honghui Zhang Date: Fri, 4 Aug 2017 09:32:26 +0800 Subject: memory: mtk-smi: add larbid handle routine In the commit 3c8f4ad85c4b ("memory/mediatek: add support for mt2701"), the larb->larbid was added but not initialized. Mediatek's gen1 smi need this hardware larbid information to get the register offset which controls whether enable iommu for this larb. This patch add the initialize routine for larbid. Reviewed-by: Matthias Brugger Signed-off-by: Honghui Zhang Signed-off-by: Joerg Roedel --- drivers/memory/mtk-smi.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'drivers/memory') diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c index 2b798bb48b74..a3ff19aed087 100644 --- a/drivers/memory/mtk-smi.c +++ b/drivers/memory/mtk-smi.c @@ -42,6 +42,7 @@ #define SMI_SECUR_CON_VAL_DOMAIN(id) (0x3 << ((((id) & 0x7) << 2) + 1)) struct mtk_smi_larb_gen { + bool need_larbid; int port_in_larb[MTK_LARB_NR_MAX + 1]; void (*config_port)(struct device *); }; @@ -214,6 +215,7 @@ static const struct mtk_smi_larb_gen mtk_smi_larb_mt8173 = { }; static const struct mtk_smi_larb_gen mtk_smi_larb_mt2701 = { + .need_larbid = true, .port_in_larb = { LARB0_PORT_OFFSET, LARB1_PORT_OFFSET, LARB2_PORT_OFFSET, LARB3_PORT_OFFSET @@ -240,6 +242,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; + int err; if (!dev->pm_domain) return -EPROBE_DEFER; @@ -263,6 +266,15 @@ static int mtk_smi_larb_probe(struct platform_device *pdev) return PTR_ERR(larb->smi.clk_smi); larb->smi.dev = dev; + if (larb->larb_gen->need_larbid) { + err = of_property_read_u32(dev->of_node, "mediatek,larb-id", + &larb->larbid); + if (err) { + dev_err(dev, "missing larbid property\n"); + return err; + } + } + smi_node = of_parse_phandle(dev->of_node, "mediatek,smi", 0); if (!smi_node) return -EINVAL; -- cgit v1.2.3 From 46cc815d6d8c3c9dd18ffae1e3e818eb3ce2c788 Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Thu, 10 Aug 2017 10:47:32 +0530 Subject: memory: mtk-smi: Handle return value of clk_prepare_enable clk_prepare_enable() can fail here and we must check its return value. Signed-off-by: Arvind Yadav Signed-off-by: Joerg Roedel --- drivers/memory/mtk-smi.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers/memory') diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c index a3ff19aed087..13f8c45dbf0d 100644 --- a/drivers/memory/mtk-smi.c +++ b/drivers/memory/mtk-smi.c @@ -327,6 +327,7 @@ static int mtk_smi_common_probe(struct platform_device *pdev) struct mtk_smi *common; struct resource *res; enum mtk_smi_gen smi_gen; + int ret; if (!dev->pm_domain) return -EPROBE_DEFER; @@ -361,7 +362,9 @@ static int mtk_smi_common_probe(struct platform_device *pdev) if (IS_ERR(common->clk_async)) return PTR_ERR(common->clk_async); - clk_prepare_enable(common->clk_async); + ret = clk_prepare_enable(common->clk_async); + if (ret) + return ret; } pm_runtime_enable(dev); platform_set_drvdata(pdev, common); -- cgit v1.2.3 From e6dec92308628cff5f1f8bd1bcdf87581c9dc676 Mon Sep 17 00:00:00 2001 From: Yong Wu Date: Mon, 21 Aug 2017 19:00:16 +0800 Subject: iommu/mediatek: Add mt2712 IOMMU support The M4U IP blocks in mt2712 is MTK's generation2 M4U which use the ARM Short-descriptor like mt8173, and most of the HW registers are the same. The difference is that there are 2 M4U HWs in mt2712 while there's only one in mt8173. The purpose of 2 M4U HWs is for balance the bandwidth. Normally if there are 2 M4U HWs, there should be 2 iommu domains, each M4U has a iommu domain. Signed-off-by: Yong Wu Signed-off-by: Joerg Roedel --- drivers/iommu/mtk_iommu.c | 71 ++++++++++++++++++++++------------------------ drivers/iommu/mtk_iommu.h | 7 +++++ drivers/memory/mtk-smi.c | 54 +++++++++++++++++++++++++++++++++-- include/soc/mediatek/smi.h | 2 +- 4 files changed, 93 insertions(+), 41 deletions(-) (limited to 'drivers/memory') diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c index 4db6c8f66b0c..df23e0201336 100644 --- a/drivers/iommu/mtk_iommu.c +++ b/drivers/iommu/mtk_iommu.c @@ -53,7 +53,11 @@ #define REG_MMU_CTRL_REG 0x110 #define F_MMU_PREFETCH_RT_REPLACE_MOD BIT(4) -#define F_MMU_TF_PROTECT_SEL(prot) (((prot) & 0x3) << 5) +#define F_MMU_TF_PROTECT_SEL_SHIFT(data) \ + ((data)->m4u_plat == M4U_MT2712 ? 4 : 5) +/* It's named by F_MMU_TF_PROT_SEL in mt2712. */ +#define F_MMU_TF_PROTECT_SEL(prot, data) \ + (((prot) & 0x3) << F_MMU_TF_PROTECT_SEL_SHIFT(data)) #define REG_MMU_IVRP_PADDR 0x114 #define F_MMU_IVRP_PA_SET(pa, ext) (((pa) >> 1) | ((!!(ext)) << 31)) @@ -96,7 +100,7 @@ * Get the local arbiter ID and the portid within the larb arbiter * from mtk_m4u_id which is defined by MTK_M4U_ID. */ -#define MTK_M4U_TO_LARB(id) (((id) >> 5) & 0x7) +#define MTK_M4U_TO_LARB(id) (((id) >> 5) & 0xf) #define MTK_M4U_TO_PORT(id) ((id) & 0x1f) struct mtk_iommu_domain { @@ -307,10 +311,6 @@ static int mtk_iommu_attach_device(struct iommu_domain *domain, data->m4u_dom = NULL; return ret; } - } else if (data->m4u_dom != dom) { - /* All the client devices should be in the same m4u domain */ - dev_err(dev, "try to attach into the error iommu domain\n"); - return -EPERM; } mtk_iommu_config(data, dev, true); @@ -470,8 +470,9 @@ static int mtk_iommu_hw_init(const struct mtk_iommu_data *data) return ret; } - regval = F_MMU_PREFETCH_RT_REPLACE_MOD | - F_MMU_TF_PROTECT_SEL(2); + regval = F_MMU_TF_PROTECT_SEL(2, data); + if (data->m4u_plat == M4U_MT8173) + regval |= F_MMU_PREFETCH_RT_REPLACE_MOD; writel_relaxed(regval, data->base + REG_MMU_CTRL_REG); regval = F_L2_MULIT_HIT_EN | @@ -493,9 +494,11 @@ static int mtk_iommu_hw_init(const struct mtk_iommu_data *data) writel_relaxed(F_MMU_IVRP_PA_SET(data->protect_base, data->enable_4GB), data->base + REG_MMU_IVRP_PADDR); - writel_relaxed(0, data->base + REG_MMU_DCM_DIS); - writel_relaxed(0, data->base + REG_MMU_STANDARD_AXI_MODE); + + /* It's MISC control register whose default value is ok except mt8173.*/ + if (data->m4u_plat == M4U_MT8173) + writel_relaxed(0, data->base + REG_MMU_STANDARD_AXI_MODE); if (devm_request_irq(data->dev, data->irq, mtk_iommu_isr, 0, dev_name(data->dev), (void *)data)) { @@ -527,6 +530,7 @@ static int mtk_iommu_probe(struct platform_device *pdev) if (!data) return -ENOMEM; data->dev = dev; + data->m4u_plat = (enum mtk_iommu_plat)of_device_get_match_data(dev); /* Protect memory. HW will access here while translation fault.*/ protect = devm_kzalloc(dev, MTK_PROTECT_PA_ALIGN * 2, GFP_KERNEL); @@ -560,6 +564,7 @@ static int mtk_iommu_probe(struct platform_device *pdev) for (i = 0; i < larb_nr; i++) { struct device_node *larbnode; struct platform_device *plarbdev; + u32 id; larbnode = of_parse_phandle(dev->of_node, "mediatek,larbs", i); if (!larbnode) @@ -568,17 +573,14 @@ static int mtk_iommu_probe(struct platform_device *pdev) if (!of_device_is_available(larbnode)) continue; + ret = of_property_read_u32(larbnode, "mediatek,larb-id", &id); + if (ret)/* The id is consecutive if there is no this property */ + id = i; + plarbdev = of_find_device_by_node(larbnode); - if (!plarbdev) { - plarbdev = of_platform_device_create( - larbnode, NULL, - platform_bus_type.dev_root); - if (!plarbdev) { - of_node_put(larbnode); - return -EPROBE_DEFER; - } - } - data->smi_imu.larb_imu[i].dev = &plarbdev->dev; + if (!plarbdev) + return -EPROBE_DEFER; + data->smi_imu.larb_imu[id].dev = &plarbdev->dev; component_match_add_release(dev, &match, release_of, compare_of, larbnode); @@ -646,8 +648,6 @@ static int __maybe_unused mtk_iommu_resume(struct device *dev) struct mtk_iommu_suspend_reg *reg = &data->reg; void __iomem *base = data->base; - writel_relaxed(data->m4u_dom->cfg.arm_v7s_cfg.ttbr[0], - base + REG_MMU_PT_BASE_ADDR); writel_relaxed(reg->standard_axi_mode, base + REG_MMU_STANDARD_AXI_MODE); writel_relaxed(reg->dcm_dis, base + REG_MMU_DCM_DIS); @@ -656,15 +656,19 @@ static int __maybe_unused mtk_iommu_resume(struct device *dev) writel_relaxed(reg->int_main_control, base + REG_MMU_INT_MAIN_CONTROL); writel_relaxed(F_MMU_IVRP_PA_SET(data->protect_base, data->enable_4GB), base + REG_MMU_IVRP_PADDR); + if (data->m4u_dom) + writel(data->m4u_dom->cfg.arm_v7s_cfg.ttbr[0], + base + REG_MMU_PT_BASE_ADDR); return 0; } -const struct dev_pm_ops mtk_iommu_pm_ops = { +static const struct dev_pm_ops mtk_iommu_pm_ops = { SET_SYSTEM_SLEEP_PM_OPS(mtk_iommu_suspend, mtk_iommu_resume) }; static const struct of_device_id mtk_iommu_of_ids[] = { - { .compatible = "mediatek,mt8173-m4u", }, + { .compatible = "mediatek,mt2712-m4u", .data = (void *)M4U_MT2712}, + { .compatible = "mediatek,mt8173-m4u", .data = (void *)M4U_MT8173}, {} }; @@ -673,27 +677,20 @@ static struct platform_driver mtk_iommu_driver = { .remove = mtk_iommu_remove, .driver = { .name = "mtk-iommu", - .of_match_table = mtk_iommu_of_ids, + .of_match_table = of_match_ptr(mtk_iommu_of_ids), .pm = &mtk_iommu_pm_ops, } }; -static int mtk_iommu_init_fn(struct device_node *np) +static int __init mtk_iommu_init(void) { int ret; - struct platform_device *pdev; - - pdev = of_platform_device_create(np, NULL, platform_bus_type.dev_root); - if (!pdev) - return -ENOMEM; ret = platform_driver_register(&mtk_iommu_driver); - if (ret) { - pr_err("%s: Failed to register driver\n", __func__); - return ret; - } + if (ret != 0) + pr_err("Failed to register MTK IOMMU driver\n"); - return 0; + return ret; } -IOMMU_OF_DECLARE(mtkm4u, "mediatek,mt8173-m4u", mtk_iommu_init_fn); +subsys_initcall(mtk_iommu_init) diff --git a/drivers/iommu/mtk_iommu.h b/drivers/iommu/mtk_iommu.h index c06cc91b5d9a..462e593b7d71 100644 --- a/drivers/iommu/mtk_iommu.h +++ b/drivers/iommu/mtk_iommu.h @@ -34,6 +34,12 @@ struct mtk_iommu_suspend_reg { u32 int_main_control; }; +enum mtk_iommu_plat { + M4U_MT2701, + M4U_MT2712, + M4U_MT8173, +}; + struct mtk_iommu_domain; struct mtk_iommu_data { @@ -50,6 +56,7 @@ struct mtk_iommu_data { bool tlb_flush_active; struct iommu_device iommu; + enum mtk_iommu_plat m4u_plat; }; static inline int compare_of(struct device *dev, void *data) diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c index 13f8c45dbf0d..8ffe3216d092 100644 --- a/drivers/memory/mtk-smi.c +++ b/drivers/memory/mtk-smi.c @@ -23,7 +23,10 @@ #include #include +/* mt8173 */ #define SMI_LARB_MMU_EN 0xf00 + +/* mt2701 */ #define REG_SMI_SECUR_CON_BASE 0x5c0 /* every register control 8 port, register offset 0x4 */ @@ -41,6 +44,10 @@ /* mt2701 domain should be set to 3 */ #define SMI_SECUR_CON_VAL_DOMAIN(id) (0x3 << ((((id) & 0x7) << 2) + 1)) +/* mt2712 */ +#define SMI_LARB_NONSEC_CON(id) (0x380 + ((id) * 4)) +#define F_MMU_EN BIT(0) + struct mtk_smi_larb_gen { bool need_larbid; int port_in_larb[MTK_LARB_NR_MAX + 1]; @@ -149,6 +156,15 @@ mtk_smi_larb_bind(struct device *dev, struct device *master, void *data) struct mtk_smi_iommu *smi_iommu = data; unsigned int i; + if (larb->larb_gen->need_larbid) { + larb->mmu = &smi_iommu->larb_imu[larb->larbid].mmu; + return 0; + } + + /* + * If there is no larbid property, Loop to find the corresponding + * iommu information. + */ for (i = 0; i < smi_iommu->larb_nr; i++) { if (dev == smi_iommu->larb_imu[i].dev) { /* The 'mmu' may be updated in iommu-attach/detach. */ @@ -159,13 +175,32 @@ mtk_smi_larb_bind(struct device *dev, struct device *master, void *data) return -ENODEV; } -static void mtk_smi_larb_config_port(struct device *dev) +static void mtk_smi_larb_config_port_mt2712(struct device *dev) { struct mtk_smi_larb *larb = dev_get_drvdata(dev); + u32 reg; + int i; - writel(*larb->mmu, larb->base + SMI_LARB_MMU_EN); + /* + * larb 8/9 is the bdpsys larb, the iommu_en is enabled defaultly. + * Don't need to set it again. + */ + if (larb->larbid == 8 || larb->larbid == 9) + return; + + for_each_set_bit(i, (unsigned long *)larb->mmu, 32) { + reg = readl_relaxed(larb->base + SMI_LARB_NONSEC_CON(i)); + reg |= F_MMU_EN; + writel(reg, larb->base + SMI_LARB_NONSEC_CON(i)); + } } +static void mtk_smi_larb_config_port_mt8173(struct device *dev) +{ + struct mtk_smi_larb *larb = dev_get_drvdata(dev); + + writel(*larb->mmu, larb->base + SMI_LARB_MMU_EN); +} static void mtk_smi_larb_config_port_gen1(struct device *dev) { @@ -211,7 +246,7 @@ static const struct component_ops mtk_smi_larb_component_ops = { static const struct mtk_smi_larb_gen mtk_smi_larb_mt8173 = { /* mt8173 do not need the port in larb */ - .config_port = mtk_smi_larb_config_port, + .config_port = mtk_smi_larb_config_port_mt8173, }; static const struct mtk_smi_larb_gen mtk_smi_larb_mt2701 = { @@ -223,6 +258,11 @@ static const struct mtk_smi_larb_gen mtk_smi_larb_mt2701 = { .config_port = mtk_smi_larb_config_port_gen1, }; +static const struct mtk_smi_larb_gen mtk_smi_larb_mt2712 = { + .need_larbid = true, + .config_port = mtk_smi_larb_config_port_mt2712, +}; + static const struct of_device_id mtk_smi_larb_of_ids[] = { { .compatible = "mediatek,mt8173-smi-larb", @@ -232,6 +272,10 @@ static const struct of_device_id mtk_smi_larb_of_ids[] = { .compatible = "mediatek,mt2701-smi-larb", .data = &mtk_smi_larb_mt2701 }, + { + .compatible = "mediatek,mt2712-smi-larb", + .data = &mtk_smi_larb_mt2712 + }, {} }; @@ -318,6 +362,10 @@ static const struct of_device_id mtk_smi_common_of_ids[] = { .compatible = "mediatek,mt2701-smi-common", .data = (void *)MTK_SMI_GEN1 }, + { + .compatible = "mediatek,mt2712-smi-common", + .data = (void *)MTK_SMI_GEN2 + }, {} }; diff --git a/include/soc/mediatek/smi.h b/include/soc/mediatek/smi.h index 8893c5eacd07..5201e9022c86 100644 --- a/include/soc/mediatek/smi.h +++ b/include/soc/mediatek/smi.h @@ -19,7 +19,7 @@ #ifdef CONFIG_MTK_SMI -#define MTK_LARB_NR_MAX 8 +#define MTK_LARB_NR_MAX 16 #define MTK_SMI_MMU_EN(port) BIT(port) -- cgit v1.2.3 From 4f608d382e6fa982655e37d0e1b6c134fdc0e4c3 Mon Sep 17 00:00:00 2001 From: Yong Wu Date: Mon, 21 Aug 2017 19:00:21 +0800 Subject: memory: mtk-smi: Degrade SMI init to module_init The initialization of MediaTek power manager(SCPSYS) is builtin_platform_driver, and SMI must depend on power-domain. Thus, currently subsys_initcall for SMI is unnecessary, SMI will be always probe defered by power-domain. Degrade it to module_init. In addition, there are two small changes about the probe sequence: 1) Delete this two lines. if (!dev->pm_domain) return -EPROBE_DEFER; This is not helpful. the platform driver framework guarantee this. The "dev_pm_domain_attach" in the "platform_drv_probe" will return EPROBE_DEFER if its powerdomain is not ready. 2) Add the probe-defer for the smi-larb device should waiting for smi-common. In mt2712, there are 2 smi-commons, 10 smi-larbs. All will be probe-defered by the power-domain, there is seldom case that smi-larb probe done before smi-common. then it will hang like this: Unable to handle kernel NULL pointer dereference at virtual address 00000000 pgd = ffffff800a4e0000 [00000000] *pgd=00000000beffe003[ 17.610026] , *pud=00000000beffe003 ... [] mtk_smi_enable+0x1c/0xd0 [] mtk_smi_larb_get+0x30/0x98 [] mtk_mipicsi0_resume+0x38/0x1b8 [] pm_generic_runtime_resume+0x3c/0x58 [] __genpd_runtime_resume+0x38/0x98 [] genpd_runtime_resume+0x164/0x220 [] __rpm_callback+0x78/0xa0 [] rpm_callback+0x38/0xa0 [] rpm_resume+0x4a4/0x6f8 [] __pm_runtime_resume+0x64/0xa0 [] mtk_mipicsi0_probe+0x40c/0xb70 [] platform_drv_probe+0x58/0xc0 [] driver_probe_device+0x284/0x438 [] __device_attach_driver+0xb4/0x160 [] bus_for_each_drv+0x68/0xa8 [] __device_attach+0xd4/0x168 [] device_initial_probe+0x24/0x30 [] bus_probe_device+0xa0/0xa8 [] deferred_probe_work_func+0x94/0xf0 [] process_one_work+0x1d8/0x6e0 Signed-off-by: Yong Wu Signed-off-by: Joerg Roedel --- drivers/memory/mtk-smi.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'drivers/memory') diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c index 8ffe3216d092..8f2d152a78b8 100644 --- a/drivers/memory/mtk-smi.c +++ b/drivers/memory/mtk-smi.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -288,9 +289,6 @@ static int mtk_smi_larb_probe(struct platform_device *pdev) struct platform_device *smi_pdev; int err; - if (!dev->pm_domain) - return -EPROBE_DEFER; - larb = devm_kzalloc(dev, sizeof(*larb), GFP_KERNEL); if (!larb) return -ENOMEM; @@ -326,6 +324,8 @@ static int mtk_smi_larb_probe(struct platform_device *pdev) smi_pdev = of_find_device_by_node(smi_node); of_node_put(smi_node); if (smi_pdev) { + if (!platform_get_drvdata(smi_pdev)) + return -EPROBE_DEFER; larb->smi_common_dev = &smi_pdev->dev; } else { dev_err(dev, "Failed to get the smi_common device\n"); @@ -377,9 +377,6 @@ static int mtk_smi_common_probe(struct platform_device *pdev) enum mtk_smi_gen smi_gen; int ret; - if (!dev->pm_domain) - return -EPROBE_DEFER; - common = devm_kzalloc(dev, sizeof(*common), GFP_KERNEL); if (!common) return -ENOMEM; @@ -456,4 +453,4 @@ err_unreg_smi: return ret; } -subsys_initcall(mtk_smi_init); +module_init(mtk_smi_init); -- cgit v1.2.3