RTC for 4.14

Subsystem:
  - Remove .open() and .release() RTC ops
  - constify i2c_device_id
 
 New driver:
  - Realtek RTD1295
  - Android emulator (goldfish) RTC
 
 Drivers:
  - ds1307: Beginning of a huge cleanup
  - s35390a: handle invalid RTC time
  - sun6i: external oscillator gate support
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEEXx9Viay1+e7J/aM4AyWl4gNJNJIFAlm5YTcACgkQAyWl4gNJ
 NJKetg//Xz4zK3O1uhfz1/yWOSqbBwYxUvHzSDFuD3FtAskFPPFACgJENkj98DMF
 w6nCqq/TXOY+BpqPTebzc68vvHGCvZ/AEKPzvCV1KciQ+ACMFGxH8xHCLox9AdyL
 VtcWftPPwu3W6oNN1azV++XgVtComzfEi4pTcTXdw9EDA5yBK/Xyg3xWZ1QV/Xs5
 /DFCcY69nhaJxmD/To0csmI1KbMbiprvN0vJHtF589Y4KhBfnlZnq3bAx2Coo1kv
 PpPy0e0kLzzlWMtMsiM6I3w5iwuf5o1Vajcg5ylAK0Wjvfgh7DqYX0ZQySw/5eZT
 f1OCqP0GVSugmJ8SFMVxYbXPGgpUETtT6ztB9fsAYdUye3I/xfqmip3A7vcFlrAb
 /R1gTZOyx/uwv3qVRsx0LJVxJQJ7vq/3dJYFiQo80AbPyY+GQT3xPr3z33DcJYJt
 2CL0pd6NfEzgesuVCnpZxF+wNJ+449Jzmxge5klqH1rYQ/IjOXS0qAg5pQRUaRjC
 CGNkjBWT82HN1Y8G++4FpdmHLUjkO07QyAAZiYvHNXX3aMcyl8Az/2kcrl+yq7tl
 03CxveLD8kP1bVsRMEIbx24l4lB93U5HyFTeli9xjBMbxDrBK2NZXCD7g/yI/sbs
 ryUe5W33Xgxm0DJ9CXts0qOf/ommiBoogYk+oxe+AGWdLR1weRo=
 =Xkx1
 -----END PGP SIGNATURE-----

Merge tag 'rtc-4.14' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux

Pull RTC updates from Alexandre Belloni:
 "Subsystem:
   - remove .open() and .release() RTC ops
   - constify i2c_device_id

  New driver:
   - Realtek RTD1295
   - Android emulator (goldfish) RTC

  Drivers:
   - ds1307: Beginning of a huge cleanup
   - s35390a: handle invalid RTC time
   - sun6i: external oscillator gate support"

* tag 'rtc-4.14' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux: (40 commits)
  rtc: ds1307: use octal permissions
  rtc: ds1307: fix braces
  rtc: ds1307: fix alignments and blank lines
  rtc: ds1307: use BIT
  rtc: ds1307: use u32
  rtc: ds1307: use sizeof
  rtc: ds1307: remove regs member
  rtc: Add Realtek RTD1295
  dt-bindings: rtc: Add Realtek RTD1295
  rtc: sun6i: Add support for the external oscillator gate
  rtc: goldfish: Add RTC driver for Android emulator
  dt-bindings: Add device tree binding for Goldfish RTC driver
  rtc: ds1307: add basic support for ds1341 chip
  rtc: ds1307: remove member nvram_offset from struct ds1307
  rtc: ds1307: factor out offset to struct chip_desc
  rtc: ds1307: factor out rtc_ops to struct chip_desc
  rtc: ds1307: factor out irq_handler to struct chip_desc
  rtc: ds1307: improve irq setup
  rtc: ds1307: constify struct chip_desc variables
  rtc: ds1307: improve trickle charger initialization
  ...
This commit is contained in:
Linus Torvalds 2017-09-13 10:56:00 -07:00
commit 561a8eb3e1
26 changed files with 955 additions and 487 deletions

View File

@ -20,13 +20,12 @@ List of legacy properties and respective binding document
1. "enable-sdio-wakeup" Documentation/devicetree/bindings/mmc/mmc.txt
2. "gpio-key,wakeup" Documentation/devicetree/bindings/input/gpio-keys{,-polled}.txt
3. "has-tpo" Documentation/devicetree/bindings/rtc/rtc-opal.txt
4. "isil,irq2-can-wakeup-machine" Documentation/devicetree/bindings/rtc/isil,isl12057.txt
5. "linux,wakeup" Documentation/devicetree/bindings/input/gpio-matrix-keypad.txt
4. "linux,wakeup" Documentation/devicetree/bindings/input/gpio-matrix-keypad.txt
Documentation/devicetree/bindings/mfd/tc3589x.txt
Documentation/devicetree/bindings/input/ads7846.txt
6. "linux,keypad-wakeup" Documentation/devicetree/bindings/input/qcom,pm8xxx-keypad.txt
7. "linux,input-wakeup" Documentation/devicetree/bindings/input/samsung-keypad.txt
8. "nvidia,wakeup-source" Documentation/devicetree/bindings/input/nvidia,tegra20-kbc.txt
5. "linux,keypad-wakeup" Documentation/devicetree/bindings/input/qcom,pm8xxx-keypad.txt
6. "linux,input-wakeup" Documentation/devicetree/bindings/input/samsung-keypad.txt
7. "nvidia,wakeup-source" Documentation/devicetree/bindings/input/nvidia,tegra20-kbc.txt
Examples
--------

View File

@ -0,0 +1,17 @@
Android Goldfish RTC
Android Goldfish RTC device used by Android emulator.
Required properties:
- compatible : should contain "google,goldfish-rtc"
- reg : <registers mapping>
- interrupts : <interrupt mapping>
Example:
goldfish_timer@9020000 {
compatible = "google,goldfish-rtc";
reg = <0x9020000 0x1000>;
interrupts = <0x3>;
};

View File

@ -24,7 +24,6 @@ Optional properties:
- "wakeup-source": mark the chip as a wakeup source, independently of
the availability of an IRQ line connected to the SoC.
(Legacy property supported: "isil,irq2-can-wakeup-machine")
- "interrupt-parent", "interrupts": for passing the interrupt line
of the SoC connected to IRQ#2 of the RTC chip.

View File

@ -0,0 +1,16 @@
Realtek RTD129x Real-Time Clock
===============================
Required properties:
- compatible : Should be "realtek,rtd1295-rtc"
- reg : Specifies the physical base address and size
- clocks : Specifies the clock gate
Example:
rtc@9801b600 {
compatible = "realtek,rtd1295-clk";
reg = <0x9801b600 0x100>;
clocks = <&clkc RTD1295_CLK_EN_MISC_RTC>;
};

View File

@ -10,7 +10,7 @@ Required properties:
Required properties for new device trees
- clocks : phandle to the 32kHz external oscillator
- clock-output-names : name of the LOSC clock created
- clock-output-names : names of the LOSC and its external output clocks created
- #clock-cells : must be equals to 1. The RTC provides two clocks: the
LOSC and its external output, with index 0 and 1
respectively.
@ -21,7 +21,7 @@ rtc: rtc@01f00000 {
compatible = "allwinner,sun6i-a31-rtc";
reg = <0x01f00000 0x54>;
interrupts = <0 40 4>, <0 41 4>;
clock-output-names = "osc32k";
clock-output-names = "osc32k", "osc32k-out";
clocks = <&ext_osc32k>;
#clock-cells = <1>;
};

View File

@ -855,6 +855,12 @@ S: Supported
F: drivers/android/
F: drivers/staging/android/
ANDROID GOLDFISH RTC DRIVER
M: Miodrag Dinic <miodrag.dinic@imgtec.com>
S: Supported
F: Documentation/devicetree/bindings/rtc/google,goldfish-rtc.txt
F: drivers/rtc/rtc-goldfish.c
ANDROID ION DRIVER
M: Laura Abbott <labbott@redhat.com>
M: Sumit Semwal <sumit.semwal@linaro.org>

View File

@ -227,14 +227,14 @@ config RTC_DRV_AS3722
will be called rtc-as3722.
config RTC_DRV_DS1307
tristate "Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSON RX-8025, ISL12057"
tristate "Dallas/Maxim DS1307/37/38/39/40/41, ST M41T00, EPSON RX-8025, ISL12057"
help
If you say yes here you get support for various compatible RTC
chips (often with battery backup) connected with I2C. This driver
should handle DS1307, DS1337, DS1338, DS1339, DS1340, ST M41T00,
EPSON RX-8025, Intersil ISL12057 and probably other chips. In some
cases the RTC must already have been initialized (by manufacturing or
a bootloader).
should handle DS1307, DS1337, DS1338, DS1339, DS1340, DS1341,
ST M41T00, EPSON RX-8025, Intersil ISL12057 and probably other chips.
In some cases the RTC must already have been initialized (by
manufacturing or a bootloader).
The first seven registers on these chips hold an RTC, and other
registers may add features such as NVRAM, a trickle charger for
@ -371,11 +371,11 @@ config RTC_DRV_MAX77686
will be called rtc-max77686.
config RTC_DRV_RK808
tristate "Rockchip RK808/RK818 RTC"
tristate "Rockchip RK805/RK808/RK818 RTC"
depends on MFD_RK808
help
If you say yes here you will get support for the
RTC of RK808 and RK818 PMIC.
RTC of RK805, RK808 and RK818 PMIC.
This driver can also be built as a module. If so, the module
will be called rk808-rtc.
@ -1765,6 +1765,14 @@ config RTC_DRV_CPCAP
Say y here for CPCAP rtc found on some Motorola phones
and tablets such as Droid 4.
config RTC_DRV_RTD119X
bool "Realtek RTD129x RTC"
depends on ARCH_REALTEK || COMPILE_TEST
default ARCH_REALTEK
help
If you say yes here, you get support for the RTD1295 SoC
Real Time Clock.
comment "HID Sensor RTC drivers"
config RTC_DRV_HID_SENSOR_TIME
@ -1780,5 +1788,13 @@ config RTC_DRV_HID_SENSOR_TIME
If this driver is compiled as a module, it will be named
rtc-hid-sensor-time.
config RTC_DRV_GOLDFISH
tristate "Goldfish Real Time Clock"
depends on MIPS && (GOLDFISH || COMPILE_TEST)
help
Say yes to enable RTC driver for the Goldfish based virtual platform.
Goldfish is a code name for the virtual platform developed by Google
for Android emulation.
endif # RTC_CLASS

View File

@ -131,6 +131,7 @@ obj-$(CONFIG_RTC_DRV_RP5C01) += rtc-rp5c01.o
obj-$(CONFIG_RTC_DRV_RS5C313) += rtc-rs5c313.o
obj-$(CONFIG_RTC_DRV_RS5C348) += rtc-rs5c348.o
obj-$(CONFIG_RTC_DRV_RS5C372) += rtc-rs5c372.o
obj-$(CONFIG_RTC_DRV_RTD119X) += rtc-rtd119x.o
obj-$(CONFIG_RTC_DRV_RV3029C2) += rtc-rv3029c2.o
obj-$(CONFIG_RTC_DRV_RV8803) += rtc-rv8803.o
obj-$(CONFIG_RTC_DRV_RX4581) += rtc-rx4581.o
@ -170,3 +171,4 @@ obj-$(CONFIG_RTC_DRV_WM8350) += rtc-wm8350.o
obj-$(CONFIG_RTC_DRV_X1205) += rtc-x1205.o
obj-$(CONFIG_RTC_DRV_XGENE) += rtc-xgene.o
obj-$(CONFIG_RTC_DRV_ZYNQMP) += rtc-zynqmp.o
obj-$(CONFIG_RTC_DRV_GOLDFISH) += rtc-goldfish.o

View File

