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