summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/caif/caif_hsi.c42
-rw-r--r--include/net/caif/caif_hsi.h1
2 files changed, 41 insertions, 2 deletions
diff --git a/drivers/net/caif/caif_hsi.c b/drivers/net/caif/caif_hsi.c
index e9e7cbf01a5f..073352517adc 100644
--- a/drivers/net/caif/caif_hsi.c
+++ b/drivers/net/caif/caif_hsi.c
@@ -674,6 +674,7 @@ static void cfhsi_wake_up(struct work_struct *work)
674 /* It happenes when wakeup is requested by 674 /* It happenes when wakeup is requested by
675 * both ends at the same time. */ 675 * both ends at the same time. */
676 clear_bit(CFHSI_WAKE_UP, &cfhsi->bits); 676 clear_bit(CFHSI_WAKE_UP, &cfhsi->bits);
677 clear_bit(CFHSI_WAKE_UP_ACK, &cfhsi->bits);
677 return; 678 return;
678 } 679 }
679 680
@@ -690,19 +691,47 @@ static void cfhsi_wake_up(struct work_struct *work)
690 &cfhsi->bits), ret); 691 &cfhsi->bits), ret);
691 if (unlikely(ret < 0)) { 692 if (unlikely(ret < 0)) {
692 /* Interrupted by signal. */ 693 /* Interrupted by signal. */
693 dev_info(&cfhsi->ndev->dev, "%s: Signalled: %ld.\n", 694 dev_err(&cfhsi->ndev->dev, "%s: Signalled: %ld.\n",
694 __func__, ret); 695 __func__, ret);
696
695 clear_bit(CFHSI_WAKE_UP, &cfhsi->bits); 697 clear_bit(CFHSI_WAKE_UP, &cfhsi->bits);
696 cfhsi->dev->cfhsi_wake_down(cfhsi->dev); 698 cfhsi->dev->cfhsi_wake_down(cfhsi->dev);
697 return; 699 return;
698 } else if (!ret) { 700 } else if (!ret) {
701 bool ca_wake = false;
702 size_t fifo_occupancy = 0;
703
699 /* Wakeup timeout */ 704 /* Wakeup timeout */
700 dev_err(&cfhsi->ndev->dev, "%s: Timeout.\n", 705 dev_err(&cfhsi->ndev->dev, "%s: Timeout.\n",
701 __func__); 706 __func__);
707
708 /* Check FIFO to check if modem has sent something. */
709 WARN_ON(cfhsi->dev->cfhsi_fifo_occupancy(cfhsi->dev,
710 &fifo_occupancy));
711
712 dev_err(&cfhsi->ndev->dev, "%s: Bytes in FIFO: %u.\n",
713 __func__, (unsigned) fifo_occupancy);
714
715 /* Check if we misssed the interrupt. */
716 WARN_ON(cfhsi->dev->cfhsi_get_peer_wake(cfhsi->dev,
717 &ca_wake));
718
719 if (ca_wake) {
720 dev_err(&cfhsi->ndev->dev, "%s: CA Wake missed !.\n",
721 __func__);
722
723 /* Clear the CFHSI_WAKE_UP_ACK bit to prevent race. */
724 clear_bit(CFHSI_WAKE_UP_ACK, &cfhsi->bits);
725
726 /* Continue execution. */
727 goto wake_ack;
728 }
729
702 clear_bit(CFHSI_WAKE_UP, &cfhsi->bits); 730 clear_bit(CFHSI_WAKE_UP, &cfhsi->bits);
703 cfhsi->dev->cfhsi_wake_down(cfhsi->dev); 731 cfhsi->dev->cfhsi_wake_down(cfhsi->dev);
704 return; 732 return;
705 } 733 }
734wake_ack:
706 dev_dbg(&cfhsi->ndev->dev, "%s: Woken.\n", 735 dev_dbg(&cfhsi->ndev->dev, "%s: Woken.\n",
707 __func__); 736 __func__);
708 737
@@ -779,12 +808,21 @@ static void cfhsi_wake_down(struct work_struct *work)
779 &cfhsi->bits), ret); 808 &cfhsi->bits), ret);
780 if (ret < 0) { 809 if (ret < 0) {
781 /* Interrupted by signal. */ 810 /* Interrupted by signal. */
782 dev_info(&cfhsi->ndev->dev, "%s: Signalled: %ld.\n", 811 dev_err(&cfhsi->ndev->dev, "%s: Signalled: %ld.\n",
783 __func__, ret); 812 __func__, ret);
784 return; 813 return;
785 } else if (!ret) { 814 } else if (!ret) {
815 bool ca_wake = true;
816
786 /* Timeout */ 817 /* Timeout */
787 dev_err(&cfhsi->ndev->dev, "%s: Timeout.\n", __func__); 818 dev_err(&cfhsi->ndev->dev, "%s: Timeout.\n", __func__);
819
820 /* Check if we misssed the interrupt. */
821 WARN_ON(cfhsi->dev->cfhsi_get_peer_wake(cfhsi->dev,
822 &ca_wake));
823 if (!ca_wake)
824 dev_err(&cfhsi->ndev->dev, "%s: CA Wake missed !.\n",
825 __func__);
788 } 826 }
789 827
790 /* Check FIFO occupancy. */ 828 /* Check FIFO occupancy. */
diff --git a/include/net/caif/caif_hsi.h b/include/net/caif/caif_hsi.h
index 3356769afaee..8d552519ff67 100644
--- a/include/net/caif/caif_hsi.h
+++ b/include/net/caif/caif_hsi.h
@@ -108,6 +108,7 @@ struct cfhsi_dev {
108 int (*cfhsi_rx) (u8 *ptr, int len, struct cfhsi_dev *dev); 108 int (*cfhsi_rx) (u8 *ptr, int len, struct cfhsi_dev *dev);
109 int (*cfhsi_wake_up) (struct cfhsi_dev *dev); 109 int (*cfhsi_wake_up) (struct cfhsi_dev *dev);
110 int (*cfhsi_wake_down) (struct cfhsi_dev *dev); 110 int (*cfhsi_wake_down) (struct cfhsi_dev *dev);
111 int (*cfhsi_get_peer_wake) (struct cfhsi_dev *dev, bool *status);
111 int (*cfhsi_fifo_occupancy)(struct cfhsi_dev *dev, size_t *occupancy); 112 int (*cfhsi_fifo_occupancy)(struct cfhsi_dev *dev, size_t *occupancy);
112 int (*cfhsi_rx_cancel)(struct cfhsi_dev *dev); 113 int (*cfhsi_rx_cancel)(struct cfhsi_dev *dev);
113 struct cfhsi_drv *drv; 114 struct cfhsi_drv *drv;