Merge branch 'pci/resource' into next
authorBjorn Helgaas <bhelgaas@google.com>
Tue, 14 Nov 2017 18:11:25 +0000 (12:11 -0600)
committerBjorn Helgaas <bhelgaas@google.com>
Tue, 14 Nov 2017 18:11:25 +0000 (12:11 -0600)
* pci/resource:
  PCI: Fail pci_map_rom() if the option ROM is invalid
  PCI: Move pci_map_rom() error path
  x86/PCI: Enable a 64bit BAR on AMD Family 15h (Models 00-1f, 30-3f, 60-7f)
  PCI: Add pci_resize_resource() for resizing BARs
  PCI: Add resizable BAR infrastructure
  PCI: Add PCI resource type mask #define

1  2 
drivers/pci/pci.c
drivers/pci/pci.h
drivers/pci/setup-bus.c
include/linux/pci.h
include/uapi/linux/pci_regs.h

diff --combined drivers/pci/pci.c
@@@ -2966,6 -2966,107 +2966,107 @@@ bool pci_acs_path_enabled(struct pci_de
  }
  
  /**
+  * pci_rebar_find_pos - find position of resize ctrl reg for BAR
+  * @pdev: PCI device
+  * @bar: BAR to find
+  *
+  * Helper to find the position of the ctrl register for a BAR.
+  * Returns -ENOTSUPP if resizable BARs are not supported at all.
+  * Returns -ENOENT if no ctrl register for the BAR could be found.
+  */
+ static int pci_rebar_find_pos(struct pci_dev *pdev, int bar)
+ {
+       unsigned int pos, nbars, i;
+       u32 ctrl;
+       pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_REBAR);
+       if (!pos)
+               return -ENOTSUPP;
+       pci_read_config_dword(pdev, pos + PCI_REBAR_CTRL, &ctrl);
+       nbars = (ctrl & PCI_REBAR_CTRL_NBAR_MASK) >>
+                   PCI_REBAR_CTRL_NBAR_SHIFT;
+       for (i = 0; i < nbars; i++, pos += 8) {
+               int bar_idx;
+               pci_read_config_dword(pdev, pos + PCI_REBAR_CTRL, &ctrl);
+               bar_idx = ctrl & PCI_REBAR_CTRL_BAR_IDX;
+               if (bar_idx == bar)
+                       return pos;
+       }
+       return -ENOENT;
+ }
+ /**
+  * pci_rebar_get_possible_sizes - get possible sizes for BAR
+  * @pdev: PCI device
+  * @bar: BAR to query
+  *
+  * Get the possible sizes of a resizable BAR as bitmask defined in the spec
+  * (bit 0=1MB, bit 19=512GB). Returns 0 if BAR isn't resizable.
+  */
+ u32 pci_rebar_get_possible_sizes(struct pci_dev *pdev, int bar)
+ {
+       int pos;
+       u32 cap;
+       pos = pci_rebar_find_pos(pdev, bar);
+       if (pos < 0)
+               return 0;
+       pci_read_config_dword(pdev, pos + PCI_REBAR_CAP, &cap);
+       return (cap & PCI_REBAR_CAP_SIZES) >> 4;
+ }
+ /**
+  * pci_rebar_get_current_size - get the current size of a BAR
+  * @pdev: PCI device
+  * @bar: BAR to set size to
+  *
+  * Read the size of a BAR from the resizable BAR config.
+  * Returns size if found or negative error code.
+  */
+ int pci_rebar_get_current_size(struct pci_dev *pdev, int bar)
+ {
+       int pos;
+       u32 ctrl;
+       pos = pci_rebar_find_pos(pdev, bar);
+       if (pos < 0)
+               return pos;
+       pci_read_config_dword(pdev, pos + PCI_REBAR_CTRL, &ctrl);
+       return (ctrl & PCI_REBAR_CTRL_BAR_SIZE) >> 8;
+ }
+ /**
+  * pci_rebar_set_size - set a new size for a BAR
+  * @pdev: PCI device
+  * @bar: BAR to set size to
+  * @size: new size as defined in the spec (0=1MB, 19=512GB)
+  *
+  * Set the new size of a BAR as defined in the spec.
+  * Returns zero if resizing was successful, error code otherwise.
+  */
+ int pci_rebar_set_size(struct pci_dev *pdev, int bar, int size)
+ {
+       int pos;
+       u32 ctrl;
+       pos = pci_rebar_find_pos(pdev, bar);
+       if (pos < 0)
+               return pos;
+       pci_read_config_dword(pdev, pos + PCI_REBAR_CTRL, &ctrl);
+       ctrl &= ~PCI_REBAR_CTRL_BAR_SIZE;
+       ctrl |= size << 8;
+       pci_write_config_dword(pdev, pos + PCI_REBAR_CTRL, ctrl);
+       return 0;
+ }
+ /**
   * pci_swizzle_interrupt_pin - swizzle INTx for device behind bridge
   * @dev: the PCI device
   * @pin: the INTx pin (1=INTA, 2=INTB, 3=INTC, 4=INTD)
@@@ -3471,7 -3572,7 +3572,7 @@@ EXPORT_SYMBOL(devm_pci_remap_cfgspace)
   * All operations are managed and will be undone on driver detach.
   *
   * Returns a pointer to the remapped memory or an ERR_PTR() encoded error code
 - * on failure. Usage example:
 + * on failure. Usage example::
   *
   *    res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
   *    base = devm_pci_remap_cfg_resource(&pdev->dev, res);
diff --combined drivers/pci/pci.h
@@@ -192,7 -192,7 +192,7 @@@ static inline int pci_no_d1d2(struct pc
  }
  extern const struct attribute_group *pci_dev_groups[];
  extern const struct attribute_group *pcibus_groups[];
 -extern struct device_type pci_dev_type;
 +extern const struct device_type pci_dev_type;
  extern const struct attribute_group *pci_bus_groups[];
  
  
@@@ -366,4 -366,12 +366,12 @@@ int acpi_get_rc_resources(struct devic
                          struct resource *res);
  #endif
  
+ u32 pci_rebar_get_possible_sizes(struct pci_dev *pdev, int bar);
+ int pci_rebar_get_current_size(struct pci_dev *pdev, int bar);
+ int pci_rebar_set_size(struct pci_dev *pdev, int bar, int size);
+ static inline u64 pci_rebar_size_to_bytes(int size)
+ {
+       return 1ULL << (size + 20);
+ }
  #endif /* DRIVERS_PCI_H */
