Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4e3c021f authored by Krzysztof Kozlowski's avatar Krzysztof Kozlowski Committed by Michael Turquette
Browse files

clk: Add clk_unregister_{divider, gate, mux} to close memory leak



The common clk_register_{divider,gate,mux} functions allocated memory
for internal data which wasn't freed anywhere. Drivers using these
helpers could only unregister clocks but the memory would still leak.

Add corresponding unregister functions which will release all resources.

Signed-off-by: default avatarKrzysztof Kozlowski <k.kozlowski@samsung.com>
Reviewed-by: default avatarStephen Boyd <sboyd@codeaurora.org>
Signed-off-by: default avatarMichael Turquette <mturquette@linaro.org>
parent 0c7665c3
Loading
Loading
Loading
Loading
+16 −0
Original line number Original line Diff line number Diff line
@@ -463,3 +463,19 @@ struct clk *clk_register_divider_table(struct device *dev, const char *name,
			width, clk_divider_flags, table, lock);
			width, clk_divider_flags, table, lock);
}
}
EXPORT_SYMBOL_GPL(clk_register_divider_table);
EXPORT_SYMBOL_GPL(clk_register_divider_table);

void clk_unregister_divider(struct clk *clk)
{
	struct clk_divider *div;
	struct clk_hw *hw;

	hw = __clk_get_hw(clk);
	if (!hw)
		return;

	div = to_clk_divider(hw);

	clk_unregister(clk);
	kfree(div);
}
EXPORT_SYMBOL_GPL(clk_unregister_divider);
+16 −0
Original line number Original line Diff line number Diff line
@@ -162,3 +162,19 @@ struct clk *clk_register_gate(struct device *dev, const char *name,
	return clk;
	return clk;
}
}
EXPORT_SYMBOL_GPL(clk_register_gate);
EXPORT_SYMBOL_GPL(clk_register_gate);

void clk_unregister_gate(struct clk *clk)
{
	struct clk_gate *gate;
	struct clk_hw *hw;

	hw = __clk_get_hw(clk);
	if (!hw)
		return;

	gate = to_clk_gate(hw);

	clk_unregister(clk);
	kfree(gate);
}
EXPORT_SYMBOL_GPL(clk_unregister_gate);
+16 −0
Original line number Original line Diff line number Diff line
@@ -177,3 +177,19 @@ struct clk *clk_register_mux(struct device *dev, const char *name,
				      NULL, lock);
				      NULL, lock);
}
}
EXPORT_SYMBOL_GPL(clk_register_mux);
EXPORT_SYMBOL_GPL(clk_register_mux);

void clk_unregister_mux(struct clk *clk)
{
	struct clk_mux *mux;
	struct clk_hw *hw;

	hw = __clk_get_hw(clk);
	if (!hw)
		return;

	mux = to_clk_mux(hw);

	clk_unregister(clk);
	kfree(mux);
}
EXPORT_SYMBOL_GPL(clk_unregister_mux);
+4 −0
Original line number Original line Diff line number Diff line
@@ -294,6 +294,7 @@ struct clk *clk_register_gate(struct device *dev, const char *name,
		const char *parent_name, unsigned long flags,
		const char *parent_name, unsigned long flags,
		void __iomem *reg, u8 bit_idx,
		void __iomem *reg, u8 bit_idx,
		u8 clk_gate_flags, spinlock_t *lock);
		u8 clk_gate_flags, spinlock_t *lock);
void clk_unregister_gate(struct clk *clk);


struct clk_div_table {
struct clk_div_table {
	unsigned int	val;
	unsigned int	val;
@@ -361,6 +362,7 @@ struct clk *clk_register_divider_table(struct device *dev, const char *name,
		void __iomem *reg, u8 shift, u8 width,
		void __iomem *reg, u8 shift, u8 width,
		u8 clk_divider_flags, const struct clk_div_table *table,
		u8 clk_divider_flags, const struct clk_div_table *table,
		spinlock_t *lock);
		spinlock_t *lock);
void clk_unregister_divider(struct clk *clk);


/**
/**
 * struct clk_mux - multiplexer clock
 * struct clk_mux - multiplexer clock
@@ -411,6 +413,8 @@ struct clk *clk_register_mux_table(struct device *dev, const char *name,
		void __iomem *reg, u8 shift, u32 mask,
		void __iomem *reg, u8 shift, u32 mask,
		u8 clk_mux_flags, u32 *table, spinlock_t *lock);
		u8 clk_mux_flags, u32 *table, spinlock_t *lock);


void clk_unregister_mux(struct clk *clk);

void of_fixed_factor_clk_setup(struct device_node *node);
void of_fixed_factor_clk_setup(struct device_node *node);


/**
/**