Skip to content

Commit

Permalink
Merge tag 'clk-fixes-for-linus' of git:https://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 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:https://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
  • Loading branch information
torvalds committed May 5, 2024
2 parents 7367539 + aacb99d commit 61ccc8c
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 8 deletions.
1 change: 1 addition & 0 deletions drivers/clk/qcom/clk-smd-rpm.c
Original file line number Diff line number Diff line change
Expand Up @@ -768,6 +768,7 @@ static struct clk_smd_rpm *msm8976_clks[] = {

static const struct rpm_smd_clk_desc rpm_clk_msm8976 = {
.clks = msm8976_clks,
.num_clks = ARRAY_SIZE(msm8976_clks),
.icc_clks = bimc_pcnoc_snoc_smmnoc_icc_clks,
.num_icc_clks = ARRAY_SIZE(bimc_pcnoc_snoc_smmnoc_icc_clks),
};
Expand Down
11 changes: 8 additions & 3 deletions drivers/clk/qcom/gdsc.c
Original file line number Diff line number Diff line change
Expand Up @@ -487,9 +487,14 @@ int gdsc_register(struct gdsc_desc *desc,
if (!scs[i] || !scs[i]->supply)
continue;

scs[i]->rsupply = devm_regulator_get(dev, scs[i]->supply);
if (IS_ERR(scs[i]->rsupply))
return PTR_ERR(scs[i]->rsupply);
scs[i]->rsupply = devm_regulator_get_optional(dev, scs[i]->supply);
if (IS_ERR(scs[i]->rsupply)) {
ret = PTR_ERR(scs[i]->rsupply);
if (ret != -ENODEV)
return ret;

scs[i]->rsupply = NULL;
}
}

data->num_domains = num;
Expand Down
13 changes: 10 additions & 3 deletions drivers/clk/samsung/clk-exynos-clkout.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@
#include <linux/io.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/pm.h>
#include <linux/property.h>

#define EXYNOS_CLKOUT_NR_CLKS 1
#define EXYNOS_CLKOUT_PARENTS 32
Expand Down Expand Up @@ -84,17 +84,24 @@ MODULE_DEVICE_TABLE(of, exynos_clkout_ids);
static int exynos_clkout_match_parent_dev(struct device *dev, u32 *mux_mask)
{
const struct exynos_clkout_variant *variant;
const struct of_device_id *match;

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

variant = device_get_match_data(dev->parent);
if (!variant) {
/*
* 'exynos_clkout_ids' arrays is not the ids array matched by
* the dev->parent driver, so of_device_get_match_data() or
* device_get_match_data() cannot be used here.
*/
match = of_match_device(exynos_clkout_ids, dev->parent);
if (!match) {
dev_err(dev, "cannot match parent device\n");
return -EINVAL;
}
variant = match->data;

*mux_mask = variant->mux_mask;

Expand Down
2 changes: 2 additions & 0 deletions drivers/clk/sunxi-ng/ccu-sun50i-a64.c
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,8 @@ static struct ccu_nkm pll_mipi_clk = {
&ccu_nkm_ops,
CLK_SET_RATE_UNGATE | CLK_SET_RATE_PARENT),
.features = CCU_FEATURE_CLOSEST_RATE,
.min_rate = 500000000,
.max_rate = 1400000000,
},
};

Expand Down
19 changes: 17 additions & 2 deletions drivers/clk/sunxi-ng/ccu-sun50i-h6.c
Original file line number Diff line number Diff line change
Expand Up @@ -1181,11 +1181,18 @@ static const u32 usb2_clk_regs[] = {
SUN50I_H6_USB3_CLK_REG,
};

static struct ccu_mux_nb sun50i_h6_cpu_nb = {
.common = &cpux_clk.common,
.cm = &cpux_clk.mux,
.delay_us = 1,
.bypass_index = 0, /* index of 24 MHz oscillator */
};

static int sun50i_h6_ccu_probe(struct platform_device *pdev)
{
void __iomem *reg;
int i, ret;
u32 val;
int i;

reg = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(reg))
Expand Down Expand Up @@ -1252,7 +1259,15 @@ static int sun50i_h6_ccu_probe(struct platform_device *pdev)
val |= BIT(24);
writel(val, reg + SUN50I_H6_HDMI_CEC_CLK_REG);

return devm_sunxi_ccu_probe(&pdev->dev, reg, &sun50i_h6_ccu_desc);
ret = devm_sunxi_ccu_probe(&pdev->dev, reg, &sun50i_h6_ccu_desc);
if (ret)
return ret;

/* Reparent CPU during PLL CPUX rate changes */
ccu_mux_notifier_register(pll_cpux_clk.common.hw.clk,
&sun50i_h6_cpu_nb);

return 0;
}

static const struct of_device_id sun50i_h6_ccu_ids[] = {
Expand Down
19 changes: 19 additions & 0 deletions drivers/clk/sunxi-ng/ccu_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,16 @@ bool ccu_is_better_rate(struct ccu_common *common,
unsigned long current_rate,
unsigned long best_rate)
{
unsigned long min_rate, max_rate;

clk_hw_get_rate_range(&common->hw, &min_rate, &max_rate);

if (current_rate > max_rate)
return false;

if (current_rate < min_rate)
return false;

if (common->features & CCU_FEATURE_CLOSEST_RATE)
return abs(current_rate - target_rate) < abs(best_rate - target_rate);

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

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

if (!hw)
Expand All @@ -136,6 +147,14 @@ static int sunxi_ccu_probe(struct sunxi_ccu *ccu, struct device *dev,
pr_err("Couldn't register clock %d - %s\n", i, name);
goto err_clk_unreg;
}

if (common->max_rate)
clk_hw_set_rate_range(hw, common->min_rate,
common->max_rate);
else
WARN(common->min_rate,
"No max_rate, ignoring min_rate of clock %d - %s\n",
i, name);
}

ret = of_clk_add_hw_provider(node, of_clk_hw_onecell_get,
Expand Down
3 changes: 3 additions & 0 deletions drivers/clk/sunxi-ng/ccu_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ struct ccu_common {
u16 lock_reg;
u32 prediv;

unsigned long min_rate;
unsigned long max_rate;

unsigned long features;
spinlock_t *lock;
struct clk_hw hw;
Expand Down

0 comments on commit 61ccc8c

Please sign in to comment.