aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/eeh.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/kernel/eeh.c')
-rw-r--r--arch/powerpc/kernel/eeh.c366
1 files changed, 343 insertions, 23 deletions
diff --git a/arch/powerpc/kernel/eeh.c b/arch/powerpc/kernel/eeh.c
index 86e25702aaca..59a64f8dc85f 100644
--- a/arch/powerpc/kernel/eeh.c
+++ b/arch/powerpc/kernel/eeh.c
@@ -27,6 +27,7 @@
27#include <linux/init.h> 27#include <linux/init.h>
28#include <linux/list.h> 28#include <linux/list.h>
29#include <linux/pci.h> 29#include <linux/pci.h>
30#include <linux/iommu.h>
30#include <linux/proc_fs.h> 31#include <linux/proc_fs.h>
31#include <linux/rbtree.h> 32#include <linux/rbtree.h>
32#include <linux/reboot.h> 33#include <linux/reboot.h>
@@ -40,6 +41,7 @@
40#include <asm/eeh.h> 41#include <asm/eeh.h>
41#include <asm/eeh_event.h> 42#include <asm/eeh_event.h>
42#include <asm/io.h> 43#include <asm/io.h>
44#include <asm/iommu.h>
43#include <asm/machdep.h> 45#include <asm/machdep.h>
44#include <asm/ppc-pci.h> 46#include <asm/ppc-pci.h>
45#include <asm/rtas.h> 47#include <asm/rtas.h>
@@ -108,6 +110,9 @@ struct eeh_ops *eeh_ops = NULL;
108/* Lock to avoid races due to multiple reports of an error */ 110/* Lock to avoid races due to multiple reports of an error */
109DEFINE_RAW_SPINLOCK(confirm_error_lock); 111DEFINE_RAW_SPINLOCK(confirm_error_lock);
110 112
113/* Lock to protect passed flags */
114static DEFINE_MUTEX(eeh_dev_mutex);
115
111/* Buffer for reporting pci register dumps. Its here in BSS, and 116/* Buffer for reporting pci register dumps. Its here in BSS, and
112 * not dynamically alloced, so that it ends up in RMO where RTAS 117 * not dynamically alloced, so that it ends up in RMO where RTAS
113 * can access it. 118 * can access it.
@@ -137,7 +142,7 @@ static struct eeh_stats eeh_stats;
137static int __init eeh_setup(char *str) 142static int __init eeh_setup(char *str)
138{ 143{
139 if (!strcmp(str, "off")) 144 if (!strcmp(str, "off"))
140 eeh_subsystem_flags |= EEH_FORCE_DISABLED; 145 eeh_add_flag(EEH_FORCE_DISABLED);
141 146
142 return 1; 147 return 1;
143} 148}
@@ -152,12 +157,13 @@ __setup("eeh=", eeh_setup);
152 * This routine captures assorted PCI configuration space data, 157 * This routine captures assorted PCI configuration space data,
153 * and puts them into a buffer for RTAS error logging. 158 * and puts them into a buffer for RTAS error logging.
154 */ 159 */
155static size_t eeh_gather_pci_data(struct eeh_dev *edev, char * buf, size_t len) 160static size_t eeh_gather_pci_data(struct eeh_dev *edev, char *buf, size_t len)
156{ 161{
157 struct device_node *dn = eeh_dev_to_of_node(edev); 162 struct device_node *dn = eeh_dev_to_of_node(edev);
158 u32 cfg; 163 u32 cfg;
159 int cap, i; 164 int cap, i;
160 int n = 0; 165 int n = 0, l = 0;
166 char buffer[128];
161 167
162 n += scnprintf(buf+n, len-n, "%s\n", dn->full_name); 168 n += scnprintf(buf+n, len-n, "%s\n", dn->full_name);
163 pr_warn("EEH: of node=%s\n", dn->full_name); 169 pr_warn("EEH: of node=%s\n", dn->full_name);
@@ -202,8 +208,22 @@ static size_t eeh_gather_pci_data(struct eeh_dev *edev, char * buf, size_t len)
202 for (i=0; i<=8; i++) { 208 for (i=0; i<=8; i++) {
203 eeh_ops->read_config(dn, cap+4*i, 4, &cfg); 209 eeh_ops->read_config(dn, cap+4*i, 4, &cfg);
204 n += scnprintf(buf+n, len-n, "%02x:%x\n", 4*i, cfg); 210 n += scnprintf(buf+n, len-n, "%02x:%x\n", 4*i, cfg);
205 pr_warn("EEH: PCI-E %02x: %08x\n", i, cfg); 211
212 if ((i % 4) == 0) {
213 if (i != 0)
214 pr_warn("%s\n", buffer);
215
216 l = scnprintf(buffer, sizeof(buffer),
217 "EEH: PCI-E %02x: %08x ",
218 4*i, cfg);
219 } else {
220 l += scnprintf(buffer+l, sizeof(buffer)-l,
221 "%08x ", cfg);
222 }
223
206 } 224 }
225
226 pr_warn("%s\n", buffer);
207 } 227 }
208 228
209 /* If AER capable, dump it */ 229 /* If AER capable, dump it */
@@ -212,11 +232,24 @@ static size_t eeh_gather_pci_data(struct eeh_dev *edev, char * buf, size_t len)
212 n += scnprintf(buf+n, len-n, "pci-e AER:\n"); 232 n += scnprintf(buf+n, len-n, "pci-e AER:\n");
213 pr_warn("EEH: PCI-E AER capability register set follows:\n"); 233 pr_warn("EEH: PCI-E AER capability register set follows:\n");
214 234
215 for (i=0; i<14; i++) { 235 for (i=0; i<=13; i++) {
216 eeh_ops->read_config(dn, cap+4*i, 4, &cfg); 236 eeh_ops->read_config(dn, cap+4*i, 4, &cfg);
217 n += scnprintf(buf+n, len-n, "%02x:%x\n", 4*i, cfg); 237 n += scnprintf(buf+n, len-n, "%02x:%x\n", 4*i, cfg);
218 pr_warn("EEH: PCI-E AER %02x: %08x\n", i, cfg); 238
239 if ((i % 4) == 0) {
240 if (i != 0)
241 pr_warn("%s\n", buffer);
242
243 l = scnprintf(buffer, sizeof(buffer),
244 "EEH: PCI-E AER %02x: %08x ",
245 4*i, cfg);
246 } else {
247 l += scnprintf(buffer+l, sizeof(buffer)-l,
248 "%08x ", cfg);
249 }
219 } 250 }
251
252 pr_warn("%s\n", buffer);
220 } 253 }
221 254
222 return n; 255 return n;
@@ -247,7 +280,7 @@ void eeh_slot_error_detail(struct eeh_pe *pe, int severity)
247 * 0xFF's is always returned from PCI config space. 280 * 0xFF's is always returned from PCI config space.
248 */ 281 */
249 if (!(pe->type & EEH_PE_PHB)) { 282 if (!(pe->type & EEH_PE_PHB)) {
250 if (eeh_probe_mode_devtree()) 283 if (eeh_has_flag(EEH_ENABLE_IO_FOR_LOG))
251 eeh_pci_enable(pe, EEH_OPT_THAW_MMIO); 284 eeh_pci_enable(pe, EEH_OPT_THAW_MMIO);
252 eeh_ops->configure_bridge(pe); 285 eeh_ops->configure_bridge(pe);
253 eeh_pe_restore_bars(pe); 286 eeh_pe_restore_bars(pe);
@@ -298,14 +331,14 @@ static int eeh_phb_check_failure(struct eeh_pe *pe)
298 unsigned long flags; 331 unsigned long flags;
299 int ret; 332 int ret;
300 333
301 if (!eeh_probe_mode_dev()) 334 if (!eeh_has_flag(EEH_PROBE_MODE_DEV))
302 return -EPERM; 335 return -EPERM;
303 336
304 /* Find the PHB PE */ 337 /* Find the PHB PE */
305 phb_pe = eeh_phb_pe_get(pe->phb); 338 phb_pe = eeh_phb_pe_get(pe->phb);
306 if (!phb_pe) { 339 if (!phb_pe) {
307 pr_warning("%s Can't find PE for PHB#%d\n", 340 pr_warn("%s Can't find PE for PHB#%d\n",
308 __func__, pe->phb->global_number); 341 __func__, pe->phb->global_number);
309 return -EEXIST; 342 return -EEXIST;
310 } 343 }
311 344
@@ -400,6 +433,14 @@ int eeh_dev_check_failure(struct eeh_dev *edev)
400 if (ret > 0) 433 if (ret > 0)
401 return ret; 434 return ret;
402 435
436 /*
437 * If the PE isn't owned by us, we shouldn't check the
438 * state. Instead, let the owner handle it if the PE has
439 * been frozen.
440 */
441 if (eeh_pe_passed(pe))
442 return 0;
443
403 /* If we already have a pending isolation event for this 444 /* If we already have a pending isolation event for this
404 * slot, we know it's bad already, we don't need to check. 445 * slot, we know it's bad already, we don't need to check.
405 * Do this checking under a lock; as multiple PCI devices 446 * Do this checking under a lock; as multiple PCI devices
@@ -746,13 +787,13 @@ void eeh_save_bars(struct eeh_dev *edev)
746int __init eeh_ops_register(struct eeh_ops *ops) 787int __init eeh_ops_register(struct eeh_ops *ops)
747{ 788{
748 if (!ops->name) { 789 if (!ops->name) {
749 pr_warning("%s: Invalid EEH ops name for %p\n", 790 pr_warn("%s: Invalid EEH ops name for %p\n",
750 __func__, ops); 791 __func__, ops);
751 return -EINVAL; 792 return -EINVAL;
752 } 793 }
753 794
754 if (eeh_ops && eeh_ops != ops) { 795 if (eeh_ops && eeh_ops != ops) {
755 pr_warning("%s: EEH ops of platform %s already existing (%s)\n", 796 pr_warn("%s: EEH ops of platform %s already existing (%s)\n",
756 __func__, eeh_ops->name, ops->name); 797 __func__, eeh_ops->name, ops->name);
757 return -EEXIST; 798 return -EEXIST;
758 } 799 }
@@ -772,7 +813,7 @@ int __init eeh_ops_register(struct eeh_ops *ops)
772int __exit eeh_ops_unregister(const char *name) 813int __exit eeh_ops_unregister(const char *name)
773{ 814{
774 if (!name || !strlen(name)) { 815 if (!name || !strlen(name)) {
775 pr_warning("%s: Invalid EEH ops name\n", 816 pr_warn("%s: Invalid EEH ops name\n",
776 __func__); 817 __func__);
777 return -EINVAL; 818 return -EINVAL;
778 } 819 }
@@ -788,7 +829,7 @@ int __exit eeh_ops_unregister(const char *name)
788static int eeh_reboot_notifier(struct notifier_block *nb, 829static int eeh_reboot_notifier(struct notifier_block *nb,
789 unsigned long action, void *unused) 830 unsigned long action, void *unused)
790{ 831{
791 eeh_set_enable(false); 832 eeh_clear_flag(EEH_ENABLED);
792 return NOTIFY_DONE; 833 return NOTIFY_DONE;
793} 834}
794 835
@@ -837,11 +878,11 @@ int eeh_init(void)
837 878
838 /* call platform initialization function */ 879 /* call platform initialization function */
839 if (!eeh_ops) { 880 if (!eeh_ops) {
840 pr_warning("%s: Platform EEH operation not found\n", 881 pr_warn("%s: Platform EEH operation not found\n",
841 __func__); 882 __func__);
842 return -EEXIST; 883 return -EEXIST;
843 } else if ((ret = eeh_ops->init())) { 884 } else if ((ret = eeh_ops->init())) {
844 pr_warning("%s: Failed to call platform init function (%d)\n", 885 pr_warn("%s: Failed to call platform init function (%d)\n",
845 __func__, ret); 886 __func__, ret);
846 return ret; 887 return ret;
847 } 888 }
@@ -852,13 +893,13 @@ int eeh_init(void)
852 return ret; 893 return ret;
853 894
854 /* Enable EEH for all adapters */ 895 /* Enable EEH for all adapters */
855 if (eeh_probe_mode_devtree()) { 896 if (eeh_has_flag(EEH_PROBE_MODE_DEVTREE)) {
856 list_for_each_entry_safe(hose, tmp, 897 list_for_each_entry_safe(hose, tmp,
857 &hose_list, list_node) { 898 &hose_list, list_node) {
858 phb = hose->dn; 899 phb = hose->dn;
859 traverse_pci_devices(phb, eeh_ops->of_probe, NULL); 900 traverse_pci_devices(phb, eeh_ops->of_probe, NULL);
860 } 901 }
861 } else if (eeh_probe_mode_dev()) { 902 } else if (eeh_has_flag(EEH_PROBE_MODE_DEV)) {
862 list_for_each_entry_safe(hose, tmp, 903 list_for_each_entry_safe(hose, tmp,
863 &hose_list, list_node) 904 &hose_list, list_node)
864 pci_walk_bus(hose->bus, eeh_ops->dev_probe, NULL); 905 pci_walk_bus(hose->bus, eeh_ops->dev_probe, NULL);
@@ -882,7 +923,7 @@ int eeh_init(void)
882 if (eeh_enabled()) 923 if (eeh_enabled())
883 pr_info("EEH: PCI Enhanced I/O Error Handling Enabled\n"); 924 pr_info("EEH: PCI Enhanced I/O Error Handling Enabled\n");
884 else 925 else
885 pr_warning("EEH: No capable adapters found\n"); 926 pr_warn("EEH: No capable adapters found\n");
886 927
887 return ret; 928 return ret;
888} 929}
@@ -910,7 +951,7 @@ void eeh_add_device_early(struct device_node *dn)
910 * would delay the probe until late stage because 951 * would delay the probe until late stage because
911 * the PCI device isn't available this moment. 952 * the PCI device isn't available this moment.
912 */ 953 */
913 if (!eeh_probe_mode_devtree()) 954 if (!eeh_has_flag(EEH_PROBE_MODE_DEVTREE))
914 return; 955 return;
915 956
916 if (!of_node_to_eeh_dev(dn)) 957 if (!of_node_to_eeh_dev(dn))
@@ -996,7 +1037,7 @@ void eeh_add_device_late(struct pci_dev *dev)
996 * We have to do the EEH probe here because the PCI device 1037 * We have to do the EEH probe here because the PCI device
997 * hasn't been created yet in the early stage. 1038 * hasn't been created yet in the early stage.
998 */ 1039 */
999 if (eeh_probe_mode_dev()) 1040 if (eeh_has_flag(EEH_PROBE_MODE_DEV))
1000 eeh_ops->dev_probe(dev, NULL); 1041 eeh_ops->dev_probe(dev, NULL);
1001 1042
1002 eeh_addr_cache_insert_dev(dev); 1043 eeh_addr_cache_insert_dev(dev);
@@ -1100,6 +1141,285 @@ void eeh_remove_device(struct pci_dev *dev)
1100 edev->mode &= ~EEH_DEV_SYSFS; 1141 edev->mode &= ~EEH_DEV_SYSFS;
1101} 1142}
1102 1143
1144/**
1145 * eeh_dev_open - Increase count of pass through devices for PE
1146 * @pdev: PCI device
1147 *
1148 * Increase count of passed through devices for the indicated
1149 * PE. In the result, the EEH errors detected on the PE won't be
1150 * reported. The PE owner will be responsible for detection
1151 * and recovery.
1152 */
1153int eeh_dev_open(struct pci_dev *pdev)
1154{
1155 struct eeh_dev *edev;
1156
1157 mutex_lock(&eeh_dev_mutex);
1158
1159 /* No PCI device ? */
1160 if (!pdev)
1161 goto out;
1162
1163 /* No EEH device or PE ? */
1164 edev = pci_dev_to_eeh_dev(pdev);
1165 if (!edev || !edev->pe)
1166 goto out;
1167
1168 /* Increase PE's pass through count */
1169 atomic_inc(&edev->pe->pass_dev_cnt);
1170 mutex_unlock(&eeh_dev_mutex);
1171
1172 return 0;
1173out:
1174 mutex_unlock(&eeh_dev_mutex);
1175 return -ENODEV;
1176}
1177EXPORT_SYMBOL_GPL(eeh_dev_open);
1178
1179/**
1180 * eeh_dev_release - Decrease count of pass through devices for PE
1181 * @pdev: PCI device
1182 *
1183 * Decrease count of pass through devices for the indicated PE. If
1184 * there is no passed through device in PE, the EEH errors detected
1185 * on the PE will be reported and handled as usual.
1186 */
1187void eeh_dev_release(struct pci_dev *pdev)
1188{
1189 struct eeh_dev *edev;
1190
1191 mutex_lock(&eeh_dev_mutex);
1192
1193 /* No PCI device ? */
1194 if (!pdev)
1195 goto out;
1196
1197 /* No EEH device ? */
1198 edev = pci_dev_to_eeh_dev(pdev);
1199 if (!edev || !edev->pe || !eeh_pe_passed(edev->pe))
1200 goto out;
1201
1202 /* Decrease PE's pass through count */
1203 atomic_dec(&edev->pe->pass_dev_cnt);
1204 WARN_ON(atomic_read(&edev->pe->pass_dev_cnt) < 0);
1205out:
1206 mutex_unlock(&eeh_dev_mutex);
1207}
1208EXPORT_SYMBOL(eeh_dev_release);
1209
1210#ifdef CONFIG_IOMMU_API
1211
1212static int dev_has_iommu_table(struct device *dev, void *data)
1213{
1214 struct pci_dev *pdev = to_pci_dev(dev);
1215 struct pci_dev **ppdev = data;
1216 struct iommu_table *tbl;
1217
1218 if (!dev)
1219 return 0;
1220
1221 tbl = get_iommu_table_base(dev);
1222 if (tbl && tbl->it_group) {
1223 *ppdev = pdev;
1224 return 1;
1225 }
1226
1227 return 0;
1228}
1229
1230/**
1231 * eeh_iommu_group_to_pe - Convert IOMMU group to EEH PE
1232 * @group: IOMMU group
1233 *
1234 * The routine is called to convert IOMMU group to EEH PE.
1235 */
1236struct eeh_pe *eeh_iommu_group_to_pe(struct iommu_group *group)
1237{
1238 struct pci_dev *pdev = NULL;
1239 struct eeh_dev *edev;
1240 int ret;
1241
1242 /* No IOMMU group ? */
1243 if (!group)
1244 return NULL;
1245
1246 ret = iommu_group_for_each_dev(group, &pdev, dev_has_iommu_table);
1247 if (!ret || !pdev)
1248 return NULL;
1249
1250 /* No EEH device or PE ? */
1251 edev = pci_dev_to_eeh_dev(pdev);
1252 if (!edev || !edev->pe)
1253 return NULL;
1254
1255 return edev->pe;
1256}
1257EXPORT_SYMBOL_GPL(eeh_iommu_group_to_pe);
1258
1259#endif /* CONFIG_IOMMU_API */
1260
1261/**
1262 * eeh_pe_set_option - Set options for the indicated PE
1263 * @pe: EEH PE
1264 * @option: requested option
1265 *
1266 * The routine is called to enable or disable EEH functionality
1267 * on the indicated PE, to enable IO or DMA for the frozen PE.
1268 */
1269int eeh_pe_set_option(struct eeh_pe *pe, int option)
1270{
1271 int ret = 0;
1272
1273 /* Invalid PE ? */
1274 if (!pe)
1275 return -ENODEV;
1276
1277 /*
1278 * EEH functionality could possibly be disabled, just
1279 * return error for the case. And the EEH functinality
1280 * isn't expected to be disabled on one specific PE.
1281 */
1282 switch (option) {
1283 case EEH_OPT_ENABLE:
1284 if (eeh_enabled())
1285 break;
1286 ret = -EIO;
1287 break;
1288 case EEH_OPT_DISABLE:
1289 break;
1290 case EEH_OPT_THAW_MMIO:
1291 case EEH_OPT_THAW_DMA:
1292 if (!eeh_ops || !eeh_ops->set_option) {
1293 ret = -ENOENT;
1294 break;
1295 }
1296
1297 ret = eeh_ops->set_option(pe, option);
1298 break;
1299 default:
1300 pr_debug("%s: Option %d out of range (%d, %d)\n",
1301 __func__, option, EEH_OPT_DISABLE, EEH_OPT_THAW_DMA);
1302 ret = -EINVAL;
1303 }
1304
1305 return ret;
1306}
1307EXPORT_SYMBOL_GPL(eeh_pe_set_option);
1308
1309/**
1310 * eeh_pe_get_state - Retrieve PE's state
1311 * @pe: EEH PE
1312 *
1313 * Retrieve the PE's state, which includes 3 aspects: enabled
1314 * DMA, enabled IO and asserted reset.
1315 */
1316int eeh_pe_get_state(struct eeh_pe *pe)
1317{
1318 int result, ret = 0;
1319 bool rst_active, dma_en, mmio_en;
1320
1321 /* Existing PE ? */
1322 if (!pe)
1323 return -ENODEV;
1324
1325 if (!eeh_ops || !eeh_ops->get_state)
1326 return -ENOENT;
1327
1328 result = eeh_ops->get_state(pe, NULL);
1329 rst_active = !!(result & EEH_STATE_RESET_ACTIVE);
1330 dma_en = !!(result & EEH_STATE_DMA_ENABLED);
1331 mmio_en = !!(result & EEH_STATE_MMIO_ENABLED);
1332
1333 if (rst_active)
1334 ret = EEH_PE_STATE_RESET;
1335 else if (dma_en && mmio_en)
1336 ret = EEH_PE_STATE_NORMAL;
1337 else if (!dma_en && !mmio_en)
1338 ret = EEH_PE_STATE_STOPPED_IO_DMA;
1339 else if (!dma_en && mmio_en)
1340 ret = EEH_PE_STATE_STOPPED_DMA;
1341 else
1342 ret = EEH_PE_STATE_UNAVAIL;
1343
1344 return ret;
1345}
1346EXPORT_SYMBOL_GPL(eeh_pe_get_state);
1347
1348/**
1349 * eeh_pe_reset - Issue PE reset according to specified type
1350 * @pe: EEH PE
1351 * @option: reset type
1352 *
1353 * The routine is called to reset the specified PE with the
1354 * indicated type, either fundamental reset or hot reset.
1355 * PE reset is the most important part for error recovery.
1356 */
1357int eeh_pe_reset(struct eeh_pe *pe, int option)
1358{
1359 int ret = 0;
1360
1361 /* Invalid PE ? */
1362 if (!pe)
1363 return -ENODEV;
1364
1365 if (!eeh_ops || !eeh_ops->set_option || !eeh_ops->reset)
1366 return -ENOENT;
1367
1368 switch (option) {
1369 case EEH_RESET_DEACTIVATE:
1370 ret = eeh_ops->reset(pe, option);
1371 if (ret)
1372 break;
1373
1374 /*
1375 * The PE is still in frozen state and we need to clear
1376 * that. It's good to clear frozen state after deassert
1377 * to avoid messy IO access during reset, which might
1378 * cause recursive frozen PE.
1379 */
1380 ret = eeh_ops->set_option(pe, EEH_OPT_THAW_MMIO);
1381 if (!ret)
1382 ret = eeh_ops->set_option(pe, EEH_OPT_THAW_DMA);
1383 if (!ret)
1384 eeh_pe_state_clear(pe, EEH_PE_ISOLATED);
1385 break;
1386 case EEH_RESET_HOT:
1387 case EEH_RESET_FUNDAMENTAL:
1388 ret = eeh_ops->reset(pe, option);
1389 break;
1390 default:
1391 pr_debug("%s: Unsupported option %d\n",
1392 __func__, option);
1393 ret = -EINVAL;
1394 }
1395
1396 return ret;
1397}
1398EXPORT_SYMBOL_GPL(eeh_pe_reset);
1399
1400/**
1401 * eeh_pe_configure - Configure PCI bridges after PE reset
1402 * @pe: EEH PE
1403 *
1404 * The routine is called to restore the PCI config space for
1405 * those PCI devices, especially PCI bridges affected by PE
1406 * reset issued previously.
1407 */
1408int eeh_pe_configure(struct eeh_pe *pe)
1409{
1410 int ret = 0;
1411
1412 /* Invalid PE ? */
1413 if (!pe)
1414 return -ENODEV;
1415
1416 /* Restore config space for the affected devices */
1417 eeh_pe_restore_bars(pe);
1418
1419 return ret;
1420}
1421EXPORT_SYMBOL_GPL(eeh_pe_configure);
1422
1103static int proc_eeh_show(struct seq_file *m, void *v) 1423static int proc_eeh_show(struct seq_file *m, void *v)
1104{ 1424{
1105 if (!eeh_enabled()) { 1425 if (!eeh_enabled()) {
@@ -1143,9 +1463,9 @@ static const struct file_operations proc_eeh_operations = {
1143static int eeh_enable_dbgfs_set(void *data, u64 val) 1463static int eeh_enable_dbgfs_set(void *data, u64 val)
1144{ 1464{
1145 if (val) 1465 if (val)
1146 eeh_subsystem_flags &= ~EEH_FORCE_DISABLED; 1466 eeh_clear_flag(EEH_FORCE_DISABLED);
1147 else 1467 else
1148 eeh_subsystem_flags |= EEH_FORCE_DISABLED; 1468 eeh_add_flag(EEH_FORCE_DISABLED);
1149 1469
1150 /* Notify the backend */ 1470 /* Notify the backend */
1151 if (eeh_ops->post_init) 1471 if (eeh_ops->post_init)