Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/2] scripts/gdb: add lx-fdtdump command
From: Jan Kiszka @ 2016-10-18 15:47 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1476803249-23328-1-git-send-email-peter.griffin@linaro.org>

On 2016-10-18 17:07, Peter Griffin wrote:
> lx-fdtdump dumps the flatenned device tree passed to the kernel
> from the bootloader to a file called fdtdump.dtb to allow further
> post processing on the machine running GDB. The fdt header is also
> also printed in the GDB console. For example:
> 
> (gdb) lx-fdtdump
> fdt_magic:         0xD00DFEED
> fdt_totalsize:     0xC108
> off_dt_struct:     0x38
> off_dt_strings:    0x3804
> off_mem_rsvmap:    0x28
> version:           17
> last_comp_version: 16
> Dumped fdt to fdtdump.dtb
> 
>> fdtdump fdtdump.dtb | less
> 
> This command is useful as the bootloader can often re-write parts
> of the device tree, and this can sometimes cause the kernel to not
> boot.
> 
> Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
> ---
>  scripts/gdb/linux/constants.py.in |  8 +++++
>  scripts/gdb/linux/proc.py         | 70 ++++++++++++++++++++++++++++++++++++++-
>  2 files changed, 77 insertions(+), 1 deletion(-)
> 
> diff --git a/scripts/gdb/linux/constants.py.in b/scripts/gdb/linux/constants.py.in
> index 7986f4e..43c6241 100644
> --- a/scripts/gdb/linux/constants.py.in
> +++ b/scripts/gdb/linux/constants.py.in
> @@ -14,6 +14,7 @@
>  
>  #include <linux/fs.h>
>  #include <linux/mount.h>
> +#include <linux/of_fdt.h>
>  
>  /* We need to stringify expanded macros so that they can be parsed */
>  
> @@ -50,3 +51,10 @@ LX_VALUE(MNT_NOEXEC)
>  LX_VALUE(MNT_NOATIME)
>  LX_VALUE(MNT_NODIRATIME)
>  LX_VALUE(MNT_RELATIME)
> +
> +/* linux/of_fdt.h> */
> +LX_VALUE(OF_DT_HEADER)
> +
> +/* Kernel Configs */
> +LX_CONFIG(CONFIG_OF)
> +
> diff --git a/scripts/gdb/linux/proc.py b/scripts/gdb/linux/proc.py
> index 38b1f09..f20fcfa 100644
> --- a/scripts/gdb/linux/proc.py
> +++ b/scripts/gdb/linux/proc.py
> @@ -16,7 +16,7 @@ from linux import constants
>  from linux import utils
>  from linux import tasks
>  from linux import lists
> -
> +from struct import *
>  
>  class LxCmdLine(gdb.Command):
>      """ Report the Linux Commandline used in the current kernel.
> @@ -195,3 +195,71 @@ values of that process namespace"""
>                          info_opts(MNT_INFO, m_flags)))
>  
>  LxMounts()
> +
> +class LxFdtDump(gdb.Command):
> +    """Output Flattened Device Tree header and dump FDT blob to a file
> +       Equivalent to 'cat /proc/fdt > fdtdump.dtb' on a running target"""
> +
> +    def __init__(self):
> +        super(LxFdtDump, self).__init__("lx-fdtdump", gdb.COMMAND_DATA)
> +
> +    def fdthdr_to_cpu(self, fdt_header):
> +
> +            fdt_header_be = ">IIIIIII"
> +            fdt_header_le = "<IIIIIII"
> +
> +            if utils.get_target_endianness() == 1:
> +                output_fmt = fdt_header_le
> +            else:
> +                output_fmt = fdt_header_be
> +
> +            return unpack(output_fmt, pack(fdt_header_be,
> +                                           fdt_header['magic'],
> +                                           fdt_header['totalsize'],
> +                                           fdt_header['off_dt_struct'],
> +                                           fdt_header['off_dt_strings'],
> +                                           fdt_header['off_mem_rsvmap'],
> +                                           fdt_header['version'],
> +                                           fdt_header['last_comp_version']))
> +
> +    def invoke(self, arg, from_tty):
> +
> +        if constants.LX_CONFIG_OF:
> +
> +            filename = "fdtdump.dtb"

Why not specifying the file name as argument? Safer than silently
overwriting potentially pre-existing files or failing without
alternatives if the current directory is not writable.

> +
> +            py_fdt_header_ptr = gdb.parse_and_eval(
> +                "(const struct fdt_header *) initial_boot_params")
> +            py_fdt_header = py_fdt_header_ptr.dereference()
> +
> +            fdt_header = self.fdthdr_to_cpu(py_fdt_header)
> +
> +            if fdt_header[0] != constants.LX_OF_DT_HEADER:
> +                raise gdb.GdbError("No flattened device tree magic found\n")
> +
> +            gdb.write("fdt_magic:         0x{:02X}\n".format(fdt_header[0]))
> +            gdb.write("fdt_totalsize:     0x{:02X}\n".format(fdt_header[1]))
> +            gdb.write("off_dt_struct:     0x{:02X}\n".format(fdt_header[2]))
> +            gdb.write("off_dt_strings:    0x{:02X}\n".format(fdt_header[3]))
> +            gdb.write("off_mem_rsvmap:    0x{:02X}\n".format(fdt_header[4]))
> +            gdb.write("version:           {}\n".format(fdt_header[5]))
> +            gdb.write("last_comp_version: {}\n".format(fdt_header[6]))
> +
> +            inf = gdb.inferiors()[0]
> +            fdt_buf = utils.read_memoryview(inf, py_fdt_header_ptr,
> +                                            fdt_header[1]).tobytes()
> +
> +            try:
> +                f = open(filename, 'wb')
> +            except:
> +                raise gdb.GdbError("Could not open file to dump fdt")
> +
> +            f.write(fdt_buf)
> +            f.close()
> +
> +            gdb.write("Dumped fdt to " + filename + "\n")
> +
> +        else:
> +            gdb.write("Kernel not compiled with CONFIG_OF\n")
> +
> +LxFdtDump()
> 

Jan

-- 
Siemens AG, Corporate Technology, CT RDA ITP SES-DE
Corporate Competence Center Embedded Linux

^ permalink raw reply

* [PATCHv4 15/15] clk: ti: omap4: cleanup unnecessary clock aliases
From: Tero Kristo @ 2016-10-18 15:46 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1476805568-19264-1-git-send-email-t-kristo@ti.com>

Cleanup any unnecessary DT_CLK() alias entries from the OMAP4 clock file.
Most of these are now handled dynamically by the driver code.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 drivers/clk/ti/clk-44xx.c | 186 ----------------------------------------------
 1 file changed, 186 deletions(-)

diff --git a/drivers/clk/ti/clk-44xx.c b/drivers/clk/ti/clk-44xx.c
index b482047..72a3622 100644
--- a/drivers/clk/ti/clk-44xx.c
+++ b/drivers/clk/ti/clk-44xx.c
@@ -1435,196 +1435,13 @@
 };
 
 static struct ti_dt_clk omap44xx_clks[] = {
-	DT_CLK(NULL, "extalt_clkin_ck", "extalt_clkin_ck"),
-	DT_CLK(NULL, "pad_clks_src_ck", "pad_clks_src_ck"),
-	DT_CLK(NULL, "pad_clks_ck", "pad_clks_ck"),
-	DT_CLK(NULL, "pad_slimbus_core_clks_ck", "pad_slimbus_core_clks_ck"),
-	DT_CLK(NULL, "secure_32k_clk_src_ck", "secure_32k_clk_src_ck"),
-	DT_CLK(NULL, "slimbus_src_clk", "slimbus_src_clk"),
-	DT_CLK(NULL, "slimbus_clk", "slimbus_clk"),
-	DT_CLK(NULL, "sys_32k_ck", "sys_32k_ck"),
-	DT_CLK(NULL, "virt_12000000_ck", "virt_12000000_ck"),
-	DT_CLK(NULL, "virt_13000000_ck", "virt_13000000_ck"),
-	DT_CLK(NULL, "virt_16800000_ck", "virt_16800000_ck"),
-	DT_CLK(NULL, "virt_19200000_ck", "virt_19200000_ck"),
-	DT_CLK(NULL, "virt_26000000_ck", "virt_26000000_ck"),
-	DT_CLK(NULL, "virt_27000000_ck", "virt_27000000_ck"),
-	DT_CLK(NULL, "virt_38400000_ck", "virt_38400000_ck"),
-	DT_CLK(NULL, "sys_clkin_ck", "sys_clkin_ck"),
-	DT_CLK(NULL, "tie_low_clock_ck", "tie_low_clock_ck"),
-	DT_CLK(NULL, "utmi_phy_clkout_ck", "utmi_phy_clkout_ck"),
-	DT_CLK(NULL, "xclk60mhsp1_ck", "xclk60mhsp1_ck"),
-	DT_CLK(NULL, "xclk60mhsp2_ck", "xclk60mhsp2_ck"),
-	DT_CLK(NULL, "xclk60motg_ck", "xclk60motg_ck"),
-	DT_CLK(NULL, "abe_dpll_bypass_clk_mux_ck", "abe_dpll_bypass_clk_mux_ck"),
-	DT_CLK(NULL, "abe_dpll_refclk_mux_ck", "abe_dpll_refclk_mux_ck"),
-	DT_CLK(NULL, "dpll_abe_ck", "dpll_abe_ck"),
-	DT_CLK(NULL, "dpll_abe_x2_ck", "dpll_abe_x2_ck"),
-	DT_CLK(NULL, "dpll_abe_m2x2_ck", "dpll_abe_m2x2_ck"),
-	DT_CLK(NULL, "abe_24m_fclk", "abe_24m_fclk"),
-	DT_CLK(NULL, "abe_clk", "abe_clk"),
-	DT_CLK(NULL, "aess_fclk", "aess_fclk"),
-	DT_CLK(NULL, "dpll_abe_m3x2_ck", "dpll_abe_m3x2_ck"),
-	DT_CLK(NULL, "core_hsd_byp_clk_mux_ck", "core_hsd_byp_clk_mux_ck"),
-	DT_CLK(NULL, "dpll_core_ck", "dpll_core_ck"),
-	DT_CLK(NULL, "dpll_core_x2_ck", "dpll_core_x2_ck"),
-	DT_CLK(NULL, "dpll_core_m6x2_ck", "dpll_core_m6x2_ck"),
-	DT_CLK(NULL, "dbgclk_mux_ck", "dbgclk_mux_ck"),
-	DT_CLK(NULL, "dpll_core_m2_ck", "dpll_core_m2_ck"),
-	DT_CLK(NULL, "ddrphy_ck", "ddrphy_ck"),
-	DT_CLK(NULL, "dpll_core_m5x2_ck", "dpll_core_m5x2_ck"),
-	DT_CLK(NULL, "div_core_ck", "div_core_ck"),
-	DT_CLK(NULL, "div_iva_hs_clk", "div_iva_hs_clk"),
-	DT_CLK(NULL, "div_mpu_hs_clk", "div_mpu_hs_clk"),
-	DT_CLK(NULL, "dpll_core_m4x2_ck", "dpll_core_m4x2_ck"),
-	DT_CLK(NULL, "dll_clk_div_ck", "dll_clk_div_ck"),
-	DT_CLK(NULL, "dpll_abe_m2_ck", "dpll_abe_m2_ck"),
-	DT_CLK(NULL, "dpll_core_m3x2_ck", "dpll_core_m3x2_ck"),
-	DT_CLK(NULL, "dpll_core_m7x2_ck", "dpll_core_m7x2_ck"),
-	DT_CLK(NULL, "iva_hsd_byp_clk_mux_ck", "iva_hsd_byp_clk_mux_ck"),
-	DT_CLK(NULL, "dpll_iva_ck", "dpll_iva_ck"),
-	DT_CLK(NULL, "dpll_iva_x2_ck", "dpll_iva_x2_ck"),
-	DT_CLK(NULL, "dpll_iva_m4x2_ck", "dpll_iva_m4x2_ck"),
-	DT_CLK(NULL, "dpll_iva_m5x2_ck", "dpll_iva_m5x2_ck"),
-	DT_CLK(NULL, "dpll_mpu_ck", "dpll_mpu_ck"),
-	DT_CLK(NULL, "dpll_mpu_m2_ck", "dpll_mpu_m2_ck"),
-	DT_CLK(NULL, "per_hs_clk_div_ck", "per_hs_clk_div_ck"),
-	DT_CLK(NULL, "per_hsd_byp_clk_mux_ck", "per_hsd_byp_clk_mux_ck"),
-	DT_CLK(NULL, "dpll_per_ck", "dpll_per_ck"),
-	DT_CLK(NULL, "dpll_per_m2_ck", "dpll_per_m2_ck"),
-	DT_CLK(NULL, "dpll_per_x2_ck", "dpll_per_x2_ck"),
-	DT_CLK(NULL, "dpll_per_m2x2_ck", "dpll_per_m2x2_ck"),
-	DT_CLK(NULL, "dpll_per_m3x2_ck", "dpll_per_m3x2_ck"),
-	DT_CLK(NULL, "dpll_per_m4x2_ck", "dpll_per_m4x2_ck"),
-	DT_CLK(NULL, "dpll_per_m5x2_ck", "dpll_per_m5x2_ck"),
-	DT_CLK(NULL, "dpll_per_m6x2_ck", "dpll_per_m6x2_ck"),
-	DT_CLK(NULL, "dpll_per_m7x2_ck", "dpll_per_m7x2_ck"),
-	DT_CLK(NULL, "usb_hs_clk_div_ck", "usb_hs_clk_div_ck"),
-	DT_CLK(NULL, "dpll_usb_ck", "dpll_usb_ck"),
-	DT_CLK(NULL, "dpll_usb_clkdcoldo_ck", "dpll_usb_clkdcoldo_ck"),
-	DT_CLK(NULL, "dpll_usb_m2_ck", "dpll_usb_m2_ck"),
-	DT_CLK(NULL, "ducati_clk_mux_ck", "ducati_clk_mux_ck"),
-	DT_CLK(NULL, "func_12m_fclk", "func_12m_fclk"),
-	DT_CLK(NULL, "func_24m_clk", "func_24m_clk"),
-	DT_CLK(NULL, "func_24mc_fclk", "func_24mc_fclk"),
-	DT_CLK(NULL, "func_48m_fclk", "func_48m_fclk"),
-	DT_CLK(NULL, "func_48mc_fclk", "func_48mc_fclk"),
-	DT_CLK(NULL, "func_64m_fclk", "func_64m_fclk"),
-	DT_CLK(NULL, "func_96m_fclk", "func_96m_fclk"),
-	DT_CLK(NULL, "init_60m_fclk", "init_60m_fclk"),
-	DT_CLK(NULL, "l3_div_ck", "l3_div_ck"),
-	DT_CLK(NULL, "l4_div_ck", "l4_div_ck"),
-	DT_CLK(NULL, "lp_clk_div_ck", "lp_clk_div_ck"),
-	DT_CLK(NULL, "l4_wkup_clk_mux_ck", "l4_wkup_clk_mux_ck"),
 	DT_CLK("smp_twd", NULL, "mpu_periphclk"),
-	DT_CLK(NULL, "ocp_abe_iclk", "ocp_abe_iclk"),
-	DT_CLK(NULL, "per_abe_24m_fclk", "per_abe_24m_fclk"),
-	DT_CLK(NULL, "per_abe_nc_fclk", "per_abe_nc_fclk"),
-	DT_CLK(NULL, "syc_clk_div_ck", "syc_clk_div_ck"),
-	DT_CLK(NULL, "aes1_fck", "aes1_fck"),
-	DT_CLK(NULL, "aes2_fck", "aes2_fck"),
-	DT_CLK(NULL, "dmic_sync_mux_ck", "dmic_sync_mux_ck"),
-	DT_CLK(NULL, "func_dmic_abe_gfclk", "func_dmic_abe_gfclk"),
-	DT_CLK(NULL, "dss_sys_clk", "dss_sys_clk"),
-	DT_CLK(NULL, "dss_tv_clk", "dss_tv_clk"),
-	DT_CLK(NULL, "dss_dss_clk", "dss_dss_clk"),
-	DT_CLK(NULL, "dss_48mhz_clk", "dss_48mhz_clk"),
-	DT_CLK(NULL, "dss_fck", "dss_fck"),
 	DT_CLK("omapdss_dss", "ick", "dss_fck"),
-	DT_CLK(NULL, "fdif_fck", "fdif_fck"),
-	DT_CLK(NULL, "gpio1_dbclk", "gpio1_dbclk"),
-	DT_CLK(NULL, "gpio2_dbclk", "gpio2_dbclk"),
-	DT_CLK(NULL, "gpio3_dbclk", "gpio3_dbclk"),
-	DT_CLK(NULL, "gpio4_dbclk", "gpio4_dbclk"),
-	DT_CLK(NULL, "gpio5_dbclk", "gpio5_dbclk"),
-	DT_CLK(NULL, "gpio6_dbclk", "gpio6_dbclk"),
-	DT_CLK(NULL, "sgx_clk_mux", "sgx_clk_mux"),
-	DT_CLK(NULL, "hsi_fck", "hsi_fck"),
-	DT_CLK(NULL, "iss_ctrlclk", "iss_ctrlclk"),
-	DT_CLK(NULL, "mcasp_sync_mux_ck", "mcasp_sync_mux_ck"),
-	DT_CLK(NULL, "func_mcasp_abe_gfclk", "func_mcasp_abe_gfclk"),
-	DT_CLK(NULL, "mcbsp1_sync_mux_ck", "mcbsp1_sync_mux_ck"),
-	DT_CLK(NULL, "func_mcbsp1_gfclk", "func_mcbsp1_gfclk"),
-	DT_CLK(NULL, "mcbsp2_sync_mux_ck", "mcbsp2_sync_mux_ck"),
-	DT_CLK(NULL, "func_mcbsp2_gfclk", "func_mcbsp2_gfclk"),
-	DT_CLK(NULL, "mcbsp3_sync_mux_ck", "mcbsp3_sync_mux_ck"),
-	DT_CLK(NULL, "func_mcbsp3_gfclk", "func_mcbsp3_gfclk"),
-	DT_CLK(NULL, "mcbsp4_sync_mux_ck", "mcbsp4_sync_mux_ck"),
-	DT_CLK(NULL, "per_mcbsp4_gfclk", "per_mcbsp4_gfclk"),
-	DT_CLK(NULL, "hsmmc1_fclk", "hsmmc1_fclk"),
-	DT_CLK(NULL, "hsmmc2_fclk", "hsmmc2_fclk"),
-	DT_CLK(NULL, "ocp2scp_usb_phy_phy_48m", "ocp2scp_usb_phy_phy_48m"),
-	DT_CLK(NULL, "sha2md5_fck", "sha2md5_fck"),
-	DT_CLK(NULL, "slimbus1_fclk_1", "slimbus1_fclk_1"),
-	DT_CLK(NULL, "slimbus1_fclk_0", "slimbus1_fclk_0"),
-	DT_CLK(NULL, "slimbus1_fclk_2", "slimbus1_fclk_2"),
-	DT_CLK(NULL, "slimbus1_slimbus_clk", "slimbus1_slimbus_clk"),
-	DT_CLK(NULL, "slimbus2_fclk_1", "slimbus2_fclk_1"),
-	DT_CLK(NULL, "slimbus2_fclk_0", "slimbus2_fclk_0"),
-	DT_CLK(NULL, "slimbus2_slimbus_clk", "slimbus2_slimbus_clk"),
-	DT_CLK(NULL, "smartreflex_core_fck", "smartreflex_core_fck"),
-	DT_CLK(NULL, "smartreflex_iva_fck", "smartreflex_iva_fck"),
-	DT_CLK(NULL, "smartreflex_mpu_fck", "smartreflex_mpu_fck"),
-	DT_CLK(NULL, "dmt1_clk_mux", "dmt1_clk_mux"),
-	DT_CLK(NULL, "cm2_dm10_mux", "cm2_dm10_mux"),
-	DT_CLK(NULL, "cm2_dm11_mux", "cm2_dm11_mux"),
-	DT_CLK(NULL, "cm2_dm2_mux", "cm2_dm2_mux"),
-	DT_CLK(NULL, "cm2_dm3_mux", "cm2_dm3_mux"),
-	DT_CLK(NULL, "cm2_dm4_mux", "cm2_dm4_mux"),
-	DT_CLK(NULL, "timer5_sync_mux", "timer5_sync_mux"),
-	DT_CLK(NULL, "timer6_sync_mux", "timer6_sync_mux"),
-	DT_CLK(NULL, "timer7_sync_mux", "timer7_sync_mux"),
-	DT_CLK(NULL, "timer8_sync_mux", "timer8_sync_mux"),
-	DT_CLK(NULL, "cm2_dm9_mux", "cm2_dm9_mux"),
-	DT_CLK(NULL, "usb_host_fs_fck", "usb_host_fs_fck"),
 	DT_CLK("usbhs_omap", "fs_fck", "usb_host_fs_fck"),
-	DT_CLK(NULL, "utmi_p1_gfclk", "utmi_p1_gfclk"),
-	DT_CLK(NULL, "usb_host_hs_utmi_p1_clk", "usb_host_hs_utmi_p1_clk"),
-	DT_CLK(NULL, "utmi_p2_gfclk", "utmi_p2_gfclk"),
-	DT_CLK(NULL, "usb_host_hs_utmi_p2_clk", "usb_host_hs_utmi_p2_clk"),
-	DT_CLK(NULL, "usb_host_hs_utmi_p3_clk", "usb_host_hs_utmi_p3_clk"),
-	DT_CLK(NULL, "usb_host_hs_hsic480m_p1_clk", "usb_host_hs_hsic480m_p1_clk"),
-	DT_CLK(NULL, "usb_host_hs_hsic60m_p1_clk", "usb_host_hs_hsic60m_p1_clk"),
-	DT_CLK(NULL, "usb_host_hs_hsic60m_p2_clk", "usb_host_hs_hsic60m_p2_clk"),
-	DT_CLK(NULL, "usb_host_hs_hsic480m_p2_clk", "usb_host_hs_hsic480m_p2_clk"),
-	DT_CLK(NULL, "usb_host_hs_func48mclk", "usb_host_hs_func48mclk"),
-	DT_CLK(NULL, "usb_host_hs_fck", "usb_host_hs_fck"),
 	DT_CLK("usbhs_omap", "hs_fck", "usb_host_hs_fck"),
-	DT_CLK(NULL, "otg_60m_gfclk", "otg_60m_gfclk"),
-	DT_CLK(NULL, "usb_otg_hs_xclk", "usb_otg_hs_xclk"),
-	DT_CLK(NULL, "usb_otg_hs_ick", "usb_otg_hs_ick"),
 	DT_CLK("musb-omap2430", "ick", "usb_otg_hs_ick"),
-	DT_CLK(NULL, "usb_phy_cm_clk32k", "usb_phy_cm_clk32k"),
-	DT_CLK(NULL, "usb_tll_hs_usb_ch2_clk", "usb_tll_hs_usb_ch2_clk"),
-	DT_CLK(NULL, "usb_tll_hs_usb_ch0_clk", "usb_tll_hs_usb_ch0_clk"),
-	DT_CLK(NULL, "usb_tll_hs_usb_ch1_clk", "usb_tll_hs_usb_ch1_clk"),
-	DT_CLK(NULL, "usb_tll_hs_ick", "usb_tll_hs_ick"),
 	DT_CLK("usbhs_omap", "usbtll_ick", "usb_tll_hs_ick"),
 	DT_CLK("usbhs_tll", "usbtll_ick", "usb_tll_hs_ick"),
-	DT_CLK(NULL, "usim_ck", "usim_ck"),
-	DT_CLK(NULL, "usim_fclk", "usim_fclk"),
-	DT_CLK(NULL, "pmd_stm_clock_mux_ck", "pmd_stm_clock_mux_ck"),
-	DT_CLK(NULL, "pmd_trace_clk_mux_ck", "pmd_trace_clk_mux_ck"),
-	DT_CLK(NULL, "stm_clk_div_ck", "stm_clk_div_ck"),
-	DT_CLK(NULL, "trace_clk_div_ck", "trace_clk_div_ck"),
-	DT_CLK(NULL, "auxclk0_src_ck", "auxclk0_src_ck"),
-	DT_CLK(NULL, "auxclk0_ck", "auxclk0_ck"),
-	DT_CLK(NULL, "auxclkreq0_ck", "auxclkreq0_ck"),
-	DT_CLK(NULL, "auxclk1_src_ck", "auxclk1_src_ck"),
-	DT_CLK(NULL, "auxclk1_ck", "auxclk1_ck"),
-	DT_CLK(NULL, "auxclkreq1_ck", "auxclkreq1_ck"),
-	DT_CLK(NULL, "auxclk2_src_ck", "auxclk2_src_ck"),
-	DT_CLK(NULL, "auxclk2_ck", "auxclk2_ck"),
-	DT_CLK(NULL, "auxclkreq2_ck", "auxclkreq2_ck"),
-	DT_CLK(NULL, "auxclk3_src_ck", "auxclk3_src_ck"),
-	DT_CLK(NULL, "auxclk3_ck", "auxclk3_ck"),
-	DT_CLK(NULL, "auxclkreq3_ck", "auxclkreq3_ck"),
-	DT_CLK(NULL, "auxclk4_src_ck", "auxclk4_src_ck"),
-	DT_CLK(NULL, "auxclk4_ck", "auxclk4_ck"),
-	DT_CLK(NULL, "auxclkreq4_ck", "auxclkreq4_ck"),
-	DT_CLK(NULL, "auxclk5_src_ck", "auxclk5_src_ck"),
-	DT_CLK(NULL, "auxclk5_ck", "auxclk5_ck"),
-	DT_CLK(NULL, "auxclkreq5_ck", "auxclkreq5_ck"),
 	DT_CLK("omap_i2c.1", "ick", "dummy_ck"),
 	DT_CLK("omap_i2c.2", "ick", "dummy_ck"),
 	DT_CLK("omap_i2c.3", "ick", "dummy_ck"),
@@ -1664,9 +1481,6 @@
 	DT_CLK("4013c000.timer", "timer_sys_ck", "syc_clk_div_ck"),
 	DT_CLK("4013e000.timer", "timer_sys_ck", "syc_clk_div_ck"),
 	DT_CLK(NULL, "cpufreq_ck", "dpll_mpu_ck"),
-	DT_CLK(NULL, "bandgap_fclk", "bandgap_fclk"),
-	DT_CLK(NULL, "div_ts_ck", "div_ts_ck"),
-	DT_CLK(NULL, "bandgap_ts_fclk", "bandgap_ts_fclk"),
 	{ .node_name = NULL },
 };
 
