Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2)  * SCI Clock driver for keystone based devices
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * Copyright (C) 2015-2016 Texas Instruments Incorporated - https://www.ti.com/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  *	Tero Kristo <t-kristo@ti.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * This program is free software; you can redistribute it and/or modify
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  * it under the terms of the GNU General Public License version 2 as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  * published by the Free Software Foundation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  * This program is distributed "as is" WITHOUT ANY WARRANTY of any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  * kind, whether express or implied; without even the implied warranty
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13)  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14)  * GNU General Public License for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/clk-provider.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <linux/of_address.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include <linux/of_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #include <linux/soc/ti/ti_sci_protocol.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #include <linux/bsearch.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #include <linux/list_sort.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #define SCI_CLK_SSC_ENABLE		BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) #define SCI_CLK_ALLOW_FREQ_CHANGE	BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) #define SCI_CLK_INPUT_TERMINATION	BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33)  * struct sci_clk_provider - TI SCI clock provider representation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34)  * @sci: Handle to the System Control Interface protocol handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35)  * @ops: Pointer to the SCI ops to be used by the clocks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36)  * @dev: Device pointer for the clock provider
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37)  * @clocks: Clocks array for this device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38)  * @num_clocks: Total number of clocks for this provider
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) struct sci_clk_provider {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 	const struct ti_sci_handle *sci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	const struct ti_sci_clk_ops *ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	struct sci_clk **clocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	int num_clocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49)  * struct sci_clk - TI SCI clock representation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50)  * @hw:		 Hardware clock cookie for common clock framework
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51)  * @dev_id:	 Device index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52)  * @clk_id:	 Clock index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53)  * @num_parents: Number of parents for this clock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54)  * @provider:	 Master clock provider
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55)  * @flags:	 Flags for the clock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56)  * @node:	 Link for handling clocks probed via DT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57)  * @cached_req:	 Cached requested freq for determine rate calls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58)  * @cached_res:	 Cached result freq for determine rate calls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) struct sci_clk {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	struct clk_hw hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	u16 dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	u32 clk_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	u32 num_parents;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	struct sci_clk_provider *provider;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	u8 flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	struct list_head node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	unsigned long cached_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	unsigned long cached_res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) #define to_sci_clk(_hw) container_of(_hw, struct sci_clk, hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75)  * sci_clk_prepare - Prepare (enable) a TI SCI clock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76)  * @hw: clock to prepare
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78)  * Prepares a clock to be actively used. Returns the SCI protocol status.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) static int sci_clk_prepare(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	struct sci_clk *clk = to_sci_clk(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	bool enable_ssc = clk->flags & SCI_CLK_SSC_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	bool allow_freq_change = clk->flags & SCI_CLK_ALLOW_FREQ_CHANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	bool input_termination = clk->flags & SCI_CLK_INPUT_TERMINATION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	return clk->provider->ops->get_clock(clk->provider->sci, clk->dev_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 					     clk->clk_id, enable_ssc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 					     allow_freq_change,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 					     input_termination);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94)  * sci_clk_unprepare - Un-prepares (disables) a TI SCI clock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95)  * @hw: clock to unprepare
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97)  * Un-prepares a clock from active state.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) static void sci_clk_unprepare(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	struct sci_clk *clk = to_sci_clk(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	ret = clk->provider->ops->put_clock(clk->provider->sci, clk->dev_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 					    clk->clk_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 		dev_err(clk->provider->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 			"unprepare failed for dev=%d, clk=%d, ret=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 			clk->dev_id, clk->clk_id, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)  * sci_clk_is_prepared - Check if a TI SCI clock is prepared or not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)  * @hw: clock to check status for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)  * Checks if a clock is prepared (enabled) in hardware. Returns non-zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)  * value if clock is enabled, zero otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) static int sci_clk_is_prepared(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	struct sci_clk *clk = to_sci_clk(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	bool req_state, current_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	ret = clk->provider->ops->is_on(clk->provider->sci, clk->dev_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 					clk->clk_id, &req_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 					&current_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 		dev_err(clk->provider->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 			"is_prepared failed for dev=%d, clk=%d, ret=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 			clk->dev_id, clk->clk_id, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	return req_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)  * sci_clk_recalc_rate - Get clock rate for a TI SCI clock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)  * @hw: clock to get rate for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)  * @parent_rate: parent rate provided by common clock framework, not used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)  * Gets the current clock rate of a TI SCI clock. Returns the current
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)  * clock rate, or zero in failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) static unsigned long sci_clk_recalc_rate(struct clk_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 					 unsigned long parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	struct sci_clk *clk = to_sci_clk(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	u64 freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	ret = clk->provider->ops->get_freq(clk->provider->sci, clk->dev_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 					   clk->clk_id, &freq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 		dev_err(clk->provider->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 			"recalc-rate failed for dev=%d, clk=%d, ret=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 			clk->dev_id, clk->clk_id, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	return freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)  * sci_clk_determine_rate - Determines a clock rate a clock can be set to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)  * @hw: clock to change rate for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)  * @req: requested rate configuration for the clock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)  * Determines a suitable clock rate and parent for a TI SCI clock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)  * The parent handling is un-used, as generally the parent clock rates
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)  * are not known by the kernel; instead these are internally handled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)  * by the firmware. Returns 0 on success, negative error value on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) static int sci_clk_determine_rate(struct clk_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 				  struct clk_rate_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	struct sci_clk *clk = to_sci_clk(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	u64 new_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	if (clk->cached_req && clk->cached_req == req->rate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 		req->rate = clk->cached_res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	ret = clk->provider->ops->get_best_match_freq(clk->provider->sci,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 						      clk->dev_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 						      clk->clk_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 						      req->min_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 						      req->rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 						      req->max_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 						      &new_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 		dev_err(clk->provider->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 			"determine-rate failed for dev=%d, clk=%d, ret=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 			clk->dev_id, clk->clk_id, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	clk->cached_req = req->rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	clk->cached_res = new_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	req->rate = new_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)  * sci_clk_set_rate - Set rate for a TI SCI clock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)  * @hw: clock to change rate for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)  * @rate: target rate for the clock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)  * @parent_rate: rate of the clock parent, not used for TI SCI clocks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)  * Sets a clock frequency for a TI SCI clock. Returns the TI SCI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)  * protocol status.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) static int sci_clk_set_rate(struct clk_hw *hw, unsigned long rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 			    unsigned long parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 	struct sci_clk *clk = to_sci_clk(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	return clk->provider->ops->set_freq(clk->provider->sci, clk->dev_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 					    clk->clk_id, rate / 10 * 9, rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 					    rate / 10 * 11);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)  * sci_clk_get_parent - Get the current parent of a TI SCI clock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)  * @hw: clock to get parent for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)  * Returns the index of the currently selected parent for a TI SCI clock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) static u8 sci_clk_get_parent(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 	struct sci_clk *clk = to_sci_clk(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 	u32 parent_id = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 	ret = clk->provider->ops->get_parent(clk->provider->sci, clk->dev_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 					     clk->clk_id, (void *)&parent_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 		dev_err(clk->provider->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 			"get-parent failed for dev=%d, clk=%d, ret=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 			clk->dev_id, clk->clk_id, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 	parent_id = parent_id - clk->clk_id - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	return (u8)parent_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)  * sci_clk_set_parent - Set the parent of a TI SCI clock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)  * @hw: clock to set parent for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)  * @index: new parent index for the clock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)  * Sets the parent of a TI SCI clock. Return TI SCI protocol status.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) static int sci_clk_set_parent(struct clk_hw *hw, u8 index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 	struct sci_clk *clk = to_sci_clk(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 	clk->cached_req = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 	return clk->provider->ops->set_parent(clk->provider->sci, clk->dev_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 					      clk->clk_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 					      index + 1 + clk->clk_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) static const struct clk_ops sci_clk_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 	.prepare = sci_clk_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 	.unprepare = sci_clk_unprepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 	.is_prepared = sci_clk_is_prepared,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 	.recalc_rate = sci_clk_recalc_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 	.determine_rate = sci_clk_determine_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 	.set_rate = sci_clk_set_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 	.get_parent = sci_clk_get_parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 	.set_parent = sci_clk_set_parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)  * _sci_clk_get - Gets a handle for an SCI clock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)  * @provider: Handle to SCI clock provider
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)  * @sci_clk: Handle to the SCI clock to populate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)  * Gets a handle to an existing TI SCI hw clock, or builds a new clock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)  * entry and registers it with the common clock framework. Called from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)  * the common clock framework, when a corresponding of_clk_get call is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)  * executed, or recursively from itself when parsing parent clocks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)  * Returns 0 on success, negative error code on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) static int _sci_clk_build(struct sci_clk_provider *provider,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 			  struct sci_clk *sci_clk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 	struct clk_init_data init = { NULL };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 	char *name = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	char **parent_names = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 	name = kasprintf(GFP_KERNEL, "clk:%d:%d", sci_clk->dev_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 			 sci_clk->clk_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 	init.name = name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 	 * From kernel point of view, we only care about a clocks parents,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 	 * if it has more than 1 possible parent. In this case, it is going
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 	 * to have mux functionality. Otherwise it is going to act as a root
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 	 * clock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 	if (sci_clk->num_parents < 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 		sci_clk->num_parents = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 	if (sci_clk->num_parents) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 		parent_names = kcalloc(sci_clk->num_parents, sizeof(char *),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 				       GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 		if (!parent_names) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 			ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 			goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 		for (i = 0; i < sci_clk->num_parents; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 			char *parent_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 			parent_name = kasprintf(GFP_KERNEL, "clk:%d:%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 						sci_clk->dev_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 						sci_clk->clk_id + 1 + i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 			if (!parent_name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 				ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 				goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 			parent_names[i] = parent_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 		init.parent_names = (void *)parent_names;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 	init.ops = &sci_clk_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 	init.num_parents = sci_clk->num_parents;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 	sci_clk->hw.init = &init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 	ret = devm_clk_hw_register(provider->dev, &sci_clk->hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 		dev_err(provider->dev, "failed clk register with %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 	if (parent_names) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 		for (i = 0; i < sci_clk->num_parents; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 			kfree(parent_names[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 		kfree(parent_names);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 	kfree(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) static int _cmp_sci_clk(const void *a, const void *b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 	const struct sci_clk *ca = a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 	const struct sci_clk *cb = *(struct sci_clk **)b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 	if (ca->dev_id == cb->dev_id && ca->clk_id == cb->clk_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 	if (ca->dev_id > cb->dev_id ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 	    (ca->dev_id == cb->dev_id && ca->clk_id > cb->clk_id))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 	return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)  * sci_clk_get - Xlate function for getting clock handles
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)  * @clkspec: device tree clock specifier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)  * @data: pointer to the clock provider
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)  * Xlate function for retrieving clock TI SCI hw clock handles based on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)  * device tree clock specifier. Called from the common clock framework,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)  * when a corresponding of_clk_get call is executed. Returns a pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)  * to the TI SCI hw clock struct, or ERR_PTR value in failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) static struct clk_hw *sci_clk_get(struct of_phandle_args *clkspec, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 	struct sci_clk_provider *provider = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 	struct sci_clk **clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 	struct sci_clk key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 	if (clkspec->args_count != 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 		return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 	key.dev_id = clkspec->args[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 	key.clk_id = clkspec->args[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 	clk = bsearch(&key, provider->clocks, provider->num_clocks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 		      sizeof(clk), _cmp_sci_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 	if (!clk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 		return ERR_PTR(-ENODEV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 	return &(*clk)->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) static int ti_sci_init_clocks(struct sci_clk_provider *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 	for (i = 0; i < p->num_clocks; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 		ret = _sci_clk_build(p, p->clocks[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 		if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) static const struct of_device_id ti_sci_clk_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 	{ .compatible = "ti,k2g-sci-clk" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 	{ /* Sentinel */ },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) MODULE_DEVICE_TABLE(of, ti_sci_clk_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) #ifdef CONFIG_TI_SCI_CLK_PROBE_FROM_FW
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) static int ti_sci_scan_clocks_from_fw(struct sci_clk_provider *provider)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 	int num_clks = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 	struct sci_clk **clks = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 	struct sci_clk **tmp_clks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 	struct sci_clk *sci_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 	int max_clks = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 	int clk_id = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 	int dev_id = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 	u32 num_parents = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 	int gap_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 	struct device *dev = provider->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 	while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 		ret = provider->ops->get_num_parents(provider->sci, dev_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 						     clk_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 						     (void *)&num_parents);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 		if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 			gap_size++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 			if (!clk_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 				if (gap_size >= 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 				dev_id++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 				if (gap_size >= 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 					dev_id++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 					clk_id = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 					gap_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 				} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 					clk_id++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 		gap_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 		if (num_clks == max_clks) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 			tmp_clks = devm_kmalloc_array(dev, max_clks + 64,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 						      sizeof(sci_clk),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 						      GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 			memcpy(tmp_clks, clks, max_clks * sizeof(sci_clk));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 			if (max_clks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 				devm_kfree(dev, clks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 			max_clks += 64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 			clks = tmp_clks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 		sci_clk = devm_kzalloc(dev, sizeof(*sci_clk), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 		if (!sci_clk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 			return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 		sci_clk->dev_id = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 		sci_clk->clk_id = clk_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 		sci_clk->provider = provider;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 		sci_clk->num_parents = num_parents;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 		clks[num_clks] = sci_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 		clk_id++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 		num_clks++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 	provider->clocks = devm_kmalloc_array(dev, num_clks, sizeof(sci_clk),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 					      GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 	if (!provider->clocks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 	memcpy(provider->clocks, clks, num_clks * sizeof(sci_clk));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 	provider->num_clocks = num_clks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 	devm_kfree(dev, clks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) static int _cmp_sci_clk_list(void *priv, struct list_head *a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 			     struct list_head *b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 	struct sci_clk *ca = container_of(a, struct sci_clk, node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 	struct sci_clk *cb = container_of(b, struct sci_clk, node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 	return _cmp_sci_clk(ca, &cb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) static int ti_sci_scan_clocks_from_dt(struct sci_clk_provider *provider)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 	struct device *dev = provider->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 	struct device_node *np = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 	int index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 	struct of_phandle_args args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 	struct list_head clks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 	struct sci_clk *sci_clk, *prev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 	int num_clks = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 	int num_parents;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 	int clk_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 	const char * const clk_names[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 		"clocks", "assigned-clocks", "assigned-clock-parents", NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 	const char * const *clk_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 	INIT_LIST_HEAD(&clks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 	clk_name = clk_names;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 	while (*clk_name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 		np = of_find_node_with_property(np, *clk_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 		if (!np) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 			clk_name++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 		if (!of_device_is_available(np))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 		index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 		do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 			ret = of_parse_phandle_with_args(np, *clk_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 							 "#clock-cells", index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 							 &args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 			if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 			if (args.args_count == 2 && args.np == dev->of_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 				sci_clk = devm_kzalloc(dev, sizeof(*sci_clk),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 						       GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 				if (!sci_clk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 					return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 				sci_clk->dev_id = args.args[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 				sci_clk->clk_id = args.args[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 				sci_clk->provider = provider;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 				provider->ops->get_num_parents(provider->sci,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 							       sci_clk->dev_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 							       sci_clk->clk_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 							       (void *)&sci_clk->num_parents);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 				list_add_tail(&sci_clk->node, &clks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 				num_clks++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 				num_parents = sci_clk->num_parents;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 				if (num_parents == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 					num_parents = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 				/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 				 * Linux kernel has inherent limitation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 				 * of 255 clock parents at the moment.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 				 * Right now, it is not expected that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 				 * any mux clock from sci-clk driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 				 * would exceed that limit either, but
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 				 * the ABI basically provides that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 				 * possibility. Print out a warning if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 				 * this happens for any clock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 				 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) 				if (num_parents >= 255) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 					dev_warn(dev, "too many parents for dev=%d, clk=%d (%d), cropping to 255.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 						 sci_clk->dev_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 						 sci_clk->clk_id, num_parents);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 					num_parents = 255;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 				clk_id = args.args[1] + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 				while (num_parents--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) 					sci_clk = devm_kzalloc(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 							       sizeof(*sci_clk),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 							       GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 					if (!sci_clk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 						return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 					sci_clk->dev_id = args.args[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) 					sci_clk->clk_id = clk_id++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 					sci_clk->provider = provider;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 					list_add_tail(&sci_clk->node, &clks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) 					num_clks++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 			index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) 		} while (args.np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) 	list_sort(NULL, &clks, _cmp_sci_clk_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) 	provider->clocks = devm_kmalloc_array(dev, num_clks, sizeof(sci_clk),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) 					      GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) 	if (!provider->clocks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) 	num_clks = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) 	prev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) 	list_for_each_entry(sci_clk, &clks, node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) 		if (prev && prev->dev_id == sci_clk->dev_id &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) 		    prev->clk_id == sci_clk->clk_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) 		provider->clocks[num_clks++] = sci_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) 		prev = sci_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) 	provider->num_clocks = num_clks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640)  * ti_sci_clk_probe - Probe function for the TI SCI clock driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641)  * @pdev: platform device pointer to be probed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643)  * Probes the TI SCI clock device. Allocates a new clock provider
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644)  * and registers this to the common clock framework. Also applies
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645)  * any required flags to the identified clocks via clock lists
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646)  * supplied from DT. Returns 0 for success, negative error value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647)  * for failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) static int ti_sci_clk_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) 	struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) 	struct device_node *np = dev->of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) 	struct sci_clk_provider *provider;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) 	const struct ti_sci_handle *handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) 	handle = devm_ti_sci_get_handle(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) 	if (IS_ERR(handle))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) 		return PTR_ERR(handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) 	provider = devm_kzalloc(dev, sizeof(*provider), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) 	if (!provider)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) 	provider->sci = handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) 	provider->ops = &handle->ops.clk_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) 	provider->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) #ifdef CONFIG_TI_SCI_CLK_PROBE_FROM_FW
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) 	ret = ti_sci_scan_clocks_from_fw(provider);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) 		dev_err(dev, "scan clocks from FW failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) 	ret = ti_sci_scan_clocks_from_dt(provider);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) 		dev_err(dev, "scan clocks from DT failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) 	ret = ti_sci_init_clocks(provider);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) 		pr_err("ti-sci-init-clocks failed.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) 	return of_clk_add_hw_provider(np, sci_clk_get, provider);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693)  * ti_sci_clk_remove - Remove TI SCI clock device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694)  * @pdev: platform device pointer for the device to be removed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696)  * Removes the TI SCI device. Unregisters the clock provider registered
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697)  * via common clock framework. Any memory allocated for the device will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698)  * be free'd silently via the devm framework. Returns 0 always.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) static int ti_sci_clk_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) 	of_clk_del_provider(pdev->dev.of_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) static struct platform_driver ti_sci_clk_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) 	.probe = ti_sci_clk_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) 	.remove = ti_sci_clk_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) 	.driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) 		.name = "ti-sci-clk",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) 		.of_match_table = of_match_ptr(ti_sci_clk_of_match),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) module_platform_driver(ti_sci_clk_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) MODULE_LICENSE("GPL v2");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) MODULE_DESCRIPTION("TI System Control Interface(SCI) Clock driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) MODULE_AUTHOR("Tero Kristo");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) MODULE_ALIAS("platform:ti-sci-clk");