Linux Audio

Check our new training course

Loading...
v5.9
  1// SPDX-License-Identifier: GPL-2.0+
  2/*
  3 * Voltage regulators coupler for NVIDIA Tegra30
  4 * Copyright (C) 2019 GRATE-DRIVER project
  5 *
  6 * Voltage constraints borrowed from downstream kernel sources
  7 * Copyright (C) 2010-2011 NVIDIA Corporation
  8 */
  9
 10#define pr_fmt(fmt)	"tegra voltage-coupler: " fmt
 11
 12#include <linux/init.h>
 13#include <linux/kernel.h>
 14#include <linux/of.h>
 
 15#include <linux/regulator/coupler.h>
 16#include <linux/regulator/driver.h>
 17#include <linux/regulator/machine.h>
 
 18
 19#include <soc/tegra/fuse.h>
 
 20
 21struct tegra_regulator_coupler {
 22	struct regulator_coupler coupler;
 23	struct regulator_dev *core_rdev;
 24	struct regulator_dev *cpu_rdev;
 25	int core_min_uV;
 
 
 
 
 
 
 26};
 27
 28static inline struct tegra_regulator_coupler *
 29to_tegra_coupler(struct regulator_coupler *coupler)
 30{
 31	return container_of(coupler, struct tegra_regulator_coupler, coupler);
 32}
 33
 34static int tegra30_core_limit(struct tegra_regulator_coupler *tegra,
 35			      struct regulator_dev *core_rdev)
 36{
 37	int core_min_uV = 0;
 38	int core_max_uV;
 39	int core_cur_uV;
 40	int err;
 41
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 42	if (tegra->core_min_uV > 0)
 43		return tegra->core_min_uV;
 44
 45	core_cur_uV = regulator_get_voltage_rdev(core_rdev);
 46	if (core_cur_uV < 0)
 47		return core_cur_uV;
 48
 49	core_max_uV = max(core_cur_uV, 1200000);
 50
 51	err = regulator_check_voltage(core_rdev, &core_min_uV, &core_max_uV);
 52	if (err)
 53		return err;
 54
 55	/*
 56	 * Limit minimum CORE voltage to a value left from bootloader or,
 57	 * if it's unreasonably low value, to the most common 1.2v or to
 58	 * whatever maximum value defined via board's device-tree.
 59	 */
 60	tegra->core_min_uV = core_max_uV;
 61
 62	pr_info("core minimum voltage limited to %duV\n", tegra->core_min_uV);
 63
 64	return tegra->core_min_uV;
 65}
 66
 67static int tegra30_core_cpu_limit(int cpu_uV)
 68{
 69	if (cpu_uV < 800000)
 70		return 950000;
 71
 72	if (cpu_uV < 900000)
 73		return 1000000;
 74
 75	if (cpu_uV < 1000000)
 76		return 1100000;
 77
 78	if (cpu_uV < 1100000)
 79		return 1200000;
 80
 81	if (cpu_uV < 1250000) {
 82		switch (tegra_sku_info.cpu_speedo_id) {
 83		case 0 ... 1:
 84		case 4:
 85		case 7 ... 8:
 86			return 1200000;
 87
 88		default:
 89			return 1300000;
 90		}
 91	}
 92
 93	return -EINVAL;
 94}
 95
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 96static int tegra30_voltage_update(struct tegra_regulator_coupler *tegra,
 97				  struct regulator_dev *cpu_rdev,
 98				  struct regulator_dev *core_rdev)
 99{
100	int core_min_uV, core_max_uV = INT_MAX;
101	int cpu_min_uV, cpu_max_uV = INT_MAX;
102	int cpu_min_uV_consumers = 0;
103	int core_min_limited_uV;
104	int core_target_uV;
105	int cpu_target_uV;
106	int core_max_step;
107	int cpu_max_step;
108	int max_spread;
109	int core_uV;
110	int cpu_uV;
111	int err;
112
113	/*
114	 * CPU voltage should not got lower than 300mV from the CORE.
115	 * CPU voltage should stay below the CORE by 100mV+, depending
116	 * by the CORE voltage. This applies to all Tegra30 SoC's.
117	 */
118	max_spread = cpu_rdev->constraints->max_spread[0];
119	cpu_max_step = cpu_rdev->constraints->max_uV_step;
120	core_max_step = core_rdev->constraints->max_uV_step;
121
122	if (!max_spread) {
123		pr_err_once("cpu-core max-spread is undefined in device-tree\n");
124		max_spread = 300000;
125	}
126
127	if (!cpu_max_step) {
128		pr_err_once("cpu max-step is undefined in device-tree\n");
129		cpu_max_step = 150000;
130	}
131
132	if (!core_max_step) {
133		pr_err_once("core max-step is undefined in device-tree\n");
134		core_max_step = 150000;
135	}
136
137	/*
138	 * The CORE voltage scaling is currently not hooked up in drivers,
139	 * hence we will limit the minimum CORE voltage to a reasonable value.
140	 * This should be good enough for the time being.
141	 */
142	core_min_uV = tegra30_core_limit(tegra, core_rdev);
143	if (core_min_uV < 0)
144		return core_min_uV;
145
146	err = regulator_check_consumers(core_rdev, &core_min_uV, &core_max_uV,
147					PM_SUSPEND_ON);
148	if (err)
149		return err;
150
 
 
 
 
 
151	core_uV = regulator_get_voltage_rdev(core_rdev);
152	if (core_uV < 0)
153		return core_uV;
154
155	cpu_min_uV = core_min_uV - max_spread;
156
157	err = regulator_check_consumers(cpu_rdev, &cpu_min_uV, &cpu_max_uV,
158					PM_SUSPEND_ON);
159	if (err)
160		return err;
161
162	err = regulator_check_consumers(cpu_rdev, &cpu_min_uV_consumers,
163					&cpu_max_uV, PM_SUSPEND_ON);
164	if (err)
165		return err;
166
167	err = regulator_check_voltage(cpu_rdev, &cpu_min_uV, &cpu_max_uV);
168	if (err)
169		return err;
170
171	cpu_uV = regulator_get_voltage_rdev(cpu_rdev);
172	if (cpu_uV < 0)
173		return cpu_uV;
174
 
 
 
 
175	/*
176	 * CPU's regulator may not have any consumers, hence the voltage
177	 * must not be changed in that case because CPU simply won't
178	 * survive the voltage drop if it's running on a higher frequency.
179	 */
180	if (!cpu_min_uV_consumers)
181		cpu_min_uV = cpu_uV;
182
183	/*
184	 * Bootloader shall set up voltages correctly, but if it
185	 * happens that there is a violation, then try to fix it
186	 * at first.
187	 */
188	core_min_limited_uV = tegra30_core_cpu_limit(cpu_uV);
189	if (core_min_limited_uV < 0)
190		return core_min_limited_uV;
191
192	core_min_uV = max(core_min_uV, tegra30_core_cpu_limit(cpu_min_uV));
193
194	err = regulator_check_voltage(core_rdev, &core_min_uV, &core_max_uV);
195	if (err)
196		return err;
197
 
 
 
 
 
 
 
 
 
198	if (core_min_limited_uV > core_uV) {
199		pr_err("core voltage constraint violated: %d %d %d\n",
200		       core_uV, core_min_limited_uV, cpu_uV);
201		goto update_core;
202	}
203
204	while (cpu_uV != cpu_min_uV || core_uV != core_min_uV) {
205		if (cpu_uV < cpu_min_uV) {
206			cpu_target_uV = min(cpu_uV + cpu_max_step, cpu_min_uV);
207		} else {
208			cpu_target_uV = max(cpu_uV - cpu_max_step, cpu_min_uV);
209			cpu_target_uV = max(core_uV - max_spread, cpu_target_uV);
210		}
211
212		if (cpu_uV == cpu_target_uV)
213			goto update_core;
214
215		err = regulator_set_voltage_rdev(cpu_rdev,
216						 cpu_target_uV,
217						 cpu_max_uV,
218						 PM_SUSPEND_ON);
219		if (err)
220			return err;
221
222		cpu_uV = cpu_target_uV;
223update_core:
224		core_min_limited_uV = tegra30_core_cpu_limit(cpu_uV);
225		if (core_min_limited_uV < 0)
226			return core_min_limited_uV;
227
228		core_target_uV = max(core_min_limited_uV, core_min_uV);
229
230		if (core_uV < core_target_uV) {
231			core_target_uV = min(core_target_uV, core_uV + core_max_step);
232			core_target_uV = min(core_target_uV, cpu_uV + max_spread);
233		} else {
234			core_target_uV = max(core_target_uV, core_uV - core_max_step);
235		}
236
237		if (core_uV == core_target_uV)
238			continue;
239
240		err = regulator_set_voltage_rdev(core_rdev,
241						 core_target_uV,
242						 core_max_uV,
243						 PM_SUSPEND_ON);
244		if (err)
245			return err;
246
247		core_uV = core_target_uV;
248	}
249
250	return 0;
251}
252
253static int tegra30_regulator_balance_voltage(struct regulator_coupler *coupler,
254					     struct regulator_dev *rdev,
255					     suspend_state_t state)
256{
257	struct tegra_regulator_coupler *tegra = to_tegra_coupler(coupler);
258	struct regulator_dev *core_rdev = tegra->core_rdev;
259	struct regulator_dev *cpu_rdev = tegra->cpu_rdev;
260
261	if ((core_rdev != rdev && cpu_rdev != rdev) || state != PM_SUSPEND_ON) {
262		pr_err("regulators are not coupled properly\n");
263		return -EINVAL;
264	}
265
 
 
 
266	return tegra30_voltage_update(tegra, cpu_rdev, core_rdev);
267}
268
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
269static int tegra30_regulator_attach(struct regulator_coupler *coupler,
270				    struct regulator_dev *rdev)
271{
272	struct tegra_regulator_coupler *tegra = to_tegra_coupler(coupler);
273	struct device_node *np = rdev->dev.of_node;
274
275	if (of_property_read_bool(np, "nvidia,tegra-core-regulator") &&
276	    !tegra->core_rdev) {
277		tegra->core_rdev = rdev;
278		return 0;
279	}
280
281	if (of_property_read_bool(np, "nvidia,tegra-cpu-regulator") &&
282	    !tegra->cpu_rdev) {
283		tegra->cpu_rdev = rdev;
284		return 0;
285	}
286
287	return -EINVAL;
288}
289
290static int tegra30_regulator_detach(struct regulator_coupler *coupler,
291				    struct regulator_dev *rdev)
292{
293	struct tegra_regulator_coupler *tegra = to_tegra_coupler(coupler);
294
 
 
 
 
 
 
 
 
295	if (tegra->core_rdev == rdev) {
296		tegra->core_rdev = NULL;
297		return 0;
298	}
299
300	if (tegra->cpu_rdev == rdev) {
301		tegra->cpu_rdev = NULL;
302		return 0;
303	}
304
305	return -EINVAL;
306}
307
308static struct tegra_regulator_coupler tegra30_coupler = {
309	.coupler = {
310		.attach_regulator = tegra30_regulator_attach,
311		.detach_regulator = tegra30_regulator_detach,
312		.balance_voltage = tegra30_regulator_balance_voltage,
313	},
 
 
314};
315
316static int __init tegra_regulator_coupler_init(void)
317{
 
 
318	if (!of_machine_is_compatible("nvidia,tegra30"))
319		return 0;
 
 
 
 
 
 
320
321	return regulator_coupler_register(&tegra30_coupler.coupler);
322}
323arch_initcall(tegra_regulator_coupler_init);
v6.13.7
  1// SPDX-License-Identifier: GPL-2.0+
  2/*
  3 * Voltage regulators coupler for NVIDIA Tegra30
  4 * Copyright (C) 2019 GRATE-DRIVER project
  5 *
  6 * Voltage constraints borrowed from downstream kernel sources
  7 * Copyright (C) 2010-2011 NVIDIA Corporation
  8 */
  9
 10#define pr_fmt(fmt)	"tegra voltage-coupler: " fmt
 11
 12#include <linux/init.h>
 13#include <linux/kernel.h>
 14#include <linux/of.h>
 15#include <linux/reboot.h>
 16#include <linux/regulator/coupler.h>
 17#include <linux/regulator/driver.h>
 18#include <linux/regulator/machine.h>
 19#include <linux/suspend.h>
 20
 21#include <soc/tegra/fuse.h>
 22#include <soc/tegra/pmc.h>
 23
 24struct tegra_regulator_coupler {
 25	struct regulator_coupler coupler;
 26	struct regulator_dev *core_rdev;
 27	struct regulator_dev *cpu_rdev;
 28	struct notifier_block reboot_notifier;
 29	struct notifier_block suspend_notifier;
 30	int core_min_uV, cpu_min_uV;
 31	bool sys_reboot_mode_req;
 32	bool sys_reboot_mode;
 33	bool sys_suspend_mode_req;
 34	bool sys_suspend_mode;
 35};
 36
 37static inline struct tegra_regulator_coupler *
 38to_tegra_coupler(struct regulator_coupler *coupler)
 39{
 40	return container_of(coupler, struct tegra_regulator_coupler, coupler);
 41}
 42
 43static int tegra30_core_limit(struct tegra_regulator_coupler *tegra,
 44			      struct regulator_dev *core_rdev)
 45{
 46	int core_min_uV = 0;
 47	int core_max_uV;
 48	int core_cur_uV;
 49	int err;
 50
 51	/*
 52	 * Tegra30 SoC has critical DVFS-capable devices that are
 53	 * permanently-active or active at a boot time, like EMC
 54	 * (DRAM controller) or Display controller for example.
 55	 *
 56	 * The voltage of a CORE SoC power domain shall not be dropped below
 57	 * a minimum level, which is determined by device's clock rate.
 58	 * This means that we can't fully allow CORE voltage scaling until
 59	 * the state of all DVFS-critical CORE devices is synced.
 60	 */
 61	if (tegra_pmc_core_domain_state_synced() && !tegra->sys_reboot_mode) {
 62		pr_info_once("voltage state synced\n");
 63		return 0;
 64	}
 65
 66	if (tegra->core_min_uV > 0)
 67		return tegra->core_min_uV;
 68
 69	core_cur_uV = regulator_get_voltage_rdev(core_rdev);
 70	if (core_cur_uV < 0)
 71		return core_cur_uV;
 72
 73	core_max_uV = max(core_cur_uV, 1200000);
 74
 75	err = regulator_check_voltage(core_rdev, &core_min_uV, &core_max_uV);
 76	if (err)
 77		return err;
 78
 79	/*
 80	 * Limit minimum CORE voltage to a value left from bootloader or,
 81	 * if it's unreasonably low value, to the most common 1.2v or to
 82	 * whatever maximum value defined via board's device-tree.
 83	 */
 84	tegra->core_min_uV = core_max_uV;
 85
 86	pr_info("core voltage initialized to %duV\n", tegra->core_min_uV);
 87
 88	return tegra->core_min_uV;
 89}
 90
 91static int tegra30_core_cpu_limit(int cpu_uV)
 92{
 93	if (cpu_uV < 800000)
 94		return 950000;
 95
 96	if (cpu_uV < 900000)
 97		return 1000000;
 98
 99	if (cpu_uV < 1000000)
100		return 1100000;
101
102	if (cpu_uV < 1100000)
103		return 1200000;
104
105	if (cpu_uV < 1250000) {
106		switch (tegra_sku_info.cpu_speedo_id) {
107		case 0 ... 1:
108		case 4:
109		case 7 ... 8:
110			return 1200000;
111
112		default:
113			return 1300000;
114		}
115	}
116
117	return -EINVAL;
118}
119
120static int tegra30_cpu_nominal_uV(void)
121{
122	switch (tegra_sku_info.cpu_speedo_id) {
123	case 10 ... 11:
124		return  850000;
125
126	case 9:
127		return  912000;
128
129	case 1 ...  3:
130	case 7 ...  8:
131		return 1050000;
132
133	default:
134		return 1125000;
135
136	case  4 ...  6:
137	case 12 ... 13:
138		return 1237000;
139	}
140}
141
142static int tegra30_core_nominal_uV(void)
143{
144	switch (tegra_sku_info.soc_speedo_id) {
145	case 0:
146		return 1200000;
147
148	case 1:
149		if (tegra_sku_info.cpu_speedo_id != 7 &&
150		    tegra_sku_info.cpu_speedo_id != 8)
151			return 1200000;
152
153		fallthrough;
154
155	case 2:
156		if (tegra_sku_info.cpu_speedo_id != 13)
157			return 1300000;
158
159		return 1350000;
160
161	default:
162		return 1250000;
163	}
164}
165
166static int tegra30_voltage_update(struct tegra_regulator_coupler *tegra,
167				  struct regulator_dev *cpu_rdev,
168				  struct regulator_dev *core_rdev)
169{
170	int core_min_uV, core_max_uV = INT_MAX;
171	int cpu_min_uV, cpu_max_uV = INT_MAX;
172	int cpu_min_uV_consumers = 0;
173	int core_min_limited_uV;
174	int core_target_uV;
175	int cpu_target_uV;
176	int core_max_step;
177	int cpu_max_step;
178	int max_spread;
179	int core_uV;
180	int cpu_uV;
181	int err;
182
183	/*
184	 * CPU voltage should not got lower than 300mV from the CORE.
185	 * CPU voltage should stay below the CORE by 100mV+, depending
186	 * by the CORE voltage. This applies to all Tegra30 SoC's.
187	 */
188	max_spread = cpu_rdev->constraints->max_spread[0];
189	cpu_max_step = cpu_rdev->constraints->max_uV_step;
190	core_max_step = core_rdev->constraints->max_uV_step;
191
192	if (!max_spread) {
193		pr_err_once("cpu-core max-spread is undefined in device-tree\n");
194		max_spread = 300000;
195	}
196
197	if (!cpu_max_step) {
198		pr_err_once("cpu max-step is undefined in device-tree\n");
199		cpu_max_step = 150000;
200	}
201
202	if (!core_max_step) {
203		pr_err_once("core max-step is undefined in device-tree\n");
204		core_max_step = 150000;
205	}
206
207	/*
208	 * The CORE voltage scaling is currently not hooked up in drivers,
209	 * hence we will limit the minimum CORE voltage to a reasonable value.
210	 * This should be good enough for the time being.
211	 */
212	core_min_uV = tegra30_core_limit(tegra, core_rdev);
213	if (core_min_uV < 0)
214		return core_min_uV;
215
216	err = regulator_check_consumers(core_rdev, &core_min_uV, &core_max_uV,
217					PM_SUSPEND_ON);
218	if (err)
219		return err;
220
221	/* prepare voltage level for suspend */
222	if (tegra->sys_suspend_mode)
223		core_min_uV = clamp(tegra30_core_nominal_uV(),
224				    core_min_uV, core_max_uV);
225
226	core_uV = regulator_get_voltage_rdev(core_rdev);
227	if (core_uV < 0)
228		return core_uV;
229
230	cpu_min_uV = core_min_uV - max_spread;
231
232	err = regulator_check_consumers(cpu_rdev, &cpu_min_uV, &cpu_max_uV,
233					PM_SUSPEND_ON);
234	if (err)
235		return err;
236
237	err = regulator_check_consumers(cpu_rdev, &cpu_min_uV_consumers,
238					&cpu_max_uV, PM_SUSPEND_ON);
239	if (err)
240		return err;
241
242	err = regulator_check_voltage(cpu_rdev, &cpu_min_uV, &cpu_max_uV);
243	if (err)
244		return err;
245
246	cpu_uV = regulator_get_voltage_rdev(cpu_rdev);
247	if (cpu_uV < 0)
248		return cpu_uV;
249
250	/* store boot voltage level */
251	if (!tegra->cpu_min_uV)
252		tegra->cpu_min_uV = cpu_uV;
253
254	/*
255	 * CPU's regulator may not have any consumers, hence the voltage
256	 * must not be changed in that case because CPU simply won't
257	 * survive the voltage drop if it's running on a higher frequency.
258	 */
259	if (!cpu_min_uV_consumers)
260		cpu_min_uV = max(cpu_uV, cpu_min_uV);
261
262	/*
263	 * Bootloader shall set up voltages correctly, but if it
264	 * happens that there is a violation, then try to fix it
265	 * at first.
266	 */
267	core_min_limited_uV = tegra30_core_cpu_limit(cpu_uV);
268	if (core_min_limited_uV < 0)
269		return core_min_limited_uV;
270
271	core_min_uV = max(core_min_uV, tegra30_core_cpu_limit(cpu_min_uV));
272
273	err = regulator_check_voltage(core_rdev, &core_min_uV, &core_max_uV);
274	if (err)
275		return err;
276
277	/* restore boot voltage level */
278	if (tegra->sys_reboot_mode)
279		cpu_min_uV = max(cpu_min_uV, tegra->cpu_min_uV);
280
281	/* prepare voltage level for suspend */
282	if (tegra->sys_suspend_mode)
283		cpu_min_uV = clamp(tegra30_cpu_nominal_uV(),
284				   cpu_min_uV, cpu_max_uV);
285
286	if (core_min_limited_uV > core_uV) {
287		pr_err("core voltage constraint violated: %d %d %d\n",
288		       core_uV, core_min_limited_uV, cpu_uV);
289		goto update_core;
290	}
291
292	while (cpu_uV != cpu_min_uV || core_uV != core_min_uV) {
293		if (cpu_uV < cpu_min_uV) {
294			cpu_target_uV = min(cpu_uV + cpu_max_step, cpu_min_uV);
295		} else {
296			cpu_target_uV = max(cpu_uV - cpu_max_step, cpu_min_uV);
297			cpu_target_uV = max(core_uV - max_spread, cpu_target_uV);
298		}
299
300		if (cpu_uV == cpu_target_uV)
301			goto update_core;
302
303		err = regulator_set_voltage_rdev(cpu_rdev,
304						 cpu_target_uV,
305						 cpu_max_uV,
306						 PM_SUSPEND_ON);
307		if (err)
308			return err;
309
310		cpu_uV = cpu_target_uV;
311update_core:
312		core_min_limited_uV = tegra30_core_cpu_limit(cpu_uV);
313		if (core_min_limited_uV < 0)
314			return core_min_limited_uV;
315
316		core_target_uV = max(core_min_limited_uV, core_min_uV);
317
318		if (core_uV < core_target_uV) {
319			core_target_uV = min(core_target_uV, core_uV + core_max_step);
320			core_target_uV = min(core_target_uV, cpu_uV + max_spread);
321		} else {
322			core_target_uV = max(core_target_uV, core_uV - core_max_step);
323		}
324
325		if (core_uV == core_target_uV)
326			continue;
327
328		err = regulator_set_voltage_rdev(core_rdev,
329						 core_target_uV,
330						 core_max_uV,
331						 PM_SUSPEND_ON);
332		if (err)
333			return err;
334
335		core_uV = core_target_uV;
336	}
337
338	return 0;
339}
340
341static int tegra30_regulator_balance_voltage(struct regulator_coupler *coupler,
342					     struct regulator_dev *rdev,
343					     suspend_state_t state)
344{
345	struct tegra_regulator_coupler *tegra = to_tegra_coupler(coupler);
346	struct regulator_dev *core_rdev = tegra->core_rdev;
347	struct regulator_dev *cpu_rdev = tegra->cpu_rdev;
348
349	if ((core_rdev != rdev && cpu_rdev != rdev) || state != PM_SUSPEND_ON) {
350		pr_err("regulators are not coupled properly\n");
351		return -EINVAL;
352	}
353
354	tegra->sys_reboot_mode = READ_ONCE(tegra->sys_reboot_mode_req);
355	tegra->sys_suspend_mode = READ_ONCE(tegra->sys_suspend_mode_req);
356
357	return tegra30_voltage_update(tegra, cpu_rdev, core_rdev);
358}
359
360static int tegra30_regulator_prepare_suspend(struct tegra_regulator_coupler *tegra,
361					     bool sys_suspend_mode)
362{
363	int err;
364
365	if (!tegra->core_rdev || !tegra->cpu_rdev)
366		return 0;
367
368	/*
369	 * All power domains are enabled early during resume from suspend
370	 * by GENPD core.  Domains like VENC may require a higher voltage
371	 * when enabled during resume from suspend.  This also prepares
372	 * hardware for resuming from LP0.
373	 */
374
375	WRITE_ONCE(tegra->sys_suspend_mode_req, sys_suspend_mode);
376
377	err = regulator_sync_voltage_rdev(tegra->cpu_rdev);
378	if (err)
379		return err;
380
381	err = regulator_sync_voltage_rdev(tegra->core_rdev);
382	if (err)
383		return err;
384
385	return 0;
386}
387
388static int tegra30_regulator_suspend(struct notifier_block *notifier,
389				     unsigned long mode, void *arg)
390{
391	struct tegra_regulator_coupler *tegra;
392	int ret = 0;
393
394	tegra = container_of(notifier, struct tegra_regulator_coupler,
395			     suspend_notifier);
396
397	switch (mode) {
398	case PM_HIBERNATION_PREPARE:
399	case PM_RESTORE_PREPARE:
400	case PM_SUSPEND_PREPARE:
401		ret = tegra30_regulator_prepare_suspend(tegra, true);
402		break;
403
404	case PM_POST_HIBERNATION:
405	case PM_POST_RESTORE:
406	case PM_POST_SUSPEND:
407		ret = tegra30_regulator_prepare_suspend(tegra, false);
408		break;
409	}
410
411	if (ret)
412		pr_err("failed to prepare regulators: %d\n", ret);
413
414	return notifier_from_errno(ret);
415}
416
417static int tegra30_regulator_prepare_reboot(struct tegra_regulator_coupler *tegra,
418					    bool sys_reboot_mode)
419{
420	int err;
421
422	if (!tegra->core_rdev || !tegra->cpu_rdev)
423		return 0;
424
425	WRITE_ONCE(tegra->sys_reboot_mode_req, true);
426
427	/*
428	 * Some devices use CPU soft-reboot method and in this case we
429	 * should ensure that voltages are sane for the reboot by restoring
430	 * the minimum boot levels.
431	 */
432	err = regulator_sync_voltage_rdev(tegra->cpu_rdev);
433	if (err)
434		return err;
435
436	err = regulator_sync_voltage_rdev(tegra->core_rdev);
437	if (err)
438		return err;
439
440	WRITE_ONCE(tegra->sys_reboot_mode_req, sys_reboot_mode);
441
442	return 0;
443}
444
445static int tegra30_regulator_reboot(struct notifier_block *notifier,
446				    unsigned long event, void *cmd)
447{
448	struct tegra_regulator_coupler *tegra;
449	int ret;
450
451	if (event != SYS_RESTART)
452		return NOTIFY_DONE;
453
454	tegra = container_of(notifier, struct tegra_regulator_coupler,
455			     reboot_notifier);
456
457	ret = tegra30_regulator_prepare_reboot(tegra, true);
458
459	return notifier_from_errno(ret);
460}
461
462static int tegra30_regulator_attach(struct regulator_coupler *coupler,
463				    struct regulator_dev *rdev)
464{
465	struct tegra_regulator_coupler *tegra = to_tegra_coupler(coupler);
466	struct device_node *np = rdev->dev.of_node;
467
468	if (of_property_read_bool(np, "nvidia,tegra-core-regulator") &&
469	    !tegra->core_rdev) {
470		tegra->core_rdev = rdev;
471		return 0;
472	}
473
474	if (of_property_read_bool(np, "nvidia,tegra-cpu-regulator") &&
475	    !tegra->cpu_rdev) {
476		tegra->cpu_rdev = rdev;
477		return 0;
478	}
479
480	return -EINVAL;
481}
482
483static int tegra30_regulator_detach(struct regulator_coupler *coupler,
484				    struct regulator_dev *rdev)
485{
486	struct tegra_regulator_coupler *tegra = to_tegra_coupler(coupler);
487
488	/*
489	 * We don't expect regulators to be decoupled during reboot,
490	 * this may race with the reboot handler and shouldn't ever
491	 * happen in practice.
492	 */
493	if (WARN_ON_ONCE(system_state > SYSTEM_RUNNING))
494		return -EPERM;
495
496	if (tegra->core_rdev == rdev) {
497		tegra->core_rdev = NULL;
498		return 0;
499	}
500
501	if (tegra->cpu_rdev == rdev) {
502		tegra->cpu_rdev = NULL;
503		return 0;
504	}
505
506	return -EINVAL;
507}
508
509static struct tegra_regulator_coupler tegra30_coupler = {
510	.coupler = {
511		.attach_regulator = tegra30_regulator_attach,
512		.detach_regulator = tegra30_regulator_detach,
513		.balance_voltage = tegra30_regulator_balance_voltage,
514	},
515	.reboot_notifier.notifier_call = tegra30_regulator_reboot,
516	.suspend_notifier.notifier_call = tegra30_regulator_suspend,
517};
518
519static int __init tegra_regulator_coupler_init(void)
520{
521	int err;
522
523	if (!of_machine_is_compatible("nvidia,tegra30"))
524		return 0;
525
526	err = register_reboot_notifier(&tegra30_coupler.reboot_notifier);
527	WARN_ON(err);
528
529	err = register_pm_notifier(&tegra30_coupler.suspend_notifier);
530	WARN_ON(err);
531
532	return regulator_coupler_register(&tegra30_coupler.coupler);
533}
534arch_initcall(tegra_regulator_coupler_init);