1 /* 2 * drivers/base/power/clock_ops.c - Generic clock manipulation PM callbacks 3 * 4 * Copyright (c) 2011 Rafael J. Wysocki <rjw@sisk.pl>, Renesas Electronics Corp. 5 * 6 * This file is released under the GPLv2. 7 */ 8 9 #include <linux/init.h> 10 #include <linux/kernel.h> 11 #include <linux/io.h> 12 #include <linux/pm.h> 13 #include <linux/pm_clock.h> 14 #include <linux/clk.h> 15 #include <linux/slab.h> 16 #include <linux/err.h> 17 18 #ifdef CONFIG_PM 19 20 enum pce_status { 21 PCE_STATUS_NONE = 0, 22 PCE_STATUS_ACQUIRED, 23 PCE_STATUS_ENABLED, 24 PCE_STATUS_ERROR, 25 }; 26 27 struct pm_clock_entry { 28 struct list_head node; 29 char *con_id; 30 struct clk *clk; 31 enum pce_status status; 32 }; 33 34 /** 35 * pm_clk_acquire - Acquire a device clock. 36 * @dev: Device whose clock is to be acquired. 37 * @ce: PM clock entry corresponding to the clock. 38 */ 39 static void pm_clk_acquire(struct device *dev, struct pm_clock_entry *ce) 40 { 41 ce->clk = clk_get(dev, ce->con_id); 42 if (IS_ERR(ce->clk)) { 43 ce->status = PCE_STATUS_ERROR; 44 } else { 45 ce->status = PCE_STATUS_ACQUIRED; 46 dev_dbg(dev, "Clock %s managed by runtime PM.\n", ce->con_id); 47 } 48 } 49 50 /** 51 * pm_clk_add - Start using a device clock for power management. 52 * @dev: Device whose clock is going to be used for power management. 53 * @con_id: Connection ID of the clock. 54 * 55 * Add the clock represented by @con_id to the list of clocks used for 56 * the power management of @dev. 57 */ 58 int pm_clk_add(struct device *dev, const char *con_id) 59 { 60 struct pm_subsys_data *psd = dev_to_psd(dev); 61 struct pm_clock_entry *ce; 62 63 if (!psd) 64 return -EINVAL; 65 66 ce = kzalloc(sizeof(*ce), GFP_KERNEL); 67 if (!ce) { 68 dev_err(dev, "Not enough memory for clock entry.\n"); 69 return -ENOMEM; 70 } 71 72 if (con_id) { 73 ce->con_id = kstrdup(con_id, GFP_KERNEL); 74 if (!ce->con_id) { 75 dev_err(dev, 76 "Not enough memory for clock connection ID.\n"); 77 kfree(ce); 78 return -ENOMEM; 79 } 80 } 81 82 pm_clk_acquire(dev, ce); 83 84 spin_lock_irq(&psd->lock); 85 list_add_tail(&ce->node, &psd->clock_list); 86 spin_unlock_irq(&psd->lock); 87 return 0; 88 } 89 90 /** 91 * __pm_clk_remove - Destroy PM clock entry. 92 * @ce: PM clock entry to destroy. 93 */ 94 static void __pm_clk_remove(struct pm_clock_entry *ce) 95 { 96 if (!ce) 97 return; 98 99 if (ce->status < PCE_STATUS_ERROR) { 100 if (ce->status == PCE_STATUS_ENABLED) 101 clk_disable(ce->clk); 102 103 if (ce->status >= PCE_STATUS_ACQUIRED) 104 clk_put(ce->clk); 105 } 106 107 kfree(ce->con_id); 108 kfree(ce); 109 } 110 111 /** 112 * pm_clk_remove - Stop using a device clock for power management. 113 * @dev: Device whose clock should not be used for PM any more. 114 * @con_id: Connection ID of the clock. 115 * 116 * Remove the clock represented by @con_id from the list of clocks used for 117 * the power management of @dev. 118 */ 119 void pm_clk_remove(struct device *dev, const char *con_id) 120 { 121 struct pm_subsys_data *psd = dev_to_psd(dev); 122 struct pm_clock_entry *ce; 123 124 if (!psd) 125 return; 126 127 spin_lock_irq(&psd->lock); 128 129 list_for_each_entry(ce, &psd->clock_list, node) { 130 if (!con_id && !ce->con_id) 131 goto remove; 132 else if (!con_id || !ce->con_id) 133 continue; 134 else if (!strcmp(con_id, ce->con_id)) 135 goto remove; 136 } 137 138 spin_unlock_irq(&psd->lock); 139 return; 140 141 remove: 142 list_del(&ce->node); 143 spin_unlock_irq(&psd->lock); 144 145 __pm_clk_remove(ce); 146 } 147 148 /** 149 * pm_clk_init - Initialize a device's list of power management clocks. 150 * @dev: Device to initialize the list of PM clocks for. 151 * 152 * Initialize the lock and clock_list members of the device's pm_subsys_data 153 * object. 154 */ 155 void pm_clk_init(struct device *dev) 156 { 157 struct pm_subsys_data *psd = dev_to_psd(dev); 158 if (psd) 159 INIT_LIST_HEAD(&psd->clock_list); 160 } 161 162 /** 163 * pm_clk_create - Create and initialize a device's list of PM clocks. 164 * @dev: Device to create and initialize the list of PM clocks for. 165 * 166 * Allocate a struct pm_subsys_data object, initialize its lock and clock_list 167 * members and make the @dev's power.subsys_data field point to it. 168 */ 169 int pm_clk_create(struct device *dev) 170 { 171 int ret = dev_pm_get_subsys_data(dev); 172 return ret < 0 ? ret : 0; 173 } 174 175 /** 176 * pm_clk_destroy - Destroy a device's list of power management clocks. 177 * @dev: Device to destroy the list of PM clocks for. 178 * 179 * Clear the @dev's power.subsys_data field, remove the list of clock entries 180 * from the struct pm_subsys_data object pointed to by it before and free 181 * that object. 182 */ 183 void pm_clk_destroy(struct device *dev) 184 { 185 struct pm_subsys_data *psd = dev_to_psd(dev); 186 struct pm_clock_entry *ce, *c; 187 struct list_head list; 188 189 if (!psd) 190 return; 191 192 INIT_LIST_HEAD(&list); 193 194 spin_lock_irq(&psd->lock); 195 196 list_for_each_entry_safe_reverse(ce, c, &psd->clock_list, node) 197 list_move(&ce->node, &list); 198 199 spin_unlock_irq(&psd->lock); 200 201 dev_pm_put_subsys_data(dev); 202 203 list_for_each_entry_safe_reverse(ce, c, &list, node) { 204 list_del(&ce->node); 205 __pm_clk_remove(ce); 206 } 207 } 208 209 #endif /* CONFIG_PM */ 210 211 #ifdef CONFIG_PM_RUNTIME 212 213 /** 214 * pm_clk_suspend - Disable clocks in a device's PM clock list. 215 * @dev: Device to disable the clocks for. 216 */ 217 int pm_clk_suspend(struct device *dev) 218 { 219 struct pm_subsys_data *psd = dev_to_psd(dev); 220 struct pm_clock_entry *ce; 221 unsigned long flags; 222 223 dev_dbg(dev, "%s()\n", __func__); 224 225 if (!psd) 226 return 0; 227 228 spin_lock_irqsave(&psd->lock, flags); 229 230 list_for_each_entry_reverse(ce, &psd->clock_list, node) { 231 if (ce->status < PCE_STATUS_ERROR) { 232 if (ce->status == PCE_STATUS_ENABLED) 233 clk_disable(ce->clk); 234 ce->status = PCE_STATUS_ACQUIRED; 235 } 236 } 237 238 spin_unlock_irqrestore(&psd->lock, flags); 239 240 return 0; 241 } 242 243 /** 244 * pm_clk_resume - Enable clocks in a device's PM clock list. 245 * @dev: Device to enable the clocks for. 246 */ 247 int pm_clk_resume(struct device *dev) 248 { 249 struct pm_subsys_data *psd = dev_to_psd(dev); 250 struct pm_clock_entry *ce; 251 unsigned long flags; 252 253 dev_dbg(dev, "%s()\n", __func__); 254 255 if (!psd) 256 return 0; 257 258 spin_lock_irqsave(&psd->lock, flags); 259 260 list_for_each_entry(ce, &psd->clock_list, node) { 261 if (ce->status < PCE_STATUS_ERROR) { 262 clk_enable(ce->clk); 263 ce->status = PCE_STATUS_ENABLED; 264 } 265 } 266 267 spin_unlock_irqrestore(&psd->lock, flags); 268 269 return 0; 270 } 271 272 /** 273 * pm_clk_notify - Notify routine for device addition and removal. 274 * @nb: Notifier block object this function is a member of. 275 * @action: Operation being carried out by the caller. 276 * @data: Device the routine is being run for. 277 * 278 * For this function to work, @nb must be a member of an object of type 279 * struct pm_clk_notifier_block containing all of the requisite data. 280 * Specifically, the pm_domain member of that object is copied to the device's 281 * pm_domain field and its con_ids member is used to populate the device's list 282 * of PM clocks, depending on @action. 283 * 284 * If the device's pm_domain field is already populated with a value different 285 * from the one stored in the struct pm_clk_notifier_block object, the function 286 * does nothing. 287 */ 288 static int pm_clk_notify(struct notifier_block *nb, 289 unsigned long action, void *data) 290 { 291 struct pm_clk_notifier_block *clknb; 292 struct device *dev = data; 293 char **con_id; 294 int error; 295 296 dev_dbg(dev, "%s() %ld\n", __func__, action); 297 298 clknb = container_of(nb, struct pm_clk_notifier_block, nb); 299 300 switch (action) { 301 case BUS_NOTIFY_ADD_DEVICE: 302 if (dev->pm_domain) 303 break; 304 305 error = pm_clk_create(dev); 306 if (error) 307 break; 308 309 dev->pm_domain = clknb->pm_domain; 310 if (clknb->con_ids[0]) { 311 for (con_id = clknb->con_ids; *con_id; con_id++) 312 pm_clk_add(dev, *con_id); 313 } else { 314 pm_clk_add(dev, NULL); 315 } 316 317 break; 318 case BUS_NOTIFY_DEL_DEVICE: 319 if (dev->pm_domain != clknb->pm_domain) 320 break; 321 322 dev->pm_domain = NULL; 323 pm_clk_destroy(dev); 324 break; 325 } 326 327 return 0; 328 } 329 330 #else /* !CONFIG_PM_RUNTIME */ 331 332 #ifdef CONFIG_PM 333 334 /** 335 * pm_clk_suspend - Disable clocks in a device's PM clock list. 336 * @dev: Device to disable the clocks for. 337 */ 338 int pm_clk_suspend(struct device *dev) 339 { 340 struct pm_subsys_data *psd = dev_to_psd(dev); 341 struct pm_clock_entry *ce; 342 unsigned long flags; 343 344 dev_dbg(dev, "%s()\n", __func__); 345 346 /* If there is no driver, the clocks are already disabled. */ 347 if (!psd || !dev->driver) 348 return 0; 349 350 spin_lock_irqsave(&psd->lock, flags); 351 352 list_for_each_entry_reverse(ce, &psd->clock_list, node) 353 clk_disable(ce->clk); 354 355 spin_unlock_irqrestore(&psd->lock, flags); 356 357 return 0; 358 } 359 360 /** 361 * pm_clk_resume - Enable clocks in a device's PM clock list. 362 * @dev: Device to enable the clocks for. 363 */ 364 int pm_clk_resume(struct device *dev) 365 { 366 struct pm_subsys_data *psd = dev_to_psd(dev); 367 struct pm_clock_entry *ce; 368 unsigned long flags; 369 370 dev_dbg(dev, "%s()\n", __func__); 371 372 /* If there is no driver, the clocks should remain disabled. */ 373 if (!psd || !dev->driver) 374 return 0; 375 376 spin_lock_irqsave(&psd->lock, flags); 377 378 list_for_each_entry(ce, &psd->clock_list, node) 379 clk_enable(ce->clk); 380 381 spin_unlock_irqrestore(&psd->lock, flags); 382 383 return 0; 384 } 385 386 #endif /* CONFIG_PM */ 387 388 /** 389 * enable_clock - Enable a device clock. 390 * @dev: Device whose clock is to be enabled. 391 * @con_id: Connection ID of the clock. 392 */ 393 static void enable_clock(struct device *dev, const char *con_id) 394 { 395 struct clk *clk; 396 397 clk = clk_get(dev, con_id); 398 if (!IS_ERR(clk)) { 399 clk_enable(clk); 400 clk_put(clk); 401 dev_info(dev, "Runtime PM disabled, clock forced on.\n"); 402 } 403 } 404 405 /** 406 * disable_clock - Disable a device clock. 407 * @dev: Device whose clock is to be disabled. 408 * @con_id: Connection ID of the clock. 409 */ 410 static void disable_clock(struct device *dev, const char *con_id) 411 { 412 struct clk *clk; 413 414 clk = clk_get(dev, con_id); 415 if (!IS_ERR(clk)) { 416 clk_disable(clk); 417 clk_put(clk); 418 dev_info(dev, "Runtime PM disabled, clock forced off.\n"); 419 } 420 } 421 422 /** 423 * pm_clk_notify - Notify routine for device addition and removal. 424 * @nb: Notifier block object this function is a member of. 425 * @action: Operation being carried out by the caller. 426 * @data: Device the routine is being run for. 427 * 428 * For this function to work, @nb must be a member of an object of type 429 * struct pm_clk_notifier_block containing all of the requisite data. 430 * Specifically, the con_ids member of that object is used to enable or disable 431 * the device's clocks, depending on @action. 432 */ 433 static int pm_clk_notify(struct notifier_block *nb, 434 unsigned long action, void *data) 435 { 436 struct pm_clk_notifier_block *clknb; 437 struct device *dev = data; 438 char **con_id; 439 440 dev_dbg(dev, "%s() %ld\n", __func__, action); 441 442 clknb = container_of(nb, struct pm_clk_notifier_block, nb); 443 444 switch (action) { 445 case BUS_NOTIFY_BIND_DRIVER: 446 if (clknb->con_ids[0]) { 447 for (con_id = clknb->con_ids; *con_id; con_id++) 448 enable_clock(dev, *con_id); 449 } else { 450 enable_clock(dev, NULL); 451 } 452 break; 453 case BUS_NOTIFY_UNBOUND_DRIVER: 454 if (clknb->con_ids[0]) { 455 for (con_id = clknb->con_ids; *con_id; con_id++) 456 disable_clock(dev, *con_id); 457 } else { 458 disable_clock(dev, NULL); 459 } 460 break; 461 } 462 463 return 0; 464 } 465 466 #endif /* !CONFIG_PM_RUNTIME */ 467 468 /** 469 * pm_clk_add_notifier - Add bus type notifier for power management clocks. 470 * @bus: Bus type to add the notifier to. 471 * @clknb: Notifier to be added to the given bus type. 472 * 473 * The nb member of @clknb is not expected to be initialized and its 474 * notifier_call member will be replaced with pm_clk_notify(). However, 475 * the remaining members of @clknb should be populated prior to calling this 476 * routine. 477 */ 478 void pm_clk_add_notifier(struct bus_type *bus, 479 struct pm_clk_notifier_block *clknb) 480 { 481 if (!bus || !clknb) 482 return; 483 484 clknb->nb.notifier_call = pm_clk_notify; 485 bus_register_notifier(bus, &clknb->nb); 486 } 487