Merge tag 'mfd-fixes-3.14-1' of git://git.linaro.org/people/lee.jones/mfd
[platform/adaptation/renesas_rcar/renesas_kernel.git] / drivers / s390 / cio / ccwgroup.c
1 /*
2  *  bus driver for ccwgroup
3  *
4  *  Copyright IBM Corp. 2002, 2012
5  *
6  *  Author(s): Arnd Bergmann (arndb@de.ibm.com)
7  *             Cornelia Huck (cornelia.huck@de.ibm.com)
8  */
9 #include <linux/module.h>
10 #include <linux/errno.h>
11 #include <linux/slab.h>
12 #include <linux/list.h>
13 #include <linux/device.h>
14 #include <linux/init.h>
15 #include <linux/ctype.h>
16 #include <linux/dcache.h>
17
18 #include <asm/cio.h>
19 #include <asm/ccwdev.h>
20 #include <asm/ccwgroup.h>
21
22 #include "device.h"
23
24 #define CCW_BUS_ID_SIZE         10
25
26 /* In Linux 2.4, we had a channel device layer called "chandev"
27  * that did all sorts of obscure stuff for networking devices.
28  * This is another driver that serves as a replacement for just
29  * one of its functions, namely the translation of single subchannels
30  * to devices that use multiple subchannels.
31  */
32
33 static struct bus_type ccwgroup_bus_type;
34
35 static void __ccwgroup_remove_symlinks(struct ccwgroup_device *gdev)
36 {
37         int i;
38         char str[8];
39
40         for (i = 0; i < gdev->count; i++) {
41                 sprintf(str, "cdev%d", i);
42                 sysfs_remove_link(&gdev->dev.kobj, str);
43                 sysfs_remove_link(&gdev->cdev[i]->dev.kobj, "group_device");
44         }
45 }
46
47 /*
48  * Remove references from ccw devices to ccw group device and from
49  * ccw group device to ccw devices.
50  */
51 static void __ccwgroup_remove_cdev_refs(struct ccwgroup_device *gdev)
52 {
53         struct ccw_device *cdev;
54         int i;
55
56         for (i = 0; i < gdev->count; i++) {
57                 cdev = gdev->cdev[i];
58                 if (!cdev)
59                         continue;
60                 spin_lock_irq(cdev->ccwlock);
61                 dev_set_drvdata(&cdev->dev, NULL);
62                 spin_unlock_irq(cdev->ccwlock);
63                 gdev->cdev[i] = NULL;
64                 put_device(&cdev->dev);
65         }
66 }
67
68 /**
69  * ccwgroup_set_online() - enable a ccwgroup device
70  * @gdev: target ccwgroup device
71  *
72  * This function attempts to put the ccwgroup device into the online state.
73  * Returns:
74  *  %0 on success and a negative error value on failure.
75  */
76 int ccwgroup_set_online(struct ccwgroup_device *gdev)
77 {
78         struct ccwgroup_driver *gdrv = to_ccwgroupdrv(gdev->dev.driver);
79         int ret = -EINVAL;
80
81         if (atomic_cmpxchg(&gdev->onoff, 0, 1) != 0)
82                 return -EAGAIN;
83         if (gdev->state == CCWGROUP_ONLINE)
84                 goto out;
85         if (gdrv->set_online)
86                 ret = gdrv->set_online(gdev);
87         if (ret)
88                 goto out;
89
90         gdev->state = CCWGROUP_ONLINE;
91 out:
92         atomic_set(&gdev->onoff, 0);
93         return ret;
94 }
95 EXPORT_SYMBOL(ccwgroup_set_online);
96
97 /**
98  * ccwgroup_set_offline() - disable a ccwgroup device
99  * @gdev: target ccwgroup device
100  *
101  * This function attempts to put the ccwgroup device into the offline state.
102  * Returns:
103  *  %0 on success and a negative error value on failure.
104  */
105 int ccwgroup_set_offline(struct ccwgroup_device *gdev)
106 {
107         struct ccwgroup_driver *gdrv = to_ccwgroupdrv(gdev->dev.driver);
108         int ret = -EINVAL;
109
110         if (atomic_cmpxchg(&gdev->onoff, 0, 1) != 0)
111                 return -EAGAIN;
112         if (gdev->state == CCWGROUP_OFFLINE)
113                 goto out;
114         if (gdrv->set_offline)
115                 ret = gdrv->set_offline(gdev);
116         if (ret)
117                 goto out;
118
119         gdev->state = CCWGROUP_OFFLINE;
120 out:
121         atomic_set(&gdev->onoff, 0);
122         return ret;
123 }
124 EXPORT_SYMBOL(ccwgroup_set_offline);
125
126 static ssize_t ccwgroup_online_store(struct device *dev,
127                                      struct device_attribute *attr,
128                                      const char *buf, size_t count)
129 {
130         struct ccwgroup_device *gdev = to_ccwgroupdev(dev);
131         unsigned long value;
132         int ret;
133
134         device_lock(dev);
135         if (!dev->driver) {
136                 ret = -EINVAL;
137                 goto out;
138         }
139
140         ret = kstrtoul(buf, 0, &value);
141         if (ret)
142                 goto out;
143
144         if (value == 1)
145                 ret = ccwgroup_set_online(gdev);
146         else if (value == 0)
147                 ret = ccwgroup_set_offline(gdev);
148         else
149                 ret = -EINVAL;
150 out:
151         device_unlock(dev);
152         return (ret == 0) ? count : ret;
153 }
154
155 static ssize_t ccwgroup_online_show(struct device *dev,
156                                     struct device_attribute *attr,
157                                     char *buf)
158 {
159         struct ccwgroup_device *gdev = to_ccwgroupdev(dev);
160         int online;
161
162         online = (gdev->state == CCWGROUP_ONLINE) ? 1 : 0;
163
164         return scnprintf(buf, PAGE_SIZE, "%d\n", online);
165 }
166
167 /*
168  * Provide an 'ungroup' attribute so the user can remove group devices no
169  * longer needed or accidentially created. Saves memory :)
170  */
171 static void ccwgroup_ungroup_callback(struct device *dev)
172 {
173         struct ccwgroup_device *gdev = to_ccwgroupdev(dev);
174
175         mutex_lock(&gdev->reg_mutex);
176         if (device_is_registered(&gdev->dev)) {
177                 __ccwgroup_remove_symlinks(gdev);
178                 device_unregister(dev);
179                 __ccwgroup_remove_cdev_refs(gdev);
180         }
181         mutex_unlock(&gdev->reg_mutex);
182 }
183
184 static ssize_t ccwgroup_ungroup_store(struct device *dev,
185                                       struct device_attribute *attr,
186                                       const char *buf, size_t count)
187 {
188         struct ccwgroup_device *gdev = to_ccwgroupdev(dev);
189         int rc;
190
191         /* Prevent concurrent online/offline processing and ungrouping. */
192         if (atomic_cmpxchg(&gdev->onoff, 0, 1) != 0)
193                 return -EAGAIN;
194         if (gdev->state != CCWGROUP_OFFLINE) {
195                 rc = -EINVAL;
196                 goto out;
197         }
198         /* Note that we cannot unregister the device from one of its
199          * attribute methods, so we have to use this roundabout approach.
200          */
201         rc = device_schedule_callback(dev, ccwgroup_ungroup_callback);
202 out:
203         if (rc) {
204                 if (rc != -EAGAIN)
205                         /* Release onoff "lock" when ungrouping failed. */
206                         atomic_set(&gdev->onoff, 0);
207                 return rc;
208         }
209         return count;
210 }
211 static DEVICE_ATTR(ungroup, 0200, NULL, ccwgroup_ungroup_store);
212 static DEVICE_ATTR(online, 0644, ccwgroup_online_show, ccwgroup_online_store);
213
214 static struct attribute *ccwgroup_attrs[] = {
215         &dev_attr_online.attr,
216         &dev_attr_ungroup.attr,
217         NULL,
218 };
219 static struct attribute_group ccwgroup_attr_group = {
220         .attrs = ccwgroup_attrs,
221 };
222 static const struct attribute_group *ccwgroup_attr_groups[] = {
223         &ccwgroup_attr_group,
224         NULL,
225 };
226
227 static void ccwgroup_release(struct device *dev)
228 {
229         kfree(to_ccwgroupdev(dev));
230 }
231
232 static int __ccwgroup_create_symlinks(struct ccwgroup_device *gdev)
233 {
234         char str[8];
235         int i, rc;
236
237         for (i = 0; i < gdev->count; i++) {
238                 rc = sysfs_create_link(&gdev->cdev[i]->dev.kobj,
239                                        &gdev->dev.kobj, "group_device");
240                 if (rc) {
241                         for (--i; i >= 0; i--)
242                                 sysfs_remove_link(&gdev->cdev[i]->dev.kobj,
243                                                   "group_device");
244                         return rc;
245                 }
246         }
247         for (i = 0; i < gdev->count; i++) {
248                 sprintf(str, "cdev%d", i);
249                 rc = sysfs_create_link(&gdev->dev.kobj,
250                                        &gdev->cdev[i]->dev.kobj, str);
251                 if (rc) {
252                         for (--i; i >= 0; i--) {
253                                 sprintf(str, "cdev%d", i);
254                                 sysfs_remove_link(&gdev->dev.kobj, str);
255                         }
256                         for (i = 0; i < gdev->count; i++)
257                                 sysfs_remove_link(&gdev->cdev[i]->dev.kobj,
258                                                   "group_device");
259                         return rc;
260                 }
261         }
262         return 0;
263 }
264
265 static int __get_next_id(const char **buf, struct ccw_dev_id *id)
266 {
267         unsigned int cssid, ssid, devno;
268         int ret = 0, len;
269         char *start, *end;
270
271         start = (char *)*buf;
272         end = strchr(start, ',');
273         if (!end) {
274                 /* Last entry. Strip trailing newline, if applicable. */
275                 end = strchr(start, '\n');
276                 if (end)
277                         *end = '\0';
278                 len = strlen(start) + 1;
279         } else {
280                 len = end - start + 1;
281                 end++;
282         }
283         if (len <= CCW_BUS_ID_SIZE) {
284                 if (sscanf(start, "%2x.%1x.%04x", &cssid, &ssid, &devno) != 3)
285                         ret = -EINVAL;
286         } else
287                 ret = -EINVAL;
288
289         if (!ret) {
290                 id->ssid = ssid;
291                 id->devno = devno;
292         }
293         *buf = end;
294         return ret;
295 }
296
297 /**
298  * ccwgroup_create_dev() - create and register a ccw group device
299  * @parent: parent device for the new device
300  * @gdrv: driver for the new group device
301  * @num_devices: number of slave devices
302  * @buf: buffer containing comma separated bus ids of slave devices
303  *
304  * Create and register a new ccw group device as a child of @parent. Slave
305  * devices are obtained from the list of bus ids given in @buf.
306  * Returns:
307  *  %0 on success and an error code on failure.
308  * Context:
309  *  non-atomic
310  */
311 int ccwgroup_create_dev(struct device *parent, struct ccwgroup_driver *gdrv,
312                         int num_devices, const char *buf)
313 {
314         struct ccwgroup_device *gdev;
315         struct ccw_dev_id dev_id;
316         int rc, i;
317
318         gdev = kzalloc(sizeof(*gdev) + num_devices * sizeof(gdev->cdev[0]),
319                        GFP_KERNEL);
320         if (!gdev)
321                 return -ENOMEM;
322
323         atomic_set(&gdev->onoff, 0);
324         mutex_init(&gdev->reg_mutex);
325         mutex_lock(&gdev->reg_mutex);
326         gdev->count = num_devices;
327         gdev->dev.bus = &ccwgroup_bus_type;
328         gdev->dev.parent = parent;
329         gdev->dev.release = ccwgroup_release;
330         device_initialize(&gdev->dev);
331
332         for (i = 0; i < num_devices && buf; i++) {
333                 rc = __get_next_id(&buf, &dev_id);
334                 if (rc != 0)
335                         goto error;
336                 gdev->cdev[i] = get_ccwdev_by_dev_id(&dev_id);
337                 /*
338                  * All devices have to be of the same type in
339                  * order to be grouped.
340                  */
341                 if (!gdev->cdev[i] || !gdev->cdev[i]->drv ||
342                     gdev->cdev[i]->drv != gdev->cdev[0]->drv ||
343                     gdev->cdev[i]->id.driver_info !=
344                     gdev->cdev[0]->id.driver_info) {
345                         rc = -EINVAL;
346                         goto error;
347                 }
348                 /* Don't allow a device to belong to more than one group. */
349                 spin_lock_irq(gdev->cdev[i]->ccwlock);
350                 if (dev_get_drvdata(&gdev->cdev[i]->dev)) {
351                         spin_unlock_irq(gdev->cdev[i]->ccwlock);
352                         rc = -EINVAL;
353                         goto error;
354                 }
355                 dev_set_drvdata(&gdev->cdev[i]->dev, gdev);
356                 spin_unlock_irq(gdev->cdev[i]->ccwlock);
357         }
358         /* Check for sufficient number of bus ids. */
359         if (i < num_devices) {
360                 rc = -EINVAL;
361                 goto error;
362         }
363         /* Check for trailing stuff. */
364         if (i == num_devices && strlen(buf) > 0) {
365                 rc = -EINVAL;
366                 goto error;
367         }
368
369         dev_set_name(&gdev->dev, "%s", dev_name(&gdev->cdev[0]->dev));
370         gdev->dev.groups = ccwgroup_attr_groups;
371
372         if (gdrv) {
373                 gdev->dev.driver = &gdrv->driver;
374                 rc = gdrv->setup ? gdrv->setup(gdev) : 0;
375                 if (rc)
376                         goto error;
377         }
378         rc = device_add(&gdev->dev);
379         if (rc)
380                 goto error;
381         rc = __ccwgroup_create_symlinks(gdev);
382         if (rc) {
383                 device_del(&gdev->dev);
384                 goto error;
385         }
386         mutex_unlock(&gdev->reg_mutex);
387         return 0;
388 error:
389         for (i = 0; i < num_devices; i++)
390                 if (gdev->cdev[i]) {
391                         spin_lock_irq(gdev->cdev[i]->ccwlock);
392                         if (dev_get_drvdata(&gdev->cdev[i]->dev) == gdev)
393                                 dev_set_drvdata(&gdev->cdev[i]->dev, NULL);
394                         spin_unlock_irq(gdev->cdev[i]->ccwlock);
395                         put_device(&gdev->cdev[i]->dev);
396                         gdev->cdev[i] = NULL;
397                 }
398         mutex_unlock(&gdev->reg_mutex);
399         put_device(&gdev->dev);
400         return rc;
401 }
402 EXPORT_SYMBOL(ccwgroup_create_dev);
403
404 static int ccwgroup_notifier(struct notifier_block *nb, unsigned long action,
405                              void *data)
406 {
407         struct device *dev = data;
408
409         if (action == BUS_NOTIFY_UNBIND_DRIVER)
410                 device_schedule_callback(dev, ccwgroup_ungroup_callback);
411
412         return NOTIFY_OK;
413 }
414
415 static struct notifier_block ccwgroup_nb = {
416         .notifier_call = ccwgroup_notifier
417 };
418
419 static int __init init_ccwgroup(void)
420 {
421         int ret;
422
423         ret = bus_register(&ccwgroup_bus_type);
424         if (ret)
425                 return ret;
426
427         ret = bus_register_notifier(&ccwgroup_bus_type, &ccwgroup_nb);
428         if (ret)
429                 bus_unregister(&ccwgroup_bus_type);
430
431         return ret;
432 }
433
434 static void __exit cleanup_ccwgroup(void)
435 {
436         bus_unregister_notifier(&ccwgroup_bus_type, &ccwgroup_nb);
437         bus_unregister(&ccwgroup_bus_type);
438 }
439
440 module_init(init_ccwgroup);
441 module_exit(cleanup_ccwgroup);
442
443 /************************** driver stuff ******************************/
444
445 static int ccwgroup_remove(struct device *dev)
446 {
447         struct ccwgroup_device *gdev = to_ccwgroupdev(dev);
448         struct ccwgroup_driver *gdrv = to_ccwgroupdrv(dev->driver);
449
450         if (!dev->driver)
451                 return 0;
452         if (gdrv->remove)
453                 gdrv->remove(gdev);
454
455         return 0;
456 }
457
458 static void ccwgroup_shutdown(struct device *dev)
459 {
460         struct ccwgroup_device *gdev = to_ccwgroupdev(dev);
461         struct ccwgroup_driver *gdrv = to_ccwgroupdrv(dev->driver);
462
463         if (!dev->driver)
464                 return;
465         if (gdrv->shutdown)
466                 gdrv->shutdown(gdev);
467 }
468
469 static int ccwgroup_pm_prepare(struct device *dev)
470 {
471         struct ccwgroup_device *gdev = to_ccwgroupdev(dev);
472         struct ccwgroup_driver *gdrv = to_ccwgroupdrv(gdev->dev.driver);
473
474         /* Fail while device is being set online/offline. */
475         if (atomic_read(&gdev->onoff))
476                 return -EAGAIN;
477
478         if (!gdev->dev.driver || gdev->state != CCWGROUP_ONLINE)
479                 return 0;
480
481         return gdrv->prepare ? gdrv->prepare(gdev) : 0;
482 }
483
484 static void ccwgroup_pm_complete(struct device *dev)
485 {
486         struct ccwgroup_device *gdev = to_ccwgroupdev(dev);
487         struct ccwgroup_driver *gdrv = to_ccwgroupdrv(dev->driver);
488
489         if (!gdev->dev.driver || gdev->state != CCWGROUP_ONLINE)
490                 return;
491
492         if (gdrv->complete)
493                 gdrv->complete(gdev);
494 }
495
496 static int ccwgroup_pm_freeze(struct device *dev)
497 {
498         struct ccwgroup_device *gdev = to_ccwgroupdev(dev);
499         struct ccwgroup_driver *gdrv = to_ccwgroupdrv(gdev->dev.driver);
500
501         if (!gdev->dev.driver || gdev->state != CCWGROUP_ONLINE)
502                 return 0;
503
504         return gdrv->freeze ? gdrv->freeze(gdev) : 0;
505 }
506
507 static int ccwgroup_pm_thaw(struct device *dev)
508 {
509         struct ccwgroup_device *gdev = to_ccwgroupdev(dev);
510         struct ccwgroup_driver *gdrv = to_ccwgroupdrv(gdev->dev.driver);
511
512         if (!gdev->dev.driver || gdev->state != CCWGROUP_ONLINE)
513                 return 0;
514
515         return gdrv->thaw ? gdrv->thaw(gdev) : 0;
516 }
517
518 static int ccwgroup_pm_restore(struct device *dev)
519 {
520         struct ccwgroup_device *gdev = to_ccwgroupdev(dev);
521         struct ccwgroup_driver *gdrv = to_ccwgroupdrv(gdev->dev.driver);
522
523         if (!gdev->dev.driver || gdev->state != CCWGROUP_ONLINE)
524                 return 0;
525
526         return gdrv->restore ? gdrv->restore(gdev) : 0;
527 }
528
529 static const struct dev_pm_ops ccwgroup_pm_ops = {
530         .prepare = ccwgroup_pm_prepare,
531         .complete = ccwgroup_pm_complete,
532         .freeze = ccwgroup_pm_freeze,
533         .thaw = ccwgroup_pm_thaw,
534         .restore = ccwgroup_pm_restore,
535 };
536
537 static struct bus_type ccwgroup_bus_type = {
538         .name   = "ccwgroup",
539         .remove = ccwgroup_remove,
540         .shutdown = ccwgroup_shutdown,
541         .pm = &ccwgroup_pm_ops,
542 };
543
544 /**
545  * ccwgroup_driver_register() - register a ccw group driver
546  * @cdriver: driver to be registered
547  *
548  * This function is mainly a wrapper around driver_register().
549  */
550 int ccwgroup_driver_register(struct ccwgroup_driver *cdriver)
551 {
552         /* register our new driver with the core */
553         cdriver->driver.bus = &ccwgroup_bus_type;
554
555         return driver_register(&cdriver->driver);
556 }
557 EXPORT_SYMBOL(ccwgroup_driver_register);
558
559 static int __ccwgroup_match_all(struct device *dev, void *data)
560 {
561         return 1;
562 }
563
564 /**
565  * ccwgroup_driver_unregister() - deregister a ccw group driver
566  * @cdriver: driver to be deregistered
567  *
568  * This function is mainly a wrapper around driver_unregister().
569  */
570 void ccwgroup_driver_unregister(struct ccwgroup_driver *cdriver)
571 {
572         struct device *dev;
573
574         /* We don't want ccwgroup devices to live longer than their driver. */
575         while ((dev = driver_find_device(&cdriver->driver, NULL, NULL,
576                                          __ccwgroup_match_all))) {
577                 struct ccwgroup_device *gdev = to_ccwgroupdev(dev);
578
579                 mutex_lock(&gdev->reg_mutex);
580                 __ccwgroup_remove_symlinks(gdev);
581                 device_unregister(dev);
582                 __ccwgroup_remove_cdev_refs(gdev);
583                 mutex_unlock(&gdev->reg_mutex);
584                 put_device(dev);
585         }
586         driver_unregister(&cdriver->driver);
587 }
588 EXPORT_SYMBOL(ccwgroup_driver_unregister);
589
590 /**
591  * ccwgroup_probe_ccwdev() - probe function for slave devices
592  * @cdev: ccw device to be probed
593  *
594  * This is a dummy probe function for ccw devices that are slave devices in
595  * a ccw group device.
596  * Returns:
597  *  always %0
598  */
599 int ccwgroup_probe_ccwdev(struct ccw_device *cdev)
600 {
601         return 0;
602 }
603 EXPORT_SYMBOL(ccwgroup_probe_ccwdev);
604
605 /**
606  * ccwgroup_remove_ccwdev() - remove function for slave devices
607  * @cdev: ccw device to be removed
608  *
609  * This is a remove function for ccw devices that are slave devices in a ccw
610  * group device. It sets the ccw device offline and also deregisters the
611  * embedding ccw group device.
612  */
613 void ccwgroup_remove_ccwdev(struct ccw_device *cdev)
614 {
615         struct ccwgroup_device *gdev;
616
617         /* Ignore offlining errors, device is gone anyway. */
618         ccw_device_set_offline(cdev);
619         /* If one of its devices is gone, the whole group is done for. */
620         spin_lock_irq(cdev->ccwlock);
621         gdev = dev_get_drvdata(&cdev->dev);
622         if (!gdev) {
623                 spin_unlock_irq(cdev->ccwlock);
624                 return;
625         }
626         /* Get ccwgroup device reference for local processing. */
627         get_device(&gdev->dev);
628         spin_unlock_irq(cdev->ccwlock);
629         /* Unregister group device. */
630         mutex_lock(&gdev->reg_mutex);
631         if (device_is_registered(&gdev->dev)) {
632                 __ccwgroup_remove_symlinks(gdev);
633                 device_unregister(&gdev->dev);
634                 __ccwgroup_remove_cdev_refs(gdev);
635         }
636         mutex_unlock(&gdev->reg_mutex);
637         /* Release ccwgroup device reference for local processing. */
638         put_device(&gdev->dev);
639 }
640 EXPORT_SYMBOL(ccwgroup_remove_ccwdev);
641 MODULE_LICENSE("GPL");