diff --combined drivers/pci/setup-bus.c
@@@ -1518,13 -1518,16 +1518,16 @@@ static void __pci_bridge_assign_resourc
                break;
        }
  }
+ #define PCI_RES_TYPE_MASK \
+       (IORESOURCE_IO | IORESOURCE_MEM | IORESOURCE_PREFETCH |\
+        IORESOURCE_MEM_64)
  static void pci_bridge_release_resources(struct pci_bus *bus,
                                          unsigned long type)
  {
        struct pci_dev *dev = bus->self;
        struct resource *r;
-       unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM |
-                                 IORESOURCE_PREFETCH | IORESOURCE_MEM_64;
        unsigned old_flags = 0;
        struct resource *b_res;
        int idx = 1;
         */
        release_child_resources(r);
        if (!release_resource(r)) {
-               type = old_flags = r->flags & type_mask;
+               type = old_flags = r->flags & PCI_RES_TYPE_MASK;
                dev_printk(KERN_DEBUG, &dev->dev, "resource %d %pR released\n",
                                        PCI_BRIDGE_RESOURCES + idx, r);
                /* keep the old size */
@@@ -1758,8 -1761,6 +1761,6 @@@ void pci_assign_unassigned_root_bus_res
        enum release_type rel_type = leaf_only;
        LIST_HEAD(fail_head);
        struct pci_dev_resource *fail_res;
-       unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM |
-                                 IORESOURCE_PREFETCH | IORESOURCE_MEM_64;
        int pci_try_num = 1;
        enum enable_type enable_local;
  
@@@ -1818,7 -1819,7 +1819,7 @@@ again
         */
        list_for_each_entry(fail_res, &fail_head, list)
                pci_bus_release_bridge_resources(fail_res->dev->bus,
-                                                fail_res->flags & type_mask,
+                                                fail_res->flags & PCI_RES_TYPE_MASK,
                                                 rel_type);
  
        /* restore size and flags */
@@@ -1853,175 -1854,6 +1854,175 @@@ void __init pci_assign_unassigned_resou
        }
  }
  
 +static void extend_bridge_window(struct pci_dev *bridge, struct resource *res,
 +                      struct list_head *add_list, resource_size_t available)
 +{
 +      struct pci_dev_resource *dev_res;
 +
 +      if (res->parent)
 +              return;
 +
 +      if (resource_size(res) >= available)
 +              return;
 +
 +      dev_res = res_to_dev_res(add_list, res);
 +      if (!dev_res)
 +              return;
 +
 +      /* Is there room to extend the window? */
 +      if (available - resource_size(res) <= dev_res->add_size)
 +              return;
 +
 +      dev_res->add_size = available - resource_size(res);
 +      dev_dbg(&bridge->dev, "bridge window %pR extended by %pa\n", res,
 +              &dev_res->add_size);
 +}
 +
 +static void pci_bus_distribute_available_resources(struct pci_bus *bus,
 +      struct list_head *add_list, resource_size_t available_io,
 +      resource_size_t available_mmio, resource_size_t available_mmio_pref)
 +{
 +      resource_size_t remaining_io, remaining_mmio, remaining_mmio_pref;
 +      unsigned int normal_bridges = 0, hotplug_bridges = 0;
 +      struct resource *io_res, *mmio_res, *mmio_pref_res;
 +      struct pci_dev *dev, *bridge = bus->self;
 +
 +      io_res = &bridge->resource[PCI_BRIDGE_RESOURCES + 0];
 +      mmio_res = &bridge->resource[PCI_BRIDGE_RESOURCES + 1];
 +      mmio_pref_res = &bridge->resource[PCI_BRIDGE_RESOURCES + 2];
 +
 +      /*
 +       * Update additional resource list (add_list) to fill all the
 +       * extra resource space available for this port except the space
 +       * calculated in __pci_bus_size_bridges() which covers all the
 +       * devices currently connected to the port and below.
 +       */
 +      extend_bridge_window(bridge, io_res, add_list, available_io);
 +      extend_bridge_window(bridge, mmio_res, add_list, available_mmio);
 +      extend_bridge_window(bridge, mmio_pref_res, add_list,
 +                           available_mmio_pref);
 +
 +      /*
 +       * Calculate the total amount of extra resource space we can
 +       * pass to bridges below this one. This is basically the
 +       * extra space reduced by the minimal required space for the
 +       * non-hotplug bridges.
 +       */
 +      remaining_io = available_io;
 +      remaining_mmio = available_mmio;
 +      remaining_mmio_pref = available_mmio_pref;
 +
 +      /*
 +       * Calculate how many hotplug bridges and normal bridges there
 +       * are on this bus. We will distribute the additional available
 +       * resources between hotplug bridges.
 +       */
 +      for_each_pci_bridge(dev, bus) {
 +              if (dev->is_hotplug_bridge)
 +                      hotplug_bridges++;
 +              else
 +                      normal_bridges++;
 +      }
 +
 +      for_each_pci_bridge(dev, bus) {
 +              const struct resource *res;
 +
 +              if (dev->is_hotplug_bridge)
 +                      continue;
 +
 +              /*
 +               * Reduce the available resource space by what the
 +               * bridge and devices below it occupy.
 +               */
 +              res = &dev->resource[PCI_BRIDGE_RESOURCES + 0];
 +              if (!res->parent && available_io > resource_size(res))
 +                      remaining_io -= resource_size(res);
 +
 +              res = &dev->resource[PCI_BRIDGE_RESOURCES + 1];
 +              if (!res->parent && available_mmio > resource_size(res))
 +                      remaining_mmio -= resource_size(res);
 +
 +              res = &dev->resource[PCI_BRIDGE_RESOURCES + 2];
 +              if (!res->parent && available_mmio_pref > resource_size(res))
 +                      remaining_mmio_pref -= resource_size(res);
 +      }
 +
 +      /*
 +       * Go over devices on this bus and distribute the remaining
 +       * resource space between hotplug bridges.
 +       */
 +      for_each_pci_bridge(dev, bus) {
 +              struct pci_bus *b;
 +
 +              b = dev->subordinate;
 +              if (!b)
 +                      continue;
 +
 +              if (!hotplug_bridges && normal_bridges == 1) {
 +                      /*
 +                       * There is only one bridge on the bus (upstream
 +                       * port) so it gets all available resources
 +                       * which it can then distribute to the possible
 +                       * hotplug bridges below.
 +                       */
 +                      pci_bus_distribute_available_resources(b, add_list,
 +                              available_io, available_mmio,
 +                              available_mmio_pref);
 +              } else if (dev->is_hotplug_bridge) {
 +                      resource_size_t align, io, mmio, mmio_pref;
 +
 +                      /*
 +                       * Distribute available extra resources equally
 +                       * between hotplug-capable downstream ports
 +                       * taking alignment into account.
 +                       *
 +                       * Here hotplug_bridges is always != 0.
 +                       */
 +                      align = pci_resource_alignment(bridge, io_res);
 +                      io = div64_ul(available_io, hotplug_bridges);
 +                      io = min(ALIGN(io, align), remaining_io);
 +                      remaining_io -= io;
 +
 +                      align = pci_resource_alignment(bridge, mmio_res);
 +                      mmio = div64_ul(available_mmio, hotplug_bridges);
 +                      mmio = min(ALIGN(mmio, align), remaining_mmio);
 +                      remaining_mmio -= mmio;
 +
 +                      align = pci_resource_alignment(bridge, mmio_pref_res);
 +                      mmio_pref = div64_ul(available_mmio_pref,
 +                                           hotplug_bridges);
 +                      mmio_pref = min(ALIGN(mmio_pref, align),
 +                                      remaining_mmio_pref);
 +                      remaining_mmio_pref -= mmio_pref;
 +
 +                      pci_bus_distribute_available_resources(b, add_list, io,
 +                                                             mmio, mmio_pref);
 +              }
 +      }
 +}
 +
 +static void
 +pci_bridge_distribute_available_resources(struct pci_dev *bridge,
 +                                        struct list_head *add_list)
 +{
 +      resource_size_t available_io, available_mmio, available_mmio_pref;
 +      const struct resource *res;
 +
 +      if (!bridge->is_hotplug_bridge)
 +              return;
 +
 +      /* Take the initial extra resources from the hotplug port */
 +      res = &bridge->resource[PCI_BRIDGE_RESOURCES + 0];
 +      available_io = resource_size(res);
 +      res = &bridge->resource[PCI_BRIDGE_RESOURCES + 1];
 +      available_mmio = resource_size(res);
 +      res = &bridge->resource[PCI_BRIDGE_RESOURCES + 2];
 +      available_mmio_pref = resource_size(res);
 +
 +      pci_bus_distribute_available_resources(bridge->subordinate,
 +              add_list, available_io, available_mmio, available_mmio_pref);
 +}
 +
  void pci_assign_unassigned_bridge_resources(struct pci_dev *bridge)
  {
        struct pci_bus *parent = bridge->subordinate;
        LIST_HEAD(fail_head);
        struct pci_dev_resource *fail_res;
        int retval;
-       unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM |
-                                 IORESOURCE_PREFETCH | IORESOURCE_MEM_64;
  
  again:
        __pci_bus_size_bridges(parent, &add_list);
 +
 +      /*
 +       * Distribute remaining resources (if any) equally between
 +       * hotplug bridges below. This makes it possible to extend the
 +       * hierarchy later without running out of resources.
 +       */
 +      pci_bridge_distribute_available_resources(bridge, &add_list);
 +
        __pci_bridge_assign_resources(bridge, &add_list, &fail_head);
        BUG_ON(!list_empty(&add_list));
        tried_times++;
         */
        list_for_each_entry(fail_res, &fail_head, list)
                pci_bus_release_bridge_resources(fail_res->dev->bus,
-                                                fail_res->flags & type_mask,
+                                                fail_res->flags & PCI_RES_TYPE_MASK,
                                                 whole_subtree);
  
        /* restore size and flags */
@@@ -2091,6 -1913,104 +2090,104 @@@ enable_all
  }
  EXPORT_SYMBOL_GPL(pci_assign_unassigned_bridge_resources);
  
