diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-03-26 14:15:54 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-03-26 14:15:54 -0400 |
| commit | 0dc82fa59b9d82469799c354d3307d48e13d5d5e (patch) | |
| tree | 7cfb62fecd04557a9e44a69a6db65138ea8ccf74 | |
| parent | 9e54ef9da519d9febfa61fa9392276fbfa6ce79c (diff) | |
| parent | 5c1724c42dc1d60addaa67106a4f25c2a9a140de (diff) | |
Merge tag 'char-misc-4.11-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc
Pull char/misc driver fixes from Greg KH:
"A smattering of different small fixes for some random driver
subsystems. Nothing all that major, just resolutions for reported
issues and bugs.
All have been in linux-next with no reported issues"
* tag 'char-misc-4.11-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: (21 commits)
extcon: int3496: Set the id pin to direction-input if necessary
extcon: int3496: Use gpiod_get instead of gpiod_get_index
extcon: int3496: Add dependency on X86 as it's Intel specific
extcon: int3496: Add GPIO ACPI mapping table
extcon: int3496: Rename GPIO pins in accordance with binding
vmw_vmci: handle the return value from pci_alloc_irq_vectors correctly
ppdev: fix registering same device name
parport: fix attempt to write duplicate procfiles
auxdisplay: img-ascii-lcd: add missing sentinel entry in img_ascii_lcd_matches
Drivers: hv: vmbus: Don't leak memory when a channel is rescinded
Drivers: hv: vmbus: Don't leak channel ids
Drivers: hv: util: don't forget to init host_ts.lock
Drivers: hv: util: move waiting for release to hv_utils_transport itself
vmbus: remove hv_event_tasklet_disable/enable
vmbus: use rcu for per-cpu channel list
mei: don't wait for os version message reply
mei: fix deadlock on mei reset
intel_th: pci: Add Gemini Lake support
intel_th: pci: Add Denverton SOC support
intel_th: Don't leak module refcount on failure to activate
...
| -rw-r--r-- | Documentation/extcon/intel-int3496.txt | 5 | ||||
| -rw-r--r-- | drivers/auxdisplay/img-ascii-lcd.c | 1 | ||||
| -rw-r--r-- | drivers/char/ppdev.c | 11 | ||||
| -rw-r--r-- | drivers/extcon/Kconfig | 2 | ||||
| -rw-r--r-- | drivers/extcon/extcon-intel-int3496.c | 39 | ||||
| -rw-r--r-- | drivers/hv/channel.c | 25 | ||||
| -rw-r--r-- | drivers/hv/channel_mgmt.c | 27 | ||||
| -rw-r--r-- | drivers/hv/hv_fcopy.c | 4 | ||||
| -rw-r--r-- | drivers/hv/hv_kvp.c | 4 | ||||
| -rw-r--r-- | drivers/hv/hv_snapshot.c | 4 | ||||
| -rw-r--r-- | drivers/hv/hv_util.c | 2 | ||||
| -rw-r--r-- | drivers/hv/hv_utils_transport.c | 12 | ||||
| -rw-r--r-- | drivers/hv/hv_utils_transport.h | 1 | ||||
| -rw-r--r-- | drivers/hv/vmbus_drv.c | 6 | ||||
| -rw-r--r-- | drivers/hwtracing/intel_th/core.c | 4 | ||||
| -rw-r--r-- | drivers/hwtracing/intel_th/pci.c | 10 | ||||
| -rw-r--r-- | drivers/misc/mei/bus-fixup.c | 14 | ||||
| -rw-r--r-- | drivers/misc/mei/init.c | 8 | ||||
| -rw-r--r-- | drivers/misc/vmw_vmci/vmci_guest.c | 4 | ||||
| -rw-r--r-- | drivers/parport/share.c | 6 | ||||
| -rw-r--r-- | include/linux/hyperv.h | 10 |
21 files changed, 111 insertions, 88 deletions
diff --git a/Documentation/extcon/intel-int3496.txt b/Documentation/extcon/intel-int3496.txt index af0b366c25b7..8155dbc7fad3 100644 --- a/Documentation/extcon/intel-int3496.txt +++ b/Documentation/extcon/intel-int3496.txt | |||
| @@ -20,3 +20,8 @@ Index 1: The output gpio for enabling Vbus output from the device to the otg | |||
| 20 | Index 2: The output gpio for muxing of the data pins between the USB host and | 20 | Index 2: The output gpio for muxing of the data pins between the USB host and |
| 21 | the USB peripheral controller, write 1 to mux to the peripheral | 21 | the USB peripheral controller, write 1 to mux to the peripheral |
| 22 | controller | 22 | controller |
| 23 | |||
| 24 | There is a mapping between indices and GPIO connection IDs as follows | ||
| 25 | id index 0 | ||
| 26 | vbus index 1 | ||
| 27 | mux index 2 | ||
diff --git a/drivers/auxdisplay/img-ascii-lcd.c b/drivers/auxdisplay/img-ascii-lcd.c index bf43b5d2aafc..83f1439e57fd 100644 --- a/drivers/auxdisplay/img-ascii-lcd.c +++ b/drivers/auxdisplay/img-ascii-lcd.c | |||
| @@ -218,6 +218,7 @@ static const struct of_device_id img_ascii_lcd_matches[] = { | |||
| 218 | { .compatible = "img,boston-lcd", .data = &boston_config }, | 218 | { .compatible = "img,boston-lcd", .data = &boston_config }, |
| 219 | { .compatible = "mti,malta-lcd", .data = &malta_config }, | 219 | { .compatible = "mti,malta-lcd", .data = &malta_config }, |
| 220 | { .compatible = "mti,sead3-lcd", .data = &sead3_config }, | 220 | { .compatible = "mti,sead3-lcd", .data = &sead3_config }, |
| 221 | { /* sentinel */ } | ||
| 221 | }; | 222 | }; |
| 222 | 223 | ||
| 223 | /** | 224 | /** |
diff --git a/drivers/char/ppdev.c b/drivers/char/ppdev.c index 2a558c706581..3e73bcdf9e65 100644 --- a/drivers/char/ppdev.c +++ b/drivers/char/ppdev.c | |||
| @@ -84,11 +84,14 @@ struct pp_struct { | |||
| 84 | struct ieee1284_info state; | 84 | struct ieee1284_info state; |
| 85 | struct ieee1284_info saved_state; | 85 | struct ieee1284_info saved_state; |
| 86 | long default_inactivity; | 86 | long default_inactivity; |
| 87 | int index; | ||
| 87 | }; | 88 | }; |
| 88 | 89 | ||
| 89 | /* should we use PARDEVICE_MAX here? */ | 90 | /* should we use PARDEVICE_MAX here? */ |
| 90 | static struct device *devices[PARPORT_MAX]; | 91 | static struct device *devices[PARPORT_MAX]; |
| 91 | 92 | ||
| 93 | static DEFINE_IDA(ida_index); | ||
| 94 | |||
| 92 | /* pp_struct.flags bitfields */ | 95 | /* pp_struct.flags bitfields */ |
| 93 | #define PP_CLAIMED (1<<0) | 96 | #define PP_CLAIMED (1<<0) |
| 94 | #define PP_EXCL (1<<1) | 97 | #define PP_EXCL (1<<1) |
| @@ -290,7 +293,7 @@ static int register_device(int minor, struct pp_struct *pp) | |||
| 290 | struct pardevice *pdev = NULL; | 293 | struct pardevice *pdev = NULL; |
| 291 | char *name; | 294 | char *name; |
| 292 | struct pardev_cb ppdev_cb; | 295 | struct pardev_cb ppdev_cb; |
| 293 | int rc = 0; | 296 | int rc = 0, index; |
| 294 | 297 | ||
| 295 | name = kasprintf(GFP_KERNEL, CHRDEV "%x", minor); | 298 | name = kasprintf(GFP_KERNEL, CHRDEV "%x", minor); |
| 296 | if (name == NULL) | 299 | if (name == NULL) |
| @@ -303,20 +306,23 @@ static int register_device(int minor, struct pp_struct *pp) | |||
| 303 | goto err; | 306 | goto err; |
| 304 | } | 307 | } |
| 305 | 308 | ||
| 309 | index = ida_simple_get(&ida_index, 0, 0, GFP_KERNEL); | ||
| 306 | memset(&ppdev_cb, 0, sizeof(ppdev_cb)); | 310 | memset(&ppdev_cb, 0, sizeof(ppdev_cb)); |
| 307 | ppdev_cb.irq_func = pp_irq; | 311 | ppdev_cb.irq_func = pp_irq; |
| 308 | ppdev_cb.flags = (pp->flags & PP_EXCL) ? PARPORT_FLAG_EXCL : 0; | 312 | ppdev_cb.flags = (pp->flags & PP_EXCL) ? PARPORT_FLAG_EXCL : 0; |
| 309 | ppdev_cb.private = pp; | 313 | ppdev_cb.private = pp; |
| 310 | pdev = parport_register_dev_model(port, name, &ppdev_cb, minor); | 314 | pdev = parport_register_dev_model(port, name, &ppdev_cb, index); |
| 311 | parport_put_port(port); | 315 | parport_put_port(port); |
| 312 | 316 | ||
| 313 | if (!pdev) { | 317 | if (!pdev) { |
| 314 | pr_warn("%s: failed to register device!\n", name); | 318 | pr_warn("%s: failed to register device!\n", name); |
| 315 | rc = -ENXIO; | 319 | rc = -ENXIO; |
| 320 | ida_simple_remove(&ida_index, index); | ||
| 316 | goto err; | 321 | goto err; |
| 317 | } | 322 | } |
| 318 | 323 | ||
| 319 | pp->pdev = pdev; | 324 | pp->pdev = pdev; |
| 325 | pp->index = index; | ||
| 320 | dev_dbg(&pdev->dev, "registered pardevice\n"); | 326 | dev_dbg(&pdev->dev, "registered pardevice\n"); |
| 321 | err: | 327 | err: |
| 322 | kfree(name); | 328 | kfree(name); |
| @@ -755,6 +761,7 @@ static int pp_release(struct inode *inode, struct file *file) | |||
| 755 | 761 | ||
| 756 | if (pp->pdev) { | 762 | if (pp->pdev) { |
| 757 | parport_unregister_device(pp->pdev); | 763 | parport_unregister_device(pp->pdev); |
| 764 | ida_simple_remove(&ida_index, pp->index); | ||
| 758 | pp->pdev = NULL; | 765 | pp->pdev = NULL; |
| 759 | pr_debug(CHRDEV "%x: unregistered pardevice\n", minor); | 766 | pr_debug(CHRDEV "%x: unregistered pardevice\n", minor); |
| 760 | } | 767 | } |
diff --git a/drivers/extcon/Kconfig b/drivers/extcon/Kconfig index 96bbae579c0b..fc09c76248b4 100644 --- a/drivers/extcon/Kconfig +++ b/drivers/extcon/Kconfig | |||
| @@ -44,7 +44,7 @@ config EXTCON_GPIO | |||
| 44 | 44 | ||
| 45 | config EXTCON_INTEL_INT3496 | 45 | config EXTCON_INTEL_INT3496 |
| 46 | tristate "Intel INT3496 ACPI device extcon driver" | 46 | tristate "Intel INT3496 ACPI device extcon driver" |
| 47 | depends on GPIOLIB && ACPI | 47 | depends on GPIOLIB && ACPI && (X86 || COMPILE_TEST) |
| 48 | help | 48 | help |
| 49 | Say Y here to enable extcon support for USB OTG ports controlled by | 49 | Say Y here to enable extcon support for USB OTG ports controlled by |
| 50 | an Intel INT3496 ACPI device. | 50 | an Intel INT3496 ACPI device. |
diff --git a/drivers/extcon/extcon-intel-int3496.c b/drivers/extcon/extcon-intel-int3496.c index a3131b036de6..9d17984bbbd4 100644 --- a/drivers/extcon/extcon-intel-int3496.c +++ b/drivers/extcon/extcon-intel-int3496.c | |||
| @@ -45,6 +45,17 @@ static const unsigned int int3496_cable[] = { | |||
| 45 | EXTCON_NONE, | 45 | EXTCON_NONE, |
| 46 | }; | 46 | }; |
| 47 | 47 | ||
| 48 | static const struct acpi_gpio_params id_gpios = { INT3496_GPIO_USB_ID, 0, false }; | ||
| 49 | static const struct acpi_gpio_params vbus_gpios = { INT3496_GPIO_VBUS_EN, 0, false }; | ||
| 50 | static const struct acpi_gpio_params mux_gpios = { INT3496_GPIO_USB_MUX, 0, false }; | ||
| 51 | |||
| 52 | static const struct acpi_gpio_mapping acpi_int3496_default_gpios[] = { | ||
| 53 | { "id-gpios", &id_gpios, 1 }, | ||
| 54 | { "vbus-gpios", &vbus_gpios, 1 }, | ||
| 55 | { "mux-gpios", &mux_gpios, 1 }, | ||
| 56 | { }, | ||
| 57 | }; | ||
| 58 | |||
| 48 | static void int3496_do_usb_id(struct work_struct *work) | 59 | static void int3496_do_usb_id(struct work_struct *work) |
| 49 | { | 60 | { |
| 50 | struct int3496_data *data = | 61 | struct int3496_data *data = |
| @@ -83,6 +94,13 @@ static int int3496_probe(struct platform_device *pdev) | |||
| 83 | struct int3496_data *data; | 94 | struct int3496_data *data; |
| 84 | int ret; | 95 | int ret; |
| 85 | 96 | ||
| 97 | ret = acpi_dev_add_driver_gpios(ACPI_COMPANION(dev), | ||
| 98 | acpi_int3496_default_gpios); | ||
| 99 | if (ret) { | ||
| 100 | dev_err(dev, "can't add GPIO ACPI mapping\n"); | ||
| 101 | return ret; | ||
| 102 | } | ||
| 103 | |||
| 86 | data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); | 104 | data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); |
| 87 | if (!data) | 105 | if (!data) |
| 88 | return -ENOMEM; | 106 | return -ENOMEM; |
| @@ -90,30 +108,27 @@ static int int3496_probe(struct platform_device *pdev) | |||
| 90 | data->dev = dev; | 108 | data->dev = dev; |
| 91 | INIT_DELAYED_WORK(&data->work, int3496_do_usb_id); | 109 | INIT_DELAYED_WORK(&data->work, int3496_do_usb_id); |
| 92 | 110 | ||
| 93 | data->gpio_usb_id = devm_gpiod_get_index(dev, "id", | 111 | data->gpio_usb_id = devm_gpiod_get(dev, "id", GPIOD_IN); |
| 94 | INT3496_GPIO_USB_ID, | ||
| 95 | GPIOD_IN); | ||
| 96 | if (IS_ERR(data->gpio_usb_id)) { | 112 | if (IS_ERR(data->gpio_usb_id)) { |
| 97 | ret = PTR_ERR(data->gpio_usb_id); | 113 | ret = PTR_ERR(data->gpio_usb_id); |
| 98 | dev_err(dev, "can't request USB ID GPIO: %d\n", ret); | 114 | dev_err(dev, "can't request USB ID GPIO: %d\n", ret); |
| 99 | return ret; | 115 | return ret; |
| 116 | } else if (gpiod_get_direction(data->gpio_usb_id) != GPIOF_DIR_IN) { | ||
| 117 | dev_warn(dev, FW_BUG "USB ID GPIO not in input mode, fixing\n"); | ||
| 118 | gpiod_direction_input(data->gpio_usb_id); | ||
| 100 | } | 119 | } |
| 101 | 120 | ||
| 102 | data->usb_id_irq = gpiod_to_irq(data->gpio_usb_id); | 121 | data->usb_id_irq = gpiod_to_irq(data->gpio_usb_id); |
| 103 | if (data->usb_id_irq <= 0) { | 122 | if (data->usb_id_irq < 0) { |
| 104 | dev_err(dev, "can't get USB ID IRQ: %d\n", data->usb_id_irq); | 123 | dev_err(dev, "can't get USB ID IRQ: %d\n", data->usb_id_irq); |
| 105 | return -EINVAL; | 124 | return data->usb_id_irq; |
| 106 | } | 125 | } |
| 107 | 126 | ||
| 108 | data->gpio_vbus_en = devm_gpiod_get_index(dev, "vbus en", | 127 | data->gpio_vbus_en = devm_gpiod_get(dev, "vbus", GPIOD_ASIS); |
| 109 | INT3496_GPIO_VBUS_EN, | ||
| 110 | GPIOD_ASIS); | ||
| 111 | if (IS_ERR(data->gpio_vbus_en)) | 128 | if (IS_ERR(data->gpio_vbus_en)) |
| 112 | dev_info(dev, "can't request VBUS EN GPIO\n"); | 129 | dev_info(dev, "can't request VBUS EN GPIO\n"); |
| 113 | 130 | ||
| 114 | data->gpio_usb_mux = devm_gpiod_get_index(dev, "usb mux", | 131 | data->gpio_usb_mux = devm_gpiod_get(dev, "mux", GPIOD_ASIS); |
| 115 | INT3496_GPIO_USB_MUX, | ||
| 116 | GPIOD_ASIS); | ||
| 117 | if (IS_ERR(data->gpio_usb_mux)) | 132 | if (IS_ERR(data->gpio_usb_mux)) |
| 118 | dev_info(dev, "can't request USB MUX GPIO\n"); | 133 | dev_info(dev, "can't request USB MUX GPIO\n"); |
| 119 | 134 | ||
| @@ -154,6 +169,8 @@ static int int3496_remove(struct platform_device *pdev) | |||
| 154 | devm_free_irq(&pdev->dev, data->usb_id_irq, data); | 169 | devm_free_irq(&pdev->dev, data->usb_id_irq, data); |
| 155 | cancel_delayed_work_sync(&data->work); | 170 | cancel_delayed_work_sync(&data->work); |
| 156 | 171 | ||
| 172 | acpi_dev_remove_driver_gpios(ACPI_COMPANION(&pdev->dev)); | ||
| 173 | |||
| 157 | return 0; | 174 | return 0; |
| 158 | } | 175 | } |
| 159 | 176 | ||
diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c index bd0d1988feb2..321b8833fa6f 100644 --- a/drivers/hv/channel.c +++ b/drivers/hv/channel.c | |||
| @@ -502,12 +502,15 @@ int vmbus_teardown_gpadl(struct vmbus_channel *channel, u32 gpadl_handle) | |||
| 502 | 502 | ||
| 503 | wait_for_completion(&info->waitevent); | 503 | wait_for_completion(&info->waitevent); |
| 504 | 504 | ||
| 505 | if (channel->rescind) { | ||
| 506 | ret = -ENODEV; | ||
| 507 | goto post_msg_err; | ||
| 508 | } | ||
| 509 | |||
| 510 | post_msg_err: | 505 | post_msg_err: |
| 506 | /* | ||
| 507 | * If the channel has been rescinded; | ||
| 508 | * we will be awakened by the rescind | ||
| 509 | * handler; set the error code to zero so we don't leak memory. | ||
| 510 | */ | ||
| 511 | if (channel->rescind) | ||
| 512 | ret = 0; | ||
| 513 | |||
| 511 | spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags); | 514 | spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags); |
| 512 | list_del(&info->msglistentry); | 515 | list_del(&info->msglistentry); |
| 513 | spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags); | 516 | spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags); |
| @@ -530,15 +533,13 @@ static int vmbus_close_internal(struct vmbus_channel *channel) | |||
| 530 | int ret; | 533 | int ret; |
| 531 | 534 | ||
| 532 | /* | 535 | /* |
| 533 | * vmbus_on_event(), running in the tasklet, can race | 536 | * vmbus_on_event(), running in the per-channel tasklet, can race |
| 534 | * with vmbus_close_internal() in the case of SMP guest, e.g., when | 537 | * with vmbus_close_internal() in the case of SMP guest, e.g., when |
| 535 | * the former is accessing channel->inbound.ring_buffer, the latter | 538 | * the former is accessing channel->inbound.ring_buffer, the latter |
| 536 | * could be freeing the ring_buffer pages. | 539 | * could be freeing the ring_buffer pages, so here we must stop it |
| 537 | * | 540 | * first. |
| 538 | * To resolve the race, we can serialize them by disabling the | ||
| 539 | * tasklet when the latter is running here. | ||
| 540 | */ | 541 | */ |
| 541 | hv_event_tasklet_disable(channel); | 542 | tasklet_disable(&channel->callback_event); |
| 542 | 543 | ||
| 543 | /* | 544 | /* |
| 544 | * In case a device driver's probe() fails (e.g., | 545 | * In case a device driver's probe() fails (e.g., |
| @@ -605,8 +606,6 @@ static int vmbus_close_internal(struct vmbus_channel *channel) | |||
| 605 | get_order(channel->ringbuffer_pagecount * PAGE_SIZE)); | 606 | get_order(channel->ringbuffer_pagecount * PAGE_SIZE)); |
| 606 | 607 | ||
| 607 | out: | 608 | out: |
| 608 | hv_event_tasklet_enable(channel); | ||
| 609 | |||
| 610 | return ret; | 609 | return ret; |
| 611 | } | 610 | } |
| 612 | 611 | ||
diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c index f33465d78a02..fbcb06352308 100644 --- a/drivers/hv/channel_mgmt.c +++ b/drivers/hv/channel_mgmt.c | |||
| @@ -350,7 +350,8 @@ static struct vmbus_channel *alloc_channel(void) | |||
| 350 | static void free_channel(struct vmbus_channel *channel) | 350 | static void free_channel(struct vmbus_channel *channel) |
| 351 | { | 351 | { |
| 352 | tasklet_kill(&channel->callback_event); | 352 | tasklet_kill(&channel->callback_event); |
| 353 | kfree(channel); | 353 | |
| 354 | kfree_rcu(channel, rcu); | ||
| 354 | } | 355 | } |
| 355 | 356 | ||
| 356 | static void percpu_channel_enq(void *arg) | 357 | static void percpu_channel_enq(void *arg) |
| @@ -359,14 +360,14 @@ static void percpu_channel_enq(void *arg) | |||
| 359 | struct hv_per_cpu_context *hv_cpu | 360 | struct hv_per_cpu_context *hv_cpu |
| 360 | = this_cpu_ptr(hv_context.cpu_context); | 361 | = this_cpu_ptr(hv_context.cpu_context); |
| 361 | 362 | ||
| 362 | list_add_tail(&channel->percpu_list, &hv_cpu->chan_list); | 363 | list_add_tail_rcu(&channel->percpu_list, &hv_cpu->chan_list); |
| 363 | } | 364 | } |
| 364 | 365 | ||
| 365 | static void percpu_channel_deq(void *arg) | 366 | static void percpu_channel_deq(void *arg) |
| 366 | { | 367 | { |
| 367 | struct vmbus_channel *channel = arg; | 368 | struct vmbus_channel *channel = arg; |
| 368 | 369 | ||
| 369 | list_del(&channel->percpu_list); | 370 | list_del_rcu(&channel->percpu_list); |
| 370 | } | 371 | } |
| 371 | 372 | ||
| 372 | 373 | ||
| @@ -381,19 +382,6 @@ static void vmbus_release_relid(u32 relid) | |||
| 381 | true); | 382 | true); |
| 382 | } | 383 | } |
| 383 | 384 | ||
| 384 | void hv_event_tasklet_disable(struct vmbus_channel *channel) | ||
| 385 | { | ||
| 386 | tasklet_disable(&channel->callback_event); | ||
| 387 | } | ||
| 388 | |||
| 389 | void hv_event_tasklet_enable(struct vmbus_channel *channel) | ||
| 390 | { | ||
| 391 | tasklet_enable(&channel->callback_event); | ||
| 392 | |||
| 393 | /* In case there is any pending event */ | ||
| 394 | tasklet_schedule(&channel->callback_event); | ||
| 395 | } | ||
| 396 | |||
| 397 | void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid) | 385 | void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid) |
| 398 | { | 386 | { |
| 399 | unsigned long flags; | 387 | unsigned long flags; |
| @@ -402,7 +390,6 @@ void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid) | |||
| 402 | BUG_ON(!channel->rescind); | 390 | BUG_ON(!channel->rescind); |
| 403 | BUG_ON(!mutex_is_locked(&vmbus_connection.channel_mutex)); | 391 | BUG_ON(!mutex_is_locked(&vmbus_connection.channel_mutex)); |
| 404 | 392 | ||
| 405 | hv_event_tasklet_disable(channel); | ||
| 406 | if (channel->target_cpu != get_cpu()) { | 393 | if (channel->target_cpu != get_cpu()) { |
| 407 | put_cpu(); | 394 | put_cpu(); |
| 408 | smp_call_function_single(channel->target_cpu, | 395 | smp_call_function_single(channel->target_cpu, |
| @@ -411,7 +398,6 @@ void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid) | |||
| 411 | percpu_channel_deq(channel); | 398 | percpu_channel_deq(channel); |
| 412 | put_cpu(); | 399 | put_cpu(); |
| 413 | } | 400 | } |
| 414 | hv_event_tasklet_enable(channel); | ||
| 415 | 401 | ||
| 416 | if (channel->primary_channel == NULL) { | 402 | if (channel->primary_channel == NULL) { |
| 417 | list_del(&channel->listentry); | 403 | list_del(&channel->listentry); |
| @@ -505,7 +491,6 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel) | |||
| 505 | 491 | ||
| 506 | init_vp_index(newchannel, dev_type); | 492 | init_vp_index(newchannel, dev_type); |
| 507 | 493 | ||
| 508 | hv_event_tasklet_disable(newchannel); | ||
| 509 | if (newchannel->target_cpu != get_cpu()) { | 494 | if (newchannel->target_cpu != get_cpu()) { |
| 510 | put_cpu(); | 495 | put_cpu(); |
| 511 | smp_call_function_single(newchannel->target_cpu, | 496 | smp_call_function_single(newchannel->target_cpu, |
| @@ -515,7 +500,6 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel) | |||
| 515 | percpu_channel_enq(newchannel); | 500 | percpu_channel_enq(newchannel); |
| 516 | put_cpu(); | 501 | put_cpu(); |
| 517 | } | 502 | } |
| 518 | hv_event_tasklet_enable(newchannel); | ||
| 519 | 503 | ||
| 520 | /* | 504 | /* |
| 521 | * This state is used to indicate a successful open | 505 | * This state is used to indicate a successful open |
| @@ -565,7 +549,6 @@ err_deq_chan: | |||
| 565 | list_del(&newchannel->listentry); | 549 | list_del(&newchannel->listentry); |
| 566 | mutex_unlock(&vmbus_connection.channel_mutex); | 550 | mutex_unlock(&vmbus_connection.channel_mutex); |
| 567 | 551 | ||
| 568 | hv_event_tasklet_disable(newchannel); | ||
| 569 | if (newchannel->target_cpu != get_cpu()) { | 552 | if (newchannel->target_cpu != get_cpu()) { |
| 570 | put_cpu(); | 553 | put_cpu(); |
| 571 | smp_call_function_single(newchannel->target_cpu, | 554 | smp_call_function_single(newchannel->target_cpu, |
| @@ -574,7 +557,6 @@ err_deq_chan: | |||
| 574 | percpu_channel_deq(newchannel); | 557 | percpu_channel_deq(newchannel); |
| 575 | put_cpu(); | 558 | put_cpu(); |
| 576 | } | 559 | } |
| 577 | hv_event_tasklet_enable(newchannel); | ||
| 578 | 560 | ||
| 579 | vmbus_release_relid(newchannel->offermsg.child_relid); | 561 | vmbus_release_relid(newchannel->offermsg.child_relid); |
| 580 | 562 | ||
| @@ -814,6 +796,7 @@ static void vmbus_onoffer(struct vmbus_channel_message_header *hdr) | |||
| 814 | /* Allocate the channel object and save this offer. */ | 796 | /* Allocate the channel object and save this offer. */ |
| 815 | newchannel = alloc_channel(); | 797 | newchannel = alloc_channel(); |
| 816 | if (!newchannel) { | 798 | if (!newchannel) { |
| 799 | vmbus_release_relid(offer->child_relid); | ||
| 817 | pr_err("Unable to allocate channel object\n"); | 800 | pr_err("Unable to allocate channel object\n"); |
| 818 | return; | 801 | return; |
| 819 | } | 802 | } |
diff --git a/drivers/hv/hv_fcopy.c b/drivers/hv/hv_fcopy.c index 9aee6014339d..a5596a642ed0 100644 --- a/drivers/hv/hv_fcopy.c +++ b/drivers/hv/hv_fcopy.c | |||
| @@ -71,7 +71,6 @@ static DECLARE_WORK(fcopy_send_work, fcopy_send_data); | |||
| 71 | static const char fcopy_devname[] = "vmbus/hv_fcopy"; | 71 | static const char fcopy_devname[] = "vmbus/hv_fcopy"; |
| 72 | static u8 *recv_buffer; | 72 | static u8 *recv_buffer; |
| 73 | static struct hvutil_transport *hvt; | 73 | static struct hvutil_transport *hvt; |
| 74 | static struct completion release_event; | ||
| 75 | /* | 74 | /* |
| 76 | * This state maintains the version number registered by the daemon. | 75 | * This state maintains the version number registered by the daemon. |
| 77 | */ | 76 | */ |
| @@ -331,7 +330,6 @@ static void fcopy_on_reset(void) | |||
| 331 | 330 | ||
| 332 | if (cancel_delayed_work_sync(&fcopy_timeout_work)) | 331 | if (cancel_delayed_work_sync(&fcopy_timeout_work)) |
| 333 | fcopy_respond_to_host(HV_E_FAIL); | 332 | fcopy_respond_to_host(HV_E_FAIL); |
| 334 | complete(&release_event); | ||
| 335 | } | 333 | } |
| 336 | 334 | ||
| 337 | int hv_fcopy_init(struct hv_util_service *srv) | 335 | int hv_fcopy_init(struct hv_util_service *srv) |
| @@ -339,7 +337,6 @@ int hv_fcopy_init(struct hv_util_service *srv) | |||
| 339 | recv_buffer = srv->recv_buffer; | 337 | recv_buffer = srv->recv_buffer; |
| 340 | fcopy_transaction.recv_channel = srv->channel; | 338 | fcopy_transaction.recv_channel = srv->channel; |
| 341 | 339 | ||
| 342 | init_completion(&release_event); | ||
| 343 | /* | 340 | /* |
| 344 | * When this driver loads, the user level daemon that | 341 | * When this driver loads, the user level daemon that |
| 345 | * processes the host requests may not yet be running. | 342 | * processes the host requests may not yet be running. |
| @@ -361,5 +358,4 @@ void hv_fcopy_deinit(void) | |||
| 361 | fcopy_transaction.state = HVUTIL_DEVICE_DYING; | 358 | fcopy_transaction.state = HVUTIL_DEVICE_DYING; |
| 362 | cancel_delayed_work_sync(&fcopy_timeout_work); | 359 | cancel_delayed_work_sync(&fcopy_timeout_work); |
| 363 | hvutil_transport_destroy(hvt); | 360 | hvutil_transport_destroy(hvt); |
| 364 | wait_for_completion(&release_event); | ||
| 365 | } | 361 | } |
diff --git a/drivers/hv/hv_kvp.c b/drivers/hv/hv_kvp.c index de263712e247..a1adfe2cfb34 100644 --- a/drivers/hv/hv_kvp.c +++ b/drivers/hv/hv_kvp.c | |||
| @@ -101,7 +101,6 @@ static DECLARE_WORK(kvp_sendkey_work, kvp_send_key); | |||
| 101 | static const char kvp_devname[] = "vmbus/hv_kvp"; | 101 | static const char kvp_devname[] = "vmbus/hv_kvp"; |
| 102 | static u8 *recv_buffer; | 102 | static u8 *recv_buffer; |
| 103 | static struct hvutil_transport *hvt; | 103 | static struct hvutil_transport *hvt; |
| 104 | static struct completion release_event; | ||
| 105 | /* | 104 | /* |
| 106 | * Register the kernel component with the user-level daemon. | 105 | * Register the kernel component with the user-level daemon. |
| 107 | * As part of this registration, pass the LIC version number. | 106 | * As part of this registration, pass the LIC version number. |
| @@ -714,7 +713,6 @@ static void kvp_on_reset(void) | |||
| 714 | if (cancel_delayed_work_sync(&kvp_timeout_work)) | 713 | if (cancel_delayed_work_sync(&kvp_timeout_work)) |
| 715 | kvp_respond_to_host(NULL, HV_E_FAIL); | 714 | kvp_respond_to_host(NULL, HV_E_FAIL); |
| 716 | kvp_transaction.state = HVUTIL_DEVICE_INIT; | 715 | kvp_transaction.state = HVUTIL_DEVICE_INIT; |
| 717 | complete(&release_event); | ||
| 718 | } | 716 | } |
| 719 | 717 | ||
| 720 | int | 718 | int |
| @@ -723,7 +721,6 @@ hv_kvp_init(struct hv_util_service *srv) | |||
| 723 | recv_buffer = srv->recv_buffer; | 721 | recv_buffer = srv->recv_buffer; |
| 724 | kvp_transaction.recv_channel = srv->channel; | 722 | kvp_transaction.recv_channel = srv->channel; |
| 725 | 723 | ||
| 726 | init_completion(&release_event); | ||
| 727 | /* | 724 | /* |
| 728 | * When this driver loads, the user level daemon that | 725 | * When this driver loads, the user level daemon that |
| 729 | * processes the host requests may not yet be running. | 726 | * processes the host requests may not yet be running. |
| @@ -747,5 +744,4 @@ void hv_kvp_deinit(void) | |||
| 747 | cancel_delayed_work_sync(&kvp_timeout_work); | 744 | cancel_delayed_work_sync(&kvp_timeout_work); |
| 748 | cancel_work_sync(&kvp_sendkey_work); | 745 | cancel_work_sync(&kvp_sendkey_work); |
| 749 | hvutil_transport_destroy(hvt); | 746 | hvutil_transport_destroy(hvt); |
| 750 | wait_for_completion(&release_event); | ||
| 751 | } | 747 | } |
diff --git a/drivers/hv/hv_snapshot.c b/drivers/hv/hv_snapshot.c index bcc03f0748d6..e659d1b94a57 100644 --- a/drivers/hv/hv_snapshot.c +++ b/drivers/hv/hv_snapshot.c | |||
| @@ -79,7 +79,6 @@ static int dm_reg_value; | |||
| 79 | static const char vss_devname[] = "vmbus/hv_vss"; | 79 | static const char vss_devname[] = "vmbus/hv_vss"; |
| 80 | static __u8 *recv_buffer; | 80 | static __u8 *recv_buffer; |
| 81 | static struct hvutil_transport *hvt; | 81 | static struct hvutil_transport *hvt; |
| 82 | static struct completion release_event; | ||
| 83 | 82 | ||
| 84 | static void vss_timeout_func(struct work_struct *dummy); | 83 | static void vss_timeout_func(struct work_struct *dummy); |
| 85 | static void vss_handle_request(struct work_struct *dummy); | 84 | static void vss_handle_request(struct work_struct *dummy); |
| @@ -361,13 +360,11 @@ static void vss_on_reset(void) | |||
| 361 | if (cancel_delayed_work_sync(&vss_timeout_work)) | 360 | if (cancel_delayed_work_sync(&vss_timeout_work)) |
| 362 | vss_respond_to_host(HV_E_FAIL); | 361 | vss_respond_to_host(HV_E_FAIL); |
| 363 | vss_transaction.state = HVUTIL_DEVICE_INIT; | 362 | vss_transaction.state = HVUTIL_DEVICE_INIT; |
| 364 | complete(&release_event); | ||
| 365 | } | 363 | } |
| 366 | 364 | ||
| 367 | int | 365 | int |
| 368 | hv_vss_init(struct hv_util_service *srv) | 366 | hv_vss_init(struct hv_util_service *srv) |
| 369 | { | 367 | { |
| 370 | init_completion(&release_event); | ||
| 371 | if (vmbus_proto_version < VERSION_WIN8_1) { | 368 | if (vmbus_proto_version < VERSION_WIN8_1) { |
| 372 | pr_warn("Integration service 'Backup (volume snapshot)'" | 369 | pr_warn("Integration service 'Backup (volume snapshot)'" |
| 373 | " not supported on this host version.\n"); | 370 | " not supported on this host version.\n"); |
| @@ -400,5 +397,4 @@ void hv_vss_deinit(void) | |||
| 400 | cancel_delayed_work_sync(&vss_timeout_work); | 397 | cancel_delayed_work_sync(&vss_timeout_work); |
| 401 | cancel_work_sync(&vss_handle_request_work); | 398 | cancel_work_sync(&vss_handle_request_work); |
| 402 | hvutil_transport_destroy(hvt); | 399 | hvutil_transport_destroy(hvt); |
| 403 | wait_for_completion(&release_event); | ||
| 404 | } | 400 | } |
diff --git a/drivers/hv/hv_util.c b/drivers/hv/hv_util.c index 3042eaa13062..186b10083c55 100644 --- a/drivers/hv/hv_util.c +++ b/drivers/hv/hv_util.c | |||
| @@ -590,6 +590,8 @@ static int hv_timesync_init(struct hv_util_service *srv) | |||
| 590 | if (!hyperv_cs) | 590 | if (!hyperv_cs) |
| 591 | return -ENODEV; | 591 | return -ENODEV; |
| 592 | 592 | ||
| 593 | spin_lock_init(&host_ts.lock); | ||
| 594 | |||
| 593 | INIT_WORK(&wrk.work, hv_set_host_time); | 595 | INIT_WORK(&wrk.work, hv_set_host_time); |
| 594 | 596 | ||
| 595 | /* | 597 | /* |
diff --git a/drivers/hv/hv_utils_transport.c b/drivers/hv/hv_utils_transport.c index c235a9515267..4402a71e23f7 100644 --- a/drivers/hv/hv_utils_transport.c +++ b/drivers/hv/hv_utils_transport.c | |||
| @@ -182,10 +182,11 @@ static int hvt_op_release(struct inode *inode, struct file *file) | |||
| 182 | * connects back. | 182 | * connects back. |
| 183 | */ | 183 | */ |
| 184 | hvt_reset(hvt); | 184 | hvt_reset(hvt); |
| 185 | mutex_unlock(&hvt->lock); | ||
| 186 | 185 | ||
| 187 | if (mode_old == HVUTIL_TRANSPORT_DESTROY) | 186 | if (mode_old == HVUTIL_TRANSPORT_DESTROY) |
| 188 | hvt_transport_free(hvt); | 187 | complete(&hvt->release); |
| 188 | |||
| 189 | mutex_unlock(&hvt->lock); | ||
| 189 | 190 | ||
| 190 | return 0; | 191 | return 0; |
| 191 | } | 192 | } |
| @@ -304,6 +305,7 @@ struct hvutil_transport *hvutil_transport_init(const char *name, | |||
| 304 | 305 | ||
| 305 | init_waitqueue_head(&hvt->outmsg_q); | 306 | init_waitqueue_head(&hvt->outmsg_q); |
| 306 | mutex_init(&hvt->lock); | 307 | mutex_init(&hvt->lock); |
| 308 | init_completion(&hvt->release); | ||
| 307 | 309 | ||
| 308 | spin_lock(&hvt_list_lock); | 310 | spin_lock(&hvt_list_lock); |
| 309 | list_add(&hvt->list, &hvt_list); | 311 | list_add(&hvt->list, &hvt_list); |
| @@ -351,6 +353,8 @@ void hvutil_transport_destroy(struct hvutil_transport *hvt) | |||
| 351 | if (hvt->cn_id.idx > 0 && hvt->cn_id.val > 0) | 353 | if (hvt->cn_id.idx > 0 && hvt->cn_id.val > 0) |
| 352 | cn_del_callback(&hvt->cn_id); | 354 | cn_del_callback(&hvt->cn_id); |
| 353 | 355 | ||
| 354 | if (mode_old != HVUTIL_TRANSPORT_CHARDEV) | 356 | if (mode_old == HVUTIL_TRANSPORT_CHARDEV) |
| 355 | hvt_transport_free(hvt); | 357 | wait_for_completion(&hvt->release); |
| 358 | |||
| 359 | hvt_transport_free(hvt); | ||
| 356 | } | 360 | } |
diff --git a/drivers/hv/hv_utils_transport.h b/drivers/hv/hv_utils_transport.h index d98f5225c3e6..79afb626e166 100644 --- a/drivers/hv/hv_utils_transport.h +++ b/drivers/hv/hv_utils_transport.h | |||
| @@ -41,6 +41,7 @@ struct hvutil_transport { | |||
| 41 | int outmsg_len; /* its length */ | 41 | int outmsg_len; /* its length */ |
| 42 | wait_queue_head_t outmsg_q; /* poll/read wait queue */ | 42 | wait_queue_head_t outmsg_q; /* poll/read wait queue */ |
| 43 | struct mutex lock; /* protects struct members */ | 43 | struct mutex lock; /* protects struct members */ |
| 44 | struct completion release; /* synchronize with fd release */ | ||
| 44 | }; | 45 | }; |
| 45 | 46 | ||
| 46 | struct hvutil_transport *hvutil_transport_init(const char *name, | 47 | struct hvutil_transport *hvutil_transport_init(const char *name, |
diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c index da6b59ba5940..8370b9dc6037 100644 --- a/drivers/hv/vmbus_drv.c +++ b/drivers/hv/vmbus_drv.c | |||
| @@ -939,8 +939,10 @@ static void vmbus_chan_sched(struct hv_per_cpu_context *hv_cpu) | |||
| 939 | if (relid == 0) | 939 | if (relid == 0) |
| 940 | continue; | 940 | continue; |
| 941 | 941 | ||
| 942 | rcu_read_lock(); | ||
| 943 | |||
| 942 | /* Find channel based on relid */ | 944 | /* Find channel based on relid */ |
| 943 | list_for_each_entry(channel, &hv_cpu->chan_list, percpu_list) { | 945 | list_for_each_entry_rcu(channel, &hv_cpu->chan_list, percpu_list) { |
| 944 | if (channel->offermsg.child_relid != relid) | 946 | if (channel->offermsg.child_relid != relid) |
| 945 | continue; | 947 | continue; |
| 946 | 948 | ||
| @@ -956,6 +958,8 @@ static void vmbus_chan_sched(struct hv_per_cpu_context *hv_cpu) | |||
| 956 | tasklet_schedule(&channel->callback_event); | 958 | tasklet_schedule(&channel->callback_event); |
| 957 | } | 959 | } |
| 958 | } | 960 | } |
| 961 | |||
| 962 | rcu_read_unlock(); | ||
| 959 | } | 963 | } |
| 960 | } | 964 | } |
| 961 | 965 | ||
diff --git a/drivers/hwtracing/intel_th/core.c b/drivers/hwtracing/intel_th/core.c index cdd9b3b26195..7563eceeaaea 100644 --- a/drivers/hwtracing/intel_th/core.c +++ b/drivers/hwtracing/intel_th/core.c | |||
| @@ -221,8 +221,10 @@ static int intel_th_output_activate(struct intel_th_device *thdev) | |||
| 221 | else | 221 | else |
| 222 | intel_th_trace_enable(thdev); | 222 | intel_th_trace_enable(thdev); |
| 223 | 223 | ||
| 224 | if (ret) | 224 | if (ret) { |
| 225 | pm_runtime_put(&thdev->dev); | 225 | pm_runtime_put(&thdev->dev); |
| 226 | module_put(thdrv->driver.owner); | ||
| 227 | } | ||
| 226 | 228 | ||
| 227 | return ret; | 229 | return ret; |
| 228 | } | 230 | } |
diff --git a/drivers/hwtracing/intel_th/pci.c b/drivers/hwtracing/intel_th/pci.c index 0bba3842336e..590cf90dd21a 100644 --- a/drivers/hwtracing/intel_th/pci.c +++ b/drivers/hwtracing/intel_th/pci.c | |||
| @@ -85,6 +85,16 @@ static const struct pci_device_id intel_th_pci_id_table[] = { | |||
| 85 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa2a6), | 85 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa2a6), |
| 86 | .driver_data = (kernel_ulong_t)0, | 86 | .driver_data = (kernel_ulong_t)0, |
| 87 | }, | 87 | }, |
| 88 | { | ||
| 89 | /* Denverton */ | ||
| 90 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x19e1), | ||
| 91 | .driver_data = (kernel_ulong_t)0, | ||
| 92 | }, | ||
| 93 | { | ||
| 94 | /* Gemini Lake */ | ||
| 95 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x318e), | ||
| 96 | .driver_data = (kernel_ulong_t)0, | ||
| 97 | }, | ||
| 88 | { 0 }, | 98 | { 0 }, |
| 89 | }; | 99 | }; |
| 90 | 100 | ||
diff --git a/drivers/misc/mei/bus-fixup.c b/drivers/misc/mei/bus-fixup.c index 3600c9993a98..29f2daed37e0 100644 --- a/drivers/misc/mei/bus-fixup.c +++ b/drivers/misc/mei/bus-fixup.c | |||
| @@ -112,11 +112,9 @@ struct mkhi_msg { | |||
| 112 | 112 | ||
| 113 | static int mei_osver(struct mei_cl_device *cldev) | 113 | static int mei_osver(struct mei_cl_device *cldev) |
| 114 | { | 114 | { |
| 115 | int ret; | ||
| 116 | const size_t size = sizeof(struct mkhi_msg_hdr) + | 115 | const size_t size = sizeof(struct mkhi_msg_hdr) + |
| 117 | sizeof(struct mkhi_fwcaps) + | 116 | sizeof(struct mkhi_fwcaps) + |
| 118 | sizeof(struct mei_os_ver); | 117 | sizeof(struct mei_os_ver); |
| 119 | size_t length = 8; | ||
| 120 | char buf[size]; | 118 | char buf[size]; |
| 121 | struct mkhi_msg *req; | 119 | struct mkhi_msg *req; |
| 122 | struct mkhi_fwcaps *fwcaps; | 120 | struct mkhi_fwcaps *fwcaps; |
| @@ -137,15 +135,7 @@ static int mei_osver(struct mei_cl_device *cldev) | |||
| 137 | os_ver = (struct mei_os_ver *)fwcaps->data; | 135 | os_ver = (struct mei_os_ver *)fwcaps->data; |
| 138 | os_ver->os_type = OSTYPE_LINUX; | 136 | os_ver->os_type = OSTYPE_LINUX; |
| 139 | 137 | ||
| 140 | ret = __mei_cl_send(cldev->cl, buf, size, mode); | 138 | return __mei_cl_send(cldev->cl, buf, size, mode); |
| 141 | if (ret < 0) | ||
| 142 | return ret; | ||
| 143 | |||
| 144 | ret = __mei_cl_recv(cldev->cl, buf, length, 0); | ||
| 145 | if (ret < 0) | ||
| 146 | return ret; | ||
| 147 | |||
| 148 | return 0; | ||
| 149 | } | 139 | } |
| 150 | 140 | ||
| 151 | static void mei_mkhi_fix(struct mei_cl_device *cldev) | 141 | static void mei_mkhi_fix(struct mei_cl_device *cldev) |
| @@ -160,7 +150,7 @@ static void mei_mkhi_fix(struct mei_cl_device *cldev) | |||
| 160 | return; | 150 | return; |
| 161 | 151 | ||
| 162 | ret = mei_osver(cldev); | 152 | ret = mei_osver(cldev); |
| 163 | if (ret) | 153 | if (ret < 0) |
| 164 | dev_err(&cldev->dev, "OS version command failed %d\n", ret); | 154 | dev_err(&cldev->dev, "OS version command failed %d\n", ret); |
| 165 | 155 | ||
| 166 | mei_cldev_disable(cldev); | 156 | mei_cldev_disable(cldev); |
diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c index cfb1cdf176fa..13c55b8f9261 100644 --- a/drivers/misc/mei/init.c +++ b/drivers/misc/mei/init.c | |||
| @@ -124,8 +124,6 @@ int mei_reset(struct mei_device *dev) | |||
| 124 | 124 | ||
| 125 | mei_clear_interrupts(dev); | 125 | mei_clear_interrupts(dev); |
| 126 | 126 | ||
| 127 | mei_synchronize_irq(dev); | ||
| 128 | |||
| 129 | /* we're already in reset, cancel the init timer | 127 | /* we're already in reset, cancel the init timer |
| 130 | * if the reset was called due the hbm protocol error | 128 | * if the reset was called due the hbm protocol error |
| 131 | * we need to call it before hw start | 129 | * we need to call it before hw start |
| @@ -304,6 +302,9 @@ static void mei_reset_work(struct work_struct *work) | |||
| 304 | container_of(work, struct mei_device, reset_work); | 302 | container_of(work, struct mei_device, reset_work); |
| 305 | int ret; | 303 | int ret; |
| 306 | 304 | ||
| 305 | mei_clear_interrupts(dev); | ||
| 306 | mei_synchronize_irq(dev); | ||
| 307 | |||
| 307 | mutex_lock(&dev->device_lock); | 308 | mutex_lock(&dev->device_lock); |
| 308 | 309 | ||
| 309 | ret = mei_reset(dev); | 310 | ret = mei_reset(dev); |
| @@ -328,6 +329,9 @@ void mei_stop(struct mei_device *dev) | |||
| 328 | 329 | ||
| 329 | mei_cancel_work(dev); | 330 | mei_cancel_work(dev); |
| 330 | 331 | ||
| 332 | mei_clear_interrupts(dev); | ||
| 333 | mei_synchronize_irq(dev); | ||
| 334 | |||
| 331 | mutex_lock(&dev->device_lock); | 335 | mutex_lock(&dev->device_lock); |
| 332 | 336 | ||
| 333 | dev->dev_state = MEI_DEV_POWER_DOWN; | 337 | dev->dev_state = MEI_DEV_POWER_DOWN; |
diff --git a/drivers/misc/vmw_vmci/vmci_guest.c b/drivers/misc/vmw_vmci/vmci_guest.c index 9d659542a335..dad5abee656e 100644 --- a/drivers/misc/vmw_vmci/vmci_guest.c +++ b/drivers/misc/vmw_vmci/vmci_guest.c | |||
| @@ -566,10 +566,10 @@ static int vmci_guest_probe_device(struct pci_dev *pdev, | |||
| 566 | */ | 566 | */ |
| 567 | error = pci_alloc_irq_vectors(pdev, VMCI_MAX_INTRS, VMCI_MAX_INTRS, | 567 | error = pci_alloc_irq_vectors(pdev, VMCI_MAX_INTRS, VMCI_MAX_INTRS, |
| 568 | PCI_IRQ_MSIX); | 568 | PCI_IRQ_MSIX); |
| 569 | if (error) { | 569 | if (error < 0) { |
| 570 | error = pci_alloc_irq_vectors(pdev, 1, 1, | 570 | error = pci_alloc_irq_vectors(pdev, 1, 1, |
| 571 | PCI_IRQ_MSIX | PCI_IRQ_MSI | PCI_IRQ_LEGACY); | 571 | PCI_IRQ_MSIX | PCI_IRQ_MSI | PCI_IRQ_LEGACY); |
| 572 | if (error) | 572 | if (error < 0) |
| 573 | goto err_remove_bitmap; | 573 | goto err_remove_bitmap; |
| 574 | } else { | 574 | } else { |
| 575 | vmci_dev->exclusive_vectors = true; | 575 | vmci_dev->exclusive_vectors = true; |
diff --git a/drivers/parport/share.c b/drivers/parport/share.c index bc090daa850a..5dc53d420ca8 100644 --- a/drivers/parport/share.c +++ b/drivers/parport/share.c | |||
| @@ -939,8 +939,10 @@ parport_register_dev_model(struct parport *port, const char *name, | |||
| 939 | * pardevice fields. -arca | 939 | * pardevice fields. -arca |
| 940 | */ | 940 | */ |
| 941 | port->ops->init_state(par_dev, par_dev->state); | 941 | port->ops->init_state(par_dev, par_dev->state); |
| 942 | port->proc_device = par_dev; | 942 | if (!test_and_set_bit(PARPORT_DEVPROC_REGISTERED, &port->devflags)) { |
| 943 | parport_device_proc_register(par_dev); | 943 | port->proc_device = par_dev; |
| 944 | parport_device_proc_register(par_dev); | ||
| 945 | } | ||
| 944 | 946 | ||
| 945 | return par_dev; | 947 | return par_dev; |
| 946 | 948 | ||
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h index 62bbf3c1aa4a..970771a5f739 100644 --- a/include/linux/hyperv.h +++ b/include/linux/hyperv.h | |||
| @@ -845,6 +845,13 @@ struct vmbus_channel { | |||
| 845 | * link up channels based on their CPU affinity. | 845 | * link up channels based on their CPU affinity. |
| 846 | */ | 846 | */ |
| 847 | struct list_head percpu_list; | 847 | struct list_head percpu_list; |
| 848 | |||
| 849 | /* | ||
| 850 | * Defer freeing channel until after all cpu's have | ||
| 851 | * gone through grace period. | ||
| 852 | */ | ||
| 853 | struct rcu_head rcu; | ||
| 854 | |||
| 848 | /* | 855 | /* |
| 849 | * For performance critical channels (storage, networking | 856 | * For performance critical channels (storage, networking |
| 850 | * etc,), Hyper-V has a mechanism to enhance the throughput | 857 | * etc,), Hyper-V has a mechanism to enhance the throughput |
| @@ -1430,9 +1437,6 @@ extern bool vmbus_prep_negotiate_resp(struct icmsg_hdr *icmsghdrp, u8 *buf, | |||
| 1430 | const int *srv_version, int srv_vercnt, | 1437 | const int *srv_version, int srv_vercnt, |
| 1431 | int *nego_fw_version, int *nego_srv_version); | 1438 | int *nego_fw_version, int *nego_srv_version); |
| 1432 | 1439 | ||
| 1433 | void hv_event_tasklet_disable(struct vmbus_channel *channel); | ||
| 1434 | void hv_event_tasklet_enable(struct vmbus_channel *channel); | ||
| 1435 | |||
| 1436 | void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid); | 1440 | void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid); |
| 1437 | 1441 | ||
| 1438 | void vmbus_setevent(struct vmbus_channel *channel); | 1442 | void vmbus_setevent(struct vmbus_channel *channel); |
