]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/tty/serdev/core.c
tty: serdev: use dev_groups and not dev_attrs for bus_type
[karo-tx-linux.git] / drivers / tty / serdev / core.c
1 /*
2  * Copyright (C) 2016-2017 Linaro Ltd., Rob Herring <robh@kernel.org>
3  *
4  * Based on drivers/spmi/spmi.c:
5  * Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License version 2 and
9  * only version 2 as published by the Free Software Foundation.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  */
16
17 #include <linux/errno.h>
18 #include <linux/idr.h>
19 #include <linux/kernel.h>
20 #include <linux/module.h>
21 #include <linux/of.h>
22 #include <linux/of_device.h>
23 #include <linux/serdev.h>
24 #include <linux/slab.h>
25
26 static bool is_registered;
27 static DEFINE_IDA(ctrl_ida);
28
29 static void serdev_device_release(struct device *dev)
30 {
31         struct serdev_device *serdev = to_serdev_device(dev);
32         kfree(serdev);
33 }
34
35 static const struct device_type serdev_device_type = {
36         .release        = serdev_device_release,
37 };
38
39 static void serdev_ctrl_release(struct device *dev)
40 {
41         struct serdev_controller *ctrl = to_serdev_controller(dev);
42         ida_simple_remove(&ctrl_ida, ctrl->nr);
43         kfree(ctrl);
44 }
45
46 static const struct device_type serdev_ctrl_type = {
47         .release        = serdev_ctrl_release,
48 };
49
50 static int serdev_device_match(struct device *dev, struct device_driver *drv)
51 {
52         /* TODO: ACPI and platform matching */
53         return of_driver_match_device(dev, drv);
54 }
55
56 static int serdev_uevent(struct device *dev, struct kobj_uevent_env *env)
57 {
58         /* TODO: ACPI and platform modalias */
59         return of_device_uevent_modalias(dev, env);
60 }
61
62 /**
63  * serdev_device_add() - add a device previously constructed via serdev_device_alloc()
64  * @serdev:     serdev_device to be added
65  */
66 int serdev_device_add(struct serdev_device *serdev)
67 {
68         struct device *parent = serdev->dev.parent;
69         int err;
70
71         dev_set_name(&serdev->dev, "%s-%d", dev_name(parent), serdev->nr);
72
73         err = device_add(&serdev->dev);
74         if (err < 0) {
75                 dev_err(&serdev->dev, "Can't add %s, status %d\n",
76                         dev_name(&serdev->dev), err);
77                 goto err_device_add;
78         }
79
80         dev_dbg(&serdev->dev, "device %s registered\n", dev_name(&serdev->dev));
81
82 err_device_add:
83         return err;
84 }
85 EXPORT_SYMBOL_GPL(serdev_device_add);
86
87 /**
88  * serdev_device_remove(): remove an serdev device
89  * @serdev:     serdev_device to be removed
90  */
91 void serdev_device_remove(struct serdev_device *serdev)
92 {
93         device_unregister(&serdev->dev);
94 }
95 EXPORT_SYMBOL_GPL(serdev_device_remove);
96
97 int serdev_device_open(struct serdev_device *serdev)
98 {
99         struct serdev_controller *ctrl = serdev->ctrl;
100
101         if (!ctrl || !ctrl->ops->open)
102                 return -EINVAL;
103
104         return ctrl->ops->open(ctrl);
105 }
106 EXPORT_SYMBOL_GPL(serdev_device_open);
107
108 void serdev_device_close(struct serdev_device *serdev)
109 {
110         struct serdev_controller *ctrl = serdev->ctrl;
111
112         if (!ctrl || !ctrl->ops->close)
113                 return;
114
115         ctrl->ops->close(ctrl);
116 }
117 EXPORT_SYMBOL_GPL(serdev_device_close);
118
119 void serdev_device_write_wakeup(struct serdev_device *serdev)
120 {
121         complete(&serdev->write_comp);
122 }
123 EXPORT_SYMBOL_GPL(serdev_device_write_wakeup);
124
125 int serdev_device_write(struct serdev_device *serdev,
126                         const unsigned char *buf, size_t count,
127                         unsigned long timeout)
128 {
129         struct serdev_controller *ctrl = serdev->ctrl;
130         int ret;
131
132         if (!ctrl || !ctrl->ops->write_buf ||
133             (timeout && !serdev->ops->write_wakeup))
134                 return -EINVAL;
135
136         mutex_lock(&serdev->write_lock);
137         do {
138                 reinit_completion(&serdev->write_comp);
139
140                 ret = ctrl->ops->write_buf(ctrl, buf, count);
141                 if (ret < 0)
142                         break;
143
144                 buf += ret;
145                 count -= ret;
146
147         } while (count &&
148                  (timeout = wait_for_completion_timeout(&serdev->write_comp,
149                                                         timeout)));
150         mutex_unlock(&serdev->write_lock);
151         return ret < 0 ? ret : (count ? -ETIMEDOUT : 0);
152 }
153 EXPORT_SYMBOL_GPL(serdev_device_write);
154
155 void serdev_device_write_flush(struct serdev_device *serdev)
156 {
157         struct serdev_controller *ctrl = serdev->ctrl;
158
159         if (!ctrl || !ctrl->ops->write_flush)
160                 return;
161
162         ctrl->ops->write_flush(ctrl);
163 }
164 EXPORT_SYMBOL_GPL(serdev_device_write_flush);
165
166 int serdev_device_write_room(struct serdev_device *serdev)
167 {
168         struct serdev_controller *ctrl = serdev->ctrl;
169
170         if (!ctrl || !ctrl->ops->write_room)
171                 return 0;
172
173         return serdev->ctrl->ops->write_room(ctrl);
174 }
175 EXPORT_SYMBOL_GPL(serdev_device_write_room);
176
177 unsigned int serdev_device_set_baudrate(struct serdev_device *serdev, unsigned int speed)
178 {
179         struct serdev_controller *ctrl = serdev->ctrl;
180
181         if (!ctrl || !ctrl->ops->set_baudrate)
182                 return 0;
183
184         return ctrl->ops->set_baudrate(ctrl, speed);
185
186 }
187 EXPORT_SYMBOL_GPL(serdev_device_set_baudrate);
188
189 void serdev_device_set_flow_control(struct serdev_device *serdev, bool enable)
190 {
191         struct serdev_controller *ctrl = serdev->ctrl;
192
193         if (!ctrl || !ctrl->ops->set_flow_control)
194                 return;
195
196         ctrl->ops->set_flow_control(ctrl, enable);
197 }
198 EXPORT_SYMBOL_GPL(serdev_device_set_flow_control);
199
200 void serdev_device_wait_until_sent(struct serdev_device *serdev, long timeout)
201 {
202         struct serdev_controller *ctrl = serdev->ctrl;
203
204         if (!ctrl || !ctrl->ops->wait_until_sent)
205                 return;
206
207         ctrl->ops->wait_until_sent(ctrl, timeout);
208 }
209 EXPORT_SYMBOL_GPL(serdev_device_wait_until_sent);
210
211 int serdev_device_get_tiocm(struct serdev_device *serdev)
212 {
213         struct serdev_controller *ctrl = serdev->ctrl;
214
215         if (!ctrl || !ctrl->ops->get_tiocm)
216                 return -ENOTSUPP;
217
218         return ctrl->ops->get_tiocm(ctrl);
219 }
220 EXPORT_SYMBOL_GPL(serdev_device_get_tiocm);
221
222 int serdev_device_set_tiocm(struct serdev_device *serdev, int set, int clear)
223 {
224         struct serdev_controller *ctrl = serdev->ctrl;
225
226         if (!ctrl || !ctrl->ops->set_tiocm)
227                 return -ENOTSUPP;
228
229         return ctrl->ops->set_tiocm(ctrl, set, clear);
230 }
231 EXPORT_SYMBOL_GPL(serdev_device_set_tiocm);
232
233 static int serdev_drv_probe(struct device *dev)
234 {
235         const struct serdev_device_driver *sdrv = to_serdev_device_driver(dev->driver);
236
237         return sdrv->probe(to_serdev_device(dev));
238 }
239
240 static int serdev_drv_remove(struct device *dev)
241 {
242         const struct serdev_device_driver *sdrv = to_serdev_device_driver(dev->driver);
243
244         sdrv->remove(to_serdev_device(dev));
245         return 0;
246 }
247
248 static ssize_t modalias_show(struct device *dev,
249                              struct device_attribute *attr, char *buf)
250 {
251         return of_device_modalias(dev, buf, PAGE_SIZE);
252 }
253 DEVICE_ATTR_RO(modalias);
254
255 static struct attribute *serdev_device_attrs[] = {
256         &dev_attr_modalias.attr,
257         NULL,
258 };
259 ATTRIBUTE_GROUPS(serdev_device);
260
261 static struct bus_type serdev_bus_type = {
262         .name           = "serial",
263         .match          = serdev_device_match,
264         .probe          = serdev_drv_probe,
265         .remove         = serdev_drv_remove,
266         .uevent         = serdev_uevent,
267         .dev_groups     = serdev_device_groups,
268 };
269
270 /**
271  * serdev_controller_alloc() - Allocate a new serdev device
272  * @ctrl:       associated controller
273  *
274  * Caller is responsible for either calling serdev_device_add() to add the
275  * newly allocated controller, or calling serdev_device_put() to discard it.
276  */
277 struct serdev_device *serdev_device_alloc(struct serdev_controller *ctrl)
278 {
279         struct serdev_device *serdev;
280
281         serdev = kzalloc(sizeof(*serdev), GFP_KERNEL);
282         if (!serdev)
283                 return NULL;
284
285         serdev->ctrl = ctrl;
286         ctrl->serdev = serdev;
287         device_initialize(&serdev->dev);
288         serdev->dev.parent = &ctrl->dev;
289         serdev->dev.bus = &serdev_bus_type;
290         serdev->dev.type = &serdev_device_type;
291         init_completion(&serdev->write_comp);
292         mutex_init(&serdev->write_lock);
293         return serdev;
294 }
295 EXPORT_SYMBOL_GPL(serdev_device_alloc);
296
297 /**
298  * serdev_controller_alloc() - Allocate a new serdev controller
299  * @parent:     parent device
300  * @size:       size of private data
301  *
302  * Caller is responsible for either calling serdev_controller_add() to add the
303  * newly allocated controller, or calling serdev_controller_put() to discard it.
304  * The allocated private data region may be accessed via
305  * serdev_controller_get_drvdata()
306  */
307 struct serdev_controller *serdev_controller_alloc(struct device *parent,
308                                               size_t size)
309 {
310         struct serdev_controller *ctrl;
311         int id;
312
313         if (WARN_ON(!parent))
314                 return NULL;
315
316         ctrl = kzalloc(sizeof(*ctrl) + size, GFP_KERNEL);
317         if (!ctrl)
318                 return NULL;
319
320         device_initialize(&ctrl->dev);
321         ctrl->dev.type = &serdev_ctrl_type;
322         ctrl->dev.bus = &serdev_bus_type;
323         ctrl->dev.parent = parent;
324         ctrl->dev.of_node = parent->of_node;
325         serdev_controller_set_drvdata(ctrl, &ctrl[1]);
326
327         id = ida_simple_get(&ctrl_ida, 0, 0, GFP_KERNEL);
328         if (id < 0) {
329                 dev_err(parent,
330                         "unable to allocate serdev controller identifier.\n");
331                 serdev_controller_put(ctrl);
332                 return NULL;
333         }
334
335         ctrl->nr = id;
336         dev_set_name(&ctrl->dev, "serial%d", id);
337
338         dev_dbg(&ctrl->dev, "allocated controller 0x%p id %d\n", ctrl, id);
339         return ctrl;
340 }
341 EXPORT_SYMBOL_GPL(serdev_controller_alloc);
342
343 static int of_serdev_register_devices(struct serdev_controller *ctrl)
344 {
345         struct device_node *node;
346         struct serdev_device *serdev = NULL;
347         int err;
348         bool found = false;
349
350         for_each_available_child_of_node(ctrl->dev.of_node, node) {
351                 if (!of_get_property(node, "compatible", NULL))
352                         continue;
353
354                 dev_dbg(&ctrl->dev, "adding child %s\n", node->full_name);
355
356                 serdev = serdev_device_alloc(ctrl);
357                 if (!serdev)
358                         continue;
359
360                 serdev->dev.of_node = node;
361
362                 err = serdev_device_add(serdev);
363                 if (err) {
364                         dev_err(&serdev->dev,
365                                 "failure adding device. status %d\n", err);
366                         serdev_device_put(serdev);
367                 } else
368                         found = true;
369         }
370         if (!found)
371                 return -ENODEV;
372
373         return 0;
374 }
375
376 /**
377  * serdev_controller_add() - Add an serdev controller
378  * @ctrl:       controller to be registered.
379  *
380  * Register a controller previously allocated via serdev_controller_alloc() with
381  * the serdev core.
382  */
383 int serdev_controller_add(struct serdev_controller *ctrl)
384 {
385         int ret;
386
387         /* Can't register until after driver model init */
388         if (WARN_ON(!is_registered))
389                 return -EAGAIN;
390
391         ret = device_add(&ctrl->dev);
392         if (ret)
393                 return ret;
394
395         ret = of_serdev_register_devices(ctrl);
396         if (ret)
397                 goto out_dev_del;
398
399         dev_dbg(&ctrl->dev, "serdev%d registered: dev:%p\n",
400                 ctrl->nr, &ctrl->dev);
401         return 0;
402
403 out_dev_del:
404         device_del(&ctrl->dev);
405         return ret;
406 };
407 EXPORT_SYMBOL_GPL(serdev_controller_add);
408
409 /* Remove a device associated with a controller */
410 static int serdev_remove_device(struct device *dev, void *data)
411 {
412         struct serdev_device *serdev = to_serdev_device(dev);
413         if (dev->type == &serdev_device_type)
414                 serdev_device_remove(serdev);
415         return 0;
416 }
417
418 /**
419  * serdev_controller_remove(): remove an serdev controller
420  * @ctrl:       controller to remove
421  *
422  * Remove a serdev controller.  Caller is responsible for calling
423  * serdev_controller_put() to discard the allocated controller.
424  */
425 void serdev_controller_remove(struct serdev_controller *ctrl)
426 {
427         int dummy;
428
429         if (!ctrl)
430                 return;
431
432         dummy = device_for_each_child(&ctrl->dev, NULL,
433                                       serdev_remove_device);
434         device_del(&ctrl->dev);
435 }
436 EXPORT_SYMBOL_GPL(serdev_controller_remove);
437
438 /**
439  * serdev_driver_register() - Register client driver with serdev core
440  * @sdrv:       client driver to be associated with client-device.
441  *
442  * This API will register the client driver with the serdev framework.
443  * It is typically called from the driver's module-init function.
444  */
445 int __serdev_device_driver_register(struct serdev_device_driver *sdrv, struct module *owner)
446 {
447         sdrv->driver.bus = &serdev_bus_type;
448         sdrv->driver.owner = owner;
449
450         /* force drivers to async probe so I/O is possible in probe */
451         sdrv->driver.probe_type = PROBE_PREFER_ASYNCHRONOUS;
452
453         return driver_register(&sdrv->driver);
454 }
455 EXPORT_SYMBOL_GPL(__serdev_device_driver_register);
456
457 static void __exit serdev_exit(void)
458 {
459         bus_unregister(&serdev_bus_type);
460 }
461 module_exit(serdev_exit);
462
463 static int __init serdev_init(void)
464 {
465         int ret;
466
467         ret = bus_register(&serdev_bus_type);
468         if (ret)
469                 return ret;
470
471         is_registered = true;
472         return 0;
473 }
474 /* Must be before serial drivers register */
475 postcore_initcall(serdev_init);
476
477 MODULE_AUTHOR("Rob Herring <robh@kernel.org>");
478 MODULE_LICENSE("GPL v2");
479 MODULE_DESCRIPTION("Serial attached device bus");