imx6: fix USB for 4.9 kernel
[oweals/openwrt.git] / target / linux / mvebu / patches-4.4 / 122-phy-separate-swphy-state-validation-from-register-ge.patch
1 From e07630ad84c7dc145863f079f108154fb7c975e7 Mon Sep 17 00:00:00 2001
2 From: Russell King <rmk+kernel@arm.linux.org.uk>
3 Date: Sun, 20 Sep 2015 11:12:15 +0100
4 Subject: [PATCH 711/744] phy: separate swphy state validation from register
5  generation
6
7 Separate out the generation of MII registers from the state validation.
8 This allows us to simplify the error handing in fixed_phy() by allowing
9 earlier error detection.
10
11 Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
12 Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
13 ---
14  drivers/net/phy/fixed_phy.c | 15 +++++++--------
15  drivers/net/phy/swphy.c     | 33 ++++++++++++++++++++++++++-------
16  drivers/net/phy/swphy.h     |  3 ++-
17  3 files changed, 35 insertions(+), 16 deletions(-)
18
19 --- a/drivers/net/phy/fixed_phy.c
20 +++ b/drivers/net/phy/fixed_phy.c
21 @@ -49,12 +49,12 @@ static struct fixed_mdio_bus platform_fm
22         .phys = LIST_HEAD_INIT(platform_fmb.phys),
23  };
24  
25 -static int fixed_phy_update_regs(struct fixed_phy *fp)
26 +static void fixed_phy_update_regs(struct fixed_phy *fp)
27  {
28         if (gpio_is_valid(fp->link_gpio))
29                 fp->status.link = !!gpio_get_value_cansleep(fp->link_gpio);
30  
31 -       return swphy_update_regs(fp->regs, &fp->status);
32 +       swphy_update_regs(fp->regs, &fp->status);
33  }
34  
35  static int fixed_mdio_read(struct mii_bus *bus, int phy_addr, int reg_num)
36 @@ -161,6 +161,10 @@ int fixed_phy_add(unsigned int irq, int
37         struct fixed_mdio_bus *fmb = &platform_fmb;
38         struct fixed_phy *fp;
39  
40 +       ret = swphy_validate_state(status);
41 +       if (ret < 0)
42 +               return ret;
43 +
44         fp = kzalloc(sizeof(*fp), GFP_KERNEL);
45         if (!fp)
46                 return -ENOMEM;
47 @@ -180,17 +184,12 @@ int fixed_phy_add(unsigned int irq, int
48                         goto err_regs;
49         }
50  
51 -       ret = fixed_phy_update_regs(fp);
52 -       if (ret)
53 -               goto err_gpio;
54 +       fixed_phy_update_regs(fp);
55  
56         list_add_tail(&fp->node, &fmb->phys);
57  
58         return 0;
59  
60 -err_gpio:
61 -       if (gpio_is_valid(fp->link_gpio))
62 -               gpio_free(fp->link_gpio);
63  err_regs:
64         kfree(fp);
65         return ret;
66 --- a/drivers/net/phy/swphy.c
67 +++ b/drivers/net/phy/swphy.c
68 @@ -87,6 +87,29 @@ static int swphy_decode_speed(int speed)
69  }
70  
71  /**
72 + * swphy_validate_state - validate the software phy status
73 + * @state: software phy status
74 + *
75 + * This checks that we can represent the state stored in @state can be
76 + * represented in the emulated MII registers.  Returns 0 if it can,
77 + * otherwise returns -EINVAL.
78 + */
79 +int swphy_validate_state(const struct fixed_phy_status *state)
80 +{
81 +       int err;
82 +
83 +       if (state->link) {
84 +               err = swphy_decode_speed(state->speed);
85 +               if (err < 0) {
86 +                       pr_warn("swphy: unknown speed\n");
87 +                       return -EINVAL;
88 +               }
89 +       }
90 +       return 0;
91 +}
92 +EXPORT_SYMBOL_GPL(swphy_validate_state);
93 +
94 +/**
95   * swphy_update_regs - update MII register array with fixed phy state
96   * @regs: array of 32 registers to update
97   * @state: fixed phy status
98 @@ -94,7 +117,7 @@ static int swphy_decode_speed(int speed)
99   * Update the array of MII registers with the fixed phy link, speed,
100   * duplex and pause mode settings.
101   */
102 -int swphy_update_regs(u16 *regs, const struct fixed_phy_status *state)
103 +void swphy_update_regs(u16 *regs, const struct fixed_phy_status *state)
104  {
105         int speed_index, duplex_index;
106         u16 bmsr = BMSR_ANEGCAPABLE;
107 @@ -103,10 +126,8 @@ int swphy_update_regs(u16 *regs, const s
108         u16 lpa = 0;
109  
110         speed_index = swphy_decode_speed(state->speed);
111 -       if (speed_index < 0) {
112 -               pr_warn("swphy: unknown speed\n");
113 -               return -EINVAL;
114 -       }
115 +       if (WARN_ON(speed_index < 0))
116 +               return;
117  
118         duplex_index = state->duplex ? SWMII_DUPLEX_FULL : SWMII_DUPLEX_HALF;
119  
120 @@ -133,7 +154,5 @@ int swphy_update_regs(u16 *regs, const s
121         regs[MII_BMCR] = bmcr;
122         regs[MII_LPA] = lpa;
123         regs[MII_STAT1000] = lpagb;
124 -
125 -       return 0;
126  }
127  EXPORT_SYMBOL_GPL(swphy_update_regs);
128 --- a/drivers/net/phy/swphy.h
129 +++ b/drivers/net/phy/swphy.h
130 @@ -3,6 +3,7 @@
131  
132  struct fixed_phy_status;
133  
134 -int swphy_update_regs(u16 *regs, const struct fixed_phy_status *state);
135 +int swphy_validate_state(const struct fixed_phy_status *state);
136 +void swphy_update_regs(u16 *regs, const struct fixed_phy_status *state);
137  
138  #endif