diff options
-rw-r--r-- | drivers/misc/mei/hw-me.c | 37 | ||||
-rw-r--r-- | drivers/misc/mei/hw-me.h | 2 | ||||
-rw-r--r-- | drivers/misc/mei/mei_dev.h | 2 | ||||
-rw-r--r-- | drivers/misc/mei/pci-me.c | 47 |
4 files changed, 54 insertions, 34 deletions
diff --git a/drivers/misc/mei/hw-me.c b/drivers/misc/mei/hw-me.c index ed081182f973..6a2d272cea43 100644 --- a/drivers/misc/mei/hw-me.c +++ b/drivers/misc/mei/hw-me.c @@ -792,6 +792,30 @@ 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, ®); + /* 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, ®); + /* 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 @@ -820,6 +844,19 @@ 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 * diff --git a/drivers/misc/mei/hw-me.h b/drivers/misc/mei/hw-me.h index 473aafbc4023..12b0f4bbe1f1 100644 --- a/drivers/misc/mei/hw-me.h +++ b/drivers/misc/mei/hw-me.h @@ -41,6 +41,8 @@ struct mei_me_hw { extern const struct mei_cfg mei_me_legacy_cfg; extern const struct mei_cfg mei_me_ich_cfg; extern const struct mei_cfg mei_me_pch_cfg; +extern const struct mei_cfg mei_me_pch_cpt_pbg_cfg; +extern const struct mei_cfg mei_me_lpt_cfg; struct mei_device *mei_me_dev_init(struct pci_dev *pdev, const struct mei_cfg *cfg); diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index 909d13de17e9..5c7e990e2f22 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h @@ -383,9 +383,11 @@ enum mei_pg_state { * mei_cfg * * @fw_status - FW status + * @quirk_probe - device exclusion quirk */ struct mei_cfg { const struct mei_fw_status fw_status; + bool (*quirk_probe)(struct pci_dev *pdev); }; diff --git a/drivers/misc/mei/pci-me.c b/drivers/misc/mei/pci-me.c index 6cb9819ac5d5..1b46c64a649f 100644 --- a/drivers/misc/mei/pci-me.c +++ b/drivers/misc/mei/pci-me.c @@ -72,15 +72,15 @@ static const struct pci_device_id mei_me_pci_tbl[] = { {MEI_PCI_DEVICE(MEI_DEV_ID_IBXPK_1, mei_me_pch_cfg)}, {MEI_PCI_DEVICE(MEI_DEV_ID_IBXPK_2, mei_me_pch_cfg)}, - {MEI_PCI_DEVICE(MEI_DEV_ID_CPT_1, mei_me_pch_cfg)}, - {MEI_PCI_DEVICE(MEI_DEV_ID_PBG_1, mei_me_pch_cfg)}, + {MEI_PCI_DEVICE(MEI_DEV_ID_CPT_1, mei_me_pch_cpt_pbg_cfg)}, + {MEI_PCI_DEVICE(MEI_DEV_ID_PBG_1, mei_me_pch_cpt_pbg_cfg)}, {MEI_PCI_DEVICE(MEI_DEV_ID_PPT_1, mei_me_pch_cfg)}, {MEI_PCI_DEVICE(MEI_DEV_ID_PPT_2, mei_me_pch_cfg)}, {MEI_PCI_DEVICE(MEI_DEV_ID_PPT_3, mei_me_pch_cfg)}, - {MEI_PCI_DEVICE(MEI_DEV_ID_LPT_H, mei_me_pch_cfg)}, - {MEI_PCI_DEVICE(MEI_DEV_ID_LPT_W, mei_me_pch_cfg)}, + {MEI_PCI_DEVICE(MEI_DEV_ID_LPT_H, mei_me_lpt_cfg)}, + {MEI_PCI_DEVICE(MEI_DEV_ID_LPT_W, mei_me_lpt_cfg)}, {MEI_PCI_DEVICE(MEI_DEV_ID_LPT_LP, mei_me_pch_cfg)}, - {MEI_PCI_DEVICE(MEI_DEV_ID_LPT_HR, mei_me_pch_cfg)}, + {MEI_PCI_DEVICE(MEI_DEV_ID_LPT_HR, mei_me_lpt_cfg)}, {MEI_PCI_DEVICE(MEI_DEV_ID_WPT_LP, mei_me_pch_cfg)}, /* required last entry */ @@ -101,40 +101,21 @@ static inline void mei_me_unset_pm_domain(struct mei_device *dev) {} * mei_quirk_probe - probe for devices that doesn't valid ME interface * * @pdev: PCI device structure - * @ent: entry into pci_device_table + * @cfg: per generation config * * returns true if ME Interface is valid, false otherwise */ static bool mei_me_quirk_probe(struct pci_dev *pdev, - const struct pci_device_id *ent) + const struct mei_cfg *cfg) { - u32 reg; - /* Cougar Point || Patsburg */ - if (ent->device == MEI_DEV_ID_CPT_1 || - ent->device == MEI_DEV_ID_PBG_1) { - pci_read_config_dword(pdev, PCI_CFG_HFS_2, ®); - /* make sure that bit 9 (NM) is up and bit 10 (DM) is down */ - if ((reg & 0x600) == 0x200) - goto no_mei; - } - - /* Lynx Point */ - if (ent->device == MEI_DEV_ID_LPT_H || - ent->device == MEI_DEV_ID_LPT_W || - ent->device == MEI_DEV_ID_LPT_HR) { - /* Read ME FW Status check for SPS Firmware */ - pci_read_config_dword(pdev, PCI_CFG_HFS_1, ®); - /* if bits [19:16] = 15, running SPS Firmware */ - if ((reg & 0xf0000) == 0xf0000) - goto no_mei; + if (cfg->quirk_probe && cfg->quirk_probe(pdev)) { + dev_info(&pdev->dev, "Device doesn't have valid ME Interface\n"); + return false; } return true; - -no_mei: - dev_info(&pdev->dev, "Device doesn't have valid ME Interface\n"); - return false; } + /** * mei_probe - Device Initialization Routine * @@ -151,10 +132,8 @@ static int mei_me_probe(struct pci_dev *pdev, const struct pci_device_id *ent) int err; - if (!mei_me_quirk_probe(pdev, ent)) { - err = -ENODEV; - goto end; - } + if (!mei_me_quirk_probe(pdev, cfg)) + return -ENODEV; /* enable pci dev */ err = pci_enable_device(pdev); |