/* lock to memory controller's control array */
static DEFINE_MUTEX(mem_ctls_mutex);
-static struct list_head mc_devices = LIST_HEAD_INIT(mc_devices);
+static LIST_HEAD(mc_devices);
#ifdef CONFIG_EDAC_DEBUG
}
EXPORT_SYMBOL_GPL(edac_mc_free);
+
+/*
+ * find_mci_by_dev
+ *
+ * scan list of controllers looking for the one that manages
+ * the 'dev' device
+ */
static struct mem_ctl_info *find_mci_by_dev(struct device *dev)
{
struct mem_ctl_info *mci;
if (edac_mc_assert_error_check_and_clear() && (mci->edac_check != NULL))
mci->edac_check(mci);
- /*
- * FIXME: temp place holder for PCI checks,
- * goes away when we break out PCI
- */
- edac_pci_do_parity_check();
-
mutex_unlock(&mem_ctls_mutex);
/* Reschedule */
{
int status;
- /* if not running POLL, leave now */
- if (mci->op_state == OP_RUNNING_POLL) {
- status = cancel_delayed_work(&mci->work);
- if (status == 0) {
- debugf0("%s() not canceled, flush the queue\n",
- __func__);
+ status = cancel_delayed_work(&mci->work);
+ if (status == 0) {
+ debugf0("%s() not canceled, flush the queue\n",
+ __func__);
- /* workq instance might be running, wait for it */
- flush_workqueue(edac_workqueue);
- }
+ /* workq instance might be running, wait for it */
+ flush_workqueue(edac_workqueue);
}
}
/*
- * edac_reset_delay_period
+ * edac_mc_reset_delay_period(unsigned long value)
+ *
+ * user space has updated our poll period value, need to
+ * reset our workq delays
*/
-static void edac_reset_delay_period(struct mem_ctl_info *mci, unsigned long value)
+void edac_mc_reset_delay_period(int value)
{
- /* cancel the current workq request */
- edac_mc_workq_teardown(mci);
+ struct mem_ctl_info *mci;
+ struct list_head *item;
+
+ mutex_lock(&mem_ctls_mutex);
+
+ /* scan the list and turn off all workq timers, doing so under lock
+ */
+ list_for_each(item, &mc_devices) {
+ mci = list_entry(item, struct mem_ctl_info, link);
+
+ if (mci->op_state == OP_RUNNING_POLL)
+ cancel_delayed_work(&mci->work);
+ }
+
+ mutex_unlock(&mem_ctls_mutex);
+
- /* lock the list of devices for the new setup */
+ /* re-walk the list, and reset the poll delay */
mutex_lock(&mem_ctls_mutex);
- /* restart the workq request, with new delay value */
- edac_mc_workq_setup(mci, value);
+ list_for_each(item, &mc_devices) {
+ mci = list_entry(item, struct mem_ctl_info, link);
+
+ edac_mc_workq_setup(mci, (unsigned long) value);
+ }
mutex_unlock(&mem_ctls_mutex);
}
+
+
/* Return 0 on success, 1 on failure.
* Before calling this function, caller must
* assign a unique value to mci->mc_idx.
fail0:
edac_printk(KERN_WARNING, EDAC_MC,
"%s (%s) %s %s already assigned %d\n", p->dev->bus_id,
- dev_name(mci), p->mod_name, p->ctl_name, p->mc_idx);
+ edac_dev_name(mci), p->mod_name, p->ctl_name, p->mc_idx);
return 1;
fail1:
/* Report action taken */
edac_mc_printk(mci, KERN_INFO, "Giving out device to '%s' '%s':"
- " DEV %s\n", mci->mod_name, mci->ctl_name, dev_name(mci));
+ " DEV %s\n", mci->mod_name, mci->ctl_name, edac_dev_name(mci));
mutex_unlock(&mem_ctls_mutex);
return 0;
edac_printk(KERN_INFO, EDAC_MC,
"Removed device %d for %s %s: DEV %s\n", mci->mc_idx,
- mci->mod_name, mci->ctl_name, dev_name(mci));
+ mci->mod_name, mci->ctl_name, edac_dev_name(mci));
return mci;
}
mci->csrows[csrow].channels[channel].ce_count++;
}
EXPORT_SYMBOL(edac_mc_handle_fbd_ce);
-
-/*
- * Iterate over all MC instances and check for ECC, et al, errors
- */
-void edac_check_mc_devices(void)
-{
- struct list_head *item;
- struct mem_ctl_info *mci;
-
- debugf3("%s()\n", __func__);
- mutex_lock(&mem_ctls_mutex);
-
- list_for_each(item, &mc_devices) {
- mci = list_entry(item, struct mem_ctl_info, link);
-
- if (mci->edac_check != NULL)
- mci->edac_check(mci);
- }
-
- mutex_unlock(&mem_ctls_mutex);
-}