Skip to content

Commit d0a231f

Browse files
committed
Merge tag 'pci-v5.17-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci
Pull pci updates from Bjorn Helgaas: "Enumeration: - Use pci_find_vsec_capability() instead of open-coding it (Andy Shevchenko) - Convert pci_dev_present() stub from macro to static inline to avoid 'unused variable' errors (Hans de Goede) - Convert sysfs slot attributes from default_attrs to default_groups (Greg Kroah-Hartman) - Use DWORD accesses for LTR, L1 SS to avoid BayHub OZ711LV2 erratum (Rajat Jain) - Remove unnecessary initialization of static variables (Longji Guo) Resource management: - Always write Intel I210 ROM BAR on update to work around device defect (Bjorn Helgaas) PCIe native device hotplug: - Fix pciehp lockdep errors on Thunderbolt undock (Hans de Goede) - Fix infinite loop in pciehp IRQ handler on power fault (Lukas Wunner) Power management: - Convert amd64-agp, sis-agp, via-agp from legacy PCI power management to generic power management (Vaibhav Gupta) IOMMU: - Add function 1 DMA alias quirk for Marvell 88SE9125 SATA controller so it can work with an IOMMU (Yifeng Li) Error handling: - Add PCI_ERROR_RESPONSE and related definitions for signaling and checking for transaction errors on PCI (Naveen Naidu) - Fabricate PCI_ERROR_RESPONSE data (~0) in config read wrappers, instead of in host controller drivers, when transactions fail on PCI (Naveen Naidu) - Use PCI_POSSIBLE_ERROR() to check for possible failure of config reads (Naveen Naidu) Peer-to-peer DMA: - Add Logan Gunthorpe as P2PDMA maintainer (Bjorn Helgaas) ASPM: - Calculate link L0s and L1 exit latencies when needed instead of caching them (Saheed O. Bolarinwa) - Calculate device L0s and L1 acceptable exit latencies when needed instead of caching them (Saheed O. Bolarinwa) - Remove struct aspm_latency since it's no longer needed (Saheed O. Bolarinwa) APM X-Gene PCIe controller driver: - Fix IB window setup, which was broken by the fact that IB resources are now sorted in address order instead of DT dma-ranges order (Rob Herring) Apple PCIe controller driver: - Enable clock gating to save power (Hector Martin) - Fix REFCLK1 enable/poll logic (Hector Martin) Broadcom STB PCIe controller driver: - Declare bitmap correctly for use by bitmap interfaces (Christophe JAILLET) - Clean up computation of legacy and non-legacy MSI bitmasks (Florian Fainelli) - Update suspend/resume/remove error handling to warn about errors and not fail the operation (Jim Quinlan) - Correct the "pcie" and "msi" interrupt descriptions in DT binding (Jim Quinlan) - Add DT bindings for endpoint voltage regulators (Jim Quinlan) - Split brcm_pcie_setup() into two functions (Jim Quinlan) - Add mechanism for turning on voltage regulators for connected devices (Jim Quinlan) - Turn voltage regulators for connected devices on/off when bus is added or removed (Jim Quinlan) - When suspending, don't turn off voltage regulators for wakeup devices (Jim Quinlan) Freescale i.MX6 PCIe controller driver: - Add i.MX8MM support (Richard Zhu) Freescale Layerscape PCIe controller driver: - Use DWC common ops instead of layerscape-specific link-up functions (Hou Zhiqiang) Intel VMD host bridge driver: - Honor platform ACPI _OSC feature negotiation for Root Ports below VMD (Kai-Heng Feng) - Add support for Raptor Lake SKUs (Karthik L Gopalakrishnan) - Reset everything below VMD before enumerating to work around failure to enumerate NVMe devices when guest OS reboots (Nirmal Patel) Bridge emulation (used by Marvell Aardvark and MVEBU): - Make emulated ROM BAR read-only by default (Pali Rohár) - Make some emulated legacy PCI bits read-only for PCIe devices (Pali Rohár) - Update reserved bits in emulated PCIe Capability (Pali Rohár) - Allow drivers to emulate different PCIe Capability versions (Pali Rohár) - Set emulated Capabilities List bit for all PCIe devices, since they must have at least a PCIe Capability (Pali Rohár) Marvell Aardvark PCIe controller driver: - Add bridge emulation definitions for PCIe DEVCAP2, DEVCTL2, DEVSTA2, LNKCAP2, LNKCTL2, LNKSTA2, SLTCAP2, SLTCTL2, SLTSTA2 (Pali Rohár) - Add aardvark support for DEVCAP2, DEVCTL2, LNKCAP2 and LNKCTL2 registers (Pali Rohár) - Clear all MSIs at setup to avoid spurious interrupts (Pali Rohár) - Disable bus mastering when unbinding host controller driver (Pali Rohár) - Mask all interrupts when unbinding host controller driver (Pali Rohár) - Fix memory leak in host controller unbind (Pali Rohár) - Assert PERST# when unbinding host controller driver (Pali Rohár) - Disable link training when unbinding host controller driver (Pali Rohár) - Disable common PHY when unbinding host controller driver (Pali Rohár) - Fix resource type checking to check only IORESOURCE_MEM, not IORESOURCE_MEM_64, which is a flavor of IORESOURCE_MEM (Pali Rohár) Marvell MVEBU PCIe controller driver: - Implement pci_remap_iospace() for ARM so mvebu can use devm_pci_remap_iospace() instead of the previous ARM-specific pci_ioremap_io() interface (Pali Rohár) - Use the standard pci_host_probe() instead of the device-specific mvebu_pci_host_probe() (Pali Rohár) - Replace all uses of ARM-specific pci_ioremap_io() with the ARM implementation of the standard pci_remap_iospace() interface and remove pci_ioremap_io() (Pali Rohár) - Skip initializing invalid Root Ports (Pali Rohár) - Check for errors from pci_bridge_emul_init() (Pali Rohár) - Ignore any bridges at non-zero function numbers (Pali Rohár) - Return ~0 data for invalid config read size (Pali Rohár) - Disallow mapping interrupts on emulated bridges (Pali Rohár) - Clear Root Port Memory & I/O Space Enable and Bus Master Enable at initialization (Pali Rohár) - Make type bits in Root Port I/O Base register read-only (Pali Rohár) - Disable Root Port windows when base/limit set to invalid values (Pali Rohár) - Set controller to Root Complex mode (Pali Rohár) - Set Root Port Class Code to PCI Bridge (Pali Rohár) - Update emulated Root Port secondary bus numbers to better reflect the actual topology (Pali Rohár) - Add PCI_BRIDGE_CTL_BUS_RESET support to emulated Root Ports so pci_reset_secondary_bus() can reset connected devices (Pali Rohár) - Add PCI_EXP_DEVCTL Error Reporting Enable support to emulated Root Ports (Pali Rohár) - Add PCI_EXP_RTSTA PME Status bit support to emulated Root Ports (Pali Rohár) - Add DEVCAP2, DEVCTL2 and LNKCTL2 support to emulated Root Ports on Armada XP and newer devices (Pali Rohár) - Export mvebu-mbus.c symbols to allow pci-mvebu.c to be a module (Pali Rohár) - Add support for compiling as a module (Pali Rohár) MediaTek PCIe controller driver: - Assert PERST# for 100ms to allow power and clock to stabilize (qizhong cheng) MediaTek PCIe Gen3 controller driver: - Disable Mediatek DVFSRC voltage request since lack of DVFSRC to respond to the request causes failure to exit L1 PM Substate (Jianjun Wang) MediaTek MT7621 PCIe controller driver: - Declare mt7621_pci_ops static (Sergio Paracuellos) - Give pcibios_root_bridge_prepare() access to host bridge windows (Sergio Paracuellos) - Move MIPS I/O coherency unit setup from driver to pcibios_root_bridge_prepare() (Sergio Paracuellos) - Add missing MODULE_LICENSE() (Sergio Paracuellos) - Allow COMPILE_TEST for all arches (Sergio Paracuellos) Microsoft Hyper-V host bridge driver: - Add hv-internal interfaces to encapsulate arch IRQ dependencies (Sunil Muthuswamy) - Add arm64 Hyper-V vPCI support (Sunil Muthuswamy) Qualcomm PCIe controller driver: - Undo PM setup in qcom_pcie_probe() error handling path (Christophe JAILLET) - Use __be16 type to store return value from cpu_to_be16() (Manivannan Sadhasivam) - Constify static dw_pcie_ep_ops (Rikard Falkeborn) Renesas R-Car PCIe controller driver: - Fix aarch32 abort handler so it doesn't check the wrong bus clock before accessing the host controller (Marek Vasut) TI Keystone PCIe controller driver: - Add register offset for ti,syscon-pcie-id and ti,syscon-pcie-mode DT properties (Kishon Vijay Abraham I) MicroSemi Switchtec management driver: - Add Gen4 automotive device IDs (Kelvin Cao) - Declare state_names[] as static so it's not allocated and initialized for every call (Kelvin Cao) Host controller driver cleanups: - Use of_device_get_match_data(), not of_match_device(), when we only need the device data in altera, artpec6, cadence, designware-plat, dra7xx, keystone, kirin (Fan Fei) - Drop pointless of_device_get_match_data() cast in j721e (Bjorn Helgaas) - Drop redundant struct device * from j721e since struct cdns_pcie already has one (Bjorn Helgaas) - Rename driver structs to *_pcie in intel-gw, iproc, ls-gen4, mediatek-gen3, microchip, mt7621, rcar-gen2, tegra194, uniphier, xgene, xilinx, xilinx-cpm for consistency across drivers (Fan Fei) - Fix invalid address space conversions in hisi, spear13xx (Bjorn Helgaas) Miscellaneous: - Sort Intel Device IDs by value (Andy Shevchenko) - Change Capability offsets to hex to match spec (Baruch Siach) - Correct misspellings (Krzysztof Wilczyński) - Terminate statement with semicolon in pci_endpoint_test.c (Ming Wang)" * tag 'pci-v5.17-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci: (151 commits) PCI: mt7621: Allow COMPILE_TEST for all arches PCI: mt7621: Add missing MODULE_LICENSE() PCI: mt7621: Move MIPS setup to pcibios_root_bridge_prepare() PCI: Let pcibios_root_bridge_prepare() access bridge->windows PCI: mt7621: Declare mt7621_pci_ops static PCI: brcmstb: Do not turn off WOL regulators on suspend PCI: brcmstb: Add control of subdevice voltage regulators PCI: brcmstb: Add mechanism to turn on subdev regulators PCI: brcmstb: Split brcm_pcie_setup() into two funcs dt-bindings: PCI: Add bindings for Brcmstb EP voltage regulators dt-bindings: PCI: Correct brcmstb interrupts, interrupt-map. PCI: brcmstb: Fix function return value handling PCI: brcmstb: Do not use __GENMASK PCI: brcmstb: Declare 'used' as bitmap, not unsigned long PCI: hv: Add arm64 Hyper-V vPCI support PCI: hv: Make the code arch neutral by adding arch specific interfaces PCI: pciehp: Use down_read/write_nested(reset_lock) to fix lockdep errors x86/PCI: Remove initialization of static variables to false PCI: Use DWORD accesses for LTR, L1 SS to avoid erratum misc: pci_endpoint_test: Terminate statement with semicolon ...
2 parents 88db845 + 87c7193 commit d0a231f

