]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/tty/serdev/core.c
ufs_truncate_blocks(): fix the case when size is in the last direct block
[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
254 static struct device_attribute serdev_device_attrs[] = {
255         __ATTR_RO(modalias),
256         __ATTR_NULL
257 };
258
259 static struct bus_type serdev_bus_type = {
260         .name           = "serial",
261         .match          = serdev_device_match,
262         .probe          = serdev_drv_probe,
263         .remove         = serdev_drv_remove,
264         .uevent         = serdev_uevent,
265         .dev_attrs      = serdev_device_attrs,
266 };
267
268 /**
269  * serdev_controller_alloc() - Allocate a new serdev device
270  * @ctrl:       associated controller
271  *
272  * Caller is responsible for either calling serdev_device_add() to add the
273  * newly allocated controller, or calling serdev_device_put() to discard it.
274  */
275 struct serdev_device *serdev_device_alloc(struct serdev_controller *ctrl)
276 {
277         struct serdev_device *serdev;
278
279         serdev = kzalloc(sizeof(*serdev), GFP_KERNEL);
280         if (!serdev)
281                 return NULL;
282
283         serdev->ctrl = ctrl;
284         ctrl->serdev = serdev;
285         device_initialize(&serdev->dev);
286         serdev->dev.parent = &ctrl->dev;
287         serdev->dev.bus = &serdev_bus_type;
288         serdev->dev.type = &serdev_device_type;
289         init_completion(&serdev->write_comp);
290         mutex_init(&serdev->write_lock);
291         return serdev;
292 }
293 EXPORT_SYMBOL_GPL(serdev_device_alloc);
294
295 /**
296  * serdev_controller_alloc() - Allocate a new serdev controller
297  * @parent:     parent device
298  * @size:       size of private data
299  *
300  * Caller is responsible for either calling serdev_controller_add() to add the
301  * newly allocated controller, or calling serdev_controller_put() to discard it.
302  * The allocated private data region may be accessed via
303  * serdev_controller_get_drvdata()
304  */
305 struct serdev_controller *serdev_controller_alloc(struct device *parent,
306                                               size_t size)
307 {
308         struct serdev_controller *ctrl;
309         int id;
310
311         if (WARN_ON(!parent))
312                 return NULL;
313
314         ctrl = kzalloc(sizeof(*ctrl) + size, GFP_KERNEL);
315         if (!ctrl)
316                 return NULL;
317
318         device_initialize(&ctrl->dev);
319         ctrl->dev.type = &serdev_ctrl_type;
320         ctrl->dev.bus = &serdev_bus_type;
321         ctrl->dev.parent = parent;
322         ctrl->dev.of_node = parent->of_node;
323         serdev_controller_set_drvdata(ctrl, &ctrl[1]);
324
325         id = ida_simple_get(&ctrl_ida, 0, 0, GFP_KERNEL);
326         if (id < 0) {
327                 dev_err(parent,
328                         "unable to allocate serdev controller identifier.\n");
329                 serdev_controller_put(ctrl);
330                 return NULL;
331         }
332
333         ctrl->nr = id;
334         dev_set_name(&ctrl->dev, "serial%d", id);
335
336         dev_dbg(&ctrl->dev, "allocated controller 0x%p id %d\n", ctrl, id);
337         return ctrl;
338 }
339 EXPORT_SYMBOL_GPL(serdev_controller_alloc);
340
341 static int of_serdev_register_devices(struct serdev_controller *ctrl)
342 {
343         struct device_node *node;
344         struct serdev_device *serdev = NULL;
345         int err;
346         bool found = false;
347
348         for_each_available_child_of_node(ctrl->dev.of_node, node) {
349                 if (!of_get_property(node, "compatible", NULL))
350                         continue;
351
352                 dev_dbg(&ctrl->dev, "adding child %s\n", node->full_name);
353
354                 serdev = serdev_device_alloc(ctrl);
355                 if (!serdev)
356                         continue;
357
358                 serdev->dev.of_node = node;
359
360                 err = serdev_device_add(serdev);
361                 if (err) {
362                         dev_err(&serdev->dev,
363                                 "failure adding device. status %d\n", err);
364                         serdev_device_put(serdev);
365                 } else
366                         found = true;
367         }
368         if (!found)
369                 return -ENODEV;
370
371         return 0;
372 }
373
374 /**
375  * serdev_controller_add() - Add an serdev controller
376  * @ctrl:       controller to be registered.
377  *
378  * Register a controller previously allocated via serdev_controller_alloc() with
379  * the serdev core.
380  */
381 int serdev_controller_add(struct serdev_controller *ctrl)
382 {
383         int ret;
384
385         /* Can't register until after driver model init */
386         if (WARN_ON(!is_registered))
387                 return -EAGAIN;
388
389         ret = device_add(&ctrl->dev);
390         if (ret)
391                 return ret;
392
393         ret = of_serdev_register_devices(ctrl);
394         if (ret)
395                 goto out_dev_del;
396
397         dev_dbg(&ctrl->dev, "serdev%d registered: dev:%p\n",
398                 ctrl->nr, &ctrl->dev);
399         return 0;
400
401 out_dev_del:
402         device_del(&ctrl->dev);
403         return ret;
404 };
405 EXPORT_SYMBOL_GPL(serdev_controller_add);
406
407 /* Remove a device associated with a controller */
408 static int serdev_remove_device(struct device *dev, void *data)
409 {
410         struct serdev_device *serdev = to_serdev_device(dev);
411         if (dev->type == &serdev_device_type)
412                 serdev_device_remove(serdev);
413         return 0;
414 }
415
416 /**
417  * serdev_controller_remove(): remove an serdev controller
418  * @ctrl:       controller to remove
419  *
420  * Remove a serdev controller.  Caller is responsible for calling
421  * serdev_controller_put() to discard the allocated controller.
422  */
423 void serdev_controller_remove(struct serdev_controller *ctrl)
424 {
425         int dummy;
426
427         if (!ctrl)
428                 return;
429
430         dummy = device_for_each_child(&ctrl->dev, NULL,
431                                       serdev_remove_device);
432         device_del(&ctrl->dev);
433 }
434 EXPORT_SYMBOL_GPL(serdev_controller_remove);
435
436 /**
437  * serdev_driver_register() - Register client driver with serdev core
438  * @sdrv:       client driver to be associated with client-device.
439  *
440  * This API will register the client driver with the serdev framework.
441  * It is typically called from the driver's module-init function.
442  */
443 int __serdev_device_driver_register(struct serdev_device_driver *sdrv, struct module *owner)
444 {
445         sdrv->driver.bus = &serdev_bus_type;
446         sdrv->driver.owner = owner;
447
448         /* force drivers to async probe so I/O is possible in probe */
449         sdrv->driver.probe_type = PROBE_PREFER_ASYNCHRONOUS;
450
451         return driver_register(&sdrv->driver);
452 }
453 EXPORT_SYMBOL_GPL(__serdev_device_driver_register);
454
455 static void __exit serdev_exit(void)
456 {
457         bus_unregister(&serdev_bus_type);
458 }
459 module_exit(serdev_exit);
460
461 static int __init serdev_init(void)
462 {
463         int ret;
464
465         ret = bus_register(&serdev_bus_type);
466         if (ret)
467                 return ret;
468
469         is_registered = true;
470         return 0;
471 }
472 /* Must be before serial drivers register */
473 postcore_initcall(serdev_init);
474
475 MODULE_AUTHOR("Rob Herring <robh@kernel.org>");
476 MODULE_LICENSE("GPL v2");
477 MODULE_DESCRIPTION("Serial attached device bus");