Skip to content

Commit 5469f16

Browse files
committed
Merge tag 'pm-5.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull power management updates from Rafael Wysocki: "These add some new hardware support (for example, IceLake-D idle states in intel_idle), fix some issues (for example, the handling of negative "sleep length" values in cpuidle governors), add new functionality to the existing drivers (for example, scale-invariance support in the ACPI CPPC cpufreq driver) and clean up code all over. Specifics: - Add idle states table for IceLake-D to the intel_idle driver and update IceLake-X C6 data in it (Artem Bityutskiy). - Fix the C7 idle state on Tegra114 in the tegra cpuidle driver and drop the unused do_idle() firmware call from it (Dmitry Osipenko). - Fix cpuidle-qcom-spm Kconfig entry (He Ying). - Fix handling of possible negative tick_nohz_get_next_hrtimer() return values of in cpuidle governors (Rafael Wysocki). - Add support for frequency-invariance to the ACPI CPPC cpufreq driver and update the frequency-invariance engine (FIE) to use it as needed (Viresh Kumar). - Simplify the default delay_us setting in the ACPI CPPC cpufreq driver (Tom Saeger). - Clean up frequency-related computations in the intel_pstate cpufreq driver (Rafael Wysocki). - Fix TBG parent setting for load levels in the armada-37xx cpufreq driver and drop the CPU PM clock .set_parent method for armada-37xx (Marek Behún). - Fix multiple issues in the armada-37xx cpufreq driver (Pali Rohár). - Fix handling of dev_pm_opp_of_cpumask_add_table() return values in cpufreq-dt to take the -EPROBE_DEFER one into acconut as appropriate (Quanyang Wang). - Fix format string in ia64-acpi-cpufreq (Sergei Trofimovich). - Drop the unused for_each_policy() macro from cpufreq (Shaokun Zhang). - Simplify computations in the schedutil cpufreq governor to avoid unnecessary overhead (Yue Hu). - Fix typos in the s5pv210 cpufreq driver (Bhaskar Chowdhury). - Fix cpufreq documentation links in Kconfig (Alexander Monakov). - Fix PCI device power state handling in pci_enable_device_flags() to avoid issuse in some cases when the device depends on an ACPI power resource (Rafael Wysocki). - Add missing documentation of pm_runtime_resume_and_get() (Alan Stern). - Add missing static inline stub for pm_runtime_has_no_callbacks() to pm_runtime.h and drop the unused try_to_freeze_nowarn() definition (YueHaibing). - Drop duplicate struct device declaration from pm.h and fix a structure type declaration in intel_rapl.h (Wan Jiabing). - Use dev_set_name() instead of an open-coded equivalent of it in the wakeup sources code and drop a redundant local variable initialization from it (Andy Shevchenko, Colin Ian King). - Use crc32 instead of md5 for e820 memory map integrity check during resume from hibernation on x86 (Chris von Recklinghausen). - Fix typos in comments in the system-wide and hibernation support code (Lu Jialin). - Modify the generic power domains (genpd) code to avoid resuming devices in the "prepare" phase of system-wide suspend and hibernation (Ulf Hansson). - Add Hygon Fam18h RAPL support to the intel_rapl power capping driver (Pu Wen). - Add MAINTAINERS entry for the dynamic thermal power management (DTPM) code (Daniel Lezcano). - Add devm variants of operating performance points (OPP) API functions and switch over some users of the OPP framework to the new resource-managed API (Yangtao Li and Dmitry Osipenko). - Update devfreq core: * Register devfreq devices as cooling devices on demand (Daniel Lezcano). * Add missing unlock opeation in devfreq_add_device() (Lukasz Luba). * Use the next frequency as resume_freq instead of the previous frequency when using the opp-suspend property (Dong Aisheng). * Check get_dev_status in devfreq_update_stats() (Dong Aisheng). * Fix set_freq path for the userspace governor in Kconfig (Dong Aisheng). * Remove invalid description of get_target_freq() (Dong Aisheng). - Update devfreq drivers: * imx8m-ddrc: Remove imx8m_ddrc_get_dev_status() and unneeded of_match_ptr() (Dong Aisheng, Fabio Estevam). * rk3399_dmc: dt-bindings: Add rockchip,pmu phandle and drop references to undefined symbols (Enric Balletbo i Serra, Gaël PORTAY). * rk3399_dmc: Use dev_err_probe() to simplify the code (Krzysztof Kozlowski). * imx-bus: Remove unneeded of_match_ptr() (Fabio Estevam). - Fix kernel-doc warnings in three places (Pierre-Louis Bossart). - Fix typo in the pm-graph utility code (Ricardo Ribalda)" * tag 'pm-5.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (74 commits) PM: wakeup: remove redundant assignment to variable retval PM: hibernate: x86: Use crc32 instead of md5 for hibernation e820 integrity check cpufreq: Kconfig: fix documentation links PM: wakeup: use dev_set_name() directly PM: runtime: Add documentation for pm_runtime_resume_and_get() cpufreq: intel_pstate: Simplify intel_pstate_update_perf_limits() cpufreq: armada-37xx: Fix module unloading cpufreq: armada-37xx: Remove cur_frequency variable cpufreq: armada-37xx: Fix determining base CPU frequency cpufreq: armada-37xx: Fix driver cleanup when registration failed clk: mvebu: armada-37xx-periph: Fix workaround for switching from L1 to L0 clk: mvebu: armada-37xx-periph: Fix switching CPU freq from 250 Mhz to 1 GHz cpufreq: armada-37xx: Fix the AVS value for load L1 clk: mvebu: armada-37xx-periph: remove .set_parent method for CPU PM clock cpufreq: armada-37xx: Fix setting TBG parent for load levels cpuidle: Fix ARM_QCOM_SPM_CPUIDLE configuration cpuidle: tegra: Remove do_idle firmware call cpuidle: tegra: Fix C7 idling state on Tegra114 PM: sleep: fix typos in comments cpufreq: Remove unused for_each_policy macro ...
2 parents d8f9176 + 59e2c95 commit 5469f16

