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_RUNTIME 19 20 struct pm_runtime_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_runtime_clk_data *__to_prd(struct device *dev) 40 { 41 return dev ? dev->power.subsys_data : NULL; 42 } 43 44 /** 45 * pm_runtime_clk_add - Start using a device clock for runtime PM. 46 * @dev: Device whose clock is going to be used for runtime PM. 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 runtime PM of @dev. 51 */ 52 int pm_runtime_clk_add(struct device *dev, const char *con_id) 53 { 54 struct pm_runtime_clk_data *prd = __to_prd(dev); 55 struct pm_clock_entry *ce; 56 57 if (!prd) 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(&prd->lock); 77 list_add_tail(&ce->node, &prd->clock_list); 78 mutex_unlock(&prd->lock); 79 return 0; 80 } 81 82 /** 83 * __pm_runtime_clk_remove - Destroy runtime PM clock entry. 84 * @ce: Runtime PM clock entry to destroy. 85 * 86 * This routine must be called under the mutex protecting the runtime PM list 87 * of clocks corresponding the the @ce's device. 88 */ 89 static void __pm_runtime_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_runtime_clk_remove - Stop using a device clock for runtime PM. 112 * @dev: Device whose clock should not be used for runtime 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 runtime PM of @dev. 117 */ 118 void pm_runtime_clk_remove(struct device *dev, const char *con_id) 119 { 120 struct pm_runtime_clk_data *prd = __to_prd(dev); 121 struct pm_clock_entry *ce; 122 123 if (!prd) 124 return; 125 126 mutex_lock(&prd->lock); 127 128 list_for_each_entry(ce, &prd->clock_list, node) { 129 if (!con_id && !ce->con_id) { 130 __pm_runtime_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_runtime_clk_remove(ce); 136 break; 137 } 138 } 139 140 mutex_unlock(&prd->lock); 141 } 142 143 /** 144 * pm_runtime_clk_init - Initialize a device's list of runtime PM clocks. 145 * @dev: Device to initialize the list of runtime PM clocks for. 146 * 147 * Allocate a struct pm_runtime_clk_data object, initialize its lock member and 148 * make the @dev's power.subsys_data field point to it. 149 */ 150 int pm_runtime_clk_init(struct device *dev) 151 { 152 struct pm_runtime_clk_data *prd; 153 154 prd = kzalloc(sizeof(*prd), GFP_KERNEL); 155 if (!prd) { 156 dev_err(dev, "Not enough memory fo runtime PM data.\n"); 157 return -ENOMEM; 158 } 159 160 INIT_LIST_HEAD(&prd->clock_list); 161 mutex_init(&prd->lock); 162 dev->power.subsys_data = prd; 163 return 0; 164 } 165 166 /** 167 * pm_runtime_clk_destroy - Destroy a device's list of runtime PM clocks. 168 * @dev: Device to destroy the list of runtime PM clocks for. 169 * 170 * Clear the @dev's power.subsys_data field, remove the list of clock entries 171 * from the struct pm_runtime_clk_data object pointed to by it before and free 172 * that object. 173 */ 174 void pm_runtime_clk_destroy(struct device *dev) 175 { 176 struct pm_runtime_clk_data *prd = __to_prd(dev); 177 struct pm_clock_entry *ce, *c; 178 179 if (!prd) 180 return; 181 182 dev->power.subsys_data = NULL; 183 184 mutex_lock(&prd->lock); 185 186 list_for_each_entry_safe_reverse(ce, c, &prd->clock_list, node) 187 __pm_runtime_clk_remove(ce); 188 189 mutex_unlock(&prd->lock); 190 191 kfree(prd); 192 } 193 194 /** 195 * pm_runtime_clk_acquire - Acquire a device clock. 196 * @dev: Device whose clock is to be acquired. 197 * @con_id: Connection ID of the clock. 198 */ 199 static void pm_runtime_clk_acquire(struct device *dev, 200 struct pm_clock_entry *ce) 201 { 202 ce->clk = clk_get(dev, ce->con_id); 203 if (IS_ERR(ce->clk)) { 204 ce->status = PCE_STATUS_ERROR; 205 } else { 206 ce->status = PCE_STATUS_ACQUIRED; 207 dev_dbg(dev, "Clock %s managed by runtime PM.\n", ce->con_id); 208 } 209 } 210 211 /** 212 * pm_runtime_clk_suspend - Disable clocks in a device's runtime PM clock list. 213 * @dev: Device to disable the clocks for. 214 */ 215 int pm_runtime_clk_suspend(struct device *dev) 216 { 217 struct pm_runtime_clk_data *prd = __to_prd(dev); 218 struct pm_clock_entry *ce; 219 220 dev_dbg(dev, "%s()\n", __func__); 221 222 if (!prd) 223 return 0; 224 225 mutex_lock(&prd->lock); 226 227 list_for_each_entry_reverse(ce, &prd->clock_list, node) { 228 if (ce->status == PCE_STATUS_NONE) 229 pm_runtime_clk_acquire(dev, ce); 230 231 if (ce->status < PCE_STATUS_ERROR) { 232 clk_disable(ce->clk); 233 ce->status = PCE_STATUS_ACQUIRED; 234 } 235 } 236 237 mutex_unlock(&prd->lock); 238 239 return 0; 240 } 241 242 /** 243 * pm_runtime_clk_resume - Enable clocks in a device's runtime PM clock list. 244 * @dev: Device to enable the clocks for. 245 */ 246 int pm_runtime_clk_resume(struct device *dev) 247 { 248 struct pm_runtime_clk_data *prd = __to_prd(dev); 249 struct pm_clock_entry *ce; 250 251 dev_dbg(dev, "%s()\n", __func__); 252 253 if (!prd) 254 return 0; 255 256 mutex_lock(&prd->lock); 257 258 list_for_each_entry(ce, &prd->clock_list, node) { 259 if (ce->status == PCE_STATUS_NONE) 260 pm_runtime_clk_acquire(dev, ce); 261 262 if (ce->status < PCE_STATUS_ERROR) { 263 clk_enable(ce->clk); 264 ce->status = PCE_STATUS_ENABLED; 265 } 266 } 267 268 mutex_unlock(&prd->lock); 269 270 return 0; 271 } 272 273 /** 274 * pm_runtime_clk_notify - Notify routine for device addition and removal. 275 * @nb: Notifier block object this function is a member of. 276 * @action: Operation being carried out by the caller. 277 * @data: Device the routine is being run for. 278 * 279 * For this function to work, @nb must be a member of an object of type 280 * struct pm_clk_notifier_block containing all of the requisite data. 281 * Specifically, the pwr_domain member of that object is copied to the device's 282 * pwr_domain field and its con_ids member is used to populate the device's list 283 * of runtime PM clocks, depending on @action. 284 * 285 * If the device's pwr_domain field is already populated with a value different 286 * from the one stored in the struct pm_clk_notifier_block object, the function 287 * does nothing. 288 */ 289 static int pm_runtime_clk_notify(struct notifier_block *nb, 290 unsigned long action, void *data) 291 { 292 struct pm_clk_notifier_block *clknb; 293 struct device *dev = data; 294 char *con_id; 295 int error; 296 297 dev_dbg(dev, "%s() %ld\n", __func__, action); 298 299 clknb = container_of(nb, struct pm_clk_notifier_block, nb); 300 301 switch (action) { 302 case BUS_NOTIFY_ADD_DEVICE: 303 if (dev->pwr_domain) 304 break; 305 306 error = pm_runtime_clk_init(dev); 307 if (error) 308 break; 309 310 dev->pwr_domain = clknb->pwr_domain; 311 if (clknb->con_ids[0]) { 312 for (con_id = clknb->con_ids[0]; *con_id; con_id++) 313 pm_runtime_clk_add(dev, con_id); 314 } else { 315 pm_runtime_clk_add(dev, NULL); 316 } 317 318 break; 319 case BUS_NOTIFY_DEL_DEVICE: 320 if (dev->pwr_domain != clknb->pwr_domain) 321 break; 322 323 dev->pwr_domain = NULL; 324 pm_runtime_clk_destroy(dev); 325 break; 326 } 327 328 return 0; 329 } 330 331 #else /* !CONFIG_PM_RUNTIME */ 332 333 /** 334 * enable_clock - Enable a device clock. 335 * @dev: Device whose clock is to be enabled. 336 * @con_id: Connection ID of the clock. 337 */ 338 static void enable_clock(struct device *dev, const char *con_id) 339 { 340 struct clk *clk; 341 342 clk = clk_get(dev, con_id); 343 if (!IS_ERR(clk)) { 344 clk_enable(clk); 345 clk_put(clk); 346 dev_info(dev, "Runtime PM disabled, clock forced on.\n"); 347 } 348 } 349 350 /** 351 * disable_clock - Disable a device clock. 352 * @dev: Device whose clock is to be disabled. 353 * @con_id: Connection ID of the clock. 354 */ 355 static void disable_clock(struct device *dev, const char *con_id) 356 { 357 struct clk *clk; 358 359 clk = clk_get(dev, con_id); 360 if (!IS_ERR(clk)) { 361 clk_disable(clk); 362 clk_put(clk); 363 dev_info(dev, "Runtime PM disabled, clock forced off.\n"); 364 } 365 } 366 367 /** 368 * pm_runtime_clk_notify - Notify routine for device addition and removal. 369 * @nb: Notifier block object this function is a member of. 370 * @action: Operation being carried out by the caller. 371 * @data: Device the routine is being run for. 372 * 373 * For this function to work, @nb must be a member of an object of type 374 * struct pm_clk_notifier_block containing all of the requisite data. 375 * Specifically, the con_ids member of that object is used to enable or disable 376 * the device's clocks, depending on @action. 377 */ 378 static int pm_runtime_clk_notify(struct notifier_block *nb, 379 unsigned long action, void *data) 380 { 381 struct pm_clk_notifier_block *clknb; 382 struct device *dev = data; 383 384 dev_dbg(dev, "%s() %ld\n", __func__, action); 385 386 clknb = container_of(nb, struct pm_clk_notifier_block, nb); 387 388 switch (action) { 389 case BUS_NOTIFY_ADD_DEVICE: 390 if (clknb->con_ids[0]) { 391 for (con_id = clknb->con_ids[0]; *con_id; con_id++) 392 enable_clock(dev, con_id); 393 } else { 394 enable_clock(dev, NULL); 395 } 396 break; 397 case BUS_NOTIFY_DEL_DEVICE: 398 if (clknb->con_ids[0]) { 399 for (con_id = clknb->con_ids[0]; *con_id; con_id++) 400 disable_clock(dev, con_id); 401 } else { 402 disable_clock(dev, NULL); 403 } 404 break; 405 } 406 407 return 0; 408 } 409 410 #endif /* !CONFIG_PM_RUNTIME */ 411 412 /** 413 * pm_runtime_clk_add_notifier - Add bus type notifier for runtime PM clocks. 414 * @bus: Bus type to add the notifier to. 415 * @clknb: Notifier to be added to the given bus type. 416 * 417 * The nb member of @clknb is not expected to be initialized and its 418 * notifier_call member will be replaced with pm_runtime_clk_notify(). However, 419 * the remaining members of @clknb should be populated prior to calling this 420 * routine. 421 */ 422 void pm_runtime_clk_add_notifier(struct bus_type *bus, 423 struct pm_clk_notifier_block *clknb) 424 { 425 if (!bus || !clknb) 426 return; 427 428 clknb->nb.notifier_call = pm_runtime_clk_notify; 429 bus_register_notifier(bus, &clknb->nb); 430 } 431