diff options
184 files changed, 1918 insertions, 804 deletions
diff --git a/.clang-format b/.clang-format index f49620f506f1..f3923a1f9858 100644 --- a/.clang-format +++ b/.clang-format | |||
| @@ -78,6 +78,8 @@ ForEachMacros: | |||
| 78 | - 'ata_qc_for_each_with_internal' | 78 | - 'ata_qc_for_each_with_internal' |
| 79 | - 'ax25_for_each' | 79 | - 'ax25_for_each' |
| 80 | - 'ax25_uid_for_each' | 80 | - 'ax25_uid_for_each' |
| 81 | - '__bio_for_each_bvec' | ||
| 82 | - 'bio_for_each_bvec' | ||
| 81 | - 'bio_for_each_integrity_vec' | 83 | - 'bio_for_each_integrity_vec' |
| 82 | - '__bio_for_each_segment' | 84 | - '__bio_for_each_segment' |
| 83 | - 'bio_for_each_segment' | 85 | - 'bio_for_each_segment' |
| @@ -118,10 +120,12 @@ ForEachMacros: | |||
| 118 | - 'drm_for_each_legacy_plane' | 120 | - 'drm_for_each_legacy_plane' |
| 119 | - 'drm_for_each_plane' | 121 | - 'drm_for_each_plane' |
| 120 | - 'drm_for_each_plane_mask' | 122 | - 'drm_for_each_plane_mask' |
| 123 | - 'drm_for_each_privobj' | ||
| 121 | - 'drm_mm_for_each_hole' | 124 | - 'drm_mm_for_each_hole' |
| 122 | - 'drm_mm_for_each_node' | 125 | - 'drm_mm_for_each_node' |
| 123 | - 'drm_mm_for_each_node_in_range' | 126 | - 'drm_mm_for_each_node_in_range' |
| 124 | - 'drm_mm_for_each_node_safe' | 127 | - 'drm_mm_for_each_node_safe' |
| 128 | - 'flow_action_for_each' | ||
| 125 | - 'for_each_active_drhd_unit' | 129 | - 'for_each_active_drhd_unit' |
| 126 | - 'for_each_active_iommu' | 130 | - 'for_each_active_iommu' |
| 127 | - 'for_each_available_child_of_node' | 131 | - 'for_each_available_child_of_node' |
| @@ -158,6 +162,9 @@ ForEachMacros: | |||
| 158 | - 'for_each_dss_dev' | 162 | - 'for_each_dss_dev' |
| 159 | - 'for_each_efi_memory_desc' | 163 | - 'for_each_efi_memory_desc' |
| 160 | - 'for_each_efi_memory_desc_in_map' | 164 | - 'for_each_efi_memory_desc_in_map' |
| 165 | - 'for_each_element' | ||
| 166 | - 'for_each_element_extid' | ||
| 167 | - 'for_each_element_id' | ||
| 161 | - 'for_each_endpoint_of_node' | 168 | - 'for_each_endpoint_of_node' |
| 162 | - 'for_each_evictable_lru' | 169 | - 'for_each_evictable_lru' |
| 163 | - 'for_each_fib6_node_rt_rcu' | 170 | - 'for_each_fib6_node_rt_rcu' |
| @@ -195,6 +202,7 @@ ForEachMacros: | |||
| 195 | - 'for_each_net_rcu' | 202 | - 'for_each_net_rcu' |
| 196 | - 'for_each_new_connector_in_state' | 203 | - 'for_each_new_connector_in_state' |
| 197 | - 'for_each_new_crtc_in_state' | 204 | - 'for_each_new_crtc_in_state' |
| 205 | - 'for_each_new_mst_mgr_in_state' | ||
| 198 | - 'for_each_new_plane_in_state' | 206 | - 'for_each_new_plane_in_state' |
| 199 | - 'for_each_new_private_obj_in_state' | 207 | - 'for_each_new_private_obj_in_state' |
| 200 | - 'for_each_node' | 208 | - 'for_each_node' |
| @@ -210,8 +218,10 @@ ForEachMacros: | |||
| 210 | - 'for_each_of_pci_range' | 218 | - 'for_each_of_pci_range' |
| 211 | - 'for_each_old_connector_in_state' | 219 | - 'for_each_old_connector_in_state' |
| 212 | - 'for_each_old_crtc_in_state' | 220 | - 'for_each_old_crtc_in_state' |
| 221 | - 'for_each_old_mst_mgr_in_state' | ||
| 213 | - 'for_each_oldnew_connector_in_state' | 222 | - 'for_each_oldnew_connector_in_state' |
| 214 | - 'for_each_oldnew_crtc_in_state' | 223 | - 'for_each_oldnew_crtc_in_state' |
| 224 | - 'for_each_oldnew_mst_mgr_in_state' | ||
| 215 | - 'for_each_oldnew_plane_in_state' | 225 | - 'for_each_oldnew_plane_in_state' |
| 216 | - 'for_each_oldnew_plane_in_state_reverse' | 226 | - 'for_each_oldnew_plane_in_state_reverse' |
| 217 | - 'for_each_oldnew_private_obj_in_state' | 227 | - 'for_each_oldnew_private_obj_in_state' |
| @@ -243,6 +253,9 @@ ForEachMacros: | |||
| 243 | - 'for_each_sg_dma_page' | 253 | - 'for_each_sg_dma_page' |
| 244 | - 'for_each_sg_page' | 254 | - 'for_each_sg_page' |
| 245 | - 'for_each_sibling_event' | 255 | - 'for_each_sibling_event' |
| 256 | - 'for_each_subelement' | ||
| 257 | - 'for_each_subelement_extid' | ||
| 258 | - 'for_each_subelement_id' | ||
| 246 | - '__for_each_thread' | 259 | - '__for_each_thread' |
| 247 | - 'for_each_thread' | 260 | - 'for_each_thread' |
| 248 | - 'for_each_zone' | 261 | - 'for_each_zone' |
| @@ -252,6 +265,8 @@ ForEachMacros: | |||
| 252 | - 'fwnode_for_each_child_node' | 265 | - 'fwnode_for_each_child_node' |
| 253 | - 'fwnode_graph_for_each_endpoint' | 266 | - 'fwnode_graph_for_each_endpoint' |
| 254 | - 'gadget_for_each_ep' | 267 | - 'gadget_for_each_ep' |
| 268 | - 'genradix_for_each' | ||
| 269 | - 'genradix_for_each_from' | ||
| 255 | - 'hash_for_each' | 270 | - 'hash_for_each' |
| 256 | - 'hash_for_each_possible' | 271 | - 'hash_for_each_possible' |
| 257 | - 'hash_for_each_possible_rcu' | 272 | - 'hash_for_each_possible_rcu' |
| @@ -293,7 +308,11 @@ ForEachMacros: | |||
| 293 | - 'key_for_each' | 308 | - 'key_for_each' |
| 294 | - 'key_for_each_safe' | 309 | - 'key_for_each_safe' |
| 295 | - 'klp_for_each_func' | 310 | - 'klp_for_each_func' |
| 311 | - 'klp_for_each_func_safe' | ||
| 312 | - 'klp_for_each_func_static' | ||
| 296 | - 'klp_for_each_object' | 313 | - 'klp_for_each_object' |
| 314 | - 'klp_for_each_object_safe' | ||
| 315 | - 'klp_for_each_object_static' | ||
| 297 | - 'kvm_for_each_memslot' | 316 | - 'kvm_for_each_memslot' |
| 298 | - 'kvm_for_each_vcpu' | 317 | - 'kvm_for_each_vcpu' |
| 299 | - 'list_for_each' | 318 | - 'list_for_each' |
| @@ -324,6 +343,8 @@ ForEachMacros: | |||
| 324 | - 'media_device_for_each_intf' | 343 | - 'media_device_for_each_intf' |
| 325 | - 'media_device_for_each_link' | 344 | - 'media_device_for_each_link' |
| 326 | - 'media_device_for_each_pad' | 345 | - 'media_device_for_each_pad' |
| 346 | - 'mp_bvec_for_each_page' | ||
| 347 | - 'mp_bvec_for_each_segment' | ||
| 327 | - 'nanddev_io_for_each_page' | 348 | - 'nanddev_io_for_each_page' |
| 328 | - 'netdev_for_each_lower_dev' | 349 | - 'netdev_for_each_lower_dev' |
| 329 | - 'netdev_for_each_lower_private' | 350 | - 'netdev_for_each_lower_private' |
| @@ -375,6 +396,7 @@ ForEachMacros: | |||
| 375 | - 'rht_for_each_rcu' | 396 | - 'rht_for_each_rcu' |
| 376 | - 'rht_for_each_rcu_continue' | 397 | - 'rht_for_each_rcu_continue' |
| 377 | - '__rq_for_each_bio' | 398 | - '__rq_for_each_bio' |
| 399 | - 'rq_for_each_bvec' | ||
| 378 | - 'rq_for_each_segment' | 400 | - 'rq_for_each_segment' |
| 379 | - 'scsi_for_each_prot_sg' | 401 | - 'scsi_for_each_prot_sg' |
| 380 | - 'scsi_for_each_sg' | 402 | - 'scsi_for_each_sg' |
| @@ -410,6 +432,8 @@ ForEachMacros: | |||
| 410 | - 'v4l2_m2m_for_each_src_buf_safe' | 432 | - 'v4l2_m2m_for_each_src_buf_safe' |
| 411 | - 'virtio_device_for_each_vq' | 433 | - 'virtio_device_for_each_vq' |
| 412 | - 'xa_for_each' | 434 | - 'xa_for_each' |
| 435 | - 'xa_for_each_marked' | ||
| 436 | - 'xa_for_each_start' | ||
| 413 | - 'xas_for_each' | 437 | - 'xas_for_each' |
| 414 | - 'xas_for_each_conflict' | 438 | - 'xas_for_each_conflict' |
| 415 | - 'xas_for_each_marked' | 439 | - 'xas_for_each_marked' |
diff --git a/MAINTAINERS b/MAINTAINERS index 2359e12e4c41..3671fdea5010 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
| @@ -7516,7 +7516,7 @@ F: include/net/mac802154.h | |||
| 7516 | F: include/net/af_ieee802154.h | 7516 | F: include/net/af_ieee802154.h |
| 7517 | F: include/net/cfg802154.h | 7517 | F: include/net/cfg802154.h |
| 7518 | F: include/net/ieee802154_netdev.h | 7518 | F: include/net/ieee802154_netdev.h |
| 7519 | F: Documentation/networking/ieee802154.txt | 7519 | F: Documentation/networking/ieee802154.rst |
| 7520 | 7520 | ||
| 7521 | IFE PROTOCOL | 7521 | IFE PROTOCOL |
| 7522 | M: Yotam Gigi <yotam.gi@gmail.com> | 7522 | M: Yotam Gigi <yotam.gi@gmail.com> |
| @@ -16509,7 +16509,7 @@ F: drivers/char/virtio_console.c | |||
| 16509 | F: include/linux/virtio_console.h | 16509 | F: include/linux/virtio_console.h |
| 16510 | F: include/uapi/linux/virtio_console.h | 16510 | F: include/uapi/linux/virtio_console.h |
| 16511 | 16511 | ||
| 16512 | VIRTIO CORE, NET AND BLOCK DRIVERS | 16512 | VIRTIO CORE AND NET DRIVERS |
| 16513 | M: "Michael S. Tsirkin" <mst@redhat.com> | 16513 | M: "Michael S. Tsirkin" <mst@redhat.com> |
| 16514 | M: Jason Wang <jasowang@redhat.com> | 16514 | M: Jason Wang <jasowang@redhat.com> |
| 16515 | L: virtualization@lists.linux-foundation.org | 16515 | L: virtualization@lists.linux-foundation.org |
| @@ -16524,6 +16524,19 @@ F: include/uapi/linux/virtio_*.h | |||
| 16524 | F: drivers/crypto/virtio/ | 16524 | F: drivers/crypto/virtio/ |
| 16525 | F: mm/balloon_compaction.c | 16525 | F: mm/balloon_compaction.c |
| 16526 | 16526 | ||
| 16527 | VIRTIO BLOCK AND SCSI DRIVERS | ||
| 16528 | M: "Michael S. Tsirkin" <mst@redhat.com> | ||
| 16529 | M: Jason Wang <jasowang@redhat.com> | ||
| 16530 | R: Paolo Bonzini <pbonzini@redhat.com> | ||
| 16531 | R: Stefan Hajnoczi <stefanha@redhat.com> | ||
| 16532 | L: virtualization@lists.linux-foundation.org | ||
| 16533 | S: Maintained | ||
| 16534 | F: drivers/block/virtio_blk.c | ||
| 16535 | F: drivers/scsi/virtio_scsi.c | ||
| 16536 | F: include/uapi/linux/virtio_blk.h | ||
| 16537 | F: include/uapi/linux/virtio_scsi.h | ||
| 16538 | F: drivers/vhost/scsi.c | ||
| 16539 | |||
| 16527 | VIRTIO CRYPTO DRIVER | 16540 | VIRTIO CRYPTO DRIVER |
| 16528 | M: Gonglei <arei.gonglei@huawei.com> | 16541 | M: Gonglei <arei.gonglei@huawei.com> |
| 16529 | L: virtualization@lists.linux-foundation.org | 16542 | L: virtualization@lists.linux-foundation.org |
diff --git a/arch/arm64/include/asm/futex.h b/arch/arm64/include/asm/futex.h index cccb83ad7fa8..e1d95f08f8e1 100644 --- a/arch/arm64/include/asm/futex.h +++ b/arch/arm64/include/asm/futex.h | |||
| @@ -30,8 +30,8 @@ do { \ | |||
| 30 | " prfm pstl1strm, %2\n" \ | 30 | " prfm pstl1strm, %2\n" \ |
| 31 | "1: ldxr %w1, %2\n" \ | 31 | "1: ldxr %w1, %2\n" \ |
| 32 | insn "\n" \ | 32 | insn "\n" \ |
| 33 | "2: stlxr %w3, %w0, %2\n" \ | 33 | "2: stlxr %w0, %w3, %2\n" \ |
| 34 | " cbnz %w3, 1b\n" \ | 34 | " cbnz %w0, 1b\n" \ |
| 35 | " dmb ish\n" \ | 35 | " dmb ish\n" \ |
| 36 | "3:\n" \ | 36 | "3:\n" \ |
| 37 | " .pushsection .fixup,\"ax\"\n" \ | 37 | " .pushsection .fixup,\"ax\"\n" \ |
| @@ -50,30 +50,30 @@ do { \ | |||
| 50 | static inline int | 50 | static inline int |
| 51 | arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *_uaddr) | 51 | arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *_uaddr) |
| 52 | { | 52 | { |
| 53 | int oldval = 0, ret, tmp; | 53 | int oldval, ret, tmp; |
| 54 | u32 __user *uaddr = __uaccess_mask_ptr(_uaddr); | 54 | u32 __user *uaddr = __uaccess_mask_ptr(_uaddr); |
| 55 | 55 | ||
| 56 | pagefault_disable(); | 56 | pagefault_disable(); |
| 57 | 57 | ||
| 58 | switch (op) { | 58 | switch (op) { |
| 59 | case FUTEX_OP_SET: | 59 | case FUTEX_OP_SET: |
| 60 | __futex_atomic_op("mov %w0, %w4", | 60 | __futex_atomic_op("mov %w3, %w4", |
| 61 | ret, oldval, uaddr, tmp, oparg); | 61 | ret, oldval, uaddr, tmp, oparg); |
| 62 | break; | 62 | break; |
| 63 | case FUTEX_OP_ADD: | 63 | case FUTEX_OP_ADD: |
| 64 | __futex_atomic_op("add %w0, %w1, %w4", | 64 | __futex_atomic_op("add %w3, %w1, %w4", |
| 65 | ret, oldval, uaddr, tmp, oparg); | 65 | ret, oldval, uaddr, tmp, oparg); |
| 66 | break; | 66 | break; |
| 67 | case FUTEX_OP_OR: | 67 | case FUTEX_OP_OR: |
| 68 | __futex_atomic_op("orr %w0, %w1, %w4", | 68 | __futex_atomic_op("orr %w3, %w1, %w4", |
| 69 | ret, oldval, uaddr, tmp, oparg); | 69 | ret, oldval, uaddr, tmp, oparg); |
| 70 | break; | 70 | break; |
| 71 | case FUTEX_OP_ANDN: | 71 | case FUTEX_OP_ANDN: |
| 72 | __futex_atomic_op("and %w0, %w1, %w4", | 72 | __futex_atomic_op("and %w3, %w1, %w4", |
| 73 | ret, oldval, uaddr, tmp, ~oparg); | 73 | ret, oldval, uaddr, tmp, ~oparg); |
| 74 | break; | 74 | break; |
| 75 | case FUTEX_OP_XOR: | 75 | case FUTEX_OP_XOR: |
| 76 | __futex_atomic_op("eor %w0, %w1, %w4", | 76 | __futex_atomic_op("eor %w3, %w1, %w4", |
| 77 | ret, oldval, uaddr, tmp, oparg); | 77 | ret, oldval, uaddr, tmp, oparg); |
| 78 | break; | 78 | break; |
| 79 | default: | 79 | default: |
diff --git a/arch/arm64/include/asm/module.h b/arch/arm64/include/asm/module.h index 905e1bb0e7bd..cd9f4e9d04d3 100644 --- a/arch/arm64/include/asm/module.h +++ b/arch/arm64/include/asm/module.h | |||
| @@ -73,4 +73,9 @@ static inline bool is_forbidden_offset_for_adrp(void *place) | |||
| 73 | struct plt_entry get_plt_entry(u64 dst, void *pc); | 73 | struct plt_entry get_plt_entry(u64 dst, void *pc); |
| 74 | bool plt_entries_equal(const struct plt_entry *a, const struct plt_entry *b); | 74 | bool plt_entries_equal(const struct plt_entry *a, const struct plt_entry *b); |
| 75 | 75 | ||
| 76 | static inline bool plt_entry_is_initialized(const struct plt_entry *e) | ||
| 77 | { | ||
| 78 | return e->adrp || e->add || e->br; | ||
| 79 | } | ||
| 80 | |||
| 76 | #endif /* __ASM_MODULE_H */ | 81 | #endif /* __ASM_MODULE_H */ |
diff --git a/arch/arm64/kernel/ftrace.c b/arch/arm64/kernel/ftrace.c index 8e4431a8821f..07b298120182 100644 --- a/arch/arm64/kernel/ftrace.c +++ b/arch/arm64/kernel/ftrace.c | |||
| @@ -107,8 +107,7 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) | |||
| 107 | trampoline = get_plt_entry(addr, mod->arch.ftrace_trampoline); | 107 | trampoline = get_plt_entry(addr, mod->arch.ftrace_trampoline); |
| 108 | if (!plt_entries_equal(mod->arch.ftrace_trampoline, | 108 | if (!plt_entries_equal(mod->arch.ftrace_trampoline, |
| 109 | &trampoline)) { | 109 | &trampoline)) { |
| 110 | if (!plt_entries_equal(mod->arch.ftrace_trampoline, | 110 | if (plt_entry_is_initialized(mod->arch.ftrace_trampoline)) { |
| 111 | &(struct plt_entry){})) { | ||
| 112 | pr_err("ftrace: far branches to multiple entry points unsupported inside a single module\n"); | 111 | pr_err("ftrace: far branches to multiple entry points unsupported inside a single module\n"); |
| 113 | return -EINVAL; | 112 | return -EINVAL; |
| 114 | } | 113 | } |
diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c index 8ad119c3f665..29755989f616 100644 --- a/arch/arm64/kernel/traps.c +++ b/arch/arm64/kernel/traps.c | |||
| @@ -102,10 +102,16 @@ static void dump_instr(const char *lvl, struct pt_regs *regs) | |||
| 102 | void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk) | 102 | void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk) |
| 103 | { | 103 | { |
| 104 | struct stackframe frame; | 104 | struct stackframe frame; |
| 105 | int skip; | 105 | int skip = 0; |
| 106 | 106 | ||
| 107 | pr_debug("%s(regs = %p tsk = %p)\n", __func__, regs, tsk); | 107 | pr_debug("%s(regs = %p tsk = %p)\n", __func__, regs, tsk); |
| 108 | 108 | ||
| 109 | if (regs) { | ||
| 110 | if (user_mode(regs)) | ||
| 111 | return; | ||
| 112 | skip = 1; | ||
| 113 | } | ||
| 114 | |||
| 109 | if (!tsk) | 115 | if (!tsk) |
| 110 | tsk = current; | 116 | tsk = current; |
| 111 | 117 | ||
| @@ -126,7 +132,6 @@ void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk) | |||
| 126 | frame.graph = 0; | 132 | frame.graph = 0; |
| 127 | #endif | 133 | #endif |
| 128 | 134 | ||
| 129 | skip = !!regs; | ||
| 130 | printk("Call trace:\n"); | 135 | printk("Call trace:\n"); |
| 131 | do { | 136 | do { |
| 132 | /* skip until specified stack frame */ | 137 | /* skip until specified stack frame */ |
| @@ -176,15 +181,13 @@ static int __die(const char *str, int err, struct pt_regs *regs) | |||
| 176 | return ret; | 181 | return ret; |
| 177 | 182 | ||
| 178 | print_modules(); | 183 | print_modules(); |
| 179 | __show_regs(regs); | ||
| 180 | pr_emerg("Process %.*s (pid: %d, stack limit = 0x%p)\n", | 184 | pr_emerg("Process %.*s (pid: %d, stack limit = 0x%p)\n", |
| 181 | TASK_COMM_LEN, tsk->comm, task_pid_nr(tsk), | 185 | TASK_COMM_LEN, tsk->comm, task_pid_nr(tsk), |
| 182 | end_of_stack(tsk)); | 186 | end_of_stack(tsk)); |
| 187 | show_regs(regs); | ||
| 183 | 188 | ||
| 184 | if (!user_mode(regs)) { | 189 | if (!user_mode(regs)) |
| 185 | dump_backtrace(regs, tsk); | ||
| 186 | dump_instr(KERN_EMERG, regs); | 190 | dump_instr(KERN_EMERG, regs); |
| 187 | } | ||
| 188 | 191 | ||
| 189 | return ret; | 192 | return ret; |
| 190 | } | 193 | } |
diff --git a/arch/mips/configs/generic/board-ocelot.config b/arch/mips/configs/generic/board-ocelot.config index f607888d2483..184eb65a6ba7 100644 --- a/arch/mips/configs/generic/board-ocelot.config +++ b/arch/mips/configs/generic/board-ocelot.config | |||
| @@ -1,6 +1,10 @@ | |||
| 1 | # require CONFIG_CPU_MIPS32_R2=y | 1 | # require CONFIG_CPU_MIPS32_R2=y |
| 2 | 2 | ||
| 3 | CONFIG_LEGACY_BOARD_OCELOT=y | 3 | CONFIG_LEGACY_BOARD_OCELOT=y |
| 4 | CONFIG_FIT_IMAGE_FDT_OCELOT=y | ||
| 5 | |||
| 6 | CONFIG_BRIDGE=y | ||
| 7 | CONFIG_GENERIC_PHY=y | ||
| 4 | 8 | ||
| 5 | CONFIG_MTD=y | 9 | CONFIG_MTD=y |
| 6 | CONFIG_MTD_CMDLINE_PARTS=y | 10 | CONFIG_MTD_CMDLINE_PARTS=y |
| @@ -19,6 +23,8 @@ CONFIG_SERIAL_8250_CONSOLE=y | |||
| 19 | CONFIG_SERIAL_OF_PLATFORM=y | 23 | CONFIG_SERIAL_OF_PLATFORM=y |
| 20 | 24 | ||
| 21 | CONFIG_NETDEVICES=y | 25 | CONFIG_NETDEVICES=y |
| 26 | CONFIG_NET_SWITCHDEV=y | ||
| 27 | CONFIG_NET_DSA=y | ||
| 22 | CONFIG_MSCC_OCELOT_SWITCH=y | 28 | CONFIG_MSCC_OCELOT_SWITCH=y |
| 23 | CONFIG_MSCC_OCELOT_SWITCH_OCELOT=y | 29 | CONFIG_MSCC_OCELOT_SWITCH_OCELOT=y |
| 24 | CONFIG_MDIO_MSCC_MIIM=y | 30 | CONFIG_MDIO_MSCC_MIIM=y |
| @@ -35,6 +41,8 @@ CONFIG_SPI_DESIGNWARE=y | |||
| 35 | CONFIG_SPI_DW_MMIO=y | 41 | CONFIG_SPI_DW_MMIO=y |
| 36 | CONFIG_SPI_SPIDEV=y | 42 | CONFIG_SPI_SPIDEV=y |
| 37 | 43 | ||
| 44 | CONFIG_PINCTRL_OCELOT=y | ||
| 45 | |||
| 38 | CONFIG_GPIO_SYSFS=y | 46 | CONFIG_GPIO_SYSFS=y |
| 39 | 47 | ||
| 40 | CONFIG_POWER_RESET=y | 48 | CONFIG_POWER_RESET=y |
diff --git a/arch/mips/kernel/kgdb.c b/arch/mips/kernel/kgdb.c index 6e574c02e4c3..ea781b29f7f1 100644 --- a/arch/mips/kernel/kgdb.c +++ b/arch/mips/kernel/kgdb.c | |||
| @@ -33,6 +33,7 @@ | |||
| 33 | #include <asm/processor.h> | 33 | #include <asm/processor.h> |
| 34 | #include <asm/sigcontext.h> | 34 | #include <asm/sigcontext.h> |
| 35 | #include <linux/uaccess.h> | 35 | #include <linux/uaccess.h> |
| 36 | #include <asm/irq_regs.h> | ||
| 36 | 37 | ||
| 37 | static struct hard_trap_info { | 38 | static struct hard_trap_info { |
| 38 | unsigned char tt; /* Trap type code for MIPS R3xxx and R4xxx */ | 39 | unsigned char tt; /* Trap type code for MIPS R3xxx and R4xxx */ |
| @@ -214,7 +215,7 @@ void kgdb_call_nmi_hook(void *ignored) | |||
| 214 | old_fs = get_fs(); | 215 | old_fs = get_fs(); |
| 215 | set_fs(KERNEL_DS); | 216 | set_fs(KERNEL_DS); |
| 216 | 217 | ||
| 217 | kgdb_nmicallback(raw_smp_processor_id(), NULL); | 218 | kgdb_nmicallback(raw_smp_processor_id(), get_irq_regs()); |
| 218 | 219 | ||
| 219 | set_fs(old_fs); | 220 | set_fs(old_fs); |
| 220 | } | 221 | } |
diff --git a/arch/mips/sgi-ip27/ip27-irq.c b/arch/mips/sgi-ip27/ip27-irq.c index 710a59764b01..a32f843cdbe0 100644 --- a/arch/mips/sgi-ip27/ip27-irq.c +++ b/arch/mips/sgi-ip27/ip27-irq.c | |||
| @@ -118,7 +118,6 @@ static void shutdown_bridge_irq(struct irq_data *d) | |||
| 118 | { | 118 | { |
| 119 | struct hub_irq_data *hd = irq_data_get_irq_chip_data(d); | 119 | struct hub_irq_data *hd = irq_data_get_irq_chip_data(d); |
| 120 | struct bridge_controller *bc; | 120 | struct bridge_controller *bc; |
| 121 | int pin = hd->pin; | ||
| 122 | 121 | ||
| 123 | if (!hd) | 122 | if (!hd) |
| 124 | return; | 123 | return; |
| @@ -126,7 +125,7 @@ static void shutdown_bridge_irq(struct irq_data *d) | |||
| 126 | disable_hub_irq(d); | 125 | disable_hub_irq(d); |
| 127 | 126 | ||
| 128 | bc = hd->bc; | 127 | bc = hd->bc; |
| 129 | bridge_clr(bc, b_int_enable, (1 << pin)); | 128 | bridge_clr(bc, b_int_enable, (1 << hd->pin)); |
| 130 | bridge_read(bc, b_wid_tflush); | 129 | bridge_read(bc, b_wid_tflush); |
| 131 | } | 130 | } |
| 132 | 131 | ||
diff --git a/arch/powerpc/include/asm/mmu.h b/arch/powerpc/include/asm/mmu.h index 598cdcdd1355..8ddd4a91bdc1 100644 --- a/arch/powerpc/include/asm/mmu.h +++ b/arch/powerpc/include/asm/mmu.h | |||
| @@ -352,7 +352,7 @@ static inline bool strict_kernel_rwx_enabled(void) | |||
| 352 | #if defined(CONFIG_SPARSEMEM_VMEMMAP) && defined(CONFIG_SPARSEMEM_EXTREME) && \ | 352 | #if defined(CONFIG_SPARSEMEM_VMEMMAP) && defined(CONFIG_SPARSEMEM_EXTREME) && \ |
| 353 | defined (CONFIG_PPC_64K_PAGES) | 353 | defined (CONFIG_PPC_64K_PAGES) |
| 354 | #define MAX_PHYSMEM_BITS 51 | 354 | #define MAX_PHYSMEM_BITS 51 |
| 355 | #elif defined(CONFIG_SPARSEMEM) | 355 | #elif defined(CONFIG_PPC64) |
| 356 | #define MAX_PHYSMEM_BITS 46 | 356 | #define MAX_PHYSMEM_BITS 46 |
| 357 | #endif | 357 | #endif |
| 358 | 358 | ||
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index a5b8fbae56a0..9481a117e242 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S | |||
| @@ -656,11 +656,17 @@ EXC_COMMON_BEGIN(data_access_slb_common) | |||
| 656 | ld r4,PACA_EXSLB+EX_DAR(r13) | 656 | ld r4,PACA_EXSLB+EX_DAR(r13) |
| 657 | std r4,_DAR(r1) | 657 | std r4,_DAR(r1) |
| 658 | addi r3,r1,STACK_FRAME_OVERHEAD | 658 | addi r3,r1,STACK_FRAME_OVERHEAD |
| 659 | BEGIN_MMU_FTR_SECTION | ||
| 660 | /* HPT case, do SLB fault */ | ||
| 659 | bl do_slb_fault | 661 | bl do_slb_fault |
| 660 | cmpdi r3,0 | 662 | cmpdi r3,0 |
| 661 | bne- 1f | 663 | bne- 1f |
| 662 | b fast_exception_return | 664 | b fast_exception_return |
| 663 | 1: /* Error case */ | 665 | 1: /* Error case */ |
| 666 | MMU_FTR_SECTION_ELSE | ||
| 667 | /* Radix case, access is outside page table range */ | ||
| 668 | li r3,-EFAULT | ||
| 669 | ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_TYPE_RADIX) | ||
| 664 | std r3,RESULT(r1) | 670 | std r3,RESULT(r1) |
| 665 | bl save_nvgprs | 671 | bl save_nvgprs |
| 666 | RECONCILE_IRQ_STATE(r10, r11) | 672 | RECONCILE_IRQ_STATE(r10, r11) |
| @@ -705,11 +711,17 @@ EXC_COMMON_BEGIN(instruction_access_slb_common) | |||
| 705 | EXCEPTION_PROLOG_COMMON(0x480, PACA_EXSLB) | 711 | EXCEPTION_PROLOG_COMMON(0x480, PACA_EXSLB) |
| 706 | ld r4,_NIP(r1) | 712 | ld r4,_NIP(r1) |
| 707 | addi r3,r1,STACK_FRAME_OVERHEAD | 713 | addi r3,r1,STACK_FRAME_OVERHEAD |
| 714 | BEGIN_MMU_FTR_SECTION | ||
| 715 | /* HPT case, do SLB fault */ | ||
| 708 | bl do_slb_fault | 716 | bl do_slb_fault |
| 709 | cmpdi r3,0 | 717 | cmpdi r3,0 |
| 710 | bne- 1f | 718 | bne- 1f |
| 711 | b fast_exception_return | 719 | b fast_exception_return |
| 712 | 1: /* Error case */ | 720 | 1: /* Error case */ |
| 721 | MMU_FTR_SECTION_ELSE | ||
| 722 | /* Radix case, access is outside page table range */ | ||
| 723 | li r3,-EFAULT | ||
| 724 | ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_TYPE_RADIX) | ||
| 713 | std r3,RESULT(r1) | 725 | std r3,RESULT(r1) |
| 714 | bl save_nvgprs | 726 | bl save_nvgprs |
| 715 | RECONCILE_IRQ_STATE(r10, r11) | 727 | RECONCILE_IRQ_STATE(r10, r11) |
diff --git a/arch/powerpc/kernel/head_32.S b/arch/powerpc/kernel/head_32.S index 48051c8977c5..e25b615e9f9e 100644 --- a/arch/powerpc/kernel/head_32.S +++ b/arch/powerpc/kernel/head_32.S | |||
| @@ -851,10 +851,6 @@ __secondary_start: | |||
| 851 | tophys(r4,r2) | 851 | tophys(r4,r2) |
| 852 | addi r4,r4,THREAD /* phys address of our thread_struct */ | 852 | addi r4,r4,THREAD /* phys address of our thread_struct */ |
| 853 | mtspr SPRN_SPRG_THREAD,r4 | 853 | mtspr SPRN_SPRG_THREAD,r4 |
| 854 | #ifdef CONFIG_PPC_RTAS | ||
| 855 | li r3,0 | ||
| 856 | stw r3, RTAS_SP(r4) /* 0 => not in RTAS */ | ||
| 857 | #endif | ||
| 858 | lis r4, (swapper_pg_dir - PAGE_OFFSET)@h | 854 | lis r4, (swapper_pg_dir - PAGE_OFFSET)@h |
| 859 | ori r4, r4, (swapper_pg_dir - PAGE_OFFSET)@l | 855 | ori r4, r4, (swapper_pg_dir - PAGE_OFFSET)@l |
| 860 | mtspr SPRN_SPRG_PGDIR, r4 | 856 | mtspr SPRN_SPRG_PGDIR, r4 |
| @@ -941,10 +937,6 @@ start_here: | |||
| 941 | tophys(r4,r2) | 937 | tophys(r4,r2) |
| 942 | addi r4,r4,THREAD /* init task's THREAD */ | 938 | addi r4,r4,THREAD /* init task's THREAD */ |
| 943 | mtspr SPRN_SPRG_THREAD,r4 | 939 | mtspr SPRN_SPRG_THREAD,r4 |
| 944 | #ifdef CONFIG_PPC_RTAS | ||
| 945 | li r3,0 | ||
| 946 | stw r3, RTAS_SP(r4) /* 0 => not in RTAS */ | ||
| 947 | #endif | ||
| 948 | lis r4, (swapper_pg_dir - PAGE_OFFSET)@h | 940 | lis r4, (swapper_pg_dir - PAGE_OFFSET)@h |
| 949 | ori r4, r4, (swapper_pg_dir - PAGE_OFFSET)@l | 941 | ori r4, r4, (swapper_pg_dir - PAGE_OFFSET)@l |
| 950 | mtspr SPRN_SPRG_PGDIR, r4 | 942 | mtspr SPRN_SPRG_PGDIR, r4 |
diff --git a/arch/powerpc/kernel/vdso32/gettimeofday.S b/arch/powerpc/kernel/vdso32/gettimeofday.S index 1e0bc5955a40..afd516b572f8 100644 --- a/arch/powerpc/kernel/vdso32/gettimeofday.S +++ b/arch/powerpc/kernel/vdso32/gettimeofday.S | |||
| @@ -98,7 +98,7 @@ V_FUNCTION_BEGIN(__kernel_clock_gettime) | |||
| 98 | * can be used, r7 contains NSEC_PER_SEC. | 98 | * can be used, r7 contains NSEC_PER_SEC. |
| 99 | */ | 99 | */ |
| 100 | 100 | ||
| 101 | lwz r5,WTOM_CLOCK_SEC(r9) | 101 | lwz r5,(WTOM_CLOCK_SEC+LOPART)(r9) |
| 102 | lwz r6,WTOM_CLOCK_NSEC(r9) | 102 | lwz r6,WTOM_CLOCK_NSEC(r9) |
| 103 | 103 | ||
| 104 | /* We now have our offset in r5,r6. We create a fake dependency | 104 | /* We now have our offset in r5,r6. We create a fake dependency |
diff --git a/arch/sparc/kernel/pci_sun4v.c b/arch/sparc/kernel/pci_sun4v.c index a8af6023c126..14b93c5564e3 100644 --- a/arch/sparc/kernel/pci_sun4v.c +++ b/arch/sparc/kernel/pci_sun4v.c | |||
| @@ -73,6 +73,11 @@ static inline void iommu_batch_start(struct device *dev, unsigned long prot, uns | |||
| 73 | p->npages = 0; | 73 | p->npages = 0; |
| 74 | } | 74 | } |
| 75 | 75 | ||
| 76 | static inline bool iommu_use_atu(struct iommu *iommu, u64 mask) | ||
| 77 | { | ||
| 78 | return iommu->atu && mask > DMA_BIT_MASK(32); | ||
| 79 | } | ||
| 80 | |||
| 76 | /* Interrupts must be disabled. */ | 81 | /* Interrupts must be disabled. */ |
| 77 | static long iommu_batch_flush(struct iommu_batch *p, u64 mask) | 82 | static long iommu_batch_flush(struct iommu_batch *p, u64 mask) |
| 78 | { | 83 | { |
| @@ -92,7 +97,7 @@ static long iommu_batch_flush(struct iommu_batch *p, u64 mask) | |||
| 92 | prot &= (HV_PCI_MAP_ATTR_READ | HV_PCI_MAP_ATTR_WRITE); | 97 | prot &= (HV_PCI_MAP_ATTR_READ | HV_PCI_MAP_ATTR_WRITE); |
| 93 | 98 | ||
| 94 | while (npages != 0) { | 99 | while (npages != 0) { |
| 95 | if (mask <= DMA_BIT_MASK(32) || !pbm->iommu->atu) { | 100 | if (!iommu_use_atu(pbm->iommu, mask)) { |
| 96 | num = pci_sun4v_iommu_map(devhandle, | 101 | num = pci_sun4v_iommu_map(devhandle, |
| 97 | HV_PCI_TSBID(0, entry), | 102 | HV_PCI_TSBID(0, entry), |
| 98 | npages, | 103 | npages, |
| @@ -179,7 +184,6 @@ static void *dma_4v_alloc_coherent(struct device *dev, size_t size, | |||
| 179 | unsigned long flags, order, first_page, npages, n; | 184 | unsigned long flags, order, first_page, npages, n; |
| 180 | unsigned long prot = 0; | 185 | unsigned long prot = 0; |
| 181 | struct iommu *iommu; | 186 | struct iommu *iommu; |
| 182 | struct atu *atu; | ||
| 183 | struct iommu_map_table *tbl; | 187 | struct iommu_map_table *tbl; |
| 184 | struct page *page; | 188 | struct page *page; |
| 185 | void *ret; | 189 | void *ret; |
| @@ -205,13 +209,11 @@ static void *dma_4v_alloc_coherent(struct device *dev, size_t size, | |||
| 205 | memset((char *)first_page, 0, PAGE_SIZE << order); | 209 | memset((char *)first_page, 0, PAGE_SIZE << order); |
| 206 | 210 | ||
| 207 | iommu = dev->archdata.iommu; | 211 | iommu = dev->archdata.iommu; |
| 208 | atu = iommu->atu; | ||
| 209 | |||
| 210 | mask = dev->coherent_dma_mask; | 212 | mask = dev->coherent_dma_mask; |
| 211 | if (mask <= DMA_BIT_MASK(32) || !atu) | 213 | if (!iommu_use_atu(iommu, mask)) |
| 212 | tbl = &iommu->tbl; | 214 | tbl = &iommu->tbl; |
| 213 | else | 215 | else |
| 214 | tbl = &atu->tbl; | 216 | tbl = &iommu->atu->tbl; |
| 215 | 217 | ||
| 216 | entry = iommu_tbl_range_alloc(dev, tbl, npages, NULL, | 218 | entry = iommu_tbl_range_alloc(dev, tbl, npages, NULL, |
| 217 | (unsigned long)(-1), 0); | 219 | (unsigned long)(-1), 0); |
| @@ -333,7 +335,7 @@ static void dma_4v_free_coherent(struct device *dev, size_t size, void *cpu, | |||
| 333 | atu = iommu->atu; | 335 | atu = iommu->atu; |
| 334 | devhandle = pbm->devhandle; | 336 | devhandle = pbm->devhandle; |
| 335 | 337 | ||
| 336 | if (dvma <= DMA_BIT_MASK(32)) { | 338 | if (!iommu_use_atu(iommu, dvma)) { |
| 337 | tbl = &iommu->tbl; | 339 | tbl = &iommu->tbl; |
| 338 | iotsb_num = 0; /* we don't care for legacy iommu */ | 340 | iotsb_num = 0; /* we don't care for legacy iommu */ |
| 339 | } else { | 341 | } else { |
| @@ -374,7 +376,7 @@ static dma_addr_t dma_4v_map_page(struct device *dev, struct page *page, | |||
| 374 | npages >>= IO_PAGE_SHIFT; | 376 | npages >>= IO_PAGE_SHIFT; |
| 375 | 377 | ||
| 376 | mask = *dev->dma_mask; | 378 | mask = *dev->dma_mask; |
| 377 | if (mask <= DMA_BIT_MASK(32)) | 379 | if (!iommu_use_atu(iommu, mask)) |
| 378 | tbl = &iommu->tbl; | 380 | tbl = &iommu->tbl; |
| 379 | else | 381 | else |
| 380 | tbl = &atu->tbl; | 382 | tbl = &atu->tbl; |
| @@ -510,7 +512,7 @@ static int dma_4v_map_sg(struct device *dev, struct scatterlist *sglist, | |||
| 510 | IO_PAGE_SIZE) >> IO_PAGE_SHIFT; | 512 | IO_PAGE_SIZE) >> IO_PAGE_SHIFT; |
| 511 | 513 | ||
| 512 | mask = *dev->dma_mask; | 514 | mask = *dev->dma_mask; |
| 513 | if (mask <= DMA_BIT_MASK(32)) | 515 | if (!iommu_use_atu(iommu, mask)) |
| 514 | tbl = &iommu->tbl; | 516 | tbl = &iommu->tbl; |
| 515 | else | 517 | else |
| 516 | tbl = &atu->tbl; | 518 | tbl = &atu->tbl; |
diff --git a/arch/x86/events/amd/core.c b/arch/x86/events/amd/core.c index 7d2d7c801dba..0ecfac84ba91 100644 --- a/arch/x86/events/amd/core.c +++ b/arch/x86/events/amd/core.c | |||
| @@ -3,10 +3,14 @@ | |||
| 3 | #include <linux/types.h> | 3 | #include <linux/types.h> |
| 4 | #include <linux/init.h> | 4 | #include <linux/init.h> |
| 5 | #include <linux/slab.h> | 5 | #include <linux/slab.h> |
| 6 | #include <linux/delay.h> | ||
| 6 | #include <asm/apicdef.h> | 7 | #include <asm/apicdef.h> |
| 8 | #include <asm/nmi.h> | ||
| 7 | 9 | ||
| 8 | #include "../perf_event.h" | 10 | #include "../perf_event.h" |
| 9 | 11 | ||
| 12 | static DEFINE_PER_CPU(unsigned int, perf_nmi_counter); | ||
| 13 | |||
| 10 | static __initconst const u64 amd_hw_cache_event_ids | 14 | static __initconst const u64 amd_hw_cache_event_ids |
| 11 | [PERF_COUNT_HW_CACHE_MAX] | 15 | [PERF_COUNT_HW_CACHE_MAX] |
| 12 | [PERF_COUNT_HW_CACHE_OP_MAX] | 16 | [PERF_COUNT_HW_CACHE_OP_MAX] |
| @@ -429,6 +433,132 @@ static void amd_pmu_cpu_dead(int cpu) | |||
| 429 | } | 433 | } |
| 430 | } | 434 | } |
| 431 | 435 | ||
| 436 | /* | ||
| 437 | * When a PMC counter overflows, an NMI is used to process the event and | ||
| 438 | * reset the counter. NMI latency can result in the counter being updated | ||
| 439 | * before the NMI can run, which can result in what appear to be spurious | ||
| 440 | * NMIs. This function is intended to wait for the NMI to run and reset | ||
| 441 | * the counter to avoid possible unhandled NMI messages. | ||
| 442 | */ | ||
| 443 | #define OVERFLOW_WAIT_COUNT 50 | ||
| 444 | |||
| 445 | static void amd_pmu_wait_on_overflow(int idx) | ||
| 446 | { | ||
| 447 | unsigned int i; | ||
| 448 | u64 counter; | ||
| 449 | |||
| 450 | /* | ||
| 451 | * Wait for the counter to be reset if it has overflowed. This loop | ||
| 452 | * should exit very, very quickly, but just in case, don't wait | ||
| 453 | * forever... | ||
| 454 | */ | ||
| 455 | for (i = 0; i < OVERFLOW_WAIT_COUNT; i++) { | ||
| 456 | rdmsrl(x86_pmu_event_addr(idx), counter); | ||
| 457 | if (counter & (1ULL << (x86_pmu.cntval_bits - 1))) | ||
| 458 | break; | ||
| 459 | |||
| 460 | /* Might be in IRQ context, so can't sleep */ | ||
| 461 | udelay(1); | ||
| 462 | } | ||
| 463 | } | ||
| 464 | |||
| 465 | static void amd_pmu_disable_all(void) | ||
| 466 | { | ||
| 467 | struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); | ||
| 468 | int idx; | ||
| 469 | |||
| 470 | x86_pmu_disable_all(); | ||
| 471 | |||
| 472 | /* | ||
| 473 | * This shouldn't be called from NMI context, but add a safeguard here | ||
| 474 | * to return, since if we're in NMI context we can't wait for an NMI | ||
| 475 | * to reset an overflowed counter value. | ||
| 476 | */ | ||
| 477 | if (in_nmi()) | ||
| 478 | return; | ||
| 479 | |||
| 480 | /* | ||
| 481 | * Check each counter for overflow and wait for it to be reset by the | ||
| 482 | * NMI if it has overflowed. This relies on the fact that all active | ||
| 483 | * counters are always enabled when this function is caled and | ||
| 484 | * ARCH_PERFMON_EVENTSEL_INT is always set. | ||
| 485 | */ | ||
| 486 | for (idx = 0; idx < x86_pmu.num_counters; idx++) { | ||
| 487 | if (!test_bit(idx, cpuc->active_mask)) | ||
| 488 | continue; | ||
| 489 | |||
| 490 | amd_pmu_wait_on_overflow(idx); | ||
| 491 | } | ||
| 492 | } | ||
| 493 | |||
| 494 | static void amd_pmu_disable_event(struct perf_event *event) | ||
| 495 | { | ||
| 496 | x86_pmu_disable_event(event); | ||
| 497 | |||
| 498 | /* | ||
| 499 | * This can be called from NMI context (via x86_pmu_stop). The counter | ||
| 500 | * may have overflowed, but either way, we'll never see it get reset | ||
| 501 | * by the NMI if we're already in the NMI. And the NMI latency support | ||
| 502 | * below will take care of any pending NMI that might have been | ||
| 503 | * generated by the overflow. | ||
| 504 | */ | ||
| 505 | if (in_nmi()) | ||
| 506 | return; | ||
| 507 | |||
| 508 | amd_pmu_wait_on_overflow(event->hw.idx); | ||
| 509 | } | ||
| 510 | |||
| 511 | /* | ||
| 512 | * Because of NMI latency, if multiple PMC counters are active or other sources | ||
| 513 | * of NMIs are received, the perf NMI handler can handle one or more overflowed | ||
| 514 | * PMC counters outside of the NMI associated with the PMC overflow. If the NMI | ||
| 515 | * doesn't arrive at the LAPIC in time to become a pending NMI, then the kernel | ||
| 516 | * back-to-back NMI support won't be active. This PMC handler needs to take into | ||
| 517 | * account that this can occur, otherwise this could result in unknown NMI | ||
| 518 | * messages being issued. Examples of this is PMC overflow while in the NMI | ||
| 519 | * handler when multiple PMCs are active or PMC overflow while handling some | ||
| 520 | * other source of an NMI. | ||
| 521 | * | ||
| 522 | * Attempt to mitigate this by using the number of active PMCs to determine | ||
| 523 | * whether to return NMI_HANDLED if the perf NMI handler did not handle/reset | ||
| 524 | * any PMCs. The per-CPU perf_nmi_counter variable is set to a minimum of the | ||
| 525 | * number of active PMCs or 2. The value of 2 is used in case an NMI does not | ||
| 526 | * arrive at the LAPIC in time to be collapsed into an already pending NMI. | ||
| 527 | */ | ||
| 528 | static int amd_pmu_handle_irq(struct pt_regs *regs) | ||
| 529 | { | ||
| 530 | struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); | ||
| 531 | int active, handled; | ||
| 532 | |||
| 533 | /* | ||
| 534 | * Obtain the active count before calling x86_pmu_handle_irq() since | ||
| 535 | * it is possible that x86_pmu_handle_irq() may make a counter | ||
| 536 | * inactive (through x86_pmu_stop). | ||
| 537 | */ | ||
| 538 | active = __bitmap_weight(cpuc->active_mask, X86_PMC_IDX_MAX); | ||
| 539 | |||
| 540 | /* Process any counter overflows */ | ||
| 541 | handled = x86_pmu_handle_irq(regs); | ||
| 542 | |||
| 543 | /* | ||
| 544 | * If a counter was handled, record the number of possible remaining | ||
| 545 | * NMIs that can occur. | ||
| 546 | */ | ||
| 547 | if (handled) { | ||
| 548 | this_cpu_write(perf_nmi_counter, | ||
| 549 | min_t(unsigned int, 2, active)); | ||
| 550 | |||
| 551 | return handled; | ||
| 552 | } | ||
| 553 | |||
| 554 | if (!this_cpu_read(perf_nmi_counter)) | ||
| 555 | return NMI_DONE; | ||
| 556 | |||
| 557 | this_cpu_dec(perf_nmi_counter); | ||
| 558 | |||
| 559 | return NMI_HANDLED; | ||
| 560 | } | ||
| 561 | |||
| 432 | static struct event_constraint * | 562 | static struct event_constraint * |
| 433 | amd_get_event_constraints(struct cpu_hw_events *cpuc, int idx, | 563 | amd_get_event_constraints(struct cpu_hw_events *cpuc, int idx, |
| 434 | struct perf_event *event) | 564 | struct perf_event *event) |
| @@ -621,11 +751,11 @@ static ssize_t amd_event_sysfs_show(char *page, u64 config) | |||
| 621 | 751 | ||
| 622 | static __initconst const struct x86_pmu amd_pmu = { | 752 | static __initconst const struct x86_pmu amd_pmu = { |
| 623 | .name = "AMD", | 753 | .name = "AMD", |
| 624 | .handle_irq = x86_pmu_handle_irq, | 754 | .handle_irq = amd_pmu_handle_irq, |
| 625 | .disable_all = x86_pmu_disable_all, | 755 | .disable_all = amd_pmu_disable_all, |
| 626 | .enable_all = x86_pmu_enable_all, | 756 | .enable_all = x86_pmu_enable_all, |
| 627 | .enable = x86_pmu_enable_event, | 757 | .enable = x86_pmu_enable_event, |
| 628 | .disable = x86_pmu_disable_event, | 758 | .disable = amd_pmu_disable_event, |
| 629 | .hw_config = amd_pmu_hw_config, | 759 | .hw_config = amd_pmu_hw_config, |
| 630 | .schedule_events = x86_schedule_events, | 760 | .schedule_events = x86_schedule_events, |
| 631 | .eventsel = MSR_K7_EVNTSEL0, | 761 | .eventsel = MSR_K7_EVNTSEL0, |
| @@ -732,7 +862,7 @@ void amd_pmu_enable_virt(void) | |||
| 732 | cpuc->perf_ctr_virt_mask = 0; | 862 | cpuc->perf_ctr_virt_mask = 0; |
| 733 | 863 | ||
| 734 | /* Reload all events */ | 864 | /* Reload all events */ |
| 735 | x86_pmu_disable_all(); | 865 | amd_pmu_disable_all(); |
| 736 | x86_pmu_enable_all(0); | 866 | x86_pmu_enable_all(0); |
| 737 | } | 867 | } |
| 738 | EXPORT_SYMBOL_GPL(amd_pmu_enable_virt); | 868 | EXPORT_SYMBOL_GPL(amd_pmu_enable_virt); |
| @@ -750,7 +880,7 @@ void amd_pmu_disable_virt(void) | |||
| 750 | cpuc->perf_ctr_virt_mask = AMD64_EVENTSEL_HOSTONLY; | 880 | cpuc->perf_ctr_virt_mask = AMD64_EVENTSEL_HOSTONLY; |
| 751 | 881 | ||
| 752 | /* Reload all events */ | 882 | /* Reload all events */ |
| 753 | x86_pmu_disable_all(); | 883 | amd_pmu_disable_all(); |
| 754 | x86_pmu_enable_all(0); | 884 | x86_pmu_enable_all(0); |
| 755 | } | 885 | } |
| 756 | EXPORT_SYMBOL_GPL(amd_pmu_disable_virt); | 886 | EXPORT_SYMBOL_GPL(amd_pmu_disable_virt); |
diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c index e2b1447192a8..81911e11a15d 100644 --- a/arch/x86/events/core.c +++ b/arch/x86/events/core.c | |||
| @@ -1349,8 +1349,9 @@ void x86_pmu_stop(struct perf_event *event, int flags) | |||
| 1349 | struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); | 1349 | struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); |
| 1350 | struct hw_perf_event *hwc = &event->hw; | 1350 | struct hw_perf_event *hwc = &event->hw; |
| 1351 | 1351 | ||
| 1352 | if (__test_and_clear_bit(hwc->idx, cpuc->active_mask)) { | 1352 | if (test_bit(hwc->idx, cpuc->active_mask)) { |
| 1353 | x86_pmu.disable(event); | 1353 | x86_pmu.disable(event); |
| 1354 | __clear_bit(hwc->idx, cpuc->active_mask); | ||
| 1354 | cpuc->events[hwc->idx] = NULL; | 1355 | cpuc->events[hwc->idx] = NULL; |
| 1355 | WARN_ON_ONCE(hwc->state & PERF_HES_STOPPED); | 1356 | WARN_ON_ONCE(hwc->state & PERF_HES_STOPPED); |
| 1356 | hwc->state |= PERF_HES_STOPPED; | 1357 | hwc->state |= PERF_HES_STOPPED; |
| @@ -1447,16 +1448,8 @@ int x86_pmu_handle_irq(struct pt_regs *regs) | |||
| 1447 | apic_write(APIC_LVTPC, APIC_DM_NMI); | 1448 | apic_write(APIC_LVTPC, APIC_DM_NMI); |
| 1448 | 1449 | ||
| 1449 | for (idx = 0; idx < x86_pmu.num_counters; idx++) { | 1450 | for (idx = 0; idx < x86_pmu.num_counters; idx++) { |
| 1450 | if (!test_bit(idx, cpuc->active_mask)) { | 1451 | if (!test_bit(idx, cpuc->active_mask)) |
| 1451 | /* | ||
| 1452 | * Though we deactivated the counter some cpus | ||
| 1453 | * might still deliver spurious interrupts still | ||
| 1454 | * in flight. Catch them: | ||
| 1455 | */ | ||
| 1456 | if (__test_and_clear_bit(idx, cpuc->running)) | ||
| 1457 | handled++; | ||
| 1458 | continue; | 1452 | continue; |
| 1459 | } | ||
| 1460 | 1453 | ||
| 1461 | event = cpuc->events[idx]; | 1454 | event = cpuc->events[idx]; |
| 1462 | 1455 | ||
diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c index 8baa441d8000..f61dcbef20ff 100644 --- a/arch/x86/events/intel/core.c +++ b/arch/x86/events/intel/core.c | |||
| @@ -3185,7 +3185,7 @@ static int intel_pmu_hw_config(struct perf_event *event) | |||
| 3185 | return ret; | 3185 | return ret; |
| 3186 | 3186 | ||
| 3187 | if (event->attr.precise_ip) { | 3187 | if (event->attr.precise_ip) { |
| 3188 | if (!event->attr.freq) { | 3188 | if (!(event->attr.freq || event->attr.wakeup_events)) { |
| 3189 | event->hw.flags |= PERF_X86_EVENT_AUTO_RELOAD; | 3189 | event->hw.flags |= PERF_X86_EVENT_AUTO_RELOAD; |
| 3190 | if (!(event->attr.sample_type & | 3190 | if (!(event->attr.sample_type & |
| 3191 | ~intel_pmu_large_pebs_flags(event))) | 3191 | ~intel_pmu_large_pebs_flags(event))) |
| @@ -3575,6 +3575,12 @@ static void intel_pmu_cpu_starting(int cpu) | |||
| 3575 | 3575 | ||
| 3576 | cpuc->lbr_sel = NULL; | 3576 | cpuc->lbr_sel = NULL; |
| 3577 | 3577 | ||
| 3578 | if (x86_pmu.flags & PMU_FL_TFA) { | ||
| 3579 | WARN_ON_ONCE(cpuc->tfa_shadow); | ||
| 3580 | cpuc->tfa_shadow = ~0ULL; | ||
| 3581 | intel_set_tfa(cpuc, false); | ||
| 3582 | } | ||
| 3583 | |||
| 3578 | if (x86_pmu.version > 1) | 3584 | if (x86_pmu.version > 1) |
| 3579 | flip_smm_bit(&x86_pmu.attr_freeze_on_smi); | 3585 | flip_smm_bit(&x86_pmu.attr_freeze_on_smi); |
| 3580 | 3586 | ||
diff --git a/arch/x86/include/asm/bitops.h b/arch/x86/include/asm/bitops.h index d153d570bb04..8e790ec219a5 100644 --- a/arch/x86/include/asm/bitops.h +++ b/arch/x86/include/asm/bitops.h | |||
| @@ -36,16 +36,17 @@ | |||
| 36 | * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1). | 36 | * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1). |
| 37 | */ | 37 | */ |
| 38 | 38 | ||
| 39 | #define BITOP_ADDR(x) "+m" (*(volatile long *) (x)) | 39 | #define RLONG_ADDR(x) "m" (*(volatile long *) (x)) |
| 40 | #define WBYTE_ADDR(x) "+m" (*(volatile char *) (x)) | ||
| 40 | 41 | ||
| 41 | #define ADDR BITOP_ADDR(addr) | 42 | #define ADDR RLONG_ADDR(addr) |
| 42 | 43 | ||
| 43 | /* | 44 | /* |
| 44 | * We do the locked ops that don't return the old value as | 45 | * We do the locked ops that don't return the old value as |
| 45 | * a mask operation on a byte. | 46 | * a mask operation on a byte. |
| 46 | */ | 47 | */ |
| 47 | #define IS_IMMEDIATE(nr) (__builtin_constant_p(nr)) | 48 | #define IS_IMMEDIATE(nr) (__builtin_constant_p(nr)) |
| 48 | #define CONST_MASK_ADDR(nr, addr) BITOP_ADDR((void *)(addr) + ((nr)>>3)) | 49 | #define CONST_MASK_ADDR(nr, addr) WBYTE_ADDR((void *)(addr) + ((nr)>>3)) |
| 49 | #define CONST_MASK(nr) (1 << ((nr) & 7)) | 50 | #define CONST_MASK(nr) (1 << ((nr) & 7)) |
| 50 | 51 | ||
| 51 | /** | 52 | /** |
| @@ -73,7 +74,7 @@ set_bit(long nr, volatile unsigned long *addr) | |||
| 73 | : "memory"); | 74 | : "memory"); |
| 74 | } else { | 75 | } else { |
| 75 | asm volatile(LOCK_PREFIX __ASM_SIZE(bts) " %1,%0" | 76 | asm volatile(LOCK_PREFIX __ASM_SIZE(bts) " %1,%0" |
| 76 | : BITOP_ADDR(addr) : "Ir" (nr) : "memory"); | 77 | : : RLONG_ADDR(addr), "Ir" (nr) : "memory"); |
| 77 | } | 78 | } |
| 78 | } | 79 | } |
| 79 | 80 | ||
| @@ -88,7 +89,7 @@ set_bit(long nr, volatile unsigned long *addr) | |||
| 88 | */ | 89 | */ |
| 89 | static __always_inline void __set_bit(long nr, volatile unsigned long *addr) | 90 | static __always_inline void __set_bit(long nr, volatile unsigned long *addr) |
| 90 | { | 91 | { |
| 91 | asm volatile(__ASM_SIZE(bts) " %1,%0" : ADDR : "Ir" (nr) : "memory"); | 92 | asm volatile(__ASM_SIZE(bts) " %1,%0" : : ADDR, "Ir" (nr) : "memory"); |
| 92 | } | 93 | } |
| 93 | 94 | ||
| 94 | /** | 95 | /** |
| @@ -110,8 +111,7 @@ clear_bit(long nr, volatile unsigned long *addr) | |||
| 110 | : "iq" ((u8)~CONST_MASK(nr))); | 111 | : "iq" ((u8)~CONST_MASK(nr))); |
| 111 | } else { | 112 | } else { |
| 112 | asm volatile(LOCK_PREFIX __ASM_SIZE(btr) " %1,%0" | 113 | asm volatile(LOCK_PREFIX __ASM_SIZE(btr) " %1,%0" |
| 113 | : BITOP_ADDR(addr) | 114 | : : RLONG_ADDR(addr), "Ir" (nr) : "memory"); |
| 114 | : "Ir" (nr)); | ||
| 115 | } | 115 | } |
| 116 | } | 116 | } |
| 117 | 117 | ||
| @@ -131,7 +131,7 @@ static __always_inline void clear_bit_unlock(long nr, volatile unsigned long *ad | |||
| 131 | 131 | ||
| 132 | static __always_inline void __clear_bit(long nr, volatile unsigned long *addr) | 132 | static __always_inline void __clear_bit(long nr, volatile unsigned long *addr) |
| 133 | { | 133 | { |
| 134 | asm volatile(__ASM_SIZE(btr) " %1,%0" : ADDR : "Ir" (nr)); | 134 | asm volatile(__ASM_SIZE(btr) " %1,%0" : : ADDR, "Ir" (nr) : "memory"); |
| 135 | } | 135 | } |
| 136 | 136 | ||
| 137 | static __always_inline bool clear_bit_unlock_is_negative_byte(long nr, volatile unsigned long *addr) | 137 | static __always_inline bool clear_bit_unlock_is_negative_byte(long nr, volatile unsigned long *addr) |
| @@ -139,7 +139,7 @@ static __always_inline bool clear_bit_unlock_is_negative_byte(long nr, volatile | |||
| 139 | bool negative; | 139 | bool negative; |
| 140 | asm volatile(LOCK_PREFIX "andb %2,%1" | 140 | asm volatile(LOCK_PREFIX "andb %2,%1" |
| 141 | CC_SET(s) | 141 | CC_SET(s) |
| 142 | : CC_OUT(s) (negative), ADDR | 142 | : CC_OUT(s) (negative), WBYTE_ADDR(addr) |
| 143 | : "ir" ((char) ~(1 << nr)) : "memory"); | 143 | : "ir" ((char) ~(1 << nr)) : "memory"); |
| 144 | return negative; | 144 | return negative; |
| 145 | } | 145 | } |
| @@ -155,13 +155,9 @@ static __always_inline bool clear_bit_unlock_is_negative_byte(long nr, volatile | |||
| 155 | * __clear_bit() is non-atomic and implies release semantics before the memory | 155 | * __clear_bit() is non-atomic and implies release semantics before the memory |
| 156 | * operation. It can be used for an unlock if no other CPUs can concurrently | 156 | * operation. It can be used for an unlock if no other CPUs can concurrently |
| 157 | * modify other bits in the word. | 157 | * modify other bits in the word. |
| 158 | * | ||
| 159 | * No memory barrier is required here, because x86 cannot reorder stores past | ||
| 160 | * older loads. Same principle as spin_unlock. | ||
| 161 | */ | 158 | */ |
| 162 | static __always_inline void __clear_bit_unlock(long nr, volatile unsigned long *addr) | 159 | static __always_inline void __clear_bit_unlock(long nr, volatile unsigned long *addr) |
| 163 | { | 160 | { |
| 164 | barrier(); | ||
| 165 | __clear_bit(nr, addr); | 161 | __clear_bit(nr, addr); |
| 166 | } | 162 | } |
| 167 | 163 | ||
| @@ -176,7 +172,7 @@ static __always_inline void __clear_bit_unlock(long nr, volatile unsigned long * | |||
| 176 | */ | 172 | */ |
| 177 | static __always_inline void __change_bit(long nr, volatile unsigned long *addr) | 173 | static __always_inline void __change_bit(long nr, volatile unsigned long *addr) |
| 178 | { | 174 | { |
| 179 | asm volatile(__ASM_SIZE(btc) " %1,%0" : ADDR : "Ir" (nr)); | 175 | asm volatile(__ASM_SIZE(btc) " %1,%0" : : ADDR, "Ir" (nr) : "memory"); |
| 180 | } | 176 | } |
| 181 | 177 | ||
| 182 | /** | 178 | /** |
| @@ -196,8 +192,7 @@ static __always_inline void change_bit(long nr, volatile unsigned long *addr) | |||
| 196 | : "iq" ((u8)CONST_MASK(nr))); | 192 | : "iq" ((u8)CONST_MASK(nr))); |
| 197 | } else { | 193 | } else { |
| 198 | asm volatile(LOCK_PREFIX __ASM_SIZE(btc) " %1,%0" | 194 | asm volatile(LOCK_PREFIX __ASM_SIZE(btc) " %1,%0" |
| 199 | : BITOP_ADDR(addr) | 195 | : : RLONG_ADDR(addr), "Ir" (nr) : "memory"); |
| 200 | : "Ir" (nr)); | ||
| 201 | } | 196 | } |
| 202 | } | 197 | } |
| 203 | 198 | ||
| @@ -242,8 +237,8 @@ static __always_inline bool __test_and_set_bit(long nr, volatile unsigned long * | |||
| 242 | 237 | ||
| 243 | asm(__ASM_SIZE(bts) " %2,%1" | 238 | asm(__ASM_SIZE(bts) " %2,%1" |
| 244 | CC_SET(c) | 239 | CC_SET(c) |
| 245 | : CC_OUT(c) (oldbit), ADDR | 240 | : CC_OUT(c) (oldbit) |
| 246 | : "Ir" (nr)); | 241 | : ADDR, "Ir" (nr) : "memory"); |
| 247 | return oldbit; | 242 | return oldbit; |
| 248 | } | 243 | } |
| 249 | 244 | ||
| @@ -282,8 +277,8 @@ static __always_inline bool __test_and_clear_bit(long nr, volatile unsigned long | |||
| 282 | 277 | ||
| 283 | asm volatile(__ASM_SIZE(btr) " %2,%1" | 278 | asm volatile(__ASM_SIZE(btr) " %2,%1" |
| 284 | CC_SET(c) | 279 | CC_SET(c) |
| 285 | : CC_OUT(c) (oldbit), ADDR | 280 | : CC_OUT(c) (oldbit) |
| 286 | : "Ir" (nr)); | 281 | : ADDR, "Ir" (nr) : "memory"); |
| 287 | return oldbit; | 282 | return oldbit; |
| 288 | } | 283 | } |
| 289 | 284 | ||
| @@ -294,8 +289,8 @@ static __always_inline bool __test_and_change_bit(long nr, volatile unsigned lon | |||
| 294 | 289 | ||
| 295 | asm volatile(__ASM_SIZE(btc) " %2,%1" | 290 | asm volatile(__ASM_SIZE(btc) " %2,%1" |
| 296 | CC_SET(c) | 291 | CC_SET(c) |
| 297 | : CC_OUT(c) (oldbit), ADDR | 292 | : CC_OUT(c) (oldbit) |
| 298 | : "Ir" (nr) : "memory"); | 293 | : ADDR, "Ir" (nr) : "memory"); |
| 299 | 294 | ||
| 300 | return oldbit; | 295 | return oldbit; |
| 301 | } | 296 | } |
| @@ -326,7 +321,7 @@ static __always_inline bool variable_test_bit(long nr, volatile const unsigned l | |||
| 326 | asm volatile(__ASM_SIZE(bt) " %2,%1" | 321 | asm volatile(__ASM_SIZE(bt) " %2,%1" |
| 327 | CC_SET(c) | 322 | CC_SET(c) |
| 328 | : CC_OUT(c) (oldbit) | 323 | : CC_OUT(c) (oldbit) |
| 329 | : "m" (*(unsigned long *)addr), "Ir" (nr)); | 324 | : "m" (*(unsigned long *)addr), "Ir" (nr) : "memory"); |
| 330 | 325 | ||
| 331 | return oldbit; | 326 | return oldbit; |
| 332 | } | 327 | } |
diff --git a/arch/x86/kernel/cpu/resctrl/rdtgroup.c b/arch/x86/kernel/cpu/resctrl/rdtgroup.c index 399601eda8e4..54b9eef3eea9 100644 --- a/arch/x86/kernel/cpu/resctrl/rdtgroup.c +++ b/arch/x86/kernel/cpu/resctrl/rdtgroup.c | |||
| @@ -2039,14 +2039,14 @@ out: | |||
| 2039 | enum rdt_param { | 2039 | enum rdt_param { |
| 2040 | Opt_cdp, | 2040 | Opt_cdp, |
| 2041 | Opt_cdpl2, | 2041 | Opt_cdpl2, |
| 2042 | Opt_mba_mpbs, | 2042 | Opt_mba_mbps, |
| 2043 | nr__rdt_params | 2043 | nr__rdt_params |
| 2044 | }; | 2044 | }; |
| 2045 | 2045 | ||
| 2046 | static const struct fs_parameter_spec rdt_param_specs[] = { | 2046 | static const struct fs_parameter_spec rdt_param_specs[] = { |
| 2047 | fsparam_flag("cdp", Opt_cdp), | 2047 | fsparam_flag("cdp", Opt_cdp), |
| 2048 | fsparam_flag("cdpl2", Opt_cdpl2), | 2048 | fsparam_flag("cdpl2", Opt_cdpl2), |
| 2049 | fsparam_flag("mba_mpbs", Opt_mba_mpbs), | 2049 | fsparam_flag("mba_MBps", Opt_mba_mbps), |
| 2050 | {} | 2050 | {} |
| 2051 | }; | 2051 | }; |
| 2052 | 2052 | ||
| @@ -2072,7 +2072,7 @@ static int rdt_parse_param(struct fs_context *fc, struct fs_parameter *param) | |||
| 2072 | case Opt_cdpl2: | 2072 | case Opt_cdpl2: |
| 2073 | ctx->enable_cdpl2 = true; | 2073 | ctx->enable_cdpl2 = true; |
| 2074 | return 0; | 2074 | return 0; |
| 2075 | case Opt_mba_mpbs: | 2075 | case Opt_mba_mbps: |
| 2076 | if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL) | 2076 | if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL) |
| 2077 | return -EINVAL; | 2077 | return -EINVAL; |
| 2078 | ctx->enable_mba_mbps = true; | 2078 | ctx->enable_mba_mbps = true; |
diff --git a/arch/xtensa/include/asm/processor.h b/arch/xtensa/include/asm/processor.h index f7dd895b2353..0c14018d1c26 100644 --- a/arch/xtensa/include/asm/processor.h +++ b/arch/xtensa/include/asm/processor.h | |||
| @@ -187,15 +187,18 @@ struct thread_struct { | |||
| 187 | 187 | ||
| 188 | /* Clearing a0 terminates the backtrace. */ | 188 | /* Clearing a0 terminates the backtrace. */ |
| 189 | #define start_thread(regs, new_pc, new_sp) \ | 189 | #define start_thread(regs, new_pc, new_sp) \ |
| 190 | memset(regs, 0, sizeof(*regs)); \ | 190 | do { \ |
| 191 | regs->pc = new_pc; \ | 191 | memset((regs), 0, sizeof(*(regs))); \ |
| 192 | regs->ps = USER_PS_VALUE; \ | 192 | (regs)->pc = (new_pc); \ |
| 193 | regs->areg[1] = new_sp; \ | 193 | (regs)->ps = USER_PS_VALUE; \ |
| 194 | regs->areg[0] = 0; \ | 194 | (regs)->areg[1] = (new_sp); \ |
| 195 | regs->wmask = 1; \ | 195 | (regs)->areg[0] = 0; \ |
| 196 | regs->depc = 0; \ | 196 | (regs)->wmask = 1; \ |
| 197 | regs->windowbase = 0; \ | 197 | (regs)->depc = 0; \ |
| 198 | regs->windowstart = 1; | 198 | (regs)->windowbase = 0; \ |
| 199 | (regs)->windowstart = 1; \ | ||
| 200 | (regs)->syscall = NO_SYSCALL; \ | ||
| 201 | } while (0) | ||
| 199 | 202 | ||
| 200 | /* Forward declaration */ | 203 | /* Forward declaration */ |
| 201 | struct task_struct; | 204 | struct task_struct; |
diff --git a/arch/xtensa/kernel/entry.S b/arch/xtensa/kernel/entry.S index e50f5124dc6f..e54af8b7e0f8 100644 --- a/arch/xtensa/kernel/entry.S +++ b/arch/xtensa/kernel/entry.S | |||
| @@ -1860,6 +1860,8 @@ ENTRY(system_call) | |||
| 1860 | l32i a7, a2, PT_SYSCALL | 1860 | l32i a7, a2, PT_SYSCALL |
| 1861 | 1861 | ||
| 1862 | 1: | 1862 | 1: |
| 1863 | s32i a7, a1, 4 | ||
| 1864 | |||
| 1863 | /* syscall = sys_call_table[syscall_nr] */ | 1865 | /* syscall = sys_call_table[syscall_nr] */ |
| 1864 | 1866 | ||
| 1865 | movi a4, sys_call_table | 1867 | movi a4, sys_call_table |
| @@ -1893,8 +1895,12 @@ ENTRY(system_call) | |||
| 1893 | retw | 1895 | retw |
| 1894 | 1896 | ||
| 1895 | 1: | 1897 | 1: |
| 1898 | l32i a4, a1, 4 | ||
| 1899 | l32i a3, a2, PT_SYSCALL | ||
| 1900 | s32i a4, a2, PT_SYSCALL | ||
| 1896 | mov a6, a2 | 1901 | mov a6, a2 |
| 1897 | call4 do_syscall_trace_leave | 1902 | call4 do_syscall_trace_leave |
| 1903 | s32i a3, a2, PT_SYSCALL | ||
| 1898 | retw | 1904 | retw |
| 1899 | 1905 | ||
| 1900 | ENDPROC(system_call) | 1906 | ENDPROC(system_call) |
diff --git a/arch/xtensa/kernel/stacktrace.c b/arch/xtensa/kernel/stacktrace.c index 174c11f13bba..b9f82510c650 100644 --- a/arch/xtensa/kernel/stacktrace.c +++ b/arch/xtensa/kernel/stacktrace.c | |||
| @@ -253,10 +253,14 @@ static int return_address_cb(struct stackframe *frame, void *data) | |||
| 253 | return 1; | 253 | return 1; |
| 254 | } | 254 | } |
| 255 | 255 | ||
| 256 | /* | ||
| 257 | * level == 0 is for the return address from the caller of this function, | ||
| 258 | * not from this function itself. | ||
| 259 | */ | ||
| 256 | unsigned long return_address(unsigned level) | 260 | unsigned long return_address(unsigned level) |
| 257 | { | 261 | { |
| 258 | struct return_addr_data r = { | 262 | struct return_addr_data r = { |
| 259 | .skip = level + 1, | 263 | .skip = level, |
| 260 | }; | 264 | }; |
| 261 | walk_stackframe(stack_pointer(NULL), return_address_cb, &r); | 265 | walk_stackframe(stack_pointer(NULL), return_address_cb, &r); |
| 262 | return r.addr; | 266 | return r.addr; |
diff --git a/arch/xtensa/mm/mmu.c b/arch/xtensa/mm/mmu.c index 2fb7d1172228..03678c4afc39 100644 --- a/arch/xtensa/mm/mmu.c +++ b/arch/xtensa/mm/mmu.c | |||
| @@ -33,7 +33,7 @@ static void * __init init_pmd(unsigned long vaddr, unsigned long n_pages) | |||
| 33 | 33 | ||
| 34 | pte = memblock_alloc_low(n_pages * sizeof(pte_t), PAGE_SIZE); | 34 | pte = memblock_alloc_low(n_pages * sizeof(pte_t), PAGE_SIZE); |
| 35 | if (!pte) | 35 | if (!pte) |
| 36 | panic("%s: Failed to allocate %zu bytes align=%lx\n", | 36 | panic("%s: Failed to allocate %lu bytes align=%lx\n", |
| 37 | __func__, n_pages * sizeof(pte_t), PAGE_SIZE); | 37 | __func__, n_pages * sizeof(pte_t), PAGE_SIZE); |
| 38 | 38 | ||
| 39 | for (i = 0; i < n_pages; ++i) | 39 | for (i = 0; i < n_pages; ++i) |
diff --git a/drivers/acpi/acpica/nsobject.c b/drivers/acpi/acpica/nsobject.c index 8638f43cfc3d..79d86da1c892 100644 --- a/drivers/acpi/acpica/nsobject.c +++ b/drivers/acpi/acpica/nsobject.c | |||
| @@ -186,6 +186,10 @@ void acpi_ns_detach_object(struct acpi_namespace_node *node) | |||
| 186 | } | 186 | } |
| 187 | } | 187 | } |
| 188 | 188 | ||
| 189 | if (obj_desc->common.type == ACPI_TYPE_REGION) { | ||
| 190 | acpi_ut_remove_address_range(obj_desc->region.space_id, node); | ||
| 191 | } | ||
| 192 | |||
| 189 | /* Clear the Node entry in all cases */ | 193 | /* Clear the Node entry in all cases */ |
| 190 | 194 | ||
| 191 | node->object = NULL; | 195 | node->object = NULL; |
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index ded198328f21..7db48ae65cd2 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c | |||
| @@ -2942,6 +2942,7 @@ static int btusb_config_oob_wake(struct hci_dev *hdev) | |||
| 2942 | return 0; | 2942 | return 0; |
| 2943 | } | 2943 | } |
| 2944 | 2944 | ||
| 2945 | irq_set_status_flags(irq, IRQ_NOAUTOEN); | ||
| 2945 | ret = devm_request_irq(&hdev->dev, irq, btusb_oob_wake_handler, | 2946 | ret = devm_request_irq(&hdev->dev, irq, btusb_oob_wake_handler, |
| 2946 | 0, "OOB Wake-on-BT", data); | 2947 | 0, "OOB Wake-on-BT", data); |
| 2947 | if (ret) { | 2948 | if (ret) { |
| @@ -2956,7 +2957,6 @@ static int btusb_config_oob_wake(struct hci_dev *hdev) | |||
| 2956 | } | 2957 | } |
| 2957 | 2958 | ||
| 2958 | data->oob_wake_irq = irq; | 2959 | data->oob_wake_irq = irq; |
| 2959 | disable_irq(irq); | ||
| 2960 | bt_dev_info(hdev, "OOB Wake-on-BT configured at IRQ %u", irq); | 2960 | bt_dev_info(hdev, "OOB Wake-on-BT configured at IRQ %u", irq); |
| 2961 | return 0; | 2961 | return 0; |
| 2962 | } | 2962 | } |
diff --git a/drivers/char/tpm/eventlog/tpm2.c b/drivers/char/tpm/eventlog/tpm2.c index d8b77133a83a..f824563fc28d 100644 --- a/drivers/char/tpm/eventlog/tpm2.c +++ b/drivers/char/tpm/eventlog/tpm2.c | |||
| @@ -37,8 +37,8 @@ | |||
| 37 | * | 37 | * |
| 38 | * Returns size of the event. If it is an invalid event, returns 0. | 38 | * Returns size of the event. If it is an invalid event, returns 0. |
| 39 | */ | 39 | */ |
| 40 | static int calc_tpm2_event_size(struct tcg_pcr_event2_head *event, | 40 | static size_t calc_tpm2_event_size(struct tcg_pcr_event2_head *event, |
| 41 | struct tcg_pcr_event *event_header) | 41 | struct tcg_pcr_event *event_header) |
| 42 | { | 42 | { |
| 43 | struct tcg_efi_specid_event_head *efispecid; | 43 | struct tcg_efi_specid_event_head *efispecid; |
| 44 | struct tcg_event_field *event_field; | 44 | struct tcg_event_field *event_field; |
diff --git a/drivers/char/tpm/tpm-dev-common.c b/drivers/char/tpm/tpm-dev-common.c index 8856cce5a23b..817ae09a369e 100644 --- a/drivers/char/tpm/tpm-dev-common.c +++ b/drivers/char/tpm/tpm-dev-common.c | |||
| @@ -233,12 +233,19 @@ __poll_t tpm_common_poll(struct file *file, poll_table *wait) | |||
| 233 | __poll_t mask = 0; | 233 | __poll_t mask = 0; |
| 234 | 234 | ||
| 235 | poll_wait(file, &priv->async_wait, wait); | 235 | poll_wait(file, &priv->async_wait, wait); |
| 236 | mutex_lock(&priv->buffer_mutex); | ||
| 236 | 237 | ||
| 237 | if (!priv->response_read || priv->response_length) | 238 | /* |
| 239 | * The response_length indicates if there is still response | ||
| 240 | * (or part of it) to be consumed. Partial reads decrease it | ||
| 241 | * by the number of bytes read, and write resets it the zero. | ||
| 242 | */ | ||
| 243 | if (priv->response_length) | ||
| 238 | mask = EPOLLIN | EPOLLRDNORM; | 244 | mask = EPOLLIN | EPOLLRDNORM; |
| 239 | else | 245 | else |
| 240 | mask = EPOLLOUT | EPOLLWRNORM; | 246 | mask = EPOLLOUT | EPOLLWRNORM; |
| 241 | 247 | ||
| 248 | mutex_unlock(&priv->buffer_mutex); | ||
| 242 | return mask; | 249 | return mask; |
| 243 | } | 250 | } |
| 244 | 251 | ||
diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c index 83ece5639f86..ae1030c9b086 100644 --- a/drivers/char/tpm/tpm-interface.c +++ b/drivers/char/tpm/tpm-interface.c | |||
| @@ -402,15 +402,13 @@ int tpm_pm_suspend(struct device *dev) | |||
| 402 | if (chip->flags & TPM_CHIP_FLAG_ALWAYS_POWERED) | 402 | if (chip->flags & TPM_CHIP_FLAG_ALWAYS_POWERED) |
| 403 | return 0; | 403 | return 0; |
| 404 | 404 | ||
| 405 | if (chip->flags & TPM_CHIP_FLAG_TPM2) { | 405 | if (!tpm_chip_start(chip)) { |
| 406 | mutex_lock(&chip->tpm_mutex); | 406 | if (chip->flags & TPM_CHIP_FLAG_TPM2) |
| 407 | if (!tpm_chip_start(chip)) { | ||
| 408 | tpm2_shutdown(chip, TPM2_SU_STATE); | 407 | tpm2_shutdown(chip, TPM2_SU_STATE); |
| 409 | tpm_chip_stop(chip); | 408 | else |
| 410 | } | 409 | rc = tpm1_pm_suspend(chip, tpm_suspend_pcr); |
| 411 | mutex_unlock(&chip->tpm_mutex); | 410 | |
| 412 | } else { | 411 | tpm_chip_stop(chip); |
| 413 | rc = tpm1_pm_suspend(chip, tpm_suspend_pcr); | ||
| 414 | } | 412 | } |
| 415 | 413 | ||
| 416 | return rc; | 414 | return rc; |
diff --git a/drivers/clk/at91/clk-programmable.c b/drivers/clk/at91/clk-programmable.c index 89d6f3736dbf..f8edbb65eda3 100644 --- a/drivers/clk/at91/clk-programmable.c +++ b/drivers/clk/at91/clk-programmable.c | |||
| @@ -20,8 +20,7 @@ | |||
| 20 | #define PROG_ID_MAX 7 | 20 | #define PROG_ID_MAX 7 |
| 21 | 21 | ||
| 22 | #define PROG_STATUS_MASK(id) (1 << ((id) + 8)) | 22 | #define PROG_STATUS_MASK(id) (1 << ((id) + 8)) |
| 23 | #define PROG_PRES_MASK 0x7 | 23 | #define PROG_PRES(layout, pckr) ((pckr >> layout->pres_shift) & layout->pres_mask) |
| 24 | #define PROG_PRES(layout, pckr) ((pckr >> layout->pres_shift) & PROG_PRES_MASK) | ||
| 25 | #define PROG_MAX_RM9200_CSS 3 | 24 | #define PROG_MAX_RM9200_CSS 3 |
| 26 | 25 | ||
| 27 | struct clk_programmable { | 26 | struct clk_programmable { |
| @@ -37,20 +36,29 @@ static unsigned long clk_programmable_recalc_rate(struct clk_hw *hw, | |||
| 37 | unsigned long parent_rate) | 36 | unsigned long parent_rate) |
| 38 | { | 37 | { |
| 39 | struct clk_programmable *prog = to_clk_programmable(hw); | 38 | struct clk_programmable *prog = to_clk_programmable(hw); |
| 39 | const struct clk_programmable_layout *layout = prog->layout; | ||
| 40 | unsigned int pckr; | 40 | unsigned int pckr; |
| 41 | unsigned long rate; | ||
| 41 | 42 | ||
| 42 | regmap_read(prog->regmap, AT91_PMC_PCKR(prog->id), &pckr); | 43 | regmap_read(prog->regmap, AT91_PMC_PCKR(prog->id), &pckr); |
| 43 | 44 | ||
| 44 | return parent_rate >> PROG_PRES(prog->layout, pckr); | 45 | if (layout->is_pres_direct) |
| 46 | rate = parent_rate / (PROG_PRES(layout, pckr) + 1); | ||
| 47 | else | ||
| 48 | rate = parent_rate >> PROG_PRES(layout, pckr); | ||
| 49 | |||
| 50 | return rate; | ||
| 45 | } | 51 | } |
| 46 | 52 | ||
| 47 | static int clk_programmable_determine_rate(struct clk_hw *hw, | 53 | static int clk_programmable_determine_rate(struct clk_hw *hw, |
| 48 | struct clk_rate_request *req) | 54 | struct clk_rate_request *req) |
| 49 | { | 55 | { |
| 56 | struct clk_programmable *prog = to_clk_programmable(hw); | ||
| 57 | const struct clk_programmable_layout *layout = prog->layout; | ||
| 50 | struct clk_hw *parent; | 58 | struct clk_hw *parent; |
| 51 | long best_rate = -EINVAL; | 59 | long best_rate = -EINVAL; |
| 52 | unsigned long parent_rate; | 60 | unsigned long parent_rate; |
| 53 | unsigned long tmp_rate; | 61 | unsigned long tmp_rate = 0; |
| 54 | int shift; | 62 | int shift; |
| 55 | int i; | 63 | int i; |
| 56 | 64 | ||
| @@ -60,10 +68,18 @@ static int clk_programmable_determine_rate(struct clk_hw *hw, | |||
| 60 | continue; | 68 | continue; |
| 61 | 69 | ||
| 62 | parent_rate = clk_hw_get_rate(parent); | 70 | parent_rate = clk_hw_get_rate(parent); |
| 63 | for (shift = 0; shift < PROG_PRES_MASK; shift++) { | 71 | if (layout->is_pres_direct) { |
| 64 | tmp_rate = parent_rate >> shift; | 72 | for (shift = 0; shift <= layout->pres_mask; shift++) { |
| 65 | if (tmp_rate <= req->rate) | 73 | tmp_rate = parent_rate / (shift + 1); |
| 66 | break; | 74 | if (tmp_rate <= req->rate) |
| 75 | break; | ||
| 76 | } | ||
| 77 | } else { | ||
| 78 | for (shift = 0; shift < layout->pres_mask; shift++) { | ||
| 79 | tmp_rate = parent_rate >> shift; | ||
| 80 | if (tmp_rate <= req->rate) | ||
| 81 | break; | ||
| 82 | } | ||
| 67 | } | 83 | } |
| 68 | 84 | ||
| 69 | if (tmp_rate > req->rate) | 85 | if (tmp_rate > req->rate) |
| @@ -137,16 +153,23 @@ static int clk_programmable_set_rate(struct clk_hw *hw, unsigned long rate, | |||
| 137 | if (!div) | 153 | if (!div) |
| 138 | return -EINVAL; | 154 | return -EINVAL; |
| 139 | 155 | ||
| 140 | shift = fls(div) - 1; | 156 | if (layout->is_pres_direct) { |
| 157 | shift = div - 1; | ||
| 141 | 158 | ||
| 142 | if (div != (1 << shift)) | 159 | if (shift > layout->pres_mask) |
| 143 | return -EINVAL; | 160 | return -EINVAL; |
| 161 | } else { | ||
| 162 | shift = fls(div) - 1; | ||
| 144 | 163 | ||
| 145 | if (shift >= PROG_PRES_MASK) | 164 | if (div != (1 << shift)) |
| 146 | return -EINVAL; | 165 | return -EINVAL; |
| 166 | |||
| 167 | if (shift >= layout->pres_mask) | ||
| 168 | return -EINVAL; | ||
| 169 | } | ||
| 147 | 170 | ||
| 148 | regmap_update_bits(prog->regmap, AT91_PMC_PCKR(prog->id), | 171 | regmap_update_bits(prog->regmap, AT91_PMC_PCKR(prog->id), |
| 149 | PROG_PRES_MASK << layout->pres_shift, | 172 | layout->pres_mask << layout->pres_shift, |
| 150 | shift << layout->pres_shift); | 173 | shift << layout->pres_shift); |
| 151 | 174 | ||
| 152 | return 0; | 175 | return 0; |
| @@ -202,19 +225,25 @@ at91_clk_register_programmable(struct regmap *regmap, | |||
| 202 | } | 225 | } |
| 203 | 226 | ||
| 204 | const struct clk_programmable_layout at91rm9200_programmable_layout = { | 227 | const struct clk_programmable_layout at91rm9200_programmable_layout = { |
| 228 | .pres_mask = 0x7, | ||
| 205 | .pres_shift = 2, | 229 | .pres_shift = 2, |
| 206 | .css_mask = 0x3, | 230 | .css_mask = 0x3, |
| 207 | .have_slck_mck = 0, | 231 | .have_slck_mck = 0, |
| 232 | .is_pres_direct = 0, | ||
| 208 | }; | 233 | }; |
| 209 | 234 | ||
| 210 | const struct clk_programmable_layout at91sam9g45_programmable_layout = { | 235 | const struct clk_programmable_layout at91sam9g45_programmable_layout = { |
| 236 | .pres_mask = 0x7, | ||
| 211 | .pres_shift = 2, | 237 | .pres_shift = 2, |
| 212 | .css_mask = 0x3, | 238 | .css_mask = 0x3, |
| 213 | .have_slck_mck = 1, | 239 | .have_slck_mck = 1, |
| 240 | .is_pres_direct = 0, | ||
| 214 | }; | 241 | }; |
| 215 | 242 | ||
| 216 | const struct clk_programmable_layout at91sam9x5_programmable_layout = { | 243 | const struct clk_programmable_layout at91sam9x5_programmable_layout = { |
| 244 | .pres_mask = 0x7, | ||
| 217 | .pres_shift = 4, | 245 | .pres_shift = 4, |
| 218 | .css_mask = 0x7, | 246 | .css_mask = 0x7, |
| 219 | .have_slck_mck = 0, | 247 | .have_slck_mck = 0, |
| 248 | .is_pres_direct = 0, | ||
| 220 | }; | 249 | }; |
diff --git a/drivers/clk/at91/pmc.h b/drivers/clk/at91/pmc.h index 672a79bda88c..a0e5ce9c9b9e 100644 --- a/drivers/clk/at91/pmc.h +++ b/drivers/clk/at91/pmc.h | |||
| @@ -71,9 +71,11 @@ struct clk_pll_characteristics { | |||
| 71 | }; | 71 | }; |
| 72 | 72 | ||
| 73 | struct clk_programmable_layout { | 73 | struct clk_programmable_layout { |
| 74 | u8 pres_mask; | ||
| 74 | u8 pres_shift; | 75 | u8 pres_shift; |
| 75 | u8 css_mask; | 76 | u8 css_mask; |
| 76 | u8 have_slck_mck; | 77 | u8 have_slck_mck; |
| 78 | u8 is_pres_direct; | ||
| 77 | }; | 79 | }; |
| 78 | 80 | ||
| 79 | extern const struct clk_programmable_layout at91rm9200_programmable_layout; | 81 | extern const struct clk_programmable_layout at91rm9200_programmable_layout; |
diff --git a/drivers/clk/at91/sama5d2.c b/drivers/clk/at91/sama5d2.c index 1f70cb164b06..81943fac4537 100644 --- a/drivers/clk/at91/sama5d2.c +++ b/drivers/clk/at91/sama5d2.c | |||
| @@ -125,6 +125,14 @@ static const struct { | |||
| 125 | .pll = true }, | 125 | .pll = true }, |
| 126 | }; | 126 | }; |
| 127 | 127 | ||
| 128 | static const struct clk_programmable_layout sama5d2_programmable_layout = { | ||
| 129 | .pres_mask = 0xff, | ||
| 130 | .pres_shift = 4, | ||
| 131 | .css_mask = 0x7, | ||
| 132 | .have_slck_mck = 0, | ||
| 133 | .is_pres_direct = 1, | ||
| 134 | }; | ||
| 135 | |||
| 128 | static void __init sama5d2_pmc_setup(struct device_node *np) | 136 | static void __init sama5d2_pmc_setup(struct device_node *np) |
| 129 | { | 137 | { |
| 130 | struct clk_range range = CLK_RANGE(0, 0); | 138 | struct clk_range range = CLK_RANGE(0, 0); |
| @@ -249,7 +257,7 @@ static void __init sama5d2_pmc_setup(struct device_node *np) | |||
| 249 | 257 | ||
| 250 | hw = at91_clk_register_programmable(regmap, name, | 258 | hw = at91_clk_register_programmable(regmap, name, |
| 251 | parent_names, 6, i, | 259 | parent_names, 6, i, |
| 252 | &at91sam9x5_programmable_layout); | 260 | &sama5d2_programmable_layout); |
| 253 | if (IS_ERR(hw)) | 261 | if (IS_ERR(hw)) |
| 254 | goto err_free; | 262 | goto err_free; |
| 255 | } | 263 | } |
diff --git a/drivers/clk/imx/clk-pll14xx.c b/drivers/clk/imx/clk-pll14xx.c index 1acfa3e3cfb4..113d71042199 100644 --- a/drivers/clk/imx/clk-pll14xx.c +++ b/drivers/clk/imx/clk-pll14xx.c | |||
| @@ -362,7 +362,7 @@ struct clk *imx_clk_pll14xx(const char *name, const char *parent_name, | |||
| 362 | 362 | ||
| 363 | switch (pll_clk->type) { | 363 | switch (pll_clk->type) { |
| 364 | case PLL_1416X: | 364 | case PLL_1416X: |
| 365 | if (!pll->rate_table) | 365 | if (!pll_clk->rate_table) |
| 366 | init.ops = &clk_pll1416x_min_ops; | 366 | init.ops = &clk_pll1416x_min_ops; |
| 367 | else | 367 | else |
| 368 | init.ops = &clk_pll1416x_ops; | 368 | init.ops = &clk_pll1416x_ops; |
diff --git a/drivers/clk/mediatek/clk-gate.c b/drivers/clk/mediatek/clk-gate.c index 9628d4e7690b..85daf826619a 100644 --- a/drivers/clk/mediatek/clk-gate.c +++ b/drivers/clk/mediatek/clk-gate.c | |||
| @@ -169,11 +169,10 @@ struct clk *mtk_clk_register_gate( | |||
| 169 | return ERR_PTR(-ENOMEM); | 169 | return ERR_PTR(-ENOMEM); |
| 170 | 170 | ||
| 171 | init.name = name; | 171 | init.name = name; |
| 172 | init.flags = CLK_SET_RATE_PARENT; | 172 | init.flags = flags | CLK_SET_RATE_PARENT; |
| 173 | init.parent_names = parent_name ? &parent_name : NULL; | 173 | init.parent_names = parent_name ? &parent_name : NULL; |
| 174 | init.num_parents = parent_name ? 1 : 0; | 174 | init.num_parents = parent_name ? 1 : 0; |
| 175 | init.ops = ops; | 175 | init.ops = ops; |
| 176 | init.flags = flags; | ||
| 177 | 176 | ||
| 178 | cg->regmap = regmap; | 177 | cg->regmap = regmap; |
| 179 | cg->set_ofs = set_ofs; | 178 | cg->set_ofs = set_ofs; |
diff --git a/drivers/clk/meson/clk-pll.c b/drivers/clk/meson/clk-pll.c index 41e16dd7272a..7a14ac9b2fec 100644 --- a/drivers/clk/meson/clk-pll.c +++ b/drivers/clk/meson/clk-pll.c | |||
| @@ -120,7 +120,7 @@ static bool meson_clk_pll_is_better(unsigned long rate, | |||
| 120 | return true; | 120 | return true; |
| 121 | } else { | 121 | } else { |
| 122 | /* Round down */ | 122 | /* Round down */ |
| 123 | if (now < rate && best < now) | 123 | if (now <= rate && best < now) |
| 124 | return true; | 124 | return true; |
| 125 | } | 125 | } |
| 126 | 126 | ||
diff --git a/drivers/clk/meson/g12a.c b/drivers/clk/meson/g12a.c index 0e1ce8c03259..f7b11e1eeebe 100644 --- a/drivers/clk/meson/g12a.c +++ b/drivers/clk/meson/g12a.c | |||
| @@ -960,14 +960,14 @@ static struct clk_regmap g12a_sd_emmc_c_clk0 = { | |||
| 960 | /* VPU Clock */ | 960 | /* VPU Clock */ |
| 961 | 961 | ||
| 962 | static const char * const g12a_vpu_parent_names[] = { | 962 | static const char * const g12a_vpu_parent_names[] = { |
| 963 | "fclk_div4", "fclk_div3", "fclk_div5", "fclk_div7", | 963 | "fclk_div3", "fclk_div4", "fclk_div5", "fclk_div7", |
| 964 | "mpll1", "vid_pll", "hifi_pll", "gp0_pll", | 964 | "mpll1", "vid_pll", "hifi_pll", "gp0_pll", |
| 965 | }; | 965 | }; |
| 966 | 966 | ||
| 967 | static struct clk_regmap g12a_vpu_0_sel = { | 967 | static struct clk_regmap g12a_vpu_0_sel = { |
| 968 | .data = &(struct clk_regmap_mux_data){ | 968 | .data = &(struct clk_regmap_mux_data){ |
| 969 | .offset = HHI_VPU_CLK_CNTL, | 969 | .offset = HHI_VPU_CLK_CNTL, |
| 970 | .mask = 0x3, | 970 | .mask = 0x7, |
| 971 | .shift = 9, | 971 | .shift = 9, |
| 972 | }, | 972 | }, |
| 973 | .hw.init = &(struct clk_init_data){ | 973 | .hw.init = &(struct clk_init_data){ |
| @@ -1011,7 +1011,7 @@ static struct clk_regmap g12a_vpu_0 = { | |||
| 1011 | static struct clk_regmap g12a_vpu_1_sel = { | 1011 | static struct clk_regmap g12a_vpu_1_sel = { |
| 1012 | .data = &(struct clk_regmap_mux_data){ | 1012 | .data = &(struct clk_regmap_mux_data){ |
| 1013 | .offset = HHI_VPU_CLK_CNTL, | 1013 | .offset = HHI_VPU_CLK_CNTL, |
| 1014 | .mask = 0x3, | 1014 | .mask = 0x7, |
| 1015 | .shift = 25, | 1015 | .shift = 25, |
| 1016 | }, | 1016 | }, |
| 1017 | .hw.init = &(struct clk_init_data){ | 1017 | .hw.init = &(struct clk_init_data){ |
diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c index 04df2e208ed6..29ffb4fde714 100644 --- a/drivers/clk/meson/gxbb.c +++ b/drivers/clk/meson/gxbb.c | |||
| @@ -2216,6 +2216,7 @@ static struct clk_regmap gxbb_vdec_1_div = { | |||
| 2216 | .offset = HHI_VDEC_CLK_CNTL, | 2216 | .offset = HHI_VDEC_CLK_CNTL, |
| 2217 | .shift = 0, | 2217 | .shift = 0, |
| 2218 | .width = 7, | 2218 | .width = 7, |
| 2219 | .flags = CLK_DIVIDER_ROUND_CLOSEST, | ||
| 2219 | }, | 2220 | }, |
| 2220 | .hw.init = &(struct clk_init_data){ | 2221 | .hw.init = &(struct clk_init_data){ |
| 2221 | .name = "vdec_1_div", | 2222 | .name = "vdec_1_div", |
| @@ -2261,6 +2262,7 @@ static struct clk_regmap gxbb_vdec_hevc_div = { | |||
| 2261 | .offset = HHI_VDEC2_CLK_CNTL, | 2262 | .offset = HHI_VDEC2_CLK_CNTL, |
| 2262 | .shift = 16, | 2263 | .shift = 16, |
| 2263 | .width = 7, | 2264 | .width = 7, |
| 2265 | .flags = CLK_DIVIDER_ROUND_CLOSEST, | ||
| 2264 | }, | 2266 | }, |
| 2265 | .hw.init = &(struct clk_init_data){ | 2267 | .hw.init = &(struct clk_init_data){ |
| 2266 | .name = "vdec_hevc_div", | 2268 | .name = "vdec_hevc_div", |
diff --git a/drivers/clk/meson/vid-pll-div.c b/drivers/clk/meson/vid-pll-div.c index 08bcc01c0923..daff235bc763 100644 --- a/drivers/clk/meson/vid-pll-div.c +++ b/drivers/clk/meson/vid-pll-div.c | |||
| @@ -82,8 +82,8 @@ static unsigned long meson_vid_pll_div_recalc_rate(struct clk_hw *hw, | |||
| 82 | div = _get_table_val(meson_parm_read(clk->map, &pll_div->val), | 82 | div = _get_table_val(meson_parm_read(clk->map, &pll_div->val), |
| 83 | meson_parm_read(clk->map, &pll_div->sel)); | 83 | meson_parm_read(clk->map, &pll_div->sel)); |
| 84 | if (!div || !div->divider) { | 84 | if (!div || !div->divider) { |
| 85 | pr_info("%s: Invalid config value for vid_pll_div\n", __func__); | 85 | pr_debug("%s: Invalid config value for vid_pll_div\n", __func__); |
| 86 | return parent_rate; | 86 | return 0; |
| 87 | } | 87 | } |
| 88 | 88 | ||
| 89 | return DIV_ROUND_UP_ULL(parent_rate * div->multiplier, div->divider); | 89 | return DIV_ROUND_UP_ULL(parent_rate * div->multiplier, div->divider); |
diff --git a/drivers/clk/x86/clk-pmc-atom.c b/drivers/clk/x86/clk-pmc-atom.c index d977193842df..19174835693b 100644 --- a/drivers/clk/x86/clk-pmc-atom.c +++ b/drivers/clk/x86/clk-pmc-atom.c | |||
| @@ -165,7 +165,7 @@ static const struct clk_ops plt_clk_ops = { | |||
| 165 | }; | 165 | }; |
| 166 | 166 | ||
| 167 | static struct clk_plt *plt_clk_register(struct platform_device *pdev, int id, | 167 | static struct clk_plt *plt_clk_register(struct platform_device *pdev, int id, |
| 168 | void __iomem *base, | 168 | const struct pmc_clk_data *pmc_data, |
| 169 | const char **parent_names, | 169 | const char **parent_names, |
| 170 | int num_parents) | 170 | int num_parents) |
| 171 | { | 171 | { |
| @@ -184,9 +184,17 @@ static struct clk_plt *plt_clk_register(struct platform_device *pdev, int id, | |||
| 184 | init.num_parents = num_parents; | 184 | init.num_parents = num_parents; |
| 185 | 185 | ||
| 186 | pclk->hw.init = &init; | 186 | pclk->hw.init = &init; |
| 187 | pclk->reg = base + PMC_CLK_CTL_OFFSET + id * PMC_CLK_CTL_SIZE; | 187 | pclk->reg = pmc_data->base + PMC_CLK_CTL_OFFSET + id * PMC_CLK_CTL_SIZE; |
| 188 | spin_lock_init(&pclk->lock); | 188 | spin_lock_init(&pclk->lock); |
| 189 | 189 | ||
| 190 | /* | ||
| 191 | * On some systems, the pmc_plt_clocks already enabled by the | ||
| 192 | * firmware are being marked as critical to avoid them being | ||
| 193 | * gated by the clock framework. | ||
| 194 | */ | ||
| 195 | if (pmc_data->critical && plt_clk_is_enabled(&pclk->hw)) | ||
| 196 | init.flags |= CLK_IS_CRITICAL; | ||
| 197 | |||
| 190 | ret = devm_clk_hw_register(&pdev->dev, &pclk->hw); | 198 | ret = devm_clk_hw_register(&pdev->dev, &pclk->hw); |
| 191 | if (ret) { | 199 | if (ret) { |
| 192 | pclk = ERR_PTR(ret); | 200 | pclk = ERR_PTR(ret); |
| @@ -332,7 +340,7 @@ static int plt_clk_probe(struct platform_device *pdev) | |||
| 332 | return PTR_ERR(parent_names); | 340 | return PTR_ERR(parent_names); |
| 333 | 341 | ||
| 334 | for (i = 0; i < PMC_CLK_NUM; i++) { | 342 | for (i = 0; i < PMC_CLK_NUM; i++) { |
| 335 | data->clks[i] = plt_clk_register(pdev, i, pmc_data->base, | 343 | data->clks[i] = plt_clk_register(pdev, i, pmc_data, |
| 336 | parent_names, data->nparents); | 344 | parent_names, data->nparents); |
| 337 | if (IS_ERR(data->clks[i])) { | 345 | if (IS_ERR(data->clks[i])) { |
| 338 | err = PTR_ERR(data->clks[i]); | 346 | err = PTR_ERR(data->clks[i]); |
diff --git a/drivers/crypto/caam/caamhash.c b/drivers/crypto/caam/caamhash.c index b1eadc6652b5..7205d9f4029e 100644 --- a/drivers/crypto/caam/caamhash.c +++ b/drivers/crypto/caam/caamhash.c | |||
| @@ -865,19 +865,18 @@ static int ahash_update_ctx(struct ahash_request *req) | |||
| 865 | if (ret) | 865 | if (ret) |
| 866 | goto unmap_ctx; | 866 | goto unmap_ctx; |
| 867 | 867 | ||
| 868 | if (mapped_nents) { | 868 | if (mapped_nents) |
| 869 | sg_to_sec4_sg_last(req->src, mapped_nents, | 869 | sg_to_sec4_sg_last(req->src, mapped_nents, |
| 870 | edesc->sec4_sg + sec4_sg_src_index, | 870 | edesc->sec4_sg + sec4_sg_src_index, |
| 871 | 0); | 871 | 0); |
| 872 | if (*next_buflen) | 872 | else |
| 873 | scatterwalk_map_and_copy(next_buf, req->src, | ||
| 874 | to_hash - *buflen, | ||
| 875 | *next_buflen, 0); | ||
| 876 | } else { | ||
| 877 | sg_to_sec4_set_last(edesc->sec4_sg + sec4_sg_src_index - | 873 | sg_to_sec4_set_last(edesc->sec4_sg + sec4_sg_src_index - |
| 878 | 1); | 874 | 1); |
| 879 | } | ||
| 880 | 875 | ||
| 876 | if (*next_buflen) | ||
| 877 | scatterwalk_map_and_copy(next_buf, req->src, | ||
| 878 | to_hash - *buflen, | ||
| 879 | *next_buflen, 0); | ||
| 881 | desc = edesc->hw_desc; | 880 | desc = edesc->hw_desc; |
| 882 | 881 | ||
| 883 | edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg, | 882 | edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg, |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index ac0d646a7b74..5d8b30fd4534 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | |||
| @@ -3173,11 +3173,16 @@ static int amdgpu_device_recover_vram(struct amdgpu_device *adev) | |||
| 3173 | break; | 3173 | break; |
| 3174 | 3174 | ||
| 3175 | if (fence) { | 3175 | if (fence) { |
| 3176 | r = dma_fence_wait_timeout(fence, false, tmo); | 3176 | tmo = dma_fence_wait_timeout(fence, false, tmo); |
| 3177 | dma_fence_put(fence); | 3177 | dma_fence_put(fence); |
| 3178 | fence = next; | 3178 | fence = next; |
| 3179 | if (r <= 0) | 3179 | if (tmo == 0) { |
| 3180 | r = -ETIMEDOUT; | ||
| 3180 | break; | 3181 | break; |
| 3182 | } else if (tmo < 0) { | ||
| 3183 | r = tmo; | ||
| 3184 | break; | ||
| 3185 | } | ||
| 3181 | } else { | 3186 | } else { |
| 3182 | fence = next; | 3187 | fence = next; |
| 3183 | } | 3188 | } |
| @@ -3188,8 +3193,8 @@ static int amdgpu_device_recover_vram(struct amdgpu_device *adev) | |||
| 3188 | tmo = dma_fence_wait_timeout(fence, false, tmo); | 3193 | tmo = dma_fence_wait_timeout(fence, false, tmo); |
| 3189 | dma_fence_put(fence); | 3194 | dma_fence_put(fence); |
| 3190 | 3195 | ||
| 3191 | if (r <= 0 || tmo <= 0) { | 3196 | if (r < 0 || tmo <= 0) { |
| 3192 | DRM_ERROR("recover vram bo from shadow failed\n"); | 3197 | DRM_ERROR("recover vram bo from shadow failed, r is %ld, tmo is %ld\n", r, tmo); |
| 3193 | return -EIO; | 3198 | return -EIO; |
| 3194 | } | 3199 | } |
| 3195 | 3200 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c index 0b8ef2d27d6b..fe393a46f881 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c | |||
| @@ -35,6 +35,7 @@ | |||
| 35 | #include "amdgpu_trace.h" | 35 | #include "amdgpu_trace.h" |
| 36 | 36 | ||
| 37 | #define AMDGPU_IB_TEST_TIMEOUT msecs_to_jiffies(1000) | 37 | #define AMDGPU_IB_TEST_TIMEOUT msecs_to_jiffies(1000) |
| 38 | #define AMDGPU_IB_TEST_GFX_XGMI_TIMEOUT msecs_to_jiffies(2000) | ||
| 38 | 39 | ||
| 39 | /* | 40 | /* |
| 40 | * IB | 41 | * IB |
| @@ -344,6 +345,8 @@ int amdgpu_ib_ring_tests(struct amdgpu_device *adev) | |||
| 344 | * cost waiting for it coming back under RUNTIME only | 345 | * cost waiting for it coming back under RUNTIME only |
| 345 | */ | 346 | */ |
| 346 | tmo_gfx = 8 * AMDGPU_IB_TEST_TIMEOUT; | 347 | tmo_gfx = 8 * AMDGPU_IB_TEST_TIMEOUT; |
| 348 | } else if (adev->gmc.xgmi.hive_id) { | ||
| 349 | tmo_gfx = AMDGPU_IB_TEST_GFX_XGMI_TIMEOUT; | ||
| 347 | } | 350 | } |
| 348 | 351 | ||
| 349 | for (i = 0; i < adev->num_rings; ++i) { | 352 | for (i = 0; i < adev->num_rings; ++i) { |
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device.c b/drivers/gpu/drm/amd/amdkfd/kfd_device.c index 8be9677c0c07..cf9a49f49d3a 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device.c | |||
| @@ -320,6 +320,7 @@ static const struct kfd_deviceid supported_devices[] = { | |||
| 320 | { 0x9876, &carrizo_device_info }, /* Carrizo */ | 320 | { 0x9876, &carrizo_device_info }, /* Carrizo */ |
| 321 | { 0x9877, &carrizo_device_info }, /* Carrizo */ | 321 | { 0x9877, &carrizo_device_info }, /* Carrizo */ |
| 322 | { 0x15DD, &raven_device_info }, /* Raven */ | 322 | { 0x15DD, &raven_device_info }, /* Raven */ |
| 323 | { 0x15D8, &raven_device_info }, /* Raven */ | ||
| 323 | #endif | 324 | #endif |
| 324 | { 0x67A0, &hawaii_device_info }, /* Hawaii */ | 325 | { 0x67A0, &hawaii_device_info }, /* Hawaii */ |
| 325 | { 0x67A1, &hawaii_device_info }, /* Hawaii */ | 326 | { 0x67A1, &hawaii_device_info }, /* Hawaii */ |
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 81127f7d6ed1..3082b55b1e77 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | |||
| @@ -4533,6 +4533,7 @@ static void handle_cursor_update(struct drm_plane *plane, | |||
| 4533 | amdgpu_crtc->cursor_width = plane->state->crtc_w; | 4533 | amdgpu_crtc->cursor_width = plane->state->crtc_w; |
| 4534 | amdgpu_crtc->cursor_height = plane->state->crtc_h; | 4534 | amdgpu_crtc->cursor_height = plane->state->crtc_h; |
| 4535 | 4535 | ||
| 4536 | memset(&attributes, 0, sizeof(attributes)); | ||
| 4536 | attributes.address.high_part = upper_32_bits(address); | 4537 | attributes.address.high_part = upper_32_bits(address); |
| 4537 | attributes.address.low_part = lower_32_bits(address); | 4538 | attributes.address.low_part = lower_32_bits(address); |
| 4538 | attributes.width = plane->state->crtc_w; | 4539 | attributes.width = plane->state->crtc_w; |
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c index 683829466a44..0ba68d41b9c3 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c | |||
| @@ -1150,28 +1150,9 @@ void hubp1_cursor_set_position( | |||
| 1150 | REG_UPDATE(CURSOR_CONTROL, | 1150 | REG_UPDATE(CURSOR_CONTROL, |
| 1151 | CURSOR_ENABLE, cur_en); | 1151 | CURSOR_ENABLE, cur_en); |
| 1152 | 1152 | ||
| 1153 | //account for cases where we see negative offset relative to overlay plane | 1153 | REG_SET_2(CURSOR_POSITION, 0, |
| 1154 | if (src_x_offset < 0 && src_y_offset < 0) { | ||
| 1155 | REG_SET_2(CURSOR_POSITION, 0, | ||
| 1156 | CURSOR_X_POSITION, 0, | ||
| 1157 | CURSOR_Y_POSITION, 0); | ||
| 1158 | x_hotspot -= src_x_offset; | ||
| 1159 | y_hotspot -= src_y_offset; | ||
| 1160 | } else if (src_x_offset < 0) { | ||
| 1161 | REG_SET_2(CURSOR_POSITION, 0, | ||
| 1162 | CURSOR_X_POSITION, 0, | ||
| 1163 | CURSOR_Y_POSITION, pos->y); | ||
| 1164 | x_hotspot -= src_x_offset; | ||
| 1165 | } else if (src_y_offset < 0) { | ||
| 1166 | REG_SET_2(CURSOR_POSITION, 0, | ||
| 1167 | CURSOR_X_POSITION, pos->x, | 1154 | CURSOR_X_POSITION, pos->x, |
| 1168 | CURSOR_Y_POSITION, 0); | 1155 | CURSOR_Y_POSITION, pos->y); |
| 1169 | y_hotspot -= src_y_offset; | ||
| 1170 | } else { | ||
| 1171 | REG_SET_2(CURSOR_POSITION, 0, | ||
| 1172 | CURSOR_X_POSITION, pos->x, | ||
| 1173 | CURSOR_Y_POSITION, pos->y); | ||
| 1174 | } | ||
| 1175 | 1156 | ||
| 1176 | REG_SET_2(CURSOR_HOT_SPOT, 0, | 1157 | REG_SET_2(CURSOR_HOT_SPOT, 0, |
| 1177 | CURSOR_HOT_SPOT_X, x_hotspot, | 1158 | CURSOR_HOT_SPOT_X, x_hotspot, |
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c index a63e5f0dae56..db761329a1e3 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | |||
| @@ -1037,6 +1037,31 @@ void dw_hdmi_phy_i2c_write(struct dw_hdmi *hdmi, unsigned short data, | |||
| 1037 | } | 1037 | } |
| 1038 | EXPORT_SYMBOL_GPL(dw_hdmi_phy_i2c_write); | 1038 | EXPORT_SYMBOL_GPL(dw_hdmi_phy_i2c_write); |
| 1039 | 1039 | ||
| 1040 | /* Filter out invalid setups to avoid configuring SCDC and scrambling */ | ||
| 1041 | static bool dw_hdmi_support_scdc(struct dw_hdmi *hdmi) | ||
| 1042 | { | ||
| 1043 | struct drm_display_info *display = &hdmi->connector.display_info; | ||
| 1044 | |||
| 1045 | /* Completely disable SCDC support for older controllers */ | ||
| 1046 | if (hdmi->version < 0x200a) | ||
| 1047 | return false; | ||
| 1048 | |||
| 1049 | /* Disable if SCDC is not supported, or if an HF-VSDB block is absent */ | ||
| 1050 | if (!display->hdmi.scdc.supported || | ||
| 1051 | !display->hdmi.scdc.scrambling.supported) | ||
| 1052 | return false; | ||
| 1053 | |||
| 1054 | /* | ||
| 1055 | * Disable if display only support low TMDS rates and scrambling | ||
| 1056 | * for low rates is not supported either | ||
| 1057 | */ | ||
| 1058 | if (!display->hdmi.scdc.scrambling.low_rates && | ||
| 1059 | display->max_tmds_clock <= 340000) | ||
| 1060 | return false; | ||
| 1061 | |||
| 1062 | return true; | ||
| 1063 | } | ||
| 1064 | |||
| 1040 | /* | 1065 | /* |
| 1041 | * HDMI2.0 Specifies the following procedure for High TMDS Bit Rates: | 1066 | * HDMI2.0 Specifies the following procedure for High TMDS Bit Rates: |
| 1042 | * - The Source shall suspend transmission of the TMDS clock and data | 1067 | * - The Source shall suspend transmission of the TMDS clock and data |
| @@ -1055,7 +1080,7 @@ void dw_hdmi_set_high_tmds_clock_ratio(struct dw_hdmi *hdmi) | |||
| 1055 | unsigned long mtmdsclock = hdmi->hdmi_data.video_mode.mtmdsclock; | 1080 | unsigned long mtmdsclock = hdmi->hdmi_data.video_mode.mtmdsclock; |
| 1056 | 1081 | ||
| 1057 | /* Control for TMDS Bit Period/TMDS Clock-Period Ratio */ | 1082 | /* Control for TMDS Bit Period/TMDS Clock-Period Ratio */ |
| 1058 | if (hdmi->connector.display_info.hdmi.scdc.supported) { | 1083 | if (dw_hdmi_support_scdc(hdmi)) { |
| 1059 | if (mtmdsclock > HDMI14_MAX_TMDSCLK) | 1084 | if (mtmdsclock > HDMI14_MAX_TMDSCLK) |
| 1060 | drm_scdc_set_high_tmds_clock_ratio(hdmi->ddc, 1); | 1085 | drm_scdc_set_high_tmds_clock_ratio(hdmi->ddc, 1); |
| 1061 | else | 1086 | else |
| @@ -1579,8 +1604,9 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi, | |||
| 1579 | 1604 | ||
| 1580 | /* Set up HDMI_FC_INVIDCONF */ | 1605 | /* Set up HDMI_FC_INVIDCONF */ |
| 1581 | inv_val = (hdmi->hdmi_data.hdcp_enable || | 1606 | inv_val = (hdmi->hdmi_data.hdcp_enable || |
| 1582 | vmode->mtmdsclock > HDMI14_MAX_TMDSCLK || | 1607 | (dw_hdmi_support_scdc(hdmi) && |
| 1583 | hdmi_info->scdc.scrambling.low_rates ? | 1608 | (vmode->mtmdsclock > HDMI14_MAX_TMDSCLK || |
| 1609 | hdmi_info->scdc.scrambling.low_rates)) ? | ||
| 1584 | HDMI_FC_INVIDCONF_HDCP_KEEPOUT_ACTIVE : | 1610 | HDMI_FC_INVIDCONF_HDCP_KEEPOUT_ACTIVE : |
| 1585 | HDMI_FC_INVIDCONF_HDCP_KEEPOUT_INACTIVE); | 1611 | HDMI_FC_INVIDCONF_HDCP_KEEPOUT_INACTIVE); |
| 1586 | 1612 | ||
| @@ -1646,7 +1672,7 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi, | |||
| 1646 | } | 1672 | } |
| 1647 | 1673 | ||
| 1648 | /* Scrambling Control */ | 1674 | /* Scrambling Control */ |
| 1649 | if (hdmi_info->scdc.supported) { | 1675 | if (dw_hdmi_support_scdc(hdmi)) { |
| 1650 | if (vmode->mtmdsclock > HDMI14_MAX_TMDSCLK || | 1676 | if (vmode->mtmdsclock > HDMI14_MAX_TMDSCLK || |
| 1651 | hdmi_info->scdc.scrambling.low_rates) { | 1677 | hdmi_info->scdc.scrambling.low_rates) { |
| 1652 | /* | 1678 | /* |
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index 40ac19848034..fbb76332cc9f 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c | |||
| @@ -1034,7 +1034,7 @@ disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state) | |||
| 1034 | funcs->atomic_disable(crtc, old_crtc_state); | 1034 | funcs->atomic_disable(crtc, old_crtc_state); |
| 1035 | else if (funcs->disable) | 1035 | else if (funcs->disable) |
| 1036 | funcs->disable(crtc); | 1036 | funcs->disable(crtc); |
| 1037 | else | 1037 | else if (funcs->dpms) |
| 1038 | funcs->dpms(crtc, DRM_MODE_DPMS_OFF); | 1038 | funcs->dpms(crtc, DRM_MODE_DPMS_OFF); |
| 1039 | 1039 | ||
| 1040 | if (!(dev->irq_enabled && dev->num_crtcs)) | 1040 | if (!(dev->irq_enabled && dev->num_crtcs)) |
| @@ -1277,10 +1277,9 @@ void drm_atomic_helper_commit_modeset_enables(struct drm_device *dev, | |||
| 1277 | if (new_crtc_state->enable) { | 1277 | if (new_crtc_state->enable) { |
| 1278 | DRM_DEBUG_ATOMIC("enabling [CRTC:%d:%s]\n", | 1278 | DRM_DEBUG_ATOMIC("enabling [CRTC:%d:%s]\n", |
| 1279 | crtc->base.id, crtc->name); | 1279 | crtc->base.id, crtc->name); |
| 1280 | |||
| 1281 | if (funcs->atomic_enable) | 1280 | if (funcs->atomic_enable) |
| 1282 | funcs->atomic_enable(crtc, old_crtc_state); | 1281 | funcs->atomic_enable(crtc, old_crtc_state); |
| 1283 | else | 1282 | else if (funcs->commit) |
| 1284 | funcs->commit(crtc); | 1283 | funcs->commit(crtc); |
| 1285 | } | 1284 | } |
| 1286 | } | 1285 | } |
diff --git a/drivers/gpu/drm/i915/gvt/dmabuf.c b/drivers/gpu/drm/i915/gvt/dmabuf.c index 5d887f7cc0d5..69a9a1b2ea4a 100644 --- a/drivers/gpu/drm/i915/gvt/dmabuf.c +++ b/drivers/gpu/drm/i915/gvt/dmabuf.c | |||
| @@ -209,7 +209,7 @@ static int vgpu_get_plane_info(struct drm_device *dev, | |||
| 209 | struct drm_i915_private *dev_priv = to_i915(dev); | 209 | struct drm_i915_private *dev_priv = to_i915(dev); |
| 210 | struct intel_vgpu_primary_plane_format p; | 210 | struct intel_vgpu_primary_plane_format p; |
| 211 | struct intel_vgpu_cursor_plane_format c; | 211 | struct intel_vgpu_cursor_plane_format c; |
| 212 | int ret; | 212 | int ret, tile_height = 1; |
| 213 | 213 | ||
| 214 | if (plane_id == DRM_PLANE_TYPE_PRIMARY) { | 214 | if (plane_id == DRM_PLANE_TYPE_PRIMARY) { |
| 215 | ret = intel_vgpu_decode_primary_plane(vgpu, &p); | 215 | ret = intel_vgpu_decode_primary_plane(vgpu, &p); |
| @@ -228,12 +228,15 @@ static int vgpu_get_plane_info(struct drm_device *dev, | |||
| 228 | break; | 228 | break; |
| 229 | case PLANE_CTL_TILED_X: | 229 | case PLANE_CTL_TILED_X: |
| 230 | info->drm_format_mod = I915_FORMAT_MOD_X_TILED; | 230 | info->drm_format_mod = I915_FORMAT_MOD_X_TILED; |
| 231 | tile_height = 8; | ||
| 231 | break; | 232 | break; |
| 232 | case PLANE_CTL_TILED_Y: | 233 | case PLANE_CTL_TILED_Y: |
| 233 | info->drm_format_mod = I915_FORMAT_MOD_Y_TILED; | 234 | info->drm_format_mod = I915_FORMAT_MOD_Y_TILED; |
| 235 | tile_height = 32; | ||
| 234 | break; | 236 | break; |
| 235 | case PLANE_CTL_TILED_YF: | 237 | case PLANE_CTL_TILED_YF: |
| 236 | info->drm_format_mod = I915_FORMAT_MOD_Yf_TILED; | 238 | info->drm_format_mod = I915_FORMAT_MOD_Yf_TILED; |
| 239 | tile_height = 32; | ||
| 237 | break; | 240 | break; |
| 238 | default: | 241 | default: |
| 239 | gvt_vgpu_err("invalid tiling mode: %x\n", p.tiled); | 242 | gvt_vgpu_err("invalid tiling mode: %x\n", p.tiled); |
| @@ -264,8 +267,8 @@ static int vgpu_get_plane_info(struct drm_device *dev, | |||
| 264 | return -EINVAL; | 267 | return -EINVAL; |
| 265 | } | 268 | } |
| 266 | 269 | ||
| 267 | info->size = (info->stride * info->height + PAGE_SIZE - 1) | 270 | info->size = (info->stride * roundup(info->height, tile_height) |
| 268 | >> PAGE_SHIFT; | 271 | + PAGE_SIZE - 1) >> PAGE_SHIFT; |
| 269 | if (info->size == 0) { | 272 | if (info->size == 0) { |
| 270 | gvt_vgpu_err("fb size is zero\n"); | 273 | gvt_vgpu_err("fb size is zero\n"); |
| 271 | return -EINVAL; | 274 | return -EINVAL; |
diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c index cf133ef03873..9814773882ec 100644 --- a/drivers/gpu/drm/i915/gvt/gtt.c +++ b/drivers/gpu/drm/i915/gvt/gtt.c | |||
| @@ -750,14 +750,20 @@ static void ppgtt_free_spt(struct intel_vgpu_ppgtt_spt *spt) | |||
| 750 | 750 | ||
| 751 | static void ppgtt_free_all_spt(struct intel_vgpu *vgpu) | 751 | static void ppgtt_free_all_spt(struct intel_vgpu *vgpu) |
| 752 | { | 752 | { |
| 753 | struct intel_vgpu_ppgtt_spt *spt; | 753 | struct intel_vgpu_ppgtt_spt *spt, *spn; |
| 754 | struct radix_tree_iter iter; | 754 | struct radix_tree_iter iter; |
| 755 | void **slot; | 755 | LIST_HEAD(all_spt); |
| 756 | void __rcu **slot; | ||
| 756 | 757 | ||
| 758 | rcu_read_lock(); | ||
| 757 | radix_tree_for_each_slot(slot, &vgpu->gtt.spt_tree, &iter, 0) { | 759 | radix_tree_for_each_slot(slot, &vgpu->gtt.spt_tree, &iter, 0) { |
| 758 | spt = radix_tree_deref_slot(slot); | 760 | spt = radix_tree_deref_slot(slot); |
| 759 | ppgtt_free_spt(spt); | 761 | list_move(&spt->post_shadow_list, &all_spt); |
| 760 | } | 762 | } |
| 763 | rcu_read_unlock(); | ||
| 764 | |||
| 765 | list_for_each_entry_safe(spt, spn, &all_spt, post_shadow_list) | ||
| 766 | ppgtt_free_spt(spt); | ||
| 761 | } | 767 | } |
| 762 | 768 | ||
| 763 | static int ppgtt_handle_guest_write_page_table_bytes( | 769 | static int ppgtt_handle_guest_write_page_table_bytes( |
diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c index d5fcc447d22f..a68addf95c23 100644 --- a/drivers/gpu/drm/i915/gvt/kvmgt.c +++ b/drivers/gpu/drm/i915/gvt/kvmgt.c | |||
| @@ -905,7 +905,7 @@ static inline bool intel_vgpu_in_aperture(struct intel_vgpu *vgpu, u64 off) | |||
| 905 | static int intel_vgpu_aperture_rw(struct intel_vgpu *vgpu, u64 off, | 905 | static int intel_vgpu_aperture_rw(struct intel_vgpu *vgpu, u64 off, |
| 906 | void *buf, unsigned long count, bool is_write) | 906 | void *buf, unsigned long count, bool is_write) |
| 907 | { | 907 | { |
| 908 | void *aperture_va; | 908 | void __iomem *aperture_va; |
| 909 | 909 | ||
| 910 | if (!intel_vgpu_in_aperture(vgpu, off) || | 910 | if (!intel_vgpu_in_aperture(vgpu, off) || |
| 911 | !intel_vgpu_in_aperture(vgpu, off + count)) { | 911 | !intel_vgpu_in_aperture(vgpu, off + count)) { |
| @@ -920,9 +920,9 @@ static int intel_vgpu_aperture_rw(struct intel_vgpu *vgpu, u64 off, | |||
| 920 | return -EIO; | 920 | return -EIO; |
| 921 | 921 | ||
| 922 | if (is_write) | 922 | if (is_write) |
| 923 | memcpy(aperture_va + offset_in_page(off), buf, count); | 923 | memcpy_toio(aperture_va + offset_in_page(off), buf, count); |
| 924 | else | 924 | else |
| 925 | memcpy(buf, aperture_va + offset_in_page(off), count); | 925 | memcpy_fromio(buf, aperture_va + offset_in_page(off), count); |
| 926 | 926 | ||
| 927 | io_mapping_unmap(aperture_va); | 927 | io_mapping_unmap(aperture_va); |
| 928 | 928 | ||
diff --git a/drivers/gpu/drm/i915/icl_dsi.c b/drivers/gpu/drm/i915/icl_dsi.c index 73a7bee24a66..641e0778fa9c 100644 --- a/drivers/gpu/drm/i915/icl_dsi.c +++ b/drivers/gpu/drm/i915/icl_dsi.c | |||
| @@ -323,6 +323,21 @@ static void gen11_dsi_program_esc_clk_div(struct intel_encoder *encoder) | |||
| 323 | } | 323 | } |
| 324 | } | 324 | } |
| 325 | 325 | ||
| 326 | static void get_dsi_io_power_domains(struct drm_i915_private *dev_priv, | ||
| 327 | struct intel_dsi *intel_dsi) | ||
| 328 | { | ||
| 329 | enum port port; | ||
| 330 | |||
| 331 | for_each_dsi_port(port, intel_dsi->ports) { | ||
| 332 | WARN_ON(intel_dsi->io_wakeref[port]); | ||
| 333 | intel_dsi->io_wakeref[port] = | ||
| 334 | intel_display_power_get(dev_priv, | ||
| 335 | port == PORT_A ? | ||
| 336 | POWER_DOMAIN_PORT_DDI_A_IO : | ||
| 337 | POWER_DOMAIN_PORT_DDI_B_IO); | ||
| 338 | } | ||
| 339 | } | ||
| 340 | |||
| 326 | static void gen11_dsi_enable_io_power(struct intel_encoder *encoder) | 341 | static void gen11_dsi_enable_io_power(struct intel_encoder *encoder) |
| 327 | { | 342 | { |
| 328 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); | 343 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); |
| @@ -336,13 +351,7 @@ static void gen11_dsi_enable_io_power(struct intel_encoder *encoder) | |||
| 336 | I915_WRITE(ICL_DSI_IO_MODECTL(port), tmp); | 351 | I915_WRITE(ICL_DSI_IO_MODECTL(port), tmp); |
| 337 | } | 352 | } |
| 338 | 353 | ||
| 339 | for_each_dsi_port(port, intel_dsi->ports) { | 354 | get_dsi_io_power_domains(dev_priv, intel_dsi); |
| 340 | intel_dsi->io_wakeref[port] = | ||
| 341 | intel_display_power_get(dev_priv, | ||
| 342 | port == PORT_A ? | ||
| 343 | POWER_DOMAIN_PORT_DDI_A_IO : | ||
| 344 | POWER_DOMAIN_PORT_DDI_B_IO); | ||
| 345 | } | ||
| 346 | } | 355 | } |
| 347 | 356 | ||
| 348 | static void gen11_dsi_power_up_lanes(struct intel_encoder *encoder) | 357 | static void gen11_dsi_power_up_lanes(struct intel_encoder *encoder) |
| @@ -589,6 +598,12 @@ static void gen11_dsi_map_pll(struct intel_encoder *encoder, | |||
| 589 | val |= DPCLKA_CFGCR0_DDI_CLK_SEL(pll->info->id, port); | 598 | val |= DPCLKA_CFGCR0_DDI_CLK_SEL(pll->info->id, port); |
| 590 | } | 599 | } |
| 591 | I915_WRITE(DPCLKA_CFGCR0_ICL, val); | 600 | I915_WRITE(DPCLKA_CFGCR0_ICL, val); |
| 601 | |||
| 602 | for_each_dsi_port(port, intel_dsi->ports) { | ||
| 603 | val &= ~DPCLKA_CFGCR0_DDI_CLK_OFF(port); | ||
| 604 | } | ||
| 605 | I915_WRITE(DPCLKA_CFGCR0_ICL, val); | ||
| 606 | |||
| 592 | POSTING_READ(DPCLKA_CFGCR0_ICL); | 607 | POSTING_READ(DPCLKA_CFGCR0_ICL); |
| 593 | 608 | ||
| 594 | mutex_unlock(&dev_priv->dpll_lock); | 609 | mutex_unlock(&dev_priv->dpll_lock); |
| @@ -1117,7 +1132,7 @@ static void gen11_dsi_disable_port(struct intel_encoder *encoder) | |||
| 1117 | DRM_ERROR("DDI port:%c buffer not idle\n", | 1132 | DRM_ERROR("DDI port:%c buffer not idle\n", |
| 1118 | port_name(port)); | 1133 | port_name(port)); |
| 1119 | } | 1134 | } |
| 1120 | gen11_dsi_ungate_clocks(encoder); | 1135 | gen11_dsi_gate_clocks(encoder); |
| 1121 | } | 1136 | } |
| 1122 | 1137 | ||
| 1123 | static void gen11_dsi_disable_io_power(struct intel_encoder *encoder) | 1138 | static void gen11_dsi_disable_io_power(struct intel_encoder *encoder) |
| @@ -1218,20 +1233,11 @@ static int gen11_dsi_compute_config(struct intel_encoder *encoder, | |||
| 1218 | return 0; | 1233 | return 0; |
| 1219 | } | 1234 | } |
| 1220 | 1235 | ||
| 1221 | static u64 gen11_dsi_get_power_domains(struct intel_encoder *encoder, | 1236 | static void gen11_dsi_get_power_domains(struct intel_encoder *encoder, |
| 1222 | struct intel_crtc_state *crtc_state) | 1237 | struct intel_crtc_state *crtc_state) |
| 1223 | { | 1238 | { |
| 1224 | struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); | 1239 | get_dsi_io_power_domains(to_i915(encoder->base.dev), |
| 1225 | u64 domains = 0; | 1240 | enc_to_intel_dsi(&encoder->base)); |
| 1226 | enum port port; | ||
| 1227 | |||
| 1228 | for_each_dsi_port(port, intel_dsi->ports) | ||
| 1229 | if (port == PORT_A) | ||
| 1230 | domains |= BIT_ULL(POWER_DOMAIN_PORT_DDI_A_IO); | ||
| 1231 | else | ||
| 1232 | domains |= BIT_ULL(POWER_DOMAIN_PORT_DDI_B_IO); | ||
| 1233 | |||
| 1234 | return domains; | ||
| 1235 | } | 1241 | } |
| 1236 | 1242 | ||
| 1237 | static bool gen11_dsi_get_hw_state(struct intel_encoder *encoder, | 1243 | static bool gen11_dsi_get_hw_state(struct intel_encoder *encoder, |
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 14d580cdefd3..ab4e60dfd6a3 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c | |||
| @@ -2075,12 +2075,11 @@ intel_ddi_main_link_aux_domain(struct intel_digital_port *dig_port) | |||
| 2075 | intel_aux_power_domain(dig_port); | 2075 | intel_aux_power_domain(dig_port); |
| 2076 | } | 2076 | } |
| 2077 | 2077 | ||
| 2078 | static u64 intel_ddi_get_power_domains(struct intel_encoder *encoder, | 2078 | static void intel_ddi_get_power_domains(struct intel_encoder *encoder, |
| 2079 | struct intel_crtc_state *crtc_state) | 2079 | struct intel_crtc_state *crtc_state) |
| 2080 | { | 2080 | { |
| 2081 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); | 2081 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); |
| 2082 | struct intel_digital_port *dig_port; | 2082 | struct intel_digital_port *dig_port; |
| 2083 | u64 domains; | ||
| 2084 | 2083 | ||
| 2085 | /* | 2084 | /* |
| 2086 | * TODO: Add support for MST encoders. Atm, the following should never | 2085 | * TODO: Add support for MST encoders. Atm, the following should never |
| @@ -2088,10 +2087,10 @@ static u64 intel_ddi_get_power_domains(struct intel_encoder *encoder, | |||
| 2088 | * hook. | 2087 | * hook. |
| 2089 | */ | 2088 | */ |
| 2090 | if (WARN_ON(intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST))) | 2089 | if (WARN_ON(intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST))) |
| 2091 | return 0; | 2090 | return; |
| 2092 | 2091 | ||
| 2093 | dig_port = enc_to_dig_port(&encoder->base); | 2092 | dig_port = enc_to_dig_port(&encoder->base); |
| 2094 | domains = BIT_ULL(dig_port->ddi_io_power_domain); | 2093 | intel_display_power_get(dev_priv, dig_port->ddi_io_power_domain); |
| 2095 | 2094 | ||
| 2096 | /* | 2095 | /* |
| 2097 | * AUX power is only needed for (e)DP mode, and for HDMI mode on TC | 2096 | * AUX power is only needed for (e)DP mode, and for HDMI mode on TC |
| @@ -2099,15 +2098,15 @@ static u64 intel_ddi_get_power_domains(struct intel_encoder *encoder, | |||
| 2099 | */ | 2098 | */ |
| 2100 | if (intel_crtc_has_dp_encoder(crtc_state) || | 2099 | if (intel_crtc_has_dp_encoder(crtc_state) || |
| 2101 | intel_port_is_tc(dev_priv, encoder->port)) | 2100 | intel_port_is_tc(dev_priv, encoder->port)) |
| 2102 | domains |= BIT_ULL(intel_ddi_main_link_aux_domain(dig_port)); | 2101 | intel_display_power_get(dev_priv, |
| 2102 | intel_ddi_main_link_aux_domain(dig_port)); | ||
| 2103 | 2103 | ||
| 2104 | /* | 2104 | /* |
| 2105 | * VDSC power is needed when DSC is enabled | 2105 | * VDSC power is needed when DSC is enabled |
| 2106 | */ | 2106 | */ |
| 2107 | if (crtc_state->dsc_params.compression_enable) | 2107 | if (crtc_state->dsc_params.compression_enable) |
| 2108 | domains |= BIT_ULL(intel_dsc_power_domain(crtc_state)); | 2108 | intel_display_power_get(dev_priv, |
| 2109 | 2109 | intel_dsc_power_domain(crtc_state)); | |
| 2110 | return domains; | ||
| 2111 | } | 2110 | } |
| 2112 | 2111 | ||
| 2113 | void intel_ddi_enable_pipe_clock(const struct intel_crtc_state *crtc_state) | 2112 | void intel_ddi_enable_pipe_clock(const struct intel_crtc_state *crtc_state) |
| @@ -2825,10 +2824,10 @@ void icl_sanitize_encoder_pll_mapping(struct intel_encoder *encoder) | |||
| 2825 | return; | 2824 | return; |
| 2826 | } | 2825 | } |
| 2827 | /* | 2826 | /* |
| 2828 | * DSI ports should have their DDI clock ungated when disabled | 2827 | * For DSI we keep the ddi clocks gated |
| 2829 | * and gated when enabled. | 2828 | * except during enable/disable sequence. |
| 2830 | */ | 2829 | */ |
| 2831 | ddi_clk_needed = !encoder->base.crtc; | 2830 | ddi_clk_needed = false; |
| 2832 | } | 2831 | } |
| 2833 | 2832 | ||
| 2834 | val = I915_READ(DPCLKA_CFGCR0_ICL); | 2833 | val = I915_READ(DPCLKA_CFGCR0_ICL); |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index ccb616351bba..421aac80a838 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
| @@ -15986,8 +15986,6 @@ get_encoder_power_domains(struct drm_i915_private *dev_priv) | |||
| 15986 | struct intel_encoder *encoder; | 15986 | struct intel_encoder *encoder; |
| 15987 | 15987 | ||
| 15988 | for_each_intel_encoder(&dev_priv->drm, encoder) { | 15988 | for_each_intel_encoder(&dev_priv->drm, encoder) { |
| 15989 | u64 get_domains; | ||
| 15990 | enum intel_display_power_domain domain; | ||
| 15991 | struct intel_crtc_state *crtc_state; | 15989 | struct intel_crtc_state *crtc_state; |
| 15992 | 15990 | ||
| 15993 | if (!encoder->get_power_domains) | 15991 | if (!encoder->get_power_domains) |
| @@ -16001,9 +15999,7 @@ get_encoder_power_domains(struct drm_i915_private *dev_priv) | |||
| 16001 | continue; | 15999 | continue; |
| 16002 | 16000 | ||
| 16003 | crtc_state = to_intel_crtc_state(encoder->base.crtc->state); | 16001 | crtc_state = to_intel_crtc_state(encoder->base.crtc->state); |
| 16004 | get_domains = encoder->get_power_domains(encoder, crtc_state); | 16002 | encoder->get_power_domains(encoder, crtc_state); |
| 16005 | for_each_power_domain(domain, get_domains) | ||
| 16006 | intel_display_power_get(dev_priv, domain); | ||
| 16007 | } | 16003 | } |
| 16008 | } | 16004 | } |
| 16009 | 16005 | ||
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index cf709835fb9a..8891f29a8c7f 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
| @@ -1859,42 +1859,6 @@ intel_dp_compute_link_config_wide(struct intel_dp *intel_dp, | |||
| 1859 | return -EINVAL; | 1859 | return -EINVAL; |
| 1860 | } | 1860 | } |
| 1861 | 1861 | ||
| 1862 | /* Optimize link config in order: max bpp, min lanes, min clock */ | ||
| 1863 | static int | ||
| 1864 | intel_dp_compute_link_config_fast(struct intel_dp *intel_dp, | ||
| 1865 | struct intel_crtc_state *pipe_config, | ||
| 1866 | const struct link_config_limits *limits) | ||
| 1867 | { | ||
| 1868 | struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode; | ||
| 1869 | int bpp, clock, lane_count; | ||
| 1870 | int mode_rate, link_clock, link_avail; | ||
| 1871 | |||
| 1872 | for (bpp = limits->max_bpp; bpp >= limits->min_bpp; bpp -= 2 * 3) { | ||
| 1873 | mode_rate = intel_dp_link_required(adjusted_mode->crtc_clock, | ||
| 1874 | bpp); | ||
| 1875 | |||
| 1876 | for (lane_count = limits->min_lane_count; | ||
| 1877 | lane_count <= limits->max_lane_count; | ||
| 1878 | lane_count <<= 1) { | ||
| 1879 | for (clock = limits->min_clock; clock <= limits->max_clock; clock++) { | ||
| 1880 | link_clock = intel_dp->common_rates[clock]; | ||
| 1881 | link_avail = intel_dp_max_data_rate(link_clock, | ||
| 1882 | lane_count); | ||
| 1883 | |||
| 1884 | if (mode_rate <= link_avail) { | ||
| 1885 | pipe_config->lane_count = lane_count; | ||
| 1886 | pipe_config->pipe_bpp = bpp; | ||
| 1887 | pipe_config->port_clock = link_clock; | ||
| 1888 | |||
| 1889 | return 0; | ||
| 1890 | } | ||
| 1891 | } | ||
| 1892 | } | ||
| 1893 | } | ||
| 1894 | |||
| 1895 | return -EINVAL; | ||
| 1896 | } | ||
| 1897 | |||
| 1898 | static int intel_dp_dsc_compute_bpp(struct intel_dp *intel_dp, u8 dsc_max_bpc) | 1862 | static int intel_dp_dsc_compute_bpp(struct intel_dp *intel_dp, u8 dsc_max_bpc) |
| 1899 | { | 1863 | { |
| 1900 | int i, num_bpc; | 1864 | int i, num_bpc; |
| @@ -2031,15 +1995,13 @@ intel_dp_compute_link_config(struct intel_encoder *encoder, | |||
| 2031 | limits.min_bpp = 6 * 3; | 1995 | limits.min_bpp = 6 * 3; |
| 2032 | limits.max_bpp = intel_dp_compute_bpp(intel_dp, pipe_config); | 1996 | limits.max_bpp = intel_dp_compute_bpp(intel_dp, pipe_config); |
| 2033 | 1997 | ||
| 2034 | if (intel_dp_is_edp(intel_dp) && intel_dp->edp_dpcd[0] < DP_EDP_14) { | 1998 | if (intel_dp_is_edp(intel_dp)) { |
| 2035 | /* | 1999 | /* |
| 2036 | * Use the maximum clock and number of lanes the eDP panel | 2000 | * Use the maximum clock and number of lanes the eDP panel |
| 2037 | * advertizes being capable of. The eDP 1.3 and earlier panels | 2001 | * advertizes being capable of. The panels are generally |
| 2038 | * are generally designed to support only a single clock and | 2002 | * designed to support only a single clock and lane |
| 2039 | * lane configuration, and typically these values correspond to | 2003 | * configuration, and typically these values correspond to the |
| 2040 | * the native resolution of the panel. With eDP 1.4 rate select | 2004 | * native resolution of the panel. |
| 2041 | * and DSC, this is decreasingly the case, and we need to be | ||
| 2042 | * able to select less than maximum link config. | ||
| 2043 | */ | 2005 | */ |
| 2044 | limits.min_lane_count = limits.max_lane_count; | 2006 | limits.min_lane_count = limits.max_lane_count; |
| 2045 | limits.min_clock = limits.max_clock; | 2007 | limits.min_clock = limits.max_clock; |
| @@ -2053,22 +2015,11 @@ intel_dp_compute_link_config(struct intel_encoder *encoder, | |||
| 2053 | intel_dp->common_rates[limits.max_clock], | 2015 | intel_dp->common_rates[limits.max_clock], |
| 2054 | limits.max_bpp, adjusted_mode->crtc_clock); | 2016 | limits.max_bpp, adjusted_mode->crtc_clock); |
| 2055 | 2017 | ||
| 2056 | if (intel_dp_is_edp(intel_dp)) | 2018 | /* |
| 2057 | /* | 2019 | * Optimize for slow and wide. This is the place to add alternative |
| 2058 | * Optimize for fast and narrow. eDP 1.3 section 3.3 and eDP 1.4 | 2020 | * optimization policy. |
| 2059 | * section A.1: "It is recommended that the minimum number of | 2021 | */ |
| 2060 | * lanes be used, using the minimum link rate allowed for that | 2022 | ret = intel_dp_compute_link_config_wide(intel_dp, pipe_config, &limits); |
| 2061 | * lane configuration." | ||
| 2062 | * | ||
| 2063 | * Note that we use the max clock and lane count for eDP 1.3 and | ||
| 2064 | * earlier, and fast vs. wide is irrelevant. | ||
| 2065 | */ | ||
| 2066 | ret = intel_dp_compute_link_config_fast(intel_dp, pipe_config, | ||
| 2067 | &limits); | ||
| 2068 | else | ||
| 2069 | /* Optimize for slow and wide. */ | ||
| 2070 | ret = intel_dp_compute_link_config_wide(intel_dp, pipe_config, | ||
| 2071 | &limits); | ||
| 2072 | 2023 | ||
| 2073 | /* enable compression if the mode doesn't fit available BW */ | 2024 | /* enable compression if the mode doesn't fit available BW */ |
| 2074 | DRM_DEBUG_KMS("Force DSC en = %d\n", intel_dp->force_dsc_en); | 2025 | DRM_DEBUG_KMS("Force DSC en = %d\n", intel_dp->force_dsc_en); |
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 15db41394b9e..d5660ac1b0d6 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
| @@ -270,10 +270,12 @@ struct intel_encoder { | |||
| 270 | * be set correctly before calling this function. */ | 270 | * be set correctly before calling this function. */ |
| 271 | void (*get_config)(struct intel_encoder *, | 271 | void (*get_config)(struct intel_encoder *, |
| 272 | struct intel_crtc_state *pipe_config); | 272 | struct intel_crtc_state *pipe_config); |
| 273 | /* Returns a mask of power domains that need to be referenced as part | 273 | /* |
| 274 | * of the hardware state readout code. */ | 274 | * Acquires the power domains needed for an active encoder during |
| 275 | u64 (*get_power_domains)(struct intel_encoder *encoder, | 275 | * hardware state readout. |
| 276 | struct intel_crtc_state *crtc_state); | 276 | */ |
| 277 | void (*get_power_domains)(struct intel_encoder *encoder, | ||
| 278 | struct intel_crtc_state *crtc_state); | ||
| 277 | /* | 279 | /* |
| 278 | * Called during system suspend after all pending requests for the | 280 | * Called during system suspend after all pending requests for the |
| 279 | * encoder are flushed (for example for DP AUX transactions) and | 281 | * encoder are flushed (for example for DP AUX transactions) and |
diff --git a/drivers/gpu/drm/i915/vlv_dsi.c b/drivers/gpu/drm/i915/vlv_dsi.c index 6403728fe778..31c93c3ccd00 100644 --- a/drivers/gpu/drm/i915/vlv_dsi.c +++ b/drivers/gpu/drm/i915/vlv_dsi.c | |||
| @@ -256,6 +256,28 @@ static void band_gap_reset(struct drm_i915_private *dev_priv) | |||
| 256 | mutex_unlock(&dev_priv->sb_lock); | 256 | mutex_unlock(&dev_priv->sb_lock); |
| 257 | } | 257 | } |
| 258 | 258 | ||
| 259 | static int bdw_get_pipemisc_bpp(struct intel_crtc *crtc) | ||
| 260 | { | ||
| 261 | struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); | ||
| 262 | u32 tmp; | ||
| 263 | |||
| 264 | tmp = I915_READ(PIPEMISC(crtc->pipe)); | ||
| 265 | |||
| 266 | switch (tmp & PIPEMISC_DITHER_BPC_MASK) { | ||
| 267 | case PIPEMISC_DITHER_6_BPC: | ||
| 268 | return 18; | ||
| 269 | case PIPEMISC_DITHER_8_BPC: | ||
| 270 | return 24; | ||
| 271 | case PIPEMISC_DITHER_10_BPC: | ||
| 272 | return 30; | ||
| 273 | case PIPEMISC_DITHER_12_BPC: | ||
| 274 | return 36; | ||
| 275 | default: | ||
| 276 | MISSING_CASE(tmp); | ||
| 277 | return 0; | ||
| 278 | } | ||
| 279 | } | ||
| 280 | |||
| 259 | static int intel_dsi_compute_config(struct intel_encoder *encoder, | 281 | static int intel_dsi_compute_config(struct intel_encoder *encoder, |
| 260 | struct intel_crtc_state *pipe_config, | 282 | struct intel_crtc_state *pipe_config, |
| 261 | struct drm_connector_state *conn_state) | 283 | struct drm_connector_state *conn_state) |
| @@ -1071,6 +1093,8 @@ static void bxt_dsi_get_pipe_config(struct intel_encoder *encoder, | |||
| 1071 | bpp = mipi_dsi_pixel_format_to_bpp( | 1093 | bpp = mipi_dsi_pixel_format_to_bpp( |
| 1072 | pixel_format_from_register_bits(fmt)); | 1094 | pixel_format_from_register_bits(fmt)); |
| 1073 | 1095 | ||
| 1096 | pipe_config->pipe_bpp = bdw_get_pipemisc_bpp(crtc); | ||
| 1097 | |||
| 1074 | /* Enable Frame time stamo based scanline reporting */ | 1098 | /* Enable Frame time stamo based scanline reporting */ |
| 1075 | adjusted_mode->private_flags |= | 1099 | adjusted_mode->private_flags |= |
| 1076 | I915_MODE_FLAG_GET_SCANLINE_FROM_TIMESTAMP; | 1100 | I915_MODE_FLAG_GET_SCANLINE_FROM_TIMESTAMP; |
diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c index 22e68a100e7b..5d333138f913 100644 --- a/drivers/gpu/drm/mediatek/mtk_dpi.c +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c | |||
| @@ -662,13 +662,11 @@ static unsigned int mt8173_calculate_factor(int clock) | |||
| 662 | static unsigned int mt2701_calculate_factor(int clock) | 662 | static unsigned int mt2701_calculate_factor(int clock) |
| 663 | { | 663 | { |
| 664 | if (clock <= 64000) | 664 | if (clock <= 64000) |
| 665 | return 16; | ||
| 666 | else if (clock <= 128000) | ||
| 667 | return 8; | ||
| 668 | else if (clock <= 256000) | ||
| 669 | return 4; | 665 | return 4; |
| 670 | else | 666 | else if (clock <= 128000) |
| 671 | return 2; | 667 | return 2; |
| 668 | else | ||
| 669 | return 1; | ||
| 672 | } | 670 | } |
| 673 | 671 | ||
| 674 | static const struct mtk_dpi_conf mt8173_conf = { | 672 | static const struct mtk_dpi_conf mt8173_conf = { |
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c index cf59ea9bccfd..57ce4708ef1b 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c | |||
| @@ -15,6 +15,7 @@ | |||
| 15 | #include <drm/drmP.h> | 15 | #include <drm/drmP.h> |
| 16 | #include <drm/drm_atomic.h> | 16 | #include <drm/drm_atomic.h> |
| 17 | #include <drm/drm_atomic_helper.h> | 17 | #include <drm/drm_atomic_helper.h> |
| 18 | #include <drm/drm_fb_helper.h> | ||
| 18 | #include <drm/drm_gem.h> | 19 | #include <drm/drm_gem.h> |
| 19 | #include <drm/drm_gem_cma_helper.h> | 20 | #include <drm/drm_gem_cma_helper.h> |
| 20 | #include <drm/drm_of.h> | 21 | #include <drm/drm_of.h> |
| @@ -341,6 +342,8 @@ static struct drm_driver mtk_drm_driver = { | |||
| 341 | .gem_prime_get_sg_table = mtk_gem_prime_get_sg_table, | 342 | .gem_prime_get_sg_table = mtk_gem_prime_get_sg_table, |
| 342 | .gem_prime_import_sg_table = mtk_gem_prime_import_sg_table, | 343 | .gem_prime_import_sg_table = mtk_gem_prime_import_sg_table, |
| 343 | .gem_prime_mmap = mtk_drm_gem_mmap_buf, | 344 | .gem_prime_mmap = mtk_drm_gem_mmap_buf, |
| 345 | .gem_prime_vmap = mtk_drm_gem_prime_vmap, | ||
| 346 | .gem_prime_vunmap = mtk_drm_gem_prime_vunmap, | ||
| 344 | .fops = &mtk_drm_fops, | 347 | .fops = &mtk_drm_fops, |
| 345 | 348 | ||
| 346 | .name = DRIVER_NAME, | 349 | .name = DRIVER_NAME, |
| @@ -376,6 +379,10 @@ static int mtk_drm_bind(struct device *dev) | |||
| 376 | if (ret < 0) | 379 | if (ret < 0) |
| 377 | goto err_deinit; | 380 | goto err_deinit; |
| 378 | 381 | ||
| 382 | ret = drm_fbdev_generic_setup(drm, 32); | ||
| 383 | if (ret) | ||
| 384 | DRM_ERROR("Failed to initialize fbdev: %d\n", ret); | ||
| 385 | |||
| 379 | return 0; | 386 | return 0; |
| 380 | 387 | ||
| 381 | err_deinit: | 388 | err_deinit: |
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_gem.c b/drivers/gpu/drm/mediatek/mtk_drm_gem.c index 259b7b0de1d2..38483e9ee071 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_gem.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_gem.c | |||
| @@ -241,3 +241,49 @@ err_gem_free: | |||
| 241 | kfree(mtk_gem); | 241 | kfree(mtk_gem); |
| 242 | return ERR_PTR(ret); | 242 | return ERR_PTR(ret); |
| 243 | } | 243 | } |
| 244 | |||
| 245 | void *mtk_drm_gem_prime_vmap(struct drm_gem_object *obj) | ||
| 246 | { | ||
| 247 | struct mtk_drm_gem_obj *mtk_gem = to_mtk_gem_obj(obj); | ||
| 248 | struct sg_table *sgt; | ||
| 249 | struct sg_page_iter iter; | ||
| 250 | unsigned int npages; | ||
| 251 | unsigned int i = 0; | ||
| 252 | |||
| 253 | if (mtk_gem->kvaddr) | ||
| 254 | return mtk_gem->kvaddr; | ||
| 255 | |||
| 256 | sgt = mtk_gem_prime_get_sg_table(obj); | ||
| 257 | if (IS_ERR(sgt)) | ||
| 258 | return NULL; | ||
| 259 | |||
| 260 | npages = obj->size >> PAGE_SHIFT; | ||
| 261 | mtk_gem->pages = kcalloc(npages, sizeof(*mtk_gem->pages), GFP_KERNEL); | ||
| 262 | if (!mtk_gem->pages) | ||
| 263 | goto out; | ||
| 264 | |||
| 265 | for_each_sg_page(sgt->sgl, &iter, sgt->orig_nents, 0) { | ||
| 266 | mtk_gem->pages[i++] = sg_page_iter_page(&iter); | ||
| 267 | if (i > npages) | ||
| 268 | break; | ||
| 269 | } | ||
| 270 | mtk_gem->kvaddr = vmap(mtk_gem->pages, npages, VM_MAP, | ||
| 271 | pgprot_writecombine(PAGE_KERNEL)); | ||
| 272 | |||
| 273 | out: | ||
| 274 | kfree((void *)sgt); | ||
| 275 | |||
| 276 | return mtk_gem->kvaddr; | ||
| 277 | } | ||
| 278 | |||
| 279 | void mtk_drm_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr) | ||
| 280 | { | ||
| 281 | struct mtk_drm_gem_obj *mtk_gem = to_mtk_gem_obj(obj); | ||
| 282 | |||
| 283 | if (!mtk_gem->pages) | ||
| 284 | return; | ||
| 285 | |||
| 286 | vunmap(vaddr); | ||
| 287 | mtk_gem->kvaddr = 0; | ||
| 288 | kfree((void *)mtk_gem->pages); | ||
| 289 | } | ||
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_gem.h b/drivers/gpu/drm/mediatek/mtk_drm_gem.h index 534639b43a1c..c047a7ef294f 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_gem.h +++ b/drivers/gpu/drm/mediatek/mtk_drm_gem.h | |||
| @@ -37,6 +37,7 @@ struct mtk_drm_gem_obj { | |||
| 37 | dma_addr_t dma_addr; | 37 | dma_addr_t dma_addr; |
| 38 | unsigned long dma_attrs; | 38 | unsigned long dma_attrs; |
| 39 | struct sg_table *sg; | 39 | struct sg_table *sg; |
| 40 | struct page **pages; | ||
| 40 | }; | 41 | }; |
| 41 | 42 | ||
| 42 | #define to_mtk_gem_obj(x) container_of(x, struct mtk_drm_gem_obj, base) | 43 | #define to_mtk_gem_obj(x) container_of(x, struct mtk_drm_gem_obj, base) |
| @@ -52,5 +53,7 @@ int mtk_drm_gem_mmap_buf(struct drm_gem_object *obj, | |||
| 52 | struct sg_table *mtk_gem_prime_get_sg_table(struct drm_gem_object *obj); | 53 | struct sg_table *mtk_gem_prime_get_sg_table(struct drm_gem_object *obj); |
| 53 | struct drm_gem_object *mtk_gem_prime_import_sg_table(struct drm_device *dev, | 54 | struct drm_gem_object *mtk_gem_prime_import_sg_table(struct drm_device *dev, |
| 54 | struct dma_buf_attachment *attach, struct sg_table *sg); | 55 | struct dma_buf_attachment *attach, struct sg_table *sg); |
| 56 | void *mtk_drm_gem_prime_vmap(struct drm_gem_object *obj); | ||
| 57 | void mtk_drm_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr); | ||
| 55 | 58 | ||
| 56 | #endif | 59 | #endif |
diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c index 915cc84621ae..e04e6c293d39 100644 --- a/drivers/gpu/drm/mediatek/mtk_hdmi.c +++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c | |||
| @@ -1480,7 +1480,6 @@ static int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi *hdmi, | |||
| 1480 | if (IS_ERR(regmap)) | 1480 | if (IS_ERR(regmap)) |
| 1481 | ret = PTR_ERR(regmap); | 1481 | ret = PTR_ERR(regmap); |
| 1482 | if (ret) { | 1482 | if (ret) { |
| 1483 | ret = PTR_ERR(regmap); | ||
| 1484 | dev_err(dev, | 1483 | dev_err(dev, |
| 1485 | "Failed to get system configuration registers: %d\n", | 1484 | "Failed to get system configuration registers: %d\n", |
| 1486 | ret); | 1485 | ret); |
| @@ -1516,6 +1515,7 @@ static int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi *hdmi, | |||
| 1516 | of_node_put(remote); | 1515 | of_node_put(remote); |
| 1517 | 1516 | ||
| 1518 | hdmi->ddc_adpt = of_find_i2c_adapter_by_node(i2c_np); | 1517 | hdmi->ddc_adpt = of_find_i2c_adapter_by_node(i2c_np); |
| 1518 | of_node_put(i2c_np); | ||
| 1519 | if (!hdmi->ddc_adpt) { | 1519 | if (!hdmi->ddc_adpt) { |
| 1520 | dev_err(dev, "Failed to get ddc i2c adapter by node\n"); | 1520 | dev_err(dev, "Failed to get ddc i2c adapter by node\n"); |
| 1521 | return -EINVAL; | 1521 | return -EINVAL; |
diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c index 4ef9c57ffd44..5223498502c4 100644 --- a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c +++ b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c | |||
| @@ -15,28 +15,6 @@ static const struct phy_ops mtk_hdmi_phy_dev_ops = { | |||
| 15 | .owner = THIS_MODULE, | 15 | .owner = THIS_MODULE, |
| 16 | }; | 16 | }; |
| 17 | 17 | ||
| 18 | long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate, | ||
| 19 | unsigned long *parent_rate) | ||
| 20 | { | ||
| 21 | struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw); | ||
| 22 | |||
| 23 | hdmi_phy->pll_rate = rate; | ||
| 24 | if (rate <= 74250000) | ||
| 25 | *parent_rate = rate; | ||
| 26 | else | ||
| 27 | *parent_rate = rate / 2; | ||
| 28 | |||
| 29 | return rate; | ||
| 30 | } | ||
| 31 | |||
| 32 | unsigned long mtk_hdmi_pll_recalc_rate(struct clk_hw *hw, | ||
| 33 | unsigned long parent_rate) | ||
| 34 | { | ||
| 35 | struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw); | ||
| 36 | |||
| 37 | return hdmi_phy->pll_rate; | ||
| 38 | } | ||
| 39 | |||
| 40 | void mtk_hdmi_phy_clear_bits(struct mtk_hdmi_phy *hdmi_phy, u32 offset, | 18 | void mtk_hdmi_phy_clear_bits(struct mtk_hdmi_phy *hdmi_phy, u32 offset, |
| 41 | u32 bits) | 19 | u32 bits) |
| 42 | { | 20 | { |
| @@ -110,13 +88,11 @@ mtk_hdmi_phy_dev_get_ops(const struct mtk_hdmi_phy *hdmi_phy) | |||
| 110 | return NULL; | 88 | return NULL; |
| 111 | } | 89 | } |
| 112 | 90 | ||
| 113 | static void mtk_hdmi_phy_clk_get_ops(struct mtk_hdmi_phy *hdmi_phy, | 91 | static void mtk_hdmi_phy_clk_get_data(struct mtk_hdmi_phy *hdmi_phy, |
| 114 | const struct clk_ops **ops) | 92 | struct clk_init_data *clk_init) |
| 115 | { | 93 | { |
| 116 | if (hdmi_phy && hdmi_phy->conf && hdmi_phy->conf->hdmi_phy_clk_ops) | 94 | clk_init->flags = hdmi_phy->conf->flags; |
| 117 | *ops = hdmi_phy->conf->hdmi_phy_clk_ops; | 95 | clk_init->ops = hdmi_phy->conf->hdmi_phy_clk_ops; |
| 118 | else | ||
| 119 | dev_err(hdmi_phy->dev, "Failed to get clk ops of phy\n"); | ||
| 120 | } | 96 | } |
| 121 | 97 | ||
| 122 | static int mtk_hdmi_phy_probe(struct platform_device *pdev) | 98 | static int mtk_hdmi_phy_probe(struct platform_device *pdev) |
| @@ -129,7 +105,6 @@ static int mtk_hdmi_phy_probe(struct platform_device *pdev) | |||
| 129 | struct clk_init_data clk_init = { | 105 | struct clk_init_data clk_init = { |
| 130 | .num_parents = 1, | 106 | .num_parents = 1, |
| 131 | .parent_names = (const char * const *)&ref_clk_name, | 107 | .parent_names = (const char * const *)&ref_clk_name, |
| 132 | .flags = CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE, | ||
| 133 | }; | 108 | }; |
| 134 | 109 | ||
| 135 | struct phy *phy; | 110 | struct phy *phy; |
| @@ -167,7 +142,7 @@ static int mtk_hdmi_phy_probe(struct platform_device *pdev) | |||
| 167 | hdmi_phy->dev = dev; | 142 | hdmi_phy->dev = dev; |
| 168 | hdmi_phy->conf = | 143 | hdmi_phy->conf = |
| 169 | (struct mtk_hdmi_phy_conf *)of_device_get_match_data(dev); | 144 | (struct mtk_hdmi_phy_conf *)of_device_get_match_data(dev); |
| 170 | mtk_hdmi_phy_clk_get_ops(hdmi_phy, &clk_init.ops); | 145 | mtk_hdmi_phy_clk_get_data(hdmi_phy, &clk_init); |
| 171 | hdmi_phy->pll_hw.init = &clk_init; | 146 | hdmi_phy->pll_hw.init = &clk_init; |
| 172 | hdmi_phy->pll = devm_clk_register(dev, &hdmi_phy->pll_hw); | 147 | hdmi_phy->pll = devm_clk_register(dev, &hdmi_phy->pll_hw); |
| 173 | if (IS_ERR(hdmi_phy->pll)) { | 148 | if (IS_ERR(hdmi_phy->pll)) { |
diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h index f39b1fc66612..2d8b3182470d 100644 --- a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h +++ b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h | |||
| @@ -21,6 +21,7 @@ struct mtk_hdmi_phy; | |||
| 21 | 21 | ||
| 22 | struct mtk_hdmi_phy_conf { | 22 | struct mtk_hdmi_phy_conf { |
| 23 | bool tz_disabled; | 23 | bool tz_disabled; |
| 24 | unsigned long flags; | ||
| 24 | const struct clk_ops *hdmi_phy_clk_ops; | 25 | const struct clk_ops *hdmi_phy_clk_ops; |
| 25 | void (*hdmi_phy_enable_tmds)(struct mtk_hdmi_phy *hdmi_phy); | 26 | void (*hdmi_phy_enable_tmds)(struct mtk_hdmi_phy *hdmi_phy); |
| 26 | void (*hdmi_phy_disable_tmds)(struct mtk_hdmi_phy *hdmi_phy); | 27 | void (*hdmi_phy_disable_tmds)(struct mtk_hdmi_phy *hdmi_phy); |
| @@ -48,10 +49,6 @@ void mtk_hdmi_phy_set_bits(struct mtk_hdmi_phy *hdmi_phy, u32 offset, | |||
| 48 | void mtk_hdmi_phy_mask(struct mtk_hdmi_phy *hdmi_phy, u32 offset, | 49 | void mtk_hdmi_phy_mask(struct mtk_hdmi_phy *hdmi_phy, u32 offset, |
| 49 | u32 val, u32 mask); | 50 | u32 val, u32 mask); |
| 50 | struct mtk_hdmi_phy *to_mtk_hdmi_phy(struct clk_hw *hw); | 51 | struct mtk_hdmi_phy *to_mtk_hdmi_phy(struct clk_hw *hw); |
| 51 | long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate, | ||
| 52 | unsigned long *parent_rate); | ||
| 53 | unsigned long mtk_hdmi_pll_recalc_rate(struct clk_hw *hw, | ||
| 54 | unsigned long parent_rate); | ||
| 55 | 52 | ||
| 56 | extern struct platform_driver mtk_hdmi_phy_driver; | 53 | extern struct platform_driver mtk_hdmi_phy_driver; |
| 57 | extern struct mtk_hdmi_phy_conf mtk_hdmi_phy_8173_conf; | 54 | extern struct mtk_hdmi_phy_conf mtk_hdmi_phy_8173_conf; |
diff --git a/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c b/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c index fcc42dc6ea7f..d3cc4022e988 100644 --- a/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c +++ b/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c | |||
| @@ -79,7 +79,6 @@ static int mtk_hdmi_pll_prepare(struct clk_hw *hw) | |||
| 79 | mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SLDO_MASK); | 79 | mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SLDO_MASK); |
| 80 | usleep_range(80, 100); | 80 | usleep_range(80, 100); |
| 81 | mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_MBIAS_LPF_EN); | 81 | mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_MBIAS_LPF_EN); |
| 82 | mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_TX_POSDIV); | ||
| 83 | mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SER_MASK); | 82 | mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SER_MASK); |
| 84 | mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_PRED_MASK); | 83 | mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_PRED_MASK); |
| 85 | mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_DRV_MASK); | 84 | mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_DRV_MASK); |
| @@ -94,7 +93,6 @@ static void mtk_hdmi_pll_unprepare(struct clk_hw *hw) | |||
| 94 | mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_DRV_MASK); | 93 | mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_DRV_MASK); |
| 95 | mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_PRED_MASK); | 94 | mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_PRED_MASK); |
| 96 | mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SER_MASK); | 95 | mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SER_MASK); |
| 97 | mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_TX_POSDIV); | ||
| 98 | mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_MBIAS_LPF_EN); | 96 | mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_MBIAS_LPF_EN); |
| 99 | usleep_range(80, 100); | 97 | usleep_range(80, 100); |
| 100 | mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SLDO_MASK); | 98 | mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SLDO_MASK); |
| @@ -108,6 +106,12 @@ static void mtk_hdmi_pll_unprepare(struct clk_hw *hw) | |||
| 108 | usleep_range(80, 100); | 106 | usleep_range(80, 100); |
| 109 | } | 107 | } |
| 110 | 108 | ||
| 109 | static long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate, | ||
| 110 | unsigned long *parent_rate) | ||
| 111 | { | ||
| 112 | return rate; | ||
| 113 | } | ||
| 114 | |||
| 111 | static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate, | 115 | static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate, |
| 112 | unsigned long parent_rate) | 116 | unsigned long parent_rate) |
| 113 | { | 117 | { |
| @@ -116,13 +120,14 @@ static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate, | |||
| 116 | 120 | ||
| 117 | if (rate <= 64000000) | 121 | if (rate <= 64000000) |
| 118 | pos_div = 3; | 122 | pos_div = 3; |
| 119 | else if (rate <= 12800000) | 123 | else if (rate <= 128000000) |
| 120 | pos_div = 1; | 124 | pos_div = 2; |
| 121 | else | 125 | else |
| 122 | pos_div = 1; | 126 | pos_div = 1; |
| 123 | 127 | ||
| 124 | mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_PREDIV_MASK); | 128 | mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_PREDIV_MASK); |
| 125 | mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_POSDIV_MASK); | 129 | mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_POSDIV_MASK); |
| 130 | mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_TX_POSDIV); | ||
| 126 | mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON6, (0x1 << RG_HTPLL_IC), | 131 | mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON6, (0x1 << RG_HTPLL_IC), |
| 127 | RG_HTPLL_IC_MASK); | 132 | RG_HTPLL_IC_MASK); |
| 128 | mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON6, (0x1 << RG_HTPLL_IR), | 133 | mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON6, (0x1 << RG_HTPLL_IR), |
| @@ -154,6 +159,39 @@ static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate, | |||
| 154 | return 0; | 159 | return 0; |
| 155 | } | 160 | } |
| 156 | 161 | ||
| 162 | static unsigned long mtk_hdmi_pll_recalc_rate(struct clk_hw *hw, | ||
| 163 | unsigned long parent_rate) | ||
| 164 | { | ||
| 165 | struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw); | ||
| 166 | unsigned long out_rate, val; | ||
| 167 | |||
| 168 | val = (readl(hdmi_phy->regs + HDMI_CON6) | ||
| 169 | & RG_HTPLL_PREDIV_MASK) >> RG_HTPLL_PREDIV; | ||
| 170 | switch (val) { | ||
| 171 | case 0x00: | ||
| 172 | out_rate = parent_rate; | ||
| 173 | break; | ||
| 174 | case 0x01: | ||
| 175 | out_rate = parent_rate / 2; | ||
| 176 | break; | ||
| 177 | default: | ||
| 178 | out_rate = parent_rate / 4; | ||
| 179 | break; | ||
| 180 | } | ||
| 181 | |||
| 182 | val = (readl(hdmi_phy->regs + HDMI_CON6) | ||
| 183 | & RG_HTPLL_FBKDIV_MASK) >> RG_HTPLL_FBKDIV; | ||
| 184 | out_rate *= (val + 1) * 2; | ||
| 185 | val = (readl(hdmi_phy->regs + HDMI_CON2) | ||
| 186 | & RG_HDMITX_TX_POSDIV_MASK); | ||
| 187 | out_rate >>= (val >> RG_HDMITX_TX_POSDIV); | ||
| 188 | |||
| 189 | if (readl(hdmi_phy->regs + HDMI_CON2) & RG_HDMITX_EN_TX_POSDIV) | ||
| 190 | out_rate /= 5; | ||
| 191 | |||
| 192 | return out_rate; | ||
| 193 | } | ||
| 194 | |||
| 157 | static const struct clk_ops mtk_hdmi_phy_pll_ops = { | 195 | static const struct clk_ops mtk_hdmi_phy_pll_ops = { |
| 158 | .prepare = mtk_hdmi_pll_prepare, | 196 | .prepare = mtk_hdmi_pll_prepare, |
| 159 | .unprepare = mtk_hdmi_pll_unprepare, | 197 | .unprepare = mtk_hdmi_pll_unprepare, |
| @@ -174,7 +212,6 @@ static void mtk_hdmi_phy_enable_tmds(struct mtk_hdmi_phy *hdmi_phy) | |||
| 174 | mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SLDO_MASK); | 212 | mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SLDO_MASK); |
| 175 | usleep_range(80, 100); | 213 | usleep_range(80, 100); |
| 176 | mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_MBIAS_LPF_EN); | 214 | mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_MBIAS_LPF_EN); |
| 177 | mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_TX_POSDIV); | ||
| 178 | mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SER_MASK); | 215 | mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SER_MASK); |
| 179 | mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_PRED_MASK); | 216 | mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_PRED_MASK); |
| 180 | mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_DRV_MASK); | 217 | mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_DRV_MASK); |
| @@ -186,7 +223,6 @@ static void mtk_hdmi_phy_disable_tmds(struct mtk_hdmi_phy *hdmi_phy) | |||
| 186 | mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_DRV_MASK); | 223 | mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_DRV_MASK); |
| 187 | mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_PRED_MASK); | 224 | mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_PRED_MASK); |
| 188 | mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SER_MASK); | 225 | mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SER_MASK); |
| 189 | mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_TX_POSDIV); | ||
| 190 | mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_MBIAS_LPF_EN); | 226 | mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_MBIAS_LPF_EN); |
| 191 | usleep_range(80, 100); | 227 | usleep_range(80, 100); |
| 192 | mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SLDO_MASK); | 228 | mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SLDO_MASK); |
| @@ -202,6 +238,7 @@ static void mtk_hdmi_phy_disable_tmds(struct mtk_hdmi_phy *hdmi_phy) | |||
| 202 | 238 | ||
| 203 | struct mtk_hdmi_phy_conf mtk_hdmi_phy_2701_conf = { | 239 | struct mtk_hdmi_phy_conf mtk_hdmi_phy_2701_conf = { |
| 204 | .tz_disabled = true, | 240 | .tz_disabled = true, |
| 241 | .flags = CLK_SET_RATE_GATE, | ||
| 205 | .hdmi_phy_clk_ops = &mtk_hdmi_phy_pll_ops, | 242 | .hdmi_phy_clk_ops = &mtk_hdmi_phy_pll_ops, |
| 206 | .hdmi_phy_enable_tmds = mtk_hdmi_phy_enable_tmds, | 243 | .hdmi_phy_enable_tmds = mtk_hdmi_phy_enable_tmds, |
| 207 | .hdmi_phy_disable_tmds = mtk_hdmi_phy_disable_tmds, | 244 | .hdmi_phy_disable_tmds = mtk_hdmi_phy_disable_tmds, |
diff --git a/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c b/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c index ed5916b27658..47f8a2951682 100644 --- a/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c +++ b/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c | |||
| @@ -199,6 +199,20 @@ static void mtk_hdmi_pll_unprepare(struct clk_hw *hw) | |||
| 199 | usleep_range(100, 150); | 199 | usleep_range(100, 150); |
| 200 | } | 200 | } |
| 201 | 201 | ||
| 202 | static long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate, | ||
| 203 | unsigned long *parent_rate) | ||
| 204 | { | ||
| 205 | struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw); | ||
| 206 | |||
| 207 | hdmi_phy->pll_rate = rate; | ||
| 208 | if (rate <= 74250000) | ||
| 209 | *parent_rate = rate; | ||
| 210 | else | ||
| 211 | *parent_rate = rate / 2; | ||
| 212 | |||
| 213 | return rate; | ||
| 214 | } | ||
| 215 | |||
| 202 | static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate, | 216 | static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate, |
| 203 | unsigned long parent_rate) | 217 | unsigned long parent_rate) |
| 204 | { | 218 | { |
| @@ -285,6 +299,14 @@ static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate, | |||
| 285 | return 0; | 299 | return 0; |
| 286 | } | 300 | } |
| 287 | 301 | ||
| 302 | static unsigned long mtk_hdmi_pll_recalc_rate(struct clk_hw *hw, | ||
| 303 | unsigned long parent_rate) | ||
| 304 | { | ||
| 305 | struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw); | ||
| 306 | |||
| 307 | return hdmi_phy->pll_rate; | ||
| 308 | } | ||
| 309 | |||
| 288 | static const struct clk_ops mtk_hdmi_phy_pll_ops = { | 310 | static const struct clk_ops mtk_hdmi_phy_pll_ops = { |
| 289 | .prepare = mtk_hdmi_pll_prepare, | 311 | .prepare = mtk_hdmi_pll_prepare, |
| 290 | .unprepare = mtk_hdmi_pll_unprepare, | 312 | .unprepare = mtk_hdmi_pll_unprepare, |
| @@ -309,6 +331,7 @@ static void mtk_hdmi_phy_disable_tmds(struct mtk_hdmi_phy *hdmi_phy) | |||
| 309 | } | 331 | } |
| 310 | 332 | ||
| 311 | struct mtk_hdmi_phy_conf mtk_hdmi_phy_8173_conf = { | 333 | struct mtk_hdmi_phy_conf mtk_hdmi_phy_8173_conf = { |
| 334 | .flags = CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE, | ||
| 312 | .hdmi_phy_clk_ops = &mtk_hdmi_phy_pll_ops, | 335 | .hdmi_phy_clk_ops = &mtk_hdmi_phy_pll_ops, |
| 313 | .hdmi_phy_enable_tmds = mtk_hdmi_phy_enable_tmds, | 336 | .hdmi_phy_enable_tmds = mtk_hdmi_phy_enable_tmds, |
| 314 | .hdmi_phy_disable_tmds = mtk_hdmi_phy_disable_tmds, | 337 | .hdmi_phy_disable_tmds = mtk_hdmi_phy_disable_tmds, |
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4_cec.c b/drivers/gpu/drm/omapdrm/dss/hdmi4_cec.c index 340383150fb9..ebf9c96d43ee 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi4_cec.c +++ b/drivers/gpu/drm/omapdrm/dss/hdmi4_cec.c | |||
| @@ -175,6 +175,7 @@ static int hdmi_cec_adap_enable(struct cec_adapter *adap, bool enable) | |||
| 175 | REG_FLD_MOD(core->base, HDMI_CORE_SYS_INTR_UNMASK4, 0, 3, 3); | 175 | REG_FLD_MOD(core->base, HDMI_CORE_SYS_INTR_UNMASK4, 0, 3, 3); |
| 176 | hdmi_wp_clear_irqenable(core->wp, HDMI_IRQ_CORE); | 176 | hdmi_wp_clear_irqenable(core->wp, HDMI_IRQ_CORE); |
| 177 | hdmi_wp_set_irqstatus(core->wp, HDMI_IRQ_CORE); | 177 | hdmi_wp_set_irqstatus(core->wp, HDMI_IRQ_CORE); |
| 178 | REG_FLD_MOD(core->wp->base, HDMI_WP_CLK, 0, 5, 0); | ||
| 178 | hdmi4_core_disable(core); | 179 | hdmi4_core_disable(core); |
| 179 | return 0; | 180 | return 0; |
| 180 | } | 181 | } |
| @@ -182,16 +183,24 @@ static int hdmi_cec_adap_enable(struct cec_adapter *adap, bool enable) | |||
| 182 | if (err) | 183 | if (err) |
| 183 | return err; | 184 | return err; |
| 184 | 185 | ||
| 186 | /* | ||
| 187 | * Initialize CEC clock divider: CEC needs 2MHz clock hence | ||
| 188 | * set the divider to 24 to get 48/24=2MHz clock | ||
| 189 | */ | ||
| 190 | REG_FLD_MOD(core->wp->base, HDMI_WP_CLK, 0x18, 5, 0); | ||
| 191 | |||
| 185 | /* Clear TX FIFO */ | 192 | /* Clear TX FIFO */ |
| 186 | if (!hdmi_cec_clear_tx_fifo(adap)) { | 193 | if (!hdmi_cec_clear_tx_fifo(adap)) { |
| 187 | pr_err("cec-%s: could not clear TX FIFO\n", adap->name); | 194 | pr_err("cec-%s: could not clear TX FIFO\n", adap->name); |
| 188 | return -EIO; | 195 | err = -EIO; |
| 196 | goto err_disable_clk; | ||
| 189 | } | 197 | } |
| 190 | 198 | ||
| 191 | /* Clear RX FIFO */ | 199 | /* Clear RX FIFO */ |
| 192 | if (!hdmi_cec_clear_rx_fifo(adap)) { | 200 | if (!hdmi_cec_clear_rx_fifo(adap)) { |
| 193 | pr_err("cec-%s: could not clear RX FIFO\n", adap->name); | 201 | pr_err("cec-%s: could not clear RX FIFO\n", adap->name); |
| 194 | return -EIO; | 202 | err = -EIO; |
| 203 | goto err_disable_clk; | ||
| 195 | } | 204 | } |
| 196 | 205 | ||
| 197 | /* Clear CEC interrupts */ | 206 | /* Clear CEC interrupts */ |
| @@ -236,6 +245,12 @@ static int hdmi_cec_adap_enable(struct cec_adapter *adap, bool enable) | |||
| 236 | hdmi_write_reg(core->base, HDMI_CEC_INT_STATUS_1, temp); | 245 | hdmi_write_reg(core->base, HDMI_CEC_INT_STATUS_1, temp); |
| 237 | } | 246 | } |
| 238 | return 0; | 247 | return 0; |
| 248 | |||
| 249 | err_disable_clk: | ||
| 250 | REG_FLD_MOD(core->wp->base, HDMI_WP_CLK, 0, 5, 0); | ||
| 251 | hdmi4_core_disable(core); | ||
| 252 | |||
| 253 | return err; | ||
| 239 | } | 254 | } |
| 240 | 255 | ||
| 241 | static int hdmi_cec_adap_log_addr(struct cec_adapter *adap, u8 log_addr) | 256 | static int hdmi_cec_adap_log_addr(struct cec_adapter *adap, u8 log_addr) |
| @@ -333,11 +348,8 @@ int hdmi4_cec_init(struct platform_device *pdev, struct hdmi_core_data *core, | |||
| 333 | return ret; | 348 | return ret; |
| 334 | core->wp = wp; | 349 | core->wp = wp; |
| 335 | 350 | ||
| 336 | /* | 351 | /* Disable clock initially, hdmi_cec_adap_enable() manages it */ |
| 337 | * Initialize CEC clock divider: CEC needs 2MHz clock hence | 352 | REG_FLD_MOD(core->wp->base, HDMI_WP_CLK, 0, 5, 0); |
| 338 | * set the devider to 24 to get 48/24=2MHz clock | ||
| 339 | */ | ||
| 340 | REG_FLD_MOD(core->wp->base, HDMI_WP_CLK, 0x18, 5, 0); | ||
| 341 | 353 | ||
| 342 | ret = cec_register_adapter(core->adap, &pdev->dev); | 354 | ret = cec_register_adapter(core->adap, &pdev->dev); |
| 343 | if (ret < 0) { | 355 | if (ret < 0) { |
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4_core.c b/drivers/gpu/drm/omapdrm/dss/hdmi4_core.c index 813ba42f2753..e384b95ad857 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi4_core.c +++ b/drivers/gpu/drm/omapdrm/dss/hdmi4_core.c | |||
| @@ -708,7 +708,7 @@ int hdmi4_audio_config(struct hdmi_core_data *core, struct hdmi_wp_data *wp, | |||
| 708 | else | 708 | else |
| 709 | acore.i2s_cfg.justification = HDMI_AUDIO_JUSTIFY_RIGHT; | 709 | acore.i2s_cfg.justification = HDMI_AUDIO_JUSTIFY_RIGHT; |
| 710 | /* | 710 | /* |
| 711 | * The I2S input word length is twice the lenght given in the IEC-60958 | 711 | * The I2S input word length is twice the length given in the IEC-60958 |
| 712 | * status word. If the word size is greater than | 712 | * status word. If the word size is greater than |
| 713 | * 20 bits, increment by one. | 713 | * 20 bits, increment by one. |
| 714 | */ | 714 | */ |
diff --git a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c index dc47720c99ba..39d8509d96a0 100644 --- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c +++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c | |||
| @@ -48,8 +48,13 @@ static enum drm_mode_status | |||
| 48 | sun8i_dw_hdmi_mode_valid_h6(struct drm_connector *connector, | 48 | sun8i_dw_hdmi_mode_valid_h6(struct drm_connector *connector, |
| 49 | const struct drm_display_mode *mode) | 49 | const struct drm_display_mode *mode) |
| 50 | { | 50 | { |
| 51 | /* This is max for HDMI 2.0b (4K@60Hz) */ | 51 | /* |
| 52 | if (mode->clock > 594000) | 52 | * Controller support maximum of 594 MHz, which correlates to |
| 53 | * 4K@60Hz 4:4:4 or RGB. However, for frequencies greater than | ||
| 54 | * 340 MHz scrambling has to be enabled. Because scrambling is | ||
| 55 | * not yet implemented, just limit to 340 MHz for now. | ||
| 56 | */ | ||
| 57 | if (mode->clock > 340000) | ||
| 53 | return MODE_CLOCK_HIGH; | 58 | return MODE_CLOCK_HIGH; |
| 54 | 59 | ||
| 55 | return MODE_OK; | 60 | return MODE_OK; |
diff --git a/drivers/gpu/drm/sun4i/sun8i_tcon_top.c b/drivers/gpu/drm/sun4i/sun8i_tcon_top.c index fc36e0c10a37..b1e7c76e9c17 100644 --- a/drivers/gpu/drm/sun4i/sun8i_tcon_top.c +++ b/drivers/gpu/drm/sun4i/sun8i_tcon_top.c | |||
| @@ -227,7 +227,7 @@ static int sun8i_tcon_top_bind(struct device *dev, struct device *master, | |||
| 227 | 227 | ||
| 228 | err_unregister_gates: | 228 | err_unregister_gates: |
| 229 | for (i = 0; i < CLK_NUM; i++) | 229 | for (i = 0; i < CLK_NUM; i++) |
| 230 | if (clk_data->hws[i]) | 230 | if (!IS_ERR_OR_NULL(clk_data->hws[i])) |
| 231 | clk_hw_unregister_gate(clk_data->hws[i]); | 231 | clk_hw_unregister_gate(clk_data->hws[i]); |
| 232 | clk_disable_unprepare(tcon_top->bus); | 232 | clk_disable_unprepare(tcon_top->bus); |
| 233 | err_assert_reset: | 233 | err_assert_reset: |
| @@ -245,7 +245,8 @@ static void sun8i_tcon_top_unbind(struct device *dev, struct device *master, | |||
| 245 | 245 | ||
| 246 | of_clk_del_provider(dev->of_node); | 246 | of_clk_del_provider(dev->of_node); |
| 247 | for (i = 0; i < CLK_NUM; i++) | 247 | for (i = 0; i < CLK_NUM; i++) |
| 248 | clk_hw_unregister_gate(clk_data->hws[i]); | 248 | if (clk_data->hws[i]) |
| 249 | clk_hw_unregister_gate(clk_data->hws[i]); | ||
| 249 | 250 | ||
| 250 | clk_disable_unprepare(tcon_top->bus); | 251 | clk_disable_unprepare(tcon_top->bus); |
| 251 | reset_control_assert(tcon_top->rst); | 252 | reset_control_assert(tcon_top->rst); |
diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c index 22cd2d13e272..ff47f890e6ad 100644 --- a/drivers/gpu/drm/udl/udl_drv.c +++ b/drivers/gpu/drm/udl/udl_drv.c | |||
| @@ -52,6 +52,7 @@ static struct drm_driver driver = { | |||
| 52 | .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME, | 52 | .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME, |
| 53 | .load = udl_driver_load, | 53 | .load = udl_driver_load, |
| 54 | .unload = udl_driver_unload, | 54 | .unload = udl_driver_unload, |
| 55 | .release = udl_driver_release, | ||
| 55 | 56 | ||
| 56 | /* gem hooks */ | 57 | /* gem hooks */ |
| 57 | .gem_free_object_unlocked = udl_gem_free_object, | 58 | .gem_free_object_unlocked = udl_gem_free_object, |
diff --git a/drivers/gpu/drm/udl/udl_drv.h b/drivers/gpu/drm/udl/udl_drv.h index e9e9b1ff678e..4ae67d882eae 100644 --- a/drivers/gpu/drm/udl/udl_drv.h +++ b/drivers/gpu/drm/udl/udl_drv.h | |||
| @@ -104,6 +104,7 @@ void udl_urb_completion(struct urb *urb); | |||
| 104 | 104 | ||
| 105 | int udl_driver_load(struct drm_device *dev, unsigned long flags); | 105 | int udl_driver_load(struct drm_device *dev, unsigned long flags); |
| 106 | void udl_driver_unload(struct drm_device *dev); | 106 | void udl_driver_unload(struct drm_device *dev); |
| 107 | void udl_driver_release(struct drm_device *dev); | ||
| 107 | 108 | ||
| 108 | int udl_fbdev_init(struct drm_device *dev); | 109 | int udl_fbdev_init(struct drm_device *dev); |
| 109 | void udl_fbdev_cleanup(struct drm_device *dev); | 110 | void udl_fbdev_cleanup(struct drm_device *dev); |
diff --git a/drivers/gpu/drm/udl/udl_main.c b/drivers/gpu/drm/udl/udl_main.c index 9086d0d1b880..1f8ef34ade24 100644 --- a/drivers/gpu/drm/udl/udl_main.c +++ b/drivers/gpu/drm/udl/udl_main.c | |||
| @@ -379,6 +379,12 @@ void udl_driver_unload(struct drm_device *dev) | |||
| 379 | udl_free_urb_list(dev); | 379 | udl_free_urb_list(dev); |
| 380 | 380 | ||
| 381 | udl_fbdev_cleanup(dev); | 381 | udl_fbdev_cleanup(dev); |
| 382 | udl_modeset_cleanup(dev); | ||
| 383 | kfree(udl); | 382 | kfree(udl); |
| 384 | } | 383 | } |
| 384 | |||
| 385 | void udl_driver_release(struct drm_device *dev) | ||
| 386 | { | ||
| 387 | udl_modeset_cleanup(dev); | ||
| 388 | drm_dev_fini(dev); | ||
| 389 | kfree(dev); | ||
| 390 | } | ||
diff --git a/drivers/gpu/host1x/hw/channel_hw.c b/drivers/gpu/host1x/hw/channel_hw.c index 27101c04a827..4030d64916f0 100644 --- a/drivers/gpu/host1x/hw/channel_hw.c +++ b/drivers/gpu/host1x/hw/channel_hw.c | |||
| @@ -114,7 +114,7 @@ static inline void synchronize_syncpt_base(struct host1x_job *job) | |||
| 114 | 114 | ||
| 115 | static void host1x_channel_set_streamid(struct host1x_channel *channel) | 115 | static void host1x_channel_set_streamid(struct host1x_channel *channel) |
| 116 | { | 116 | { |
| 117 | #if HOST1X_HW >= 6 | 117 | #if IS_ENABLED(CONFIG_IOMMU_API) && HOST1X_HW >= 6 |
| 118 | struct iommu_fwspec *spec = dev_iommu_fwspec_get(channel->dev->parent); | 118 | struct iommu_fwspec *spec = dev_iommu_fwspec_get(channel->dev->parent); |
| 119 | u32 sid = spec ? spec->ids[0] & 0xffff : 0x7f; | 119 | u32 sid = spec ? spec->ids[0] & 0xffff : 0x7f; |
| 120 | 120 | ||
diff --git a/drivers/infiniband/hw/hfi1/chip.c b/drivers/infiniband/hw/hfi1/chip.c index 612f04190ed8..9784c6c0d2ec 100644 --- a/drivers/infiniband/hw/hfi1/chip.c +++ b/drivers/infiniband/hw/hfi1/chip.c | |||
| @@ -13232,7 +13232,7 @@ static int set_up_context_variables(struct hfi1_devdata *dd) | |||
| 13232 | int total_contexts; | 13232 | int total_contexts; |
| 13233 | int ret; | 13233 | int ret; |
| 13234 | unsigned ngroups; | 13234 | unsigned ngroups; |
| 13235 | int qos_rmt_count; | 13235 | int rmt_count; |
| 13236 | int user_rmt_reduced; | 13236 | int user_rmt_reduced; |
| 13237 | u32 n_usr_ctxts; | 13237 | u32 n_usr_ctxts; |
| 13238 | u32 send_contexts = chip_send_contexts(dd); | 13238 | u32 send_contexts = chip_send_contexts(dd); |
| @@ -13294,10 +13294,20 @@ static int set_up_context_variables(struct hfi1_devdata *dd) | |||
| 13294 | n_usr_ctxts = rcv_contexts - total_contexts; | 13294 | n_usr_ctxts = rcv_contexts - total_contexts; |
| 13295 | } | 13295 | } |
| 13296 | 13296 | ||
| 13297 | /* each user context requires an entry in the RMT */ | 13297 | /* |
| 13298 | qos_rmt_count = qos_rmt_entries(dd, NULL, NULL); | 13298 | * The RMT entries are currently allocated as shown below: |
| 13299 | if (qos_rmt_count + n_usr_ctxts > NUM_MAP_ENTRIES) { | 13299 | * 1. QOS (0 to 128 entries); |
| 13300 | user_rmt_reduced = NUM_MAP_ENTRIES - qos_rmt_count; | 13300 | * 2. FECN for PSM (num_user_contexts + num_vnic_contexts); |
| 13301 | * 3. VNIC (num_vnic_contexts). | ||
| 13302 | * It should be noted that PSM FECN oversubscribe num_vnic_contexts | ||
| 13303 | * entries of RMT because both VNIC and PSM could allocate any receive | ||
| 13304 | * context between dd->first_dyn_alloc_text and dd->num_rcv_contexts, | ||
| 13305 | * and PSM FECN must reserve an RMT entry for each possible PSM receive | ||
| 13306 | * context. | ||
| 13307 | */ | ||
| 13308 | rmt_count = qos_rmt_entries(dd, NULL, NULL) + (num_vnic_contexts * 2); | ||
| 13309 | if (rmt_count + n_usr_ctxts > NUM_MAP_ENTRIES) { | ||
| 13310 | user_rmt_reduced = NUM_MAP_ENTRIES - rmt_count; | ||
| 13301 | dd_dev_err(dd, | 13311 | dd_dev_err(dd, |
| 13302 | "RMT size is reducing the number of user receive contexts from %u to %d\n", | 13312 | "RMT size is reducing the number of user receive contexts from %u to %d\n", |
| 13303 | n_usr_ctxts, | 13313 | n_usr_ctxts, |
| @@ -14285,9 +14295,11 @@ static void init_user_fecn_handling(struct hfi1_devdata *dd, | |||
| 14285 | u64 reg; | 14295 | u64 reg; |
| 14286 | int i, idx, regoff, regidx; | 14296 | int i, idx, regoff, regidx; |
| 14287 | u8 offset; | 14297 | u8 offset; |
| 14298 | u32 total_cnt; | ||
| 14288 | 14299 | ||
| 14289 | /* there needs to be enough room in the map table */ | 14300 | /* there needs to be enough room in the map table */ |
| 14290 | if (rmt->used + dd->num_user_contexts >= NUM_MAP_ENTRIES) { | 14301 | total_cnt = dd->num_rcv_contexts - dd->first_dyn_alloc_ctxt; |
| 14302 | if (rmt->used + total_cnt >= NUM_MAP_ENTRIES) { | ||
| 14291 | dd_dev_err(dd, "User FECN handling disabled - too many user contexts allocated\n"); | 14303 | dd_dev_err(dd, "User FECN handling disabled - too many user contexts allocated\n"); |
| 14292 | return; | 14304 | return; |
| 14293 | } | 14305 | } |
| @@ -14341,7 +14353,7 @@ static void init_user_fecn_handling(struct hfi1_devdata *dd, | |||
| 14341 | /* add rule 1 */ | 14353 | /* add rule 1 */ |
| 14342 | add_rsm_rule(dd, RSM_INS_FECN, &rrd); | 14354 | add_rsm_rule(dd, RSM_INS_FECN, &rrd); |
| 14343 | 14355 | ||
| 14344 | rmt->used += dd->num_user_contexts; | 14356 | rmt->used += total_cnt; |
| 14345 | } | 14357 | } |
| 14346 | 14358 | ||
| 14347 | /* Initialize RSM for VNIC */ | 14359 | /* Initialize RSM for VNIC */ |
diff --git a/drivers/infiniband/hw/hfi1/qp.c b/drivers/infiniband/hw/hfi1/qp.c index 9b643c2409cf..eba300330a02 100644 --- a/drivers/infiniband/hw/hfi1/qp.c +++ b/drivers/infiniband/hw/hfi1/qp.c | |||
| @@ -898,7 +898,9 @@ void notify_error_qp(struct rvt_qp *qp) | |||
| 898 | if (!list_empty(&priv->s_iowait.list) && | 898 | if (!list_empty(&priv->s_iowait.list) && |
| 899 | !(qp->s_flags & RVT_S_BUSY) && | 899 | !(qp->s_flags & RVT_S_BUSY) && |
| 900 | !(priv->s_flags & RVT_S_BUSY)) { | 900 | !(priv->s_flags & RVT_S_BUSY)) { |
| 901 | qp->s_flags &= ~RVT_S_ANY_WAIT_IO; | 901 | qp->s_flags &= ~HFI1_S_ANY_WAIT_IO; |
| 902 | iowait_clear_flag(&priv->s_iowait, IOWAIT_PENDING_IB); | ||
| 903 | iowait_clear_flag(&priv->s_iowait, IOWAIT_PENDING_TID); | ||
| 902 | list_del_init(&priv->s_iowait.list); | 904 | list_del_init(&priv->s_iowait.list); |
| 903 | priv->s_iowait.lock = NULL; | 905 | priv->s_iowait.lock = NULL; |
| 904 | rvt_put_qp(qp); | 906 | rvt_put_qp(qp); |
diff --git a/drivers/infiniband/hw/hfi1/rc.c b/drivers/infiniband/hw/hfi1/rc.c index e6726c1ab866..5991211d72bd 100644 --- a/drivers/infiniband/hw/hfi1/rc.c +++ b/drivers/infiniband/hw/hfi1/rc.c | |||
| @@ -3088,7 +3088,7 @@ send_last: | |||
| 3088 | update_ack_queue(qp, next); | 3088 | update_ack_queue(qp, next); |
| 3089 | } | 3089 | } |
| 3090 | e = &qp->s_ack_queue[qp->r_head_ack_queue]; | 3090 | e = &qp->s_ack_queue[qp->r_head_ack_queue]; |
| 3091 | if (e->opcode == OP(RDMA_READ_REQUEST) && e->rdma_sge.mr) { | 3091 | if (e->rdma_sge.mr) { |
| 3092 | rvt_put_mr(e->rdma_sge.mr); | 3092 | rvt_put_mr(e->rdma_sge.mr); |
| 3093 | e->rdma_sge.mr = NULL; | 3093 | e->rdma_sge.mr = NULL; |
| 3094 | } | 3094 | } |
| @@ -3166,7 +3166,7 @@ send_last: | |||
| 3166 | update_ack_queue(qp, next); | 3166 | update_ack_queue(qp, next); |
| 3167 | } | 3167 | } |
| 3168 | e = &qp->s_ack_queue[qp->r_head_ack_queue]; | 3168 | e = &qp->s_ack_queue[qp->r_head_ack_queue]; |
| 3169 | if (e->opcode == OP(RDMA_READ_REQUEST) && e->rdma_sge.mr) { | 3169 | if (e->rdma_sge.mr) { |
| 3170 | rvt_put_mr(e->rdma_sge.mr); | 3170 | rvt_put_mr(e->rdma_sge.mr); |
| 3171 | e->rdma_sge.mr = NULL; | 3171 | e->rdma_sge.mr = NULL; |
| 3172 | } | 3172 | } |
diff --git a/drivers/infiniband/hw/hfi1/tid_rdma.c b/drivers/infiniband/hw/hfi1/tid_rdma.c index fdda33aca77f..43cbce7a19ea 100644 --- a/drivers/infiniband/hw/hfi1/tid_rdma.c +++ b/drivers/infiniband/hw/hfi1/tid_rdma.c | |||
| @@ -5017,24 +5017,14 @@ int hfi1_make_tid_rdma_pkt(struct rvt_qp *qp, struct hfi1_pkt_state *ps) | |||
| 5017 | make_tid_rdma_ack(qp, ohdr, ps)) | 5017 | make_tid_rdma_ack(qp, ohdr, ps)) |
| 5018 | return 1; | 5018 | return 1; |
| 5019 | 5019 | ||
| 5020 | if (!(ib_rvt_state_ops[qp->state] & RVT_PROCESS_SEND_OK)) { | 5020 | /* |
| 5021 | if (!(ib_rvt_state_ops[qp->state] & RVT_FLUSH_SEND)) | 5021 | * Bail out if we can't send data. |
| 5022 | goto bail; | 5022 | * Be reminded that this check must been done after the call to |
| 5023 | /* We are in the error state, flush the work request. */ | 5023 | * make_tid_rdma_ack() because the responding QP could be in |
| 5024 | if (qp->s_last == READ_ONCE(qp->s_head)) | 5024 | * RTR state where it can send TID RDMA ACK, not TID RDMA WRITE DATA. |
| 5025 | goto bail; | 5025 | */ |
| 5026 | /* If DMAs are in progress, we can't flush immediately. */ | 5026 | if (!(ib_rvt_state_ops[qp->state] & RVT_PROCESS_SEND_OK)) |
| 5027 | if (iowait_sdma_pending(&priv->s_iowait)) { | 5027 | goto bail; |
| 5028 | qp->s_flags |= RVT_S_WAIT_DMA; | ||
| 5029 | goto bail; | ||
| 5030 | } | ||
| 5031 | clear_ahg(qp); | ||
| 5032 | wqe = rvt_get_swqe_ptr(qp, qp->s_last); | ||
| 5033 | hfi1_trdma_send_complete(qp, wqe, qp->s_last != qp->s_acked ? | ||
| 5034 | IB_WC_SUCCESS : IB_WC_WR_FLUSH_ERR); | ||
| 5035 | /* will get called again */ | ||
| 5036 | goto done_free_tx; | ||
| 5037 | } | ||
| 5038 | 5028 | ||
| 5039 | if (priv->s_flags & RVT_S_WAIT_ACK) | 5029 | if (priv->s_flags & RVT_S_WAIT_ACK) |
| 5040 | goto bail; | 5030 | goto bail; |
| @@ -5144,11 +5134,6 @@ int hfi1_make_tid_rdma_pkt(struct rvt_qp *qp, struct hfi1_pkt_state *ps) | |||
| 5144 | hfi1_make_ruc_header(qp, ohdr, (opcode << 24), bth1, bth2, | 5134 | hfi1_make_ruc_header(qp, ohdr, (opcode << 24), bth1, bth2, |
| 5145 | middle, ps); | 5135 | middle, ps); |
| 5146 | return 1; | 5136 | return 1; |
| 5147 | done_free_tx: | ||
| 5148 | hfi1_put_txreq(ps->s_txreq); | ||
| 5149 | ps->s_txreq = NULL; | ||
| 5150 | return 1; | ||
| 5151 | |||
| 5152 | bail: | 5137 | bail: |
| 5153 | hfi1_put_txreq(ps->s_txreq); | 5138 | hfi1_put_txreq(ps->s_txreq); |
| 5154 | bail_no_tx: | 5139 | bail_no_tx: |
diff --git a/drivers/infiniband/hw/hns/hns_roce_hem.c b/drivers/infiniband/hw/hns/hns_roce_hem.c index f1fec56f3ff4..8e29dbb5b5fb 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hem.c +++ b/drivers/infiniband/hw/hns/hns_roce_hem.c | |||
| @@ -792,6 +792,8 @@ void *hns_roce_table_find(struct hns_roce_dev *hr_dev, | |||
| 792 | idx_offset = (obj & (table->num_obj - 1)) % obj_per_chunk; | 792 | idx_offset = (obj & (table->num_obj - 1)) % obj_per_chunk; |
| 793 | dma_offset = offset = idx_offset * table->obj_size; | 793 | dma_offset = offset = idx_offset * table->obj_size; |
| 794 | } else { | 794 | } else { |
| 795 | u32 seg_size = 64; /* 8 bytes per BA and 8 BA per segment */ | ||
| 796 | |||
| 795 | hns_roce_calc_hem_mhop(hr_dev, table, &mhop_obj, &mhop); | 797 | hns_roce_calc_hem_mhop(hr_dev, table, &mhop_obj, &mhop); |
| 796 | /* mtt mhop */ | 798 | /* mtt mhop */ |
| 797 | i = mhop.l0_idx; | 799 | i = mhop.l0_idx; |
| @@ -803,8 +805,8 @@ void *hns_roce_table_find(struct hns_roce_dev *hr_dev, | |||
| 803 | hem_idx = i; | 805 | hem_idx = i; |
| 804 | 806 | ||
| 805 | hem = table->hem[hem_idx]; | 807 | hem = table->hem[hem_idx]; |
| 806 | dma_offset = offset = (obj & (table->num_obj - 1)) * | 808 | dma_offset = offset = (obj & (table->num_obj - 1)) * seg_size % |
| 807 | table->obj_size % mhop.bt_chunk_size; | 809 | mhop.bt_chunk_size; |
| 808 | if (mhop.hop_num == 2) | 810 | if (mhop.hop_num == 2) |
| 809 | dma_offset = offset = 0; | 811 | dma_offset = offset = 0; |
| 810 | } | 812 | } |
diff --git a/drivers/infiniband/hw/hns/hns_roce_mr.c b/drivers/infiniband/hw/hns/hns_roce_mr.c index b09f1cde2ff5..08be0e4eabcd 100644 --- a/drivers/infiniband/hw/hns/hns_roce_mr.c +++ b/drivers/infiniband/hw/hns/hns_roce_mr.c | |||
| @@ -746,7 +746,6 @@ static int hns_roce_write_mtt_chunk(struct hns_roce_dev *hr_dev, | |||
| 746 | struct hns_roce_hem_table *table; | 746 | struct hns_roce_hem_table *table; |
| 747 | dma_addr_t dma_handle; | 747 | dma_addr_t dma_handle; |
| 748 | __le64 *mtts; | 748 | __le64 *mtts; |
| 749 | u32 s = start_index * sizeof(u64); | ||
| 750 | u32 bt_page_size; | 749 | u32 bt_page_size; |
| 751 | u32 i; | 750 | u32 i; |
| 752 | 751 | ||
| @@ -780,7 +779,8 @@ static int hns_roce_write_mtt_chunk(struct hns_roce_dev *hr_dev, | |||
| 780 | return -EINVAL; | 779 | return -EINVAL; |
| 781 | 780 | ||
| 782 | mtts = hns_roce_table_find(hr_dev, table, | 781 | mtts = hns_roce_table_find(hr_dev, table, |
| 783 | mtt->first_seg + s / hr_dev->caps.mtt_entry_sz, | 782 | mtt->first_seg + |
| 783 | start_index / HNS_ROCE_MTT_ENTRY_PER_SEG, | ||
| 784 | &dma_handle); | 784 | &dma_handle); |
| 785 | if (!mtts) | 785 | if (!mtts) |
| 786 | return -ENOMEM; | 786 | return -ENOMEM; |
diff --git a/drivers/infiniband/hw/hns/hns_roce_qp.c b/drivers/infiniband/hw/hns/hns_roce_qp.c index 57c76eafef2f..66cdf625534f 100644 --- a/drivers/infiniband/hw/hns/hns_roce_qp.c +++ b/drivers/infiniband/hw/hns/hns_roce_qp.c | |||
| @@ -274,9 +274,6 @@ void hns_roce_qp_free(struct hns_roce_dev *hr_dev, struct hns_roce_qp *hr_qp) | |||
| 274 | wait_for_completion(&hr_qp->free); | 274 | wait_for_completion(&hr_qp->free); |
| 275 | 275 | ||
| 276 | if ((hr_qp->ibqp.qp_type) != IB_QPT_GSI) { | 276 | if ((hr_qp->ibqp.qp_type) != IB_QPT_GSI) { |
| 277 | if (hr_dev->caps.sccc_entry_sz) | ||
| 278 | hns_roce_table_put(hr_dev, &qp_table->sccc_table, | ||
| 279 | hr_qp->qpn); | ||
| 280 | if (hr_dev->caps.trrl_entry_sz) | 277 | if (hr_dev->caps.trrl_entry_sz) |
| 281 | hns_roce_table_put(hr_dev, &qp_table->trrl_table, | 278 | hns_roce_table_put(hr_dev, &qp_table->trrl_table, |
| 282 | hr_qp->qpn); | 279 | hr_qp->qpn); |
diff --git a/drivers/infiniband/hw/mlx5/odp.c b/drivers/infiniband/hw/mlx5/odp.c index c20bfc41ecf1..0aa10ebda5d9 100644 --- a/drivers/infiniband/hw/mlx5/odp.c +++ b/drivers/infiniband/hw/mlx5/odp.c | |||
| @@ -585,7 +585,7 @@ static int pagefault_mr(struct mlx5_ib_dev *dev, struct mlx5_ib_mr *mr, | |||
| 585 | struct ib_umem_odp *odp_mr = to_ib_umem_odp(mr->umem); | 585 | struct ib_umem_odp *odp_mr = to_ib_umem_odp(mr->umem); |
| 586 | bool downgrade = flags & MLX5_PF_FLAGS_DOWNGRADE; | 586 | bool downgrade = flags & MLX5_PF_FLAGS_DOWNGRADE; |
| 587 | bool prefetch = flags & MLX5_PF_FLAGS_PREFETCH; | 587 | bool prefetch = flags & MLX5_PF_FLAGS_PREFETCH; |
| 588 | u64 access_mask = ODP_READ_ALLOWED_BIT; | 588 | u64 access_mask; |
| 589 | u64 start_idx, page_mask; | 589 | u64 start_idx, page_mask; |
| 590 | struct ib_umem_odp *odp; | 590 | struct ib_umem_odp *odp; |
| 591 | size_t size; | 591 | size_t size; |
| @@ -607,6 +607,7 @@ next_mr: | |||
| 607 | page_shift = mr->umem->page_shift; | 607 | page_shift = mr->umem->page_shift; |
| 608 | page_mask = ~(BIT(page_shift) - 1); | 608 | page_mask = ~(BIT(page_shift) - 1); |
| 609 | start_idx = (io_virt - (mr->mmkey.iova & page_mask)) >> page_shift; | 609 | start_idx = (io_virt - (mr->mmkey.iova & page_mask)) >> page_shift; |
| 610 | access_mask = ODP_READ_ALLOWED_BIT; | ||
| 610 | 611 | ||
| 611 | if (prefetch && !downgrade && !mr->umem->writable) { | 612 | if (prefetch && !downgrade && !mr->umem->writable) { |
| 612 | /* prefetch with write-access must | 613 | /* prefetch with write-access must |
diff --git a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_main.c b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_main.c index 6d8b3e0de57a..ec41400fec0c 100644 --- a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_main.c +++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_main.c | |||
| @@ -1131,6 +1131,8 @@ static void pvrdma_pci_remove(struct pci_dev *pdev) | |||
| 1131 | pvrdma_page_dir_cleanup(dev, &dev->cq_pdir); | 1131 | pvrdma_page_dir_cleanup(dev, &dev->cq_pdir); |
| 1132 | pvrdma_page_dir_cleanup(dev, &dev->async_pdir); | 1132 | pvrdma_page_dir_cleanup(dev, &dev->async_pdir); |
| 1133 | pvrdma_free_slots(dev); | 1133 | pvrdma_free_slots(dev); |
| 1134 | dma_free_coherent(&pdev->dev, sizeof(*dev->dsr), dev->dsr, | ||
| 1135 | dev->dsrbase); | ||
| 1134 | 1136 | ||
| 1135 | iounmap(dev->regs); | 1137 | iounmap(dev->regs); |
| 1136 | kfree(dev->sgid_tbl); | 1138 | kfree(dev->sgid_tbl); |
diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c index 1b1378619fc9..ff40ba758cf3 100644 --- a/drivers/iommu/amd_iommu_init.c +++ b/drivers/iommu/amd_iommu_init.c | |||
| @@ -359,7 +359,7 @@ static void iommu_write_l2(struct amd_iommu *iommu, u8 address, u32 val) | |||
| 359 | static void iommu_set_exclusion_range(struct amd_iommu *iommu) | 359 | static void iommu_set_exclusion_range(struct amd_iommu *iommu) |
| 360 | { | 360 | { |
| 361 | u64 start = iommu->exclusion_start & PAGE_MASK; | 361 | u64 start = iommu->exclusion_start & PAGE_MASK; |
| 362 | u64 limit = (start + iommu->exclusion_length) & PAGE_MASK; | 362 | u64 limit = (start + iommu->exclusion_length - 1) & PAGE_MASK; |
| 363 | u64 entry; | 363 | u64 entry; |
| 364 | 364 | ||
| 365 | if (!iommu->exclusion_start) | 365 | if (!iommu->exclusion_start) |
diff --git a/drivers/irqchip/irq-ls1x.c b/drivers/irqchip/irq-ls1x.c index 86b72fbd3b45..353111a10413 100644 --- a/drivers/irqchip/irq-ls1x.c +++ b/drivers/irqchip/irq-ls1x.c | |||
| @@ -130,6 +130,7 @@ static int __init ls1x_intc_of_init(struct device_node *node, | |||
| 130 | NULL); | 130 | NULL); |
| 131 | if (!priv->domain) { | 131 | if (!priv->domain) { |
| 132 | pr_err("ls1x-irq: cannot add IRQ domain\n"); | 132 | pr_err("ls1x-irq: cannot add IRQ domain\n"); |
| 133 | err = -ENOMEM; | ||
| 133 | goto out_iounmap; | 134 | goto out_iounmap; |
| 134 | } | 135 | } |
| 135 | 136 | ||
diff --git a/drivers/mmc/host/alcor.c b/drivers/mmc/host/alcor.c index 82a97866e0cf..7c8f203f9a24 100644 --- a/drivers/mmc/host/alcor.c +++ b/drivers/mmc/host/alcor.c | |||
| @@ -48,7 +48,6 @@ struct alcor_sdmmc_host { | |||
| 48 | struct mmc_command *cmd; | 48 | struct mmc_command *cmd; |
| 49 | struct mmc_data *data; | 49 | struct mmc_data *data; |
| 50 | unsigned int dma_on:1; | 50 | unsigned int dma_on:1; |
| 51 | unsigned int early_data:1; | ||
| 52 | 51 | ||
| 53 | struct mutex cmd_mutex; | 52 | struct mutex cmd_mutex; |
| 54 | 53 | ||
| @@ -144,8 +143,7 @@ static void alcor_data_set_dma(struct alcor_sdmmc_host *host) | |||
| 144 | host->sg_count--; | 143 | host->sg_count--; |
| 145 | } | 144 | } |
| 146 | 145 | ||
| 147 | static void alcor_trigger_data_transfer(struct alcor_sdmmc_host *host, | 146 | static void alcor_trigger_data_transfer(struct alcor_sdmmc_host *host) |
| 148 | bool early) | ||
| 149 | { | 147 | { |
| 150 | struct alcor_pci_priv *priv = host->alcor_pci; | 148 | struct alcor_pci_priv *priv = host->alcor_pci; |
| 151 | struct mmc_data *data = host->data; | 149 | struct mmc_data *data = host->data; |
| @@ -155,13 +153,6 @@ static void alcor_trigger_data_transfer(struct alcor_sdmmc_host *host, | |||
| 155 | ctrl |= AU6601_DATA_WRITE; | 153 | ctrl |= AU6601_DATA_WRITE; |
| 156 | 154 | ||
| 157 | if (data->host_cookie == COOKIE_MAPPED) { | 155 | if (data->host_cookie == COOKIE_MAPPED) { |
| 158 | if (host->early_data) { | ||
| 159 | host->early_data = false; | ||
| 160 | return; | ||
| 161 | } | ||
| 162 | |||
| 163 | host->early_data = early; | ||
| 164 | |||
| 165 | alcor_data_set_dma(host); | 156 | alcor_data_set_dma(host); |
| 166 | ctrl |= AU6601_DATA_DMA_MODE; | 157 | ctrl |= AU6601_DATA_DMA_MODE; |
| 167 | host->dma_on = 1; | 158 | host->dma_on = 1; |
| @@ -231,6 +222,7 @@ static void alcor_prepare_sg_miter(struct alcor_sdmmc_host *host) | |||
| 231 | static void alcor_prepare_data(struct alcor_sdmmc_host *host, | 222 | static void alcor_prepare_data(struct alcor_sdmmc_host *host, |
| 232 | struct mmc_command *cmd) | 223 | struct mmc_command *cmd) |
| 233 | { | 224 | { |
| 225 | struct alcor_pci_priv *priv = host->alcor_pci; | ||
| 234 | struct mmc_data *data = cmd->data; | 226 | struct mmc_data *data = cmd->data; |
| 235 | 227 | ||
| 236 | if (!data) | 228 | if (!data) |
| @@ -248,7 +240,7 @@ static void alcor_prepare_data(struct alcor_sdmmc_host *host, | |||
| 248 | if (data->host_cookie != COOKIE_MAPPED) | 240 | if (data->host_cookie != COOKIE_MAPPED) |
| 249 | alcor_prepare_sg_miter(host); | 241 | alcor_prepare_sg_miter(host); |
| 250 | 242 | ||
| 251 | alcor_trigger_data_transfer(host, true); | 243 | alcor_write8(priv, 0, AU6601_DATA_XFER_CTRL); |
| 252 | } | 244 | } |
| 253 | 245 | ||
| 254 | static void alcor_send_cmd(struct alcor_sdmmc_host *host, | 246 | static void alcor_send_cmd(struct alcor_sdmmc_host *host, |
| @@ -435,7 +427,7 @@ static int alcor_cmd_irq_done(struct alcor_sdmmc_host *host, u32 intmask) | |||
| 435 | if (!host->data) | 427 | if (!host->data) |
| 436 | return false; | 428 | return false; |
| 437 | 429 | ||
| 438 | alcor_trigger_data_transfer(host, false); | 430 | alcor_trigger_data_transfer(host); |
| 439 | host->cmd = NULL; | 431 | host->cmd = NULL; |
| 440 | return true; | 432 | return true; |
| 441 | } | 433 | } |
| @@ -456,7 +448,7 @@ static void alcor_cmd_irq_thread(struct alcor_sdmmc_host *host, u32 intmask) | |||
| 456 | if (!host->data) | 448 | if (!host->data) |
| 457 | alcor_request_complete(host, 1); | 449 | alcor_request_complete(host, 1); |
| 458 | else | 450 | else |
| 459 | alcor_trigger_data_transfer(host, false); | 451 | alcor_trigger_data_transfer(host); |
| 460 | host->cmd = NULL; | 452 | host->cmd = NULL; |
| 461 | } | 453 | } |
| 462 | 454 | ||
| @@ -487,15 +479,9 @@ static int alcor_data_irq_done(struct alcor_sdmmc_host *host, u32 intmask) | |||
| 487 | break; | 479 | break; |
| 488 | case AU6601_INT_READ_BUF_RDY: | 480 | case AU6601_INT_READ_BUF_RDY: |
| 489 | alcor_trf_block_pio(host, true); | 481 | alcor_trf_block_pio(host, true); |
| 490 | if (!host->blocks) | ||
| 491 | break; | ||
| 492 | alcor_trigger_data_transfer(host, false); | ||
| 493 | return 1; | 482 | return 1; |
| 494 | case AU6601_INT_WRITE_BUF_RDY: | 483 | case AU6601_INT_WRITE_BUF_RDY: |
| 495 | alcor_trf_block_pio(host, false); | 484 | alcor_trf_block_pio(host, false); |
| 496 | if (!host->blocks) | ||
| 497 | break; | ||
| 498 | alcor_trigger_data_transfer(host, false); | ||
| 499 | return 1; | 485 | return 1; |
| 500 | case AU6601_INT_DMA_END: | 486 | case AU6601_INT_DMA_END: |
| 501 | if (!host->sg_count) | 487 | if (!host->sg_count) |
| @@ -508,8 +494,14 @@ static int alcor_data_irq_done(struct alcor_sdmmc_host *host, u32 intmask) | |||
| 508 | break; | 494 | break; |
| 509 | } | 495 | } |
| 510 | 496 | ||
| 511 | if (intmask & AU6601_INT_DATA_END) | 497 | if (intmask & AU6601_INT_DATA_END) { |
| 512 | return 0; | 498 | if (!host->dma_on && host->blocks) { |
| 499 | alcor_trigger_data_transfer(host); | ||
| 500 | return 1; | ||
| 501 | } else { | ||
| 502 | return 0; | ||
| 503 | } | ||
| 504 | } | ||
| 513 | 505 | ||
| 514 | return 1; | 506 | return 1; |
| 515 | } | 507 | } |
diff --git a/drivers/mmc/host/sdhci-omap.c b/drivers/mmc/host/sdhci-omap.c index 5bbed477c9b1..9f20fff9781b 100644 --- a/drivers/mmc/host/sdhci-omap.c +++ b/drivers/mmc/host/sdhci-omap.c | |||
| @@ -797,6 +797,43 @@ void sdhci_omap_reset(struct sdhci_host *host, u8 mask) | |||
| 797 | sdhci_reset(host, mask); | 797 | sdhci_reset(host, mask); |
| 798 | } | 798 | } |
| 799 | 799 | ||
| 800 | #define CMD_ERR_MASK (SDHCI_INT_CRC | SDHCI_INT_END_BIT | SDHCI_INT_INDEX |\ | ||
| 801 | SDHCI_INT_TIMEOUT) | ||
| 802 | #define CMD_MASK (CMD_ERR_MASK | SDHCI_INT_RESPONSE) | ||
| 803 | |||
| 804 | static u32 sdhci_omap_irq(struct sdhci_host *host, u32 intmask) | ||
| 805 | { | ||
| 806 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | ||
| 807 | struct sdhci_omap_host *omap_host = sdhci_pltfm_priv(pltfm_host); | ||
| 808 | |||
| 809 | if (omap_host->is_tuning && host->cmd && !host->data_early && | ||
| 810 | (intmask & CMD_ERR_MASK)) { | ||
| 811 | |||
| 812 | /* | ||
| 813 | * Since we are not resetting data lines during tuning | ||
| 814 | * operation, data error or data complete interrupts | ||
| 815 | * might still arrive. Mark this request as a failure | ||
| 816 | * but still wait for the data interrupt | ||
| 817 | */ | ||
| 818 | if (intmask & SDHCI_INT_TIMEOUT) | ||
| 819 | host->cmd->error = -ETIMEDOUT; | ||
| 820 | else | ||
| 821 | host->cmd->error = -EILSEQ; | ||
| 822 | |||
| 823 | host->cmd = NULL; | ||
| 824 | |||
| 825 | /* | ||
| 826 | * Sometimes command error interrupts and command complete | ||
| 827 | * interrupt will arrive together. Clear all command related | ||
| 828 | * interrupts here. | ||
| 829 | */ | ||
| 830 | sdhci_writel(host, intmask & CMD_MASK, SDHCI_INT_STATUS); | ||
| 831 | intmask &= ~CMD_MASK; | ||
| 832 | } | ||
| 833 | |||
| 834 | return intmask; | ||
| 835 | } | ||
| 836 | |||
| 800 | static struct sdhci_ops sdhci_omap_ops = { | 837 | static struct sdhci_ops sdhci_omap_ops = { |
| 801 | .set_clock = sdhci_omap_set_clock, | 838 | .set_clock = sdhci_omap_set_clock, |
| 802 | .set_power = sdhci_omap_set_power, | 839 | .set_power = sdhci_omap_set_power, |
| @@ -807,6 +844,7 @@ static struct sdhci_ops sdhci_omap_ops = { | |||
| 807 | .platform_send_init_74_clocks = sdhci_omap_init_74_clocks, | 844 | .platform_send_init_74_clocks = sdhci_omap_init_74_clocks, |
| 808 | .reset = sdhci_omap_reset, | 845 | .reset = sdhci_omap_reset, |
| 809 | .set_uhs_signaling = sdhci_omap_set_uhs_signaling, | 846 | .set_uhs_signaling = sdhci_omap_set_uhs_signaling, |
| 847 | .irq = sdhci_omap_irq, | ||
| 810 | }; | 848 | }; |
| 811 | 849 | ||
| 812 | static int sdhci_omap_set_capabilities(struct sdhci_omap_host *omap_host) | 850 | static int sdhci_omap_set_capabilities(struct sdhci_omap_host *omap_host) |
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index 0bb9d7b3a2b6..4c586ba4364b 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c | |||
| @@ -1133,6 +1133,8 @@ static void bnxt_tpa_start(struct bnxt *bp, struct bnxt_rx_ring_info *rxr, | |||
| 1133 | tpa_info = &rxr->rx_tpa[agg_id]; | 1133 | tpa_info = &rxr->rx_tpa[agg_id]; |
| 1134 | 1134 | ||
| 1135 | if (unlikely(cons != rxr->rx_next_cons)) { | 1135 | if (unlikely(cons != rxr->rx_next_cons)) { |
| 1136 | netdev_warn(bp->dev, "TPA cons %x != expected cons %x\n", | ||
| 1137 | cons, rxr->rx_next_cons); | ||
| 1136 | bnxt_sched_reset(bp, rxr); | 1138 | bnxt_sched_reset(bp, rxr); |
| 1137 | return; | 1139 | return; |
| 1138 | } | 1140 | } |
| @@ -1585,15 +1587,17 @@ static int bnxt_rx_pkt(struct bnxt *bp, struct bnxt_cp_ring_info *cpr, | |||
| 1585 | } | 1587 | } |
| 1586 | 1588 | ||
| 1587 | cons = rxcmp->rx_cmp_opaque; | 1589 | cons = rxcmp->rx_cmp_opaque; |
| 1588 | rx_buf = &rxr->rx_buf_ring[cons]; | ||
| 1589 | data = rx_buf->data; | ||
| 1590 | data_ptr = rx_buf->data_ptr; | ||
| 1591 | if (unlikely(cons != rxr->rx_next_cons)) { | 1590 | if (unlikely(cons != rxr->rx_next_cons)) { |
| 1592 | int rc1 = bnxt_discard_rx(bp, cpr, raw_cons, rxcmp); | 1591 | int rc1 = bnxt_discard_rx(bp, cpr, raw_cons, rxcmp); |
| 1593 | 1592 | ||
| 1593 | netdev_warn(bp->dev, "RX cons %x != expected cons %x\n", | ||
| 1594 | cons, rxr->rx_next_cons); | ||
| 1594 | bnxt_sched_reset(bp, rxr); | 1595 | bnxt_sched_reset(bp, rxr); |
| 1595 | return rc1; | 1596 | return rc1; |
| 1596 | } | 1597 | } |
| 1598 | rx_buf = &rxr->rx_buf_ring[cons]; | ||
| 1599 | data = rx_buf->data; | ||
| 1600 | data_ptr = rx_buf->data_ptr; | ||
| 1597 | prefetch(data_ptr); | 1601 | prefetch(data_ptr); |
| 1598 | 1602 | ||
| 1599 | misc = le32_to_cpu(rxcmp->rx_cmp_misc_v1); | 1603 | misc = le32_to_cpu(rxcmp->rx_cmp_misc_v1); |
| @@ -1610,11 +1614,17 @@ static int bnxt_rx_pkt(struct bnxt *bp, struct bnxt_cp_ring_info *cpr, | |||
| 1610 | 1614 | ||
| 1611 | rx_buf->data = NULL; | 1615 | rx_buf->data = NULL; |
| 1612 | if (rxcmp1->rx_cmp_cfa_code_errors_v2 & RX_CMP_L2_ERRORS) { | 1616 | if (rxcmp1->rx_cmp_cfa_code_errors_v2 & RX_CMP_L2_ERRORS) { |
| 1617 | u32 rx_err = le32_to_cpu(rxcmp1->rx_cmp_cfa_code_errors_v2); | ||
| 1618 | |||
| 1613 | bnxt_reuse_rx_data(rxr, cons, data); | 1619 | bnxt_reuse_rx_data(rxr, cons, data); |
| 1614 | if (agg_bufs) | 1620 | if (agg_bufs) |
| 1615 | bnxt_reuse_rx_agg_bufs(cpr, cp_cons, agg_bufs); | 1621 | bnxt_reuse_rx_agg_bufs(cpr, cp_cons, agg_bufs); |
| 1616 | 1622 | ||
| 1617 | rc = -EIO; | 1623 | rc = -EIO; |
| 1624 | if (rx_err & RX_CMPL_ERRORS_BUFFER_ERROR_MASK) { | ||
| 1625 | netdev_warn(bp->dev, "RX buffer error %x\n", rx_err); | ||
| 1626 | bnxt_sched_reset(bp, rxr); | ||
| 1627 | } | ||
| 1618 | goto next_rx; | 1628 | goto next_rx; |
| 1619 | } | 1629 | } |
| 1620 | 1630 | ||
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index 328373e0578f..060a6f386104 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c | |||
| @@ -4283,7 +4283,7 @@ static void tg3_power_down(struct tg3 *tp) | |||
| 4283 | pci_set_power_state(tp->pdev, PCI_D3hot); | 4283 | pci_set_power_state(tp->pdev, PCI_D3hot); |
| 4284 | } | 4284 | } |
| 4285 | 4285 | ||
| 4286 | static void tg3_aux_stat_to_speed_duplex(struct tg3 *tp, u32 val, u16 *speed, u8 *duplex) | 4286 | static void tg3_aux_stat_to_speed_duplex(struct tg3 *tp, u32 val, u32 *speed, u8 *duplex) |
| 4287 | { | 4287 | { |
| 4288 | switch (val & MII_TG3_AUX_STAT_SPDMASK) { | 4288 | switch (val & MII_TG3_AUX_STAT_SPDMASK) { |
| 4289 | case MII_TG3_AUX_STAT_10HALF: | 4289 | case MII_TG3_AUX_STAT_10HALF: |
| @@ -4787,7 +4787,7 @@ static int tg3_setup_copper_phy(struct tg3 *tp, bool force_reset) | |||
| 4787 | bool current_link_up; | 4787 | bool current_link_up; |
| 4788 | u32 bmsr, val; | 4788 | u32 bmsr, val; |
| 4789 | u32 lcl_adv, rmt_adv; | 4789 | u32 lcl_adv, rmt_adv; |
| 4790 | u16 current_speed; | 4790 | u32 current_speed; |
| 4791 | u8 current_duplex; | 4791 | u8 current_duplex; |
| 4792 | int i, err; | 4792 | int i, err; |
| 4793 | 4793 | ||
| @@ -5719,7 +5719,7 @@ out: | |||
| 5719 | static int tg3_setup_fiber_phy(struct tg3 *tp, bool force_reset) | 5719 | static int tg3_setup_fiber_phy(struct tg3 *tp, bool force_reset) |
| 5720 | { | 5720 | { |
| 5721 | u32 orig_pause_cfg; | 5721 | u32 orig_pause_cfg; |
| 5722 | u16 orig_active_speed; | 5722 | u32 orig_active_speed; |
| 5723 | u8 orig_active_duplex; | 5723 | u8 orig_active_duplex; |
| 5724 | u32 mac_status; | 5724 | u32 mac_status; |
| 5725 | bool current_link_up; | 5725 | bool current_link_up; |
| @@ -5823,7 +5823,7 @@ static int tg3_setup_fiber_mii_phy(struct tg3 *tp, bool force_reset) | |||
| 5823 | { | 5823 | { |
| 5824 | int err = 0; | 5824 | int err = 0; |
| 5825 | u32 bmsr, bmcr; | 5825 | u32 bmsr, bmcr; |
| 5826 | u16 current_speed = SPEED_UNKNOWN; | 5826 | u32 current_speed = SPEED_UNKNOWN; |
| 5827 | u8 current_duplex = DUPLEX_UNKNOWN; | 5827 | u8 current_duplex = DUPLEX_UNKNOWN; |
| 5828 | bool current_link_up = false; | 5828 | bool current_link_up = false; |
| 5829 | u32 local_adv, remote_adv, sgsr; | 5829 | u32 local_adv, remote_adv, sgsr; |
diff --git a/drivers/net/ethernet/broadcom/tg3.h b/drivers/net/ethernet/broadcom/tg3.h index a772a33b685c..6953d0546acb 100644 --- a/drivers/net/ethernet/broadcom/tg3.h +++ b/drivers/net/ethernet/broadcom/tg3.h | |||
| @@ -2873,7 +2873,7 @@ struct tg3_tx_ring_info { | |||
| 2873 | struct tg3_link_config { | 2873 | struct tg3_link_config { |
| 2874 | /* Describes what we're trying to get. */ | 2874 | /* Describes what we're trying to get. */ |
| 2875 | u32 advertising; | 2875 | u32 advertising; |
| 2876 | u16 speed; | 2876 | u32 speed; |
| 2877 | u8 duplex; | 2877 | u8 duplex; |
| 2878 | u8 autoneg; | 2878 | u8 autoneg; |
| 2879 | u8 flowctrl; | 2879 | u8 flowctrl; |
| @@ -2882,7 +2882,7 @@ struct tg3_link_config { | |||
| 2882 | u8 active_flowctrl; | 2882 | u8 active_flowctrl; |
| 2883 | 2883 | ||
| 2884 | u8 active_duplex; | 2884 | u8 active_duplex; |
| 2885 | u16 active_speed; | 2885 | u32 active_speed; |
| 2886 | u32 rmt_adv; | 2886 | u32 rmt_adv; |
| 2887 | }; | 2887 | }; |
| 2888 | 2888 | ||
diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c index 1522aee81884..3da2795e2486 100644 --- a/drivers/net/ethernet/cadence/macb_main.c +++ b/drivers/net/ethernet/cadence/macb_main.c | |||
| @@ -898,7 +898,9 @@ static void macb_tx_interrupt(struct macb_queue *queue) | |||
| 898 | 898 | ||
| 899 | /* First, update TX stats if needed */ | 899 | /* First, update TX stats if needed */ |
| 900 | if (skb) { | 900 | if (skb) { |
| 901 | if (gem_ptp_do_txstamp(queue, skb, desc) == 0) { | 901 | if (unlikely(skb_shinfo(skb)->tx_flags & |
| 902 | SKBTX_HW_TSTAMP) && | ||
| 903 | gem_ptp_do_txstamp(queue, skb, desc) == 0) { | ||
| 902 | /* skb now belongs to timestamp buffer | 904 | /* skb now belongs to timestamp buffer |
| 903 | * and will be removed later | 905 | * and will be removed later |
| 904 | */ | 906 | */ |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h index 0c443ea98479..374a4d4371f9 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h | |||
| @@ -497,7 +497,7 @@ struct qlcnic_hardware_context { | |||
| 497 | u16 board_type; | 497 | u16 board_type; |
| 498 | u16 supported_type; | 498 | u16 supported_type; |
| 499 | 499 | ||
| 500 | u16 link_speed; | 500 | u32 link_speed; |
| 501 | u16 link_duplex; | 501 | u16 link_duplex; |
| 502 | u16 link_autoneg; | 502 | u16 link_autoneg; |
| 503 | u16 module_type; | 503 | u16 module_type; |
diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 19efa88f3f02..ed651dde6ef9 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c | |||
| @@ -28,6 +28,7 @@ | |||
| 28 | #include <linux/pm_runtime.h> | 28 | #include <linux/pm_runtime.h> |
| 29 | #include <linux/firmware.h> | 29 | #include <linux/firmware.h> |
| 30 | #include <linux/prefetch.h> | 30 | #include <linux/prefetch.h> |
| 31 | #include <linux/pci-aspm.h> | ||
| 31 | #include <linux/ipv6.h> | 32 | #include <linux/ipv6.h> |
| 32 | #include <net/ip6_checksum.h> | 33 | #include <net/ip6_checksum.h> |
| 33 | 34 | ||
| @@ -7352,6 +7353,11 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
| 7352 | if (rc) | 7353 | if (rc) |
| 7353 | return rc; | 7354 | return rc; |
| 7354 | 7355 | ||
| 7356 | /* Disable ASPM completely as that cause random device stop working | ||
| 7357 | * problems as well as full system hangs for some PCIe devices users. | ||
| 7358 | */ | ||
| 7359 | pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1); | ||
| 7360 | |||
| 7355 | /* enable device (incl. PCI PM wakeup and hotplug setup) */ | 7361 | /* enable device (incl. PCI PM wakeup and hotplug setup) */ |
| 7356 | rc = pcim_enable_device(pdev); | 7362 | rc = pcim_enable_device(pdev); |
| 7357 | if (rc < 0) { | 7363 | if (rc < 0) { |
diff --git a/drivers/net/vrf.c b/drivers/net/vrf.c index 6d1a1abbed27..cd15c32b2e43 100644 --- a/drivers/net/vrf.c +++ b/drivers/net/vrf.c | |||
| @@ -1275,8 +1275,12 @@ static void vrf_setup(struct net_device *dev) | |||
| 1275 | dev->priv_flags |= IFF_NO_QUEUE; | 1275 | dev->priv_flags |= IFF_NO_QUEUE; |
| 1276 | dev->priv_flags |= IFF_NO_RX_HANDLER; | 1276 | dev->priv_flags |= IFF_NO_RX_HANDLER; |
| 1277 | 1277 | ||
| 1278 | dev->min_mtu = 0; | 1278 | /* VRF devices do not care about MTU, but if the MTU is set |
| 1279 | dev->max_mtu = 0; | 1279 | * too low then the ipv4 and ipv6 protocols are disabled |
| 1280 | * which breaks networking. | ||
| 1281 | */ | ||
| 1282 | dev->min_mtu = IPV6_MIN_MTU; | ||
| 1283 | dev->max_mtu = ETH_MAX_MTU; | ||
| 1280 | } | 1284 | } |
| 1281 | 1285 | ||
| 1282 | static int vrf_validate(struct nlattr *tb[], struct nlattr *data[], | 1286 | static int vrf_validate(struct nlattr *tb[], struct nlattr *data[], |
diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c index 3f3df4c29f6e..905282a8ddaa 100644 --- a/drivers/pci/hotplug/pciehp_ctrl.c +++ b/drivers/pci/hotplug/pciehp_ctrl.c | |||
| @@ -115,6 +115,10 @@ static void remove_board(struct controller *ctrl, bool safe_removal) | |||
| 115 | * removed from the slot/adapter. | 115 | * removed from the slot/adapter. |
| 116 | */ | 116 | */ |
| 117 | msleep(1000); | 117 | msleep(1000); |
| 118 | |||
| 119 | /* Ignore link or presence changes caused by power off */ | ||
| 120 | atomic_and(~(PCI_EXP_SLTSTA_DLLSC | PCI_EXP_SLTSTA_PDC), | ||
| 121 | &ctrl->pending_events); | ||
| 118 | } | 122 | } |
| 119 | 123 | ||
| 120 | /* turn off Green LED */ | 124 | /* turn off Green LED */ |
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index a59ad09ce911..a077f67fe1da 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
| @@ -3877,6 +3877,8 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x9128, | |||
| 3877 | /* https://bugzilla.kernel.org/show_bug.cgi?id=42679#c14 */ | 3877 | /* https://bugzilla.kernel.org/show_bug.cgi?id=42679#c14 */ |
| 3878 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x9130, | 3878 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x9130, |
| 3879 | quirk_dma_func1_alias); | 3879 | quirk_dma_func1_alias); |
| 3880 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x9170, | ||
| 3881 | quirk_dma_func1_alias); | ||
| 3880 | /* https://bugzilla.kernel.org/show_bug.cgi?id=42679#c47 + c57 */ | 3882 | /* https://bugzilla.kernel.org/show_bug.cgi?id=42679#c47 + c57 */ |
| 3881 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x9172, | 3883 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x9172, |
| 3882 | quirk_dma_func1_alias); | 3884 | quirk_dma_func1_alias); |
diff --git a/drivers/platform/x86/pmc_atom.c b/drivers/platform/x86/pmc_atom.c index 8f018b3f3cd4..c7039f52ad51 100644 --- a/drivers/platform/x86/pmc_atom.c +++ b/drivers/platform/x86/pmc_atom.c | |||
| @@ -17,6 +17,7 @@ | |||
| 17 | 17 | ||
| 18 | #include <linux/debugfs.h> | 18 | #include <linux/debugfs.h> |
| 19 | #include <linux/device.h> | 19 | #include <linux/device.h> |
| 20 | #include <linux/dmi.h> | ||
| 20 | #include <linux/init.h> | 21 | #include <linux/init.h> |
| 21 | #include <linux/io.h> | 22 | #include <linux/io.h> |
| 22 | #include <linux/platform_data/x86/clk-pmc-atom.h> | 23 | #include <linux/platform_data/x86/clk-pmc-atom.h> |
| @@ -391,11 +392,27 @@ static int pmc_dbgfs_register(struct pmc_dev *pmc) | |||
| 391 | } | 392 | } |
| 392 | #endif /* CONFIG_DEBUG_FS */ | 393 | #endif /* CONFIG_DEBUG_FS */ |
| 393 | 394 | ||
| 395 | /* | ||
| 396 | * Some systems need one or more of their pmc_plt_clks to be | ||
| 397 | * marked as critical. | ||
| 398 | */ | ||
| 399 | static const struct dmi_system_id critclk_systems[] = { | ||
| 400 | { | ||
| 401 | .ident = "MPL CEC1x", | ||
| 402 | .matches = { | ||
| 403 | DMI_MATCH(DMI_SYS_VENDOR, "MPL AG"), | ||
| 404 | DMI_MATCH(DMI_PRODUCT_NAME, "CEC10 Family"), | ||
| 405 | }, | ||
| 406 | }, | ||
| 407 | { /*sentinel*/ } | ||
| 408 | }; | ||
| 409 | |||
| 394 | static int pmc_setup_clks(struct pci_dev *pdev, void __iomem *pmc_regmap, | 410 | static int pmc_setup_clks(struct pci_dev *pdev, void __iomem *pmc_regmap, |
| 395 | const struct pmc_data *pmc_data) | 411 | const struct pmc_data *pmc_data) |
| 396 | { | 412 | { |
| 397 | struct platform_device *clkdev; | 413 | struct platform_device *clkdev; |
| 398 | struct pmc_clk_data *clk_data; | 414 | struct pmc_clk_data *clk_data; |
| 415 | const struct dmi_system_id *d = dmi_first_match(critclk_systems); | ||
| 399 | 416 | ||
| 400 | clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL); | 417 | clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL); |
| 401 | if (!clk_data) | 418 | if (!clk_data) |
| @@ -403,6 +420,10 @@ static int pmc_setup_clks(struct pci_dev *pdev, void __iomem *pmc_regmap, | |||
| 403 | 420 | ||
| 404 | clk_data->base = pmc_regmap; /* offset is added by client */ | 421 | clk_data->base = pmc_regmap; /* offset is added by client */ |
| 405 | clk_data->clks = pmc_data->clks; | 422 | clk_data->clks = pmc_data->clks; |
| 423 | if (d) { | ||
| 424 | clk_data->critical = true; | ||
| 425 | pr_info("%s critclks quirk enabled\n", d->ident); | ||
| 426 | } | ||
| 406 | 427 | ||
| 407 | clkdev = platform_device_register_data(&pdev->dev, "clk-pmc-atom", | 428 | clkdev = platform_device_register_data(&pdev->dev, "clk-pmc-atom", |
| 408 | PLATFORM_DEVID_NONE, | 429 | PLATFORM_DEVID_NONE, |
diff --git a/drivers/scsi/csiostor/csio_scsi.c b/drivers/scsi/csiostor/csio_scsi.c index 462560b2855e..469d0bc9f5fe 100644 --- a/drivers/scsi/csiostor/csio_scsi.c +++ b/drivers/scsi/csiostor/csio_scsi.c | |||
| @@ -1713,8 +1713,11 @@ csio_scsi_err_handler(struct csio_hw *hw, struct csio_ioreq *req) | |||
| 1713 | } | 1713 | } |
| 1714 | 1714 | ||
| 1715 | out: | 1715 | out: |
| 1716 | if (req->nsge > 0) | 1716 | if (req->nsge > 0) { |
| 1717 | scsi_dma_unmap(cmnd); | 1717 | scsi_dma_unmap(cmnd); |
| 1718 | if (req->dcopy && (host_status == DID_OK)) | ||
| 1719 | host_status = csio_scsi_copy_to_sgl(hw, req); | ||
| 1720 | } | ||
| 1718 | 1721 | ||
| 1719 | cmnd->result = (((host_status) << 16) | scsi_status); | 1722 | cmnd->result = (((host_status) << 16) | scsi_status); |
| 1720 | cmnd->scsi_done(cmnd); | 1723 | cmnd->scsi_done(cmnd); |
diff --git a/drivers/virtio/virtio_pci_common.c b/drivers/virtio/virtio_pci_common.c index d0584c040c60..7a0398bb84f7 100644 --- a/drivers/virtio/virtio_pci_common.c +++ b/drivers/virtio/virtio_pci_common.c | |||
| @@ -255,9 +255,11 @@ void vp_del_vqs(struct virtio_device *vdev) | |||
| 255 | for (i = 0; i < vp_dev->msix_used_vectors; ++i) | 255 | for (i = 0; i < vp_dev->msix_used_vectors; ++i) |
| 256 | free_irq(pci_irq_vector(vp_dev->pci_dev, i), vp_dev); | 256 | free_irq(pci_irq_vector(vp_dev->pci_dev, i), vp_dev); |
| 257 | 257 | ||
| 258 | for (i = 0; i < vp_dev->msix_vectors; i++) | 258 | if (vp_dev->msix_affinity_masks) { |
| 259 | if (vp_dev->msix_affinity_masks[i]) | 259 | for (i = 0; i < vp_dev->msix_vectors; i++) |
| 260 | free_cpumask_var(vp_dev->msix_affinity_masks[i]); | 260 | if (vp_dev->msix_affinity_masks[i]) |
| 261 | free_cpumask_var(vp_dev->msix_affinity_masks[i]); | ||
| 262 | } | ||
| 261 | 263 | ||
| 262 | if (vp_dev->msix_enabled) { | 264 | if (vp_dev->msix_enabled) { |
| 263 | /* Disable the vector used for configuration */ | 265 | /* Disable the vector used for configuration */ |
diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c index 18846afb39da..5df92c308286 100644 --- a/drivers/virtio/virtio_ring.c +++ b/drivers/virtio/virtio_ring.c | |||
| @@ -882,6 +882,8 @@ static struct virtqueue *vring_create_virtqueue_split( | |||
| 882 | GFP_KERNEL|__GFP_NOWARN|__GFP_ZERO); | 882 | GFP_KERNEL|__GFP_NOWARN|__GFP_ZERO); |
| 883 | if (queue) | 883 | if (queue) |
| 884 | break; | 884 | break; |
| 885 | if (!may_reduce_num) | ||
| 886 | return NULL; | ||
| 885 | } | 887 | } |
| 886 | 888 | ||
| 887 | if (!num) | 889 | if (!num) |
| @@ -1034,7 +1034,7 @@ static inline struct aio_kiocb *aio_get_req(struct kioctx *ctx) | |||
| 1034 | return NULL; | 1034 | return NULL; |
| 1035 | 1035 | ||
| 1036 | if (unlikely(!get_reqs_available(ctx))) { | 1036 | if (unlikely(!get_reqs_available(ctx))) { |
| 1037 | kfree(req); | 1037 | kmem_cache_free(kiocb_cachep, req); |
| 1038 | return NULL; | 1038 | return NULL; |
| 1039 | } | 1039 | } |
| 1040 | 1040 | ||
| @@ -1794,7 +1794,7 @@ static int __io_submit_one(struct kioctx *ctx, const struct iocb *iocb, | |||
| 1794 | */ | 1794 | */ |
| 1795 | eventfd = eventfd_ctx_fdget(iocb->aio_resfd); | 1795 | eventfd = eventfd_ctx_fdget(iocb->aio_resfd); |
| 1796 | if (IS_ERR(eventfd)) | 1796 | if (IS_ERR(eventfd)) |
| 1797 | return PTR_ERR(req->ki_eventfd); | 1797 | return PTR_ERR(eventfd); |
| 1798 | 1798 | ||
| 1799 | req->ki_eventfd = eventfd; | 1799 | req->ki_eventfd = eventfd; |
| 1800 | } | 1800 | } |
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index ec2d8919e7fb..cd4e693406a0 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
| @@ -501,6 +501,16 @@ static noinline int btrfs_ioctl_fitrim(struct file *file, void __user *arg) | |||
| 501 | if (!capable(CAP_SYS_ADMIN)) | 501 | if (!capable(CAP_SYS_ADMIN)) |
| 502 | return -EPERM; | 502 | return -EPERM; |
| 503 | 503 | ||
| 504 | /* | ||
| 505 | * If the fs is mounted with nologreplay, which requires it to be | ||
| 506 | * mounted in RO mode as well, we can not allow discard on free space | ||
| 507 | * inside block groups, because log trees refer to extents that are not | ||
| 508 | * pinned in a block group's free space cache (pinning the extents is | ||
| 509 | * precisely the first phase of replaying a log tree). | ||
| 510 | */ | ||
| 511 | if (btrfs_test_opt(fs_info, NOLOGREPLAY)) | ||
| 512 | return -EROFS; | ||
| 513 | |||
| 504 | rcu_read_lock(); | 514 | rcu_read_lock(); |
| 505 | list_for_each_entry_rcu(device, &fs_info->fs_devices->devices, | 515 | list_for_each_entry_rcu(device, &fs_info->fs_devices->devices, |
| 506 | dev_list) { | 516 | dev_list) { |
diff --git a/fs/btrfs/props.c b/fs/btrfs/props.c index dc6140013ae8..61d22a56c0ba 100644 --- a/fs/btrfs/props.c +++ b/fs/btrfs/props.c | |||
| @@ -366,11 +366,11 @@ int btrfs_subvol_inherit_props(struct btrfs_trans_handle *trans, | |||
| 366 | 366 | ||
| 367 | static int prop_compression_validate(const char *value, size_t len) | 367 | static int prop_compression_validate(const char *value, size_t len) |
| 368 | { | 368 | { |
| 369 | if (!strncmp("lzo", value, len)) | 369 | if (!strncmp("lzo", value, 3)) |
| 370 | return 0; | 370 | return 0; |
| 371 | else if (!strncmp("zlib", value, len)) | 371 | else if (!strncmp("zlib", value, 4)) |
| 372 | return 0; | 372 | return 0; |
| 373 | else if (!strncmp("zstd", value, len)) | 373 | else if (!strncmp("zstd", value, 4)) |
| 374 | return 0; | 374 | return 0; |
| 375 | 375 | ||
| 376 | return -EINVAL; | 376 | return -EINVAL; |
| @@ -396,7 +396,7 @@ static int prop_compression_apply(struct inode *inode, | |||
| 396 | btrfs_set_fs_incompat(fs_info, COMPRESS_LZO); | 396 | btrfs_set_fs_incompat(fs_info, COMPRESS_LZO); |
| 397 | } else if (!strncmp("zlib", value, 4)) { | 397 | } else if (!strncmp("zlib", value, 4)) { |
| 398 | type = BTRFS_COMPRESS_ZLIB; | 398 | type = BTRFS_COMPRESS_ZLIB; |
| 399 | } else if (!strncmp("zstd", value, len)) { | 399 | } else if (!strncmp("zstd", value, 4)) { |
| 400 | type = BTRFS_COMPRESS_ZSTD; | 400 | type = BTRFS_COMPRESS_ZSTD; |
| 401 | btrfs_set_fs_incompat(fs_info, COMPRESS_ZSTD); | 401 | btrfs_set_fs_incompat(fs_info, COMPRESS_ZSTD); |
| 402 | } else { | 402 | } else { |
diff --git a/fs/nfs/nfs42proc.c b/fs/nfs/nfs42proc.c index ff6f85fb676b..5196bfa7894d 100644 --- a/fs/nfs/nfs42proc.c +++ b/fs/nfs/nfs42proc.c | |||
| @@ -329,9 +329,6 @@ ssize_t nfs42_proc_copy(struct file *src, loff_t pos_src, | |||
| 329 | }; | 329 | }; |
| 330 | ssize_t err, err2; | 330 | ssize_t err, err2; |
| 331 | 331 | ||
| 332 | if (!nfs_server_capable(file_inode(dst), NFS_CAP_COPY)) | ||
| 333 | return -EOPNOTSUPP; | ||
| 334 | |||
| 335 | src_lock = nfs_get_lock_context(nfs_file_open_context(src)); | 332 | src_lock = nfs_get_lock_context(nfs_file_open_context(src)); |
| 336 | if (IS_ERR(src_lock)) | 333 | if (IS_ERR(src_lock)) |
| 337 | return PTR_ERR(src_lock); | 334 | return PTR_ERR(src_lock); |
diff --git a/fs/nfs/nfs4file.c b/fs/nfs/nfs4file.c index 45b2322e092d..00d17198ee12 100644 --- a/fs/nfs/nfs4file.c +++ b/fs/nfs/nfs4file.c | |||
| @@ -133,8 +133,10 @@ static ssize_t nfs4_copy_file_range(struct file *file_in, loff_t pos_in, | |||
| 133 | struct file *file_out, loff_t pos_out, | 133 | struct file *file_out, loff_t pos_out, |
| 134 | size_t count, unsigned int flags) | 134 | size_t count, unsigned int flags) |
| 135 | { | 135 | { |
| 136 | if (!nfs_server_capable(file_inode(file_out), NFS_CAP_COPY)) | ||
| 137 | return -EOPNOTSUPP; | ||
| 136 | if (file_inode(file_in) == file_inode(file_out)) | 138 | if (file_inode(file_in) == file_inode(file_out)) |
| 137 | return -EINVAL; | 139 | return -EOPNOTSUPP; |
| 138 | return nfs42_proc_copy(file_in, pos_in, file_out, pos_out, count); | 140 | return nfs42_proc_copy(file_in, pos_in, file_out, pos_out, count); |
| 139 | } | 141 | } |
| 140 | 142 | ||
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index cfcabc33e24d..602446158bfb 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c | |||
| @@ -2589,7 +2589,7 @@ static void nfs4_xdr_enc_getacl(struct rpc_rqst *req, struct xdr_stream *xdr, | |||
| 2589 | ARRAY_SIZE(nfs4_acl_bitmap), &hdr); | 2589 | ARRAY_SIZE(nfs4_acl_bitmap), &hdr); |
| 2590 | 2590 | ||
| 2591 | rpc_prepare_reply_pages(req, args->acl_pages, 0, | 2591 | rpc_prepare_reply_pages(req, args->acl_pages, 0, |
| 2592 | args->acl_len, replen); | 2592 | args->acl_len, replen + 1); |
| 2593 | encode_nops(&hdr); | 2593 | encode_nops(&hdr); |
| 2594 | } | 2594 | } |
| 2595 | 2595 | ||
| @@ -2811,7 +2811,7 @@ static void nfs4_xdr_enc_fs_locations(struct rpc_rqst *req, | |||
| 2811 | } | 2811 | } |
| 2812 | 2812 | ||
| 2813 | rpc_prepare_reply_pages(req, (struct page **)&args->page, 0, | 2813 | rpc_prepare_reply_pages(req, (struct page **)&args->page, 0, |
| 2814 | PAGE_SIZE, replen); | 2814 | PAGE_SIZE, replen + 1); |
| 2815 | encode_nops(&hdr); | 2815 | encode_nops(&hdr); |
| 2816 | } | 2816 | } |
| 2817 | 2817 | ||
diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 23790c7b2289..c27ac96a95bd 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c | |||
| @@ -2041,7 +2041,8 @@ static int nfs23_validate_mount_data(void *options, | |||
| 2041 | memcpy(sap, &data->addr, sizeof(data->addr)); | 2041 | memcpy(sap, &data->addr, sizeof(data->addr)); |
| 2042 | args->nfs_server.addrlen = sizeof(data->addr); | 2042 | args->nfs_server.addrlen = sizeof(data->addr); |
| 2043 | args->nfs_server.port = ntohs(data->addr.sin_port); | 2043 | args->nfs_server.port = ntohs(data->addr.sin_port); |
| 2044 | if (!nfs_verify_server_address(sap)) | 2044 | if (sap->sa_family != AF_INET || |
| 2045 | !nfs_verify_server_address(sap)) | ||
| 2045 | goto out_no_address; | 2046 | goto out_no_address; |
| 2046 | 2047 | ||
| 2047 | if (!(data->flags & NFS_MOUNT_TCP)) | 2048 | if (!(data->flags & NFS_MOUNT_TCP)) |
diff --git a/include/drm/drm_modeset_helper_vtables.h b/include/drm/drm_modeset_helper_vtables.h index cfb7be40bed7..ce4de6b1e444 100644 --- a/include/drm/drm_modeset_helper_vtables.h +++ b/include/drm/drm_modeset_helper_vtables.h | |||
| @@ -418,6 +418,8 @@ struct drm_crtc_helper_funcs { | |||
| 418 | * Drivers can use the @old_crtc_state input parameter if the operations | 418 | * Drivers can use the @old_crtc_state input parameter if the operations |
| 419 | * needed to enable the CRTC don't depend solely on the new state but | 419 | * needed to enable the CRTC don't depend solely on the new state but |
| 420 | * also on the transition between the old state and the new state. | 420 | * also on the transition between the old state and the new state. |
| 421 | * | ||
| 422 | * This function is optional. | ||
| 421 | */ | 423 | */ |
| 422 | void (*atomic_enable)(struct drm_crtc *crtc, | 424 | void (*atomic_enable)(struct drm_crtc *crtc, |
| 423 | struct drm_crtc_state *old_crtc_state); | 425 | struct drm_crtc_state *old_crtc_state); |
| @@ -441,6 +443,8 @@ struct drm_crtc_helper_funcs { | |||
| 441 | * parameter @old_crtc_state which could be used to access the old | 443 | * parameter @old_crtc_state which could be used to access the old |
| 442 | * state. Atomic drivers should consider to use this one instead | 444 | * state. Atomic drivers should consider to use this one instead |
| 443 | * of @disable. | 445 | * of @disable. |
| 446 | * | ||
| 447 | * This function is optional. | ||
| 444 | */ | 448 | */ |
| 445 | void (*atomic_disable)(struct drm_crtc *crtc, | 449 | void (*atomic_disable)(struct drm_crtc *crtc, |
| 446 | struct drm_crtc_state *old_crtc_state); | 450 | struct drm_crtc_state *old_crtc_state); |
diff --git a/include/keys/trusted.h b/include/keys/trusted.h index adbcb6817826..0071298b9b28 100644 --- a/include/keys/trusted.h +++ b/include/keys/trusted.h | |||
| @@ -38,7 +38,7 @@ enum { | |||
| 38 | 38 | ||
| 39 | int TSS_authhmac(unsigned char *digest, const unsigned char *key, | 39 | int TSS_authhmac(unsigned char *digest, const unsigned char *key, |
| 40 | unsigned int keylen, unsigned char *h1, | 40 | unsigned int keylen, unsigned char *h1, |
| 41 | unsigned char *h2, unsigned char h3, ...); | 41 | unsigned char *h2, unsigned int h3, ...); |
| 42 | int TSS_checkhmac1(unsigned char *buffer, | 42 | int TSS_checkhmac1(unsigned char *buffer, |
| 43 | const uint32_t command, | 43 | const uint32_t command, |
| 44 | const unsigned char *ononce, | 44 | const unsigned char *ononce, |
diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 34a5036debd3..2d14e21c16c0 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h | |||
| @@ -47,8 +47,8 @@ | |||
| 47 | 47 | ||
| 48 | #define u64_to_user_ptr(x) ( \ | 48 | #define u64_to_user_ptr(x) ( \ |
| 49 | { \ | 49 | { \ |
| 50 | typecheck(u64, x); \ | 50 | typecheck(u64, (x)); \ |
| 51 | (void __user *)(uintptr_t)x; \ | 51 | (void __user *)(uintptr_t)(x); \ |
| 52 | } \ | 52 | } \ |
| 53 | ) | 53 | ) |
| 54 | 54 | ||
diff --git a/include/linux/platform_data/x86/clk-pmc-atom.h b/include/linux/platform_data/x86/clk-pmc-atom.h index 3ab892208343..7a37ac27d0fb 100644 --- a/include/linux/platform_data/x86/clk-pmc-atom.h +++ b/include/linux/platform_data/x86/clk-pmc-atom.h | |||
| @@ -35,10 +35,13 @@ struct pmc_clk { | |||
| 35 | * | 35 | * |
| 36 | * @base: PMC clock register base offset | 36 | * @base: PMC clock register base offset |
| 37 | * @clks: pointer to set of registered clocks, typically 0..5 | 37 | * @clks: pointer to set of registered clocks, typically 0..5 |
| 38 | * @critical: flag to indicate if firmware enabled pmc_plt_clks | ||
| 39 | * should be marked as critial or not | ||
| 38 | */ | 40 | */ |
| 39 | struct pmc_clk_data { | 41 | struct pmc_clk_data { |
| 40 | void __iomem *base; | 42 | void __iomem *base; |
| 41 | const struct pmc_clk *clks; | 43 | const struct pmc_clk *clks; |
| 44 | bool critical; | ||
| 42 | }; | 45 | }; |
| 43 | 46 | ||
| 44 | #endif /* __PLATFORM_DATA_X86_CLK_PMC_ATOM_H */ | 47 | #endif /* __PLATFORM_DATA_X86_CLK_PMC_ATOM_H */ |
diff --git a/include/linux/sunrpc/sched.h b/include/linux/sunrpc/sched.h index ec861cd0cfe8..52d41d0c1ae1 100644 --- a/include/linux/sunrpc/sched.h +++ b/include/linux/sunrpc/sched.h | |||
| @@ -304,12 +304,4 @@ rpc_clnt_swap_deactivate(struct rpc_clnt *clnt) | |||
| 304 | } | 304 | } |
| 305 | #endif /* CONFIG_SUNRPC_SWAP */ | 305 | #endif /* CONFIG_SUNRPC_SWAP */ |
| 306 | 306 | ||
| 307 | static inline bool | ||
| 308 | rpc_task_need_resched(const struct rpc_task *task) | ||
| 309 | { | ||
| 310 | if (RPC_IS_QUEUED(task) || task->tk_callback) | ||
| 311 | return true; | ||
| 312 | return false; | ||
| 313 | } | ||
| 314 | |||
| 315 | #endif /* _LINUX_SUNRPC_SCHED_H_ */ | 307 | #endif /* _LINUX_SUNRPC_SCHED_H_ */ |
diff --git a/include/linux/virtio_ring.h b/include/linux/virtio_ring.h index fab02133a919..3dc70adfe5f5 100644 --- a/include/linux/virtio_ring.h +++ b/include/linux/virtio_ring.h | |||
| @@ -63,7 +63,7 @@ struct virtqueue; | |||
| 63 | /* | 63 | /* |
| 64 | * Creates a virtqueue and allocates the descriptor ring. If | 64 | * Creates a virtqueue and allocates the descriptor ring. If |
| 65 | * may_reduce_num is set, then this may allocate a smaller ring than | 65 | * may_reduce_num is set, then this may allocate a smaller ring than |
| 66 | * expected. The caller should query virtqueue_get_ring_size to learn | 66 | * expected. The caller should query virtqueue_get_vring_size to learn |
| 67 | * the actual size of the ring. | 67 | * the actual size of the ring. |
| 68 | */ | 68 | */ |
| 69 | struct virtqueue *vring_create_virtqueue(unsigned int index, | 69 | struct virtqueue *vring_create_virtqueue(unsigned int index, |
diff --git a/include/net/nfc/nci_core.h b/include/net/nfc/nci_core.h index 87499b6b35d6..df5c69db68af 100644 --- a/include/net/nfc/nci_core.h +++ b/include/net/nfc/nci_core.h | |||
| @@ -166,7 +166,7 @@ struct nci_conn_info { | |||
| 166 | * According to specification 102 622 chapter 4.4 Pipes, | 166 | * According to specification 102 622 chapter 4.4 Pipes, |
| 167 | * the pipe identifier is 7 bits long. | 167 | * the pipe identifier is 7 bits long. |
| 168 | */ | 168 | */ |
| 169 | #define NCI_HCI_MAX_PIPES 127 | 169 | #define NCI_HCI_MAX_PIPES 128 |
| 170 | 170 | ||
| 171 | struct nci_hci_gate { | 171 | struct nci_hci_gate { |
| 172 | u8 gate; | 172 | u8 gate; |
diff --git a/include/sound/soc.h b/include/sound/soc.h index eb7db605955b..482b4ea87c3c 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h | |||
| @@ -802,8 +802,13 @@ struct snd_soc_component_driver { | |||
| 802 | int probe_order; | 802 | int probe_order; |
| 803 | int remove_order; | 803 | int remove_order; |
| 804 | 804 | ||
| 805 | /* signal if the module handling the component cannot be removed */ | 805 | /* |
| 806 | unsigned int ignore_module_refcount:1; | 806 | * signal if the module handling the component should not be removed |
| 807 | * if a pcm is open. Setting this would prevent the module | ||
| 808 | * refcount being incremented in probe() but allow it be incremented | ||
| 809 | * when a pcm is opened and decremented when it is closed. | ||
| 810 | */ | ||
| 811 | unsigned int module_get_upon_open:1; | ||
| 807 | 812 | ||
| 808 | /* bits */ | 813 | /* bits */ |
| 809 | unsigned int idle_bias_on:1; | 814 | unsigned int idle_bias_on:1; |
| @@ -1083,6 +1088,8 @@ struct snd_soc_card { | |||
| 1083 | struct mutex mutex; | 1088 | struct mutex mutex; |
| 1084 | struct mutex dapm_mutex; | 1089 | struct mutex dapm_mutex; |
| 1085 | 1090 | ||
| 1091 | spinlock_t dpcm_lock; | ||
| 1092 | |||
| 1086 | bool instantiated; | 1093 | bool instantiated; |
| 1087 | bool topology_shortname_created; | 1094 | bool topology_shortname_created; |
| 1088 | 1095 | ||
diff --git a/include/uapi/linux/ethtool.h b/include/uapi/linux/ethtool.h index 3652b239dad1..d473e5ed044c 100644 --- a/include/uapi/linux/ethtool.h +++ b/include/uapi/linux/ethtool.h | |||
| @@ -1591,7 +1591,7 @@ enum ethtool_link_mode_bit_indices { | |||
| 1591 | 1591 | ||
| 1592 | static inline int ethtool_validate_speed(__u32 speed) | 1592 | static inline int ethtool_validate_speed(__u32 speed) |
| 1593 | { | 1593 | { |
| 1594 | return speed <= INT_MAX || speed == SPEED_UNKNOWN; | 1594 | return speed <= INT_MAX || speed == (__u32)SPEED_UNKNOWN; |
| 1595 | } | 1595 | } |
| 1596 | 1596 | ||
| 1597 | /* Duplex, half or full. */ | 1597 | /* Duplex, half or full. */ |
diff --git a/include/uapi/sound/asound.h b/include/uapi/sound/asound.h index 404d4b9ffe76..df1153cea0b7 100644 --- a/include/uapi/sound/asound.h +++ b/include/uapi/sound/asound.h | |||
| @@ -32,6 +32,7 @@ | |||
| 32 | 32 | ||
| 33 | #ifndef __KERNEL__ | 33 | #ifndef __KERNEL__ |
| 34 | #include <stdlib.h> | 34 | #include <stdlib.h> |
| 35 | #include <time.h> | ||
| 35 | #endif | 36 | #endif |
| 36 | 37 | ||
| 37 | /* | 38 | /* |
diff --git a/kernel/dma/debug.c b/kernel/dma/debug.c index 45d51e8e26f6..a218e43cc382 100644 --- a/kernel/dma/debug.c +++ b/kernel/dma/debug.c | |||
| @@ -706,7 +706,7 @@ static struct dma_debug_entry *dma_entry_alloc(void) | |||
| 706 | #ifdef CONFIG_STACKTRACE | 706 | #ifdef CONFIG_STACKTRACE |
| 707 | entry->stacktrace.max_entries = DMA_DEBUG_STACKTRACE_ENTRIES; | 707 | entry->stacktrace.max_entries = DMA_DEBUG_STACKTRACE_ENTRIES; |
| 708 | entry->stacktrace.entries = entry->st_entries; | 708 | entry->stacktrace.entries = entry->st_entries; |
| 709 | entry->stacktrace.skip = 2; | 709 | entry->stacktrace.skip = 1; |
| 710 | save_stack_trace(&entry->stacktrace); | 710 | save_stack_trace(&entry->stacktrace); |
| 711 | #endif | 711 | #endif |
| 712 | 712 | ||
diff --git a/kernel/events/core.c b/kernel/events/core.c index 72d06e302e99..534e01e7bc36 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c | |||
| @@ -2009,8 +2009,8 @@ event_sched_out(struct perf_event *event, | |||
| 2009 | event->pmu->del(event, 0); | 2009 | event->pmu->del(event, 0); |
| 2010 | event->oncpu = -1; | 2010 | event->oncpu = -1; |
| 2011 | 2011 | ||
| 2012 | if (event->pending_disable) { | 2012 | if (READ_ONCE(event->pending_disable) >= 0) { |
| 2013 | event->pending_disable = 0; | 2013 | WRITE_ONCE(event->pending_disable, -1); |
| 2014 | state = PERF_EVENT_STATE_OFF; | 2014 | state = PERF_EVENT_STATE_OFF; |
| 2015 | } | 2015 | } |
| 2016 | perf_event_set_state(event, state); | 2016 | perf_event_set_state(event, state); |
| @@ -2198,7 +2198,8 @@ EXPORT_SYMBOL_GPL(perf_event_disable); | |||
| 2198 | 2198 | ||
| 2199 | void perf_event_disable_inatomic(struct perf_event *event) | 2199 | void perf_event_disable_inatomic(struct perf_event *event) |
| 2200 | { | 2200 | { |
| 2201 | event->pending_disable = 1; | 2201 | WRITE_ONCE(event->pending_disable, smp_processor_id()); |
| 2202 | /* can fail, see perf_pending_event_disable() */ | ||
| 2202 | irq_work_queue(&event->pending); | 2203 | irq_work_queue(&event->pending); |
| 2203 | } | 2204 | } |
| 2204 | 2205 | ||
| @@ -5810,10 +5811,45 @@ void perf_event_wakeup(struct perf_event *event) | |||
| 5810 | } | 5811 | } |
| 5811 | } | 5812 | } |
| 5812 | 5813 | ||
| 5814 | static void perf_pending_event_disable(struct perf_event *event) | ||
| 5815 | { | ||
| 5816 | int cpu = READ_ONCE(event->pending_disable); | ||
| 5817 | |||
| 5818 | if (cpu < 0) | ||
| 5819 | return; | ||
| 5820 | |||
| 5821 | if (cpu == smp_processor_id()) { | ||
| 5822 | WRITE_ONCE(event->pending_disable, -1); | ||
| 5823 | perf_event_disable_local(event); | ||
| 5824 | return; | ||
| 5825 | } | ||
| 5826 | |||
| 5827 | /* | ||
| 5828 | * CPU-A CPU-B | ||
| 5829 | * | ||
| 5830 | * perf_event_disable_inatomic() | ||
| 5831 | * @pending_disable = CPU-A; | ||
| 5832 | * irq_work_queue(); | ||
| 5833 | * | ||
| 5834 | * sched-out | ||
| 5835 | * @pending_disable = -1; | ||
| 5836 | * | ||
| 5837 | * sched-in | ||
| 5838 | * perf_event_disable_inatomic() | ||
| 5839 | * @pending_disable = CPU-B; | ||
| 5840 | * irq_work_queue(); // FAILS | ||
| 5841 | * | ||
| 5842 | * irq_work_run() | ||
| 5843 | * perf_pending_event() | ||
| 5844 | * | ||
| 5845 | * But the event runs on CPU-B and wants disabling there. | ||
| 5846 | */ | ||
| 5847 | irq_work_queue_on(&event->pending, cpu); | ||
| 5848 | } | ||
| 5849 | |||
| 5813 | static void perf_pending_event(struct irq_work *entry) | 5850 | static void perf_pending_event(struct irq_work *entry) |
| 5814 | { | 5851 | { |
| 5815 | struct perf_event *event = container_of(entry, | 5852 | struct perf_event *event = container_of(entry, struct perf_event, pending); |
| 5816 | struct perf_event, pending); | ||
| 5817 | int rctx; | 5853 | int rctx; |
| 5818 | 5854 | ||
| 5819 | rctx = perf_swevent_get_recursion_context(); | 5855 | rctx = perf_swevent_get_recursion_context(); |
| @@ -5822,10 +5858,7 @@ static void perf_pending_event(struct irq_work *entry) | |||
| 5822 | * and we won't recurse 'further'. | 5858 | * and we won't recurse 'further'. |
| 5823 | */ | 5859 | */ |
| 5824 | 5860 | ||
| 5825 | if (event->pending_disable) { | 5861 | perf_pending_event_disable(event); |
| 5826 | event->pending_disable = 0; | ||
| 5827 | perf_event_disable_local(event); | ||
| 5828 | } | ||
| 5829 | 5862 | ||
| 5830 | if (event->pending_wakeup) { | 5863 | if (event->pending_wakeup) { |
| 5831 | event->pending_wakeup = 0; | 5864 | event->pending_wakeup = 0; |
| @@ -10236,6 +10269,7 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu, | |||
| 10236 | 10269 | ||
| 10237 | 10270 | ||
| 10238 | init_waitqueue_head(&event->waitq); | 10271 | init_waitqueue_head(&event->waitq); |
| 10272 | event->pending_disable = -1; | ||
| 10239 | init_irq_work(&event->pending, perf_pending_event); | 10273 | init_irq_work(&event->pending, perf_pending_event); |
| 10240 | 10274 | ||
| 10241 | mutex_init(&event->mmap_mutex); | 10275 | mutex_init(&event->mmap_mutex); |
diff --git a/kernel/events/ring_buffer.c b/kernel/events/ring_buffer.c index a4047321d7d8..2545ac08cc77 100644 --- a/kernel/events/ring_buffer.c +++ b/kernel/events/ring_buffer.c | |||
| @@ -392,7 +392,7 @@ void *perf_aux_output_begin(struct perf_output_handle *handle, | |||
| 392 | * store that will be enabled on successful return | 392 | * store that will be enabled on successful return |
| 393 | */ | 393 | */ |
| 394 | if (!handle->size) { /* A, matches D */ | 394 | if (!handle->size) { /* A, matches D */ |
| 395 | event->pending_disable = 1; | 395 | event->pending_disable = smp_processor_id(); |
| 396 | perf_output_wakeup(handle); | 396 | perf_output_wakeup(handle); |
| 397 | local_set(&rb->aux_nest, 0); | 397 | local_set(&rb->aux_nest, 0); |
| 398 | goto err_put; | 398 | goto err_put; |
| @@ -480,7 +480,7 @@ void perf_aux_output_end(struct perf_output_handle *handle, unsigned long size) | |||
| 480 | 480 | ||
| 481 | if (wakeup) { | 481 | if (wakeup) { |
| 482 | if (handle->aux_flags & PERF_AUX_FLAG_TRUNCATED) | 482 | if (handle->aux_flags & PERF_AUX_FLAG_TRUNCATED) |
| 483 | handle->event->pending_disable = 1; | 483 | handle->event->pending_disable = smp_processor_id(); |
| 484 | perf_output_wakeup(handle); | 484 | perf_output_wakeup(handle); |
| 485 | } | 485 | } |
| 486 | 486 | ||
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c index 3faef4a77f71..51128bea3846 100644 --- a/kernel/irq/chip.c +++ b/kernel/irq/chip.c | |||
| @@ -1449,6 +1449,10 @@ int irq_chip_set_vcpu_affinity_parent(struct irq_data *data, void *vcpu_info) | |||
| 1449 | int irq_chip_set_wake_parent(struct irq_data *data, unsigned int on) | 1449 | int irq_chip_set_wake_parent(struct irq_data *data, unsigned int on) |
| 1450 | { | 1450 | { |
| 1451 | data = data->parent_data; | 1451 | data = data->parent_data; |
| 1452 | |||
| 1453 | if (data->chip->flags & IRQCHIP_SKIP_SET_WAKE) | ||
| 1454 | return 0; | ||
| 1455 | |||
| 1452 | if (data->chip->irq_set_wake) | 1456 | if (data->chip->irq_set_wake) |
| 1453 | return data->chip->irq_set_wake(data, on); | 1457 | return data->chip->irq_set_wake(data, on); |
| 1454 | 1458 | ||
diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c index 13539e12cd80..9f8a709337cf 100644 --- a/kernel/irq/irqdesc.c +++ b/kernel/irq/irqdesc.c | |||
| @@ -558,6 +558,7 @@ int __init early_irq_init(void) | |||
| 558 | alloc_masks(&desc[i], node); | 558 | alloc_masks(&desc[i], node); |
| 559 | raw_spin_lock_init(&desc[i].lock); | 559 | raw_spin_lock_init(&desc[i].lock); |
| 560 | lockdep_set_class(&desc[i].lock, &irq_desc_lock_class); | 560 | lockdep_set_class(&desc[i].lock, &irq_desc_lock_class); |
| 561 | mutex_init(&desc[i].request_mutex); | ||
| 561 | desc_set_defaults(i, &desc[i], node, NULL, NULL); | 562 | desc_set_defaults(i, &desc[i], node, NULL, NULL); |
| 562 | } | 563 | } |
| 563 | return arch_early_irq_init(); | 564 | return arch_early_irq_init(); |
diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c index 34cdcbedda49..e16766ff184b 100644 --- a/kernel/locking/lockdep.c +++ b/kernel/locking/lockdep.c | |||
| @@ -4689,8 +4689,8 @@ static void free_zapped_rcu(struct rcu_head *ch) | |||
| 4689 | return; | 4689 | return; |
| 4690 | 4690 | ||
| 4691 | raw_local_irq_save(flags); | 4691 | raw_local_irq_save(flags); |
| 4692 | if (!graph_lock()) | 4692 | arch_spin_lock(&lockdep_lock); |
| 4693 | goto out_irq; | 4693 | current->lockdep_recursion = 1; |
| 4694 | 4694 | ||
| 4695 | /* closed head */ | 4695 | /* closed head */ |
| 4696 | pf = delayed_free.pf + (delayed_free.index ^ 1); | 4696 | pf = delayed_free.pf + (delayed_free.index ^ 1); |
| @@ -4702,8 +4702,8 @@ static void free_zapped_rcu(struct rcu_head *ch) | |||
| 4702 | */ | 4702 | */ |
| 4703 | call_rcu_zapped(delayed_free.pf + delayed_free.index); | 4703 | call_rcu_zapped(delayed_free.pf + delayed_free.index); |
| 4704 | 4704 | ||
| 4705 | graph_unlock(); | 4705 | current->lockdep_recursion = 0; |
| 4706 | out_irq: | 4706 | arch_spin_unlock(&lockdep_lock); |
| 4707 | raw_local_irq_restore(flags); | 4707 | raw_local_irq_restore(flags); |
| 4708 | } | 4708 | } |
| 4709 | 4709 | ||
| @@ -4744,21 +4744,17 @@ static void lockdep_free_key_range_reg(void *start, unsigned long size) | |||
| 4744 | { | 4744 | { |
| 4745 | struct pending_free *pf; | 4745 | struct pending_free *pf; |
| 4746 | unsigned long flags; | 4746 | unsigned long flags; |
| 4747 | int locked; | ||
| 4748 | 4747 | ||
| 4749 | init_data_structures_once(); | 4748 | init_data_structures_once(); |
| 4750 | 4749 | ||
| 4751 | raw_local_irq_save(flags); | 4750 | raw_local_irq_save(flags); |
| 4752 | locked = graph_lock(); | 4751 | arch_spin_lock(&lockdep_lock); |
| 4753 | if (!locked) | 4752 | current->lockdep_recursion = 1; |
| 4754 | goto out_irq; | ||
| 4755 | |||
| 4756 | pf = get_pending_free(); | 4753 | pf = get_pending_free(); |
| 4757 | __lockdep_free_key_range(pf, start, size); | 4754 | __lockdep_free_key_range(pf, start, size); |
| 4758 | call_rcu_zapped(pf); | 4755 | call_rcu_zapped(pf); |
| 4759 | 4756 | current->lockdep_recursion = 0; | |
| 4760 | graph_unlock(); | 4757 | arch_spin_unlock(&lockdep_lock); |
| 4761 | out_irq: | ||
| 4762 | raw_local_irq_restore(flags); | 4758 | raw_local_irq_restore(flags); |
| 4763 | 4759 | ||
| 4764 | /* | 4760 | /* |
| @@ -4911,9 +4907,8 @@ void lockdep_unregister_key(struct lock_class_key *key) | |||
| 4911 | return; | 4907 | return; |
| 4912 | 4908 | ||
| 4913 | raw_local_irq_save(flags); | 4909 | raw_local_irq_save(flags); |
| 4914 | if (!graph_lock()) | 4910 | arch_spin_lock(&lockdep_lock); |
| 4915 | goto out_irq; | 4911 | current->lockdep_recursion = 1; |
| 4916 | |||
| 4917 | pf = get_pending_free(); | 4912 | pf = get_pending_free(); |
| 4918 | hlist_for_each_entry_rcu(k, hash_head, hash_entry) { | 4913 | hlist_for_each_entry_rcu(k, hash_head, hash_entry) { |
| 4919 | if (k == key) { | 4914 | if (k == key) { |
| @@ -4925,8 +4920,8 @@ void lockdep_unregister_key(struct lock_class_key *key) | |||
| 4925 | WARN_ON_ONCE(!found); | 4920 | WARN_ON_ONCE(!found); |
| 4926 | __lockdep_free_key_range(pf, key, 1); | 4921 | __lockdep_free_key_range(pf, key, 1); |
| 4927 | call_rcu_zapped(pf); | 4922 | call_rcu_zapped(pf); |
| 4928 | graph_unlock(); | 4923 | current->lockdep_recursion = 0; |
| 4929 | out_irq: | 4924 | arch_spin_unlock(&lockdep_lock); |
| 4930 | raw_local_irq_restore(flags); | 4925 | raw_local_irq_restore(flags); |
| 4931 | 4926 | ||
| 4932 | /* Wait until is_dynamic_key() has finished accessing k->hash_entry. */ | 4927 | /* Wait until is_dynamic_key() has finished accessing k->hash_entry. */ |
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index fdab7eb6f351..40bd1e27b1b7 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c | |||
| @@ -7784,10 +7784,10 @@ static void update_cfs_rq_h_load(struct cfs_rq *cfs_rq) | |||
| 7784 | if (cfs_rq->last_h_load_update == now) | 7784 | if (cfs_rq->last_h_load_update == now) |
| 7785 | return; | 7785 | return; |
| 7786 | 7786 | ||
| 7787 | cfs_rq->h_load_next = NULL; | 7787 | WRITE_ONCE(cfs_rq->h_load_next, NULL); |
| 7788 | for_each_sched_entity(se) { | 7788 | for_each_sched_entity(se) { |
| 7789 | cfs_rq = cfs_rq_of(se); | 7789 | cfs_rq = cfs_rq_of(se); |
| 7790 | cfs_rq->h_load_next = se; | 7790 | WRITE_ONCE(cfs_rq->h_load_next, se); |
| 7791 | if (cfs_rq->last_h_load_update == now) | 7791 | if (cfs_rq->last_h_load_update == now) |
| 7792 | break; | 7792 | break; |
| 7793 | } | 7793 | } |
| @@ -7797,7 +7797,7 @@ static void update_cfs_rq_h_load(struct cfs_rq *cfs_rq) | |||
| 7797 | cfs_rq->last_h_load_update = now; | 7797 | cfs_rq->last_h_load_update = now; |
| 7798 | } | 7798 | } |
| 7799 | 7799 | ||
| 7800 | while ((se = cfs_rq->h_load_next) != NULL) { | 7800 | while ((se = READ_ONCE(cfs_rq->h_load_next)) != NULL) { |
| 7801 | load = cfs_rq->h_load; | 7801 | load = cfs_rq->h_load; |
| 7802 | load = div64_ul(load * se->avg.load_avg, | 7802 | load = div64_ul(load * se->avg.load_avg, |
| 7803 | cfs_rq_load_avg(cfs_rq) + 1); | 7803 | cfs_rq_load_avg(cfs_rq) + 1); |
diff --git a/kernel/time/alarmtimer.c b/kernel/time/alarmtimer.c index 2c97e8c2d29f..0519a8805aab 100644 --- a/kernel/time/alarmtimer.c +++ b/kernel/time/alarmtimer.c | |||
| @@ -594,7 +594,7 @@ static ktime_t alarm_timer_remaining(struct k_itimer *timr, ktime_t now) | |||
| 594 | { | 594 | { |
| 595 | struct alarm *alarm = &timr->it.alarm.alarmtimer; | 595 | struct alarm *alarm = &timr->it.alarm.alarmtimer; |
| 596 | 596 | ||
| 597 | return ktime_sub(now, alarm->node.expires); | 597 | return ktime_sub(alarm->node.expires, now); |
| 598 | } | 598 | } |
| 599 | 599 | ||
| 600 | /** | 600 | /** |
diff --git a/lib/iov_iter.c b/lib/iov_iter.c index ea36dc355da1..b396d328a764 100644 --- a/lib/iov_iter.c +++ b/lib/iov_iter.c | |||
| @@ -1528,6 +1528,7 @@ EXPORT_SYMBOL(csum_and_copy_to_iter); | |||
| 1528 | size_t hash_and_copy_to_iter(const void *addr, size_t bytes, void *hashp, | 1528 | size_t hash_and_copy_to_iter(const void *addr, size_t bytes, void *hashp, |
| 1529 | struct iov_iter *i) | 1529 | struct iov_iter *i) |
| 1530 | { | 1530 | { |
| 1531 | #ifdef CONFIG_CRYPTO | ||
| 1531 | struct ahash_request *hash = hashp; | 1532 | struct ahash_request *hash = hashp; |
| 1532 | struct scatterlist sg; | 1533 | struct scatterlist sg; |
| 1533 | size_t copied; | 1534 | size_t copied; |
| @@ -1537,6 +1538,9 @@ size_t hash_and_copy_to_iter(const void *addr, size_t bytes, void *hashp, | |||
| 1537 | ahash_request_set_crypt(hash, &sg, NULL, copied); | 1538 | ahash_request_set_crypt(hash, &sg, NULL, copied); |
| 1538 | crypto_ahash_update(hash); | 1539 | crypto_ahash_update(hash); |
| 1539 | return copied; | 1540 | return copied; |
| 1541 | #else | ||
| 1542 | return 0; | ||
| 1543 | #endif | ||
| 1540 | } | 1544 | } |
| 1541 | EXPORT_SYMBOL(hash_and_copy_to_iter); | 1545 | EXPORT_SYMBOL(hash_and_copy_to_iter); |
| 1542 | 1546 | ||
| @@ -4308,7 +4308,8 @@ static void show_symbol(struct seq_file *m, unsigned long address) | |||
| 4308 | 4308 | ||
| 4309 | static int leaks_show(struct seq_file *m, void *p) | 4309 | static int leaks_show(struct seq_file *m, void *p) |
| 4310 | { | 4310 | { |
| 4311 | struct kmem_cache *cachep = list_entry(p, struct kmem_cache, list); | 4311 | struct kmem_cache *cachep = list_entry(p, struct kmem_cache, |
| 4312 | root_caches_node); | ||
| 4312 | struct page *page; | 4313 | struct page *page; |
| 4313 | struct kmem_cache_node *n; | 4314 | struct kmem_cache_node *n; |
| 4314 | const char *name; | 4315 | const char *name; |
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index fd219f7bd3ea..4b0526441476 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c | |||
| @@ -259,7 +259,6 @@ static int erspan_rcv(struct sk_buff *skb, struct tnl_ptk_info *tpi, | |||
| 259 | struct net *net = dev_net(skb->dev); | 259 | struct net *net = dev_net(skb->dev); |
| 260 | struct metadata_dst *tun_dst = NULL; | 260 | struct metadata_dst *tun_dst = NULL; |
| 261 | struct erspan_base_hdr *ershdr; | 261 | struct erspan_base_hdr *ershdr; |
| 262 | struct erspan_metadata *pkt_md; | ||
| 263 | struct ip_tunnel_net *itn; | 262 | struct ip_tunnel_net *itn; |
| 264 | struct ip_tunnel *tunnel; | 263 | struct ip_tunnel *tunnel; |
| 265 | const struct iphdr *iph; | 264 | const struct iphdr *iph; |
| @@ -282,9 +281,6 @@ static int erspan_rcv(struct sk_buff *skb, struct tnl_ptk_info *tpi, | |||
| 282 | if (unlikely(!pskb_may_pull(skb, len))) | 281 | if (unlikely(!pskb_may_pull(skb, len))) |
| 283 | return PACKET_REJECT; | 282 | return PACKET_REJECT; |
| 284 | 283 | ||
| 285 | ershdr = (struct erspan_base_hdr *)(skb->data + gre_hdr_len); | ||
| 286 | pkt_md = (struct erspan_metadata *)(ershdr + 1); | ||
| 287 | |||
| 288 | if (__iptunnel_pull_header(skb, | 284 | if (__iptunnel_pull_header(skb, |
| 289 | len, | 285 | len, |
| 290 | htons(ETH_P_TEB), | 286 | htons(ETH_P_TEB), |
| @@ -292,8 +288,9 @@ static int erspan_rcv(struct sk_buff *skb, struct tnl_ptk_info *tpi, | |||
| 292 | goto drop; | 288 | goto drop; |
| 293 | 289 | ||
| 294 | if (tunnel->collect_md) { | 290 | if (tunnel->collect_md) { |
| 291 | struct erspan_metadata *pkt_md, *md; | ||
| 295 | struct ip_tunnel_info *info; | 292 | struct ip_tunnel_info *info; |
| 296 | struct erspan_metadata *md; | 293 | unsigned char *gh; |
| 297 | __be64 tun_id; | 294 | __be64 tun_id; |
| 298 | __be16 flags; | 295 | __be16 flags; |
| 299 | 296 | ||
| @@ -306,6 +303,14 @@ static int erspan_rcv(struct sk_buff *skb, struct tnl_ptk_info *tpi, | |||
| 306 | if (!tun_dst) | 303 | if (!tun_dst) |
| 307 | return PACKET_REJECT; | 304 | return PACKET_REJECT; |
| 308 | 305 | ||
| 306 | /* skb can be uncloned in __iptunnel_pull_header, so | ||
| 307 | * old pkt_md is no longer valid and we need to reset | ||
| 308 | * it | ||
| 309 | */ | ||
| 310 | gh = skb_network_header(skb) + | ||
| 311 | skb_network_header_len(skb); | ||
| 312 | pkt_md = (struct erspan_metadata *)(gh + gre_hdr_len + | ||
| 313 | sizeof(*ershdr)); | ||
| 309 | md = ip_tunnel_info_opts(&tun_dst->u.tun_info); | 314 | md = ip_tunnel_info_opts(&tun_dst->u.tun_info); |
| 310 | md->version = ver; | 315 | md->version = ver; |
| 311 | md2 = &md->u.md2; | 316 | md2 = &md->u.md2; |
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c index b32c95f02128..655e46b227f9 100644 --- a/net/ipv6/ip6_gre.c +++ b/net/ipv6/ip6_gre.c | |||
| @@ -525,10 +525,10 @@ static int ip6gre_rcv(struct sk_buff *skb, const struct tnl_ptk_info *tpi) | |||
| 525 | } | 525 | } |
| 526 | 526 | ||
| 527 | static int ip6erspan_rcv(struct sk_buff *skb, | 527 | static int ip6erspan_rcv(struct sk_buff *skb, |
| 528 | struct tnl_ptk_info *tpi) | 528 | struct tnl_ptk_info *tpi, |
| 529 | int gre_hdr_len) | ||
| 529 | { | 530 | { |
| 530 | struct erspan_base_hdr *ershdr; | 531 | struct erspan_base_hdr *ershdr; |
| 531 | struct erspan_metadata *pkt_md; | ||
| 532 | const struct ipv6hdr *ipv6h; | 532 | const struct ipv6hdr *ipv6h; |
| 533 | struct erspan_md2 *md2; | 533 | struct erspan_md2 *md2; |
| 534 | struct ip6_tnl *tunnel; | 534 | struct ip6_tnl *tunnel; |
| @@ -547,18 +547,16 @@ static int ip6erspan_rcv(struct sk_buff *skb, | |||
| 547 | if (unlikely(!pskb_may_pull(skb, len))) | 547 | if (unlikely(!pskb_may_pull(skb, len))) |
| 548 | return PACKET_REJECT; | 548 | return PACKET_REJECT; |
| 549 | 549 | ||
| 550 | ershdr = (struct erspan_base_hdr *)skb->data; | ||
| 551 | pkt_md = (struct erspan_metadata *)(ershdr + 1); | ||
| 552 | |||
| 553 | if (__iptunnel_pull_header(skb, len, | 550 | if (__iptunnel_pull_header(skb, len, |
| 554 | htons(ETH_P_TEB), | 551 | htons(ETH_P_TEB), |
| 555 | false, false) < 0) | 552 | false, false) < 0) |
| 556 | return PACKET_REJECT; | 553 | return PACKET_REJECT; |
| 557 | 554 | ||
| 558 | if (tunnel->parms.collect_md) { | 555 | if (tunnel->parms.collect_md) { |
| 556 | struct erspan_metadata *pkt_md, *md; | ||
| 559 | struct metadata_dst *tun_dst; | 557 | struct metadata_dst *tun_dst; |
| 560 | struct ip_tunnel_info *info; | 558 | struct ip_tunnel_info *info; |
| 561 | struct erspan_metadata *md; | 559 | unsigned char *gh; |
| 562 | __be64 tun_id; | 560 | __be64 tun_id; |
| 563 | __be16 flags; | 561 | __be16 flags; |
| 564 | 562 | ||
| @@ -571,6 +569,14 @@ static int ip6erspan_rcv(struct sk_buff *skb, | |||
| 571 | if (!tun_dst) | 569 | if (!tun_dst) |
| 572 | return PACKET_REJECT; | 570 | return PACKET_REJECT; |
| 573 | 571 | ||
| 572 | /* skb can be uncloned in __iptunnel_pull_header, so | ||
| 573 | * old pkt_md is no longer valid and we need to reset | ||
| 574 | * it | ||
| 575 | */ | ||
| 576 | gh = skb_network_header(skb) + | ||
| 577 | skb_network_header_len(skb); | ||
| 578 | pkt_md = (struct erspan_metadata *)(gh + gre_hdr_len + | ||
| 579 | sizeof(*ershdr)); | ||
| 574 | info = &tun_dst->u.tun_info; | 580 | info = &tun_dst->u.tun_info; |
| 575 | md = ip_tunnel_info_opts(info); | 581 | md = ip_tunnel_info_opts(info); |
| 576 | md->version = ver; | 582 | md->version = ver; |
| @@ -607,7 +613,7 @@ static int gre_rcv(struct sk_buff *skb) | |||
| 607 | 613 | ||
| 608 | if (unlikely(tpi.proto == htons(ETH_P_ERSPAN) || | 614 | if (unlikely(tpi.proto == htons(ETH_P_ERSPAN) || |
| 609 | tpi.proto == htons(ETH_P_ERSPAN2))) { | 615 | tpi.proto == htons(ETH_P_ERSPAN2))) { |
| 610 | if (ip6erspan_rcv(skb, &tpi) == PACKET_RCVD) | 616 | if (ip6erspan_rcv(skb, &tpi, hdr_len) == PACKET_RCVD) |
| 611 | return 0; | 617 | return 0; |
| 612 | goto out; | 618 | goto out; |
| 613 | } | 619 | } |
diff --git a/net/nfc/nci/hci.c b/net/nfc/nci/hci.c index ddfc52ac1f9b..c0d323b58e73 100644 --- a/net/nfc/nci/hci.c +++ b/net/nfc/nci/hci.c | |||
| @@ -312,6 +312,10 @@ static void nci_hci_cmd_received(struct nci_dev *ndev, u8 pipe, | |||
| 312 | create_info = (struct nci_hci_create_pipe_resp *)skb->data; | 312 | create_info = (struct nci_hci_create_pipe_resp *)skb->data; |
| 313 | dest_gate = create_info->dest_gate; | 313 | dest_gate = create_info->dest_gate; |
| 314 | new_pipe = create_info->pipe; | 314 | new_pipe = create_info->pipe; |
| 315 | if (new_pipe >= NCI_HCI_MAX_PIPES) { | ||
| 316 | status = NCI_HCI_ANY_E_NOK; | ||
| 317 | goto exit; | ||
| 318 | } | ||
| 315 | 319 | ||
| 316 | /* Save the new created pipe and bind with local gate, | 320 | /* Save the new created pipe and bind with local gate, |
| 317 | * the description for skb->data[3] is destination gate id | 321 | * the description for skb->data[3] is destination gate id |
| @@ -336,6 +340,10 @@ static void nci_hci_cmd_received(struct nci_dev *ndev, u8 pipe, | |||
| 336 | goto exit; | 340 | goto exit; |
| 337 | } | 341 | } |
| 338 | delete_info = (struct nci_hci_delete_pipe_noti *)skb->data; | 342 | delete_info = (struct nci_hci_delete_pipe_noti *)skb->data; |
| 343 | if (delete_info->pipe >= NCI_HCI_MAX_PIPES) { | ||
| 344 | status = NCI_HCI_ANY_E_NOK; | ||
| 345 | goto exit; | ||
| 346 | } | ||
| 339 | 347 | ||
| 340 | ndev->hci_dev->pipes[delete_info->pipe].gate = | 348 | ndev->hci_dev->pipes[delete_info->pipe].gate = |
| 341 | NCI_HCI_INVALID_GATE; | 349 | NCI_HCI_INVALID_GATE; |
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 187d10443a15..1d0395ef62c9 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c | |||
| @@ -1540,7 +1540,6 @@ call_start(struct rpc_task *task) | |||
| 1540 | clnt->cl_stats->rpccnt++; | 1540 | clnt->cl_stats->rpccnt++; |
| 1541 | task->tk_action = call_reserve; | 1541 | task->tk_action = call_reserve; |
| 1542 | rpc_task_set_transport(task, clnt); | 1542 | rpc_task_set_transport(task, clnt); |
| 1543 | call_reserve(task); | ||
| 1544 | } | 1543 | } |
| 1545 | 1544 | ||
| 1546 | /* | 1545 | /* |
| @@ -1554,9 +1553,6 @@ call_reserve(struct rpc_task *task) | |||
| 1554 | task->tk_status = 0; | 1553 | task->tk_status = 0; |
| 1555 | task->tk_action = call_reserveresult; | 1554 | task->tk_action = call_reserveresult; |
| 1556 | xprt_reserve(task); | 1555 | xprt_reserve(task); |
| 1557 | if (rpc_task_need_resched(task)) | ||
| 1558 | return; | ||
| 1559 | call_reserveresult(task); | ||
| 1560 | } | 1556 | } |
| 1561 | 1557 | ||
| 1562 | static void call_retry_reserve(struct rpc_task *task); | 1558 | static void call_retry_reserve(struct rpc_task *task); |
| @@ -1579,7 +1575,6 @@ call_reserveresult(struct rpc_task *task) | |||
| 1579 | if (status >= 0) { | 1575 | if (status >= 0) { |
| 1580 | if (task->tk_rqstp) { | 1576 | if (task->tk_rqstp) { |
| 1581 | task->tk_action = call_refresh; | 1577 | task->tk_action = call_refresh; |
| 1582 | call_refresh(task); | ||
| 1583 | return; | 1578 | return; |
| 1584 | } | 1579 | } |
| 1585 | 1580 | ||
| @@ -1605,7 +1600,6 @@ call_reserveresult(struct rpc_task *task) | |||
| 1605 | /* fall through */ | 1600 | /* fall through */ |
| 1606 | case -EAGAIN: /* woken up; retry */ | 1601 | case -EAGAIN: /* woken up; retry */ |
| 1607 | task->tk_action = call_retry_reserve; | 1602 | task->tk_action = call_retry_reserve; |
| 1608 | call_retry_reserve(task); | ||
| 1609 | return; | 1603 | return; |
| 1610 | case -EIO: /* probably a shutdown */ | 1604 | case -EIO: /* probably a shutdown */ |
| 1611 | break; | 1605 | break; |
| @@ -1628,9 +1622,6 @@ call_retry_reserve(struct rpc_task *task) | |||
| 1628 | task->tk_status = 0; | 1622 | task->tk_status = 0; |
| 1629 | task->tk_action = call_reserveresult; | 1623 | task->tk_action = call_reserveresult; |
| 1630 | xprt_retry_reserve(task); | 1624 | xprt_retry_reserve(task); |
| 1631 | if (rpc_task_need_resched(task)) | ||
| 1632 | return; | ||
| 1633 | call_reserveresult(task); | ||
| 1634 | } | 1625 | } |
| 1635 | 1626 | ||
| 1636 | /* | 1627 | /* |
| @@ -1645,9 +1636,6 @@ call_refresh(struct rpc_task *task) | |||
| 1645 | task->tk_status = 0; | 1636 | task->tk_status = 0; |
| 1646 | task->tk_client->cl_stats->rpcauthrefresh++; | 1637 | task->tk_client->cl_stats->rpcauthrefresh++; |
| 1647 | rpcauth_refreshcred(task); | 1638 | rpcauth_refreshcred(task); |
| 1648 | if (rpc_task_need_resched(task)) | ||
| 1649 | return; | ||
| 1650 | call_refreshresult(task); | ||
| 1651 | } | 1639 | } |
| 1652 | 1640 | ||
| 1653 | /* | 1641 | /* |
| @@ -1666,7 +1654,6 @@ call_refreshresult(struct rpc_task *task) | |||
| 1666 | case 0: | 1654 | case 0: |
| 1667 | if (rpcauth_uptodatecred(task)) { | 1655 | if (rpcauth_uptodatecred(task)) { |
| 1668 | task->tk_action = call_allocate; | 1656 | task->tk_action = call_allocate; |
| 1669 | call_allocate(task); | ||
| 1670 | return; | 1657 | return; |
| 1671 | } | 1658 | } |
| 1672 | /* Use rate-limiting and a max number of retries if refresh | 1659 | /* Use rate-limiting and a max number of retries if refresh |
| @@ -1685,7 +1672,6 @@ call_refreshresult(struct rpc_task *task) | |||
| 1685 | task->tk_cred_retry--; | 1672 | task->tk_cred_retry--; |
| 1686 | dprintk("RPC: %5u %s: retry refresh creds\n", | 1673 | dprintk("RPC: %5u %s: retry refresh creds\n", |
| 1687 | task->tk_pid, __func__); | 1674 | task->tk_pid, __func__); |
| 1688 | call_refresh(task); | ||
| 1689 | return; | 1675 | return; |
| 1690 | } | 1676 | } |
| 1691 | dprintk("RPC: %5u %s: refresh creds failed with error %d\n", | 1677 | dprintk("RPC: %5u %s: refresh creds failed with error %d\n", |
| @@ -1711,10 +1697,8 @@ call_allocate(struct rpc_task *task) | |||
| 1711 | task->tk_status = 0; | 1697 | task->tk_status = 0; |
| 1712 | task->tk_action = call_encode; | 1698 | task->tk_action = call_encode; |
| 1713 | 1699 | ||
| 1714 | if (req->rq_buffer) { | 1700 | if (req->rq_buffer) |
| 1715 | call_encode(task); | ||
| 1716 | return; | 1701 | return; |
| 1717 | } | ||
| 1718 | 1702 | ||
| 1719 | if (proc->p_proc != 0) { | 1703 | if (proc->p_proc != 0) { |
| 1720 | BUG_ON(proc->p_arglen == 0); | 1704 | BUG_ON(proc->p_arglen == 0); |
| @@ -1740,12 +1724,8 @@ call_allocate(struct rpc_task *task) | |||
| 1740 | 1724 | ||
| 1741 | status = xprt->ops->buf_alloc(task); | 1725 | status = xprt->ops->buf_alloc(task); |
| 1742 | xprt_inject_disconnect(xprt); | 1726 | xprt_inject_disconnect(xprt); |
| 1743 | if (status == 0) { | 1727 | if (status == 0) |
| 1744 | if (rpc_task_need_resched(task)) | ||
| 1745 | return; | ||
| 1746 | call_encode(task); | ||
| 1747 | return; | 1728 | return; |
| 1748 | } | ||
| 1749 | if (status != -ENOMEM) { | 1729 | if (status != -ENOMEM) { |
| 1750 | rpc_exit(task, status); | 1730 | rpc_exit(task, status); |
| 1751 | return; | 1731 | return; |
| @@ -1828,8 +1808,12 @@ call_encode(struct rpc_task *task) | |||
| 1828 | xprt_request_enqueue_receive(task); | 1808 | xprt_request_enqueue_receive(task); |
| 1829 | xprt_request_enqueue_transmit(task); | 1809 | xprt_request_enqueue_transmit(task); |
| 1830 | out: | 1810 | out: |
| 1831 | task->tk_action = call_bind; | 1811 | task->tk_action = call_transmit; |
| 1832 | call_bind(task); | 1812 | /* Check that the connection is OK */ |
| 1813 | if (!xprt_bound(task->tk_xprt)) | ||
| 1814 | task->tk_action = call_bind; | ||
| 1815 | else if (!xprt_connected(task->tk_xprt)) | ||
| 1816 | task->tk_action = call_connect; | ||
| 1833 | } | 1817 | } |
| 1834 | 1818 | ||
| 1835 | /* | 1819 | /* |
| @@ -1847,7 +1831,6 @@ rpc_task_handle_transmitted(struct rpc_task *task) | |||
| 1847 | { | 1831 | { |
| 1848 | xprt_end_transmit(task); | 1832 | xprt_end_transmit(task); |
| 1849 | task->tk_action = call_transmit_status; | 1833 | task->tk_action = call_transmit_status; |
| 1850 | call_transmit_status(task); | ||
| 1851 | } | 1834 | } |
| 1852 | 1835 | ||
| 1853 | /* | 1836 | /* |
| @@ -1865,7 +1848,6 @@ call_bind(struct rpc_task *task) | |||
| 1865 | 1848 | ||
| 1866 | if (xprt_bound(xprt)) { | 1849 | if (xprt_bound(xprt)) { |
| 1867 | task->tk_action = call_connect; | 1850 | task->tk_action = call_connect; |
| 1868 | call_connect(task); | ||
| 1869 | return; | 1851 | return; |
| 1870 | } | 1852 | } |
| 1871 | 1853 | ||
| @@ -1896,7 +1878,6 @@ call_bind_status(struct rpc_task *task) | |||
| 1896 | dprint_status(task); | 1878 | dprint_status(task); |
| 1897 | task->tk_status = 0; | 1879 | task->tk_status = 0; |
| 1898 | task->tk_action = call_connect; | 1880 | task->tk_action = call_connect; |
| 1899 | call_connect(task); | ||
| 1900 | return; | 1881 | return; |
| 1901 | } | 1882 | } |
| 1902 | 1883 | ||
| @@ -1981,7 +1962,6 @@ call_connect(struct rpc_task *task) | |||
| 1981 | 1962 | ||
| 1982 | if (xprt_connected(xprt)) { | 1963 | if (xprt_connected(xprt)) { |
| 1983 | task->tk_action = call_transmit; | 1964 | task->tk_action = call_transmit; |
| 1984 | call_transmit(task); | ||
| 1985 | return; | 1965 | return; |
| 1986 | } | 1966 | } |
| 1987 | 1967 | ||
| @@ -2051,7 +2031,6 @@ call_connect_status(struct rpc_task *task) | |||
| 2051 | case 0: | 2031 | case 0: |
| 2052 | clnt->cl_stats->netreconn++; | 2032 | clnt->cl_stats->netreconn++; |
| 2053 | task->tk_action = call_transmit; | 2033 | task->tk_action = call_transmit; |
| 2054 | call_transmit(task); | ||
| 2055 | return; | 2034 | return; |
| 2056 | } | 2035 | } |
| 2057 | rpc_exit(task, status); | 2036 | rpc_exit(task, status); |
| @@ -2087,9 +2066,6 @@ call_transmit(struct rpc_task *task) | |||
| 2087 | xprt_transmit(task); | 2066 | xprt_transmit(task); |
| 2088 | } | 2067 | } |
| 2089 | xprt_end_transmit(task); | 2068 | xprt_end_transmit(task); |
| 2090 | if (rpc_task_need_resched(task)) | ||
| 2091 | return; | ||
| 2092 | call_transmit_status(task); | ||
| 2093 | } | 2069 | } |
| 2094 | 2070 | ||
| 2095 | /* | 2071 | /* |
| @@ -2107,9 +2083,6 @@ call_transmit_status(struct rpc_task *task) | |||
| 2107 | if (rpc_task_transmitted(task)) { | 2083 | if (rpc_task_transmitted(task)) { |
| 2108 | if (task->tk_status == 0) | 2084 | if (task->tk_status == 0) |
| 2109 | xprt_request_wait_receive(task); | 2085 | xprt_request_wait_receive(task); |
| 2110 | if (rpc_task_need_resched(task)) | ||
| 2111 | return; | ||
| 2112 | call_status(task); | ||
| 2113 | return; | 2086 | return; |
| 2114 | } | 2087 | } |
| 2115 | 2088 | ||
| @@ -2170,7 +2143,6 @@ call_bc_encode(struct rpc_task *task) | |||
| 2170 | { | 2143 | { |
| 2171 | xprt_request_enqueue_transmit(task); | 2144 | xprt_request_enqueue_transmit(task); |
| 2172 | task->tk_action = call_bc_transmit; | 2145 | task->tk_action = call_bc_transmit; |
| 2173 | call_bc_transmit(task); | ||
| 2174 | } | 2146 | } |
| 2175 | 2147 | ||
| 2176 | /* | 2148 | /* |
| @@ -2261,7 +2233,6 @@ call_status(struct rpc_task *task) | |||
| 2261 | status = task->tk_status; | 2233 | status = task->tk_status; |
| 2262 | if (status >= 0) { | 2234 | if (status >= 0) { |
| 2263 | task->tk_action = call_decode; | 2235 | task->tk_action = call_decode; |
| 2264 | call_decode(task); | ||
| 2265 | return; | 2236 | return; |
| 2266 | } | 2237 | } |
| 2267 | 2238 | ||
diff --git a/net/sunrpc/xprtrdma/verbs.c b/net/sunrpc/xprtrdma/verbs.c index 89a63391d4d4..30cfc0efe699 100644 --- a/net/sunrpc/xprtrdma/verbs.c +++ b/net/sunrpc/xprtrdma/verbs.c | |||
| @@ -90,7 +90,7 @@ static void rpcrdma_xprt_drain(struct rpcrdma_xprt *r_xprt) | |||
| 90 | /* Flush Receives, then wait for deferred Reply work | 90 | /* Flush Receives, then wait for deferred Reply work |
| 91 | * to complete. | 91 | * to complete. |
| 92 | */ | 92 | */ |
| 93 | ib_drain_qp(ia->ri_id->qp); | 93 | ib_drain_rq(ia->ri_id->qp); |
| 94 | drain_workqueue(buf->rb_completion_wq); | 94 | drain_workqueue(buf->rb_completion_wq); |
| 95 | 95 | ||
| 96 | /* Deferred Reply processing might have scheduled | 96 | /* Deferred Reply processing might have scheduled |
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c index 49d664ddff44..87500bde5a92 100644 --- a/security/apparmor/lsm.c +++ b/security/apparmor/lsm.c | |||
| @@ -1336,9 +1336,16 @@ module_param_named(path_max, aa_g_path_max, aauint, S_IRUSR); | |||
| 1336 | bool aa_g_paranoid_load = true; | 1336 | bool aa_g_paranoid_load = true; |
| 1337 | module_param_named(paranoid_load, aa_g_paranoid_load, aabool, S_IRUGO); | 1337 | module_param_named(paranoid_load, aa_g_paranoid_load, aabool, S_IRUGO); |
| 1338 | 1338 | ||
| 1339 | static int param_get_aaintbool(char *buffer, const struct kernel_param *kp); | ||
| 1340 | static int param_set_aaintbool(const char *val, const struct kernel_param *kp); | ||
| 1341 | #define param_check_aaintbool param_check_int | ||
| 1342 | static const struct kernel_param_ops param_ops_aaintbool = { | ||
| 1343 | .set = param_set_aaintbool, | ||
| 1344 | .get = param_get_aaintbool | ||
| 1345 | }; | ||
| 1339 | /* Boot time disable flag */ | 1346 | /* Boot time disable flag */ |
| 1340 | static int apparmor_enabled __lsm_ro_after_init = 1; | 1347 | static int apparmor_enabled __lsm_ro_after_init = 1; |
| 1341 | module_param_named(enabled, apparmor_enabled, int, 0444); | 1348 | module_param_named(enabled, apparmor_enabled, aaintbool, 0444); |
| 1342 | 1349 | ||
| 1343 | static int __init apparmor_enabled_setup(char *str) | 1350 | static int __init apparmor_enabled_setup(char *str) |
| 1344 | { | 1351 | { |
| @@ -1413,6 +1420,46 @@ static int param_get_aauint(char *buffer, const struct kernel_param *kp) | |||
| 1413 | return param_get_uint(buffer, kp); | 1420 | return param_get_uint(buffer, kp); |
| 1414 | } | 1421 | } |
| 1415 | 1422 | ||
| 1423 | /* Can only be set before AppArmor is initialized (i.e. on boot cmdline). */ | ||
| 1424 | static int param_set_aaintbool(const char *val, const struct kernel_param *kp) | ||
| 1425 | { | ||
| 1426 | struct kernel_param kp_local; | ||
| 1427 | bool value; | ||
| 1428 | int error; | ||
| 1429 | |||
| 1430 | if (apparmor_initialized) | ||
| 1431 | return -EPERM; | ||
| 1432 | |||
| 1433 | /* Create local copy, with arg pointing to bool type. */ | ||
| 1434 | value = !!*((int *)kp->arg); | ||
| 1435 | memcpy(&kp_local, kp, sizeof(kp_local)); | ||
| 1436 | kp_local.arg = &value; | ||
| 1437 | |||
| 1438 | error = param_set_bool(val, &kp_local); | ||
| 1439 | if (!error) | ||
| 1440 | *((int *)kp->arg) = *((bool *)kp_local.arg); | ||
| 1441 | return error; | ||
| 1442 | } | ||
| 1443 | |||
| 1444 | /* | ||
| 1445 | * To avoid changing /sys/module/apparmor/parameters/enabled from Y/N to | ||
| 1446 | * 1/0, this converts the "int that is actually bool" back to bool for | ||
| 1447 | * display in the /sys filesystem, while keeping it "int" for the LSM | ||
| 1448 | * infrastructure. | ||
| 1449 | */ | ||
| 1450 | static int param_get_aaintbool(char *buffer, const struct kernel_param *kp) | ||
| 1451 | { | ||
| 1452 | struct kernel_param kp_local; | ||
| 1453 | bool value; | ||
| 1454 | |||
| 1455 | /* Create local copy, with arg pointing to bool type. */ | ||
| 1456 | value = !!*((int *)kp->arg); | ||
| 1457 | memcpy(&kp_local, kp, sizeof(kp_local)); | ||
| 1458 | kp_local.arg = &value; | ||
| 1459 | |||
| 1460 | return param_get_bool(buffer, &kp_local); | ||
| 1461 | } | ||
| 1462 | |||
| 1416 | static int param_get_audit(char *buffer, const struct kernel_param *kp) | 1463 | static int param_get_audit(char *buffer, const struct kernel_param *kp) |
| 1417 | { | 1464 | { |
| 1418 | if (!apparmor_enabled) | 1465 | if (!apparmor_enabled) |
diff --git a/security/keys/trusted.c b/security/keys/trusted.c index bcc9c6ead7fd..efdbf17f3915 100644 --- a/security/keys/trusted.c +++ b/security/keys/trusted.c | |||
| @@ -125,7 +125,7 @@ out: | |||
| 125 | */ | 125 | */ |
| 126 | int TSS_authhmac(unsigned char *digest, const unsigned char *key, | 126 | int TSS_authhmac(unsigned char *digest, const unsigned char *key, |
| 127 | unsigned int keylen, unsigned char *h1, | 127 | unsigned int keylen, unsigned char *h1, |
| 128 | unsigned char *h2, unsigned char h3, ...) | 128 | unsigned char *h2, unsigned int h3, ...) |
| 129 | { | 129 | { |
| 130 | unsigned char paramdigest[SHA1_DIGEST_SIZE]; | 130 | unsigned char paramdigest[SHA1_DIGEST_SIZE]; |
| 131 | struct sdesc *sdesc; | 131 | struct sdesc *sdesc; |
| @@ -135,13 +135,16 @@ int TSS_authhmac(unsigned char *digest, const unsigned char *key, | |||
| 135 | int ret; | 135 | int ret; |
| 136 | va_list argp; | 136 | va_list argp; |
| 137 | 137 | ||
| 138 | if (!chip) | ||
| 139 | return -ENODEV; | ||
| 140 | |||
| 138 | sdesc = init_sdesc(hashalg); | 141 | sdesc = init_sdesc(hashalg); |
| 139 | if (IS_ERR(sdesc)) { | 142 | if (IS_ERR(sdesc)) { |
| 140 | pr_info("trusted_key: can't alloc %s\n", hash_alg); | 143 | pr_info("trusted_key: can't alloc %s\n", hash_alg); |
| 141 | return PTR_ERR(sdesc); | 144 | return PTR_ERR(sdesc); |
| 142 | } | 145 | } |
| 143 | 146 | ||
| 144 | c = h3; | 147 | c = !!h3; |
| 145 | ret = crypto_shash_init(&sdesc->shash); | 148 | ret = crypto_shash_init(&sdesc->shash); |
| 146 | if (ret < 0) | 149 | if (ret < 0) |
| 147 | goto out; | 150 | goto out; |
| @@ -196,6 +199,9 @@ int TSS_checkhmac1(unsigned char *buffer, | |||
| 196 | va_list argp; | 199 | va_list argp; |
| 197 | int ret; | 200 | int ret; |
| 198 | 201 | ||
| 202 | if (!chip) | ||
| 203 | return -ENODEV; | ||
| 204 | |||
| 199 | bufsize = LOAD32(buffer, TPM_SIZE_OFFSET); | 205 | bufsize = LOAD32(buffer, TPM_SIZE_OFFSET); |
| 200 | tag = LOAD16(buffer, 0); | 206 | tag = LOAD16(buffer, 0); |
| 201 | ordinal = command; | 207 | ordinal = command; |
| @@ -363,6 +369,9 @@ int trusted_tpm_send(unsigned char *cmd, size_t buflen) | |||
| 363 | { | 369 | { |
| 364 | int rc; | 370 | int rc; |
| 365 | 371 | ||
| 372 | if (!chip) | ||
| 373 | return -ENODEV; | ||
| 374 | |||
| 366 | dump_tpm_buf(cmd); | 375 | dump_tpm_buf(cmd); |
| 367 | rc = tpm_send(chip, cmd, buflen); | 376 | rc = tpm_send(chip, cmd, buflen); |
| 368 | dump_tpm_buf(cmd); | 377 | dump_tpm_buf(cmd); |
| @@ -429,6 +438,9 @@ int oiap(struct tpm_buf *tb, uint32_t *handle, unsigned char *nonce) | |||
| 429 | { | 438 | { |
| 430 | int ret; | 439 | int ret; |
| 431 | 440 | ||
| 441 | if (!chip) | ||
| 442 | return -ENODEV; | ||
| 443 | |||
| 432 | INIT_BUF(tb); | 444 | INIT_BUF(tb); |
| 433 | store16(tb, TPM_TAG_RQU_COMMAND); | 445 | store16(tb, TPM_TAG_RQU_COMMAND); |
| 434 | store32(tb, TPM_OIAP_SIZE); | 446 | store32(tb, TPM_OIAP_SIZE); |
| @@ -1245,9 +1257,13 @@ static int __init init_trusted(void) | |||
| 1245 | { | 1257 | { |
| 1246 | int ret; | 1258 | int ret; |
| 1247 | 1259 | ||
| 1260 | /* encrypted_keys.ko depends on successful load of this module even if | ||
| 1261 | * TPM is not used. | ||
| 1262 | */ | ||
| 1248 | chip = tpm_default_chip(); | 1263 | chip = tpm_default_chip(); |
| 1249 | if (!chip) | 1264 | if (!chip) |
| 1250 | return -ENOENT; | 1265 | return 0; |
| 1266 | |||
| 1251 | ret = init_digests(); | 1267 | ret = init_digests(); |
| 1252 | if (ret < 0) | 1268 | if (ret < 0) |
| 1253 | goto err_put; | 1269 | goto err_put; |
| @@ -1269,10 +1285,12 @@ err_put: | |||
| 1269 | 1285 | ||
| 1270 | static void __exit cleanup_trusted(void) | 1286 | static void __exit cleanup_trusted(void) |
| 1271 | { | 1287 | { |
| 1272 | put_device(&chip->dev); | 1288 | if (chip) { |
| 1273 | kfree(digests); | 1289 | put_device(&chip->dev); |
| 1274 | trusted_shash_release(); | 1290 | kfree(digests); |
| 1275 | unregister_key_type(&key_type_trusted); | 1291 | trusted_shash_release(); |
| 1292 | unregister_key_type(&key_type_trusted); | ||
| 1293 | } | ||
| 1276 | } | 1294 | } |
| 1277 | 1295 | ||
| 1278 | late_initcall(init_trusted); | 1296 | late_initcall(init_trusted); |
diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c index 7d4640d1fe9f..38e7deab6384 100644 --- a/sound/core/seq/seq_clientmgr.c +++ b/sound/core/seq/seq_clientmgr.c | |||
| @@ -1252,7 +1252,7 @@ static int snd_seq_ioctl_set_client_info(struct snd_seq_client *client, | |||
| 1252 | 1252 | ||
| 1253 | /* fill the info fields */ | 1253 | /* fill the info fields */ |
| 1254 | if (client_info->name[0]) | 1254 | if (client_info->name[0]) |
| 1255 | strlcpy(client->name, client_info->name, sizeof(client->name)); | 1255 | strscpy(client->name, client_info->name, sizeof(client->name)); |
| 1256 | 1256 | ||
| 1257 | client->filter = client_info->filter; | 1257 | client->filter = client_info->filter; |
| 1258 | client->event_lost = client_info->event_lost; | 1258 | client->event_lost = client_info->event_lost; |
| @@ -1530,7 +1530,7 @@ static int snd_seq_ioctl_create_queue(struct snd_seq_client *client, void *arg) | |||
| 1530 | /* set queue name */ | 1530 | /* set queue name */ |
| 1531 | if (!info->name[0]) | 1531 | if (!info->name[0]) |
| 1532 | snprintf(info->name, sizeof(info->name), "Queue-%d", q->queue); | 1532 | snprintf(info->name, sizeof(info->name), "Queue-%d", q->queue); |
| 1533 | strlcpy(q->name, info->name, sizeof(q->name)); | 1533 | strscpy(q->name, info->name, sizeof(q->name)); |
| 1534 | snd_use_lock_free(&q->use_lock); | 1534 | snd_use_lock_free(&q->use_lock); |
| 1535 | 1535 | ||
| 1536 | return 0; | 1536 | return 0; |
| @@ -1592,7 +1592,7 @@ static int snd_seq_ioctl_set_queue_info(struct snd_seq_client *client, | |||
| 1592 | queuefree(q); | 1592 | queuefree(q); |
| 1593 | return -EPERM; | 1593 | return -EPERM; |
| 1594 | } | 1594 | } |
| 1595 | strlcpy(q->name, info->name, sizeof(q->name)); | 1595 | strscpy(q->name, info->name, sizeof(q->name)); |
| 1596 | queuefree(q); | 1596 | queuefree(q); |
| 1597 | 1597 | ||
| 1598 | return 0; | 1598 | return 0; |
diff --git a/sound/hda/ext/hdac_ext_bus.c b/sound/hda/ext/hdac_ext_bus.c index 9c37d9af3023..ec7715c6b0c0 100644 --- a/sound/hda/ext/hdac_ext_bus.c +++ b/sound/hda/ext/hdac_ext_bus.c | |||
| @@ -107,7 +107,6 @@ int snd_hdac_ext_bus_init(struct hdac_bus *bus, struct device *dev, | |||
| 107 | INIT_LIST_HEAD(&bus->hlink_list); | 107 | INIT_LIST_HEAD(&bus->hlink_list); |
| 108 | bus->idx = idx++; | 108 | bus->idx = idx++; |
| 109 | 109 | ||
| 110 | mutex_init(&bus->lock); | ||
| 111 | bus->cmd_dma_state = true; | 110 | bus->cmd_dma_state = true; |
| 112 | 111 | ||
| 113 | return 0; | 112 | return 0; |
diff --git a/sound/hda/hdac_bus.c b/sound/hda/hdac_bus.c index 012305177f68..ad8eee08013f 100644 --- a/sound/hda/hdac_bus.c +++ b/sound/hda/hdac_bus.c | |||
| @@ -38,6 +38,7 @@ int snd_hdac_bus_init(struct hdac_bus *bus, struct device *dev, | |||
| 38 | INIT_WORK(&bus->unsol_work, snd_hdac_bus_process_unsol_events); | 38 | INIT_WORK(&bus->unsol_work, snd_hdac_bus_process_unsol_events); |
| 39 | spin_lock_init(&bus->reg_lock); | 39 | spin_lock_init(&bus->reg_lock); |
| 40 | mutex_init(&bus->cmd_mutex); | 40 | mutex_init(&bus->cmd_mutex); |
| 41 | mutex_init(&bus->lock); | ||
| 41 | bus->irq = -1; | 42 | bus->irq = -1; |
| 42 | return 0; | 43 | return 0; |
| 43 | } | 44 | } |
diff --git a/sound/hda/hdac_component.c b/sound/hda/hdac_component.c index 5c95933e739a..1ea51e3b942a 100644 --- a/sound/hda/hdac_component.c +++ b/sound/hda/hdac_component.c | |||
| @@ -69,13 +69,15 @@ void snd_hdac_display_power(struct hdac_bus *bus, unsigned int idx, bool enable) | |||
| 69 | 69 | ||
| 70 | dev_dbg(bus->dev, "display power %s\n", | 70 | dev_dbg(bus->dev, "display power %s\n", |
| 71 | enable ? "enable" : "disable"); | 71 | enable ? "enable" : "disable"); |
| 72 | |||
| 73 | mutex_lock(&bus->lock); | ||
| 72 | if (enable) | 74 | if (enable) |
| 73 | set_bit(idx, &bus->display_power_status); | 75 | set_bit(idx, &bus->display_power_status); |
| 74 | else | 76 | else |
| 75 | clear_bit(idx, &bus->display_power_status); | 77 | clear_bit(idx, &bus->display_power_status); |
| 76 | 78 | ||
| 77 | if (!acomp || !acomp->ops) | 79 | if (!acomp || !acomp->ops) |
| 78 | return; | 80 | goto unlock; |
| 79 | 81 | ||
| 80 | if (bus->display_power_status) { | 82 | if (bus->display_power_status) { |
| 81 | if (!bus->display_power_active) { | 83 | if (!bus->display_power_active) { |
| @@ -92,6 +94,8 @@ void snd_hdac_display_power(struct hdac_bus *bus, unsigned int idx, bool enable) | |||
| 92 | bus->display_power_active = false; | 94 | bus->display_power_active = false; |
| 93 | } | 95 | } |
| 94 | } | 96 | } |
| 97 | unlock: | ||
| 98 | mutex_unlock(&bus->lock); | ||
| 95 | } | 99 | } |
| 96 | EXPORT_SYMBOL_GPL(snd_hdac_display_power); | 100 | EXPORT_SYMBOL_GPL(snd_hdac_display_power); |
| 97 | 101 | ||
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index ece256a3b48f..2ec91085fa3e 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
| @@ -2142,6 +2142,8 @@ static struct snd_pci_quirk power_save_blacklist[] = { | |||
| 2142 | SND_PCI_QUIRK(0x8086, 0x2040, "Intel DZ77BH-55K", 0), | 2142 | SND_PCI_QUIRK(0x8086, 0x2040, "Intel DZ77BH-55K", 0), |
| 2143 | /* https://bugzilla.kernel.org/show_bug.cgi?id=199607 */ | 2143 | /* https://bugzilla.kernel.org/show_bug.cgi?id=199607 */ |
| 2144 | SND_PCI_QUIRK(0x8086, 0x2057, "Intel NUC5i7RYB", 0), | 2144 | SND_PCI_QUIRK(0x8086, 0x2057, "Intel NUC5i7RYB", 0), |
| 2145 | /* https://bugs.launchpad.net/bugs/1821663 */ | ||
| 2146 | SND_PCI_QUIRK(0x8086, 0x2064, "Intel SDP 8086:2064", 0), | ||
| 2145 | /* https://bugzilla.redhat.com/show_bug.cgi?id=1520902 */ | 2147 | /* https://bugzilla.redhat.com/show_bug.cgi?id=1520902 */ |
| 2146 | SND_PCI_QUIRK(0x8086, 0x2068, "Intel NUC7i3BNB", 0), | 2148 | SND_PCI_QUIRK(0x8086, 0x2068, "Intel NUC7i3BNB", 0), |
| 2147 | /* https://bugzilla.kernel.org/show_bug.cgi?id=198611 */ | 2149 | /* https://bugzilla.kernel.org/show_bug.cgi?id=198611 */ |
| @@ -2150,6 +2152,8 @@ static struct snd_pci_quirk power_save_blacklist[] = { | |||
| 2150 | SND_PCI_QUIRK(0x17aa, 0x367b, "Lenovo IdeaCentre B550", 0), | 2152 | SND_PCI_QUIRK(0x17aa, 0x367b, "Lenovo IdeaCentre B550", 0), |
| 2151 | /* https://bugzilla.redhat.com/show_bug.cgi?id=1572975 */ | 2153 | /* https://bugzilla.redhat.com/show_bug.cgi?id=1572975 */ |
| 2152 | SND_PCI_QUIRK(0x17aa, 0x36a7, "Lenovo C50 All in one", 0), | 2154 | SND_PCI_QUIRK(0x17aa, 0x36a7, "Lenovo C50 All in one", 0), |
| 2155 | /* https://bugs.launchpad.net/bugs/1821663 */ | ||
| 2156 | SND_PCI_QUIRK(0x1631, 0xe017, "Packard Bell NEC IMEDIA 5204", 0), | ||
| 2153 | {} | 2157 | {} |
| 2154 | }; | 2158 | }; |
| 2155 | #endif /* CONFIG_PM */ | 2159 | #endif /* CONFIG_PM */ |
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index a3fb3d4c5730..810479766090 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
| @@ -1864,8 +1864,8 @@ enum { | |||
| 1864 | ALC887_FIXUP_BASS_CHMAP, | 1864 | ALC887_FIXUP_BASS_CHMAP, |
| 1865 | ALC1220_FIXUP_GB_DUAL_CODECS, | 1865 | ALC1220_FIXUP_GB_DUAL_CODECS, |
| 1866 | ALC1220_FIXUP_CLEVO_P950, | 1866 | ALC1220_FIXUP_CLEVO_P950, |
| 1867 | ALC1220_FIXUP_SYSTEM76_ORYP5, | 1867 | ALC1220_FIXUP_CLEVO_PB51ED, |
| 1868 | ALC1220_FIXUP_SYSTEM76_ORYP5_PINS, | 1868 | ALC1220_FIXUP_CLEVO_PB51ED_PINS, |
| 1869 | }; | 1869 | }; |
| 1870 | 1870 | ||
| 1871 | static void alc889_fixup_coef(struct hda_codec *codec, | 1871 | static void alc889_fixup_coef(struct hda_codec *codec, |
| @@ -2070,7 +2070,7 @@ static void alc1220_fixup_clevo_p950(struct hda_codec *codec, | |||
| 2070 | static void alc_fixup_headset_mode_no_hp_mic(struct hda_codec *codec, | 2070 | static void alc_fixup_headset_mode_no_hp_mic(struct hda_codec *codec, |
| 2071 | const struct hda_fixup *fix, int action); | 2071 | const struct hda_fixup *fix, int action); |
| 2072 | 2072 | ||
| 2073 | static void alc1220_fixup_system76_oryp5(struct hda_codec *codec, | 2073 | static void alc1220_fixup_clevo_pb51ed(struct hda_codec *codec, |
| 2074 | const struct hda_fixup *fix, | 2074 | const struct hda_fixup *fix, |
| 2075 | int action) | 2075 | int action) |
| 2076 | { | 2076 | { |
| @@ -2322,18 +2322,18 @@ static const struct hda_fixup alc882_fixups[] = { | |||
| 2322 | .type = HDA_FIXUP_FUNC, | 2322 | .type = HDA_FIXUP_FUNC, |
| 2323 | .v.func = alc1220_fixup_clevo_p950, | 2323 | .v.func = alc1220_fixup_clevo_p950, |
| 2324 | }, | 2324 | }, |
| 2325 | [ALC1220_FIXUP_SYSTEM76_ORYP5] = { | 2325 | [ALC1220_FIXUP_CLEVO_PB51ED] = { |
| 2326 | .type = HDA_FIXUP_FUNC, | 2326 | .type = HDA_FIXUP_FUNC, |
| 2327 | .v.func = alc1220_fixup_system76_oryp5, | 2327 | .v.func = alc1220_fixup_clevo_pb51ed, |
| 2328 | }, | 2328 | }, |
| 2329 | [ALC1220_FIXUP_SYSTEM76_ORYP5_PINS] = { | 2329 | [ALC1220_FIXUP_CLEVO_PB51ED_PINS] = { |
| 2330 | .type = HDA_FIXUP_PINS, | 2330 | .type = HDA_FIXUP_PINS, |
| 2331 | .v.pins = (const struct hda_pintbl[]) { | 2331 | .v.pins = (const struct hda_pintbl[]) { |
| 2332 | { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */ | 2332 | { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */ |
| 2333 | {} | 2333 | {} |
| 2334 | }, | 2334 | }, |
| 2335 | .chained = true, | 2335 | .chained = true, |
| 2336 | .chain_id = ALC1220_FIXUP_SYSTEM76_ORYP5, | 2336 | .chain_id = ALC1220_FIXUP_CLEVO_PB51ED, |
| 2337 | }, | 2337 | }, |
| 2338 | }; | 2338 | }; |
| 2339 | 2339 | ||
| @@ -2411,8 +2411,9 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = { | |||
| 2411 | SND_PCI_QUIRK(0x1558, 0x9501, "Clevo P950HR", ALC1220_FIXUP_CLEVO_P950), | 2411 | SND_PCI_QUIRK(0x1558, 0x9501, "Clevo P950HR", ALC1220_FIXUP_CLEVO_P950), |
| 2412 | SND_PCI_QUIRK(0x1558, 0x95e1, "Clevo P95xER", ALC1220_FIXUP_CLEVO_P950), | 2412 | SND_PCI_QUIRK(0x1558, 0x95e1, "Clevo P95xER", ALC1220_FIXUP_CLEVO_P950), |
| 2413 | SND_PCI_QUIRK(0x1558, 0x95e2, "Clevo P950ER", ALC1220_FIXUP_CLEVO_P950), | 2413 | SND_PCI_QUIRK(0x1558, 0x95e2, "Clevo P950ER", ALC1220_FIXUP_CLEVO_P950), |
| 2414 | SND_PCI_QUIRK(0x1558, 0x96e1, "System76 Oryx Pro (oryp5)", ALC1220_FIXUP_SYSTEM76_ORYP5_PINS), | 2414 | SND_PCI_QUIRK(0x1558, 0x96e1, "System76 Oryx Pro (oryp5)", ALC1220_FIXUP_CLEVO_PB51ED_PINS), |
| 2415 | SND_PCI_QUIRK(0x1558, 0x97e1, "System76 Oryx Pro (oryp5)", ALC1220_FIXUP_SYSTEM76_ORYP5_PINS), | 2415 | SND_PCI_QUIRK(0x1558, 0x97e1, "System76 Oryx Pro (oryp5)", ALC1220_FIXUP_CLEVO_PB51ED_PINS), |
| 2416 | SND_PCI_QUIRK(0x1558, 0x65d1, "Tuxedo Book XC1509", ALC1220_FIXUP_CLEVO_PB51ED_PINS), | ||
| 2416 | SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC882_FIXUP_EAPD), | 2417 | SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC882_FIXUP_EAPD), |
| 2417 | SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_FIXUP_EAPD), | 2418 | SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_FIXUP_EAPD), |
| 2418 | SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", ALC882_FIXUP_LENOVO_Y530), | 2419 | SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", ALC882_FIXUP_LENOVO_Y530), |
| @@ -5491,7 +5492,7 @@ static void alc_headset_btn_callback(struct hda_codec *codec, | |||
| 5491 | jack->jack->button_state = report; | 5492 | jack->jack->button_state = report; |
| 5492 | } | 5493 | } |
| 5493 | 5494 | ||
| 5494 | static void alc295_fixup_chromebook(struct hda_codec *codec, | 5495 | static void alc_fixup_headset_jack(struct hda_codec *codec, |
| 5495 | const struct hda_fixup *fix, int action) | 5496 | const struct hda_fixup *fix, int action) |
| 5496 | { | 5497 | { |
| 5497 | 5498 | ||
| @@ -5501,16 +5502,6 @@ static void alc295_fixup_chromebook(struct hda_codec *codec, | |||
| 5501 | alc_headset_btn_callback); | 5502 | alc_headset_btn_callback); |
| 5502 | snd_hda_jack_add_kctl(codec, 0x55, "Headset Jack", false, | 5503 | snd_hda_jack_add_kctl(codec, 0x55, "Headset Jack", false, |
| 5503 | SND_JACK_HEADSET, alc_headset_btn_keymap); | 5504 | SND_JACK_HEADSET, alc_headset_btn_keymap); |
| 5504 | switch (codec->core.vendor_id) { | ||
| 5505 | case 0x10ec0295: | ||
| 5506 | alc_update_coef_idx(codec, 0x4a, 0x8000, 1 << 15); /* Reset HP JD */ | ||
| 5507 | alc_update_coef_idx(codec, 0x4a, 0x8000, 0 << 15); | ||
| 5508 | break; | ||
| 5509 | case 0x10ec0236: | ||
| 5510 | alc_update_coef_idx(codec, 0x1b, 0x8000, 1 << 15); /* Reset HP JD */ | ||
| 5511 | alc_update_coef_idx(codec, 0x1b, 0x8000, 0 << 15); | ||
| 5512 | break; | ||
| 5513 | } | ||
| 5514 | break; | 5505 | break; |
| 5515 | case HDA_FIXUP_ACT_INIT: | 5506 | case HDA_FIXUP_ACT_INIT: |
| 5516 | switch (codec->core.vendor_id) { | 5507 | switch (codec->core.vendor_id) { |
| @@ -5531,6 +5522,25 @@ static void alc295_fixup_chromebook(struct hda_codec *codec, | |||
| 5531 | } | 5522 | } |
| 5532 | } | 5523 | } |
| 5533 | 5524 | ||
| 5525 | static void alc295_fixup_chromebook(struct hda_codec *codec, | ||
| 5526 | const struct hda_fixup *fix, int action) | ||
| 5527 | { | ||
| 5528 | switch (action) { | ||
| 5529 | case HDA_FIXUP_ACT_INIT: | ||
| 5530 | switch (codec->core.vendor_id) { | ||
| 5531 | case 0x10ec0295: | ||
| 5532 | alc_update_coef_idx(codec, 0x4a, 0x8000, 1 << 15); /* Reset HP JD */ | ||
| 5533 | alc_update_coef_idx(codec, 0x4a, 0x8000, 0 << 15); | ||
| 5534 | break; | ||
| 5535 | case 0x10ec0236: | ||
| 5536 | alc_update_coef_idx(codec, 0x1b, 0x8000, 1 << 15); /* Reset HP JD */ | ||
| 5537 | alc_update_coef_idx(codec, 0x1b, 0x8000, 0 << 15); | ||
| 5538 | break; | ||
| 5539 | } | ||
| 5540 | break; | ||
| 5541 | } | ||
| 5542 | } | ||
| 5543 | |||
| 5534 | static void alc_fixup_disable_mic_vref(struct hda_codec *codec, | 5544 | static void alc_fixup_disable_mic_vref(struct hda_codec *codec, |
| 5535 | const struct hda_fixup *fix, int action) | 5545 | const struct hda_fixup *fix, int action) |
| 5536 | { | 5546 | { |
| @@ -5663,6 +5673,7 @@ enum { | |||
| 5663 | ALC233_FIXUP_ASUS_MIC_NO_PRESENCE, | 5673 | ALC233_FIXUP_ASUS_MIC_NO_PRESENCE, |
| 5664 | ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE, | 5674 | ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE, |
| 5665 | ALC233_FIXUP_LENOVO_MULTI_CODECS, | 5675 | ALC233_FIXUP_LENOVO_MULTI_CODECS, |
| 5676 | ALC233_FIXUP_ACER_HEADSET_MIC, | ||
| 5666 | ALC294_FIXUP_LENOVO_MIC_LOCATION, | 5677 | ALC294_FIXUP_LENOVO_MIC_LOCATION, |
| 5667 | ALC225_FIXUP_DELL_WYSE_MIC_NO_PRESENCE, | 5678 | ALC225_FIXUP_DELL_WYSE_MIC_NO_PRESENCE, |
| 5668 | ALC700_FIXUP_INTEL_REFERENCE, | 5679 | ALC700_FIXUP_INTEL_REFERENCE, |
| @@ -5684,6 +5695,7 @@ enum { | |||
| 5684 | ALC285_FIXUP_LENOVO_PC_BEEP_IN_NOISE, | 5695 | ALC285_FIXUP_LENOVO_PC_BEEP_IN_NOISE, |
| 5685 | ALC255_FIXUP_ACER_HEADSET_MIC, | 5696 | ALC255_FIXUP_ACER_HEADSET_MIC, |
| 5686 | ALC295_FIXUP_CHROME_BOOK, | 5697 | ALC295_FIXUP_CHROME_BOOK, |
| 5698 | ALC225_FIXUP_HEADSET_JACK, | ||
| 5687 | ALC225_FIXUP_DELL_WYSE_AIO_MIC_NO_PRESENCE, | 5699 | ALC225_FIXUP_DELL_WYSE_AIO_MIC_NO_PRESENCE, |
| 5688 | ALC225_FIXUP_WYSE_AUTO_MUTE, | 5700 | ALC225_FIXUP_WYSE_AUTO_MUTE, |
| 5689 | ALC225_FIXUP_WYSE_DISABLE_MIC_VREF, | 5701 | ALC225_FIXUP_WYSE_DISABLE_MIC_VREF, |
| @@ -6490,6 +6502,16 @@ static const struct hda_fixup alc269_fixups[] = { | |||
| 6490 | .type = HDA_FIXUP_FUNC, | 6502 | .type = HDA_FIXUP_FUNC, |
| 6491 | .v.func = alc233_alc662_fixup_lenovo_dual_codecs, | 6503 | .v.func = alc233_alc662_fixup_lenovo_dual_codecs, |
| 6492 | }, | 6504 | }, |
| 6505 | [ALC233_FIXUP_ACER_HEADSET_MIC] = { | ||
| 6506 | .type = HDA_FIXUP_VERBS, | ||
| 6507 | .v.verbs = (const struct hda_verb[]) { | ||
| 6508 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x45 }, | ||
| 6509 | { 0x20, AC_VERB_SET_PROC_COEF, 0x5089 }, | ||
| 6510 | { } | ||
| 6511 | }, | ||
| 6512 | .chained = true, | ||
| 6513 | .chain_id = ALC233_FIXUP_ASUS_MIC_NO_PRESENCE | ||
| 6514 | }, | ||
| 6493 | [ALC294_FIXUP_LENOVO_MIC_LOCATION] = { | 6515 | [ALC294_FIXUP_LENOVO_MIC_LOCATION] = { |
| 6494 | .type = HDA_FIXUP_PINS, | 6516 | .type = HDA_FIXUP_PINS, |
| 6495 | .v.pins = (const struct hda_pintbl[]) { | 6517 | .v.pins = (const struct hda_pintbl[]) { |
| @@ -6635,6 +6657,12 @@ static const struct hda_fixup alc269_fixups[] = { | |||
| 6635 | [ALC295_FIXUP_CHROME_BOOK] = { | 6657 | [ALC295_FIXUP_CHROME_BOOK] = { |
| 6636 | .type = HDA_FIXUP_FUNC, | 6658 | .type = HDA_FIXUP_FUNC, |
| 6637 | .v.func = alc295_fixup_chromebook, | 6659 | .v.func = alc295_fixup_chromebook, |
| 6660 | .chained = true, | ||
| 6661 | .chain_id = ALC225_FIXUP_HEADSET_JACK | ||
| 6662 | }, | ||
| 6663 | [ALC225_FIXUP_HEADSET_JACK] = { | ||
| 6664 | .type = HDA_FIXUP_FUNC, | ||
| 6665 | .v.func = alc_fixup_headset_jack, | ||
| 6638 | }, | 6666 | }, |
| 6639 | [ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE] = { | 6667 | [ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE] = { |
| 6640 | .type = HDA_FIXUP_PINS, | 6668 | .type = HDA_FIXUP_PINS, |
| @@ -6737,6 +6765,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { | |||
| 6737 | SND_PCI_QUIRK(0x1025, 0x1290, "Acer Veriton Z4860G", ALC286_FIXUP_ACER_AIO_HEADSET_MIC), | 6765 | SND_PCI_QUIRK(0x1025, 0x1290, "Acer Veriton Z4860G", ALC286_FIXUP_ACER_AIO_HEADSET_MIC), |
| 6738 | SND_PCI_QUIRK(0x1025, 0x1291, "Acer Veriton Z4660G", ALC286_FIXUP_ACER_AIO_HEADSET_MIC), | 6766 | SND_PCI_QUIRK(0x1025, 0x1291, "Acer Veriton Z4660G", ALC286_FIXUP_ACER_AIO_HEADSET_MIC), |
| 6739 | SND_PCI_QUIRK(0x1025, 0x1308, "Acer Aspire Z24-890", ALC286_FIXUP_ACER_AIO_HEADSET_MIC), | 6767 | SND_PCI_QUIRK(0x1025, 0x1308, "Acer Aspire Z24-890", ALC286_FIXUP_ACER_AIO_HEADSET_MIC), |
| 6768 | SND_PCI_QUIRK(0x1025, 0x132a, "Acer TravelMate B114-21", ALC233_FIXUP_ACER_HEADSET_MIC), | ||
| 6740 | SND_PCI_QUIRK(0x1025, 0x1330, "Acer TravelMate X514-51T", ALC255_FIXUP_ACER_HEADSET_MIC), | 6769 | SND_PCI_QUIRK(0x1025, 0x1330, "Acer TravelMate X514-51T", ALC255_FIXUP_ACER_HEADSET_MIC), |
| 6741 | SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z), | 6770 | SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z), |
| 6742 | SND_PCI_QUIRK(0x1028, 0x054b, "Dell XPS one 2710", ALC275_FIXUP_DELL_XPS), | 6771 | SND_PCI_QUIRK(0x1028, 0x054b, "Dell XPS one 2710", ALC275_FIXUP_DELL_XPS), |
| @@ -7132,7 +7161,8 @@ static const struct hda_model_fixup alc269_fixup_models[] = { | |||
| 7132 | {.id = ALC255_FIXUP_DUMMY_LINEOUT_VERB, .name = "alc255-dummy-lineout"}, | 7161 | {.id = ALC255_FIXUP_DUMMY_LINEOUT_VERB, .name = "alc255-dummy-lineout"}, |
| 7133 | {.id = ALC255_FIXUP_DELL_HEADSET_MIC, .name = "alc255-dell-headset"}, | 7162 | {.id = ALC255_FIXUP_DELL_HEADSET_MIC, .name = "alc255-dell-headset"}, |
| 7134 | {.id = ALC295_FIXUP_HP_X360, .name = "alc295-hp-x360"}, | 7163 | {.id = ALC295_FIXUP_HP_X360, .name = "alc295-hp-x360"}, |
| 7135 | {.id = ALC295_FIXUP_CHROME_BOOK, .name = "alc-sense-combo"}, | 7164 | {.id = ALC225_FIXUP_HEADSET_JACK, .name = "alc-headset-jack"}, |
| 7165 | {.id = ALC295_FIXUP_CHROME_BOOK, .name = "alc-chrome-book"}, | ||
| 7136 | {.id = ALC299_FIXUP_PREDATOR_SPK, .name = "predator-spk"}, | 7166 | {.id = ALC299_FIXUP_PREDATOR_SPK, .name = "predator-spk"}, |
| 7137 | {} | 7167 | {} |
| 7138 | }; | 7168 | }; |
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 419114edfd57..667fc1d59e18 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig | |||
| @@ -1151,6 +1151,7 @@ config SND_SOC_WCD9335 | |||
| 1151 | tristate "WCD9335 Codec" | 1151 | tristate "WCD9335 Codec" |
| 1152 | depends on SLIMBUS | 1152 | depends on SLIMBUS |
| 1153 | select REGMAP_SLIMBUS | 1153 | select REGMAP_SLIMBUS |
| 1154 | select REGMAP_IRQ | ||
| 1154 | help | 1155 | help |
| 1155 | The WCD9335 is a standalone Hi-Fi audio CODEC IC, supports | 1156 | The WCD9335 is a standalone Hi-Fi audio CODEC IC, supports |
| 1156 | Qualcomm Technologies, Inc. (QTI) multimedia solutions, | 1157 | Qualcomm Technologies, Inc. (QTI) multimedia solutions, |
diff --git a/sound/soc/codecs/ab8500-codec.c b/sound/soc/codecs/ab8500-codec.c index 03bbbcd3b6c1..87616b126018 100644 --- a/sound/soc/codecs/ab8500-codec.c +++ b/sound/soc/codecs/ab8500-codec.c | |||
| @@ -2129,6 +2129,7 @@ static int ab8500_codec_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) | |||
| 2129 | dev_err(dai->component->dev, | 2129 | dev_err(dai->component->dev, |
| 2130 | "%s: ERROR: The device is either a master or a slave.\n", | 2130 | "%s: ERROR: The device is either a master or a slave.\n", |
| 2131 | __func__); | 2131 | __func__); |
| 2132 | /* fall through */ | ||
| 2132 | default: | 2133 | default: |
| 2133 | dev_err(dai->component->dev, | 2134 | dev_err(dai->component->dev, |
| 2134 | "%s: ERROR: Unsupporter master mask 0x%x\n", | 2135 | "%s: ERROR: Unsupporter master mask 0x%x\n", |
diff --git a/sound/soc/codecs/cs35l35.c b/sound/soc/codecs/cs35l35.c index 9f4a59871cee..c71696146c5e 100644 --- a/sound/soc/codecs/cs35l35.c +++ b/sound/soc/codecs/cs35l35.c | |||
| @@ -1635,6 +1635,16 @@ err: | |||
| 1635 | return ret; | 1635 | return ret; |
| 1636 | } | 1636 | } |
| 1637 | 1637 | ||
| 1638 | static int cs35l35_i2c_remove(struct i2c_client *i2c_client) | ||
| 1639 | { | ||
| 1640 | struct cs35l35_private *cs35l35 = i2c_get_clientdata(i2c_client); | ||
| 1641 | |||
| 1642 | regulator_bulk_disable(cs35l35->num_supplies, cs35l35->supplies); | ||
| 1643 | gpiod_set_value_cansleep(cs35l35->reset_gpio, 0); | ||
| 1644 | |||
| 1645 | return 0; | ||
| 1646 | } | ||
| 1647 | |||
| 1638 | static const struct of_device_id cs35l35_of_match[] = { | 1648 | static const struct of_device_id cs35l35_of_match[] = { |
| 1639 | {.compatible = "cirrus,cs35l35"}, | 1649 | {.compatible = "cirrus,cs35l35"}, |
| 1640 | {}, | 1650 | {}, |
| @@ -1655,6 +1665,7 @@ static struct i2c_driver cs35l35_i2c_driver = { | |||
| 1655 | }, | 1665 | }, |
| 1656 | .id_table = cs35l35_id, | 1666 | .id_table = cs35l35_id, |
| 1657 | .probe = cs35l35_i2c_probe, | 1667 | .probe = cs35l35_i2c_probe, |
| 1668 | .remove = cs35l35_i2c_remove, | ||
| 1658 | }; | 1669 | }; |
| 1659 | 1670 | ||
| 1660 | module_i2c_driver(cs35l35_i2c_driver); | 1671 | module_i2c_driver(cs35l35_i2c_driver); |
diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c index 33d74f163bd7..793a14d58667 100644 --- a/sound/soc/codecs/cs4270.c +++ b/sound/soc/codecs/cs4270.c | |||
| @@ -642,6 +642,7 @@ static const struct regmap_config cs4270_regmap = { | |||
| 642 | .reg_defaults = cs4270_reg_defaults, | 642 | .reg_defaults = cs4270_reg_defaults, |
| 643 | .num_reg_defaults = ARRAY_SIZE(cs4270_reg_defaults), | 643 | .num_reg_defaults = ARRAY_SIZE(cs4270_reg_defaults), |
| 644 | .cache_type = REGCACHE_RBTREE, | 644 | .cache_type = REGCACHE_RBTREE, |
| 645 | .write_flag_mask = CS4270_I2C_INCR, | ||
| 645 | 646 | ||
| 646 | .readable_reg = cs4270_reg_is_readable, | 647 | .readable_reg = cs4270_reg_is_readable, |
| 647 | .volatile_reg = cs4270_reg_is_volatile, | 648 | .volatile_reg = cs4270_reg_is_volatile, |
diff --git a/sound/soc/codecs/hdac_hda.c b/sound/soc/codecs/hdac_hda.c index ffecdaaa8cf2..f889d94c8e3c 100644 --- a/sound/soc/codecs/hdac_hda.c +++ b/sound/soc/codecs/hdac_hda.c | |||
| @@ -38,6 +38,9 @@ static void hdac_hda_dai_close(struct snd_pcm_substream *substream, | |||
| 38 | struct snd_soc_dai *dai); | 38 | struct snd_soc_dai *dai); |
| 39 | static int hdac_hda_dai_prepare(struct snd_pcm_substream *substream, | 39 | static int hdac_hda_dai_prepare(struct snd_pcm_substream *substream, |
| 40 | struct snd_soc_dai *dai); | 40 | struct snd_soc_dai *dai); |
| 41 | static int hdac_hda_dai_hw_params(struct snd_pcm_substream *substream, | ||
| 42 | struct snd_pcm_hw_params *params, | ||
| 43 | struct snd_soc_dai *dai); | ||
| 41 | static int hdac_hda_dai_hw_free(struct snd_pcm_substream *substream, | 44 | static int hdac_hda_dai_hw_free(struct snd_pcm_substream *substream, |
| 42 | struct snd_soc_dai *dai); | 45 | struct snd_soc_dai *dai); |
| 43 | static int hdac_hda_dai_set_tdm_slot(struct snd_soc_dai *dai, | 46 | static int hdac_hda_dai_set_tdm_slot(struct snd_soc_dai *dai, |
| @@ -50,6 +53,7 @@ static const struct snd_soc_dai_ops hdac_hda_dai_ops = { | |||
| 50 | .startup = hdac_hda_dai_open, | 53 | .startup = hdac_hda_dai_open, |
| 51 | .shutdown = hdac_hda_dai_close, | 54 | .shutdown = hdac_hda_dai_close, |
| 52 | .prepare = hdac_hda_dai_prepare, | 55 | .prepare = hdac_hda_dai_prepare, |
| 56 | .hw_params = hdac_hda_dai_hw_params, | ||
| 53 | .hw_free = hdac_hda_dai_hw_free, | 57 | .hw_free = hdac_hda_dai_hw_free, |
| 54 | .set_tdm_slot = hdac_hda_dai_set_tdm_slot, | 58 | .set_tdm_slot = hdac_hda_dai_set_tdm_slot, |
| 55 | }; | 59 | }; |
| @@ -139,6 +143,39 @@ static int hdac_hda_dai_set_tdm_slot(struct snd_soc_dai *dai, | |||
| 139 | return 0; | 143 | return 0; |
| 140 | } | 144 | } |
| 141 | 145 | ||
| 146 | static int hdac_hda_dai_hw_params(struct snd_pcm_substream *substream, | ||
| 147 | struct snd_pcm_hw_params *params, | ||
| 148 | struct snd_soc_dai *dai) | ||
| 149 | { | ||
| 150 | struct snd_soc_component *component = dai->component; | ||
| 151 | struct hdac_hda_priv *hda_pvt; | ||
| 152 | unsigned int format_val; | ||
| 153 | unsigned int maxbps; | ||
| 154 | |||
| 155 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | ||
| 156 | maxbps = dai->driver->playback.sig_bits; | ||
| 157 | else | ||
| 158 | maxbps = dai->driver->capture.sig_bits; | ||
| 159 | |||
| 160 | hda_pvt = snd_soc_component_get_drvdata(component); | ||
| 161 | format_val = snd_hdac_calc_stream_format(params_rate(params), | ||
| 162 | params_channels(params), | ||
| 163 | params_format(params), | ||
| 164 | maxbps, | ||
| 165 | 0); | ||
| 166 | if (!format_val) { | ||
| 167 | dev_err(dai->dev, | ||
| 168 | "invalid format_val, rate=%d, ch=%d, format=%d, maxbps=%d\n", | ||
| 169 | params_rate(params), params_channels(params), | ||
| 170 | params_format(params), maxbps); | ||
| 171 | |||
| 172 | return -EINVAL; | ||
| 173 | } | ||
| 174 | |||
| 175 | hda_pvt->pcm[dai->id].format_val[substream->stream] = format_val; | ||
| 176 | return 0; | ||
| 177 | } | ||
| 178 | |||
| 142 | static int hdac_hda_dai_hw_free(struct snd_pcm_substream *substream, | 179 | static int hdac_hda_dai_hw_free(struct snd_pcm_substream *substream, |
| 143 | struct snd_soc_dai *dai) | 180 | struct snd_soc_dai *dai) |
| 144 | { | 181 | { |
| @@ -162,10 +199,9 @@ static int hdac_hda_dai_prepare(struct snd_pcm_substream *substream, | |||
| 162 | struct snd_soc_dai *dai) | 199 | struct snd_soc_dai *dai) |
| 163 | { | 200 | { |
| 164 | struct snd_soc_component *component = dai->component; | 201 | struct snd_soc_component *component = dai->component; |
| 202 | struct hda_pcm_stream *hda_stream; | ||
| 165 | struct hdac_hda_priv *hda_pvt; | 203 | struct hdac_hda_priv *hda_pvt; |
| 166 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
| 167 | struct hdac_device *hdev; | 204 | struct hdac_device *hdev; |
| 168 | struct hda_pcm_stream *hda_stream; | ||
| 169 | unsigned int format_val; | 205 | unsigned int format_val; |
| 170 | struct hda_pcm *pcm; | 206 | struct hda_pcm *pcm; |
| 171 | unsigned int stream; | 207 | unsigned int stream; |
| @@ -179,19 +215,8 @@ static int hdac_hda_dai_prepare(struct snd_pcm_substream *substream, | |||
| 179 | 215 | ||
| 180 | hda_stream = &pcm->stream[substream->stream]; | 216 | hda_stream = &pcm->stream[substream->stream]; |
| 181 | 217 | ||
| 182 | format_val = snd_hdac_calc_stream_format(runtime->rate, | ||
| 183 | runtime->channels, | ||
| 184 | runtime->format, | ||
| 185 | hda_stream->maxbps, | ||
| 186 | 0); | ||
| 187 | if (!format_val) { | ||
| 188 | dev_err(&hdev->dev, | ||
| 189 | "invalid format_val, rate=%d, ch=%d, format=%d\n", | ||
| 190 | runtime->rate, runtime->channels, runtime->format); | ||
| 191 | return -EINVAL; | ||
| 192 | } | ||
| 193 | |||
| 194 | stream = hda_pvt->pcm[dai->id].stream_tag[substream->stream]; | 218 | stream = hda_pvt->pcm[dai->id].stream_tag[substream->stream]; |
| 219 | format_val = hda_pvt->pcm[dai->id].format_val[substream->stream]; | ||
| 195 | 220 | ||
| 196 | ret = snd_hda_codec_prepare(&hda_pvt->codec, hda_stream, | 221 | ret = snd_hda_codec_prepare(&hda_pvt->codec, hda_stream, |
| 197 | stream, format_val, substream); | 222 | stream, format_val, substream); |
diff --git a/sound/soc/codecs/hdac_hda.h b/sound/soc/codecs/hdac_hda.h index e444ef593360..6b1bd4f428e7 100644 --- a/sound/soc/codecs/hdac_hda.h +++ b/sound/soc/codecs/hdac_hda.h | |||
| @@ -8,6 +8,7 @@ | |||
| 8 | 8 | ||
| 9 | struct hdac_hda_pcm { | 9 | struct hdac_hda_pcm { |
| 10 | int stream_tag[2]; | 10 | int stream_tag[2]; |
| 11 | unsigned int format_val[2]; | ||
| 11 | }; | 12 | }; |
| 12 | 13 | ||
| 13 | struct hdac_hda_priv { | 14 | struct hdac_hda_priv { |
diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c index e5b6769b9797..35df73e42cbc 100644 --- a/sound/soc/codecs/hdmi-codec.c +++ b/sound/soc/codecs/hdmi-codec.c | |||
| @@ -484,9 +484,6 @@ static int hdmi_codec_hw_params(struct snd_pcm_substream *substream, | |||
| 484 | params_width(params), params_rate(params), | 484 | params_width(params), params_rate(params), |
| 485 | params_channels(params)); | 485 | params_channels(params)); |
| 486 | 486 | ||
| 487 | if (params_width(params) > 24) | ||
| 488 | params->msbits = 24; | ||
| 489 | |||
| 490 | ret = snd_pcm_create_iec958_consumer_hw_params(params, hp.iec.status, | 487 | ret = snd_pcm_create_iec958_consumer_hw_params(params, hp.iec.status, |
| 491 | sizeof(hp.iec.status)); | 488 | sizeof(hp.iec.status)); |
| 492 | if (ret < 0) { | 489 | if (ret < 0) { |
| @@ -529,73 +526,71 @@ static int hdmi_codec_set_fmt(struct snd_soc_dai *dai, | |||
| 529 | { | 526 | { |
| 530 | struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai); | 527 | struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai); |
| 531 | struct hdmi_codec_daifmt cf = { 0 }; | 528 | struct hdmi_codec_daifmt cf = { 0 }; |
| 532 | int ret = 0; | ||
| 533 | 529 | ||
| 534 | dev_dbg(dai->dev, "%s()\n", __func__); | 530 | dev_dbg(dai->dev, "%s()\n", __func__); |
| 535 | 531 | ||
| 536 | if (dai->id == DAI_ID_SPDIF) { | 532 | if (dai->id == DAI_ID_SPDIF) |
| 537 | cf.fmt = HDMI_SPDIF; | 533 | return 0; |
| 538 | } else { | 534 | |
| 539 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { | 535 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { |
| 540 | case SND_SOC_DAIFMT_CBM_CFM: | 536 | case SND_SOC_DAIFMT_CBM_CFM: |
| 541 | cf.bit_clk_master = 1; | 537 | cf.bit_clk_master = 1; |
| 542 | cf.frame_clk_master = 1; | 538 | cf.frame_clk_master = 1; |
| 543 | break; | 539 | break; |
| 544 | case SND_SOC_DAIFMT_CBS_CFM: | 540 | case SND_SOC_DAIFMT_CBS_CFM: |
| 545 | cf.frame_clk_master = 1; | 541 | cf.frame_clk_master = 1; |
| 546 | break; | 542 | break; |
| 547 | case SND_SOC_DAIFMT_CBM_CFS: | 543 | case SND_SOC_DAIFMT_CBM_CFS: |
| 548 | cf.bit_clk_master = 1; | 544 | cf.bit_clk_master = 1; |
| 549 | break; | 545 | break; |
| 550 | case SND_SOC_DAIFMT_CBS_CFS: | 546 | case SND_SOC_DAIFMT_CBS_CFS: |
| 551 | break; | 547 | break; |
| 552 | default: | 548 | default: |
| 553 | return -EINVAL; | 549 | return -EINVAL; |
| 554 | } | 550 | } |
| 555 | 551 | ||
| 556 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { | 552 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { |
| 557 | case SND_SOC_DAIFMT_NB_NF: | 553 | case SND_SOC_DAIFMT_NB_NF: |
| 558 | break; | 554 | break; |
| 559 | case SND_SOC_DAIFMT_NB_IF: | 555 | case SND_SOC_DAIFMT_NB_IF: |
| 560 | cf.frame_clk_inv = 1; | 556 | cf.frame_clk_inv = 1; |
| 561 | break; | 557 | break; |
| 562 | case SND_SOC_DAIFMT_IB_NF: | 558 | case SND_SOC_DAIFMT_IB_NF: |
| 563 | cf.bit_clk_inv = 1; | 559 | cf.bit_clk_inv = 1; |
| 564 | break; | 560 | break; |
| 565 | case SND_SOC_DAIFMT_IB_IF: | 561 | case SND_SOC_DAIFMT_IB_IF: |
| 566 | cf.frame_clk_inv = 1; | 562 | cf.frame_clk_inv = 1; |
| 567 | cf.bit_clk_inv = 1; | 563 | cf.bit_clk_inv = 1; |
| 568 | break; | 564 | break; |
| 569 | } | 565 | } |
| 570 | 566 | ||
| 571 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | 567 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { |
| 572 | case SND_SOC_DAIFMT_I2S: | 568 | case SND_SOC_DAIFMT_I2S: |
| 573 | cf.fmt = HDMI_I2S; | 569 | cf.fmt = HDMI_I2S; |
| 574 | break; | 570 | break; |
| 575 | case SND_SOC_DAIFMT_DSP_A: | 571 | case SND_SOC_DAIFMT_DSP_A: |
| 576 | cf.fmt = HDMI_DSP_A; | 572 | cf.fmt = HDMI_DSP_A; |
| 577 | break; | 573 | break; |
| 578 | case SND_SOC_DAIFMT_DSP_B: | 574 | case SND_SOC_DAIFMT_DSP_B: |
| 579 | cf.fmt = HDMI_DSP_B; | 575 | cf.fmt = HDMI_DSP_B; |
| 580 | break; | 576 | break; |
| 581 | case SND_SOC_DAIFMT_RIGHT_J: | 577 | case SND_SOC_DAIFMT_RIGHT_J: |
| 582 | cf.fmt = HDMI_RIGHT_J; | 578 | cf.fmt = HDMI_RIGHT_J; |
| 583 | break; | 579 | break; |
| 584 | case SND_SOC_DAIFMT_LEFT_J: | 580 | case SND_SOC_DAIFMT_LEFT_J: |
| 585 | cf.fmt = HDMI_LEFT_J; | 581 | cf.fmt = HDMI_LEFT_J; |
| 586 | break; | 582 | break; |
| 587 | case SND_SOC_DAIFMT_AC97: | 583 | case SND_SOC_DAIFMT_AC97: |
| 588 | cf.fmt = HDMI_AC97; | 584 | cf.fmt = HDMI_AC97; |
| 589 | break; | 585 | break; |
| 590 | default: | 586 | default: |
| 591 | dev_err(dai->dev, "Invalid DAI interface format\n"); | 587 | dev_err(dai->dev, "Invalid DAI interface format\n"); |
| 592 | return -EINVAL; | 588 | return -EINVAL; |
| 593 | } | ||
| 594 | } | 589 | } |
| 595 | 590 | ||
| 596 | hcp->daifmt[dai->id] = cf; | 591 | hcp->daifmt[dai->id] = cf; |
| 597 | 592 | ||
| 598 | return ret; | 593 | return 0; |
| 599 | } | 594 | } |
| 600 | 595 | ||
| 601 | static int hdmi_codec_digital_mute(struct snd_soc_dai *dai, int mute) | 596 | static int hdmi_codec_digital_mute(struct snd_soc_dai *dai, int mute) |
| @@ -792,8 +787,10 @@ static int hdmi_codec_probe(struct platform_device *pdev) | |||
| 792 | i++; | 787 | i++; |
| 793 | } | 788 | } |
| 794 | 789 | ||
| 795 | if (hcd->spdif) | 790 | if (hcd->spdif) { |
| 796 | hcp->daidrv[i] = hdmi_spdif_dai; | 791 | hcp->daidrv[i] = hdmi_spdif_dai; |
| 792 | hcp->daifmt[DAI_ID_SPDIF].fmt = HDMI_SPDIF; | ||
| 793 | } | ||
| 797 | 794 | ||
| 798 | dev_set_drvdata(dev, hcp); | 795 | dev_set_drvdata(dev, hcp); |
| 799 | 796 | ||
diff --git a/sound/soc/codecs/nau8810.c b/sound/soc/codecs/nau8810.c index bfd74b86c9d2..645aa0794123 100644 --- a/sound/soc/codecs/nau8810.c +++ b/sound/soc/codecs/nau8810.c | |||
| @@ -411,9 +411,9 @@ static const struct snd_soc_dapm_widget nau8810_dapm_widgets[] = { | |||
| 411 | SND_SOC_DAPM_MIXER("Mono Mixer", NAU8810_REG_POWER3, | 411 | SND_SOC_DAPM_MIXER("Mono Mixer", NAU8810_REG_POWER3, |
| 412 | NAU8810_MOUTMX_EN_SFT, 0, &nau8810_mono_mixer_controls[0], | 412 | NAU8810_MOUTMX_EN_SFT, 0, &nau8810_mono_mixer_controls[0], |
| 413 | ARRAY_SIZE(nau8810_mono_mixer_controls)), | 413 | ARRAY_SIZE(nau8810_mono_mixer_controls)), |
| 414 | SND_SOC_DAPM_DAC("DAC", "HiFi Playback", NAU8810_REG_POWER3, | 414 | SND_SOC_DAPM_DAC("DAC", "Playback", NAU8810_REG_POWER3, |
| 415 | NAU8810_DAC_EN_SFT, 0), | 415 | NAU8810_DAC_EN_SFT, 0), |
| 416 | SND_SOC_DAPM_ADC("ADC", "HiFi Capture", NAU8810_REG_POWER2, | 416 | SND_SOC_DAPM_ADC("ADC", "Capture", NAU8810_REG_POWER2, |
| 417 | NAU8810_ADC_EN_SFT, 0), | 417 | NAU8810_ADC_EN_SFT, 0), |
| 418 | SND_SOC_DAPM_PGA("SpkN Out", NAU8810_REG_POWER3, | 418 | SND_SOC_DAPM_PGA("SpkN Out", NAU8810_REG_POWER3, |
| 419 | NAU8810_NSPK_EN_SFT, 0, NULL, 0), | 419 | NAU8810_NSPK_EN_SFT, 0, NULL, 0), |
diff --git a/sound/soc/codecs/nau8824.c b/sound/soc/codecs/nau8824.c index 87ed3dc496dc..5ab05e75edea 100644 --- a/sound/soc/codecs/nau8824.c +++ b/sound/soc/codecs/nau8824.c | |||
| @@ -681,8 +681,8 @@ static const struct snd_soc_dapm_widget nau8824_dapm_widgets[] = { | |||
| 681 | SND_SOC_DAPM_ADC("ADCR", NULL, NAU8824_REG_ANALOG_ADC_2, | 681 | SND_SOC_DAPM_ADC("ADCR", NULL, NAU8824_REG_ANALOG_ADC_2, |
| 682 | NAU8824_ADCR_EN_SFT, 0), | 682 | NAU8824_ADCR_EN_SFT, 0), |
| 683 | 683 | ||
| 684 | SND_SOC_DAPM_AIF_OUT("AIFTX", "HiFi Capture", 0, SND_SOC_NOPM, 0, 0), | 684 | SND_SOC_DAPM_AIF_OUT("AIFTX", "Capture", 0, SND_SOC_NOPM, 0, 0), |
| 685 | SND_SOC_DAPM_AIF_IN("AIFRX", "HiFi Playback", 0, SND_SOC_NOPM, 0, 0), | 685 | SND_SOC_DAPM_AIF_IN("AIFRX", "Playback", 0, SND_SOC_NOPM, 0, 0), |
| 686 | 686 | ||
| 687 | SND_SOC_DAPM_DAC("DACL", NULL, NAU8824_REG_RDAC, | 687 | SND_SOC_DAPM_DAC("DACL", NULL, NAU8824_REG_RDAC, |
| 688 | NAU8824_DACL_EN_SFT, 0), | 688 | NAU8824_DACL_EN_SFT, 0), |
| @@ -831,6 +831,36 @@ static void nau8824_int_status_clear_all(struct regmap *regmap) | |||
| 831 | } | 831 | } |
| 832 | } | 832 | } |
| 833 | 833 | ||
| 834 | static void nau8824_dapm_disable_pin(struct nau8824 *nau8824, const char *pin) | ||
| 835 | { | ||
| 836 | struct snd_soc_dapm_context *dapm = nau8824->dapm; | ||
| 837 | const char *prefix = dapm->component->name_prefix; | ||
| 838 | char prefixed_pin[80]; | ||
| 839 | |||
| 840 | if (prefix) { | ||
| 841 | snprintf(prefixed_pin, sizeof(prefixed_pin), "%s %s", | ||
| 842 | prefix, pin); | ||
| 843 | snd_soc_dapm_disable_pin(dapm, prefixed_pin); | ||
| 844 | } else { | ||
| 845 | snd_soc_dapm_disable_pin(dapm, pin); | ||
| 846 | } | ||
| 847 | } | ||
| 848 | |||
| 849 | static void nau8824_dapm_enable_pin(struct nau8824 *nau8824, const char *pin) | ||
| 850 | { | ||
| 851 | struct snd_soc_dapm_context *dapm = nau8824->dapm; | ||
| 852 | const char *prefix = dapm->component->name_prefix; | ||
| 853 | char prefixed_pin[80]; | ||
| 854 | |||
| 855 | if (prefix) { | ||
| 856 | snprintf(prefixed_pin, sizeof(prefixed_pin), "%s %s", | ||
| 857 | prefix, pin); | ||
| 858 | snd_soc_dapm_force_enable_pin(dapm, prefixed_pin); | ||
| 859 | } else { | ||
| 860 | snd_soc_dapm_force_enable_pin(dapm, pin); | ||
| 861 | } | ||
| 862 | } | ||
| 863 | |||
| 834 | static void nau8824_eject_jack(struct nau8824 *nau8824) | 864 | static void nau8824_eject_jack(struct nau8824 *nau8824) |
| 835 | { | 865 | { |
| 836 | struct snd_soc_dapm_context *dapm = nau8824->dapm; | 866 | struct snd_soc_dapm_context *dapm = nau8824->dapm; |
| @@ -839,8 +869,8 @@ static void nau8824_eject_jack(struct nau8824 *nau8824) | |||
| 839 | /* Clear all interruption status */ | 869 | /* Clear all interruption status */ |
| 840 | nau8824_int_status_clear_all(regmap); | 870 | nau8824_int_status_clear_all(regmap); |
| 841 | 871 | ||
| 842 | snd_soc_dapm_disable_pin(dapm, "SAR"); | 872 | nau8824_dapm_disable_pin(nau8824, "SAR"); |
| 843 | snd_soc_dapm_disable_pin(dapm, "MICBIAS"); | 873 | nau8824_dapm_disable_pin(nau8824, "MICBIAS"); |
| 844 | snd_soc_dapm_sync(dapm); | 874 | snd_soc_dapm_sync(dapm); |
| 845 | 875 | ||
| 846 | /* Enable the insertion interruption, disable the ejection | 876 | /* Enable the insertion interruption, disable the ejection |
| @@ -870,8 +900,8 @@ static void nau8824_jdet_work(struct work_struct *work) | |||
| 870 | struct regmap *regmap = nau8824->regmap; | 900 | struct regmap *regmap = nau8824->regmap; |
| 871 | int adc_value, event = 0, event_mask = 0; | 901 | int adc_value, event = 0, event_mask = 0; |
| 872 | 902 | ||
| 873 | snd_soc_dapm_force_enable_pin(dapm, "MICBIAS"); | 903 | nau8824_dapm_enable_pin(nau8824, "MICBIAS"); |
| 874 | snd_soc_dapm_force_enable_pin(dapm, "SAR"); | 904 | nau8824_dapm_enable_pin(nau8824, "SAR"); |
| 875 | snd_soc_dapm_sync(dapm); | 905 | snd_soc_dapm_sync(dapm); |
| 876 | 906 | ||
| 877 | msleep(100); | 907 | msleep(100); |
| @@ -882,8 +912,8 @@ static void nau8824_jdet_work(struct work_struct *work) | |||
| 882 | if (adc_value < HEADSET_SARADC_THD) { | 912 | if (adc_value < HEADSET_SARADC_THD) { |
| 883 | event |= SND_JACK_HEADPHONE; | 913 | event |= SND_JACK_HEADPHONE; |
| 884 | 914 | ||
| 885 | snd_soc_dapm_disable_pin(dapm, "SAR"); | 915 | nau8824_dapm_disable_pin(nau8824, "SAR"); |
| 886 | snd_soc_dapm_disable_pin(dapm, "MICBIAS"); | 916 | nau8824_dapm_disable_pin(nau8824, "MICBIAS"); |
| 887 | snd_soc_dapm_sync(dapm); | 917 | snd_soc_dapm_sync(dapm); |
| 888 | } else { | 918 | } else { |
| 889 | event |= SND_JACK_HEADSET; | 919 | event |= SND_JACK_HEADSET; |
diff --git a/sound/soc/codecs/rt5682.c b/sound/soc/codecs/rt5682.c index 9d5acd2d04ab..86a7fa31c294 100644 --- a/sound/soc/codecs/rt5682.c +++ b/sound/soc/codecs/rt5682.c | |||
| @@ -910,13 +910,21 @@ static int rt5682_headset_detect(struct snd_soc_component *component, | |||
| 910 | int jack_insert) | 910 | int jack_insert) |
| 911 | { | 911 | { |
| 912 | struct rt5682_priv *rt5682 = snd_soc_component_get_drvdata(component); | 912 | struct rt5682_priv *rt5682 = snd_soc_component_get_drvdata(component); |
| 913 | struct snd_soc_dapm_context *dapm = | ||
| 914 | snd_soc_component_get_dapm(component); | ||
| 915 | unsigned int val, count; | 913 | unsigned int val, count; |
| 916 | 914 | ||
| 917 | if (jack_insert) { | 915 | if (jack_insert) { |
| 918 | snd_soc_dapm_force_enable_pin(dapm, "CBJ Power"); | 916 | |
| 919 | snd_soc_dapm_sync(dapm); | 917 | snd_soc_component_update_bits(component, RT5682_PWR_ANLG_1, |
| 918 | RT5682_PWR_VREF2 | RT5682_PWR_MB, | ||
| 919 | RT5682_PWR_VREF2 | RT5682_PWR_MB); | ||
| 920 | snd_soc_component_update_bits(component, | ||
| 921 | RT5682_PWR_ANLG_1, RT5682_PWR_FV2, 0); | ||
| 922 | usleep_range(15000, 20000); | ||
| 923 | snd_soc_component_update_bits(component, | ||
| 924 | RT5682_PWR_ANLG_1, RT5682_PWR_FV2, RT5682_PWR_FV2); | ||
| 925 | snd_soc_component_update_bits(component, RT5682_PWR_ANLG_3, | ||
| 926 | RT5682_PWR_CBJ, RT5682_PWR_CBJ); | ||
| 927 | |||
| 920 | snd_soc_component_update_bits(component, RT5682_CBJ_CTRL_1, | 928 | snd_soc_component_update_bits(component, RT5682_CBJ_CTRL_1, |
| 921 | RT5682_TRIG_JD_MASK, RT5682_TRIG_JD_HIGH); | 929 | RT5682_TRIG_JD_MASK, RT5682_TRIG_JD_HIGH); |
| 922 | 930 | ||
| @@ -944,8 +952,10 @@ static int rt5682_headset_detect(struct snd_soc_component *component, | |||
| 944 | rt5682_enable_push_button_irq(component, false); | 952 | rt5682_enable_push_button_irq(component, false); |
| 945 | snd_soc_component_update_bits(component, RT5682_CBJ_CTRL_1, | 953 | snd_soc_component_update_bits(component, RT5682_CBJ_CTRL_1, |
| 946 | RT5682_TRIG_JD_MASK, RT5682_TRIG_JD_LOW); | 954 | RT5682_TRIG_JD_MASK, RT5682_TRIG_JD_LOW); |
| 947 | snd_soc_dapm_disable_pin(dapm, "CBJ Power"); | 955 | snd_soc_component_update_bits(component, RT5682_PWR_ANLG_1, |
| 948 | snd_soc_dapm_sync(dapm); | 956 | RT5682_PWR_VREF2 | RT5682_PWR_MB, 0); |
| 957 | snd_soc_component_update_bits(component, RT5682_PWR_ANLG_3, | ||
| 958 | RT5682_PWR_CBJ, 0); | ||
| 949 | 959 | ||
| 950 | rt5682->jack_type = 0; | 960 | rt5682->jack_type = 0; |
| 951 | } | 961 | } |
| @@ -1198,7 +1208,7 @@ static int set_filter_clk(struct snd_soc_dapm_widget *w, | |||
| 1198 | struct snd_soc_component *component = | 1208 | struct snd_soc_component *component = |
| 1199 | snd_soc_dapm_to_component(w->dapm); | 1209 | snd_soc_dapm_to_component(w->dapm); |
| 1200 | struct rt5682_priv *rt5682 = snd_soc_component_get_drvdata(component); | 1210 | struct rt5682_priv *rt5682 = snd_soc_component_get_drvdata(component); |
| 1201 | int ref, val, reg, sft, mask, idx = -EINVAL; | 1211 | int ref, val, reg, idx = -EINVAL; |
| 1202 | static const int div_f[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48}; | 1212 | static const int div_f[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48}; |
| 1203 | static const int div_o[] = {1, 2, 4, 6, 8, 12, 16, 24, 32, 48}; | 1213 | static const int div_o[] = {1, 2, 4, 6, 8, 12, 16, 24, 32, 48}; |
| 1204 | 1214 | ||
| @@ -1212,15 +1222,10 @@ static int set_filter_clk(struct snd_soc_dapm_widget *w, | |||
| 1212 | 1222 | ||
| 1213 | idx = rt5682_div_sel(rt5682, ref, div_f, ARRAY_SIZE(div_f)); | 1223 | idx = rt5682_div_sel(rt5682, ref, div_f, ARRAY_SIZE(div_f)); |
| 1214 | 1224 | ||
| 1215 | if (w->shift == RT5682_PWR_ADC_S1F_BIT) { | 1225 | if (w->shift == RT5682_PWR_ADC_S1F_BIT) |
| 1216 | reg = RT5682_PLL_TRACK_3; | 1226 | reg = RT5682_PLL_TRACK_3; |
| 1217 | sft = RT5682_ADC_OSR_SFT; | 1227 | else |
| 1218 | mask = RT5682_ADC_OSR_MASK; | ||
| 1219 | } else { | ||
| 1220 | reg = RT5682_PLL_TRACK_2; | 1228 | reg = RT5682_PLL_TRACK_2; |
| 1221 | sft = RT5682_DAC_OSR_SFT; | ||
| 1222 | mask = RT5682_DAC_OSR_MASK; | ||
| 1223 | } | ||
| 1224 | 1229 | ||
| 1225 | snd_soc_component_update_bits(component, reg, | 1230 | snd_soc_component_update_bits(component, reg, |
| 1226 | RT5682_FILTER_CLK_DIV_MASK, idx << RT5682_FILTER_CLK_DIV_SFT); | 1231 | RT5682_FILTER_CLK_DIV_MASK, idx << RT5682_FILTER_CLK_DIV_SFT); |
| @@ -1232,7 +1237,8 @@ static int set_filter_clk(struct snd_soc_dapm_widget *w, | |||
| 1232 | } | 1237 | } |
| 1233 | 1238 | ||
| 1234 | snd_soc_component_update_bits(component, RT5682_ADDA_CLK_1, | 1239 | snd_soc_component_update_bits(component, RT5682_ADDA_CLK_1, |
| 1235 | mask, idx << sft); | 1240 | RT5682_ADC_OSR_MASK | RT5682_DAC_OSR_MASK, |
| 1241 | (idx << RT5682_ADC_OSR_SFT) | (idx << RT5682_DAC_OSR_SFT)); | ||
| 1236 | 1242 | ||
| 1237 | return 0; | 1243 | return 0; |
| 1238 | } | 1244 | } |
| @@ -1591,8 +1597,6 @@ static const struct snd_soc_dapm_widget rt5682_dapm_widgets[] = { | |||
| 1591 | 0, NULL, 0), | 1597 | 0, NULL, 0), |
| 1592 | SND_SOC_DAPM_SUPPLY("Vref1", RT5682_PWR_ANLG_1, RT5682_PWR_VREF1_BIT, 0, | 1598 | SND_SOC_DAPM_SUPPLY("Vref1", RT5682_PWR_ANLG_1, RT5682_PWR_VREF1_BIT, 0, |
| 1593 | rt5655_set_verf, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), | 1599 | rt5655_set_verf, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), |
| 1594 | SND_SOC_DAPM_SUPPLY("Vref2", RT5682_PWR_ANLG_1, RT5682_PWR_VREF2_BIT, 0, | ||
| 1595 | rt5655_set_verf, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), | ||
| 1596 | 1600 | ||
| 1597 | /* ASRC */ | 1601 | /* ASRC */ |
| 1598 | SND_SOC_DAPM_SUPPLY_S("DAC STO1 ASRC", 1, RT5682_PLL_TRACK_1, | 1602 | SND_SOC_DAPM_SUPPLY_S("DAC STO1 ASRC", 1, RT5682_PLL_TRACK_1, |
| @@ -1627,9 +1631,6 @@ static const struct snd_soc_dapm_widget rt5682_dapm_widgets[] = { | |||
| 1627 | SND_SOC_DAPM_PGA("BST1 CBJ", SND_SOC_NOPM, | 1631 | SND_SOC_DAPM_PGA("BST1 CBJ", SND_SOC_NOPM, |
| 1628 | 0, 0, NULL, 0), | 1632 | 0, 0, NULL, 0), |
| 1629 | 1633 | ||
| 1630 | SND_SOC_DAPM_SUPPLY("CBJ Power", RT5682_PWR_ANLG_3, | ||
| 1631 | RT5682_PWR_CBJ_BIT, 0, NULL, 0), | ||
| 1632 | |||
| 1633 | /* REC Mixer */ | 1634 | /* REC Mixer */ |
| 1634 | SND_SOC_DAPM_MIXER("RECMIX1L", SND_SOC_NOPM, 0, 0, rt5682_rec1_l_mix, | 1635 | SND_SOC_DAPM_MIXER("RECMIX1L", SND_SOC_NOPM, 0, 0, rt5682_rec1_l_mix, |
| 1635 | ARRAY_SIZE(rt5682_rec1_l_mix)), | 1636 | ARRAY_SIZE(rt5682_rec1_l_mix)), |
| @@ -1792,17 +1793,13 @@ static const struct snd_soc_dapm_route rt5682_dapm_routes[] = { | |||
| 1792 | 1793 | ||
| 1793 | /*Vref*/ | 1794 | /*Vref*/ |
| 1794 | {"MICBIAS1", NULL, "Vref1"}, | 1795 | {"MICBIAS1", NULL, "Vref1"}, |
| 1795 | {"MICBIAS1", NULL, "Vref2"}, | ||
| 1796 | {"MICBIAS2", NULL, "Vref1"}, | 1796 | {"MICBIAS2", NULL, "Vref1"}, |
| 1797 | {"MICBIAS2", NULL, "Vref2"}, | ||
| 1798 | 1797 | ||
| 1799 | {"CLKDET SYS", NULL, "CLKDET"}, | 1798 | {"CLKDET SYS", NULL, "CLKDET"}, |
| 1800 | 1799 | ||
| 1801 | {"IN1P", NULL, "LDO2"}, | 1800 | {"IN1P", NULL, "LDO2"}, |
| 1802 | 1801 | ||
| 1803 | {"BST1 CBJ", NULL, "IN1P"}, | 1802 | {"BST1 CBJ", NULL, "IN1P"}, |
| 1804 | {"BST1 CBJ", NULL, "CBJ Power"}, | ||
| 1805 | {"CBJ Power", NULL, "Vref2"}, | ||
| 1806 | 1803 | ||
| 1807 | {"RECMIX1L", "CBJ Switch", "BST1 CBJ"}, | 1804 | {"RECMIX1L", "CBJ Switch", "BST1 CBJ"}, |
| 1808 | {"RECMIX1L", NULL, "RECMIX1L Power"}, | 1805 | {"RECMIX1L", NULL, "RECMIX1L Power"}, |
| @@ -1912,9 +1909,7 @@ static const struct snd_soc_dapm_route rt5682_dapm_routes[] = { | |||
| 1912 | {"HP Amp", NULL, "Capless"}, | 1909 | {"HP Amp", NULL, "Capless"}, |
| 1913 | {"HP Amp", NULL, "Charge Pump"}, | 1910 | {"HP Amp", NULL, "Charge Pump"}, |
| 1914 | {"HP Amp", NULL, "CLKDET SYS"}, | 1911 | {"HP Amp", NULL, "CLKDET SYS"}, |
| 1915 | {"HP Amp", NULL, "CBJ Power"}, | ||
| 1916 | {"HP Amp", NULL, "Vref1"}, | 1912 | {"HP Amp", NULL, "Vref1"}, |
| 1917 | {"HP Amp", NULL, "Vref2"}, | ||
| 1918 | {"HPOL Playback", "Switch", "HP Amp"}, | 1913 | {"HPOL Playback", "Switch", "HP Amp"}, |
| 1919 | {"HPOR Playback", "Switch", "HP Amp"}, | 1914 | {"HPOR Playback", "Switch", "HP Amp"}, |
| 1920 | {"HPOL", NULL, "HPOL Playback"}, | 1915 | {"HPOL", NULL, "HPOL Playback"}, |
| @@ -2303,16 +2298,13 @@ static int rt5682_set_bias_level(struct snd_soc_component *component, | |||
| 2303 | switch (level) { | 2298 | switch (level) { |
| 2304 | case SND_SOC_BIAS_PREPARE: | 2299 | case SND_SOC_BIAS_PREPARE: |
| 2305 | regmap_update_bits(rt5682->regmap, RT5682_PWR_ANLG_1, | 2300 | regmap_update_bits(rt5682->regmap, RT5682_PWR_ANLG_1, |
| 2306 | RT5682_PWR_MB | RT5682_PWR_BG, | 2301 | RT5682_PWR_BG, RT5682_PWR_BG); |
| 2307 | RT5682_PWR_MB | RT5682_PWR_BG); | ||
| 2308 | regmap_update_bits(rt5682->regmap, RT5682_PWR_DIG_1, | 2302 | regmap_update_bits(rt5682->regmap, RT5682_PWR_DIG_1, |
| 2309 | RT5682_DIG_GATE_CTRL | RT5682_PWR_LDO, | 2303 | RT5682_DIG_GATE_CTRL | RT5682_PWR_LDO, |
| 2310 | RT5682_DIG_GATE_CTRL | RT5682_PWR_LDO); | 2304 | RT5682_DIG_GATE_CTRL | RT5682_PWR_LDO); |
| 2311 | break; | 2305 | break; |
| 2312 | 2306 | ||
| 2313 | case SND_SOC_BIAS_STANDBY: | 2307 | case SND_SOC_BIAS_STANDBY: |
| 2314 | regmap_update_bits(rt5682->regmap, RT5682_PWR_ANLG_1, | ||
| 2315 | RT5682_PWR_MB, RT5682_PWR_MB); | ||
| 2316 | regmap_update_bits(rt5682->regmap, RT5682_PWR_DIG_1, | 2308 | regmap_update_bits(rt5682->regmap, RT5682_PWR_DIG_1, |
| 2317 | RT5682_DIG_GATE_CTRL, RT5682_DIG_GATE_CTRL); | 2309 | RT5682_DIG_GATE_CTRL, RT5682_DIG_GATE_CTRL); |
| 2318 | break; | 2310 | break; |
| @@ -2320,7 +2312,7 @@ static int rt5682_set_bias_level(struct snd_soc_component *component, | |||
| 2320 | regmap_update_bits(rt5682->regmap, RT5682_PWR_DIG_1, | 2312 | regmap_update_bits(rt5682->regmap, RT5682_PWR_DIG_1, |
| 2321 | RT5682_DIG_GATE_CTRL | RT5682_PWR_LDO, 0); | 2313 | RT5682_DIG_GATE_CTRL | RT5682_PWR_LDO, 0); |
| 2322 | regmap_update_bits(rt5682->regmap, RT5682_PWR_ANLG_1, | 2314 | regmap_update_bits(rt5682->regmap, RT5682_PWR_ANLG_1, |
| 2323 | RT5682_PWR_MB | RT5682_PWR_BG, 0); | 2315 | RT5682_PWR_BG, 0); |
| 2324 | break; | 2316 | break; |
| 2325 | 2317 | ||
| 2326 | default: | 2318 | default: |
| @@ -2363,6 +2355,8 @@ static int rt5682_resume(struct snd_soc_component *component) | |||
| 2363 | regcache_cache_only(rt5682->regmap, false); | 2355 | regcache_cache_only(rt5682->regmap, false); |
| 2364 | regcache_sync(rt5682->regmap); | 2356 | regcache_sync(rt5682->regmap); |
| 2365 | 2357 | ||
| 2358 | rt5682_irq(0, rt5682); | ||
| 2359 | |||
| 2366 | return 0; | 2360 | return 0; |
| 2367 | } | 2361 | } |
| 2368 | #else | 2362 | #else |
diff --git a/sound/soc/codecs/tlv320aic32x4-i2c.c b/sound/soc/codecs/tlv320aic32x4-i2c.c index 385fa2e9525a..22c3a6bc0b6c 100644 --- a/sound/soc/codecs/tlv320aic32x4-i2c.c +++ b/sound/soc/codecs/tlv320aic32x4-i2c.c | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | * | 3 | * |
| 4 | * Copyright 2011 NW Digital Radio | 4 | * Copyright 2011 NW Digital Radio |
| 5 | * | 5 | * |
| 6 | * Author: Jeremy McDermond <nh6z@nh6z.net> | 6 | * Author: Annaliese McDermond <nh6z@nh6z.net> |
| 7 | * | 7 | * |
| 8 | * Based on sound/soc/codecs/wm8974 and TI driver for kernel 2.6.27. | 8 | * Based on sound/soc/codecs/wm8974 and TI driver for kernel 2.6.27. |
| 9 | * | 9 | * |
| @@ -72,5 +72,5 @@ static struct i2c_driver aic32x4_i2c_driver = { | |||
| 72 | module_i2c_driver(aic32x4_i2c_driver); | 72 | module_i2c_driver(aic32x4_i2c_driver); |
| 73 | 73 | ||
| 74 | MODULE_DESCRIPTION("ASoC TLV320AIC32x4 codec driver I2C"); | 74 | MODULE_DESCRIPTION("ASoC TLV320AIC32x4 codec driver I2C"); |
| 75 | MODULE_AUTHOR("Jeremy McDermond <nh6z@nh6z.net>"); | 75 | MODULE_AUTHOR("Annaliese McDermond <nh6z@nh6z.net>"); |
| 76 | MODULE_LICENSE("GPL"); | 76 | MODULE_LICENSE("GPL"); |
diff --git a/sound/soc/codecs/tlv320aic32x4-spi.c b/sound/soc/codecs/tlv320aic32x4-spi.c index 07d78ae51e05..aa5b7ba0254b 100644 --- a/sound/soc/codecs/tlv320aic32x4-spi.c +++ b/sound/soc/codecs/tlv320aic32x4-spi.c | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | * | 3 | * |
| 4 | * Copyright 2011 NW Digital Radio | 4 | * Copyright 2011 NW Digital Radio |
| 5 | * | 5 | * |
| 6 | * Author: Jeremy McDermond <nh6z@nh6z.net> | 6 | * Author: Annaliese McDermond <nh6z@nh6z.net> |
| 7 | * | 7 | * |
| 8 | * Based on sound/soc/codecs/wm8974 and TI driver for kernel 2.6.27. | 8 | * Based on sound/soc/codecs/wm8974 and TI driver for kernel 2.6.27. |
| 9 | * | 9 | * |
| @@ -74,5 +74,5 @@ static struct spi_driver aic32x4_spi_driver = { | |||
| 74 | module_spi_driver(aic32x4_spi_driver); | 74 | module_spi_driver(aic32x4_spi_driver); |
| 75 | 75 | ||
| 76 | MODULE_DESCRIPTION("ASoC TLV320AIC32x4 codec driver SPI"); | 76 | MODULE_DESCRIPTION("ASoC TLV320AIC32x4 codec driver SPI"); |
| 77 | MODULE_AUTHOR("Jeremy McDermond <nh6z@nh6z.net>"); | 77 | MODULE_AUTHOR("Annaliese McDermond <nh6z@nh6z.net>"); |
| 78 | MODULE_LICENSE("GPL"); | 78 | MODULE_LICENSE("GPL"); |
diff --git a/sound/soc/codecs/tlv320aic32x4.c b/sound/soc/codecs/tlv320aic32x4.c index 96f1526cb258..5520044929f4 100644 --- a/sound/soc/codecs/tlv320aic32x4.c +++ b/sound/soc/codecs/tlv320aic32x4.c | |||
| @@ -490,6 +490,8 @@ static const struct snd_soc_dapm_widget aic32x4_dapm_widgets[] = { | |||
| 490 | SND_SOC_DAPM_INPUT("IN2_R"), | 490 | SND_SOC_DAPM_INPUT("IN2_R"), |
| 491 | SND_SOC_DAPM_INPUT("IN3_L"), | 491 | SND_SOC_DAPM_INPUT("IN3_L"), |
| 492 | SND_SOC_DAPM_INPUT("IN3_R"), | 492 | SND_SOC_DAPM_INPUT("IN3_R"), |
| 493 | SND_SOC_DAPM_INPUT("CM_L"), | ||
| 494 | SND_SOC_DAPM_INPUT("CM_R"), | ||
| 493 | }; | 495 | }; |
| 494 | 496 | ||
| 495 | static const struct snd_soc_dapm_route aic32x4_dapm_routes[] = { | 497 | static const struct snd_soc_dapm_route aic32x4_dapm_routes[] = { |
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index 283583d1db60..516d17cb2182 100644 --- a/sound/soc/codecs/tlv320aic3x.c +++ b/sound/soc/codecs/tlv320aic3x.c | |||
| @@ -1609,7 +1609,6 @@ static int aic3x_probe(struct snd_soc_component *component) | |||
| 1609 | struct aic3x_priv *aic3x = snd_soc_component_get_drvdata(component); | 1609 | struct aic3x_priv *aic3x = snd_soc_component_get_drvdata(component); |
| 1610 | int ret, i; | 1610 | int ret, i; |
| 1611 | 1611 | ||
| 1612 | INIT_LIST_HEAD(&aic3x->list); | ||
| 1613 | aic3x->component = component; | 1612 | aic3x->component = component; |
| 1614 | 1613 | ||
| 1615 | for (i = 0; i < ARRAY_SIZE(aic3x->supplies); i++) { | 1614 | for (i = 0; i < ARRAY_SIZE(aic3x->supplies); i++) { |
| @@ -1873,6 +1872,7 @@ static int aic3x_i2c_probe(struct i2c_client *i2c, | |||
| 1873 | if (ret != 0) | 1872 | if (ret != 0) |
| 1874 | goto err_gpio; | 1873 | goto err_gpio; |
| 1875 | 1874 | ||
| 1875 | INIT_LIST_HEAD(&aic3x->list); | ||
| 1876 | list_add(&aic3x->list, &reset_list); | 1876 | list_add(&aic3x->list, &reset_list); |
| 1877 | 1877 | ||
| 1878 | return 0; | 1878 | return 0; |
| @@ -1889,6 +1889,8 @@ static int aic3x_i2c_remove(struct i2c_client *client) | |||
| 1889 | { | 1889 | { |
| 1890 | struct aic3x_priv *aic3x = i2c_get_clientdata(client); | 1890 | struct aic3x_priv *aic3x = i2c_get_clientdata(client); |
| 1891 | 1891 | ||
| 1892 | list_del(&aic3x->list); | ||
| 1893 | |||
| 1892 | if (gpio_is_valid(aic3x->gpio_reset) && | 1894 | if (gpio_is_valid(aic3x->gpio_reset) && |
| 1893 | !aic3x_is_shared_reset(aic3x)) { | 1895 | !aic3x_is_shared_reset(aic3x)) { |
| 1894 | gpio_set_value(aic3x->gpio_reset, 0); | 1896 | gpio_set_value(aic3x->gpio_reset, 0); |
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index b93fdc8d2d6f..b0b48eb9c7c9 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c | |||
| @@ -2905,6 +2905,8 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w, | |||
| 2905 | if (wm_adsp_fw[dsp->fw].num_caps != 0) | 2905 | if (wm_adsp_fw[dsp->fw].num_caps != 0) |
| 2906 | wm_adsp_buffer_free(dsp); | 2906 | wm_adsp_buffer_free(dsp); |
| 2907 | 2907 | ||
| 2908 | dsp->fatal_error = false; | ||
| 2909 | |||
| 2908 | mutex_unlock(&dsp->pwr_lock); | 2910 | mutex_unlock(&dsp->pwr_lock); |
| 2909 | 2911 | ||
| 2910 | adsp_dbg(dsp, "Execution stopped\n"); | 2912 | adsp_dbg(dsp, "Execution stopped\n"); |
| @@ -3000,6 +3002,9 @@ static int wm_adsp_compr_attach(struct wm_adsp_compr *compr) | |||
| 3000 | { | 3002 | { |
| 3001 | struct wm_adsp_compr_buf *buf = NULL, *tmp; | 3003 | struct wm_adsp_compr_buf *buf = NULL, *tmp; |
| 3002 | 3004 | ||
| 3005 | if (compr->dsp->fatal_error) | ||
| 3006 | return -EINVAL; | ||
| 3007 | |||
| 3003 | list_for_each_entry(tmp, &compr->dsp->buffer_list, list) { | 3008 | list_for_each_entry(tmp, &compr->dsp->buffer_list, list) { |
| 3004 | if (!tmp->name || !strcmp(compr->name, tmp->name)) { | 3009 | if (!tmp->name || !strcmp(compr->name, tmp->name)) { |
| 3005 | buf = tmp; | 3010 | buf = tmp; |
| @@ -3535,11 +3540,11 @@ static int wm_adsp_buffer_get_error(struct wm_adsp_compr_buf *buf) | |||
| 3535 | 3540 | ||
| 3536 | ret = wm_adsp_buffer_read(buf, HOST_BUFFER_FIELD(error), &buf->error); | 3541 | ret = wm_adsp_buffer_read(buf, HOST_BUFFER_FIELD(error), &buf->error); |
| 3537 | if (ret < 0) { | 3542 | if (ret < 0) { |
| 3538 | adsp_err(buf->dsp, "Failed to check buffer error: %d\n", ret); | 3543 | compr_err(buf, "Failed to check buffer error: %d\n", ret); |
| 3539 | return ret; | 3544 | return ret; |
| 3540 | } | 3545 | } |
| 3541 | if (buf->error != 0) { | 3546 | if (buf->error != 0) { |
| 3542 | adsp_err(buf->dsp, "Buffer error occurred: %d\n", buf->error); | 3547 | compr_err(buf, "Buffer error occurred: %d\n", buf->error); |
| 3543 | return -EIO; | 3548 | return -EIO; |
| 3544 | } | 3549 | } |
| 3545 | 3550 | ||
| @@ -3571,8 +3576,6 @@ int wm_adsp_compr_trigger(struct snd_compr_stream *stream, int cmd) | |||
| 3571 | if (ret < 0) | 3576 | if (ret < 0) |
| 3572 | break; | 3577 | break; |
| 3573 | 3578 | ||
| 3574 | wm_adsp_buffer_clear(compr->buf); | ||
| 3575 | |||
| 3576 | /* Trigger the IRQ at one fragment of data */ | 3579 | /* Trigger the IRQ at one fragment of data */ |
| 3577 | ret = wm_adsp_buffer_write(compr->buf, | 3580 | ret = wm_adsp_buffer_write(compr->buf, |
| 3578 | HOST_BUFFER_FIELD(high_water_mark), | 3581 | HOST_BUFFER_FIELD(high_water_mark), |
| @@ -3584,6 +3587,8 @@ int wm_adsp_compr_trigger(struct snd_compr_stream *stream, int cmd) | |||
| 3584 | } | 3587 | } |
| 3585 | break; | 3588 | break; |
| 3586 | case SNDRV_PCM_TRIGGER_STOP: | 3589 | case SNDRV_PCM_TRIGGER_STOP: |
| 3590 | if (wm_adsp_compr_attached(compr)) | ||
| 3591 | wm_adsp_buffer_clear(compr->buf); | ||
| 3587 | break; | 3592 | break; |
| 3588 | default: | 3593 | default: |
| 3589 | ret = -EINVAL; | 3594 | ret = -EINVAL; |
| @@ -3917,22 +3922,40 @@ int wm_adsp2_lock(struct wm_adsp *dsp, unsigned int lock_regions) | |||
| 3917 | } | 3922 | } |
| 3918 | EXPORT_SYMBOL_GPL(wm_adsp2_lock); | 3923 | EXPORT_SYMBOL_GPL(wm_adsp2_lock); |
| 3919 | 3924 | ||
| 3925 | static void wm_adsp_fatal_error(struct wm_adsp *dsp) | ||
| 3926 | { | ||
| 3927 | struct wm_adsp_compr *compr; | ||
| 3928 | |||
| 3929 | dsp->fatal_error = true; | ||
| 3930 | |||
| 3931 | list_for_each_entry(compr, &dsp->compr_list, list) { | ||
| 3932 | if (compr->stream) { | ||
| 3933 | snd_compr_stop_error(compr->stream, | ||
| 3934 | SNDRV_PCM_STATE_XRUN); | ||
| 3935 | snd_compr_fragment_elapsed(compr->stream); | ||
| 3936 | } | ||
| 3937 | } | ||
| 3938 | } | ||
| 3939 | |||
| 3920 | irqreturn_t wm_adsp2_bus_error(struct wm_adsp *dsp) | 3940 | irqreturn_t wm_adsp2_bus_error(struct wm_adsp *dsp) |
| 3921 | { | 3941 | { |
| 3922 | unsigned int val; | 3942 | unsigned int val; |
| 3923 | struct regmap *regmap = dsp->regmap; | 3943 | struct regmap *regmap = dsp->regmap; |
| 3924 | int ret = 0; | 3944 | int ret = 0; |
| 3925 | 3945 | ||
| 3946 | mutex_lock(&dsp->pwr_lock); | ||
| 3947 | |||
| 3926 | ret = regmap_read(regmap, dsp->base + ADSP2_LOCK_REGION_CTRL, &val); | 3948 | ret = regmap_read(regmap, dsp->base + ADSP2_LOCK_REGION_CTRL, &val); |
| 3927 | if (ret) { | 3949 | if (ret) { |
| 3928 | adsp_err(dsp, | 3950 | adsp_err(dsp, |
| 3929 | "Failed to read Region Lock Ctrl register: %d\n", ret); | 3951 | "Failed to read Region Lock Ctrl register: %d\n", ret); |
| 3930 | return IRQ_HANDLED; | 3952 | goto error; |
| 3931 | } | 3953 | } |
| 3932 | 3954 | ||
| 3933 | if (val & ADSP2_WDT_TIMEOUT_STS_MASK) { | 3955 | if (val & ADSP2_WDT_TIMEOUT_STS_MASK) { |
| 3934 | adsp_err(dsp, "watchdog timeout error\n"); | 3956 | adsp_err(dsp, "watchdog timeout error\n"); |
| 3935 | wm_adsp_stop_watchdog(dsp); | 3957 | wm_adsp_stop_watchdog(dsp); |
| 3958 | wm_adsp_fatal_error(dsp); | ||
| 3936 | } | 3959 | } |
| 3937 | 3960 | ||
| 3938 | if (val & (ADSP2_SLAVE_ERR_MASK | ADSP2_REGION_LOCK_ERR_MASK)) { | 3961 | if (val & (ADSP2_SLAVE_ERR_MASK | ADSP2_REGION_LOCK_ERR_MASK)) { |
| @@ -3946,7 +3969,7 @@ irqreturn_t wm_adsp2_bus_error(struct wm_adsp *dsp) | |||
| 3946 | adsp_err(dsp, | 3969 | adsp_err(dsp, |
| 3947 | "Failed to read Bus Err Addr register: %d\n", | 3970 | "Failed to read Bus Err Addr register: %d\n", |
| 3948 | ret); | 3971 | ret); |
| 3949 | return IRQ_HANDLED; | 3972 | goto error; |
| 3950 | } | 3973 | } |
| 3951 | 3974 | ||
| 3952 | adsp_err(dsp, "bus error address = 0x%x\n", | 3975 | adsp_err(dsp, "bus error address = 0x%x\n", |
| @@ -3959,7 +3982,7 @@ irqreturn_t wm_adsp2_bus_error(struct wm_adsp *dsp) | |||
| 3959 | adsp_err(dsp, | 3982 | adsp_err(dsp, |
| 3960 | "Failed to read Pmem Xmem Err Addr register: %d\n", | 3983 | "Failed to read Pmem Xmem Err Addr register: %d\n", |
| 3961 | ret); | 3984 | ret); |
| 3962 | return IRQ_HANDLED; | 3985 | goto error; |
| 3963 | } | 3986 | } |
| 3964 | 3987 | ||
| 3965 | adsp_err(dsp, "xmem error address = 0x%x\n", | 3988 | adsp_err(dsp, "xmem error address = 0x%x\n", |
| @@ -3972,6 +3995,9 @@ irqreturn_t wm_adsp2_bus_error(struct wm_adsp *dsp) | |||
| 3972 | regmap_update_bits(regmap, dsp->base + ADSP2_LOCK_REGION_CTRL, | 3995 | regmap_update_bits(regmap, dsp->base + ADSP2_LOCK_REGION_CTRL, |
| 3973 | ADSP2_CTRL_ERR_EINT, ADSP2_CTRL_ERR_EINT); | 3996 | ADSP2_CTRL_ERR_EINT, ADSP2_CTRL_ERR_EINT); |
| 3974 | 3997 | ||
| 3998 | error: | ||
| 3999 | mutex_unlock(&dsp->pwr_lock); | ||
| 4000 | |||
| 3975 | return IRQ_HANDLED; | 4001 | return IRQ_HANDLED; |
| 3976 | } | 4002 | } |
| 3977 | EXPORT_SYMBOL_GPL(wm_adsp2_bus_error); | 4003 | EXPORT_SYMBOL_GPL(wm_adsp2_bus_error); |
diff --git a/sound/soc/codecs/wm_adsp.h b/sound/soc/codecs/wm_adsp.h index 59e07ad16329..8f09b4419a91 100644 --- a/sound/soc/codecs/wm_adsp.h +++ b/sound/soc/codecs/wm_adsp.h | |||
| @@ -85,6 +85,7 @@ struct wm_adsp { | |||
| 85 | bool preloaded; | 85 | bool preloaded; |
| 86 | bool booted; | 86 | bool booted; |
| 87 | bool running; | 87 | bool running; |
| 88 | bool fatal_error; | ||
| 88 | 89 | ||
| 89 | struct list_head ctl_list; | 90 | struct list_head ctl_list; |
| 90 | 91 | ||
diff --git a/sound/soc/fsl/fsl_asrc.c b/sound/soc/fsl/fsl_asrc.c index 528e8b108422..0b937924d2e4 100644 --- a/sound/soc/fsl/fsl_asrc.c +++ b/sound/soc/fsl/fsl_asrc.c | |||
| @@ -445,6 +445,19 @@ struct dma_chan *fsl_asrc_get_dma_channel(struct fsl_asrc_pair *pair, bool dir) | |||
| 445 | } | 445 | } |
| 446 | EXPORT_SYMBOL_GPL(fsl_asrc_get_dma_channel); | 446 | EXPORT_SYMBOL_GPL(fsl_asrc_get_dma_channel); |
| 447 | 447 | ||
| 448 | static int fsl_asrc_dai_startup(struct snd_pcm_substream *substream, | ||
| 449 | struct snd_soc_dai *dai) | ||
| 450 | { | ||
| 451 | struct fsl_asrc *asrc_priv = snd_soc_dai_get_drvdata(dai); | ||
| 452 | |||
| 453 | /* Odd channel number is not valid for older ASRC (channel_bits==3) */ | ||
| 454 | if (asrc_priv->channel_bits == 3) | ||
| 455 | snd_pcm_hw_constraint_step(substream->runtime, 0, | ||
| 456 | SNDRV_PCM_HW_PARAM_CHANNELS, 2); | ||
| 457 | |||
| 458 | return 0; | ||
| 459 | } | ||
| 460 | |||
| 448 | static int fsl_asrc_dai_hw_params(struct snd_pcm_substream *substream, | 461 | static int fsl_asrc_dai_hw_params(struct snd_pcm_substream *substream, |
| 449 | struct snd_pcm_hw_params *params, | 462 | struct snd_pcm_hw_params *params, |
| 450 | struct snd_soc_dai *dai) | 463 | struct snd_soc_dai *dai) |
| @@ -539,6 +552,7 @@ static int fsl_asrc_dai_trigger(struct snd_pcm_substream *substream, int cmd, | |||
| 539 | } | 552 | } |
| 540 | 553 | ||
| 541 | static const struct snd_soc_dai_ops fsl_asrc_dai_ops = { | 554 | static const struct snd_soc_dai_ops fsl_asrc_dai_ops = { |
| 555 | .startup = fsl_asrc_dai_startup, | ||
| 542 | .hw_params = fsl_asrc_dai_hw_params, | 556 | .hw_params = fsl_asrc_dai_hw_params, |
| 543 | .hw_free = fsl_asrc_dai_hw_free, | 557 | .hw_free = fsl_asrc_dai_hw_free, |
| 544 | .trigger = fsl_asrc_dai_trigger, | 558 | .trigger = fsl_asrc_dai_trigger, |
diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c index afe67c865330..3623aa9a6f2e 100644 --- a/sound/soc/fsl/fsl_esai.c +++ b/sound/soc/fsl/fsl_esai.c | |||
| @@ -54,6 +54,8 @@ struct fsl_esai { | |||
| 54 | u32 fifo_depth; | 54 | u32 fifo_depth; |
| 55 | u32 slot_width; | 55 | u32 slot_width; |
| 56 | u32 slots; | 56 | u32 slots; |
| 57 | u32 tx_mask; | ||
| 58 | u32 rx_mask; | ||
| 57 | u32 hck_rate[2]; | 59 | u32 hck_rate[2]; |
| 58 | u32 sck_rate[2]; | 60 | u32 sck_rate[2]; |
| 59 | bool hck_dir[2]; | 61 | bool hck_dir[2]; |
| @@ -361,21 +363,13 @@ static int fsl_esai_set_dai_tdm_slot(struct snd_soc_dai *dai, u32 tx_mask, | |||
| 361 | regmap_update_bits(esai_priv->regmap, REG_ESAI_TCCR, | 363 | regmap_update_bits(esai_priv->regmap, REG_ESAI_TCCR, |
| 362 | ESAI_xCCR_xDC_MASK, ESAI_xCCR_xDC(slots)); | 364 | ESAI_xCCR_xDC_MASK, ESAI_xCCR_xDC(slots)); |
| 363 | 365 | ||
| 364 | regmap_update_bits(esai_priv->regmap, REG_ESAI_TSMA, | ||
| 365 | ESAI_xSMA_xS_MASK, ESAI_xSMA_xS(tx_mask)); | ||
| 366 | regmap_update_bits(esai_priv->regmap, REG_ESAI_TSMB, | ||
| 367 | ESAI_xSMB_xS_MASK, ESAI_xSMB_xS(tx_mask)); | ||
| 368 | |||
| 369 | regmap_update_bits(esai_priv->regmap, REG_ESAI_RCCR, | 366 | regmap_update_bits(esai_priv->regmap, REG_ESAI_RCCR, |
| 370 | ESAI_xCCR_xDC_MASK, ESAI_xCCR_xDC(slots)); | 367 | ESAI_xCCR_xDC_MASK, ESAI_xCCR_xDC(slots)); |
| 371 | 368 | ||
| 372 | regmap_update_bits(esai_priv->regmap, REG_ESAI_RSMA, | ||
| 373 | ESAI_xSMA_xS_MASK, ESAI_xSMA_xS(rx_mask)); | ||
| 374 | regmap_update_bits(esai_priv->regmap, REG_ESAI_RSMB, | ||
| 375 | ESAI_xSMB_xS_MASK, ESAI_xSMB_xS(rx_mask)); | ||
| 376 | |||
| 377 | esai_priv->slot_width = slot_width; | 369 | esai_priv->slot_width = slot_width; |
| 378 | esai_priv->slots = slots; | 370 | esai_priv->slots = slots; |
| 371 | esai_priv->tx_mask = tx_mask; | ||
| 372 | esai_priv->rx_mask = rx_mask; | ||
| 379 | 373 | ||
| 380 | return 0; | 374 | return 0; |
| 381 | } | 375 | } |
| @@ -596,6 +590,7 @@ static int fsl_esai_trigger(struct snd_pcm_substream *substream, int cmd, | |||
| 596 | bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; | 590 | bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; |
| 597 | u8 i, channels = substream->runtime->channels; | 591 | u8 i, channels = substream->runtime->channels; |
| 598 | u32 pins = DIV_ROUND_UP(channels, esai_priv->slots); | 592 | u32 pins = DIV_ROUND_UP(channels, esai_priv->slots); |
| 593 | u32 mask; | ||
| 599 | 594 | ||
| 600 | switch (cmd) { | 595 | switch (cmd) { |
| 601 | case SNDRV_PCM_TRIGGER_START: | 596 | case SNDRV_PCM_TRIGGER_START: |
| @@ -608,15 +603,38 @@ static int fsl_esai_trigger(struct snd_pcm_substream *substream, int cmd, | |||
| 608 | for (i = 0; tx && i < channels; i++) | 603 | for (i = 0; tx && i < channels; i++) |
| 609 | regmap_write(esai_priv->regmap, REG_ESAI_ETDR, 0x0); | 604 | regmap_write(esai_priv->regmap, REG_ESAI_ETDR, 0x0); |
| 610 | 605 | ||
| 606 | /* | ||
| 607 | * When set the TE/RE in the end of enablement flow, there | ||
| 608 | * will be channel swap issue for multi data line case. | ||
| 609 | * In order to workaround this issue, we switch the bit | ||
| 610 | * enablement sequence to below sequence | ||
| 611 | * 1) clear the xSMB & xSMA: which is done in probe and | ||
| 612 | * stop state. | ||
| 613 | * 2) set TE/RE | ||
| 614 | * 3) set xSMB | ||
| 615 | * 4) set xSMA: xSMA is the last one in this flow, which | ||
| 616 | * will trigger esai to start. | ||
| 617 | */ | ||
| 611 | regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx), | 618 | regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx), |
| 612 | tx ? ESAI_xCR_TE_MASK : ESAI_xCR_RE_MASK, | 619 | tx ? ESAI_xCR_TE_MASK : ESAI_xCR_RE_MASK, |
| 613 | tx ? ESAI_xCR_TE(pins) : ESAI_xCR_RE(pins)); | 620 | tx ? ESAI_xCR_TE(pins) : ESAI_xCR_RE(pins)); |
| 621 | mask = tx ? esai_priv->tx_mask : esai_priv->rx_mask; | ||
| 622 | |||
| 623 | regmap_update_bits(esai_priv->regmap, REG_ESAI_xSMB(tx), | ||
| 624 | ESAI_xSMB_xS_MASK, ESAI_xSMB_xS(mask)); | ||
| 625 | regmap_update_bits(esai_priv->regmap, REG_ESAI_xSMA(tx), | ||
| 626 | ESAI_xSMA_xS_MASK, ESAI_xSMA_xS(mask)); | ||
| 627 | |||
| 614 | break; | 628 | break; |
| 615 | case SNDRV_PCM_TRIGGER_SUSPEND: | 629 | case SNDRV_PCM_TRIGGER_SUSPEND: |
| 616 | case SNDRV_PCM_TRIGGER_STOP: | 630 | case SNDRV_PCM_TRIGGER_STOP: |
| 617 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | 631 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: |
| 618 | regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx), | 632 | regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx), |
| 619 | tx ? ESAI_xCR_TE_MASK : ESAI_xCR_RE_MASK, 0); | 633 | tx ? ESAI_xCR_TE_MASK : ESAI_xCR_RE_MASK, 0); |
| 634 | regmap_update_bits(esai_priv->regmap, REG_ESAI_xSMA(tx), | ||
| 635 | ESAI_xSMA_xS_MASK, 0); | ||
| 636 | regmap_update_bits(esai_priv->regmap, REG_ESAI_xSMB(tx), | ||
| 637 | ESAI_xSMB_xS_MASK, 0); | ||
| 620 | 638 | ||
| 621 | /* Disable and reset FIFO */ | 639 | /* Disable and reset FIFO */ |
| 622 | regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx), | 640 | regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx), |
| @@ -906,6 +924,15 @@ static int fsl_esai_probe(struct platform_device *pdev) | |||
| 906 | return ret; | 924 | return ret; |
| 907 | } | 925 | } |
| 908 | 926 | ||
| 927 | esai_priv->tx_mask = 0xFFFFFFFF; | ||
| 928 | esai_priv->rx_mask = 0xFFFFFFFF; | ||
| 929 | |||
| 930 | /* Clear the TSMA, TSMB, RSMA, RSMB */ | ||
| 931 | regmap_write(esai_priv->regmap, REG_ESAI_TSMA, 0); | ||
| 932 | regmap_write(esai_priv->regmap, REG_ESAI_TSMB, 0); | ||
| 933 | regmap_write(esai_priv->regmap, REG_ESAI_RSMA, 0); | ||
| 934 | regmap_write(esai_priv->regmap, REG_ESAI_RSMB, 0); | ||
| 935 | |||
| 909 | ret = devm_snd_soc_register_component(&pdev->dev, &fsl_esai_component, | 936 | ret = devm_snd_soc_register_component(&pdev->dev, &fsl_esai_component, |
| 910 | &fsl_esai_dai, 1); | 937 | &fsl_esai_dai, 1); |
| 911 | if (ret) { | 938 | if (ret) { |
diff --git a/sound/soc/generic/audio-graph-card.c b/sound/soc/generic/audio-graph-card.c index bb12351330e8..69bc4848d787 100644 --- a/sound/soc/generic/audio-graph-card.c +++ b/sound/soc/generic/audio-graph-card.c | |||
| @@ -20,6 +20,8 @@ | |||
| 20 | #include <linux/string.h> | 20 | #include <linux/string.h> |
| 21 | #include <sound/simple_card_utils.h> | 21 | #include <sound/simple_card_utils.h> |
| 22 | 22 | ||
| 23 | #define DPCM_SELECTABLE 1 | ||
| 24 | |||
| 23 | struct graph_priv { | 25 | struct graph_priv { |
| 24 | struct snd_soc_card snd_card; | 26 | struct snd_soc_card snd_card; |
| 25 | struct graph_dai_props { | 27 | struct graph_dai_props { |
| @@ -440,6 +442,7 @@ static int graph_for_each_link(struct graph_priv *priv, | |||
| 440 | struct device_node *codec_port; | 442 | struct device_node *codec_port; |
| 441 | struct device_node *codec_port_old = NULL; | 443 | struct device_node *codec_port_old = NULL; |
| 442 | struct asoc_simple_card_data adata; | 444 | struct asoc_simple_card_data adata; |
| 445 | uintptr_t dpcm_selectable = (uintptr_t)of_device_get_match_data(dev); | ||
| 443 | int rc, ret; | 446 | int rc, ret; |
| 444 | 447 | ||
| 445 | /* loop for all listed CPU port */ | 448 | /* loop for all listed CPU port */ |
| @@ -470,8 +473,9 @@ static int graph_for_each_link(struct graph_priv *priv, | |||
| 470 | * if Codec port has many endpoints, | 473 | * if Codec port has many endpoints, |
| 471 | * or has convert-xxx property | 474 | * or has convert-xxx property |
| 472 | */ | 475 | */ |
| 473 | if ((of_get_child_count(codec_port) > 1) || | 476 | if (dpcm_selectable && |
| 474 | adata.convert_rate || adata.convert_channels) | 477 | ((of_get_child_count(codec_port) > 1) || |
| 478 | adata.convert_rate || adata.convert_channels)) | ||
| 475 | ret = func_dpcm(priv, cpu_ep, codec_ep, li, | 479 | ret = func_dpcm(priv, cpu_ep, codec_ep, li, |
| 476 | (codec_port_old == codec_port)); | 480 | (codec_port_old == codec_port)); |
| 477 | /* else normal sound */ | 481 | /* else normal sound */ |
| @@ -732,7 +736,8 @@ static int graph_remove(struct platform_device *pdev) | |||
| 732 | 736 | ||
| 733 | static const struct of_device_id graph_of_match[] = { | 737 | static const struct of_device_id graph_of_match[] = { |
| 734 | { .compatible = "audio-graph-card", }, | 738 | { .compatible = "audio-graph-card", }, |
| 735 | { .compatible = "audio-graph-scu-card", }, | 739 | { .compatible = "audio-graph-scu-card", |
| 740 | .data = (void *)DPCM_SELECTABLE }, | ||
| 736 | {}, | 741 | {}, |
| 737 | }; | 742 | }; |
| 738 | MODULE_DEVICE_TABLE(of, graph_of_match); | 743 | MODULE_DEVICE_TABLE(of, graph_of_match); |
diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c index 7147bba45a2a..34de32efc4c4 100644 --- a/sound/soc/generic/simple-card.c +++ b/sound/soc/generic/simple-card.c | |||
| @@ -9,12 +9,15 @@ | |||
| 9 | #include <linux/device.h> | 9 | #include <linux/device.h> |
| 10 | #include <linux/module.h> | 10 | #include <linux/module.h> |
| 11 | #include <linux/of.h> | 11 | #include <linux/of.h> |
| 12 | #include <linux/of_device.h> | ||
| 12 | #include <linux/platform_device.h> | 13 | #include <linux/platform_device.h> |
| 13 | #include <linux/string.h> | 14 | #include <linux/string.h> |
| 14 | #include <sound/simple_card.h> | 15 | #include <sound/simple_card.h> |
| 15 | #include <sound/soc-dai.h> | 16 | #include <sound/soc-dai.h> |
| 16 | #include <sound/soc.h> | 17 | #include <sound/soc.h> |
| 17 | 18 | ||
| 19 | #define DPCM_SELECTABLE 1 | ||
| 20 | |||
| 18 | struct simple_priv { | 21 | struct simple_priv { |
| 19 | struct snd_soc_card snd_card; | 22 | struct snd_soc_card snd_card; |
| 20 | struct simple_dai_props { | 23 | struct simple_dai_props { |
| @@ -441,6 +444,7 @@ static int simple_for_each_link(struct simple_priv *priv, | |||
| 441 | struct device *dev = simple_priv_to_dev(priv); | 444 | struct device *dev = simple_priv_to_dev(priv); |
| 442 | struct device_node *top = dev->of_node; | 445 | struct device_node *top = dev->of_node; |
| 443 | struct device_node *node; | 446 | struct device_node *node; |
| 447 | uintptr_t dpcm_selectable = (uintptr_t)of_device_get_match_data(dev); | ||
| 444 | bool is_top = 0; | 448 | bool is_top = 0; |
| 445 | int ret = 0; | 449 | int ret = 0; |
| 446 | 450 | ||
| @@ -480,8 +484,9 @@ static int simple_for_each_link(struct simple_priv *priv, | |||
| 480 | * if it has many CPUs, | 484 | * if it has many CPUs, |
| 481 | * or has convert-xxx property | 485 | * or has convert-xxx property |
| 482 | */ | 486 | */ |
| 483 | if (num > 2 || | 487 | if (dpcm_selectable && |
| 484 | adata.convert_rate || adata.convert_channels) | 488 | (num > 2 || |
| 489 | adata.convert_rate || adata.convert_channels)) | ||
| 485 | ret = func_dpcm(priv, np, codec, li, is_top); | 490 | ret = func_dpcm(priv, np, codec, li, is_top); |
| 486 | /* else normal sound */ | 491 | /* else normal sound */ |
| 487 | else | 492 | else |
| @@ -822,7 +827,8 @@ static int simple_remove(struct platform_device *pdev) | |||
| 822 | 827 | ||
| 823 | static const struct of_device_id simple_of_match[] = { | 828 | static const struct of_device_id simple_of_match[] = { |
| 824 | { .compatible = "simple-audio-card", }, | 829 | { .compatible = "simple-audio-card", }, |
| 825 | { .compatible = "simple-scu-audio-card", }, | 830 | { .compatible = "simple-scu-audio-card", |
| 831 | .data = (void *)DPCM_SELECTABLE }, | ||
| 826 | {}, | 832 | {}, |
| 827 | }; | 833 | }; |
| 828 | MODULE_DEVICE_TABLE(of, simple_of_match); | 834 | MODULE_DEVICE_TABLE(of, simple_of_match); |
diff --git a/sound/soc/intel/atom/sst-mfld-platform-pcm.c b/sound/soc/intel/atom/sst-mfld-platform-pcm.c index 08cea5b5cda9..0e8b1c5eec88 100644 --- a/sound/soc/intel/atom/sst-mfld-platform-pcm.c +++ b/sound/soc/intel/atom/sst-mfld-platform-pcm.c | |||
| @@ -706,9 +706,17 @@ static int sst_soc_probe(struct snd_soc_component *component) | |||
| 706 | return sst_dsp_init_v2_dpcm(component); | 706 | return sst_dsp_init_v2_dpcm(component); |
| 707 | } | 707 | } |
| 708 | 708 | ||
| 709 | static void sst_soc_remove(struct snd_soc_component *component) | ||
| 710 | { | ||
| 711 | struct sst_data *drv = dev_get_drvdata(component->dev); | ||
| 712 | |||
| 713 | drv->soc_card = NULL; | ||
| 714 | } | ||
| 715 | |||
| 709 | static const struct snd_soc_component_driver sst_soc_platform_drv = { | 716 | static const struct snd_soc_component_driver sst_soc_platform_drv = { |
| 710 | .name = DRV_NAME, | 717 | .name = DRV_NAME, |
| 711 | .probe = sst_soc_probe, | 718 | .probe = sst_soc_probe, |
| 719 | .remove = sst_soc_remove, | ||
| 712 | .ops = &sst_platform_ops, | 720 | .ops = &sst_platform_ops, |
| 713 | .compr_ops = &sst_platform_compr_ops, | 721 | .compr_ops = &sst_platform_compr_ops, |
| 714 | .pcm_new = sst_pcm_new, | 722 | .pcm_new = sst_pcm_new, |
diff --git a/sound/soc/intel/boards/cht_bsw_max98090_ti.c b/sound/soc/intel/boards/cht_bsw_max98090_ti.c index 3263b0495853..c0e0844f75b9 100644 --- a/sound/soc/intel/boards/cht_bsw_max98090_ti.c +++ b/sound/soc/intel/boards/cht_bsw_max98090_ti.c | |||
| @@ -43,6 +43,7 @@ struct cht_mc_private { | |||
| 43 | struct clk *mclk; | 43 | struct clk *mclk; |
| 44 | struct snd_soc_jack jack; | 44 | struct snd_soc_jack jack; |
| 45 | bool ts3a227e_present; | 45 | bool ts3a227e_present; |
| 46 | int quirks; | ||
| 46 | }; | 47 | }; |
| 47 | 48 | ||
| 48 | static int platform_clock_control(struct snd_soc_dapm_widget *w, | 49 | static int platform_clock_control(struct snd_soc_dapm_widget *w, |
| @@ -54,6 +55,10 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w, | |||
| 54 | struct cht_mc_private *ctx = snd_soc_card_get_drvdata(card); | 55 | struct cht_mc_private *ctx = snd_soc_card_get_drvdata(card); |
| 55 | int ret; | 56 | int ret; |
| 56 | 57 | ||
| 58 | /* See the comment in snd_cht_mc_probe() */ | ||
| 59 | if (ctx->quirks & QUIRK_PMC_PLT_CLK_0) | ||
| 60 | return 0; | ||
| 61 | |||
| 57 | codec_dai = snd_soc_card_get_codec_dai(card, CHT_CODEC_DAI); | 62 | codec_dai = snd_soc_card_get_codec_dai(card, CHT_CODEC_DAI); |
| 58 | if (!codec_dai) { | 63 | if (!codec_dai) { |
| 59 | dev_err(card->dev, "Codec dai not found; Unable to set platform clock\n"); | 64 | dev_err(card->dev, "Codec dai not found; Unable to set platform clock\n"); |
| @@ -223,6 +228,10 @@ static int cht_codec_init(struct snd_soc_pcm_runtime *runtime) | |||
| 223 | "jack detection gpios not added, error %d\n", ret); | 228 | "jack detection gpios not added, error %d\n", ret); |
| 224 | } | 229 | } |
| 225 | 230 | ||
| 231 | /* See the comment in snd_cht_mc_probe() */ | ||
| 232 | if (ctx->quirks & QUIRK_PMC_PLT_CLK_0) | ||
| 233 | return 0; | ||
| 234 | |||
| 226 | /* | 235 | /* |
| 227 | * The firmware might enable the clock at | 236 | * The firmware might enable the clock at |
| 228 | * boot (this information may or may not | 237 | * boot (this information may or may not |
| @@ -423,16 +432,15 @@ static int snd_cht_mc_probe(struct platform_device *pdev) | |||
| 423 | const char *mclk_name; | 432 | const char *mclk_name; |
| 424 | struct snd_soc_acpi_mach *mach; | 433 | struct snd_soc_acpi_mach *mach; |
| 425 | const char *platform_name; | 434 | const char *platform_name; |
| 426 | int quirks = 0; | ||
| 427 | |||
| 428 | dmi_id = dmi_first_match(cht_max98090_quirk_table); | ||
| 429 | if (dmi_id) | ||
| 430 | quirks = (unsigned long)dmi_id->driver_data; | ||
| 431 | 435 | ||
| 432 | drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_KERNEL); | 436 | drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_KERNEL); |
| 433 | if (!drv) | 437 | if (!drv) |
| 434 | return -ENOMEM; | 438 | return -ENOMEM; |
| 435 | 439 | ||
| 440 | dmi_id = dmi_first_match(cht_max98090_quirk_table); | ||
| 441 | if (dmi_id) | ||
| 442 | drv->quirks = (unsigned long)dmi_id->driver_data; | ||
| 443 | |||
| 436 | drv->ts3a227e_present = acpi_dev_found("104C227E"); | 444 | drv->ts3a227e_present = acpi_dev_found("104C227E"); |
| 437 | if (!drv->ts3a227e_present) { | 445 | if (!drv->ts3a227e_present) { |
| 438 | /* no need probe TI jack detection chip */ | 446 | /* no need probe TI jack detection chip */ |
| @@ -458,7 +466,7 @@ static int snd_cht_mc_probe(struct platform_device *pdev) | |||
| 458 | snd_soc_card_cht.dev = &pdev->dev; | 466 | snd_soc_card_cht.dev = &pdev->dev; |
| 459 | snd_soc_card_set_drvdata(&snd_soc_card_cht, drv); | 467 | snd_soc_card_set_drvdata(&snd_soc_card_cht, drv); |
| 460 | 468 | ||
| 461 | if (quirks & QUIRK_PMC_PLT_CLK_0) | 469 | if (drv->quirks & QUIRK_PMC_PLT_CLK_0) |
| 462 | mclk_name = "pmc_plt_clk_0"; | 470 | mclk_name = "pmc_plt_clk_0"; |
| 463 | else | 471 | else |
| 464 | mclk_name = "pmc_plt_clk_3"; | 472 | mclk_name = "pmc_plt_clk_3"; |
| @@ -471,6 +479,21 @@ static int snd_cht_mc_probe(struct platform_device *pdev) | |||
| 471 | return PTR_ERR(drv->mclk); | 479 | return PTR_ERR(drv->mclk); |
| 472 | } | 480 | } |
| 473 | 481 | ||
| 482 | /* | ||
| 483 | * Boards which have the MAX98090's clk connected to clk_0 do not seem | ||
| 484 | * to like it if we muck with the clock. If we disable the clock when | ||
| 485 | * it is unused we get "max98090 i2c-193C9890:00: PLL unlocked" errors | ||
| 486 | * and the PLL never seems to lock again. | ||
| 487 | * So for these boards we enable it here once and leave it at that. | ||
| 488 | */ | ||
| 489 | if (drv->quirks & QUIRK_PMC_PLT_CLK_0) { | ||
| 490 | ret_val = clk_prepare_enable(drv->mclk); | ||
| 491 | if (ret_val < 0) { | ||
| 492 | dev_err(&pdev->dev, "MCLK enable error: %d\n", ret_val); | ||
| 493 | return ret_val; | ||
| 494 | } | ||
| 495 | } | ||
| 496 | |||
| 474 | ret_val = devm_snd_soc_register_card(&pdev->dev, &snd_soc_card_cht); | 497 | ret_val = devm_snd_soc_register_card(&pdev->dev, &snd_soc_card_cht); |
| 475 | if (ret_val) { | 498 | if (ret_val) { |
| 476 | dev_err(&pdev->dev, | 499 | dev_err(&pdev->dev, |
| @@ -481,11 +504,23 @@ static int snd_cht_mc_probe(struct platform_device *pdev) | |||
| 481 | return ret_val; | 504 | return ret_val; |
| 482 | } | 505 | } |
| 483 | 506 | ||
| 507 | static int snd_cht_mc_remove(struct platform_device *pdev) | ||
| 508 | { | ||
| 509 | struct snd_soc_card *card = platform_get_drvdata(pdev); | ||
| 510 | struct cht_mc_private *ctx = snd_soc_card_get_drvdata(card); | ||
| 511 | |||
| 512 | if (ctx->quirks & QUIRK_PMC_PLT_CLK_0) | ||
| 513 | clk_disable_unprepare(ctx->mclk); | ||
| 514 | |||
| 515 | return 0; | ||
| 516 | } | ||
| 517 | |||
| 484 | static struct platform_driver snd_cht_mc_driver = { | 518 | static struct platform_driver snd_cht_mc_driver = { |
| 485 | .driver = { | 519 | .driver = { |
| 486 | .name = "cht-bsw-max98090", | 520 | .name = "cht-bsw-max98090", |
| 487 | }, | 521 | }, |
| 488 | .probe = snd_cht_mc_probe, | 522 | .probe = snd_cht_mc_probe, |
| 523 | .remove = snd_cht_mc_remove, | ||
| 489 | }; | 524 | }; |
| 490 | 525 | ||
| 491 | module_platform_driver(snd_cht_mc_driver) | 526 | module_platform_driver(snd_cht_mc_driver) |
diff --git a/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c b/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c index 7044d8c2b187..879f14257a3e 100644 --- a/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c +++ b/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c | |||
| @@ -405,7 +405,7 @@ static const struct snd_pcm_hw_constraint_list constraints_dmic_channels = { | |||
| 405 | }; | 405 | }; |
| 406 | 406 | ||
| 407 | static const unsigned int dmic_2ch[] = { | 407 | static const unsigned int dmic_2ch[] = { |
| 408 | 4, | 408 | 2, |
| 409 | }; | 409 | }; |
| 410 | 410 | ||
| 411 | static const struct snd_pcm_hw_constraint_list constraints_dmic_2ch = { | 411 | static const struct snd_pcm_hw_constraint_list constraints_dmic_2ch = { |
diff --git a/sound/soc/intel/skylake/skl-messages.c b/sound/soc/intel/skylake/skl-messages.c index 28c4806b196a..4bf70b4429f0 100644 --- a/sound/soc/intel/skylake/skl-messages.c +++ b/sound/soc/intel/skylake/skl-messages.c | |||
| @@ -483,6 +483,7 @@ static void skl_set_base_module_format(struct skl_sst *ctx, | |||
| 483 | base_cfg->audio_fmt.bit_depth = format->bit_depth; | 483 | base_cfg->audio_fmt.bit_depth = format->bit_depth; |
| 484 | base_cfg->audio_fmt.valid_bit_depth = format->valid_bit_depth; | 484 | base_cfg->audio_fmt.valid_bit_depth = format->valid_bit_depth; |
| 485 | base_cfg->audio_fmt.ch_cfg = format->ch_cfg; | 485 | base_cfg->audio_fmt.ch_cfg = format->ch_cfg; |
| 486 | base_cfg->audio_fmt.sample_type = format->sample_type; | ||
| 486 | 487 | ||
| 487 | dev_dbg(ctx->dev, "bit_depth=%x valid_bd=%x ch_config=%x\n", | 488 | dev_dbg(ctx->dev, "bit_depth=%x valid_bd=%x ch_config=%x\n", |
| 488 | format->bit_depth, format->valid_bit_depth, | 489 | format->bit_depth, format->valid_bit_depth, |
diff --git a/sound/soc/intel/skylake/skl-pcm.c b/sound/soc/intel/skylake/skl-pcm.c index 1ae83f4ccc36..9735e2412251 100644 --- a/sound/soc/intel/skylake/skl-pcm.c +++ b/sound/soc/intel/skylake/skl-pcm.c | |||
| @@ -181,6 +181,7 @@ int skl_pcm_link_dma_prepare(struct device *dev, struct skl_pipe_params *params) | |||
| 181 | struct hdac_stream *hstream; | 181 | struct hdac_stream *hstream; |
| 182 | struct hdac_ext_stream *stream; | 182 | struct hdac_ext_stream *stream; |
| 183 | struct hdac_ext_link *link; | 183 | struct hdac_ext_link *link; |
| 184 | unsigned char stream_tag; | ||
| 184 | 185 | ||
| 185 | hstream = snd_hdac_get_stream(bus, params->stream, | 186 | hstream = snd_hdac_get_stream(bus, params->stream, |
| 186 | params->link_dma_id + 1); | 187 | params->link_dma_id + 1); |
| @@ -199,10 +200,13 @@ int skl_pcm_link_dma_prepare(struct device *dev, struct skl_pipe_params *params) | |||
| 199 | 200 | ||
| 200 | snd_hdac_ext_link_stream_setup(stream, format_val); | 201 | snd_hdac_ext_link_stream_setup(stream, format_val); |
| 201 | 202 | ||
| 202 | list_for_each_entry(link, &bus->hlink_list, list) { | 203 | stream_tag = hstream->stream_tag; |
| 203 | if (link->index == params->link_index) | 204 | if (stream->hstream.direction == SNDRV_PCM_STREAM_PLAYBACK) { |
| 204 | snd_hdac_ext_link_set_stream_id(link, | 205 | list_for_each_entry(link, &bus->hlink_list, list) { |
| 205 | hstream->stream_tag); | 206 | if (link->index == params->link_index) |
| 207 | snd_hdac_ext_link_set_stream_id(link, | ||
| 208 | stream_tag); | ||
| 209 | } | ||
| 206 | } | 210 | } |
| 207 | 211 | ||
| 208 | stream->link_prepared = 1; | 212 | stream->link_prepared = 1; |
| @@ -645,6 +649,7 @@ static int skl_link_hw_free(struct snd_pcm_substream *substream, | |||
| 645 | struct hdac_ext_stream *link_dev = | 649 | struct hdac_ext_stream *link_dev = |
| 646 | snd_soc_dai_get_dma_data(dai, substream); | 650 | snd_soc_dai_get_dma_data(dai, substream); |
| 647 | struct hdac_ext_link *link; | 651 | struct hdac_ext_link *link; |
| 652 | unsigned char stream_tag; | ||
| 648 | 653 | ||
| 649 | dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name); | 654 | dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name); |
| 650 | 655 | ||
| @@ -654,7 +659,11 @@ static int skl_link_hw_free(struct snd_pcm_substream *substream, | |||
| 654 | if (!link) | 659 | if (!link) |
| 655 | return -EINVAL; | 660 | return -EINVAL; |
| 656 | 661 | ||
| 657 | snd_hdac_ext_link_clear_stream_id(link, hdac_stream(link_dev)->stream_tag); | 662 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { |
| 663 | stream_tag = hdac_stream(link_dev)->stream_tag; | ||
| 664 | snd_hdac_ext_link_clear_stream_id(link, stream_tag); | ||
| 665 | } | ||
| 666 | |||
| 658 | snd_hdac_ext_stream_release(link_dev, HDAC_EXT_STREAM_TYPE_LINK); | 667 | snd_hdac_ext_stream_release(link_dev, HDAC_EXT_STREAM_TYPE_LINK); |
| 659 | return 0; | 668 | return 0; |
| 660 | } | 669 | } |
| @@ -1453,13 +1462,20 @@ static int skl_platform_soc_probe(struct snd_soc_component *component) | |||
| 1453 | return 0; | 1462 | return 0; |
| 1454 | } | 1463 | } |
| 1455 | 1464 | ||
| 1465 | static void skl_pcm_remove(struct snd_soc_component *component) | ||
| 1466 | { | ||
| 1467 | /* remove topology */ | ||
| 1468 | snd_soc_tplg_component_remove(component, SND_SOC_TPLG_INDEX_ALL); | ||
| 1469 | } | ||
| 1470 | |||
| 1456 | static const struct snd_soc_component_driver skl_component = { | 1471 | static const struct snd_soc_component_driver skl_component = { |
| 1457 | .name = "pcm", | 1472 | .name = "pcm", |
| 1458 | .probe = skl_platform_soc_probe, | 1473 | .probe = skl_platform_soc_probe, |
| 1474 | .remove = skl_pcm_remove, | ||
| 1459 | .ops = &skl_platform_ops, | 1475 | .ops = &skl_platform_ops, |
| 1460 | .pcm_new = skl_pcm_new, | 1476 | .pcm_new = skl_pcm_new, |
| 1461 | .pcm_free = skl_pcm_free, | 1477 | .pcm_free = skl_pcm_free, |
| 1462 | .ignore_module_refcount = 1, /* do not increase the refcount in core */ | 1478 | .module_get_upon_open = 1, /* increment refcount when a pcm is opened */ |
| 1463 | }; | 1479 | }; |
| 1464 | 1480 | ||
| 1465 | int skl_platform_register(struct device *dev) | 1481 | int skl_platform_register(struct device *dev) |
diff --git a/sound/soc/mediatek/common/mtk-btcvsd.c b/sound/soc/mediatek/common/mtk-btcvsd.c index 1b8bcdaf02d1..9a163d7064d1 100644 --- a/sound/soc/mediatek/common/mtk-btcvsd.c +++ b/sound/soc/mediatek/common/mtk-btcvsd.c | |||
| @@ -49,6 +49,7 @@ enum bt_sco_state { | |||
| 49 | BT_SCO_STATE_IDLE, | 49 | BT_SCO_STATE_IDLE, |
| 50 | BT_SCO_STATE_RUNNING, | 50 | BT_SCO_STATE_RUNNING, |
| 51 | BT_SCO_STATE_ENDING, | 51 | BT_SCO_STATE_ENDING, |
| 52 | BT_SCO_STATE_LOOPBACK, | ||
| 52 | }; | 53 | }; |
| 53 | 54 | ||
| 54 | enum bt_sco_direct { | 55 | enum bt_sco_direct { |
| @@ -486,7 +487,8 @@ static irqreturn_t mtk_btcvsd_snd_irq_handler(int irq_id, void *dev) | |||
| 486 | if (bt->rx->state != BT_SCO_STATE_RUNNING && | 487 | if (bt->rx->state != BT_SCO_STATE_RUNNING && |
| 487 | bt->rx->state != BT_SCO_STATE_ENDING && | 488 | bt->rx->state != BT_SCO_STATE_ENDING && |
| 488 | bt->tx->state != BT_SCO_STATE_RUNNING && | 489 | bt->tx->state != BT_SCO_STATE_RUNNING && |
| 489 | bt->tx->state != BT_SCO_STATE_ENDING) { | 490 | bt->tx->state != BT_SCO_STATE_ENDING && |
| 491 | bt->tx->state != BT_SCO_STATE_LOOPBACK) { | ||
| 490 | dev_warn(bt->dev, "%s(), in idle state: rx->state: %d, tx->state: %d\n", | 492 | dev_warn(bt->dev, "%s(), in idle state: rx->state: %d, tx->state: %d\n", |
| 491 | __func__, bt->rx->state, bt->tx->state); | 493 | __func__, bt->rx->state, bt->tx->state); |
| 492 | goto irq_handler_exit; | 494 | goto irq_handler_exit; |
| @@ -512,6 +514,42 @@ static irqreturn_t mtk_btcvsd_snd_irq_handler(int irq_id, void *dev) | |||
| 512 | buf_cnt_tx = btsco_packet_info[packet_type][2]; | 514 | buf_cnt_tx = btsco_packet_info[packet_type][2]; |
| 513 | buf_cnt_rx = btsco_packet_info[packet_type][3]; | 515 | buf_cnt_rx = btsco_packet_info[packet_type][3]; |
| 514 | 516 | ||
| 517 | if (bt->tx->state == BT_SCO_STATE_LOOPBACK) { | ||
| 518 | u8 *src, *dst; | ||
| 519 | unsigned long connsys_addr_rx, ap_addr_rx; | ||
| 520 | unsigned long connsys_addr_tx, ap_addr_tx; | ||
| 521 | |||
| 522 | connsys_addr_rx = *bt->bt_reg_pkt_r; | ||
| 523 | ap_addr_rx = (unsigned long)bt->bt_sram_bank2_base + | ||
| 524 | (connsys_addr_rx & 0xFFFF); | ||
| 525 | |||
| 526 | connsys_addr_tx = *bt->bt_reg_pkt_w; | ||
| 527 | ap_addr_tx = (unsigned long)bt->bt_sram_bank2_base + | ||
| 528 | (connsys_addr_tx & 0xFFFF); | ||
| 529 | |||
| 530 | if (connsys_addr_tx == 0xdeadfeed || | ||
| 531 | connsys_addr_rx == 0xdeadfeed) { | ||
| 532 | /* bt return 0xdeadfeed if read reg during bt sleep */ | ||
| 533 | dev_warn(bt->dev, "%s(), connsys_addr_tx == 0xdeadfeed\n", | ||
| 534 | __func__); | ||
| 535 | goto irq_handler_exit; | ||
| 536 | } | ||
| 537 | |||
| 538 | src = (u8 *)ap_addr_rx; | ||
| 539 | dst = (u8 *)ap_addr_tx; | ||
| 540 | |||
| 541 | mtk_btcvsd_snd_data_transfer(BT_SCO_DIRECT_BT2ARM, src, | ||
| 542 | bt->tx->temp_packet_buf, | ||
| 543 | packet_length, | ||
| 544 | packet_num); | ||
| 545 | mtk_btcvsd_snd_data_transfer(BT_SCO_DIRECT_ARM2BT, | ||
| 546 | bt->tx->temp_packet_buf, dst, | ||
| 547 | packet_length, | ||
| 548 | packet_num); | ||
| 549 | bt->rx->rw_cnt++; | ||
| 550 | bt->tx->rw_cnt++; | ||
| 551 | } | ||
| 552 | |||
| 515 | if (bt->rx->state == BT_SCO_STATE_RUNNING || | 553 | if (bt->rx->state == BT_SCO_STATE_RUNNING || |
| 516 | bt->rx->state == BT_SCO_STATE_ENDING) { | 554 | bt->rx->state == BT_SCO_STATE_ENDING) { |
| 517 | if (bt->rx->xrun) { | 555 | if (bt->rx->xrun) { |
| @@ -1067,6 +1105,33 @@ static int btcvsd_band_set(struct snd_kcontrol *kcontrol, | |||
| 1067 | return 0; | 1105 | return 0; |
| 1068 | } | 1106 | } |
| 1069 | 1107 | ||
| 1108 | static int btcvsd_loopback_get(struct snd_kcontrol *kcontrol, | ||
| 1109 | struct snd_ctl_elem_value *ucontrol) | ||
| 1110 | { | ||
| 1111 | struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); | ||
| 1112 | struct mtk_btcvsd_snd *bt = snd_soc_component_get_drvdata(cmpnt); | ||
| 1113 | bool lpbk_en = bt->tx->state == BT_SCO_STATE_LOOPBACK; | ||
| 1114 | |||
| 1115 | ucontrol->value.integer.value[0] = lpbk_en; | ||
| 1116 | return 0; | ||
| 1117 | } | ||
| 1118 | |||
| 1119 | static int btcvsd_loopback_set(struct snd_kcontrol *kcontrol, | ||
| 1120 | struct snd_ctl_elem_value *ucontrol) | ||
| 1121 | { | ||
| 1122 | struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); | ||
| 1123 | struct mtk_btcvsd_snd *bt = snd_soc_component_get_drvdata(cmpnt); | ||
| 1124 | |||
| 1125 | if (ucontrol->value.integer.value[0]) { | ||
| 1126 | mtk_btcvsd_snd_set_state(bt, bt->tx, BT_SCO_STATE_LOOPBACK); | ||
| 1127 | mtk_btcvsd_snd_set_state(bt, bt->rx, BT_SCO_STATE_LOOPBACK); | ||
| 1128 | } else { | ||
| 1129 | mtk_btcvsd_snd_set_state(bt, bt->tx, BT_SCO_STATE_RUNNING); | ||
| 1130 | mtk_btcvsd_snd_set_state(bt, bt->rx, BT_SCO_STATE_RUNNING); | ||
| 1131 | } | ||
| 1132 | return 0; | ||
| 1133 | } | ||
| 1134 | |||
| 1070 | static int btcvsd_tx_mute_get(struct snd_kcontrol *kcontrol, | 1135 | static int btcvsd_tx_mute_get(struct snd_kcontrol *kcontrol, |
| 1071 | struct snd_ctl_elem_value *ucontrol) | 1136 | struct snd_ctl_elem_value *ucontrol) |
| 1072 | { | 1137 | { |
| @@ -1202,6 +1267,8 @@ static int btcvsd_tx_timestamp_get(struct snd_kcontrol *kcontrol, | |||
| 1202 | static const struct snd_kcontrol_new mtk_btcvsd_snd_controls[] = { | 1267 | static const struct snd_kcontrol_new mtk_btcvsd_snd_controls[] = { |
| 1203 | SOC_ENUM_EXT("BTCVSD Band", btcvsd_enum[0], | 1268 | SOC_ENUM_EXT("BTCVSD Band", btcvsd_enum[0], |
| 1204 | btcvsd_band_get, btcvsd_band_set), | 1269 | btcvsd_band_get, btcvsd_band_set), |
| 1270 | SOC_SINGLE_BOOL_EXT("BTCVSD Loopback Switch", 0, | ||
| 1271 | btcvsd_loopback_get, btcvsd_loopback_set), | ||
| 1205 | SOC_SINGLE_BOOL_EXT("BTCVSD Tx Mute Switch", 0, | 1272 | SOC_SINGLE_BOOL_EXT("BTCVSD Tx Mute Switch", 0, |
| 1206 | btcvsd_tx_mute_get, btcvsd_tx_mute_set), | 1273 | btcvsd_tx_mute_get, btcvsd_tx_mute_set), |
| 1207 | SOC_SINGLE_BOOL_EXT("BTCVSD Tx Irq Received Switch", 0, | 1274 | SOC_SINGLE_BOOL_EXT("BTCVSD Tx Irq Received Switch", 0, |
diff --git a/sound/soc/mediatek/mt8183/mt8183-afe-clk.c b/sound/soc/mediatek/mt8183/mt8183-afe-clk.c index f523ad103acc..48e81c5d52fc 100644 --- a/sound/soc/mediatek/mt8183/mt8183-afe-clk.c +++ b/sound/soc/mediatek/mt8183/mt8183-afe-clk.c | |||
| @@ -605,6 +605,10 @@ void mt8183_mck_disable(struct mtk_base_afe *afe, int mck_id) | |||
| 605 | int m_sel_id = mck_div[mck_id].m_sel_id; | 605 | int m_sel_id = mck_div[mck_id].m_sel_id; |
| 606 | int div_clk_id = mck_div[mck_id].div_clk_id; | 606 | int div_clk_id = mck_div[mck_id].div_clk_id; |
| 607 | 607 | ||
| 608 | /* i2s5 mck not support */ | ||
| 609 | if (mck_id == MT8183_I2S5_MCK) | ||
| 610 | return; | ||
| 611 | |||
| 608 | clk_disable_unprepare(afe_priv->clk[div_clk_id]); | 612 | clk_disable_unprepare(afe_priv->clk[div_clk_id]); |
| 609 | if (m_sel_id >= 0) | 613 | if (m_sel_id >= 0) |
| 610 | clk_disable_unprepare(afe_priv->clk[m_sel_id]); | 614 | clk_disable_unprepare(afe_priv->clk[m_sel_id]); |
diff --git a/sound/soc/rockchip/rockchip_pdm.c b/sound/soc/rockchip/rockchip_pdm.c index 400e29edb1c9..d0b403a0e27b 100644 --- a/sound/soc/rockchip/rockchip_pdm.c +++ b/sound/soc/rockchip/rockchip_pdm.c | |||
| @@ -24,7 +24,7 @@ | |||
| 24 | 24 | ||
| 25 | #include "rockchip_pdm.h" | 25 | #include "rockchip_pdm.h" |
| 26 | 26 | ||
| 27 | #define PDM_DMA_BURST_SIZE (16) /* size * width: 16*4 = 64 bytes */ | 27 | #define PDM_DMA_BURST_SIZE (8) /* size * width: 8*4 = 32 bytes */ |
| 28 | 28 | ||
| 29 | struct rk_pdm_dev { | 29 | struct rk_pdm_dev { |
| 30 | struct device *dev; | 30 | struct device *dev; |
| @@ -208,7 +208,9 @@ static int rockchip_pdm_set_fmt(struct snd_soc_dai *cpu_dai, | |||
| 208 | return -EINVAL; | 208 | return -EINVAL; |
| 209 | } | 209 | } |
| 210 | 210 | ||
| 211 | pm_runtime_get_sync(cpu_dai->dev); | ||
| 211 | regmap_update_bits(pdm->regmap, PDM_CLK_CTRL, mask, val); | 212 | regmap_update_bits(pdm->regmap, PDM_CLK_CTRL, mask, val); |
| 213 | pm_runtime_put(cpu_dai->dev); | ||
| 212 | 214 | ||
| 213 | return 0; | 215 | return 0; |
| 214 | } | 216 | } |
diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c index 4231001226f4..ab471d550d17 100644 --- a/sound/soc/samsung/i2s.c +++ b/sound/soc/samsung/i2s.c | |||
| @@ -1130,11 +1130,11 @@ static const struct snd_soc_dapm_widget samsung_i2s_widgets[] = { | |||
| 1130 | }; | 1130 | }; |
| 1131 | 1131 | ||
| 1132 | static const struct snd_soc_dapm_route samsung_i2s_dapm_routes[] = { | 1132 | static const struct snd_soc_dapm_route samsung_i2s_dapm_routes[] = { |
| 1133 | { "Playback Mixer", NULL, "Primary" }, | 1133 | { "Playback Mixer", NULL, "Primary Playback" }, |
| 1134 | { "Playback Mixer", NULL, "Secondary" }, | 1134 | { "Playback Mixer", NULL, "Secondary Playback" }, |
| 1135 | 1135 | ||
| 1136 | { "Mixer DAI TX", NULL, "Playback Mixer" }, | 1136 | { "Mixer DAI TX", NULL, "Playback Mixer" }, |
| 1137 | { "Playback Mixer", NULL, "Mixer DAI RX" }, | 1137 | { "Primary Capture", NULL, "Mixer DAI RX" }, |
| 1138 | }; | 1138 | }; |
| 1139 | 1139 | ||
| 1140 | static const struct snd_soc_component_driver samsung_i2s_component = { | 1140 | static const struct snd_soc_component_driver samsung_i2s_component = { |
| @@ -1155,7 +1155,8 @@ static int i2s_alloc_dais(struct samsung_i2s_priv *priv, | |||
| 1155 | int num_dais) | 1155 | int num_dais) |
| 1156 | { | 1156 | { |
| 1157 | static const char *dai_names[] = { "samsung-i2s", "samsung-i2s-sec" }; | 1157 | static const char *dai_names[] = { "samsung-i2s", "samsung-i2s-sec" }; |
| 1158 | static const char *stream_names[] = { "Primary", "Secondary" }; | 1158 | static const char *stream_names[] = { "Primary Playback", |
| 1159 | "Secondary Playback" }; | ||
| 1159 | struct snd_soc_dai_driver *dai_drv; | 1160 | struct snd_soc_dai_driver *dai_drv; |
| 1160 | struct i2s_dai *dai; | 1161 | struct i2s_dai *dai; |
| 1161 | int i; | 1162 | int i; |
| @@ -1201,6 +1202,7 @@ static int i2s_alloc_dais(struct samsung_i2s_priv *priv, | |||
| 1201 | dai_drv->capture.channels_max = 2; | 1202 | dai_drv->capture.channels_max = 2; |
| 1202 | dai_drv->capture.rates = i2s_dai_data->pcm_rates; | 1203 | dai_drv->capture.rates = i2s_dai_data->pcm_rates; |
| 1203 | dai_drv->capture.formats = SAMSUNG_I2S_FMTS; | 1204 | dai_drv->capture.formats = SAMSUNG_I2S_FMTS; |
| 1205 | dai_drv->capture.stream_name = "Primary Capture"; | ||
| 1204 | 1206 | ||
| 1205 | return 0; | 1207 | return 0; |
| 1206 | } | 1208 | } |
diff --git a/sound/soc/samsung/odroid.c b/sound/soc/samsung/odroid.c index 694512f980fd..1dc54c4206f0 100644 --- a/sound/soc/samsung/odroid.c +++ b/sound/soc/samsung/odroid.c | |||
| @@ -91,11 +91,11 @@ static int odroid_card_be_hw_params(struct snd_pcm_substream *substream, | |||
| 91 | return ret; | 91 | return ret; |
| 92 | 92 | ||
| 93 | /* | 93 | /* |
| 94 | * We add 1 to the rclk_freq value in order to avoid too low clock | 94 | * We add 2 to the rclk_freq value in order to avoid too low clock |
| 95 | * frequency values due to the EPLL output frequency not being exact | 95 | * frequency values due to the EPLL output frequency not being exact |
| 96 | * multiple of the audio sampling rate. | 96 | * multiple of the audio sampling rate. |
| 97 | */ | 97 | */ |
| 98 | rclk_freq = params_rate(params) * rfs + 1; | 98 | rclk_freq = params_rate(params) * rfs + 2; |
| 99 | 99 | ||
| 100 | ret = clk_set_rate(priv->sclk_i2s, rclk_freq); | 100 | ret = clk_set_rate(priv->sclk_i2s, rclk_freq); |
| 101 | if (ret < 0) | 101 | if (ret < 0) |
diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index 022996d2db13..4fe83e611c01 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c | |||
| @@ -110,6 +110,8 @@ static const struct of_device_id rsnd_of_match[] = { | |||
| 110 | { .compatible = "renesas,rcar_sound-gen1", .data = (void *)RSND_GEN1 }, | 110 | { .compatible = "renesas,rcar_sound-gen1", .data = (void *)RSND_GEN1 }, |
| 111 | { .compatible = "renesas,rcar_sound-gen2", .data = (void *)RSND_GEN2 }, | 111 | { .compatible = "renesas,rcar_sound-gen2", .data = (void *)RSND_GEN2 }, |
| 112 | { .compatible = "renesas,rcar_sound-gen3", .data = (void *)RSND_GEN3 }, | 112 | { .compatible = "renesas,rcar_sound-gen3", .data = (void *)RSND_GEN3 }, |
| 113 | /* Special Handling */ | ||
| 114 | { .compatible = "renesas,rcar_sound-r8a77990", .data = (void *)(RSND_GEN3 | RSND_SOC_E) }, | ||
| 113 | {}, | 115 | {}, |
| 114 | }; | 116 | }; |
| 115 | MODULE_DEVICE_TABLE(of, rsnd_of_match); | 117 | MODULE_DEVICE_TABLE(of, rsnd_of_match); |
diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index 90625c57847b..0e6ef4e18400 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h | |||
| @@ -607,6 +607,8 @@ struct rsnd_priv { | |||
| 607 | #define RSND_GEN1 (1 << 0) | 607 | #define RSND_GEN1 (1 << 0) |
| 608 | #define RSND_GEN2 (2 << 0) | 608 | #define RSND_GEN2 (2 << 0) |
| 609 | #define RSND_GEN3 (3 << 0) | 609 | #define RSND_GEN3 (3 << 0) |
| 610 | #define RSND_SOC_MASK (0xFF << 4) | ||
| 611 | #define RSND_SOC_E (1 << 4) /* E1/E2/E3 */ | ||
| 610 | 612 | ||
| 611 | /* | 613 | /* |
| 612 | * below value will be filled on rsnd_gen_probe() | 614 | * below value will be filled on rsnd_gen_probe() |
| @@ -679,6 +681,9 @@ struct rsnd_priv { | |||
| 679 | #define rsnd_is_gen1(priv) (((priv)->flags & RSND_GEN_MASK) == RSND_GEN1) | 681 | #define rsnd_is_gen1(priv) (((priv)->flags & RSND_GEN_MASK) == RSND_GEN1) |
| 680 | #define rsnd_is_gen2(priv) (((priv)->flags & RSND_GEN_MASK) == RSND_GEN2) | 682 | #define rsnd_is_gen2(priv) (((priv)->flags & RSND_GEN_MASK) == RSND_GEN2) |
| 681 | #define rsnd_is_gen3(priv) (((priv)->flags & RSND_GEN_MASK) == RSND_GEN3) | 683 | #define rsnd_is_gen3(priv) (((priv)->flags & RSND_GEN_MASK) == RSND_GEN3) |
| 684 | #define rsnd_is_e3(priv) (((priv)->flags & \ | ||
| 685 | (RSND_GEN_MASK | RSND_SOC_MASK)) == \ | ||
| 686 | (RSND_GEN3 | RSND_SOC_E)) | ||
| 682 | 687 | ||
| 683 | #define rsnd_flags_has(p, f) ((p)->flags & (f)) | 688 | #define rsnd_flags_has(p, f) ((p)->flags & (f)) |
| 684 | #define rsnd_flags_set(p, f) ((p)->flags |= (f)) | 689 | #define rsnd_flags_set(p, f) ((p)->flags |= (f)) |
diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c index db81e066b92e..585ffba0244b 100644 --- a/sound/soc/sh/rcar/src.c +++ b/sound/soc/sh/rcar/src.c | |||
| @@ -14,7 +14,6 @@ | |||
| 14 | */ | 14 | */ |
| 15 | 15 | ||
| 16 | #include "rsnd.h" | 16 | #include "rsnd.h" |
| 17 | #include <linux/sys_soc.h> | ||
| 18 | 17 | ||
| 19 | #define SRC_NAME "src" | 18 | #define SRC_NAME "src" |
| 20 | 19 | ||
| @@ -135,7 +134,7 @@ unsigned int rsnd_src_get_rate(struct rsnd_priv *priv, | |||
| 135 | return rate; | 134 | return rate; |
| 136 | } | 135 | } |
| 137 | 136 | ||
| 138 | const static u32 bsdsr_table_pattern1[] = { | 137 | static const u32 bsdsr_table_pattern1[] = { |
| 139 | 0x01800000, /* 6 - 1/6 */ | 138 | 0x01800000, /* 6 - 1/6 */ |
| 140 | 0x01000000, /* 6 - 1/4 */ | 139 | 0x01000000, /* 6 - 1/4 */ |
| 141 | 0x00c00000, /* 6 - 1/3 */ | 140 | 0x00c00000, /* 6 - 1/3 */ |
| @@ -144,7 +143,7 @@ const static u32 bsdsr_table_pattern1[] = { | |||
| 144 | 0x00400000, /* 6 - 1 */ | 143 | 0x00400000, /* 6 - 1 */ |
| 145 | }; | 144 | }; |
| 146 | 145 | ||
| 147 | const static u32 bsdsr_table_pattern2[] = { | 146 | static const u32 bsdsr_table_pattern2[] = { |
| 148 | 0x02400000, /* 6 - 1/6 */ | 147 | 0x02400000, /* 6 - 1/6 */ |
| 149 | 0x01800000, /* 6 - 1/4 */ | 148 | 0x01800000, /* 6 - 1/4 */ |
| 150 | 0x01200000, /* 6 - 1/3 */ | 149 | 0x01200000, /* 6 - 1/3 */ |
| @@ -153,7 +152,7 @@ const static u32 bsdsr_table_pattern2[] = { | |||
| 153 | 0x00600000, /* 6 - 1 */ | 152 | 0x00600000, /* 6 - 1 */ |
| 154 | }; | 153 | }; |
| 155 | 154 | ||
| 156 | const static u32 bsisr_table[] = { | 155 | static const u32 bsisr_table[] = { |
| 157 | 0x00100060, /* 6 - 1/6 */ | 156 | 0x00100060, /* 6 - 1/6 */ |
| 158 | 0x00100040, /* 6 - 1/4 */ | 157 | 0x00100040, /* 6 - 1/4 */ |
| 159 | 0x00100030, /* 6 - 1/3 */ | 158 | 0x00100030, /* 6 - 1/3 */ |
| @@ -162,7 +161,7 @@ const static u32 bsisr_table[] = { | |||
| 162 | 0x00100020, /* 6 - 1 */ | 161 | 0x00100020, /* 6 - 1 */ |
| 163 | }; | 162 | }; |
| 164 | 163 | ||
| 165 | const static u32 chan288888[] = { | 164 | static const u32 chan288888[] = { |
| 166 | 0x00000006, /* 1 to 2 */ | 165 | 0x00000006, /* 1 to 2 */ |
| 167 | 0x000001fe, /* 1 to 8 */ | 166 | 0x000001fe, /* 1 to 8 */ |
| 168 | 0x000001fe, /* 1 to 8 */ | 167 | 0x000001fe, /* 1 to 8 */ |
| @@ -171,7 +170,7 @@ const static u32 chan288888[] = { | |||
| 171 | 0x000001fe, /* 1 to 8 */ | 170 | 0x000001fe, /* 1 to 8 */ |
| 172 | }; | 171 | }; |
| 173 | 172 | ||
| 174 | const static u32 chan244888[] = { | 173 | static const u32 chan244888[] = { |
| 175 | 0x00000006, /* 1 to 2 */ | 174 | 0x00000006, /* 1 to 2 */ |
| 176 | 0x0000001e, /* 1 to 4 */ | 175 | 0x0000001e, /* 1 to 4 */ |
| 177 | 0x0000001e, /* 1 to 4 */ | 176 | 0x0000001e, /* 1 to 4 */ |
| @@ -180,7 +179,7 @@ const static u32 chan244888[] = { | |||
| 180 | 0x000001fe, /* 1 to 8 */ | 179 | 0x000001fe, /* 1 to 8 */ |
| 181 | }; | 180 | }; |
| 182 | 181 | ||
| 183 | const static u32 chan222222[] = { | 182 | static const u32 chan222222[] = { |
| 184 | 0x00000006, /* 1 to 2 */ | 183 | 0x00000006, /* 1 to 2 */ |
| 185 | 0x00000006, /* 1 to 2 */ | 184 | 0x00000006, /* 1 to 2 */ |
| 186 | 0x00000006, /* 1 to 2 */ | 185 | 0x00000006, /* 1 to 2 */ |
| @@ -189,18 +188,12 @@ const static u32 chan222222[] = { | |||
| 189 | 0x00000006, /* 1 to 2 */ | 188 | 0x00000006, /* 1 to 2 */ |
| 190 | }; | 189 | }; |
| 191 | 190 | ||
| 192 | static const struct soc_device_attribute ov_soc[] = { | ||
| 193 | { .soc_id = "r8a77990" }, /* E3 */ | ||
| 194 | { /* sentinel */ } | ||
| 195 | }; | ||
| 196 | |||
| 197 | static void rsnd_src_set_convert_rate(struct rsnd_dai_stream *io, | 191 | static void rsnd_src_set_convert_rate(struct rsnd_dai_stream *io, |
| 198 | struct rsnd_mod *mod) | 192 | struct rsnd_mod *mod) |
| 199 | { | 193 | { |
| 200 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); | 194 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); |
| 201 | struct device *dev = rsnd_priv_to_dev(priv); | 195 | struct device *dev = rsnd_priv_to_dev(priv); |
| 202 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); | 196 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); |
| 203 | const struct soc_device_attribute *soc = soc_device_match(ov_soc); | ||
| 204 | int is_play = rsnd_io_is_play(io); | 197 | int is_play = rsnd_io_is_play(io); |
| 205 | int use_src = 0; | 198 | int use_src = 0; |
| 206 | u32 fin, fout; | 199 | u32 fin, fout; |
| @@ -307,7 +300,7 @@ static void rsnd_src_set_convert_rate(struct rsnd_dai_stream *io, | |||
| 307 | /* | 300 | /* |
| 308 | * E3 need to overwrite | 301 | * E3 need to overwrite |
| 309 | */ | 302 | */ |
| 310 | if (soc) | 303 | if (rsnd_is_e3(priv)) |
| 311 | switch (rsnd_mod_id(mod)) { | 304 | switch (rsnd_mod_id(mod)) { |
| 312 | case 0: | 305 | case 0: |
| 313 | case 4: | 306 | case 4: |
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 93d316d5bf8e..46e3ab0fced4 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c | |||
| @@ -947,7 +947,7 @@ static void soc_cleanup_component(struct snd_soc_component *component) | |||
| 947 | snd_soc_dapm_free(snd_soc_component_get_dapm(component)); | 947 | snd_soc_dapm_free(snd_soc_component_get_dapm(component)); |
| 948 | soc_cleanup_component_debugfs(component); | 948 | soc_cleanup_component_debugfs(component); |
| 949 | component->card = NULL; | 949 | component->card = NULL; |
| 950 | if (!component->driver->ignore_module_refcount) | 950 | if (!component->driver->module_get_upon_open) |
| 951 | module_put(component->dev->driver->owner); | 951 | module_put(component->dev->driver->owner); |
| 952 | } | 952 | } |
| 953 | 953 | ||
| @@ -1381,7 +1381,7 @@ static int soc_probe_component(struct snd_soc_card *card, | |||
| 1381 | return 0; | 1381 | return 0; |
| 1382 | } | 1382 | } |
| 1383 | 1383 | ||
| 1384 | if (!component->driver->ignore_module_refcount && | 1384 | if (!component->driver->module_get_upon_open && |
| 1385 | !try_module_get(component->dev->driver->owner)) | 1385 | !try_module_get(component->dev->driver->owner)) |
| 1386 | return -ENODEV; | 1386 | return -ENODEV; |
| 1387 | 1387 | ||
| @@ -2797,6 +2797,7 @@ int snd_soc_register_card(struct snd_soc_card *card) | |||
| 2797 | 2797 | ||
| 2798 | ret = soc_init_dai_link(card, link); | 2798 | ret = soc_init_dai_link(card, link); |
| 2799 | if (ret) { | 2799 | if (ret) { |
| 2800 | soc_cleanup_platform(card); | ||
| 2800 | dev_err(card->dev, "ASoC: failed to init link %s\n", | 2801 | dev_err(card->dev, "ASoC: failed to init link %s\n", |
| 2801 | link->name); | 2802 | link->name); |
| 2802 | mutex_unlock(&client_mutex); | 2803 | mutex_unlock(&client_mutex); |
| @@ -2819,6 +2820,7 @@ int snd_soc_register_card(struct snd_soc_card *card) | |||
| 2819 | card->instantiated = 0; | 2820 | card->instantiated = 0; |
| 2820 | mutex_init(&card->mutex); | 2821 | mutex_init(&card->mutex); |
| 2821 | mutex_init(&card->dapm_mutex); | 2822 | mutex_init(&card->dapm_mutex); |
| 2823 | spin_lock_init(&card->dpcm_lock); | ||
| 2822 | 2824 | ||
| 2823 | return snd_soc_bind_card(card); | 2825 | return snd_soc_bind_card(card); |
| 2824 | } | 2826 | } |
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 1ec06ef6d161..0382a47b30bd 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c | |||
| @@ -3650,6 +3650,13 @@ snd_soc_dapm_new_control_unlocked(struct snd_soc_dapm_context *dapm, | |||
| 3650 | case snd_soc_dapm_dac: | 3650 | case snd_soc_dapm_dac: |
| 3651 | case snd_soc_dapm_aif_in: | 3651 | case snd_soc_dapm_aif_in: |
| 3652 | case snd_soc_dapm_pga: | 3652 | case snd_soc_dapm_pga: |
| 3653 | case snd_soc_dapm_buffer: | ||
| 3654 | case snd_soc_dapm_scheduler: | ||
| 3655 | case snd_soc_dapm_effect: | ||
| 3656 | case snd_soc_dapm_src: | ||
| 3657 | case snd_soc_dapm_asrc: | ||
| 3658 | case snd_soc_dapm_encoder: | ||
| 3659 | case snd_soc_dapm_decoder: | ||
| 3653 | case snd_soc_dapm_out_drv: | 3660 | case snd_soc_dapm_out_drv: |
| 3654 | case snd_soc_dapm_micbias: | 3661 | case snd_soc_dapm_micbias: |
| 3655 | case snd_soc_dapm_line: | 3662 | case snd_soc_dapm_line: |
| @@ -3957,6 +3964,10 @@ snd_soc_dapm_free_kcontrol(struct snd_soc_card *card, | |||
| 3957 | int count; | 3964 | int count; |
| 3958 | 3965 | ||
| 3959 | devm_kfree(card->dev, (void *)*private_value); | 3966 | devm_kfree(card->dev, (void *)*private_value); |
| 3967 | |||
| 3968 | if (!w_param_text) | ||
| 3969 | return; | ||
| 3970 | |||
| 3960 | for (count = 0 ; count < num_params; count++) | 3971 | for (count = 0 ; count < num_params; count++) |
| 3961 | devm_kfree(card->dev, (void *)w_param_text[count]); | 3972 | devm_kfree(card->dev, (void *)w_param_text[count]); |
| 3962 | devm_kfree(card->dev, w_param_text); | 3973 | devm_kfree(card->dev, w_param_text); |
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index 0d5ec68a1e50..be80a12fba27 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c | |||
| @@ -15,6 +15,7 @@ | |||
| 15 | #include <linux/delay.h> | 15 | #include <linux/delay.h> |
| 16 | #include <linux/pinctrl/consumer.h> | 16 | #include <linux/pinctrl/consumer.h> |
| 17 | #include <linux/pm_runtime.h> | 17 | #include <linux/pm_runtime.h> |
| 18 | #include <linux/module.h> | ||
| 18 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
| 19 | #include <linux/workqueue.h> | 20 | #include <linux/workqueue.h> |
| 20 | #include <linux/export.h> | 21 | #include <linux/export.h> |
| @@ -463,6 +464,9 @@ static int soc_pcm_components_close(struct snd_pcm_substream *substream, | |||
| 463 | continue; | 464 | continue; |
| 464 | 465 | ||
| 465 | component->driver->ops->close(substream); | 466 | component->driver->ops->close(substream); |
| 467 | |||
| 468 | if (component->driver->module_get_upon_open) | ||
| 469 | module_put(component->dev->driver->owner); | ||
| 466 | } | 470 | } |
| 467 | 471 | ||
| 468 | return 0; | 472 | return 0; |
| @@ -513,6 +517,12 @@ static int soc_pcm_open(struct snd_pcm_substream *substream) | |||
| 513 | !component->driver->ops->open) | 517 | !component->driver->ops->open) |
| 514 | continue; | 518 | continue; |
| 515 | 519 | ||
| 520 | if (component->driver->module_get_upon_open && | ||
| 521 | !try_module_get(component->dev->driver->owner)) { | ||
| 522 | ret = -ENODEV; | ||
| 523 | goto module_err; | ||
| 524 | } | ||
| 525 | |||
| 516 | ret = component->driver->ops->open(substream); | 526 | ret = component->driver->ops->open(substream); |
| 517 | if (ret < 0) { | 527 | if (ret < 0) { |
| 518 | dev_err(component->dev, | 528 | dev_err(component->dev, |
| @@ -628,7 +638,7 @@ codec_dai_err: | |||
| 628 | 638 | ||
| 629 | component_err: | 639 | component_err: |
| 630 | soc_pcm_components_close(substream, component); | 640 | soc_pcm_components_close(substream, component); |
| 631 | 641 | module_err: | |
| 632 | if (cpu_dai->driver->ops->shutdown) | 642 | if (cpu_dai->driver->ops->shutdown) |
| 633 | cpu_dai->driver->ops->shutdown(substream, cpu_dai); | 643 | cpu_dai->driver->ops->shutdown(substream, cpu_dai); |
| 634 | out: | 644 | out: |
| @@ -954,10 +964,13 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream, | |||
| 954 | codec_params = *params; | 964 | codec_params = *params; |
| 955 | 965 | ||
| 956 | /* fixup params based on TDM slot masks */ | 966 | /* fixup params based on TDM slot masks */ |
| 957 | if (codec_dai->tx_mask) | 967 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && |
| 968 | codec_dai->tx_mask) | ||
| 958 | soc_pcm_codec_params_fixup(&codec_params, | 969 | soc_pcm_codec_params_fixup(&codec_params, |
| 959 | codec_dai->tx_mask); | 970 | codec_dai->tx_mask); |
| 960 | if (codec_dai->rx_mask) | 971 | |
| 972 | if (substream->stream == SNDRV_PCM_STREAM_CAPTURE && | ||
| 973 | codec_dai->rx_mask) | ||
| 961 | soc_pcm_codec_params_fixup(&codec_params, | 974 | soc_pcm_codec_params_fixup(&codec_params, |
| 962 | codec_dai->rx_mask); | 975 | codec_dai->rx_mask); |
| 963 | 976 | ||
| @@ -1213,6 +1226,7 @@ static int dpcm_be_connect(struct snd_soc_pcm_runtime *fe, | |||
| 1213 | struct snd_soc_pcm_runtime *be, int stream) | 1226 | struct snd_soc_pcm_runtime *be, int stream) |
| 1214 | { | 1227 | { |
| 1215 | struct snd_soc_dpcm *dpcm; | 1228 | struct snd_soc_dpcm *dpcm; |
| 1229 | unsigned long flags; | ||
| 1216 | 1230 | ||
| 1217 | /* only add new dpcms */ | 1231 | /* only add new dpcms */ |
| 1218 | for_each_dpcm_be(fe, stream, dpcm) { | 1232 | for_each_dpcm_be(fe, stream, dpcm) { |
| @@ -1228,8 +1242,10 @@ static int dpcm_be_connect(struct snd_soc_pcm_runtime *fe, | |||
| 1228 | dpcm->fe = fe; | 1242 | dpcm->fe = fe; |
| 1229 | be->dpcm[stream].runtime = fe->dpcm[stream].runtime; | 1243 | be->dpcm[stream].runtime = fe->dpcm[stream].runtime; |
| 1230 | dpcm->state = SND_SOC_DPCM_LINK_STATE_NEW; | 1244 | dpcm->state = SND_SOC_DPCM_LINK_STATE_NEW; |
| 1245 | spin_lock_irqsave(&fe->card->dpcm_lock, flags); | ||
| 1231 | list_add(&dpcm->list_be, &fe->dpcm[stream].be_clients); | 1246 | list_add(&dpcm->list_be, &fe->dpcm[stream].be_clients); |
| 1232 | list_add(&dpcm->list_fe, &be->dpcm[stream].fe_clients); | 1247 | list_add(&dpcm->list_fe, &be->dpcm[stream].fe_clients); |
| 1248 | spin_unlock_irqrestore(&fe->card->dpcm_lock, flags); | ||
| 1233 | 1249 | ||
| 1234 | dev_dbg(fe->dev, "connected new DPCM %s path %s %s %s\n", | 1250 | dev_dbg(fe->dev, "connected new DPCM %s path %s %s %s\n", |
| 1235 | stream ? "capture" : "playback", fe->dai_link->name, | 1251 | stream ? "capture" : "playback", fe->dai_link->name, |
| @@ -1275,6 +1291,7 @@ static void dpcm_be_reparent(struct snd_soc_pcm_runtime *fe, | |||
| 1275 | void dpcm_be_disconnect(struct snd_soc_pcm_runtime *fe, int stream) | 1291 | void dpcm_be_disconnect(struct snd_soc_pcm_runtime *fe, int stream) |
| 1276 | { | 1292 | { |
| 1277 | struct snd_soc_dpcm *dpcm, *d; | 1293 | struct snd_soc_dpcm *dpcm, *d; |
| 1294 | unsigned long flags; | ||
| 1278 | 1295 | ||
| 1279 | for_each_dpcm_be_safe(fe, stream, dpcm, d) { | 1296 | for_each_dpcm_be_safe(fe, stream, dpcm, d) { |
| 1280 | dev_dbg(fe->dev, "ASoC: BE %s disconnect check for %s\n", | 1297 | dev_dbg(fe->dev, "ASoC: BE %s disconnect check for %s\n", |
| @@ -1294,8 +1311,10 @@ void dpcm_be_disconnect(struct snd_soc_pcm_runtime *fe, int stream) | |||
| 1294 | #ifdef CONFIG_DEBUG_FS | 1311 | #ifdef CONFIG_DEBUG_FS |
| 1295 | debugfs_remove(dpcm->debugfs_state); | 1312 | debugfs_remove(dpcm->debugfs_state); |
| 1296 | #endif | 1313 | #endif |
| 1314 | spin_lock_irqsave(&fe->card->dpcm_lock, flags); | ||
| 1297 | list_del(&dpcm->list_be); | 1315 | list_del(&dpcm->list_be); |
| 1298 | list_del(&dpcm->list_fe); | 1316 | list_del(&dpcm->list_fe); |
| 1317 | spin_unlock_irqrestore(&fe->card->dpcm_lock, flags); | ||
| 1299 | kfree(dpcm); | 1318 | kfree(dpcm); |
| 1300 | } | 1319 | } |
| 1301 | } | 1320 | } |
| @@ -1547,10 +1566,13 @@ int dpcm_process_paths(struct snd_soc_pcm_runtime *fe, | |||
| 1547 | void dpcm_clear_pending_state(struct snd_soc_pcm_runtime *fe, int stream) | 1566 | void dpcm_clear_pending_state(struct snd_soc_pcm_runtime *fe, int stream) |
| 1548 | { | 1567 | { |
| 1549 | struct snd_soc_dpcm *dpcm; | 1568 | struct snd_soc_dpcm *dpcm; |
| 1569 | unsigned long flags; | ||
| 1550 | 1570 | ||
| 1571 | spin_lock_irqsave(&fe->card->dpcm_lock, flags); | ||
| 1551 | for_each_dpcm_be(fe, stream, dpcm) | 1572 | for_each_dpcm_be(fe, stream, dpcm) |
| 1552 | dpcm->be->dpcm[stream].runtime_update = | 1573 | dpcm->be->dpcm[stream].runtime_update = |
| 1553 | SND_SOC_DPCM_UPDATE_NO; | 1574 | SND_SOC_DPCM_UPDATE_NO; |
| 1575 | spin_unlock_irqrestore(&fe->card->dpcm_lock, flags); | ||
| 1554 | } | 1576 | } |
| 1555 | 1577 | ||
| 1556 | static void dpcm_be_dai_startup_unwind(struct snd_soc_pcm_runtime *fe, | 1578 | static void dpcm_be_dai_startup_unwind(struct snd_soc_pcm_runtime *fe, |
| @@ -1899,10 +1921,15 @@ static int dpcm_apply_symmetry(struct snd_pcm_substream *fe_substream, | |||
| 1899 | struct snd_soc_pcm_runtime *be = dpcm->be; | 1921 | struct snd_soc_pcm_runtime *be = dpcm->be; |
| 1900 | struct snd_pcm_substream *be_substream = | 1922 | struct snd_pcm_substream *be_substream = |
| 1901 | snd_soc_dpcm_get_substream(be, stream); | 1923 | snd_soc_dpcm_get_substream(be, stream); |
| 1902 | struct snd_soc_pcm_runtime *rtd = be_substream->private_data; | 1924 | struct snd_soc_pcm_runtime *rtd; |
| 1903 | struct snd_soc_dai *codec_dai; | 1925 | struct snd_soc_dai *codec_dai; |
| 1904 | int i; | 1926 | int i; |
| 1905 | 1927 | ||
| 1928 | /* A backend may not have the requested substream */ | ||
| 1929 | if (!be_substream) | ||
| 1930 | continue; | ||
| 1931 | |||
| 1932 | rtd = be_substream->private_data; | ||
| 1906 | if (rtd->dai_link->be_hw_params_fixup) | 1933 | if (rtd->dai_link->be_hw_params_fixup) |
| 1907 | continue; | 1934 | continue; |
| 1908 | 1935 | ||
| @@ -2571,6 +2598,7 @@ static int dpcm_run_update_startup(struct snd_soc_pcm_runtime *fe, int stream) | |||
| 2571 | struct snd_soc_dpcm *dpcm; | 2598 | struct snd_soc_dpcm *dpcm; |
| 2572 | enum snd_soc_dpcm_trigger trigger = fe->dai_link->trigger[stream]; | 2599 | enum snd_soc_dpcm_trigger trigger = fe->dai_link->trigger[stream]; |
| 2573 | int ret; | 2600 | int ret; |
| 2601 | unsigned long flags; | ||
| 2574 | 2602 | ||
| 2575 | dev_dbg(fe->dev, "ASoC: runtime %s open on FE %s\n", | 2603 | dev_dbg(fe->dev, "ASoC: runtime %s open on FE %s\n", |
| 2576 | stream ? "capture" : "playback", fe->dai_link->name); | 2604 | stream ? "capture" : "playback", fe->dai_link->name); |
| @@ -2640,11 +2668,13 @@ close: | |||
| 2640 | dpcm_be_dai_shutdown(fe, stream); | 2668 | dpcm_be_dai_shutdown(fe, stream); |
| 2641 | disconnect: | 2669 | disconnect: |
| 2642 | /* disconnect any non started BEs */ | 2670 | /* disconnect any non started BEs */ |
| 2671 | spin_lock_irqsave(&fe->card->dpcm_lock, flags); | ||
| 2643 | for_each_dpcm_be(fe, stream, dpcm) { | 2672 | for_each_dpcm_be(fe, stream, dpcm) { |
| 2644 | struct snd_soc_pcm_runtime *be = dpcm->be; | 2673 | struct snd_soc_pcm_runtime *be = dpcm->be; |
| 2645 | if (be->dpcm[stream].state != SND_SOC_DPCM_STATE_START) | 2674 | if (be->dpcm[stream].state != SND_SOC_DPCM_STATE_START) |
| 2646 | dpcm->state = SND_SOC_DPCM_LINK_STATE_FREE; | 2675 | dpcm->state = SND_SOC_DPCM_LINK_STATE_FREE; |
| 2647 | } | 2676 | } |
| 2677 | spin_unlock_irqrestore(&fe->card->dpcm_lock, flags); | ||
| 2648 | 2678 | ||
| 2649 | return ret; | 2679 | return ret; |
| 2650 | } | 2680 | } |
| @@ -3221,7 +3251,10 @@ int snd_soc_dpcm_can_be_free_stop(struct snd_soc_pcm_runtime *fe, | |||
| 3221 | { | 3251 | { |
| 3222 | struct snd_soc_dpcm *dpcm; | 3252 | struct snd_soc_dpcm *dpcm; |
| 3223 | int state; | 3253 | int state; |
| 3254 | int ret = 1; | ||
| 3255 | unsigned long flags; | ||
| 3224 | 3256 | ||
| 3257 | spin_lock_irqsave(&fe->card->dpcm_lock, flags); | ||
| 3225 | for_each_dpcm_fe(be, stream, dpcm) { | 3258 | for_each_dpcm_fe(be, stream, dpcm) { |
| 3226 | 3259 | ||
| 3227 | if (dpcm->fe == fe) | 3260 | if (dpcm->fe == fe) |
| @@ -3230,12 +3263,15 @@ int snd_soc_dpcm_can_be_free_stop(struct snd_soc_pcm_runtime *fe, | |||
| 3230 | state = dpcm->fe->dpcm[stream].state; | 3263 | state = dpcm->fe->dpcm[stream].state; |
| 3231 | if (state == SND_SOC_DPCM_STATE_START || | 3264 | if (state == SND_SOC_DPCM_STATE_START || |
| 3232 | state == SND_SOC_DPCM_STATE_PAUSED || | 3265 | state == SND_SOC_DPCM_STATE_PAUSED || |
| 3233 | state == SND_SOC_DPCM_STATE_SUSPEND) | 3266 | state == SND_SOC_DPCM_STATE_SUSPEND) { |
| 3234 | return 0; | 3267 | ret = 0; |
| 3268 | break; | ||
| 3269 | } | ||
| 3235 | } | 3270 | } |
| 3271 | spin_unlock_irqrestore(&fe->card->dpcm_lock, flags); | ||
| 3236 | 3272 | ||
| 3237 | /* it's safe to free/stop this BE DAI */ | 3273 | /* it's safe to free/stop this BE DAI */ |
| 3238 | return 1; | 3274 | return ret; |
| 3239 | } | 3275 | } |
| 3240 | EXPORT_SYMBOL_GPL(snd_soc_dpcm_can_be_free_stop); | 3276 | EXPORT_SYMBOL_GPL(snd_soc_dpcm_can_be_free_stop); |
| 3241 | 3277 | ||
| @@ -3248,7 +3284,10 @@ int snd_soc_dpcm_can_be_params(struct snd_soc_pcm_runtime *fe, | |||
| 3248 | { | 3284 | { |
| 3249 | struct snd_soc_dpcm *dpcm; | 3285 | struct snd_soc_dpcm *dpcm; |
| 3250 | int state; | 3286 | int state; |
| 3287 | int ret = 1; | ||
| 3288 | unsigned long flags; | ||
| 3251 | 3289 | ||
| 3290 | spin_lock_irqsave(&fe->card->dpcm_lock, flags); | ||
| 3252 | for_each_dpcm_fe(be, stream, dpcm) { | 3291 | for_each_dpcm_fe(be, stream, dpcm) { |
| 3253 | 3292 | ||
| 3254 | if (dpcm->fe == fe) | 3293 | if (dpcm->fe == fe) |
| @@ -3258,12 +3297,15 @@ int snd_soc_dpcm_can_be_params(struct snd_soc_pcm_runtime *fe, | |||
| 3258 | if (state == SND_SOC_DPCM_STATE_START || | 3297 | if (state == SND_SOC_DPCM_STATE_START || |
| 3259 | state == SND_SOC_DPCM_STATE_PAUSED || | 3298 | state == SND_SOC_DPCM_STATE_PAUSED || |
| 3260 | state == SND_SOC_DPCM_STATE_SUSPEND || | 3299 | state == SND_SOC_DPCM_STATE_SUSPEND || |
| 3261 | state == SND_SOC_DPCM_STATE_PREPARE) | 3300 | state == SND_SOC_DPCM_STATE_PREPARE) { |
| 3262 | return 0; | 3301 | ret = 0; |
| 3302 | break; | ||
| 3303 | } | ||
| 3263 | } | 3304 | } |
| 3305 | spin_unlock_irqrestore(&fe->card->dpcm_lock, flags); | ||
| 3264 | 3306 | ||
| 3265 | /* it's safe to change hw_params */ | 3307 | /* it's safe to change hw_params */ |
| 3266 | return 1; | 3308 | return ret; |
| 3267 | } | 3309 | } |
| 3268 | EXPORT_SYMBOL_GPL(snd_soc_dpcm_can_be_params); | 3310 | EXPORT_SYMBOL_GPL(snd_soc_dpcm_can_be_params); |
| 3269 | 3311 | ||
| @@ -3302,6 +3344,7 @@ static ssize_t dpcm_show_state(struct snd_soc_pcm_runtime *fe, | |||
| 3302 | struct snd_pcm_hw_params *params = &fe->dpcm[stream].hw_params; | 3344 | struct snd_pcm_hw_params *params = &fe->dpcm[stream].hw_params; |
| 3303 | struct snd_soc_dpcm *dpcm; | 3345 | struct snd_soc_dpcm *dpcm; |
| 3304 | ssize_t offset = 0; | 3346 | ssize_t offset = 0; |
| 3347 | unsigned long flags; | ||
| 3305 | 3348 | ||
| 3306 | /* FE state */ | 3349 | /* FE state */ |
| 3307 | offset += snprintf(buf + offset, size - offset, | 3350 | offset += snprintf(buf + offset, size - offset, |
| @@ -3329,6 +3372,7 @@ static ssize_t dpcm_show_state(struct snd_soc_pcm_runtime *fe, | |||
| 3329 | goto out; | 3372 | goto out; |
| 3330 | } | 3373 | } |
| 3331 | 3374 | ||
| 3375 | spin_lock_irqsave(&fe->card->dpcm_lock, flags); | ||
| 3332 | for_each_dpcm_be(fe, stream, dpcm) { | 3376 | for_each_dpcm_be(fe, stream, dpcm) { |
| 3333 | struct snd_soc_pcm_runtime *be = dpcm->be; | 3377 | struct snd_soc_pcm_runtime *be = dpcm->be; |
| 3334 | params = &dpcm->hw_params; | 3378 | params = &dpcm->hw_params; |
| @@ -3349,7 +3393,7 @@ static ssize_t dpcm_show_state(struct snd_soc_pcm_runtime *fe, | |||
| 3349 | params_channels(params), | 3393 | params_channels(params), |
| 3350 | params_rate(params)); | 3394 | params_rate(params)); |
| 3351 | } | 3395 | } |
| 3352 | 3396 | spin_unlock_irqrestore(&fe->card->dpcm_lock, flags); | |
| 3353 | out: | 3397 | out: |
| 3354 | return offset; | 3398 | return offset; |
| 3355 | } | 3399 | } |
diff --git a/sound/soc/soc-topology.c b/sound/soc/soc-topology.c index 25fca7055464..96852d250619 100644 --- a/sound/soc/soc-topology.c +++ b/sound/soc/soc-topology.c | |||
| @@ -482,10 +482,11 @@ static void remove_widget(struct snd_soc_component *comp, | |||
| 482 | 482 | ||
| 483 | snd_ctl_remove(card, kcontrol); | 483 | snd_ctl_remove(card, kcontrol); |
| 484 | 484 | ||
| 485 | kfree(dobj->control.dvalues); | 485 | /* free enum kcontrol's dvalues and dtexts */ |
| 486 | kfree(se->dobj.control.dvalues); | ||
| 486 | for (j = 0; j < se->items; j++) | 487 | for (j = 0; j < se->items; j++) |
| 487 | kfree(dobj->control.dtexts[j]); | 488 | kfree(se->dobj.control.dtexts[j]); |
| 488 | kfree(dobj->control.dtexts); | 489 | kfree(se->dobj.control.dtexts); |
| 489 | 490 | ||
| 490 | kfree(se); | 491 | kfree(se); |
| 491 | kfree(w->kcontrol_news[i].name); | 492 | kfree(w->kcontrol_news[i].name); |
diff --git a/sound/soc/stm/stm32_adfsdm.c b/sound/soc/stm/stm32_adfsdm.c index 47901983a6ff..78bed9734713 100644 --- a/sound/soc/stm/stm32_adfsdm.c +++ b/sound/soc/stm/stm32_adfsdm.c | |||
| @@ -9,6 +9,7 @@ | |||
| 9 | 9 | ||
| 10 | #include <linux/clk.h> | 10 | #include <linux/clk.h> |
| 11 | #include <linux/module.h> | 11 | #include <linux/module.h> |
| 12 | #include <linux/mutex.h> | ||
| 12 | #include <linux/platform_device.h> | 13 | #include <linux/platform_device.h> |
| 13 | #include <linux/slab.h> | 14 | #include <linux/slab.h> |
| 14 | 15 | ||
| @@ -37,6 +38,8 @@ struct stm32_adfsdm_priv { | |||
| 37 | /* PCM buffer */ | 38 | /* PCM buffer */ |
| 38 | unsigned char *pcm_buff; | 39 | unsigned char *pcm_buff; |
| 39 | unsigned int pos; | 40 | unsigned int pos; |
| 41 | |||
| 42 | struct mutex lock; /* protect against race condition on iio state */ | ||
| 40 | }; | 43 | }; |
| 41 | 44 | ||
| 42 | static const struct snd_pcm_hardware stm32_adfsdm_pcm_hw = { | 45 | static const struct snd_pcm_hardware stm32_adfsdm_pcm_hw = { |
| @@ -62,10 +65,12 @@ static void stm32_adfsdm_shutdown(struct snd_pcm_substream *substream, | |||
| 62 | { | 65 | { |
| 63 | struct stm32_adfsdm_priv *priv = snd_soc_dai_get_drvdata(dai); | 66 | struct stm32_adfsdm_priv *priv = snd_soc_dai_get_drvdata(dai); |
| 64 | 67 | ||
| 68 | mutex_lock(&priv->lock); | ||
| 65 | if (priv->iio_active) { | 69 | if (priv->iio_active) { |
| 66 | iio_channel_stop_all_cb(priv->iio_cb); | 70 | iio_channel_stop_all_cb(priv->iio_cb); |
| 67 | priv->iio_active = false; | 71 | priv->iio_active = false; |
| 68 | } | 72 | } |
| 73 | mutex_unlock(&priv->lock); | ||
| 69 | } | 74 | } |
| 70 | 75 | ||
| 71 | static int stm32_adfsdm_dai_prepare(struct snd_pcm_substream *substream, | 76 | static int stm32_adfsdm_dai_prepare(struct snd_pcm_substream *substream, |
| @@ -74,13 +79,19 @@ static int stm32_adfsdm_dai_prepare(struct snd_pcm_substream *substream, | |||
| 74 | struct stm32_adfsdm_priv *priv = snd_soc_dai_get_drvdata(dai); | 79 | struct stm32_adfsdm_priv *priv = snd_soc_dai_get_drvdata(dai); |
| 75 | int ret; | 80 | int ret; |
| 76 | 81 | ||
| 82 | mutex_lock(&priv->lock); | ||
| 83 | if (priv->iio_active) { | ||
| 84 | iio_channel_stop_all_cb(priv->iio_cb); | ||
| 85 | priv->iio_active = false; | ||
| 86 | } | ||
| 87 | |||
| 77 | ret = iio_write_channel_attribute(priv->iio_ch, | 88 | ret = iio_write_channel_attribute(priv->iio_ch, |
| 78 | substream->runtime->rate, 0, | 89 | substream->runtime->rate, 0, |
| 79 | IIO_CHAN_INFO_SAMP_FREQ); | 90 | IIO_CHAN_INFO_SAMP_FREQ); |
| 80 | if (ret < 0) { | 91 | if (ret < 0) { |
| 81 | dev_err(dai->dev, "%s: Failed to set %d sampling rate\n", | 92 | dev_err(dai->dev, "%s: Failed to set %d sampling rate\n", |
| 82 | __func__, substream->runtime->rate); | 93 | __func__, substream->runtime->rate); |
| 83 | return ret; | 94 | goto out; |
| 84 | } | 95 | } |
| 85 | 96 | ||
| 86 | if (!priv->iio_active) { | 97 | if (!priv->iio_active) { |
| @@ -92,6 +103,9 @@ static int stm32_adfsdm_dai_prepare(struct snd_pcm_substream *substream, | |||
| 92 | __func__, ret); | 103 | __func__, ret); |
| 93 | } | 104 | } |
| 94 | 105 | ||
| 106 | out: | ||
| 107 | mutex_unlock(&priv->lock); | ||
| 108 | |||
| 95 | return ret; | 109 | return ret; |
| 96 | } | 110 | } |
| 97 | 111 | ||
| @@ -291,6 +305,7 @@ MODULE_DEVICE_TABLE(of, stm32_adfsdm_of_match); | |||
| 291 | static int stm32_adfsdm_probe(struct platform_device *pdev) | 305 | static int stm32_adfsdm_probe(struct platform_device *pdev) |
| 292 | { | 306 | { |
| 293 | struct stm32_adfsdm_priv *priv; | 307 | struct stm32_adfsdm_priv *priv; |
| 308 | struct snd_soc_component *component; | ||
| 294 | int ret; | 309 | int ret; |
| 295 | 310 | ||
| 296 | priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); | 311 | priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); |
| @@ -299,6 +314,7 @@ static int stm32_adfsdm_probe(struct platform_device *pdev) | |||
| 299 | 314 | ||
| 300 | priv->dev = &pdev->dev; | 315 | priv->dev = &pdev->dev; |
| 301 | priv->dai_drv = stm32_adfsdm_dai; | 316 | priv->dai_drv = stm32_adfsdm_dai; |
| 317 | mutex_init(&priv->lock); | ||
| 302 | 318 | ||
| 303 | dev_set_drvdata(&pdev->dev, priv); | 319 | dev_set_drvdata(&pdev->dev, priv); |
| 304 | 320 | ||
| @@ -317,9 +333,15 @@ static int stm32_adfsdm_probe(struct platform_device *pdev) | |||
| 317 | if (IS_ERR(priv->iio_cb)) | 333 | if (IS_ERR(priv->iio_cb)) |
| 318 | return PTR_ERR(priv->iio_cb); | 334 | return PTR_ERR(priv->iio_cb); |
| 319 | 335 | ||
| 320 | ret = devm_snd_soc_register_component(&pdev->dev, | 336 | component = devm_kzalloc(&pdev->dev, sizeof(*component), GFP_KERNEL); |
| 321 | &stm32_adfsdm_soc_platform, | 337 | if (!component) |
| 322 | NULL, 0); | 338 | return -ENOMEM; |
| 339 | #ifdef CONFIG_DEBUG_FS | ||
| 340 | component->debugfs_prefix = "pcm"; | ||
| 341 | #endif | ||
| 342 | |||
| 343 | ret = snd_soc_add_component(&pdev->dev, component, | ||
| 344 | &stm32_adfsdm_soc_platform, NULL, 0); | ||
| 323 | if (ret < 0) | 345 | if (ret < 0) |
| 324 | dev_err(&pdev->dev, "%s: Failed to register PCM platform\n", | 346 | dev_err(&pdev->dev, "%s: Failed to register PCM platform\n", |
| 325 | __func__); | 347 | __func__); |
| @@ -327,12 +349,20 @@ static int stm32_adfsdm_probe(struct platform_device *pdev) | |||
| 327 | return ret; | 349 | return ret; |
| 328 | } | 350 | } |
| 329 | 351 | ||
| 352 | static int stm32_adfsdm_remove(struct platform_device *pdev) | ||
| 353 | { | ||
| 354 | snd_soc_unregister_component(&pdev->dev); | ||
| 355 | |||
| 356 | return 0; | ||
| 357 | } | ||
| 358 | |||
| 330 | static struct platform_driver stm32_adfsdm_driver = { | 359 | static struct platform_driver stm32_adfsdm_driver = { |
| 331 | .driver = { | 360 | .driver = { |
| 332 | .name = STM32_ADFSDM_DRV_NAME, | 361 | .name = STM32_ADFSDM_DRV_NAME, |
| 333 | .of_match_table = stm32_adfsdm_of_match, | 362 | .of_match_table = stm32_adfsdm_of_match, |
| 334 | }, | 363 | }, |
| 335 | .probe = stm32_adfsdm_probe, | 364 | .probe = stm32_adfsdm_probe, |
| 365 | .remove = stm32_adfsdm_remove, | ||
| 336 | }; | 366 | }; |
| 337 | 367 | ||
| 338 | module_platform_driver(stm32_adfsdm_driver); | 368 | module_platform_driver(stm32_adfsdm_driver); |
diff --git a/sound/soc/stm/stm32_i2s.c b/sound/soc/stm/stm32_i2s.c index 47c334de6b09..8968458eec62 100644 --- a/sound/soc/stm/stm32_i2s.c +++ b/sound/soc/stm/stm32_i2s.c | |||
| @@ -281,7 +281,6 @@ static bool stm32_i2s_readable_reg(struct device *dev, unsigned int reg) | |||
| 281 | case STM32_I2S_CFG2_REG: | 281 | case STM32_I2S_CFG2_REG: |
| 282 | case STM32_I2S_IER_REG: | 282 | case STM32_I2S_IER_REG: |
| 283 | case STM32_I2S_SR_REG: | 283 | case STM32_I2S_SR_REG: |
| 284 | case STM32_I2S_TXDR_REG: | ||
| 285 | case STM32_I2S_RXDR_REG: | 284 | case STM32_I2S_RXDR_REG: |
| 286 | case STM32_I2S_CGFR_REG: | 285 | case STM32_I2S_CGFR_REG: |
| 287 | return true; | 286 | return true; |
| @@ -293,7 +292,7 @@ static bool stm32_i2s_readable_reg(struct device *dev, unsigned int reg) | |||
| 293 | static bool stm32_i2s_volatile_reg(struct device *dev, unsigned int reg) | 292 | static bool stm32_i2s_volatile_reg(struct device *dev, unsigned int reg) |
| 294 | { | 293 | { |
| 295 | switch (reg) { | 294 | switch (reg) { |
| 296 | case STM32_I2S_TXDR_REG: | 295 | case STM32_I2S_SR_REG: |
| 297 | case STM32_I2S_RXDR_REG: | 296 | case STM32_I2S_RXDR_REG: |
| 298 | return true; | 297 | return true; |
| 299 | default: | 298 | default: |
diff --git a/sound/soc/stm/stm32_sai.c b/sound/soc/stm/stm32_sai.c index 14c9591aae42..d68d62f12df5 100644 --- a/sound/soc/stm/stm32_sai.c +++ b/sound/soc/stm/stm32_sai.c | |||
| @@ -105,6 +105,7 @@ static int stm32_sai_set_sync(struct stm32_sai_data *sai_client, | |||
| 105 | if (!pdev) { | 105 | if (!pdev) { |
| 106 | dev_err(&sai_client->pdev->dev, | 106 | dev_err(&sai_client->pdev->dev, |
| 107 | "Device not found for node %pOFn\n", np_provider); | 107 | "Device not found for node %pOFn\n", np_provider); |
| 108 | of_node_put(np_provider); | ||
| 108 | return -ENODEV; | 109 | return -ENODEV; |
| 109 | } | 110 | } |
| 110 | 111 | ||
| @@ -113,19 +114,20 @@ static int stm32_sai_set_sync(struct stm32_sai_data *sai_client, | |||
| 113 | dev_err(&sai_client->pdev->dev, | 114 | dev_err(&sai_client->pdev->dev, |
| 114 | "SAI sync provider data not found\n"); | 115 | "SAI sync provider data not found\n"); |
| 115 | ret = -EINVAL; | 116 | ret = -EINVAL; |
| 116 | goto out_put_dev; | 117 | goto error; |
| 117 | } | 118 | } |
| 118 | 119 | ||
| 119 | /* Configure sync client */ | 120 | /* Configure sync client */ |
| 120 | ret = stm32_sai_sync_conf_client(sai_client, synci); | 121 | ret = stm32_sai_sync_conf_client(sai_client, synci); |
| 121 | if (ret < 0) | 122 | if (ret < 0) |
| 122 | goto out_put_dev; | 123 | goto error; |
| 123 | 124 | ||
| 124 | /* Configure sync provider */ | 125 | /* Configure sync provider */ |
| 125 | ret = stm32_sai_sync_conf_provider(sai_provider, synco); | 126 | ret = stm32_sai_sync_conf_provider(sai_provider, synco); |
| 126 | 127 | ||
| 127 | out_put_dev: | 128 | error: |
| 128 | put_device(&pdev->dev); | 129 | put_device(&pdev->dev); |
| 130 | of_node_put(np_provider); | ||
| 129 | return ret; | 131 | return ret; |
| 130 | } | 132 | } |
| 131 | 133 | ||
diff --git a/sound/soc/stm/stm32_sai_sub.c b/sound/soc/stm/stm32_sai_sub.c index f9297228c41c..d7045aa520de 100644 --- a/sound/soc/stm/stm32_sai_sub.c +++ b/sound/soc/stm/stm32_sai_sub.c | |||
| @@ -70,6 +70,7 @@ | |||
| 70 | #define SAI_IEC60958_STATUS_BYTES 24 | 70 | #define SAI_IEC60958_STATUS_BYTES 24 |
| 71 | 71 | ||
| 72 | #define SAI_MCLK_NAME_LEN 32 | 72 | #define SAI_MCLK_NAME_LEN 32 |
| 73 | #define SAI_RATE_11K 11025 | ||
| 73 | 74 | ||
| 74 | /** | 75 | /** |
| 75 | * struct stm32_sai_sub_data - private data of SAI sub block (block A or B) | 76 | * struct stm32_sai_sub_data - private data of SAI sub block (block A or B) |
| @@ -100,8 +101,9 @@ | |||
| 100 | * @slot_mask: rx or tx active slots mask. set at init or at runtime | 101 | * @slot_mask: rx or tx active slots mask. set at init or at runtime |
| 101 | * @data_size: PCM data width. corresponds to PCM substream width. | 102 | * @data_size: PCM data width. corresponds to PCM substream width. |
| 102 | * @spdif_frm_cnt: S/PDIF playback frame counter | 103 | * @spdif_frm_cnt: S/PDIF playback frame counter |
| 103 | * @snd_aes_iec958: iec958 data | 104 | * @iec958: iec958 data |
| 104 | * @ctrl_lock: control lock | 105 | * @ctrl_lock: control lock |
| 106 | * @irq_lock: prevent race condition with IRQ | ||
| 105 | */ | 107 | */ |
| 106 | struct stm32_sai_sub_data { | 108 | struct stm32_sai_sub_data { |
| 107 | struct platform_device *pdev; | 109 | struct platform_device *pdev; |
| @@ -133,6 +135,7 @@ struct stm32_sai_sub_data { | |||
| 133 | unsigned int spdif_frm_cnt; | 135 | unsigned int spdif_frm_cnt; |
| 134 | struct snd_aes_iec958 iec958; | 136 | struct snd_aes_iec958 iec958; |
| 135 | struct mutex ctrl_lock; /* protect resources accessed by controls */ | 137 | struct mutex ctrl_lock; /* protect resources accessed by controls */ |
| 138 | spinlock_t irq_lock; /* used to prevent race condition with IRQ */ | ||
| 136 | }; | 139 | }; |
| 137 | 140 | ||
| 138 | enum stm32_sai_fifo_th { | 141 | enum stm32_sai_fifo_th { |
| @@ -307,6 +310,25 @@ static int stm32_sai_set_clk_div(struct stm32_sai_sub_data *sai, | |||
| 307 | return ret; | 310 | return ret; |
| 308 | } | 311 | } |
| 309 | 312 | ||
| 313 | static int stm32_sai_set_parent_clock(struct stm32_sai_sub_data *sai, | ||
| 314 | unsigned int rate) | ||
| 315 | { | ||
| 316 | struct platform_device *pdev = sai->pdev; | ||
| 317 | struct clk *parent_clk = sai->pdata->clk_x8k; | ||
| 318 | int ret; | ||
| 319 | |||
| 320 | if (!(rate % SAI_RATE_11K)) | ||
| 321 | parent_clk = sai->pdata->clk_x11k; | ||
| 322 | |||
| 323 | ret = clk_set_parent(sai->sai_ck, parent_clk); | ||
| 324 | if (ret) | ||
| 325 | dev_err(&pdev->dev, " Error %d setting sai_ck parent clock. %s", | ||
| 326 | ret, ret == -EBUSY ? | ||
| 327 | "Active stream rates conflict\n" : "\n"); | ||
| 328 | |||
| 329 | return ret; | ||
| 330 | } | ||
| 331 | |||
| 310 | static long stm32_sai_mclk_round_rate(struct clk_hw *hw, unsigned long rate, | 332 | static long stm32_sai_mclk_round_rate(struct clk_hw *hw, unsigned long rate, |
| 311 | unsigned long *prate) | 333 | unsigned long *prate) |
| 312 | { | 334 | { |
| @@ -474,8 +496,10 @@ static irqreturn_t stm32_sai_isr(int irq, void *devid) | |||
| 474 | status = SNDRV_PCM_STATE_XRUN; | 496 | status = SNDRV_PCM_STATE_XRUN; |
| 475 | } | 497 | } |
| 476 | 498 | ||
| 477 | if (status != SNDRV_PCM_STATE_RUNNING) | 499 | spin_lock(&sai->irq_lock); |
| 500 | if (status != SNDRV_PCM_STATE_RUNNING && sai->substream) | ||
| 478 | snd_pcm_stop_xrun(sai->substream); | 501 | snd_pcm_stop_xrun(sai->substream); |
| 502 | spin_unlock(&sai->irq_lock); | ||
| 479 | 503 | ||
| 480 | return IRQ_HANDLED; | 504 | return IRQ_HANDLED; |
| 481 | } | 505 | } |
| @@ -486,25 +510,29 @@ static int stm32_sai_set_sysclk(struct snd_soc_dai *cpu_dai, | |||
| 486 | struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai); | 510 | struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai); |
| 487 | int ret; | 511 | int ret; |
| 488 | 512 | ||
| 489 | if (dir == SND_SOC_CLOCK_OUT) { | 513 | if (dir == SND_SOC_CLOCK_OUT && sai->sai_mclk) { |
| 490 | ret = regmap_update_bits(sai->regmap, STM_SAI_CR1_REGX, | 514 | ret = regmap_update_bits(sai->regmap, STM_SAI_CR1_REGX, |
| 491 | SAI_XCR1_NODIV, | 515 | SAI_XCR1_NODIV, |
| 492 | (unsigned int)~SAI_XCR1_NODIV); | 516 | (unsigned int)~SAI_XCR1_NODIV); |
| 493 | if (ret < 0) | 517 | if (ret < 0) |
| 494 | return ret; | 518 | return ret; |
| 495 | 519 | ||
| 496 | dev_dbg(cpu_dai->dev, "SAI MCLK frequency is %uHz\n", freq); | 520 | /* If master clock is used, set parent clock now */ |
| 497 | sai->mclk_rate = freq; | 521 | ret = stm32_sai_set_parent_clock(sai, freq); |
| 522 | if (ret) | ||
| 523 | return ret; | ||
| 498 | 524 | ||
| 499 | if (sai->sai_mclk) { | 525 | ret = clk_set_rate_exclusive(sai->sai_mclk, freq); |
| 500 | ret = clk_set_rate_exclusive(sai->sai_mclk, | 526 | if (ret) { |
| 501 | sai->mclk_rate); | 527 | dev_err(cpu_dai->dev, |
| 502 | if (ret) { | 528 | ret == -EBUSY ? |
| 503 | dev_err(cpu_dai->dev, | 529 | "Active streams have incompatible rates" : |
| 504 | "Could not set mclk rate\n"); | 530 | "Could not set mclk rate\n"); |
| 505 | return ret; | 531 | return ret; |
| 506 | } | ||
| 507 | } | 532 | } |
| 533 | |||
| 534 | dev_dbg(cpu_dai->dev, "SAI MCLK frequency is %uHz\n", freq); | ||
| 535 | sai->mclk_rate = freq; | ||
| 508 | } | 536 | } |
| 509 | 537 | ||
| 510 | return 0; | 538 | return 0; |
| @@ -679,8 +707,19 @@ static int stm32_sai_startup(struct snd_pcm_substream *substream, | |||
| 679 | { | 707 | { |
| 680 | struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai); | 708 | struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai); |
| 681 | int imr, cr2, ret; | 709 | int imr, cr2, ret; |
| 710 | unsigned long flags; | ||
| 682 | 711 | ||
| 712 | spin_lock_irqsave(&sai->irq_lock, flags); | ||
| 683 | sai->substream = substream; | 713 | sai->substream = substream; |
| 714 | spin_unlock_irqrestore(&sai->irq_lock, flags); | ||
| 715 | |||
| 716 | if (STM_SAI_PROTOCOL_IS_SPDIF(sai)) { | ||
| 717 | snd_pcm_hw_constraint_mask64(substream->runtime, | ||
| 718 | SNDRV_PCM_HW_PARAM_FORMAT, | ||
| 719 | SNDRV_PCM_FMTBIT_S32_LE); | ||
| 720 | snd_pcm_hw_constraint_single(substream->runtime, | ||
| 721 | SNDRV_PCM_HW_PARAM_CHANNELS, 2); | ||
| 722 | } | ||
| 684 | 723 | ||
| 685 | ret = clk_prepare_enable(sai->sai_ck); | 724 | ret = clk_prepare_enable(sai->sai_ck); |
| 686 | if (ret < 0) { | 725 | if (ret < 0) { |
| @@ -898,14 +937,16 @@ static int stm32_sai_configure_clock(struct snd_soc_dai *cpu_dai, | |||
| 898 | struct snd_pcm_hw_params *params) | 937 | struct snd_pcm_hw_params *params) |
| 899 | { | 938 | { |
| 900 | struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai); | 939 | struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai); |
| 901 | int div = 0; | 940 | int div = 0, cr1 = 0; |
| 902 | int sai_clk_rate, mclk_ratio, den; | 941 | int sai_clk_rate, mclk_ratio, den; |
| 903 | unsigned int rate = params_rate(params); | 942 | unsigned int rate = params_rate(params); |
| 943 | int ret; | ||
| 904 | 944 | ||
| 905 | if (!(rate % 11025)) | 945 | if (!sai->sai_mclk) { |
| 906 | clk_set_parent(sai->sai_ck, sai->pdata->clk_x11k); | 946 | ret = stm32_sai_set_parent_clock(sai, rate); |
| 907 | else | 947 | if (ret) |
| 908 | clk_set_parent(sai->sai_ck, sai->pdata->clk_x8k); | 948 | return ret; |
| 949 | } | ||
| 909 | sai_clk_rate = clk_get_rate(sai->sai_ck); | 950 | sai_clk_rate = clk_get_rate(sai->sai_ck); |
| 910 | 951 | ||
| 911 | if (STM_SAI_IS_F4(sai->pdata)) { | 952 | if (STM_SAI_IS_F4(sai->pdata)) { |
| @@ -943,13 +984,19 @@ static int stm32_sai_configure_clock(struct snd_soc_dai *cpu_dai, | |||
| 943 | } else { | 984 | } else { |
| 944 | if (sai->mclk_rate) { | 985 | if (sai->mclk_rate) { |
| 945 | mclk_ratio = sai->mclk_rate / rate; | 986 | mclk_ratio = sai->mclk_rate / rate; |
| 946 | if ((mclk_ratio != 512) && | 987 | if (mclk_ratio == 512) { |
| 947 | (mclk_ratio != 256)) { | 988 | cr1 = SAI_XCR1_OSR; |
| 989 | } else if (mclk_ratio != 256) { | ||
| 948 | dev_err(cpu_dai->dev, | 990 | dev_err(cpu_dai->dev, |
| 949 | "Wrong mclk ratio %d\n", | 991 | "Wrong mclk ratio %d\n", |
| 950 | mclk_ratio); | 992 | mclk_ratio); |
| 951 | return -EINVAL; | 993 | return -EINVAL; |
| 952 | } | 994 | } |
| 995 | |||
| 996 | regmap_update_bits(sai->regmap, | ||
| 997 | STM_SAI_CR1_REGX, | ||
| 998 | SAI_XCR1_OSR, cr1); | ||
| 999 | |||
| 953 | div = stm32_sai_get_clk_div(sai, sai_clk_rate, | 1000 | div = stm32_sai_get_clk_div(sai, sai_clk_rate, |
| 954 | sai->mclk_rate); | 1001 | sai->mclk_rate); |
| 955 | if (div < 0) | 1002 | if (div < 0) |
| @@ -1051,28 +1098,36 @@ static void stm32_sai_shutdown(struct snd_pcm_substream *substream, | |||
| 1051 | struct snd_soc_dai *cpu_dai) | 1098 | struct snd_soc_dai *cpu_dai) |
| 1052 | { | 1099 | { |
| 1053 | struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai); | 1100 | struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai); |
| 1101 | unsigned long flags; | ||
| 1054 | 1102 | ||
| 1055 | regmap_update_bits(sai->regmap, STM_SAI_IMR_REGX, SAI_XIMR_MASK, 0); | 1103 | regmap_update_bits(sai->regmap, STM_SAI_IMR_REGX, SAI_XIMR_MASK, 0); |
| 1056 | 1104 | ||
| 1057 | regmap_update_bits(sai->regmap, STM_SAI_CR1_REGX, SAI_XCR1_NODIV, | 1105 | regmap_update_bits(sai->regmap, STM_SAI_CR1_REGX, SAI_XCR1_NODIV, |
| 1058 | SAI_XCR1_NODIV); | 1106 | SAI_XCR1_NODIV); |
| 1059 | 1107 | ||
| 1060 | clk_disable_unprepare(sai->sai_ck); | 1108 | /* Release mclk rate only if rate was actually set */ |
| 1109 | if (sai->mclk_rate) { | ||
| 1110 | clk_rate_exclusive_put(sai->sai_mclk); | ||
| 1111 | sai->mclk_rate = 0; | ||
| 1112 | } | ||
| 1061 | 1113 | ||
| 1062 | clk_rate_exclusive_put(sai->sai_mclk); | 1114 | clk_disable_unprepare(sai->sai_ck); |
| 1063 | 1115 | ||
| 1116 | spin_lock_irqsave(&sai->irq_lock, flags); | ||
| 1064 | sai->substream = NULL; | 1117 | sai->substream = NULL; |
| 1118 | spin_unlock_irqrestore(&sai->irq_lock, flags); | ||
| 1065 | } | 1119 | } |
| 1066 | 1120 | ||
| 1067 | static int stm32_sai_pcm_new(struct snd_soc_pcm_runtime *rtd, | 1121 | static int stm32_sai_pcm_new(struct snd_soc_pcm_runtime *rtd, |
| 1068 | struct snd_soc_dai *cpu_dai) | 1122 | struct snd_soc_dai *cpu_dai) |
| 1069 | { | 1123 | { |
| 1070 | struct stm32_sai_sub_data *sai = dev_get_drvdata(cpu_dai->dev); | 1124 | struct stm32_sai_sub_data *sai = dev_get_drvdata(cpu_dai->dev); |
| 1125 | struct snd_kcontrol_new knew = iec958_ctls; | ||
| 1071 | 1126 | ||
| 1072 | if (STM_SAI_PROTOCOL_IS_SPDIF(sai)) { | 1127 | if (STM_SAI_PROTOCOL_IS_SPDIF(sai)) { |
| 1073 | dev_dbg(&sai->pdev->dev, "%s: register iec controls", __func__); | 1128 | dev_dbg(&sai->pdev->dev, "%s: register iec controls", __func__); |
| 1074 | return snd_ctl_add(rtd->pcm->card, | 1129 | knew.device = rtd->pcm->device; |
| 1075 | snd_ctl_new1(&iec958_ctls, sai)); | 1130 | return snd_ctl_add(rtd->pcm->card, snd_ctl_new1(&knew, sai)); |
| 1076 | } | 1131 | } |
| 1077 | 1132 | ||
| 1078 | return 0; | 1133 | return 0; |
| @@ -1081,7 +1136,7 @@ static int stm32_sai_pcm_new(struct snd_soc_pcm_runtime *rtd, | |||
| 1081 | static int stm32_sai_dai_probe(struct snd_soc_dai *cpu_dai) | 1136 | static int stm32_sai_dai_probe(struct snd_soc_dai *cpu_dai) |
| 1082 | { | 1137 | { |
| 1083 | struct stm32_sai_sub_data *sai = dev_get_drvdata(cpu_dai->dev); | 1138 | struct stm32_sai_sub_data *sai = dev_get_drvdata(cpu_dai->dev); |
| 1084 | int cr1 = 0, cr1_mask; | 1139 | int cr1 = 0, cr1_mask, ret; |
| 1085 | 1140 | ||
| 1086 | sai->cpu_dai = cpu_dai; | 1141 | sai->cpu_dai = cpu_dai; |
| 1087 | 1142 | ||
| @@ -1111,8 +1166,10 @@ static int stm32_sai_dai_probe(struct snd_soc_dai *cpu_dai) | |||
| 1111 | /* Configure synchronization */ | 1166 | /* Configure synchronization */ |
| 1112 | if (sai->sync == SAI_SYNC_EXTERNAL) { | 1167 | if (sai->sync == SAI_SYNC_EXTERNAL) { |
| 1113 | /* Configure synchro client and provider */ | 1168 | /* Configure synchro client and provider */ |
| 1114 | sai->pdata->set_sync(sai->pdata, sai->np_sync_provider, | 1169 | ret = sai->pdata->set_sync(sai->pdata, sai->np_sync_provider, |
| 1115 | sai->synco, sai->synci); | 1170 | sai->synco, sai->synci); |
| 1171 | if (ret) | ||
| 1172 | return ret; | ||
| 1116 | } | 1173 | } |
| 1117 | 1174 | ||
| 1118 | cr1_mask |= SAI_XCR1_SYNCEN_MASK; | 1175 | cr1_mask |= SAI_XCR1_SYNCEN_MASK; |
| @@ -1392,7 +1449,6 @@ static int stm32_sai_sub_dais_init(struct platform_device *pdev, | |||
| 1392 | if (!sai->cpu_dai_drv) | 1449 | if (!sai->cpu_dai_drv) |
| 1393 | return -ENOMEM; | 1450 | return -ENOMEM; |
| 1394 | 1451 | ||
| 1395 | sai->cpu_dai_drv->name = dev_name(&pdev->dev); | ||
| 1396 | if (STM_SAI_IS_PLAYBACK(sai)) { | 1452 | if (STM_SAI_IS_PLAYBACK(sai)) { |
| 1397 | memcpy(sai->cpu_dai_drv, &stm32_sai_playback_dai, | 1453 | memcpy(sai->cpu_dai_drv, &stm32_sai_playback_dai, |
| 1398 | sizeof(stm32_sai_playback_dai)); | 1454 | sizeof(stm32_sai_playback_dai)); |
| @@ -1402,6 +1458,7 @@ static int stm32_sai_sub_dais_init(struct platform_device *pdev, | |||
| 1402 | sizeof(stm32_sai_capture_dai)); | 1458 | sizeof(stm32_sai_capture_dai)); |
| 1403 | sai->cpu_dai_drv->capture.stream_name = sai->cpu_dai_drv->name; | 1459 | sai->cpu_dai_drv->capture.stream_name = sai->cpu_dai_drv->name; |
| 1404 | } | 1460 | } |
| 1461 | sai->cpu_dai_drv->name = dev_name(&pdev->dev); | ||
| 1405 | 1462 | ||
| 1406 | return 0; | 1463 | return 0; |
| 1407 | } | 1464 | } |
| @@ -1424,6 +1481,7 @@ static int stm32_sai_sub_probe(struct platform_device *pdev) | |||
| 1424 | 1481 | ||
| 1425 | sai->pdev = pdev; | 1482 | sai->pdev = pdev; |
| 1426 | mutex_init(&sai->ctrl_lock); | 1483 | mutex_init(&sai->ctrl_lock); |
| 1484 | spin_lock_init(&sai->irq_lock); | ||
| 1427 | platform_set_drvdata(pdev, sai); | 1485 | platform_set_drvdata(pdev, sai); |
| 1428 | 1486 | ||
| 1429 | sai->pdata = dev_get_drvdata(pdev->dev.parent); | 1487 | sai->pdata = dev_get_drvdata(pdev->dev.parent); |
diff --git a/sound/xen/xen_snd_front_alsa.c b/sound/xen/xen_snd_front_alsa.c index a7f413cb704d..b14ab512c2ce 100644 --- a/sound/xen/xen_snd_front_alsa.c +++ b/sound/xen/xen_snd_front_alsa.c | |||
| @@ -441,7 +441,7 @@ static int shbuf_setup_backstore(struct xen_snd_front_pcm_stream_info *stream, | |||
| 441 | { | 441 | { |
| 442 | int i; | 442 | int i; |
| 443 | 443 | ||
| 444 | stream->buffer = alloc_pages_exact(stream->buffer_sz, GFP_KERNEL); | 444 | stream->buffer = alloc_pages_exact(buffer_sz, GFP_KERNEL); |
| 445 | if (!stream->buffer) | 445 | if (!stream->buffer) |
| 446 | return -ENOMEM; | 446 | return -ENOMEM; |
| 447 | 447 | ||
diff --git a/tools/objtool/check.c b/tools/objtool/check.c index 5dde107083c6..479196aeb409 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c | |||
| @@ -165,6 +165,7 @@ static int __dead_end_function(struct objtool_file *file, struct symbol *func, | |||
| 165 | "fortify_panic", | 165 | "fortify_panic", |
| 166 | "usercopy_abort", | 166 | "usercopy_abort", |
| 167 | "machine_real_restart", | 167 | "machine_real_restart", |
| 168 | "rewind_stack_do_exit", | ||
| 168 | }; | 169 | }; |
| 169 | 170 | ||
| 170 | if (func->bind == STB_WEAK) | 171 | if (func->bind == STB_WEAK) |
diff --git a/tools/testing/selftests/tc-testing/tc-tests/filters/tests.json b/tools/testing/selftests/tc-testing/tc-tests/filters/tests.json index 99a5ffca1088..2d096b2abf2c 100644 --- a/tools/testing/selftests/tc-testing/tc-tests/filters/tests.json +++ b/tools/testing/selftests/tc-testing/tc-tests/filters/tests.json | |||
| @@ -19,6 +19,26 @@ | |||
| 19 | ] | 19 | ] |
| 20 | }, | 20 | }, |
| 21 | { | 21 | { |
| 22 | "id": "2638", | ||
| 23 | "name": "Add matchall and try to get it", | ||
| 24 | "category": [ | ||
| 25 | "filter", | ||
| 26 | "matchall" | ||
| 27 | ], | ||
| 28 | "setup": [ | ||
| 29 | "$TC qdisc add dev $DEV1 clsact", | ||
| 30 | "$TC filter add dev $DEV1 protocol all pref 1 ingress handle 0x1234 matchall action ok" | ||
| 31 | ], | ||
| 32 | "cmdUnderTest": "$TC filter get dev $DEV1 protocol all pref 1 ingress handle 0x1234 matchall", | ||
| 33 | "expExitCode": "0", | ||
| 34 | "verifyCmd": "$TC filter show dev $DEV1 ingress", | ||
| 35 | "matchPattern": "filter protocol all pref 1 matchall chain 0 handle 0x1234", | ||
| 36 | "matchCount": "1", | ||
| 37 | "teardown": [ | ||
| 38 | "$TC qdisc del dev $DEV1 clsact" | ||
| 39 | ] | ||
| 40 | }, | ||
| 41 | { | ||
| 22 | "id": "d052", | 42 | "id": "d052", |
| 23 | "name": "Add 1M filters with the same action", | 43 | "name": "Add 1M filters with the same action", |
| 24 | "category": [ | 44 | "category": [ |
diff --git a/tools/testing/selftests/tpm2/tpm2.py b/tools/testing/selftests/tpm2/tpm2.py index 40ea95ce2ead..828c18584624 100644 --- a/tools/testing/selftests/tpm2/tpm2.py +++ b/tools/testing/selftests/tpm2/tpm2.py | |||
| @@ -22,6 +22,7 @@ TPM2_CC_UNSEAL = 0x015E | |||
| 22 | TPM2_CC_FLUSH_CONTEXT = 0x0165 | 22 | TPM2_CC_FLUSH_CONTEXT = 0x0165 |
| 23 | TPM2_CC_START_AUTH_SESSION = 0x0176 | 23 | TPM2_CC_START_AUTH_SESSION = 0x0176 |
| 24 | TPM2_CC_GET_CAPABILITY = 0x017A | 24 | TPM2_CC_GET_CAPABILITY = 0x017A |
| 25 | TPM2_CC_GET_RANDOM = 0x017B | ||
| 25 | TPM2_CC_PCR_READ = 0x017E | 26 | TPM2_CC_PCR_READ = 0x017E |
| 26 | TPM2_CC_POLICY_PCR = 0x017F | 27 | TPM2_CC_POLICY_PCR = 0x017F |
| 27 | TPM2_CC_PCR_EXTEND = 0x0182 | 28 | TPM2_CC_PCR_EXTEND = 0x0182 |
| @@ -357,9 +358,9 @@ class Client: | |||
| 357 | self.flags = flags | 358 | self.flags = flags |
| 358 | 359 | ||
| 359 | if (self.flags & Client.FLAG_SPACE) == 0: | 360 | if (self.flags & Client.FLAG_SPACE) == 0: |
| 360 | self.tpm = open('/dev/tpm0', 'r+b') | 361 | self.tpm = open('/dev/tpm0', 'r+b', buffering=0) |
| 361 | else: | 362 | else: |
| 362 | self.tpm = open('/dev/tpmrm0', 'r+b') | 363 | self.tpm = open('/dev/tpmrm0', 'r+b', buffering=0) |
| 363 | 364 | ||
| 364 | def close(self): | 365 | def close(self): |
| 365 | self.tpm.close() | 366 | self.tpm.close() |
diff --git a/tools/testing/selftests/tpm2/tpm2_tests.py b/tools/testing/selftests/tpm2/tpm2_tests.py index 3bb066fea4a0..d4973be53493 100644 --- a/tools/testing/selftests/tpm2/tpm2_tests.py +++ b/tools/testing/selftests/tpm2/tpm2_tests.py | |||
| @@ -158,6 +158,69 @@ class SmokeTest(unittest.TestCase): | |||
| 158 | pass | 158 | pass |
| 159 | self.assertEqual(rejected, True) | 159 | self.assertEqual(rejected, True) |
| 160 | 160 | ||
| 161 | def test_read_partial_resp(self): | ||
| 162 | try: | ||
| 163 | fmt = '>HIIH' | ||
| 164 | cmd = struct.pack(fmt, | ||
| 165 | tpm2.TPM2_ST_NO_SESSIONS, | ||
| 166 | struct.calcsize(fmt), | ||
| 167 | tpm2.TPM2_CC_GET_RANDOM, | ||
| 168 | 0x20) | ||
| 169 | self.client.tpm.write(cmd) | ||
| 170 | hdr = self.client.tpm.read(10) | ||
| 171 | sz = struct.unpack('>I', hdr[2:6])[0] | ||
| 172 | rsp = self.client.tpm.read() | ||
| 173 | except: | ||
| 174 | pass | ||
| 175 | self.assertEqual(sz, 10 + 2 + 32) | ||
| 176 | self.assertEqual(len(rsp), 2 + 32) | ||
| 177 | |||
| 178 | def test_read_partial_overwrite(self): | ||
| 179 | try: | ||
| 180 | fmt = '>HIIH' | ||
| 181 | cmd = struct.pack(fmt, | ||
| 182 | tpm2.TPM2_ST_NO_SESSIONS, | ||
| 183 | struct.calcsize(fmt), | ||
| 184 | tpm2.TPM2_CC_GET_RANDOM, | ||
| 185 | 0x20) | ||
| 186 | self.client.tpm.write(cmd) | ||
| 187 | # Read part of the respone | ||
| 188 | rsp1 = self.client.tpm.read(15) | ||
| 189 | |||
| 190 | # Send a new cmd | ||
| 191 | self.client.tpm.write(cmd) | ||
| 192 | |||
| 193 | # Read the whole respone | ||
| 194 | rsp2 = self.client.tpm.read() | ||
| 195 | except: | ||
| 196 | pass | ||
| 197 | self.assertEqual(len(rsp1), 15) | ||
| 198 | self.assertEqual(len(rsp2), 10 + 2 + 32) | ||
| 199 | |||
| 200 | def test_send_two_cmds(self): | ||
| 201 | rejected = False | ||
| 202 | try: | ||
| 203 | fmt = '>HIIH' | ||
| 204 | cmd = struct.pack(fmt, | ||
| 205 | tpm2.TPM2_ST_NO_SESSIONS, | ||
| 206 | struct.calcsize(fmt), | ||
| 207 | tpm2.TPM2_CC_GET_RANDOM, | ||
| 208 | 0x20) | ||
| 209 | self.client.tpm.write(cmd) | ||
| 210 | |||
| 211 | # expect the second one to raise -EBUSY error | ||
| 212 | self.client.tpm.write(cmd) | ||
| 213 | rsp = self.client.tpm.read() | ||
| 214 | |||
| 215 | except IOError, e: | ||
| 216 | # read the response | ||
| 217 | rsp = self.client.tpm.read() | ||
| 218 | rejected = True | ||
| 219 | pass | ||
| 220 | except: | ||
| 221 | pass | ||
| 222 | self.assertEqual(rejected, True) | ||
| 223 | |||
| 161 | class SpaceTest(unittest.TestCase): | 224 | class SpaceTest(unittest.TestCase): |
| 162 | def setUp(self): | 225 | def setUp(self): |
| 163 | logging.basicConfig(filename='SpaceTest.log', level=logging.DEBUG) | 226 | logging.basicConfig(filename='SpaceTest.log', level=logging.DEBUG) |
