diff -drupN a/drivers/clk/ingenic/clk-t40.c b/drivers/clk/ingenic/clk-t40.c --- a/drivers/clk/ingenic/clk-t40.c 1970-01-01 03:00:00.000000000 +0300 +++ b/drivers/clk/ingenic/clk-t40.c 2022-06-09 05:02:28.000000000 +0300 @@ -0,0 +1,365 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "clk.h" + +#define CLK_FLG_ENABLE BIT(1) +static struct ingenic_clk_provider *ctx; + + +/******************************************************************************* + * FIXED CLK + ********************************************************************************/ +static struct ingenic_fixed_rate_clock t40_fixed_rate_ext_clks[] __initdata = { + FRATE(CLK_EXT, "ext", NULL, CLK_IS_ROOT, 24000000), + FRATE(CLK_RTC_EXT, "rtc_ext", NULL, CLK_IS_ROOT, 32768), +}; + + + +/******************************************************************************* + * PLL + ********************************************************************************/ + +static struct ingenic_pll_rate_table t40_pll_rate_table[] = { + PLL_RATE(1800000000, 150, 1, 2, 1), + PLL_RATE(1608000000, 134, 1, 2, 1), + PLL_RATE(1500000000, 125, 1, 2, 1), + PLL_RATE(1404000000, 117, 1, 2, 1), + PLL_RATE(1400000000, 350, 3, 2, 1), + PLL_RATE(1392000000, 116, 1, 2, 1), + PLL_RATE(1308000000, 109, 1, 2, 1), + PLL_RATE(1296000000, 108, 1, 2, 1), + PLL_RATE(1200000000, 100, 1, 2, 1), + PLL_RATE(1104000000, 92, 1, 2, 1), + PLL_RATE(1100000000, 275, 2, 3, 1), + PLL_RATE(1080000000, 90, 1, 2, 1), + PLL_RATE(1008000000, 84, 1, 2, 1), + PLL_RATE(1000000000, 125, 1, 3, 1), + PLL_RATE(900000000, 75, 1, 2, 1), + PLL_RATE(891000000, 297, 4, 2, 1), + PLL_RATE(864000000, 72, 1, 2, 1), + PLL_RATE(600000000, 75, 1, 3, 1), +}; + + + +/*PLL HWDESC*/ +static struct ingenic_pll_hwdesc apll_hwdesc = \ + PLL_DESC(CPM_CPAPCR, 20, 12, 14, 6, 11, 3, 8, 3, 3, 0, 2); + +static struct ingenic_pll_hwdesc mpll_hwdesc = \ + PLL_DESC(CPM_CPMPCR, 20, 12, 14, 6, 11, 3, 8, 3, 3, 0, 2); + +static struct ingenic_pll_hwdesc vpll_hwdesc = \ + PLL_DESC(CPM_CPVPCR, 20, 12, 14, 6, 11, 3, 8, 3, 3, 0, 2); + +static struct ingenic_pll_hwdesc epll_hwdesc = \ + PLL_DESC(CPM_CPEPCR, 20, 12, 14, 6, 11, 3, 8, 3, 3, 0, 2); + + + +static struct ingenic_pll_clock t40_pll_clks[] __initdata = { + PLL(CLK_PLL_APLL, "apll", "ext", &apll_hwdesc, t40_pll_rate_table), + PLL(CLK_PLL_MPLL, "mpll", "ext", &mpll_hwdesc, t40_pll_rate_table), + PLL(CLK_PLL_VPLL, "vpll", "ext", &vpll_hwdesc, t40_pll_rate_table), + PLL(CLK_PLL_EPLL, "epll", "ext", &epll_hwdesc, t40_pll_rate_table), +}; + + +/******************************************************************************* + * MUX + ********************************************************************************/ +PNAME(mux_table_0) = {"stop", "ext", "apll"}; +PNAME(mux_table_1) = {"stop", "sclka", "mpll"}; +PNAME(mux_table_2) = {"sclka", "mpll", "vpll", "epll"}; +PNAME(mux_table_3) = {"sclka", "mpll", "epll", "ext"}; +PNAME(mux_table_4) = {"sclka", "vpll", "ext"}; +PNAME(mux_table_5) = {"mux_ahb2", "ext"}; + +static unsigned int ingenic_mux_table[] = {0, 1, 2, 3}; + + +static struct ingenic_mux_clock t40_mux_clks[] __initdata = { + MUX(CLK_MUX_SCLKA, "sclka", ingenic_mux_table, mux_table_0, CPM_CPCCR, 30, 2, 0), + MUX(CLK_MUX_CPU_L2C, "mux_cpu_l2c", ingenic_mux_table, mux_table_1, CPM_CPCCR, 28, 2, 0), + MUX(CLK_MUX_AHB0, "mux_ahb0", ingenic_mux_table, mux_table_1, CPM_CPCCR, 26, 2, 0), + MUX(CLK_MUX_AHB2, "mux_ahb2", ingenic_mux_table, mux_table_1, CPM_CPCCR, 24, 2, 0), + + MUX(CLK_MUX_DDR, "mux_ddr", ingenic_mux_table, mux_table_1, CPM_DDRCDR, 30, 2, 0), + MUX(CLK_MUX_EL150, "mux_el150", ingenic_mux_table, mux_table_2, CPM_EL150CDR, 30, 2, 0), + MUX(CLK_MUX_RSA, "mux_rsa", ingenic_mux_table, mux_table_2, CPM_RSACDR, 30, 2, 0), + MUX(CLK_MUX_MACPHY, "mux_macphy", ingenic_mux_table, mux_table_2, CPM_MACCDR, 30, 2, 0), + MUX(CLK_MUX_SFC, "mux_sfc", ingenic_mux_table, mux_table_2, CPM_SFCCDR, 30, 2, 0), + MUX(CLK_MUX_LCD, "mux_lcd", ingenic_mux_table, mux_table_2, CPM_LPCDR, 30, 2, 0), + MUX(CLK_MUX_MSC0, "mux_msc0", ingenic_mux_table, mux_table_2, CPM_MSC0CDR, 30, 2, 0), + MUX(CLK_MUX_MSC1, "mux_msc1", ingenic_mux_table, mux_table_2, CPM_MSC1CDR, 30, 2, 0), + MUX(CLK_MUX_SSI, "mux_ssi", ingenic_mux_table, mux_table_2, CPM_SSICDR, 30, 2, 0), + MUX(CLK_MUX_I2ST, "mux_i2st", ingenic_mux_table, mux_table_2, CPM_I2STCDR, 30, 2, 0), + MUX(CLK_MUX_ISP, "mux_isp", ingenic_mux_table, mux_table_2, CPM_ISPCDR, 30, 2, 0), + MUX(CLK_MUX_I2SR, "mux_i2sr", ingenic_mux_table, mux_table_2, CPM_I2STCDR, 30, 2, 0), + MUX(CLK_MUX_CIM0, "mux_cim0", ingenic_mux_table, mux_table_2, CPM_CIM0CDR, 30, 2, 0), + MUX(CLK_MUX_CIM1, "mux_cim1", ingenic_mux_table, mux_table_2, CPM_CIM1CDR, 30, 2, 0), + MUX(CLK_MUX_CIM2, "mux_cim2", ingenic_mux_table, mux_table_2, CPM_CIM2CDR, 30, 2, 0), + MUX(CLK_MUX_BSCALER, "mux_bscaler", ingenic_mux_table, mux_table_2, CPM_BSCALERCDR, 30, 2, 0), + MUX(CLK_MUX_BT0, "mux_bt0", ingenic_mux_table, mux_table_2, CPM_BT0CDR, 30, 2, 0), + +}; + +/******************************************************************************* + * DIV BUS + ********************************************************************************/ + +static struct ingenic_bus_clock t40_bus_div_clks[] __initdata = { + BUS_DIV(CLK_DIV_CPU, "div_cpu", "mux_cpu_l2c", CPM_CPCCR, 0, 4, 0, 0, CPM_CPCSR, 0, 22, BUS_DIV_SELF), + BUS_DIV(CLK_DIV_L2C, "div_l2c", "mux_cpu_l2c", CPM_CPCCR, 4, 4, 0, 0, CPM_CPCSR, 0, 22, BUS_DIV_SELF), + BUS_DIV(CLK_DIV_AHB0, "div_ahb0", "mux_ahb0", CPM_CPCCR, 8, 4, 0, 0, CPM_CPCSR, 1, 21, BUS_DIV_SELF), + BUS_DIV(CLK_DIV_AHB2, "div_ahb2", "mux_ahb2", CPM_CPCCR, 12, 4, 0, 0, CPM_CPCSR, 2, 20, BUS_DIV_SELF), + BUS_DIV(CLK_DIV_APB, "div_apb", "mux_ahb2", CPM_CPCCR, 16, 4, 0, 0, CPM_CPCSR, 2, 20, BUS_DIV_SELF), + BUS_DIV(CLK_DIV_CPU_L2C_X1, "div_cpu_l2c_x1", "mux_cpu_l2c", CPM_CPCCR, 0, 4, 4, 4, CPM_CPCSR, 0, 22, BUS_DIV_ONE), + BUS_DIV(CLK_DIV_CPU_L2C_X2, "div_cpu_l2c_x2", "mux_cpu_l2c", CPM_CPCCR, 0, 4, 4, 4, CPM_CPCSR, 0, 22, BUS_DIV_TWO), +}; + + +/******************************************************************************* + * DIV + ********************************************************************************/ + +static struct clk_div_table t40_clk_div_table[256] = {}; + +static struct ingenic_div_clock t40_div_clks[] __initdata = { + DIV(CLK_DIV_DDR, "div_ddr", "mux_ddr", CPM_DDRCDR, 4, 0, NULL), + DIV(CLK_DIV_MACPHY, "div_macphy", "mux_macphy", CPM_MACCDR, 8, 0, NULL), + DIV(CLK_DIV_LCD, "div_lcd", "mux_lcd", CPM_LPCDR, 8, 0, NULL), + DIV(CLK_DIV_MSC0, "div_msc0", "mux_msc0", CPM_MSC0CDR, 8, 0, t40_clk_div_table), + DIV(CLK_DIV_MSC1, "div_msc1", "mux_msc1", CPM_MSC1CDR, 8, 0, t40_clk_div_table), + DIV(CLK_DIV_SFC, "div_sfc", "mux_sfc", CPM_SFCCDR, 8, 0, NULL), + DIV(CLK_DIV_SSI, "div_ssi", "mux_ssi", CPM_SSICDR, 8, 0, NULL), + DIV(CLK_DIV_CIM0, "div_cim0", "mux_cim0", CPM_CIM0CDR, 8, 0, NULL), + DIV(CLK_DIV_CIM1, "div_cim1", "mux_cim1", CPM_CIM1CDR, 8, 0, NULL), + DIV(CLK_DIV_CIM2, "div_cim2", "mux_cim2", CPM_CIM2CDR, 8, 0, NULL), + DIV(CLK_DIV_ISP, "div_isp", "mux_isp", CPM_ISPCDR, 4, 0, NULL), + DIV(CLK_DIV_RSA, "div_rsa", "mux_rsa", CPM_RSACDR, 4, 0, NULL), + DIV(CLK_DIV_EL150, "div_el150", "mux_el150", CPM_EL150CDR, 4, 0, NULL), + DIV(CLK_DIV_BSCALER, "div_bscaler", "mux_bscaler", CPM_BSCALERCDR, 4, 0, NULL), + DIV(CLK_DIV_BT0, "div_bt0", "mux_bt0", CPM_BT0CDR, 8, 0, NULL), + +}; + +/******************************************************************************* + * FRACTIONAL-DIVIDER + ********************************************************************************/ + +static struct ingenic_fra_div_clock t40_fdiv_clks[] __initdata = { + FRA_DIV(CLK_DIV_I2ST, "div_i2st", "mux_i2st", CPM_I2STCDR, 20, 9, 0, 20), + FRA_DIV(CLK_DIV_I2SR, "div_i2sr", "mux_i2sr", CPM_I2SRCDR, 20, 9, 0, 20), +}; + +/******************************************************************************* + * GATE + ********************************************************************************/ +static struct ingenic_gate_clock t40_gate_clks[] __initdata = { + + GATE(CLK_GATE_DDR, "gate_ddr", "div_ddr", CPM_CLKGR, 31, CLK_IGNORE_UNUSED, CLK_GATE_SET_TO_DISABLE), + GATE(CLK_GATE_TCU, "gate_tcu", "div_apb", CPM_CLKGR, 30, 0, CLK_GATE_SET_TO_DISABLE), + GATE(CLK_GATE_DES, "gate_des", "div_apb", CPM_CLKGR, 28, 0, CLK_GATE_SET_TO_DISABLE), + GATE(CLK_GATE_RSA, "gate_rsa", "div_rsa", CPM_CLKGR, 27, 0, CLK_GATE_SET_TO_DISABLE), + GATE(CLK_GATE_MIPI_CSI, "gate_csi", "div_ahb0", CPM_CLKGR, 25, 0, CLK_GATE_SET_TO_DISABLE), + GATE(CLK_GATE_LCD, "gate_lcd", "div_lcd", CPM_CLKGR, 24, 0, CLK_GATE_SET_TO_DISABLE), + GATE(CLK_GATE_ISP, "gate_isp", "div_isp", CPM_CLKGR, 23, 0, CLK_GATE_SET_TO_DISABLE), + GATE(CLK_GATE_PDMA, "gate_pdma", "div_ahb2", CPM_CLKGR, 22, 0, CLK_GATE_SET_TO_DISABLE), + GATE(CLK_GATE_SFC, "gate_sfc", "div_sfc", CPM_CLKGR, 21, 0, CLK_GATE_SET_TO_DISABLE), + GATE(CLK_GATE_SSI1, "gate_ssi1", "div_ssi", CPM_CLKGR, 20, 0, CLK_GATE_SET_TO_DISABLE), + GATE(CLK_GATE_HASH, "gate_hash", "div_ahb2", CPM_CLKGR, 19, 0, CLK_GATE_SET_TO_DISABLE), + GATE(CLK_GATE_SLV, "gate_slv", "div_apb", CPM_CLKGR, 18, 0, CLK_GATE_SET_TO_DISABLE), + GATE(CLK_GATE_UART3, "gate_uart3", "div_apb", CPM_CLKGR, 17, 0, CLK_GATE_SET_TO_DISABLE), + GATE(CLK_GATE_UART2, "gate_uart2", "div_apb", CPM_CLKGR, 16, 0, CLK_GATE_SET_TO_DISABLE), + GATE(CLK_GATE_UART1, "gate_uart1", "div_apb", CPM_CLKGR, 15, 0, CLK_GATE_SET_TO_DISABLE), + GATE(CLK_GATE_UART0, "gate_uart0", "div_apb", CPM_CLKGR, 14, 0, CLK_GATE_SET_TO_DISABLE), + GATE(CLK_GATE_SADC, "gate_sadc", "div_apb", CPM_CLKGR, 13, 0, CLK_GATE_SET_TO_DISABLE), + GATE(CLK_GATE_DMIC, "gate_dmic", "mux_apb", CPM_CLKGR, 12, 0, CLK_GATE_SET_TO_DISABLE), + GATE(CLK_GATE_AIC, "gate_aic", "div_i2st", CPM_CLKGR, 11, 0, CLK_GATE_SET_TO_DISABLE), + GATE(CLK_GATE_SMB3, "gate_i2c3", "div_apb", CPM_CLKGR, 10, 0, CLK_GATE_SET_TO_DISABLE), + GATE(CLK_GATE_SMB2, "gate_i2c2", "div_apb", CPM_CLKGR, 9, 0, CLK_GATE_SET_TO_DISABLE), + GATE(CLK_GATE_SMB1, "gate_i2c1", "div_apb", CPM_CLKGR, 8, 0, CLK_GATE_SET_TO_DISABLE), + GATE(CLK_GATE_SMB0, "gate_i2c0", "div_apb", CPM_CLKGR, 7, 0, CLK_GATE_SET_TO_DISABLE), + GATE(CLK_GATE_SSI0, "gate_ssi0", "div_ssi", CPM_CLKGR, 6, 0, CLK_GATE_SET_TO_DISABLE), + GATE(CLK_GATE_MSC1, "gate_msc1", "div_msc1", CPM_CLKGR, 5, 0, CLK_GATE_SET_TO_DISABLE), + GATE(CLK_GATE_MSC0, "gate_msc0", "div_msc0", CPM_CLKGR, 4, 0, CLK_GATE_SET_TO_DISABLE), + GATE(CLK_GATE_OTG, "gate_otg", "div_ahb2", CPM_CLKGR, 3, 0, CLK_GATE_SET_TO_DISABLE), + GATE(CLK_GATE_BSCALER, "gate_bscaler", "div_bscaler", CPM_CLKGR, 2, 0, CLK_GATE_SET_TO_DISABLE), + GATE(CLK_GATE_EFUSE, "gate_efuse", "div_ahb2", CPM_CLKGR, 1, 0, CLK_GATE_HIWORD_MASK), + GATE(CLK_GATE_NEMC, "gate_nemc", "div_ahb2", CPM_CLKGR, 0, 0, CLK_GATE_SET_TO_DISABLE), + GATE(CLK_GATE_CPU, "gate_cpu", "div_cpu", CPM_CLKGR1, 15, 0, CLK_GATE_SET_TO_DISABLE), + GATE(CLK_GATE_APB0, "gate_apb0", "div_ahb0", CPM_CLKGR1, 14, CLK_IGNORE_UNUSED, CLK_GATE_SET_TO_DISABLE), + GATE(CLK_GATE_OST, "gate_ost", "ext", CPM_CLKGR1, 11, CLK_IGNORE_UNUSED, CLK_GATE_SET_TO_DISABLE), + GATE(CLK_GATE_AHB0, "gate_ahb0", "div_ahb0", CPM_CLKGR1, 10, CLK_IGNORE_UNUSED, CLK_GATE_SET_TO_DISABLE), + GATE(CLK_GATE_MONITOR, "gate_monitor", "div_ahb0", CPM_CLKGR1, 9, 0, CLK_GATE_SET_TO_DISABLE), + GATE(CLK_GATE_I2D, "gate_i2d", "div_ahb0", CPM_CLKGR1, 8, 0, CLK_GATE_SET_TO_DISABLE), + GATE(CLK_GATE_MIPI_DSI, "gate_dsi", "div_ahb0", CPM_CLKGR1, 7, 0, CLK_GATE_SET_TO_DISABLE), + GATE(CLK_GATE_DRAWBOX, "gate_drawbox", "div_ahb0", CPM_CLKGR1, 6, 0, CLK_GATE_SET_TO_DISABLE), + GATE(CLK_GATE_AES, "gate_aes", "div_ahb2", CPM_CLKGR1, 5, 0, CLK_GATE_SET_TO_DISABLE), + GATE(CLK_GATE_GMAC, "gate_gmac", "div_macphy", CPM_CLKGR1, 4, 0, CLK_GATE_SET_TO_DISABLE), + GATE(CLK_GATE_AHB1, "gate_ahb1", "div_ahb2", CPM_CLKGR1, 3, 0, CLK_GATE_SET_TO_DISABLE), + GATE(CLK_GATE_IPU, "gate_ipu", "div_ahb0", CPM_CLKGR1, 2, 0, CLK_GATE_SET_TO_DISABLE), + GATE(CLK_GATE_DTRNG, "gate_dtrng", "div_apb", CPM_CLKGR1, 1, 0, CLK_GATE_SET_TO_DISABLE), + GATE(CLK_GATE_EL150, "gate_el150", "div_el150", CPM_CLKGR1, 0, 0, CLK_GATE_SET_TO_DISABLE), + GATE(CLK_CE_I2ST, "ce_i2st", "div_i2st", CPM_I2STCDR, 29, 0, 0), + GATE(CLK_CE_I2SR, "ce_i2sr", "div_i2sr", CPM_I2SRCDR, 29, 0, 0), + GATE(CLK_GATE_USBPHY, "gate_usbphy", "div_apb", CPM_OPCR, 23, 0, CLK_GATE_SET_TO_DISABLE) +}; + +static void clk_div_table_generate(void) +{ + int i; + for (i = 0; i < ARRAY_SIZE(t40_clk_div_table); i++) { + t40_clk_div_table[i].val = i; + t40_clk_div_table[i].div = (i + 1) * 4; + } + +} + +static const struct of_device_id ext_clk_match[] __initconst = { + { .compatible = "ingenic,fixed-clock", .data = (void *)0, }, + {}, +}; + +static int clocks_show(struct seq_file *m, void *v) +{ + int i = 0; + struct clk_onecell_data * clk_data = NULL; + struct clk *clk = NULL; + + if(m->private != NULL) { + seq_printf(m, "CLKGR\t: %08x\n", cpm_inl(CPM_CLKGR)); + seq_printf(m, "CLKGR1\t: %08x\n", cpm_inl(CPM_CLKGR1)); + seq_printf(m, "LCR1\t: %08x\n", cpm_inl(CPM_LCR)); + } else { + seq_printf(m, " ID NAME FRE sta count parent\n"); + clk_data = &ctx->clk_data; + for(i = 0; i < clk_data->clk_num; i++) { + clk = clk_data->clks[i]; + if (clk != ERR_PTR(-ENOENT)) { + if (__clk_get_name(clk) == NULL) { + seq_printf(m, "--------------------------------------------------------\n"); + } else { + unsigned int mhz = _get_rate(__clk_get_name(clk)) / 1000; + seq_printf(m, "%3d %-15s %4d.%03dMHz %7sable %d %10s\n", i, __clk_get_name(clk) + , mhz/1000, mhz%1000 + , __clk_get_flags(clk) & CLK_FLG_ENABLE? "en": "dis" + , __clk_get_enable_count(clk) + , clk_get_parent(clk)? __clk_get_name(clk_get_parent(clk)): "root"); + } + } + } + } + + return 0; +} + +static int clocks_open(struct inode *inode, struct file *file) +{ + return single_open_size(file, clocks_show, PDE_DATA(inode),8192); +} + +static const struct file_operations clocks_proc_fops ={ + .read = seq_read, + .open = clocks_open, + .llseek = seq_lseek, + .release = single_release, +}; + +/* Register t40 clocks. */ +static void __init t40_clk_init(struct device_node *np, void __iomem *base) +{ + void __iomem *reg_base; + + printk("t40 Clock Power Management Unit init!\n"); + + reg_base = base; + + if (np) { + reg_base = of_iomap(np, 0); + if (!reg_base) + panic("%s: failed to map registers\n", __func__); + } + + + ctx = ingenic_clk_init(np, reg_base, NR_CLKS); + if (!ctx) + panic("%s: unable to allocate context.\n", __func__); + + /* Register Ext Clocks From DT */ + ingenic_clk_of_register_fixed_ext(ctx, t40_fixed_rate_ext_clks, + ARRAY_SIZE(t40_fixed_rate_ext_clks), ext_clk_match); + + /* Register PLLs. */ + ingenic_clk_register_pll(ctx, t40_pll_clks, + ARRAY_SIZE(t40_pll_clks), reg_base); + + + /* Register Muxs */ + ingenic_clk_register_mux(ctx, t40_mux_clks, ARRAY_SIZE(t40_mux_clks)); + + /* Register Bus Divs */ + ingenic_clk_register_bus_div(ctx, t40_bus_div_clks, ARRAY_SIZE(t40_bus_div_clks)); + + /* Register Divs */ + clk_div_table_generate(); + ingenic_clk_register_cgu_div(ctx, t40_div_clks, ARRAY_SIZE(t40_div_clks)); + + /* Register Fractional Divs */ + ingenic_clk_register_fra_div(ctx, t40_fdiv_clks, ARRAY_SIZE(t40_fdiv_clks)); + + /* Register Gates */ + ingenic_clk_register_gate(ctx, t40_gate_clks, ARRAY_SIZE(t40_gate_clks)); + + /* Register Powers */ +// ingenic_power_register_gate(ctx, t40_gate_power, ARRAY_SIZE(t40_gate_power)); + + ingenic_clk_of_add_provider(np, ctx); + + + //ingenic_clk_of_dump(ctx); + + + pr_info("=========== t40 clocks: =============\n" + "\tapll = %lu , mpll = %lu\n" + "\tcpu_clk = %lu , l2c_clk = %lu\n" + "\tahb0_clk = %lu , ahb2_clk = %lu\n" + "\tapb_clk = %lu , ext_clk = %lu\n\n", + _get_rate("apll"), _get_rate("mpll"), + _get_rate("div_cpu"), _get_rate("div_l2c"), + _get_rate("div_ahb0"), _get_rate("div_ahb2"), + _get_rate("div_apb"), _get_rate("ext")); + +} + +CLK_OF_DECLARE(t40_clk, "ingenic,t40-clocks", t40_clk_init); + +static int __init init_clk_proc(void) +{ + struct proc_dir_entry *p; + + p = jz_proc_mkdir("clock"); + if (!p) { + pr_warning("create_proc_entry for common clock failed!\n"); + } else { + proc_create_data("clocks", 0600, p, &clocks_proc_fops, 0); + proc_create_data("misc", 0600, p, &clocks_proc_fops, (void *)1); + } + return 0; +} + +module_init(init_clk_proc);