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.

Merge branch 'dpll-zl3073x-consolidate-chip-info-and-add-temperature-reporting'

Ivan Vecera says:

====================
dpll: zl3073x: consolidate chip info and add temperature reporting

This series refactors the ZL3073x chip variant handling and adds die
temperature reporting for chips that support it.

Patch 1 replaces the five per-variant chip_info structures and their
exported symbols with a single consolidated lookup table. The chip
variant is now detected at runtime from the chip ID register rather
than being selected at compile time via bus driver match data. This
simplifies the I2C/SPI drivers and makes adding new variants a
single-line table addition. A flags field replaces the hardcoded
chip_id switch in zl3073x_dev_is_ref_phase_comp_32bit().

Patch 2 uses the new flags infrastructure to add die temperature
reporting for chip variants that provide a temperature status register.
The temp_get callback is conditionally set during device registration
based on the ZL3073X_FLAG_DIE_TEMP chip flag.
====================

Link: https://patch.msgid.link/20260227105300.710272-1-ivecera@redhat.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>

+112 -169
+32 -84
drivers/dpll/zl3073x/core.c
··· 20 20 #include "dpll.h" 21 21 #include "regs.h" 22 22 23 - /* Chip IDs for zl30731 */ 24 - static const u16 zl30731_ids[] = { 25 - 0x0E93, 26 - 0x1E93, 27 - 0x2E93, 28 - }; 23 + #define ZL_CHIP_INFO(_id, _nchannels, _flags) \ 24 + { .id = (_id), .num_channels = (_nchannels), .flags = (_flags) } 29 25 30 - const struct zl3073x_chip_info zl30731_chip_info = { 31 - .ids = zl30731_ids, 32 - .num_ids = ARRAY_SIZE(zl30731_ids), 33 - .num_channels = 1, 26 + static const struct zl3073x_chip_info zl3073x_chip_ids[] = { 27 + ZL_CHIP_INFO(0x0E30, 2, ZL3073X_FLAG_REF_PHASE_COMP_32), 28 + ZL_CHIP_INFO(0x0E93, 1, ZL3073X_FLAG_REF_PHASE_COMP_32), 29 + ZL_CHIP_INFO(0x0E94, 2, ZL3073X_FLAG_REF_PHASE_COMP_32), 30 + ZL_CHIP_INFO(0x0E95, 3, ZL3073X_FLAG_REF_PHASE_COMP_32), 31 + ZL_CHIP_INFO(0x0E96, 4, ZL3073X_FLAG_REF_PHASE_COMP_32), 32 + ZL_CHIP_INFO(0x0E97, 5, ZL3073X_FLAG_REF_PHASE_COMP_32), 33 + ZL_CHIP_INFO(0x1E93, 1, ZL3073X_FLAG_DIE_TEMP), 34 + ZL_CHIP_INFO(0x1E94, 2, ZL3073X_FLAG_DIE_TEMP), 35 + ZL_CHIP_INFO(0x1E95, 3, ZL3073X_FLAG_DIE_TEMP), 36 + ZL_CHIP_INFO(0x1E96, 4, ZL3073X_FLAG_DIE_TEMP), 37 + ZL_CHIP_INFO(0x1E97, 5, ZL3073X_FLAG_DIE_TEMP), 38 + ZL_CHIP_INFO(0x1F60, 2, ZL3073X_FLAG_REF_PHASE_COMP_32), 39 + ZL_CHIP_INFO(0x2E93, 1, ZL3073X_FLAG_DIE_TEMP), 40 + ZL_CHIP_INFO(0x2E94, 2, ZL3073X_FLAG_DIE_TEMP), 41 + ZL_CHIP_INFO(0x2E95, 3, ZL3073X_FLAG_DIE_TEMP), 42 + ZL_CHIP_INFO(0x2E96, 4, ZL3073X_FLAG_DIE_TEMP), 43 + ZL_CHIP_INFO(0x2E97, 5, ZL3073X_FLAG_DIE_TEMP), 44 + ZL_CHIP_INFO(0x3FC4, 2, ZL3073X_FLAG_DIE_TEMP), 34 45 }; 35 - EXPORT_SYMBOL_NS_GPL(zl30731_chip_info, "ZL3073X"); 36 - 37 - /* Chip IDs for zl30732 */ 38 - static const u16 zl30732_ids[] = { 39 - 0x0E30, 40 - 0x0E94, 41 - 0x1E94, 42 - 0x1F60, 43 - 0x2E94, 44 - 0x3FC4, 45 - }; 46 - 47 - const struct zl3073x_chip_info zl30732_chip_info = { 48 - .ids = zl30732_ids, 49 - .num_ids = ARRAY_SIZE(zl30732_ids), 50 - .num_channels = 2, 51 - }; 52 - EXPORT_SYMBOL_NS_GPL(zl30732_chip_info, "ZL3073X"); 53 - 54 - /* Chip IDs for zl30733 */ 55 - static const u16 zl30733_ids[] = { 56 - 0x0E95, 57 - 0x1E95, 58 - 0x2E95, 59 - }; 60 - 61 - const struct zl3073x_chip_info zl30733_chip_info = { 62 - .ids = zl30733_ids, 63 - .num_ids = ARRAY_SIZE(zl30733_ids), 64 - .num_channels = 3, 65 - }; 66 - EXPORT_SYMBOL_NS_GPL(zl30733_chip_info, "ZL3073X"); 67 - 68 - /* Chip IDs for zl30734 */ 69 - static const u16 zl30734_ids[] = { 70 - 0x0E96, 71 - 0x1E96, 72 - 0x2E96, 73 - }; 74 - 75 - const struct zl3073x_chip_info zl30734_chip_info = { 76 - .ids = zl30734_ids, 77 - .num_ids = ARRAY_SIZE(zl30734_ids), 78 - .num_channels = 4, 79 - }; 80 - EXPORT_SYMBOL_NS_GPL(zl30734_chip_info, "ZL3073X"); 81 - 82 - /* Chip IDs for zl30735 */ 83 - static const u16 zl30735_ids[] = { 84 - 0x0E97, 85 - 0x1E97, 86 - 0x2E97, 87 - }; 88 - 89 - const struct zl3073x_chip_info zl30735_chip_info = { 90 - .ids = zl30735_ids, 91 - .num_ids = ARRAY_SIZE(zl30735_ids), 92 - .num_channels = 5, 93 - }; 94 - EXPORT_SYMBOL_NS_GPL(zl30735_chip_info, "ZL3073X"); 95 46 96 47 #define ZL_RANGE_OFFSET 0x80 97 48 #define ZL_PAGE_SIZE 0x80 ··· 893 942 } 894 943 895 944 static int 896 - zl3073x_devm_dpll_init(struct zl3073x_dev *zldev, u8 num_dplls) 945 + zl3073x_devm_dpll_init(struct zl3073x_dev *zldev) 897 946 { 898 947 struct kthread_worker *kworker; 899 948 struct zl3073x_dpll *zldpll; ··· 903 952 INIT_LIST_HEAD(&zldev->dplls); 904 953 905 954 /* Allocate all DPLLs */ 906 - for (i = 0; i < num_dplls; i++) { 955 + for (i = 0; i < zldev->info->num_channels; i++) { 907 956 zldpll = zl3073x_dpll_alloc(zldev, i); 908 957 if (IS_ERR(zldpll)) { 909 958 dev_err_probe(zldev->dev, PTR_ERR(zldpll), ··· 943 992 /** 944 993 * zl3073x_dev_probe - initialize zl3073x device 945 994 * @zldev: pointer to zl3073x device 946 - * @chip_info: chip info based on compatible 947 995 * 948 996 * Common initialization of zl3073x device structure. 949 997 * 950 998 * Returns: 0 on success, <0 on error 951 999 */ 952 - int zl3073x_dev_probe(struct zl3073x_dev *zldev, 953 - const struct zl3073x_chip_info *chip_info) 1000 + int zl3073x_dev_probe(struct zl3073x_dev *zldev) 954 1001 { 955 1002 u16 id, revision, fw_ver; 956 1003 unsigned int i; ··· 960 1011 if (rc) 961 1012 return rc; 962 1013 963 - /* Check it matches */ 964 - for (i = 0; i < chip_info->num_ids; i++) { 965 - if (id == chip_info->ids[i]) 1014 + /* Detect chip variant */ 1015 + for (i = 0; i < ARRAY_SIZE(zl3073x_chip_ids); i++) { 1016 + if (zl3073x_chip_ids[i].id == id) 966 1017 break; 967 1018 } 968 1019 969 - if (i == chip_info->num_ids) { 1020 + if (i == ARRAY_SIZE(zl3073x_chip_ids)) 970 1021 return dev_err_probe(zldev->dev, -ENODEV, 971 - "Unknown or non-match chip ID: 0x%0x\n", 972 - id); 973 - } 974 - zldev->chip_id = id; 1022 + "Unknown chip ID: 0x%04x\n", id); 1023 + 1024 + zldev->info = &zl3073x_chip_ids[i]; 975 1025 976 1026 /* Read revision, firmware version and custom config version */ 977 1027 rc = zl3073x_read_u16(zldev, ZL_REG_REVISION, &revision); ··· 1009 1061 "Failed to initialize mutex\n"); 1010 1062 1011 1063 /* Register DPLL channels */ 1012 - rc = zl3073x_devm_dpll_init(zldev, chip_info->num_channels); 1064 + rc = zl3073x_devm_dpll_init(zldev); 1013 1065 if (rc) 1014 1066 return rc; 1015 1067
+29 -30
drivers/dpll/zl3073x/core.h
··· 30 30 #define ZL3073X_NUM_PINS (ZL3073X_NUM_INPUT_PINS + \ 31 31 ZL3073X_NUM_OUTPUT_PINS) 32 32 33 + enum zl3073x_flags { 34 + ZL3073X_FLAG_REF_PHASE_COMP_32_BIT, 35 + ZL3073X_FLAG_DIE_TEMP_BIT, 36 + ZL3073X_FLAGS_NBITS /* must be last */ 37 + }; 38 + 39 + #define __ZL3073X_FLAG(name) BIT(ZL3073X_FLAG_ ## name ## _BIT) 40 + #define ZL3073X_FLAG_REF_PHASE_COMP_32 __ZL3073X_FLAG(REF_PHASE_COMP_32) 41 + #define ZL3073X_FLAG_DIE_TEMP __ZL3073X_FLAG(DIE_TEMP) 42 + 43 + /** 44 + * struct zl3073x_chip_info - chip variant identification 45 + * @id: chip ID 46 + * @num_channels: number of DPLL channels supported by this variant 47 + * @flags: chip variant flags 48 + */ 49 + struct zl3073x_chip_info { 50 + u16 id; 51 + u8 num_channels; 52 + unsigned long flags; 53 + }; 54 + 33 55 /** 34 56 * struct zl3073x_dev - zl3073x device 35 57 * @dev: pointer to device 36 58 * @regmap: regmap to access device registers 59 + * @info: detected chip info 37 60 * @multiop_lock: to serialize multiple register operations 38 - * @chip_id: chip ID read from hardware 39 61 * @ref: array of input references' invariants 40 62 * @out: array of outs' invariants 41 63 * @synth: array of synths' invariants ··· 68 46 * @phase_avg_factor: phase offset measurement averaging factor 69 47 */ 70 48 struct zl3073x_dev { 71 - struct device *dev; 72 - struct regmap *regmap; 73 - struct mutex multiop_lock; 74 - u16 chip_id; 49 + struct device *dev; 50 + struct regmap *regmap; 51 + const struct zl3073x_chip_info *info; 52 + struct mutex multiop_lock; 75 53 76 54 /* Invariants */ 77 55 struct zl3073x_ref ref[ZL3073X_NUM_REFS]; ··· 90 68 u8 phase_avg_factor; 91 69 }; 92 70 93 - struct zl3073x_chip_info { 94 - const u16 *ids; 95 - size_t num_ids; 96 - int num_channels; 97 - }; 98 - 99 - extern const struct zl3073x_chip_info zl30731_chip_info; 100 - extern const struct zl3073x_chip_info zl30732_chip_info; 101 - extern const struct zl3073x_chip_info zl30733_chip_info; 102 - extern const struct zl3073x_chip_info zl30734_chip_info; 103 - extern const struct zl3073x_chip_info zl30735_chip_info; 104 71 extern const struct regmap_config zl3073x_regmap_config; 105 72 106 73 struct zl3073x_dev *zl3073x_devm_alloc(struct device *dev); 107 - int zl3073x_dev_probe(struct zl3073x_dev *zldev, 108 - const struct zl3073x_chip_info *chip_info); 74 + int zl3073x_dev_probe(struct zl3073x_dev *zldev); 109 75 110 76 int zl3073x_dev_start(struct zl3073x_dev *zldev, bool full); 111 77 void zl3073x_dev_stop(struct zl3073x_dev *zldev); ··· 168 158 static inline bool 169 159 zl3073x_dev_is_ref_phase_comp_32bit(struct zl3073x_dev *zldev) 170 160 { 171 - switch (zldev->chip_id) { 172 - case 0x0E30: 173 - case 0x0E93: 174 - case 0x0E94: 175 - case 0x0E95: 176 - case 0x0E96: 177 - case 0x0E97: 178 - case 0x1F60: 179 - return true; 180 - default: 181 - return false; 182 - } 161 + return zldev->info->flags & ZL3073X_FLAG_REF_PHASE_COMP_32; 183 162 } 184 163 185 164 static inline bool
+25 -3
drivers/dpll/zl3073x/dpll.c
··· 1066 1066 } 1067 1067 1068 1068 static int 1069 + zl3073x_dpll_temp_get(const struct dpll_device *dpll, void *dpll_priv, 1070 + s32 *temp, struct netlink_ext_ack *extack) 1071 + { 1072 + struct zl3073x_dpll *zldpll = dpll_priv; 1073 + struct zl3073x_dev *zldev = zldpll->dev; 1074 + u16 val; 1075 + int rc; 1076 + 1077 + rc = zl3073x_read_u16(zldev, ZL_REG_DIE_TEMP_STATUS, &val); 1078 + if (rc) 1079 + return rc; 1080 + 1081 + /* Register value is in units of 0.1 C, convert to millidegrees */ 1082 + *temp = (s16)val * 100; 1083 + 1084 + return 0; 1085 + } 1086 + 1087 + static int 1069 1088 zl3073x_dpll_lock_status_get(const struct dpll_device *dpll, void *dpll_priv, 1070 1089 enum dpll_lock_status *status, 1071 1090 enum dpll_lock_status_error *status_error, ··· 1690 1671 zldpll->forced_ref = FIELD_GET(ZL_DPLL_MODE_REFSEL_REF, 1691 1672 dpll_mode_refsel); 1692 1673 1674 + zldpll->ops = zl3073x_dpll_device_ops; 1675 + if (zldev->info->flags & ZL3073X_FLAG_DIE_TEMP) 1676 + zldpll->ops.temp_get = zl3073x_dpll_temp_get; 1677 + 1693 1678 zldpll->dpll_dev = dpll_device_get(zldev->clock_id, zldpll->id, 1694 1679 THIS_MODULE, &zldpll->tracker); 1695 1680 if (IS_ERR(zldpll->dpll_dev)) { ··· 1705 1682 1706 1683 rc = dpll_device_register(zldpll->dpll_dev, 1707 1684 zl3073x_prop_dpll_type_get(zldev, zldpll->id), 1708 - &zl3073x_dpll_device_ops, zldpll); 1685 + &zldpll->ops, zldpll); 1709 1686 if (rc) { 1710 1687 dpll_device_put(zldpll->dpll_dev, &zldpll->tracker); 1711 1688 zldpll->dpll_dev = NULL; ··· 1728 1705 1729 1706 cancel_work_sync(&zldpll->change_work); 1730 1707 1731 - dpll_device_unregister(zldpll->dpll_dev, &zl3073x_dpll_device_ops, 1732 - zldpll); 1708 + dpll_device_unregister(zldpll->dpll_dev, &zldpll->ops, zldpll); 1733 1709 dpll_device_put(zldpll->dpll_dev, &zldpll->tracker); 1734 1710 zldpll->dpll_dev = NULL; 1735 1711 }
+2
drivers/dpll/zl3073x/dpll.h
··· 17 17 * @forced_ref: selected reference in forced reference lock mode 18 18 * @check_count: periodic check counter 19 19 * @phase_monitor: is phase offset monitor enabled 20 + * @ops: DPLL device operations for this instance 20 21 * @dpll_dev: pointer to registered DPLL device 21 22 * @tracker: tracking object for the acquired reference 22 23 * @lock_status: last saved DPLL lock status ··· 32 31 u8 forced_ref; 33 32 u8 check_count; 34 33 bool phase_monitor; 34 + struct dpll_device_ops ops; 35 35 struct dpll_device *dpll_dev; 36 36 dpll_tracker tracker; 37 37 enum dpll_lock_status lock_status;
+11 -26
drivers/dpll/zl3073x/i2c.c
··· 22 22 return dev_err_probe(dev, PTR_ERR(zldev->regmap), 23 23 "Failed to initialize regmap\n"); 24 24 25 - return zl3073x_dev_probe(zldev, i2c_get_match_data(client)); 25 + return zl3073x_dev_probe(zldev); 26 26 } 27 27 28 28 static const struct i2c_device_id zl3073x_i2c_id[] = { 29 - { 30 - .name = "zl30731", 31 - .driver_data = (kernel_ulong_t)&zl30731_chip_info, 32 - }, 33 - { 34 - .name = "zl30732", 35 - .driver_data = (kernel_ulong_t)&zl30732_chip_info, 36 - }, 37 - { 38 - .name = "zl30733", 39 - .driver_data = (kernel_ulong_t)&zl30733_chip_info, 40 - }, 41 - { 42 - .name = "zl30734", 43 - .driver_data = (kernel_ulong_t)&zl30734_chip_info, 44 - }, 45 - { 46 - .name = "zl30735", 47 - .driver_data = (kernel_ulong_t)&zl30735_chip_info, 48 - }, 29 + { "zl30731" }, 30 + { "zl30732" }, 31 + { "zl30733" }, 32 + { "zl30734" }, 33 + { "zl30735" }, 49 34 { /* sentinel */ } 50 35 }; 51 36 MODULE_DEVICE_TABLE(i2c, zl3073x_i2c_id); 52 37 53 38 static const struct of_device_id zl3073x_i2c_of_match[] = { 54 - { .compatible = "microchip,zl30731", .data = &zl30731_chip_info }, 55 - { .compatible = "microchip,zl30732", .data = &zl30732_chip_info }, 56 - { .compatible = "microchip,zl30733", .data = &zl30733_chip_info }, 57 - { .compatible = "microchip,zl30734", .data = &zl30734_chip_info }, 58 - { .compatible = "microchip,zl30735", .data = &zl30735_chip_info }, 39 + { .compatible = "microchip,zl30731" }, 40 + { .compatible = "microchip,zl30732" }, 41 + { .compatible = "microchip,zl30733" }, 42 + { .compatible = "microchip,zl30734" }, 43 + { .compatible = "microchip,zl30735" }, 59 44 { /* sentinel */ } 60 45 }; 61 46 MODULE_DEVICE_TABLE(of, zl3073x_i2c_of_match);
+2
drivers/dpll/zl3073x/regs.h
··· 78 78 #define ZL_REG_RESET_STATUS ZL_REG(0, 0x18, 1) 79 79 #define ZL_REG_RESET_STATUS_RESET BIT(0) 80 80 81 + #define ZL_REG_DIE_TEMP_STATUS ZL_REG(0, 0x44, 2) 82 + 81 83 /************************* 82 84 * Register Page 2, Status 83 85 *************************/
+11 -26
drivers/dpll/zl3073x/spi.c
··· 22 22 return dev_err_probe(dev, PTR_ERR(zldev->regmap), 23 23 "Failed to initialize regmap\n"); 24 24 25 - return zl3073x_dev_probe(zldev, spi_get_device_match_data(spi)); 25 + return zl3073x_dev_probe(zldev); 26 26 } 27 27 28 28 static const struct spi_device_id zl3073x_spi_id[] = { 29 - { 30 - .name = "zl30731", 31 - .driver_data = (kernel_ulong_t)&zl30731_chip_info 32 - }, 33 - { 34 - .name = "zl30732", 35 - .driver_data = (kernel_ulong_t)&zl30732_chip_info, 36 - }, 37 - { 38 - .name = "zl30733", 39 - .driver_data = (kernel_ulong_t)&zl30733_chip_info, 40 - }, 41 - { 42 - .name = "zl30734", 43 - .driver_data = (kernel_ulong_t)&zl30734_chip_info, 44 - }, 45 - { 46 - .name = "zl30735", 47 - .driver_data = (kernel_ulong_t)&zl30735_chip_info, 48 - }, 29 + { "zl30731" }, 30 + { "zl30732" }, 31 + { "zl30733" }, 32 + { "zl30734" }, 33 + { "zl30735" }, 49 34 { /* sentinel */ } 50 35 }; 51 36 MODULE_DEVICE_TABLE(spi, zl3073x_spi_id); 52 37 53 38 static const struct of_device_id zl3073x_spi_of_match[] = { 54 - { .compatible = "microchip,zl30731", .data = &zl30731_chip_info }, 55 - { .compatible = "microchip,zl30732", .data = &zl30732_chip_info }, 56 - { .compatible = "microchip,zl30733", .data = &zl30733_chip_info }, 57 - { .compatible = "microchip,zl30734", .data = &zl30734_chip_info }, 58 - { .compatible = "microchip,zl30735", .data = &zl30735_chip_info }, 39 + { .compatible = "microchip,zl30731" }, 40 + { .compatible = "microchip,zl30732" }, 41 + { .compatible = "microchip,zl30733" }, 42 + { .compatible = "microchip,zl30734" }, 43 + { .compatible = "microchip,zl30735" }, 59 44 { /* sentinel */ } 60 45 }; 61 46 MODULE_DEVICE_TABLE(of, zl3073x_spi_of_match);