ar71xx: Add QCA955X GPIO mux and function definitions
[openwrt.git] / target / linux / ar71xx / patches-4.4 / 901-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/phy/mdio-bitbang.c | 9 +++++++++
13  1 file changed, 9 insertions(+)
14
15 --- a/drivers/net/phy/mdio-bitbang.c
16 +++ b/drivers/net/phy/mdio-bitbang.c
17 @@ -17,6 +17,7 @@
18   * kind, whether express or implied.
19   */
20  
21 +#include <linux/irqflags.h>
22  #include <linux/module.h>
23  #include <linux/mdio-bitbang.h>
24  #include <linux/types.h>
25 @@ -156,7 +157,9 @@ static int mdiobb_read(struct mii_bus *b
26  {
27         struct mdiobb_ctrl *ctrl = bus->priv;
28         int ret, i;
29 +       long flags;
30  
31 +       local_irq_save(flags);
32         if (reg & MII_ADDR_C45) {
33                 reg = mdiobb_cmd_addr(ctrl, phy, reg);
34                 mdiobb_cmd(ctrl, MDIO_C45_READ, phy, reg);
35 @@ -169,13 +172,17 @@ static int mdiobb_read(struct mii_bus *b
36  
37         ret = mdiobb_get_num(ctrl, 16);
38         mdiobb_get_bit(ctrl);
39 +       local_irq_restore(flags);
40 +
41         return ret;
42  }
43  
44  static int mdiobb_write(struct mii_bus *bus, int phy, int reg, u16 val)
45  {
46         struct mdiobb_ctrl *ctrl = bus->priv;
47 +       long flags;
48  
49 +       local_irq_save(flags);
50         if (reg & MII_ADDR_C45) {
51                 reg = mdiobb_cmd_addr(ctrl, phy, reg);
52                 mdiobb_cmd(ctrl, MDIO_C45_WRITE, phy, reg);
53 @@ -190,6 +197,8 @@ static int mdiobb_write(struct mii_bus *
54  
55         ctrl->ops->set_mdio_dir(ctrl, 0);
56         mdiobb_get_bit(ctrl);
57 +       local_irq_restore(flags);
58 +
59         return 0;
60  }
61