hc
2024-05-14 bedbef8ad3e75a304af6361af235302bcc61d06b
kernel/drivers/watchdog/f71808e_wdt.c
....@@ -1,22 +1,9 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /***************************************************************************
23 * Copyright (C) 2006 by Hans Edgington <hans@edgington.nl> *
34 * Copyright (C) 2007-2009 Hans de Goede <hdegoede@redhat.com> *
45 * Copyright (C) 2010 Giel van Schijndel <me@mortis.eu> *
56 * *
6
- * This program is free software; you can redistribute it and/or modify *
7
- * it under the terms of the GNU General Public License as published by *
8
- * the Free Software Foundation; either version 2 of the License, or *
9
- * (at your option) any later version. *
10
- * *
11
- * This program is distributed in the hope that it will be useful, *
12
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14
- * GNU General Public License for more details. *
15
- * *
16
- * You should have received a copy of the GNU General Public License *
17
- * along with this program; if not, write to the *
18
- * Free Software Foundation, Inc., *
19
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
207 ***************************************************************************/
218
229 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
....@@ -44,8 +31,10 @@
4431 #define SIO_REG_DEVID 0x20 /* Device ID (2 bytes) */
4532 #define SIO_REG_DEVREV 0x22 /* Device revision */
4633 #define SIO_REG_MANID 0x23 /* Fintek ID (2 bytes) */
34
+#define SIO_REG_CLOCK_SEL 0x26 /* Clock select */
4735 #define SIO_REG_ROM_ADDR_SEL 0x27 /* ROM address select */
4836 #define SIO_F81866_REG_PORT_SEL 0x27 /* F81866 Multi-Function Register */
37
+#define SIO_REG_TSI_LEVEL_SEL 0x28 /* TSI Level select */
4938 #define SIO_REG_MFUNCT1 0x29 /* Multi function select 1 */
5039 #define SIO_REG_MFUNCT2 0x2a /* Multi function select 2 */
5140 #define SIO_REG_MFUNCT3 0x2b /* Multi function select 3 */
....@@ -62,6 +51,7 @@
6251 #define SIO_F71869A_ID 0x1007 /* Chipset ID */
6352 #define SIO_F71882_ID 0x0541 /* Chipset ID */
6453 #define SIO_F71889_ID 0x0723 /* Chipset ID */
54
+#define SIO_F81803_ID 0x1210 /* Chipset ID */
6555 #define SIO_F81865_ID 0x0704 /* Chipset ID */
6656 #define SIO_F81866_ID 0x1010 /* Chipset ID */
6757
....@@ -121,7 +111,7 @@
121111 " given initial timeout. Zero (default) disables this feature.");
122112
123113 enum chips { f71808fg, f71858fg, f71862fg, f71868, f71869, f71882fg, f71889fg,
124
- f81865, f81866};
114
+ f81803, f81865, f81866};
125115
126116 static const char *f71808e_names[] = {
127117 "f71808fg",
....@@ -131,6 +121,7 @@
131121 "f71869",
132122 "f71882fg",
133123 "f71889fg",
124
+ "f81803",
134125 "f81865",
135126 "f81866",
136127 };
....@@ -317,31 +308,13 @@
317308 return err;
318309 }
319310
320
-static int f71862fg_pin_configure(unsigned short ioaddr)
321
-{
322
- /* When ioaddr is non-zero the calling function has to take care of
323
- mutex handling and superio preparation! */
324
-
325
- if (f71862fg_pin == 63) {
326
- if (ioaddr) {
327
- /* SPI must be disabled first to use this pin! */
328
- superio_clear_bit(ioaddr, SIO_REG_ROM_ADDR_SEL, 6);
329
- superio_set_bit(ioaddr, SIO_REG_MFUNCT3, 4);
330
- }
331
- } else if (f71862fg_pin == 56) {
332
- if (ioaddr)
333
- superio_set_bit(ioaddr, SIO_REG_MFUNCT1, 1);
334
- } else {
335
- pr_err("Invalid argument f71862fg_pin=%d\n", f71862fg_pin);
336
- return -EINVAL;
337
- }
338
- return 0;
339
-}
340
-
341311 static int watchdog_start(void)
342312 {
313
+ int err;
314
+ u8 tmp;
315
+
343316 /* Make sure we don't die as soon as the watchdog is enabled below */
344
- int err = watchdog_keepalive();
317
+ err = watchdog_keepalive();
345318 if (err)
346319 return err;
347320
....@@ -360,9 +333,13 @@
360333 break;
361334
362335 case f71862fg:
363
- err = f71862fg_pin_configure(watchdog.sioaddr);
364
- if (err)
365
- goto exit_superio;
336
+ if (f71862fg_pin == 63) {
337
+ /* SPI must be disabled first to use this pin! */
338
+ superio_clear_bit(watchdog.sioaddr, SIO_REG_ROM_ADDR_SEL, 6);
339
+ superio_set_bit(watchdog.sioaddr, SIO_REG_MFUNCT3, 4);
340
+ } else if (f71862fg_pin == 56) {
341
+ superio_set_bit(watchdog.sioaddr, SIO_REG_MFUNCT1, 1);
342
+ }
366343 break;
367344
368345 case f71868:
....@@ -382,25 +359,32 @@
382359 superio_inb(watchdog.sioaddr, SIO_REG_MFUNCT3) & 0xcf);
383360 break;
384361
362
+ case f81803:
363
+ /* Enable TSI Level register bank */
364
+ superio_clear_bit(watchdog.sioaddr, SIO_REG_CLOCK_SEL, 3);
365
+ /* Set pin 27 to WDTRST# */
366
+ superio_outb(watchdog.sioaddr, SIO_REG_TSI_LEVEL_SEL, 0x5f &
367
+ superio_inb(watchdog.sioaddr, SIO_REG_TSI_LEVEL_SEL));
368
+ break;
369
+
385370 case f81865:
386371 /* Set pin 70 to WDTRST# */
387372 superio_clear_bit(watchdog.sioaddr, SIO_REG_MFUNCT3, 5);
388373 break;
389374
390375 case f81866:
391
- /* Set pin 70 to WDTRST# */
392
- superio_clear_bit(watchdog.sioaddr, SIO_F81866_REG_PORT_SEL,
393
- BIT(3) | BIT(0));
394
- superio_set_bit(watchdog.sioaddr, SIO_F81866_REG_PORT_SEL,
395
- BIT(2));
396376 /*
397377 * GPIO1 Control Register when 27h BIT3:2 = 01 & BIT0 = 0.
398378 * The PIN 70(GPIO15/WDTRST) is controlled by 2Ch:
399379 * BIT5: 0 -> WDTRST#
400380 * 1 -> GPIO15
401381 */
402
- superio_clear_bit(watchdog.sioaddr, SIO_F81866_REG_GPIO1,
403
- BIT(5));
382
+ tmp = superio_inb(watchdog.sioaddr, SIO_F81866_REG_PORT_SEL);
383
+ tmp &= ~(BIT(3) | BIT(0));
384
+ tmp |= BIT(2);
385
+ superio_outb(watchdog.sioaddr, SIO_F81866_REG_PORT_SEL, tmp);
386
+
387
+ superio_clear_bit(watchdog.sioaddr, SIO_F81866_REG_GPIO1, 5);
404388 break;
405389
406390 default:
....@@ -527,7 +511,7 @@
527511 __module_get(THIS_MODULE);
528512
529513 watchdog.expect_close = 0;
530
- return nonseekable_open(inode, file);
514
+ return stream_open(inode, file);
531515 }
532516
533517 static int watchdog_release(struct inode *inode, struct file *file)
....@@ -630,7 +614,7 @@
630614
631615 if (new_options & WDIOS_ENABLECARD)
632616 return watchdog_start();
633
- /* fall through */
617
+ fallthrough;
634618
635619 case WDIOC_KEEPALIVE:
636620 watchdog_keepalive();
....@@ -644,7 +628,7 @@
644628 return -EINVAL;
645629
646630 watchdog_keepalive();
647
- /* fall through */
631
+ fallthrough;
648632
649633 case WDIOC_GETTIMEOUT:
650634 return put_user(watchdog.timeout, uarg.i);
....@@ -670,6 +654,7 @@
670654 .release = watchdog_release,
671655 .write = watchdog_write,
672656 .unlocked_ioctl = watchdog_ioctl,
657
+ .compat_ioctl = compat_ptr_ioctl,
673658 };
674659
675660 static struct miscdevice watchdog_miscdev = {
....@@ -810,7 +795,6 @@
810795 break;
811796 case SIO_F71862_ID:
812797 watchdog.type = f71862fg;
813
- err = f71862fg_pin_configure(0); /* validate module parameter */
814798 break;
815799 case SIO_F71868_ID:
816800 watchdog.type = f71868;
....@@ -829,6 +813,9 @@
829813 /* Confirmed (by datasheet) not to have a watchdog. */
830814 err = -ENODEV;
831815 goto exit;
816
+ case SIO_F81803_ID:
817
+ watchdog.type = f81803;
818
+ break;
832819 case SIO_F81865_ID:
833820 watchdog.type = f81865;
834821 break;
....@@ -856,6 +843,11 @@
856843 int err = -ENODEV;
857844 int i;
858845
846
+ if (f71862fg_pin != 63 && f71862fg_pin != 56) {
847
+ pr_err("Invalid argument f71862fg_pin=%d\n", f71862fg_pin);
848
+ return -EINVAL;
849
+ }
850
+
859851 for (i = 0; i < ARRAY_SIZE(addrs); i++) {
860852 err = f71808e_find(addrs[i]);
861853 if (err == 0)