Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

rtc: loongson: Add Loongson-2K0300 support

The Loongson-2K0300's rtc hardware design is similar to that of the
Loongson-1B, but it does not support the alarm feature.

Introduce `LOONGSON_RTC_ALARM_WORKAROUND`, which indicates a chip that
does not support the alarm feature, and rewrite the related logic in
`loongson_rtc_alarm_setting()`.

Reviewed-by: Huacai Chen <chenhuacai@loongson.cn>
Signed-off-by: Binbin Zhou <zhoubinbin@loongson.cn>
Link: https://patch.msgid.link/abff68dda2fe6a6601a9e58b31e278d941297fce.1768616276.git.zhoubinbin@loongson.cn
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>

authored by

Binbin Zhou and committed by
Alexandre Belloni
770a54ac 5d4899d4

+47 -24
+47 -24
drivers/rtc/rtc-loongson.c
··· 66 66 * According to the LS1C manual, RTC_CTRL and alarm-related registers are not defined. 67 67 * Accessing the relevant registers will cause the system to hang. 68 68 */ 69 - #define LS1C_RTC_CTRL_WORKAROUND BIT(0) 69 + #define LOONGSON_RTC_CTRL_WORKAROUND BIT(0) 70 + #define LOONGSON_RTC_ALARM_WORKAROUND BIT(1) 70 71 71 72 struct loongson_rtc_config { 72 73 u32 pm_offset; /* Offset of PM domain, for RTC alarm wakeup */ ··· 90 89 91 90 static const struct loongson_rtc_config ls1c_rtc_config = { 92 91 .pm_offset = 0, 93 - .flags = LS1C_RTC_CTRL_WORKAROUND, 92 + .flags = LOONGSON_RTC_CTRL_WORKAROUND | LOONGSON_RTC_ALARM_WORKAROUND, 94 93 }; 95 94 96 95 static const struct loongson_rtc_config generic_rtc_config = { 97 96 .pm_offset = 0x100, 98 97 .flags = 0, 98 + }; 99 + 100 + static const struct loongson_rtc_config ls2k0300_rtc_config = { 101 + .pm_offset = 0x0, 102 + .flags = LOONGSON_RTC_ALARM_WORKAROUND, 99 103 }; 100 104 101 105 static const struct loongson_rtc_config ls2k1000_rtc_config = { ··· 159 153 { 160 154 struct loongson_rtc_priv *priv = dev_get_drvdata(dev); 161 155 162 - if (priv->config->flags & LS1C_RTC_CTRL_WORKAROUND) 156 + if (priv->config->flags & LOONGSON_RTC_CTRL_WORKAROUND) 163 157 return 0; 164 158 165 159 /* Enable RTC TOY counters and crystal */ ··· 173 167 u32 ctrl_data; 174 168 struct loongson_rtc_priv *priv = dev_get_drvdata(dev); 175 169 176 - if (priv->config->flags & LS1C_RTC_CTRL_WORKAROUND) 170 + if (priv->config->flags & LOONGSON_RTC_CTRL_WORKAROUND) 177 171 return true; 178 172 179 173 ret = regmap_read(priv->regmap, RTC_CTRL_REG, &ctrl_data); ··· 305 299 .alarm_irq_enable = loongson_rtc_alarm_irq_enable, 306 300 }; 307 301 302 + static int loongson_rtc_alarm_setting(struct platform_device *pdev, void __iomem *regs) 303 + { 304 + int ret = 0, alarm_irq; 305 + struct device *dev = &pdev->dev; 306 + struct loongson_rtc_priv *priv = dev_get_drvdata(dev); 307 + 308 + if (priv->config->flags & LOONGSON_RTC_ALARM_WORKAROUND) { 309 + /* Loongson-1C/Loongson-2K0300 RTC does not support alarm */ 310 + clear_bit(RTC_FEATURE_ALARM, priv->rtcdev->features); 311 + return 0; 312 + } 313 + 314 + /* Get RTC alarm irq */ 315 + alarm_irq = platform_get_irq(pdev, 0); 316 + if (alarm_irq < 0) 317 + return alarm_irq; 318 + 319 + ret = devm_request_irq(dev, alarm_irq, loongson_rtc_isr, 0, "loongson-alarm", 320 + priv); 321 + if (ret < 0) 322 + return ret; 323 + 324 + priv->pm_base = regs - priv->config->pm_offset; 325 + device_init_wakeup(dev, true); 326 + 327 + if (has_acpi_companion(dev)) 328 + acpi_install_fixed_event_handler(ACPI_EVENT_RTC, 329 + loongson_rtc_handler, priv); 330 + 331 + return ret; 332 + } 333 + 308 334 static int loongson_rtc_probe(struct platform_device *pdev) 309 335 { 310 - int ret, alarm_irq; 336 + int ret; 311 337 void __iomem *regs; 312 338 struct loongson_rtc_priv *priv; 313 339 struct device *dev = &pdev->dev; ··· 368 330 return dev_err_probe(dev, PTR_ERR(priv->rtcdev), 369 331 "devm_rtc_allocate_device failed\n"); 370 332 371 - /* Get RTC alarm irq */ 372 - alarm_irq = platform_get_irq(pdev, 0); 373 - if (alarm_irq > 0) { 374 - ret = devm_request_irq(dev, alarm_irq, loongson_rtc_isr, 375 - 0, "loongson-alarm", priv); 376 - if (ret < 0) 377 - return dev_err_probe(dev, ret, "Unable to request irq %d\n", 378 - alarm_irq); 379 - 380 - priv->pm_base = regs - priv->config->pm_offset; 381 - device_init_wakeup(dev, true); 382 - 383 - if (has_acpi_companion(dev)) 384 - acpi_install_fixed_event_handler(ACPI_EVENT_RTC, 385 - loongson_rtc_handler, priv); 386 - } else { 387 - /* Loongson-1C RTC does not support alarm */ 388 - clear_bit(RTC_FEATURE_ALARM, priv->rtcdev->features); 389 - } 333 + ret = loongson_rtc_alarm_setting(pdev, regs); 334 + if (ret) 335 + return ret; 390 336 391 337 /* Loongson RTC does not support UIE */ 392 338 clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, priv->rtcdev->features); ··· 401 379 { .compatible = "loongson,ls1b-rtc", .data = &ls1b_rtc_config }, 402 380 { .compatible = "loongson,ls1c-rtc", .data = &ls1c_rtc_config }, 403 381 { .compatible = "loongson,ls7a-rtc", .data = &generic_rtc_config }, 382 + { .compatible = "loongson,ls2k0300-rtc", .data = &ls2k0300_rtc_config }, 404 383 { .compatible = "loongson,ls2k1000-rtc", .data = &ls2k1000_rtc_config }, 405 384 { /* sentinel */ } 406 385 };