#include <linux/circ_buf.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
+#include <linux/device.h>
#include <asm/io.h>
#include <asm/hardware.h>
unsigned int oldstate)
{
struct uart_pxa_port *up = (struct uart_pxa_port *)port;
- if (state) {
- /* sleep */
- CKEN &= ~up->cken;
- } else {
- /* wake */
- CKEN |= up->cken;
+ pxa_set_cken(up->cken, !state);
+ if (!state)
udelay(1);
- }
}
static void serial_pxa_release_port(struct uart_port *port)
.cons = PXA_CONSOLE,
};
-static int __init serial_pxa_init(void)
+static int serial_pxa_suspend(struct device *_dev, u32 state, u32 level)
{
- int i, ret;
+ struct uart_pxa_port *sport = dev_get_drvdata(_dev);
- ret = uart_register_driver(&serial_pxa_reg);
- if (ret)
- return ret;
+ if (sport && level == SUSPEND_DISABLE)
+ uart_suspend_port(&serial_pxa_reg, &sport->port);
+
+ return 0;
+}
+
+static int serial_pxa_resume(struct device *_dev, u32 level)
+{
+ struct uart_pxa_port *sport = dev_get_drvdata(_dev);
- for (i = 0; i < ARRAY_SIZE(serial_pxa_ports); i++)
- uart_add_one_port(&serial_pxa_reg, &serial_pxa_ports[i].port);
+ if (sport && level == RESUME_ENABLE)
+ uart_resume_port(&serial_pxa_reg, &sport->port);
+ return 0;
+}
+
+static int serial_pxa_probe(struct device *_dev)
+{
+ struct platform_device *dev = to_platform_device(_dev);
+
+ serial_pxa_ports[dev->id].port.dev = _dev;
+ uart_add_one_port(&serial_pxa_reg, &serial_pxa_ports[dev->id].port);
+ dev_set_drvdata(_dev, &serial_pxa_ports[dev->id]);
return 0;
}
-static void __exit serial_pxa_exit(void)
+static int serial_pxa_remove(struct device *_dev)
{
- int i;
+ struct uart_pxa_port *sport = dev_get_drvdata(_dev);
+
+ dev_set_drvdata(_dev, NULL);
+
+ if (sport)
+ uart_remove_one_port(&serial_pxa_reg, &sport->port);
+
+ return 0;
+}
+
+static struct device_driver serial_pxa_driver = {
+ .name = "pxa2xx-uart",
+ .bus = &platform_bus_type,
+ .probe = serial_pxa_probe,
+ .remove = serial_pxa_remove,
+
+ .suspend = serial_pxa_suspend,
+ .resume = serial_pxa_resume,
+};
+
+int __init serial_pxa_init(void)
+{
+ int ret;
- for (i = 0; i < ARRAY_SIZE(serial_pxa_ports); i++)
- uart_remove_one_port(&serial_pxa_reg, &serial_pxa_ports[i].port);
+ ret = uart_register_driver(&serial_pxa_reg);
+ if (ret != 0)
+ return ret;
+
+ ret = driver_register(&serial_pxa_driver);
+ if (ret != 0)
+ uart_unregister_driver(&serial_pxa_reg);
+
+ return ret;
+}
+
+void __exit serial_pxa_exit(void)
+{
+ driver_unregister(&serial_pxa_driver);
uart_unregister_driver(&serial_pxa_reg);
}