Add support "interrupts-extended".
* fdtbus_get_phandle_with_data(). Add utility subroutine to get phandle with data.
This commit is contained in:
parent
61bd4906ee
commit
c62fc3ec68
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: fdt_intr.c,v 1.21 2019/02/27 17:01:57 jakllsch Exp $ */
|
/* $NetBSD: fdt_intr.c,v 1.22 2019/06/14 11:08:18 hkenken Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 2015-2018 Jared McNeill <jmcneill@invisible.ca>
|
* Copyright (c) 2015-2018 Jared McNeill <jmcneill@invisible.ca>
|
||||||
|
@ -27,7 +27,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__KERNEL_RCSID(0, "$NetBSD: fdt_intr.c,v 1.21 2019/02/27 17:01:57 jakllsch Exp $");
|
__KERNEL_RCSID(0, "$NetBSD: fdt_intr.c,v 1.22 2019/06/14 11:08:18 hkenken Exp $");
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/bus.h>
|
#include <sys/bus.h>
|
||||||
|
@ -322,12 +322,31 @@ done:
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static const u_int *
|
||||||
|
get_specifier_from_extended(int phandle, int pindex, int *piphandle)
|
||||||
|
{
|
||||||
|
const u_int *result = NULL;
|
||||||
|
struct fdt_phandle_data data;
|
||||||
|
|
||||||
|
if (fdtbus_get_phandle_with_data(phandle, "interrupts-extended",
|
||||||
|
"#interrupt-cells", pindex, &data) == 0) {
|
||||||
|
*piphandle = data.phandle;
|
||||||
|
result = data.values;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
static const u_int *
|
static const u_int *
|
||||||
get_specifier_by_index(int phandle, int pindex, int *piphandle)
|
get_specifier_by_index(int phandle, int pindex, int *piphandle)
|
||||||
{
|
{
|
||||||
const u_int *node_specifier;
|
const u_int *node_specifier;
|
||||||
int interrupt_parent, interrupt_cells, len;
|
int interrupt_parent, interrupt_cells, len;
|
||||||
|
|
||||||
|
if (of_hasprop(phandle, "interrupts-extended"))
|
||||||
|
return get_specifier_from_extended(phandle, pindex, piphandle);
|
||||||
|
|
||||||
interrupt_parent = fdtbus_get_interrupt_parent(phandle);
|
interrupt_parent = fdtbus_get_interrupt_parent(phandle);
|
||||||
if (interrupt_parent <= 0)
|
if (interrupt_parent <= 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: fdt_subr.c,v 1.29 2019/02/27 16:56:00 jakllsch Exp $ */
|
/* $NetBSD: fdt_subr.c,v 1.30 2019/06/14 11:08:18 hkenken Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 2015 Jared D. McNeill <jmcneill@invisible.ca>
|
* Copyright (c) 2015 Jared D. McNeill <jmcneill@invisible.ca>
|
||||||
|
@ -27,7 +27,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__KERNEL_RCSID(0, "$NetBSD: fdt_subr.c,v 1.29 2019/02/27 16:56:00 jakllsch Exp $");
|
__KERNEL_RCSID(0, "$NetBSD: fdt_subr.c,v 1.30 2019/06/14 11:08:18 hkenken Exp $");
|
||||||
|
|
||||||
#include "opt_fdt.h"
|
#include "opt_fdt.h"
|
||||||
|
|
||||||
|
@ -129,6 +129,42 @@ fdtbus_get_phandle(int phandle, const char *prop)
|
||||||
return fdtbus_get_phandle_from_native(phandle_ref);
|
return fdtbus_get_phandle_from_native(phandle_ref);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
fdtbus_get_phandle_with_data(int phandle, const char *prop, const char *cells,
|
||||||
|
int index, struct fdt_phandle_data *data)
|
||||||
|
{
|
||||||
|
int len;
|
||||||
|
const int offset = 1;
|
||||||
|
|
||||||
|
const u_int *p = fdtbus_get_prop(phandle, prop, &len);
|
||||||
|
if (p == NULL || len <= 0)
|
||||||
|
return EINVAL;
|
||||||
|
|
||||||
|
for (int i = 0; len > 0; i++) {
|
||||||
|
u_int phandle_ref = be32toh(*p);
|
||||||
|
const u_int iparent = fdtbus_get_phandle_from_native(phandle_ref);
|
||||||
|
uint32_t cells_num;
|
||||||
|
of_getprop_uint32(iparent, cells, &cells_num);
|
||||||
|
|
||||||
|
if (index == i) {
|
||||||
|
if (data != NULL) {
|
||||||
|
data->phandle = iparent;
|
||||||
|
data->count = cells_num;
|
||||||
|
data->values = p + offset;
|
||||||
|
}
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
const u_int reclen = offset + cells_num;
|
||||||
|
len -= reclen * sizeof(u_int);
|
||||||
|
p += reclen;
|
||||||
|
}
|
||||||
|
return EINVAL;
|
||||||
|
|
||||||
|
done:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
fdtbus_get_phandle_from_native(int phandle)
|
fdtbus_get_phandle_from_native(int phandle)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: fdtvar.h,v 1.51 2019/05/08 13:40:18 isaki Exp $ */
|
/* $NetBSD: fdtvar.h,v 1.52 2019/06/14 11:08:18 hkenken Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 2015 Jared D. McNeill <jmcneill@invisible.ca>
|
* Copyright (c) 2015 Jared D. McNeill <jmcneill@invisible.ca>
|
||||||
|
@ -232,6 +232,12 @@ struct fdt_console_info {
|
||||||
const struct fdt_console *ops;
|
const struct fdt_console *ops;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct fdt_phandle_data {
|
||||||
|
int phandle;
|
||||||
|
int count;
|
||||||
|
const u_int *values;
|
||||||
|
};
|
||||||
|
|
||||||
#define _FDT_CONSOLE_REGISTER(name) \
|
#define _FDT_CONSOLE_REGISTER(name) \
|
||||||
__link_set_add_rodata(fdt_consoles, __CONCAT(name,_consinfo));
|
__link_set_add_rodata(fdt_consoles, __CONCAT(name,_consinfo));
|
||||||
|
|
||||||
|
@ -278,6 +284,8 @@ int fdtbus_get_reg_byname(int, const char *, bus_addr_t *,
|
||||||
bus_size_t *);
|
bus_size_t *);
|
||||||
int fdtbus_get_reg64(int, u_int, uint64_t *, uint64_t *);
|
int fdtbus_get_reg64(int, u_int, uint64_t *, uint64_t *);
|
||||||
int fdtbus_get_phandle(int, const char *);
|
int fdtbus_get_phandle(int, const char *);
|
||||||
|
int fdtbus_get_phandle_with_data(int, const char *, const char *,
|
||||||
|
int, struct fdt_phandle_data *);
|
||||||
int fdtbus_get_phandle_from_native(int);
|
int fdtbus_get_phandle_from_native(int);
|
||||||
i2c_tag_t fdtbus_get_i2c_tag(int);
|
i2c_tag_t fdtbus_get_i2c_tag(int);
|
||||||
i2c_tag_t fdtbus_i2c_acquire(int, const char *);
|
i2c_tag_t fdtbus_i2c_acquire(int, const char *);
|
||||||
|
|
Loading…
Reference in New Issue