+
+#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
+/*
+ * Please consider existing compatible strings before adding a new
+ * one to keep this table compact. Or you may add a generic "ns16550"
+ * compatible string to your dts.
+ */
+static const struct udevice_id ns16550_serial_ids[] = {
+ { .compatible = "ns16550", .data = PORT_NS16550 },
+ { .compatible = "ns16550a", .data = PORT_NS16550 },
+ { .compatible = "ingenic,jz4780-uart", .data = PORT_JZ4780 },
+ { .compatible = "nvidia,tegra20-uart", .data = PORT_NS16550 },
+ { .compatible = "snps,dw-apb-uart", .data = PORT_NS16550 },
+ {}
+};
+#endif /* OF_CONTROL && !OF_PLATDATA */
+
+#if CONFIG_IS_ENABLED(SERIAL_PRESENT)
+
+/* TODO(sjg@chromium.org): Integrate this into a macro like CONFIG_IS_ENABLED */
+#if !defined(CONFIG_TPL_BUILD) || defined(CONFIG_TPL_DM_SERIAL)
+U_BOOT_DRIVER(ns16550_serial) = {
+ .name = "ns16550_serial",
+ .id = UCLASS_SERIAL,
+#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
+ .of_match = ns16550_serial_ids,
+ .ofdata_to_platdata = ns16550_serial_ofdata_to_platdata,
+ .platdata_auto_alloc_size = sizeof(struct ns16550_platdata),
+#endif
+ .priv_auto_alloc_size = sizeof(struct NS16550),
+ .probe = ns16550_serial_probe,
+ .ops = &ns16550_serial_ops,
+#if !CONFIG_IS_ENABLED(OF_CONTROL)
+ .flags = DM_FLAG_PRE_RELOC,
+#endif
+};
+#endif
+#endif /* SERIAL_PRESENT */
+