66 files changed

Lines changed: 996 additions & 722 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Documentation/ABI/testing/sysfs-class-devfreq

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -97,10 +97,7 @@ Description:
9797
object. The values are represented in ms. If the value is
9898
less than 1 jiffy, it is considered to be 0, which means
9999
no polling. This value is meaningless if the governor is
100-
not polling; thus. If the governor is not using
101-
devfreq-provided central polling
102-
(/sys/class/devfreq/.../central_polling is 0), this value
103-
may be useless.
100+
not polling.
104101

105102
A list of governors that support the node:
106103
- simple_ondmenad

Documentation/devicetree/bindings/devfreq/rk3399_dmc.txt

Lines changed: 36 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ Required properties:
1212
for details.
1313
- center-supply: DMC supply node.
1414
- status: Marks the node enabled/disabled.
15+
- rockchip,pmu: Phandle to the syscon managing the "PMU general register
16+
files".
1517

1618
Optional properties:
1719
- interrupts: The CPU interrupt number. The interrupt specifier
@@ -77,24 +79,23 @@ Following properties relate to DDR timing:
7779

7880
- rockchip,ddr3_drv : When the DRAM type is DDR3, this parameter defines
7981
the DRAM side driver strength in ohms. Default
80-
value is DDR3_DS_40ohm.
82+
value is 40.
8183

8284
- rockchip,ddr3_odt : When the DRAM type is DDR3, this parameter defines
8385
the DRAM side ODT strength in ohms. Default value
84-
is DDR3_ODT_120ohm.
86+
is 120.
8587

8688
- rockchip,phy_ddr3_ca_drv : When the DRAM type is DDR3, this parameter defines
8789
the phy side CA line (incluing command line,
8890
address line and clock line) driver strength.
89-
Default value is PHY_DRV_ODT_40.
91+
Default value is 40.
9092

9193
- rockchip,phy_ddr3_dq_drv : When the DRAM type is DDR3, this parameter defines
9294
the PHY side DQ line (including DQS/DQ/DM line)
93-
driver strength. Default value is PHY_DRV_ODT_40.
95+
driver strength. Default value is 40.
9496

