diff options
| -rw-r--r-- | arch/sh/drivers/pci/pcie-sh7786.c | 2 | ||||
| -rw-r--r-- | include/linux/async.h | 13 | ||||
| -rw-r--r-- | kernel/async.c | 40 |
3 files changed, 24 insertions, 31 deletions
diff --git a/arch/sh/drivers/pci/pcie-sh7786.c b/arch/sh/drivers/pci/pcie-sh7786.c index c2c85f6cd738..a162a7f86b2e 100644 --- a/arch/sh/drivers/pci/pcie-sh7786.c +++ b/arch/sh/drivers/pci/pcie-sh7786.c | |||
| @@ -35,7 +35,7 @@ static unsigned int nr_ports; | |||
| 35 | 35 | ||
| 36 | static struct sh7786_pcie_hwops { | 36 | static struct sh7786_pcie_hwops { |
| 37 | int (*core_init)(void); | 37 | int (*core_init)(void); |
| 38 | async_func_ptr *port_init_hw; | 38 | async_func_t port_init_hw; |
| 39 | } *sh7786_pcie_hwops; | 39 | } *sh7786_pcie_hwops; |
| 40 | 40 | ||
| 41 | static struct resource sh7786_pci0_resources[] = { | 41 | static struct resource sh7786_pci0_resources[] = { |
diff --git a/include/linux/async.h b/include/linux/async.h index a2e3f18b2ad6..6b0226bdaadc 100644 --- a/include/linux/async.h +++ b/include/linux/async.h | |||
| @@ -16,9 +16,8 @@ | |||
| 16 | #include <linux/list.h> | 16 | #include <linux/list.h> |
| 17 | 17 | ||
| 18 | typedef u64 async_cookie_t; | 18 | typedef u64 async_cookie_t; |
| 19 | typedef void (async_func_ptr) (void *data, async_cookie_t cookie); | 19 | typedef void (*async_func_t) (void *data, async_cookie_t cookie); |
| 20 | struct async_domain { | 20 | struct async_domain { |
| 21 | struct list_head node; | ||
| 22 | struct list_head pending; | 21 | struct list_head pending; |
| 23 | unsigned registered:1; | 22 | unsigned registered:1; |
| 24 | }; | 23 | }; |
| @@ -27,8 +26,7 @@ struct async_domain { | |||
| 27 | * domain participates in global async_synchronize_full | 26 | * domain participates in global async_synchronize_full |
| 28 | */ | 27 | */ |
| 29 | #define ASYNC_DOMAIN(_name) \ | 28 | #define ASYNC_DOMAIN(_name) \ |
| 30 | struct async_domain _name = { .node = LIST_HEAD_INIT(_name.node), \ | 29 | struct async_domain _name = { .pending = LIST_HEAD_INIT(_name.pending), \ |
| 31 | .pending = LIST_HEAD_INIT(_name.pending), \ | ||
| 32 | .registered = 1 } | 30 | .registered = 1 } |
| 33 | 31 | ||
| 34 | /* | 32 | /* |
| @@ -36,12 +34,11 @@ struct async_domain { | |||
| 36 | * complete, this domain does not participate in async_synchronize_full | 34 | * complete, this domain does not participate in async_synchronize_full |
| 37 | */ | 35 | */ |
| 38 | #define ASYNC_DOMAIN_EXCLUSIVE(_name) \ | 36 | #define ASYNC_DOMAIN_EXCLUSIVE(_name) \ |
| 39 | struct async_domain _name = { .node = LIST_HEAD_INIT(_name.node), \ | 37 | struct async_domain _name = { .pending = LIST_HEAD_INIT(_name.pending), \ |
| 40 | .pending = LIST_HEAD_INIT(_name.pending), \ | ||
| 41 | .registered = 0 } | 38 | .registered = 0 } |
| 42 | 39 | ||
| 43 | extern async_cookie_t async_schedule(async_func_ptr *ptr, void *data); | 40 | extern async_cookie_t async_schedule(async_func_t func, void *data); |
| 44 | extern async_cookie_t async_schedule_domain(async_func_ptr *ptr, void *data, | 41 | extern async_cookie_t async_schedule_domain(async_func_t func, void *data, |
| 45 | struct async_domain *domain); | 42 | struct async_domain *domain); |
| 46 | void async_unregister_domain(struct async_domain *domain); | 43 | void async_unregister_domain(struct async_domain *domain); |
| 47 | extern void async_synchronize_full(void); | 44 | extern void async_synchronize_full(void); |
diff --git a/kernel/async.c b/kernel/async.c index 8ddee2c3e5b0..61f023ce0228 100644 --- a/kernel/async.c +++ b/kernel/async.c | |||
| @@ -73,7 +73,7 @@ struct async_entry { | |||
| 73 | struct list_head global_list; | 73 | struct list_head global_list; |
| 74 | struct work_struct work; | 74 | struct work_struct work; |
| 75 | async_cookie_t cookie; | 75 | async_cookie_t cookie; |
| 76 | async_func_ptr *func; | 76 | async_func_t func; |
| 77 | void *data; | 77 | void *data; |
| 78 | struct async_domain *domain; | 78 | struct async_domain *domain; |
| 79 | }; | 79 | }; |
| @@ -84,24 +84,20 @@ static atomic_t entry_count; | |||
| 84 | 84 | ||
| 85 | static async_cookie_t lowest_in_progress(struct async_domain *domain) | 85 | static async_cookie_t lowest_in_progress(struct async_domain *domain) |
| 86 | { | 86 | { |
| 87 | struct async_entry *first = NULL; | 87 | struct list_head *pending; |
| 88 | async_cookie_t ret = ASYNC_COOKIE_MAX; | 88 | async_cookie_t ret = ASYNC_COOKIE_MAX; |
| 89 | unsigned long flags; | 89 | unsigned long flags; |
| 90 | 90 | ||
| 91 | spin_lock_irqsave(&async_lock, flags); | 91 | spin_lock_irqsave(&async_lock, flags); |
| 92 | 92 | ||
| 93 | if (domain) { | 93 | if (domain) |
| 94 | if (!list_empty(&domain->pending)) | 94 | pending = &domain->pending; |
| 95 | first = list_first_entry(&domain->pending, | 95 | else |
| 96 | struct async_entry, domain_list); | 96 | pending = &async_global_pending; |
| 97 | } else { | ||
| 98 | if (!list_empty(&async_global_pending)) | ||
| 99 | first = list_first_entry(&async_global_pending, | ||
| 100 | struct async_entry, global_list); | ||
| 101 | } | ||
| 102 | 97 | ||
| 103 | if (first) | 98 | if (!list_empty(pending)) |
| 104 | ret = first->cookie; | 99 | ret = list_first_entry(pending, struct async_entry, |
| 100 | domain_list)->cookie; | ||
| 105 | 101 | ||
| 106 | spin_unlock_irqrestore(&async_lock, flags); | 102 | spin_unlock_irqrestore(&async_lock, flags); |
| 107 | return ret; | 103 | return ret; |
| @@ -149,7 +145,7 @@ static void async_run_entry_fn(struct work_struct *work) | |||
| 149 | wake_up(&async_done); | 145 | wake_up(&async_done); |
| 150 | } | 146 | } |
| 151 | 147 | ||
| 152 | static async_cookie_t __async_schedule(async_func_ptr *ptr, void *data, struct async_domain *domain) | 148 | static async_cookie_t __async_schedule(async_func_t func, void *data, struct async_domain *domain) |
| 153 | { | 149 | { |
| 154 | struct async_entry *entry; | 150 | struct async_entry *entry; |
| 155 | unsigned long flags; | 151 | unsigned long flags; |
| @@ -169,13 +165,13 @@ static async_cookie_t __async_schedule(async_func_ptr *ptr, void *data, struct a | |||
| 169 | spin_unlock_irqrestore(&async_lock, flags); | 165 | spin_unlock_irqrestore(&async_lock, flags); |
| 170 | 166 | ||
| 171 | /* low on memory.. run synchronously */ | 167 | /* low on memory.. run synchronously */ |
| 172 | ptr(data, newcookie); | 168 | func(data, newcookie); |
| 173 | return newcookie; | 169 | return newcookie; |
| 174 | } | 170 | } |
| 175 | INIT_LIST_HEAD(&entry->domain_list); | 171 | INIT_LIST_HEAD(&entry->domain_list); |
| 176 | INIT_LIST_HEAD(&entry->global_list); | 172 | INIT_LIST_HEAD(&entry->global_list); |
| 177 | INIT_WORK(&entry->work, async_run_entry_fn); | 173 | INIT_WORK(&entry->work, async_run_entry_fn); |
| 178 | entry->func = ptr; | 174 | entry->func = func; |
| 179 | entry->data = data; | 175 | entry->data = data; |
| 180 | entry->domain = domain; | 176 | entry->domain = domain; |
| 181 | 177 | ||
| @@ -202,21 +198,21 @@ static async_cookie_t __async_schedule(async_func_ptr *ptr, void *data, struct a | |||
| 202 | 198 | ||
| 203 | /** | 199 | /** |
| 204 | * async_schedule - schedule a function for asynchronous execution | 200 | * async_schedule - schedule a function for asynchronous execution |
| 205 | * @ptr: function to execute asynchronously | 201 | * @func: function to execute asynchronously |
| 206 | * @data: data pointer to pass to the function | 202 | * @data: data pointer to pass to the function |
| 207 | * | 203 | * |
| 208 | * Returns an async_cookie_t that may be used for checkpointing later. | 204 | * Returns an async_cookie_t that may be used for checkpointing later. |
| 209 | * Note: This function may be called from atomic or non-atomic contexts. | 205 | * Note: This function may be called from atomic or non-atomic contexts. |
| 210 | */ | 206 | */ |
| 211 | async_cookie_t async_schedule(async_func_ptr *ptr, void *data) | 207 | async_cookie_t async_schedule(async_func_t func, void *data) |
| 212 | { | 208 | { |
| 213 | return __async_schedule(ptr, data, &async_dfl_domain); | 209 | return __async_schedule(func, data, &async_dfl_domain); |
| 214 | } | 210 | } |
| 215 | EXPORT_SYMBOL_GPL(async_schedule); | 211 | EXPORT_SYMBOL_GPL(async_schedule); |
| 216 | 212 | ||
| 217 | /** | 213 | /** |
| 218 | * async_schedule_domain - schedule a function for asynchronous execution within a certain domain | 214 | * async_schedule_domain - schedule a function for asynchronous execution within a certain domain |
| 219 | * @ptr: function to execute asynchronously | 215 | * @func: function to execute asynchronously |
| 220 | * @data: data pointer to pass to the function | 216 | * @data: data pointer to pass to the function |
| 221 | * @domain: the domain | 217 | * @domain: the domain |
| 222 | * | 218 | * |
| @@ -226,10 +222,10 @@ EXPORT_SYMBOL_GPL(async_schedule); | |||
| 226 | * synchronization domain is specified via @domain. Note: This function | 222 | * synchronization domain is specified via @domain. Note: This function |
| 227 | * may be called from atomic or non-atomic contexts. | 223 | * may be called from atomic or non-atomic contexts. |
| 228 | */ | 224 | */ |
| 229 | async_cookie_t async_schedule_domain(async_func_ptr *ptr, void *data, | 225 | async_cookie_t async_schedule_domain(async_func_t func, void *data, |
| 230 | struct async_domain *domain) | 226 | struct async_domain *domain) |
| 231 | { | 227 | { |
| 232 | return __async_schedule(ptr, data, domain); | 228 | return __async_schedule(func, data, domain); |
| 233 | } | 229 | } |
| 234 | EXPORT_SYMBOL_GPL(async_schedule_domain); | 230 | EXPORT_SYMBOL_GPL(async_schedule_domain); |
| 235 | 231 | ||
