| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * I2C client/driver for the ST M41T80 family of i2c rtc chips. |
|---|
| 3 | 4 | * |
|---|
| .. | .. |
|---|
| 6 | 7 | * Based on m41t00.c by Mark A. Greer <mgreer@mvista.com> |
|---|
| 7 | 8 | * |
|---|
| 8 | 9 | * 2006 (c) mycable GmbH |
|---|
| 9 | | - * |
|---|
| 10 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 11 | | - * it under the terms of the GNU General Public License version 2 as |
|---|
| 12 | | - * published by the Free Software Foundation. |
|---|
| 13 | | - * |
|---|
| 14 | 10 | */ |
|---|
| 15 | 11 | |
|---|
| 16 | 12 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
|---|
| .. | .. |
|---|
| 217 | 213 | sizeof(buf), buf); |
|---|
| 218 | 214 | if (err < 0) { |
|---|
| 219 | 215 | dev_err(&client->dev, "Unable to read date\n"); |
|---|
| 220 | | - return -EIO; |
|---|
| 216 | + return err; |
|---|
| 221 | 217 | } |
|---|
| 222 | 218 | |
|---|
| 223 | 219 | tm->tm_sec = bcd2bin(buf[M41T80_REG_SEC] & 0x7f); |
|---|
| .. | .. |
|---|
| 238 | 234 | struct m41t80_data *clientdata = i2c_get_clientdata(client); |
|---|
| 239 | 235 | unsigned char buf[8]; |
|---|
| 240 | 236 | int err, flags; |
|---|
| 241 | | - |
|---|
| 242 | | - if (tm->tm_year < 100 || tm->tm_year > 199) |
|---|
| 243 | | - return -EINVAL; |
|---|
| 244 | 237 | |
|---|
| 245 | 238 | buf[M41T80_REG_SSEC] = 0; |
|---|
| 246 | 239 | buf[M41T80_REG_SEC] = bin2bcd(tm->tm_sec); |
|---|
| .. | .. |
|---|
| 274 | 267 | if (flags < 0) |
|---|
| 275 | 268 | return flags; |
|---|
| 276 | 269 | |
|---|
| 277 | | - if (i2c_smbus_write_byte_data(client, M41T80_REG_FLAGS, |
|---|
| 278 | | - flags & ~M41T80_FLAGS_OF)) { |
|---|
| 270 | + err = i2c_smbus_write_byte_data(client, M41T80_REG_FLAGS, |
|---|
| 271 | + flags & ~M41T80_FLAGS_OF); |
|---|
| 272 | + if (err < 0) { |
|---|
| 279 | 273 | dev_err(&client->dev, "Unable to write flags register\n"); |
|---|
| 280 | | - return -EIO; |
|---|
| 274 | + return err; |
|---|
| 281 | 275 | } |
|---|
| 282 | 276 | |
|---|
| 283 | 277 | return err; |
|---|
| .. | .. |
|---|
| 287 | 281 | { |
|---|
| 288 | 282 | struct i2c_client *client = to_i2c_client(dev); |
|---|
| 289 | 283 | struct m41t80_data *clientdata = i2c_get_clientdata(client); |
|---|
| 290 | | - u8 reg; |
|---|
| 284 | + int reg; |
|---|
| 291 | 285 | |
|---|
| 292 | 286 | if (clientdata->features & M41T80_FEATURE_BL) { |
|---|
| 293 | 287 | reg = i2c_smbus_read_byte_data(client, M41T80_REG_FLAGS); |
|---|
| 288 | + if (reg < 0) |
|---|
| 289 | + return reg; |
|---|
| 294 | 290 | seq_printf(seq, "battery\t\t: %s\n", |
|---|
| 295 | 291 | (reg & M41T80_FLAGS_BATT_LOW) ? "exhausted" : "ok"); |
|---|
| 296 | 292 | } |
|---|
| .. | .. |
|---|
| 706 | 702 | |
|---|
| 707 | 703 | /** |
|---|
| 708 | 704 | * wdt_ioctl: |
|---|
| 709 | | - * @inode: inode of the device |
|---|
| 710 | 705 | * @file: file handle to the device |
|---|
| 711 | 706 | * @cmd: watchdog command |
|---|
| 712 | 707 | * @arg: argument pointer |
|---|
| .. | .. |
|---|
| 745 | 740 | return -EINVAL; |
|---|
| 746 | 741 | wdt_margin = new_margin; |
|---|
| 747 | 742 | wdt_ping(); |
|---|
| 748 | | - /* Fall */ |
|---|
| 743 | + fallthrough; |
|---|
| 749 | 744 | case WDIOC_GETTIMEOUT: |
|---|
| 750 | 745 | return put_user(wdt_margin, (int __user *)arg); |
|---|
| 751 | 746 | |
|---|
| .. | .. |
|---|
| 799 | 794 | */ |
|---|
| 800 | 795 | wdt_is_open = 1; |
|---|
| 801 | 796 | mutex_unlock(&m41t80_rtc_mutex); |
|---|
| 802 | | - return nonseekable_open(inode, file); |
|---|
| 797 | + return stream_open(inode, file); |
|---|
| 803 | 798 | } |
|---|
| 804 | 799 | return -ENODEV; |
|---|
| 805 | 800 | } |
|---|
| .. | .. |
|---|
| 841 | 836 | .owner = THIS_MODULE, |
|---|
| 842 | 837 | .read = wdt_read, |
|---|
| 843 | 838 | .unlocked_ioctl = wdt_unlocked_ioctl, |
|---|
| 839 | + .compat_ioctl = compat_ptr_ioctl, |
|---|
| 844 | 840 | .write = wdt_write, |
|---|
| 845 | 841 | .open = wdt_open, |
|---|
| 846 | 842 | .release = wdt_release, |
|---|
| .. | .. |
|---|
| 873 | 869 | static int m41t80_probe(struct i2c_client *client, |
|---|
| 874 | 870 | const struct i2c_device_id *id) |
|---|
| 875 | 871 | { |
|---|
| 876 | | - struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); |
|---|
| 872 | + struct i2c_adapter *adapter = client->adapter; |
|---|
| 877 | 873 | int rc = 0; |
|---|
| 878 | 874 | struct rtc_time tm; |
|---|
| 879 | 875 | struct m41t80_data *m41t80_data = NULL; |
|---|
| .. | .. |
|---|
| 926 | 922 | } |
|---|
| 927 | 923 | |
|---|
| 928 | 924 | m41t80_data->rtc->ops = &m41t80_rtc_ops; |
|---|
| 925 | + m41t80_data->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000; |
|---|
| 926 | + m41t80_data->rtc->range_max = RTC_TIMESTAMP_END_2099; |
|---|
| 929 | 927 | |
|---|
| 930 | 928 | if (client->irq <= 0) { |
|---|
| 931 | 929 | /* We cannot support UIE mode if we do not have an IRQ line */ |
|---|
| .. | .. |
|---|
| 939 | 937 | if (m41t80_data->features & M41T80_FEATURE_HT) { |
|---|
| 940 | 938 | m41t80_rtc_read_time(&client->dev, &tm); |
|---|
| 941 | 939 | dev_info(&client->dev, "HT bit was set!\n"); |
|---|
| 942 | | - dev_info(&client->dev, |
|---|
| 943 | | - "Power Down at %04i-%02i-%02i %02i:%02i:%02i\n", |
|---|
| 944 | | - tm.tm_year + 1900, |
|---|
| 945 | | - tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, |
|---|
| 946 | | - tm.tm_min, tm.tm_sec); |
|---|
| 940 | + dev_info(&client->dev, "Power Down at %ptR\n", &tm); |
|---|
| 947 | 941 | } |
|---|
| 948 | 942 | rc = i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_HOUR, |
|---|
| 949 | 943 | rc & ~M41T80_ALHOUR_HT); |
|---|