Commit 958879d0 authored by Stephen Boyd's avatar Stephen Boyd
Browse files

Merge tag 'clk-imx-5.11' of...

Merge tag 'clk-imx-5.11' of git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux into clk-imx

Pull i.MX clk driver updates from Shawn Guo:

 - A series from Abel Vesa to improve clk-gate2 driver and make it more
   flexible.
 - A patch set from Dong Aisheng to add a new two cells binding for SCU
   clocks, so that IMX SCU based platforms like MX8QM and MX8QXP can be
   supported with SS (Subsystems).
 - Drop of_match_ptr from of_device_id table for i.MX8 clock drivers, as
   they can only be probed from device tree.
 - Other small cosmetic changes.

* tag 'clk-imx-5.11' of git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux: (24 commits)
  clk: imx: scu: remove the calling of device_is_bound
  clk: imx: scu: Make pd_np with static keyword
  clk: imx8mq: drop of_match_ptr from of_device_id table
  clk: imx8mp: drop of_match_ptr from of_device_id table
  clk: imx8mn: drop of_match_ptr from of_device_id table
  clk: imx8mm: drop of_match_ptr from of_device_id table
  clk: imx: gate2: Remove unused variable ret
  clk: imx: gate2: Add locking in is_enabled op
  clk: imx: gate2: Add cgr_mask for more flexible number of control bits
  clk: imx: gate2: Check if clock is enabled against cgr_val
  clk: imx: gate2: Keep the register writing in on place
  clk: imx: gate2: Remove the IMX_CLK_GATE2_SINGLE_BIT special case
  clk: imx: scu: fix build break when compiled as modules
  clk: imx: remove redundant assignment to pointer np
  clk: imx: remove unneeded semicolon
  clk: imx: lpcg: add suspend/resume support
  clk: imx: clk-imx8qxp-lpcg: add runtime pm support
  clk: imx: lpcg: allow lpcg clk to take device pointer
  clk: imx: imx8qxp-lpcg: add parsing clocks from device tree
  clk: imx: scu: add suspend/resume support
  ...
