summaryrefslogtreecommitdiffstats
path: root/lib/xarray.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2019-02-08 08:20:32 -0500
committerTakashi Iwai <tiwai@suse.de>2019-02-08 08:20:32 -0500
commitd02cac152c97dffcb0cdd91e09b54fd6e2cca63d (patch)
tree68e4c6bd842703009f3edbf8f0e0e9326e4b2fad /lib/xarray.c
parent36e4617c01153757cde9e5fcd375a75a8f8425c3 (diff)
parenta50e32694fbcdbf55875095258b9398e2eabd71f (diff)
Merge tag 'asoc-v5.1' of https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-next
ASoC: Updates for v5.1 Lots and lots of new drivers so far, a highlight being the MediaTek BTCVSD which is a driver for a Bluetooth radio chip - the first such driver we've had upstream. Hopefully we will soon also see a baseband with an upstream driver! - Support for only powering up channels that are actively being used. - Quite a few improvements to simplify the generic card drivers, especially the merge of the SCU cards into the main generic drivers. - Lots of fixes for probing on Intel systems, trying to rationalize things to look more standard from a framework point of view. - New drivers for Asahi Kasei Microdevices AK4497, Cirrus Logic CS4341, Google ChromeOS embedded controllers, Ingenic JZ4725B, MediaTek BTCVSD, MT8183 and MT6358, NXP MICFIL, Rockchip RK3328, Spreadtrum DMA controllers, Qualcomm WCD9335, Xilinx S/PDIF and PCM formatters.
Diffstat (limited to 'lib/xarray.c')
-rw-r--r--lib/xarray.c92
1 files changed, 54 insertions, 38 deletions
diff --git a/lib/xarray.c b/lib/xarray.c
index 5f3f9311de89..81c3171ddde9 100644
--- a/lib/xarray.c
+++ b/lib/xarray.c
@@ -232,6 +232,8 @@ void *xas_load(struct xa_state *xas)
232 if (xas->xa_shift > node->shift) 232 if (xas->xa_shift > node->shift)
233 break; 233 break;
234 entry = xas_descend(xas, node); 234 entry = xas_descend(xas, node);
235 if (node->shift == 0)
236 break;
235 } 237 }
236 return entry; 238 return entry;
237} 239}
@@ -506,7 +508,7 @@ static void xas_free_nodes(struct xa_state *xas, struct xa_node *top)
506 for (;;) { 508 for (;;) {
507 void *entry = xa_entry_locked(xas->xa, node, offset); 509 void *entry = xa_entry_locked(xas->xa, node, offset);
508 510
509 if (xa_is_node(entry)) { 511 if (node->shift && xa_is_node(entry)) {
510 node = xa_to_node(entry); 512 node = xa_to_node(entry);
511 offset = 0; 513 offset = 0;
512 continue; 514 continue;
@@ -604,6 +606,7 @@ static int xas_expand(struct xa_state *xas, void *head)
604/* 606/*
605 * xas_create() - Create a slot to store an entry in. 607 * xas_create() - Create a slot to store an entry in.
606 * @xas: XArray operation state. 608 * @xas: XArray operation state.
609 * @allow_root: %true if we can store the entry in the root directly
607 * 610 *
608 * Most users will not need to call this function directly, as it is called 611 * Most users will not need to call this function directly, as it is called
609 * by xas_store(). It is useful for doing conditional store operations 612 * by xas_store(). It is useful for doing conditional store operations
@@ -613,7 +616,7 @@ static int xas_expand(struct xa_state *xas, void *head)
613 * If the slot was newly created, returns %NULL. If it failed to create the 616 * If the slot was newly created, returns %NULL. If it failed to create the
614 * slot, returns %NULL and indicates the error in @xas. 617 * slot, returns %NULL and indicates the error in @xas.
615 */ 618 */
616static void *xas_create(struct xa_state *xas) 619static void *xas_create(struct xa_state *xas, bool allow_root)
617{ 620{
618 struct xarray *xa = xas->xa; 621 struct xarray *xa = xas->xa;
619 void *entry; 622 void *entry;
@@ -628,6 +631,8 @@ static void *xas_create(struct xa_state *xas)
628 shift = xas_expand(xas, entry); 631 shift = xas_expand(xas, entry);
629 if (shift < 0) 632 if (shift < 0)
630 return NULL; 633 return NULL;
634 if (!shift && !allow_root)
635 shift = XA_CHUNK_SHIFT;
631 entry = xa_head_locked(xa); 636 entry = xa_head_locked(xa);
632 slot = &xa->xa_head; 637 slot = &xa->xa_head;
633 } else if (xas_error(xas)) { 638 } else if (xas_error(xas)) {
@@ -687,7 +692,7 @@ void xas_create_range(struct xa_state *xas)
687 xas->xa_sibs = 0; 692 xas->xa_sibs = 0;
688 693
689 for (;;) { 694 for (;;) {
690 xas_create(xas); 695 xas_create(xas, true);
691 if (xas_error(xas)) 696 if (xas_error(xas))
692 goto restore; 697 goto restore;
693 if (xas->xa_index <= (index | XA_CHUNK_MASK)) 698 if (xas->xa_index <= (index | XA_CHUNK_MASK))
@@ -754,7 +759,7 @@ void *xas_store(struct xa_state *xas, void *entry)
754 bool value = xa_is_value(entry); 759 bool value = xa_is_value(entry);
755 760
756 if (entry) 761 if (entry)
757 first = xas_create(xas); 762 first = xas_create(xas, !xa_is_node(entry));
758 else 763 else
759 first = xas_load(xas); 764 first = xas_load(xas);
760 765
@@ -1251,35 +1256,6 @@ void *xas_find_conflict(struct xa_state *xas)
1251EXPORT_SYMBOL_GPL(xas_find_conflict); 1256EXPORT_SYMBOL_GPL(xas_find_conflict);
1252 1257
1253/** 1258/**
1254 * xa_init_flags() - Initialise an empty XArray with flags.
1255 * @xa: XArray.
1256 * @flags: XA_FLAG values.
1257 *
1258 * If you need to initialise an XArray with special flags (eg you need
1259 * to take the lock from interrupt context), use this function instead
1260 * of xa_init().
1261 *
1262 * Context: Any context.
1263 */
1264void xa_init_flags(struct xarray *xa, gfp_t flags)
1265{
1266 unsigned int lock_type;
1267 static struct lock_class_key xa_lock_irq;
1268 static struct lock_class_key xa_lock_bh;
1269
1270 spin_lock_init(&xa->xa_lock);
1271 xa->xa_flags = flags;
1272 xa->xa_head = NULL;
1273
1274 lock_type = xa_lock_type(xa);
1275 if (lock_type == XA_LOCK_IRQ)
1276 lockdep_set_class(&xa->xa_lock, &xa_lock_irq);
1277 else if (lock_type == XA_LOCK_BH)
1278 lockdep_set_class(&xa->xa_lock, &xa_lock_bh);
1279}
1280EXPORT_SYMBOL(xa_init_flags);
1281
1282/**
1283 * xa_load() - Load an entry from an XArray. 1259 * xa_load() - Load an entry from an XArray.
1284 * @xa: XArray. 1260 * @xa: XArray.
1285 * @index: index into array. 1261 * @index: index into array.
@@ -1308,7 +1284,6 @@ static void *xas_result(struct xa_state *xas, void *curr)
1308{ 1284{
1309 if (xa_is_zero(curr)) 1285 if (xa_is_zero(curr))
1310 return NULL; 1286 return NULL;
1311 XA_NODE_BUG_ON(xas->xa_node, xa_is_internal(curr));
1312 if (xas_error(xas)) 1287 if (xas_error(xas))
1313 curr = xas->xa_node; 1288 curr = xas->xa_node;
1314 return curr; 1289 return curr;
@@ -1378,7 +1353,7 @@ void *__xa_store(struct xarray *xa, unsigned long index, void *entry, gfp_t gfp)
1378 XA_STATE(xas, xa, index); 1353 XA_STATE(xas, xa, index);
1379 void *curr; 1354 void *curr;
1380 1355
1381 if (WARN_ON_ONCE(xa_is_internal(entry))) 1356 if (WARN_ON_ONCE(xa_is_advanced(entry)))
1382 return XA_ERROR(-EINVAL); 1357 return XA_ERROR(-EINVAL);
1383 if (xa_track_free(xa) && !entry) 1358 if (xa_track_free(xa) && !entry)
1384 entry = XA_ZERO_ENTRY; 1359 entry = XA_ZERO_ENTRY;
@@ -1444,7 +1419,7 @@ void *__xa_cmpxchg(struct xarray *xa, unsigned long index,
1444 XA_STATE(xas, xa, index); 1419 XA_STATE(xas, xa, index);
1445 void *curr; 1420 void *curr;
1446 1421
1447 if (WARN_ON_ONCE(xa_is_internal(entry))) 1422 if (WARN_ON_ONCE(xa_is_advanced(entry)))
1448 return XA_ERROR(-EINVAL); 1423 return XA_ERROR(-EINVAL);
1449 if (xa_track_free(xa) && !entry) 1424 if (xa_track_free(xa) && !entry)
1450 entry = XA_ZERO_ENTRY; 1425 entry = XA_ZERO_ENTRY;
@@ -1465,6 +1440,47 @@ void *__xa_cmpxchg(struct xarray *xa, unsigned long index,
1465EXPORT_SYMBOL(__xa_cmpxchg); 1440EXPORT_SYMBOL(__xa_cmpxchg);
1466 1441
1467/** 1442/**
1443 * __xa_insert() - Store this entry in the XArray if no entry is present.
1444 * @xa: XArray.
1445 * @index: Index into array.
1446 * @entry: New entry.
1447 * @gfp: Memory allocation flags.
1448 *
1449 * Inserting a NULL entry will store a reserved entry (like xa_reserve())
1450 * if no entry is present. Inserting will fail if a reserved entry is
1451 * present, even though loading from this index will return NULL.
1452 *
1453 * Context: Any context. Expects xa_lock to be held on entry. May
1454 * release and reacquire xa_lock if @gfp flags permit.
1455 * Return: 0 if the store succeeded. -EEXIST if another entry was present.
1456 * -ENOMEM if memory could not be allocated.
1457 */
1458int __xa_insert(struct xarray *xa, unsigned long index, void *entry, gfp_t gfp)
1459{
1460 XA_STATE(xas, xa, index);
1461 void *curr;
1462
1463 if (WARN_ON_ONCE(xa_is_advanced(entry)))
1464 return -EINVAL;
1465 if (!entry)
1466 entry = XA_ZERO_ENTRY;
1467
1468 do {
1469 curr = xas_load(&xas);
1470 if (!curr) {
1471 xas_store(&xas, entry);
1472 if (xa_track_free(xa))
1473 xas_clear_mark(&xas, XA_FREE_MARK);
1474 } else {
1475 xas_set_err(&xas, -EEXIST);
1476 }
1477 } while (__xas_nomem(&xas, gfp));
1478
1479 return xas_error(&xas);
1480}
1481EXPORT_SYMBOL(__xa_insert);
1482
1483/**
1468 * __xa_reserve() - Reserve this index in the XArray. 1484 * __xa_reserve() - Reserve this index in the XArray.
1469 * @xa: XArray. 1485 * @xa: XArray.
1470 * @index: Index into array. 1486 * @index: Index into array.
@@ -1567,7 +1583,7 @@ void *xa_store_range(struct xarray *xa, unsigned long first,
1567 if (last + 1) 1583 if (last + 1)
1568 order = __ffs(last + 1); 1584 order = __ffs(last + 1);
1569 xas_set_order(&xas, last, order); 1585 xas_set_order(&xas, last, order);
1570 xas_create(&xas); 1586 xas_create(&xas, true);
1571 if (xas_error(&xas)) 1587 if (xas_error(&xas))
1572 goto unlock; 1588 goto unlock;
1573 } 1589 }
@@ -1609,7 +1625,7 @@ int __xa_alloc(struct xarray *xa, u32 *id, u32 max, void *entry, gfp_t gfp)
1609 XA_STATE(xas, xa, 0); 1625 XA_STATE(xas, xa, 0);
1610 int err; 1626 int err;
1611 1627
1612 if (WARN_ON_ONCE(xa_is_internal(entry))) 1628 if (WARN_ON_ONCE(xa_is_advanced(entry)))
1613 return -EINVAL; 1629 return -EINVAL;
1614 if (WARN_ON_ONCE(!xa_track_free(xa))) 1630 if (WARN_ON_ONCE(!xa_track_free(xa)))
1615 return -EINVAL; 1631 return -EINVAL;