Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a2d81b93 authored by qctecmdr Service's avatar qctecmdr Service Committed by Gerrit - the friendly Code Review server
Browse files

Merge "clk: qcom: gdsc: Fix issue with dereferencing NULL pointer in gdsc APIs"

parents cf433b5d c7d3dc88
Loading
Loading
Loading
Loading
+5 −4
Original line number Original line Diff line number Diff line
@@ -50,10 +50,11 @@ Optional properties:
			to enable.
			to enable.
 - qcom,reset-aon-logic: If present, the GPU DEMET cells need to be reset while
 - qcom,reset-aon-logic: If present, the GPU DEMET cells need to be reset while
			 enabling the GX GDSC.
			 enabling the GX GDSC.
 - qcom,vote-parent-supply-voltage: If present, need to vote for a minimum
 - vdd_parent-supply:	phandle to the regulator that this GDSC gates. If
			operational voltage (LOW_SVS) on the GDSC parent
			present, need to vote for a minimum operational voltage
			regulator prior to configuring it. The vote is removed
			(LOW_SVS) on the GDSC parent regulator prior to
			once the GDSC FSM has latched on to the new state.
			configuring it. The vote is removed once the GDSC FSM
			has latched on to the new state.
 - resets: reset specifier pair consisting of phandle for the reset controller
 - resets: reset specifier pair consisting of phandle for the reset controller
			and reset lines used by this controller. These can be
			and reset lines used by this controller. These can be
			supplied only if we support qcom,skip-logic-collapse.
			supplied only if we support qcom,skip-logic-collapse.
+26 −19
Original line number Original line Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0
// SPDX-License-Identifier: GPL-2.0
/*
/*
 * Copyright (c) 2017, The Linux Foundation. All rights reserved.
 * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
 */
 */


