/** * ish_event_tracer() - Callback function to dump trace messages * @dev: ishtp device * @format: printf style format * * Callback to direct log messages to Linux trace buffers
*/ static __printf(2, 3) void ish_event_tracer(struct ishtp_device *dev, constchar *format, ...)
{ if (trace_ishtp_dump_enabled()) {
va_list args; char tmp_buf[100];
va_start(args, format);
vsnprintf(tmp_buf, sizeof(tmp_buf), format, args);
va_end(args);
trace_ishtp_dump(tmp_buf);
}
}
/** * ish_init() - Init function * @dev: ishtp device * * This function initialize wait queues for suspend/resume and call * calls hadware initialization function. This will initiate * startup sequence * * Return: 0 for success or error code for failure
*/ staticint ish_init(struct ishtp_device *dev)
{ int ret;
/* Set the state of ISH HW to start */
ret = ish_hw_start(dev); if (ret) {
dev_err(dev->devc, "ISH: hw start failed.\n"); return ret;
}
/* Start the inter process communication to ISH processor */
ret = ishtp_start(dev); if (ret) {
dev_err(dev->devc, "ISHTP: Protocol init failed.\n"); return ret;
}
/** * ish_probe() - PCI driver probe callback * @pdev: pci device * @ent: pci device id * * Initialize PCI function, setup interrupt and call for ISH initialization * * Return: 0 for success or error code for failure
*/ staticint ish_probe(struct pci_dev *pdev, conststruct pci_device_id *ent)
{ int ret; struct ish_hw *hw; unsignedlong irq_flag = 0; struct ishtp_device *ishtp; struct device *dev = &pdev->dev;
/* Check for invalid platforms for ISH support */ if (pci_dev_present(ish_invalid_pci_ids)) return -ENODEV;
/* enable pci dev */
ret = pcim_enable_device(pdev); if (ret) {
dev_err(dev, "ISH: Failed to enable PCI device\n"); return ret;
}
/* set PCI host mastering */
pci_set_master(pdev);
/* pci request regions for ISH driver */
ret = pcim_iomap_regions(pdev, 1 << 0, KBUILD_MODNAME); if (ret) {
dev_err(dev, "ISH: Failed to get PCI regions\n"); return ret;
}
/* allocates and initializes the ISH dev structure */
ishtp = ish_dev_init(pdev); if (!ishtp) {
ret = -ENOMEM; return ret;
}
hw = to_ish_hw(ishtp);
ishtp->print_log = ish_event_tracer;
ishtp->driver_data = &ishtp_driver_data[ent->driver_data];
/** * ish_resume_handler() - Work function to complete resume * @work: work struct * * The resume work function to complete resume function asynchronously. * There are two resume paths, one where ISH is not powered off, * in that case a simple resume message is enough, others we need * a reset sequence.
*/ staticvoid __maybe_unused ish_resume_handler(struct work_struct *work)
{ struct pci_dev *pdev = to_pci_dev(ish_resume_device); struct ishtp_device *dev = pci_get_drvdata(pdev);
uint32_t fwsts = dev->ops->get_fw_status(dev);
if (ish_should_leave_d0i3(pdev) && !dev->suspend_flag
&& IPC_IS_ISH_ILUP(fwsts)) { if (device_may_wakeup(&pdev->dev))
disable_irq_wake(pdev->irq);
ish_set_host_ready(dev);
ishtp_send_resume(dev);
/* Waiting to get resume response */ if (dev->resume_flag)
wait_event_interruptible_timeout(dev->resume_wait,
!dev->resume_flag,
msecs_to_jiffies(WAIT_FOR_RESUME_ACK_MS));
/* * If the flag is not cleared, something is wrong with ISH FW. * So on resume, need to go through init sequence again.
*/ if (dev->resume_flag)
ish_init(dev);
} else { /* * Resume from the D3, full reboot of ISH processor will happen, * so need to go through init sequence again.
*/
ish_init(dev);
}
}
if (ish_should_enter_d0i3(pdev)) { /* * If previous suspend hasn't been asnwered then ISH is likely * dead, don't attempt nested notification
*/ if (dev->suspend_flag) return 0;
/* 25 ms should be enough for live ISH to flush all IPC buf */ if (dev->suspend_flag)
wait_event_interruptible_timeout(dev->suspend_wait,
!dev->suspend_flag,
msecs_to_jiffies(25));
if (dev->suspend_flag) { /* * It looks like FW halt, clear the DMA bit, and put * ISH into D3, and FW would reset on resume.
*/
ish_disable_dma(dev);
} else { /* * Save state so PCI core will keep the device at D0, * the ISH would enter D0i3
*/
pci_save_state(pdev);
if (device_may_wakeup(&pdev->dev))
enable_irq_wake(pdev->irq);
}
} else { /* * Clear the DMA bit before putting ISH into D3, * or ISH FW would reset automatically.
*/
ish_disable_dma(dev);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.