9597
- rockchip,phy_ddr3_odt : When the DRAM type is DDR3, this parameter defines
96-
the PHY side ODT strength. Default value is
97-
PHY_DRV_ODT_240.
98+
the PHY side ODT strength. Default value is 240.
9899

99100
- rockchip,lpddr3_odt_dis_freq : When the DRAM type is LPDDR3, this parameter defines
100101
then ODT disable frequency in MHz (Mega Hz).
@@ -104,25 +105,23 @@ Following properties relate to DDR timing:
104105

105106
- rockchip,lpddr3_drv : When the DRAM type is LPDDR3, this parameter defines
106107
the DRAM side driver strength in ohms. Default
107-
value is LP3_DS_34ohm.
108+
value is 34.
108109

109110
- rockchip,lpddr3_odt : When the DRAM type is LPDDR3, this parameter defines
110111
the DRAM side ODT strength in ohms. Default value
111-
is LP3_ODT_240ohm.
112+
is 240.
112113

113114
- rockchip,phy_lpddr3_ca_drv : When the DRAM type is LPDDR3, this parameter defines
114115
the PHY side CA line (including command line,
115116
address line and clock line) driver strength.
116-
Default value is PHY_DRV_ODT_40.
117+
Default value is 40.
117118

118119
- rockchip,phy_lpddr3_dq_drv : When the DRAM type is LPDDR3, this parameter defines
119120
the PHY side DQ line (including DQS/DQ/DM line)
120-
driver strength. Default value is
121-
PHY_DRV_ODT_40.
121+
driver strength. Default value is 40.
122122

123123
- rockchip,phy_lpddr3_odt : When dram type is LPDDR3, this parameter define
124-
the phy side odt strength, default value is
125-
PHY_DRV_ODT_240.
124+
the phy side odt strength, default value is 240.
126125

127126
- rockchip,lpddr4_odt_dis_freq : When the DRAM type is LPDDR4, this parameter
128127
defines the ODT disable frequency in
@@ -132,32 +131,30 @@ Following properties relate to DDR timing:
132131

133132
- rockchip,lpddr4_drv : When the DRAM type is LPDDR4, this parameter defines
134133
the DRAM side driver strength in ohms. Default
135-
value is LP4_PDDS_60ohm.
134+
value is 60.
136135

137136
- rockchip,lpddr4_dq_odt : When the DRAM type is LPDDR4, this parameter defines
138137
the DRAM side ODT on DQS/DQ line strength in ohms.
139-
Default value is LP4_DQ_ODT_40ohm.
138+
Default value is 40.
140139

141140
- rockchip,lpddr4_ca_odt : When the DRAM type is LPDDR4, this parameter defines
142141
the DRAM side ODT on CA line strength in ohms.
143-
Default value is LP4_CA_ODT_40ohm.
142+
Default value is 40.
144143

145144
- rockchip,phy_lpddr4_ca_drv : When the DRAM type is LPDDR4, this parameter defines
146145
the PHY side CA line (including command address
147-
line) driver strength. Default value is
148-
PHY_DRV_ODT_40.
146+
line) driver strength. Default value is 40.
149147

150148
- rockchip,phy_lpddr4_ck_cs_drv : When the DRAM type is LPDDR4, this parameter defines
151149
the PHY side clock line and CS line driver
152-
strength. Default value is PHY_DRV_ODT_80.
150+
strength. Default value is 80.
153151

154152
- rockchip,phy_lpddr4_dq_drv : When the DRAM type is LPDDR4, this parameter defines
155153
the PHY side DQ line (including DQS/DQ/DM line)
156-
driver strength. Default value is PHY_DRV_ODT_80.
154+
driver strength. Default value is 80.
157155

158156
- rockchip,phy_lpddr4_odt : When the DRAM type is LPDDR4, this parameter defines
159-
the PHY side ODT strength. Default value is
160-
PHY_DRV_ODT_60.
157+
the PHY side ODT strength. Default value is 60.
161158

