aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ieee802154
diff options
context:
space:
mode:
authorAlexander Aring <alex.aring@gmail.com>2014-10-07 04:38:32 -0400
committerMarcel Holtmann <marcel@holtmann.org>2014-10-25 01:56:23 -0400
commit97fed795e70d97fb89ebd8c3efc30b33aa4ac1fa (patch)
tree7a8549a6f79f4ae5870445b2edba86982590a218 /drivers/net/ieee802154
parent35e92a8e1b9058a5f7da271a7a60264a4888f4b9 (diff)
at86rf230: fix enable_irq handling on async spi
Sometimes the async state function is call in an context where the spi irq is diabled. This patch fix the handling to enable the irq when spi_async failed in the async state change calling chain. We do this by a context parameter irq_enable and evaluate this parameter when spi_async failed instead of returning spi_async errno. Signed-off-by: Alexander Aring <alex.aring@gmail.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'drivers/net/ieee802154')
-rw-r--r--drivers/net/ieee802154/at86rf230.c157
1 files changed, 77 insertions, 80 deletions
diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c
index 5dbec64eb786..7a1a8e39b130 100644
--- a/drivers/net/ieee802154/at86rf230.c
+++ b/drivers/net/ieee802154/at86rf230.c
@@ -74,6 +74,8 @@ struct at86rf230_state_change {
74 void (*complete)(void *context); 74 void (*complete)(void *context);
75 u8 from_state; 75 u8 from_state;
76 u8 to_state; 76 u8 to_state;
77
78 bool irq_enable;
77}; 79};
78 80
79struct at86rf230_local { 81struct at86rf230_local {
@@ -292,10 +294,11 @@ struct at86rf230_local {
292 294
293#define AT86RF2XX_NUMREGS 0x3F 295#define AT86RF2XX_NUMREGS 0x3F
294 296
295static int 297static void
296at86rf230_async_state_change(struct at86rf230_local *lp, 298at86rf230_async_state_change(struct at86rf230_local *lp,
297 struct at86rf230_state_change *ctx, 299 struct at86rf230_state_change *ctx,
298 const u8 state, void (*complete)(void *context)); 300 const u8 state, void (*complete)(void *context),
301 const bool irq_enable);
299 302
300static inline int 303static inline int
301__at86rf230_write(struct at86rf230_local *lp, 304__at86rf230_write(struct at86rf230_local *lp,
@@ -452,7 +455,7 @@ at86rf230_async_error_recover(void *context)
452 struct at86rf230_state_change *ctx = context; 455 struct at86rf230_state_change *ctx = context;
453 struct at86rf230_local *lp = ctx->lp; 456 struct at86rf230_local *lp = ctx->lp;
454 457
455 at86rf230_async_state_change(lp, ctx, STATE_RX_AACK_ON, NULL); 458 at86rf230_async_state_change(lp, ctx, STATE_RX_AACK_ON, NULL, false);
456} 459}
457 460
458static void 461static void
@@ -462,21 +465,31 @@ at86rf230_async_error(struct at86rf230_local *lp,
462 dev_err(&lp->spi->dev, "spi_async error %d\n", rc); 465 dev_err(&lp->spi->dev, "spi_async error %d\n", rc);
463 466
464 at86rf230_async_state_change(lp, ctx, STATE_FORCE_TRX_OFF, 467 at86rf230_async_state_change(lp, ctx, STATE_FORCE_TRX_OFF,
465 at86rf230_async_error_recover); 468 at86rf230_async_error_recover, false);
466} 469}
467 470
468/* Generic function to get some register value in async mode */ 471/* Generic function to get some register value in async mode */
469static int 472static void
470at86rf230_async_read_reg(struct at86rf230_local *lp, const u8 reg, 473at86rf230_async_read_reg(struct at86rf230_local *lp, const u8 reg,
471 struct at86rf230_state_change *ctx, 474 struct at86rf230_state_change *ctx,
472 void (*complete)(void *context)) 475 void (*complete)(void *context),
476 const bool irq_enable)
473{ 477{
478 int rc;
479
474 u8 *tx_buf = ctx->buf; 480 u8 *tx_buf = ctx->buf;
475 481
476 tx_buf[0] = (reg & CMD_REG_MASK) | CMD_REG; 482 tx_buf[0] = (reg & CMD_REG_MASK) | CMD_REG;
477 ctx->trx.len = 2; 483 ctx->trx.len = 2;
478 ctx->msg.complete = complete; 484 ctx->msg.complete = complete;
479 return spi_async(lp->spi, &ctx->msg); 485 ctx->irq_enable = irq_enable;
486 rc = spi_async(lp->spi, &ctx->msg);
487 if (rc) {
488 if (irq_enable)
489 enable_irq(lp->spi->irq);
490
491 at86rf230_async_error(lp, ctx, rc);
492 }
480} 493}
481 494
482static void 495static void
@@ -513,7 +526,8 @@ at86rf230_async_state_assert(void *context)
513 if (ctx->to_state == STATE_TX_ON) { 526 if (ctx->to_state == STATE_TX_ON) {
514 at86rf230_async_state_change(lp, ctx, 527 at86rf230_async_state_change(lp, ctx,
515 STATE_FORCE_TX_ON, 528 STATE_FORCE_TX_ON,
516 ctx->complete); 529 ctx->complete,
530 ctx->irq_enable);
517 return; 531 return;
518 } 532 }
519 } 533 }
@@ -536,7 +550,6 @@ at86rf230_async_state_delay(void *context)
536 struct at86rf230_local *lp = ctx->lp; 550 struct at86rf230_local *lp = ctx->lp;
537 struct at86rf2xx_chip_data *c = lp->data; 551 struct at86rf2xx_chip_data *c = lp->data;
538 bool force = false; 552 bool force = false;
539 int rc;
540 553
541 /* The force state changes are will show as normal states in the 554 /* The force state changes are will show as normal states in the
542 * state status subregister. We change the to_state to the 555 * state status subregister. We change the to_state to the
@@ -605,10 +618,9 @@ at86rf230_async_state_delay(void *context)
605 udelay(1); 618 udelay(1);
606 619
607change: 620change:
608 rc = at86rf230_async_read_reg(lp, RG_TRX_STATUS, ctx, 621 at86rf230_async_read_reg(lp, RG_TRX_STATUS, ctx,
609 at86rf230_async_state_assert); 622 at86rf230_async_state_assert,
610 if (rc) 623 ctx->irq_enable);
611 dev_err(&lp->spi->dev, "spi_async error %d\n", rc);
612} 624}
613 625
614static void 626static void
@@ -623,10 +635,9 @@ at86rf230_async_state_change_start(void *context)
623 /* Check for "possible" STATE_TRANSITION_IN_PROGRESS */ 635 /* Check for "possible" STATE_TRANSITION_IN_PROGRESS */
624 if (trx_state == STATE_TRANSITION_IN_PROGRESS) { 636 if (trx_state == STATE_TRANSITION_IN_PROGRESS) {
625 udelay(1); 637 udelay(1);
626 rc = at86rf230_async_read_reg(lp, RG_TRX_STATUS, ctx, 638 at86rf230_async_read_reg(lp, RG_TRX_STATUS, ctx,
627 at86rf230_async_state_change_start); 639 at86rf230_async_state_change_start,
628 if (rc) 640 ctx->irq_enable);
629 dev_err(&lp->spi->dev, "spi_async error %d\n", rc);
630 return; 641 return;
631 } 642 }
632 643
@@ -648,20 +659,28 @@ at86rf230_async_state_change_start(void *context)
648 ctx->trx.len = 2; 659 ctx->trx.len = 2;
649 ctx->msg.complete = at86rf230_async_state_delay; 660 ctx->msg.complete = at86rf230_async_state_delay;
650 rc = spi_async(lp->spi, &ctx->msg); 661 rc = spi_async(lp->spi, &ctx->msg);
651 if (rc) 662 if (rc) {
663 if (ctx->irq_enable)
664 enable_irq(lp->spi->irq);
665
666 at86rf230_async_error(lp, &lp->state, rc);
652 dev_err(&lp->spi->dev, "spi_async error %d\n", rc); 667 dev_err(&lp->spi->dev, "spi_async error %d\n", rc);
668 }
653} 669}
654 670
655static int 671static void
656at86rf230_async_state_change(struct at86rf230_local *lp, 672at86rf230_async_state_change(struct at86rf230_local *lp,
657 struct at86rf230_state_change *ctx, 673 struct at86rf230_state_change *ctx,
658 const u8 state, void (*complete)(void *context)) 674 const u8 state, void (*complete)(void *context),
675 const bool irq_enable)
659{ 676{
660 /* Initialization for the state change context */ 677 /* Initialization for the state change context */
661 ctx->to_state = state; 678 ctx->to_state = state;
662 ctx->complete = complete; 679 ctx->complete = complete;
663 return at86rf230_async_read_reg(lp, RG_TRX_STATUS, ctx, 680 ctx->irq_enable = irq_enable;
664 at86rf230_async_state_change_start); 681 at86rf230_async_read_reg(lp, RG_TRX_STATUS, ctx,
682 at86rf230_async_state_change_start,
683 irq_enable);
665} 684}
666 685
667static void 686static void
@@ -682,12 +701,9 @@ at86rf230_sync_state_change(struct at86rf230_local *lp, unsigned int state)
682{ 701{
683 int rc; 702 int rc;
684 703
685 rc = at86rf230_async_state_change(lp, &lp->state, state, 704 at86rf230_async_state_change(lp, &lp->state, state,
686 at86rf230_sync_state_change_complete); 705 at86rf230_sync_state_change_complete,
687 if (rc) { 706 false);
688 at86rf230_async_error(lp, &lp->state, rc);
689 return rc;
690 }
691 707
692 rc = wait_for_completion_timeout(&lp->state_complete, 708 rc = wait_for_completion_timeout(&lp->state_complete,
693 msecs_to_jiffies(100)); 709 msecs_to_jiffies(100));
@@ -714,12 +730,9 @@ at86rf230_tx_on(void *context)
714{ 730{
715 struct at86rf230_state_change *ctx = context; 731 struct at86rf230_state_change *ctx = context;
716 struct at86rf230_local *lp = ctx->lp; 732 struct at86rf230_local *lp = ctx->lp;
717 int rc;
718 733
719 rc = at86rf230_async_state_change(lp, &lp->irq, STATE_RX_AACK_ON, 734 at86rf230_async_state_change(lp, &lp->irq, STATE_RX_AACK_ON,
720 at86rf230_tx_complete); 735 at86rf230_tx_complete, true);
721 if (rc)
722 at86rf230_async_error(lp, ctx, rc);
723} 736}
724 737
725static void 738static void
@@ -727,12 +740,9 @@ at86rf230_tx_trac_error(void *context)
727{ 740{
728 struct at86rf230_state_change *ctx = context; 741 struct at86rf230_state_change *ctx = context;
729 struct at86rf230_local *lp = ctx->lp; 742 struct at86rf230_local *lp = ctx->lp;
730 int rc;
731 743
732 rc = at86rf230_async_state_change(lp, ctx, STATE_TX_ON, 744 at86rf230_async_state_change(lp, ctx, STATE_TX_ON,
733 at86rf230_tx_on); 745 at86rf230_tx_on, true);
734 if (rc)
735 at86rf230_async_error(lp, ctx, rc);
736} 746}
737 747
738static void 748static void
@@ -742,17 +752,14 @@ at86rf230_tx_trac_check(void *context)
742 struct at86rf230_local *lp = ctx->lp; 752 struct at86rf230_local *lp = ctx->lp;
743 const u8 *buf = ctx->buf; 753 const u8 *buf = ctx->buf;
744 const u8 trac = (buf[1] & 0xe0) >> 5; 754 const u8 trac = (buf[1] & 0xe0) >> 5;
745 int rc;
746 755
747 /* If trac status is different than zero we need to do a state change 756 /* If trac status is different than zero we need to do a state change
748 * to STATE_FORCE_TRX_OFF then STATE_TX_ON to recover the transceiver 757 * to STATE_FORCE_TRX_OFF then STATE_TX_ON to recover the transceiver
749 * state to TX_ON. 758 * state to TX_ON.
750 */ 759 */
751 if (trac) { 760 if (trac) {
752 rc = at86rf230_async_state_change(lp, ctx, STATE_FORCE_TRX_OFF, 761 at86rf230_async_state_change(lp, ctx, STATE_FORCE_TRX_OFF,
753 at86rf230_tx_trac_error); 762 at86rf230_tx_trac_error, true);
754 if (rc)
755 at86rf230_async_error(lp, ctx, rc);
756 return; 763 return;
757 } 764 }
758 765
@@ -765,12 +772,9 @@ at86rf230_tx_trac_status(void *context)
765{ 772{
766 struct at86rf230_state_change *ctx = context; 773 struct at86rf230_state_change *ctx = context;
767 struct at86rf230_local *lp = ctx->lp; 774 struct at86rf230_local *lp = ctx->lp;
768 int rc;
769 775
770 rc = at86rf230_async_read_reg(lp, RG_TRX_STATE, ctx, 776 at86rf230_async_read_reg(lp, RG_TRX_STATE, ctx,
771 at86rf230_tx_trac_check); 777 at86rf230_tx_trac_check, true);
772 if (rc)
773 at86rf230_async_error(lp, ctx, rc);
774} 778}
775 779
776static void 780static void
@@ -823,15 +827,21 @@ at86rf230_rx_read_frame_complete(void *context)
823 at86rf230_rx(lp, buf + 2, len); 827 at86rf230_rx(lp, buf + 2, len);
824} 828}
825 829
826static int 830static void
827at86rf230_rx_read_frame(struct at86rf230_local *lp) 831at86rf230_rx_read_frame(struct at86rf230_local *lp)
828{ 832{
833 int rc;
834
829 u8 *buf = lp->irq.buf; 835 u8 *buf = lp->irq.buf;
830 836
831 buf[0] = CMD_FB; 837 buf[0] = CMD_FB;
832 lp->irq.trx.len = AT86RF2XX_MAX_BUF; 838 lp->irq.trx.len = AT86RF2XX_MAX_BUF;
833 lp->irq.msg.complete = at86rf230_rx_read_frame_complete; 839 lp->irq.msg.complete = at86rf230_rx_read_frame_complete;
834 return spi_async(lp->spi, &lp->irq.msg); 840 rc = spi_async(lp->spi, &lp->irq.msg);
841 if (rc) {
842 enable_irq(lp->spi->irq);
843 at86rf230_async_error(lp, &lp->irq, rc);
844 }
835} 845}
836 846
837static void 847static void
@@ -839,7 +849,6 @@ at86rf230_rx_trac_check(void *context)
839{ 849{
840 struct at86rf230_state_change *ctx = context; 850 struct at86rf230_state_change *ctx = context;
841 struct at86rf230_local *lp = ctx->lp; 851 struct at86rf230_local *lp = ctx->lp;
842 int rc;
843 852
844 /* Possible check on trac status here. This could be useful to make 853 /* Possible check on trac status here. This could be useful to make
845 * some stats why receive is failed. Not used at the moment, but it's 854 * some stats why receive is failed. Not used at the moment, but it's
@@ -847,14 +856,10 @@ at86rf230_rx_trac_check(void *context)
847 * The programming guide say do it so. 856 * The programming guide say do it so.
848 */ 857 */
849 858
850 rc = at86rf230_rx_read_frame(lp); 859 at86rf230_rx_read_frame(lp);
851 if (rc) {
852 enable_irq(lp->spi->irq);
853 at86rf230_async_error(lp, ctx, rc);
854 }
855} 860}
856 861
857static int 862static void
858at86rf230_irq_trx_end(struct at86rf230_local *lp) 863at86rf230_irq_trx_end(struct at86rf230_local *lp)
859{ 864{
860 spin_lock(&lp->lock); 865 spin_lock(&lp->lock);
@@ -863,17 +868,19 @@ at86rf230_irq_trx_end(struct at86rf230_local *lp)
863 spin_unlock(&lp->lock); 868 spin_unlock(&lp->lock);
864 869
865 if (lp->tx_aret) 870 if (lp->tx_aret)
866 return at86rf230_async_state_change(lp, &lp->irq, 871 at86rf230_async_state_change(lp, &lp->irq,
867 STATE_FORCE_TX_ON, 872 STATE_FORCE_TX_ON,
868 at86rf230_tx_trac_status); 873 at86rf230_tx_trac_status,
874 true);
869 else 875 else
870 return at86rf230_async_state_change(lp, &lp->irq, 876 at86rf230_async_state_change(lp, &lp->irq,
871 STATE_RX_AACK_ON, 877 STATE_RX_AACK_ON,
872 at86rf230_tx_complete); 878 at86rf230_tx_complete,
879 true);
873 } else { 880 } else {
874 spin_unlock(&lp->lock); 881 spin_unlock(&lp->lock);
875 return at86rf230_async_read_reg(lp, RG_TRX_STATE, &lp->irq, 882 at86rf230_async_read_reg(lp, RG_TRX_STATE, &lp->irq,
876 at86rf230_rx_trac_check); 883 at86rf230_rx_trac_check, true);
877 } 884 }
878} 885}
879 886
@@ -884,12 +891,9 @@ at86rf230_irq_status(void *context)
884 struct at86rf230_local *lp = ctx->lp; 891 struct at86rf230_local *lp = ctx->lp;
885 const u8 *buf = lp->irq.buf; 892 const u8 *buf = lp->irq.buf;
886 const u8 irq = buf[1]; 893 const u8 irq = buf[1];
887 int rc;
888 894
889 if (irq & IRQ_TRX_END) { 895 if (irq & IRQ_TRX_END) {
890 rc = at86rf230_irq_trx_end(lp); 896 at86rf230_irq_trx_end(lp);
891 if (rc)
892 at86rf230_async_error(lp, ctx, rc);
893 } else { 897 } else {
894 enable_irq(lp->spi->irq); 898 enable_irq(lp->spi->irq);
895 dev_err(&lp->spi->dev, "not supported irq %02x received\n", 899 dev_err(&lp->spi->dev, "not supported irq %02x received\n",
@@ -964,12 +968,9 @@ at86rf230_xmit_tx_on(void *context)
964{ 968{
965 struct at86rf230_state_change *ctx = context; 969 struct at86rf230_state_change *ctx = context;
966 struct at86rf230_local *lp = ctx->lp; 970 struct at86rf230_local *lp = ctx->lp;
967 int rc;
968 971
969 rc = at86rf230_async_state_change(lp, ctx, STATE_TX_ARET_ON, 972 at86rf230_async_state_change(lp, ctx, STATE_TX_ARET_ON,
970 at86rf230_write_frame); 973 at86rf230_write_frame, false);
971 if (rc)
972 at86rf230_async_error(lp, ctx, rc);
973} 974}
974 975
975static int 976static int
@@ -990,12 +991,8 @@ at86rf230_xmit(struct ieee802154_dev *dev, struct sk_buff *skb)
990 if (lp->tx_aret) 991 if (lp->tx_aret)
991 tx_complete = at86rf230_xmit_tx_on; 992 tx_complete = at86rf230_xmit_tx_on;
992 993
993 rc = at86rf230_async_state_change(lp, ctx, STATE_TX_ON, 994 at86rf230_async_state_change(lp, ctx, STATE_TX_ON, tx_complete, false);
994 tx_complete); 995
995 if (rc) {
996 at86rf230_async_error(lp, ctx, rc);
997 return rc;
998 }
999 rc = wait_for_completion_interruptible_timeout(&lp->tx_complete, 996 rc = wait_for_completion_interruptible_timeout(&lp->tx_complete,
1000 msecs_to_jiffies(lp->data->t_tx_timeout)); 997 msecs_to_jiffies(lp->data->t_tx_timeout));
1001 if (!rc) { 998 if (!rc) {