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