aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/mei/hw-me.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/misc/mei/hw-me.c')
-rw-r--r--drivers/misc/mei/hw-me.c59
1 files changed, 55 insertions, 4 deletions
diff --git a/drivers/misc/mei/hw-me.c b/drivers/misc/mei/hw-me.c
index 6fb75e62a764..43d7101ff993 100644
--- a/drivers/misc/mei/hw-me.c
+++ b/drivers/misc/mei/hw-me.c
@@ -663,11 +663,27 @@ int mei_me_pg_exit_sync(struct mei_device *dev)
663 mutex_lock(&dev->device_lock); 663 mutex_lock(&dev->device_lock);
664 664
665reply: 665reply:
666 if (dev->pg_event == MEI_PG_EVENT_RECEIVED) 666 if (dev->pg_event != MEI_PG_EVENT_RECEIVED) {
667 ret = mei_hbm_pg(dev, MEI_PG_ISOLATION_EXIT_RES_CMD); 667 ret = -ETIME;
668 goto out;
669 }
670
671 dev->pg_event = MEI_PG_EVENT_INTR_WAIT;
672 ret = mei_hbm_pg(dev, MEI_PG_ISOLATION_EXIT_RES_CMD);
673 if (ret)
674 return ret;
675
676 mutex_unlock(&dev->device_lock);
677 wait_event_timeout(dev->wait_pg,
678 dev->pg_event == MEI_PG_EVENT_INTR_RECEIVED, timeout);
679 mutex_lock(&dev->device_lock);
680
681 if (dev->pg_event == MEI_PG_EVENT_INTR_RECEIVED)
682 ret = 0;
668 else 683 else
669 ret = -ETIME; 684 ret = -ETIME;
670 685
686out:
671 dev->pg_event = MEI_PG_EVENT_IDLE; 687 dev->pg_event = MEI_PG_EVENT_IDLE;
672 hw->pg_state = MEI_PG_OFF; 688 hw->pg_state = MEI_PG_OFF;
673 689
@@ -675,6 +691,19 @@ reply:
675} 691}
676 692
677/** 693/**
694 * mei_me_pg_in_transition - is device now in pg transition
695 *
696 * @dev: the device structure
697 *
698 * Return: true if in pg transition, false otherwise
699 */
700static bool mei_me_pg_in_transition(struct mei_device *dev)
701{
702 return dev->pg_event >= MEI_PG_EVENT_WAIT &&
703 dev->pg_event <= MEI_PG_EVENT_INTR_WAIT;
704}
705
706/**
678 * mei_me_pg_is_enabled - detect if PG is supported by HW 707 * mei_me_pg_is_enabled - detect if PG is supported by HW
679 * 708 *
680 * @dev: the device structure 709 * @dev: the device structure
@@ -705,6 +734,24 @@ notsupported:
705} 734}
706 735
707/** 736/**
737 * mei_me_pg_intr - perform pg processing in interrupt thread handler
738 *
739 * @dev: the device structure
740 */
741static void mei_me_pg_intr(struct mei_device *dev)
742{
743 struct mei_me_hw *hw = to_me_hw(dev);
744
745 if (dev->pg_event != MEI_PG_EVENT_INTR_WAIT)
746 return;
747
748 dev->pg_event = MEI_PG_EVENT_INTR_RECEIVED;
749 hw->pg_state = MEI_PG_OFF;
750 if (waitqueue_active(&dev->wait_pg))
751 wake_up(&dev->wait_pg);
752}
753
754/**
708 * mei_me_irq_quick_handler - The ISR of the MEI device 755 * mei_me_irq_quick_handler - The ISR of the MEI device
709 * 756 *
710 * @irq: The irq number 757 * @irq: The irq number
@@ -761,6 +808,8 @@ irqreturn_t mei_me_irq_thread_handler(int irq, void *dev_id)
761 goto end; 808 goto end;
762 } 809 }
763 810
811 mei_me_pg_intr(dev);
812
764 /* check if we need to start the dev */ 813 /* check if we need to start the dev */
765 if (!mei_host_is_ready(dev)) { 814 if (!mei_host_is_ready(dev)) {
766 if (mei_hw_is_ready(dev)) { 815 if (mei_hw_is_ready(dev)) {
@@ -797,9 +846,10 @@ irqreturn_t mei_me_irq_thread_handler(int irq, void *dev_id)
797 /* 846 /*
798 * During PG handshake only allowed write is the replay to the 847 * During PG handshake only allowed write is the replay to the
799 * PG exit message, so block calling write function 848 * PG exit message, so block calling write function
800 * if the pg state is not idle 849 * if the pg event is in PG handshake
801 */ 850 */
802 if (dev->pg_event == MEI_PG_EVENT_IDLE) { 851 if (dev->pg_event != MEI_PG_EVENT_WAIT &&
852 dev->pg_event != MEI_PG_EVENT_RECEIVED) {
803 rets = mei_irq_write_handler(dev, &complete_list); 853 rets = mei_irq_write_handler(dev, &complete_list);
804 dev->hbuf_is_ready = mei_hbuf_is_ready(dev); 854 dev->hbuf_is_ready = mei_hbuf_is_ready(dev);
805 } 855 }
@@ -824,6 +874,7 @@ static const struct mei_hw_ops mei_me_hw_ops = {
824 .hw_config = mei_me_hw_config, 874 .hw_config = mei_me_hw_config,
825 .hw_start = mei_me_hw_start, 875 .hw_start = mei_me_hw_start,
826 876
877 .pg_in_transition = mei_me_pg_in_transition,
827 .pg_is_enabled = mei_me_pg_is_enabled, 878 .pg_is_enabled = mei_me_pg_is_enabled,
828 879
829 .intr_clear = mei_me_intr_clear, 880 .intr_clear = mei_me_intr_clear,