Message ID | 1593656074-10092-4-git-send-email-Anson.Huang@nxp.com (mailing list archive) |
---|---|
State | Superseded, archived |
Headers | show |
Series | Support building i.MX8 SoCs clock driver as module | expand |
On Thu, Jul 2, 2020 at 10:19 AM Anson Huang <Anson.Huang@nxp.com> wrote: > > There are more and more requirements of building SoC specific drivers > as modules, add support for building i.MX common clock driver as module > to meet the requirement. > > Signed-off-by: Anson Huang <Anson.Huang@nxp.com> > --- > Changes since V3: > - ONLY include __setup_param() build for built-in, module build no need > to have it. > --- > drivers/clk/imx/Kconfig | 8 ++++++-- > drivers/clk/imx/Makefile | 40 +++++++++++++++++++------------------- > drivers/clk/imx/clk-composite-8m.c | 2 ++ > drivers/clk/imx/clk-cpu.c | 2 ++ > drivers/clk/imx/clk-frac-pll.c | 2 ++ > drivers/clk/imx/clk-gate2.c | 2 ++ > drivers/clk/imx/clk-pll14xx.c | 5 +++++ > drivers/clk/imx/clk-sscg-pll.c | 2 ++ > drivers/clk/imx/clk.c | 22 +++++++++++++++------ > 9 files changed, 57 insertions(+), 28 deletions(-) > > diff --git a/drivers/clk/imx/Kconfig b/drivers/clk/imx/Kconfig > index 09fc8ad..f6ddf76 100644 > --- a/drivers/clk/imx/Kconfig > +++ b/drivers/clk/imx/Kconfig > @@ -1,8 +1,8 @@ > # SPDX-License-Identifier: GPL-2.0 > # common clock support for NXP i.MX SoC family. > config MXC_CLK > - bool > - def_bool ARCH_MXC > + tristate "IMX clock" > + depends on ARCH_MXC > > config MXC_CLK_SCU > bool > @@ -101,24 +101,28 @@ config CLK_VF610 > config CLK_IMX8MM > bool "IMX8MM CCM Clock Driver" > depends on ARCH_MXC > + select MXC_CLK > help > Build the driver for i.MX8MM CCM Clock Driver > > config CLK_IMX8MN > bool "IMX8MN CCM Clock Driver" > depends on ARCH_MXC > + select MXC_CLK > help > Build the driver for i.MX8MN CCM Clock Driver > > config CLK_IMX8MP > bool "IMX8MP CCM Clock Driver" > depends on ARCH_MXC > + select MXC_CLK > help > Build the driver for i.MX8MP CCM Clock Driver > > config CLK_IMX8MQ > bool "IMX8MQ CCM Clock Driver" > depends on ARCH_MXC > + select MXC_CLK > help > Build the driver for i.MX8MQ CCM Clock Driver > > diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile > index 394ade7..17f5d12 100644 > --- a/drivers/clk/imx/Makefile > +++ b/drivers/clk/imx/Makefile > @@ -1,25 +1,25 @@ > # SPDX-License-Identifier: GPL-2.0 > > -obj-$(CONFIG_MXC_CLK) += \ > - clk.o \ > - clk-busy.o \ > - clk-composite-8m.o \ > - clk-cpu.o \ > - clk-composite-7ulp.o \ > - clk-divider-gate.o \ > - clk-fixup-div.o \ > - clk-fixup-mux.o \ > - clk-frac-pll.o \ > - clk-gate-exclusive.o \ > - clk-gate2.o \ > - clk-pfd.o \ > - clk-pfdv2.o \ > - clk-pllv1.o \ > - clk-pllv2.o \ > - clk-pllv3.o \ > - clk-pllv4.o \ > - clk-sscg-pll.o \ > - clk-pll14xx.o > +mxc-clk-objs += clk.o > +mxc-clk-objs += clk-busy.o > +mxc-clk-objs += clk-composite-7ulp.o > +mxc-clk-objs += clk-composite-8m.o > +mxc-clk-objs += clk-cpu.o > +mxc-clk-objs += clk-divider-gate.o > +mxc-clk-objs += clk-fixup-div.o > +mxc-clk-objs += clk-fixup-mux.o > +mxc-clk-objs += clk-frac-pll.o > +mxc-clk-objs += clk-gate2.o > +mxc-clk-objs += clk-gate-exclusive.o > +mxc-clk-objs += clk-pfd.o > +mxc-clk-objs += clk-pfdv2.o > +mxc-clk-objs += clk-pllv1.o > +mxc-clk-objs += clk-pllv2.o > +mxc-clk-objs += clk-pllv3.o > +mxc-clk-objs += clk-pllv4.o > +mxc-clk-objs += clk-pll14xx.o > +mxc-clk-objs += clk-sscg-pll.o > +obj-$(CONFIG_MXC_CLK) += mxc-clk.o > > obj-$(CONFIG_MXC_CLK_SCU) += \ > clk-scu.o \ > diff --git a/drivers/clk/imx/clk-composite-8m.c b/drivers/clk/imx/clk-composite-8m.c > index d2b5af8..78fb7e5 100644 > --- a/drivers/clk/imx/clk-composite-8m.c > +++ b/drivers/clk/imx/clk-composite-8m.c > @@ -5,6 +5,7 @@ > > #include <linux/clk-provider.h> > #include <linux/errno.h> > +#include <linux/export.h> > #include <linux/io.h> > #include <linux/slab.h> > > @@ -243,3 +244,4 @@ struct clk_hw *imx8m_clk_hw_composite_flags(const char *name, > kfree(mux); > return ERR_CAST(hw); > } > +EXPORT_SYMBOL_GPL(imx8m_clk_hw_composite_flags); > diff --git a/drivers/clk/imx/clk-cpu.c b/drivers/clk/imx/clk-cpu.c > index cb182be..cb6ca4c 100644 > --- a/drivers/clk/imx/clk-cpu.c > +++ b/drivers/clk/imx/clk-cpu.c > @@ -5,6 +5,7 @@ > > #include <linux/clk.h> > #include <linux/clk-provider.h> > +#include <linux/export.h> > #include <linux/slab.h> > #include "clk.h" > > @@ -104,3 +105,4 @@ struct clk_hw *imx_clk_hw_cpu(const char *name, const char *parent_name, > > return hw; > } > +EXPORT_SYMBOL_GPL(imx_clk_hw_cpu); > diff --git a/drivers/clk/imx/clk-frac-pll.c b/drivers/clk/imx/clk-frac-pll.c > index 101e0a3..c703056 100644 > --- a/drivers/clk/imx/clk-frac-pll.c > +++ b/drivers/clk/imx/clk-frac-pll.c > @@ -10,6 +10,7 @@ > > #include <linux/clk-provider.h> > #include <linux/err.h> > +#include <linux/export.h> > #include <linux/io.h> > #include <linux/iopoll.h> > #include <linux/slab.h> > @@ -233,3 +234,4 @@ struct clk_hw *imx_clk_hw_frac_pll(const char *name, > > return hw; > } > +EXPORT_SYMBOL_GPL(imx_clk_hw_frac_pll); > diff --git a/drivers/clk/imx/clk-gate2.c b/drivers/clk/imx/clk-gate2.c > index b87ab3c..512f675 100644 > --- a/drivers/clk/imx/clk-gate2.c > +++ b/drivers/clk/imx/clk-gate2.c > @@ -7,6 +7,7 @@ > */ > > #include <linux/clk-provider.h> > +#include <linux/export.h> > #include <linux/module.h> > #include <linux/slab.h> > #include <linux/io.h> > @@ -177,3 +178,4 @@ struct clk_hw *clk_hw_register_gate2(struct device *dev, const char *name, > > return hw; > } > +EXPORT_SYMBOL_GPL(clk_hw_register_gate2); > diff --git a/drivers/clk/imx/clk-pll14xx.c b/drivers/clk/imx/clk-pll14xx.c > index f9eb189..f5c3e7e 100644 > --- a/drivers/clk/imx/clk-pll14xx.c > +++ b/drivers/clk/imx/clk-pll14xx.c > @@ -6,6 +6,7 @@ > #include <linux/bitops.h> > #include <linux/clk-provider.h> > #include <linux/err.h> > +#include <linux/export.h> > #include <linux/io.h> > #include <linux/iopoll.h> > #include <linux/slab.h> > @@ -68,6 +69,7 @@ struct imx_pll14xx_clk imx_1443x_pll = { > .rate_table = imx_pll1443x_tbl, > .rate_count = ARRAY_SIZE(imx_pll1443x_tbl), > }; > +EXPORT_SYMBOL_GPL(imx_1443x_pll); > > struct imx_pll14xx_clk imx_1443x_dram_pll = { > .type = PLL_1443X, > @@ -75,12 +77,14 @@ struct imx_pll14xx_clk imx_1443x_dram_pll = { > .rate_count = ARRAY_SIZE(imx_pll1443x_tbl), > .flags = CLK_GET_RATE_NOCACHE, > }; > +EXPORT_SYMBOL_GPL(imx_1443x_dram_pll); > > struct imx_pll14xx_clk imx_1416x_pll = { > .type = PLL_1416X, > .rate_table = imx_pll1416x_tbl, > .rate_count = ARRAY_SIZE(imx_pll1416x_tbl), > }; > +EXPORT_SYMBOL_GPL(imx_1416x_pll); > > static const struct imx_pll14xx_rate_table *imx_get_pll_settings( > struct clk_pll14xx *pll, unsigned long rate) > @@ -436,3 +440,4 @@ struct clk_hw *imx_dev_clk_hw_pll14xx(struct device *dev, const char *name, > > return hw; > } > +EXPORT_SYMBOL_GPL(imx_dev_clk_hw_pll14xx); > diff --git a/drivers/clk/imx/clk-sscg-pll.c b/drivers/clk/imx/clk-sscg-pll.c > index 773d8a5..9d6cdff 100644 > --- a/drivers/clk/imx/clk-sscg-pll.c > +++ b/drivers/clk/imx/clk-sscg-pll.c > @@ -10,6 +10,7 @@ > > #include <linux/clk-provider.h> > #include <linux/err.h> > +#include <linux/export.h> > #include <linux/io.h> > #include <linux/iopoll.h> > #include <linux/slab.h> > @@ -537,3 +538,4 @@ struct clk_hw *imx_clk_hw_sscg_pll(const char *name, > > return hw; > } > +EXPORT_SYMBOL_GPL(imx_clk_hw_sscg_pll); > diff --git a/drivers/clk/imx/clk.c b/drivers/clk/imx/clk.c > index 87ab8db..6f2a94d 100644 > --- a/drivers/clk/imx/clk.c > +++ b/drivers/clk/imx/clk.c > @@ -3,6 +3,7 @@ > #include <linux/clk-provider.h> > #include <linux/err.h> > #include <linux/io.h> > +#include <linux/module.h> > #include <linux/of.h> > #include <linux/slab.h> > #include <linux/spinlock.h> > @@ -13,6 +14,7 @@ > #define CCDR_MMDC_CH1_MASK BIT(16) > > DEFINE_SPINLOCK(imx_ccm_lock); > +EXPORT_SYMBOL_GPL(imx_ccm_lock); > > void imx_unregister_clocks(struct clk *clks[], unsigned int count) > { > @@ -29,8 +31,9 @@ void imx_unregister_hw_clocks(struct clk_hw *hws[], unsigned int count) > for (i = 0; i < count; i++) > clk_hw_unregister(hws[i]); > } > +EXPORT_SYMBOL_GPL(imx_unregister_hw_clocks); > > -void __init imx_mmdc_mask_handshake(void __iomem *ccm_base, > +void imx_mmdc_mask_handshake(void __iomem *ccm_base, > unsigned int chn) > { > unsigned int reg; > @@ -59,8 +62,9 @@ void imx_check_clk_hws(struct clk_hw *clks[], unsigned int count) > pr_err("i.MX clk %u: register failed with %ld\n", > i, PTR_ERR(clks[i])); > } > +EXPORT_SYMBOL_GPL(imx_check_clk_hws); > > -static struct clk * __init imx_obtain_fixed_clock_from_dt(const char *name) > +static struct clk *imx_obtain_fixed_clock_from_dt(const char *name) > { > struct of_phandle_args phandle; > struct clk *clk = ERR_PTR(-ENODEV); > @@ -80,7 +84,7 @@ static struct clk * __init imx_obtain_fixed_clock_from_dt(const char *name) > return clk; > } > > -struct clk * __init imx_obtain_fixed_clock( > +struct clk *imx_obtain_fixed_clock( > const char *name, unsigned long rate) > { > struct clk *clk; > @@ -91,7 +95,7 @@ struct clk * __init imx_obtain_fixed_clock( > return clk; > } > > -struct clk_hw * __init imx_obtain_fixed_clock_hw( > +struct clk_hw *imx_obtain_fixed_clock_hw( > const char *name, unsigned long rate) > { > struct clk *clk; > @@ -113,6 +117,7 @@ struct clk_hw * imx_obtain_fixed_clk_hw(struct device_node *np, > > return __clk_get_hw(clk); > } > +EXPORT_SYMBOL_GPL(imx_obtain_fixed_clk_hw); > > /* > * This fixups the register CCM_CSCMR1 write value. > @@ -143,16 +148,18 @@ void imx_cscmr1_fixup(u32 *val) > static int imx_keep_uart_clocks; > static struct clk ** const *imx_uart_clocks; > > -static int __init imx_keep_uart_clocks_param(char *str) > +static int __maybe_unused imx_keep_uart_clocks_param(char *str) > { > imx_keep_uart_clocks = 1; > > return 0; > } > +#ifndef MODULE > __setup_param("earlycon", imx_keep_uart_earlycon, > imx_keep_uart_clocks_param, 0); > __setup_param("earlyprintk", imx_keep_uart_earlyprintk, > imx_keep_uart_clocks_param, 0); I feel not only the __setup_param, the whole logic of keep_uart_clocks are not needed for Module case. Is it true? Regards Aisheng > +#endif > > void imx_register_uart_clocks(struct clk ** const clks[]) > { > @@ -164,8 +171,9 @@ void imx_register_uart_clocks(struct clk ** const clks[]) > clk_prepare_enable(*imx_uart_clocks[i]); > } > } > +EXPORT_SYMBOL_GPL(imx_register_uart_clocks); > > -static int __init imx_clk_disable_uart(void) > +static int imx_clk_disable_uart(void) > { > if (imx_keep_uart_clocks && imx_uart_clocks) { > int i; > @@ -177,3 +185,5 @@ static int __init imx_clk_disable_uart(void) > return 0; > } > late_initcall_sync(imx_clk_disable_uart); > + > +MODULE_LICENSE("GPL v2"); > -- > 2.7.4 >
> Subject: Re: [PATCH V4 3/5] clk: imx: Support building i.MX common clock > driver as module > > On Thu, Jul 2, 2020 at 10:19 AM Anson Huang <Anson.Huang@nxp.com> > wrote: > > > > There are more and more requirements of building SoC specific drivers > > as modules, add support for building i.MX common clock driver as > > module to meet the requirement. > > > > Signed-off-by: Anson Huang <Anson.Huang@nxp.com> > > --- > > Changes since V3: > > - ONLY include __setup_param() build for built-in, module build no > need > > to have it. > > --- > > drivers/clk/imx/Kconfig | 8 ++++++-- > > drivers/clk/imx/Makefile | 40 > +++++++++++++++++++------------------- > > drivers/clk/imx/clk-composite-8m.c | 2 ++ > > drivers/clk/imx/clk-cpu.c | 2 ++ > > drivers/clk/imx/clk-frac-pll.c | 2 ++ > > drivers/clk/imx/clk-gate2.c | 2 ++ > > drivers/clk/imx/clk-pll14xx.c | 5 +++++ > > drivers/clk/imx/clk-sscg-pll.c | 2 ++ > > drivers/clk/imx/clk.c | 22 +++++++++++++++------ > > 9 files changed, 57 insertions(+), 28 deletions(-) > > > > diff --git a/drivers/clk/imx/Kconfig b/drivers/clk/imx/Kconfig index > > 09fc8ad..f6ddf76 100644 > > --- a/drivers/clk/imx/Kconfig > > +++ b/drivers/clk/imx/Kconfig > > @@ -1,8 +1,8 @@ > > # SPDX-License-Identifier: GPL-2.0 > > # common clock support for NXP i.MX SoC family. > > config MXC_CLK > > - bool > > - def_bool ARCH_MXC > > + tristate "IMX clock" > > + depends on ARCH_MXC > > > > config MXC_CLK_SCU > > bool > > @@ -101,24 +101,28 @@ config CLK_VF610 config CLK_IMX8MM > > bool "IMX8MM CCM Clock Driver" > > depends on ARCH_MXC > > + select MXC_CLK > > help > > Build the driver for i.MX8MM CCM Clock Driver > > > > config CLK_IMX8MN > > bool "IMX8MN CCM Clock Driver" > > depends on ARCH_MXC > > + select MXC_CLK > > help > > Build the driver for i.MX8MN CCM Clock Driver > > > > config CLK_IMX8MP > > bool "IMX8MP CCM Clock Driver" > > depends on ARCH_MXC > > + select MXC_CLK > > help > > Build the driver for i.MX8MP CCM Clock Driver > > > > config CLK_IMX8MQ > > bool "IMX8MQ CCM Clock Driver" > > depends on ARCH_MXC > > + select MXC_CLK > > help > > Build the driver for i.MX8MQ CCM Clock Driver > > > > diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile index > > 394ade7..17f5d12 100644 > > --- a/drivers/clk/imx/Makefile > > +++ b/drivers/clk/imx/Makefile > > @@ -1,25 +1,25 @@ > > # SPDX-License-Identifier: GPL-2.0 > > > > -obj-$(CONFIG_MXC_CLK) += \ > > - clk.o \ > > - clk-busy.o \ > > - clk-composite-8m.o \ > > - clk-cpu.o \ > > - clk-composite-7ulp.o \ > > - clk-divider-gate.o \ > > - clk-fixup-div.o \ > > - clk-fixup-mux.o \ > > - clk-frac-pll.o \ > > - clk-gate-exclusive.o \ > > - clk-gate2.o \ > > - clk-pfd.o \ > > - clk-pfdv2.o \ > > - clk-pllv1.o \ > > - clk-pllv2.o \ > > - clk-pllv3.o \ > > - clk-pllv4.o \ > > - clk-sscg-pll.o \ > > - clk-pll14xx.o > > +mxc-clk-objs += clk.o > > +mxc-clk-objs += clk-busy.o > > +mxc-clk-objs += clk-composite-7ulp.o > > +mxc-clk-objs += clk-composite-8m.o > > +mxc-clk-objs += clk-cpu.o > > +mxc-clk-objs += clk-divider-gate.o > > +mxc-clk-objs += clk-fixup-div.o > > +mxc-clk-objs += clk-fixup-mux.o > > +mxc-clk-objs += clk-frac-pll.o > > +mxc-clk-objs += clk-gate2.o > > +mxc-clk-objs += clk-gate-exclusive.o > > +mxc-clk-objs += clk-pfd.o > > +mxc-clk-objs += clk-pfdv2.o > > +mxc-clk-objs += clk-pllv1.o > > +mxc-clk-objs += clk-pllv2.o > > +mxc-clk-objs += clk-pllv3.o > > +mxc-clk-objs += clk-pllv4.o > > +mxc-clk-objs += clk-pll14xx.o > > +mxc-clk-objs += clk-sscg-pll.o > > +obj-$(CONFIG_MXC_CLK) += mxc-clk.o > > > > obj-$(CONFIG_MXC_CLK_SCU) += \ > > clk-scu.o \ > > diff --git a/drivers/clk/imx/clk-composite-8m.c > > b/drivers/clk/imx/clk-composite-8m.c > > index d2b5af8..78fb7e5 100644 > > --- a/drivers/clk/imx/clk-composite-8m.c > > +++ b/drivers/clk/imx/clk-composite-8m.c > > @@ -5,6 +5,7 @@ > > > > #include <linux/clk-provider.h> > > #include <linux/errno.h> > > +#include <linux/export.h> > > #include <linux/io.h> > > #include <linux/slab.h> > > > > @@ -243,3 +244,4 @@ struct clk_hw > *imx8m_clk_hw_composite_flags(const char *name, > > kfree(mux); > > return ERR_CAST(hw); > > } > > +EXPORT_SYMBOL_GPL(imx8m_clk_hw_composite_flags); > > diff --git a/drivers/clk/imx/clk-cpu.c b/drivers/clk/imx/clk-cpu.c > > index cb182be..cb6ca4c 100644 > > --- a/drivers/clk/imx/clk-cpu.c > > +++ b/drivers/clk/imx/clk-cpu.c > > @@ -5,6 +5,7 @@ > > > > #include <linux/clk.h> > > #include <linux/clk-provider.h> > > +#include <linux/export.h> > > #include <linux/slab.h> > > #include "clk.h" > > > > @@ -104,3 +105,4 @@ struct clk_hw *imx_clk_hw_cpu(const char *name, > > const char *parent_name, > > > > return hw; > > } > > +EXPORT_SYMBOL_GPL(imx_clk_hw_cpu); > > diff --git a/drivers/clk/imx/clk-frac-pll.c > > b/drivers/clk/imx/clk-frac-pll.c index 101e0a3..c703056 100644 > > --- a/drivers/clk/imx/clk-frac-pll.c > > +++ b/drivers/clk/imx/clk-frac-pll.c > > @@ -10,6 +10,7 @@ > > > > #include <linux/clk-provider.h> > > #include <linux/err.h> > > +#include <linux/export.h> > > #include <linux/io.h> > > #include <linux/iopoll.h> > > #include <linux/slab.h> > > @@ -233,3 +234,4 @@ struct clk_hw *imx_clk_hw_frac_pll(const char > > *name, > > > > return hw; > > } > > +EXPORT_SYMBOL_GPL(imx_clk_hw_frac_pll); > > diff --git a/drivers/clk/imx/clk-gate2.c b/drivers/clk/imx/clk-gate2.c > > index b87ab3c..512f675 100644 > > --- a/drivers/clk/imx/clk-gate2.c > > +++ b/drivers/clk/imx/clk-gate2.c > > @@ -7,6 +7,7 @@ > > */ > > > > #include <linux/clk-provider.h> > > +#include <linux/export.h> > > #include <linux/module.h> > > #include <linux/slab.h> > > #include <linux/io.h> > > @@ -177,3 +178,4 @@ struct clk_hw *clk_hw_register_gate2(struct device > > *dev, const char *name, > > > > return hw; > > } > > +EXPORT_SYMBOL_GPL(clk_hw_register_gate2); > > diff --git a/drivers/clk/imx/clk-pll14xx.c > > b/drivers/clk/imx/clk-pll14xx.c index f9eb189..f5c3e7e 100644 > > --- a/drivers/clk/imx/clk-pll14xx.c > > +++ b/drivers/clk/imx/clk-pll14xx.c > > @@ -6,6 +6,7 @@ > > #include <linux/bitops.h> > > #include <linux/clk-provider.h> > > #include <linux/err.h> > > +#include <linux/export.h> > > #include <linux/io.h> > > #include <linux/iopoll.h> > > #include <linux/slab.h> > > @@ -68,6 +69,7 @@ struct imx_pll14xx_clk imx_1443x_pll = { > > .rate_table = imx_pll1443x_tbl, > > .rate_count = ARRAY_SIZE(imx_pll1443x_tbl), }; > > +EXPORT_SYMBOL_GPL(imx_1443x_pll); > > > > struct imx_pll14xx_clk imx_1443x_dram_pll = { > > .type = PLL_1443X, > > @@ -75,12 +77,14 @@ struct imx_pll14xx_clk imx_1443x_dram_pll = { > > .rate_count = ARRAY_SIZE(imx_pll1443x_tbl), > > .flags = CLK_GET_RATE_NOCACHE, > > }; > > +EXPORT_SYMBOL_GPL(imx_1443x_dram_pll); > > > > struct imx_pll14xx_clk imx_1416x_pll = { > > .type = PLL_1416X, > > .rate_table = imx_pll1416x_tbl, > > .rate_count = ARRAY_SIZE(imx_pll1416x_tbl), > > }; > > +EXPORT_SYMBOL_GPL(imx_1416x_pll); > > > > static const struct imx_pll14xx_rate_table *imx_get_pll_settings( > > struct clk_pll14xx *pll, unsigned long rate) > > @@ -436,3 +440,4 @@ struct clk_hw *imx_dev_clk_hw_pll14xx(struct > device *dev, const char *name, > > > > return hw; > > } > > +EXPORT_SYMBOL_GPL(imx_dev_clk_hw_pll14xx); > > diff --git a/drivers/clk/imx/clk-sscg-pll.c b/drivers/clk/imx/clk-sscg-pll.c > > index 773d8a5..9d6cdff 100644 > > --- a/drivers/clk/imx/clk-sscg-pll.c > > +++ b/drivers/clk/imx/clk-sscg-pll.c > > @@ -10,6 +10,7 @@ > > > > #include <linux/clk-provider.h> > > #include <linux/err.h> > > +#include <linux/export.h> > > #include <linux/io.h> > > #include <linux/iopoll.h> > > #include <linux/slab.h> > > @@ -537,3 +538,4 @@ struct clk_hw *imx_clk_hw_sscg_pll(const char > *name, > > > > return hw; > > } > > +EXPORT_SYMBOL_GPL(imx_clk_hw_sscg_pll); > > diff --git a/drivers/clk/imx/clk.c b/drivers/clk/imx/clk.c > > index 87ab8db..6f2a94d 100644 > > --- a/drivers/clk/imx/clk.c > > +++ b/drivers/clk/imx/clk.c > > @@ -3,6 +3,7 @@ > > #include <linux/clk-provider.h> > > #include <linux/err.h> > > #include <linux/io.h> > > +#include <linux/module.h> > > #include <linux/of.h> > > #include <linux/slab.h> > > #include <linux/spinlock.h> > > @@ -13,6 +14,7 @@ > > #define CCDR_MMDC_CH1_MASK BIT(16) > > > > DEFINE_SPINLOCK(imx_ccm_lock); > > +EXPORT_SYMBOL_GPL(imx_ccm_lock); > > > > void imx_unregister_clocks(struct clk *clks[], unsigned int count) > > { > > @@ -29,8 +31,9 @@ void imx_unregister_hw_clocks(struct clk_hw *hws[], > unsigned int count) > > for (i = 0; i < count; i++) > > clk_hw_unregister(hws[i]); > > } > > +EXPORT_SYMBOL_GPL(imx_unregister_hw_clocks); > > > > -void __init imx_mmdc_mask_handshake(void __iomem *ccm_base, > > +void imx_mmdc_mask_handshake(void __iomem *ccm_base, > > unsigned int chn) > > { > > unsigned int reg; > > @@ -59,8 +62,9 @@ void imx_check_clk_hws(struct clk_hw *clks[], > unsigned int count) > > pr_err("i.MX clk %u: register failed with %ld\n", > > i, PTR_ERR(clks[i])); > > } > > +EXPORT_SYMBOL_GPL(imx_check_clk_hws); > > > > -static struct clk * __init imx_obtain_fixed_clock_from_dt(const char *name) > > +static struct clk *imx_obtain_fixed_clock_from_dt(const char *name) > > { > > struct of_phandle_args phandle; > > struct clk *clk = ERR_PTR(-ENODEV); > > @@ -80,7 +84,7 @@ static struct clk * __init > imx_obtain_fixed_clock_from_dt(const char *name) > > return clk; > > } > > > > -struct clk * __init imx_obtain_fixed_clock( > > +struct clk *imx_obtain_fixed_clock( > > const char *name, unsigned long rate) > > { > > struct clk *clk; > > @@ -91,7 +95,7 @@ struct clk * __init imx_obtain_fixed_clock( > > return clk; > > } > > > > -struct clk_hw * __init imx_obtain_fixed_clock_hw( > > +struct clk_hw *imx_obtain_fixed_clock_hw( > > const char *name, unsigned long rate) > > { > > struct clk *clk; > > @@ -113,6 +117,7 @@ struct clk_hw * imx_obtain_fixed_clk_hw(struct > device_node *np, > > > > return __clk_get_hw(clk); > > } > > +EXPORT_SYMBOL_GPL(imx_obtain_fixed_clk_hw); > > > > /* > > * This fixups the register CCM_CSCMR1 write value. > > @@ -143,16 +148,18 @@ void imx_cscmr1_fixup(u32 *val) > > static int imx_keep_uart_clocks; > > static struct clk ** const *imx_uart_clocks; > > > > -static int __init imx_keep_uart_clocks_param(char *str) > > +static int __maybe_unused imx_keep_uart_clocks_param(char *str) > > { > > imx_keep_uart_clocks = 1; > > > > return 0; > > } > > +#ifndef MODULE > > __setup_param("earlycon", imx_keep_uart_earlycon, > > imx_keep_uart_clocks_param, 0); > > __setup_param("earlyprintk", imx_keep_uart_earlyprintk, > > imx_keep_uart_clocks_param, 0); > > I feel not only the __setup_param, the whole logic of keep_uart_clocks > are not needed for Module case. Is it true? Yes, but the 'keep_uart_clocks' is false by default and the function imx_keep_uart_clocks_param() already has '__maybe_unused', it does NOT impact anything if it is for module build, so I did NOT add the #ifndef check for them, just to keep code easy and clean. Thanks, Anson
On Thu, Jul 2, 2020 at 11:26 AM Anson Huang <anson.huang@nxp.com> wrote: [...] > > > @@ -143,16 +148,18 @@ void imx_cscmr1_fixup(u32 *val) > > > static int imx_keep_uart_clocks; > > > static struct clk ** const *imx_uart_clocks; > > > > > > -static int __init imx_keep_uart_clocks_param(char *str) > > > +static int __maybe_unused imx_keep_uart_clocks_param(char *str) > > > { > > > imx_keep_uart_clocks = 1; > > > > > > return 0; > > > } > > > +#ifndef MODULE > > > __setup_param("earlycon", imx_keep_uart_earlycon, > > > imx_keep_uart_clocks_param, 0); > > > __setup_param("earlyprintk", imx_keep_uart_earlyprintk, > > > imx_keep_uart_clocks_param, 0); > > > > I feel not only the __setup_param, the whole logic of keep_uart_clocks > > are not needed for Module case. Is it true? > > Yes, but the 'keep_uart_clocks' is false by default and the function imx_keep_uart_clocks_param() > already has '__maybe_unused', it does NOT impact anything if it is for module build, so I did NOT > add the #ifndef check for them, just to keep code easy and clean. > IMHO do not compile them is a more easy and clean way. Then users don't have to look into the code logic which is meaingless for Module case. BTW, it really does not make any sense to only condionally compile __setup_parm() but left the param functions definition to be handled by __maybe_unnused. They're together part of code, aren't they? Regards Aisheng Regards Aisheng > Thanks, > Anson >
> Subject: Re: [PATCH V4 3/5] clk: imx: Support building i.MX common clock > driver as module > > On Thu, Jul 2, 2020 at 11:26 AM Anson Huang <anson.huang@nxp.com> > wrote: > [...] > > > > @@ -143,16 +148,18 @@ void imx_cscmr1_fixup(u32 *val) static int > > > > imx_keep_uart_clocks; static struct clk ** const > > > > *imx_uart_clocks; > > > > > > > > -static int __init imx_keep_uart_clocks_param(char *str) > > > > +static int __maybe_unused imx_keep_uart_clocks_param(char *str) > > > > { > > > > imx_keep_uart_clocks = 1; > > > > > > > > return 0; > > > > } > > > > +#ifndef MODULE > > > > __setup_param("earlycon", imx_keep_uart_earlycon, > > > > imx_keep_uart_clocks_param, 0); > > > > __setup_param("earlyprintk", imx_keep_uart_earlyprintk, > > > > imx_keep_uart_clocks_param, 0); > > > > > > I feel not only the __setup_param, the whole logic of > > > keep_uart_clocks are not needed for Module case. Is it true? > > > > Yes, but the 'keep_uart_clocks' is false by default and the function > > imx_keep_uart_clocks_param() already has '__maybe_unused', it does NOT > > impact anything if it is for module build, so I did NOT add the #ifndef check > for them, just to keep code easy and clean. > > > > IMHO do not compile them is a more easy and clean way. Then users don't > have to look into the code logic which is meaingless for Module case. > > BTW, it really does not make any sense to only condionally compile > __setup_parm() but left > the param functions definition to be handled by __maybe_unnused. > They're together part of code, aren't they? I am fine of adding the '#ifndef MODULE' to imx_clk_disable_uart() and imx_keep_uart_clocks_param() as well in next patch series. Others like ' imx_keep_uart_clocks ' and imx_register_uart_clocks() need to be kept always built, since they are used by each clock driver no matter built-in or module build. So that means I have to add another 'ifndef MODULE' or I need to adjust some code sequence to make those code can be built-out in same block and just use single 'ifndef MODULE', I think adjust the code sequence should be better, will go with this way. Anson
On Thu, Jul 2, 2020 at 2:11 PM Anson Huang <anson.huang@nxp.com> wrote: > > > Subject: Re: [PATCH V4 3/5] clk: imx: Support building i.MX common clock > > driver as module > > > > On Thu, Jul 2, 2020 at 11:26 AM Anson Huang <anson.huang@nxp.com> > > wrote: > > [...] > > > > > @@ -143,16 +148,18 @@ void imx_cscmr1_fixup(u32 *val) static int > > > > > imx_keep_uart_clocks; static struct clk ** const > > > > > *imx_uart_clocks; > > > > > > > > > > -static int __init imx_keep_uart_clocks_param(char *str) > > > > > +static int __maybe_unused imx_keep_uart_clocks_param(char *str) > > > > > { > > > > > imx_keep_uart_clocks = 1; > > > > > > > > > > return 0; > > > > > } > > > > > +#ifndef MODULE > > > > > __setup_param("earlycon", imx_keep_uart_earlycon, > > > > > imx_keep_uart_clocks_param, 0); > > > > > __setup_param("earlyprintk", imx_keep_uart_earlyprintk, > > > > > imx_keep_uart_clocks_param, 0); > > > > > > > > I feel not only the __setup_param, the whole logic of > > > > keep_uart_clocks are not needed for Module case. Is it true? > > > > > > Yes, but the 'keep_uart_clocks' is false by default and the function > > > imx_keep_uart_clocks_param() already has '__maybe_unused', it does NOT > > > impact anything if it is for module build, so I did NOT add the #ifndef check > > for them, just to keep code easy and clean. > > > > > > > IMHO do not compile them is a more easy and clean way. Then users don't > > have to look into the code logic which is meaingless for Module case. > > > > BTW, it really does not make any sense to only condionally compile > > __setup_parm() but left > > the param functions definition to be handled by __maybe_unnused. > > They're together part of code, aren't they? > > I am fine of adding the '#ifndef MODULE' to imx_clk_disable_uart() and imx_keep_uart_clocks_param() > as well in next patch series. Others like ' imx_keep_uart_clocks ' and imx_register_uart_clocks() need to > be kept always built, since they are used by each clock driver no matter built-in or module build. > > So that means I have to add another 'ifndef MODULE' or I need to adjust some code sequence to make > those code can be built-out in same block and just use single 'ifndef MODULE', I think adjust the code > sequence should be better, will go with this way. What if we condionally compile it in clk.h? Will that be easiser? Regards Aisheng > > Anson
> Subject: Re: [PATCH V4 3/5] clk: imx: Support building i.MX common clock > driver as module > > On Thu, Jul 2, 2020 at 2:11 PM Anson Huang <anson.huang@nxp.com> wrote: > > > > > Subject: Re: [PATCH V4 3/5] clk: imx: Support building i.MX common > > > clock driver as module > > > > > > On Thu, Jul 2, 2020 at 11:26 AM Anson Huang <anson.huang@nxp.com> > > > wrote: > > > [...] > > > > > > @@ -143,16 +148,18 @@ void imx_cscmr1_fixup(u32 *val) static > > > > > > int imx_keep_uart_clocks; static struct clk ** const > > > > > > *imx_uart_clocks; > > > > > > > > > > > > -static int __init imx_keep_uart_clocks_param(char *str) > > > > > > +static int __maybe_unused imx_keep_uart_clocks_param(char > > > > > > +*str) > > > > > > { > > > > > > imx_keep_uart_clocks = 1; > > > > > > > > > > > > return 0; > > > > > > } > > > > > > +#ifndef MODULE > > > > > > __setup_param("earlycon", imx_keep_uart_earlycon, > > > > > > imx_keep_uart_clocks_param, 0); > > > > > > __setup_param("earlyprintk", imx_keep_uart_earlyprintk, > > > > > > imx_keep_uart_clocks_param, 0); > > > > > > > > > > I feel not only the __setup_param, the whole logic of > > > > > keep_uart_clocks are not needed for Module case. Is it true? > > > > > > > > Yes, but the 'keep_uart_clocks' is false by default and the > > > > function > > > > imx_keep_uart_clocks_param() already has '__maybe_unused', it does > > > > NOT impact anything if it is for module build, so I did NOT add > > > > the #ifndef check > > > for them, just to keep code easy and clean. > > > > > > > > > > IMHO do not compile them is a more easy and clean way. Then users > > > don't have to look into the code logic which is meaingless for Module case. > > > > > > BTW, it really does not make any sense to only condionally compile > > > __setup_parm() but left > > > the param functions definition to be handled by __maybe_unnused. > > > They're together part of code, aren't they? > > > > I am fine of adding the '#ifndef MODULE' to imx_clk_disable_uart() and > > imx_keep_uart_clocks_param() as well in next patch series. Others like > > ' imx_keep_uart_clocks ' and imx_register_uart_clocks() need to be kept > always built, since they are used by each clock driver no matter built-in or > module build. > > > > So that means I have to add another 'ifndef MODULE' or I need to > > adjust some code sequence to make those code can be built-out in same > > block and just use single 'ifndef MODULE', I think adjust the code sequence > should be better, will go with this way. > > What if we condionally compile it in clk.h? Will that be easiser? Adjust the function sequence looks like NOT complicated, just need to exchange the imx_register_uart_clocks() and imx_clk_disable_uart(), then I can use single '#ifndef MODULE', will go with this way in V5. Anson
On Thu, Jul 2, 2020 at 8:40 AM Dong Aisheng <dongas86@gmail.com> wrote: > On Thu, Jul 2, 2020 at 2:11 PM Anson Huang <anson.huang@nxp.com> wrote: > > > Subject: Re: [PATCH V4 3/5] clk: imx: Support building i.MX common clock > > > > I am fine of adding the '#ifndef MODULE' to imx_clk_disable_uart() and imx_keep_uart_clocks_param() > > as well in next patch series. Others like ' imx_keep_uart_clocks ' and imx_register_uart_clocks() need to > > be kept always built, since they are used by each clock driver no matter built-in or module build. > > > > So that means I have to add another 'ifndef MODULE' or I need to adjust some code sequence to make > > those code can be built-out in same block and just use single 'ifndef MODULE', I think adjust the code > > sequence should be better, will go with this way. > > What if we condionally compile it in clk.h? Will that be easiser? Yes, that's what I expected to see in v4 after the previous discussion. If imx_register_uart_clocks() is an empty inline function, then the arrays passed to it are unused and also get dropped by the compiler. The question is whether the #ifdef check in the header to test for MODULE (only calling it if this particular soc has a built-in clk driver, which is sufficient) or for IS_MODULE(CONFIG_MXC_CLK) (call it if _any_ clk driver is built-in and the function exists, which leaves extra code in the driver but is a more conventional check). Arnd
Hi, Arnd > Subject: Re: [PATCH V4 3/5] clk: imx: Support building i.MX common clock > driver as module > > On Thu, Jul 2, 2020 at 8:40 AM Dong Aisheng <dongas86@gmail.com> wrote: > > On Thu, Jul 2, 2020 at 2:11 PM Anson Huang <anson.huang@nxp.com> > wrote: > > > > Subject: Re: [PATCH V4 3/5] clk: imx: Support building i.MX common > > > > clock > > > > > > I am fine of adding the '#ifndef MODULE' to imx_clk_disable_uart() > > > and imx_keep_uart_clocks_param() as well in next patch series. > > > Others like ' imx_keep_uart_clocks ' and imx_register_uart_clocks() need to > be kept always built, since they are used by each clock driver no matter > built-in or module build. > > > > > > So that means I have to add another 'ifndef MODULE' or I need to > > > adjust some code sequence to make those code can be built-out in > > > same block and just use single 'ifndef MODULE', I think adjust the code > sequence should be better, will go with this way. > > > > What if we condionally compile it in clk.h? Will that be easiser? > > Yes, that's what I expected to see in v4 after the previous discussion. If > imx_register_uart_clocks() is an empty inline function, then the arrays passed > to it are unused and also get dropped by the compiler. > > The question is whether the #ifdef check in the header to test for MODULE > (only calling it if this particular soc has a built-in clk driver, which is sufficient) > or for IS_MODULE(CONFIG_MXC_CLK) (call it if _any_ clk driver is built-in and > the function exists, which leaves extra code in the driver but is a more > conventional check). > So you prefer to add an empty inline function for imx_register_uart_clocks() with check of MODULE build? Even with this, we still need to add MODULE build check to whole block of this earlycon uart clock handler in imx/clk.c. Thanks, Anson
On Thu, Jul 2, 2020 at 9:12 AM Anson Huang <anson.huang@nxp.com> wrote: > > > > The question is whether the #ifdef check in the header to test for MODULE > > (only calling it if this particular soc has a built-in clk driver, which is sufficient) > > or for IS_MODULE(CONFIG_MXC_CLK) (call it if _any_ clk driver is built-in and > > the function exists, which leaves extra code in the driver but is a more > > conventional check). > > > > So you prefer to add an empty inline function for imx_register_uart_clocks() with check > of MODULE build? Yes, I want the empty inline stub, but either symbol check would work > Even with this, we still need to add MODULE build check to whole block > of this earlycon uart clock handler in imx/clk.c. Correct. Arnd
diff --git a/drivers/clk/imx/Kconfig b/drivers/clk/imx/Kconfig index 09fc8ad..f6ddf76 100644 --- a/drivers/clk/imx/Kconfig +++ b/drivers/clk/imx/Kconfig @@ -1,8 +1,8 @@ # SPDX-License-Identifier: GPL-2.0 # common clock support for NXP i.MX SoC family. config MXC_CLK - bool - def_bool ARCH_MXC + tristate "IMX clock" + depends on ARCH_MXC config MXC_CLK_SCU bool @@ -101,24 +101,28 @@ config CLK_VF610 config CLK_IMX8MM bool "IMX8MM CCM Clock Driver" depends on ARCH_MXC + select MXC_CLK help Build the driver for i.MX8MM CCM Clock Driver config CLK_IMX8MN bool "IMX8MN CCM Clock Driver" depends on ARCH_MXC + select MXC_CLK help Build the driver for i.MX8MN CCM Clock Driver config CLK_IMX8MP bool "IMX8MP CCM Clock Driver" depends on ARCH_MXC + select MXC_CLK help Build the driver for i.MX8MP CCM Clock Driver config CLK_IMX8MQ bool "IMX8MQ CCM Clock Driver" depends on ARCH_MXC + select MXC_CLK help Build the driver for i.MX8MQ CCM Clock Driver diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile index 394ade7..17f5d12 100644 --- a/drivers/clk/imx/Makefile +++ b/drivers/clk/imx/Makefile @@ -1,25 +1,25 @@ # SPDX-License-Identifier: GPL-2.0 -obj-$(CONFIG_MXC_CLK) += \ - clk.o \ - clk-busy.o \ - clk-composite-8m.o \ - clk-cpu.o \ - clk-composite-7ulp.o \ - clk-divider-gate.o \ - clk-fixup-div.o \ - clk-fixup-mux.o \ - clk-frac-pll.o \ - clk-gate-exclusive.o \ - clk-gate2.o \ - clk-pfd.o \ - clk-pfdv2.o \ - clk-pllv1.o \ - clk-pllv2.o \ - clk-pllv3.o \ - clk-pllv4.o \ - clk-sscg-pll.o \ - clk-pll14xx.o +mxc-clk-objs += clk.o +mxc-clk-objs += clk-busy.o +mxc-clk-objs += clk-composite-7ulp.o +mxc-clk-objs += clk-composite-8m.o +mxc-clk-objs += clk-cpu.o +mxc-clk-objs += clk-divider-gate.o +mxc-clk-objs += clk-fixup-div.o +mxc-clk-objs += clk-fixup-mux.o +mxc-clk-objs += clk-frac-pll.o +mxc-clk-objs += clk-gate2.o +mxc-clk-objs += clk-gate-exclusive.o +mxc-clk-objs += clk-pfd.o +mxc-clk-objs += clk-pfdv2.o +mxc-clk-objs += clk-pllv1.o +mxc-clk-objs += clk-pllv2.o +mxc-clk-objs += clk-pllv3.o +mxc-clk-objs += clk-pllv4.o +mxc-clk-objs += clk-pll14xx.o +mxc-clk-objs += clk-sscg-pll.o +obj-$(CONFIG_MXC_CLK) += mxc-clk.o obj-$(CONFIG_MXC_CLK_SCU) += \ clk-scu.o \ diff --git a/drivers/clk/imx/clk-composite-8m.c b/drivers/clk/imx/clk-composite-8m.c index d2b5af8..78fb7e5 100644 --- a/drivers/clk/imx/clk-composite-8m.c +++ b/drivers/clk/imx/clk-composite-8m.c @@ -5,6 +5,7 @@ #include <linux/clk-provider.h> #include <linux/errno.h> +#include <linux/export.h> #include <linux/io.h> #include <linux/slab.h> @@ -243,3 +244,4 @@ struct clk_hw *imx8m_clk_hw_composite_flags(const char *name, kfree(mux); return ERR_CAST(hw); } +EXPORT_SYMBOL_GPL(imx8m_clk_hw_composite_flags); diff --git a/drivers/clk/imx/clk-cpu.c b/drivers/clk/imx/clk-cpu.c index cb182be..cb6ca4c 100644 --- a/drivers/clk/imx/clk-cpu.c +++ b/drivers/clk/imx/clk-cpu.c @@ -5,6 +5,7 @@ #include <linux/clk.h> #include <linux/clk-provider.h> +#include <linux/export.h> #include <linux/slab.h> #include "clk.h" @@ -104,3 +105,4 @@ struct clk_hw *imx_clk_hw_cpu(const char *name, const char *parent_name, return hw; } +EXPORT_SYMBOL_GPL(imx_clk_hw_cpu); diff --git a/drivers/clk/imx/clk-frac-pll.c b/drivers/clk/imx/clk-frac-pll.c index 101e0a3..c703056 100644 --- a/drivers/clk/imx/clk-frac-pll.c +++ b/drivers/clk/imx/clk-frac-pll.c @@ -10,6 +10,7 @@ #include <linux/clk-provider.h> #include <linux/err.h> +#include <linux/export.h> #include <linux/io.h> #include <linux/iopoll.h> #include <linux/slab.h> @@ -233,3 +234,4 @@ struct clk_hw *imx_clk_hw_frac_pll(const char *name, return hw; } +EXPORT_SYMBOL_GPL(imx_clk_hw_frac_pll); diff --git a/drivers/clk/imx/clk-gate2.c b/drivers/clk/imx/clk-gate2.c index b87ab3c..512f675 100644 --- a/drivers/clk/imx/clk-gate2.c +++ b/drivers/clk/imx/clk-gate2.c @@ -7,6 +7,7 @@ */ #include <linux/clk-provider.h> +#include <linux/export.h> #include <linux/module.h> #include <linux/slab.h> #include <linux/io.h> @@ -177,3 +178,4 @@ struct clk_hw *clk_hw_register_gate2(struct device *dev, const char *name, return hw; } +EXPORT_SYMBOL_GPL(clk_hw_register_gate2); diff --git a/drivers/clk/imx/clk-pll14xx.c b/drivers/clk/imx/clk-pll14xx.c index f9eb189..f5c3e7e 100644 --- a/drivers/clk/imx/clk-pll14xx.c +++ b/drivers/clk/imx/clk-pll14xx.c @@ -6,6 +6,7 @@ #include <linux/bitops.h> #include <linux/clk-provider.h> #include <linux/err.h> +#include <linux/export.h> #include <linux/io.h> #include <linux/iopoll.h> #include <linux/slab.h> @@ -68,6 +69,7 @@ struct imx_pll14xx_clk imx_1443x_pll = { .rate_table = imx_pll1443x_tbl, .rate_count = ARRAY_SIZE(imx_pll1443x_tbl), }; +EXPORT_SYMBOL_GPL(imx_1443x_pll); struct imx_pll14xx_clk imx_1443x_dram_pll = { .type = PLL_1443X, @@ -75,12 +77,14 @@ struct imx_pll14xx_clk imx_1443x_dram_pll = { .rate_count = ARRAY_SIZE(imx_pll1443x_tbl), .flags = CLK_GET_RATE_NOCACHE, }; +EXPORT_SYMBOL_GPL(imx_1443x_dram_pll); struct imx_pll14xx_clk imx_1416x_pll = { .type = PLL_1416X, .rate_table = imx_pll1416x_tbl, .rate_count = ARRAY_SIZE(imx_pll1416x_tbl), }; +EXPORT_SYMBOL_GPL(imx_1416x_pll); static const struct imx_pll14xx_rate_table *imx_get_pll_settings( struct clk_pll14xx *pll, unsigned long rate) @@ -436,3 +440,4 @@ struct clk_hw *imx_dev_clk_hw_pll14xx(struct device *dev, const char *name, return hw; } +EXPORT_SYMBOL_GPL(imx_dev_clk_hw_pll14xx); diff --git a/drivers/clk/imx/clk-sscg-pll.c b/drivers/clk/imx/clk-sscg-pll.c index 773d8a5..9d6cdff 100644 --- a/drivers/clk/imx/clk-sscg-pll.c +++ b/drivers/clk/imx/clk-sscg-pll.c @@ -10,6 +10,7 @@ #include <linux/clk-provider.h> #include <linux/err.h> +#include <linux/export.h> #include <linux/io.h> #include <linux/iopoll.h> #include <linux/slab.h> @@ -537,3 +538,4 @@ struct clk_hw *imx_clk_hw_sscg_pll(const char *name, return hw; } +EXPORT_SYMBOL_GPL(imx_clk_hw_sscg_pll); diff --git a/drivers/clk/imx/clk.c b/drivers/clk/imx/clk.c index 87ab8db..6f2a94d 100644 --- a/drivers/clk/imx/clk.c +++ b/drivers/clk/imx/clk.c @@ -3,6 +3,7 @@ #include <linux/clk-provider.h> #include <linux/err.h> #include <linux/io.h> +#include <linux/module.h> #include <linux/of.h> #include <linux/slab.h> #include <linux/spinlock.h> @@ -13,6 +14,7 @@ #define CCDR_MMDC_CH1_MASK BIT(16) DEFINE_SPINLOCK(imx_ccm_lock); +EXPORT_SYMBOL_GPL(imx_ccm_lock); void imx_unregister_clocks(struct clk *clks[], unsigned int count) { @@ -29,8 +31,9 @@ void imx_unregister_hw_clocks(struct clk_hw *hws[], unsigned int count) for (i = 0; i < count; i++) clk_hw_unregister(hws[i]); } +EXPORT_SYMBOL_GPL(imx_unregister_hw_clocks); -void __init imx_mmdc_mask_handshake(void __iomem *ccm_base, +void imx_mmdc_mask_handshake(void __iomem *ccm_base, unsigned int chn) { unsigned int reg; @@ -59,8 +62,9 @@ void imx_check_clk_hws(struct clk_hw *clks[], unsigned int count) pr_err("i.MX clk %u: register failed with %ld\n", i, PTR_ERR(clks[i])); } +EXPORT_SYMBOL_GPL(imx_check_clk_hws); -static struct clk * __init imx_obtain_fixed_clock_from_dt(const char *name) +static struct clk *imx_obtain_fixed_clock_from_dt(const char *name) { struct of_phandle_args phandle; struct clk *clk = ERR_PTR(-ENODEV); @@ -80,7 +84,7 @@ static struct clk * __init imx_obtain_fixed_clock_from_dt(const char *name) return clk; } -struct clk * __init imx_obtain_fixed_clock( +struct clk *imx_obtain_fixed_clock( const char *name, unsigned long rate) { struct clk *clk; @@ -91,7 +95,7 @@ struct clk * __init imx_obtain_fixed_clock( return clk; } -struct clk_hw * __init imx_obtain_fixed_clock_hw( +struct clk_hw *imx_obtain_fixed_clock_hw( const char *name, unsigned long rate) { struct clk *clk; @@ -113,6 +117,7 @@ struct clk_hw * imx_obtain_fixed_clk_hw(struct device_node *np, return __clk_get_hw(clk); } +EXPORT_SYMBOL_GPL(imx_obtain_fixed_clk_hw); /* * This fixups the register CCM_CSCMR1 write value. @@ -143,16 +148,18 @@ void imx_cscmr1_fixup(u32 *val) static int imx_keep_uart_clocks; static struct clk ** const *imx_uart_clocks; -static int __init imx_keep_uart_clocks_param(char *str) +static int __maybe_unused imx_keep_uart_clocks_param(char *str) { imx_keep_uart_clocks = 1; return 0; } +#ifndef MODULE __setup_param("earlycon", imx_keep_uart_earlycon, imx_keep_uart_clocks_param, 0); __setup_param("earlyprintk", imx_keep_uart_earlyprintk, imx_keep_uart_clocks_param, 0); +#endif void imx_register_uart_clocks(struct clk ** const clks[]) { @@ -164,8 +171,9 @@ void imx_register_uart_clocks(struct clk ** const clks[]) clk_prepare_enable(*imx_uart_clocks[i]); } } +EXPORT_SYMBOL_GPL(imx_register_uart_clocks); -static int __init imx_clk_disable_uart(void) +static int imx_clk_disable_uart(void) { if (imx_keep_uart_clocks && imx_uart_clocks) { int i; @@ -177,3 +185,5 @@ static int __init imx_clk_disable_uart(void) return 0; } late_initcall_sync(imx_clk_disable_uart); + +MODULE_LICENSE("GPL v2");
There are more and more requirements of building SoC specific drivers as modules, add support for building i.MX common clock driver as module to meet the requirement. Signed-off-by: Anson Huang <Anson.Huang@nxp.com> --- Changes since V3: - ONLY include __setup_param() build for built-in, module build no need to have it. --- drivers/clk/imx/Kconfig | 8 ++++++-- drivers/clk/imx/Makefile | 40 +++++++++++++++++++------------------- drivers/clk/imx/clk-composite-8m.c | 2 ++ drivers/clk/imx/clk-cpu.c | 2 ++ drivers/clk/imx/clk-frac-pll.c | 2 ++ drivers/clk/imx/clk-gate2.c | 2 ++ drivers/clk/imx/clk-pll14xx.c | 5 +++++ drivers/clk/imx/clk-sscg-pll.c | 2 ++ drivers/clk/imx/clk.c | 22 +++++++++++++++------ 9 files changed, 57 insertions(+), 28 deletions(-)