#include <linux/kernel.h>
#include <linux/kernel.h>
@@ -52,6 +52,7 @@ struct gdsc {
	struct regmap           *hw_ctrl;
	struct regmap           *hw_ctrl;
	struct regmap           *sw_reset;
	struct regmap           *sw_reset;
	struct clk		**clocks;
	struct clk		**clocks;
	struct regulator	*parent_regulator;
	struct reset_control	**reset_clocks;
	struct reset_control	**reset_clocks;
	bool			toggle_mem;
	bool			toggle_mem;
	bool			toggle_periph;
	bool			toggle_periph;
@@ -63,7 +64,6 @@ struct gdsc {
	bool			is_gdsc_enabled;
	bool			is_gdsc_enabled;
	bool			allow_clear;
	bool			allow_clear;
	bool			reset_aon;
	bool			reset_aon;
	bool			vote_supply_voltage;
	int			clock_count;
	int			clock_count;
	int			reset_count;
	int			reset_count;
	int			root_clk_idx;
	int			root_clk_idx;
@@ -162,8 +162,8 @@ static int gdsc_enable(struct regulator_dev *rdev)


	mutex_lock(&gdsc_seq_lock);
	mutex_lock(&gdsc_seq_lock);


	if (sc->vote_supply_voltage) {
	if (sc->parent_regulator) {
		ret = regulator_set_voltage(sc->rdev->supply,
		ret = regulator_set_voltage(sc->parent_regulator,
				RPMH_REGULATOR_LEVEL_LOW_SVS, INT_MAX);
				RPMH_REGULATOR_LEVEL_LOW_SVS, INT_MAX);
		if (ret) {
		if (ret) {
			mutex_unlock(&gdsc_seq_lock);
			mutex_unlock(&gdsc_seq_lock);
@@ -308,8 +308,8 @@ static int gdsc_enable(struct regulator_dev *rdev)


	sc->is_gdsc_enabled = true;
	sc->is_gdsc_enabled = true;
end:
end:
	if (sc->vote_supply_voltage)
	if (sc->parent_regulator)
		regulator_set_voltage(sc->rdev->supply, 0, INT_MAX);
		regulator_set_voltage(sc->parent_regulator, 0, INT_MAX);


	mutex_unlock(&gdsc_seq_lock);
	mutex_unlock(&gdsc_seq_lock);


@@ -324,8 +324,8 @@ static int gdsc_disable(struct regulator_dev *rdev)


	mutex_lock(&gdsc_seq_lock);
	mutex_lock(&gdsc_seq_lock);


	if (sc->vote_supply_voltage) {
	if (sc->parent_regulator) {
		ret = regulator_set_voltage(sc->rdev->supply,
		ret = regulator_set_voltage(sc->parent_regulator,
				RPMH_REGULATOR_LEVEL_LOW_SVS, INT_MAX);
				RPMH_REGULATOR_LEVEL_LOW_SVS, INT_MAX);
		if (ret) {
		if (ret) {
			mutex_unlock(&gdsc_seq_lock);
			mutex_unlock(&gdsc_seq_lock);
@@ -390,8 +390,8 @@ static int gdsc_disable(struct regulator_dev *rdev)
	if ((sc->is_gdsc_enabled && sc->root_en) || sc->force_root_en)
	if ((sc->is_gdsc_enabled && sc->root_en) || sc->force_root_en)
		clk_disable_unprepare(sc->clocks[sc->root_clk_idx]);
		clk_disable_unprepare(sc->clocks[sc->root_clk_idx]);


	if (sc->vote_supply_voltage)
	if (sc->parent_regulator)
		regulator_set_voltage(sc->rdev->supply, 0, INT_MAX);
		regulator_set_voltage(sc->parent_regulator, 0, INT_MAX);


	sc->is_gdsc_enabled = false;
	sc->is_gdsc_enabled = false;


@@ -423,8 +423,8 @@ static int gdsc_set_mode(struct regulator_dev *rdev, unsigned int mode)


	mutex_lock(&gdsc_seq_lock);
	mutex_lock(&gdsc_seq_lock);


	if (sc->vote_supply_voltage) {
	if (sc->parent_regulator) {
		ret = regulator_set_voltage(sc->rdev->supply,
		ret = regulator_set_voltage(sc->parent_regulator,
				RPMH_REGULATOR_LEVEL_LOW_SVS, INT_MAX);
				RPMH_REGULATOR_LEVEL_LOW_SVS, INT_MAX);
		if (ret) {
		if (ret) {
			mutex_unlock(&gdsc_seq_lock);
			mutex_unlock(&gdsc_seq_lock);
@@ -475,8 +475,8 @@ static int gdsc_set_mode(struct regulator_dev *rdev, unsigned int mode)
		break;
		break;
	}
	}


	if (sc->vote_supply_voltage)
	if (sc->parent_regulator)
		regulator_set_voltage(sc->rdev->supply, 0, INT_MAX);
		regulator_set_voltage(sc->parent_regulator, 0, INT_MAX);


	mutex_unlock(&gdsc_seq_lock);
	mutex_unlock(&gdsc_seq_lock);


@@ -594,8 +594,18 @@ static int gdsc_probe(struct platform_device *pdev)
	sc->force_root_en = of_property_read_bool(pdev->dev.of_node,
	sc->force_root_en = of_property_read_bool(pdev->dev.of_node,
						"qcom,force-enable-root-clk");
						"qcom,force-enable-root-clk");


	sc->vote_supply_voltage = of_property_read_bool(pdev->dev.of_node,
	if (of_find_property(pdev->dev.of_node, "vdd_parent-supply", NULL)) {
					"qcom,vote-parent-supply-voltage");
		sc->parent_regulator = devm_regulator_get(&pdev->dev,
							"vdd_parent");
		if (IS_ERR(sc->parent_regulator)) {
			ret = PTR_ERR(sc->parent_regulator);
			if (ret != -EPROBE_DEFER)
				dev_err(&pdev->dev,
				"Unable to get vdd_parent regulator, err: %d\n",
					ret);
			return ret;
		}
	}


	for (i = 0; i < sc->clock_count; i++) {
	for (i = 0; i < sc->clock_count; i++) {
		const char *clock_name;
		const char *clock_name;
@@ -741,9 +751,6 @@ static int gdsc_probe(struct platform_device *pdev)
		return PTR_ERR(sc->rdev);
		return PTR_ERR(sc->rdev);
	}
	}


	if (!sc->rdev->supply)
		sc->vote_supply_voltage = false;

	return 0;
	return 0;
}
}