void bakery_lock_release(unsigned long mpidr, bakery_lock * bakery)
{
	unsigned int entry = platform_get_core_pos(mpidr);

	assert_bakery_entry_valid(entry, bakery);
	assert(bakery->owner == entry);

	bakery->owner = NO_OWNER;
	bakery->number[entry] = 0;
}
/*
 * Acquire bakery lock
 *
 * Contending CPUs need first obtain a non-zero ticket and then calculate
 * priority value. A contending CPU iterate over all other CPUs in the platform,
 * which may be contending for the same lock, in the order of their ordinal
 * position (CPU0, CPU1 and so on). A non-contending CPU will have its ticket
 * (and priority) value as 0. The contending CPU compares its priority with that
 * of others'. The CPU with the highest priority (lowest numerical value)
 * acquires the lock
 */
void bakery_lock_get(unsigned long mpidr, bakery_lock_t *bakery)
{
	unsigned int they, me;
	unsigned int my_ticket, my_prio, their_ticket;

	me = platform_get_core_pos(mpidr);

	assert_bakery_entry_valid(me, bakery);

	/* Prevent recursive acquisition */
	assert(bakery->owner != me);

	/* Get a ticket */
	my_ticket = bakery_get_ticket(bakery, me);

	/*
	 * Now that we got our ticket, compute our priority value, then compare
	 * with that of others, and proceed to acquire the lock
	 */
	my_prio = PRIORITY(my_ticket, me);
	for (they = 0; they < BAKERY_LOCK_MAX_CPUS; they++) {
		if (me == they)
			continue;

		/* Wait for the contender to get their ticket */
		while (bakery->entering[they])
			wfe();

		/*
		 * If the other party is a contender, they'll have non-zero
		 * (valid) ticket value. If they do, compare priorities
		 */
		their_ticket = bakery->number[they];
		if (their_ticket && (PRIORITY(their_ticket, they) < my_prio)) {
			/*
			 * They have higher priority (lower value). Wait for
			 * their ticket value to change (either release the lock
			 * to have it dropped to 0; or drop and probably content
			 * again for the same lock to have an even higher value)
			 */
			do {
				wfe();
			} while (their_ticket == bakery->number[they]);
		}
	}

	/* Lock acquired */
	bakery->owner = me;
}
/* Release the lock and signal contenders */
void bakery_lock_release(unsigned long mpidr, bakery_lock_t *bakery)
{
	unsigned int me = platform_get_core_pos(mpidr);

	assert_bakery_entry_valid(me, bakery);
	assert(bakery->owner == me);

	/*
	 * Release lock by resetting ownership and ticket. Then signal other
	 * waiting contenders
	 */
	bakery->owner = NO_OWNER;
	bakery->number[me] = 0;
	sev();
}
/* Release the lock and signal contenders */
void bakery_lock_release(bakery_lock_t *bakery)
{
	unsigned int me = plat_my_core_pos();

	assert_bakery_entry_valid(me, bakery);
	assert(bakery_ticket_number(bakery->lock_data[me]));

	/*
	 * Release lock by resetting ticket. Then signal other
	 * waiting contenders
	 */
	bakery->lock_data[me] = 0;
	dsb();
	sev();
}
void bakery_lock_get(unsigned long mpidr, bakery_lock * bakery)
{
	unsigned int i, max = 0, my_full_number, his_full_number, entry;

	entry = platform_get_core_pos(mpidr);

	assert_bakery_entry_valid(entry, bakery);

	// Catch recursive attempts to take the lock under the same entry:
	assert(bakery->owner != entry);

	// Get a ticket
	bakery->entering[entry] = 1;
	for (i = 0; i < BAKERY_LOCK_MAX_CPUS; ++i) {
		if (bakery->number[i] > max) {
			max = bakery->number[i];
		}
	}
	++max;
	bakery->number[entry] = max;
	bakery->entering[entry] = 0;

	// Wait for our turn
	my_full_number = (max << 8) + entry;
	for (i = 0; i < BAKERY_LOCK_MAX_CPUS; ++i) {
		while (bakery->entering[i]) ;	/* Wait */
		do {
			his_full_number = bakery->number[i];
			if (his_full_number) {
				his_full_number = (his_full_number << 8) + i;
			}
		}
		while (his_full_number && (his_full_number < my_full_number));
	}

	bakery->owner = entry;
}