diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-07-26 21:59:59 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-07-26 21:59:59 -0400 |
commit | 9c1958fc326a0a0a533ec8e86ea6fa30977207de (patch) | |
tree | 9d76e6a146c2622fad0eefbb8ff0503caefe33cc /drivers/of | |
parent | 1b3fc0bef8859268d542230172f80e85553fdab4 (diff) | |
parent | 009a620848218d521f008141c62f56bf19294dd9 (diff) |
Merge tag 'media/v4.8-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media
Pull media updates from Mauro Carvalho Chehab:
- new framework support for HDMI CEC and remote control support
- new encoding codec driver for Mediatek SoC
- new frontend driver: helene tuner
- added support for NetUp almost universal devices, with supports
DVB-C/S/S2/T/T2 and ISDB-T
- the mn88472 frontend driver got promoted from staging
- a new driver for RCar video input
- some soc_camera legacy drivers got removed: timb, omap1, mx2, mx3
- lots of driver cleanups, improvements and fixups
* tag 'media/v4.8-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (377 commits)
[media] cec: always check all_device_types and features
[media] cec: poll should check if there is room in the tx queue
[media] vivid: support monitor all mode
[media] cec: fix test for unconfigured adapter in main message loop
[media] cec: limit the size of the transmit queue
[media] cec: zero unused msg part after msg->len
[media] cec: don't set fh to NULL in CEC_TRANSMIT
[media] cec: clear all status fields before transmit and always fill in sequence
[media] cec: CEC_RECEIVE overwrote the timeout field
[media] cxd2841er: Reading SNR for DVB-C added
[media] cxd2841er: Reading BER and UCB for DVB-C added
[media] cxd2841er: fix switch-case for DVB-C
[media] cxd2841er: fix signal strength scale for ISDB-T
[media] cxd2841er: adjust the dB scale for DVB-C
[media] cxd2841er: provide signal strength for DVB-C
[media] cxd2841er: fix BER report via DVBv5 stats API
[media] mb86a20s: apply mask to val after checking for read failure
[media] airspy: fix error logic during device register
[media] s5p-cec/TODO: add TODO item
[media] cec/TODO: drop comment about sphinx documentation
...
Diffstat (limited to 'drivers/of')
-rw-r--r-- | drivers/of/of_reserved_mem.c | 83 |
1 files changed, 63 insertions, 20 deletions
diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c index 216648233874..06af99f64ad8 100644 --- a/drivers/of/of_reserved_mem.c +++ b/drivers/of/of_reserved_mem.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/sizes.h> | 21 | #include <linux/sizes.h> |
22 | #include <linux/of_reserved_mem.h> | 22 | #include <linux/of_reserved_mem.h> |
23 | #include <linux/sort.h> | 23 | #include <linux/sort.h> |
24 | #include <linux/slab.h> | ||
24 | 25 | ||
25 | #define MAX_RESERVED_REGIONS 16 | 26 | #define MAX_RESERVED_REGIONS 16 |
26 | static struct reserved_mem reserved_mem[MAX_RESERVED_REGIONS]; | 27 | static struct reserved_mem reserved_mem[MAX_RESERVED_REGIONS]; |
@@ -296,53 +297,95 @@ static inline struct reserved_mem *__find_rmem(struct device_node *node) | |||
296 | return NULL; | 297 | return NULL; |
297 | } | 298 | } |
298 | 299 | ||
300 | struct rmem_assigned_device { | ||
301 | struct device *dev; | ||
302 | struct reserved_mem *rmem; | ||
303 | struct list_head list; | ||
304 | }; | ||
305 | |||
306 | static LIST_HEAD(of_rmem_assigned_device_list); | ||
307 | static DEFINE_MUTEX(of_rmem_assigned_device_mutex); | ||
308 | |||
299 | /** | 309 | /** |
300 | * of_reserved_mem_device_init() - assign reserved memory region to given device | 310 | * of_reserved_mem_device_init_by_idx() - assign reserved memory region to |
311 | * given device | ||
312 | * @dev: Pointer to the device to configure | ||
313 | * @np: Pointer to the device_node with 'reserved-memory' property | ||
314 | * @idx: Index of selected region | ||
301 | * | 315 | * |
302 | * This function assign memory region pointed by "memory-region" device tree | 316 | * This function assigns respective DMA-mapping operations based on reserved |
303 | * property to the given device. | 317 | * memory region specified by 'memory-region' property in @np node to the @dev |
318 | * device. When driver needs to use more than one reserved memory region, it | ||
319 | * should allocate child devices and initialize regions by name for each of | ||
320 | * child device. | ||
321 | * | ||
322 | * Returns error code or zero on success. | ||
304 | */ | 323 | */ |
305 | int of_reserved_mem_device_init(struct device *dev) | 324 | int of_reserved_mem_device_init_by_idx(struct device *dev, |
325 | struct device_node *np, int idx) | ||
306 | { | 326 | { |
327 | struct rmem_assigned_device *rd; | ||
328 | struct device_node *target; | ||
307 | struct reserved_mem *rmem; | 329 | struct reserved_mem *rmem; |
308 | struct device_node *np; | ||
309 | int ret; | 330 | int ret; |
310 | 331 | ||
311 | np = of_parse_phandle(dev->of_node, "memory-region", 0); | 332 | if (!np || !dev) |
312 | if (!np) | 333 | return -EINVAL; |
334 | |||
335 | target = of_parse_phandle(np, "memory-region", idx); | ||
336 | if (!target) | ||
313 | return -ENODEV; | 337 | return -ENODEV; |
314 | 338 | ||
315 | rmem = __find_rmem(np); | 339 | rmem = __find_rmem(target); |
316 | of_node_put(np); | 340 | of_node_put(target); |
317 | 341 | ||
318 | if (!rmem || !rmem->ops || !rmem->ops->device_init) | 342 | if (!rmem || !rmem->ops || !rmem->ops->device_init) |
319 | return -EINVAL; | 343 | return -EINVAL; |
320 | 344 | ||
345 | rd = kmalloc(sizeof(struct rmem_assigned_device), GFP_KERNEL); | ||
346 | if (!rd) | ||
347 | return -ENOMEM; | ||
348 | |||
321 | ret = rmem->ops->device_init(rmem, dev); | 349 | ret = rmem->ops->device_init(rmem, dev); |
322 | if (ret == 0) | 350 | if (ret == 0) { |
351 | rd->dev = dev; | ||
352 | rd->rmem = rmem; | ||
353 | |||
354 | mutex_lock(&of_rmem_assigned_device_mutex); | ||
355 | list_add(&rd->list, &of_rmem_assigned_device_list); | ||
356 | mutex_unlock(&of_rmem_assigned_device_mutex); | ||
357 | |||
323 | dev_info(dev, "assigned reserved memory node %s\n", rmem->name); | 358 | dev_info(dev, "assigned reserved memory node %s\n", rmem->name); |
359 | } else { | ||
360 | kfree(rd); | ||
361 | } | ||
324 | 362 | ||
325 | return ret; | 363 | return ret; |
326 | } | 364 | } |
327 | EXPORT_SYMBOL_GPL(of_reserved_mem_device_init); | 365 | EXPORT_SYMBOL_GPL(of_reserved_mem_device_init_by_idx); |
328 | 366 | ||
329 | /** | 367 | /** |
330 | * of_reserved_mem_device_release() - release reserved memory device structures | 368 | * of_reserved_mem_device_release() - release reserved memory device structures |
369 | * @dev: Pointer to the device to deconfigure | ||
331 | * | 370 | * |
332 | * This function releases structures allocated for memory region handling for | 371 | * This function releases structures allocated for memory region handling for |
333 | * the given device. | 372 | * the given device. |
334 | */ | 373 | */ |
335 | void of_reserved_mem_device_release(struct device *dev) | 374 | void of_reserved_mem_device_release(struct device *dev) |
336 | { | 375 | { |
337 | struct reserved_mem *rmem; | 376 | struct rmem_assigned_device *rd; |
338 | struct device_node *np; | 377 | struct reserved_mem *rmem = NULL; |
339 | 378 | ||
340 | np = of_parse_phandle(dev->of_node, "memory-region", 0); | 379 | mutex_lock(&of_rmem_assigned_device_mutex); |
341 | if (!np) | 380 | list_for_each_entry(rd, &of_rmem_assigned_device_list, list) { |
342 | return; | 381 | if (rd->dev == dev) { |
343 | 382 | rmem = rd->rmem; | |
344 | rmem = __find_rmem(np); | 383 | list_del(&rd->list); |
345 | of_node_put(np); | 384 | kfree(rd); |
385 | break; | ||
386 | } | ||
387 | } | ||
388 | mutex_unlock(&of_rmem_assigned_device_mutex); | ||
346 | 389 | ||
347 | if (!rmem || !rmem->ops || !rmem->ops->device_release) | 390 | if (!rmem || !rmem->ops || !rmem->ops->device_release) |
348 | return; | 391 | return; |