diff options
| author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2018-01-02 08:46:35 -0500 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2018-01-02 08:46:35 -0500 |
| commit | b6a09416e83ffe4eccfb4ef1b91b3b66483fa810 (patch) | |
| tree | b30f266e85047244dcdb47d5afc134e76aec530d /drivers | |
| parent | db809859c8cee415293b830e67178f526d1eb2be (diff) | |
| parent | 30a7acd573899fd8b8ac39236eff6468b195ac7d (diff) | |
Merge 4.15-rc6 into char-misc-next
We want the fixes in here as well.
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers')
299 files changed, 2862 insertions, 1372 deletions
diff --git a/drivers/acpi/apei/erst.c b/drivers/acpi/apei/erst.c index 6742f6c68034..9bff853e85f3 100644 --- a/drivers/acpi/apei/erst.c +++ b/drivers/acpi/apei/erst.c | |||
| @@ -1007,7 +1007,7 @@ skip: | |||
| 1007 | /* The record may be cleared by others, try read next record */ | 1007 | /* The record may be cleared by others, try read next record */ |
| 1008 | if (len == -ENOENT) | 1008 | if (len == -ENOENT) |
| 1009 | goto skip; | 1009 | goto skip; |
| 1010 | else if (len < sizeof(*rcd)) { | 1010 | else if (len < 0 || len < sizeof(*rcd)) { |
| 1011 | rc = -EIO; | 1011 | rc = -EIO; |
| 1012 | goto out; | 1012 | goto out; |
| 1013 | } | 1013 | } |
diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c index 30e84cc600ae..06ea4749ebd9 100644 --- a/drivers/acpi/cppc_acpi.c +++ b/drivers/acpi/cppc_acpi.c | |||
| @@ -1171,7 +1171,7 @@ int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls) | |||
| 1171 | struct cpc_desc *cpc_desc = per_cpu(cpc_desc_ptr, cpu); | 1171 | struct cpc_desc *cpc_desc = per_cpu(cpc_desc_ptr, cpu); |
| 1172 | struct cpc_register_resource *desired_reg; | 1172 | struct cpc_register_resource *desired_reg; |
| 1173 | int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpu); | 1173 | int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpu); |
| 1174 | struct cppc_pcc_data *pcc_ss_data = pcc_data[pcc_ss_id]; | 1174 | struct cppc_pcc_data *pcc_ss_data; |
| 1175 | int ret = 0; | 1175 | int ret = 0; |
| 1176 | 1176 | ||
| 1177 | if (!cpc_desc || pcc_ss_id < 0) { | 1177 | if (!cpc_desc || pcc_ss_id < 0) { |
diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c index e4ffaeec9ec2..a4c8ad98560d 100644 --- a/drivers/acpi/device_pm.c +++ b/drivers/acpi/device_pm.c | |||
| @@ -1138,7 +1138,7 @@ int acpi_subsys_thaw_noirq(struct device *dev) | |||
| 1138 | * skip all of the subsequent "thaw" callbacks for the device. | 1138 | * skip all of the subsequent "thaw" callbacks for the device. |
| 1139 | */ | 1139 | */ |
| 1140 | if (dev_pm_smart_suspend_and_suspended(dev)) { | 1140 | if (dev_pm_smart_suspend_and_suspended(dev)) { |
| 1141 | dev->power.direct_complete = true; | 1141 | dev_pm_skip_next_resume_phases(dev); |
| 1142 | return 0; | 1142 | return 0; |
| 1143 | } | 1143 | } |
| 1144 | 1144 | ||
diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c index ff2580e7611d..abeb4df4f22e 100644 --- a/drivers/acpi/nfit/core.c +++ b/drivers/acpi/nfit/core.c | |||
| @@ -1670,6 +1670,11 @@ static int acpi_nfit_add_dimm(struct acpi_nfit_desc *acpi_desc, | |||
| 1670 | dev_name(&adev_dimm->dev)); | 1670 | dev_name(&adev_dimm->dev)); |
| 1671 | return -ENXIO; | 1671 | return -ENXIO; |
| 1672 | } | 1672 | } |
| 1673 | /* | ||
| 1674 | * Record nfit_mem for the notification path to track back to | ||
| 1675 | * the nfit sysfs attributes for this dimm device object. | ||
| 1676 | */ | ||
| 1677 | dev_set_drvdata(&adev_dimm->dev, nfit_mem); | ||
| 1673 | 1678 | ||
| 1674 | /* | 1679 | /* |
| 1675 | * Until standardization materializes we need to consider 4 | 1680 | * Until standardization materializes we need to consider 4 |
| @@ -1752,9 +1757,11 @@ static void shutdown_dimm_notify(void *data) | |||
| 1752 | sysfs_put(nfit_mem->flags_attr); | 1757 | sysfs_put(nfit_mem->flags_attr); |
| 1753 | nfit_mem->flags_attr = NULL; | 1758 | nfit_mem->flags_attr = NULL; |
| 1754 | } | 1759 | } |
| 1755 | if (adev_dimm) | 1760 | if (adev_dimm) { |
| 1756 | acpi_remove_notify_handler(adev_dimm->handle, | 1761 | acpi_remove_notify_handler(adev_dimm->handle, |
| 1757 | ACPI_DEVICE_NOTIFY, acpi_nvdimm_notify); | 1762 | ACPI_DEVICE_NOTIFY, acpi_nvdimm_notify); |
| 1763 | dev_set_drvdata(&adev_dimm->dev, NULL); | ||
| 1764 | } | ||
| 1758 | } | 1765 | } |
| 1759 | mutex_unlock(&acpi_desc->init_mutex); | 1766 | mutex_unlock(&acpi_desc->init_mutex); |
| 1760 | } | 1767 | } |
diff --git a/drivers/android/binder.c b/drivers/android/binder.c index a54a0f1f69a9..778caed570c6 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c | |||
| @@ -482,7 +482,8 @@ enum binder_deferred_state { | |||
| 482 | * @tsk task_struct for group_leader of process | 482 | * @tsk task_struct for group_leader of process |
| 483 | * (invariant after initialized) | 483 | * (invariant after initialized) |
| 484 | * @files files_struct for process | 484 | * @files files_struct for process |
| 485 | * (invariant after initialized) | 485 | * (protected by @files_lock) |
| 486 | * @files_lock mutex to protect @files | ||
| 486 | * @deferred_work_node: element for binder_deferred_list | 487 | * @deferred_work_node: element for binder_deferred_list |
| 487 | * (protected by binder_deferred_lock) | 488 | * (protected by binder_deferred_lock) |
| 488 | * @deferred_work: bitmap of deferred work to perform | 489 | * @deferred_work: bitmap of deferred work to perform |
| @@ -530,6 +531,7 @@ struct binder_proc { | |||
| 530 | int pid; | 531 | int pid; |
| 531 | struct task_struct *tsk; | 532 | struct task_struct *tsk; |
| 532 | struct files_struct *files; | 533 | struct files_struct *files; |
| 534 | struct mutex files_lock; | ||
| 533 | struct hlist_node deferred_work_node; | 535 | struct hlist_node deferred_work_node; |
| 534 | int deferred_work; | 536 | int deferred_work; |
| 535 | bool is_dead; | 537 | bool is_dead; |
| @@ -924,20 +926,26 @@ static void binder_inc_node_tmpref_ilocked(struct binder_node *node); | |||
| 924 | 926 | ||
| 925 | static int task_get_unused_fd_flags(struct binder_proc *proc, int flags) | 927 | static int task_get_unused_fd_flags(struct binder_proc *proc, int flags) |
| 926 | { | 928 | { |
| 927 | struct files_struct *files = proc->files; | ||
| 928 | unsigned long rlim_cur; | 929 | unsigned long rlim_cur; |
| 929 | unsigned long irqs; | 930 | unsigned long irqs; |
| 931 | int ret; | ||
| 930 | 932 | ||
| 931 | if (files == NULL) | 933 | mutex_lock(&proc->files_lock); |
| 932 | return -ESRCH; | 934 | if (proc->files == NULL) { |
| 933 | 935 | ret = -ESRCH; | |
| 934 | if (!lock_task_sighand(proc->tsk, &irqs)) | 936 | goto err; |
| 935 | return -EMFILE; | 937 | } |
| 936 | 938 | if (!lock_task_sighand(proc->tsk, &irqs)) { | |
| 939 | ret = -EMFILE; | ||
| 940 | goto err; | ||
| 941 | } | ||
| 937 | rlim_cur = task_rlimit(proc->tsk, RLIMIT_NOFILE); | 942 | rlim_cur = task_rlimit(proc->tsk, RLIMIT_NOFILE); |
| 938 | unlock_task_sighand(proc->tsk, &irqs); | 943 | unlock_task_sighand(proc->tsk, &irqs); |
| 939 | 944 | ||
| 940 | return __alloc_fd(files, 0, rlim_cur, flags); | 945 | ret = __alloc_fd(proc->files, 0, rlim_cur, flags); |
| 946 | err: | ||
| 947 | mutex_unlock(&proc->files_lock); | ||
| 948 | return ret; | ||
| 941 | } | 949 | } |
| 942 | 950 | ||
| 943 | /* | 951 | /* |
| @@ -946,8 +954,10 @@ static int task_get_unused_fd_flags(struct binder_proc *proc, int flags) | |||
| 946 | static void task_fd_install( | 954 | static void task_fd_install( |
| 947 | struct binder_proc *proc, unsigned int fd, struct file *file) | 955 | struct binder_proc *proc, unsigned int fd, struct file *file) |
| 948 | { | 956 | { |
| 957 | mutex_lock(&proc->files_lock); | ||
| 949 | if (proc->files) | 958 | if (proc->files) |
| 950 | __fd_install(proc->files, fd, file); | 959 | __fd_install(proc->files, fd, file); |
| 960 | mutex_unlock(&proc->files_lock); | ||
| 951 | } | 961 | } |
| 952 | 962 | ||
| 953 | /* | 963 | /* |
| @@ -957,9 +967,11 @@ static long task_close_fd(struct binder_proc *proc, unsigned int fd) | |||
| 957 | { | 967 | { |
| 958 | int retval; | 968 | int retval; |
| 959 | 969 | ||
| 960 | if (proc->files == NULL) | 970 | mutex_lock(&proc->files_lock); |
| 961 | return -ESRCH; | 971 | if (proc->files == NULL) { |
| 962 | 972 | retval = -ESRCH; | |
| 973 | goto err; | ||
| 974 | } | ||
| 963 | retval = __close_fd(proc->files, fd); | 975 | retval = __close_fd(proc->files, fd); |
| 964 | /* can't restart close syscall because file table entry was cleared */ | 976 | /* can't restart close syscall because file table entry was cleared */ |
| 965 | if (unlikely(retval == -ERESTARTSYS || | 977 | if (unlikely(retval == -ERESTARTSYS || |
| @@ -967,7 +979,8 @@ static long task_close_fd(struct binder_proc *proc, unsigned int fd) | |||
| 967 | retval == -ERESTARTNOHAND || | 979 | retval == -ERESTARTNOHAND || |
| 968 | retval == -ERESTART_RESTARTBLOCK)) | 980 | retval == -ERESTART_RESTARTBLOCK)) |
| 969 | retval = -EINTR; | 981 | retval = -EINTR; |
| 970 | 982 | err: | |
| 983 | mutex_unlock(&proc->files_lock); | ||
| 971 | return retval; | 984 | return retval; |
| 972 | } | 985 | } |
| 973 | 986 | ||
| @@ -4690,7 +4703,9 @@ static int binder_mmap(struct file *filp, struct vm_area_struct *vma) | |||
| 4690 | ret = binder_alloc_mmap_handler(&proc->alloc, vma); | 4703 | ret = binder_alloc_mmap_handler(&proc->alloc, vma); |
| 4691 | if (ret) | 4704 | if (ret) |
| 4692 | return ret; | 4705 | return ret; |
| 4706 | mutex_lock(&proc->files_lock); | ||
| 4693 | proc->files = get_files_struct(current); | 4707 | proc->files = get_files_struct(current); |
| 4708 | mutex_unlock(&proc->files_lock); | ||
| 4694 | return 0; | 4709 | return 0; |
| 4695 | 4710 | ||
| 4696 | err_bad_arg: | 4711 | err_bad_arg: |
| @@ -4714,6 +4729,7 @@ static int binder_open(struct inode *nodp, struct file *filp) | |||
| 4714 | spin_lock_init(&proc->outer_lock); | 4729 | spin_lock_init(&proc->outer_lock); |
| 4715 | get_task_struct(current->group_leader); | 4730 | get_task_struct(current->group_leader); |
| 4716 | proc->tsk = current->group_leader; | 4731 | proc->tsk = current->group_leader; |
| 4732 | mutex_init(&proc->files_lock); | ||
| 4717 | INIT_LIST_HEAD(&proc->todo); | 4733 | INIT_LIST_HEAD(&proc->todo); |
| 4718 | proc->default_priority = task_nice(current); | 4734 | proc->default_priority = task_nice(current); |
| 4719 | binder_dev = container_of(filp->private_data, struct binder_device, | 4735 | binder_dev = container_of(filp->private_data, struct binder_device, |
| @@ -4966,9 +4982,11 @@ static void binder_deferred_func(struct work_struct *work) | |||
| 4966 | 4982 | ||
| 4967 | files = NULL; | 4983 | files = NULL; |
| 4968 | if (defer & BINDER_DEFERRED_PUT_FILES) { | 4984 | if (defer & BINDER_DEFERRED_PUT_FILES) { |
| 4985 | mutex_lock(&proc->files_lock); | ||
| 4969 | files = proc->files; | 4986 | files = proc->files; |
| 4970 | if (files) | 4987 | if (files) |
| 4971 | proc->files = NULL; | 4988 | proc->files = NULL; |
| 4989 | mutex_unlock(&proc->files_lock); | ||
| 4972 | } | 4990 | } |
| 4973 | 4991 | ||
| 4974 | if (defer & BINDER_DEFERRED_FLUSH) | 4992 | if (defer & BINDER_DEFERRED_FLUSH) |
diff --git a/drivers/ata/ahci_mtk.c b/drivers/ata/ahci_mtk.c index 80854f71559a..0ae6971c2a4c 100644 --- a/drivers/ata/ahci_mtk.c +++ b/drivers/ata/ahci_mtk.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * MeidaTek AHCI SATA driver | 2 | * MediaTek AHCI SATA driver |
| 3 | * | 3 | * |
| 4 | * Copyright (c) 2017 MediaTek Inc. | 4 | * Copyright (c) 2017 MediaTek Inc. |
| 5 | * Author: Ryder Lee <ryder.lee@mediatek.com> | 5 | * Author: Ryder Lee <ryder.lee@mediatek.com> |
| @@ -25,7 +25,7 @@ | |||
| 25 | #include <linux/reset.h> | 25 | #include <linux/reset.h> |
| 26 | #include "ahci.h" | 26 | #include "ahci.h" |
| 27 | 27 | ||
| 28 | #define DRV_NAME "ahci" | 28 | #define DRV_NAME "ahci-mtk" |
| 29 | 29 | ||
| 30 | #define SYS_CFG 0x14 | 30 | #define SYS_CFG 0x14 |
| 31 | #define SYS_CFG_SATA_MSK GENMASK(31, 30) | 31 | #define SYS_CFG_SATA_MSK GENMASK(31, 30) |
| @@ -192,5 +192,5 @@ static struct platform_driver mtk_ahci_driver = { | |||
| 192 | }; | 192 | }; |
| 193 | module_platform_driver(mtk_ahci_driver); | 193 | module_platform_driver(mtk_ahci_driver); |
| 194 | 194 | ||
| 195 | MODULE_DESCRIPTION("MeidaTek SATA AHCI Driver"); | 195 | MODULE_DESCRIPTION("MediaTek SATA AHCI Driver"); |
| 196 | MODULE_LICENSE("GPL v2"); | 196 | MODULE_LICENSE("GPL v2"); |
diff --git a/drivers/ata/ahci_qoriq.c b/drivers/ata/ahci_qoriq.c index b6b0bf76dfc7..2685f28160f7 100644 --- a/drivers/ata/ahci_qoriq.c +++ b/drivers/ata/ahci_qoriq.c | |||
| @@ -35,6 +35,8 @@ | |||
| 35 | 35 | ||
| 36 | /* port register default value */ | 36 | /* port register default value */ |
| 37 | #define AHCI_PORT_PHY_1_CFG 0xa003fffe | 37 | #define AHCI_PORT_PHY_1_CFG 0xa003fffe |
| 38 | #define AHCI_PORT_PHY2_CFG 0x28184d1f | ||
| 39 | #define AHCI_PORT_PHY3_CFG 0x0e081509 | ||
| 38 | #define AHCI_PORT_TRANS_CFG 0x08000029 | 40 | #define AHCI_PORT_TRANS_CFG 0x08000029 |
| 39 | #define AHCI_PORT_AXICC_CFG 0x3fffffff | 41 | #define AHCI_PORT_AXICC_CFG 0x3fffffff |
| 40 | 42 | ||
| @@ -183,6 +185,8 @@ static int ahci_qoriq_phy_init(struct ahci_host_priv *hpriv) | |||
| 183 | writel(readl(qpriv->ecc_addr) | ECC_DIS_ARMV8_CH2, | 185 | writel(readl(qpriv->ecc_addr) | ECC_DIS_ARMV8_CH2, |
| 184 | qpriv->ecc_addr); | 186 | qpriv->ecc_addr); |
| 185 | writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1); | 187 | writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1); |
| 188 | writel(AHCI_PORT_PHY2_CFG, reg_base + PORT_PHY2); | ||
| 189 | writel(AHCI_PORT_PHY3_CFG, reg_base + PORT_PHY3); | ||
| 186 | writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS); | 190 | writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS); |
| 187 | if (qpriv->is_dmacoherent) | 191 | if (qpriv->is_dmacoherent) |
| 188 | writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC); | 192 | writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC); |
| @@ -190,6 +194,8 @@ static int ahci_qoriq_phy_init(struct ahci_host_priv *hpriv) | |||
| 190 | 194 | ||
| 191 | case AHCI_LS2080A: | 195 | case AHCI_LS2080A: |
| 192 | writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1); | 196 | writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1); |
| 197 | writel(AHCI_PORT_PHY2_CFG, reg_base + PORT_PHY2); | ||
| 198 | writel(AHCI_PORT_PHY3_CFG, reg_base + PORT_PHY3); | ||
| 193 | writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS); | 199 | writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS); |
| 194 | if (qpriv->is_dmacoherent) | 200 | if (qpriv->is_dmacoherent) |
| 195 | writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC); | 201 | writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC); |
| @@ -201,6 +207,8 @@ static int ahci_qoriq_phy_init(struct ahci_host_priv *hpriv) | |||
| 201 | writel(readl(qpriv->ecc_addr) | ECC_DIS_ARMV8_CH2, | 207 | writel(readl(qpriv->ecc_addr) | ECC_DIS_ARMV8_CH2, |
| 202 | qpriv->ecc_addr); | 208 | qpriv->ecc_addr); |
| 203 | writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1); | 209 | writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1); |
| 210 | writel(AHCI_PORT_PHY2_CFG, reg_base + PORT_PHY2); | ||
| 211 | writel(AHCI_PORT_PHY3_CFG, reg_base + PORT_PHY3); | ||
| 204 | writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS); | 212 | writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS); |
| 205 | if (qpriv->is_dmacoherent) | 213 | if (qpriv->is_dmacoherent) |
| 206 | writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC); | 214 | writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC); |
| @@ -212,6 +220,8 @@ static int ahci_qoriq_phy_init(struct ahci_host_priv *hpriv) | |||
| 212 | writel(readl(qpriv->ecc_addr) | ECC_DIS_LS1088A, | 220 | writel(readl(qpriv->ecc_addr) | ECC_DIS_LS1088A, |
| 213 | qpriv->ecc_addr); | 221 | qpriv->ecc_addr); |
| 214 | writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1); | 222 | writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1); |
| 223 | writel(AHCI_PORT_PHY2_CFG, reg_base + PORT_PHY2); | ||
| 224 | writel(AHCI_PORT_PHY3_CFG, reg_base + PORT_PHY3); | ||
| 215 | writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS); | 225 | writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS); |
| 216 | if (qpriv->is_dmacoherent) | 226 | if (qpriv->is_dmacoherent) |
| 217 | writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC); | 227 | writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC); |
| @@ -219,6 +229,8 @@ static int ahci_qoriq_phy_init(struct ahci_host_priv *hpriv) | |||
| 219 | 229 | ||
| 220 | case AHCI_LS2088A: | 230 | case AHCI_LS2088A: |
| 221 | writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1); | 231 | writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1); |
| 232 | writel(AHCI_PORT_PHY2_CFG, reg_base + PORT_PHY2); | ||
| 233 | writel(AHCI_PORT_PHY3_CFG, reg_base + PORT_PHY3); | ||
| 222 | writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS); | 234 | writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS); |
| 223 | if (qpriv->is_dmacoherent) | 235 | if (qpriv->is_dmacoherent) |
| 224 | writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC); | 236 | writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC); |
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 2a882929de4a..8193b38a1cae 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
| @@ -3082,13 +3082,19 @@ int sata_down_spd_limit(struct ata_link *link, u32 spd_limit) | |||
| 3082 | bit = fls(mask) - 1; | 3082 | bit = fls(mask) - 1; |
| 3083 | mask &= ~(1 << bit); | 3083 | mask &= ~(1 << bit); |
| 3084 | 3084 | ||
| 3085 | /* Mask off all speeds higher than or equal to the current | 3085 | /* |
| 3086 | * one. Force 1.5Gbps if current SPD is not available. | 3086 | * Mask off all speeds higher than or equal to the current one. At |
| 3087 | * this point, if current SPD is not available and we previously | ||
| 3088 | * recorded the link speed from SStatus, the driver has already | ||
| 3089 | * masked off the highest bit so mask should already be 1 or 0. | ||
| 3090 | * Otherwise, we should not force 1.5Gbps on a link where we have | ||
| 3091 | * not previously recorded speed from SStatus. Just return in this | ||
| 3092 | * case. | ||
| 3087 | */ | 3093 | */ |
| 3088 | if (spd > 1) | 3094 | if (spd > 1) |
| 3089 | mask &= (1 << (spd - 1)) - 1; | 3095 | mask &= (1 << (spd - 1)) - 1; |
| 3090 | else | 3096 | else |
| 3091 | mask &= 1; | 3097 | return -EINVAL; |
| 3092 | 3098 | ||
| 3093 | /* were we already at the bottom? */ | 3099 | /* were we already at the bottom? */ |
| 3094 | if (!mask) | 3100 | if (!mask) |
diff --git a/drivers/ata/pata_pdc2027x.c b/drivers/ata/pata_pdc2027x.c index ffd8d33c6e0f..6db2e34bd52f 100644 --- a/drivers/ata/pata_pdc2027x.c +++ b/drivers/ata/pata_pdc2027x.c | |||
| @@ -82,7 +82,7 @@ static int pdc2027x_set_mode(struct ata_link *link, struct ata_device **r_failed | |||
| 82 | * is issued to the device. However, if the controller clock is 133MHz, | 82 | * is issued to the device. However, if the controller clock is 133MHz, |
| 83 | * the following tables must be used. | 83 | * the following tables must be used. |
| 84 | */ | 84 | */ |
| 85 | static struct pdc2027x_pio_timing { | 85 | static const struct pdc2027x_pio_timing { |
| 86 | u8 value0, value1, value2; | 86 | u8 value0, value1, value2; |
| 87 | } pdc2027x_pio_timing_tbl[] = { | 87 | } pdc2027x_pio_timing_tbl[] = { |
| 88 | { 0xfb, 0x2b, 0xac }, /* PIO mode 0 */ | 88 | { 0xfb, 0x2b, 0xac }, /* PIO mode 0 */ |
| @@ -92,7 +92,7 @@ static struct pdc2027x_pio_timing { | |||
| 92 | { 0x23, 0x09, 0x25 }, /* PIO mode 4, IORDY on, Prefetch off */ | 92 | { 0x23, 0x09, 0x25 }, /* PIO mode 4, IORDY on, Prefetch off */ |
| 93 | }; | 93 | }; |
| 94 | 94 | ||
| 95 | static struct pdc2027x_mdma_timing { | 95 | static const struct pdc2027x_mdma_timing { |
| 96 | u8 value0, value1; | 96 | u8 value0, value1; |
| 97 | } pdc2027x_mdma_timing_tbl[] = { | 97 | } pdc2027x_mdma_timing_tbl[] = { |
| 98 | { 0xdf, 0x5f }, /* MDMA mode 0 */ | 98 | { 0xdf, 0x5f }, /* MDMA mode 0 */ |
| @@ -100,7 +100,7 @@ static struct pdc2027x_mdma_timing { | |||
| 100 | { 0x69, 0x25 }, /* MDMA mode 2 */ | 100 | { 0x69, 0x25 }, /* MDMA mode 2 */ |
| 101 | }; | 101 | }; |
| 102 | 102 | ||
| 103 | static struct pdc2027x_udma_timing { | 103 | static const struct pdc2027x_udma_timing { |
| 104 | u8 value0, value1, value2; | 104 | u8 value0, value1, value2; |
| 105 | } pdc2027x_udma_timing_tbl[] = { | 105 | } pdc2027x_udma_timing_tbl[] = { |
| 106 | { 0x4a, 0x0f, 0xd5 }, /* UDMA mode 0 */ | 106 | { 0x4a, 0x0f, 0xd5 }, /* UDMA mode 0 */ |
| @@ -649,7 +649,7 @@ static long pdc_detect_pll_input_clock(struct ata_host *host) | |||
| 649 | * @host: target ATA host | 649 | * @host: target ATA host |
| 650 | * @board_idx: board identifier | 650 | * @board_idx: board identifier |
| 651 | */ | 651 | */ |
| 652 | static int pdc_hardware_init(struct ata_host *host, unsigned int board_idx) | 652 | static void pdc_hardware_init(struct ata_host *host, unsigned int board_idx) |
| 653 | { | 653 | { |
| 654 | long pll_clock; | 654 | long pll_clock; |
| 655 | 655 | ||
| @@ -665,8 +665,6 @@ static int pdc_hardware_init(struct ata_host *host, unsigned int board_idx) | |||
| 665 | 665 | ||
| 666 | /* Adjust PLL control register */ | 666 | /* Adjust PLL control register */ |
| 667 | pdc_adjust_pll(host, pll_clock, board_idx); | 667 | pdc_adjust_pll(host, pll_clock, board_idx); |
| 668 | |||
| 669 | return 0; | ||
| 670 | } | 668 | } |
| 671 | 669 | ||
| 672 | /** | 670 | /** |
| @@ -753,8 +751,7 @@ static int pdc2027x_init_one(struct pci_dev *pdev, | |||
| 753 | //pci_enable_intx(pdev); | 751 | //pci_enable_intx(pdev); |
| 754 | 752 | ||
| 755 | /* initialize adapter */ | 753 | /* initialize adapter */ |
| 756 | if (pdc_hardware_init(host, board_idx) != 0) | 754 | pdc_hardware_init(host, board_idx); |
| 757 | return -EIO; | ||
| 758 | 755 | ||
| 759 | pci_set_master(pdev); | 756 | pci_set_master(pdev); |
| 760 | return ata_host_activate(host, pdev->irq, ata_bmdma_interrupt, | 757 | return ata_host_activate(host, pdev->irq, ata_bmdma_interrupt, |
| @@ -778,8 +775,7 @@ static int pdc2027x_reinit_one(struct pci_dev *pdev) | |||
| 778 | else | 775 | else |
| 779 | board_idx = PDC_UDMA_133; | 776 | board_idx = PDC_UDMA_133; |
| 780 | 777 | ||
| 781 | if (pdc_hardware_init(host, board_idx)) | 778 | pdc_hardware_init(host, board_idx); |
| 782 | return -EIO; | ||
| 783 | 779 | ||
| 784 | ata_host_resume(host); | 780 | ata_host_resume(host); |
| 785 | return 0; | 781 | return 0; |
diff --git a/drivers/base/cacheinfo.c b/drivers/base/cacheinfo.c index eb3af2739537..07532d83be0b 100644 --- a/drivers/base/cacheinfo.c +++ b/drivers/base/cacheinfo.c | |||
| @@ -186,6 +186,11 @@ static void cache_associativity(struct cacheinfo *this_leaf) | |||
| 186 | this_leaf->ways_of_associativity = (size / nr_sets) / line_size; | 186 | this_leaf->ways_of_associativity = (size / nr_sets) / line_size; |
| 187 | } | 187 | } |
| 188 | 188 | ||
| 189 | static bool cache_node_is_unified(struct cacheinfo *this_leaf) | ||
| 190 | { | ||
| 191 | return of_property_read_bool(this_leaf->of_node, "cache-unified"); | ||
| 192 | } | ||
| 193 | |||
| 189 | static void cache_of_override_properties(unsigned int cpu) | 194 | static void cache_of_override_properties(unsigned int cpu) |
| 190 | { | 195 | { |
| 191 | int index; | 196 | int index; |
| @@ -194,6 +199,14 @@ static void cache_of_override_properties(unsigned int cpu) | |||
| 194 | 199 | ||
| 195 | for (index = 0; index < cache_leaves(cpu); index++) { | 200 | for (index = 0; index < cache_leaves(cpu); index++) { |
| 196 | this_leaf = this_cpu_ci->info_list + index; | 201 | this_leaf = this_cpu_ci->info_list + index; |
| 202 | /* | ||
| 203 | * init_cache_level must setup the cache level correctly | ||
| 204 | * overriding the architecturally specified levels, so | ||
| 205 | * if type is NONE at this stage, it should be unified | ||
| 206 | */ | ||
| 207 | if (this_leaf->type == CACHE_TYPE_NOCACHE && | ||
| 208 | cache_node_is_unified(this_leaf)) | ||
| 209 | this_leaf->type = CACHE_TYPE_UNIFIED; | ||
| 197 | cache_size(this_leaf); | 210 | cache_size(this_leaf); |
| 198 | cache_get_line_size(this_leaf); | 211 | cache_get_line_size(this_leaf); |
| 199 | cache_nr_sets(this_leaf); | 212 | cache_nr_sets(this_leaf); |
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index db2f04415927..08744b572af6 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c | |||
| @@ -526,6 +526,21 @@ static void dpm_watchdog_clear(struct dpm_watchdog *wd) | |||
| 526 | /*------------------------- Resume routines -------------------------*/ | 526 | /*------------------------- Resume routines -------------------------*/ |
| 527 | 527 | ||
| 528 | /** | 528 | /** |
| 529 | * dev_pm_skip_next_resume_phases - Skip next system resume phases for device. | ||
| 530 | * @dev: Target device. | ||
| 531 | * | ||
| 532 | * Make the core skip the "early resume" and "resume" phases for @dev. | ||
| 533 | * | ||
| 534 | * This function can be called by middle-layer code during the "noirq" phase of | ||
| 535 | * system resume if necessary, but not by device drivers. | ||
| 536 | */ | ||
| 537 | void dev_pm_skip_next_resume_phases(struct device *dev) | ||
| 538 | { | ||
| 539 | dev->power.is_late_suspended = false; | ||
| 540 | dev->power.is_suspended = false; | ||
| 541 | } | ||
| 542 | |||
| 543 | /** | ||
| 529 | * device_resume_noirq - Execute a "noirq resume" callback for given device. | 544 | * device_resume_noirq - Execute a "noirq resume" callback for given device. |
| 530 | * @dev: Device to handle. | 545 | * @dev: Device to handle. |
| 531 | * @state: PM transition of the system being carried out. | 546 | * @state: PM transition of the system being carried out. |
diff --git a/drivers/block/null_blk.c b/drivers/block/null_blk.c index ccb9975a97fa..ad0477ae820f 100644 --- a/drivers/block/null_blk.c +++ b/drivers/block/null_blk.c | |||
| @@ -35,13 +35,13 @@ static inline u64 mb_per_tick(int mbps) | |||
| 35 | struct nullb_cmd { | 35 | struct nullb_cmd { |
| 36 | struct list_head list; | 36 | struct list_head list; |
| 37 | struct llist_node ll_list; | 37 | struct llist_node ll_list; |
| 38 | call_single_data_t csd; | 38 | struct __call_single_data csd; |
| 39 | struct request *rq; | 39 | struct request *rq; |
| 40 | struct bio *bio; | 40 | struct bio *bio; |
| 41 | unsigned int tag; | 41 | unsigned int tag; |
| 42 | blk_status_t error; | ||
| 42 | struct nullb_queue *nq; | 43 | struct nullb_queue *nq; |
| 43 | struct hrtimer timer; | 44 | struct hrtimer timer; |
| 44 | blk_status_t error; | ||
| 45 | }; | 45 | }; |
| 46 | 46 | ||
| 47 | struct nullb_queue { | 47 | struct nullb_queue { |
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 779869ed32b1..71fad747c0c7 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c | |||
| @@ -199,6 +199,9 @@ struct smi_info { | |||
| 199 | /* The timer for this si. */ | 199 | /* The timer for this si. */ |
| 200 | struct timer_list si_timer; | 200 | struct timer_list si_timer; |
| 201 | 201 | ||
| 202 | /* This flag is set, if the timer can be set */ | ||
| 203 | bool timer_can_start; | ||
| 204 | |||
| 202 | /* This flag is set, if the timer is running (timer_pending() isn't enough) */ | 205 | /* This flag is set, if the timer is running (timer_pending() isn't enough) */ |
| 203 | bool timer_running; | 206 | bool timer_running; |
| 204 | 207 | ||
| @@ -355,6 +358,8 @@ out: | |||
| 355 | 358 | ||
| 356 | static void smi_mod_timer(struct smi_info *smi_info, unsigned long new_val) | 359 | static void smi_mod_timer(struct smi_info *smi_info, unsigned long new_val) |
| 357 | { | 360 | { |
| 361 | if (!smi_info->timer_can_start) | ||
| 362 | return; | ||
| 358 | smi_info->last_timeout_jiffies = jiffies; | 363 | smi_info->last_timeout_jiffies = jiffies; |
| 359 | mod_timer(&smi_info->si_timer, new_val); | 364 | mod_timer(&smi_info->si_timer, new_val); |
| 360 | smi_info->timer_running = true; | 365 | smi_info->timer_running = true; |
| @@ -374,21 +379,18 @@ static void start_new_msg(struct smi_info *smi_info, unsigned char *msg, | |||
| 374 | smi_info->handlers->start_transaction(smi_info->si_sm, msg, size); | 379 | smi_info->handlers->start_transaction(smi_info->si_sm, msg, size); |
| 375 | } | 380 | } |
| 376 | 381 | ||
| 377 | static void start_check_enables(struct smi_info *smi_info, bool start_timer) | 382 | static void start_check_enables(struct smi_info *smi_info) |
| 378 | { | 383 | { |
| 379 | unsigned char msg[2]; | 384 | unsigned char msg[2]; |
| 380 | 385 | ||
| 381 | msg[0] = (IPMI_NETFN_APP_REQUEST << 2); | 386 | msg[0] = (IPMI_NETFN_APP_REQUEST << 2); |
| 382 | msg[1] = IPMI_GET_BMC_GLOBAL_ENABLES_CMD; | 387 | msg[1] = IPMI_GET_BMC_GLOBAL_ENABLES_CMD; |
| 383 | 388 | ||
| 384 | if (start_timer) | 389 | start_new_msg(smi_info, msg, 2); |
| 385 | start_new_msg(smi_info, msg, 2); | ||
| 386 | else | ||
| 387 | smi_info->handlers->start_transaction(smi_info->si_sm, msg, 2); | ||
| 388 | smi_info->si_state = SI_CHECKING_ENABLES; | 390 | smi_info->si_state = SI_CHECKING_ENABLES; |
| 389 | } | 391 | } |
| 390 | 392 | ||
| 391 | static void start_clear_flags(struct smi_info *smi_info, bool start_timer) | 393 | static void start_clear_flags(struct smi_info *smi_info) |
| 392 | { | 394 | { |
| 393 | unsigned char msg[3]; | 395 | unsigned char msg[3]; |
| 394 | 396 | ||
| @@ -397,10 +399,7 @@ static void start_clear_flags(struct smi_info *smi_info, bool start_timer) | |||
| 397 | msg[1] = IPMI_CLEAR_MSG_FLAGS_CMD; | 399 | msg[1] = IPMI_CLEAR_MSG_FLAGS_CMD; |
| 398 | msg[2] = WDT_PRE_TIMEOUT_INT; | 400 | msg[2] = WDT_PRE_TIMEOUT_INT; |
| 399 | 401 | ||
| 400 | if (start_timer) | 402 | start_new_msg(smi_info, msg, 3); |
| 401 | start_new_msg(smi_info, msg, 3); | ||
| 402 | else | ||
| 403 | smi_info->handlers->start_transaction(smi_info->si_sm, msg, 3); | ||
| 404 | smi_info->si_state = SI_CLEARING_FLAGS; | 403 | smi_info->si_state = SI_CLEARING_FLAGS; |
| 405 | } | 404 | } |
| 406 | 405 | ||
| @@ -435,11 +434,11 @@ static void start_getting_events(struct smi_info *smi_info) | |||
| 435 | * Note that we cannot just use disable_irq(), since the interrupt may | 434 | * Note that we cannot just use disable_irq(), since the interrupt may |
| 436 | * be shared. | 435 | * be shared. |
| 437 | */ | 436 | */ |
| 438 | static inline bool disable_si_irq(struct smi_info *smi_info, bool start_timer) | 437 | static inline bool disable_si_irq(struct smi_info *smi_info) |
| 439 | { | 438 | { |
| 440 | if ((smi_info->io.irq) && (!smi_info->interrupt_disabled)) { | 439 | if ((smi_info->io.irq) && (!smi_info->interrupt_disabled)) { |
| 441 | smi_info->interrupt_disabled = true; | 440 | smi_info->interrupt_disabled = true; |
| 442 | start_check_enables(smi_info, start_timer); | 441 | start_check_enables(smi_info); |
| 443 | return true; | 442 | return true; |
| 444 | } | 443 | } |
| 445 | return false; | 444 | return false; |
| @@ -449,7 +448,7 @@ static inline bool enable_si_irq(struct smi_info *smi_info) | |||
| 449 | { | 448 | { |
| 450 | if ((smi_info->io.irq) && (smi_info->interrupt_disabled)) { | 449 | if ((smi_info->io.irq) && (smi_info->interrupt_disabled)) { |
| 451 | smi_info->interrupt_disabled = false; | 450 | smi_info->interrupt_disabled = false; |
| 452 | start_check_enables(smi_info, true); | 451 | start_check_enables(smi_info); |
| 453 | return true; | 452 | return true; |
| 454 | } | 453 | } |
| 455 | return false; | 454 | return false; |
| @@ -467,7 +466,7 @@ static struct ipmi_smi_msg *alloc_msg_handle_irq(struct smi_info *smi_info) | |||
| 467 | 466 | ||
| 468 | msg = ipmi_alloc_smi_msg(); | 467 | msg = ipmi_alloc_smi_msg(); |
| 469 | if (!msg) { | 468 | if (!msg) { |
| 470 | if (!disable_si_irq(smi_info, true)) | 469 | if (!disable_si_irq(smi_info)) |
| 471 | smi_info->si_state = SI_NORMAL; | 470 | smi_info->si_state = SI_NORMAL; |
| 472 | } else if (enable_si_irq(smi_info)) { | 471 | } else if (enable_si_irq(smi_info)) { |
| 473 | ipmi_free_smi_msg(msg); | 472 | ipmi_free_smi_msg(msg); |
| @@ -483,7 +482,7 @@ retry: | |||
| 483 | /* Watchdog pre-timeout */ | 482 | /* Watchdog pre-timeout */ |
| 484 | smi_inc_stat(smi_info, watchdog_pretimeouts); | 483 | smi_inc_stat(smi_info, watchdog_pretimeouts); |
| 485 | 484 | ||
| 486 | start_clear_flags(smi_info, true); | 485 | start_clear_flags(smi_info); |
| 487 | smi_info->msg_flags &= ~WDT_PRE_TIMEOUT_INT; | 486 | smi_info->msg_flags &= ~WDT_PRE_TIMEOUT_INT; |
| 488 | if (smi_info->intf) | 487 | if (smi_info->intf) |
| 489 | ipmi_smi_watchdog_pretimeout(smi_info->intf); | 488 | ipmi_smi_watchdog_pretimeout(smi_info->intf); |
| @@ -866,7 +865,7 @@ restart: | |||
| 866 | * disable and messages disabled. | 865 | * disable and messages disabled. |
| 867 | */ | 866 | */ |
| 868 | if (smi_info->supports_event_msg_buff || smi_info->io.irq) { | 867 | if (smi_info->supports_event_msg_buff || smi_info->io.irq) { |
| 869 | start_check_enables(smi_info, true); | 868 | start_check_enables(smi_info); |
| 870 | } else { | 869 | } else { |
| 871 | smi_info->curr_msg = alloc_msg_handle_irq(smi_info); | 870 | smi_info->curr_msg = alloc_msg_handle_irq(smi_info); |
| 872 | if (!smi_info->curr_msg) | 871 | if (!smi_info->curr_msg) |
| @@ -1167,6 +1166,7 @@ static int smi_start_processing(void *send_info, | |||
| 1167 | 1166 | ||
| 1168 | /* Set up the timer that drives the interface. */ | 1167 | /* Set up the timer that drives the interface. */ |
| 1169 | timer_setup(&new_smi->si_timer, smi_timeout, 0); | 1168 | timer_setup(&new_smi->si_timer, smi_timeout, 0); |
| 1169 | new_smi->timer_can_start = true; | ||
| 1170 | smi_mod_timer(new_smi, jiffies + SI_TIMEOUT_JIFFIES); | 1170 | smi_mod_timer(new_smi, jiffies + SI_TIMEOUT_JIFFIES); |
| 1171 | 1171 | ||
| 1172 | /* Try to claim any interrupts. */ | 1172 | /* Try to claim any interrupts. */ |
| @@ -1936,10 +1936,12 @@ static void check_for_broken_irqs(struct smi_info *smi_info) | |||
| 1936 | check_set_rcv_irq(smi_info); | 1936 | check_set_rcv_irq(smi_info); |
| 1937 | } | 1937 | } |
| 1938 | 1938 | ||
| 1939 | static inline void wait_for_timer_and_thread(struct smi_info *smi_info) | 1939 | static inline void stop_timer_and_thread(struct smi_info *smi_info) |
| 1940 | { | 1940 | { |
| 1941 | if (smi_info->thread != NULL) | 1941 | if (smi_info->thread != NULL) |
| 1942 | kthread_stop(smi_info->thread); | 1942 | kthread_stop(smi_info->thread); |
| 1943 | |||
| 1944 | smi_info->timer_can_start = false; | ||
| 1943 | if (smi_info->timer_running) | 1945 | if (smi_info->timer_running) |
| 1944 | del_timer_sync(&smi_info->si_timer); | 1946 | del_timer_sync(&smi_info->si_timer); |
| 1945 | } | 1947 | } |
| @@ -2152,7 +2154,7 @@ static int try_smi_init(struct smi_info *new_smi) | |||
| 2152 | * Start clearing the flags before we enable interrupts or the | 2154 | * Start clearing the flags before we enable interrupts or the |
| 2153 | * timer to avoid racing with the timer. | 2155 | * timer to avoid racing with the timer. |
| 2154 | */ | 2156 | */ |
| 2155 | start_clear_flags(new_smi, false); | 2157 | start_clear_flags(new_smi); |
| 2156 | 2158 | ||
| 2157 | /* | 2159 | /* |
| 2158 | * IRQ is defined to be set when non-zero. req_events will | 2160 | * IRQ is defined to be set when non-zero. req_events will |
| @@ -2238,7 +2240,7 @@ out_err_remove_attrs: | |||
| 2238 | dev_set_drvdata(new_smi->io.dev, NULL); | 2240 | dev_set_drvdata(new_smi->io.dev, NULL); |
| 2239 | 2241 | ||
| 2240 | out_err_stop_timer: | 2242 | out_err_stop_timer: |
| 2241 | wait_for_timer_and_thread(new_smi); | 2243 | stop_timer_and_thread(new_smi); |
| 2242 | 2244 | ||
| 2243 | out_err: | 2245 | out_err: |
| 2244 | new_smi->interrupt_disabled = true; | 2246 | new_smi->interrupt_disabled = true; |
| @@ -2388,7 +2390,7 @@ static void cleanup_one_si(struct smi_info *to_clean) | |||
| 2388 | */ | 2390 | */ |
| 2389 | if (to_clean->io.irq_cleanup) | 2391 | if (to_clean->io.irq_cleanup) |
| 2390 | to_clean->io.irq_cleanup(&to_clean->io); | 2392 | to_clean->io.irq_cleanup(&to_clean->io); |
| 2391 | wait_for_timer_and_thread(to_clean); | 2393 | stop_timer_and_thread(to_clean); |
| 2392 | 2394 | ||
| 2393 | /* | 2395 | /* |
| 2394 | * Timeouts are stopped, now make sure the interrupts are off | 2396 | * Timeouts are stopped, now make sure the interrupts are off |
| @@ -2400,7 +2402,7 @@ static void cleanup_one_si(struct smi_info *to_clean) | |||
| 2400 | schedule_timeout_uninterruptible(1); | 2402 | schedule_timeout_uninterruptible(1); |
| 2401 | } | 2403 | } |
| 2402 | if (to_clean->handlers) | 2404 | if (to_clean->handlers) |
| 2403 | disable_si_irq(to_clean, false); | 2405 | disable_si_irq(to_clean); |
| 2404 | while (to_clean->curr_msg || (to_clean->si_state != SI_NORMAL)) { | 2406 | while (to_clean->curr_msg || (to_clean->si_state != SI_NORMAL)) { |
| 2405 | poll(to_clean); | 2407 | poll(to_clean); |
| 2406 | schedule_timeout_uninterruptible(1); | 2408 | schedule_timeout_uninterruptible(1); |
diff --git a/drivers/char/ipmi/ipmi_si_parisc.c b/drivers/char/ipmi/ipmi_si_parisc.c index 090b073ab441..6b10f0e18a95 100644 --- a/drivers/char/ipmi/ipmi_si_parisc.c +++ b/drivers/char/ipmi/ipmi_si_parisc.c | |||
| @@ -10,6 +10,8 @@ static int __init ipmi_parisc_probe(struct parisc_device *dev) | |||
| 10 | { | 10 | { |
| 11 | struct si_sm_io io; | 11 | struct si_sm_io io; |
| 12 | 12 | ||
| 13 | memset(&io, 0, sizeof(io)); | ||
| 14 | |||
| 13 | io.si_type = SI_KCS; | 15 | io.si_type = SI_KCS; |
| 14 | io.addr_source = SI_DEVICETREE; | 16 | io.addr_source = SI_DEVICETREE; |
| 15 | io.addr_type = IPMI_MEM_ADDR_SPACE; | 17 | io.addr_type = IPMI_MEM_ADDR_SPACE; |
diff --git a/drivers/char/ipmi/ipmi_si_pci.c b/drivers/char/ipmi/ipmi_si_pci.c index 99771f5cad07..27dd11c49d21 100644 --- a/drivers/char/ipmi/ipmi_si_pci.c +++ b/drivers/char/ipmi/ipmi_si_pci.c | |||
| @@ -103,10 +103,13 @@ static int ipmi_pci_probe(struct pci_dev *pdev, | |||
| 103 | io.addr_source_cleanup = ipmi_pci_cleanup; | 103 | io.addr_source_cleanup = ipmi_pci_cleanup; |
| 104 | io.addr_source_data = pdev; | 104 | io.addr_source_data = pdev; |
| 105 | 105 | ||
| 106 | if (pci_resource_flags(pdev, 0) & IORESOURCE_IO) | 106 | if (pci_resource_flags(pdev, 0) & IORESOURCE_IO) { |
| 107 | io.addr_type = IPMI_IO_ADDR_SPACE; | 107 | io.addr_type = IPMI_IO_ADDR_SPACE; |
| 108 | else | 108 | io.io_setup = ipmi_si_port_setup; |
| 109 | } else { | ||
| 109 | io.addr_type = IPMI_MEM_ADDR_SPACE; | 110 | io.addr_type = IPMI_MEM_ADDR_SPACE; |
| 111 | io.io_setup = ipmi_si_mem_setup; | ||
| 112 | } | ||
| 110 | io.addr_data = pci_resource_start(pdev, 0); | 113 | io.addr_data = pci_resource_start(pdev, 0); |
| 111 | 114 | ||
| 112 | io.regspacing = ipmi_pci_probe_regspacing(&io); | 115 | io.regspacing = ipmi_pci_probe_regspacing(&io); |
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 647d056df88c..b56c11f51baf 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c | |||
| @@ -220,7 +220,8 @@ static bool clk_core_is_enabled(struct clk_core *core) | |||
| 220 | 220 | ||
| 221 | ret = core->ops->is_enabled(core->hw); | 221 | ret = core->ops->is_enabled(core->hw); |
| 222 | done: | 222 | done: |
| 223 | clk_pm_runtime_put(core); | 223 | if (core->dev) |
| 224 | pm_runtime_put(core->dev); | ||
| 224 | 225 | ||
| 225 | return ret; | 226 | return ret; |
| 226 | } | 227 | } |
| @@ -1564,6 +1565,9 @@ static void clk_change_rate(struct clk_core *core) | |||
| 1564 | best_parent_rate = core->parent->rate; | 1565 | best_parent_rate = core->parent->rate; |
| 1565 | } | 1566 | } |
| 1566 | 1567 | ||
| 1568 | if (clk_pm_runtime_get(core)) | ||
| 1569 | return; | ||
| 1570 | |||
| 1567 | if (core->flags & CLK_SET_RATE_UNGATE) { | 1571 | if (core->flags & CLK_SET_RATE_UNGATE) { |
| 1568 | unsigned long flags; | 1572 | unsigned long flags; |
| 1569 | 1573 | ||
| @@ -1634,6 +1638,8 @@ static void clk_change_rate(struct clk_core *core) | |||
| 1634 | /* handle the new child who might not be in core->children yet */ | 1638 | /* handle the new child who might not be in core->children yet */ |
| 1635 | if (core->new_child) | 1639 | if (core->new_child) |
| 1636 | clk_change_rate(core->new_child); | 1640 | clk_change_rate(core->new_child); |
| 1641 | |||
| 1642 | clk_pm_runtime_put(core); | ||
| 1637 | } | 1643 | } |
| 1638 | 1644 | ||
| 1639 | static int clk_core_set_rate_nolock(struct clk_core *core, | 1645 | static int clk_core_set_rate_nolock(struct clk_core *core, |
diff --git a/drivers/clk/sunxi/clk-sun9i-mmc.c b/drivers/clk/sunxi/clk-sun9i-mmc.c index a1a634253d6f..f00d8758ba24 100644 --- a/drivers/clk/sunxi/clk-sun9i-mmc.c +++ b/drivers/clk/sunxi/clk-sun9i-mmc.c | |||
| @@ -16,6 +16,7 @@ | |||
| 16 | 16 | ||
| 17 | #include <linux/clk.h> | 17 | #include <linux/clk.h> |
| 18 | #include <linux/clk-provider.h> | 18 | #include <linux/clk-provider.h> |
| 19 | #include <linux/delay.h> | ||
| 19 | #include <linux/init.h> | 20 | #include <linux/init.h> |
| 20 | #include <linux/of.h> | 21 | #include <linux/of.h> |
| 21 | #include <linux/of_device.h> | 22 | #include <linux/of_device.h> |
| @@ -83,9 +84,20 @@ static int sun9i_mmc_reset_deassert(struct reset_controller_dev *rcdev, | |||
| 83 | return 0; | 84 | return 0; |
| 84 | } | 85 | } |
| 85 | 86 | ||
| 87 | static int sun9i_mmc_reset_reset(struct reset_controller_dev *rcdev, | ||
| 88 | unsigned long id) | ||
| 89 | { | ||
| 90 | sun9i_mmc_reset_assert(rcdev, id); | ||
| 91 | udelay(10); | ||
| 92 | sun9i_mmc_reset_deassert(rcdev, id); | ||
| 93 | |||
| 94 | return 0; | ||
| 95 | } | ||
| 96 | |||
| 86 | static const struct reset_control_ops sun9i_mmc_reset_ops = { | 97 | static const struct reset_control_ops sun9i_mmc_reset_ops = { |
| 87 | .assert = sun9i_mmc_reset_assert, | 98 | .assert = sun9i_mmc_reset_assert, |
| 88 | .deassert = sun9i_mmc_reset_deassert, | 99 | .deassert = sun9i_mmc_reset_deassert, |
| 100 | .reset = sun9i_mmc_reset_reset, | ||
| 89 | }; | 101 | }; |
| 90 | 102 | ||
| 91 | static int sun9i_a80_mmc_config_clk_probe(struct platform_device *pdev) | 103 | static int sun9i_a80_mmc_config_clk_probe(struct platform_device *pdev) |
diff --git a/drivers/cpufreq/cpufreq_governor.c b/drivers/cpufreq/cpufreq_governor.c index 58d4f4e1ad6a..ca38229b045a 100644 --- a/drivers/cpufreq/cpufreq_governor.c +++ b/drivers/cpufreq/cpufreq_governor.c | |||
| @@ -22,6 +22,8 @@ | |||
| 22 | 22 | ||
| 23 | #include "cpufreq_governor.h" | 23 | #include "cpufreq_governor.h" |
| 24 | 24 | ||
| 25 | #define CPUFREQ_DBS_MIN_SAMPLING_INTERVAL (2 * TICK_NSEC / NSEC_PER_USEC) | ||
| 26 | |||
| 25 | static DEFINE_PER_CPU(struct cpu_dbs_info, cpu_dbs); | 27 | static DEFINE_PER_CPU(struct cpu_dbs_info, cpu_dbs); |
| 26 | 28 | ||
| 27 | static DEFINE_MUTEX(gov_dbs_data_mutex); | 29 | static DEFINE_MUTEX(gov_dbs_data_mutex); |
| @@ -47,11 +49,15 @@ ssize_t store_sampling_rate(struct gov_attr_set *attr_set, const char *buf, | |||
| 47 | { | 49 | { |
| 48 | struct dbs_data *dbs_data = to_dbs_data(attr_set); | 50 | struct dbs_data *dbs_data = to_dbs_data(attr_set); |
| 49 | struct policy_dbs_info *policy_dbs; | 51 | struct policy_dbs_info *policy_dbs; |
| 52 | unsigned int sampling_interval; | ||
| 50 | int ret; | 53 | int ret; |
| 51 | ret = sscanf(buf, "%u", &dbs_data->sampling_rate); | 54 | |
| 52 | if (ret != 1) | 55 | ret = sscanf(buf, "%u", &sampling_interval); |
| 56 | if (ret != 1 || sampling_interval < CPUFREQ_DBS_MIN_SAMPLING_INTERVAL) | ||
| 53 | return -EINVAL; | 57 | return -EINVAL; |
| 54 | 58 | ||
| 59 | dbs_data->sampling_rate = sampling_interval; | ||
| 60 | |||
| 55 | /* | 61 | /* |
| 56 | * We are operating under dbs_data->mutex and so the list and its | 62 | * We are operating under dbs_data->mutex and so the list and its |
| 57 | * entries can't be freed concurrently. | 63 | * entries can't be freed concurrently. |
| @@ -430,7 +436,14 @@ int cpufreq_dbs_governor_init(struct cpufreq_policy *policy) | |||
| 430 | if (ret) | 436 | if (ret) |
| 431 | goto free_policy_dbs_info; | 437 | goto free_policy_dbs_info; |
| 432 | 438 | ||
| 433 | dbs_data->sampling_rate = cpufreq_policy_transition_delay_us(policy); | 439 | /* |
| 440 | * The sampling interval should not be less than the transition latency | ||
| 441 | * of the CPU and it also cannot be too small for dbs_update() to work | ||
| 442 | * correctly. | ||
| 443 | */ | ||
| 444 | dbs_data->sampling_rate = max_t(unsigned int, | ||
| 445 | CPUFREQ_DBS_MIN_SAMPLING_INTERVAL, | ||
| 446 | cpufreq_policy_transition_delay_us(policy)); | ||
| 434 | 447 | ||
| 435 | if (!have_governor_per_policy()) | 448 | if (!have_governor_per_policy()) |
| 436 | gov->gdbs_data = dbs_data; | 449 | gov->gdbs_data = dbs_data; |
diff --git a/drivers/cpufreq/imx6q-cpufreq.c b/drivers/cpufreq/imx6q-cpufreq.c index 628fe899cb48..d9b2c2de49c4 100644 --- a/drivers/cpufreq/imx6q-cpufreq.c +++ b/drivers/cpufreq/imx6q-cpufreq.c | |||
| @@ -226,17 +226,18 @@ static void imx6q_opp_check_speed_grading(struct device *dev) | |||
| 226 | val >>= OCOTP_CFG3_SPEED_SHIFT; | 226 | val >>= OCOTP_CFG3_SPEED_SHIFT; |
| 227 | val &= 0x3; | 227 | val &= 0x3; |
| 228 | 228 | ||
| 229 | if ((val != OCOTP_CFG3_SPEED_1P2GHZ) && | ||
| 230 | of_machine_is_compatible("fsl,imx6q")) | ||
| 231 | if (dev_pm_opp_disable(dev, 1200000000)) | ||
| 232 | dev_warn(dev, "failed to disable 1.2GHz OPP\n"); | ||
| 233 | if (val < OCOTP_CFG3_SPEED_996MHZ) | 229 | if (val < OCOTP_CFG3_SPEED_996MHZ) |
| 234 | if (dev_pm_opp_disable(dev, 996000000)) | 230 | if (dev_pm_opp_disable(dev, 996000000)) |
| 235 | dev_warn(dev, "failed to disable 996MHz OPP\n"); | 231 | dev_warn(dev, "failed to disable 996MHz OPP\n"); |
| 236 | if (of_machine_is_compatible("fsl,imx6q")) { | 232 | |
| 233 | if (of_machine_is_compatible("fsl,imx6q") || | ||
| 234 | of_machine_is_compatible("fsl,imx6qp")) { | ||
| 237 | if (val != OCOTP_CFG3_SPEED_852MHZ) | 235 | if (val != OCOTP_CFG3_SPEED_852MHZ) |
| 238 | if (dev_pm_opp_disable(dev, 852000000)) | 236 | if (dev_pm_opp_disable(dev, 852000000)) |
| 239 | dev_warn(dev, "failed to disable 852MHz OPP\n"); | 237 | dev_warn(dev, "failed to disable 852MHz OPP\n"); |
| 238 | if (val != OCOTP_CFG3_SPEED_1P2GHZ) | ||
| 239 | if (dev_pm_opp_disable(dev, 1200000000)) | ||
| 240 | dev_warn(dev, "failed to disable 1.2GHz OPP\n"); | ||
| 240 | } | 241 | } |
| 241 | iounmap(base); | 242 | iounmap(base); |
| 242 | put_node: | 243 | put_node: |
diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c index fbab271b3bf9..a861b5b4d443 100644 --- a/drivers/dma/at_hdmac.c +++ b/drivers/dma/at_hdmac.c | |||
| @@ -708,7 +708,7 @@ atc_prep_dma_interleaved(struct dma_chan *chan, | |||
| 708 | unsigned long flags) | 708 | unsigned long flags) |
| 709 | { | 709 | { |
| 710 | struct at_dma_chan *atchan = to_at_dma_chan(chan); | 710 | struct at_dma_chan *atchan = to_at_dma_chan(chan); |
| 711 | struct data_chunk *first = xt->sgl; | 711 | struct data_chunk *first; |
| 712 | struct at_desc *desc = NULL; | 712 | struct at_desc *desc = NULL; |
| 713 | size_t xfer_count; | 713 | size_t xfer_count; |
| 714 | unsigned int dwidth; | 714 | unsigned int dwidth; |
| @@ -720,6 +720,8 @@ atc_prep_dma_interleaved(struct dma_chan *chan, | |||
| 720 | if (unlikely(!xt || xt->numf != 1 || !xt->frame_size)) | 720 | if (unlikely(!xt || xt->numf != 1 || !xt->frame_size)) |
| 721 | return NULL; | 721 | return NULL; |
| 722 | 722 | ||
| 723 | first = xt->sgl; | ||
| 724 | |||
| 723 | dev_info(chan2dev(chan), | 725 | dev_info(chan2dev(chan), |
| 724 | "%s: src=%pad, dest=%pad, numf=%d, frame_size=%d, flags=0x%lx\n", | 726 | "%s: src=%pad, dest=%pad, numf=%d, frame_size=%d, flags=0x%lx\n", |
| 725 | __func__, &xt->src_start, &xt->dst_start, xt->numf, | 727 | __func__, &xt->src_start, &xt->dst_start, xt->numf, |
diff --git a/drivers/dma/dma-jz4740.c b/drivers/dma/dma-jz4740.c index d50273fed715..afd5e10f8927 100644 --- a/drivers/dma/dma-jz4740.c +++ b/drivers/dma/dma-jz4740.c | |||
| @@ -555,7 +555,7 @@ static int jz4740_dma_probe(struct platform_device *pdev) | |||
| 555 | 555 | ||
| 556 | ret = dma_async_device_register(dd); | 556 | ret = dma_async_device_register(dd); |
| 557 | if (ret) | 557 | if (ret) |
| 558 | return ret; | 558 | goto err_clk; |
| 559 | 559 | ||
| 560 | irq = platform_get_irq(pdev, 0); | 560 | irq = platform_get_irq(pdev, 0); |
| 561 | ret = request_irq(irq, jz4740_dma_irq, 0, dev_name(&pdev->dev), dmadev); | 561 | ret = request_irq(irq, jz4740_dma_irq, 0, dev_name(&pdev->dev), dmadev); |
| @@ -568,6 +568,8 @@ static int jz4740_dma_probe(struct platform_device *pdev) | |||
| 568 | 568 | ||
| 569 | err_unregister: | 569 | err_unregister: |
| 570 | dma_async_device_unregister(dd); | 570 | dma_async_device_unregister(dd); |
| 571 | err_clk: | ||
| 572 | clk_disable_unprepare(dmadev->clk); | ||
| 571 | return ret; | 573 | return ret; |
| 572 | } | 574 | } |
| 573 | 575 | ||
diff --git a/drivers/dma/dmatest.c b/drivers/dma/dmatest.c index 47edc7fbf91f..ec5f9d2bc820 100644 --- a/drivers/dma/dmatest.c +++ b/drivers/dma/dmatest.c | |||
| @@ -155,6 +155,12 @@ MODULE_PARM_DESC(run, "Run the test (default: false)"); | |||
| 155 | #define PATTERN_COUNT_MASK 0x1f | 155 | #define PATTERN_COUNT_MASK 0x1f |
| 156 | #define PATTERN_MEMSET_IDX 0x01 | 156 | #define PATTERN_MEMSET_IDX 0x01 |
| 157 | 157 | ||
| 158 | /* poor man's completion - we want to use wait_event_freezable() on it */ | ||
| 159 | struct dmatest_done { | ||
| 160 | bool done; | ||
| 161 | wait_queue_head_t *wait; | ||
| 162 | }; | ||
| 163 | |||
| 158 | struct dmatest_thread { | 164 | struct dmatest_thread { |
| 159 | struct list_head node; | 165 | struct list_head node; |
| 160 | struct dmatest_info *info; | 166 | struct dmatest_info *info; |
| @@ -165,6 +171,8 @@ struct dmatest_thread { | |||
| 165 | u8 **dsts; | 171 | u8 **dsts; |
| 166 | u8 **udsts; | 172 | u8 **udsts; |
| 167 | enum dma_transaction_type type; | 173 | enum dma_transaction_type type; |
| 174 | wait_queue_head_t done_wait; | ||
| 175 | struct dmatest_done test_done; | ||
| 168 | bool done; | 176 | bool done; |
| 169 | }; | 177 | }; |
| 170 | 178 | ||
| @@ -342,18 +350,25 @@ static unsigned int dmatest_verify(u8 **bufs, unsigned int start, | |||
| 342 | return error_count; | 350 | return error_count; |
| 343 | } | 351 | } |
| 344 | 352 | ||
| 345 | /* poor man's completion - we want to use wait_event_freezable() on it */ | ||
| 346 | struct dmatest_done { | ||
| 347 | bool done; | ||
| 348 | wait_queue_head_t *wait; | ||
| 349 | }; | ||
| 350 | 353 | ||
| 351 | static void dmatest_callback(void *arg) | 354 | static void dmatest_callback(void *arg) |
| 352 | { | 355 | { |
| 353 | struct dmatest_done *done = arg; | 356 | struct dmatest_done *done = arg; |
| 354 | 357 | struct dmatest_thread *thread = | |
| 355 | done->done = true; | 358 | container_of(arg, struct dmatest_thread, done_wait); |
| 356 | wake_up_all(done->wait); | 359 | if (!thread->done) { |
| 360 | done->done = true; | ||
| 361 | wake_up_all(done->wait); | ||
| 362 | } else { | ||
| 363 | /* | ||
| 364 | * If thread->done, it means that this callback occurred | ||
| 365 | * after the parent thread has cleaned up. This can | ||
| 366 | * happen in the case that driver doesn't implement | ||
| 367 | * the terminate_all() functionality and a dma operation | ||
| 368 | * did not occur within the timeout period | ||
| 369 | */ | ||
| 370 | WARN(1, "dmatest: Kernel memory may be corrupted!!\n"); | ||
| 371 | } | ||
| 357 | } | 372 | } |
| 358 | 373 | ||
| 359 | static unsigned int min_odd(unsigned int x, unsigned int y) | 374 | static unsigned int min_odd(unsigned int x, unsigned int y) |
| @@ -424,9 +439,8 @@ static unsigned long long dmatest_KBs(s64 runtime, unsigned long long len) | |||
| 424 | */ | 439 | */ |
| 425 | static int dmatest_func(void *data) | 440 | static int dmatest_func(void *data) |
| 426 | { | 441 | { |
| 427 | DECLARE_WAIT_QUEUE_HEAD_ONSTACK(done_wait); | ||
| 428 | struct dmatest_thread *thread = data; | 442 | struct dmatest_thread *thread = data; |
| 429 | struct dmatest_done done = { .wait = &done_wait }; | 443 | struct dmatest_done *done = &thread->test_done; |
| 430 | struct dmatest_info *info; | 444 | struct dmatest_info *info; |
| 431 | struct dmatest_params *params; | 445 | struct dmatest_params *params; |
| 432 | struct dma_chan *chan; | 446 | struct dma_chan *chan; |
| @@ -673,9 +687,9 @@ static int dmatest_func(void *data) | |||
| 673 | continue; | 687 | continue; |
| 674 | } | 688 | } |
| 675 | 689 | ||
| 676 | done.done = false; | 690 | done->done = false; |
| 677 | tx->callback = dmatest_callback; | 691 | tx->callback = dmatest_callback; |
| 678 | tx->callback_param = &done; | 692 | tx->callback_param = done; |
| 679 | cookie = tx->tx_submit(tx); | 693 | cookie = tx->tx_submit(tx); |
| 680 | 694 | ||
| 681 | if (dma_submit_error(cookie)) { | 695 | if (dma_submit_error(cookie)) { |
| @@ -688,21 +702,12 @@ static int dmatest_func(void *data) | |||
| 688 | } | 702 | } |
| 689 | dma_async_issue_pending(chan); | 703 | dma_async_issue_pending(chan); |
| 690 | 704 | ||
| 691 | wait_event_freezable_timeout(done_wait, done.done, | 705 | wait_event_freezable_timeout(thread->done_wait, done->done, |
| 692 | msecs_to_jiffies(params->timeout)); | 706 | msecs_to_jiffies(params->timeout)); |
| 693 | 707 | ||
| 694 | status = dma_async_is_tx_complete(chan, cookie, NULL, NULL); | 708 | status = dma_async_is_tx_complete(chan, cookie, NULL, NULL); |
| 695 | 709 | ||
| 696 | if (!done.done) { | 710 | if (!done->done) { |
| 697 | /* | ||
| 698 | * We're leaving the timed out dma operation with | ||
| 699 | * dangling pointer to done_wait. To make this | ||
| 700 | * correct, we'll need to allocate wait_done for | ||
| 701 | * each test iteration and perform "who's gonna | ||
| 702 | * free it this time?" dancing. For now, just | ||
| 703 | * leave it dangling. | ||
| 704 | */ | ||
| 705 | WARN(1, "dmatest: Kernel stack may be corrupted!!\n"); | ||
| 706 | dmaengine_unmap_put(um); | 711 | dmaengine_unmap_put(um); |
| 707 | result("test timed out", total_tests, src_off, dst_off, | 712 | result("test timed out", total_tests, src_off, dst_off, |
| 708 | len, 0); | 713 | len, 0); |
| @@ -789,7 +794,7 @@ err_thread_type: | |||
| 789 | dmatest_KBs(runtime, total_len), ret); | 794 | dmatest_KBs(runtime, total_len), ret); |
| 790 | 795 | ||
| 791 | /* terminate all transfers on specified channels */ | 796 | /* terminate all transfers on specified channels */ |
| 792 | if (ret) | 797 | if (ret || failed_tests) |
| 793 | dmaengine_terminate_all(chan); | 798 | dmaengine_terminate_all(chan); |
| 794 | 799 | ||
| 795 | thread->done = true; | 800 | thread->done = true; |
| @@ -849,6 +854,8 @@ static int dmatest_add_threads(struct dmatest_info *info, | |||
| 849 | thread->info = info; | 854 | thread->info = info; |
| 850 | thread->chan = dtc->chan; | 855 | thread->chan = dtc->chan; |
| 851 | thread->type = type; | 856 | thread->type = type; |
| 857 | thread->test_done.wait = &thread->done_wait; | ||
| 858 | init_waitqueue_head(&thread->done_wait); | ||
| 852 | smp_wmb(); | 859 | smp_wmb(); |
| 853 | thread->task = kthread_create(dmatest_func, thread, "%s-%s%u", | 860 | thread->task = kthread_create(dmatest_func, thread, "%s-%s%u", |
| 854 | dma_chan_name(chan), op, i); | 861 | dma_chan_name(chan), op, i); |
diff --git a/drivers/dma/fsl-edma.c b/drivers/dma/fsl-edma.c index 6775f2c74e25..c7568869284e 100644 --- a/drivers/dma/fsl-edma.c +++ b/drivers/dma/fsl-edma.c | |||
| @@ -863,11 +863,11 @@ static void fsl_edma_irq_exit( | |||
| 863 | } | 863 | } |
| 864 | } | 864 | } |
| 865 | 865 | ||
| 866 | static void fsl_disable_clocks(struct fsl_edma_engine *fsl_edma) | 866 | static void fsl_disable_clocks(struct fsl_edma_engine *fsl_edma, int nr_clocks) |
| 867 | { | 867 | { |
| 868 | int i; | 868 | int i; |
| 869 | 869 | ||
| 870 | for (i = 0; i < DMAMUX_NR; i++) | 870 | for (i = 0; i < nr_clocks; i++) |
| 871 | clk_disable_unprepare(fsl_edma->muxclk[i]); | 871 | clk_disable_unprepare(fsl_edma->muxclk[i]); |
| 872 | } | 872 | } |
| 873 | 873 | ||
| @@ -904,25 +904,25 @@ static int fsl_edma_probe(struct platform_device *pdev) | |||
| 904 | 904 | ||
| 905 | res = platform_get_resource(pdev, IORESOURCE_MEM, 1 + i); | 905 | res = platform_get_resource(pdev, IORESOURCE_MEM, 1 + i); |
| 906 | fsl_edma->muxbase[i] = devm_ioremap_resource(&pdev->dev, res); | 906 | fsl_edma->muxbase[i] = devm_ioremap_resource(&pdev->dev, res); |
| 907 | if (IS_ERR(fsl_edma->muxbase[i])) | 907 | if (IS_ERR(fsl_edma->muxbase[i])) { |
| 908 | /* on error: disable all previously enabled clks */ | ||
| 909 | fsl_disable_clocks(fsl_edma, i); | ||
| 908 | return PTR_ERR(fsl_edma->muxbase[i]); | 910 | return PTR_ERR(fsl_edma->muxbase[i]); |
| 911 | } | ||
| 909 | 912 | ||
| 910 | sprintf(clkname, "dmamux%d", i); | 913 | sprintf(clkname, "dmamux%d", i); |
| 911 | fsl_edma->muxclk[i] = devm_clk_get(&pdev->dev, clkname); | 914 | fsl_edma->muxclk[i] = devm_clk_get(&pdev->dev, clkname); |
| 912 | if (IS_ERR(fsl_edma->muxclk[i])) { | 915 | if (IS_ERR(fsl_edma->muxclk[i])) { |
| 913 | dev_err(&pdev->dev, "Missing DMAMUX block clock.\n"); | 916 | dev_err(&pdev->dev, "Missing DMAMUX block clock.\n"); |
| 917 | /* on error: disable all previously enabled clks */ | ||
| 918 | fsl_disable_clocks(fsl_edma, i); | ||
| 914 | return PTR_ERR(fsl_edma->muxclk[i]); | 919 | return PTR_ERR(fsl_edma->muxclk[i]); |
| 915 | } | 920 | } |
| 916 | 921 | ||
| 917 | ret = clk_prepare_enable(fsl_edma->muxclk[i]); | 922 | ret = clk_prepare_enable(fsl_edma->muxclk[i]); |
| 918 | if (ret) { | 923 | if (ret) |
| 919 | /* disable only clks which were enabled on error */ | 924 | /* on error: disable all previously enabled clks */ |
| 920 | for (; i >= 0; i--) | 925 | fsl_disable_clocks(fsl_edma, i); |
| 921 | clk_disable_unprepare(fsl_edma->muxclk[i]); | ||
| 922 | |||
| 923 | dev_err(&pdev->dev, "DMAMUX clk block failed.\n"); | ||
| 924 | return ret; | ||
| 925 | } | ||
| 926 | 926 | ||
| 927 | } | 927 | } |
| 928 | 928 | ||
| @@ -976,7 +976,7 @@ static int fsl_edma_probe(struct platform_device *pdev) | |||
| 976 | if (ret) { | 976 | if (ret) { |
| 977 | dev_err(&pdev->dev, | 977 | dev_err(&pdev->dev, |
| 978 | "Can't register Freescale eDMA engine. (%d)\n", ret); | 978 | "Can't register Freescale eDMA engine. (%d)\n", ret); |
| 979 | fsl_disable_clocks(fsl_edma); | 979 | fsl_disable_clocks(fsl_edma, DMAMUX_NR); |
| 980 | return ret; | 980 | return ret; |
| 981 | } | 981 | } |
| 982 | 982 | ||
| @@ -985,7 +985,7 @@ static int fsl_edma_probe(struct platform_device *pdev) | |||
| 985 | dev_err(&pdev->dev, | 985 | dev_err(&pdev->dev, |
| 986 | "Can't register Freescale eDMA of_dma. (%d)\n", ret); | 986 | "Can't register Freescale eDMA of_dma. (%d)\n", ret); |
| 987 | dma_async_device_unregister(&fsl_edma->dma_dev); | 987 | dma_async_device_unregister(&fsl_edma->dma_dev); |
| 988 | fsl_disable_clocks(fsl_edma); | 988 | fsl_disable_clocks(fsl_edma, DMAMUX_NR); |
| 989 | return ret; | 989 | return ret; |
| 990 | } | 990 | } |
| 991 | 991 | ||
| @@ -1015,7 +1015,7 @@ static int fsl_edma_remove(struct platform_device *pdev) | |||
| 1015 | fsl_edma_cleanup_vchan(&fsl_edma->dma_dev); | 1015 | fsl_edma_cleanup_vchan(&fsl_edma->dma_dev); |
| 1016 | of_dma_controller_free(np); | 1016 | of_dma_controller_free(np); |
| 1017 | dma_async_device_unregister(&fsl_edma->dma_dev); | 1017 | dma_async_device_unregister(&fsl_edma->dma_dev); |
| 1018 | fsl_disable_clocks(fsl_edma); | 1018 | fsl_disable_clocks(fsl_edma, DMAMUX_NR); |
| 1019 | 1019 | ||
| 1020 | return 0; | 1020 | return 0; |
| 1021 | } | 1021 | } |
diff --git a/drivers/dma/ioat/init.c b/drivers/dma/ioat/init.c index 2f31d3d0caa6..7792a9186f9c 100644 --- a/drivers/dma/ioat/init.c +++ b/drivers/dma/ioat/init.c | |||
| @@ -390,7 +390,7 @@ static int ioat_dma_self_test(struct ioatdma_device *ioat_dma) | |||
| 390 | if (memcmp(src, dest, IOAT_TEST_SIZE)) { | 390 | if (memcmp(src, dest, IOAT_TEST_SIZE)) { |
| 391 | dev_err(dev, "Self-test copy failed compare, disabling\n"); | 391 | dev_err(dev, "Self-test copy failed compare, disabling\n"); |
| 392 | err = -ENODEV; | 392 | err = -ENODEV; |
| 393 | goto free_resources; | 393 | goto unmap_dma; |
| 394 | } | 394 | } |
| 395 | 395 | ||
| 396 | unmap_dma: | 396 | unmap_dma: |
diff --git a/drivers/gpio/gpio-bcm-kona.c b/drivers/gpio/gpio-bcm-kona.c index dfcf56ee3c61..76861a00bb92 100644 --- a/drivers/gpio/gpio-bcm-kona.c +++ b/drivers/gpio/gpio-bcm-kona.c | |||
| @@ -522,6 +522,7 @@ static struct of_device_id const bcm_kona_gpio_of_match[] = { | |||
| 522 | * category than their parents, so it won't report false recursion. | 522 | * category than their parents, so it won't report false recursion. |
| 523 | */ | 523 | */ |
| 524 | static struct lock_class_key gpio_lock_class; | 524 | static struct lock_class_key gpio_lock_class; |
| 525 | static struct lock_class_key gpio_request_class; | ||
| 525 | 526 | ||
| 526 | static int bcm_kona_gpio_irq_map(struct irq_domain *d, unsigned int irq, | 527 | static int bcm_kona_gpio_irq_map(struct irq_domain *d, unsigned int irq, |
| 527 | irq_hw_number_t hwirq) | 528 | irq_hw_number_t hwirq) |
| @@ -531,7 +532,7 @@ static int bcm_kona_gpio_irq_map(struct irq_domain *d, unsigned int irq, | |||
| 531 | ret = irq_set_chip_data(irq, d->host_data); | 532 | ret = irq_set_chip_data(irq, d->host_data); |
| 532 | if (ret < 0) | 533 | if (ret < 0) |
| 533 | return ret; | 534 | return ret; |
| 534 | irq_set_lockdep_class(irq, &gpio_lock_class); | 535 | irq_set_lockdep_class(irq, &gpio_lock_class, &gpio_request_class); |
| 535 | irq_set_chip_and_handler(irq, &bcm_gpio_irq_chip, handle_simple_irq); | 536 | irq_set_chip_and_handler(irq, &bcm_gpio_irq_chip, handle_simple_irq); |
| 536 | irq_set_noprobe(irq); | 537 | irq_set_noprobe(irq); |
| 537 | 538 | ||
diff --git a/drivers/gpio/gpio-brcmstb.c b/drivers/gpio/gpio-brcmstb.c index 545d43a587b7..bb4f8cf18bd9 100644 --- a/drivers/gpio/gpio-brcmstb.c +++ b/drivers/gpio/gpio-brcmstb.c | |||
| @@ -327,6 +327,7 @@ static struct brcmstb_gpio_bank *brcmstb_gpio_hwirq_to_bank( | |||
| 327 | * category than their parents, so it won't report false recursion. | 327 | * category than their parents, so it won't report false recursion. |
| 328 | */ | 328 | */ |
| 329 | static struct lock_class_key brcmstb_gpio_irq_lock_class; | 329 | static struct lock_class_key brcmstb_gpio_irq_lock_class; |
| 330 | static struct lock_class_key brcmstb_gpio_irq_request_class; | ||
| 330 | 331 | ||
| 331 | 332 | ||
| 332 | static int brcmstb_gpio_irq_map(struct irq_domain *d, unsigned int irq, | 333 | static int brcmstb_gpio_irq_map(struct irq_domain *d, unsigned int irq, |
| @@ -346,7 +347,8 @@ static int brcmstb_gpio_irq_map(struct irq_domain *d, unsigned int irq, | |||
| 346 | ret = irq_set_chip_data(irq, &bank->gc); | 347 | ret = irq_set_chip_data(irq, &bank->gc); |
| 347 | if (ret < 0) | 348 | if (ret < 0) |
| 348 | return ret; | 349 | return ret; |
| 349 | irq_set_lockdep_class(irq, &brcmstb_gpio_irq_lock_class); | 350 | irq_set_lockdep_class(irq, &brcmstb_gpio_irq_lock_class, |
| 351 | &brcmstb_gpio_irq_request_class); | ||
| 350 | irq_set_chip_and_handler(irq, &priv->irq_chip, handle_level_irq); | 352 | irq_set_chip_and_handler(irq, &priv->irq_chip, handle_level_irq); |
| 351 | irq_set_noprobe(irq); | 353 | irq_set_noprobe(irq); |
| 352 | return 0; | 354 | return 0; |
diff --git a/drivers/gpio/gpio-reg.c b/drivers/gpio/gpio-reg.c index 23e771dba4c1..e85903eddc68 100644 --- a/drivers/gpio/gpio-reg.c +++ b/drivers/gpio/gpio-reg.c | |||
| @@ -103,8 +103,8 @@ static int gpio_reg_to_irq(struct gpio_chip *gc, unsigned offset) | |||
| 103 | struct gpio_reg *r = to_gpio_reg(gc); | 103 | struct gpio_reg *r = to_gpio_reg(gc); |
| 104 | int irq = r->irqs[offset]; | 104 | int irq = r->irqs[offset]; |
| 105 | 105 | ||
| 106 | if (irq >= 0 && r->irq.domain) | 106 | if (irq >= 0 && r->irqdomain) |
| 107 | irq = irq_find_mapping(r->irq.domain, irq); | 107 | irq = irq_find_mapping(r->irqdomain, irq); |
| 108 | 108 | ||
| 109 | return irq; | 109 | return irq; |
| 110 | } | 110 | } |
diff --git a/drivers/gpio/gpio-tegra.c b/drivers/gpio/gpio-tegra.c index 8db47f671708..02fa8fe2292a 100644 --- a/drivers/gpio/gpio-tegra.c +++ b/drivers/gpio/gpio-tegra.c | |||
| @@ -565,6 +565,7 @@ static const struct dev_pm_ops tegra_gpio_pm_ops = { | |||
| 565 | * than their parents, so it won't report false recursion. | 565 | * than their parents, so it won't report false recursion. |
| 566 | */ | 566 | */ |
| 567 | static struct lock_class_key gpio_lock_class; | 567 | static struct lock_class_key gpio_lock_class; |
| 568 | static struct lock_class_key gpio_request_class; | ||
| 568 | 569 | ||
| 569 | static int tegra_gpio_probe(struct platform_device *pdev) | 570 | static int tegra_gpio_probe(struct platform_device *pdev) |
| 570 | { | 571 | { |
| @@ -670,7 +671,8 @@ static int tegra_gpio_probe(struct platform_device *pdev) | |||
| 670 | 671 | ||
| 671 | bank = &tgi->bank_info[GPIO_BANK(gpio)]; | 672 | bank = &tgi->bank_info[GPIO_BANK(gpio)]; |
| 672 | 673 | ||
| 673 | irq_set_lockdep_class(irq, &gpio_lock_class); | 674 | irq_set_lockdep_class(irq, &gpio_lock_class, |
| 675 | &gpio_request_class); | ||
| 674 | irq_set_chip_data(irq, bank); | 676 | irq_set_chip_data(irq, bank); |
| 675 | irq_set_chip_and_handler(irq, &tgi->ic, handle_simple_irq); | 677 | irq_set_chip_and_handler(irq, &tgi->ic, handle_simple_irq); |
| 676 | } | 678 | } |
diff --git a/drivers/gpio/gpio-xgene-sb.c b/drivers/gpio/gpio-xgene-sb.c index 2313af82fad3..acd59113e08b 100644 --- a/drivers/gpio/gpio-xgene-sb.c +++ b/drivers/gpio/gpio-xgene-sb.c | |||
| @@ -139,7 +139,7 @@ static int xgene_gpio_sb_to_irq(struct gpio_chip *gc, u32 gpio) | |||
| 139 | 139 | ||
| 140 | static int xgene_gpio_sb_domain_activate(struct irq_domain *d, | 140 | static int xgene_gpio_sb_domain_activate(struct irq_domain *d, |
| 141 | struct irq_data *irq_data, | 141 | struct irq_data *irq_data, |
| 142 | bool early) | 142 | bool reserve) |
| 143 | { | 143 | { |
| 144 | struct xgene_gpio_sb *priv = d->host_data; | 144 | struct xgene_gpio_sb *priv = d->host_data; |
| 145 | u32 gpio = HWIRQ_TO_GPIO(priv, irq_data->hwirq); | 145 | u32 gpio = HWIRQ_TO_GPIO(priv, irq_data->hwirq); |
diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c index eb4528c87c0b..d6f3d9ee1350 100644 --- a/drivers/gpio/gpiolib-acpi.c +++ b/drivers/gpio/gpiolib-acpi.c | |||
| @@ -1074,7 +1074,7 @@ void acpi_gpiochip_add(struct gpio_chip *chip) | |||
| 1074 | } | 1074 | } |
| 1075 | 1075 | ||
| 1076 | if (!chip->names) | 1076 | if (!chip->names) |
| 1077 | devprop_gpiochip_set_names(chip); | 1077 | devprop_gpiochip_set_names(chip, dev_fwnode(chip->parent)); |
| 1078 | 1078 | ||
| 1079 | acpi_gpiochip_request_regions(acpi_gpio); | 1079 | acpi_gpiochip_request_regions(acpi_gpio); |
| 1080 | acpi_gpiochip_scan_gpios(acpi_gpio); | 1080 | acpi_gpiochip_scan_gpios(acpi_gpio); |
diff --git a/drivers/gpio/gpiolib-devprop.c b/drivers/gpio/gpiolib-devprop.c index 27f383bda7d9..f748aa3e77f7 100644 --- a/drivers/gpio/gpiolib-devprop.c +++ b/drivers/gpio/gpiolib-devprop.c | |||
| @@ -19,30 +19,27 @@ | |||
| 19 | /** | 19 | /** |
| 20 | * devprop_gpiochip_set_names - Set GPIO line names using device properties | 20 | * devprop_gpiochip_set_names - Set GPIO line names using device properties |
| 21 | * @chip: GPIO chip whose lines should be named, if possible | 21 | * @chip: GPIO chip whose lines should be named, if possible |
| 22 | * @fwnode: Property Node containing the gpio-line-names property | ||
| 22 | * | 23 | * |
| 23 | * Looks for device property "gpio-line-names" and if it exists assigns | 24 | * Looks for device property "gpio-line-names" and if it exists assigns |
| 24 | * GPIO line names for the chip. The memory allocated for the assigned | 25 | * GPIO line names for the chip. The memory allocated for the assigned |
| 25 | * names belong to the underlying firmware node and should not be released | 26 | * names belong to the underlying firmware node and should not be released |
| 26 | * by the caller. | 27 | * by the caller. |
| 27 | */ | 28 | */ |
| 28 | void devprop_gpiochip_set_names(struct gpio_chip *chip) | 29 | void devprop_gpiochip_set_names(struct gpio_chip *chip, |
| 30 | const struct fwnode_handle *fwnode) | ||
| 29 | { | 31 | { |
| 30 | struct gpio_device *gdev = chip->gpiodev; | 32 | struct gpio_device *gdev = chip->gpiodev; |
| 31 | const char **names; | 33 | const char **names; |
| 32 | int ret, i; | 34 | int ret, i; |
| 33 | 35 | ||
| 34 | if (!chip->parent) { | 36 | ret = fwnode_property_read_string_array(fwnode, "gpio-line-names", |
| 35 | dev_warn(&gdev->dev, "GPIO chip parent is NULL\n"); | ||
| 36 | return; | ||
| 37 | } | ||
| 38 | |||
| 39 | ret = device_property_read_string_array(chip->parent, "gpio-line-names", | ||
| 40 | NULL, 0); | 37 | NULL, 0); |
| 41 | if (ret < 0) | 38 | if (ret < 0) |
| 42 | return; | 39 | return; |
| 43 | 40 | ||
| 44 | if (ret != gdev->ngpio) { | 41 | if (ret != gdev->ngpio) { |
| 45 | dev_warn(chip->parent, | 42 | dev_warn(&gdev->dev, |
| 46 | "names %d do not match number of GPIOs %d\n", ret, | 43 | "names %d do not match number of GPIOs %d\n", ret, |
| 47 | gdev->ngpio); | 44 | gdev->ngpio); |
| 48 | return; | 45 | return; |
| @@ -52,10 +49,10 @@ void devprop_gpiochip_set_names(struct gpio_chip *chip) | |||
| 52 | if (!names) | 49 | if (!names) |
| 53 | return; | 50 | return; |
| 54 | 51 | ||
| 55 | ret = device_property_read_string_array(chip->parent, "gpio-line-names", | 52 | ret = fwnode_property_read_string_array(fwnode, "gpio-line-names", |
| 56 | names, gdev->ngpio); | 53 | names, gdev->ngpio); |
| 57 | if (ret < 0) { | 54 | if (ret < 0) { |
| 58 | dev_warn(chip->parent, "failed to read GPIO line names\n"); | 55 | dev_warn(&gdev->dev, "failed to read GPIO line names\n"); |
| 59 | kfree(names); | 56 | kfree(names); |
| 60 | return; | 57 | return; |
| 61 | } | 58 | } |
diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c index e0d59e61b52f..72a0695d2ac3 100644 --- a/drivers/gpio/gpiolib-of.c +++ b/drivers/gpio/gpiolib-of.c | |||
| @@ -493,7 +493,8 @@ int of_gpiochip_add(struct gpio_chip *chip) | |||
| 493 | 493 | ||
| 494 | /* If the chip defines names itself, these take precedence */ | 494 | /* If the chip defines names itself, these take precedence */ |
| 495 | if (!chip->names) | 495 | if (!chip->names) |
| 496 | devprop_gpiochip_set_names(chip); | 496 | devprop_gpiochip_set_names(chip, |
| 497 | of_fwnode_handle(chip->of_node)); | ||
| 497 | 498 | ||
| 498 | of_node_get(chip->of_node); | 499 | of_node_get(chip->of_node); |
| 499 | 500 | ||
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index aad84a6306c4..44332b793718 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c | |||
| @@ -73,7 +73,8 @@ LIST_HEAD(gpio_devices); | |||
| 73 | 73 | ||
| 74 | static void gpiochip_free_hogs(struct gpio_chip *chip); | 74 | static void gpiochip_free_hogs(struct gpio_chip *chip); |
| 75 | static int gpiochip_add_irqchip(struct gpio_chip *gpiochip, | 75 | static int gpiochip_add_irqchip(struct gpio_chip *gpiochip, |
| 76 | struct lock_class_key *key); | 76 | struct lock_class_key *lock_key, |
| 77 | struct lock_class_key *request_key); | ||
| 77 | static void gpiochip_irqchip_remove(struct gpio_chip *gpiochip); | 78 | static void gpiochip_irqchip_remove(struct gpio_chip *gpiochip); |
| 78 | static int gpiochip_irqchip_init_valid_mask(struct gpio_chip *gpiochip); | 79 | static int gpiochip_irqchip_init_valid_mask(struct gpio_chip *gpiochip); |
| 79 | static void gpiochip_irqchip_free_valid_mask(struct gpio_chip *gpiochip); | 80 | static void gpiochip_irqchip_free_valid_mask(struct gpio_chip *gpiochip); |
| @@ -1100,7 +1101,8 @@ static void gpiochip_setup_devs(void) | |||
| 1100 | } | 1101 | } |
| 1101 | 1102 | ||
| 1102 | int gpiochip_add_data_with_key(struct gpio_chip *chip, void *data, | 1103 | int gpiochip_add_data_with_key(struct gpio_chip *chip, void *data, |
| 1103 | struct lock_class_key *key) | 1104 | struct lock_class_key *lock_key, |
| 1105 | struct lock_class_key *request_key) | ||
| 1104 | { | 1106 | { |
| 1105 | unsigned long flags; | 1107 | unsigned long flags; |
| 1106 | int status = 0; | 1108 | int status = 0; |
| @@ -1246,7 +1248,7 @@ int gpiochip_add_data_with_key(struct gpio_chip *chip, void *data, | |||
| 1246 | if (status) | 1248 | if (status) |
| 1247 | goto err_remove_from_list; | 1249 | goto err_remove_from_list; |
| 1248 | 1250 | ||
| 1249 | status = gpiochip_add_irqchip(chip, key); | 1251 | status = gpiochip_add_irqchip(chip, lock_key, request_key); |
| 1250 | if (status) | 1252 | if (status) |
| 1251 | goto err_remove_chip; | 1253 | goto err_remove_chip; |
| 1252 | 1254 | ||
| @@ -1632,7 +1634,7 @@ int gpiochip_irq_map(struct irq_domain *d, unsigned int irq, | |||
| 1632 | * This lock class tells lockdep that GPIO irqs are in a different | 1634 | * This lock class tells lockdep that GPIO irqs are in a different |
| 1633 | * category than their parents, so it won't report false recursion. | 1635 | * category than their parents, so it won't report false recursion. |
| 1634 | */ | 1636 | */ |
| 1635 | irq_set_lockdep_class(irq, chip->irq.lock_key); | 1637 | irq_set_lockdep_class(irq, chip->irq.lock_key, chip->irq.request_key); |
| 1636 | irq_set_chip_and_handler(irq, chip->irq.chip, chip->irq.handler); | 1638 | irq_set_chip_and_handler(irq, chip->irq.chip, chip->irq.handler); |
| 1637 | /* Chips that use nested thread handlers have them marked */ | 1639 | /* Chips that use nested thread handlers have them marked */ |
| 1638 | if (chip->irq.threaded) | 1640 | if (chip->irq.threaded) |
| @@ -1712,10 +1714,12 @@ static int gpiochip_to_irq(struct gpio_chip *chip, unsigned offset) | |||
| 1712 | /** | 1714 | /** |
| 1713 | * gpiochip_add_irqchip() - adds an IRQ chip to a GPIO chip | 1715 | * gpiochip_add_irqchip() - adds an IRQ chip to a GPIO chip |
| 1714 | * @gpiochip: the GPIO chip to add the IRQ chip to | 1716 | * @gpiochip: the GPIO chip to add the IRQ chip to |
| 1715 | * @lock_key: lockdep class | 1717 | * @lock_key: lockdep class for IRQ lock |
| 1718 | * @request_key: lockdep class for IRQ request | ||
| 1716 | */ | 1719 | */ |
| 1717 | static int gpiochip_add_irqchip(struct gpio_chip *gpiochip, | 1720 | static int gpiochip_add_irqchip(struct gpio_chip *gpiochip, |
| 1718 | struct lock_class_key *lock_key) | 1721 | struct lock_class_key *lock_key, |
| 1722 | struct lock_class_key *request_key) | ||
| 1719 | { | 1723 | { |
| 1720 | struct irq_chip *irqchip = gpiochip->irq.chip; | 1724 | struct irq_chip *irqchip = gpiochip->irq.chip; |
| 1721 | const struct irq_domain_ops *ops; | 1725 | const struct irq_domain_ops *ops; |
| @@ -1753,6 +1757,7 @@ static int gpiochip_add_irqchip(struct gpio_chip *gpiochip, | |||
| 1753 | gpiochip->to_irq = gpiochip_to_irq; | 1757 | gpiochip->to_irq = gpiochip_to_irq; |
| 1754 | gpiochip->irq.default_type = type; | 1758 | gpiochip->irq.default_type = type; |
| 1755 | gpiochip->irq.lock_key = lock_key; | 1759 | gpiochip->irq.lock_key = lock_key; |
| 1760 | gpiochip->irq.request_key = request_key; | ||
| 1756 | 1761 | ||
| 1757 | if (gpiochip->irq.domain_ops) | 1762 | if (gpiochip->irq.domain_ops) |
| 1758 | ops = gpiochip->irq.domain_ops; | 1763 | ops = gpiochip->irq.domain_ops; |
| @@ -1850,7 +1855,8 @@ static void gpiochip_irqchip_remove(struct gpio_chip *gpiochip) | |||
| 1850 | * @type: the default type for IRQs on this irqchip, pass IRQ_TYPE_NONE | 1855 | * @type: the default type for IRQs on this irqchip, pass IRQ_TYPE_NONE |
| 1851 | * to have the core avoid setting up any default type in the hardware. | 1856 | * to have the core avoid setting up any default type in the hardware. |
| 1852 | * @threaded: whether this irqchip uses a nested thread handler | 1857 | * @threaded: whether this irqchip uses a nested thread handler |
| 1853 | * @lock_key: lockdep class | 1858 | * @lock_key: lockdep class for IRQ lock |
| 1859 | * @request_key: lockdep class for IRQ request | ||
| 1854 | * | 1860 | * |
| 1855 | * This function closely associates a certain irqchip with a certain | 1861 | * This function closely associates a certain irqchip with a certain |
| 1856 | * gpiochip, providing an irq domain to translate the local IRQs to | 1862 | * gpiochip, providing an irq domain to translate the local IRQs to |
| @@ -1872,7 +1878,8 @@ int gpiochip_irqchip_add_key(struct gpio_chip *gpiochip, | |||
| 1872 | irq_flow_handler_t handler, | 1878 | irq_flow_handler_t handler, |
| 1873 | unsigned int type, | 1879 | unsigned int type, |
| 1874 | bool threaded, | 1880 | bool threaded, |
| 1875 | struct lock_class_key *lock_key) | 1881 | struct lock_class_key *lock_key, |
| 1882 | struct lock_class_key *request_key) | ||
| 1876 | { | 1883 | { |
| 1877 | struct device_node *of_node; | 1884 | struct device_node *of_node; |
| 1878 | 1885 | ||
| @@ -1913,6 +1920,7 @@ int gpiochip_irqchip_add_key(struct gpio_chip *gpiochip, | |||
| 1913 | gpiochip->irq.default_type = type; | 1920 | gpiochip->irq.default_type = type; |
| 1914 | gpiochip->to_irq = gpiochip_to_irq; | 1921 | gpiochip->to_irq = gpiochip_to_irq; |
| 1915 | gpiochip->irq.lock_key = lock_key; | 1922 | gpiochip->irq.lock_key = lock_key; |
| 1923 | gpiochip->irq.request_key = request_key; | ||
| 1916 | gpiochip->irq.domain = irq_domain_add_simple(of_node, | 1924 | gpiochip->irq.domain = irq_domain_add_simple(of_node, |
| 1917 | gpiochip->ngpio, first_irq, | 1925 | gpiochip->ngpio, first_irq, |
| 1918 | &gpiochip_domain_ops, gpiochip); | 1926 | &gpiochip_domain_ops, gpiochip); |
| @@ -1940,7 +1948,8 @@ EXPORT_SYMBOL_GPL(gpiochip_irqchip_add_key); | |||
| 1940 | #else /* CONFIG_GPIOLIB_IRQCHIP */ | 1948 | #else /* CONFIG_GPIOLIB_IRQCHIP */ |
| 1941 | 1949 | ||
| 1942 | static inline int gpiochip_add_irqchip(struct gpio_chip *gpiochip, | 1950 | static inline int gpiochip_add_irqchip(struct gpio_chip *gpiochip, |
| 1943 | struct lock_class_key *key) | 1951 | struct lock_class_key *lock_key, |
| 1952 | struct lock_class_key *request_key) | ||
| 1944 | { | 1953 | { |
| 1945 | return 0; | 1954 | return 0; |
| 1946 | } | 1955 | } |
diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h index af48322839c3..6c44d1652139 100644 --- a/drivers/gpio/gpiolib.h +++ b/drivers/gpio/gpiolib.h | |||
| @@ -228,7 +228,8 @@ static inline int gpio_chip_hwgpio(const struct gpio_desc *desc) | |||
| 228 | return desc - &desc->gdev->descs[0]; | 228 | return desc - &desc->gdev->descs[0]; |
| 229 | } | 229 | } |
| 230 | 230 | ||
| 231 | void devprop_gpiochip_set_names(struct gpio_chip *chip); | 231 | void devprop_gpiochip_set_names(struct gpio_chip *chip, |
| 232 | const struct fwnode_handle *fwnode); | ||
| 232 | 233 | ||
| 233 | /* With descriptor prefix */ | 234 | /* With descriptor prefix */ |
| 234 | 235 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c index da43813d67a4..5aeb5f8816f3 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | |||
| @@ -2467,7 +2467,7 @@ static int gfx_v9_0_kiq_kcq_enable(struct amdgpu_device *adev) | |||
| 2467 | PACKET3_MAP_QUEUES_PIPE(ring->pipe) | | 2467 | PACKET3_MAP_QUEUES_PIPE(ring->pipe) | |
| 2468 | PACKET3_MAP_QUEUES_ME((ring->me == 1 ? 0 : 1)) | | 2468 | PACKET3_MAP_QUEUES_ME((ring->me == 1 ? 0 : 1)) | |
| 2469 | PACKET3_MAP_QUEUES_QUEUE_TYPE(0) | /*queue_type: normal compute queue */ | 2469 | PACKET3_MAP_QUEUES_QUEUE_TYPE(0) | /*queue_type: normal compute queue */ |
| 2470 | PACKET3_MAP_QUEUES_ALLOC_FORMAT(1) | /* alloc format: all_on_one_pipe */ | 2470 | PACKET3_MAP_QUEUES_ALLOC_FORMAT(0) | /* alloc format: all_on_one_pipe */ |
| 2471 | PACKET3_MAP_QUEUES_ENGINE_SEL(0) | /* engine_sel: compute */ | 2471 | PACKET3_MAP_QUEUES_ENGINE_SEL(0) | /* engine_sel: compute */ |
| 2472 | PACKET3_MAP_QUEUES_NUM_QUEUES(1)); /* num_queues: must be 1 */ | 2472 | PACKET3_MAP_QUEUES_NUM_QUEUES(1)); /* num_queues: must be 1 */ |
| 2473 | amdgpu_ring_write(kiq_ring, PACKET3_MAP_QUEUES_DOORBELL_OFFSET(ring->doorbell_index)); | 2473 | amdgpu_ring_write(kiq_ring, PACKET3_MAP_QUEUES_DOORBELL_OFFSET(ring->doorbell_index)); |
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 f71fe6d2ddda..bb5fa895fb64 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | |||
| @@ -2336,7 +2336,7 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector, | |||
| 2336 | const struct dm_connector_state *dm_state) | 2336 | const struct dm_connector_state *dm_state) |
| 2337 | { | 2337 | { |
| 2338 | struct drm_display_mode *preferred_mode = NULL; | 2338 | struct drm_display_mode *preferred_mode = NULL; |
| 2339 | const struct drm_connector *drm_connector; | 2339 | struct drm_connector *drm_connector; |
| 2340 | struct dc_stream_state *stream = NULL; | 2340 | struct dc_stream_state *stream = NULL; |
| 2341 | struct drm_display_mode mode = *drm_mode; | 2341 | struct drm_display_mode mode = *drm_mode; |
| 2342 | bool native_mode_found = false; | 2342 | bool native_mode_found = false; |
| @@ -2355,11 +2355,13 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector, | |||
| 2355 | 2355 | ||
| 2356 | if (!aconnector->dc_sink) { | 2356 | if (!aconnector->dc_sink) { |
| 2357 | /* | 2357 | /* |
| 2358 | * Exclude MST from creating fake_sink | 2358 | * Create dc_sink when necessary to MST |
| 2359 | * TODO: need to enable MST into fake_sink feature | 2359 | * Don't apply fake_sink to MST |
| 2360 | */ | 2360 | */ |
| 2361 | if (aconnector->mst_port) | 2361 | if (aconnector->mst_port) { |
| 2362 | goto stream_create_fail; | 2362 | dm_dp_mst_dc_sink_create(drm_connector); |
| 2363 | goto mst_dc_sink_create_done; | ||
| 2364 | } | ||
| 2363 | 2365 | ||
| 2364 | if (create_fake_sink(aconnector)) | 2366 | if (create_fake_sink(aconnector)) |
| 2365 | goto stream_create_fail; | 2367 | goto stream_create_fail; |
| @@ -2410,6 +2412,7 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector, | |||
| 2410 | stream_create_fail: | 2412 | stream_create_fail: |
| 2411 | dm_state_null: | 2413 | dm_state_null: |
| 2412 | drm_connector_null: | 2414 | drm_connector_null: |
| 2415 | mst_dc_sink_create_done: | ||
| 2413 | return stream; | 2416 | return stream; |
| 2414 | } | 2417 | } |
| 2415 | 2418 | ||
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h index 117521c6a6ed..0230250a1164 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | |||
| @@ -189,6 +189,8 @@ struct amdgpu_dm_connector { | |||
| 189 | struct mutex hpd_lock; | 189 | struct mutex hpd_lock; |
| 190 | 190 | ||
| 191 | bool fake_enable; | 191 | bool fake_enable; |
| 192 | |||
| 193 | bool mst_connected; | ||
| 192 | }; | 194 | }; |
| 193 | 195 | ||
| 194 | #define to_amdgpu_dm_connector(x) container_of(x, struct amdgpu_dm_connector, base) | 196 | #define to_amdgpu_dm_connector(x) container_of(x, struct amdgpu_dm_connector, base) |
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c index f8efb98b1fa7..638c2c2b5cd7 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | |||
| @@ -185,6 +185,42 @@ static int dm_connector_update_modes(struct drm_connector *connector, | |||
| 185 | return ret; | 185 | return ret; |
| 186 | } | 186 | } |
| 187 | 187 | ||
| 188 | void dm_dp_mst_dc_sink_create(struct drm_connector *connector) | ||
| 189 | { | ||
| 190 | struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector); | ||
| 191 | struct edid *edid; | ||
| 192 | struct dc_sink *dc_sink; | ||
| 193 | struct dc_sink_init_data init_params = { | ||
| 194 | .link = aconnector->dc_link, | ||
| 195 | .sink_signal = SIGNAL_TYPE_DISPLAY_PORT_MST }; | ||
| 196 | |||
| 197 | edid = drm_dp_mst_get_edid(connector, &aconnector->mst_port->mst_mgr, aconnector->port); | ||
| 198 | |||
| 199 | if (!edid) { | ||
| 200 | drm_mode_connector_update_edid_property( | ||
| 201 | &aconnector->base, | ||
| 202 | NULL); | ||
| 203 | return; | ||
| 204 | } | ||
| 205 | |||
| 206 | aconnector->edid = edid; | ||
| 207 | |||
| 208 | dc_sink = dc_link_add_remote_sink( | ||
| 209 | aconnector->dc_link, | ||
| 210 | (uint8_t *)aconnector->edid, | ||
| 211 | (aconnector->edid->extensions + 1) * EDID_LENGTH, | ||
| 212 | &init_params); | ||
| 213 | |||
| 214 | dc_sink->priv = aconnector; | ||
| 215 | aconnector->dc_sink = dc_sink; | ||
| 216 | |||
| 217 | amdgpu_dm_add_sink_to_freesync_module( | ||
| 218 | connector, aconnector->edid); | ||
| 219 | |||
| 220 | drm_mode_connector_update_edid_property( | ||
| 221 | &aconnector->base, aconnector->edid); | ||
| 222 | } | ||
| 223 | |||
| 188 | static int dm_dp_mst_get_modes(struct drm_connector *connector) | 224 | static int dm_dp_mst_get_modes(struct drm_connector *connector) |
| 189 | { | 225 | { |
| 190 | struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector); | 226 | struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector); |
| @@ -311,6 +347,7 @@ dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr, | |||
| 311 | drm_mode_connector_set_path_property(connector, pathprop); | 347 | drm_mode_connector_set_path_property(connector, pathprop); |
| 312 | 348 | ||
| 313 | drm_connector_list_iter_end(&conn_iter); | 349 | drm_connector_list_iter_end(&conn_iter); |
| 350 | aconnector->mst_connected = true; | ||
| 314 | return &aconnector->base; | 351 | return &aconnector->base; |
| 315 | } | 352 | } |
| 316 | } | 353 | } |
| @@ -363,6 +400,8 @@ dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr, | |||
| 363 | */ | 400 | */ |
| 364 | amdgpu_dm_connector_funcs_reset(connector); | 401 | amdgpu_dm_connector_funcs_reset(connector); |
| 365 | 402 | ||
| 403 | aconnector->mst_connected = true; | ||
| 404 | |||
| 366 | DRM_INFO("DM_MST: added connector: %p [id: %d] [master: %p]\n", | 405 | DRM_INFO("DM_MST: added connector: %p [id: %d] [master: %p]\n", |
| 367 | aconnector, connector->base.id, aconnector->mst_port); | 406 | aconnector, connector->base.id, aconnector->mst_port); |
| 368 | 407 | ||
| @@ -394,6 +433,8 @@ static void dm_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr, | |||
| 394 | drm_mode_connector_update_edid_property( | 433 | drm_mode_connector_update_edid_property( |
| 395 | &aconnector->base, | 434 | &aconnector->base, |
| 396 | NULL); | 435 | NULL); |
| 436 | |||
| 437 | aconnector->mst_connected = false; | ||
| 397 | } | 438 | } |
| 398 | 439 | ||
| 399 | static void dm_dp_mst_hotplug(struct drm_dp_mst_topology_mgr *mgr) | 440 | static void dm_dp_mst_hotplug(struct drm_dp_mst_topology_mgr *mgr) |
| @@ -404,10 +445,18 @@ static void dm_dp_mst_hotplug(struct drm_dp_mst_topology_mgr *mgr) | |||
| 404 | drm_kms_helper_hotplug_event(dev); | 445 | drm_kms_helper_hotplug_event(dev); |
| 405 | } | 446 | } |
| 406 | 447 | ||
| 448 | static void dm_dp_mst_link_status_reset(struct drm_connector *connector) | ||
| 449 | { | ||
| 450 | mutex_lock(&connector->dev->mode_config.mutex); | ||
| 451 | drm_mode_connector_set_link_status_property(connector, DRM_MODE_LINK_STATUS_BAD); | ||
| 452 | mutex_unlock(&connector->dev->mode_config.mutex); | ||
| 453 | } | ||
| 454 | |||
| 407 | static void dm_dp_mst_register_connector(struct drm_connector *connector) | 455 | static void dm_dp_mst_register_connector(struct drm_connector *connector) |
| 408 | { | 456 | { |
| 409 | struct drm_device *dev = connector->dev; | 457 | struct drm_device *dev = connector->dev; |
| 410 | struct amdgpu_device *adev = dev->dev_private; | 458 | struct amdgpu_device *adev = dev->dev_private; |
| 459 | struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector); | ||
| 411 | 460 | ||
| 412 | if (adev->mode_info.rfbdev) | 461 | if (adev->mode_info.rfbdev) |
| 413 | drm_fb_helper_add_one_connector(&adev->mode_info.rfbdev->helper, connector); | 462 | drm_fb_helper_add_one_connector(&adev->mode_info.rfbdev->helper, connector); |
| @@ -416,6 +465,8 @@ static void dm_dp_mst_register_connector(struct drm_connector *connector) | |||
| 416 | 465 | ||
| 417 | drm_connector_register(connector); | 466 | drm_connector_register(connector); |
| 418 | 467 | ||
| 468 | if (aconnector->mst_connected) | ||
| 469 | dm_dp_mst_link_status_reset(connector); | ||
| 419 | } | 470 | } |
| 420 | 471 | ||
| 421 | static const struct drm_dp_mst_topology_cbs dm_mst_cbs = { | 472 | static const struct drm_dp_mst_topology_cbs dm_mst_cbs = { |
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h index 2da851b40042..8cf51da26657 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h | |||
| @@ -31,5 +31,6 @@ struct amdgpu_dm_connector; | |||
| 31 | 31 | ||
| 32 | void amdgpu_dm_initialize_dp_connector(struct amdgpu_display_manager *dm, | 32 | void amdgpu_dm_initialize_dp_connector(struct amdgpu_display_manager *dm, |
| 33 | struct amdgpu_dm_connector *aconnector); | 33 | struct amdgpu_dm_connector *aconnector); |
| 34 | void dm_dp_mst_dc_sink_create(struct drm_connector *connector); | ||
| 34 | 35 | ||
| 35 | #endif | 36 | #endif |
diff --git a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c index 3dce35e66b09..b142629a1058 100644 --- a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c +++ b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c | |||
| @@ -900,6 +900,15 @@ bool dcn_validate_bandwidth( | |||
| 900 | v->override_vta_ps[input_idx] = pipe->plane_res.scl_data.taps.v_taps; | 900 | v->override_vta_ps[input_idx] = pipe->plane_res.scl_data.taps.v_taps; |
| 901 | v->override_hta_pschroma[input_idx] = pipe->plane_res.scl_data.taps.h_taps_c; | 901 | v->override_hta_pschroma[input_idx] = pipe->plane_res.scl_data.taps.h_taps_c; |
| 902 | v->override_vta_pschroma[input_idx] = pipe->plane_res.scl_data.taps.v_taps_c; | 902 | v->override_vta_pschroma[input_idx] = pipe->plane_res.scl_data.taps.v_taps_c; |
| 903 | /* | ||
| 904 | * Spreadsheet doesn't handle taps_c is one properly, | ||
| 905 | * need to force Chroma to always be scaled to pass | ||
| 906 | * bandwidth validation. | ||
| 907 | */ | ||
| 908 | if (v->override_hta_pschroma[input_idx] == 1) | ||
| 909 | v->override_hta_pschroma[input_idx] = 2; | ||
| 910 | if (v->override_vta_pschroma[input_idx] == 1) | ||
| 911 | v->override_vta_pschroma[input_idx] = 2; | ||
| 903 | v->source_scan[input_idx] = (pipe->plane_state->rotation % 2) ? dcn_bw_vert : dcn_bw_hor; | 912 | v->source_scan[input_idx] = (pipe->plane_state->rotation % 2) ? dcn_bw_vert : dcn_bw_hor; |
| 904 | } | 913 | } |
| 905 | if (v->is_line_buffer_bpp_fixed == dcn_bw_yes) | 914 | if (v->is_line_buffer_bpp_fixed == dcn_bw_yes) |
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c index e27ed4a45265..42a111b9505d 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c | |||
| @@ -1801,7 +1801,7 @@ static void disable_link(struct dc_link *link, enum signal_type signal) | |||
| 1801 | link->link_enc->funcs->disable_output(link->link_enc, signal, link); | 1801 | link->link_enc->funcs->disable_output(link->link_enc, signal, link); |
| 1802 | } | 1802 | } |
| 1803 | 1803 | ||
| 1804 | bool dp_active_dongle_validate_timing( | 1804 | static bool dp_active_dongle_validate_timing( |
| 1805 | const struct dc_crtc_timing *timing, | 1805 | const struct dc_crtc_timing *timing, |
| 1806 | const struct dc_dongle_caps *dongle_caps) | 1806 | const struct dc_dongle_caps *dongle_caps) |
| 1807 | { | 1807 | { |
| @@ -1833,6 +1833,8 @@ bool dp_active_dongle_validate_timing( | |||
| 1833 | /* Check Color Depth and Pixel Clock */ | 1833 | /* Check Color Depth and Pixel Clock */ |
| 1834 | if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR420) | 1834 | if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR420) |
| 1835 | required_pix_clk /= 2; | 1835 | required_pix_clk /= 2; |
| 1836 | else if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR422) | ||
| 1837 | required_pix_clk = required_pix_clk * 2 / 3; | ||
| 1836 | 1838 | ||
| 1837 | switch (timing->display_color_depth) { | 1839 | switch (timing->display_color_depth) { |
| 1838 | case COLOR_DEPTH_666: | 1840 | case COLOR_DEPTH_666: |
diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c index 07ff8d2faf3f..d844fadcd56f 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c | |||
| @@ -2866,16 +2866,19 @@ static void dce110_apply_ctx_for_surface( | |||
| 2866 | int num_planes, | 2866 | int num_planes, |
| 2867 | struct dc_state *context) | 2867 | struct dc_state *context) |
| 2868 | { | 2868 | { |
| 2869 | int i, be_idx; | 2869 | int i; |
| 2870 | 2870 | ||
| 2871 | if (num_planes == 0) | 2871 | if (num_planes == 0) |
| 2872 | return; | 2872 | return; |
| 2873 | 2873 | ||
| 2874 | be_idx = -1; | ||
| 2875 | for (i = 0; i < dc->res_pool->pipe_count; i++) { | 2874 | for (i = 0; i < dc->res_pool->pipe_count; i++) { |
| 2876 | if (stream == context->res_ctx.pipe_ctx[i].stream) { | 2875 | struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; |
| 2877 | be_idx = context->res_ctx.pipe_ctx[i].stream_res.tg->inst; | 2876 | struct pipe_ctx *old_pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i]; |
| 2878 | break; | 2877 | |
| 2878 | if (stream == pipe_ctx->stream) { | ||
| 2879 | if (!pipe_ctx->top_pipe && | ||
| 2880 | (pipe_ctx->plane_state || old_pipe_ctx->plane_state)) | ||
| 2881 | dc->hwss.pipe_control_lock(dc, pipe_ctx, true); | ||
| 2879 | } | 2882 | } |
| 2880 | } | 2883 | } |
| 2881 | 2884 | ||
| @@ -2895,9 +2898,22 @@ static void dce110_apply_ctx_for_surface( | |||
| 2895 | context->stream_count); | 2898 | context->stream_count); |
| 2896 | 2899 | ||
| 2897 | dce110_program_front_end_for_pipe(dc, pipe_ctx); | 2900 | dce110_program_front_end_for_pipe(dc, pipe_ctx); |
| 2901 | |||
| 2902 | dc->hwss.update_plane_addr(dc, pipe_ctx); | ||
| 2903 | |||
| 2898 | program_surface_visibility(dc, pipe_ctx); | 2904 | program_surface_visibility(dc, pipe_ctx); |
| 2899 | 2905 | ||
| 2900 | } | 2906 | } |
| 2907 | |||
| 2908 | for (i = 0; i < dc->res_pool->pipe_count; i++) { | ||
| 2909 | struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; | ||
| 2910 | struct pipe_ctx *old_pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i]; | ||
| 2911 | |||
| 2912 | if ((stream == pipe_ctx->stream) && | ||
| 2913 | (!pipe_ctx->top_pipe) && | ||
| 2914 | (pipe_ctx->plane_state || old_pipe_ctx->plane_state)) | ||
| 2915 | dc->hwss.pipe_control_lock(dc, pipe_ctx, false); | ||
| 2916 | } | ||
| 2901 | } | 2917 | } |
| 2902 | 2918 | ||
| 2903 | static void dce110_power_down_fe(struct dc *dc, int fe_idx) | 2919 | static void dce110_power_down_fe(struct dc *dc, int fe_idx) |
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c index 74e7c82bdc76..a9d55d0dd69e 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c | |||
| @@ -159,11 +159,10 @@ bool dpp_get_optimal_number_of_taps( | |||
| 159 | scl_data->taps.h_taps = 1; | 159 | scl_data->taps.h_taps = 1; |
| 160 | if (IDENTITY_RATIO(scl_data->ratios.vert)) | 160 | if (IDENTITY_RATIO(scl_data->ratios.vert)) |
| 161 | scl_data->taps.v_taps = 1; | 161 | scl_data->taps.v_taps = 1; |
| 162 | /* | 162 | if (IDENTITY_RATIO(scl_data->ratios.horz_c)) |
| 163 | * Spreadsheet doesn't handle taps_c is one properly, | 163 | scl_data->taps.h_taps_c = 1; |
| 164 | * need to force Chroma to always be scaled to pass | 164 | if (IDENTITY_RATIO(scl_data->ratios.vert_c)) |
| 165 | * bandwidth validation. | 165 | scl_data->taps.v_taps_c = 1; |
| 166 | */ | ||
| 167 | } | 166 | } |
| 168 | 167 | ||
| 169 | return true; | 168 | return true; |
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c index 482014137953..9ae236036e32 100644 --- a/drivers/gpu/drm/drm_connector.c +++ b/drivers/gpu/drm/drm_connector.c | |||
| @@ -152,14 +152,23 @@ static void drm_connector_free(struct kref *kref) | |||
| 152 | connector->funcs->destroy(connector); | 152 | connector->funcs->destroy(connector); |
| 153 | } | 153 | } |
| 154 | 154 | ||
| 155 | static void drm_connector_free_work_fn(struct work_struct *work) | 155 | void drm_connector_free_work_fn(struct work_struct *work) |
| 156 | { | 156 | { |
| 157 | struct drm_connector *connector = | 157 | struct drm_connector *connector, *n; |
| 158 | container_of(work, struct drm_connector, free_work); | 158 | struct drm_device *dev = |
| 159 | struct drm_device *dev = connector->dev; | 159 | container_of(work, struct drm_device, mode_config.connector_free_work); |
| 160 | struct drm_mode_config *config = &dev->mode_config; | ||
| 161 | unsigned long flags; | ||
| 162 | struct llist_node *freed; | ||
| 160 | 163 | ||
| 161 | drm_mode_object_unregister(dev, &connector->base); | 164 | spin_lock_irqsave(&config->connector_list_lock, flags); |
| 162 | connector->funcs->destroy(connector); | 165 | freed = llist_del_all(&config->connector_free_list); |
| 166 | spin_unlock_irqrestore(&config->connector_list_lock, flags); | ||
| 167 | |||
| 168 | llist_for_each_entry_safe(connector, n, freed, free_node) { | ||
| 169 | drm_mode_object_unregister(dev, &connector->base); | ||
| 170 | connector->funcs->destroy(connector); | ||
| 171 | } | ||
| 163 | } | 172 | } |
| 164 | 173 | ||
| 165 | /** | 174 | /** |
| @@ -191,8 +200,6 @@ int drm_connector_init(struct drm_device *dev, | |||
| 191 | if (ret) | 200 | if (ret) |
| 192 | return ret; | 201 | return ret; |
| 193 | 202 | ||
| 194 | INIT_WORK(&connector->free_work, drm_connector_free_work_fn); | ||
| 195 | |||
| 196 | connector->base.properties = &connector->properties; | 203 | connector->base.properties = &connector->properties; |
| 197 | connector->dev = dev; | 204 | connector->dev = dev; |
| 198 | connector->funcs = funcs; | 205 | connector->funcs = funcs; |
| @@ -547,10 +554,17 @@ EXPORT_SYMBOL(drm_connector_list_iter_begin); | |||
| 547 | * actually release the connector when dropping our final reference. | 554 | * actually release the connector when dropping our final reference. |
| 548 | */ | 555 | */ |
| 549 | static void | 556 | static void |
| 550 | drm_connector_put_safe(struct drm_connector *conn) | 557 | __drm_connector_put_safe(struct drm_connector *conn) |
| 551 | { | 558 | { |
| 552 | if (refcount_dec_and_test(&conn->base.refcount.refcount)) | 559 | struct drm_mode_config *config = &conn->dev->mode_config; |
| 553 | schedule_work(&conn->free_work); | 560 | |
| 561 | lockdep_assert_held(&config->connector_list_lock); | ||
| 562 | |||
| 563 | if (!refcount_dec_and_test(&conn->base.refcount.refcount)) | ||
| 564 | return; | ||
| 565 | |||
| 566 | llist_add(&conn->free_node, &config->connector_free_list); | ||
| 567 | schedule_work(&config->connector_free_work); | ||
| 554 | } | 568 | } |
| 555 | 569 | ||
| 556 | /** | 570 | /** |
| @@ -582,10 +596,10 @@ drm_connector_list_iter_next(struct drm_connector_list_iter *iter) | |||
| 582 | 596 | ||
| 583 | /* loop until it's not a zombie connector */ | 597 | /* loop until it's not a zombie connector */ |
| 584 | } while (!kref_get_unless_zero(&iter->conn->base.refcount)); | 598 | } while (!kref_get_unless_zero(&iter->conn->base.refcount)); |
| 585 | spin_unlock_irqrestore(&config->connector_list_lock, flags); | ||
| 586 | 599 | ||
| 587 | if (old_conn) | 600 | if (old_conn) |
| 588 | drm_connector_put_safe(old_conn); | 601 | __drm_connector_put_safe(old_conn); |
| 602 | spin_unlock_irqrestore(&config->connector_list_lock, flags); | ||
| 589 | 603 | ||
| 590 | return iter->conn; | 604 | return iter->conn; |
| 591 | } | 605 | } |
| @@ -602,9 +616,15 @@ EXPORT_SYMBOL(drm_connector_list_iter_next); | |||
| 602 | */ | 616 | */ |
| 603 | void drm_connector_list_iter_end(struct drm_connector_list_iter *iter) | 617 | void drm_connector_list_iter_end(struct drm_connector_list_iter *iter) |
| 604 | { | 618 | { |
| 619 | struct drm_mode_config *config = &iter->dev->mode_config; | ||
| 620 | unsigned long flags; | ||
| 621 | |||
| 605 | iter->dev = NULL; | 622 | iter->dev = NULL; |
| 606 | if (iter->conn) | 623 | if (iter->conn) { |
| 607 | drm_connector_put_safe(iter->conn); | 624 | spin_lock_irqsave(&config->connector_list_lock, flags); |
| 625 | __drm_connector_put_safe(iter->conn); | ||
| 626 | spin_unlock_irqrestore(&config->connector_list_lock, flags); | ||
| 627 | } | ||
| 608 | lock_release(&connector_list_iter_dep_map, 0, _RET_IP_); | 628 | lock_release(&connector_list_iter_dep_map, 0, _RET_IP_); |
| 609 | } | 629 | } |
| 610 | EXPORT_SYMBOL(drm_connector_list_iter_end); | 630 | EXPORT_SYMBOL(drm_connector_list_iter_end); |
| @@ -1231,6 +1251,19 @@ int drm_mode_connector_update_edid_property(struct drm_connector *connector, | |||
| 1231 | if (edid) | 1251 | if (edid) |
| 1232 | size = EDID_LENGTH * (1 + edid->extensions); | 1252 | size = EDID_LENGTH * (1 + edid->extensions); |
| 1233 | 1253 | ||
| 1254 | /* Set the display info, using edid if available, otherwise | ||
| 1255 | * reseting the values to defaults. This duplicates the work | ||
| 1256 | * done in drm_add_edid_modes, but that function is not | ||
| 1257 | * consistently called before this one in all drivers and the | ||
| 1258 | * computation is cheap enough that it seems better to | ||
| 1259 | * duplicate it rather than attempt to ensure some arbitrary | ||
| 1260 | * ordering of calls. | ||
| 1261 | */ | ||
| 1262 | if (edid) | ||
| 1263 | drm_add_display_info(connector, edid); | ||
| 1264 | else | ||
| 1265 | drm_reset_display_info(connector); | ||
| 1266 | |||
| 1234 | drm_object_property_set_value(&connector->base, | 1267 | drm_object_property_set_value(&connector->base, |
| 1235 | dev->mode_config.non_desktop_property, | 1268 | dev->mode_config.non_desktop_property, |
| 1236 | connector->display_info.non_desktop); | 1269 | connector->display_info.non_desktop); |
diff --git a/drivers/gpu/drm/drm_crtc_internal.h b/drivers/gpu/drm/drm_crtc_internal.h index 9ebb8841778c..af00f42ba269 100644 --- a/drivers/gpu/drm/drm_crtc_internal.h +++ b/drivers/gpu/drm/drm_crtc_internal.h | |||
| @@ -142,6 +142,7 @@ int drm_mode_connector_set_obj_prop(struct drm_mode_object *obj, | |||
| 142 | uint64_t value); | 142 | uint64_t value); |
| 143 | int drm_connector_create_standard_properties(struct drm_device *dev); | 143 | int drm_connector_create_standard_properties(struct drm_device *dev); |
| 144 | const char *drm_get_connector_force_name(enum drm_connector_force force); | 144 | const char *drm_get_connector_force_name(enum drm_connector_force force); |
| 145 | void drm_connector_free_work_fn(struct work_struct *work); | ||
| 145 | 146 | ||
| 146 | /* IOCTL */ | 147 | /* IOCTL */ |
| 147 | int drm_mode_connector_property_set_ioctl(struct drm_device *dev, | 148 | int drm_mode_connector_property_set_ioctl(struct drm_device *dev, |
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 5dfe14763871..cb487148359a 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c | |||
| @@ -1731,7 +1731,7 @@ EXPORT_SYMBOL(drm_edid_duplicate); | |||
| 1731 | * | 1731 | * |
| 1732 | * Returns true if @vendor is in @edid, false otherwise | 1732 | * Returns true if @vendor is in @edid, false otherwise |
| 1733 | */ | 1733 | */ |
| 1734 | static bool edid_vendor(struct edid *edid, const char *vendor) | 1734 | static bool edid_vendor(const struct edid *edid, const char *vendor) |
| 1735 | { | 1735 | { |
| 1736 | char edid_vendor[3]; | 1736 | char edid_vendor[3]; |
| 1737 | 1737 | ||
| @@ -1749,7 +1749,7 @@ static bool edid_vendor(struct edid *edid, const char *vendor) | |||
| 1749 | * | 1749 | * |
| 1750 | * This tells subsequent routines what fixes they need to apply. | 1750 | * This tells subsequent routines what fixes they need to apply. |
| 1751 | */ | 1751 | */ |
| 1752 | static u32 edid_get_quirks(struct edid *edid) | 1752 | static u32 edid_get_quirks(const struct edid *edid) |
| 1753 | { | 1753 | { |
| 1754 | const struct edid_quirk *quirk; | 1754 | const struct edid_quirk *quirk; |
| 1755 | int i; | 1755 | int i; |
| @@ -2813,7 +2813,7 @@ add_detailed_modes(struct drm_connector *connector, struct edid *edid, | |||
| 2813 | /* | 2813 | /* |
| 2814 | * Search EDID for CEA extension block. | 2814 | * Search EDID for CEA extension block. |
| 2815 | */ | 2815 | */ |
| 2816 | static u8 *drm_find_edid_extension(struct edid *edid, int ext_id) | 2816 | static u8 *drm_find_edid_extension(const struct edid *edid, int ext_id) |
| 2817 | { | 2817 | { |
| 2818 | u8 *edid_ext = NULL; | 2818 | u8 *edid_ext = NULL; |
| 2819 | int i; | 2819 | int i; |
| @@ -2835,12 +2835,12 @@ static u8 *drm_find_edid_extension(struct edid *edid, int ext_id) | |||
| 2835 | return edid_ext; | 2835 | return edid_ext; |
| 2836 | } | 2836 | } |
| 2837 | 2837 | ||
| 2838 | static u8 *drm_find_cea_extension(struct edid *edid) | 2838 | static u8 *drm_find_cea_extension(const struct edid *edid) |
| 2839 | { | 2839 | { |
| 2840 | return drm_find_edid_extension(edid, CEA_EXT); | 2840 | return drm_find_edid_extension(edid, CEA_EXT); |
| 2841 | } | 2841 | } |
| 2842 | 2842 | ||
| 2843 | static u8 *drm_find_displayid_extension(struct edid *edid) | 2843 | static u8 *drm_find_displayid_extension(const struct edid *edid) |
| 2844 | { | 2844 | { |
| 2845 | return drm_find_edid_extension(edid, DISPLAYID_EXT); | 2845 | return drm_find_edid_extension(edid, DISPLAYID_EXT); |
| 2846 | } | 2846 | } |
| @@ -4363,7 +4363,7 @@ drm_parse_hdmi_vsdb_video(struct drm_connector *connector, const u8 *db) | |||
| 4363 | } | 4363 | } |
| 4364 | 4364 | ||
| 4365 | static void drm_parse_cea_ext(struct drm_connector *connector, | 4365 | static void drm_parse_cea_ext(struct drm_connector *connector, |
| 4366 | struct edid *edid) | 4366 | const struct edid *edid) |
| 4367 | { | 4367 | { |
| 4368 | struct drm_display_info *info = &connector->display_info; | 4368 | struct drm_display_info *info = &connector->display_info; |
| 4369 | const u8 *edid_ext; | 4369 | const u8 *edid_ext; |
| @@ -4397,11 +4397,33 @@ static void drm_parse_cea_ext(struct drm_connector *connector, | |||
| 4397 | } | 4397 | } |
| 4398 | } | 4398 | } |
| 4399 | 4399 | ||
| 4400 | static void drm_add_display_info(struct drm_connector *connector, | 4400 | /* A connector has no EDID information, so we've got no EDID to compute quirks from. Reset |
| 4401 | struct edid *edid, u32 quirks) | 4401 | * all of the values which would have been set from EDID |
| 4402 | */ | ||
| 4403 | void | ||
| 4404 | drm_reset_display_info(struct drm_connector *connector) | ||
| 4402 | { | 4405 | { |
| 4403 | struct drm_display_info *info = &connector->display_info; | 4406 | struct drm_display_info *info = &connector->display_info; |
| 4404 | 4407 | ||
| 4408 | info->width_mm = 0; | ||
| 4409 | info->height_mm = 0; | ||
| 4410 | |||
| 4411 | info->bpc = 0; | ||
| 4412 | info->color_formats = 0; | ||
| 4413 | info->cea_rev = 0; | ||
| 4414 | info->max_tmds_clock = 0; | ||
| 4415 | info->dvi_dual = false; | ||
| 4416 | |||
| 4417 | info->non_desktop = 0; | ||
| 4418 | } | ||
| 4419 | EXPORT_SYMBOL_GPL(drm_reset_display_info); | ||
| 4420 | |||
| 4421 | u32 drm_add_display_info(struct drm_connector *connector, const struct edid *edid) | ||
| 4422 | { | ||
| 4423 | struct drm_display_info *info = &connector->display_info; | ||
| 4424 | |||
| 4425 | u32 quirks = edid_get_quirks(edid); | ||
| 4426 | |||
| 4405 | info->width_mm = edid->width_cm * 10; | 4427 | info->width_mm = edid->width_cm * 10; |
| 4406 | info->height_mm = edid->height_cm * 10; | 4428 | info->height_mm = edid->height_cm * 10; |
| 4407 | 4429 | ||
| @@ -4414,11 +4436,13 @@ static void drm_add_display_info(struct drm_connector *connector, | |||
| 4414 | 4436 | ||
| 4415 | info->non_desktop = !!(quirks & EDID_QUIRK_NON_DESKTOP); | 4437 | info->non_desktop = !!(quirks & EDID_QUIRK_NON_DESKTOP); |
| 4416 | 4438 | ||
| 4439 | DRM_DEBUG_KMS("non_desktop set to %d\n", info->non_desktop); | ||
| 4440 | |||
| 4417 | if (edid->revision < 3) | 4441 | if (edid->revision < 3) |
| 4418 | return; | 4442 | return quirks; |
| 4419 | 4443 | ||
| 4420 | if (!(edid->input & DRM_EDID_INPUT_DIGITAL)) | 4444 | if (!(edid->input & DRM_EDID_INPUT_DIGITAL)) |
| 4421 | return; | 4445 | return quirks; |
| 4422 | 4446 | ||
| 4423 | drm_parse_cea_ext(connector, edid); | 4447 | drm_parse_cea_ext(connector, edid); |
| 4424 | 4448 | ||
| @@ -4438,7 +4462,7 @@ static void drm_add_display_info(struct drm_connector *connector, | |||
| 4438 | 4462 | ||
| 4439 | /* Only defined for 1.4 with digital displays */ | 4463 | /* Only defined for 1.4 with digital displays */ |
| 4440 | if (edid->revision < 4) | 4464 | if (edid->revision < 4) |
| 4441 | return; | 4465 | return quirks; |
| 4442 | 4466 | ||
| 4443 | switch (edid->input & DRM_EDID_DIGITAL_DEPTH_MASK) { | 4467 | switch (edid->input & DRM_EDID_DIGITAL_DEPTH_MASK) { |
| 4444 | case DRM_EDID_DIGITAL_DEPTH_6: | 4468 | case DRM_EDID_DIGITAL_DEPTH_6: |
| @@ -4473,7 +4497,9 @@ static void drm_add_display_info(struct drm_connector *connector, | |||
| 4473 | info->color_formats |= DRM_COLOR_FORMAT_YCRCB444; | 4497 | info->color_formats |= DRM_COLOR_FORMAT_YCRCB444; |
| 4474 | if (edid->features & DRM_EDID_FEATURE_RGB_YCRCB422) | 4498 | if (edid->features & DRM_EDID_FEATURE_RGB_YCRCB422) |
| 4475 | info->color_formats |= DRM_COLOR_FORMAT_YCRCB422; | 4499 | info->color_formats |= DRM_COLOR_FORMAT_YCRCB422; |
| 4500 | return quirks; | ||
| 4476 | } | 4501 | } |
| 4502 | EXPORT_SYMBOL_GPL(drm_add_display_info); | ||
| 4477 | 4503 | ||
| 4478 | static int validate_displayid(u8 *displayid, int length, int idx) | 4504 | static int validate_displayid(u8 *displayid, int length, int idx) |
| 4479 | { | 4505 | { |
| @@ -4627,14 +4653,12 @@ int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid) | |||
| 4627 | return 0; | 4653 | return 0; |
| 4628 | } | 4654 | } |
| 4629 | 4655 | ||
| 4630 | quirks = edid_get_quirks(edid); | ||
| 4631 | |||
| 4632 | /* | 4656 | /* |
| 4633 | * CEA-861-F adds ycbcr capability map block, for HDMI 2.0 sinks. | 4657 | * CEA-861-F adds ycbcr capability map block, for HDMI 2.0 sinks. |
| 4634 | * To avoid multiple parsing of same block, lets parse that map | 4658 | * To avoid multiple parsing of same block, lets parse that map |
| 4635 | * from sink info, before parsing CEA modes. | 4659 | * from sink info, before parsing CEA modes. |
| 4636 | */ | 4660 | */ |
| 4637 | drm_add_display_info(connector, edid, quirks); | 4661 | quirks = drm_add_display_info(connector, edid); |
| 4638 | 4662 | ||
| 4639 | /* | 4663 | /* |
| 4640 | * EDID spec says modes should be preferred in this order: | 4664 | * EDID spec says modes should be preferred in this order: |
diff --git a/drivers/gpu/drm/drm_lease.c b/drivers/gpu/drm/drm_lease.c index d1eb56a1eff4..1402c0e71b03 100644 --- a/drivers/gpu/drm/drm_lease.c +++ b/drivers/gpu/drm/drm_lease.c | |||
| @@ -220,17 +220,6 @@ static struct drm_master *drm_lease_create(struct drm_master *lessor, struct idr | |||
| 220 | 220 | ||
| 221 | mutex_lock(&dev->mode_config.idr_mutex); | 221 | mutex_lock(&dev->mode_config.idr_mutex); |
| 222 | 222 | ||
| 223 | /* Insert the new lessee into the tree */ | ||
| 224 | id = idr_alloc(&(drm_lease_owner(lessor)->lessee_idr), lessee, 1, 0, GFP_KERNEL); | ||
| 225 | if (id < 0) { | ||
| 226 | error = id; | ||
| 227 | goto out_lessee; | ||
| 228 | } | ||
| 229 | |||
| 230 | lessee->lessee_id = id; | ||
| 231 | lessee->lessor = drm_master_get(lessor); | ||
| 232 | list_add_tail(&lessee->lessee_list, &lessor->lessees); | ||
| 233 | |||
| 234 | idr_for_each_entry(leases, entry, object) { | 223 | idr_for_each_entry(leases, entry, object) { |
| 235 | error = 0; | 224 | error = 0; |
| 236 | if (!idr_find(&dev->mode_config.crtc_idr, object)) | 225 | if (!idr_find(&dev->mode_config.crtc_idr, object)) |
| @@ -246,6 +235,17 @@ static struct drm_master *drm_lease_create(struct drm_master *lessor, struct idr | |||
| 246 | } | 235 | } |
| 247 | } | 236 | } |
| 248 | 237 | ||
| 238 | /* Insert the new lessee into the tree */ | ||
| 239 | id = idr_alloc(&(drm_lease_owner(lessor)->lessee_idr), lessee, 1, 0, GFP_KERNEL); | ||
| 240 | if (id < 0) { | ||
| 241 | error = id; | ||
| 242 | goto out_lessee; | ||
| 243 | } | ||
| 244 | |||
| 245 | lessee->lessee_id = id; | ||
| 246 | lessee->lessor = drm_master_get(lessor); | ||
| 247 | list_add_tail(&lessee->lessee_list, &lessor->lessees); | ||
| 248 | |||
| 249 | /* Move the leases over */ | 249 | /* Move the leases over */ |
| 250 | lessee->leases = *leases; | 250 | lessee->leases = *leases; |
| 251 | DRM_DEBUG_LEASE("new lessee %d %p, lessor %d %p\n", lessee->lessee_id, lessee, lessor->lessee_id, lessor); | 251 | DRM_DEBUG_LEASE("new lessee %d %p, lessor %d %p\n", lessee->lessee_id, lessee, lessor->lessee_id, lessor); |
| @@ -254,10 +254,10 @@ static struct drm_master *drm_lease_create(struct drm_master *lessor, struct idr | |||
| 254 | return lessee; | 254 | return lessee; |
| 255 | 255 | ||
| 256 | out_lessee: | 256 | out_lessee: |
| 257 | drm_master_put(&lessee); | ||
| 258 | |||
| 259 | mutex_unlock(&dev->mode_config.idr_mutex); | 257 | mutex_unlock(&dev->mode_config.idr_mutex); |
| 260 | 258 | ||
| 259 | drm_master_put(&lessee); | ||
| 260 | |||
| 261 | return ERR_PTR(error); | 261 | return ERR_PTR(error); |
| 262 | } | 262 | } |
| 263 | 263 | ||
diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c index 61a1c8ea74bc..c3c79ee6119e 100644 --- a/drivers/gpu/drm/drm_mm.c +++ b/drivers/gpu/drm/drm_mm.c | |||
| @@ -575,21 +575,23 @@ EXPORT_SYMBOL(drm_mm_remove_node); | |||
| 575 | */ | 575 | */ |
| 576 | void drm_mm_replace_node(struct drm_mm_node *old, struct drm_mm_node *new) | 576 | void drm_mm_replace_node(struct drm_mm_node *old, struct drm_mm_node *new) |
| 577 | { | 577 | { |
| 578 | struct drm_mm *mm = old->mm; | ||
| 579 | |||
| 578 | DRM_MM_BUG_ON(!old->allocated); | 580 | DRM_MM_BUG_ON(!old->allocated); |
| 579 | 581 | ||
| 580 | *new = *old; | 582 | *new = *old; |
| 581 | 583 | ||
| 582 | list_replace(&old->node_list, &new->node_list); | 584 | list_replace(&old->node_list, &new->node_list); |
| 583 | rb_replace_node(&old->rb, &new->rb, &old->mm->interval_tree.rb_root); | 585 | rb_replace_node_cached(&old->rb, &new->rb, &mm->interval_tree); |
| 584 | 586 | ||
| 585 | if (drm_mm_hole_follows(old)) { | 587 | if (drm_mm_hole_follows(old)) { |
| 586 | list_replace(&old->hole_stack, &new->hole_stack); | 588 | list_replace(&old->hole_stack, &new->hole_stack); |
| 587 | rb_replace_node(&old->rb_hole_size, | 589 | rb_replace_node(&old->rb_hole_size, |
| 588 | &new->rb_hole_size, | 590 | &new->rb_hole_size, |
| 589 | &old->mm->holes_size); | 591 | &mm->holes_size); |
| 590 | rb_replace_node(&old->rb_hole_addr, | 592 | rb_replace_node(&old->rb_hole_addr, |
| 591 | &new->rb_hole_addr, | 593 | &new->rb_hole_addr, |
| 592 | &old->mm->holes_addr); | 594 | &mm->holes_addr); |
| 593 | } | 595 | } |
| 594 | 596 | ||
| 595 | old->allocated = false; | 597 | old->allocated = false; |
diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c index cc78b3d9e5e4..256de7313612 100644 --- a/drivers/gpu/drm/drm_mode_config.c +++ b/drivers/gpu/drm/drm_mode_config.c | |||
| @@ -382,6 +382,9 @@ void drm_mode_config_init(struct drm_device *dev) | |||
| 382 | ida_init(&dev->mode_config.connector_ida); | 382 | ida_init(&dev->mode_config.connector_ida); |
| 383 | spin_lock_init(&dev->mode_config.connector_list_lock); | 383 | spin_lock_init(&dev->mode_config.connector_list_lock); |
| 384 | 384 | ||
| 385 | init_llist_head(&dev->mode_config.connector_free_list); | ||
| 386 | INIT_WORK(&dev->mode_config.connector_free_work, drm_connector_free_work_fn); | ||
| 387 | |||
| 385 | drm_mode_create_standard_properties(dev); | 388 | drm_mode_create_standard_properties(dev); |
| 386 | 389 | ||
| 387 | /* Just to be sure */ | 390 | /* Just to be sure */ |
| @@ -432,7 +435,7 @@ void drm_mode_config_cleanup(struct drm_device *dev) | |||
| 432 | } | 435 | } |
| 433 | drm_connector_list_iter_end(&conn_iter); | 436 | drm_connector_list_iter_end(&conn_iter); |
| 434 | /* connector_iter drops references in a work item. */ | 437 | /* connector_iter drops references in a work item. */ |
| 435 | flush_scheduled_work(); | 438 | flush_work(&dev->mode_config.connector_free_work); |
| 436 | if (WARN_ON(!list_empty(&dev->mode_config.connector_list))) { | 439 | if (WARN_ON(!list_empty(&dev->mode_config.connector_list))) { |
| 437 | drm_connector_list_iter_begin(dev, &conn_iter); | 440 | drm_connector_list_iter_begin(dev, &conn_iter); |
| 438 | drm_for_each_connector_iter(connector, &conn_iter) | 441 | drm_for_each_connector_iter(connector, &conn_iter) |
diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c index 37a93cdffb4a..2c90519576a3 100644 --- a/drivers/gpu/drm/drm_plane.c +++ b/drivers/gpu/drm/drm_plane.c | |||
| @@ -558,11 +558,10 @@ int drm_plane_check_pixel_format(const struct drm_plane *plane, u32 format) | |||
| 558 | } | 558 | } |
| 559 | 559 | ||
| 560 | /* | 560 | /* |
| 561 | * setplane_internal - setplane handler for internal callers | 561 | * __setplane_internal - setplane handler for internal callers |
| 562 | * | 562 | * |
| 563 | * Note that we assume an extra reference has already been taken on fb. If the | 563 | * This function will take a reference on the new fb for the plane |
| 564 | * update fails, this reference will be dropped before return; if it succeeds, | 564 | * on success. |
| 565 | * the previous framebuffer (if any) will be unreferenced instead. | ||
| 566 | * | 565 | * |
| 567 | * src_{x,y,w,h} are provided in 16.16 fixed point format | 566 | * src_{x,y,w,h} are provided in 16.16 fixed point format |
| 568 | */ | 567 | */ |
| @@ -630,14 +629,12 @@ static int __setplane_internal(struct drm_plane *plane, | |||
| 630 | if (!ret) { | 629 | if (!ret) { |
| 631 | plane->crtc = crtc; | 630 | plane->crtc = crtc; |
| 632 | plane->fb = fb; | 631 | plane->fb = fb; |
| 633 | fb = NULL; | 632 | drm_framebuffer_get(plane->fb); |
| 634 | } else { | 633 | } else { |
| 635 | plane->old_fb = NULL; | 634 | plane->old_fb = NULL; |
| 636 | } | 635 | } |
| 637 | 636 | ||
| 638 | out: | 637 | out: |
| 639 | if (fb) | ||
| 640 | drm_framebuffer_put(fb); | ||
| 641 | if (plane->old_fb) | 638 | if (plane->old_fb) |
| 642 | drm_framebuffer_put(plane->old_fb); | 639 | drm_framebuffer_put(plane->old_fb); |
| 643 | plane->old_fb = NULL; | 640 | plane->old_fb = NULL; |
| @@ -685,6 +682,7 @@ int drm_mode_setplane(struct drm_device *dev, void *data, | |||
| 685 | struct drm_plane *plane; | 682 | struct drm_plane *plane; |
| 686 | struct drm_crtc *crtc = NULL; | 683 | struct drm_crtc *crtc = NULL; |
| 687 | struct drm_framebuffer *fb = NULL; | 684 | struct drm_framebuffer *fb = NULL; |
| 685 | int ret; | ||
| 688 | 686 | ||
| 689 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) | 687 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) |
| 690 | return -EINVAL; | 688 | return -EINVAL; |
| @@ -717,15 +715,16 @@ int drm_mode_setplane(struct drm_device *dev, void *data, | |||
| 717 | } | 715 | } |
| 718 | } | 716 | } |
| 719 | 717 | ||
| 720 | /* | 718 | ret = setplane_internal(plane, crtc, fb, |
| 721 | * setplane_internal will take care of deref'ing either the old or new | 719 | plane_req->crtc_x, plane_req->crtc_y, |
| 722 | * framebuffer depending on success. | 720 | plane_req->crtc_w, plane_req->crtc_h, |
| 723 | */ | 721 | plane_req->src_x, plane_req->src_y, |
| 724 | return setplane_internal(plane, crtc, fb, | 722 | plane_req->src_w, plane_req->src_h); |
| 725 | plane_req->crtc_x, plane_req->crtc_y, | 723 | |
| 726 | plane_req->crtc_w, plane_req->crtc_h, | 724 | if (fb) |
| 727 | plane_req->src_x, plane_req->src_y, | 725 | drm_framebuffer_put(fb); |
| 728 | plane_req->src_w, plane_req->src_h); | 726 | |
| 727 | return ret; | ||
| 729 | } | 728 | } |
| 730 | 729 | ||
| 731 | static int drm_mode_cursor_universal(struct drm_crtc *crtc, | 730 | static int drm_mode_cursor_universal(struct drm_crtc *crtc, |
| @@ -788,13 +787,12 @@ static int drm_mode_cursor_universal(struct drm_crtc *crtc, | |||
| 788 | src_h = fb->height << 16; | 787 | src_h = fb->height << 16; |
| 789 | } | 788 | } |
| 790 | 789 | ||
| 791 | /* | ||
| 792 | * setplane_internal will take care of deref'ing either the old or new | ||
| 793 | * framebuffer depending on success. | ||
| 794 | */ | ||
| 795 | ret = __setplane_internal(crtc->cursor, crtc, fb, | 790 | ret = __setplane_internal(crtc->cursor, crtc, fb, |
| 796 | crtc_x, crtc_y, crtc_w, crtc_h, | 791 | crtc_x, crtc_y, crtc_w, crtc_h, |
| 797 | 0, 0, src_w, src_h, ctx); | 792 | 0, 0, src_w, src_h, ctx); |
| 793 | |||
| 794 | if (fb) | ||
| 795 | drm_framebuffer_put(fb); | ||
| 798 | 796 | ||
| 799 | /* Update successful; save new cursor position, if necessary */ | 797 | /* Update successful; save new cursor position, if necessary */ |
| 800 | if (ret == 0 && req->flags & DRM_MODE_CURSOR_MOVE) { | 798 | if (ret == 0 && req->flags & DRM_MODE_CURSOR_MOVE) { |
diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c index f776fc1cc543..cb4d09c70fd4 100644 --- a/drivers/gpu/drm/drm_syncobj.c +++ b/drivers/gpu/drm/drm_syncobj.c | |||
| @@ -369,40 +369,26 @@ static const struct file_operations drm_syncobj_file_fops = { | |||
| 369 | .release = drm_syncobj_file_release, | 369 | .release = drm_syncobj_file_release, |
| 370 | }; | 370 | }; |
| 371 | 371 | ||
| 372 | static int drm_syncobj_alloc_file(struct drm_syncobj *syncobj) | ||
| 373 | { | ||
| 374 | struct file *file = anon_inode_getfile("syncobj_file", | ||
| 375 | &drm_syncobj_file_fops, | ||
| 376 | syncobj, 0); | ||
| 377 | if (IS_ERR(file)) | ||
| 378 | return PTR_ERR(file); | ||
| 379 | |||
| 380 | drm_syncobj_get(syncobj); | ||
| 381 | if (cmpxchg(&syncobj->file, NULL, file)) { | ||
| 382 | /* lost the race */ | ||
| 383 | fput(file); | ||
| 384 | } | ||
| 385 | |||
| 386 | return 0; | ||
| 387 | } | ||
| 388 | |||
| 389 | int drm_syncobj_get_fd(struct drm_syncobj *syncobj, int *p_fd) | 372 | int drm_syncobj_get_fd(struct drm_syncobj *syncobj, int *p_fd) |
| 390 | { | 373 | { |
| 391 | int ret; | 374 | struct file *file; |
| 392 | int fd; | 375 | int fd; |
| 393 | 376 | ||
| 394 | fd = get_unused_fd_flags(O_CLOEXEC); | 377 | fd = get_unused_fd_flags(O_CLOEXEC); |
| 395 | if (fd < 0) | 378 | if (fd < 0) |
| 396 | return fd; | 379 | return fd; |
| 397 | 380 | ||
| 398 | if (!syncobj->file) { | 381 | file = anon_inode_getfile("syncobj_file", |
| 399 | ret = drm_syncobj_alloc_file(syncobj); | 382 | &drm_syncobj_file_fops, |
| 400 | if (ret) { | 383 | syncobj, 0); |
| 401 | put_unused_fd(fd); | 384 | if (IS_ERR(file)) { |
| 402 | return ret; | 385 | put_unused_fd(fd); |
| 403 | } | 386 | return PTR_ERR(file); |
| 404 | } | 387 | } |
| 405 | fd_install(fd, syncobj->file); | 388 | |
| 389 | drm_syncobj_get(syncobj); | ||
| 390 | fd_install(fd, file); | ||
| 391 | |||
| 406 | *p_fd = fd; | 392 | *p_fd = fd; |
| 407 | return 0; | 393 | return 0; |
| 408 | } | 394 | } |
| @@ -422,31 +408,24 @@ static int drm_syncobj_handle_to_fd(struct drm_file *file_private, | |||
| 422 | return ret; | 408 | return ret; |
| 423 | } | 409 | } |
| 424 | 410 | ||
| 425 | static struct drm_syncobj *drm_syncobj_fdget(int fd) | ||
| 426 | { | ||
| 427 | struct file *file = fget(fd); | ||
| 428 | |||
| 429 | if (!file) | ||
| 430 | return NULL; | ||
| 431 | if (file->f_op != &drm_syncobj_file_fops) | ||
| 432 | goto err; | ||
| 433 | |||
| 434 | return file->private_data; | ||
| 435 | err: | ||
| 436 | fput(file); | ||
| 437 | return NULL; | ||
| 438 | }; | ||
| 439 | |||
| 440 | static int drm_syncobj_fd_to_handle(struct drm_file *file_private, | 411 | static int drm_syncobj_fd_to_handle(struct drm_file *file_private, |
| 441 | int fd, u32 *handle) | 412 | int fd, u32 *handle) |
| 442 | { | 413 | { |
| 443 | struct drm_syncobj *syncobj = drm_syncobj_fdget(fd); | 414 | struct drm_syncobj *syncobj; |
| 415 | struct file *file; | ||
| 444 | int ret; | 416 | int ret; |
| 445 | 417 | ||
| 446 | if (!syncobj) | 418 | file = fget(fd); |
| 419 | if (!file) | ||
| 447 | return -EINVAL; | 420 | return -EINVAL; |
| 448 | 421 | ||
| 422 | if (file->f_op != &drm_syncobj_file_fops) { | ||
| 423 | fput(file); | ||
| 424 | return -EINVAL; | ||
| 425 | } | ||
| 426 | |||
| 449 | /* take a reference to put in the idr */ | 427 | /* take a reference to put in the idr */ |
| 428 | syncobj = file->private_data; | ||
| 450 | drm_syncobj_get(syncobj); | 429 | drm_syncobj_get(syncobj); |
| 451 | 430 | ||
| 452 | idr_preload(GFP_KERNEL); | 431 | idr_preload(GFP_KERNEL); |
| @@ -455,12 +434,14 @@ static int drm_syncobj_fd_to_handle(struct drm_file *file_private, | |||
| 455 | spin_unlock(&file_private->syncobj_table_lock); | 434 | spin_unlock(&file_private->syncobj_table_lock); |
| 456 | idr_preload_end(); | 435 | idr_preload_end(); |
| 457 | 436 | ||
| 458 | if (ret < 0) { | 437 | if (ret > 0) { |
| 459 | fput(syncobj->file); | 438 | *handle = ret; |
| 460 | return ret; | 439 | ret = 0; |
| 461 | } | 440 | } else |
| 462 | *handle = ret; | 441 | drm_syncobj_put(syncobj); |
| 463 | return 0; | 442 | |
| 443 | fput(file); | ||
| 444 | return ret; | ||
| 464 | } | 445 | } |
| 465 | 446 | ||
| 466 | static int drm_syncobj_import_sync_file_fence(struct drm_file *file_private, | 447 | static int drm_syncobj_import_sync_file_fence(struct drm_file *file_private, |
diff --git a/drivers/gpu/drm/i915/gvt/display.c b/drivers/gpu/drm/i915/gvt/display.c index 355120865efd..309f3fa6794a 100644 --- a/drivers/gpu/drm/i915/gvt/display.c +++ b/drivers/gpu/drm/i915/gvt/display.c | |||
| @@ -266,6 +266,8 @@ static void emulate_monitor_status_change(struct intel_vgpu *vgpu) | |||
| 266 | /* Clear host CRT status, so guest couldn't detect this host CRT. */ | 266 | /* Clear host CRT status, so guest couldn't detect this host CRT. */ |
| 267 | if (IS_BROADWELL(dev_priv)) | 267 | if (IS_BROADWELL(dev_priv)) |
| 268 | vgpu_vreg(vgpu, PCH_ADPA) &= ~ADPA_CRT_HOTPLUG_MONITOR_MASK; | 268 | vgpu_vreg(vgpu, PCH_ADPA) &= ~ADPA_CRT_HOTPLUG_MONITOR_MASK; |
| 269 | |||
| 270 | vgpu_vreg(vgpu, PIPECONF(PIPE_A)) |= PIPECONF_ENABLE; | ||
| 269 | } | 271 | } |
| 270 | 272 | ||
| 271 | static void clean_virtual_dp_monitor(struct intel_vgpu *vgpu, int port_num) | 273 | static void clean_virtual_dp_monitor(struct intel_vgpu *vgpu, int port_num) |
| @@ -282,7 +284,6 @@ static void clean_virtual_dp_monitor(struct intel_vgpu *vgpu, int port_num) | |||
| 282 | static int setup_virtual_dp_monitor(struct intel_vgpu *vgpu, int port_num, | 284 | static int setup_virtual_dp_monitor(struct intel_vgpu *vgpu, int port_num, |
| 283 | int type, unsigned int resolution) | 285 | int type, unsigned int resolution) |
| 284 | { | 286 | { |
| 285 | struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv; | ||
| 286 | struct intel_vgpu_port *port = intel_vgpu_port(vgpu, port_num); | 287 | struct intel_vgpu_port *port = intel_vgpu_port(vgpu, port_num); |
| 287 | 288 | ||
| 288 | if (WARN_ON(resolution >= GVT_EDID_NUM)) | 289 | if (WARN_ON(resolution >= GVT_EDID_NUM)) |
| @@ -308,7 +309,7 @@ static int setup_virtual_dp_monitor(struct intel_vgpu *vgpu, int port_num, | |||
| 308 | port->type = type; | 309 | port->type = type; |
| 309 | 310 | ||
| 310 | emulate_monitor_status_change(vgpu); | 311 | emulate_monitor_status_change(vgpu); |
| 311 | vgpu_vreg(vgpu, PIPECONF(PIPE_A)) |= PIPECONF_ENABLE; | 312 | |
| 312 | return 0; | 313 | return 0; |
| 313 | } | 314 | } |
| 314 | 315 | ||
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index ad4050f7ab3b..18de6569d04a 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
| @@ -330,17 +330,10 @@ int i915_gem_object_unbind(struct drm_i915_gem_object *obj) | |||
| 330 | * must wait for all rendering to complete to the object (as unbinding | 330 | * must wait for all rendering to complete to the object (as unbinding |
| 331 | * must anyway), and retire the requests. | 331 | * must anyway), and retire the requests. |
| 332 | */ | 332 | */ |
| 333 | ret = i915_gem_object_wait(obj, | 333 | ret = i915_gem_object_set_to_cpu_domain(obj, false); |
| 334 | I915_WAIT_INTERRUPTIBLE | | ||
| 335 | I915_WAIT_LOCKED | | ||
| 336 | I915_WAIT_ALL, | ||
| 337 | MAX_SCHEDULE_TIMEOUT, | ||
| 338 | NULL); | ||
| 339 | if (ret) | 334 | if (ret) |
| 340 | return ret; | 335 | return ret; |
| 341 | 336 | ||
| 342 | i915_gem_retire_requests(to_i915(obj->base.dev)); | ||
| 343 | |||
| 344 | while ((vma = list_first_entry_or_null(&obj->vma_list, | 337 | while ((vma = list_first_entry_or_null(&obj->vma_list, |
| 345 | struct i915_vma, | 338 | struct i915_vma, |
| 346 | obj_link))) { | 339 | obj_link))) { |
diff --git a/drivers/gpu/drm/i915/i915_sw_fence.c b/drivers/gpu/drm/i915/i915_sw_fence.c index e8ca67a129d2..ac236b88c99c 100644 --- a/drivers/gpu/drm/i915/i915_sw_fence.c +++ b/drivers/gpu/drm/i915/i915_sw_fence.c | |||
| @@ -367,6 +367,7 @@ struct i915_sw_dma_fence_cb { | |||
| 367 | struct dma_fence *dma; | 367 | struct dma_fence *dma; |
| 368 | struct timer_list timer; | 368 | struct timer_list timer; |
| 369 | struct irq_work work; | 369 | struct irq_work work; |
| 370 | struct rcu_head rcu; | ||
| 370 | }; | 371 | }; |
| 371 | 372 | ||
| 372 | static void timer_i915_sw_fence_wake(struct timer_list *t) | 373 | static void timer_i915_sw_fence_wake(struct timer_list *t) |
| @@ -406,7 +407,7 @@ static void irq_i915_sw_fence_work(struct irq_work *wrk) | |||
| 406 | del_timer_sync(&cb->timer); | 407 | del_timer_sync(&cb->timer); |
| 407 | dma_fence_put(cb->dma); | 408 | dma_fence_put(cb->dma); |
| 408 | 409 | ||
| 409 | kfree(cb); | 410 | kfree_rcu(cb, rcu); |
| 410 | } | 411 | } |
| 411 | 412 | ||
| 412 | int i915_sw_fence_await_dma_fence(struct i915_sw_fence *fence, | 413 | int i915_sw_fence_await_dma_fence(struct i915_sw_fence *fence, |
diff --git a/drivers/gpu/drm/i915/intel_breadcrumbs.c b/drivers/gpu/drm/i915/intel_breadcrumbs.c index 5f8b9f1f40f1..bcbc7abe6693 100644 --- a/drivers/gpu/drm/i915/intel_breadcrumbs.c +++ b/drivers/gpu/drm/i915/intel_breadcrumbs.c | |||
| @@ -186,7 +186,7 @@ void intel_engine_disarm_breadcrumbs(struct intel_engine_cs *engine) | |||
| 186 | struct intel_wait *wait, *n, *first; | 186 | struct intel_wait *wait, *n, *first; |
| 187 | 187 | ||
| 188 | if (!b->irq_armed) | 188 | if (!b->irq_armed) |
| 189 | return; | 189 | goto wakeup_signaler; |
| 190 | 190 | ||
| 191 | /* We only disarm the irq when we are idle (all requests completed), | 191 | /* We only disarm the irq when we are idle (all requests completed), |
| 192 | * so if the bottom-half remains asleep, it missed the request | 192 | * so if the bottom-half remains asleep, it missed the request |
| @@ -208,6 +208,14 @@ void intel_engine_disarm_breadcrumbs(struct intel_engine_cs *engine) | |||
| 208 | b->waiters = RB_ROOT; | 208 | b->waiters = RB_ROOT; |
| 209 | 209 | ||
| 210 | spin_unlock_irq(&b->rb_lock); | 210 | spin_unlock_irq(&b->rb_lock); |
| 211 | |||
| 212 | /* | ||
| 213 | * The signaling thread may be asleep holding a reference to a request, | ||
| 214 | * that had its signaling cancelled prior to being preempted. We need | ||
| 215 | * to kick the signaler, just in case, to release any such reference. | ||
| 216 | */ | ||
| 217 | wakeup_signaler: | ||
| 218 | wake_up_process(b->signaler); | ||
| 211 | } | 219 | } |
| 212 | 220 | ||
| 213 | static bool use_fake_irq(const struct intel_breadcrumbs *b) | 221 | static bool use_fake_irq(const struct intel_breadcrumbs *b) |
| @@ -651,23 +659,15 @@ static int intel_breadcrumbs_signaler(void *arg) | |||
| 651 | } | 659 | } |
| 652 | 660 | ||
| 653 | if (unlikely(do_schedule)) { | 661 | if (unlikely(do_schedule)) { |
| 654 | DEFINE_WAIT(exec); | ||
| 655 | |||
| 656 | if (kthread_should_park()) | 662 | if (kthread_should_park()) |
| 657 | kthread_parkme(); | 663 | kthread_parkme(); |
| 658 | 664 | ||
| 659 | if (kthread_should_stop()) { | 665 | if (unlikely(kthread_should_stop())) { |
| 660 | GEM_BUG_ON(request); | 666 | i915_gem_request_put(request); |
| 661 | break; | 667 | break; |
| 662 | } | 668 | } |
| 663 | 669 | ||
| 664 | if (request) | ||
| 665 | add_wait_queue(&request->execute, &exec); | ||
| 666 | |||
| 667 | schedule(); | 670 | schedule(); |
| 668 | |||
| 669 | if (request) | ||
| 670 | remove_wait_queue(&request->execute, &exec); | ||
| 671 | } | 671 | } |
| 672 | i915_gem_request_put(request); | 672 | i915_gem_request_put(request); |
| 673 | } while (1); | 673 | } while (1); |
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index e0843bb99169..58a3755544b2 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c | |||
| @@ -2128,6 +2128,8 @@ static void intel_ddi_clk_select(struct intel_encoder *encoder, | |||
| 2128 | if (WARN_ON(!pll)) | 2128 | if (WARN_ON(!pll)) |
| 2129 | return; | 2129 | return; |
| 2130 | 2130 | ||
| 2131 | mutex_lock(&dev_priv->dpll_lock); | ||
| 2132 | |||
| 2131 | if (IS_CANNONLAKE(dev_priv)) { | 2133 | if (IS_CANNONLAKE(dev_priv)) { |
| 2132 | /* Configure DPCLKA_CFGCR0 to map the DPLL to the DDI. */ | 2134 | /* Configure DPCLKA_CFGCR0 to map the DPLL to the DDI. */ |
| 2133 | val = I915_READ(DPCLKA_CFGCR0); | 2135 | val = I915_READ(DPCLKA_CFGCR0); |
| @@ -2157,6 +2159,8 @@ static void intel_ddi_clk_select(struct intel_encoder *encoder, | |||
| 2157 | } else if (INTEL_INFO(dev_priv)->gen < 9) { | 2159 | } else if (INTEL_INFO(dev_priv)->gen < 9) { |
| 2158 | I915_WRITE(PORT_CLK_SEL(port), hsw_pll_to_ddi_pll_sel(pll)); | 2160 | I915_WRITE(PORT_CLK_SEL(port), hsw_pll_to_ddi_pll_sel(pll)); |
| 2159 | } | 2161 | } |
| 2162 | |||
| 2163 | mutex_unlock(&dev_priv->dpll_lock); | ||
| 2160 | } | 2164 | } |
| 2161 | 2165 | ||
| 2162 | static void intel_ddi_clk_disable(struct intel_encoder *encoder) | 2166 | static void intel_ddi_clk_disable(struct intel_encoder *encoder) |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index e8ccf89cb17b..30cf273d57aa 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
| @@ -9944,11 +9944,10 @@ found: | |||
| 9944 | } | 9944 | } |
| 9945 | 9945 | ||
| 9946 | ret = intel_modeset_setup_plane_state(state, crtc, mode, fb, 0, 0); | 9946 | ret = intel_modeset_setup_plane_state(state, crtc, mode, fb, 0, 0); |
| 9947 | drm_framebuffer_put(fb); | ||
| 9947 | if (ret) | 9948 | if (ret) |
| 9948 | goto fail; | 9949 | goto fail; |
| 9949 | 9950 | ||
| 9950 | drm_framebuffer_put(fb); | ||
| 9951 | |||
| 9952 | ret = drm_atomic_set_mode_for_crtc(&crtc_state->base, mode); | 9951 | ret = drm_atomic_set_mode_for_crtc(&crtc_state->base, mode); |
| 9953 | if (ret) | 9952 | if (ret) |
| 9954 | goto fail; | 9953 | goto fail; |
| @@ -13195,7 +13194,7 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe) | |||
| 13195 | primary->frontbuffer_bit = INTEL_FRONTBUFFER_PRIMARY(pipe); | 13194 | primary->frontbuffer_bit = INTEL_FRONTBUFFER_PRIMARY(pipe); |
| 13196 | primary->check_plane = intel_check_primary_plane; | 13195 | primary->check_plane = intel_check_primary_plane; |
| 13197 | 13196 | ||
| 13198 | if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) { | 13197 | if (INTEL_GEN(dev_priv) >= 10) { |
| 13199 | intel_primary_formats = skl_primary_formats; | 13198 | intel_primary_formats = skl_primary_formats; |
| 13200 | num_formats = ARRAY_SIZE(skl_primary_formats); | 13199 | num_formats = ARRAY_SIZE(skl_primary_formats); |
| 13201 | modifiers = skl_format_modifiers_ccs; | 13200 | modifiers = skl_format_modifiers_ccs; |
diff --git a/drivers/gpu/drm/i915/intel_lpe_audio.c b/drivers/gpu/drm/i915/intel_lpe_audio.c index 3bf65288ffff..5809b29044fc 100644 --- a/drivers/gpu/drm/i915/intel_lpe_audio.c +++ b/drivers/gpu/drm/i915/intel_lpe_audio.c | |||
| @@ -193,7 +193,7 @@ static bool lpe_audio_detect(struct drm_i915_private *dev_priv) | |||
| 193 | }; | 193 | }; |
| 194 | 194 | ||
| 195 | if (!pci_dev_present(atom_hdaudio_ids)) { | 195 | if (!pci_dev_present(atom_hdaudio_ids)) { |
| 196 | DRM_INFO("%s\n", "HDaudio controller not detected, using LPE audio instead\n"); | 196 | DRM_INFO("HDaudio controller not detected, using LPE audio instead\n"); |
| 197 | lpe_present = true; | 197 | lpe_present = true; |
| 198 | } | 198 | } |
| 199 | } | 199 | } |
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 2615912430cc..435ff8662cfa 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c | |||
| @@ -224,7 +224,7 @@ nouveau_bo_new(struct nouveau_cli *cli, u64 size, int align, | |||
| 224 | /* Determine if we can get a cache-coherent map, forcing | 224 | /* Determine if we can get a cache-coherent map, forcing |
| 225 | * uncached mapping if we can't. | 225 | * uncached mapping if we can't. |
| 226 | */ | 226 | */ |
| 227 | if (mmu->type[drm->ttm.type_host].type & NVIF_MEM_UNCACHED) | 227 | if (!nouveau_drm_use_coherent_gpu_mapping(drm)) |
| 228 | nvbo->force_coherent = true; | 228 | nvbo->force_coherent = true; |
| 229 | } | 229 | } |
| 230 | 230 | ||
| @@ -262,7 +262,8 @@ nouveau_bo_new(struct nouveau_cli *cli, u64 size, int align, | |||
| 262 | if (cli->device.info.family > NV_DEVICE_INFO_V0_CURIE && | 262 | if (cli->device.info.family > NV_DEVICE_INFO_V0_CURIE && |
| 263 | (flags & TTM_PL_FLAG_VRAM) && !vmm->page[i].vram) | 263 | (flags & TTM_PL_FLAG_VRAM) && !vmm->page[i].vram) |
| 264 | continue; | 264 | continue; |
| 265 | if ((flags & TTM_PL_FLAG_TT ) && !vmm->page[i].host) | 265 | if ((flags & TTM_PL_FLAG_TT) && |
| 266 | (!vmm->page[i].host || vmm->page[i].shift > PAGE_SHIFT)) | ||
| 266 | continue; | 267 | continue; |
| 267 | 268 | ||
| 268 | /* Select this page size if it's the first that supports | 269 | /* Select this page size if it's the first that supports |
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index 8d4a5be3b913..56fe261b6268 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c | |||
| @@ -152,9 +152,9 @@ nouveau_cli_work_queue(struct nouveau_cli *cli, struct dma_fence *fence, | |||
| 152 | work->cli = cli; | 152 | work->cli = cli; |
| 153 | mutex_lock(&cli->lock); | 153 | mutex_lock(&cli->lock); |
| 154 | list_add_tail(&work->head, &cli->worker); | 154 | list_add_tail(&work->head, &cli->worker); |
| 155 | mutex_unlock(&cli->lock); | ||
| 156 | if (dma_fence_add_callback(fence, &work->cb, nouveau_cli_work_fence)) | 155 | if (dma_fence_add_callback(fence, &work->cb, nouveau_cli_work_fence)) |
| 157 | nouveau_cli_work_fence(fence, &work->cb); | 156 | nouveau_cli_work_fence(fence, &work->cb); |
| 157 | mutex_unlock(&cli->lock); | ||
| 158 | } | 158 | } |
| 159 | 159 | ||
| 160 | static void | 160 | static void |
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 3331e82ae9e7..96f6bd8aee5d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h | |||
| @@ -157,8 +157,8 @@ struct nouveau_drm { | |||
| 157 | struct nvif_object copy; | 157 | struct nvif_object copy; |
| 158 | int mtrr; | 158 | int mtrr; |
| 159 | int type_vram; | 159 | int type_vram; |
| 160 | int type_host; | 160 | int type_host[2]; |
| 161 | int type_ncoh; | 161 | int type_ncoh[2]; |
| 162 | } ttm; | 162 | } ttm; |
| 163 | 163 | ||
| 164 | /* GEM interface support */ | 164 | /* GEM interface support */ |
| @@ -217,6 +217,13 @@ nouveau_drm(struct drm_device *dev) | |||
| 217 | return dev->dev_private; | 217 | return dev->dev_private; |
| 218 | } | 218 | } |
| 219 | 219 | ||
| 220 | static inline bool | ||
| 221 | nouveau_drm_use_coherent_gpu_mapping(struct nouveau_drm *drm) | ||
| 222 | { | ||
| 223 | struct nvif_mmu *mmu = &drm->client.mmu; | ||
| 224 | return !(mmu->type[drm->ttm.type_host[0]].type & NVIF_MEM_UNCACHED); | ||
| 225 | } | ||
| 226 | |||
| 220 | int nouveau_pmops_suspend(struct device *); | 227 | int nouveau_pmops_suspend(struct device *); |
| 221 | int nouveau_pmops_resume(struct device *); | 228 | int nouveau_pmops_resume(struct device *); |
| 222 | bool nouveau_pmops_runtime(void); | 229 | bool nouveau_pmops_runtime(void); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c index c533d8e04afc..be7357bf2246 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c | |||
| @@ -429,7 +429,7 @@ nouveau_fbcon_destroy(struct drm_device *dev, struct nouveau_fbdev *fbcon) | |||
| 429 | drm_fb_helper_unregister_fbi(&fbcon->helper); | 429 | drm_fb_helper_unregister_fbi(&fbcon->helper); |
| 430 | drm_fb_helper_fini(&fbcon->helper); | 430 | drm_fb_helper_fini(&fbcon->helper); |
| 431 | 431 | ||
| 432 | if (nouveau_fb->nvbo) { | 432 | if (nouveau_fb && nouveau_fb->nvbo) { |
| 433 | nouveau_vma_del(&nouveau_fb->vma); | 433 | nouveau_vma_del(&nouveau_fb->vma); |
| 434 | nouveau_bo_unmap(nouveau_fb->nvbo); | 434 | nouveau_bo_unmap(nouveau_fb->nvbo); |
| 435 | nouveau_bo_unpin(nouveau_fb->nvbo); | 435 | nouveau_bo_unpin(nouveau_fb->nvbo); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c index 589a9621db76..c002f8968507 100644 --- a/drivers/gpu/drm/nouveau/nouveau_mem.c +++ b/drivers/gpu/drm/nouveau/nouveau_mem.c | |||
| @@ -103,10 +103,10 @@ nouveau_mem_host(struct ttm_mem_reg *reg, struct ttm_dma_tt *tt) | |||
| 103 | u8 type; | 103 | u8 type; |
| 104 | int ret; | 104 | int ret; |
| 105 | 105 | ||
| 106 | if (mmu->type[drm->ttm.type_host].type & NVIF_MEM_UNCACHED) | 106 | if (!nouveau_drm_use_coherent_gpu_mapping(drm)) |
| 107 | type = drm->ttm.type_ncoh; | 107 | type = drm->ttm.type_ncoh[!!mem->kind]; |
| 108 | else | 108 | else |
| 109 | type = drm->ttm.type_host; | 109 | type = drm->ttm.type_host[0]; |
| 110 | 110 | ||
| 111 | if (mem->kind && !(mmu->type[type].type & NVIF_MEM_KIND)) | 111 | if (mem->kind && !(mmu->type[type].type & NVIF_MEM_KIND)) |
| 112 | mem->comp = mem->kind = 0; | 112 | mem->comp = mem->kind = 0; |
diff --git a/drivers/gpu/drm/nouveau/nouveau_ttm.c b/drivers/gpu/drm/nouveau/nouveau_ttm.c index 08b974b30482..dff51a0ee028 100644 --- a/drivers/gpu/drm/nouveau/nouveau_ttm.c +++ b/drivers/gpu/drm/nouveau/nouveau_ttm.c | |||
| @@ -235,27 +235,46 @@ nouveau_ttm_global_release(struct nouveau_drm *drm) | |||
| 235 | drm->ttm.mem_global_ref.release = NULL; | 235 | drm->ttm.mem_global_ref.release = NULL; |
| 236 | } | 236 | } |
| 237 | 237 | ||
| 238 | int | 238 | static int |
| 239 | nouveau_ttm_init(struct nouveau_drm *drm) | 239 | nouveau_ttm_init_host(struct nouveau_drm *drm, u8 kind) |
| 240 | { | 240 | { |
| 241 | struct nvkm_device *device = nvxx_device(&drm->client.device); | ||
| 242 | struct nvkm_pci *pci = device->pci; | ||
| 243 | struct nvif_mmu *mmu = &drm->client.mmu; | 241 | struct nvif_mmu *mmu = &drm->client.mmu; |
| 244 | struct drm_device *dev = drm->dev; | 242 | int typei; |
| 245 | int typei, ret; | ||
| 246 | 243 | ||
| 247 | typei = nvif_mmu_type(mmu, NVIF_MEM_HOST | NVIF_MEM_MAPPABLE | | 244 | typei = nvif_mmu_type(mmu, NVIF_MEM_HOST | NVIF_MEM_MAPPABLE | |
| 248 | NVIF_MEM_COHERENT); | 245 | kind | NVIF_MEM_COHERENT); |
| 249 | if (typei < 0) | 246 | if (typei < 0) |
| 250 | return -ENOSYS; | 247 | return -ENOSYS; |
| 251 | 248 | ||
| 252 | drm->ttm.type_host = typei; | 249 | drm->ttm.type_host[!!kind] = typei; |
| 253 | 250 | ||
| 254 | typei = nvif_mmu_type(mmu, NVIF_MEM_HOST | NVIF_MEM_MAPPABLE); | 251 | typei = nvif_mmu_type(mmu, NVIF_MEM_HOST | NVIF_MEM_MAPPABLE | kind); |
| 255 | if (typei < 0) | 252 | if (typei < 0) |
| 256 | return -ENOSYS; | 253 | return -ENOSYS; |
| 257 | 254 | ||
| 258 | drm->ttm.type_ncoh = typei; | 255 | drm->ttm.type_ncoh[!!kind] = typei; |
| 256 | return 0; | ||
| 257 | } | ||
| 258 | |||
| 259 | int | ||
| 260 | nouveau_ttm_init(struct nouveau_drm *drm) | ||
| 261 | { | ||
| 262 | struct nvkm_device *device = nvxx_device(&drm->client.device); | ||
| 263 | struct nvkm_pci *pci = device->pci; | ||
| 264 | struct nvif_mmu *mmu = &drm->client.mmu; | ||
| 265 | struct drm_device *dev = drm->dev; | ||
| 266 | int typei, ret; | ||
| 267 | |||
| 268 | ret = nouveau_ttm_init_host(drm, 0); | ||
| 269 | if (ret) | ||
| 270 | return ret; | ||
| 271 | |||
| 272 | if (drm->client.device.info.family >= NV_DEVICE_INFO_V0_TESLA && | ||
| 273 | drm->client.device.info.chipset != 0x50) { | ||
| 274 | ret = nouveau_ttm_init_host(drm, NVIF_MEM_KIND); | ||
| 275 | if (ret) | ||
| 276 | return ret; | ||
| 277 | } | ||
| 259 | 278 | ||
| 260 | if (drm->client.device.info.platform != NV_DEVICE_INFO_V0_SOC && | 279 | if (drm->client.device.info.platform != NV_DEVICE_INFO_V0_SOC && |
| 261 | drm->client.device.info.family >= NV_DEVICE_INFO_V0_TESLA) { | 280 | drm->client.device.info.family >= NV_DEVICE_INFO_V0_TESLA) { |
diff --git a/drivers/gpu/drm/nouveau/nouveau_vmm.c b/drivers/gpu/drm/nouveau/nouveau_vmm.c index 9e2628dd8e4d..f5371d96b003 100644 --- a/drivers/gpu/drm/nouveau/nouveau_vmm.c +++ b/drivers/gpu/drm/nouveau/nouveau_vmm.c | |||
| @@ -67,8 +67,8 @@ nouveau_vma_del(struct nouveau_vma **pvma) | |||
| 67 | nvif_vmm_put(&vma->vmm->vmm, &tmp); | 67 | nvif_vmm_put(&vma->vmm->vmm, &tmp); |
| 68 | } | 68 | } |
| 69 | list_del(&vma->head); | 69 | list_del(&vma->head); |
| 70 | *pvma = NULL; | ||
| 71 | kfree(*pvma); | 70 | kfree(*pvma); |
| 71 | *pvma = NULL; | ||
| 72 | } | 72 | } |
| 73 | } | 73 | } |
| 74 | 74 | ||
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c index e14643615698..00eeaaffeae5 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c | |||
| @@ -2369,7 +2369,7 @@ nv13b_chipset = { | |||
| 2369 | .imem = gk20a_instmem_new, | 2369 | .imem = gk20a_instmem_new, |
| 2370 | .ltc = gp100_ltc_new, | 2370 | .ltc = gp100_ltc_new, |
| 2371 | .mc = gp10b_mc_new, | 2371 | .mc = gp10b_mc_new, |
| 2372 | .mmu = gf100_mmu_new, | 2372 | .mmu = gp10b_mmu_new, |
| 2373 | .secboot = gp10b_secboot_new, | 2373 | .secboot = gp10b_secboot_new, |
| 2374 | .pmu = gm20b_pmu_new, | 2374 | .pmu = gm20b_pmu_new, |
| 2375 | .timer = gk20a_timer_new, | 2375 | .timer = gk20a_timer_new, |
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/dp.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/dp.c index 972370ed36f0..7c7efa4ea0d0 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/dp.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/dp.c | |||
| @@ -36,6 +36,7 @@ nvbios_dp_table(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len) | |||
| 36 | if (data) { | 36 | if (data) { |
| 37 | *ver = nvbios_rd08(bios, data + 0x00); | 37 | *ver = nvbios_rd08(bios, data + 0x00); |
| 38 | switch (*ver) { | 38 | switch (*ver) { |
| 39 | case 0x20: | ||
| 39 | case 0x21: | 40 | case 0x21: |
| 40 | case 0x30: | 41 | case 0x30: |
| 41 | case 0x40: | 42 | case 0x40: |
| @@ -63,6 +64,7 @@ nvbios_dpout_entry(struct nvkm_bios *bios, u8 idx, | |||
| 63 | if (data && idx < *cnt) { | 64 | if (data && idx < *cnt) { |
| 64 | u16 outp = nvbios_rd16(bios, data + *hdr + idx * *len); | 65 | u16 outp = nvbios_rd16(bios, data + *hdr + idx * *len); |
| 65 | switch (*ver * !!outp) { | 66 | switch (*ver * !!outp) { |
| 67 | case 0x20: | ||
| 66 | case 0x21: | 68 | case 0x21: |
| 67 | case 0x30: | 69 | case 0x30: |
| 68 | *hdr = nvbios_rd08(bios, data + 0x04); | 70 | *hdr = nvbios_rd08(bios, data + 0x04); |
| @@ -96,12 +98,16 @@ nvbios_dpout_parse(struct nvkm_bios *bios, u8 idx, | |||
| 96 | info->type = nvbios_rd16(bios, data + 0x00); | 98 | info->type = nvbios_rd16(bios, data + 0x00); |
| 97 | info->mask = nvbios_rd16(bios, data + 0x02); | 99 | info->mask = nvbios_rd16(bios, data + 0x02); |
| 98 | switch (*ver) { | 100 | switch (*ver) { |
| 101 | case 0x20: | ||
| 102 | info->mask |= 0x00c0; /* match any link */ | ||
| 103 | /* fall-through */ | ||
| 99 | case 0x21: | 104 | case 0x21: |
| 100 | case 0x30: | 105 | case 0x30: |
| 101 | info->flags = nvbios_rd08(bios, data + 0x05); | 106 | info->flags = nvbios_rd08(bios, data + 0x05); |
| 102 | info->script[0] = nvbios_rd16(bios, data + 0x06); | 107 | info->script[0] = nvbios_rd16(bios, data + 0x06); |
| 103 | info->script[1] = nvbios_rd16(bios, data + 0x08); | 108 | info->script[1] = nvbios_rd16(bios, data + 0x08); |
| 104 | info->lnkcmp = nvbios_rd16(bios, data + 0x0a); | 109 | if (*len >= 0x0c) |
| 110 | info->lnkcmp = nvbios_rd16(bios, data + 0x0a); | ||
| 105 | if (*len >= 0x0f) { | 111 | if (*len >= 0x0f) { |
| 106 | info->script[2] = nvbios_rd16(bios, data + 0x0c); | 112 | info->script[2] = nvbios_rd16(bios, data + 0x0c); |
| 107 | info->script[3] = nvbios_rd16(bios, data + 0x0e); | 113 | info->script[3] = nvbios_rd16(bios, data + 0x0e); |
| @@ -170,6 +176,7 @@ nvbios_dpcfg_parse(struct nvkm_bios *bios, u16 outp, u8 idx, | |||
| 170 | memset(info, 0x00, sizeof(*info)); | 176 | memset(info, 0x00, sizeof(*info)); |
| 171 | if (data) { | 177 | if (data) { |
| 172 | switch (*ver) { | 178 | switch (*ver) { |
| 179 | case 0x20: | ||
| 173 | case 0x21: | 180 | case 0x21: |
| 174 | info->dc = nvbios_rd08(bios, data + 0x02); | 181 | info->dc = nvbios_rd08(bios, data + 0x02); |
| 175 | info->pe = nvbios_rd08(bios, data + 0x03); | 182 | info->pe = nvbios_rd08(bios, data + 0x03); |
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c index 1ba7289684aa..db48a1daca0c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c | |||
| @@ -249,7 +249,7 @@ nv50_instobj_acquire(struct nvkm_memory *memory) | |||
| 249 | iobj->base.memory.ptrs = &nv50_instobj_fast; | 249 | iobj->base.memory.ptrs = &nv50_instobj_fast; |
| 250 | else | 250 | else |
| 251 | iobj->base.memory.ptrs = &nv50_instobj_slow; | 251 | iobj->base.memory.ptrs = &nv50_instobj_slow; |
| 252 | refcount_inc(&iobj->maps); | 252 | refcount_set(&iobj->maps, 1); |
| 253 | } | 253 | } |
| 254 | 254 | ||
| 255 | mutex_unlock(&imem->subdev.mutex); | 255 | mutex_unlock(&imem->subdev.mutex); |
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c index b1b1f3626b96..deb96de54b00 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c | |||
| @@ -136,6 +136,13 @@ nvkm_pci_init(struct nvkm_subdev *subdev) | |||
| 136 | return ret; | 136 | return ret; |
| 137 | 137 | ||
| 138 | pci->irq = pdev->irq; | 138 | pci->irq = pdev->irq; |
| 139 | |||
| 140 | /* Ensure MSI interrupts are armed, for the case where there are | ||
| 141 | * already interrupts pending (for whatever reason) at load time. | ||
| 142 | */ | ||
| 143 | if (pci->msi) | ||
| 144 | pci->func->msi_rearm(pci); | ||
| 145 | |||
| 139 | return ret; | 146 | return ret; |
| 140 | } | 147 | } |
| 141 | 148 | ||
diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c index dda904ec0534..500b6fb3e028 100644 --- a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c +++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c | |||
| @@ -175,11 +175,31 @@ static void sun4i_hdmi_mode_set(struct drm_encoder *encoder, | |||
| 175 | writel(val, hdmi->base + SUN4I_HDMI_VID_TIMING_POL_REG); | 175 | writel(val, hdmi->base + SUN4I_HDMI_VID_TIMING_POL_REG); |
| 176 | } | 176 | } |
| 177 | 177 | ||
| 178 | static enum drm_mode_status sun4i_hdmi_mode_valid(struct drm_encoder *encoder, | ||
| 179 | const struct drm_display_mode *mode) | ||
| 180 | { | ||
| 181 | struct sun4i_hdmi *hdmi = drm_encoder_to_sun4i_hdmi(encoder); | ||
| 182 | unsigned long rate = mode->clock * 1000; | ||
| 183 | unsigned long diff = rate / 200; /* +-0.5% allowed by HDMI spec */ | ||
| 184 | long rounded_rate; | ||
| 185 | |||
| 186 | /* 165 MHz is the typical max pixelclock frequency for HDMI <= 1.2 */ | ||
| 187 | if (rate > 165000000) | ||
| 188 | return MODE_CLOCK_HIGH; | ||
| 189 | rounded_rate = clk_round_rate(hdmi->tmds_clk, rate); | ||
| 190 | if (rounded_rate > 0 && | ||
| 191 | max_t(unsigned long, rounded_rate, rate) - | ||
| 192 | min_t(unsigned long, rounded_rate, rate) < diff) | ||
| 193 | return MODE_OK; | ||
| 194 | return MODE_NOCLOCK; | ||
| 195 | } | ||
| 196 | |||
| 178 | static const struct drm_encoder_helper_funcs sun4i_hdmi_helper_funcs = { | 197 | static const struct drm_encoder_helper_funcs sun4i_hdmi_helper_funcs = { |
| 179 | .atomic_check = sun4i_hdmi_atomic_check, | 198 | .atomic_check = sun4i_hdmi_atomic_check, |
| 180 | .disable = sun4i_hdmi_disable, | 199 | .disable = sun4i_hdmi_disable, |
| 181 | .enable = sun4i_hdmi_enable, | 200 | .enable = sun4i_hdmi_enable, |
| 182 | .mode_set = sun4i_hdmi_mode_set, | 201 | .mode_set = sun4i_hdmi_mode_set, |
| 202 | .mode_valid = sun4i_hdmi_mode_valid, | ||
| 183 | }; | 203 | }; |
| 184 | 204 | ||
| 185 | static const struct drm_encoder_funcs sun4i_hdmi_funcs = { | 205 | static const struct drm_encoder_funcs sun4i_hdmi_funcs = { |
diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c index e122f5b2a395..f4284b51bdca 100644 --- a/drivers/gpu/drm/sun4i/sun4i_tcon.c +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c | |||
| @@ -724,12 +724,12 @@ static int sun4i_tcon_bind(struct device *dev, struct device *master, | |||
| 724 | if (IS_ERR(tcon->crtc)) { | 724 | if (IS_ERR(tcon->crtc)) { |
| 725 | dev_err(dev, "Couldn't create our CRTC\n"); | 725 | dev_err(dev, "Couldn't create our CRTC\n"); |
| 726 | ret = PTR_ERR(tcon->crtc); | 726 | ret = PTR_ERR(tcon->crtc); |
| 727 | goto err_free_clocks; | 727 | goto err_free_dotclock; |
| 728 | } | 728 | } |
| 729 | 729 | ||
| 730 | ret = sun4i_rgb_init(drm, tcon); | 730 | ret = sun4i_rgb_init(drm, tcon); |
| 731 | if (ret < 0) | 731 | if (ret < 0) |
| 732 | goto err_free_clocks; | 732 | goto err_free_dotclock; |
| 733 | 733 | ||
| 734 | if (tcon->quirks->needs_de_be_mux) { | 734 | if (tcon->quirks->needs_de_be_mux) { |
| 735 | /* | 735 | /* |
diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc.c b/drivers/gpu/drm/ttm/ttm_page_alloc.c index 44343a2bf55c..b5ba6441489f 100644 --- a/drivers/gpu/drm/ttm/ttm_page_alloc.c +++ b/drivers/gpu/drm/ttm/ttm_page_alloc.c | |||
| @@ -455,6 +455,7 @@ ttm_pool_shrink_scan(struct shrinker *shrink, struct shrink_control *sc) | |||
| 455 | freed += (nr_free_pool - shrink_pages) << pool->order; | 455 | freed += (nr_free_pool - shrink_pages) << pool->order; |
| 456 | if (freed >= sc->nr_to_scan) | 456 | if (freed >= sc->nr_to_scan) |
| 457 | break; | 457 | break; |
| 458 | shrink_pages <<= pool->order; | ||
| 458 | } | 459 | } |
| 459 | mutex_unlock(&lock); | 460 | mutex_unlock(&lock); |
| 460 | return freed; | 461 | return freed; |
| @@ -543,7 +544,7 @@ static int ttm_alloc_new_pages(struct list_head *pages, gfp_t gfp_flags, | |||
| 543 | int r = 0; | 544 | int r = 0; |
| 544 | unsigned i, j, cpages; | 545 | unsigned i, j, cpages; |
| 545 | unsigned npages = 1 << order; | 546 | unsigned npages = 1 << order; |
| 546 | unsigned max_cpages = min(count, (unsigned)NUM_PAGES_TO_ALLOC); | 547 | unsigned max_cpages = min(count << order, (unsigned)NUM_PAGES_TO_ALLOC); |
| 547 | 548 | ||
| 548 | /* allocate array for page caching change */ | 549 | /* allocate array for page caching change */ |
| 549 | caching_array = kmalloc(max_cpages*sizeof(struct page *), GFP_KERNEL); | 550 | caching_array = kmalloc(max_cpages*sizeof(struct page *), GFP_KERNEL); |
diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c index 6c32c89a83a9..638540943c61 100644 --- a/drivers/gpu/drm/vc4/vc4_gem.c +++ b/drivers/gpu/drm/vc4/vc4_gem.c | |||
| @@ -888,8 +888,10 @@ vc4_complete_exec(struct drm_device *dev, struct vc4_exec_info *exec) | |||
| 888 | /* If we got force-completed because of GPU reset rather than | 888 | /* If we got force-completed because of GPU reset rather than |
| 889 | * through our IRQ handler, signal the fence now. | 889 | * through our IRQ handler, signal the fence now. |
| 890 | */ | 890 | */ |
| 891 | if (exec->fence) | 891 | if (exec->fence) { |
| 892 | dma_fence_signal(exec->fence); | 892 | dma_fence_signal(exec->fence); |
| 893 | dma_fence_put(exec->fence); | ||
| 894 | } | ||
| 893 | 895 | ||
| 894 | if (exec->bo) { | 896 | if (exec->bo) { |
| 895 | for (i = 0; i < exec->bo_count; i++) { | 897 | for (i = 0; i < exec->bo_count; i++) { |
diff --git a/drivers/gpu/drm/vc4/vc4_irq.c b/drivers/gpu/drm/vc4/vc4_irq.c index 61b2e5377993..26eddbb62893 100644 --- a/drivers/gpu/drm/vc4/vc4_irq.c +++ b/drivers/gpu/drm/vc4/vc4_irq.c | |||
| @@ -139,6 +139,7 @@ vc4_irq_finish_render_job(struct drm_device *dev) | |||
| 139 | list_move_tail(&exec->head, &vc4->job_done_list); | 139 | list_move_tail(&exec->head, &vc4->job_done_list); |
| 140 | if (exec->fence) { | 140 | if (exec->fence) { |
| 141 | dma_fence_signal_locked(exec->fence); | 141 | dma_fence_signal_locked(exec->fence); |
| 142 | dma_fence_put(exec->fence); | ||
| 142 | exec->fence = NULL; | 143 | exec->fence = NULL; |
| 143 | } | 144 | } |
| 144 | vc4_submit_next_render_job(dev); | 145 | vc4_submit_next_render_job(dev); |
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index f3fcb836a1f9..0c3f608131cf 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c | |||
| @@ -551,7 +551,7 @@ static int hid_parser_main(struct hid_parser *parser, struct hid_item *item) | |||
| 551 | ret = hid_add_field(parser, HID_FEATURE_REPORT, data); | 551 | ret = hid_add_field(parser, HID_FEATURE_REPORT, data); |
| 552 | break; | 552 | break; |
| 553 | default: | 553 | default: |
| 554 | hid_err(parser->device, "unknown main item tag 0x%x\n", item->tag); | 554 | hid_warn(parser->device, "unknown main item tag 0x%x\n", item->tag); |
| 555 | ret = 0; | 555 | ret = 0; |
| 556 | } | 556 | } |
| 557 | 557 | ||
diff --git a/drivers/hid/hid-cp2112.c b/drivers/hid/hid-cp2112.c index 68cdc962265b..271f31461da4 100644 --- a/drivers/hid/hid-cp2112.c +++ b/drivers/hid/hid-cp2112.c | |||
| @@ -696,8 +696,16 @@ static int cp2112_xfer(struct i2c_adapter *adap, u16 addr, | |||
| 696 | (u8 *)&word, 2); | 696 | (u8 *)&word, 2); |
| 697 | break; | 697 | break; |
| 698 | case I2C_SMBUS_I2C_BLOCK_DATA: | 698 | case I2C_SMBUS_I2C_BLOCK_DATA: |
| 699 | size = I2C_SMBUS_BLOCK_DATA; | 699 | if (read_write == I2C_SMBUS_READ) { |
| 700 | /* fallthrough */ | 700 | read_length = data->block[0]; |
| 701 | count = cp2112_write_read_req(buf, addr, read_length, | ||
| 702 | command, NULL, 0); | ||
| 703 | } else { | ||
| 704 | count = cp2112_write_req(buf, addr, command, | ||
| 705 | data->block + 1, | ||
| 706 | data->block[0]); | ||
| 707 | } | ||
| 708 | break; | ||
| 701 | case I2C_SMBUS_BLOCK_DATA: | 709 | case I2C_SMBUS_BLOCK_DATA: |
| 702 | if (I2C_SMBUS_READ == read_write) { | 710 | if (I2C_SMBUS_READ == read_write) { |
| 703 | count = cp2112_write_read_req(buf, addr, | 711 | count = cp2112_write_read_req(buf, addr, |
| @@ -785,6 +793,9 @@ static int cp2112_xfer(struct i2c_adapter *adap, u16 addr, | |||
| 785 | case I2C_SMBUS_WORD_DATA: | 793 | case I2C_SMBUS_WORD_DATA: |
| 786 | data->word = le16_to_cpup((__le16 *)buf); | 794 | data->word = le16_to_cpup((__le16 *)buf); |
| 787 | break; | 795 | break; |
| 796 | case I2C_SMBUS_I2C_BLOCK_DATA: | ||
| 797 | memcpy(data->block + 1, buf, read_length); | ||
| 798 | break; | ||
| 788 | case I2C_SMBUS_BLOCK_DATA: | 799 | case I2C_SMBUS_BLOCK_DATA: |
| 789 | if (read_length > I2C_SMBUS_BLOCK_MAX) { | 800 | if (read_length > I2C_SMBUS_BLOCK_MAX) { |
| 790 | ret = -EPROTO; | 801 | ret = -EPROTO; |
diff --git a/drivers/hid/hid-holtekff.c b/drivers/hid/hid-holtekff.c index 9325545fc3ae..edc0f64bb584 100644 --- a/drivers/hid/hid-holtekff.c +++ b/drivers/hid/hid-holtekff.c | |||
| @@ -32,10 +32,6 @@ | |||
| 32 | 32 | ||
| 33 | #ifdef CONFIG_HOLTEK_FF | 33 | #ifdef CONFIG_HOLTEK_FF |
| 34 | 34 | ||
| 35 | MODULE_LICENSE("GPL"); | ||
| 36 | MODULE_AUTHOR("Anssi Hannula <anssi.hannula@iki.fi>"); | ||
| 37 | MODULE_DESCRIPTION("Force feedback support for Holtek On Line Grip based devices"); | ||
| 38 | |||
| 39 | /* | 35 | /* |
| 40 | * These commands and parameters are currently known: | 36 | * These commands and parameters are currently known: |
| 41 | * | 37 | * |
| @@ -223,3 +219,7 @@ static struct hid_driver holtek_driver = { | |||
| 223 | .probe = holtek_probe, | 219 | .probe = holtek_probe, |
| 224 | }; | 220 | }; |
| 225 | module_hid_driver(holtek_driver); | 221 | module_hid_driver(holtek_driver); |
| 222 | |||
| 223 | MODULE_LICENSE("GPL"); | ||
| 224 | MODULE_AUTHOR("Anssi Hannula <anssi.hannula@iki.fi>"); | ||
| 225 | MODULE_DESCRIPTION("Force feedback support for Holtek On Line Grip based devices"); | ||
diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c index 76ed9a216f10..610223f0e945 100644 --- a/drivers/hv/vmbus_drv.c +++ b/drivers/hv/vmbus_drv.c | |||
| @@ -1378,6 +1378,8 @@ void vmbus_device_unregister(struct hv_device *device_obj) | |||
| 1378 | pr_debug("child device %s unregistered\n", | 1378 | pr_debug("child device %s unregistered\n", |
| 1379 | dev_name(&device_obj->device)); | 1379 | dev_name(&device_obj->device)); |
| 1380 | 1380 | ||
| 1381 | kset_unregister(device_obj->channels_kset); | ||
| 1382 | |||
| 1381 | /* | 1383 | /* |
| 1382 | * Kick off the process of unregistering the device. | 1384 | * Kick off the process of unregistering the device. |
| 1383 | * This will call vmbus_remove() and eventually vmbus_device_release() | 1385 | * This will call vmbus_remove() and eventually vmbus_device_release() |
diff --git a/drivers/hwmon/hwmon.c b/drivers/hwmon/hwmon.c index c9790e2c3440..af5123042990 100644 --- a/drivers/hwmon/hwmon.c +++ b/drivers/hwmon/hwmon.c | |||
| @@ -143,6 +143,7 @@ static int hwmon_thermal_add_sensor(struct device *dev, | |||
| 143 | struct hwmon_device *hwdev, int index) | 143 | struct hwmon_device *hwdev, int index) |
| 144 | { | 144 | { |
| 145 | struct hwmon_thermal_data *tdata; | 145 | struct hwmon_thermal_data *tdata; |
| 146 | struct thermal_zone_device *tzd; | ||
| 146 | 147 | ||
| 147 | tdata = devm_kzalloc(dev, sizeof(*tdata), GFP_KERNEL); | 148 | tdata = devm_kzalloc(dev, sizeof(*tdata), GFP_KERNEL); |
| 148 | if (!tdata) | 149 | if (!tdata) |
| @@ -151,8 +152,14 @@ static int hwmon_thermal_add_sensor(struct device *dev, | |||
| 151 | tdata->hwdev = hwdev; | 152 | tdata->hwdev = hwdev; |
| 152 | tdata->index = index; | 153 | tdata->index = index; |
| 153 | 154 | ||
| 154 | devm_thermal_zone_of_sensor_register(&hwdev->dev, index, tdata, | 155 | tzd = devm_thermal_zone_of_sensor_register(&hwdev->dev, index, tdata, |
| 155 | &hwmon_thermal_ops); | 156 | &hwmon_thermal_ops); |
| 157 | /* | ||
| 158 | * If CONFIG_THERMAL_OF is disabled, this returns -ENODEV, | ||
| 159 | * so ignore that error but forward any other error. | ||
| 160 | */ | ||
| 161 | if (IS_ERR(tzd) && (PTR_ERR(tzd) != -ENODEV)) | ||
| 162 | return PTR_ERR(tzd); | ||
| 156 | 163 | ||
| 157 | return 0; | 164 | return 0; |
| 158 | } | 165 | } |
| @@ -621,14 +628,20 @@ __hwmon_device_register(struct device *dev, const char *name, void *drvdata, | |||
| 621 | if (!chip->ops->is_visible(drvdata, hwmon_temp, | 628 | if (!chip->ops->is_visible(drvdata, hwmon_temp, |
| 622 | hwmon_temp_input, j)) | 629 | hwmon_temp_input, j)) |
| 623 | continue; | 630 | continue; |
| 624 | if (info[i]->config[j] & HWMON_T_INPUT) | 631 | if (info[i]->config[j] & HWMON_T_INPUT) { |
| 625 | hwmon_thermal_add_sensor(dev, hwdev, j); | 632 | err = hwmon_thermal_add_sensor(dev, |
| 633 | hwdev, j); | ||
| 634 | if (err) | ||
| 635 | goto free_device; | ||
| 636 | } | ||
| 626 | } | 637 | } |
| 627 | } | 638 | } |
| 628 | } | 639 | } |
| 629 | 640 | ||
| 630 | return hdev; | 641 | return hdev; |
| 631 | 642 | ||
| 643 | free_device: | ||
| 644 | device_unregister(hdev); | ||
| 632 | free_hwmon: | 645 | free_hwmon: |
| 633 | kfree(hwdev); | 646 | kfree(hwdev); |
| 634 | ida_remove: | 647 | ida_remove: |
diff --git a/drivers/hwtracing/stm/ftrace.c b/drivers/hwtracing/stm/ftrace.c index bd126a7c6da2..7da75644c750 100644 --- a/drivers/hwtracing/stm/ftrace.c +++ b/drivers/hwtracing/stm/ftrace.c | |||
| @@ -42,9 +42,11 @@ static struct stm_ftrace { | |||
| 42 | * @len: length of the data packet | 42 | * @len: length of the data packet |
| 43 | */ | 43 | */ |
| 44 | static void notrace | 44 | static void notrace |
| 45 | stm_ftrace_write(const void *buf, unsigned int len) | 45 | stm_ftrace_write(struct trace_export *export, const void *buf, unsigned int len) |
| 46 | { | 46 | { |
| 47 | stm_source_write(&stm_ftrace.data, STM_FTRACE_CHAN, buf, len); | 47 | struct stm_ftrace *stm = container_of(export, struct stm_ftrace, ftrace); |
| 48 | |||
| 49 | stm_source_write(&stm->data, STM_FTRACE_CHAN, buf, len); | ||
| 48 | } | 50 | } |
| 49 | 51 | ||
| 50 | static int stm_ftrace_link(struct stm_source_data *data) | 52 | static int stm_ftrace_link(struct stm_source_data *data) |
diff --git a/drivers/i2c/busses/i2c-cht-wc.c b/drivers/i2c/busses/i2c-cht-wc.c index 0d05dadb2dc5..44cffad43701 100644 --- a/drivers/i2c/busses/i2c-cht-wc.c +++ b/drivers/i2c/busses/i2c-cht-wc.c | |||
| @@ -379,7 +379,7 @@ static int cht_wc_i2c_adap_i2c_remove(struct platform_device *pdev) | |||
| 379 | return 0; | 379 | return 0; |
| 380 | } | 380 | } |
| 381 | 381 | ||
| 382 | static struct platform_device_id cht_wc_i2c_adap_id_table[] = { | 382 | static const struct platform_device_id cht_wc_i2c_adap_id_table[] = { |
| 383 | { .name = "cht_wcove_ext_chgr" }, | 383 | { .name = "cht_wcove_ext_chgr" }, |
| 384 | {}, | 384 | {}, |
| 385 | }; | 385 | }; |
diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c index 174579d32e5f..462948e2c535 100644 --- a/drivers/i2c/busses/i2c-piix4.c +++ b/drivers/i2c/busses/i2c-piix4.c | |||
| @@ -983,7 +983,7 @@ static void piix4_adap_remove(struct i2c_adapter *adap) | |||
| 983 | 983 | ||
| 984 | if (adapdata->smba) { | 984 | if (adapdata->smba) { |
| 985 | i2c_del_adapter(adap); | 985 | i2c_del_adapter(adap); |
| 986 | if (adapdata->port == (0 << 1)) { | 986 | if (adapdata->port == (0 << piix4_port_shift_sb800)) { |
| 987 | release_region(adapdata->smba, SMBIOSIZE); | 987 | release_region(adapdata->smba, SMBIOSIZE); |
| 988 | if (adapdata->sb800_main) | 988 | if (adapdata->sb800_main) |
| 989 | release_region(SB800_PIIX4_SMB_IDX, 2); | 989 | release_region(SB800_PIIX4_SMB_IDX, 2); |
diff --git a/drivers/i2c/busses/i2c-stm32.h b/drivers/i2c/busses/i2c-stm32.h index dab51761f8c5..d4f9cef251ac 100644 --- a/drivers/i2c/busses/i2c-stm32.h +++ b/drivers/i2c/busses/i2c-stm32.h | |||
| @@ -1,10 +1,11 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | ||
| 1 | /* | 2 | /* |
| 2 | * i2c-stm32.h | 3 | * i2c-stm32.h |
| 3 | * | 4 | * |
| 4 | * Copyright (C) M'boumba Cedric Madianga 2017 | 5 | * Copyright (C) M'boumba Cedric Madianga 2017 |
| 6 | * Copyright (C) STMicroelectronics 2017 | ||
| 5 | * Author: M'boumba Cedric Madianga <cedric.madianga@gmail.com> | 7 | * Author: M'boumba Cedric Madianga <cedric.madianga@gmail.com> |
| 6 | * | 8 | * |
| 7 | * License terms: GNU General Public License (GPL), version 2 | ||
| 8 | */ | 9 | */ |
| 9 | 10 | ||
| 10 | #ifndef _I2C_STM32_H | 11 | #ifndef _I2C_STM32_H |
diff --git a/drivers/i2c/busses/i2c-stm32f4.c b/drivers/i2c/busses/i2c-stm32f4.c index 4ec108496f15..47c8d00de53f 100644 --- a/drivers/i2c/busses/i2c-stm32f4.c +++ b/drivers/i2c/busses/i2c-stm32f4.c | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | ||
| 1 | /* | 2 | /* |
| 2 | * Driver for STMicroelectronics STM32 I2C controller | 3 | * Driver for STMicroelectronics STM32 I2C controller |
| 3 | * | 4 | * |
| @@ -6,11 +7,11 @@ | |||
| 6 | * http://www.st.com/resource/en/reference_manual/DM00031020.pdf | 7 | * http://www.st.com/resource/en/reference_manual/DM00031020.pdf |
| 7 | * | 8 | * |
| 8 | * Copyright (C) M'boumba Cedric Madianga 2016 | 9 | * Copyright (C) M'boumba Cedric Madianga 2016 |
| 10 | * Copyright (C) STMicroelectronics 2017 | ||
| 9 | * Author: M'boumba Cedric Madianga <cedric.madianga@gmail.com> | 11 | * Author: M'boumba Cedric Madianga <cedric.madianga@gmail.com> |
| 10 | * | 12 | * |
| 11 | * This driver is based on i2c-st.c | 13 | * This driver is based on i2c-st.c |
| 12 | * | 14 | * |
| 13 | * License terms: GNU General Public License (GPL), version 2 | ||
| 14 | */ | 15 | */ |
| 15 | 16 | ||
| 16 | #include <linux/clk.h> | 17 | #include <linux/clk.h> |
diff --git a/drivers/i2c/busses/i2c-stm32f7.c b/drivers/i2c/busses/i2c-stm32f7.c index d4a6e9c2e9aa..b445b3bb0bb1 100644 --- a/drivers/i2c/busses/i2c-stm32f7.c +++ b/drivers/i2c/busses/i2c-stm32f7.c | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | ||
| 1 | /* | 2 | /* |
| 2 | * Driver for STMicroelectronics STM32F7 I2C controller | 3 | * Driver for STMicroelectronics STM32F7 I2C controller |
| 3 | * | 4 | * |
| @@ -7,11 +8,11 @@ | |||
| 7 | * http://www.st.com/resource/en/reference_manual/dm00124865.pdf | 8 | * http://www.st.com/resource/en/reference_manual/dm00124865.pdf |
| 8 | * | 9 | * |
| 9 | * Copyright (C) M'boumba Cedric Madianga 2017 | 10 | * Copyright (C) M'boumba Cedric Madianga 2017 |
| 11 | * Copyright (C) STMicroelectronics 2017 | ||
| 10 | * Author: M'boumba Cedric Madianga <cedric.madianga@gmail.com> | 12 | * Author: M'boumba Cedric Madianga <cedric.madianga@gmail.com> |
| 11 | * | 13 | * |
| 12 | * This driver is based on i2c-stm32f4.c | 14 | * This driver is based on i2c-stm32f4.c |
| 13 | * | 15 | * |
| 14 | * License terms: GNU General Public License (GPL), version 2 | ||
| 15 | */ | 16 | */ |
| 16 | #include <linux/clk.h> | 17 | #include <linux/clk.h> |
| 17 | #include <linux/delay.h> | 18 | #include <linux/delay.h> |
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c index f6983357145d..6294a7001d33 100644 --- a/drivers/infiniband/core/cma.c +++ b/drivers/infiniband/core/cma.c | |||
| @@ -4458,7 +4458,7 @@ out: | |||
| 4458 | return skb->len; | 4458 | return skb->len; |
| 4459 | } | 4459 | } |
| 4460 | 4460 | ||
| 4461 | static const struct rdma_nl_cbs cma_cb_table[] = { | 4461 | static const struct rdma_nl_cbs cma_cb_table[RDMA_NL_RDMA_CM_NUM_OPS] = { |
| 4462 | [RDMA_NL_RDMA_CM_ID_STATS] = { .dump = cma_get_id_stats}, | 4462 | [RDMA_NL_RDMA_CM_ID_STATS] = { .dump = cma_get_id_stats}, |
| 4463 | }; | 4463 | }; |
| 4464 | 4464 | ||
diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c index 5e1be4949d5f..30914f3baa5f 100644 --- a/drivers/infiniband/core/device.c +++ b/drivers/infiniband/core/device.c | |||
| @@ -1146,7 +1146,7 @@ struct net_device *ib_get_net_dev_by_params(struct ib_device *dev, | |||
| 1146 | } | 1146 | } |
| 1147 | EXPORT_SYMBOL(ib_get_net_dev_by_params); | 1147 | EXPORT_SYMBOL(ib_get_net_dev_by_params); |
| 1148 | 1148 | ||
| 1149 | static const struct rdma_nl_cbs ibnl_ls_cb_table[] = { | 1149 | static const struct rdma_nl_cbs ibnl_ls_cb_table[RDMA_NL_LS_NUM_OPS] = { |
| 1150 | [RDMA_NL_LS_OP_RESOLVE] = { | 1150 | [RDMA_NL_LS_OP_RESOLVE] = { |
| 1151 | .doit = ib_nl_handle_resolve_resp, | 1151 | .doit = ib_nl_handle_resolve_resp, |
| 1152 | .flags = RDMA_NL_ADMIN_PERM, | 1152 | .flags = RDMA_NL_ADMIN_PERM, |
diff --git a/drivers/infiniband/core/iwcm.c b/drivers/infiniband/core/iwcm.c index e9e189ec7502..5d676cff41f4 100644 --- a/drivers/infiniband/core/iwcm.c +++ b/drivers/infiniband/core/iwcm.c | |||
| @@ -80,7 +80,7 @@ const char *__attribute_const__ iwcm_reject_msg(int reason) | |||
| 80 | } | 80 | } |
| 81 | EXPORT_SYMBOL(iwcm_reject_msg); | 81 | EXPORT_SYMBOL(iwcm_reject_msg); |
| 82 | 82 | ||
| 83 | static struct rdma_nl_cbs iwcm_nl_cb_table[] = { | 83 | static struct rdma_nl_cbs iwcm_nl_cb_table[RDMA_NL_IWPM_NUM_OPS] = { |
| 84 | [RDMA_NL_IWPM_REG_PID] = {.dump = iwpm_register_pid_cb}, | 84 | [RDMA_NL_IWPM_REG_PID] = {.dump = iwpm_register_pid_cb}, |
| 85 | [RDMA_NL_IWPM_ADD_MAPPING] = {.dump = iwpm_add_mapping_cb}, | 85 | [RDMA_NL_IWPM_ADD_MAPPING] = {.dump = iwpm_add_mapping_cb}, |
| 86 | [RDMA_NL_IWPM_QUERY_MAPPING] = {.dump = iwpm_add_and_query_mapping_cb}, | 86 | [RDMA_NL_IWPM_QUERY_MAPPING] = {.dump = iwpm_add_and_query_mapping_cb}, |
diff --git a/drivers/infiniband/core/nldev.c b/drivers/infiniband/core/nldev.c index 2fae850a3eff..9a05245a1acf 100644 --- a/drivers/infiniband/core/nldev.c +++ b/drivers/infiniband/core/nldev.c | |||
| @@ -303,7 +303,7 @@ out: cb->args[0] = idx; | |||
| 303 | return skb->len; | 303 | return skb->len; |
| 304 | } | 304 | } |
| 305 | 305 | ||
| 306 | static const struct rdma_nl_cbs nldev_cb_table[] = { | 306 | static const struct rdma_nl_cbs nldev_cb_table[RDMA_NLDEV_NUM_OPS] = { |
| 307 | [RDMA_NLDEV_CMD_GET] = { | 307 | [RDMA_NLDEV_CMD_GET] = { |
| 308 | .doit = nldev_get_doit, | 308 | .doit = nldev_get_doit, |
| 309 | .dump = nldev_get_dumpit, | 309 | .dump = nldev_get_dumpit, |
diff --git a/drivers/infiniband/core/security.c b/drivers/infiniband/core/security.c index a337386652b0..59b2f96d986a 100644 --- a/drivers/infiniband/core/security.c +++ b/drivers/infiniband/core/security.c | |||
| @@ -386,6 +386,9 @@ int ib_open_shared_qp_security(struct ib_qp *qp, struct ib_device *dev) | |||
| 386 | if (ret) | 386 | if (ret) |
| 387 | return ret; | 387 | return ret; |
| 388 | 388 | ||
| 389 | if (!qp->qp_sec) | ||
| 390 | return 0; | ||
| 391 | |||
| 389 | mutex_lock(&real_qp->qp_sec->mutex); | 392 | mutex_lock(&real_qp->qp_sec->mutex); |
| 390 | ret = check_qp_port_pkey_settings(real_qp->qp_sec->ports_pkeys, | 393 | ret = check_qp_port_pkey_settings(real_qp->qp_sec->ports_pkeys, |
| 391 | qp->qp_sec); | 394 | qp->qp_sec); |
| @@ -739,8 +742,11 @@ int ib_mad_enforce_security(struct ib_mad_agent_private *map, u16 pkey_index) | |||
| 739 | if (!rdma_protocol_ib(map->agent.device, map->agent.port_num)) | 742 | if (!rdma_protocol_ib(map->agent.device, map->agent.port_num)) |
| 740 | return 0; | 743 | return 0; |
| 741 | 744 | ||
| 742 | if (map->agent.qp->qp_type == IB_QPT_SMI && !map->agent.smp_allowed) | 745 | if (map->agent.qp->qp_type == IB_QPT_SMI) { |
| 743 | return -EACCES; | 746 | if (!map->agent.smp_allowed) |
| 747 | return -EACCES; | ||
| 748 | return 0; | ||
| 749 | } | ||
| 744 | 750 | ||
| 745 | return ib_security_pkey_access(map->agent.device, | 751 | return ib_security_pkey_access(map->agent.device, |
| 746 | map->agent.port_num, | 752 | map->agent.port_num, |
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c index 16d55710b116..840b24096690 100644 --- a/drivers/infiniband/core/uverbs_cmd.c +++ b/drivers/infiniband/core/uverbs_cmd.c | |||
| @@ -1971,6 +1971,12 @@ static int modify_qp(struct ib_uverbs_file *file, | |||
| 1971 | goto release_qp; | 1971 | goto release_qp; |
| 1972 | } | 1972 | } |
| 1973 | 1973 | ||
| 1974 | if ((cmd->base.attr_mask & IB_QP_ALT_PATH) && | ||
| 1975 | !rdma_is_port_valid(qp->device, cmd->base.alt_port_num)) { | ||
| 1976 | ret = -EINVAL; | ||
| 1977 | goto release_qp; | ||
| 1978 | } | ||
| 1979 | |||
| 1974 | attr->qp_state = cmd->base.qp_state; | 1980 | attr->qp_state = cmd->base.qp_state; |
| 1975 | attr->cur_qp_state = cmd->base.cur_qp_state; | 1981 | attr->cur_qp_state = cmd->base.cur_qp_state; |
| 1976 | attr->path_mtu = cmd->base.path_mtu; | 1982 | attr->path_mtu = cmd->base.path_mtu; |
| @@ -2068,8 +2074,8 @@ int ib_uverbs_ex_modify_qp(struct ib_uverbs_file *file, | |||
| 2068 | return -EOPNOTSUPP; | 2074 | return -EOPNOTSUPP; |
| 2069 | 2075 | ||
| 2070 | if (ucore->inlen > sizeof(cmd)) { | 2076 | if (ucore->inlen > sizeof(cmd)) { |
| 2071 | if (ib_is_udata_cleared(ucore, sizeof(cmd), | 2077 | if (!ib_is_udata_cleared(ucore, sizeof(cmd), |
| 2072 | ucore->inlen - sizeof(cmd))) | 2078 | ucore->inlen - sizeof(cmd))) |
| 2073 | return -EOPNOTSUPP; | 2079 | return -EOPNOTSUPP; |
| 2074 | } | 2080 | } |
| 2075 | 2081 | ||
diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c index 3fb8fb6cc824..e36d27ed4daa 100644 --- a/drivers/infiniband/core/verbs.c +++ b/drivers/infiniband/core/verbs.c | |||
| @@ -1438,7 +1438,8 @@ int ib_close_qp(struct ib_qp *qp) | |||
| 1438 | spin_unlock_irqrestore(&real_qp->device->event_handler_lock, flags); | 1438 | spin_unlock_irqrestore(&real_qp->device->event_handler_lock, flags); |
| 1439 | 1439 | ||
| 1440 | atomic_dec(&real_qp->usecnt); | 1440 | atomic_dec(&real_qp->usecnt); |
| 1441 | ib_close_shared_qp_security(qp->qp_sec); | 1441 | if (qp->qp_sec) |
| 1442 | ib_close_shared_qp_security(qp->qp_sec); | ||
| 1442 | kfree(qp); | 1443 | kfree(qp); |
| 1443 | 1444 | ||
| 1444 | return 0; | 1445 | return 0; |
diff --git a/drivers/infiniband/hw/cxgb4/cq.c b/drivers/infiniband/hw/cxgb4/cq.c index ea55e95cd2c5..6f2b26126c64 100644 --- a/drivers/infiniband/hw/cxgb4/cq.c +++ b/drivers/infiniband/hw/cxgb4/cq.c | |||
| @@ -395,6 +395,11 @@ next_cqe: | |||
| 395 | 395 | ||
| 396 | static int cqe_completes_wr(struct t4_cqe *cqe, struct t4_wq *wq) | 396 | static int cqe_completes_wr(struct t4_cqe *cqe, struct t4_wq *wq) |
| 397 | { | 397 | { |
| 398 | if (DRAIN_CQE(cqe)) { | ||
| 399 | WARN_ONCE(1, "Unexpected DRAIN CQE qp id %u!\n", wq->sq.qid); | ||
| 400 | return 0; | ||
| 401 | } | ||
| 402 | |||
| 398 | if (CQE_OPCODE(cqe) == FW_RI_TERMINATE) | 403 | if (CQE_OPCODE(cqe) == FW_RI_TERMINATE) |
| 399 | return 0; | 404 | return 0; |
| 400 | 405 | ||
| @@ -489,7 +494,7 @@ static int poll_cq(struct t4_wq *wq, struct t4_cq *cq, struct t4_cqe *cqe, | |||
| 489 | /* | 494 | /* |
| 490 | * Special cqe for drain WR completions... | 495 | * Special cqe for drain WR completions... |
| 491 | */ | 496 | */ |
| 492 | if (CQE_OPCODE(hw_cqe) == C4IW_DRAIN_OPCODE) { | 497 | if (DRAIN_CQE(hw_cqe)) { |
| 493 | *cookie = CQE_DRAIN_COOKIE(hw_cqe); | 498 | *cookie = CQE_DRAIN_COOKIE(hw_cqe); |
| 494 | *cqe = *hw_cqe; | 499 | *cqe = *hw_cqe; |
| 495 | goto skip_cqe; | 500 | goto skip_cqe; |
| @@ -566,10 +571,10 @@ static int poll_cq(struct t4_wq *wq, struct t4_cq *cq, struct t4_cqe *cqe, | |||
| 566 | ret = -EAGAIN; | 571 | ret = -EAGAIN; |
| 567 | goto skip_cqe; | 572 | goto skip_cqe; |
| 568 | } | 573 | } |
| 569 | if (unlikely((CQE_WRID_MSN(hw_cqe) != (wq->rq.msn)))) { | 574 | if (unlikely(!CQE_STATUS(hw_cqe) && |
| 575 | CQE_WRID_MSN(hw_cqe) != wq->rq.msn)) { | ||
| 570 | t4_set_wq_in_error(wq); | 576 | t4_set_wq_in_error(wq); |
| 571 | hw_cqe->header |= htonl(CQE_STATUS_V(T4_ERR_MSN)); | 577 | hw_cqe->header |= cpu_to_be32(CQE_STATUS_V(T4_ERR_MSN)); |
| 572 | goto proc_cqe; | ||
| 573 | } | 578 | } |
| 574 | goto proc_cqe; | 579 | goto proc_cqe; |
| 575 | } | 580 | } |
| @@ -743,9 +748,6 @@ static int c4iw_poll_cq_one(struct c4iw_cq *chp, struct ib_wc *wc) | |||
| 743 | c4iw_invalidate_mr(qhp->rhp, | 748 | c4iw_invalidate_mr(qhp->rhp, |
| 744 | CQE_WRID_FR_STAG(&cqe)); | 749 | CQE_WRID_FR_STAG(&cqe)); |
| 745 | break; | 750 | break; |
| 746 | case C4IW_DRAIN_OPCODE: | ||
| 747 | wc->opcode = IB_WC_SEND; | ||
| 748 | break; | ||
| 749 | default: | 751 | default: |
| 750 | pr_err("Unexpected opcode %d in the CQE received for QPID=0x%0x\n", | 752 | pr_err("Unexpected opcode %d in the CQE received for QPID=0x%0x\n", |
| 751 | CQE_OPCODE(&cqe), CQE_QPID(&cqe)); | 753 | CQE_OPCODE(&cqe), CQE_QPID(&cqe)); |
diff --git a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h index 470f97a79ebb..65dd3726ca02 100644 --- a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h +++ b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h | |||
| @@ -693,8 +693,6 @@ static inline int to_ib_qp_state(int c4iw_qp_state) | |||
| 693 | return IB_QPS_ERR; | 693 | return IB_QPS_ERR; |
| 694 | } | 694 | } |
| 695 | 695 | ||
| 696 | #define C4IW_DRAIN_OPCODE FW_RI_SGE_EC_CR_RETURN | ||
| 697 | |||
| 698 | static inline u32 c4iw_ib_to_tpt_access(int a) | 696 | static inline u32 c4iw_ib_to_tpt_access(int a) |
| 699 | { | 697 | { |
| 700 | return (a & IB_ACCESS_REMOTE_WRITE ? FW_RI_MEM_ACCESS_REM_WRITE : 0) | | 698 | return (a & IB_ACCESS_REMOTE_WRITE ? FW_RI_MEM_ACCESS_REM_WRITE : 0) | |
diff --git a/drivers/infiniband/hw/cxgb4/qp.c b/drivers/infiniband/hw/cxgb4/qp.c index 5ee7fe433136..d5c92fc520d6 100644 --- a/drivers/infiniband/hw/cxgb4/qp.c +++ b/drivers/infiniband/hw/cxgb4/qp.c | |||
| @@ -790,21 +790,57 @@ static int ring_kernel_rq_db(struct c4iw_qp *qhp, u16 inc) | |||
| 790 | return 0; | 790 | return 0; |
| 791 | } | 791 | } |
| 792 | 792 | ||
| 793 | static void complete_sq_drain_wr(struct c4iw_qp *qhp, struct ib_send_wr *wr) | 793 | static int ib_to_fw_opcode(int ib_opcode) |
| 794 | { | ||
| 795 | int opcode; | ||
| 796 | |||
| 797 | switch (ib_opcode) { | ||
| 798 | case IB_WR_SEND_WITH_INV: | ||
| 799 | opcode = FW_RI_SEND_WITH_INV; | ||
| 800 | break; | ||
| 801 | case IB_WR_SEND: | ||
| 802 | opcode = FW_RI_SEND; | ||
| 803 | break; | ||
| 804 | case IB_WR_RDMA_WRITE: | ||
| 805 | opcode = FW_RI_RDMA_WRITE; | ||
| 806 | break; | ||
| 807 | case IB_WR_RDMA_READ: | ||
| 808 | case IB_WR_RDMA_READ_WITH_INV: | ||
| 809 | opcode = FW_RI_READ_REQ; | ||
| 810 | break; | ||
| 811 | case IB_WR_REG_MR: | ||
| 812 | opcode = FW_RI_FAST_REGISTER; | ||
| 813 | break; | ||
| 814 | case IB_WR_LOCAL_INV: | ||
| 815 | opcode = FW_RI_LOCAL_INV; | ||
| 816 | break; | ||
| 817 | default: | ||
| 818 | opcode = -EINVAL; | ||
| 819 | } | ||
| 820 | return opcode; | ||
| 821 | } | ||
| 822 | |||
| 823 | static int complete_sq_drain_wr(struct c4iw_qp *qhp, struct ib_send_wr *wr) | ||
| 794 | { | 824 | { |
| 795 | struct t4_cqe cqe = {}; | 825 | struct t4_cqe cqe = {}; |
| 796 | struct c4iw_cq *schp; | 826 | struct c4iw_cq *schp; |
| 797 | unsigned long flag; | 827 | unsigned long flag; |
| 798 | struct t4_cq *cq; | 828 | struct t4_cq *cq; |
| 829 | int opcode; | ||
| 799 | 830 | ||
| 800 | schp = to_c4iw_cq(qhp->ibqp.send_cq); | 831 | schp = to_c4iw_cq(qhp->ibqp.send_cq); |
| 801 | cq = &schp->cq; | 832 | cq = &schp->cq; |
| 802 | 833 | ||
| 834 | opcode = ib_to_fw_opcode(wr->opcode); | ||
| 835 | if (opcode < 0) | ||
| 836 | return opcode; | ||
| 837 | |||
| 803 | cqe.u.drain_cookie = wr->wr_id; | 838 | cqe.u.drain_cookie = wr->wr_id; |
| 804 | cqe.header = cpu_to_be32(CQE_STATUS_V(T4_ERR_SWFLUSH) | | 839 | cqe.header = cpu_to_be32(CQE_STATUS_V(T4_ERR_SWFLUSH) | |
| 805 | CQE_OPCODE_V(C4IW_DRAIN_OPCODE) | | 840 | CQE_OPCODE_V(opcode) | |
| 806 | CQE_TYPE_V(1) | | 841 | CQE_TYPE_V(1) | |
| 807 | CQE_SWCQE_V(1) | | 842 | CQE_SWCQE_V(1) | |
| 843 | CQE_DRAIN_V(1) | | ||
| 808 | CQE_QPID_V(qhp->wq.sq.qid)); | 844 | CQE_QPID_V(qhp->wq.sq.qid)); |
| 809 | 845 | ||
| 810 | spin_lock_irqsave(&schp->lock, flag); | 846 | spin_lock_irqsave(&schp->lock, flag); |
| @@ -819,6 +855,23 @@ static void complete_sq_drain_wr(struct c4iw_qp *qhp, struct ib_send_wr *wr) | |||
| 819 | schp->ibcq.cq_context); | 855 | schp->ibcq.cq_context); |
| 820 | spin_unlock_irqrestore(&schp->comp_handler_lock, flag); | 856 | spin_unlock_irqrestore(&schp->comp_handler_lock, flag); |
| 821 | } | 857 | } |
| 858 | return 0; | ||
| 859 | } | ||
| 860 | |||
| 861 | static int complete_sq_drain_wrs(struct c4iw_qp *qhp, struct ib_send_wr *wr, | ||
| 862 | struct ib_send_wr **bad_wr) | ||
| 863 | { | ||
| 864 | int ret = 0; | ||
| 865 | |||
| 866 | while (wr) { | ||
| 867 | ret = complete_sq_drain_wr(qhp, wr); | ||
| 868 | if (ret) { | ||
| 869 | *bad_wr = wr; | ||
| 870 | break; | ||
| 871 | } | ||
| 872 | wr = wr->next; | ||
| 873 | } | ||
| 874 | return ret; | ||
| 822 | } | 875 | } |
| 823 | 876 | ||
| 824 | static void complete_rq_drain_wr(struct c4iw_qp *qhp, struct ib_recv_wr *wr) | 877 | static void complete_rq_drain_wr(struct c4iw_qp *qhp, struct ib_recv_wr *wr) |
| @@ -833,9 +886,10 @@ static void complete_rq_drain_wr(struct c4iw_qp *qhp, struct ib_recv_wr *wr) | |||
| 833 | 886 | ||
| 834 | cqe.u.drain_cookie = wr->wr_id; | 887 | cqe.u.drain_cookie = wr->wr_id; |
| 835 | cqe.header = cpu_to_be32(CQE_STATUS_V(T4_ERR_SWFLUSH) | | 888 | cqe.header = cpu_to_be32(CQE_STATUS_V(T4_ERR_SWFLUSH) | |
| 836 | CQE_OPCODE_V(C4IW_DRAIN_OPCODE) | | 889 | CQE_OPCODE_V(FW_RI_SEND) | |
| 837 | CQE_TYPE_V(0) | | 890 | CQE_TYPE_V(0) | |
| 838 | CQE_SWCQE_V(1) | | 891 | CQE_SWCQE_V(1) | |
| 892 | CQE_DRAIN_V(1) | | ||
| 839 | CQE_QPID_V(qhp->wq.sq.qid)); | 893 | CQE_QPID_V(qhp->wq.sq.qid)); |
| 840 | 894 | ||
| 841 | spin_lock_irqsave(&rchp->lock, flag); | 895 | spin_lock_irqsave(&rchp->lock, flag); |
| @@ -852,6 +906,14 @@ static void complete_rq_drain_wr(struct c4iw_qp *qhp, struct ib_recv_wr *wr) | |||
| 852 | } | 906 | } |
| 853 | } | 907 | } |
| 854 | 908 | ||
| 909 | static void complete_rq_drain_wrs(struct c4iw_qp *qhp, struct ib_recv_wr *wr) | ||
| 910 | { | ||
| 911 | while (wr) { | ||
| 912 | complete_rq_drain_wr(qhp, wr); | ||
| 913 | wr = wr->next; | ||
| 914 | } | ||
| 915 | } | ||
| 916 | |||
| 855 | int c4iw_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, | 917 | int c4iw_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, |
| 856 | struct ib_send_wr **bad_wr) | 918 | struct ib_send_wr **bad_wr) |
| 857 | { | 919 | { |
| @@ -868,9 +930,14 @@ int c4iw_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, | |||
| 868 | 930 | ||
| 869 | qhp = to_c4iw_qp(ibqp); | 931 | qhp = to_c4iw_qp(ibqp); |
| 870 | spin_lock_irqsave(&qhp->lock, flag); | 932 | spin_lock_irqsave(&qhp->lock, flag); |
| 871 | if (t4_wq_in_error(&qhp->wq)) { | 933 | |
| 934 | /* | ||
| 935 | * If the qp has been flushed, then just insert a special | ||
| 936 | * drain cqe. | ||
| 937 | */ | ||
| 938 | if (qhp->wq.flushed) { | ||
| 872 | spin_unlock_irqrestore(&qhp->lock, flag); | 939 | spin_unlock_irqrestore(&qhp->lock, flag); |
| 873 | complete_sq_drain_wr(qhp, wr); | 940 | err = complete_sq_drain_wrs(qhp, wr, bad_wr); |
| 874 | return err; | 941 | return err; |
| 875 | } | 942 | } |
| 876 | num_wrs = t4_sq_avail(&qhp->wq); | 943 | num_wrs = t4_sq_avail(&qhp->wq); |
| @@ -1011,9 +1078,14 @@ int c4iw_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr, | |||
| 1011 | 1078 | ||
| 1012 | qhp = to_c4iw_qp(ibqp); | 1079 | qhp = to_c4iw_qp(ibqp); |
| 1013 | spin_lock_irqsave(&qhp->lock, flag); | 1080 | spin_lock_irqsave(&qhp->lock, flag); |
| 1014 | if (t4_wq_in_error(&qhp->wq)) { | 1081 | |
| 1082 | /* | ||
| 1083 | * If the qp has been flushed, then just insert a special | ||
| 1084 | * drain cqe. | ||
| 1085 | */ | ||
| 1086 | if (qhp->wq.flushed) { | ||
| 1015 | spin_unlock_irqrestore(&qhp->lock, flag); | 1087 | spin_unlock_irqrestore(&qhp->lock, flag); |
| 1016 | complete_rq_drain_wr(qhp, wr); | 1088 | complete_rq_drain_wrs(qhp, wr); |
| 1017 | return err; | 1089 | return err; |
| 1018 | } | 1090 | } |
| 1019 | num_wrs = t4_rq_avail(&qhp->wq); | 1091 | num_wrs = t4_rq_avail(&qhp->wq); |
| @@ -1285,21 +1357,21 @@ static void __flush_qp(struct c4iw_qp *qhp, struct c4iw_cq *rchp, | |||
| 1285 | spin_unlock_irqrestore(&rchp->lock, flag); | 1357 | spin_unlock_irqrestore(&rchp->lock, flag); |
| 1286 | 1358 | ||
| 1287 | if (schp == rchp) { | 1359 | if (schp == rchp) { |
| 1288 | if (t4_clear_cq_armed(&rchp->cq) && | 1360 | if ((rq_flushed || sq_flushed) && |
| 1289 | (rq_flushed || sq_flushed)) { | 1361 | t4_clear_cq_armed(&rchp->cq)) { |
| 1290 | spin_lock_irqsave(&rchp->comp_handler_lock, flag); | 1362 | spin_lock_irqsave(&rchp->comp_handler_lock, flag); |
| 1291 | (*rchp->ibcq.comp_handler)(&rchp->ibcq, | 1363 | (*rchp->ibcq.comp_handler)(&rchp->ibcq, |
| 1292 | rchp->ibcq.cq_context); | 1364 | rchp->ibcq.cq_context); |
| 1293 | spin_unlock_irqrestore(&rchp->comp_handler_lock, flag); | 1365 | spin_unlock_irqrestore(&rchp->comp_handler_lock, flag); |
| 1294 | } | 1366 | } |
| 1295 | } else { | 1367 | } else { |
| 1296 | if (t4_clear_cq_armed(&rchp->cq) && rq_flushed) { | 1368 | if (rq_flushed && t4_clear_cq_armed(&rchp->cq)) { |
| 1297 | spin_lock_irqsave(&rchp->comp_handler_lock, flag); | 1369 | spin_lock_irqsave(&rchp->comp_handler_lock, flag); |
| 1298 | (*rchp->ibcq.comp_handler)(&rchp->ibcq, | 1370 | (*rchp->ibcq.comp_handler)(&rchp->ibcq, |
| 1299 | rchp->ibcq.cq_context); | 1371 | rchp->ibcq.cq_context); |
| 1300 | spin_unlock_irqrestore(&rchp->comp_handler_lock, flag); | 1372 | spin_unlock_irqrestore(&rchp->comp_handler_lock, flag); |
| 1301 | } | 1373 | } |
| 1302 | if (t4_clear_cq_armed(&schp->cq) && sq_flushed) { | 1374 | if (sq_flushed && t4_clear_cq_armed(&schp->cq)) { |
| 1303 | spin_lock_irqsave(&schp->comp_handler_lock, flag); | 1375 | spin_lock_irqsave(&schp->comp_handler_lock, flag); |
| 1304 | (*schp->ibcq.comp_handler)(&schp->ibcq, | 1376 | (*schp->ibcq.comp_handler)(&schp->ibcq, |
| 1305 | schp->ibcq.cq_context); | 1377 | schp->ibcq.cq_context); |
diff --git a/drivers/infiniband/hw/cxgb4/t4.h b/drivers/infiniband/hw/cxgb4/t4.h index e9ea94268d51..79e8ee12c391 100644 --- a/drivers/infiniband/hw/cxgb4/t4.h +++ b/drivers/infiniband/hw/cxgb4/t4.h | |||
| @@ -197,6 +197,11 @@ struct t4_cqe { | |||
| 197 | #define CQE_SWCQE_G(x) ((((x) >> CQE_SWCQE_S)) & CQE_SWCQE_M) | 197 | #define CQE_SWCQE_G(x) ((((x) >> CQE_SWCQE_S)) & CQE_SWCQE_M) |
| 198 | #define CQE_SWCQE_V(x) ((x)<<CQE_SWCQE_S) | 198 | #define CQE_SWCQE_V(x) ((x)<<CQE_SWCQE_S) |
| 199 | 199 | ||
| 200 | #define CQE_DRAIN_S 10 | ||
| 201 | #define CQE_DRAIN_M 0x1 | ||
| 202 | #define CQE_DRAIN_G(x) ((((x) >> CQE_DRAIN_S)) & CQE_DRAIN_M) | ||
| 203 | #define CQE_DRAIN_V(x) ((x)<<CQE_DRAIN_S) | ||
| 204 | |||
| 200 | #define CQE_STATUS_S 5 | 205 | #define CQE_STATUS_S 5 |
| 201 | #define CQE_STATUS_M 0x1F | 206 | #define CQE_STATUS_M 0x1F |
| 202 | #define CQE_STATUS_G(x) ((((x) >> CQE_STATUS_S)) & CQE_STATUS_M) | 207 | #define CQE_STATUS_G(x) ((((x) >> CQE_STATUS_S)) & CQE_STATUS_M) |
| @@ -213,6 +218,7 @@ struct t4_cqe { | |||
| 213 | #define CQE_OPCODE_V(x) ((x)<<CQE_OPCODE_S) | 218 | #define CQE_OPCODE_V(x) ((x)<<CQE_OPCODE_S) |
| 214 | 219 | ||
| 215 | #define SW_CQE(x) (CQE_SWCQE_G(be32_to_cpu((x)->header))) | 220 | #define SW_CQE(x) (CQE_SWCQE_G(be32_to_cpu((x)->header))) |
| 221 | #define DRAIN_CQE(x) (CQE_DRAIN_G(be32_to_cpu((x)->header))) | ||
| 216 | #define CQE_QPID(x) (CQE_QPID_G(be32_to_cpu((x)->header))) | 222 | #define CQE_QPID(x) (CQE_QPID_G(be32_to_cpu((x)->header))) |
| 217 | #define CQE_TYPE(x) (CQE_TYPE_G(be32_to_cpu((x)->header))) | 223 | #define CQE_TYPE(x) (CQE_TYPE_G(be32_to_cpu((x)->header))) |
| 218 | #define SQ_TYPE(x) (CQE_TYPE((x))) | 224 | #define SQ_TYPE(x) (CQE_TYPE((x))) |
diff --git a/drivers/infiniband/hw/hfi1/hfi.h b/drivers/infiniband/hw/hfi1/hfi.h index 4a9b4d7efe63..8ce9118d4a7f 100644 --- a/drivers/infiniband/hw/hfi1/hfi.h +++ b/drivers/infiniband/hw/hfi1/hfi.h | |||
| @@ -1131,7 +1131,6 @@ struct hfi1_devdata { | |||
| 1131 | u16 pcie_lnkctl; | 1131 | u16 pcie_lnkctl; |
| 1132 | u16 pcie_devctl2; | 1132 | u16 pcie_devctl2; |
| 1133 | u32 pci_msix0; | 1133 | u32 pci_msix0; |
| 1134 | u32 pci_lnkctl3; | ||
| 1135 | u32 pci_tph2; | 1134 | u32 pci_tph2; |
| 1136 | 1135 | ||
| 1137 | /* | 1136 | /* |
diff --git a/drivers/infiniband/hw/hfi1/pcie.c b/drivers/infiniband/hw/hfi1/pcie.c index 09e50fd2a08f..8c7e7a60b715 100644 --- a/drivers/infiniband/hw/hfi1/pcie.c +++ b/drivers/infiniband/hw/hfi1/pcie.c | |||
| @@ -411,15 +411,12 @@ int restore_pci_variables(struct hfi1_devdata *dd) | |||
| 411 | if (ret) | 411 | if (ret) |
| 412 | goto error; | 412 | goto error; |
| 413 | 413 | ||
| 414 | ret = pci_write_config_dword(dd->pcidev, PCIE_CFG_SPCIE1, | 414 | if (pci_find_ext_capability(dd->pcidev, PCI_EXT_CAP_ID_TPH)) { |
| 415 | dd->pci_lnkctl3); | 415 | ret = pci_write_config_dword(dd->pcidev, PCIE_CFG_TPH2, |
| 416 | if (ret) | 416 | dd->pci_tph2); |
| 417 | goto error; | 417 | if (ret) |
| 418 | 418 | goto error; | |
| 419 | ret = pci_write_config_dword(dd->pcidev, PCIE_CFG_TPH2, dd->pci_tph2); | 419 | } |
| 420 | if (ret) | ||
| 421 | goto error; | ||
| 422 | |||
| 423 | return 0; | 420 | return 0; |
| 424 | 421 | ||
| 425 | error: | 422 | error: |
| @@ -469,15 +466,12 @@ int save_pci_variables(struct hfi1_devdata *dd) | |||
| 469 | if (ret) | 466 | if (ret) |
| 470 | goto error; | 467 | goto error; |
| 471 | 468 | ||
| 472 | ret = pci_read_config_dword(dd->pcidev, PCIE_CFG_SPCIE1, | 469 | if (pci_find_ext_capability(dd->pcidev, PCI_EXT_CAP_ID_TPH)) { |
| 473 | &dd->pci_lnkctl3); | 470 | ret = pci_read_config_dword(dd->pcidev, PCIE_CFG_TPH2, |
| 474 | if (ret) | 471 | &dd->pci_tph2); |
| 475 | goto error; | 472 | if (ret) |
| 476 | 473 | goto error; | |
| 477 | ret = pci_read_config_dword(dd->pcidev, PCIE_CFG_TPH2, &dd->pci_tph2); | 474 | } |
| 478 | if (ret) | ||
| 479 | goto error; | ||
| 480 | |||
| 481 | return 0; | 475 | return 0; |
| 482 | 476 | ||
| 483 | error: | 477 | error: |
diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c index 013049bcdb53..caf490ab24c8 100644 --- a/drivers/infiniband/hw/mlx4/qp.c +++ b/drivers/infiniband/hw/mlx4/qp.c | |||
| @@ -666,6 +666,19 @@ static int set_qp_rss(struct mlx4_ib_dev *dev, struct mlx4_ib_rss *rss_ctx, | |||
| 666 | return (-EOPNOTSUPP); | 666 | return (-EOPNOTSUPP); |
| 667 | } | 667 | } |
| 668 | 668 | ||
| 669 | if (ucmd->rx_hash_fields_mask & ~(MLX4_IB_RX_HASH_SRC_IPV4 | | ||
| 670 | MLX4_IB_RX_HASH_DST_IPV4 | | ||
| 671 | MLX4_IB_RX_HASH_SRC_IPV6 | | ||
| 672 | MLX4_IB_RX_HASH_DST_IPV6 | | ||
| 673 | MLX4_IB_RX_HASH_SRC_PORT_TCP | | ||
| 674 | MLX4_IB_RX_HASH_DST_PORT_TCP | | ||
| 675 | MLX4_IB_RX_HASH_SRC_PORT_UDP | | ||
| 676 | MLX4_IB_RX_HASH_DST_PORT_UDP)) { | ||
| 677 | pr_debug("RX Hash fields_mask has unsupported mask (0x%llx)\n", | ||
| 678 | ucmd->rx_hash_fields_mask); | ||
| 679 | return (-EOPNOTSUPP); | ||
| 680 | } | ||
| 681 | |||
| 669 | if ((ucmd->rx_hash_fields_mask & MLX4_IB_RX_HASH_SRC_IPV4) && | 682 | if ((ucmd->rx_hash_fields_mask & MLX4_IB_RX_HASH_SRC_IPV4) && |
| 670 | (ucmd->rx_hash_fields_mask & MLX4_IB_RX_HASH_DST_IPV4)) { | 683 | (ucmd->rx_hash_fields_mask & MLX4_IB_RX_HASH_DST_IPV4)) { |
| 671 | rss_ctx->flags = MLX4_RSS_IPV4; | 684 | rss_ctx->flags = MLX4_RSS_IPV4; |
| @@ -691,11 +704,11 @@ static int set_qp_rss(struct mlx4_ib_dev *dev, struct mlx4_ib_rss *rss_ctx, | |||
| 691 | return (-EOPNOTSUPP); | 704 | return (-EOPNOTSUPP); |
| 692 | } | 705 | } |
| 693 | 706 | ||
| 694 | if (rss_ctx->flags & MLX4_RSS_IPV4) { | 707 | if (rss_ctx->flags & MLX4_RSS_IPV4) |
| 695 | rss_ctx->flags |= MLX4_RSS_UDP_IPV4; | 708 | rss_ctx->flags |= MLX4_RSS_UDP_IPV4; |
| 696 | } else if (rss_ctx->flags & MLX4_RSS_IPV6) { | 709 | if (rss_ctx->flags & MLX4_RSS_IPV6) |
| 697 | rss_ctx->flags |= MLX4_RSS_UDP_IPV6; | 710 | rss_ctx->flags |= MLX4_RSS_UDP_IPV6; |
| 698 | } else { | 711 | if (!(rss_ctx->flags & (MLX4_RSS_IPV6 | MLX4_RSS_IPV4))) { |
| 699 | pr_debug("RX Hash fields_mask is not supported - UDP must be set with IPv4 or IPv6\n"); | 712 | pr_debug("RX Hash fields_mask is not supported - UDP must be set with IPv4 or IPv6\n"); |
| 700 | return (-EOPNOTSUPP); | 713 | return (-EOPNOTSUPP); |
| 701 | } | 714 | } |
| @@ -707,15 +720,14 @@ static int set_qp_rss(struct mlx4_ib_dev *dev, struct mlx4_ib_rss *rss_ctx, | |||
| 707 | 720 | ||
| 708 | if ((ucmd->rx_hash_fields_mask & MLX4_IB_RX_HASH_SRC_PORT_TCP) && | 721 | if ((ucmd->rx_hash_fields_mask & MLX4_IB_RX_HASH_SRC_PORT_TCP) && |
| 709 | (ucmd->rx_hash_fields_mask & MLX4_IB_RX_HASH_DST_PORT_TCP)) { | 722 | (ucmd->rx_hash_fields_mask & MLX4_IB_RX_HASH_DST_PORT_TCP)) { |
| 710 | if (rss_ctx->flags & MLX4_RSS_IPV4) { | 723 | if (rss_ctx->flags & MLX4_RSS_IPV4) |
| 711 | rss_ctx->flags |= MLX4_RSS_TCP_IPV4; | 724 | rss_ctx->flags |= MLX4_RSS_TCP_IPV4; |
| 712 | } else if (rss_ctx->flags & MLX4_RSS_IPV6) { | 725 | if (rss_ctx->flags & MLX4_RSS_IPV6) |
| 713 | rss_ctx->flags |= MLX4_RSS_TCP_IPV6; | 726 | rss_ctx->flags |= MLX4_RSS_TCP_IPV6; |
| 714 | } else { | 727 | if (!(rss_ctx->flags & (MLX4_RSS_IPV6 | MLX4_RSS_IPV4))) { |
| 715 | pr_debug("RX Hash fields_mask is not supported - TCP must be set with IPv4 or IPv6\n"); | 728 | pr_debug("RX Hash fields_mask is not supported - TCP must be set with IPv4 or IPv6\n"); |
| 716 | return (-EOPNOTSUPP); | 729 | return (-EOPNOTSUPP); |
| 717 | } | 730 | } |
| 718 | |||
| 719 | } else if ((ucmd->rx_hash_fields_mask & MLX4_IB_RX_HASH_SRC_PORT_TCP) || | 731 | } else if ((ucmd->rx_hash_fields_mask & MLX4_IB_RX_HASH_SRC_PORT_TCP) || |
| 720 | (ucmd->rx_hash_fields_mask & MLX4_IB_RX_HASH_DST_PORT_TCP)) { | 732 | (ucmd->rx_hash_fields_mask & MLX4_IB_RX_HASH_DST_PORT_TCP)) { |
| 721 | pr_debug("RX Hash fields_mask is not supported - both TCP SRC and DST must be set\n"); | 733 | pr_debug("RX Hash fields_mask is not supported - both TCP SRC and DST must be set\n"); |
diff --git a/drivers/infiniband/hw/mlx5/cmd.c b/drivers/infiniband/hw/mlx5/cmd.c index 470995fa38d2..6f6712f87a73 100644 --- a/drivers/infiniband/hw/mlx5/cmd.c +++ b/drivers/infiniband/hw/mlx5/cmd.c | |||
| @@ -47,17 +47,6 @@ int mlx5_cmd_null_mkey(struct mlx5_core_dev *dev, u32 *null_mkey) | |||
| 47 | return err; | 47 | return err; |
| 48 | } | 48 | } |
| 49 | 49 | ||
| 50 | int mlx5_cmd_query_cong_counter(struct mlx5_core_dev *dev, | ||
| 51 | bool reset, void *out, int out_size) | ||
| 52 | { | ||
| 53 | u32 in[MLX5_ST_SZ_DW(query_cong_statistics_in)] = { }; | ||
| 54 | |||
| 55 | MLX5_SET(query_cong_statistics_in, in, opcode, | ||
| 56 | MLX5_CMD_OP_QUERY_CONG_STATISTICS); | ||
| 57 | MLX5_SET(query_cong_statistics_in, in, clear, reset); | ||
| 58 | return mlx5_cmd_exec(dev, in, sizeof(in), out, out_size); | ||
| 59 | } | ||
| 60 | |||
| 61 | int mlx5_cmd_query_cong_params(struct mlx5_core_dev *dev, int cong_point, | 50 | int mlx5_cmd_query_cong_params(struct mlx5_core_dev *dev, int cong_point, |
| 62 | void *out, int out_size) | 51 | void *out, int out_size) |
| 63 | { | 52 | { |
diff --git a/drivers/infiniband/hw/mlx5/cmd.h b/drivers/infiniband/hw/mlx5/cmd.h index af4c24596274..78ffded7cc2c 100644 --- a/drivers/infiniband/hw/mlx5/cmd.h +++ b/drivers/infiniband/hw/mlx5/cmd.h | |||
| @@ -37,8 +37,6 @@ | |||
| 37 | #include <linux/mlx5/driver.h> | 37 | #include <linux/mlx5/driver.h> |
| 38 | 38 | ||
| 39 | int mlx5_cmd_null_mkey(struct mlx5_core_dev *dev, u32 *null_mkey); | 39 | int mlx5_cmd_null_mkey(struct mlx5_core_dev *dev, u32 *null_mkey); |
| 40 | int mlx5_cmd_query_cong_counter(struct mlx5_core_dev *dev, | ||
| 41 | bool reset, void *out, int out_size); | ||
| 42 | int mlx5_cmd_query_cong_params(struct mlx5_core_dev *dev, int cong_point, | 40 | int mlx5_cmd_query_cong_params(struct mlx5_core_dev *dev, int cong_point, |
| 43 | void *out, int out_size); | 41 | void *out, int out_size); |
| 44 | int mlx5_cmd_modify_cong_params(struct mlx5_core_dev *mdev, | 42 | int mlx5_cmd_modify_cong_params(struct mlx5_core_dev *mdev, |
diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c index 543d0a4c8bf3..8ac50de2b242 100644 --- a/drivers/infiniband/hw/mlx5/main.c +++ b/drivers/infiniband/hw/mlx5/main.c | |||
| @@ -1463,6 +1463,7 @@ static struct ib_ucontext *mlx5_ib_alloc_ucontext(struct ib_device *ibdev, | |||
| 1463 | } | 1463 | } |
| 1464 | 1464 | ||
| 1465 | INIT_LIST_HEAD(&context->vma_private_list); | 1465 | INIT_LIST_HEAD(&context->vma_private_list); |
| 1466 | mutex_init(&context->vma_private_list_mutex); | ||
| 1466 | INIT_LIST_HEAD(&context->db_page_list); | 1467 | INIT_LIST_HEAD(&context->db_page_list); |
| 1467 | mutex_init(&context->db_page_mutex); | 1468 | mutex_init(&context->db_page_mutex); |
| 1468 | 1469 | ||
| @@ -1624,7 +1625,9 @@ static void mlx5_ib_vma_close(struct vm_area_struct *area) | |||
| 1624 | * mlx5_ib_disassociate_ucontext(). | 1625 | * mlx5_ib_disassociate_ucontext(). |
| 1625 | */ | 1626 | */ |
| 1626 | mlx5_ib_vma_priv_data->vma = NULL; | 1627 | mlx5_ib_vma_priv_data->vma = NULL; |
| 1628 | mutex_lock(mlx5_ib_vma_priv_data->vma_private_list_mutex); | ||
| 1627 | list_del(&mlx5_ib_vma_priv_data->list); | 1629 | list_del(&mlx5_ib_vma_priv_data->list); |
| 1630 | mutex_unlock(mlx5_ib_vma_priv_data->vma_private_list_mutex); | ||
| 1628 | kfree(mlx5_ib_vma_priv_data); | 1631 | kfree(mlx5_ib_vma_priv_data); |
| 1629 | } | 1632 | } |
| 1630 | 1633 | ||
| @@ -1644,10 +1647,13 @@ static int mlx5_ib_set_vma_data(struct vm_area_struct *vma, | |||
| 1644 | return -ENOMEM; | 1647 | return -ENOMEM; |
| 1645 | 1648 | ||
| 1646 | vma_prv->vma = vma; | 1649 | vma_prv->vma = vma; |
| 1650 | vma_prv->vma_private_list_mutex = &ctx->vma_private_list_mutex; | ||
| 1647 | vma->vm_private_data = vma_prv; | 1651 | vma->vm_private_data = vma_prv; |
| 1648 | vma->vm_ops = &mlx5_ib_vm_ops; | 1652 | vma->vm_ops = &mlx5_ib_vm_ops; |
| 1649 | 1653 | ||
| 1654 | mutex_lock(&ctx->vma_private_list_mutex); | ||
| 1650 | list_add(&vma_prv->list, vma_head); | 1655 | list_add(&vma_prv->list, vma_head); |
| 1656 | mutex_unlock(&ctx->vma_private_list_mutex); | ||
| 1651 | 1657 | ||
| 1652 | return 0; | 1658 | return 0; |
| 1653 | } | 1659 | } |
| @@ -1690,6 +1696,7 @@ static void mlx5_ib_disassociate_ucontext(struct ib_ucontext *ibcontext) | |||
| 1690 | * mlx5_ib_vma_close. | 1696 | * mlx5_ib_vma_close. |
| 1691 | */ | 1697 | */ |
| 1692 | down_write(&owning_mm->mmap_sem); | 1698 | down_write(&owning_mm->mmap_sem); |
| 1699 | mutex_lock(&context->vma_private_list_mutex); | ||
| 1693 | list_for_each_entry_safe(vma_private, n, &context->vma_private_list, | 1700 | list_for_each_entry_safe(vma_private, n, &context->vma_private_list, |
| 1694 | list) { | 1701 | list) { |
| 1695 | vma = vma_private->vma; | 1702 | vma = vma_private->vma; |
| @@ -1704,6 +1711,7 @@ static void mlx5_ib_disassociate_ucontext(struct ib_ucontext *ibcontext) | |||
| 1704 | list_del(&vma_private->list); | 1711 | list_del(&vma_private->list); |
| 1705 | kfree(vma_private); | 1712 | kfree(vma_private); |
| 1706 | } | 1713 | } |
| 1714 | mutex_unlock(&context->vma_private_list_mutex); | ||
| 1707 | up_write(&owning_mm->mmap_sem); | 1715 | up_write(&owning_mm->mmap_sem); |
| 1708 | mmput(owning_mm); | 1716 | mmput(owning_mm); |
| 1709 | put_task_struct(owning_process); | 1717 | put_task_struct(owning_process); |
| @@ -3737,34 +3745,6 @@ free: | |||
| 3737 | return ret; | 3745 | return ret; |
| 3738 | } | 3746 | } |
| 3739 | 3747 | ||
| 3740 | static int mlx5_ib_query_cong_counters(struct mlx5_ib_dev *dev, | ||
| 3741 | struct mlx5_ib_port *port, | ||
| 3742 | struct rdma_hw_stats *stats) | ||
| 3743 | { | ||
| 3744 | int outlen = MLX5_ST_SZ_BYTES(query_cong_statistics_out); | ||
| 3745 | void *out; | ||
| 3746 | int ret, i; | ||
| 3747 | int offset = port->cnts.num_q_counters; | ||
| 3748 | |||
| 3749 | out = kvzalloc(outlen, GFP_KERNEL); | ||
| 3750 | if (!out) | ||
| 3751 | return -ENOMEM; | ||
| 3752 | |||
| 3753 | ret = mlx5_cmd_query_cong_counter(dev->mdev, false, out, outlen); | ||
| 3754 | if (ret) | ||
| 3755 | goto free; | ||
| 3756 | |||
| 3757 | for (i = 0; i < port->cnts.num_cong_counters; i++) { | ||
| 3758 | stats->value[i + offset] = | ||
| 3759 | be64_to_cpup((__be64 *)(out + | ||
| 3760 | port->cnts.offsets[i + offset])); | ||
| 3761 | } | ||
| 3762 | |||
| 3763 | free: | ||
| 3764 | kvfree(out); | ||
| 3765 | return ret; | ||
| 3766 | } | ||
| 3767 | |||
| 3768 | static int mlx5_ib_get_hw_stats(struct ib_device *ibdev, | 3748 | static int mlx5_ib_get_hw_stats(struct ib_device *ibdev, |
| 3769 | struct rdma_hw_stats *stats, | 3749 | struct rdma_hw_stats *stats, |
| 3770 | u8 port_num, int index) | 3750 | u8 port_num, int index) |
| @@ -3782,7 +3762,12 @@ static int mlx5_ib_get_hw_stats(struct ib_device *ibdev, | |||
| 3782 | num_counters = port->cnts.num_q_counters; | 3762 | num_counters = port->cnts.num_q_counters; |
| 3783 | 3763 | ||
| 3784 | if (MLX5_CAP_GEN(dev->mdev, cc_query_allowed)) { | 3764 | if (MLX5_CAP_GEN(dev->mdev, cc_query_allowed)) { |
| 3785 | ret = mlx5_ib_query_cong_counters(dev, port, stats); | 3765 | ret = mlx5_lag_query_cong_counters(dev->mdev, |
| 3766 | stats->value + | ||
| 3767 | port->cnts.num_q_counters, | ||
| 3768 | port->cnts.num_cong_counters, | ||
| 3769 | port->cnts.offsets + | ||
| 3770 | port->cnts.num_q_counters); | ||
| 3786 | if (ret) | 3771 | if (ret) |
| 3787 | return ret; | 3772 | return ret; |
| 3788 | num_counters += port->cnts.num_cong_counters; | 3773 | num_counters += port->cnts.num_cong_counters; |
diff --git a/drivers/infiniband/hw/mlx5/mlx5_ib.h b/drivers/infiniband/hw/mlx5/mlx5_ib.h index 6dd8cac78de2..2c5f3533bbc9 100644 --- a/drivers/infiniband/hw/mlx5/mlx5_ib.h +++ b/drivers/infiniband/hw/mlx5/mlx5_ib.h | |||
| @@ -115,6 +115,8 @@ enum { | |||
| 115 | struct mlx5_ib_vma_private_data { | 115 | struct mlx5_ib_vma_private_data { |
| 116 | struct list_head list; | 116 | struct list_head list; |
| 117 | struct vm_area_struct *vma; | 117 | struct vm_area_struct *vma; |
| 118 | /* protect vma_private_list add/del */ | ||
| 119 | struct mutex *vma_private_list_mutex; | ||
| 118 | }; | 120 | }; |
| 119 | 121 | ||
| 120 | struct mlx5_ib_ucontext { | 122 | struct mlx5_ib_ucontext { |
| @@ -129,6 +131,8 @@ struct mlx5_ib_ucontext { | |||
| 129 | /* Transport Domain number */ | 131 | /* Transport Domain number */ |
| 130 | u32 tdn; | 132 | u32 tdn; |
| 131 | struct list_head vma_private_list; | 133 | struct list_head vma_private_list; |
| 134 | /* protect vma_private_list add/del */ | ||
| 135 | struct mutex vma_private_list_mutex; | ||
| 132 | 136 | ||
| 133 | unsigned long upd_xlt_page; | 137 | unsigned long upd_xlt_page; |
| 134 | /* protect ODP/KSM */ | 138 | /* protect ODP/KSM */ |
diff --git a/drivers/infiniband/hw/mlx5/mr.c b/drivers/infiniband/hw/mlx5/mr.c index ee0ee1f9994b..d109fe8290a7 100644 --- a/drivers/infiniband/hw/mlx5/mr.c +++ b/drivers/infiniband/hw/mlx5/mr.c | |||
| @@ -1637,6 +1637,7 @@ struct ib_mr *mlx5_ib_alloc_mr(struct ib_pd *pd, | |||
| 1637 | MLX5_SET(mkc, mkc, access_mode, mr->access_mode); | 1637 | MLX5_SET(mkc, mkc, access_mode, mr->access_mode); |
| 1638 | MLX5_SET(mkc, mkc, umr_en, 1); | 1638 | MLX5_SET(mkc, mkc, umr_en, 1); |
| 1639 | 1639 | ||
| 1640 | mr->ibmr.device = pd->device; | ||
| 1640 | err = mlx5_core_create_mkey(dev->mdev, &mr->mmkey, in, inlen); | 1641 | err = mlx5_core_create_mkey(dev->mdev, &mr->mmkey, in, inlen); |
| 1641 | if (err) | 1642 | if (err) |
| 1642 | goto err_destroy_psv; | 1643 | goto err_destroy_psv; |
diff --git a/drivers/infiniband/hw/vmw_pvrdma/pvrdma.h b/drivers/infiniband/hw/vmw_pvrdma/pvrdma.h index 63bc2efc34eb..4f7bd3b6a315 100644 --- a/drivers/infiniband/hw/vmw_pvrdma/pvrdma.h +++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma.h | |||
| @@ -94,7 +94,7 @@ struct pvrdma_cq { | |||
| 94 | u32 cq_handle; | 94 | u32 cq_handle; |
| 95 | bool is_kernel; | 95 | bool is_kernel; |
| 96 | atomic_t refcnt; | 96 | atomic_t refcnt; |
| 97 | wait_queue_head_t wait; | 97 | struct completion free; |
| 98 | }; | 98 | }; |
| 99 | 99 | ||
| 100 | struct pvrdma_id_table { | 100 | struct pvrdma_id_table { |
| @@ -175,7 +175,7 @@ struct pvrdma_srq { | |||
| 175 | u32 srq_handle; | 175 | u32 srq_handle; |
| 176 | int npages; | 176 | int npages; |
| 177 | refcount_t refcnt; | 177 | refcount_t refcnt; |
| 178 | wait_queue_head_t wait; | 178 | struct completion free; |
| 179 | }; | 179 | }; |
| 180 | 180 | ||
| 181 | struct pvrdma_qp { | 181 | struct pvrdma_qp { |
| @@ -197,7 +197,7 @@ struct pvrdma_qp { | |||
| 197 | bool is_kernel; | 197 | bool is_kernel; |
| 198 | struct mutex mutex; /* QP state mutex. */ | 198 | struct mutex mutex; /* QP state mutex. */ |
| 199 | atomic_t refcnt; | 199 | atomic_t refcnt; |
| 200 | wait_queue_head_t wait; | 200 | struct completion free; |
| 201 | }; | 201 | }; |
| 202 | 202 | ||
| 203 | struct pvrdma_dev { | 203 | struct pvrdma_dev { |
diff --git a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_cq.c b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_cq.c index 3562c0c30492..e529622cefad 100644 --- a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_cq.c +++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_cq.c | |||
| @@ -179,7 +179,7 @@ struct ib_cq *pvrdma_create_cq(struct ib_device *ibdev, | |||
| 179 | pvrdma_page_dir_insert_umem(&cq->pdir, cq->umem, 0); | 179 | pvrdma_page_dir_insert_umem(&cq->pdir, cq->umem, 0); |
| 180 | 180 | ||
| 181 | atomic_set(&cq->refcnt, 1); | 181 | atomic_set(&cq->refcnt, 1); |
| 182 | init_waitqueue_head(&cq->wait); | 182 | init_completion(&cq->free); |
| 183 | spin_lock_init(&cq->cq_lock); | 183 | spin_lock_init(&cq->cq_lock); |
| 184 | 184 | ||
| 185 | memset(cmd, 0, sizeof(*cmd)); | 185 | memset(cmd, 0, sizeof(*cmd)); |
| @@ -230,8 +230,9 @@ err_cq: | |||
| 230 | 230 | ||
| 231 | static void pvrdma_free_cq(struct pvrdma_dev *dev, struct pvrdma_cq *cq) | 231 | static void pvrdma_free_cq(struct pvrdma_dev *dev, struct pvrdma_cq *cq) |
| 232 | { | 232 | { |
| 233 | atomic_dec(&cq->refcnt); | 233 | if (atomic_dec_and_test(&cq->refcnt)) |
| 234 | wait_event(cq->wait, !atomic_read(&cq->refcnt)); | 234 | complete(&cq->free); |
| 235 | wait_for_completion(&cq->free); | ||
| 235 | 236 | ||
| 236 | if (!cq->is_kernel) | 237 | if (!cq->is_kernel) |
| 237 | ib_umem_release(cq->umem); | 238 | ib_umem_release(cq->umem); |
diff --git a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_main.c b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_main.c index 1f4e18717a00..e92681878c93 100644 --- a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_main.c +++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_main.c | |||
| @@ -346,9 +346,8 @@ static void pvrdma_qp_event(struct pvrdma_dev *dev, u32 qpn, int type) | |||
| 346 | ibqp->event_handler(&e, ibqp->qp_context); | 346 | ibqp->event_handler(&e, ibqp->qp_context); |
| 347 | } | 347 | } |
| 348 | if (qp) { | 348 | if (qp) { |
| 349 | atomic_dec(&qp->refcnt); | 349 | if (atomic_dec_and_test(&qp->refcnt)) |
| 350 | if (atomic_read(&qp->refcnt) == 0) | 350 | complete(&qp->free); |
| 351 | wake_up(&qp->wait); | ||
| 352 | } | 351 | } |
| 353 | } | 352 | } |
| 354 | 353 | ||
| @@ -373,9 +372,8 @@ static void pvrdma_cq_event(struct pvrdma_dev *dev, u32 cqn, int type) | |||
| 373 | ibcq->event_handler(&e, ibcq->cq_context); | 372 | ibcq->event_handler(&e, ibcq->cq_context); |
| 374 | } | 373 | } |
| 375 | if (cq) { | 374 | if (cq) { |
| 376 | atomic_dec(&cq->refcnt); | 375 | if (atomic_dec_and_test(&cq->refcnt)) |
| 377 | if (atomic_read(&cq->refcnt) == 0) | 376 | complete(&cq->free); |
| 378 | wake_up(&cq->wait); | ||
| 379 | } | 377 | } |
| 380 | } | 378 | } |
| 381 | 379 | ||
| @@ -404,7 +402,7 @@ static void pvrdma_srq_event(struct pvrdma_dev *dev, u32 srqn, int type) | |||
| 404 | } | 402 | } |
| 405 | if (srq) { | 403 | if (srq) { |
| 406 | if (refcount_dec_and_test(&srq->refcnt)) | 404 | if (refcount_dec_and_test(&srq->refcnt)) |
| 407 | wake_up(&srq->wait); | 405 | complete(&srq->free); |
| 408 | } | 406 | } |
| 409 | } | 407 | } |
| 410 | 408 | ||
| @@ -539,9 +537,8 @@ static irqreturn_t pvrdma_intrx_handler(int irq, void *dev_id) | |||
| 539 | if (cq && cq->ibcq.comp_handler) | 537 | if (cq && cq->ibcq.comp_handler) |
| 540 | cq->ibcq.comp_handler(&cq->ibcq, cq->ibcq.cq_context); | 538 | cq->ibcq.comp_handler(&cq->ibcq, cq->ibcq.cq_context); |
| 541 | if (cq) { | 539 | if (cq) { |
| 542 | atomic_dec(&cq->refcnt); | 540 | if (atomic_dec_and_test(&cq->refcnt)) |
| 543 | if (atomic_read(&cq->refcnt)) | 541 | complete(&cq->free); |
| 544 | wake_up(&cq->wait); | ||
| 545 | } | 542 | } |
| 546 | pvrdma_idx_ring_inc(&ring->cons_head, ring_slots); | 543 | pvrdma_idx_ring_inc(&ring->cons_head, ring_slots); |
| 547 | } | 544 | } |
diff --git a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_qp.c b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_qp.c index 10420a18d02f..4059308e1454 100644 --- a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_qp.c +++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_qp.c | |||
| @@ -246,7 +246,7 @@ struct ib_qp *pvrdma_create_qp(struct ib_pd *pd, | |||
| 246 | spin_lock_init(&qp->rq.lock); | 246 | spin_lock_init(&qp->rq.lock); |
| 247 | mutex_init(&qp->mutex); | 247 | mutex_init(&qp->mutex); |
| 248 | atomic_set(&qp->refcnt, 1); | 248 | atomic_set(&qp->refcnt, 1); |
| 249 | init_waitqueue_head(&qp->wait); | 249 | init_completion(&qp->free); |
| 250 | 250 | ||
| 251 | qp->state = IB_QPS_RESET; | 251 | qp->state = IB_QPS_RESET; |
| 252 | 252 | ||
| @@ -428,8 +428,16 @@ static void pvrdma_free_qp(struct pvrdma_qp *qp) | |||
| 428 | 428 | ||
| 429 | pvrdma_unlock_cqs(scq, rcq, &scq_flags, &rcq_flags); | 429 | pvrdma_unlock_cqs(scq, rcq, &scq_flags, &rcq_flags); |
| 430 | 430 | ||
| 431 | atomic_dec(&qp->refcnt); | 431 | if (atomic_dec_and_test(&qp->refcnt)) |
| 432 | wait_event(qp->wait, !atomic_read(&qp->refcnt)); | 432 | complete(&qp->free); |
| 433 | wait_for_completion(&qp->free); | ||
| 434 | |||
| 435 | if (!qp->is_kernel) { | ||
| 436 | if (qp->rumem) | ||
| 437 | ib_umem_release(qp->rumem); | ||
| 438 | if (qp->sumem) | ||
| 439 | ib_umem_release(qp->sumem); | ||
| 440 | } | ||
| 433 | 441 | ||
| 434 | pvrdma_page_dir_cleanup(dev, &qp->pdir); | 442 | pvrdma_page_dir_cleanup(dev, &qp->pdir); |
| 435 | 443 | ||
diff --git a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_srq.c b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_srq.c index 826ccb864596..5acebb1ef631 100644 --- a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_srq.c +++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_srq.c | |||
| @@ -149,7 +149,7 @@ struct ib_srq *pvrdma_create_srq(struct ib_pd *pd, | |||
| 149 | 149 | ||
| 150 | spin_lock_init(&srq->lock); | 150 | spin_lock_init(&srq->lock); |
| 151 | refcount_set(&srq->refcnt, 1); | 151 | refcount_set(&srq->refcnt, 1); |
| 152 | init_waitqueue_head(&srq->wait); | 152 | init_completion(&srq->free); |
| 153 | 153 | ||
| 154 | dev_dbg(&dev->pdev->dev, | 154 | dev_dbg(&dev->pdev->dev, |
| 155 | "create shared receive queue from user space\n"); | 155 | "create shared receive queue from user space\n"); |
| @@ -236,8 +236,9 @@ static void pvrdma_free_srq(struct pvrdma_dev *dev, struct pvrdma_srq *srq) | |||
| 236 | dev->srq_tbl[srq->srq_handle] = NULL; | 236 | dev->srq_tbl[srq->srq_handle] = NULL; |
| 237 | spin_unlock_irqrestore(&dev->srq_tbl_lock, flags); | 237 | spin_unlock_irqrestore(&dev->srq_tbl_lock, flags); |
| 238 | 238 | ||
| 239 | refcount_dec(&srq->refcnt); | 239 | if (refcount_dec_and_test(&srq->refcnt)) |
| 240 | wait_event(srq->wait, !refcount_read(&srq->refcnt)); | 240 | complete(&srq->free); |
| 241 | wait_for_completion(&srq->free); | ||
| 241 | 242 | ||
| 242 | /* There is no support for kernel clients, so this is safe. */ | 243 | /* There is no support for kernel clients, so this is safe. */ |
| 243 | ib_umem_release(srq->umem); | 244 | ib_umem_release(srq->umem); |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c index 87f4bd99cdf7..2c13123bfd69 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c | |||
| @@ -1145,6 +1145,7 @@ static int ipoib_cm_tx_init(struct ipoib_cm_tx *p, u32 qpn, | |||
| 1145 | noio_flag = memalloc_noio_save(); | 1145 | noio_flag = memalloc_noio_save(); |
| 1146 | p->tx_ring = vzalloc(ipoib_sendq_size * sizeof(*p->tx_ring)); | 1146 | p->tx_ring = vzalloc(ipoib_sendq_size * sizeof(*p->tx_ring)); |
| 1147 | if (!p->tx_ring) { | 1147 | if (!p->tx_ring) { |
| 1148 | memalloc_noio_restore(noio_flag); | ||
| 1148 | ret = -ENOMEM; | 1149 | ret = -ENOMEM; |
| 1149 | goto err_tx; | 1150 | goto err_tx; |
| 1150 | } | 1151 | } |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c index 3b96cdaf9a83..e6151a29c412 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c | |||
| @@ -1236,13 +1236,10 @@ static void __ipoib_ib_dev_flush(struct ipoib_dev_priv *priv, | |||
| 1236 | ipoib_ib_dev_down(dev); | 1236 | ipoib_ib_dev_down(dev); |
| 1237 | 1237 | ||
| 1238 | if (level == IPOIB_FLUSH_HEAVY) { | 1238 | if (level == IPOIB_FLUSH_HEAVY) { |
| 1239 | rtnl_lock(); | ||
| 1240 | if (test_bit(IPOIB_FLAG_INITIALIZED, &priv->flags)) | 1239 | if (test_bit(IPOIB_FLAG_INITIALIZED, &priv->flags)) |
| 1241 | ipoib_ib_dev_stop(dev); | 1240 | ipoib_ib_dev_stop(dev); |
| 1242 | 1241 | ||
| 1243 | result = ipoib_ib_dev_open(dev); | 1242 | if (ipoib_ib_dev_open(dev)) |
| 1244 | rtnl_unlock(); | ||
| 1245 | if (result) | ||
| 1246 | return; | 1243 | return; |
| 1247 | 1244 | ||
| 1248 | if (netif_queue_stopped(dev)) | 1245 | if (netif_queue_stopped(dev)) |
| @@ -1282,7 +1279,9 @@ void ipoib_ib_dev_flush_heavy(struct work_struct *work) | |||
| 1282 | struct ipoib_dev_priv *priv = | 1279 | struct ipoib_dev_priv *priv = |
| 1283 | container_of(work, struct ipoib_dev_priv, flush_heavy); | 1280 | container_of(work, struct ipoib_dev_priv, flush_heavy); |
| 1284 | 1281 | ||
| 1282 | rtnl_lock(); | ||
| 1285 | __ipoib_ib_dev_flush(priv, IPOIB_FLUSH_HEAVY, 0); | 1283 | __ipoib_ib_dev_flush(priv, IPOIB_FLUSH_HEAVY, 0); |
| 1284 | rtnl_unlock(); | ||
| 1286 | } | 1285 | } |
| 1287 | 1286 | ||
| 1288 | void ipoib_ib_dev_cleanup(struct net_device *dev) | 1287 | void ipoib_ib_dev_cleanup(struct net_device *dev) |
diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c index 7d5eb004091d..97baf88d9505 100644 --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c | |||
| @@ -4184,7 +4184,7 @@ static void amd_ir_update_irte(struct irq_data *irqd, struct amd_iommu *iommu, | |||
| 4184 | struct irq_cfg *cfg); | 4184 | struct irq_cfg *cfg); |
| 4185 | 4185 | ||
| 4186 | static int irq_remapping_activate(struct irq_domain *domain, | 4186 | static int irq_remapping_activate(struct irq_domain *domain, |
| 4187 | struct irq_data *irq_data, bool early) | 4187 | struct irq_data *irq_data, bool reserve) |
| 4188 | { | 4188 | { |
| 4189 | struct amd_ir_data *data = irq_data->chip_data; | 4189 | struct amd_ir_data *data = irq_data->chip_data; |
| 4190 | struct irq_2_irte *irte_info = &data->irq_2_irte; | 4190 | struct irq_2_irte *irte_info = &data->irq_2_irte; |
diff --git a/drivers/iommu/intel_irq_remapping.c b/drivers/iommu/intel_irq_remapping.c index 76a193c7fcfc..66f69af2c219 100644 --- a/drivers/iommu/intel_irq_remapping.c +++ b/drivers/iommu/intel_irq_remapping.c | |||
| @@ -1397,7 +1397,7 @@ static void intel_irq_remapping_free(struct irq_domain *domain, | |||
| 1397 | } | 1397 | } |
| 1398 | 1398 | ||
| 1399 | static int intel_irq_remapping_activate(struct irq_domain *domain, | 1399 | static int intel_irq_remapping_activate(struct irq_domain *domain, |
| 1400 | struct irq_data *irq_data, bool early) | 1400 | struct irq_data *irq_data, bool reserve) |
| 1401 | { | 1401 | { |
| 1402 | intel_ir_reconfigure_irte(irq_data, true); | 1402 | intel_ir_reconfigure_irte(irq_data, true); |
| 1403 | return 0; | 1403 | return 0; |
diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index 4039e64cd342..06f025fd5726 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c | |||
| @@ -2303,7 +2303,7 @@ static int its_irq_domain_alloc(struct irq_domain *domain, unsigned int virq, | |||
| 2303 | } | 2303 | } |
| 2304 | 2304 | ||
| 2305 | static int its_irq_domain_activate(struct irq_domain *domain, | 2305 | static int its_irq_domain_activate(struct irq_domain *domain, |
| 2306 | struct irq_data *d, bool early) | 2306 | struct irq_data *d, bool reserve) |
| 2307 | { | 2307 | { |
| 2308 | struct its_device *its_dev = irq_data_get_irq_chip_data(d); | 2308 | struct its_device *its_dev = irq_data_get_irq_chip_data(d); |
| 2309 | u32 event = its_get_event_id(d); | 2309 | u32 event = its_get_event_id(d); |
| @@ -2818,7 +2818,7 @@ static int its_vpe_irq_domain_alloc(struct irq_domain *domain, unsigned int virq | |||
| 2818 | } | 2818 | } |
| 2819 | 2819 | ||
| 2820 | static int its_vpe_irq_domain_activate(struct irq_domain *domain, | 2820 | static int its_vpe_irq_domain_activate(struct irq_domain *domain, |
| 2821 | struct irq_data *d, bool early) | 2821 | struct irq_data *d, bool reserve) |
| 2822 | { | 2822 | { |
| 2823 | struct its_vpe *vpe = irq_data_get_irq_chip_data(d); | 2823 | struct its_vpe *vpe = irq_data_get_irq_chip_data(d); |
| 2824 | struct its_node *its; | 2824 | struct its_node *its; |
diff --git a/drivers/irqchip/irq-renesas-intc-irqpin.c b/drivers/irqchip/irq-renesas-intc-irqpin.c index 06f29cf5018a..cee59fe1321c 100644 --- a/drivers/irqchip/irq-renesas-intc-irqpin.c +++ b/drivers/irqchip/irq-renesas-intc-irqpin.c | |||
| @@ -342,6 +342,9 @@ static irqreturn_t intc_irqpin_shared_irq_handler(int irq, void *dev_id) | |||
| 342 | */ | 342 | */ |
| 343 | static struct lock_class_key intc_irqpin_irq_lock_class; | 343 | static struct lock_class_key intc_irqpin_irq_lock_class; |
| 344 | 344 | ||
| 345 | /* And this is for the request mutex */ | ||
| 346 | static struct lock_class_key intc_irqpin_irq_request_class; | ||
| 347 | |||
| 345 | static int intc_irqpin_irq_domain_map(struct irq_domain *h, unsigned int virq, | 348 | static int intc_irqpin_irq_domain_map(struct irq_domain *h, unsigned int virq, |
| 346 | irq_hw_number_t hw) | 349 | irq_hw_number_t hw) |
| 347 | { | 350 | { |
| @@ -352,7 +355,8 @@ static int intc_irqpin_irq_domain_map(struct irq_domain *h, unsigned int virq, | |||
| 352 | 355 | ||
| 353 | intc_irqpin_dbg(&p->irq[hw], "map"); | 356 | intc_irqpin_dbg(&p->irq[hw], "map"); |
| 354 | irq_set_chip_data(virq, h->host_data); | 357 | irq_set_chip_data(virq, h->host_data); |
| 355 | irq_set_lockdep_class(virq, &intc_irqpin_irq_lock_class); | 358 | irq_set_lockdep_class(virq, &intc_irqpin_irq_lock_class, |
| 359 | &intc_irqpin_irq_request_class); | ||
| 356 | irq_set_chip_and_handler(virq, &p->irq_chip, handle_level_irq); | 360 | irq_set_chip_and_handler(virq, &p->irq_chip, handle_level_irq); |
| 357 | return 0; | 361 | return 0; |
| 358 | } | 362 | } |
diff --git a/drivers/leds/led-core.c b/drivers/leds/led-core.c index fd83c7f77a95..f3654fd2eaf3 100644 --- a/drivers/leds/led-core.c +++ b/drivers/leds/led-core.c | |||
| @@ -186,7 +186,7 @@ void led_blink_set(struct led_classdev *led_cdev, | |||
| 186 | unsigned long *delay_on, | 186 | unsigned long *delay_on, |
| 187 | unsigned long *delay_off) | 187 | unsigned long *delay_off) |
| 188 | { | 188 | { |
| 189 | del_timer_sync(&led_cdev->blink_timer); | 189 | led_stop_software_blink(led_cdev); |
| 190 | 190 | ||
| 191 | clear_bit(LED_BLINK_ONESHOT, &led_cdev->work_flags); | 191 | clear_bit(LED_BLINK_ONESHOT, &led_cdev->work_flags); |
| 192 | clear_bit(LED_BLINK_ONESHOT_STOP, &led_cdev->work_flags); | 192 | clear_bit(LED_BLINK_ONESHOT_STOP, &led_cdev->work_flags); |
diff --git a/drivers/md/dm-bufio.c b/drivers/md/dm-bufio.c index b8ac591aaaa7..c546b567f3b5 100644 --- a/drivers/md/dm-bufio.c +++ b/drivers/md/dm-bufio.c | |||
| @@ -1611,7 +1611,8 @@ static unsigned long __scan(struct dm_bufio_client *c, unsigned long nr_to_scan, | |||
| 1611 | int l; | 1611 | int l; |
| 1612 | struct dm_buffer *b, *tmp; | 1612 | struct dm_buffer *b, *tmp; |
| 1613 | unsigned long freed = 0; | 1613 | unsigned long freed = 0; |
| 1614 | unsigned long count = nr_to_scan; | 1614 | unsigned long count = c->n_buffers[LIST_CLEAN] + |
| 1615 | c->n_buffers[LIST_DIRTY]; | ||
| 1615 | unsigned long retain_target = get_retain_buffers(c); | 1616 | unsigned long retain_target = get_retain_buffers(c); |
| 1616 | 1617 | ||
| 1617 | for (l = 0; l < LIST_SIZE; l++) { | 1618 | for (l = 0; l < LIST_SIZE; l++) { |
| @@ -1647,8 +1648,11 @@ static unsigned long | |||
| 1647 | dm_bufio_shrink_count(struct shrinker *shrink, struct shrink_control *sc) | 1648 | dm_bufio_shrink_count(struct shrinker *shrink, struct shrink_control *sc) |
| 1648 | { | 1649 | { |
| 1649 | struct dm_bufio_client *c = container_of(shrink, struct dm_bufio_client, shrinker); | 1650 | struct dm_bufio_client *c = container_of(shrink, struct dm_bufio_client, shrinker); |
| 1651 | unsigned long count = READ_ONCE(c->n_buffers[LIST_CLEAN]) + | ||
| 1652 | READ_ONCE(c->n_buffers[LIST_DIRTY]); | ||
| 1653 | unsigned long retain_target = get_retain_buffers(c); | ||
| 1650 | 1654 | ||
| 1651 | return READ_ONCE(c->n_buffers[LIST_CLEAN]) + READ_ONCE(c->n_buffers[LIST_DIRTY]); | 1655 | return (count < retain_target) ? 0 : (count - retain_target); |
| 1652 | } | 1656 | } |
| 1653 | 1657 | ||
| 1654 | /* | 1658 | /* |
diff --git a/drivers/md/dm-cache-target.c b/drivers/md/dm-cache-target.c index cf23a14f9c6a..47407e43b96a 100644 --- a/drivers/md/dm-cache-target.c +++ b/drivers/md/dm-cache-target.c | |||
| @@ -3472,18 +3472,18 @@ static int __init dm_cache_init(void) | |||
| 3472 | { | 3472 | { |
| 3473 | int r; | 3473 | int r; |
| 3474 | 3474 | ||
| 3475 | r = dm_register_target(&cache_target); | ||
| 3476 | if (r) { | ||
| 3477 | DMERR("cache target registration failed: %d", r); | ||
| 3478 | return r; | ||
| 3479 | } | ||
| 3480 | |||
| 3481 | migration_cache = KMEM_CACHE(dm_cache_migration, 0); | 3475 | migration_cache = KMEM_CACHE(dm_cache_migration, 0); |
| 3482 | if (!migration_cache) { | 3476 | if (!migration_cache) { |
| 3483 | dm_unregister_target(&cache_target); | 3477 | dm_unregister_target(&cache_target); |
| 3484 | return -ENOMEM; | 3478 | return -ENOMEM; |
| 3485 | } | 3479 | } |
| 3486 | 3480 | ||
| 3481 | r = dm_register_target(&cache_target); | ||
| 3482 | if (r) { | ||
| 3483 | DMERR("cache target registration failed: %d", r); | ||
| 3484 | return r; | ||
| 3485 | } | ||
| 3486 | |||
| 3487 | return 0; | 3487 | return 0; |
| 3488 | } | 3488 | } |
| 3489 | 3489 | ||
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c index c8faa2b85842..f7810cc869ac 100644 --- a/drivers/md/dm-mpath.c +++ b/drivers/md/dm-mpath.c | |||
| @@ -458,6 +458,38 @@ do { \ | |||
| 458 | } while (0) | 458 | } while (0) |
| 459 | 459 | ||
| 460 | /* | 460 | /* |
| 461 | * Check whether bios must be queued in the device-mapper core rather | ||
| 462 | * than here in the target. | ||
| 463 | * | ||
| 464 | * If MPATHF_QUEUE_IF_NO_PATH and MPATHF_SAVED_QUEUE_IF_NO_PATH hold | ||
| 465 | * the same value then we are not between multipath_presuspend() | ||
| 466 | * and multipath_resume() calls and we have no need to check | ||
| 467 | * for the DMF_NOFLUSH_SUSPENDING flag. | ||
| 468 | */ | ||
| 469 | static bool __must_push_back(struct multipath *m, unsigned long flags) | ||
| 470 | { | ||
| 471 | return ((test_bit(MPATHF_QUEUE_IF_NO_PATH, &flags) != | ||
| 472 | test_bit(MPATHF_SAVED_QUEUE_IF_NO_PATH, &flags)) && | ||
| 473 | dm_noflush_suspending(m->ti)); | ||
| 474 | } | ||
| 475 | |||
| 476 | /* | ||
| 477 | * Following functions use READ_ONCE to get atomic access to | ||
| 478 | * all m->flags to avoid taking spinlock | ||
| 479 | */ | ||
| 480 | static bool must_push_back_rq(struct multipath *m) | ||
| 481 | { | ||
| 482 | unsigned long flags = READ_ONCE(m->flags); | ||
| 483 | return test_bit(MPATHF_QUEUE_IF_NO_PATH, &flags) || __must_push_back(m, flags); | ||
| 484 | } | ||
| 485 | |||
| 486 | static bool must_push_back_bio(struct multipath *m) | ||
| 487 | { | ||
| 488 | unsigned long flags = READ_ONCE(m->flags); | ||
| 489 | return __must_push_back(m, flags); | ||
| 490 | } | ||
| 491 | |||
| 492 | /* | ||
| 461 | * Map cloned requests (request-based multipath) | 493 | * Map cloned requests (request-based multipath) |
| 462 | */ | 494 | */ |
| 463 | static int multipath_clone_and_map(struct dm_target *ti, struct request *rq, | 495 | static int multipath_clone_and_map(struct dm_target *ti, struct request *rq, |
| @@ -478,7 +510,7 @@ static int multipath_clone_and_map(struct dm_target *ti, struct request *rq, | |||
| 478 | pgpath = choose_pgpath(m, nr_bytes); | 510 | pgpath = choose_pgpath(m, nr_bytes); |
| 479 | 511 | ||
| 480 | if (!pgpath) { | 512 | if (!pgpath) { |
| 481 | if (test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags)) | 513 | if (must_push_back_rq(m)) |
| 482 | return DM_MAPIO_DELAY_REQUEUE; | 514 | return DM_MAPIO_DELAY_REQUEUE; |
| 483 | dm_report_EIO(m); /* Failed */ | 515 | dm_report_EIO(m); /* Failed */ |
| 484 | return DM_MAPIO_KILL; | 516 | return DM_MAPIO_KILL; |
| @@ -553,7 +585,7 @@ static int __multipath_map_bio(struct multipath *m, struct bio *bio, struct dm_m | |||
| 553 | } | 585 | } |
| 554 | 586 | ||
| 555 | if (!pgpath) { | 587 | if (!pgpath) { |
| 556 | if (test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags)) | 588 | if (must_push_back_bio(m)) |
| 557 | return DM_MAPIO_REQUEUE; | 589 | return DM_MAPIO_REQUEUE; |
| 558 | dm_report_EIO(m); | 590 | dm_report_EIO(m); |
| 559 | return DM_MAPIO_KILL; | 591 | return DM_MAPIO_KILL; |
| @@ -651,8 +683,7 @@ static int queue_if_no_path(struct multipath *m, bool queue_if_no_path, | |||
| 651 | assign_bit(MPATHF_SAVED_QUEUE_IF_NO_PATH, &m->flags, | 683 | assign_bit(MPATHF_SAVED_QUEUE_IF_NO_PATH, &m->flags, |
| 652 | (save_old_value && test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags)) || | 684 | (save_old_value && test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags)) || |
| 653 | (!save_old_value && queue_if_no_path)); | 685 | (!save_old_value && queue_if_no_path)); |
| 654 | assign_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags, | 686 | assign_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags, queue_if_no_path); |
| 655 | queue_if_no_path || dm_noflush_suspending(m->ti)); | ||
| 656 | spin_unlock_irqrestore(&m->lock, flags); | 687 | spin_unlock_irqrestore(&m->lock, flags); |
| 657 | 688 | ||
| 658 | if (!queue_if_no_path) { | 689 | if (!queue_if_no_path) { |
| @@ -1486,7 +1517,7 @@ static int multipath_end_io(struct dm_target *ti, struct request *clone, | |||
| 1486 | fail_path(pgpath); | 1517 | fail_path(pgpath); |
| 1487 | 1518 | ||
| 1488 | if (atomic_read(&m->nr_valid_paths) == 0 && | 1519 | if (atomic_read(&m->nr_valid_paths) == 0 && |
| 1489 | !test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags)) { | 1520 | !must_push_back_rq(m)) { |
| 1490 | if (error == BLK_STS_IOERR) | 1521 | if (error == BLK_STS_IOERR) |
| 1491 | dm_report_EIO(m); | 1522 | dm_report_EIO(m); |
| 1492 | /* complete with the original error */ | 1523 | /* complete with the original error */ |
| @@ -1521,8 +1552,12 @@ static int multipath_end_io_bio(struct dm_target *ti, struct bio *clone, | |||
| 1521 | 1552 | ||
| 1522 | if (atomic_read(&m->nr_valid_paths) == 0 && | 1553 | if (atomic_read(&m->nr_valid_paths) == 0 && |
| 1523 | !test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags)) { | 1554 | !test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags)) { |
| 1524 | dm_report_EIO(m); | 1555 | if (must_push_back_bio(m)) { |
| 1525 | *error = BLK_STS_IOERR; | 1556 | r = DM_ENDIO_REQUEUE; |
| 1557 | } else { | ||
| 1558 | dm_report_EIO(m); | ||
| 1559 | *error = BLK_STS_IOERR; | ||
| 1560 | } | ||
| 1526 | goto done; | 1561 | goto done; |
| 1527 | } | 1562 | } |
| 1528 | 1563 | ||
| @@ -1957,13 +1992,6 @@ static int __init dm_multipath_init(void) | |||
| 1957 | { | 1992 | { |
| 1958 | int r; | 1993 | int r; |
| 1959 | 1994 | ||
| 1960 | r = dm_register_target(&multipath_target); | ||
| 1961 | if (r < 0) { | ||
| 1962 | DMERR("request-based register failed %d", r); | ||
| 1963 | r = -EINVAL; | ||
| 1964 | goto bad_register_target; | ||
| 1965 | } | ||
| 1966 | |||
| 1967 | kmultipathd = alloc_workqueue("kmpathd", WQ_MEM_RECLAIM, 0); | 1995 | kmultipathd = alloc_workqueue("kmpathd", WQ_MEM_RECLAIM, 0); |
| 1968 | if (!kmultipathd) { | 1996 | if (!kmultipathd) { |
| 1969 | DMERR("failed to create workqueue kmpathd"); | 1997 | DMERR("failed to create workqueue kmpathd"); |
| @@ -1985,13 +2013,20 @@ static int __init dm_multipath_init(void) | |||
| 1985 | goto bad_alloc_kmpath_handlerd; | 2013 | goto bad_alloc_kmpath_handlerd; |
| 1986 | } | 2014 | } |
| 1987 | 2015 | ||
| 2016 | r = dm_register_target(&multipath_target); | ||
| 2017 | if (r < 0) { | ||
| 2018 | DMERR("request-based register failed %d", r); | ||
| 2019 | r = -EINVAL; | ||
| 2020 | goto bad_register_target; | ||
| 2021 | } | ||
| 2022 | |||
| 1988 | return 0; | 2023 | return 0; |
| 1989 | 2024 | ||
| 2025 | bad_register_target: | ||
| 2026 | destroy_workqueue(kmpath_handlerd); | ||
| 1990 | bad_alloc_kmpath_handlerd: | 2027 | bad_alloc_kmpath_handlerd: |
| 1991 | destroy_workqueue(kmultipathd); | 2028 | destroy_workqueue(kmultipathd); |
| 1992 | bad_alloc_kmultipathd: | 2029 | bad_alloc_kmultipathd: |
| 1993 | dm_unregister_target(&multipath_target); | ||
| 1994 | bad_register_target: | ||
| 1995 | return r; | 2030 | return r; |
| 1996 | } | 2031 | } |
| 1997 | 2032 | ||
diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c index 1113b42e1eda..a0613bd8ed00 100644 --- a/drivers/md/dm-snap.c +++ b/drivers/md/dm-snap.c | |||
| @@ -2411,24 +2411,6 @@ static int __init dm_snapshot_init(void) | |||
| 2411 | return r; | 2411 | return r; |
| 2412 | } | 2412 | } |
| 2413 | 2413 | ||
| 2414 | r = dm_register_target(&snapshot_target); | ||
| 2415 | if (r < 0) { | ||
| 2416 | DMERR("snapshot target register failed %d", r); | ||
| 2417 | goto bad_register_snapshot_target; | ||
| 2418 | } | ||
| 2419 | |||
| 2420 | r = dm_register_target(&origin_target); | ||
| 2421 | if (r < 0) { | ||
| 2422 | DMERR("Origin target register failed %d", r); | ||
| 2423 | goto bad_register_origin_target; | ||
| 2424 | } | ||
| 2425 | |||
| 2426 | r = dm_register_target(&merge_target); | ||
| 2427 | if (r < 0) { | ||
| 2428 | DMERR("Merge target register failed %d", r); | ||
| 2429 | goto bad_register_merge_target; | ||
| 2430 | } | ||
| 2431 | |||
| 2432 | r = init_origin_hash(); | 2414 | r = init_origin_hash(); |
| 2433 | if (r) { | 2415 | if (r) { |
| 2434 | DMERR("init_origin_hash failed."); | 2416 | DMERR("init_origin_hash failed."); |
| @@ -2449,19 +2431,37 @@ static int __init dm_snapshot_init(void) | |||
| 2449 | goto bad_pending_cache; | 2431 | goto bad_pending_cache; |
| 2450 | } | 2432 | } |
| 2451 | 2433 | ||
| 2434 | r = dm_register_target(&snapshot_target); | ||
| 2435 | if (r < 0) { | ||
| 2436 | DMERR("snapshot target register failed %d", r); | ||
| 2437 | goto bad_register_snapshot_target; | ||
| 2438 | } | ||
| 2439 | |||
| 2440 | r = dm_register_target(&origin_target); | ||
| 2441 | if (r < 0) { | ||
| 2442 | DMERR("Origin target register failed %d", r); | ||
| 2443 | goto bad_register_origin_target; | ||
| 2444 | } | ||
| 2445 | |||
| 2446 | r = dm_register_target(&merge_target); | ||
| 2447 | if (r < 0) { | ||
| 2448 | DMERR("Merge target register failed %d", r); | ||
| 2449 | goto bad_register_merge_target; | ||
| 2450 | } | ||
| 2451 | |||
| 2452 | return 0; | 2452 | return 0; |
| 2453 | 2453 | ||
| 2454 | bad_pending_cache: | ||
| 2455 | kmem_cache_destroy(exception_cache); | ||
| 2456 | bad_exception_cache: | ||
| 2457 | exit_origin_hash(); | ||
| 2458 | bad_origin_hash: | ||
| 2459 | dm_unregister_target(&merge_target); | ||
| 2460 | bad_register_merge_target: | 2454 | bad_register_merge_target: |
| 2461 | dm_unregister_target(&origin_target); | 2455 | dm_unregister_target(&origin_target); |
| 2462 | bad_register_origin_target: | 2456 | bad_register_origin_target: |
| 2463 | dm_unregister_target(&snapshot_target); | 2457 | dm_unregister_target(&snapshot_target); |
| 2464 | bad_register_snapshot_target: | 2458 | bad_register_snapshot_target: |
| 2459 | kmem_cache_destroy(pending_cache); | ||
| 2460 | bad_pending_cache: | ||
| 2461 | kmem_cache_destroy(exception_cache); | ||
| 2462 | bad_exception_cache: | ||
| 2463 | exit_origin_hash(); | ||
| 2464 | bad_origin_hash: | ||
| 2465 | dm_exception_store_exit(); | 2465 | dm_exception_store_exit(); |
| 2466 | 2466 | ||
| 2467 | return r; | 2467 | return r; |
diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c index 88130b5d95f9..aaffd0c0ee9a 100644 --- a/drivers/md/dm-table.c +++ b/drivers/md/dm-table.c | |||
| @@ -453,14 +453,15 @@ int dm_get_device(struct dm_target *ti, const char *path, fmode_t mode, | |||
| 453 | 453 | ||
| 454 | refcount_set(&dd->count, 1); | 454 | refcount_set(&dd->count, 1); |
| 455 | list_add(&dd->list, &t->devices); | 455 | list_add(&dd->list, &t->devices); |
| 456 | goto out; | ||
| 456 | 457 | ||
| 457 | } else if (dd->dm_dev->mode != (mode | dd->dm_dev->mode)) { | 458 | } else if (dd->dm_dev->mode != (mode | dd->dm_dev->mode)) { |
| 458 | r = upgrade_mode(dd, mode, t->md); | 459 | r = upgrade_mode(dd, mode, t->md); |
| 459 | if (r) | 460 | if (r) |
| 460 | return r; | 461 | return r; |
| 461 | refcount_inc(&dd->count); | ||
| 462 | } | 462 | } |
| 463 | 463 | refcount_inc(&dd->count); | |
| 464 | out: | ||
| 464 | *result = dd->dm_dev; | 465 | *result = dd->dm_dev; |
| 465 | return 0; | 466 | return 0; |
| 466 | } | 467 | } |
diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c index 89e5dff9b4cf..f91d771fff4b 100644 --- a/drivers/md/dm-thin.c +++ b/drivers/md/dm-thin.c | |||
| @@ -4355,30 +4355,28 @@ static struct target_type thin_target = { | |||
| 4355 | 4355 | ||
| 4356 | static int __init dm_thin_init(void) | 4356 | static int __init dm_thin_init(void) |
| 4357 | { | 4357 | { |
| 4358 | int r; | 4358 | int r = -ENOMEM; |
| 4359 | 4359 | ||
| 4360 | pool_table_init(); | 4360 | pool_table_init(); |
| 4361 | 4361 | ||
| 4362 | _new_mapping_cache = KMEM_CACHE(dm_thin_new_mapping, 0); | ||
| 4363 | if (!_new_mapping_cache) | ||
| 4364 | return r; | ||
| 4365 | |||
| 4362 | r = dm_register_target(&thin_target); | 4366 | r = dm_register_target(&thin_target); |
| 4363 | if (r) | 4367 | if (r) |
| 4364 | return r; | 4368 | goto bad_new_mapping_cache; |
| 4365 | 4369 | ||
| 4366 | r = dm_register_target(&pool_target); | 4370 | r = dm_register_target(&pool_target); |
| 4367 | if (r) | 4371 | if (r) |
| 4368 | goto bad_pool_target; | 4372 | goto bad_thin_target; |
| 4369 | |||
| 4370 | r = -ENOMEM; | ||
| 4371 | |||
| 4372 | _new_mapping_cache = KMEM_CACHE(dm_thin_new_mapping, 0); | ||
| 4373 | if (!_new_mapping_cache) | ||
| 4374 | goto bad_new_mapping_cache; | ||
| 4375 | 4373 | ||
| 4376 | return 0; | 4374 | return 0; |
| 4377 | 4375 | ||
| 4378 | bad_new_mapping_cache: | 4376 | bad_thin_target: |
| 4379 | dm_unregister_target(&pool_target); | ||
| 4380 | bad_pool_target: | ||
| 4381 | dm_unregister_target(&thin_target); | 4377 | dm_unregister_target(&thin_target); |
| 4378 | bad_new_mapping_cache: | ||
| 4379 | kmem_cache_destroy(_new_mapping_cache); | ||
| 4382 | 4380 | ||
| 4383 | return r; | 4381 | return r; |
| 4384 | } | 4382 | } |
diff --git a/drivers/mfd/arizona-irq.c b/drivers/mfd/arizona-irq.c index 09cf3699e354..a307832d7e45 100644 --- a/drivers/mfd/arizona-irq.c +++ b/drivers/mfd/arizona-irq.c | |||
| @@ -184,6 +184,7 @@ static struct irq_chip arizona_irq_chip = { | |||
| 184 | }; | 184 | }; |
| 185 | 185 | ||
| 186 | static struct lock_class_key arizona_irq_lock_class; | 186 | static struct lock_class_key arizona_irq_lock_class; |
| 187 | static struct lock_class_key arizona_irq_request_class; | ||
| 187 | 188 | ||
| 188 | static int arizona_irq_map(struct irq_domain *h, unsigned int virq, | 189 | static int arizona_irq_map(struct irq_domain *h, unsigned int virq, |
| 189 | irq_hw_number_t hw) | 190 | irq_hw_number_t hw) |
| @@ -191,7 +192,8 @@ static int arizona_irq_map(struct irq_domain *h, unsigned int virq, | |||
| 191 | struct arizona *data = h->host_data; | 192 | struct arizona *data = h->host_data; |
| 192 | 193 | ||
| 193 | irq_set_chip_data(virq, data); | 194 | irq_set_chip_data(virq, data); |
| 194 | irq_set_lockdep_class(virq, &arizona_irq_lock_class); | 195 | irq_set_lockdep_class(virq, &arizona_irq_lock_class, |
| 196 | &arizona_irq_request_class); | ||
| 195 | irq_set_chip_and_handler(virq, &arizona_irq_chip, handle_simple_irq); | 197 | irq_set_chip_and_handler(virq, &arizona_irq_chip, handle_simple_irq); |
| 196 | irq_set_nested_thread(virq, 1); | 198 | irq_set_nested_thread(virq, 1); |
| 197 | irq_set_noprobe(virq); | 199 | irq_set_noprobe(virq); |
diff --git a/drivers/mfd/cros_ec_spi.c b/drivers/mfd/cros_ec_spi.c index c9714072e224..59c82cdcf48d 100644 --- a/drivers/mfd/cros_ec_spi.c +++ b/drivers/mfd/cros_ec_spi.c | |||
| @@ -377,6 +377,7 @@ static int cros_ec_pkt_xfer_spi(struct cros_ec_device *ec_dev, | |||
| 377 | u8 *ptr; | 377 | u8 *ptr; |
| 378 | u8 *rx_buf; | 378 | u8 *rx_buf; |
| 379 | u8 sum; | 379 | u8 sum; |
| 380 | u8 rx_byte; | ||
| 380 | int ret = 0, final_ret; | 381 | int ret = 0, final_ret; |
| 381 | 382 | ||
| 382 | len = cros_ec_prepare_tx(ec_dev, ec_msg); | 383 | len = cros_ec_prepare_tx(ec_dev, ec_msg); |
| @@ -421,25 +422,22 @@ static int cros_ec_pkt_xfer_spi(struct cros_ec_device *ec_dev, | |||
| 421 | if (!ret) { | 422 | if (!ret) { |
| 422 | /* Verify that EC can process command */ | 423 | /* Verify that EC can process command */ |
| 423 | for (i = 0; i < len; i++) { | 424 | for (i = 0; i < len; i++) { |
| 424 | switch (rx_buf[i]) { | 425 | rx_byte = rx_buf[i]; |
| 425 | case EC_SPI_PAST_END: | 426 | if (rx_byte == EC_SPI_PAST_END || |
| 426 | case EC_SPI_RX_BAD_DATA: | 427 | rx_byte == EC_SPI_RX_BAD_DATA || |
| 427 | case EC_SPI_NOT_READY: | 428 | rx_byte == EC_SPI_NOT_READY) { |
| 428 | ret = -EAGAIN; | 429 | ret = -EREMOTEIO; |
| 429 | ec_msg->result = EC_RES_IN_PROGRESS; | ||
| 430 | default: | ||
| 431 | break; | 430 | break; |
| 432 | } | 431 | } |
| 433 | if (ret) | ||
| 434 | break; | ||
| 435 | } | 432 | } |
| 436 | if (!ret) | ||
| 437 | ret = cros_ec_spi_receive_packet(ec_dev, | ||
| 438 | ec_msg->insize + sizeof(*response)); | ||
| 439 | } else { | ||
| 440 | dev_err(ec_dev->dev, "spi transfer failed: %d\n", ret); | ||
| 441 | } | 433 | } |
| 442 | 434 | ||
| 435 | if (!ret) | ||
| 436 | ret = cros_ec_spi_receive_packet(ec_dev, | ||
| 437 | ec_msg->insize + sizeof(*response)); | ||
| 438 | else | ||
| 439 | dev_err(ec_dev->dev, "spi transfer failed: %d\n", ret); | ||
| 440 | |||
| 443 | final_ret = terminate_request(ec_dev); | 441 | final_ret = terminate_request(ec_dev); |
| 444 | 442 | ||
| 445 | spi_bus_unlock(ec_spi->spi->master); | 443 | spi_bus_unlock(ec_spi->spi->master); |
| @@ -508,6 +506,7 @@ static int cros_ec_cmd_xfer_spi(struct cros_ec_device *ec_dev, | |||
| 508 | int i, len; | 506 | int i, len; |
| 509 | u8 *ptr; | 507 | u8 *ptr; |
| 510 | u8 *rx_buf; | 508 | u8 *rx_buf; |
| 509 | u8 rx_byte; | ||
| 511 | int sum; | 510 | int sum; |
| 512 | int ret = 0, final_ret; | 511 | int ret = 0, final_ret; |
| 513 | 512 | ||
| @@ -544,25 +543,22 @@ static int cros_ec_cmd_xfer_spi(struct cros_ec_device *ec_dev, | |||
| 544 | if (!ret) { | 543 | if (!ret) { |
| 545 | /* Verify that EC can process command */ | 544 | /* Verify that EC can process command */ |
| 546 | for (i = 0; i < len; i++) { | 545 | for (i = 0; i < len; i++) { |
| 547 | switch (rx_buf[i]) { | 546 | rx_byte = rx_buf[i]; |
| 548 | case EC_SPI_PAST_END: | 547 | if (rx_byte == EC_SPI_PAST_END || |
| 549 | case EC_SPI_RX_BAD_DATA: | 548 | rx_byte == EC_SPI_RX_BAD_DATA || |
| 550 | case EC_SPI_NOT_READY: | 549 | rx_byte == EC_SPI_NOT_READY) { |
| 551 | ret = -EAGAIN; | 550 | ret = -EREMOTEIO; |
| 552 | ec_msg->result = EC_RES_IN_PROGRESS; | ||
| 553 | default: | ||
| 554 | break; | 551 | break; |
| 555 | } | 552 | } |
| 556 | if (ret) | ||
| 557 | break; | ||
| 558 | } | 553 | } |
| 559 | if (!ret) | ||
| 560 | ret = cros_ec_spi_receive_response(ec_dev, | ||
| 561 | ec_msg->insize + EC_MSG_TX_PROTO_BYTES); | ||
| 562 | } else { | ||
| 563 | dev_err(ec_dev->dev, "spi transfer failed: %d\n", ret); | ||
| 564 | } | 554 | } |
| 565 | 555 | ||
| 556 | if (!ret) | ||
| 557 | ret = cros_ec_spi_receive_response(ec_dev, | ||
| 558 | ec_msg->insize + EC_MSG_TX_PROTO_BYTES); | ||
| 559 | else | ||
| 560 | dev_err(ec_dev->dev, "spi transfer failed: %d\n", ret); | ||
| 561 | |||
| 566 | final_ret = terminate_request(ec_dev); | 562 | final_ret = terminate_request(ec_dev); |
| 567 | 563 | ||
| 568 | spi_bus_unlock(ec_spi->spi->master); | 564 | spi_bus_unlock(ec_spi->spi->master); |
| @@ -667,6 +663,7 @@ static int cros_ec_spi_probe(struct spi_device *spi) | |||
| 667 | sizeof(struct ec_response_get_protocol_info); | 663 | sizeof(struct ec_response_get_protocol_info); |
| 668 | ec_dev->dout_size = sizeof(struct ec_host_request); | 664 | ec_dev->dout_size = sizeof(struct ec_host_request); |
| 669 | 665 | ||
| 666 | ec_spi->last_transfer_ns = ktime_get_ns(); | ||
| 670 | 667 | ||
| 671 | err = cros_ec_register(ec_dev); | 668 | err = cros_ec_register(ec_dev); |
| 672 | if (err) { | 669 | if (err) { |
diff --git a/drivers/mfd/twl4030-audio.c b/drivers/mfd/twl4030-audio.c index da16bf45fab4..dc94ffc6321a 100644 --- a/drivers/mfd/twl4030-audio.c +++ b/drivers/mfd/twl4030-audio.c | |||
| @@ -159,13 +159,18 @@ unsigned int twl4030_audio_get_mclk(void) | |||
| 159 | EXPORT_SYMBOL_GPL(twl4030_audio_get_mclk); | 159 | EXPORT_SYMBOL_GPL(twl4030_audio_get_mclk); |
| 160 | 160 | ||
| 161 | static bool twl4030_audio_has_codec(struct twl4030_audio_data *pdata, | 161 | static bool twl4030_audio_has_codec(struct twl4030_audio_data *pdata, |
| 162 | struct device_node *node) | 162 | struct device_node *parent) |
| 163 | { | 163 | { |
| 164 | struct device_node *node; | ||
| 165 | |||
| 164 | if (pdata && pdata->codec) | 166 | if (pdata && pdata->codec) |
| 165 | return true; | 167 | return true; |
| 166 | 168 | ||
| 167 | if (of_find_node_by_name(node, "codec")) | 169 | node = of_get_child_by_name(parent, "codec"); |
| 170 | if (node) { | ||
| 171 | of_node_put(node); | ||
| 168 | return true; | 172 | return true; |
| 173 | } | ||
| 169 | 174 | ||
| 170 | return false; | 175 | return false; |
| 171 | } | 176 | } |
diff --git a/drivers/mfd/twl6040.c b/drivers/mfd/twl6040.c index d66502d36ba0..dd19f17a1b63 100644 --- a/drivers/mfd/twl6040.c +++ b/drivers/mfd/twl6040.c | |||
| @@ -97,12 +97,16 @@ static struct reg_sequence twl6040_patch[] = { | |||
| 97 | }; | 97 | }; |
| 98 | 98 | ||
| 99 | 99 | ||
| 100 | static bool twl6040_has_vibra(struct device_node *node) | 100 | static bool twl6040_has_vibra(struct device_node *parent) |
| 101 | { | 101 | { |
| 102 | #ifdef CONFIG_OF | 102 | struct device_node *node; |
| 103 | if (of_find_node_by_name(node, "vibra")) | 103 | |
| 104 | node = of_get_child_by_name(parent, "vibra"); | ||
| 105 | if (node) { | ||
| 106 | of_node_put(node); | ||
| 104 | return true; | 107 | return true; |
| 105 | #endif | 108 | } |
| 109 | |||
| 106 | return false; | 110 | return false; |
| 107 | } | 111 | } |
| 108 | 112 | ||
diff --git a/drivers/misc/eeprom/at24.c b/drivers/misc/eeprom/at24.c index 305a7a464d09..4d63ac8a82e0 100644 --- a/drivers/misc/eeprom/at24.c +++ b/drivers/misc/eeprom/at24.c | |||
| @@ -562,7 +562,7 @@ static ssize_t at24_eeprom_write_i2c(struct at24_data *at24, const char *buf, | |||
| 562 | static int at24_read(void *priv, unsigned int off, void *val, size_t count) | 562 | static int at24_read(void *priv, unsigned int off, void *val, size_t count) |
| 563 | { | 563 | { |
| 564 | struct at24_data *at24 = priv; | 564 | struct at24_data *at24 = priv; |
| 565 | struct i2c_client *client; | 565 | struct device *dev = &at24->client[0]->dev; |
| 566 | char *buf = val; | 566 | char *buf = val; |
| 567 | int ret; | 567 | int ret; |
| 568 | 568 | ||
| @@ -572,11 +572,9 @@ static int at24_read(void *priv, unsigned int off, void *val, size_t count) | |||
| 572 | if (off + count > at24->chip.byte_len) | 572 | if (off + count > at24->chip.byte_len) |
| 573 | return -EINVAL; | 573 | return -EINVAL; |
| 574 | 574 | ||
| 575 | client = at24_translate_offset(at24, &off); | 575 | ret = pm_runtime_get_sync(dev); |
| 576 | |||
| 577 | ret = pm_runtime_get_sync(&client->dev); | ||
| 578 | if (ret < 0) { | 576 | if (ret < 0) { |
| 579 | pm_runtime_put_noidle(&client->dev); | 577 | pm_runtime_put_noidle(dev); |
| 580 | return ret; | 578 | return ret; |
| 581 | } | 579 | } |
| 582 | 580 | ||
| @@ -592,7 +590,7 @@ static int at24_read(void *priv, unsigned int off, void *val, size_t count) | |||
| 592 | status = at24->read_func(at24, buf, off, count); | 590 | status = at24->read_func(at24, buf, off, count); |
| 593 | if (status < 0) { | 591 | if (status < 0) { |
| 594 | mutex_unlock(&at24->lock); | 592 | mutex_unlock(&at24->lock); |
| 595 | pm_runtime_put(&client->dev); | 593 | pm_runtime_put(dev); |
| 596 | return status; | 594 | return status; |
| 597 | } | 595 | } |
| 598 | buf += status; | 596 | buf += status; |
| @@ -602,7 +600,7 @@ static int at24_read(void *priv, unsigned int off, void *val, size_t count) | |||
| 602 | 600 | ||
| 603 | mutex_unlock(&at24->lock); | 601 | mutex_unlock(&at24->lock); |
| 604 | 602 | ||
| 605 | pm_runtime_put(&client->dev); | 603 | pm_runtime_put(dev); |
| 606 | 604 | ||
| 607 | return 0; | 605 | return 0; |
| 608 | } | 606 | } |
| @@ -610,7 +608,7 @@ static int at24_read(void *priv, unsigned int off, void *val, size_t count) | |||
| 610 | static int at24_write(void *priv, unsigned int off, void *val, size_t count) | 608 | static int at24_write(void *priv, unsigned int off, void *val, size_t count) |
| 611 | { | 609 | { |
| 612 | struct at24_data *at24 = priv; | 610 | struct at24_data *at24 = priv; |
| 613 | struct i2c_client *client; | 611 | struct device *dev = &at24->client[0]->dev; |
| 614 | char *buf = val; | 612 | char *buf = val; |
| 615 | int ret; | 613 | int ret; |
| 616 | 614 | ||
| @@ -620,11 +618,9 @@ static int at24_write(void *priv, unsigned int off, void *val, size_t count) | |||
| 620 | if (off + count > at24->chip.byte_len) | 618 | if (off + count > at24->chip.byte_len) |
| 621 | return -EINVAL; | 619 | return -EINVAL; |
| 622 | 620 | ||
| 623 | client = at24_translate_offset(at24, &off); | 621 | ret = pm_runtime_get_sync(dev); |
| 624 | |||
| 625 | ret = pm_runtime_get_sync(&client->dev); | ||
| 626 | if (ret < 0) { | 622 | if (ret < 0) { |
| 627 | pm_runtime_put_noidle(&client->dev); | 623 | pm_runtime_put_noidle(dev); |
| 628 | return ret; | 624 | return ret; |
| 629 | } | 625 | } |
| 630 | 626 | ||
| @@ -640,7 +636,7 @@ static int at24_write(void *priv, unsigned int off, void *val, size_t count) | |||
| 640 | status = at24->write_func(at24, buf, off, count); | 636 | status = at24->write_func(at24, buf, off, count); |
| 641 | if (status < 0) { | 637 | if (status < 0) { |
| 642 | mutex_unlock(&at24->lock); | 638 | mutex_unlock(&at24->lock); |
| 643 | pm_runtime_put(&client->dev); | 639 | pm_runtime_put(dev); |
| 644 | return status; | 640 | return status; |
| 645 | } | 641 | } |
| 646 | buf += status; | 642 | buf += status; |
| @@ -650,7 +646,7 @@ static int at24_write(void *priv, unsigned int off, void *val, size_t count) | |||
| 650 | 646 | ||
| 651 | mutex_unlock(&at24->lock); | 647 | mutex_unlock(&at24->lock); |
| 652 | 648 | ||
| 653 | pm_runtime_put(&client->dev); | 649 | pm_runtime_put(dev); |
| 654 | 650 | ||
| 655 | return 0; | 651 | return 0; |
| 656 | } | 652 | } |
| @@ -880,7 +876,7 @@ static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
| 880 | at24->nvmem_config.reg_read = at24_read; | 876 | at24->nvmem_config.reg_read = at24_read; |
| 881 | at24->nvmem_config.reg_write = at24_write; | 877 | at24->nvmem_config.reg_write = at24_write; |
| 882 | at24->nvmem_config.priv = at24; | 878 | at24->nvmem_config.priv = at24; |
| 883 | at24->nvmem_config.stride = 4; | 879 | at24->nvmem_config.stride = 1; |
| 884 | at24->nvmem_config.word_size = 1; | 880 | at24->nvmem_config.word_size = 1; |
| 885 | at24->nvmem_config.size = chip.byte_len; | 881 | at24->nvmem_config.size = chip.byte_len; |
| 886 | 882 | ||
diff --git a/drivers/misc/pti.c b/drivers/misc/pti.c index eda38cbe8530..41f2a9f6851d 100644 --- a/drivers/misc/pti.c +++ b/drivers/misc/pti.c | |||
| @@ -32,7 +32,7 @@ | |||
| 32 | #include <linux/pci.h> | 32 | #include <linux/pci.h> |
| 33 | #include <linux/mutex.h> | 33 | #include <linux/mutex.h> |
| 34 | #include <linux/miscdevice.h> | 34 | #include <linux/miscdevice.h> |
| 35 | #include <linux/pti.h> | 35 | #include <linux/intel-pti.h> |
| 36 | #include <linux/slab.h> | 36 | #include <linux/slab.h> |
| 37 | #include <linux/uaccess.h> | 37 | #include <linux/uaccess.h> |
| 38 | 38 | ||
diff --git a/drivers/mmc/core/card.h b/drivers/mmc/core/card.h index f06cd91964ce..79a5b985ccf5 100644 --- a/drivers/mmc/core/card.h +++ b/drivers/mmc/core/card.h | |||
| @@ -75,9 +75,11 @@ struct mmc_fixup { | |||
| 75 | #define EXT_CSD_REV_ANY (-1u) | 75 | #define EXT_CSD_REV_ANY (-1u) |
| 76 | 76 | ||
| 77 | #define CID_MANFID_SANDISK 0x2 | 77 | #define CID_MANFID_SANDISK 0x2 |
| 78 | #define CID_MANFID_ATP 0x9 | ||
| 78 | #define CID_MANFID_TOSHIBA 0x11 | 79 | #define CID_MANFID_TOSHIBA 0x11 |
| 79 | #define CID_MANFID_MICRON 0x13 | 80 | #define CID_MANFID_MICRON 0x13 |
| 80 | #define CID_MANFID_SAMSUNG 0x15 | 81 | #define CID_MANFID_SAMSUNG 0x15 |
| 82 | #define CID_MANFID_APACER 0x27 | ||
| 81 | #define CID_MANFID_KINGSTON 0x70 | 83 | #define CID_MANFID_KINGSTON 0x70 |
| 82 | #define CID_MANFID_HYNIX 0x90 | 84 | #define CID_MANFID_HYNIX 0x90 |
| 83 | 85 | ||
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index d209fb466979..208a762b87ef 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c | |||
| @@ -1290,7 +1290,7 @@ out_err: | |||
| 1290 | 1290 | ||
| 1291 | static void mmc_select_driver_type(struct mmc_card *card) | 1291 | static void mmc_select_driver_type(struct mmc_card *card) |
| 1292 | { | 1292 | { |
| 1293 | int card_drv_type, drive_strength, drv_type; | 1293 | int card_drv_type, drive_strength, drv_type = 0; |
| 1294 | int fixed_drv_type = card->host->fixed_drv_type; | 1294 | int fixed_drv_type = card->host->fixed_drv_type; |
| 1295 | 1295 | ||
| 1296 | card_drv_type = card->ext_csd.raw_driver_strength | | 1296 | card_drv_type = card->ext_csd.raw_driver_strength | |
diff --git a/drivers/mmc/core/quirks.h b/drivers/mmc/core/quirks.h index f664e9cbc9f8..75d317623852 100644 --- a/drivers/mmc/core/quirks.h +++ b/drivers/mmc/core/quirks.h | |||
| @@ -53,6 +53,14 @@ static const struct mmc_fixup mmc_blk_fixups[] = { | |||
| 53 | MMC_QUIRK_BLK_NO_CMD23), | 53 | MMC_QUIRK_BLK_NO_CMD23), |
| 54 | 54 | ||
| 55 | /* | 55 | /* |
| 56 | * Some SD cards lockup while using CMD23 multiblock transfers. | ||
| 57 | */ | ||
| 58 | MMC_FIXUP("AF SD", CID_MANFID_ATP, CID_OEMID_ANY, add_quirk_sd, | ||
| 59 | MMC_QUIRK_BLK_NO_CMD23), | ||
| 60 | MMC_FIXUP("APUSD", CID_MANFID_APACER, 0x5048, add_quirk_sd, | ||
| 61 | MMC_QUIRK_BLK_NO_CMD23), | ||
| 62 | |||
| 63 | /* | ||
| 56 | * Some MMC cards need longer data read timeout than indicated in CSD. | 64 | * Some MMC cards need longer data read timeout than indicated in CSD. |
| 57 | */ | 65 | */ |
| 58 | MMC_FIXUP(CID_NAME_ANY, CID_MANFID_MICRON, 0x200, add_quirk_mmc, | 66 | MMC_FIXUP(CID_NAME_ANY, CID_MANFID_MICRON, 0x200, add_quirk_mmc, |
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c index f80e911b8843..73b605577447 100644 --- a/drivers/mtd/mtdcore.c +++ b/drivers/mtd/mtdcore.c | |||
| @@ -1114,7 +1114,7 @@ static int mtd_check_oob_ops(struct mtd_info *mtd, loff_t offs, | |||
| 1114 | if (!ops->oobbuf) | 1114 | if (!ops->oobbuf) |
| 1115 | ops->ooblen = 0; | 1115 | ops->ooblen = 0; |
| 1116 | 1116 | ||
| 1117 | if (offs < 0 || offs + ops->len >= mtd->size) | 1117 | if (offs < 0 || offs + ops->len > mtd->size) |
| 1118 | return -EINVAL; | 1118 | return -EINVAL; |
| 1119 | 1119 | ||
| 1120 | if (ops->ooblen) { | 1120 | if (ops->ooblen) { |
diff --git a/drivers/mtd/nand/brcmnand/brcmnand.c b/drivers/mtd/nand/brcmnand/brcmnand.c index e0eb51d8c012..dd56a671ea42 100644 --- a/drivers/mtd/nand/brcmnand/brcmnand.c +++ b/drivers/mtd/nand/brcmnand/brcmnand.c | |||
| @@ -1763,7 +1763,7 @@ try_dmaread: | |||
| 1763 | err = brcmstb_nand_verify_erased_page(mtd, chip, buf, | 1763 | err = brcmstb_nand_verify_erased_page(mtd, chip, buf, |
| 1764 | addr); | 1764 | addr); |
| 1765 | /* erased page bitflips corrected */ | 1765 | /* erased page bitflips corrected */ |
| 1766 | if (err > 0) | 1766 | if (err >= 0) |
| 1767 | return err; | 1767 | return err; |
| 1768 | } | 1768 | } |
| 1769 | 1769 | ||
diff --git a/drivers/mtd/nand/gpio.c b/drivers/mtd/nand/gpio.c index 484f7fbc3f7d..a8bde6665c24 100644 --- a/drivers/mtd/nand/gpio.c +++ b/drivers/mtd/nand/gpio.c | |||
| @@ -253,9 +253,9 @@ static int gpio_nand_probe(struct platform_device *pdev) | |||
| 253 | goto out_ce; | 253 | goto out_ce; |
| 254 | } | 254 | } |
| 255 | 255 | ||
| 256 | gpiomtd->nwp = devm_gpiod_get(dev, "ale", GPIOD_OUT_LOW); | 256 | gpiomtd->ale = devm_gpiod_get(dev, "ale", GPIOD_OUT_LOW); |
| 257 | if (IS_ERR(gpiomtd->nwp)) { | 257 | if (IS_ERR(gpiomtd->ale)) { |
| 258 | ret = PTR_ERR(gpiomtd->nwp); | 258 | ret = PTR_ERR(gpiomtd->ale); |
| 259 | goto out_ce; | 259 | goto out_ce; |
| 260 | } | 260 | } |
| 261 | 261 | ||
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c index 50f8d4a1b983..d4d824ef64e9 100644 --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c | |||
| @@ -1067,9 +1067,6 @@ static int gpmi_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip, | |||
| 1067 | return ret; | 1067 | return ret; |
| 1068 | } | 1068 | } |
| 1069 | 1069 | ||
| 1070 | /* handle the block mark swapping */ | ||
| 1071 | block_mark_swapping(this, payload_virt, auxiliary_virt); | ||
| 1072 | |||
| 1073 | /* Loop over status bytes, accumulating ECC status. */ | 1070 | /* Loop over status bytes, accumulating ECC status. */ |
| 1074 | status = auxiliary_virt + nfc_geo->auxiliary_status_offset; | 1071 | status = auxiliary_virt + nfc_geo->auxiliary_status_offset; |
| 1075 | 1072 | ||
| @@ -1158,6 +1155,9 @@ static int gpmi_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip, | |||
| 1158 | max_bitflips = max_t(unsigned int, max_bitflips, *status); | 1155 | max_bitflips = max_t(unsigned int, max_bitflips, *status); |
| 1159 | } | 1156 | } |
| 1160 | 1157 | ||
| 1158 | /* handle the block mark swapping */ | ||
| 1159 | block_mark_swapping(this, buf, auxiliary_virt); | ||
| 1160 | |||
| 1161 | if (oob_required) { | 1161 | if (oob_required) { |
| 1162 | /* | 1162 | /* |
| 1163 | * It's time to deliver the OOB bytes. See gpmi_ecc_read_oob() | 1163 | * It's time to deliver the OOB bytes. See gpmi_ecc_read_oob() |
diff --git a/drivers/net/dsa/mv88e6xxx/port.c b/drivers/net/dsa/mv88e6xxx/port.c index a7801f6668a5..6315774d72b3 100644 --- a/drivers/net/dsa/mv88e6xxx/port.c +++ b/drivers/net/dsa/mv88e6xxx/port.c | |||
| @@ -338,6 +338,7 @@ int mv88e6390x_port_set_cmode(struct mv88e6xxx_chip *chip, int port, | |||
| 338 | cmode = MV88E6XXX_PORT_STS_CMODE_2500BASEX; | 338 | cmode = MV88E6XXX_PORT_STS_CMODE_2500BASEX; |
| 339 | break; | 339 | break; |
| 340 | case PHY_INTERFACE_MODE_XGMII: | 340 | case PHY_INTERFACE_MODE_XGMII: |
| 341 | case PHY_INTERFACE_MODE_XAUI: | ||
| 341 | cmode = MV88E6XXX_PORT_STS_CMODE_XAUI; | 342 | cmode = MV88E6XXX_PORT_STS_CMODE_XAUI; |
| 342 | break; | 343 | break; |
| 343 | case PHY_INTERFACE_MODE_RXAUI: | 344 | case PHY_INTERFACE_MODE_RXAUI: |
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_cfg.h b/drivers/net/ethernet/aquantia/atlantic/aq_cfg.h index 57e796870595..105fdb958cef 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_cfg.h +++ b/drivers/net/ethernet/aquantia/atlantic/aq_cfg.h | |||
| @@ -50,7 +50,7 @@ | |||
| 50 | #define AQ_CFG_PCI_FUNC_MSIX_IRQS 9U | 50 | #define AQ_CFG_PCI_FUNC_MSIX_IRQS 9U |
| 51 | #define AQ_CFG_PCI_FUNC_PORTS 2U | 51 | #define AQ_CFG_PCI_FUNC_PORTS 2U |
| 52 | 52 | ||
| 53 | #define AQ_CFG_SERVICE_TIMER_INTERVAL (2 * HZ) | 53 | #define AQ_CFG_SERVICE_TIMER_INTERVAL (1 * HZ) |
| 54 | #define AQ_CFG_POLLING_TIMER_INTERVAL ((unsigned int)(2 * HZ)) | 54 | #define AQ_CFG_POLLING_TIMER_INTERVAL ((unsigned int)(2 * HZ)) |
| 55 | 55 | ||
| 56 | #define AQ_CFG_SKB_FRAGS_MAX 32U | 56 | #define AQ_CFG_SKB_FRAGS_MAX 32U |
| @@ -80,6 +80,7 @@ | |||
| 80 | #define AQ_CFG_DRV_VERSION __stringify(NIC_MAJOR_DRIVER_VERSION)"."\ | 80 | #define AQ_CFG_DRV_VERSION __stringify(NIC_MAJOR_DRIVER_VERSION)"."\ |
| 81 | __stringify(NIC_MINOR_DRIVER_VERSION)"."\ | 81 | __stringify(NIC_MINOR_DRIVER_VERSION)"."\ |
| 82 | __stringify(NIC_BUILD_DRIVER_VERSION)"."\ | 82 | __stringify(NIC_BUILD_DRIVER_VERSION)"."\ |
| 83 | __stringify(NIC_REVISION_DRIVER_VERSION) | 83 | __stringify(NIC_REVISION_DRIVER_VERSION) \ |
| 84 | AQ_CFG_DRV_VERSION_SUFFIX | ||
| 84 | 85 | ||
| 85 | #endif /* AQ_CFG_H */ | 86 | #endif /* AQ_CFG_H */ |
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c b/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c index 70efb7467bf3..f2d8063a2cef 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c +++ b/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c | |||
| @@ -66,14 +66,14 @@ static const char aq_ethtool_stat_names[][ETH_GSTRING_LEN] = { | |||
| 66 | "OutUCast", | 66 | "OutUCast", |
| 67 | "OutMCast", | 67 | "OutMCast", |
| 68 | "OutBCast", | 68 | "OutBCast", |
| 69 | "InUCastOctects", | 69 | "InUCastOctets", |
| 70 | "OutUCastOctects", | 70 | "OutUCastOctets", |
| 71 | "InMCastOctects", | 71 | "InMCastOctets", |
| 72 | "OutMCastOctects", | 72 | "OutMCastOctets", |
| 73 | "InBCastOctects", | 73 | "InBCastOctets", |
| 74 | "OutBCastOctects", | 74 | "OutBCastOctets", |
| 75 | "InOctects", | 75 | "InOctets", |
| 76 | "OutOctects", | 76 | "OutOctets", |
| 77 | "InPacketsDma", | 77 | "InPacketsDma", |
| 78 | "OutPacketsDma", | 78 | "OutPacketsDma", |
| 79 | "InOctetsDma", | 79 | "InOctetsDma", |
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_hw.h b/drivers/net/ethernet/aquantia/atlantic/aq_hw.h index 0207927dc8a6..b3825de6cdfb 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_hw.h +++ b/drivers/net/ethernet/aquantia/atlantic/aq_hw.h | |||
| @@ -46,6 +46,28 @@ struct aq_hw_link_status_s { | |||
| 46 | unsigned int mbps; | 46 | unsigned int mbps; |
| 47 | }; | 47 | }; |
| 48 | 48 | ||
| 49 | struct aq_stats_s { | ||
| 50 | u64 uprc; | ||
| 51 | u64 mprc; | ||
| 52 | u64 bprc; | ||
| 53 | u64 erpt; | ||
| 54 | u64 uptc; | ||
| 55 | u64 mptc; | ||
| 56 | u64 bptc; | ||
| 57 | u64 erpr; | ||
| 58 | u64 mbtc; | ||
| 59 | u64 bbtc; | ||
| 60 | u64 mbrc; | ||
| 61 | u64 bbrc; | ||
| 62 | u64 ubrc; | ||
| 63 | u64 ubtc; | ||
| 64 | u64 dpc; | ||
| 65 | u64 dma_pkt_rc; | ||
| 66 | u64 dma_pkt_tc; | ||
| 67 | u64 dma_oct_rc; | ||
| 68 | u64 dma_oct_tc; | ||
| 69 | }; | ||
| 70 | |||
| 49 | #define AQ_HW_IRQ_INVALID 0U | 71 | #define AQ_HW_IRQ_INVALID 0U |
| 50 | #define AQ_HW_IRQ_LEGACY 1U | 72 | #define AQ_HW_IRQ_LEGACY 1U |
| 51 | #define AQ_HW_IRQ_MSI 2U | 73 | #define AQ_HW_IRQ_MSI 2U |
| @@ -85,7 +107,9 @@ struct aq_hw_ops { | |||
| 85 | void (*destroy)(struct aq_hw_s *self); | 107 | void (*destroy)(struct aq_hw_s *self); |
| 86 | 108 | ||
| 87 | int (*get_hw_caps)(struct aq_hw_s *self, | 109 | int (*get_hw_caps)(struct aq_hw_s *self, |
| 88 | struct aq_hw_caps_s *aq_hw_caps); | 110 | struct aq_hw_caps_s *aq_hw_caps, |
| 111 | unsigned short device, | ||
| 112 | unsigned short subsystem_device); | ||
| 89 | 113 | ||
| 90 | int (*hw_ring_tx_xmit)(struct aq_hw_s *self, struct aq_ring_s *aq_ring, | 114 | int (*hw_ring_tx_xmit)(struct aq_hw_s *self, struct aq_ring_s *aq_ring, |
| 91 | unsigned int frags); | 115 | unsigned int frags); |
| @@ -164,8 +188,7 @@ struct aq_hw_ops { | |||
| 164 | 188 | ||
| 165 | int (*hw_update_stats)(struct aq_hw_s *self); | 189 | int (*hw_update_stats)(struct aq_hw_s *self); |
| 166 | 190 | ||
| 167 | int (*hw_get_hw_stats)(struct aq_hw_s *self, u64 *data, | 191 | struct aq_stats_s *(*hw_get_hw_stats)(struct aq_hw_s *self); |
| 168 | unsigned int *p_count); | ||
| 169 | 192 | ||
| 170 | int (*hw_get_fw_version)(struct aq_hw_s *self, u32 *fw_version); | 193 | int (*hw_get_fw_version)(struct aq_hw_s *self, u32 *fw_version); |
| 171 | 194 | ||
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c index 78dfb2ab78ce..75a894a9251c 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c +++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c | |||
| @@ -37,6 +37,8 @@ static unsigned int aq_itr_rx; | |||
| 37 | module_param_named(aq_itr_rx, aq_itr_rx, uint, 0644); | 37 | module_param_named(aq_itr_rx, aq_itr_rx, uint, 0644); |
| 38 | MODULE_PARM_DESC(aq_itr_rx, "RX interrupt throttle rate"); | 38 | MODULE_PARM_DESC(aq_itr_rx, "RX interrupt throttle rate"); |
| 39 | 39 | ||
| 40 | static void aq_nic_update_ndev_stats(struct aq_nic_s *self); | ||
| 41 | |||
| 40 | static void aq_nic_rss_init(struct aq_nic_s *self, unsigned int num_rss_queues) | 42 | static void aq_nic_rss_init(struct aq_nic_s *self, unsigned int num_rss_queues) |
| 41 | { | 43 | { |
| 42 | struct aq_nic_cfg_s *cfg = &self->aq_nic_cfg; | 44 | struct aq_nic_cfg_s *cfg = &self->aq_nic_cfg; |
| @@ -166,11 +168,8 @@ static int aq_nic_update_link_status(struct aq_nic_s *self) | |||
| 166 | static void aq_nic_service_timer_cb(struct timer_list *t) | 168 | static void aq_nic_service_timer_cb(struct timer_list *t) |
| 167 | { | 169 | { |
| 168 | struct aq_nic_s *self = from_timer(self, t, service_timer); | 170 | struct aq_nic_s *self = from_timer(self, t, service_timer); |
| 169 | struct net_device *ndev = aq_nic_get_ndev(self); | 171 | int ctimer = AQ_CFG_SERVICE_TIMER_INTERVAL; |
| 170 | int err = 0; | 172 | int err = 0; |
| 171 | unsigned int i = 0U; | ||
| 172 | struct aq_ring_stats_rx_s stats_rx; | ||
| 173 | struct aq_ring_stats_tx_s stats_tx; | ||
| 174 | 173 | ||
| 175 | if (aq_utils_obj_test(&self->header.flags, AQ_NIC_FLAGS_IS_NOT_READY)) | 174 | if (aq_utils_obj_test(&self->header.flags, AQ_NIC_FLAGS_IS_NOT_READY)) |
| 176 | goto err_exit; | 175 | goto err_exit; |
| @@ -182,23 +181,14 @@ static void aq_nic_service_timer_cb(struct timer_list *t) | |||
| 182 | if (self->aq_hw_ops.hw_update_stats) | 181 | if (self->aq_hw_ops.hw_update_stats) |
| 183 | self->aq_hw_ops.hw_update_stats(self->aq_hw); | 182 | self->aq_hw_ops.hw_update_stats(self->aq_hw); |
| 184 | 183 | ||
| 185 | memset(&stats_rx, 0U, sizeof(struct aq_ring_stats_rx_s)); | 184 | aq_nic_update_ndev_stats(self); |
| 186 | memset(&stats_tx, 0U, sizeof(struct aq_ring_stats_tx_s)); | ||
| 187 | for (i = AQ_DIMOF(self->aq_vec); i--;) { | ||
| 188 | if (self->aq_vec[i]) | ||
| 189 | aq_vec_add_stats(self->aq_vec[i], &stats_rx, &stats_tx); | ||
| 190 | } | ||
| 191 | 185 | ||
| 192 | ndev->stats.rx_packets = stats_rx.packets; | 186 | /* If no link - use faster timer rate to detect link up asap */ |
| 193 | ndev->stats.rx_bytes = stats_rx.bytes; | 187 | if (!netif_carrier_ok(self->ndev)) |
| 194 | ndev->stats.rx_errors = stats_rx.errors; | 188 | ctimer = max(ctimer / 2, 1); |
| 195 | ndev->stats.tx_packets = stats_tx.packets; | ||
| 196 | ndev->stats.tx_bytes = stats_tx.bytes; | ||
| 197 | ndev->stats.tx_errors = stats_tx.errors; | ||
| 198 | 189 | ||
| 199 | err_exit: | 190 | err_exit: |
| 200 | mod_timer(&self->service_timer, | 191 | mod_timer(&self->service_timer, jiffies + ctimer); |
| 201 | jiffies + AQ_CFG_SERVICE_TIMER_INTERVAL); | ||
| 202 | } | 192 | } |
| 203 | 193 | ||
| 204 | static void aq_nic_polling_timer_cb(struct timer_list *t) | 194 | static void aq_nic_polling_timer_cb(struct timer_list *t) |
| @@ -222,7 +212,7 @@ static struct net_device *aq_nic_ndev_alloc(void) | |||
| 222 | 212 | ||
| 223 | struct aq_nic_s *aq_nic_alloc_cold(const struct net_device_ops *ndev_ops, | 213 | struct aq_nic_s *aq_nic_alloc_cold(const struct net_device_ops *ndev_ops, |
| 224 | const struct ethtool_ops *et_ops, | 214 | const struct ethtool_ops *et_ops, |
| 225 | struct device *dev, | 215 | struct pci_dev *pdev, |
| 226 | struct aq_pci_func_s *aq_pci_func, | 216 | struct aq_pci_func_s *aq_pci_func, |
| 227 | unsigned int port, | 217 | unsigned int port, |
| 228 | const struct aq_hw_ops *aq_hw_ops) | 218 | const struct aq_hw_ops *aq_hw_ops) |
| @@ -242,7 +232,7 @@ struct aq_nic_s *aq_nic_alloc_cold(const struct net_device_ops *ndev_ops, | |||
| 242 | ndev->netdev_ops = ndev_ops; | 232 | ndev->netdev_ops = ndev_ops; |
| 243 | ndev->ethtool_ops = et_ops; | 233 | ndev->ethtool_ops = et_ops; |
| 244 | 234 | ||
| 245 | SET_NETDEV_DEV(ndev, dev); | 235 | SET_NETDEV_DEV(ndev, &pdev->dev); |
| 246 | 236 | ||
| 247 | ndev->if_port = port; | 237 | ndev->if_port = port; |
| 248 | self->ndev = ndev; | 238 | self->ndev = ndev; |
| @@ -254,7 +244,8 @@ struct aq_nic_s *aq_nic_alloc_cold(const struct net_device_ops *ndev_ops, | |||
| 254 | 244 | ||
| 255 | self->aq_hw = self->aq_hw_ops.create(aq_pci_func, self->port, | 245 | self->aq_hw = self->aq_hw_ops.create(aq_pci_func, self->port, |
| 256 | &self->aq_hw_ops); | 246 | &self->aq_hw_ops); |
| 257 | err = self->aq_hw_ops.get_hw_caps(self->aq_hw, &self->aq_hw_caps); | 247 | err = self->aq_hw_ops.get_hw_caps(self->aq_hw, &self->aq_hw_caps, |
| 248 | pdev->device, pdev->subsystem_device); | ||
| 258 | if (err < 0) | 249 | if (err < 0) |
| 259 | goto err_exit; | 250 | goto err_exit; |
| 260 | 251 | ||
| @@ -749,16 +740,40 @@ int aq_nic_get_regs_count(struct aq_nic_s *self) | |||
| 749 | 740 | ||
| 750 | void aq_nic_get_stats(struct aq_nic_s *self, u64 *data) | 741 | void aq_nic_get_stats(struct aq_nic_s *self, u64 *data) |
| 751 | { | 742 | { |
| 752 | struct aq_vec_s *aq_vec = NULL; | ||
| 753 | unsigned int i = 0U; | 743 | unsigned int i = 0U; |
| 754 | unsigned int count = 0U; | 744 | unsigned int count = 0U; |
| 755 | int err = 0; | 745 | struct aq_vec_s *aq_vec = NULL; |
| 746 | struct aq_stats_s *stats = self->aq_hw_ops.hw_get_hw_stats(self->aq_hw); | ||
| 756 | 747 | ||
| 757 | err = self->aq_hw_ops.hw_get_hw_stats(self->aq_hw, data, &count); | 748 | if (!stats) |
| 758 | if (err < 0) | ||
| 759 | goto err_exit; | 749 | goto err_exit; |
| 760 | 750 | ||
| 761 | data += count; | 751 | data[i] = stats->uprc + stats->mprc + stats->bprc; |
| 752 | data[++i] = stats->uprc; | ||
| 753 | data[++i] = stats->mprc; | ||
| 754 | data[++i] = stats->bprc; | ||
| 755 | data[++i] = stats->erpt; | ||
| 756 | data[++i] = stats->uptc + stats->mptc + stats->bptc; | ||
| 757 | data[++i] = stats->uptc; | ||
| 758 | data[++i] = stats->mptc; | ||
| 759 | data[++i] = stats->bptc; | ||
| 760 | data[++i] = stats->ubrc; | ||
| 761 | data[++i] = stats->ubtc; | ||
| 762 | data[++i] = stats->mbrc; | ||
| 763 | data[++i] = stats->mbtc; | ||
| 764 | data[++i] = stats->bbrc; | ||
| 765 | data[++i] = stats->bbtc; | ||
| 766 | data[++i] = stats->ubrc + stats->mbrc + stats->bbrc; | ||
| 767 | data[++i] = stats->ubtc + stats->mbtc + stats->bbtc; | ||
| 768 | data[++i] = stats->dma_pkt_rc; | ||
| 769 | data[++i] = stats->dma_pkt_tc; | ||
| 770 | data[++i] = stats->dma_oct_rc; | ||
| 771 | data[++i] = stats->dma_oct_tc; | ||
| 772 | data[++i] = stats->dpc; | ||
| 773 | |||
| 774 | i++; | ||
| 775 | |||
| 776 | data += i; | ||
| 762 | count = 0U; | 777 | count = 0U; |
| 763 | 778 | ||
| 764 | for (i = 0U, aq_vec = self->aq_vec[0]; | 779 | for (i = 0U, aq_vec = self->aq_vec[0]; |
| @@ -768,7 +783,20 @@ void aq_nic_get_stats(struct aq_nic_s *self, u64 *data) | |||
| 768 | } | 783 | } |
| 769 | 784 | ||
| 770 | err_exit:; | 785 | err_exit:; |
| 771 | (void)err; | 786 | } |
| 787 | |||
| 788 | static void aq_nic_update_ndev_stats(struct aq_nic_s *self) | ||
| 789 | { | ||
| 790 | struct net_device *ndev = self->ndev; | ||
| 791 | struct aq_stats_s *stats = self->aq_hw_ops.hw_get_hw_stats(self->aq_hw); | ||
| 792 | |||
| 793 | ndev->stats.rx_packets = stats->uprc + stats->mprc + stats->bprc; | ||
| 794 | ndev->stats.rx_bytes = stats->ubrc + stats->mbrc + stats->bbrc; | ||
| 795 | ndev->stats.rx_errors = stats->erpr; | ||
| 796 | ndev->stats.tx_packets = stats->uptc + stats->mptc + stats->bptc; | ||
| 797 | ndev->stats.tx_bytes = stats->ubtc + stats->mbtc + stats->bbtc; | ||
| 798 | ndev->stats.tx_errors = stats->erpt; | ||
| 799 | ndev->stats.multicast = stats->mprc; | ||
| 772 | } | 800 | } |
| 773 | 801 | ||
| 774 | void aq_nic_get_link_ksettings(struct aq_nic_s *self, | 802 | void aq_nic_get_link_ksettings(struct aq_nic_s *self, |
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.h b/drivers/net/ethernet/aquantia/atlantic/aq_nic.h index 4309983acdd6..3c9f8db03d5f 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.h +++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.h | |||
| @@ -71,7 +71,7 @@ struct aq_nic_cfg_s { | |||
| 71 | 71 | ||
| 72 | struct aq_nic_s *aq_nic_alloc_cold(const struct net_device_ops *ndev_ops, | 72 | struct aq_nic_s *aq_nic_alloc_cold(const struct net_device_ops *ndev_ops, |
| 73 | const struct ethtool_ops *et_ops, | 73 | const struct ethtool_ops *et_ops, |
| 74 | struct device *dev, | 74 | struct pci_dev *pdev, |
| 75 | struct aq_pci_func_s *aq_pci_func, | 75 | struct aq_pci_func_s *aq_pci_func, |
| 76 | unsigned int port, | 76 | unsigned int port, |
| 77 | const struct aq_hw_ops *aq_hw_ops); | 77 | const struct aq_hw_ops *aq_hw_ops); |
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c b/drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c index cadaa646c89f..58c29d04b186 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c +++ b/drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c | |||
| @@ -51,7 +51,8 @@ struct aq_pci_func_s *aq_pci_func_alloc(struct aq_hw_ops *aq_hw_ops, | |||
| 51 | pci_set_drvdata(pdev, self); | 51 | pci_set_drvdata(pdev, self); |
| 52 | self->pdev = pdev; | 52 | self->pdev = pdev; |
| 53 | 53 | ||
| 54 | err = aq_hw_ops->get_hw_caps(NULL, &self->aq_hw_caps); | 54 | err = aq_hw_ops->get_hw_caps(NULL, &self->aq_hw_caps, pdev->device, |
| 55 | pdev->subsystem_device); | ||
| 55 | if (err < 0) | 56 | if (err < 0) |
| 56 | goto err_exit; | 57 | goto err_exit; |
| 57 | 58 | ||
| @@ -59,7 +60,7 @@ struct aq_pci_func_s *aq_pci_func_alloc(struct aq_hw_ops *aq_hw_ops, | |||
| 59 | 60 | ||
| 60 | for (port = 0; port < self->ports; ++port) { | 61 | for (port = 0; port < self->ports; ++port) { |
| 61 | struct aq_nic_s *aq_nic = aq_nic_alloc_cold(ndev_ops, eth_ops, | 62 | struct aq_nic_s *aq_nic = aq_nic_alloc_cold(ndev_ops, eth_ops, |
| 62 | &pdev->dev, self, | 63 | pdev, self, |
| 63 | port, aq_hw_ops); | 64 | port, aq_hw_ops); |
| 64 | 65 | ||
| 65 | if (!aq_nic) { | 66 | if (!aq_nic) { |
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c index 07b3c49a16a4..f18dce14c93c 100644 --- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c +++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c | |||
| @@ -18,9 +18,20 @@ | |||
| 18 | #include "hw_atl_a0_internal.h" | 18 | #include "hw_atl_a0_internal.h" |
| 19 | 19 | ||
| 20 | static int hw_atl_a0_get_hw_caps(struct aq_hw_s *self, | 20 | static int hw_atl_a0_get_hw_caps(struct aq_hw_s *self, |
| 21 | struct aq_hw_caps_s *aq_hw_caps) | 21 | struct aq_hw_caps_s *aq_hw_caps, |
| 22 | unsigned short device, | ||
| 23 | unsigned short subsystem_device) | ||
| 22 | { | 24 | { |
| 23 | memcpy(aq_hw_caps, &hw_atl_a0_hw_caps_, sizeof(*aq_hw_caps)); | 25 | memcpy(aq_hw_caps, &hw_atl_a0_hw_caps_, sizeof(*aq_hw_caps)); |
| 26 | |||
| 27 | if (device == HW_ATL_DEVICE_ID_D108 && subsystem_device == 0x0001) | ||
| 28 | aq_hw_caps->link_speed_msk &= ~HW_ATL_A0_RATE_10G; | ||
| 29 | |||
| 30 | if (device == HW_ATL_DEVICE_ID_D109 && subsystem_device == 0x0001) { | ||
| 31 | aq_hw_caps->link_speed_msk &= ~HW_ATL_A0_RATE_10G; | ||
| 32 | aq_hw_caps->link_speed_msk &= ~HW_ATL_A0_RATE_5G; | ||
| 33 | } | ||
| 34 | |||
| 24 | return 0; | 35 | return 0; |
| 25 | } | 36 | } |
| 26 | 37 | ||
| @@ -333,6 +344,10 @@ static int hw_atl_a0_hw_init(struct aq_hw_s *self, | |||
| 333 | hw_atl_a0_hw_rss_set(self, &aq_nic_cfg->aq_rss); | 344 | hw_atl_a0_hw_rss_set(self, &aq_nic_cfg->aq_rss); |
| 334 | hw_atl_a0_hw_rss_hash_set(self, &aq_nic_cfg->aq_rss); | 345 | hw_atl_a0_hw_rss_hash_set(self, &aq_nic_cfg->aq_rss); |
| 335 | 346 | ||
| 347 | /* Reset link status and read out initial hardware counters */ | ||
| 348 | self->aq_link_status.mbps = 0; | ||
| 349 | hw_atl_utils_update_stats(self); | ||
| 350 | |||
| 336 | err = aq_hw_err_from_flags(self); | 351 | err = aq_hw_err_from_flags(self); |
| 337 | if (err < 0) | 352 | if (err < 0) |
| 338 | goto err_exit; | 353 | goto err_exit; |
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c index ec68c20efcbd..e4a22ce7bf09 100644 --- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c +++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c | |||
| @@ -16,11 +16,23 @@ | |||
| 16 | #include "hw_atl_utils.h" | 16 | #include "hw_atl_utils.h" |
| 17 | #include "hw_atl_llh.h" | 17 | #include "hw_atl_llh.h" |
| 18 | #include "hw_atl_b0_internal.h" | 18 | #include "hw_atl_b0_internal.h" |
| 19 | #include "hw_atl_llh_internal.h" | ||
| 19 | 20 | ||
| 20 | static int hw_atl_b0_get_hw_caps(struct aq_hw_s *self, | 21 | static int hw_atl_b0_get_hw_caps(struct aq_hw_s *self, |
| 21 | struct aq_hw_caps_s *aq_hw_caps) | 22 | struct aq_hw_caps_s *aq_hw_caps, |
| 23 | unsigned short device, | ||
| 24 | unsigned short subsystem_device) | ||
| 22 | { | 25 | { |
| 23 | memcpy(aq_hw_caps, &hw_atl_b0_hw_caps_, sizeof(*aq_hw_caps)); | 26 | memcpy(aq_hw_caps, &hw_atl_b0_hw_caps_, sizeof(*aq_hw_caps)); |
| 27 | |||
| 28 | if (device == HW_ATL_DEVICE_ID_D108 && subsystem_device == 0x0001) | ||
| 29 | aq_hw_caps->link_speed_msk &= ~HW_ATL_B0_RATE_10G; | ||
| 30 | |||
| 31 | if (device == HW_ATL_DEVICE_ID_D109 && subsystem_device == 0x0001) { | ||
| 32 | aq_hw_caps->link_speed_msk &= ~HW_ATL_B0_RATE_10G; | ||
| 33 | aq_hw_caps->link_speed_msk &= ~HW_ATL_B0_RATE_5G; | ||
| 34 | } | ||
| 35 | |||
| 24 | return 0; | 36 | return 0; |
| 25 | } | 37 | } |
| 26 | 38 | ||
| @@ -357,6 +369,7 @@ static int hw_atl_b0_hw_init(struct aq_hw_s *self, | |||
| 357 | }; | 369 | }; |
| 358 | 370 | ||
| 359 | int err = 0; | 371 | int err = 0; |
| 372 | u32 val; | ||
| 360 | 373 | ||
| 361 | self->aq_nic_cfg = aq_nic_cfg; | 374 | self->aq_nic_cfg = aq_nic_cfg; |
| 362 | 375 | ||
| @@ -374,6 +387,20 @@ static int hw_atl_b0_hw_init(struct aq_hw_s *self, | |||
| 374 | hw_atl_b0_hw_rss_set(self, &aq_nic_cfg->aq_rss); | 387 | hw_atl_b0_hw_rss_set(self, &aq_nic_cfg->aq_rss); |
| 375 | hw_atl_b0_hw_rss_hash_set(self, &aq_nic_cfg->aq_rss); | 388 | hw_atl_b0_hw_rss_hash_set(self, &aq_nic_cfg->aq_rss); |
| 376 | 389 | ||
| 390 | /* Force limit MRRS on RDM/TDM to 2K */ | ||
| 391 | val = aq_hw_read_reg(self, pci_reg_control6_adr); | ||
| 392 | aq_hw_write_reg(self, pci_reg_control6_adr, (val & ~0x707) | 0x404); | ||
| 393 | |||
| 394 | /* TX DMA total request limit. B0 hardware is not capable to | ||
| 395 | * handle more than (8K-MRRS) incoming DMA data. | ||
| 396 | * Value 24 in 256byte units | ||
| 397 | */ | ||
| 398 | aq_hw_write_reg(self, tx_dma_total_req_limit_adr, 24); | ||
| 399 | |||
| 400 | /* Reset link status and read out initial hardware counters */ | ||
| 401 | self->aq_link_status.mbps = 0; | ||
| 402 | hw_atl_utils_update_stats(self); | ||
| 403 | |||
| 377 | err = aq_hw_err_from_flags(self); | 404 | err = aq_hw_err_from_flags(self); |
| 378 | if (err < 0) | 405 | if (err < 0) |
| 379 | goto err_exit; | 406 | goto err_exit; |
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh_internal.h b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh_internal.h index 5527fc0e5942..93450ec930e8 100644 --- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh_internal.h +++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh_internal.h | |||
| @@ -2343,6 +2343,9 @@ | |||
| 2343 | #define tx_dma_desc_base_addrmsw_adr(descriptor) \ | 2343 | #define tx_dma_desc_base_addrmsw_adr(descriptor) \ |
| 2344 | (0x00007c04u + (descriptor) * 0x40) | 2344 | (0x00007c04u + (descriptor) * 0x40) |
| 2345 | 2345 | ||
| 2346 | /* tx dma total request limit */ | ||
| 2347 | #define tx_dma_total_req_limit_adr 0x00007b20u | ||
| 2348 | |||
| 2346 | /* tx interrupt moderation control register definitions | 2349 | /* tx interrupt moderation control register definitions |
| 2347 | * Preprocessor definitions for TX Interrupt Moderation Control Register | 2350 | * Preprocessor definitions for TX Interrupt Moderation Control Register |
| 2348 | * Base Address: 0x00008980 | 2351 | * Base Address: 0x00008980 |
| @@ -2369,6 +2372,9 @@ | |||
| 2369 | /* default value of bitfield reg_res_dsbl */ | 2372 | /* default value of bitfield reg_res_dsbl */ |
| 2370 | #define pci_reg_res_dsbl_default 0x1 | 2373 | #define pci_reg_res_dsbl_default 0x1 |
| 2371 | 2374 | ||
| 2375 | /* PCI core control register */ | ||
| 2376 | #define pci_reg_control6_adr 0x1014u | ||
| 2377 | |||
| 2372 | /* global microprocessor scratch pad definitions */ | 2378 | /* global microprocessor scratch pad definitions */ |
| 2373 | #define glb_cpu_scratch_scp_adr(scratch_scp) (0x00000300u + (scratch_scp) * 0x4) | 2379 | #define glb_cpu_scratch_scp_adr(scratch_scp) (0x00000300u + (scratch_scp) * 0x4) |
| 2374 | 2380 | ||
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c index 1fe016fc4bc7..f2ce12ed4218 100644 --- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c +++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c | |||
| @@ -503,73 +503,43 @@ int hw_atl_utils_update_stats(struct aq_hw_s *self) | |||
| 503 | struct hw_atl_s *hw_self = PHAL_ATLANTIC; | 503 | struct hw_atl_s *hw_self = PHAL_ATLANTIC; |
| 504 | struct hw_aq_atl_utils_mbox mbox; | 504 | struct hw_aq_atl_utils_mbox mbox; |
| 505 | 505 | ||
| 506 | if (!self->aq_link_status.mbps) | ||
| 507 | return 0; | ||
| 508 | |||
| 509 | hw_atl_utils_mpi_read_stats(self, &mbox); | 506 | hw_atl_utils_mpi_read_stats(self, &mbox); |
| 510 | 507 | ||
| 511 | #define AQ_SDELTA(_N_) (hw_self->curr_stats._N_ += \ | 508 | #define AQ_SDELTA(_N_) (hw_self->curr_stats._N_ += \ |
| 512 | mbox.stats._N_ - hw_self->last_stats._N_) | 509 | mbox.stats._N_ - hw_self->last_stats._N_) |
| 513 | 510 | if (self->aq_link_status.mbps) { | |
| 514 | AQ_SDELTA(uprc); | 511 | AQ_SDELTA(uprc); |
| 515 | AQ_SDELTA(mprc); | 512 | AQ_SDELTA(mprc); |
| 516 | AQ_SDELTA(bprc); | 513 | AQ_SDELTA(bprc); |
| 517 | AQ_SDELTA(erpt); | 514 | AQ_SDELTA(erpt); |
| 518 | 515 | ||
| 519 | AQ_SDELTA(uptc); | 516 | AQ_SDELTA(uptc); |
| 520 | AQ_SDELTA(mptc); | 517 | AQ_SDELTA(mptc); |
| 521 | AQ_SDELTA(bptc); | 518 | AQ_SDELTA(bptc); |
| 522 | AQ_SDELTA(erpr); | 519 | AQ_SDELTA(erpr); |
| 523 | 520 | ||
| 524 | AQ_SDELTA(ubrc); | 521 | AQ_SDELTA(ubrc); |
| 525 | AQ_SDELTA(ubtc); | 522 | AQ_SDELTA(ubtc); |
| 526 | AQ_SDELTA(mbrc); | 523 | AQ_SDELTA(mbrc); |
| 527 | AQ_SDELTA(mbtc); | 524 | AQ_SDELTA(mbtc); |
| 528 | AQ_SDELTA(bbrc); | 525 | AQ_SDELTA(bbrc); |
| 529 | AQ_SDELTA(bbtc); | 526 | AQ_SDELTA(bbtc); |
| 530 | AQ_SDELTA(dpc); | 527 | AQ_SDELTA(dpc); |
| 531 | 528 | } | |
| 532 | #undef AQ_SDELTA | 529 | #undef AQ_SDELTA |
| 530 | hw_self->curr_stats.dma_pkt_rc = stats_rx_dma_good_pkt_counterlsw_get(self); | ||
| 531 | hw_self->curr_stats.dma_pkt_tc = stats_tx_dma_good_pkt_counterlsw_get(self); | ||
| 532 | hw_self->curr_stats.dma_oct_rc = stats_rx_dma_good_octet_counterlsw_get(self); | ||
| 533 | hw_self->curr_stats.dma_oct_tc = stats_tx_dma_good_octet_counterlsw_get(self); | ||
| 533 | 534 | ||
| 534 | memcpy(&hw_self->last_stats, &mbox.stats, sizeof(mbox.stats)); | 535 | memcpy(&hw_self->last_stats, &mbox.stats, sizeof(mbox.stats)); |
| 535 | 536 | ||
| 536 | return 0; | 537 | return 0; |
| 537 | } | 538 | } |
| 538 | 539 | ||
| 539 | int hw_atl_utils_get_hw_stats(struct aq_hw_s *self, | 540 | struct aq_stats_s *hw_atl_utils_get_hw_stats(struct aq_hw_s *self) |
| 540 | u64 *data, unsigned int *p_count) | ||
| 541 | { | 541 | { |
| 542 | struct hw_atl_s *hw_self = PHAL_ATLANTIC; | 542 | return &PHAL_ATLANTIC->curr_stats; |
| 543 | struct hw_atl_stats_s *stats = &hw_self->curr_stats; | ||
| 544 | int i = 0; | ||
| 545 | |||
| 546 | data[i] = stats->uprc + stats->mprc + stats->bprc; | ||
| 547 | data[++i] = stats->uprc; | ||
| 548 | data[++i] = stats->mprc; | ||
| 549 | data[++i] = stats->bprc; | ||
| 550 | data[++i] = stats->erpt; | ||
| 551 | data[++i] = stats->uptc + stats->mptc + stats->bptc; | ||
| 552 | data[++i] = stats->uptc; | ||
| 553 | data[++i] = stats->mptc; | ||
| 554 | data[++i] = stats->bptc; | ||
| 555 | data[++i] = stats->ubrc; | ||
| 556 | data[++i] = stats->ubtc; | ||
| 557 | data[++i] = stats->mbrc; | ||
| 558 | data[++i] = stats->mbtc; | ||
| 559 | data[++i] = stats->bbrc; | ||
| 560 | data[++i] = stats->bbtc; | ||
| 561 | data[++i] = stats->ubrc + stats->mbrc + stats->bbrc; | ||
| 562 | data[++i] = stats->ubtc + stats->mbtc + stats->bbtc; | ||
| 563 | data[++i] = stats_rx_dma_good_pkt_counterlsw_get(self); | ||
| 564 | data[++i] = stats_tx_dma_good_pkt_counterlsw_get(self); | ||
| 565 | data[++i] = stats_rx_dma_good_octet_counterlsw_get(self); | ||
| 566 | data[++i] = stats_tx_dma_good_octet_counterlsw_get(self); | ||
| 567 | data[++i] = stats->dpc; | ||
| 568 | |||
| 569 | if (p_count) | ||
| 570 | *p_count = ++i; | ||
| 571 | |||
| 572 | return 0; | ||
| 573 | } | 543 | } |
| 574 | 544 | ||
| 575 | static const u32 hw_atl_utils_hw_mac_regs[] = { | 545 | static const u32 hw_atl_utils_hw_mac_regs[] = { |
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h index c99cc690e425..21aeca6908d3 100644 --- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h +++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h | |||
| @@ -129,7 +129,7 @@ struct __packed hw_aq_atl_utils_mbox { | |||
| 129 | struct __packed hw_atl_s { | 129 | struct __packed hw_atl_s { |
| 130 | struct aq_hw_s base; | 130 | struct aq_hw_s base; |
| 131 | struct hw_atl_stats_s last_stats; | 131 | struct hw_atl_stats_s last_stats; |
| 132 | struct hw_atl_stats_s curr_stats; | 132 | struct aq_stats_s curr_stats; |
| 133 | u64 speed; | 133 | u64 speed; |
| 134 | unsigned int chip_features; | 134 | unsigned int chip_features; |
| 135 | u32 fw_ver_actual; | 135 | u32 fw_ver_actual; |
| @@ -207,8 +207,6 @@ int hw_atl_utils_get_fw_version(struct aq_hw_s *self, u32 *fw_version); | |||
| 207 | 207 | ||
| 208 | int hw_atl_utils_update_stats(struct aq_hw_s *self); | 208 | int hw_atl_utils_update_stats(struct aq_hw_s *self); |
| 209 | 209 | ||
| 210 | int hw_atl_utils_get_hw_stats(struct aq_hw_s *self, | 210 | struct aq_stats_s *hw_atl_utils_get_hw_stats(struct aq_hw_s *self); |
| 211 | u64 *data, | ||
| 212 | unsigned int *p_count); | ||
| 213 | 211 | ||
| 214 | #endif /* HW_ATL_UTILS_H */ | 212 | #endif /* HW_ATL_UTILS_H */ |
diff --git a/drivers/net/ethernet/aquantia/atlantic/ver.h b/drivers/net/ethernet/aquantia/atlantic/ver.h index 0de858d215c2..9009f2651e70 100644 --- a/drivers/net/ethernet/aquantia/atlantic/ver.h +++ b/drivers/net/ethernet/aquantia/atlantic/ver.h | |||
| @@ -11,8 +11,10 @@ | |||
| 11 | #define VER_H | 11 | #define VER_H |
| 12 | 12 | ||
| 13 | #define NIC_MAJOR_DRIVER_VERSION 1 | 13 | #define NIC_MAJOR_DRIVER_VERSION 1 |
| 14 | #define NIC_MINOR_DRIVER_VERSION 5 | 14 | #define NIC_MINOR_DRIVER_VERSION 6 |
| 15 | #define NIC_BUILD_DRIVER_VERSION 345 | 15 | #define NIC_BUILD_DRIVER_VERSION 13 |
| 16 | #define NIC_REVISION_DRIVER_VERSION 0 | 16 | #define NIC_REVISION_DRIVER_VERSION 0 |
| 17 | 17 | ||
| 18 | #define AQ_CFG_DRV_VERSION_SUFFIX "-kern" | ||
| 19 | |||
| 18 | #endif /* VER_H */ | 20 | #endif /* VER_H */ |
diff --git a/drivers/net/ethernet/arc/emac.h b/drivers/net/ethernet/arc/emac.h index 3c63b16d485f..d9efbc8d783b 100644 --- a/drivers/net/ethernet/arc/emac.h +++ b/drivers/net/ethernet/arc/emac.h | |||
| @@ -159,6 +159,8 @@ struct arc_emac_priv { | |||
| 159 | unsigned int link; | 159 | unsigned int link; |
| 160 | unsigned int duplex; | 160 | unsigned int duplex; |
| 161 | unsigned int speed; | 161 | unsigned int speed; |
| 162 | |||
| 163 | unsigned int rx_missed_errors; | ||
| 162 | }; | 164 | }; |
| 163 | 165 | ||
| 164 | /** | 166 | /** |
diff --git a/drivers/net/ethernet/arc/emac_main.c b/drivers/net/ethernet/arc/emac_main.c index 3241af1ce718..bd277b0dc615 100644 --- a/drivers/net/ethernet/arc/emac_main.c +++ b/drivers/net/ethernet/arc/emac_main.c | |||
| @@ -26,6 +26,8 @@ | |||
| 26 | 26 | ||
| 27 | #include "emac.h" | 27 | #include "emac.h" |
| 28 | 28 | ||
| 29 | static void arc_emac_restart(struct net_device *ndev); | ||
| 30 | |||
| 29 | /** | 31 | /** |
| 30 | * arc_emac_tx_avail - Return the number of available slots in the tx ring. | 32 | * arc_emac_tx_avail - Return the number of available slots in the tx ring. |
| 31 | * @priv: Pointer to ARC EMAC private data structure. | 33 | * @priv: Pointer to ARC EMAC private data structure. |
| @@ -210,39 +212,48 @@ static int arc_emac_rx(struct net_device *ndev, int budget) | |||
| 210 | continue; | 212 | continue; |
| 211 | } | 213 | } |
| 212 | 214 | ||
| 213 | pktlen = info & LEN_MASK; | 215 | /* Prepare the BD for next cycle. netif_receive_skb() |
| 214 | stats->rx_packets++; | 216 | * only if new skb was allocated and mapped to avoid holes |
| 215 | stats->rx_bytes += pktlen; | 217 | * in the RX fifo. |
| 216 | skb = rx_buff->skb; | 218 | */ |
| 217 | skb_put(skb, pktlen); | 219 | skb = netdev_alloc_skb_ip_align(ndev, EMAC_BUFFER_SIZE); |
| 218 | skb->dev = ndev; | 220 | if (unlikely(!skb)) { |
| 219 | skb->protocol = eth_type_trans(skb, ndev); | 221 | if (net_ratelimit()) |
| 220 | 222 | netdev_err(ndev, "cannot allocate skb\n"); | |
| 221 | dma_unmap_single(&ndev->dev, dma_unmap_addr(rx_buff, addr), | 223 | /* Return ownership to EMAC */ |
| 222 | dma_unmap_len(rx_buff, len), DMA_FROM_DEVICE); | 224 | rxbd->info = cpu_to_le32(FOR_EMAC | EMAC_BUFFER_SIZE); |
| 223 | |||
| 224 | /* Prepare the BD for next cycle */ | ||
| 225 | rx_buff->skb = netdev_alloc_skb_ip_align(ndev, | ||
| 226 | EMAC_BUFFER_SIZE); | ||
| 227 | if (unlikely(!rx_buff->skb)) { | ||
| 228 | stats->rx_errors++; | 225 | stats->rx_errors++; |
| 229 | /* Because receive_skb is below, increment rx_dropped */ | ||
| 230 | stats->rx_dropped++; | 226 | stats->rx_dropped++; |
| 231 | continue; | 227 | continue; |
| 232 | } | 228 | } |
| 233 | 229 | ||
| 234 | /* receive_skb only if new skb was allocated to avoid holes */ | 230 | addr = dma_map_single(&ndev->dev, (void *)skb->data, |
| 235 | netif_receive_skb(skb); | ||
| 236 | |||
| 237 | addr = dma_map_single(&ndev->dev, (void *)rx_buff->skb->data, | ||
| 238 | EMAC_BUFFER_SIZE, DMA_FROM_DEVICE); | 231 | EMAC_BUFFER_SIZE, DMA_FROM_DEVICE); |
| 239 | if (dma_mapping_error(&ndev->dev, addr)) { | 232 | if (dma_mapping_error(&ndev->dev, addr)) { |
| 240 | if (net_ratelimit()) | 233 | if (net_ratelimit()) |
| 241 | netdev_err(ndev, "cannot dma map\n"); | 234 | netdev_err(ndev, "cannot map dma buffer\n"); |
| 242 | dev_kfree_skb(rx_buff->skb); | 235 | dev_kfree_skb(skb); |
| 236 | /* Return ownership to EMAC */ | ||
| 237 | rxbd->info = cpu_to_le32(FOR_EMAC | EMAC_BUFFER_SIZE); | ||
| 243 | stats->rx_errors++; | 238 | stats->rx_errors++; |
| 239 | stats->rx_dropped++; | ||
| 244 | continue; | 240 | continue; |
| 245 | } | 241 | } |
| 242 | |||
| 243 | /* unmap previosly mapped skb */ | ||
| 244 | dma_unmap_single(&ndev->dev, dma_unmap_addr(rx_buff, addr), | ||
| 245 | dma_unmap_len(rx_buff, len), DMA_FROM_DEVICE); | ||
| 246 | |||
| 247 | pktlen = info & LEN_MASK; | ||
| 248 | stats->rx_packets++; | ||
| 249 | stats->rx_bytes += pktlen; | ||
| 250 | skb_put(rx_buff->skb, pktlen); | ||
| 251 | rx_buff->skb->dev = ndev; | ||
| 252 | rx_buff->skb->protocol = eth_type_trans(rx_buff->skb, ndev); | ||
| 253 | |||
| 254 | netif_receive_skb(rx_buff->skb); | ||
| 255 | |||
| 256 | rx_buff->skb = skb; | ||
| 246 | dma_unmap_addr_set(rx_buff, addr, addr); | 257 | dma_unmap_addr_set(rx_buff, addr, addr); |
| 247 | dma_unmap_len_set(rx_buff, len, EMAC_BUFFER_SIZE); | 258 | dma_unmap_len_set(rx_buff, len, EMAC_BUFFER_SIZE); |
| 248 | 259 | ||
| @@ -259,6 +270,53 @@ static int arc_emac_rx(struct net_device *ndev, int budget) | |||
| 259 | } | 270 | } |
| 260 | 271 | ||
| 261 | /** | 272 | /** |
| 273 | * arc_emac_rx_miss_handle - handle R_MISS register | ||
| 274 | * @ndev: Pointer to the net_device structure. | ||
| 275 | */ | ||
| 276 | static void arc_emac_rx_miss_handle(struct net_device *ndev) | ||
| 277 | { | ||
| 278 | struct arc_emac_priv *priv = netdev_priv(ndev); | ||
| 279 | struct net_device_stats *stats = &ndev->stats; | ||
| 280 | unsigned int miss; | ||
| 281 | |||
| 282 | miss = arc_reg_get(priv, R_MISS); | ||
| 283 | if (miss) { | ||
| 284 | stats->rx_errors += miss; | ||
| 285 | stats->rx_missed_errors += miss; | ||
| 286 | priv->rx_missed_errors += miss; | ||
| 287 | } | ||
| 288 | } | ||
| 289 | |||
| 290 | /** | ||
| 291 | * arc_emac_rx_stall_check - check RX stall | ||
| 292 | * @ndev: Pointer to the net_device structure. | ||
| 293 | * @budget: How many BDs requested to process on 1 call. | ||
| 294 | * @work_done: How many BDs processed | ||
| 295 | * | ||
| 296 | * Under certain conditions EMAC stop reception of incoming packets and | ||
| 297 | * continuously increment R_MISS register instead of saving data into | ||
| 298 | * provided buffer. This function detect that condition and restart | ||
| 299 | * EMAC. | ||
| 300 | */ | ||
| 301 | static void arc_emac_rx_stall_check(struct net_device *ndev, | ||
| 302 | int budget, unsigned int work_done) | ||
| 303 | { | ||
| 304 | struct arc_emac_priv *priv = netdev_priv(ndev); | ||
| 305 | struct arc_emac_bd *rxbd; | ||
| 306 | |||
| 307 | if (work_done) | ||
| 308 | priv->rx_missed_errors = 0; | ||
| 309 | |||
| 310 | if (priv->rx_missed_errors && budget) { | ||
| 311 | rxbd = &priv->rxbd[priv->last_rx_bd]; | ||
| 312 | if (le32_to_cpu(rxbd->info) & FOR_EMAC) { | ||
| 313 | arc_emac_restart(ndev); | ||
| 314 | priv->rx_missed_errors = 0; | ||
| 315 | } | ||
| 316 | } | ||
| 317 | } | ||
| 318 | |||
| 319 | /** | ||
| 262 | * arc_emac_poll - NAPI poll handler. | 320 | * arc_emac_poll - NAPI poll handler. |
| 263 | * @napi: Pointer to napi_struct structure. | 321 | * @napi: Pointer to napi_struct structure. |
| 264 | * @budget: How many BDs to process on 1 call. | 322 | * @budget: How many BDs to process on 1 call. |
| @@ -272,6 +330,7 @@ static int arc_emac_poll(struct napi_struct *napi, int budget) | |||
| 272 | unsigned int work_done; | 330 | unsigned int work_done; |
| 273 | 331 | ||
| 274 | arc_emac_tx_clean(ndev); | 332 | arc_emac_tx_clean(ndev); |
| 333 | arc_emac_rx_miss_handle(ndev); | ||
| 275 | 334 | ||
| 276 | work_done = arc_emac_rx(ndev, budget); | 335 | work_done = arc_emac_rx(ndev, budget); |
| 277 | if (work_done < budget) { | 336 | if (work_done < budget) { |
| @@ -279,6 +338,8 @@ static int arc_emac_poll(struct napi_struct *napi, int budget) | |||
| 279 | arc_reg_or(priv, R_ENABLE, RXINT_MASK | TXINT_MASK); | 338 | arc_reg_or(priv, R_ENABLE, RXINT_MASK | TXINT_MASK); |
| 280 | } | 339 | } |
| 281 | 340 | ||
| 341 | arc_emac_rx_stall_check(ndev, budget, work_done); | ||
| 342 | |||
| 282 | return work_done; | 343 | return work_done; |
| 283 | } | 344 | } |
| 284 | 345 | ||
| @@ -320,6 +381,8 @@ static irqreturn_t arc_emac_intr(int irq, void *dev_instance) | |||
| 320 | if (status & MSER_MASK) { | 381 | if (status & MSER_MASK) { |
| 321 | stats->rx_missed_errors += 0x100; | 382 | stats->rx_missed_errors += 0x100; |
| 322 | stats->rx_errors += 0x100; | 383 | stats->rx_errors += 0x100; |
| 384 | priv->rx_missed_errors += 0x100; | ||
| 385 | napi_schedule(&priv->napi); | ||
| 323 | } | 386 | } |
| 324 | 387 | ||
| 325 | if (status & RXCR_MASK) { | 388 | if (status & RXCR_MASK) { |
| @@ -732,6 +795,63 @@ static int arc_emac_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) | |||
| 732 | } | 795 | } |
| 733 | 796 | ||
| 734 | 797 | ||
| 798 | /** | ||
| 799 | * arc_emac_restart - Restart EMAC | ||
| 800 | * @ndev: Pointer to net_device structure. | ||
| 801 | * | ||
| 802 | * This function do hardware reset of EMAC in order to restore | ||
| 803 | * network packets reception. | ||
| 804 | */ | ||
| 805 | static void arc_emac_restart(struct net_device *ndev) | ||
| 806 | { | ||
| 807 | struct arc_emac_priv *priv = netdev_priv(ndev); | ||
| 808 | struct net_device_stats *stats = &ndev->stats; | ||
| 809 | int i; | ||
| 810 | |||
| 811 | if (net_ratelimit()) | ||
| 812 | netdev_warn(ndev, "restarting stalled EMAC\n"); | ||
| 813 | |||
| 814 | netif_stop_queue(ndev); | ||
| 815 | |||
| 816 | /* Disable interrupts */ | ||
| 817 | arc_reg_clr(priv, R_ENABLE, RXINT_MASK | TXINT_MASK | ERR_MASK); | ||
| 818 | |||
| 819 | /* Disable EMAC */ | ||
| 820 | arc_reg_clr(priv, R_CTRL, EN_MASK); | ||
| 821 | |||
| 822 | /* Return the sk_buff to system */ | ||
| 823 | arc_free_tx_queue(ndev); | ||
| 824 | |||
| 825 | /* Clean Tx BD's */ | ||
| 826 | priv->txbd_curr = 0; | ||
| 827 | priv->txbd_dirty = 0; | ||
| 828 | memset(priv->txbd, 0, TX_RING_SZ); | ||
| 829 | |||
| 830 | for (i = 0; i < RX_BD_NUM; i++) { | ||
| 831 | struct arc_emac_bd *rxbd = &priv->rxbd[i]; | ||
| 832 | unsigned int info = le32_to_cpu(rxbd->info); | ||
| 833 | |||
| 834 | if (!(info & FOR_EMAC)) { | ||
| 835 | stats->rx_errors++; | ||
| 836 | stats->rx_dropped++; | ||
| 837 | } | ||
| 838 | /* Return ownership to EMAC */ | ||
| 839 | rxbd->info = cpu_to_le32(FOR_EMAC | EMAC_BUFFER_SIZE); | ||
| 840 | } | ||
| 841 | priv->last_rx_bd = 0; | ||
| 842 | |||
| 843 | /* Make sure info is visible to EMAC before enable */ | ||
| 844 | wmb(); | ||
| 845 | |||
| 846 | /* Enable interrupts */ | ||
| 847 | arc_reg_set(priv, R_ENABLE, RXINT_MASK | TXINT_MASK | ERR_MASK); | ||
| 848 | |||
| 849 | /* Enable EMAC */ | ||
| 850 | arc_reg_or(priv, R_CTRL, EN_MASK); | ||
| 851 | |||
| 852 | netif_start_queue(ndev); | ||
| 853 | } | ||
| 854 | |||
| 735 | static const struct net_device_ops arc_emac_netdev_ops = { | 855 | static const struct net_device_ops arc_emac_netdev_ops = { |
| 736 | .ndo_open = arc_emac_open, | 856 | .ndo_open = arc_emac_open, |
| 737 | .ndo_stop = arc_emac_stop, | 857 | .ndo_stop = arc_emac_stop, |
diff --git a/drivers/net/ethernet/arc/emac_rockchip.c b/drivers/net/ethernet/arc/emac_rockchip.c index c6163874e4e7..16f9bee992fe 100644 --- a/drivers/net/ethernet/arc/emac_rockchip.c +++ b/drivers/net/ethernet/arc/emac_rockchip.c | |||
| @@ -199,9 +199,11 @@ static int emac_rockchip_probe(struct platform_device *pdev) | |||
| 199 | 199 | ||
| 200 | /* RMII interface needs always a rate of 50MHz */ | 200 | /* RMII interface needs always a rate of 50MHz */ |
| 201 | err = clk_set_rate(priv->refclk, 50000000); | 201 | err = clk_set_rate(priv->refclk, 50000000); |
| 202 | if (err) | 202 | if (err) { |
| 203 | dev_err(dev, | 203 | dev_err(dev, |
| 204 | "failed to change reference clock rate (%d)\n", err); | 204 | "failed to change reference clock rate (%d)\n", err); |
| 205 | goto out_regulator_disable; | ||
| 206 | } | ||
| 205 | 207 | ||
| 206 | if (priv->soc_data->need_div_macclk) { | 208 | if (priv->soc_data->need_div_macclk) { |
| 207 | priv->macclk = devm_clk_get(dev, "macclk"); | 209 | priv->macclk = devm_clk_get(dev, "macclk"); |
| @@ -230,12 +232,14 @@ static int emac_rockchip_probe(struct platform_device *pdev) | |||
| 230 | err = arc_emac_probe(ndev, interface); | 232 | err = arc_emac_probe(ndev, interface); |
| 231 | if (err) { | 233 | if (err) { |
| 232 | dev_err(dev, "failed to probe arc emac (%d)\n", err); | 234 | dev_err(dev, "failed to probe arc emac (%d)\n", err); |
| 233 | goto out_regulator_disable; | 235 | goto out_clk_disable_macclk; |
| 234 | } | 236 | } |
| 235 | 237 | ||
| 236 | return 0; | 238 | return 0; |
| 239 | |||
| 237 | out_clk_disable_macclk: | 240 | out_clk_disable_macclk: |
| 238 | clk_disable_unprepare(priv->macclk); | 241 | if (priv->soc_data->need_div_macclk) |
| 242 | clk_disable_unprepare(priv->macclk); | ||
| 239 | out_regulator_disable: | 243 | out_regulator_disable: |
| 240 | if (priv->regulator) | 244 | if (priv->regulator) |
| 241 | regulator_disable(priv->regulator); | 245 | regulator_disable(priv->regulator); |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index 4c739d5355d2..8ae269ec17a1 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | |||
| @@ -3030,7 +3030,7 @@ int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode, bool keep_link) | |||
| 3030 | 3030 | ||
| 3031 | del_timer_sync(&bp->timer); | 3031 | del_timer_sync(&bp->timer); |
| 3032 | 3032 | ||
| 3033 | if (IS_PF(bp)) { | 3033 | if (IS_PF(bp) && !BP_NOMCP(bp)) { |
| 3034 | /* Set ALWAYS_ALIVE bit in shmem */ | 3034 | /* Set ALWAYS_ALIVE bit in shmem */ |
| 3035 | bp->fw_drv_pulse_wr_seq |= DRV_PULSE_ALWAYS_ALIVE; | 3035 | bp->fw_drv_pulse_wr_seq |= DRV_PULSE_ALWAYS_ALIVE; |
| 3036 | bnx2x_drv_pulse(bp); | 3036 | bnx2x_drv_pulse(bp); |
| @@ -3116,7 +3116,7 @@ int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode, bool keep_link) | |||
| 3116 | bp->cnic_loaded = false; | 3116 | bp->cnic_loaded = false; |
| 3117 | 3117 | ||
| 3118 | /* Clear driver version indication in shmem */ | 3118 | /* Clear driver version indication in shmem */ |
| 3119 | if (IS_PF(bp)) | 3119 | if (IS_PF(bp) && !BP_NOMCP(bp)) |
| 3120 | bnx2x_update_mng_version(bp); | 3120 | bnx2x_update_mng_version(bp); |
| 3121 | 3121 | ||
| 3122 | /* Check if there are pending parity attentions. If there are - set | 3122 | /* Check if there are pending parity attentions. If there are - set |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 91e2a7560b48..ddd5d3ebd201 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | |||
| @@ -9578,6 +9578,15 @@ static int bnx2x_init_shmem(struct bnx2x *bp) | |||
| 9578 | 9578 | ||
| 9579 | do { | 9579 | do { |
| 9580 | bp->common.shmem_base = REG_RD(bp, MISC_REG_SHARED_MEM_ADDR); | 9580 | bp->common.shmem_base = REG_RD(bp, MISC_REG_SHARED_MEM_ADDR); |
| 9581 | |||
| 9582 | /* If we read all 0xFFs, means we are in PCI error state and | ||
| 9583 | * should bail out to avoid crashes on adapter's FW reads. | ||
| 9584 | */ | ||
| 9585 | if (bp->common.shmem_base == 0xFFFFFFFF) { | ||
| 9586 | bp->flags |= NO_MCP_FLAG; | ||
| 9587 | return -ENODEV; | ||
| 9588 | } | ||
| 9589 | |||
| 9581 | if (bp->common.shmem_base) { | 9590 | if (bp->common.shmem_base) { |
| 9582 | val = SHMEM_RD(bp, validity_map[BP_PORT(bp)]); | 9591 | val = SHMEM_RD(bp, validity_map[BP_PORT(bp)]); |
| 9583 | if (val & SHR_MEM_VALIDITY_MB) | 9592 | if (val & SHR_MEM_VALIDITY_MB) |
| @@ -14320,7 +14329,10 @@ static pci_ers_result_t bnx2x_io_slot_reset(struct pci_dev *pdev) | |||
| 14320 | BNX2X_ERR("IO slot reset --> driver unload\n"); | 14329 | BNX2X_ERR("IO slot reset --> driver unload\n"); |
| 14321 | 14330 | ||
| 14322 | /* MCP should have been reset; Need to wait for validity */ | 14331 | /* MCP should have been reset; Need to wait for validity */ |
| 14323 | bnx2x_init_shmem(bp); | 14332 | if (bnx2x_init_shmem(bp)) { |
| 14333 | rtnl_unlock(); | ||
| 14334 | return PCI_ERS_RESULT_DISCONNECT; | ||
| 14335 | } | ||
| 14324 | 14336 | ||
| 14325 | if (IS_PF(bp) && SHMEM2_HAS(bp, drv_capabilities_flag)) { | 14337 | if (IS_PF(bp) && SHMEM2_HAS(bp, drv_capabilities_flag)) { |
| 14326 | u32 v; | 14338 | u32 v; |
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index de51c2177d03..8995cfefbfcf 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c | |||
| @@ -4,11 +4,13 @@ | |||
| 4 | * Copyright (C) 2001, 2002, 2003, 2004 David S. Miller (davem@redhat.com) | 4 | * Copyright (C) 2001, 2002, 2003, 2004 David S. Miller (davem@redhat.com) |
| 5 | * Copyright (C) 2001, 2002, 2003 Jeff Garzik (jgarzik@pobox.com) | 5 | * Copyright (C) 2001, 2002, 2003 Jeff Garzik (jgarzik@pobox.com) |
| 6 | * Copyright (C) 2004 Sun Microsystems Inc. | 6 | * Copyright (C) 2004 Sun Microsystems Inc. |
| 7 | * Copyright (C) 2005-2014 Broadcom Corporation. | 7 | * Copyright (C) 2005-2016 Broadcom Corporation. |
| 8 | * Copyright (C) 2016-2017 Broadcom Limited. | ||
| 8 | * | 9 | * |
| 9 | * Firmware is: | 10 | * Firmware is: |
| 10 | * Derived from proprietary unpublished source code, | 11 | * Derived from proprietary unpublished source code, |
| 11 | * Copyright (C) 2000-2003 Broadcom Corporation. | 12 | * Copyright (C) 2000-2016 Broadcom Corporation. |
| 13 | * Copyright (C) 2016-2017 Broadcom Ltd. | ||
| 12 | * | 14 | * |
| 13 | * Permission is hereby granted for the distribution of this firmware | 15 | * Permission is hereby granted for the distribution of this firmware |
| 14 | * data in hexadecimal or equivalent format, provided this copyright | 16 | * data in hexadecimal or equivalent format, provided this copyright |
| @@ -10052,6 +10054,16 @@ static int tg3_reset_hw(struct tg3 *tp, bool reset_phy) | |||
| 10052 | 10054 | ||
| 10053 | tw32(GRC_MODE, tp->grc_mode | val); | 10055 | tw32(GRC_MODE, tp->grc_mode | val); |
| 10054 | 10056 | ||
| 10057 | /* On one of the AMD platform, MRRS is restricted to 4000 because of | ||
| 10058 | * south bridge limitation. As a workaround, Driver is setting MRRS | ||
| 10059 | * to 2048 instead of default 4096. | ||
| 10060 | */ | ||
| 10061 | if (tp->pdev->subsystem_vendor == PCI_VENDOR_ID_DELL && | ||
| 10062 | tp->pdev->subsystem_device == TG3PCI_SUBDEVICE_ID_DELL_5762) { | ||
| 10063 | val = tr32(TG3PCI_DEV_STATUS_CTRL) & ~MAX_READ_REQ_MASK; | ||
| 10064 | tw32(TG3PCI_DEV_STATUS_CTRL, val | MAX_READ_REQ_SIZE_2048); | ||
| 10065 | } | ||
| 10066 | |||
| 10055 | /* Setup the timer prescalar register. Clock is always 66Mhz. */ | 10067 | /* Setup the timer prescalar register. Clock is always 66Mhz. */ |
| 10056 | val = tr32(GRC_MISC_CFG); | 10068 | val = tr32(GRC_MISC_CFG); |
| 10057 | val &= ~0xff; | 10069 | val &= ~0xff; |
| @@ -14225,7 +14237,10 @@ static int tg3_change_mtu(struct net_device *dev, int new_mtu) | |||
| 14225 | /* Reset PHY, otherwise the read DMA engine will be in a mode that | 14237 | /* Reset PHY, otherwise the read DMA engine will be in a mode that |
| 14226 | * breaks all requests to 256 bytes. | 14238 | * breaks all requests to 256 bytes. |
| 14227 | */ | 14239 | */ |
| 14228 | if (tg3_asic_rev(tp) == ASIC_REV_57766) | 14240 | if (tg3_asic_rev(tp) == ASIC_REV_57766 || |
| 14241 | tg3_asic_rev(tp) == ASIC_REV_5717 || | ||
| 14242 | tg3_asic_rev(tp) == ASIC_REV_5719 || | ||
| 14243 | tg3_asic_rev(tp) == ASIC_REV_5720) | ||
| 14229 | reset_phy = true; | 14244 | reset_phy = true; |
| 14230 | 14245 | ||
| 14231 | err = tg3_restart_hw(tp, reset_phy); | 14246 | err = tg3_restart_hw(tp, reset_phy); |
diff --git a/drivers/net/ethernet/broadcom/tg3.h b/drivers/net/ethernet/broadcom/tg3.h index c2d02d02d1e6..1f0271fa7c74 100644 --- a/drivers/net/ethernet/broadcom/tg3.h +++ b/drivers/net/ethernet/broadcom/tg3.h | |||
| @@ -5,7 +5,8 @@ | |||
| 5 | * Copyright (C) 2001, 2002, 2003, 2004 David S. Miller (davem@redhat.com) | 5 | * Copyright (C) 2001, 2002, 2003, 2004 David S. Miller (davem@redhat.com) |
| 6 | * Copyright (C) 2001 Jeff Garzik (jgarzik@pobox.com) | 6 | * Copyright (C) 2001 Jeff Garzik (jgarzik@pobox.com) |
| 7 | * Copyright (C) 2004 Sun Microsystems Inc. | 7 | * Copyright (C) 2004 Sun Microsystems Inc. |
| 8 | * Copyright (C) 2007-2014 Broadcom Corporation. | 8 | * Copyright (C) 2007-2016 Broadcom Corporation. |
| 9 | * Copyright (C) 2016-2017 Broadcom Limited. | ||
| 9 | */ | 10 | */ |
| 10 | 11 | ||
| 11 | #ifndef _T3_H | 12 | #ifndef _T3_H |
| @@ -96,6 +97,7 @@ | |||
| 96 | #define TG3PCI_SUBDEVICE_ID_DELL_JAGUAR 0x0106 | 97 | #define TG3PCI_SUBDEVICE_ID_DELL_JAGUAR 0x0106 |
| 97 | #define TG3PCI_SUBDEVICE_ID_DELL_MERLOT 0x0109 | 98 | #define TG3PCI_SUBDEVICE_ID_DELL_MERLOT 0x0109 |
| 98 | #define TG3PCI_SUBDEVICE_ID_DELL_SLIM_MERLOT 0x010a | 99 | #define TG3PCI_SUBDEVICE_ID_DELL_SLIM_MERLOT 0x010a |
| 100 | #define TG3PCI_SUBDEVICE_ID_DELL_5762 0x07f0 | ||
| 99 | #define TG3PCI_SUBVENDOR_ID_COMPAQ PCI_VENDOR_ID_COMPAQ | 101 | #define TG3PCI_SUBVENDOR_ID_COMPAQ PCI_VENDOR_ID_COMPAQ |
| 100 | #define TG3PCI_SUBDEVICE_ID_COMPAQ_BANSHEE 0x007c | 102 | #define TG3PCI_SUBDEVICE_ID_COMPAQ_BANSHEE 0x007c |
| 101 | #define TG3PCI_SUBDEVICE_ID_COMPAQ_BANSHEE_2 0x009a | 103 | #define TG3PCI_SUBDEVICE_ID_COMPAQ_BANSHEE_2 0x009a |
| @@ -281,6 +283,9 @@ | |||
| 281 | #define TG3PCI_STD_RING_PROD_IDX 0x00000098 /* 64-bit */ | 283 | #define TG3PCI_STD_RING_PROD_IDX 0x00000098 /* 64-bit */ |
| 282 | #define TG3PCI_RCV_RET_RING_CON_IDX 0x000000a0 /* 64-bit */ | 284 | #define TG3PCI_RCV_RET_RING_CON_IDX 0x000000a0 /* 64-bit */ |
| 283 | /* 0xa8 --> 0xb8 unused */ | 285 | /* 0xa8 --> 0xb8 unused */ |
| 286 | #define TG3PCI_DEV_STATUS_CTRL 0x000000b4 | ||
| 287 | #define MAX_READ_REQ_SIZE_2048 0x00004000 | ||
| 288 | #define MAX_READ_REQ_MASK 0x00007000 | ||
| 284 | #define TG3PCI_DUAL_MAC_CTRL 0x000000b8 | 289 | #define TG3PCI_DUAL_MAC_CTRL 0x000000b8 |
| 285 | #define DUAL_MAC_CTRL_CH_MASK 0x00000003 | 290 | #define DUAL_MAC_CTRL_CH_MASK 0x00000003 |
| 286 | #define DUAL_MAC_CTRL_ID 0x00000004 | 291 | #define DUAL_MAC_CTRL_ID 0x00000004 |
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c index 610573855213..8184d2fca9be 100644 --- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c | |||
| @@ -818,6 +818,12 @@ static void fec_enet_bd_init(struct net_device *dev) | |||
| 818 | for (i = 0; i < txq->bd.ring_size; i++) { | 818 | for (i = 0; i < txq->bd.ring_size; i++) { |
| 819 | /* Initialize the BD for every fragment in the page. */ | 819 | /* Initialize the BD for every fragment in the page. */ |
| 820 | bdp->cbd_sc = cpu_to_fec16(0); | 820 | bdp->cbd_sc = cpu_to_fec16(0); |
| 821 | if (bdp->cbd_bufaddr && | ||
| 822 | !IS_TSO_HEADER(txq, fec32_to_cpu(bdp->cbd_bufaddr))) | ||
| 823 | dma_unmap_single(&fep->pdev->dev, | ||
| 824 | fec32_to_cpu(bdp->cbd_bufaddr), | ||
| 825 | fec16_to_cpu(bdp->cbd_datlen), | ||
| 826 | DMA_TO_DEVICE); | ||
| 821 | if (txq->tx_skbuff[i]) { | 827 | if (txq->tx_skbuff[i]) { |
| 822 | dev_kfree_skb_any(txq->tx_skbuff[i]); | 828 | dev_kfree_skb_any(txq->tx_skbuff[i]); |
| 823 | txq->tx_skbuff[i] = NULL; | 829 | txq->tx_skbuff[i] = NULL; |
diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c index bc93b69cfd1e..a539263cd79c 100644 --- a/drivers/net/ethernet/marvell/mvneta.c +++ b/drivers/net/ethernet/marvell/mvneta.c | |||
| @@ -1214,6 +1214,10 @@ static void mvneta_port_disable(struct mvneta_port *pp) | |||
| 1214 | val &= ~MVNETA_GMAC0_PORT_ENABLE; | 1214 | val &= ~MVNETA_GMAC0_PORT_ENABLE; |
| 1215 | mvreg_write(pp, MVNETA_GMAC_CTRL_0, val); | 1215 | mvreg_write(pp, MVNETA_GMAC_CTRL_0, val); |
| 1216 | 1216 | ||
| 1217 | pp->link = 0; | ||
| 1218 | pp->duplex = -1; | ||
| 1219 | pp->speed = 0; | ||
| 1220 | |||
| 1217 | udelay(200); | 1221 | udelay(200); |
| 1218 | } | 1222 | } |
| 1219 | 1223 | ||
| @@ -1958,9 +1962,9 @@ static int mvneta_rx_swbm(struct mvneta_port *pp, int rx_todo, | |||
| 1958 | 1962 | ||
| 1959 | if (!mvneta_rxq_desc_is_first_last(rx_status) || | 1963 | if (!mvneta_rxq_desc_is_first_last(rx_status) || |
| 1960 | (rx_status & MVNETA_RXD_ERR_SUMMARY)) { | 1964 | (rx_status & MVNETA_RXD_ERR_SUMMARY)) { |
| 1965 | mvneta_rx_error(pp, rx_desc); | ||
| 1961 | err_drop_frame: | 1966 | err_drop_frame: |
| 1962 | dev->stats.rx_errors++; | 1967 | dev->stats.rx_errors++; |
| 1963 | mvneta_rx_error(pp, rx_desc); | ||
| 1964 | /* leave the descriptor untouched */ | 1968 | /* leave the descriptor untouched */ |
| 1965 | continue; | 1969 | continue; |
| 1966 | } | 1970 | } |
| @@ -3011,7 +3015,7 @@ static void mvneta_cleanup_rxqs(struct mvneta_port *pp) | |||
| 3011 | { | 3015 | { |
| 3012 | int queue; | 3016 | int queue; |
| 3013 | 3017 | ||
| 3014 | for (queue = 0; queue < txq_number; queue++) | 3018 | for (queue = 0; queue < rxq_number; queue++) |
| 3015 | mvneta_rxq_deinit(pp, &pp->rxqs[queue]); | 3019 | mvneta_rxq_deinit(pp, &pp->rxqs[queue]); |
| 3016 | } | 3020 | } |
| 3017 | 3021 | ||
diff --git a/drivers/net/ethernet/marvell/skge.c b/drivers/net/ethernet/marvell/skge.c index 6e423f098a60..31efc47c847e 100644 --- a/drivers/net/ethernet/marvell/skge.c +++ b/drivers/net/ethernet/marvell/skge.c | |||
| @@ -4081,7 +4081,6 @@ static void skge_remove(struct pci_dev *pdev) | |||
| 4081 | if (hw->ports > 1) { | 4081 | if (hw->ports > 1) { |
| 4082 | skge_write32(hw, B0_IMSK, 0); | 4082 | skge_write32(hw, B0_IMSK, 0); |
| 4083 | skge_read32(hw, B0_IMSK); | 4083 | skge_read32(hw, B0_IMSK); |
| 4084 | free_irq(pdev->irq, hw); | ||
| 4085 | } | 4084 | } |
| 4086 | spin_unlock_irq(&hw->hw_lock); | 4085 | spin_unlock_irq(&hw->hw_lock); |
| 4087 | 4086 | ||
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c index 54adfd967858..fc67e35b253e 100644 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c | |||
| @@ -1961,11 +1961,12 @@ static int mtk_hw_init(struct mtk_eth *eth) | |||
| 1961 | /* set GE2 TUNE */ | 1961 | /* set GE2 TUNE */ |
| 1962 | regmap_write(eth->pctl, GPIO_BIAS_CTRL, 0x0); | 1962 | regmap_write(eth->pctl, GPIO_BIAS_CTRL, 0x0); |
| 1963 | 1963 | ||
| 1964 | /* GE1, Force 1000M/FD, FC ON */ | 1964 | /* Set linkdown as the default for each GMAC. Its own MCR would be set |
| 1965 | mtk_w32(eth, MAC_MCR_FIXED_LINK, MTK_MAC_MCR(0)); | 1965 | * up with the more appropriate value when mtk_phy_link_adjust call is |
| 1966 | 1966 | * being invoked. | |
| 1967 | /* GE2, Force 1000M/FD, FC ON */ | 1967 | */ |
| 1968 | mtk_w32(eth, MAC_MCR_FIXED_LINK, MTK_MAC_MCR(1)); | 1968 | for (i = 0; i < MTK_MAC_COUNT; i++) |
| 1969 | mtk_w32(eth, 0, MTK_MAC_MCR(i)); | ||
| 1969 | 1970 | ||
| 1970 | /* Indicates CDM to parse the MTK special tag from CPU | 1971 | /* Indicates CDM to parse the MTK special tag from CPU |
| 1971 | * which also is working out for untag packets. | 1972 | * which also is working out for untag packets. |
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_port.c b/drivers/net/ethernet/mellanox/mlx4/en_port.c index e0eb695318e6..1fa4849a6f56 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_port.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_port.c | |||
| @@ -188,7 +188,7 @@ int mlx4_en_DUMP_ETH_STATS(struct mlx4_en_dev *mdev, u8 port, u8 reset) | |||
| 188 | struct net_device *dev = mdev->pndev[port]; | 188 | struct net_device *dev = mdev->pndev[port]; |
| 189 | struct mlx4_en_priv *priv = netdev_priv(dev); | 189 | struct mlx4_en_priv *priv = netdev_priv(dev); |
| 190 | struct net_device_stats *stats = &dev->stats; | 190 | struct net_device_stats *stats = &dev->stats; |
| 191 | struct mlx4_cmd_mailbox *mailbox; | 191 | struct mlx4_cmd_mailbox *mailbox, *mailbox_priority; |
| 192 | u64 in_mod = reset << 8 | port; | 192 | u64 in_mod = reset << 8 | port; |
| 193 | int err; | 193 | int err; |
| 194 | int i, counter_index; | 194 | int i, counter_index; |
| @@ -198,6 +198,13 @@ int mlx4_en_DUMP_ETH_STATS(struct mlx4_en_dev *mdev, u8 port, u8 reset) | |||
| 198 | mailbox = mlx4_alloc_cmd_mailbox(mdev->dev); | 198 | mailbox = mlx4_alloc_cmd_mailbox(mdev->dev); |
| 199 | if (IS_ERR(mailbox)) | 199 | if (IS_ERR(mailbox)) |
| 200 | return PTR_ERR(mailbox); | 200 | return PTR_ERR(mailbox); |
| 201 | |||
| 202 | mailbox_priority = mlx4_alloc_cmd_mailbox(mdev->dev); | ||
| 203 | if (IS_ERR(mailbox_priority)) { | ||
| 204 | mlx4_free_cmd_mailbox(mdev->dev, mailbox); | ||
| 205 | return PTR_ERR(mailbox_priority); | ||
| 206 | } | ||
| 207 | |||
| 201 | err = mlx4_cmd_box(mdev->dev, 0, mailbox->dma, in_mod, 0, | 208 | err = mlx4_cmd_box(mdev->dev, 0, mailbox->dma, in_mod, 0, |
| 202 | MLX4_CMD_DUMP_ETH_STATS, MLX4_CMD_TIME_CLASS_B, | 209 | MLX4_CMD_DUMP_ETH_STATS, MLX4_CMD_TIME_CLASS_B, |
| 203 | MLX4_CMD_NATIVE); | 210 | MLX4_CMD_NATIVE); |
| @@ -206,6 +213,28 @@ int mlx4_en_DUMP_ETH_STATS(struct mlx4_en_dev *mdev, u8 port, u8 reset) | |||
| 206 | 213 | ||
| 207 | mlx4_en_stats = mailbox->buf; | 214 | mlx4_en_stats = mailbox->buf; |
| 208 | 215 | ||
| 216 | memset(&tmp_counter_stats, 0, sizeof(tmp_counter_stats)); | ||
| 217 | counter_index = mlx4_get_default_counter_index(mdev->dev, port); | ||
| 218 | err = mlx4_get_counter_stats(mdev->dev, counter_index, | ||
| 219 | &tmp_counter_stats, reset); | ||
| 220 | |||
| 221 | /* 0xffs indicates invalid value */ | ||
| 222 | memset(mailbox_priority->buf, 0xff, | ||
| 223 | sizeof(*flowstats) * MLX4_NUM_PRIORITIES); | ||
| 224 | |||
| 225 | if (mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_FLOWSTATS_EN) { | ||
| 226 | memset(mailbox_priority->buf, 0, | ||
| 227 | sizeof(*flowstats) * MLX4_NUM_PRIORITIES); | ||
| 228 | err = mlx4_cmd_box(mdev->dev, 0, mailbox_priority->dma, | ||
| 229 | in_mod | MLX4_DUMP_ETH_STATS_FLOW_CONTROL, | ||
| 230 | 0, MLX4_CMD_DUMP_ETH_STATS, | ||
| 231 | MLX4_CMD_TIME_CLASS_B, MLX4_CMD_NATIVE); | ||
| 232 | if (err) | ||
| 233 | goto out; | ||
| 234 | } | ||
| 235 | |||
| 236 | flowstats = mailbox_priority->buf; | ||
| 237 | |||
| 209 | spin_lock_bh(&priv->stats_lock); | 238 | spin_lock_bh(&priv->stats_lock); |
| 210 | 239 | ||
| 211 | mlx4_en_fold_software_stats(dev); | 240 | mlx4_en_fold_software_stats(dev); |
| @@ -345,31 +374,6 @@ int mlx4_en_DUMP_ETH_STATS(struct mlx4_en_dev *mdev, u8 port, u8 reset) | |||
| 345 | priv->pkstats.tx_prio[8][0] = be64_to_cpu(mlx4_en_stats->TTOT_novlan); | 374 | priv->pkstats.tx_prio[8][0] = be64_to_cpu(mlx4_en_stats->TTOT_novlan); |
| 346 | priv->pkstats.tx_prio[8][1] = be64_to_cpu(mlx4_en_stats->TOCT_novlan); | 375 | priv->pkstats.tx_prio[8][1] = be64_to_cpu(mlx4_en_stats->TOCT_novlan); |
| 347 | 376 | ||
| 348 | spin_unlock_bh(&priv->stats_lock); | ||
| 349 | |||
| 350 | memset(&tmp_counter_stats, 0, sizeof(tmp_counter_stats)); | ||
| 351 | counter_index = mlx4_get_default_counter_index(mdev->dev, port); | ||
| 352 | err = mlx4_get_counter_stats(mdev->dev, counter_index, | ||
| 353 | &tmp_counter_stats, reset); | ||
| 354 | |||
| 355 | /* 0xffs indicates invalid value */ | ||
| 356 | memset(mailbox->buf, 0xff, sizeof(*flowstats) * MLX4_NUM_PRIORITIES); | ||
| 357 | |||
| 358 | if (mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_FLOWSTATS_EN) { | ||
| 359 | memset(mailbox->buf, 0, | ||
| 360 | sizeof(*flowstats) * MLX4_NUM_PRIORITIES); | ||
| 361 | err = mlx4_cmd_box(mdev->dev, 0, mailbox->dma, | ||
| 362 | in_mod | MLX4_DUMP_ETH_STATS_FLOW_CONTROL, | ||
| 363 | 0, MLX4_CMD_DUMP_ETH_STATS, | ||
| 364 | MLX4_CMD_TIME_CLASS_B, MLX4_CMD_NATIVE); | ||
| 365 | if (err) | ||
| 366 | goto out; | ||
| 367 | } | ||
| 368 | |||
| 369 | flowstats = mailbox->buf; | ||
| 370 | |||
| 371 | spin_lock_bh(&priv->stats_lock); | ||
| 372 | |||
| 373 | if (tmp_counter_stats.counter_mode == 0) { | 377 | if (tmp_counter_stats.counter_mode == 0) { |
| 374 | priv->pf_stats.rx_bytes = be64_to_cpu(tmp_counter_stats.rx_bytes); | 378 | priv->pf_stats.rx_bytes = be64_to_cpu(tmp_counter_stats.rx_bytes); |
| 375 | priv->pf_stats.tx_bytes = be64_to_cpu(tmp_counter_stats.tx_bytes); | 379 | priv->pf_stats.tx_bytes = be64_to_cpu(tmp_counter_stats.tx_bytes); |
| @@ -410,6 +414,7 @@ int mlx4_en_DUMP_ETH_STATS(struct mlx4_en_dev *mdev, u8 port, u8 reset) | |||
| 410 | 414 | ||
| 411 | out: | 415 | out: |
| 412 | mlx4_free_cmd_mailbox(mdev->dev, mailbox); | 416 | mlx4_free_cmd_mailbox(mdev->dev, mailbox); |
| 417 | mlx4_free_cmd_mailbox(mdev->dev, mailbox_priority); | ||
| 413 | return err; | 418 | return err; |
| 414 | } | 419 | } |
| 415 | 420 | ||
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_selftest.c b/drivers/net/ethernet/mellanox/mlx4/en_selftest.c index 88699b181946..946d9db7c8c2 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_selftest.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_selftest.c | |||
| @@ -185,7 +185,7 @@ void mlx4_en_ex_selftest(struct net_device *dev, u32 *flags, u64 *buf) | |||
| 185 | if (priv->mdev->dev->caps.flags & | 185 | if (priv->mdev->dev->caps.flags & |
| 186 | MLX4_DEV_CAP_FLAG_UC_LOOPBACK) { | 186 | MLX4_DEV_CAP_FLAG_UC_LOOPBACK) { |
| 187 | buf[3] = mlx4_en_test_registers(priv); | 187 | buf[3] = mlx4_en_test_registers(priv); |
| 188 | if (priv->port_up) | 188 | if (priv->port_up && dev->mtu >= MLX4_SELFTEST_LB_MIN_MTU) |
| 189 | buf[4] = mlx4_en_test_loopback(priv); | 189 | buf[4] = mlx4_en_test_loopback(priv); |
| 190 | } | 190 | } |
| 191 | 191 | ||
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h index 1856e279a7e0..2b72677eccd4 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | |||
| @@ -153,6 +153,9 @@ | |||
| 153 | #define SMALL_PACKET_SIZE (256 - NET_IP_ALIGN) | 153 | #define SMALL_PACKET_SIZE (256 - NET_IP_ALIGN) |
| 154 | #define HEADER_COPY_SIZE (128 - NET_IP_ALIGN) | 154 | #define HEADER_COPY_SIZE (128 - NET_IP_ALIGN) |
| 155 | #define MLX4_LOOPBACK_TEST_PAYLOAD (HEADER_COPY_SIZE - ETH_HLEN) | 155 | #define MLX4_LOOPBACK_TEST_PAYLOAD (HEADER_COPY_SIZE - ETH_HLEN) |
| 156 | #define PREAMBLE_LEN 8 | ||
| 157 | #define MLX4_SELFTEST_LB_MIN_MTU (MLX4_LOOPBACK_TEST_PAYLOAD + NET_IP_ALIGN + \ | ||
| 158 | ETH_HLEN + PREAMBLE_LEN) | ||
| 156 | 159 | ||
| 157 | #define MLX4_EN_MIN_MTU 46 | 160 | #define MLX4_EN_MIN_MTU 46 |
| 158 | /* VLAN_HLEN is added twice,to support skb vlan tagged with multiple | 161 | /* VLAN_HLEN is added twice,to support skb vlan tagged with multiple |
diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c index 04304dd894c6..606a0e0beeae 100644 --- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c +++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c | |||
| @@ -611,7 +611,6 @@ int mlx4_init_resource_tracker(struct mlx4_dev *dev) | |||
| 611 | MLX4_MAX_PORTS; | 611 | MLX4_MAX_PORTS; |
| 612 | else | 612 | else |
| 613 | res_alloc->guaranteed[t] = 0; | 613 | res_alloc->guaranteed[t] = 0; |
| 614 | res_alloc->res_free -= res_alloc->guaranteed[t]; | ||
| 615 | break; | 614 | break; |
| 616 | default: | 615 | default: |
| 617 | break; | 616 | break; |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c index 1fffdebbc9e8..e9a1fbcc4adf 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c | |||
| @@ -362,7 +362,7 @@ static int mlx5_internal_err_ret_value(struct mlx5_core_dev *dev, u16 op, | |||
| 362 | case MLX5_CMD_OP_QUERY_VPORT_COUNTER: | 362 | case MLX5_CMD_OP_QUERY_VPORT_COUNTER: |
| 363 | case MLX5_CMD_OP_ALLOC_Q_COUNTER: | 363 | case MLX5_CMD_OP_ALLOC_Q_COUNTER: |
| 364 | case MLX5_CMD_OP_QUERY_Q_COUNTER: | 364 | case MLX5_CMD_OP_QUERY_Q_COUNTER: |
| 365 | case MLX5_CMD_OP_SET_RATE_LIMIT: | 365 | case MLX5_CMD_OP_SET_PP_RATE_LIMIT: |
| 366 | case MLX5_CMD_OP_QUERY_RATE_LIMIT: | 366 | case MLX5_CMD_OP_QUERY_RATE_LIMIT: |
| 367 | case MLX5_CMD_OP_CREATE_SCHEDULING_ELEMENT: | 367 | case MLX5_CMD_OP_CREATE_SCHEDULING_ELEMENT: |
| 368 | case MLX5_CMD_OP_QUERY_SCHEDULING_ELEMENT: | 368 | case MLX5_CMD_OP_QUERY_SCHEDULING_ELEMENT: |
| @@ -505,7 +505,7 @@ const char *mlx5_command_str(int command) | |||
| 505 | MLX5_COMMAND_STR_CASE(ALLOC_Q_COUNTER); | 505 | MLX5_COMMAND_STR_CASE(ALLOC_Q_COUNTER); |
| 506 | MLX5_COMMAND_STR_CASE(DEALLOC_Q_COUNTER); | 506 | MLX5_COMMAND_STR_CASE(DEALLOC_Q_COUNTER); |
| 507 | MLX5_COMMAND_STR_CASE(QUERY_Q_COUNTER); | 507 | MLX5_COMMAND_STR_CASE(QUERY_Q_COUNTER); |
| 508 | MLX5_COMMAND_STR_CASE(SET_RATE_LIMIT); | 508 | MLX5_COMMAND_STR_CASE(SET_PP_RATE_LIMIT); |
| 509 | MLX5_COMMAND_STR_CASE(QUERY_RATE_LIMIT); | 509 | MLX5_COMMAND_STR_CASE(QUERY_RATE_LIMIT); |
| 510 | MLX5_COMMAND_STR_CASE(CREATE_SCHEDULING_ELEMENT); | 510 | MLX5_COMMAND_STR_CASE(CREATE_SCHEDULING_ELEMENT); |
| 511 | MLX5_COMMAND_STR_CASE(DESTROY_SCHEDULING_ELEMENT); | 511 | MLX5_COMMAND_STR_CASE(DESTROY_SCHEDULING_ELEMENT); |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h index c0872b3284cb..543060c305a0 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h | |||
| @@ -82,6 +82,9 @@ | |||
| 82 | max_t(u32, MLX5_MPWRQ_MIN_LOG_STRIDE_SZ(mdev), req) | 82 | max_t(u32, MLX5_MPWRQ_MIN_LOG_STRIDE_SZ(mdev), req) |
| 83 | #define MLX5_MPWRQ_DEF_LOG_STRIDE_SZ(mdev) MLX5_MPWRQ_LOG_STRIDE_SZ(mdev, 6) | 83 | #define MLX5_MPWRQ_DEF_LOG_STRIDE_SZ(mdev) MLX5_MPWRQ_LOG_STRIDE_SZ(mdev, 6) |
| 84 | #define MLX5_MPWRQ_CQE_CMPRS_LOG_STRIDE_SZ(mdev) MLX5_MPWRQ_LOG_STRIDE_SZ(mdev, 8) | 84 | #define MLX5_MPWRQ_CQE_CMPRS_LOG_STRIDE_SZ(mdev) MLX5_MPWRQ_LOG_STRIDE_SZ(mdev, 8) |
| 85 | #define MLX5E_MPWQE_STRIDE_SZ(mdev, cqe_cmprs) \ | ||
| 86 | (cqe_cmprs ? MLX5_MPWRQ_CQE_CMPRS_LOG_STRIDE_SZ(mdev) : \ | ||
| 87 | MLX5_MPWRQ_DEF_LOG_STRIDE_SZ(mdev)) | ||
| 85 | 88 | ||
| 86 | #define MLX5_MPWRQ_LOG_WQE_SZ 18 | 89 | #define MLX5_MPWRQ_LOG_WQE_SZ 18 |
| 87 | #define MLX5_MPWRQ_WQE_PAGE_ORDER (MLX5_MPWRQ_LOG_WQE_SZ - PAGE_SHIFT > 0 ? \ | 90 | #define MLX5_MPWRQ_WQE_PAGE_ORDER (MLX5_MPWRQ_LOG_WQE_SZ - PAGE_SHIFT > 0 ? \ |
| @@ -590,6 +593,7 @@ struct mlx5e_channel { | |||
| 590 | struct mlx5_core_dev *mdev; | 593 | struct mlx5_core_dev *mdev; |
| 591 | struct hwtstamp_config *tstamp; | 594 | struct hwtstamp_config *tstamp; |
| 592 | int ix; | 595 | int ix; |
| 596 | int cpu; | ||
| 593 | }; | 597 | }; |
| 594 | 598 | ||
| 595 | struct mlx5e_channels { | 599 | struct mlx5e_channels { |
| @@ -935,8 +939,9 @@ void mlx5e_set_tx_cq_mode_params(struct mlx5e_params *params, | |||
| 935 | u8 cq_period_mode); | 939 | u8 cq_period_mode); |
| 936 | void mlx5e_set_rx_cq_mode_params(struct mlx5e_params *params, | 940 | void mlx5e_set_rx_cq_mode_params(struct mlx5e_params *params, |
| 937 | u8 cq_period_mode); | 941 | u8 cq_period_mode); |
| 938 | void mlx5e_set_rq_type_params(struct mlx5_core_dev *mdev, | 942 | void mlx5e_init_rq_type_params(struct mlx5_core_dev *mdev, |
| 939 | struct mlx5e_params *params, u8 rq_type); | 943 | struct mlx5e_params *params, |
| 944 | u8 rq_type); | ||
| 940 | 945 | ||
| 941 | static inline bool mlx5e_tunnel_inner_ft_supported(struct mlx5_core_dev *mdev) | 946 | static inline bool mlx5e_tunnel_inner_ft_supported(struct mlx5_core_dev *mdev) |
| 942 | { | 947 | { |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c index c6d90b6dd80e..9bcf38f4123b 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c | |||
| @@ -274,6 +274,7 @@ int mlx5e_dcbnl_ieee_setets_core(struct mlx5e_priv *priv, struct ieee_ets *ets) | |||
| 274 | static int mlx5e_dbcnl_validate_ets(struct net_device *netdev, | 274 | static int mlx5e_dbcnl_validate_ets(struct net_device *netdev, |
| 275 | struct ieee_ets *ets) | 275 | struct ieee_ets *ets) |
| 276 | { | 276 | { |
| 277 | bool have_ets_tc = false; | ||
| 277 | int bw_sum = 0; | 278 | int bw_sum = 0; |
| 278 | int i; | 279 | int i; |
| 279 | 280 | ||
| @@ -288,11 +289,14 @@ static int mlx5e_dbcnl_validate_ets(struct net_device *netdev, | |||
| 288 | } | 289 | } |
| 289 | 290 | ||
| 290 | /* Validate Bandwidth Sum */ | 291 | /* Validate Bandwidth Sum */ |
| 291 | for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) | 292 | for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) { |
| 292 | if (ets->tc_tsa[i] == IEEE_8021QAZ_TSA_ETS) | 293 | if (ets->tc_tsa[i] == IEEE_8021QAZ_TSA_ETS) { |
| 294 | have_ets_tc = true; | ||
| 293 | bw_sum += ets->tc_tx_bw[i]; | 295 | bw_sum += ets->tc_tx_bw[i]; |
| 296 | } | ||
| 297 | } | ||
| 294 | 298 | ||
| 295 | if (bw_sum != 0 && bw_sum != 100) { | 299 | if (have_ets_tc && bw_sum != 100) { |
| 296 | netdev_err(netdev, | 300 | netdev_err(netdev, |
| 297 | "Failed to validate ETS: BW sum is illegal\n"); | 301 | "Failed to validate ETS: BW sum is illegal\n"); |
| 298 | return -EINVAL; | 302 | return -EINVAL; |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c index 23425f028405..8f05efa5c829 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c | |||
| @@ -1523,8 +1523,10 @@ int mlx5e_modify_rx_cqe_compression_locked(struct mlx5e_priv *priv, bool new_val | |||
| 1523 | new_channels.params = priv->channels.params; | 1523 | new_channels.params = priv->channels.params; |
| 1524 | MLX5E_SET_PFLAG(&new_channels.params, MLX5E_PFLAG_RX_CQE_COMPRESS, new_val); | 1524 | MLX5E_SET_PFLAG(&new_channels.params, MLX5E_PFLAG_RX_CQE_COMPRESS, new_val); |
| 1525 | 1525 | ||
| 1526 | mlx5e_set_rq_type_params(priv->mdev, &new_channels.params, | 1526 | new_channels.params.mpwqe_log_stride_sz = |
| 1527 | new_channels.params.rq_wq_type); | 1527 | MLX5E_MPWQE_STRIDE_SZ(priv->mdev, new_val); |
| 1528 | new_channels.params.mpwqe_log_num_strides = | ||
| 1529 | MLX5_MPWRQ_LOG_WQE_SZ - new_channels.params.mpwqe_log_stride_sz; | ||
| 1528 | 1530 | ||
| 1529 | if (!test_bit(MLX5E_STATE_OPENED, &priv->state)) { | 1531 | if (!test_bit(MLX5E_STATE_OPENED, &priv->state)) { |
| 1530 | priv->channels.params = new_channels.params; | 1532 | priv->channels.params = new_channels.params; |
| @@ -1536,6 +1538,10 @@ int mlx5e_modify_rx_cqe_compression_locked(struct mlx5e_priv *priv, bool new_val | |||
| 1536 | return err; | 1538 | return err; |
| 1537 | 1539 | ||
| 1538 | mlx5e_switch_priv_channels(priv, &new_channels, NULL); | 1540 | mlx5e_switch_priv_channels(priv, &new_channels, NULL); |
| 1541 | mlx5e_dbg(DRV, priv, "MLX5E: RxCqeCmprss was turned %s\n", | ||
| 1542 | MLX5E_GET_PFLAG(&priv->channels.params, | ||
| 1543 | MLX5E_PFLAG_RX_CQE_COMPRESS) ? "ON" : "OFF"); | ||
| 1544 | |||
| 1539 | return 0; | 1545 | return 0; |
| 1540 | } | 1546 | } |
| 1541 | 1547 | ||
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c index d2b057a3e512..d9d8227f195f 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c | |||
| @@ -71,11 +71,6 @@ struct mlx5e_channel_param { | |||
| 71 | struct mlx5e_cq_param icosq_cq; | 71 | struct mlx5e_cq_param icosq_cq; |
| 72 | }; | 72 | }; |
| 73 | 73 | ||
| 74 | static int mlx5e_get_node(struct mlx5e_priv *priv, int ix) | ||
| 75 | { | ||
| 76 | return pci_irq_get_node(priv->mdev->pdev, MLX5_EQ_VEC_COMP_BASE + ix); | ||
| 77 | } | ||
| 78 | |||
| 79 | static bool mlx5e_check_fragmented_striding_rq_cap(struct mlx5_core_dev *mdev) | 74 | static bool mlx5e_check_fragmented_striding_rq_cap(struct mlx5_core_dev *mdev) |
| 80 | { | 75 | { |
| 81 | return MLX5_CAP_GEN(mdev, striding_rq) && | 76 | return MLX5_CAP_GEN(mdev, striding_rq) && |
| @@ -83,8 +78,8 @@ static bool mlx5e_check_fragmented_striding_rq_cap(struct mlx5_core_dev *mdev) | |||
| 83 | MLX5_CAP_ETH(mdev, reg_umr_sq); | 78 | MLX5_CAP_ETH(mdev, reg_umr_sq); |
| 84 | } | 79 | } |
| 85 | 80 | ||
| 86 | void mlx5e_set_rq_type_params(struct mlx5_core_dev *mdev, | 81 | void mlx5e_init_rq_type_params(struct mlx5_core_dev *mdev, |
| 87 | struct mlx5e_params *params, u8 rq_type) | 82 | struct mlx5e_params *params, u8 rq_type) |
| 88 | { | 83 | { |
| 89 | params->rq_wq_type = rq_type; | 84 | params->rq_wq_type = rq_type; |
| 90 | params->lro_wqe_sz = MLX5E_PARAMS_DEFAULT_LRO_WQE_SZ; | 85 | params->lro_wqe_sz = MLX5E_PARAMS_DEFAULT_LRO_WQE_SZ; |
| @@ -93,10 +88,8 @@ void mlx5e_set_rq_type_params(struct mlx5_core_dev *mdev, | |||
| 93 | params->log_rq_size = is_kdump_kernel() ? | 88 | params->log_rq_size = is_kdump_kernel() ? |
| 94 | MLX5E_PARAMS_MINIMUM_LOG_RQ_SIZE_MPW : | 89 | MLX5E_PARAMS_MINIMUM_LOG_RQ_SIZE_MPW : |
| 95 | MLX5E_PARAMS_DEFAULT_LOG_RQ_SIZE_MPW; | 90 | MLX5E_PARAMS_DEFAULT_LOG_RQ_SIZE_MPW; |
| 96 | params->mpwqe_log_stride_sz = | 91 | params->mpwqe_log_stride_sz = MLX5E_MPWQE_STRIDE_SZ(mdev, |
| 97 | MLX5E_GET_PFLAG(params, MLX5E_PFLAG_RX_CQE_COMPRESS) ? | 92 | MLX5E_GET_PFLAG(params, MLX5E_PFLAG_RX_CQE_COMPRESS)); |
| 98 | MLX5_MPWRQ_CQE_CMPRS_LOG_STRIDE_SZ(mdev) : | ||
| 99 | MLX5_MPWRQ_DEF_LOG_STRIDE_SZ(mdev); | ||
| 100 | params->mpwqe_log_num_strides = MLX5_MPWRQ_LOG_WQE_SZ - | 93 | params->mpwqe_log_num_strides = MLX5_MPWRQ_LOG_WQE_SZ - |
| 101 | params->mpwqe_log_stride_sz; | 94 | params->mpwqe_log_stride_sz; |
| 102 | break; | 95 | break; |
| @@ -120,13 +113,14 @@ void mlx5e_set_rq_type_params(struct mlx5_core_dev *mdev, | |||
| 120 | MLX5E_GET_PFLAG(params, MLX5E_PFLAG_RX_CQE_COMPRESS)); | 113 | MLX5E_GET_PFLAG(params, MLX5E_PFLAG_RX_CQE_COMPRESS)); |
| 121 | } | 114 | } |
| 122 | 115 | ||
| 123 | static void mlx5e_set_rq_params(struct mlx5_core_dev *mdev, struct mlx5e_params *params) | 116 | static void mlx5e_set_rq_params(struct mlx5_core_dev *mdev, |
| 117 | struct mlx5e_params *params) | ||
| 124 | { | 118 | { |
| 125 | u8 rq_type = mlx5e_check_fragmented_striding_rq_cap(mdev) && | 119 | u8 rq_type = mlx5e_check_fragmented_striding_rq_cap(mdev) && |
| 126 | !params->xdp_prog && !MLX5_IPSEC_DEV(mdev) ? | 120 | !params->xdp_prog && !MLX5_IPSEC_DEV(mdev) ? |
| 127 | MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ : | 121 | MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ : |
| 128 | MLX5_WQ_TYPE_LINKED_LIST; | 122 | MLX5_WQ_TYPE_LINKED_LIST; |
| 129 | mlx5e_set_rq_type_params(mdev, params, rq_type); | 123 | mlx5e_init_rq_type_params(mdev, params, rq_type); |
| 130 | } | 124 | } |
| 131 | 125 | ||
| 132 | static void mlx5e_update_carrier(struct mlx5e_priv *priv) | 126 | static void mlx5e_update_carrier(struct mlx5e_priv *priv) |
| @@ -444,17 +438,16 @@ static int mlx5e_rq_alloc_mpwqe_info(struct mlx5e_rq *rq, | |||
| 444 | int wq_sz = mlx5_wq_ll_get_size(&rq->wq); | 438 | int wq_sz = mlx5_wq_ll_get_size(&rq->wq); |
| 445 | int mtt_sz = mlx5e_get_wqe_mtt_sz(); | 439 | int mtt_sz = mlx5e_get_wqe_mtt_sz(); |
| 446 | int mtt_alloc = mtt_sz + MLX5_UMR_ALIGN - 1; | 440 | int mtt_alloc = mtt_sz + MLX5_UMR_ALIGN - 1; |
| 447 | int node = mlx5e_get_node(c->priv, c->ix); | ||
| 448 | int i; | 441 | int i; |
| 449 | 442 | ||
| 450 | rq->mpwqe.info = kzalloc_node(wq_sz * sizeof(*rq->mpwqe.info), | 443 | rq->mpwqe.info = kzalloc_node(wq_sz * sizeof(*rq->mpwqe.info), |
| 451 | GFP_KERNEL, node); | 444 | GFP_KERNEL, cpu_to_node(c->cpu)); |
| 452 | if (!rq->mpwqe.info) | 445 | if (!rq->mpwqe.info) |
| 453 | goto err_out; | 446 | goto err_out; |
| 454 | 447 | ||
| 455 | /* We allocate more than mtt_sz as we will align the pointer */ | 448 | /* We allocate more than mtt_sz as we will align the pointer */ |
| 456 | rq->mpwqe.mtt_no_align = kzalloc_node(mtt_alloc * wq_sz, | 449 | rq->mpwqe.mtt_no_align = kzalloc_node(mtt_alloc * wq_sz, GFP_KERNEL, |
| 457 | GFP_KERNEL, node); | 450 | cpu_to_node(c->cpu)); |
| 458 | if (unlikely(!rq->mpwqe.mtt_no_align)) | 451 | if (unlikely(!rq->mpwqe.mtt_no_align)) |
| 459 | goto err_free_wqe_info; | 452 | goto err_free_wqe_info; |
| 460 | 453 | ||
| @@ -562,7 +555,7 @@ static int mlx5e_alloc_rq(struct mlx5e_channel *c, | |||
| 562 | int err; | 555 | int err; |
| 563 | int i; | 556 | int i; |
| 564 | 557 | ||
| 565 | rqp->wq.db_numa_node = mlx5e_get_node(c->priv, c->ix); | 558 | rqp->wq.db_numa_node = cpu_to_node(c->cpu); |
| 566 | 559 | ||
| 567 | err = mlx5_wq_ll_create(mdev, &rqp->wq, rqc_wq, &rq->wq, | 560 | err = mlx5_wq_ll_create(mdev, &rqp->wq, rqc_wq, &rq->wq, |
| 568 | &rq->wq_ctrl); | 561 | &rq->wq_ctrl); |
| @@ -629,8 +622,7 @@ static int mlx5e_alloc_rq(struct mlx5e_channel *c, | |||
| 629 | default: /* MLX5_WQ_TYPE_LINKED_LIST */ | 622 | default: /* MLX5_WQ_TYPE_LINKED_LIST */ |
| 630 | rq->wqe.frag_info = | 623 | rq->wqe.frag_info = |
| 631 | kzalloc_node(wq_sz * sizeof(*rq->wqe.frag_info), | 624 | kzalloc_node(wq_sz * sizeof(*rq->wqe.frag_info), |
| 632 | GFP_KERNEL, | 625 | GFP_KERNEL, cpu_to_node(c->cpu)); |
| 633 | mlx5e_get_node(c->priv, c->ix)); | ||
| 634 | if (!rq->wqe.frag_info) { | 626 | if (!rq->wqe.frag_info) { |
| 635 | err = -ENOMEM; | 627 | err = -ENOMEM; |
| 636 | goto err_rq_wq_destroy; | 628 | goto err_rq_wq_destroy; |
| @@ -1000,13 +992,13 @@ static int mlx5e_alloc_xdpsq(struct mlx5e_channel *c, | |||
| 1000 | sq->uar_map = mdev->mlx5e_res.bfreg.map; | 992 | sq->uar_map = mdev->mlx5e_res.bfreg.map; |
| 1001 | sq->min_inline_mode = params->tx_min_inline_mode; | 993 | sq->min_inline_mode = params->tx_min_inline_mode; |
| 1002 | 994 | ||
| 1003 | param->wq.db_numa_node = mlx5e_get_node(c->priv, c->ix); | 995 | param->wq.db_numa_node = cpu_to_node(c->cpu); |
| 1004 | err = mlx5_wq_cyc_create(mdev, ¶m->wq, sqc_wq, &sq->wq, &sq->wq_ctrl); | 996 | err = mlx5_wq_cyc_create(mdev, ¶m->wq, sqc_wq, &sq->wq, &sq->wq_ctrl); |
| 1005 | if (err) | 997 | if (err) |
| 1006 | return err; | 998 | return err; |
| 1007 | sq->wq.db = &sq->wq.db[MLX5_SND_DBR]; | 999 | sq->wq.db = &sq->wq.db[MLX5_SND_DBR]; |
| 1008 | 1000 | ||
| 1009 | err = mlx5e_alloc_xdpsq_db(sq, mlx5e_get_node(c->priv, c->ix)); | 1001 | err = mlx5e_alloc_xdpsq_db(sq, cpu_to_node(c->cpu)); |
| 1010 | if (err) | 1002 | if (err) |
| 1011 | goto err_sq_wq_destroy; | 1003 | goto err_sq_wq_destroy; |
| 1012 | 1004 | ||
| @@ -1053,13 +1045,13 @@ static int mlx5e_alloc_icosq(struct mlx5e_channel *c, | |||
| 1053 | sq->channel = c; | 1045 | sq->channel = c; |
| 1054 | sq->uar_map = mdev->mlx5e_res.bfreg.map; | 1046 | sq->uar_map = mdev->mlx5e_res.bfreg.map; |
| 1055 | 1047 | ||
| 1056 | param->wq.db_numa_node = mlx5e_get_node(c->priv, c->ix); | 1048 | param->wq.db_numa_node = cpu_to_node(c->cpu); |
| 1057 | err = mlx5_wq_cyc_create(mdev, ¶m->wq, sqc_wq, &sq->wq, &sq->wq_ctrl); | 1049 | err = mlx5_wq_cyc_create(mdev, ¶m->wq, sqc_wq, &sq->wq, &sq->wq_ctrl); |
| 1058 | if (err) | 1050 | if (err) |
| 1059 | return err; | 1051 | return err; |
| 1060 | sq->wq.db = &sq->wq.db[MLX5_SND_DBR]; | 1052 | sq->wq.db = &sq->wq.db[MLX5_SND_DBR]; |
| 1061 | 1053 | ||
| 1062 | err = mlx5e_alloc_icosq_db(sq, mlx5e_get_node(c->priv, c->ix)); | 1054 | err = mlx5e_alloc_icosq_db(sq, cpu_to_node(c->cpu)); |
| 1063 | if (err) | 1055 | if (err) |
| 1064 | goto err_sq_wq_destroy; | 1056 | goto err_sq_wq_destroy; |
| 1065 | 1057 | ||
| @@ -1126,13 +1118,13 @@ static int mlx5e_alloc_txqsq(struct mlx5e_channel *c, | |||
| 1126 | if (MLX5_IPSEC_DEV(c->priv->mdev)) | 1118 | if (MLX5_IPSEC_DEV(c->priv->mdev)) |
| 1127 | set_bit(MLX5E_SQ_STATE_IPSEC, &sq->state); | 1119 | set_bit(MLX5E_SQ_STATE_IPSEC, &sq->state); |
| 1128 | 1120 | ||
| 1129 | param->wq.db_numa_node = mlx5e_get_node(c->priv, c->ix); | 1121 | param->wq.db_numa_node = cpu_to_node(c->cpu); |
| 1130 | err = mlx5_wq_cyc_create(mdev, ¶m->wq, sqc_wq, &sq->wq, &sq->wq_ctrl); | 1122 | err = mlx5_wq_cyc_create(mdev, ¶m->wq, sqc_wq, &sq->wq, &sq->wq_ctrl); |
| 1131 | if (err) | 1123 | if (err) |
| 1132 | return err; | 1124 | return err; |
| 1133 | sq->wq.db = &sq->wq.db[MLX5_SND_DBR]; | 1125 | sq->wq.db = &sq->wq.db[MLX5_SND_DBR]; |
| 1134 | 1126 | ||
| 1135 | err = mlx5e_alloc_txqsq_db(sq, mlx5e_get_node(c->priv, c->ix)); | 1127 | err = mlx5e_alloc_txqsq_db(sq, cpu_to_node(c->cpu)); |
| 1136 | if (err) | 1128 | if (err) |
| 1137 | goto err_sq_wq_destroy; | 1129 | goto err_sq_wq_destroy; |
| 1138 | 1130 | ||
| @@ -1504,8 +1496,8 @@ static int mlx5e_alloc_cq(struct mlx5e_channel *c, | |||
| 1504 | struct mlx5_core_dev *mdev = c->priv->mdev; | 1496 | struct mlx5_core_dev *mdev = c->priv->mdev; |
| 1505 | int err; | 1497 | int err; |
| 1506 | 1498 | ||
| 1507 | param->wq.buf_numa_node = mlx5e_get_node(c->priv, c->ix); | 1499 | param->wq.buf_numa_node = cpu_to_node(c->cpu); |
| 1508 | param->wq.db_numa_node = mlx5e_get_node(c->priv, c->ix); | 1500 | param->wq.db_numa_node = cpu_to_node(c->cpu); |
| 1509 | param->eq_ix = c->ix; | 1501 | param->eq_ix = c->ix; |
| 1510 | 1502 | ||
| 1511 | err = mlx5e_alloc_cq_common(mdev, param, cq); | 1503 | err = mlx5e_alloc_cq_common(mdev, param, cq); |
| @@ -1604,6 +1596,11 @@ static void mlx5e_close_cq(struct mlx5e_cq *cq) | |||
| 1604 | mlx5e_free_cq(cq); | 1596 | mlx5e_free_cq(cq); |
| 1605 | } | 1597 | } |
| 1606 | 1598 | ||
| 1599 | static int mlx5e_get_cpu(struct mlx5e_priv *priv, int ix) | ||
| 1600 | { | ||
| 1601 | return cpumask_first(priv->mdev->priv.irq_info[ix].mask); | ||
| 1602 | } | ||
| 1603 | |||
| 1607 | static int mlx5e_open_tx_cqs(struct mlx5e_channel *c, | 1604 | static int mlx5e_open_tx_cqs(struct mlx5e_channel *c, |
| 1608 | struct mlx5e_params *params, | 1605 | struct mlx5e_params *params, |
| 1609 | struct mlx5e_channel_param *cparam) | 1606 | struct mlx5e_channel_param *cparam) |
| @@ -1752,12 +1749,13 @@ static int mlx5e_open_channel(struct mlx5e_priv *priv, int ix, | |||
| 1752 | { | 1749 | { |
| 1753 | struct mlx5e_cq_moder icocq_moder = {0, 0}; | 1750 | struct mlx5e_cq_moder icocq_moder = {0, 0}; |
| 1754 | struct net_device *netdev = priv->netdev; | 1751 | struct net_device *netdev = priv->netdev; |
| 1752 | int cpu = mlx5e_get_cpu(priv, ix); | ||
| 1755 | struct mlx5e_channel *c; | 1753 | struct mlx5e_channel *c; |
| 1756 | unsigned int irq; | 1754 | unsigned int irq; |
| 1757 | int err; | 1755 | int err; |
| 1758 | int eqn; | 1756 | int eqn; |
| 1759 | 1757 | ||
| 1760 | c = kzalloc_node(sizeof(*c), GFP_KERNEL, mlx5e_get_node(priv, ix)); | 1758 | c = kzalloc_node(sizeof(*c), GFP_KERNEL, cpu_to_node(cpu)); |
| 1761 | if (!c) | 1759 | if (!c) |
| 1762 | return -ENOMEM; | 1760 | return -ENOMEM; |
| 1763 | 1761 | ||
| @@ -1765,6 +1763,7 @@ static int mlx5e_open_channel(struct mlx5e_priv *priv, int ix, | |||
| 1765 | c->mdev = priv->mdev; | 1763 | c->mdev = priv->mdev; |
| 1766 | c->tstamp = &priv->tstamp; | 1764 | c->tstamp = &priv->tstamp; |
| 1767 | c->ix = ix; | 1765 | c->ix = ix; |
| 1766 | c->cpu = cpu; | ||
| 1768 | c->pdev = &priv->mdev->pdev->dev; | 1767 | c->pdev = &priv->mdev->pdev->dev; |
| 1769 | c->netdev = priv->netdev; | 1768 | c->netdev = priv->netdev; |
| 1770 | c->mkey_be = cpu_to_be32(priv->mdev->mlx5e_res.mkey.key); | 1769 | c->mkey_be = cpu_to_be32(priv->mdev->mlx5e_res.mkey.key); |
| @@ -1853,8 +1852,7 @@ static void mlx5e_activate_channel(struct mlx5e_channel *c) | |||
| 1853 | for (tc = 0; tc < c->num_tc; tc++) | 1852 | for (tc = 0; tc < c->num_tc; tc++) |
| 1854 | mlx5e_activate_txqsq(&c->sq[tc]); | 1853 | mlx5e_activate_txqsq(&c->sq[tc]); |
| 1855 | mlx5e_activate_rq(&c->rq); | 1854 | mlx5e_activate_rq(&c->rq); |
| 1856 | netif_set_xps_queue(c->netdev, | 1855 | netif_set_xps_queue(c->netdev, get_cpu_mask(c->cpu), c->ix); |
| 1857 | mlx5_get_vector_affinity(c->priv->mdev, c->ix), c->ix); | ||
| 1858 | } | 1856 | } |
| 1859 | 1857 | ||
| 1860 | static void mlx5e_deactivate_channel(struct mlx5e_channel *c) | 1858 | static void mlx5e_deactivate_channel(struct mlx5e_channel *c) |
| @@ -3679,6 +3677,7 @@ static netdev_features_t mlx5e_tunnel_features_check(struct mlx5e_priv *priv, | |||
| 3679 | struct sk_buff *skb, | 3677 | struct sk_buff *skb, |
| 3680 | netdev_features_t features) | 3678 | netdev_features_t features) |
| 3681 | { | 3679 | { |
| 3680 | unsigned int offset = 0; | ||
| 3682 | struct udphdr *udph; | 3681 | struct udphdr *udph; |
| 3683 | u8 proto; | 3682 | u8 proto; |
| 3684 | u16 port; | 3683 | u16 port; |
| @@ -3688,7 +3687,7 @@ static netdev_features_t mlx5e_tunnel_features_check(struct mlx5e_priv *priv, | |||
| 3688 | proto = ip_hdr(skb)->protocol; | 3687 | proto = ip_hdr(skb)->protocol; |
| 3689 | break; | 3688 | break; |
| 3690 | case htons(ETH_P_IPV6): | 3689 | case htons(ETH_P_IPV6): |
| 3691 | proto = ipv6_hdr(skb)->nexthdr; | 3690 | proto = ipv6_find_hdr(skb, &offset, -1, NULL, NULL); |
| 3692 | break; | 3691 | break; |
| 3693 | default: | 3692 | default: |
| 3694 | goto out; | 3693 | goto out; |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eq.c b/drivers/net/ethernet/mellanox/mlx5/core/eq.c index 60771865c99c..e7e7cef2bde4 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/eq.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/eq.c | |||
| @@ -466,7 +466,7 @@ static irqreturn_t mlx5_eq_int(int irq, void *eq_ptr) | |||
| 466 | break; | 466 | break; |
| 467 | case MLX5_EVENT_TYPE_CQ_ERROR: | 467 | case MLX5_EVENT_TYPE_CQ_ERROR: |
| 468 | cqn = be32_to_cpu(eqe->data.cq_err.cqn) & 0xffffff; | 468 | cqn = be32_to_cpu(eqe->data.cq_err.cqn) & 0xffffff; |
| 469 | mlx5_core_warn(dev, "CQ error on CQN 0x%x, syndrom 0x%x\n", | 469 | mlx5_core_warn(dev, "CQ error on CQN 0x%x, syndrome 0x%x\n", |
| 470 | cqn, eqe->data.cq_err.syndrome); | 470 | cqn, eqe->data.cq_err.syndrome); |
| 471 | mlx5_cq_event(dev, cqn, eqe->type); | 471 | mlx5_cq_event(dev, cqn, eqe->type); |
| 472 | break; | 472 | break; |
| @@ -775,7 +775,7 @@ err1: | |||
| 775 | return err; | 775 | return err; |
| 776 | } | 776 | } |
| 777 | 777 | ||
| 778 | int mlx5_stop_eqs(struct mlx5_core_dev *dev) | 778 | void mlx5_stop_eqs(struct mlx5_core_dev *dev) |
| 779 | { | 779 | { |
| 780 | struct mlx5_eq_table *table = &dev->priv.eq_table; | 780 | struct mlx5_eq_table *table = &dev->priv.eq_table; |
| 781 | int err; | 781 | int err; |
| @@ -784,22 +784,26 @@ int mlx5_stop_eqs(struct mlx5_core_dev *dev) | |||
| 784 | if (MLX5_CAP_GEN(dev, pg)) { | 784 | if (MLX5_CAP_GEN(dev, pg)) { |
| 785 | err = mlx5_destroy_unmap_eq(dev, &table->pfault_eq); | 785 | err = mlx5_destroy_unmap_eq(dev, &table->pfault_eq); |
| 786 | if (err) | 786 | if (err) |
| 787 | return err; | 787 | mlx5_core_err(dev, "failed to destroy page fault eq, err(%d)\n", |
| 788 | err); | ||
| 788 | } | 789 | } |
| 789 | #endif | 790 | #endif |
| 790 | 791 | ||
| 791 | err = mlx5_destroy_unmap_eq(dev, &table->pages_eq); | 792 | err = mlx5_destroy_unmap_eq(dev, &table->pages_eq); |
| 792 | if (err) | 793 | if (err) |
| 793 | return err; | 794 | mlx5_core_err(dev, "failed to destroy pages eq, err(%d)\n", |
| 795 | err); | ||
| 794 | 796 | ||
| 795 | mlx5_destroy_unmap_eq(dev, &table->async_eq); | 797 | err = mlx5_destroy_unmap_eq(dev, &table->async_eq); |
| 798 | if (err) | ||
| 799 | mlx5_core_err(dev, "failed to destroy async eq, err(%d)\n", | ||
| 800 | err); | ||
| 796 | mlx5_cmd_use_polling(dev); | 801 | mlx5_cmd_use_polling(dev); |
| 797 | 802 | ||
| 798 | err = mlx5_destroy_unmap_eq(dev, &table->cmd_eq); | 803 | err = mlx5_destroy_unmap_eq(dev, &table->cmd_eq); |
| 799 | if (err) | 804 | if (err) |
| 800 | mlx5_cmd_use_events(dev); | 805 | mlx5_core_err(dev, "failed to destroy command eq, err(%d)\n", |
| 801 | 806 | err); | |
| 802 | return err; | ||
| 803 | } | 807 | } |
| 804 | 808 | ||
| 805 | int mlx5_core_eq_query(struct mlx5_core_dev *dev, struct mlx5_eq *eq, | 809 | int mlx5_core_eq_query(struct mlx5_core_dev *dev, struct mlx5_eq *eq, |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fpga/sdk.c b/drivers/net/ethernet/mellanox/mlx5/core/fpga/sdk.c index 3c11d6e2160a..14962969c5ba 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/fpga/sdk.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/fpga/sdk.c | |||
| @@ -66,6 +66,9 @@ static int mlx5_fpga_mem_read_i2c(struct mlx5_fpga_device *fdev, size_t size, | |||
| 66 | u8 actual_size; | 66 | u8 actual_size; |
| 67 | int err; | 67 | int err; |
| 68 | 68 | ||
| 69 | if (!size) | ||
| 70 | return -EINVAL; | ||
| 71 | |||
| 69 | if (!fdev->mdev) | 72 | if (!fdev->mdev) |
| 70 | return -ENOTCONN; | 73 | return -ENOTCONN; |
| 71 | 74 | ||
| @@ -95,6 +98,9 @@ static int mlx5_fpga_mem_write_i2c(struct mlx5_fpga_device *fdev, size_t size, | |||
| 95 | u8 actual_size; | 98 | u8 actual_size; |
| 96 | int err; | 99 | int err; |
| 97 | 100 | ||
| 101 | if (!size) | ||
| 102 | return -EINVAL; | ||
| 103 | |||
| 98 | if (!fdev->mdev) | 104 | if (!fdev->mdev) |
| 99 | return -ENOTCONN; | 105 | return -ENOTCONN; |
| 100 | 106 | ||
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c index c70fd663a633..dfaad9ecb2b8 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c | |||
| @@ -174,6 +174,8 @@ static void del_hw_fte(struct fs_node *node); | |||
| 174 | static void del_sw_flow_table(struct fs_node *node); | 174 | static void del_sw_flow_table(struct fs_node *node); |
| 175 | static void del_sw_flow_group(struct fs_node *node); | 175 | static void del_sw_flow_group(struct fs_node *node); |
| 176 | static void del_sw_fte(struct fs_node *node); | 176 | static void del_sw_fte(struct fs_node *node); |
| 177 | static void del_sw_prio(struct fs_node *node); | ||
| 178 | static void del_sw_ns(struct fs_node *node); | ||
| 177 | /* Delete rule (destination) is special case that | 179 | /* Delete rule (destination) is special case that |
| 178 | * requires to lock the FTE for all the deletion process. | 180 | * requires to lock the FTE for all the deletion process. |
| 179 | */ | 181 | */ |
| @@ -408,6 +410,16 @@ static inline struct mlx5_core_dev *get_dev(struct fs_node *node) | |||
| 408 | return NULL; | 410 | return NULL; |
| 409 | } | 411 | } |
| 410 | 412 | ||
| 413 | static void del_sw_ns(struct fs_node *node) | ||
| 414 | { | ||
| 415 | kfree(node); | ||
| 416 | } | ||
| 417 | |||
| 418 | static void del_sw_prio(struct fs_node *node) | ||
| 419 | { | ||
| 420 | kfree(node); | ||
| 421 | } | ||
| 422 | |||
| 411 | static void del_hw_flow_table(struct fs_node *node) | 423 | static void del_hw_flow_table(struct fs_node *node) |
| 412 | { | 424 | { |
| 413 | struct mlx5_flow_table *ft; | 425 | struct mlx5_flow_table *ft; |
| @@ -2064,7 +2076,7 @@ static struct fs_prio *fs_create_prio(struct mlx5_flow_namespace *ns, | |||
| 2064 | return ERR_PTR(-ENOMEM); | 2076 | return ERR_PTR(-ENOMEM); |
| 2065 | 2077 | ||
| 2066 | fs_prio->node.type = FS_TYPE_PRIO; | 2078 | fs_prio->node.type = FS_TYPE_PRIO; |
| 2067 | tree_init_node(&fs_prio->node, NULL, NULL); | 2079 | tree_init_node(&fs_prio->node, NULL, del_sw_prio); |
| 2068 | tree_add_node(&fs_prio->node, &ns->node); | 2080 | tree_add_node(&fs_prio->node, &ns->node); |
| 2069 | fs_prio->num_levels = num_levels; | 2081 | fs_prio->num_levels = num_levels; |
| 2070 | fs_prio->prio = prio; | 2082 | fs_prio->prio = prio; |
| @@ -2090,7 +2102,7 @@ static struct mlx5_flow_namespace *fs_create_namespace(struct fs_prio *prio) | |||
| 2090 | return ERR_PTR(-ENOMEM); | 2102 | return ERR_PTR(-ENOMEM); |
| 2091 | 2103 | ||
| 2092 | fs_init_namespace(ns); | 2104 | fs_init_namespace(ns); |
| 2093 | tree_init_node(&ns->node, NULL, NULL); | 2105 | tree_init_node(&ns->node, NULL, del_sw_ns); |
| 2094 | tree_add_node(&ns->node, &prio->node); | 2106 | tree_add_node(&ns->node, &prio->node); |
| 2095 | list_add_tail(&ns->node.list, &prio->node.children); | 2107 | list_add_tail(&ns->node.list, &prio->node.children); |
| 2096 | 2108 | ||
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/health.c b/drivers/net/ethernet/mellanox/mlx5/core/health.c index 1a0e797ad001..21d29f7936f6 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/health.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/health.c | |||
| @@ -241,7 +241,7 @@ static void print_health_info(struct mlx5_core_dev *dev) | |||
| 241 | u32 fw; | 241 | u32 fw; |
| 242 | int i; | 242 | int i; |
| 243 | 243 | ||
| 244 | /* If the syndrom is 0, the device is OK and no need to print buffer */ | 244 | /* If the syndrome is 0, the device is OK and no need to print buffer */ |
| 245 | if (!ioread8(&h->synd)) | 245 | if (!ioread8(&h->synd)) |
| 246 | return; | 246 | return; |
| 247 | 247 | ||
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c b/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c index d2a66dc4adc6..8812d7208e8f 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c | |||
| @@ -57,7 +57,7 @@ static void mlx5i_build_nic_params(struct mlx5_core_dev *mdev, | |||
| 57 | struct mlx5e_params *params) | 57 | struct mlx5e_params *params) |
| 58 | { | 58 | { |
| 59 | /* Override RQ params as IPoIB supports only LINKED LIST RQ for now */ | 59 | /* Override RQ params as IPoIB supports only LINKED LIST RQ for now */ |
| 60 | mlx5e_set_rq_type_params(mdev, params, MLX5_WQ_TYPE_LINKED_LIST); | 60 | mlx5e_init_rq_type_params(mdev, params, MLX5_WQ_TYPE_LINKED_LIST); |
| 61 | 61 | ||
| 62 | /* RQ size in ipoib by default is 512 */ | 62 | /* RQ size in ipoib by default is 512 */ |
| 63 | params->log_rq_size = is_kdump_kernel() ? | 63 | params->log_rq_size = is_kdump_kernel() ? |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lag.c b/drivers/net/ethernet/mellanox/mlx5/core/lag.c index f26f97fe4666..582b2f18010a 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/lag.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/lag.c | |||
| @@ -137,6 +137,17 @@ int mlx5_cmd_destroy_vport_lag(struct mlx5_core_dev *dev) | |||
| 137 | } | 137 | } |
| 138 | EXPORT_SYMBOL(mlx5_cmd_destroy_vport_lag); | 138 | EXPORT_SYMBOL(mlx5_cmd_destroy_vport_lag); |
| 139 | 139 | ||
| 140 | static int mlx5_cmd_query_cong_counter(struct mlx5_core_dev *dev, | ||
| 141 | bool reset, void *out, int out_size) | ||
| 142 | { | ||
| 143 | u32 in[MLX5_ST_SZ_DW(query_cong_statistics_in)] = { }; | ||
| 144 | |||
| 145 | MLX5_SET(query_cong_statistics_in, in, opcode, | ||
| 146 | MLX5_CMD_OP_QUERY_CONG_STATISTICS); | ||
| 147 | MLX5_SET(query_cong_statistics_in, in, clear, reset); | ||
| 148 | return mlx5_cmd_exec(dev, in, sizeof(in), out, out_size); | ||
| 149 | } | ||
| 150 | |||
| 140 | static struct mlx5_lag *mlx5_lag_dev_get(struct mlx5_core_dev *dev) | 151 | static struct mlx5_lag *mlx5_lag_dev_get(struct mlx5_core_dev *dev) |
| 141 | { | 152 | { |
| 142 | return dev->priv.lag; | 153 | return dev->priv.lag; |
| @@ -633,3 +644,48 @@ bool mlx5_lag_intf_add(struct mlx5_interface *intf, struct mlx5_priv *priv) | |||
| 633 | /* If bonded, we do not add an IB device for PF1. */ | 644 | /* If bonded, we do not add an IB device for PF1. */ |
| 634 | return false; | 645 | return false; |
| 635 | } | 646 | } |
| 647 | |||
| 648 | int mlx5_lag_query_cong_counters(struct mlx5_core_dev *dev, | ||
| 649 | u64 *values, | ||
| 650 | int num_counters, | ||
| 651 | size_t *offsets) | ||
| 652 | { | ||
| 653 | int outlen = MLX5_ST_SZ_BYTES(query_cong_statistics_out); | ||
| 654 | struct mlx5_core_dev *mdev[MLX5_MAX_PORTS]; | ||
| 655 | struct mlx5_lag *ldev; | ||
| 656 | int num_ports; | ||
| 657 | int ret, i, j; | ||
| 658 | void *out; | ||
| 659 | |||
| 660 | out = kvzalloc(outlen, GFP_KERNEL); | ||
| 661 | if (!out) | ||
| 662 | return -ENOMEM; | ||
| 663 | |||
| 664 | memset(values, 0, sizeof(*values) * num_counters); | ||
| 665 | |||
| 666 | mutex_lock(&lag_mutex); | ||
| 667 | ldev = mlx5_lag_dev_get(dev); | ||
| 668 | if (ldev && mlx5_lag_is_bonded(ldev)) { | ||
| 669 | num_ports = MLX5_MAX_PORTS; | ||
| 670 | mdev[0] = ldev->pf[0].dev; | ||
| 671 | mdev[1] = ldev->pf[1].dev; | ||
| 672 | } else { | ||
| 673 | num_ports = 1; | ||
| 674 | mdev[0] = dev; | ||
| 675 | } | ||
| 676 | |||
| 677 | for (i = 0; i < num_ports; ++i) { | ||
| 678 | ret = mlx5_cmd_query_cong_counter(mdev[i], false, out, outlen); | ||
| 679 | if (ret) | ||
| 680 | goto unlock; | ||
| 681 | |||
| 682 | for (j = 0; j < num_counters; ++j) | ||
| 683 | values[j] += be64_to_cpup((__be64 *)(out + offsets[j])); | ||
| 684 | } | ||
| 685 | |||
| 686 | unlock: | ||
| 687 | mutex_unlock(&lag_mutex); | ||
| 688 | kvfree(out); | ||
| 689 | return ret; | ||
| 690 | } | ||
| 691 | EXPORT_SYMBOL(mlx5_lag_query_cong_counters); | ||
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c index 5f323442cc5a..8a89c7e8cd63 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c | |||
| @@ -317,9 +317,6 @@ static int mlx5_alloc_irq_vectors(struct mlx5_core_dev *dev) | |||
| 317 | { | 317 | { |
| 318 | struct mlx5_priv *priv = &dev->priv; | 318 | struct mlx5_priv *priv = &dev->priv; |
| 319 | struct mlx5_eq_table *table = &priv->eq_table; | 319 | struct mlx5_eq_table *table = &priv->eq_table; |
| 320 | struct irq_affinity irqdesc = { | ||
| 321 | .pre_vectors = MLX5_EQ_VEC_COMP_BASE, | ||
| 322 | }; | ||
| 323 | int num_eqs = 1 << MLX5_CAP_GEN(dev, log_max_eq); | 320 | int num_eqs = 1 << MLX5_CAP_GEN(dev, log_max_eq); |
| 324 | int nvec; | 321 | int nvec; |
| 325 | 322 | ||
| @@ -333,10 +330,9 @@ static int mlx5_alloc_irq_vectors(struct mlx5_core_dev *dev) | |||
| 333 | if (!priv->irq_info) | 330 | if (!priv->irq_info) |
| 334 | goto err_free_msix; | 331 | goto err_free_msix; |
| 335 | 332 | ||
| 336 | nvec = pci_alloc_irq_vectors_affinity(dev->pdev, | 333 | nvec = pci_alloc_irq_vectors(dev->pdev, |
| 337 | MLX5_EQ_VEC_COMP_BASE + 1, nvec, | 334 | MLX5_EQ_VEC_COMP_BASE + 1, nvec, |
| 338 | PCI_IRQ_MSIX | PCI_IRQ_AFFINITY, | 335 | PCI_IRQ_MSIX); |
| 339 | &irqdesc); | ||
| 340 | if (nvec < 0) | 336 | if (nvec < 0) |
| 341 | return nvec; | 337 | return nvec; |
| 342 | 338 | ||
| @@ -622,6 +618,63 @@ u64 mlx5_read_internal_timer(struct mlx5_core_dev *dev) | |||
| 622 | return (u64)timer_l | (u64)timer_h1 << 32; | 618 | return (u64)timer_l | (u64)timer_h1 << 32; |
| 623 | } | 619 | } |
| 624 | 620 | ||
| 621 | static int mlx5_irq_set_affinity_hint(struct mlx5_core_dev *mdev, int i) | ||
| 622 | { | ||
| 623 | struct mlx5_priv *priv = &mdev->priv; | ||
| 624 | int irq = pci_irq_vector(mdev->pdev, MLX5_EQ_VEC_COMP_BASE + i); | ||
| 625 | |||
| 626 | if (!zalloc_cpumask_var(&priv->irq_info[i].mask, GFP_KERNEL)) { | ||
| 627 | mlx5_core_warn(mdev, "zalloc_cpumask_var failed"); | ||
| 628 | return -ENOMEM; | ||
| 629 | } | ||
| 630 | |||
| 631 | cpumask_set_cpu(cpumask_local_spread(i, priv->numa_node), | ||
| 632 | priv->irq_info[i].mask); | ||
| 633 | |||
| 634 | if (IS_ENABLED(CONFIG_SMP) && | ||
| 635 | irq_set_affinity_hint(irq, priv->irq_info[i].mask)) | ||
| 636 | mlx5_core_warn(mdev, "irq_set_affinity_hint failed, irq 0x%.4x", irq); | ||
| 637 | |||
| 638 | return 0; | ||
| 639 | } | ||
| 640 | |||
| 641 | static void mlx5_irq_clear_affinity_hint(struct mlx5_core_dev *mdev, int i) | ||
| 642 | { | ||
| 643 | struct mlx5_priv *priv = &mdev->priv; | ||
| 644 | int irq = pci_irq_vector(mdev->pdev, MLX5_EQ_VEC_COMP_BASE + i); | ||
| 645 | |||
| 646 | irq_set_affinity_hint(irq, NULL); | ||
| 647 | free_cpumask_var(priv->irq_info[i].mask); | ||
| 648 | } | ||
| 649 | |||
| 650 | static int mlx5_irq_set_affinity_hints(struct mlx5_core_dev *mdev) | ||
| 651 | { | ||
| 652 | int err; | ||
| 653 | int i; | ||
| 654 | |||
| 655 | for (i = 0; i < mdev->priv.eq_table.num_comp_vectors; i++) { | ||
| 656 | err = mlx5_irq_set_affinity_hint(mdev, i); | ||
| 657 | if (err) | ||
| 658 | goto err_out; | ||
| 659 | } | ||
| 660 | |||
| 661 | return 0; | ||
| 662 | |||
| 663 | err_out: | ||
| 664 | for (i--; i >= 0; i--) | ||
| 665 | mlx5_irq_clear_affinity_hint(mdev, i); | ||
| 666 | |||
| 667 | return err; | ||
| 668 | } | ||
| 669 | |||
| 670 | static void mlx5_irq_clear_affinity_hints(struct mlx5_core_dev *mdev) | ||
| 671 | { | ||
| 672 | int i; | ||
| 673 | |||
| 674 | for (i = 0; i < mdev->priv.eq_table.num_comp_vectors; i++) | ||
| 675 | mlx5_irq_clear_affinity_hint(mdev, i); | ||
| 676 | } | ||
| 677 | |||
| 625 | int mlx5_vector2eqn(struct mlx5_core_dev *dev, int vector, int *eqn, | 678 | int mlx5_vector2eqn(struct mlx5_core_dev *dev, int vector, int *eqn, |
| 626 | unsigned int *irqn) | 679 | unsigned int *irqn) |
| 627 | { | 680 | { |
| @@ -1097,6 +1150,12 @@ static int mlx5_load_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv, | |||
| 1097 | goto err_stop_eqs; | 1150 | goto err_stop_eqs; |
| 1098 | } | 1151 | } |
| 1099 | 1152 | ||
| 1153 | err = mlx5_irq_set_affinity_hints(dev); | ||
| 1154 | if (err) { | ||
| 1155 | dev_err(&pdev->dev, "Failed to alloc affinity hint cpumask\n"); | ||
| 1156 | goto err_affinity_hints; | ||
| 1157 | } | ||
| 1158 | |||
| 1100 | err = mlx5_init_fs(dev); | 1159 | err = mlx5_init_fs(dev); |
| 1101 | if (err) { | 1160 | if (err) { |
| 1102 | dev_err(&pdev->dev, "Failed to init flow steering\n"); | 1161 | dev_err(&pdev->dev, "Failed to init flow steering\n"); |
| @@ -1154,6 +1213,9 @@ err_sriov: | |||
| 1154 | mlx5_cleanup_fs(dev); | 1213 | mlx5_cleanup_fs(dev); |
| 1155 | 1214 | ||
| 1156 | err_fs: | 1215 | err_fs: |
| 1216 | mlx5_irq_clear_affinity_hints(dev); | ||
| 1217 | |||
| 1218 | err_affinity_hints: | ||
| 1157 | free_comp_eqs(dev); | 1219 | free_comp_eqs(dev); |
| 1158 | 1220 | ||
| 1159 | err_stop_eqs: | 1221 | err_stop_eqs: |
| @@ -1222,6 +1284,7 @@ static int mlx5_unload_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv, | |||
| 1222 | 1284 | ||
| 1223 | mlx5_sriov_detach(dev); | 1285 | mlx5_sriov_detach(dev); |
| 1224 | mlx5_cleanup_fs(dev); | 1286 | mlx5_cleanup_fs(dev); |
| 1287 | mlx5_irq_clear_affinity_hints(dev); | ||
| 1225 | free_comp_eqs(dev); | 1288 | free_comp_eqs(dev); |
| 1226 | mlx5_stop_eqs(dev); | 1289 | mlx5_stop_eqs(dev); |
| 1227 | mlx5_put_uars_page(dev, priv->uar); | 1290 | mlx5_put_uars_page(dev, priv->uar); |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/qp.c b/drivers/net/ethernet/mellanox/mlx5/core/qp.c index db9e665ab104..889130edb715 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/qp.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/qp.c | |||
| @@ -213,8 +213,8 @@ int mlx5_core_create_qp(struct mlx5_core_dev *dev, | |||
| 213 | err_cmd: | 213 | err_cmd: |
| 214 | memset(din, 0, sizeof(din)); | 214 | memset(din, 0, sizeof(din)); |
| 215 | memset(dout, 0, sizeof(dout)); | 215 | memset(dout, 0, sizeof(dout)); |
| 216 | MLX5_SET(destroy_qp_in, in, opcode, MLX5_CMD_OP_DESTROY_QP); | 216 | MLX5_SET(destroy_qp_in, din, opcode, MLX5_CMD_OP_DESTROY_QP); |
| 217 | MLX5_SET(destroy_qp_in, in, qpn, qp->qpn); | 217 | MLX5_SET(destroy_qp_in, din, qpn, qp->qpn); |
| 218 | mlx5_cmd_exec(dev, din, sizeof(din), dout, sizeof(dout)); | 218 | mlx5_cmd_exec(dev, din, sizeof(din), dout, sizeof(dout)); |
| 219 | return err; | 219 | return err; |
| 220 | } | 220 | } |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/rl.c b/drivers/net/ethernet/mellanox/mlx5/core/rl.c index e651e4c02867..d3c33e9eea72 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/rl.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/rl.c | |||
| @@ -125,16 +125,16 @@ static struct mlx5_rl_entry *find_rl_entry(struct mlx5_rl_table *table, | |||
| 125 | return ret_entry; | 125 | return ret_entry; |
| 126 | } | 126 | } |
| 127 | 127 | ||
| 128 | static int mlx5_set_rate_limit_cmd(struct mlx5_core_dev *dev, | 128 | static int mlx5_set_pp_rate_limit_cmd(struct mlx5_core_dev *dev, |
| 129 | u32 rate, u16 index) | 129 | u32 rate, u16 index) |
| 130 | { | 130 | { |
| 131 | u32 in[MLX5_ST_SZ_DW(set_rate_limit_in)] = {0}; | 131 | u32 in[MLX5_ST_SZ_DW(set_pp_rate_limit_in)] = {0}; |
| 132 | u32 out[MLX5_ST_SZ_DW(set_rate_limit_out)] = {0}; | 132 | u32 out[MLX5_ST_SZ_DW(set_pp_rate_limit_out)] = {0}; |
| 133 | 133 | ||
| 134 | MLX5_SET(set_rate_limit_in, in, opcode, | 134 | MLX5_SET(set_pp_rate_limit_in, in, opcode, |
| 135 | MLX5_CMD_OP_SET_RATE_LIMIT); | 135 | MLX5_CMD_OP_SET_PP_RATE_LIMIT); |
| 136 | MLX5_SET(set_rate_limit_in, in, rate_limit_index, index); | 136 | MLX5_SET(set_pp_rate_limit_in, in, rate_limit_index, index); |
| 137 | MLX5_SET(set_rate_limit_in, in, rate_limit, rate); | 137 | MLX5_SET(set_pp_rate_limit_in, in, rate_limit, rate); |
| 138 | return mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out)); | 138 | return mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out)); |
| 139 | } | 139 | } |
| 140 | 140 | ||
| @@ -173,7 +173,7 @@ int mlx5_rl_add_rate(struct mlx5_core_dev *dev, u32 rate, u16 *index) | |||
| 173 | entry->refcount++; | 173 | entry->refcount++; |
| 174 | } else { | 174 | } else { |
| 175 | /* new rate limit */ | 175 | /* new rate limit */ |
| 176 | err = mlx5_set_rate_limit_cmd(dev, rate, entry->index); | 176 | err = mlx5_set_pp_rate_limit_cmd(dev, rate, entry->index); |
| 177 | if (err) { | 177 | if (err) { |
| 178 | mlx5_core_err(dev, "Failed configuring rate: %u (%d)\n", | 178 | mlx5_core_err(dev, "Failed configuring rate: %u (%d)\n", |
| 179 | rate, err); | 179 | rate, err); |
| @@ -209,7 +209,7 @@ void mlx5_rl_remove_rate(struct mlx5_core_dev *dev, u32 rate) | |||
| 209 | entry->refcount--; | 209 | entry->refcount--; |
| 210 | if (!entry->refcount) { | 210 | if (!entry->refcount) { |
| 211 | /* need to remove rate */ | 211 | /* need to remove rate */ |
| 212 | mlx5_set_rate_limit_cmd(dev, 0, entry->index); | 212 | mlx5_set_pp_rate_limit_cmd(dev, 0, entry->index); |
| 213 | entry->rate = 0; | 213 | entry->rate = 0; |
| 214 | } | 214 | } |
| 215 | 215 | ||
| @@ -262,8 +262,8 @@ void mlx5_cleanup_rl_table(struct mlx5_core_dev *dev) | |||
| 262 | /* Clear all configured rates */ | 262 | /* Clear all configured rates */ |
| 263 | for (i = 0; i < table->max_size; i++) | 263 | for (i = 0; i < table->max_size; i++) |
| 264 | if (table->rl_entry[i].rate) | 264 | if (table->rl_entry[i].rate) |
| 265 | mlx5_set_rate_limit_cmd(dev, 0, | 265 | mlx5_set_pp_rate_limit_cmd(dev, 0, |
| 266 | table->rl_entry[i].index); | 266 | table->rl_entry[i].index); |
| 267 | 267 | ||
| 268 | kfree(dev->priv.rl_table.rl_entry); | 268 | kfree(dev->priv.rl_table.rl_entry); |
| 269 | } | 269 | } |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/vxlan.c b/drivers/net/ethernet/mellanox/mlx5/core/vxlan.c index 07a9ba6cfc70..2f74953e4561 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/vxlan.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/vxlan.c | |||
| @@ -71,9 +71,9 @@ struct mlx5e_vxlan *mlx5e_vxlan_lookup_port(struct mlx5e_priv *priv, u16 port) | |||
| 71 | struct mlx5e_vxlan_db *vxlan_db = &priv->vxlan; | 71 | struct mlx5e_vxlan_db *vxlan_db = &priv->vxlan; |
| 72 | struct mlx5e_vxlan *vxlan; | 72 | struct mlx5e_vxlan *vxlan; |
| 73 | 73 | ||
| 74 | spin_lock(&vxlan_db->lock); | 74 | spin_lock_bh(&vxlan_db->lock); |
| 75 | vxlan = radix_tree_lookup(&vxlan_db->tree, port); | 75 | vxlan = radix_tree_lookup(&vxlan_db->tree, port); |
| 76 | spin_unlock(&vxlan_db->lock); | 76 | spin_unlock_bh(&vxlan_db->lock); |
| 77 | 77 | ||
| 78 | return vxlan; | 78 | return vxlan; |
| 79 | } | 79 | } |
| @@ -88,8 +88,12 @@ static void mlx5e_vxlan_add_port(struct work_struct *work) | |||
| 88 | struct mlx5e_vxlan *vxlan; | 88 | struct mlx5e_vxlan *vxlan; |
| 89 | int err; | 89 | int err; |
| 90 | 90 | ||
| 91 | if (mlx5e_vxlan_lookup_port(priv, port)) | 91 | mutex_lock(&priv->state_lock); |
| 92 | vxlan = mlx5e_vxlan_lookup_port(priv, port); | ||
| 93 | if (vxlan) { | ||
| 94 | atomic_inc(&vxlan->refcount); | ||
| 92 | goto free_work; | 95 | goto free_work; |
| 96 | } | ||
| 93 | 97 | ||
| 94 | if (mlx5e_vxlan_core_add_port_cmd(priv->mdev, port)) | 98 | if (mlx5e_vxlan_core_add_port_cmd(priv->mdev, port)) |
| 95 | goto free_work; | 99 | goto free_work; |
| @@ -99,10 +103,11 @@ static void mlx5e_vxlan_add_port(struct work_struct *work) | |||
| 99 | goto err_delete_port; | 103 | goto err_delete_port; |
| 100 | 104 | ||
| 101 | vxlan->udp_port = port; | 105 | vxlan->udp_port = port; |
| 106 | atomic_set(&vxlan->refcount, 1); | ||
| 102 | 107 | ||
| 103 | spin_lock_irq(&vxlan_db->lock); | 108 | spin_lock_bh(&vxlan_db->lock); |
| 104 | err = radix_tree_insert(&vxlan_db->tree, vxlan->udp_port, vxlan); | 109 | err = radix_tree_insert(&vxlan_db->tree, vxlan->udp_port, vxlan); |
| 105 | spin_unlock_irq(&vxlan_db->lock); | 110 | spin_unlock_bh(&vxlan_db->lock); |
| 106 | if (err) | 111 | if (err) |
| 107 | goto err_free; | 112 | goto err_free; |
| 108 | 113 | ||
| @@ -113,35 +118,39 @@ err_free: | |||
| 113 | err_delete_port: | 118 | err_delete_port: |
| 114 | mlx5e_vxlan_core_del_port_cmd(priv->mdev, port); | 119 | mlx5e_vxlan_core_del_port_cmd(priv->mdev, port); |
| 115 | free_work: | 120 | free_work: |
| 121 | mutex_unlock(&priv->state_lock); | ||
| 116 | kfree(vxlan_work); | 122 | kfree(vxlan_work); |
| 117 | } | 123 | } |
| 118 | 124 | ||
| 119 | static void __mlx5e_vxlan_core_del_port(struct mlx5e_priv *priv, u16 port) | 125 | static void mlx5e_vxlan_del_port(struct work_struct *work) |
| 120 | { | 126 | { |
| 127 | struct mlx5e_vxlan_work *vxlan_work = | ||
| 128 | container_of(work, struct mlx5e_vxlan_work, work); | ||
| 129 | struct mlx5e_priv *priv = vxlan_work->priv; | ||
| 121 | struct mlx5e_vxlan_db *vxlan_db = &priv->vxlan; | 130 | struct mlx5e_vxlan_db *vxlan_db = &priv->vxlan; |
| 131 | u16 port = vxlan_work->port; | ||
| 122 | struct mlx5e_vxlan *vxlan; | 132 | struct mlx5e_vxlan *vxlan; |
| 133 | bool remove = false; | ||
| 123 | 134 | ||
| 124 | spin_lock_irq(&vxlan_db->lock); | 135 | mutex_lock(&priv->state_lock); |
| 125 | vxlan = radix_tree_delete(&vxlan_db->tree, port); | 136 | spin_lock_bh(&vxlan_db->lock); |
| 126 | spin_unlock_irq(&vxlan_db->lock); | 137 | vxlan = radix_tree_lookup(&vxlan_db->tree, port); |
| 127 | |||
| 128 | if (!vxlan) | 138 | if (!vxlan) |
| 129 | return; | 139 | goto out_unlock; |
| 130 | |||
| 131 | mlx5e_vxlan_core_del_port_cmd(priv->mdev, vxlan->udp_port); | ||
| 132 | |||
| 133 | kfree(vxlan); | ||
| 134 | } | ||
| 135 | 140 | ||
| 136 | static void mlx5e_vxlan_del_port(struct work_struct *work) | 141 | if (atomic_dec_and_test(&vxlan->refcount)) { |
| 137 | { | 142 | radix_tree_delete(&vxlan_db->tree, port); |
| 138 | struct mlx5e_vxlan_work *vxlan_work = | 143 | remove = true; |
| 139 | container_of(work, struct mlx5e_vxlan_work, work); | 144 | } |
| 140 | struct mlx5e_priv *priv = vxlan_work->priv; | ||
| 141 | u16 port = vxlan_work->port; | ||
| 142 | 145 | ||
| 143 | __mlx5e_vxlan_core_del_port(priv, port); | 146 | out_unlock: |
| 147 | spin_unlock_bh(&vxlan_db->lock); | ||
| 144 | 148 | ||
| 149 | if (remove) { | ||
| 150 | mlx5e_vxlan_core_del_port_cmd(priv->mdev, port); | ||
| 151 | kfree(vxlan); | ||
| 152 | } | ||
| 153 | mutex_unlock(&priv->state_lock); | ||
| 145 | kfree(vxlan_work); | 154 | kfree(vxlan_work); |
| 146 | } | 155 | } |
| 147 | 156 | ||
| @@ -171,12 +180,11 @@ void mlx5e_vxlan_cleanup(struct mlx5e_priv *priv) | |||
| 171 | struct mlx5e_vxlan *vxlan; | 180 | struct mlx5e_vxlan *vxlan; |
| 172 | unsigned int port = 0; | 181 | unsigned int port = 0; |
| 173 | 182 | ||
| 174 | spin_lock_irq(&vxlan_db->lock); | 183 | /* Lockless since we are the only radix-tree consumers, wq is disabled */ |
| 175 | while (radix_tree_gang_lookup(&vxlan_db->tree, (void **)&vxlan, port, 1)) { | 184 | while (radix_tree_gang_lookup(&vxlan_db->tree, (void **)&vxlan, port, 1)) { |
| 176 | port = vxlan->udp_port; | 185 | port = vxlan->udp_port; |
| 177 | spin_unlock_irq(&vxlan_db->lock); | 186 | radix_tree_delete(&vxlan_db->tree, port); |
| 178 | __mlx5e_vxlan_core_del_port(priv, (u16)port); | 187 | mlx5e_vxlan_core_del_port_cmd(priv->mdev, port); |
| 179 | spin_lock_irq(&vxlan_db->lock); | 188 | kfree(vxlan); |
| 180 | } | 189 | } |
| 181 | spin_unlock_irq(&vxlan_db->lock); | ||
| 182 | } | 190 | } |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/vxlan.h b/drivers/net/ethernet/mellanox/mlx5/core/vxlan.h index 5def12c048e3..5ef6ae7d568a 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/vxlan.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/vxlan.h | |||
| @@ -36,6 +36,7 @@ | |||
| 36 | #include "en.h" | 36 | #include "en.h" |
| 37 | 37 | ||
| 38 | struct mlx5e_vxlan { | 38 | struct mlx5e_vxlan { |
| 39 | atomic_t refcount; | ||
| 39 | u16 udp_port; | 40 | u16 udp_port; |
| 40 | }; | 41 | }; |
| 41 | 42 | ||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c index 2d0897b7d860..9bd8d28de152 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c | |||
| @@ -4300,6 +4300,7 @@ static int mlxsw_sp_port_stp_set(struct mlxsw_sp_port *mlxsw_sp_port, | |||
| 4300 | 4300 | ||
| 4301 | static int mlxsw_sp_port_ovs_join(struct mlxsw_sp_port *mlxsw_sp_port) | 4301 | static int mlxsw_sp_port_ovs_join(struct mlxsw_sp_port *mlxsw_sp_port) |
| 4302 | { | 4302 | { |
| 4303 | u16 vid = 1; | ||
| 4303 | int err; | 4304 | int err; |
| 4304 | 4305 | ||
| 4305 | err = mlxsw_sp_port_vp_mode_set(mlxsw_sp_port, true); | 4306 | err = mlxsw_sp_port_vp_mode_set(mlxsw_sp_port, true); |
| @@ -4312,8 +4313,19 @@ static int mlxsw_sp_port_ovs_join(struct mlxsw_sp_port *mlxsw_sp_port) | |||
| 4312 | true, false); | 4313 | true, false); |
| 4313 | if (err) | 4314 | if (err) |
| 4314 | goto err_port_vlan_set; | 4315 | goto err_port_vlan_set; |
| 4316 | |||
| 4317 | for (; vid <= VLAN_N_VID - 1; vid++) { | ||
| 4318 | err = mlxsw_sp_port_vid_learning_set(mlxsw_sp_port, | ||
| 4319 | vid, false); | ||
| 4320 | if (err) | ||
| 4321 | goto err_vid_learning_set; | ||
| 4322 | } | ||
| 4323 | |||
| 4315 | return 0; | 4324 | return 0; |
| 4316 | 4325 | ||
| 4326 | err_vid_learning_set: | ||
| 4327 | for (vid--; vid >= 1; vid--) | ||
| 4328 | mlxsw_sp_port_vid_learning_set(mlxsw_sp_port, vid, true); | ||
| 4317 | err_port_vlan_set: | 4329 | err_port_vlan_set: |
| 4318 | mlxsw_sp_port_stp_set(mlxsw_sp_port, false); | 4330 | mlxsw_sp_port_stp_set(mlxsw_sp_port, false); |
| 4319 | err_port_stp_set: | 4331 | err_port_stp_set: |
| @@ -4323,6 +4335,12 @@ err_port_stp_set: | |||
| 4323 | 4335 | ||
| 4324 | static void mlxsw_sp_port_ovs_leave(struct mlxsw_sp_port *mlxsw_sp_port) | 4336 | static void mlxsw_sp_port_ovs_leave(struct mlxsw_sp_port *mlxsw_sp_port) |
| 4325 | { | 4337 | { |
| 4338 | u16 vid; | ||
| 4339 | |||
| 4340 | for (vid = VLAN_N_VID - 1; vid >= 1; vid--) | ||
| 4341 | mlxsw_sp_port_vid_learning_set(mlxsw_sp_port, | ||
| 4342 | vid, true); | ||
| 4343 | |||
| 4326 | mlxsw_sp_port_vlan_set(mlxsw_sp_port, 2, VLAN_N_VID - 1, | 4344 | mlxsw_sp_port_vlan_set(mlxsw_sp_port, 2, VLAN_N_VID - 1, |
| 4327 | false, false); | 4345 | false, false); |
| 4328 | mlxsw_sp_port_stp_set(mlxsw_sp_port, false); | 4346 | mlxsw_sp_port_stp_set(mlxsw_sp_port, false); |
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c index 72ef4f8025f0..be657b8533f0 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c | |||
| @@ -2436,25 +2436,16 @@ static void mlxsw_sp_neigh_fini(struct mlxsw_sp *mlxsw_sp) | |||
| 2436 | rhashtable_destroy(&mlxsw_sp->router->neigh_ht); | 2436 | rhashtable_destroy(&mlxsw_sp->router->neigh_ht); |
| 2437 | } | 2437 | } |
| 2438 | 2438 | ||
| 2439 | static int mlxsw_sp_neigh_rif_flush(struct mlxsw_sp *mlxsw_sp, | ||
| 2440 | const struct mlxsw_sp_rif *rif) | ||
| 2441 | { | ||
| 2442 | char rauht_pl[MLXSW_REG_RAUHT_LEN]; | ||
| 2443 | |||
| 2444 | mlxsw_reg_rauht_pack(rauht_pl, MLXSW_REG_RAUHT_OP_WRITE_DELETE_ALL, | ||
| 2445 | rif->rif_index, rif->addr); | ||
| 2446 | return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(rauht), rauht_pl); | ||
| 2447 | } | ||
| 2448 | |||
| 2449 | static void mlxsw_sp_neigh_rif_gone_sync(struct mlxsw_sp *mlxsw_sp, | 2439 | static void mlxsw_sp_neigh_rif_gone_sync(struct mlxsw_sp *mlxsw_sp, |
| 2450 | struct mlxsw_sp_rif *rif) | 2440 | struct mlxsw_sp_rif *rif) |
| 2451 | { | 2441 | { |
| 2452 | struct mlxsw_sp_neigh_entry *neigh_entry, *tmp; | 2442 | struct mlxsw_sp_neigh_entry *neigh_entry, *tmp; |
| 2453 | 2443 | ||
| 2454 | mlxsw_sp_neigh_rif_flush(mlxsw_sp, rif); | ||
| 2455 | list_for_each_entry_safe(neigh_entry, tmp, &rif->neigh_list, | 2444 | list_for_each_entry_safe(neigh_entry, tmp, &rif->neigh_list, |
| 2456 | rif_list_node) | 2445 | rif_list_node) { |
| 2446 | mlxsw_sp_neigh_entry_update(mlxsw_sp, neigh_entry, false); | ||
| 2457 | mlxsw_sp_neigh_entry_destroy(mlxsw_sp, neigh_entry); | 2447 | mlxsw_sp_neigh_entry_destroy(mlxsw_sp, neigh_entry); |
| 2448 | } | ||
| 2458 | } | 2449 | } |
| 2459 | 2450 | ||
| 2460 | enum mlxsw_sp_nexthop_type { | 2451 | enum mlxsw_sp_nexthop_type { |
diff --git a/drivers/net/ethernet/netronome/nfp/bpf/main.c b/drivers/net/ethernet/netronome/nfp/bpf/main.c index e379b78e86ef..13190aa09faf 100644 --- a/drivers/net/ethernet/netronome/nfp/bpf/main.c +++ b/drivers/net/ethernet/netronome/nfp/bpf/main.c | |||
| @@ -82,10 +82,33 @@ static const char *nfp_bpf_extra_cap(struct nfp_app *app, struct nfp_net *nn) | |||
| 82 | return nfp_net_ebpf_capable(nn) ? "BPF" : ""; | 82 | return nfp_net_ebpf_capable(nn) ? "BPF" : ""; |
| 83 | } | 83 | } |
| 84 | 84 | ||
| 85 | static int | ||
| 86 | nfp_bpf_vnic_alloc(struct nfp_app *app, struct nfp_net *nn, unsigned int id) | ||
| 87 | { | ||
| 88 | int err; | ||
| 89 | |||
| 90 | nn->app_priv = kzalloc(sizeof(struct nfp_bpf_vnic), GFP_KERNEL); | ||
| 91 | if (!nn->app_priv) | ||
| 92 | return -ENOMEM; | ||
| 93 | |||
| 94 | err = nfp_app_nic_vnic_alloc(app, nn, id); | ||
| 95 | if (err) | ||
| 96 | goto err_free_priv; | ||
| 97 | |||
| 98 | return 0; | ||
| 99 | err_free_priv: | ||
| 100 | kfree(nn->app_priv); | ||
| 101 | return err; | ||
| 102 | } | ||
| 103 | |||
| 85 | static void nfp_bpf_vnic_free(struct nfp_app *app, struct nfp_net *nn) | 104 | static void nfp_bpf_vnic_free(struct nfp_app *app, struct nfp_net *nn) |
| 86 | { | 105 | { |
| 106 | struct nfp_bpf_vnic *bv = nn->app_priv; | ||
| 107 | |||
| 87 | if (nn->dp.bpf_offload_xdp) | 108 | if (nn->dp.bpf_offload_xdp) |
| 88 | nfp_bpf_xdp_offload(app, nn, NULL); | 109 | nfp_bpf_xdp_offload(app, nn, NULL); |
| 110 | WARN_ON(bv->tc_prog); | ||
| 111 | kfree(bv); | ||
| 89 | } | 112 | } |
| 90 | 113 | ||
| 91 | static int nfp_bpf_setup_tc_block_cb(enum tc_setup_type type, | 114 | static int nfp_bpf_setup_tc_block_cb(enum tc_setup_type type, |
| @@ -93,6 +116,9 @@ static int nfp_bpf_setup_tc_block_cb(enum tc_setup_type type, | |||
| 93 | { | 116 | { |
| 94 | struct tc_cls_bpf_offload *cls_bpf = type_data; | 117 | struct tc_cls_bpf_offload *cls_bpf = type_data; |
| 95 | struct nfp_net *nn = cb_priv; | 118 | struct nfp_net *nn = cb_priv; |
| 119 | struct bpf_prog *oldprog; | ||
| 120 | struct nfp_bpf_vnic *bv; | ||
| 121 | int err; | ||
| 96 | 122 | ||
| 97 | if (type != TC_SETUP_CLSBPF || | 123 | if (type != TC_SETUP_CLSBPF || |
| 98 | !tc_can_offload(nn->dp.netdev) || | 124 | !tc_can_offload(nn->dp.netdev) || |
| @@ -100,8 +126,6 @@ static int nfp_bpf_setup_tc_block_cb(enum tc_setup_type type, | |||
| 100 | cls_bpf->common.protocol != htons(ETH_P_ALL) || | 126 | cls_bpf->common.protocol != htons(ETH_P_ALL) || |
| 101 | cls_bpf->common.chain_index) | 127 | cls_bpf->common.chain_index) |
| 102 | return -EOPNOTSUPP; | 128 | return -EOPNOTSUPP; |
| 103 | if (nn->dp.bpf_offload_xdp) | ||
| 104 | return -EBUSY; | ||
| 105 | 129 | ||
| 106 | /* Only support TC direct action */ | 130 | /* Only support TC direct action */ |
| 107 | if (!cls_bpf->exts_integrated || | 131 | if (!cls_bpf->exts_integrated || |
| @@ -110,16 +134,25 @@ static int nfp_bpf_setup_tc_block_cb(enum tc_setup_type type, | |||
| 110 | return -EOPNOTSUPP; | 134 | return -EOPNOTSUPP; |
| 111 | } | 135 | } |
| 112 | 136 | ||
| 113 | switch (cls_bpf->command) { | 137 | if (cls_bpf->command != TC_CLSBPF_OFFLOAD) |
| 114 | case TC_CLSBPF_REPLACE: | ||
| 115 | return nfp_net_bpf_offload(nn, cls_bpf->prog, true); | ||
| 116 | case TC_CLSBPF_ADD: | ||
| 117 | return nfp_net_bpf_offload(nn, cls_bpf->prog, false); | ||
| 118 | case TC_CLSBPF_DESTROY: | ||
| 119 | return nfp_net_bpf_offload(nn, NULL, true); | ||
| 120 | default: | ||
| 121 | return -EOPNOTSUPP; | 138 | return -EOPNOTSUPP; |
| 139 | |||
| 140 | bv = nn->app_priv; | ||
| 141 | oldprog = cls_bpf->oldprog; | ||
| 142 | |||
| 143 | /* Don't remove if oldprog doesn't match driver's state */ | ||
| 144 | if (bv->tc_prog != oldprog) { | ||
| 145 | oldprog = NULL; | ||
| 146 | if (!cls_bpf->prog) | ||
| 147 | return 0; | ||
| 122 | } | 148 | } |
| 149 | |||
| 150 | err = nfp_net_bpf_offload(nn, cls_bpf->prog, oldprog); | ||
| 151 | if (err) | ||
| 152 | return err; | ||
| 153 | |||
| 154 | bv->tc_prog = cls_bpf->prog; | ||
| 155 | return 0; | ||
| 123 | } | 156 | } |
| 124 | 157 | ||
| 125 | static int nfp_bpf_setup_tc_block(struct net_device *netdev, | 158 | static int nfp_bpf_setup_tc_block(struct net_device *netdev, |
| @@ -167,7 +200,7 @@ const struct nfp_app_type app_bpf = { | |||
| 167 | 200 | ||
| 168 | .extra_cap = nfp_bpf_extra_cap, | 201 | .extra_cap = nfp_bpf_extra_cap, |
| 169 | 202 | ||
| 170 | .vnic_alloc = nfp_app_nic_vnic_alloc, | 203 | .vnic_alloc = nfp_bpf_vnic_alloc, |
| 171 | .vnic_free = nfp_bpf_vnic_free, | 204 | .vnic_free = nfp_bpf_vnic_free, |
| 172 | 205 | ||
| 173 | .setup_tc = nfp_bpf_setup_tc, | 206 | .setup_tc = nfp_bpf_setup_tc, |
diff --git a/drivers/net/ethernet/netronome/nfp/bpf/main.h b/drivers/net/ethernet/netronome/nfp/bpf/main.h index 082a15f6dfb5..57b6043177a3 100644 --- a/drivers/net/ethernet/netronome/nfp/bpf/main.h +++ b/drivers/net/ethernet/netronome/nfp/bpf/main.h | |||
| @@ -172,6 +172,14 @@ struct nfp_prog { | |||
| 172 | struct list_head insns; | 172 | struct list_head insns; |
| 173 | }; | 173 | }; |
| 174 | 174 | ||
| 175 | /** | ||
| 176 | * struct nfp_bpf_vnic - per-vNIC BPF priv structure | ||
| 177 | * @tc_prog: currently loaded cls_bpf program | ||
| 178 | */ | ||
| 179 | struct nfp_bpf_vnic { | ||
| 180 | struct bpf_prog *tc_prog; | ||
| 181 | }; | ||
| 182 | |||
| 175 | int nfp_bpf_jit(struct nfp_prog *prog); | 183 | int nfp_bpf_jit(struct nfp_prog *prog); |
| 176 | 184 | ||
| 177 | extern const struct bpf_ext_analyzer_ops nfp_bpf_analyzer_ops; | 185 | extern const struct bpf_ext_analyzer_ops nfp_bpf_analyzer_ops; |
diff --git a/drivers/net/ethernet/qualcomm/emac/emac-phy.c b/drivers/net/ethernet/qualcomm/emac/emac-phy.c index 18461fcb9815..53dbf1e163a8 100644 --- a/drivers/net/ethernet/qualcomm/emac/emac-phy.c +++ b/drivers/net/ethernet/qualcomm/emac/emac-phy.c | |||
| @@ -47,6 +47,7 @@ | |||
| 47 | #define MDIO_CLK_25_28 7 | 47 | #define MDIO_CLK_25_28 7 |
| 48 | 48 | ||
| 49 | #define MDIO_WAIT_TIMES 1000 | 49 | #define MDIO_WAIT_TIMES 1000 |
| 50 | #define MDIO_STATUS_DELAY_TIME 1 | ||
| 50 | 51 | ||
| 51 | static int emac_mdio_read(struct mii_bus *bus, int addr, int regnum) | 52 | static int emac_mdio_read(struct mii_bus *bus, int addr, int regnum) |
| 52 | { | 53 | { |
| @@ -65,7 +66,7 @@ static int emac_mdio_read(struct mii_bus *bus, int addr, int regnum) | |||
| 65 | 66 | ||
| 66 | if (readl_poll_timeout(adpt->base + EMAC_MDIO_CTRL, reg, | 67 | if (readl_poll_timeout(adpt->base + EMAC_MDIO_CTRL, reg, |
| 67 | !(reg & (MDIO_START | MDIO_BUSY)), | 68 | !(reg & (MDIO_START | MDIO_BUSY)), |
| 68 | 100, MDIO_WAIT_TIMES * 100)) | 69 | MDIO_STATUS_DELAY_TIME, MDIO_WAIT_TIMES * 100)) |
| 69 | return -EIO; | 70 | return -EIO; |
| 70 | 71 | ||
| 71 | return (reg >> MDIO_DATA_SHFT) & MDIO_DATA_BMSK; | 72 | return (reg >> MDIO_DATA_SHFT) & MDIO_DATA_BMSK; |
| @@ -88,8 +89,8 @@ static int emac_mdio_write(struct mii_bus *bus, int addr, int regnum, u16 val) | |||
| 88 | writel(reg, adpt->base + EMAC_MDIO_CTRL); | 89 | writel(reg, adpt->base + EMAC_MDIO_CTRL); |
| 89 | 90 | ||
| 90 | if (readl_poll_timeout(adpt->base + EMAC_MDIO_CTRL, reg, | 91 | if (readl_poll_timeout(adpt->base + EMAC_MDIO_CTRL, reg, |
| 91 | !(reg & (MDIO_START | MDIO_BUSY)), 100, | 92 | !(reg & (MDIO_START | MDIO_BUSY)), |
| 92 | MDIO_WAIT_TIMES * 100)) | 93 | MDIO_STATUS_DELAY_TIME, MDIO_WAIT_TIMES * 100)) |
| 93 | return -EIO; | 94 | return -EIO; |
| 94 | 95 | ||
| 95 | return 0; | 96 | return 0; |
diff --git a/drivers/net/ethernet/qualcomm/emac/emac.c b/drivers/net/ethernet/qualcomm/emac/emac.c index 70c92b649b29..38c924bdd32e 100644 --- a/drivers/net/ethernet/qualcomm/emac/emac.c +++ b/drivers/net/ethernet/qualcomm/emac/emac.c | |||
| @@ -253,18 +253,18 @@ static int emac_open(struct net_device *netdev) | |||
| 253 | return ret; | 253 | return ret; |
| 254 | } | 254 | } |
| 255 | 255 | ||
| 256 | ret = emac_mac_up(adpt); | 256 | ret = adpt->phy.open(adpt); |
| 257 | if (ret) { | 257 | if (ret) { |
| 258 | emac_mac_rx_tx_rings_free_all(adpt); | 258 | emac_mac_rx_tx_rings_free_all(adpt); |
| 259 | free_irq(irq->irq, irq); | 259 | free_irq(irq->irq, irq); |
| 260 | return ret; | 260 | return ret; |
| 261 | } | 261 | } |
| 262 | 262 | ||
| 263 | ret = adpt->phy.open(adpt); | 263 | ret = emac_mac_up(adpt); |
| 264 | if (ret) { | 264 | if (ret) { |
| 265 | emac_mac_down(adpt); | ||
| 266 | emac_mac_rx_tx_rings_free_all(adpt); | 265 | emac_mac_rx_tx_rings_free_all(adpt); |
| 267 | free_irq(irq->irq, irq); | 266 | free_irq(irq->irq, irq); |
| 267 | adpt->phy.close(adpt); | ||
| 268 | return ret; | 268 | return ret; |
| 269 | } | 269 | } |
| 270 | 270 | ||
diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c index 2b962d349f5f..009780df664b 100644 --- a/drivers/net/ethernet/renesas/ravb_main.c +++ b/drivers/net/ethernet/renesas/ravb_main.c | |||
| @@ -2308,32 +2308,9 @@ static int __maybe_unused ravb_resume(struct device *dev) | |||
| 2308 | struct ravb_private *priv = netdev_priv(ndev); | 2308 | struct ravb_private *priv = netdev_priv(ndev); |
| 2309 | int ret = 0; | 2309 | int ret = 0; |
| 2310 | 2310 | ||
| 2311 | if (priv->wol_enabled) { | 2311 | /* If WoL is enabled set reset mode to rearm the WoL logic */ |
| 2312 | /* Reduce the usecount of the clock to zero and then | 2312 | if (priv->wol_enabled) |
| 2313 | * restore it to its original value. This is done to force | ||
| 2314 | * the clock to be re-enabled which is a workaround | ||
| 2315 | * for renesas-cpg-mssr driver which do not enable clocks | ||
| 2316 | * when resuming from PSCI suspend/resume. | ||
| 2317 | * | ||
| 2318 | * Without this workaround the driver fails to communicate | ||
| 2319 | * with the hardware if WoL was enabled when the system | ||
| 2320 | * entered PSCI suspend. This is due to that if WoL is enabled | ||
| 2321 | * we explicitly keep the clock from being turned off when | ||
| 2322 | * suspending, but in PSCI sleep power is cut so the clock | ||
| 2323 | * is disabled anyhow, the clock driver is not aware of this | ||
| 2324 | * so the clock is not turned back on when resuming. | ||
| 2325 | * | ||
| 2326 | * TODO: once the renesas-cpg-mssr suspend/resume is working | ||
| 2327 | * this clock dance should be removed. | ||
| 2328 | */ | ||
| 2329 | clk_disable(priv->clk); | ||
| 2330 | clk_disable(priv->clk); | ||
| 2331 | clk_enable(priv->clk); | ||
| 2332 | clk_enable(priv->clk); | ||
| 2333 | |||
| 2334 | /* Set reset mode to rearm the WoL logic */ | ||
| 2335 | ravb_write(ndev, CCC_OPC_RESET, CCC); | 2313 | ravb_write(ndev, CCC_OPC_RESET, CCC); |
| 2336 | } | ||
| 2337 | 2314 | ||
| 2338 | /* All register have been reset to default values. | 2315 | /* All register have been reset to default values. |
| 2339 | * Restore all registers which where setup at probe time and | 2316 | * Restore all registers which where setup at probe time and |
diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index db72d13cebb9..75323000c364 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c | |||
| @@ -1892,6 +1892,16 @@ static int sh_eth_phy_init(struct net_device *ndev) | |||
| 1892 | return PTR_ERR(phydev); | 1892 | return PTR_ERR(phydev); |
| 1893 | } | 1893 | } |
| 1894 | 1894 | ||
| 1895 | /* mask with MAC supported features */ | ||
| 1896 | if (mdp->cd->register_type != SH_ETH_REG_GIGABIT) { | ||
| 1897 | int err = phy_set_max_speed(phydev, SPEED_100); | ||
| 1898 | if (err) { | ||
| 1899 | netdev_err(ndev, "failed to limit PHY to 100 Mbit/s\n"); | ||
| 1900 | phy_disconnect(phydev); | ||
| 1901 | return err; | ||
| 1902 | } | ||
| 1903 | } | ||
| 1904 | |||
| 1895 | phy_attached_info(phydev); | 1905 | phy_attached_info(phydev); |
| 1896 | 1906 | ||
| 1897 | return 0; | 1907 | return 0; |
diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h index e1e5ac053760..ce2ea2d491ac 100644 --- a/drivers/net/ethernet/stmicro/stmmac/common.h +++ b/drivers/net/ethernet/stmicro/stmmac/common.h | |||
| @@ -409,7 +409,7 @@ struct stmmac_desc_ops { | |||
| 409 | /* get timestamp value */ | 409 | /* get timestamp value */ |
| 410 | u64(*get_timestamp) (void *desc, u32 ats); | 410 | u64(*get_timestamp) (void *desc, u32 ats); |
| 411 | /* get rx timestamp status */ | 411 | /* get rx timestamp status */ |
| 412 | int (*get_rx_timestamp_status) (void *desc, u32 ats); | 412 | int (*get_rx_timestamp_status)(void *desc, void *next_desc, u32 ats); |
| 413 | /* Display ring */ | 413 | /* Display ring */ |
| 414 | void (*display_ring)(void *head, unsigned int size, bool rx); | 414 | void (*display_ring)(void *head, unsigned int size, bool rx); |
| 415 | /* set MSS via context descriptor */ | 415 | /* set MSS via context descriptor */ |
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c index 4b286e27c4ca..7e089bf906b4 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c | |||
| @@ -258,7 +258,8 @@ static int dwmac4_rx_check_timestamp(void *desc) | |||
| 258 | return ret; | 258 | return ret; |
| 259 | } | 259 | } |
| 260 | 260 | ||
| 261 | static int dwmac4_wrback_get_rx_timestamp_status(void *desc, u32 ats) | 261 | static int dwmac4_wrback_get_rx_timestamp_status(void *desc, void *next_desc, |
| 262 | u32 ats) | ||
| 262 | { | 263 | { |
| 263 | struct dma_desc *p = (struct dma_desc *)desc; | 264 | struct dma_desc *p = (struct dma_desc *)desc; |
| 264 | int ret = -EINVAL; | 265 | int ret = -EINVAL; |
| @@ -270,7 +271,7 @@ static int dwmac4_wrback_get_rx_timestamp_status(void *desc, u32 ats) | |||
| 270 | 271 | ||
| 271 | /* Check if timestamp is OK from context descriptor */ | 272 | /* Check if timestamp is OK from context descriptor */ |
| 272 | do { | 273 | do { |
| 273 | ret = dwmac4_rx_check_timestamp(desc); | 274 | ret = dwmac4_rx_check_timestamp(next_desc); |
| 274 | if (ret < 0) | 275 | if (ret < 0) |
| 275 | goto exit; | 276 | goto exit; |
| 276 | i++; | 277 | i++; |
diff --git a/drivers/net/ethernet/stmicro/stmmac/enh_desc.c b/drivers/net/ethernet/stmicro/stmmac/enh_desc.c index 7546b3664113..2a828a312814 100644 --- a/drivers/net/ethernet/stmicro/stmmac/enh_desc.c +++ b/drivers/net/ethernet/stmicro/stmmac/enh_desc.c | |||
| @@ -400,7 +400,8 @@ static u64 enh_desc_get_timestamp(void *desc, u32 ats) | |||
| 400 | return ns; | 400 | return ns; |
| 401 | } | 401 | } |
| 402 | 402 | ||
| 403 | static int enh_desc_get_rx_timestamp_status(void *desc, u32 ats) | 403 | static int enh_desc_get_rx_timestamp_status(void *desc, void *next_desc, |
| 404 | u32 ats) | ||
| 404 | { | 405 | { |
| 405 | if (ats) { | 406 | if (ats) { |
| 406 | struct dma_extended_desc *p = (struct dma_extended_desc *)desc; | 407 | struct dma_extended_desc *p = (struct dma_extended_desc *)desc; |
diff --git a/drivers/net/ethernet/stmicro/stmmac/norm_desc.c b/drivers/net/ethernet/stmicro/stmmac/norm_desc.c index f817f8f36569..db4cee57bb24 100644 --- a/drivers/net/ethernet/stmicro/stmmac/norm_desc.c +++ b/drivers/net/ethernet/stmicro/stmmac/norm_desc.c | |||
| @@ -265,7 +265,7 @@ static u64 ndesc_get_timestamp(void *desc, u32 ats) | |||
| 265 | return ns; | 265 | return ns; |
| 266 | } | 266 | } |
| 267 | 267 | ||
| 268 | static int ndesc_get_rx_timestamp_status(void *desc, u32 ats) | 268 | static int ndesc_get_rx_timestamp_status(void *desc, void *next_desc, u32 ats) |
| 269 | { | 269 | { |
| 270 | struct dma_desc *p = (struct dma_desc *)desc; | 270 | struct dma_desc *p = (struct dma_desc *)desc; |
| 271 | 271 | ||
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c index 721b61655261..08c19ebd5306 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c | |||
| @@ -34,6 +34,7 @@ static u32 stmmac_config_sub_second_increment(void __iomem *ioaddr, | |||
| 34 | { | 34 | { |
| 35 | u32 value = readl(ioaddr + PTP_TCR); | 35 | u32 value = readl(ioaddr + PTP_TCR); |
| 36 | unsigned long data; | 36 | unsigned long data; |
| 37 | u32 reg_value; | ||
| 37 | 38 | ||
| 38 | /* For GMAC3.x, 4.x versions, convert the ptp_clock to nano second | 39 | /* For GMAC3.x, 4.x versions, convert the ptp_clock to nano second |
| 39 | * formula = (1/ptp_clock) * 1000000000 | 40 | * formula = (1/ptp_clock) * 1000000000 |
| @@ -50,10 +51,11 @@ static u32 stmmac_config_sub_second_increment(void __iomem *ioaddr, | |||
| 50 | 51 | ||
| 51 | data &= PTP_SSIR_SSINC_MASK; | 52 | data &= PTP_SSIR_SSINC_MASK; |
| 52 | 53 | ||
| 54 | reg_value = data; | ||
| 53 | if (gmac4) | 55 | if (gmac4) |
| 54 | data = data << GMAC4_PTP_SSIR_SSINC_SHIFT; | 56 | reg_value <<= GMAC4_PTP_SSIR_SSINC_SHIFT; |
| 55 | 57 | ||
| 56 | writel(data, ioaddr + PTP_SSIR); | 58 | writel(reg_value, ioaddr + PTP_SSIR); |
| 57 | 59 | ||
| 58 | return data; | 60 | return data; |
| 59 | } | 61 | } |
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index d7250539d0bd..337d53d12e94 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | |||
| @@ -482,7 +482,7 @@ static void stmmac_get_rx_hwtstamp(struct stmmac_priv *priv, struct dma_desc *p, | |||
| 482 | desc = np; | 482 | desc = np; |
| 483 | 483 | ||
| 484 | /* Check if timestamp is available */ | 484 | /* Check if timestamp is available */ |
| 485 | if (priv->hw->desc->get_rx_timestamp_status(desc, priv->adv_ts)) { | 485 | if (priv->hw->desc->get_rx_timestamp_status(p, np, priv->adv_ts)) { |
| 486 | ns = priv->hw->desc->get_timestamp(desc, priv->adv_ts); | 486 | ns = priv->hw->desc->get_timestamp(desc, priv->adv_ts); |
| 487 | netdev_dbg(priv->dev, "get valid RX hw timestamp %llu\n", ns); | 487 | netdev_dbg(priv->dev, "get valid RX hw timestamp %llu\n", ns); |
| 488 | shhwtstamp = skb_hwtstamps(skb); | 488 | shhwtstamp = skb_hwtstamps(skb); |
diff --git a/drivers/net/hippi/rrunner.c b/drivers/net/hippi/rrunner.c index 8483f03d5a41..1ab97d99b9ba 100644 --- a/drivers/net/hippi/rrunner.c +++ b/drivers/net/hippi/rrunner.c | |||
| @@ -1379,8 +1379,8 @@ static int rr_close(struct net_device *dev) | |||
| 1379 | rrpriv->info_dma); | 1379 | rrpriv->info_dma); |
| 1380 | rrpriv->info = NULL; | 1380 | rrpriv->info = NULL; |
| 1381 | 1381 | ||
| 1382 | free_irq(pdev->irq, dev); | ||
| 1383 | spin_unlock_irqrestore(&rrpriv->lock, flags); | 1382 | spin_unlock_irqrestore(&rrpriv->lock, flags); |
| 1383 | free_irq(pdev->irq, dev); | ||
| 1384 | 1384 | ||
| 1385 | return 0; | 1385 | return 0; |
| 1386 | } | 1386 | } |
diff --git a/drivers/net/phy/at803x.c b/drivers/net/phy/at803x.c index 5f93e6add563..e911e4990b20 100644 --- a/drivers/net/phy/at803x.c +++ b/drivers/net/phy/at803x.c | |||
| @@ -239,14 +239,10 @@ static int at803x_resume(struct phy_device *phydev) | |||
| 239 | { | 239 | { |
| 240 | int value; | 240 | int value; |
| 241 | 241 | ||
| 242 | mutex_lock(&phydev->lock); | ||
| 243 | |||
| 244 | value = phy_read(phydev, MII_BMCR); | 242 | value = phy_read(phydev, MII_BMCR); |
| 245 | value &= ~(BMCR_PDOWN | BMCR_ISOLATE); | 243 | value &= ~(BMCR_PDOWN | BMCR_ISOLATE); |
| 246 | phy_write(phydev, MII_BMCR, value); | 244 | phy_write(phydev, MII_BMCR, value); |
| 247 | 245 | ||
| 248 | mutex_unlock(&phydev->lock); | ||
| 249 | |||
| 250 | return 0; | 246 | return 0; |
| 251 | } | 247 | } |
| 252 | 248 | ||
diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c index 4d02b27df044..82104edca393 100644 --- a/drivers/net/phy/marvell.c +++ b/drivers/net/phy/marvell.c | |||
| @@ -637,6 +637,10 @@ static int m88e1510_config_aneg(struct phy_device *phydev) | |||
| 637 | if (err < 0) | 637 | if (err < 0) |
| 638 | goto error; | 638 | goto error; |
| 639 | 639 | ||
| 640 | /* Do not touch the fiber page if we're in copper->sgmii mode */ | ||
| 641 | if (phydev->interface == PHY_INTERFACE_MODE_SGMII) | ||
| 642 | return 0; | ||
| 643 | |||
| 640 | /* Then the fiber link */ | 644 | /* Then the fiber link */ |
| 641 | err = marvell_set_page(phydev, MII_MARVELL_FIBER_PAGE); | 645 | err = marvell_set_page(phydev, MII_MARVELL_FIBER_PAGE); |
| 642 | if (err < 0) | 646 | if (err < 0) |
| @@ -875,6 +879,8 @@ static int m88e1510_config_init(struct phy_device *phydev) | |||
| 875 | 879 | ||
| 876 | /* SGMII-to-Copper mode initialization */ | 880 | /* SGMII-to-Copper mode initialization */ |
| 877 | if (phydev->interface == PHY_INTERFACE_MODE_SGMII) { | 881 | if (phydev->interface == PHY_INTERFACE_MODE_SGMII) { |
| 882 | u32 pause; | ||
| 883 | |||
| 878 | /* Select page 18 */ | 884 | /* Select page 18 */ |
| 879 | err = marvell_set_page(phydev, 18); | 885 | err = marvell_set_page(phydev, 18); |
| 880 | if (err < 0) | 886 | if (err < 0) |
| @@ -898,6 +904,16 @@ static int m88e1510_config_init(struct phy_device *phydev) | |||
| 898 | err = marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE); | 904 | err = marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE); |
| 899 | if (err < 0) | 905 | if (err < 0) |
| 900 | return err; | 906 | return err; |
| 907 | |||
| 908 | /* There appears to be a bug in the 88e1512 when used in | ||
| 909 | * SGMII to copper mode, where the AN advertisment register | ||
| 910 | * clears the pause bits each time a negotiation occurs. | ||
| 911 | * This means we can never be truely sure what was advertised, | ||
| 912 | * so disable Pause support. | ||
| 913 | */ | ||
| 914 | pause = SUPPORTED_Pause | SUPPORTED_Asym_Pause; | ||
| 915 | phydev->supported &= ~pause; | ||
| 916 | phydev->advertising &= ~pause; | ||
| 901 | } | 917 | } |
| 902 | 918 | ||
| 903 | return m88e1121_config_init(phydev); | 919 | return m88e1121_config_init(phydev); |
| @@ -2069,7 +2085,7 @@ static struct phy_driver marvell_drivers[] = { | |||
| 2069 | .flags = PHY_HAS_INTERRUPT, | 2085 | .flags = PHY_HAS_INTERRUPT, |
| 2070 | .probe = marvell_probe, | 2086 | .probe = marvell_probe, |
| 2071 | .config_init = &m88e1145_config_init, | 2087 | .config_init = &m88e1145_config_init, |
| 2072 | .config_aneg = &marvell_config_aneg, | 2088 | .config_aneg = &m88e1101_config_aneg, |
| 2073 | .read_status = &genphy_read_status, | 2089 | .read_status = &genphy_read_status, |
| 2074 | .ack_interrupt = &marvell_ack_interrupt, | 2090 | .ack_interrupt = &marvell_ack_interrupt, |
| 2075 | .config_intr = &marvell_config_intr, | 2091 | .config_intr = &marvell_config_intr, |
diff --git a/drivers/net/phy/mdio-xgene.c b/drivers/net/phy/mdio-xgene.c index bfd3090fb055..07c6048200c6 100644 --- a/drivers/net/phy/mdio-xgene.c +++ b/drivers/net/phy/mdio-xgene.c | |||
| @@ -194,8 +194,11 @@ static int xgene_mdio_reset(struct xgene_mdio_pdata *pdata) | |||
| 194 | } | 194 | } |
| 195 | 195 | ||
| 196 | ret = xgene_enet_ecc_init(pdata); | 196 | ret = xgene_enet_ecc_init(pdata); |
| 197 | if (ret) | 197 | if (ret) { |
| 198 | if (pdata->dev->of_node) | ||
| 199 | clk_disable_unprepare(pdata->clk); | ||
| 198 | return ret; | 200 | return ret; |
| 201 | } | ||
| 199 | xgene_gmac_reset(pdata); | 202 | xgene_gmac_reset(pdata); |
| 200 | 203 | ||
| 201 | return 0; | 204 | return 0; |
| @@ -388,8 +391,10 @@ static int xgene_mdio_probe(struct platform_device *pdev) | |||
| 388 | return ret; | 391 | return ret; |
| 389 | 392 | ||
| 390 | mdio_bus = mdiobus_alloc(); | 393 | mdio_bus = mdiobus_alloc(); |
| 391 | if (!mdio_bus) | 394 | if (!mdio_bus) { |
| 392 | return -ENOMEM; | 395 | ret = -ENOMEM; |
| 396 | goto out_clk; | ||
| 397 | } | ||
| 393 | 398 | ||
| 394 | mdio_bus->name = "APM X-Gene MDIO bus"; | 399 | mdio_bus->name = "APM X-Gene MDIO bus"; |
| 395 | 400 | ||
| @@ -418,7 +423,7 @@ static int xgene_mdio_probe(struct platform_device *pdev) | |||
| 418 | mdio_bus->phy_mask = ~0; | 423 | mdio_bus->phy_mask = ~0; |
| 419 | ret = mdiobus_register(mdio_bus); | 424 | ret = mdiobus_register(mdio_bus); |
| 420 | if (ret) | 425 | if (ret) |
| 421 | goto out; | 426 | goto out_mdiobus; |
| 422 | 427 | ||
| 423 | acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_HANDLE(dev), 1, | 428 | acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_HANDLE(dev), 1, |
| 424 | acpi_register_phy, NULL, mdio_bus, NULL); | 429 | acpi_register_phy, NULL, mdio_bus, NULL); |
| @@ -426,16 +431,20 @@ static int xgene_mdio_probe(struct platform_device *pdev) | |||
| 426 | } | 431 | } |
| 427 | 432 | ||
| 428 | if (ret) | 433 | if (ret) |
| 429 | goto out; | 434 | goto out_mdiobus; |
| 430 | 435 | ||
| 431 | pdata->mdio_bus = mdio_bus; | 436 | pdata->mdio_bus = mdio_bus; |
| 432 | xgene_mdio_status = true; | 437 | xgene_mdio_status = true; |
| 433 | 438 | ||
| 434 | return 0; | 439 | return 0; |
| 435 | 440 | ||
| 436 | out: | 441 | out_mdiobus: |
| 437 | mdiobus_free(mdio_bus); | 442 | mdiobus_free(mdio_bus); |
| 438 | 443 | ||
| 444 | out_clk: | ||
| 445 | if (dev->of_node) | ||
| 446 | clk_disable_unprepare(pdata->clk); | ||
| 447 | |||
| 439 | return ret; | 448 | return ret; |
| 440 | } | 449 | } |
| 441 | 450 | ||
diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c index 2df7b62c1a36..54d00a1d2bef 100644 --- a/drivers/net/phy/mdio_bus.c +++ b/drivers/net/phy/mdio_bus.c | |||
| @@ -270,6 +270,7 @@ static void of_mdiobus_link_mdiodev(struct mii_bus *bus, | |||
| 270 | 270 | ||
| 271 | if (addr == mdiodev->addr) { | 271 | if (addr == mdiodev->addr) { |
| 272 | dev->of_node = child; | 272 | dev->of_node = child; |
| 273 | dev->fwnode = of_fwnode_handle(child); | ||
| 273 | return; | 274 | return; |
| 274 | } | 275 | } |
| 275 | } | 276 | } |
diff --git a/drivers/net/phy/meson-gxl.c b/drivers/net/phy/meson-gxl.c index 1ea69b7585d9..842eb871a6e3 100644 --- a/drivers/net/phy/meson-gxl.c +++ b/drivers/net/phy/meson-gxl.c | |||
| @@ -22,6 +22,7 @@ | |||
| 22 | #include <linux/ethtool.h> | 22 | #include <linux/ethtool.h> |
| 23 | #include <linux/phy.h> | 23 | #include <linux/phy.h> |
| 24 | #include <linux/netdevice.h> | 24 | #include <linux/netdevice.h> |
| 25 | #include <linux/bitfield.h> | ||
| 25 | 26 | ||
| 26 | static int meson_gxl_config_init(struct phy_device *phydev) | 27 | static int meson_gxl_config_init(struct phy_device *phydev) |
| 27 | { | 28 | { |
| @@ -50,6 +51,77 @@ static int meson_gxl_config_init(struct phy_device *phydev) | |||
| 50 | return 0; | 51 | return 0; |
| 51 | } | 52 | } |
| 52 | 53 | ||
| 54 | /* This function is provided to cope with the possible failures of this phy | ||
| 55 | * during aneg process. When aneg fails, the PHY reports that aneg is done | ||
| 56 | * but the value found in MII_LPA is wrong: | ||
| 57 | * - Early failures: MII_LPA is just 0x0001. if MII_EXPANSION reports that | ||
| 58 | * the link partner (LP) supports aneg but the LP never acked our base | ||
| 59 | * code word, it is likely that we never sent it to begin with. | ||
| 60 | * - Late failures: MII_LPA is filled with a value which seems to make sense | ||
| 61 | * but it actually is not what the LP is advertising. It seems that we | ||
| 62 | * can detect this using a magic bit in the WOL bank (reg 12 - bit 12). | ||
| 63 | * If this particular bit is not set when aneg is reported being done, | ||
| 64 | * it means MII_LPA is likely to be wrong. | ||
| 65 | * | ||
| 66 | * In both case, forcing a restart of the aneg process solve the problem. | ||
| 67 | * When this failure happens, the first retry is usually successful but, | ||
| 68 | * in some cases, it may take up to 6 retries to get a decent result | ||
| 69 | */ | ||
| 70 | static int meson_gxl_read_status(struct phy_device *phydev) | ||
| 71 | { | ||
| 72 | int ret, wol, lpa, exp; | ||
| 73 | |||
| 74 | if (phydev->autoneg == AUTONEG_ENABLE) { | ||
| 75 | ret = genphy_aneg_done(phydev); | ||
| 76 | if (ret < 0) | ||
| 77 | return ret; | ||
| 78 | else if (!ret) | ||
| 79 | goto read_status_continue; | ||
| 80 | |||
| 81 | /* Need to access WOL bank, make sure the access is open */ | ||
| 82 | ret = phy_write(phydev, 0x14, 0x0000); | ||
| 83 | if (ret) | ||
| 84 | return ret; | ||
| 85 | ret = phy_write(phydev, 0x14, 0x0400); | ||
| 86 | if (ret) | ||
| 87 | return ret; | ||
| 88 | ret = phy_write(phydev, 0x14, 0x0000); | ||
| 89 | if (ret) | ||
| 90 | return ret; | ||
| 91 | ret = phy_write(phydev, 0x14, 0x0400); | ||
| 92 | if (ret) | ||
| 93 | return ret; | ||
| 94 | |||
| 95 | /* Request LPI_STATUS WOL register */ | ||
| 96 | ret = phy_write(phydev, 0x14, 0x8D80); | ||
| 97 | if (ret) | ||
| 98 | return ret; | ||
| 99 | |||
| 100 | /* Read LPI_STATUS value */ | ||
| 101 | wol = phy_read(phydev, 0x15); | ||
| 102 | if (wol < 0) | ||
| 103 | return wol; | ||
| 104 | |||
| 105 | lpa = phy_read(phydev, MII_LPA); | ||
| 106 | if (lpa < 0) | ||
| 107 | return lpa; | ||
| 108 | |||
| 109 | exp = phy_read(phydev, MII_EXPANSION); | ||
| 110 | if (exp < 0) | ||
| 111 | return exp; | ||
| 112 | |||
| 113 | if (!(wol & BIT(12)) || | ||
| 114 | ((exp & EXPANSION_NWAY) && !(lpa & LPA_LPACK))) { | ||
| 115 | /* Looks like aneg failed after all */ | ||
| 116 | phydev_dbg(phydev, "LPA corruption - aneg restart\n"); | ||
| 117 | return genphy_restart_aneg(phydev); | ||
| 118 | } | ||
| 119 | } | ||
| 120 | |||
| 121 | read_status_continue: | ||
| 122 | return genphy_read_status(phydev); | ||
| 123 | } | ||
| 124 | |||
| 53 | static struct phy_driver meson_gxl_phy[] = { | 125 | static struct phy_driver meson_gxl_phy[] = { |
| 54 | { | 126 | { |
| 55 | .phy_id = 0x01814400, | 127 | .phy_id = 0x01814400, |
| @@ -60,7 +132,7 @@ static struct phy_driver meson_gxl_phy[] = { | |||
| 60 | .config_init = meson_gxl_config_init, | 132 | .config_init = meson_gxl_config_init, |
| 61 | .config_aneg = genphy_config_aneg, | 133 | .config_aneg = genphy_config_aneg, |
| 62 | .aneg_done = genphy_aneg_done, | 134 | .aneg_done = genphy_aneg_done, |
| 63 | .read_status = genphy_read_status, | 135 | .read_status = meson_gxl_read_status, |
| 64 | .suspend = genphy_suspend, | 136 | .suspend = genphy_suspend, |
| 65 | .resume = genphy_resume, | 137 | .resume = genphy_resume, |
| 66 | }, | 138 | }, |
diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c index ab4614113403..422ff6333c52 100644 --- a/drivers/net/phy/micrel.c +++ b/drivers/net/phy/micrel.c | |||
| @@ -624,6 +624,7 @@ static int ksz9031_read_status(struct phy_device *phydev) | |||
| 624 | phydev->link = 0; | 624 | phydev->link = 0; |
| 625 | if (phydev->drv->config_intr && phy_interrupt_is_valid(phydev)) | 625 | if (phydev->drv->config_intr && phy_interrupt_is_valid(phydev)) |
| 626 | phydev->drv->config_intr(phydev); | 626 | phydev->drv->config_intr(phydev); |
| 627 | return genphy_config_aneg(phydev); | ||
| 627 | } | 628 | } |
| 628 | 629 | ||
| 629 | return 0; | 630 | return 0; |
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index 2b1e67bc1e73..ed10d1fc8f59 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c | |||
| @@ -828,7 +828,6 @@ EXPORT_SYMBOL(phy_stop); | |||
| 828 | */ | 828 | */ |
| 829 | void phy_start(struct phy_device *phydev) | 829 | void phy_start(struct phy_device *phydev) |
| 830 | { | 830 | { |
| 831 | bool do_resume = false; | ||
| 832 | int err = 0; | 831 | int err = 0; |
| 833 | 832 | ||
| 834 | mutex_lock(&phydev->lock); | 833 | mutex_lock(&phydev->lock); |
| @@ -841,6 +840,9 @@ void phy_start(struct phy_device *phydev) | |||
| 841 | phydev->state = PHY_UP; | 840 | phydev->state = PHY_UP; |
| 842 | break; | 841 | break; |
| 843 | case PHY_HALTED: | 842 | case PHY_HALTED: |
| 843 | /* if phy was suspended, bring the physical link up again */ | ||
| 844 | phy_resume(phydev); | ||
| 845 | |||
| 844 | /* make sure interrupts are re-enabled for the PHY */ | 846 | /* make sure interrupts are re-enabled for the PHY */ |
| 845 | if (phydev->irq != PHY_POLL) { | 847 | if (phydev->irq != PHY_POLL) { |
| 846 | err = phy_enable_interrupts(phydev); | 848 | err = phy_enable_interrupts(phydev); |
| @@ -849,17 +851,12 @@ void phy_start(struct phy_device *phydev) | |||
| 849 | } | 851 | } |
| 850 | 852 | ||
| 851 | phydev->state = PHY_RESUMING; | 853 | phydev->state = PHY_RESUMING; |
| 852 | do_resume = true; | ||
| 853 | break; | 854 | break; |
| 854 | default: | 855 | default: |
| 855 | break; | 856 | break; |
| 856 | } | 857 | } |
| 857 | mutex_unlock(&phydev->lock); | 858 | mutex_unlock(&phydev->lock); |
| 858 | 859 | ||
| 859 | /* if phy was suspended, bring the physical link up again */ | ||
| 860 | if (do_resume) | ||
| 861 | phy_resume(phydev); | ||
| 862 | |||
| 863 | phy_trigger_machine(phydev, true); | 860 | phy_trigger_machine(phydev, true); |
| 864 | } | 861 | } |
| 865 | EXPORT_SYMBOL(phy_start); | 862 | EXPORT_SYMBOL(phy_start); |
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index 67f25ac29025..b15b31ca2618 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c | |||
| @@ -135,7 +135,9 @@ static int mdio_bus_phy_resume(struct device *dev) | |||
| 135 | if (!mdio_bus_phy_may_suspend(phydev)) | 135 | if (!mdio_bus_phy_may_suspend(phydev)) |
| 136 | goto no_resume; | 136 | goto no_resume; |
| 137 | 137 | ||
| 138 | mutex_lock(&phydev->lock); | ||
| 138 | ret = phy_resume(phydev); | 139 | ret = phy_resume(phydev); |
| 140 | mutex_unlock(&phydev->lock); | ||
| 139 | if (ret < 0) | 141 | if (ret < 0) |
| 140 | return ret; | 142 | return ret; |
| 141 | 143 | ||
| @@ -1026,7 +1028,9 @@ int phy_attach_direct(struct net_device *dev, struct phy_device *phydev, | |||
| 1026 | if (err) | 1028 | if (err) |
| 1027 | goto error; | 1029 | goto error; |
| 1028 | 1030 | ||
| 1031 | mutex_lock(&phydev->lock); | ||
| 1029 | phy_resume(phydev); | 1032 | phy_resume(phydev); |
| 1033 | mutex_unlock(&phydev->lock); | ||
| 1030 | phy_led_triggers_register(phydev); | 1034 | phy_led_triggers_register(phydev); |
| 1031 | 1035 | ||
| 1032 | return err; | 1036 | return err; |
| @@ -1157,6 +1161,8 @@ int phy_resume(struct phy_device *phydev) | |||
| 1157 | struct phy_driver *phydrv = to_phy_driver(phydev->mdio.dev.driver); | 1161 | struct phy_driver *phydrv = to_phy_driver(phydev->mdio.dev.driver); |
| 1158 | int ret = 0; | 1162 | int ret = 0; |
| 1159 | 1163 | ||
| 1164 | WARN_ON(!mutex_is_locked(&phydev->lock)); | ||
| 1165 | |||
| 1160 | if (phydev->drv && phydrv->resume) | 1166 | if (phydev->drv && phydrv->resume) |
| 1161 | ret = phydrv->resume(phydev); | 1167 | ret = phydrv->resume(phydev); |
| 1162 | 1168 | ||
| @@ -1639,13 +1645,9 @@ int genphy_resume(struct phy_device *phydev) | |||
| 1639 | { | 1645 | { |
| 1640 | int value; | 1646 | int value; |
| 1641 | 1647 | ||
| 1642 | mutex_lock(&phydev->lock); | ||
| 1643 | |||
| 1644 | value = phy_read(phydev, MII_BMCR); | 1648 | value = phy_read(phydev, MII_BMCR); |
| 1645 | phy_write(phydev, MII_BMCR, value & ~BMCR_PDOWN); | 1649 | phy_write(phydev, MII_BMCR, value & ~BMCR_PDOWN); |
| 1646 | 1650 | ||
| 1647 | mutex_unlock(&phydev->lock); | ||
| 1648 | |||
| 1649 | return 0; | 1651 | return 0; |
| 1650 | } | 1652 | } |
| 1651 | EXPORT_SYMBOL(genphy_resume); | 1653 | EXPORT_SYMBOL(genphy_resume); |
diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c index 5dc9668dde34..827f3f92560e 100644 --- a/drivers/net/phy/phylink.c +++ b/drivers/net/phy/phylink.c | |||
| @@ -526,6 +526,7 @@ struct phylink *phylink_create(struct net_device *ndev, struct device_node *np, | |||
| 526 | pl->link_config.pause = MLO_PAUSE_AN; | 526 | pl->link_config.pause = MLO_PAUSE_AN; |
| 527 | pl->link_config.speed = SPEED_UNKNOWN; | 527 | pl->link_config.speed = SPEED_UNKNOWN; |
| 528 | pl->link_config.duplex = DUPLEX_UNKNOWN; | 528 | pl->link_config.duplex = DUPLEX_UNKNOWN; |
| 529 | pl->link_config.an_enabled = true; | ||
| 529 | pl->ops = ops; | 530 | pl->ops = ops; |
| 530 | __set_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state); | 531 | __set_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state); |
| 531 | 532 | ||
| @@ -951,6 +952,7 @@ int phylink_ethtool_ksettings_set(struct phylink *pl, | |||
| 951 | mutex_lock(&pl->state_mutex); | 952 | mutex_lock(&pl->state_mutex); |
| 952 | /* Configure the MAC to match the new settings */ | 953 | /* Configure the MAC to match the new settings */ |
| 953 | linkmode_copy(pl->link_config.advertising, our_kset.link_modes.advertising); | 954 | linkmode_copy(pl->link_config.advertising, our_kset.link_modes.advertising); |
| 955 | pl->link_config.interface = config.interface; | ||
| 954 | pl->link_config.speed = our_kset.base.speed; | 956 | pl->link_config.speed = our_kset.base.speed; |
| 955 | pl->link_config.duplex = our_kset.base.duplex; | 957 | pl->link_config.duplex = our_kset.base.duplex; |
| 956 | pl->link_config.an_enabled = our_kset.base.autoneg != AUTONEG_DISABLE; | 958 | pl->link_config.an_enabled = our_kset.base.autoneg != AUTONEG_DISABLE; |
diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index 304ec6555cd8..3000ddd1c7e2 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c | |||
| @@ -1204,12 +1204,14 @@ static const struct usb_device_id products[] = { | |||
| 1204 | {QMI_FIXED_INTF(0x1199, 0x9079, 10)}, /* Sierra Wireless EM74xx */ | 1204 | {QMI_FIXED_INTF(0x1199, 0x9079, 10)}, /* Sierra Wireless EM74xx */ |
| 1205 | {QMI_FIXED_INTF(0x1199, 0x907b, 8)}, /* Sierra Wireless EM74xx */ | 1205 | {QMI_FIXED_INTF(0x1199, 0x907b, 8)}, /* Sierra Wireless EM74xx */ |
| 1206 | {QMI_FIXED_INTF(0x1199, 0x907b, 10)}, /* Sierra Wireless EM74xx */ | 1206 | {QMI_FIXED_INTF(0x1199, 0x907b, 10)}, /* Sierra Wireless EM74xx */ |
| 1207 | {QMI_FIXED_INTF(0x1199, 0x9091, 8)}, /* Sierra Wireless EM7565 */ | ||
| 1207 | {QMI_FIXED_INTF(0x1bbb, 0x011e, 4)}, /* Telekom Speedstick LTE II (Alcatel One Touch L100V LTE) */ | 1208 | {QMI_FIXED_INTF(0x1bbb, 0x011e, 4)}, /* Telekom Speedstick LTE II (Alcatel One Touch L100V LTE) */ |
| 1208 | {QMI_FIXED_INTF(0x1bbb, 0x0203, 2)}, /* Alcatel L800MA */ | 1209 | {QMI_FIXED_INTF(0x1bbb, 0x0203, 2)}, /* Alcatel L800MA */ |
| 1209 | {QMI_FIXED_INTF(0x2357, 0x0201, 4)}, /* TP-LINK HSUPA Modem MA180 */ | 1210 | {QMI_FIXED_INTF(0x2357, 0x0201, 4)}, /* TP-LINK HSUPA Modem MA180 */ |
| 1210 | {QMI_FIXED_INTF(0x2357, 0x9000, 4)}, /* TP-LINK MA260 */ | 1211 | {QMI_FIXED_INTF(0x2357, 0x9000, 4)}, /* TP-LINK MA260 */ |
| 1211 | {QMI_QUIRK_SET_DTR(0x1bc7, 0x1040, 2)}, /* Telit LE922A */ | 1212 | {QMI_QUIRK_SET_DTR(0x1bc7, 0x1040, 2)}, /* Telit LE922A */ |
| 1212 | {QMI_FIXED_INTF(0x1bc7, 0x1100, 3)}, /* Telit ME910 */ | 1213 | {QMI_FIXED_INTF(0x1bc7, 0x1100, 3)}, /* Telit ME910 */ |
| 1214 | {QMI_FIXED_INTF(0x1bc7, 0x1101, 3)}, /* Telit ME910 dual modem */ | ||
| 1213 | {QMI_FIXED_INTF(0x1bc7, 0x1200, 5)}, /* Telit LE920 */ | 1215 | {QMI_FIXED_INTF(0x1bc7, 0x1200, 5)}, /* Telit LE920 */ |
| 1214 | {QMI_QUIRK_SET_DTR(0x1bc7, 0x1201, 2)}, /* Telit LE920, LE920A4 */ | 1216 | {QMI_QUIRK_SET_DTR(0x1bc7, 0x1201, 2)}, /* Telit LE920, LE920A4 */ |
| 1215 | {QMI_FIXED_INTF(0x1c9e, 0x9801, 3)}, /* Telewell TW-3G HSPA+ */ | 1217 | {QMI_FIXED_INTF(0x1c9e, 0x9801, 3)}, /* Telewell TW-3G HSPA+ */ |
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index 19b9cc51079e..31f4b7911ef8 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c | |||
| @@ -2155,6 +2155,13 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, | |||
| 2155 | } | 2155 | } |
| 2156 | 2156 | ||
| 2157 | ndst = &rt->dst; | 2157 | ndst = &rt->dst; |
| 2158 | if (skb_dst(skb)) { | ||
| 2159 | int mtu = dst_mtu(ndst) - VXLAN_HEADROOM; | ||
| 2160 | |||
| 2161 | skb_dst(skb)->ops->update_pmtu(skb_dst(skb), NULL, | ||
| 2162 | skb, mtu); | ||
| 2163 | } | ||
| 2164 | |||
| 2158 | tos = ip_tunnel_ecn_encap(tos, old_iph, skb); | 2165 | tos = ip_tunnel_ecn_encap(tos, old_iph, skb); |
| 2159 | ttl = ttl ? : ip4_dst_hoplimit(&rt->dst); | 2166 | ttl = ttl ? : ip4_dst_hoplimit(&rt->dst); |
| 2160 | err = vxlan_build_skb(skb, ndst, sizeof(struct iphdr), | 2167 | err = vxlan_build_skb(skb, ndst, sizeof(struct iphdr), |
| @@ -2190,6 +2197,13 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, | |||
| 2190 | goto out_unlock; | 2197 | goto out_unlock; |
| 2191 | } | 2198 | } |
| 2192 | 2199 | ||
| 2200 | if (skb_dst(skb)) { | ||
| 2201 | int mtu = dst_mtu(ndst) - VXLAN6_HEADROOM; | ||
| 2202 | |||
| 2203 | skb_dst(skb)->ops->update_pmtu(skb_dst(skb), NULL, | ||
| 2204 | skb, mtu); | ||
| 2205 | } | ||
| 2206 | |||
| 2193 | tos = ip_tunnel_ecn_encap(tos, old_iph, skb); | 2207 | tos = ip_tunnel_ecn_encap(tos, old_iph, skb); |
| 2194 | ttl = ttl ? : ip6_dst_hoplimit(ndst); | 2208 | ttl = ttl ? : ip6_dst_hoplimit(ndst); |
| 2195 | skb_scrub_packet(skb, xnet); | 2209 | skb_scrub_packet(skb, xnet); |
| @@ -3103,6 +3117,11 @@ static void vxlan_config_apply(struct net_device *dev, | |||
| 3103 | 3117 | ||
| 3104 | max_mtu = lowerdev->mtu - (use_ipv6 ? VXLAN6_HEADROOM : | 3118 | max_mtu = lowerdev->mtu - (use_ipv6 ? VXLAN6_HEADROOM : |
| 3105 | VXLAN_HEADROOM); | 3119 | VXLAN_HEADROOM); |
| 3120 | if (max_mtu < ETH_MIN_MTU) | ||
| 3121 | max_mtu = ETH_MIN_MTU; | ||
| 3122 | |||
| 3123 | if (!changelink && !conf->mtu) | ||
| 3124 | dev->mtu = max_mtu; | ||
| 3106 | } | 3125 | } |
| 3107 | 3126 | ||
| 3108 | if (dev->mtu > max_mtu) | 3127 | if (dev->mtu > max_mtu) |
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 10b075a46b26..e8189c07b41f 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c | |||
| @@ -684,6 +684,7 @@ static void hwsim_send_nullfunc(struct mac80211_hwsim_data *data, u8 *mac, | |||
| 684 | hdr = skb_put(skb, sizeof(*hdr) - ETH_ALEN); | 684 | hdr = skb_put(skb, sizeof(*hdr) - ETH_ALEN); |
| 685 | hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA | | 685 | hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA | |
| 686 | IEEE80211_STYPE_NULLFUNC | | 686 | IEEE80211_STYPE_NULLFUNC | |
| 687 | IEEE80211_FCTL_TODS | | ||
| 687 | (ps ? IEEE80211_FCTL_PM : 0)); | 688 | (ps ? IEEE80211_FCTL_PM : 0)); |
| 688 | hdr->duration_id = cpu_to_le16(0); | 689 | hdr->duration_id = cpu_to_le16(0); |
| 689 | memcpy(hdr->addr1, vp->bssid, ETH_ALEN); | 690 | memcpy(hdr->addr1, vp->bssid, ETH_ALEN); |
| @@ -3215,7 +3216,7 @@ static int hwsim_get_radio_nl(struct sk_buff *msg, struct genl_info *info) | |||
| 3215 | if (!net_eq(wiphy_net(data->hw->wiphy), genl_info_net(info))) | 3216 | if (!net_eq(wiphy_net(data->hw->wiphy), genl_info_net(info))) |
| 3216 | continue; | 3217 | continue; |
| 3217 | 3218 | ||
| 3218 | skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); | 3219 | skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC); |
| 3219 | if (!skb) { | 3220 | if (!skb) { |
| 3220 | res = -ENOMEM; | 3221 | res = -ENOMEM; |
| 3221 | goto out_err; | 3222 | goto out_err; |
diff --git a/drivers/nvdimm/btt.c b/drivers/nvdimm/btt.c index e949e3302af4..c586bcdb5190 100644 --- a/drivers/nvdimm/btt.c +++ b/drivers/nvdimm/btt.c | |||
| @@ -211,12 +211,12 @@ static int btt_map_read(struct arena_info *arena, u32 lba, u32 *mapping, | |||
| 211 | return ret; | 211 | return ret; |
| 212 | } | 212 | } |
| 213 | 213 | ||
| 214 | static int btt_log_read_pair(struct arena_info *arena, u32 lane, | 214 | static int btt_log_group_read(struct arena_info *arena, u32 lane, |
| 215 | struct log_entry *ent) | 215 | struct log_group *log) |
| 216 | { | 216 | { |
| 217 | return arena_read_bytes(arena, | 217 | return arena_read_bytes(arena, |
| 218 | arena->logoff + (2 * lane * LOG_ENT_SIZE), ent, | 218 | arena->logoff + (lane * LOG_GRP_SIZE), log, |
| 219 | 2 * LOG_ENT_SIZE, 0); | 219 | LOG_GRP_SIZE, 0); |
| 220 | } | 220 | } |
| 221 | 221 | ||
| 222 | static struct dentry *debugfs_root; | 222 | static struct dentry *debugfs_root; |
| @@ -256,6 +256,8 @@ static void arena_debugfs_init(struct arena_info *a, struct dentry *parent, | |||
| 256 | debugfs_create_x64("logoff", S_IRUGO, d, &a->logoff); | 256 | debugfs_create_x64("logoff", S_IRUGO, d, &a->logoff); |
| 257 | debugfs_create_x64("info2off", S_IRUGO, d, &a->info2off); | 257 | debugfs_create_x64("info2off", S_IRUGO, d, &a->info2off); |
| 258 | debugfs_create_x32("flags", S_IRUGO, d, &a->flags); | 258 | debugfs_create_x32("flags", S_IRUGO, d, &a->flags); |
| 259 | debugfs_create_u32("log_index_0", S_IRUGO, d, &a->log_index[0]); | ||
| 260 | debugfs_create_u32("log_index_1", S_IRUGO, d, &a->log_index[1]); | ||
| 259 | } | 261 | } |
| 260 | 262 | ||
| 261 | static void btt_debugfs_init(struct btt *btt) | 263 | static void btt_debugfs_init(struct btt *btt) |
| @@ -274,6 +276,11 @@ static void btt_debugfs_init(struct btt *btt) | |||
| 274 | } | 276 | } |
| 275 | } | 277 | } |
| 276 | 278 | ||
| 279 | static u32 log_seq(struct log_group *log, int log_idx) | ||
| 280 | { | ||
| 281 | return le32_to_cpu(log->ent[log_idx].seq); | ||
| 282 | } | ||
| 283 | |||
| 277 | /* | 284 | /* |
| 278 | * This function accepts two log entries, and uses the | 285 | * This function accepts two log entries, and uses the |
| 279 | * sequence number to find the 'older' entry. | 286 | * sequence number to find the 'older' entry. |
| @@ -283,8 +290,10 @@ static void btt_debugfs_init(struct btt *btt) | |||
| 283 | * | 290 | * |
| 284 | * TODO The logic feels a bit kludge-y. make it better.. | 291 | * TODO The logic feels a bit kludge-y. make it better.. |
| 285 | */ | 292 | */ |
| 286 | static int btt_log_get_old(struct log_entry *ent) | 293 | static int btt_log_get_old(struct arena_info *a, struct log_group *log) |
| 287 | { | 294 | { |
| 295 | int idx0 = a->log_index[0]; | ||
| 296 | int idx1 = a->log_index[1]; | ||
| 288 | int old; | 297 | int old; |
| 289 | 298 | ||
| 290 | /* | 299 | /* |
| @@ -292,23 +301,23 @@ static int btt_log_get_old(struct log_entry *ent) | |||
| 292 | * the next time, the following logic works out to put this | 301 | * the next time, the following logic works out to put this |
| 293 | * (next) entry into [1] | 302 | * (next) entry into [1] |
| 294 | */ | 303 | */ |
| 295 | if (ent[0].seq == 0) { | 304 | if (log_seq(log, idx0) == 0) { |
| 296 | ent[0].seq = cpu_to_le32(1); | 305 | log->ent[idx0].seq = cpu_to_le32(1); |
| 297 | return 0; | 306 | return 0; |
| 298 | } | 307 | } |
| 299 | 308 | ||
| 300 | if (ent[0].seq == ent[1].seq) | 309 | if (log_seq(log, idx0) == log_seq(log, idx1)) |
| 301 | return -EINVAL; | 310 | return -EINVAL; |
| 302 | if (le32_to_cpu(ent[0].seq) + le32_to_cpu(ent[1].seq) > 5) | 311 | if (log_seq(log, idx0) + log_seq(log, idx1) > 5) |
| 303 | return -EINVAL; | 312 | return -EINVAL; |
| 304 | 313 | ||
| 305 | if (le32_to_cpu(ent[0].seq) < le32_to_cpu(ent[1].seq)) { | 314 | if (log_seq(log, idx0) < log_seq(log, idx1)) { |
| 306 | if (le32_to_cpu(ent[1].seq) - le32_to_cpu(ent[0].seq) == 1) | 315 | if ((log_seq(log, idx1) - log_seq(log, idx0)) == 1) |
| 307 | old = 0; | 316 | old = 0; |
| 308 | else | 317 | else |
| 309 | old = 1; | 318 | old = 1; |
| 310 | } else { | 319 | } else { |
| 311 | if (le32_to_cpu(ent[0].seq) - le32_to_cpu(ent[1].seq) == 1) | 320 | if ((log_seq(log, idx0) - log_seq(log, idx1)) == 1) |
| 312 | old = 1; | 321 | old = 1; |
| 313 | else | 322 | else |
| 314 | old = 0; | 323 | old = 0; |
| @@ -328,17 +337,18 @@ static int btt_log_read(struct arena_info *arena, u32 lane, | |||
| 328 | { | 337 | { |
| 329 | int ret; | 338 | int ret; |
| 330 | int old_ent, ret_ent; | 339 | int old_ent, ret_ent; |
| 331 | struct log_entry log[2]; | 340 | struct log_group log; |
| 332 | 341 | ||
| 333 | ret = btt_log_read_pair(arena, lane, log); | 342 | ret = btt_log_group_read(arena, lane, &log); |
| 334 | if (ret) | 343 | if (ret) |
| 335 | return -EIO; | 344 | return -EIO; |
| 336 | 345 | ||
| 337 | old_ent = btt_log_get_old(log); | 346 | old_ent = btt_log_get_old(arena, &log); |
| 338 | if (old_ent < 0 || old_ent > 1) { | 347 | if (old_ent < 0 || old_ent > 1) { |
| 339 | dev_err(to_dev(arena), | 348 | dev_err(to_dev(arena), |
| 340 | "log corruption (%d): lane %d seq [%d, %d]\n", | 349 | "log corruption (%d): lane %d seq [%d, %d]\n", |
| 341 | old_ent, lane, log[0].seq, log[1].seq); | 350 | old_ent, lane, log.ent[arena->log_index[0]].seq, |
| 351 | log.ent[arena->log_index[1]].seq); | ||
| 342 | /* TODO set error state? */ | 352 | /* TODO set error state? */ |
| 343 | return -EIO; | 353 | return -EIO; |
| 344 | } | 354 | } |
| @@ -346,7 +356,7 @@ static int btt_log_read(struct arena_info *arena, u32 lane, | |||
| 346 | ret_ent = (old_flag ? old_ent : (1 - old_ent)); | 356 | ret_ent = (old_flag ? old_ent : (1 - old_ent)); |
| 347 | 357 | ||
| 348 | if (ent != NULL) | 358 | if (ent != NULL) |
| 349 | memcpy(ent, &log[ret_ent], LOG_ENT_SIZE); | 359 | memcpy(ent, &log.ent[arena->log_index[ret_ent]], LOG_ENT_SIZE); |
| 350 | 360 | ||
| 351 | return ret_ent; | 361 | return ret_ent; |
| 352 | } | 362 | } |
| @@ -360,17 +370,13 @@ static int __btt_log_write(struct arena_info *arena, u32 lane, | |||
| 360 | u32 sub, struct log_entry *ent, unsigned long flags) | 370 | u32 sub, struct log_entry *ent, unsigned long flags) |
| 361 | { | 371 | { |
| 362 | int ret; | 372 | int ret; |
| 363 | /* | 373 | u32 group_slot = arena->log_index[sub]; |
| 364 | * Ignore the padding in log_entry for calculating log_half. | 374 | unsigned int log_half = LOG_ENT_SIZE / 2; |
| 365 | * The entry is 'committed' when we write the sequence number, | ||
| 366 | * and we want to ensure that that is the last thing written. | ||
| 367 | * We don't bother writing the padding as that would be extra | ||
| 368 | * media wear and write amplification | ||
| 369 | */ | ||
| 370 | unsigned int log_half = (LOG_ENT_SIZE - 2 * sizeof(u64)) / 2; | ||
| 371 | u64 ns_off = arena->logoff + (((2 * lane) + sub) * LOG_ENT_SIZE); | ||
| 372 | void *src = ent; | 375 | void *src = ent; |
| 376 | u64 ns_off; | ||
| 373 | 377 | ||
| 378 | ns_off = arena->logoff + (lane * LOG_GRP_SIZE) + | ||
| 379 | (group_slot * LOG_ENT_SIZE); | ||
| 374 | /* split the 16B write into atomic, durable halves */ | 380 | /* split the 16B write into atomic, durable halves */ |
| 375 | ret = arena_write_bytes(arena, ns_off, src, log_half, flags); | 381 | ret = arena_write_bytes(arena, ns_off, src, log_half, flags); |
| 376 | if (ret) | 382 | if (ret) |
| @@ -453,7 +459,7 @@ static int btt_log_init(struct arena_info *arena) | |||
| 453 | { | 459 | { |
| 454 | size_t logsize = arena->info2off - arena->logoff; | 460 | size_t logsize = arena->info2off - arena->logoff; |
| 455 | size_t chunk_size = SZ_4K, offset = 0; | 461 | size_t chunk_size = SZ_4K, offset = 0; |
| 456 | struct log_entry log; | 462 | struct log_entry ent; |
| 457 | void *zerobuf; | 463 | void *zerobuf; |
| 458 | int ret; | 464 | int ret; |
| 459 | u32 i; | 465 | u32 i; |
| @@ -485,11 +491,11 @@ static int btt_log_init(struct arena_info *arena) | |||
| 485 | } | 491 | } |
| 486 | 492 | ||
| 487 | for (i = 0; i < arena->nfree; i++) { | 493 | for (i = 0; i < arena->nfree; i++) { |
| 488 | log.lba = cpu_to_le32(i); | 494 | ent.lba = cpu_to_le32(i); |
| 489 | log.old_map = cpu_to_le32(arena->external_nlba + i); | 495 | ent.old_map = cpu_to_le32(arena->external_nlba + i); |
| 490 | log.new_map = cpu_to_le32(arena->external_nlba + i); | 496 | ent.new_map = cpu_to_le32(arena->external_nlba + i); |
| 491 | log.seq = cpu_to_le32(LOG_SEQ_INIT); | 497 | ent.seq = cpu_to_le32(LOG_SEQ_INIT); |
| 492 | ret = __btt_log_write(arena, i, 0, &log, 0); | 498 | ret = __btt_log_write(arena, i, 0, &ent, 0); |
| 493 | if (ret) | 499 | if (ret) |
| 494 | goto free; | 500 | goto free; |
| 495 | } | 501 | } |
| @@ -594,6 +600,123 @@ static int btt_freelist_init(struct arena_info *arena) | |||
| 594 | return 0; | 600 | return 0; |
| 595 | } | 601 | } |
| 596 | 602 | ||
| 603 | static bool ent_is_padding(struct log_entry *ent) | ||
| 604 | { | ||
| 605 | return (ent->lba == 0) && (ent->old_map == 0) && (ent->new_map == 0) | ||
| 606 | && (ent->seq == 0); | ||
| 607 | } | ||
| 608 | |||
| 609 | /* | ||
| 610 | * Detecting valid log indices: We read a log group (see the comments in btt.h | ||
| 611 | * for a description of a 'log_group' and its 'slots'), and iterate over its | ||
| 612 | * four slots. We expect that a padding slot will be all-zeroes, and use this | ||
| 613 | * to detect a padding slot vs. an actual entry. | ||
| 614 | * | ||
| 615 | * If a log_group is in the initial state, i.e. hasn't been used since the | ||
| 616 | * creation of this BTT layout, it will have three of the four slots with | ||
| 617 | * zeroes. We skip over these log_groups for the detection of log_index. If | ||
| 618 | * all log_groups are in the initial state (i.e. the BTT has never been | ||
| 619 | * written to), it is safe to assume the 'new format' of log entries in slots | ||
| 620 | * (0, 1). | ||
| 621 | */ | ||
| 622 | static int log_set_indices(struct arena_info *arena) | ||
| 623 | { | ||
| 624 | bool idx_set = false, initial_state = true; | ||
| 625 | int ret, log_index[2] = {-1, -1}; | ||
| 626 | u32 i, j, next_idx = 0; | ||
| 627 | struct log_group log; | ||
| 628 | u32 pad_count = 0; | ||
| 629 | |||
| 630 | for (i = 0; i < arena->nfree; i++) { | ||
| 631 | ret = btt_log_group_read(arena, i, &log); | ||
| 632 | if (ret < 0) | ||
| 633 | return ret; | ||
| 634 | |||
| 635 | for (j = 0; j < 4; j++) { | ||
| 636 | if (!idx_set) { | ||
| 637 | if (ent_is_padding(&log.ent[j])) { | ||
| 638 | pad_count++; | ||
| 639 | continue; | ||
| 640 | } else { | ||
| 641 | /* Skip if index has been recorded */ | ||
| 642 | if ((next_idx == 1) && | ||
| 643 | (j == log_index[0])) | ||
| 644 | continue; | ||
| 645 | /* valid entry, record index */ | ||
| 646 | log_index[next_idx] = j; | ||
| 647 | next_idx++; | ||
| 648 | } | ||
| 649 | if (next_idx == 2) { | ||
| 650 | /* two valid entries found */ | ||
| 651 | idx_set = true; | ||
| 652 | } else if (next_idx > 2) { | ||
| 653 | /* too many valid indices */ | ||
| 654 | return -ENXIO; | ||
| 655 | } | ||
| 656 | } else { | ||
| 657 | /* | ||
| 658 | * once the indices have been set, just verify | ||
| 659 | * that all subsequent log groups are either in | ||
| 660 | * their initial state or follow the same | ||
| 661 | * indices. | ||
| 662 | */ | ||
| 663 | if (j == log_index[0]) { | ||
| 664 | /* entry must be 'valid' */ | ||
| 665 | if (ent_is_padding(&log.ent[j])) | ||
| 666 | return -ENXIO; | ||
| 667 | } else if (j == log_index[1]) { | ||
| 668 | ; | ||
| 669 | /* | ||
| 670 | * log_index[1] can be padding if the | ||
| 671 | * lane never got used and it is still | ||
| 672 | * in the initial state (three 'padding' | ||
| 673 | * entries) | ||
| 674 | */ | ||
| 675 | } else { | ||
| 676 | /* entry must be invalid (padding) */ | ||
| 677 | if (!ent_is_padding(&log.ent[j])) | ||
| 678 | return -ENXIO; | ||
| 679 | } | ||
| 680 | } | ||
| 681 | } | ||
| 682 | /* | ||
| 683 | * If any of the log_groups have more than one valid, | ||
| 684 | * non-padding entry, then the we are no longer in the | ||
| 685 | * initial_state | ||
| 686 | */ | ||
| 687 | if (pad_count < 3) | ||
| 688 | initial_state = false; | ||
| 689 | pad_count = 0; | ||
| 690 | } | ||
| 691 | |||
| 692 | if (!initial_state && !idx_set) | ||
| 693 | return -ENXIO; | ||
| 694 | |||
| 695 | /* | ||
| 696 | * If all the entries in the log were in the initial state, | ||
| 697 | * assume new padding scheme | ||
| 698 | */ | ||
| 699 | if (initial_state) | ||
| 700 | log_index[1] = 1; | ||
| 701 | |||
| 702 | /* | ||
| 703 | * Only allow the known permutations of log/padding indices, | ||
| 704 | * i.e. (0, 1), and (0, 2) | ||
| 705 | */ | ||
| 706 | if ((log_index[0] == 0) && ((log_index[1] == 1) || (log_index[1] == 2))) | ||
| 707 | ; /* known index possibilities */ | ||
| 708 | else { | ||
| 709 | dev_err(to_dev(arena), "Found an unknown padding scheme\n"); | ||
| 710 | return -ENXIO; | ||
| 711 | } | ||
| 712 | |||
| 713 | arena->log_index[0] = log_index[0]; | ||
| 714 | arena->log_index[1] = log_index[1]; | ||
| 715 | dev_dbg(to_dev(arena), "log_index_0 = %d\n", log_index[0]); | ||
| 716 | dev_dbg(to_dev(arena), "log_index_1 = %d\n", log_index[1]); | ||
| 717 | return 0; | ||
| 718 | } | ||
| 719 | |||
| 597 | static int btt_rtt_init(struct arena_info *arena) | 720 | static int btt_rtt_init(struct arena_info *arena) |
| 598 | { | 721 | { |
| 599 | arena->rtt = kcalloc(arena->nfree, sizeof(u32), GFP_KERNEL); | 722 | arena->rtt = kcalloc(arena->nfree, sizeof(u32), GFP_KERNEL); |
| @@ -650,8 +773,7 @@ static struct arena_info *alloc_arena(struct btt *btt, size_t size, | |||
| 650 | available -= 2 * BTT_PG_SIZE; | 773 | available -= 2 * BTT_PG_SIZE; |
| 651 | 774 | ||
| 652 | /* The log takes a fixed amount of space based on nfree */ | 775 | /* The log takes a fixed amount of space based on nfree */ |
| 653 | logsize = roundup(2 * arena->nfree * sizeof(struct log_entry), | 776 | logsize = roundup(arena->nfree * LOG_GRP_SIZE, BTT_PG_SIZE); |
| 654 | BTT_PG_SIZE); | ||
| 655 | available -= logsize; | 777 | available -= logsize; |
| 656 | 778 | ||
| 657 | /* Calculate optimal split between map and data area */ | 779 | /* Calculate optimal split between map and data area */ |
| @@ -668,6 +790,10 @@ static struct arena_info *alloc_arena(struct btt *btt, size_t size, | |||
| 668 | arena->mapoff = arena->dataoff + datasize; | 790 | arena->mapoff = arena->dataoff + datasize; |
| 669 | arena->logoff = arena->mapoff + mapsize; | 791 | arena->logoff = arena->mapoff + mapsize; |
| 670 | arena->info2off = arena->logoff + logsize; | 792 | arena->info2off = arena->logoff + logsize; |
| 793 | |||
| 794 | /* Default log indices are (0,1) */ | ||
| 795 | arena->log_index[0] = 0; | ||
| 796 | arena->log_index[1] = 1; | ||
| 671 | return arena; | 797 | return arena; |
| 672 | } | 798 | } |
| 673 | 799 | ||
| @@ -758,6 +884,13 @@ static int discover_arenas(struct btt *btt) | |||
| 758 | arena->external_lba_start = cur_nlba; | 884 | arena->external_lba_start = cur_nlba; |
| 759 | parse_arena_meta(arena, super, cur_off); | 885 | parse_arena_meta(arena, super, cur_off); |
| 760 | 886 | ||
| 887 | ret = log_set_indices(arena); | ||
| 888 | if (ret) { | ||
| 889 | dev_err(to_dev(arena), | ||
| 890 | "Unable to deduce log/padding indices\n"); | ||
| 891 | goto out; | ||
| 892 | } | ||
| 893 | |||
| 761 | mutex_init(&arena->err_lock); | 894 | mutex_init(&arena->err_lock); |
| 762 | ret = btt_freelist_init(arena); | 895 | ret = btt_freelist_init(arena); |
| 763 | if (ret) | 896 | if (ret) |
diff --git a/drivers/nvdimm/btt.h b/drivers/nvdimm/btt.h index 578c2057524d..db3cb6d4d0d4 100644 --- a/drivers/nvdimm/btt.h +++ b/drivers/nvdimm/btt.h | |||
| @@ -27,6 +27,7 @@ | |||
| 27 | #define MAP_ERR_MASK (1 << MAP_ERR_SHIFT) | 27 | #define MAP_ERR_MASK (1 << MAP_ERR_SHIFT) |
| 28 | #define MAP_LBA_MASK (~((1 << MAP_TRIM_SHIFT) | (1 << MAP_ERR_SHIFT))) | 28 | #define MAP_LBA_MASK (~((1 << MAP_TRIM_SHIFT) | (1 << MAP_ERR_SHIFT))) |
| 29 | #define MAP_ENT_NORMAL 0xC0000000 | 29 | #define MAP_ENT_NORMAL 0xC0000000 |
| 30 | #define LOG_GRP_SIZE sizeof(struct log_group) | ||
| 30 | #define LOG_ENT_SIZE sizeof(struct log_entry) | 31 | #define LOG_ENT_SIZE sizeof(struct log_entry) |
| 31 | #define ARENA_MIN_SIZE (1UL << 24) /* 16 MB */ | 32 | #define ARENA_MIN_SIZE (1UL << 24) /* 16 MB */ |
| 32 | #define ARENA_MAX_SIZE (1ULL << 39) /* 512 GB */ | 33 | #define ARENA_MAX_SIZE (1ULL << 39) /* 512 GB */ |
| @@ -50,12 +51,52 @@ enum btt_init_state { | |||
| 50 | INIT_READY | 51 | INIT_READY |
| 51 | }; | 52 | }; |
| 52 | 53 | ||
| 54 | /* | ||
| 55 | * A log group represents one log 'lane', and consists of four log entries. | ||
| 56 | * Two of the four entries are valid entries, and the remaining two are | ||
| 57 | * padding. Due to an old bug in the padding location, we need to perform a | ||
| 58 | * test to determine the padding scheme being used, and use that scheme | ||
| 59 | * thereafter. | ||
| 60 | * | ||
| 61 | * In kernels prior to 4.15, 'log group' would have actual log entries at | ||
| 62 | * indices (0, 2) and padding at indices (1, 3), where as the correct/updated | ||
| 63 | * format has log entries at indices (0, 1) and padding at indices (2, 3). | ||
| 64 | * | ||
| 65 | * Old (pre 4.15) format: | ||
| 66 | * +-----------------+-----------------+ | ||
| 67 | * | ent[0] | ent[1] | | ||
| 68 | * | 16B | 16B | | ||
| 69 | * | lba/old/new/seq | pad | | ||
| 70 | * +-----------------------------------+ | ||
| 71 | * | ent[2] | ent[3] | | ||
| 72 | * | 16B | 16B | | ||
| 73 | * | lba/old/new/seq | pad | | ||
| 74 | * +-----------------+-----------------+ | ||
| 75 | * | ||
| 76 | * New format: | ||
| 77 | * +-----------------+-----------------+ | ||
| 78 | * | ent[0] | ent[1] | | ||
| 79 | * | 16B | 16B | | ||
| 80 | * | lba/old/new/seq | lba/old/new/seq | | ||
| 81 | * +-----------------------------------+ | ||
| 82 | * | ent[2] | ent[3] | | ||
| 83 | * | 16B | 16B | | ||
| 84 | * | pad | pad | | ||
| 85 | * +-----------------+-----------------+ | ||
| 86 | * | ||
| 87 | * We detect during start-up which format is in use, and set | ||
| 88 | * arena->log_index[(0, 1)] with the detected format. | ||
| 89 | */ | ||
| 90 | |||
| 53 | struct log_entry { | 91 | struct log_entry { |
| 54 | __le32 lba; | 92 | __le32 lba; |
| 55 | __le32 old_map; | 93 | __le32 old_map; |
| 56 | __le32 new_map; | 94 | __le32 new_map; |
| 57 | __le32 seq; | 95 | __le32 seq; |
| 58 | __le64 padding[2]; | 96 | }; |
| 97 | |||
| 98 | struct log_group { | ||
| 99 | struct log_entry ent[4]; | ||
| 59 | }; | 100 | }; |
| 60 | 101 | ||
| 61 | struct btt_sb { | 102 | struct btt_sb { |
| @@ -125,6 +166,8 @@ struct aligned_lock { | |||
| 125 | * @list: List head for list of arenas | 166 | * @list: List head for list of arenas |
| 126 | * @debugfs_dir: Debugfs dentry | 167 | * @debugfs_dir: Debugfs dentry |
| 127 | * @flags: Arena flags - may signify error states. | 168 | * @flags: Arena flags - may signify error states. |
| 169 | * @err_lock: Mutex for synchronizing error clearing. | ||
| 170 | * @log_index: Indices of the valid log entries in a log_group | ||
| 128 | * | 171 | * |
| 129 | * arena_info is a per-arena handle. Once an arena is narrowed down for an | 172 | * arena_info is a per-arena handle. Once an arena is narrowed down for an |
| 130 | * IO, this struct is passed around for the duration of the IO. | 173 | * IO, this struct is passed around for the duration of the IO. |
| @@ -157,6 +200,7 @@ struct arena_info { | |||
| 157 | /* Arena flags */ | 200 | /* Arena flags */ |
| 158 | u32 flags; | 201 | u32 flags; |
| 159 | struct mutex err_lock; | 202 | struct mutex err_lock; |
| 203 | int log_index[2]; | ||
| 160 | }; | 204 | }; |
| 161 | 205 | ||
| 162 | /** | 206 | /** |
| @@ -176,6 +220,7 @@ struct arena_info { | |||
| 176 | * @init_lock: Mutex used for the BTT initialization | 220 | * @init_lock: Mutex used for the BTT initialization |
| 177 | * @init_state: Flag describing the initialization state for the BTT | 221 | * @init_state: Flag describing the initialization state for the BTT |
| 178 | * @num_arenas: Number of arenas in the BTT instance | 222 | * @num_arenas: Number of arenas in the BTT instance |
| 223 | * @phys_bb: Pointer to the namespace's badblocks structure | ||
| 179 | */ | 224 | */ |
| 180 | struct btt { | 225 | struct btt { |
| 181 | struct gendisk *btt_disk; | 226 | struct gendisk *btt_disk; |
diff --git a/drivers/nvdimm/pfn_devs.c b/drivers/nvdimm/pfn_devs.c index 65cc171c721d..2adada1a5855 100644 --- a/drivers/nvdimm/pfn_devs.c +++ b/drivers/nvdimm/pfn_devs.c | |||
| @@ -364,9 +364,9 @@ struct device *nd_pfn_create(struct nd_region *nd_region) | |||
| 364 | int nd_pfn_validate(struct nd_pfn *nd_pfn, const char *sig) | 364 | int nd_pfn_validate(struct nd_pfn *nd_pfn, const char *sig) |
| 365 | { | 365 | { |
| 366 | u64 checksum, offset; | 366 | u64 checksum, offset; |
| 367 | unsigned long align; | ||
| 368 | enum nd_pfn_mode mode; | 367 | enum nd_pfn_mode mode; |
| 369 | struct nd_namespace_io *nsio; | 368 | struct nd_namespace_io *nsio; |
| 369 | unsigned long align, start_pad; | ||
| 370 | struct nd_pfn_sb *pfn_sb = nd_pfn->pfn_sb; | 370 | struct nd_pfn_sb *pfn_sb = nd_pfn->pfn_sb; |
| 371 | struct nd_namespace_common *ndns = nd_pfn->ndns; | 371 | struct nd_namespace_common *ndns = nd_pfn->ndns; |
| 372 | const u8 *parent_uuid = nd_dev_to_uuid(&ndns->dev); | 372 | const u8 *parent_uuid = nd_dev_to_uuid(&ndns->dev); |
| @@ -410,6 +410,7 @@ int nd_pfn_validate(struct nd_pfn *nd_pfn, const char *sig) | |||
| 410 | 410 | ||
| 411 | align = le32_to_cpu(pfn_sb->align); | 411 | align = le32_to_cpu(pfn_sb->align); |
| 412 | offset = le64_to_cpu(pfn_sb->dataoff); | 412 | offset = le64_to_cpu(pfn_sb->dataoff); |
| 413 | start_pad = le32_to_cpu(pfn_sb->start_pad); | ||
| 413 | if (align == 0) | 414 | if (align == 0) |
| 414 | align = 1UL << ilog2(offset); | 415 | align = 1UL << ilog2(offset); |
| 415 | mode = le32_to_cpu(pfn_sb->mode); | 416 | mode = le32_to_cpu(pfn_sb->mode); |
| @@ -468,7 +469,7 @@ int nd_pfn_validate(struct nd_pfn *nd_pfn, const char *sig) | |||
| 468 | return -EBUSY; | 469 | return -EBUSY; |
| 469 | } | 470 | } |
| 470 | 471 | ||
| 471 | if ((align && !IS_ALIGNED(offset, align)) | 472 | if ((align && !IS_ALIGNED(nsio->res.start + offset + start_pad, align)) |
| 472 | || !IS_ALIGNED(offset, PAGE_SIZE)) { | 473 | || !IS_ALIGNED(offset, PAGE_SIZE)) { |
| 473 | dev_err(&nd_pfn->dev, | 474 | dev_err(&nd_pfn->dev, |
| 474 | "bad offset: %#llx dax disabled align: %#lx\n", | 475 | "bad offset: %#llx dax disabled align: %#lx\n", |
| @@ -582,6 +583,12 @@ static struct vmem_altmap *__nvdimm_setup_pfn(struct nd_pfn *nd_pfn, | |||
| 582 | return altmap; | 583 | return altmap; |
| 583 | } | 584 | } |
| 584 | 585 | ||
| 586 | static u64 phys_pmem_align_down(struct nd_pfn *nd_pfn, u64 phys) | ||
| 587 | { | ||
| 588 | return min_t(u64, PHYS_SECTION_ALIGN_DOWN(phys), | ||
| 589 | ALIGN_DOWN(phys, nd_pfn->align)); | ||
| 590 | } | ||
| 591 | |||
| 585 | static int nd_pfn_init(struct nd_pfn *nd_pfn) | 592 | static int nd_pfn_init(struct nd_pfn *nd_pfn) |
| 586 | { | 593 | { |
| 587 | u32 dax_label_reserve = is_nd_dax(&nd_pfn->dev) ? SZ_128K : 0; | 594 | u32 dax_label_reserve = is_nd_dax(&nd_pfn->dev) ? SZ_128K : 0; |
| @@ -637,13 +644,16 @@ static int nd_pfn_init(struct nd_pfn *nd_pfn) | |||
| 637 | start = nsio->res.start; | 644 | start = nsio->res.start; |
| 638 | size = PHYS_SECTION_ALIGN_UP(start + size) - start; | 645 | size = PHYS_SECTION_ALIGN_UP(start + size) - start; |
| 639 | if (region_intersects(start, size, IORESOURCE_SYSTEM_RAM, | 646 | if (region_intersects(start, size, IORESOURCE_SYSTEM_RAM, |
| 640 | IORES_DESC_NONE) == REGION_MIXED) { | 647 | IORES_DESC_NONE) == REGION_MIXED |
| 648 | || !IS_ALIGNED(start + resource_size(&nsio->res), | ||
| 649 | nd_pfn->align)) { | ||
| 641 | size = resource_size(&nsio->res); | 650 | size = resource_size(&nsio->res); |
| 642 | end_trunc = start + size - PHYS_SECTION_ALIGN_DOWN(start + size); | 651 | end_trunc = start + size - phys_pmem_align_down(nd_pfn, |
| 652 | start + size); | ||
| 643 | } | 653 | } |
| 644 | 654 | ||
| 645 | if (start_pad + end_trunc) | 655 | if (start_pad + end_trunc) |
| 646 | dev_info(&nd_pfn->dev, "%s section collision, truncate %d bytes\n", | 656 | dev_info(&nd_pfn->dev, "%s alignment collision, truncate %d bytes\n", |
| 647 | dev_name(&ndns->dev), start_pad + end_trunc); | 657 | dev_name(&ndns->dev), start_pad + end_trunc); |
| 648 | 658 | ||
| 649 | /* | 659 | /* |
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index f837d666cbd4..1e46e60b8f10 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c | |||
| @@ -1287,7 +1287,7 @@ static void nvme_config_discard(struct nvme_ctrl *ctrl, | |||
| 1287 | BUILD_BUG_ON(PAGE_SIZE / sizeof(struct nvme_dsm_range) < | 1287 | BUILD_BUG_ON(PAGE_SIZE / sizeof(struct nvme_dsm_range) < |
| 1288 | NVME_DSM_MAX_RANGES); | 1288 | NVME_DSM_MAX_RANGES); |
| 1289 | 1289 | ||
| 1290 | queue->limits.discard_alignment = size; | 1290 | queue->limits.discard_alignment = 0; |
| 1291 | queue->limits.discard_granularity = size; | 1291 | queue->limits.discard_granularity = size; |
| 1292 | 1292 | ||
| 1293 | blk_queue_max_discard_sectors(queue, UINT_MAX); | 1293 | blk_queue_max_discard_sectors(queue, UINT_MAX); |
| @@ -1705,7 +1705,8 @@ static void nvme_set_queue_limits(struct nvme_ctrl *ctrl, | |||
| 1705 | blk_queue_max_hw_sectors(q, ctrl->max_hw_sectors); | 1705 | blk_queue_max_hw_sectors(q, ctrl->max_hw_sectors); |
| 1706 | blk_queue_max_segments(q, min_t(u32, max_segments, USHRT_MAX)); | 1706 | blk_queue_max_segments(q, min_t(u32, max_segments, USHRT_MAX)); |
| 1707 | } | 1707 | } |
| 1708 | if (ctrl->quirks & NVME_QUIRK_STRIPE_SIZE) | 1708 | if ((ctrl->quirks & NVME_QUIRK_STRIPE_SIZE) && |
| 1709 | is_power_of_2(ctrl->max_hw_sectors)) | ||
| 1709 | blk_queue_chunk_sectors(q, ctrl->max_hw_sectors); | 1710 | blk_queue_chunk_sectors(q, ctrl->max_hw_sectors); |
| 1710 | blk_queue_virt_boundary(q, ctrl->page_size - 1); | 1711 | blk_queue_virt_boundary(q, ctrl->page_size - 1); |
| 1711 | if (ctrl->vwc & NVME_CTRL_VWC_PRESENT) | 1712 | if (ctrl->vwc & NVME_CTRL_VWC_PRESENT) |
| @@ -2869,7 +2870,6 @@ static void nvme_alloc_ns(struct nvme_ctrl *ctrl, unsigned nsid) | |||
| 2869 | 2870 | ||
| 2870 | blk_queue_logical_block_size(ns->queue, 1 << ns->lba_shift); | 2871 | blk_queue_logical_block_size(ns->queue, 1 << ns->lba_shift); |
| 2871 | nvme_set_queue_limits(ctrl, ns->queue); | 2872 | nvme_set_queue_limits(ctrl, ns->queue); |
| 2872 | nvme_setup_streams_ns(ctrl, ns); | ||
| 2873 | 2873 | ||
| 2874 | id = nvme_identify_ns(ctrl, nsid); | 2874 | id = nvme_identify_ns(ctrl, nsid); |
| 2875 | if (!id) | 2875 | if (!id) |
| @@ -2880,6 +2880,7 @@ static void nvme_alloc_ns(struct nvme_ctrl *ctrl, unsigned nsid) | |||
| 2880 | 2880 | ||
| 2881 | if (nvme_init_ns_head(ns, nsid, id, &new)) | 2881 | if (nvme_init_ns_head(ns, nsid, id, &new)) |
| 2882 | goto out_free_id; | 2882 | goto out_free_id; |
| 2883 | nvme_setup_streams_ns(ctrl, ns); | ||
| 2883 | 2884 | ||
| 2884 | #ifdef CONFIG_NVME_MULTIPATH | 2885 | #ifdef CONFIG_NVME_MULTIPATH |
| 2885 | /* | 2886 | /* |
| @@ -2965,8 +2966,6 @@ static void nvme_ns_remove(struct nvme_ns *ns) | |||
| 2965 | return; | 2966 | return; |
| 2966 | 2967 | ||
| 2967 | if (ns->disk && ns->disk->flags & GENHD_FL_UP) { | 2968 | if (ns->disk && ns->disk->flags & GENHD_FL_UP) { |
| 2968 | if (blk_get_integrity(ns->disk)) | ||
| 2969 | blk_integrity_unregister(ns->disk); | ||
| 2970 | nvme_mpath_remove_disk_links(ns); | 2969 | nvme_mpath_remove_disk_links(ns); |
| 2971 | sysfs_remove_group(&disk_to_dev(ns->disk)->kobj, | 2970 | sysfs_remove_group(&disk_to_dev(ns->disk)->kobj, |
| 2972 | &nvme_ns_id_attr_group); | 2971 | &nvme_ns_id_attr_group); |
| @@ -2974,6 +2973,8 @@ static void nvme_ns_remove(struct nvme_ns *ns) | |||
| 2974 | nvme_nvm_unregister_sysfs(ns); | 2973 | nvme_nvm_unregister_sysfs(ns); |
| 2975 | del_gendisk(ns->disk); | 2974 | del_gendisk(ns->disk); |
| 2976 | blk_cleanup_queue(ns->queue); | 2975 | blk_cleanup_queue(ns->queue); |
| 2976 | if (blk_get_integrity(ns->disk)) | ||
| 2977 | blk_integrity_unregister(ns->disk); | ||
| 2977 | } | 2978 | } |
| 2978 | 2979 | ||
| 2979 | mutex_lock(&ns->ctrl->subsys->lock); | 2980 | mutex_lock(&ns->ctrl->subsys->lock); |
diff --git a/drivers/nvme/host/fc.c b/drivers/nvme/host/fc.c index 0a8af4daef89..794e66e4aa20 100644 --- a/drivers/nvme/host/fc.c +++ b/drivers/nvme/host/fc.c | |||
| @@ -3221,7 +3221,6 @@ nvme_fc_init_ctrl(struct device *dev, struct nvmf_ctrl_options *opts, | |||
| 3221 | 3221 | ||
| 3222 | /* initiate nvme ctrl ref counting teardown */ | 3222 | /* initiate nvme ctrl ref counting teardown */ |
| 3223 | nvme_uninit_ctrl(&ctrl->ctrl); | 3223 | nvme_uninit_ctrl(&ctrl->ctrl); |
| 3224 | nvme_put_ctrl(&ctrl->ctrl); | ||
| 3225 | 3224 | ||
| 3226 | /* Remove core ctrl ref. */ | 3225 | /* Remove core ctrl ref. */ |
| 3227 | nvme_put_ctrl(&ctrl->ctrl); | 3226 | nvme_put_ctrl(&ctrl->ctrl); |
diff --git a/drivers/nvmem/meson-mx-efuse.c b/drivers/nvmem/meson-mx-efuse.c index a346b4923550..41d3a3c1104e 100644 --- a/drivers/nvmem/meson-mx-efuse.c +++ b/drivers/nvmem/meson-mx-efuse.c | |||
| @@ -156,8 +156,8 @@ static int meson_mx_efuse_read(void *context, unsigned int offset, | |||
| 156 | MESON_MX_EFUSE_CNTL1_AUTO_RD_ENABLE, | 156 | MESON_MX_EFUSE_CNTL1_AUTO_RD_ENABLE, |
| 157 | MESON_MX_EFUSE_CNTL1_AUTO_RD_ENABLE); | 157 | MESON_MX_EFUSE_CNTL1_AUTO_RD_ENABLE); |
| 158 | 158 | ||
| 159 | for (i = offset; i < offset + bytes; i += efuse->config.word_size) { | 159 | for (i = 0; i < bytes; i += efuse->config.word_size) { |
| 160 | addr = i / efuse->config.word_size; | 160 | addr = (offset + i) / efuse->config.word_size; |
| 161 | 161 | ||
| 162 | err = meson_mx_efuse_read_addr(efuse, addr, &tmp); | 162 | err = meson_mx_efuse_read_addr(efuse, addr, &tmp); |
| 163 | if (err) | 163 | if (err) |
diff --git a/drivers/of/of_mdio.c b/drivers/of/of_mdio.c index 98258583abb0..3481e69738b5 100644 --- a/drivers/of/of_mdio.c +++ b/drivers/of/of_mdio.c | |||
| @@ -81,6 +81,7 @@ static int of_mdiobus_register_phy(struct mii_bus *mdio, | |||
| 81 | * can be looked up later */ | 81 | * can be looked up later */ |
| 82 | of_node_get(child); | 82 | of_node_get(child); |
| 83 | phy->mdio.dev.of_node = child; | 83 | phy->mdio.dev.of_node = child; |
| 84 | phy->mdio.dev.fwnode = of_fwnode_handle(child); | ||
| 84 | 85 | ||
| 85 | /* All data is now stored in the phy struct; | 86 | /* All data is now stored in the phy struct; |
| 86 | * register it */ | 87 | * register it */ |
| @@ -111,6 +112,7 @@ static int of_mdiobus_register_device(struct mii_bus *mdio, | |||
| 111 | */ | 112 | */ |
| 112 | of_node_get(child); | 113 | of_node_get(child); |
| 113 | mdiodev->dev.of_node = child; | 114 | mdiodev->dev.of_node = child; |
| 115 | mdiodev->dev.fwnode = of_fwnode_handle(child); | ||
| 114 | 116 | ||
| 115 | /* All data is now stored in the mdiodev struct; register it. */ | 117 | /* All data is now stored in the mdiodev struct; register it. */ |
| 116 | rc = mdio_device_register(mdiodev); | 118 | rc = mdio_device_register(mdiodev); |
| @@ -206,6 +208,7 @@ int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np) | |||
| 206 | mdio->phy_mask = ~0; | 208 | mdio->phy_mask = ~0; |
| 207 | 209 | ||
| 208 | mdio->dev.of_node = np; | 210 | mdio->dev.of_node = np; |
| 211 | mdio->dev.fwnode = of_fwnode_handle(np); | ||
| 209 | 212 | ||
| 210 | /* Get bus level PHY reset GPIO details */ | 213 | /* Get bus level PHY reset GPIO details */ |
| 211 | mdio->reset_delay_us = DEFAULT_GPIO_RESET_DELAY; | 214 | mdio->reset_delay_us = DEFAULT_GPIO_RESET_DELAY; |
diff --git a/drivers/parisc/lba_pci.c b/drivers/parisc/lba_pci.c index a25fed52f7e9..41b740aed3a3 100644 --- a/drivers/parisc/lba_pci.c +++ b/drivers/parisc/lba_pci.c | |||
| @@ -1692,3 +1692,36 @@ void lba_set_iregs(struct parisc_device *lba, u32 ibase, u32 imask) | |||
| 1692 | iounmap(base_addr); | 1692 | iounmap(base_addr); |
| 1693 | } | 1693 | } |
| 1694 | 1694 | ||
| 1695 | |||
| 1696 | /* | ||
| 1697 | * The design of the Diva management card in rp34x0 machines (rp3410, rp3440) | ||
| 1698 | * seems rushed, so that many built-in components simply don't work. | ||
| 1699 | * The following quirks disable the serial AUX port and the built-in ATI RV100 | ||
| 1700 | * Radeon 7000 graphics card which both don't have any external connectors and | ||
| 1701 | * thus are useless, and even worse, e.g. the AUX port occupies ttyS0 and as | ||
| 1702 | * such makes those machines the only PARISC machines on which we can't use | ||
| 1703 | * ttyS0 as boot console. | ||
| 1704 | */ | ||
| 1705 | static void quirk_diva_ati_card(struct pci_dev *dev) | ||
| 1706 | { | ||
| 1707 | if (dev->subsystem_vendor != PCI_VENDOR_ID_HP || | ||
| 1708 | dev->subsystem_device != 0x1292) | ||
| 1709 | return; | ||
| 1710 | |||
| 1711 | dev_info(&dev->dev, "Hiding Diva built-in ATI card"); | ||
| 1712 | dev->device = 0; | ||
| 1713 | } | ||
| 1714 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QY, | ||
| 1715 | quirk_diva_ati_card); | ||
| 1716 | |||
| 1717 | static void quirk_diva_aux_disable(struct pci_dev *dev) | ||
| 1718 | { | ||
| 1719 | if (dev->subsystem_vendor != PCI_VENDOR_ID_HP || | ||
| 1720 | dev->subsystem_device != 0x1291) | ||
| 1721 | return; | ||
| 1722 | |||
| 1723 | dev_info(&dev->dev, "Hiding Diva built-in AUX serial device"); | ||
| 1724 | dev->device = 0; | ||
| 1725 | } | ||
| 1726 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_DIVA_AUX, | ||
| 1727 | quirk_diva_aux_disable); | ||
diff --git a/drivers/pci/host/pci-hyperv.c b/drivers/pci/host/pci-hyperv.c index 04dac6a42c9f..6b8d060d07de 100644 --- a/drivers/pci/host/pci-hyperv.c +++ b/drivers/pci/host/pci-hyperv.c | |||
| @@ -985,9 +985,7 @@ static u32 hv_compose_msi_req_v1( | |||
| 985 | int_pkt->wslot.slot = slot; | 985 | int_pkt->wslot.slot = slot; |
| 986 | int_pkt->int_desc.vector = vector; | 986 | int_pkt->int_desc.vector = vector; |
| 987 | int_pkt->int_desc.vector_count = 1; | 987 | int_pkt->int_desc.vector_count = 1; |
| 988 | int_pkt->int_desc.delivery_mode = | 988 | int_pkt->int_desc.delivery_mode = dest_Fixed; |
| 989 | (apic->irq_delivery_mode == dest_LowestPrio) ? | ||
| 990 | dest_LowestPrio : dest_Fixed; | ||
| 991 | 989 | ||
| 992 | /* | 990 | /* |
| 993 | * Create MSI w/ dummy vCPU set, overwritten by subsequent retarget in | 991 | * Create MSI w/ dummy vCPU set, overwritten by subsequent retarget in |
| @@ -1008,9 +1006,7 @@ static u32 hv_compose_msi_req_v2( | |||
| 1008 | int_pkt->wslot.slot = slot; | 1006 | int_pkt->wslot.slot = slot; |
| 1009 | int_pkt->int_desc.vector = vector; | 1007 | int_pkt->int_desc.vector = vector; |
| 1010 | int_pkt->int_desc.vector_count = 1; | 1008 | int_pkt->int_desc.vector_count = 1; |
| 1011 | int_pkt->int_desc.delivery_mode = | 1009 | int_pkt->int_desc.delivery_mode = dest_Fixed; |
| 1012 | (apic->irq_delivery_mode == dest_LowestPrio) ? | ||
| 1013 | dest_LowestPrio : dest_Fixed; | ||
| 1014 | 1010 | ||
| 1015 | /* | 1011 | /* |
| 1016 | * Create MSI w/ dummy vCPU set targeting just one vCPU, overwritten | 1012 | * Create MSI w/ dummy vCPU set targeting just one vCPU, overwritten |
diff --git a/drivers/pci/host/pcie-rcar.c b/drivers/pci/host/pcie-rcar.c index 12796eccb2be..52ab3cb0a0bf 100644 --- a/drivers/pci/host/pcie-rcar.c +++ b/drivers/pci/host/pcie-rcar.c | |||
| @@ -1128,12 +1128,12 @@ static int rcar_pcie_probe(struct platform_device *pdev) | |||
| 1128 | err = rcar_pcie_get_resources(pcie); | 1128 | err = rcar_pcie_get_resources(pcie); |
| 1129 | if (err < 0) { | 1129 | if (err < 0) { |
| 1130 | dev_err(dev, "failed to request resources: %d\n", err); | 1130 | dev_err(dev, "failed to request resources: %d\n", err); |
| 1131 | goto err_free_bridge; | 1131 | goto err_free_resource_list; |
| 1132 | } | 1132 | } |
| 1133 | 1133 | ||
| 1134 | err = rcar_pcie_parse_map_dma_ranges(pcie, dev->of_node); | 1134 | err = rcar_pcie_parse_map_dma_ranges(pcie, dev->of_node); |
| 1135 | if (err) | 1135 | if (err) |
| 1136 | goto err_free_bridge; | 1136 | goto err_free_resource_list; |
| 1137 | 1137 | ||
| 1138 | pm_runtime_enable(dev); | 1138 | pm_runtime_enable(dev); |
| 1139 | err = pm_runtime_get_sync(dev); | 1139 | err = pm_runtime_get_sync(dev); |
| @@ -1176,9 +1176,9 @@ err_pm_put: | |||
| 1176 | err_pm_disable: | 1176 | err_pm_disable: |
| 1177 | pm_runtime_disable(dev); | 1177 | pm_runtime_disable(dev); |
| 1178 | 1178 | ||
| 1179 | err_free_bridge: | 1179 | err_free_resource_list: |
| 1180 | pci_free_host_bridge(bridge); | ||
| 1181 | pci_free_resource_list(&pcie->resources); | 1180 | pci_free_resource_list(&pcie->resources); |
| 1181 | pci_free_host_bridge(bridge); | ||
| 1182 | 1182 | ||
| 1183 | return err; | 1183 | return err; |
| 1184 | } | 1184 | } |
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index 7f47bb72bf30..14fd865a5120 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c | |||
| @@ -999,7 +999,7 @@ static int pci_pm_thaw_noirq(struct device *dev) | |||
| 999 | * the subsequent "thaw" callbacks for the device. | 999 | * the subsequent "thaw" callbacks for the device. |
| 1000 | */ | 1000 | */ |
| 1001 | if (dev_pm_smart_suspend_and_suspended(dev)) { | 1001 | if (dev_pm_smart_suspend_and_suspended(dev)) { |
| 1002 | dev->power.direct_complete = true; | 1002 | dev_pm_skip_next_resume_phases(dev); |
| 1003 | return 0; | 1003 | return 0; |
| 1004 | } | 1004 | } |
| 1005 | 1005 | ||
| @@ -1012,7 +1012,12 @@ static int pci_pm_thaw_noirq(struct device *dev) | |||
| 1012 | if (pci_has_legacy_pm_support(pci_dev)) | 1012 | if (pci_has_legacy_pm_support(pci_dev)) |
| 1013 | return pci_legacy_resume_early(dev); | 1013 | return pci_legacy_resume_early(dev); |
| 1014 | 1014 | ||
| 1015 | pci_update_current_state(pci_dev, PCI_D0); | 1015 | /* |
| 1016 | * pci_restore_state() requires the device to be in D0 (because of MSI | ||
| 1017 | * restoration among other things), so force it into D0 in case the | ||
| 1018 | * driver's "freeze" callbacks put it into a low-power state directly. | ||
| 1019 | */ | ||
| 1020 | pci_set_power_state(pci_dev, PCI_D0); | ||
| 1016 | pci_restore_state(pci_dev); | 1021 | pci_restore_state(pci_dev); |
| 1017 | 1022 | ||
| 1018 | if (drv && drv->pm && drv->pm->thaw_noirq) | 1023 | if (drv && drv->pm && drv->pm->thaw_noirq) |
diff --git a/drivers/phy/motorola/phy-cpcap-usb.c b/drivers/phy/motorola/phy-cpcap-usb.c index accaaaccb662..6601ad0dfb3a 100644 --- a/drivers/phy/motorola/phy-cpcap-usb.c +++ b/drivers/phy/motorola/phy-cpcap-usb.c | |||
| @@ -310,7 +310,7 @@ static int cpcap_usb_init_irq(struct platform_device *pdev, | |||
| 310 | int irq, error; | 310 | int irq, error; |
| 311 | 311 | ||
| 312 | irq = platform_get_irq_byname(pdev, name); | 312 | irq = platform_get_irq_byname(pdev, name); |
| 313 | if (!irq) | 313 | if (irq < 0) |
| 314 | return -ENODEV; | 314 | return -ENODEV; |
| 315 | 315 | ||
| 316 | error = devm_request_threaded_irq(ddata->dev, irq, NULL, | 316 | error = devm_request_threaded_irq(ddata->dev, irq, NULL, |
diff --git a/drivers/phy/renesas/Kconfig b/drivers/phy/renesas/Kconfig index cb09245e9b4c..c845facacb06 100644 --- a/drivers/phy/renesas/Kconfig +++ b/drivers/phy/renesas/Kconfig | |||
| @@ -12,7 +12,9 @@ config PHY_RCAR_GEN3_USB2 | |||
| 12 | tristate "Renesas R-Car generation 3 USB 2.0 PHY driver" | 12 | tristate "Renesas R-Car generation 3 USB 2.0 PHY driver" |
| 13 | depends on ARCH_RENESAS | 13 | depends on ARCH_RENESAS |
| 14 | depends on EXTCON | 14 | depends on EXTCON |
| 15 | depends on USB_SUPPORT | ||
| 15 | select GENERIC_PHY | 16 | select GENERIC_PHY |
| 17 | select USB_COMMON | ||
| 16 | help | 18 | help |
| 17 | Support for USB 2.0 PHY found on Renesas R-Car generation 3 SoCs. | 19 | Support for USB 2.0 PHY found on Renesas R-Car generation 3 SoCs. |
| 18 | 20 | ||
diff --git a/drivers/phy/rockchip/phy-rockchip-typec.c b/drivers/phy/rockchip/phy-rockchip-typec.c index ee85fa0ca4b0..7492c8978217 100644 --- a/drivers/phy/rockchip/phy-rockchip-typec.c +++ b/drivers/phy/rockchip/phy-rockchip-typec.c | |||
| @@ -1137,6 +1137,7 @@ static int rockchip_typec_phy_probe(struct platform_device *pdev) | |||
| 1137 | if (IS_ERR(phy)) { | 1137 | if (IS_ERR(phy)) { |
| 1138 | dev_err(dev, "failed to create phy: %s\n", | 1138 | dev_err(dev, "failed to create phy: %s\n", |
| 1139 | child_np->name); | 1139 | child_np->name); |
| 1140 | pm_runtime_disable(dev); | ||
| 1140 | return PTR_ERR(phy); | 1141 | return PTR_ERR(phy); |
| 1141 | } | 1142 | } |
| 1142 | 1143 | ||
| @@ -1146,6 +1147,7 @@ static int rockchip_typec_phy_probe(struct platform_device *pdev) | |||
| 1146 | phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); | 1147 | phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); |
| 1147 | if (IS_ERR(phy_provider)) { | 1148 | if (IS_ERR(phy_provider)) { |
| 1148 | dev_err(dev, "Failed to register phy provider\n"); | 1149 | dev_err(dev, "Failed to register phy provider\n"); |
| 1150 | pm_runtime_disable(dev); | ||
| 1149 | return PTR_ERR(phy_provider); | 1151 | return PTR_ERR(phy_provider); |
| 1150 | } | 1152 | } |
| 1151 | 1153 | ||
diff --git a/drivers/phy/tegra/xusb.c b/drivers/phy/tegra/xusb.c index 4307bf0013e1..63e916d4d069 100644 --- a/drivers/phy/tegra/xusb.c +++ b/drivers/phy/tegra/xusb.c | |||
| @@ -75,14 +75,14 @@ MODULE_DEVICE_TABLE(of, tegra_xusb_padctl_of_match); | |||
| 75 | static struct device_node * | 75 | static struct device_node * |
| 76 | tegra_xusb_find_pad_node(struct tegra_xusb_padctl *padctl, const char *name) | 76 | tegra_xusb_find_pad_node(struct tegra_xusb_padctl *padctl, const char *name) |
| 77 | { | 77 | { |
| 78 | /* | 78 | struct device_node *pads, *np; |
| 79 | * of_find_node_by_name() drops a reference, so make sure to grab one. | 79 | |
| 80 | */ | 80 | pads = of_get_child_by_name(padctl->dev->of_node, "pads"); |
| 81 | struct device_node *np = of_node_get(padctl->dev->of_node); | 81 | if (!pads) |
| 82 | return NULL; | ||
| 82 | 83 | ||
| 83 | np = of_find_node_by_name(np, "pads"); | 84 | np = of_get_child_by_name(pads, name); |
| 84 | if (np) | 85 | of_node_put(pads); |
| 85 | np = of_find_node_by_name(np, name); | ||
| 86 | 86 | ||
| 87 | return np; | 87 | return np; |
| 88 | } | 88 | } |
| @@ -90,16 +90,16 @@ tegra_xusb_find_pad_node(struct tegra_xusb_padctl *padctl, const char *name) | |||
| 90 | static struct device_node * | 90 | static struct device_node * |
| 91 | tegra_xusb_pad_find_phy_node(struct tegra_xusb_pad *pad, unsigned int index) | 91 | tegra_xusb_pad_find_phy_node(struct tegra_xusb_pad *pad, unsigned int index) |
| 92 | { | 92 | { |
| 93 | /* | 93 | struct device_node *np, *lanes; |
| 94 | * of_find_node_by_name() drops a reference, so make sure to grab one. | ||
| 95 | */ | ||
| 96 | struct device_node *np = of_node_get(pad->dev.of_node); | ||
| 97 | 94 | ||
| 98 | np = of_find_node_by_name(np, "lanes"); | 95 | lanes = of_get_child_by_name(pad->dev.of_node, "lanes"); |
| 99 | if (!np) | 96 | if (!lanes) |
| 100 | return NULL; | 97 | return NULL; |
| 101 | 98 | ||
| 102 | return of_find_node_by_name(np, pad->soc->lanes[index].name); | 99 | np = of_get_child_by_name(lanes, pad->soc->lanes[index].name); |
| 100 | of_node_put(lanes); | ||
| 101 | |||
| 102 | return np; | ||
| 103 | } | 103 | } |
| 104 | 104 | ||
| 105 | static int | 105 | static int |
| @@ -195,7 +195,7 @@ int tegra_xusb_pad_register(struct tegra_xusb_pad *pad, | |||
| 195 | unsigned int i; | 195 | unsigned int i; |
| 196 | int err; | 196 | int err; |
| 197 | 197 | ||
| 198 | children = of_find_node_by_name(pad->dev.of_node, "lanes"); | 198 | children = of_get_child_by_name(pad->dev.of_node, "lanes"); |
| 199 | if (!children) | 199 | if (!children) |
| 200 | return -ENODEV; | 200 | return -ENODEV; |
| 201 | 201 | ||
| @@ -444,21 +444,21 @@ static struct device_node * | |||
| 444 | tegra_xusb_find_port_node(struct tegra_xusb_padctl *padctl, const char *type, | 444 | tegra_xusb_find_port_node(struct tegra_xusb_padctl *padctl, const char *type, |
| 445 | unsigned int index) | 445 | unsigned int index) |
| 446 | { | 446 | { |
| 447 | /* | 447 | struct device_node *ports, *np; |
| 448 | * of_find_node_by_name() drops a reference, so make sure to grab one. | 448 | char *name; |
| 449 | */ | ||
| 450 | struct device_node *np = of_node_get(padctl->dev->of_node); | ||
| 451 | 449 | ||
| 452 | np = of_find_node_by_name(np, "ports"); | 450 | ports = of_get_child_by_name(padctl->dev->of_node, "ports"); |
| 453 | if (np) { | 451 | if (!ports) |
| 454 | char *name; | 452 | return NULL; |
| 455 | 453 | ||
| 456 | name = kasprintf(GFP_KERNEL, "%s-%u", type, index); | 454 | name = kasprintf(GFP_KERNEL, "%s-%u", type, index); |
| 457 | if (!name) | 455 | if (!name) { |
| 458 | return ERR_PTR(-ENOMEM); | 456 | of_node_put(ports); |
| 459 | np = of_find_node_by_name(np, name); | 457 | return ERR_PTR(-ENOMEM); |
| 460 | kfree(name); | ||
| 461 | } | 458 | } |
| 459 | np = of_get_child_by_name(ports, name); | ||
| 460 | kfree(name); | ||
| 461 | of_node_put(ports); | ||
| 462 | 462 | ||
| 463 | return np; | 463 | return np; |
| 464 | } | 464 | } |
| @@ -847,7 +847,7 @@ static void tegra_xusb_remove_ports(struct tegra_xusb_padctl *padctl) | |||
| 847 | 847 | ||
| 848 | static int tegra_xusb_padctl_probe(struct platform_device *pdev) | 848 | static int tegra_xusb_padctl_probe(struct platform_device *pdev) |
| 849 | { | 849 | { |
| 850 | struct device_node *np = of_node_get(pdev->dev.of_node); | 850 | struct device_node *np = pdev->dev.of_node; |
| 851 | const struct tegra_xusb_padctl_soc *soc; | 851 | const struct tegra_xusb_padctl_soc *soc; |
| 852 | struct tegra_xusb_padctl *padctl; | 852 | struct tegra_xusb_padctl *padctl; |
| 853 | const struct of_device_id *match; | 853 | const struct of_device_id *match; |
| @@ -855,7 +855,7 @@ static int tegra_xusb_padctl_probe(struct platform_device *pdev) | |||
| 855 | int err; | 855 | int err; |
| 856 | 856 | ||
| 857 | /* for backwards compatibility with old device trees */ | 857 | /* for backwards compatibility with old device trees */ |
| 858 | np = of_find_node_by_name(np, "pads"); | 858 | np = of_get_child_by_name(np, "pads"); |
| 859 | if (!np) { | 859 | if (!np) { |
| 860 | dev_warn(&pdev->dev, "deprecated DT, using legacy driver\n"); | 860 | dev_warn(&pdev->dev, "deprecated DT, using legacy driver\n"); |
| 861 | return tegra_xusb_padctl_legacy_probe(pdev); | 861 | return tegra_xusb_padctl_legacy_probe(pdev); |
diff --git a/drivers/pinctrl/intel/pinctrl-cherryview.c b/drivers/pinctrl/intel/pinctrl-cherryview.c index bdedb6325c72..4471fd94e1fe 100644 --- a/drivers/pinctrl/intel/pinctrl-cherryview.c +++ b/drivers/pinctrl/intel/pinctrl-cherryview.c | |||
| @@ -1620,6 +1620,22 @@ static int chv_gpio_probe(struct chv_pinctrl *pctrl, int irq) | |||
| 1620 | clear_bit(i, chip->irq.valid_mask); | 1620 | clear_bit(i, chip->irq.valid_mask); |
| 1621 | } | 1621 | } |
| 1622 | 1622 | ||
| 1623 | /* | ||
| 1624 | * The same set of machines in chv_no_valid_mask[] have incorrectly | ||
| 1625 | * configured GPIOs that generate spurious interrupts so we use | ||
| 1626 | * this same list to apply another quirk for them. | ||
| 1627 | * | ||
| 1628 | * See also https://bugzilla.kernel.org/show_bug.cgi?id=197953. | ||
| 1629 | */ | ||
| 1630 | if (!need_valid_mask) { | ||
| 1631 | /* | ||
| 1632 | * Mask all interrupts the community is able to generate | ||
| 1633 | * but leave the ones that can only generate GPEs unmasked. | ||
| 1634 | */ | ||
| 1635 | chv_writel(GENMASK(31, pctrl->community->nirqs), | ||
| 1636 | pctrl->regs + CHV_INTMASK); | ||
| 1637 | } | ||
| 1638 | |||
| 1623 | /* Clear all interrupts */ | 1639 | /* Clear all interrupts */ |
| 1624 | chv_writel(0xffff, pctrl->regs + CHV_INTSTAT); | 1640 | chv_writel(0xffff, pctrl->regs + CHV_INTSTAT); |
| 1625 | 1641 | ||
diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c index e6cd8de793e2..3501491e5bfc 100644 --- a/drivers/pinctrl/pinctrl-single.c +++ b/drivers/pinctrl/pinctrl-single.c | |||
| @@ -222,6 +222,9 @@ static enum pin_config_param pcs_bias[] = { | |||
| 222 | */ | 222 | */ |
| 223 | static struct lock_class_key pcs_lock_class; | 223 | static struct lock_class_key pcs_lock_class; |
| 224 | 224 | ||
| 225 | /* Class for the IRQ request mutex */ | ||
| 226 | static struct lock_class_key pcs_request_class; | ||
| 227 | |||
| 225 | /* | 228 | /* |
| 226 | * REVISIT: Reads and writes could eventually use regmap or something | 229 | * REVISIT: Reads and writes could eventually use regmap or something |
| 227 | * generic. But at least on omaps, some mux registers are performance | 230 | * generic. But at least on omaps, some mux registers are performance |
| @@ -1486,7 +1489,7 @@ static int pcs_irqdomain_map(struct irq_domain *d, unsigned int irq, | |||
| 1486 | irq_set_chip_data(irq, pcs_soc); | 1489 | irq_set_chip_data(irq, pcs_soc); |
| 1487 | irq_set_chip_and_handler(irq, &pcs->chip, | 1490 | irq_set_chip_and_handler(irq, &pcs->chip, |
| 1488 | handle_level_irq); | 1491 | handle_level_irq); |
| 1489 | irq_set_lockdep_class(irq, &pcs_lock_class); | 1492 | irq_set_lockdep_class(irq, &pcs_lock_class, &pcs_request_class); |
| 1490 | irq_set_noprobe(irq); | 1493 | irq_set_noprobe(irq); |
| 1491 | 1494 | ||
| 1492 | return 0; | 1495 | return 0; |
diff --git a/drivers/pinctrl/stm32/pinctrl-stm32.c b/drivers/pinctrl/stm32/pinctrl-stm32.c index a276c61be217..e62ab087bfd8 100644 --- a/drivers/pinctrl/stm32/pinctrl-stm32.c +++ b/drivers/pinctrl/stm32/pinctrl-stm32.c | |||
| @@ -290,7 +290,7 @@ static int stm32_gpio_domain_translate(struct irq_domain *d, | |||
| 290 | } | 290 | } |
| 291 | 291 | ||
| 292 | static int stm32_gpio_domain_activate(struct irq_domain *d, | 292 | static int stm32_gpio_domain_activate(struct irq_domain *d, |
| 293 | struct irq_data *irq_data, bool early) | 293 | struct irq_data *irq_data, bool reserve) |
| 294 | { | 294 | { |
| 295 | struct stm32_gpio_bank *bank = d->host_data; | 295 | struct stm32_gpio_bank *bank = d->host_data; |
| 296 | struct stm32_pinctrl *pctl = dev_get_drvdata(bank->gpio_chip.parent); | 296 | struct stm32_pinctrl *pctl = dev_get_drvdata(bank->gpio_chip.parent); |
diff --git a/drivers/platform/x86/asus-wireless.c b/drivers/platform/x86/asus-wireless.c index f3796164329e..d4aeac3477f5 100644 --- a/drivers/platform/x86/asus-wireless.c +++ b/drivers/platform/x86/asus-wireless.c | |||
| @@ -118,6 +118,7 @@ static void asus_wireless_notify(struct acpi_device *adev, u32 event) | |||
| 118 | return; | 118 | return; |
| 119 | } | 119 | } |
| 120 | input_report_key(data->idev, KEY_RFKILL, 1); | 120 | input_report_key(data->idev, KEY_RFKILL, 1); |
| 121 | input_sync(data->idev); | ||
| 121 | input_report_key(data->idev, KEY_RFKILL, 0); | 122 | input_report_key(data->idev, KEY_RFKILL, 0); |
| 122 | input_sync(data->idev); | 123 | input_sync(data->idev); |
| 123 | } | 124 | } |
diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c index bf897b1832b1..cd4725e7e0b5 100644 --- a/drivers/platform/x86/dell-laptop.c +++ b/drivers/platform/x86/dell-laptop.c | |||
| @@ -37,6 +37,7 @@ | |||
| 37 | 37 | ||
| 38 | struct quirk_entry { | 38 | struct quirk_entry { |
| 39 | u8 touchpad_led; | 39 | u8 touchpad_led; |
| 40 | u8 kbd_led_levels_off_1; | ||
| 40 | 41 | ||
| 41 | int needs_kbd_timeouts; | 42 | int needs_kbd_timeouts; |
| 42 | /* | 43 | /* |
| @@ -67,6 +68,10 @@ static struct quirk_entry quirk_dell_xps13_9333 = { | |||
| 67 | .kbd_timeouts = { 0, 5, 15, 60, 5 * 60, 15 * 60, -1 }, | 68 | .kbd_timeouts = { 0, 5, 15, 60, 5 * 60, 15 * 60, -1 }, |
| 68 | }; | 69 | }; |
| 69 | 70 | ||
| 71 | static struct quirk_entry quirk_dell_latitude_e6410 = { | ||
| 72 | .kbd_led_levels_off_1 = 1, | ||
| 73 | }; | ||
| 74 | |||
| 70 | static struct platform_driver platform_driver = { | 75 | static struct platform_driver platform_driver = { |
| 71 | .driver = { | 76 | .driver = { |
| 72 | .name = "dell-laptop", | 77 | .name = "dell-laptop", |
| @@ -269,6 +274,15 @@ static const struct dmi_system_id dell_quirks[] __initconst = { | |||
| 269 | }, | 274 | }, |
| 270 | .driver_data = &quirk_dell_xps13_9333, | 275 | .driver_data = &quirk_dell_xps13_9333, |
| 271 | }, | 276 | }, |
| 277 | { | ||
| 278 | .callback = dmi_matched, | ||
| 279 | .ident = "Dell Latitude E6410", | ||
| 280 | .matches = { | ||
| 281 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
| 282 | DMI_MATCH(DMI_PRODUCT_NAME, "Latitude E6410"), | ||
| 283 | }, | ||
| 284 | .driver_data = &quirk_dell_latitude_e6410, | ||
| 285 | }, | ||
| 272 | { } | 286 | { } |
| 273 | }; | 287 | }; |
| 274 | 288 | ||
| @@ -1149,6 +1163,9 @@ static int kbd_get_info(struct kbd_info *info) | |||
| 1149 | units = (buffer->output[2] >> 8) & 0xFF; | 1163 | units = (buffer->output[2] >> 8) & 0xFF; |
| 1150 | info->levels = (buffer->output[2] >> 16) & 0xFF; | 1164 | info->levels = (buffer->output[2] >> 16) & 0xFF; |
| 1151 | 1165 | ||
| 1166 | if (quirks && quirks->kbd_led_levels_off_1 && info->levels) | ||
| 1167 | info->levels--; | ||
| 1168 | |||
| 1152 | if (units & BIT(0)) | 1169 | if (units & BIT(0)) |
| 1153 | info->seconds = (buffer->output[3] >> 0) & 0xFF; | 1170 | info->seconds = (buffer->output[3] >> 0) & 0xFF; |
| 1154 | if (units & BIT(1)) | 1171 | if (units & BIT(1)) |
diff --git a/drivers/platform/x86/dell-wmi.c b/drivers/platform/x86/dell-wmi.c index 39d2f4518483..fb25b20df316 100644 --- a/drivers/platform/x86/dell-wmi.c +++ b/drivers/platform/x86/dell-wmi.c | |||
| @@ -639,6 +639,8 @@ static int dell_wmi_events_set_enabled(bool enable) | |||
| 639 | int ret; | 639 | int ret; |
| 640 | 640 | ||
| 641 | buffer = kzalloc(sizeof(struct calling_interface_buffer), GFP_KERNEL); | 641 | buffer = kzalloc(sizeof(struct calling_interface_buffer), GFP_KERNEL); |
| 642 | if (!buffer) | ||
| 643 | return -ENOMEM; | ||
| 642 | buffer->cmd_class = CLASS_INFO; | 644 | buffer->cmd_class = CLASS_INFO; |
| 643 | buffer->cmd_select = SELECT_APP_REGISTRATION; | 645 | buffer->cmd_select = SELECT_APP_REGISTRATION; |
| 644 | buffer->input[0] = 0x10000; | 646 | buffer->input[0] = 0x10000; |
diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h index 15015a24f8ad..badf42acbf95 100644 --- a/drivers/s390/net/qeth_core.h +++ b/drivers/s390/net/qeth_core.h | |||
| @@ -565,9 +565,9 @@ enum qeth_cq { | |||
| 565 | }; | 565 | }; |
| 566 | 566 | ||
| 567 | struct qeth_ipato { | 567 | struct qeth_ipato { |
| 568 | int enabled; | 568 | bool enabled; |
| 569 | int invert4; | 569 | bool invert4; |
| 570 | int invert6; | 570 | bool invert6; |
| 571 | struct list_head entries; | 571 | struct list_head entries; |
| 572 | }; | 572 | }; |
| 573 | 573 | ||
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 430e3214f7e2..3614df68830f 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c | |||
| @@ -1480,9 +1480,9 @@ static int qeth_setup_card(struct qeth_card *card) | |||
| 1480 | qeth_set_intial_options(card); | 1480 | qeth_set_intial_options(card); |
| 1481 | /* IP address takeover */ | 1481 | /* IP address takeover */ |
| 1482 | INIT_LIST_HEAD(&card->ipato.entries); | 1482 | INIT_LIST_HEAD(&card->ipato.entries); |
| 1483 | card->ipato.enabled = 0; | 1483 | card->ipato.enabled = false; |
| 1484 | card->ipato.invert4 = 0; | 1484 | card->ipato.invert4 = false; |
| 1485 | card->ipato.invert6 = 0; | 1485 | card->ipato.invert6 = false; |
| 1486 | /* init QDIO stuff */ | 1486 | /* init QDIO stuff */ |
| 1487 | qeth_init_qdio_info(card); | 1487 | qeth_init_qdio_info(card); |
| 1488 | INIT_DELAYED_WORK(&card->buffer_reclaim_work, qeth_buffer_reclaim_work); | 1488 | INIT_DELAYED_WORK(&card->buffer_reclaim_work, qeth_buffer_reclaim_work); |
| @@ -5386,6 +5386,13 @@ out: | |||
| 5386 | } | 5386 | } |
| 5387 | EXPORT_SYMBOL_GPL(qeth_poll); | 5387 | EXPORT_SYMBOL_GPL(qeth_poll); |
| 5388 | 5388 | ||
| 5389 | static int qeth_setassparms_inspect_rc(struct qeth_ipa_cmd *cmd) | ||
| 5390 | { | ||
| 5391 | if (!cmd->hdr.return_code) | ||
| 5392 | cmd->hdr.return_code = cmd->data.setassparms.hdr.return_code; | ||
| 5393 | return cmd->hdr.return_code; | ||
| 5394 | } | ||
| 5395 | |||
| 5389 | int qeth_setassparms_cb(struct qeth_card *card, | 5396 | int qeth_setassparms_cb(struct qeth_card *card, |
| 5390 | struct qeth_reply *reply, unsigned long data) | 5397 | struct qeth_reply *reply, unsigned long data) |
| 5391 | { | 5398 | { |
| @@ -6242,7 +6249,7 @@ static int qeth_ipa_checksum_run_cmd_cb(struct qeth_card *card, | |||
| 6242 | (struct qeth_checksum_cmd *)reply->param; | 6249 | (struct qeth_checksum_cmd *)reply->param; |
| 6243 | 6250 | ||
| 6244 | QETH_CARD_TEXT(card, 4, "chkdoccb"); | 6251 | QETH_CARD_TEXT(card, 4, "chkdoccb"); |
| 6245 | if (cmd->hdr.return_code) | 6252 | if (qeth_setassparms_inspect_rc(cmd)) |
| 6246 | return 0; | 6253 | return 0; |
| 6247 | 6254 | ||
| 6248 | memset(chksum_cb, 0, sizeof(*chksum_cb)); | 6255 | memset(chksum_cb, 0, sizeof(*chksum_cb)); |
diff --git a/drivers/s390/net/qeth_l3.h b/drivers/s390/net/qeth_l3.h index 194ae9b577cc..e5833837b799 100644 --- a/drivers/s390/net/qeth_l3.h +++ b/drivers/s390/net/qeth_l3.h | |||
| @@ -82,7 +82,7 @@ void qeth_l3_del_vipa(struct qeth_card *, enum qeth_prot_versions, const u8 *); | |||
| 82 | int qeth_l3_add_rxip(struct qeth_card *, enum qeth_prot_versions, const u8 *); | 82 | int qeth_l3_add_rxip(struct qeth_card *, enum qeth_prot_versions, const u8 *); |
| 83 | void qeth_l3_del_rxip(struct qeth_card *card, enum qeth_prot_versions, | 83 | void qeth_l3_del_rxip(struct qeth_card *card, enum qeth_prot_versions, |
| 84 | const u8 *); | 84 | const u8 *); |
| 85 | int qeth_l3_is_addr_covered_by_ipato(struct qeth_card *, struct qeth_ipaddr *); | 85 | void qeth_l3_update_ipato(struct qeth_card *card); |
| 86 | struct qeth_ipaddr *qeth_l3_get_addr_buffer(enum qeth_prot_versions); | 86 | struct qeth_ipaddr *qeth_l3_get_addr_buffer(enum qeth_prot_versions); |
| 87 | int qeth_l3_add_ip(struct qeth_card *, struct qeth_ipaddr *); | 87 | int qeth_l3_add_ip(struct qeth_card *, struct qeth_ipaddr *); |
| 88 | int qeth_l3_delete_ip(struct qeth_card *, struct qeth_ipaddr *); | 88 | int qeth_l3_delete_ip(struct qeth_card *, struct qeth_ipaddr *); |
diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index 6a73894b0cb5..ef0961e18686 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c | |||
| @@ -164,8 +164,8 @@ static void qeth_l3_convert_addr_to_bits(u8 *addr, u8 *bits, int len) | |||
| 164 | } | 164 | } |
| 165 | } | 165 | } |
| 166 | 166 | ||
| 167 | int qeth_l3_is_addr_covered_by_ipato(struct qeth_card *card, | 167 | static bool qeth_l3_is_addr_covered_by_ipato(struct qeth_card *card, |
| 168 | struct qeth_ipaddr *addr) | 168 | struct qeth_ipaddr *addr) |
| 169 | { | 169 | { |
| 170 | struct qeth_ipato_entry *ipatoe; | 170 | struct qeth_ipato_entry *ipatoe; |
| 171 | u8 addr_bits[128] = {0, }; | 171 | u8 addr_bits[128] = {0, }; |
| @@ -174,6 +174,8 @@ int qeth_l3_is_addr_covered_by_ipato(struct qeth_card *card, | |||
| 174 | 174 | ||
| 175 | if (!card->ipato.enabled) | 175 | if (!card->ipato.enabled) |
| 176 | return 0; | 176 | return 0; |
| 177 | if (addr->type != QETH_IP_TYPE_NORMAL) | ||
| 178 | return 0; | ||
| 177 | 179 | ||
| 178 | qeth_l3_convert_addr_to_bits((u8 *) &addr->u, addr_bits, | 180 | qeth_l3_convert_addr_to_bits((u8 *) &addr->u, addr_bits, |
| 179 | (addr->proto == QETH_PROT_IPV4)? 4:16); | 181 | (addr->proto == QETH_PROT_IPV4)? 4:16); |
| @@ -290,8 +292,7 @@ int qeth_l3_add_ip(struct qeth_card *card, struct qeth_ipaddr *tmp_addr) | |||
| 290 | memcpy(addr, tmp_addr, sizeof(struct qeth_ipaddr)); | 292 | memcpy(addr, tmp_addr, sizeof(struct qeth_ipaddr)); |
| 291 | addr->ref_counter = 1; | 293 | addr->ref_counter = 1; |
| 292 | 294 | ||
| 293 | if (addr->type == QETH_IP_TYPE_NORMAL && | 295 | if (qeth_l3_is_addr_covered_by_ipato(card, addr)) { |
| 294 | qeth_l3_is_addr_covered_by_ipato(card, addr)) { | ||
| 295 | QETH_CARD_TEXT(card, 2, "tkovaddr"); | 296 | QETH_CARD_TEXT(card, 2, "tkovaddr"); |
| 296 | addr->set_flags |= QETH_IPA_SETIP_TAKEOVER_FLAG; | 297 | addr->set_flags |= QETH_IPA_SETIP_TAKEOVER_FLAG; |
| 297 | } | 298 | } |
| @@ -605,6 +606,27 @@ int qeth_l3_setrouting_v6(struct qeth_card *card) | |||
| 605 | /* | 606 | /* |
| 606 | * IP address takeover related functions | 607 | * IP address takeover related functions |
| 607 | */ | 608 | */ |
| 609 | |||
| 610 | /** | ||
| 611 | * qeth_l3_update_ipato() - Update 'takeover' property, for all NORMAL IPs. | ||
| 612 | * | ||
| 613 | * Caller must hold ip_lock. | ||
| 614 | */ | ||
| 615 | void qeth_l3_update_ipato(struct qeth_card *card) | ||
| 616 | { | ||
| 617 | struct qeth_ipaddr *addr; | ||
| 618 | unsigned int i; | ||
| 619 | |||
| 620 | hash_for_each(card->ip_htable, i, addr, hnode) { | ||
| 621 | if (addr->type != QETH_IP_TYPE_NORMAL) | ||
| 622 | continue; | ||
| 623 | if (qeth_l3_is_addr_covered_by_ipato(card, addr)) | ||
| 624 | addr->set_flags |= QETH_IPA_SETIP_TAKEOVER_FLAG; | ||
| 625 | else | ||
| 626 | addr->set_flags &= ~QETH_IPA_SETIP_TAKEOVER_FLAG; | ||
| 627 | } | ||
| 628 | } | ||
| 629 | |||
| 608 | static void qeth_l3_clear_ipato_list(struct qeth_card *card) | 630 | static void qeth_l3_clear_ipato_list(struct qeth_card *card) |
| 609 | { | 631 | { |
| 610 | struct qeth_ipato_entry *ipatoe, *tmp; | 632 | struct qeth_ipato_entry *ipatoe, *tmp; |
| @@ -616,6 +638,7 @@ static void qeth_l3_clear_ipato_list(struct qeth_card *card) | |||
| 616 | kfree(ipatoe); | 638 | kfree(ipatoe); |
| 617 | } | 639 | } |
| 618 | 640 | ||
| 641 | qeth_l3_update_ipato(card); | ||
| 619 | spin_unlock_bh(&card->ip_lock); | 642 | spin_unlock_bh(&card->ip_lock); |
| 620 | } | 643 | } |
| 621 | 644 | ||
| @@ -640,8 +663,10 @@ int qeth_l3_add_ipato_entry(struct qeth_card *card, | |||
| 640 | } | 663 | } |
| 641 | } | 664 | } |
| 642 | 665 | ||
| 643 | if (!rc) | 666 | if (!rc) { |
| 644 | list_add_tail(&new->entry, &card->ipato.entries); | 667 | list_add_tail(&new->entry, &card->ipato.entries); |
| 668 | qeth_l3_update_ipato(card); | ||
| 669 | } | ||
| 645 | 670 | ||
| 646 | spin_unlock_bh(&card->ip_lock); | 671 | spin_unlock_bh(&card->ip_lock); |
| 647 | 672 | ||
| @@ -664,6 +689,7 @@ void qeth_l3_del_ipato_entry(struct qeth_card *card, | |||
| 664 | (proto == QETH_PROT_IPV4)? 4:16) && | 689 | (proto == QETH_PROT_IPV4)? 4:16) && |
| 665 | (ipatoe->mask_bits == mask_bits)) { | 690 | (ipatoe->mask_bits == mask_bits)) { |
| 666 | list_del(&ipatoe->entry); | 691 | list_del(&ipatoe->entry); |
| 692 | qeth_l3_update_ipato(card); | ||
| 667 | kfree(ipatoe); | 693 | kfree(ipatoe); |
| 668 | } | 694 | } |
| 669 | } | 695 | } |
diff --git a/drivers/s390/net/qeth_l3_sys.c b/drivers/s390/net/qeth_l3_sys.c index bd12fdf678be..6ea2b528a64e 100644 --- a/drivers/s390/net/qeth_l3_sys.c +++ b/drivers/s390/net/qeth_l3_sys.c | |||
| @@ -370,8 +370,8 @@ static ssize_t qeth_l3_dev_ipato_enable_store(struct device *dev, | |||
| 370 | struct device_attribute *attr, const char *buf, size_t count) | 370 | struct device_attribute *attr, const char *buf, size_t count) |
| 371 | { | 371 | { |
| 372 | struct qeth_card *card = dev_get_drvdata(dev); | 372 | struct qeth_card *card = dev_get_drvdata(dev); |
| 373 | struct qeth_ipaddr *addr; | 373 | bool enable; |
| 374 | int i, rc = 0; | 374 | int rc = 0; |
| 375 | 375 | ||
| 376 | if (!card) | 376 | if (!card) |
| 377 | return -EINVAL; | 377 | return -EINVAL; |
| @@ -384,25 +384,18 @@ static ssize_t qeth_l3_dev_ipato_enable_store(struct device *dev, | |||
| 384 | } | 384 | } |
| 385 | 385 | ||
| 386 | if (sysfs_streq(buf, "toggle")) { | 386 | if (sysfs_streq(buf, "toggle")) { |
| 387 | card->ipato.enabled = (card->ipato.enabled)? 0 : 1; | 387 | enable = !card->ipato.enabled; |
| 388 | } else if (sysfs_streq(buf, "1")) { | 388 | } else if (kstrtobool(buf, &enable)) { |
| 389 | card->ipato.enabled = 1; | ||
| 390 | hash_for_each(card->ip_htable, i, addr, hnode) { | ||
| 391 | if ((addr->type == QETH_IP_TYPE_NORMAL) && | ||
| 392 | qeth_l3_is_addr_covered_by_ipato(card, addr)) | ||
| 393 | addr->set_flags |= | ||
| 394 | QETH_IPA_SETIP_TAKEOVER_FLAG; | ||
| 395 | } | ||
| 396 | } else if (sysfs_streq(buf, "0")) { | ||
| 397 | card->ipato.enabled = 0; | ||
| 398 | hash_for_each(card->ip_htable, i, addr, hnode) { | ||
| 399 | if (addr->set_flags & | ||
| 400 | QETH_IPA_SETIP_TAKEOVER_FLAG) | ||
| 401 | addr->set_flags &= | ||
| 402 | ~QETH_IPA_SETIP_TAKEOVER_FLAG; | ||
| 403 | } | ||
| 404 | } else | ||
| 405 | rc = -EINVAL; | 389 | rc = -EINVAL; |
| 390 | goto out; | ||
| 391 | } | ||
| 392 | |||
| 393 | if (card->ipato.enabled != enable) { | ||
| 394 | card->ipato.enabled = enable; | ||
| 395 | spin_lock_bh(&card->ip_lock); | ||
| 396 | qeth_l3_update_ipato(card); | ||
| 397 | spin_unlock_bh(&card->ip_lock); | ||
| 398 | } | ||
| 406 | out: | 399 | out: |
| 407 | mutex_unlock(&card->conf_mutex); | 400 | mutex_unlock(&card->conf_mutex); |
| 408 | return rc ? rc : count; | 401 | return rc ? rc : count; |
| @@ -428,20 +421,27 @@ static ssize_t qeth_l3_dev_ipato_invert4_store(struct device *dev, | |||
| 428 | const char *buf, size_t count) | 421 | const char *buf, size_t count) |
| 429 | { | 422 | { |
| 430 | struct qeth_card *card = dev_get_drvdata(dev); | 423 | struct qeth_card *card = dev_get_drvdata(dev); |
| 424 | bool invert; | ||
| 431 | int rc = 0; | 425 | int rc = 0; |
| 432 | 426 | ||
| 433 | if (!card) | 427 | if (!card) |
| 434 | return -EINVAL; | 428 | return -EINVAL; |
| 435 | 429 | ||
| 436 | mutex_lock(&card->conf_mutex); | 430 | mutex_lock(&card->conf_mutex); |
| 437 | if (sysfs_streq(buf, "toggle")) | 431 | if (sysfs_streq(buf, "toggle")) { |
| 438 | card->ipato.invert4 = (card->ipato.invert4)? 0 : 1; | 432 | invert = !card->ipato.invert4; |
| 439 | else if (sysfs_streq(buf, "1")) | 433 | } else if (kstrtobool(buf, &invert)) { |
| 440 | card->ipato.invert4 = 1; | ||
| 441 | else if (sysfs_streq(buf, "0")) | ||
| 442 | card->ipato.invert4 = 0; | ||
| 443 | else | ||
| 444 | rc = -EINVAL; | 434 | rc = -EINVAL; |
| 435 | goto out; | ||
| 436 | } | ||
| 437 | |||
| 438 | if (card->ipato.invert4 != invert) { | ||
| 439 | card->ipato.invert4 = invert; | ||
| 440 | spin_lock_bh(&card->ip_lock); | ||
| 441 | qeth_l3_update_ipato(card); | ||
| 442 | spin_unlock_bh(&card->ip_lock); | ||
| 443 | } | ||
| 444 | out: | ||
| 445 | mutex_unlock(&card->conf_mutex); | 445 | mutex_unlock(&card->conf_mutex); |
| 446 | return rc ? rc : count; | 446 | return rc ? rc : count; |
| 447 | } | 447 | } |
| @@ -607,20 +607,27 @@ static ssize_t qeth_l3_dev_ipato_invert6_store(struct device *dev, | |||
| 607 | struct device_attribute *attr, const char *buf, size_t count) | 607 | struct device_attribute *attr, const char *buf, size_t count) |
| 608 | { | 608 | { |
| 609 | struct qeth_card *card = dev_get_drvdata(dev); | 609 | struct qeth_card *card = dev_get_drvdata(dev); |
| 610 | bool invert; | ||
| 610 | int rc = 0; | 611 | int rc = 0; |
| 611 | 612 | ||
| 612 | if (!card) | 613 | if (!card) |
| 613 | return -EINVAL; | 614 | return -EINVAL; |
| 614 | 615 | ||
| 615 | mutex_lock(&card->conf_mutex); | 616 | mutex_lock(&card->conf_mutex); |
| 616 | if (sysfs_streq(buf, "toggle")) | 617 | if (sysfs_streq(buf, "toggle")) { |
| 617 | card->ipato.invert6 = (card->ipato.invert6)? 0 : 1; | 618 | invert = !card->ipato.invert6; |
| 618 | else if (sysfs_streq(buf, "1")) | 619 | } else if (kstrtobool(buf, &invert)) { |
| 619 | card->ipato.invert6 = 1; | ||
| 620 | else if (sysfs_streq(buf, "0")) | ||
| 621 | card->ipato.invert6 = 0; | ||
| 622 | else | ||
| 623 | rc = -EINVAL; | 620 | rc = -EINVAL; |
| 621 | goto out; | ||
| 622 | } | ||
| 623 | |||
| 624 | if (card->ipato.invert6 != invert) { | ||
| 625 | card->ipato.invert6 = invert; | ||
| 626 | spin_lock_bh(&card->ip_lock); | ||
| 627 | qeth_l3_update_ipato(card); | ||
| 628 | spin_unlock_bh(&card->ip_lock); | ||
| 629 | } | ||
| 630 | out: | ||
| 624 | mutex_unlock(&card->conf_mutex); | 631 | mutex_unlock(&card->conf_mutex); |
| 625 | return rc ? rc : count; | 632 | return rc ? rc : count; |
| 626 | } | 633 | } |
diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index 6e3d81969a77..d52265416da2 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/drivers/scsi/aacraid/aacraid.h | |||
| @@ -1725,6 +1725,7 @@ struct aac_dev | |||
| 1725 | #define FIB_CONTEXT_FLAG_NATIVE_HBA (0x00000010) | 1725 | #define FIB_CONTEXT_FLAG_NATIVE_HBA (0x00000010) |
| 1726 | #define FIB_CONTEXT_FLAG_NATIVE_HBA_TMF (0x00000020) | 1726 | #define FIB_CONTEXT_FLAG_NATIVE_HBA_TMF (0x00000020) |
| 1727 | #define FIB_CONTEXT_FLAG_SCSI_CMD (0x00000040) | 1727 | #define FIB_CONTEXT_FLAG_SCSI_CMD (0x00000040) |
| 1728 | #define FIB_CONTEXT_FLAG_EH_RESET (0x00000080) | ||
| 1728 | 1729 | ||
| 1729 | /* | 1730 | /* |
| 1730 | * Define the command values | 1731 | * Define the command values |
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index bec9f3193f60..80a8cb26cdea 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c | |||
| @@ -2482,8 +2482,8 @@ int aac_command_thread(void *data) | |||
| 2482 | /* Synchronize our watches */ | 2482 | /* Synchronize our watches */ |
| 2483 | if (((NSEC_PER_SEC - (NSEC_PER_SEC / HZ)) > now.tv_nsec) | 2483 | if (((NSEC_PER_SEC - (NSEC_PER_SEC / HZ)) > now.tv_nsec) |
| 2484 | && (now.tv_nsec > (NSEC_PER_SEC / HZ))) | 2484 | && (now.tv_nsec > (NSEC_PER_SEC / HZ))) |
| 2485 | difference = (((NSEC_PER_SEC - now.tv_nsec) * HZ) | 2485 | difference = HZ + HZ / 2 - |
| 2486 | + NSEC_PER_SEC / 2) / NSEC_PER_SEC; | 2486 | now.tv_nsec / (NSEC_PER_SEC / HZ); |
| 2487 | else { | 2487 | else { |
| 2488 | if (now.tv_nsec > NSEC_PER_SEC / 2) | 2488 | if (now.tv_nsec > NSEC_PER_SEC / 2) |
| 2489 | ++now.tv_sec; | 2489 | ++now.tv_sec; |
| @@ -2507,6 +2507,10 @@ int aac_command_thread(void *data) | |||
| 2507 | if (kthread_should_stop()) | 2507 | if (kthread_should_stop()) |
| 2508 | break; | 2508 | break; |
| 2509 | 2509 | ||
| 2510 | /* | ||
| 2511 | * we probably want usleep_range() here instead of the | ||
| 2512 | * jiffies computation | ||
| 2513 | */ | ||
| 2510 | schedule_timeout(difference); | 2514 | schedule_timeout(difference); |
| 2511 | 2515 | ||
| 2512 | if (kthread_should_stop()) | 2516 | if (kthread_should_stop()) |
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c index bdf127aaab41..d55332de08f9 100644 --- a/drivers/scsi/aacraid/linit.c +++ b/drivers/scsi/aacraid/linit.c | |||
| @@ -1037,7 +1037,7 @@ static int aac_eh_bus_reset(struct scsi_cmnd* cmd) | |||
| 1037 | info = &aac->hba_map[bus][cid]; | 1037 | info = &aac->hba_map[bus][cid]; |
| 1038 | if (bus >= AAC_MAX_BUSES || cid >= AAC_MAX_TARGETS || | 1038 | if (bus >= AAC_MAX_BUSES || cid >= AAC_MAX_TARGETS || |
| 1039 | info->devtype != AAC_DEVTYPE_NATIVE_RAW) { | 1039 | info->devtype != AAC_DEVTYPE_NATIVE_RAW) { |
| 1040 | fib->flags |= FIB_CONTEXT_FLAG_TIMED_OUT; | 1040 | fib->flags |= FIB_CONTEXT_FLAG_EH_RESET; |
| 1041 | cmd->SCp.phase = AAC_OWNER_ERROR_HANDLER; | 1041 | cmd->SCp.phase = AAC_OWNER_ERROR_HANDLER; |
| 1042 | } | 1042 | } |
| 1043 | } | 1043 | } |
diff --git a/drivers/scsi/bfa/bfad_bsg.c b/drivers/scsi/bfa/bfad_bsg.c index 72ca2a2e08e2..b2fa195adc7a 100644 --- a/drivers/scsi/bfa/bfad_bsg.c +++ b/drivers/scsi/bfa/bfad_bsg.c | |||
| @@ -3135,7 +3135,8 @@ bfad_im_bsg_vendor_request(struct bsg_job *job) | |||
| 3135 | struct fc_bsg_request *bsg_request = job->request; | 3135 | struct fc_bsg_request *bsg_request = job->request; |
| 3136 | struct fc_bsg_reply *bsg_reply = job->reply; | 3136 | struct fc_bsg_reply *bsg_reply = job->reply; |
| 3137 | uint32_t vendor_cmd = bsg_request->rqst_data.h_vendor.vendor_cmd[0]; | 3137 | uint32_t vendor_cmd = bsg_request->rqst_data.h_vendor.vendor_cmd[0]; |
| 3138 | struct bfad_im_port_s *im_port = shost_priv(fc_bsg_to_shost(job)); | 3138 | struct Scsi_Host *shost = fc_bsg_to_shost(job); |
| 3139 | struct bfad_im_port_s *im_port = bfad_get_im_port(shost); | ||
| 3139 | struct bfad_s *bfad = im_port->bfad; | 3140 | struct bfad_s *bfad = im_port->bfad; |
| 3140 | void *payload_kbuf; | 3141 | void *payload_kbuf; |
| 3141 | int rc = -EINVAL; | 3142 | int rc = -EINVAL; |
| @@ -3350,7 +3351,8 @@ int | |||
| 3350 | bfad_im_bsg_els_ct_request(struct bsg_job *job) | 3351 | bfad_im_bsg_els_ct_request(struct bsg_job *job) |
| 3351 | { | 3352 | { |
| 3352 | struct bfa_bsg_data *bsg_data; | 3353 | struct bfa_bsg_data *bsg_data; |
| 3353 | struct bfad_im_port_s *im_port = shost_priv(fc_bsg_to_shost(job)); | 3354 | struct Scsi_Host *shost = fc_bsg_to_shost(job); |
| 3355 | struct bfad_im_port_s *im_port = bfad_get_im_port(shost); | ||
| 3354 | struct bfad_s *bfad = im_port->bfad; | 3356 | struct bfad_s *bfad = im_port->bfad; |
| 3355 | bfa_bsg_fcpt_t *bsg_fcpt; | 3357 | bfa_bsg_fcpt_t *bsg_fcpt; |
| 3356 | struct bfad_fcxp *drv_fcxp; | 3358 | struct bfad_fcxp *drv_fcxp; |
diff --git a/drivers/scsi/bfa/bfad_im.c b/drivers/scsi/bfa/bfad_im.c index 24e657a4ec80..c05d6e91e4bd 100644 --- a/drivers/scsi/bfa/bfad_im.c +++ b/drivers/scsi/bfa/bfad_im.c | |||
| @@ -546,6 +546,7 @@ int | |||
| 546 | bfad_im_scsi_host_alloc(struct bfad_s *bfad, struct bfad_im_port_s *im_port, | 546 | bfad_im_scsi_host_alloc(struct bfad_s *bfad, struct bfad_im_port_s *im_port, |
| 547 | struct device *dev) | 547 | struct device *dev) |
| 548 | { | 548 | { |
| 549 | struct bfad_im_port_pointer *im_portp; | ||
| 549 | int error = 1; | 550 | int error = 1; |
| 550 | 551 | ||
| 551 | mutex_lock(&bfad_mutex); | 552 | mutex_lock(&bfad_mutex); |
| @@ -564,7 +565,8 @@ bfad_im_scsi_host_alloc(struct bfad_s *bfad, struct bfad_im_port_s *im_port, | |||
| 564 | goto out_free_idr; | 565 | goto out_free_idr; |
| 565 | } | 566 | } |
| 566 | 567 | ||
| 567 | im_port->shost->hostdata[0] = (unsigned long)im_port; | 568 | im_portp = shost_priv(im_port->shost); |
| 569 | im_portp->p = im_port; | ||
| 568 | im_port->shost->unique_id = im_port->idr_id; | 570 | im_port->shost->unique_id = im_port->idr_id; |
| 569 | im_port->shost->this_id = -1; | 571 | im_port->shost->this_id = -1; |
| 570 | im_port->shost->max_id = MAX_FCP_TARGET; | 572 | im_port->shost->max_id = MAX_FCP_TARGET; |
| @@ -748,7 +750,7 @@ bfad_scsi_host_alloc(struct bfad_im_port_s *im_port, struct bfad_s *bfad) | |||
| 748 | 750 | ||
| 749 | sht->sg_tablesize = bfad->cfg_data.io_max_sge; | 751 | sht->sg_tablesize = bfad->cfg_data.io_max_sge; |
| 750 | 752 | ||
| 751 | return scsi_host_alloc(sht, sizeof(unsigned long)); | 753 | return scsi_host_alloc(sht, sizeof(struct bfad_im_port_pointer)); |
| 752 | } | 754 | } |
| 753 | 755 | ||
| 754 | void | 756 | void |
diff --git a/drivers/scsi/bfa/bfad_im.h b/drivers/scsi/bfa/bfad_im.h index c81ec2a77ef5..06ce4ba2b7bc 100644 --- a/drivers/scsi/bfa/bfad_im.h +++ b/drivers/scsi/bfa/bfad_im.h | |||
| @@ -69,6 +69,16 @@ struct bfad_im_port_s { | |||
| 69 | struct fc_vport *fc_vport; | 69 | struct fc_vport *fc_vport; |
| 70 | }; | 70 | }; |
| 71 | 71 | ||
| 72 | struct bfad_im_port_pointer { | ||
| 73 | struct bfad_im_port_s *p; | ||
| 74 | }; | ||
| 75 | |||
| 76 | static inline struct bfad_im_port_s *bfad_get_im_port(struct Scsi_Host *host) | ||
| 77 | { | ||
| 78 | struct bfad_im_port_pointer *im_portp = shost_priv(host); | ||
| 79 | return im_portp->p; | ||
| 80 | } | ||
| 81 | |||
| 72 | enum bfad_itnim_state { | 82 | enum bfad_itnim_state { |
| 73 | ITNIM_STATE_NONE, | 83 | ITNIM_STATE_NONE, |
| 74 | ITNIM_STATE_ONLINE, | 84 | ITNIM_STATE_ONLINE, |
diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c index 5da46052e179..21be672679fb 100644 --- a/drivers/scsi/libfc/fc_lport.c +++ b/drivers/scsi/libfc/fc_lport.c | |||
| @@ -904,10 +904,14 @@ static void fc_lport_recv_els_req(struct fc_lport *lport, | |||
| 904 | case ELS_FLOGI: | 904 | case ELS_FLOGI: |
| 905 | if (!lport->point_to_multipoint) | 905 | if (!lport->point_to_multipoint) |
| 906 | fc_lport_recv_flogi_req(lport, fp); | 906 | fc_lport_recv_flogi_req(lport, fp); |
| 907 | else | ||
| 908 | fc_rport_recv_req(lport, fp); | ||
| 907 | break; | 909 | break; |
| 908 | case ELS_LOGO: | 910 | case ELS_LOGO: |
| 909 | if (fc_frame_sid(fp) == FC_FID_FLOGI) | 911 | if (fc_frame_sid(fp) == FC_FID_FLOGI) |
| 910 | fc_lport_recv_logo_req(lport, fp); | 912 | fc_lport_recv_logo_req(lport, fp); |
| 913 | else | ||
| 914 | fc_rport_recv_req(lport, fp); | ||
| 911 | break; | 915 | break; |
| 912 | case ELS_RSCN: | 916 | case ELS_RSCN: |
| 913 | lport->tt.disc_recv_req(lport, fp); | 917 | lport->tt.disc_recv_req(lport, fp); |
diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c index ca1566237ae7..3183d63de4da 100644 --- a/drivers/scsi/libsas/sas_expander.c +++ b/drivers/scsi/libsas/sas_expander.c | |||
| @@ -2145,7 +2145,7 @@ void sas_smp_handler(struct bsg_job *job, struct Scsi_Host *shost, | |||
| 2145 | struct sas_rphy *rphy) | 2145 | struct sas_rphy *rphy) |
| 2146 | { | 2146 | { |
| 2147 | struct domain_device *dev; | 2147 | struct domain_device *dev; |
| 2148 | unsigned int reslen = 0; | 2148 | unsigned int rcvlen = 0; |
| 2149 | int ret = -EINVAL; | 2149 | int ret = -EINVAL; |
| 2150 | 2150 | ||
| 2151 | /* no rphy means no smp target support (ie aic94xx host) */ | 2151 | /* no rphy means no smp target support (ie aic94xx host) */ |
| @@ -2179,12 +2179,12 @@ void sas_smp_handler(struct bsg_job *job, struct Scsi_Host *shost, | |||
| 2179 | 2179 | ||
| 2180 | ret = smp_execute_task_sg(dev, job->request_payload.sg_list, | 2180 | ret = smp_execute_task_sg(dev, job->request_payload.sg_list, |
| 2181 | job->reply_payload.sg_list); | 2181 | job->reply_payload.sg_list); |
| 2182 | if (ret > 0) { | 2182 | if (ret >= 0) { |
| 2183 | /* positive number is the untransferred residual */ | 2183 | /* bsg_job_done() requires the length received */ |
| 2184 | reslen = ret; | 2184 | rcvlen = job->reply_payload.payload_len - ret; |
| 2185 | ret = 0; | 2185 | ret = 0; |
| 2186 | } | 2186 | } |
| 2187 | 2187 | ||
| 2188 | out: | 2188 | out: |
| 2189 | bsg_job_done(job, ret, reslen); | 2189 | bsg_job_done(job, ret, rcvlen); |
| 2190 | } | 2190 | } |
diff --git a/drivers/scsi/lpfc/lpfc_mem.c b/drivers/scsi/lpfc/lpfc_mem.c index 56faeb049b4a..87c08ff37ddd 100644 --- a/drivers/scsi/lpfc/lpfc_mem.c +++ b/drivers/scsi/lpfc/lpfc_mem.c | |||
| @@ -753,12 +753,12 @@ lpfc_rq_buf_free(struct lpfc_hba *phba, struct lpfc_dmabuf *mp) | |||
| 753 | drqe.address_hi = putPaddrHigh(rqb_entry->dbuf.phys); | 753 | drqe.address_hi = putPaddrHigh(rqb_entry->dbuf.phys); |
| 754 | rc = lpfc_sli4_rq_put(rqb_entry->hrq, rqb_entry->drq, &hrqe, &drqe); | 754 | rc = lpfc_sli4_rq_put(rqb_entry->hrq, rqb_entry->drq, &hrqe, &drqe); |
| 755 | if (rc < 0) { | 755 | if (rc < 0) { |
| 756 | (rqbp->rqb_free_buffer)(phba, rqb_entry); | ||
| 757 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 756 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
| 758 | "6409 Cannot post to RQ %d: %x %x\n", | 757 | "6409 Cannot post to RQ %d: %x %x\n", |
| 759 | rqb_entry->hrq->queue_id, | 758 | rqb_entry->hrq->queue_id, |
| 760 | rqb_entry->hrq->host_index, | 759 | rqb_entry->hrq->host_index, |
| 761 | rqb_entry->hrq->hba_index); | 760 | rqb_entry->hrq->hba_index); |
| 761 | (rqbp->rqb_free_buffer)(phba, rqb_entry); | ||
| 762 | } else { | 762 | } else { |
| 763 | list_add_tail(&rqb_entry->hbuf.list, &rqbp->rqb_buffer_list); | 763 | list_add_tail(&rqb_entry->hbuf.list, &rqbp->rqb_buffer_list); |
| 764 | rqbp->buffer_count++; | 764 | rqbp->buffer_count++; |
diff --git a/drivers/scsi/osd/osd_initiator.c b/drivers/scsi/osd/osd_initiator.c index a4f28b7e4c65..e18877177f1b 100644 --- a/drivers/scsi/osd/osd_initiator.c +++ b/drivers/scsi/osd/osd_initiator.c | |||
| @@ -1576,7 +1576,9 @@ static struct request *_make_request(struct request_queue *q, bool has_write, | |||
| 1576 | return req; | 1576 | return req; |
| 1577 | 1577 | ||
| 1578 | for_each_bio(bio) { | 1578 | for_each_bio(bio) { |
| 1579 | ret = blk_rq_append_bio(req, bio); | 1579 | struct bio *bounce_bio = bio; |
| 1580 | |||
| 1581 | ret = blk_rq_append_bio(req, &bounce_bio); | ||
| 1580 | if (ret) | 1582 | if (ret) |
| 1581 | return ERR_PTR(ret); | 1583 | return ERR_PTR(ret); |
| 1582 | } | 1584 | } |
diff --git a/drivers/scsi/scsi_debugfs.c b/drivers/scsi/scsi_debugfs.c index 01f08c03f2c1..c3765d29fd3f 100644 --- a/drivers/scsi/scsi_debugfs.c +++ b/drivers/scsi/scsi_debugfs.c | |||
| @@ -8,9 +8,11 @@ void scsi_show_rq(struct seq_file *m, struct request *rq) | |||
| 8 | { | 8 | { |
| 9 | struct scsi_cmnd *cmd = container_of(scsi_req(rq), typeof(*cmd), req); | 9 | struct scsi_cmnd *cmd = container_of(scsi_req(rq), typeof(*cmd), req); |
| 10 | int msecs = jiffies_to_msecs(jiffies - cmd->jiffies_at_alloc); | 10 | int msecs = jiffies_to_msecs(jiffies - cmd->jiffies_at_alloc); |
| 11 | char buf[80]; | 11 | const u8 *const cdb = READ_ONCE(cmd->cmnd); |
| 12 | char buf[80] = "(?)"; | ||
| 12 | 13 | ||
| 13 | __scsi_format_command(buf, sizeof(buf), cmd->cmnd, cmd->cmd_len); | 14 | if (cdb) |
| 15 | __scsi_format_command(buf, sizeof(buf), cdb, cmd->cmd_len); | ||
| 14 | seq_printf(m, ", .cmd=%s, .retries=%d, allocated %d.%03d s ago", buf, | 16 | seq_printf(m, ", .cmd=%s, .retries=%d, allocated %d.%03d s ago", buf, |
| 15 | cmd->retries, msecs / 1000, msecs % 1000); | 17 | cmd->retries, msecs / 1000, msecs % 1000); |
| 16 | } | 18 | } |
diff --git a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c index 78d4aa8df675..dfb8da83fa50 100644 --- a/drivers/scsi/scsi_devinfo.c +++ b/drivers/scsi/scsi_devinfo.c | |||
| @@ -34,7 +34,6 @@ struct scsi_dev_info_list_table { | |||
| 34 | }; | 34 | }; |
| 35 | 35 | ||
| 36 | 36 | ||
| 37 | static const char spaces[] = " "; /* 16 of them */ | ||
| 38 | static blist_flags_t scsi_default_dev_flags; | 37 | static blist_flags_t scsi_default_dev_flags; |
| 39 | static LIST_HEAD(scsi_dev_info_list); | 38 | static LIST_HEAD(scsi_dev_info_list); |
| 40 | static char scsi_dev_flags[256]; | 39 | static char scsi_dev_flags[256]; |
| @@ -298,20 +297,13 @@ static void scsi_strcpy_devinfo(char *name, char *to, size_t to_length, | |||
| 298 | size_t from_length; | 297 | size_t from_length; |
| 299 | 298 | ||
| 300 | from_length = strlen(from); | 299 | from_length = strlen(from); |
| 301 | strncpy(to, from, min(to_length, from_length)); | 300 | /* This zero-pads the destination */ |
| 302 | if (from_length < to_length) { | 301 | strncpy(to, from, to_length); |
| 303 | if (compatible) { | 302 | if (from_length < to_length && !compatible) { |
| 304 | /* | 303 | /* |
| 305 | * NUL terminate the string if it is short. | 304 | * space pad the string if it is short. |
| 306 | */ | 305 | */ |
| 307 | to[from_length] = '\0'; | 306 | memset(&to[from_length], ' ', to_length - from_length); |
| 308 | } else { | ||
| 309 | /* | ||
| 310 | * space pad the string if it is short. | ||
| 311 | */ | ||
| 312 | strncpy(&to[from_length], spaces, | ||
| 313 | to_length - from_length); | ||
| 314 | } | ||
| 315 | } | 307 | } |
| 316 | if (from_length > to_length) | 308 | if (from_length > to_length) |
| 317 | printk(KERN_WARNING "%s: %s string '%s' is too long\n", | 309 | printk(KERN_WARNING "%s: %s string '%s' is too long\n", |
| @@ -382,10 +374,8 @@ int scsi_dev_info_list_add_keyed(int compatible, char *vendor, char *model, | |||
| 382 | model, compatible); | 374 | model, compatible); |
| 383 | 375 | ||
| 384 | if (strflags) | 376 | if (strflags) |
| 385 | devinfo->flags = simple_strtoul(strflags, NULL, 0); | 377 | flags = (__force blist_flags_t)simple_strtoul(strflags, NULL, 0); |
| 386 | else | 378 | devinfo->flags = flags; |
| 387 | devinfo->flags = flags; | ||
| 388 | |||
| 389 | devinfo->compatible = compatible; | 379 | devinfo->compatible = compatible; |
| 390 | 380 | ||
| 391 | if (compatible) | 381 | if (compatible) |
| @@ -458,7 +448,8 @@ static struct scsi_dev_info_list *scsi_dev_info_list_find(const char *vendor, | |||
| 458 | /* | 448 | /* |
| 459 | * vendor strings must be an exact match | 449 | * vendor strings must be an exact match |
| 460 | */ | 450 | */ |
| 461 | if (vmax != strlen(devinfo->vendor) || | 451 | if (vmax != strnlen(devinfo->vendor, |
| 452 | sizeof(devinfo->vendor)) || | ||
| 462 | memcmp(devinfo->vendor, vskip, vmax)) | 453 | memcmp(devinfo->vendor, vskip, vmax)) |
| 463 | continue; | 454 | continue; |
| 464 | 455 | ||
| @@ -466,7 +457,7 @@ static struct scsi_dev_info_list *scsi_dev_info_list_find(const char *vendor, | |||
| 466 | * @model specifies the full string, and | 457 | * @model specifies the full string, and |
| 467 | * must be larger or equal to devinfo->model | 458 | * must be larger or equal to devinfo->model |
| 468 | */ | 459 | */ |
| 469 | mlen = strlen(devinfo->model); | 460 | mlen = strnlen(devinfo->model, sizeof(devinfo->model)); |
| 470 | if (mmax < mlen || memcmp(devinfo->model, mskip, mlen)) | 461 | if (mmax < mlen || memcmp(devinfo->model, mskip, mlen)) |
| 471 | continue; | 462 | continue; |
| 472 | return devinfo; | 463 | return devinfo; |
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 00742c50cd44..d9ca1dfab154 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c | |||
| @@ -1967,6 +1967,8 @@ static bool scsi_mq_get_budget(struct blk_mq_hw_ctx *hctx) | |||
| 1967 | out_put_device: | 1967 | out_put_device: |
| 1968 | put_device(&sdev->sdev_gendev); | 1968 | put_device(&sdev->sdev_gendev); |
| 1969 | out: | 1969 | out: |
| 1970 | if (atomic_read(&sdev->device_busy) == 0 && !scsi_device_blocked(sdev)) | ||
| 1971 | blk_mq_delay_run_hw_queue(hctx, SCSI_QUEUE_DELAY); | ||
| 1970 | return false; | 1972 | return false; |
| 1971 | } | 1973 | } |
| 1972 | 1974 | ||
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index be5e919db0e8..0880d975eed3 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c | |||
| @@ -770,7 +770,7 @@ static int scsi_probe_lun(struct scsi_device *sdev, unsigned char *inq_result, | |||
| 770 | * SCSI_SCAN_LUN_PRESENT: a new scsi_device was allocated and initialized | 770 | * SCSI_SCAN_LUN_PRESENT: a new scsi_device was allocated and initialized |
| 771 | **/ | 771 | **/ |
| 772 | static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result, | 772 | static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result, |
| 773 | int *bflags, int async) | 773 | blist_flags_t *bflags, int async) |
| 774 | { | 774 | { |
| 775 | int ret; | 775 | int ret; |
| 776 | 776 | ||
| @@ -1049,14 +1049,15 @@ static unsigned char *scsi_inq_str(unsigned char *buf, unsigned char *inq, | |||
| 1049 | * - SCSI_SCAN_LUN_PRESENT: a new scsi_device was allocated and initialized | 1049 | * - SCSI_SCAN_LUN_PRESENT: a new scsi_device was allocated and initialized |
| 1050 | **/ | 1050 | **/ |
| 1051 | static int scsi_probe_and_add_lun(struct scsi_target *starget, | 1051 | static int scsi_probe_and_add_lun(struct scsi_target *starget, |
| 1052 | u64 lun, int *bflagsp, | 1052 | u64 lun, blist_flags_t *bflagsp, |
| 1053 | struct scsi_device **sdevp, | 1053 | struct scsi_device **sdevp, |
| 1054 | enum scsi_scan_mode rescan, | 1054 | enum scsi_scan_mode rescan, |
| 1055 | void *hostdata) | 1055 | void *hostdata) |
| 1056 | { | 1056 | { |
| 1057 | struct scsi_device *sdev; | 1057 | struct scsi_device *sdev; |
| 1058 | unsigned char *result; | 1058 | unsigned char *result; |
| 1059 | int bflags, res = SCSI_SCAN_NO_RESPONSE, result_len = 256; | 1059 | blist_flags_t bflags; |
| 1060 | int res = SCSI_SCAN_NO_RESPONSE, result_len = 256; | ||
| 1060 | struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); | 1061 | struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); |
| 1061 | 1062 | ||
| 1062 | /* | 1063 | /* |
| @@ -1201,7 +1202,7 @@ static int scsi_probe_and_add_lun(struct scsi_target *starget, | |||
| 1201 | * Modifies sdevscan->lun. | 1202 | * Modifies sdevscan->lun. |
| 1202 | **/ | 1203 | **/ |
| 1203 | static void scsi_sequential_lun_scan(struct scsi_target *starget, | 1204 | static void scsi_sequential_lun_scan(struct scsi_target *starget, |
| 1204 | int bflags, int scsi_level, | 1205 | blist_flags_t bflags, int scsi_level, |
| 1205 | enum scsi_scan_mode rescan) | 1206 | enum scsi_scan_mode rescan) |
| 1206 | { | 1207 | { |
| 1207 | uint max_dev_lun; | 1208 | uint max_dev_lun; |
| @@ -1292,7 +1293,7 @@ static void scsi_sequential_lun_scan(struct scsi_target *starget, | |||
| 1292 | * 0: scan completed (or no memory, so further scanning is futile) | 1293 | * 0: scan completed (or no memory, so further scanning is futile) |
| 1293 | * 1: could not scan with REPORT LUN | 1294 | * 1: could not scan with REPORT LUN |
| 1294 | **/ | 1295 | **/ |
| 1295 | static int scsi_report_lun_scan(struct scsi_target *starget, int bflags, | 1296 | static int scsi_report_lun_scan(struct scsi_target *starget, blist_flags_t bflags, |
| 1296 | enum scsi_scan_mode rescan) | 1297 | enum scsi_scan_mode rescan) |
| 1297 | { | 1298 | { |
| 1298 | unsigned char scsi_cmd[MAX_COMMAND_SIZE]; | 1299 | unsigned char scsi_cmd[MAX_COMMAND_SIZE]; |
| @@ -1538,7 +1539,7 @@ static void __scsi_scan_target(struct device *parent, unsigned int channel, | |||
| 1538 | unsigned int id, u64 lun, enum scsi_scan_mode rescan) | 1539 | unsigned int id, u64 lun, enum scsi_scan_mode rescan) |
| 1539 | { | 1540 | { |
| 1540 | struct Scsi_Host *shost = dev_to_shost(parent); | 1541 | struct Scsi_Host *shost = dev_to_shost(parent); |
| 1541 | int bflags = 0; | 1542 | blist_flags_t bflags = 0; |
| 1542 | int res; | 1543 | int res; |
| 1543 | struct scsi_target *starget; | 1544 | struct scsi_target *starget; |
| 1544 | 1545 | ||
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index 50e7d7e4a861..26ce17178401 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c | |||
| @@ -967,7 +967,8 @@ sdev_show_wwid(struct device *dev, struct device_attribute *attr, | |||
| 967 | } | 967 | } |
| 968 | static DEVICE_ATTR(wwid, S_IRUGO, sdev_show_wwid, NULL); | 968 | static DEVICE_ATTR(wwid, S_IRUGO, sdev_show_wwid, NULL); |
| 969 | 969 | ||
| 970 | #define BLIST_FLAG_NAME(name) [ilog2(BLIST_##name)] = #name | 970 | #define BLIST_FLAG_NAME(name) \ |
| 971 | [ilog2((__force unsigned int)BLIST_##name)] = #name | ||
| 971 | static const char *const sdev_bflags_name[] = { | 972 | static const char *const sdev_bflags_name[] = { |
| 972 | #include "scsi_devinfo_tbl.c" | 973 | #include "scsi_devinfo_tbl.c" |
| 973 | }; | 974 | }; |
| @@ -984,7 +985,7 @@ sdev_show_blacklist(struct device *dev, struct device_attribute *attr, | |||
| 984 | for (i = 0; i < sizeof(sdev->sdev_bflags) * BITS_PER_BYTE; i++) { | 985 | for (i = 0; i < sizeof(sdev->sdev_bflags) * BITS_PER_BYTE; i++) { |
| 985 | const char *name = NULL; | 986 | const char *name = NULL; |
| 986 | 987 | ||
| 987 | if (!(sdev->sdev_bflags & BIT(i))) | 988 | if (!(sdev->sdev_bflags & (__force blist_flags_t)BIT(i))) |
| 988 | continue; | 989 | continue; |
| 989 | if (i < ARRAY_SIZE(sdev_bflags_name) && sdev_bflags_name[i]) | 990 | if (i < ARRAY_SIZE(sdev_bflags_name) && sdev_bflags_name[i]) |
| 990 | name = sdev_bflags_name[i]; | 991 | name = sdev_bflags_name[i]; |
| @@ -1414,7 +1415,10 @@ static void __scsi_remove_target(struct scsi_target *starget) | |||
| 1414 | * check. | 1415 | * check. |
| 1415 | */ | 1416 | */ |
| 1416 | if (sdev->channel != starget->channel || | 1417 | if (sdev->channel != starget->channel || |
| 1417 | sdev->id != starget->id || | 1418 | sdev->id != starget->id) |
| 1419 | continue; | ||
| 1420 | if (sdev->sdev_state == SDEV_DEL || | ||
| 1421 | sdev->sdev_state == SDEV_CANCEL || | ||
| 1418 | !get_device(&sdev->sdev_gendev)) | 1422 | !get_device(&sdev->sdev_gendev)) |
| 1419 | continue; | 1423 | continue; |
| 1420 | spin_unlock_irqrestore(shost->host_lock, flags); | 1424 | spin_unlock_irqrestore(shost->host_lock, flags); |
diff --git a/drivers/scsi/scsi_transport_spi.c b/drivers/scsi/scsi_transport_spi.c index d0219e36080c..10ebb213ddb3 100644 --- a/drivers/scsi/scsi_transport_spi.c +++ b/drivers/scsi/scsi_transport_spi.c | |||
| @@ -50,14 +50,14 @@ | |||
| 50 | 50 | ||
| 51 | /* Our blacklist flags */ | 51 | /* Our blacklist flags */ |
| 52 | enum { | 52 | enum { |
| 53 | SPI_BLIST_NOIUS = 0x1, | 53 | SPI_BLIST_NOIUS = (__force blist_flags_t)0x1, |
| 54 | }; | 54 | }; |
| 55 | 55 | ||
| 56 | /* blacklist table, modelled on scsi_devinfo.c */ | 56 | /* blacklist table, modelled on scsi_devinfo.c */ |
| 57 | static struct { | 57 | static struct { |
| 58 | char *vendor; | 58 | char *vendor; |
| 59 | char *model; | 59 | char *model; |
| 60 | unsigned flags; | 60 | blist_flags_t flags; |
| 61 | } spi_static_device_list[] __initdata = { | 61 | } spi_static_device_list[] __initdata = { |
| 62 | {"HP", "Ultrium 3-SCSI", SPI_BLIST_NOIUS }, | 62 | {"HP", "Ultrium 3-SCSI", SPI_BLIST_NOIUS }, |
| 63 | {"IBM", "ULTRIUM-TD3", SPI_BLIST_NOIUS }, | 63 | {"IBM", "ULTRIUM-TD3", SPI_BLIST_NOIUS }, |
| @@ -221,9 +221,11 @@ static int spi_device_configure(struct transport_container *tc, | |||
| 221 | { | 221 | { |
| 222 | struct scsi_device *sdev = to_scsi_device(dev); | 222 | struct scsi_device *sdev = to_scsi_device(dev); |
| 223 | struct scsi_target *starget = sdev->sdev_target; | 223 | struct scsi_target *starget = sdev->sdev_target; |
| 224 | unsigned bflags = scsi_get_device_flags_keyed(sdev, &sdev->inquiry[8], | 224 | blist_flags_t bflags; |
| 225 | &sdev->inquiry[16], | 225 | |
| 226 | SCSI_DEVINFO_SPI); | 226 | bflags = scsi_get_device_flags_keyed(sdev, &sdev->inquiry[8], |
| 227 | &sdev->inquiry[16], | ||
| 228 | SCSI_DEVINFO_SPI); | ||
| 227 | 229 | ||
| 228 | /* Populate the target capability fields with the values | 230 | /* Populate the target capability fields with the values |
| 229 | * gleaned from the device inquiry */ | 231 | * gleaned from the device inquiry */ |
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 24fe68522716..a028ab3322a9 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c | |||
| @@ -1312,6 +1312,7 @@ static int sd_init_command(struct scsi_cmnd *cmd) | |||
| 1312 | static void sd_uninit_command(struct scsi_cmnd *SCpnt) | 1312 | static void sd_uninit_command(struct scsi_cmnd *SCpnt) |
| 1313 | { | 1313 | { |
| 1314 | struct request *rq = SCpnt->request; | 1314 | struct request *rq = SCpnt->request; |
| 1315 | u8 *cmnd; | ||
| 1315 | 1316 | ||
| 1316 | if (SCpnt->flags & SCMD_ZONE_WRITE_LOCK) | 1317 | if (SCpnt->flags & SCMD_ZONE_WRITE_LOCK) |
| 1317 | sd_zbc_write_unlock_zone(SCpnt); | 1318 | sd_zbc_write_unlock_zone(SCpnt); |
| @@ -1320,9 +1321,10 @@ static void sd_uninit_command(struct scsi_cmnd *SCpnt) | |||
| 1320 | __free_page(rq->special_vec.bv_page); | 1321 | __free_page(rq->special_vec.bv_page); |
| 1321 | 1322 | ||
| 1322 | if (SCpnt->cmnd != scsi_req(rq)->cmd) { | 1323 | if (SCpnt->cmnd != scsi_req(rq)->cmd) { |
| 1323 | mempool_free(SCpnt->cmnd, sd_cdb_pool); | 1324 | cmnd = SCpnt->cmnd; |
| 1324 | SCpnt->cmnd = NULL; | 1325 | SCpnt->cmnd = NULL; |
| 1325 | SCpnt->cmd_len = 0; | 1326 | SCpnt->cmd_len = 0; |
| 1327 | mempool_free(cmnd, sd_cdb_pool); | ||
| 1326 | } | 1328 | } |
| 1327 | } | 1329 | } |
| 1328 | 1330 | ||
diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c index 1b06cf0375dc..3b3d1d050cac 100644 --- a/drivers/scsi/storvsc_drv.c +++ b/drivers/scsi/storvsc_drv.c | |||
| @@ -953,10 +953,11 @@ static void storvsc_handle_error(struct vmscsi_request *vm_srb, | |||
| 953 | case TEST_UNIT_READY: | 953 | case TEST_UNIT_READY: |
| 954 | break; | 954 | break; |
| 955 | default: | 955 | default: |
| 956 | set_host_byte(scmnd, DID_TARGET_FAILURE); | 956 | set_host_byte(scmnd, DID_ERROR); |
| 957 | } | 957 | } |
| 958 | break; | 958 | break; |
| 959 | case SRB_STATUS_INVALID_LUN: | 959 | case SRB_STATUS_INVALID_LUN: |
| 960 | set_host_byte(scmnd, DID_NO_CONNECT); | ||
| 960 | do_work = true; | 961 | do_work = true; |
| 961 | process_err_fn = storvsc_remove_lun; | 962 | process_err_fn = storvsc_remove_lun; |
| 962 | break; | 963 | break; |
diff --git a/drivers/spi/spi-armada-3700.c b/drivers/spi/spi-armada-3700.c index 77fe55ce790c..d65345312527 100644 --- a/drivers/spi/spi-armada-3700.c +++ b/drivers/spi/spi-armada-3700.c | |||
| @@ -79,6 +79,7 @@ | |||
| 79 | #define A3700_SPI_BYTE_LEN BIT(5) | 79 | #define A3700_SPI_BYTE_LEN BIT(5) |
| 80 | #define A3700_SPI_CLK_PRESCALE BIT(0) | 80 | #define A3700_SPI_CLK_PRESCALE BIT(0) |
| 81 | #define A3700_SPI_CLK_PRESCALE_MASK (0x1f) | 81 | #define A3700_SPI_CLK_PRESCALE_MASK (0x1f) |
| 82 | #define A3700_SPI_CLK_EVEN_OFFS (0x10) | ||
| 82 | 83 | ||
| 83 | #define A3700_SPI_WFIFO_THRS_BIT 28 | 84 | #define A3700_SPI_WFIFO_THRS_BIT 28 |
| 84 | #define A3700_SPI_RFIFO_THRS_BIT 24 | 85 | #define A3700_SPI_RFIFO_THRS_BIT 24 |
| @@ -220,6 +221,13 @@ static void a3700_spi_clock_set(struct a3700_spi *a3700_spi, | |||
| 220 | 221 | ||
| 221 | prescale = DIV_ROUND_UP(clk_get_rate(a3700_spi->clk), speed_hz); | 222 | prescale = DIV_ROUND_UP(clk_get_rate(a3700_spi->clk), speed_hz); |
| 222 | 223 | ||
| 224 | /* For prescaler values over 15, we can only set it by steps of 2. | ||
| 225 | * Starting from A3700_SPI_CLK_EVEN_OFFS, we set values from 0 up to | ||
| 226 | * 30. We only use this range from 16 to 30. | ||
| 227 | */ | ||
| 228 | if (prescale > 15) | ||
| 229 | prescale = A3700_SPI_CLK_EVEN_OFFS + DIV_ROUND_UP(prescale, 2); | ||
| 230 | |||
| 223 | val = spireg_read(a3700_spi, A3700_SPI_IF_CFG_REG); | 231 | val = spireg_read(a3700_spi, A3700_SPI_IF_CFG_REG); |
| 224 | val = val & ~A3700_SPI_CLK_PRESCALE_MASK; | 232 | val = val & ~A3700_SPI_CLK_PRESCALE_MASK; |
| 225 | 233 | ||
diff --git a/drivers/spi/spi-atmel.c b/drivers/spi/spi-atmel.c index f95da364c283..669470971023 100644 --- a/drivers/spi/spi-atmel.c +++ b/drivers/spi/spi-atmel.c | |||
| @@ -1661,12 +1661,12 @@ static int atmel_spi_remove(struct platform_device *pdev) | |||
| 1661 | pm_runtime_get_sync(&pdev->dev); | 1661 | pm_runtime_get_sync(&pdev->dev); |
| 1662 | 1662 | ||
| 1663 | /* reset the hardware and block queue progress */ | 1663 | /* reset the hardware and block queue progress */ |
| 1664 | spin_lock_irq(&as->lock); | ||
| 1665 | if (as->use_dma) { | 1664 | if (as->use_dma) { |
| 1666 | atmel_spi_stop_dma(master); | 1665 | atmel_spi_stop_dma(master); |
| 1667 | atmel_spi_release_dma(master); | 1666 | atmel_spi_release_dma(master); |
| 1668 | } | 1667 | } |
| 1669 | 1668 | ||
| 1669 | spin_lock_irq(&as->lock); | ||
| 1670 | spi_writel(as, CR, SPI_BIT(SWRST)); | 1670 | spi_writel(as, CR, SPI_BIT(SWRST)); |
| 1671 | spi_writel(as, CR, SPI_BIT(SWRST)); /* AT91SAM9263 Rev B workaround */ | 1671 | spi_writel(as, CR, SPI_BIT(SWRST)); /* AT91SAM9263 Rev B workaround */ |
| 1672 | spi_readl(as, SR); | 1672 | spi_readl(as, SR); |
diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c index 2ce875764ca6..0835a8d88fb8 100644 --- a/drivers/spi/spi-rspi.c +++ b/drivers/spi/spi-rspi.c | |||
| @@ -377,8 +377,8 @@ static int qspi_set_config_register(struct rspi_data *rspi, int access_size) | |||
| 377 | /* Sets SPCMD */ | 377 | /* Sets SPCMD */ |
| 378 | rspi_write16(rspi, rspi->spcmd, RSPI_SPCMD0); | 378 | rspi_write16(rspi, rspi->spcmd, RSPI_SPCMD0); |
| 379 | 379 | ||
| 380 | /* Enables SPI function in master mode */ | 380 | /* Sets RSPI mode */ |
| 381 | rspi_write8(rspi, SPCR_SPE | SPCR_MSTR, RSPI_SPCR); | 381 | rspi_write8(rspi, SPCR_MSTR, RSPI_SPCR); |
| 382 | 382 | ||
| 383 | return 0; | 383 | return 0; |
| 384 | } | 384 | } |
diff --git a/drivers/spi/spi-sun4i.c b/drivers/spi/spi-sun4i.c index c5cd635c28f3..41410031f8e9 100644 --- a/drivers/spi/spi-sun4i.c +++ b/drivers/spi/spi-sun4i.c | |||
| @@ -525,7 +525,7 @@ err_free_master: | |||
| 525 | 525 | ||
| 526 | static int sun4i_spi_remove(struct platform_device *pdev) | 526 | static int sun4i_spi_remove(struct platform_device *pdev) |
| 527 | { | 527 | { |
| 528 | pm_runtime_disable(&pdev->dev); | 528 | pm_runtime_force_suspend(&pdev->dev); |
| 529 | 529 | ||
| 530 | return 0; | 530 | return 0; |
| 531 | } | 531 | } |
diff --git a/drivers/spi/spi-xilinx.c b/drivers/spi/spi-xilinx.c index bc7100b93dfc..e0b9fe1d0e37 100644 --- a/drivers/spi/spi-xilinx.c +++ b/drivers/spi/spi-xilinx.c | |||
| @@ -271,6 +271,7 @@ static int xilinx_spi_txrx_bufs(struct spi_device *spi, struct spi_transfer *t) | |||
| 271 | while (remaining_words) { | 271 | while (remaining_words) { |
| 272 | int n_words, tx_words, rx_words; | 272 | int n_words, tx_words, rx_words; |
| 273 | u32 sr; | 273 | u32 sr; |
| 274 | int stalled; | ||
| 274 | 275 | ||
| 275 | n_words = min(remaining_words, xspi->buffer_size); | 276 | n_words = min(remaining_words, xspi->buffer_size); |
| 276 | 277 | ||
| @@ -299,7 +300,17 @@ static int xilinx_spi_txrx_bufs(struct spi_device *spi, struct spi_transfer *t) | |||
| 299 | 300 | ||
| 300 | /* Read out all the data from the Rx FIFO */ | 301 | /* Read out all the data from the Rx FIFO */ |
| 301 | rx_words = n_words; | 302 | rx_words = n_words; |
| 303 | stalled = 10; | ||
| 302 | while (rx_words) { | 304 | while (rx_words) { |
| 305 | if (rx_words == n_words && !(stalled--) && | ||
| 306 | !(sr & XSPI_SR_TX_EMPTY_MASK) && | ||
| 307 | (sr & XSPI_SR_RX_EMPTY_MASK)) { | ||
| 308 | dev_err(&spi->dev, | ||
| 309 | "Detected stall. Check C_SPI_MODE and C_SPI_MEMORY\n"); | ||
| 310 | xspi_init_hw(xspi); | ||
| 311 | return -EIO; | ||
| 312 | } | ||
| 313 | |||
| 303 | if ((sr & XSPI_SR_TX_EMPTY_MASK) && (rx_words > 1)) { | 314 | if ((sr & XSPI_SR_TX_EMPTY_MASK) && (rx_words > 1)) { |
| 304 | xilinx_spi_rx(xspi); | 315 | xilinx_spi_rx(xspi); |
| 305 | rx_words--; | 316 | rx_words--; |
diff --git a/drivers/staging/android/ion/Kconfig b/drivers/staging/android/ion/Kconfig index a517b2d29f1b..8f6494158d3d 100644 --- a/drivers/staging/android/ion/Kconfig +++ b/drivers/staging/android/ion/Kconfig | |||
| @@ -37,7 +37,7 @@ config ION_CHUNK_HEAP | |||
| 37 | 37 | ||
| 38 | config ION_CMA_HEAP | 38 | config ION_CMA_HEAP |
| 39 | bool "Ion CMA heap support" | 39 | bool "Ion CMA heap support" |
| 40 | depends on ION && CMA | 40 | depends on ION && DMA_CMA |
| 41 | help | 41 | help |
| 42 | Choose this option to enable CMA heaps with Ion. This heap is backed | 42 | Choose this option to enable CMA heaps with Ion. This heap is backed |
| 43 | by the Contiguous Memory Allocator (CMA). If your system has these | 43 | by the Contiguous Memory Allocator (CMA). If your system has these |
diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c index a7d9b0e98572..f480885e346b 100644 --- a/drivers/staging/android/ion/ion.c +++ b/drivers/staging/android/ion/ion.c | |||
| @@ -346,7 +346,7 @@ static int ion_dma_buf_begin_cpu_access(struct dma_buf *dmabuf, | |||
| 346 | mutex_lock(&buffer->lock); | 346 | mutex_lock(&buffer->lock); |
| 347 | list_for_each_entry(a, &buffer->attachments, list) { | 347 | list_for_each_entry(a, &buffer->attachments, list) { |
| 348 | dma_sync_sg_for_cpu(a->dev, a->table->sgl, a->table->nents, | 348 | dma_sync_sg_for_cpu(a->dev, a->table->sgl, a->table->nents, |
| 349 | DMA_BIDIRECTIONAL); | 349 | direction); |
| 350 | } | 350 | } |
| 351 | mutex_unlock(&buffer->lock); | 351 | mutex_unlock(&buffer->lock); |
| 352 | 352 | ||
| @@ -368,7 +368,7 @@ static int ion_dma_buf_end_cpu_access(struct dma_buf *dmabuf, | |||
| 368 | mutex_lock(&buffer->lock); | 368 | mutex_lock(&buffer->lock); |
| 369 | list_for_each_entry(a, &buffer->attachments, list) { | 369 | list_for_each_entry(a, &buffer->attachments, list) { |
| 370 | dma_sync_sg_for_device(a->dev, a->table->sgl, a->table->nents, | 370 | dma_sync_sg_for_device(a->dev, a->table->sgl, a->table->nents, |
| 371 | DMA_BIDIRECTIONAL); | 371 | direction); |
| 372 | } | 372 | } |
| 373 | mutex_unlock(&buffer->lock); | 373 | mutex_unlock(&buffer->lock); |
| 374 | 374 | ||
diff --git a/drivers/staging/android/ion/ion_cma_heap.c b/drivers/staging/android/ion/ion_cma_heap.c index dd5545d9990a..86196ffd2faf 100644 --- a/drivers/staging/android/ion/ion_cma_heap.c +++ b/drivers/staging/android/ion/ion_cma_heap.c | |||
| @@ -39,9 +39,15 @@ static int ion_cma_allocate(struct ion_heap *heap, struct ion_buffer *buffer, | |||
| 39 | struct ion_cma_heap *cma_heap = to_cma_heap(heap); | 39 | struct ion_cma_heap *cma_heap = to_cma_heap(heap); |
| 40 | struct sg_table *table; | 40 | struct sg_table *table; |
| 41 | struct page *pages; | 41 | struct page *pages; |
| 42 | unsigned long size = PAGE_ALIGN(len); | ||
| 43 | unsigned long nr_pages = size >> PAGE_SHIFT; | ||
| 44 | unsigned long align = get_order(size); | ||
| 42 | int ret; | 45 | int ret; |
| 43 | 46 | ||
| 44 | pages = cma_alloc(cma_heap->cma, len, 0, GFP_KERNEL); | 47 | if (align > CONFIG_CMA_ALIGNMENT) |
| 48 | align = CONFIG_CMA_ALIGNMENT; | ||
| 49 | |||
| 50 | pages = cma_alloc(cma_heap->cma, nr_pages, align, GFP_KERNEL); | ||
| 45 | if (!pages) | 51 | if (!pages) |
| 46 | return -ENOMEM; | 52 | return -ENOMEM; |
| 47 | 53 | ||
| @@ -53,7 +59,7 @@ static int ion_cma_allocate(struct ion_heap *heap, struct ion_buffer *buffer, | |||
| 53 | if (ret) | 59 | if (ret) |
| 54 | goto free_mem; | 60 | goto free_mem; |
| 55 | 61 | ||
| 56 | sg_set_page(table->sgl, pages, len, 0); | 62 | sg_set_page(table->sgl, pages, size, 0); |
| 57 | 63 | ||
| 58 | buffer->priv_virt = pages; | 64 | buffer->priv_virt = pages; |
| 59 | buffer->sg_table = table; | 65 | buffer->sg_table = table; |
| @@ -62,7 +68,7 @@ static int ion_cma_allocate(struct ion_heap *heap, struct ion_buffer *buffer, | |||
| 62 | free_mem: | 68 | free_mem: |
| 63 | kfree(table); | 69 | kfree(table); |
| 64 | err: | 70 | err: |
| 65 | cma_release(cma_heap->cma, pages, buffer->size); | 71 | cma_release(cma_heap->cma, pages, nr_pages); |
| 66 | return -ENOMEM; | 72 | return -ENOMEM; |
| 67 | } | 73 | } |
| 68 | 74 | ||
| @@ -70,9 +76,10 @@ static void ion_cma_free(struct ion_buffer *buffer) | |||
| 70 | { | 76 | { |
| 71 | struct ion_cma_heap *cma_heap = to_cma_heap(buffer->heap); | 77 | struct ion_cma_heap *cma_heap = to_cma_heap(buffer->heap); |
| 72 | struct page *pages = buffer->priv_virt; | 78 | struct page *pages = buffer->priv_virt; |
| 79 | unsigned long nr_pages = PAGE_ALIGN(buffer->size) >> PAGE_SHIFT; | ||
| 73 | 80 | ||
| 74 | /* release memory */ | 81 | /* release memory */ |
| 75 | cma_release(cma_heap->cma, pages, buffer->size); | 82 | cma_release(cma_heap->cma, pages, nr_pages); |
| 76 | /* release sg table */ | 83 | /* release sg table */ |
| 77 | sg_free_table(buffer->sg_table); | 84 | sg_free_table(buffer->sg_table); |
| 78 | kfree(buffer->sg_table); | 85 | kfree(buffer->sg_table); |
diff --git a/drivers/staging/ccree/ssi_hash.c b/drivers/staging/ccree/ssi_hash.c index 1799d3f26a9e..2035835b62dc 100644 --- a/drivers/staging/ccree/ssi_hash.c +++ b/drivers/staging/ccree/ssi_hash.c | |||
| @@ -1769,7 +1769,7 @@ static int ssi_ahash_import(struct ahash_request *req, const void *in) | |||
| 1769 | struct device *dev = drvdata_to_dev(ctx->drvdata); | 1769 | struct device *dev = drvdata_to_dev(ctx->drvdata); |
| 1770 | struct ahash_req_ctx *state = ahash_request_ctx(req); | 1770 | struct ahash_req_ctx *state = ahash_request_ctx(req); |
| 1771 | u32 tmp; | 1771 | u32 tmp; |
| 1772 | int rc; | 1772 | int rc = 0; |
| 1773 | 1773 | ||
| 1774 | memcpy(&tmp, in, sizeof(u32)); | 1774 | memcpy(&tmp, in, sizeof(u32)); |
| 1775 | if (tmp != CC_EXPORT_MAGIC) { | 1775 | if (tmp != CC_EXPORT_MAGIC) { |
diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c index 986c2a40d978..8267119ccc8e 100644 --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c | |||
| @@ -487,21 +487,18 @@ ksocknal_add_peer(struct lnet_ni *ni, struct lnet_process_id id, __u32 ipaddr, | |||
| 487 | ksocknal_nid2peerlist(id.nid)); | 487 | ksocknal_nid2peerlist(id.nid)); |
| 488 | } | 488 | } |
| 489 | 489 | ||
| 490 | route2 = NULL; | ||
| 491 | list_for_each_entry(route2, &peer->ksnp_routes, ksnr_list) { | 490 | list_for_each_entry(route2, &peer->ksnp_routes, ksnr_list) { |
| 492 | if (route2->ksnr_ipaddr == ipaddr) | 491 | if (route2->ksnr_ipaddr == ipaddr) { |
| 493 | break; | 492 | /* Route already exists, use the old one */ |
| 494 | 493 | ksocknal_route_decref(route); | |
| 495 | route2 = NULL; | 494 | route2->ksnr_share_count++; |
| 496 | } | 495 | goto out; |
| 497 | if (!route2) { | 496 | } |
| 498 | ksocknal_add_route_locked(peer, route); | ||
| 499 | route->ksnr_share_count++; | ||
| 500 | } else { | ||
| 501 | ksocknal_route_decref(route); | ||
| 502 | route2->ksnr_share_count++; | ||
| 503 | } | 497 | } |
| 504 | 498 | /* Route doesn't already exist, add the new one */ | |
| 499 | ksocknal_add_route_locked(peer, route); | ||
| 500 | route->ksnr_share_count++; | ||
| 501 | out: | ||
| 505 | write_unlock_bh(&ksocknal_data.ksnd_global_lock); | 502 | write_unlock_bh(&ksocknal_data.ksnd_global_lock); |
| 506 | 503 | ||
| 507 | return 0; | 504 | return 0; |
diff --git a/drivers/staging/pi433/rf69.c b/drivers/staging/pi433/rf69.c index e69a2153c999..12c9df9cddde 100644 --- a/drivers/staging/pi433/rf69.c +++ b/drivers/staging/pi433/rf69.c | |||
| @@ -102,7 +102,7 @@ enum modulation rf69_get_modulation(struct spi_device *spi) | |||
| 102 | 102 | ||
| 103 | currentValue = READ_REG(REG_DATAMODUL); | 103 | currentValue = READ_REG(REG_DATAMODUL); |
| 104 | 104 | ||
| 105 | switch (currentValue & MASK_DATAMODUL_MODULATION_TYPE >> 3) { // TODO improvement: change 3 to define | 105 | switch (currentValue & MASK_DATAMODUL_MODULATION_TYPE) { |
| 106 | case DATAMODUL_MODULATION_TYPE_OOK: return OOK; | 106 | case DATAMODUL_MODULATION_TYPE_OOK: return OOK; |
| 107 | case DATAMODUL_MODULATION_TYPE_FSK: return FSK; | 107 | case DATAMODUL_MODULATION_TYPE_FSK: return FSK; |
| 108 | default: return undefined; | 108 | default: return undefined; |
diff --git a/drivers/target/target_core_pscsi.c b/drivers/target/target_core_pscsi.c index 7c69b4a9694d..0d99b242e82e 100644 --- a/drivers/target/target_core_pscsi.c +++ b/drivers/target/target_core_pscsi.c | |||
| @@ -920,7 +920,7 @@ pscsi_map_sg(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents, | |||
| 920 | " %d i: %d bio: %p, allocating another" | 920 | " %d i: %d bio: %p, allocating another" |
| 921 | " bio\n", bio->bi_vcnt, i, bio); | 921 | " bio\n", bio->bi_vcnt, i, bio); |
| 922 | 922 | ||
| 923 | rc = blk_rq_append_bio(req, bio); | 923 | rc = blk_rq_append_bio(req, &bio); |
| 924 | if (rc) { | 924 | if (rc) { |
| 925 | pr_err("pSCSI: failed to append bio\n"); | 925 | pr_err("pSCSI: failed to append bio\n"); |
| 926 | goto fail; | 926 | goto fail; |
| @@ -938,7 +938,7 @@ pscsi_map_sg(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents, | |||
| 938 | } | 938 | } |
| 939 | 939 | ||
| 940 | if (bio) { | 940 | if (bio) { |
| 941 | rc = blk_rq_append_bio(req, bio); | 941 | rc = blk_rq_append_bio(req, &bio); |
| 942 | if (rc) { | 942 | if (rc) { |
| 943 | pr_err("pSCSI: failed to append bio\n"); | 943 | pr_err("pSCSI: failed to append bio\n"); |
| 944 | goto fail; | 944 | goto fail; |
diff --git a/drivers/thunderbolt/nhi.c b/drivers/thunderbolt/nhi.c index 419a7a90bce0..f45bcbc63738 100644 --- a/drivers/thunderbolt/nhi.c +++ b/drivers/thunderbolt/nhi.c | |||
| @@ -339,7 +339,7 @@ static void __ring_interrupt(struct tb_ring *ring) | |||
| 339 | return; | 339 | return; |
| 340 | 340 | ||
| 341 | if (ring->start_poll) { | 341 | if (ring->start_poll) { |
| 342 | __ring_interrupt_mask(ring, false); | 342 | __ring_interrupt_mask(ring, true); |
| 343 | ring->start_poll(ring->poll_data); | 343 | ring->start_poll(ring->poll_data); |
| 344 | } else { | 344 | } else { |
| 345 | schedule_work(&ring->work); | 345 | schedule_work(&ring->work); |
diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index 427e0d5d8f13..539b49adb6af 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c | |||
| @@ -1762,7 +1762,7 @@ static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old) | |||
| 1762 | { | 1762 | { |
| 1763 | struct n_tty_data *ldata = tty->disc_data; | 1763 | struct n_tty_data *ldata = tty->disc_data; |
| 1764 | 1764 | ||
| 1765 | if (!old || (old->c_lflag ^ tty->termios.c_lflag) & ICANON) { | 1765 | if (!old || (old->c_lflag ^ tty->termios.c_lflag) & (ICANON | EXTPROC)) { |
| 1766 | bitmap_zero(ldata->read_flags, N_TTY_BUF_SIZE); | 1766 | bitmap_zero(ldata->read_flags, N_TTY_BUF_SIZE); |
| 1767 | ldata->line_start = ldata->read_tail; | 1767 | ldata->line_start = ldata->read_tail; |
| 1768 | if (!L_ICANON(tty) || !read_cnt(ldata)) { | 1768 | if (!L_ICANON(tty) || !read_cnt(ldata)) { |
| @@ -2425,7 +2425,7 @@ static int n_tty_ioctl(struct tty_struct *tty, struct file *file, | |||
| 2425 | return put_user(tty_chars_in_buffer(tty), (int __user *) arg); | 2425 | return put_user(tty_chars_in_buffer(tty), (int __user *) arg); |
| 2426 | case TIOCINQ: | 2426 | case TIOCINQ: |
| 2427 | down_write(&tty->termios_rwsem); | 2427 | down_write(&tty->termios_rwsem); |
| 2428 | if (L_ICANON(tty)) | 2428 | if (L_ICANON(tty) && !L_EXTPROC(tty)) |
| 2429 | retval = inq_canon(ldata); | 2429 | retval = inq_canon(ldata); |
| 2430 | else | 2430 | else |
| 2431 | retval = read_cnt(ldata); | 2431 | retval = read_cnt(ldata); |
diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c index 3593ce0ec641..880009987460 100644 --- a/drivers/usb/chipidea/ci_hdrc_msm.c +++ b/drivers/usb/chipidea/ci_hdrc_msm.c | |||
| @@ -247,7 +247,7 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev) | |||
| 247 | if (ret) | 247 | if (ret) |
| 248 | goto err_mux; | 248 | goto err_mux; |
| 249 | 249 | ||
| 250 | ulpi_node = of_find_node_by_name(of_node_get(pdev->dev.of_node), "ulpi"); | 250 | ulpi_node = of_get_child_by_name(pdev->dev.of_node, "ulpi"); |
| 251 | if (ulpi_node) { | 251 | if (ulpi_node) { |
| 252 | phy_node = of_get_next_available_child(ulpi_node, NULL); | 252 | phy_node = of_get_next_available_child(ulpi_node, NULL); |
| 253 | ci->hsic = of_device_is_compatible(phy_node, "qcom,usb-hsic-phy"); | 253 | ci->hsic = of_device_is_compatible(phy_node, "qcom,usb-hsic-phy"); |
diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c index 55b198ba629b..c821b4b9647e 100644 --- a/drivers/usb/core/config.c +++ b/drivers/usb/core/config.c | |||
| @@ -555,6 +555,9 @@ static int usb_parse_configuration(struct usb_device *dev, int cfgidx, | |||
| 555 | unsigned iad_num = 0; | 555 | unsigned iad_num = 0; |
| 556 | 556 | ||
| 557 | memcpy(&config->desc, buffer, USB_DT_CONFIG_SIZE); | 557 | memcpy(&config->desc, buffer, USB_DT_CONFIG_SIZE); |
| 558 | nintf = nintf_orig = config->desc.bNumInterfaces; | ||
| 559 | config->desc.bNumInterfaces = 0; // Adjusted later | ||
| 560 | |||
| 558 | if (config->desc.bDescriptorType != USB_DT_CONFIG || | 561 | if (config->desc.bDescriptorType != USB_DT_CONFIG || |
| 559 | config->desc.bLength < USB_DT_CONFIG_SIZE || | 562 | config->desc.bLength < USB_DT_CONFIG_SIZE || |
| 560 | config->desc.bLength > size) { | 563 | config->desc.bLength > size) { |
| @@ -568,7 +571,6 @@ static int usb_parse_configuration(struct usb_device *dev, int cfgidx, | |||
| 568 | buffer += config->desc.bLength; | 571 | buffer += config->desc.bLength; |
| 569 | size -= config->desc.bLength; | 572 | size -= config->desc.bLength; |
| 570 | 573 | ||
| 571 | nintf = nintf_orig = config->desc.bNumInterfaces; | ||
| 572 | if (nintf > USB_MAXINTERFACES) { | 574 | if (nintf > USB_MAXINTERFACES) { |
| 573 | dev_warn(ddev, "config %d has too many interfaces: %d, " | 575 | dev_warn(ddev, "config %d has too many interfaces: %d, " |
| 574 | "using maximum allowed: %d\n", | 576 | "using maximum allowed: %d\n", |
| @@ -1005,7 +1007,7 @@ int usb_get_bos_descriptor(struct usb_device *dev) | |||
| 1005 | case USB_SSP_CAP_TYPE: | 1007 | case USB_SSP_CAP_TYPE: |
| 1006 | ssp_cap = (struct usb_ssp_cap_descriptor *)buffer; | 1008 | ssp_cap = (struct usb_ssp_cap_descriptor *)buffer; |
| 1007 | ssac = (le32_to_cpu(ssp_cap->bmAttributes) & | 1009 | ssac = (le32_to_cpu(ssp_cap->bmAttributes) & |
| 1008 | USB_SSP_SUBLINK_SPEED_ATTRIBS) + 1; | 1010 | USB_SSP_SUBLINK_SPEED_ATTRIBS); |
| 1009 | if (length >= USB_DT_USB_SSP_CAP_SIZE(ssac)) | 1011 | if (length >= USB_DT_USB_SSP_CAP_SIZE(ssac)) |
| 1010 | dev->bos->ssp_cap = ssp_cap; | 1012 | dev->bos->ssp_cap = ssp_cap; |
| 1011 | break; | 1013 | break; |
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index a10b346b9777..4024926c1d68 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c | |||
| @@ -52,10 +52,11 @@ static const struct usb_device_id usb_quirk_list[] = { | |||
| 52 | /* Microsoft LifeCam-VX700 v2.0 */ | 52 | /* Microsoft LifeCam-VX700 v2.0 */ |
| 53 | { USB_DEVICE(0x045e, 0x0770), .driver_info = USB_QUIRK_RESET_RESUME }, | 53 | { USB_DEVICE(0x045e, 0x0770), .driver_info = USB_QUIRK_RESET_RESUME }, |
| 54 | 54 | ||
| 55 | /* Logitech HD Pro Webcams C920, C920-C and C930e */ | 55 | /* Logitech HD Pro Webcams C920, C920-C, C925e and C930e */ |
| 56 | { USB_DEVICE(0x046d, 0x082d), .driver_info = USB_QUIRK_DELAY_INIT }, | 56 | { USB_DEVICE(0x046d, 0x082d), .driver_info = USB_QUIRK_DELAY_INIT }, |
| 57 | { USB_DEVICE(0x046d, 0x0841), .driver_info = USB_QUIRK_DELAY_INIT }, | 57 | { USB_DEVICE(0x046d, 0x0841), .driver_info = USB_QUIRK_DELAY_INIT }, |
| 58 | { USB_DEVICE(0x046d, 0x0843), .driver_info = USB_QUIRK_DELAY_INIT }, | 58 | { USB_DEVICE(0x046d, 0x0843), .driver_info = USB_QUIRK_DELAY_INIT }, |
| 59 | { USB_DEVICE(0x046d, 0x085b), .driver_info = USB_QUIRK_DELAY_INIT }, | ||
| 59 | 60 | ||
| 60 | /* Logitech ConferenceCam CC3000e */ | 61 | /* Logitech ConferenceCam CC3000e */ |
| 61 | { USB_DEVICE(0x046d, 0x0847), .driver_info = USB_QUIRK_DELAY_INIT }, | 62 | { USB_DEVICE(0x046d, 0x0847), .driver_info = USB_QUIRK_DELAY_INIT }, |
| @@ -149,6 +150,9 @@ static const struct usb_device_id usb_quirk_list[] = { | |||
| 149 | /* Genesys Logic hub, internally used by KY-688 USB 3.1 Type-C Hub */ | 150 | /* Genesys Logic hub, internally used by KY-688 USB 3.1 Type-C Hub */ |
| 150 | { USB_DEVICE(0x05e3, 0x0612), .driver_info = USB_QUIRK_NO_LPM }, | 151 | { USB_DEVICE(0x05e3, 0x0612), .driver_info = USB_QUIRK_NO_LPM }, |
| 151 | 152 | ||
| 153 | /* ELSA MicroLink 56K */ | ||
| 154 | { USB_DEVICE(0x05cc, 0x2267), .driver_info = USB_QUIRK_RESET_RESUME }, | ||
| 155 | |||
| 152 | /* Genesys Logic hub, internally used by Moshi USB to Ethernet Adapter */ | 156 | /* Genesys Logic hub, internally used by Moshi USB to Ethernet Adapter */ |
| 153 | { USB_DEVICE(0x05e3, 0x0616), .driver_info = USB_QUIRK_NO_LPM }, | 157 | { USB_DEVICE(0x05e3, 0x0616), .driver_info = USB_QUIRK_NO_LPM }, |
| 154 | 158 | ||
diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index f66c94130cac..31749c79045f 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h | |||
| @@ -537,6 +537,7 @@ struct dwc2_core_params { | |||
| 537 | * 2 - Internal DMA | 537 | * 2 - Internal DMA |
| 538 | * @power_optimized Are power optimizations enabled? | 538 | * @power_optimized Are power optimizations enabled? |
| 539 | * @num_dev_ep Number of device endpoints available | 539 | * @num_dev_ep Number of device endpoints available |
| 540 | * @num_dev_in_eps Number of device IN endpoints available | ||
| 540 | * @num_dev_perio_in_ep Number of device periodic IN endpoints | 541 | * @num_dev_perio_in_ep Number of device periodic IN endpoints |
| 541 | * available | 542 | * available |
| 542 | * @dev_token_q_depth Device Mode IN Token Sequence Learning Queue | 543 | * @dev_token_q_depth Device Mode IN Token Sequence Learning Queue |
| @@ -565,6 +566,7 @@ struct dwc2_core_params { | |||
| 565 | * 2 - 8 or 16 bits | 566 | * 2 - 8 or 16 bits |
| 566 | * @snpsid: Value from SNPSID register | 567 | * @snpsid: Value from SNPSID register |
| 567 | * @dev_ep_dirs: Direction of device endpoints (GHWCFG1) | 568 | * @dev_ep_dirs: Direction of device endpoints (GHWCFG1) |
| 569 | * @g_tx_fifo_size[] Power-on values of TxFIFO sizes | ||
| 568 | */ | 570 | */ |
| 569 | struct dwc2_hw_params { | 571 | struct dwc2_hw_params { |
| 570 | unsigned op_mode:3; | 572 | unsigned op_mode:3; |
| @@ -586,12 +588,14 @@ struct dwc2_hw_params { | |||
| 586 | unsigned fs_phy_type:2; | 588 | unsigned fs_phy_type:2; |
| 587 | unsigned i2c_enable:1; | 589 | unsigned i2c_enable:1; |
| 588 | unsigned num_dev_ep:4; | 590 | unsigned num_dev_ep:4; |
| 591 | unsigned num_dev_in_eps : 4; | ||
| 589 | unsigned num_dev_perio_in_ep:4; | 592 | unsigned num_dev_perio_in_ep:4; |
| 590 | unsigned total_fifo_size:16; | 593 | unsigned total_fifo_size:16; |
| 591 | unsigned power_optimized:1; | 594 | unsigned power_optimized:1; |
| 592 | unsigned utmi_phy_data_width:2; | 595 | unsigned utmi_phy_data_width:2; |
| 593 | u32 snpsid; | 596 | u32 snpsid; |
| 594 | u32 dev_ep_dirs; | 597 | u32 dev_ep_dirs; |
| 598 | u32 g_tx_fifo_size[MAX_EPS_CHANNELS]; | ||
| 595 | }; | 599 | }; |
| 596 | 600 | ||
| 597 | /* Size of control and EP0 buffers */ | 601 | /* Size of control and EP0 buffers */ |
diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 88529d092503..e4c3ce0de5de 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c | |||
| @@ -195,55 +195,18 @@ int dwc2_hsotg_tx_fifo_count(struct dwc2_hsotg *hsotg) | |||
| 195 | { | 195 | { |
| 196 | if (hsotg->hw_params.en_multiple_tx_fifo) | 196 | if (hsotg->hw_params.en_multiple_tx_fifo) |
| 197 | /* In dedicated FIFO mode we need count of IN EPs */ | 197 | /* In dedicated FIFO mode we need count of IN EPs */ |
| 198 | return (dwc2_readl(hsotg->regs + GHWCFG4) & | 198 | return hsotg->hw_params.num_dev_in_eps; |
| 199 | GHWCFG4_NUM_IN_EPS_MASK) >> GHWCFG4_NUM_IN_EPS_SHIFT; | ||
| 200 | else | 199 | else |
| 201 | /* In shared FIFO mode we need count of Periodic IN EPs */ | 200 | /* In shared FIFO mode we need count of Periodic IN EPs */ |
| 202 | return hsotg->hw_params.num_dev_perio_in_ep; | 201 | return hsotg->hw_params.num_dev_perio_in_ep; |
| 203 | } | 202 | } |
| 204 | 203 | ||
| 205 | /** | 204 | /** |
| 206 | * dwc2_hsotg_ep_info_size - return Endpoint Info Control block size in DWORDs | ||
| 207 | */ | ||
| 208 | static int dwc2_hsotg_ep_info_size(struct dwc2_hsotg *hsotg) | ||
| 209 | { | ||
| 210 | int val = 0; | ||
| 211 | int i; | ||
| 212 | u32 ep_dirs; | ||
| 213 | |||
| 214 | /* | ||
| 215 | * Don't need additional space for ep info control registers in | ||
| 216 | * slave mode. | ||
| 217 | */ | ||
| 218 | if (!using_dma(hsotg)) { | ||
| 219 | dev_dbg(hsotg->dev, "Buffer DMA ep info size 0\n"); | ||
| 220 | return 0; | ||
| 221 | } | ||
| 222 | |||
| 223 | /* | ||
| 224 | * Buffer DMA mode - 1 location per endpoit | ||
| 225 | * Descriptor DMA mode - 4 locations per endpoint | ||
| 226 | */ | ||
| 227 | ep_dirs = hsotg->hw_params.dev_ep_dirs; | ||
| 228 | |||
| 229 | for (i = 0; i <= hsotg->hw_params.num_dev_ep; i++) { | ||
| 230 | val += ep_dirs & 3 ? 1 : 2; | ||
| 231 | ep_dirs >>= 2; | ||
| 232 | } | ||
| 233 | |||
| 234 | if (using_desc_dma(hsotg)) | ||
| 235 | val = val * 4; | ||
| 236 | |||
| 237 | return val; | ||
| 238 | } | ||
| 239 | |||
| 240 | /** | ||
| 241 | * dwc2_hsotg_tx_fifo_total_depth - return total FIFO depth available for | 205 | * dwc2_hsotg_tx_fifo_total_depth - return total FIFO depth available for |
| 242 | * device mode TX FIFOs | 206 | * device mode TX FIFOs |
| 243 | */ | 207 | */ |
| 244 | int dwc2_hsotg_tx_fifo_total_depth(struct dwc2_hsotg *hsotg) | 208 | int dwc2_hsotg_tx_fifo_total_depth(struct dwc2_hsotg *hsotg) |
| 245 | { | 209 | { |
| 246 | int ep_info_size; | ||
| 247 | int addr; | 210 | int addr; |
| 248 | int tx_addr_max; | 211 | int tx_addr_max; |
| 249 | u32 np_tx_fifo_size; | 212 | u32 np_tx_fifo_size; |
| @@ -252,8 +215,7 @@ int dwc2_hsotg_tx_fifo_total_depth(struct dwc2_hsotg *hsotg) | |||
| 252 | hsotg->params.g_np_tx_fifo_size); | 215 | hsotg->params.g_np_tx_fifo_size); |
| 253 | 216 | ||
| 254 | /* Get Endpoint Info Control block size in DWORDs. */ | 217 | /* Get Endpoint Info Control block size in DWORDs. */ |
| 255 | ep_info_size = dwc2_hsotg_ep_info_size(hsotg); | 218 | tx_addr_max = hsotg->hw_params.total_fifo_size; |
| 256 | tx_addr_max = hsotg->hw_params.total_fifo_size - ep_info_size; | ||
| 257 | 219 | ||
| 258 | addr = hsotg->params.g_rx_fifo_size + np_tx_fifo_size; | 220 | addr = hsotg->params.g_rx_fifo_size + np_tx_fifo_size; |
| 259 | if (tx_addr_max <= addr) | 221 | if (tx_addr_max <= addr) |
diff --git a/drivers/usb/dwc2/params.c b/drivers/usb/dwc2/params.c index ef73af6e03a9..03fd20f0b496 100644 --- a/drivers/usb/dwc2/params.c +++ b/drivers/usb/dwc2/params.c | |||
| @@ -484,8 +484,7 @@ static void dwc2_check_param_tx_fifo_sizes(struct dwc2_hsotg *hsotg) | |||
| 484 | } | 484 | } |
| 485 | 485 | ||
| 486 | for (fifo = 1; fifo <= fifo_count; fifo++) { | 486 | for (fifo = 1; fifo <= fifo_count; fifo++) { |
| 487 | dptxfszn = (dwc2_readl(hsotg->regs + DPTXFSIZN(fifo)) & | 487 | dptxfszn = hsotg->hw_params.g_tx_fifo_size[fifo]; |
| 488 | FIFOSIZE_DEPTH_MASK) >> FIFOSIZE_DEPTH_SHIFT; | ||
| 489 | 488 | ||
| 490 | if (hsotg->params.g_tx_fifo_size[fifo] < min || | 489 | if (hsotg->params.g_tx_fifo_size[fifo] < min || |
| 491 | hsotg->params.g_tx_fifo_size[fifo] > dptxfszn) { | 490 | hsotg->params.g_tx_fifo_size[fifo] > dptxfszn) { |
| @@ -609,6 +608,7 @@ static void dwc2_get_dev_hwparams(struct dwc2_hsotg *hsotg) | |||
| 609 | struct dwc2_hw_params *hw = &hsotg->hw_params; | 608 | struct dwc2_hw_params *hw = &hsotg->hw_params; |
| 610 | bool forced; | 609 | bool forced; |
| 611 | u32 gnptxfsiz; | 610 | u32 gnptxfsiz; |
| 611 | int fifo, fifo_count; | ||
| 612 | 612 | ||
| 613 | if (hsotg->dr_mode == USB_DR_MODE_HOST) | 613 | if (hsotg->dr_mode == USB_DR_MODE_HOST) |
| 614 | return; | 614 | return; |
| @@ -617,6 +617,14 @@ static void dwc2_get_dev_hwparams(struct dwc2_hsotg *hsotg) | |||
| 617 | 617 | ||
| 618 | gnptxfsiz = dwc2_readl(hsotg->regs + GNPTXFSIZ); | 618 | gnptxfsiz = dwc2_readl(hsotg->regs + GNPTXFSIZ); |
| 619 | 619 | ||
| 620 | fifo_count = dwc2_hsotg_tx_fifo_count(hsotg); | ||
| 621 | |||
| 622 | for (fifo = 1; fifo <= fifo_count; fifo++) { | ||
| 623 | hw->g_tx_fifo_size[fifo] = | ||
| 624 | (dwc2_readl(hsotg->regs + DPTXFSIZN(fifo)) & | ||
| 625 | FIFOSIZE_DEPTH_MASK) >> FIFOSIZE_DEPTH_SHIFT; | ||
| 626 | } | ||
| 627 | |||
| 620 | if (forced) | 628 | if (forced) |
| 621 | dwc2_clear_force_mode(hsotg); | 629 | dwc2_clear_force_mode(hsotg); |
| 622 | 630 | ||
| @@ -661,14 +669,6 @@ int dwc2_get_hwparams(struct dwc2_hsotg *hsotg) | |||
| 661 | hwcfg4 = dwc2_readl(hsotg->regs + GHWCFG4); | 669 | hwcfg4 = dwc2_readl(hsotg->regs + GHWCFG4); |
| 662 | grxfsiz = dwc2_readl(hsotg->regs + GRXFSIZ); | 670 | grxfsiz = dwc2_readl(hsotg->regs + GRXFSIZ); |
| 663 | 671 | ||
| 664 | /* | ||
| 665 | * Host specific hardware parameters. Reading these parameters | ||
| 666 | * requires the controller to be in host mode. The mode will | ||
| 667 | * be forced, if necessary, to read these values. | ||
| 668 | */ | ||
| 669 | dwc2_get_host_hwparams(hsotg); | ||
| 670 | dwc2_get_dev_hwparams(hsotg); | ||
| 671 | |||
| 672 | /* hwcfg1 */ | 672 | /* hwcfg1 */ |
| 673 | hw->dev_ep_dirs = hwcfg1; | 673 | hw->dev_ep_dirs = hwcfg1; |
| 674 | 674 | ||
| @@ -711,6 +711,8 @@ int dwc2_get_hwparams(struct dwc2_hsotg *hsotg) | |||
| 711 | hw->en_multiple_tx_fifo = !!(hwcfg4 & GHWCFG4_DED_FIFO_EN); | 711 | hw->en_multiple_tx_fifo = !!(hwcfg4 & GHWCFG4_DED_FIFO_EN); |
| 712 | hw->num_dev_perio_in_ep = (hwcfg4 & GHWCFG4_NUM_DEV_PERIO_IN_EP_MASK) >> | 712 | hw->num_dev_perio_in_ep = (hwcfg4 & GHWCFG4_NUM_DEV_PERIO_IN_EP_MASK) >> |
| 713 | GHWCFG4_NUM_DEV_PERIO_IN_EP_SHIFT; | 713 | GHWCFG4_NUM_DEV_PERIO_IN_EP_SHIFT; |
| 714 | hw->num_dev_in_eps = (hwcfg4 & GHWCFG4_NUM_IN_EPS_MASK) >> | ||
| 715 | GHWCFG4_NUM_IN_EPS_SHIFT; | ||
| 714 | hw->dma_desc_enable = !!(hwcfg4 & GHWCFG4_DESC_DMA); | 716 | hw->dma_desc_enable = !!(hwcfg4 & GHWCFG4_DESC_DMA); |
| 715 | hw->power_optimized = !!(hwcfg4 & GHWCFG4_POWER_OPTIMIZ); | 717 | hw->power_optimized = !!(hwcfg4 & GHWCFG4_POWER_OPTIMIZ); |
| 716 | hw->utmi_phy_data_width = (hwcfg4 & GHWCFG4_UTMI_PHY_DATA_WIDTH_MASK) >> | 718 | hw->utmi_phy_data_width = (hwcfg4 & GHWCFG4_UTMI_PHY_DATA_WIDTH_MASK) >> |
| @@ -719,6 +721,13 @@ int dwc2_get_hwparams(struct dwc2_hsotg *hsotg) | |||
| 719 | /* fifo sizes */ | 721 | /* fifo sizes */ |
| 720 | hw->rx_fifo_size = (grxfsiz & GRXFSIZ_DEPTH_MASK) >> | 722 | hw->rx_fifo_size = (grxfsiz & GRXFSIZ_DEPTH_MASK) >> |
| 721 | GRXFSIZ_DEPTH_SHIFT; | 723 | GRXFSIZ_DEPTH_SHIFT; |
| 724 | /* | ||
| 725 | * Host specific hardware parameters. Reading these parameters | ||
| 726 | * requires the controller to be in host mode. The mode will | ||
| 727 | * be forced, if necessary, to read these values. | ||
| 728 | */ | ||
| 729 | dwc2_get_host_hwparams(hsotg); | ||
| 730 | dwc2_get_dev_hwparams(hsotg); | ||
| 722 | 731 | ||
| 723 | return 0; | 732 | return 0; |
| 724 | } | 733 | } |
diff --git a/drivers/usb/dwc3/dwc3-of-simple.c b/drivers/usb/dwc3/dwc3-of-simple.c index c4a4d7bd2766..7ae0eefc7cc7 100644 --- a/drivers/usb/dwc3/dwc3-of-simple.c +++ b/drivers/usb/dwc3/dwc3-of-simple.c | |||
| @@ -51,8 +51,10 @@ static int dwc3_of_simple_clk_init(struct dwc3_of_simple *simple, int count) | |||
| 51 | 51 | ||
| 52 | clk = of_clk_get(np, i); | 52 | clk = of_clk_get(np, i); |
| 53 | if (IS_ERR(clk)) { | 53 | if (IS_ERR(clk)) { |
| 54 | while (--i >= 0) | 54 | while (--i >= 0) { |
| 55 | clk_disable_unprepare(simple->clks[i]); | ||
| 55 | clk_put(simple->clks[i]); | 56 | clk_put(simple->clks[i]); |
| 57 | } | ||
| 56 | return PTR_ERR(clk); | 58 | return PTR_ERR(clk); |
| 57 | } | 59 | } |
| 58 | 60 | ||
| @@ -203,6 +205,7 @@ static struct platform_driver dwc3_of_simple_driver = { | |||
| 203 | .driver = { | 205 | .driver = { |
| 204 | .name = "dwc3-of-simple", | 206 | .name = "dwc3-of-simple", |
| 205 | .of_match_table = of_dwc3_simple_match, | 207 | .of_match_table = of_dwc3_simple_match, |
| 208 | .pm = &dwc3_of_simple_dev_pm_ops, | ||
| 206 | }, | 209 | }, |
| 207 | }; | 210 | }; |
| 208 | 211 | ||
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 981fd986cf82..639dd1b163a0 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c | |||
| @@ -259,7 +259,7 @@ int dwc3_send_gadget_ep_cmd(struct dwc3_ep *dep, unsigned cmd, | |||
| 259 | { | 259 | { |
| 260 | const struct usb_endpoint_descriptor *desc = dep->endpoint.desc; | 260 | const struct usb_endpoint_descriptor *desc = dep->endpoint.desc; |
| 261 | struct dwc3 *dwc = dep->dwc; | 261 | struct dwc3 *dwc = dep->dwc; |
| 262 | u32 timeout = 500; | 262 | u32 timeout = 1000; |
| 263 | u32 reg; | 263 | u32 reg; |
| 264 | 264 | ||
| 265 | int cmd_status = 0; | 265 | int cmd_status = 0; |
| @@ -912,7 +912,7 @@ static void __dwc3_prepare_one_trb(struct dwc3_ep *dep, struct dwc3_trb *trb, | |||
| 912 | */ | 912 | */ |
| 913 | if (speed == USB_SPEED_HIGH) { | 913 | if (speed == USB_SPEED_HIGH) { |
| 914 | struct usb_ep *ep = &dep->endpoint; | 914 | struct usb_ep *ep = &dep->endpoint; |
| 915 | unsigned int mult = ep->mult - 1; | 915 | unsigned int mult = 2; |
| 916 | unsigned int maxp = usb_endpoint_maxp(ep->desc); | 916 | unsigned int maxp = usb_endpoint_maxp(ep->desc); |
| 917 | 917 | ||
| 918 | if (length <= (2 * maxp)) | 918 | if (length <= (2 * maxp)) |
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 0a19a76645ad..31cce7805eb2 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig | |||
| @@ -508,8 +508,8 @@ choice | |||
| 508 | controller, and the relevant drivers for each function declared | 508 | controller, and the relevant drivers for each function declared |
| 509 | by the device. | 509 | by the device. |
| 510 | 510 | ||
| 511 | endchoice | ||
| 512 | |||
| 513 | source "drivers/usb/gadget/legacy/Kconfig" | 511 | source "drivers/usb/gadget/legacy/Kconfig" |
| 514 | 512 | ||
| 513 | endchoice | ||
| 514 | |||
| 515 | endif # USB_GADGET | 515 | endif # USB_GADGET |
diff --git a/drivers/usb/gadget/legacy/Kconfig b/drivers/usb/gadget/legacy/Kconfig index 9570bbeced4f..784bf86dad4f 100644 --- a/drivers/usb/gadget/legacy/Kconfig +++ b/drivers/usb/gadget/legacy/Kconfig | |||
| @@ -13,14 +13,6 @@ | |||
| 13 | # both kinds of controller can also support "USB On-the-Go" (CONFIG_USB_OTG). | 13 | # both kinds of controller can also support "USB On-the-Go" (CONFIG_USB_OTG). |
| 14 | # | 14 | # |
| 15 | 15 | ||
| 16 | menuconfig USB_GADGET_LEGACY | ||
| 17 | bool "Legacy USB Gadget Support" | ||
| 18 | help | ||
| 19 | Legacy USB gadgets are USB gadgets that do not use the USB gadget | ||
| 20 | configfs interface. | ||
| 21 | |||
| 22 | if USB_GADGET_LEGACY | ||
| 23 | |||
| 24 | config USB_ZERO | 16 | config USB_ZERO |
| 25 | tristate "Gadget Zero (DEVELOPMENT)" | 17 | tristate "Gadget Zero (DEVELOPMENT)" |
| 26 | select USB_LIBCOMPOSITE | 18 | select USB_LIBCOMPOSITE |
| @@ -487,7 +479,7 @@ endif | |||
| 487 | # or video class gadget drivers), or specific hardware, here. | 479 | # or video class gadget drivers), or specific hardware, here. |
| 488 | config USB_G_WEBCAM | 480 | config USB_G_WEBCAM |
| 489 | tristate "USB Webcam Gadget" | 481 | tristate "USB Webcam Gadget" |
| 490 | depends on VIDEO_DEV | 482 | depends on VIDEO_V4L2 |
| 491 | select USB_LIBCOMPOSITE | 483 | select USB_LIBCOMPOSITE |
| 492 | select VIDEOBUF2_VMALLOC | 484 | select VIDEOBUF2_VMALLOC |
| 493 | select USB_F_UVC | 485 | select USB_F_UVC |
| @@ -498,5 +490,3 @@ config USB_G_WEBCAM | |||
| 498 | 490 | ||
| 499 | Say "y" to link the driver statically, or "m" to build a | 491 | Say "y" to link the driver statically, or "m" to build a |
| 500 | dynamically linked module called "g_webcam". | 492 | dynamically linked module called "g_webcam". |
| 501 | |||
| 502 | endif | ||
diff --git a/drivers/usb/host/xhci-debugfs.c b/drivers/usb/host/xhci-debugfs.c index 4f7895dbcf88..e26e685d8a57 100644 --- a/drivers/usb/host/xhci-debugfs.c +++ b/drivers/usb/host/xhci-debugfs.c | |||
| @@ -162,7 +162,7 @@ static void xhci_debugfs_extcap_regset(struct xhci_hcd *xhci, int cap_id, | |||
| 162 | static int xhci_ring_enqueue_show(struct seq_file *s, void *unused) | 162 | static int xhci_ring_enqueue_show(struct seq_file *s, void *unused) |
| 163 | { | 163 | { |
| 164 | dma_addr_t dma; | 164 | dma_addr_t dma; |
| 165 | struct xhci_ring *ring = s->private; | 165 | struct xhci_ring *ring = *(struct xhci_ring **)s->private; |
| 166 | 166 | ||
| 167 | dma = xhci_trb_virt_to_dma(ring->enq_seg, ring->enqueue); | 167 | dma = xhci_trb_virt_to_dma(ring->enq_seg, ring->enqueue); |
| 168 | seq_printf(s, "%pad\n", &dma); | 168 | seq_printf(s, "%pad\n", &dma); |
| @@ -173,7 +173,7 @@ static int xhci_ring_enqueue_show(struct seq_file *s, void *unused) | |||
| 173 | static int xhci_ring_dequeue_show(struct seq_file *s, void *unused) | 173 | static int xhci_ring_dequeue_show(struct seq_file *s, void *unused) |
| 174 | { | 174 | { |
| 175 | dma_addr_t dma; | 175 | dma_addr_t dma; |
| 176 | struct xhci_ring *ring = s->private; | 176 | struct xhci_ring *ring = *(struct xhci_ring **)s->private; |
| 177 | 177 | ||
| 178 | dma = xhci_trb_virt_to_dma(ring->deq_seg, ring->dequeue); | 178 | dma = xhci_trb_virt_to_dma(ring->deq_seg, ring->dequeue); |
| 179 | seq_printf(s, "%pad\n", &dma); | 179 | seq_printf(s, "%pad\n", &dma); |
| @@ -183,7 +183,7 @@ static int xhci_ring_dequeue_show(struct seq_file *s, void *unused) | |||
| 183 | 183 | ||
| 184 | static int xhci_ring_cycle_show(struct seq_file *s, void *unused) | 184 | static int xhci_ring_cycle_show(struct seq_file *s, void *unused) |
| 185 | { | 185 | { |
| 186 | struct xhci_ring *ring = s->private; | 186 | struct xhci_ring *ring = *(struct xhci_ring **)s->private; |
| 187 | 187 | ||
| 188 | seq_printf(s, "%d\n", ring->cycle_state); | 188 | seq_printf(s, "%d\n", ring->cycle_state); |
| 189 | 189 | ||
| @@ -346,7 +346,7 @@ static void xhci_debugfs_create_files(struct xhci_hcd *xhci, | |||
| 346 | } | 346 | } |
| 347 | 347 | ||
| 348 | static struct dentry *xhci_debugfs_create_ring_dir(struct xhci_hcd *xhci, | 348 | static struct dentry *xhci_debugfs_create_ring_dir(struct xhci_hcd *xhci, |
| 349 | struct xhci_ring *ring, | 349 | struct xhci_ring **ring, |
| 350 | const char *name, | 350 | const char *name, |
| 351 | struct dentry *parent) | 351 | struct dentry *parent) |
| 352 | { | 352 | { |
| @@ -387,7 +387,7 @@ void xhci_debugfs_create_endpoint(struct xhci_hcd *xhci, | |||
| 387 | 387 | ||
| 388 | snprintf(epriv->name, sizeof(epriv->name), "ep%02d", ep_index); | 388 | snprintf(epriv->name, sizeof(epriv->name), "ep%02d", ep_index); |
| 389 | epriv->root = xhci_debugfs_create_ring_dir(xhci, | 389 | epriv->root = xhci_debugfs_create_ring_dir(xhci, |
| 390 | dev->eps[ep_index].new_ring, | 390 | &dev->eps[ep_index].new_ring, |
| 391 | epriv->name, | 391 | epriv->name, |
| 392 | spriv->root); | 392 | spriv->root); |
| 393 | spriv->eps[ep_index] = epriv; | 393 | spriv->eps[ep_index] = epriv; |
| @@ -423,7 +423,7 @@ void xhci_debugfs_create_slot(struct xhci_hcd *xhci, int slot_id) | |||
| 423 | priv->dev = dev; | 423 | priv->dev = dev; |
| 424 | dev->debugfs_private = priv; | 424 | dev->debugfs_private = priv; |
| 425 | 425 | ||
| 426 | xhci_debugfs_create_ring_dir(xhci, dev->eps[0].ring, | 426 | xhci_debugfs_create_ring_dir(xhci, &dev->eps[0].ring, |
| 427 | "ep00", priv->root); | 427 | "ep00", priv->root); |
| 428 | 428 | ||
| 429 | xhci_debugfs_create_context_files(xhci, priv->root, slot_id); | 429 | xhci_debugfs_create_context_files(xhci, priv->root, slot_id); |
| @@ -488,11 +488,11 @@ void xhci_debugfs_init(struct xhci_hcd *xhci) | |||
| 488 | ARRAY_SIZE(xhci_extcap_dbc), | 488 | ARRAY_SIZE(xhci_extcap_dbc), |
| 489 | "reg-ext-dbc"); | 489 | "reg-ext-dbc"); |
| 490 | 490 | ||
| 491 | xhci_debugfs_create_ring_dir(xhci, xhci->cmd_ring, | 491 | xhci_debugfs_create_ring_dir(xhci, &xhci->cmd_ring, |
| 492 | "command-ring", | 492 | "command-ring", |
| 493 | xhci->debugfs_root); | 493 | xhci->debugfs_root); |
| 494 | 494 | ||
| 495 | xhci_debugfs_create_ring_dir(xhci, xhci->event_ring, | 495 | xhci_debugfs_create_ring_dir(xhci, &xhci->event_ring, |
| 496 | "event-ring", | 496 | "event-ring", |
| 497 | xhci->debugfs_root); | 497 | xhci->debugfs_root); |
| 498 | 498 | ||
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 15f7d422885f..3a29b32a3bd0 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c | |||
| @@ -971,10 +971,9 @@ int xhci_alloc_virt_device(struct xhci_hcd *xhci, int slot_id, | |||
| 971 | return 0; | 971 | return 0; |
| 972 | } | 972 | } |
| 973 | 973 | ||
| 974 | xhci->devs[slot_id] = kzalloc(sizeof(*xhci->devs[slot_id]), flags); | 974 | dev = kzalloc(sizeof(*dev), flags); |
| 975 | if (!xhci->devs[slot_id]) | 975 | if (!dev) |
| 976 | return 0; | 976 | return 0; |
| 977 | dev = xhci->devs[slot_id]; | ||
| 978 | 977 | ||
| 979 | /* Allocate the (output) device context that will be used in the HC. */ | 978 | /* Allocate the (output) device context that will be used in the HC. */ |
| 980 | dev->out_ctx = xhci_alloc_container_ctx(xhci, XHCI_CTX_TYPE_DEVICE, flags); | 979 | dev->out_ctx = xhci_alloc_container_ctx(xhci, XHCI_CTX_TYPE_DEVICE, flags); |
| @@ -1015,9 +1014,17 @@ int xhci_alloc_virt_device(struct xhci_hcd *xhci, int slot_id, | |||
| 1015 | 1014 | ||
| 1016 | trace_xhci_alloc_virt_device(dev); | 1015 | trace_xhci_alloc_virt_device(dev); |
| 1017 | 1016 | ||
| 1017 | xhci->devs[slot_id] = dev; | ||
| 1018 | |||
| 1018 | return 1; | 1019 | return 1; |
| 1019 | fail: | 1020 | fail: |
| 1020 | xhci_free_virt_device(xhci, slot_id); | 1021 | |
| 1022 | if (dev->in_ctx) | ||
| 1023 | xhci_free_container_ctx(xhci, dev->in_ctx); | ||
| 1024 | if (dev->out_ctx) | ||
| 1025 | xhci_free_container_ctx(xhci, dev->out_ctx); | ||
| 1026 | kfree(dev); | ||
| 1027 | |||
| 1021 | return 0; | 1028 | return 0; |
| 1022 | } | 1029 | } |
| 1023 | 1030 | ||
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index 7ef1274ef7f7..1aad89b8aba0 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c | |||
| @@ -178,6 +178,9 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) | |||
| 178 | xhci->quirks |= XHCI_BROKEN_STREAMS; | 178 | xhci->quirks |= XHCI_BROKEN_STREAMS; |
| 179 | } | 179 | } |
| 180 | if (pdev->vendor == PCI_VENDOR_ID_RENESAS && | 180 | if (pdev->vendor == PCI_VENDOR_ID_RENESAS && |
| 181 | pdev->device == 0x0014) | ||
| 182 | xhci->quirks |= XHCI_TRUST_TX_LENGTH; | ||
| 183 | if (pdev->vendor == PCI_VENDOR_ID_RENESAS && | ||
| 181 | pdev->device == 0x0015) | 184 | pdev->device == 0x0015) |
| 182 | xhci->quirks |= XHCI_RESET_ON_RESUME; | 185 | xhci->quirks |= XHCI_RESET_ON_RESUME; |
| 183 | if (pdev->vendor == PCI_VENDOR_ID_VIA) | 186 | if (pdev->vendor == PCI_VENDOR_ID_VIA) |
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 6eb87c6e4d24..c5cbc685c691 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c | |||
| @@ -3112,7 +3112,7 @@ static u32 xhci_td_remainder(struct xhci_hcd *xhci, int transferred, | |||
| 3112 | { | 3112 | { |
| 3113 | u32 maxp, total_packet_count; | 3113 | u32 maxp, total_packet_count; |
| 3114 | 3114 | ||
| 3115 | /* MTK xHCI is mostly 0.97 but contains some features from 1.0 */ | 3115 | /* MTK xHCI 0.96 contains some features from 1.0 */ |
| 3116 | if (xhci->hci_version < 0x100 && !(xhci->quirks & XHCI_MTK_HOST)) | 3116 | if (xhci->hci_version < 0x100 && !(xhci->quirks & XHCI_MTK_HOST)) |
| 3117 | return ((td_total_len - transferred) >> 10); | 3117 | return ((td_total_len - transferred) >> 10); |
| 3118 | 3118 | ||
| @@ -3121,8 +3121,8 @@ static u32 xhci_td_remainder(struct xhci_hcd *xhci, int transferred, | |||
| 3121 | trb_buff_len == td_total_len) | 3121 | trb_buff_len == td_total_len) |
| 3122 | return 0; | 3122 | return 0; |
| 3123 | 3123 | ||
| 3124 | /* for MTK xHCI, TD size doesn't include this TRB */ | 3124 | /* for MTK xHCI 0.96, TD size include this TRB, but not in 1.x */ |
| 3125 | if (xhci->quirks & XHCI_MTK_HOST) | 3125 | if ((xhci->quirks & XHCI_MTK_HOST) && (xhci->hci_version < 0x100)) |
| 3126 | trb_buff_len = 0; | 3126 | trb_buff_len = 0; |
| 3127 | 3127 | ||
| 3128 | maxp = usb_endpoint_maxp(&urb->ep->desc); | 3128 | maxp = usb_endpoint_maxp(&urb->ep->desc); |
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 2424d3020ca3..da6dbe3ebd8b 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c | |||
| @@ -3525,8 +3525,6 @@ static void xhci_free_dev(struct usb_hcd *hcd, struct usb_device *udev) | |||
| 3525 | struct xhci_slot_ctx *slot_ctx; | 3525 | struct xhci_slot_ctx *slot_ctx; |
| 3526 | int i, ret; | 3526 | int i, ret; |
| 3527 | 3527 | ||
| 3528 | xhci_debugfs_remove_slot(xhci, udev->slot_id); | ||
| 3529 | |||
| 3530 | #ifndef CONFIG_USB_DEFAULT_PERSIST | 3528 | #ifndef CONFIG_USB_DEFAULT_PERSIST |
| 3531 | /* | 3529 | /* |
| 3532 | * We called pm_runtime_get_noresume when the device was attached. | 3530 | * We called pm_runtime_get_noresume when the device was attached. |
| @@ -3555,8 +3553,10 @@ static void xhci_free_dev(struct usb_hcd *hcd, struct usb_device *udev) | |||
| 3555 | } | 3553 | } |
| 3556 | 3554 | ||
| 3557 | ret = xhci_disable_slot(xhci, udev->slot_id); | 3555 | ret = xhci_disable_slot(xhci, udev->slot_id); |
| 3558 | if (ret) | 3556 | if (ret) { |
| 3557 | xhci_debugfs_remove_slot(xhci, udev->slot_id); | ||
| 3559 | xhci_free_virt_device(xhci, udev->slot_id); | 3558 | xhci_free_virt_device(xhci, udev->slot_id); |
| 3559 | } | ||
| 3560 | } | 3560 | } |
| 3561 | 3561 | ||
| 3562 | int xhci_disable_slot(struct xhci_hcd *xhci, u32 slot_id) | 3562 | int xhci_disable_slot(struct xhci_hcd *xhci, u32 slot_id) |
diff --git a/drivers/usb/musb/da8xx.c b/drivers/usb/musb/da8xx.c index 0397606a211b..6c036de63272 100644 --- a/drivers/usb/musb/da8xx.c +++ b/drivers/usb/musb/da8xx.c | |||
| @@ -284,7 +284,15 @@ static irqreturn_t da8xx_musb_interrupt(int irq, void *hci) | |||
| 284 | musb->xceiv->otg->state = OTG_STATE_A_WAIT_VRISE; | 284 | musb->xceiv->otg->state = OTG_STATE_A_WAIT_VRISE; |
| 285 | portstate(musb->port1_status |= USB_PORT_STAT_POWER); | 285 | portstate(musb->port1_status |= USB_PORT_STAT_POWER); |
| 286 | del_timer(&musb->dev_timer); | 286 | del_timer(&musb->dev_timer); |
| 287 | } else { | 287 | } else if (!(musb->int_usb & MUSB_INTR_BABBLE)) { |
| 288 | /* | ||
| 289 | * When babble condition happens, drvvbus interrupt | ||
| 290 | * is also generated. Ignore this drvvbus interrupt | ||
| 291 | * and let babble interrupt handler recovers the | ||
| 292 | * controller; otherwise, the host-mode flag is lost | ||
| 293 | * due to the MUSB_DEV_MODE() call below and babble | ||
| 294 | * recovery logic will not be called. | ||
| 295 | */ | ||
| 288 | musb->is_active = 0; | 296 | musb->is_active = 0; |
| 289 | MUSB_DEV_MODE(musb); | 297 | MUSB_DEV_MODE(musb); |
| 290 | otg->default_a = 0; | 298 | otg->default_a = 0; |
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 1aba9105b369..fc68952c994a 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
| @@ -1013,6 +1013,7 @@ static const struct usb_device_id id_table_combined[] = { | |||
| 1013 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, | 1013 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, |
| 1014 | { USB_DEVICE(CYPRESS_VID, CYPRESS_WICED_BT_USB_PID) }, | 1014 | { USB_DEVICE(CYPRESS_VID, CYPRESS_WICED_BT_USB_PID) }, |
| 1015 | { USB_DEVICE(CYPRESS_VID, CYPRESS_WICED_WL_USB_PID) }, | 1015 | { USB_DEVICE(CYPRESS_VID, CYPRESS_WICED_WL_USB_PID) }, |
| 1016 | { USB_DEVICE(AIRBUS_DS_VID, AIRBUS_DS_P8GR) }, | ||
| 1016 | { } /* Terminating entry */ | 1017 | { } /* Terminating entry */ |
| 1017 | }; | 1018 | }; |
| 1018 | 1019 | ||
diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h index 4faa09fe308c..8b4ecd2bd297 100644 --- a/drivers/usb/serial/ftdi_sio_ids.h +++ b/drivers/usb/serial/ftdi_sio_ids.h | |||
| @@ -915,6 +915,12 @@ | |||
| 915 | #define ICPDAS_I7563U_PID 0x0105 | 915 | #define ICPDAS_I7563U_PID 0x0105 |
| 916 | 916 | ||
| 917 | /* | 917 | /* |
| 918 | * Airbus Defence and Space | ||
| 919 | */ | ||
| 920 | #define AIRBUS_DS_VID 0x1e8e /* Vendor ID */ | ||
| 921 | #define AIRBUS_DS_P8GR 0x6001 /* Tetra P8GR */ | ||
| 922 | |||
| 923 | /* | ||
| 918 | * RT Systems programming cables for various ham radios | 924 | * RT Systems programming cables for various ham radios |
| 919 | */ | 925 | */ |
| 920 | #define RTSYSTEMS_VID 0x2100 /* Vendor ID */ | 926 | #define RTSYSTEMS_VID 0x2100 /* Vendor ID */ |
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 3b3513874cfd..b6320e3be429 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
| @@ -233,6 +233,8 @@ static void option_instat_callback(struct urb *urb); | |||
| 233 | /* These Quectel products use Qualcomm's vendor ID */ | 233 | /* These Quectel products use Qualcomm's vendor ID */ |
| 234 | #define QUECTEL_PRODUCT_UC20 0x9003 | 234 | #define QUECTEL_PRODUCT_UC20 0x9003 |
| 235 | #define QUECTEL_PRODUCT_UC15 0x9090 | 235 | #define QUECTEL_PRODUCT_UC15 0x9090 |
| 236 | /* These Yuga products use Qualcomm's vendor ID */ | ||
| 237 | #define YUGA_PRODUCT_CLM920_NC5 0x9625 | ||
| 236 | 238 | ||
| 237 | #define QUECTEL_VENDOR_ID 0x2c7c | 239 | #define QUECTEL_VENDOR_ID 0x2c7c |
| 238 | /* These Quectel products use Quectel's vendor ID */ | 240 | /* These Quectel products use Quectel's vendor ID */ |
| @@ -280,6 +282,7 @@ static void option_instat_callback(struct urb *urb); | |||
| 280 | #define TELIT_PRODUCT_LE922_USBCFG3 0x1043 | 282 | #define TELIT_PRODUCT_LE922_USBCFG3 0x1043 |
| 281 | #define TELIT_PRODUCT_LE922_USBCFG5 0x1045 | 283 | #define TELIT_PRODUCT_LE922_USBCFG5 0x1045 |
| 282 | #define TELIT_PRODUCT_ME910 0x1100 | 284 | #define TELIT_PRODUCT_ME910 0x1100 |
| 285 | #define TELIT_PRODUCT_ME910_DUAL_MODEM 0x1101 | ||
| 283 | #define TELIT_PRODUCT_LE920 0x1200 | 286 | #define TELIT_PRODUCT_LE920 0x1200 |
| 284 | #define TELIT_PRODUCT_LE910 0x1201 | 287 | #define TELIT_PRODUCT_LE910 0x1201 |
| 285 | #define TELIT_PRODUCT_LE910_USBCFG4 0x1206 | 288 | #define TELIT_PRODUCT_LE910_USBCFG4 0x1206 |
| @@ -645,6 +648,11 @@ static const struct option_blacklist_info telit_me910_blacklist = { | |||
| 645 | .reserved = BIT(1) | BIT(3), | 648 | .reserved = BIT(1) | BIT(3), |
| 646 | }; | 649 | }; |
| 647 | 650 | ||
| 651 | static const struct option_blacklist_info telit_me910_dual_modem_blacklist = { | ||
| 652 | .sendsetup = BIT(0), | ||
| 653 | .reserved = BIT(3), | ||
| 654 | }; | ||
| 655 | |||
| 648 | static const struct option_blacklist_info telit_le910_blacklist = { | 656 | static const struct option_blacklist_info telit_le910_blacklist = { |
| 649 | .sendsetup = BIT(0), | 657 | .sendsetup = BIT(0), |
| 650 | .reserved = BIT(1) | BIT(2), | 658 | .reserved = BIT(1) | BIT(2), |
| @@ -674,6 +682,10 @@ static const struct option_blacklist_info cinterion_rmnet2_blacklist = { | |||
| 674 | .reserved = BIT(4) | BIT(5), | 682 | .reserved = BIT(4) | BIT(5), |
| 675 | }; | 683 | }; |
| 676 | 684 | ||
| 685 | static const struct option_blacklist_info yuga_clm920_nc5_blacklist = { | ||
| 686 | .reserved = BIT(1) | BIT(4), | ||
| 687 | }; | ||
| 688 | |||
| 677 | static const struct usb_device_id option_ids[] = { | 689 | static const struct usb_device_id option_ids[] = { |
| 678 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, | 690 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, |
| 679 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) }, | 691 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) }, |
| @@ -1178,6 +1190,9 @@ static const struct usb_device_id option_ids[] = { | |||
| 1178 | { USB_DEVICE(QUALCOMM_VENDOR_ID, QUECTEL_PRODUCT_UC15)}, | 1190 | { USB_DEVICE(QUALCOMM_VENDOR_ID, QUECTEL_PRODUCT_UC15)}, |
| 1179 | { USB_DEVICE(QUALCOMM_VENDOR_ID, QUECTEL_PRODUCT_UC20), | 1191 | { USB_DEVICE(QUALCOMM_VENDOR_ID, QUECTEL_PRODUCT_UC20), |
| 1180 | .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, | 1192 | .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, |
| 1193 | /* Yuga products use Qualcomm vendor ID */ | ||
| 1194 | { USB_DEVICE(QUALCOMM_VENDOR_ID, YUGA_PRODUCT_CLM920_NC5), | ||
| 1195 | .driver_info = (kernel_ulong_t)&yuga_clm920_nc5_blacklist }, | ||
| 1181 | /* Quectel products using Quectel vendor ID */ | 1196 | /* Quectel products using Quectel vendor ID */ |
| 1182 | { USB_DEVICE(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC21), | 1197 | { USB_DEVICE(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC21), |
| 1183 | .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, | 1198 | .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, |
| @@ -1244,6 +1259,8 @@ static const struct usb_device_id option_ids[] = { | |||
| 1244 | .driver_info = (kernel_ulong_t)&telit_le922_blacklist_usbcfg0 }, | 1259 | .driver_info = (kernel_ulong_t)&telit_le922_blacklist_usbcfg0 }, |
| 1245 | { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910), | 1260 | { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910), |
| 1246 | .driver_info = (kernel_ulong_t)&telit_me910_blacklist }, | 1261 | .driver_info = (kernel_ulong_t)&telit_me910_blacklist }, |
| 1262 | { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910_DUAL_MODEM), | ||
| 1263 | .driver_info = (kernel_ulong_t)&telit_me910_dual_modem_blacklist }, | ||
| 1247 | { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE910), | 1264 | { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE910), |
| 1248 | .driver_info = (kernel_ulong_t)&telit_le910_blacklist }, | 1265 | .driver_info = (kernel_ulong_t)&telit_le910_blacklist }, |
| 1249 | { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE910_USBCFG4), | 1266 | { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE910_USBCFG4), |
diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c index e3892541a489..613f91add03d 100644 --- a/drivers/usb/serial/qcserial.c +++ b/drivers/usb/serial/qcserial.c | |||
| @@ -162,6 +162,8 @@ static const struct usb_device_id id_table[] = { | |||
| 162 | {DEVICE_SWI(0x1199, 0x9079)}, /* Sierra Wireless EM74xx */ | 162 | {DEVICE_SWI(0x1199, 0x9079)}, /* Sierra Wireless EM74xx */ |
| 163 | {DEVICE_SWI(0x1199, 0x907a)}, /* Sierra Wireless EM74xx QDL */ | 163 | {DEVICE_SWI(0x1199, 0x907a)}, /* Sierra Wireless EM74xx QDL */ |
| 164 | {DEVICE_SWI(0x1199, 0x907b)}, /* Sierra Wireless EM74xx */ | 164 | {DEVICE_SWI(0x1199, 0x907b)}, /* Sierra Wireless EM74xx */ |
| 165 | {DEVICE_SWI(0x1199, 0x9090)}, /* Sierra Wireless EM7565 QDL */ | ||
| 166 | {DEVICE_SWI(0x1199, 0x9091)}, /* Sierra Wireless EM7565 */ | ||
| 165 | {DEVICE_SWI(0x413c, 0x81a2)}, /* Dell Wireless 5806 Gobi(TM) 4G LTE Mobile Broadband Card */ | 167 | {DEVICE_SWI(0x413c, 0x81a2)}, /* Dell Wireless 5806 Gobi(TM) 4G LTE Mobile Broadband Card */ |
| 166 | {DEVICE_SWI(0x413c, 0x81a3)}, /* Dell Wireless 5570 HSPA+ (42Mbps) Mobile Broadband Card */ | 168 | {DEVICE_SWI(0x413c, 0x81a3)}, /* Dell Wireless 5570 HSPA+ (42Mbps) Mobile Broadband Card */ |
| 167 | {DEVICE_SWI(0x413c, 0x81a4)}, /* Dell Wireless 5570e HSPA+ (42Mbps) Mobile Broadband Card */ | 169 | {DEVICE_SWI(0x413c, 0x81a4)}, /* Dell Wireless 5570e HSPA+ (42Mbps) Mobile Broadband Card */ |
| @@ -342,6 +344,7 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id) | |||
| 342 | break; | 344 | break; |
| 343 | case 2: | 345 | case 2: |
| 344 | dev_dbg(dev, "NMEA GPS interface found\n"); | 346 | dev_dbg(dev, "NMEA GPS interface found\n"); |
| 347 | sendsetup = true; | ||
| 345 | break; | 348 | break; |
| 346 | case 3: | 349 | case 3: |
| 347 | dev_dbg(dev, "Modem port found\n"); | 350 | dev_dbg(dev, "Modem port found\n"); |
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index 2968046e7c05..f72d045ee9ef 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h | |||
| @@ -2100,6 +2100,13 @@ UNUSUAL_DEV( 0x152d, 0x0567, 0x0114, 0x0116, | |||
| 2100 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, | 2100 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, |
| 2101 | US_FL_BROKEN_FUA ), | 2101 | US_FL_BROKEN_FUA ), |
| 2102 | 2102 | ||
| 2103 | /* Reported by David Kozub <zub@linux.fjfi.cvut.cz> */ | ||
| 2104 | UNUSUAL_DEV(0x152d, 0x0578, 0x0000, 0x9999, | ||
| 2105 | "JMicron", | ||
| 2106 | "JMS567", | ||
| 2107 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, | ||
| 2108 | US_FL_BROKEN_FUA), | ||
| 2109 | |||
| 2103 | /* | 2110 | /* |
| 2104 | * Reported by Alexandre Oliva <oliva@lsd.ic.unicamp.br> | 2111 | * Reported by Alexandre Oliva <oliva@lsd.ic.unicamp.br> |
| 2105 | * JMicron responds to USN and several other SCSI ioctls with a | 2112 | * JMicron responds to USN and several other SCSI ioctls with a |
diff --git a/drivers/usb/storage/unusual_uas.h b/drivers/usb/storage/unusual_uas.h index d520374a824e..e6127fb21c12 100644 --- a/drivers/usb/storage/unusual_uas.h +++ b/drivers/usb/storage/unusual_uas.h | |||
| @@ -129,6 +129,13 @@ UNUSUAL_DEV(0x152d, 0x0567, 0x0000, 0x9999, | |||
| 129 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, | 129 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, |
| 130 | US_FL_BROKEN_FUA | US_FL_NO_REPORT_OPCODES), | 130 | US_FL_BROKEN_FUA | US_FL_NO_REPORT_OPCODES), |
| 131 | 131 | ||
| 132 | /* Reported-by: David Kozub <zub@linux.fjfi.cvut.cz> */ | ||
| 133 | UNUSUAL_DEV(0x152d, 0x0578, 0x0000, 0x9999, | ||
| 134 | "JMicron", | ||
| 135 | "JMS567", | ||
| 136 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, | ||
| 137 | US_FL_BROKEN_FUA), | ||
| 138 | |||
| 132 | /* Reported-by: Hans de Goede <hdegoede@redhat.com> */ | 139 | /* Reported-by: Hans de Goede <hdegoede@redhat.com> */ |
| 133 | UNUSUAL_DEV(0x2109, 0x0711, 0x0000, 0x9999, | 140 | UNUSUAL_DEV(0x2109, 0x0711, 0x0000, 0x9999, |
| 134 | "VIA", | 141 | "VIA", |
diff --git a/drivers/usb/usbip/stub_dev.c b/drivers/usb/usbip/stub_dev.c index a3df8ee82faf..e31a6f204397 100644 --- a/drivers/usb/usbip/stub_dev.c +++ b/drivers/usb/usbip/stub_dev.c | |||
| @@ -149,8 +149,7 @@ static void stub_shutdown_connection(struct usbip_device *ud) | |||
| 149 | * step 1? | 149 | * step 1? |
| 150 | */ | 150 | */ |
| 151 | if (ud->tcp_socket) { | 151 | if (ud->tcp_socket) { |
| 152 | dev_dbg(&sdev->udev->dev, "shutdown tcp_socket %p\n", | 152 | dev_dbg(&sdev->udev->dev, "shutdown sockfd %d\n", ud->sockfd); |
| 153 | ud->tcp_socket); | ||
| 154 | kernel_sock_shutdown(ud->tcp_socket, SHUT_RDWR); | 153 | kernel_sock_shutdown(ud->tcp_socket, SHUT_RDWR); |
| 155 | } | 154 | } |
| 156 | 155 | ||
diff --git a/drivers/usb/usbip/stub_main.c b/drivers/usb/usbip/stub_main.c index 4f48b306713f..c31c8402a0c5 100644 --- a/drivers/usb/usbip/stub_main.c +++ b/drivers/usb/usbip/stub_main.c | |||
| @@ -237,11 +237,12 @@ void stub_device_cleanup_urbs(struct stub_device *sdev) | |||
| 237 | struct stub_priv *priv; | 237 | struct stub_priv *priv; |
| 238 | struct urb *urb; | 238 | struct urb *urb; |
| 239 | 239 | ||
| 240 | dev_dbg(&sdev->udev->dev, "free sdev %p\n", sdev); | 240 | dev_dbg(&sdev->udev->dev, "Stub device cleaning up urbs\n"); |
| 241 | 241 | ||
| 242 | while ((priv = stub_priv_pop(sdev))) { | 242 | while ((priv = stub_priv_pop(sdev))) { |
| 243 | urb = priv->urb; | 243 | urb = priv->urb; |
| 244 | dev_dbg(&sdev->udev->dev, "free urb %p\n", urb); | 244 | dev_dbg(&sdev->udev->dev, "free urb seqnum %lu\n", |
| 245 | priv->seqnum); | ||
| 245 | usb_kill_urb(urb); | 246 | usb_kill_urb(urb); |
| 246 | 247 | ||
| 247 | kmem_cache_free(stub_priv_cache, priv); | 248 | kmem_cache_free(stub_priv_cache, priv); |
diff --git a/drivers/usb/usbip/stub_rx.c b/drivers/usb/usbip/stub_rx.c index 536e037f541f..6c5a59313999 100644 --- a/drivers/usb/usbip/stub_rx.c +++ b/drivers/usb/usbip/stub_rx.c | |||
| @@ -211,9 +211,6 @@ static int stub_recv_cmd_unlink(struct stub_device *sdev, | |||
| 211 | if (priv->seqnum != pdu->u.cmd_unlink.seqnum) | 211 | if (priv->seqnum != pdu->u.cmd_unlink.seqnum) |
| 212 | continue; | 212 | continue; |
| 213 | 213 | ||
| 214 | dev_info(&priv->urb->dev->dev, "unlink urb %p\n", | ||
| 215 | priv->urb); | ||
| 216 | |||
| 217 | /* | 214 | /* |
| 218 | * This matched urb is not completed yet (i.e., be in | 215 | * This matched urb is not completed yet (i.e., be in |
| 219 | * flight in usb hcd hardware/driver). Now we are | 216 | * flight in usb hcd hardware/driver). Now we are |
| @@ -252,8 +249,8 @@ static int stub_recv_cmd_unlink(struct stub_device *sdev, | |||
| 252 | ret = usb_unlink_urb(priv->urb); | 249 | ret = usb_unlink_urb(priv->urb); |
| 253 | if (ret != -EINPROGRESS) | 250 | if (ret != -EINPROGRESS) |
| 254 | dev_err(&priv->urb->dev->dev, | 251 | dev_err(&priv->urb->dev->dev, |
| 255 | "failed to unlink a urb %p, ret %d\n", | 252 | "failed to unlink a urb # %lu, ret %d\n", |
| 256 | priv->urb, ret); | 253 | priv->seqnum, ret); |
| 257 | 254 | ||
| 258 | return 0; | 255 | return 0; |
| 259 | } | 256 | } |
| @@ -322,23 +319,26 @@ static struct stub_priv *stub_priv_alloc(struct stub_device *sdev, | |||
| 322 | return priv; | 319 | return priv; |
| 323 | } | 320 | } |
| 324 | 321 | ||
| 325 | static int get_pipe(struct stub_device *sdev, int epnum, int dir) | 322 | static int get_pipe(struct stub_device *sdev, struct usbip_header *pdu) |
| 326 | { | 323 | { |
| 327 | struct usb_device *udev = sdev->udev; | 324 | struct usb_device *udev = sdev->udev; |
| 328 | struct usb_host_endpoint *ep; | 325 | struct usb_host_endpoint *ep; |
| 329 | struct usb_endpoint_descriptor *epd = NULL; | 326 | struct usb_endpoint_descriptor *epd = NULL; |
| 327 | int epnum = pdu->base.ep; | ||
| 328 | int dir = pdu->base.direction; | ||
| 329 | |||
| 330 | if (epnum < 0 || epnum > 15) | ||
| 331 | goto err_ret; | ||
| 330 | 332 | ||
| 331 | if (dir == USBIP_DIR_IN) | 333 | if (dir == USBIP_DIR_IN) |
| 332 | ep = udev->ep_in[epnum & 0x7f]; | 334 | ep = udev->ep_in[epnum & 0x7f]; |
| 333 | else | 335 | else |
| 334 | ep = udev->ep_out[epnum & 0x7f]; | 336 | ep = udev->ep_out[epnum & 0x7f]; |
| 335 | if (!ep) { | 337 | if (!ep) |
| 336 | dev_err(&sdev->udev->dev, "no such endpoint?, %d\n", | 338 | goto err_ret; |
| 337 | epnum); | ||
| 338 | BUG(); | ||
| 339 | } | ||
| 340 | 339 | ||
| 341 | epd = &ep->desc; | 340 | epd = &ep->desc; |
| 341 | |||
| 342 | if (usb_endpoint_xfer_control(epd)) { | 342 | if (usb_endpoint_xfer_control(epd)) { |
| 343 | if (dir == USBIP_DIR_OUT) | 343 | if (dir == USBIP_DIR_OUT) |
| 344 | return usb_sndctrlpipe(udev, epnum); | 344 | return usb_sndctrlpipe(udev, epnum); |
| @@ -361,15 +361,31 @@ static int get_pipe(struct stub_device *sdev, int epnum, int dir) | |||
| 361 | } | 361 | } |
| 362 | 362 | ||
| 363 | if (usb_endpoint_xfer_isoc(epd)) { | 363 | if (usb_endpoint_xfer_isoc(epd)) { |
| 364 | /* validate packet size and number of packets */ | ||
| 365 | unsigned int maxp, packets, bytes; | ||
| 366 | |||
| 367 | maxp = usb_endpoint_maxp(epd); | ||
| 368 | maxp *= usb_endpoint_maxp_mult(epd); | ||
| 369 | bytes = pdu->u.cmd_submit.transfer_buffer_length; | ||
| 370 | packets = DIV_ROUND_UP(bytes, maxp); | ||
| 371 | |||
| 372 | if (pdu->u.cmd_submit.number_of_packets < 0 || | ||
| 373 | pdu->u.cmd_submit.number_of_packets > packets) { | ||
| 374 | dev_err(&sdev->udev->dev, | ||
| 375 | "CMD_SUBMIT: isoc invalid num packets %d\n", | ||
| 376 | pdu->u.cmd_submit.number_of_packets); | ||
| 377 | return -1; | ||
| 378 | } | ||
| 364 | if (dir == USBIP_DIR_OUT) | 379 | if (dir == USBIP_DIR_OUT) |
| 365 | return usb_sndisocpipe(udev, epnum); | 380 | return usb_sndisocpipe(udev, epnum); |
| 366 | else | 381 | else |
| 367 | return usb_rcvisocpipe(udev, epnum); | 382 | return usb_rcvisocpipe(udev, epnum); |
| 368 | } | 383 | } |
| 369 | 384 | ||
| 385 | err_ret: | ||
| 370 | /* NOT REACHED */ | 386 | /* NOT REACHED */ |
| 371 | dev_err(&sdev->udev->dev, "get pipe, epnum %d\n", epnum); | 387 | dev_err(&sdev->udev->dev, "CMD_SUBMIT: invalid epnum %d\n", epnum); |
| 372 | return 0; | 388 | return -1; |
| 373 | } | 389 | } |
| 374 | 390 | ||
| 375 | static void masking_bogus_flags(struct urb *urb) | 391 | static void masking_bogus_flags(struct urb *urb) |
| @@ -433,7 +449,10 @@ static void stub_recv_cmd_submit(struct stub_device *sdev, | |||
| 433 | struct stub_priv *priv; | 449 | struct stub_priv *priv; |
| 434 | struct usbip_device *ud = &sdev->ud; | 450 | struct usbip_device *ud = &sdev->ud; |
| 435 | struct usb_device *udev = sdev->udev; | 451 | struct usb_device *udev = sdev->udev; |
| 436 | int pipe = get_pipe(sdev, pdu->base.ep, pdu->base.direction); | 452 | int pipe = get_pipe(sdev, pdu); |
| 453 | |||
| 454 | if (pipe == -1) | ||
| 455 | return; | ||
| 437 | 456 | ||
| 438 | priv = stub_priv_alloc(sdev, pdu); | 457 | priv = stub_priv_alloc(sdev, pdu); |
| 439 | if (!priv) | 458 | if (!priv) |
diff --git a/drivers/usb/usbip/stub_tx.c b/drivers/usb/usbip/stub_tx.c index b18bce96c212..f0ec41a50cbc 100644 --- a/drivers/usb/usbip/stub_tx.c +++ b/drivers/usb/usbip/stub_tx.c | |||
| @@ -88,7 +88,7 @@ void stub_complete(struct urb *urb) | |||
| 88 | /* link a urb to the queue of tx. */ | 88 | /* link a urb to the queue of tx. */ |
| 89 | spin_lock_irqsave(&sdev->priv_lock, flags); | 89 | spin_lock_irqsave(&sdev->priv_lock, flags); |
| 90 | if (sdev->ud.tcp_socket == NULL) { | 90 | if (sdev->ud.tcp_socket == NULL) { |
| 91 | usbip_dbg_stub_tx("ignore urb for closed connection %p", urb); | 91 | usbip_dbg_stub_tx("ignore urb for closed connection\n"); |
| 92 | /* It will be freed in stub_device_cleanup_urbs(). */ | 92 | /* It will be freed in stub_device_cleanup_urbs(). */ |
| 93 | } else if (priv->unlinking) { | 93 | } else if (priv->unlinking) { |
| 94 | stub_enqueue_ret_unlink(sdev, priv->seqnum, urb->status); | 94 | stub_enqueue_ret_unlink(sdev, priv->seqnum, urb->status); |
| @@ -167,6 +167,13 @@ static int stub_send_ret_submit(struct stub_device *sdev) | |||
| 167 | memset(&pdu_header, 0, sizeof(pdu_header)); | 167 | memset(&pdu_header, 0, sizeof(pdu_header)); |
| 168 | memset(&msg, 0, sizeof(msg)); | 168 | memset(&msg, 0, sizeof(msg)); |
| 169 | 169 | ||
| 170 | if (urb->actual_length > 0 && !urb->transfer_buffer) { | ||
| 171 | dev_err(&sdev->udev->dev, | ||
| 172 | "urb: actual_length %d transfer_buffer null\n", | ||
| 173 | urb->actual_length); | ||
| 174 | return -1; | ||
| 175 | } | ||
| 176 | |||
| 170 | if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) | 177 | if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) |
| 171 | iovnum = 2 + urb->number_of_packets; | 178 | iovnum = 2 + urb->number_of_packets; |
| 172 | else | 179 | else |
| @@ -183,8 +190,8 @@ static int stub_send_ret_submit(struct stub_device *sdev) | |||
| 183 | 190 | ||
| 184 | /* 1. setup usbip_header */ | 191 | /* 1. setup usbip_header */ |
| 185 | setup_ret_submit_pdu(&pdu_header, urb); | 192 | setup_ret_submit_pdu(&pdu_header, urb); |
| 186 | usbip_dbg_stub_tx("setup txdata seqnum: %d urb: %p\n", | 193 | usbip_dbg_stub_tx("setup txdata seqnum: %d\n", |
| 187 | pdu_header.base.seqnum, urb); | 194 | pdu_header.base.seqnum); |
| 188 | usbip_header_correct_endian(&pdu_header, 1); | 195 | usbip_header_correct_endian(&pdu_header, 1); |
| 189 | 196 | ||
| 190 | iov[iovnum].iov_base = &pdu_header; | 197 | iov[iovnum].iov_base = &pdu_header; |
diff --git a/drivers/usb/usbip/usbip_common.c b/drivers/usb/usbip/usbip_common.c index f7978933b402..7b219d9109b4 100644 --- a/drivers/usb/usbip/usbip_common.c +++ b/drivers/usb/usbip/usbip_common.c | |||
| @@ -317,26 +317,20 @@ int usbip_recv(struct socket *sock, void *buf, int size) | |||
| 317 | struct msghdr msg = {.msg_flags = MSG_NOSIGNAL}; | 317 | struct msghdr msg = {.msg_flags = MSG_NOSIGNAL}; |
| 318 | int total = 0; | 318 | int total = 0; |
| 319 | 319 | ||
| 320 | if (!sock || !buf || !size) | ||
| 321 | return -EINVAL; | ||
| 322 | |||
| 320 | iov_iter_kvec(&msg.msg_iter, READ|ITER_KVEC, &iov, 1, size); | 323 | iov_iter_kvec(&msg.msg_iter, READ|ITER_KVEC, &iov, 1, size); |
| 321 | 324 | ||
| 322 | usbip_dbg_xmit("enter\n"); | 325 | usbip_dbg_xmit("enter\n"); |
| 323 | 326 | ||
| 324 | if (!sock || !buf || !size) { | ||
| 325 | pr_err("invalid arg, sock %p buff %p size %d\n", sock, buf, | ||
| 326 | size); | ||
| 327 | return -EINVAL; | ||
| 328 | } | ||
| 329 | |||
| 330 | do { | 327 | do { |
| 331 | int sz = msg_data_left(&msg); | 328 | msg_data_left(&msg); |
| 332 | sock->sk->sk_allocation = GFP_NOIO; | 329 | sock->sk->sk_allocation = GFP_NOIO; |
| 333 | 330 | ||
| 334 | result = sock_recvmsg(sock, &msg, MSG_WAITALL); | 331 | result = sock_recvmsg(sock, &msg, MSG_WAITALL); |
| 335 | if (result <= 0) { | 332 | if (result <= 0) |
| 336 | pr_debug("receive sock %p buf %p size %u ret %d total %d\n", | ||
| 337 | sock, buf + total, sz, result, total); | ||
| 338 | goto err; | 333 | goto err; |
| 339 | } | ||
| 340 | 334 | ||
| 341 | total += result; | 335 | total += result; |
| 342 | } while (msg_data_left(&msg)); | 336 | } while (msg_data_left(&msg)); |
diff --git a/drivers/usb/usbip/usbip_common.h b/drivers/usb/usbip/usbip_common.h index e5de35c8c505..473fb8a87289 100644 --- a/drivers/usb/usbip/usbip_common.h +++ b/drivers/usb/usbip/usbip_common.h | |||
| @@ -256,6 +256,7 @@ struct usbip_device { | |||
| 256 | /* lock for status */ | 256 | /* lock for status */ |
| 257 | spinlock_t lock; | 257 | spinlock_t lock; |
| 258 | 258 | ||
| 259 | int sockfd; | ||
| 259 | struct socket *tcp_socket; | 260 | struct socket *tcp_socket; |
| 260 | 261 | ||
| 261 | struct task_struct *tcp_rx; | 262 | struct task_struct *tcp_rx; |
diff --git a/drivers/usb/usbip/vhci_hcd.c b/drivers/usb/usbip/vhci_hcd.c index 6b3278c4b72a..c3e1008aa491 100644 --- a/drivers/usb/usbip/vhci_hcd.c +++ b/drivers/usb/usbip/vhci_hcd.c | |||
| @@ -656,9 +656,6 @@ static int vhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flag | |||
| 656 | struct vhci_device *vdev; | 656 | struct vhci_device *vdev; |
| 657 | unsigned long flags; | 657 | unsigned long flags; |
| 658 | 658 | ||
| 659 | usbip_dbg_vhci_hc("enter, usb_hcd %p urb %p mem_flags %d\n", | ||
| 660 | hcd, urb, mem_flags); | ||
| 661 | |||
| 662 | if (portnum > VHCI_HC_PORTS) { | 659 | if (portnum > VHCI_HC_PORTS) { |
| 663 | pr_err("invalid port number %d\n", portnum); | 660 | pr_err("invalid port number %d\n", portnum); |
| 664 | return -ENODEV; | 661 | return -ENODEV; |
| @@ -822,8 +819,6 @@ static int vhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) | |||
| 822 | struct vhci_device *vdev; | 819 | struct vhci_device *vdev; |
| 823 | unsigned long flags; | 820 | unsigned long flags; |
| 824 | 821 | ||
| 825 | pr_info("dequeue a urb %p\n", urb); | ||
| 826 | |||
| 827 | spin_lock_irqsave(&vhci->lock, flags); | 822 | spin_lock_irqsave(&vhci->lock, flags); |
| 828 | 823 | ||
| 829 | priv = urb->hcpriv; | 824 | priv = urb->hcpriv; |
| @@ -851,7 +846,6 @@ static int vhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) | |||
| 851 | /* tcp connection is closed */ | 846 | /* tcp connection is closed */ |
| 852 | spin_lock(&vdev->priv_lock); | 847 | spin_lock(&vdev->priv_lock); |
| 853 | 848 | ||
| 854 | pr_info("device %p seems to be disconnected\n", vdev); | ||
| 855 | list_del(&priv->list); | 849 | list_del(&priv->list); |
| 856 | kfree(priv); | 850 | kfree(priv); |
| 857 | urb->hcpriv = NULL; | 851 | urb->hcpriv = NULL; |
| @@ -863,8 +857,6 @@ static int vhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) | |||
| 863 | * vhci_rx will receive RET_UNLINK and give back the URB. | 857 | * vhci_rx will receive RET_UNLINK and give back the URB. |
| 864 | * Otherwise, we give back it here. | 858 | * Otherwise, we give back it here. |
| 865 | */ | 859 | */ |
| 866 | pr_info("gives back urb %p\n", urb); | ||
| 867 | |||
| 868 | usb_hcd_unlink_urb_from_ep(hcd, urb); | 860 | usb_hcd_unlink_urb_from_ep(hcd, urb); |
| 869 | 861 | ||
| 870 | spin_unlock_irqrestore(&vhci->lock, flags); | 862 | spin_unlock_irqrestore(&vhci->lock, flags); |
| @@ -892,8 +884,6 @@ static int vhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) | |||
| 892 | 884 | ||
| 893 | unlink->unlink_seqnum = priv->seqnum; | 885 | unlink->unlink_seqnum = priv->seqnum; |
| 894 | 886 | ||
| 895 | pr_info("device %p seems to be still connected\n", vdev); | ||
| 896 | |||
| 897 | /* send cmd_unlink and try to cancel the pending URB in the | 887 | /* send cmd_unlink and try to cancel the pending URB in the |
| 898 | * peer */ | 888 | * peer */ |
| 899 | list_add_tail(&unlink->list, &vdev->unlink_tx); | 889 | list_add_tail(&unlink->list, &vdev->unlink_tx); |
| @@ -975,7 +965,7 @@ static void vhci_shutdown_connection(struct usbip_device *ud) | |||
| 975 | 965 | ||
| 976 | /* need this? see stub_dev.c */ | 966 | /* need this? see stub_dev.c */ |
| 977 | if (ud->tcp_socket) { | 967 | if (ud->tcp_socket) { |
| 978 | pr_debug("shutdown tcp_socket %p\n", ud->tcp_socket); | 968 | pr_debug("shutdown tcp_socket %d\n", ud->sockfd); |
| 979 | kernel_sock_shutdown(ud->tcp_socket, SHUT_RDWR); | 969 | kernel_sock_shutdown(ud->tcp_socket, SHUT_RDWR); |
| 980 | } | 970 | } |
| 981 | 971 | ||
diff --git a/drivers/usb/usbip/vhci_rx.c b/drivers/usb/usbip/vhci_rx.c index 90577e8b2282..112ebb90d8c9 100644 --- a/drivers/usb/usbip/vhci_rx.c +++ b/drivers/usb/usbip/vhci_rx.c | |||
| @@ -23,24 +23,23 @@ struct urb *pickup_urb_and_free_priv(struct vhci_device *vdev, __u32 seqnum) | |||
| 23 | urb = priv->urb; | 23 | urb = priv->urb; |
| 24 | status = urb->status; | 24 | status = urb->status; |
| 25 | 25 | ||
| 26 | usbip_dbg_vhci_rx("find urb %p vurb %p seqnum %u\n", | 26 | usbip_dbg_vhci_rx("find urb seqnum %u\n", seqnum); |
| 27 | urb, priv, seqnum); | ||
| 28 | 27 | ||
| 29 | switch (status) { | 28 | switch (status) { |
| 30 | case -ENOENT: | 29 | case -ENOENT: |
| 31 | /* fall through */ | 30 | /* fall through */ |
| 32 | case -ECONNRESET: | 31 | case -ECONNRESET: |
| 33 | dev_info(&urb->dev->dev, | 32 | dev_dbg(&urb->dev->dev, |
| 34 | "urb %p was unlinked %ssynchronuously.\n", urb, | 33 | "urb seq# %u was unlinked %ssynchronuously\n", |
| 35 | status == -ENOENT ? "" : "a"); | 34 | seqnum, status == -ENOENT ? "" : "a"); |
| 36 | break; | 35 | break; |
| 37 | case -EINPROGRESS: | 36 | case -EINPROGRESS: |
| 38 | /* no info output */ | 37 | /* no info output */ |
| 39 | break; | 38 | break; |
| 40 | default: | 39 | default: |
| 41 | dev_info(&urb->dev->dev, | 40 | dev_dbg(&urb->dev->dev, |
| 42 | "urb %p may be in a error, status %d\n", urb, | 41 | "urb seq# %u may be in a error, status %d\n", |
| 43 | status); | 42 | seqnum, status); |
| 44 | } | 43 | } |
| 45 | 44 | ||
| 46 | list_del(&priv->list); | 45 | list_del(&priv->list); |
| @@ -67,8 +66,8 @@ static void vhci_recv_ret_submit(struct vhci_device *vdev, | |||
| 67 | spin_unlock_irqrestore(&vdev->priv_lock, flags); | 66 | spin_unlock_irqrestore(&vdev->priv_lock, flags); |
| 68 | 67 | ||
| 69 | if (!urb) { | 68 | if (!urb) { |
| 70 | pr_err("cannot find a urb of seqnum %u\n", pdu->base.seqnum); | 69 | pr_err("cannot find a urb of seqnum %u max seqnum %d\n", |
| 71 | pr_info("max seqnum %d\n", | 70 | pdu->base.seqnum, |
| 72 | atomic_read(&vhci_hcd->seqnum)); | 71 | atomic_read(&vhci_hcd->seqnum)); |
| 73 | usbip_event_add(ud, VDEV_EVENT_ERROR_TCP); | 72 | usbip_event_add(ud, VDEV_EVENT_ERROR_TCP); |
| 74 | return; | 73 | return; |
| @@ -91,7 +90,7 @@ static void vhci_recv_ret_submit(struct vhci_device *vdev, | |||
| 91 | if (usbip_dbg_flag_vhci_rx) | 90 | if (usbip_dbg_flag_vhci_rx) |
| 92 | usbip_dump_urb(urb); | 91 | usbip_dump_urb(urb); |
| 93 | 92 | ||
| 94 | usbip_dbg_vhci_rx("now giveback urb %p\n", urb); | 93 | usbip_dbg_vhci_rx("now giveback urb %u\n", pdu->base.seqnum); |
| 95 | 94 | ||
| 96 | spin_lock_irqsave(&vhci->lock, flags); | 95 | spin_lock_irqsave(&vhci->lock, flags); |
| 97 | usb_hcd_unlink_urb_from_ep(vhci_hcd_to_hcd(vhci_hcd), urb); | 96 | usb_hcd_unlink_urb_from_ep(vhci_hcd_to_hcd(vhci_hcd), urb); |
| @@ -158,7 +157,7 @@ static void vhci_recv_ret_unlink(struct vhci_device *vdev, | |||
| 158 | pr_info("the urb (seqnum %d) was already given back\n", | 157 | pr_info("the urb (seqnum %d) was already given back\n", |
| 159 | pdu->base.seqnum); | 158 | pdu->base.seqnum); |
| 160 | } else { | 159 | } else { |
| 161 | usbip_dbg_vhci_rx("now giveback urb %p\n", urb); | 160 | usbip_dbg_vhci_rx("now giveback urb %d\n", pdu->base.seqnum); |
| 162 | 161 | ||
| 163 | /* If unlink is successful, status is -ECONNRESET */ | 162 | /* If unlink is successful, status is -ECONNRESET */ |
| 164 | urb->status = pdu->u.ret_unlink.status; | 163 | urb->status = pdu->u.ret_unlink.status; |
diff --git a/drivers/usb/usbip/vhci_sysfs.c b/drivers/usb/usbip/vhci_sysfs.c index e78f7472cac4..091f76b7196d 100644 --- a/drivers/usb/usbip/vhci_sysfs.c +++ b/drivers/usb/usbip/vhci_sysfs.c | |||
| @@ -17,15 +17,20 @@ | |||
| 17 | 17 | ||
| 18 | /* | 18 | /* |
| 19 | * output example: | 19 | * output example: |
| 20 | * hub port sta spd dev socket local_busid | 20 | * hub port sta spd dev sockfd local_busid |
| 21 | * hs 0000 004 000 00000000 c5a7bb80 1-2.3 | 21 | * hs 0000 004 000 00000000 3 1-2.3 |
| 22 | * ................................................ | 22 | * ................................................ |
| 23 | * ss 0008 004 000 00000000 d8cee980 2-3.4 | 23 | * ss 0008 004 000 00000000 4 2-3.4 |
| 24 | * ................................................ | 24 | * ................................................ |
| 25 | * | 25 | * |
| 26 | * IP address can be retrieved from a socket pointer address by looking | 26 | * Output includes socket fd instead of socket pointer address to avoid |
| 27 | * up /proc/net/{tcp,tcp6}. Also, a userland program may remember a | 27 | * leaking kernel memory address in: |
| 28 | * port number and its peer IP address. | 28 | * /sys/devices/platform/vhci_hcd.0/status and in debug output. |
| 29 | * The socket pointer address is not used at the moment and it was made | ||
| 30 | * visible as a convenient way to find IP address from socket pointer | ||
| 31 | * address by looking up /proc/net/{tcp,tcp6}. As this opens a security | ||
| 32 | * hole, the change is made to use sockfd instead. | ||
| 33 | * | ||
| 29 | */ | 34 | */ |
| 30 | static void port_show_vhci(char **out, int hub, int port, struct vhci_device *vdev) | 35 | static void port_show_vhci(char **out, int hub, int port, struct vhci_device *vdev) |
| 31 | { | 36 | { |
| @@ -39,8 +44,8 @@ static void port_show_vhci(char **out, int hub, int port, struct vhci_device *vd | |||
| 39 | if (vdev->ud.status == VDEV_ST_USED) { | 44 | if (vdev->ud.status == VDEV_ST_USED) { |
| 40 | *out += sprintf(*out, "%03u %08x ", | 45 | *out += sprintf(*out, "%03u %08x ", |
| 41 | vdev->speed, vdev->devid); | 46 | vdev->speed, vdev->devid); |
| 42 | *out += sprintf(*out, "%16p %s", | 47 | *out += sprintf(*out, "%u %s", |
| 43 | vdev->ud.tcp_socket, | 48 | vdev->ud.sockfd, |
| 44 | dev_name(&vdev->udev->dev)); | 49 | dev_name(&vdev->udev->dev)); |
| 45 | 50 | ||
| 46 | } else { | 51 | } else { |
| @@ -160,7 +165,8 @@ static ssize_t nports_show(struct device *dev, struct device_attribute *attr, | |||
| 160 | char *s = out; | 165 | char *s = out; |
| 161 | 166 | ||
| 162 | /* | 167 | /* |
| 163 | * Half the ports are for SPEED_HIGH and half for SPEED_SUPER, thus the * 2. | 168 | * Half the ports are for SPEED_HIGH and half for SPEED_SUPER, |
| 169 | * thus the * 2. | ||
| 164 | */ | 170 | */ |
| 165 | out += sprintf(out, "%d\n", VHCI_PORTS * vhci_num_controllers); | 171 | out += sprintf(out, "%d\n", VHCI_PORTS * vhci_num_controllers); |
| 166 | return out - s; | 172 | return out - s; |
| @@ -366,6 +372,7 @@ static ssize_t store_attach(struct device *dev, struct device_attribute *attr, | |||
| 366 | 372 | ||
| 367 | vdev->devid = devid; | 373 | vdev->devid = devid; |
| 368 | vdev->speed = speed; | 374 | vdev->speed = speed; |
| 375 | vdev->ud.sockfd = sockfd; | ||
| 369 | vdev->ud.tcp_socket = socket; | 376 | vdev->ud.tcp_socket = socket; |
| 370 | vdev->ud.status = VDEV_ST_NOTASSIGNED; | 377 | vdev->ud.status = VDEV_ST_NOTASSIGNED; |
| 371 | 378 | ||
diff --git a/drivers/usb/usbip/vhci_tx.c b/drivers/usb/usbip/vhci_tx.c index d625a2ff4b71..9aed15a358b7 100644 --- a/drivers/usb/usbip/vhci_tx.c +++ b/drivers/usb/usbip/vhci_tx.c | |||
| @@ -69,7 +69,8 @@ static int vhci_send_cmd_submit(struct vhci_device *vdev) | |||
| 69 | memset(&msg, 0, sizeof(msg)); | 69 | memset(&msg, 0, sizeof(msg)); |
| 70 | memset(&iov, 0, sizeof(iov)); | 70 | memset(&iov, 0, sizeof(iov)); |
| 71 | 71 | ||
| 72 | usbip_dbg_vhci_tx("setup txdata urb %p\n", urb); | 72 | usbip_dbg_vhci_tx("setup txdata urb seqnum %lu\n", |
| 73 | priv->seqnum); | ||
| 73 | 74 | ||
| 74 | /* 1. setup usbip_header */ | 75 | /* 1. setup usbip_header */ |
| 75 | setup_cmd_submit_pdu(&pdu_header, urb); | 76 | setup_cmd_submit_pdu(&pdu_header, urb); |
diff --git a/drivers/virtio/virtio_mmio.c b/drivers/virtio/virtio_mmio.c index a9192fe4f345..c92131edfaba 100644 --- a/drivers/virtio/virtio_mmio.c +++ b/drivers/virtio/virtio_mmio.c | |||
| @@ -522,10 +522,8 @@ static int virtio_mmio_probe(struct platform_device *pdev) | |||
| 522 | return -EBUSY; | 522 | return -EBUSY; |
| 523 | 523 | ||
| 524 | vm_dev = devm_kzalloc(&pdev->dev, sizeof(*vm_dev), GFP_KERNEL); | 524 | vm_dev = devm_kzalloc(&pdev->dev, sizeof(*vm_dev), GFP_KERNEL); |
| 525 | if (!vm_dev) { | 525 | if (!vm_dev) |
| 526 | rc = -ENOMEM; | 526 | return -ENOMEM; |
| 527 | goto free_mem; | ||
| 528 | } | ||
| 529 | 527 | ||
| 530 | vm_dev->vdev.dev.parent = &pdev->dev; | 528 | vm_dev->vdev.dev.parent = &pdev->dev; |
| 531 | vm_dev->vdev.dev.release = virtio_mmio_release_dev; | 529 | vm_dev->vdev.dev.release = virtio_mmio_release_dev; |
| @@ -535,17 +533,14 @@ static int virtio_mmio_probe(struct platform_device *pdev) | |||
| 535 | spin_lock_init(&vm_dev->lock); | 533 | spin_lock_init(&vm_dev->lock); |
| 536 | 534 | ||
| 537 | vm_dev->base = devm_ioremap(&pdev->dev, mem->start, resource_size(mem)); | 535 | vm_dev->base = devm_ioremap(&pdev->dev, mem->start, resource_size(mem)); |
| 538 | if (vm_dev->base == NULL) { | 536 | if (vm_dev->base == NULL) |
| 539 | rc = -EFAULT; | 537 | return -EFAULT; |
| 540 | goto free_vmdev; | ||
| 541 | } | ||
| 542 | 538 | ||
| 543 | /* Check magic value */ | 539 | /* Check magic value */ |
| 544 | magic = readl(vm_dev->base + VIRTIO_MMIO_MAGIC_VALUE); | 540 | magic = readl(vm_dev->base + VIRTIO_MMIO_MAGIC_VALUE); |
| 545 | if (magic != ('v' | 'i' << 8 | 'r' << 16 | 't' << 24)) { | 541 | if (magic != ('v' | 'i' << 8 | 'r' << 16 | 't' << 24)) { |
| 546 | dev_warn(&pdev->dev, "Wrong magic value 0x%08lx!\n", magic); | 542 | dev_warn(&pdev->dev, "Wrong magic value 0x%08lx!\n", magic); |
| 547 | rc = -ENODEV; | 543 | return -ENODEV; |
| 548 | goto unmap; | ||
| 549 | } | 544 | } |
| 550 | 545 | ||
| 551 | /* Check device version */ | 546 | /* Check device version */ |
| @@ -553,8 +548,7 @@ static int virtio_mmio_probe(struct platform_device *pdev) | |||
| 553 | if (vm_dev->version < 1 || vm_dev->version > 2) { | 548 | if (vm_dev->version < 1 || vm_dev->version > 2) { |
| 554 | dev_err(&pdev->dev, "Version %ld not supported!\n", | 549 | dev_err(&pdev->dev, "Version %ld not supported!\n", |
| 555 | vm_dev->version); | 550 | vm_dev->version); |
| 556 | rc = -ENXIO; | 551 | return -ENXIO; |
| 557 | goto unmap; | ||
| 558 | } | 552 | } |
| 559 | 553 | ||
| 560 | vm_dev->vdev.id.device = readl(vm_dev->base + VIRTIO_MMIO_DEVICE_ID); | 554 | vm_dev->vdev.id.device = readl(vm_dev->base + VIRTIO_MMIO_DEVICE_ID); |
| @@ -563,8 +557,7 @@ static int virtio_mmio_probe(struct platform_device *pdev) | |||
| 563 | * virtio-mmio device with an ID 0 is a (dummy) placeholder | 557 | * virtio-mmio device with an ID 0 is a (dummy) placeholder |
| 564 | * with no function. End probing now with no error reported. | 558 | * with no function. End probing now with no error reported. |
| 565 | */ | 559 | */ |
| 566 | rc = -ENODEV; | 560 | return -ENODEV; |
| 567 | goto unmap; | ||
| 568 | } | 561 | } |
| 569 | vm_dev->vdev.id.vendor = readl(vm_dev->base + VIRTIO_MMIO_VENDOR_ID); | 562 | vm_dev->vdev.id.vendor = readl(vm_dev->base + VIRTIO_MMIO_VENDOR_ID); |
| 570 | 563 | ||
| @@ -590,33 +583,15 @@ static int virtio_mmio_probe(struct platform_device *pdev) | |||
| 590 | platform_set_drvdata(pdev, vm_dev); | 583 | platform_set_drvdata(pdev, vm_dev); |
| 591 | 584 | ||
| 592 | rc = register_virtio_device(&vm_dev->vdev); | 585 | rc = register_virtio_device(&vm_dev->vdev); |
| 593 | if (rc) { | 586 | if (rc) |
| 594 | iounmap(vm_dev->base); | ||
| 595 | devm_release_mem_region(&pdev->dev, mem->start, | ||
| 596 | resource_size(mem)); | ||
| 597 | put_device(&vm_dev->vdev.dev); | 587 | put_device(&vm_dev->vdev.dev); |
| 598 | } | 588 | |
| 599 | return rc; | ||
| 600 | unmap: | ||
| 601 | iounmap(vm_dev->base); | ||
| 602 | free_mem: | ||
| 603 | devm_release_mem_region(&pdev->dev, mem->start, | ||
| 604 | resource_size(mem)); | ||
| 605 | free_vmdev: | ||
| 606 | devm_kfree(&pdev->dev, vm_dev); | ||
| 607 | return rc; | 589 | return rc; |
| 608 | } | 590 | } |
| 609 | 591 | ||
| 610 | static int virtio_mmio_remove(struct platform_device *pdev) | 592 | static int virtio_mmio_remove(struct platform_device *pdev) |
| 611 | { | 593 | { |
| 612 | struct virtio_mmio_device *vm_dev = platform_get_drvdata(pdev); | 594 | struct virtio_mmio_device *vm_dev = platform_get_drvdata(pdev); |
| 613 | struct resource *mem; | ||
| 614 | |||
| 615 | iounmap(vm_dev->base); | ||
| 616 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 617 | if (mem) | ||
| 618 | devm_release_mem_region(&pdev->dev, mem->start, | ||
| 619 | resource_size(mem)); | ||
| 620 | unregister_virtio_device(&vm_dev->vdev); | 595 | unregister_virtio_device(&vm_dev->vdev); |
| 621 | 596 | ||
| 622 | return 0; | 597 | return 0; |
diff --git a/drivers/xen/Kconfig b/drivers/xen/Kconfig index d8dd54678ab7..e5d0c28372ea 100644 --- a/drivers/xen/Kconfig +++ b/drivers/xen/Kconfig | |||
| @@ -269,7 +269,7 @@ config XEN_ACPI_HOTPLUG_CPU | |||
| 269 | 269 | ||
| 270 | config XEN_ACPI_PROCESSOR | 270 | config XEN_ACPI_PROCESSOR |
| 271 | tristate "Xen ACPI processor" | 271 | tristate "Xen ACPI processor" |
| 272 | depends on XEN && X86 && ACPI_PROCESSOR && CPU_FREQ | 272 | depends on XEN && XEN_DOM0 && X86 && ACPI_PROCESSOR && CPU_FREQ |
| 273 | default m | 273 | default m |
| 274 | help | 274 | help |
| 275 | This ACPI processor uploads Power Management information to the Xen | 275 | This ACPI processor uploads Power Management information to the Xen |
diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c index f77e499afddd..065f0b607373 100644 --- a/drivers/xen/balloon.c +++ b/drivers/xen/balloon.c | |||
| @@ -257,10 +257,25 @@ static void release_memory_resource(struct resource *resource) | |||
| 257 | kfree(resource); | 257 | kfree(resource); |
| 258 | } | 258 | } |
| 259 | 259 | ||
| 260 | /* | ||
| 261 | * Host memory not allocated to dom0. We can use this range for hotplug-based | ||
| 262 | * ballooning. | ||
| 263 | * | ||
| 264 | * It's a type-less resource. Setting IORESOURCE_MEM will make resource | ||
| 265 | * management algorithms (arch_remove_reservations()) look into guest e820, | ||
| 266 | * which we don't want. | ||
| 267 | */ | ||
| 268 | static struct resource hostmem_resource = { | ||
| 269 | .name = "Host RAM", | ||
| 270 | }; | ||
| 271 | |||
| 272 | void __attribute__((weak)) __init arch_xen_balloon_init(struct resource *res) | ||
| 273 | {} | ||
| 274 | |||
| 260 | static struct resource *additional_memory_resource(phys_addr_t size) | 275 | static struct resource *additional_memory_resource(phys_addr_t size) |
| 261 | { | 276 | { |
| 262 | struct resource *res; | 277 | struct resource *res, *res_hostmem; |
| 263 | int ret; | 278 | int ret = -ENOMEM; |
| 264 | 279 | ||
| 265 | res = kzalloc(sizeof(*res), GFP_KERNEL); | 280 | res = kzalloc(sizeof(*res), GFP_KERNEL); |
| 266 | if (!res) | 281 | if (!res) |
| @@ -269,13 +284,42 @@ static struct resource *additional_memory_resource(phys_addr_t size) | |||
| 269 | res->name = "System RAM"; | 284 | res->name = "System RAM"; |
| 270 | res->flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY; | 285 | res->flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY; |
| 271 | 286 | ||
| 272 | ret = allocate_resource(&iomem_resource, res, | 287 | res_hostmem = kzalloc(sizeof(*res), GFP_KERNEL); |
| 273 | size, 0, -1, | 288 | if (res_hostmem) { |
| 274 | PAGES_PER_SECTION * PAGE_SIZE, NULL, NULL); | 289 | /* Try to grab a range from hostmem */ |
| 275 | if (ret < 0) { | 290 | res_hostmem->name = "Host memory"; |
| 276 | pr_err("Cannot allocate new System RAM resource\n"); | 291 | ret = allocate_resource(&hostmem_resource, res_hostmem, |
| 277 | kfree(res); | 292 | size, 0, -1, |
| 278 | return NULL; | 293 | PAGES_PER_SECTION * PAGE_SIZE, NULL, NULL); |
| 294 | } | ||
| 295 | |||
| 296 | if (!ret) { | ||
| 297 | /* | ||
| 298 | * Insert this resource into iomem. Because hostmem_resource | ||
| 299 | * tracks portion of guest e820 marked as UNUSABLE noone else | ||
| 300 | * should try to use it. | ||
| 301 | */ | ||
| 302 | res->start = res_hostmem->start; | ||
| 303 | res->end = res_hostmem->end; | ||
| 304 | ret = insert_resource(&iomem_resource, res); | ||
| 305 | if (ret < 0) { | ||
| 306 | pr_err("Can't insert iomem_resource [%llx - %llx]\n", | ||
| 307 | res->start, res->end); | ||
| 308 | release_memory_resource(res_hostmem); | ||
| 309 | res_hostmem = NULL; | ||
| 310 | res->start = res->end = 0; | ||
| 311 | } | ||
| 312 | } | ||
| 313 | |||
| 314 | if (ret) { | ||
| 315 | ret = allocate_resource(&iomem_resource, res, | ||
| 316 | size, 0, -1, | ||
| 317 | PAGES_PER_SECTION * PAGE_SIZE, NULL, NULL); | ||
| 318 | if (ret < 0) { | ||
| 319 | pr_err("Cannot allocate new System RAM resource\n"); | ||
| 320 | kfree(res); | ||
| 321 | return NULL; | ||
| 322 | } | ||
| 279 | } | 323 | } |
| 280 | 324 | ||
| 281 | #ifdef CONFIG_SPARSEMEM | 325 | #ifdef CONFIG_SPARSEMEM |
| @@ -287,6 +331,7 @@ static struct resource *additional_memory_resource(phys_addr_t size) | |||
| 287 | pr_err("New System RAM resource outside addressable RAM (%lu > %lu)\n", | 331 | pr_err("New System RAM resource outside addressable RAM (%lu > %lu)\n", |
| 288 | pfn, limit); | 332 | pfn, limit); |
| 289 | release_memory_resource(res); | 333 | release_memory_resource(res); |
| 334 | release_memory_resource(res_hostmem); | ||
| 290 | return NULL; | 335 | return NULL; |
| 291 | } | 336 | } |
| 292 | } | 337 | } |
| @@ -765,6 +810,8 @@ static int __init balloon_init(void) | |||
| 765 | set_online_page_callback(&xen_online_page); | 810 | set_online_page_callback(&xen_online_page); |
| 766 | register_memory_notifier(&xen_memory_nb); | 811 | register_memory_notifier(&xen_memory_nb); |
| 767 | register_sysctl_table(xen_root); | 812 | register_sysctl_table(xen_root); |
| 813 | |||
| 814 | arch_xen_balloon_init(&hostmem_resource); | ||
| 768 | #endif | 815 | #endif |
| 769 | 816 | ||
| 770 | #ifdef CONFIG_XEN_PV | 817 | #ifdef CONFIG_XEN_PV |
