0001
0002
0003
0004
0005
0006
0007 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0008
0009 #include <linux/module.h>
0010 #include <linux/mod_devicetable.h>
0011 #include <linux/init.h>
0012 #include <linux/platform_device.h>
0013 #include <linux/dmi.h>
0014 #include <linux/err.h>
0015 #include <linux/io.h>
0016 #include <linux/acpi.h>
0017 #include <linux/delay.h>
0018 #include <linux/fs.h>
0019 #include <linux/watchdog.h>
0020 #include <linux/uaccess.h>
0021 #include <linux/slab.h>
0022 #include "sch56xx-common.h"
0023
0024 static bool ignore_dmi;
0025 module_param(ignore_dmi, bool, 0);
0026 MODULE_PARM_DESC(ignore_dmi, "Omit DMI check for supported devices (default=0)");
0027
0028 static bool nowayout = WATCHDOG_NOWAYOUT;
0029 module_param(nowayout, bool, 0);
0030 MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
0031 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
0032
0033 #define SIO_SCH56XX_LD_EM 0x0C
0034 #define SIO_UNLOCK_KEY 0x55
0035 #define SIO_LOCK_KEY 0xAA
0036
0037 #define SIO_REG_LDSEL 0x07
0038 #define SIO_REG_DEVID 0x20
0039 #define SIO_REG_ENABLE 0x30
0040 #define SIO_REG_ADDR 0x66
0041
0042 #define SIO_SCH5627_ID 0xC6
0043 #define SIO_SCH5636_ID 0xC7
0044
0045 #define REGION_LENGTH 10
0046
0047 #define SCH56XX_CMD_READ 0x02
0048 #define SCH56XX_CMD_WRITE 0x03
0049
0050
0051 #define SCH56XX_REG_WDOG_PRESET 0x58B
0052 #define SCH56XX_REG_WDOG_CONTROL 0x58C
0053 #define SCH56XX_WDOG_TIME_BASE_SEC 0x01
0054 #define SCH56XX_REG_WDOG_OUTPUT_ENABLE 0x58E
0055 #define SCH56XX_WDOG_OUTPUT_ENABLE 0x02
0056
0057 struct sch56xx_watchdog_data {
0058 u16 addr;
0059 struct mutex *io_lock;
0060 struct watchdog_info wdinfo;
0061 struct watchdog_device wddev;
0062 u8 watchdog_preset;
0063 u8 watchdog_control;
0064 u8 watchdog_output_enable;
0065 };
0066
0067 static struct platform_device *sch56xx_pdev;
0068
0069
0070 static inline int superio_inb(int base, int reg)
0071 {
0072 outb(reg, base);
0073 return inb(base + 1);
0074 }
0075
0076 static inline int superio_enter(int base)
0077 {
0078
0079 if (!request_muxed_region(base, 2, "sch56xx")) {
0080 pr_err("I/O address 0x%04x already in use\n", base);
0081 return -EBUSY;
0082 }
0083
0084 outb(SIO_UNLOCK_KEY, base);
0085
0086 return 0;
0087 }
0088
0089 static inline void superio_select(int base, int ld)
0090 {
0091 outb(SIO_REG_LDSEL, base);
0092 outb(ld, base + 1);
0093 }
0094
0095 static inline void superio_exit(int base)
0096 {
0097 outb(SIO_LOCK_KEY, base);
0098 release_region(base, 2);
0099 }
0100
0101 static int sch56xx_send_cmd(u16 addr, u8 cmd, u16 reg, u8 v)
0102 {
0103 u8 val;
0104 int i;
0105
0106
0107
0108
0109
0110
0111
0112 const int max_busy_polls = 64;
0113 const int max_lazy_polls = 32;
0114
0115
0116 val = inb(addr + 1);
0117 outb(val, addr + 1);
0118
0119
0120 outb(0x00, addr + 2);
0121 outb(0x80, addr + 3);
0122
0123
0124 outb(cmd, addr + 4);
0125 outb(0x01, addr + 5);
0126 outb(0x04, addr + 2);
0127
0128
0129 if (cmd == SCH56XX_CMD_WRITE)
0130 outb(v, addr + 4);
0131
0132
0133 outb(reg & 0xff, addr + 6);
0134 outb(reg >> 8, addr + 7);
0135
0136
0137 outb(0x01, addr);
0138
0139
0140 for (i = 0; i < max_busy_polls + max_lazy_polls; i++) {
0141 if (i >= max_busy_polls)
0142 usleep_range(1000, 2000);
0143
0144 val = inb(addr + 8);
0145
0146 if (val)
0147 outb(val, addr + 8);
0148
0149 if (val & 0x01)
0150 break;
0151 }
0152 if (i == max_busy_polls + max_lazy_polls) {
0153 pr_err("Max retries exceeded reading virtual register 0x%04hx (%d)\n",
0154 reg, 1);
0155 return -EIO;
0156 }
0157
0158
0159
0160
0161
0162 for (i = 0; i < max_busy_polls; i++) {
0163
0164 val = inb(addr + 1);
0165
0166 if (val == 0x01)
0167 break;
0168
0169 if (i == 0)
0170 pr_warn("EC reports: 0x%02x reading virtual register 0x%04hx\n",
0171 (unsigned int)val, reg);
0172 }
0173 if (i == max_busy_polls) {
0174 pr_err("Max retries exceeded reading virtual register 0x%04hx (%d)\n",
0175 reg, 2);
0176 return -EIO;
0177 }
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188
0189
0190 if (cmd == SCH56XX_CMD_READ)
0191 return inb(addr + 4);
0192
0193 return 0;
0194 }
0195
0196 int sch56xx_read_virtual_reg(u16 addr, u16 reg)
0197 {
0198 return sch56xx_send_cmd(addr, SCH56XX_CMD_READ, reg, 0);
0199 }
0200 EXPORT_SYMBOL(sch56xx_read_virtual_reg);
0201
0202 int sch56xx_write_virtual_reg(u16 addr, u16 reg, u8 val)
0203 {
0204 return sch56xx_send_cmd(addr, SCH56XX_CMD_WRITE, reg, val);
0205 }
0206 EXPORT_SYMBOL(sch56xx_write_virtual_reg);
0207
0208 int sch56xx_read_virtual_reg16(u16 addr, u16 reg)
0209 {
0210 int lsb, msb;
0211
0212
0213 lsb = sch56xx_read_virtual_reg(addr, reg);
0214 if (lsb < 0)
0215 return lsb;
0216
0217 msb = sch56xx_read_virtual_reg(addr, reg + 1);
0218 if (msb < 0)
0219 return msb;
0220
0221 return lsb | (msb << 8);
0222 }
0223 EXPORT_SYMBOL(sch56xx_read_virtual_reg16);
0224
0225 int sch56xx_read_virtual_reg12(u16 addr, u16 msb_reg, u16 lsn_reg,
0226 int high_nibble)
0227 {
0228 int msb, lsn;
0229
0230
0231 msb = sch56xx_read_virtual_reg(addr, msb_reg);
0232 if (msb < 0)
0233 return msb;
0234
0235 lsn = sch56xx_read_virtual_reg(addr, lsn_reg);
0236 if (lsn < 0)
0237 return lsn;
0238
0239 if (high_nibble)
0240 return (msb << 4) | (lsn >> 4);
0241 else
0242 return (msb << 4) | (lsn & 0x0f);
0243 }
0244 EXPORT_SYMBOL(sch56xx_read_virtual_reg12);
0245
0246
0247
0248
0249
0250 static int watchdog_set_timeout(struct watchdog_device *wddev,
0251 unsigned int timeout)
0252 {
0253 struct sch56xx_watchdog_data *data = watchdog_get_drvdata(wddev);
0254 unsigned int resolution;
0255 u8 control;
0256 int ret;
0257
0258
0259 if (timeout <= 255)
0260 resolution = 1;
0261 else
0262 resolution = 60;
0263
0264 if (timeout < resolution || timeout > (resolution * 255))
0265 return -EINVAL;
0266
0267 if (resolution == 1)
0268 control = data->watchdog_control | SCH56XX_WDOG_TIME_BASE_SEC;
0269 else
0270 control = data->watchdog_control & ~SCH56XX_WDOG_TIME_BASE_SEC;
0271
0272 if (data->watchdog_control != control) {
0273 mutex_lock(data->io_lock);
0274 ret = sch56xx_write_virtual_reg(data->addr,
0275 SCH56XX_REG_WDOG_CONTROL,
0276 control);
0277 mutex_unlock(data->io_lock);
0278 if (ret)
0279 return ret;
0280
0281 data->watchdog_control = control;
0282 }
0283
0284
0285
0286
0287
0288 data->watchdog_preset = DIV_ROUND_UP(timeout, resolution);
0289 wddev->timeout = data->watchdog_preset * resolution;
0290
0291 return 0;
0292 }
0293
0294 static int watchdog_start(struct watchdog_device *wddev)
0295 {
0296 struct sch56xx_watchdog_data *data = watchdog_get_drvdata(wddev);
0297 int ret;
0298 u8 val;
0299
0300
0301
0302
0303
0304
0305
0306
0307
0308
0309
0310
0311
0312
0313
0314
0315
0316
0317
0318
0319 mutex_lock(data->io_lock);
0320
0321
0322 ret = sch56xx_write_virtual_reg(data->addr, SCH56XX_REG_WDOG_PRESET,
0323 data->watchdog_preset);
0324 if (ret)
0325 goto leave;
0326
0327
0328 val = data->watchdog_output_enable | SCH56XX_WDOG_OUTPUT_ENABLE;
0329 ret = sch56xx_write_virtual_reg(data->addr,
0330 SCH56XX_REG_WDOG_OUTPUT_ENABLE, val);
0331 if (ret)
0332 goto leave;
0333
0334 data->watchdog_output_enable = val;
0335
0336
0337 val = inb(data->addr + 9);
0338 if (val & 0x01)
0339 outb(0x01, data->addr + 9);
0340
0341 leave:
0342 mutex_unlock(data->io_lock);
0343 return ret;
0344 }
0345
0346 static int watchdog_trigger(struct watchdog_device *wddev)
0347 {
0348 struct sch56xx_watchdog_data *data = watchdog_get_drvdata(wddev);
0349 int ret;
0350
0351
0352 mutex_lock(data->io_lock);
0353 ret = sch56xx_write_virtual_reg(data->addr, SCH56XX_REG_WDOG_PRESET,
0354 data->watchdog_preset);
0355 mutex_unlock(data->io_lock);
0356
0357 return ret;
0358 }
0359
0360 static int watchdog_stop(struct watchdog_device *wddev)
0361 {
0362 struct sch56xx_watchdog_data *data = watchdog_get_drvdata(wddev);
0363 int ret = 0;
0364 u8 val;
0365
0366 val = data->watchdog_output_enable & ~SCH56XX_WDOG_OUTPUT_ENABLE;
0367 mutex_lock(data->io_lock);
0368 ret = sch56xx_write_virtual_reg(data->addr,
0369 SCH56XX_REG_WDOG_OUTPUT_ENABLE, val);
0370 mutex_unlock(data->io_lock);
0371 if (ret)
0372 return ret;
0373
0374 data->watchdog_output_enable = val;
0375 return 0;
0376 }
0377
0378 static const struct watchdog_ops watchdog_ops = {
0379 .owner = THIS_MODULE,
0380 .start = watchdog_start,
0381 .stop = watchdog_stop,
0382 .ping = watchdog_trigger,
0383 .set_timeout = watchdog_set_timeout,
0384 };
0385
0386 void sch56xx_watchdog_register(struct device *parent, u16 addr, u32 revision,
0387 struct mutex *io_lock, int check_enabled)
0388 {
0389 struct sch56xx_watchdog_data *data;
0390 int err, control, output_enable;
0391
0392
0393 mutex_lock(io_lock);
0394 control =
0395 sch56xx_read_virtual_reg(addr, SCH56XX_REG_WDOG_CONTROL);
0396 output_enable =
0397 sch56xx_read_virtual_reg(addr, SCH56XX_REG_WDOG_OUTPUT_ENABLE);
0398 mutex_unlock(io_lock);
0399
0400 if (control < 0)
0401 return;
0402 if (output_enable < 0)
0403 return;
0404 if (check_enabled && !(output_enable & SCH56XX_WDOG_OUTPUT_ENABLE)) {
0405 pr_warn("Watchdog not enabled by BIOS, not registering\n");
0406 return;
0407 }
0408
0409 data = devm_kzalloc(parent, sizeof(struct sch56xx_watchdog_data), GFP_KERNEL);
0410 if (!data)
0411 return;
0412
0413 data->addr = addr;
0414 data->io_lock = io_lock;
0415
0416 strscpy(data->wdinfo.identity, "sch56xx watchdog", sizeof(data->wdinfo.identity));
0417 data->wdinfo.firmware_version = revision;
0418 data->wdinfo.options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT;
0419 if (!nowayout)
0420 data->wdinfo.options |= WDIOF_MAGICCLOSE;
0421
0422 data->wddev.info = &data->wdinfo;
0423 data->wddev.ops = &watchdog_ops;
0424 data->wddev.parent = parent;
0425 data->wddev.timeout = 60;
0426 data->wddev.min_timeout = 1;
0427 data->wddev.max_timeout = 255 * 60;
0428 watchdog_set_nowayout(&data->wddev, nowayout);
0429 if (output_enable & SCH56XX_WDOG_OUTPUT_ENABLE)
0430 set_bit(WDOG_HW_RUNNING, &data->wddev.status);
0431
0432
0433
0434
0435 if (control & SCH56XX_WDOG_TIME_BASE_SEC)
0436 data->watchdog_preset = 60;
0437 else
0438 data->watchdog_preset = 1;
0439
0440 data->watchdog_control = control;
0441 data->watchdog_output_enable = output_enable;
0442
0443 watchdog_set_drvdata(&data->wddev, data);
0444 err = devm_watchdog_register_device(parent, &data->wddev);
0445 if (err) {
0446 pr_err("Registering watchdog chardev: %d\n", err);
0447 devm_kfree(parent, data);
0448 }
0449 }
0450 EXPORT_SYMBOL(sch56xx_watchdog_register);
0451
0452
0453
0454
0455
0456 static int __init sch56xx_find(int sioaddr, const char **name)
0457 {
0458 u8 devid;
0459 unsigned short address;
0460 int err;
0461
0462 err = superio_enter(sioaddr);
0463 if (err)
0464 return err;
0465
0466 devid = superio_inb(sioaddr, SIO_REG_DEVID);
0467 switch (devid) {
0468 case SIO_SCH5627_ID:
0469 *name = "sch5627";
0470 break;
0471 case SIO_SCH5636_ID:
0472 *name = "sch5636";
0473 break;
0474 default:
0475 pr_debug("Unsupported device id: 0x%02x\n",
0476 (unsigned int)devid);
0477 err = -ENODEV;
0478 goto exit;
0479 }
0480
0481 superio_select(sioaddr, SIO_SCH56XX_LD_EM);
0482
0483 if (!(superio_inb(sioaddr, SIO_REG_ENABLE) & 0x01)) {
0484 pr_warn("Device not activated\n");
0485 err = -ENODEV;
0486 goto exit;
0487 }
0488
0489
0490
0491
0492
0493 address = superio_inb(sioaddr, SIO_REG_ADDR) |
0494 superio_inb(sioaddr, SIO_REG_ADDR + 1) << 8;
0495 if (address == 0) {
0496 pr_warn("Base address not set\n");
0497 err = -ENODEV;
0498 goto exit;
0499 }
0500 err = address;
0501
0502 exit:
0503 superio_exit(sioaddr);
0504 return err;
0505 }
0506
0507 static int __init sch56xx_device_add(int address, const char *name)
0508 {
0509 struct resource res = {
0510 .start = address,
0511 .end = address + REGION_LENGTH - 1,
0512 .name = name,
0513 .flags = IORESOURCE_IO,
0514 };
0515 int err;
0516
0517 err = acpi_check_resource_conflict(&res);
0518 if (err)
0519 return err;
0520
0521 sch56xx_pdev = platform_device_register_simple(name, -1, &res, 1);
0522
0523 return PTR_ERR_OR_ZERO(sch56xx_pdev);
0524 }
0525
0526 static const struct dmi_system_id sch56xx_dmi_override_table[] __initconst = {
0527 {
0528 .matches = {
0529 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
0530 DMI_MATCH(DMI_PRODUCT_NAME, "CELSIUS W380"),
0531 },
0532 },
0533 {
0534 .matches = {
0535 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
0536 DMI_MATCH(DMI_PRODUCT_NAME, "ESPRIMO P710"),
0537 },
0538 },
0539 {
0540 .matches = {
0541 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
0542 DMI_MATCH(DMI_PRODUCT_NAME, "ESPRIMO E9900"),
0543 },
0544 },
0545 { }
0546 };
0547
0548
0549 static const struct dmi_system_id sch56xx_dmi_table[] __initconst = {
0550 {
0551 .matches = {
0552 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
0553 },
0554 },
0555 { }
0556 };
0557 MODULE_DEVICE_TABLE(dmi, sch56xx_dmi_table);
0558
0559 static int __init sch56xx_init(void)
0560 {
0561 const char *name = NULL;
0562 int address;
0563
0564 if (!ignore_dmi) {
0565 if (!dmi_check_system(sch56xx_dmi_table))
0566 return -ENODEV;
0567
0568 if (!dmi_check_system(sch56xx_dmi_override_table)) {
0569
0570
0571
0572
0573
0574 if (!dmi_find_device(DMI_DEV_TYPE_OTHER, "Antiope", NULL) &&
0575 !dmi_find_device(DMI_DEV_TYPE_OTHER, " Antiope", NULL) &&
0576 !dmi_find_device(DMI_DEV_TYPE_OTHER, "Theseus", NULL) &&
0577 !dmi_find_device(DMI_DEV_TYPE_OTHER, " Theseus", NULL))
0578 return -ENODEV;
0579 }
0580 }
0581
0582
0583
0584
0585
0586 address = sch56xx_find(0x4e, &name);
0587 if (address < 0)
0588 address = sch56xx_find(0x2e, &name);
0589 if (address < 0)
0590 return address;
0591
0592 return sch56xx_device_add(address, name);
0593 }
0594
0595 static void __exit sch56xx_exit(void)
0596 {
0597 platform_device_unregister(sch56xx_pdev);
0598 }
0599
0600 MODULE_DESCRIPTION("SMSC SCH56xx Hardware Monitoring Common Code");
0601 MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
0602 MODULE_LICENSE("GPL");
0603
0604 module_init(sch56xx_init);
0605 module_exit(sch56xx_exit);