diff options
Diffstat (limited to 'drivers/edac/edac_mc.c')
-rw-r--r-- | drivers/edac/edac_mc.c | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c index 1b4fc9221803..1df8c0c5d40a 100644 --- a/drivers/edac/edac_mc.c +++ b/drivers/edac/edac_mc.c | |||
@@ -927,6 +927,57 @@ static ssize_t mci_reset_counters_store(struct mem_ctl_info *mci, | |||
927 | return count; | 927 | return count; |
928 | } | 928 | } |
929 | 929 | ||
930 | /* memory scrubbing */ | ||
931 | static ssize_t mci_sdram_scrub_rate_store(struct mem_ctl_info *mci, | ||
932 | const char *data, size_t count) | ||
933 | { | ||
934 | u32 bandwidth = -1; | ||
935 | |||
936 | if (mci->set_sdram_scrub_rate) { | ||
937 | |||
938 | memctrl_int_store(&bandwidth, data, count); | ||
939 | |||
940 | if (!(*mci->set_sdram_scrub_rate)(mci, &bandwidth)) { | ||
941 | edac_printk(KERN_DEBUG, EDAC_MC, | ||
942 | "Scrub rate set successfully, applied: %d\n", | ||
943 | bandwidth); | ||
944 | } else { | ||
945 | /* FIXME: error codes maybe? */ | ||
946 | edac_printk(KERN_DEBUG, EDAC_MC, | ||
947 | "Scrub rate set FAILED, could not apply: %d\n", | ||
948 | bandwidth); | ||
949 | } | ||
950 | } else { | ||
951 | /* FIXME: produce "not implemented" ERROR for user-side. */ | ||
952 | edac_printk(KERN_WARNING, EDAC_MC, | ||
953 | "Memory scrubbing 'set'control is not implemented!\n"); | ||
954 | } | ||
955 | return count; | ||
956 | } | ||
957 | |||
958 | static ssize_t mci_sdram_scrub_rate_show(struct mem_ctl_info *mci, char *data) | ||
959 | { | ||
960 | u32 bandwidth = -1; | ||
961 | |||
962 | if (mci->get_sdram_scrub_rate) { | ||
963 | if (!(*mci->get_sdram_scrub_rate)(mci, &bandwidth)) { | ||
964 | edac_printk(KERN_DEBUG, EDAC_MC, | ||
965 | "Scrub rate successfully, fetched: %d\n", | ||
966 | bandwidth); | ||
967 | } else { | ||
968 | /* FIXME: error codes maybe? */ | ||
969 | edac_printk(KERN_DEBUG, EDAC_MC, | ||
970 | "Scrub rate fetch FAILED, got: %d\n", | ||
971 | bandwidth); | ||
972 | } | ||
973 | } else { | ||
974 | /* FIXME: produce "not implemented" ERROR for user-side. */ | ||
975 | edac_printk(KERN_WARNING, EDAC_MC, | ||
976 | "Memory scrubbing 'get' control is not implemented!\n"); | ||
977 | } | ||
978 | return sprintf(data, "%d\n", bandwidth); | ||
979 | } | ||
980 | |||
930 | /* default attribute files for the MCI object */ | 981 | /* default attribute files for the MCI object */ |
931 | static ssize_t mci_ue_count_show(struct mem_ctl_info *mci, char *data) | 982 | static ssize_t mci_ue_count_show(struct mem_ctl_info *mci, char *data) |
932 | { | 983 | { |
@@ -1033,6 +1084,9 @@ MCIDEV_ATTR(ce_noinfo_count,S_IRUGO,mci_ce_noinfo_show,NULL); | |||
1033 | MCIDEV_ATTR(ue_count,S_IRUGO,mci_ue_count_show,NULL); | 1084 | MCIDEV_ATTR(ue_count,S_IRUGO,mci_ue_count_show,NULL); |
1034 | MCIDEV_ATTR(ce_count,S_IRUGO,mci_ce_count_show,NULL); | 1085 | MCIDEV_ATTR(ce_count,S_IRUGO,mci_ce_count_show,NULL); |
1035 | 1086 | ||
1087 | /* memory scrubber attribute file */ | ||
1088 | MCIDEV_ATTR(sdram_scrub_rate,S_IRUGO|S_IWUSR,mci_sdram_scrub_rate_show,mci_sdram_scrub_rate_store); | ||
1089 | |||
1036 | static struct mcidev_attribute *mci_attr[] = { | 1090 | static struct mcidev_attribute *mci_attr[] = { |
1037 | &mci_attr_reset_counters, | 1091 | &mci_attr_reset_counters, |
1038 | &mci_attr_mc_name, | 1092 | &mci_attr_mc_name, |
@@ -1042,6 +1096,7 @@ static struct mcidev_attribute *mci_attr[] = { | |||
1042 | &mci_attr_ce_noinfo_count, | 1096 | &mci_attr_ce_noinfo_count, |
1043 | &mci_attr_ue_count, | 1097 | &mci_attr_ue_count, |
1044 | &mci_attr_ce_count, | 1098 | &mci_attr_ce_count, |
1099 | &mci_attr_sdram_scrub_rate, | ||
1045 | NULL | 1100 | NULL |
1046 | }; | 1101 | }; |
1047 | 1102 | ||