File tree

94 files changed

+2613
-1734
lines changed

Some content is hidden

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

94 files changed

+2613
-1734
lines changed

Documentation/devicetree/bindings/pci/brcm,stb-pcie.yaml

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -146,17 +146,40 @@ examples:
146146
#address-cells = <3>;
147147
#size-cells = <2>;
148148
#interrupt-cells = <1>;
149-
interrupts = <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>,
149+
interrupts = <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>,
150150
<GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>;
151151
interrupt-names = "pcie", "msi";
152152
interrupt-map-mask = <0x0 0x0 0x0 0x7>;
153-
interrupt-map = <0 0 0 1 &gicv2 GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>;
153+
interrupt-map = <0 0 0 1 &gicv2 GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH
154+
0 0 0 2 &gicv2 GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH
155+
0 0 0 3 &gicv2 GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH
156+
0 0 0 4 &gicv2 GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>;
157+
154158
msi-parent = <&pcie0>;
155159
msi-controller;
156160
ranges = <0x02000000 0x0 0xf8000000 0x6 0x00000000 0x0 0x04000000>;
157161
dma-ranges = <0x42000000 0x1 0x00000000 0x0 0x40000000 0x0 0x80000000>,
158162
<0x42000000 0x1 0x80000000 0x3 0x00000000 0x0 0x80000000>;
159163
brcm,enable-ssc;
160164
brcm,scb-sizes = <0x0000000080000000 0x0000000080000000>;
165+
166+
/* PCIe bridge, Root Port */
167+
pci@0,0 {
168+
#address-cells = <3>;
169+
#size-cells = <2>;
170+
reg = <0x0 0x0 0x0 0x0 0x0>;
171+
compatible = "pciclass,0604";
172+
device_type = "pci";
173+
vpcie3v3-supply = <&vreg7>;
174+
ranges;
175+
176+
/* PCIe endpoint */
177+
pci-ep@0,0 {
178+
assigned-addresses =
179+
<0x82010000 0x0 0xf8000000 0x6 0x00000000 0x0 0x2000>;
180+
reg = <0x0 0x0 0x0 0x0 0x0>;
181+
compatible = "pci14e4,1688";
182+
};
183+
};
161184
};
162185
};

Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,12 @@ properties:
127127
enum: [1, 2, 3, 4]
128128
default: 1
129129

