Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

+60 -8
+1
drivers/clk/qcom/clk-smd-rpm.c
··· 768 768 769 769 static const struct rpm_smd_clk_desc rpm_clk_msm8976 = { 770 770 .clks = msm8976_clks, 771 + .num_clks = ARRAY_SIZE(msm8976_clks), 771 772 .icc_clks = bimc_pcnoc_snoc_smmnoc_icc_clks, 772 773 .num_icc_clks = ARRAY_SIZE(bimc_pcnoc_snoc_smmnoc_icc_clks), 773 774 };
+8 -3
drivers/clk/qcom/gdsc.c
··· 487 487 if (!scs[i] || !scs[i]->supply) 488 488 continue; 489 489 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 + } 493 498 } 494 499 495 500 data->num_domains = num;
+10 -3
drivers/clk/samsung/clk-exynos-clkout.c
··· 13 13 #include <linux/io.h> 14 14 #include <linux/of.h> 15 15 #include <linux/of_address.h> 16 + #include <linux/of_device.h> 16 17 #include <linux/platform_device.h> 17 18 #include <linux/pm.h> 18 - #include <linux/property.h> 19 19 20 20 #define EXYNOS_CLKOUT_NR_CLKS 1 21 21 #define EXYNOS_CLKOUT_PARENTS 32 ··· 84 84 static int exynos_clkout_match_parent_dev(struct device *dev, u32 *mux_mask) 85 85 { 86 86 const struct exynos_clkout_variant *variant; 87 + const struct of_device_id *match; 87 88 88 89 if (!dev->parent) { 89 90 dev_err(dev, "not instantiated from MFD\n"); 90 91 return -EINVAL; 91 92 } 92 93 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) { 95 101 dev_err(dev, "cannot match parent device\n"); 96 102 return -EINVAL; 97 103 } 104 + variant = match->data; 98 105 99 106 *mux_mask = variant->mux_mask; 100 107
+2
drivers/clk/sunxi-ng/ccu-sun50i-a64.c
··· 182 182 &ccu_nkm_ops, 183 183 CLK_SET_RATE_UNGATE | CLK_SET_RATE_PARENT), 184 184 .features = CCU_FEATURE_CLOSEST_RATE, 185 + .min_rate = 500000000, 186 + .max_rate = 1400000000, 185 187 }, 186 188 }; 187 189
+17 -2
drivers/clk/sunxi-ng/ccu-sun50i-h6.c
··· 1181 1181 SUN50I_H6_USB3_CLK_REG, 1182 1182 }; 1183 1183 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 + 1184 1191 static int sun50i_h6_ccu_probe(struct platform_device *pdev) 1185 1192 { 1186 1193 void __iomem *reg; 1194 + int i, ret; 1187 1195 u32 val; 1188 - int i; 1189 1196 1190 1197 reg = devm_platform_ioremap_resource(pdev, 0); 1191 1198 if (IS_ERR(reg)) ··· 1259 1252 val |= BIT(24); 1260 1253 writel(val, reg + SUN50I_H6_HDMI_CEC_CLK_REG); 1261 1254 1262 - return devm_sunxi_ccu_probe(&pdev->dev, reg, &sun50i_h6_ccu_desc); 1255 + ret = devm_sunxi_ccu_probe(&pdev->dev, reg, &sun50i_h6_ccu_desc); 1256 + if (ret) 1257 + return ret; 1258 + 1259 + /* Reparent CPU during PLL CPUX rate changes */ 1260 + ccu_mux_notifier_register(pll_cpux_clk.common.hw.clk, 1261 + &sun50i_h6_cpu_nb); 1262 + 1263 + return 0; 1263 1264 } 1264 1265 1265 1266 static const struct of_device_id sun50i_h6_ccu_ids[] = {
+19
drivers/clk/sunxi-ng/ccu_common.c
··· 44 44 unsigned long current_rate, 45 45 unsigned long best_rate) 46 46 { 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 + 47 57 if (common->features & CCU_FEATURE_CLOSEST_RATE) 48 58 return abs(current_rate - target_rate) < abs(best_rate - target_rate); 49 59 ··· 132 122 133 123 for (i = 0; i < desc->hw_clks->num ; i++) { 134 124 struct clk_hw *hw = desc->hw_clks->hws[i]; 125 + struct ccu_common *common = hw_to_ccu_common(hw); 135 126 const char *name; 136 127 137 128 if (!hw) ··· 147 136 pr_err("Couldn't register clock %d - %s\n", i, name); 148 137 goto err_clk_unreg; 149 138 } 139 + 140 + if (common->max_rate) 141 + clk_hw_set_rate_range(hw, common->min_rate, 142 + common->max_rate); 143 + else 144 + WARN(common->min_rate, 145 + "No max_rate, ignoring min_rate of clock %d - %s\n", 146 + i, name); 150 147 } 151 148 152 149 ret = of_clk_add_hw_provider(node, of_clk_hw_onecell_get,
+3
drivers/clk/sunxi-ng/ccu_common.h
··· 31 31 u16 lock_reg; 32 32 u32 prediv; 33 33 34 + unsigned long min_rate; 35 + unsigned long max_rate; 36 + 34 37 unsigned long features; 35 38 spinlock_t *lock; 36 39 struct clk_hw hw;