ath79: refresh 6.6 kernel patches
[openwrt/openwrt.git] / target / linux / ath79 / patches-6.6 / 721-phy-mdio-bitbang-prevent-rescheduling-during-command.patch
1 From 66e584435ac0de6e0abeb6d7166fe4fe25d6bb73 Mon Sep 17 00:00:00 2001
2 From: Jonas Gorski <jogo@openwrt.org>
3 Date: Tue, 16 Jun 2015 13:15:08 +0200
4 Subject: [PATCH] phy/mdio-bitbang: prevent rescheduling during command
5
6 It seems some phys have some maximum timings for accessing the MDIO line,
7 resulting in bit errors under cpu stress. Prevent this from happening by
8 disabling interrupts when sending commands.
9
10 Signed-off-by: Jonas Gorski <jogo@openwrt.org>
11 ---
12 drivers/net/mdio/mdio-bitbang.c | 9 +++++++++
13 1 file changed, 9 insertions(+)
14
15 --- a/drivers/net/mdio/mdio-bitbang.c
16 +++ b/drivers/net/mdio/mdio-bitbang.c
17 @@ -14,6 +14,7 @@
18 * Vitaly Bordug <vbordug@ru.mvista.com>
19 */
20
21 +#include <linux/irqflags.h>
22 #include <linux/delay.h>
23 #include <linux/mdio-bitbang.h>
24 #include <linux/module.h>
25 @@ -161,22 +162,32 @@ static int mdiobb_read_common(struct mii
26
27 int mdiobb_read_c22(struct mii_bus *bus, int phy, int reg)
28 {
29 + int ret;
30 + unsigned long flags;
31 struct mdiobb_ctrl *ctrl = bus->priv;
32
33 + local_irq_save(flags);
34 mdiobb_cmd(ctrl, ctrl->op_c22_read, phy, reg);
35
36 - return mdiobb_read_common(bus, phy);
37 + ret = mdiobb_read_common(bus, phy);
38 + local_irq_restore(flags);
39 + return ret;
40 }
41 EXPORT_SYMBOL(mdiobb_read_c22);
42
43 int mdiobb_read_c45(struct mii_bus *bus, int phy, int devad, int reg)
44 {
45 + int ret;
46 + unsigned long flags;
47 struct mdiobb_ctrl *ctrl = bus->priv;
48
49 + local_irq_save(flags);
50 mdiobb_cmd_addr(ctrl, phy, devad, reg);
51 mdiobb_cmd(ctrl, MDIO_C45_READ, phy, devad);
52
53 - return mdiobb_read_common(bus, phy);
54 + ret = mdiobb_read_common(bus, phy);
55 + local_irq_restore(flags);
56 + return ret;
57 }
58 EXPORT_SYMBOL(mdiobb_read_c45);
59
60 @@ -197,22 +208,32 @@ static int mdiobb_write_common(struct mi
61
62 int mdiobb_write_c22(struct mii_bus *bus, int phy, int reg, u16 val)
63 {
64 + int ret;
65 + unsigned long flags;
66 struct mdiobb_ctrl *ctrl = bus->priv;
67
68 + local_irq_save(flags);
69 mdiobb_cmd(ctrl, ctrl->op_c22_write, phy, reg);
70
71 - return mdiobb_write_common(bus, val);
72 + ret = mdiobb_write_common(bus, val);
73 + local_irq_restore(flags);
74 + return ret;
75 }
76 EXPORT_SYMBOL(mdiobb_write_c22);
77
78 int mdiobb_write_c45(struct mii_bus *bus, int phy, int devad, int reg, u16 val)
79 {
80 + int ret;
81 + unsigned long flags;
82 struct mdiobb_ctrl *ctrl = bus->priv;
83
84 + local_irq_save(flags);
85 mdiobb_cmd_addr(ctrl, phy, devad, reg);
86 mdiobb_cmd(ctrl, MDIO_C45_WRITE, phy, devad);
87
88 - return mdiobb_write_common(bus, val);
89 + ret = mdiobb_write_common(bus, val);
90 + local_irq_restore(flags);
91 + return ret;
92 }
93 EXPORT_SYMBOL(mdiobb_write_c45);
94