]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
Merge remote-tracking branch 'clk/clk-next'
authorStephen Rothwell <sfr@canb.auug.org.au>
Thu, 11 Feb 2016 03:26:48 +0000 (14:26 +1100)
committerStephen Rothwell <sfr@canb.auug.org.au>
Thu, 11 Feb 2016 03:26:48 +0000 (14:26 +1100)
59 files changed:
Documentation/devicetree/bindings/clock/axi-clkgen.txt
Documentation/devicetree/bindings/clock/brcm,iproc-clocks.txt
Documentation/devicetree/bindings/clock/rockchip,rk3036-cru.txt
Documentation/devicetree/bindings/clock/xgene.txt
arch/arm/mach-s3c24xx/Kconfig
drivers/clk/Kconfig
drivers/clk/Makefile
drivers/clk/bcm/clk-cygnus.c
drivers/clk/bcm/clk-iproc-pll.c
drivers/clk/bcm/clk-iproc.h
drivers/clk/clk-axi-clkgen.c
drivers/clk/clk-composite.c
drivers/clk/clk-divider.c
drivers/clk/clk-fixed-factor.c
drivers/clk/clk-fixed-rate.c
drivers/clk/clk-fractional-divider.c
drivers/clk/clk-gate.c
drivers/clk/clk-gpio.c
drivers/clk/clk-multiplier.c
drivers/clk/clk-mux.c
drivers/clk/clk-palmas.c
drivers/clk/clk-s2mps11.c
drivers/clk/clk-scpi.c
drivers/clk/clk-vt8500.c
drivers/clk/clk-xgene.c
drivers/clk/clk.c
drivers/clk/imx/clk-busy.c
drivers/clk/imx/clk-fixup-div.c
drivers/clk/imx/clk-fixup-mux.c
drivers/clk/imx/clk-gate-exclusive.c
drivers/clk/mediatek/clk-gate.c
drivers/clk/mediatek/clk-gate.h
drivers/clk/mediatek/clk-mtk.c
drivers/clk/meson/clkc.c
drivers/clk/mvebu/common.c
drivers/clk/mvebu/dove-divider.c
drivers/clk/mvebu/kirkwood.c
drivers/clk/mxs/clk-div.c
drivers/clk/nxp/clk-lpc18xx-ccu.c
drivers/clk/nxp/clk-lpc32xx.c
drivers/clk/qcom/common.c
drivers/clk/qcom/gcc-msm8916.c
drivers/clk/rockchip/clk-rk3036.c
drivers/clk/rockchip/clk-rk3368.c
drivers/clk/rockchip/clk.c
drivers/clk/samsung/Kconfig
drivers/clk/socfpga/clk-pll-a10.c
drivers/clk/st/clkgen-fsyn.c
drivers/clk/st/clkgen-mux.c
drivers/clk/ti/composite.c
drivers/clk/ti/divider.c
drivers/clk/ti/gate.c
drivers/clk/ti/mux.c
drivers/clk/versatile/clk-icst.c
include/dt-bindings/clock/bcm-cygnus.h
include/dt-bindings/clock/lpc32xx-clock.h
include/dt-bindings/clock/qcom,gcc-msm8916.h
include/linux/clk-provider.h
include/linux/device.h

index 20e1704e7df2110c518ce71ca07e94a0b4db574a..fb40da303d25c8f13093aafe43df83eaf2f88f47 100644 (file)
@@ -8,7 +8,10 @@ Required properties:
 - compatible : shall be "adi,axi-clkgen-1.00.a" or "adi,axi-clkgen-2.00.a".
 - #clock-cells : from common clock binding; Should always be set to 0.
 - reg : Address and length of the axi-clkgen register set.
-- clocks : Phandle and clock specifier for the parent clock.
+- clocks : Phandle and clock specifier for the parent clock(s). This must
+       either reference one clock if only the first clock input is connected or two
+       if both clock inputs are connected. For the later case the clock connected
+       to the first input must be specified first.
 
 Optional properties:
 - clock-output-names : From common clock binding.
index 0b35e71b39e891fb15cfbac0d6af1d4763192e40..6f66e9aa354c1996beb76e3e9c830dc25b288159 100644 (file)
@@ -92,6 +92,7 @@ PLL and leaf clock compatible strings for Cygnus are:
     "brcm,cygnus-lcpll0"
     "brcm,cygnus-mipipll"
     "brcm,cygnus-asiu-clk"
+    "brcm,cygnus-audiopll"
 
 The following table defines the set of PLL/clock index and ID for Cygnus.
 These clock IDs are defined in:
@@ -131,6 +132,11 @@ These clock IDs are defined in:
     ch4_unused mipipll          5       BCM_CYGNUS_MIPIPLL_CH4_UNUSED
     ch5_unused mipipll          6       BCM_CYGNUS_MIPIPLL_CH5_UNUSED
 
+    audiopll   crystal          0       BCM_CYGNUS_AUDIOPLL
+    ch0_audio  audiopll         1       BCM_CYGNUS_AUDIOPLL_CH0
+    ch1_audio  audiopll         2       BCM_CYGNUS_AUDIOPLL_CH1
+    ch2_audio  audiopll         3       BCM_CYGNUS_AUDIOPLL_CH2
+
 Northstar and Northstar Plus
 ------
 PLL and leaf clock compatible strings for Northstar and Northstar Plus are:
index ace05992a262592fb22f88db5c2e13036e20c015..20df350b9ef3d491b3e2e714f8877d74477afcd8 100644 (file)
@@ -30,7 +30,7 @@ that they are defined using standard clock bindings with following
 clock-output-names:
  - "xin24m" - crystal input - required,
  - "ext_i2s" - external I2S clock - optional,
- - "ext_gmac" - external GMAC clock - optional
+ - "rmii_clkin" - external EMAC clock - optional
 
 Example: Clock controller node:
 
index 1c4ef773feea1b7ee659d887f1f03287268db9b4..82f9638121dbf31fd36d24b02e714e410b7c5be7 100644 (file)
@@ -9,6 +9,8 @@ Required properties:
        "apm,xgene-socpll-clock" - for a X-Gene SoC PLL clock
        "apm,xgene-pcppll-clock" - for a X-Gene PCP PLL clock
        "apm,xgene-device-clock" - for a X-Gene device clock
+       "apm,xgene-socpll-v2-clock" - for a X-Gene SoC PLL v2 clock
+       "apm,xgene-pcppll-v2-clock" - for a X-Gene PCP PLL v2 clock
 
 Required properties for SoC or PCP PLL clocks:
 - reg : shall be the physical PLL register address for the pll clock.
index ef68ecb273964f7c237078752b555d326aa08056..f02495f5ca1f89fdf8312138da4314bad9b2203c 100644 (file)
@@ -15,6 +15,7 @@ config PLAT_S3C24XX
        select NO_IOPORT_MAP
        select S3C_DEV_NAND
        select IRQ_DOMAIN
+       select COMMON_CLK
        help
          Base platform code for any Samsung S3C24XX device
 
index eca8e019e0054bb7443c63196b01ca217fabbd55..a8c2c882ed1fca5d76675aa868398f63ef2afa4b 100644 (file)
@@ -99,6 +99,14 @@ config COMMON_CLK_SI570
          This driver supports Silicon Labs 570/571/598/599 programmable
          clock generators.
 
+config COMMON_CLK_CDCE706
+       tristate "Clock driver for TI CDCE706 clock synthesizer"
+       depends on I2C
+       select REGMAP_I2C
+       select RATIONAL
+       ---help---
+         This driver supports TI CDCE706 programmable 3-PLL clock synthesizer.
+
 config COMMON_CLK_CDCE925
        tristate "Clock driver for TI CDCE925 devices"
        depends on I2C
@@ -190,23 +198,13 @@ config COMMON_CLK_PWM
 config COMMON_CLK_PXA
        def_bool COMMON_CLK && ARCH_PXA
        ---help---
-         Sypport for the Marvell PXA SoC.
-
-config COMMON_CLK_CDCE706
-       tristate "Clock driver for TI CDCE706 clock synthesizer"
-       depends on I2C
-       select REGMAP_I2C
-       select RATIONAL
-       ---help---
-         This driver supports TI CDCE706 programmable 3-PLL clock synthesizer.
+         Support for the Marvell PXA SoC.
 
 source "drivers/clk/bcm/Kconfig"
 source "drivers/clk/hisilicon/Kconfig"
-source "drivers/clk/qcom/Kconfig"
-
-endmenu
-
 source "drivers/clk/mvebu/Kconfig"
-
+source "drivers/clk/qcom/Kconfig"
 source "drivers/clk/samsung/Kconfig"
 source "drivers/clk/tegra/Kconfig"
+
+endmenu
index b038e36660587aaf97d4c3b41de17d1175635694..bae4be6501dfb06a51dc0aaa3befb91b47156ca0 100644 (file)
@@ -43,7 +43,7 @@ obj-$(CONFIG_COMMON_CLK_SI514)                += clk-si514.o
 obj-$(CONFIG_COMMON_CLK_SI570)         += clk-si570.o
 obj-$(CONFIG_COMMON_CLK_CDCE925)       += clk-cdce925.o
 obj-$(CONFIG_ARCH_STM32)               += clk-stm32f4.o
-obj-$(CONFIG_ARCH_TANGOX)              += clk-tango4.o
+obj-$(CONFIG_ARCH_TANGO              += clk-tango4.o
 obj-$(CONFIG_CLK_TWL6040)              += clk-twl6040.o
 obj-$(CONFIG_ARCH_U300)                        += clk-u300.o
 obj-$(CONFIG_ARCH_VT8500)              += clk-vt8500.o
index 3a228b6d4feefe6466f29941e9f66fee0c532615..464fdc4bc66b38d971597b7726d907fcde26f6bb 100644 (file)
@@ -268,3 +268,62 @@ static void __init cygnus_asiu_init(struct device_node *node)
        iproc_asiu_setup(node, asiu_div, asiu_gate, ARRAY_SIZE(asiu_div));
 }
 CLK_OF_DECLARE(cygnus_asiu_clk, "brcm,cygnus-asiu-clk", cygnus_asiu_init);
+
+/*
+ * AUDIO PLL VCO frequency parameter table
+ *
+ * PLL output frequency = ((ndiv_int + ndiv_frac / 2^20) *
+ * (parent clock rate / pdiv)
+ *
+ * On Cygnus, parent is the 25MHz oscillator
+ */
+static const struct iproc_pll_vco_param audiopll_vco_params[] = {
+       /* rate (Hz) ndiv_int ndiv_frac pdiv */
+       { 1354750204UL,  54,     199238,   1 },
+       { 1769470191UL,  70,     816639,   1 },
+};
+
+static const struct iproc_pll_ctrl audiopll = {
+       .flags = IPROC_CLK_PLL_NEEDS_SW_CFG | IPROC_CLK_PLL_HAS_NDIV_FRAC |
+               IPROC_CLK_PLL_USER_MODE_ON | IPROC_CLK_PLL_RESET_ACTIVE_LOW,
+       .reset = RESET_VAL(0x5c, 0, 1),
+       .dig_filter = DF_VAL(0x48, 0, 3, 6, 4, 3, 3),
+       .sw_ctrl = SW_CTRL_VAL(0x4, 0),
+       .ndiv_int = REG_VAL(0x8, 0, 10),
+       .ndiv_frac = REG_VAL(0x8, 10, 20),
+       .pdiv = REG_VAL(0x44, 0, 4),
+       .vco_ctrl = VCO_CTRL_VAL(0x0c, 0x10),
+       .status = REG_VAL(0x54, 0, 1),
+       .macro_mode = REG_VAL(0x0, 0, 3),
+};
+
+static const struct iproc_clk_ctrl audiopll_clk[] = {
+       [BCM_CYGNUS_AUDIOPLL_CH0] = {
+               .channel = BCM_CYGNUS_AUDIOPLL_CH0,
+               .flags = IPROC_CLK_AON |
+                               IPROC_CLK_MCLK_DIV_BY_2,
+               .enable = ENABLE_VAL(0x14, 8, 10, 9),
+               .mdiv = REG_VAL(0x14, 0, 8),
+       },
+       [BCM_CYGNUS_AUDIOPLL_CH1] = {
+               .channel = BCM_CYGNUS_AUDIOPLL_CH1,
+               .flags = IPROC_CLK_AON,
+               .enable = ENABLE_VAL(0x18, 8, 10, 9),
+               .mdiv = REG_VAL(0x18, 0, 8),
+       },
+       [BCM_CYGNUS_AUDIOPLL_CH2] = {
+               .channel = BCM_CYGNUS_AUDIOPLL_CH2,
+               .flags = IPROC_CLK_AON,
+               .enable = ENABLE_VAL(0x1c, 8, 10, 9),
+               .mdiv = REG_VAL(0x1c, 0, 8),
+       },
+};
+
+static void __init cygnus_audiopll_clk_init(struct device_node *node)
+{
+       iproc_pll_clk_setup(node, &audiopll, audiopll_vco_params,
+                           ARRAY_SIZE(audiopll_vco_params), audiopll_clk,
+                           ARRAY_SIZE(audiopll_clk));
+}
+CLK_OF_DECLARE(cygnus_audiopll, "brcm,cygnus-audiopll",
+                       cygnus_audiopll_clk_init);
index afd5891ac9e6aafeb6f429e487d5e06cbfd2f4f1..fd492a5dad12bf48b96fbaa2484100093f581d96 100644 (file)
 #define PLL_VCO_HIGH_SHIFT 19
 #define PLL_VCO_LOW_SHIFT  30
 
+/*
+ * PLL MACRO_SELECT modes 0 to 5 choose pre-calculated PLL output frequencies
+ * from a look-up table. Mode 7 allows user to manipulate PLL clock dividers
+ */
+#define PLL_USER_MODE 7
+
 /* number of delay loops waiting for PLL to lock */
 #define LOCK_DELAY 100
 
@@ -215,7 +221,10 @@ static void __pll_put_in_reset(struct iproc_pll *pll)
        const struct iproc_pll_reset_ctrl *reset = &ctrl->reset;
 
        val = readl(pll->control_base + reset->offset);
-       val &= ~(1 << reset->reset_shift | 1 << reset->p_reset_shift);
+       if (ctrl->flags & IPROC_CLK_PLL_RESET_ACTIVE_LOW)
+               val |= BIT(reset->reset_shift) | BIT(reset->p_reset_shift);
+       else
+               val &= ~(BIT(reset->reset_shift) | BIT(reset->p_reset_shift));
        iproc_pll_write(pll, pll->control_base, reset->offset, val);
 }
 
@@ -236,7 +245,10 @@ static void __pll_bring_out_reset(struct iproc_pll *pll, unsigned int kp,
        iproc_pll_write(pll, pll->control_base, dig_filter->offset, val);
 
        val = readl(pll->control_base + reset->offset);
-       val |= 1 << reset->reset_shift | 1 << reset->p_reset_shift;
+       if (ctrl->flags & IPROC_CLK_PLL_RESET_ACTIVE_LOW)
+               val &= ~(BIT(reset->reset_shift) | BIT(reset->p_reset_shift));
+       else
+               val |= BIT(reset->reset_shift) | BIT(reset->p_reset_shift);
        iproc_pll_write(pll, pll->control_base, reset->offset, val);
 }
 
