drivers: remove struct module * setting from struct class
[linux-2.6-microblaze.git] / drivers / staging / greybus / vibrator.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Greybus Vibrator protocol driver.
4  *
5  * Copyright 2014 Google Inc.
6  * Copyright 2014 Linaro Ltd.
7  */
8
9 #include <linux/kernel.h>
10 #include <linux/module.h>
11 #include <linux/slab.h>
12 #include <linux/device.h>
13 #include <linux/kdev_t.h>
14 #include <linux/idr.h>
15 #include <linux/pm_runtime.h>
16 #include <linux/greybus.h>
17
18 struct gb_vibrator_device {
19         struct gb_connection    *connection;
20         struct device           *dev;
21         int                     minor;          /* vibrator minor number */
22         struct delayed_work     delayed_work;
23 };
24
25 /* Greybus Vibrator operation types */
26 #define GB_VIBRATOR_TYPE_ON                     0x02
27 #define GB_VIBRATOR_TYPE_OFF                    0x03
28
29 static int turn_off(struct gb_vibrator_device *vib)
30 {
31         struct gb_bundle *bundle = vib->connection->bundle;
32         int ret;
33
34         ret = gb_operation_sync(vib->connection, GB_VIBRATOR_TYPE_OFF,
35                                 NULL, 0, NULL, 0);
36
37         gb_pm_runtime_put_autosuspend(bundle);
38
39         return ret;
40 }
41
42 static int turn_on(struct gb_vibrator_device *vib, u16 timeout_ms)
43 {
44         struct gb_bundle *bundle = vib->connection->bundle;
45         int ret;
46
47         ret = gb_pm_runtime_get_sync(bundle);
48         if (ret)
49                 return ret;
50
51         /* Vibrator was switched ON earlier */
52         if (cancel_delayed_work_sync(&vib->delayed_work))
53                 turn_off(vib);
54
55         ret = gb_operation_sync(vib->connection, GB_VIBRATOR_TYPE_ON,
56                                 NULL, 0, NULL, 0);
57         if (ret) {
58                 gb_pm_runtime_put_autosuspend(bundle);
59                 return ret;
60         }
61
62         schedule_delayed_work(&vib->delayed_work, msecs_to_jiffies(timeout_ms));
63
64         return 0;
65 }
66
67 static void gb_vibrator_worker(struct work_struct *work)
68 {
69         struct delayed_work *delayed_work = to_delayed_work(work);
70         struct gb_vibrator_device *vib =
71                 container_of(delayed_work,
72                              struct gb_vibrator_device,
73                              delayed_work);
74
75         turn_off(vib);
76 }
77
78 static ssize_t timeout_store(struct device *dev, struct device_attribute *attr,
79                              const char *buf, size_t count)
80 {
81         struct gb_vibrator_device *vib = dev_get_drvdata(dev);
82         unsigned long val;
83         int retval;
84
85         retval = kstrtoul(buf, 10, &val);
86         if (retval < 0) {
87                 dev_err(dev, "could not parse timeout value %d\n", retval);
88                 return retval;
89         }
90
91         if (val)
92                 retval = turn_on(vib, (u16)val);
93         else
94                 retval = turn_off(vib);
95         if (retval)
96                 return retval;
97
98         return count;
99 }
100 static DEVICE_ATTR_WO(timeout);
101
102 static struct attribute *vibrator_attrs[] = {
103         &dev_attr_timeout.attr,
104         NULL,
105 };
106 ATTRIBUTE_GROUPS(vibrator);
107
108 static struct class vibrator_class = {
109         .name           = "vibrator",
110         .dev_groups     = vibrator_groups,
111 };
112
113 static DEFINE_IDA(minors);
114
115 static int gb_vibrator_probe(struct gb_bundle *bundle,
116                              const struct greybus_bundle_id *id)
117 {
118         struct greybus_descriptor_cport *cport_desc;
119         struct gb_connection *connection;
120         struct gb_vibrator_device *vib;
121         struct device *dev;
122         int retval;
123
124         if (bundle->num_cports != 1)
125                 return -ENODEV;
126
127         cport_desc = &bundle->cport_desc[0];
128         if (cport_desc->protocol_id != GREYBUS_PROTOCOL_VIBRATOR)
129                 return -ENODEV;
130
131         vib = kzalloc(sizeof(*vib), GFP_KERNEL);
132         if (!vib)
133                 return -ENOMEM;
134
135         connection = gb_connection_create(bundle, le16_to_cpu(cport_desc->id),
136                                           NULL);
137         if (IS_ERR(connection)) {
138                 retval = PTR_ERR(connection);
139                 goto err_free_vib;
140         }
141         gb_connection_set_data(connection, vib);
142
143         vib->connection = connection;
144
145         greybus_set_drvdata(bundle, vib);
146
147         retval = gb_connection_enable(connection);
148         if (retval)
149                 goto err_connection_destroy;
150
151         /*
152          * For now we create a device in sysfs for the vibrator, but odds are
153          * there is a "real" device somewhere in the kernel for this, but I
154          * can't find it at the moment...
155          */
156         vib->minor = ida_simple_get(&minors, 0, 0, GFP_KERNEL);
157         if (vib->minor < 0) {
158                 retval = vib->minor;
159                 goto err_connection_disable;
160         }
161         dev = device_create(&vibrator_class, &bundle->dev,
162                             MKDEV(0, 0), vib, "vibrator%d", vib->minor);
163         if (IS_ERR(dev)) {
164                 retval = -EINVAL;
165                 goto err_ida_remove;
166         }
167         vib->dev = dev;
168
169         INIT_DELAYED_WORK(&vib->delayed_work, gb_vibrator_worker);
170
171         gb_pm_runtime_put_autosuspend(bundle);
172
173         return 0;
174
175 err_ida_remove:
176         ida_simple_remove(&minors, vib->minor);
177 err_connection_disable:
178         gb_connection_disable(connection);
179 err_connection_destroy:
180         gb_connection_destroy(connection);
181 err_free_vib:
182         kfree(vib);
183
184         return retval;
185 }
186
187 static void gb_vibrator_disconnect(struct gb_bundle *bundle)
188 {
189         struct gb_vibrator_device *vib = greybus_get_drvdata(bundle);
190         int ret;
191
192         ret = gb_pm_runtime_get_sync(bundle);
193         if (ret)
194                 gb_pm_runtime_get_noresume(bundle);
195
196         if (cancel_delayed_work_sync(&vib->delayed_work))
197                 turn_off(vib);
198
199         device_unregister(vib->dev);
200         ida_simple_remove(&minors, vib->minor);
201         gb_connection_disable(vib->connection);
202         gb_connection_destroy(vib->connection);
203         kfree(vib);
204 }
205
206 static const struct greybus_bundle_id gb_vibrator_id_table[] = {
207         { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_VIBRATOR) },
208         { }
209 };
210 MODULE_DEVICE_TABLE(greybus, gb_vibrator_id_table);
211
212 static struct greybus_driver gb_vibrator_driver = {
213         .name           = "vibrator",
214         .probe          = gb_vibrator_probe,
215         .disconnect     = gb_vibrator_disconnect,
216         .id_table       = gb_vibrator_id_table,
217 };
218
219 static __init int gb_vibrator_init(void)
220 {
221         int retval;
222
223         retval = class_register(&vibrator_class);
224         if (retval)
225                 return retval;
226
227         retval = greybus_register(&gb_vibrator_driver);
228         if (retval)
229                 goto err_class_unregister;
230
231         return 0;
232
233 err_class_unregister:
234         class_unregister(&vibrator_class);
235
236         return retval;
237 }
238 module_init(gb_vibrator_init);
239
240 static __exit void gb_vibrator_exit(void)
241 {
242         greybus_deregister(&gb_vibrator_driver);
243         class_unregister(&vibrator_class);
244         ida_destroy(&minors);
245 }
246 module_exit(gb_vibrator_exit);
247
248 MODULE_LICENSE("GPL v2");