162159
Example:
163160
dmc_opp_table: dmc_opp_table {
@@ -193,23 +190,23 @@ Example:
193190
rockchip,phy_dll_dis_freq = <125>;
194191
rockchip,auto_pd_dis_freq = <666>;
195192
rockchip,ddr3_odt_dis_freq = <333>;
196-
rockchip,ddr3_drv = <DDR3_DS_40ohm>;
197-
rockchip,ddr3_odt = <DDR3_ODT_120ohm>;
198-
rockchip,phy_ddr3_ca_drv = <PHY_DRV_ODT_40>;
199-
rockchip,phy_ddr3_dq_drv = <PHY_DRV_ODT_40>;
200-
rockchip,phy_ddr3_odt = <PHY_DRV_ODT_240>;
193+
rockchip,ddr3_drv = <40>;
194+
rockchip,ddr3_odt = <120>;
195+
rockchip,phy_ddr3_ca_drv = <40>;
196+
rockchip,phy_ddr3_dq_drv = <40>;
197+
rockchip,phy_ddr3_odt = <240>;
201198
rockchip,lpddr3_odt_dis_freq = <333>;
202-
rockchip,lpddr3_drv = <LP3_DS_34ohm>;
203-
rockchip,lpddr3_odt = <LP3_ODT_240ohm>;
204-
rockchip,phy_lpddr3_ca_drv = <PHY_DRV_ODT_40>;
205-
rockchip,phy_lpddr3_dq_drv = <PHY_DRV_ODT_40>;
206-
rockchip,phy_lpddr3_odt = <PHY_DRV_ODT_240>;
199+
rockchip,lpddr3_drv = <34>;
200+
rockchip,lpddr3_odt = <240>;
201+
rockchip,phy_lpddr3_ca_drv = <40>;
202+
rockchip,phy_lpddr3_dq_drv = <40>;
203+
rockchip,phy_lpddr3_odt = <240>;
207204
rockchip,lpddr4_odt_dis_freq = <333>;
208-
rockchip,lpddr4_drv = <LP4_PDDS_60ohm>;
209-
rockchip,lpddr4_dq_odt = <LP4_DQ_ODT_40ohm>;
210-
rockchip,lpddr4_ca_odt = <LP4_CA_ODT_40ohm>;
211-
rockchip,phy_lpddr4_ca_drv = <PHY_DRV_ODT_40>;
212-
rockchip,phy_lpddr4_ck_cs_drv = <PHY_DRV_ODT_80>;
213-
rockchip,phy_lpddr4_dq_drv = <PHY_DRV_ODT_80>;
214-
rockchip,phy_lpddr4_odt = <PHY_DRV_ODT_60>;
205+
rockchip,lpddr4_drv = <60>;
206+
rockchip,lpddr4_dq_odt = <40>;
207+
rockchip,lpddr4_ca_odt = <40>;
208+
rockchip,phy_lpddr4_ca_drv = <40>;
209+
rockchip,phy_lpddr4_ck_cs_drv = <80>;
210+
rockchip,phy_lpddr4_dq_drv = <80>;
211+
rockchip,phy_lpddr4_odt = <60>;
215212
};

Documentation/power/runtime_pm.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,10 @@ drivers/base/power/runtime.c and include/linux/pm_runtime.h:
339339
checked additionally, and -EACCES means that 'power.disable_depth' is
340340
different from 0
341341

342+
`int pm_runtime_resume_and_get(struct device *dev);`
343+
- run pm_runtime_resume(dev) and if successful, increment the device's
344+
usage counter; return the result of pm_runtime_resume
345+
342346
`int pm_request_idle(struct device *dev);`
343347
- submit a request to execute the subsystem-level idle callback for the
344348
device (the request is represented by a work item in pm_wq); returns 0 on

MAINTAINERS

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14439,6 +14439,15 @@ F: include/linux/pm_*
1443914439
F: include/linux/powercap.h
1444014440
F: kernel/configs/nopm.config
1444114441

