Usage of counter_register() yields issues in device lifetime tracking. All drivers were converted to the new API, so the old one can go away.
Unified · Split
| @@ -43,8 +43,7 @@ static void counter_device_release(struct device *dev) · 42 unmodified lines | |||
| 43 | counter_chrdev_remove(counter); | 43 | counter_chrdev_remove(counter); |
| 44 | ida_free(&counter_ida, dev->id); | 44 | ida_free(&counter_ida, dev->id); |
| 45 | 45 | ||
| 46 | if (!counter->legacy_device) | 46 | kfree(container_of(counter, struct counter_device_allochelper, counter)); |
| 47 | kfree(container_of(counter, struct counter_device_allochelper, counter)); | ||
| 48 | } | 47 | } |
| 49 | 48 | ||
| 50 | static struct device_type counter_device_type = { | 49 | static struct device_type counter_device_type = { |
| @@ -67,76 +66,13 @@ static dev_t counter_devt; · 16 unmodified lines | |||
| 67 | */ | 66 | */ |
| 68 | void *counter_priv(const struct counter_device *const counter) | 67 | void *counter_priv(const struct counter_device *const counter) |
| 69 | { | 68 | { |
| 70 | if (counter->legacy_device) { | 69 | struct counter_device_allochelper *ch = |
| 71 | return counter->priv; | 70 | container_of(counter, struct counter_device_allochelper, counter); |
| 72 | } else { | ||
| 73 | struct counter_device_allochelper *ch = | ||
| 74 | container_of(counter, struct counter_device_allochelper, counter); | ||
| 75 | 71 | ||
| 76 | return &ch->privdata; | 72 | return &ch->privdata; |
| 77 | } | ||
| 78 | } | 73 | } |
| 79 | EXPORT_SYMBOL_GPL(counter_priv); | 74 | EXPORT_SYMBOL_GPL(counter_priv); |
| 80 | 75 | ||
| 81 | /** | ||
| 82 | * counter_register - register Counter to the system | ||
| 83 | * @counter: pointer to Counter to register | ||
| 84 | * | ||
| 85 | * This function registers a Counter to the system. A sysfs "counter" directory | ||
| 86 | * will be created and populated with sysfs attributes correlating with the | ||
| 87 | * Counter Signals, Synapses, and Counts respectively. | ||
| 88 | * | ||
| 89 | * RETURNS: | ||
| 90 | * 0 on success, negative error number on failure. | ||
| 91 | */ | ||
| 92 | int counter_register(struct counter_device *const counter) | ||
| 93 | { | ||
| 94 | struct device *const dev = &counter->dev; | ||
| 95 | int id; | ||
| 96 | int err; | ||
| 97 | |||
| 98 | counter->legacy_device = true; | ||
| 99 | |||
| 100 | /* Acquire unique ID */ | ||
| 101 | id = ida_alloc(&counter_ida, GFP_KERNEL); | ||
| 102 | if (id < 0) | ||
| 103 | return id; | ||
| 104 | |||
| 105 | mutex_init(&counter->ops_exist_lock); | ||
| 106 | |||
| 107 | /* Configure device structure for Counter */ | ||
| 108 | dev->id = id; | ||
| 109 | dev->type = &counter_device_type; | ||
| 110 | dev->bus = &counter_bus_type; | ||
| 111 | dev->devt = MKDEV(MAJOR(counter_devt), id); | ||
| 112 | if (counter->parent) { | ||
| 113 | dev->parent = counter->parent; | ||
| 114 | dev->of_node = counter->parent->of_node; | ||
| 115 | } | ||
| 116 | device_initialize(dev); | ||
| 117 | |||
| 118 | err = counter_sysfs_add(counter); | ||
| 119 | if (err < 0) | ||
| 120 | goto err_free_id; | ||
| 121 | |||
| 122 | err = counter_chrdev_add(counter); | ||
| 123 | if (err < 0) | ||
| 124 | goto err_free_id; | ||
| 125 | |||
| 126 | err = cdev_device_add(&counter->chrdev, dev); | ||
| 127 | if (err < 0) | ||
| 128 | goto err_remove_chrdev; | ||
| 129 | |||
| 130 | return 0; | ||
| 131 | |||
| 132 | err_remove_chrdev: | ||
| 133 | counter_chrdev_remove(counter); | ||
| 134 | err_free_id: | ||
| 135 | put_device(dev); | ||
| 136 | return err; | ||
| 137 | } | ||
| 138 | EXPORT_SYMBOL_GPL(counter_register); | ||
| 139 | |||
| 140 | /** | 76 | /** |
| 141 | * counter_alloc - allocate a counter_device | 77 | * counter_alloc - allocate a counter_device |
| 142 | * @sizeof_priv: size of the driver private data | 78 | * @sizeof_priv: size of the driver private data |
| @@ -245,9 +181,6 @@ void counter_unregister(struct counter_device *const counter) · 102 unmodified lines | |||
| 245 | wake_up(&counter->events_wait); | 181 | wake_up(&counter->events_wait); |
| 246 | 182 | ||
| 247 | mutex_unlock(&counter->ops_exist_lock); | 183 | mutex_unlock(&counter->ops_exist_lock); |
| 248 | |||
| 249 | if (counter->legacy_device) | ||
| 250 | put_device(&counter->dev); | ||
| 251 | } | 184 | } |
| 252 | EXPORT_SYMBOL_GPL(counter_unregister); | 185 | EXPORT_SYMBOL_GPL(counter_unregister); |
| 253 | 186 | ||
| @@ -256,31 +189,6 @@ static void devm_counter_release(void *counter) · 2 unmodified lines | |||
| 256 | counter_unregister(counter); | 189 | counter_unregister(counter); |
| 257 | } | 190 | } |
| 258 | 191 | ||
| 259 | /** | ||
| 260 | * devm_counter_register - Resource-managed counter_register | ||
| 261 | * @dev: device to allocate counter_device for | ||
| 262 | * @counter: pointer to Counter to register | ||
| 263 | * | ||
| 264 | * Managed counter_register. The Counter registered with this function is | ||
| 265 | * automatically unregistered on driver detach. This function calls | ||
| 266 | * counter_register internally. Refer to that function for more information. | ||
| 267 | * | ||
| 268 | * RETURNS: | ||
| 269 | * 0 on success, negative error number on failure. | ||
| 270 | */ | ||
| 271 | int devm_counter_register(struct device *dev, | ||
| 272 | struct counter_device *const counter) | ||
| 273 | { | ||
| 274 | int err; | ||
| 275 | |||
| 276 | err = counter_register(counter); | ||
| 277 | if (err < 0) | ||
| 278 | return err; | ||
| 279 | |||
| 280 | return devm_add_action_or_reset(dev, devm_counter_release, counter); | ||
| 281 | } | ||
| 282 | EXPORT_SYMBOL_GPL(devm_counter_register); | ||
| 283 | |||
| 284 | static void devm_counter_put(void *counter) | 192 | static void devm_counter_put(void *counter) |
| 285 | { | 193 | { |
| 286 | counter_put(counter); | 194 | counter_put(counter); |
| @@ -314,8 +314,6 @@ struct counter_device { · 313 unmodified lines | |||
| 314 | struct counter_comp *ext; | 314 | struct counter_comp *ext; |
| 315 | size_t num_ext; | 315 | size_t num_ext; |
| 316 | 316 | ||
| 317 | void *priv; | ||
| 318 | |||
| 319 | struct device dev; | 317 | struct device dev; |
| 320 | struct cdev chrdev; | 318 | struct cdev chrdev; |
| 321 | struct list_head events_list; | 319 | struct list_head events_list; |
| @@ -327,25 +325,15 @@ struct counter_device { · 5 unmodified lines | |||
| 327 | spinlock_t events_in_lock; | 325 | spinlock_t events_in_lock; |
| 328 | struct mutex events_out_lock; | 326 | struct mutex events_out_lock; |
| 329 | struct mutex ops_exist_lock; | 327 | struct mutex ops_exist_lock; |
| 330 | |||
| 331 | /* | ||
| 332 | * This can go away once all drivers are converted to | ||
| 333 | * counter_alloc()/counter_add(). | ||
| 334 | */ | ||
| 335 | bool legacy_device; | ||
| 336 | }; | 328 | }; |
| 337 | 329 | ||
| 338 | void *counter_priv(const struct counter_device *const counter); | 330 | void *counter_priv(const struct counter_device *const counter); |
| 339 | 331 | ||
| 340 | int counter_register(struct counter_device *const counter); | ||
| 341 | |||
| 342 | struct counter_device *counter_alloc(size_t sizeof_priv); | 332 | struct counter_device *counter_alloc(size_t sizeof_priv); |
| 343 | void counter_put(struct counter_device *const counter); | 333 | void counter_put(struct counter_device *const counter); |
| 344 | int counter_add(struct counter_device *const counter); | 334 | int counter_add(struct counter_device *const counter); |
| 345 | 335 | ||
| 346 | void counter_unregister(struct counter_device *const counter); | 336 | void counter_unregister(struct counter_device *const counter); |
| 347 | int devm_counter_register(struct device *dev, | ||
| 348 | struct counter_device *const counter); | ||
| 349 | struct counter_device *devm_counter_alloc(struct device *dev, | 337 | struct counter_device *devm_counter_alloc(struct device *dev, |
| 350 | size_t sizeof_priv); | 338 | size_t sizeof_priv); |
| 351 | int devm_counter_add(struct device *dev, | 339 | int devm_counter_add(struct device *dev, |