+static void sm501_setup_uart_data(struct sm501_devdata *sm,
+ struct plat_serial8250_port *uart_data,
+ unsigned int offset)
+{
+ uart_data->membase = sm->regs + offset;
+ uart_data->mapbase = sm->io_res->start + offset;
+ uart_data->iotype = UPIO_MEM;
+ uart_data->irq = sm->irq;
+ uart_data->flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ;
+ uart_data->regshift = 2;
+ uart_data->uartclk = (9600 * 16);
+}
+
+static int sm501_register_uart(struct sm501_devdata *sm, int devices)
+{
+ struct platform_device *pdev;
+ struct plat_serial8250_port *uart_data;
+
+ pdev = sm501_create_subdev(sm, "serial8250", 0,
+ sizeof(struct plat_serial8250_port) * 3);
+ if (!pdev)
+ return -ENOMEM;
+
+ uart_data = pdev->dev.platform_data;
+
+ if (devices & SM501_USE_UART0) {
+ sm501_setup_uart_data(sm, uart_data++, 0x30000);
+ sm501_unit_power(sm->dev, SM501_GATE_UART0, 1);
+ sm501_modify_reg(sm->dev, SM501_IRQ_MASK, 1 << 12, 0);
+ sm501_modify_reg(sm->dev, SM501_GPIO63_32_CONTROL, 0x01e0, 0);
+ }
+ if (devices & SM501_USE_UART1) {
+ sm501_setup_uart_data(sm, uart_data++, 0x30020);
+ sm501_unit_power(sm->dev, SM501_GATE_UART1, 1);
+ sm501_modify_reg(sm->dev, SM501_IRQ_MASK, 1 << 13, 0);
+ sm501_modify_reg(sm->dev, SM501_GPIO63_32_CONTROL, 0x1e00, 0);
+ }
+
+ pdev->id = PLAT8250_DEV_SM501;
+
+ return sm501_register_device(sm, pdev);
+}
+