14442+
DYNAMIC THERMAL POWER MANAGEMENT (DTPM)
14443+
M: Daniel Lezcano <daniel.lezcano@kernel.org>
14444+
L: linux-pm@vger.kernel.org
14445+
S: Supported
14446+
B: https://bugzilla.kernel.org
14447+
T: git git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
14448+
F: drivers/powercap/dtpm*
14449+
F: include/linux/dtpm.h
14450+
1444214451
POWER STATE COORDINATION INTERFACE (PSCI)
1444314452
M: Mark Rutland <mark.rutland@arm.com>
1444414453
M: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>

arch/arm64/include/asm/topology.h

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,9 @@ int pcibus_to_node(struct pci_bus *bus);
1717
#include <linux/arch_topology.h>
1818

1919
void update_freq_counters_refs(void);
20-
void topology_scale_freq_tick(void);
21-
22-
#ifdef CONFIG_ARM64_AMU_EXTN
23-
/*
24-
* Replace task scheduler's default counter-based
25-
* frequency-invariance scale factor setting.
26-
*/
27-
#define arch_scale_freq_tick topology_scale_freq_tick
28-
#endif /* CONFIG_ARM64_AMU_EXTN */
2920

3021
/* Replace task scheduler's default frequency-invariant accounting */
22+
#define arch_scale_freq_tick topology_scale_freq_tick
3123
#define arch_set_freq_scale topology_set_freq_scale
3224
#define arch_scale_freq_capacity topology_get_freq_scale
3325
#define arch_scale_freq_invariant topology_scale_freq_invariant

arch/arm64/kernel/topology.c

Lines changed: 41 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -199,12 +199,47 @@ static int freq_inv_set_max_ratio(int cpu, u64 max_rate, u64 ref_rate)
199199
return 0;
200200
}
201201

202-
static DEFINE_STATIC_KEY_FALSE(amu_fie_key);
203-
#define amu_freq_invariant() static_branch_unlikely(&amu_fie_key)
202+
static void amu_scale_freq_tick(void)
203+
{
204+
u64 prev_core_cnt, prev_const_cnt;
205+
u64 core_cnt, const_cnt, scale;
206+
207+
prev_const_cnt = this_cpu_read(arch_const_cycles_prev);
208+
prev_core_cnt = this_cpu_read(arch_core_cycles_prev);
209+
210+
update_freq_counters_refs();
211+
212+
const_cnt = this_cpu_read(arch_const_cycles_prev);
213+
core_cnt = this_cpu_read(arch_core_cycles_prev);
214+
215+
if (unlikely(core_cnt <= prev_core_cnt ||
216+
const_cnt <= prev_const_cnt))
217+
return;
218+
219+
/*
220+
* /\core arch_max_freq_scale
221+
* scale = ------- * --------------------
222+
* /\const SCHED_CAPACITY_SCALE
223+
*
224+
* See validate_cpu_freq_invariance_counters() for details on
225+
* arch_max_freq_scale and the use of SCHED_CAPACITY_SHIFT.
226+
*/
227+
scale = core_cnt - prev_core_cnt;
228+
scale *= this_cpu_read(arch_max_freq_scale);
229+
scale = div64_u64(scale >> SCHED_CAPACITY_SHIFT,
230+
const_cnt - prev_const_cnt);
231+
232+
scale = min_t(unsigned long, scale, SCHED_CAPACITY_SCALE);
233+
this_cpu_write(arch_freq_scale, (unsigned long)scale);
234+
}
235+
236+
static struct scale_freq_data amu_sfd = {
237+
.source = SCALE_FREQ_SOURCE_ARCH,
238+
.set_freq_scale = amu_scale_freq_tick,
239+
};
204240

