diff options
Diffstat (limited to 'drivers')
136 files changed, 1229 insertions, 902 deletions
diff --git a/drivers/acpi/acpica/Makefile b/drivers/acpi/acpica/Makefile index f919811156b1..b6cf9c9bd639 100644 --- a/drivers/acpi/acpica/Makefile +++ b/drivers/acpi/acpica/Makefile @@ -5,6 +5,7 @@ ccflags-y := -D_LINUX -DBUILDING_ACPICA ccflags-$(CONFIG_ACPI_DEBUG) += -DACPI_DEBUG_OUTPUT +CFLAGS_tbfind.o += $(call cc-disable-warning, stringop-truncation) # use acpi.o to put all files here into acpi.o modparam namespace obj-y += acpi.o diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c index ca51d1558111..cc7320f040da 100644 --- a/drivers/acpi/resource.c +++ b/drivers/acpi/resource.c @@ -475,6 +475,18 @@ static const struct dmi_system_id asus_laptop[] = { DMI_MATCH(DMI_BOARD_NAME, "B2502CBA"), }, }, + { + /* TongFang GXxHRXx/TUXEDO InfinityBook Pro Gen9 AMD */ + .matches = { + DMI_MATCH(DMI_BOARD_NAME, "GXxHRXx"), + }, + }, + { + /* TongFang GMxHGxx/TUXEDO Stellaris Slim Gen1 AMD */ + .matches = { + DMI_MATCH(DMI_BOARD_NAME, "GMxHGxx"), + }, + }, { } }; diff --git a/drivers/android/binder.c b/drivers/android/binder.c index 0fe56dcdf441..a53d7f9458ff 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -480,7 +480,7 @@ struct binder_proc { struct list_head todo; struct binder_stats stats; struct list_head delivered_death; - int max_threads; + u32 max_threads; int requested_threads; int requested_threads_started; int tmp_ref; @@ -5412,7 +5412,7 @@ static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) goto err; break; case BINDER_SET_MAX_THREADS: { - int max_threads; + u32 max_threads; if (copy_from_user(&max_threads, ubuf, sizeof(max_threads))) { diff --git a/drivers/ata/pata_legacy.c b/drivers/ata/pata_legacy.c index 4405d255e3aa..220739b309ea 100644 --- a/drivers/ata/pata_legacy.c +++ b/drivers/ata/pata_legacy.c @@ -114,8 +114,6 @@ static int legacy_port[NR_HOST] = { 0x1f0, 0x170, 0x1e8, 0x168, 0x1e0, 0x160 }; static struct legacy_probe probe_list[NR_HOST]; static struct legacy_data legacy_data[NR_HOST]; static struct ata_host *legacy_host[NR_HOST]; -static int nr_legacy_host; - static int probe_all; /* Set to check all ISA port ranges */ static int ht6560a; /* HT 6560A on primary 1, second 2, both 3 */ @@ -1239,9 +1237,11 @@ static __exit void legacy_exit(void) { int i; - for (i = 0; i < nr_legacy_host; i++) { + for (i = 0; i < NR_HOST; i++) { struct legacy_data *ld = &legacy_data[i]; - ata_host_detach(legacy_host[i]); + + if (legacy_host[i]) + ata_host_detach(legacy_host[i]); platform_device_unregister(ld->platform_dev); } } diff --git a/drivers/ata/sata_gemini.c b/drivers/ata/sata_gemini.c index 6fd54e968d10..1564472fd5d5 100644 --- a/drivers/ata/sata_gemini.c +++ b/drivers/ata/sata_gemini.c @@ -201,7 +201,10 @@ int gemini_sata_start_bridge(struct sata_gemini *sg, unsigned int bridge) pclk = sg->sata0_pclk; else pclk = sg->sata1_pclk; - clk_enable(pclk); + ret = clk_enable(pclk); + if (ret) + return ret; + msleep(10); /* Do not keep clocking a bridge that is not online */ diff --git a/drivers/block/null_blk_main.c b/drivers/block/null_blk_main.c index 6cbdd8a691d2..218658df77ae 100644 --- a/drivers/block/null_blk_main.c +++ b/drivers/block/null_blk_main.c @@ -1868,10 +1868,13 @@ static void __exit null_exit(void) if (g_queue_mode == NULL_Q_MQ && shared_tags) blk_mq_free_tag_set(&tag_set); + + mutex_destroy(&lock); } module_init(null_init); module_exit(null_exit); MODULE_AUTHOR("Jens Axboe <axboe@kernel.dk>"); +MODULE_DESCRIPTION("multi queue aware block test driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/char/ppdev.c b/drivers/char/ppdev.c index 34bb88fe0b0a..fb51430e1d5c 100644 --- a/drivers/char/ppdev.c +++ b/drivers/char/ppdev.c @@ -296,28 +296,35 @@ static int register_device(int minor, struct pp_struct *pp) if (!port) { pr_warn("%s: no associated port!\n", name); rc = -ENXIO; - goto err; + goto err_free_name; + } + + index = ida_alloc(&ida_index, GFP_KERNEL); + if (index < 0) { + pr_warn("%s: failed to get index!\n", name); + rc = index; + goto err_put_port; } - index = ida_simple_get(&ida_index, 0, 0, GFP_KERNEL); memset(&ppdev_cb, 0, sizeof(ppdev_cb)); ppdev_cb.irq_func = pp_irq; ppdev_cb.flags = (pp->flags & PP_EXCL) ? PARPORT_FLAG_EXCL : 0; ppdev_cb.private = pp; pdev = parport_register_dev_model(port, name, &ppdev_cb, index); - parport_put_port(port); if (!pdev) { pr_warn("%s: failed to register device!\n", name); rc = -ENXIO; - ida_simple_remove(&ida_index, index); - goto err; + ida_free(&ida_index, index); + goto err_put_port; } pp->pdev = pdev; pp->index = index; dev_dbg(&pdev->dev, "registered pardevice\n"); -err: +err_put_port: + parport_put_port(port); +err_free_name: kfree(name); return rc; } @@ -762,7 +769,7 @@ static int pp_release(struct inode *inode, struct file *file) if (pp->pdev) { parport_unregister_device(pp->pdev); - ida_simple_remove(&ida_index, pp->index); + ida_free(&ida_index, pp->index); pp->pdev = NULL; pr_debug(CHRDEV "%x: unregistered pardevice\n", minor); } diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 59a77587da47..56be3f97c265 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -4061,7 +4061,8 @@ void clk_unregister(struct clk *clk) if (clk->core->ops == &clk_nodrv_ops) { pr_err("%s: unregistered clock: %s\n", __func__, clk->core->name); - goto unlock; + clk_prepare_unlock(); + return; } /* * Assign empty clock ops for consumers that might still hold @@ -4092,11 +4093,10 @@ void clk_unregister(struct clk *clk) if (clk->core->protect_count) pr_warn("%s: unregistering protected clock: %s\n", __func__, clk->core->name); + clk_prepare_unlock(); kref_put(&clk->core->ref, __clk_release); free_clk(clk); -unlock: - clk_prepare_unlock(); } EXPORT_SYMBOL_GPL(clk_unregister); @@ -4258,13 +4258,11 @@ void __clk_put(struct clk *clk) clk->max_rate < clk->core->req_rate) clk_core_set_rate_nolock(clk->core, clk->core->req_rate); - owner = clk->core->owner; - kref_put(&clk->core->ref, __clk_release); - clk_prepare_unlock(); + owner = clk->core->owner; + kref_put(&clk->core->ref, __clk_release); module_put(owner); - free_clk(clk); } diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-h6.c b/drivers/clk/sunxi-ng/ccu-sun50i-h6.c index 2f00f1b7b9c0..c02f4e4a69e4 100644 --- a/drivers/clk/sunxi-ng/ccu-sun50i-h6.c +++ b/drivers/clk/sunxi-ng/ccu-sun50i-h6.c @@ -1172,12 +1172,19 @@ static const u32 usb2_clk_regs[] = { SUN50I_H6_USB3_CLK_REG, }; +static struct ccu_mux_nb sun50i_h6_cpu_nb = { + .common = &cpux_clk.common, + .cm = &cpux_clk.mux, + .delay_us = 1, + .bypass_index = 0, /* index of 24 MHz oscillator */ +}; + static int sun50i_h6_ccu_probe(struct platform_device *pdev) { struct resource *res; void __iomem *reg; + int i, ret; u32 val; - int i; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); reg = devm_ioremap_resource(&pdev->dev, res); @@ -1231,7 +1238,15 @@ static int sun50i_h6_ccu_probe(struct platform_device *pdev) val |= BIT(24); writel(val, reg + SUN50I_H6_HDMI_CEC_CLK_REG); - return sunxi_ccu_probe(pdev->dev.of_node, reg, &sun50i_h6_ccu_desc); + ret = sunxi_ccu_probe(pdev->dev.of_node, reg, &sun50i_h6_ccu_desc); + if (ret) + return ret; + + /* Reparent CPU during PLL CPUX rate changes */ + ccu_mux_notifier_register(pll_cpux_clk.common.hw.clk, + &sun50i_h6_cpu_nb); + + return 0; } static const struct of_device_id sun50i_h6_ccu_ids[] = { diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 11b9edc713ba..c79bbd8cc125 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -1553,47 +1553,36 @@ static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif) return 0; } -static int cpufreq_offline(unsigned int cpu) +static void __cpufreq_offline(unsigned int cpu, struct cpufreq_policy *policy) { - struct cpufreq_policy *policy; int ret; - pr_debug("%s: unregistering CPU %u\n", __func__, cpu); - - policy = cpufreq_cpu_get_raw(cpu); - if (!policy) { - pr_debug("%s: No cpu_data found\n", __func__); - return 0; - } - - down_write(&policy->rwsem); if (has_target()) cpufreq_stop_governor(policy); cpumask_clear_cpu(cpu, policy->cpus); - if (policy_is_inactive(policy)) { - if (has_target()) - strncpy(policy->last_governor, policy->governor->name, - CPUFREQ_NAME_LEN); - else - policy->last_policy = policy->policy; - } else if (cpu == policy->cpu) { - /* Nominate new CPU */ - policy->cpu = cpumask_any(policy->cpus); - } - - /* Start governor again for active policy */ if (!policy_is_inactive(policy)) { + /* Nominate a new CPU if necessary. */ + if (cpu == policy->cpu) + policy->cpu = cpumask_any(policy->cpus); + + /* Start the governor again for the active policy. */ if (has_target()) { ret = cpufreq_start_governor(policy); if (ret) pr_err("%s: Failed to start governor\n", __func__); } - goto unlock; + return; } + if (has_target()) + strncpy(policy->last_governor, policy->governor->name, + CPUFREQ_NAME_LEN); + else + policy->last_policy = policy->policy; + if (cpufreq_thermal_control_enabled(cpufreq_driver)) { cpufreq_cooling_unregister(policy->cdev); policy->cdev = NULL; @@ -1611,12 +1600,31 @@ static int cpufreq_offline(unsigned int cpu) */ if (cpufreq_driver->offline) { cpufreq_driver->offline(policy); - } else if (cpufreq_driver->exit) { + return; + } + + if (cpufreq_driver->exit) cpufreq_driver->exit(policy); - policy->freq_table = NULL; + + policy->freq_table = NULL; +} + +static int cpufreq_offline(unsigned int cpu) +{ + struct cpufreq_policy *policy; + + pr_debug("%s: unregistering CPU %u\n", __func__, cpu); + + policy = cpufreq_cpu_get_raw(cpu); + if (!policy) { + pr_debug("%s: No cpu_data found\n", __func__); + return 0; } -unlock: + down_write(&policy->rwsem); + + __cpufreq_offline(cpu, policy); + up_write(&policy->rwsem); return 0; } @@ -1634,19 +1642,26 @@ static void cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif) if (!policy) return; + down_write(&policy->rwsem); + if (cpu_online(cpu)) - cpufreq_offline(cpu); + __cpufreq_offline(cpu, policy); cpumask_clear_cpu(cpu, policy->real_cpus); remove_cpu_dev_symlink(policy, dev); - if (cpumask_empty(policy->real_cpus)) { - /* We did light-weight exit earlier, do full tear down now */ - if (cpufreq_driver->offline) - cpufreq_driver->exit(policy); - - cpufreq_policy_free(policy); + if (!cpumask_empty(policy->real_cpus)) { + up_write(&policy->rwsem); + return; } + + /* We did light-weight exit earlier, do full tear down now */ + if (cpufreq_driver->offline && cpufreq_driver->exit) + cpufreq_driver->exit(policy); + + up_write(&policy->rwsem); + + cpufreq_policy_free(policy); } /** diff --git a/drivers/crypto/bcm/spu2.c b/drivers/crypto/bcm/spu2.c index 2add51024575..a8d4cbc8d3f9 100644 --- a/drivers/crypto/bcm/spu2.c +++ b/drivers/crypto/bcm/spu2.c @@ -495,7 +495,7 @@ static void spu2_dump_omd(u8 *omd, u16 hash_key_len, u16 ciph_key_len, if (hash_iv_len) { packet_log(" Hash IV Length %u bytes\n", hash_iv_len); packet_dump(" hash IV: ", ptr, hash_iv_len); - ptr += ciph_key_len; + ptr += hash_iv_len; } if (ciph_iv_len) { diff --git a/drivers/crypto/ccp/sp-platform.c b/drivers/crypto/ccp/sp-platform.c index 831aac1393a2..d7a226b9d622 100644 --- a/drivers/crypto/ccp/sp-platform.c +++ b/drivers/crypto/ccp/sp-platform.c @@ -39,44 +39,38 @@ static const struct sp_dev_vdata dev_vdata[] = { }, }; -#ifdef CONFIG_ACPI static const struct acpi_device_id sp_acpi_match[] = { { "AMDI0C00", (kernel_ulong_t)&dev_vdata[0] }, { }, }; MODULE_DEVICE_TABLE(acpi, sp_acpi_match); -#endif -#ifdef CONFIG_OF static const struct of_device_id sp_of_match[] = { { .compatible = "amd,ccp-seattle-v1a", .data = (const void *)&dev_vdata[0] }, { }, }; MODULE_DEVICE_TABLE(of, sp_of_match); -#endif static struct sp_dev_vdata *sp_get_of_version(struct platform_device *pdev) { -#ifdef CONFIG_OF const struct of_device_id *match; match = of_match_node(sp_of_match, pdev->dev.of_node); if (match && match->data) return (struct sp_dev_vdata *)match->data; -#endif + return NULL; } static struct sp_dev_vdata *sp_get_acpi_version(struct platform_device *pdev) { -#ifdef CONFIG_ACPI const struct acpi_device_id *match; match = acpi_match_device(sp_acpi_match, &pdev->dev); if (match && match->driver_data) return (struct sp_dev_vdata *)match->driver_data; -#endif + return NULL; } @@ -222,12 +216,8 @@ static int sp_platform_resume(struct platform_device *pdev) static struct platform_driver sp_platform_driver = { .driver = { .name = "ccp", -#ifdef CONFIG_ACPI .acpi_match_table = sp_acpi_match, -#endif -#ifdef CONFIG_OF .of_match_table = sp_of_match, -#endif }, .probe = sp_platform_probe, .remove = sp_platform_remove, diff --git a/drivers/crypto/qat/qat_common/adf_aer.c b/drivers/crypto/qat/qat_common/adf_aer.c index a2989f0188ca..a08c4828a035 100644 --- a/drivers/crypto/qat/qat_common/adf_aer.c +++ b/drivers/crypto/qat/qat_common/adf_aer.c @@ -139,8 +139,7 @@ static void adf_device_reset_worker(struct work_struct *work) if (adf_dev_init(accel_dev) || adf_dev_start(accel_dev)) { /* The device hanged and we can't restart it so stop here */ dev_err(&GET_DEV(accel_dev), "Restart device failed\n"); - if (reset_data->mode == ADF_DEV_RESET_ASYNC || - completion_done(&reset_data->compl)) + if (reset_data->mode == ADF_DEV_RESET_ASYNC) kfree(reset_data); WARN(1, "QAT: device restart failed. Device is unusable\n"); return; @@ -148,16 +147,8 @@ static void adf_device_reset_worker(struct work_struct *work) adf_dev_restarted_notify(accel_dev); clear_bit(ADF_STATUS_RESTARTING, &accel_dev->status); - /* - * The dev is back alive. Notify the caller if in sync mode - * - * If device restart will take a more time than expected, - * the schedule_reset() function can timeout and exit. This can be - * detected by calling the completion_done() function. In this case - * the reset_data structure needs to be freed here. - */ - if (reset_data->mode == ADF_DEV_RESET_ASYNC || - completion_done(&reset_data->compl)) + /* The dev is back alive. Notify the caller if in sync mode */ + if (reset_data->mode == ADF_DEV_RESET_ASYNC) kfree(reset_data); else complete(&reset_data->compl); @@ -192,10 +183,10 @@ static int adf_dev_aer_schedule_reset(struct adf_accel_dev *accel_dev, if (!timeout) { dev_err(&GET_DEV(accel_dev), "Reset device timeout expired\n"); + cancel_work_sync(&reset_data->reset_work); ret = -EFAULT; - } else { - kfree(reset_data); } + kfree(reset_data); return ret; } return 0; diff --git a/drivers/dma-buf/sync_debug.c b/drivers/dma-buf/sync_debug.c index 101394f16930..237bce21d1e7 100644 --- a/drivers/dma-buf/sync_debug.c +++ b/drivers/dma-buf/sync_debug.c @@ -110,12 +110,12 @@ static void sync_print_obj(struct seq_file *s, struct sync_timeline *obj) seq_printf(s, "%s: %d\n", obj->name, obj->value); - spin_lock_irq(&obj->lock); + spin_lock(&obj->lock); /* Caller already disabled IRQ. */ list_for_each(pos, &obj->pt_list) { struct sync_pt *pt = container_of(pos, struct sync_pt, link); sync_print_fence(s, &pt->base, false); } - spin_unlock_irq(&obj->lock); + spin_unlock(&obj->lock); } static void sync_print_sync_file(struct seq_file *s, diff --git a/drivers/dma/idma64.c b/drivers/dma/idma64.c index db506e1f7ef4..0f065ba844c0 100644 --- a/drivers/dma/idma64.c +++ b/drivers/dma/idma64.c @@ -594,7 +594,9 @@ static int idma64_probe(struct idma64_chip *chip) idma64->dma.dev = chip->sysdev; - dma_set_max_seg_size(idma64->dma.dev, IDMA64C_CTLH_BLOCK_TS_MASK); + ret = dma_set_max_seg_size(idma64->dma.dev, IDMA64C_CTLH_BLOCK_TS_MASK); + if (ret) + return ret; ret = dma_async_device_register(&idma64->dma); if (ret) diff --git a/drivers/extcon/Kconfig b/drivers/extcon/Kconfig index aac507bff135..09485803280e 100644 --- a/drivers/extcon/Kconfig +++ b/drivers/extcon/Kconfig @@ -121,7 +121,8 @@ config EXTCON_MAX77843 config EXTCON_MAX8997 tristate "Maxim MAX8997 EXTCON Support" - depends on MFD_MAX8997 && IRQ_DOMAIN + depends on MFD_MAX8997 + select IRQ_DOMAIN help If you say yes here you get support for the MUIC device of Maxim MAX8997 PMIC. The MAX8997 MUIC is a USB port accessory diff --git a/drivers/firewire/nosy.c b/drivers/firewire/nosy.c index 9ee747a85ee4..8bb609085911 100644 --- a/drivers/firewire/nosy.c +++ b/drivers/firewire/nosy.c @@ -148,10 +148,12 @@ packet_buffer_get(struct client *client, char __user *data, size_t user_length) if (atomic_read(&buffer->size) == 0) return -ENODEV; - /* FIXME: Check length <= user_length. */ + length = buffer->head->length; + + if (length > user_length) + return 0; end = buffer->data + buffer->capacity; - length = buffer->head->length; if (&buffer->head->data[length] < end) { if (copy_to_user(data, buffer->head->data, length)) diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c index 6603f13f5de9..2db5448c4293 100644 --- a/drivers/firewire/ohci.c +++ b/drivers/firewire/ohci.c @@ -2053,6 +2053,8 @@ static void bus_reset_work(struct work_struct *work) ohci->generation = generation; reg_write(ohci, OHCI1394_IntEventClear, OHCI1394_busReset); + if (param_debug & OHCI_PARAM_DEBUG_BUSRESETS) + reg_write(ohci, OHCI1394_IntMaskSet, OHCI1394_busReset); if (ohci->quirks & QUIRK_RESET_PACKET) ohci->request_generation = generation; @@ -2119,12 +2121,14 @@ static irqreturn_t irq_handler(int irq, void *data) return IRQ_NONE; /* - * busReset and postedWriteErr must not be cleared yet + * busReset and postedWriteErr events must not be cleared yet * (OHCI 1.1 clauses 7.2.3.2 and 13.2.8.1) */ reg_write(ohci, OHCI1394_IntEventClear, event & ~(OHCI1394_busReset | OHCI1394_postedWriteErr)); log_irqs(ohci, event); + if (event & OHCI1394_busReset) + reg_write(ohci, OHCI1394_IntMaskClear, OHCI1394_busReset); if (event & OHCI1394_selfIDComplete) queue_work(selfid_workqueue, &ohci->bus_reset_work); diff --git a/drivers/firmware/arm_scmi/reset.c b/drivers/firmware/arm_scmi/reset.c index 6d223f345b6c..b45d3e9cee12 100644 --- a/drivers/firmware/arm_scmi/reset.c +++ b/drivers/firmware/arm_scmi/reset.c @@ -135,8 +135,12 @@ static int scmi_domain_reset(const struct scmi_handle *handle, u32 domain, struct scmi_xfer *t; struct scmi_msg_reset_domain_reset *dom; struct scmi_reset_info *pi = handle->reset_priv; - struct reset_dom_info *rdom = pi->dom_info + domain; + struct reset_dom_info *rdom; + if (domain >= pi->num_domains) + return -EINVAL; + + rdom = pi->dom_info + domain; if (rdom->async_reset) flags |= ASYNCHRONOUS_RESET; diff --git a/drivers/firmware/dmi-id.c b/drivers/firmware/dmi-id.c index ff39f64f2aae..1bb3370650cf 100644 --- a/drivers/firmware/dmi-id.c +++ b/drivers/firmware/dmi-id.c @@ -160,9 +160,14 @@ static int dmi_dev_uevent(struct device *dev, struct kobj_uevent_env *env) return 0; } +static void dmi_dev_release(struct device *dev) +{ + kfree(dev); +} + static struct class dmi_class = { .name = "dmi", - .dev_release = (void(*)(struct device *)) kfree, + .dev_release = dmi_dev_release, .dev_uevent = dmi_dev_uevent, }; diff --git a/drivers/firmware/raspberrypi.c b/drivers/firmware/raspberrypi.c index 1a690b2c1e2f..9fdebb1171e5 100644 --- a/drivers/firmware/raspberrypi.c +++ b/drivers/firmware/raspberrypi.c @@ -9,6 +9,7 @@ #include <linux/dma-mapping.h> #include <linux/kref.h> #include <linux/mailbox_client.h> +#include <linux/mailbox_controller.h> #include <linux/module.h> #include <linux/of_platform.h> #include <linux/platform_device.h> @@ -96,8 +97,8 @@ int rpi_firmware_property_list(struct rpi_firmware *fw, if (size & 3) return -EINVAL; - buf = dma_alloc_coherent(fw->cl.dev, PAGE_ALIGN(size), &bus_addr, - GFP_ATOMIC); + buf = dma_alloc_coherent(fw->chan->mbox->dev, PAGE_ALIGN(size), + &bus_addr, GFP_ATOMIC); if (!buf) return -ENOMEM; @@ -125,7 +126,7 @@ int rpi_firmware_property_list(struct rpi_firmware *fw, ret = -EINVAL; } - dma_free_coherent(fw->cl.dev, PAGE_ALIGN(size), buf, bus_addr); + dma_free_coherent(fw->chan->mbox->dev, PAGE_ALIGN(size), buf, bus_addr); return ret; } diff --git a/drivers/gpio/gpio-crystalcove.c b/drivers/gpio/gpio-crystalcove.c index 14d1f4c933b6..8b9c1833bf7d 100644 --- a/drivers/gpio/gpio-crystalcove.c +++ b/drivers/gpio/gpio-crystalcove.c @@ -91,7 +91,7 @@ static inline int to_reg(int gpio, enum ctrl_register reg_type) case 0x5e: return GPIOPANELCTL; default: - return -EOPNOTSUPP; + return -ENOTSUPP; } } diff --git a/drivers/gpio/gpio-wcove.c b/drivers/gpio/gpio-wcove.c index 444fe9e7f04a..79946c098271 100644 --- a/drivers/gpio/gpio-wcove.c +++ b/drivers/gpio/gpio-wcove.c @@ -102,7 +102,7 @@ static inline int to_reg(int gpio, enum ctrl_register reg_type) unsigned int reg; if (gpio >= WCOVE_GPIO_NUM) - return -EOPNOTSUPP; + return -ENOTSUPP; if (reg_type == CTRL_IN) reg = GPIO_IN_CTRL_BASE + gpio; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c index 9c5cbc47edf1..b6fc191c353a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c @@ -594,6 +594,9 @@ int amdgpu_ras_error_query(struct amdgpu_device *adev, if (!obj) return -EINVAL; + if (!info || info->head.block == AMDGPU_RAS_BLOCK_COUNT) + return -EINVAL; + switch (info->head.block) { case AMDGPU_RAS_BLOCK__UMC: if (adev->umc.funcs->query_ras_error_count) diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c index 7ca7a68d588e..8bb54fc0d534 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c @@ -2007,6 +2007,9 @@ static int sdma_v4_0_process_trap_irq(struct amdgpu_device *adev, DRM_DEBUG("IH: SDMA trap\n"); instance = sdma_v4_0_irq_id_to_seq(entry->client_id); + if (instance < 0) + return instance; + switch (entry->ring_id) { case 0: amdgpu_fence_process(&adev->sdma.instance[instance].ring); diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process.c b/drivers/gpu/drm/amd/amdkfd/kfd_process.c index aa0a617b8d44..662e4d973f13 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_process.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c @@ -289,6 +289,14 @@ struct kfd_process *kfd_create_process(struct file *filep) if (process) { pr_debug("Process already found\n"); } else { + /* If the process just called exec(3), it is possible that the + * cleanup of the kfd_process (following the release of the mm + * of the old process image) is still in the cleanup work queue. + * Make sure to drain any job before trying to recreate any + * resource for this process. + */ + flush_workqueue(kfd_process_wq); + process = create_process(thread); if (IS_ERR(process)) goto out; 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 3f3242783e1c..3bfc4aa328c6 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -1251,6 +1251,7 @@ static int dm_resume(void *handle) dc_stream_release(dm_new_crtc_state->stream); dm_new_crtc_state->stream = NULL; } + dm_new_crtc_state->base.color_mgmt_changed = true; } for_each_new_plane_in_state(dm->cached_state, plane, new_plane_state, i) { diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c index bbd6e01b3eca..f1b1bc8da175 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c @@ -380,6 +380,11 @@ bool cm_helper_translate_curve_to_hw_format( i += increment) { if (j == hw_points - 1) break; + if (i >= TRANSFER_FUNC_POINTS) { + DC_LOG_ERROR("Index out of bounds: i=%d, TRANSFER_FUNC_POINTS=%d\n", + i, TRANSFER_FUNC_POINTS); + return false; + } rgb_resulted[j].red = output_tf->tf_pts.red[i]; rgb_resulted[j].green = output_tf->tf_pts.green[i]; rgb_resulted[j].blue = output_tf->tf_pts.blue[i]; diff --git a/drivers/gpu/drm/arm/malidp_mw.c b/drivers/gpu/drm/arm/malidp_mw.c index 7d0e7b031e44..fa5e77ee3af8 100644 --- a/drivers/gpu/drm/arm/malidp_mw.c +++ b/drivers/gpu/drm/arm/malidp_mw.c @@ -70,7 +70,10 @@ static void malidp_mw_connector_reset(struct drm_connector *connector) __drm_atomic_helper_connector_destroy_state(connector->state); kfree(connector->state); - __drm_atomic_helper_connector_reset(connector, &mw_state->base); + connector->state = NULL; + + if (mw_state) + __drm_atomic_helper_connector_reset(connector, &mw_state->base); } static enum drm_connector_status diff --git a/drivers/gpu/drm/mediatek/mtk_drm_gem.c b/drivers/gpu/drm/mediatek/mtk_drm_gem.c index 5f87d56d2d1d..de15cf6105d9 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_gem.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_gem.c @@ -21,6 +21,9 @@ static struct mtk_drm_gem_obj *mtk_drm_gem_init(struct drm_device *dev, size = round_up(size, PAGE_SIZE); + if (size == 0) + return ERR_PTR(-EINVAL); + mtk_gem_obj = kzalloc(sizeof(*mtk_gem_obj), GFP_KERNEL); if (!mtk_gem_obj) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c index 2923b63d95fe..34b39a475e3e 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c @@ -479,9 +479,6 @@ static void dpu_encoder_phys_cmd_enable_helper( _dpu_encoder_phys_cmd_pingpong_config(phys_enc); - if (!dpu_encoder_phys_cmd_is_master(phys_enc)) - return; - ctl = phys_enc->hw_ctl; ctl->ops.get_bitmask_intf(ctl, &flush_mask, phys_enc->intf_idx); ctl->ops.update_pending_flush(ctl, flush_mask); diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index fd8b16dcf13e..83cba00f854d 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -1729,6 +1729,9 @@ static const struct panel_desc innolux_g121x1_l03 = { .unprepare = 200, .disable = 400, }, + .bus_format = MEDIA_BUS_FMT_RGB666_1X7X3_SPWG, + .bus_flags = DRM_BUS_FLAG_DE_HIGH, + .connector_type = DRM_MODE_CONNECTOR_LVDS, }; /* diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c index 874093a0b04f..da052e3a187e 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c @@ -1066,7 +1066,7 @@ static int vmw_event_fence_action_create(struct drm_file *file_priv, } event->event.base.type = DRM_VMW_EVENT_FENCE_SIGNALED; - event->event.base.length = sizeof(*event); + event->event.base.length = sizeof(event->event); event->event.user_data = user_data; ret = drm_event_reserve_init(dev, file_priv, &event->base, &event->event.base); diff --git a/drivers/gpu/host1x/bus.c b/drivers/gpu/host1x/bus.c index fcda8621ae6f..5a1bf59be734 100644 --- a/drivers/gpu/host1x/bus.c +++ b/drivers/gpu/host1x/bus.c @@ -335,11 +335,6 @@ static int host1x_device_uevent(struct device *dev, return 0; } -static int host1x_dma_configure(struct device *dev) -{ - return of_dma_configure(dev, dev->of_node, true); -} - static const struct dev_pm_ops host1x_device_pm_ops = { .suspend = pm_generic_suspend, .resume = pm_generic_resume, @@ -353,7 +348,6 @@ struct bus_type host1x_bus_type = { .name = "host1x", .match = host1x_device_match, .uevent = host1x_device_uevent, - .dma_configure = host1x_dma_configure, .pm = &host1x_device_pm_ops, }; @@ -442,8 +436,6 @@ static int host1x_device_add(struct host1x *host1x, device->dev.bus = &host1x_bus_type; device->dev.parent = host1x->dev; - of_dma_configure(&device->dev, host1x->dev->of_node, true); - device->dev.dma_parms = &device->dma_parms; dma_set_max_seg_size(&device->dev, SZ_4M); diff --git a/drivers/hid/intel-ish-hid/ipc/pci-ish.c b/drivers/hid/intel-ish-hid/ipc/pci-ish.c index f491d8b4e24c..05134ee80277 100644 --- a/drivers/hid/intel-ish-hid/ipc/pci-ish.c +++ b/drivers/hid/intel-ish-hid/ipc/pci-ish.c @@ -159,6 +159,11 @@ static int ish_probe(struct pci_dev *pdev, const struct pci_device_id *ent) /* request and enable interrupt */ ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES); + if (ret < 0) { + dev_err(dev, "ISH: Failed to allocate IRQ vectors\n"); + return ret; + } + if (!pdev->msi_enabled && !pdev->msix_enabled) irq_flag = IRQF_SHARED; diff --git a/drivers/hwtracing/intel_th/pci.c b/drivers/hwtracing/intel_th/pci.c index 6fcc20e0bc7b..486621f37bb5 100644 --- a/drivers/hwtracing/intel_th/pci.c +++ b/drivers/hwtracing/intel_th/pci.c @@ -290,6 +290,11 @@ static const struct pci_device_id intel_th_pci_id_table[] = { .driver_data = (kernel_ulong_t)&intel_th_2x, }, { + /* Meteor Lake-S CPU */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xae24), + .driver_data = (kernel_ulong_t)&intel_th_2x, + }, + { /* Raptor Lake-S */ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7a26), .driver_data = (kernel_ulong_t)&intel_th_2x, diff --git a/drivers/hwtracing/stm/core.c b/drivers/hwtracing/stm/core.c index 603b83ac5085..1cfae56c4fdb 100644 --- a/drivers/hwtracing/stm/core.c +++ b/drivers/hwtracing/stm/core.c @@ -878,8 +878,11 @@ int stm_register_device(struct device *parent, struct stm_data *stm_data, return -ENOMEM; stm->major = register_chrdev(0, stm_data->name, &stm_fops); - if (stm->major < 0) - goto err_free; + if (stm->major < 0) { + err = stm->major; + vfree(stm); + return err; + } device_initialize(&stm->dev); stm->dev.devt = MKDEV(stm->major, 0); @@ -923,10 +926,8 @@ int stm_register_device(struct device *parent, struct stm_data *stm_data, err_device: unregister_chrdev(stm->major, stm_data->name); - /* matches device_initialize() above */ + /* calls stm_device_release() */ put_device(&stm->dev); -err_free: - vfree(stm); return err; } diff --git a/drivers/iio/pressure/dps310.c b/drivers/iio/pressure/dps310.c index 2b2203eea3e9..9bb45a354d38 100644 --- a/drivers/iio/pressure/dps310.c +++ b/drivers/iio/pressure/dps310.c @@ -730,7 +730,7 @@ static int dps310_read_pressure(struct dps310_data *data, int *val, int *val2, } } -static int dps310_calculate_temp(struct dps310_data *data) +static int dps310_calculate_temp(struct dps310_data *data, int *val) { s64 c0; s64 t; @@ -746,7 +746,9 @@ static int dps310_calculate_temp(struct dps310_data *data) t = c0 + ((s64)data->temp_raw * (s64)data->c1); /* Convert to milliCelsius and scale the temperature */ - return (int)div_s64(t * 1000LL, kt); + *val = (int)div_s64(t * 1000LL, kt); + + return 0; } static int dps310_read_temp(struct dps310_data *data, int *val, int *val2, @@ -768,11 +770,10 @@ static int dps310_read_temp(struct dps310_data *data, int *val, int *val2, if (rc) return rc; - rc = dps310_calculate_temp(data); - if (rc < 0) + rc = dps310_calculate_temp(data, val); + if (rc) return rc; - *val = rc; return IIO_VAL_INT; case IIO_CHAN_INFO_OVERSAMPLING_RATIO: diff --git a/drivers/infiniband/hw/hns/hns_roce_hem.h b/drivers/infiniband/hw/hns/hns_roce_hem.h index 3bb8f78fb7b0..2bca2069135d 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hem.h +++ b/drivers/infiniband/hw/hns/hns_roce_hem.h @@ -62,16 +62,16 @@ enum { (sizeof(struct scatterlist) + sizeof(void *))) #define check_whether_bt_num_3(type, hop_num) \ - (type < HEM_TYPE_MTT && hop_num == 2) + ((type) < HEM_TYPE_MTT && (hop_num) == 2) #define check_whether_bt_num_2(type, hop_num) \ - ((type < HEM_TYPE_MTT && hop_num == 1) || \ - (type >= HEM_TYPE_MTT && hop_num == 2)) + (((type) < HEM_TYPE_MTT && (hop_num) == 1) || \ + ((type) >= HEM_TYPE_MTT && (hop_num) == 2)) #define check_whether_bt_num_1(type, hop_num) \ - ((type < HEM_TYPE_MTT && hop_num == HNS_ROCE_HOP_NUM_0) || \ - (type >= HEM_TYPE_MTT && hop_num == 1) || \ - (type >= HEM_TYPE_MTT && hop_num == HNS_ROCE_HOP_NUM_0)) + (((type) < HEM_TYPE_MTT && (hop_num) == HNS_ROCE_HOP_NUM_0) || \ + ((type) >= HEM_TYPE_MTT && (hop_num) == 1) || \ + ((type) >= HEM_TYPE_MTT && (hop_num) == HNS_ROCE_HOP_NUM_0)) enum { HNS_ROCE_HEM_PAGE_SHIFT = 12, diff --git a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c index 58ca5e9c6079..1c1cd10283ac 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c @@ -182,8 +182,12 @@ int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey) ppriv = ipoib_priv(pdev); - snprintf(intf_name, sizeof(intf_name), "%s.%04x", - ppriv->dev->name, pkey); + /* If you increase IFNAMSIZ, update snprintf below + * to allow longer names. + */ + BUILD_BUG_ON(IFNAMSIZ != 16); + snprintf(intf_name, sizeof(intf_name), "%.10s.%04x", ppriv->dev->name, + pkey); ndev = ipoib_intf_alloc(ppriv->ca, ppriv->port, intf_name); if (IS_ERR(ndev)) { diff --git a/drivers/input/misc/ims-pcu.c b/drivers/input/misc/ims-pcu.c index d8dbfc030d0f..4dfed127952d 100644 --- a/drivers/input/misc/ims-pcu.c +++ b/drivers/input/misc/ims-pcu.c @@ -42,8 +42,8 @@ struct ims_pcu_backlight { #define IMS_PCU_PART_NUMBER_LEN 15 #define IMS_PCU_SERIAL_NUMBER_LEN 8 #define IMS_PCU_DOM_LEN 8 -#define IMS_PCU_FW_VERSION_LEN (9 + 1) -#define IMS_PCU_BL_VERSION_LEN (9 + 1) +#define IMS_PCU_FW_VERSION_LEN 16 +#define IMS_PCU_BL_VERSION_LEN 16 #define IMS_PCU_BL_RESET_REASON_LEN (2 + 1) #define IMS_PCU_PCU_B_DEVICE_ID 5 diff --git a/drivers/input/misc/pm8xxx-vibrator.c b/drivers/input/misc/pm8xxx-vibrator.c index 53ad25eaf1a2..8bfe5c7b1244 100644 --- a/drivers/input/misc/pm8xxx-vibrator.c +++ b/drivers/input/misc/pm8xxx-vibrator.c @@ -14,7 +14,8 @@ #define VIB_MAX_LEVEL_mV (3100) #define VIB_MIN_LEVEL_mV (1200) -#define VIB_MAX_LEVELS (VIB_MAX_LEVEL_mV - VIB_MIN_LEVEL_mV) +#define VIB_PER_STEP_mV (100) +#define VIB_MAX_LEVELS (VIB_MAX_LEVEL_mV - VIB_MIN_LEVEL_mV + VIB_PER_STEP_mV) #define MAX_FF_SPEED 0xff @@ -118,10 +119,10 @@ static void pm8xxx_work_handler(struct work_struct *work) vib->active = true; vib->level = ((VIB_MAX_LEVELS * vib->speed) / MAX_FF_SPEED) + VIB_MIN_LEVEL_mV; - vib->level /= 100; + vib->level /= VIB_PER_STEP_mV; } else { vib->active = false; - vib->level = VIB_MIN_LEVEL_mV / 100; + vib->level = VIB_MIN_LEVEL_mV / VIB_PER_STEP_mV; } pm8xxx_vib_set(vib, vib->active); diff --git a/drivers/irqchip/irq-alpine-msi.c b/drivers/irqchip/irq-alpine-msi.c index 1819bb1d2723..aedbc4befcdf 100644 --- a/drivers/irqchip/irq-alpine-msi.c +++ b/drivers/irqchip/irq-alpine-msi.c @@ -165,7 +165,7 @@ static int alpine_msix_middle_domain_alloc(struct irq_domain *domain, return 0; err_sgi: - irq_domain_free_irqs_parent(domain, virq, i - 1); + irq_domain_free_irqs_parent(domain, virq, i); alpine_msix_free_sgi(priv, sgi, nr_irqs); return err; } diff --git a/drivers/macintosh/via-macii.c b/drivers/macintosh/via-macii.c index 6aa903529570..9344452deaa3 100644 --- a/drivers/macintosh/via-macii.c +++ b/drivers/macintosh/via-macii.c @@ -135,24 +135,19 @@ static int macii_probe(void) /* Initialize the driver */ int macii_init(void) { - unsigned long flags; int err; - local_irq_save(flags); - err = macii_init_via(); if (err) - goto out; + return err; err = request_irq(IRQ_MAC_ADB, macii_interrupt, 0, "ADB", macii_interrupt); if (err) - goto out; + return err; macii_state = idle; -out: - local_irq_restore(flags); - return err; + return 0; } /* initialize the hardware */ diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c index 843139447a96..8fc85b6251e4 100644 --- a/drivers/md/md-bitmap.c +++ b/drivers/md/md-bitmap.c @@ -1359,7 +1359,7 @@ __acquires(bitmap->lock) sector_t chunk = offset >> bitmap->chunkshift; unsigned long page = chunk >> PAGE_COUNTER_SHIFT; unsigned long pageoff = (chunk & PAGE_COUNTER_MASK) << COUNTER_BYTE_SHIFT; - sector_t csize; + sector_t csize = ((sector_t)1) << bitmap->chunkshift; int err; if (page >= bitmap->pages) { @@ -1368,6 +1368,7 @@ __acquires(bitmap->lock) * End-of-device while looking for a whole page or * user set a huge number to sysfs bitmap_set_bits. */ + *blocks = csize - (offset & (csize - 1)); return NULL; } err = md_bitmap_checkpage(bitmap, page, create, 0); @@ -1376,8 +1377,7 @@ __acquires(bitmap->lock) bitmap->bp[page].map == NULL) csize = ((sector_t)1) << (bitmap->chunkshift + PAGE_COUNTER_SHIFT); - else - csize = ((sector_t)1) << bitmap->chunkshift; + *blocks = csize - (offset & (csize - 1)); if (err < 0) diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index f3d60c4b34b8..bba5e61cc145 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -36,7 +36,6 @@ */ #include <linux/blkdev.h> -#include <linux/delay.h> #include <linux/kthread.h> #include <linux/raid/pq.h> #include <linux/async_tx.h> @@ -6299,6 +6298,9 @@ static void raid5d(struct md_thread *thread) int batch_size, released; unsigned int offset; + if (test_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags)) + break; + released = release_stripe_list(conf, conf->temp_inactive_list); if (released) clear_bit(R5_DID_ALLOC, &conf->cache_state); @@ -6335,18 +6337,7 @@ static void raid5d(struct md_thread *thread) spin_unlock_irq(&conf->device_lock); md_check_recovery(mddev); spin_lock_irq(&conf->device_lock); - - /* - * Waiting on MD_SB_CHANGE_PENDING below may deadlock - * seeing md_check_recovery() is needed to clear - * the flag when using mdmon. - */ - continue; } - - wait_event_lock_irq(mddev->sb_wait, - !test_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags), - conf->device_lock); } pr_debug("%d stripes handled\n", handled); diff --git a/drivers/media/cec/cec-adap.c b/drivers/media/cec/cec-adap.c index 4c1770b8128c..94ddaca496c9 100644 --- a/drivers/media/cec/cec-adap.c +++ b/drivers/media/cec/cec-adap.c @@ -908,8 +908,7 @@ int cec_transmit_msg_fh(struct cec_adapter *adap, struct cec_msg *msg, */ mutex_unlock(&adap->lock); wait_for_completion_killable(&data->c); - if (!data->completed) - cancel_delayed_work_sync(&data->work); + cancel_delayed_work_sync(&data->work); mutex_lock(&adap->lock); /* Cancel the transmit if it was interrupted */ diff --git a/drivers/media/cec/cec-api.c b/drivers/media/cec/cec-api.c index ed75636a6fb3..90e90234f5bd 100644 --- a/drivers/media/cec/cec-api.c +++ b/drivers/media/cec/cec-api.c @@ -652,6 +652,8 @@ static int cec_release(struct inode *inode, struct file *filp) list_del(&data->xfer_list); } mutex_unlock(&adap->lock); + + mutex_lock(&fh->lock); while (!list_empty(&fh->msgs)) { struct cec_msg_entry *entry = list_first_entry(&fh->msgs, struct cec_msg_entry, list); @@ -669,6 +671,7 @@ static int cec_release(struct inode *inode, struct file *filp) kfree(entry); } } + mutex_unlock(&fh->lock); kfree(fh); cec_put_device(devnode); diff --git a/drivers/media/dvb-frontends/lgdt3306a.c b/drivers/media/dvb-frontends/lgdt3306a.c index 0e7d97e7b0f5..a4d881c721b8 100644 --- a/drivers/media/dvb-frontends/lgdt3306a.c +++ b/drivers/media/dvb-frontends/lgdt3306a.c @@ -2199,6 +2199,11 @@ static int lgdt3306a_probe(struct i2c_client *client, struct dvb_frontend *fe; int ret; + if (!client->dev.platform_data) { + dev_err(&client->dev, "platform data is mandatory\n"); + return -EINVAL; + } + config = kmemdup(client->dev.platform_data, sizeof(struct lgdt3306a_config), GFP_KERNEL); if (config == NULL) { diff --git a/drivers/media/dvb-frontends/mxl5xx.c b/drivers/media/dvb-frontends/mxl5xx.c index 290b9eab099f..215bfa20bb26 100644 --- a/drivers/media/dvb-frontends/mxl5xx.c +++ b/drivers/media/dvb-frontends/mxl5xx.c @@ -1391,57 +1391,57 @@ static int config_ts(struct mxl *state, enum MXL_HYDRA_DEMOD_ID_E demod_id, u32 nco_count_min = 0; u32 clk_type = 0; - struct MXL_REG_FIELD_T xpt_sync_polarity[MXL_HYDRA_DEMOD_MAX] = { + static const struct MXL_REG_FIELD_T xpt_sync_polarity[MXL_HYDRA_DEMOD_MAX] = { {0x90700010, 8, 1}, {0x90700010, 9, 1}, {0x90700010, 10, 1}, {0x90700010, 11, 1}, {0x90700010, 12, 1}, {0x90700010, 13, 1}, {0x90700010, 14, 1}, {0x90700010, 15, 1} }; - struct MXL_REG_FIELD_T xpt_clock_polarity[MXL_HYDRA_DEMOD_MAX] = { + static const struct MXL_REG_FIELD_T xpt_clock_polarity[MXL_HYDRA_DEMOD_MAX] = { {0x90700010, 16, 1}, {0x90700010, 17, 1}, {0x90700010, 18, 1}, {0x90700010, 19, 1}, {0x90700010, 20, 1}, {0x90700010, 21, 1}, {0x90700010, 22, 1}, {0x90700010, 23, 1} }; - struct MXL_REG_FIELD_T xpt_valid_polarity[MXL_HYDRA_DEMOD_MAX] = { + static const struct MXL_REG_FIELD_T xpt_valid_polarity[MXL_HYDRA_DEMOD_MAX] = { {0x90700014, 0, 1}, {0x90700014, 1, 1}, {0x90700014, 2, 1}, {0x90700014, 3, 1}, {0x90700014, 4, 1}, {0x90700014, 5, 1}, {0x90700014, 6, 1}, {0x90700014, 7, 1} }; - struct MXL_REG_FIELD_T xpt_ts_clock_phase[MXL_HYDRA_DEMOD_MAX] = { + static const struct MXL_REG_FIELD_T xpt_ts_clock_phase[MXL_HYDRA_DEMOD_MAX] = { {0x90700018, 0, 3}, {0x90700018, 4, 3}, {0x90700018, 8, 3}, {0x90700018, 12, 3}, {0x90700018, 16, 3}, {0x90700018, 20, 3}, {0x90700018, 24, 3}, {0x90700018, 28, 3} }; - struct MXL_REG_FIELD_T xpt_lsb_first[MXL_HYDRA_DEMOD_MAX] = { + static const struct MXL_REG_FIELD_T xpt_lsb_first[MXL_HYDRA_DEMOD_MAX] = { {0x9070000C, 16, 1}, {0x9070000C, 17, 1}, {0x9070000C, 18, 1}, {0x9070000C, 19, 1}, {0x9070000C, 20, 1}, {0x9070000C, 21, 1}, {0x9070000C, 22, 1}, {0x9070000C, 23, 1} }; - struct MXL_REG_FIELD_T xpt_sync_byte[MXL_HYDRA_DEMOD_MAX] = { + static const struct MXL_REG_FIELD_T xpt_sync_byte[MXL_HYDRA_DEMOD_MAX] = { {0x90700010, 0, 1}, {0x90700010, 1, 1}, {0x90700010, 2, 1}, {0x90700010, 3, 1}, {0x90700010, 4, 1}, {0x90700010, 5, 1}, {0x90700010, 6, 1}, {0x90700010, 7, 1} }; - struct MXL_REG_FIELD_T xpt_enable_output[MXL_HYDRA_DEMOD_MAX] = { + static const struct MXL_REG_FIELD_T xpt_enable_output[MXL_HYDRA_DEMOD_MAX] = { {0x9070000C, 0, 1}, {0x9070000C, 1, 1}, {0x9070000C, 2, 1}, {0x9070000C, 3, 1}, {0x9070000C, 4, 1}, {0x9070000C, 5, 1}, {0x9070000C, 6, 1}, {0x9070000C, 7, 1} }; - struct MXL_REG_FIELD_T xpt_err_replace_sync[MXL_HYDRA_DEMOD_MAX] = { + static const struct MXL_REG_FIELD_T xpt_err_replace_sync[MXL_HYDRA_DEMOD_MAX] = { {0x9070000C, 24, 1}, {0x9070000C, 25, 1}, {0x9070000C, 26, 1}, {0x9070000C, 27, 1}, {0x9070000C, 28, 1}, {0x9070000C, 29, 1}, {0x9070000C, 30, 1}, {0x9070000C, 31, 1} }; - struct MXL_REG_FIELD_T xpt_err_replace_valid[MXL_HYDRA_DEMOD_MAX] = { + static const struct MXL_REG_FIELD_T xpt_err_replace_valid[MXL_HYDRA_DEMOD_MAX] = { {0x90700014, 8, 1}, {0x90700014, 9, 1}, {0x90700014, 10, 1}, {0x90700014, 11, 1}, {0x90700014, 12, 1}, {0x90700014, 13, 1}, {0x90700014, 14, 1}, {0x90700014, 15, 1} }; - struct MXL_REG_FIELD_T xpt_continuous_clock[MXL_HYDRA_DEMOD_MAX] = { + static const struct MXL_REG_FIELD_T xpt_continuous_clock[MXL_HYDRA_DEMOD_MAX] = { {0x907001D4, 0, 1}, {0x907001D4, 1, 1}, {0x907001D4, 2, 1}, {0x907001D4, 3, 1}, {0x907001D4, 4, 1}, {0x907001D4, 5, 1}, {0x907001D4, 6, 1}, {0x907001D4, 7, 1} }; - struct MXL_REG_FIELD_T xpt_nco_clock_rate[MXL_HYDRA_DEMOD_MAX] = { + static const struct MXL_REG_FIELD_T xpt_nco_clock_rate[MXL_HYDRA_DEMOD_MAX] = { {0x90700044, 16, 80}, {0x90700044, 16, 81}, {0x90700044, 16, 82}, {0x90700044, 16, 83}, {0x90700044, 16, 84}, {0x90700044, 16, 85}, diff --git a/drivers/media/mc/mc-devnode.c b/drivers/media/mc/mc-devnode.c index f11382afe23b..f249199dc616 100644 --- a/drivers/media/mc/mc-devnode.c +++ b/drivers/media/mc/mc-devnode.c @@ -246,15 +246,14 @@ int __must_check media_devnode_register(struct media_device *mdev, kobject_set_name(&devnode->cdev.kobj, "media%d", devnode->minor); /* Part 3: Add the media and char device */ + set_bit(MEDIA_FLAG_REGISTERED, &devnode->flags); ret = cdev_device_add(&devnode->cdev, &devnode->dev); if (ret < 0) { + clear_bit(MEDIA_FLAG_REGISTERED, &devnode->flags); pr_err("%s: cdev_device_add failed\n", __func__); goto cdev_add_error; } - /* Part 4: Activate this minor. The char device can now be used. */ - set_bit(MEDIA_FLAG_REGISTERED, &devnode->flags); - return 0; cdev_add_error: diff --git a/drivers/media/pci/ngene/ngene-core.c b/drivers/media/pci/ngene/ngene-core.c index 919b297e645c..622b2d2950a7 100644 --- a/drivers/media/pci/ngene/ngene-core.c +++ b/drivers/media/pci/ngene/ngene-core.c @@ -1488,7 +1488,9 @@ static int init_channel(struct ngene_channel *chan) } if (dev->ci.en && (io & NGENE_IO_TSOUT)) { - dvb_ca_en50221_init(adapter, dev->ci.en, 0, 1); + ret = dvb_ca_en50221_init(adapter, dev->ci.en, 0, 1); + if (ret != 0) + goto err; set_transfer(chan, 1); chan->dev->channel[2].DataFormatFlags = DF_SWAP32; set_transfer(&chan->dev->channel[2], 1); diff --git a/drivers/media/radio/radio-shark2.c b/drivers/media/radio/radio-shark2.c index f1c5c0a6a335..e3e6aa87fe08 100644 --- a/drivers/media/radio/radio-shark2.c +++ b/drivers/media/radio/radio-shark2.c @@ -62,7 +62,7 @@ struct shark_device { #ifdef SHARK_USE_LEDS struct work_struct led_work; struct led_classdev leds[NO_LEDS]; - char led_names[NO_LEDS][32]; + char led_names[NO_LEDS][64]; atomic_t brightness[NO_LEDS]; unsigned long brightness_new; #endif diff --git a/drivers/media/usb/stk1160/stk1160-video.c b/drivers/media/usb/stk1160/stk1160-video.c index 4cf540d1b250..2a5a90311e0c 100644 --- a/drivers/media/usb/stk1160/stk1160-video.c +++ b/drivers/media/usb/stk1160/stk1160-video.c @@ -99,7 +99,7 @@ void stk1160_buffer_done(struct stk1160 *dev) static inline void stk1160_copy_video(struct stk1160 *dev, u8 *src, int len) { - int linesdone, lineoff, lencopy; + int linesdone, lineoff, lencopy, offset; int bytesperline = dev->width * 2; struct stk1160_buffer *buf = dev->isoc_ctl.buf; u8 *dst = buf->mem; @@ -139,8 +139,13 @@ void stk1160_copy_video(struct stk1160 *dev, u8 *src, int len) * Check if we have enough space left in the buffer. * In that case, we force loop exit after copy. */ - if (lencopy > buf->bytesused - buf->length) { - lencopy = buf->bytesused - buf->length; + offset = dst - (u8 *)buf->mem; + if (offset > buf->length) { + dev_warn_ratelimited(dev->dev, "out of bounds offset\n"); + return; + } + if (lencopy > buf->length - offset) { + lencopy = buf->length - offset; remain = lencopy; } @@ -182,8 +187,13 @@ void stk1160_copy_video(struct stk1160 *dev, u8 *src, int len) * Check if we have enough space left in the buffer. * In that case, we force loop exit after copy. */ - if (lencopy > buf->bytesused - buf->length) { - lencopy = buf->bytesused - buf->length; + offset = dst - (u8 *)buf->mem; + if (offset > buf->length) { + dev_warn_ratelimited(dev->dev, "offset out of bounds\n"); + return; + } + if (lencopy > buf->length - offset) { + lencopy = buf->length - offset; remain = lencopy; } diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c index ddc861868ce0..d9ddb1ddc150 100644 --- a/drivers/media/v4l2-core/v4l2-dev.c +++ b/drivers/media/v4l2-core/v4l2-dev.c @@ -1011,8 +1011,10 @@ int __video_register_device(struct video_device *vdev, vdev->dev.devt = MKDEV(VIDEO_MAJOR, vdev->minor); vdev->dev.parent = vdev->dev_parent; dev_set_name(&vdev->dev, "%s%d", name_base, vdev->num); + mutex_lock(&videodev_lock); ret = device_register(&vdev->dev); if (ret < 0) { + mutex_unlock(&videodev_lock); pr_err("%s: device_register failed\n", __func__); goto cleanup; } @@ -1032,6 +1034,7 @@ int __video_register_device(struct video_device *vdev, /* Part 6: Activate this minor. The char device can now be used. */ set_bit(V4L2_FL_REGISTERED, &vdev->flags); + mutex_unlock(&videodev_lock); return 0; diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c index 2d63c0f188e1..c4b40c06de22 100644 --- a/drivers/mmc/core/host.c +++ b/drivers/mmc/core/host.c @@ -111,13 +111,12 @@ void mmc_retune_enable(struct mmc_host *host) /* * Pause re-tuning for a small set of operations. The pause begins after the - * next command and after first doing re-tuning. + * next command. */ void mmc_retune_pause(struct mmc_host *host) { if (!host->retune_paused) { host->retune_paused = 1; - mmc_retune_needed(host); mmc_retune_hold(host); } } diff --git a/drivers/mtd/nand/raw/nand_hynix.c b/drivers/mtd/nand/raw/nand_hynix.c index 194e4227aefe..15131e595312 100644 --- a/drivers/mtd/nand/raw/nand_hynix.c +++ b/drivers/mtd/nand/raw/nand_hynix.c @@ -402,7 +402,7 @@ static int hynix_nand_rr_init(struct nand_chip *chip) if (ret) pr_warn("failed to initialize read-retry infrastructure"); - return 0; + return ret; } static void hynix_nand_extract_oobsize(struct nand_chip *chip, diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c index c1655e595222..81e6227cc875 100644 --- a/drivers/net/dsa/mv88e6xxx/chip.c +++ b/drivers/net/dsa/mv88e6xxx/chip.c @@ -4200,6 +4200,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { .family = MV88E6XXX_FAMILY_6097, .name = "Marvell 88E6085", .num_databases = 4096, + .num_macs = 8192, .num_ports = 10, .num_internal_phys = 5, .max_vid = 4095, @@ -4222,6 +4223,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { .family = MV88E6XXX_FAMILY_6095, .name = "Marvell 88E6095/88E6095F", .num_databases = 256, + .num_macs = 8192, .num_ports = 11, .num_internal_phys = 0, .max_vid = 4095, @@ -4242,6 +4244,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { .family = MV88E6XXX_FAMILY_6097, .name = "Marvell 88E6097/88E6097F", .num_databases = 4096, + .num_macs = 8192, .num_ports = 11, .num_internal_phys = 8, .max_vid = 4095, @@ -4264,6 +4267,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { .family = MV88E6XXX_FAMILY_6165, .name = "Marvell 88E6123", .num_databases = 4096, + .num_macs = 1024, .num_ports = 3, .num_internal_phys = 5, .max_vid = 4095, @@ -4286,6 +4290,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { .family = MV88E6XXX_FAMILY_6185, .name = "Marvell 88E6131", .num_databases = 256, + .num_macs = 8192, .num_ports = 8, .num_internal_phys = 0, .max_vid = 4095, @@ -4305,7 +4310,8 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6141, .family = MV88E6XXX_FAMILY_6341, .name = "Marvell 88E6141", - .num_databases = 4096, + .num_databases = 256, + .num_macs = 2048, .num_ports = 6, .num_internal_phys = 5, .num_gpio = 11, @@ -4329,6 +4335,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { .family = MV88E6XXX_FAMILY_6165, .name = "Marvell 88E6161", .num_databases = 4096, + .num_macs = 1024, .num_ports = 6, .num_internal_phys = 5, .max_vid = 4095, @@ -4352,6 +4359,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { .family = MV88E6XXX_FAMILY_6165, .name = "Marvell 88E6165", .num_databases = 4096, + .num_macs = 8192, .num_ports = 6, .num_internal_phys = 0, .max_vid = 4095, @@ -4375,6 +4383,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { .family = MV88E6XXX_FAMILY_6351, .name = "Marvell 88E6171", .num_databases = 4096, + .num_macs = 8192, .num_ports = 7, .num_internal_phys = 5, .max_vid = 4095, @@ -4397,6 +4406,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { .family = MV88E6XXX_FAMILY_6352, .name = "Marvell 88E6172", .num_databases = 4096, + .num_macs = 8192, .num_ports = 7, .num_internal_phys = 5, .num_gpio = 15, @@ -4420,6 +4430,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { .family = MV88E6XXX_FAMILY_6351, .name = "Marvell 88E6175", .num_databases = 4096, + .num_macs = 8192, .num_ports = 7, .num_internal_phys = 5, .max_vid = 4095, @@ -4442,6 +4453,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { .family = MV88E6XXX_FAMILY_6352, .name = "Marvell 88E6176", .num_databases = 4096, + .num_macs = 8192, .num_ports = 7, .num_internal_phys = 5, .num_gpio = 15, @@ -4465,6 +4477,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { .family = MV88E6XXX_FAMILY_6185, .name = "Marvell 88E6185", .num_databases = 256, + .num_macs = 8192, .num_ports = 10, .num_internal_phys = 0, .max_vid = 4095, @@ -4485,6 +4498,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { .family = MV88E6XXX_FAMILY_6390, .name = "Marvell 88E6190", .num_databases = 4096, + .num_macs = 16384, .num_ports = 11, /* 10 + Z80 */ .num_internal_phys = 9, .num_gpio = 16, @@ -4508,6 +4522,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { .family = MV88E6XXX_FAMILY_6390, .name = "Marvell 88E6190X", .num_databases = 4096, + .num_macs = 16384, .num_ports = 11, /* 10 + Z80 */ .num_internal_phys = 9, .num_gpio = 16, @@ -4531,6 +4546,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { .family = MV88E6XXX_FAMILY_6390, .name = "Marvell 88E6191", .num_databases = 4096, + .num_macs = 16384, .num_ports = 11, /* 10 + Z80 */ .num_internal_phys = 9, .max_vid = 8191, @@ -4581,6 +4597,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { .family = MV88E6XXX_FAMILY_6352, .name = "Marvell 88E6240", .num_databases = 4096, + .num_macs = 8192, .num_ports = 7, .num_internal_phys = 5, .num_gpio = 15, @@ -4651,6 +4668,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { .family = MV88E6XXX_FAMILY_6320, .name = "Marvell 88E6320", .num_databases = 4096, + .num_macs = 8192, .num_ports = 7, .num_internal_phys = 5, .num_gpio = 15, @@ -4675,6 +4693,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { .family = MV88E6XXX_FAMILY_6320, .name = "Marvell 88E6321", .num_databases = 4096, + .num_macs = 8192, .num_ports = 7, .num_internal_phys = 5, .num_gpio = 15, @@ -4697,7 +4716,8 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6341, .family = MV88E6XXX_FAMILY_6341, .name = "Marvell 88E6341", - .num_databases = 4096, + .num_databases = 256, + .num_macs = 2048, .num_internal_phys = 5, .num_ports = 6, .num_gpio = 11, @@ -4722,6 +4742,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { .family = MV88E6XXX_FAMILY_6351, .name = "Marvell 88E6350", .num_databases = 4096, + .num_macs = 8192, .num_ports = 7, .num_internal_phys = 5, .max_vid = 4095, @@ -4744,6 +4765,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { .family = MV88E6XXX_FAMILY_6351, .name = "Marvell 88E6351", .num_databases = 4096, + .num_macs = 8192, .num_ports = 7, .num_internal_phys = 5, .max_vid = 4095, @@ -4766,6 +4788,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { .family = MV88E6XXX_FAMILY_6352, .name = "Marvell 88E6352", .num_databases = 4096, + .num_macs = 8192, .num_ports = 7, .num_internal_phys = 5, .num_gpio = 15, @@ -4789,6 +4812,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { .family = MV88E6XXX_FAMILY_6390, .name = "Marvell 88E6390", .num_databases = 4096, + .num_macs = 16384, .num_ports = 11, /* 10 + Z80 */ .num_internal_phys = 9, .num_gpio = 16, @@ -4812,6 +4836,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { .family = MV88E6XXX_FAMILY_6390, .name = "Marvell 88E6390X", .num_databases = 4096, + .num_macs = 16384, .num_ports = 11, /* 10 + Z80 */ .num_internal_phys = 9, .num_gpio = 16, diff --git a/drivers/net/dsa/mv88e6xxx/chip.h b/drivers/net/dsa/mv88e6xxx/chip.h index e9b1a1ac9a8e..24dd73be3704 100644 --- a/drivers/net/dsa/mv88e6xxx/chip.h +++ b/drivers/net/dsa/mv88e6xxx/chip.h @@ -94,6 +94,7 @@ struct mv88e6xxx_info { u16 prod_num; const char *name; unsigned int num_databases; + unsigned int num_macs; unsigned int num_ports; unsigned int num_internal_phys; unsigned int num_gpio; @@ -609,6 +610,11 @@ static inline unsigned int mv88e6xxx_num_databases(struct mv88e6xxx_chip *chip) return chip->info->num_databases; } +static inline unsigned int mv88e6xxx_num_macs(struct mv88e6xxx_chip *chip) +{ + return chip->info->num_macs; +} + static inline unsigned int mv88e6xxx_num_ports(struct mv88e6xxx_chip *chip) { return chip->info->num_ports; diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c index 380bf7a328ba..fd5f9a3a8352 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c @@ -1990,12 +1990,18 @@ static void umac_enable_set(struct bcmgenet_priv *priv, u32 mask, bool enable) { u32 reg; + spin_lock_bh(&priv->reg_lock); reg = bcmgenet_umac_readl(priv, UMAC_CMD); + if (reg & CMD_SW_RESET) { + spin_unlock_bh(&priv->reg_lock); + return; + } if (enable) reg |= mask; else reg &= ~mask; bcmgenet_umac_writel(priv, reg, UMAC_CMD); + spin_unlock_bh(&priv->reg_lock); /* UniMAC stops on a packet boundary, wait for a full-size packet * to be processed @@ -2010,11 +2016,11 @@ static void reset_umac(struct bcmgenet_priv *priv) bcmgenet_rbuf_ctrl_set(priv, 0); udelay(10); - /* disable MAC while updating its registers */ - bcmgenet_umac_writel(priv, 0, UMAC_CMD); - - /* issue soft reset with (rg)mii loopback to ensure a stable rxclk */ - bcmgenet_umac_writel(priv, CMD_SW_RESET | CMD_LCL_LOOP_EN, UMAC_CMD); + /* issue soft reset and disable MAC while updating its registers */ + spin_lock_bh(&priv->reg_lock); + bcmgenet_umac_writel(priv, CMD_SW_RESET, UMAC_CMD); + udelay(2); + spin_unlock_bh(&priv->reg_lock); } static void bcmgenet_intr_disable(struct bcmgenet_priv *priv) @@ -2796,7 +2802,7 @@ static void bcmgenet_set_hw_addr(struct bcmgenet_priv *priv, } /* Returns a reusable dma control register value */ -static u32 bcmgenet_dma_disable(struct bcmgenet_priv *priv) +static u32 bcmgenet_dma_disable(struct bcmgenet_priv *priv, bool flush_rx) { unsigned int i; u32 reg; @@ -2821,6 +2827,14 @@ static u32 bcmgenet_dma_disable(struct bcmgenet_priv *priv) udelay(10); bcmgenet_umac_writel(priv, 0, UMAC_TX_FLUSH); + if (flush_rx) { + reg = bcmgenet_rbuf_ctrl_get(priv); + bcmgenet_rbuf_ctrl_set(priv, reg | BIT(0)); + udelay(10); + bcmgenet_rbuf_ctrl_set(priv, reg); + udelay(10); + } + return dma_ctrl; } @@ -2874,7 +2888,9 @@ static void bcmgenet_netif_start(struct net_device *dev) struct bcmgenet_priv *priv = netdev_priv(dev); /* Start the network engine */ + netif_addr_lock_bh(dev); bcmgenet_set_rx_mode(dev); + netif_addr_unlock_bh(dev); bcmgenet_enable_rx_napi(priv); umac_enable_set(priv, CMD_TX_EN | CMD_RX_EN, true); @@ -2916,8 +2932,8 @@ static int bcmgenet_open(struct net_device *dev) bcmgenet_set_hw_addr(priv, dev->dev_addr); - /* Disable RX/TX DMA and flush TX queues */ - dma_ctrl = bcmgenet_dma_disable(priv); + /* Disable RX/TX DMA and flush TX and RX queues */ + dma_ctrl = bcmgenet_dma_disable(priv, true); /* Reinitialize TDMA and RDMA and SW housekeeping */ ret = bcmgenet_init_dma(priv); @@ -3138,16 +3154,19 @@ static void bcmgenet_set_rx_mode(struct net_device *dev) * 3. The number of filters needed exceeds the number filters * supported by the hardware. */ + spin_lock(&priv->reg_lock); reg = bcmgenet_umac_readl(priv, UMAC_CMD); if ((dev->flags & (IFF_PROMISC | IFF_ALLMULTI)) || (nfilter > MAX_MDF_FILTER)) { reg |= CMD_PROMISC; bcmgenet_umac_writel(priv, reg, UMAC_CMD); + spin_unlock(&priv->reg_lock); bcmgenet_umac_writel(priv, 0, UMAC_MDF_CTRL); return; } else { reg &= ~CMD_PROMISC; bcmgenet_umac_writel(priv, reg, UMAC_CMD); + spin_unlock(&priv->reg_lock); } /* update MDF filter */ @@ -3505,6 +3524,7 @@ static int bcmgenet_probe(struct platform_device *pdev) goto err; } + spin_lock_init(&priv->reg_lock); spin_lock_init(&priv->lock); SET_NETDEV_DEV(dev, &pdev->dev); @@ -3670,7 +3690,7 @@ static int bcmgenet_resume(struct device *d) bcmgenet_power_up(priv, GENET_POWER_WOL_MAGIC); /* Disable RX/TX DMA and flush TX queues */ - dma_ctrl = bcmgenet_dma_disable(priv); + dma_ctrl = bcmgenet_dma_disable(priv, false); /* Reinitialize TDMA and RDMA and SW housekeeping */ ret = bcmgenet_init_dma(priv); diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.h b/drivers/net/ethernet/broadcom/genet/bcmgenet.h index 29bf256d13f6..9efc503a9c8b 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.h +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.h @@ -608,6 +608,8 @@ struct bcmgenet_rx_ring { /* device context */ struct bcmgenet_priv { void __iomem *base; + /* reg_lock: lock to serialize access to shared registers */ + spinlock_t reg_lock; enum bcmgenet_version version; struct net_device *dev; diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c b/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c index a2da09da4907..973275d116b6 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c @@ -132,10 +132,16 @@ int bcmgenet_wol_power_down_cfg(struct bcmgenet_priv *priv, return -EINVAL; } - /* disable RX */ + /* Can't suspend with WoL if MAC is still in reset */ + spin_lock_bh(&priv->reg_lock); reg = bcmgenet_umac_readl(priv, UMAC_CMD); + if (reg & CMD_SW_RESET) + reg &= ~CMD_SW_RESET; + + /* disable RX */ reg &= ~CMD_RX_EN; bcmgenet_umac_writel(priv, reg, UMAC_CMD); + spin_unlock_bh(&priv->reg_lock); mdelay(10); reg = bcmgenet_umac_readl(priv, UMAC_MPD_CTRL); @@ -159,6 +165,7 @@ int bcmgenet_wol_power_down_cfg(struct bcmgenet_priv *priv, retries); /* Enable CRC forward */ + spin_lock_bh(&priv->reg_lock); reg = bcmgenet_umac_readl(priv, UMAC_CMD); priv->crc_fwd_en = 1; reg |= CMD_CRC_FWD; @@ -166,6 +173,7 @@ int bcmgenet_wol_power_down_cfg(struct bcmgenet_priv *priv, /* Receiver must be enabled for WOL MP detection */ reg |= CMD_RX_EN; bcmgenet_umac_writel(priv, reg, UMAC_CMD); + spin_unlock_bh(&priv->reg_lock); return 0; } @@ -187,8 +195,10 @@ void bcmgenet_wol_power_up_cfg(struct bcmgenet_priv *priv, bcmgenet_umac_writel(priv, reg, UMAC_MPD_CTRL); /* Disable CRC Forward */ + spin_lock_bh(&priv->reg_lock); reg = bcmgenet_umac_readl(priv, UMAC_CMD); reg &= ~CMD_CRC_FWD; bcmgenet_umac_writel(priv, reg, UMAC_CMD); + spin_unlock_bh(&priv->reg_lock); priv->crc_fwd_en = 0; } diff --git a/drivers/net/ethernet/broadcom/genet/bcmmii.c b/drivers/net/ethernet/broadcom/genet/bcmmii.c index 026f00ccaa0c..bd532e5b9f73 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmmii.c +++ b/drivers/net/ethernet/broadcom/genet/bcmmii.c @@ -91,12 +91,20 @@ void bcmgenet_mii_setup(struct net_device *dev) reg |= RGMII_LINK; bcmgenet_ext_writel(priv, reg, EXT_RGMII_OOB_CTRL); + spin_lock_bh(&priv->reg_lock); reg = bcmgenet_umac_readl(priv, UMAC_CMD); reg &= ~((CMD_SPEED_MASK << CMD_SPEED_SHIFT) | CMD_HD_EN | CMD_RX_PAUSE_IGNORE | CMD_TX_PAUSE_IGNORE); reg |= cmd_bits; + if (reg & CMD_SW_RESET) { + reg &= ~CMD_SW_RESET; + bcmgenet_umac_writel(priv, reg, UMAC_CMD); + udelay(2); + reg |= CMD_TX_EN | CMD_RX_EN; + } bcmgenet_umac_writel(priv, reg, UMAC_CMD); + spin_unlock_bh(&priv->reg_lock); priv->eee.eee_active = phy_init_eee(phydev, 0) >= 0; bcmgenet_eee_enable_set(dev, @@ -187,38 +195,8 @@ int bcmgenet_mii_config(struct net_device *dev, bool init) const char *phy_name = NULL; u32 id_mode_dis = 0; u32 port_ctrl; - int bmcr = -1; - int ret; u32 reg; - /* MAC clocking workaround during reset of umac state machines */ - reg = bcmgenet_umac_readl(priv, UMAC_CMD); - if (reg & CMD_SW_RESET) { - /* An MII PHY must be isolated to prevent TXC contention */ - if (priv->phy_interface == PHY_INTERFACE_MODE_MII) { - ret = phy_read(phydev, MII_BMCR); - if (ret >= 0) { - bmcr = ret; - ret = phy_write(phydev, MII_BMCR, - bmcr | BMCR_ISOLATE); - } - if (ret) { - netdev_err(dev, "failed to isolate PHY\n"); - return ret; - } - } - /* Switch MAC clocking to RGMII generated clock */ - bcmgenet_sys_writel(priv, PORT_MODE_EXT_GPHY, SYS_PORT_CTRL); - /* Ensure 5 clks with Rx disabled - * followed by 5 clks with Reset asserted - */ - udelay(4); - reg &= ~(CMD_SW_RESET | CMD_LCL_LOOP_EN); - bcmgenet_umac_writel(priv, reg, UMAC_CMD); - /* Ensure 5 more clocks before Rx is enabled */ - udelay(2); - } - priv->ext_phy = !priv->internal_phy && (priv->phy_interface != PHY_INTERFACE_MODE_MOCA); @@ -250,9 +228,6 @@ int bcmgenet_mii_config(struct net_device *dev, bool init) phy_set_max_speed(phydev, SPEED_100); bcmgenet_sys_writel(priv, PORT_MODE_EXT_EPHY, SYS_PORT_CTRL); - /* Restore the MII PHY after isolation */ - if (bmcr >= 0) - phy_write(phydev, MII_BMCR, bmcr); break; case PHY_INTERFACE_MODE_REVMII: @@ -296,6 +271,7 @@ int bcmgenet_mii_config(struct net_device *dev, bool init) * block for the interface to work */ if (priv->ext_phy) { + mutex_lock(&phydev->lock); reg = bcmgenet_ext_readl(priv, EXT_RGMII_OOB_CTRL); reg |= id_mode_dis; if (GENET_IS_V1(priv) || GENET_IS_V2(priv) || GENET_IS_V3(priv)) @@ -303,6 +279,7 @@ int bcmgenet_mii_config(struct net_device *dev, bool init) else reg |= RGMII_MODE_EN; bcmgenet_ext_writel(priv, reg, EXT_RGMII_OOB_CTRL); + mutex_unlock(&phydev->lock); } if (init) diff --git a/drivers/net/ethernet/brocade/bna/bnad_debugfs.c b/drivers/net/ethernet/brocade/bna/bnad_debugfs.c index 04ad0f2b9677..777f0d7e4819 100644 --- a/drivers/net/ethernet/brocade/bna/bnad_debugfs.c +++ b/drivers/net/ethernet/brocade/bna/bnad_debugfs.c @@ -312,7 +312,7 @@ bnad_debugfs_write_regrd(struct file *file, const char __user *buf, void *kern_buf; /* Copy the user space buf */ - kern_buf = memdup_user(buf, nbytes); + kern_buf = memdup_user_nul(buf, nbytes); if (IS_ERR(kern_buf)) return PTR_ERR(kern_buf); @@ -372,7 +372,7 @@ bnad_debugfs_write_regwr(struct file *file, const char __user *buf, void *kern_buf; /* Copy the user space buf */ - kern_buf = memdup_user(buf, nbytes); + kern_buf = memdup_user_nul(buf, nbytes); if (IS_ERR(kern_buf)) return PTR_ERR(kern_buf); diff --git a/drivers/net/ethernet/cisco/enic/enic_main.c b/drivers/net/ethernet/cisco/enic/enic_main.c index 03c8af58050c..892c4b5ff303 100644 --- a/drivers/net/ethernet/cisco/enic/enic_main.c +++ b/drivers/net/ethernet/cisco/enic/enic_main.c @@ -1152,18 +1152,30 @@ static int enic_set_vf_port(struct net_device *netdev, int vf, pp->request = nla_get_u8(port[IFLA_PORT_REQUEST]); if (port[IFLA_PORT_PROFILE]) { + if (nla_len(port[IFLA_PORT_PROFILE]) != PORT_PROFILE_MAX) { + memcpy(pp, &prev_pp, sizeof(*pp)); + return -EINVAL; + } pp->set |= ENIC_SET_NAME; memcpy(pp->name, nla_data(port[IFLA_PORT_PROFILE]), PORT_PROFILE_MAX); } if (port[IFLA_PORT_INSTANCE_UUID]) { + if (nla_len(port[IFLA_PORT_INSTANCE_UUID]) != PORT_UUID_MAX) { + memcpy(pp, &prev_pp, sizeof(*pp)); + return -EINVAL; + } pp->set |= ENIC_SET_INSTANCE; memcpy(pp->instance_uuid, nla_data(port[IFLA_PORT_INSTANCE_UUID]), PORT_UUID_MAX); } if (port[IFLA_PORT_HOST_UUID]) { + if (nla_len(port[IFLA_PORT_HOST_UUID]) != PORT_UUID_MAX) { + memcpy(pp, &prev_pp, sizeof(*pp)); + return -EINVAL; + } pp->set |= ENIC_SET_HOST; memcpy(pp->host_uuid, nla_data(port[IFLA_PORT_HOST_UUID]), PORT_UUID_MAX); diff --git a/drivers/net/ethernet/cortina/gemini.c b/drivers/net/ethernet/cortina/gemini.c index 4bcdb48b0e9c..91952d086f22 100644 --- a/drivers/net/ethernet/cortina/gemini.c +++ b/drivers/net/ethernet/cortina/gemini.c @@ -1115,10 +1115,13 @@ static void gmac_tx_irq_enable(struct net_device *netdev, { struct gemini_ethernet_port *port = netdev_priv(netdev); struct gemini_ethernet *geth = port->geth; + unsigned long flags; u32 val, mask; netdev_dbg(netdev, "%s device %d\n", __func__, netdev->dev_id); + spin_lock_irqsave(&geth->irq_lock, flags); + mask = GMAC0_IRQ0_TXQ0_INTS << (6 * netdev->dev_id + txq); if (en) @@ -1127,6 +1130,8 @@ static void gmac_tx_irq_enable(struct net_device *netdev, val = readl(geth->base + GLOBAL_INTERRUPT_ENABLE_0_REG); val = en ? val | mask : val & ~mask; writel(val, geth->base + GLOBAL_INTERRUPT_ENABLE_0_REG); + + spin_unlock_irqrestore(&geth->irq_lock, flags); } static void gmac_tx_irq(struct net_device *netdev, unsigned int txq_num) @@ -1432,15 +1437,19 @@ static unsigned int gmac_rx(struct net_device *netdev, unsigned int budget) union gmac_rxdesc_3 word3; struct page *page = NULL; unsigned int page_offs; + unsigned long flags; unsigned short r, w; union dma_rwptr rw; dma_addr_t mapping; int frag_nr = 0; + spin_lock_irqsave(&geth->irq_lock, flags); rw.bits32 = readl(ptr_reg); /* Reset interrupt as all packages until here are taken into account */ writel(DEFAULT_Q0_INT_BIT << netdev->dev_id, geth->base + GLOBAL_INTERRUPT_STATUS_1_REG); + spin_unlock_irqrestore(&geth->irq_lock, flags); + r = rw.bits.rptr; w = rw.bits.wptr; @@ -1743,10 +1752,9 @@ static irqreturn_t gmac_irq(int irq, void *data) gmac_update_hw_stats(netdev); if (val & (GMAC0_RX_OVERRUN_INT_BIT << (netdev->dev_id * 8))) { + spin_lock(&geth->irq_lock); writel(GMAC0_RXDERR_INT_BIT << (netdev->dev_id * 8), geth->base + GLOBAL_INTERRUPT_STATUS_4_REG); - - spin_lock(&geth->irq_lock); u64_stats_update_begin(&port->ir_stats_syncp); ++port->stats.rx_fifo_errors; u64_stats_update_end(&port->ir_stats_syncp); diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c index b55d6ed9aa13..fb7039b001ef 100644 --- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c @@ -3371,6 +3371,14 @@ free_queue_mem: return ret; } +static void fec_enet_deinit(struct net_device *ndev) +{ + struct fec_enet_private *fep = netdev_priv(ndev); + + netif_napi_del(&fep->napi); + fec_enet_free_queue(ndev); +} + #ifdef CONFIG_OF static int fec_reset_phy(struct platform_device *pdev) { @@ -3735,6 +3743,7 @@ failed_register: fec_enet_mii_remove(fep); failed_mii_init: failed_irq: + fec_enet_deinit(ndev); failed_init: fec_ptp_stop(pdev); failed_reset: @@ -3796,6 +3805,7 @@ fec_drv_remove(struct platform_device *pdev) pm_runtime_put_noidle(&pdev->dev); pm_runtime_disable(&pdev->dev); + fec_enet_deinit(ndev); free_netdev(ndev); return 0; } diff --git a/drivers/net/ethernet/freescale/fec_ptp.c b/drivers/net/ethernet/freescale/fec_ptp.c index 6fd0c73b327e..37b8ad29b5b3 100644 --- a/drivers/net/ethernet/freescale/fec_ptp.c +++ b/drivers/net/ethernet/freescale/fec_ptp.c @@ -108,14 +108,13 @@ static int fec_ptp_enable_pps(struct fec_enet_private *fep, uint enable) return -EINVAL; } - if (fep->pps_enable == enable) - return 0; - - fep->pps_channel = DEFAULT_PPS_CHANNEL; - fep->reload_period = PPS_OUPUT_RELOAD_PERIOD; - spin_lock_irqsave(&fep->tmreg_lock, flags); + if (fep->pps_enable == enable) { + spin_unlock_irqrestore(&fep->tmreg_lock, flags); + return 0; + } + if (enable) { /* clear capture or output compare interrupt status if have. */ @@ -446,6 +445,9 @@ static int fec_ptp_enable(struct ptp_clock_info *ptp, int ret = 0; if (rq->type == PTP_CLK_REQ_PPS) { + fep->pps_channel = DEFAULT_PPS_CHANNEL; + fep->reload_period = PPS_OUPUT_RELOAD_PERIOD; + ret = fec_ptp_enable_pps(fep, on); return ret; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c index 35630b538c82..facbbd3fac66 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c @@ -3667,7 +3667,7 @@ mlx5e_get_stats(struct net_device *dev, struct rtnl_link_stats64 *stats) mlx5e_fold_sw_stats64(priv, stats); } - stats->rx_dropped = priv->stats.qcnt.rx_out_of_buffer; + stats->rx_missed_errors = priv->stats.qcnt.rx_out_of_buffer; stats->rx_length_errors = PPORT_802_3_GET(pstats, a_in_range_length_errors) + diff --git a/drivers/net/ethernet/qlogic/qed/qed_main.c b/drivers/net/ethernet/qlogic/qed/qed_main.c index 1cbcc2760278..91ca2b706938 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_main.c +++ b/drivers/net/ethernet/qlogic/qed/qed_main.c @@ -1177,7 +1177,6 @@ static void qed_slowpath_task(struct work_struct *work) static int qed_slowpath_wq_start(struct qed_dev *cdev) { struct qed_hwfn *hwfn; - char name[NAME_SIZE]; int i; if (IS_VF(cdev)) @@ -1186,11 +1185,11 @@ static int qed_slowpath_wq_start(struct qed_dev *cdev) for_each_hwfn(cdev, i) { hwfn = &cdev->hwfns[i]; - snprintf(name, NAME_SIZE, "slowpath-%02x:%02x.%02x", - cdev->pdev->bus->number, - PCI_SLOT(cdev->pdev->devfn), hwfn->abs_pf_id); + hwfn->slowpath_wq = alloc_workqueue("slowpath-%02x:%02x.%02x", + 0, 0, cdev->pdev->bus->number, + PCI_SLOT(cdev->pdev->devfn), + hwfn->abs_pf_id); - hwfn->slowpath_wq = alloc_workqueue(name, 0, 0); if (!hwfn->slowpath_wq) { DP_NOTICE(hwfn, "Cannot create slowpath workqueue\n"); return -ENOMEM; diff --git a/drivers/net/ethernet/qlogic/qede/qede_filter.c b/drivers/net/ethernet/qlogic/qede/qede_filter.c index 5041994bf03f..3142d92a98f0 100644 --- a/drivers/net/ethernet/qlogic/qede/qede_filter.c +++ b/drivers/net/ethernet/qlogic/qede/qede_filter.c @@ -1949,8 +1949,8 @@ int qede_add_tc_flower_fltr(struct qede_dev *edev, __be16 proto, struct flow_cls_offload *f) { struct qede_arfs_fltr_node *n; - int min_hlen, rc = -EINVAL; struct qede_arfs_tuple t; + int min_hlen, rc; __qede_lock(edev); @@ -1960,7 +1960,8 @@ int qede_add_tc_flower_fltr(struct qede_dev *edev, __be16 proto, } /* parse flower attribute and prepare filter */ - if (qede_parse_flow_attr(edev, proto, f->rule, &t)) + rc = qede_parse_flow_attr(edev, proto, f->rule, &t); + if (rc) goto unlock; /* Validate profile mode and number of filters */ @@ -1969,12 +1970,15 @@ int qede_add_tc_flower_fltr(struct qede_dev *edev, __be16 proto, DP_NOTICE(edev, "Filter configuration invalidated, filter mode=0x%x, configured mode=0x%x, filter count=0x%x\n", t.mode, edev->arfs->mode, edev->arfs->filter_count); + rc = -EINVAL; goto unlock; } /* parse tc actions and get the vf_id */ - if (qede_parse_actions(edev, &f->rule->action)) + if (qede_parse_actions(edev, &f->rule->action)) { + rc = -EINVAL; goto unlock; + } if (qede_flow_find_fltr(edev, &t)) { rc = -EEXIST; @@ -2079,10 +2083,9 @@ static int qede_flow_spec_to_rule(struct qede_dev *edev, if (IS_ERR(flow)) return PTR_ERR(flow); - if (qede_parse_flow_attr(edev, proto, flow->rule, t)) { - err = -EINVAL; + err = qede_parse_flow_attr(edev, proto, flow->rule, t); + if (err) goto err_out; - } /* Make sure location is valid and filter isn't already set */ err = qede_flow_spec_validate(edev, &flow->rule->action, t, diff --git a/drivers/net/ethernet/smsc/smc91x.h b/drivers/net/ethernet/smsc/smc91x.h index 387539a8094b..95e9204ce827 100644 --- a/drivers/net/ethernet/smsc/smc91x.h +++ b/drivers/net/ethernet/smsc/smc91x.h @@ -175,8 +175,8 @@ static inline void mcf_outsw(void *a, unsigned char *p, int l) writew(*wp++, a); } -#define SMC_inw(a, r) _swapw(readw((a) + (r))) -#define SMC_outw(lp, v, a, r) writew(_swapw(v), (a) + (r)) +#define SMC_inw(a, r) ioread16be((a) + (r)) +#define SMC_outw(lp, v, a, r) iowrite16be(v, (a) + (r)) #define SMC_insw(a, r, p, l) mcf_insw(a + r, p, l) #define SMC_outsw(a, r, p, l) mcf_outsw(a + r, p, l) diff --git a/drivers/net/ipvlan/ipvlan_core.c b/drivers/net/ipvlan/ipvlan_core.c index bfea28bd4502..d04b1450875b 100644 --- a/drivers/net/ipvlan/ipvlan_core.c +++ b/drivers/net/ipvlan/ipvlan_core.c @@ -440,7 +440,7 @@ static noinline_for_stack int ipvlan_process_v4_outbound(struct sk_buff *skb) memset(IPCB(skb), 0, sizeof(*IPCB(skb))); - err = ip_local_out(net, skb->sk, skb); + err = ip_local_out(net, NULL, skb); if (unlikely(net_xmit_eval(err))) DEV_STATS_INC(dev, tx_errors); else @@ -495,7 +495,7 @@ static int ipvlan_process_v6_outbound(struct sk_buff *skb) memset(IP6CB(skb), 0, sizeof(*IP6CB(skb))); - err = ip6_local_out(dev_net(dev), skb->sk, skb); + err = ip6_local_out(dev_net(dev), NULL, skb); if (unlikely(net_xmit_eval(err))) DEV_STATS_INC(dev, tx_errors); else diff --git a/drivers/net/usb/aqc111.c b/drivers/net/usb/aqc111.c index 892d58b38cf5..b958e0005882 100644 --- a/drivers/net/usb/aqc111.c +++ b/drivers/net/usb/aqc111.c @@ -1141,17 +1141,15 @@ static int aqc111_rx_fixup(struct usbnet *dev, struct sk_buff *skb) continue; } - /* Clone SKB */ - new_skb = skb_clone(skb, GFP_ATOMIC); + new_skb = netdev_alloc_skb_ip_align(dev->net, pkt_len); if (!new_skb) goto err; - new_skb->len = pkt_len; + skb_put(new_skb, pkt_len); + memcpy(new_skb->data, skb->data, pkt_len); skb_pull(new_skb, AQ_RX_HW_PAD); - skb_set_tail_pointer(new_skb, new_skb->len); - new_skb->truesize = SKB_TRUESIZE(new_skb->len); if (aqc111_data->rx_checksum) aqc111_rx_checksum(new_skb, pkt_desc); diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index c2bd4abce6de..7cad9850e6f1 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c @@ -1323,6 +1323,9 @@ static const struct usb_device_id products[] = { {QMI_QUIRK_SET_DTR(0x1bc7, 0x1060, 2)}, /* Telit LN920 */ {QMI_QUIRK_SET_DTR(0x1bc7, 0x1070, 2)}, /* Telit FN990 */ {QMI_QUIRK_SET_DTR(0x1bc7, 0x1080, 2)}, /* Telit FE990 */ + {QMI_QUIRK_SET_DTR(0x1bc7, 0x10a0, 0)}, /* Telit FN920C04 */ + {QMI_QUIRK_SET_DTR(0x1bc7, 0x10a4, 0)}, /* Telit FN920C04 */ + {QMI_QUIRK_SET_DTR(0x1bc7, 0x10a9, 0)}, /* Telit FN920C04 */ {QMI_FIXED_INTF(0x1bc7, 0x1100, 3)}, /* Telit ME910 */ {QMI_FIXED_INTF(0x1bc7, 0x1101, 3)}, /* Telit ME910 dual modem */ {QMI_FIXED_INTF(0x1bc7, 0x1200, 5)}, /* Telit LE920 */ @@ -1380,6 +1383,7 @@ static const struct usb_device_id products[] = { {QMI_FIXED_INTF(0x0489, 0xe0b5, 0)}, /* Foxconn T77W968 LTE with eSIM support*/ {QMI_FIXED_INTF(0x2692, 0x9025, 4)}, /* Cellient MPL200 (rebranded Qualcomm 05c6:9025) */ {QMI_QUIRK_SET_DTR(0x1546, 0x1342, 4)}, /* u-blox LARA-L6 */ + {QMI_QUIRK_SET_DTR(0x33f8, 0x0104, 4)}, /* Rolling RW101 RMNET */ /* 4. Gobi 1000 devices */ {QMI_GOBI1K_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */ diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c index 7c579b038be7..2dd4c78f5465 100644 --- a/drivers/net/usb/smsc95xx.c +++ b/drivers/net/usb/smsc95xx.c @@ -261,16 +261,18 @@ done: mutex_unlock(&dev->phy_mutex); } -static int smsc95xx_mdio_read_nopm(struct net_device *netdev, int phy_id, - int idx) +static int smsc95xx_mdio_read_nopm(struct usbnet *dev, int idx) { - return __smsc95xx_mdio_read(netdev, phy_id, idx, 1); + struct mii_if_info *mii = &dev->mii; + + return __smsc95xx_mdio_read(dev->net, mii->phy_id, idx, 1); } -static void smsc95xx_mdio_write_nopm(struct net_device *netdev, int phy_id, - int idx, int regval) +static void smsc95xx_mdio_write_nopm(struct usbnet *dev, int idx, int regval) { - __smsc95xx_mdio_write(netdev, phy_id, idx, regval, 1); + struct mii_if_info *mii = &dev->mii; + + __smsc95xx_mdio_write(dev->net, mii->phy_id, idx, regval, 1); } static int smsc95xx_mdio_read(struct net_device *netdev, int phy_id, int idx) @@ -455,7 +457,7 @@ static unsigned int smsc95xx_hash(char addr[ETH_ALEN]) static void smsc95xx_set_multicast(struct net_device *netdev) { struct usbnet *dev = netdev_priv(netdev); - struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]); + struct smsc95xx_priv *pdata = dev->driver_priv; unsigned long flags; int ret; @@ -550,7 +552,7 @@ static int smsc95xx_phy_update_flowcontrol(struct usbnet *dev, u8 duplex, static int smsc95xx_link_reset(struct usbnet *dev) { - struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]); + struct smsc95xx_priv *pdata = dev->driver_priv; struct mii_if_info *mii = &dev->mii; struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET }; unsigned long flags; @@ -618,7 +620,7 @@ static void smsc95xx_status(struct usbnet *dev, struct urb *urb) static void set_carrier(struct usbnet *dev, bool link) { - struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]); + struct smsc95xx_priv *pdata = dev->driver_priv; if (pdata->link_ok == link) return; @@ -747,7 +749,7 @@ static void smsc95xx_ethtool_get_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo) { struct usbnet *dev = netdev_priv(net); - struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]); + struct smsc95xx_priv *pdata = dev->driver_priv; wolinfo->supported = SUPPORTED_WAKE; wolinfo->wolopts = pdata->wolopts; @@ -757,7 +759,7 @@ static int smsc95xx_ethtool_set_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo) { struct usbnet *dev = netdev_priv(net); - struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]); + struct smsc95xx_priv *pdata = dev->driver_priv; int ret; if (wolinfo->wolopts & ~SUPPORTED_WAKE) @@ -796,7 +798,7 @@ static int get_mdix_status(struct net_device *net) static void set_mdix_status(struct net_device *net, __u8 mdix_ctrl) { struct usbnet *dev = netdev_priv(net); - struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]); + struct smsc95xx_priv *pdata = dev->driver_priv; int buf; if ((pdata->chip_id == ID_REV_CHIP_ID_9500A_) || @@ -845,7 +847,7 @@ static int smsc95xx_get_link_ksettings(struct net_device *net, struct ethtool_link_ksettings *cmd) { struct usbnet *dev = netdev_priv(net); - struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]); + struct smsc95xx_priv *pdata = dev->driver_priv; int retval; retval = usbnet_get_link_ksettings(net, cmd); @@ -860,7 +862,7 @@ static int smsc95xx_set_link_ksettings(struct net_device *net, const struct ethtool_link_ksettings *cmd) { struct usbnet *dev = netdev_priv(net); - struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]); + struct smsc95xx_priv *pdata = dev->driver_priv; int retval; if (pdata->mdix_ctrl != cmd->base.eth_tp_mdix_ctrl) @@ -942,7 +944,7 @@ static int smsc95xx_set_mac_address(struct usbnet *dev) /* starts the TX path */ static int smsc95xx_start_tx_path(struct usbnet *dev) { - struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]); + struct smsc95xx_priv *pdata = dev->driver_priv; unsigned long flags; int ret; @@ -962,7 +964,7 @@ static int smsc95xx_start_tx_path(struct usbnet *dev) /* Starts the Receive path */ static int smsc95xx_start_rx_path(struct usbnet *dev, int in_pm) { - struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]); + struct smsc95xx_priv *pdata = dev->driver_priv; unsigned long flags; spin_lock_irqsave(&pdata->mac_cr_lock, flags); @@ -1019,8 +1021,8 @@ static int smsc95xx_phy_initialize(struct usbnet *dev) static int smsc95xx_reset(struct usbnet *dev) { - struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]); - u32 read_buf, write_buf, burst_cap; + struct smsc95xx_priv *pdata = dev->driver_priv; + u32 read_buf, burst_cap; int ret = 0, timeout; netif_dbg(dev, ifup, dev->net, "entering smsc95xx_reset\n"); @@ -1162,10 +1164,13 @@ static int smsc95xx_reset(struct usbnet *dev) return ret; netif_dbg(dev, ifup, dev->net, "ID_REV = 0x%08x\n", read_buf); + ret = smsc95xx_read_reg(dev, LED_GPIO_CFG, &read_buf); + if (ret < 0) + return ret; /* Configure GPIO pins as LED outputs */ - write_buf = LED_GPIO_CFG_SPD_LED | LED_GPIO_CFG_LNK_LED | - LED_GPIO_CFG_FDX_LED; - ret = smsc95xx_write_reg(dev, LED_GPIO_CFG, write_buf); + read_buf |= LED_GPIO_CFG_SPD_LED | LED_GPIO_CFG_LNK_LED | + LED_GPIO_CFG_FDX_LED; + ret = smsc95xx_write_reg(dev, LED_GPIO_CFG, read_buf); if (ret < 0) return ret; @@ -1247,7 +1252,7 @@ static const struct net_device_ops smsc95xx_netdev_ops = { static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf) { - struct smsc95xx_priv *pdata = NULL; + struct smsc95xx_priv *pdata; u32 val; int ret; @@ -1259,13 +1264,12 @@ static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf) return ret; } - dev->data[0] = (unsigned long)kzalloc(sizeof(struct smsc95xx_priv), - GFP_KERNEL); - - pdata = (struct smsc95xx_priv *)(dev->data[0]); + pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); if (!pdata) return -ENOMEM; + dev->driver_priv = pdata; + spin_lock_init(&pdata->mac_cr_lock); /* LAN95xx devices do not alter the computed checksum of 0 to 0xffff. @@ -1328,15 +1332,11 @@ free_pdata: static void smsc95xx_unbind(struct usbnet *dev, struct usb_interface *intf) { - struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]); - - if (pdata) { - cancel_delayed_work_sync(&pdata->carrier_check); - netif_dbg(dev, ifdown, dev->net, "free pdata\n"); - kfree(pdata); - pdata = NULL; - dev->data[0] = 0; - } + struct smsc95xx_priv *pdata = dev->driver_priv; + + cancel_delayed_work_sync(&pdata->carrier_check); + netif_dbg(dev, ifdown, dev->net, "free pdata\n"); + kfree(pdata); } static u32 smsc_crc(const u8 *buffer, size_t len, int filter) @@ -1347,39 +1347,37 @@ static u32 smsc_crc(const u8 *buffer, size_t len, int filter) static int smsc95xx_enable_phy_wakeup_interrupts(struct usbnet *dev, u16 mask) { - struct mii_if_info *mii = &dev->mii; int ret; netdev_dbg(dev->net, "enabling PHY wakeup interrupts\n"); /* read to clear */ - ret = smsc95xx_mdio_read_nopm(dev->net, mii->phy_id, PHY_INT_SRC); + ret = smsc95xx_mdio_read_nopm(dev, PHY_INT_SRC); if (ret < 0) return ret; /* enable interrupt source */ - ret = smsc95xx_mdio_read_nopm(dev->net, mii->phy_id, PHY_INT_MASK); + ret = smsc95xx_mdio_read_nopm(dev, PHY_INT_MASK); if (ret < 0) return ret; ret |= mask; - smsc95xx_mdio_write_nopm(dev->net, mii->phy_id, PHY_INT_MASK, ret); + smsc95xx_mdio_write_nopm(dev, PHY_INT_MASK, ret); return 0; } static int smsc95xx_link_ok_nopm(struct usbnet *dev) { - struct mii_if_info *mii = &dev->mii; int ret; /* first, a dummy read, needed to latch some MII phys */ - ret = smsc95xx_mdio_read_nopm(dev->net, mii->phy_id, MII_BMSR); + ret = smsc95xx_mdio_read_nopm(dev, MII_BMSR); if (ret < 0) return ret; - ret = smsc95xx_mdio_read_nopm(dev->net, mii->phy_id, MII_BMSR); + ret = smsc95xx_mdio_read_nopm(dev, MII_BMSR); if (ret < 0) return ret; @@ -1388,7 +1386,7 @@ static int smsc95xx_link_ok_nopm(struct usbnet *dev) static int smsc95xx_enter_suspend0(struct usbnet *dev) { - struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]); + struct smsc95xx_priv *pdata = dev->driver_priv; u32 val; int ret; @@ -1427,8 +1425,7 @@ static int smsc95xx_enter_suspend0(struct usbnet *dev) static int smsc95xx_enter_suspend1(struct usbnet *dev) { - struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]); - struct mii_if_info *mii = &dev->mii; + struct smsc95xx_priv *pdata = dev->driver_priv; u32 val; int ret; @@ -1436,17 +1433,17 @@ static int smsc95xx_enter_suspend1(struct usbnet *dev) * compatibility with non-standard link partners */ if (pdata->features & FEATURE_PHY_NLP_CROSSOVER) - smsc95xx_mdio_write_nopm(dev->net, mii->phy_id, PHY_EDPD_CONFIG, - PHY_EDPD_CONFIG_DEFAULT); + smsc95xx_mdio_write_nopm(dev, PHY_EDPD_CONFIG, + PHY_EDPD_CONFIG_DEFAULT); /* enable energy detect power-down mode */ - ret = smsc95xx_mdio_read_nopm(dev->net, mii->phy_id, PHY_MODE_CTRL_STS); + ret = smsc95xx_mdio_read_nopm(dev, PHY_MODE_CTRL_STS); if (ret < 0) return ret; ret |= MODE_CTRL_STS_EDPWRDOWN_; - smsc95xx_mdio_write_nopm(dev->net, mii->phy_id, PHY_MODE_CTRL_STS, ret); + smsc95xx_mdio_write_nopm(dev, PHY_MODE_CTRL_STS, ret); /* enter SUSPEND1 mode */ ret = smsc95xx_read_reg_nopm(dev, PM_CTRL, &val); @@ -1475,7 +1472,7 @@ static int smsc95xx_enter_suspend1(struct usbnet *dev) static int smsc95xx_enter_suspend2(struct usbnet *dev) { - struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]); + struct smsc95xx_priv *pdata = dev->driver_priv; u32 val; int ret; @@ -1497,7 +1494,7 @@ static int smsc95xx_enter_suspend2(struct usbnet *dev) static int smsc95xx_enter_suspend3(struct usbnet *dev) { - struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]); + struct smsc95xx_priv *pdata = dev->driver_priv; u32 val; int ret; @@ -1536,7 +1533,7 @@ static int smsc95xx_enter_suspend3(struct usbnet *dev) static int smsc95xx_autosuspend(struct usbnet *dev, u32 link_up) { - struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]); + struct smsc95xx_priv *pdata = dev->driver_priv; int ret; if (!netif_running(dev->net)) { @@ -1584,7 +1581,7 @@ static int smsc95xx_autosuspend(struct usbnet *dev, u32 link_up) static int smsc95xx_suspend(struct usb_interface *intf, pm_message_t message) { struct usbnet *dev = usb_get_intfdata(intf); - struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]); + struct smsc95xx_priv *pdata = dev->driver_priv; u32 val, link_up; int ret; @@ -1855,7 +1852,7 @@ static int smsc95xx_resume(struct usb_interface *intf) u32 val; BUG_ON(!dev); - pdata = (struct smsc95xx_priv *)(dev->data[0]); + pdata = dev->driver_priv; suspend_flags = pdata->suspend_flags; netdev_dbg(dev->net, "resume suspend_flags=0x%02x\n", suspend_flags); @@ -1910,9 +1907,11 @@ static int smsc95xx_reset_resume(struct usb_interface *intf) static void smsc95xx_rx_csum_offload(struct sk_buff *skb) { - skb->csum = *(u16 *)(skb_tail_pointer(skb) - 2); + u16 *csum_ptr = (u16 *)(skb_tail_pointer(skb) - 2); + + skb->csum = (__force __wsum)get_unaligned(csum_ptr); skb->ip_summed = CHECKSUM_COMPLETE; - skb_trim(skb, skb->len - 2); + skb_trim(skb, skb->len - 2); /* remove csum */ } static int smsc95xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb) @@ -1970,25 +1969,22 @@ static int smsc95xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb) if (dev->net->features & NETIF_F_RXCSUM) smsc95xx_rx_csum_offload(skb); skb_trim(skb, skb->len - 4); /* remove fcs */ - skb->truesize = size + sizeof(struct sk_buff); return 1; } - ax_skb = skb_clone(skb, GFP_ATOMIC); + ax_skb = netdev_alloc_skb_ip_align(dev->net, size); if (unlikely(!ax_skb)) { netdev_warn(dev->net, "Error allocating skb\n"); return 0; } - ax_skb->len = size; - ax_skb->data = packet; - skb_set_tail_pointer(ax_skb, size); + skb_put(ax_skb, size); + memcpy(ax_skb->data, packet, size); if (dev->net->features & NETIF_F_RXCSUM) smsc95xx_rx_csum_offload(ax_skb); skb_trim(ax_skb, ax_skb->len - 4); /* remove fcs */ - ax_skb->truesize = size + sizeof(struct sk_buff); usbnet_skb_return(dev, ax_skb); } @@ -2081,7 +2077,7 @@ static struct sk_buff *smsc95xx_tx_fixup(struct usbnet *dev, static int smsc95xx_manage_power(struct usbnet *dev, int on) { - struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]); + struct smsc95xx_priv *pdata = dev->driver_priv; dev->intf->needs_remote_wakeup = on; diff --git a/drivers/net/usb/sr9700.c b/drivers/net/usb/sr9700.c index 811c8751308c..3fac642bec77 100644 --- a/drivers/net/usb/sr9700.c +++ b/drivers/net/usb/sr9700.c @@ -418,19 +418,15 @@ static int sr9700_rx_fixup(struct usbnet *dev, struct sk_buff *skb) skb_pull(skb, 3); skb->len = len; skb_set_tail_pointer(skb, len); - skb->truesize = len + sizeof(struct sk_buff); return 2; } - /* skb_clone is used for address align */ - sr_skb = skb_clone(skb, GFP_ATOMIC); + sr_skb = netdev_alloc_skb_ip_align(dev->net, len); if (!sr_skb) return 0; - sr_skb->len = len; - sr_skb->data = skb->data + 3; - skb_set_tail_pointer(sr_skb, len); - sr_skb->truesize = len + sizeof(struct sk_buff); + skb_put(sr_skb, len); + memcpy(sr_skb->data, skb->data + 3, len); usbnet_skb_return(dev, sr_skb); skb_pull(skb, len + SR_RX_OVERHEAD); diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index f70500c85e2a..8808a6540b19 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c @@ -1605,10 +1605,6 @@ static bool vxlan_set_mac(struct vxlan_dev *vxlan, if (ether_addr_equal(eth_hdr(skb)->h_source, vxlan->dev->dev_addr)) return false; - /* Ignore packets from invalid src-address */ - if (!is_valid_ether_addr(eth_hdr(skb)->h_source)) - return false; - /* Get address from the outer IP header */ if (vxlan_get_sk_family(vs) == AF_INET) { saddr.sin.sin_addr.s_addr = ip_hdr(skb)->saddr; diff --git a/drivers/net/wireless/ath/ar5523/ar5523.c b/drivers/net/wireless/ath/ar5523/ar5523.c index 5d3cf354f6cb..5ffd6f215292 100644 --- a/drivers/net/wireless/ath/ar5523/ar5523.c +++ b/drivers/net/wireless/ath/ar5523/ar5523.c @@ -1590,6 +1590,20 @@ static int ar5523_probe(struct usb_interface *intf, struct ar5523 *ar; int error = -ENOMEM; + static const u8 bulk_ep_addr[] = { + AR5523_CMD_TX_PIPE | USB_DIR_OUT, + AR5523_DATA_TX_PIPE | USB_DIR_OUT, + AR5523_CMD_RX_PIPE | USB_DIR_IN, + AR5523_DATA_RX_PIPE | USB_DIR_IN, + 0}; + + if (!usb_check_bulk_endpoints(intf, bulk_ep_addr)) { + dev_err(&dev->dev, + "Could not find all expected endpoints\n"); + error = -ENODEV; + goto out; + } + /* * Load firmware if the device requires it. This will return * -ENXIO on success and we'll get called back afer the usb diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c index 09e77be6e314..0b8d725338e2 100644 --- a/drivers/net/wireless/ath/ath10k/core.c +++ b/drivers/net/wireless/ath/ath10k/core.c @@ -579,6 +579,9 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { .max_spatial_stream = 4, .fw = { .dir = WCN3990_HW_1_0_FW_DIR, + .board = WCN3990_HW_1_0_BOARD_DATA_FILE, + .board_size = WCN3990_BOARD_DATA_SZ, + .board_ext_size = WCN3990_BOARD_EXT_DATA_SZ, }, .sw_decrypt_mcast_mgmt = true, .hw_ops = &wcn3990_ops, diff --git a/drivers/net/wireless/ath/ath10k/debugfs_sta.c b/drivers/net/wireless/ath/ath10k/debugfs_sta.c index 42931a669b02..17bc4255e2ea 100644 --- a/drivers/net/wireless/ath/ath10k/debugfs_sta.c +++ b/drivers/net/wireless/ath/ath10k/debugfs_sta.c @@ -438,7 +438,7 @@ ath10k_dbg_sta_write_peer_debug_trigger(struct file *file, } out: mutex_unlock(&ar->conf_mutex); - return count; + return ret ?: count; } static const struct file_operations fops_peer_debug_trigger = { diff --git a/drivers/net/wireless/ath/ath10k/hw.h b/drivers/net/wireless/ath/ath10k/hw.h index 705ab83cdff4..eb27aeeb94c8 100644 --- a/drivers/net/wireless/ath/ath10k/hw.h +++ b/drivers/net/wireless/ath/ath10k/hw.h @@ -132,6 +132,7 @@ enum qca9377_chip_id_rev { /* WCN3990 1.0 definitions */ #define WCN3990_HW_1_0_DEV_VERSION ATH10K_HW_WCN3990 #define WCN3990_HW_1_0_FW_DIR ATH10K_FW_DIR "/WCN3990/hw1.0" +#define WCN3990_HW_1_0_BOARD_DATA_FILE "board.bin" #define ATH10K_FW_FILE_BASE "firmware" #define ATH10K_FW_API_MAX 6 diff --git a/drivers/net/wireless/ath/ath10k/targaddrs.h b/drivers/net/wireless/ath/ath10k/targaddrs.h index dff6c8ac9dba..362508ac37fe 100644 --- a/drivers/net/wireless/ath/ath10k/targaddrs.h +++ b/drivers/net/wireless/ath/ath10k/targaddrs.h @@ -480,4 +480,7 @@ struct host_interest { #define QCA4019_BOARD_DATA_SZ 12064 #define QCA4019_BOARD_EXT_DATA_SZ 0 +#define WCN3990_BOARD_DATA_SZ 26328 +#define WCN3990_BOARD_EXT_DATA_SZ 0 + #endif /* __TARGADDRS_H__ */ diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index 4adbe3ab9c87..81689dbab7f4 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c @@ -1720,12 +1720,32 @@ void ath10k_wmi_put_wmi_channel(struct wmi_channel *ch, int ath10k_wmi_wait_for_service_ready(struct ath10k *ar) { - unsigned long time_left; + unsigned long time_left, i; time_left = wait_for_completion_timeout(&ar->wmi.service_ready, WMI_SERVICE_READY_TIMEOUT_HZ); - if (!time_left) - return -ETIMEDOUT; + if (!time_left) { + /* Sometimes the PCI HIF doesn't receive interrupt + * for the service ready message even if the buffer + * was completed. PCIe sniffer shows that it's + * because the corresponding CE ring doesn't fires + * it. Workaround here by polling CE rings once. + */ + ath10k_warn(ar, "failed to receive service ready completion, polling..\n"); + + for (i = 0; i < CE_COUNT; i++) + ath10k_hif_send_complete_check(ar, i, 1); + + time_left = wait_for_completion_timeout(&ar->wmi.service_ready, + WMI_SERVICE_READY_TIMEOUT_HZ); + if (!time_left) { + ath10k_warn(ar, "polling timed out\n"); + return -ETIMEDOUT; + } + + ath10k_warn(ar, "service ready completion received, continuing normally\n"); + } + return 0; } diff --git a/drivers/net/wireless/ath/carl9170/usb.c b/drivers/net/wireless/ath/carl9170/usb.c index 486957a04bd1..98fdfa84b0a9 100644 --- a/drivers/net/wireless/ath/carl9170/usb.c +++ b/drivers/net/wireless/ath/carl9170/usb.c @@ -1069,6 +1069,38 @@ static int carl9170_usb_probe(struct usb_interface *intf, ar->usb_ep_cmd_is_bulk = true; } + /* Verify that all expected endpoints are present */ + if (ar->usb_ep_cmd_is_bulk) { + u8 bulk_ep_addr[] = { + AR9170_USB_EP_RX | USB_DIR_IN, + AR9170_USB_EP_TX | USB_DIR_OUT, + AR9170_USB_EP_CMD | USB_DIR_OUT, + 0}; + u8 int_ep_addr[] = { + AR9170_USB_EP_IRQ | USB_DIR_IN, + 0}; + if (!usb_check_bulk_endpoints(intf, bulk_ep_addr) || + !usb_check_int_endpoints(intf, int_ep_addr)) + err = -ENODEV; + } else { + u8 bulk_ep_addr[] = { + AR9170_USB_EP_RX | USB_DIR_IN, + AR9170_USB_EP_TX | USB_DIR_OUT, + 0}; + u8 int_ep_addr[] = { + AR9170_USB_EP_IRQ | USB_DIR_IN, + AR9170_USB_EP_CMD | USB_DIR_OUT, + 0}; + if (!usb_check_bulk_endpoints(intf, bulk_ep_addr) || + !usb_check_int_endpoints(intf, int_ep_addr)) + err = -ENODEV; + } + + if (err) { + carl9170_free(ar); + return err; + } + usb_set_intfdata(intf, ar); SET_IEEE80211_DEV(ar->hw, &intf->dev); diff --git a/drivers/net/wireless/marvell/mwl8k.c b/drivers/net/wireless/marvell/mwl8k.c index 14ac2384218d..abd5c8670bc4 100644 --- a/drivers/net/wireless/marvell/mwl8k.c +++ b/drivers/net/wireless/marvell/mwl8k.c @@ -2714,7 +2714,7 @@ __mwl8k_cmd_mac_multicast_adr(struct ieee80211_hw *hw, int allmulti, cmd->action |= cpu_to_le16(MWL8K_ENABLE_RX_MULTICAST); cmd->numaddr = cpu_to_le16(mc_count); netdev_hw_addr_list_for_each(ha, mc_list) { - memcpy(cmd->addr[i], ha->addr, ETH_ALEN); + memcpy(cmd->addr[i++], ha->addr, ETH_ALEN); } } diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c index 0d9e31746fd2..5611f00ef0bd 100644 --- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c @@ -28,6 +28,7 @@ #include <linux/wireless.h> #include <linux/firmware.h> #include <linux/moduleparam.h> +#include <linux/bitfield.h> #include <net/mac80211.h> #include "rtl8xxxu.h" #include "rtl8xxxu_regs.h" @@ -1390,13 +1391,13 @@ rtl8xxxu_gen1_set_tx_power(struct rtl8xxxu_priv *priv, int channel, bool ht40) u8 cck[RTL8723A_MAX_RF_PATHS], ofdm[RTL8723A_MAX_RF_PATHS]; u8 ofdmbase[RTL8723A_MAX_RF_PATHS], mcsbase[RTL8723A_MAX_RF_PATHS]; u32 val32, ofdm_a, ofdm_b, mcs_a, mcs_b; - u8 val8; + u8 val8, base; int group, i; group = rtl8xxxu_gen1_channel_to_group(channel); - cck[0] = priv->cck_tx_power_index_A[group] - 1; - cck[1] = priv->cck_tx_power_index_B[group] - 1; + cck[0] = priv->cck_tx_power_index_A[group]; + cck[1] = priv->cck_tx_power_index_B[group]; if (priv->hi_pa) { if (cck[0] > 0x20) @@ -1407,10 +1408,6 @@ rtl8xxxu_gen1_set_tx_power(struct rtl8xxxu_priv *priv, int channel, bool ht40) ofdm[0] = priv->ht40_1s_tx_power_index_A[group]; ofdm[1] = priv->ht40_1s_tx_power_index_B[group]; - if (ofdm[0]) - ofdm[0] -= 1; - if (ofdm[1]) - ofdm[1] -= 1; ofdmbase[0] = ofdm[0] + priv->ofdm_tx_power_index_diff[group].a; ofdmbase[1] = ofdm[1] + priv->ofdm_tx_power_index_diff[group].b; @@ -1499,20 +1496,19 @@ rtl8xxxu_gen1_set_tx_power(struct rtl8xxxu_priv *priv, int channel, bool ht40) rtl8xxxu_write32(priv, REG_TX_AGC_A_MCS15_MCS12, mcs_a + power_base->reg_0e1c); + val8 = u32_get_bits(mcs_a + power_base->reg_0e1c, 0xff000000); for (i = 0; i < 3; i++) { - if (i != 2) - val8 = (mcsbase[0] > 8) ? (mcsbase[0] - 8) : 0; - else - val8 = (mcsbase[0] > 6) ? (mcsbase[0] - 6) : 0; + base = i != 2 ? 8 : 6; + val8 = max_t(int, val8 - base, 0); rtl8xxxu_write8(priv, REG_OFDM0_XC_TX_IQ_IMBALANCE + i, val8); } + rtl8xxxu_write32(priv, REG_TX_AGC_B_MCS15_MCS12, mcs_b + power_base->reg_0868); + val8 = u32_get_bits(mcs_b + power_base->reg_0868, 0xff000000); for (i = 0; i < 3; i++) { - if (i != 2) - val8 = (mcsbase[1] > 8) ? (mcsbase[1] - 8) : 0; - else - val8 = (mcsbase[1] > 6) ? (mcsbase[1] - 6) : 0; + base = i != 2 ? 8 : 6; + val8 = max_t(int, val8 - base, 0); rtl8xxxu_write8(priv, REG_OFDM0_XD_TX_IQ_IMBALANCE + i, val8); } } diff --git a/drivers/nvme/host/multipath.c b/drivers/nvme/host/multipath.c index 811f7b96b551..4f3220aef7c4 100644 --- a/drivers/nvme/host/multipath.c +++ b/drivers/nvme/host/multipath.c @@ -180,7 +180,8 @@ static struct nvme_ns *__nvme_find_path(struct nvme_ns_head *head, int node) if (nvme_path_is_disabled(ns)) continue; - if (READ_ONCE(head->subsys->iopolicy) == NVME_IOPOLICY_NUMA) + if (ns->ctrl->numa_node != NUMA_NO_NODE && + READ_ONCE(head->subsys->iopolicy) == NVME_IOPOLICY_NUMA) distance = node_distance(node, ns->ctrl->numa_node); else distance = LOCAL_DISTANCE; diff --git a/drivers/nvme/target/configfs.c b/drivers/nvme/target/configfs.c index baf8a3e4ed12..9add3516ae2e 100644 --- a/drivers/nvme/target/configfs.c +++ b/drivers/nvme/target/configfs.c @@ -507,10 +507,18 @@ static ssize_t nvmet_ns_enable_store(struct config_item *item, if (strtobool(page, &enable)) return -EINVAL; + /* + * take a global nvmet_config_sem because the disable routine has a + * window where it releases the subsys-lock, giving a chance to + * a parallel enable to concurrently execute causing the disable to + * have a misaccounting of the ns percpu_ref. + */ + down_write(&nvmet_config_sem); if (enable) ret = nvmet_ns_enable(ns); else nvmet_ns_disable(ns); + up_write(&nvmet_config_sem); return ret ? ret : count; } diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index a1c2dc304fb1..44802e501794 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -203,6 +203,7 @@ static int pinctrl_register_one_pin(struct pinctrl_dev *pctldev, const struct pinctrl_pin_desc *pin) { struct pin_desc *pindesc; + int error; pindesc = pin_desc_get(pctldev, pin->number); if (pindesc) { @@ -224,18 +225,25 @@ static int pinctrl_register_one_pin(struct pinctrl_dev *pctldev, } else { pindesc->name = kasprintf(GFP_KERNEL, "PIN%u", pin->number); if (!pindesc->name) { - kfree(pindesc); - return -ENOMEM; + error = -ENOMEM; + goto failed; } pindesc->dynamic_name = true; } pindesc->drv_data = pin->drv_data; - radix_tree_insert(&pctldev->pin_desc_tree, pin->number, pindesc); + error = radix_tree_insert(&pctldev->pin_desc_tree, pin->number, pindesc); + if (error) + goto failed; + pr_debug("registered pin %d (%s) on %s\n", pin->number, pindesc->name, pctldev->desc->name); return 0; + +failed: + kfree(pindesc); + return error; } static int pinctrl_register_pins(struct pinctrl_dev *pctldev, @@ -2053,13 +2061,7 @@ int pinctrl_enable(struct pinctrl_dev *pctldev) error = pinctrl_claim_hogs(pctldev); if (error) { - dev_err(pctldev->dev, "could not claim hogs: %i\n", - error); - pinctrl_free_pindescs(pctldev, pctldev->desc->pins, - pctldev->desc->npins); - mutex_destroy(&pctldev->mutex); - kfree(pctldev); - + dev_err(pctldev->dev, "could not claim hogs: %i\n", error); return error; } diff --git a/drivers/pinctrl/devicetree.c b/drivers/pinctrl/devicetree.c index 362d84c2ead4..200357094e3b 100644 --- a/drivers/pinctrl/devicetree.c +++ b/drivers/pinctrl/devicetree.c @@ -223,14 +223,16 @@ int pinctrl_dt_to_map(struct pinctrl *p, struct pinctrl_dev *pctldev) for (state = 0; ; state++) { /* Retrieve the pinctrl-* property */ propname = kasprintf(GFP_KERNEL, "pinctrl-%d", state); - if (!propname) - return -ENOMEM; + if (!propname) { + ret = -ENOMEM; + goto err; + } prop = of_find_property(np, propname, &size); kfree(propname); if (!prop) { if (state == 0) { - of_node_put(np); - return -ENODEV; + ret = -ENODEV; + goto err; } break; } diff --git a/drivers/pinctrl/mediatek/pinctrl-mt6765.c b/drivers/pinctrl/mediatek/pinctrl-mt6765.c index 32451e8693be..905dae8c3fd8 100644 --- a/drivers/pinctrl/mediatek/pinctrl-mt6765.c +++ b/drivers/pinctrl/mediatek/pinctrl-mt6765.c @@ -1070,15 +1070,12 @@ static const struct mtk_pin_soc mt6765_data = { .ngrps = ARRAY_SIZE(mtk_pins_mt6765), .eint_hw = &mt6765_eint_hw, .gpio_m = 0, - .ies_present = true, .base_names = mt6765_pinctrl_register_base_names, .nbase_names = ARRAY_SIZE(mt6765_pinctrl_register_base_names), - .bias_disable_set = mtk_pinconf_bias_disable_set, - .bias_disable_get = mtk_pinconf_bias_disable_get, - .bias_set = mtk_pinconf_bias_set, - .bias_get = mtk_pinconf_bias_get, - .drive_set = mtk_pinconf_drive_set_rev1, - .drive_get = mtk_pinconf_drive_get_rev1, + .bias_set_combo = mtk_pinconf_bias_set_combo, + .bias_get_combo = mtk_pinconf_bias_get_combo, + .drive_set = mtk_pinconf_drive_set_raw, + .drive_get = mtk_pinconf_drive_get_raw, .adv_pull_get = mtk_pinconf_adv_pull_get, .adv_pull_set = mtk_pinconf_adv_pull_set, }; diff --git a/drivers/pinctrl/mediatek/pinctrl-mt8183.c b/drivers/pinctrl/mediatek/pinctrl-mt8183.c index 9a74d5025be6..60318339b618 100644 --- a/drivers/pinctrl/mediatek/pinctrl-mt8183.c +++ b/drivers/pinctrl/mediatek/pinctrl-mt8183.c @@ -554,13 +554,10 @@ static const struct mtk_pin_soc mt8183_data = { .ngrps = ARRAY_SIZE(mtk_pins_mt8183), .eint_hw = &mt8183_eint_hw, .gpio_m = 0, - .ies_present = true, .base_names = mt8183_pinctrl_register_base_names, .nbase_names = ARRAY_SIZE(mt8183_pinctrl_register_base_names), - .bias_disable_set = mtk_pinconf_bias_disable_set_rev1, - .bias_disable_get = mtk_pinconf_bias_disable_get_rev1, - .bias_set = mtk_pinconf_bias_set_rev1, - .bias_get = mtk_pinconf_bias_get_rev1, + .bias_set_combo = mtk_pinconf_bias_set_combo, + .bias_get_combo = mtk_pinconf_bias_get_combo, .drive_set = mtk_pinconf_drive_set_rev1, .drive_get = mtk_pinconf_drive_get_rev1, .adv_pull_get = mtk_pinconf_adv_pull_get, diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c index c3e6f3c1b474..7dea3fcda880 100644 --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c @@ -6,6 +6,7 @@ * */ +#include <dt-bindings/pinctrl/mt65xx.h> #include <linux/device.h> #include <linux/err.h> #include <linux/gpio/driver.h> @@ -66,34 +67,44 @@ static int mtk_hw_pin_field_lookup(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc, int field, struct mtk_pin_field *pfd) { - const struct mtk_pin_field_calc *c, *e; + const struct mtk_pin_field_calc *c; const struct mtk_pin_reg_calc *rc; + int start = 0, end, check; + bool found = false; u32 bits; if (hw->soc->reg_cal && hw->soc->reg_cal[field].range) { rc = &hw->soc->reg_cal[field]; } else { dev_dbg(hw->dev, - "Not support field %d for pin %d (%s)\n", - field, desc->number, desc->name); + "Not support field %d for this soc\n", field); return -ENOTSUPP; } - c = rc->range; - e = c + rc->nranges; + end = rc->nranges - 1; - while (c < e) { - if (desc->number >= c->s_pin && desc->number <= c->e_pin) + while (start <= end) { + check = (start + end) >> 1; + if (desc->number >= rc->range[check].s_pin + && desc->number <= rc->range[check].e_pin) { + found = true; + break; + } else if (start == end) break; - c++; + else if (desc->number < rc->range[check].s_pin) + end = check - 1; + else + start = check + 1; } - if (c >= e) { + if (!found) { dev_dbg(hw->dev, "Not support field %d for pin = %d (%s)\n", field, desc->number, desc->name); return -ENOTSUPP; } + c = rc->range + check; + if (c->i_base > hw->nbase - 1) { dev_err(hw->dev, "Invalid base for field %d for pin = %d (%s)\n", @@ -182,6 +193,9 @@ int mtk_hw_set_value(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc, if (err) return err; + if (value < 0 || value > pf.mask) + return -EINVAL; + if (!pf.next) mtk_rmw(hw, pf.index, pf.offset, pf.mask << pf.bitpos, (value & pf.mask) << pf.bitpos); @@ -506,6 +520,226 @@ int mtk_pinconf_bias_get_rev1(struct mtk_pinctrl *hw, return 0; } +/* Combo for the following pull register type: + * 1. PU + PD + * 2. PULLSEL + PULLEN + * 3. PUPD + R0 + R1 + */ +static int mtk_pinconf_bias_set_pu_pd(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, + u32 pullup, u32 arg) +{ + int err, pu, pd; + + if (arg == MTK_DISABLE) { + pu = 0; + pd = 0; + } else if ((arg == MTK_ENABLE) && pullup) { + pu = 1; + pd = 0; + } else if ((arg == MTK_ENABLE) && !pullup) { + pu = 0; + pd = 1; + } else { + err = -EINVAL; + goto out; + } + + err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PU, pu); + if (err) + goto out; + + err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PD, pd); + +out: + return err; +} + +static int mtk_pinconf_bias_set_pullsel_pullen(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, + u32 pullup, u32 arg) +{ + int err, enable; + + if (arg == MTK_DISABLE) + enable = 0; + else if (arg == MTK_ENABLE) + enable = 1; + else { + err = -EINVAL; + goto out; + } + + err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PULLEN, enable); + if (err) + goto out; + + err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PULLSEL, pullup); + +out: + return err; +} + +static int mtk_pinconf_bias_set_pupd_r1_r0(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, + u32 pullup, u32 arg) +{ + int err, r0, r1; + + if ((arg == MTK_DISABLE) || (arg == MTK_PUPD_SET_R1R0_00)) { + pullup = 0; + r0 = 0; + r1 = 0; + } else if (arg == MTK_PUPD_SET_R1R0_01) { + r0 = 1; + r1 = 0; + } else if (arg == MTK_PUPD_SET_R1R0_10) { + r0 = 0; + r1 = 1; + } else if (arg == MTK_PUPD_SET_R1R0_11) { + r0 = 1; + r1 = 1; + } else { + err = -EINVAL; + goto out; + } + + /* MTK HW PUPD bit: 1 for pull-down, 0 for pull-up */ + err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PUPD, !pullup); + if (err) + goto out; + + err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_R0, r0); + if (err) + goto out; + + err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_R1, r1); + +out: + return err; +} + +static int mtk_pinconf_bias_get_pu_pd(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, + u32 *pullup, u32 *enable) +{ + int err, pu, pd; + + err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PU, &pu); + if (err) + goto out; + + err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PD, &pd); + if (err) + goto out; + + if (pu == 0 && pd == 0) { + *pullup = 0; + *enable = MTK_DISABLE; + } else if (pu == 1 && pd == 0) { + *pullup = 1; + *enable = MTK_ENABLE; + } else if (pu == 0 && pd == 1) { + *pullup = 0; + *enable = MTK_ENABLE; + } else + err = -EINVAL; + +out: + return err; +} + +static int mtk_pinconf_bias_get_pullsel_pullen(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, + u32 *pullup, u32 *enable) +{ + int err; + + err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PULLSEL, pullup); + if (err) + goto out; + + err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PULLEN, enable); + +out: + return err; +} + +static int mtk_pinconf_bias_get_pupd_r1_r0(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, + u32 *pullup, u32 *enable) +{ + int err, r0, r1; + + err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PUPD, pullup); + if (err) + goto out; + /* MTK HW PUPD bit: 1 for pull-down, 0 for pull-up */ + *pullup = !(*pullup); + + err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_R0, &r0); + if (err) + goto out; + + err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_R1, &r1); + if (err) + goto out; + + if ((r1 == 0) && (r0 == 0)) + *enable = MTK_PUPD_SET_R1R0_00; + else if ((r1 == 0) && (r0 == 1)) + *enable = MTK_PUPD_SET_R1R0_01; + else if ((r1 == 1) && (r0 == 0)) + *enable = MTK_PUPD_SET_R1R0_10; + else if ((r1 == 1) && (r0 == 1)) + *enable = MTK_PUPD_SET_R1R0_11; + else + err = -EINVAL; + +out: + return err; +} + +int mtk_pinconf_bias_set_combo(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, + u32 pullup, u32 arg) +{ + int err; + + err = mtk_pinconf_bias_set_pu_pd(hw, desc, pullup, arg); + if (!err) + goto out; + + err = mtk_pinconf_bias_set_pullsel_pullen(hw, desc, pullup, arg); + if (!err) + goto out; + + err = mtk_pinconf_bias_set_pupd_r1_r0(hw, desc, pullup, arg); + +out: + return err; +} + +int mtk_pinconf_bias_get_combo(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, + u32 *pullup, u32 *enable) +{ + int err; + + err = mtk_pinconf_bias_get_pu_pd(hw, desc, pullup, enable); + if (!err) + goto out; + + err = mtk_pinconf_bias_get_pullsel_pullen(hw, desc, pullup, enable); + if (!err) + goto out; + + err = mtk_pinconf_bias_get_pupd_r1_r0(hw, desc, pullup, enable); + +out: + return err; +} + /* Revision 0 */ int mtk_pinconf_drive_set(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc, u32 arg) @@ -597,6 +831,18 @@ int mtk_pinconf_drive_get_rev1(struct mtk_pinctrl *hw, return 0; } +int mtk_pinconf_drive_set_raw(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, u32 arg) +{ + return mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DRV, arg); +} + +int mtk_pinconf_drive_get_raw(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, int *val) +{ + return mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DRV, val); +} + int mtk_pinconf_adv_pull_set(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc, bool pullup, u32 arg) @@ -630,7 +876,9 @@ int mtk_pinconf_adv_pull_set(struct mtk_pinctrl *hw, if (err) return err; } else { - return -ENOTSUPP; + err = mtk_pinconf_bias_set_rev1(hw, desc, pullup); + if (err) + err = mtk_pinconf_bias_set(hw, desc, pullup); } } diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h index 1b7da42aa1d5..27df08736396 100644 --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h @@ -216,6 +216,11 @@ struct mtk_pin_soc { int (*bias_get)(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc, bool pullup, int *res); + int (*bias_set_combo)(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, u32 pullup, u32 arg); + int (*bias_get_combo)(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, u32 *pullup, u32 *arg); + int (*drive_set)(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc, u32 arg); int (*drive_get)(struct mtk_pinctrl *hw, @@ -277,6 +282,12 @@ int mtk_pinconf_bias_set_rev1(struct mtk_pinctrl *hw, int mtk_pinconf_bias_get_rev1(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc, bool pullup, int *res); +int mtk_pinconf_bias_set_combo(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, + u32 pullup, u32 enable); +int mtk_pinconf_bias_get_combo(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, + u32 *pullup, u32 *enable); int mtk_pinconf_drive_set(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc, u32 arg); @@ -288,6 +299,11 @@ int mtk_pinconf_drive_set_rev1(struct mtk_pinctrl *hw, int mtk_pinconf_drive_get_rev1(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc, int *val); +int mtk_pinconf_drive_set_raw(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, u32 arg); +int mtk_pinconf_drive_get_raw(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, int *val); + int mtk_pinconf_adv_pull_set(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc, bool pullup, u32 arg); diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c b/drivers/pinctrl/mediatek/pinctrl-paris.c index 31449514a8c0..126bf1a43b29 100644 --- a/drivers/pinctrl/mediatek/pinctrl-paris.c +++ b/drivers/pinctrl/mediatek/pinctrl-paris.c @@ -78,123 +78,101 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev, { struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev); u32 param = pinconf_to_config_param(*config); - int val, val2, err, reg, ret = 1; + int pullup, reg, err = -ENOTSUPP, ret = 1; const struct mtk_pin_desc *desc; + if (pin >= hw->soc->npins) + return -EINVAL; + desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin]; switch (param) { case PIN_CONFIG_BIAS_DISABLE: - if (hw->soc->bias_disable_get) { - err = hw->soc->bias_disable_get(hw, desc, &ret); - if (err) - return err; - } else { - return -ENOTSUPP; - } - break; case PIN_CONFIG_BIAS_PULL_UP: - if (hw->soc->bias_get) { - err = hw->soc->bias_get(hw, desc, 1, &ret); - if (err) - return err; - } else { - return -ENOTSUPP; - } - break; case PIN_CONFIG_BIAS_PULL_DOWN: - if (hw->soc->bias_get) { - err = hw->soc->bias_get(hw, desc, 0, &ret); - if (err) - return err; - } else { - return -ENOTSUPP; + if (!hw->soc->bias_get_combo) + break; + err = hw->soc->bias_get_combo(hw, desc, &pullup, &ret); + if (err) + break; + if (ret == MTK_PUPD_SET_R1R0_00) + ret = MTK_DISABLE; + if (param == PIN_CONFIG_BIAS_DISABLE) { + if (ret != MTK_DISABLE) + err = -EINVAL; + } else if (param == PIN_CONFIG_BIAS_PULL_UP) { + if (!pullup || ret == MTK_DISABLE) + err = -EINVAL; + } else if (param == PIN_CONFIG_BIAS_PULL_DOWN) { + if (pullup || ret == MTK_DISABLE) + err = -EINVAL; } break; case PIN_CONFIG_SLEW_RATE: - err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SR, &val); - if (err) - return err; - - if (!val) - return -EINVAL; - + err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SR, &ret); break; case PIN_CONFIG_INPUT_ENABLE: - case PIN_CONFIG_OUTPUT_ENABLE: - err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &val); + err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_IES, &ret); + if (!ret) + err = -EINVAL; + break; + case PIN_CONFIG_OUTPUT: + err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &ret); if (err) - return err; + break; - /* HW takes input mode as zero; output mode as non-zero */ - if ((val && param == PIN_CONFIG_INPUT_ENABLE) || - (!val && param == PIN_CONFIG_OUTPUT_ENABLE)) - return -EINVAL; + if (!ret) { + err = -EINVAL; + break; + } + err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DO, &ret); break; case PIN_CONFIG_INPUT_SCHMITT_ENABLE: - err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &val); + err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &ret); if (err) - return err; - - err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SMT, &val2); - if (err) - return err; - - if (val || !val2) - return -EINVAL; + break; + /* return error when in output mode + * because schmitt trigger only work in input mode + */ + if (ret) { + err = -EINVAL; + break; + } + err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SMT, &ret); + if (!ret) + err = -EINVAL; break; case PIN_CONFIG_DRIVE_STRENGTH: - if (hw->soc->drive_get) { - err = hw->soc->drive_get(hw, desc, &ret); - if (err) - return err; - } else { - err = -ENOTSUPP; - } + if (!hw->soc->drive_get) + break; + err = hw->soc->drive_get(hw, desc, &ret); break; case MTK_PIN_CONFIG_TDSEL: case MTK_PIN_CONFIG_RDSEL: reg = (param == MTK_PIN_CONFIG_TDSEL) ? PINCTRL_PIN_REG_TDSEL : PINCTRL_PIN_REG_RDSEL; - - err = mtk_hw_get_value(hw, desc, reg, &val); - if (err) - return err; - - ret = val; - + err = mtk_hw_get_value(hw, desc, reg, &ret); break; case MTK_PIN_CONFIG_PU_ADV: case MTK_PIN_CONFIG_PD_ADV: - if (hw->soc->adv_pull_get) { - bool pullup; - - pullup = param == MTK_PIN_CONFIG_PU_ADV; - err = hw->soc->adv_pull_get(hw, desc, pullup, &ret); - if (err) - return err; - } else { - return -ENOTSUPP; - } + if (!hw->soc->adv_pull_get) + break; + pullup = param == MTK_PIN_CONFIG_PU_ADV; + err = hw->soc->adv_pull_get(hw, desc, pullup, &ret); break; case MTK_PIN_CONFIG_DRV_ADV: - if (hw->soc->adv_drive_get) { - err = hw->soc->adv_drive_get(hw, desc, &ret); - if (err) - return err; - } else { - return -ENOTSUPP; - } + if (!hw->soc->adv_drive_get) + break; + err = hw->soc->adv_drive_get(hw, desc, &ret); break; - default: - return -ENOTSUPP; } - *config = pinconf_to_config_packed(param, ret); + if (!err) + *config = pinconf_to_config_packed(param, ret); - return 0; + return err; } static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, @@ -202,140 +180,84 @@ static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, { struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev); const struct mtk_pin_desc *desc; - int err = 0; + int err = -ENOTSUPP; u32 reg; + if (pin >= hw->soc->npins) + return -EINVAL; + desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin]; switch ((u32)param) { case PIN_CONFIG_BIAS_DISABLE: - if (hw->soc->bias_disable_set) { - err = hw->soc->bias_disable_set(hw, desc); - if (err) - return err; - } else { - return -ENOTSUPP; - } + if (!hw->soc->bias_set_combo) + break; + err = hw->soc->bias_set_combo(hw, desc, 0, MTK_DISABLE); break; case PIN_CONFIG_BIAS_PULL_UP: - if (hw->soc->bias_set) { - err = hw->soc->bias_set(hw, desc, 1); - if (err) - return err; - } else { - return -ENOTSUPP; - } + if (!hw->soc->bias_set_combo) + break; + err = hw->soc->bias_set_combo(hw, desc, 1, arg); break; case PIN_CONFIG_BIAS_PULL_DOWN: - if (hw->soc->bias_set) { - err = hw->soc->bias_set(hw, desc, 0); - if (err) - return err; - } else { - return -ENOTSUPP; - } - break; - case PIN_CONFIG_OUTPUT_ENABLE: - err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SMT, - MTK_DISABLE); - if (err) - goto err; - - err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR, - MTK_OUTPUT); - if (err) - goto err; + if (!hw->soc->bias_set_combo) + break; + err = hw->soc->bias_set_combo(hw, desc, 0, arg); break; case PIN_CONFIG_INPUT_ENABLE: - if (hw->soc->ies_present) { - mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_IES, - MTK_ENABLE); - } - - err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR, - MTK_INPUT); - if (err) - goto err; + /* regard all non-zero value as enable */ + err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_IES, !!arg); break; case PIN_CONFIG_SLEW_RATE: - err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SR, - arg); - if (err) - goto err; - + /* regard all non-zero value as enable */ + err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SR, !!arg); break; case PIN_CONFIG_OUTPUT: err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR, MTK_OUTPUT); if (err) - goto err; + break; err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DO, arg); - if (err) - goto err; break; + case PIN_CONFIG_INPUT_SCHMITT: case PIN_CONFIG_INPUT_SCHMITT_ENABLE: /* arg = 1: Input mode & SMT enable ; * arg = 0: Output mode & SMT disable */ - arg = arg ? 2 : 1; - err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR, - arg & 1); + err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR, !arg); if (err) - goto err; + break; - err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SMT, - !!(arg & 2)); - if (err) - goto err; + err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SMT, !!arg); break; case PIN_CONFIG_DRIVE_STRENGTH: - if (hw->soc->drive_set) { - err = hw->soc->drive_set(hw, desc, arg); - if (err) - return err; - } else { - return -ENOTSUPP; - } + if (!hw->soc->drive_set) + break; + err = hw->soc->drive_set(hw, desc, arg); break; case MTK_PIN_CONFIG_TDSEL: case MTK_PIN_CONFIG_RDSEL: reg = (param == MTK_PIN_CONFIG_TDSEL) ? PINCTRL_PIN_REG_TDSEL : PINCTRL_PIN_REG_RDSEL; - err = mtk_hw_set_value(hw, desc, reg, arg); - if (err) - goto err; break; case MTK_PIN_CONFIG_PU_ADV: case MTK_PIN_CONFIG_PD_ADV: - if (hw->soc->adv_pull_set) { - bool pullup; - - pullup = param == MTK_PIN_CONFIG_PU_ADV; - err = hw->soc->adv_pull_set(hw, desc, pullup, - arg); - if (err) - return err; - } else { - return -ENOTSUPP; - } + if (!hw->soc->adv_pull_set) + break; + err = hw->soc->adv_pull_set(hw, desc, + (param == MTK_PIN_CONFIG_PU_ADV), + arg); break; case MTK_PIN_CONFIG_DRV_ADV: - if (hw->soc->adv_drive_set) { - err = hw->soc->adv_drive_set(hw, desc, arg); - if (err) - return err; - } else { - return -ENOTSUPP; - } + if (!hw->soc->adv_drive_set) + break; + err = hw->soc->adv_drive_set(hw, desc, arg); break; - default: - err = -ENOTSUPP; } -err: return err; } @@ -690,6 +612,9 @@ static int mtk_gpio_get_direction(struct gpio_chip *chip, unsigned int gpio) const struct mtk_pin_desc *desc; int value, err; + if (gpio >= hw->soc->npins) + return -EINVAL; + desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio]; err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &value); @@ -705,6 +630,9 @@ static int mtk_gpio_get(struct gpio_chip *chip, unsigned int gpio) const struct mtk_pin_desc *desc; int value, err; + if (gpio >= hw->soc->npins) + return -EINVAL; + desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio]; err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DI, &value); @@ -719,6 +647,9 @@ static void mtk_gpio_set(struct gpio_chip *chip, unsigned int gpio, int value) struct mtk_pinctrl *hw = gpiochip_get_data(chip); const struct mtk_pin_desc *desc; + if (gpio >= hw->soc->npins) + return; + desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio]; mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DO, !!value); @@ -726,12 +657,22 @@ static void mtk_gpio_set(struct gpio_chip *chip, unsigned int gpio, int value) static int mtk_gpio_direction_input(struct gpio_chip *chip, unsigned int gpio) { + struct mtk_pinctrl *hw = gpiochip_get_data(chip); + + if (gpio >= hw->soc->npins) + return -EINVAL; + return pinctrl_gpio_direction_input(chip->base + gpio); } static int mtk_gpio_direction_output(struct gpio_chip *chip, unsigned int gpio, int value) { + struct mtk_pinctrl *hw = gpiochip_get_data(chip); + + if (gpio >= hw->soc->npins) + return -EINVAL; + mtk_gpio_set(chip, gpio, value); return pinctrl_gpio_direction_output(chip->base + gpio); diff --git a/drivers/platform/x86/xiaomi-wmi.c b/drivers/platform/x86/xiaomi-wmi.c index 601cbb282f54..54a2546bb93b 100644 --- a/drivers/platform/x86/xiaomi-wmi.c +++ b/drivers/platform/x86/xiaomi-wmi.c @@ -23,7 +23,7 @@ struct xiaomi_wmi { unsigned int key_code; }; -int xiaomi_wmi_probe(struct wmi_device *wdev, const void *context) +static int xiaomi_wmi_probe(struct wmi_device *wdev, const void *context) { struct xiaomi_wmi *data; @@ -48,7 +48,7 @@ int xiaomi_wmi_probe(struct wmi_device *wdev, const void *context) return input_register_device(data->input_dev); } -void xiaomi_wmi_notify(struct wmi_device *wdev, union acpi_object *dummy) +static void xiaomi_wmi_notify(struct wmi_device *wdev, union acpi_object *dummy) { struct xiaomi_wmi *data; diff --git a/drivers/power/supply/rt9455_charger.c b/drivers/power/supply/rt9455_charger.c index 29161ae90245..5864b31426b8 100644 --- a/drivers/power/supply/rt9455_charger.c +++ b/drivers/power/supply/rt9455_charger.c @@ -193,6 +193,7 @@ static const int rt9455_voreg_values[] = { 4450000, 4450000, 4450000, 4450000, 4450000, 4450000, 4450000, 4450000 }; +#if IS_ENABLED(CONFIG_USB_PHY) /* * When the charger is in boost mode, REG02[7:2] represent boost output * voltage. @@ -208,6 +209,7 @@ static const int rt9455_boost_voltage_values[] = { 5600000, 5600000, 5600000, 5600000, 5600000, 5600000, 5600000, 5600000, 5600000, 5600000, 5600000, 5600000, 5600000, 5600000, 5600000, 5600000, }; +#endif /* REG07[3:0] (VMREG) in uV */ static const int rt9455_vmreg_values[] = { diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 894915892eaf..5c50e7add577 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -1708,19 +1708,24 @@ static struct regulator *create_regulator(struct regulator_dev *rdev, } } - if (err != -EEXIST) + if (err != -EEXIST) { regulator->debugfs = debugfs_create_dir(supply_name, rdev->debugfs); - if (IS_ERR(regulator->debugfs)) - rdev_dbg(rdev, "Failed to create debugfs directory\n"); + if (IS_ERR(regulator->debugfs)) { + rdev_dbg(rdev, "Failed to create debugfs directory\n"); + regulator->debugfs = NULL; + } + } - debugfs_create_u32("uA_load", 0444, regulator->debugfs, - ®ulator->uA_load); - debugfs_create_u32("min_uV", 0444, regulator->debugfs, - ®ulator->voltage[PM_SUSPEND_ON].min_uV); - debugfs_create_u32("max_uV", 0444, regulator->debugfs, - ®ulator->voltage[PM_SUSPEND_ON].max_uV); - debugfs_create_file("constraint_flags", 0444, regulator->debugfs, - regulator, &constraint_flags_fops); + if (regulator->debugfs) { + debugfs_create_u32("uA_load", 0444, regulator->debugfs, + ®ulator->uA_load); + debugfs_create_u32("min_uV", 0444, regulator->debugfs, + ®ulator->voltage[PM_SUSPEND_ON].min_uV); + debugfs_create_u32("max_uV", 0444, regulator->debugfs, + ®ulator->voltage[PM_SUSPEND_ON].max_uV); + debugfs_create_file("constraint_flags", 0444, regulator->debugfs, + regulator, &constraint_flags_fops); + } /* * Check now if the regulator is an always on regulator - if diff --git a/drivers/s390/cio/trace.h b/drivers/s390/cio/trace.h index 4803139bce14..4716798b1368 100644 --- a/drivers/s390/cio/trace.h +++ b/drivers/s390/cio/trace.h @@ -50,7 +50,7 @@ DECLARE_EVENT_CLASS(s390_class_schib, __entry->devno = schib->pmcw.dev; __entry->schib = *schib; __entry->pmcw_ena = schib->pmcw.ena; - __entry->pmcw_st = schib->pmcw.ena; + __entry->pmcw_st = schib->pmcw.st; __entry->pmcw_dnv = schib->pmcw.dnv; __entry->pmcw_dev = schib->pmcw.dev; __entry->pmcw_lpm = schib->pmcw.lpm; diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c index fb1de363fb28..7033d61cca6b 100644 --- a/drivers/s390/crypto/ap_bus.c +++ b/drivers/s390/crypto/ap_bus.c @@ -947,7 +947,7 @@ static int hex2bitmap(const char *str, unsigned long *bitmap, int bits) */ static int modify_bitmap(const char *str, unsigned long *bitmap, int bits) { - int a, i, z; + unsigned long a, i, z; char *np, sign; /* bits needs to be a multiple of 8 */ diff --git a/drivers/scsi/bfa/bfad_debugfs.c b/drivers/scsi/bfa/bfad_debugfs.c index fd1b378a263a..d3c7d4423c51 100644 --- a/drivers/scsi/bfa/bfad_debugfs.c +++ b/drivers/scsi/bfa/bfad_debugfs.c @@ -250,7 +250,7 @@ bfad_debugfs_write_regrd(struct file *file, const char __user *buf, unsigned long flags; void *kern_buf; - kern_buf = memdup_user(buf, nbytes); + kern_buf = memdup_user_nul(buf, nbytes); if (IS_ERR(kern_buf)) return PTR_ERR(kern_buf); @@ -317,7 +317,7 @@ bfad_debugfs_write_regwr(struct file *file, const char __user *buf, unsigned long flags; void *kern_buf; - kern_buf = memdup_user(buf, nbytes); + kern_buf = memdup_user_nul(buf, nbytes); if (IS_ERR(kern_buf)) return PTR_ERR(kern_buf); diff --git a/drivers/scsi/bnx2fc/bnx2fc_tgt.c b/drivers/scsi/bnx2fc/bnx2fc_tgt.c index 50384b4a817c..5b184c8384d0 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_tgt.c +++ b/drivers/scsi/bnx2fc/bnx2fc_tgt.c @@ -834,7 +834,6 @@ static void bnx2fc_free_session_resc(struct bnx2fc_hba *hba, BNX2FC_TGT_DBG(tgt, "Freeing up session resources\n"); - spin_lock_bh(&tgt->cq_lock); ctx_base_ptr = tgt->ctx_base; tgt->ctx_base = NULL; @@ -890,7 +889,6 @@ static void bnx2fc_free_session_resc(struct bnx2fc_hba *hba, tgt->sq, tgt->sq_dma); tgt->sq = NULL; } - spin_unlock_bh(&tgt->cq_lock); if (ctx_base_ptr) iounmap(ctx_base_ptr); diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index e670cce0cb6e..b760477b5742 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c @@ -5810,7 +5810,7 @@ static int hpsa_scsi_host_alloc(struct ctlr_info *h) { struct Scsi_Host *sh; - sh = scsi_host_alloc(&hpsa_driver_template, sizeof(struct ctlr_info)); + sh = scsi_host_alloc(&hpsa_driver_template, sizeof(struct ctlr_info *)); if (sh == NULL) { dev_err(&h->pdev->dev, "scsi_host_alloc failed\n"); return -ENOMEM; diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c index 173f91ae38f0..295941e41433 100644 --- a/drivers/scsi/libsas/sas_expander.c +++ b/drivers/scsi/libsas/sas_expander.c @@ -256,8 +256,7 @@ static void sas_set_ex_phy(struct domain_device *dev, int phy_id, void *rsp) /* help some expanders that fail to zero sas_address in the 'no * device' case */ - if (phy->attached_dev_type == SAS_PHY_UNUSED || - phy->linkrate < SAS_LINK_RATE_1_5_GBPS) + if (phy->attached_dev_type == SAS_PHY_UNUSED) memset(phy->attached_sas_addr, 0, SAS_ADDR_SIZE); else memcpy(phy->attached_sas_addr, dr->attached_sas_addr, SAS_ADDR_SIZE); diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index 7ce0d94cdc01..98ab07c3774e 100644 --- a/drivers/scsi/lpfc/lpfc.h +++ b/drivers/scsi/lpfc/lpfc.h @@ -1039,7 +1039,6 @@ struct lpfc_hba { unsigned long bit_flags; #define FABRIC_COMANDS_BLOCKED 0 atomic_t num_rsrc_err; - atomic_t num_cmd_success; unsigned long last_rsrc_error_time; unsigned long last_ramp_down_time; #ifdef CONFIG_SCSI_LPFC_DEBUG_FS diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 816235ccd299..f238e0f41f07 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -246,11 +246,10 @@ lpfc_ramp_down_queue_handler(struct lpfc_hba *phba) struct Scsi_Host *shost; struct scsi_device *sdev; unsigned long new_queue_depth; - unsigned long num_rsrc_err, num_cmd_success; + unsigned long num_rsrc_err; int i; num_rsrc_err = atomic_read(&phba->num_rsrc_err); - num_cmd_success = atomic_read(&phba->num_cmd_success); /* * The error and success command counters are global per @@ -265,20 +264,16 @@ lpfc_ramp_down_queue_handler(struct lpfc_hba *phba) for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) { shost = lpfc_shost_from_vport(vports[i]); shost_for_each_device(sdev, shost) { - new_queue_depth = - sdev->queue_depth * num_rsrc_err / - (num_rsrc_err + num_cmd_success); - if (!new_queue_depth) - new_queue_depth = sdev->queue_depth - 1; + if (num_rsrc_err >= sdev->queue_depth) + new_queue_depth = 1; else new_queue_depth = sdev->queue_depth - - new_queue_depth; + num_rsrc_err; scsi_change_queue_depth(sdev, new_queue_depth); } } lpfc_destroy_vport_work_array(phba, vports); atomic_set(&phba->num_rsrc_err, 0); - atomic_set(&phba->num_cmd_success, 0); } /** diff --git a/drivers/scsi/qedf/qedf_debugfs.c b/drivers/scsi/qedf/qedf_debugfs.c index b0a28a6a9c64..41e7fab99013 100644 --- a/drivers/scsi/qedf/qedf_debugfs.c +++ b/drivers/scsi/qedf/qedf_debugfs.c @@ -172,7 +172,7 @@ qedf_dbg_debug_cmd_write(struct file *filp, const char __user *buffer, if (!count || *ppos) return 0; - kern_buf = memdup_user(buffer, count); + kern_buf = memdup_user_nul(buffer, count); if (IS_ERR(kern_buf)) return PTR_ERR(kern_buf); diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 8a0ac87f70a9..11ee2c7487b2 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -4479,7 +4479,7 @@ qla2x00_set_model_info(scsi_qla_host_t *vha, uint8_t *model, size_t len, if (use_tbl && ha->pdev->subsystem_vendor == PCI_VENDOR_ID_QLOGIC && index < QLA_MODEL_NAMES) - strlcpy(ha->model_desc, + strscpy(ha->model_desc, qla2x00_model_name[index * 2 + 1], sizeof(ha->model_desc)); } else { @@ -4487,14 +4487,14 @@ qla2x00_set_model_info(scsi_qla_host_t *vha, uint8_t *model, size_t len, if (use_tbl && ha->pdev->subsystem_vendor == PCI_VENDOR_ID_QLOGIC && index < QLA_MODEL_NAMES) { - strlcpy(ha->model_number, + strscpy(ha->model_number, qla2x00_model_name[index * 2], sizeof(ha->model_number)); - strlcpy(ha->model_desc, + strscpy(ha->model_desc, qla2x00_model_name[index * 2 + 1], sizeof(ha->model_desc)); } else { - strlcpy(ha->model_number, def, + strscpy(ha->model_number, def, sizeof(ha->model_number)); } } diff --git a/drivers/scsi/qla2xxx/qla_mr.c b/drivers/scsi/qla2xxx/qla_mr.c index badd09c5dd42..6b44be4ce5bd 100644 --- a/drivers/scsi/qla2xxx/qla_mr.c +++ b/drivers/scsi/qla2xxx/qla_mr.c @@ -693,7 +693,7 @@ qlafx00_pci_info_str(struct scsi_qla_host *vha, char *str, size_t str_len) struct qla_hw_data *ha = vha->hw; if (pci_is_pcie(ha->pdev)) - strlcpy(str, "PCIe iSA", str_len); + strscpy(str, "PCIe iSA", str_len); return str; } @@ -1854,21 +1854,21 @@ qlafx00_fx_disc(scsi_qla_host_t *vha, fc_port_t *fcport, uint16_t fx_type) phost_info = &preg_hsi->hsi; memset(preg_hsi, 0, sizeof(struct register_host_info)); phost_info->os_type = OS_TYPE_LINUX; - strlcpy(phost_info->sysname, p_sysid->sysname, + strscpy(phost_info->sysname, p_sysid->sysname, sizeof(phost_info->sysname)); - strlcpy(phost_info->nodename, p_sysid->nodename, + strscpy(phost_info->nodename, p_sysid->nodename, sizeof(phost_info->nodename)); if (!strcmp(phost_info->nodename, "(none)")) ha->mr.host_info_resend = true; - strlcpy(phost_info->release, p_sysid->release, + strscpy(phost_info->release, p_sysid->release, sizeof(phost_info->release)); - strlcpy(phost_info->version, p_sysid->version, + strscpy(phost_info->version, p_sysid->version, sizeof(phost_info->version)); - strlcpy(phost_info->machine, p_sysid->machine, + strscpy(phost_info->machine, p_sysid->machine, sizeof(phost_info->machine)); - strlcpy(phost_info->domainname, p_sysid->domainname, + strscpy(phost_info->domainname, p_sysid->domainname, sizeof(phost_info->domainname)); - strlcpy(phost_info->hostdriver, QLA2XXX_VERSION, + strscpy(phost_info->hostdriver, QLA2XXX_VERSION, sizeof(phost_info->hostdriver)); preg_hsi->utc = (uint64_t)ktime_get_real_seconds(); ql_dbg(ql_dbg_init, vha, 0x0149, @@ -1914,9 +1914,9 @@ qlafx00_fx_disc(scsi_qla_host_t *vha, fc_port_t *fcport, uint16_t fx_type) if (fx_type == FXDISC_GET_CONFIG_INFO) { struct config_info_data *pinfo = (struct config_info_data *) fdisc->u.fxiocb.rsp_addr; - strlcpy(vha->hw->model_number, pinfo->model_num, + strscpy(vha->hw->model_number, pinfo->model_num, ARRAY_SIZE(vha->hw->model_number)); - strlcpy(vha->hw->model_desc, pinfo->model_description, + strscpy(vha->hw->model_desc, pinfo->model_description, ARRAY_SIZE(vha->hw->model_desc)); memcpy(&vha->hw->mr.symbolic_name, pinfo->symbolic_name, sizeof(vha->hw->mr.symbolic_name)); diff --git a/drivers/scsi/ufs/cdns-pltfrm.c b/drivers/scsi/ufs/cdns-pltfrm.c index 6feeb0faf123..9d6bb4716870 100644 --- a/drivers/scsi/ufs/cdns-pltfrm.c +++ b/drivers/scsi/ufs/cdns-pltfrm.c @@ -56,7 +56,7 @@ static int cdns_ufs_set_hclkdiv(struct ufs_hba *hba) * Make sure the register was updated, * UniPro layer will not work with an incorrect value. */ - mb(); + ufshcd_readl(hba, CDNS_UFS_REG_HCLKDIV); return 0; } diff --git a/drivers/scsi/ufs/ufs-qcom.h b/drivers/scsi/ufs/ufs-qcom.h index d401f174bb70..3220345682a9 100644 --- a/drivers/scsi/ufs/ufs-qcom.h +++ b/drivers/scsi/ufs/ufs-qcom.h @@ -155,10 +155,10 @@ static inline void ufs_qcom_assert_reset(struct ufs_hba *hba) 1 << OFFSET_UFS_PHY_SOFT_RESET, REG_UFS_CFG1); /* - * Make sure assertion of ufs phy reset is written to - * register before returning + * Dummy read to ensure the write takes effect before doing any sort + * of delay */ - mb(); + ufshcd_readl(hba, REG_UFS_CFG1); } static inline void ufs_qcom_deassert_reset(struct ufs_hba *hba) @@ -167,10 +167,10 @@ static inline void ufs_qcom_deassert_reset(struct ufs_hba *hba) 0 << OFFSET_UFS_PHY_SOFT_RESET, REG_UFS_CFG1); /* - * Make sure de-assertion of ufs phy reset is written to - * register before returning + * Dummy read to ensure the write takes effect before doing any sort + * of delay */ - mb(); + ufshcd_readl(hba, REG_UFS_CFG1); } struct ufs_qcom_bus_vote { diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 363adf489079..e54a08f96a50 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -3731,7 +3731,7 @@ static int ufshcd_uic_pwr_ctrl(struct ufs_hba *hba, struct uic_command *cmd) * Make sure UIC command completion interrupt is disabled before * issuing UIC command. */ - wmb(); + ufshcd_readl(hba, REG_INTERRUPT_ENABLE); reenable_intr = true; } ret = __ufshcd_send_uic_cmd(hba, cmd, false); @@ -8424,7 +8424,7 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq) * Make sure that UFS interrupts are disabled and any pending interrupt * status is cleared before registering UFS interrupt handler. */ - mb(); + ufshcd_readl(hba, REG_INTERRUPT_ENABLE); /* IRQ registration */ err = devm_request_irq(dev, irq, ufshcd_intr, IRQF_SHARED, UFSHCD, hba); diff --git a/drivers/soundwire/cadence_master.c b/drivers/soundwire/cadence_master.c index f7d0f63921dc..07c252603380 100644 --- a/drivers/soundwire/cadence_master.c +++ b/drivers/soundwire/cadence_master.c @@ -183,9 +183,6 @@ MODULE_PARM_DESC(cdns_mcp_int_mask, "Cadence MCP IntMask"); #define CDNS_DEFAULT_SSP_INTERVAL 0x18 #define CDNS_TX_TIMEOUT 2000 -#define CDNS_PCM_PDI_OFFSET 0x2 -#define CDNS_PDM_PDI_OFFSET 0x6 - #define CDNS_SCP_RX_FIFOLEVEL 0x2 /* @@ -295,11 +292,7 @@ static int cdns_reg_show(struct seq_file *s, void *data) ret += scnprintf(buf + ret, RD_BUF - ret, "\nDPn B0 Registers\n"); - /* - * in sdw_cdns_pdi_init() we filter out the Bulk PDIs, - * so the indices need to be corrected again - */ - num_ports = cdns->num_ports + CDNS_PCM_PDI_OFFSET; + num_ports = cdns->num_ports; for (i = 0; i < num_ports; i++) { ret += scnprintf(buf + ret, RD_BUF - ret, @@ -852,7 +845,6 @@ static int cdns_allocate_pdi(struct sdw_cdns *cdns, for (i = 0; i < num; i++) { pdi[i].num = i + pdi_offset; - pdi[i].assigned = false; } *stream = pdi; @@ -869,7 +861,8 @@ int sdw_cdns_pdi_init(struct sdw_cdns *cdns, struct sdw_cdns_stream_config config) { struct sdw_cdns_streams *stream; - int offset, i, ret; + int offset; + int ret; cdns->pcm.num_bd = config.pcm_bd; cdns->pcm.num_in = config.pcm_in; @@ -881,11 +874,8 @@ int sdw_cdns_pdi_init(struct sdw_cdns *cdns, /* Allocate PDIs for PCMs */ stream = &cdns->pcm; - /* First two PDIs are reserved for bulk transfers */ - if (stream->num_bd < CDNS_PCM_PDI_OFFSET) - return -EINVAL; - stream->num_bd -= CDNS_PCM_PDI_OFFSET; - offset = CDNS_PCM_PDI_OFFSET; + /* we allocate PDI0 and PDI1 which are used for Bulk */ + offset = 0; ret = cdns_allocate_pdi(cdns, &stream->bd, stream->num_bd, offset); @@ -912,7 +902,6 @@ int sdw_cdns_pdi_init(struct sdw_cdns *cdns, /* Allocate PDIs for PDMs */ stream = &cdns->pdm; - offset = CDNS_PDM_PDI_OFFSET; ret = cdns_allocate_pdi(cdns, &stream->bd, stream->num_bd, offset); if (ret) @@ -929,6 +918,9 @@ int sdw_cdns_pdi_init(struct sdw_cdns *cdns, ret = cdns_allocate_pdi(cdns, &stream->out, stream->num_out, offset); + + offset += stream->num_out; + if (ret) return ret; @@ -936,18 +928,6 @@ int sdw_cdns_pdi_init(struct sdw_cdns *cdns, stream->num_pdi = stream->num_bd + stream->num_in + stream->num_out; cdns->num_ports += stream->num_pdi; - cdns->ports = devm_kcalloc(cdns->dev, cdns->num_ports, - sizeof(*cdns->ports), GFP_KERNEL); - if (!cdns->ports) { - ret = -ENOMEM; - return ret; - } - - for (i = 0; i < cdns->num_ports; i++) { - cdns->ports[i].assigned = false; - cdns->ports[i].num = i + 1; /* Port 0 reserved for bulk */ - } - return 0; } EXPORT_SYMBOL(sdw_cdns_pdi_init); @@ -1217,20 +1197,20 @@ EXPORT_SYMBOL(cdns_set_sdw_stream); * @num: Number of PDIs * @pdi: PDI instances * - * Find and return a free PDI for a given PDI array + * Find a PDI for a given PDI array. The PDI num and dai_id are + * expected to match, return NULL otherwise. */ static struct sdw_cdns_pdi *cdns_find_pdi(struct sdw_cdns *cdns, + unsigned int offset, unsigned int num, - struct sdw_cdns_pdi *pdi) + struct sdw_cdns_pdi *pdi, + int dai_id) { int i; - for (i = 0; i < num; i++) { - if (pdi[i].assigned) - continue; - pdi[i].assigned = true; - return &pdi[i]; - } + for (i = offset; i < offset + num; i++) + if (pdi[i].num == dai_id) + return &pdi[i]; return NULL; } @@ -1239,13 +1219,11 @@ static struct sdw_cdns_pdi *cdns_find_pdi(struct sdw_cdns *cdns, * sdw_cdns_config_stream: Configure a stream * * @cdns: Cadence instance - * @port: Cadence data port * @ch: Channel count * @dir: Data direction * @pdi: PDI to be used */ void sdw_cdns_config_stream(struct sdw_cdns *cdns, - struct sdw_cdns_port *port, u32 ch, u32 dir, struct sdw_cdns_pdi *pdi) { u32 offset, val = 0; @@ -1253,113 +1231,51 @@ void sdw_cdns_config_stream(struct sdw_cdns *cdns, if (dir == SDW_DATA_DIR_RX) val = CDNS_PORTCTRL_DIRN; - offset = CDNS_PORTCTRL + port->num * CDNS_PORT_OFFSET; + offset = CDNS_PORTCTRL + pdi->num * CDNS_PORT_OFFSET; cdns_updatel(cdns, offset, CDNS_PORTCTRL_DIRN, val); - val = port->num; + val = pdi->num; val |= ((1 << ch) - 1) << SDW_REG_SHIFT(CDNS_PDI_CONFIG_CHANNEL); cdns_writel(cdns, CDNS_PDI_CONFIG(pdi->num), val); } EXPORT_SYMBOL(sdw_cdns_config_stream); /** - * cdns_get_num_pdi() - Get number of PDIs required - * - * @cdns: Cadence instance - * @pdi: PDI to be used - * @num: Number of PDIs - * @ch_count: Channel count - */ -static int cdns_get_num_pdi(struct sdw_cdns *cdns, - struct sdw_cdns_pdi *pdi, - unsigned int num, u32 ch_count) -{ - int i, pdis = 0; - - for (i = 0; i < num; i++) { - if (pdi[i].assigned) - continue; - - if (pdi[i].ch_count < ch_count) - ch_count -= pdi[i].ch_count; - else - ch_count = 0; - - pdis++; - - if (!ch_count) - break; - } - - if (ch_count) - return 0; - - return pdis; -} - -/** - * sdw_cdns_get_stream() - Get stream information + * sdw_cdns_alloc_pdi() - Allocate a PDI * * @cdns: Cadence instance * @stream: Stream to be allocated * @ch: Channel count * @dir: Data direction */ -int sdw_cdns_get_stream(struct sdw_cdns *cdns, - struct sdw_cdns_streams *stream, - u32 ch, u32 dir) -{ - int pdis = 0; - - if (dir == SDW_DATA_DIR_RX) - pdis = cdns_get_num_pdi(cdns, stream->in, stream->num_in, ch); - else - pdis = cdns_get_num_pdi(cdns, stream->out, stream->num_out, ch); - - /* check if we found PDI, else find in bi-directional */ - if (!pdis) - pdis = cdns_get_num_pdi(cdns, stream->bd, stream->num_bd, ch); - - return pdis; -} -EXPORT_SYMBOL(sdw_cdns_get_stream); - -/** - * sdw_cdns_alloc_stream() - Allocate a stream - * - * @cdns: Cadence instance - * @stream: Stream to be allocated - * @port: Cadence data port - * @ch: Channel count - * @dir: Data direction - */ -int sdw_cdns_alloc_stream(struct sdw_cdns *cdns, - struct sdw_cdns_streams *stream, - struct sdw_cdns_port *port, u32 ch, u32 dir) +struct sdw_cdns_pdi *sdw_cdns_alloc_pdi(struct sdw_cdns *cdns, + struct sdw_cdns_streams *stream, + u32 ch, u32 dir, int dai_id) { struct sdw_cdns_pdi *pdi = NULL; if (dir == SDW_DATA_DIR_RX) - pdi = cdns_find_pdi(cdns, stream->num_in, stream->in); + pdi = cdns_find_pdi(cdns, 0, stream->num_in, stream->in, + dai_id); else - pdi = cdns_find_pdi(cdns, stream->num_out, stream->out); + pdi = cdns_find_pdi(cdns, 0, stream->num_out, stream->out, + dai_id); /* check if we found a PDI, else find in bi-directional */ if (!pdi) - pdi = cdns_find_pdi(cdns, stream->num_bd, stream->bd); - - if (!pdi) - return -EIO; - - port->pdi = pdi; - pdi->l_ch_num = 0; - pdi->h_ch_num = ch - 1; - pdi->dir = dir; - pdi->ch_count = ch; + pdi = cdns_find_pdi(cdns, 0, stream->num_bd, stream->bd, + dai_id); + + if (pdi) { + pdi->l_ch_num = 0; + pdi->h_ch_num = ch - 1; + pdi->dir = dir; + pdi->ch_count = ch; + } - return 0; + return pdi; } -EXPORT_SYMBOL(sdw_cdns_alloc_stream); +EXPORT_SYMBOL(sdw_cdns_alloc_pdi); MODULE_LICENSE("Dual BSD/GPL"); MODULE_DESCRIPTION("Cadence Soundwire Library"); diff --git a/drivers/soundwire/cadence_master.h b/drivers/soundwire/cadence_master.h index 1a67728c5000..6199e71edeab 100644 --- a/drivers/soundwire/cadence_master.h +++ b/drivers/soundwire/cadence_master.h @@ -8,7 +8,6 @@ /** * struct sdw_cdns_pdi: PDI (Physical Data Interface) instance * - * @assigned: pdi assigned * @num: pdi number * @intel_alh_id: link identifier * @l_ch_num: low channel for PDI @@ -18,7 +17,6 @@ * @type: stream type, PDM or PCM */ struct sdw_cdns_pdi { - bool assigned; int num; int intel_alh_id; int l_ch_num; @@ -29,23 +27,6 @@ struct sdw_cdns_pdi { }; /** - * struct sdw_cdns_port: Cadence port structure - * - * @num: port number - * @assigned: port assigned - * @ch: channel count - * @direction: data port direction - * @pdi: pdi for this port - */ -struct sdw_cdns_port { - unsigned int num; - bool assigned; - unsigned int ch; - enum sdw_data_direction direction; - struct sdw_cdns_pdi *pdi; -}; - -/** * struct sdw_cdns_streams: Cadence stream data structure * * @num_bd: number of bidirectional streams @@ -95,8 +76,8 @@ struct sdw_cdns_stream_config { * struct sdw_cdns_dma_data: Cadence DMA data * * @name: SoundWire stream name - * @nr_ports: Number of ports - * @port: Ports + * @stream: stream runtime + * @pdi: PDI used for this dai * @bus: Bus handle * @stream_type: Stream type * @link_id: Master link id @@ -104,8 +85,7 @@ struct sdw_cdns_stream_config { struct sdw_cdns_dma_data { char *name; struct sdw_stream_runtime *stream; - int nr_ports; - struct sdw_cdns_port **port; + struct sdw_cdns_pdi *pdi; struct sdw_bus *bus; enum sdw_stream_type stream_type; int link_id; @@ -171,10 +151,10 @@ void sdw_cdns_debugfs_init(struct sdw_cdns *cdns, struct dentry *root); int sdw_cdns_get_stream(struct sdw_cdns *cdns, struct sdw_cdns_streams *stream, u32 ch, u32 dir); -int sdw_cdns_alloc_stream(struct sdw_cdns *cdns, - struct sdw_cdns_streams *stream, - struct sdw_cdns_port *port, u32 ch, u32 dir); -void sdw_cdns_config_stream(struct sdw_cdns *cdns, struct sdw_cdns_port *port, +struct sdw_cdns_pdi *sdw_cdns_alloc_pdi(struct sdw_cdns *cdns, + struct sdw_cdns_streams *stream, + u32 ch, u32 dir, int dai_id); +void sdw_cdns_config_stream(struct sdw_cdns *cdns, u32 ch, u32 dir, struct sdw_cdns_pdi *pdi); int sdw_cdns_pcm_set_stream(struct snd_soc_dai *dai, diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c index a2da04946f0b..7470adfaabf3 100644 --- a/drivers/soundwire/intel.c +++ b/drivers/soundwire/intel.c @@ -609,66 +609,6 @@ static int intel_post_bank_switch(struct sdw_bus *bus) * DAI routines */ -static struct sdw_cdns_port *intel_alloc_port(struct sdw_intel *sdw, - u32 ch, u32 dir, bool pcm) -{ - struct sdw_cdns *cdns = &sdw->cdns; - struct sdw_cdns_port *port = NULL; - int i, ret = 0; - - for (i = 0; i < cdns->num_ports; i++) { - if (cdns->ports[i].assigned) - continue; - - port = &cdns->ports[i]; - port->assigned = true; - port->direction = dir; - port->ch = ch; - break; - } - - if (!port) { - dev_err(cdns->dev, "Unable to find a free port\n"); - return NULL; - } - - if (pcm) { - ret = sdw_cdns_alloc_stream(cdns, &cdns->pcm, port, ch, dir); - if (ret) - goto out; - - intel_pdi_shim_configure(sdw, port->pdi); - sdw_cdns_config_stream(cdns, port, ch, dir, port->pdi); - - intel_pdi_alh_configure(sdw, port->pdi); - - } else { - ret = sdw_cdns_alloc_stream(cdns, &cdns->pdm, port, ch, dir); - } - -out: - if (ret) { - port->assigned = false; - port = NULL; - } - - return port; -} - -static void intel_port_cleanup(struct sdw_cdns_dma_data *dma) -{ - int i; - - for (i = 0; i < dma->nr_ports; i++) { - if (dma->port[i]) { - dma->port[i]->pdi->assigned = false; - dma->port[i]->pdi = NULL; - dma->port[i]->assigned = false; - dma->port[i] = NULL; - } - } -} - static int intel_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) @@ -676,9 +616,11 @@ static int intel_hw_params(struct snd_pcm_substream *substream, struct sdw_cdns *cdns = snd_soc_dai_get_drvdata(dai); struct sdw_intel *sdw = cdns_to_intel(cdns); struct sdw_cdns_dma_data *dma; + struct sdw_cdns_pdi *pdi; struct sdw_stream_config sconfig; struct sdw_port_config *pconfig; - int ret, i, ch, dir; + int ch, dir; + int ret; bool pcm = true; dma = snd_soc_dai_get_dma_data(dai, substream); @@ -691,38 +633,30 @@ static int intel_hw_params(struct snd_pcm_substream *substream, else dir = SDW_DATA_DIR_TX; - if (dma->stream_type == SDW_STREAM_PDM) { - /* TODO: Check whether PDM decimator is already in use */ - dma->nr_ports = sdw_cdns_get_stream(cdns, &cdns->pdm, ch, dir); + if (dma->stream_type == SDW_STREAM_PDM) pcm = false; - } else { - dma->nr_ports = sdw_cdns_get_stream(cdns, &cdns->pcm, ch, dir); - } - if (!dma->nr_ports) { - dev_err(dai->dev, "ports/resources not available\n"); - return -EINVAL; + if (pcm) + pdi = sdw_cdns_alloc_pdi(cdns, &cdns->pcm, ch, dir, dai->id); + else + pdi = sdw_cdns_alloc_pdi(cdns, &cdns->pdm, ch, dir, dai->id); + + if (!pdi) { + ret = -EINVAL; + goto error; } - dma->port = kcalloc(dma->nr_ports, sizeof(*dma->port), GFP_KERNEL); - if (!dma->port) - return -ENOMEM; + /* do run-time configurations for SHIM, ALH and PDI/PORT */ + intel_pdi_shim_configure(sdw, pdi); + intel_pdi_alh_configure(sdw, pdi); + sdw_cdns_config_stream(cdns, ch, dir, pdi); - for (i = 0; i < dma->nr_ports; i++) { - dma->port[i] = intel_alloc_port(sdw, ch, dir, pcm); - if (!dma->port[i]) { - ret = -EINVAL; - goto port_error; - } - } /* Inform DSP about PDI stream number */ - for (i = 0; i < dma->nr_ports; i++) { - ret = intel_config_stream(sdw, substream, dai, params, - dma->port[i]->pdi->intel_alh_id); - if (ret) - goto port_error; - } + ret = intel_config_stream(sdw, substream, dai, params, + pdi->intel_alh_id); + if (ret) + goto error; sconfig.direction = dir; sconfig.ch_count = ch; @@ -737,32 +671,22 @@ static int intel_hw_params(struct snd_pcm_substream *substream, } /* Port configuration */ - pconfig = kcalloc(dma->nr_ports, sizeof(*pconfig), GFP_KERNEL); + pconfig = kcalloc(1, sizeof(*pconfig), GFP_KERNEL); if (!pconfig) { ret = -ENOMEM; - goto port_error; + goto error; } - for (i = 0; i < dma->nr_ports; i++) { - pconfig[i].num = dma->port[i]->num; - pconfig[i].ch_mask = (1 << ch) - 1; - } + pconfig->num = pdi->num; + pconfig->ch_mask = (1 << ch) - 1; ret = sdw_stream_add_master(&cdns->bus, &sconfig, - pconfig, dma->nr_ports, dma->stream); - if (ret) { + pconfig, 1, dma->stream); + if (ret) dev_err(cdns->dev, "add master to stream failed:%d\n", ret); - goto stream_error; - } - - kfree(pconfig); - return ret; -stream_error: kfree(pconfig); -port_error: - intel_port_cleanup(dma); - kfree(dma->port); +error: return ret; } @@ -782,8 +706,6 @@ intel_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) dev_err(dai->dev, "remove master from stream %s failed: %d\n", dma->stream->name, ret); - intel_port_cleanup(dma); - kfree(dma->port); return ret; } diff --git a/drivers/spi/spi-stm32.c b/drivers/spi/spi-stm32.c index e843e9453c71..759c502b094d 100644 --- a/drivers/spi/spi-stm32.c +++ b/drivers/spi/spi-stm32.c @@ -927,7 +927,7 @@ static irqreturn_t stm32h7_spi_irq_thread(int irq, void *dev_id) mask |= STM32H7_SPI_SR_TXP | STM32H7_SPI_SR_RXP; if (!(sr & mask)) { - dev_warn(spi->dev, "spurious IT (sr=0x%08x, ier=0x%08x)\n", + dev_vdbg(spi->dev, "spurious IT (sr=0x%08x, ier=0x%08x)\n", sr, ier); spin_unlock_irqrestore(&spi->lock, flags); return IRQ_NONE; diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index b18ae50db1f5..0f9410ed4829 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -931,6 +931,7 @@ static int __spi_map_msg(struct spi_controller *ctlr, struct spi_message *msg) else rx_dev = ctlr->dev.parent; + ret = -ENOMSG; list_for_each_entry(xfer, &msg->transfers, transfer_list) { if (!ctlr->can_dma(ctlr, msg->spi, xfer)) continue; @@ -954,6 +955,9 @@ static int __spi_map_msg(struct spi_controller *ctlr, struct spi_message *msg) } } } + /* No transfer has been mapped, bail out with success */ + if (ret) + return 0; ctlr->cur_msg_mapped = true; diff --git a/drivers/staging/greybus/arche-apb-ctrl.c b/drivers/staging/greybus/arche-apb-ctrl.c index bbf3ba744fc4..c7383c6c6094 100644 --- a/drivers/staging/greybus/arche-apb-ctrl.c +++ b/drivers/staging/greybus/arche-apb-ctrl.c @@ -468,6 +468,7 @@ static const struct of_device_id arche_apb_ctrl_of_match[] = { { .compatible = "usbffff,2", }, { }, }; +MODULE_DEVICE_TABLE(of, arche_apb_ctrl_of_match); static struct platform_driver arche_apb_ctrl_device_driver = { .probe = arche_apb_ctrl_probe, diff --git a/drivers/staging/greybus/arche-platform.c b/drivers/staging/greybus/arche-platform.c index eebf0deb39f5..02a700f720e6 100644 --- a/drivers/staging/greybus/arche-platform.c +++ b/drivers/staging/greybus/arche-platform.c @@ -622,14 +622,7 @@ static const struct of_device_id arche_platform_of_match[] = { { .compatible = "google,arche-platform", }, { }, }; - -static const struct of_device_id arche_combined_id[] = { - /* Use PID/VID of SVC device */ - { .compatible = "google,arche-platform", }, - { .compatible = "usbffff,2", }, - { }, -}; -MODULE_DEVICE_TABLE(of, arche_combined_id); +MODULE_DEVICE_TABLE(of, arche_platform_of_match); static struct platform_driver arche_platform_device_driver = { .probe = arche_platform_probe, diff --git a/drivers/staging/greybus/light.c b/drivers/staging/greybus/light.c index e59bb27236b9..7352d7deb8ba 100644 --- a/drivers/staging/greybus/light.c +++ b/drivers/staging/greybus/light.c @@ -147,6 +147,9 @@ static int __gb_lights_flash_brightness_set(struct gb_channel *channel) channel = get_channel_from_mode(channel->light, GB_CHANNEL_MODE_TORCH); + if (!channel) + return -EINVAL; + /* For not flash we need to convert brightness to intensity */ intensity = channel->intensity_uA.min + (channel->intensity_uA.step * channel->led->brightness); @@ -550,7 +553,10 @@ static int gb_lights_light_v4l2_register(struct gb_light *light) } channel_flash = get_channel_from_mode(light, GB_CHANNEL_MODE_FLASH); - WARN_ON(!channel_flash); + if (!channel_flash) { + dev_err(dev, "failed to get flash channel from mode\n"); + return -EINVAL; + } fled = &channel_flash->fled; diff --git a/drivers/staging/speakup/main.c b/drivers/staging/speakup/main.c index 08b07e77bb9d..876122503c8a 100644 --- a/drivers/staging/speakup/main.c +++ b/drivers/staging/speakup/main.c @@ -577,7 +577,7 @@ static u_long get_word(struct vc_data *vc) } attr_ch = get_char(vc, (u_short *)tmp_pos, &spk_attr); buf[cnt++] = attr_ch; - while (tmpx < vc->vc_cols - 1 && cnt < sizeof(buf) - 1) { + while (tmpx < vc->vc_cols - 1 && cnt < ARRAY_SIZE(buf) - 1) { tmp_pos += 2; tmpx++; ch = get_char(vc, (u_short *)tmp_pos, &temp); diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c index e6e175597860..4edabab65b87 100644 --- a/drivers/target/target_core_configfs.c +++ b/drivers/target/target_core_configfs.c @@ -3458,6 +3458,8 @@ static int __init target_core_init_configfs(void) { struct configfs_subsystem *subsys = &target_core_fabrics; struct t10_alua_lu_gp *lu_gp; + struct cred *kern_cred; + const struct cred *old_cred; int ret; pr_debug("TARGET_CORE[0]: Loading Generic Kernel Storage" @@ -3534,11 +3536,21 @@ static int __init target_core_init_configfs(void) if (ret < 0) goto out; + /* We use the kernel credentials to access the target directory */ + kern_cred = prepare_kernel_cred(&init_task); + if (!kern_cred) { + ret = -ENOMEM; + goto out; + } + old_cred = override_creds(kern_cred); target_init_dbroot(); + revert_creds(old_cred); + put_cred(kern_cred); return 0; out: + target_xcopy_release_pt(); configfs_unregister_subsystem(subsys); core_dev_release_virtual_lun0(); rd_module_exit(); diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index 43899147a77a..0e4c6b1429e9 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -1974,8 +1974,12 @@ static void gsm0_receive(struct gsm_mux *gsm, unsigned char c) break; case GSM_DATA: /* Data */ gsm->buf[gsm->count++] = c; - if (gsm->count == gsm->len) + if (gsm->count >= MAX_MRU) { + gsm->bad_size++; + gsm->state = GSM_SEARCH; + } else if (gsm->count >= gsm->len) { gsm->state = GSM_FCS; + } break; case GSM_FCS: /* FCS follows the packet */ gsm->received_fcs = c; @@ -2055,7 +2059,7 @@ static void gsm1_receive(struct gsm_mux *gsm, unsigned char c) gsm->state = GSM_DATA; break; case GSM_DATA: /* Data */ - if (gsm->count > gsm->mru) { /* Allow one for the FCS */ + if (gsm->count > gsm->mru || gsm->count > MAX_MRU) { /* Allow one for the FCS */ gsm->state = GSM_OVERRUN; gsm->bad_size++; } else diff --git a/drivers/tty/serial/kgdboc.c b/drivers/tty/serial/kgdboc.c index 6d4792ec9e5f..2df77f894746 100644 --- a/drivers/tty/serial/kgdboc.c +++ b/drivers/tty/serial/kgdboc.c @@ -19,6 +19,7 @@ #include <linux/console.h> #include <linux/vt_kern.h> #include <linux/input.h> +#include <linux/irq_work.h> #include <linux/module.h> #include <linux/platform_device.h> @@ -42,6 +43,25 @@ static int kgdb_tty_line; static struct platform_device *kgdboc_pdev; +/* + * When we leave the debug trap handler we need to reset the keyboard status + * (since the original keyboard state gets partially clobbered by kdb use of + * the keyboard). + * + * The path to deliver the reset is somewhat circuitous. + * + * To deliver the reset we register an input handler, reset the keyboard and + * then deregister the input handler. However, to get this done right, we do + * have to carefully manage the calling context because we can only register + * input handlers from task context. + * + * In particular we need to trigger the action from the debug trap handler with + * all its NMI and/or NMI-like oddities. To solve this the kgdboc trap exit code + * (the "post_exception" callback) uses irq_work_queue(), which is NMI-safe, to + * schedule a callback from a hardirq context. From there we have to defer the + * work again, this time using schedule_work(), to get a callback using the + * system workqueue, which runs in task context. + */ #ifdef CONFIG_KDB_KEYBOARD static int kgdboc_reset_connect(struct input_handler *handler, struct input_dev *dev, @@ -93,10 +113,17 @@ static void kgdboc_restore_input_helper(struct work_struct *dummy) static DECLARE_WORK(kgdboc_restore_input_work, kgdboc_restore_input_helper); +static void kgdboc_queue_restore_input_helper(struct irq_work *unused) +{ + schedule_work(&kgdboc_restore_input_work); +} + +static DEFINE_IRQ_WORK(kgdboc_restore_input_irq_work, kgdboc_queue_restore_input_helper); + static void kgdboc_restore_input(void) { if (likely(system_state == SYSTEM_RUNNING)) - schedule_work(&kgdboc_restore_input_work); + irq_work_queue(&kgdboc_restore_input_irq_work); } static int kgdboc_register_kbd(char **cptr) @@ -127,6 +154,7 @@ static void kgdboc_unregister_kbd(void) i--; } } + irq_work_sync(&kgdboc_restore_input_irq_work); flush_work(&kgdboc_restore_input_work); } #else /* ! CONFIG_KDB_KEYBOARD */ diff --git a/drivers/tty/serial/max3100.c b/drivers/tty/serial/max3100.c index 371569a0fd00..17b6f4a872d6 100644 --- a/drivers/tty/serial/max3100.c +++ b/drivers/tty/serial/max3100.c @@ -45,6 +45,9 @@ #include <linux/freezer.h> #include <linux/tty.h> #include <linux/tty_flip.h> +#include <linux/types.h> + +#include <asm/unaligned.h> #include <linux/serial_max3100.h> @@ -191,7 +194,7 @@ static void max3100_timeout(struct timer_list *t) static int max3100_sr(struct max3100_port *s, u16 tx, u16 *rx) { struct spi_message message; - u16 etx, erx; + __be16 etx, erx; int status; struct spi_transfer tran = { .tx_buf = &etx, @@ -213,7 +216,7 @@ static int max3100_sr(struct max3100_port *s, u16 tx, u16 *rx) return 0; } -static int max3100_handlerx(struct max3100_port *s, u16 rx) +static int max3100_handlerx_unlocked(struct max3100_port *s, u16 rx) { unsigned int ch, flg, status = 0; int ret = 0, cts; @@ -253,6 +256,17 @@ static int max3100_handlerx(struct max3100_port *s, u16 rx) return ret; } +static int max3100_handlerx(struct max3100_port *s, u16 rx) +{ + unsigned long flags; + int ret; + + uart_port_lock_irqsave(&s->port, &flags); + ret = max3100_handlerx_unlocked(s, rx); + uart_port_unlock_irqrestore(&s->port, flags); + return ret; +} + static void max3100_work(struct work_struct *w) { struct max3100_port *s = container_of(w, struct max3100_port, work); @@ -743,13 +757,14 @@ static int max3100_probe(struct spi_device *spi) mutex_lock(&max3100s_lock); if (!uart_driver_registered) { - uart_driver_registered = 1; retval = uart_register_driver(&max3100_uart_driver); if (retval) { printk(KERN_ERR "Couldn't register max3100 uart driver\n"); mutex_unlock(&max3100s_lock); return retval; } + + uart_driver_registered = 1; } for (i = 0; i < MAX_MAX3100; i++) @@ -835,6 +850,7 @@ static int max3100_remove(struct spi_device *spi) } pr_debug("removing max3100 driver\n"); uart_unregister_driver(&max3100_uart_driver); + uart_driver_registered = 0; mutex_unlock(&max3100s_lock); return 0; diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 95db67c07c34..d570edf21239 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -1259,9 +1259,14 @@ static void sci_dma_rx_chan_invalidate(struct sci_port *s) static void sci_dma_rx_release(struct sci_port *s) { struct dma_chan *chan = s->chan_rx_saved; + struct uart_port *port = &s->port; + unsigned long flags; + uart_port_lock_irqsave(port, &flags); s->chan_rx_saved = NULL; sci_dma_rx_chan_invalidate(s); + uart_port_unlock_irqrestore(port, flags); + dmaengine_terminate_sync(chan); dma_free_coherent(chan->device->dev, s->buf_len_rx * 2, s->rx_buf[0], sg_dma_address(&s->sg_rx[0])); diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index a3106b179562..17ae3b394469 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -1925,7 +1925,7 @@ unknown: buf[5] = 0x01; switch (ctrl->bRequestType & USB_RECIP_MASK) { case USB_RECIP_DEVICE: - if (w_index != 0x4 || (w_value >> 8)) + if (w_index != 0x4 || (w_value & 0xff)) break; buf[6] = w_index; /* Number of ext compat interfaces */ @@ -1941,9 +1941,9 @@ unknown: } break; case USB_RECIP_INTERFACE: - if (w_index != 0x5 || (w_value >> 8)) + if (w_index != 0x5 || (w_value & 0xff)) break; - interface = w_value & 0xFF; + interface = w_value >> 8; if (interface >= MAX_CONFIG_INTERFACES || !os_desc_cfg->interface[interface]) break; diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c index 588a659f245e..1cf4f4bee019 100644 --- a/drivers/usb/gadget/function/f_fs.c +++ b/drivers/usb/gadget/function/f_fs.c @@ -3422,7 +3422,7 @@ static int ffs_func_setup(struct usb_function *f, __ffs_event_add(ffs, FUNCTIONFS_SETUP); spin_unlock_irqrestore(&ffs->ev.waitq.lock, flags); - return creq->wLength == 0 ? USB_GADGET_DELAYED_STATUS : 0; + return ffs->ev.setup.wLength == 0 ? USB_GADGET_DELAYED_STATUS : 0; } static bool ffs_func_req_match(struct usb_function *f, diff --git a/drivers/usb/gadget/function/u_audio.c b/drivers/usb/gadget/function/u_audio.c index 53b30de16a89..994316d51a0e 100644 --- a/drivers/usb/gadget/function/u_audio.c +++ b/drivers/usb/gadget/function/u_audio.c @@ -624,6 +624,8 @@ void g_audio_cleanup(struct g_audio *g_audio) return; uac = g_audio->uac; + g_audio->uac = NULL; + card = uac->card; if (card) snd_card_free_when_closed(card); diff --git a/drivers/usb/typec/ucsi/displayport.c b/drivers/usb/typec/ucsi/displayport.c index 166c2aabb512..f67c5a304155 100644 --- a/drivers/usb/typec/ucsi/displayport.c +++ b/drivers/usb/typec/ucsi/displayport.c @@ -251,8 +251,6 @@ static void ucsi_displayport_work(struct work_struct *work) struct ucsi_dp *dp = container_of(work, struct ucsi_dp, work); int ret; - mutex_lock(&dp->con->lock); - ret = typec_altmode_vdm(dp->alt, dp->header, dp->vdo_data, dp->vdo_size); if (ret) @@ -261,8 +259,6 @@ static void ucsi_displayport_work(struct work_struct *work) dp->vdo_data = NULL; dp->vdo_size = 0; dp->header = 0; - - mutex_unlock(&dp->con->lock); } void ucsi_displayport_remove_partner(struct typec_altmode *alt) diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index 0396df868bc7..8a3014455327 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -2031,8 +2031,8 @@ config FB_COBALT depends on FB && MIPS_COBALT config FB_SH7760 - bool "SH7760/SH7763/SH7720/SH7721 LCDC support" - depends on FB=y && (CPU_SUBTYPE_SH7760 || CPU_SUBTYPE_SH7763 \ + tristate "SH7760/SH7763/SH7720/SH7721 LCDC support" + depends on FB && (CPU_SUBTYPE_SH7760 || CPU_SUBTYPE_SH7763 \ || CPU_SUBTYPE_SH7720 || CPU_SUBTYPE_SH7721) select FB_CFB_FILLRECT select FB_CFB_COPYAREA diff --git a/drivers/video/fbdev/savage/savagefb_driver.c b/drivers/video/fbdev/savage/savagefb_driver.c index 368500c40140..35b9a3953413 100644 --- a/drivers/video/fbdev/savage/savagefb_driver.c +++ b/drivers/video/fbdev/savage/savagefb_driver.c @@ -2273,7 +2273,10 @@ static int savagefb_probe(struct pci_dev *dev, const struct pci_device_id *id) if (info->var.xres_virtual > 0x1000) info->var.xres_virtual = 0x1000; #endif - savagefb_check_var(&info->var, info); + err = savagefb_check_var(&info->var, info); + if (err) + goto failed; + savagefb_set_fix(info); /* diff --git a/drivers/video/fbdev/sh_mobile_lcdcfb.c b/drivers/video/fbdev/sh_mobile_lcdcfb.c index c249763dbf0b..85af63f32d5e 100644 --- a/drivers/video/fbdev/sh_mobile_lcdcfb.c +++ b/drivers/video/fbdev/sh_mobile_lcdcfb.c @@ -1580,7 +1580,7 @@ sh_mobile_lcdc_overlay_fb_init(struct sh_mobile_lcdc_overlay *ovl) */ info->fix = sh_mobile_lcdc_overlay_fix; snprintf(info->fix.id, sizeof(info->fix.id), - "SH Mobile LCDC Overlay %u", ovl->index); + "SHMobile ovl %u", ovl->index); info->fix.smem_start = ovl->dma_handle; info->fix.smem_len = ovl->fb_size; info->fix.line_length = ovl->pitch; diff --git a/drivers/video/fbdev/sis/init301.c b/drivers/video/fbdev/sis/init301.c index a8fb41f1a258..09329072004f 100644 --- a/drivers/video/fbdev/sis/init301.c +++ b/drivers/video/fbdev/sis/init301.c @@ -172,7 +172,7 @@ static const unsigned char SiS_HiTVGroup3_2[] = { }; /* 301C / 302ELV extended Part2 TV registers (4 tap scaler) */ - +#ifdef CONFIG_FB_SIS_315 static const unsigned char SiS_Part2CLVX_1[] = { 0x00,0x00, 0x00,0x20,0x00,0x00,0x7F,0x20,0x02,0x7F,0x7D,0x20,0x04,0x7F,0x7D,0x1F,0x06,0x7E, @@ -245,7 +245,6 @@ static const unsigned char SiS_Part2CLVX_6[] = { /* 1080i */ 0xFF,0xFF, }; -#ifdef CONFIG_FB_SIS_315 /* 661 et al LCD data structure (2.03.00) */ static const unsigned char SiS_LCDStruct661[] = { /* 1024x768 */ diff --git a/drivers/virtio/virtio_pci_common.c b/drivers/virtio/virtio_pci_common.c index 1e890ef17687..a6f375417fd5 100644 --- a/drivers/virtio/virtio_pci_common.c +++ b/drivers/virtio/virtio_pci_common.c @@ -339,8 +339,10 @@ static int vp_find_vqs_msix(struct virtio_device *vdev, unsigned nvqs, vring_interrupt, 0, vp_dev->msix_names[msix_vec], vqs[i]); - if (err) + if (err) { + vp_del_vq(vqs[i]); goto error_find; + } } return 0; |