Skip to content

Commit

Permalink
Merge tag 'clk-fixes-for-linus' of git://git.kernel.org/pub/scm/linux…
Browse files Browse the repository at this point in the history
…/kernel/git/clk/linux

Pull clk fixes from Stephen Boyd:
 "A few clk driver fixes this time:

   - Introduce protected-clock DT binding to fix breakage on qcom
     sdm845-mtp boards where the qspi clks introduced this merge window
     cause the firmware on those boards to take down the system if we
     try to read the clk registers

   - Fix a couple off-by-one errors found by Dan Carpenter

   - Handle failure in zynq fixed factor clk driver to avoid using
     uninitialized data"

* tag 'clk-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux:
  clk: zynqmp: Off by one in zynqmp_is_valid_clock()
  clk: mmp: Off by one in mmp_clk_add()
  clk: mvebu: Off by one bugs in cp110_of_clk_get()
  arm64: dts: qcom: sdm845-mtp: Mark protected gcc clocks
  clk: qcom: Support 'protected-clocks' property
  dt-bindings: clk: Introduce 'protected-clocks' property
  clk: zynqmp: handle fixed factor param query error
  • Loading branch information
torvalds committed Dec 8, 2018
2 parents f896adc + 9a43be9 commit 570c913
Show file tree
Hide file tree
Showing 6 changed files with 47 additions and 4 deletions.
16 changes: 16 additions & 0 deletions Documentation/devicetree/bindings/clock/clock-bindings.txt
Original file line number Diff line number Diff line change
Expand Up @@ -168,3 +168,19 @@ a shared clock is forbidden.

Configuration of common clocks, which affect multiple consumer devices can
be similarly specified in the clock provider node.

==Protected clocks==

Some platforms or firmwares may not fully expose all the clocks to the OS, such
as in situations where those clks are used by drivers running in ARM secure
execution levels. Such a configuration can be specified in device tree with the
protected-clocks property in the form of a clock specifier list. This property should
only be specified in the node that is providing the clocks being protected:

clock-controller@a000f000 {
compatible = "vendor,clk95;
reg = <0xa000f000 0x1000>
#clocks-cells = <1>;
...
protected-clocks = <UART3_CLK>, <SPI5_CLK>;
};
6 changes: 6 additions & 0 deletions arch/arm64/boot/dts/qcom/sdm845-mtp.dts
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,12 @@
};
};

&gcc {
protected-clocks = <GCC_QSPI_CORE_CLK>,
<GCC_QSPI_CORE_CLK_SRC>,
<GCC_QSPI_CNOC_PERIPH_AHB_CLK>;
};

&i2c10 {
status = "okay";
clock-frequency = <400000>;
Expand Down
2 changes: 1 addition & 1 deletion drivers/clk/mmp/clk.c
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ void mmp_clk_add(struct mmp_clk_unit *unit, unsigned int id,
pr_err("CLK %d has invalid pointer %p\n", id, clk);
return;
}
if (id > unit->nr_clks) {
if (id >= unit->nr_clks) {
pr_err("CLK %d is invalid\n", id);
return;
}
Expand Down
4 changes: 2 additions & 2 deletions drivers/clk/mvebu/cp110-system-controller.c
Original file line number Diff line number Diff line change
Expand Up @@ -200,11 +200,11 @@ static struct clk_hw *cp110_of_clk_get(struct of_phandle_args *clkspec,
unsigned int idx = clkspec->args[1];

if (type == CP110_CLK_TYPE_CORE) {
if (idx > CP110_MAX_CORE_CLOCKS)
if (idx >= CP110_MAX_CORE_CLOCKS)
return ERR_PTR(-EINVAL);
return clk_data->hws[idx];
} else if (type == CP110_CLK_TYPE_GATABLE) {
if (idx > CP110_MAX_GATABLE_CLOCKS)
if (idx >= CP110_MAX_GATABLE_CLOCKS)
return ERR_PTR(-EINVAL);
return clk_data->hws[CP110_MAX_CORE_CLOCKS + idx];
}
Expand Down
18 changes: 18 additions & 0 deletions drivers/clk/qcom/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,22 @@ int qcom_cc_register_sleep_clk(struct device *dev)
}
EXPORT_SYMBOL_GPL(qcom_cc_register_sleep_clk);

/* Drop 'protected-clocks' from the list of clocks to register */
static void qcom_cc_drop_protected(struct device *dev, struct qcom_cc *cc)
{
struct device_node *np = dev->of_node;
struct property *prop;
const __be32 *p;
u32 i;

of_property_for_each_u32(np, "protected-clocks", prop, p, i) {
if (i >= cc->num_rclks)
continue;

cc->rclks[i] = NULL;
}
}

static struct clk_hw *qcom_cc_clk_hw_get(struct of_phandle_args *clkspec,
void *data)
{
Expand Down Expand Up @@ -251,6 +267,8 @@ int qcom_cc_really_probe(struct platform_device *pdev,
cc->rclks = rclks;
cc->num_rclks = num_clks;

qcom_cc_drop_protected(dev, cc);

for (i = 0; i < num_clks; i++) {
if (!rclks[i])
continue;
Expand Down
5 changes: 4 additions & 1 deletion drivers/clk/zynqmp/clkc.c
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ static const struct zynqmp_eemi_ops *eemi_ops;
*/
static inline int zynqmp_is_valid_clock(u32 clk_id)
{
if (clk_id > clock_max_idx)
if (clk_id >= clock_max_idx)
return -ENODEV;

return clock[clk_id].valid;
Expand Down Expand Up @@ -279,6 +279,9 @@ struct clk_hw *zynqmp_clk_register_fixed_factor(const char *name, u32 clk_id,
qdata.arg1 = clk_id;

ret = eemi_ops->query_data(qdata, ret_payload);
if (ret)
return ERR_PTR(ret);

mult = ret_payload[1];
div = ret_payload[2];

Expand Down

0 comments on commit 570c913

Please sign in to comment.