6666 * According to the LS1C manual, RTC_CTRL and alarm-related registers are not defined.
6767 * Accessing the relevant registers will cause the system to hang.
6868 */
69- #define LS1C_RTC_CTRL_WORKAROUND BIT(0)
69+ #define LOONGSON_RTC_CTRL_WORKAROUND BIT(0)
70+ #define LOONGSON_RTC_ALARM_WORKAROUND BIT(1)
7071
7172struct loongson_rtc_config {
7273 u32 pm_offset ; /* Offset of PM domain, for RTC alarm wakeup */
@@ -89,14 +90,19 @@ static const struct loongson_rtc_config ls1b_rtc_config = {
8990
9091static const struct loongson_rtc_config ls1c_rtc_config = {
9192 .pm_offset = 0 ,
92- .flags = LS1C_RTC_CTRL_WORKAROUND ,
93+ .flags = LOONGSON_RTC_CTRL_WORKAROUND | LOONGSON_RTC_ALARM_WORKAROUND ,
9394};
9495
9596static const struct loongson_rtc_config generic_rtc_config = {
9697 .pm_offset = 0x100 ,
9798 .flags = 0 ,
9899};
99100
101+ static const struct loongson_rtc_config ls2k0300_rtc_config = {
102+ .pm_offset = 0x0 ,
103+ .flags = LOONGSON_RTC_ALARM_WORKAROUND ,
104+ };
105+
100106static const struct loongson_rtc_config ls2k1000_rtc_config = {
101107 .pm_offset = 0x800 ,
102108 .flags = 0 ,
@@ -153,7 +159,7 @@ static int loongson_rtc_set_enabled(struct device *dev)
153159{
154160 struct loongson_rtc_priv * priv = dev_get_drvdata (dev );
155161
156- if (priv -> config -> flags & LS1C_RTC_CTRL_WORKAROUND )
162+ if (priv -> config -> flags & LOONGSON_RTC_CTRL_WORKAROUND )
157163 return 0 ;
158164
159165 /* Enable RTC TOY counters and crystal */
@@ -167,7 +173,7 @@ static bool loongson_rtc_get_enabled(struct device *dev)
167173 u32 ctrl_data ;
168174 struct loongson_rtc_priv * priv = dev_get_drvdata (dev );
169175
170- if (priv -> config -> flags & LS1C_RTC_CTRL_WORKAROUND )
176+ if (priv -> config -> flags & LOONGSON_RTC_CTRL_WORKAROUND )
171177 return true;
172178
173179 ret = regmap_read (priv -> regmap , RTC_CTRL_REG , & ctrl_data );
@@ -299,9 +305,41 @@ static const struct rtc_class_ops loongson_rtc_ops = {
299305 .alarm_irq_enable = loongson_rtc_alarm_irq_enable ,
300306};
301307
308+ static int loongson_rtc_alarm_setting (struct platform_device * pdev , void __iomem * regs )
309+ {
310+ int ret = 0 , alarm_irq ;
311+ struct device * dev = & pdev -> dev ;
312+ struct loongson_rtc_priv * priv = dev_get_drvdata (dev );
313+
314+ if (priv -> config -> flags & LOONGSON_RTC_ALARM_WORKAROUND ) {
315+ /* Loongson-1C/Loongson-2K0300 RTC does not support alarm */
316+ clear_bit (RTC_FEATURE_ALARM , priv -> rtcdev -> features );
317+ return 0 ;
318+ }
319+
320+ /* Get RTC alarm irq */
321+ alarm_irq = platform_get_irq (pdev , 0 );
322+ if (alarm_irq < 0 )
323+ return alarm_irq ;
324+
325+ ret = devm_request_irq (dev , alarm_irq , loongson_rtc_isr , 0 , "loongson-alarm" ,
326+ priv );
327+ if (ret < 0 )
328+ return ret ;
329+
330+ priv -> pm_base = regs - priv -> config -> pm_offset ;
331+ device_init_wakeup (dev , true);
332+
333+ if (has_acpi_companion (dev ))
334+ acpi_install_fixed_event_handler (ACPI_EVENT_RTC ,
335+ loongson_rtc_handler , priv );
336+
337+ return ret ;
338+ }
339+
302340static int loongson_rtc_probe (struct platform_device * pdev )
303341{
304- int ret , alarm_irq ;
342+ int ret ;
305343 void __iomem * regs ;
306344 struct loongson_rtc_priv * priv ;
307345 struct device * dev = & pdev -> dev ;
@@ -330,25 +368,9 @@ static int loongson_rtc_probe(struct platform_device *pdev)
330368 return dev_err_probe (dev , PTR_ERR (priv -> rtcdev ),
331369 "devm_rtc_allocate_device failed\n" );
332370
333- /* Get RTC alarm irq */
334- alarm_irq = platform_get_irq (pdev , 0 );
335- if (alarm_irq > 0 ) {
336- ret = devm_request_irq (dev , alarm_irq , loongson_rtc_isr ,
337- 0 , "loongson-alarm" , priv );
338- if (ret < 0 )
339- return dev_err_probe (dev , ret , "Unable to request irq %d\n" ,
340- alarm_irq );
341-
342- priv -> pm_base = regs - priv -> config -> pm_offset ;
343- device_init_wakeup (dev , true);
344-
345- if (has_acpi_companion (dev ))
346- acpi_install_fixed_event_handler (ACPI_EVENT_RTC ,
347- loongson_rtc_handler , priv );
348- } else {
349- /* Loongson-1C RTC does not support alarm */
350- clear_bit (RTC_FEATURE_ALARM , priv -> rtcdev -> features );
351- }
371+ ret = loongson_rtc_alarm_setting (pdev , regs );
372+ if (ret )
373+ return ret ;
352374
353375 /* Loongson RTC does not support UIE */
354376 clear_bit (RTC_FEATURE_UPDATE_INTERRUPT , priv -> rtcdev -> features );
@@ -379,6 +401,7 @@ static const struct of_device_id loongson_rtc_of_match[] = {
379401 { .compatible = "loongson,ls1b-rtc" , .data = & ls1b_rtc_config },
380402 { .compatible = "loongson,ls1c-rtc" , .data = & ls1c_rtc_config },
381403 { .compatible = "loongson,ls7a-rtc" , .data = & generic_rtc_config },
404+ { .compatible = "loongson,ls2k0300-rtc" , .data = & ls2k0300_rtc_config },
382405 { .compatible = "loongson,ls2k1000-rtc" , .data = & ls2k1000_rtc_config },
383406 { /* sentinel */ }
384407};
0 commit comments