diff options
author | Jiawen Wu <jiawenwu@trustnetic.com> | 2024-01-25 14:22:13 +0800 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2024-01-27 14:31:55 +0000 |
commit | aefd013624a10f39b0bfaee8432a235128705380 (patch) | |
tree | 1944f6508a496e54fdbefa5738ce61e7431470a8 /drivers/net/ethernet/wangxun/txgbe/txgbe_phy.c | |
parent | 63aabc3ef1961a5eb3049d02a323b3b7fabb9a23 (diff) |
net: txgbe: use irq_domain for interrupt controller
In the current interrupt controller, the MAC interrupt acts as the
parent interrupt in the GPIO IRQ chip. But when the number of Rx/Tx
ring changes, the PCI IRQ vector needs to be reallocated. Then this
interrupt controller would be corrupted. So use irq_domain structure
to avoid the above problem.
Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/wangxun/txgbe/txgbe_phy.c')
-rw-r--r-- | drivers/net/ethernet/wangxun/txgbe/txgbe_phy.c | 59 |
1 files changed, 21 insertions, 38 deletions
diff --git a/drivers/net/ethernet/wangxun/txgbe/txgbe_phy.c b/drivers/net/ethernet/wangxun/txgbe/txgbe_phy.c index 1b84d495d14e..bae0a8ee7014 100644 --- a/drivers/net/ethernet/wangxun/txgbe/txgbe_phy.c +++ b/drivers/net/ethernet/wangxun/txgbe/txgbe_phy.c @@ -292,6 +292,21 @@ static int txgbe_phylink_init(struct txgbe *txgbe) return 0; } +irqreturn_t txgbe_link_irq_handler(int irq, void *data) +{ + struct txgbe *txgbe = data; + struct wx *wx = txgbe->wx; + u32 status; + bool up; + + status = rd32(wx, TXGBE_CFG_PORT_ST); + up = !!(status & TXGBE_CFG_PORT_ST_LINK_UP); + + phylink_mac_change(wx->phylink, up); + + return IRQ_HANDLED; +} + static int txgbe_gpio_get(struct gpio_chip *chip, unsigned int offset) { struct wx *wx = gpiochip_get_data(chip); @@ -437,7 +452,7 @@ static int txgbe_gpio_set_type(struct irq_data *d, unsigned int type) } static const struct irq_chip txgbe_gpio_irq_chip = { - .name = "txgbe_gpio_irq", + .name = "txgbe-gpio-irq", .irq_ack = txgbe_gpio_irq_ack, .irq_mask = txgbe_gpio_irq_mask, .irq_unmask = txgbe_gpio_irq_unmask, @@ -446,20 +461,14 @@ static const struct irq_chip txgbe_gpio_irq_chip = { GPIOCHIP_IRQ_RESOURCE_HELPERS, }; -static void txgbe_irq_handler(struct irq_desc *desc) +irqreturn_t txgbe_gpio_irq_handler(int irq, void *data) { - struct irq_chip *chip = irq_desc_get_chip(desc); - struct wx *wx = irq_desc_get_handler_data(desc); - struct txgbe *txgbe = wx->priv; + struct txgbe *txgbe = data; + struct wx *wx = txgbe->wx; irq_hw_number_t hwirq; unsigned long gpioirq; struct gpio_chip *gc; unsigned long flags; - u32 eicr; - - eicr = wx_misc_isb(wx, WX_ISB_MISC); - - chained_irq_enter(chip, desc); gpioirq = rd32(wx, WX_GPIO_INTSTATUS); @@ -468,7 +477,7 @@ static void txgbe_irq_handler(struct irq_desc *desc) int gpio = irq_find_mapping(gc->irq.domain, hwirq); u32 irq_type = irq_get_trigger_type(gpio); - generic_handle_domain_irq(gc->irq.domain, hwirq); + handle_nested_irq(gpio); if ((irq_type & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH) { raw_spin_lock_irqsave(&wx->gpio_lock, flags); @@ -477,17 +486,7 @@ static void txgbe_irq_handler(struct irq_desc *desc) } } - chained_irq_exit(chip, desc); - - if (eicr & (TXGBE_PX_MISC_ETH_LK | TXGBE_PX_MISC_ETH_LKDN | - TXGBE_PX_MISC_ETH_AN)) { - u32 reg = rd32(wx, TXGBE_CFG_PORT_ST); - - phylink_mac_change(wx->phylink, !!(reg & TXGBE_CFG_PORT_ST_LINK_UP)); - } - - /* unmask interrupt */ - wx_intr_enable(wx, TXGBE_INTR_MISC); + return IRQ_HANDLED; } static int txgbe_gpio_init(struct txgbe *txgbe) @@ -524,19 +523,6 @@ static int txgbe_gpio_init(struct txgbe *txgbe) girq = &gc->irq; gpio_irq_chip_set_chip(girq, &txgbe_gpio_irq_chip); - girq->parent_handler = txgbe_irq_handler; - girq->parent_handler_data = wx; - girq->num_parents = 1; - girq->parents = devm_kcalloc(dev, girq->num_parents, - sizeof(*girq->parents), GFP_KERNEL); - if (!girq->parents) - return -ENOMEM; - - /* now only suuported on MSI-X interrupt */ - if (!wx->msix_entry) - return -EPERM; - - girq->parents[0] = wx->msix_entry->vector; girq->default_type = IRQ_TYPE_NONE; girq->handler = handle_bad_irq; @@ -754,8 +740,6 @@ int txgbe_init_phy(struct txgbe *txgbe) goto err_unregister_i2c; } - wx->msix_in_use = true; - return 0; err_unregister_i2c: @@ -788,5 +772,4 @@ void txgbe_remove_phy(struct txgbe *txgbe) phylink_destroy(txgbe->wx->phylink); xpcs_destroy(txgbe->xpcs); software_node_unregister_node_group(txgbe->nodes.group); - txgbe->wx->msix_in_use = false; } |