@ -24,18 +24,14 @@ static dev_t rtc_devt;
static int rtc_dev_open(struct inode *inode, struct file *file)
{
int err;
struct rtc_device *rtc = container_of(inode->i_cdev,
struct rtc_device, char_dev);
const struct rtc_class_ops *ops = rtc->ops;
if (test_and_set_bit_lock(RTC_DEV_BUSY, &rtc->flags))
return -EBUSY;
file->private_data = rtc;
err = ops->open ? ops->open(rtc->dev.parent) : 0;
if (err == 0) {
spin_lock_irq(&rtc->irq_lock);
rtc->irq_data = 0;
spin_unlock_irq(&rtc->irq_lock);
@ -43,11 +39,6 @@ static int rtc_dev_open(struct inode *inode, struct file *file)
return 0;
}
/* something has gone wrong */
clear_bit_unlock(RTC_DEV_BUSY, &rtc->flags);
return err;
}
#ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL
/*
* Routine to poll RTC seconds field for change as often as possible,
@ -438,9 +429,6 @@ static int rtc_dev_release(struct inode *inode, struct file *file)
rtc_update_irq_enable(rtc, 0);
rtc_irq_set_state(rtc, NULL, 0);
if (rtc->ops->release)
rtc->ops->release(rtc->dev.parent);
clear_bit_unlock(RTC_DEV_BUSY, &rtc->flags);
return 0;
}

View File

@ -39,6 +39,7 @@ enum ds_type {
ds_1338,
ds_1339,
ds_1340,
ds_1341,
ds_1388,
ds_3231,
m41t0,
@ -50,7 +51,6 @@ enum ds_type {
/* rs5c372 too? different address... */
};
/* RTC registers don't differ much, except for the century flag */
#define DS1307_REG_SECS 0x00 /* 00-59 */
# define DS1307_BIT_CH 0x80
@ -113,11 +113,7 @@ enum ds_type {
# define RX8025_BIT_VDET 0x40
# define RX8025_BIT_XST 0x20
struct ds1307 {
u8 offset; /* register's offset */
u8 regs[11];
u16 nvram_offset;
struct nvmem_config nvmem_cfg;
enum ds_type type;
unsigned long flags;
@ -126,7 +122,6 @@ struct ds1307 {
struct device *dev;
struct regmap *regmap;
const char *name;
int irq;
struct rtc_device *rtc;
#ifdef CONFIG_COMMON_CLK
struct clk_hw clks[2];
@ -137,18 +132,47 @@ struct chip_desc {
unsigned alarm:1;
u16 nvram_offset;
u16 nvram_size;
u8 offset; /* register's offset */
u8 century_reg;
u8 century_enable_bit;
u8 century_bit;
u8 bbsqi_bit;
irq_handler_t irq_handler;
const struct rtc_class_ops *rtc_ops;
u16 trickle_charger_reg;
u8 trickle_charger_setup;
u8 (*do_trickle_setup)(struct ds1307 *, uint32_t,
u8 (*do_trickle_setup)(struct ds1307 *, u32,
bool);
};
static u8 do_trickle_setup_ds1339(struct ds1307 *, uint32_t ohms, bool diode);
static int ds1307_get_time(struct device *dev, struct rtc_time *t);
static int ds1307_set_time(struct device *dev, struct rtc_time *t);
static u8 do_trickle_setup_ds1339(struct ds1307 *, u32 ohms, bool diode);
static irqreturn_t rx8130_irq(int irq, void *dev_id);
static int rx8130_read_alarm(struct device *dev, struct rtc_wkalrm *t);
static int rx8130_set_alarm(struct device *dev, struct rtc_wkalrm *t);
static int rx8130_alarm_irq_enable(struct device *dev, unsigned int enabled);
static irqreturn_t mcp794xx_irq(int irq, void *dev_id);
static int mcp794xx_read_alarm(struct device *dev, struct rtc_wkalrm *t);
static int mcp794xx_set_alarm(struct device *dev, struct rtc_wkalrm *t);
static int mcp794xx_alarm_irq_enable(struct device *dev, unsigned int enabled);
static struct chip_desc chips[last_ds_type] = {
static const struct rtc_class_ops rx8130_rtc_ops = {
.read_time = ds1307_get_time,
.set_time = ds1307_set_time,
.read_alarm = rx8130_read_alarm,
.set_alarm = rx8130_set_alarm,
.alarm_irq_enable = rx8130_alarm_irq_enable,
};
static const struct rtc_class_ops mcp794xx_rtc_ops = {
.read_time = ds1307_get_time,
.set_time = ds1307_set_time,
.read_alarm = mcp794xx_read_alarm,
.set_alarm = mcp794xx_set_alarm,
.alarm_irq_enable = mcp794xx_alarm_irq_enable,
};
static const struct chip_desc chips[last_ds_type] = {
[ds_1307] = {
.nvram_offset = 8,
.nvram_size = 56,
@ -170,6 +194,7 @@ static struct chip_desc chips[last_ds_type] = {
.alarm = 1,
.century_reg = DS1307_REG_MONTH,
.century_bit = DS1337_BIT_CENTURY,
.bbsqi_bit = DS1339_BIT_BBSQI,
.trickle_charger_reg = 0x10,
.do_trickle_setup = &do_trickle_setup_ds1339,
},
@ -179,25 +204,36 @@ static struct chip_desc chips[last_ds_type] = {
.century_bit = DS1340_BIT_CENTURY,
.trickle_charger_reg = 0x08,
},
[ds_1341] = {
.century_reg = DS1307_REG_MONTH,
.century_bit = DS1337_BIT_CENTURY,
},
[ds_1388] = {
.offset = 1,
.trickle_charger_reg = 0x0a,
},
[ds_3231] = {
.alarm = 1,
.century_reg = DS1307_REG_MONTH,
.century_bit = DS1337_BIT_CENTURY,
.bbsqi_bit = DS3231_BIT_BBSQW,
},
[rx_8130] = {
.alarm = 1,
/* this is battery backed SRAM */
.nvram_offset = 0x20,
.nvram_size = 4, /* 32bit (4 word x 8 bit) */
.offset = 0x10,
.irq_handler = rx8130_irq,
.rtc_ops = &rx8130_rtc_ops,
},
[mcp794xx] = {
.alarm = 1,
/* this is battery backed SRAM */
.nvram_offset = 0x20,
.nvram_size = 0x40,
.irq_handler = mcp794xx_irq,
.rtc_ops = &mcp794xx_rtc_ops,
},
};
@ -209,6 +245,7 @@ static const struct i2c_device_id ds1307_id[] = {
{ "ds1339", ds_1339 },
{ "ds1388", ds_1388 },
{ "ds1340", ds_1340 },
{ "ds1341", ds_1341 },
{ "ds3231", ds_3231 },
{ "m41t0", m41t0 },
{ "m41t00", m41t00 },
@ -252,6 +289,10 @@ static const struct of_device_id ds1307_of_match[] = {
.compatible = "dallas,ds1340",
.data = (void *)ds_1340
},
{
.compatible = "dallas,ds1341",
.data = (void *)ds_1341
},
{
.compatible = "maxim,ds3231",
.data = (void *)ds_3231
@ -298,6 +339,7 @@ static const struct acpi_device_id ds1307_acpi_ids[] = {
{ .id = "DS1339", .driver_data = ds_1339 },
{ .id = "DS1388", .driver_data = ds_1388 },
{ .id = "DS1340", .driver_data = ds_1340 },
{ .id = "DS1341", .driver_data = ds_1341 },
{ .id = "DS3231", .driver_data = ds_3231 },
{ .id = "M41T0", .driver_data = m41t0 },
{ .id = "M41T00", .driver_data = m41t00 },
@ -352,34 +394,36 @@ static int ds1307_get_time(struct device *dev, struct rtc_time *t)
struct ds1307 *ds1307 = dev_get_drvdata(dev);
int tmp, ret;
const struct chip_desc *chip = &chips[ds1307->type];
u8 regs[7];
/* read the RTC date and time registers all at once */
ret = regmap_bulk_read(ds1307->regmap, ds1307->offset, ds1307->regs, 7);
ret = regmap_bulk_read(ds1307->regmap, chip->offset, regs,
sizeof(regs));
if (ret) {
dev_err(dev, "%s error %d\n", "read", ret);
return ret;
}
dev_dbg(dev, "%s: %7ph\n", "read", ds1307->regs);
dev_dbg(dev, "%s: %7ph\n", "read", regs);
/* if oscillator fail bit is set, no data can be trusted */
if (ds1307->type == m41t0 &&
ds1307->regs[DS1307_REG_MIN] & M41T0_BIT_OF) {
regs[DS1307_REG_MIN] & M41T0_BIT_OF) {
dev_warn_once(dev, "oscillator failed, set time!\n");
return -EINVAL;
}
t->tm_sec = bcd2bin(ds1307->regs[DS1307_REG_SECS] & 0x7f);
t->tm_min = bcd2bin(ds1307->regs[DS1307_REG_MIN] & 0x7f);
tmp = ds1307->regs[DS1307_REG_HOUR] & 0x3f;
t->tm_sec = bcd2bin(regs[DS1307_REG_SECS] & 0x7f);
t->tm_min = bcd2bin(regs[DS1307_REG_MIN] & 0x7f);
tmp = regs[DS1307_REG_HOUR] & 0x3f;
t->tm_hour = bcd2bin(tmp);
t->tm_wday = bcd2bin(ds1307->regs[DS1307_REG_WDAY] & 0x07) - 1;
t->tm_mday = bcd2bin(ds1307->regs[DS1307_REG_MDAY] & 0x3f);
tmp = ds1307->regs[DS1307_REG_MONTH] & 0x1f;
t->tm_wday = bcd2bin(regs[DS1307_REG_WDAY] & 0x07) - 1;
t->tm_mday = bcd2bin(regs[DS1307_REG_MDAY] & 0x3f);
tmp = regs[DS1307_REG_MONTH] & 0x1f;
t->tm_mon = bcd2bin(tmp) - 1;
t->tm_year = bcd2bin(ds1307->regs[DS1307_REG_YEAR]) + 100;
t->tm_year = bcd2bin(regs[DS1307_REG_YEAR]) + 100;
if (ds1307->regs[chip->century_reg] & chip->century_bit &&
if (regs[chip->century_reg] & chip->century_bit &&
IS_ENABLED(CONFIG_RTC_DRV_DS1307_CENTURY))
t->tm_year += 100;
@ -399,7 +443,7 @@ static int ds1307_set_time(struct device *dev, struct rtc_time *t)
const struct chip_desc *chip = &chips[ds1307->type];
int result;
int tmp;
u8 *buf = ds1307->regs;
u8 regs[7];
dev_dbg(dev, "%s secs=%d, mins=%d, "
"hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n",
@ -418,35 +462,36 @@ static int ds1307_set_time(struct device *dev, struct rtc_time *t)
return -EINVAL;
#endif
buf[DS1307_REG_SECS] = bin2bcd(t->tm_sec);
buf[DS1307_REG_MIN] = bin2bcd(t->tm_min);
buf[DS1307_REG_HOUR] = bin2bcd(t->tm_hour);
buf[DS1307_REG_WDAY] = bin2bcd(t->tm_wday + 1);
buf[DS1307_REG_MDAY] = bin2bcd(t->tm_mday);
buf[DS1307_REG_MONTH] = bin2bcd(t->tm_mon + 1);
regs[DS1307_REG_SECS] = bin2bcd(t->tm_sec);
regs[DS1307_REG_MIN] = bin2bcd(t->tm_min);
regs[DS1307_REG_HOUR] = bin2bcd(t->tm_hour);
regs[DS1307_REG_WDAY] = bin2bcd(t->tm_wday + 1);
regs[DS1307_REG_MDAY] = bin2bcd(t->tm_mday);
regs[DS1307_REG_MONTH] = bin2bcd(t->tm_mon + 1);
/* assume 20YY not 19YY */
tmp = t->tm_year - 100;
buf[DS1307_REG_YEAR] = bin2bcd(tmp);
regs[DS1307_REG_YEAR] = bin2bcd(tmp);
if (chip->century_enable_bit)
buf[chip->century_reg] |= chip->century_enable_bit;
regs[chip->century_reg] |= chip->century_enable_bit;
if (t->tm_year > 199 && chip->century_bit)
buf[chip->century_reg] |= chip->century_bit;
regs[chip->century_reg] |= chip->century_bit;
if (ds1307->type == mcp794xx) {
/*
* these bits were cleared when preparing the date/time
* values and need to be set again before writing the
* buffer out to the device.
* regsfer out to the device.
*/
buf[DS1307_REG_SECS] |= MCP794XX_BIT_ST;
buf[DS1307_REG_WDAY] |= MCP794XX_BIT_VBATEN;
regs[DS1307_REG_SECS] |= MCP794XX_BIT_ST;
regs[DS1307_REG_WDAY] |= MCP794XX_BIT_VBATEN;
}
dev_dbg(dev, "%s: %7ph\n", "write", buf);
dev_dbg(dev, "%s: %7ph\n", "write", regs);
result = regmap_bulk_write(ds1307->regmap, ds1307->offset, buf, 7);
result = regmap_bulk_write(ds1307->regmap, chip->offset, regs,
sizeof(regs));
if (result) {
dev_err(dev, "%s error %d\n", "write", result);
return result;
@ -458,33 +503,34 @@ static int ds1337_read_alarm(struct device *dev, struct rtc_wkalrm *t)
{
struct ds1307 *ds1307 = dev_get_drvdata(dev);
int ret;
u8 regs[9];
if (!test_bit(HAS_ALARM, &ds1307->flags))
return -EINVAL;
/* read all ALARM1, ALARM2, and status registers at once */
ret = regmap_bulk_read(ds1307->regmap, DS1339_REG_ALARM1_SECS,
ds1307->regs, 9);
regs, sizeof(regs));
if (ret) {
dev_err(dev, "%s error %d\n", "alarm read", ret);
return ret;
}
dev_dbg(dev, "%s: %4ph, %3ph, %2ph\n", "alarm read",
&ds1307->regs[0], &ds1307->regs[4], &ds1307->regs[7]);
&regs[0], &regs[4], &regs[7]);
/*
* report alarm time (ALARM1); assume 24 hour and day-of-month modes,
* and that all four fields are checked matches
*/
t->time.tm_sec = bcd2bin(ds1307->regs[0] & 0x7f);
t->time.tm_min = bcd2bin(ds1307->regs[1] & 0x7f);
t->time.tm_hour = bcd2bin(ds1307->regs[2] & 0x3f);
t->time.tm_mday = bcd2bin(ds1307->regs[3] & 0x3f);
t->time.tm_sec = bcd2bin(regs[0] & 0x7f);
t->time.tm_min = bcd2bin(regs[1] & 0x7f);
t->time.tm_hour = bcd2bin(regs[2] & 0x3f);
t->time.tm_mday = bcd2bin(regs[3] & 0x3f);
/* ... and status */
t->enabled = !!(ds1307->regs[7] & DS1337_BIT_A1IE);
t->pending = !!(ds1307->regs[8] & DS1337_BIT_A1I);
t->enabled = !!(regs[7] & DS1337_BIT_A1IE);
t->pending = !!(regs[8] & DS1337_BIT_A1I);
dev_dbg(dev, "%s secs=%d, mins=%d, "
"hours=%d, mday=%d, enabled=%d, pending=%d\n",
@ -498,7 +544,7 @@ static int ds1337_read_alarm(struct device *dev, struct rtc_wkalrm *t)
static int ds1337_set_alarm(struct device *dev, struct rtc_wkalrm *t)
{
struct ds1307 *ds1307 = dev_get_drvdata(dev);
unsigned char *buf = ds1307->regs;
unsigned char regs[9];
u8 control, status;
int ret;
@ -512,33 +558,35 @@ static int ds1337_set_alarm(struct device *dev, struct rtc_wkalrm *t)
t->enabled, t->pending);
/* read current status of both alarms and the chip */
ret = regmap_bulk_read(ds1307->regmap, DS1339_REG_ALARM1_SECS, buf, 9);
ret = regmap_bulk_read(ds1307->regmap, DS1339_REG_ALARM1_SECS, regs,
sizeof(regs));
if (ret) {
dev_err(dev, "%s error %d\n", "alarm write", ret);
return ret;
}
control = ds1307->regs[7];
status = ds1307->regs[8];
control = regs[7];
status = regs[8];
dev_dbg(dev, "%s: %4ph, %3ph, %02x %02x\n", "alarm set (old status)",
&ds1307->regs[0], &ds1307->regs[4], control, status);
&regs[0], &regs[4], control, status);
/* set ALARM1, using 24 hour and day-of-month modes */
buf[0] = bin2bcd(t->time.tm_sec);
buf[1] = bin2bcd(t->time.tm_min);
buf[2] = bin2bcd(t->time.tm_hour);
buf[3] = bin2bcd(t->time.tm_mday);
regs[0] = bin2bcd(t->time.tm_sec);
regs[1] = bin2bcd(t->time.tm_min);
regs[2] = bin2bcd(t->time.tm_hour);
regs[3] = bin2bcd(t->time.tm_mday);
/* set ALARM2 to non-garbage */
buf[4] = 0;
buf[5] = 0;
buf[6] = 0;
regs[4] = 0;
regs[5] = 0;
regs[6] = 0;
/* disable alarms */
buf[7] = control & ~(DS1337_BIT_A1IE | DS1337_BIT_A2IE);
buf[8] = status & ~(DS1337_BIT_A1I | DS1337_BIT_A2I);
regs[7] = control & ~(DS1337_BIT_A1IE | DS1337_BIT_A2IE);
regs[8] = status & ~(DS1337_BIT_A1I | DS1337_BIT_A2I);
ret = regmap_bulk_write(ds1307->regmap, DS1339_REG_ALARM1_SECS, buf, 9);
ret = regmap_bulk_write(ds1307->regmap, DS1339_REG_ALARM1_SECS, regs,
sizeof(regs));
if (ret) {
dev_err(dev, "can't set alarm time\n");
return ret;
@ -547,8 +595,8 @@ static int ds1337_set_alarm(struct device *dev, struct rtc_wkalrm *t)
/* optionally enable ALARM1 */
if (t->enabled) {
dev_dbg(dev, "alarm IRQ armed\n");
buf[7] |= DS1337_BIT_A1IE; /* only ALARM1 is used */
regmap_write(ds1307->regmap, DS1337_REG_CONTROL, buf[7]);
regs[7] |= DS1337_BIT_A1IE; /* only ALARM1 is used */
regmap_write(ds1307->regmap, DS1337_REG_CONTROL, regs[7]);
}
return 0;
@ -584,11 +632,11 @@ static const struct rtc_class_ops ds13xx_rtc_ops = {
#define RX8130_REG_ALARM_HOUR 0x08
#define RX8130_REG_ALARM_WEEK_OR_DAY 0x09
#define RX8130_REG_EXTENSION 0x0c
#define RX8130_REG_EXTENSION_WADA (1 << 3)
#define RX8130_REG_EXTENSION_WADA BIT(3)
#define RX8130_REG_FLAG 0x0d
#define RX8130_REG_FLAG_AF (1 << 3)
#define RX8130_REG_FLAG_AF BIT(3)
#define RX8130_REG_CONTROL0 0x0e
#define RX8130_REG_CONTROL0_AIE (1 << 3)
#define RX8130_REG_CONTROL0_AIE BIT(3)
static irqreturn_t rx8130_irq(int irq, void *dev_id)
{
@ -600,7 +648,8 @@ static irqreturn_t rx8130_irq(int irq, void *dev_id)
mutex_lock(lock);
/* Read control registers. */
ret = regmap_bulk_read(ds1307->regmap, RX8130_REG_EXTENSION, ctl, 3);
ret = regmap_bulk_read(ds1307->regmap, RX8130_REG_EXTENSION, ctl,
sizeof(ctl));
if (ret < 0)
goto out;
if (!(ctl[1] & RX8130_REG_FLAG_AF))
@ -608,7 +657,8 @@ static irqreturn_t rx8130_irq(int irq, void *dev_id)
ctl[1] &= ~RX8130_REG_FLAG_AF;
ctl[2] &= ~RX8130_REG_CONTROL0_AIE;
ret = regmap_bulk_write(ds1307->regmap, RX8130_REG_EXTENSION, ctl, 3);
ret = regmap_bulk_write(ds1307->regmap, RX8130_REG_EXTENSION, ctl,
sizeof(ctl));
if (ret < 0)
goto out;
@ -630,12 +680,14 @@ static int rx8130_read_alarm(struct device *dev, struct rtc_wkalrm *t)
return -EINVAL;
/* Read alarm registers. */
ret = regmap_bulk_read(ds1307->regmap, RX8130_REG_ALARM_MIN, ald, 3);
ret = regmap_bulk_read(ds1307->regmap, RX8130_REG_ALARM_MIN, ald,
sizeof(ald));
if (ret < 0)
return ret;
/* Read control registers. */
ret = regmap_bulk_read(ds1307->regmap, RX8130_REG_EXTENSION, ctl, 3);
ret = regmap_bulk_read(ds1307->regmap, RX8130_REG_EXTENSION, ctl,
sizeof(ctl));
if (ret < 0)
return ret;
@ -676,7 +728,8 @@ static int rx8130_set_alarm(struct device *dev, struct rtc_wkalrm *t)
t->enabled, t->pending);
/* Read control registers. */
ret = regmap_bulk_read(ds1307->regmap, RX8130_REG_EXTENSION, ctl, 3);
ret = regmap_bulk_read(ds1307->regmap, RX8130_REG_EXTENSION, ctl,
sizeof(ctl));
if (ret < 0)
return ret;
@ -684,7 +737,8 @@ static int rx8130_set_alarm(struct device *dev, struct rtc_wkalrm *t)
ctl[1] |= RX8130_REG_FLAG_AF;
ctl[2] &= ~RX8130_REG_CONTROL0_AIE;
ret = regmap_bulk_write(ds1307->regmap, RX8130_REG_EXTENSION, ctl, 3);
ret = regmap_bulk_write(ds1307->regmap, RX8130_REG_EXTENSION, ctl,
sizeof(ctl));
if (ret < 0)
return ret;
@ -693,7 +747,8 @@ static int rx8130_set_alarm(struct device *dev, struct rtc_wkalrm *t)
ald[1] = bin2bcd(t->time.tm_hour);
ald[2] = bin2bcd(t->time.tm_mday);
ret = regmap_bulk_write(ds1307->regmap, RX8130_REG_ALARM_MIN, ald, 3);
ret = regmap_bulk_write(ds1307->regmap, RX8130_REG_ALARM_MIN, ald,
sizeof(ald));
if (ret < 0)
return ret;
@ -702,7 +757,8 @@ static int rx8130_set_alarm(struct device *dev, struct rtc_wkalrm *t)
ctl[2] |= RX8130_REG_CONTROL0_AIE;
return regmap_bulk_write(ds1307->regmap, RX8130_REG_EXTENSION, ctl, 3);
return regmap_bulk_write(ds1307->regmap, RX8130_REG_EXTENSION, ctl,
sizeof(ctl));
}
static int rx8130_alarm_irq_enable(struct device *dev, unsigned int enabled)
@ -725,14 +781,6 @@ static int rx8130_alarm_irq_enable(struct device *dev, unsigned int enabled)
return regmap_write(ds1307->regmap, RX8130_REG_CONTROL0, reg);
}
static const struct rtc_class_ops rx8130_rtc_ops = {
.read_time = ds1307_get_time,
.set_time = ds1307_set_time,
.read_alarm = rx8130_read_alarm,
.set_alarm = rx8130_set_alarm,
.alarm_irq_enable = rx8130_alarm_irq_enable,
};
/*----------------------------------------------------------------------*/
/*
@ -748,11 +796,11 @@ static const struct rtc_class_ops rx8130_rtc_ops = {
#define MCP794XX_REG_ALARM0_CTRL 0x0d
#define MCP794XX_REG_ALARM1_BASE 0x11
#define MCP794XX_REG_ALARM1_CTRL 0x14
# define MCP794XX_BIT_ALMX_IF (1 << 3)
# define MCP794XX_BIT_ALMX_C0 (1 << 4)
# define MCP794XX_BIT_ALMX_C1 (1 << 5)
# define MCP794XX_BIT_ALMX_C2 (1 << 6)
# define MCP794XX_BIT_ALMX_POL (1 << 7)
# define MCP794XX_BIT_ALMX_IF BIT(3)
# define MCP794XX_BIT_ALMX_C0 BIT(4)
# define MCP794XX_BIT_ALMX_C1 BIT(5)
# define MCP794XX_BIT_ALMX_C2 BIT(6)
# define MCP794XX_BIT_ALMX_POL BIT(7)
# define MCP794XX_MSK_ALMX_MATCH (MCP794XX_BIT_ALMX_C0 | \
MCP794XX_BIT_ALMX_C1 | \
MCP794XX_BIT_ALMX_C2)
@ -793,37 +841,38 @@ static irqreturn_t mcp794xx_irq(int irq, void *dev_id)
static int mcp794xx_read_alarm(struct device *dev, struct rtc_wkalrm *t)
{
struct ds1307 *ds1307 = dev_get_drvdata(dev);
u8 *regs = ds1307->regs;
u8 regs[10];
int ret;
if (!test_bit(HAS_ALARM, &ds1307->flags))
return -EINVAL;
/* Read control and alarm 0 registers. */
ret = regmap_bulk_read(ds1307->regmap, MCP794XX_REG_CONTROL, regs, 10);
ret = regmap_bulk_read(ds1307->regmap, MCP794XX_REG_CONTROL, regs,
sizeof(regs));
if (ret)
return ret;
t->enabled = !!(regs[0] & MCP794XX_BIT_ALM0_EN);
/* Report alarm 0 time assuming 24-hour and day-of-month modes. */
t->time.tm_sec = bcd2bin(ds1307->regs[3] & 0x7f);
t->time.tm_min = bcd2bin(ds1307->regs[4] & 0x7f);
t->time.tm_hour = bcd2bin(ds1307->regs[5] & 0x3f);
t->time.tm_wday = bcd2bin(ds1307->regs[6] & 0x7) - 1;
t->time.tm_mday = bcd2bin(ds1307->regs[7] & 0x3f);
t->time.tm_mon = bcd2bin(ds1307->regs[8] & 0x1f) - 1;
t->time.tm_sec = bcd2bin(regs[3] & 0x7f);
t->time.tm_min = bcd2bin(regs[4] & 0x7f);
t->time.tm_hour = bcd2bin(regs[5] & 0x3f);
t->time.tm_wday = bcd2bin(regs[6] & 0x7) - 1;
t->time.tm_mday = bcd2bin(regs[7] & 0x3f);
t->time.tm_mon = bcd2bin(regs[8] & 0x1f) - 1;
t->time.tm_year = -1;
t->time.tm_yday = -1;
t->time.tm_isdst = -1;
dev_dbg(dev, "%s, sec=%d min=%d hour=%d wday=%d mday=%d mon=%d "
"enabled=%d polarity=%d irq=%d match=%d\n", __func__,
"enabled=%d polarity=%d irq=%d match=%lu\n", __func__,
t->time.tm_sec, t->time.tm_min, t->time.tm_hour,
t->time.tm_wday, t->time.tm_mday, t->time.tm_mon, t->enabled,
!!(ds1307->regs[6] & MCP794XX_BIT_ALMX_POL),
!!(ds1307->regs[6] & MCP794XX_BIT_ALMX_IF),
(ds1307->regs[6] & MCP794XX_MSK_ALMX_MATCH) >> 4);
!!(regs[6] & MCP794XX_BIT_ALMX_POL),
!!(regs[6] & MCP794XX_BIT_ALMX_IF),
(regs[6] & MCP794XX_MSK_ALMX_MATCH) >> 4);
return 0;
}
@ -831,7 +880,7 @@ static int mcp794xx_read_alarm(struct device *dev, struct rtc_wkalrm *t)
static int mcp794xx_set_alarm(struct device *dev, struct rtc_wkalrm *t)
{
struct ds1307 *ds1307 = dev_get_drvdata(dev);
unsigned char *regs = ds1307->regs;
unsigned char regs[10];
int ret;
if (!test_bit(HAS_ALARM, &ds1307->flags))
@ -844,7 +893,8 @@ static int mcp794xx_set_alarm(struct device *dev, struct rtc_wkalrm *t)
t->enabled, t->pending);
/* Read control and alarm 0 registers. */
ret = regmap_bulk_read(ds1307->regmap, MCP794XX_REG_CONTROL, regs, 10);
ret = regmap_bulk_read(ds1307->regmap, MCP794XX_REG_CONTROL, regs,
sizeof(regs));
if (ret)
return ret;
@ -863,7 +913,8 @@ static int mcp794xx_set_alarm(struct device *dev, struct rtc_wkalrm *t)
/* Disable interrupt. We will not enable until completely programmed */
regs[0] &= ~MCP794XX_BIT_ALM0_EN;
ret = regmap_bulk_write(ds1307->regmap, MCP794XX_REG_CONTROL, regs, 10);
ret = regmap_bulk_write(ds1307->regmap, MCP794XX_REG_CONTROL, regs,
sizeof(regs));
if (ret)
return ret;
@ -885,22 +936,15 @@ static int mcp794xx_alarm_irq_enable(struct device *dev, unsigned int enabled)
enabled ? MCP794XX_BIT_ALM0_EN : 0);
}
static const struct rtc_class_ops mcp794xx_rtc_ops = {
.read_time = ds1307_get_time,
.set_time = ds1307_set_time,
.read_alarm = mcp794xx_read_alarm,
.set_alarm = mcp794xx_set_alarm,
.alarm_irq_enable = mcp794xx_alarm_irq_enable,
};
/*----------------------------------------------------------------------*/
static int ds1307_nvram_read(void *priv, unsigned int offset, void *val,
size_t bytes)
{
struct ds1307 *ds1307 = priv;
const struct chip_desc *chip = &chips[ds1307->type];
return regmap_bulk_read(ds1307->regmap, ds1307->nvram_offset + offset,
return regmap_bulk_read(ds1307->regmap, chip->nvram_offset + offset,
val, bytes);
}
@ -908,15 +952,16 @@ static int ds1307_nvram_write(void *priv, unsigned int offset, void *val,
size_t bytes)
{
struct ds1307 *ds1307 = priv;
const struct chip_desc *chip = &chips[ds1307->type];
return regmap_bulk_write(ds1307->regmap, ds1307->nvram_offset + offset,
return regmap_bulk_write(ds1307->regmap, chip->nvram_offset + offset,
val, bytes);
}
/*----------------------------------------------------------------------*/
static u8 do_trickle_setup_ds1339(struct ds1307 *ds1307,
uint32_t ohms, bool diode)
u32 ohms, bool diode)
{
u8 setup = (diode) ? DS1307_TRICKLE_CHARGER_DIODE :
DS1307_TRICKLE_CHARGER_NO_DIODE;
@ -939,23 +984,23 @@ static u8 do_trickle_setup_ds1339(struct ds1307 *ds1307,
return setup;
}
static void ds1307_trickle_init(struct ds1307 *ds1307,
struct chip_desc *chip)
static u8 ds1307_trickle_init(struct ds1307 *ds1307,
const struct chip_desc *chip)
{
uint32_t ohms = 0;
u32 ohms;
bool diode = true;
if (!chip->do_trickle_setup)
goto out;
return 0;
if (device_property_read_u32(ds1307->dev, "trickle-resistor-ohms",
&ohms))
goto out;
return 0;
if (device_property_read_bool(ds1307->dev, "trickle-diode-disable"))
diode = false;
chip->trickle_charger_setup = chip->do_trickle_setup(ds1307,
ohms, diode);
out:
return;
return chip->do_trickle_setup(ds1307, ohms, diode);
}
/*----------------------------------------------------------------------*/
@ -1006,7 +1051,7 @@ static ssize_t ds3231_hwmon_show_temp(struct device *dev,
return sprintf(buf, "%d\n", temp);
}
static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, ds3231_hwmon_show_temp,
static SENSOR_DEVICE_ATTR(temp1_input, 0444, ds3231_hwmon_show_temp,
NULL, 0);
static struct attribute *ds3231_hwmon_attrs[] = {
@ -1023,7 +1068,8 @@ static void ds1307_hwmon_register(struct ds1307 *ds1307)
return;
dev = devm_hwmon_device_register_with_groups(ds1307->dev, ds1307->name,
ds1307, ds3231_hwmon_groups);
ds1307,
ds3231_hwmon_groups);
if (IS_ERR(dev)) {
dev_warn(ds1307->dev, "unable to register hwmon device %ld\n",
PTR_ERR(dev));
@ -1309,22 +1355,14 @@ static int ds1307_probe(struct i2c_client *client,
struct ds1307 *ds1307;
int err = -ENODEV;
int tmp, wday;
struct chip_desc *chip;
bool want_irq = false;
const struct chip_desc *chip;
bool want_irq;
bool ds1307_can_wakeup_device = false;
unsigned char *buf;
unsigned char regs[8];
struct ds1307_platform_data *pdata = dev_get_platdata(&client->dev);
struct rtc_time tm;
unsigned long timestamp;
irq_handler_t irq_handler = ds1307_irq;
static const int bbsqi_bitpos[] = {
[ds_1337] = 0,
[ds_1339] = DS1339_BIT_BBSQI,
[ds_3231] = DS3231_BIT_BBSQW,
};
const struct rtc_class_ops *rtc_ops = &ds13xx_rtc_ops;
u8 trickle_charger_setup = 0;
ds1307 = devm_kzalloc(&client->dev, sizeof(struct ds1307), GFP_KERNEL);
if (!ds1307)
@ -1333,7 +1371,6 @@ static int ds1307_probe(struct i2c_client *client,
dev_set_drvdata(&client->dev, ds1307);
ds1307->dev = &client->dev;
ds1307->name = client->name;
ds1307->irq = client->irq;
ds1307->regmap = devm_regmap_init_i2c(client, &regmap_config);
if (IS_ERR(ds1307->regmap)) {
@ -1361,23 +1398,22 @@ static int ds1307_probe(struct i2c_client *client,
ds1307->type = acpi_id->driver_data;
}
if (!pdata)
ds1307_trickle_init(ds1307, chip);
else if (pdata->trickle_charger_setup)
chip->trickle_charger_setup = pdata->trickle_charger_setup;
want_irq = client->irq > 0 && chip->alarm;
if (chip->trickle_charger_setup && chip->trickle_charger_reg) {
if (!pdata)
trickle_charger_setup = ds1307_trickle_init(ds1307, chip);
else if (pdata->trickle_charger_setup)
trickle_charger_setup = pdata->trickle_charger_setup;
if (trickle_charger_setup && chip->trickle_charger_reg) {
trickle_charger_setup |= DS13XX_TRICKLE_CHARGER_MAGIC;
dev_dbg(ds1307->dev,
"writing trickle charger info 0x%x to 0x%x\n",
DS13XX_TRICKLE_CHARGER_MAGIC | chip->trickle_charger_setup,
chip->trickle_charger_reg);
trickle_charger_setup, chip->trickle_charger_reg);
regmap_write(ds1307->regmap, chip->trickle_charger_reg,
DS13XX_TRICKLE_CHARGER_MAGIC |
chip->trickle_charger_setup);
trickle_charger_setup);
}
buf = ds1307->regs;
#ifdef CONFIG_OF
/*
* For devices with no IRQ directly connected to the SoC, the RTC chip
@ -1387,31 +1423,27 @@ static int ds1307_probe(struct i2c_client *client,
* This will guarantee the 'wakealarm' sysfs entry is available on the device,
* if supported by the RTC.
*/
if (of_property_read_bool(client->dev.of_node, "wakeup-source")) {
if (chip->alarm && of_property_read_bool(client->dev.of_node,
"wakeup-source"))
ds1307_can_wakeup_device = true;
}
/* Intersil ISL12057 DT backward compatibility */
if (of_property_read_bool(client->dev.of_node,
"isil,irq2-can-wakeup-machine")) {
ds1307_can_wakeup_device = true;
}
#endif
switch (ds1307->type) {
case ds_1337:
case ds_1339:
case ds_1341:
case ds_3231:
/* get registers that the "rtc" read below won't read... */
err = regmap_bulk_read(ds1307->regmap, DS1337_REG_CONTROL,
buf, 2);
regs, 2);
if (err) {
dev_dbg(ds1307->dev, "read error %d\n", err);
goto exit;
}
/* oscillator off? turn it on, so clock can tick. */
if (ds1307->regs[0] & DS1337_BIT_nEOSC)
ds1307->regs[0] &= ~DS1337_BIT_nEOSC;
if (regs[0] & DS1337_BIT_nEOSC)
regs[0] &= ~DS1337_BIT_nEOSC;
/*
* Using IRQ or defined as wakeup-source?
@ -1419,114 +1451,92 @@ static int ds1307_probe(struct i2c_client *client,
* For some variants, be sure alarms can trigger when we're
* running on Vbackup (BBSQI/BBSQW)
*/
if (chip->alarm && (ds1307->irq > 0 ||
ds1307_can_wakeup_device)) {
ds1307->regs[0] |= DS1337_BIT_INTCN
| bbsqi_bitpos[ds1307->type];
ds1307->regs[0] &= ~(DS1337_BIT_A2IE | DS1337_BIT_A1IE);
want_irq = true;
if (want_irq || ds1307_can_wakeup_device) {
regs[0] |= DS1337_BIT_INTCN | chip->bbsqi_bit;
regs[0] &= ~(DS1337_BIT_A2IE | DS1337_BIT_A1IE);
}
regmap_write(ds1307->regmap, DS1337_REG_CONTROL,
ds1307->regs[0]);
regs[0]);
/* oscillator fault? clear flag, and warn */
if (ds1307->regs[1] & DS1337_BIT_OSF) {
if (regs[1] & DS1337_BIT_OSF) {
regmap_write(ds1307->regmap, DS1337_REG_STATUS,
ds1307->regs[1] & ~DS1337_BIT_OSF);
regs[1] & ~DS1337_BIT_OSF);
dev_warn(ds1307->dev, "SET TIME!\n");
}
break;
case rx_8025:
err = regmap_bulk_read(ds1307->regmap,
RX8025_REG_CTRL1 << 4 | 0x08, buf, 2);
RX8025_REG_CTRL1 << 4 | 0x08, regs, 2);
if (err) {
dev_dbg(ds1307->dev, "read error %d\n", err);
goto exit;
}
/* oscillator off? turn it on, so clock can tick. */
if (!(ds1307->regs[1] & RX8025_BIT_XST)) {
ds1307->regs[1] |= RX8025_BIT_XST;
if (!(regs[1] & RX8025_BIT_XST)) {
regs[1] |= RX8025_BIT_XST;
regmap_write(ds1307->regmap,
RX8025_REG_CTRL2 << 4 | 0x08,
ds1307->regs[1]);
regs[1]);
dev_warn(ds1307->dev,
"oscillator stop detected - SET TIME!\n");
}
if (ds1307->regs[1] & RX8025_BIT_PON) {
ds1307->regs[1] &= ~RX8025_BIT_PON;
if (regs[1] & RX8025_BIT_PON) {
regs[1] &= ~RX8025_BIT_PON;
regmap_write(ds1307->regmap,
RX8025_REG_CTRL2 << 4 | 0x08,
ds1307->regs[1]);
regs[1]);
dev_warn(ds1307->dev, "power-on detected\n");
}
if (ds1307->regs[1] & RX8025_BIT_VDET) {
ds1307->regs[1] &= ~RX8025_BIT_VDET;
if (regs[1] & RX8025_BIT_VDET) {
regs[1] &= ~RX8025_BIT_VDET;
regmap_write(ds1307->regmap,
RX8025_REG_CTRL2 << 4 | 0x08,
ds1307->regs[1]);
regs[1]);
dev_warn(ds1307->dev, "voltage drop detected\n");
}
/* make sure we are running in 24hour mode */
if (!(ds1307->regs[0] & RX8025_BIT_2412)) {
if (!(regs[0] & RX8025_BIT_2412)) {
u8 hour;
/* switch to 24 hour mode */
regmap_write(ds1307->regmap,
RX8025_REG_CTRL1 << 4 | 0x08,
ds1307->regs[0] | RX8025_BIT_2412);
regs[0] | RX8025_BIT_2412);
err = regmap_bulk_read(ds1307->regmap,
RX8025_REG_CTRL1 << 4 | 0x08,
buf, 2);
regs, 2);
if (err) {
dev_dbg(ds1307->dev, "read error %d\n", err);
goto exit;
}
/* correct hour */
hour = bcd2bin(ds1307->regs[DS1307_REG_HOUR]);
hour = bcd2bin(regs[DS1307_REG_HOUR]);
if (hour == 12)
hour = 0;
if (ds1307->regs[DS1307_REG_HOUR] & DS1307_BIT_PM)
if (regs[DS1307_REG_HOUR] & DS1307_BIT_PM)
hour += 12;
regmap_write(ds1307->regmap,
DS1307_REG_HOUR << 4 | 0x08, hour);
}
break;
case rx_8130:
ds1307->offset = 0x10; /* Seconds starts at 0x10 */
rtc_ops = &rx8130_rtc_ops;
if (chip->alarm && ds1307->irq > 0) {
irq_handler = rx8130_irq;
want_irq = true;
}
break;
case ds_1388:
ds1307->offset = 1; /* Seconds starts at 1 */
break;
case mcp794xx:
rtc_ops = &mcp794xx_rtc_ops;
if (chip->alarm && (ds1307->irq > 0 ||
ds1307_can_wakeup_device)) {
irq_handler = mcp794xx_irq;
want_irq = true;
}
break;
default:
break;
}
read_rtc:
/* read RTC registers */
err = regmap_bulk_read(ds1307->regmap, ds1307->offset, buf, 8);
err = regmap_bulk_read(ds1307->regmap, chip->offset, regs,
sizeof(regs));
if (err) {
dev_dbg(ds1307->dev, "read error %d\n", err);
goto exit;
@ -1537,7 +1547,7 @@ static int ds1307_probe(struct i2c_client *client,
* specify the extra bits as must-be-zero, but there are
* still a few values that are clearly out-of-range.
*/
tmp = ds1307->regs[DS1307_REG_SECS];
tmp = regs[DS1307_REG_SECS];
switch (ds1307->type) {
case ds_1307:
case m41t0:
@ -1556,9 +1566,9 @@ static int ds1307_probe(struct i2c_client *client,
regmap_write(ds1307->regmap, DS1307_REG_SECS, 0);
/* oscillator fault? clear flag, and warn */
if (ds1307->regs[DS1307_REG_CONTROL] & DS1338_BIT_OSF) {
if (regs[DS1307_REG_CONTROL] & DS1338_BIT_OSF) {
regmap_write(ds1307->regmap, DS1307_REG_CONTROL,
ds1307->regs[DS1307_REG_CONTROL] &
regs[DS1307_REG_CONTROL] &
~DS1338_BIT_OSF);
dev_warn(ds1307->dev, "SET TIME!\n");
goto read_rtc;
@ -1583,9 +1593,9 @@ static int ds1307_probe(struct i2c_client *client,
break;
case mcp794xx:
/* make sure that the backup battery is enabled */
if (!(ds1307->regs[DS1307_REG_WDAY] & MCP794XX_BIT_VBATEN)) {
if (!(regs[DS1307_REG_WDAY] & MCP794XX_BIT_VBATEN)) {
regmap_write(ds1307->regmap, DS1307_REG_WDAY,
ds1307->regs[DS1307_REG_WDAY] |
regs[DS1307_REG_WDAY] |
MCP794XX_BIT_VBATEN);
}
@ -1602,7 +1612,7 @@ static int ds1307_probe(struct i2c_client *client,
break;
}
tmp = ds1307->regs[DS1307_REG_HOUR];
tmp = regs[DS1307_REG_HOUR];
switch (ds1307->type) {
case ds_1340:
case m41t0:
@ -1625,9 +1635,9 @@ static int ds1307_probe(struct i2c_client *client,
tmp = bcd2bin(tmp & 0x1f);
if (tmp == 12)
tmp = 0;
if (ds1307->regs[DS1307_REG_HOUR] & DS1307_BIT_PM)
if (regs[DS1307_REG_HOUR] & DS1307_BIT_PM)
tmp += 12;
regmap_write(ds1307->regmap, ds1307->offset + DS1307_REG_HOUR,
regmap_write(ds1307->regmap, chip->offset + DS1307_REG_HOUR,
bin2bcd(tmp));
}
@ -1650,19 +1660,16 @@ static int ds1307_probe(struct i2c_client *client,
MCP794XX_REG_WEEKDAY_WDAY_MASK,
tm.tm_wday + 1);
if (want_irq) {
if (want_irq || ds1307_can_wakeup_device) {
device_set_wakeup_capable(ds1307->dev, true);
set_bit(HAS_ALARM, &ds1307->flags);
}
ds1307->rtc = devm_rtc_allocate_device(ds1307->dev);
if (IS_ERR(ds1307->rtc)) {
if (IS_ERR(ds1307->rtc))
return PTR_ERR(ds1307->rtc);
}
if (ds1307_can_wakeup_device && ds1307->irq <= 0) {
/* Disable request for an IRQ */
want_irq = false;
if (ds1307_can_wakeup_device && !want_irq) {
dev_info(ds1307->dev,
"'wakeup-source' is set, request for an IRQ is disabled!\n");
/* We cannot support UIE mode if we do not have an IRQ line */
@ -1670,8 +1677,8 @@ static int ds1307_probe(struct i2c_client *client,
}
if (want_irq) {
err = devm_request_threaded_irq(ds1307->dev,
ds1307->irq, NULL, irq_handler,
err = devm_request_threaded_irq(ds1307->dev, client->irq, NULL,
chip->irq_handler ?: ds1307_irq,
IRQF_SHARED | IRQF_ONESHOT,
ds1307->name, ds1307);
if (err) {
@ -1679,9 +1686,10 @@ static int ds1307_probe(struct i2c_client *client,
device_set_wakeup_capable(ds1307->dev, false);
clear_bit(HAS_ALARM, &ds1307->flags);
dev_err(ds1307->dev, "unable to request IRQ!\n");
} else
} else {
dev_dbg(ds1307->dev, "got IRQ %d\n", client->irq);
}
}
if (chip->nvram_size) {
ds1307->nvmem_cfg.name = "ds1307_nvram";
@ -1691,13 +1699,12 @@ static int ds1307_probe(struct i2c_client *client,
ds1307->nvmem_cfg.reg_read = ds1307_nvram_read;
ds1307->nvmem_cfg.reg_write = ds1307_nvram_write;
ds1307->nvmem_cfg.priv = ds1307;
ds1307->nvram_offset = chip->nvram_offset;
ds1307->rtc->nvmem_config = &ds1307->nvmem_cfg;
ds1307->rtc->nvram_old_abi = true;
}
ds1307->rtc->ops = rtc_ops;
ds1307->rtc->ops = chip->rtc_ops ?: &ds13xx_rtc_ops;
err = rtc_register_device(ds1307->rtc);
if (err)
return err;

View File

@ -190,7 +190,7 @@ static int ds1672_probe(struct i2c_client *client,
return 0;
}
static struct i2c_device_id ds1672_id[] = {
static const struct i2c_device_id ds1672_id[] = {
{ "ds1672", 0 },
{ }
};

View File

@ -132,7 +132,7 @@ static int em3027_probe(struct i2c_client *client,
return 0;
}
static struct i2c_device_id em3027_id[] = {
static const struct i2c_device_id em3027_id[] = {
{ "em3027", 0 },
{ }
};

237
drivers/rtc/rtc-goldfish.c Normal file
View File

@ -0,0 +1,237 @@
/* drivers/rtc/rtc-goldfish.c
*
* Copyright (C) 2007 Google, Inc.
* Copyright (C) 2017 Imagination Technologies Ltd.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/rtc.h>
#include <linux/io.h>
#define TIMER_TIME_LOW 0x00 /* get low bits of current time */
/* and update TIMER_TIME_HIGH */
#define TIMER_TIME_HIGH 0x04 /* get high bits of time at last */
/* TIMER_TIME_LOW read */
#define TIMER_ALARM_LOW 0x08 /* set low bits of alarm and */
/* activate it */
#define TIMER_ALARM_HIGH 0x0c /* set high bits of next alarm */
#define TIMER_IRQ_ENABLED 0x10
#define TIMER_CLEAR_ALARM 0x14
#define TIMER_ALARM_STATUS 0x18
#define TIMER_CLEAR_INTERRUPT 0x1c
struct goldfish_rtc {
void __iomem *base;
int irq;
struct rtc_device *rtc;
};
static int goldfish_rtc_read_alarm(struct device *dev,
struct rtc_wkalrm *alrm)
{
u64 rtc_alarm;
u64 rtc_alarm_low;
u64 rtc_alarm_high;
void __iomem *base;
struct goldfish_rtc *rtcdrv;
rtcdrv = dev_get_drvdata(dev);
base = rtcdrv->base;
rtc_alarm_low = readl(base + TIMER_ALARM_LOW);
rtc_alarm_high = readl(base + TIMER_ALARM_HIGH);
rtc_alarm = (rtc_alarm_high << 32) | rtc_alarm_low;
do_div(rtc_alarm, NSEC_PER_SEC);
memset(alrm, 0, sizeof(struct rtc_wkalrm));
rtc_time_to_tm(rtc_alarm, &alrm->time);
if (readl(base + TIMER_ALARM_STATUS))
alrm->enabled = 1;
else
alrm->enabled = 0;
return 0;
}
static int goldfish_rtc_set_alarm(struct device *dev,
struct rtc_wkalrm *alrm)
{
struct goldfish_rtc *rtcdrv;
unsigned long rtc_alarm;
u64 rtc_alarm64;
u64 rtc_status_reg;
void __iomem *base;
int ret = 0;
rtcdrv = dev_get_drvdata(dev);
base = rtcdrv->base;
if (alrm->enabled) {
ret = rtc_tm_to_time(&alrm->time, &rtc_alarm);
if (ret != 0)
return ret;
rtc_alarm64 = rtc_alarm * NSEC_PER_SEC;
writel((rtc_alarm64 >> 32), base + TIMER_ALARM_HIGH);
writel(rtc_alarm64, base + TIMER_ALARM_LOW);
} else {
/*
* if this function was called with enabled=0
* then it could mean that the application is
* trying to cancel an ongoing alarm
*/
rtc_status_reg = readl(base + TIMER_ALARM_STATUS);
if (rtc_status_reg)
writel(1, base + TIMER_CLEAR_ALARM);
}
return ret;
}
static int goldfish_rtc_alarm_irq_enable(struct device *dev,
unsigned int enabled)
{
void __iomem *base;
struct goldfish_rtc *rtcdrv;
rtcdrv = dev_get_drvdata(dev);
base = rtcdrv->base;
if (enabled)
writel(1, base + TIMER_IRQ_ENABLED);
else
writel(0, base + TIMER_IRQ_ENABLED);
return 0;
}
static irqreturn_t goldfish_rtc_interrupt(int irq, void *dev_id)
{
struct goldfish_rtc *rtcdrv = dev_id;
void __iomem *base = rtcdrv->base;
writel(1, base + TIMER_CLEAR_INTERRUPT);
rtc_update_irq(rtcdrv->rtc, 1, RTC_IRQF | RTC_AF);
return IRQ_HANDLED;
}
static int goldfish_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
struct goldfish_rtc *rtcdrv;
void __iomem *base;
u64 time_high;
u64 time_low;
u64 time;
rtcdrv = dev_get_drvdata(dev);
base = rtcdrv->base;
time_low = readl(base + TIMER_TIME_LOW);
time_high = readl(base + TIMER_TIME_HIGH);
time = (time_high << 32) | time_low;
do_div(time, NSEC_PER_SEC);
rtc_time_to_tm(time, tm);
return 0;
}
static int goldfish_rtc_set_time(struct device *dev, struct rtc_time *tm)
{
struct goldfish_rtc *rtcdrv;
void __iomem *base;
unsigned long now;
u64 now64;
int ret;
rtcdrv = dev_get_drvdata(dev);
base = rtcdrv->base;
ret = rtc_tm_to_time(tm, &now);
if (ret == 0) {
now64 = now * NSEC_PER_SEC;
writel((now64 >> 32), base + TIMER_TIME_HIGH);
writel(now64, base + TIMER_TIME_LOW);
}
return ret;
}
static const struct rtc_class_ops goldfish_rtc_ops = {
.read_time = goldfish_rtc_read_time,
.set_time = goldfish_rtc_set_time,
.read_alarm = goldfish_rtc_read_alarm,
.set_alarm = goldfish_rtc_set_alarm,
.alarm_irq_enable = goldfish_rtc_alarm_irq_enable
};
static int goldfish_rtc_probe(struct platform_device *pdev)
{
struct goldfish_rtc *rtcdrv;
struct resource *r;
int err;
rtcdrv = devm_kzalloc(&pdev->dev, sizeof(*rtcdrv), GFP_KERNEL);
if (!rtcdrv)
return -ENOMEM;
platform_set_drvdata(pdev, rtcdrv);
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!r)
return -ENODEV;
rtcdrv->base = devm_ioremap_resource(&pdev->dev, r);
if (IS_ERR(rtcdrv->base))
return -ENODEV;
rtcdrv->irq = platform_get_irq(pdev, 0);
if (rtcdrv->irq < 0)
return -ENODEV;
rtcdrv->rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
&goldfish_rtc_ops,
THIS_MODULE);
if (IS_ERR(rtcdrv->rtc))
return PTR_ERR(rtcdrv->rtc);
err = devm_request_irq(&pdev->dev, rtcdrv->irq,
goldfish_rtc_interrupt,
0, pdev->name, rtcdrv);
if (err)
return err;
return 0;
}
static const struct of_device_id goldfish_rtc_of_match[] = {
{ .compatible = "google,goldfish-rtc", },
{},
};
MODULE_DEVICE_TABLE(of, goldfish_rtc_of_match);
static struct platform_driver goldfish_rtc = {
.probe = goldfish_rtc_probe,
.driver = {
.name = "goldfish_rtc",
.of_match_table = goldfish_rtc_of_match,
}
};
module_platform_driver(goldfish_rtc);

View File

@ -440,28 +440,6 @@ static int m41t80_resume(struct device *dev)
static SIMPLE_DEV_PM_OPS(m41t80_pm, m41t80_suspend, m41t80_resume);
static ssize_t flags_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct i2c_client *client = to_i2c_client(dev);
int val;
val = i2c_smbus_read_byte_data(client, M41T80_REG_FLAGS);
if (val < 0)
return val;
return sprintf(buf, "%#x\n", val);
}
static DEVICE_ATTR_RO(flags);
static struct attribute *attrs[] = {
&dev_attr_flags.attr,
NULL,
};
static struct attribute_group attr_group = {
.attrs = attrs,
};
#ifdef CONFIG_COMMON_CLK
#define sqw_to_m41t80_data(_hw) container_of(_hw, struct m41t80_data, sqw)
@ -912,13 +890,6 @@ static struct notifier_block wdt_notifier = {
*****************************************************************************
*/
static void m41t80_remove_sysfs_group(void *_dev)
{
struct device *dev = _dev;
sysfs_remove_group(&dev->kobj, &attr_group);
}
static int m41t80_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
@ -927,6 +898,7 @@ static int m41t80_probe(struct i2c_client *client,
struct rtc_device *rtc = NULL;
struct rtc_time tm;
struct m41t80_data *m41t80_data = NULL;
bool wakeup_source = false;
if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK |
I2C_FUNC_SMBUS_BYTE_DATA)) {
@ -947,6 +919,10 @@ static int m41t80_probe(struct i2c_client *client,
m41t80_data->features = id->driver_data;
i2c_set_clientdata(client, m41t80_data);
#ifdef CONFIG_OF
wakeup_source = of_property_read_bool(client->dev.of_node,
"wakeup-source");
#endif
if (client->irq > 0) {
rc = devm_request_threaded_irq(&client->dev, client->irq,
NULL, m41t80_handle_irq,
@ -955,14 +931,16 @@ static int m41t80_probe(struct i2c_client *client,
if (rc) {
dev_warn(&client->dev, "unable to request IRQ, alarms disabled\n");
client->irq = 0;
} else {
wakeup_source = false;
}
}
if (client->irq > 0 || wakeup_source) {
m41t80_rtc_ops.read_alarm = m41t80_read_alarm;
m41t80_rtc_ops.set_alarm = m41t80_set_alarm;
m41t80_rtc_ops.alarm_irq_enable = m41t80_alarm_irq_enable;
/* Enable the wakealarm */
device_init_wakeup(&client->dev, true);
}
}
rtc = devm_rtc_device_register(&client->dev, client->name,
&m41t80_rtc_ops, THIS_MODULE);
@ -970,6 +948,10 @@ static int m41t80_probe(struct i2c_client *client,
return PTR_ERR(rtc);
m41t80_data->rtc = rtc;
if (client->irq <= 0) {
/* We cannot support UIE mode if we do not have an IRQ line */
rtc->uie_unsupported = 1;
}
/* Make sure HT (Halt Update) bit is cleared */
rc = i2c_smbus_read_byte_data(client, M41T80_REG_ALARM_HOUR);
@ -1004,21 +986,6 @@ static int m41t80_probe(struct i2c_client *client,
return rc;
}
/* Export sysfs entries */
rc = sysfs_create_group(&(&client->dev)->kobj, &attr_group);
if (rc) {
dev_err(&client->dev, "Failed to create sysfs group: %d\n", rc);
return rc;
}
rc = devm_add_action_or_reset(&client->dev, m41t80_remove_sysfs_group,
&client->dev);
if (rc) {
dev_err(&client->dev,
"Failed to add sysfs cleanup action: %d\n", rc);
return rc;
}
#ifdef CONFIG_RTC_DRV_M41T80_WDT
if (m41t80_data->features & M41T80_FEATURE_HT) {
save_client = client;

View File

@ -226,7 +226,7 @@ max6900_probe(struct i2c_client *client, const struct i2c_device_id *id)
return 0;
}
static struct i2c_device_id max6900_id[] = {
static const struct i2c_device_id max6900_id[] = {
{ "max6900", 0 },
{ }
};

View File

@ -234,8 +234,6 @@ static int max8925_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
ret = max8925_reg_write(info->rtc, MAX8925_ALARM0_CNTL, 0x77);
else
ret = max8925_reg_write(info->rtc, MAX8925_ALARM0_CNTL, 0x0);
if (ret < 0)
goto out;
out:
return ret;
}

View File

@ -238,26 +238,6 @@ static irqreturn_t mxc_rtc_interrupt(int irq, void *dev_id)
return IRQ_HANDLED;
}
/*
* Clear all interrupts and release the IRQ
*/
static void mxc_rtc_release(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
void __iomem *ioaddr = pdata->ioaddr;
spin_lock_irq(&pdata->rtc->irq_lock);
/* Disable all rtc interrupts */
writew(0, ioaddr + RTC_RTCIENR);
/* Clear all interrupt status */
writew(0xffffffff, ioaddr + RTC_RTCISR);
spin_unlock_irq(&pdata->rtc->irq_lock);
}
static int mxc_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
{
mxc_rtc_irq_enable(dev, RTC_ALM_BIT, enabled);
@ -343,7 +323,6 @@ static int mxc_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
/* RTC layer */
static const struct rtc_class_ops mxc_rtc_ops = {
.release = mxc_rtc_release,
.read_time = mxc_rtc_read_time,
.set_mmss64 = mxc_rtc_set_mmss,
.read_alarm = mxc_rtc_read_alarm,

View File

@ -157,49 +157,7 @@ static int puv3_rtc_proc(struct device *dev, struct seq_file *seq)
return 0;
}
static int puv3_rtc_open(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct rtc_device *rtc_dev = platform_get_drvdata(pdev);
int ret;
ret = request_irq(puv3_rtc_alarmno, puv3_rtc_alarmirq,
0, "pkunity-rtc alarm", rtc_dev);
if (ret) {
dev_err(dev, "IRQ%d error %d\n", puv3_rtc_alarmno, ret);
return ret;
}
ret = request_irq(puv3_rtc_tickno, puv3_rtc_tickirq,
0, "pkunity-rtc tick", rtc_dev);
if (ret) {
dev_err(dev, "IRQ%d error %d\n", puv3_rtc_tickno, ret);
goto tick_err;
}
return ret;
tick_err:
free_irq(puv3_rtc_alarmno, rtc_dev);
return ret;
}
static void puv3_rtc_release(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct rtc_device *rtc_dev = platform_get_drvdata(pdev);
/* do not clear AIE here, it may be needed for wake */
puv3_rtc_setpie(dev, 0);
free_irq(puv3_rtc_alarmno, rtc_dev);
free_irq(puv3_rtc_tickno, rtc_dev);
}
static const struct rtc_class_ops puv3_rtcops = {
.open = puv3_rtc_open,
.release = puv3_rtc_release,
.read_time = puv3_rtc_gettime,
.set_time = puv3_rtc_settime,
.read_alarm = puv3_rtc_getalarm,
@ -222,10 +180,6 @@ static void puv3_rtc_enable(struct device *dev, int en)
static int puv3_rtc_remove(struct platform_device *dev)
{
struct rtc_device *rtc = platform_get_drvdata(dev);
rtc_device_unregister(rtc);
puv3_rtc_setpie(&dev->dev, 0);
puv3_rtc_setaie(&dev->dev, 0);
@ -259,6 +213,24 @@ static int puv3_rtc_probe(struct platform_device *pdev)
dev_dbg(&pdev->dev, "PKUnity_rtc: tick irq %d, alarm irq %d\n",
puv3_rtc_tickno, puv3_rtc_alarmno);
rtc = devm_rtc_allocate_device(&pdev->dev);
if (IS_ERR(rtc))
return PTR_ERR(rtc);
ret = devm_request_irq(&pdev->dev, puv3_rtc_alarmno, puv3_rtc_alarmirq,
0, "pkunity-rtc alarm", rtc);
if (ret) {
dev_err(&pdev->dev, "IRQ%d error %d\n", puv3_rtc_alarmno, ret);
return ret;
}
ret = devm_request_irq(&pdev->dev, puv3_rtc_tickno, puv3_rtc_tickirq,
0, "pkunity-rtc tick", rtc);
if (ret) {
dev_err(&pdev->dev, "IRQ%d error %d\n", puv3_rtc_tickno, ret);
return ret;
}
/* get the memory region */
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (res == NULL) {
@ -278,12 +250,10 @@ static int puv3_rtc_probe(struct platform_device *pdev)
puv3_rtc_enable(&pdev->dev, 1);
/* register RTC and exit */
rtc = rtc_device_register("pkunity", &pdev->dev, &puv3_rtcops,
THIS_MODULE);
if (IS_ERR(rtc)) {
rtc->ops = &puv3_rtcops;
ret = rtc_register_device(rtc);
if (ret) {
dev_err(&pdev->dev, "cannot attach rtc\n");
ret = PTR_ERR(rtc);
goto err_nortc;
}

View File

@ -348,7 +348,7 @@ static int __init pxa_rtc_probe(struct platform_device *pdev)
dev_err(dev, "No alarm IRQ resource defined\n");
return -ENXIO;
}
pxa_rtc_open(dev);
pxa_rtc->base = devm_ioremap(dev, pxa_rtc->ress->start,
resource_size(pxa_rtc->ress));
if (!pxa_rtc->base) {
@ -356,6 +356,8 @@ static int __init pxa_rtc_probe(struct platform_device *pdev)
return -ENOMEM;
}
pxa_rtc_open(dev);
sa1100_rtc->rcnr = pxa_rtc->base + 0x0;
sa1100_rtc->rtsr = pxa_rtc->base + 0x8;
sa1100_rtc->rtar = pxa_rtc->base + 0x4;

242
drivers/rtc/rtc-rtd119x.c Normal file
View File

@ -0,0 +1,242 @@
/*
* Realtek RTD129x RTC
*
* Copyright (c) 2017 Andreas Färber
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/platform_device.h>
#include <linux/rtc.h>
#include <linux/spinlock.h>
#define RTD_RTCSEC 0x00
#define RTD_RTCMIN 0x04
#define RTD_RTCHR 0x08
#define RTD_RTCDATE1 0x0c
#define RTD_RTCDATE2 0x10
#define RTD_RTCACR 0x28
#define RTD_RTCEN 0x2c
#define RTD_RTCCR 0x30
#define RTD_RTCSEC_RTCSEC_MASK 0x7f
#define RTD_RTCMIN_RTCMIN_MASK 0x3f
#define RTD_RTCHR_RTCHR_MASK 0x1f
#define RTD_RTCDATE1_RTCDATE1_MASK 0xff
#define RTD_RTCDATE2_RTCDATE2_MASK 0x7f
#define RTD_RTCACR_RTCPWR BIT(7)
#define RTD_RTCEN_RTCEN_MASK 0xff
#define RTD_RTCCR_RTCRST BIT(6)
struct rtd119x_rtc {
void __iomem *base;
struct clk *clk;
struct rtc_device *rtcdev;
unsigned int base_year;
};
static inline int rtd119x_rtc_days_in_year(int year)
{
return 365 + (is_leap_year(year) ? 1 : 0);
}
static void rtd119x_rtc_reset(struct device *dev)
{
struct rtd119x_rtc *data = dev_get_drvdata(dev);
u32 val;
val = readl_relaxed(data->base + RTD_RTCCR);
val |= RTD_RTCCR_RTCRST;
writel_relaxed(val, data->base + RTD_RTCCR);
val &= ~RTD_RTCCR_RTCRST;
writel(val, data->base + RTD_RTCCR);
}
static void rtd119x_rtc_set_enabled(struct device *dev, bool enable)
{
struct rtd119x_rtc *data = dev_get_drvdata(dev);
u32 val;
val = readl_relaxed(data->base + RTD_RTCEN);
if (enable) {
if ((val & RTD_RTCEN_RTCEN_MASK) == 0x5a)
return;
writel_relaxed(0x5a, data->base + RTD_RTCEN);
} else {
writel_relaxed(0, data->base + RTD_RTCEN);
}
}
static int rtd119x_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
struct rtd119x_rtc *data = dev_get_drvdata(dev);
s32 day;
u32 sec;
unsigned int year;
int tries = 0;
while (true) {
tm->tm_sec = (readl_relaxed(data->base + RTD_RTCSEC) & RTD_RTCSEC_RTCSEC_MASK) >> 1;
tm->tm_min = readl_relaxed(data->base + RTD_RTCMIN) & RTD_RTCMIN_RTCMIN_MASK;
tm->tm_hour = readl_relaxed(data->base + RTD_RTCHR) & RTD_RTCHR_RTCHR_MASK;
day = readl_relaxed(data->base + RTD_RTCDATE1) & RTD_RTCDATE1_RTCDATE1_MASK;
day |= (readl_relaxed(data->base + RTD_RTCDATE2) & RTD_RTCDATE2_RTCDATE2_MASK) << 8;
sec = (readl_relaxed(data->base + RTD_RTCSEC) & RTD_RTCSEC_RTCSEC_MASK) >> 1;
tries++;
if (sec == tm->tm_sec)
break;
if (tries >= 3)
return -EINVAL;
}
if (tries > 1)
dev_dbg(dev, "%s: needed %i tries\n", __func__, tries);
year = data->base_year;
while (day >= rtd119x_rtc_days_in_year(year)) {
day -= rtd119x_rtc_days_in_year(year);
year++;
}
tm->tm_year = year - 1900;
tm->tm_yday = day;
tm->tm_mon = 0;
while (day >= rtc_month_days(tm->tm_mon, year)) {
day -= rtc_month_days(tm->tm_mon, year);
tm->tm_mon++;
}
tm->tm_mday = day + 1;
return 0;
}
static int rtd119x_rtc_set_time(struct device *dev, struct rtc_time *tm)
{
struct rtd119x_rtc *data = dev_get_drvdata(dev);
unsigned int day;
int i;
if (1900 + tm->tm_year < data->base_year)
return -EINVAL;
day = 0;
for (i = data->base_year; i < 1900 + tm->tm_year; i++)
day += rtd119x_rtc_days_in_year(i);
day += tm->tm_yday;
if (day > 0x7fff)
return -EINVAL;
rtd119x_rtc_set_enabled(dev, false);
writel_relaxed((tm->tm_sec << 1) & RTD_RTCSEC_RTCSEC_MASK, data->base + RTD_RTCSEC);
writel_relaxed(tm->tm_min & RTD_RTCMIN_RTCMIN_MASK, data->base + RTD_RTCMIN);
writel_relaxed(tm->tm_hour & RTD_RTCHR_RTCHR_MASK, data->base + RTD_RTCHR);
writel_relaxed(day & RTD_RTCDATE1_RTCDATE1_MASK, data->base + RTD_RTCDATE1);
writel_relaxed((day >> 8) & RTD_RTCDATE2_RTCDATE2_MASK, data->base + RTD_RTCDATE2);
rtd119x_rtc_set_enabled(dev, true);
return 0;
}
static const struct rtc_class_ops rtd119x_rtc_ops = {
.read_time = rtd119x_rtc_read_time,
.set_time = rtd119x_rtc_set_time,
};
static const struct of_device_id rtd119x_rtc_dt_ids[] = {
{ .compatible = "realtek,rtd1295-rtc" },
{ }
};
static int rtd119x_rtc_probe(struct platform_device *pdev)
{
struct rtd119x_rtc *data;
struct resource *res;
u32 val;
int ret;
data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
if (!data)
return -ENOMEM;
platform_set_drvdata(pdev, data);
data->base_year = 2014;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
data->base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(data->base))
return PTR_ERR(data->base);
data->clk = of_clk_get(pdev->dev.of_node, 0);
if (IS_ERR(data->clk))
return PTR_ERR(data->clk);
ret = clk_prepare_enable(data->clk);
if (ret) {
clk_put(data->clk);
return ret;
}
val = readl_relaxed(data->base + RTD_RTCACR);
if (!(val & RTD_RTCACR_RTCPWR)) {
writel_relaxed(RTD_RTCACR_RTCPWR, data->base + RTD_RTCACR);
rtd119x_rtc_reset(&pdev->dev);
writel_relaxed(0, data->base + RTD_RTCMIN);
writel_relaxed(0, data->base + RTD_RTCHR);
writel_relaxed(0, data->base + RTD_RTCDATE1);
writel_relaxed(0, data->base + RTD_RTCDATE2);
}
rtd119x_rtc_set_enabled(&pdev->dev, true);
data->rtcdev = devm_rtc_device_register(&pdev->dev, "rtc",
&rtd119x_rtc_ops, THIS_MODULE);
if (IS_ERR(data->rtcdev)) {
dev_err(&pdev->dev, "failed to register rtc device");
clk_disable_unprepare(data->clk);
clk_put(data->clk);
return PTR_ERR(data->rtcdev);
}
return 0;
}
static int rtd119x_rtc_remove(struct platform_device *pdev)
{
struct rtd119x_rtc *data = platform_get_drvdata(pdev);
rtd119x_rtc_set_enabled(&pdev->dev, false);
clk_disable_unprepare(data->clk);
clk_put(data->clk);
return 0;
}
static struct platform_driver rtd119x_rtc_driver = {
.probe = rtd119x_rtc_probe,
.remove = rtd119x_rtc_remove,
.driver = {
.name = "rtd1295-rtc",
.of_match_table = rtd119x_rtc_dt_ids,
},
};
builtin_platform_driver(rtd119x_rtc_driver);

View File

@ -868,7 +868,7 @@ static int rv3029_i2c_probe(struct i2c_client *client,
return rv3029_probe(&client->dev, regmap, client->irq, client->name);
}
static struct i2c_device_id rv3029_id[] = {
static const struct i2c_device_id rv3029_id[] = {
{ "rv3029", 0 },
{ "rv3029c2", 0 },
{ }

View File

@ -106,33 +106,12 @@ static int s35390a_get_reg(struct s35390a *s35390a, int reg, char *buf, int len)
return 0;
}
/*
* Returns <0 on error, 0 if rtc is setup fine and 1 if the chip was reset.
* To keep the information if an irq is pending, pass the value read from
* STATUS1 to the caller.
*/
static int s35390a_reset(struct s35390a *s35390a, char *status1)
static int s35390a_init(struct s35390a *s35390a)
{
char buf;
int ret;
unsigned initcount = 0;
ret = s35390a_get_reg(s35390a, S35390A_CMD_STATUS1, status1, 1);
if (ret < 0)
return ret;
if (*status1 & S35390A_FLAG_POC)
/*
* Do not communicate for 0.5 seconds since the power-on
* detection circuit is in operation.
*/
msleep(500);
else if (!(*status1 & S35390A_FLAG_BLD))
/*
* If both POC and BLD are unset everything is fine.
*/
return 0;
/*
* At least one of POC and BLD are set, so reinitialise chip. Keeping
* this information in the hardware to know later that the time isn't
@ -142,7 +121,6 @@ static int s35390a_reset(struct s35390a *s35390a, char *status1)
* The 24H bit is kept over reset, so set it already here.
*/
initialize:
*status1 = S35390A_FLAG_24H;
buf = S35390A_FLAG_RESET | S35390A_FLAG_24H;
ret = s35390a_set_reg(s35390a, S35390A_CMD_STATUS1, &buf, 1);
@ -165,6 +143,34 @@ static int s35390a_reset(struct s35390a *s35390a, char *status1)
return 1;
}
/*
* Returns <0 on error, 0 if rtc is setup fine and 1 if the chip was reset.
* To keep the information if an irq is pending, pass the value read from
* STATUS1 to the caller.
*/
static int s35390a_read_status(struct s35390a *s35390a, char *status1)
{
int ret;
ret = s35390a_get_reg(s35390a, S35390A_CMD_STATUS1, status1, 1);
if (ret < 0)
return ret;
if (*status1 & S35390A_FLAG_POC) {
/*
* Do not communicate for 0.5 seconds since the power-on
* detection circuit is in operation.
*/
msleep(500);
return 1;
} else if (*status1 & S35390A_FLAG_BLD)
return 1;
/*
* If both POC and BLD are unset everything is fine.
*/
return 0;
}
static int s35390a_disable_test_mode(struct s35390a *s35390a)
{
char buf[1];
@ -208,13 +214,16 @@ static int s35390a_set_datetime(struct i2c_client *client, struct rtc_time *tm)
{
struct s35390a *s35390a = i2c_get_clientdata(client);
int i, err;
char buf[7];
char buf[7], status;
dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d mday=%d, "
"mon=%d, year=%d, wday=%d\n", __func__, tm->tm_sec,
tm->tm_min, tm->tm_hour, tm->tm_mday, tm->tm_mon, tm->tm_year,
tm->tm_wday);
if (s35390a_read_status(s35390a, &status) == 1)
s35390a_init(s35390a);
buf[S35390A_BYTE_YEAR] = bin2bcd(tm->tm_year - 100);
buf[S35390A_BYTE_MONTH] = bin2bcd(tm->tm_mon + 1);
buf[S35390A_BYTE_DAY] = bin2bcd(tm->tm_mday);
@ -235,9 +244,12 @@ static int s35390a_set_datetime(struct i2c_client *client, struct rtc_time *tm)
static int s35390a_get_datetime(struct i2c_client *client, struct rtc_time *tm)
{
struct s35390a *s35390a = i2c_get_clientdata(client);
char buf[7];
char buf[7], status;
int i, err;
if (s35390a_read_status(s35390a, &status) == 1)
return -EINVAL;
err = s35390a_get_reg(s35390a, S35390A_CMD_TIME1, buf, sizeof(buf));
if (err < 0)
return err;
@ -392,12 +404,42 @@ static int s35390a_rtc_set_time(struct device *dev, struct rtc_time *tm)
return s35390a_set_datetime(to_i2c_client(dev), tm);
}
static int s35390a_rtc_ioctl(struct device *dev, unsigned int cmd,
unsigned long arg)
{
struct i2c_client *client = to_i2c_client(dev);
struct s35390a *s35390a = i2c_get_clientdata(client);
char sts;
int err;
switch (cmd) {
case RTC_VL_READ:
/* s35390a_reset set lowvoltage flag and init RTC if needed */
err = s35390a_read_status(s35390a, &sts);
if (err < 0)
return err;
if (copy_to_user((void __user *)arg, &err, sizeof(int)))
return -EFAULT;
break;
case RTC_VL_CLR:
/* update flag and clear register */
err = s35390a_init(s35390a);
if (err < 0)
return err;
break;
default:
return -ENOIOCTLCMD;
}
return 0;
}
static const struct rtc_class_ops s35390a_rtc_ops = {
.read_time = s35390a_rtc_read_time,
.set_time = s35390a_rtc_set_time,
.set_alarm = s35390a_rtc_set_alarm,
.read_alarm = s35390a_rtc_read_alarm,
.ioctl = s35390a_rtc_ioctl,
};
static struct i2c_driver s35390a_driver;
@ -405,7 +447,7 @@ static struct i2c_driver s35390a_driver;
static int s35390a_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
int err, err_reset;
int err, err_read;
unsigned int i;
struct s35390a *s35390a;
struct rtc_time tm;
@ -438,9 +480,9 @@ static int s35390a_probe(struct i2c_client *client,
}
}
err_reset = s35390a_reset(s35390a, &status1);
if (err_reset < 0) {
err = err_reset;
err_read = s35390a_read_status(s35390a, &status1);
if (err_read < 0) {
err = err_read;
dev_err(&client->dev, "error resetting chip\n");
goto exit_dummy;
}
@ -466,7 +508,7 @@ static int s35390a_probe(struct i2c_client *client,
}
}
if (err_reset > 0 || s35390a_get_datetime(client, &tm) < 0)
if (err_read > 0 || s35390a_get_datetime(client, &tm) < 0)
dev_warn(&client->dev, "clock needs to be set\n");
device_set_wakeup_capable(&client->dev, 1);

View File

@ -95,46 +95,6 @@ static irqreturn_t sa1100_rtc_interrupt(int irq, void *dev_id)
return IRQ_HANDLED;
}
static int sa1100_rtc_open(struct device *dev)
{
struct sa1100_rtc *info = dev_get_drvdata(dev);
struct rtc_device *rtc = info->rtc;
int ret;
ret = request_irq(info->irq_1hz, sa1100_rtc_interrupt, 0, "rtc 1Hz", dev);
if (ret) {
dev_err(dev, "IRQ %d already in use.\n", info->irq_1hz);
goto fail_ui;
}
ret = request_irq(info->irq_alarm, sa1100_rtc_interrupt, 0, "rtc Alrm", dev);
if (ret) {
dev_err(dev, "IRQ %d already in use.\n", info->irq_alarm);
goto fail_ai;
}
rtc->max_user_freq = RTC_FREQ;
rtc_irq_set_freq(rtc, NULL, RTC_FREQ);
return 0;
fail_ai:
free_irq(info->irq_1hz, dev);
fail_ui:
clk_disable_unprepare(info->clk);
return ret;
}
static void sa1100_rtc_release(struct device *dev)
{
struct sa1100_rtc *info = dev_get_drvdata(dev);
spin_lock_irq(&info->lock);
writel_relaxed(0, info->rtsr);
spin_unlock_irq(&info->lock);
free_irq(info->irq_alarm, dev);
free_irq(info->irq_1hz, dev);
}
static int sa1100_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
{
u32 rtsr;
@ -216,8 +176,6 @@ static int sa1100_rtc_proc(struct device *dev, struct seq_file *seq)
}
static const struct rtc_class_ops sa1100_rtc_ops = {
.open = sa1100_rtc_open,
.release = sa1100_rtc_release,
.read_time = sa1100_rtc_read_time,
.set_time = sa1100_rtc_set_time,
.read_alarm = sa1100_rtc_read_alarm,
@ -265,6 +223,9 @@ int sa1100_rtc_init(struct platform_device *pdev, struct sa1100_rtc *info)
}
info->rtc = rtc;
rtc->max_user_freq = RTC_FREQ;
rtc_irq_set_freq(rtc, NULL, RTC_FREQ);
/* Fix for a nasty initialization problem the in SA11xx RTSR register.
* See also the comments in sa1100_rtc_interrupt().
*
@ -299,6 +260,7 @@ static int sa1100_rtc_probe(struct platform_device *pdev)
struct resource *iores;
void __iomem *base;
int irq_1hz, irq_alarm;
int ret;
irq_1hz = platform_get_irq_byname(pdev, "rtc 1Hz");
irq_alarm = platform_get_irq_byname(pdev, "rtc alarm");
@ -311,6 +273,19 @@ static int sa1100_rtc_probe(struct platform_device *pdev)
info->irq_1hz = irq_1hz;
info->irq_alarm = irq_alarm;
ret = devm_request_irq(&pdev->dev, irq_1hz, sa1100_rtc_interrupt, 0,
"rtc 1Hz", &pdev->dev);
if (ret) {
dev_err(&pdev->dev, "IRQ %d already in use.\n", irq_1hz);
return ret;
}
ret = devm_request_irq(&pdev->dev, irq_alarm, sa1100_rtc_interrupt, 0,
"rtc Alrm", &pdev->dev);
if (ret) {
dev_err(&pdev->dev, "IRQ %d already in use.\n", irq_alarm);
return ret;
}
iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
base = devm_ioremap_resource(&pdev->dev, iores);
if (IS_ERR(base))
@ -339,8 +314,12 @@ static int sa1100_rtc_remove(struct platform_device *pdev)
{
struct sa1100_rtc *info = platform_get_drvdata(pdev);
if (info)
if (info) {
spin_lock_irq(&info->lock);
writel_relaxed(0, info->rtsr);
spin_unlock_irq(&info->lock);
clk_disable_unprepare(info->clk);
}
return 0;
}

View File

@ -73,6 +73,9 @@
#define SUN6I_ALARM_CONFIG 0x0050
#define SUN6I_ALARM_CONFIG_WAKEUP BIT(0)
#define SUN6I_LOSC_OUT_GATING 0x0060
#define SUN6I_LOSC_OUT_GATING_EN BIT(0)
/*
* Get date values
*/
@ -125,6 +128,7 @@ struct sun6i_rtc_dev {
struct clk_hw hw;
struct clk_hw *int_osc;
struct clk *losc;
struct clk *ext_losc;
spinlock_t lock;
};
@ -188,23 +192,24 @@ static void __init sun6i_rtc_clk_init(struct device_node *node)
struct clk_init_data init = {
.ops = &sun6i_rtc_osc_ops,
};
const char *clkout_name = "osc32k-out";
const char *parents[2];
rtc = kzalloc(sizeof(*rtc), GFP_KERNEL);
if (!rtc)
return;
spin_lock_init(&rtc->lock);
clk_data = kzalloc(sizeof(*clk_data) + sizeof(*clk_data->hws),
clk_data = kzalloc(sizeof(*clk_data) + (sizeof(*clk_data->hws) * 2),
GFP_KERNEL);
if (!clk_data)
return;
spin_lock_init(&rtc->lock);
rtc->base = of_io_request_and_map(node, 0, of_node_full_name(node));
if (IS_ERR(rtc->base)) {
pr_crit("Can't map RTC registers");
return;
goto err;
}
/* Switch to the external, more precise, oscillator */
@ -216,7 +221,7 @@ static void __init sun6i_rtc_clk_init(struct device_node *node)
/* Deal with old DTs */
if (!of_get_property(node, "clocks", NULL))
return;
goto err;
rtc->int_osc = clk_hw_register_fixed_rate_with_accuracy(NULL,
"rtc-int-osc",
@ -235,7 +240,8 @@ static void __init sun6i_rtc_clk_init(struct device_node *node)
init.parent_names = parents;
init.num_parents = of_clk_get_parent_count(node) + 1;
of_property_read_string(node, "clock-output-names", &init.name);
of_property_read_string_index(node, "clock-output-names", 0,
&init.name);
rtc->losc = clk_register(NULL, &rtc->hw);
if (IS_ERR(rtc->losc)) {
@ -243,9 +249,25 @@ static void __init sun6i_rtc_clk_init(struct device_node *node)
return;
}
clk_data->num = 1;
of_property_read_string_index(node, "clock-output-names", 1,
&clkout_name);
rtc->ext_losc = clk_register_gate(NULL, clkout_name, rtc->hw.init->name,
0, rtc->base + SUN6I_LOSC_OUT_GATING,
SUN6I_LOSC_OUT_GATING_EN, 0,
&rtc->lock);
if (IS_ERR(rtc->ext_losc)) {
pr_crit("Couldn't register the LOSC external gate\n");
return;
}
clk_data->num = 2;
clk_data->hws[0] = &rtc->hw;
clk_data->hws[1] = __clk_get_hw(rtc->ext_losc);
of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
return;
err:
kfree(clk_data);
}
CLK_OF_DECLARE_DRIVER(sun6i_rtc_clk, "allwinner,sun6i-a31-rtc",
sun6i_rtc_clk_init);

View File

@ -119,23 +119,6 @@ static inline void write_elapsed_second(unsigned long sec)
spin_unlock_irq(&rtc_lock);
}
static void vr41xx_rtc_release(struct device *dev)
{
spin_lock_irq(&rtc_lock);
rtc1_write(ECMPLREG, 0);
rtc1_write(ECMPMREG, 0);
rtc1_write(ECMPHREG, 0);
rtc1_write(RTCL1LREG, 0);
rtc1_write(RTCL1HREG, 0);
spin_unlock_irq(&rtc_lock);
disable_irq(aie_irq);
disable_irq(pie_irq);
}
static int vr41xx_rtc_read_time(struct device *dev, struct rtc_time *time)
{
unsigned long epoch_sec, elapsed_sec;
@ -272,7 +255,6 @@ static irqreturn_t rtclong1_interrupt(int irq, void *dev_id)
}
static const struct rtc_class_ops vr41xx_rtc_ops = {
.release = vr41xx_rtc_release,
.ioctl = vr41xx_rtc_ioctl,
.read_time = vr41xx_rtc_read_time,
.set_time = vr41xx_rtc_set_time,

View File

@ -72,8 +72,6 @@ extern struct class *rtc_class;
* issued through ioctl() ...
*/
struct rtc_class_ops {
int (*open)(struct device *);
void (*release)(struct device *);
int (*ioctl)(struct device *, unsigned int, unsigned long);
int (*read_time)(struct device *, struct rtc_time *);
int (*set_time)(struct device *, struct rtc_time *);