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.

pwm: Add a struct device to struct pwm_chip

This replaces the formerly dynamically allocated struct device. This
allows to additionally use it to track the lifetime of the struct
pwm_chip. Otherwise the new struct device provides the same sysfs API as
was provided by the dynamic device before.

Link: https://lore.kernel.org/r/35c65ea7f6de789a568ff39d7b6b4ce80de4b7dc.1710670958.git.u.kleine-koenig@pengutronix.de
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>

+54 -44
+51 -42
drivers/pwm/core.c
··· 343 343 if (!try_module_get(chip->owner)) 344 344 return -ENODEV; 345 345 346 + if (!get_device(&chip->dev)) { 347 + err = -ENODEV; 348 + goto err_get_device; 349 + } 350 + 346 351 if (ops->request) { 347 352 err = ops->request(chip, pwm); 348 353 if (err) { 354 + put_device(&chip->dev); 355 + err_get_device: 349 356 module_put(chip->owner); 350 357 return err; 351 358 } ··· 470 463 471 464 static inline struct pwm_chip *pwmchip_from_dev(struct device *pwmchip_dev) 472 465 { 473 - return dev_get_drvdata(pwmchip_dev); 466 + return container_of(pwmchip_dev, struct pwm_chip, dev); 474 467 } 475 468 476 469 static inline struct pwm_export *pwmexport_from_dev(struct device *pwm_dev) ··· 948 941 .pm = pm_sleep_ptr(&pwm_class_pm_ops), 949 942 }; 950 943 951 - static int pwmchip_sysfs_match(struct device *pwmchip_dev, const void *data) 952 - { 953 - return pwmchip_from_dev(pwmchip_dev) == data; 954 - } 955 - 956 - static void pwmchip_sysfs_export(struct pwm_chip *chip) 957 - { 958 - struct device *pwmchip_dev; 959 - 960 - /* 961 - * If device_create() fails the pwm_chip is still usable by 962 - * the kernel it's just not exported. 963 - */ 964 - pwmchip_dev = device_create(&pwm_class, pwmchip_parent(chip), MKDEV(0, 0), chip, 965 - "pwmchip%d", chip->id); 966 - if (IS_ERR(pwmchip_dev)) { 967 - dev_warn(pwmchip_parent(chip), 968 - "device_create failed for pwm_chip sysfs export\n"); 969 - } 970 - } 971 - 972 944 static void pwmchip_sysfs_unexport(struct pwm_chip *chip) 973 945 { 974 - struct device *pwmchip_dev; 975 946 unsigned int i; 976 - 977 - pwmchip_dev = class_find_device(&pwm_class, NULL, chip, 978 - pwmchip_sysfs_match); 979 - if (!pwmchip_dev) 980 - return; 981 947 982 948 for (i = 0; i < chip->npwm; i++) { 983 949 struct pwm_device *pwm = &chip->pwms[i]; 984 950 985 951 if (test_bit(PWMF_EXPORTED, &pwm->flags)) 986 - pwm_unexport_child(pwmchip_dev, pwm); 952 + pwm_unexport_child(&chip->dev, pwm); 987 953 } 988 - 989 - put_device(pwmchip_dev); 990 - device_unregister(pwmchip_dev); 991 954 } 992 955 993 956 #define PWMCHIP_ALIGN ARCH_DMA_MINALIGN ··· 970 993 /* This is the counterpart to pwmchip_alloc() */ 971 994 void pwmchip_put(struct pwm_chip *chip) 972 995 { 973 - kfree(chip); 996 + put_device(&chip->dev); 974 997 } 975 998 EXPORT_SYMBOL_GPL(pwmchip_put); 999 + 1000 + static void pwmchip_release(struct device *pwmchip_dev) 1001 + { 1002 + struct pwm_chip *chip = pwmchip_from_dev(pwmchip_dev); 1003 + 1004 + kfree(chip); 1005 + } 976 1006 977 1007 struct pwm_chip *pwmchip_alloc(struct device *parent, unsigned int npwm, size_t sizeof_priv) 978 1008 { 979 1009 struct pwm_chip *chip; 1010 + struct device *pwmchip_dev; 980 1011 size_t alloc_size; 981 1012 unsigned int i; 982 1013 ··· 995 1010 if (!chip) 996 1011 return ERR_PTR(-ENOMEM); 997 1012 998 - chip->dev = parent; 999 1013 chip->npwm = npwm; 1000 1014 chip->uses_pwmchip_alloc = true; 1015 + 1016 + pwmchip_dev = &chip->dev; 1017 + device_initialize(pwmchip_dev); 1018 + pwmchip_dev->class = &pwm_class; 1019 + pwmchip_dev->parent = parent; 1020 + pwmchip_dev->release = pwmchip_release; 1001 1021 1002 1022 pwmchip_set_drvdata(chip, pwmchip_priv(chip)); 1003 1023 ··· 1105 1115 mutex_lock(&pwm_lock); 1106 1116 1107 1117 ret = idr_alloc(&pwm_chips, chip, 0, 0, GFP_KERNEL); 1108 - if (ret < 0) { 1109 - mutex_unlock(&pwm_lock); 1110 - return ret; 1111 - } 1118 + if (ret < 0) 1119 + goto err_idr_alloc; 1112 1120 1113 1121 chip->id = ret; 1114 1122 1115 - mutex_unlock(&pwm_lock); 1123 + dev_set_name(&chip->dev, "pwmchip%u", chip->id); 1116 1124 1117 1125 if (IS_ENABLED(CONFIG_OF)) 1118 1126 of_pwmchip_add(chip); 1119 1127 1120 - pwmchip_sysfs_export(chip); 1128 + ret = device_add(&chip->dev); 1129 + if (ret) 1130 + goto err_device_add; 1131 + 1132 + mutex_unlock(&pwm_lock); 1121 1133 1122 1134 return 0; 1135 + 1136 + err_device_add: 1137 + if (IS_ENABLED(CONFIG_OF)) 1138 + of_pwmchip_remove(chip); 1139 + 1140 + idr_remove(&pwm_chips, chip->id); 1141 + err_idr_alloc: 1142 + 1143 + mutex_unlock(&pwm_lock); 1144 + 1145 + return ret; 1123 1146 } 1124 1147 EXPORT_SYMBOL_GPL(__pwmchip_add); 1125 1148 ··· 1154 1151 idr_remove(&pwm_chips, chip->id); 1155 1152 1156 1153 mutex_unlock(&pwm_lock); 1154 + 1155 + device_del(&chip->dev); 1157 1156 } 1158 1157 EXPORT_SYMBOL_GPL(pwmchip_remove); 1159 1158 ··· 1525 1520 */ 1526 1521 void pwm_put(struct pwm_device *pwm) 1527 1522 { 1523 + struct pwm_chip *chip = pwm->chip; 1524 + 1528 1525 if (!pwm) 1529 1526 return; 1530 1527 ··· 1537 1530 goto out; 1538 1531 } 1539 1532 1540 - if (pwm->chip->ops->free) 1533 + if (chip->ops->free) 1541 1534 pwm->chip->ops->free(pwm->chip, pwm); 1542 1535 1543 1536 pwm->label = NULL; 1544 1537 1545 - module_put(pwm->chip->owner); 1538 + put_device(&chip->dev); 1539 + 1540 + module_put(chip->owner); 1546 1541 out: 1547 1542 mutex_unlock(&pwm_lock); 1548 1543 }
+3 -2
include/linux/pwm.h
··· 2 2 #ifndef __LINUX_PWM_H 3 3 #define __LINUX_PWM_H 4 4 5 + #include <linux/device.h> 5 6 #include <linux/err.h> 6 7 #include <linux/mutex.h> 7 8 #include <linux/of.h> ··· 278 277 * @pwms: array of PWM devices allocated by the framework 279 278 */ 280 279 struct pwm_chip { 281 - struct device *dev; 280 + struct device dev; 282 281 const struct pwm_ops *ops; 283 282 struct module *owner; 284 283 unsigned int id; ··· 296 295 297 296 static inline struct device *pwmchip_parent(const struct pwm_chip *chip) 298 297 { 299 - return chip->dev; 298 + return chip->dev.parent; 300 299 } 301 300 302 301 static inline void *pwmchip_get_drvdata(struct pwm_chip *chip)