diff options
Diffstat (limited to 'drivers/base')
| -rw-r--r-- | drivers/base/bus.c | 22 | ||||
| -rw-r--r-- | drivers/base/cpu.c | 2 | ||||
| -rw-r--r-- | drivers/base/firmware_class.c | 6 | ||||
| -rw-r--r-- | drivers/base/map.c | 21 | ||||
| -rw-r--r-- | drivers/base/platform.c | 6 | ||||
| -rw-r--r-- | drivers/base/power/suspend.c | 5 |
6 files changed, 45 insertions, 17 deletions
diff --git a/drivers/base/bus.c b/drivers/base/bus.c index c3141565d59d..48718b7f4fa0 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c | |||
| @@ -536,6 +536,28 @@ void bus_rescan_devices(struct bus_type * bus) | |||
| 536 | bus_for_each_dev(bus, NULL, NULL, bus_rescan_devices_helper); | 536 | bus_for_each_dev(bus, NULL, NULL, bus_rescan_devices_helper); |
| 537 | } | 537 | } |
| 538 | 538 | ||
| 539 | /** | ||
| 540 | * device_reprobe - remove driver for a device and probe for a new driver | ||
| 541 | * @dev: the device to reprobe | ||
| 542 | * | ||
| 543 | * This function detaches the attached driver (if any) for the given | ||
| 544 | * device and restarts the driver probing process. It is intended | ||
| 545 | * to use if probing criteria changed during a devices lifetime and | ||
| 546 | * driver attachment should change accordingly. | ||
| 547 | */ | ||
| 548 | void device_reprobe(struct device *dev) | ||
| 549 | { | ||
| 550 | if (dev->driver) { | ||
| 551 | if (dev->parent) /* Needed for USB */ | ||
| 552 | down(&dev->parent->sem); | ||
| 553 | device_release_driver(dev); | ||
| 554 | if (dev->parent) | ||
| 555 | up(&dev->parent->sem); | ||
| 556 | } | ||
| 557 | |||
| 558 | bus_rescan_devices_helper(dev, NULL); | ||
| 559 | } | ||
| 560 | EXPORT_SYMBOL_GPL(device_reprobe); | ||
| 539 | 561 | ||
| 540 | struct bus_type * get_bus(struct bus_type * bus) | 562 | struct bus_type * get_bus(struct bus_type * bus) |
| 541 | { | 563 | { |
diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c index 07a7f97e1de9..29f3d7504da1 100644 --- a/drivers/base/cpu.c +++ b/drivers/base/cpu.c | |||
| @@ -141,7 +141,7 @@ int __devinit register_cpu(struct cpu *cpu, int num, struct node *root) | |||
| 141 | return error; | 141 | return error; |
| 142 | } | 142 | } |
| 143 | 143 | ||
| 144 | struct sys_device *get_cpu_sysdev(int cpu) | 144 | struct sys_device *get_cpu_sysdev(unsigned cpu) |
| 145 | { | 145 | { |
| 146 | if (cpu < NR_CPUS) | 146 | if (cpu < NR_CPUS) |
| 147 | return cpu_sys_devices[cpu]; | 147 | return cpu_sys_devices[cpu]; |
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index e97e911ebf7a..472318205236 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c | |||
| @@ -211,18 +211,20 @@ static int | |||
| 211 | fw_realloc_buffer(struct firmware_priv *fw_priv, int min_size) | 211 | fw_realloc_buffer(struct firmware_priv *fw_priv, int min_size) |
| 212 | { | 212 | { |
| 213 | u8 *new_data; | 213 | u8 *new_data; |
| 214 | int new_size = fw_priv->alloc_size; | ||
| 214 | 215 | ||
| 215 | if (min_size <= fw_priv->alloc_size) | 216 | if (min_size <= fw_priv->alloc_size) |
| 216 | return 0; | 217 | return 0; |
| 217 | 218 | ||
| 218 | new_data = vmalloc(fw_priv->alloc_size + PAGE_SIZE); | 219 | new_size = ALIGN(min_size, PAGE_SIZE); |
| 220 | new_data = vmalloc(new_size); | ||
| 219 | if (!new_data) { | 221 | if (!new_data) { |
| 220 | printk(KERN_ERR "%s: unable to alloc buffer\n", __FUNCTION__); | 222 | printk(KERN_ERR "%s: unable to alloc buffer\n", __FUNCTION__); |
| 221 | /* Make sure that we don't keep incomplete data */ | 223 | /* Make sure that we don't keep incomplete data */ |
| 222 | fw_load_abort(fw_priv); | 224 | fw_load_abort(fw_priv); |
| 223 | return -ENOMEM; | 225 | return -ENOMEM; |
| 224 | } | 226 | } |
| 225 | fw_priv->alloc_size += PAGE_SIZE; | 227 | fw_priv->alloc_size = new_size; |
| 226 | if (fw_priv->fw->data) { | 228 | if (fw_priv->fw->data) { |
| 227 | memcpy(new_data, fw_priv->fw->data, fw_priv->fw->size); | 229 | memcpy(new_data, fw_priv->fw->data, fw_priv->fw->size); |
| 228 | vfree(fw_priv->fw->data); | 230 | vfree(fw_priv->fw->data); |
diff --git a/drivers/base/map.c b/drivers/base/map.c index b449dae6f0d3..e87017f36853 100644 --- a/drivers/base/map.c +++ b/drivers/base/map.c | |||
| @@ -11,6 +11,7 @@ | |||
| 11 | 11 | ||
| 12 | #include <linux/module.h> | 12 | #include <linux/module.h> |
| 13 | #include <linux/slab.h> | 13 | #include <linux/slab.h> |
| 14 | #include <linux/mutex.h> | ||
| 14 | #include <linux/kdev_t.h> | 15 | #include <linux/kdev_t.h> |
| 15 | #include <linux/kobject.h> | 16 | #include <linux/kobject.h> |
| 16 | #include <linux/kobj_map.h> | 17 | #include <linux/kobj_map.h> |
| @@ -25,7 +26,7 @@ struct kobj_map { | |||
| 25 | int (*lock)(dev_t, void *); | 26 | int (*lock)(dev_t, void *); |
| 26 | void *data; | 27 | void *data; |
| 27 | } *probes[255]; | 28 | } *probes[255]; |
| 28 | struct semaphore *sem; | 29 | struct mutex *lock; |
| 29 | }; | 30 | }; |
| 30 | 31 | ||
| 31 | int kobj_map(struct kobj_map *domain, dev_t dev, unsigned long range, | 32 | int kobj_map(struct kobj_map *domain, dev_t dev, unsigned long range, |
| @@ -53,7 +54,7 @@ int kobj_map(struct kobj_map *domain, dev_t dev, unsigned long range, | |||
| 53 | p->range = range; | 54 | p->range = range; |
| 54 | p->data = data; | 55 | p->data = data; |
| 55 | } | 56 | } |
| 56 | down(domain->sem); | 57 | mutex_lock(domain->lock); |
| 57 | for (i = 0, p -= n; i < n; i++, p++, index++) { | 58 | for (i = 0, p -= n; i < n; i++, p++, index++) { |
| 58 | struct probe **s = &domain->probes[index % 255]; | 59 | struct probe **s = &domain->probes[index % 255]; |
| 59 | while (*s && (*s)->range < range) | 60 | while (*s && (*s)->range < range) |
| @@ -61,7 +62,7 @@ int kobj_map(struct kobj_map *domain, dev_t dev, unsigned long range, | |||
| 61 | p->next = *s; | 62 | p->next = *s; |
| 62 | *s = p; | 63 | *s = p; |
| 63 | } | 64 | } |
| 64 | up(domain->sem); | 65 | mutex_unlock(domain->lock); |
| 65 | return 0; | 66 | return 0; |
| 66 | } | 67 | } |
| 67 | 68 | ||
| @@ -75,7 +76,7 @@ void kobj_unmap(struct kobj_map *domain, dev_t dev, unsigned long range) | |||
| 75 | if (n > 255) | 76 | if (n > 255) |
| 76 | n = 255; | 77 | n = 255; |
| 77 | 78 | ||
| 78 | down(domain->sem); | 79 | mutex_lock(domain->lock); |
| 79 | for (i = 0; i < n; i++, index++) { | 80 | for (i = 0; i < n; i++, index++) { |
| 80 | struct probe **s; | 81 | struct probe **s; |
| 81 | for (s = &domain->probes[index % 255]; *s; s = &(*s)->next) { | 82 | for (s = &domain->probes[index % 255]; *s; s = &(*s)->next) { |
| @@ -88,7 +89,7 @@ void kobj_unmap(struct kobj_map *domain, dev_t dev, unsigned long range) | |||
| 88 | } | 89 | } |
| 89 | } | 90 | } |
| 90 | } | 91 | } |
| 91 | up(domain->sem); | 92 | mutex_unlock(domain->lock); |
| 92 | kfree(found); | 93 | kfree(found); |
| 93 | } | 94 | } |
| 94 | 95 | ||
| @@ -99,7 +100,7 @@ struct kobject *kobj_lookup(struct kobj_map *domain, dev_t dev, int *index) | |||
| 99 | unsigned long best = ~0UL; | 100 | unsigned long best = ~0UL; |
| 100 | 101 | ||
| 101 | retry: | 102 | retry: |
| 102 | down(domain->sem); | 103 | mutex_lock(domain->lock); |
| 103 | for (p = domain->probes[MAJOR(dev) % 255]; p; p = p->next) { | 104 | for (p = domain->probes[MAJOR(dev) % 255]; p; p = p->next) { |
| 104 | struct kobject *(*probe)(dev_t, int *, void *); | 105 | struct kobject *(*probe)(dev_t, int *, void *); |
| 105 | struct module *owner; | 106 | struct module *owner; |
| @@ -120,7 +121,7 @@ retry: | |||
| 120 | module_put(owner); | 121 | module_put(owner); |
| 121 | continue; | 122 | continue; |
| 122 | } | 123 | } |
| 123 | up(domain->sem); | 124 | mutex_unlock(domain->lock); |
| 124 | kobj = probe(dev, index, data); | 125 | kobj = probe(dev, index, data); |
| 125 | /* Currently ->owner protects _only_ ->probe() itself. */ | 126 | /* Currently ->owner protects _only_ ->probe() itself. */ |
| 126 | module_put(owner); | 127 | module_put(owner); |
| @@ -128,11 +129,11 @@ retry: | |||
| 128 | return kobj; | 129 | return kobj; |
| 129 | goto retry; | 130 | goto retry; |
| 130 | } | 131 | } |
| 131 | up(domain->sem); | 132 | mutex_unlock(domain->lock); |
| 132 | return NULL; | 133 | return NULL; |
| 133 | } | 134 | } |
| 134 | 135 | ||
| 135 | struct kobj_map *kobj_map_init(kobj_probe_t *base_probe, struct semaphore *sem) | 136 | struct kobj_map *kobj_map_init(kobj_probe_t *base_probe, struct mutex *lock) |
| 136 | { | 137 | { |
| 137 | struct kobj_map *p = kmalloc(sizeof(struct kobj_map), GFP_KERNEL); | 138 | struct kobj_map *p = kmalloc(sizeof(struct kobj_map), GFP_KERNEL); |
| 138 | struct probe *base = kzalloc(sizeof(*base), GFP_KERNEL); | 139 | struct probe *base = kzalloc(sizeof(*base), GFP_KERNEL); |
| @@ -149,6 +150,6 @@ struct kobj_map *kobj_map_init(kobj_probe_t *base_probe, struct semaphore *sem) | |||
| 149 | base->get = base_probe; | 150 | base->get = base_probe; |
| 150 | for (i = 0; i < 255; i++) | 151 | for (i = 0; i < 255; i++) |
| 151 | p->probes[i] = base; | 152 | p->probes[i] = base; |
| 152 | p->sem = sem; | 153 | p->lock = lock; |
| 153 | return p; | 154 | return p; |
| 154 | } | 155 | } |
diff --git a/drivers/base/platform.c b/drivers/base/platform.c index 461554a02517..83f5c5984d1a 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c | |||
| @@ -61,7 +61,7 @@ int platform_get_irq(struct platform_device *dev, unsigned int num) | |||
| 61 | { | 61 | { |
| 62 | struct resource *r = platform_get_resource(dev, IORESOURCE_IRQ, num); | 62 | struct resource *r = platform_get_resource(dev, IORESOURCE_IRQ, num); |
| 63 | 63 | ||
| 64 | return r ? r->start : 0; | 64 | return r ? r->start : -ENXIO; |
| 65 | } | 65 | } |
| 66 | EXPORT_SYMBOL_GPL(platform_get_irq); | 66 | EXPORT_SYMBOL_GPL(platform_get_irq); |
| 67 | 67 | ||
| @@ -98,7 +98,7 @@ int platform_get_irq_byname(struct platform_device *dev, char *name) | |||
| 98 | { | 98 | { |
| 99 | struct resource *r = platform_get_resource_byname(dev, IORESOURCE_IRQ, name); | 99 | struct resource *r = platform_get_resource_byname(dev, IORESOURCE_IRQ, name); |
| 100 | 100 | ||
| 101 | return r ? r->start : 0; | 101 | return r ? r->start : -ENXIO; |
| 102 | } | 102 | } |
| 103 | EXPORT_SYMBOL_GPL(platform_get_irq_byname); | 103 | EXPORT_SYMBOL_GPL(platform_get_irq_byname); |
| 104 | 104 | ||
| @@ -326,7 +326,7 @@ EXPORT_SYMBOL_GPL(platform_device_register); | |||
| 326 | * platform_device_unregister - unregister a platform-level device | 326 | * platform_device_unregister - unregister a platform-level device |
| 327 | * @pdev: platform device we're unregistering | 327 | * @pdev: platform device we're unregistering |
| 328 | * | 328 | * |
| 329 | * Unregistration is done in 2 steps. Fisrt we release all resources | 329 | * Unregistration is done in 2 steps. First we release all resources |
| 330 | * and remove it from the subsystem, then we drop reference count by | 330 | * and remove it from the subsystem, then we drop reference count by |
| 331 | * calling platform_device_put(). | 331 | * calling platform_device_put(). |
| 332 | */ | 332 | */ |
diff --git a/drivers/base/power/suspend.c b/drivers/base/power/suspend.c index 8660779fb288..bdb60663f2ef 100644 --- a/drivers/base/power/suspend.c +++ b/drivers/base/power/suspend.c | |||
| @@ -8,6 +8,7 @@ | |||
| 8 | * | 8 | * |
| 9 | */ | 9 | */ |
| 10 | 10 | ||
| 11 | #include <linux/vt_kern.h> | ||
| 11 | #include <linux/device.h> | 12 | #include <linux/device.h> |
| 12 | #include "../base.h" | 13 | #include "../base.h" |
| 13 | #include "power.h" | 14 | #include "power.h" |
| @@ -62,7 +63,6 @@ int suspend_device(struct device * dev, pm_message_t state) | |||
| 62 | return error; | 63 | return error; |
| 63 | } | 64 | } |
| 64 | 65 | ||
| 65 | |||
| 66 | /** | 66 | /** |
| 67 | * device_suspend - Save state and stop all devices in system. | 67 | * device_suspend - Save state and stop all devices in system. |
| 68 | * @state: Power state to put each device in. | 68 | * @state: Power state to put each device in. |
| @@ -82,6 +82,9 @@ int device_suspend(pm_message_t state) | |||
| 82 | { | 82 | { |
| 83 | int error = 0; | 83 | int error = 0; |
| 84 | 84 | ||
| 85 | if (!is_console_suspend_safe()) | ||
| 86 | return -EINVAL; | ||
| 87 | |||
| 85 | down(&dpm_sem); | 88 | down(&dpm_sem); |
| 86 | down(&dpm_list_sem); | 89 | down(&dpm_list_sem); |
| 87 | while (!list_empty(&dpm_active) && error == 0) { | 90 | while (!list_empty(&dpm_active) && error == 0) { |
