@@ -55,8 +55,6 @@
*/
#define DEFAULT_TIMEOUT 0
-#define MAX_UART_HWMOD_NAME_LEN 16
-
struct omap_uart_state {
int num;
int can_sleep;
@@ -96,6 +94,12 @@ struct omap_uart_state {
#endif
};
+struct uart_oh {
+ struct list_head node;
+ struct omap_hwmod *oh;
+};
+
+static LIST_HEAD(uart_oh_list);
static LIST_HEAD(uart_list);
static u8 num_uarts;
@@ -568,52 +572,37 @@ static void serial_out_override(struct uart_port *up, int offset, int value)
}
#endif
-void __init omap_serial_early_init(void)
+static int omap_serial_port_init(struct omap_hwmod *oh, void *user)
{
- int i = 0;
-
- do {
- char oh_name[MAX_UART_HWMOD_NAME_LEN];
- struct omap_hwmod *oh;
- struct omap_uart_state *uart;
-
- snprintf(oh_name, MAX_UART_HWMOD_NAME_LEN,
- "uart%d", i + 1);
- oh = omap_hwmod_lookup(oh_name);
- if (!oh)
- break;
-
- uart = kzalloc(sizeof(struct omap_uart_state), GFP_KERNEL);
- if (WARN_ON(!uart))
- return;
-
- uart->oh = oh;
- uart->num = i++;
- list_add_tail(&uart->node, &uart_list);
- num_uarts++;
-
- /*
- * NOTE: omap_hwmod_init() has not yet been called,
- * so no hwmod functions will work yet.
- */
+ struct uart_oh *uoh;
- /*
- * During UART early init, device need to be probed
- * to determine SoC specific init before omap_device
- * is ready. Therefore, don't allow idle here
- */
- uart->oh->flags |= HWMOD_INIT_NO_IDLE;
-
- /*
- * Since UART hwmod is idle/enabled inside the
- * idle loop, interrupts are already disabled and
- * thus no locking is needed. Since the mutex-based
- * locking in hwmod might sleep, allowing locking
- * may introduce problems.
- */
- uart->oh->flags |= HWMOD_NO_IDLE_LOCKING;
+ uoh = kzalloc(sizeof(struct uart_oh), GFP_KERNEL);
+ if (WARN_ON(!uoh))
+ return -ENOMEM;
+ /*
+ * During UART early init, device need to be probed
+ * to determine SoC specific init before omap_device
+ * is ready. Therefore, don't allow idle here
+ */
+ oh->flags |= HWMOD_INIT_NO_IDLE;
+ /*
+ * Since UART hwmod is idle/enabled inside the
+ * idle loop, interrupts are already disabled and
+ * thus no locking is needed. Since the mutex-based
+ * locking in hwmod might sleep, allowing locking
+ * may introduce problems.
+ */
+ oh->flags |= HWMOD_NO_IDLE_LOCKING;
+ list_add_tail(&uoh->node, &uart_oh_list);
+ uoh->oh = oh;
+ num_uarts++;
+ return 0;
+}
- } while (1);
+void __init omap_serial_early_init(void)
+{
+ omap_hwmod_for_each_by_class("uart",
+ omap_serial_port_init, NULL);
}
/**
@@ -769,7 +758,16 @@ void __init omap_serial_init_port(int port)
void __init omap_serial_init(void)
{
struct omap_uart_state *uart;
+ struct uart_oh *uoh;
+ int i = 0;
- list_for_each_entry(uart, &uart_list, node)
+ list_for_each_entry(uoh, &uart_oh_list, node) {
+ uart = kzalloc(sizeof(struct omap_uart_state), GFP_KERNEL);
+ if (WARN_ON(!uart))
+ return;
+ list_add_tail(&uart->node, &uart_list);
+ uart->num = i++;
+ uart->oh = uoh->oh;
omap_serial_init_port(uart->num);
+ }
}