diff options
Diffstat (limited to 'drivers/net/dsa')
| -rw-r--r-- | drivers/net/dsa/b53/b53_common.c | 8 | ||||
| -rw-r--r-- | drivers/net/dsa/mv88e6xxx/chip.c | 21 |
2 files changed, 17 insertions, 12 deletions
diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c index 5e010b1592f7..d93c790bfbe8 100644 --- a/drivers/net/dsa/b53/b53_common.c +++ b/drivers/net/dsa/b53/b53_common.c @@ -2044,14 +2044,14 @@ static int b53_switch_init(struct b53_device *dev) } } - dev->ports = devm_kzalloc(dev->dev, - sizeof(struct b53_port) * dev->num_ports, + dev->ports = devm_kcalloc(dev->dev, + dev->num_ports, sizeof(struct b53_port), GFP_KERNEL); if (!dev->ports) return -ENOMEM; - dev->vlans = devm_kzalloc(dev->dev, - sizeof(struct b53_vlan) * dev->num_vlans, + dev->vlans = devm_kcalloc(dev->dev, + dev->num_vlans, sizeof(struct b53_vlan), GFP_KERNEL); if (!dev->vlans) return -ENOMEM; diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c index 437cd6eb4faa..9ef07a06aceb 100644 --- a/drivers/net/dsa/mv88e6xxx/chip.c +++ b/drivers/net/dsa/mv88e6xxx/chip.c @@ -343,6 +343,7 @@ static const struct irq_domain_ops mv88e6xxx_g1_irq_domain_ops = { .xlate = irq_domain_xlate_twocell, }; +/* To be called with reg_lock held */ static void mv88e6xxx_g1_irq_free_common(struct mv88e6xxx_chip *chip) { int irq, virq; @@ -362,9 +363,15 @@ static void mv88e6xxx_g1_irq_free_common(struct mv88e6xxx_chip *chip) static void mv88e6xxx_g1_irq_free(struct mv88e6xxx_chip *chip) { - mv88e6xxx_g1_irq_free_common(chip); - + /* + * free_irq must be called without reg_lock taken because the irq + * handler takes this lock, too. + */ free_irq(chip->irq, chip); + + mutex_lock(&chip->reg_lock); + mv88e6xxx_g1_irq_free_common(chip); + mutex_unlock(&chip->reg_lock); } static int mv88e6xxx_g1_irq_setup_common(struct mv88e6xxx_chip *chip) @@ -469,10 +476,12 @@ static int mv88e6xxx_irq_poll_setup(struct mv88e6xxx_chip *chip) static void mv88e6xxx_irq_poll_free(struct mv88e6xxx_chip *chip) { - mv88e6xxx_g1_irq_free_common(chip); - kthread_cancel_delayed_work_sync(&chip->irq_poll_work); kthread_destroy_worker(chip->kworker); + + mutex_lock(&chip->reg_lock); + mv88e6xxx_g1_irq_free_common(chip); + mutex_unlock(&chip->reg_lock); } int mv88e6xxx_wait(struct mv88e6xxx_chip *chip, int addr, int reg, u16 mask) @@ -4506,12 +4515,10 @@ out_g2_irq: if (chip->info->g2_irqs > 0) mv88e6xxx_g2_irq_free(chip); out_g1_irq: - mutex_lock(&chip->reg_lock); if (chip->irq > 0) mv88e6xxx_g1_irq_free(chip); else mv88e6xxx_irq_poll_free(chip); - mutex_unlock(&chip->reg_lock); out: if (pdata) dev_put(pdata->netdev); @@ -4539,12 +4546,10 @@ static void mv88e6xxx_remove(struct mdio_device *mdiodev) if (chip->info->g2_irqs > 0) mv88e6xxx_g2_irq_free(chip); - mutex_lock(&chip->reg_lock); if (chip->irq > 0) mv88e6xxx_g1_irq_free(chip); else mv88e6xxx_irq_poll_free(chip); - mutex_unlock(&chip->reg_lock); } static const struct of_device_id mv88e6xxx_of_match[] = { |

