| /* |
| * Copyright (c) 2014 Hauke Mehrtens <hauke@hauke-m.de> |
| * |
| * Backport functionality introduced in Linux 3.17. |
| * |
| * This program is free software; you can redistribute it and/or modify |
| * it under the terms of the GNU General Public License version 2 as |
| * published by the Free Software Foundation. |
| */ |
| #include <linux/wait.h> |
| #include <linux/sched.h> |
| #include <linux/device.h> |
| #include <linux/export.h> |
| #include <linux/ktime.h> |
| #include <linux/jiffies.h> |
| #include <linux/moduleparam.h> |
| |
| int bit_wait(void *word) |
| { |
| schedule(); |
| return 0; |
| } |
| EXPORT_SYMBOL_GPL(bit_wait); |
| |
| int bit_wait_io(void *word) |
| { |
| io_schedule(); |
| return 0; |
| } |
| EXPORT_SYMBOL_GPL(bit_wait_io); |
| |
| /** |
| * ktime_get_raw - Returns the raw monotonic time in ktime_t format |
| */ |
| ktime_t ktime_get_raw(void) |
| { |
| struct timespec ts; |
| |
| getrawmonotonic(&ts); |
| return timespec_to_ktime(ts); |
| } |
| EXPORT_SYMBOL_GPL(ktime_get_raw); |
| |
| |
| /** |
| * nsecs_to_jiffies64 - Convert nsecs in u64 to jiffies64 |
| * |
| * @n: nsecs in u64 |
| * |
| * Unlike {m,u}secs_to_jiffies, type of input is not unsigned int but u64. |
| * And this doesn't return MAX_JIFFY_OFFSET since this function is designed |
| * for scheduler, not for use in device drivers to calculate timeout value. |
| * |
| * note: |
| * NSEC_PER_SEC = 10^9 = (5^9 * 2^9) = (1953125 * 512) |
| * ULLONG_MAX ns = 18446744073.709551615 secs = about 584 years |
| */ |
| static u64 backport_nsecs_to_jiffies64(u64 n) |
| { |
| #if (NSEC_PER_SEC % HZ) == 0 |
| /* Common case, HZ = 100, 128, 200, 250, 256, 500, 512, 1000 etc. */ |
| return div_u64(n, NSEC_PER_SEC / HZ); |
| #elif (HZ % 512) == 0 |
| /* overflow after 292 years if HZ = 1024 */ |
| return div_u64(n * HZ / 512, NSEC_PER_SEC / 512); |
| #else |
| /* |
| * Generic case - optimized for cases where HZ is a multiple of 3. |
| * overflow after 64.99 years, exact for HZ = 60, 72, 90, 120 etc. |
| */ |
| return div_u64(n * 9, (9ull * NSEC_PER_SEC + HZ / 2) / HZ); |
| #endif |
| } |
| |
| /** |
| * nsecs_to_jiffies - Convert nsecs in u64 to jiffies |
| * |
| * @n: nsecs in u64 |
| * |
| * Unlike {m,u}secs_to_jiffies, type of input is not unsigned int but u64. |
| * And this doesn't return MAX_JIFFY_OFFSET since this function is designed |
| * for scheduler, not for use in device drivers to calculate timeout value. |
| * |
| * note: |
| * NSEC_PER_SEC = 10^9 = (5^9 * 2^9) = (1953125 * 512) |
| * ULLONG_MAX ns = 18446744073.709551615 secs = about 584 years |
| */ |
| unsigned long nsecs_to_jiffies(u64 n) |
| { |
| return (unsigned long)backport_nsecs_to_jiffies64(n); |
| } |
| EXPORT_SYMBOL_GPL(nsecs_to_jiffies); |
| |
| /** |
| * devm_kvasprintf - Allocate resource managed space |
| * for the formatted string. |
| * @dev: Device to allocate memory for |
| * @gfp: the GFP mask used in the devm_kmalloc() call when |
| * allocating memory |
| * @fmt: the formatted string to duplicate |
| * @ap: the list of tokens to be placed in the formatted string |
| * RETURNS: |
| * Pointer to allocated string on success, NULL on failure. |
| */ |
| char *devm_kvasprintf(struct device *dev, gfp_t gfp, const char *fmt, |
| va_list ap) |
| { |
| unsigned int len; |
| char *p; |
| va_list aq; |
| |
| va_copy(aq, ap); |
| len = vsnprintf(NULL, 0, fmt, aq); |
| va_end(aq); |
| |
| p = devm_kmalloc(dev, len+1, gfp); |
| if (!p) |
| return NULL; |
| |
| vsnprintf(p, len+1, fmt, ap); |
| |
| return p; |
| } |
| EXPORT_SYMBOL_GPL(devm_kvasprintf); |
| |
| /** |
| * devm_kasprintf - Allocate resource managed space |
| * and copy an existing formatted string into that |
| * @dev: Device to allocate memory for |
| * @gfp: the GFP mask used in the devm_kmalloc() call when |
| * allocating memory |
| * @fmt: the string to duplicate |
| * RETURNS: |
| * Pointer to allocated string on success, NULL on failure. |
| */ |
| char *devm_kasprintf(struct device *dev, gfp_t gfp, const char *fmt, ...) |
| { |
| va_list ap; |
| char *p; |
| |
| va_start(ap, fmt); |
| p = devm_kvasprintf(dev, gfp, fmt, ap); |
| va_end(ap); |
| |
| return p; |
| } |
| EXPORT_SYMBOL_GPL(devm_kasprintf); |
| |
| #define STANDARD_PARAM_DEF(name, type, format, strtolfn) \ |
| int param_set_##name(const char *val, const struct kernel_param *kp) \ |
| { \ |
| return strtolfn(val, 0, (type *)kp->arg); \ |
| } \ |
| int param_get_##name(char *buffer, const struct kernel_param *kp) \ |
| { \ |
| return scnprintf(buffer, PAGE_SIZE, format, \ |
| *((type *)kp->arg)); \ |
| } \ |
| struct kernel_param_ops param_ops_##name = { \ |
| .set = param_set_##name, \ |
| .get = param_get_##name, \ |
| }; \ |
| EXPORT_SYMBOL(param_set_##name); \ |
| EXPORT_SYMBOL(param_get_##name); \ |
| EXPORT_SYMBOL(param_ops_##name) |
| STANDARD_PARAM_DEF(ullong, unsigned long long, "%llu", kstrtoull); |