mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 04:18:39 +08:00
RTC for 6.7
Subsytem: - convert platform drivers to remove_new - prevent modpost warnings for unremovable platform drivers New driver: - Mstar SSD202D Drivers: - brcmstb-waketimer: support level alarm_irq - ep93xx: add DT support - rtc7301: support byte-addressed IO -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEBqsFVZXh8s/0O5JiY6TcMGxwOjIFAmVIF7AACgkQY6TcMGxw OjItMg/7B+cMYofdX7xuZ0QRCMRw0Op+wz1wBXdZPlUW/Bbha5A7FM4oVQYr6dCo 8rpeD+0d4DaLX5BwJZof5YUlLoD+sw9hr++isHU7xZ040ieqFleH1LfNqCMGtF+1 tML6bJfip7wz25Rs+E9l+oNo3W8LwAI1n5CbSB+KDAZU46P6DBqvH4rgyOFPQkR2 xwogNCYHSpgEFnKii6TVRMksvab0kA4kVA1Dhj7CEpOnchN0rK/Jfl7KEsftXAr8 0m74C9/Q7t6vgC2w4rM0m5XDWpCARUKUVAQwGJ/3kXagkMANrlYJclcN9jiOdqN9 DtWYvFibtPrGKv/6B4JTRezlDzqjLgOqb+jS6BK6p5NWg4Mh8mHG4SK8SNJdaNK9 htUzfiKSXW7n3HBPsX/xyysIhoUCQjdsHScxEOTN7n1xpnhbDQ0dKAJv2goe4UVS mik/hKbJrfHVduvQigUdrqRraiPF/A9XbjG8Q+WwPwAHpuSa/vks/49aScvUliJK i/YCNDW7KbCpjbYyA8tKOCghOXwjRzWJazP2FEpbgP06H9oNG/I/+v70Zh9AHK+t 6/x4ec7xGQj0NkaGLjKTw04z/EO4TI3NWx+Bt2LdIpzOpM6h5HiwGR4aR3CQ+5wT NA5F4yaFQWaSsQoXPBpQivoExEa46Ib5QaA3iVdSo4U9OdGGNj0= =4rbF -----END PGP SIGNATURE----- Merge tag 'rtc-6.7' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux Pull RTC updates from Alexandre Belloni: "There is a new driver for the RTC of the Mstar SSD202D SoC. The rtc7301 driver gains support for byte addresses to support the USRobotics USR8200. Then we have many non user visible changes and typo fixes. Summary: Subsytem: - convert platform drivers to remove_new - prevent modpost warnings for unremovable platform drivers New driver: - Mstar SSD202D Drivers: - brcmstb-waketimer: support level alarm_irq - ep93xx: add DT support - rtc7301: support byte-addressed IO" * tag 'rtc-6.7' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux: (28 commits) dt-bindings: rtc: Add Mstar SSD202D RTC rtc: Add support for the SSD202D RTC rtc: at91rm9200: annotate at91_rtc_remove with __exit again dt-bindings: rtc: microcrystal,rv3032: Document wakeup-source property dt-bindings: rtc: pcf8523: Convert to YAML dt-bindings: rtc: mcp795: move to trivial-rtc rtc: ep93xx: add DT support for Cirrus EP93xx dt-bindings: rtc: Add Cirrus EP93xx dt-bindings: rtc: pcf2123: convert to YAML rtc: efi: fixed typo in efi_procfs() rtc: omap: Use device_get_match_data() rtc: pcf85363: fix wrong mask/val parameters in regmap_update_bits call rtc: rtc7301: Support byte-addressed IO rtc: rtc7301: Rewrite bindings in schema rtc: sh: Convert to platform remove callback returning void rtc: pxa: Convert to platform remove callback returning void rtc: mv: Convert to platform remove callback returning void rtc: imxdi: Convert to platform remove callback returning void rtc: at91rm9200: Convert to platform remove callback returning void rtc: pcap: Drop no-op remove function ...
This commit is contained in:
commit
d2f51b3516
42
Documentation/devicetree/bindings/rtc/cirrus,ep9301-rtc.yaml
Normal file
42
Documentation/devicetree/bindings/rtc/cirrus,ep9301-rtc.yaml
Normal file
@ -0,0 +1,42 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/rtc/cirrus,ep9301-rtc.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Cirrus EP93xx Real Time Clock controller
|
||||
|
||||
maintainers:
|
||||
- Hartley Sweeten <hsweeten@visionengravers.com>
|
||||
- Alexander Sverdlin <alexander.sverdlin@gmail.com>
|
||||
|
||||
allOf:
|
||||
- $ref: rtc.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
oneOf:
|
||||
- const: cirrus,ep9301-rtc
|
||||
- items:
|
||||
- enum:
|
||||
- cirrus,ep9302-rtc
|
||||
- cirrus,ep9307-rtc
|
||||
- cirrus,ep9312-rtc
|
||||
- cirrus,ep9315-rtc
|
||||
- const: cirrus,ep9301-rtc
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
rtc@80920000 {
|
||||
compatible = "cirrus,ep9301-rtc";
|
||||
reg = <0x80920000 0x100>;
|
||||
};
|
@ -1,16 +0,0 @@
|
||||
EPSON TOYOCOM RTC-7301SF/DG
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible: Should be "epson,rtc7301sf" or "epson,rtc7301dg"
|
||||
- reg: Specifies base physical address and size of the registers.
|
||||
- interrupts: A single interrupt specifier.
|
||||
|
||||
Example:
|
||||
|
||||
rtc: rtc@44a00000 {
|
||||
compatible = "epson,rtc7301dg";
|
||||
reg = <0x44a00000 0x10000>;
|
||||
interrupt-parent = <&axi_intc_0>;
|
||||
interrupts = <3 2>;
|
||||
};
|
51
Documentation/devicetree/bindings/rtc/epson,rtc7301.yaml
Normal file
51
Documentation/devicetree/bindings/rtc/epson,rtc7301.yaml
Normal file
@ -0,0 +1,51 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/rtc/epson,rtc7301.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Epson Toyocom RTC-7301SF/DG
|
||||
|
||||
description:
|
||||
The only difference between the two variants is the packaging.
|
||||
The DG variant is a DIL package, and the SF variant is a flat
|
||||
package.
|
||||
|
||||
maintainers:
|
||||
- Akinobu Mita <akinobu.mita@gmail.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- epson,rtc7301dg
|
||||
- epson,rtc7301sf
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
reg-io-width:
|
||||
description:
|
||||
The size (in bytes) of the IO accesses that should be performed
|
||||
on the device.
|
||||
enum: [1, 4]
|
||||
default: 4
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
rtc: rtc@44a00000 {
|
||||
compatible = "epson,rtc7301dg";
|
||||
reg = <0x44a00000 0x10000>;
|
||||
reg-io-width = <4>;
|
||||
interrupt-parent = <&axi_intc_0>;
|
||||
interrupts = <3 2>;
|
||||
};
|
@ -1,11 +0,0 @@
|
||||
* Maxim MCP795 SPI Serial Real-Time Clock
|
||||
|
||||
Required properties:
|
||||
- compatible: Should contain "maxim,mcp795".
|
||||
- reg: SPI address for chip
|
||||
|
||||
Example:
|
||||
mcp795: rtc@0 {
|
||||
compatible = "maxim,mcp795";
|
||||
reg = <0>;
|
||||
};
|
@ -38,6 +38,8 @@ properties:
|
||||
- 3000
|
||||
- 4400
|
||||
|
||||
wakeup-source: true
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
35
Documentation/devicetree/bindings/rtc/mstar,ssd202d-rtc.yaml
Normal file
35
Documentation/devicetree/bindings/rtc/mstar,ssd202d-rtc.yaml
Normal file
@ -0,0 +1,35 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/rtc/mstar,ssd202d-rtc.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Mstar SSD202D Real Time Clock
|
||||
|
||||
maintainers:
|
||||
- Daniel Palmer <daniel@0x0f.com>
|
||||
- Romain Perier <romain.perier@gmail.com>
|
||||
|
||||
allOf:
|
||||
- $ref: rtc.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- mstar,ssd202d-rtc
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
rtc@6800 {
|
||||
compatible = "mstar,ssd202d-rtc";
|
||||
reg = <0x6800 0x200>;
|
||||
};
|
||||
...
|
47
Documentation/devicetree/bindings/rtc/nxp,pcf2123.yaml
Normal file
47
Documentation/devicetree/bindings/rtc/nxp,pcf2123.yaml
Normal file
@ -0,0 +1,47 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/rtc/nxp,pcf2123.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: NXP PCF2123 SPI Real Time Clock
|
||||
|
||||
maintainers:
|
||||
- Javier Carrasco <javier.carrasco.cruz@gmail.com>
|
||||
|
||||
allOf:
|
||||
- $ref: /schemas/spi/spi-peripheral-props.yaml#
|
||||
- $ref: rtc.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- nxp,pcf2123
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
spi {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
rtc@3 {
|
||||
compatible = "nxp,pcf2123";
|
||||
reg = <3>;
|
||||
interrupts = <GIC_SPI 130 IRQ_TYPE_LEVEL_LOW>;
|
||||
spi-cs-high;
|
||||
};
|
||||
};
|
||||
...
|
@ -1,18 +0,0 @@
|
||||
* NXP PCF8523 Real Time Clock
|
||||
|
||||
Required properties:
|
||||
- compatible: Should contain "nxp,pcf8523".
|
||||
- reg: I2C address for chip.
|
||||
|
||||
Optional property:
|
||||
- quartz-load-femtofarads: The capacitive load of the quartz(x-tal),
|
||||
expressed in femto Farad (fF). Valid values are 7000 and 12500.
|
||||
Default value (if no value is specified) is 12500fF.
|
||||
|
||||
Example:
|
||||
|
||||
pcf8523: rtc@68 {
|
||||
compatible = "nxp,pcf8523";
|
||||
reg = <0x68>;
|
||||
quartz-load-femtofarads = <7000>;
|
||||
};
|
45
Documentation/devicetree/bindings/rtc/nxp,pcf8523.yaml
Normal file
45
Documentation/devicetree/bindings/rtc/nxp,pcf8523.yaml
Normal file
@ -0,0 +1,45 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/rtc/nxp,pcf8523.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: NXP PCF8523 Real Time Clock
|
||||
|
||||
maintainers:
|
||||
- Sam Ravnborg <sam@ravnborg.org>
|
||||
|
||||
allOf:
|
||||
- $ref: rtc.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: nxp,pcf8523
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
quartz-load-femtofarads:
|
||||
description:
|
||||
The capacitive load of the crystal, expressed in femto Farad (fF).
|
||||
enum: [ 7000, 12500 ]
|
||||
default: 12500
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
rtc@68 {
|
||||
compatible = "nxp,pcf8523";
|
||||
reg = <0x68>;
|
||||
quartz-load-femtofarads = <7000>;
|
||||
};
|
||||
};
|
@ -1,17 +0,0 @@
|
||||
NXP PCF2123 SPI Real Time Clock
|
||||
|
||||
Required properties:
|
||||
- compatible: should be: "nxp,pcf2123"
|
||||
or "microcrystal,rv2123"
|
||||
- reg: should be the SPI slave chipselect address
|
||||
|
||||
Optional properties:
|
||||
- spi-cs-high: PCF2123 needs chipselect high
|
||||
|
||||
Example:
|
||||
|
||||
pcf2123: rtc@3 {
|
||||
compatible = "nxp,pcf2123"
|
||||
reg = <3>
|
||||
spi-cs-high;
|
||||
};
|
@ -45,6 +45,8 @@ properties:
|
||||
- isil,isl1208
|
||||
# Intersil ISL1218 Low Power RTC with Battery Backed SRAM
|
||||
- isil,isl1218
|
||||
# SPI-BUS INTERFACE REAL TIME CLOCK MODULE
|
||||
- maxim,mcp795
|
||||
# Real Time Clock Module with I2C-Bus
|
||||
- microcrystal,rv3029
|
||||
# Real Time Clock
|
||||
|
@ -1351,7 +1351,7 @@ config RTC_DRV_DIGICOLOR
|
||||
|
||||
config RTC_DRV_IMXDI
|
||||
tristate "Freescale IMX DryIce Real Time Clock"
|
||||
depends on ARCH_MXC
|
||||
depends on ARCH_MXC || COMPILE_TEST
|
||||
depends on OF
|
||||
help
|
||||
Support for Freescale IMX DryIce RTC
|
||||
@ -1984,4 +1984,15 @@ config RTC_DRV_POLARFIRE_SOC
|
||||
This driver can also be built as a module, if so, the module
|
||||
will be called "rtc-mpfs".
|
||||
|
||||
config RTC_DRV_SSD202D
|
||||
tristate "SigmaStar SSD202D RTC"
|
||||
depends on ARCH_MSTARV7 || COMPILE_TEST
|
||||
default ARCH_MSTARV7
|
||||
help
|
||||
If you say yes here you get support for the SigmaStar SSD202D On-Chip
|
||||
Real Time Clock.
|
||||
|
||||
This driver can also be built as a module, if so, the module
|
||||
will be called "rtc-ssd20xd".
|
||||
|
||||
endif # RTC_CLASS
|
||||
|
@ -103,6 +103,7 @@ obj-$(CONFIG_RTC_DRV_MESON) += rtc-meson.o
|
||||
obj-$(CONFIG_RTC_DRV_MOXART) += rtc-moxart.o
|
||||
obj-$(CONFIG_RTC_DRV_MPC5121) += rtc-mpc5121.o
|
||||
obj-$(CONFIG_RTC_DRV_MSC313) += rtc-msc313.o
|
||||
obj-$(CONFIG_RTC_DRV_SSD202D) += rtc-ssd202d.o
|
||||
obj-$(CONFIG_RTC_DRV_MSM6242) += rtc-msm6242.o
|
||||
obj-$(CONFIG_RTC_DRV_MT2712) += rtc-mt2712.o
|
||||
obj-$(CONFIG_RTC_DRV_MT6397) += rtc-mt6397.o
|
||||
|
@ -558,7 +558,7 @@ err_clk:
|
||||
/*
|
||||
* Disable and remove the RTC driver
|
||||
*/
|
||||
static int __exit at91_rtc_remove(struct platform_device *pdev)
|
||||
static void __exit at91_rtc_remove(struct platform_device *pdev)
|
||||
{
|
||||
/* Disable all interrupts */
|
||||
at91_rtc_write_idr(AT91_RTC_ACKUPD | AT91_RTC_ALARM |
|
||||
@ -566,8 +566,6 @@ static int __exit at91_rtc_remove(struct platform_device *pdev)
|
||||
AT91_RTC_CALEV);
|
||||
|
||||
clk_disable_unprepare(sclk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void at91_rtc_shutdown(struct platform_device *pdev)
|
||||
@ -635,8 +633,14 @@ static int at91_rtc_resume(struct device *dev)
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(at91_rtc_pm_ops, at91_rtc_suspend, at91_rtc_resume);
|
||||
|
||||
static struct platform_driver at91_rtc_driver = {
|
||||
.remove = __exit_p(at91_rtc_remove),
|
||||
/*
|
||||
* at91_rtc_remove() lives in .exit.text. For drivers registered via
|
||||
* module_platform_driver_probe() this is ok because they cannot get unbound at
|
||||
* runtime. So mark the driver struct with __refdata to prevent modpost
|
||||
* triggering a section mismatch warning.
|
||||
*/
|
||||
static struct platform_driver at91_rtc_driver __refdata = {
|
||||
.remove_new = __exit_p(at91_rtc_remove),
|
||||
.shutdown = at91_rtc_shutdown,
|
||||
.driver = {
|
||||
.name = "at91_rtc",
|
||||
|
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright © 2014-2017 Broadcom
|
||||
* Copyright © 2014-2023 Broadcom
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
@ -34,6 +34,7 @@ struct brcmstb_waketmr {
|
||||
u32 rate;
|
||||
unsigned long rtc_alarm;
|
||||
bool alarm_en;
|
||||
bool alarm_expired;
|
||||
};
|
||||
|
||||
#define BRCMSTB_WKTMR_EVENT 0x00
|
||||
@ -64,6 +65,11 @@ static inline void brcmstb_waketmr_clear_alarm(struct brcmstb_waketmr *timer)
|
||||
writel_relaxed(reg - 1, timer->base + BRCMSTB_WKTMR_ALARM);
|
||||
writel_relaxed(WKTMR_ALARM_EVENT, timer->base + BRCMSTB_WKTMR_EVENT);
|
||||
(void)readl_relaxed(timer->base + BRCMSTB_WKTMR_EVENT);
|
||||
if (timer->alarm_expired) {
|
||||
timer->alarm_expired = false;
|
||||
/* maintain call balance */
|
||||
enable_irq(timer->alarm_irq);
|
||||
}
|
||||
}
|
||||
|
||||
static void brcmstb_waketmr_set_alarm(struct brcmstb_waketmr *timer,
|
||||
@ -105,10 +111,17 @@ static irqreturn_t brcmstb_alarm_irq(int irq, void *data)
|
||||
return IRQ_HANDLED;
|
||||
|
||||
if (timer->alarm_en) {
|
||||
if (!device_may_wakeup(timer->dev))
|
||||
if (device_may_wakeup(timer->dev)) {
|
||||
disable_irq_nosync(irq);
|
||||
timer->alarm_expired = true;
|
||||
} else {
|
||||
writel_relaxed(WKTMR_ALARM_EVENT,
|
||||
timer->base + BRCMSTB_WKTMR_EVENT);
|
||||
}
|
||||
rtc_update_irq(timer->rtc, 1, RTC_IRQF | RTC_AF);
|
||||
} else {
|
||||
writel_relaxed(WKTMR_ALARM_EVENT,
|
||||
timer->base + BRCMSTB_WKTMR_EVENT);
|
||||
}
|
||||
|
||||
return IRQ_HANDLED;
|
||||
@ -221,8 +234,14 @@ static int brcmstb_waketmr_alarm_enable(struct device *dev,
|
||||
!brcmstb_waketmr_is_pending(timer))
|
||||
return -EINVAL;
|
||||
timer->alarm_en = true;
|
||||
if (timer->alarm_irq)
|
||||
if (timer->alarm_irq) {
|
||||
if (timer->alarm_expired) {
|
||||
timer->alarm_expired = false;
|
||||
/* maintain call balance */
|
||||
enable_irq(timer->alarm_irq);
|
||||
}
|
||||
enable_irq(timer->alarm_irq);
|
||||
}
|
||||
} else if (!enabled && timer->alarm_en) {
|
||||
if (timer->alarm_irq)
|
||||
disable_irq(timer->alarm_irq);
|
||||
@ -352,6 +371,17 @@ static int brcmstb_waketmr_suspend(struct device *dev)
|
||||
return brcmstb_waketmr_prepare_suspend(timer);
|
||||
}
|
||||
|
||||
static int brcmstb_waketmr_suspend_noirq(struct device *dev)
|
||||
{
|
||||
struct brcmstb_waketmr *timer = dev_get_drvdata(dev);
|
||||
|
||||
/* Catch any alarms occurring prior to noirq */
|
||||
if (timer->alarm_expired && device_may_wakeup(dev))
|
||||
return -EBUSY;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int brcmstb_waketmr_resume(struct device *dev)
|
||||
{
|
||||
struct brcmstb_waketmr *timer = dev_get_drvdata(dev);
|
||||
@ -368,10 +398,17 @@ static int brcmstb_waketmr_resume(struct device *dev)
|
||||
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
#define brcmstb_waketmr_suspend NULL
|
||||
#define brcmstb_waketmr_suspend_noirq NULL
|
||||
#define brcmstb_waketmr_resume NULL
|
||||
#endif /* CONFIG_PM_SLEEP */
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(brcmstb_waketmr_pm_ops,
|
||||
brcmstb_waketmr_suspend, brcmstb_waketmr_resume);
|
||||
static const struct dev_pm_ops brcmstb_waketmr_pm_ops = {
|
||||
.suspend = brcmstb_waketmr_suspend,
|
||||
.suspend_noirq = brcmstb_waketmr_suspend_noirq,
|
||||
.resume = brcmstb_waketmr_resume,
|
||||
};
|
||||
|
||||
static const __maybe_unused struct of_device_id brcmstb_waketmr_of_match[] = {
|
||||
{ .compatible = "brcm,brcmstb-waketimer" },
|
||||
|
@ -227,7 +227,7 @@ static int efi_procfs(struct device *dev, struct seq_file *seq)
|
||||
enabled == 1 ? "yes" : "no",
|
||||
pending == 1 ? "yes" : "no");
|
||||
|
||||
if (eft.timezone == EFI_UNSPECIFIED_TIMEZONE)
|
||||
if (alm.timezone == EFI_UNSPECIFIED_TIMEZONE)
|
||||
seq_puts(seq, "Timezone\t: unspecified\n");
|
||||
else
|
||||
/* XXX fixme: convert to string? */
|
||||
|
@ -7,6 +7,7 @@
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/rtc.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/io.h>
|
||||
@ -148,9 +149,16 @@ static int ep93xx_rtc_probe(struct platform_device *pdev)
|
||||
return devm_rtc_register_device(ep93xx_rtc->rtc);
|
||||
}
|
||||
|
||||
static const struct of_device_id ep93xx_rtc_of_ids[] = {
|
||||
{ .compatible = "cirrus,ep9301-rtc" },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, ep93xx_rtc_of_ids);
|
||||
|
||||
static struct platform_driver ep93xx_rtc_driver = {
|
||||
.driver = {
|
||||
.name = "ep93xx-rtc",
|
||||
.of_match_table = ep93xx_rtc_of_ids,
|
||||
},
|
||||
.probe = ep93xx_rtc_probe,
|
||||
};
|
||||
|
@ -830,7 +830,7 @@ err:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int __exit dryice_rtc_remove(struct platform_device *pdev)
|
||||
static void __exit dryice_rtc_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct imxdi_dev *imxdi = platform_get_drvdata(pdev);
|
||||
|
||||
@ -840,8 +840,6 @@ static int __exit dryice_rtc_remove(struct platform_device *pdev)
|
||||
writel(0, imxdi->ioaddr + DIER);
|
||||
|
||||
clk_disable_unprepare(imxdi->clk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id dryice_dt_ids[] = {
|
||||
@ -851,12 +849,18 @@ static const struct of_device_id dryice_dt_ids[] = {
|
||||
|
||||
MODULE_DEVICE_TABLE(of, dryice_dt_ids);
|
||||
|
||||
static struct platform_driver dryice_rtc_driver = {
|
||||
/*
|
||||
* dryice_rtc_remove() lives in .exit.text. For drivers registered via
|
||||
* module_platform_driver_probe() this is ok because they cannot get unbound at
|
||||
* runtime. So mark the driver struct with __refdata to prevent modpost
|
||||
* triggering a section mismatch warning.
|
||||
*/
|
||||
static struct platform_driver dryice_rtc_driver __refdata = {
|
||||
.driver = {
|
||||
.name = "imxdi_rtc",
|
||||
.of_match_table = dryice_dt_ids,
|
||||
},
|
||||
.remove = __exit_p(dryice_rtc_remove),
|
||||
.remove_new = __exit_p(dryice_rtc_remove),
|
||||
};
|
||||
|
||||
module_platform_driver_probe(dryice_rtc_driver, dryice_rtc_probe);
|
||||
|
@ -282,7 +282,7 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __exit mv_rtc_remove(struct platform_device *pdev)
|
||||
static void __exit mv_rtc_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
|
||||
|
||||
@ -291,8 +291,6 @@ static int __exit mv_rtc_remove(struct platform_device *pdev)
|
||||
|
||||
if (!IS_ERR(pdata->clk))
|
||||
clk_disable_unprepare(pdata->clk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
@ -303,8 +301,14 @@ static const struct of_device_id rtc_mv_of_match_table[] = {
|
||||
MODULE_DEVICE_TABLE(of, rtc_mv_of_match_table);
|
||||
#endif
|
||||
|
||||
static struct platform_driver mv_rtc_driver = {
|
||||
.remove = __exit_p(mv_rtc_remove),
|
||||
/*
|
||||
* mv_rtc_remove() lives in .exit.text. For drivers registered via
|
||||
* module_platform_driver_probe() this is ok because they cannot get unbound at
|
||||
* runtime. So mark the driver struct with __refdata to prevent modpost
|
||||
* triggering a section mismatch warning.
|
||||
*/
|
||||
static struct platform_driver mv_rtc_driver __refdata = {
|
||||
.remove_new = __exit_p(mv_rtc_remove),
|
||||
.driver = {
|
||||
.name = "rtc-mv",
|
||||
.of_match_table = of_match_ptr(rtc_mv_of_match_table),
|
||||
|
@ -18,12 +18,12 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/pinctrl/pinctrl.h>
|
||||
#include <linux/pinctrl/pinconf.h>
|
||||
#include <linux/pinctrl/pinconf-generic.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/property.h>
|
||||
#include <linux/rtc.h>
|
||||
#include <linux/rtc/rtc-omap.h>
|
||||
|
||||
@ -729,16 +729,14 @@ static int omap_rtc_probe(struct platform_device *pdev)
|
||||
struct omap_rtc *rtc;
|
||||
u8 reg, mask, new_ctrl;
|
||||
const struct platform_device_id *id_entry;
|
||||
const struct of_device_id *of_id;
|
||||
int ret;
|
||||
|
||||
rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL);
|
||||
if (!rtc)
|
||||
return -ENOMEM;
|
||||
|
||||
of_id = of_match_device(omap_rtc_of_match, &pdev->dev);
|
||||
if (of_id) {
|
||||
rtc->type = of_id->data;
|
||||
rtc->type = device_get_match_data(&pdev->dev);
|
||||
if (rtc->type) {
|
||||
rtc->is_pmic_controller = rtc->type->has_pmic_mode &&
|
||||
of_device_is_system_power_controller(pdev->dev.of_node);
|
||||
} else {
|
||||
|
@ -166,13 +166,7 @@ static int __init pcap_rtc_probe(struct platform_device *pdev)
|
||||
return devm_rtc_register_device(pcap_rtc->rtc);
|
||||
}
|
||||
|
||||
static int __exit pcap_rtc_remove(struct platform_device *pdev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver pcap_rtc_driver = {
|
||||
.remove = __exit_p(pcap_rtc_remove),
|
||||
.driver = {
|
||||
.name = "pcap-rtc",
|
||||
},
|
||||
|
@ -438,7 +438,7 @@ static int pcf85363_probe(struct i2c_client *client)
|
||||
if (client->irq > 0 || wakeup_source) {
|
||||
regmap_write(pcf85363->regmap, CTRL_FLAGS, 0);
|
||||
regmap_update_bits(pcf85363->regmap, CTRL_PIN_IO,
|
||||
PIN_IO_INTA_OUT, PIN_IO_INTAPM);
|
||||
PIN_IO_INTAPM, PIN_IO_INTA_OUT);
|
||||
}
|
||||
|
||||
if (client->irq > 0) {
|
||||
|
@ -365,12 +365,11 @@ static int __init pxa_rtc_probe(struct platform_device *pdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __exit pxa_rtc_remove(struct platform_device *pdev)
|
||||
static void __exit pxa_rtc_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
|
||||
pxa_rtc_release(dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
@ -403,8 +402,14 @@ static int pxa_rtc_resume(struct device *dev)
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(pxa_rtc_pm_ops, pxa_rtc_suspend, pxa_rtc_resume);
|
||||
|
||||
static struct platform_driver pxa_rtc_driver = {
|
||||
.remove = __exit_p(pxa_rtc_remove),
|
||||
/*
|
||||
* pxa_rtc_remove() lives in .exit.text. For drivers registered via
|
||||
* module_platform_driver_probe() this is ok because they cannot get unbound at
|
||||
* runtime. So mark the driver struct with __refdata to prevent modpost
|
||||
* triggering a section mismatch warning.
|
||||
*/
|
||||
static struct platform_driver pxa_rtc_driver __refdata = {
|
||||
.remove_new = __exit_p(pxa_rtc_remove),
|
||||
.driver = {
|
||||
.name = "pxa-rtc",
|
||||
.of_match_table = of_match_ptr(pxa_rtc_dt_ids),
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/property.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/rtc.h>
|
||||
@ -55,12 +56,23 @@ struct rtc7301_priv {
|
||||
u8 bank;
|
||||
};
|
||||
|
||||
static const struct regmap_config rtc7301_regmap_config = {
|
||||
/*
|
||||
* When the device is memory-mapped, some platforms pack the registers into
|
||||
* 32-bit access using the lower 8 bits at each 4-byte stride, while others
|
||||
* expose them as simply consecutive bytes.
|
||||
*/
|
||||
static const struct regmap_config rtc7301_regmap_32_config = {
|
||||
.reg_bits = 32,
|
||||
.val_bits = 8,
|
||||
.reg_stride = 4,
|
||||
};
|
||||
|
||||
static const struct regmap_config rtc7301_regmap_8_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
.reg_stride = 1,
|
||||
};
|
||||
|
||||
static u8 rtc7301_read(struct rtc7301_priv *priv, unsigned int reg)
|
||||
{
|
||||
int reg_stride = regmap_get_reg_stride(priv->regmap);
|
||||
@ -356,7 +368,9 @@ static int __init rtc7301_rtc_probe(struct platform_device *dev)
|
||||
void __iomem *regs;
|
||||
struct rtc7301_priv *priv;
|
||||
struct rtc_device *rtc;
|
||||
static const struct regmap_config *mapconf;
|
||||
int ret;
|
||||
u32 val;
|
||||
|
||||
priv = devm_kzalloc(&dev->dev, sizeof(*priv), GFP_KERNEL);
|
||||
if (!priv)
|
||||
@ -366,8 +380,25 @@ static int __init rtc7301_rtc_probe(struct platform_device *dev)
|
||||
if (IS_ERR(regs))
|
||||
return PTR_ERR(regs);
|
||||
|
||||
ret = device_property_read_u32(&dev->dev, "reg-io-width", &val);
|
||||
if (ret)
|
||||
/* Default to 32bit accesses */
|
||||
val = 4;
|
||||
|
||||
switch (val) {
|
||||
case 1:
|
||||
mapconf = &rtc7301_regmap_8_config;
|
||||
break;
|
||||
case 4:
|
||||
mapconf = &rtc7301_regmap_32_config;
|
||||
break;
|
||||
default:
|
||||
dev_err(&dev->dev, "invalid reg-io-width %d\n", val);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
priv->regmap = devm_regmap_init_mmio(&dev->dev, regs,
|
||||
&rtc7301_regmap_config);
|
||||
mapconf);
|
||||
if (IS_ERR(priv->regmap))
|
||||
return PTR_ERR(priv->regmap);
|
||||
|
||||
|
@ -469,7 +469,7 @@ static int __init sh_rtc_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct sh_rtc *rtc;
|
||||
struct resource *res;
|
||||
char clk_name[6];
|
||||
char clk_name[14];
|
||||
int clk_id, ret;
|
||||
|
||||
rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL);
|
||||
@ -620,7 +620,7 @@ err_unmap:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __exit sh_rtc_remove(struct platform_device *pdev)
|
||||
static void __exit sh_rtc_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct sh_rtc *rtc = platform_get_drvdata(pdev);
|
||||
|
||||
@ -628,8 +628,6 @@ static int __exit sh_rtc_remove(struct platform_device *pdev)
|
||||
sh_rtc_setcie(&pdev->dev, 0);
|
||||
|
||||
clk_disable(rtc->clk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sh_rtc_set_irq_wake(struct device *dev, int enabled)
|
||||
@ -668,13 +666,19 @@ static const struct of_device_id sh_rtc_of_match[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, sh_rtc_of_match);
|
||||
|
||||
static struct platform_driver sh_rtc_platform_driver = {
|
||||
/*
|
||||
* sh_rtc_remove() lives in .exit.text. For drivers registered via
|
||||
* module_platform_driver_probe() this is ok because they cannot get unbound at
|
||||
* runtime. So mark the driver struct with __refdata to prevent modpost
|
||||
* triggering a section mismatch warning.
|
||||
*/
|
||||
static struct platform_driver sh_rtc_platform_driver __refdata = {
|
||||
.driver = {
|
||||
.name = DRV_NAME,
|
||||
.pm = &sh_rtc_pm_ops,
|
||||
.of_match_table = sh_rtc_of_match,
|
||||
},
|
||||
.remove = __exit_p(sh_rtc_remove),
|
||||
.remove_new = __exit_p(sh_rtc_remove),
|
||||
};
|
||||
|
||||
module_platform_driver_probe(sh_rtc_platform_driver, sh_rtc_probe);
|
||||
|
249
drivers/rtc/rtc-ssd202d.c
Normal file
249
drivers/rtc/rtc-ssd202d.c
Normal file
@ -0,0 +1,249 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Real time clocks driver for MStar/SigmaStar SSD202D SoCs.
|
||||
*
|
||||
* (C) 2021 Daniel Palmer
|
||||
* (C) 2023 Romain Perier
|
||||
*/
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/rtc.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/pm.h>
|
||||
|
||||
#define REG_CTRL 0x0
|
||||
#define REG_CTRL1 0x4
|
||||
#define REG_ISO_CTRL 0xc
|
||||
#define REG_WRDATA_L 0x10
|
||||
#define REG_WRDATA_H 0x14
|
||||
#define REG_ISOACK 0x20
|
||||
#define REG_RDDATA_L 0x24
|
||||
#define REG_RDDATA_H 0x28
|
||||
#define REG_RDCNT_L 0x30
|
||||
#define REG_RDCNT_H 0x34
|
||||
#define REG_CNT_TRIG 0x38
|
||||
#define REG_PWRCTRL 0x3c
|
||||
#define REG_RTC_TEST 0x54
|
||||
|
||||
#define CNT_RD_TRIG_BIT BIT(0)
|
||||
#define CNT_RD_BIT BIT(0)
|
||||
#define BASE_WR_BIT BIT(1)
|
||||
#define BASE_RD_BIT BIT(2)
|
||||
#define CNT_RST_BIT BIT(3)
|
||||
#define ISO_CTRL_ACK_MASK BIT(3)
|
||||
#define ISO_CTRL_ACK_SHIFT 3
|
||||
#define SW0_WR_BIT BIT(5)
|
||||
#define SW1_WR_BIT BIT(6)
|
||||
#define SW0_RD_BIT BIT(7)
|
||||
#define SW1_RD_BIT BIT(8)
|
||||
|
||||
#define ISO_CTRL_MASK GENMASK(2, 0)
|
||||
|
||||
struct ssd202d_rtc {
|
||||
struct rtc_device *rtc_dev;
|
||||
void __iomem *base;
|
||||
};
|
||||
|
||||
static u8 read_iso_en(void __iomem *base)
|
||||
{
|
||||
return readb(base + REG_RTC_TEST) & 0x1;
|
||||
}
|
||||
|
||||
static u8 read_iso_ctrl_ack(void __iomem *base)
|
||||
{
|
||||
return (readb(base + REG_ISOACK) & ISO_CTRL_ACK_MASK) >> ISO_CTRL_ACK_SHIFT;
|
||||
}
|
||||
|
||||
static int ssd202d_rtc_isoctrl(struct ssd202d_rtc *priv)
|
||||
{
|
||||
static const unsigned int sequence[] = { 0x0, 0x1, 0x3, 0x7, 0x5, 0x1, 0x0 };
|
||||
unsigned int val;
|
||||
struct device *dev = &priv->rtc_dev->dev;
|
||||
int i, ret;
|
||||
|
||||
/*
|
||||
* This gates iso_en by writing a special sequence of bytes to iso_ctrl
|
||||
* and ensuring that it has been correctly applied by reading iso_ctrl_ack
|
||||
*/
|
||||
for (i = 0; i < ARRAY_SIZE(sequence); i++) {
|
||||
writeb(sequence[i] & ISO_CTRL_MASK, priv->base + REG_ISO_CTRL);
|
||||
|
||||
ret = read_poll_timeout(read_iso_ctrl_ack, val, val == (i % 2), 100,
|
||||
20 * 100, true, priv->base);
|
||||
if (ret) {
|
||||
dev_dbg(dev, "Timeout waiting for ack byte %i (%x) of sequence\n", i,
|
||||
sequence[i]);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* At this point iso_en should be raised for 1ms
|
||||
*/
|
||||
ret = read_poll_timeout(read_iso_en, val, val, 100, 22 * 100, true, priv->base);
|
||||
if (ret)
|
||||
dev_dbg(dev, "Timeout waiting for iso_en\n");
|
||||
mdelay(2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ssd202d_rtc_read_reg(struct ssd202d_rtc *priv, unsigned int reg,
|
||||
unsigned int field, unsigned int *base)
|
||||
{
|
||||
unsigned int l, h;
|
||||
u16 val;
|
||||
|
||||
/* Ask for the content of an RTC value into RDDATA by gating iso_en,
|
||||
* then iso_en is gated and the content of RDDATA can be read
|
||||
*/
|
||||
val = readw(priv->base + reg);
|
||||
writew(val | field, priv->base + reg);
|
||||
ssd202d_rtc_isoctrl(priv);
|
||||
writew(val & ~field, priv->base + reg);
|
||||
|
||||
l = readw(priv->base + REG_RDDATA_L);
|
||||
h = readw(priv->base + REG_RDDATA_H);
|
||||
|
||||
*base = (h << 16) | l;
|
||||
}
|
||||
|
||||
static void ssd202d_rtc_write_reg(struct ssd202d_rtc *priv, unsigned int reg,
|
||||
unsigned int field, u32 base)
|
||||
{
|
||||
u16 val;
|
||||
|
||||
/* Set the content of an RTC value from WRDATA by gating iso_en */
|
||||
val = readw(priv->base + reg);
|
||||
writew(val | field, priv->base + reg);
|
||||
writew(base, priv->base + REG_WRDATA_L);
|
||||
writew(base >> 16, priv->base + REG_WRDATA_H);
|
||||
ssd202d_rtc_isoctrl(priv);
|
||||
writew(val & ~field, priv->base + reg);
|
||||
}
|
||||
|
||||
static int ssd202d_rtc_read_counter(struct ssd202d_rtc *priv, unsigned int *counter)
|
||||
{
|
||||
unsigned int l, h;
|
||||
u16 val;
|
||||
|
||||
val = readw(priv->base + REG_CTRL1);
|
||||
writew(val | CNT_RD_BIT, priv->base + REG_CTRL1);
|
||||
ssd202d_rtc_isoctrl(priv);
|
||||
writew(val & ~CNT_RD_BIT, priv->base + REG_CTRL1);
|
||||
|
||||
val = readw(priv->base + REG_CTRL1);
|
||||
writew(val | CNT_RD_TRIG_BIT, priv->base + REG_CNT_TRIG);
|
||||
writew(val & ~CNT_RD_TRIG_BIT, priv->base + REG_CNT_TRIG);
|
||||
|
||||
l = readw(priv->base + REG_RDCNT_L);
|
||||
h = readw(priv->base + REG_RDCNT_H);
|
||||
|
||||
*counter = (h << 16) | l;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ssd202d_rtc_read_time(struct device *dev, struct rtc_time *tm)
|
||||
{
|
||||
struct ssd202d_rtc *priv = dev_get_drvdata(dev);
|
||||
unsigned int sw0, base, counter;
|
||||
u32 seconds;
|
||||
int ret;
|
||||
|
||||
/* Check that RTC is enabled by SW */
|
||||
ssd202d_rtc_read_reg(priv, REG_CTRL, SW0_RD_BIT, &sw0);
|
||||
if (sw0 != 1)
|
||||
return -EINVAL;
|
||||
|
||||
/* Get RTC base value from RDDATA */
|
||||
ssd202d_rtc_read_reg(priv, REG_CTRL, BASE_RD_BIT, &base);
|
||||
/* Get RTC counter value from RDDATA */
|
||||
ret = ssd202d_rtc_read_counter(priv, &counter);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
seconds = base + counter;
|
||||
|
||||
rtc_time64_to_tm(seconds, tm);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ssd202d_rtc_reset_counter(struct ssd202d_rtc *priv)
|
||||
{
|
||||
u16 val;
|
||||
|
||||
val = readw(priv->base + REG_CTRL);
|
||||
writew(val | CNT_RST_BIT, priv->base + REG_CTRL);
|
||||
ssd202d_rtc_isoctrl(priv);
|
||||
writew(val & ~CNT_RST_BIT, priv->base + REG_CTRL);
|
||||
ssd202d_rtc_isoctrl(priv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ssd202d_rtc_set_time(struct device *dev, struct rtc_time *tm)
|
||||
{
|
||||
struct ssd202d_rtc *priv = dev_get_drvdata(dev);
|
||||
unsigned long seconds = rtc_tm_to_time64(tm);
|
||||
|
||||
ssd202d_rtc_write_reg(priv, REG_CTRL, BASE_WR_BIT, seconds);
|
||||
ssd202d_rtc_reset_counter(priv);
|
||||
ssd202d_rtc_write_reg(priv, REG_CTRL, SW0_WR_BIT, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct rtc_class_ops ssd202d_rtc_ops = {
|
||||
.read_time = ssd202d_rtc_read_time,
|
||||
.set_time = ssd202d_rtc_set_time,
|
||||
};
|
||||
|
||||
static int ssd202d_rtc_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct ssd202d_rtc *priv;
|
||||
|
||||
priv = devm_kzalloc(&pdev->dev, sizeof(struct ssd202d_rtc), GFP_KERNEL);
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
|
||||
priv->base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(priv->base))
|
||||
return PTR_ERR(priv->base);
|
||||
|
||||
priv->rtc_dev = devm_rtc_allocate_device(dev);
|
||||
if (IS_ERR(priv->rtc_dev))
|
||||
return PTR_ERR(priv->rtc_dev);
|
||||
|
||||
priv->rtc_dev->ops = &ssd202d_rtc_ops;
|
||||
priv->rtc_dev->range_max = U32_MAX;
|
||||
|
||||
platform_set_drvdata(pdev, priv);
|
||||
|
||||
return devm_rtc_register_device(priv->rtc_dev);
|
||||
}
|
||||
|
||||
static const struct of_device_id ssd202d_rtc_of_match_table[] = {
|
||||
{ .compatible = "mstar,ssd202d-rtc" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, ssd202d_rtc_of_match_table);
|
||||
|
||||
static struct platform_driver ssd202d_rtc_driver = {
|
||||
.probe = ssd202d_rtc_probe,
|
||||
.driver = {
|
||||
.name = "ssd202d-rtc",
|
||||
.of_match_table = ssd202d_rtc_of_match_table,
|
||||
},
|
||||
};
|
||||
module_platform_driver(ssd202d_rtc_driver);
|
||||
|
||||
MODULE_AUTHOR("Daniel Palmer <daniel@thingy.jp>");
|
||||
MODULE_AUTHOR("Romain Perier <romain.perier@gmail.com>");
|
||||
MODULE_DESCRIPTION("MStar SSD202D RTC Driver");
|
||||
MODULE_LICENSE("GPL");
|
Loading…
Reference in New Issue
Block a user