130+
phys:
131+
maxItems: 1
132+
133+
phy-names:
134+
const: pcie-phy
135+
130136
reset-gpio:
131137
description: Should specify the GPIO for controlling the PCI bus device
132138
reset signal. It's not polarity aware and defaults to active-low reset

Documentation/devicetree/bindings/pci/ti,am65-pci-ep.yaml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,12 @@ properties:
3232
maxItems: 1
3333

3434
ti,syscon-pcie-mode:
35+
$ref: /schemas/types.yaml#/definitions/phandle-array
36+
items:
37+
- items:
38+
- description: Phandle to the SYSCON entry
39+
- description: pcie_ctrl register offset within SYSCON
3540
description: Phandle to the SYSCON entry required for configuring PCIe in RC or EP mode.
36-
$ref: /schemas/types.yaml#/definitions/phandle
3741

3842
interrupts:
3943
minItems: 1
@@ -65,7 +69,7 @@ examples:
6569
<0x5506000 0x1000>;
6670
reg-names = "app", "dbics", "addr_space", "atu";
6771
power-domains = <&k3_pds 120 TI_SCI_PD_EXCLUSIVE>;
68-
ti,syscon-pcie-mode = <&pcie0_mode>;
72+
ti,syscon-pcie-mode = <&scm_conf 0x4060>;
6973
max-link-speed = <2>;
7074
dma-coherent;
7175
interrupts = <GIC_SPI 340 IRQ_TYPE_EDGE_RISING>;

