Le Thu, 15 Dec 2022 09:30:45 -0800, Lizhi Hou <lizhi.hou@xxxxxxx> a écrit : Further comments > diff --git a/drivers/pci/of_property.c b/drivers/pci/of_property.c > new file mode 100644 > index 000000000000..05c8ca05a71b > --- /dev/null > +++ b/drivers/pci/of_property.c > @@ -0,0 +1,222 @@ > +// SPDX-License-Identifier: GPL-2.0+ > +/* > + * Copyright (C) 2022, Advanced Micro Devices, Inc. > + */ > + > +#include <linux/pci.h> > +#include <linux/of.h> > +#include <linux/bitfield.h> > +#include <linux/bits.h> > +#include <asm/unaligned.h> > +#include "pci.h" > + > +#define OF_PCI_ADDRESS_CELLS 3 > +#define OF_PCI_SIZE_CELLS 2 > + > +struct of_pci_addr_pair { > + u32 phys_addr[OF_PCI_ADDRESS_CELLS]; > + u32 size[OF_PCI_SIZE_CELLS]; > +}; > + > +struct of_pci_range { > + u32 child_addr[OF_PCI_ADDRESS_CELLS]; > + u32 parent_addr[OF_PCI_ADDRESS_CELLS]; > + u32 size[OF_PCI_SIZE_CELLS]; > +}; > + > +#define OF_PCI_ADDR_SPACE_CONFIG 0x0 > +#define OF_PCI_ADDR_SPACE_IO 0x1 > +#define OF_PCI_ADDR_SPACE_MEM32 0x2 > +#define OF_PCI_ADDR_SPACE_MEM64 0x3 > + > +#define OF_PCI_ADDR_FIELD_NONRELOC BIT(31) > +#define OF_PCI_ADDR_FIELD_SS GENMASK(25, 24) > +#define OF_PCI_ADDR_FIELD_PREFETCH BIT(30) > +#define OF_PCI_ADDR_FIELD_BUS GENMASK(23, 16) > +#define OF_PCI_ADDR_FIELD_DEV GENMASK(15, 11) > +#define OF_PCI_ADDR_FIELD_FUNC GENMASK(10, 8) > +#define OF_PCI_ADDR_FIELD_REG GENMASK(7, 0) > + > +#define OF_PCI_ADDR_HI GENMASK_ULL(63, 32) > +#define OF_PCI_ADDR_LO GENMASK_ULL(31, 0) > +#define OF_PCI_SIZE_HI GENMASK_ULL(63, 32) > +#define OF_PCI_SIZE_LO GENMASK_ULL(31, 0) This is unused. > + > +enum of_pci_prop_compatible { > + PROP_COMPAT_PCI_VVVV_DDDD, > + PROP_COMPAT_PCICLASS_CCSSPP, > + PROP_COMPAT_PCICLASS_CCSS, > + PROP_COMPAT_NUM, > +}; > + > +static int of_pci_prop_device_type(struct pci_dev *pdev, > + struct of_changeset *ocs, > + struct device_node *np) > +{ > + return of_changeset_add_prop_string(ocs, np, "device_type", "pci"); > +} > + > +static int of_pci_prop_address_cells(struct pci_dev *pdev, > + struct of_changeset *ocs, > + struct device_node *np) > +{ > + return of_changeset_add_prop_u32(ocs, np, "#address_cells", > + OF_PCI_ADDRESS_CELLS); > +} > + > +static int of_pci_prop_size_cells(struct pci_dev *pdev, > + struct of_changeset *ocs, > + struct device_node *np) > +{ > + return of_changeset_add_prop_u32(ocs, np, "#size_cells", > + OF_PCI_SIZE_CELLS); > +} > + > +static void of_pci_set_address(u32 *prop, u64 addr, u32 flags) > +{ > + prop[0] = flags; > + put_unaligned(addr, &prop[1]); > +} > + > +static int of_pci_get_addr_flags(struct resource *res, u32 *flags) > +{ > + u32 ss; > + > + if (res->flags & IORESOURCE_IO) > + ss = OF_PCI_ADDR_SPACE_IO; > + else if (res->flags & IORESOURCE_MEM_64) > + ss = OF_PCI_ADDR_SPACE_MEM64; > + else if (res->flags & IORESOURCE_MEM) > + ss = OF_PCI_ADDR_SPACE_MEM32; > + else > + return -EINVAL; > + > + *flags &= ~(OF_PCI_ADDR_FIELD_SS | OF_PCI_ADDR_FIELD_PREFETCH); > + if (res->flags & IORESOURCE_PREFETCH) > + *flags |= OF_PCI_ADDR_FIELD_PREFETCH; > + > + *flags |= ss; This seems wrong, should be: *flags |= FIELD_PREP(OF_PCI_ADDR_FIELD_SS, ss); -- Clément Léger, Embedded Linux and Kernel engineer at Bootlin https://bootlin.com