1 // SPDX-License-Identifier: GPL-2.0-only
3 // Framework for Ethernet Power Sourcing Equipment
8 #include <linux/device.h>
10 #include <linux/pse-pd/pse.h>
12 static DEFINE_MUTEX(pse_list_mutex);
13 static LIST_HEAD(pse_controller_list);
16 * struct pse_control - a PSE control
17 * @pcdev: a pointer to the PSE controller device
18 * this PSE control belongs to
19 * @list: list entry for the pcdev's PSE controller list
20 * @id: ID of the PSE line in the PSE controller device
21 * @refcnt: Number of gets of this pse_control
24 struct pse_controller_dev *pcdev;
25 struct list_head list;
31 * of_pse_zero_xlate - dummy function for controllers with one only control
32 * @pcdev: a pointer to the PSE controller device
33 * @pse_spec: PSE line specifier as found in the device tree
35 * This static translation function is used by default if of_xlate in
36 * :c:type:`pse_controller_dev` is not set. It is useful for all PSE
37 * controllers with #pse-cells = <0>.
39 static int of_pse_zero_xlate(struct pse_controller_dev *pcdev,
40 const struct of_phandle_args *pse_spec)
46 * of_pse_simple_xlate - translate pse_spec to the PSE line number
47 * @pcdev: a pointer to the PSE controller device
48 * @pse_spec: PSE line specifier as found in the device tree
50 * This static translation function is used by default if of_xlate in
51 * :c:type:`pse_controller_dev` is not set. It is useful for all PSE
52 * controllers with 1:1 mapping, where PSE lines can be indexed by number
55 static int of_pse_simple_xlate(struct pse_controller_dev *pcdev,
56 const struct of_phandle_args *pse_spec)
58 if (pse_spec->args[0] >= pcdev->nr_lines)
61 return pse_spec->args[0];
65 * pse_controller_register - register a PSE controller device
66 * @pcdev: a pointer to the initialized PSE controller device
68 int pse_controller_register(struct pse_controller_dev *pcdev)
70 if (!pcdev->of_xlate) {
71 if (pcdev->of_pse_n_cells == 0)
72 pcdev->of_xlate = of_pse_zero_xlate;
73 else if (pcdev->of_pse_n_cells == 1)
74 pcdev->of_xlate = of_pse_simple_xlate;
77 mutex_init(&pcdev->lock);
78 INIT_LIST_HEAD(&pcdev->pse_control_head);
80 mutex_lock(&pse_list_mutex);
81 list_add(&pcdev->list, &pse_controller_list);
82 mutex_unlock(&pse_list_mutex);
86 EXPORT_SYMBOL_GPL(pse_controller_register);
89 * pse_controller_unregister - unregister a PSE controller device
90 * @pcdev: a pointer to the PSE controller device
92 void pse_controller_unregister(struct pse_controller_dev *pcdev)
94 mutex_lock(&pse_list_mutex);
95 list_del(&pcdev->list);
96 mutex_unlock(&pse_list_mutex);
98 EXPORT_SYMBOL_GPL(pse_controller_unregister);
100 static void devm_pse_controller_release(struct device *dev, void *res)
102 pse_controller_unregister(*(struct pse_controller_dev **)res);
106 * devm_pse_controller_register - resource managed pse_controller_register()
107 * @dev: device that is registering this PSE controller
108 * @pcdev: a pointer to the initialized PSE controller device
110 * Managed pse_controller_register(). For PSE controllers registered by
111 * this function, pse_controller_unregister() is automatically called on
112 * driver detach. See pse_controller_register() for more information.
114 int devm_pse_controller_register(struct device *dev,
115 struct pse_controller_dev *pcdev)
117 struct pse_controller_dev **pcdevp;
120 pcdevp = devres_alloc(devm_pse_controller_release, sizeof(*pcdevp),
125 ret = pse_controller_register(pcdev);
132 devres_add(dev, pcdevp);
136 EXPORT_SYMBOL_GPL(devm_pse_controller_register);
138 /* PSE control section */
140 static void __pse_control_release(struct kref *kref)
142 struct pse_control *psec = container_of(kref, struct pse_control,
145 lockdep_assert_held(&pse_list_mutex);
147 module_put(psec->pcdev->owner);
149 list_del(&psec->list);
153 static void __pse_control_put_internal(struct pse_control *psec)
155 lockdep_assert_held(&pse_list_mutex);
157 kref_put(&psec->refcnt, __pse_control_release);
161 * pse_control_put - free the PSE control
162 * @psec: PSE control pointer
164 void pse_control_put(struct pse_control *psec)
166 if (IS_ERR_OR_NULL(psec))
169 mutex_lock(&pse_list_mutex);
170 __pse_control_put_internal(psec);
171 mutex_unlock(&pse_list_mutex);
173 EXPORT_SYMBOL_GPL(pse_control_put);
175 static struct pse_control *
176 pse_control_get_internal(struct pse_controller_dev *pcdev, unsigned int index)
178 struct pse_control *psec;
180 lockdep_assert_held(&pse_list_mutex);
182 list_for_each_entry(psec, &pcdev->pse_control_head, list) {
183 if (psec->id == index) {
184 kref_get(&psec->refcnt);
189 psec = kzalloc(sizeof(*psec), GFP_KERNEL);
191 return ERR_PTR(-ENOMEM);
193 if (!try_module_get(pcdev->owner)) {
195 return ERR_PTR(-ENODEV);
199 list_add(&psec->list, &pcdev->pse_control_head);
201 kref_init(&psec->refcnt);
207 of_pse_control_get(struct device_node *node)
209 struct pse_controller_dev *r, *pcdev;
210 struct of_phandle_args args;
211 struct pse_control *psec;
216 return ERR_PTR(-EINVAL);
218 ret = of_parse_phandle_with_args(node, "pses", "#pse-cells", 0, &args);
222 mutex_lock(&pse_list_mutex);
224 list_for_each_entry(r, &pse_controller_list, list) {
225 if (args.np == r->dev->of_node) {
232 psec = ERR_PTR(-EPROBE_DEFER);
236 if (WARN_ON(args.args_count != pcdev->of_pse_n_cells)) {
237 psec = ERR_PTR(-EINVAL);
241 psec_id = pcdev->of_xlate(pcdev, &args);
243 psec = ERR_PTR(psec_id);
247 /* pse_list_mutex also protects the pcdev's pse_control list */
248 psec = pse_control_get_internal(pcdev, psec_id);
251 mutex_unlock(&pse_list_mutex);
252 of_node_put(args.np);
256 EXPORT_SYMBOL_GPL(of_pse_control_get);
259 * pse_ethtool_get_status - get status of PSE control
260 * @psec: PSE control pointer
261 * @extack: extack for reporting useful error messages
262 * @status: struct to store PSE status
264 int pse_ethtool_get_status(struct pse_control *psec,
265 struct netlink_ext_ack *extack,
266 struct pse_control_status *status)
268 const struct pse_controller_ops *ops;
271 ops = psec->pcdev->ops;
273 if (!ops->ethtool_get_status) {
274 NL_SET_ERR_MSG(extack,
275 "PSE driver does not support status report");
279 mutex_lock(&psec->pcdev->lock);
280 err = ops->ethtool_get_status(psec->pcdev, psec->id, extack, status);
281 mutex_unlock(&psec->pcdev->lock);
285 EXPORT_SYMBOL_GPL(pse_ethtool_get_status);
288 * pse_ethtool_set_config - set PSE control configuration
289 * @psec: PSE control pointer
290 * @extack: extack for reporting useful error messages
291 * @config: Configuration of the test to run
293 int pse_ethtool_set_config(struct pse_control *psec,
294 struct netlink_ext_ack *extack,
295 const struct pse_control_config *config)
297 const struct pse_controller_ops *ops;
300 ops = psec->pcdev->ops;
302 if (!ops->ethtool_set_config) {
303 NL_SET_ERR_MSG(extack,
304 "PSE driver does not configuration");
308 mutex_lock(&psec->pcdev->lock);
309 err = ops->ethtool_set_config(psec->pcdev, psec->id, extack, config);
310 mutex_unlock(&psec->pcdev->lock);
314 EXPORT_SYMBOL_GPL(pse_ethtool_set_config);