blob: d1840e754429deb939c06f1847016025c76a6349 [file] [log] [blame]
/*
* Copyright (C) ST-Ericsson SA 2011
* Author: Maxime Coquelin <maxime.coquelin@stericsson.com> for ST-Ericsson.
* License terms: GNU General Public License (GPL), version 2
*/
#include <linux/pasr.h>
struct pasr_die *pasr_addr2die(struct pasr_map *map, phys_addr_t addr)
{
unsigned int left, right, mid;
if (!map)
return NULL;
left = 0;
right = map->nr_dies;
while (left != right) {
struct pasr_die *d;
phys_addr_t start;
mid = (left + right) >> 1;
d = &map->die[mid];
start = addr & ~((section_size * d->nr_sections) - 1);
if (start == d->start)
return d;
if (left == mid || right == mid)
break;
if (start > d->start)
left = mid;
else
right = mid;
}
pr_err("%s: No die found for address %#x",
__func__, addr);
return NULL;
}
struct pasr_section *pasr_addr2section(struct pasr_map *map
, phys_addr_t addr)
{
unsigned int left, right, mid;
struct pasr_die *die;
/* Find the die the address it is located in */
die = pasr_addr2die(map, addr);
if (!die)
goto err;
left = 0;
right = die->nr_sections;
addr &= ~(section_size - 1);
while (left != right) {
struct pasr_section *s;
mid = (left + right) >> 1;
s = &die->section[mid];
if (addr == s->start)
return s;
if (left == mid || right == mid)
break;
if (addr > s->start)
left = mid;
else
right = mid;
}
err:
/* Provided address isn't in any declared section */
pr_err("%s: No section found for address %#x",
__func__, addr);
return NULL;
}
phys_addr_t pasr_section2addr(struct pasr_section *s)
{
return s->start;
}