- unsigned c;
- int type;
-
- for (c = 0; c < MAX_NUM_GPIOS; c++) {
- type = get_config(c); /* GPIO, not SFPIO */
- if (type) {
- printf("GPIO_%d:\t%s is an %s, ", c,
- get_name(c),
- get_direction(c) ? "OUTPUT" : "INPUT");
- if (get_direction(c))
- printf("value = %d", gpio_get_output_value(c));
- else
- printf("value = %d", gpio_get_value(c));
- printf("\n");
- } else
- continue;
+ struct tegra_gpio_platdata *plat = parent->platdata;
+ struct gpio_ctlr *ctlr;
+ int bank_count;
+ int bank;
+ int ret;
+
+ /* If this is a child device, there is nothing to do here */
+ if (plat)
+ return 0;
+
+ /* TODO(sjg@chromium.org): Remove once SPL supports device tree */
+#ifdef CONFIG_SPL_BUILD
+ ctlr = (struct gpio_ctlr *)NV_PA_GPIO_BASE;
+ bank_count = TEGRA_GPIO_BANKS;
+#else
+ {
+ int len;
+
+ /*
+ * This driver does not make use of interrupts, other than to figure
+ * out the number of GPIO banks
+ */
+ len = dev_read_size(parent, "interrupts");
+ if (len < 0)
+ return len;
+ bank_count = len / 3 / sizeof(u32);
+ ctlr = (struct gpio_ctlr *)dev_read_addr(parent);
+ if ((ulong)ctlr == FDT_ADDR_T_NONE)
+ return -EINVAL;
+ }
+#endif
+ for (bank = 0; bank < bank_count; bank++) {
+ int port;
+
+ for (port = 0; port < TEGRA_PORTS_PER_BANK; port++) {
+ struct tegra_gpio_platdata *plat;
+ struct udevice *dev;
+ int base_port;
+
+ plat = calloc(1, sizeof(*plat));
+ if (!plat)
+ return -ENOMEM;
+ plat->bank = &ctlr->gpio_bank[bank];
+ base_port = bank * TEGRA_PORTS_PER_BANK + port;
+ plat->base_gpio = TEGRA_GPIOS_PER_PORT * base_port;
+ plat->port_name = gpio_port_name(base_port);
+
+ ret = device_bind(parent, parent->driver,
+ plat->port_name, plat, -1, &dev);
+ if (ret)
+ return ret;
+ dev_set_of_offset(dev, dev_of_offset(parent));
+ }