diff options
| -rw-r--r-- | Documentation/devicetree/bindings/clock/clock-bindings.txt | 16 | ||||
| -rw-r--r-- | arch/arm64/boot/dts/qcom/sdm845-mtp.dts | 6 | ||||
| -rw-r--r-- | drivers/clk/mmp/clk.c | 2 | ||||
| -rw-r--r-- | drivers/clk/mvebu/cp110-system-controller.c | 4 | ||||
| -rw-r--r-- | drivers/clk/qcom/common.c | 18 | ||||
| -rw-r--r-- | drivers/clk/zynqmp/clkc.c | 5 |
6 files changed, 47 insertions, 4 deletions
diff --git a/Documentation/devicetree/bindings/clock/clock-bindings.txt b/Documentation/devicetree/bindings/clock/clock-bindings.txt index 2ec489eebe72..b646bbcf7f92 100644 --- a/Documentation/devicetree/bindings/clock/clock-bindings.txt +++ b/Documentation/devicetree/bindings/clock/clock-bindings.txt | |||
| @@ -168,3 +168,19 @@ a shared clock is forbidden. | |||
| 168 | 168 | ||
| 169 | Configuration of common clocks, which affect multiple consumer devices can | 169 | Configuration of common clocks, which affect multiple consumer devices can |
| 170 | be similarly specified in the clock provider node. | 170 | be similarly specified in the clock provider node. |
| 171 | |||
| 172 | ==Protected clocks== | ||
| 173 | |||
| 174 | Some platforms or firmwares may not fully expose all the clocks to the OS, such | ||
| 175 | as in situations where those clks are used by drivers running in ARM secure | ||
| 176 | execution levels. Such a configuration can be specified in device tree with the | ||
| 177 | protected-clocks property in the form of a clock specifier list. This property should | ||
| 178 | only be specified in the node that is providing the clocks being protected: | ||
| 179 | |||
| 180 | clock-controller@a000f000 { | ||
| 181 | compatible = "vendor,clk95; | ||
| 182 | reg = <0xa000f000 0x1000> | ||
| 183 | #clocks-cells = <1>; | ||
| 184 | ... | ||
| 185 | protected-clocks = <UART3_CLK>, <SPI5_CLK>; | ||
| 186 | }; | ||
diff --git a/arch/arm64/boot/dts/qcom/sdm845-mtp.dts b/arch/arm64/boot/dts/qcom/sdm845-mtp.dts index d667eee4e6d0..b3def0358177 100644 --- a/arch/arm64/boot/dts/qcom/sdm845-mtp.dts +++ b/arch/arm64/boot/dts/qcom/sdm845-mtp.dts | |||
| @@ -343,6 +343,12 @@ | |||
| 343 | }; | 343 | }; |
| 344 | }; | 344 | }; |
| 345 | 345 | ||
| 346 | &gcc { | ||
| 347 | protected-clocks = <GCC_QSPI_CORE_CLK>, | ||
| 348 | <GCC_QSPI_CORE_CLK_SRC>, | ||
| 349 | <GCC_QSPI_CNOC_PERIPH_AHB_CLK>; | ||
| 350 | }; | ||
| 351 | |||
| 346 | &i2c10 { | 352 | &i2c10 { |
| 347 | status = "okay"; | 353 | status = "okay"; |
| 348 | clock-frequency = <400000>; | 354 | clock-frequency = <400000>; |
diff --git a/drivers/clk/mmp/clk.c b/drivers/clk/mmp/clk.c index ad8d483a35cd..ca7d37e2c7be 100644 --- a/drivers/clk/mmp/clk.c +++ b/drivers/clk/mmp/clk.c | |||
| @@ -183,7 +183,7 @@ void mmp_clk_add(struct mmp_clk_unit *unit, unsigned int id, | |||
| 183 | pr_err("CLK %d has invalid pointer %p\n", id, clk); | 183 | pr_err("CLK %d has invalid pointer %p\n", id, clk); |
| 184 | return; | 184 | return; |
| 185 | } | 185 | } |
| 186 | if (id > unit->nr_clks) { | 186 | if (id >= unit->nr_clks) { |
| 187 | pr_err("CLK %d is invalid\n", id); | 187 | pr_err("CLK %d is invalid\n", id); |
| 188 | return; | 188 | return; |
| 189 | } | 189 | } |
diff --git a/drivers/clk/mvebu/cp110-system-controller.c b/drivers/clk/mvebu/cp110-system-controller.c index 9781b1bf5998..9235a331b588 100644 --- a/drivers/clk/mvebu/cp110-system-controller.c +++ b/drivers/clk/mvebu/cp110-system-controller.c | |||
| @@ -200,11 +200,11 @@ static struct clk_hw *cp110_of_clk_get(struct of_phandle_args *clkspec, | |||
| 200 | unsigned int idx = clkspec->args[1]; | 200 | unsigned int idx = clkspec->args[1]; |
| 201 | 201 | ||
| 202 | if (type == CP110_CLK_TYPE_CORE) { | 202 | if (type == CP110_CLK_TYPE_CORE) { |
| 203 | if (idx > CP110_MAX_CORE_CLOCKS) | 203 | if (idx >= CP110_MAX_CORE_CLOCKS) |
| 204 | return ERR_PTR(-EINVAL); | 204 | return ERR_PTR(-EINVAL); |
| 205 | return clk_data->hws[idx]; | 205 | return clk_data->hws[idx]; |
| 206 | } else if (type == CP110_CLK_TYPE_GATABLE) { | 206 | } else if (type == CP110_CLK_TYPE_GATABLE) { |
| 207 | if (idx > CP110_MAX_GATABLE_CLOCKS) | 207 | if (idx >= CP110_MAX_GATABLE_CLOCKS) |
| 208 | return ERR_PTR(-EINVAL); | 208 | return ERR_PTR(-EINVAL); |
| 209 | return clk_data->hws[CP110_MAX_CORE_CLOCKS + idx]; | 209 | return clk_data->hws[CP110_MAX_CORE_CLOCKS + idx]; |
| 210 | } | 210 | } |
diff --git a/drivers/clk/qcom/common.c b/drivers/clk/qcom/common.c index db9b2471ac40..0a48ed56833b 100644 --- a/drivers/clk/qcom/common.c +++ b/drivers/clk/qcom/common.c | |||
| @@ -191,6 +191,22 @@ int qcom_cc_register_sleep_clk(struct device *dev) | |||
| 191 | } | 191 | } |
| 192 | EXPORT_SYMBOL_GPL(qcom_cc_register_sleep_clk); | 192 | EXPORT_SYMBOL_GPL(qcom_cc_register_sleep_clk); |
| 193 | 193 | ||
| 194 | /* Drop 'protected-clocks' from the list of clocks to register */ | ||
| 195 | static void qcom_cc_drop_protected(struct device *dev, struct qcom_cc *cc) | ||
| 196 | { | ||
| 197 | struct device_node *np = dev->of_node; | ||
| 198 | struct property *prop; | ||
| 199 | const __be32 *p; | ||
| 200 | u32 i; | ||
| 201 | |||
| 202 | of_property_for_each_u32(np, "protected-clocks", prop, p, i) { | ||
| 203 | if (i >= cc->num_rclks) | ||
| 204 | continue; | ||
| 205 | |||
| 206 | cc->rclks[i] = NULL; | ||
| 207 | } | ||
| 208 | } | ||
| 209 | |||
| 194 | static struct clk_hw *qcom_cc_clk_hw_get(struct of_phandle_args *clkspec, | 210 | static struct clk_hw *qcom_cc_clk_hw_get(struct of_phandle_args *clkspec, |
| 195 | void *data) | 211 | void *data) |
| 196 | { | 212 | { |
| @@ -251,6 +267,8 @@ int qcom_cc_really_probe(struct platform_device *pdev, | |||
| 251 | cc->rclks = rclks; | 267 | cc->rclks = rclks; |
| 252 | cc->num_rclks = num_clks; | 268 | cc->num_rclks = num_clks; |
| 253 | 269 | ||
| 270 | qcom_cc_drop_protected(dev, cc); | ||
| 271 | |||
| 254 | for (i = 0; i < num_clks; i++) { | 272 | for (i = 0; i < num_clks; i++) { |
| 255 | if (!rclks[i]) | 273 | if (!rclks[i]) |
| 256 | continue; | 274 | continue; |
diff --git a/drivers/clk/zynqmp/clkc.c b/drivers/clk/zynqmp/clkc.c index 9d7d297f0ea8..f65cc0ff76ab 100644 --- a/drivers/clk/zynqmp/clkc.c +++ b/drivers/clk/zynqmp/clkc.c | |||
| @@ -128,7 +128,7 @@ static const struct zynqmp_eemi_ops *eemi_ops; | |||
| 128 | */ | 128 | */ |
| 129 | static inline int zynqmp_is_valid_clock(u32 clk_id) | 129 | static inline int zynqmp_is_valid_clock(u32 clk_id) |
| 130 | { | 130 | { |
| 131 | if (clk_id > clock_max_idx) | 131 | if (clk_id >= clock_max_idx) |
| 132 | return -ENODEV; | 132 | return -ENODEV; |
| 133 | 133 | ||
| 134 | return clock[clk_id].valid; | 134 | return clock[clk_id].valid; |
| @@ -279,6 +279,9 @@ struct clk_hw *zynqmp_clk_register_fixed_factor(const char *name, u32 clk_id, | |||
| 279 | qdata.arg1 = clk_id; | 279 | qdata.arg1 = clk_id; |
| 280 | 280 | ||
| 281 | ret = eemi_ops->query_data(qdata, ret_payload); | 281 | ret = eemi_ops->query_data(qdata, ret_payload); |
| 282 | if (ret) | ||
| 283 | return ERR_PTR(ret); | ||
| 284 | |||
| 282 | mult = ret_payload[1]; | 285 | mult = ret_payload[1]; |
| 283 | div = ret_payload[2]; | 286 | div = ret_payload[2]; |
| 284 | 287 | ||