@@ -292,6 +304,16 @@ static int pll_set_rate(struct iproc_clk *clk, unsigned int rate_index,
        /* put PLL in reset */
        __pll_put_in_reset(pll);
 
+       /* set PLL in user mode before modifying PLL controls */
+       if (ctrl->flags & IPROC_CLK_PLL_USER_MODE_ON) {
+               val = readl(pll->control_base + ctrl->macro_mode.offset);
+               val &= ~(bit_mask(ctrl->macro_mode.width) <<
+                       ctrl->macro_mode.shift);
+               val |= PLL_USER_MODE << ctrl->macro_mode.shift;
+               iproc_pll_write(pll, pll->control_base,
+                       ctrl->macro_mode.offset, val);
+       }
+
        iproc_pll_write(pll, pll->control_base, ctrl->vco_ctrl.u_offset, 0);
 
        val = readl(pll->control_base + ctrl->vco_ctrl.l_offset);
@@ -505,7 +527,10 @@ static unsigned long iproc_clk_recalc_rate(struct clk_hw *hw,
        if (mdiv == 0)
                mdiv = 256;
 
-       clk->rate = parent_rate / mdiv;
+       if (ctrl->flags & IPROC_CLK_MCLK_DIV_BY_2)
+               clk->rate = parent_rate / (mdiv * 2);
+       else
+               clk->rate = parent_rate / mdiv;
 
        return clk->rate;
 }
@@ -543,7 +568,10 @@ static int iproc_clk_set_rate(struct clk_hw *hw, unsigned long rate,
        if (rate == 0 || parent_rate == 0)
                return -EINVAL;
 
-       div = DIV_ROUND_UP(parent_rate, rate);
+       if (ctrl->flags & IPROC_CLK_MCLK_DIV_BY_2)
+               div = DIV_ROUND_UP(parent_rate, rate * 2);
+       else
+               div = DIV_ROUND_UP(parent_rate, rate);
        if (div > 256)
                return -EINVAL;
 
@@ -555,7 +583,10 @@ static int iproc_clk_set_rate(struct clk_hw *hw, unsigned long rate,
                val |= div << ctrl->mdiv.shift;
        }
        iproc_pll_write(pll, pll->control_base, ctrl->mdiv.offset, val);
-       clk->rate = parent_rate / div;
+       if (ctrl->flags & IPROC_CLK_MCLK_DIV_BY_2)
+               clk->rate = parent_rate / (div * 2);
+       else
+               clk->rate = parent_rate / div;
 
        return 0;
 }
index 8988de70a98cc3fd38c4d72212443ce8250ffca3..2148b4ea9f2898e61cbc341ad30c25d761562862 100644 (file)
  */
 #define IPROC_CLK_PLL_SPLIT_STAT_CTRL BIT(6)
 
+/*
+ * Some PLLs have an additional divide by 2 in master clock calculation;
+ * MCLK = VCO_freq / (Mdiv * 2). Identify this to let the driver know
+ * of modified calculations
+ */
+#define IPROC_CLK_MCLK_DIV_BY_2 BIT(7)
+
+/*
+ * Some PLLs provide a look up table for the leaf clock frequencies and
+ * auto calculates VCO frequency parameters based on the provided leaf
+ * clock frequencies. They have a user mode that allows the divider
+ * controls to be determined by the user
+ */
+#define IPROC_CLK_PLL_USER_MODE_ON BIT(8)
+
+/*
+ * Some PLLs have an active low reset
+ */
+#define IPROC_CLK_PLL_RESET_ACTIVE_LOW BIT(9)
+
 /*
  * Parameters for VCO frequency configuration
  *
@@ -149,6 +169,7 @@ struct iproc_pll_ctrl {
        struct iproc_clk_reg_op pdiv;
        struct iproc_pll_vco_ctrl vco_ctrl;
        struct iproc_clk_reg_op status;
+       struct iproc_clk_reg_op macro_mode;
 };
 
 /*
@@ -183,16 +204,16 @@ struct iproc_asiu_div {
        unsigned int low_width;
 };
 
-void __init iproc_armpll_setup(struct device_node *node);
-void __init iproc_pll_clk_setup(struct device_node *node,
-                               const struct iproc_pll_ctrl *pll_ctrl,
-                               const struct iproc_pll_vco_param *vco,
-                               unsigned int num_vco_entries,
-                               const struct iproc_clk_ctrl *clk_ctrl,
-                               unsigned int num_clks);
-void __init iproc_asiu_setup(struct device_node *node,
-                            const struct iproc_asiu_div *div,
-                            const struct iproc_asiu_gate *gate,
-                            unsigned int num_clks);
+void iproc_armpll_setup(struct device_node *node);
+void iproc_pll_clk_setup(struct device_node *node,
+                        const struct iproc_pll_ctrl *pll_ctrl,
+                        const struct iproc_pll_vco_param *vco,
+                        unsigned int num_vco_entries,
+                        const struct iproc_clk_ctrl *clk_ctrl,
+                        unsigned int num_clks);
+void iproc_asiu_setup(struct device_node *node,
+                     const struct iproc_asiu_div *div,
+                     const struct iproc_asiu_gate *gate,
+                     unsigned int num_clks);
 
 #endif /* _CLK_IPROC_H */
index 3bcd42fbb55e3fbbcdb401f707aef3879fe5d001..3294db3b4e4e7303903b7a0b10a149b25642b148 100644 (file)
 #include <linux/module.h>
 #include <linux/err.h>
 
-#define AXI_CLKGEN_V1_REG_UPDATE_ENABLE        0x04
-#define AXI_CLKGEN_V1_REG_CLK_OUT1     0x08
-#define AXI_CLKGEN_V1_REG_CLK_OUT2     0x0c
-#define AXI_CLKGEN_V1_REG_CLK_DIV      0x10
-#define AXI_CLKGEN_V1_REG_CLK_FB1      0x14
-#define AXI_CLKGEN_V1_REG_CLK_FB2      0x18
-#define AXI_CLKGEN_V1_REG_LOCK1                0x1c
-#define AXI_CLKGEN_V1_REG_LOCK2                0x20
-#define AXI_CLKGEN_V1_REG_LOCK3                0x24
-#define AXI_CLKGEN_V1_REG_FILTER1      0x28
-#define AXI_CLKGEN_V1_REG_FILTER2      0x2c
-
 #define AXI_CLKGEN_V2_REG_RESET                0x40
+#define AXI_CLKGEN_V2_REG_CLKSEL       0x44
 #define AXI_CLKGEN_V2_REG_DRP_CNTRL    0x70
 #define AXI_CLKGEN_V2_REG_DRP_STATUS   0x74
 
 #define MMCM_REG_FILTER1       0x4e
 #define MMCM_REG_FILTER2       0x4f
 
-struct axi_clkgen;
-
-struct axi_clkgen_mmcm_ops {
-       void (*enable)(struct axi_clkgen *axi_clkgen, bool enable);
-       int (*write)(struct axi_clkgen *axi_clkgen, unsigned int reg,
-                    unsigned int val, unsigned int mask);
-       int (*read)(struct axi_clkgen *axi_clkgen, unsigned int reg,
-                   unsigned int *val);
-};
-
 struct axi_clkgen {
        void __iomem *base;
-       const struct axi_clkgen_mmcm_ops *mmcm_ops;
        struct clk_hw clk_hw;
 };
 
-static void axi_clkgen_mmcm_enable(struct axi_clkgen *axi_clkgen,
-       bool enable)
-{
-       axi_clkgen->mmcm_ops->enable(axi_clkgen, enable);
-}
-
-static int axi_clkgen_mmcm_write(struct axi_clkgen *axi_clkgen,
-       unsigned int reg, unsigned int val, unsigned int mask)
-{
-       return axi_clkgen->mmcm_ops->write(axi_clkgen, reg, val, mask);
-}
-
-static int axi_clkgen_mmcm_read(struct axi_clkgen *axi_clkgen,
-       unsigned int reg, unsigned int *val)
-{
-       return axi_clkgen->mmcm_ops->read(axi_clkgen, reg, val);
-}
-
 static uint32_t axi_clkgen_lookup_filter(unsigned int m)
 {
        switch (m) {
@@ -207,70 +167,6 @@ static void axi_clkgen_read(struct axi_clkgen *axi_clkgen,
        *val = readl(axi_clkgen->base + reg);
 }
 
-static unsigned int axi_clkgen_v1_map_mmcm_reg(unsigned int reg)
-{
-       switch (reg) {
-       case MMCM_REG_CLKOUT0_1:
-               return AXI_CLKGEN_V1_REG_CLK_OUT1;
-       case MMCM_REG_CLKOUT0_2:
-               return AXI_CLKGEN_V1_REG_CLK_OUT2;
-       case MMCM_REG_CLK_FB1:
-               return AXI_CLKGEN_V1_REG_CLK_FB1;
-       case MMCM_REG_CLK_FB2:
-               return AXI_CLKGEN_V1_REG_CLK_FB2;
-       case MMCM_REG_CLK_DIV:
-               return AXI_CLKGEN_V1_REG_CLK_DIV;
-       case MMCM_REG_LOCK1:
-               return AXI_CLKGEN_V1_REG_LOCK1;
-       case MMCM_REG_LOCK2:
-               return AXI_CLKGEN_V1_REG_LOCK2;
-       case MMCM_REG_LOCK3:
-               return AXI_CLKGEN_V1_REG_LOCK3;
-       case MMCM_REG_FILTER1:
-               return AXI_CLKGEN_V1_REG_FILTER1;
-       case MMCM_REG_FILTER2:
-               return AXI_CLKGEN_V1_REG_FILTER2;
-       default:
-               return 0;
-       }
-}
-
-static int axi_clkgen_v1_mmcm_write(struct axi_clkgen *axi_clkgen,
-       unsigned int reg, unsigned int val, unsigned int mask)
-{
-       reg = axi_clkgen_v1_map_mmcm_reg(reg);
-       if (reg == 0)
-               return -EINVAL;
-
-       axi_clkgen_write(axi_clkgen, reg, val);
-
-       return 0;
-}
-
-static int axi_clkgen_v1_mmcm_read(struct axi_clkgen *axi_clkgen,
-       unsigned int reg, unsigned int *val)
-{
-       reg = axi_clkgen_v1_map_mmcm_reg(reg);
-       if (reg == 0)
-               return -EINVAL;
-
-       axi_clkgen_read(axi_clkgen, reg, val);
-
-       return 0;
-}
-
-static void axi_clkgen_v1_mmcm_enable(struct axi_clkgen *axi_clkgen,
-       bool enable)
-{
-       axi_clkgen_write(axi_clkgen, AXI_CLKGEN_V1_REG_UPDATE_ENABLE, enable);
-}
-
-static const struct axi_clkgen_mmcm_ops axi_clkgen_v1_mmcm_ops = {
-       .write = axi_clkgen_v1_mmcm_write,
-       .read = axi_clkgen_v1_mmcm_read,
-       .enable = axi_clkgen_v1_mmcm_enable,
-};
-
 static int axi_clkgen_wait_non_busy(struct axi_clkgen *axi_clkgen)
 {
        unsigned int timeout = 10000;
@@ -286,7 +182,7 @@ static int axi_clkgen_wait_non_busy(struct axi_clkgen *axi_clkgen)
        return val & 0xffff;
 }
 
-static int axi_clkgen_v2_mmcm_read(struct axi_clkgen *axi_clkgen,
+static int axi_clkgen_mmcm_read(struct axi_clkgen *axi_clkgen,
        unsigned int reg, unsigned int *val)
 {
        unsigned int reg_val;
@@ -310,7 +206,7 @@ static int axi_clkgen_v2_mmcm_read(struct axi_clkgen *axi_clkgen,
        return 0;
 }
 
-static int axi_clkgen_v2_mmcm_write(struct axi_clkgen *axi_clkgen,
+static int axi_clkgen_mmcm_write(struct axi_clkgen *axi_clkgen,
        unsigned int reg, unsigned int val, unsigned int mask)
 {
        unsigned int reg_val = 0;
@@ -321,7 +217,7 @@ static int axi_clkgen_v2_mmcm_write(struct axi_clkgen *axi_clkgen,
                return ret;
 
        if (mask != 0xffff) {
-               axi_clkgen_v2_mmcm_read(axi_clkgen, reg, &reg_val);
+               axi_clkgen_mmcm_read(axi_clkgen, reg, &reg_val);
                reg_val &= ~mask;
        }
 
@@ -332,7 +228,7 @@ static int axi_clkgen_v2_mmcm_write(struct axi_clkgen *axi_clkgen,
        return 0;
 }
 
-static void axi_clkgen_v2_mmcm_enable(struct axi_clkgen *axi_clkgen,
+static void axi_clkgen_mmcm_enable(struct axi_clkgen *axi_clkgen,
        bool enable)
 {
        unsigned int val = AXI_CLKGEN_V2_RESET_ENABLE;
@@ -343,12 +239,6 @@ static void axi_clkgen_v2_mmcm_enable(struct axi_clkgen *axi_clkgen,
        axi_clkgen_write(axi_clkgen, AXI_CLKGEN_V2_REG_RESET, val);
 }
 
-static const struct axi_clkgen_mmcm_ops axi_clkgen_v2_mmcm_ops = {
-       .write = axi_clkgen_v2_mmcm_write,
-       .read = axi_clkgen_v2_mmcm_read,
-       .enable = axi_clkgen_v2_mmcm_enable,
-};
-
 static struct axi_clkgen *clk_hw_to_axi_clkgen(struct clk_hw *clk_hw)
 {
        return container_of(clk_hw, struct axi_clkgen, clk_hw);
@@ -438,10 +328,7 @@ static unsigned long axi_clkgen_recalc_rate(struct clk_hw *clk_hw,
        tmp = (unsigned long long)(parent_rate / d) * m;
        do_div(tmp, dout);
 
-       if (tmp > ULONG_MAX)
-               return ULONG_MAX;
-
-       return tmp;
+       return min_t(unsigned long long, tmp, ULONG_MAX);
 }
 
 static int axi_clkgen_enable(struct clk_hw *clk_hw)
@@ -460,21 +347,38 @@ static void axi_clkgen_disable(struct clk_hw *clk_hw)
        axi_clkgen_mmcm_enable(axi_clkgen, false);
 }
 
+static int axi_clkgen_set_parent(struct clk_hw *clk_hw, u8 index)
+{
+       struct axi_clkgen *axi_clkgen = clk_hw_to_axi_clkgen(clk_hw);
+
+       axi_clkgen_write(axi_clkgen, AXI_CLKGEN_V2_REG_CLKSEL, index);
+
+       return 0;
+}
+
+static u8 axi_clkgen_get_parent(struct clk_hw *clk_hw)
+{
+       struct axi_clkgen *axi_clkgen = clk_hw_to_axi_clkgen(clk_hw);
+       unsigned int parent;
+
+       axi_clkgen_read(axi_clkgen, AXI_CLKGEN_V2_REG_CLKSEL, &parent);
+
+       return parent;
+}
+
 static const struct clk_ops axi_clkgen_ops = {
        .recalc_rate = axi_clkgen_recalc_rate,
        .round_rate = axi_clkgen_round_rate,
        .set_rate = axi_clkgen_set_rate,
        .enable = axi_clkgen_enable,
        .disable = axi_clkgen_disable,
+       .set_parent = axi_clkgen_set_parent,
+       .get_parent = axi_clkgen_get_parent,
 };
 
 static const struct of_device_id axi_clkgen_ids[] = {
        {
-               .compatible = "adi,axi-clkgen-1.00.a",
-               .data = &axi_clkgen_v1_mmcm_ops
-       }, {
                .compatible = "adi,axi-clkgen-2.00.a",
-               .data = &axi_clkgen_v2_mmcm_ops,
        },
        { },
 };
@@ -485,10 +389,11 @@ static int axi_clkgen_probe(struct platform_device *pdev)
        const struct of_device_id *id;
        struct axi_clkgen *axi_clkgen;
        struct clk_init_data init;
-       const char *parent_name;
+       const char *parent_names[2];
        const char *clk_name;
        struct resource *mem;
        struct clk *clk;
+       unsigned int i;
 
        if (!pdev->dev.of_node)
                return -ENODEV;
@@ -501,26 +406,29 @@ static int axi_clkgen_probe(struct platform_device *pdev)
        if (!axi_clkgen)
                return -ENOMEM;
 
-       axi_clkgen->mmcm_ops = id->data;
-
        mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        axi_clkgen->base = devm_ioremap_resource(&pdev->dev, mem);
        if (IS_ERR(axi_clkgen->base))
                return PTR_ERR(axi_clkgen->base);
 
-       parent_name = of_clk_get_parent_name(pdev->dev.of_node, 0);
-       if (!parent_name)
+       init.num_parents = of_clk_get_parent_count(pdev->dev.of_node);
+       if (init.num_parents < 1 || init.num_parents > 2)
                return -EINVAL;
 
+       for (i = 0; i < init.num_parents; i++) {
+               parent_names[i] = of_clk_get_parent_name(pdev->dev.of_node, i);
+               if (!parent_names[i])
+                       return -EINVAL;
+       }
+
        clk_name = pdev->dev.of_node->name;
        of_property_read_string(pdev->dev.of_node, "clock-output-names",
                &clk_name);
 
        init.name = clk_name;
        init.ops = &axi_clkgen_ops;
-       init.flags = CLK_SET_RATE_GATE;
-       init.parent_names = &parent_name;
-       init.num_parents = 1;
+       init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE;
+       init.parent_names = parent_names;
 
        axi_clkgen_mmcm_enable(axi_clkgen, false);
 
index 4735de0660cc912f1bafea1e31388bcf9843543d..1f903e1f86a281385a817d0a450404240ac40109 100644 (file)
@@ -19,8 +19,6 @@
 #include <linux/err.h>
 #include <linux/slab.h>
 
-#define to_clk_composite(_hw) container_of(_hw, struct clk_composite, hw)
-
 static u8 clk_composite_get_parent(struct clk_hw *hw)
 {
        struct clk_composite *composite = to_clk_composite(hw);
index ded3ff4b91b9a2492710c0487976c36fcb6dfa80..00e035b51c695be31a215319fd3af62fcd72112d 100644 (file)
@@ -28,8 +28,6 @@
  * parent - fixed parent.  No clk_set_parent support
  */
 
-#define to_clk_divider(_hw) container_of(_hw, struct clk_divider, hw)
-
 #define div_mask(width)        ((1 << (width)) - 1)
 
 static unsigned int _get_table_maxdiv(const struct clk_div_table *table,
@@ -305,9 +303,8 @@ static int clk_divider_bestdiv(struct clk_hw *hw, unsigned long rate,
         */
        maxdiv = min(ULONG_MAX / rate, maxdiv);
 
-       for (i = 1; i <= maxdiv; i = _next_div(table, i, flags)) {
-               if (!_is_valid_div(table, i, flags))
-                       continue;
+       for (i = _next_div(table, 0, flags); i <= maxdiv;
+                                            i = _next_div(table, i, flags)) {
                if (rate * i == parent_rate_saved) {
                        /*
                         * It's the most ideal case if the requested rate can be
@@ -423,6 +420,12 @@ const struct clk_ops clk_divider_ops = {
 };
 EXPORT_SYMBOL_GPL(clk_divider_ops);
 
+const struct clk_ops clk_divider_ro_ops = {
+       .recalc_rate = clk_divider_recalc_rate,
+       .round_rate = clk_divider_round_rate,
+};
+EXPORT_SYMBOL_GPL(clk_divider_ro_ops);
+
 static struct clk *_register_divider(struct device *dev, const char *name,
                const char *parent_name, unsigned long flags,
                void __iomem *reg, u8 shift, u8 width,
@@ -446,7 +449,10 @@ static struct clk *_register_divider(struct device *dev, const char *name,
                return ERR_PTR(-ENOMEM);
 
        init.name = name;
-       init.ops = &clk_divider_ops;
+       if (clk_divider_flags & CLK_DIVIDER_READ_ONLY)
+               init.ops = &clk_divider_ro_ops;
+       else
+               init.ops = &clk_divider_ops;
        init.flags = flags | CLK_IS_BASIC;
        init.parent_names = (parent_name ? &parent_name: NULL);
        init.num_parents = (parent_name ? 1 : 0);
index 83de57aeceea514dfaf53fc5a0271b1ca7d3b13d..053448e2453d7b2c44726440853495541138c714 100644 (file)
@@ -23,8 +23,6 @@
  * parent - fixed parent.  No clk_set_parent support
  */
 
-#define to_clk_fixed_factor(_hw) container_of(_hw, struct clk_fixed_factor, hw)
-
 static unsigned long clk_factor_recalc_rate(struct clk_hw *hw,
                unsigned long parent_rate)
 {
@@ -102,6 +100,19 @@ struct clk *clk_register_fixed_factor(struct device *dev, const char *name,
 }
 EXPORT_SYMBOL_GPL(clk_register_fixed_factor);
 
+void clk_unregister_fixed_factor(struct clk *clk)
+{
+       struct clk_hw *hw;
+
+       hw = __clk_get_hw(clk);
+       if (!hw)
+               return;
+
+       clk_unregister(clk);
+       kfree(to_clk_fixed_factor(hw));
+}
+EXPORT_SYMBOL_GPL(clk_unregister_fixed_factor);
+
 #ifdef CONFIG_OF
 /**
  * of_fixed_factor_clk_setup() - Setup function for simple fixed factor clock
index f85ec8d1711fb7f36ac2e724308745dbf7b1ef47..6858bfc548a920e57b6f25675bf974ee94744d9d 100644 (file)
@@ -26,8 +26,6 @@
  * parent - fixed parent.  No clk_set_parent support
  */
 
-#define to_clk_fixed_rate(_hw) container_of(_hw, struct clk_fixed_rate, hw)
-
 static unsigned long clk_fixed_rate_recalc_rate(struct clk_hw *hw,
                unsigned long parent_rate)
 {
@@ -106,6 +104,19 @@ struct clk *clk_register_fixed_rate(struct device *dev, const char *name,
 }
 EXPORT_SYMBOL_GPL(clk_register_fixed_rate);
 
+void clk_unregister_fixed_rate(struct clk *clk)
+{
+       struct clk_hw *hw;
+
+       hw = __clk_get_hw(clk);
+       if (!hw)
+               return;
+
+       clk_unregister(clk);
+       kfree(to_clk_fixed_rate(hw));
+}
+EXPORT_SYMBOL_GPL(clk_unregister_fixed_rate);
+
 #ifdef CONFIG_OF
 /**
  * of_fixed_clk_setup() - Setup function for simple fixed rate clock
index 5c4955e33f7a259711b960593941df38d526f2bb..1abcd76b4993805f2b135b92e5bc285b10de5c95 100644 (file)
@@ -16,8 +16,6 @@
 #include <linux/slab.h>
 #include <linux/rational.h>
 
-#define to_clk_fd(_hw) container_of(_hw, struct clk_fractional_divider, hw)
-
 static unsigned long clk_fd_recalc_rate(struct clk_hw *hw,
                                        unsigned long parent_rate)
 {
index de0b322f5f58d4a57677455e6a5a2a78dcf0687d..d0d8ec8e1f1b0c8ae6de9457179ddf6bb8616434 100644 (file)
@@ -26,8 +26,6 @@
  * parent - fixed parent.  No clk_set_parent support
  */
 
-#define to_clk_gate(_hw) container_of(_hw, struct clk_gate, hw)
-
 /*
  * It works on following logic:
  *
index 19fed65587e8206c20f6ee13a1b736276e8922ae..fb32a7366ef6f7b4b752871592b508a55d67dd9c 100644 (file)
@@ -20,6 +20,8 @@
 #include <linux/of_gpio.h>
 #include <linux/err.h>
 #include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/of_device.h>
 
 /**
  * DOC: basic gpio gated clock which can be enabled and disabled
@@ -31,8 +33,6 @@
  * parent - fixed parent.  No clk_set_parent support
  */
 
-#define to_clk_gpio(_hw) container_of(_hw, struct clk_gpio, hw)
-
 static int clk_gpio_gate_enable(struct clk_hw *hw)
 {
        struct clk_gpio *clk = to_clk_gpio(hw);
@@ -201,134 +201,71 @@ struct clk *clk_register_gpio_mux(struct device *dev, const char *name,
 }
 EXPORT_SYMBOL_GPL(clk_register_gpio_mux);
 
-#ifdef CONFIG_OF
-/**
- * clk_register_get() has to be delayed, because -EPROBE_DEFER
- * can not be handled properly at of_clk_init() call time.
- */
-
-struct clk_gpio_delayed_register_data {
-       const char *gpio_name;
-       int num_parents;
-       const char **parent_names;
-       struct device_node *node;
-       struct mutex lock;
-       struct clk *clk;
-       struct clk *(*clk_register_get)(const char *name,
-                       const char * const *parent_names, u8 num_parents,
-                       unsigned gpio, bool active_low);
-};
-
-static struct clk *of_clk_gpio_delayed_register_get(
-               struct of_phandle_args *clkspec, void *_data)
+static int gpio_clk_driver_probe(struct platform_device *pdev)
 {
-       struct clk_gpio_delayed_register_data *data = _data;
-       struct clk *clk;
-       int gpio;
+       struct device_node *node = pdev->dev.of_node;
+       const char **parent_names, *gpio_name;
+       int num_parents, gpio;
        enum of_gpio_flags of_flags;
+       struct clk *clk;
+       bool active_low, is_mux;
+
+       num_parents = of_clk_get_parent_count(node);
+       if (num_parents < 0)
+               return -EINVAL;
 
-       mutex_lock(&data->lock);
+       if (num_parents) {
+               parent_names = devm_kcalloc(&pdev->dev, num_parents,
+                                           sizeof(char *), GFP_KERNEL);
+               if (!parent_names)
+                       return -ENOMEM;
 
-       if (data->clk) {
-               mutex_unlock(&data->lock);
-               return data->clk;
+               of_clk_parent_fill(node, parent_names, num_parents);
+       } else {
+               parent_names = NULL;
        }
 
-       gpio = of_get_named_gpio_flags(data->node, data->gpio_name, 0,
-                       &of_flags);
+       is_mux = of_device_is_compatible(node, "gpio-mux-clock");
+
+       gpio_name = is_mux ? "select-gpios" : "enable-gpios";
+       gpio = of_get_named_gpio_flags(node, gpio_name, 0, &of_flags);
        if (gpio < 0) {
-               mutex_unlock(&data->lock);
                if (gpio == -EPROBE_DEFER)
                        pr_debug("%s: %s: GPIOs not yet available, retry later\n",
-                                       data->node->name, __func__);
+                                       node->name, __func__);
                else
                        pr_err("%s: %s: Can't get '%s' DT property\n",
-                                       data->node->name, __func__,
-                                       data->gpio_name);
-               return ERR_PTR(gpio);
+                                       node->name, __func__,
+                                       gpio_name);
+               return gpio;
        }
 
-       clk = data->clk_register_get(data->node->name, data->parent_names,
-                       data->num_parents, gpio, of_flags & OF_GPIO_ACTIVE_LOW);
-       if (IS_ERR(clk))
-               goto out;
-
-       data->clk = clk;
-out:
-       mutex_unlock(&data->lock);
-
-       return clk;
-}
-
-static struct clk *of_clk_gpio_gate_delayed_register_get(const char *name,
-               const char * const *parent_names, u8 num_parents,
-               unsigned gpio, bool active_low)
-{
-       return clk_register_gpio_gate(NULL, name, parent_names ?
-                       parent_names[0] : NULL, gpio, active_low, 0);
-}
+       active_low = of_flags & OF_GPIO_ACTIVE_LOW;
 
-static struct clk *of_clk_gpio_mux_delayed_register_get(const char *name,
-               const char * const *parent_names, u8 num_parents, unsigned gpio,
-               bool active_low)
-{
-       return clk_register_gpio_mux(NULL, name, parent_names, num_parents,
-                       gpio, active_low, 0);
-}
-
-static void __init of_gpio_clk_setup(struct device_node *node,
-               const char *gpio_name,
-               struct clk *(*clk_register_get)(const char *name,
-                               const char * const *parent_names,
-                               u8 num_parents,
-                               unsigned gpio, bool active_low))
-{
-       struct clk_gpio_delayed_register_data *data;
-       const char **parent_names;
-       int i, num_parents;
-
-       num_parents = of_clk_get_parent_count(node);
-       if (num_parents < 0)
-               return;
-
-       data = kzalloc(sizeof(*data), GFP_KERNEL);
-       if (!data)
-               return;
-
-       if (num_parents) {
-               parent_names = kcalloc(num_parents, sizeof(char *), GFP_KERNEL);
-               if (!parent_names) {
-                       kfree(data);
-                       return;
-               }
-
-               for (i = 0; i < num_parents; i++)
-                       parent_names[i] = of_clk_get_parent_name(node, i);
-       } else {
-               parent_names = NULL;
-       }
-
-       data->num_parents = num_parents;
-       data->parent_names = parent_names;
-       data->node = node;
-       data->gpio_name = gpio_name;
-       data->clk_register_get = clk_register_get;
-       mutex_init(&data->lock);
+       if (is_mux)
+               clk = clk_register_gpio_mux(&pdev->dev, node->name,
+                               parent_names, num_parents, gpio, active_low, 0);
+       else
+               clk = clk_register_gpio_gate(&pdev->dev, node->name,
+                               parent_names ?  parent_names[0] : NULL, gpio,
+                               active_low, 0);
+       if (IS_ERR(clk))
+               return PTR_ERR(clk);
 
-       of_clk_add_provider(node, of_clk_gpio_delayed_register_get, data);
+       return of_clk_add_provider(node, of_clk_src_simple_get, clk);
 }
 
-static void __init of_gpio_gate_clk_setup(struct device_node *node)
-{
-       of_gpio_clk_setup(node, "enable-gpios",
-               of_clk_gpio_gate_delayed_register_get);
-}
-CLK_OF_DECLARE(gpio_gate_clk, "gpio-gate-clock", of_gpio_gate_clk_setup);
+static const struct of_device_id gpio_clk_match_table[] = {
+       { .compatible = "gpio-mux-clock" },
+       { .compatible = "gpio-gate-clock" },
+       { }
+};
 
-void __init of_gpio_mux_clk_setup(struct device_node *node)
-{
-       of_gpio_clk_setup(node, "select-gpios",
-               of_clk_gpio_mux_delayed_register_get);
-}
-CLK_OF_DECLARE(gpio_mux_clk, "gpio-mux-clock", of_gpio_mux_clk_setup);
-#endif
+static struct platform_driver gpio_clk_driver = {
+       .probe          = gpio_clk_driver_probe,
+       .driver         = {
+               .name   = "gpio-clk",
+               .of_match_table = gpio_clk_match_table,
+       },
+};
+builtin_platform_driver(gpio_clk_driver);
index fe7806506bf34e8a554a815cef99c5afba754b26..9e449c7b751c328e23b074186e1bebf426172087 100644 (file)
@@ -14,8 +14,6 @@
 #include <linux/of.h>
 #include <linux/slab.h>
 
-#define to_clk_multiplier(_hw) container_of(_hw, struct clk_multiplier, hw)
-
 static unsigned long __get_mult(struct clk_multiplier *mult,
                                unsigned long rate,
                                unsigned long parent_rate)
index 5ed03c8a8df9e122b904d5c62bb603f884d4deb5..252188fd8bcdf49872bff06d313142df6d297ba3 100644 (file)
@@ -26,8 +26,6 @@
  * parent - parent is adjustable through clk_set_parent
  */
 
-#define to_clk_mux(_hw) container_of(_hw, struct clk_mux, hw)
-
 static u8 clk_mux_get_parent(struct clk_hw *hw)
 {
        struct clk_mux *mux = to_clk_mux(hw);
index 8e3039f0c3f9544de39bc8c06be41a2337b8492a..9c0b8e6b1ab322b13aaef11ddb451c1b84ecffc9 100644 (file)
@@ -44,7 +44,7 @@ struct palmas_clock_info {
        struct clk *clk;
        struct clk_hw hw;
        struct palmas *palmas;
-       struct palmas_clk32k_desc *clk_desc;
+       const struct palmas_clk32k_desc *clk_desc;
        int ext_control_pin;
 };
 
@@ -125,10 +125,10 @@ static struct clk_ops palmas_clks_ops = {
 
 struct palmas_clks_of_match_data {
        struct clk_init_data init;
-       struct palmas_clk32k_desc desc;
+       const struct palmas_clk32k_desc desc;
 };
 
-static struct palmas_clks_of_match_data palmas_of_clk32kg = {
+static const struct palmas_clks_of_match_data palmas_of_clk32kg = {
        .init = {
                .name = "clk32kg",
                .ops = &palmas_clks_ops,
@@ -144,7 +144,7 @@ static struct palmas_clks_of_match_data palmas_of_clk32kg = {
        },
 };
 
-static struct palmas_clks_of_match_data palmas_of_clk32kgaudio = {
+static const struct palmas_clks_of_match_data palmas_of_clk32kgaudio = {
        .init = {
                .name = "clk32kgaudio",
                .ops = &palmas_clks_ops,
@@ -240,14 +240,14 @@ static int palmas_clks_probe(struct platform_device *pdev)
 {
        struct palmas *palmas = dev_get_drvdata(pdev->dev.parent);
        struct device_node *node = pdev->dev.of_node;
-       struct palmas_clks_of_match_data *match_data;
-       const struct of_device_id *match;
+       const struct palmas_clks_of_match_data *match_data;
        struct palmas_clock_info *cinfo;
        struct clk *clk;
        int ret;
 
-       match = of_match_device(palmas_clks_of_match, &pdev->dev);
-       match_data = (struct palmas_clks_of_match_data *)match->data;
+       match_data = of_device_get_match_data(&pdev->dev);
+       if (!match_data)
+               return 1;
 
        cinfo = devm_kzalloc(&pdev->dev, sizeof(*cinfo), GFP_KERNEL);
        if (!cinfo)
index d266299dfdb1a26e22477f78a2c389d5dc858f4f..371150aabd15e357b4f0e2de6b71fc4aee193c3a 100644 (file)
 #include <linux/mfd/samsung/s5m8767.h>
 #include <linux/mfd/samsung/core.h>
 
-#define s2mps11_name(a) (a->hw.init->name)
-
-static struct clk **clk_table;
-static struct clk_onecell_data clk_data;
-
 enum {
        S2MPS11_CLK_AP = 0,
        S2MPS11_CLK_CP,
@@ -99,6 +94,7 @@ static struct clk_ops s2mps11_clk_ops = {
        .recalc_rate    = s2mps11_clk_recalc_rate,
 };
 
+/* This s2mps11_clks_init tructure is common to s2mps11, s2mps13 and s2mps14 */
 static struct clk_init_data s2mps11_clks_init[S2MPS11_CLKS_NUM] = {
        [S2MPS11_CLK_AP] = {
                .name = "s2mps11_ap",
@@ -117,37 +113,6 @@ static struct clk_init_data s2mps11_clks_init[S2MPS11_CLKS_NUM] = {
        },
 };
 
-static struct clk_init_data s2mps13_clks_init[S2MPS11_CLKS_NUM] = {
-       [S2MPS11_CLK_AP] = {
-               .name = "s2mps13_ap",
-               .ops = &s2mps11_clk_ops,
-               .flags = CLK_IS_ROOT,
-       },
-       [S2MPS11_CLK_CP] = {
-               .name = "s2mps13_cp",
-               .ops = &s2mps11_clk_ops,
-               .flags = CLK_IS_ROOT,
-       },
-       [S2MPS11_CLK_BT] = {
-               .name = "s2mps13_bt",
-               .ops = &s2mps11_clk_ops,
-               .flags = CLK_IS_ROOT,
-       },
-};
-
-static struct clk_init_data s2mps14_clks_init[S2MPS11_CLKS_NUM] = {
-       [S2MPS11_CLK_AP] = {
-               .name = "s2mps14_ap",
-               .ops = &s2mps11_clk_ops,
-               .flags = CLK_IS_ROOT,
-       },
-       [S2MPS11_CLK_BT] = {
-               .name = "s2mps14_bt",
-               .ops = &s2mps11_clk_ops,
-               .flags = CLK_IS_ROOT,
-       },
-};
-
 static struct device_node *s2mps11_clk_parse_dt(struct platform_device *pdev,
                struct clk_init_data *clks_init)
 {
@@ -164,12 +129,9 @@ static struct device_node *s2mps11_clk_parse_dt(struct platform_device *pdev,
                return ERR_PTR(-EINVAL);
        }
 
-       for (i = 0; i < S2MPS11_CLKS_NUM; i++) {
-               if (!clks_init[i].name)
-                       continue; /* Skip clocks not present in some devices */
+       for (i = 0; i < S2MPS11_CLKS_NUM; i++)
                of_property_read_string_index(clk_np, "clock-output-names", i,
                                &clks_init[i].name);
-       }
 
        return clk_np;
 }
@@ -177,39 +139,38 @@ static struct device_node *s2mps11_clk_parse_dt(struct platform_device *pdev,
 static int s2mps11_clk_probe(struct platform_device *pdev)
 {
        struct sec_pmic_dev *iodev = dev_get_drvdata(pdev->dev.parent);
-       struct s2mps11_clk *s2mps11_clks, *s2mps11_clk;
+       struct s2mps11_clk *s2mps11_clks;
+       struct clk_onecell_data *clk_data;
        unsigned int s2mps11_reg;
-       struct clk_init_data *clks_init;
        int i, ret = 0;
+       enum sec_device_type hwid = platform_get_device_id(pdev)->driver_data;
 
        s2mps11_clks = devm_kcalloc(&pdev->dev, S2MPS11_CLKS_NUM,
-                               sizeof(*s2mps11_clk), GFP_KERNEL);
+                               sizeof(*s2mps11_clks), GFP_KERNEL);
        if (!s2mps11_clks)
                return -ENOMEM;
 
-       s2mps11_clk = s2mps11_clks;
+       clk_data = devm_kzalloc(&pdev->dev, sizeof(*clk_data), GFP_KERNEL);
+       if (!clk_data)
+               return -ENOMEM;
 
-       clk_table = devm_kcalloc(&pdev->dev, S2MPS11_CLKS_NUM,
+       clk_data->clks = devm_kcalloc(&pdev->dev, S2MPS11_CLKS_NUM,
                                sizeof(struct clk *), GFP_KERNEL);
-       if (!clk_table)
+       if (!clk_data->clks)
                return -ENOMEM;
 
-       switch(platform_get_device_id(pdev)->driver_data) {
+       switch (hwid) {
        case S2MPS11X:
                s2mps11_reg = S2MPS11_REG_RTC_CTRL;
-               clks_init = s2mps11_clks_init;
                break;
        case S2MPS13X:
                s2mps11_reg = S2MPS13_REG_RTCCTRL;
-               clks_init = s2mps13_clks_init;
                break;
        case S2MPS14X:
                s2mps11_reg = S2MPS14_REG_RTCCTRL;
-               clks_init = s2mps14_clks_init;
                break;
        case S5M8767X:
                s2mps11_reg = S5M8767_REG_CTRL1;
-               clks_init = s2mps11_clks_init;
                break;
        default:
                dev_err(&pdev->dev, "Invalid device type\n");
@@ -217,46 +178,39 @@ static int s2mps11_clk_probe(struct platform_device *pdev)
        }
 
        /* Store clocks of_node in first element of s2mps11_clks array */
-       s2mps11_clks->clk_np = s2mps11_clk_parse_dt(pdev, clks_init);
+       s2mps11_clks->clk_np = s2mps11_clk_parse_dt(pdev, s2mps11_clks_init);
        if (IS_ERR(s2mps11_clks->clk_np))
                return PTR_ERR(s2mps11_clks->clk_np);
 
-       for (i = 0; i < S2MPS11_CLKS_NUM; i++, s2mps11_clk++) {
-               if (!clks_init[i].name)
+       for (i = 0; i < S2MPS11_CLKS_NUM; i++) {
+               if (i == S2MPS11_CLK_CP && hwid == S2MPS14X)
                        continue; /* Skip clocks not present in some devices */
-               s2mps11_clk->iodev = iodev;
-               s2mps11_clk->hw.init = &clks_init[i];
-               s2mps11_clk->mask = 1 << i;
-               s2mps11_clk->reg = s2mps11_reg;
-
-               s2mps11_clk->clk = devm_clk_register(&pdev->dev,
-                                                       &s2mps11_clk->hw);
-               if (IS_ERR(s2mps11_clk->clk)) {
+               s2mps11_clks[i].iodev = iodev;
+               s2mps11_clks[i].hw.init = &s2mps11_clks_init[i];
+               s2mps11_clks[i].mask = 1 << i;
+               s2mps11_clks[i].reg = s2mps11_reg;
+
+               s2mps11_clks[i].clk = devm_clk_register(&pdev->dev,
+                                                       &s2mps11_clks[i].hw);
+               if (IS_ERR(s2mps11_clks[i].clk)) {
                        dev_err(&pdev->dev, "Fail to register : %s\n",
-                                               s2mps11_name(s2mps11_clk));
-                       ret = PTR_ERR(s2mps11_clk->clk);
+                                               s2mps11_clks_init[i].name);
+                       ret = PTR_ERR(s2mps11_clks[i].clk);
                        goto err_reg;
                }
 
-               s2mps11_clk->lookup = clkdev_create(s2mps11_clk->clk,
-                                       s2mps11_name(s2mps11_clk), NULL);
-               if (!s2mps11_clk->lookup) {
+               s2mps11_clks[i].lookup = clkdev_create(s2mps11_clks[i].clk,
+                                       s2mps11_clks_init[i].name, NULL);
+               if (!s2mps11_clks[i].lookup) {
                        ret = -ENOMEM;
                        goto err_reg;
                }
+               clk_data->clks[i] = s2mps11_clks[i].clk;
        }
 
-       for (i = 0; i < S2MPS11_CLKS_NUM; i++) {
-               /* Skip clocks not present on S2MPS14 */
-               if (!clks_init[i].name)
-                       continue;
-               clk_table[i] = s2mps11_clks[i].clk;
-       }
-
-       clk_data.clks = clk_table;
-       clk_data.clk_num = S2MPS11_CLKS_NUM;
+       clk_data->clk_num = S2MPS11_CLKS_NUM;
        of_clk_add_provider(s2mps11_clks->clk_np, of_clk_src_onecell_get,
-                       &clk_data);
+                       clk_data);
 
        platform_set_drvdata(pdev, s2mps11_clks);
 
index cd0f2726f5e0dd0da33b06e4518f02fc231cf1f7..89e9ca78bb947ec2ff8242d5d826ccf8449d6259 100644 (file)
@@ -299,7 +299,7 @@ static int scpi_clocks_probe(struct platform_device *pdev)
        /* Add the virtual cpufreq device */
        cpufreq_dev = platform_device_register_simple("scpi-cpufreq",
                                                      -1, NULL, 0);
-       if (!cpufreq_dev)
+       if (IS_ERR(cpufreq_dev))
                pr_warn("unable to register cpufreq device");
 
        return 0;
index 37e928846ec5b3fb1fed8144570c1f8aeaa027bb..b0f76a84f1e9fec9d3f2bcc7ec0f41eec37fbf93 100644 (file)
@@ -355,7 +355,7 @@ CLK_OF_DECLARE(vt8500_device, "via,vt8500-device-clock", vtwm_device_clk_init);
 #define WM8850_BITS_TO_VAL(m, d1, d2)                                  \
                ((((m / 2) - 1) << 16) | ((d1 - 1) << 8) | d2)
 
-static void vt8500_find_pll_bits(unsigned long rate, unsigned long parent_rate,
+static int vt8500_find_pll_bits(unsigned long rate, unsigned long parent_rate,
                                u32 *multiplier, u32 *prediv)
 {
        unsigned long tclk;
@@ -365,7 +365,7 @@ static void vt8500_find_pll_bits(unsigned long rate, unsigned long parent_rate,
                pr_err("%s: requested rate out of range\n", __func__);
                *multiplier = 0;
                *prediv = 1;
-               return;
+               return -EINVAL;
        }
        if (rate <= parent_rate * 31)
                /* use the prediv to double the resolution */
@@ -379,12 +379,15 @@ static void vt8500_find_pll_bits(unsigned long rate, unsigned long parent_rate,
        if (tclk != rate)
                pr_warn("%s: requested rate %lu, found rate %lu\n", __func__,
                                                                rate, tclk);
+
+       return 0;
 }
 
-static void wm8650_find_pll_bits(unsigned long rate, unsigned long parent_rate,
+static int wm8650_find_pll_bits(unsigned long rate, unsigned long parent_rate,
                                u32 *multiplier, u32 *divisor1, u32 *divisor2)
 {
-       u32 mul, div1, div2;
+       u32 mul, div1;
+       int div2;
        u32 best_mul, best_div1, best_div2;
        unsigned long tclk, rate_err, best_err;
 
@@ -403,7 +406,7 @@ static void wm8650_find_pll_bits(unsigned long rate, unsigned long parent_rate,
                                        *multiplier = mul;
                                        *divisor1 = div1;
                                        *divisor2 = div2;
-                                       return;
+                                       return 0;
                                }
 
                                if (rate_err < best_err) {
@@ -414,12 +417,19 @@ static void wm8650_find_pll_bits(unsigned long rate, unsigned long parent_rate,
                                }
                        }
 
+       if (best_err == (unsigned long)-1) {
+               pr_warn("%s: impossible rate %lu\n", __func__, rate);
+               return -EINVAL;
+       }
+
        /* if we got here, it wasn't an exact match */
        pr_warn("%s: requested rate %lu, found rate %lu\n", __func__, rate,
                                                        rate - best_err);
        *multiplier = best_mul;
        *divisor1 = best_div1;
        *divisor2 = best_div2;
+
+       return 0;
 }
 
 static u32 wm8750_get_filter(u32 parent_rate, u32 divisor1)
@@ -449,10 +459,11 @@ static u32 wm8750_get_filter(u32 parent_rate, u32 divisor1)
        return 0;
 }
 
-static void wm8750_find_pll_bits(unsigned long rate, unsigned long parent_rate,
+static int wm8750_find_pll_bits(unsigned long rate, unsigned long parent_rate,
                                u32 *filter, u32 *multiplier, u32 *divisor1, u32 *divisor2)
 {
-       u32 mul, div1, div2;
+       u32 mul;
+       int div1, div2;
        u32 best_mul, best_div1, best_div2;
        unsigned long tclk, rate_err, best_err;
 
@@ -472,7 +483,7 @@ static void wm8750_find_pll_bits(unsigned long rate, unsigned long parent_rate,
                                        *multiplier = mul;
                                        *divisor1 = div1;
                                        *divisor2 = div2;
-                                       return;
+                                       return 0;
                                }
 
                                if (rate_err < best_err) {
@@ -483,6 +494,11 @@ static void wm8750_find_pll_bits(unsigned long rate, unsigned long parent_rate,
                                }
                        }
 
+       if (best_err == (unsigned long)-1) {
+               pr_warn("%s: impossible rate %lu\n", __func__, rate);
+               return -EINVAL;
+       }
+
        /* if we got here, it wasn't an exact match */
        pr_warn("%s: requested rate %lu, found rate %lu\n", __func__, rate,
                                                        rate - best_err);
@@ -491,12 +507,15 @@ static void wm8750_find_pll_bits(unsigned long rate, unsigned long parent_rate,
        *multiplier = best_mul;
        *divisor1 = best_div1;
        *divisor2 = best_div2;
+
+       return 0;
 }
 
-static void wm8850_find_pll_bits(unsigned long rate, unsigned long parent_rate,
+static int wm8850_find_pll_bits(unsigned long rate, unsigned long parent_rate,
                                u32 *multiplier, u32 *divisor1, u32 *divisor2)
 {
-       u32 mul, div1, div2;
+       u32 mul;
+       int div1, div2;
        u32 best_mul, best_div1, best_div2;
        unsigned long tclk, rate_err, best_err;
 
@@ -516,7 +535,7 @@ static void wm8850_find_pll_bits(unsigned long rate, unsigned long parent_rate,
                                        *multiplier = mul;
                                        *divisor1 = div1;
                                        *divisor2 = div2;
-                                       return;
+                                       return 0;
                                }
 
                                if (rate_err < best_err) {
@@ -527,6 +546,11 @@ static void wm8850_find_pll_bits(unsigned long rate, unsigned long parent_rate,
                                }
                        }
 
+       if (best_err == (unsigned long)-1) {
+               pr_warn("%s: impossible rate %lu\n", __func__, rate);
+               return -EINVAL;
+       }
+
        /* if we got here, it wasn't an exact match */
        pr_warn("%s: requested rate %lu, found rate %lu\n", __func__, rate,
                                                        rate - best_err);
@@ -534,6 +558,8 @@ static void wm8850_find_pll_bits(unsigned long rate, unsigned long parent_rate,
        *multiplier = best_mul;
        *divisor1 = best_div1;
        *divisor2 = best_div2;
+
+       return 0;
 }
 
 static int vtwm_pll_set_rate(struct clk_hw *hw, unsigned long rate,
@@ -543,31 +569,39 @@ static int vtwm_pll_set_rate(struct clk_hw *hw, unsigned long rate,
        u32 filter, mul, div1, div2;
        u32 pll_val;
        unsigned long flags = 0;
+       int ret;
 
        /* sanity check */
 
        switch (pll->type) {
        case PLL_TYPE_VT8500:
-               vt8500_find_pll_bits(rate, parent_rate, &mul, &div1);
-               pll_val = VT8500_BITS_TO_VAL(mul, div1);
+               ret = vt8500_find_pll_bits(rate, parent_rate, &mul, &div1);
+               if (!ret)
+                       pll_val = VT8500_BITS_TO_VAL(mul, div1);
                break;
        case PLL_TYPE_WM8650:
-               wm8650_find_pll_bits(rate, parent_rate, &mul, &div1, &div2);
-               pll_val = WM8650_BITS_TO_VAL(mul, div1, div2);
+               ret = wm8650_find_pll_bits(rate, parent_rate, &mul, &div1, &div2);
+               if (!ret)
+                       pll_val = WM8650_BITS_TO_VAL(mul, div1, div2);
                break;
        case PLL_TYPE_WM8750:
-               wm8750_find_pll_bits(rate, parent_rate, &filter, &mul, &div1, &div2);
-               pll_val = WM8750_BITS_TO_VAL(filter, mul, div1, div2);
+               ret = wm8750_find_pll_bits(rate, parent_rate, &filter, &mul, &div1, &div2);
+               if (!ret)
+                       pll_val = WM8750_BITS_TO_VAL(filter, mul, div1, div2);
                break;
        case PLL_TYPE_WM8850:
-               wm8850_find_pll_bits(rate, parent_rate, &mul, &div1, &div2);
-               pll_val = WM8850_BITS_TO_VAL(mul, div1, div2);
+               ret = wm8850_find_pll_bits(rate, parent_rate, &mul, &div1, &div2);
+               if (!ret)
+                       pll_val = WM8850_BITS_TO_VAL(mul, div1, div2);
                break;
        default:
                pr_err("%s: invalid pll type\n", __func__);
-               return 0;
+               ret = -EINVAL;
        }
 
+       if (ret)
+               return ret;
+
        spin_lock_irqsave(pll->lock, flags);
 
        vt8500_pmc_wait_busy();
@@ -585,28 +619,36 @@ static long vtwm_pll_round_rate(struct clk_hw *hw, unsigned long rate,
        struct clk_pll *pll = to_clk_pll(hw);
        u32 filter, mul, div1, div2;
        long round_rate;
+       int ret;
 
        switch (pll->type) {
        case PLL_TYPE_VT8500:
-               vt8500_find_pll_bits(rate, *prate, &mul, &div1);
-               round_rate = VT8500_BITS_TO_FREQ(*prate, mul, div1);
+               ret = vt8500_find_pll_bits(rate, *prate, &mul, &div1);
+               if (!ret)
+                       round_rate = VT8500_BITS_TO_FREQ(*prate, mul, div1);
                break;
        case PLL_TYPE_WM8650:
-               wm8650_find_pll_bits(rate, *prate, &mul, &div1, &div2);
-               round_rate = WM8650_BITS_TO_FREQ(*prate, mul, div1, div2);
+               ret = wm8650_find_pll_bits(rate, *prate, &mul, &div1, &div2);
+               if (!ret)
+                       round_rate = WM8650_BITS_TO_FREQ(*prate, mul, div1, div2);
                break;
        case PLL_TYPE_WM8750:
-               wm8750_find_pll_bits(rate, *prate, &filter, &mul, &div1, &div2);
-               round_rate = WM8750_BITS_TO_FREQ(*prate, mul, div1, div2);
+               ret = wm8750_find_pll_bits(rate, *prate, &filter, &mul, &div1, &div2);
+               if (!ret)
+                       round_rate = WM8750_BITS_TO_FREQ(*prate, mul, div1, div2);
                break;
        case PLL_TYPE_WM8850:
-               wm8850_find_pll_bits(rate, *prate, &mul, &div1, &div2);
-               round_rate = WM8850_BITS_TO_FREQ(*prate, mul, div1, div2);
+               ret = wm8850_find_pll_bits(rate, *prate, &mul, &div1, &div2);
+               if (!ret)
+                       round_rate = WM8850_BITS_TO_FREQ(*prate, mul, div1, div2);
                break;
        default:
-               round_rate = 0;
+               ret = -EINVAL;
        }
 
+       if (ret)
+               return ret;
+
        return round_rate;
 }
 
index 10224b01b97c5c6206372f36f9f81fa7ed861b56..bd7156baa08bcf757f2a6663b5f5394ebaef5a1f 100644 (file)
@@ -29,7 +29,9 @@
 #include <linux/of_address.h>
 
 /* Register SCU_PCPPLL bit fields */
-#define N_DIV_RD(src)                  (((src) & 0x000001ff))
+#define N_DIV_RD(src)                  ((src) & 0x000001ff)
+#define SC_N_DIV_RD(src)               ((src) & 0x0000007f)
+#define SC_OUTDIV2(src)                        (((src) & 0x00000100) >> 8)
 
 /* Register SCU_SOCPLL bit fields */
 #define CLKR_RD(src)                   (((src) & 0x07000000)>>24)
@@ -48,7 +50,7 @@ static inline u32 xgene_clk_read(void __iomem *csr)
 
 static inline void xgene_clk_write(u32 data, void __iomem *csr)
 {
-       return writel_relaxed(data, csr);
+       writel_relaxed(data, csr);
 }
 
 /* PLL Clock */
@@ -63,6 +65,7 @@ struct xgene_clk_pll {
        spinlock_t      *lock;
        u32             pll_offset;
        enum xgene_pll_type     type;
+       int             version;
 };
 
 #define to_xgene_clk_pll(_hw) container_of(_hw, struct xgene_clk_pll, hw)
@@ -92,27 +95,37 @@ static unsigned long xgene_clk_pll_recalc_rate(struct clk_hw *hw,
 
        pll = xgene_clk_read(pllclk->reg + pllclk->pll_offset);
 
-       if (pllclk->type == PLL_TYPE_PCP) {
-               /*
-                * PLL VCO = Reference clock * NF
-                * PCP PLL = PLL_VCO / 2
-                */
-               nout = 2;
-               fvco = parent_rate * (N_DIV_RD(pll) + 4);
+       if (pllclk->version <= 1) {
+               if (pllclk->type == PLL_TYPE_PCP) {
+                       /*
+                       * PLL VCO = Reference clock * NF
+                       * PCP PLL = PLL_VCO / 2
+                       */
+                       nout = 2;
+                       fvco = parent_rate * (N_DIV_RD(pll) + 4);
+               } else {
+                       /*
+                       * Fref = Reference Clock / NREF;
+                       * Fvco = Fref * NFB;
+                       * Fout = Fvco / NOUT;
+                       */
+                       nref = CLKR_RD(pll) + 1;
+                       nout = CLKOD_RD(pll) + 1;
+                       nfb = CLKF_RD(pll);
+                       fref = parent_rate / nref;
+                       fvco = fref * nfb;
+               }
        } else {
                /*
-                * Fref = Reference Clock / NREF;
-                * Fvco = Fref * NFB;
-                * Fout = Fvco / NOUT;
+                * fvco = Reference clock * FBDIVC
+                * PLL freq = fvco / NOUT
                 */
-               nref = CLKR_RD(pll) + 1;
-               nout = CLKOD_RD(pll) + 1;
-               nfb = CLKF_RD(pll);
-               fref = parent_rate / nref;
-               fvco = fref * nfb;
+               nout = SC_OUTDIV2(pll) ? 2 : 3;
+               fvco = parent_rate * SC_N_DIV_RD(pll);
        }
-       pr_debug("%s pll recalc rate %ld parent %ld\n", clk_hw_get_name(hw),
-               fvco / nout, parent_rate);
+       pr_debug("%s pll recalc rate %ld parent %ld version %d\n",
+                clk_hw_get_name(hw), fvco / nout, parent_rate,
+                pllclk->version);
 
        return fvco / nout;
 }
@@ -125,7 +138,7 @@ static const struct clk_ops xgene_clk_pll_ops = {
 static struct clk *xgene_register_clk_pll(struct device *dev,
        const char *name, const char *parent_name,
        unsigned long flags, void __iomem *reg, u32 pll_offset,
-       u32 type, spinlock_t *lock)
+       u32 type, spinlock_t *lock, int version)
 {
        struct xgene_clk_pll *apmclk;
        struct clk *clk;
@@ -144,6 +157,7 @@ static struct clk *xgene_register_clk_pll(struct device *dev,
        init.parent_names = parent_name ? &parent_name : NULL;
        init.num_parents = parent_name ? 1 : 0;
 
+       apmclk->version = version;
        apmclk->reg = reg;
        apmclk->lock = lock;
        apmclk->pll_offset = pll_offset;
@@ -160,26 +174,37 @@ static struct clk *xgene_register_clk_pll(struct device *dev,
        return clk;
 }
 
+static int xgene_pllclk_version(struct device_node *np)
+{
+       if (of_device_is_compatible(np, "apm,xgene-socpll-clock"))
+               return 1;
+       if (of_device_is_compatible(np, "apm,xgene-pcppll-clock"))
+               return 1;
+       return 2;
+}
+
 static void xgene_pllclk_init(struct device_node *np, enum xgene_pll_type pll_type)
 {
-        const char *clk_name = np->full_name;
-        struct clk *clk;
-        void __iomem *reg;
+       const char *clk_name = np->full_name;
+       struct clk *clk;
+       void __iomem *reg;
+       int version = xgene_pllclk_version(np);
 
-        reg = of_iomap(np, 0);
-        if (reg == NULL) {
-                pr_err("Unable to map CSR register for %s\n", np->full_name);
-                return;
-        }
-        of_property_read_string(np, "clock-output-names", &clk_name);
-        clk = xgene_register_clk_pll(NULL,
-                        clk_name, of_clk_get_parent_name(np, 0),
-                        CLK_IS_ROOT, reg, 0, pll_type, &clk_lock);
-        if (!IS_ERR(clk)) {
-                of_clk_add_provider(np, of_clk_src_simple_get, clk);
-                clk_register_clkdev(clk, clk_name, NULL);
-                pr_debug("Add %s clock PLL\n", clk_name);
-        }
+       reg = of_iomap(np, 0);
+       if (reg == NULL) {
+               pr_err("Unable to map CSR register for %s\n", np->full_name);
+               return;
+       }
+       of_property_read_string(np, "clock-output-names", &clk_name);
+       clk = xgene_register_clk_pll(NULL,
+                       clk_name, of_clk_get_parent_name(np, 0),
+                       CLK_IS_ROOT, reg, 0, pll_type, &clk_lock,
+                       version);
+       if (!IS_ERR(clk)) {
+               of_clk_add_provider(np, of_clk_src_simple_get, clk);
+               clk_register_clkdev(clk, clk_name, NULL);
+               pr_debug("Add %s clock PLL\n", clk_name);
+       }
 }
 
 static void xgene_socpllclk_init(struct device_node *np)
@@ -460,7 +485,7 @@ static void __init xgene_devclk_init(struct device_node *np)
                rc = of_address_to_resource(np, i, &res);
                if (rc != 0) {
                        if (i == 0) {
-                               pr_err("no DTS register for %s\n", 
+                               pr_err("no DTS register for %s\n",
                                        np->full_name);
                                return;
                        }
@@ -518,4 +543,8 @@ err:
 
 CLK_OF_DECLARE(xgene_socpll_clock, "apm,xgene-socpll-clock", xgene_socpllclk_init);
 CLK_OF_DECLARE(xgene_pcppll_clock, "apm,xgene-pcppll-clock", xgene_pcppllclk_init);
+CLK_OF_DECLARE(xgene_socpll_v2_clock, "apm,xgene-socpll-v2-clock",
+              xgene_socpllclk_init);
+CLK_OF_DECLARE(xgene_pcppll_v2_clock, "apm,xgene-pcppll-v2-clock",
+              xgene_pcppllclk_init);
 CLK_OF_DECLARE(xgene_dev_clock, "apm,xgene-device-clock", xgene_devclk_init);
index b4db67a446c81ad961d8ab3e027f1ff955483efb..67cd2f116c3b8b34925caa6c21c02570ccaf872a 100644 (file)
@@ -350,13 +350,12 @@ static struct clk_core *clk_core_get_parent_by_index(struct clk_core *core,
 {
        if (!core || index >= core->num_parents)
                return NULL;
-       else if (!core->parents)
-               return clk_core_lookup(core->parent_names[index]);
-       else if (!core->parents[index])
-               return core->parents[index] =
-                       clk_core_lookup(core->parent_names[index]);
-       else
-               return core->parents[index];
+
+       if (!core->parents[index])
+               core->parents[index] =
+                               clk_core_lookup(core->parent_names[index]);
+
+       return core->parents[index];
 }
 
 struct clk_hw *
@@ -386,7 +385,7 @@ static unsigned long clk_core_get_rate_nolock(struct clk_core *core)
 
        ret = core->rate;
 
-       if (core->flags & CLK_IS_ROOT)
+       if (!core->num_parents)
                goto out;
 
        if (!core->parent)
@@ -1067,30 +1066,12 @@ static int clk_fetch_parent_index(struct clk_core *core,
 {
        int i;
 
-       if (!core->parents) {
-               core->parents = kcalloc(core->num_parents,
-                                       sizeof(struct clk *), GFP_KERNEL);
-               if (!core->parents)
-                       return -ENOMEM;
-       }
-
-       /*
-        * find index of new parent clock using cached parent ptrs,
-        * or if not yet cached, use string name comparison and cache
-        * them now to avoid future calls to clk_core_lookup.
-        */
-       for (i = 0; i < core->num_parents; i++) {
-               if (core->parents[i] == parent)
-                       return i;
-
-               if (core->parents[i])
-                       continue;
+       if (!parent)
+               return -EINVAL;
 
-               if (!strcmp(core->parent_names[i], parent->name)) {
-                       core->parents[i] = clk_core_lookup(parent->name);
+       for (i = 0; i < core->num_parents; i++)
+               if (clk_core_get_parent_by_index(core, i) == parent)
                        return i;
-               }
-       }
 
        return -EINVAL;
 }
@@ -1677,56 +1658,14 @@ struct clk *clk_get_parent(struct clk *clk)
 }
 EXPORT_SYMBOL_GPL(clk_get_parent);
 
-/*
- * .get_parent is mandatory for clocks with multiple possible parents.  It is
- * optional for single-parent clocks.  Always call .get_parent if it is
- * available and WARN if it is missing for multi-parent clocks.
- *
- * For single-parent clocks without .get_parent, first check to see if the
- * .parents array exists, and if so use it to avoid an expensive tree
- * traversal.  If .parents does not exist then walk the tree.
- */
 static struct clk_core *__clk_init_parent(struct clk_core *core)
 {
-       struct clk_core *ret = NULL;
-       u8 index;
-
-       /* handle the trivial cases */
-
-       if (!core->num_parents)
-               goto out;
-
-       if (core->num_parents == 1) {
-               if (IS_ERR_OR_NULL(core->parent))
-                       core->parent = clk_core_lookup(core->parent_names[0]);
-               ret = core->parent;
-               goto out;
-       }
-
-       if (!core->ops->get_parent) {
-               WARN(!core->ops->get_parent,
-                       "%s: multi-parent clocks must implement .get_parent\n",
-                       __func__);
-               goto out;
-       }
-
-       /*
-        * Do our best to cache parent clocks in core->parents.  This prevents
-        * unnecessary and expensive lookups.  We don't set core->parent here;
-        * that is done by the calling function.
-        */
+       u8 index = 0;
 
-       index = core->ops->get_parent(core->hw);
+       if (core->num_parents > 1 && core->ops->get_parent)
+               index = core->ops->get_parent(core->hw);
 
-       if (!core->parents)
-               core->parents =
-                       kcalloc(core->num_parents, sizeof(struct clk *),
-                                       GFP_KERNEL);
-
-       ret = clk_core_get_parent_by_index(core, index);
-
-out:
-       return ret;
+       return clk_core_get_parent_by_index(core, index);
 }
 
 static void clk_core_reparent(struct clk_core *core,
@@ -1809,13 +1748,13 @@ static int clk_core_set_parent(struct clk_core *core, struct clk_core *parent)
        /* try finding the new parent index */
        if (parent) {
                p_index = clk_fetch_parent_index(core, parent);
-               p_rate = parent->rate;
                if (p_index < 0) {
                        pr_debug("%s: clk %s can not be parent of clk %s\n",
                                        __func__, parent->name, core->name);
                        ret = p_index;
                        goto out;
                }
+               p_rate = parent->rate;
        }
 
        /* propagate PRE_RATE_CHANGE notifications */
@@ -2303,26 +2242,54 @@ static inline void clk_debug_unregister(struct clk_core *core)
 #endif
 
 /**
- * __clk_init - initialize the data structures in a struct clk
- * @dev:       device initializing this clk, placeholder for now
- * @clk:       clk being initialized
+ * __clk_is_ancestor - check if a clk_core is a possible ancestor of another
+ * @core: clock core
+ * @ancestor: ancestor clock core
+ *
+ * Returns true if there is a possibility that @ancestor can be an ancestor
+ * of @core, false otherwise.
+ *
+ * This function can be used against @core or @ancestor that has not been
+ * registered yet.
+ */
+static bool __clk_is_ancestor(struct clk_core *core, struct clk_core *ancestor)
+{
+       struct clk_core *parent;
+       int i;
+
+       for (i = 0; i < core->num_parents; i++) {
+               parent = clk_core_get_parent_by_index(core, i);
+               /*
+                * If ancestor has not been added to clk_{root,orphan}_list
+                * yet, clk_core_lookup() cannot find it.  If parent is NULL,
+                * compare the name strings, too.
+                */
+               if ((parent && (parent == ancestor ||
+                               __clk_is_ancestor(parent, ancestor))) ||
+                   (!parent && !strcmp(core->parent_names[i], ancestor->name)))
+                       return true;
+       }
+
+       return false;
+}
+
+/**
+ * __clk_core_init - initialize the data structures in a struct clk_core
+ * @core:      clk_core being initialized
  *
  * Initializes the lists in struct clk_core, queries the hardware for the
  * parent and rate and sets them both.
  */
-static int __clk_init(struct device *dev, struct clk *clk_user)
+static int __clk_core_init(struct clk_core *core)
 {
        int i, ret = 0;
        struct clk_core *orphan;
        struct hlist_node *tmp2;
-       struct clk_core *core;
        unsigned long rate;
 
-       if (!clk_user)
+       if (!core)
                return -EINVAL;
 
-       core = clk_user->core;
-
        clk_prepare_lock();
 
        /* check to see if a clock with this name is already registered */
@@ -2337,22 +2304,29 @@ static int __clk_init(struct device *dev, struct clk *clk_user)
        if (core->ops->set_rate &&
            !((core->ops->round_rate || core->ops->determine_rate) &&
              core->ops->recalc_rate)) {
-               pr_warning("%s: %s must implement .round_rate or .determine_rate in addition to .recalc_rate\n",
-                               __func__, core->name);
+               pr_err("%s: %s must implement .round_rate or .determine_rate in addition to .recalc_rate\n",
+                      __func__, core->name);
                ret = -EINVAL;
                goto out;
        }
 
        if (core->ops->set_parent && !core->ops->get_parent) {
-               pr_warning("%s: %s must implement .get_parent & .set_parent\n",
-                               __func__, core->name);
+               pr_err("%s: %s must implement .get_parent & .set_parent\n",
+                      __func__, core->name);
+               ret = -EINVAL;
+               goto out;
+       }
+
+       if (core->num_parents > 1 && !core->ops->get_parent) {
+               pr_err("%s: %s must implement .get_parent as it has multi parents\n",
+                      __func__, core->name);
                ret = -EINVAL;
                goto out;
        }
 
        if (core->ops->set_rate_and_parent &&
                        !(core->ops->set_parent && core->ops->set_rate)) {
-               pr_warn("%s: %s must implement .set_parent & .set_rate\n",
+               pr_err("%s: %s must implement .set_parent & .set_rate\n",
                                __func__, core->name);
                ret = -EINVAL;
                goto out;
@@ -2364,29 +2338,12 @@ static int __clk_init(struct device *dev, struct clk *clk_user)
                                "%s: invalid NULL in %s's .parent_names\n",
                                __func__, core->name);
 
-       /*
-        * Allocate an array of struct clk *'s to avoid unnecessary string
-        * look-ups of clk's possible parents.  This can fail for clocks passed
-        * in to clk_init during early boot; thus any access to core->parents[]
-        * must always check for a NULL pointer and try to populate it if
-        * necessary.
-        *
-        * If core->parents is not NULL we skip this entire block.  This allows
-        * for clock drivers to statically initialize core->parents.
-        */
-       if (core->num_parents > 1 && !core->parents) {
-               core->parents = kcalloc(core->num_parents, sizeof(struct clk *),
-                                       GFP_KERNEL);
-               /*
-                * clk_core_lookup returns NULL for parents that have not been
-                * clk_init'd; thus any access to clk->parents[] must check
-                * for a NULL pointer.  We can always perform lazy lookups for
-                * missing parents later on.
-                */
-               if (core->parents)
-                       for (i = 0; i < core->num_parents; i++)
-                               core->parents[i] =
-                                       clk_core_lookup(core->parent_names[i]);
+       /* If core is an ancestor of itself, it would make a loop. */
+       if (__clk_is_ancestor(core, core)) {
+               pr_err("%s: %s would create circular parent\n", __func__,
+                      core->name);
+               ret = -EINVAL;
+               goto out;
        }
 
        core->parent = __clk_init_parent(core);
@@ -2394,7 +2351,7 @@ static int __clk_init(struct device *dev, struct clk *clk_user)
        /*
         * Populate core->parent if parent has already been __clk_init'd.  If
         * parent has not yet been __clk_init'd then place clk in the orphan
-        * list.  If clk has set the CLK_IS_ROOT flag then place it in the root
+        * list.  If clk doesn't have any parents then place it in the root
         * clk list.
         *
         * Every time a new clk is clk_init'd then we walk the list of orphan
@@ -2405,7 +2362,7 @@ static int __clk_init(struct device *dev, struct clk *clk_user)
                hlist_add_head(&core->child_node,
                                &core->parent->children);
                core->orphan = core->parent->orphan;
-       } else if (core->flags & CLK_IS_ROOT) {
+       } else if (!core->num_parents) {
                hlist_add_head(&core->child_node, &clk_root_list);
                core->orphan = false;
        } else {
@@ -2454,24 +2411,15 @@ static int __clk_init(struct device *dev, struct clk *clk_user)
        core->rate = core->req_rate = rate;
 
        /*
-        * walk the list of orphan clocks and reparent any that are children of
-        * this clock
+        * walk the list of orphan clocks and reparent any that newly finds a
+        * parent.
         */
        hlist_for_each_entry_safe(orphan, tmp2, &clk_orphan_list, child_node) {
-               if (orphan->num_parents && orphan->ops->get_parent) {
-                       i = orphan->ops->get_parent(orphan->hw);
-                       if (i >= 0 && i < orphan->num_parents &&
-                           !strcmp(core->name, orphan->parent_names[i]))
-                               clk_core_reparent(orphan, core);
-                       continue;
-               }
+               struct clk_core *parent = __clk_init_parent(orphan);
 
-               for (i = 0; i < orphan->num_parents; i++)
-                       if (!strcmp(core->name, orphan->parent_names[i])) {
-                               clk_core_reparent(orphan, core);
-                               break;
-                       }
-        }
+               if (parent)
+                       clk_core_reparent(orphan, parent);
+       }
 
        /*
         * optional platform-specific magic
@@ -2585,21 +2533,31 @@ struct clk *clk_register(struct device *dev, struct clk_hw *hw)
                }
        }
 
+       /* avoid unnecessary string look-ups of clk_core's possible parents. */
+       core->parents = kcalloc(core->num_parents, sizeof(*core->parents),
+                               GFP_KERNEL);
+       if (!core->parents) {
+               ret = -ENOMEM;
+               goto fail_parents;
+       };
+
        INIT_HLIST_HEAD(&core->clks);
 
        hw->clk = __clk_create_clk(hw, NULL, NULL);
        if (IS_ERR(hw->clk)) {
                ret = PTR_ERR(hw->clk);
-               goto fail_parent_names_copy;
+               goto fail_parents;
        }
 
-       ret = __clk_init(dev, hw->clk);
+       ret = __clk_core_init(core);
        if (!ret)
                return hw->clk;
 
        __clk_free_clk(hw->clk);
        hw->clk = NULL;
 
+fail_parents:
+       kfree(core->parents);
 fail_parent_names_copy:
        while (--i >= 0)
                kfree_const(core->parent_names[i]);
@@ -2683,7 +2641,7 @@ void clk_unregister(struct clk *clk)
        if (clk->core->ops == &clk_nodrv_ops) {
                pr_err("%s: unregistered clock: %s\n", __func__,
                       clk->core->name);
-               return;
+               goto unlock;
        }
        /*
         * Assign empty clock ops for consumers that might still hold
@@ -2709,7 +2667,7 @@ void clk_unregister(struct clk *clk)
                pr_warn("%s: unregistering prepared clock: %s\n",
                                        __func__, clk->core->name);
        kref_put(&clk->core->ref, __clk_release);
-
+unlock:
        clk_prepare_unlock();
 }
 EXPORT_SYMBOL_GPL(clk_unregister);
index 4bb1bc419b798e5323652d36c0cf1413e45ccf31..5cc99590f9a33a397bc1fc51ffaf821867aeb6e9 100644 (file)
@@ -38,7 +38,7 @@ struct clk_busy_divider {
 
 static inline struct clk_busy_divider *to_clk_busy_divider(struct clk_hw *hw)
 {
-       struct clk_divider *div = container_of(hw, struct clk_divider, hw);
+       struct clk_divider *div = to_clk_divider(hw);
 
        return container_of(div, struct clk_busy_divider, div);
 }
@@ -123,7 +123,7 @@ struct clk_busy_mux {
 
 static inline struct clk_busy_mux *to_clk_busy_mux(struct clk_hw *hw)
 {
-       struct clk_mux *mux = container_of(hw, struct clk_mux, hw);
+       struct clk_mux *mux = to_clk_mux(hw);
 
        return container_of(mux, struct clk_busy_mux, mux);
 }
index 21db020b1f2dccee6b7646ac4cd0a4f6e8308e7d..ce57227327153064b9f359d82ce91da148e6f02e 100644 (file)
@@ -15,7 +15,6 @@
 #include <linux/slab.h>
 #include "clk.h"
 
-#define to_clk_div(_hw) container_of(_hw, struct clk_divider, hw)
 #define div_mask(d)    ((1 << (d->width)) - 1)
 
 /**
@@ -35,7 +34,7 @@ struct clk_fixup_div {
 
 static inline struct clk_fixup_div *to_clk_fixup_div(struct clk_hw *hw)
 {
-       struct clk_divider *divider = to_clk_div(hw);
+       struct clk_divider *divider = to_clk_divider(hw);
 
        return container_of(divider, struct clk_fixup_div, divider);
 }
@@ -60,7 +59,7 @@ static int clk_fixup_div_set_rate(struct clk_hw *hw, unsigned long rate,
                            unsigned long parent_rate)
 {
        struct clk_fixup_div *fixup_div = to_clk_fixup_div(hw);
-       struct clk_divider *div = to_clk_div(hw);
+       struct clk_divider *div = to_clk_divider(hw);
        unsigned int divider, value;
        unsigned long flags = 0;
        u32 val;
index 0d40b35c557cba39980ad2644e6d4a97902f9555..c9b327e0a8dd9b2fd6f9c939f762c6dd46ae9917 100644 (file)
@@ -15,8 +15,6 @@
 #include <linux/slab.h>
 #include "clk.h"
 
-#define to_clk_mux(_hw) container_of(_hw, struct clk_mux, hw)
-
 /**
  * struct clk_fixup_mux - imx integer fixup multiplexer clock
  * @mux: the parent class
index c12f5f2e04dc1dda3d2a55c795e07e55ed012e52..3bd9dee618b2c2c06a9d18aa6f4efde5e8bf0f0d 100644 (file)
@@ -31,7 +31,7 @@ struct clk_gate_exclusive {
 
 static int clk_gate_exclusive_enable(struct clk_hw *hw)
 {
-       struct clk_gate *gate = container_of(hw, struct clk_gate, hw);
+       struct clk_gate *gate = to_clk_gate(hw);
        struct clk_gate_exclusive *exgate = container_of(gate,
                                        struct clk_gate_exclusive, gate);
        u32 val = readl(gate->reg);
index 576bdb7c98b8c98f6ece22aea9ae80443ad2b887..2a76901bf04bf377c3903bf19ff58670c96cd332 100644 (file)
@@ -25,7 +25,7 @@
 
 static int mtk_cg_bit_is_cleared(struct clk_hw *hw)
 {
-       struct mtk_clk_gate *cg = to_clk_gate(hw);
+       struct mtk_clk_gate *cg = to_mtk_clk_gate(hw);
        u32 val;
 
        regmap_read(cg->regmap, cg->sta_ofs, &val);
@@ -37,7 +37,7 @@ static int mtk_cg_bit_is_cleared(struct clk_hw *hw)
 
 static int mtk_cg_bit_is_set(struct clk_hw *hw)
 {
-       struct mtk_clk_gate *cg = to_clk_gate(hw);
+       struct mtk_clk_gate *cg = to_mtk_clk_gate(hw);
        u32 val;
 
        regmap_read(cg->regmap, cg->sta_ofs, &val);
@@ -49,14 +49,14 @@ static int mtk_cg_bit_is_set(struct clk_hw *hw)
 
 static void mtk_cg_set_bit(struct clk_hw *hw)
 {
-       struct mtk_clk_gate *cg = to_clk_gate(hw);
+       struct mtk_clk_gate *cg = to_mtk_clk_gate(hw);
 
        regmap_write(cg->regmap, cg->set_ofs, BIT(cg->bit));
 }
 
 static void mtk_cg_clr_bit(struct clk_hw *hw)
 {
-       struct mtk_clk_gate *cg = to_clk_gate(hw);
+       struct mtk_clk_gate *cg = to_mtk_clk_gate(hw);
 
        regmap_write(cg->regmap, cg->clr_ofs, BIT(cg->bit));
 }
index 11e25c992948fdcc7ea00c5cfa31f0274e6dfb53..b1821603b887f2874f97c6fb1819ff0fddfcd619 100644 (file)
@@ -29,7 +29,7 @@ struct mtk_clk_gate {
        u8              bit;
 };
 
-static inline struct mtk_clk_gate *to_clk_gate(struct clk_hw *hw)
+static inline struct mtk_clk_gate *to_mtk_clk_gate(struct clk_hw *hw)
 {
        return container_of(hw, struct mtk_clk_gate, hw);
 }
index cf08db6c130c9887e6bc4ed40415aa683efd9b8d..352830369e0ef0de57ff34d66024c978d2660dcc 100644 (file)
@@ -209,12 +209,14 @@ struct clk * __init mtk_clk_register_composite(const struct mtk_composite *mc,
                mc->flags);
 
        if (IS_ERR(clk)) {
-               kfree(gate);
-               kfree(mux);
+               ret = PTR_ERR(clk);
+               goto err_out;
        }
 
        return clk;
 err_out:
+       kfree(div);
+       kfree(gate);
        kfree(mux);
 
        return ERR_PTR(ret);
index c83ae1367abc1791618b858fe3544211c12dfaaf..d920d410b51d2fb586c26a41fb989b68836d9751 100644 (file)
@@ -198,7 +198,7 @@ meson_clk_register_fixed_rate(const struct clk_conf *clk_conf,
 }
 
 void __init meson_clk_register_clks(const struct clk_conf *clk_confs,
-                                   size_t nr_confs,
+                                   unsigned int nr_confs,
                                    void __iomem *clk_base)
 {
        unsigned int i;
index 28aac67e7b92b0c668fee1d2d7c637a708141cef..daa6ebdac13112fbd50ee7bcfe4a6cf665b8bf67 100644 (file)
@@ -199,8 +199,6 @@ struct clk_gating_ctrl {
        u32 saved_reg;
 };
 
-#define to_clk_gate(_hw) container_of(_hw, struct clk_gate, hw)
-
 static struct clk_gating_ctrl *ctrl;
 
 static struct clk *clk_gating_get_src(
index d5c5bfa35a5aef734a47e6d199c410eebe237d75..3e0b52daa35f8814a413ccfe7599ac80a3f59e8f 100644 (file)
@@ -247,7 +247,7 @@ static struct clk_onecell_data dove_divider_data = {
 
 void __init dove_divider_clk_init(struct device_node *np)
 {
-       void *base;
+       void __iomem *base;
 
        base = of_iomap(np, 0);
        if (WARN_ON(!base))
index 99550f25975ea74b8963bb77910b5cf1614f3594..a2a8d614039da91a1b3f99272aa98e5952b79037 100644 (file)
@@ -256,8 +256,6 @@ static const struct clk_muxing_soc_desc kirkwood_mux_desc[] __initconst = {
                11, 1, 0 },
 };
 
-#define to_clk_mux(_hw) container_of(_hw, struct clk_mux, hw)
-
 static struct clk *clk_muxing_get_src(
        struct of_phandle_args *clkspec, void *data)
 {
index 049ee27d5a22e680fad65c689a69813086d157e8..f75e989c578ffca5ce8474262a60b9809e13fd7f 100644 (file)
@@ -33,7 +33,7 @@ struct clk_div {
 
 static inline struct clk_div *to_clk_div(struct clk_hw *hw)
 {
-       struct clk_divider *divider = container_of(hw, struct clk_divider, hw);
+       struct clk_divider *divider = to_clk_divider(hw);
 
        return container_of(divider, struct clk_div, divider);
 }
index 13aabbb3acbec3ff91d1fd478f097cd3014bfd8d..f7136b94fd0ea51f8b877e6403f076a9463263da 100644 (file)
@@ -28,8 +28,6 @@
 #define CCU_BRANCH_IS_BUS      BIT(0)
 #define CCU_BRANCH_HAVE_DIV2   BIT(1)
 
-#define to_clk_gate(_hw) container_of(_hw, struct clk_gate, hw)
-
 struct lpc18xx_branch_clk_data {
        const char **name;
        int num;
@@ -222,7 +220,7 @@ static void lpc18xx_ccu_register_branch_gate_div(struct lpc18xx_clk_branch *bran
                div->width = 1;
 
                div_hw = &div->hw;
-               div_ops = &clk_divider_ops;
+               div_ops = &clk_divider_ro_ops;
        }
 
        branch->gate.reg = branch->offset + reg_base;
index 10dd0fdaa474b2fcac7fa917d95e6fce890fba6f..48b3a11aa09a9e48bd962528eef69ae06c8c6022 100644 (file)
@@ -87,7 +87,7 @@ enum {
 
 enum {
        /* Start from the last defined clock in dt bindings */
-       LPC32XX_CLK_ADC_DIV = LPC32XX_CLK_ADC + 1,
+       LPC32XX_CLK_ADC_DIV = LPC32XX_CLK_HCLK_PLL + 1,
        LPC32XX_CLK_ADC_RTC,
        LPC32XX_CLK_TEST1,
        LPC32XX_CLK_TEST2,
@@ -96,7 +96,6 @@ enum {
        LPC32XX_CLK_OSC,
        LPC32XX_CLK_SYS,
        LPC32XX_CLK_PLL397X,
-       LPC32XX_CLK_HCLK_PLL,
        LPC32XX_CLK_HCLK_DIV_PERIPH,
        LPC32XX_CLK_HCLK_DIV,
        LPC32XX_CLK_HCLK,
@@ -1515,7 +1514,7 @@ static void __init lpc32xx_clk_init(struct device_node *np)
                return;
        }
 
-       for (i = 0; i < LPC32XX_CLK_MAX; i++) {
+       for (i = 1; i < LPC32XX_CLK_MAX; i++) {
                clk[i] = lpc32xx_clk_register(i);
                if (IS_ERR(clk[i])) {
                        pr_err("failed to register %s clock: %ld\n",
@@ -1526,9 +1525,6 @@ static void __init lpc32xx_clk_init(struct device_node *np)
 
        of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
 
-       /* For 13MHz osc valid output range of PLL is from 156MHz to 266.5MHz */
-       clk_set_rate(clk[LPC32XX_CLK_HCLK_PLL], 208000000);
-
        /* Set 48MHz rate of USB PLL clock */
        clk_set_rate(clk[LPC32XX_CLK_USB_PLL], 48000000);
 
@@ -1555,7 +1551,7 @@ static void __init lpc32xx_usb_clk_init(struct device_node *np)
                return;
        }
 
-       for (i = 0; i < LPC32XX_USB_CLK_MAX; i++) {
+       for (i = 1; i < LPC32XX_USB_CLK_MAX; i++) {
                usb_clk[i] = lpc32xx_clk_register(i + LPC32XX_CLK_USB_OFFSET);
                if (IS_ERR(usb_clk[i])) {
                        pr_err("failed to register %s clock: %ld\n",
index c112ebaba70d179b1f9d99a9fc253ecf34ee6dbe..65809f1a1f2b56c2446d4fc402da9fa248fc7046 100644 (file)
@@ -213,7 +213,11 @@ int qcom_cc_really_probe(struct platform_device *pdev,
        if (ret)
                return ret;
 
-       devm_add_action(dev, qcom_cc_del_clk_provider, pdev->dev.of_node);
+       ret = devm_add_action_or_reset(dev, qcom_cc_del_clk_provider,
+                                      pdev->dev.of_node);
+
+       if (ret)
+               return ret;
 
        reset = &cc->reset;
        reset->rcdev.of_node = dev->of_node;
@@ -227,7 +231,11 @@ int qcom_cc_really_probe(struct platform_device *pdev,
        if (ret)
                return ret;
 
-       devm_add_action(dev, qcom_cc_reset_unregister, &reset->rcdev);
+       ret = devm_add_action_or_reset(dev, qcom_cc_reset_unregister,
+                                      &reset->rcdev);
+
+       if (ret)
+               return ret;
 
        if (desc->gdscs && desc->num_gdscs) {
                ret = gdsc_register(dev, desc->gdscs, desc->num_gdscs,
@@ -236,10 +244,7 @@ int qcom_cc_really_probe(struct platform_device *pdev,
                        return ret;
        }
 
-       devm_add_action(dev, qcom_cc_gdsc_unregister, dev);
-
-
-       return 0;
+       return devm_add_action_or_reset(dev, qcom_cc_gdsc_unregister, dev);
 }
 EXPORT_SYMBOL_GPL(qcom_cc_really_probe);
 
index e3bf09d7d0ef07f5672f9933dca6dd6896daff4c..899349b5aa07aa52d767c26dcbff7d540b560f2e 100644 (file)
@@ -2590,6 +2590,23 @@ static struct clk_branch gcc_mss_cfg_ahb_clk = {
        },
 };
 
+static struct clk_branch gcc_mss_q6_bimc_axi_clk = {
+       .halt_reg = 0x49004,
+       .clkr = {
+               .enable_reg = 0x49004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_mss_q6_bimc_axi_clk",
+                       .parent_names = (const char *[]){
+                               "bimc_ddr_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
 static struct clk_branch gcc_oxili_ahb_clk = {
        .halt_reg = 0x59028,
        .clkr = {
@@ -3227,6 +3244,7 @@ static struct clk_regmap *gcc_msm8916_clocks[] = {
        [GCC_ULTAUDIO_LPAIF_SEC_I2S_CLK] = &gcc_ultaudio_lpaif_sec_i2s_clk.clkr,
        [GCC_ULTAUDIO_LPAIF_AUX_I2S_CLK] = &gcc_ultaudio_lpaif_aux_i2s_clk.clkr,
        [GCC_CODEC_DIGCODEC_CLK] = &gcc_codec_digcodec_clk.clkr,
+       [GCC_MSS_Q6_BIMC_AXI_CLK] = &gcc_mss_q6_bimc_axi_clk.clkr,
 };
 
 static struct gdsc *gcc_msm8916_gdscs[] = {
index 5759d75780cf70b4d30becc7fc442dd8cad1e4d1..0703c8f08ef869638f8c2672827a1eea34e406e0 100644 (file)
@@ -133,7 +133,7 @@ PNAME(mux_spdif_p)  = { "spdif_src", "spdif_frac", "xin12m" };
 PNAME(mux_uart0_p)     = { "uart0_src", "uart0_frac", "xin24m" };
 PNAME(mux_uart1_p)     = { "uart1_src", "uart1_frac", "xin24m" };
 PNAME(mux_uart2_p)     = { "uart2_src", "uart2_frac", "xin24m" };
-PNAME(mux_mac_p)       = { "mac_pll_src", "ext_gmac" };
+PNAME(mux_mac_p)       = { "mac_pll_src", "rmii_clkin" };
 PNAME(mux_dclk_p)      = { "dclk_lcdc", "dclk_cru" };
 
 static struct rockchip_pll_clock rk3036_pll_clks[] __initdata = {
@@ -227,16 +227,16 @@ static struct rockchip_clk_branch rk3036_clk_branches[] __initdata = {
                        RK2928_CLKGATE_CON(2), 2, GFLAGS),
 
        COMPOSITE_NODIV(SCLK_TIMER0, "sclk_timer0", mux_timer_p, CLK_IGNORE_UNUSED,
-                       RK2928_CLKSEL_CON(2), 4, 1, DFLAGS,
+                       RK2928_CLKSEL_CON(2), 4, 1, MFLAGS,
                        RK2928_CLKGATE_CON(1), 0, GFLAGS),
        COMPOSITE_NODIV(SCLK_TIMER1, "sclk_timer1", mux_timer_p, CLK_IGNORE_UNUSED,
-                       RK2928_CLKSEL_CON(2), 5, 1, DFLAGS,
+                       RK2928_CLKSEL_CON(2), 5, 1, MFLAGS,
                        RK2928_CLKGATE_CON(1), 1, GFLAGS),
        COMPOSITE_NODIV(SCLK_TIMER2, "sclk_timer2", mux_timer_p, CLK_IGNORE_UNUSED,
-                       RK2928_CLKSEL_CON(2), 6, 1, DFLAGS,
+                       RK2928_CLKSEL_CON(2), 6, 1, MFLAGS,
                        RK2928_CLKGATE_CON(2), 4, GFLAGS),
        COMPOSITE_NODIV(SCLK_TIMER3, "sclk_timer3", mux_timer_p, CLK_IGNORE_UNUSED,
-                       RK2928_CLKSEL_CON(2), 7, 1, DFLAGS,
+                       RK2928_CLKSEL_CON(2), 7, 1, MFLAGS,
                        RK2928_CLKGATE_CON(2), 5, GFLAGS),
 
        MUX(0, "uart_pll_clk", mux_pll_src_apll_dpll_gpll_usb480m_p, 0,
@@ -245,11 +245,11 @@ static struct rockchip_clk_branch rk3036_clk_branches[] __initdata = {
                        RK2928_CLKSEL_CON(13), 0, 7, DFLAGS,
                        RK2928_CLKGATE_CON(1), 8, GFLAGS),
        COMPOSITE_NOMUX(0, "uart1_src", "uart_pll_clk", 0,
-                       RK2928_CLKSEL_CON(13), 0, 7, DFLAGS,
-                       RK2928_CLKGATE_CON(1), 8, GFLAGS),
+                       RK2928_CLKSEL_CON(14), 0, 7, DFLAGS,
+                       RK2928_CLKGATE_CON(1), 10, GFLAGS),
        COMPOSITE_NOMUX(0, "uart2_src", "uart_pll_clk", 0,
-                       RK2928_CLKSEL_CON(13), 0, 7, DFLAGS,
-                       RK2928_CLKGATE_CON(1), 8, GFLAGS),
+                       RK2928_CLKSEL_CON(15), 0, 7, DFLAGS,
+                       RK2928_CLKGATE_CON(1), 12, GFLAGS),
        COMPOSITE_FRACMUX(0, "uart0_frac", "uart0_src", CLK_SET_RATE_PARENT,
                        RK2928_CLKSEL_CON(17), 0,
                        RK2928_CLKGATE_CON(1), 9, GFLAGS,
@@ -284,13 +284,13 @@ static struct rockchip_clk_branch rk3036_clk_branches[] __initdata = {
                        RK2928_CLKGATE_CON(3), 2, GFLAGS),
 
        COMPOSITE_NODIV(0, "sclk_sdmmc_src", mux_mmc_src_p, 0,
-                       RK2928_CLKSEL_CON(12), 8, 2, DFLAGS,
+                       RK2928_CLKSEL_CON(12), 8, 2, MFLAGS,
                        RK2928_CLKGATE_CON(2), 11, GFLAGS),
        DIV(SCLK_SDMMC, "sclk_sdmmc", "sclk_sdmmc_src", 0,
                        RK2928_CLKSEL_CON(11), 0, 7, DFLAGS),
 
        COMPOSITE_NODIV(0, "sclk_sdio_src", mux_mmc_src_p, 0,
-                       RK2928_CLKSEL_CON(12), 10, 2, DFLAGS,
+                       RK2928_CLKSEL_CON(12), 10, 2, MFLAGS,
                        RK2928_CLKGATE_CON(2), 13, GFLAGS),
        DIV(SCLK_SDIO, "sclk_sdio", "sclk_sdio_src", 0,
                        RK2928_CLKSEL_CON(11), 8, 7, DFLAGS),
@@ -349,12 +349,12 @@ static struct rockchip_clk_branch rk3036_clk_branches[] __initdata = {
                        RK2928_CLKGATE_CON(10), 5, GFLAGS),
 
        COMPOSITE_NOGATE(0, "mac_pll_src", mux_pll_src_3plls_p, 0,
-                       RK2928_CLKSEL_CON(21), 0, 2, MFLAGS, 4, 5, DFLAGS),
+                       RK2928_CLKSEL_CON(21), 0, 2, MFLAGS, 9, 5, DFLAGS),
        MUX(SCLK_MACREF, "mac_clk_ref", mux_mac_p, CLK_SET_RATE_PARENT,
                        RK2928_CLKSEL_CON(21), 3, 1, MFLAGS),
 
        COMPOSITE_NOMUX(SCLK_MAC, "mac_clk", "mac_clk_ref", 0,
-                       RK2928_CLKSEL_CON(21), 9, 5, DFLAGS,
+                       RK2928_CLKSEL_CON(21), 4, 5, DFLAGS,
                        RK2928_CLKGATE_CON(2), 6, GFLAGS),
        FACTOR(0, "sclk_macref_out", "hclk_peri_src", 0, 1, 2),
 
index 31facd8426f754640a63b2984cf27aa7cb4d74d6..c2b0421f2076135161e49de66cf02c91ac034587 100644 (file)
@@ -782,13 +782,13 @@ static struct rockchip_clk_branch rk3368_clk_branches[] __initdata = {
        GATE(PCLK_TSADC, "pclk_tsadc", "pclk_peri", 0, RK3368_CLKGATE_CON(20), 0, GFLAGS),
 
        /* pclk_pd_alive gates */
-       GATE(PCLK_TIMER1, "pclk_timer1", "pclk_pd_alive", 0, RK3368_CLKGATE_CON(14), 8, GFLAGS),
-       GATE(PCLK_TIMER0, "pclk_timer0", "pclk_pd_alive", 0, RK3368_CLKGATE_CON(14), 7, GFLAGS),
-       GATE(0, "pclk_alive_niu", "pclk_pd_alive", CLK_IGNORE_UNUSED, RK3368_CLKGATE_CON(14), 12, GFLAGS),
-       GATE(PCLK_GRF, "pclk_grf", "pclk_pd_alive", CLK_IGNORE_UNUSED, RK3368_CLKGATE_CON(14), 11, GFLAGS),
-       GATE(PCLK_GPIO3, "pclk_gpio3", "pclk_pd_alive", 0, RK3368_CLKGATE_CON(14), 3, GFLAGS),
-       GATE(PCLK_GPIO2, "pclk_gpio2", "pclk_pd_alive", 0, RK3368_CLKGATE_CON(14), 2, GFLAGS),
-       GATE(PCLK_GPIO1, "pclk_gpio1", "pclk_pd_alive", 0, RK3368_CLKGATE_CON(14), 1, GFLAGS),
+       GATE(PCLK_TIMER1, "pclk_timer1", "pclk_pd_alive", 0, RK3368_CLKGATE_CON(22), 13, GFLAGS),
+       GATE(PCLK_TIMER0, "pclk_timer0", "pclk_pd_alive", 0, RK3368_CLKGATE_CON(22), 12, GFLAGS),
+       GATE(0, "pclk_alive_niu", "pclk_pd_alive", CLK_IGNORE_UNUSED, RK3368_CLKGATE_CON(22), 9, GFLAGS),
+       GATE(PCLK_GRF, "pclk_grf", "pclk_pd_alive", CLK_IGNORE_UNUSED, RK3368_CLKGATE_CON(22), 8, GFLAGS),
+       GATE(PCLK_GPIO3, "pclk_gpio3", "pclk_pd_alive", 0, RK3368_CLKGATE_CON(22), 3, GFLAGS),
+       GATE(PCLK_GPIO2, "pclk_gpio2", "pclk_pd_alive", 0, RK3368_CLKGATE_CON(22), 2, GFLAGS),
+       GATE(PCLK_GPIO1, "pclk_gpio1", "pclk_pd_alive", 0, RK3368_CLKGATE_CON(22), 1, GFLAGS),
 
        /*
         * pclk_vio gates
@@ -798,12 +798,12 @@ static struct rockchip_clk_branch rk3368_clk_branches[] __initdata = {
        GATE(0, "pclk_dphytx", "hclk_vio", CLK_IGNORE_UNUSED, RK3368_CLKGATE_CON(14), 8, GFLAGS),
 
        /* pclk_pd_pmu gates */
-       GATE(PCLK_PMUGRF, "pclk_pmugrf", "pclk_pd_pmu", CLK_IGNORE_UNUSED, RK3368_CLKGATE_CON(17), 0, GFLAGS),
-       GATE(PCLK_GPIO0, "pclk_gpio0", "pclk_pd_pmu", 0, RK3368_CLKGATE_CON(17), 4, GFLAGS),
-       GATE(PCLK_SGRF, "pclk_sgrf", "pclk_pd_pmu", CLK_IGNORE_UNUSED, RK3368_CLKGATE_CON(17), 3, GFLAGS),
-       GATE(0, "pclk_pmu_noc", "pclk_pd_pmu", CLK_IGNORE_UNUSED, RK3368_CLKGATE_CON(17), 2, GFLAGS),
-       GATE(0, "pclk_intmem1", "pclk_pd_pmu", CLK_IGNORE_UNUSED, RK3368_CLKGATE_CON(17), 1, GFLAGS),
-       GATE(PCLK_PMU, "pclk_pmu", "pclk_pd_pmu", CLK_IGNORE_UNUSED, RK3368_CLKGATE_CON(17), 2, GFLAGS),
+       GATE(PCLK_PMUGRF, "pclk_pmugrf", "pclk_pd_pmu", CLK_IGNORE_UNUSED, RK3368_CLKGATE_CON(23), 5, GFLAGS),
+       GATE(PCLK_GPIO0, "pclk_gpio0", "pclk_pd_pmu", 0, RK3368_CLKGATE_CON(23), 4, GFLAGS),
+       GATE(PCLK_SGRF, "pclk_sgrf", "pclk_pd_pmu", CLK_IGNORE_UNUSED, RK3368_CLKGATE_CON(23), 3, GFLAGS),
+       GATE(0, "pclk_pmu_noc", "pclk_pd_pmu", CLK_IGNORE_UNUSED, RK3368_CLKGATE_CON(23), 2, GFLAGS),
+       GATE(0, "pclk_intmem1", "pclk_pd_pmu", CLK_IGNORE_UNUSED, RK3368_CLKGATE_CON(23), 1, GFLAGS),
+       GATE(PCLK_PMU, "pclk_pmu", "pclk_pd_pmu", CLK_IGNORE_UNUSED, RK3368_CLKGATE_CON(23), 0, GFLAGS),
 
        /* timer gates */
        GATE(0, "sclk_timer15", "xin24m", CLK_IGNORE_UNUSED, RK3368_CLKGATE_CON(24), 11, GFLAGS),
index ab505247887013d8b5eac570c996e96627165f26..ec06350c78c4808c7dc6a849f157428402cccf0f 100644 (file)
@@ -90,7 +90,9 @@ static struct clk *rockchip_clk_register_branch(const char *name,
                div->width = div_width;
                div->lock = lock;
                div->table = div_table;
-               div_ops = &clk_divider_ops;
+               div_ops = (div_flags & CLK_DIVIDER_READ_ONLY)
+                                               ? &clk_divider_ro_ops
+                                               : &clk_divider_ops;
        }
 
        clk = clk_register_composite(NULL, name, parent_names, num_parents,
index 84196ecdaa12f5df319f6fafe2e9b6bd664bc9d5..b3fe5cb01afe2d2db031e9e8692161fe171bc93c 100644 (file)
@@ -1,6 +1,5 @@
 config COMMON_CLK_SAMSUNG
        bool
-       select COMMON_CLK
 
 config S3C2410_COMMON_CLK
        bool
index 402d630bd531ecf65ee15ba3f70966afe33cb8e7..35fabe1a32c30e4b400a77205c892f150b3f5f7c 100644 (file)
@@ -74,7 +74,7 @@ static struct clk_ops clk_pll_ops = {
        .get_parent = clk_pll_get_parent,
 };
 
-static struct __init clk * __socfpga_pll_init(struct device_node *node,
+static struct clk * __init __socfpga_pll_init(struct device_node *node,
        const struct clk_ops *ops)
 {
        u32 reg;
index ccb324d97160d7756dd8e187633091c4e67064ce..dec4eaaecc0006c24aadac0a969e050505bb141c 100644 (file)
@@ -574,12 +574,16 @@ static int quadfs_pll_fs660c32_set_rate(struct clk_hw *hw, unsigned long rate,
        struct stm_fs params;
        long hwrate = 0;
        unsigned long flags = 0;
+       int ret;
 
        if (!rate || !parent_rate)
                return -EINVAL;
 
-       if (!clk_fs660c32_vco_get_params(parent_rate, rate, &params))
-               clk_fs660c32_vco_get_rate(parent_rate, &params, &hwrate);
+       ret = clk_fs660c32_vco_get_params(parent_rate, rate, &params);
+       if (ret)
+               return ret;
+
+       clk_fs660c32_vco_get_rate(parent_rate, &params, &hwrate);
 
        pr_debug("%s: %s new rate %ld [ndiv=0x%x]\n",
                 __func__, clk_hw_get_name(hw),
index 5dc5ce21796065df6739d4e395a35ce5c50375b2..0d9a74b66ea3d7fb2b76cc7843ba5ddc0573bddc 100644 (file)
@@ -822,11 +822,10 @@ err:
                if (!clk_data->clks[i])
                        continue;
 
-               composite = container_of(__clk_get_hw(clk_data->clks[i]),
-                                        struct clk_composite, hw);
-               kfree(container_of(composite->gate_hw, struct clk_gate, hw));
-               kfree(container_of(composite->rate_hw, struct clk_divider, hw));
-               kfree(container_of(composite->mux_hw, struct clk_mux, hw));
+               composite = to_clk_composite(__clk_get_hw(clk_data->clks[i]));
+               kfree(to_clk_gate(composite->gate_hw));
+               kfree(to_clk_divider(composite->rate_hw));
+               kfree(to_clk_mux(composite->mux_hw));
        }
 
        kfree(clk_data->clks);
index dbef218fe5ecd3ad64319700ac1b142d9c42a89c..43345c417815473f9160ef94ca599357fa3d6841 100644 (file)
@@ -28,8 +28,6 @@
 #undef pr_fmt
 #define pr_fmt(fmt) "%s: " fmt, __func__
 
-#define to_clk_divider(_hw) container_of(_hw, struct clk_divider, hw)
-
 static unsigned long ti_composite_recalc_rate(struct clk_hw *hw,
                                              unsigned long parent_rate)
 {
index df2558350fc1d6be681d818c361339acd2afaba3..b4e5de16e561e05a3d2e9ff41d38beb52f48555f 100644 (file)
@@ -26,8 +26,6 @@
 #undef pr_fmt
 #define pr_fmt(fmt) "%s: " fmt, __func__
 
-#define to_clk_divider(_hw) container_of(_hw, struct clk_divider, hw)
-
 #define div_mask(d)    ((1 << ((d)->width)) - 1)
 
 static unsigned int _get_table_maxdiv(const struct clk_div_table *table)
index 5429d35343639632a821548ef7837ccacd172a31..bc05f276f32b90039a0eed1879d7a1201930ea97 100644 (file)
@@ -24,8 +24,6 @@
 
 #include "clock.h"
 
-#define to_clk_divider(_hw) container_of(_hw, struct clk_divider, hw)
-
 #undef pr_fmt
 #define pr_fmt(fmt) "%s: " fmt, __func__
 
index dab9ba88b9d6d2b1b97e2472694bbb588997d8de..618ded96ace36ba47a32e2b00bf9be053431fb0b 100644 (file)
@@ -26,8 +26,6 @@
 #undef pr_fmt
 #define pr_fmt(fmt) "%s: " fmt, __func__
 
-#define to_clk_mux(_hw) container_of(_hw, struct clk_mux, hw)
-
 static u8 ti_clk_mux_get_parent(struct clk_hw *hw)
 {
        struct clk_mux *mux = to_clk_mux(hw);
index e62f8cb2c9b53ec4f22811549878ad844e24b612..3bca438ecd19dabbc3df761dedb81c96a463b449 100644 (file)
@@ -78,6 +78,9 @@ static int vco_set(struct clk_icst *icst, struct icst_vco vco)
        ret = regmap_read(icst->map, icst->vcoreg_off, &val);
        if (ret)
                return ret;
+
+       /* Mask the 18 bits used by the VCO */
+       val &= ~0x7ffff;
        val |= vco.v | (vco.r << 9) | (vco.s << 16);
 
        /* This magic unlocks the VCO so it can be controlled */
index 32fbc475087ad933452fcc96948544332be8a470..62ac5d782a000305aa23bc24cc3560771793fae9 100644 (file)
 #define BCM_CYGNUS_ASIU_ADC_CLK       1
 #define BCM_CYGNUS_ASIU_PWM_CLK       2
 
+/* AUDIO clock ID */
+#define BCM_CYGNUS_AUDIOPLL           0
+#define BCM_CYGNUS_AUDIOPLL_CH0       1
+#define BCM_CYGNUS_AUDIOPLL_CH1       2
+#define BCM_CYGNUS_AUDIOPLL_CH2       3
+
 #endif /* _CLOCK_BCM_CYGNUS_H */
index bcb1c9a7351958bb8ba1c76be27dffeb32bd23a0..d41b6fea145079d0da22a5d195ab7f001e7335a7 100644 (file)
@@ -47,6 +47,7 @@
 #define LPC32XX_CLK_PWM1       32
 #define LPC32XX_CLK_PWM2       33
 #define LPC32XX_CLK_ADC                34
+#define LPC32XX_CLK_HCLK_PLL   35
 
 /* LPC32XX USB clocks */
 #define LPC32XX_USB_CLK_I2C    1
index 257e2fbedd9466ff19d25169e394a847a5e5755b..28a27a4ed3c3c27e03dc04bfa13f03ee16d00d47 100644 (file)
 #define GCC_ULTAUDIO_LPAIF_SEC_I2S_CLK         157
 #define GCC_ULTAUDIO_LPAIF_AUX_I2S_CLK         158
 #define GCC_CODEC_DIGCODEC_CLK                 159
+#define GCC_MSS_Q6_BIMC_AXI_CLK                        160
 
 /* Indexes for GDSCs */
 #define BIMC_GDSC                              0
index 1143e38555a40e893fb96da2fa1a48f53db50cbf..fce7f027f8a77a15aacc6892d08c9509defeab19 100644 (file)
@@ -25,7 +25,7 @@
 #define CLK_SET_PARENT_GATE    BIT(1) /* must be gated across re-parent */
 #define CLK_SET_RATE_PARENT    BIT(2) /* propagate rate change up one level */
 #define CLK_IGNORE_UNUSED      BIT(3) /* do not gate even if unused */
-#define CLK_IS_ROOT            BIT(4) /* root clk, has no parent */
+#define CLK_IS_ROOT            BIT(4) /* Deprecated: Don't use */
 #define CLK_IS_BASIC           BIT(5) /* Basic clk, can't do a to_clk_foo() */
 #define CLK_GET_RATE_NOCACHE   BIT(6) /* do not use the cached clk rate */
 #define CLK_SET_RATE_NO_REPARENT BIT(7) /* don't re-parent on rate change */
@@ -276,6 +276,8 @@ struct clk_fixed_rate {
        u8              flags;
 };
 
+#define to_clk_fixed_rate(_hw) container_of(_hw, struct clk_fixed_rate, hw)
+
 extern const struct clk_ops clk_fixed_rate_ops;
 struct clk *clk_register_fixed_rate(struct device *dev, const char *name,
                const char *parent_name, unsigned long flags,
@@ -283,7 +285,7 @@ struct clk *clk_register_fixed_rate(struct device *dev, const char *name,
 struct clk *clk_register_fixed_rate_with_accuracy(struct device *dev,
                const char *name, const char *parent_name, unsigned long flags,
                unsigned long fixed_rate, unsigned long fixed_accuracy);
-
+void clk_unregister_fixed_rate(struct clk *clk);
 void of_fixed_clk_setup(struct device_node *np);
 
 /**
@@ -314,6 +316,8 @@ struct clk_gate {
        spinlock_t      *lock;
 };
 
+#define to_clk_gate(_hw) container_of(_hw, struct clk_gate, hw)
+
 #define CLK_GATE_SET_TO_DISABLE                BIT(0)
 #define CLK_GATE_HIWORD_MASK           BIT(1)
 
@@ -376,6 +380,8 @@ struct clk_divider {
        spinlock_t      *lock;
 };
 
+#define to_clk_divider(_hw) container_of(_hw, struct clk_divider, hw)
+
 #define CLK_DIVIDER_ONE_BASED          BIT(0)
 #define CLK_DIVIDER_POWER_OF_TWO       BIT(1)
 #define CLK_DIVIDER_ALLOW_ZERO         BIT(2)
@@ -385,6 +391,7 @@ struct clk_divider {
 #define CLK_DIVIDER_MAX_AT_ZERO                BIT(6)
 
 extern const struct clk_ops clk_divider_ops;
+extern const struct clk_ops clk_divider_ro_ops;
 
 unsigned long divider_recalc_rate(struct clk_hw *hw, unsigned long parent_rate,
                unsigned int val, const struct clk_div_table *table,
@@ -440,6 +447,8 @@ struct clk_mux {
        spinlock_t      *lock;
 };
 
+#define to_clk_mux(_hw) container_of(_hw, struct clk_mux, hw)
+
 #define CLK_MUX_INDEX_ONE              BIT(0)
 #define CLK_MUX_INDEX_BIT              BIT(1)
 #define CLK_MUX_HIWORD_MASK            BIT(2)
@@ -483,10 +492,13 @@ struct clk_fixed_factor {
        unsigned int    div;
 };
 
+#define to_clk_fixed_factor(_hw) container_of(_hw, struct clk_fixed_factor, hw)
+
 extern const struct clk_ops clk_fixed_factor_ops;
 struct clk *clk_register_fixed_factor(struct device *dev, const char *name,
                const char *parent_name, unsigned long flags,
                unsigned int mult, unsigned int div);
+void clk_unregister_fixed_factor(struct clk *clk);
 
 /**
  * struct clk_fractional_divider - adjustable fractional divider clock
@@ -514,6 +526,8 @@ struct clk_fractional_divider {
        spinlock_t      *lock;
 };
 
+#define to_clk_fd(_hw) container_of(_hw, struct clk_fractional_divider, hw)
+
 extern const struct clk_ops clk_fractional_divider_ops;
 struct clk *clk_register_fractional_divider(struct device *dev,
                const char *name, const char *parent_name, unsigned long flags,
@@ -550,6 +564,8 @@ struct clk_multiplier {
        spinlock_t      *lock;
 };
 
+#define to_clk_multiplier(_hw) container_of(_hw, struct clk_multiplier, hw)
+
 #define CLK_MULTIPLIER_ZERO_BYPASS             BIT(0)
 #define CLK_MULTIPLIER_ROUND_CLOSEST   BIT(1)
 
@@ -579,6 +595,8 @@ struct clk_composite {
        const struct clk_ops    *gate_ops;
 };
 
+#define to_clk_composite(_hw) container_of(_hw, struct clk_composite, hw)
+
 struct clk *clk_register_composite(struct device *dev, const char *name,
                const char * const *parent_names, int num_parents,
                struct clk_hw *mux_hw, const struct clk_ops *mux_ops,
@@ -601,13 +619,13 @@ struct clk_gpio {
        struct gpio_desc *gpiod;
 };
 
+#define to_clk_gpio(_hw) container_of(_hw, struct clk_gpio, hw)
+
 extern const struct clk_ops clk_gpio_gate_ops;
 struct clk *clk_register_gpio_gate(struct device *dev, const char *name,
                const char *parent_name, unsigned gpio, bool active_low,
                unsigned long flags);
 
-void of_gpio_clk_gate_setup(struct device_node *node);
-
 /**
  * struct clk_gpio_mux - gpio controlled clock multiplexer
  *
@@ -623,8 +641,6 @@ struct clk *clk_register_gpio_mux(struct device *dev, const char *name,
                const char * const *parent_names, u8 num_parents, unsigned gpio,
                bool active_low, unsigned long flags);
 
-void of_gpio_mux_clk_setup(struct device_node *node);
-
 /**
  * clk_register - allocate a new clock, register it and return an opaque cookie
  * @dev: device that is registering this clock
index 6c1a8ce77e3b391396939a7e7663c7bc21745608..deb861960c6f06502546d35e95420cc773243702 100644 (file)
@@ -682,6 +682,18 @@ void __iomem *devm_ioremap_resource(struct device *dev, struct resource *res);
 int devm_add_action(struct device *dev, void (*action)(void *), void *data);
 void devm_remove_action(struct device *dev, void (*action)(void *), void *data);
 
+static inline int devm_add_action_or_reset(struct device *dev,
+                                          void (*action)(void *), void *data)
+{
+       int ret;
+
+       ret = devm_add_action(dev, action, data);
+       if (ret)
+               action(data);
+
+       return ret;
+}
+
 struct device_dma_parameters {
        /*
         * a low level driver may set these to teach IOMMU code about