aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/edac/i5100_edac.c
diff options
context:
space:
mode:
authorNiklas Söderlund <niklas.soderlund@ericsson.com>2012-08-08 11:30:56 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2013-02-21 09:06:32 -0500
commit52608ba20546139dc76cca8a46c1d901455d5450 (patch)
treee200c6ae257abba4e4c57eea26784de577dc351b /drivers/edac/i5100_edac.c
parente7100478fa894c45ae33321b5721b5a8f956b814 (diff)
i5100_edac: probe for device 19 function 0
Probe and store the device handle for the device 19 function 0 during driver initialization. The device is used during fault injection. Signed-off-by: Niklas Söderlund <niklas.soderlund@ericsson.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/edac/i5100_edac.c')
-rw-r--r--drivers/edac/i5100_edac.c28
1 files changed, 27 insertions, 1 deletions
diff --git a/drivers/edac/i5100_edac.c b/drivers/edac/i5100_edac.c
index d6955b2cc99f..33c5c8e663f2 100644
--- a/drivers/edac/i5100_edac.c
+++ b/drivers/edac/i5100_edac.c
@@ -338,6 +338,7 @@ struct i5100_priv {
338 unsigned ranksperchan; /* number of ranks per channel */ 338 unsigned ranksperchan; /* number of ranks per channel */
339 339
340 struct pci_dev *mc; /* device 16 func 1 */ 340 struct pci_dev *mc; /* device 16 func 1 */
341 struct pci_dev *einj; /* device 19 func 0 */
341 struct pci_dev *ch0mm; /* device 21 func 0 */ 342 struct pci_dev *ch0mm; /* device 21 func 0 */
342 struct pci_dev *ch1mm; /* device 22 func 0 */ 343 struct pci_dev *ch1mm; /* device 22 func 0 */
343 344
@@ -869,7 +870,7 @@ static int i5100_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
869 struct mem_ctl_info *mci; 870 struct mem_ctl_info *mci;
870 struct edac_mc_layer layers[2]; 871 struct edac_mc_layer layers[2];
871 struct i5100_priv *priv; 872 struct i5100_priv *priv;
872 struct pci_dev *ch0mm, *ch1mm; 873 struct pci_dev *ch0mm, *ch1mm, *einj;
873 int ret = 0; 874 int ret = 0;
874 u32 dw; 875 u32 dw;
875 int ranksperch; 876 int ranksperch;
@@ -941,6 +942,22 @@ static int i5100_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
941 goto bail_disable_ch1; 942 goto bail_disable_ch1;
942 } 943 }
943 944
945
946 /* device 19, func 0, Error injection */
947 einj = pci_get_device_func(PCI_VENDOR_ID_INTEL,
948 PCI_DEVICE_ID_INTEL_5100_19, 0);
949 if (!einj) {
950 ret = -ENODEV;
951 goto bail_einj;
952 }
953
954 rc = pci_enable_device(einj);
955 if (rc < 0) {
956 ret = rc;
957 goto bail_disable_einj;
958 }
959
960
944 mci->pdev = &pdev->dev; 961 mci->pdev = &pdev->dev;
945 962
946 priv = mci->pvt_info; 963 priv = mci->pvt_info;
@@ -948,6 +965,7 @@ static int i5100_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
948 priv->mc = pdev; 965 priv->mc = pdev;
949 priv->ch0mm = ch0mm; 966 priv->ch0mm = ch0mm;
950 priv->ch1mm = ch1mm; 967 priv->ch1mm = ch1mm;
968 priv->einj = einj;
951 969
952 INIT_DELAYED_WORK(&(priv->i5100_scrubbing), i5100_refresh_scrubbing); 970 INIT_DELAYED_WORK(&(priv->i5100_scrubbing), i5100_refresh_scrubbing);
953 971
@@ -999,6 +1017,12 @@ bail_scrub:
999 cancel_delayed_work_sync(&(priv->i5100_scrubbing)); 1017 cancel_delayed_work_sync(&(priv->i5100_scrubbing));
1000 edac_mc_free(mci); 1018 edac_mc_free(mci);
1001 1019
1020bail_disable_einj:
1021 pci_disable_device(einj);
1022
1023bail_einj:
1024 pci_dev_put(einj);
1025
1002bail_disable_ch1: 1026bail_disable_ch1:
1003 pci_disable_device(ch1mm); 1027 pci_disable_device(ch1mm);
1004 1028
@@ -1036,8 +1060,10 @@ static void i5100_remove_one(struct pci_dev *pdev)
1036 pci_disable_device(pdev); 1060 pci_disable_device(pdev);
1037 pci_disable_device(priv->ch0mm); 1061 pci_disable_device(priv->ch0mm);
1038 pci_disable_device(priv->ch1mm); 1062 pci_disable_device(priv->ch1mm);
1063 pci_disable_device(priv->einj);
1039 pci_dev_put(priv->ch0mm); 1064 pci_dev_put(priv->ch0mm);
1040 pci_dev_put(priv->ch1mm); 1065 pci_dev_put(priv->ch1mm);
1066 pci_dev_put(priv->einj);
1041 1067
1042 edac_mc_free(mci); 1068 edac_mc_free(mci);
1043} 1069}