Documentation/devicetree/bindings/pci/ti,am65-pci-host.yaml

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,20 @@ properties:
3636
maxItems: 1
3737

3838
ti,syscon-pcie-id:
39+
$ref: /schemas/types.yaml#/definitions/phandle-array
40+
items:
41+
- items:
42+
- description: Phandle to the SYSCON entry
43+
- description: pcie_device_id register offset within SYSCON
3944
description: Phandle to the SYSCON entry required for getting PCIe device/vendor ID
40-
$ref: /schemas/types.yaml#/definitions/phandle
4145

4246
ti,syscon-pcie-mode:
47+
$ref: /schemas/types.yaml#/definitions/phandle-array
48+
items:
49+
- items:
50+
- description: Phandle to the SYSCON entry
51+
- description: pcie_ctrl register offset within SYSCON
4352
description: Phandle to the SYSCON entry required for configuring PCIe in RC or EP mode.
44-
$ref: /schemas/types.yaml#/definitions/phandle
4553

4654
msi-map: true
4755

@@ -87,8 +95,8 @@ examples:
8795
#size-cells = <2>;
8896
ranges = <0x81000000 0 0 0x10020000 0 0x00010000>,
8997
<0x82000000 0 0x10030000 0x10030000 0 0x07FD0000>;
90-
ti,syscon-pcie-id = <&pcie_devid>;
91-
ti,syscon-pcie-mode = <&pcie0_mode>;
98+
ti,syscon-pcie-id = <&scm_conf 0x0210>;
99+
ti,syscon-pcie-mode = <&scm_conf 0x4060>;
92100
bus-range = <0x0 0xff>;
93101
max-link-speed = <2>;
94102
dma-coherent;

