summaryrefslogtreecommitdiffstats
path: root/src/dtblint.c
blob: ed9f0b292315f94506f052c846f8c81c57080b48 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
/*
 * Copyright (C) 2016 Pengutronix, Uwe Kleine-König <kernel@pengutronix.de>
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License version 2 as published by the
 * Free Software Foundation.
 */
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>

#include <dt/dt.h>

#include "dtblint.h"

static const char * const fsl_fec_compatibles[] = {
	"fsl,imx25-fec",
	"fsl,imx27-fec",
	"fsl,imx28-fec",
	"fsl,imx6q-fec",
	"fsl,imx6sx-fec",
	"fsl,mvf600-fec",
};

static void fsl_fec_reset_polarity(void)
{
	size_t i;
	/*
	 * For historical reasons the gpio flag in the phy-reset-gpios property
	 * isn't evaluated and the gpio is assumed to be active low. Inversion
	 * can be accomplished by adding the property phy-reset-active-high.
	 * The gpio flag should match the presence of this property.
	 */
	struct device_node *np;
	int ret;

	for (i = 0; i < ARRAY_SIZE(fsl_fec_compatibles); ++i) {
		for_each_compatible_node(np, NULL, fsl_fec_compatibles[i]) {
			struct of_phandle_args out_args[MAX_PHANDLE_ARGS];

			bool active_high_property =
				of_property_read_bool(np,
						      "phy-reset-active-high");
			bool active_high_gpio_flag;

			ret = of_parse_phandle_with_args(np, "phy-reset-gpios",
							 "#gpio-cells", 0,
							 out_args);
			if (ret < 0)
				continue;

			if (out_args->args_count < 2)
				continue;

			active_high_gpio_flag = out_args->args[1] == 0;

			if (active_high_gpio_flag != active_high_property) {
				printf("E: phy-reset-gpios flags don't match presence of phy-reset-active-high property (%s)\n",
				       np->full_name);
			}
		}
	}
}

static const char * const fsl_pcie_compatibles[] = {
        "fsl,imx6q-pcie",
        "fsl,imx6sx-pcie",
        "fsl,imx6qp-pcie",
        "fsl,imx7d-pcie",
};

static void fsl_pcie_reset_polarity(void)
{
	size_t i;
	/*
	 * For historical reasons the gpio flag in the reset-gpio property
	 * isn't evaluated and the gpio is assumed to be active low. Inversion
	 * can be accomplished by adding the property reset-gpio-active-high.
	 * The gpio flag should match the presence of this property.
	 */
	struct device_node *np;
	int ret;

	for (i = 0; i < ARRAY_SIZE(fsl_pcie_compatibles); ++i) {
		for_each_compatible_node(np, NULL, fsl_pcie_compatibles[i]) {
			struct of_phandle_args out_args[MAX_PHANDLE_ARGS];

			bool active_high_property =
				of_property_read_bool(np,
						      "reset-gpio-active-high");
			bool active_high_gpio_flag;

			ret = of_parse_phandle_with_args(np, "reset-gpio",
							 "#gpio-cells", 0,
							 out_args);
			if (ret < 0)
				continue;

			if (out_args->args_count < 2)
				continue;

			active_high_gpio_flag = out_args->args[1] == 0;

			if (active_high_gpio_flag != active_high_property) {
				printf("E: reset-gpios flags don't match presence of reset-gpio-active-high property (%s)\n",
				       np->full_name);
			}
		}
	}
}

int main(int argc, const char *argv[])
{
	void *fdt;
	struct device_node *root;

	if (argc < 2) {
		fprintf(stderr, "No filename given\n");
		return EXIT_FAILURE;
	}

	fdt = read_file(argv[1], NULL);
	if (!fdt) {
		fprintf(stderr, "failed to read dtb\n");
		return EXIT_FAILURE;
	}

	root = of_unflatten_dtb(fdt);
	free(fdt);
	if (IS_ERR(root)) {
		fprintf(stderr, "failed to unflatten device tree (%ld)\n",
			PTR_ERR(root));
		return EXIT_FAILURE;
	}
	of_set_root_node(root);

	dtblint_imx_pinmux();
	fsl_fec_reset_polarity();
	fsl_pcie_reset_polarity();
}