-- 
1.9.1

^ permalink raw reply related

* [PATCHv4 14/15] clk: ti: omap4: add hwmod clock data
From: Tero Kristo @ 2016-10-18 15:46 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1476805568-19264-1-git-send-email-t-kristo@ti.com>

Add hwmod clock data for omap4 SoC. This data is basically a conversion
of the existing hwmod data to clock format.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 drivers/clk/ti/clk-44xx.c | 1403 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 1403 insertions(+)

diff --git a/drivers/clk/ti/clk-44xx.c b/drivers/clk/ti/clk-44xx.c
index 7a8b51b..b482047 100644
--- a/drivers/clk/ti/clk-44xx.c
+++ b/drivers/clk/ti/clk-44xx.c
@@ -15,6 +15,7 @@
 #include <linux/clk.h>
 #include <linux/clkdev.h>
 #include <linux/clk/ti.h>
+#include <dt-bindings/clock/ti,omap44xx.h>
 
 #include "clock.h"
 
@@ -33,6 +34,1406 @@
  */
 #define OMAP4_DPLL_USB_DEFFREQ				960000000
 
+static struct ti_clk_hwmod mpu_mod_ck_data = {
+	.reg = OMAP44XX_MPUSS_MPU,
+	.parent = "dpll_mpu_m2_ck",
+};
+
+static struct ti_clk mpu_mod_ck = {
+	.name = "mpu_mod_ck",
+	.clkdm_name = "mpuss_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &mpu_mod_ck_data,
+};
+
+static struct ti_clk_hwmod dsp_mod_ck_data = {
+	.reg = OMAP44XX_TESLA_DSP,
+	.parent = "dpll_iva_m4x2_ck",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk dsp_mod_ck = {
+	.name = "dsp_mod_ck",
+	.clkdm_name = "tesla_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &dsp_mod_ck_data,
+};
+
+static struct ti_clk_hwmod mmu_dsp_mod_ck_data = {
+	.reg = OMAP44XX_TESLA_MMU_DSP,
+	.parent = "dpll_iva_m4x2_ck",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk mmu_dsp_mod_ck = {
+	.name = "mmu_dsp_mod_ck",
+	.clkdm_name = "tesla_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &mmu_dsp_mod_ck_data,
+};
+
+static struct ti_clk_hwmod l4_abe_mod_ck_data = {
+	.reg = OMAP44XX_ABE_L4_ABE,
+	.parent = "ocp_abe_iclk",
+};
+
+static struct ti_clk l4_abe_mod_ck = {
+	.name = "l4_abe_mod_ck",
+	.clkdm_name = "abe_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &l4_abe_mod_ck_data,
+};
+
+static struct ti_clk_hwmod aess_mod_ck_data = {
+	.reg = OMAP44XX_ABE_AESS,
+	.parent = "aess_fclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk aess_mod_ck = {
+	.name = "aess_mod_ck",
+	.clkdm_name = "abe_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &aess_mod_ck_data,
+};
+
+static struct ti_clk_hwmod mcpdm_mod_ck_data = {
+	.reg = OMAP44XX_ABE_MCPDM,
+	.parent = "pad_clks_ck",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk mcpdm_mod_ck = {
+	.name = "mcpdm_mod_ck",
+	.clkdm_name = "abe_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &mcpdm_mod_ck_data,
+};
+
+static struct ti_clk_hwmod dmic_mod_ck_data = {
+	.reg = OMAP44XX_ABE_DMIC,
+	.parent = "func_dmic_abe_gfclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk dmic_mod_ck = {
+	.name = "dmic_mod_ck",
+	.clkdm_name = "abe_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &dmic_mod_ck_data,
+};
+
+static struct ti_clk_hwmod mcasp_mod_ck_data = {
+	.reg = OMAP44XX_ABE_MCASP,
+	.parent = "func_mcasp_abe_gfclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk mcasp_mod_ck = {
+	.name = "mcasp_mod_ck",
+	.clkdm_name = "abe_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &mcasp_mod_ck_data,
+};
+
+static struct ti_clk_hwmod mcbsp1_mod_ck_data = {
+	.reg = OMAP44XX_ABE_MCBSP1,
+	.parent = "func_mcbsp1_gfclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk mcbsp1_mod_ck = {
+	.name = "mcbsp1_mod_ck",
+	.clkdm_name = "abe_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &mcbsp1_mod_ck_data,
+};
+
+static struct ti_clk_hwmod mcbsp2_mod_ck_data = {
+	.reg = OMAP44XX_ABE_MCBSP2,
+	.parent = "func_mcbsp2_gfclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk mcbsp2_mod_ck = {
+	.name = "mcbsp2_mod_ck",
+	.clkdm_name = "abe_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &mcbsp2_mod_ck_data,
+};
+
+static struct ti_clk_hwmod mcbsp3_mod_ck_data = {
+	.reg = OMAP44XX_ABE_MCBSP3,
+	.parent = "func_mcbsp3_gfclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk mcbsp3_mod_ck = {
+	.name = "mcbsp3_mod_ck",
+	.clkdm_name = "abe_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &mcbsp3_mod_ck_data,
+};
+
+static struct ti_clk_hwmod slimbus1_mod_ck_data = {
+	.reg = OMAP44XX_ABE_SLIMBUS1,
+	.parent = "slimbus1_fclk_0",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk slimbus1_mod_ck = {
+	.name = "slimbus1_mod_ck",
+	.clkdm_name = "abe_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &slimbus1_mod_ck_data,
+};
+
+static const char * const timer5_mod_ck_parents[] = {
+	"syc_clk_div_ck",
+	"sys_32k_ck",
+};
+
+static struct ti_clk_hwmod_mux timer5_mod_ck_data = {
+	.mod_reg = OMAP44XX_ABE_TIMER5,
+	.mux_reg = OMAP44XX_ABE_TIMER5,
+	.shift = 24,
+	.parents = timer5_mod_ck_parents,
+	.num_parents = ARRAY_SIZE(timer5_mod_ck_parents),
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk timer5_mod_ck = {
+	.name = "timer5_mod_ck",
+	.clkdm_name = "abe_clkdm",
+	.type = TI_CLK_HWMOD_MUX,
+	.data = &timer5_mod_ck_data,
+};
+
+static const char * const timer6_mod_ck_parents[] = {
+	"syc_clk_div_ck",
+	"sys_32k_ck",
+};
+
+static struct ti_clk_hwmod_mux timer6_mod_ck_data = {
+	.mod_reg = OMAP44XX_ABE_TIMER6,
+	.mux_reg = OMAP44XX_ABE_TIMER6,
+	.shift = 24,
+	.parents = timer6_mod_ck_parents,
+	.num_parents = ARRAY_SIZE(timer6_mod_ck_parents),
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk timer6_mod_ck = {
+	.name = "timer6_mod_ck",
+	.clkdm_name = "abe_clkdm",
+	.type = TI_CLK_HWMOD_MUX,
+	.data = &timer6_mod_ck_data,
+};
+
+static const char * const timer7_mod_ck_parents[] = {
+	"syc_clk_div_ck",
+	"sys_32k_ck",
+};
+
+static struct ti_clk_hwmod_mux timer7_mod_ck_data = {
+	.mod_reg = OMAP44XX_ABE_TIMER7,
+	.mux_reg = OMAP44XX_ABE_TIMER7,
+	.shift = 24,
+	.parents = timer7_mod_ck_parents,
+	.num_parents = ARRAY_SIZE(timer7_mod_ck_parents),
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk timer7_mod_ck = {
+	.name = "timer7_mod_ck",
+	.clkdm_name = "abe_clkdm",
+	.type = TI_CLK_HWMOD_MUX,
+	.data = &timer7_mod_ck_data,
+};
+
+static const char * const timer8_mod_ck_parents[] = {
+	"syc_clk_div_ck",
+	"sys_32k_ck",
+};
+
+static struct ti_clk_hwmod_mux timer8_mod_ck_data = {
+	.mod_reg = OMAP44XX_ABE_TIMER8,
+	.mux_reg = OMAP44XX_ABE_TIMER8,
+	.shift = 24,
+	.parents = timer8_mod_ck_parents,
+	.num_parents = ARRAY_SIZE(timer8_mod_ck_parents),
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk timer8_mod_ck = {
+	.name = "timer8_mod_ck",
+	.clkdm_name = "abe_clkdm",
+	.type = TI_CLK_HWMOD_MUX,
+	.data = &timer8_mod_ck_data,
+};
+
+static struct ti_clk_hwmod wd_timer3_mod_ck_data = {
+	.reg = OMAP44XX_ABE_WD_TIMER3,
+	.parent = "sys_32k_ck",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk wd_timer3_mod_ck = {
+	.name = "wd_timer3_mod_ck",
+	.clkdm_name = "abe_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &wd_timer3_mod_ck_data,
+};
+
+static struct ti_clk_hwmod l4_wkup_mod_ck_data = {
+	.reg = OMAP44XX_L4_WKUP_L4_WKUP,
+	.parent = "l4_wkup_clk_mux_ck",
+};
+
+static struct ti_clk l4_wkup_mod_ck = {
+	.name = "l4_wkup_mod_ck",
+	.clkdm_name = "l4_wkup_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &l4_wkup_mod_ck_data,
+};
+
+static struct ti_clk_hwmod wd_timer2_mod_ck_data = {
+	.reg = OMAP44XX_L4_WKUP_WD_TIMER2,
+	.parent = "sys_32k_ck",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk wd_timer2_mod_ck = {
+	.name = "wd_timer2_mod_ck",
+	.clkdm_name = "l4_wkup_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &wd_timer2_mod_ck_data,
+};
+
+static struct ti_clk_hwmod gpio1_mod_ck_data = {
+	.reg = OMAP44XX_L4_WKUP_GPIO1,
+	.parent = "l4_wkup_clk_mux_ck",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk gpio1_mod_ck = {
+	.name = "gpio1_mod_ck",
+	.clkdm_name = "l4_wkup_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &gpio1_mod_ck_data,
+};
+
+static const char * const timer1_mod_ck_parents[] = {
+	"sys_clkin_ck",
+	"sys_32k_ck",
+};
+
+static struct ti_clk_hwmod_mux timer1_mod_ck_data = {
+	.mod_reg = OMAP44XX_L4_WKUP_TIMER1,
+	.mux_reg = OMAP44XX_L4_WKUP_TIMER1,
+	.shift = 24,
+	.parents = timer1_mod_ck_parents,
+	.num_parents = ARRAY_SIZE(timer1_mod_ck_parents),
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk timer1_mod_ck = {
+	.name = "timer1_mod_ck",
+	.clkdm_name = "l4_wkup_clkdm",
+	.type = TI_CLK_HWMOD_MUX,
+	.data = &timer1_mod_ck_data,
+};
+
+static struct ti_clk_hwmod counter_32k_mod_ck_data = {
+	.reg = OMAP44XX_L4_WKUP_COUNTER_32K,
+	.parent = "sys_32k_ck",
+};
+
+static struct ti_clk counter_32k_mod_ck = {
+	.name = "counter_32k_mod_ck",
+	.clkdm_name = "l4_wkup_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &counter_32k_mod_ck_data,
+};
+
+static struct ti_clk_hwmod kbd_mod_ck_data = {
+	.reg = OMAP44XX_L4_WKUP_KBD,
+	.parent = "sys_32k_ck",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk kbd_mod_ck = {
+	.name = "kbd_mod_ck",
+	.clkdm_name = "l4_wkup_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &kbd_mod_ck_data,
+};
+
+static struct ti_clk_hwmod debugss_mod_ck_data = {
+	.reg = OMAP44XX_EMU_SYS_DEBUGSS,
+	.parent = "trace_clk_div_ck",
+};
+
+static struct ti_clk debugss_mod_ck = {
+	.name = "debugss_mod_ck",
+	.clkdm_name = "emu_sys_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &debugss_mod_ck_data,
+};
+
+static struct ti_clk_hwmod dss_core_mod_ck_data = {
+	.reg = OMAP44XX_L3_DSS_DSS_CORE,
+	.parent = "dss_dss_clk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk dss_core_mod_ck = {
+	.name = "dss_core_mod_ck",
+	.clkdm_name = "l3_dss_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &dss_core_mod_ck_data,
+};
+
+static struct ti_clk_hwmod dss_venc_mod_ck_data = {
+	.reg = OMAP44XX_L3_DSS_DSS_VENC,
+	.parent = "dss_tv_clk",
+};
+
+static struct ti_clk dss_venc_mod_ck = {
+	.name = "dss_venc_mod_ck",
+	.clkdm_name = "l3_dss_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &dss_venc_mod_ck_data,
+};
+
+static struct ti_clk_hwmod dss_dispc_mod_ck_data = {
+	.reg = OMAP44XX_L3_DSS_DSS_DISPC,
+	.parent = "dss_dss_clk",
+};
+
+static struct ti_clk dss_dispc_mod_ck = {
+	.name = "dss_dispc_mod_ck",
+	.clkdm_name = "l3_dss_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &dss_dispc_mod_ck_data,
+};
+
+static struct ti_clk_hwmod dss_dsi1_mod_ck_data = {
+	.reg = OMAP44XX_L3_DSS_DSS_DSI1,
+	.parent = "dss_dss_clk",
+};
+
+static struct ti_clk dss_dsi1_mod_ck = {
+	.name = "dss_dsi1_mod_ck",
+	.clkdm_name = "l3_dss_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &dss_dsi1_mod_ck_data,
+};
+
+static struct ti_clk_hwmod dss_rfbi_mod_ck_data = {
+	.reg = OMAP44XX_L3_DSS_DSS_RFBI,
+	.parent = "dss_dss_clk",
+};
+
+static struct ti_clk dss_rfbi_mod_ck = {
+	.name = "dss_rfbi_mod_ck",
+	.clkdm_name = "l3_dss_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &dss_rfbi_mod_ck_data,
+};
+
+static struct ti_clk_hwmod dss_dsi2_mod_ck_data = {
+	.reg = OMAP44XX_L3_DSS_DSS_DSI2,
+	.parent = "dss_dss_clk",
+};
+
+static struct ti_clk dss_dsi2_mod_ck = {
+	.name = "dss_dsi2_mod_ck",
+	.clkdm_name = "l3_dss_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &dss_dsi2_mod_ck_data,
+};
+
+static struct ti_clk_hwmod dss_hdmi_mod_ck_data = {
+	.reg = OMAP44XX_L3_DSS_DSS_HDMI,
+	.parent = "dss_48mhz_clk",
+};
+
+static struct ti_clk dss_hdmi_mod_ck = {
+	.name = "dss_hdmi_mod_ck",
+	.clkdm_name = "l3_dss_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &dss_hdmi_mod_ck_data,
+};
+
+static struct ti_clk_hwmod fdif_mod_ck_data = {
+	.reg = OMAP44XX_ISS_FDIF,
+	.parent = "fdif_fck",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk fdif_mod_ck = {
+	.name = "fdif_mod_ck",
+	.clkdm_name = "iss_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &fdif_mod_ck_data,
+};
+
+static struct ti_clk_hwmod gpio2_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_GPIO2,
+	.parent = "l4_div_ck",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk gpio2_mod_ck = {
+	.name = "gpio2_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &gpio2_mod_ck_data,
+};
+
+static struct ti_clk_hwmod gpio3_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_GPIO3,
+	.parent = "l4_div_ck",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk gpio3_mod_ck = {
+	.name = "gpio3_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &gpio3_mod_ck_data,
+};
+
+static struct ti_clk_hwmod gpio4_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_GPIO4,
+	.parent = "l4_div_ck",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk gpio4_mod_ck = {
+	.name = "gpio4_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &gpio4_mod_ck_data,
+};
+
+static struct ti_clk_hwmod gpio5_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_GPIO5,
+	.parent = "l4_div_ck",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk gpio5_mod_ck = {
+	.name = "gpio5_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &gpio5_mod_ck_data,
+};
+
+static struct ti_clk_hwmod gpio6_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_GPIO6,
+	.parent = "l4_div_ck",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk gpio6_mod_ck = {
+	.name = "gpio6_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &gpio6_mod_ck_data,
+};
+
+static struct ti_clk_hwmod hdq1w_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_HDQ1W,
+	.parent = "func_12m_fclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk hdq1w_mod_ck = {
+	.name = "hdq1w_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &hdq1w_mod_ck_data,
+};
+
+static struct ti_clk_hwmod i2c1_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_I2C1,
+	.parent = "func_96m_fclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk i2c1_mod_ck = {
+	.name = "i2c1_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &i2c1_mod_ck_data,
+};
+
+static struct ti_clk_hwmod i2c2_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_I2C2,
+	.parent = "func_96m_fclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk i2c2_mod_ck = {
+	.name = "i2c2_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &i2c2_mod_ck_data,
+};
+
+static struct ti_clk_hwmod i2c3_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_I2C3,
+	.parent = "func_96m_fclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk i2c3_mod_ck = {
+	.name = "i2c3_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &i2c3_mod_ck_data,
+};
+
+static struct ti_clk_hwmod i2c4_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_I2C4,
+	.parent = "func_96m_fclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk i2c4_mod_ck = {
+	.name = "i2c4_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &i2c4_mod_ck_data,
+};
+
+static struct ti_clk_hwmod l4_per_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_L4_PER,
+	.parent = "l4_div_ck",
+};
+
+static struct ti_clk l4_per_mod_ck = {
+	.name = "l4_per_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &l4_per_mod_ck_data,
+};
+
+static struct ti_clk_hwmod gpu_mod_ck_data = {
+	.reg = OMAP44XX_L3_GFX_GPU,
+	.parent = "sgx_clk_mux",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk gpu_mod_ck = {
+	.name = "gpu_mod_ck",
+	.clkdm_name = "l3_gfx_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &gpu_mod_ck_data,
+};
+
+static struct ti_clk_hwmod hsi_mod_ck_data = {
+	.reg = OMAP44XX_L3_INIT_HSI,
+	.parent = "hsi_fck",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk hsi_mod_ck = {
+	.name = "hsi_mod_ck",
+	.clkdm_name = "l3_init_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &hsi_mod_ck_data,
+};
+
+static struct ti_clk_hwmod iss_mod_ck_data = {
+	.reg = OMAP44XX_ISS_ISS,
+	.parent = "ducati_clk_mux_ck",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk iss_mod_ck = {
+	.name = "iss_mod_ck",
+	.clkdm_name = "iss_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &iss_mod_ck_data,
+};
+
+static struct ti_clk_hwmod mcbsp4_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_MCBSP4,
+	.parent = "per_mcbsp4_gfclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk mcbsp4_mod_ck = {
+	.name = "mcbsp4_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &mcbsp4_mod_ck_data,
+};
+
+static struct ti_clk_hwmod mcspi1_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_MCSPI1,
+	.parent = "func_48m_fclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk mcspi1_mod_ck = {
+	.name = "mcspi1_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &mcspi1_mod_ck_data,
+};
+
+static struct ti_clk_hwmod mcspi2_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_MCSPI2,
+	.parent = "func_48m_fclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk mcspi2_mod_ck = {
+	.name = "mcspi2_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &mcspi2_mod_ck_data,
+};
+
+static struct ti_clk_hwmod mcspi3_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_MCSPI3,
+	.parent = "func_48m_fclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk mcspi3_mod_ck = {
+	.name = "mcspi3_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &mcspi3_mod_ck_data,
+};
+
+static struct ti_clk_hwmod mcspi4_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_MCSPI4,
+	.parent = "func_48m_fclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk mcspi4_mod_ck = {
+	.name = "mcspi4_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &mcspi4_mod_ck_data,
+};
+
+static struct ti_clk_hwmod mmc3_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_MMC3,
+	.parent = "func_48m_fclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk mmc3_mod_ck = {
+	.name = "mmc3_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &mmc3_mod_ck_data,
+};
+
+static struct ti_clk_hwmod mmc4_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_MMC4,
+	.parent = "func_48m_fclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk mmc4_mod_ck = {
+	.name = "mmc4_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &mmc4_mod_ck_data,
+};
+
+static struct ti_clk_hwmod mmc1_mod_ck_data = {
+	.reg = OMAP44XX_L3_INIT_MMC1,
+	.parent = "hsmmc1_fclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk mmc1_mod_ck = {
+	.name = "mmc1_mod_ck",
+	.clkdm_name = "l3_init_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &mmc1_mod_ck_data,
+};
+
+static struct ti_clk_hwmod mmc2_mod_ck_data = {
+	.reg = OMAP44XX_L3_INIT_MMC2,
+	.parent = "hsmmc2_fclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk mmc2_mod_ck = {
+	.name = "mmc2_mod_ck",
+	.clkdm_name = "l3_init_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &mmc2_mod_ck_data,
+};
+
+static struct ti_clk_hwmod ocp2scp_usb_phy_mod_ck_data = {
+	.reg = OMAP44XX_L3_INIT_OCP2SCP_USB_PHY,
+	.parent = "ocp2scp_usb_phy_phy_48m",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk ocp2scp_usb_phy_mod_ck = {
+	.name = "ocp2scp_usb_phy_mod_ck",
+	.clkdm_name = "l3_init_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &ocp2scp_usb_phy_mod_ck_data,
+};
+
+static const char * const timer10_mod_ck_parents[] = {
+	"sys_clkin_ck",
+	"sys_32k_ck",
+};
+
+static struct ti_clk_hwmod_mux timer10_mod_ck_data = {
+	.mod_reg = OMAP44XX_L4_PER_TIMER10,
+	.mux_reg = OMAP44XX_L4_PER_TIMER10,
+	.shift = 24,
+	.parents = timer10_mod_ck_parents,
+	.num_parents = ARRAY_SIZE(timer10_mod_ck_parents),
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk timer10_mod_ck = {
+	.name = "timer10_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD_MUX,
+	.data = &timer10_mod_ck_data,
+};
+
+static const char * const timer11_mod_ck_parents[] = {
+	"sys_clkin_ck",
+	"sys_32k_ck",
+};
+
+static struct ti_clk_hwmod_mux timer11_mod_ck_data = {
+	.mod_reg = OMAP44XX_L4_PER_TIMER11,
+	.mux_reg = OMAP44XX_L4_PER_TIMER11,
+	.shift = 24,
+	.parents = timer11_mod_ck_parents,
+	.num_parents = ARRAY_SIZE(timer11_mod_ck_parents),
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk timer11_mod_ck = {
+	.name = "timer11_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD_MUX,
+	.data = &timer11_mod_ck_data,
+};
+
+static const char * const timer2_mod_ck_parents[] = {
+	"sys_clkin_ck",
+	"sys_32k_ck",
+};
+
+static struct ti_clk_hwmod_mux timer2_mod_ck_data = {
+	.mod_reg = OMAP44XX_L4_PER_TIMER2,
+	.mux_reg = OMAP44XX_L4_PER_TIMER2,
+	.shift = 24,
+	.parents = timer2_mod_ck_parents,
+	.num_parents = ARRAY_SIZE(timer2_mod_ck_parents),
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk timer2_mod_ck = {
+	.name = "timer2_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD_MUX,
+	.data = &timer2_mod_ck_data,
+};
+
+static const char * const timer3_mod_ck_parents[] = {
+	"sys_clkin_ck",
+	"sys_32k_ck",
+};
+
+static struct ti_clk_hwmod_mux timer3_mod_ck_data = {
+	.mod_reg = OMAP44XX_L4_PER_TIMER3,
+	.mux_reg = OMAP44XX_L4_PER_TIMER3,
+	.shift = 24,
+	.parents = timer3_mod_ck_parents,
+	.num_parents = ARRAY_SIZE(timer3_mod_ck_parents),
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk timer3_mod_ck = {
+	.name = "timer3_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD_MUX,
+	.data = &timer3_mod_ck_data,
+};
+
+static const char * const timer4_mod_ck_parents[] = {
+	"sys_clkin_ck",
+	"sys_32k_ck",
+};
+
+static struct ti_clk_hwmod_mux timer4_mod_ck_data = {
+	.mod_reg = OMAP44XX_L4_PER_TIMER4,
+	.mux_reg = OMAP44XX_L4_PER_TIMER4,
+	.shift = 24,
+	.parents = timer4_mod_ck_parents,
+	.num_parents = ARRAY_SIZE(timer4_mod_ck_parents),
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk timer4_mod_ck = {
+	.name = "timer4_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD_MUX,
+	.data = &timer4_mod_ck_data,
+};
+
+static const char * const timer9_mod_ck_parents[] = {
+	"sys_clkin_ck",
+	"sys_32k_ck",
+};
+
+static struct ti_clk_hwmod_mux timer9_mod_ck_data = {
+	.mod_reg = OMAP44XX_L4_PER_TIMER9,
+	.mux_reg = OMAP44XX_L4_PER_TIMER9,
+	.shift = 24,
+	.parents = timer9_mod_ck_parents,
+	.num_parents = ARRAY_SIZE(timer9_mod_ck_parents),
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk timer9_mod_ck = {
+	.name = "timer9_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD_MUX,
+	.data = &timer9_mod_ck_data,
+};
+
+static struct ti_clk_hwmod elm_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_ELM,
+	.parent = "l4_div_ck",
+};
+
+static struct ti_clk elm_mod_ck = {
+	.name = "elm_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &elm_mod_ck_data,
+};
+
+static struct ti_clk_hwmod slimbus2_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_SLIMBUS2,
+	.parent = "slimbus2_fclk_0",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk slimbus2_mod_ck = {
+	.name = "slimbus2_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &slimbus2_mod_ck_data,
+};
+
+static struct ti_clk_hwmod uart1_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_UART1,
+	.parent = "func_48m_fclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk uart1_mod_ck = {
+	.name = "uart1_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &uart1_mod_ck_data,
+};
+
+static struct ti_clk_hwmod uart2_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_UART2,
+	.parent = "func_48m_fclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk uart2_mod_ck = {
+	.name = "uart2_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &uart2_mod_ck_data,
+};
+
+static struct ti_clk_hwmod uart3_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_UART3,
+	.parent = "func_48m_fclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk uart3_mod_ck = {
+	.name = "uart3_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &uart3_mod_ck_data,
+};
+
+static struct ti_clk_hwmod uart4_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_UART4,
+	.parent = "func_48m_fclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk uart4_mod_ck = {
+	.name = "uart4_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &uart4_mod_ck_data,
+};
+
+static struct ti_clk_hwmod mmc5_mod_ck_data = {
+	.reg = OMAP44XX_L4_PER_MMC5,
+	.parent = "func_48m_fclk",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk mmc5_mod_ck = {
+	.name = "mmc5_mod_ck",
+	.clkdm_name = "l4_per_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &mmc5_mod_ck_data,
+};
+
+static struct ti_clk_hwmod smartreflex_core_mod_ck_data = {
+	.reg = OMAP44XX_L4_AO_SMARTREFLEX_CORE,
+	.parent = "smartreflex_core_fck",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk smartreflex_core_mod_ck = {
+	.name = "smartreflex_core_mod_ck",
+	.clkdm_name = "l4_ao_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &smartreflex_core_mod_ck_data,
+};
+
+static struct ti_clk_hwmod smartreflex_iva_mod_ck_data = {
+	.reg = OMAP44XX_L4_AO_SMARTREFLEX_IVA,
+	.parent = "smartreflex_iva_fck",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk smartreflex_iva_mod_ck = {
+	.name = "smartreflex_iva_mod_ck",
+	.clkdm_name = "l4_ao_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &smartreflex_iva_mod_ck_data,
+};
+
+static struct ti_clk_hwmod smartreflex_mpu_mod_ck_data = {
+	.reg = OMAP44XX_L4_AO_SMARTREFLEX_MPU,
+	.parent = "smartreflex_mpu_fck",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk smartreflex_mpu_mod_ck = {
+	.name = "smartreflex_mpu_mod_ck",
+	.clkdm_name = "l4_ao_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &smartreflex_mpu_mod_ck_data,
+};
+
+static struct ti_clk_hwmod usb_host_fs_mod_ck_data = {
+	.reg = OMAP44XX_L3_INIT_USB_HOST_FS,
+	.parent = "usb_host_fs_fck",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk usb_host_fs_mod_ck = {
+	.name = "usb_host_fs_mod_ck",
+	.clkdm_name = "l3_init_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &usb_host_fs_mod_ck_data,
+};
+
+static struct ti_clk_hwmod usb_host_hs_mod_ck_data = {
+	.reg = OMAP44XX_L3_INIT_USB_HOST_HS,
+	.parent = "usb_host_hs_fck",
+	.flags = CLKF_SW_SUP,
+};
+
+static struct ti_clk usb_host_hs_mod_ck = {
+	.name = "usb_host_hs_mod_ck",
+	.clkdm_name = "l3_init_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &usb_host_hs_mod_ck_data,
+};
+
+static struct ti_clk_hwmod usb_otg_hs_mod_ck_data = {
+	.reg = OMAP44XX_L3_INIT_USB_OTG_HS,
+	.parent = "usb_otg_hs_ick",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk usb_otg_hs_mod_ck = {
+	.name = "usb_otg_hs_mod_ck",
+	.clkdm_name = "l3_init_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &usb_otg_hs_mod_ck_data,
+};
+
+static struct ti_clk_hwmod l3_main_1_mod_ck_data = {
+	.reg = OMAP44XX_L3_1_L3_MAIN_1,
+	.parent = "l3_div_ck",
+};
+
+static struct ti_clk l3_main_1_mod_ck = {
+	.name = "l3_main_1_mod_ck",
+	.clkdm_name = "l3_1_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &l3_main_1_mod_ck_data,
+};
+
+static struct ti_clk_hwmod l3_main_2_mod_ck_data = {
+	.reg = OMAP44XX_L3_2_L3_MAIN_2,
+	.parent = "l3_div_ck",
+};
+
+static struct ti_clk l3_main_2_mod_ck = {
+	.name = "l3_main_2_mod_ck",
+	.clkdm_name = "l3_2_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &l3_main_2_mod_ck_data,
+};
+
+static struct ti_clk_hwmod gpmc_mod_ck_data = {
+	.reg = OMAP44XX_L3_2_GPMC,
+	.parent = "l3_div_ck",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk gpmc_mod_ck = {
+	.name = "gpmc_mod_ck",
+	.clkdm_name = "l3_2_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &gpmc_mod_ck_data,
+};
+
+static struct ti_clk_hwmod ocmc_ram_mod_ck_data = {
+	.reg = OMAP44XX_L3_2_OCMC_RAM,
+	.parent = "l3_div_ck",
+};
+
+static struct ti_clk ocmc_ram_mod_ck = {
+	.name = "ocmc_ram_mod_ck",
+	.clkdm_name = "l3_2_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &ocmc_ram_mod_ck_data,
+};
+
+static struct ti_clk_hwmod ipu_mod_ck_data = {
+	.reg = OMAP44XX_DUCATI_IPU,
+	.parent = "ducati_clk_mux_ck",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk ipu_mod_ck = {
+	.name = "ipu_mod_ck",
+	.clkdm_name = "ducati_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &ipu_mod_ck_data,
+};
+
+static struct ti_clk_hwmod mmu_ipu_mod_ck_data = {
+	.reg = OMAP44XX_DUCATI_MMU_IPU,
+	.parent = "ducati_clk_mux_ck",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk mmu_ipu_mod_ck = {
+	.name = "mmu_ipu_mod_ck",
+	.clkdm_name = "ducati_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &mmu_ipu_mod_ck_data,
+};
+
+static struct ti_clk_hwmod dma_system_mod_ck_data = {
+	.reg = OMAP44XX_L3_DMA_DMA_SYSTEM,
+	.parent = "l3_div_ck",
+};
+
+static struct ti_clk dma_system_mod_ck = {
+	.name = "dma_system_mod_ck",
+	.clkdm_name = "l3_dma_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &dma_system_mod_ck_data,
+};
+
+static struct ti_clk_hwmod dmm_mod_ck_data = {
+	.reg = OMAP44XX_L3_EMIF_DMM,
+	.parent = "l3_div_ck",
+};
+
+static struct ti_clk dmm_mod_ck = {
+	.name = "dmm_mod_ck",
+	.clkdm_name = "l3_emif_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &dmm_mod_ck_data,
+};
+
+static struct ti_clk_hwmod emif1_mod_ck_data = {
+	.reg = OMAP44XX_L3_EMIF_EMIF1,
+	.parent = "ddrphy_ck",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk emif1_mod_ck = {
+	.name = "emif1_mod_ck",
+	.clkdm_name = "l3_emif_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &emif1_mod_ck_data,
+};
+
+static struct ti_clk_hwmod emif2_mod_ck_data = {
+	.reg = OMAP44XX_L3_EMIF_EMIF2,
+	.parent = "ddrphy_ck",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk emif2_mod_ck = {
+	.name = "emif2_mod_ck",
+	.clkdm_name = "l3_emif_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &emif2_mod_ck_data,
+};
+
+static struct ti_clk_hwmod c2c_mod_ck_data = {
+	.reg = OMAP44XX_D2D_C2C,
+	.parent = "div_core_ck",
+};
+
+static struct ti_clk c2c_mod_ck = {
+	.name = "c2c_mod_ck",
+	.clkdm_name = "d2d_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &c2c_mod_ck_data,
+};
+
+static struct ti_clk_hwmod l4_cfg_mod_ck_data = {
+	.reg = OMAP44XX_L4_CFG_L4_CFG,
+	.parent = "l4_div_ck",
+};
+
+static struct ti_clk l4_cfg_mod_ck = {
+	.name = "l4_cfg_mod_ck",
+	.clkdm_name = "l4_cfg_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &l4_cfg_mod_ck_data,
+};
+
+static struct ti_clk_hwmod spinlock_mod_ck_data = {
+	.reg = OMAP44XX_L4_CFG_SPINLOCK,
+	.parent = "l4_div_ck",
+};
+
+static struct ti_clk spinlock_mod_ck = {
+	.name = "spinlock_mod_ck",
+	.clkdm_name = "l4_cfg_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &spinlock_mod_ck_data,
+};
+
+static struct ti_clk_hwmod mailbox_mod_ck_data = {
+	.reg = OMAP44XX_L4_CFG_MAILBOX,
+	.parent = "l4_div_ck",
+};
+
+static struct ti_clk mailbox_mod_ck = {
+	.name = "mailbox_mod_ck",
+	.clkdm_name = "l4_cfg_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &mailbox_mod_ck_data,
+};
+
+static struct ti_clk_hwmod l3_main_3_mod_ck_data = {
+	.reg = OMAP44XX_L3_INSTR_L3_MAIN_3,
+	.parent = "l3_div_ck",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk l3_main_3_mod_ck = {
+	.name = "l3_main_3_mod_ck",
+	.clkdm_name = "l3_instr_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &l3_main_3_mod_ck_data,
+};
+
+static struct ti_clk_hwmod l3_instr_mod_ck_data = {
+	.reg = OMAP44XX_L3_INSTR_L3_INSTR,
+	.parent = "l3_div_ck",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk l3_instr_mod_ck = {
+	.name = "l3_instr_mod_ck",
+	.clkdm_name = "l3_instr_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &l3_instr_mod_ck_data,
+};
+
+static struct ti_clk_hwmod ocp_wp_noc_mod_ck_data = {
+	.reg = OMAP44XX_L3_INSTR_OCP_WP_NOC,
+	.parent = "l3_div_ck",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk ocp_wp_noc_mod_ck = {
+	.name = "ocp_wp_noc_mod_ck",
+	.clkdm_name = "l3_instr_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &ocp_wp_noc_mod_ck_data,
+};
+
+static struct ti_clk_hwmod iva_mod_ck_data = {
+	.reg = OMAP44XX_IVAHD_IVA,
+	.parent = "dpll_iva_m5x2_ck",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk iva_mod_ck = {
+	.name = "iva_mod_ck",
+	.clkdm_name = "ivahd_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &iva_mod_ck_data,
+};
+
+static struct ti_clk_hwmod sl2if_mod_ck_data = {
+	.reg = OMAP44XX_IVAHD_SL2IF,
+	.parent = "dpll_iva_m5x2_ck",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk sl2if_mod_ck = {
+	.name = "sl2if_mod_ck",
+	.clkdm_name = "ivahd_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &sl2if_mod_ck_data,
+};
+
+static struct ti_clk_hwmod usb_tll_hs_mod_ck_data = {
+	.reg = OMAP44XX_L3_INIT_USB_TLL_HS,
+	.parent = "usb_tll_hs_ick",
+	.flags = CLKF_HW_SUP,
+};
+
+static struct ti_clk usb_tll_hs_mod_ck = {
+	.name = "usb_tll_hs_mod_ck",
+	.clkdm_name = "l3_init_clkdm",
+	.type = TI_CLK_HWMOD,
+	.data = &usb_tll_hs_mod_ck_data,
+};
+
+static struct ti_clk_alias omap44xx_hwmod_clks[] = {
+	CLK(NULL, "mpu_mod_ck", &mpu_mod_ck),
+	CLK(NULL, "dsp_mod_ck", &dsp_mod_ck),
+	CLK(NULL, "mmu_dsp_mod_ck", &mmu_dsp_mod_ck),
+	CLK(NULL, "l4_abe_mod_ck", &l4_abe_mod_ck),
+	CLK(NULL, "aess_mod_ck", &aess_mod_ck),
+	CLK(NULL, "mcpdm_mod_ck", &mcpdm_mod_ck),
+	CLK(NULL, "dmic_mod_ck", &dmic_mod_ck),
+	CLK(NULL, "mcasp_mod_ck", &mcasp_mod_ck),
+	CLK(NULL, "mcbsp1_mod_ck", &mcbsp1_mod_ck),
+	CLK(NULL, "mcbsp2_mod_ck", &mcbsp2_mod_ck),
+	CLK(NULL, "mcbsp3_mod_ck", &mcbsp3_mod_ck),
+	CLK(NULL, "slimbus1_mod_ck", &slimbus1_mod_ck),
+	CLK(NULL, "timer5_mod_ck", &timer5_mod_ck),
+	CLK(NULL, "timer6_mod_ck", &timer6_mod_ck),
+	CLK(NULL, "timer7_mod_ck", &timer7_mod_ck),
+	CLK(NULL, "timer8_mod_ck", &timer8_mod_ck),
+	CLK(NULL, "wd_timer3_mod_ck", &wd_timer3_mod_ck),
+	CLK(NULL, "l4_wkup_mod_ck", &l4_wkup_mod_ck),
+	CLK(NULL, "wd_timer2_mod_ck", &wd_timer2_mod_ck),
+	CLK(NULL, "gpio1_mod_ck", &gpio1_mod_ck),
+	CLK(NULL, "timer1_mod_ck", &timer1_mod_ck),
+	CLK(NULL, "counter_32k_mod_ck", &counter_32k_mod_ck),
+	CLK(NULL, "kbd_mod_ck", &kbd_mod_ck),
+	CLK(NULL, "debugss_mod_ck", &debugss_mod_ck),
+	CLK(NULL, "dss_core_mod_ck", &dss_core_mod_ck),
+	CLK(NULL, "dss_venc_mod_ck", &dss_venc_mod_ck),
+	CLK(NULL, "dss_dispc_mod_ck", &dss_dispc_mod_ck),
+	CLK(NULL, "dss_dsi1_mod_ck", &dss_dsi1_mod_ck),
+	CLK(NULL, "dss_rfbi_mod_ck", &dss_rfbi_mod_ck),
+	CLK(NULL, "dss_dsi2_mod_ck", &dss_dsi2_mod_ck),
+	CLK(NULL, "dss_hdmi_mod_ck", &dss_hdmi_mod_ck),
+	CLK(NULL, "fdif_mod_ck", &fdif_mod_ck),
+	CLK(NULL, "gpio2_mod_ck", &gpio2_mod_ck),
+	CLK(NULL, "gpio3_mod_ck", &gpio3_mod_ck),
+	CLK(NULL, "gpio4_mod_ck", &gpio4_mod_ck),
+	CLK(NULL, "gpio5_mod_ck", &gpio5_mod_ck),
+	CLK(NULL, "gpio6_mod_ck", &gpio6_mod_ck),
+	CLK(NULL, "hdq1w_mod_ck", &hdq1w_mod_ck),
+	CLK(NULL, "i2c1_mod_ck", &i2c1_mod_ck),
+	CLK(NULL, "i2c2_mod_ck", &i2c2_mod_ck),
+	CLK(NULL, "i2c3_mod_ck", &i2c3_mod_ck),
+	CLK(NULL, "i2c4_mod_ck", &i2c4_mod_ck),
+	CLK(NULL, "l4_per_mod_ck", &l4_per_mod_ck),
+	CLK(NULL, "gpu_mod_ck", &gpu_mod_ck),
+	CLK(NULL, "hsi_mod_ck", &hsi_mod_ck),
+	CLK(NULL, "iss_mod_ck", &iss_mod_ck),
+	CLK(NULL, "mcbsp4_mod_ck", &mcbsp4_mod_ck),
+	CLK(NULL, "mcspi1_mod_ck", &mcspi1_mod_ck),
+	CLK(NULL, "mcspi2_mod_ck", &mcspi2_mod_ck),
+	CLK(NULL, "mcspi3_mod_ck", &mcspi3_mod_ck),
+	CLK(NULL, "mcspi4_mod_ck", &mcspi4_mod_ck),
+	CLK(NULL, "mmc3_mod_ck", &mmc3_mod_ck),
+	CLK(NULL, "mmc4_mod_ck", &mmc4_mod_ck),
+	CLK(NULL, "mmc1_mod_ck", &mmc1_mod_ck),
+	CLK(NULL, "mmc2_mod_ck", &mmc2_mod_ck),
+	CLK(NULL, "ocp2scp_usb_phy_mod_ck", &ocp2scp_usb_phy_mod_ck),
+	CLK(NULL, "timer10_mod_ck", &timer10_mod_ck),
+	CLK(NULL, "timer11_mod_ck", &timer11_mod_ck),
+	CLK(NULL, "timer2_mod_ck", &timer2_mod_ck),
+	CLK(NULL, "timer3_mod_ck", &timer3_mod_ck),
+	CLK(NULL, "timer4_mod_ck", &timer4_mod_ck),
+	CLK(NULL, "timer9_mod_ck", &timer9_mod_ck),
+	CLK(NULL, "elm_mod_ck", &elm_mod_ck),
+	CLK(NULL, "slimbus2_mod_ck", &slimbus2_mod_ck),
+	CLK(NULL, "uart1_mod_ck", &uart1_mod_ck),
+	CLK(NULL, "uart2_mod_ck", &uart2_mod_ck),
+	CLK(NULL, "uart3_mod_ck", &uart3_mod_ck),
+	CLK(NULL, "uart4_mod_ck", &uart4_mod_ck),
+	CLK(NULL, "mmc5_mod_ck", &mmc5_mod_ck),
+	CLK(NULL, "smartreflex_core_mod_ck", &smartreflex_core_mod_ck),
+	CLK(NULL, "smartreflex_iva_mod_ck", &smartreflex_iva_mod_ck),
+	CLK(NULL, "smartreflex_mpu_mod_ck", &smartreflex_mpu_mod_ck),
+	CLK(NULL, "usb_host_fs_mod_ck", &usb_host_fs_mod_ck),
+	CLK(NULL, "usb_host_hs_mod_ck", &usb_host_hs_mod_ck),
+	CLK(NULL, "usb_otg_hs_mod_ck", &usb_otg_hs_mod_ck),
+	CLK(NULL, "l3_main_1_mod_ck", &l3_main_1_mod_ck),
+	CLK(NULL, "l3_main_2_mod_ck", &l3_main_2_mod_ck),
+	CLK(NULL, "gpmc_mod_ck", &gpmc_mod_ck),
+	CLK(NULL, "ocmc_ram_mod_ck", &ocmc_ram_mod_ck),
+	CLK(NULL, "ipu_mod_ck", &ipu_mod_ck),
+	CLK(NULL, "mmu_ipu_mod_ck", &mmu_ipu_mod_ck),
+	CLK(NULL, "dma_system_mod_ck", &dma_system_mod_ck),
+	CLK(NULL, "dmm_mod_ck", &dmm_mod_ck),
+	CLK(NULL, "emif1_mod_ck", &emif1_mod_ck),
+	CLK(NULL, "emif2_mod_ck", &emif2_mod_ck),
+	CLK(NULL, "c2c_mod_ck", &c2c_mod_ck),
+	CLK(NULL, "l4_cfg_mod_ck", &l4_cfg_mod_ck),
+	CLK(NULL, "spinlock_mod_ck", &spinlock_mod_ck),
+	CLK(NULL, "mailbox_mod_ck", &mailbox_mod_ck),
+	CLK(NULL, "l3_main_3_mod_ck", &l3_main_3_mod_ck),
+	CLK(NULL, "l3_instr_mod_ck", &l3_instr_mod_ck),
+	CLK(NULL, "ocp_wp_noc_mod_ck", &ocp_wp_noc_mod_ck),
+	CLK(NULL, "iva_mod_ck", &iva_mod_ck),
+	CLK(NULL, "sl2if_mod_ck", &sl2if_mod_ck),
+	CLK(NULL, "usb_tll_hs_mod_ck", &usb_tll_hs_mod_ck),
+	{ NULL },
+};
+
 static struct ti_dt_clk omap44xx_clks[] = {
 	DT_CLK(NULL, "extalt_clkin_ck", "extalt_clkin_ck"),
 	DT_CLK(NULL, "pad_clks_src_ck", "pad_clks_src_ck"),
@@ -276,6 +1677,8 @@ int __init omap4xxx_dt_clk_init(void)
 
 	ti_dt_clocks_register(omap44xx_clks);
 
+	ti_clk_register_clks(omap44xx_hwmod_clks);
+
 	omap2_clk_disable_autoidle_all();
 
 	/*
-- 
1.9.1

^ permalink raw reply related

* [PATCHv4 13/15] clk: ti: add support for omap4 module clocks
From: Tero Kristo @ 2016-10-18 15:46 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1476805568-19264-1-git-send-email-t-kristo@ti.com>

Previously, hwmod core has been used for controlling the hwmod level
clocks. This has certain drawbacks, like being unable to share the
clocks for multiple users, missing usecounting and generally being
totally incompatible with common clock framework.

Add support for new clock type under the TI clock driver, which will
be used to convert all the existing hwmod clocks to.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 drivers/clk/ti/Makefile   |   3 +-
 drivers/clk/ti/clk.c      |   6 +
 drivers/clk/ti/clkt_mod.c | 344 ++++++++++++++++++++++++++++++++++++++++++++++
 drivers/clk/ti/clock.h    |  24 ++++
 include/linux/clk/ti.h    |   2 +
 5 files changed, 378 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/ti/clkt_mod.c

diff --git a/drivers/clk/ti/Makefile b/drivers/clk/ti/Makefile
index 0deac98..15886ef 100644
--- a/drivers/clk/ti/Makefile
+++ b/drivers/clk/ti/Makefile
@@ -3,7 +3,8 @@ ifeq ($(CONFIG_ARCH_OMAP2PLUS), y)
 obj-y					+= clk.o autoidle.o clockdomain.o
 clk-common				= dpll.o composite.o divider.o gate.o \
 					  fixed-factor.o mux.o apll.o \
-					  clkt_dpll.o clkt_iclk.o clkt_dflt.o
+					  clkt_dpll.o clkt_iclk.o clkt_dflt.o \
+					  clkt_mod.o
 obj-$(CONFIG_SOC_AM33XX)		+= $(clk-common) clk-33xx.o dpll3xxx.o
 obj-$(CONFIG_SOC_TI81XX)		+= $(clk-common) fapll.o clk-814x.o clk-816x.o
 obj-$(CONFIG_ARCH_OMAP2)		+= $(clk-common) interface.o clk-2xxx.o
diff --git a/drivers/clk/ti/clk.c b/drivers/clk/ti/clk.c
index 8bebda4..3a75d8e 100644
--- a/drivers/clk/ti/clk.c
+++ b/drivers/clk/ti/clk.c
@@ -372,6 +372,12 @@ struct clk __init *ti_clk_register_clk(struct ti_clk *setup)
 	case TI_CLK_DPLL:
 		clk = ti_clk_register_dpll(setup);
 		break;
+	case TI_CLK_HWMOD:
+		clk = ti_clk_register_hwmod(setup);
+		break;
+	case TI_CLK_HWMOD_MUX:
+		clk = ti_clk_register_hwmod_mux(setup);
+		break;
 	default:
 		pr_err("bad type for %s!\n", setup->name);
 		clk = ERR_PTR(-EINVAL);
diff --git a/drivers/clk/ti/clkt_mod.c b/drivers/clk/ti/clkt_mod.c
new file mode 100644
index 0000000..dc86109
--- /dev/null
+++ b/drivers/clk/ti/clkt_mod.c
@@ -0,0 +1,344 @@
+/*
+ * OMAP hardware module clock support
+ *
+ * Copyright (C) 2015 Texas Instruments, Inc.
+ *
+ * Tero Kristo <t-kristo@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/slab.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/clk/ti.h>
+#include <linux/delay.h>
+#include "clock.h"
+
+#undef pr_fmt
+#define pr_fmt(fmt) "%s: " fmt, __func__
+
+#define NO_IDLEST			0x1
+
+#define OMAP4_MODULEMODE_MASK		0x3
+
+#define MODULEMODE_HWCTRL		0x1
+#define MODULEMODE_SWCTRL		0x2
+
+#define OMAP4_IDLEST_MASK		(0x3 << 16)
+#define OMAP4_IDLEST_SHIFT		16
+
+#define CLKCTRL_IDLEST_FUNCTIONAL	0x0
+#define CLKCTRL_IDLEST_INTERFACE_IDLE	0x2
+#define CLKCTRL_IDLEST_DISABLED		0x3
+
+/* These timeouts are in us */
+#define OMAP4_MAX_MODULE_READY_TIME	2000
+#define OMAP4_MAX_MODULE_DISABLE_TIME	5000
+
+static bool _early_timeout = true;
+
+union omap4_timeout {
+	u32 cycles;
+	ktime_t start;
+};
+
+static u32 _omap4_idlest(u32 val)
+{
+	val &= OMAP4_IDLEST_MASK;
+	val >>= OMAP4_IDLEST_SHIFT;
+
+	return val;
+}
+
+static bool _omap4_is_idle(u32 val)
+{
+	val = _omap4_idlest(val);
+
+	return val == CLKCTRL_IDLEST_DISABLED;
+}
+
+static bool _omap4_is_ready(u32 val)
+{
+	val = _omap4_idlest(val);
+
+	return val == CLKCTRL_IDLEST_FUNCTIONAL ||
+	       val == CLKCTRL_IDLEST_INTERFACE_IDLE;
+}
+
+static bool _omap4_is_timeout(union omap4_timeout *time, u32 timeout)
+{
+	if (unlikely(_early_timeout)) {
+		if (time->cycles++ < timeout) {
+			udelay(1);
+			return false;
+		}
+	} else {
+		if (!ktime_to_ns(time->start)) {
+			time->start = ktime_get();
+			return false;
+		}
+
+		if (ktime_us_delta(ktime_get(), time->start) < timeout) {
+			cpu_relax();
+			return false;
+		}
+	}
+
+	return true;
+}
+
+static int __init _omap4_disable_early_timeout(void)
+{
+	_early_timeout = false;
+
+	return 0;
+}
+arch_initcall(_omap4_disable_early_timeout);
+
+static int _omap4_hwmod_clk_enable(struct clk_hw *hw)
+{
+	struct clk_hw_omap *clk = to_clk_hw_omap(hw);
+	u32 val;
+	int ret;
+	union omap4_timeout timeout = { 0 };
+
+	if (!clk->enable_bit)
+		return 0;
+
+	if (clk->clkdm) {
+		ret = ti_clk_ll_ops->clkdm_clk_enable(clk->clkdm, hw->clk);
+		if (ret) {
+			WARN(1,
+			     "%s: could not enable %s's clockdomain %s: %d\n",
+			     __func__, clk_hw_get_name(hw),
+			     clk->clkdm_name, ret);
+			return ret;
+		}
+	}
+
+	val = ti_clk_ll_ops->clk_readl(clk->enable_reg);
+
+	val &= ~OMAP4_MODULEMODE_MASK;
+	val |= clk->enable_bit;
+
+	ti_clk_ll_ops->clk_writel(val, clk->enable_reg);
+
+	if (clk->flags & NO_IDLEST)
+		return 0;
+
+	/* Wait until module is enabled */
+	while (!_omap4_is_ready(ti_clk_ll_ops->clk_readl(clk->enable_reg))) {
+		if (_omap4_is_timeout(&timeout, OMAP4_MAX_MODULE_READY_TIME)) {
+			pr_err("%s: failed to enable\n", clk_hw_get_name(hw));
+			return -EBUSY;
+		}
+	}
+
+	return 0;
+}
+
+static void _omap4_hwmod_clk_disable(struct clk_hw *hw)
+{
+	struct clk_hw_omap *clk = to_clk_hw_omap(hw);
+	u32 val;
+	union omap4_timeout timeout = { 0 };
+
+	if (!clk->enable_bit)
+		return;
+
+	val = ti_clk_ll_ops->clk_readl(clk->enable_reg);
+
+	val &= ~OMAP4_MODULEMODE_MASK;
+
+	ti_clk_ll_ops->clk_writel(val, clk->enable_reg);
+
+	if (clk->flags & NO_IDLEST)
+		return;
+
+	/* Wait until module is disabled */
+	while (!_omap4_is_idle(ti_clk_ll_ops->clk_readl(clk->enable_reg))) {
+		if (_omap4_is_timeout(&timeout,
+				      OMAP4_MAX_MODULE_DISABLE_TIME)) {
+			pr_err("%s: failed to disable\n", clk_hw_get_name(hw));
+			break;
+		}
+	}
+
+	if (clk->clkdm)
+		ti_clk_ll_ops->clkdm_clk_disable(clk->clkdm, hw->clk);
+}
+
+static int _omap4_hwmod_clk_is_enabled(struct clk_hw *hw)
+{
+	struct clk_hw_omap *clk = to_clk_hw_omap(hw);
+	u32 val;
+
+	val = ti_clk_ll_ops->clk_readl(clk->enable_reg);
+
+	if (val & clk->enable_bit)
+		return 1;
+
+	return 0;
+}
+
+static const struct clk_ops omap4_module_clk_ops = {
+	.enable		= _omap4_hwmod_clk_enable,
+	.disable	= _omap4_hwmod_clk_disable,
+	.is_enabled	= _omap4_hwmod_clk_is_enabled,
+};
+
+struct clk *ti_clk_register_hwmod(struct ti_clk *setup)
+{
+	struct ti_clk_hwmod *data = setup->data;
+	struct clk_init_data init = { NULL };
+	struct clk_hw_omap *hw;
+	struct clk *clk;
+	int ret;
+
+	hw = kzalloc(sizeof(*hw), GFP_KERNEL);
+	if (!hw) {
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	hw->enable_reg = ti_clk_get_reg_addr_clkdm(setup->clkdm_name,
+						   data->reg);
+	if (!hw->enable_reg) {
+		ret = -EINVAL;
+		goto err;
+	}
+
+	if (data->flags & CLKF_SW_SUP)
+		hw->enable_bit = MODULEMODE_SWCTRL;
+	if (data->flags & CLKF_HW_SUP)
+		hw->enable_bit = MODULEMODE_HWCTRL;
+	if (data->flags & CLKF_NO_IDLEST)
+		hw->flags |= NO_IDLEST;
+
+	init.parent_names = &data->parent;
+	init.num_parents = 1;
+	init.flags = 0;
+	init.name = setup->name;
+	init.ops = &omap4_module_clk_ops;
+	hw->hw.init = &init;
+
+	clk = ti_clk_register(NULL, &hw->hw, setup->name);
+	if (!IS_ERR(clk))
+		return clk;
+err:
+	kfree(hw);
+	return ERR_PTR(ret);
+}
+
+static u8 _omap4_mux_mod_get_parent(struct clk_hw *hw)
+{
+	struct clk_hw_omap *clk = to_clk_hw_omap(hw);
+	struct clk_hw *mux_hw = clk->mux;
+
+	__clk_hw_set_clk(mux_hw, hw);
+
+	return ti_clk_mux_get_parent(mux_hw);
+}
+
+static int _omap4_mux_mod_set_parent(struct clk_hw *hw, u8 index)
+{
+	struct clk_hw_omap *clk = to_clk_hw_omap(hw);
+	struct clk_hw *mux_hw = clk->mux;
+
+	__clk_hw_set_clk(mux_hw, hw);
+
+	return ti_clk_mux_set_parent(mux_hw, index);
+}
+
+static int _omap4_mux_mod_determine_rate(struct clk_hw *hw,
+					 struct clk_rate_request *req)
+{
+	struct clk_hw_omap *clk = to_clk_hw_omap(hw);
+	struct clk_hw *mux_hw = clk->mux;
+
+	__clk_hw_set_clk(mux_hw, hw);
+
+	return __clk_mux_determine_rate(mux_hw, req);
+}
+
+static const struct clk_ops omap4_mux_module_clk_ops = {
+	.enable		= _omap4_hwmod_clk_enable,
+	.disable	= _omap4_hwmod_clk_disable,
+	.is_enabled	= _omap4_hwmod_clk_is_enabled,
+	.get_parent	= _omap4_mux_mod_get_parent,
+	.set_parent	= _omap4_mux_mod_set_parent,
+	.determine_rate	= _omap4_mux_mod_determine_rate,
+};
+
+struct clk *ti_clk_register_hwmod_mux(struct ti_clk *setup)
+{
+	struct ti_clk_hwmod_mux *data = setup->data;
+	struct clk_init_data init = { NULL };
+	struct clk_mux *mux;
+	struct clk_hw_omap *gate;
+	struct clk *clk;
+	int ret;
+	u8 modulemode;
+
+	if (data->num_parents < 2) {
+		pr_err("%s: must have parents\n", setup->name);
+		return ERR_PTR(-EINVAL);
+	}
+
+	mux = kzalloc(sizeof(*mux), GFP_KERNEL);
+	gate = kzalloc(sizeof(*gate), GFP_KERNEL);
+
+	if (!mux || !gate) {
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	gate->mux = &mux->hw;
+	mux->shift = data->shift;
+
+	if (data->flags & CLKF_INDEX_STARTS_AT_ONE)
+		mux->flags |= CLK_MUX_INDEX_ONE;
+
+	if (data->flags & CLKF_SW_SUP)
+		modulemode = MODULEMODE_SWCTRL;
+	if (data->flags & CLKF_HW_SUP)
+		modulemode = MODULEMODE_HWCTRL;
+
+	gate->enable_bit = modulemode;
+	gate->enable_reg = ti_clk_get_reg_addr_clkdm(setup->clkdm_name,
+						     data->mod_reg);
+	mux->reg = ti_clk_get_reg_addr_clkdm(setup->clkdm_name, data->mux_reg);
+
+	if (!gate->enable_reg || !mux->reg) {
+		ret = -EINVAL;
+		goto err;
+	}
+
+	init.num_parents = data->num_parents;
+	init.parent_names = data->parents;
+	init.flags = 0;
+
+	init.name = setup->name;
+	init.ops = &omap4_mux_module_clk_ops;
+	gate->hw.init = &init;
+
+	clk = ti_clk_register(NULL, &gate->hw, setup->name);
+
+	if (!IS_ERR(clk))
+		return clk;
+
+err:
+	kfree(gate);
+	kfree(mux);
+
+	return ERR_PTR(ret);
+}
diff --git a/drivers/clk/ti/clock.h b/drivers/clk/ti/clock.h
index 2e5fab8..ebcd81b 100644
--- a/drivers/clk/ti/clock.h
+++ b/drivers/clk/ti/clock.h
@@ -26,6 +26,8 @@ enum {
 	TI_CLK_FIXED_FACTOR,
 	TI_CLK_GATE,
 	TI_CLK_DPLL,
+	TI_CLK_HWMOD,
+	TI_CLK_HWMOD_MUX,
 };
 
 /* Global flags */
@@ -54,6 +56,11 @@ enum {
 #define CLKF_CORE			(1 << 9)
 #define CLKF_J_TYPE			(1 << 10)
 
+/* HWMOD clk flags */
+#define CLKF_SW_SUP			BIT(5)
+#define CLKF_HW_SUP			BIT(6)
+#define CLKF_NO_IDLEST			BIT(7)
+
 #define CLK(dev, con, ck)		\
 	{				\
 		.lk = {			\
@@ -156,6 +163,21 @@ struct ti_clk_dpll {
 	u8 recal_st_bit;
 };
 
+struct ti_clk_hwmod {
+	u16 reg;
+	u16 flags;
+	const char *parent;
+};
+
+struct ti_clk_hwmod_mux {
+	u16 mux_reg;
+	u16 mod_reg;
+	u16 flags;
+	u8 shift;
+	u8 num_parents;
+	const char * const *parents;
+};
+
 /* Composite clock component types */
 enum {
 	CLK_COMPONENT_TYPE_GATE = 0,
@@ -191,6 +213,8 @@ struct ti_dt_clk {
 struct clk *ti_clk_register_divider(struct ti_clk *setup);
 struct clk *ti_clk_register_composite(struct ti_clk *setup);
 struct clk *ti_clk_register_dpll(struct ti_clk *setup);
+struct clk *ti_clk_register_hwmod(struct ti_clk *setup);
+struct clk *ti_clk_register_hwmod_mux(struct ti_clk *setup);
 struct clk *ti_clk_register(struct device *dev, struct clk_hw *hw,
 			    const char *con);
 int ti_clk_add_alias(struct device *dev, struct clk *clk, const char *con);
diff --git a/include/linux/clk/ti.h b/include/linux/clk/ti.h
index afccb48..5c7c24c 100644
--- a/include/linux/clk/ti.h
+++ b/include/linux/clk/ti.h
@@ -130,6 +130,7 @@ struct clk_hw_omap_ops {
  * @enable_bit: bitshift to write to enable/disable the clock (see @enable_reg)
  * @flags: see "struct clk.flags possibilities" above
  * @clksel_reg: for clksel clks, register va containing src/divisor select
+ * @mux: for module clocks, pointer to the optional mux component
  * @dpll_data: for DPLLs, pointer to struct dpll_data for this clock
  * @clkdm_name: clockdomain name that this clock is contained in
  * @clkdm: pointer to struct clockdomain, resolved from @clkdm_name@runtime
@@ -145,6 +146,7 @@ struct clk_hw_omap {
 	u8			enable_bit;
 	u8			flags;
 	void __iomem		*clksel_reg;
+	struct clk_hw		*mux;
 	struct dpll_data	*dpll_data;
 	const char		*clkdm_name;
 	struct clockdomain	*clkdm;
-- 
1.9.1

^ permalink raw reply related

* [PATCHv4 12/15] clk: ti: enforce const types on string arrays
From: Tero Kristo @ 2016-10-18 15:46 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1476805568-19264-1-git-send-email-t-kristo@ti.com>

Constant string arrays should use const char * const instead of just
const char *. Change the implementations using these to proper type.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 drivers/clk/ti/clock.h     | 2 +-
 drivers/clk/ti/composite.c | 2 +-
 drivers/clk/ti/mux.c       | 8 ++++----
 3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/clk/ti/clock.h b/drivers/clk/ti/clock.h
index f6383ab..2e5fab8 100644
--- a/drivers/clk/ti/clock.h
+++ b/drivers/clk/ti/clock.h
@@ -88,7 +88,7 @@ struct ti_clk_mux {
 	int num_parents;
 	u16 reg;
 	u8 module;
-	const char **parents;
+	const char * const *parents;
 	u16 flags;
 };
 
diff --git a/drivers/clk/ti/composite.c b/drivers/clk/ti/composite.c
index 3f60f99..beea894 100644
--- a/drivers/clk/ti/composite.c
+++ b/drivers/clk/ti/composite.c
@@ -124,7 +124,7 @@ struct clk *ti_clk_register_composite(struct ti_clk *setup)
 	struct clk_hw *mux;
 	struct clk_hw *div;
 	int num_parents = 1;
-	const char **parent_names = NULL;
+	const char * const *parent_names = NULL;
 	struct clk *clk;
 	int ret;
 
diff --git a/drivers/clk/ti/mux.c b/drivers/clk/ti/mux.c
index 774098e..520a18e 100644
--- a/drivers/clk/ti/mux.c
+++ b/drivers/clk/ti/mux.c
@@ -97,10 +97,10 @@ int ti_clk_mux_set_parent(struct clk_hw *hw, u8 index)
 };
 
 static struct clk *_register_mux(struct device *dev, const char *name,
-				 const char **parent_names, u8 num_parents,
-				 unsigned long flags, void __iomem *reg,
-				 u8 shift, u32 mask, u8 clk_mux_flags,
-				 u32 *table)
+				 const char * const *parent_names,
+				 u8 num_parents, unsigned long flags,
+				 void __iomem *reg, u8 shift, u32 mask,
+				 u8 clk_mux_flags, u32 *table)
 {
 	struct clk_mux *mux;
 	struct clk *clk;
-- 
1.9.1

^ permalink raw reply related

* [PATCHv4 11/15] clk: ti: clockdomain: add clock provider support to clockdomains
From: Tero Kristo @ 2016-10-18 15:46 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1476805568-19264-1-git-send-email-t-kristo@ti.com>

Clockdomains can now be used as clock providers in the system. This
patch initializes the provider data during init, and parses the clocks
while they are being registered. An xlate function for the provider
is also given.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 .../devicetree/bindings/arm/omap/prcm.txt          |  13 ++
 .../devicetree/bindings/clock/ti/clockdomain.txt   |  12 +-
 arch/arm/mach-omap2/io.c                           |   2 +
 drivers/clk/ti/clock.h                             |   1 +
 drivers/clk/ti/clockdomain.c                       | 147 +++++++++++++++++++++
 include/linux/clk/ti.h                             |   3 +
 6 files changed, 177 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/arm/omap/prcm.txt b/Documentation/devicetree/bindings/arm/omap/prcm.txt
index 3eb6d7a..301f576 100644
--- a/Documentation/devicetree/bindings/arm/omap/prcm.txt
+++ b/Documentation/devicetree/bindings/arm/omap/prcm.txt
@@ -47,6 +47,19 @@ cm: cm at 48004000 {
 	};
 }
 
+cm2: cm2 at 8000 {
+	compatible = "ti,omap4-cm2";
+	reg = <0x8000 0x3000>;
+	#address-cells = <1>;
+	#size-cells = <1>;
+	ranges = <0 0x8000 0x3000>;
+
+	l4_per_clkdm: l4_per_clkdm {
+		compatible = "ti,clockdomain";
+		reg = <0x1400 0x200>;
+	};
+};
+
 &cm_clocks {
 	omap2_32k_fck: omap_32k_fck {
 		#clock-cells = <0>;
diff --git a/Documentation/devicetree/bindings/clock/ti/clockdomain.txt b/Documentation/devicetree/bindings/clock/ti/clockdomain.txt
index cb76b3f..5d8ca61 100644
--- a/Documentation/devicetree/bindings/clock/ti/clockdomain.txt
+++ b/Documentation/devicetree/bindings/clock/ti/clockdomain.txt
@@ -14,11 +14,21 @@ hardware hierarchy.
 
 Required properties:
 - compatible : shall be "ti,clockdomain"
-- #clock-cells : from common clock binding; shall be set to 0.
+- #clock-cells : from common clock binding; shall be set to 1 if this
+		 clockdomain acts as a clock provider.
+
+Optional properties:
 - clocks : link phandles of clocks within this domain
+- reg : address for the clockdomain
 
 Examples:
 	dss_clkdm: dss_clkdm {
 		compatible = "ti,clockdomain";
 		clocks = <&dss1_alwon_fck_3430es2>, <&dss_ick_3430es2>;
 	};
+
+	l4_per_clkdm: l4_per_clkdm {
+		compatible = "ti,clockdomain";
+		#clock-cells = <1>;
+		reg = <0x1400 0x200>;
+	};
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
index 0e9acdd..c1a5cfb 100644
--- a/arch/arm/mach-omap2/io.c
+++ b/arch/arm/mach-omap2/io.c
@@ -794,6 +794,8 @@ int __init omap_clk_init(void)
 		if (ret)
 			return ret;
 
+		ti_dt_clockdomains_early_setup();
+
 		of_clk_init(NULL);
 
 		ti_dt_clk_init_retry_clks();
diff --git a/drivers/clk/ti/clock.h b/drivers/clk/ti/clock.h
index 9b8a5f2..f6383ab 100644
--- a/drivers/clk/ti/clock.h
+++ b/drivers/clk/ti/clock.h
@@ -205,6 +205,7 @@ struct clk *ti_clk_register(struct device *dev, struct clk_hw *hw,
 
 int ti_clk_get_memmap_index(struct device_node *node);
 void __iomem *ti_clk_get_reg_addr(struct device_node *node, int index);
+void __iomem *ti_clk_get_reg_addr_clkdm(const char *clkdm_name, u16 offset);
 void ti_dt_clocks_register(struct ti_dt_clk *oclks);
 int ti_clk_retry_init(struct device_node *node, struct clk_hw *hw,
 		      ti_of_clk_init_cb_t func);
diff --git a/drivers/clk/ti/clockdomain.c b/drivers/clk/ti/clockdomain.c
index 704157d..7b0a6c3 100644
--- a/drivers/clk/ti/clockdomain.c
+++ b/drivers/clk/ti/clockdomain.c
@@ -28,6 +28,23 @@
 #define pr_fmt(fmt) "%s: " fmt, __func__
 
 /**
+ * struct ti_clkdm - TI clockdomain data structure
+ * @name: name of the clockdomain
+ * @index: index of the clk_iomap struct for this clkdm
+ * @offset: clockdomain offset from the beginning of the iomap
+ * @link: link to the list
+ */
+struct ti_clkdm {
+	const char *name;
+	int index;
+	u32 offset;
+	struct list_head link;
+	struct list_head clocks;
+};
+
+static LIST_HEAD(clkdms);
+
+/**
  * omap2_clkops_enable_clkdm - increment usecount on clkdm of @hw
  * @hw: struct clk_hw * of the clock being enabled
  *
@@ -116,6 +133,8 @@ void omap2_init_clk_clkdm(struct clk_hw *hw)
 	struct clk_hw_omap *clk = to_clk_hw_omap(hw);
 	struct clockdomain *clkdm;
 	const char *clk_name;
+	struct ti_clkdm *ti_clkdm;
+	bool match = false;
 
 	if (!clk->clkdm_name)
 		return;
@@ -130,7 +149,21 @@ void omap2_init_clk_clkdm(struct clk_hw *hw)
 	} else {
 		pr_debug("clock: could not associate clk %s to clkdm %s\n",
 			 clk_name, clk->clkdm_name);
+		return;
 	}
+
+	list_for_each_entry(ti_clkdm, &clkdms, link) {
+		if (!strcmp(ti_clkdm->name, clk->clkdm_name)) {
+			match = true;
+			break;
+		}
+	}
+
+	if (!match)
+		return;
+
+	/* Add clock to the list of provided clocks */
+	list_add(&clk->clkdm_link, &ti_clkdm->clocks);
 }
 
 static void __init of_ti_clockdomain_setup(struct device_node *node)
@@ -161,11 +194,125 @@ static void __init of_ti_clockdomain_setup(struct device_node *node)
 	}
 }
 
+static struct clk_hw *clkdm_clk_xlate(struct of_phandle_args *clkspec,
+				      void *data)
+{
+	struct ti_clkdm *clkdm = data;
+	struct clk_hw_omap *clk;
+	u16 offset = clkspec->args[0];
+
+	list_for_each_entry(clk, &clkdm->clocks, clkdm_link)
+		if (((u32)clk->enable_reg & 0xffff) - clkdm->offset == offset)
+			return &clk->hw;
+
+	return ERR_PTR(-EINVAL);
+}
+
+static int ti_clk_register_clkdm(struct device_node *node)
+{
+	u64 clkdm_addr;
+	u64 inst_addr;
+	const __be32 *reg;
+	u32 offset;
+	int idx;
+	struct ti_clkdm *clkdm;
+	int ret;
+
+	reg = of_get_address(node, 0, NULL, NULL);
+	if (!reg)
+		return -ENOENT;
+
+	clkdm_addr = of_translate_address(node, reg);
+
+	reg = of_get_address(node->parent, 0, NULL, NULL);
+	if (!reg)
+		return -EINVAL;
+
+	inst_addr = of_translate_address(node->parent, reg);
+
+	offset = clkdm_addr - inst_addr;
+
+	idx = ti_clk_get_memmap_index(node->parent);
+
+	if (idx < 0) {
+		pr_err("bad memmap index for %s\n", node->name);
+		return idx;
+	}
+
+	clkdm = kzalloc(sizeof(*clkdm), GFP_KERNEL);
+	if (!clkdm)
+		return -ENOMEM;
+
+	clkdm->name = node->name;
+	clkdm->index = idx;
+	clkdm->offset = offset;
+
+	INIT_LIST_HEAD(&clkdm->clocks);
+
+	list_add(&clkdm->link, &clkdms);
+
+	ret = of_clk_add_hw_provider(node, clkdm_clk_xlate, clkdm);
+	if (ret) {
+		list_del(&clkdm->link);
+		kfree(clkdm);
+		return ret;
+	}
+
+	return 0;
+}
+
+/**
+ * ti_clk_get_reg_addr_clkdm - get register address relative to clockdomain
+ * @clkdm_name: parent clockdomain
+ * @offset: offset from the clockdomain
+ *
+ * Gets a register address relative to parent clockdomain. Searches the
+ * list of available clockdomain, and if match is found, calculates the
+ * register address from the iomap relative to the clockdomain.
+ * Returns the register address, or NULL if not found.
+ */
+void __iomem *ti_clk_get_reg_addr_clkdm(const char *clkdm_name, u16 offset)
+{
+	u32 reg;
+	struct clk_omap_reg *reg_setup;
+	struct ti_clkdm *clkdm;
+	bool match = false;
+
+	reg_setup = (struct clk_omap_reg *)&reg;
+
+	/* XXX: get offset from clkdm, get base for instance */
+	list_for_each_entry(clkdm, &clkdms, link) {
+		if (!strcmp(clkdm->name, clkdm_name)) {
+			match = true;
+			break;
+		}
+	}
+
+	if (!match) {
+		pr_err("%s: no entry for %s\n", __func__, clkdm_name);
+		return NULL;
+	}
+
+	reg_setup->offset = clkdm->offset + offset;
+	reg_setup->index = clkdm->index;
+
+	return (void __iomem *)reg;
+}
+
 static const struct of_device_id ti_clkdm_match_table[] __initconst = {
 	{ .compatible = "ti,clockdomain" },
 	{ }
 };
 
+void __init ti_dt_clockdomains_early_setup(void)
+{
+	struct device_node *np;
+
+	for_each_matching_node(np, ti_clkdm_match_table) {
+		ti_clk_register_clkdm(np);
+	}
+}
+
 /**
  * ti_dt_clockdomains_setup - setup device tree clockdomains
  *
diff --git a/include/linux/clk/ti.h b/include/linux/clk/ti.h
index 626ae94..afccb48 100644
--- a/include/linux/clk/ti.h
+++ b/include/linux/clk/ti.h
@@ -125,6 +125,7 @@ struct clk_hw_omap_ops {
 /**
  * struct clk_hw_omap - OMAP struct clk
  * @node: list_head connecting this clock into the full clock list
+ * @clkdm_link: list_head connecting this clock into the clockdomain
  * @enable_reg: register to write to enable the clock (see @enable_bit)
  * @enable_bit: bitshift to write to enable/disable the clock (see @enable_reg)
  * @flags: see "struct clk.flags possibilities" above
@@ -137,6 +138,7 @@ struct clk_hw_omap_ops {
 struct clk_hw_omap {
 	struct clk_hw		hw;
 	struct list_head	node;
+	struct list_head	clkdm_link;
 	unsigned long		fixed_rate;
 	u8			fixed_div;
 	void __iomem		*enable_reg;
@@ -251,6 +253,7 @@ int omap2_reprogram_dpllcore(struct clk_hw *clk, unsigned long rate,
 unsigned long omap2_get_dpll_rate(struct clk_hw_omap *clk);
 
 void ti_dt_clk_init_retry_clks(void);
+void ti_dt_clockdomains_early_setup(void);
 void ti_dt_clockdomains_setup(void);
 int ti_clk_setup_ll_ops(struct ti_clk_ll_ops *ops);
 
-- 
1.9.1

^ permalink raw reply related

* [PATCHv4 10/15] clk: ti: add support API for fetching memmap index
From: Tero Kristo @ 2016-10-18 15:46 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1476805568-19264-1-git-send-email-t-kristo@ti.com>

Searches for a memmap index for a given node. Checks against all the
registered iomaps and sees if the node is registered for this.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 drivers/clk/ti/clk.c   | 24 ++++++++++++++++++++++++
 drivers/clk/ti/clock.h |  1 +
 2 files changed, 25 insertions(+)

diff --git a/drivers/clk/ti/clk.c b/drivers/clk/ti/clk.c
index 7a445f4..8bebda4 100644
--- a/drivers/clk/ti/clk.c
+++ b/drivers/clk/ti/clk.c
@@ -39,6 +39,7 @@
 struct clk_iomap {
 	struct regmap *regmap;
 	void __iomem *mem;
+	struct device_node *node;
 };
 
 static struct clk_iomap *clk_memmaps[CLK_MAX_MEMMAPS];
@@ -199,6 +200,28 @@ void __iomem *ti_clk_get_reg_addr(struct device_node *node, int index)
 }
 
 /**
+ * ti_clk_get_memmap_index - get memory mapping index for a node
+ * @node: device node pointer to find memmap index for
+ *
+ * Finds a matching memory mapping index for a node. Returns the index
+ * to the mapping, or negative error value in failure.
+ */
+int ti_clk_get_memmap_index(struct device_node *node)
+{
+	int i;
+
+	for (i = 0; i < CLK_MAX_MEMMAPS; i++) {
+		if (!clk_memmaps[i])
+			continue;
+
+		if (clk_memmaps[i]->node == node)
+			return i;
+	}
+
+	return -ENOENT;
+}
+
+/**
  * omap2_clk_provider_init - init master clock provider
  * @parent: master node
  * @index: internal index for clk_reg_ops
@@ -234,6 +257,7 @@ int __init omap2_clk_provider_init(struct device_node *parent, int index,
 
 	io->regmap = syscon;
 	io->mem = mem;
+	io->node = parent;
 
 	clk_memmaps[index] = io;
 
diff --git a/drivers/clk/ti/clock.h b/drivers/clk/ti/clock.h
index 9c85a51..9b8a5f2 100644
--- a/drivers/clk/ti/clock.h
+++ b/drivers/clk/ti/clock.h
@@ -203,6 +203,7 @@ struct clk *ti_clk_register(struct device *dev, struct clk_hw *hw,
 struct clk *ti_clk_register_clk(struct ti_clk *setup);
 int ti_clk_register_clks(struct ti_clk_alias *clks);
 
+int ti_clk_get_memmap_index(struct device_node *node);
 void __iomem *ti_clk_get_reg_addr(struct device_node *node, int index);
 void ti_dt_clocks_register(struct ti_dt_clk *oclks);
 int ti_clk_retry_init(struct device_node *node, struct clk_hw *hw,
-- 
1.9.1

^ permalink raw reply related

* [PATCHv4 09/15] clk: ti: move omap2_init_clk_clkdm under TI clock driver
From: Tero Kristo @ 2016-10-18 15:46 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1476805568-19264-1-git-send-email-t-kristo@ti.com>

This is not needed outside the driver, so move it inside it and remove
the prototype from the public header also.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/clock.c  | 34 ----------------------------------
 drivers/clk/ti/clock.h       |  1 +
 drivers/clk/ti/clockdomain.c | 30 ++++++++++++++++++++++++++++++
 include/linux/clk/ti.h       |  1 -
 4 files changed, 31 insertions(+), 35 deletions(-)

diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c
index 5391b66..ce8e804 100644
--- a/arch/arm/mach-omap2/clock.c
+++ b/arch/arm/mach-omap2/clock.c
@@ -79,40 +79,6 @@ int __init omap2_clk_setup_ll_ops(void)
  * OMAP2+ specific clock functions
  */
 
-/* Private functions */
-
-/* Public functions */
-
-/**
- * omap2_init_clk_clkdm - look up a clockdomain name, store pointer in clk
- * @clk: OMAP clock struct ptr to use
- *
- * Convert a clockdomain name stored in a struct clk 'clk' into a
- * clockdomain pointer, and save it into the struct clk.  Intended to be
- * called during clk_register().  No return value.
- */
-void omap2_init_clk_clkdm(struct clk_hw *hw)
-{
-	struct clk_hw_omap *clk = to_clk_hw_omap(hw);
-	struct clockdomain *clkdm;
-	const char *clk_name;
-
-	if (!clk->clkdm_name)
-		return;
-
-	clk_name = __clk_get_name(hw->clk);
-
-	clkdm = clkdm_lookup(clk->clkdm_name);
-	if (clkdm) {
-		pr_debug("clock: associated clk %s to clkdm %s\n",
-			 clk_name, clk->clkdm_name);
-		clk->clkdm = clkdm;
-	} else {
-		pr_debug("clock: could not associate clk %s to clkdm %s\n",
-			 clk_name, clk->clkdm_name);
-	}
-}
-
 static int __initdata mpurate;
 
 /*
diff --git a/drivers/clk/ti/clock.h b/drivers/clk/ti/clock.h
index 5675e37..9c85a51 100644
--- a/drivers/clk/ti/clock.h
+++ b/drivers/clk/ti/clock.h
@@ -232,6 +232,7 @@ int ti_clk_retry_init(struct device_node *node, struct clk_hw *hw,
 u8 ti_clk_mux_get_parent(struct clk_hw *hw);
 int ti_clk_mux_set_parent(struct clk_hw *hw, u8 index);
 
+void omap2_init_clk_clkdm(struct clk_hw *hw);
 int omap2_clkops_enable_clkdm(struct clk_hw *hw);
 void omap2_clkops_disable_clkdm(struct clk_hw *hw);
 
diff --git a/drivers/clk/ti/clockdomain.c b/drivers/clk/ti/clockdomain.c
index 6cf9dd1..704157d 100644
--- a/drivers/clk/ti/clockdomain.c
+++ b/drivers/clk/ti/clockdomain.c
@@ -103,6 +103,36 @@ void omap2_clkops_disable_clkdm(struct clk_hw *hw)
 	ti_clk_ll_ops->clkdm_clk_disable(clk->clkdm, hw->clk);
 }
 
+/**
+ * omap2_init_clk_clkdm - look up a clockdomain name, store pointer in clk
+ * @clk: OMAP clock struct ptr to use
+ *
+ * Convert a clockdomain name stored in a struct clk 'clk' into a
+ * clockdomain pointer, and save it into the struct clk.  Intended to be
+ * called during clk_register().  No return value.
+ */
+void omap2_init_clk_clkdm(struct clk_hw *hw)
+{
+	struct clk_hw_omap *clk = to_clk_hw_omap(hw);
+	struct clockdomain *clkdm;
+	const char *clk_name;
+
+	if (!clk->clkdm_name)
+		return;
+
+	clk_name = __clk_get_name(hw->clk);
+
+	clkdm = ti_clk_ll_ops->clkdm_lookup(clk->clkdm_name);
+	if (clkdm) {
+		pr_debug("clock: associated clk %s to clkdm %s\n",
+			 clk_name, clk->clkdm_name);
+		clk->clkdm = clkdm;
+	} else {
+		pr_debug("clock: could not associate clk %s to clkdm %s\n",
+			 clk_name, clk->clkdm_name);
+	}
+}
+
 static void __init of_ti_clockdomain_setup(struct device_node *node)
 {
 	struct clk *clk;
diff --git a/include/linux/clk/ti.h b/include/linux/clk/ti.h
index bc7fd8f..626ae94 100644
--- a/include/linux/clk/ti.h
+++ b/include/linux/clk/ti.h
@@ -238,7 +238,6 @@ struct ti_clk_ll_ops {
 
 #define to_clk_hw_omap(_hw) container_of(_hw, struct clk_hw_omap, hw)
 
-void omap2_init_clk_clkdm(struct clk_hw *clk);
 int omap2_clk_disable_autoidle_all(void);
 int omap2_clk_enable_autoidle_all(void);
 int omap2_clk_allow_idle(struct clk *clk);
-- 
1.9.1

^ permalink raw reply related

* [PATCHv4 08/15] clk: ti: add clkdm_lookup to the exported functions
From: Tero Kristo @ 2016-10-18 15:46 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1476805568-19264-1-git-send-email-t-kristo@ti.com>

This will be needed to move some additional clockdomain functionality
under clock driver.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/clock.c | 1 +
 include/linux/clk/ti.h      | 2 ++
 2 files changed, 3 insertions(+)

diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c
index d058125..5391b66 100644
--- a/arch/arm/mach-omap2/clock.c
+++ b/arch/arm/mach-omap2/clock.c
@@ -57,6 +57,7 @@
 static struct ti_clk_ll_ops omap_clk_ll_ops = {
 	.clkdm_clk_enable = clkdm_clk_enable,
 	.clkdm_clk_disable = clkdm_clk_disable,
+	.clkdm_lookup = clkdm_lookup,
 	.cm_wait_module_ready = omap_cm_wait_module_ready,
 	.cm_split_idlest_reg = cm_split_idlest_reg,
 };
diff --git a/include/linux/clk/ti.h b/include/linux/clk/ti.h
index 07308db..bc7fd8f 100644
--- a/include/linux/clk/ti.h
+++ b/include/linux/clk/ti.h
@@ -213,6 +213,7 @@ struct clk_omap_reg {
  * @clk_writel: pointer to register write function
  * @clkdm_clk_enable: pointer to clockdomain enable function
  * @clkdm_clk_disable: pointer to clockdomain disable function
+ * @clkdm_lookup: pointer to clockdomain lookup function
  * @cm_wait_module_ready: pointer to CM module wait ready function
  * @cm_split_idlest_reg: pointer to CM module function to split idlest reg
  *
@@ -228,6 +229,7 @@ struct ti_clk_ll_ops {
 	int	(*clkdm_clk_enable)(struct clockdomain *clkdm, struct clk *clk);
 	int	(*clkdm_clk_disable)(struct clockdomain *clkdm,
 				     struct clk *clk);
+	struct clockdomain * (*clkdm_lookup)(const char *name);
 	int	(*cm_wait_module_ready)(u8 part, s16 prcm_mod, u16 idlest_reg,
 					u8 idlest_shift);
 	int	(*cm_split_idlest_reg)(void __iomem *idlest_reg, s16 *prcm_inst,
-- 
1.9.1

^ permalink raw reply related

* [PATCHv4 07/15] clk: ti: rename ti_clk_register_legacy_clks API
From: Tero Kristo @ 2016-10-18 15:46 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1476805568-19264-1-git-send-email-t-kristo@ti.com>

Drop the '_legacy_' part out of the name, as this will be used to register
also non-legacy clocks in the following patches; namely the hwmod clocks.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 drivers/clk/ti/clk-3xxx-legacy.c | 30 +++++++++++++++---------------
 drivers/clk/ti/clk.c             |  4 ++--
 drivers/clk/ti/clock.h           |  2 +-
 3 files changed, 18 insertions(+), 18 deletions(-)

diff --git a/drivers/clk/ti/clk-3xxx-legacy.c b/drivers/clk/ti/clk-3xxx-legacy.c
index 0fbf8a9..5a860d2 100644
--- a/drivers/clk/ti/clk-3xxx-legacy.c
+++ b/drivers/clk/ti/clk-3xxx-legacy.c
@@ -4600,9 +4600,9 @@ int __init omap3430es1_clk_legacy_init(void)
 {
 	int r;
 
-	r = ti_clk_register_legacy_clks(omap3430es1_clks);
-	r |= ti_clk_register_legacy_clks(omap34xx_omap36xx_clks);
-	r |= ti_clk_register_legacy_clks(omap3xxx_clks);
+	r = ti_clk_register_clks(omap3430es1_clks);
+	r |= ti_clk_register_clks(omap34xx_omap36xx_clks);
+	r |= ti_clk_register_clks(omap3xxx_clks);
 
 	omap3_clk_legacy_common_init();
 
@@ -4613,10 +4613,10 @@ int __init omap3430_clk_legacy_init(void)
 {
 	int r;
 
-	r = ti_clk_register_legacy_clks(omap34xx_omap36xx_clks);
-	r |= ti_clk_register_legacy_clks(omap36xx_omap3430es2plus_clks);
-	r |= ti_clk_register_legacy_clks(omap36xx_am35xx_omap3430es2plus_clks);
-	r |= ti_clk_register_legacy_clks(omap3xxx_clks);
+	r = ti_clk_register_clks(omap34xx_omap36xx_clks);
+	r |= ti_clk_register_clks(omap36xx_omap3430es2plus_clks);
+	r |= ti_clk_register_clks(omap36xx_am35xx_omap3430es2plus_clks);
+	r |= ti_clk_register_clks(omap3xxx_clks);
 
 	omap3_clk_legacy_common_init();
 	omap3_clk_lock_dpll5();
@@ -4629,11 +4629,11 @@ int __init omap36xx_clk_legacy_init(void)
 	int r;
 
 	ti_clk_patch_legacy_clks(omap36xx_clk_patches);
-	r = ti_clk_register_legacy_clks(omap36xx_clks);
-	r |= ti_clk_register_legacy_clks(omap36xx_omap3430es2plus_clks);
-	r |= ti_clk_register_legacy_clks(omap34xx_omap36xx_clks);
-	r |= ti_clk_register_legacy_clks(omap36xx_am35xx_omap3430es2plus_clks);
-	r |= ti_clk_register_legacy_clks(omap3xxx_clks);
+	r = ti_clk_register_clks(omap36xx_clks);
+	r |= ti_clk_register_clks(omap36xx_omap3430es2plus_clks);
+	r |= ti_clk_register_clks(omap34xx_omap36xx_clks);
+	r |= ti_clk_register_clks(omap36xx_am35xx_omap3430es2plus_clks);
+	r |= ti_clk_register_clks(omap3xxx_clks);
 
 	omap3_clk_legacy_common_init();
 	omap3_clk_lock_dpll5();
@@ -4645,9 +4645,9 @@ int __init am35xx_clk_legacy_init(void)
 {
 	int r;
 
-	r = ti_clk_register_legacy_clks(am35xx_clks);
-	r |= ti_clk_register_legacy_clks(omap36xx_am35xx_omap3430es2plus_clks);
-	r |= ti_clk_register_legacy_clks(omap3xxx_clks);
+	r = ti_clk_register_clks(am35xx_clks);
+	r |= ti_clk_register_clks(omap36xx_am35xx_omap3430es2plus_clks);
+	r |= ti_clk_register_clks(omap3xxx_clks);
 
 	omap3_clk_legacy_common_init();
 	omap3_clk_lock_dpll5();
diff --git a/drivers/clk/ti/clk.c b/drivers/clk/ti/clk.c
index f526f0d..7a445f4 100644
--- a/drivers/clk/ti/clk.c
+++ b/drivers/clk/ti/clk.c
@@ -291,6 +291,7 @@ void __init ti_clk_patch_legacy_clks(struct ti_clk **patch)
 		patch++;
 	}
 }
+#endif
 
 struct clk __init *ti_clk_register_clk(struct ti_clk *setup)
 {
@@ -376,7 +377,7 @@ struct clk __init *ti_clk_register_clk(struct ti_clk *setup)
 	{ }
 };
 
-int __init ti_clk_register_legacy_clks(struct ti_clk_alias *clks)
+int __init ti_clk_register_clks(struct ti_clk_alias *clks)
 {
 	struct clk *clk;
 	bool retry;
@@ -443,7 +444,6 @@ int __init ti_clk_register_legacy_clks(struct ti_clk_alias *clks)
 
 	return 0;
 }
-#endif
 
 /**
  * ti_clk_setup_features - setup clock features flags
diff --git a/drivers/clk/ti/clock.h b/drivers/clk/ti/clock.h
index 6bf962d..5675e37 100644
--- a/drivers/clk/ti/clock.h
+++ b/drivers/clk/ti/clock.h
@@ -201,7 +201,7 @@ struct clk *ti_clk_register(struct device *dev, struct clk_hw *hw,
 
 void ti_clk_patch_legacy_clks(struct ti_clk **patch);
 struct clk *ti_clk_register_clk(struct ti_clk *setup);
-int ti_clk_register_legacy_clks(struct ti_clk_alias *clks);
+int ti_clk_register_clks(struct ti_clk_alias *clks);
 
 void __iomem *ti_clk_get_reg_addr(struct device_node *node, int index);
 void ti_dt_clocks_register(struct ti_dt_clk *oclks);
-- 
1.9.1

^ permalink raw reply related

* [PATCHv4 06/15] clk: ti: use automatic clock alias generation framework
From: Tero Kristo @ 2016-10-18 15:45 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1476805568-19264-1-git-send-email-t-kristo@ti.com>

Generate clock aliases automatically for all TI clock drivers.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 drivers/clk/ti/apll.c         |  2 +-
 drivers/clk/ti/clk-dra7-atl.c | 11 ++++++++++-
 drivers/clk/ti/clk.c          | 20 +++++++++++++++-----
 drivers/clk/ti/composite.c    | 16 +++++++++++++++-
 drivers/clk/ti/divider.c      |  2 +-
 drivers/clk/ti/dpll.c         |  6 +++---
 drivers/clk/ti/fixed-factor.c |  1 +
 drivers/clk/ti/gate.c         |  2 +-
 drivers/clk/ti/interface.c    |  2 +-
 drivers/clk/ti/mux.c          |  2 +-
 10 files changed, 49 insertions(+), 15 deletions(-)

diff --git a/drivers/clk/ti/apll.c b/drivers/clk/ti/apll.c
index 6411e13..62b5db7 100644
--- a/drivers/clk/ti/apll.c
+++ b/drivers/clk/ti/apll.c
@@ -164,7 +164,7 @@ static void __init omap_clk_register_apll(struct clk_hw *hw,
 
 	ad->clk_bypass = __clk_get_hw(clk);
 
-	clk = clk_register(NULL, &clk_hw->hw);
+	clk = ti_clk_register(NULL, &clk_hw->hw, node->name);
 	if (!IS_ERR(clk)) {
 		of_clk_add_provider(node, of_clk_src_simple_get, clk);
 		kfree(clk_hw->hw.init->parent_names);
diff --git a/drivers/clk/ti/clk-dra7-atl.c b/drivers/clk/ti/clk-dra7-atl.c
index c773332..265b115a2 100644
--- a/drivers/clk/ti/clk-dra7-atl.c
+++ b/drivers/clk/ti/clk-dra7-atl.c
@@ -24,6 +24,9 @@
 #include <linux/of_address.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
+#include <linux/clk/ti.h>
+
+#include "clock.h"
 
 #define DRA7_ATL_INSTANCES	4
 
@@ -171,6 +174,7 @@ static void __init of_dra7_atl_clock_setup(struct device_node *node)
 	struct clk_init_data init = { NULL };
 	const char **parent_names = NULL;
 	struct clk *clk;
+	int ret;
 
 	clk_hw = kzalloc(sizeof(*clk_hw), GFP_KERNEL);
 	if (!clk_hw) {
@@ -200,9 +204,14 @@ static void __init of_dra7_atl_clock_setup(struct device_node *node)
 
 	init.parent_names = parent_names;
 
-	clk = clk_register(NULL, &clk_hw->hw);
+	clk = ti_clk_register(NULL, &clk_hw->hw, node->name);
 
 	if (!IS_ERR(clk)) {
+		ret = ti_clk_add_alias(NULL, clk, node->name);
+		if (ret) {
+			clk_unregister(clk);
+			goto cleanup;
+		}
 		of_clk_add_provider(node, of_clk_src_simple_get, clk);
 		kfree(parent_names);
 		return;
diff --git a/drivers/clk/ti/clk.c b/drivers/clk/ti/clk.c
index 7fd9d8e..f526f0d 100644
--- a/drivers/clk/ti/clk.c
+++ b/drivers/clk/ti/clk.c
@@ -298,6 +298,7 @@ struct clk __init *ti_clk_register_clk(struct ti_clk *setup)
 	struct ti_clk_fixed *fixed;
 	struct ti_clk_fixed_factor *fixed_factor;
 	struct clk_hw *clk_hw;
+	int ret;
 
 	if (setup->clk)
 		return setup->clk;
@@ -308,6 +309,13 @@ struct clk __init *ti_clk_register_clk(struct ti_clk *setup)
 
 		clk = clk_register_fixed_rate(NULL, setup->name, NULL, 0,
 					      fixed->frequency);
+		if (!IS_ERR(clk)) {
+			ret = ti_clk_add_alias(NULL, clk, setup->name);
+			if (ret) {
+				clk_unregister(clk);
+				clk = ERR_PTR(ret);
+			}
+		}
 		break;
 	case TI_CLK_MUX:
 		clk = ti_clk_register_mux(setup);
@@ -325,6 +333,13 @@ struct clk __init *ti_clk_register_clk(struct ti_clk *setup)
 						fixed_factor->parent,
 						0, fixed_factor->mult,
 						fixed_factor->div);
+		if (!IS_ERR(clk)) {
+			ret = ti_clk_add_alias(NULL, clk, setup->name);
+			if (ret) {
+				clk_unregister(clk);
+				clk = ERR_PTR(ret);
+			}
+		}
 		break;
 	case TI_CLK_GATE:
 		clk = ti_clk_register_gate(setup);
@@ -387,9 +402,6 @@ int __init ti_clk_register_legacy_clks(struct ti_clk_alias *clks)
 				 */
 				goto add_aliases;
 			}
-		} else {
-			clks->lk.clk = clk;
-			clkdev_add(&clks->lk);
 		}
 		clks++;
 	}
@@ -412,8 +424,6 @@ int __init ti_clk_register_legacy_clks(struct ti_clk_alias *clks)
 				}
 			} else {
 				retry = true;
-				retry_clk->lk.clk = clk;
-				clkdev_add(&retry_clk->lk);
 				list_del(&retry_clk->link);
 			}
 		}
diff --git a/drivers/clk/ti/composite.c b/drivers/clk/ti/composite.c
index 1cf70f4..3f60f99 100644
--- a/drivers/clk/ti/composite.c
+++ b/drivers/clk/ti/composite.c
@@ -126,6 +126,7 @@ struct clk *ti_clk_register_composite(struct ti_clk *setup)
 	int num_parents = 1;
 	const char **parent_names = NULL;
 	struct clk *clk;
+	int ret;
 
 	comp = setup->data;
 
@@ -150,6 +151,12 @@ struct clk *ti_clk_register_composite(struct ti_clk *setup)
 				     &ti_composite_divider_ops, gate,
 				     &ti_composite_gate_ops, 0);
 
+	ret = ti_clk_add_alias(NULL, clk, setup->name);
+	if (ret) {
+		clk_unregister(clk);
+		return ERR_PTR(ret);
+	}
+
 	return clk;
 }
 #endif
@@ -163,6 +170,7 @@ static void __init _register_composite(struct clk_hw *hw,
 	int num_parents = 0;
 	const char **parent_names = NULL;
 	int i;
+	int ret;
 
 	/* Check for presence of each component clock */
 	for (i = 0; i < CLK_COMPONENT_TYPE_MAX; i++) {
@@ -217,8 +225,14 @@ static void __init _register_composite(struct clk_hw *hw,
 				     _get_hw(cclk, CLK_COMPONENT_TYPE_GATE),
 				     &ti_composite_gate_ops, 0);
 
-	if (!IS_ERR(clk))
+	if (!IS_ERR(clk)) {
+		ret = ti_clk_add_alias(NULL, clk, node->name);
+		if (ret) {
+			clk_unregister(clk);
+			goto cleanup;
+		}
 		of_clk_add_provider(node, of_clk_src_simple_get, clk);
+	}
 
 cleanup:
 	/* Free component clock list entries */
diff --git a/drivers/clk/ti/divider.c b/drivers/clk/ti/divider.c
index b4e5de1..a6750f8 100644
--- a/drivers/clk/ti/divider.c
+++ b/drivers/clk/ti/divider.c
@@ -282,7 +282,7 @@ static struct clk *_register_divider(struct device *dev, const char *name,
 	div->table = table;
 
 	/* register the clock */
-	clk = clk_register(dev, &div->hw);
+	clk = ti_clk_register(dev, &div->hw, name);
 
 	if (IS_ERR(clk))
 		kfree(div);
diff --git a/drivers/clk/ti/dpll.c b/drivers/clk/ti/dpll.c
index 9fc8754..2c3c83e 100644
--- a/drivers/clk/ti/dpll.c
+++ b/drivers/clk/ti/dpll.c
@@ -173,7 +173,7 @@ static void __init _register_dpll(struct clk_hw *hw,
 	dd->clk_bypass = __clk_get_hw(clk);
 
 	/* register the clock */
-	clk = clk_register(NULL, &clk_hw->hw);
+	clk = ti_clk_register(NULL, &clk_hw->hw, node->name);
 
 	if (!IS_ERR(clk)) {
 		omap2_init_clk_hw_omap_clocks(&clk_hw->hw);
@@ -276,7 +276,7 @@ struct clk *ti_clk_register_dpll(struct ti_clk *setup)
 	if (dpll->flags & CLKF_J_TYPE)
 		dd->flags |= DPLL_J_TYPE;
 
-	clk = clk_register(NULL, &clk_hw->hw);
+	clk = ti_clk_register(NULL, &clk_hw->hw, setup->name);
 
 	if (!IS_ERR(clk))
 		return clk;
@@ -328,7 +328,7 @@ static void _register_dpll_x2(struct device_node *node,
 	init.num_parents = 1;
 
 	/* register the clock */
-	clk = clk_register(NULL, &clk_hw->hw);
+	clk = ti_clk_register(NULL, &clk_hw->hw, name);
 
 	if (IS_ERR(clk)) {
 		kfree(clk_hw);
diff --git a/drivers/clk/ti/fixed-factor.c b/drivers/clk/ti/fixed-factor.c
index 3cd4067..0174a51 100644
--- a/drivers/clk/ti/fixed-factor.c
+++ b/drivers/clk/ti/fixed-factor.c
@@ -62,6 +62,7 @@ static void __init of_ti_fixed_factor_clk_setup(struct device_node *node)
 	if (!IS_ERR(clk)) {
 		of_clk_add_provider(node, of_clk_src_simple_get, clk);
 		of_ti_clk_autoidle_setup(node);
+		ti_clk_add_alias(NULL, clk, clk_name);
 	}
 }
 CLK_OF_DECLARE(ti_fixed_factor_clk, "ti,fixed-factor-clock",
diff --git a/drivers/clk/ti/gate.c b/drivers/clk/ti/gate.c
index bc05f27..b3291db 100644
--- a/drivers/clk/ti/gate.c
+++ b/drivers/clk/ti/gate.c
@@ -120,7 +120,7 @@ static struct clk *_register_gate(struct device *dev, const char *name,
 
 	init.flags = flags;
 
-	clk = clk_register(NULL, &clk_hw->hw);
+	clk = ti_clk_register(NULL, &clk_hw->hw, name);
 
 	if (IS_ERR(clk))
 		kfree(clk_hw);
diff --git a/drivers/clk/ti/interface.c b/drivers/clk/ti/interface.c
index e505e6f..7927e1a 100644
--- a/drivers/clk/ti/interface.c
+++ b/drivers/clk/ti/interface.c
@@ -58,7 +58,7 @@ static struct clk *_register_interface(struct device *dev, const char *name,
 	init.num_parents = 1;
 	init.parent_names = &parent_name;
 
-	clk = clk_register(NULL, &clk_hw->hw);
+	clk = ti_clk_register(NULL, &clk_hw->hw, name);
 
 	if (IS_ERR(clk))
 		kfree(clk_hw);
diff --git a/drivers/clk/ti/mux.c b/drivers/clk/ti/mux.c
index 57ff471..774098e 100644
--- a/drivers/clk/ti/mux.c
+++ b/drivers/clk/ti/mux.c
@@ -127,7 +127,7 @@ static struct clk *_register_mux(struct device *dev, const char *name,
 	mux->table = table;
 	mux->hw.init = &init;
 
-	clk = clk_register(dev, &mux->hw);
+	clk = ti_clk_register(dev, &mux->hw, name);
 
 	if (IS_ERR(clk))
 		kfree(mux);
-- 
1.9.1

^ permalink raw reply related

* [PATCHv4 05/15] clk: ti: create clock aliases automatically for simple clock types
From: Tero Kristo @ 2016-10-18 15:45 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1476805568-19264-1-git-send-email-t-kristo@ti.com>

This patch generates clock aliases automatically for simple clock types
(fixed-clock, fixed-factor-clock), so that we don't need to add the data
for these statically into tables.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 drivers/clk/ti/clk.c | 29 ++++++++++++++++++++++++++++-
 1 file changed, 28 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/ti/clk.c b/drivers/clk/ti/clk.c
index 91bad55..7fd9d8e 100644
--- a/drivers/clk/ti/clk.c
+++ b/drivers/clk/ti/clk.c
@@ -355,12 +355,20 @@ struct clk __init *ti_clk_register_clk(struct ti_clk *setup)
 	return clk;
 }
 
+static const struct of_device_id simple_clk_match_table[] __initconst = {
+	{ .compatible = "fixed-clock" },
+	{ .compatible = "fixed-factor-clock" },
+	{ }
+};
+
 int __init ti_clk_register_legacy_clks(struct ti_clk_alias *clks)
 {
 	struct clk *clk;
 	bool retry;
 	struct ti_clk_alias *retry_clk;
 	struct ti_clk_alias *tmp;
+	struct device_node *np;
+	int ret = 0;
 
 	while (clks->clk) {
 		clk = ti_clk_register_clk(clks->clk);
@@ -370,7 +378,14 @@ int __init ti_clk_register_legacy_clks(struct ti_clk_alias *clks)
 			} else {
 				pr_err("register for %s failed: %ld\n",
 				       clks->clk->name, PTR_ERR(clk));
-				return PTR_ERR(clk);
+				ret = PTR_ERR(clk);
+				/*
+				 * Aliases still need to be added here,
+				 * as we might be running on a
+				 * transitional system that has old DT
+				 * clock data in place.
+				 */
+				goto add_aliases;
 			}
 		} else {
 			clks->lk.clk = clk;
@@ -404,6 +419,18 @@ int __init ti_clk_register_legacy_clks(struct ti_clk_alias *clks)
 		}
 	}
 
+add_aliases:
+	/* add clock aliases for any fixed-clocks / fixed-factor-clocks */
+	if (of_have_populated_dt())
+		for_each_matching_node(np, simple_clk_match_table) {
+			struct of_phandle_args clkspec;
+
+			clkspec.np = np;
+			clk = of_clk_get_from_provider(&clkspec);
+
+			ti_clk_add_alias(NULL, clk, np->name);
+		}
+
 	return 0;
 }
 #endif
-- 
1.9.1

^ permalink raw reply related

* [PATCHv4 04/15] clk: ti: add support for automatic clock alias generation
From: Tero Kristo @ 2016-10-18 15:45 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1476805568-19264-1-git-send-email-t-kristo@ti.com>

Large portions of the OMAP framework still depend on the support of
having clock aliases in place, so add support functions for generating
these automatically.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 drivers/clk/ti/clk.c   | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++
 drivers/clk/ti/clock.h |  5 ++++
 2 files changed, 69 insertions(+)

diff --git a/drivers/clk/ti/clk.c b/drivers/clk/ti/clk.c
index 5fcf247..91bad55 100644
--- a/drivers/clk/ti/clk.c
+++ b/drivers/clk/ti/clk.c
@@ -24,6 +24,7 @@
 #include <linux/list.h>
 #include <linux/regmap.h>
 #include <linux/bootmem.h>
+#include <linux/device.h>
 
 #include "clock.h"
 
@@ -453,3 +454,66 @@ void omap2_clk_enable_init_clocks(const char **clk_names, u8 num_clocks)
 		clk_prepare_enable(init_clk);
 	}
 }
+
+/**
+ * ti_clk_add_alias - add a clock alias for a TI clock
+ * @dev: device alias for this clock
+ * @clk: clock handle to create alias for
+ * @con: connection ID for this clock
+ *
+ * Creates a clock alias for a TI clock. Allocates the clock lookup entry
+ * and assigns the data to it. Returns 0 if successful, negative error
+ * value otherwise.
+ */
+int ti_clk_add_alias(struct device *dev, struct clk *clk, const char *con)
+{
+	struct clk_lookup *cl;
+
+	if (!clk)
+		return 0;
+
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	cl = kzalloc(sizeof(*cl), GFP_KERNEL);
+	if (!cl)
+		return -ENOMEM;
+
+	if (dev)
+		cl->dev_id = dev_name(dev);
+	cl->con_id = con;
+	cl->clk = clk;
+
+	clkdev_add(cl);
+
+	return 0;
+}
+
+/**
+ * ti_clk_register - register a TI clock to the common clock framework
+ * @dev: device for this clock
+ * @hw: hardware clock handle
+ * @con: connection ID for this clock
+ *
+ * Registers a TI clock to the common clock framework, and adds a clock
+ * alias for it. Returns a handle to the registered clock if successful,
+ * ERR_PTR value in failure.
+ */
+struct clk *ti_clk_register(struct device *dev, struct clk_hw *hw,
+			    const char *con)
+{
+	struct clk *clk;
+	int ret;
+
+	clk = clk_register(dev, hw);
+	if (IS_ERR(clk))
+		return clk;
+
+	ret = ti_clk_add_alias(dev, clk, con);
+	if (ret) {
+		clk_unregister(clk);
+		return ERR_PTR(ret);
+	}
+
+	return clk;
+}
diff --git a/drivers/clk/ti/clock.h b/drivers/clk/ti/clock.h
index 7eca8a1..6bf962d 100644
--- a/drivers/clk/ti/clock.h
+++ b/drivers/clk/ti/clock.h
@@ -16,6 +16,8 @@
 #ifndef __DRIVERS_CLK_TI_CLOCK__
 #define __DRIVERS_CLK_TI_CLOCK__
 
+#include <linux/clkdev.h>
+
 enum {
 	TI_CLK_FIXED,
 	TI_CLK_MUX,
@@ -189,6 +191,9 @@ struct ti_dt_clk {
 struct clk *ti_clk_register_divider(struct ti_clk *setup);
 struct clk *ti_clk_register_composite(struct ti_clk *setup);
 struct clk *ti_clk_register_dpll(struct ti_clk *setup);
+struct clk *ti_clk_register(struct device *dev, struct clk_hw *hw,
+			    const char *con);
+int ti_clk_add_alias(struct device *dev, struct clk *clk, const char *con);
 
 struct clk_hw *ti_clk_build_component_div(struct ti_clk_divider *setup);
 struct clk_hw *ti_clk_build_component_gate(struct ti_clk_gate *setup);
-- 
1.9.1

^ permalink raw reply related

* [PATCHv4 03/15] dt-bindings: clock: add omap4 hwmod clock IDs
From: Tero Kristo @ 2016-10-18 15:45 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1476805568-19264-1-git-send-email-t-kristo@ti.com>

Add IDs for omap4 hwmod clocks. These are basically register offsets
from the beginning of the clockdomain address space.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 include/dt-bindings/clock/ti,omap44xx.h | 116 ++++++++++++++++++++++++++++++++
 1 file changed, 116 insertions(+)
 create mode 100644 include/dt-bindings/clock/ti,omap44xx.h

diff --git a/include/dt-bindings/clock/ti,omap44xx.h b/include/dt-bindings/clock/ti,omap44xx.h
new file mode 100644
index 0000000..38af57d
--- /dev/null
+++ b/include/dt-bindings/clock/ti,omap44xx.h
@@ -0,0 +1,116 @@
+/*
+ * TI OMAP4 SoC clock definitions
+ *
+ * Copyright (C) 2016 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __DT_BINDINGS_CLOCK_TI_OMAP4_H__
+#define __DT_BINDINGS_CLOCK_TI_OMAP4_H__
+
+#define OMAP44XX_MPUSS_MPU 0x20
+#define OMAP44XX_TESLA_DSP 0x20
+#define OMAP44XX_TESLA_MMU_DSP 0x20
+#define OMAP44XX_ABE_L4_ABE 0x20
+#define OMAP44XX_ABE_AESS 0x28
+#define OMAP44XX_ABE_MCPDM 0x30
+#define OMAP44XX_ABE_DMIC 0x38
+#define OMAP44XX_ABE_MCASP 0x40
+#define OMAP44XX_ABE_MCBSP1 0x48
+#define OMAP44XX_ABE_MCBSP2 0x50
+#define OMAP44XX_ABE_MCBSP3 0x58
+#define OMAP44XX_ABE_SLIMBUS1 0x60
+#define OMAP44XX_ABE_TIMER5 0x68
+#define OMAP44XX_ABE_TIMER6 0x70
+#define OMAP44XX_ABE_TIMER7 0x78
+#define OMAP44XX_ABE_TIMER8 0x80
+#define OMAP44XX_ABE_WD_TIMER3 0x88
+#define OMAP44XX_L4_WKUP_L4_WKUP 0x20
+#define OMAP44XX_L4_WKUP_WD_TIMER2 0x30
+#define OMAP44XX_L4_WKUP_GPIO1 0x38
+#define OMAP44XX_L4_WKUP_TIMER1 0x40
+#define OMAP44XX_L4_WKUP_COUNTER_32K 0x50
+#define OMAP44XX_L4_WKUP_KBD 0x78
+#define OMAP44XX_EMU_SYS_DEBUGSS 0x20
+#define OMAP44XX_L3_DSS_DSS_CORE 0x20
+#define OMAP44XX_L3_DSS_DSS_RFBI 0x20
+#define OMAP44XX_L3_DSS_DSS_HDMI 0x20
+#define OMAP44XX_L3_DSS_DSS_DSI2 0x20
+#define OMAP44XX_L3_DSS_DSS_VENC 0x20
+#define OMAP44XX_L3_DSS_DSS_DISPC 0x20
+#define OMAP44XX_L3_DSS_DSS_DSI1 0x20
+#define OMAP44XX_ISS_FDIF 0x28
+#define OMAP44XX_L4_PER_GPIO2 0x60
+#define OMAP44XX_L4_PER_GPIO3 0x68
+#define OMAP44XX_L4_PER_GPIO4 0x70
+#define OMAP44XX_L4_PER_GPIO5 0x78
+#define OMAP44XX_L4_PER_GPIO6 0x80
+#define OMAP44XX_L4_PER_HDQ1W 0x88
+#define OMAP44XX_L4_PER_I2C1 0xa0
+#define OMAP44XX_L4_PER_I2C2 0xa8
+#define OMAP44XX_L4_PER_I2C3 0xb0
+#define OMAP44XX_L4_PER_I2C4 0xb8
+#define OMAP44XX_L4_PER_L4_PER 0xc0
+#define OMAP44XX_L3_GFX_GPU 0x20
+#define OMAP44XX_L3_INIT_HSI 0x38
+#define OMAP44XX_ISS_ISS 0x20
+#define OMAP44XX_L4_PER_MCBSP4 0xe0
+#define OMAP44XX_L4_PER_MCSPI1 0xf0
+#define OMAP44XX_L4_PER_MCSPI2 0xf8
+#define OMAP44XX_L4_PER_MCSPI3 0x100
+#define OMAP44XX_L4_PER_MCSPI4 0x108
+#define OMAP44XX_L4_PER_MMC3 0x120
+#define OMAP44XX_L4_PER_MMC4 0x128
+#define OMAP44XX_L3_INIT_MMC1 0x28
+#define OMAP44XX_L3_INIT_MMC2 0x30
+#define OMAP44XX_L3_INIT_OCP2SCP_USB_PHY 0xe0
+#define OMAP44XX_L4_PER_TIMER10 0x28
+#define OMAP44XX_L4_PER_TIMER11 0x30
+#define OMAP44XX_L4_PER_TIMER2 0x38
+#define OMAP44XX_L4_PER_TIMER3 0x40
+#define OMAP44XX_L4_PER_TIMER4 0x48
+#define OMAP44XX_L4_PER_TIMER9 0x50
+#define OMAP44XX_L4_PER_ELM 0x58
+#define OMAP44XX_L4_PER_SLIMBUS2 0x138
+#define OMAP44XX_L4_PER_UART1 0x140
+#define OMAP44XX_L4_PER_UART2 0x148
+#define OMAP44XX_L4_PER_UART3 0x150
+#define OMAP44XX_L4_PER_UART4 0x158
+#define OMAP44XX_L4_PER_MMC5 0x160
+#define OMAP44XX_L4_AO_SMARTREFLEX_CORE 0x38
+#define OMAP44XX_L4_AO_SMARTREFLEX_IVA 0x30
+#define OMAP44XX_L4_AO_SMARTREFLEX_MPU 0x28
+#define OMAP44XX_L3_INIT_USB_HOST_FS 0xd0
+#define OMAP44XX_L3_INIT_USB_HOST_HS 0x58
+#define OMAP44XX_L3_INIT_USB_OTG_HS 0x60
+#define OMAP44XX_L3_1_L3_MAIN_1 0x20
+#define OMAP44XX_L3_2_L3_MAIN_2 0x20
+#define OMAP44XX_L3_2_GPMC 0x28
+#define OMAP44XX_L3_2_OCMC_RAM 0x30
+#define OMAP44XX_DUCATI_IPU 0x20
+#define OMAP44XX_DUCATI_MMU_IPU 0x20
+#define OMAP44XX_L3_DMA_DMA_SYSTEM 0x20
+#define OMAP44XX_L3_EMIF_DMM 0x20
+#define OMAP44XX_L3_EMIF_EMIF1 0x30
+#define OMAP44XX_L3_EMIF_EMIF2 0x38
+#define OMAP44XX_D2D_C2C 0x20
+#define OMAP44XX_L4_CFG_L4_CFG 0x20
+#define OMAP44XX_L4_CFG_SPINLOCK 0x28
+#define OMAP44XX_L4_CFG_MAILBOX 0x30
+#define OMAP44XX_L3_INSTR_L3_MAIN_3 0x20
+#define OMAP44XX_L3_INSTR_L3_INSTR 0x28
+#define OMAP44XX_L3_INSTR_OCP_WP_NOC 0x40
+#define OMAP44XX_IVAHD_IVA 0x20
+#define OMAP44XX_IVAHD_SL2IF 0x28
+#define OMAP44XX_L3_INIT_USB_TLL_HS 0x68
+
+#endif
-- 
1.9.1

^ permalink raw reply related

* [PATCHv4 02/15] clk: ti: mux: export mux clock APIs locally
From: Tero Kristo @ 2016-10-18 15:45 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1476805568-19264-1-git-send-email-t-kristo@ti.com>

get_parent and set_parent are going to be required by the support of
module clocks, so export these locally.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 drivers/clk/ti/clock.h | 3 +++
 drivers/clk/ti/mux.c   | 4 ++--
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/ti/clock.h b/drivers/clk/ti/clock.h
index 90f3f47..7eca8a1 100644
--- a/drivers/clk/ti/clock.h
+++ b/drivers/clk/ti/clock.h
@@ -224,6 +224,9 @@ int ti_clk_retry_init(struct device_node *node, struct clk_hw *hw,
 extern const struct clk_ops ti_clk_divider_ops;
 extern const struct clk_ops ti_clk_mux_ops;
 
+u8 ti_clk_mux_get_parent(struct clk_hw *hw);
+int ti_clk_mux_set_parent(struct clk_hw *hw, u8 index);
+
 int omap2_clkops_enable_clkdm(struct clk_hw *hw);
 void omap2_clkops_disable_clkdm(struct clk_hw *hw);
 
diff --git a/drivers/clk/ti/mux.c b/drivers/clk/ti/mux.c
index 44777ab..57ff471 100644
--- a/drivers/clk/ti/mux.c
+++ b/drivers/clk/ti/mux.c
@@ -26,7 +26,7 @@
 #undef pr_fmt
 #define pr_fmt(fmt) "%s: " fmt, __func__
 
-static u8 ti_clk_mux_get_parent(struct clk_hw *hw)
+u8 ti_clk_mux_get_parent(struct clk_hw *hw)
 {
 	struct clk_mux *mux = to_clk_mux(hw);
 	int num_parents = clk_hw_get_num_parents(hw);
@@ -63,7 +63,7 @@ static u8 ti_clk_mux_get_parent(struct clk_hw *hw)
 	return val;
 }
 
-static int ti_clk_mux_set_parent(struct clk_hw *hw, u8 index)
+int ti_clk_mux_set_parent(struct clk_hw *hw, u8 index)
 {
 	struct clk_mux *mux = to_clk_mux(hw);
 	u32 val;
-- 
1.9.1

^ permalink raw reply related

* [PATCHv4 01/15] clk: ti: remove un-used definitions from public clk_hw_omap struct
From: Tero Kristo @ 2016-10-18 15:45 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1476805568-19264-1-git-send-email-t-kristo@ti.com>

Clksel support has been deprecated a while back, so remove these from
the struct also.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 include/linux/clk/ti.h | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/include/linux/clk/ti.h b/include/linux/clk/ti.h
index 6110fe0..07308db 100644
--- a/include/linux/clk/ti.h
+++ b/include/linux/clk/ti.h
@@ -129,8 +129,6 @@ struct clk_hw_omap_ops {
  * @enable_bit: bitshift to write to enable/disable the clock (see @enable_reg)
  * @flags: see "struct clk.flags possibilities" above
  * @clksel_reg: for clksel clks, register va containing src/divisor select
- * @clksel_mask: bitmask in @clksel_reg for the src/divisor selector
- * @clksel: for clksel clks, pointer to struct clksel for this clock
  * @dpll_data: for DPLLs, pointer to struct dpll_data for this clock
  * @clkdm_name: clockdomain name that this clock is contained in
  * @clkdm: pointer to struct clockdomain, resolved from @clkdm_name at runtime
@@ -145,8 +143,6 @@ struct clk_hw_omap {
 	u8			enable_bit;
 	u8			flags;
 	void __iomem		*clksel_reg;
-	u32			clksel_mask;
-	const struct clksel	*clksel;
 	struct dpll_data	*dpll_data;
 	const char		*clkdm_name;
 	struct clockdomain	*clkdm;
-- 
1.9.1

^ permalink raw reply related

* [PATCHv4 00/15] clk: ti: add support for hwmod clocks
From: Tero Kristo @ 2016-10-18 15:45 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

As a recap, this series is part of the ongoing work to get rid of the
hwmod database under mach-omap2 folder. This series converts the
existing clock related functionality to a new clock type, which will
allow removing all the .clkctrl related items from hwmod database.
This series adds sample solution for OMAP4 only, rest of the SoCs can
be converted automatically once the approach is acceptable.

v4 has the following high level changes compared to v3:
- Clock data is now statically built-in to the driver
- Adds clockdomain provider support, which can be used to fetch
  clocks based on clockdomain relation. Only clockdomains need to be
  registered within DT.
- Added some automatic clock alias generation support to the TI clock
  drivers, if this is not acceptable, I can change this to add all the
  aliases under the individual drivers/clk/ti/clk-xyz.c files
- As a sample, only omap4 clock data is available with this set

After this series, the clock data can be dropped from the hwmod database
for OMAP4, I have working patches for this for anybody interested. Also,
the DT files require some modifications to add proper support for
clockdomain providers, and drop some unnecessary clock nodes.

Boot + simple PM test seems to be working on OMAP4 with this set, and
boot test with other boards I have access to don't seem to cause any
issues. Applies on top of 4.9-rc1.

-Tero

^ permalink raw reply

* [PATCH V7 1/3] tracing: add a possibility of exporting function trace to other places instead of ring buffer only
From: Steven Rostedt @ 2016-10-18 15:44 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1476778140-10319-2-git-send-email-zhang.chunyan@linaro.org>

On Tue, 18 Oct 2016 16:08:58 +0800
Chunyan Zhang <zhang.chunyan@linaro.org> wrote:

> Currently Function traces can be only exported to ring buffer, this
> patch added trace_export concept which can process traces and export
> them to a registered destination as an addition to the current only
> one output of Ftrace - i.e. ring buffer.
> 
> In this way, if we want Function traces to be sent to other destination
> rather than ring buffer only, we just need to register a new trace_export
> and implement its own .write() function for writing traces to storage.
> 
> With this patch, only Function trace (trace type is TRACE_FN)
> is supported.

This is getting better, but I still have some nits.

> 
> Signed-off-by: Chunyan Zhang <zhang.chunyan@linaro.org>
> ---
>  include/linux/trace.h |  28 +++++++++++
>  kernel/trace/trace.c  | 132 +++++++++++++++++++++++++++++++++++++++++++++++++-
>  2 files changed, 159 insertions(+), 1 deletion(-)
>  create mode 100644 include/linux/trace.h
> 
> diff --git a/include/linux/trace.h b/include/linux/trace.h
> new file mode 100644
> index 0000000..eb1c5b8
> --- /dev/null
> +++ b/include/linux/trace.h
> @@ -0,0 +1,28 @@
> +#ifndef _LINUX_TRACE_H
> +#define _LINUX_TRACE_H
> +
> +#ifdef CONFIG_TRACING
> +/*
> + * The trace export - an export of Ftrace output. The trace_export
> + * can process traces and export them to a registered destination as
> + * an addition to the current only output of Ftrace - i.e. ring buffer.
> + *
> + * If you want traces to be sent to some other place rather than ring
> + * buffer only, just need to register a new trace_export and implement
> + * its own .write() function for writing traces to the storage.
> + *
> + * next		- pointer to the next trace_export
> + * write	- copy traces which have been delt with ->commit() to
> + *		  the destination
> + */
> +struct trace_export {
> +	struct trace_export __rcu	*next;
> +	void (*write)(const char *, unsigned int);

Why const char*? Why not const void *? This will never be a string.


> +};
> +
> +int register_ftrace_export(struct trace_export *export);
> +int unregister_ftrace_export(struct trace_export *export);
> +
> +#endif	/* CONFIG_TRACING */
> +
> +#endif	/* _LINUX_TRACE_H */
> diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
> index 8696ce6..db94ec1 100644
> --- a/kernel/trace/trace.c
> +++ b/kernel/trace/trace.c
> @@ -40,6 +40,7 @@
>  #include <linux/poll.h>
>  #include <linux/nmi.h>
>  #include <linux/fs.h>
> +#include <linux/trace.h>
>  #include <linux/sched/rt.h>
>  
>  #include "trace.h"
> @@ -2128,6 +2129,132 @@ void trace_buffer_unlock_commit_regs(struct trace_array *tr,
>  	ftrace_trace_userstack(buffer, flags, pc);
>  }
>  
> +static void
> +trace_process_export(struct trace_export *export,
> +	       struct ring_buffer_event *event)
> +{
> +	struct trace_entry *entry;
> +	unsigned int size = 0;
> +
> +	entry = ring_buffer_event_data(event);
> +
> +	size = ring_buffer_event_length(event);
> +
> +	if (export->write)
> +		export->write((char *)entry, size);

Is there ever going to be a time where export->write wont be set?

And if there is, this can be racy. As in


	CPU 0:			CPU 1:
	------			------
	if (export->write)

				export->write = NULL;

	export->write(entry, size);

	BOOM!


-- Steve

> +}
> +
> +static DEFINE_MUTEX(ftrace_export_lock);
> +
> +static struct trace_export __rcu *ftrace_exports_list __read_mostly;
> +
> +static DEFINE_STATIC_KEY_FALSE(ftrace_exports_enabled);
> +
> +static inline void ftrace_exports_enable(void)
> +{
> +	static_branch_enable(&ftrace_exports_enabled);
> +}
> +
> +static inline void ftrace_exports_disable(void)
> +{
> +	static_branch_disable(&ftrace_exports_enabled);
> +}
> +
> +void ftrace_exports(struct ring_buffer_event *event)
> +{
> +	struct trace_export *export;
> +
> +	preempt_disable_notrace();
> +
> +	export = rcu_dereference_raw_notrace(ftrace_exports_list);
> +	while (export) {
> +		trace_process_export(export, event);
> +		export = rcu_dereference_raw_notrace(export->next);
> +	}
> +
> +	preempt_enable_notrace();
> +}
> +
> +static inline void
> +add_trace_export(struct trace_export **list, struct trace_export *export)
> +{
> +	rcu_assign_pointer(export->next, *list);
> +	/*
> +	 * We are entering export into the list but another
> +	 * CPU might be walking that list. We need to make sure
> +	 * the export->next pointer is valid before another CPU sees
> +	 * the export pointer included into the list.
> +	 */
> +	rcu_assign_pointer(*list, export);
> +}
> +
> +static inline int
> +rm_trace_export(struct trace_export **list, struct trace_export *export)
> +{
> +	struct trace_export **p;
> +
> +	for (p = list; *p != NULL; p = &(*p)->next)
> +		if (*p == export)
> +			break;
> +
> +	if (*p != export)
> +		return -1;
> +
> +	rcu_assign_pointer(*p, (*p)->next);
> +
> +	return 0;
> +}
> +
> +static inline void
> +add_ftrace_export(struct trace_export **list, struct trace_export *export)
> +{
> +	if (*list == NULL)
> +		ftrace_exports_enable();
> +
> +	add_trace_export(list, export);
> +}
> +
> +static inline int
> +rm_ftrace_export(struct trace_export **list, struct trace_export *export)
> +{
> +	int ret;
> +
> +	ret = rm_trace_export(list, export);
> +	if (*list == NULL)
> +		ftrace_exports_disable();
> +
> +	return ret;
> +}
> +
> +int register_ftrace_export(struct trace_export *export)
> +{
> +	if (WARN_ON_ONCE(!export->write))
> +		return -1;
> +
> +	mutex_lock(&ftrace_export_lock);
> +
> +	add_ftrace_export(&ftrace_exports_list, export);
> +
> +	mutex_unlock(&ftrace_export_lock);
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL_GPL(register_ftrace_export);
> +
> +int unregister_ftrace_export(struct trace_export *export)
> +{
> +	int ret;
> +
> +	mutex_lock(&ftrace_export_lock);
> +
> +	ret = rm_ftrace_export(&ftrace_exports_list, export);
> +
> +	mutex_unlock(&ftrace_export_lock);
> +
> +	return ret;
> +}
> +EXPORT_SYMBOL_GPL(unregister_ftrace_export);
> +
>  void
>  trace_function(struct trace_array *tr,
>  	       unsigned long ip, unsigned long parent_ip, unsigned long flags,
> @@ -2146,8 +2273,11 @@ trace_function(struct trace_array *tr,
>  	entry->ip			= ip;
>  	entry->parent_ip		= parent_ip;
>  
> -	if (!call_filter_check_discard(call, entry, buffer, event))
> +	if (!call_filter_check_discard(call, entry, buffer, event)) {
> +		if (static_branch_unlikely(&ftrace_exports_enabled))
> +			ftrace_exports(event);
>  		__buffer_unlock_commit(buffer, event);
> +	}
>  }
>  
>  #ifdef CONFIG_STACKTRACE

^ permalink raw reply

* [PATCH] ARM: sti: stih410-clocks: Add PROC_STFE as a critical clock
From: Peter Griffin @ 2016-10-18 15:35 UTC (permalink / raw)
  To: linux-arm-kernel

Once the ST frontend demux HW IP has been enabled, the clock can't
be disabled otherwise the system will hang and the board will
be unserviceable.

To allow balanced clock enable/disable calls in the driver we use
the critical clock infrastructure to take an extra reference on the
clock so the clock will never actually be disabled.

Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
---
 arch/arm/boot/dts/stih410-clock.dtsi | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/stih410-clock.dtsi b/arch/arm/boot/dts/stih410-clock.dtsi
index 8598eff..07c8ef9 100644
--- a/arch/arm/boot/dts/stih410-clock.dtsi
+++ b/arch/arm/boot/dts/stih410-clock.dtsi
@@ -208,7 +208,8 @@
 						     "clk-clust-hades",
 						     "clk-hwpe-hades",
 						     "clk-fc-hades";
-				clock-critical = <CLK_ICN_CPU>,
+				clock-critical = <CLK_PROC_STFE>,
+						 <CLK_ICN_CPU>,
 						 <CLK_TX_ICN_DMU>,
 						 <CLK_EXT2F_A9>,
 						 <CLK_ICN_LMI>,
-- 
1.9.1

^ permalink raw reply related

* [PATCH v2 1/4] cpufreq: pxa: use generic platdev driver for device-tree
From: Robert Jarzmik @ 2016-10-18 15:35 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161018113835.GB11471@vireshk-i7>

Viresh Kumar <viresh.kumar@linaro.org> writes:

> On 15-10-16, 21:57, Robert Jarzmik wrote:
>> For device-tree based pxa25x and pxa27x platforms, cpufreq-dt driver is
>> doing the job as well as pxa2xx-cpufreq, so add these platforms to the
>> compatibility list.
>> 
>> This won't work for legacy non device-tree platforms where
>> pxa2xx-cpufreq is still required.
>> 
>> Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
>> ---
>>  drivers/cpufreq/cpufreq-dt-platdev.c | 2 ++
>>  1 file changed, 2 insertions(+)
>> 
>> diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c b/drivers/cpufreq/cpufreq-dt-platdev.c
>> index 0bb44d5b5df4..356825b5c9b8 100644
>> --- a/drivers/cpufreq/cpufreq-dt-platdev.c
>> +++ b/drivers/cpufreq/cpufreq-dt-platdev.c
>> @@ -32,6 +32,8 @@ static const struct of_device_id machines[] __initconst = {
>>  	{ .compatible = "fsl,imx7d", },
>>  
>>  	{ .compatible = "marvell,berlin", },
>> +	{ .compatible = "marvell,pxa250", },
>> +	{ .compatible = "marvell,pxa270", },
>>  
>>  	{ .compatible = "samsung,exynos3250", },
>>  	{ .compatible = "samsung,exynos4210", },
>
> Isn't there a race between cpufreq-dt and the platform driver to
> register first ?
Ah, could you be more specific about the race you're talking of ?

My understanding was that cpufreq-dt-platdev does create the device, and
cpufreq-dt is a driver for it, so there is no race but a direct relationship
AFAIU.

> Also, it seems that atleast the next two patches are required before
> applying this? You need to fix the order if that is the case.
Ok, as you wish, let it become number 3 and (2, 3) become (1, 2).

Cheers.

-- 
Robert

^ permalink raw reply

* [PATCH V3 1/3] ACPI, PCI IRQ: add PCI_USING penalty for ISA interrupts
From: Sinan Kaya @ 2016-10-18 15:32 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <b4a8995e-1454-3b84-0681-1491788087ec@codeaurora.org>

Sorry, I think I didn't have enough morning coffee.

Looking at these again and trying to be specific.

On 10/18/2016 8:20 AM, Sinan Kaya wrote:
> It seems wrong to me that we call acpi_irq_get_penalty() from
>> acpi_irq_penalty_update() and acpi_penalize_isa_irq().  It seems like they
>> should just manipulate acpi_isa_irq_penalty[irq] directly.
>> 
>> acpi_irq_penalty_update() is for command-line parameters, so it certainly
>> doesn't need the acpi_irq_pci_sharing_penalty() information (the
>> acpi_link_list should be empty at the time we process the command-line
>> parameters).

Calling acpi_irq_get_penalty for ISA IRQ is OK as long as it doesn't have
any dynamic IRQ calculation such that acpi_isa_irq_penalty[irq] = acpi_irq_get_penalty.

If this is broken, then we need special care so that we don't assign
dynamically calcualted sci_penalty back to acpi_isa_irq_penalty[irq]. This
results in returning incorrect penalty as

acpi_irq_get_penalty = acpi_isa_irq_original_penalty[irq] + 2 * sci_penalty.

Now that we added sci_penalty into the acpi_irq_get_penalty function,
calling acpi_irq_get_penalty is not correct anymore. This line here needs to
be replaced with acpi_isa_irq_penalty[irq] as you suggested.

                if (used)
                        new_penalty = acpi_irq_get_penalty(irq) +
                                        PIRQ_PENALTY_ISA_USED;
                else
                        new_penalty = 0;

                acpi_isa_irq_penalty[irq] = new_penalty;


>> 
>> acpi_penalize_isa_irq() is telling us that a PNP or ACPI device is using
>> the IRQ -- this should modify the IRQ's penalty, but it shouldn't depend on
>> the acpi_irq_pci_sharing_penalty() value at all.
>> 

Same problem here. This line will be broken after the sci_penalty change.

                acpi_isa_irq_penalty[irq] = acpi_irq_get_penalty(irq) +
                  (active ? PIRQ_PENALTY_ISA_USED : PIRQ_PENALTY_PCI_USING);




-- 
Sinan Kaya
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.

^ permalink raw reply

* [PATCH 00/10] mm: adjust get_user_pages* functions to explicitly pass FOLL_* flags
From: Michal Hocko @ 2016-10-18 15:30 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161013002020.3062-1-lstoakes@gmail.com>

On Thu 13-10-16 01:20:10, Lorenzo Stoakes wrote:
> This patch series adjusts functions in the get_user_pages* family such that
> desired FOLL_* flags are passed as an argument rather than implied by flags.
> 
> The purpose of this change is to make the use of FOLL_FORCE explicit so it is
> easier to grep for and clearer to callers that this flag is being used. The use
> of FOLL_FORCE is an issue as it overrides missing VM_READ/VM_WRITE flags for the
> VMA whose pages we are reading from/writing to, which can result in surprising
> behaviour.
> 
> The patch series came out of the discussion around commit 38e0885, which
> addressed a BUG_ON() being triggered when a page was faulted in with PROT_NONE
> set but having been overridden by FOLL_FORCE. do_numa_page() was run on the
> assumption the page _must_ be one marked for NUMA node migration as an actual
> PROT_NONE page would have been dealt with prior to this code path, however
> FOLL_FORCE introduced a situation where this assumption did not hold.
> 
> See https://marc.info/?l=linux-mm&m=147585445805166 for the patch proposal.

I like this cleanup. Tracking FOLL_FORCE users was always a nightmare
and the flag behavior is really subtle so we should better be explicit
about it. I haven't gone through each patch separately but rather
applied the whole series and checked the resulting diff. This all seems
OK to me and feel free to add
Acked-by: Michal Hocko <mhocko@suse.com>

I am wondering whether we can go further. E.g. it is not really clear to
me whether we need an explicit FOLL_REMOTE when we can in fact check
mm != current->mm and imply that. Maybe there are some contexts which
wouldn't work, I haven't checked.

Then I am also wondering about FOLL_TOUCH behavior.
__get_user_pages_unlocked has only few callers which used to be
get_user_pages_unlocked before 1e9877902dc7e ("mm/gup: Introduce
get_user_pages_remote()"). To me a dropped FOLL_TOUCH seems
unintentional. Now that get_user_pages_unlocked has gup_flags argument I
guess we might want to get rid of the __g-u-p-u version altogether, no?

__get_user_pages is quite low level and imho shouldn't be exported. It's
only user - kvm - should rather pull those two functions to gup instead
and export them. There is nothing really KVM specific in them.

I also cannot say I would be entirely thrilled about get_user_pages_locked,
we only have one user which can simply do lock g-u-p unlock AFAICS.

I guess there is more work in that area and I do not want to impose all
that work on you, but I couldn't resist once I saw you playing in that
area ;) Definitely a good start!
-- 
Michal Hocko
SUSE Labs

^ permalink raw reply

* [PATCH v2 2/4] ARM: dts: pxa: add pxa25x cpu operating points
From: Robert Jarzmik @ 2016-10-18 15:30 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161018113944.GC11471@vireshk-i7>

Viresh Kumar <viresh.kumar@linaro.org> writes:

> On 15-10-16, 21:57, Robert Jarzmik wrote:
>> Add the relevant data taken from the PXA 25x Electrical, Mechanical, and
>> Thermal Specfication. This will be input data for cpufreq-dt driver.
>> 
>> Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
>> ---
>>  arch/arm/boot/dts/pxa25x.dtsi | 25 +++++++++++++++++++++++++
>>  1 file changed, 25 insertions(+)
>> 
>> diff --git a/arch/arm/boot/dts/pxa25x.dtsi b/arch/arm/boot/dts/pxa25x.dtsi
>> index 0d1e012178c4..16b4e8bad4a5 100644
>> --- a/arch/arm/boot/dts/pxa25x.dtsi
>> +++ b/arch/arm/boot/dts/pxa25x.dtsi
>> @@ -89,4 +89,29 @@
>>  		clocks = <&clktimer>;
>>  		status = "okay";
>>  	};
>> +
>> +	pxa250_opp_table: opp_table0 {
>> +		compatible = "operating-points-v2";
>> +
>> +		opp at 99500 {
>
> We have been keeping the values in ^^^ same as the values present
> below. Any specific reason for making it different here ?
No, that's a good comment, I'll change that.

I wrote this incrementaly, first the node, then the opp-hz. Then I realized that
the source crystal, at 3.8684 MHz didn't provide a round 99.5 MHz core clock,
but a 99.5328 MHz clock.

Anyway, I'll change that ... let's say into opp at 99533 in this case ?

-- 
Robert

^ permalink raw reply

* [PATCH 2/2] scripts/gdb: fixup some pep8 errors in proc.py
From: Kieran Bingham @ 2016-10-18 15:27 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1476803249-23328-2-git-send-email-peter.griffin@linaro.org>

Hi Pete,

On 18/10/16 16:07, Peter Griffin wrote:
> proc.py:22:1: E302 expected 2 blank lines, found 1
> proc.py:200:1: E302 expected 2 blank lines, found 1
> 
> Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
> ---
>  scripts/gdb/linux/proc.py | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/scripts/gdb/linux/proc.py b/scripts/gdb/linux/proc.py
> index f20fcfa..2d6f74e 100644
> --- a/scripts/gdb/linux/proc.py
> +++ b/scripts/gdb/linux/proc.py
> @@ -18,6 +18,7 @@ from linux import tasks
>  from linux import lists
>  from struct import *
>  
> +

This was added by patch 1, and can be squashed there.

>  class LxCmdLine(gdb.Command):
>      """ Report the Linux Commandline used in the current kernel.
>          Equivalent to cat /proc/cmdline on a running target"""
> @@ -196,6 +197,7 @@ values of that process namespace"""
>  
>  LxMounts()
>  
> +

Likewise...

>  class LxFdtDump(gdb.Command):
>      """Output Flattened Device Tree header and dump FDT blob to a file
>         Equivalent to 'cat /proc/fdt > fdtdump.dtb' on a running target"""
> 

-- 
Regards

Kieran Bingham

^ permalink raw reply

* [PATCH V3 1/3] ACPI, PCI IRQ: add PCI_USING penalty for ISA interrupts
From: Sinan Kaya @ 2016-10-18 15:20 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161018135912.GD18903@localhost>

On 10/18/2016 6:59 AM, Bjorn Helgaas wrote:
>> However, this function only gets called if the IRQ number is greater than
>> > 16 and acpi_irq_get_penalty function gets called before ACPI start in
>> > acpi_isa_irq_available and acpi_penalize_isa_irq functions. We can't rely
>> > on iterating the link list.

Maybe, I am missing context here. I can add this paragraph to the commit. 

When we started cleaning the code we got rid of the acpi_irq_penalty_init function
in favor of acpi_irq_pci_sharing_penalty function as it does have some fair
amount of code duplication.

I tried putting back the acpi_irq_pci_sharing_penalty function into the ISA
IRQ path again during the debug and the machine died way too early. We couldn't
collect any debug message.

This is telling me that we can't even iterate the link list when these two API
is called. ISA IRQ need to be handled with special care due to calling order.


> It seems wrong to me that we call acpi_irq_get_penalty() from
> acpi_irq_penalty_update() and acpi_penalize_isa_irq().  It seems like they
> should just manipulate acpi_isa_irq_penalty[irq] directly.
> 
> acpi_irq_penalty_update() is for command-line parameters, so it certainly
> doesn't need the acpi_irq_pci_sharing_penalty() information (the
> acpi_link_list should be empty at the time we process the command-line
> parameters).
> 
> acpi_penalize_isa_irq() is telling us that a PNP or ACPI device is using
> the IRQ -- this should modify the IRQ's penalty, but it shouldn't depend on
> the acpi_irq_pci_sharing_penalty() value at all.
> 

acpi_irq_get_penalty function knows how to deal with ISA IRQ. So, it is harmless
to call it. Also, reading the acpi_isa_irq_penalty array directly isn't also right.
It doesn't contain the SCI penalty. So, it returns incorrect penalty value.

The rule of thumb is:
- all PCI/SCI penalty reads need to go through acpi_isa_irq_penalty function
- all ISA penalty writes need to go through acpi_isa_irq_penalty array directly.
- we do not support modifying the PCI IRQ penalties greater than the ISA IRQ numbers.
The original code supported this.


-- 
Sinan Kaya
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox