dddfcc201869c88038fedebb275faef205266178
[oweals/openwrt.git] /
1 From c1e3f753f6b85d7636024159bb78f764e09492f1 Mon Sep 17 00:00:00 2001
2 From: Heiner Kallweit <hkallweit1@gmail.com>
3 Date: Sun, 10 Feb 2019 19:57:56 +0100
4 Subject: [PATCH 604/660] net: phy: add register modifying helpers returning 1
5  on change
6
7 When modifying registers there are scenarios where we need to know
8 whether the register content actually changed. This patch adds
9 new helpers to not break users of the current ones, phy_modify() etc.
10
11 Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
12 Reviewed-by: Andrew Lunn <andrew@lunn.ch>
13 Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
14 Signed-off-by: David S. Miller <davem@davemloft.net>
15 Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
16 ---
17  drivers/net/phy/phy-core.c | 127 ++++++++++++++++++++++++++++++++++---
18  include/linux/phy.h        |  12 +++-
19  2 files changed, 128 insertions(+), 11 deletions(-)
20
21 --- a/drivers/net/phy/phy-core.c
22 +++ b/drivers/net/phy/phy-core.c
23 @@ -364,7 +364,7 @@ int phy_write_mmd(struct phy_device *phy
24  EXPORT_SYMBOL(phy_write_mmd);
25  
26  /**
27 - * __phy_modify() - Convenience function for modifying a PHY register
28 + * __phy_modify_changed() - Convenience function for modifying a PHY register
29   * @phydev: a pointer to a &struct phy_device
30   * @regnum: register number
31   * @mask: bit mask of bits to clear
32 @@ -372,16 +372,69 @@ EXPORT_SYMBOL(phy_write_mmd);
33   *
34   * Unlocked helper function which allows a PHY register to be modified as
35   * new register value = (old register value & ~mask) | set
36 + *
37 + * Returns negative errno, 0 if there was no change, and 1 in case of change
38   */
39 -int __phy_modify(struct phy_device *phydev, u32 regnum, u16 mask, u16 set)
40 +int __phy_modify_changed(struct phy_device *phydev, u32 regnum, u16 mask,
41 +                        u16 set)
42  {
43 -       int ret;
44 +       int new, ret;
45  
46         ret = __phy_read(phydev, regnum);
47         if (ret < 0)
48                 return ret;
49  
50 -       ret = __phy_write(phydev, regnum, (ret & ~mask) | set);
51 +       new = (ret & ~mask) | set;
52 +       if (new == ret)
53 +               return 0;
54 +
55 +       ret = __phy_write(phydev, regnum, new);
56 +
57 +       return ret < 0 ? ret : 1;
58 +}
59 +EXPORT_SYMBOL_GPL(__phy_modify_changed);
60 +
61 +/**
62 + * phy_modify_changed - Function for modifying a PHY register
63 + * @phydev: the phy_device struct
64 + * @regnum: register number to modify
65 + * @mask: bit mask of bits to clear
66 + * @set: new value of bits set in mask to write to @regnum
67 + *
68 + * NOTE: MUST NOT be called from interrupt context,
69 + * because the bus read/write functions may wait for an interrupt
70 + * to conclude the operation.
71 + *
72 + * Returns negative errno, 0 if there was no change, and 1 in case of change
73 + */
74 +int phy_modify_changed(struct phy_device *phydev, u32 regnum, u16 mask, u16 set)
75 +{
76 +       int ret;
77 +
78 +       mutex_lock(&phydev->mdio.bus->mdio_lock);
79 +       ret = __phy_modify_changed(phydev, regnum, mask, set);
80 +       mutex_unlock(&phydev->mdio.bus->mdio_lock);
81 +
82 +       return ret;
83 +}
84 +EXPORT_SYMBOL_GPL(phy_modify_changed);
85 +
86 +/**
87 + * __phy_modify - Convenience function for modifying a PHY register
88 + * @phydev: the phy_device struct
89 + * @regnum: register number to modify
90 + * @mask: bit mask of bits to clear
91 + * @set: new value of bits set in mask to write to @regnum
92 + *
93 + * NOTE: MUST NOT be called from interrupt context,
94 + * because the bus read/write functions may wait for an interrupt
95 + * to conclude the operation.
96 + */
97 +int __phy_modify(struct phy_device *phydev, u32 regnum, u16 mask, u16 set)
98 +{
99 +       int ret;
100 +
101 +       ret = __phy_modify_changed(phydev, regnum, mask, set);
102  
103         return ret < 0 ? ret : 0;
104  }
105 @@ -411,7 +464,7 @@ int phy_modify(struct phy_device *phydev
106  EXPORT_SYMBOL_GPL(phy_modify);
107  
108  /**
109 - * __phy_modify_mmd - Convenience function for modifying a register on MMD
110 + * __phy_modify_mmd_changed - Function for modifying a register on MMD
111   * @phydev: the phy_device struct
112   * @devad: the MMD containing register to modify
113   * @regnum: register number to modify
114 @@ -420,17 +473,73 @@ EXPORT_SYMBOL_GPL(phy_modify);
115   *
116   * Unlocked helper function which allows a MMD register to be modified as
117   * new register value = (old register value & ~mask) | set
118 + *
119 + * Returns negative errno, 0 if there was no change, and 1 in case of change
120   */
121 -int __phy_modify_mmd(struct phy_device *phydev, int devad, u32 regnum,
122 -                    u16 mask, u16 set)
123 +int __phy_modify_mmd_changed(struct phy_device *phydev, int devad, u32 regnum,
124 +                            u16 mask, u16 set)
125  {
126 -       int ret;
127 +       int new, ret;
128  
129         ret = __phy_read_mmd(phydev, devad, regnum);
130         if (ret < 0)
131                 return ret;
132  
133 -       ret = __phy_write_mmd(phydev, devad, regnum, (ret & ~mask) | set);
134 +       new = (ret & ~mask) | set;
135 +       if (new == ret)
136 +               return 0;
137 +
138 +       ret = __phy_write_mmd(phydev, devad, regnum, new);
139 +
140 +       return ret < 0 ? ret : 1;
141 +}
142 +EXPORT_SYMBOL_GPL(__phy_modify_mmd_changed);
143 +
144 +/**
145 + * phy_modify_mmd_changed - Function for modifying a register on MMD
146 + * @phydev: the phy_device struct
147 + * @devad: the MMD containing register to modify
148 + * @regnum: register number to modify
149 + * @mask: bit mask of bits to clear
150 + * @set: new value of bits set in mask to write to @regnum
151 + *
152 + * NOTE: MUST NOT be called from interrupt context,
153 + * because the bus read/write functions may wait for an interrupt
154 + * to conclude the operation.
155 + *
156 + * Returns negative errno, 0 if there was no change, and 1 in case of change
157 + */
158 +int phy_modify_mmd_changed(struct phy_device *phydev, int devad, u32 regnum,
159 +                          u16 mask, u16 set)
160 +{
161 +       int ret;
162 +
163 +       mutex_lock(&phydev->mdio.bus->mdio_lock);
164 +       ret = __phy_modify_mmd_changed(phydev, devad, regnum, mask, set);
165 +       mutex_unlock(&phydev->mdio.bus->mdio_lock);
166 +
167 +       return ret;
168 +}
169 +EXPORT_SYMBOL_GPL(phy_modify_mmd_changed);
170 +
171 +/**
172 + * __phy_modify_mmd - Convenience function for modifying a register on MMD
173 + * @phydev: the phy_device struct
174 + * @devad: the MMD containing register to modify
175 + * @regnum: register number to modify
176 + * @mask: bit mask of bits to clear
177 + * @set: new value of bits set in mask to write to @regnum
178 + *
179 + * NOTE: MUST NOT be called from interrupt context,
180 + * because the bus read/write functions may wait for an interrupt
181 + * to conclude the operation.
182 + */
183 +int __phy_modify_mmd(struct phy_device *phydev, int devad, u32 regnum,
184 +                    u16 mask, u16 set)
185 +{
186 +       int ret;
187 +
188 +       ret = __phy_modify_mmd_changed(phydev, devad, regnum, mask, set);
189  
190         return ret < 0 ? ret : 0;
191  }
192 --- a/include/linux/phy.h
193 +++ b/include/linux/phy.h
194 @@ -795,13 +795,21 @@ int phy_write_mmd(struct phy_device *phy
195   */
196  int __phy_write_mmd(struct phy_device *phydev, int devad, u32 regnum, u16 val);
197  
198 +int __phy_modify_changed(struct phy_device *phydev, u32 regnum, u16 mask,
199 +                        u16 set);
200 +int phy_modify_changed(struct phy_device *phydev, u32 regnum, u16 mask,
201 +                      u16 set);
202  int __phy_modify(struct phy_device *phydev, u32 regnum, u16 mask, u16 set);
203  int phy_modify(struct phy_device *phydev, u32 regnum, u16 mask, u16 set);
204  
205 +int __phy_modify_mmd_changed(struct phy_device *phydev, int devad, u32 regnum,
206 +                            u16 mask, u16 set);
207 +int phy_modify_mmd_changed(struct phy_device *phydev, int devad, u32 regnum,
208 +                          u16 mask, u16 set);
209  int __phy_modify_mmd(struct phy_device *phydev, int devad, u32 regnum,
210 -               u16 mask, u16 set);
211 +                    u16 mask, u16 set);
212  int phy_modify_mmd(struct phy_device *phydev, int devad, u32 regnum,
213 -               u16 mask, u16 set);
214 +                  u16 mask, u16 set);
215  
216  /**
217   * __phy_set_bits - Convenience function for setting bits in a PHY register