Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

misc: keba: Add fan device

Add support for the fan auxiliary device. This enables monitoring of the
fan.

Signed-off-by: Gerhard Engleder <eg@keba.com>
Link: https://lore.kernel.org/r/20241011191257.19702-7-gerhard@engleder-embedded.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Gerhard Engleder and committed by
Greg Kroah-Hartman
f965d315 c6576d91

+84 -9
+74 -9
drivers/misc/keba/cp500.c
··· 32 32 /* BAR 0 registers */ 33 33 #define CP500_VERSION_REG 0x00 34 34 #define CP500_RECONFIG_REG 0x11 /* upper 8-bits of STARTUP register */ 35 + #define CP500_PRESENT_REG 0x20 35 36 #define CP500_AXI_REG 0x40 36 37 37 38 /* Bits in BUILD_REG */ ··· 40 39 41 40 /* Bits in RECONFIG_REG */ 42 41 #define CP500_RECFG_REQ 0x01 /* reconfigure FPGA on next reset */ 42 + 43 + /* Bits in PRESENT_REG */ 44 + #define CP500_PRESENT_FAN0 0x01 43 45 44 46 /* MSIX */ 45 47 #define CP500_AXI_MSIX 3 ··· 81 77 struct cp500_dev_info startup; 82 78 struct cp500_dev_info spi; 83 79 struct cp500_dev_info i2c; 80 + struct cp500_dev_info fan; 84 81 }; 85 82 86 83 /* list of devices within FPGA of CP035 family (CP035, CP056, CP057) */ 87 84 static struct cp500_devs cp035_devices = { 88 - .startup = { 0x0000, SZ_4K }, 89 - .spi = { 0x1000, SZ_4K }, 90 - .i2c = { 0x4000, SZ_4K }, 85 + .startup = { 0x0000, SZ_4K }, 86 + .spi = { 0x1000, SZ_4K }, 87 + .i2c = { 0x4000, SZ_4K }, 88 + .fan = { 0x9000, SZ_4K }, 91 89 }; 92 90 93 91 /* list of devices within FPGA of CP505 family (CP503, CP505, CP507) */ 94 92 static struct cp500_devs cp505_devices = { 95 - .startup = { 0x0000, SZ_4K }, 96 - .spi = { 0x4000, SZ_4K }, 97 - .i2c = { 0x5000, SZ_4K }, 93 + .startup = { 0x0000, SZ_4K }, 94 + .spi = { 0x4000, SZ_4K }, 95 + .i2c = { 0x5000, SZ_4K }, 96 + .fan = { 0x9000, SZ_4K }, 98 97 }; 99 98 100 99 /* list of devices within FPGA of CP520 family (CP520, CP530) */ 101 100 static struct cp500_devs cp520_devices = { 102 - .startup = { 0x0000, SZ_4K }, 103 - .spi = { 0x4000, SZ_4K }, 104 - .i2c = { 0x5000, SZ_4K }, 101 + .startup = { 0x0000, SZ_4K }, 102 + .spi = { 0x4000, SZ_4K }, 103 + .i2c = { 0x5000, SZ_4K }, 104 + .fan = { 0x8000, SZ_4K }, 105 105 }; 106 106 107 107 struct cp500_nvmem { ··· 129 121 resource_size_t sys_hwbase; 130 122 struct keba_spi_auxdev *spi; 131 123 struct keba_i2c_auxdev *i2c; 124 + struct keba_fan_auxdev *fan; 132 125 133 126 /* ECM EtherCAT BAR */ 134 127 resource_size_t ecm_hwbase; ··· 409 400 return 0; 410 401 } 411 402 403 + static void cp500_fan_release(struct device *dev) 404 + { 405 + struct keba_fan_auxdev *fan = 406 + container_of(dev, struct keba_fan_auxdev, auxdev.dev); 407 + 408 + kfree(fan); 409 + } 410 + 411 + static int cp500_register_fan(struct cp500 *cp500) 412 + { 413 + int ret; 414 + 415 + cp500->fan = kzalloc(sizeof(*cp500->fan), GFP_KERNEL); 416 + if (!cp500->fan) 417 + return -ENOMEM; 418 + 419 + cp500->fan->auxdev.name = "fan"; 420 + cp500->fan->auxdev.id = 0; 421 + cp500->fan->auxdev.dev.release = cp500_fan_release; 422 + cp500->fan->auxdev.dev.parent = &cp500->pci_dev->dev; 423 + cp500->fan->io = (struct resource) { 424 + /* fan register area */ 425 + .start = (resource_size_t) cp500->sys_hwbase + 426 + cp500->devs->fan.offset, 427 + .end = (resource_size_t) cp500->sys_hwbase + 428 + cp500->devs->fan.offset + 429 + cp500->devs->fan.size - 1, 430 + .flags = IORESOURCE_MEM, 431 + }; 432 + 433 + ret = auxiliary_device_init(&cp500->fan->auxdev); 434 + if (ret) { 435 + kfree(cp500->fan); 436 + cp500->fan = NULL; 437 + 438 + return ret; 439 + } 440 + ret = __auxiliary_device_add(&cp500->fan->auxdev, "keba"); 441 + if (ret) { 442 + auxiliary_device_uninit(&cp500->fan->auxdev); 443 + cp500->fan = NULL; 444 + 445 + return ret; 446 + } 447 + 448 + return 0; 449 + } 450 + 412 451 static int cp500_nvmem_read(void *priv, unsigned int offset, void *val, 413 452 size_t bytes) 414 453 { ··· 606 549 static void cp500_register_auxiliary_devs(struct cp500 *cp500) 607 550 { 608 551 struct device *dev = &cp500->pci_dev->dev; 552 + u8 present = ioread8(cp500->system_startup_addr + CP500_PRESENT_REG); 609 553 610 554 if (cp500_register_i2c(cp500)) 611 555 dev_warn(dev, "Failed to register I2C!\n"); 556 + if (present & CP500_PRESENT_FAN0) 557 + if (cp500_register_fan(cp500)) 558 + dev_warn(dev, "Failed to register fan!\n"); 612 559 } 613 560 614 561 static void cp500_unregister_dev(struct auxiliary_device *auxdev) ··· 630 569 if (cp500->i2c) { 631 570 cp500_unregister_dev(&cp500->i2c->auxdev); 632 571 cp500->i2c = NULL; 572 + } 573 + if (cp500->fan) { 574 + cp500_unregister_dev(&cp500->fan->auxdev); 575 + cp500->fan = NULL; 633 576 } 634 577 } 635 578
+10
include/linux/misc/keba.h
··· 37 37 struct spi_board_info *info; 38 38 }; 39 39 40 + /** 41 + * struct keba_fan_auxdev - KEBA fan auxiliary device 42 + * @auxdev: auxiliary device object 43 + * @io: address range of fan controller IO memory 44 + */ 45 + struct keba_fan_auxdev { 46 + struct auxiliary_device auxdev; 47 + struct resource io; 48 + }; 49 + 40 50 #endif /* _LINUX_MISC_KEBA_H */