* kind, whether express or implied.
*/
+#undef DEBUG
+
#include <linux/platform_device.h>
#include <linux/module.h>
#include <linux/console.h>
.verify_port = ulite_verify_port
};
+/**
+ * ulite_get_port: Get the uart_port for a given port number and base addr
+ */
+static struct uart_port * ulite_get_port(int id)
+{
+ struct uart_port *port;
+
+ /* if id = -1; then scan for a free id and use that */
+ if (id < 0) {
+ for (id = 0; id < ULITE_NR_UARTS; id++)
+ if (ulite_ports[id].mapbase == 0)
+ break;
+ }
+
+ if ((id < 0) || (id >= ULITE_NR_UARTS)) {
+ printk(KERN_WARNING "uartlite: invalid id: %i\n", id);
+ return NULL;
+ }
+
+ /* The ID is valid, so get the address of the uart_port structure */
+ port = &ulite_ports[id];
+
+ /* Is the structure is already initialized? */
+ if (port->mapbase)
+ return port;
+
+ /* At this point, we've got an empty uart_port struct, initialize it */
+ spin_lock_init(&port->lock);
+ port->membase = NULL;
+ port->fifosize = 16;
+ port->regshift = 2;
+ port->iotype = UPIO_MEM;
+ port->iobase = 1; /* mark port in use */
+ port->ops = &ulite_ops;
+ port->irq = NO_IRQ;
+ port->flags = UPF_BOOT_AUTOCONF;
+ port->dev = NULL;
+ port->type = PORT_UNKNOWN;
+ port->line = id;
+
+ return port;
+}
+
/* ---------------------------------------------------------------------
* Console driver operations
*/
spin_unlock_irqrestore(&port->lock, flags);
}
+#if defined(CONFIG_OF)
+static inline u32 __init ulite_console_of_find_device(int id)
+{
+ struct device_node *np;
+ struct resource res;
+ const unsigned int *of_id;
+ int rc;
+ const struct of_device_id *matches = ulite_of_match;
+
+ while (matches->compatible[0]) {
+ for_each_compatible_node(np, NULL, matches->compatible) {
+ if (!of_match_node(matches, np))
+ continue;
+
+ of_id = of_get_property(np, "port-number", NULL);
+ if ((!of_id) || (*of_id != id))
+ continue;
+
+ rc = of_address_to_resource(np, 0, &res);
+ if (rc)
+ continue;
+
+ of_node_put(np);
+ return res.start+3;
+ }
+ matches++;
+ }
+
+ return 0;
+}
+#else /* CONFIG_OF */
+static inline u32 __init ulite_console_of_find_device(int id) { return 0; }
+#endif /* CONFIG_OF */
+
static int __init ulite_console_setup(struct console *co, char *options)
{
struct uart_port *port;
int bits = 8;
int parity = 'n';
int flow = 'n';
+ u32 base;
- if (co->index < 0 || co->index >= ULITE_NR_UARTS)
- return -EINVAL;
+ /* Find a matching uart port in the device tree */
+ base = ulite_console_of_find_device(co->index);
- port = &ulite_ports[co->index];
-
- /* Has the device been initialized yet? */
- if (!port->mapbase) {
- pr_debug("console on ttyUL%i not present\n", co->index);
+ /* Get the port structure */
+ port = ulite_get_port(co->index);
+ if (!port)
return -ENODEV;
+
+ /* was it initialized for this device? */
+ if (base) {
+ if ((port->mapbase) && (port->mapbase != base)) {
+ pr_debug(KERN_DEBUG "ulite: addr mismatch; %x != %x\n",
+ port->mapbase, base);
+ return -ENODEV; /* port used by another device; bail */
+ }
+ port->mapbase = base;
}
- /* not initialized yet? */
+ if (!port->mapbase)
+ return -ENODEV;
+
+ /* registers mapped yet? */
if (!port->membase) {
- if (ulite_request_port(port))
+ port->membase = ioremap(port->mapbase, ULITE_REGION);
+ if (!port->membase)
return -ENODEV;
}
struct uart_port *port;
int rc;
- /* if id = -1; then scan for a free id and use that */
- if (id < 0) {
- for (id = 0; id < ULITE_NR_UARTS; id++)
- if (ulite_ports[id].mapbase == 0)
- break;
- }
- if (id < 0 || id >= ULITE_NR_UARTS) {
- dev_err(dev, "%s%i too large\n", ULITE_NAME, id);
- return -EINVAL;
+ port = ulite_get_port(id);
+ if (!port) {
+ dev_err(dev, "Cannot get uart_port structure\n");
+ return -ENODEV;
}
- if ((ulite_ports[id].mapbase) && (ulite_ports[id].mapbase != base)) {
- dev_err(dev, "cannot assign to %s%i; it is already in use\n",
- ULITE_NAME, id);
- return -EBUSY;
+ /* was it initialized for this device? */
+ if ((port->mapbase) && (port->mapbase != base)) {
+ pr_debug(KERN_DEBUG "ulite: addr mismatch; %x != %x\n",
+ port->mapbase, base);
+ return -ENODEV;
}
- port = &ulite_ports[id];
-
- spin_lock_init(&port->lock);
- port->fifosize = 16;
- port->regshift = 2;
- port->iotype = UPIO_MEM;
- port->iobase = 1; /* mark port in use */
port->mapbase = base;
- port->membase = NULL;
- port->ops = &ulite_ops;
port->irq = irq;
- port->flags = UPF_BOOT_AUTOCONF;
port->dev = dev;
- port->type = PORT_UNKNOWN;
- port->line = id;
-
dev_set_drvdata(dev, port);
/* Register the port */