|
@@ -13,6 +13,7 @@
|
|
|
#include <drivers/ofw.h>
|
|
|
#include <drivers/ofw_io.h>
|
|
|
#include <drivers/ofw_fdt.h>
|
|
|
+#include <drivers/misc.h>
|
|
|
|
|
|
#define DBG_TAG "rtdm.ofw"
|
|
|
#define DBG_LVL DBG_INFO
|
|
@@ -20,6 +21,9 @@
|
|
|
|
|
|
#include "ofw_internal.h"
|
|
|
|
|
|
+static volatile rt_atomic_t _bus_ranges_idx = 0;
|
|
|
+static struct bus_ranges *_bus_ranges[RT_USING_OFW_BUS_RANGES_NUMBER] = {};
|
|
|
+
|
|
|
static int ofw_bus_addr_cells(struct rt_ofw_node *np)
|
|
|
{
|
|
|
int res = OFW_ROOT_NODE_ADDR_CELLS_DEFAULT;
|
|
@@ -245,6 +249,7 @@ int rt_ofw_get_address_array(struct rt_ofw_node *np, int nr, rt_uint64_t *out_re
|
|
|
|
|
|
static struct bus_ranges *ofw_bus_ranges(struct rt_ofw_node *np, struct rt_ofw_prop *prop)
|
|
|
{
|
|
|
+ int id;
|
|
|
const fdt32_t *cell;
|
|
|
struct bus_ranges *ranges = RT_NULL;
|
|
|
int child_address_cells, child_size_cells, parent_address_cells, groups;
|
|
@@ -322,7 +327,12 @@ static struct bus_ranges *ofw_bus_ranges(struct rt_ofw_node *np, struct rt_ofw_p
|
|
|
*child_size++ = rt_fdt_next_cell(&cell, child_size_cells);
|
|
|
}
|
|
|
|
|
|
- rt_ofw_data(np) = ranges;
|
|
|
+ ranges->np = np;
|
|
|
+
|
|
|
+ id = (int)rt_atomic_add(&_bus_ranges_idx, 1);
|
|
|
+ RT_ASSERT(id < RT_ARRAY_SIZE(_bus_ranges));
|
|
|
+
|
|
|
+ _bus_ranges[id] = ranges;
|
|
|
} while (0);
|
|
|
|
|
|
return ranges;
|
|
@@ -341,7 +351,7 @@ rt_uint64_t rt_ofw_translate_address(struct rt_ofw_node *np, const char *range_t
|
|
|
{
|
|
|
rt_ssize_t len;
|
|
|
struct rt_ofw_prop *prop;
|
|
|
- struct bus_ranges *ranges;
|
|
|
+ struct bus_ranges *ranges = RT_NULL;
|
|
|
|
|
|
prop = rt_ofw_get_prop(np, range_type, &len);
|
|
|
|
|
@@ -350,7 +360,19 @@ rt_uint64_t rt_ofw_translate_address(struct rt_ofw_node *np, const char *range_t
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
- ranges = rt_ofw_data(np);
|
|
|
+ for (int i = 0; i < RT_ARRAY_SIZE(_bus_ranges); ++i)
|
|
|
+ {
|
|
|
+ if (!_bus_ranges[i])
|
|
|
+ {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (_bus_ranges[i]->np == np)
|
|
|
+ {
|
|
|
+ ranges = _bus_ranges[i];
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
if (!ranges)
|
|
|
{
|