11e3121bfSAisheng Dong // SPDX-License-Identifier: GPL-2.0+ 21e3121bfSAisheng Dong /* 31e3121bfSAisheng Dong * Copyright 2018 NXP 41e3121bfSAisheng Dong * Dong Aisheng <aisheng.dong@nxp.com> 51e3121bfSAisheng Dong */ 61e3121bfSAisheng Dong 71e3121bfSAisheng Dong #include <linux/clk-provider.h> 81e3121bfSAisheng Dong #include <linux/err.h> 91e3121bfSAisheng Dong #include <linux/io.h> 101e3121bfSAisheng Dong #include <linux/module.h> 111e3121bfSAisheng Dong #include <linux/of.h> 121e3121bfSAisheng Dong #include <linux/of_device.h> 131e3121bfSAisheng Dong #include <linux/platform_device.h> 141e3121bfSAisheng Dong #include <linux/slab.h> 151e3121bfSAisheng Dong 161e3121bfSAisheng Dong #include "clk-scu.h" 171e3121bfSAisheng Dong #include "clk-imx8qxp-lpcg.h" 181e3121bfSAisheng Dong 19*08972760SAisheng Dong #include <dt-bindings/clock/imx8-clock.h> 201e3121bfSAisheng Dong 211e3121bfSAisheng Dong /* 221e3121bfSAisheng Dong * struct imx8qxp_lpcg_data - Description of one LPCG clock 231e3121bfSAisheng Dong * @id: clock ID 241e3121bfSAisheng Dong * @name: clock name 251e3121bfSAisheng Dong * @parent: parent clock name 261e3121bfSAisheng Dong * @flags: common clock flags 271e3121bfSAisheng Dong * @offset: offset of this LPCG clock 281e3121bfSAisheng Dong * @bit_idx: bit index of this LPCG clock 291e3121bfSAisheng Dong * @hw_gate: whether supports HW autogate 301e3121bfSAisheng Dong * 311e3121bfSAisheng Dong * This structure describes one LPCG clock 321e3121bfSAisheng Dong */ 331e3121bfSAisheng Dong struct imx8qxp_lpcg_data { 341e3121bfSAisheng Dong int id; 351e3121bfSAisheng Dong char *name; 361e3121bfSAisheng Dong char *parent; 371e3121bfSAisheng Dong unsigned long flags; 381e3121bfSAisheng Dong u32 offset; 391e3121bfSAisheng Dong u8 bit_idx; 401e3121bfSAisheng Dong bool hw_gate; 411e3121bfSAisheng Dong }; 421e3121bfSAisheng Dong 431e3121bfSAisheng Dong /* 441e3121bfSAisheng Dong * struct imx8qxp_ss_lpcg - Description of one subsystem LPCG clocks 451e3121bfSAisheng Dong * @lpcg: LPCG clocks array of one subsystem 461e3121bfSAisheng Dong * @num_lpcg: the number of LPCG clocks 471e3121bfSAisheng Dong * @num_max: the maximum number of LPCG clocks 481e3121bfSAisheng Dong * 491e3121bfSAisheng Dong * This structure describes each subsystem LPCG clocks information 501e3121bfSAisheng Dong * which then will be used to create respective LPCGs clocks 511e3121bfSAisheng Dong */ 521e3121bfSAisheng Dong struct imx8qxp_ss_lpcg { 531e3121bfSAisheng Dong const struct imx8qxp_lpcg_data *lpcg; 541e3121bfSAisheng Dong u8 num_lpcg; 551e3121bfSAisheng Dong u8 num_max; 561e3121bfSAisheng Dong }; 571e3121bfSAisheng Dong 581e3121bfSAisheng Dong static const struct imx8qxp_lpcg_data imx8qxp_lpcg_adma[] = { 59*08972760SAisheng Dong { IMX_ADMA_LPCG_UART0_IPG_CLK, "uart0_lpcg_ipg_clk", "dma_ipg_clk_root", 0, ADMA_LPUART_0_LPCG, 16, 0, }, 60*08972760SAisheng Dong { IMX_ADMA_LPCG_UART0_BAUD_CLK, "uart0_lpcg_baud_clk", "uart0_clk", 0, ADMA_LPUART_0_LPCG, 0, 0, }, 61*08972760SAisheng Dong { IMX_ADMA_LPCG_UART1_IPG_CLK, "uart1_lpcg_ipg_clk", "dma_ipg_clk_root", 0, ADMA_LPUART_1_LPCG, 16, 0, }, 62*08972760SAisheng Dong { IMX_ADMA_LPCG_UART1_BAUD_CLK, "uart1_lpcg_baud_clk", "uart1_clk", 0, ADMA_LPUART_1_LPCG, 0, 0, }, 63*08972760SAisheng Dong { IMX_ADMA_LPCG_UART2_IPG_CLK, "uart2_lpcg_ipg_clk", "dma_ipg_clk_root", 0, ADMA_LPUART_2_LPCG, 16, 0, }, 64*08972760SAisheng Dong { IMX_ADMA_LPCG_UART2_BAUD_CLK, "uart2_lpcg_baud_clk", "uart2_clk", 0, ADMA_LPUART_2_LPCG, 0, 0, }, 65*08972760SAisheng Dong { IMX_ADMA_LPCG_UART3_IPG_CLK, "uart3_lpcg_ipg_clk", "dma_ipg_clk_root", 0, ADMA_LPUART_3_LPCG, 16, 0, }, 66*08972760SAisheng Dong { IMX_ADMA_LPCG_UART3_BAUD_CLK, "uart3_lpcg_baud_clk", "uart3_clk", 0, ADMA_LPUART_3_LPCG, 0, 0, }, 67*08972760SAisheng Dong { IMX_ADMA_LPCG_I2C0_IPG_CLK, "i2c0_lpcg_ipg_clk", "dma_ipg_clk_root", 0, ADMA_LPI2C_0_LPCG, 16, 0, }, 68*08972760SAisheng Dong { IMX_ADMA_LPCG_I2C0_CLK, "i2c0_lpcg_clk", "i2c0_clk", 0, ADMA_LPI2C_0_LPCG, 0, 0, }, 69*08972760SAisheng Dong { IMX_ADMA_LPCG_I2C1_IPG_CLK, "i2c1_lpcg_ipg_clk", "dma_ipg_clk_root", 0, ADMA_LPI2C_1_LPCG, 16, 0, }, 70*08972760SAisheng Dong { IMX_ADMA_LPCG_I2C1_CLK, "i2c1_lpcg_clk", "i2c1_clk", 0, ADMA_LPI2C_1_LPCG, 0, 0, }, 71*08972760SAisheng Dong { IMX_ADMA_LPCG_I2C2_IPG_CLK, "i2c2_lpcg_ipg_clk", "dma_ipg_clk_root", 0, ADMA_LPI2C_2_LPCG, 16, 0, }, 72*08972760SAisheng Dong { IMX_ADMA_LPCG_I2C2_CLK, "i2c2_lpcg_clk", "i2c2_clk", 0, ADMA_LPI2C_2_LPCG, 0, 0, }, 73*08972760SAisheng Dong { IMX_ADMA_LPCG_I2C3_IPG_CLK, "i2c3_lpcg_ipg_clk", "dma_ipg_clk_root", 0, ADMA_LPI2C_3_LPCG, 16, 0, }, 74*08972760SAisheng Dong { IMX_ADMA_LPCG_I2C3_CLK, "i2c3_lpcg_clk", "i2c3_clk", 0, ADMA_LPI2C_3_LPCG, 0, 0, }, 751e3121bfSAisheng Dong }; 761e3121bfSAisheng Dong 771e3121bfSAisheng Dong static const struct imx8qxp_ss_lpcg imx8qxp_ss_adma = { 781e3121bfSAisheng Dong .lpcg = imx8qxp_lpcg_adma, 791e3121bfSAisheng Dong .num_lpcg = ARRAY_SIZE(imx8qxp_lpcg_adma), 80*08972760SAisheng Dong .num_max = IMX_ADMA_LPCG_CLK_END, 811e3121bfSAisheng Dong }; 821e3121bfSAisheng Dong 831e3121bfSAisheng Dong static const struct imx8qxp_lpcg_data imx8qxp_lpcg_conn[] = { 84*08972760SAisheng Dong { IMX_CONN_LPCG_SDHC0_PER_CLK, "sdhc0_lpcg_per_clk", "sdhc0_clk", 0, CONN_USDHC_0_LPCG, 0, 0, }, 85*08972760SAisheng Dong { IMX_CONN_LPCG_SDHC0_IPG_CLK, "sdhc0_lpcg_ipg_clk", "conn_ipg_clk_root", 0, CONN_USDHC_0_LPCG, 16, 0, }, 86*08972760SAisheng Dong { IMX_CONN_LPCG_SDHC0_HCLK, "sdhc0_lpcg_ahb_clk", "conn_axi_clk_root", 0, CONN_USDHC_0_LPCG, 20, 0, }, 87*08972760SAisheng Dong { IMX_CONN_LPCG_SDHC1_PER_CLK, "sdhc1_lpcg_per_clk", "sdhc1_clk", 0, CONN_USDHC_1_LPCG, 0, 0, }, 88*08972760SAisheng Dong { IMX_CONN_LPCG_SDHC1_IPG_CLK, "sdhc1_lpcg_ipg_clk", "conn_ipg_clk_root", 0, CONN_USDHC_1_LPCG, 16, 0, }, 89*08972760SAisheng Dong { IMX_CONN_LPCG_SDHC1_HCLK, "sdhc1_lpcg_ahb_clk", "conn_axi_clk_root", 0, CONN_USDHC_1_LPCG, 20, 0, }, 90*08972760SAisheng Dong { IMX_CONN_LPCG_SDHC2_PER_CLK, "sdhc2_lpcg_per_clk", "sdhc2_clk", 0, CONN_USDHC_2_LPCG, 0, 0, }, 91*08972760SAisheng Dong { IMX_CONN_LPCG_SDHC2_IPG_CLK, "sdhc2_lpcg_ipg_clk", "conn_ipg_clk_root", 0, CONN_USDHC_2_LPCG, 16, 0, }, 92*08972760SAisheng Dong { IMX_CONN_LPCG_SDHC2_HCLK, "sdhc2_lpcg_ahb_clk", "conn_axi_clk_root", 0, CONN_USDHC_2_LPCG, 20, 0, }, 93*08972760SAisheng Dong { IMX_CONN_LPCG_ENET0_ROOT_CLK, "enet0_ipg_root_clk", "enet0_clk", 0, CONN_ENET_0_LPCG, 0, 0, }, 94*08972760SAisheng Dong { IMX_CONN_LPCG_ENET0_TX_CLK, "enet0_tx_clk", "enet0_clk", 0, CONN_ENET_0_LPCG, 4, 0, }, 95*08972760SAisheng Dong { IMX_CONN_LPCG_ENET0_AHB_CLK, "enet0_ahb_clk", "conn_axi_clk_root", 0, CONN_ENET_0_LPCG, 8, 0, }, 96*08972760SAisheng Dong { IMX_CONN_LPCG_ENET0_IPG_S_CLK, "enet0_ipg_s_clk", "conn_ipg_clk_root", 0, CONN_ENET_0_LPCG, 20, 0, }, 97*08972760SAisheng Dong { IMX_CONN_LPCG_ENET0_IPG_CLK, "enet0_ipg_clk", "enet0_ipg_s_clk", 0, CONN_ENET_0_LPCG, 16, 0, }, 98*08972760SAisheng Dong { IMX_CONN_LPCG_ENET1_ROOT_CLK, "enet1_ipg_root_clk", "enet1_clk", 0, CONN_ENET_1_LPCG, 0, 0, }, 99*08972760SAisheng Dong { IMX_CONN_LPCG_ENET1_TX_CLK, "enet1_tx_clk", "enet1_clk", 0, CONN_ENET_1_LPCG, 4, 0, }, 100*08972760SAisheng Dong { IMX_CONN_LPCG_ENET1_AHB_CLK, "enet1_ahb_clk", "conn_axi_clk_root", 0, CONN_ENET_1_LPCG, 8, 0, }, 101*08972760SAisheng Dong { IMX_CONN_LPCG_ENET1_IPG_S_CLK, "enet1_ipg_s_clk", "conn_ipg_clk_root", 0, CONN_ENET_1_LPCG, 20, 0, }, 102*08972760SAisheng Dong { IMX_CONN_LPCG_ENET1_IPG_CLK, "enet1_ipg_clk", "enet0_ipg_s_clk", 0, CONN_ENET_1_LPCG, 16, 0, }, 1031e3121bfSAisheng Dong }; 1041e3121bfSAisheng Dong 1051e3121bfSAisheng Dong static const struct imx8qxp_ss_lpcg imx8qxp_ss_conn = { 1061e3121bfSAisheng Dong .lpcg = imx8qxp_lpcg_conn, 1071e3121bfSAisheng Dong .num_lpcg = ARRAY_SIZE(imx8qxp_lpcg_conn), 108*08972760SAisheng Dong .num_max = IMX_CONN_LPCG_CLK_END, 1091e3121bfSAisheng Dong }; 1101e3121bfSAisheng Dong 1111e3121bfSAisheng Dong static const struct imx8qxp_lpcg_data imx8qxp_lpcg_lsio[] = { 112*08972760SAisheng Dong { IMX_LSIO_LPCG_PWM0_IPG_CLK, "pwm0_lpcg_ipg_clk", "pwm0_clk", 0, LSIO_PWM_0_LPCG, 0, 0, }, 113*08972760SAisheng Dong { IMX_LSIO_LPCG_PWM0_IPG_HF_CLK, "pwm0_lpcg_ipg_hf_clk", "pwm0_clk", 0, LSIO_PWM_0_LPCG, 4, 0, }, 114*08972760SAisheng Dong { IMX_LSIO_LPCG_PWM0_IPG_S_CLK, "pwm0_lpcg_ipg_s_clk", "pwm0_clk", 0, LSIO_PWM_0_LPCG, 16, 0, }, 115*08972760SAisheng Dong { IMX_LSIO_LPCG_PWM0_IPG_SLV_CLK, "pwm0_lpcg_ipg_slv_clk", "lsio_bus_clk_root", 0, LSIO_PWM_0_LPCG, 20, 0, }, 116*08972760SAisheng Dong { IMX_LSIO_LPCG_PWM0_IPG_MSTR_CLK, "pwm0_lpcg_ipg_mstr_clk", "pwm0_clk", 0, LSIO_PWM_0_LPCG, 24, 0, }, 117*08972760SAisheng Dong { IMX_LSIO_LPCG_PWM1_IPG_CLK, "pwm1_lpcg_ipg_clk", "pwm1_clk", 0, LSIO_PWM_1_LPCG, 0, 0, }, 118*08972760SAisheng Dong { IMX_LSIO_LPCG_PWM1_IPG_HF_CLK, "pwm1_lpcg_ipg_hf_clk", "pwm1_clk", 0, LSIO_PWM_1_LPCG, 4, 0, }, 119*08972760SAisheng Dong { IMX_LSIO_LPCG_PWM1_IPG_S_CLK, "pwm1_lpcg_ipg_s_clk", "pwm1_clk", 0, LSIO_PWM_1_LPCG, 16, 0, }, 120*08972760SAisheng Dong { IMX_LSIO_LPCG_PWM1_IPG_SLV_CLK, "pwm1_lpcg_ipg_slv_clk", "lsio_bus_clk_root", 0, LSIO_PWM_1_LPCG, 20, 0, }, 121*08972760SAisheng Dong { IMX_LSIO_LPCG_PWM1_IPG_MSTR_CLK, "pwm1_lpcg_ipg_mstr_clk", "pwm1_clk", 0, LSIO_PWM_1_LPCG, 24, 0, }, 122*08972760SAisheng Dong { IMX_LSIO_LPCG_PWM2_IPG_CLK, "pwm2_lpcg_ipg_clk", "pwm2_clk", 0, LSIO_PWM_2_LPCG, 0, 0, }, 123*08972760SAisheng Dong { IMX_LSIO_LPCG_PWM2_IPG_HF_CLK, "pwm2_lpcg_ipg_hf_clk", "pwm2_clk", 0, LSIO_PWM_2_LPCG, 4, 0, }, 124*08972760SAisheng Dong { IMX_LSIO_LPCG_PWM2_IPG_S_CLK, "pwm2_lpcg_ipg_s_clk", "pwm2_clk", 0, LSIO_PWM_2_LPCG, 16, 0, }, 125*08972760SAisheng Dong { IMX_LSIO_LPCG_PWM2_IPG_SLV_CLK, "pwm2_lpcg_ipg_slv_clk", "lsio_bus_clk_root", 0, LSIO_PWM_2_LPCG, 20, 0, }, 126*08972760SAisheng Dong { IMX_LSIO_LPCG_PWM2_IPG_MSTR_CLK, "pwm2_lpcg_ipg_mstr_clk", "pwm2_clk", 0, LSIO_PWM_2_LPCG, 24, 0, }, 127*08972760SAisheng Dong { IMX_LSIO_LPCG_PWM3_IPG_CLK, "pwm3_lpcg_ipg_clk", "pwm3_clk", 0, LSIO_PWM_3_LPCG, 0, 0, }, 128*08972760SAisheng Dong { IMX_LSIO_LPCG_PWM3_IPG_HF_CLK, "pwm3_lpcg_ipg_hf_clk", "pwm3_clk", 0, LSIO_PWM_3_LPCG, 4, 0, }, 129*08972760SAisheng Dong { IMX_LSIO_LPCG_PWM3_IPG_S_CLK, "pwm3_lpcg_ipg_s_clk", "pwm3_clk", 0, LSIO_PWM_3_LPCG, 16, 0, }, 130*08972760SAisheng Dong { IMX_LSIO_LPCG_PWM3_IPG_SLV_CLK, "pwm3_lpcg_ipg_slv_clk", "lsio_bus_clk_root", 0, LSIO_PWM_3_LPCG, 20, 0, }, 131*08972760SAisheng Dong { IMX_LSIO_LPCG_PWM3_IPG_MSTR_CLK, "pwm3_lpcg_ipg_mstr_clk", "pwm3_clk", 0, LSIO_PWM_3_LPCG, 24, 0, }, 132*08972760SAisheng Dong { IMX_LSIO_LPCG_PWM4_IPG_CLK, "pwm4_lpcg_ipg_clk", "pwm4_clk", 0, LSIO_PWM_4_LPCG, 0, 0, }, 133*08972760SAisheng Dong { IMX_LSIO_LPCG_PWM4_IPG_HF_CLK, "pwm4_lpcg_ipg_hf_clk", "pwm4_clk", 0, LSIO_PWM_4_LPCG, 4, 0, }, 134*08972760SAisheng Dong { IMX_LSIO_LPCG_PWM4_IPG_S_CLK, "pwm4_lpcg_ipg_s_clk", "pwm4_clk", 0, LSIO_PWM_4_LPCG, 16, 0, }, 135*08972760SAisheng Dong { IMX_LSIO_LPCG_PWM4_IPG_SLV_CLK, "pwm4_lpcg_ipg_slv_clk", "lsio_bus_clk_root", 0, LSIO_PWM_4_LPCG, 20, 0, }, 136*08972760SAisheng Dong { IMX_LSIO_LPCG_PWM4_IPG_MSTR_CLK, "pwm4_lpcg_ipg_mstr_clk", "pwm4_clk", 0, LSIO_PWM_4_LPCG, 24, 0, }, 137*08972760SAisheng Dong { IMX_LSIO_LPCG_PWM5_IPG_CLK, "pwm5_lpcg_ipg_clk", "pwm5_clk", 0, LSIO_PWM_5_LPCG, 0, 0, }, 138*08972760SAisheng Dong { IMX_LSIO_LPCG_PWM5_IPG_HF_CLK, "pwm5_lpcg_ipg_hf_clk", "pwm5_clk", 0, LSIO_PWM_5_LPCG, 4, 0, }, 139*08972760SAisheng Dong { IMX_LSIO_LPCG_PWM5_IPG_S_CLK, "pwm5_lpcg_ipg_s_clk", "pwm5_clk", 0, LSIO_PWM_5_LPCG, 16, 0, }, 140*08972760SAisheng Dong { IMX_LSIO_LPCG_PWM5_IPG_SLV_CLK, "pwm5_lpcg_ipg_slv_clk", "lsio_bus_clk_root", 0, LSIO_PWM_5_LPCG, 20, 0, }, 141*08972760SAisheng Dong { IMX_LSIO_LPCG_PWM5_IPG_MSTR_CLK, "pwm5_lpcg_ipg_mstr_clk", "pwm5_clk", 0, LSIO_PWM_5_LPCG, 24, 0, }, 142*08972760SAisheng Dong { IMX_LSIO_LPCG_PWM6_IPG_CLK, "pwm6_lpcg_ipg_clk", "pwm6_clk", 0, LSIO_PWM_6_LPCG, 0, 0, }, 143*08972760SAisheng Dong { IMX_LSIO_LPCG_PWM6_IPG_HF_CLK, "pwm6_lpcg_ipg_hf_clk", "pwm6_clk", 0, LSIO_PWM_6_LPCG, 4, 0, }, 144*08972760SAisheng Dong { IMX_LSIO_LPCG_PWM6_IPG_S_CLK, "pwm6_lpcg_ipg_s_clk", "pwm6_clk", 0, LSIO_PWM_6_LPCG, 16, 0, }, 145*08972760SAisheng Dong { IMX_LSIO_LPCG_PWM6_IPG_SLV_CLK, "pwm6_lpcg_ipg_slv_clk", "lsio_bus_clk_root", 0, LSIO_PWM_6_LPCG, 20, 0, }, 146*08972760SAisheng Dong { IMX_LSIO_LPCG_PWM6_IPG_MSTR_CLK, "pwm6_lpcg_ipg_mstr_clk", "pwm6_clk", 0, LSIO_PWM_6_LPCG, 24, 0, }, 1471e3121bfSAisheng Dong }; 1481e3121bfSAisheng Dong 1491e3121bfSAisheng Dong static const struct imx8qxp_ss_lpcg imx8qxp_ss_lsio = { 1501e3121bfSAisheng Dong .lpcg = imx8qxp_lpcg_lsio, 1511e3121bfSAisheng Dong .num_lpcg = ARRAY_SIZE(imx8qxp_lpcg_lsio), 152*08972760SAisheng Dong .num_max = IMX_LSIO_LPCG_CLK_END, 1531e3121bfSAisheng Dong }; 1541e3121bfSAisheng Dong 1551e3121bfSAisheng Dong static int imx8qxp_lpcg_clk_probe(struct platform_device *pdev) 1561e3121bfSAisheng Dong { 1571e3121bfSAisheng Dong struct device *dev = &pdev->dev; 1581e3121bfSAisheng Dong struct device_node *np = dev->of_node; 1591e3121bfSAisheng Dong struct clk_hw_onecell_data *clk_data; 1601e3121bfSAisheng Dong const struct imx8qxp_ss_lpcg *ss_lpcg; 1611e3121bfSAisheng Dong const struct imx8qxp_lpcg_data *lpcg; 1621e3121bfSAisheng Dong struct resource *res; 1631e3121bfSAisheng Dong struct clk_hw **clks; 1641e3121bfSAisheng Dong void __iomem *base; 1651e3121bfSAisheng Dong int i; 1661e3121bfSAisheng Dong 1671e3121bfSAisheng Dong ss_lpcg = of_device_get_match_data(dev); 1681e3121bfSAisheng Dong if (!ss_lpcg) 1691e3121bfSAisheng Dong return -ENODEV; 1701e3121bfSAisheng Dong 1711e3121bfSAisheng Dong res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1721e3121bfSAisheng Dong base = devm_ioremap(dev, res->start, resource_size(res)); 1731e3121bfSAisheng Dong if (!base) 1741e3121bfSAisheng Dong return -ENOMEM; 1751e3121bfSAisheng Dong 1761e3121bfSAisheng Dong clk_data = devm_kzalloc(&pdev->dev, struct_size(clk_data, hws, 1771e3121bfSAisheng Dong ss_lpcg->num_max), GFP_KERNEL); 1781e3121bfSAisheng Dong if (!clk_data) 1791e3121bfSAisheng Dong return -ENOMEM; 1801e3121bfSAisheng Dong 1811e3121bfSAisheng Dong clk_data->num = ss_lpcg->num_max; 1821e3121bfSAisheng Dong clks = clk_data->hws; 1831e3121bfSAisheng Dong 1841e3121bfSAisheng Dong for (i = 0; i < ss_lpcg->num_lpcg; i++) { 1851e3121bfSAisheng Dong lpcg = ss_lpcg->lpcg + i; 1861e3121bfSAisheng Dong clks[lpcg->id] = imx_clk_lpcg_scu(lpcg->name, lpcg->parent, 1871e3121bfSAisheng Dong lpcg->flags, base + lpcg->offset, 1881e3121bfSAisheng Dong lpcg->bit_idx, lpcg->hw_gate); 1891e3121bfSAisheng Dong } 1901e3121bfSAisheng Dong 1911e3121bfSAisheng Dong for (i = 0; i < clk_data->num; i++) { 1921e3121bfSAisheng Dong if (IS_ERR(clks[i])) 1931e3121bfSAisheng Dong pr_warn("i.MX clk %u: register failed with %ld\n", 1941e3121bfSAisheng Dong i, PTR_ERR(clks[i])); 1951e3121bfSAisheng Dong } 1961e3121bfSAisheng Dong 1971e3121bfSAisheng Dong return of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_data); 1981e3121bfSAisheng Dong } 1991e3121bfSAisheng Dong 2001e3121bfSAisheng Dong static const struct of_device_id imx8qxp_lpcg_match[] = { 2011e3121bfSAisheng Dong { .compatible = "fsl,imx8qxp-lpcg-adma", &imx8qxp_ss_adma, }, 2021e3121bfSAisheng Dong { .compatible = "fsl,imx8qxp-lpcg-conn", &imx8qxp_ss_conn, }, 2031e3121bfSAisheng Dong { .compatible = "fsl,imx8qxp-lpcg-lsio", &imx8qxp_ss_lsio, }, 2041e3121bfSAisheng Dong { /* sentinel */ } 2051e3121bfSAisheng Dong }; 2061e3121bfSAisheng Dong 2071e3121bfSAisheng Dong static struct platform_driver imx8qxp_lpcg_clk_driver = { 2081e3121bfSAisheng Dong .driver = { 2091e3121bfSAisheng Dong .name = "imx8qxp-lpcg-clk", 2101e3121bfSAisheng Dong .of_match_table = imx8qxp_lpcg_match, 2111e3121bfSAisheng Dong .suppress_bind_attrs = true, 2121e3121bfSAisheng Dong }, 2131e3121bfSAisheng Dong .probe = imx8qxp_lpcg_clk_probe, 2141e3121bfSAisheng Dong }; 2151e3121bfSAisheng Dong 2161e3121bfSAisheng Dong builtin_platform_driver(imx8qxp_lpcg_clk_driver); 217