#include <linux/init.h>
 #include <linux/list.h>
 #include <linux/string.h>
+#include <linux/time.h>
 
 struct pci_dev;
 struct pci_bus;
        struct pci_bus *bus;            /* Top PCI bus for bus PE       */
        int check_count;                /* Times of ignored error       */
        int freeze_count;               /* Times of froze up            */
+       struct timeval tstamp;          /* Time on first-time freeze    */
        int false_positives;            /* Times of reported #ff's      */
        struct eeh_pe *parent;          /* Parent PE                    */
        struct list_head child_list;    /* Link PE to the child list    */
 struct eeh_pe *eeh_pe_get(struct eeh_dev *edev);
 int eeh_add_to_parent_pe(struct eeh_dev *edev);
 int eeh_rmv_from_parent_pe(struct eeh_dev *edev, int purge_pe);
+void eeh_pe_update_time_stamp(struct eeh_pe *pe);
 void *eeh_pe_dev_traverse(struct eeh_pe *root,
                eeh_traverse_func fn, void *flag);
 void eeh_pe_restore_bars(struct eeh_pe *pe);
 
  */
 static int eeh_reset_device(struct eeh_pe *pe, struct pci_bus *bus)
 {
+       struct timeval tstamp;
        int cnt, rc;
 
        /* pcibios will clear the counter; save the value */
        cnt = pe->freeze_count;
+       tstamp = pe->tstamp;
 
        /*
         * We don't remove the corresponding PE instances because
                ssleep(5);
                pcibios_add_pci_devices(bus);
        }
+
+       pe->tstamp = tstamp;
        pe->freeze_count = cnt;
 
        return 0;
                return;
        }
 
+       eeh_pe_update_time_stamp(pe);
        pe->freeze_count++;
        if (pe->freeze_count > EEH_MAX_ALLOWED_FREEZES)
                goto excess_failures;
 
        return 0;
 }
 
+/**
+ * eeh_pe_update_time_stamp - Update PE's frozen time stamp
+ * @pe: EEH PE
+ *
+ * We have time stamp for each PE to trace its time of getting
+ * frozen in last hour. The function should be called to update
+ * the time stamp on first error of the specific PE. On the other
+ * handle, we needn't account for errors happened in last hour.
+ */
+void eeh_pe_update_time_stamp(struct eeh_pe *pe)
+{
+       struct timeval tstamp;
+
+       if (!pe) return;
+
+       if (pe->freeze_count <= 0) {
+               pe->freeze_count = 0;
+               do_gettimeofday(&pe->tstamp);
+       } else {
+               do_gettimeofday(&tstamp);
+               if (tstamp.tv_sec - pe->tstamp.tv_sec > 3600) {
+                       pe->tstamp = tstamp;
+                       pe->freeze_count = 0;
+               }
+       }
+}
+
 /**
  * __eeh_pe_state_mark - Mark the state for the PE
  * @data: EEH PE