Revision 497d2214e5ba58ef55025b9951e7f9cccab760e4 authored by Mike Turquette on 06 January 2014, 05:36:43 UTC, committed by Mike Turquette on 06 January 2014, 05:36:43 UTC
Samsung Clock fixes for 3.13-rc7

* Several patches fixing up incorrectly defined register addresses and
  bitfield offsets that could lead to undefined operation when accessing
  respective registers or bitfields.

 1) clk: exynos5250: fix sysmmu_mfc{l,r} gate clocks

 2a) clk: samsung: exynos5250: Fix ACP gate register offset
 2b) clk: samsung: exynos5250: Add MDMA0 clocks
 2c) ARM: dts: exynos5250: Fix MDMA0 clock number

 3) clk: samsung: exynos4: Correct SRC_MFC register

   All three issues have been present since Exynos5250 and Exynos4 clock
   drivers were added by commits 6e3ad26816b72 ("clk: exynos5250:
   register clocks using common clock framework") and e062b571777f5
   ("clk: exynos4: register clocks using common clock framework")
   respectively.

* Patch to fix automatic disabling of Exynos5250 sysreg clock that could
  cause undefined operation of several peripherals, such as USB, I2C,
  MIPI or display block.

 4) clk: samsung: exynos5250: Add CLK_IGNORE_UNUSED flag for the sysreg
    clock

   Present since Exynos5250 clock drivers was added by commits
   6e3ad26816b72 ("clk: exynos5250: register clocks using common clock
   framework").

* Patch fixing compilation warning in clk-exynos-audss driver when
  CONFIG_PM_SLEEP is disabled.

 5) clk: exynos: File scope reg_save array should depend on PM_SLEEP

   Present since the driver was added by commit 1241ef94ccc3 ("clk:
   samsung: register audio subsystem clocks using common clock
   framework").
2 parent s d6e0a2d + 3fd68c9
Raw File
range.c
/*
 * Range add and subtract
 */
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/sort.h>
#include <linux/string.h>
#include <linux/range.h>

int add_range(struct range *range, int az, int nr_range, u64 start, u64 end)
{
	if (start >= end)
		return nr_range;

	/* Out of slots: */
	if (nr_range >= az)
		return nr_range;

	range[nr_range].start = start;
	range[nr_range].end = end;

	nr_range++;

	return nr_range;
}

int add_range_with_merge(struct range *range, int az, int nr_range,
		     u64 start, u64 end)
{
	int i;

	if (start >= end)
		return nr_range;

	/* get new start/end: */
	for (i = 0; i < nr_range; i++) {
		u64 common_start, common_end;

		if (!range[i].end)
			continue;

		common_start = max(range[i].start, start);
		common_end = min(range[i].end, end);
		if (common_start > common_end)
			continue;

		/* new start/end, will add it back at last */
		start = min(range[i].start, start);
		end = max(range[i].end, end);

		memmove(&range[i], &range[i + 1],
			(nr_range - (i + 1)) * sizeof(range[i]));
		range[nr_range - 1].start = 0;
		range[nr_range - 1].end   = 0;
		nr_range--;
		i--;
	}

	/* Need to add it: */
	return add_range(range, az, nr_range, start, end);
}

void subtract_range(struct range *range, int az, u64 start, u64 end)
{
	int i, j;

	if (start >= end)
		return;

	for (j = 0; j < az; j++) {
		if (!range[j].end)
			continue;

		if (start <= range[j].start && end >= range[j].end) {
			range[j].start = 0;
			range[j].end = 0;
			continue;
		}

		if (start <= range[j].start && end < range[j].end &&
		    range[j].start < end) {
			range[j].start = end;
			continue;
		}


		if (start > range[j].start && end >= range[j].end &&
		    range[j].end > start) {
			range[j].end = start;
			continue;
		}

		if (start > range[j].start && end < range[j].end) {
			/* Find the new spare: */
			for (i = 0; i < az; i++) {
				if (range[i].end == 0)
					break;
			}
			if (i < az) {
				range[i].end = range[j].end;
				range[i].start = end;
			} else {
				pr_err("%s: run out of slot in ranges\n",
					__func__);
			}
			range[j].end = start;
			continue;
		}
	}
}

static int cmp_range(const void *x1, const void *x2)
{
	const struct range *r1 = x1;
	const struct range *r2 = x2;
	s64 start1, start2;

	start1 = r1->start;
	start2 = r2->start;

	return start1 - start2;
}

int clean_sort_range(struct range *range, int az)
{
	int i, j, k = az - 1, nr_range = az;

	for (i = 0; i < k; i++) {
		if (range[i].end)
			continue;
		for (j = k; j > i; j--) {
			if (range[j].end) {
				k = j;
				break;
			}
		}
		if (j == i)
			break;
		range[i].start = range[k].start;
		range[i].end   = range[k].end;
		range[k].start = 0;
		range[k].end   = 0;
		k--;
	}
	/* count it */
	for (i = 0; i < az; i++) {
		if (!range[i].end) {
			nr_range = i;
			break;
		}
	}

	/* sort them */
	sort(range, nr_range, sizeof(struct range), cmp_range, NULL);

	return nr_range;
}

void sort_range(struct range *range, int nr_range)
{
	/* sort them */
	sort(range, nr_range, sizeof(struct range), cmp_range, NULL);
}
back to top