Commit 2153f949 authored by Johan Hovold's avatar Johan Hovold Committed by Linus Torvalds

rtc: omap: add structured device-type info

Add structured device-type info to encode IP-block revision differences.
Signed-off-by: default avatarJohan Hovold <johan@kernel.org>
Cc: Alessandro Zummo <a.zummo@towertech.it>
Cc: Tony Lindgren <tony@atomide.com>
Cc: Benot Cousson <bcousson@baylibre.com>
Cc: Lokesh Vutla <lokeshvutla@ti.com>
Cc: Guenter Roeck <linux@roeck-us.net>
Cc: Sekhar Nori <nsekhar@ti.com>
Cc: Tero Kristo <t-kristo@ti.com>
Cc: Keerthy J <j-keerthy@ti.com>
Tested-by: default avatarFelipe Balbi <balbi@ti.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent a430ca22
...@@ -102,19 +102,11 @@ ...@@ -102,19 +102,11 @@
#define KICK0_VALUE 0x83e70b13 #define KICK0_VALUE 0x83e70b13
#define KICK1_VALUE 0x95a4f1e0 #define KICK1_VALUE 0x95a4f1e0
#define OMAP_RTC_HAS_KICKER BIT(0) struct omap_rtc_device_type {
bool has_32kclk_en;
/* bool has_kicker;
* Few RTC IP revisions has special WAKE-EN Register to enable Wakeup bool has_irqwakeen;
* generation for event Alarm. };
*/
#define OMAP_RTC_HAS_IRQWAKEEN BIT(1)
/*
* Some RTC IP revisions (like those in AM335x and DRA7x) need
* the 32KHz clock to be explicitly enabled.
*/
#define OMAP_RTC_HAS_32KCLK_EN BIT(2)
struct omap_rtc { struct omap_rtc {
struct rtc_device *rtc; struct rtc_device *rtc;
...@@ -122,7 +114,7 @@ struct omap_rtc { ...@@ -122,7 +114,7 @@ struct omap_rtc {
int irq_alarm; int irq_alarm;
int irq_timer; int irq_timer;
u8 interrupts_reg; u8 interrupts_reg;
unsigned long flags; const struct omap_rtc_device_type *type;
}; };
static inline u8 rtc_read(struct omap_rtc *rtc, unsigned int reg) static inline u8 rtc_read(struct omap_rtc *rtc, unsigned int reg)
...@@ -190,7 +182,7 @@ static int omap_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) ...@@ -190,7 +182,7 @@ static int omap_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
local_irq_disable(); local_irq_disable();
rtc_wait_not_busy(rtc); rtc_wait_not_busy(rtc);
reg = rtc_read(rtc, OMAP_RTC_INTERRUPTS_REG); reg = rtc_read(rtc, OMAP_RTC_INTERRUPTS_REG);
if (rtc->flags & OMAP_RTC_HAS_IRQWAKEEN) if (rtc->type->has_irqwakeen)
irqwake_reg = rtc_read(rtc, OMAP_RTC_IRQWAKEEN); irqwake_reg = rtc_read(rtc, OMAP_RTC_IRQWAKEEN);
if (enabled) { if (enabled) {
...@@ -202,7 +194,7 @@ static int omap_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) ...@@ -202,7 +194,7 @@ static int omap_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
} }
rtc_wait_not_busy(rtc); rtc_wait_not_busy(rtc);
rtc_write(rtc, OMAP_RTC_INTERRUPTS_REG, reg); rtc_write(rtc, OMAP_RTC_INTERRUPTS_REG, reg);
if (rtc->flags & OMAP_RTC_HAS_IRQWAKEEN) if (rtc->type->has_irqwakeen)
rtc_write(rtc, OMAP_RTC_IRQWAKEEN, irqwake_reg); rtc_write(rtc, OMAP_RTC_IRQWAKEEN, irqwake_reg);
local_irq_enable(); local_irq_enable();
...@@ -326,7 +318,7 @@ static int omap_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) ...@@ -326,7 +318,7 @@ static int omap_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
rtc_write(rtc, OMAP_RTC_ALARM_SECONDS_REG, alm->time.tm_sec); rtc_write(rtc, OMAP_RTC_ALARM_SECONDS_REG, alm->time.tm_sec);
reg = rtc_read(rtc, OMAP_RTC_INTERRUPTS_REG); reg = rtc_read(rtc, OMAP_RTC_INTERRUPTS_REG);
if (rtc->flags & OMAP_RTC_HAS_IRQWAKEEN) if (rtc->type->has_irqwakeen)
irqwake_reg = rtc_read(rtc, OMAP_RTC_IRQWAKEEN); irqwake_reg = rtc_read(rtc, OMAP_RTC_IRQWAKEEN);
if (alm->enabled) { if (alm->enabled) {
...@@ -337,7 +329,7 @@ static int omap_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) ...@@ -337,7 +329,7 @@ static int omap_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
irqwake_reg &= ~OMAP_RTC_IRQWAKEEN_ALARM_WAKEEN; irqwake_reg &= ~OMAP_RTC_IRQWAKEEN_ALARM_WAKEEN;
} }
rtc_write(rtc, OMAP_RTC_INTERRUPTS_REG, reg); rtc_write(rtc, OMAP_RTC_INTERRUPTS_REG, reg);
if (rtc->flags & OMAP_RTC_HAS_IRQWAKEEN) if (rtc->type->has_irqwakeen)
rtc_write(rtc, OMAP_RTC_IRQWAKEEN, irqwake_reg); rtc_write(rtc, OMAP_RTC_IRQWAKEEN, irqwake_reg);
local_irq_enable(); local_irq_enable();
...@@ -353,34 +345,45 @@ static struct rtc_class_ops omap_rtc_ops = { ...@@ -353,34 +345,45 @@ static struct rtc_class_ops omap_rtc_ops = {
.alarm_irq_enable = omap_rtc_alarm_irq_enable, .alarm_irq_enable = omap_rtc_alarm_irq_enable,
}; };
#define OMAP_RTC_DATA_AM3352_IDX 1 static const struct omap_rtc_device_type omap_rtc_default_type = {
#define OMAP_RTC_DATA_DA830_IDX 2 };
static const struct omap_rtc_device_type omap_rtc_am3352_type = {
.has_32kclk_en = true,
.has_kicker = true,
.has_irqwakeen = true,
};
static const struct omap_rtc_device_type omap_rtc_da830_type = {
.has_kicker = true,
};
static const struct platform_device_id omap_rtc_devtype[] = { static const struct platform_device_id omap_rtc_id_table[] = {
{ {
.name = "omap_rtc", .name = "omap_rtc",
}, .driver_data = (kernel_ulong_t)&omap_rtc_default_type,
[OMAP_RTC_DATA_AM3352_IDX] = { }, {
.name = "am3352-rtc", .name = "am3352-rtc",
.driver_data = OMAP_RTC_HAS_KICKER | OMAP_RTC_HAS_IRQWAKEEN | .driver_data = (kernel_ulong_t)&omap_rtc_am3352_type,
OMAP_RTC_HAS_32KCLK_EN, }, {
},
[OMAP_RTC_DATA_DA830_IDX] = {
.name = "da830-rtc", .name = "da830-rtc",
.driver_data = OMAP_RTC_HAS_KICKER, .driver_data = (kernel_ulong_t)&omap_rtc_da830_type,
}, }, {
{}, /* sentinel */
}
}; };
MODULE_DEVICE_TABLE(platform, omap_rtc_devtype); MODULE_DEVICE_TABLE(platform, omap_rtc_id_table);
static const struct of_device_id omap_rtc_of_match[] = { static const struct of_device_id omap_rtc_of_match[] = {
{ .compatible = "ti,da830-rtc", {
.data = &omap_rtc_devtype[OMAP_RTC_DATA_DA830_IDX], .compatible = "ti,am3352-rtc",
}, .data = &omap_rtc_am3352_type,
{ .compatible = "ti,am3352-rtc", }, {
.data = &omap_rtc_devtype[OMAP_RTC_DATA_AM3352_IDX], .compatible = "ti,da830-rtc",
}, .data = &omap_rtc_da830_type,
{}, }, {
/* sentinel */
}
}; };
MODULE_DEVICE_TABLE(of, omap_rtc_of_match); MODULE_DEVICE_TABLE(of, omap_rtc_of_match);
...@@ -398,17 +401,13 @@ static int __init omap_rtc_probe(struct platform_device *pdev) ...@@ -398,17 +401,13 @@ static int __init omap_rtc_probe(struct platform_device *pdev)
return -ENOMEM; return -ENOMEM;
of_id = of_match_device(omap_rtc_of_match, &pdev->dev); of_id = of_match_device(omap_rtc_of_match, &pdev->dev);
if (of_id) if (of_id) {
pdev->id_entry = of_id->data; rtc->type = of_id->data;
} else {
id_entry = platform_get_device_id(pdev); id_entry = platform_get_device_id(pdev);
if (!id_entry) { rtc->type = (void *)id_entry->driver_data;
dev_err(&pdev->dev, "no matching device entry\n");
return -ENODEV;
} }
rtc->flags = id_entry->driver_data;
rtc->irq_timer = platform_get_irq(pdev, 0); rtc->irq_timer = platform_get_irq(pdev, 0);
if (rtc->irq_timer <= 0) if (rtc->irq_timer <= 0)
return -ENOENT; return -ENOENT;
...@@ -428,7 +427,7 @@ static int __init omap_rtc_probe(struct platform_device *pdev) ...@@ -428,7 +427,7 @@ static int __init omap_rtc_probe(struct platform_device *pdev)
pm_runtime_enable(&pdev->dev); pm_runtime_enable(&pdev->dev);
pm_runtime_get_sync(&pdev->dev); pm_runtime_get_sync(&pdev->dev);
if (rtc->flags & OMAP_RTC_HAS_KICKER) { if (rtc->type->has_kicker) {
rtc_writel(rtc, OMAP_RTC_KICK0_REG, KICK0_VALUE); rtc_writel(rtc, OMAP_RTC_KICK0_REG, KICK0_VALUE);
rtc_writel(rtc, OMAP_RTC_KICK1_REG, KICK1_VALUE); rtc_writel(rtc, OMAP_RTC_KICK1_REG, KICK1_VALUE);
} }
...@@ -441,7 +440,7 @@ static int __init omap_rtc_probe(struct platform_device *pdev) ...@@ -441,7 +440,7 @@ static int __init omap_rtc_probe(struct platform_device *pdev)
rtc_writel(rtc, OMAP_RTC_INTERRUPTS_REG, 0); rtc_writel(rtc, OMAP_RTC_INTERRUPTS_REG, 0);
/* enable RTC functional clock */ /* enable RTC functional clock */
if (rtc->flags & OMAP_RTC_HAS_32KCLK_EN) { if (rtc->type->has_32kclk_en) {
reg = rtc_read(rtc, OMAP_RTC_OSC_REG); reg = rtc_read(rtc, OMAP_RTC_OSC_REG);
rtc_writel(rtc, OMAP_RTC_OSC_REG, rtc_writel(rtc, OMAP_RTC_OSC_REG,
reg | OMAP_RTC_OSC_32KCLK_EN); reg | OMAP_RTC_OSC_32KCLK_EN);
...@@ -511,7 +510,7 @@ static int __init omap_rtc_probe(struct platform_device *pdev) ...@@ -511,7 +510,7 @@ static int __init omap_rtc_probe(struct platform_device *pdev)
err: err:
device_init_wakeup(&pdev->dev, false); device_init_wakeup(&pdev->dev, false);
if (rtc->flags & OMAP_RTC_HAS_KICKER) if (rtc->type->has_kicker)
rtc_writel(rtc, OMAP_RTC_KICK0_REG, 0); rtc_writel(rtc, OMAP_RTC_KICK0_REG, 0);
pm_runtime_put_sync(&pdev->dev); pm_runtime_put_sync(&pdev->dev);
pm_runtime_disable(&pdev->dev); pm_runtime_disable(&pdev->dev);
...@@ -528,7 +527,7 @@ static int __exit omap_rtc_remove(struct platform_device *pdev) ...@@ -528,7 +527,7 @@ static int __exit omap_rtc_remove(struct platform_device *pdev)
/* leave rtc running, but disable irqs */ /* leave rtc running, but disable irqs */
rtc_write(rtc, OMAP_RTC_INTERRUPTS_REG, 0); rtc_write(rtc, OMAP_RTC_INTERRUPTS_REG, 0);
if (rtc->flags & OMAP_RTC_HAS_KICKER) if (rtc->type->has_kicker)
rtc_writel(rtc, OMAP_RTC_KICK0_REG, 0); rtc_writel(rtc, OMAP_RTC_KICK0_REG, 0);
/* Disable the clock/module */ /* Disable the clock/module */
...@@ -594,7 +593,7 @@ static struct platform_driver omap_rtc_driver = { ...@@ -594,7 +593,7 @@ static struct platform_driver omap_rtc_driver = {
.pm = &omap_rtc_pm_ops, .pm = &omap_rtc_pm_ops,
.of_match_table = omap_rtc_of_match, .of_match_table = omap_rtc_of_match,
}, },
.id_table = omap_rtc_devtype, .id_table = omap_rtc_id_table,
}; };
module_platform_driver_probe(omap_rtc_driver, omap_rtc_probe); module_platform_driver_probe(omap_rtc_driver, omap_rtc_probe);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment