diff options
34 files changed, 263 insertions, 89 deletions
diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S index 000d4199b03e..31e2d5bf3e38 100644 --- a/arch/x86/kernel/entry_32.S +++ b/arch/x86/kernel/entry_32.S | |||
| @@ -982,6 +982,9 @@ ENTRY(xen_hypervisor_callback) | |||
| 982 | ENTRY(xen_do_upcall) | 982 | ENTRY(xen_do_upcall) |
| 983 | 1: mov %esp, %eax | 983 | 1: mov %esp, %eax |
| 984 | call xen_evtchn_do_upcall | 984 | call xen_evtchn_do_upcall |
| 985 | #ifndef CONFIG_PREEMPT | ||
| 986 | call xen_maybe_preempt_hcall | ||
| 987 | #endif | ||
| 985 | jmp ret_from_intr | 988 | jmp ret_from_intr |
| 986 | CFI_ENDPROC | 989 | CFI_ENDPROC |
| 987 | ENDPROC(xen_hypervisor_callback) | 990 | ENDPROC(xen_hypervisor_callback) |
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index db13655c3a2a..10074ad9ebf8 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S | |||
| @@ -1208,6 +1208,9 @@ ENTRY(xen_do_hypervisor_callback) # do_hypervisor_callback(struct *pt_regs) | |||
| 1208 | popq %rsp | 1208 | popq %rsp |
| 1209 | CFI_DEF_CFA_REGISTER rsp | 1209 | CFI_DEF_CFA_REGISTER rsp |
| 1210 | decl PER_CPU_VAR(irq_count) | 1210 | decl PER_CPU_VAR(irq_count) |
| 1211 | #ifndef CONFIG_PREEMPT | ||
| 1212 | call xen_maybe_preempt_hcall | ||
| 1213 | #endif | ||
| 1211 | jmp error_exit | 1214 | jmp error_exit |
| 1212 | CFI_ENDPROC | 1215 | CFI_ENDPROC |
| 1213 | END(xen_do_hypervisor_callback) | 1216 | END(xen_do_hypervisor_callback) |
diff --git a/arch/x86/lguest/Kconfig b/arch/x86/lguest/Kconfig index 4a0890f815c4..08f41caada45 100644 --- a/arch/x86/lguest/Kconfig +++ b/arch/x86/lguest/Kconfig | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | config LGUEST_GUEST | 1 | config LGUEST_GUEST |
| 2 | bool "Lguest guest support" | 2 | bool "Lguest guest support" |
| 3 | depends on X86_32 && PARAVIRT | 3 | depends on X86_32 && PARAVIRT && PCI |
| 4 | select TTY | 4 | select TTY |
| 5 | select VIRTUALIZATION | 5 | select VIRTUALIZATION |
| 6 | select VIRTIO | 6 | select VIRTIO |
| @@ -8,7 +8,7 @@ config LGUEST_GUEST | |||
| 8 | help | 8 | help |
| 9 | Lguest is a tiny in-kernel hypervisor. Selecting this will | 9 | Lguest is a tiny in-kernel hypervisor. Selecting this will |
| 10 | allow your kernel to boot under lguest. This option will increase | 10 | allow your kernel to boot under lguest. This option will increase |
| 11 | your kernel size by about 6k. If in doubt, say N. | 11 | your kernel size by about 10k. If in doubt, say N. |
| 12 | 12 | ||
| 13 | If you say Y here, make sure you say Y (or M) to the virtio block | 13 | If you say Y here, make sure you say Y (or M) to the virtio block |
| 14 | and net drivers which lguest needs. | 14 | and net drivers which lguest needs. |
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index bd8b8459c3d0..5240f563076d 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c | |||
| @@ -1070,6 +1070,23 @@ static inline void xen_write_cr8(unsigned long val) | |||
| 1070 | BUG_ON(val); | 1070 | BUG_ON(val); |
| 1071 | } | 1071 | } |
| 1072 | #endif | 1072 | #endif |
| 1073 | |||
| 1074 | static u64 xen_read_msr_safe(unsigned int msr, int *err) | ||
| 1075 | { | ||
| 1076 | u64 val; | ||
| 1077 | |||
| 1078 | val = native_read_msr_safe(msr, err); | ||
| 1079 | switch (msr) { | ||
| 1080 | case MSR_IA32_APICBASE: | ||
| 1081 | #ifdef CONFIG_X86_X2APIC | ||
| 1082 | if (!(cpuid_ecx(1) & (1 << (X86_FEATURE_X2APIC & 31)))) | ||
| 1083 | #endif | ||
| 1084 | val &= ~X2APIC_ENABLE; | ||
| 1085 | break; | ||
| 1086 | } | ||
| 1087 | return val; | ||
| 1088 | } | ||
| 1089 | |||
| 1073 | static int xen_write_msr_safe(unsigned int msr, unsigned low, unsigned high) | 1090 | static int xen_write_msr_safe(unsigned int msr, unsigned low, unsigned high) |
| 1074 | { | 1091 | { |
| 1075 | int ret; | 1092 | int ret; |
| @@ -1240,7 +1257,7 @@ static const struct pv_cpu_ops xen_cpu_ops __initconst = { | |||
| 1240 | 1257 | ||
| 1241 | .wbinvd = native_wbinvd, | 1258 | .wbinvd = native_wbinvd, |
| 1242 | 1259 | ||
| 1243 | .read_msr = native_read_msr_safe, | 1260 | .read_msr = xen_read_msr_safe, |
| 1244 | .write_msr = xen_write_msr_safe, | 1261 | .write_msr = xen_write_msr_safe, |
| 1245 | 1262 | ||
| 1246 | .read_tsc = native_read_tsc, | 1263 | .read_tsc = native_read_tsc, |
| @@ -1741,6 +1758,7 @@ asmlinkage __visible void __init xen_start_kernel(void) | |||
| 1741 | #ifdef CONFIG_X86_32 | 1758 | #ifdef CONFIG_X86_32 |
| 1742 | i386_start_kernel(); | 1759 | i386_start_kernel(); |
| 1743 | #else | 1760 | #else |
| 1761 | cr4_init_shadow(); /* 32b kernel does this in i386_start_kernel() */ | ||
| 1744 | x86_64_start_reservations((char *)__pa_symbol(&boot_params)); | 1762 | x86_64_start_reservations((char *)__pa_symbol(&boot_params)); |
| 1745 | #endif | 1763 | #endif |
| 1746 | } | 1764 | } |
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index db4fb6e1cc5b..7c669c328c4c 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c | |||
| @@ -1872,6 +1872,7 @@ static const struct hid_device_id hid_have_special_driver[] = { | |||
| 1872 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_GV) }, | 1872 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_GV) }, |
| 1873 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K) }, | 1873 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K) }, |
| 1874 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K_JP) }, | 1874 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K_JP) }, |
| 1875 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE7K) }, | ||
| 1875 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_LK6K) }, | 1876 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_LK6K) }, |
| 1876 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_USB) }, | 1877 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_USB) }, |
| 1877 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_3K) }, | 1878 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_3K) }, |
| @@ -1926,6 +1927,7 @@ static const struct hid_device_id hid_have_special_driver[] = { | |||
| 1926 | #endif | 1927 | #endif |
| 1927 | #if IS_ENABLED(CONFIG_HID_SAITEK) | 1928 | #if IS_ENABLED(CONFIG_HID_SAITEK) |
| 1928 | { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_PS1000) }, | 1929 | { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_PS1000) }, |
| 1930 | { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RAT7_OLD) }, | ||
| 1929 | { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RAT7) }, | 1931 | { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RAT7) }, |
| 1930 | { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_MMO7) }, | 1932 | { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_MMO7) }, |
| 1931 | { HID_USB_DEVICE(USB_VENDOR_ID_MADCATZ, USB_DEVICE_ID_MADCATZ_RAT9) }, | 1933 | { HID_USB_DEVICE(USB_VENDOR_ID_MADCATZ, USB_DEVICE_ID_MADCATZ_RAT9) }, |
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 46edb4d3ed28..204312bfab2c 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h | |||
| @@ -654,6 +654,7 @@ | |||
| 654 | #define USB_DEVICE_ID_MS_LK6K 0x00f9 | 654 | #define USB_DEVICE_ID_MS_LK6K 0x00f9 |
| 655 | #define USB_DEVICE_ID_MS_PRESENTER_8K_BT 0x0701 | 655 | #define USB_DEVICE_ID_MS_PRESENTER_8K_BT 0x0701 |
| 656 | #define USB_DEVICE_ID_MS_PRESENTER_8K_USB 0x0713 | 656 | #define USB_DEVICE_ID_MS_PRESENTER_8K_USB 0x0713 |
| 657 | #define USB_DEVICE_ID_MS_NE7K 0x071d | ||
| 657 | #define USB_DEVICE_ID_MS_DIGITAL_MEDIA_3K 0x0730 | 658 | #define USB_DEVICE_ID_MS_DIGITAL_MEDIA_3K 0x0730 |
| 658 | #define USB_DEVICE_ID_MS_COMFORT_MOUSE_4500 0x076c | 659 | #define USB_DEVICE_ID_MS_COMFORT_MOUSE_4500 0x076c |
| 659 | #define USB_DEVICE_ID_MS_SURFACE_PRO_2 0x0799 | 660 | #define USB_DEVICE_ID_MS_SURFACE_PRO_2 0x0799 |
| @@ -802,6 +803,7 @@ | |||
| 802 | #define USB_VENDOR_ID_SAITEK 0x06a3 | 803 | #define USB_VENDOR_ID_SAITEK 0x06a3 |
| 803 | #define USB_DEVICE_ID_SAITEK_RUMBLEPAD 0xff17 | 804 | #define USB_DEVICE_ID_SAITEK_RUMBLEPAD 0xff17 |
| 804 | #define USB_DEVICE_ID_SAITEK_PS1000 0x0621 | 805 | #define USB_DEVICE_ID_SAITEK_PS1000 0x0621 |
| 806 | #define USB_DEVICE_ID_SAITEK_RAT7_OLD 0x0ccb | ||
| 805 | #define USB_DEVICE_ID_SAITEK_RAT7 0x0cd7 | 807 | #define USB_DEVICE_ID_SAITEK_RAT7 0x0cd7 |
| 806 | #define USB_DEVICE_ID_SAITEK_MMO7 0x0cd0 | 808 | #define USB_DEVICE_ID_SAITEK_MMO7 0x0cd0 |
| 807 | 809 | ||
diff --git a/drivers/hid/hid-microsoft.c b/drivers/hid/hid-microsoft.c index fbaea6eb882e..af935eb198c9 100644 --- a/drivers/hid/hid-microsoft.c +++ b/drivers/hid/hid-microsoft.c | |||
| @@ -264,6 +264,8 @@ static const struct hid_device_id ms_devices[] = { | |||
| 264 | .driver_data = MS_ERGONOMY }, | 264 | .driver_data = MS_ERGONOMY }, |
| 265 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K_JP), | 265 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K_JP), |
| 266 | .driver_data = MS_ERGONOMY }, | 266 | .driver_data = MS_ERGONOMY }, |
| 267 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE7K), | ||
| 268 | .driver_data = MS_ERGONOMY }, | ||
| 267 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_LK6K), | 269 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_LK6K), |
| 268 | .driver_data = MS_ERGONOMY | MS_RDESC }, | 270 | .driver_data = MS_ERGONOMY | MS_RDESC }, |
| 269 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_USB), | 271 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_USB), |
diff --git a/drivers/hid/hid-saitek.c b/drivers/hid/hid-saitek.c index 5632c54eadf0..a014f21275d8 100644 --- a/drivers/hid/hid-saitek.c +++ b/drivers/hid/hid-saitek.c | |||
| @@ -177,6 +177,8 @@ static int saitek_event(struct hid_device *hdev, struct hid_field *field, | |||
| 177 | static const struct hid_device_id saitek_devices[] = { | 177 | static const struct hid_device_id saitek_devices[] = { |
| 178 | { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_PS1000), | 178 | { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_PS1000), |
| 179 | .driver_data = SAITEK_FIX_PS1000 }, | 179 | .driver_data = SAITEK_FIX_PS1000 }, |
| 180 | { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RAT7_OLD), | ||
| 181 | .driver_data = SAITEK_RELEASE_MODE_RAT7 }, | ||
| 180 | { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RAT7), | 182 | { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RAT7), |
| 181 | .driver_data = SAITEK_RELEASE_MODE_RAT7 }, | 183 | .driver_data = SAITEK_RELEASE_MODE_RAT7 }, |
| 182 | { HID_USB_DEVICE(USB_VENDOR_ID_MADCATZ, USB_DEVICE_ID_MADCATZ_RAT9), | 184 | { HID_USB_DEVICE(USB_VENDOR_ID_MADCATZ, USB_DEVICE_ID_MADCATZ_RAT9), |
diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c index 6a58b6c723aa..e54ce1097e2c 100644 --- a/drivers/hid/hid-sensor-hub.c +++ b/drivers/hid/hid-sensor-hub.c | |||
| @@ -135,8 +135,9 @@ static struct hid_sensor_hub_callbacks *sensor_hub_get_callback( | |||
| 135 | { | 135 | { |
| 136 | struct hid_sensor_hub_callbacks_list *callback; | 136 | struct hid_sensor_hub_callbacks_list *callback; |
| 137 | struct sensor_hub_data *pdata = hid_get_drvdata(hdev); | 137 | struct sensor_hub_data *pdata = hid_get_drvdata(hdev); |
| 138 | unsigned long flags; | ||
| 138 | 139 | ||
| 139 | spin_lock(&pdata->dyn_callback_lock); | 140 | spin_lock_irqsave(&pdata->dyn_callback_lock, flags); |
| 140 | list_for_each_entry(callback, &pdata->dyn_callback_list, list) | 141 | list_for_each_entry(callback, &pdata->dyn_callback_list, list) |
| 141 | if (callback->usage_id == usage_id && | 142 | if (callback->usage_id == usage_id && |
| 142 | (collection_index >= | 143 | (collection_index >= |
| @@ -145,10 +146,11 @@ static struct hid_sensor_hub_callbacks *sensor_hub_get_callback( | |||
| 145 | callback->hsdev->end_collection_index)) { | 146 | callback->hsdev->end_collection_index)) { |
| 146 | *priv = callback->priv; | 147 | *priv = callback->priv; |
| 147 | *hsdev = callback->hsdev; | 148 | *hsdev = callback->hsdev; |
| 148 | spin_unlock(&pdata->dyn_callback_lock); | 149 | spin_unlock_irqrestore(&pdata->dyn_callback_lock, |
| 150 | flags); | ||
| 149 | return callback->usage_callback; | 151 | return callback->usage_callback; |
| 150 | } | 152 | } |
| 151 | spin_unlock(&pdata->dyn_callback_lock); | 153 | spin_unlock_irqrestore(&pdata->dyn_callback_lock, flags); |
| 152 | 154 | ||
| 153 | return NULL; | 155 | return NULL; |
| 154 | } | 156 | } |
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index 31e9d2561106..1896c019e302 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c | |||
| @@ -804,7 +804,7 @@ union sixaxis_output_report_01 { | |||
| 804 | #define DS4_REPORT_0x81_SIZE 7 | 804 | #define DS4_REPORT_0x81_SIZE 7 |
| 805 | #define SIXAXIS_REPORT_0xF2_SIZE 18 | 805 | #define SIXAXIS_REPORT_0xF2_SIZE 18 |
| 806 | 806 | ||
| 807 | static spinlock_t sony_dev_list_lock; | 807 | static DEFINE_SPINLOCK(sony_dev_list_lock); |
| 808 | static LIST_HEAD(sony_device_list); | 808 | static LIST_HEAD(sony_device_list); |
| 809 | static DEFINE_IDA(sony_device_id_allocator); | 809 | static DEFINE_IDA(sony_device_id_allocator); |
| 810 | 810 | ||
| @@ -1944,6 +1944,8 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
| 1944 | return -ENOMEM; | 1944 | return -ENOMEM; |
| 1945 | } | 1945 | } |
| 1946 | 1946 | ||
| 1947 | spin_lock_init(&sc->lock); | ||
| 1948 | |||
| 1947 | sc->quirks = quirks; | 1949 | sc->quirks = quirks; |
| 1948 | hid_set_drvdata(hdev, sc); | 1950 | hid_set_drvdata(hdev, sc); |
| 1949 | sc->hdev = hdev; | 1951 | sc->hdev = hdev; |
| @@ -2147,8 +2149,8 @@ static void __exit sony_exit(void) | |||
| 2147 | { | 2149 | { |
| 2148 | dbg_hid("Sony:%s\n", __func__); | 2150 | dbg_hid("Sony:%s\n", __func__); |
| 2149 | 2151 | ||
| 2150 | ida_destroy(&sony_device_id_allocator); | ||
| 2151 | hid_unregister_driver(&sony_driver); | 2152 | hid_unregister_driver(&sony_driver); |
| 2153 | ida_destroy(&sony_device_id_allocator); | ||
| 2152 | } | 2154 | } |
| 2153 | module_init(sony_init); | 2155 | module_init(sony_init); |
| 2154 | module_exit(sony_exit); | 2156 | module_exit(sony_exit); |
diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c index d43e967e7533..36053f33d6d9 100644 --- a/drivers/hid/i2c-hid/i2c-hid.c +++ b/drivers/hid/i2c-hid/i2c-hid.c | |||
| @@ -370,7 +370,10 @@ static int i2c_hid_hwreset(struct i2c_client *client) | |||
| 370 | static void i2c_hid_get_input(struct i2c_hid *ihid) | 370 | static void i2c_hid_get_input(struct i2c_hid *ihid) |
| 371 | { | 371 | { |
| 372 | int ret, ret_size; | 372 | int ret, ret_size; |
| 373 | int size = ihid->bufsize; | 373 | int size = le16_to_cpu(ihid->hdesc.wMaxInputLength); |
| 374 | |||
| 375 | if (size > ihid->bufsize) | ||
| 376 | size = ihid->bufsize; | ||
| 374 | 377 | ||
| 375 | ret = i2c_master_recv(ihid->client, ihid->inbuf, size); | 378 | ret = i2c_master_recv(ihid->client, ihid->inbuf, size); |
| 376 | if (ret != size) { | 379 | if (ret != size) { |
| @@ -785,7 +788,7 @@ static int i2c_hid_init_irq(struct i2c_client *client) | |||
| 785 | dev_dbg(&client->dev, "Requesting IRQ: %d\n", client->irq); | 788 | dev_dbg(&client->dev, "Requesting IRQ: %d\n", client->irq); |
| 786 | 789 | ||
| 787 | ret = request_threaded_irq(client->irq, NULL, i2c_hid_irq, | 790 | ret = request_threaded_irq(client->irq, NULL, i2c_hid_irq, |
| 788 | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, | 791 | IRQF_TRIGGER_LOW | IRQF_ONESHOT, |
| 789 | client->name, ihid); | 792 | client->name, ihid); |
| 790 | if (ret < 0) { | 793 | if (ret < 0) { |
| 791 | dev_warn(&client->dev, | 794 | dev_warn(&client->dev, |
diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 1a6507999a65..046351cf17f3 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c | |||
| @@ -778,6 +778,11 @@ static int wacom_intuos_irq(struct wacom_wac *wacom) | |||
| 778 | input_report_abs(input, ABS_X, be16_to_cpup((__be16 *)&data[4])); | 778 | input_report_abs(input, ABS_X, be16_to_cpup((__be16 *)&data[4])); |
| 779 | input_report_abs(input, ABS_Y, be16_to_cpup((__be16 *)&data[6])); | 779 | input_report_abs(input, ABS_Y, be16_to_cpup((__be16 *)&data[6])); |
| 780 | input_report_abs(input, ABS_Z, be16_to_cpup((__be16 *)&data[8])); | 780 | input_report_abs(input, ABS_Z, be16_to_cpup((__be16 *)&data[8])); |
| 781 | if ((data[2] & 0x07) | data[4] | data[5] | data[6] | data[7] | data[8] | data[9]) { | ||
| 782 | input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); | ||
| 783 | } else { | ||
| 784 | input_report_abs(input, ABS_MISC, 0); | ||
| 785 | } | ||
| 781 | } else if (features->type == CINTIQ_HYBRID) { | 786 | } else if (features->type == CINTIQ_HYBRID) { |
| 782 | /* | 787 | /* |
| 783 | * Do not send hardware buttons under Android. They | 788 | * Do not send hardware buttons under Android. They |
| @@ -2725,9 +2730,9 @@ static const struct wacom_features wacom_features_0xF6 = | |||
| 2725 | .oVid = USB_VENDOR_ID_WACOM, .oPid = 0xf8, .touch_max = 10, | 2730 | .oVid = USB_VENDOR_ID_WACOM, .oPid = 0xf8, .touch_max = 10, |
| 2726 | .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE }; | 2731 | .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE }; |
| 2727 | static const struct wacom_features wacom_features_0x32A = | 2732 | static const struct wacom_features wacom_features_0x32A = |
| 2728 | { "Wacom Cintiq 27QHD", 119740, 67520, 2047, | 2733 | { "Wacom Cintiq 27QHD", 119740, 67520, 2047, 63, |
| 2729 | 63, WACOM_27QHD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, | 2734 | WACOM_27QHD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, |
| 2730 | WACOM_27QHD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | 2735 | WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET }; |
| 2731 | static const struct wacom_features wacom_features_0x32B = | 2736 | static const struct wacom_features wacom_features_0x32B = |
| 2732 | { "Wacom Cintiq 27QHD touch", 119740, 67520, 2047, 63, | 2737 | { "Wacom Cintiq 27QHD touch", 119740, 67520, 2047, 63, |
| 2733 | WACOM_27QHD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, | 2738 | WACOM_27QHD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, |
diff --git a/drivers/hwmon/ads7828.c b/drivers/hwmon/ads7828.c index bce4e9ff21bf..6c99ee7bafa3 100644 --- a/drivers/hwmon/ads7828.c +++ b/drivers/hwmon/ads7828.c | |||
| @@ -147,6 +147,9 @@ static int ads7828_probe(struct i2c_client *client, | |||
| 147 | &ads2830_regmap_config); | 147 | &ads2830_regmap_config); |
| 148 | } | 148 | } |
| 149 | 149 | ||
| 150 | if (IS_ERR(data->regmap)) | ||
| 151 | return PTR_ERR(data->regmap); | ||
| 152 | |||
| 150 | data->cmd_byte = ext_vref ? ADS7828_CMD_PD1 : ADS7828_CMD_PD3; | 153 | data->cmd_byte = ext_vref ? ADS7828_CMD_PD1 : ADS7828_CMD_PD3; |
| 151 | if (!diff_input) | 154 | if (!diff_input) |
| 152 | data->cmd_byte |= ADS7828_CMD_SD_SE; | 155 | data->cmd_byte |= ADS7828_CMD_SD_SE; |
diff --git a/drivers/xen/Makefile b/drivers/xen/Makefile index 2140398a2a8c..2ccd3592d41f 100644 --- a/drivers/xen/Makefile +++ b/drivers/xen/Makefile | |||
| @@ -2,7 +2,7 @@ ifeq ($(filter y, $(CONFIG_ARM) $(CONFIG_ARM64)),) | |||
| 2 | obj-$(CONFIG_HOTPLUG_CPU) += cpu_hotplug.o | 2 | obj-$(CONFIG_HOTPLUG_CPU) += cpu_hotplug.o |
| 3 | endif | 3 | endif |
| 4 | obj-$(CONFIG_X86) += fallback.o | 4 | obj-$(CONFIG_X86) += fallback.o |
| 5 | obj-y += grant-table.o features.o balloon.o manage.o | 5 | obj-y += grant-table.o features.o balloon.o manage.o preempt.o |
| 6 | obj-y += events/ | 6 | obj-y += events/ |
| 7 | obj-y += xenbus/ | 7 | obj-y += xenbus/ |
| 8 | 8 | ||
diff --git a/drivers/xen/preempt.c b/drivers/xen/preempt.c new file mode 100644 index 000000000000..a1800c150839 --- /dev/null +++ b/drivers/xen/preempt.c | |||
| @@ -0,0 +1,44 @@ | |||
| 1 | /* | ||
| 2 | * Preemptible hypercalls | ||
| 3 | * | ||
| 4 | * Copyright (C) 2014 Citrix Systems R&D ltd. | ||
| 5 | * | ||
| 6 | * This source code is free software; you can redistribute it and/or | ||
| 7 | * modify it under the terms of the GNU General Public License as | ||
| 8 | * published by the Free Software Foundation; either version 2 of the | ||
| 9 | * License, or (at your option) any later version. | ||
| 10 | */ | ||
| 11 | |||
| 12 | #include <linux/sched.h> | ||
| 13 | #include <xen/xen-ops.h> | ||
| 14 | |||
| 15 | #ifndef CONFIG_PREEMPT | ||
| 16 | |||
| 17 | /* | ||
| 18 | * Some hypercalls issued by the toolstack can take many 10s of | ||
| 19 | * seconds. Allow tasks running hypercalls via the privcmd driver to | ||
| 20 | * be voluntarily preempted even if full kernel preemption is | ||
| 21 | * disabled. | ||
| 22 | * | ||
| 23 | * Such preemptible hypercalls are bracketed by | ||
| 24 | * xen_preemptible_hcall_begin() and xen_preemptible_hcall_end() | ||
| 25 | * calls. | ||
| 26 | */ | ||
| 27 | |||
| 28 | DEFINE_PER_CPU(bool, xen_in_preemptible_hcall); | ||
| 29 | EXPORT_SYMBOL_GPL(xen_in_preemptible_hcall); | ||
| 30 | |||
| 31 | asmlinkage __visible void xen_maybe_preempt_hcall(void) | ||
| 32 | { | ||
| 33 | if (unlikely(__this_cpu_read(xen_in_preemptible_hcall) | ||
| 34 | && should_resched())) { | ||
| 35 | /* | ||
| 36 | * Clear flag as we may be rescheduled on a different | ||
| 37 | * cpu. | ||
| 38 | */ | ||
| 39 | __this_cpu_write(xen_in_preemptible_hcall, false); | ||
| 40 | _cond_resched(); | ||
| 41 | __this_cpu_write(xen_in_preemptible_hcall, true); | ||
| 42 | } | ||
| 43 | } | ||
| 44 | #endif /* CONFIG_PREEMPT */ | ||
diff --git a/drivers/xen/privcmd.c b/drivers/xen/privcmd.c index 569a13b9e856..59ac71c4a043 100644 --- a/drivers/xen/privcmd.c +++ b/drivers/xen/privcmd.c | |||
| @@ -56,10 +56,12 @@ static long privcmd_ioctl_hypercall(void __user *udata) | |||
| 56 | if (copy_from_user(&hypercall, udata, sizeof(hypercall))) | 56 | if (copy_from_user(&hypercall, udata, sizeof(hypercall))) |
| 57 | return -EFAULT; | 57 | return -EFAULT; |
| 58 | 58 | ||
| 59 | xen_preemptible_hcall_begin(); | ||
| 59 | ret = privcmd_call(hypercall.op, | 60 | ret = privcmd_call(hypercall.op, |
| 60 | hypercall.arg[0], hypercall.arg[1], | 61 | hypercall.arg[0], hypercall.arg[1], |
| 61 | hypercall.arg[2], hypercall.arg[3], | 62 | hypercall.arg[2], hypercall.arg[3], |
| 62 | hypercall.arg[4]); | 63 | hypercall.arg[4]); |
| 64 | xen_preemptible_hcall_end(); | ||
| 63 | 65 | ||
| 64 | return ret; | 66 | return ret; |
| 65 | } | 67 | } |
diff --git a/drivers/xen/xen-scsiback.c b/drivers/xen/xen-scsiback.c index 61653a03a8f5..9faca6a60bb0 100644 --- a/drivers/xen/xen-scsiback.c +++ b/drivers/xen/xen-scsiback.c | |||
| @@ -709,12 +709,11 @@ static int prepare_pending_reqs(struct vscsibk_info *info, | |||
| 709 | static int scsiback_do_cmd_fn(struct vscsibk_info *info) | 709 | static int scsiback_do_cmd_fn(struct vscsibk_info *info) |
| 710 | { | 710 | { |
| 711 | struct vscsiif_back_ring *ring = &info->ring; | 711 | struct vscsiif_back_ring *ring = &info->ring; |
| 712 | struct vscsiif_request *ring_req; | 712 | struct vscsiif_request ring_req; |
| 713 | struct vscsibk_pend *pending_req; | 713 | struct vscsibk_pend *pending_req; |
| 714 | RING_IDX rc, rp; | 714 | RING_IDX rc, rp; |
| 715 | int err, more_to_do; | 715 | int err, more_to_do; |
| 716 | uint32_t result; | 716 | uint32_t result; |
| 717 | uint8_t act; | ||
| 718 | 717 | ||
| 719 | rc = ring->req_cons; | 718 | rc = ring->req_cons; |
| 720 | rp = ring->sring->req_prod; | 719 | rp = ring->sring->req_prod; |
| @@ -735,11 +734,10 @@ static int scsiback_do_cmd_fn(struct vscsibk_info *info) | |||
| 735 | if (!pending_req) | 734 | if (!pending_req) |
| 736 | return 1; | 735 | return 1; |
| 737 | 736 | ||
| 738 | ring_req = RING_GET_REQUEST(ring, rc); | 737 | ring_req = *RING_GET_REQUEST(ring, rc); |
| 739 | ring->req_cons = ++rc; | 738 | ring->req_cons = ++rc; |
| 740 | 739 | ||
| 741 | act = ring_req->act; | 740 | err = prepare_pending_reqs(info, &ring_req, pending_req); |
| 742 | err = prepare_pending_reqs(info, ring_req, pending_req); | ||
| 743 | if (err) { | 741 | if (err) { |
| 744 | switch (err) { | 742 | switch (err) { |
| 745 | case -ENODEV: | 743 | case -ENODEV: |
| @@ -755,9 +753,9 @@ static int scsiback_do_cmd_fn(struct vscsibk_info *info) | |||
| 755 | return 1; | 753 | return 1; |
| 756 | } | 754 | } |
| 757 | 755 | ||
| 758 | switch (act) { | 756 | switch (ring_req.act) { |
| 759 | case VSCSIIF_ACT_SCSI_CDB: | 757 | case VSCSIIF_ACT_SCSI_CDB: |
| 760 | if (scsiback_gnttab_data_map(ring_req, pending_req)) { | 758 | if (scsiback_gnttab_data_map(&ring_req, pending_req)) { |
| 761 | scsiback_fast_flush_area(pending_req); | 759 | scsiback_fast_flush_area(pending_req); |
| 762 | scsiback_do_resp_with_sense(NULL, | 760 | scsiback_do_resp_with_sense(NULL, |
| 763 | DRIVER_ERROR << 24, 0, pending_req); | 761 | DRIVER_ERROR << 24, 0, pending_req); |
| @@ -768,7 +766,7 @@ static int scsiback_do_cmd_fn(struct vscsibk_info *info) | |||
| 768 | break; | 766 | break; |
| 769 | case VSCSIIF_ACT_SCSI_ABORT: | 767 | case VSCSIIF_ACT_SCSI_ABORT: |
| 770 | scsiback_device_action(pending_req, TMR_ABORT_TASK, | 768 | scsiback_device_action(pending_req, TMR_ABORT_TASK, |
| 771 | ring_req->ref_rqid); | 769 | ring_req.ref_rqid); |
| 772 | break; | 770 | break; |
| 773 | case VSCSIIF_ACT_SCSI_RESET: | 771 | case VSCSIIF_ACT_SCSI_RESET: |
| 774 | scsiback_device_action(pending_req, TMR_LUN_RESET, 0); | 772 | scsiback_device_action(pending_req, TMR_LUN_RESET, 0); |
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index cd4d1315aaa9..8222f6f74147 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c | |||
| @@ -4903,10 +4903,17 @@ static void sort_parity_stripes(struct btrfs_bio *bbio, int num_stripes) | |||
| 4903 | static struct btrfs_bio *alloc_btrfs_bio(int total_stripes, int real_stripes) | 4903 | static struct btrfs_bio *alloc_btrfs_bio(int total_stripes, int real_stripes) |
| 4904 | { | 4904 | { |
| 4905 | struct btrfs_bio *bbio = kzalloc( | 4905 | struct btrfs_bio *bbio = kzalloc( |
| 4906 | /* the size of the btrfs_bio */ | ||
| 4906 | sizeof(struct btrfs_bio) + | 4907 | sizeof(struct btrfs_bio) + |
| 4908 | /* plus the variable array for the stripes */ | ||
| 4907 | sizeof(struct btrfs_bio_stripe) * (total_stripes) + | 4909 | sizeof(struct btrfs_bio_stripe) * (total_stripes) + |
| 4910 | /* plus the variable array for the tgt dev */ | ||
| 4908 | sizeof(int) * (real_stripes) + | 4911 | sizeof(int) * (real_stripes) + |
| 4909 | sizeof(u64) * (real_stripes), | 4912 | /* |
| 4913 | * plus the raid_map, which includes both the tgt dev | ||
| 4914 | * and the stripes | ||
| 4915 | */ | ||
| 4916 | sizeof(u64) * (total_stripes), | ||
| 4910 | GFP_NOFS); | 4917 | GFP_NOFS); |
| 4911 | if (!bbio) | 4918 | if (!bbio) |
| 4912 | return NULL; | 4919 | return NULL; |
diff --git a/include/linux/hid-sensor-hub.h b/include/linux/hid-sensor-hub.h index 51f7ccadf923..4173a8fdad9e 100644 --- a/include/linux/hid-sensor-hub.h +++ b/include/linux/hid-sensor-hub.h | |||
| @@ -33,6 +33,8 @@ | |||
| 33 | * @units: Measurment unit for this attribute. | 33 | * @units: Measurment unit for this attribute. |
| 34 | * @unit_expo: Exponent used in the data. | 34 | * @unit_expo: Exponent used in the data. |
| 35 | * @size: Size in bytes for data size. | 35 | * @size: Size in bytes for data size. |
| 36 | * @logical_minimum: Logical minimum value for this attribute. | ||
| 37 | * @logical_maximum: Logical maximum value for this attribute. | ||
| 36 | */ | 38 | */ |
| 37 | struct hid_sensor_hub_attribute_info { | 39 | struct hid_sensor_hub_attribute_info { |
| 38 | u32 usage_id; | 40 | u32 usage_id; |
| @@ -146,6 +148,7 @@ int sensor_hub_input_get_attribute_info(struct hid_sensor_hub_device *hsdev, | |||
| 146 | 148 | ||
| 147 | /** | 149 | /** |
| 148 | * sensor_hub_input_attr_get_raw_value() - Synchronous read request | 150 | * sensor_hub_input_attr_get_raw_value() - Synchronous read request |
| 151 | * @hsdev: Hub device instance. | ||
| 149 | * @usage_id: Attribute usage id of parent physical device as per spec | 152 | * @usage_id: Attribute usage id of parent physical device as per spec |
| 150 | * @attr_usage_id: Attribute usage id as per spec | 153 | * @attr_usage_id: Attribute usage id as per spec |
| 151 | * @report_id: Report id to look for | 154 | * @report_id: Report id to look for |
| @@ -160,6 +163,7 @@ int sensor_hub_input_attr_get_raw_value(struct hid_sensor_hub_device *hsdev, | |||
| 160 | u32 attr_usage_id, u32 report_id); | 163 | u32 attr_usage_id, u32 report_id); |
| 161 | /** | 164 | /** |
| 162 | * sensor_hub_set_feature() - Feature set request | 165 | * sensor_hub_set_feature() - Feature set request |
| 166 | * @hsdev: Hub device instance. | ||
| 163 | * @report_id: Report id to look for | 167 | * @report_id: Report id to look for |
| 164 | * @field_index: Field index inside a report | 168 | * @field_index: Field index inside a report |
| 165 | * @value: Value to set | 169 | * @value: Value to set |
| @@ -172,6 +176,7 @@ int sensor_hub_set_feature(struct hid_sensor_hub_device *hsdev, u32 report_id, | |||
| 172 | 176 | ||
| 173 | /** | 177 | /** |
| 174 | * sensor_hub_get_feature() - Feature get request | 178 | * sensor_hub_get_feature() - Feature get request |
| 179 | * @hsdev: Hub device instance. | ||
| 175 | * @report_id: Report id to look for | 180 | * @report_id: Report id to look for |
| 176 | * @field_index: Field index inside a report | 181 | * @field_index: Field index inside a report |
| 177 | * @value: Place holder for return value | 182 | * @value: Place holder for return value |
diff --git a/include/xen/xen-ops.h b/include/xen/xen-ops.h index 7491ee5d8164..83338210ee04 100644 --- a/include/xen/xen-ops.h +++ b/include/xen/xen-ops.h | |||
| @@ -46,4 +46,30 @@ static inline efi_system_table_t __init *xen_efi_probe(void) | |||
| 46 | } | 46 | } |
| 47 | #endif | 47 | #endif |
| 48 | 48 | ||
| 49 | #ifdef CONFIG_PREEMPT | ||
| 50 | |||
| 51 | static inline void xen_preemptible_hcall_begin(void) | ||
| 52 | { | ||
| 53 | } | ||
| 54 | |||
| 55 | static inline void xen_preemptible_hcall_end(void) | ||
| 56 | { | ||
| 57 | } | ||
| 58 | |||
| 59 | #else | ||
| 60 | |||
| 61 | DECLARE_PER_CPU(bool, xen_in_preemptible_hcall); | ||
| 62 | |||
| 63 | static inline void xen_preemptible_hcall_begin(void) | ||
| 64 | { | ||
| 65 | __this_cpu_write(xen_in_preemptible_hcall, true); | ||
| 66 | } | ||
| 67 | |||
| 68 | static inline void xen_preemptible_hcall_end(void) | ||
| 69 | { | ||
| 70 | __this_cpu_write(xen_in_preemptible_hcall, false); | ||
| 71 | } | ||
| 72 | |||
| 73 | #endif /* CONFIG_PREEMPT */ | ||
| 74 | |||
| 49 | #endif /* INCLUDE_XEN_OPS_H */ | 75 | #endif /* INCLUDE_XEN_OPS_H */ |
diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c index ff7f47d026ac..782172f073c5 100644 --- a/kernel/livepatch/core.c +++ b/kernel/livepatch/core.c | |||
| @@ -314,12 +314,12 @@ static void notrace klp_ftrace_handler(unsigned long ip, | |||
| 314 | rcu_read_lock(); | 314 | rcu_read_lock(); |
| 315 | func = list_first_or_null_rcu(&ops->func_stack, struct klp_func, | 315 | func = list_first_or_null_rcu(&ops->func_stack, struct klp_func, |
| 316 | stack_node); | 316 | stack_node); |
| 317 | rcu_read_unlock(); | ||
| 318 | |||
| 319 | if (WARN_ON_ONCE(!func)) | 317 | if (WARN_ON_ONCE(!func)) |
| 320 | return; | 318 | goto unlock; |
| 321 | 319 | ||
| 322 | klp_arch_set_pc(regs, (unsigned long)func->new_func); | 320 | klp_arch_set_pc(regs, (unsigned long)func->new_func); |
| 321 | unlock: | ||
| 322 | rcu_read_unlock(); | ||
| 323 | } | 323 | } |
| 324 | 324 | ||
| 325 | static int klp_disable_func(struct klp_func *func) | 325 | static int klp_disable_func(struct klp_func *func) |
| @@ -731,7 +731,7 @@ static int klp_init_func(struct klp_object *obj, struct klp_func *func) | |||
| 731 | func->state = KLP_DISABLED; | 731 | func->state = KLP_DISABLED; |
| 732 | 732 | ||
| 733 | return kobject_init_and_add(&func->kobj, &klp_ktype_func, | 733 | return kobject_init_and_add(&func->kobj, &klp_ktype_func, |
| 734 | obj->kobj, func->old_name); | 734 | obj->kobj, "%s", func->old_name); |
| 735 | } | 735 | } |
| 736 | 736 | ||
| 737 | /* parts of the initialization that is done only when the object is loaded */ | 737 | /* parts of the initialization that is done only when the object is loaded */ |
| @@ -807,7 +807,7 @@ static int klp_init_patch(struct klp_patch *patch) | |||
| 807 | patch->state = KLP_DISABLED; | 807 | patch->state = KLP_DISABLED; |
| 808 | 808 | ||
| 809 | ret = kobject_init_and_add(&patch->kobj, &klp_ktype_patch, | 809 | ret = kobject_init_and_add(&patch->kobj, &klp_ktype_patch, |
| 810 | klp_root_kobj, patch->mod->name); | 810 | klp_root_kobj, "%s", patch->mod->name); |
| 811 | if (ret) | 811 | if (ret) |
| 812 | goto unlock; | 812 | goto unlock; |
| 813 | 813 | ||
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index b03a638b420c..279e24f61305 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c | |||
| @@ -1552,6 +1552,8 @@ static int snd_pcm_do_drain_init(struct snd_pcm_substream *substream, int state) | |||
| 1552 | if (! snd_pcm_playback_empty(substream)) { | 1552 | if (! snd_pcm_playback_empty(substream)) { |
| 1553 | snd_pcm_do_start(substream, SNDRV_PCM_STATE_DRAINING); | 1553 | snd_pcm_do_start(substream, SNDRV_PCM_STATE_DRAINING); |
| 1554 | snd_pcm_post_start(substream, SNDRV_PCM_STATE_DRAINING); | 1554 | snd_pcm_post_start(substream, SNDRV_PCM_STATE_DRAINING); |
| 1555 | } else { | ||
| 1556 | runtime->status->state = SNDRV_PCM_STATE_SETUP; | ||
| 1555 | } | 1557 | } |
| 1556 | break; | 1558 | break; |
| 1557 | case SNDRV_PCM_STATE_RUNNING: | 1559 | case SNDRV_PCM_STATE_RUNNING: |
diff --git a/sound/firewire/amdtp.c b/sound/firewire/amdtp.c index 0d580186ef1a..5cc356db5351 100644 --- a/sound/firewire/amdtp.c +++ b/sound/firewire/amdtp.c | |||
| @@ -33,7 +33,7 @@ | |||
| 33 | */ | 33 | */ |
| 34 | #define MAX_MIDI_RX_BLOCKS 8 | 34 | #define MAX_MIDI_RX_BLOCKS 8 |
| 35 | 35 | ||
| 36 | #define TRANSFER_DELAY_TICKS 0x2e00 /* 479.17 µs */ | 36 | #define TRANSFER_DELAY_TICKS 0x2e00 /* 479.17 microseconds */ |
| 37 | 37 | ||
| 38 | /* isochronous header parameters */ | 38 | /* isochronous header parameters */ |
| 39 | #define ISO_DATA_LENGTH_SHIFT 16 | 39 | #define ISO_DATA_LENGTH_SHIFT 16 |
| @@ -78,7 +78,7 @@ static void pcm_period_tasklet(unsigned long data); | |||
| 78 | int amdtp_stream_init(struct amdtp_stream *s, struct fw_unit *unit, | 78 | int amdtp_stream_init(struct amdtp_stream *s, struct fw_unit *unit, |
| 79 | enum amdtp_stream_direction dir, enum cip_flags flags) | 79 | enum amdtp_stream_direction dir, enum cip_flags flags) |
| 80 | { | 80 | { |
| 81 | s->unit = fw_unit_get(unit); | 81 | s->unit = unit; |
| 82 | s->direction = dir; | 82 | s->direction = dir; |
| 83 | s->flags = flags; | 83 | s->flags = flags; |
| 84 | s->context = ERR_PTR(-1); | 84 | s->context = ERR_PTR(-1); |
| @@ -102,7 +102,6 @@ void amdtp_stream_destroy(struct amdtp_stream *s) | |||
| 102 | { | 102 | { |
| 103 | WARN_ON(amdtp_stream_running(s)); | 103 | WARN_ON(amdtp_stream_running(s)); |
| 104 | mutex_destroy(&s->mutex); | 104 | mutex_destroy(&s->mutex); |
| 105 | fw_unit_put(s->unit); | ||
| 106 | } | 105 | } |
| 107 | EXPORT_SYMBOL(amdtp_stream_destroy); | 106 | EXPORT_SYMBOL(amdtp_stream_destroy); |
| 108 | 107 | ||
diff --git a/sound/firewire/bebob/bebob.c b/sound/firewire/bebob/bebob.c index fc19c99654aa..611b7dae7ee5 100644 --- a/sound/firewire/bebob/bebob.c +++ b/sound/firewire/bebob/bebob.c | |||
| @@ -116,11 +116,22 @@ end: | |||
| 116 | return err; | 116 | return err; |
| 117 | } | 117 | } |
| 118 | 118 | ||
| 119 | /* | ||
| 120 | * This module releases the FireWire unit data after all ALSA character devices | ||
| 121 | * are released by applications. This is for releasing stream data or finishing | ||
| 122 | * transactions safely. Thus at returning from .remove(), this module still keep | ||
| 123 | * references for the unit. | ||
| 124 | */ | ||
| 119 | static void | 125 | static void |
| 120 | bebob_card_free(struct snd_card *card) | 126 | bebob_card_free(struct snd_card *card) |
| 121 | { | 127 | { |
| 122 | struct snd_bebob *bebob = card->private_data; | 128 | struct snd_bebob *bebob = card->private_data; |
| 123 | 129 | ||
| 130 | snd_bebob_stream_destroy_duplex(bebob); | ||
| 131 | fw_unit_put(bebob->unit); | ||
| 132 | |||
| 133 | kfree(bebob->maudio_special_quirk); | ||
| 134 | |||
| 124 | if (bebob->card_index >= 0) { | 135 | if (bebob->card_index >= 0) { |
| 125 | mutex_lock(&devices_mutex); | 136 | mutex_lock(&devices_mutex); |
| 126 | clear_bit(bebob->card_index, devices_used); | 137 | clear_bit(bebob->card_index, devices_used); |
| @@ -205,7 +216,7 @@ bebob_probe(struct fw_unit *unit, | |||
| 205 | card->private_free = bebob_card_free; | 216 | card->private_free = bebob_card_free; |
| 206 | 217 | ||
| 207 | bebob->card = card; | 218 | bebob->card = card; |
| 208 | bebob->unit = unit; | 219 | bebob->unit = fw_unit_get(unit); |
| 209 | bebob->spec = spec; | 220 | bebob->spec = spec; |
| 210 | mutex_init(&bebob->mutex); | 221 | mutex_init(&bebob->mutex); |
| 211 | spin_lock_init(&bebob->lock); | 222 | spin_lock_init(&bebob->lock); |
| @@ -306,10 +317,11 @@ static void bebob_remove(struct fw_unit *unit) | |||
| 306 | if (bebob == NULL) | 317 | if (bebob == NULL) |
| 307 | return; | 318 | return; |
| 308 | 319 | ||
| 309 | kfree(bebob->maudio_special_quirk); | 320 | /* Awake bus-reset waiters. */ |
| 321 | if (!completion_done(&bebob->bus_reset)) | ||
| 322 | complete_all(&bebob->bus_reset); | ||
| 310 | 323 | ||
| 311 | snd_bebob_stream_destroy_duplex(bebob); | 324 | /* No need to wait for releasing card object in this context. */ |
| 312 | snd_card_disconnect(bebob->card); | ||
| 313 | snd_card_free_when_closed(bebob->card); | 325 | snd_card_free_when_closed(bebob->card); |
| 314 | } | 326 | } |
| 315 | 327 | ||
diff --git a/sound/firewire/bebob/bebob_stream.c b/sound/firewire/bebob/bebob_stream.c index 0ebcabfdc7ce..98e4fc8121a1 100644 --- a/sound/firewire/bebob/bebob_stream.c +++ b/sound/firewire/bebob/bebob_stream.c | |||
| @@ -410,8 +410,6 @@ break_both_connections(struct snd_bebob *bebob) | |||
| 410 | static void | 410 | static void |
| 411 | destroy_both_connections(struct snd_bebob *bebob) | 411 | destroy_both_connections(struct snd_bebob *bebob) |
| 412 | { | 412 | { |
| 413 | break_both_connections(bebob); | ||
| 414 | |||
| 415 | cmp_connection_destroy(&bebob->in_conn); | 413 | cmp_connection_destroy(&bebob->in_conn); |
| 416 | cmp_connection_destroy(&bebob->out_conn); | 414 | cmp_connection_destroy(&bebob->out_conn); |
| 417 | } | 415 | } |
| @@ -712,22 +710,16 @@ void snd_bebob_stream_update_duplex(struct snd_bebob *bebob) | |||
| 712 | mutex_unlock(&bebob->mutex); | 710 | mutex_unlock(&bebob->mutex); |
| 713 | } | 711 | } |
| 714 | 712 | ||
| 713 | /* | ||
| 714 | * This function should be called before starting streams or after stopping | ||
| 715 | * streams. | ||
| 716 | */ | ||
| 715 | void snd_bebob_stream_destroy_duplex(struct snd_bebob *bebob) | 717 | void snd_bebob_stream_destroy_duplex(struct snd_bebob *bebob) |
| 716 | { | 718 | { |
| 717 | mutex_lock(&bebob->mutex); | ||
| 718 | |||
| 719 | amdtp_stream_pcm_abort(&bebob->rx_stream); | ||
| 720 | amdtp_stream_pcm_abort(&bebob->tx_stream); | ||
| 721 | |||
| 722 | amdtp_stream_stop(&bebob->rx_stream); | ||
| 723 | amdtp_stream_stop(&bebob->tx_stream); | ||
| 724 | |||
| 725 | amdtp_stream_destroy(&bebob->rx_stream); | 719 | amdtp_stream_destroy(&bebob->rx_stream); |
| 726 | amdtp_stream_destroy(&bebob->tx_stream); | 720 | amdtp_stream_destroy(&bebob->tx_stream); |
| 727 | 721 | ||
| 728 | destroy_both_connections(bebob); | 722 | destroy_both_connections(bebob); |
| 729 | |||
| 730 | mutex_unlock(&bebob->mutex); | ||
| 731 | } | 723 | } |
| 732 | 724 | ||
| 733 | /* | 725 | /* |
diff --git a/sound/firewire/dice/dice-stream.c b/sound/firewire/dice/dice-stream.c index fa9cf761b610..07dbd01d7a6b 100644 --- a/sound/firewire/dice/dice-stream.c +++ b/sound/firewire/dice/dice-stream.c | |||
| @@ -311,14 +311,21 @@ end: | |||
| 311 | return err; | 311 | return err; |
| 312 | } | 312 | } |
| 313 | 313 | ||
| 314 | /* | ||
| 315 | * This function should be called before starting streams or after stopping | ||
| 316 | * streams. | ||
| 317 | */ | ||
| 314 | static void destroy_stream(struct snd_dice *dice, struct amdtp_stream *stream) | 318 | static void destroy_stream(struct snd_dice *dice, struct amdtp_stream *stream) |
| 315 | { | 319 | { |
| 316 | amdtp_stream_destroy(stream); | 320 | struct fw_iso_resources *resources; |
| 317 | 321 | ||
| 318 | if (stream == &dice->tx_stream) | 322 | if (stream == &dice->tx_stream) |
| 319 | fw_iso_resources_destroy(&dice->tx_resources); | 323 | resources = &dice->tx_resources; |
| 320 | else | 324 | else |
| 321 | fw_iso_resources_destroy(&dice->rx_resources); | 325 | resources = &dice->rx_resources; |
| 326 | |||
| 327 | amdtp_stream_destroy(stream); | ||
| 328 | fw_iso_resources_destroy(resources); | ||
| 322 | } | 329 | } |
| 323 | 330 | ||
| 324 | int snd_dice_stream_init_duplex(struct snd_dice *dice) | 331 | int snd_dice_stream_init_duplex(struct snd_dice *dice) |
| @@ -332,6 +339,8 @@ int snd_dice_stream_init_duplex(struct snd_dice *dice) | |||
| 332 | goto end; | 339 | goto end; |
| 333 | 340 | ||
| 334 | err = init_stream(dice, &dice->rx_stream); | 341 | err = init_stream(dice, &dice->rx_stream); |
| 342 | if (err < 0) | ||
| 343 | destroy_stream(dice, &dice->tx_stream); | ||
| 335 | end: | 344 | end: |
| 336 | return err; | 345 | return err; |
| 337 | } | 346 | } |
| @@ -340,10 +349,7 @@ void snd_dice_stream_destroy_duplex(struct snd_dice *dice) | |||
| 340 | { | 349 | { |
| 341 | snd_dice_transaction_clear_enable(dice); | 350 | snd_dice_transaction_clear_enable(dice); |
| 342 | 351 | ||
| 343 | stop_stream(dice, &dice->tx_stream); | ||
| 344 | destroy_stream(dice, &dice->tx_stream); | 352 | destroy_stream(dice, &dice->tx_stream); |
| 345 | |||
| 346 | stop_stream(dice, &dice->rx_stream); | ||
| 347 | destroy_stream(dice, &dice->rx_stream); | 353 | destroy_stream(dice, &dice->rx_stream); |
| 348 | 354 | ||
| 349 | dice->substreams_counter = 0; | 355 | dice->substreams_counter = 0; |
diff --git a/sound/firewire/dice/dice.c b/sound/firewire/dice/dice.c index 90d8f40ff727..70a111d7f428 100644 --- a/sound/firewire/dice/dice.c +++ b/sound/firewire/dice/dice.c | |||
| @@ -226,11 +226,20 @@ static void dice_card_strings(struct snd_dice *dice) | |||
| 226 | strcpy(card->mixername, "DICE"); | 226 | strcpy(card->mixername, "DICE"); |
| 227 | } | 227 | } |
| 228 | 228 | ||
| 229 | /* | ||
| 230 | * This module releases the FireWire unit data after all ALSA character devices | ||
| 231 | * are released by applications. This is for releasing stream data or finishing | ||
| 232 | * transactions safely. Thus at returning from .remove(), this module still keep | ||
| 233 | * references for the unit. | ||
| 234 | */ | ||
| 229 | static void dice_card_free(struct snd_card *card) | 235 | static void dice_card_free(struct snd_card *card) |
| 230 | { | 236 | { |
| 231 | struct snd_dice *dice = card->private_data; | 237 | struct snd_dice *dice = card->private_data; |
| 232 | 238 | ||
| 239 | snd_dice_stream_destroy_duplex(dice); | ||
| 233 | snd_dice_transaction_destroy(dice); | 240 | snd_dice_transaction_destroy(dice); |
| 241 | fw_unit_put(dice->unit); | ||
| 242 | |||
| 234 | mutex_destroy(&dice->mutex); | 243 | mutex_destroy(&dice->mutex); |
| 235 | } | 244 | } |
| 236 | 245 | ||
| @@ -251,7 +260,7 @@ static int dice_probe(struct fw_unit *unit, const struct ieee1394_device_id *id) | |||
| 251 | 260 | ||
| 252 | dice = card->private_data; | 261 | dice = card->private_data; |
| 253 | dice->card = card; | 262 | dice->card = card; |
| 254 | dice->unit = unit; | 263 | dice->unit = fw_unit_get(unit); |
| 255 | card->private_free = dice_card_free; | 264 | card->private_free = dice_card_free; |
| 256 | 265 | ||
| 257 | spin_lock_init(&dice->lock); | 266 | spin_lock_init(&dice->lock); |
| @@ -305,10 +314,7 @@ static void dice_remove(struct fw_unit *unit) | |||
| 305 | { | 314 | { |
| 306 | struct snd_dice *dice = dev_get_drvdata(&unit->device); | 315 | struct snd_dice *dice = dev_get_drvdata(&unit->device); |
| 307 | 316 | ||
| 308 | snd_card_disconnect(dice->card); | 317 | /* No need to wait for releasing card object in this context. */ |
| 309 | |||
| 310 | snd_dice_stream_destroy_duplex(dice); | ||
| 311 | |||
| 312 | snd_card_free_when_closed(dice->card); | 318 | snd_card_free_when_closed(dice->card); |
| 313 | } | 319 | } |
| 314 | 320 | ||
diff --git a/sound/firewire/fireworks/fireworks.c b/sound/firewire/fireworks/fireworks.c index 3e2ed8e82cbc..2682e7e3e5c9 100644 --- a/sound/firewire/fireworks/fireworks.c +++ b/sound/firewire/fireworks/fireworks.c | |||
| @@ -173,11 +173,23 @@ end: | |||
| 173 | return err; | 173 | return err; |
| 174 | } | 174 | } |
| 175 | 175 | ||
| 176 | /* | ||
| 177 | * This module releases the FireWire unit data after all ALSA character devices | ||
| 178 | * are released by applications. This is for releasing stream data or finishing | ||
| 179 | * transactions safely. Thus at returning from .remove(), this module still keep | ||
| 180 | * references for the unit. | ||
| 181 | */ | ||
| 176 | static void | 182 | static void |
| 177 | efw_card_free(struct snd_card *card) | 183 | efw_card_free(struct snd_card *card) |
| 178 | { | 184 | { |
| 179 | struct snd_efw *efw = card->private_data; | 185 | struct snd_efw *efw = card->private_data; |
| 180 | 186 | ||
| 187 | snd_efw_stream_destroy_duplex(efw); | ||
| 188 | snd_efw_transaction_remove_instance(efw); | ||
| 189 | fw_unit_put(efw->unit); | ||
| 190 | |||
| 191 | kfree(efw->resp_buf); | ||
| 192 | |||
| 181 | if (efw->card_index >= 0) { | 193 | if (efw->card_index >= 0) { |
| 182 | mutex_lock(&devices_mutex); | 194 | mutex_lock(&devices_mutex); |
| 183 | clear_bit(efw->card_index, devices_used); | 195 | clear_bit(efw->card_index, devices_used); |
| @@ -185,7 +197,6 @@ efw_card_free(struct snd_card *card) | |||
| 185 | } | 197 | } |
| 186 | 198 | ||
| 187 | mutex_destroy(&efw->mutex); | 199 | mutex_destroy(&efw->mutex); |
| 188 | kfree(efw->resp_buf); | ||
| 189 | } | 200 | } |
| 190 | 201 | ||
| 191 | static int | 202 | static int |
| @@ -218,7 +229,7 @@ efw_probe(struct fw_unit *unit, | |||
| 218 | card->private_free = efw_card_free; | 229 | card->private_free = efw_card_free; |
| 219 | 230 | ||
| 220 | efw->card = card; | 231 | efw->card = card; |
| 221 | efw->unit = unit; | 232 | efw->unit = fw_unit_get(unit); |
| 222 | mutex_init(&efw->mutex); | 233 | mutex_init(&efw->mutex); |
| 223 | spin_lock_init(&efw->lock); | 234 | spin_lock_init(&efw->lock); |
| 224 | init_waitqueue_head(&efw->hwdep_wait); | 235 | init_waitqueue_head(&efw->hwdep_wait); |
| @@ -289,10 +300,7 @@ static void efw_remove(struct fw_unit *unit) | |||
| 289 | { | 300 | { |
| 290 | struct snd_efw *efw = dev_get_drvdata(&unit->device); | 301 | struct snd_efw *efw = dev_get_drvdata(&unit->device); |
| 291 | 302 | ||
| 292 | snd_efw_stream_destroy_duplex(efw); | 303 | /* No need to wait for releasing card object in this context. */ |
| 293 | snd_efw_transaction_remove_instance(efw); | ||
| 294 | |||
| 295 | snd_card_disconnect(efw->card); | ||
| 296 | snd_card_free_when_closed(efw->card); | 304 | snd_card_free_when_closed(efw->card); |
| 297 | } | 305 | } |
| 298 | 306 | ||
diff --git a/sound/firewire/fireworks/fireworks_stream.c b/sound/firewire/fireworks/fireworks_stream.c index 4f440e163667..c55db1bddc80 100644 --- a/sound/firewire/fireworks/fireworks_stream.c +++ b/sound/firewire/fireworks/fireworks_stream.c | |||
| @@ -100,17 +100,22 @@ end: | |||
| 100 | return err; | 100 | return err; |
| 101 | } | 101 | } |
| 102 | 102 | ||
| 103 | /* | ||
| 104 | * This function should be called before starting the stream or after stopping | ||
| 105 | * the streams. | ||
| 106 | */ | ||
| 103 | static void | 107 | static void |
| 104 | destroy_stream(struct snd_efw *efw, struct amdtp_stream *stream) | 108 | destroy_stream(struct snd_efw *efw, struct amdtp_stream *stream) |
| 105 | { | 109 | { |
| 106 | stop_stream(efw, stream); | 110 | struct cmp_connection *conn; |
| 107 | |||
| 108 | amdtp_stream_destroy(stream); | ||
| 109 | 111 | ||
| 110 | if (stream == &efw->tx_stream) | 112 | if (stream == &efw->tx_stream) |
| 111 | cmp_connection_destroy(&efw->out_conn); | 113 | conn = &efw->out_conn; |
| 112 | else | 114 | else |
| 113 | cmp_connection_destroy(&efw->in_conn); | 115 | conn = &efw->in_conn; |
| 116 | |||
| 117 | amdtp_stream_destroy(stream); | ||
| 118 | cmp_connection_destroy(&efw->out_conn); | ||
| 114 | } | 119 | } |
| 115 | 120 | ||
| 116 | static int | 121 | static int |
| @@ -319,12 +324,8 @@ void snd_efw_stream_update_duplex(struct snd_efw *efw) | |||
| 319 | 324 | ||
| 320 | void snd_efw_stream_destroy_duplex(struct snd_efw *efw) | 325 | void snd_efw_stream_destroy_duplex(struct snd_efw *efw) |
| 321 | { | 326 | { |
| 322 | mutex_lock(&efw->mutex); | ||
| 323 | |||
| 324 | destroy_stream(efw, &efw->rx_stream); | 327 | destroy_stream(efw, &efw->rx_stream); |
| 325 | destroy_stream(efw, &efw->tx_stream); | 328 | destroy_stream(efw, &efw->tx_stream); |
| 326 | |||
| 327 | mutex_unlock(&efw->mutex); | ||
| 328 | } | 329 | } |
| 329 | 330 | ||
| 330 | void snd_efw_stream_lock_changed(struct snd_efw *efw) | 331 | void snd_efw_stream_lock_changed(struct snd_efw *efw) |
diff --git a/sound/firewire/oxfw/oxfw-stream.c b/sound/firewire/oxfw/oxfw-stream.c index bda845afb470..29ccb3637164 100644 --- a/sound/firewire/oxfw/oxfw-stream.c +++ b/sound/firewire/oxfw/oxfw-stream.c | |||
| @@ -337,6 +337,10 @@ void snd_oxfw_stream_stop_simplex(struct snd_oxfw *oxfw, | |||
| 337 | stop_stream(oxfw, stream); | 337 | stop_stream(oxfw, stream); |
| 338 | } | 338 | } |
| 339 | 339 | ||
| 340 | /* | ||
| 341 | * This function should be called before starting the stream or after stopping | ||
| 342 | * the streams. | ||
| 343 | */ | ||
| 340 | void snd_oxfw_stream_destroy_simplex(struct snd_oxfw *oxfw, | 344 | void snd_oxfw_stream_destroy_simplex(struct snd_oxfw *oxfw, |
| 341 | struct amdtp_stream *stream) | 345 | struct amdtp_stream *stream) |
| 342 | { | 346 | { |
| @@ -347,8 +351,6 @@ void snd_oxfw_stream_destroy_simplex(struct snd_oxfw *oxfw, | |||
| 347 | else | 351 | else |
| 348 | conn = &oxfw->in_conn; | 352 | conn = &oxfw->in_conn; |
| 349 | 353 | ||
| 350 | stop_stream(oxfw, stream); | ||
| 351 | |||
| 352 | amdtp_stream_destroy(stream); | 354 | amdtp_stream_destroy(stream); |
| 353 | cmp_connection_destroy(conn); | 355 | cmp_connection_destroy(conn); |
| 354 | } | 356 | } |
diff --git a/sound/firewire/oxfw/oxfw.c b/sound/firewire/oxfw/oxfw.c index 60e5cad0531a..8c6ce019f437 100644 --- a/sound/firewire/oxfw/oxfw.c +++ b/sound/firewire/oxfw/oxfw.c | |||
| @@ -104,11 +104,23 @@ end: | |||
| 104 | return err; | 104 | return err; |
| 105 | } | 105 | } |
| 106 | 106 | ||
| 107 | /* | ||
| 108 | * This module releases the FireWire unit data after all ALSA character devices | ||
| 109 | * are released by applications. This is for releasing stream data or finishing | ||
| 110 | * transactions safely. Thus at returning from .remove(), this module still keep | ||
| 111 | * references for the unit. | ||
| 112 | */ | ||
| 107 | static void oxfw_card_free(struct snd_card *card) | 113 | static void oxfw_card_free(struct snd_card *card) |
| 108 | { | 114 | { |
| 109 | struct snd_oxfw *oxfw = card->private_data; | 115 | struct snd_oxfw *oxfw = card->private_data; |
| 110 | unsigned int i; | 116 | unsigned int i; |
| 111 | 117 | ||
| 118 | snd_oxfw_stream_destroy_simplex(oxfw, &oxfw->rx_stream); | ||
| 119 | if (oxfw->has_output) | ||
| 120 | snd_oxfw_stream_destroy_simplex(oxfw, &oxfw->tx_stream); | ||
| 121 | |||
| 122 | fw_unit_put(oxfw->unit); | ||
| 123 | |||
| 112 | for (i = 0; i < SND_OXFW_STREAM_FORMAT_ENTRIES; i++) { | 124 | for (i = 0; i < SND_OXFW_STREAM_FORMAT_ENTRIES; i++) { |
| 113 | kfree(oxfw->tx_stream_formats[i]); | 125 | kfree(oxfw->tx_stream_formats[i]); |
| 114 | kfree(oxfw->rx_stream_formats[i]); | 126 | kfree(oxfw->rx_stream_formats[i]); |
| @@ -136,7 +148,7 @@ static int oxfw_probe(struct fw_unit *unit, | |||
| 136 | oxfw = card->private_data; | 148 | oxfw = card->private_data; |
| 137 | oxfw->card = card; | 149 | oxfw->card = card; |
| 138 | mutex_init(&oxfw->mutex); | 150 | mutex_init(&oxfw->mutex); |
| 139 | oxfw->unit = unit; | 151 | oxfw->unit = fw_unit_get(unit); |
| 140 | oxfw->device_info = (const struct device_info *)id->driver_data; | 152 | oxfw->device_info = (const struct device_info *)id->driver_data; |
| 141 | spin_lock_init(&oxfw->lock); | 153 | spin_lock_init(&oxfw->lock); |
| 142 | init_waitqueue_head(&oxfw->hwdep_wait); | 154 | init_waitqueue_head(&oxfw->hwdep_wait); |
| @@ -212,12 +224,7 @@ static void oxfw_remove(struct fw_unit *unit) | |||
| 212 | { | 224 | { |
| 213 | struct snd_oxfw *oxfw = dev_get_drvdata(&unit->device); | 225 | struct snd_oxfw *oxfw = dev_get_drvdata(&unit->device); |
| 214 | 226 | ||
| 215 | snd_card_disconnect(oxfw->card); | 227 | /* No need to wait for releasing card object in this context. */ |
| 216 | |||
| 217 | snd_oxfw_stream_destroy_simplex(oxfw, &oxfw->rx_stream); | ||
| 218 | if (oxfw->has_output) | ||
| 219 | snd_oxfw_stream_destroy_simplex(oxfw, &oxfw->tx_stream); | ||
| 220 | |||
| 221 | snd_card_free_when_closed(oxfw->card); | 228 | snd_card_free_when_closed(oxfw->card); |
| 222 | } | 229 | } |
| 223 | 230 | ||
diff --git a/sound/pci/hda/hda_controller.c b/sound/pci/hda/hda_controller.c index dfcb5e929f9f..a2ce773bdc62 100644 --- a/sound/pci/hda/hda_controller.c +++ b/sound/pci/hda/hda_controller.c | |||
| @@ -961,7 +961,6 @@ static int azx_alloc_cmd_io(struct azx *chip) | |||
| 961 | dev_err(chip->card->dev, "cannot allocate CORB/RIRB\n"); | 961 | dev_err(chip->card->dev, "cannot allocate CORB/RIRB\n"); |
| 962 | return err; | 962 | return err; |
| 963 | } | 963 | } |
| 964 | EXPORT_SYMBOL_GPL(azx_alloc_cmd_io); | ||
| 965 | 964 | ||
| 966 | static void azx_init_cmd_io(struct azx *chip) | 965 | static void azx_init_cmd_io(struct azx *chip) |
| 967 | { | 966 | { |
| @@ -1026,7 +1025,6 @@ static void azx_init_cmd_io(struct azx *chip) | |||
| 1026 | azx_writeb(chip, RIRBCTL, AZX_RBCTL_DMA_EN | AZX_RBCTL_IRQ_EN); | 1025 | azx_writeb(chip, RIRBCTL, AZX_RBCTL_DMA_EN | AZX_RBCTL_IRQ_EN); |
| 1027 | spin_unlock_irq(&chip->reg_lock); | 1026 | spin_unlock_irq(&chip->reg_lock); |
| 1028 | } | 1027 | } |
| 1029 | EXPORT_SYMBOL_GPL(azx_init_cmd_io); | ||
| 1030 | 1028 | ||
| 1031 | static void azx_free_cmd_io(struct azx *chip) | 1029 | static void azx_free_cmd_io(struct azx *chip) |
| 1032 | { | 1030 | { |
| @@ -1036,7 +1034,6 @@ static void azx_free_cmd_io(struct azx *chip) | |||
| 1036 | azx_writeb(chip, CORBCTL, 0); | 1034 | azx_writeb(chip, CORBCTL, 0); |
| 1037 | spin_unlock_irq(&chip->reg_lock); | 1035 | spin_unlock_irq(&chip->reg_lock); |
| 1038 | } | 1036 | } |
| 1039 | EXPORT_SYMBOL_GPL(azx_free_cmd_io); | ||
| 1040 | 1037 | ||
| 1041 | static unsigned int azx_command_addr(u32 cmd) | 1038 | static unsigned int azx_command_addr(u32 cmd) |
| 1042 | { | 1039 | { |
| @@ -1316,7 +1313,6 @@ static int azx_send_cmd(struct hda_bus *bus, unsigned int val) | |||
| 1316 | else | 1313 | else |
| 1317 | return azx_corb_send_cmd(bus, val); | 1314 | return azx_corb_send_cmd(bus, val); |
| 1318 | } | 1315 | } |
| 1319 | EXPORT_SYMBOL_GPL(azx_send_cmd); | ||
| 1320 | 1316 | ||
| 1321 | /* get a response */ | 1317 | /* get a response */ |
| 1322 | static unsigned int azx_get_response(struct hda_bus *bus, | 1318 | static unsigned int azx_get_response(struct hda_bus *bus, |
| @@ -1330,7 +1326,6 @@ static unsigned int azx_get_response(struct hda_bus *bus, | |||
| 1330 | else | 1326 | else |
| 1331 | return azx_rirb_get_response(bus, addr); | 1327 | return azx_rirb_get_response(bus, addr); |
| 1332 | } | 1328 | } |
| 1333 | EXPORT_SYMBOL_GPL(azx_get_response); | ||
| 1334 | 1329 | ||
| 1335 | #ifdef CONFIG_SND_HDA_DSP_LOADER | 1330 | #ifdef CONFIG_SND_HDA_DSP_LOADER |
| 1336 | /* | 1331 | /* |
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 36d2f20db7a4..4ca3d5d02436 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
| @@ -1966,7 +1966,7 @@ static const struct pci_device_id azx_ids[] = { | |||
| 1966 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH_NOPM }, | 1966 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH_NOPM }, |
| 1967 | /* Panther Point */ | 1967 | /* Panther Point */ |
| 1968 | { PCI_DEVICE(0x8086, 0x1e20), | 1968 | { PCI_DEVICE(0x8086, 0x1e20), |
| 1969 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH }, | 1969 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH_NOPM }, |
| 1970 | /* Lynx Point */ | 1970 | /* Lynx Point */ |
| 1971 | { PCI_DEVICE(0x8086, 0x8c20), | 1971 | { PCI_DEVICE(0x8086, 0x8c20), |
| 1972 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH }, | 1972 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH }, |
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 6d36c5b78805..87eff3173ce9 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
| @@ -79,6 +79,7 @@ enum { | |||
| 79 | STAC_ALIENWARE_M17X, | 79 | STAC_ALIENWARE_M17X, |
| 80 | STAC_92HD89XX_HP_FRONT_JACK, | 80 | STAC_92HD89XX_HP_FRONT_JACK, |
| 81 | STAC_92HD89XX_HP_Z1_G2_RIGHT_MIC_JACK, | 81 | STAC_92HD89XX_HP_Z1_G2_RIGHT_MIC_JACK, |
| 82 | STAC_92HD73XX_ASUS_MOBO, | ||
| 82 | STAC_92HD73XX_MODELS | 83 | STAC_92HD73XX_MODELS |
| 83 | }; | 84 | }; |
| 84 | 85 | ||
| @@ -1911,7 +1912,18 @@ static const struct hda_fixup stac92hd73xx_fixups[] = { | |||
| 1911 | [STAC_92HD89XX_HP_Z1_G2_RIGHT_MIC_JACK] = { | 1912 | [STAC_92HD89XX_HP_Z1_G2_RIGHT_MIC_JACK] = { |
| 1912 | .type = HDA_FIXUP_PINS, | 1913 | .type = HDA_FIXUP_PINS, |
| 1913 | .v.pins = stac92hd89xx_hp_z1_g2_right_mic_jack_pin_configs, | 1914 | .v.pins = stac92hd89xx_hp_z1_g2_right_mic_jack_pin_configs, |
| 1914 | } | 1915 | }, |
| 1916 | [STAC_92HD73XX_ASUS_MOBO] = { | ||
| 1917 | .type = HDA_FIXUP_PINS, | ||
| 1918 | .v.pins = (const struct hda_pintbl[]) { | ||
| 1919 | /* enable 5.1 and SPDIF out */ | ||
| 1920 | { 0x0c, 0x01014411 }, | ||
| 1921 | { 0x0d, 0x01014410 }, | ||
| 1922 | { 0x0e, 0x01014412 }, | ||
| 1923 | { 0x22, 0x014b1180 }, | ||
| 1924 | { } | ||
| 1925 | } | ||
| 1926 | }, | ||
| 1915 | }; | 1927 | }; |
| 1916 | 1928 | ||
| 1917 | static const struct hda_model_fixup stac92hd73xx_models[] = { | 1929 | static const struct hda_model_fixup stac92hd73xx_models[] = { |
| @@ -1923,6 +1935,7 @@ static const struct hda_model_fixup stac92hd73xx_models[] = { | |||
| 1923 | { .id = STAC_DELL_M6_BOTH, .name = "dell-m6" }, | 1935 | { .id = STAC_DELL_M6_BOTH, .name = "dell-m6" }, |
| 1924 | { .id = STAC_DELL_EQ, .name = "dell-eq" }, | 1936 | { .id = STAC_DELL_EQ, .name = "dell-eq" }, |
| 1925 | { .id = STAC_ALIENWARE_M17X, .name = "alienware" }, | 1937 | { .id = STAC_ALIENWARE_M17X, .name = "alienware" }, |
| 1938 | { .id = STAC_92HD73XX_ASUS_MOBO, .name = "asus-mobo" }, | ||
| 1926 | {} | 1939 | {} |
| 1927 | }; | 1940 | }; |
| 1928 | 1941 | ||
| @@ -1975,6 +1988,8 @@ static const struct snd_pci_quirk stac92hd73xx_fixup_tbl[] = { | |||
| 1975 | "HP Z1 G2", STAC_92HD89XX_HP_Z1_G2_RIGHT_MIC_JACK), | 1988 | "HP Z1 G2", STAC_92HD89XX_HP_Z1_G2_RIGHT_MIC_JACK), |
| 1976 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x2b17, | 1989 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x2b17, |
| 1977 | "unknown HP", STAC_92HD89XX_HP_FRONT_JACK), | 1990 | "unknown HP", STAC_92HD89XX_HP_FRONT_JACK), |
| 1991 | SND_PCI_QUIRK(PCI_VENDOR_ID_ASUSTEK, 0x83f8, "ASUS AT4NM10", | ||
| 1992 | STAC_92HD73XX_ASUS_MOBO), | ||
| 1978 | {} /* terminator */ | 1993 | {} /* terminator */ |
| 1979 | }; | 1994 | }; |
| 1980 | 1995 | ||
