2019-05-27 09:55:05 +03:00
// SPDX-License-Identifier: GPL-2.0-or-later
2009-11-05 17:51:34 +03:00
/*
* DaVinci Power Management and Real Time Clock Driver for TI platforms
*
* Copyright ( C ) 2009 Texas Instruments , Inc
*
* Author : Miguel Aguilar < miguel . aguilar @ ridgerun . com >
*/
# include <linux/kernel.h>
# include <linux/init.h>
# include <linux/module.h>
# include <linux/ioport.h>
# include <linux/delay.h>
# include <linux/spinlock.h>
# include <linux/rtc.h>
# include <linux/bcd.h>
# include <linux/platform_device.h>
# include <linux/io.h>
2010-03-29 21:52:36 +04:00
# include <linux/slab.h>
2009-11-05 17:51:34 +03:00
/*
* The DaVinci RTC is a simple RTC with the following
* Sec : 0 - 59 : BCD count
* Min : 0 - 59 : BCD count
* Hour : 0 - 23 : BCD count
* Day : 0 - 0x7FFF ( 32767 ) : Binary count ( Over 89 years )
*/
/* PRTC interface registers */
# define DAVINCI_PRTCIF_PID 0x00
# define PRTCIF_CTLR 0x04
# define PRTCIF_LDATA 0x08
# define PRTCIF_UDATA 0x0C
# define PRTCIF_INTEN 0x10
# define PRTCIF_INTFLG 0x14
/* PRTCIF_CTLR bit fields */
# define PRTCIF_CTLR_BUSY BIT(31)
# define PRTCIF_CTLR_SIZE BIT(25)
# define PRTCIF_CTLR_DIR BIT(24)
# define PRTCIF_CTLR_BENU_MSB BIT(23)
# define PRTCIF_CTLR_BENU_3RD_BYTE BIT(22)
# define PRTCIF_CTLR_BENU_2ND_BYTE BIT(21)
# define PRTCIF_CTLR_BENU_LSB BIT(20)
# define PRTCIF_CTLR_BENU_MASK (0x00F00000)
# define PRTCIF_CTLR_BENL_MSB BIT(19)
# define PRTCIF_CTLR_BENL_3RD_BYTE BIT(18)
# define PRTCIF_CTLR_BENL_2ND_BYTE BIT(17)
# define PRTCIF_CTLR_BENL_LSB BIT(16)
# define PRTCIF_CTLR_BENL_MASK (0x000F0000)
/* PRTCIF_INTEN bit fields */
# define PRTCIF_INTEN_RTCSS BIT(1)
# define PRTCIF_INTEN_RTCIF BIT(0)
# define PRTCIF_INTEN_MASK (PRTCIF_INTEN_RTCSS \
| PRTCIF_INTEN_RTCIF )
/* PRTCIF_INTFLG bit fields */
# define PRTCIF_INTFLG_RTCSS BIT(1)
# define PRTCIF_INTFLG_RTCIF BIT(0)
# define PRTCIF_INTFLG_MASK (PRTCIF_INTFLG_RTCSS \
| PRTCIF_INTFLG_RTCIF )
/* PRTC subsystem registers */
# define PRTCSS_RTC_INTC_EXTENA1 (0x0C)
# define PRTCSS_RTC_CTRL (0x10)
# define PRTCSS_RTC_WDT (0x11)
# define PRTCSS_RTC_TMR0 (0x12)
# define PRTCSS_RTC_TMR1 (0x13)
# define PRTCSS_RTC_CCTRL (0x14)
# define PRTCSS_RTC_SEC (0x15)
# define PRTCSS_RTC_MIN (0x16)
# define PRTCSS_RTC_HOUR (0x17)
# define PRTCSS_RTC_DAY0 (0x18)
# define PRTCSS_RTC_DAY1 (0x19)
# define PRTCSS_RTC_AMIN (0x1A)
# define PRTCSS_RTC_AHOUR (0x1B)
# define PRTCSS_RTC_ADAY0 (0x1C)
# define PRTCSS_RTC_ADAY1 (0x1D)
# define PRTCSS_RTC_CLKC_CNT (0x20)
/* PRTCSS_RTC_INTC_EXTENA1 */
# define PRTCSS_RTC_INTC_EXTENA1_MASK (0x07)
/* PRTCSS_RTC_CTRL bit fields */
# define PRTCSS_RTC_CTRL_WDTBUS BIT(7)
# define PRTCSS_RTC_CTRL_WEN BIT(6)
# define PRTCSS_RTC_CTRL_WDRT BIT(5)
# define PRTCSS_RTC_CTRL_WDTFLG BIT(4)
# define PRTCSS_RTC_CTRL_TE BIT(3)
# define PRTCSS_RTC_CTRL_TIEN BIT(2)
# define PRTCSS_RTC_CTRL_TMRFLG BIT(1)
# define PRTCSS_RTC_CTRL_TMMD BIT(0)
/* PRTCSS_RTC_CCTRL bit fields */
# define PRTCSS_RTC_CCTRL_CALBUSY BIT(7)
# define PRTCSS_RTC_CCTRL_DAEN BIT(5)
# define PRTCSS_RTC_CCTRL_HAEN BIT(4)
# define PRTCSS_RTC_CCTRL_MAEN BIT(3)
# define PRTCSS_RTC_CCTRL_ALMFLG BIT(2)
# define PRTCSS_RTC_CCTRL_AIEN BIT(1)
# define PRTCSS_RTC_CCTRL_CAEN BIT(0)
static DEFINE_SPINLOCK ( davinci_rtc_lock ) ;
struct davinci_rtc {
2013-07-04 02:05:46 +04:00
struct rtc_device * rtc ;
2009-11-05 17:51:34 +03:00
void __iomem * base ;
int irq ;
} ;
static inline void rtcif_write ( struct davinci_rtc * davinci_rtc ,
u32 val , u32 addr )
{
writel ( val , davinci_rtc - > base + addr ) ;
}
static inline u32 rtcif_read ( struct davinci_rtc * davinci_rtc , u32 addr )
{
return readl ( davinci_rtc - > base + addr ) ;
}
static inline void rtcif_wait ( struct davinci_rtc * davinci_rtc )
{
while ( rtcif_read ( davinci_rtc , PRTCIF_CTLR ) & PRTCIF_CTLR_BUSY )
cpu_relax ( ) ;
}
static inline void rtcss_write ( struct davinci_rtc * davinci_rtc ,
unsigned long val , u8 addr )
{
rtcif_wait ( davinci_rtc ) ;
rtcif_write ( davinci_rtc , PRTCIF_CTLR_BENL_LSB | addr , PRTCIF_CTLR ) ;
rtcif_write ( davinci_rtc , val , PRTCIF_LDATA ) ;
rtcif_wait ( davinci_rtc ) ;
}
static inline u8 rtcss_read ( struct davinci_rtc * davinci_rtc , u8 addr )
{
rtcif_wait ( davinci_rtc ) ;
rtcif_write ( davinci_rtc , PRTCIF_CTLR_DIR | PRTCIF_CTLR_BENL_LSB | addr ,
PRTCIF_CTLR ) ;
rtcif_wait ( davinci_rtc ) ;
return rtcif_read ( davinci_rtc , PRTCIF_LDATA ) ;
}
static inline void davinci_rtcss_calendar_wait ( struct davinci_rtc * davinci_rtc )
{
while ( rtcss_read ( davinci_rtc , PRTCSS_RTC_CCTRL ) &
PRTCSS_RTC_CCTRL_CALBUSY )
cpu_relax ( ) ;
}
static irqreturn_t davinci_rtc_interrupt ( int irq , void * class_dev )
{
struct davinci_rtc * davinci_rtc = class_dev ;
unsigned long events = 0 ;
u32 irq_flg ;
u8 alm_irq , tmr_irq ;
u8 rtc_ctrl , rtc_cctrl ;
int ret = IRQ_NONE ;
irq_flg = rtcif_read ( davinci_rtc , PRTCIF_INTFLG ) &
PRTCIF_INTFLG_RTCSS ;
alm_irq = rtcss_read ( davinci_rtc , PRTCSS_RTC_CCTRL ) &
PRTCSS_RTC_CCTRL_ALMFLG ;
tmr_irq = rtcss_read ( davinci_rtc , PRTCSS_RTC_CTRL ) &
PRTCSS_RTC_CTRL_TMRFLG ;
if ( irq_flg ) {
if ( alm_irq ) {
events | = RTC_IRQF | RTC_AF ;
rtc_cctrl = rtcss_read ( davinci_rtc , PRTCSS_RTC_CCTRL ) ;
rtc_cctrl | = PRTCSS_RTC_CCTRL_ALMFLG ;
rtcss_write ( davinci_rtc , rtc_cctrl , PRTCSS_RTC_CCTRL ) ;
} else if ( tmr_irq ) {
events | = RTC_IRQF | RTC_PF ;
rtc_ctrl = rtcss_read ( davinci_rtc , PRTCSS_RTC_CTRL ) ;
rtc_ctrl | = PRTCSS_RTC_CTRL_TMRFLG ;
rtcss_write ( davinci_rtc , rtc_ctrl , PRTCSS_RTC_CTRL ) ;
}
rtcif_write ( davinci_rtc , PRTCIF_INTFLG_RTCSS ,
PRTCIF_INTFLG ) ;
rtc_update_irq ( davinci_rtc - > rtc , 1 , events ) ;
ret = IRQ_HANDLED ;
}
return ret ;
}
static int
davinci_rtc_ioctl ( struct device * dev , unsigned int cmd , unsigned long arg )
{
struct davinci_rtc * davinci_rtc = dev_get_drvdata ( dev ) ;
u8 rtc_ctrl ;
unsigned long flags ;
int ret = 0 ;
spin_lock_irqsave ( & davinci_rtc_lock , flags ) ;
rtc_ctrl = rtcss_read ( davinci_rtc , PRTCSS_RTC_CTRL ) ;
switch ( cmd ) {
case RTC_WIE_ON :
rtc_ctrl | = PRTCSS_RTC_CTRL_WEN | PRTCSS_RTC_CTRL_WDTFLG ;
break ;
case RTC_WIE_OFF :
rtc_ctrl & = ~ PRTCSS_RTC_CTRL_WEN ;
break ;
default :
ret = - ENOIOCTLCMD ;
}
rtcss_write ( davinci_rtc , rtc_ctrl , PRTCSS_RTC_CTRL ) ;
spin_unlock_irqrestore ( & davinci_rtc_lock , flags ) ;
return ret ;
}
2020-03-06 00:50:22 +03:00
static void convertfromdays ( u16 days , struct rtc_time * tm )
2009-11-05 17:51:34 +03:00
{
int tmp_days , year , mon ;
for ( year = 2000 ; ; year + + ) {
tmp_days = rtc_year_days ( 1 , 12 , year ) ;
if ( days > = tmp_days )
days - = tmp_days ;
else {
for ( mon = 0 ; ; mon + + ) {
tmp_days = rtc_month_days ( mon , year ) ;
if ( days > = tmp_days ) {
days - = tmp_days ;
} else {
tm - > tm_year = year - 1900 ;
tm - > tm_mon = mon ;
tm - > tm_mday = days + 1 ;
break ;
}
}
break ;
}
}
}
2020-03-06 00:50:22 +03:00
static void convert2days ( u16 * days , struct rtc_time * tm )
2009-11-05 17:51:34 +03:00
{
int i ;
* days = 0 ;
for ( i = 2000 ; i < 1900 + tm - > tm_year ; i + + )
* days + = rtc_year_days ( 1 , 12 , i ) ;
* days + = rtc_year_days ( tm - > tm_mday , tm - > tm_mon , 1900 + tm - > tm_year ) ;
}
static int davinci_rtc_read_time ( struct device * dev , struct rtc_time * tm )
{
struct davinci_rtc * davinci_rtc = dev_get_drvdata ( dev ) ;
u16 days = 0 ;
u8 day0 , day1 ;
unsigned long flags ;
spin_lock_irqsave ( & davinci_rtc_lock , flags ) ;
davinci_rtcss_calendar_wait ( davinci_rtc ) ;
tm - > tm_sec = bcd2bin ( rtcss_read ( davinci_rtc , PRTCSS_RTC_SEC ) ) ;
davinci_rtcss_calendar_wait ( davinci_rtc ) ;
tm - > tm_min = bcd2bin ( rtcss_read ( davinci_rtc , PRTCSS_RTC_MIN ) ) ;
davinci_rtcss_calendar_wait ( davinci_rtc ) ;
tm - > tm_hour = bcd2bin ( rtcss_read ( davinci_rtc , PRTCSS_RTC_HOUR ) ) ;
davinci_rtcss_calendar_wait ( davinci_rtc ) ;
day0 = rtcss_read ( davinci_rtc , PRTCSS_RTC_DAY0 ) ;
davinci_rtcss_calendar_wait ( davinci_rtc ) ;
day1 = rtcss_read ( davinci_rtc , PRTCSS_RTC_DAY1 ) ;
spin_unlock_irqrestore ( & davinci_rtc_lock , flags ) ;
days | = day1 ;
days < < = 8 ;
days | = day0 ;
2020-03-06 00:50:22 +03:00
convertfromdays ( days , tm ) ;
2009-11-05 17:51:34 +03:00
return 0 ;
}
static int davinci_rtc_set_time ( struct device * dev , struct rtc_time * tm )
{
struct davinci_rtc * davinci_rtc = dev_get_drvdata ( dev ) ;
u16 days ;
u8 rtc_cctrl ;
unsigned long flags ;
2020-03-06 00:50:21 +03:00
convert2days ( & days , tm ) ;
2009-11-05 17:51:34 +03:00
spin_lock_irqsave ( & davinci_rtc_lock , flags ) ;
davinci_rtcss_calendar_wait ( davinci_rtc ) ;
rtcss_write ( davinci_rtc , bin2bcd ( tm - > tm_sec ) , PRTCSS_RTC_SEC ) ;
davinci_rtcss_calendar_wait ( davinci_rtc ) ;
rtcss_write ( davinci_rtc , bin2bcd ( tm - > tm_min ) , PRTCSS_RTC_MIN ) ;
davinci_rtcss_calendar_wait ( davinci_rtc ) ;
rtcss_write ( davinci_rtc , bin2bcd ( tm - > tm_hour ) , PRTCSS_RTC_HOUR ) ;
davinci_rtcss_calendar_wait ( davinci_rtc ) ;
rtcss_write ( davinci_rtc , days & 0xFF , PRTCSS_RTC_DAY0 ) ;
davinci_rtcss_calendar_wait ( davinci_rtc ) ;
rtcss_write ( davinci_rtc , ( days & 0xFF00 ) > > 8 , PRTCSS_RTC_DAY1 ) ;
rtc_cctrl = rtcss_read ( davinci_rtc , PRTCSS_RTC_CCTRL ) ;
rtc_cctrl | = PRTCSS_RTC_CCTRL_CAEN ;
rtcss_write ( davinci_rtc , rtc_cctrl , PRTCSS_RTC_CCTRL ) ;
spin_unlock_irqrestore ( & davinci_rtc_lock , flags ) ;
return 0 ;
}
static int davinci_rtc_alarm_irq_enable ( struct device * dev ,
unsigned int enabled )
{
struct davinci_rtc * davinci_rtc = dev_get_drvdata ( dev ) ;
unsigned long flags ;
u8 rtc_cctrl = rtcss_read ( davinci_rtc , PRTCSS_RTC_CCTRL ) ;
spin_lock_irqsave ( & davinci_rtc_lock , flags ) ;
if ( enabled )
rtc_cctrl | = PRTCSS_RTC_CCTRL_DAEN |
PRTCSS_RTC_CCTRL_HAEN |
PRTCSS_RTC_CCTRL_MAEN |
PRTCSS_RTC_CCTRL_ALMFLG |
PRTCSS_RTC_CCTRL_AIEN ;
else
rtc_cctrl & = ~ PRTCSS_RTC_CCTRL_AIEN ;
davinci_rtcss_calendar_wait ( davinci_rtc ) ;
rtcss_write ( davinci_rtc , rtc_cctrl , PRTCSS_RTC_CCTRL ) ;
spin_unlock_irqrestore ( & davinci_rtc_lock , flags ) ;
return 0 ;
}
static int davinci_rtc_read_alarm ( struct device * dev , struct rtc_wkalrm * alm )
{
struct davinci_rtc * davinci_rtc = dev_get_drvdata ( dev ) ;
u16 days = 0 ;
u8 day0 , day1 ;
unsigned long flags ;
2016-07-11 11:05:27 +03:00
alm - > time . tm_sec = 0 ;
2009-11-05 17:51:34 +03:00
spin_lock_irqsave ( & davinci_rtc_lock , flags ) ;
davinci_rtcss_calendar_wait ( davinci_rtc ) ;
alm - > time . tm_min = bcd2bin ( rtcss_read ( davinci_rtc , PRTCSS_RTC_AMIN ) ) ;
davinci_rtcss_calendar_wait ( davinci_rtc ) ;
alm - > time . tm_hour = bcd2bin ( rtcss_read ( davinci_rtc , PRTCSS_RTC_AHOUR ) ) ;
davinci_rtcss_calendar_wait ( davinci_rtc ) ;
day0 = rtcss_read ( davinci_rtc , PRTCSS_RTC_ADAY0 ) ;
davinci_rtcss_calendar_wait ( davinci_rtc ) ;
day1 = rtcss_read ( davinci_rtc , PRTCSS_RTC_ADAY1 ) ;
spin_unlock_irqrestore ( & davinci_rtc_lock , flags ) ;
days | = day1 ;
days < < = 8 ;
days | = day0 ;
2020-03-06 00:50:22 +03:00
convertfromdays ( days , & alm - > time ) ;
2009-11-05 17:51:34 +03:00
alm - > pending = ! ! ( rtcss_read ( davinci_rtc ,
PRTCSS_RTC_CCTRL ) &
PRTCSS_RTC_CCTRL_AIEN ) ;
alm - > enabled = alm - > pending & & device_may_wakeup ( dev ) ;
return 0 ;
}
static int davinci_rtc_set_alarm ( struct device * dev , struct rtc_wkalrm * alm )
{
struct davinci_rtc * davinci_rtc = dev_get_drvdata ( dev ) ;
unsigned long flags ;
u16 days ;
2020-03-06 00:50:21 +03:00
convert2days ( & days , & alm - > time ) ;
2009-11-05 17:51:34 +03:00
spin_lock_irqsave ( & davinci_rtc_lock , flags ) ;
davinci_rtcss_calendar_wait ( davinci_rtc ) ;
rtcss_write ( davinci_rtc , bin2bcd ( alm - > time . tm_min ) , PRTCSS_RTC_AMIN ) ;
davinci_rtcss_calendar_wait ( davinci_rtc ) ;
rtcss_write ( davinci_rtc , bin2bcd ( alm - > time . tm_hour ) , PRTCSS_RTC_AHOUR ) ;
davinci_rtcss_calendar_wait ( davinci_rtc ) ;
rtcss_write ( davinci_rtc , days & 0xFF , PRTCSS_RTC_ADAY0 ) ;
davinci_rtcss_calendar_wait ( davinci_rtc ) ;
rtcss_write ( davinci_rtc , ( days & 0xFF00 ) > > 8 , PRTCSS_RTC_ADAY1 ) ;
spin_unlock_irqrestore ( & davinci_rtc_lock , flags ) ;
return 0 ;
}
rtc: constify rtc_class_ops structures
Check for rtc_class_ops structures that are only passed to
devm_rtc_device_register, rtc_device_register,
platform_device_register_data, all of which declare the corresponding
parameter as const. Declare rtc_class_ops structures that have these
properties as const.
The semantic patch that makes this change is as follows:
(http://coccinelle.lip6.fr/)
// <smpl>
@r disable optional_qualifier@
identifier i;
position p;
@@
static struct rtc_class_ops i@p = { ... };
@ok@
identifier r.i;
expression e1,e2,e3,e4;
position p;
@@
(
devm_rtc_device_register(e1,e2,&i@p,e3)
|
rtc_device_register(e1,e2,&i@p,e3)
|
platform_device_register_data(e1,e2,e3,&i@p,e4)
)
@bad@
position p != {r.p,ok.p};
identifier r.i;
@@
i@p
@depends on !bad disable optional_qualifier@
identifier r.i;
@@
static
+const
struct rtc_class_ops i = { ... };
// </smpl>
Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr>
Acked-by: Baruch Siach <baruch@tkos.co.il>
Acked-by: Hans Ulli Kroll <ulli.kroll@googlemail.com>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Acked-by: Thierry Reding <treding@nvidia.com>
Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
2016-08-31 11:05:25 +03:00
static const struct rtc_class_ops davinci_rtc_ops = {
2009-11-05 17:51:34 +03:00
. ioctl = davinci_rtc_ioctl ,
. read_time = davinci_rtc_read_time ,
. set_time = davinci_rtc_set_time ,
. alarm_irq_enable = davinci_rtc_alarm_irq_enable ,
. read_alarm = davinci_rtc_read_alarm ,
. set_alarm = davinci_rtc_set_alarm ,
} ;
static int __init davinci_rtc_probe ( struct platform_device * pdev )
{
struct device * dev = & pdev - > dev ;
struct davinci_rtc * davinci_rtc ;
int ret = 0 ;
2012-12-18 04:02:41 +04:00
davinci_rtc = devm_kzalloc ( & pdev - > dev , sizeof ( struct davinci_rtc ) , GFP_KERNEL ) ;
2014-04-04 01:49:39 +04:00
if ( ! davinci_rtc )
2009-11-05 17:51:34 +03:00
return - ENOMEM ;
davinci_rtc - > irq = platform_get_irq ( pdev , 0 ) ;
2019-07-30 21:15:39 +03:00
if ( davinci_rtc - > irq < 0 )
2012-12-18 04:02:41 +04:00
return davinci_rtc - > irq ;
2009-11-05 17:51:34 +03:00
2019-10-06 13:29:20 +03:00
davinci_rtc - > base = devm_platform_ioremap_resource ( pdev , 0 ) ;
2014-04-04 01:49:48 +04:00
if ( IS_ERR ( davinci_rtc - > base ) )
return PTR_ERR ( davinci_rtc - > base ) ;
2009-11-05 17:51:34 +03:00
2011-05-05 13:46:14 +04:00
platform_set_drvdata ( pdev , davinci_rtc ) ;
2020-03-06 00:50:19 +03:00
davinci_rtc - > rtc = devm_rtc_allocate_device ( & pdev - > dev ) ;
if ( IS_ERR ( davinci_rtc - > rtc ) )
2013-07-04 02:06:19 +04:00
return PTR_ERR ( davinci_rtc - > rtc ) ;
2020-03-06 00:50:19 +03:00
davinci_rtc - > rtc - > ops = & davinci_rtc_ops ;
2020-03-06 00:50:21 +03:00
davinci_rtc - > rtc - > range_min = RTC_TIMESTAMP_BEGIN_2000 ;
davinci_rtc - > rtc - > range_max = RTC_TIMESTAMP_BEGIN_2000 + ( 1 < < 16 ) * 86400ULL - 1 ;
2009-11-05 17:51:34 +03:00
rtcif_write ( davinci_rtc , PRTCIF_INTFLG_RTCSS , PRTCIF_INTFLG ) ;
rtcif_write ( davinci_rtc , 0 , PRTCIF_INTEN ) ;
rtcss_write ( davinci_rtc , 0 , PRTCSS_RTC_INTC_EXTENA1 ) ;
rtcss_write ( davinci_rtc , 0 , PRTCSS_RTC_CTRL ) ;
rtcss_write ( davinci_rtc , 0 , PRTCSS_RTC_CCTRL ) ;
2013-02-22 04:45:45 +04:00
ret = devm_request_irq ( dev , davinci_rtc - > irq , davinci_rtc_interrupt ,
2012-03-24 02:02:34 +04:00
0 , " davinci_rtc " , davinci_rtc ) ;
2009-11-05 17:51:34 +03:00
if ( ret < 0 ) {
dev_err ( dev , " unable to register davinci RTC interrupt \n " ) ;
2013-07-04 02:06:19 +04:00
return ret ;
2009-11-05 17:51:34 +03:00
}
/* Enable interrupts */
rtcif_write ( davinci_rtc , PRTCIF_INTEN_RTCSS , PRTCIF_INTEN ) ;
rtcss_write ( davinci_rtc , PRTCSS_RTC_INTC_EXTENA1_MASK ,
PRTCSS_RTC_INTC_EXTENA1 ) ;
rtcss_write ( davinci_rtc , PRTCSS_RTC_CCTRL_CAEN , PRTCSS_RTC_CCTRL ) ;
device_init_wakeup ( & pdev - > dev , 0 ) ;
2020-11-09 19:34:08 +03:00
return devm_rtc_register_device ( davinci_rtc - > rtc ) ;
2009-11-05 17:51:34 +03:00
}
2013-04-30 03:18:22 +04:00
static int __exit davinci_rtc_remove ( struct platform_device * pdev )
2009-11-05 17:51:34 +03:00
{
struct davinci_rtc * davinci_rtc = platform_get_drvdata ( pdev ) ;
device_init_wakeup ( & pdev - > dev , 0 ) ;
rtcif_write ( davinci_rtc , 0 , PRTCIF_INTEN ) ;
return 0 ;
}
static struct platform_driver davinci_rtc_driver = {
2013-04-30 03:18:22 +04:00
. remove = __exit_p ( davinci_rtc_remove ) ,
2009-11-05 17:51:34 +03:00
. driver = {
. name = " rtc_davinci " ,
} ,
} ;
2013-04-30 03:18:38 +04:00
module_platform_driver_probe ( davinci_rtc_driver , davinci_rtc_probe ) ;
2009-11-05 17:51:34 +03:00
MODULE_AUTHOR ( " Miguel Aguilar <miguel.aguilar@ridgerun.com> " ) ;
MODULE_DESCRIPTION ( " Texas Instruments DaVinci PRTC Driver " ) ;
MODULE_LICENSE ( " GPL " ) ;