/** * mei_restart - restart device after suspend * * @dev: the device structure * * returns 0 on success or -ENODEV if the restart hasn't succeeded */ int mei_restart(struct mei_device *dev) { int err; mutex_lock(&dev->device_lock); mei_clear_interrupts(dev); dev->dev_state = MEI_DEV_POWER_UP; dev->reset_count = 0; err = mei_reset(dev); mutex_unlock(&dev->device_lock); if (err == -ENODEV || dev->dev_state == MEI_DEV_DISABLED) { dev_err(&dev->pdev->dev, "device disabled = %d\n", err); return -ENODEV; } /* try to start again */ if (err) schedule_work(&dev->reset_work); return 0; }
/** * mei_start - initializes host and fw to start work. * * @dev: the device structure * * returns 0 on success, <0 on failure. */ int mei_start(struct mei_device *dev) { int ret; mutex_lock(&dev->device_lock); /* acknowledge interrupt and stop interrupts */ mei_clear_interrupts(dev); mei_hw_config(dev); dev_dbg(&dev->pdev->dev, "reset in start the mei device.\n"); dev->reset_count = 0; do { dev->dev_state = MEI_DEV_INITIALIZING; ret = mei_reset(dev); if (ret == -ENODEV || dev->dev_state == MEI_DEV_DISABLED) { dev_err(&dev->pdev->dev, "reset failed ret = %d", ret); goto err; } } while (ret); /* we cannot start the device w/o hbm start message completed */ if (dev->dev_state == MEI_DEV_DISABLED) { dev_err(&dev->pdev->dev, "reset failed"); goto err; } if (mei_hbm_start_wait(dev)) { dev_err(&dev->pdev->dev, "HBM haven't started"); goto err; } if (!mei_host_is_ready(dev)) { dev_err(&dev->pdev->dev, "host is not ready.\n"); goto err; } if (!mei_hw_is_ready(dev)) { dev_err(&dev->pdev->dev, "ME is not ready.\n"); goto err; } if (!mei_hbm_version_is_supported(dev)) { dev_dbg(&dev->pdev->dev, "MEI start failed.\n"); goto err; } dev_dbg(&dev->pdev->dev, "link layer has been established.\n"); mutex_unlock(&dev->device_lock); return 0; err: dev_err(&dev->pdev->dev, "link layer initialization failed.\n"); dev->dev_state = MEI_DEV_DISABLED; mutex_unlock(&dev->device_lock); return -ENODEV; }
static void mei_reset_work(struct work_struct *work) { struct mei_device *dev = container_of(work, struct mei_device, reset_work); mutex_lock(&dev->device_lock); mei_reset(dev); mutex_unlock(&dev->device_lock); if (dev->dev_state == MEI_DEV_DISABLED) dev_err(&dev->pdev->dev, "reset failed"); }
void mei_stop(struct mei_device *dev) { dev_dbg(&dev->pdev->dev, "stopping the device.\n"); mutex_lock(&dev->device_lock); cancel_delayed_work(&dev->timer_work); mei_wd_stop(dev); dev->dev_state = MEI_DEV_POWER_DOWN; mei_reset(dev, 0); mutex_unlock(&dev->device_lock); flush_scheduled_work(); }
/** * mei_start - initializes host and fw to start work. * * @dev: the device structure * * returns 0 on success, <0 on failure. */ int mei_start(struct mei_device *dev) { mutex_lock(&dev->device_lock); /* acknowledge interrupt and stop interupts */ mei_clear_interrupts(dev); mei_hw_config(dev); dev_dbg(&dev->pdev->dev, "reset in start the mei device.\n"); mei_reset(dev, 1); if (mei_hbm_start_wait(dev)) { dev_err(&dev->pdev->dev, "HBM haven't started"); goto err; } if (!mei_host_is_ready(dev)) { dev_err(&dev->pdev->dev, "host is not ready.\n"); goto err; } if (!mei_hw_is_ready(dev)) { dev_err(&dev->pdev->dev, "ME is not ready.\n"); goto err; } if (dev->version.major_version != HBM_MAJOR_VERSION || dev->version.minor_version != HBM_MINOR_VERSION) { dev_dbg(&dev->pdev->dev, "MEI start failed.\n"); goto err; } dev_dbg(&dev->pdev->dev, "link layer has been established.\n"); mutex_unlock(&dev->device_lock); return 0; err: dev_err(&dev->pdev->dev, "link layer initialization failed.\n"); dev->dev_state = MEI_DEV_DISABLED; mutex_unlock(&dev->device_lock); return -ENODEV; }
void mei_stop(struct mei_device *dev) { dev_dbg(&dev->pdev->dev, "stopping the device.\n"); mei_cancel_work(dev); mei_nfc_host_exit(dev); mutex_lock(&dev->device_lock); mei_wd_stop(dev); dev->dev_state = MEI_DEV_POWER_DOWN; mei_reset(dev); mutex_unlock(&dev->device_lock); mei_watchdog_unregister(dev); }
/** * mei_restart - restart device after suspend * * @dev: the device structure * * returns 0 on success or -ENODEV if the restart hasn't succeeded */ int mei_restart(struct mei_device *dev) { int err; mutex_lock(&dev->device_lock); mei_clear_interrupts(dev); dev->dev_state = MEI_DEV_POWER_UP; dev->reset_count = 0; err = mei_reset(dev); mutex_unlock(&dev->device_lock); if (err || dev->dev_state == MEI_DEV_DISABLED) return -ENODEV; return 0; }
static int mei_me_pci_resume(struct device *device) { struct pci_dev *pdev = to_pci_dev(device); struct mei_device *dev; int err; dev = pci_get_drvdata(pdev); if (!dev) return -ENODEV; pci_enable_msi(pdev); /* request and enable interrupt */ if (pci_dev_msi_enabled(pdev)) err = request_threaded_irq(pdev->irq, NULL, mei_me_irq_thread_handler, IRQF_ONESHOT, KBUILD_MODNAME, dev); else err = request_threaded_irq(pdev->irq, mei_me_irq_quick_handler, mei_me_irq_thread_handler, IRQF_SHARED, KBUILD_MODNAME, dev); if (err) { dev_err(&pdev->dev, "request_threaded_irq failed: irq = %d.\n", pdev->irq); return err; } mutex_lock(&dev->device_lock); dev->dev_state = MEI_DEV_POWER_UP; mei_clear_interrupts(dev); mei_reset(dev, 1); mutex_unlock(&dev->device_lock); /* Start timer if stopped in suspend */ schedule_delayed_work(&dev->timer_work, HZ); return err; }
static void mei_reset_work(struct work_struct *work) { struct mei_device *dev = container_of(work, struct mei_device, reset_work); int ret; mutex_lock(&dev->device_lock); ret = mei_reset(dev); mutex_unlock(&dev->device_lock); if (dev->dev_state == MEI_DEV_DISABLED) { dev_err(&dev->pdev->dev, "device disabled = %d\n", ret); return; } /* retry reset in case of failure */ if (ret) schedule_work(&dev->reset_work); }
void mei_stop(struct mei_device *dev) { dev_dbg(&dev->pdev->dev, "stopping the device.\n"); mei_cancel_work(dev); mei_nfc_host_exit(dev); mutex_lock(&dev->device_lock); mei_wd_stop(dev); dev->dev_state = MEI_DEV_POWER_DOWN; mei_reset(dev); /* move device to disabled state unconditionally */ dev->dev_state = MEI_DEV_DISABLED; mutex_unlock(&dev->device_lock); mei_watchdog_unregister(dev); }
void mei_stop(struct mei_device *dev) { dev_dbg(dev->dev, "stopping the device.\n"); mutex_lock(&dev->device_lock); dev->dev_state = MEI_DEV_POWER_DOWN; mutex_unlock(&dev->device_lock); mei_cl_bus_remove_devices(dev); mei_cancel_work(dev); mei_clear_interrupts(dev); mei_synchronize_irq(dev); mutex_lock(&dev->device_lock); mei_reset(dev); /* move device to disabled state unconditionally */ dev->dev_state = MEI_DEV_DISABLED; mutex_unlock(&dev->device_lock); }
/** * mei_hw_init - initializes host and fw to start work. * * @dev: the device structure * * returns 0 on success, <0 on failure. */ int mei_hw_init(struct mei_device *dev) { int ret = 0; mutex_lock(&dev->device_lock); /* acknowledge interrupt and stop interupts */ mei_clear_interrupts(dev); mei_hw_config(dev); dev->recvd_msg = false; dev_dbg(&dev->pdev->dev, "reset in start the mei device.\n"); mei_reset(dev, 1); /* wait for ME to turn on ME_RDY */ if (!dev->recvd_msg) { mutex_unlock(&dev->device_lock); ret = wait_event_interruptible_timeout(dev->wait_recvd_msg, dev->recvd_msg, mei_secs_to_jiffies(MEI_INTEROP_TIMEOUT)); mutex_lock(&dev->device_lock); } if (ret <= 0 && !dev->recvd_msg) { dev->dev_state = MEI_DEV_DISABLED; dev_dbg(&dev->pdev->dev, "wait_event_interruptible_timeout failed" "on wait for ME to turn on ME_RDY.\n"); goto err; } if (!mei_host_is_ready(dev)) { dev_err(&dev->pdev->dev, "host is not ready.\n"); goto err; } if (!mei_hw_is_ready(dev)) { dev_err(&dev->pdev->dev, "ME is not ready.\n"); goto err; } if (dev->version.major_version != HBM_MAJOR_VERSION || dev->version.minor_version != HBM_MINOR_VERSION) { dev_dbg(&dev->pdev->dev, "MEI start failed.\n"); goto err; } dev->recvd_msg = false; dev_dbg(&dev->pdev->dev, "link layer has been established.\n"); mutex_unlock(&dev->device_lock); return 0; err: dev_err(&dev->pdev->dev, "link layer initialization failed.\n"); dev->dev_state = MEI_DEV_DISABLED; mutex_unlock(&dev->device_lock); return -ENODEV; }