+ int pci_reassign_bridge_resources(struct pci_dev *bridge, unsigned long type)
+ {
+       struct pci_dev_resource *dev_res;
+       struct pci_dev *next;
+       LIST_HEAD(saved);
+       LIST_HEAD(added);
+       LIST_HEAD(failed);
+       unsigned int i;
+       int ret;
+       /* Walk to the root hub, releasing bridge BARs when possible */
+       next = bridge;
+       do {
+               bridge = next;
+               for (i = PCI_BRIDGE_RESOURCES; i < PCI_BRIDGE_RESOURCE_END;
+                    i++) {
+                       struct resource *res = &bridge->resource[i];
+                       if ((res->flags ^ type) & PCI_RES_TYPE_MASK)
+                               continue;
+                       /* Ignore BARs which are still in use */
+                       if (res->child)
+                               continue;
+                       ret = add_to_list(&saved, bridge, res, 0, 0);
+                       if (ret)
+                               goto cleanup;
+                       dev_info(&bridge->dev, "BAR %d: releasing %pR\n",
+                                i, res);
+                       if (res->parent)
+                               release_resource(res);
+                       res->start = 0;
+                       res->end = 0;
+                       break;
+               }
+               if (i == PCI_BRIDGE_RESOURCE_END)
+                       break;
+               next = bridge->bus ? bridge->bus->self : NULL;
+       } while (next);
+       if (list_empty(&saved))
+               return -ENOENT;
+       __pci_bus_size_bridges(bridge->subordinate, &added);
+       __pci_bridge_assign_resources(bridge, &added, &failed);
+       BUG_ON(!list_empty(&added));
+       if (!list_empty(&failed)) {
+               ret = -ENOSPC;
+               goto cleanup;
+       }
+       list_for_each_entry(dev_res, &saved, list) {
+               /* Skip the bridge we just assigned resources for. */
+               if (bridge == dev_res->dev)
+                       continue;
+               bridge = dev_res->dev;
+               pci_setup_bridge(bridge->subordinate);
+       }
+       free_list(&saved);
+       return 0;
+ cleanup:
+       /* restore size and flags */
+       list_for_each_entry(dev_res, &failed, list) {
+               struct resource *res = dev_res->res;
+               res->start = dev_res->start;
+               res->end = dev_res->end;
+               res->flags = dev_res->flags;
+       }
+       free_list(&failed);
+       /* Revert to the old configuration */
+       list_for_each_entry(dev_res, &saved, list) {
+               struct resource *res = dev_res->res;
+               bridge = dev_res->dev;
+               i = res - bridge->resource;
+               res->start = dev_res->start;
+               res->end = dev_res->end;
+               res->flags = dev_res->flags;
+               pci_claim_resource(bridge, i);
+               pci_setup_bridge(bridge->subordinate);
+       }
+       free_list(&saved);
+       return ret;
+ }
  void pci_assign_unassigned_bus_resources(struct pci_bus *bus)
  {
        struct pci_dev *dev;
                                        want additional resources */
  
        down_read(&pci_bus_sem);
 -      list_for_each_entry(dev, &bus->devices, bus_list)
 -              if (pci_is_bridge(dev) && pci_has_subordinate(dev))
 -                              __pci_bus_size_bridges(dev->subordinate,
 -                                                       &add_list);
 +      for_each_pci_bridge(dev, bus)
 +              if (pci_has_subordinate(dev))
 +                      __pci_bus_size_bridges(dev->subordinate, &add_list);
        up_read(&pci_bus_sem);
        __pci_bus_assign_resources(bus, &add_list, NULL);
        BUG_ON(!list_empty(&add_list));
diff --combined include/linux/pci.h
@@@ -596,10 -596,6 +596,10 @@@ static inline bool pci_is_bridge(struc
                dev->hdr_type == PCI_HEADER_TYPE_CARDBUS;
  }
  
 +#define for_each_pci_bridge(dev, bus)                         \
 +      list_for_each_entry(dev, &bus->devices, bus_list)       \
 +              if (!pci_is_bridge(dev)) {} else
 +
  static inline struct pci_dev *pci_upstream_bridge(struct pci_dev *dev)
  {
        dev = pci_physfn(dev);
@@@ -1110,6 -1106,8 +1110,8 @@@ void pci_reset_bridge_secondary_bus(str
  void pci_update_resource(struct pci_dev *dev, int resno);
  int __must_check pci_assign_resource(struct pci_dev *dev, int i);
  int __must_check pci_reassign_resource(struct pci_dev *dev, int i, resource_size_t add_size, resource_size_t align);
+ void pci_release_resource(struct pci_dev *dev, int resno);
+ int __must_check pci_resize_resource(struct pci_dev *dev, int i, int size);
  int pci_select_bars(struct pci_dev *dev, unsigned long flags);
  bool pci_device_is_present(struct pci_dev *pdev);
  void pci_ignore_hotplug(struct pci_dev *dev);
@@@ -1189,6 -1187,7 +1191,7 @@@ void pci_assign_unassigned_resources(vo
  void pci_assign_unassigned_bridge_resources(struct pci_dev *bridge);
  void pci_assign_unassigned_bus_resources(struct pci_bus *bus);
  void pci_assign_unassigned_root_bus_resources(struct pci_bus *bus);
+ int pci_reassign_bridge_resources(struct pci_dev *bridge, unsigned long type);
  void pdev_enable_device(struct pci_dev *);
  int pci_enable_resources(struct pci_dev *, int mask);
  void pci_assign_irq(struct pci_dev *dev);
  #define PCI_ERR_ROOT_FIRST_FATAL      0x00000010 /* First UNC is Fatal */
  #define PCI_ERR_ROOT_NONFATAL_RCV     0x00000020 /* Non-Fatal Received */
  #define PCI_ERR_ROOT_FATAL_RCV                0x00000040 /* Fatal Received */
 +#define PCI_ERR_ROOT_AER_IRQ          0xf8000000 /* Advanced Error Interrupt Message Number */
  #define PCI_ERR_ROOT_ERR_SRC  52      /* Error Source Identification */
  
  /* Virtual Channel */
  #define PCI_SATA_SIZEOF_LONG  16
  
  /* Resizable BARs */
+ #define PCI_REBAR_CAP         4       /* capability register */
+ #define  PCI_REBAR_CAP_SIZES          0x00FFFFF0  /* supported BAR sizes */
  #define PCI_REBAR_CTRL                8       /* control register */
- #define  PCI_REBAR_CTRL_NBAR_MASK     (7 << 5)        /* mask for # bars */
- #define  PCI_REBAR_CTRL_NBAR_SHIFT    5       /* shift for # bars */
+ #define  PCI_REBAR_CTRL_BAR_IDX               0x00000007  /* BAR index */
+ #define  PCI_REBAR_CTRL_NBAR_MASK     0x000000E0  /* # of resizable BARs */
+ #define  PCI_REBAR_CTRL_NBAR_SHIFT    5           /* shift for # of BARs */
+ #define  PCI_REBAR_CTRL_BAR_SIZE      0x00001F00  /* BAR size */
  
  /* Dynamic Power Allocation */
  #define PCI_DPA_CAP           4       /* capability register */
  
  /* Downstream Port Containment */
  #define PCI_EXP_DPC_CAP                       4       /* DPC Capability */
 +#define PCI_EXP_DPC_IRQ                       0x1f    /* DPC Interrupt Message Number */
  #define  PCI_EXP_DPC_CAP_RP_EXT               0x20    /* Root Port Extensions for DPC */
  #define  PCI_EXP_DPC_CAP_POISONED_TLP 0x40    /* Poisoned TLP Egress Blocking Supported */
  #define  PCI_EXP_DPC_CAP_SW_TRIGGER   0x80    /* Software Triggering Supported */
  #define  PCI_PTM_CTRL_ENABLE          0x00000001  /* PTM enable */
  #define  PCI_PTM_CTRL_ROOT            0x00000002  /* Root select */
  
 -/* L1 PM Substates */
 -#define PCI_L1SS_CAP              4   /* capability register */
 -#define  PCI_L1SS_CAP_PCIPM_L1_2       1      /* PCI PM L1.2 Support */
 -#define  PCI_L1SS_CAP_PCIPM_L1_1       2      /* PCI PM L1.1 Support */
 -#define  PCI_L1SS_CAP_ASPM_L1_2                4      /* ASPM L1.2 Support */
 -#define  PCI_L1SS_CAP_ASPM_L1_1                8      /* ASPM L1.1 Support */
 -#define  PCI_L1SS_CAP_L1_PM_SS                16      /* L1 PM Substates Support */
 -#define PCI_L1SS_CTL1             8   /* Control Register 1 */
 -#define  PCI_L1SS_CTL1_PCIPM_L1_2     1       /* PCI PM L1.2 Enable */
 -#define  PCI_L1SS_CTL1_PCIPM_L1_1     2       /* PCI PM L1.1 Support */
 -#define  PCI_L1SS_CTL1_ASPM_L1_2      4       /* ASPM L1.2 Support */
 -#define  PCI_L1SS_CTL1_ASPM_L1_1      8       /* ASPM L1.1 Support */
 -#define  PCI_L1SS_CTL1_L1SS_MASK      0x0000000F
 -#define PCI_L1SS_CTL2             0xC /* Control Register 2 */
 +/* ASPM L1 PM Substates */
 +#define PCI_L1SS_CAP          0x04    /* Capabilities Register */
 +#define  PCI_L1SS_CAP_PCIPM_L1_2      0x00000001  /* PCI-PM L1.2 Supported */
 +#define  PCI_L1SS_CAP_PCIPM_L1_1      0x00000002  /* PCI-PM L1.1 Supported */
 +#define  PCI_L1SS_CAP_ASPM_L1_2               0x00000004  /* ASPM L1.2 Supported */
 +#define  PCI_L1SS_CAP_ASPM_L1_1               0x00000008  /* ASPM L1.1 Supported */
 +#define  PCI_L1SS_CAP_L1_PM_SS                0x00000010  /* L1 PM Substates Supported */
 +#define  PCI_L1SS_CAP_CM_RESTORE_TIME 0x0000ff00  /* Port Common_Mode_Restore_Time */
 +#define  PCI_L1SS_CAP_P_PWR_ON_SCALE  0x00030000  /* Port T_POWER_ON scale */
 +#define  PCI_L1SS_CAP_P_PWR_ON_VALUE  0x00f80000  /* Port T_POWER_ON value */
 +#define PCI_L1SS_CTL1         0x08    /* Control 1 Register */
 +#define  PCI_L1SS_CTL1_PCIPM_L1_2     0x00000001  /* PCI-PM L1.2 Enable */
 +#define  PCI_L1SS_CTL1_PCIPM_L1_1     0x00000002  /* PCI-PM L1.1 Enable */
 +#define  PCI_L1SS_CTL1_ASPM_L1_2      0x00000004  /* ASPM L1.2 Enable */
 +#define  PCI_L1SS_CTL1_ASPM_L1_1      0x00000008  /* ASPM L1.1 Enable */
 +#define  PCI_L1SS_CTL1_L1SS_MASK      0x0000000f
 +#define  PCI_L1SS_CTL1_CM_RESTORE_TIME        0x0000ff00  /* Common_Mode_Restore_Time */
 +#define  PCI_L1SS_CTL1_LTR_L12_TH_VALUE       0x03ff0000  /* LTR_L1.2_THRESHOLD_Value */
 +#define  PCI_L1SS_CTL1_LTR_L12_TH_SCALE       0xe0000000  /* LTR_L1.2_THRESHOLD_Scale */
 +#define PCI_L1SS_CTL2         0x0c    /* Control 2 Register */
  
  #endif /* LINUX_PCI_REGS_H */