thermal: rockchip: rk3368: ajust tsadc's data path according request of qos
[firefly-linux-kernel-4.4.55.git] / drivers / mcb / mcb-core.c
1 /*
2  * MEN Chameleon Bus.
3  *
4  * Copyright (C) 2013 MEN Mikroelektronik GmbH (www.men.de)
5  * Author: Johannes Thumshirn <johannes.thumshirn@men.de>
6  *
7  * This program is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU General Public License as published by the Free
9  * Software Foundation; version 2 of the License.
10  */
11 #include <linux/kernel.h>
12 #include <linux/module.h>
13 #include <linux/slab.h>
14 #include <linux/types.h>
15 #include <linux/idr.h>
16 #include <linux/mcb.h>
17
18 static DEFINE_IDA(mcb_ida);
19
20 static const struct mcb_device_id *mcb_match_id(const struct mcb_device_id *ids,
21                                                 struct mcb_device *dev)
22 {
23         if (ids) {
24                 while (ids->device) {
25                         if (ids->device == dev->id)
26                                 return ids;
27                         ids++;
28                 }
29         }
30
31         return NULL;
32 }
33
34 static int mcb_match(struct device *dev, struct device_driver *drv)
35 {
36         struct mcb_driver *mdrv = to_mcb_driver(drv);
37         struct mcb_device *mdev = to_mcb_device(dev);
38         const struct mcb_device_id *found_id;
39
40         found_id = mcb_match_id(mdrv->id_table, mdev);
41         if (found_id)
42                 return 1;
43
44         return 0;
45 }
46
47 static int mcb_uevent(struct device *dev, struct kobj_uevent_env *env)
48 {
49         struct mcb_device *mdev = to_mcb_device(dev);
50         int ret;
51
52         ret = add_uevent_var(env, "MODALIAS=mcb:16z%03d", mdev->id);
53         if (ret)
54                 return -ENOMEM;
55
56         return 0;
57 }
58
59 static int mcb_probe(struct device *dev)
60 {
61         struct mcb_driver *mdrv = to_mcb_driver(dev->driver);
62         struct mcb_device *mdev = to_mcb_device(dev);
63         const struct mcb_device_id *found_id;
64
65         found_id = mcb_match_id(mdrv->id_table, mdev);
66         if (!found_id)
67                 return -ENODEV;
68
69         return mdrv->probe(mdev, found_id);
70 }
71
72 static int mcb_remove(struct device *dev)
73 {
74         struct mcb_driver *mdrv = to_mcb_driver(dev->driver);
75         struct mcb_device *mdev = to_mcb_device(dev);
76
77         mdrv->remove(mdev);
78
79         put_device(&mdev->dev);
80
81         return 0;
82 }
83
84 static void mcb_shutdown(struct device *dev)
85 {
86         struct mcb_device *mdev = to_mcb_device(dev);
87         struct mcb_driver *mdrv = mdev->driver;
88
89         if (mdrv && mdrv->shutdown)
90                 mdrv->shutdown(mdev);
91 }
92
93 static struct bus_type mcb_bus_type = {
94         .name = "mcb",
95         .match = mcb_match,
96         .uevent = mcb_uevent,
97         .probe = mcb_probe,
98         .remove = mcb_remove,
99         .shutdown = mcb_shutdown,
100 };
101
102 /**
103  * __mcb_register_driver() - Register a @mcb_driver at the system
104  * @drv: The @mcb_driver
105  * @owner: The @mcb_driver's module
106  * @mod_name: The name of the @mcb_driver's module
107  *
108  * Register a @mcb_driver at the system. Perform some sanity checks, if
109  * the .probe and .remove methods are provided by the driver.
110  */
111 int __mcb_register_driver(struct mcb_driver *drv, struct module *owner,
112                         const char *mod_name)
113 {
114         if (!drv->probe || !drv->remove)
115                 return -EINVAL;
116
117         drv->driver.owner = owner;
118         drv->driver.bus = &mcb_bus_type;
119         drv->driver.mod_name = mod_name;
120
121         return driver_register(&drv->driver);
122 }
123 EXPORT_SYMBOL_GPL(__mcb_register_driver);
124
125 /**
126  * mcb_unregister_driver() - Unregister a @mcb_driver from the system
127  * @drv: The @mcb_driver
128  *
129  * Unregister a @mcb_driver from the system.
130  */
131 void mcb_unregister_driver(struct mcb_driver *drv)
132 {
133         driver_unregister(&drv->driver);
134 }
135 EXPORT_SYMBOL_GPL(mcb_unregister_driver);
136
137 static void mcb_release_dev(struct device *dev)
138 {
139         struct mcb_device *mdev = to_mcb_device(dev);
140
141         mcb_bus_put(mdev->bus);
142         kfree(mdev);
143 }
144
145 /**
146  * mcb_device_register() - Register a mcb_device
147  * @bus: The @mcb_bus of the device
148  * @dev: The @mcb_device
149  *
150  * Register a specific @mcb_device at a @mcb_bus and the system itself.
151  */
152 int mcb_device_register(struct mcb_bus *bus, struct mcb_device *dev)
153 {
154         int ret;
155         int device_id;
156
157         device_initialize(&dev->dev);
158         dev->dev.bus = &mcb_bus_type;
159         dev->dev.parent = bus->dev.parent;
160         dev->dev.release = mcb_release_dev;
161
162         device_id = dev->id;
163         dev_set_name(&dev->dev, "mcb%d-16z%03d-%d:%d:%d",
164                 bus->bus_nr, device_id, dev->inst, dev->group, dev->var);
165
166         ret = device_add(&dev->dev);
167         if (ret < 0) {
168                 pr_err("Failed registering device 16z%03d on bus mcb%d (%d)\n",
169                         device_id, bus->bus_nr, ret);
170                 goto out;
171         }
172
173         return 0;
174
175 out:
176
177         return ret;
178 }
179 EXPORT_SYMBOL_GPL(mcb_device_register);
180
181 /**
182  * mcb_alloc_bus() - Allocate a new @mcb_bus
183  *
184  * Allocate a new @mcb_bus.
185  */
186 struct mcb_bus *mcb_alloc_bus(struct device *carrier)
187 {
188         struct mcb_bus *bus;
189         int bus_nr;
190
191         bus = kzalloc(sizeof(struct mcb_bus), GFP_KERNEL);
192         if (!bus)
193                 return ERR_PTR(-ENOMEM);
194
195         bus_nr = ida_simple_get(&mcb_ida, 0, 0, GFP_KERNEL);
196         if (bus_nr < 0) {
197                 kfree(bus);
198                 return ERR_PTR(bus_nr);
199         }
200
201         INIT_LIST_HEAD(&bus->children);
202         bus->bus_nr = bus_nr;
203         bus->carrier = carrier;
204         return bus;
205 }
206 EXPORT_SYMBOL_GPL(mcb_alloc_bus);
207
208 static int __mcb_devices_unregister(struct device *dev, void *data)
209 {
210         device_unregister(dev);
211         return 0;
212 }
213
214 static void mcb_devices_unregister(struct mcb_bus *bus)
215 {
216         bus_for_each_dev(&mcb_bus_type, NULL, NULL, __mcb_devices_unregister);
217 }
218 /**
219  * mcb_release_bus() - Free a @mcb_bus
220  * @bus: The @mcb_bus to release
221  *
222  * Release an allocated @mcb_bus from the system.
223  */
224 void mcb_release_bus(struct mcb_bus *bus)
225 {
226         mcb_devices_unregister(bus);
227
228         ida_simple_remove(&mcb_ida, bus->bus_nr);
229
230         kfree(bus);
231 }
232 EXPORT_SYMBOL_GPL(mcb_release_bus);
233
234 /**
235  * mcb_bus_put() - Increment refcnt
236  * @bus: The @mcb_bus
237  *
238  * Get a @mcb_bus' ref
239  */
240 struct mcb_bus *mcb_bus_get(struct mcb_bus *bus)
241 {
242         if (bus)
243                 get_device(&bus->dev);
244
245         return bus;
246 }
247 EXPORT_SYMBOL_GPL(mcb_bus_get);
248
249 /**
250  * mcb_bus_put() - Decrement refcnt
251  * @bus: The @mcb_bus
252  *
253  * Release a @mcb_bus' ref
254  */
255 void mcb_bus_put(struct mcb_bus *bus)
256 {
257         if (bus)
258                 put_device(&bus->dev);
259 }
260 EXPORT_SYMBOL_GPL(mcb_bus_put);
261
262 /**
263  * mcb_alloc_dev() - Allocate a device
264  * @bus: The @mcb_bus the device is part of
265  *
266  * Allocate a @mcb_device and add bus.
267  */
268 struct mcb_device *mcb_alloc_dev(struct mcb_bus *bus)
269 {
270         struct mcb_device *dev;
271
272         dev = kzalloc(sizeof(struct mcb_device), GFP_KERNEL);
273         if (!dev)
274                 return NULL;
275
276         INIT_LIST_HEAD(&dev->bus_list);
277         dev->bus = bus;
278
279         return dev;
280 }
281 EXPORT_SYMBOL_GPL(mcb_alloc_dev);
282
283 /**
284  * mcb_free_dev() - Free @mcb_device
285  * @dev: The device to free
286  *
287  * Free a @mcb_device
288  */
289 void mcb_free_dev(struct mcb_device *dev)
290 {
291         kfree(dev);
292 }
293 EXPORT_SYMBOL_GPL(mcb_free_dev);
294
295 static int __mcb_bus_add_devices(struct device *dev, void *data)
296 {
297         struct mcb_device *mdev = to_mcb_device(dev);
298         int retval;
299
300         if (mdev->is_added)
301                 return 0;
302
303         retval = device_attach(dev);
304         if (retval < 0)
305                 dev_err(dev, "Error adding device (%d)\n", retval);
306
307         mdev->is_added = true;
308
309         return 0;
310 }
311
312 static int __mcb_bus_add_child(struct device *dev, void *data)
313 {
314         struct mcb_device *mdev = to_mcb_device(dev);
315         struct mcb_bus *child;
316
317         BUG_ON(!mdev->is_added);
318         child = mdev->subordinate;
319
320         if (child)
321                 mcb_bus_add_devices(child);
322
323         return 0;
324 }
325
326 /**
327  * mcb_bus_add_devices() - Add devices in the bus' internal device list
328  * @bus: The @mcb_bus we add the devices
329  *
330  * Add devices in the bus' internal device list to the system.
331  */
332 void mcb_bus_add_devices(const struct mcb_bus *bus)
333 {
334         bus_for_each_dev(&mcb_bus_type, NULL, NULL, __mcb_bus_add_devices);
335         bus_for_each_dev(&mcb_bus_type, NULL, NULL, __mcb_bus_add_child);
336
337 }
338 EXPORT_SYMBOL_GPL(mcb_bus_add_devices);
339
340 /**
341  * mcb_request_mem() - Request memory
342  * @dev: The @mcb_device the memory is for
343  * @name: The name for the memory reference.
344  *
345  * Request memory for a @mcb_device. If @name is NULL the driver name will
346  * be used.
347  */
348 struct resource *mcb_request_mem(struct mcb_device *dev, const char *name)
349 {
350         struct resource *mem;
351         u32 size;
352
353         if (!name)
354                 name = dev->dev.driver->name;
355
356         size = resource_size(&dev->mem);
357
358         mem = request_mem_region(dev->mem.start, size, name);
359         if (!mem)
360                 return ERR_PTR(-EBUSY);
361
362         return mem;
363 }
364 EXPORT_SYMBOL_GPL(mcb_request_mem);
365
366 /**
367  * mcb_release_mem() - Release memory requested by device
368  * @dev: The @mcb_device that requested the memory
369  *
370  * Release memory that was prior requested via @mcb_request_mem().
371  */
372 void mcb_release_mem(struct resource *mem)
373 {
374         u32 size;
375
376         size = resource_size(mem);
377         release_mem_region(mem->start, size);
378 }
379 EXPORT_SYMBOL_GPL(mcb_release_mem);
380
381 static int __mcb_get_irq(struct mcb_device *dev)
382 {
383         struct resource *irq = &dev->irq;
384
385         return irq->start;
386 }
387
388 /**
389  * mcb_get_irq() - Get device's IRQ number
390  * @dev: The @mcb_device the IRQ is for
391  *
392  * Get the IRQ number of a given @mcb_device.
393  */
394 int mcb_get_irq(struct mcb_device *dev)
395 {
396         struct mcb_bus *bus = dev->bus;
397
398         if (bus->get_irq)
399                 return bus->get_irq(dev);
400
401         return __mcb_get_irq(dev);
402 }
403 EXPORT_SYMBOL_GPL(mcb_get_irq);
404
405 static int mcb_init(void)
406 {
407         return bus_register(&mcb_bus_type);
408 }
409
410 static void mcb_exit(void)
411 {
412         ida_destroy(&mcb_ida);
413         bus_unregister(&mcb_bus_type);
414 }
415
416 /* mcb must be initialized after PCI but before the chameleon drivers.
417  * That means we must use some initcall between subsys_initcall and
418  * device_initcall.
419  */
420 fs_initcall(mcb_init);
421 module_exit(mcb_exit);
422
423 MODULE_DESCRIPTION("MEN Chameleon Bus Driver");
424 MODULE_AUTHOR("Johannes Thumshirn <johannes.thumshirn@men.de>");
425 MODULE_LICENSE("GPL v2");