MAINTAINERS

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14890,6 +14890,19 @@ L: [email protected]
1489014890
S: Supported
1489114891
F: Documentation/PCI/pci-error-recovery.rst
1489214892

14893+
PCI PEER-TO-PEER DMA (P2PDMA)
14894+
M: Bjorn Helgaas <[email protected]>
14895+
M: Logan Gunthorpe <[email protected]>
14896+
14897+
S: Supported
14898+
Q: https://patchwork.kernel.org/project/linux-pci/list/
14899+
B: https://bugzilla.kernel.org
14900+
C: irc://irc.oftc.net/linux-pci
14901+
T: git git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci.git
14902+
F: Documentation/driver-api/pci/p2pdma.rst
14903+
F: drivers/pci/p2pdma.c
14904+
F: include/linux/pci-p2pdma.h
14905+
1489314906
PCI MSI DRIVER FOR ALTERA MSI IP
1489414907
M: Joyce Ooi <[email protected]>
1489514908

arch/arm/include/asm/io.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,10 @@ void pci_ioremap_set_mem_type(int mem_type);
180180
static inline void pci_ioremap_set_mem_type(int mem_type) {}
181181
#endif
182182

183-
extern int pci_ioremap_io(unsigned int offset, phys_addr_t phys_addr);
183+
struct resource;
184+
185+
#define pci_remap_iospace pci_remap_iospace
186+
int pci_remap_iospace(const struct resource *res, phys_addr_t phys_addr);
184187

