mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-20 22:23:27 +00:00
60 lines
1.6 KiB
Diff
60 lines
1.6 KiB
Diff
|
From b3797d1a92afe97c173b00fdb7824cedba24eef0 Mon Sep 17 00:00:00 2001
|
||
|
From: Chuanhong Guo <gch981213@gmail.com>
|
||
|
Date: Sun, 20 Sep 2020 01:00:45 +0800
|
||
|
Subject: [PATCH] ath79: ar8216: make switch register access atomic
|
||
|
|
||
|
due to some unknown reason these register accesses sometimes fail
|
||
|
on the integrated switch without this patch.
|
||
|
|
||
|
THIS ONLY WORKS ON ATH79 AND MAY BREAK THE DRIVER ON OTHER PLATFORMS!
|
||
|
The mdio bus on ath79 works in polling mode and doesn't rely on
|
||
|
any interrupt. This patch breaks the driver on any mdio master
|
||
|
with interrupts used.
|
||
|
|
||
|
---
|
||
|
--- a/drivers/net/phy/ar8216.c
|
||
|
+++ b/drivers/net/phy/ar8216.c
|
||
|
@@ -252,6 +252,7 @@ ar8xxx_mii_write32(struct ar8xxx_priv *p
|
||
|
u32
|
||
|
ar8xxx_read(struct ar8xxx_priv *priv, int reg)
|
||
|
{
|
||
|
+ unsigned long flags;
|
||
|
struct mii_bus *bus = priv->mii_bus;
|
||
|
u16 r1, r2, page;
|
||
|
u32 val;
|
||
|
@@ -259,11 +260,13 @@ ar8xxx_read(struct ar8xxx_priv *priv, in
|
||
|
split_addr((u32) reg, &r1, &r2, &page);
|
||
|
|
||
|
mutex_lock(&bus->mdio_lock);
|
||
|
+ local_irq_save(flags);
|
||
|
|
||
|
bus->write(bus, 0x18, 0, page);
|
||
|
wait_for_page_switch();
|
||
|
val = ar8xxx_mii_read32(priv, 0x10 | r2, r1);
|
||
|
|
||
|
+ local_irq_restore(flags);
|
||
|
mutex_unlock(&bus->mdio_lock);
|
||
|
|
||
|
return val;
|
||
|
@@ -272,17 +275,20 @@ ar8xxx_read(struct ar8xxx_priv *priv, in
|
||
|
void
|
||
|
ar8xxx_write(struct ar8xxx_priv *priv, int reg, u32 val)
|
||
|
{
|
||
|
+ unsigned long flags;
|
||
|
struct mii_bus *bus = priv->mii_bus;
|
||
|
u16 r1, r2, page;
|
||
|
|
||
|
split_addr((u32) reg, &r1, &r2, &page);
|
||
|
|
||
|
mutex_lock(&bus->mdio_lock);
|
||
|
+ local_irq_save(flags);
|
||
|
|
||
|
bus->write(bus, 0x18, 0, page);
|
||
|
wait_for_page_switch();
|
||
|
ar8xxx_mii_write32(priv, 0x10 | r2, r1, val);
|
||
|
|
||
|
+ local_irq_restore(flags);
|
||
|
mutex_unlock(&bus->mdio_lock);
|
||
|
}
|
||
|
|