|
@@ -38,6 +38,8 @@
|
|
|
* the SoC). See the BOARD-SPECIFIC CUSTOMIZATION comment.
|
|
|
*/
|
|
|
|
|
|
+#define DRIVER_NAME "omap_rtc"
|
|
|
+
|
|
|
#define OMAP_RTC_BASE 0xfffb4800
|
|
|
|
|
|
/* RTC registers */
|
|
@@ -64,6 +66,9 @@
|
|
|
#define OMAP_RTC_COMP_MSB_REG 0x50
|
|
|
#define OMAP_RTC_OSC_REG 0x54
|
|
|
|
|
|
+#define OMAP_RTC_KICK0_REG 0x6c
|
|
|
+#define OMAP_RTC_KICK1_REG 0x70
|
|
|
+
|
|
|
/* OMAP_RTC_CTRL_REG bit fields: */
|
|
|
#define OMAP_RTC_CTRL_SPLIT (1<<7)
|
|
|
#define OMAP_RTC_CTRL_DISABLE (1<<6)
|
|
@@ -88,10 +93,18 @@
|
|
|
#define OMAP_RTC_INTERRUPTS_IT_ALARM (1<<3)
|
|
|
#define OMAP_RTC_INTERRUPTS_IT_TIMER (1<<2)
|
|
|
|
|
|
+/* OMAP_RTC_KICKER values */
|
|
|
+#define KICK0_VALUE 0x83e70b13
|
|
|
+#define KICK1_VALUE 0x95a4f1e0
|
|
|
+
|
|
|
+#define OMAP_RTC_HAS_KICKER 0x1
|
|
|
+
|
|
|
static void __iomem *rtc_base;
|
|
|
|
|
|
-#define rtc_read(addr) __raw_readb(rtc_base + (addr))
|
|
|
-#define rtc_write(val, addr) __raw_writeb(val, rtc_base + (addr))
|
|
|
+#define rtc_read(addr) readb(rtc_base + (addr))
|
|
|
+#define rtc_write(val, addr) writeb(val, rtc_base + (addr))
|
|
|
+
|
|
|
+#define rtc_writel(val, addr) writel(val, rtc_base + (addr))
|
|
|
|
|
|
|
|
|
/* we rely on the rtc framework to handle locking (rtc->ops_lock),
|
|
@@ -285,11 +298,23 @@ static struct rtc_class_ops omap_rtc_ops = {
|
|
|
static int omap_rtc_alarm;
|
|
|
static int omap_rtc_timer;
|
|
|
|
|
|
+static struct platform_device_id omap_rtc_devtype[] = {
|
|
|
+ {
|
|
|
+ .name = DRIVER_NAME,
|
|
|
+ }, {
|
|
|
+ .name = "da830-rtc",
|
|
|
+ .driver_data = OMAP_RTC_HAS_KICKER,
|
|
|
+ },
|
|
|
+ {},
|
|
|
+};
|
|
|
+MODULE_DEVICE_TABLE(platform, omap_rtc_devtype);
|
|
|
+
|
|
|
static int __init omap_rtc_probe(struct platform_device *pdev)
|
|
|
{
|
|
|
struct resource *res, *mem;
|
|
|
struct rtc_device *rtc;
|
|
|
u8 reg, new_ctrl;
|
|
|
+ const struct platform_device_id *id_entry;
|
|
|
|
|
|
omap_rtc_timer = platform_get_irq(pdev, 0);
|
|
|
if (omap_rtc_timer <= 0) {
|
|
@@ -322,6 +347,12 @@ static int __init omap_rtc_probe(struct platform_device *pdev)
|
|
|
goto fail;
|
|
|
}
|
|
|
|
|
|
+ id_entry = platform_get_device_id(pdev);
|
|
|
+ if (id_entry && (id_entry->driver_data & OMAP_RTC_HAS_KICKER)) {
|
|
|
+ rtc_writel(KICK0_VALUE, OMAP_RTC_KICK0_REG);
|
|
|
+ rtc_writel(KICK1_VALUE, OMAP_RTC_KICK1_REG);
|
|
|
+ }
|
|
|
+
|
|
|
rtc = rtc_device_register(pdev->name, &pdev->dev,
|
|
|
&omap_rtc_ops, THIS_MODULE);
|
|
|
if (IS_ERR(rtc)) {
|
|
@@ -398,6 +429,8 @@ fail2:
|
|
|
fail1:
|
|
|
rtc_device_unregister(rtc);
|
|
|
fail0:
|
|
|
+ if (id_entry && (id_entry->driver_data & OMAP_RTC_HAS_KICKER))
|
|
|
+ rtc_writel(0, OMAP_RTC_KICK0_REG);
|
|
|
iounmap(rtc_base);
|
|
|
fail:
|
|
|
release_mem_region(mem->start, resource_size(mem));
|
|
@@ -408,6 +441,8 @@ static int __exit omap_rtc_remove(struct platform_device *pdev)
|
|
|
{
|
|
|
struct rtc_device *rtc = platform_get_drvdata(pdev);
|
|
|
struct resource *mem = dev_get_drvdata(&rtc->dev);
|
|
|
+ const struct platform_device_id *id_entry =
|
|
|
+ platform_get_device_id(pdev);
|
|
|
|
|
|
device_init_wakeup(&pdev->dev, 0);
|
|
|
|
|
@@ -420,6 +455,8 @@ static int __exit omap_rtc_remove(struct platform_device *pdev)
|
|
|
free_irq(omap_rtc_alarm, rtc);
|
|
|
|
|
|
rtc_device_unregister(rtc);
|
|
|
+ if (id_entry && (id_entry->driver_data & OMAP_RTC_HAS_KICKER))
|
|
|
+ rtc_writel(0, OMAP_RTC_KICK0_REG);
|
|
|
iounmap(rtc_base);
|
|
|
release_mem_region(mem->start, resource_size(mem));
|
|
|
return 0;
|
|
@@ -471,9 +508,10 @@ static struct platform_driver omap_rtc_driver = {
|
|
|
.resume = omap_rtc_resume,
|
|
|
.shutdown = omap_rtc_shutdown,
|
|
|
.driver = {
|
|
|
- .name = "omap_rtc",
|
|
|
+ .name = DRIVER_NAME,
|
|
|
.owner = THIS_MODULE,
|
|
|
},
|
|
|
+ .id_table = omap_rtc_devtype,
|
|
|
};
|
|
|
|
|
|
static int __init rtc_init(void)
|