185188
/*
186189
* PCI configuration space mapping function.

arch/arm/mach-dove/pcie.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ static int num_pcie_ports;
3838
static int __init dove_pcie_setup(int nr, struct pci_sys_data *sys)
3939
{
4040
struct pcie_port *pp;
41+
struct resource realio;
4142

4243
if (nr >= num_pcie_ports)
4344
return 0;
@@ -53,10 +54,10 @@ static int __init dove_pcie_setup(int nr, struct pci_sys_data *sys)
5354

5455
orion_pcie_setup(pp->base);
5556

56-
if (pp->index == 0)
57-
pci_ioremap_io(sys->busnr * SZ_64K, DOVE_PCIE0_IO_PHYS_BASE);
58-
else
59-
pci_ioremap_io(sys->busnr * SZ_64K, DOVE_PCIE1_IO_PHYS_BASE);
57+
realio.start = sys->busnr * SZ_64K;
58+
realio.end = realio.start + SZ_64K - 1;
59+
pci_remap_iospace(&realio, pp->index == 0 ? DOVE_PCIE0_IO_PHYS_BASE :
60+
DOVE_PCIE1_IO_PHYS_BASE);
6061

6162
/*
6263
* IORESOURCE_MEM

arch/arm/mach-iop32x/pci.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,7 @@ iop3xx_pci_abort(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
185185
int iop3xx_pci_setup(int nr, struct pci_sys_data *sys)
186186
{
187187
struct resource *res;
188+
struct resource realio;
188189

189190
if (nr != 0)
190191
return 0;
@@ -206,7 +207,9 @@ int iop3xx_pci_setup(int nr, struct pci_sys_data *sys)
206207

207208
pci_add_resource_offset(&sys->resources, res, sys->mem_offset);
208209

209-
pci_ioremap_io(0, IOP3XX_PCI_LOWER_IO_PA);
210+
realio.start = 0;
211+
realio.end = realio.start + SZ_64K - 1;
212+
pci_remap_iospace(&realio, IOP3XX_PCI_LOWER_IO_PA);
210213

211214
return 1;
212215
}

arch/arm/mach-mv78xx0/pcie.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ static void __init mv78xx0_pcie_preinit(void)
101101
static int __init mv78xx0_pcie_setup(int nr, struct pci_sys_data *sys)
102102
{
103103
struct pcie_port *pp;
104+
struct resource realio;
104105

105106
if (nr >= num_pcie_ports)
106107
return 0;
@@ -115,7 +116,9 @@ static int __init mv78xx0_pcie_setup(int nr, struct pci_sys_data *sys)
115116
orion_pcie_set_local_bus_nr(pp->base, sys->busnr);
116117
orion_pcie_setup(pp->base);
117118

118-
pci_ioremap_io(nr * SZ_64K, MV78XX0_PCIE_IO_PHYS_BASE(nr));
119+
realio.start = nr * SZ_64K;
120+
realio.end = realio.start + SZ_64K - 1;
121+
pci_remap_iospace(&realio, MV78XX0_PCIE_IO_PHYS_BASE(nr));
119122

120123
pci_add_resource_offset(&sys->resources, &pp->res, sys->mem_offset);
121124

arch/arm/mach-orion5x/pci.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ static struct pci_ops pcie_ops = {
142142
static int __init pcie_setup(struct pci_sys_data *sys)
143143
{
144144
struct resource *res;
145+
struct resource realio;
145146
int dev;
146147

147148
/*
@@ -164,7 +165,9 @@ static int __init pcie_setup(struct pci_sys_data *sys)
164165
pcie_ops.read = pcie_rd_conf_wa;
165166
}
166167

167-
pci_ioremap_io(sys->busnr * SZ_64K, ORION5X_PCIE_IO_PHYS_BASE);
168+
realio.start = sys->busnr * SZ_64K;
169+
realio.end = realio.start + SZ_64K - 1;
170+
pci_remap_iospace(&realio, ORION5X_PCIE_IO_PHYS_BASE);
168171

169172
/*
170173
* Request resources.
@@ -466,6 +469,7 @@ static void __init orion5x_setup_pci_wins(void)
466469
static int __init pci_setup(struct pci_sys_data *sys)
467470
{
468471
struct resource *res;
472+
struct resource realio;
469473

470474
/*
471475
* Point PCI unit MBUS decode windows to DRAM space.
@@ -482,7 +486,9 @@ static int __init pci_setup(struct pci_sys_data *sys)
482486
*/
483487
orion5x_setbits(PCI_CMD, PCI_CMD_HOST_REORDER);
484488

485-
pci_ioremap_io(sys->busnr * SZ_64K, ORION5X_PCI_IO_PHYS_BASE);
489+
realio.start = sys->busnr * SZ_64K;
490+
realio.end = realio.start + SZ_64K - 1;
491+
pci_remap_iospace(&realio, ORION5X_PCI_IO_PHYS_BASE);
486492

487493
/*
488494
* Request resources

0 commit comments

Comments
 (0)