Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

caif-hsi: Added recovery check of CA wake status.

Added recovery check of CA wake status in case of wake up timeout.
Added check of CA wake status in case of wake down timeout.

Signed-off-by: Sjur Brændeland <sjur.brandeland@stericsson.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Daniel Martensson and committed by
David S. Miller
5ea2ef5f 5bbed92d

+41 -2
+40 -2
drivers/net/caif/caif_hsi.c
··· 674 674 /* It happenes when wakeup is requested by 675 675 * both ends at the same time. */ 676 676 clear_bit(CFHSI_WAKE_UP, &cfhsi->bits); 677 + clear_bit(CFHSI_WAKE_UP_ACK, &cfhsi->bits); 677 678 return; 678 679 } 679 680 ··· 691 690 &cfhsi->bits), ret); 692 691 if (unlikely(ret < 0)) { 693 692 /* Interrupted by signal. */ 694 - dev_info(&cfhsi->ndev->dev, "%s: Signalled: %ld.\n", 693 + dev_err(&cfhsi->ndev->dev, "%s: Signalled: %ld.\n", 695 694 __func__, ret); 695 + 696 696 clear_bit(CFHSI_WAKE_UP, &cfhsi->bits); 697 697 cfhsi->dev->cfhsi_wake_down(cfhsi->dev); 698 698 return; 699 699 } else if (!ret) { 700 + bool ca_wake = false; 701 + size_t fifo_occupancy = 0; 702 + 700 703 /* Wakeup timeout */ 701 704 dev_err(&cfhsi->ndev->dev, "%s: Timeout.\n", 702 705 __func__); 706 + 707 + /* Check FIFO to check if modem has sent something. */ 708 + WARN_ON(cfhsi->dev->cfhsi_fifo_occupancy(cfhsi->dev, 709 + &fifo_occupancy)); 710 + 711 + dev_err(&cfhsi->ndev->dev, "%s: Bytes in FIFO: %u.\n", 712 + __func__, (unsigned) fifo_occupancy); 713 + 714 + /* Check if we misssed the interrupt. */ 715 + WARN_ON(cfhsi->dev->cfhsi_get_peer_wake(cfhsi->dev, 716 + &ca_wake)); 717 + 718 + if (ca_wake) { 719 + dev_err(&cfhsi->ndev->dev, "%s: CA Wake missed !.\n", 720 + __func__); 721 + 722 + /* Clear the CFHSI_WAKE_UP_ACK bit to prevent race. */ 723 + clear_bit(CFHSI_WAKE_UP_ACK, &cfhsi->bits); 724 + 725 + /* Continue execution. */ 726 + goto wake_ack; 727 + } 728 + 703 729 clear_bit(CFHSI_WAKE_UP, &cfhsi->bits); 704 730 cfhsi->dev->cfhsi_wake_down(cfhsi->dev); 705 731 return; 706 732 } 733 + wake_ack: 707 734 dev_dbg(&cfhsi->ndev->dev, "%s: Woken.\n", 708 735 __func__); 709 736 ··· 808 779 &cfhsi->bits), ret); 809 780 if (ret < 0) { 810 781 /* Interrupted by signal. */ 811 - dev_info(&cfhsi->ndev->dev, "%s: Signalled: %ld.\n", 782 + dev_err(&cfhsi->ndev->dev, "%s: Signalled: %ld.\n", 812 783 __func__, ret); 813 784 return; 814 785 } else if (!ret) { 786 + bool ca_wake = true; 787 + 815 788 /* Timeout */ 816 789 dev_err(&cfhsi->ndev->dev, "%s: Timeout.\n", __func__); 790 + 791 + /* Check if we misssed the interrupt. */ 792 + WARN_ON(cfhsi->dev->cfhsi_get_peer_wake(cfhsi->dev, 793 + &ca_wake)); 794 + if (!ca_wake) 795 + dev_err(&cfhsi->ndev->dev, "%s: CA Wake missed !.\n", 796 + __func__); 817 797 } 818 798 819 799 /* Check FIFO occupancy. */
+1
include/net/caif/caif_hsi.h
··· 108 108 int (*cfhsi_rx) (u8 *ptr, int len, struct cfhsi_dev *dev); 109 109 int (*cfhsi_wake_up) (struct cfhsi_dev *dev); 110 110 int (*cfhsi_wake_down) (struct cfhsi_dev *dev); 111 + int (*cfhsi_get_peer_wake) (struct cfhsi_dev *dev, bool *status); 111 112 int (*cfhsi_fifo_occupancy)(struct cfhsi_dev *dev, size_t *occupancy); 112 113 int (*cfhsi_rx_cancel)(struct cfhsi_dev *dev); 113 114 struct cfhsi_drv *drv;