205241
static void amu_fie_setup(const struct cpumask *cpus)
206242
{
207-
bool invariant;
208243
int cpu;
209244

210245
/* We are already set since the last insmod of cpufreq driver */
@@ -221,25 +256,10 @@ static void amu_fie_setup(const struct cpumask *cpus)
221256

222257
cpumask_or(amu_fie_cpus, amu_fie_cpus, cpus);
223258

224-
invariant = topology_scale_freq_invariant();
225-
226-
/* We aren't fully invariant yet */
227-
if (!invariant && !cpumask_equal(amu_fie_cpus, cpu_present_mask))
228-
return;
229-
230-
static_branch_enable(&amu_fie_key);
259+
topology_set_scale_freq_source(&amu_sfd, amu_fie_cpus);
231260

232261
pr_debug("CPUs[%*pbl]: counters will be used for FIE.",
233262
cpumask_pr_args(cpus));
234-
235-
/*
236-
* Task scheduler behavior depends on frequency invariance support,
237-
* either cpufreq or counter driven. If the support status changes as
238-
* a result of counter initialisation and use, retrigger the build of
239-
* scheduling domains to ensure the information is propagated properly.
240-
*/
241-
if (!invariant)
242-
rebuild_sched_domains_energy();
243263
}
244264

245265
static int init_amu_fie_callback(struct notifier_block *nb, unsigned long val,
@@ -256,8 +276,8 @@ static int init_amu_fie_callback(struct notifier_block *nb, unsigned long val,
256276
* initialized AMU support and enabled invariance. The AMU counters will
257277
* keep on working just fine in the absence of the cpufreq driver, and
258278
* for the CPUs for which there are no counters available, the last set
259-
* value of freq_scale will remain valid as that is the frequency those
260-
* CPUs are running at.
279+
* value of arch_freq_scale will remain valid as that is the frequency
280+
* those CPUs are running at.
261281
*/
262282

263283
return 0;
@@ -283,53 +303,6 @@ static int __init init_amu_fie(void)
283303
}
284304
core_initcall(init_amu_fie);
285305

286-
bool arch_freq_counters_available(const struct cpumask *cpus)
287-
{
288-
return amu_freq_invariant() &&
289-
cpumask_subset(cpus, amu_fie_cpus);
290-
}
291-
292-
void topology_scale_freq_tick(void)
293-
{
294-
u64 prev_core_cnt, prev_const_cnt;
295-
u64 core_cnt, const_cnt, scale;
296-
int cpu = smp_processor_id();
297-
298-
if (!amu_freq_invariant())
299-
return;
300-
301-
if (!cpumask_test_cpu(cpu, amu_fie_cpus))
302-
return;
303-
304-
prev_const_cnt = this_cpu_read(arch_const_cycles_prev);
305-
prev_core_cnt = this_cpu_read(arch_core_cycles_prev);
306-
307-
update_freq_counters_refs();
308-
309-
const_cnt = this_cpu_read(arch_const_cycles_prev);
310-
core_cnt = this_cpu_read(arch_core_cycles_prev);
311-
312-
if (unlikely(core_cnt <= prev_core_cnt ||
313-
const_cnt <= prev_const_cnt))
314-
return;
315-
316-
/*
317-
* /\core arch_max_freq_scale
318-
* scale = ------- * --------------------
319-
* /\const SCHED_CAPACITY_SCALE
320-
*
321-
* See validate_cpu_freq_invariance_counters() for details on
322-
* arch_max_freq_scale and the use of SCHED_CAPACITY_SHIFT.
323-
*/
324-
scale = core_cnt - prev_core_cnt;
325-
scale *= this_cpu_read(arch_max_freq_scale);
326-
scale = div64_u64(scale >> SCHED_CAPACITY_SHIFT,
327-
const_cnt - prev_const_cnt);
328-
329-
scale = min_t(unsigned long, scale, SCHED_CAPACITY_SCALE);
330-
this_cpu_write(freq_scale, (unsigned long)scale);
331-
}
332-
333306
#ifdef CONFIG_ACPI_CPPC_LIB
334307
#include <acpi/cppc_acpi.h>
335308

arch/x86/kernel/e820.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@
3131
* - inform the user about the firmware's notion of memory layout
3232
* via /sys/firmware/memmap
3333
*
34-
* - the hibernation code uses it to generate a kernel-independent MD5
35-
* fingerprint of the physical memory layout of a system.
34+
* - the hibernation code uses it to generate a kernel-independent CRC32
35+
* checksum of the physical memory layout of a system.
3636
*
3737
* - 'e820_table_kexec': a slightly modified (by the kernel) firmware version
3838
* passed to us by the bootloader - the major difference between

0 commit comments

Comments
 (0)