Skip to content

Commit 61ccc8c

Browse files
committed
Merge tag 'clk-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux
Pull clk fixes from Stephen Boyd: "A handful of clk driver fixes: - Avoid a deadlock in the Qualcomm clk driver by making the regulator which supplies the GDSC optional - Restore RPM clks on Qualcomm msm8976 by setting num_clks - Fix Allwinner H6 CPU rate changing logic to avoid system crashes by temporarily reparenting the CPU clk to something that isn't being changed - Set a MIPI PLL min/max rate on Allwinner A64 to fix blank screens on some devices - Revert back to of_match_device() in the Samsung clkout driver to get the match data based on the parent device's compatible string" * tag 'clk-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux: clk: samsung: Revert "clk: Use device_get_match_data()" clk: sunxi-ng: a64: Set minimum and maximum rate for PLL-MIPI clk: sunxi-ng: common: Support minimum and maximum rate clk: sunxi-ng: h6: Reparent CPUX during PLL CPUX rate change clk: qcom: smd-rpm: Restore msm8976 num_clk clk: qcom: gdsc: treat optional supplies as optional
2 parents 7367539 + aacb99d commit 61ccc8c

File tree

7 files changed

+60
-8
lines changed

7 files changed

+60
-8
lines changed

drivers/clk/qcom/clk-smd-rpm.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -768,6 +768,7 @@ static struct clk_smd_rpm *msm8976_clks[] = {
768768

769769
static const struct rpm_smd_clk_desc rpm_clk_msm8976 = {
770770
.clks = msm8976_clks,
771+
.num_clks = ARRAY_SIZE(msm8976_clks),
771772
.icc_clks = bimc_pcnoc_snoc_smmnoc_icc_clks,
772773
.num_icc_clks = ARRAY_SIZE(bimc_pcnoc_snoc_smmnoc_icc_clks),
773774
};

drivers/clk/qcom/gdsc.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -487,9 +487,14 @@ int gdsc_register(struct gdsc_desc *desc,
487487
if (!scs[i] || !scs[i]->supply)
488488
continue;
489489

490-
scs[i]->rsupply = devm_regulator_get(dev, scs[i]->supply);
491-
if (IS_ERR(scs[i]->rsupply))
492-
return PTR_ERR(scs[i]->rsupply);
490+
scs[i]->rsupply = devm_regulator_get_optional(dev, scs[i]->supply);
491+
if (IS_ERR(scs[i]->rsupply)) {
492+
ret = PTR_ERR(scs[i]->rsupply);
493+
if (ret != -ENODEV)
494+
return ret;
495+
496+
scs[i]->rsupply = NULL;
497+
}
493498
}
494499

495500
data->num_domains = num;

drivers/clk/samsung/clk-exynos-clkout.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@
1313
#include <linux/io.h>
1414
#include <linux/of.h>
1515
#include <linux/of_address.h>
16+
#include <linux/of_device.h>
1617
#include <linux/platform_device.h>
1718
#include <linux/pm.h>
18-
#include <linux/property.h>
1919

2020
#define EXYNOS_CLKOUT_NR_CLKS 1
2121
#define EXYNOS_CLKOUT_PARENTS 32
@@ -84,17 +84,24 @@ MODULE_DEVICE_TABLE(of, exynos_clkout_ids);
8484
static int exynos_clkout_match_parent_dev(struct device *dev, u32 *mux_mask)
8585
{
8686
const struct exynos_clkout_variant *variant;
87+
const struct of_device_id *match;
8788

8889
if (!dev->parent) {
8990
dev_err(dev, "not instantiated from MFD\n");
9091
return -EINVAL;
9192
}
9293

93-
variant = device_get_match_data(dev->parent);
94-
if (!variant) {
94+
/*
95+
* 'exynos_clkout_ids' arrays is not the ids array matched by
96+
* the dev->parent driver, so of_device_get_match_data() or
97+
* device_get_match_data() cannot be used here.
98+
*/
99+
match = of_match_device(exynos_clkout_ids, dev->parent);
100+
if (!match) {
95101
dev_err(dev, "cannot match parent device\n");
96102
return -EINVAL;
97103
}
104+
variant = match->data;
98105

99106
*mux_mask = variant->mux_mask;
100107

drivers/clk/sunxi-ng/ccu-sun50i-a64.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,8 @@ static struct ccu_nkm pll_mipi_clk = {
182182
&ccu_nkm_ops,
183183
CLK_SET_RATE_UNGATE | CLK_SET_RATE_PARENT),
184184
.features = CCU_FEATURE_CLOSEST_RATE,
185+
.min_rate = 500000000,
186+
.max_rate = 1400000000,
185187
},
186188
};
187189

drivers/clk/sunxi-ng/ccu-sun50i-h6.c

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1181,11 +1181,18 @@ static const u32 usb2_clk_regs[] = {
11811181
SUN50I_H6_USB3_CLK_REG,
11821182
};
11831183

1184+
static struct ccu_mux_nb sun50i_h6_cpu_nb = {
1185+
.common = &cpux_clk.common,
1186+
.cm = &cpux_clk.mux,
1187+
.delay_us = 1,
1188+
.bypass_index = 0, /* index of 24 MHz oscillator */
1189+
};
1190+
11841191
static int sun50i_h6_ccu_probe(struct platform_device *pdev)
11851192
{
11861193
void __iomem *reg;
1194+
int i, ret;
11871195
u32 val;
1188-
int i;
11891196

11901197
reg = devm_platform_ioremap_resource(pdev, 0);
11911198
if (IS_ERR(reg))
@@ -1252,7 +1259,15 @@ static int sun50i_h6_ccu_probe(struct platform_device *pdev)
12521259
val |= BIT(24);
12531260
writel(val, reg + SUN50I_H6_HDMI_CEC_CLK_REG);
12541261

1255-
return devm_sunxi_ccu_probe(&pdev->dev, reg, &sun50i_h6_ccu_desc);
1262+
ret = devm_sunxi_ccu_probe(&pdev->dev, reg, &sun50i_h6_ccu_desc);
1263+
if (ret)
1264+
return ret;
1265+
1266+
/* Reparent CPU during PLL CPUX rate changes */
1267+
ccu_mux_notifier_register(pll_cpux_clk.common.hw.clk,
1268+
&sun50i_h6_cpu_nb);
1269+
1270+
return 0;
12561271
}
12571272

12581273
static const struct of_device_id sun50i_h6_ccu_ids[] = {

drivers/clk/sunxi-ng/ccu_common.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,16 @@ bool ccu_is_better_rate(struct ccu_common *common,
4444
unsigned long current_rate,
4545
unsigned long best_rate)
4646
{
47+
unsigned long min_rate, max_rate;
48+
49+
clk_hw_get_rate_range(&common->hw, &min_rate, &max_rate);
50+
51+
if (current_rate > max_rate)
52+
return false;
53+
54+
if (current_rate < min_rate)
55+
return false;
56+
4757
if (common->features & CCU_FEATURE_CLOSEST_RATE)
4858
return abs(current_rate - target_rate) < abs(best_rate - target_rate);
4959

@@ -122,6 +132,7 @@ static int sunxi_ccu_probe(struct sunxi_ccu *ccu, struct device *dev,
122132

123133
for (i = 0; i < desc->hw_clks->num ; i++) {
124134
struct clk_hw *hw = desc->hw_clks->hws[i];
135+
struct ccu_common *common = hw_to_ccu_common(hw);
125136
const char *name;
126137

127138
if (!hw)
@@ -136,6 +147,14 @@ static int sunxi_ccu_probe(struct sunxi_ccu *ccu, struct device *dev,
136147
pr_err("Couldn't register clock %d - %s\n", i, name);
137148
goto err_clk_unreg;
138149
}
150+
151+
if (common->max_rate)
152+
clk_hw_set_rate_range(hw, common->min_rate,
153+
common->max_rate);
154+
else
155+
WARN(common->min_rate,
156+
"No max_rate, ignoring min_rate of clock %d - %s\n",
157+
i, name);
139158
}
140159

141160
ret = of_clk_add_hw_provider(node, of_clk_hw_onecell_get,

drivers/clk/sunxi-ng/ccu_common.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ struct ccu_common {
3131
u16 lock_reg;
3232
u32 prediv;
3333

34+
unsigned long min_rate;
35+
unsigned long max_rate;
36+
3437
unsigned long features;
3538
spinlock_t *lock;
3639
struct clk_hw hw;

0 commit comments

Comments
 (0)