Merge tag 'pm+acpi-3.16-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael...
[cascardo/linux.git] / drivers / misc / mei / hw-me.c
index 016ad88..6a2d272 100644 (file)
@@ -792,14 +792,81 @@ static const struct mei_hw_ops mei_me_hw_ops = {
        .read = mei_me_read_slots
 };
 
+static bool mei_me_fw_type_nm(struct pci_dev *pdev)
+{
+       u32 reg;
+       pci_read_config_dword(pdev, PCI_CFG_HFS_2, &reg);
+       /* make sure that bit 9 (NM) is up and bit 10 (DM) is down */
+       return (reg & 0x600) == 0x200;
+}
+
+#define MEI_CFG_FW_NM                           \
+       .quirk_probe = mei_me_fw_type_nm
+
+static bool mei_me_fw_type_sps(struct pci_dev *pdev)
+{
+       u32 reg;
+       /* Read ME FW Status check for SPS Firmware */
+       pci_read_config_dword(pdev, PCI_CFG_HFS_1, &reg);
+       /* if bits [19:16] = 15, running SPS Firmware */
+       return (reg & 0xf0000) == 0xf0000;
+}
+
+#define MEI_CFG_FW_SPS                           \
+       .quirk_probe = mei_me_fw_type_sps
+
+
+#define MEI_CFG_LEGACY_HFS                      \
+       .fw_status.count = 0
+
+#define MEI_CFG_ICH_HFS                        \
+       .fw_status.count = 1,                   \
+       .fw_status.status[0] = PCI_CFG_HFS_1
+
+#define MEI_CFG_PCH_HFS                         \
+       .fw_status.count = 2,                   \
+       .fw_status.status[0] = PCI_CFG_HFS_1,   \
+       .fw_status.status[1] = PCI_CFG_HFS_2
+
+
+/* ICH Legacy devices */
+const struct mei_cfg mei_me_legacy_cfg = {
+       MEI_CFG_LEGACY_HFS,
+};
+
+/* ICH devices */
+const struct mei_cfg mei_me_ich_cfg = {
+       MEI_CFG_ICH_HFS,
+};
+
+/* PCH devices */
+const struct mei_cfg mei_me_pch_cfg = {
+       MEI_CFG_PCH_HFS,
+};
+
+
+/* PCH Cougar Point and Patsburg with quirk for Node Manager exclusion */
+const struct mei_cfg mei_me_pch_cpt_pbg_cfg = {
+       MEI_CFG_PCH_HFS,
+       MEI_CFG_FW_NM,
+};
+
+/* PCH Lynx Point with quirk for SPS Firmware exclusion */
+const struct mei_cfg mei_me_lpt_cfg = {
+       MEI_CFG_PCH_HFS,
+       MEI_CFG_FW_SPS,
+};
+
 /**
  * mei_me_dev_init - allocates and initializes the mei device structure
  *
  * @pdev: The pci device structure
+ * @cfg: per device generation config
  *
  * returns The mei_device_device pointer on success, NULL on failure.
  */
-struct mei_device *mei_me_dev_init(struct pci_dev *pdev)
+struct mei_device *mei_me_dev_init(struct pci_dev *pdev,
+                                  const struct mei_cfg *cfg)
 {
        struct mei_device *dev;
 
@@ -808,7 +875,7 @@ struct mei_device *mei_me_dev_init(struct pci_dev *pdev)
        if (!dev)
                return NULL;
 
-       mei_device_init(dev);
+       mei_device_init(dev, cfg);
 
        dev->ops = &mei_me_hw_ops;