aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ieee802154
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ieee802154')
-rw-r--r--drivers/net/ieee802154/at86rf230.c53
1 files changed, 38 insertions, 15 deletions
diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c
index cf098889ba64..6f10b4964726 100644
--- a/drivers/net/ieee802154/at86rf230.c
+++ b/drivers/net/ieee802154/at86rf230.c
@@ -51,7 +51,7 @@ struct at86rf230_local {
51 struct ieee802154_dev *dev; 51 struct ieee802154_dev *dev;
52 52
53 spinlock_t lock; 53 spinlock_t lock;
54 bool irq_disabled; 54 bool irq_busy;
55 bool is_tx; 55 bool is_tx;
56}; 56};
57 57
@@ -547,7 +547,7 @@ at86rf230_xmit(struct ieee802154_dev *dev, struct sk_buff *skb)
547 unsigned long flags; 547 unsigned long flags;
548 548
549 spin_lock(&lp->lock); 549 spin_lock(&lp->lock);
550 if (lp->irq_disabled) { 550 if (lp->irq_busy) {
551 spin_unlock(&lp->lock); 551 spin_unlock(&lp->lock);
552 return -EBUSY; 552 return -EBUSY;
553 } 553 }
@@ -708,8 +708,16 @@ static void at86rf230_irqwork(struct work_struct *work)
708 } 708 }
709 709
710 spin_lock_irqsave(&lp->lock, flags); 710 spin_lock_irqsave(&lp->lock, flags);
711 lp->irq_disabled = 0; 711 lp->irq_busy = 0;
712 spin_unlock_irqrestore(&lp->lock, flags); 712 spin_unlock_irqrestore(&lp->lock, flags);
713}
714
715static void at86rf230_irqwork_level(struct work_struct *work)
716{
717 struct at86rf230_local *lp =
718 container_of(work, struct at86rf230_local, irqwork);
719
720 at86rf230_irqwork(work);
713 721
714 enable_irq(lp->spi->irq); 722 enable_irq(lp->spi->irq);
715} 723}
@@ -718,10 +726,8 @@ static irqreturn_t at86rf230_isr(int irq, void *data)
718{ 726{
719 struct at86rf230_local *lp = data; 727 struct at86rf230_local *lp = data;
720 728
721 disable_irq_nosync(irq);
722
723 spin_lock(&lp->lock); 729 spin_lock(&lp->lock);
724 lp->irq_disabled = 1; 730 lp->irq_busy = 1;
725 spin_unlock(&lp->lock); 731 spin_unlock(&lp->lock);
726 732
727 schedule_work(&lp->irqwork); 733 schedule_work(&lp->irqwork);
@@ -729,6 +735,13 @@ static irqreturn_t at86rf230_isr(int irq, void *data)
729 return IRQ_HANDLED; 735 return IRQ_HANDLED;
730} 736}
731 737
738static irqreturn_t at86rf230_isr_level(int irq, void *data)
739{
740 disable_irq_nosync(irq);
741
742 return at86rf230_isr(irq, data);
743}
744
732static int at86rf230_irq_polarity(struct at86rf230_local *lp, int pol) 745static int at86rf230_irq_polarity(struct at86rf230_local *lp, int pol)
733{ 746{
734 return at86rf230_write_subreg(lp, SR_IRQ_POLARITY, pol); 747 return at86rf230_write_subreg(lp, SR_IRQ_POLARITY, pol);
@@ -766,12 +779,7 @@ static int at86rf230_hw_init(struct at86rf230_local *lp)
766 if (rc) 779 if (rc)
767 return rc; 780 return rc;
768 781
769 rc = at86rf230_write_subreg(lp, SR_IRQ_MASK, 0xff); /* IRQ_TRX_UR | 782 rc = at86rf230_write_subreg(lp, SR_IRQ_MASK, IRQ_TRX_END);
770 * IRQ_CCA_ED |
771 * IRQ_TRX_END |
772 * IRQ_PLL_UNL |
773 * IRQ_PLL_LOCK
774 */
775 if (rc) 783 if (rc)
776 return rc; 784 return rc;
777 785
@@ -831,7 +839,9 @@ static int at86rf230_probe(struct spi_device *spi)
831 struct at86rf230_platform_data *pdata; 839 struct at86rf230_platform_data *pdata;
832 struct ieee802154_dev *dev; 840 struct ieee802154_dev *dev;
833 struct at86rf230_local *lp; 841 struct at86rf230_local *lp;
834 u8 man_id_0, man_id_1; 842 u8 man_id_0, man_id_1, status;
843 irq_handler_t irq_handler;
844 work_func_t irq_worker;
835 int rc, supported = 0; 845 int rc, supported = 0;
836 const char *chip; 846 const char *chip;
837 847
@@ -861,8 +871,16 @@ static int at86rf230_probe(struct spi_device *spi)
861 dev->phy->channels_supported[0] = 0x7FFF800; 871 dev->phy->channels_supported[0] = 0x7FFF800;
862 dev->flags = IEEE802154_HW_OMIT_CKSUM; 872 dev->flags = IEEE802154_HW_OMIT_CKSUM;
863 873
874 if (pdata->irq_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) {
875 irq_worker = at86rf230_irqwork;
876 irq_handler = at86rf230_isr;
877 } else {
878 irq_worker = at86rf230_irqwork_level;
879 irq_handler = at86rf230_isr_level;
880 }
881
864 mutex_init(&lp->bmux); 882 mutex_init(&lp->bmux);
865 INIT_WORK(&lp->irqwork, at86rf230_irqwork); 883 INIT_WORK(&lp->irqwork, irq_worker);
866 spin_lock_init(&lp->lock); 884 spin_lock_init(&lp->lock);
867 init_completion(&lp->tx_complete); 885 init_completion(&lp->tx_complete);
868 886
@@ -943,12 +961,17 @@ static int at86rf230_probe(struct spi_device *spi)
943 if (rc) 961 if (rc)
944 goto err_gpio_dir; 962 goto err_gpio_dir;
945 963
946 rc = request_irq(spi->irq, at86rf230_isr, 964 rc = request_irq(spi->irq, irq_handler,
947 IRQF_SHARED | pdata->irq_type, 965 IRQF_SHARED | pdata->irq_type,
948 dev_name(&spi->dev), lp); 966 dev_name(&spi->dev), lp);
949 if (rc) 967 if (rc)
950 goto err_gpio_dir; 968 goto err_gpio_dir;
951 969
970 /* Read irq status register to reset irq line */
971 rc = at86rf230_read_subreg(lp, RG_IRQ_STATUS, 0xff, 0, &status);
972 if (rc)
973 goto err_irq;
974
952 rc = ieee802154_register_device(lp->dev); 975 rc = ieee802154_register_device(lp->dev);
953 if (rc) 976 if (rc)
954 goto err_irq; 977 goto err_irq;