parents 3650b228 43d24796
Loading
Loading
Loading
Loading
+32 −36
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ struct clk_gate2 {
	void __iomem	*reg;
	u8		bit_idx;
	u8		cgr_val;
	u8		cgr_mask;
	u8		flags;
	spinlock_t	*lock;
	unsigned int	*share_count;
@@ -37,37 +38,38 @@ struct clk_gate2 {

#define to_clk_gate2(_hw) container_of(_hw, struct clk_gate2, hw)

static int clk_gate2_enable(struct clk_hw *hw)
static void clk_gate2_do_shared_clks(struct clk_hw *hw, bool enable)
{
	struct clk_gate2 *gate = to_clk_gate2(hw);
	u32 reg;

	reg = readl(gate->reg);
	reg &= ~(gate->cgr_mask << gate->bit_idx);
	if (enable)
		reg |= (gate->cgr_val & gate->cgr_mask) << gate->bit_idx;
	writel(reg, gate->reg);
}

static int clk_gate2_enable(struct clk_hw *hw)
{
	struct clk_gate2 *gate = to_clk_gate2(hw);
	unsigned long flags;
	int ret = 0;

	spin_lock_irqsave(gate->lock, flags);

	if (gate->share_count && (*gate->share_count)++ > 0)
		goto out;

	if (gate->flags & IMX_CLK_GATE2_SINGLE_BIT) {
		ret = clk_gate_ops.enable(hw);
	} else {
		reg = readl(gate->reg);
		reg &= ~(3 << gate->bit_idx);
		reg |= gate->cgr_val << gate->bit_idx;
		writel(reg, gate->reg);
	}

	clk_gate2_do_shared_clks(hw, true);
out:
	spin_unlock_irqrestore(gate->lock, flags);

	return ret;
	return 0;
}

static void clk_gate2_disable(struct clk_hw *hw)
{
	struct clk_gate2 *gate = to_clk_gate2(hw);
	u32 reg;
	unsigned long flags;

	spin_lock_irqsave(gate->lock, flags);
@@ -79,23 +81,17 @@ static void clk_gate2_disable(struct clk_hw *hw)
			goto out;
	}

	if (gate->flags & IMX_CLK_GATE2_SINGLE_BIT) {
		clk_gate_ops.disable(hw);
	} else {
		reg = readl(gate->reg);
		reg &= ~(3 << gate->bit_idx);
		writel(reg, gate->reg);
	}

	clk_gate2_do_shared_clks(hw, false);
out:
	spin_unlock_irqrestore(gate->lock, flags);
}

static int clk_gate2_reg_is_enabled(void __iomem *reg, u8 bit_idx)
static int clk_gate2_reg_is_enabled(void __iomem *reg, u8 bit_idx,
					u8 cgr_val, u8 cgr_mask)
{
	u32 val = readl(reg);

	if (((val >> bit_idx) & 1) == 1)
	if (((val >> bit_idx) & cgr_mask) == cgr_val)
		return 1;

	return 0;
@@ -104,29 +100,28 @@ static int clk_gate2_reg_is_enabled(void __iomem *reg, u8 bit_idx)
static int clk_gate2_is_enabled(struct clk_hw *hw)
{
	struct clk_gate2 *gate = to_clk_gate2(hw);
	unsigned long flags;
	int ret = 0;

	spin_lock_irqsave(gate->lock, flags);

	if (gate->flags & IMX_CLK_GATE2_SINGLE_BIT)
		return clk_gate_ops.is_enabled(hw);
	ret = clk_gate2_reg_is_enabled(gate->reg, gate->bit_idx,
					gate->cgr_val, gate->cgr_mask);

	return clk_gate2_reg_is_enabled(gate->reg, gate->bit_idx);
	spin_unlock_irqrestore(gate->lock, flags);

	return ret;
}

static void clk_gate2_disable_unused(struct clk_hw *hw)
{
	struct clk_gate2 *gate = to_clk_gate2(hw);
	unsigned long flags;
	u32 reg;

	if (gate->flags & IMX_CLK_GATE2_SINGLE_BIT)
		return;

	spin_lock_irqsave(gate->lock, flags);

	if (!gate->share_count || *gate->share_count == 0) {
		reg = readl(gate->reg);
		reg &= ~(3 << gate->bit_idx);
		writel(reg, gate->reg);
	}
	if (!gate->share_count || *gate->share_count == 0)
		clk_gate2_do_shared_clks(hw, false);

	spin_unlock_irqrestore(gate->lock, flags);
}
@@ -140,7 +135,7 @@ static const struct clk_ops clk_gate2_ops = {

struct clk_hw *clk_hw_register_gate2(struct device *dev, const char *name,
		const char *parent_name, unsigned long flags,
		void __iomem *reg, u8 bit_idx, u8 cgr_val,
		void __iomem *reg, u8 bit_idx, u8 cgr_val, u8 cgr_mask,
		u8 clk_gate2_flags, spinlock_t *lock,
		unsigned int *share_count)
{
@@ -157,6 +152,7 @@ struct clk_hw *clk_hw_register_gate2(struct device *dev, const char *name,
	gate->reg = reg;
	gate->bit_idx = bit_idx;
	gate->cgr_val = cgr_val;
	gate->cgr_mask = cgr_mask;
	gate->flags = clk_gate2_flags;
	gate->lock = lock;
	gate->share_count = share_count;
+1 −1
Original line number Diff line number Diff line
@@ -653,7 +653,7 @@ static struct platform_driver imx8mm_clk_driver = {
		 * reloading the driver will crash or break devices.
		 */
		.suppress_bind_attrs = true,
		.of_match_table = of_match_ptr(imx8mm_clk_of_match),
		.of_match_table = imx8mm_clk_of_match,
	},
};
module_platform_driver(imx8mm_clk_driver);
+1 −1
Original line number Diff line number Diff line
@@ -604,7 +604,7 @@ static struct platform_driver imx8mn_clk_driver = {
		 * reloading the driver will crash or break devices.
		 */
		.suppress_bind_attrs = true,
		.of_match_table = of_match_ptr(imx8mn_clk_of_match),
		.of_match_table = imx8mn_clk_of_match,
	},
};
module_platform_driver(imx8mn_clk_driver);
+2 −2
Original line number Diff line number Diff line
@@ -425,7 +425,7 @@ static struct clk **uart_clks[ARRAY_SIZE(uart_clk_ids) + 1];
static int imx8mp_clocks_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct device_node *np = dev->of_node;
	struct device_node *np;
	void __iomem *anatop_base, *ccm_base;
	int i;

@@ -763,7 +763,7 @@ static struct platform_driver imx8mp_clk_driver = {
		 * reloading the driver will crash or break devices.
		 */
		.suppress_bind_attrs = true,
		.of_match_table = of_match_ptr(imx8mp_clk_of_match),
		.of_match_table = imx8mp_clk_of_match,
	},
};
module_platform_driver(imx8mp_clk_driver);
+1 −1
Original line number Diff line number Diff line
@@ -639,7 +639,7 @@ static struct platform_driver imx8mq_clk_driver = {
		 * reloading the driver will crash or break devices.
		 */
		.suppress_bind_attrs = true,
		.of_match_table = of_match_ptr(imx8mq_clk_of_match),
		.of_match_table = imx8mq_clk_of_match,
	},
};
module_platform_driver(imx8mq_clk_driver);
Loading