diff options
author | André Fabian Silva Delgado <emulatorman@parabola.nu> | 2016-09-11 04:34:46 -0300 |
---|---|---|
committer | André Fabian Silva Delgado <emulatorman@parabola.nu> | 2016-09-11 04:34:46 -0300 |
commit | 863981e96738983919de841ec669e157e6bdaeb0 (patch) | |
tree | d6d89a12e7eb8017837c057935a2271290907f76 /drivers/misc | |
parent | 8dec7c70575785729a6a9e6719a955e9c545bcab (diff) |
Linux-libre 4.7.1-gnupck-4.7.1-gnu
Diffstat (limited to 'drivers/misc')
-rw-r--r-- | drivers/misc/cxl/api.c | 28 | ||||
-rw-r--r-- | drivers/misc/cxl/context.c | 3 | ||||
-rw-r--r-- | drivers/misc/cxl/cxl.h | 15 | ||||
-rw-r--r-- | drivers/misc/cxl/fault.c | 10 | ||||
-rw-r--r-- | drivers/misc/cxl/guest.c | 78 | ||||
-rw-r--r-- | drivers/misc/cxl/native.c | 29 | ||||
-rw-r--r-- | drivers/misc/cxl/pci.c | 64 | ||||
-rw-r--r-- | drivers/misc/cxl/sysfs.c | 10 | ||||
-rw-r--r-- | drivers/misc/eeprom/Kconfig | 2 | ||||
-rw-r--r-- | drivers/misc/eeprom/at24.c | 112 | ||||
-rw-r--r-- | drivers/misc/eeprom/at25.c | 91 | ||||
-rw-r--r-- | drivers/misc/eeprom/eeprom_93xx46.c | 92 | ||||
-rw-r--r-- | drivers/misc/mei/bus.c | 27 | ||||
-rw-r--r-- | drivers/misc/mei/client.c | 26 | ||||
-rw-r--r-- | drivers/misc/mei/hbm.c | 23 | ||||
-rw-r--r-- | drivers/misc/mei/mei_dev.h | 2 | ||||
-rw-r--r-- | drivers/misc/mic/Kconfig | 1 | ||||
-rw-r--r-- | drivers/misc/mic/host/mic_boot.c | 6 | ||||
-rw-r--r-- | drivers/misc/mic/scif/scif_fence.c | 3 | ||||
-rw-r--r-- | drivers/misc/mic/vop/vop_vringh.c | 5 | ||||
-rw-r--r-- | drivers/misc/qcom-coincell.c | 3 | ||||
-rw-r--r-- | drivers/misc/sgi-gru/grukservices.c | 38 | ||||
-rw-r--r-- | drivers/misc/sram.c | 4 | ||||
-rw-r--r-- | drivers/misc/ti-st/st_kim.c | 1 |
24 files changed, 299 insertions, 374 deletions
diff --git a/drivers/misc/cxl/api.c b/drivers/misc/cxl/api.c index 2107c9484..6d228ccd8 100644 --- a/drivers/misc/cxl/api.c +++ b/drivers/misc/cxl/api.c @@ -68,15 +68,6 @@ struct cxl_context *cxl_get_context(struct pci_dev *dev) } EXPORT_SYMBOL_GPL(cxl_get_context); -struct device *cxl_get_phys_dev(struct pci_dev *dev) -{ - struct cxl_afu *afu; - - afu = cxl_pci_to_afu(dev); - - return afu->adapter->dev.parent; -} - int cxl_release_context(struct cxl_context *ctx) { if (ctx->status >= STARTED) @@ -192,6 +183,7 @@ int cxl_start_context(struct cxl_context *ctx, u64 wed, ctx->pid = get_task_pid(task, PIDTYPE_PID); ctx->glpid = get_task_pid(task->group_leader, PIDTYPE_PID); kernel = false; + ctx->real_mode = false; } cxl_ctx_get(); @@ -228,6 +220,24 @@ void cxl_set_master(struct cxl_context *ctx) } EXPORT_SYMBOL_GPL(cxl_set_master); +int cxl_set_translation_mode(struct cxl_context *ctx, bool real_mode) +{ + if (ctx->status == STARTED) { + /* + * We could potentially update the PE and issue an update LLCMD + * to support this, but it doesn't seem to have a good use case + * since it's trivial to just create a second kernel context + * with different translation modes, so until someone convinces + * me otherwise: + */ + return -EBUSY; + } + + ctx->real_mode = real_mode; + return 0; +} +EXPORT_SYMBOL_GPL(cxl_set_translation_mode); + /* wrappers around afu_* file ops which are EXPORTED */ int cxl_fd_open(struct inode *inode, struct file *file) { diff --git a/drivers/misc/cxl/context.c b/drivers/misc/cxl/context.c index 7edea9c19..26d206b1d 100644 --- a/drivers/misc/cxl/context.c +++ b/drivers/misc/cxl/context.c @@ -297,8 +297,7 @@ static void reclaim_ctx(struct rcu_head *rcu) if (ctx->kernelapi) kfree(ctx->mapping); - if (ctx->irq_bitmap) - kfree(ctx->irq_bitmap); + kfree(ctx->irq_bitmap); /* Drop ref to the afu device taken during cxl_context_init */ cxl_afu_put(ctx->afu); diff --git a/drivers/misc/cxl/cxl.h b/drivers/misc/cxl/cxl.h index 73dc2a33d..4fe50788f 100644 --- a/drivers/misc/cxl/cxl.h +++ b/drivers/misc/cxl/cxl.h @@ -178,15 +178,6 @@ static const cxl_p2n_reg_t CXL_PSL_WED_An = {0x0A0}; #define CXL_PSL_SR_An_MP (1ull << (63-62)) /* Master Process */ #define CXL_PSL_SR_An_LE (1ull << (63-63)) /* Little Endian */ -/****** CXL_PSL_LLCMD_An ****************************************************/ -#define CXL_LLCMD_TERMINATE 0x0001000000000000ULL -#define CXL_LLCMD_REMOVE 0x0002000000000000ULL -#define CXL_LLCMD_SUSPEND 0x0003000000000000ULL -#define CXL_LLCMD_RESUME 0x0004000000000000ULL -#define CXL_LLCMD_ADD 0x0005000000000000ULL -#define CXL_LLCMD_UPDATE 0x0006000000000000ULL -#define CXL_LLCMD_HANDLE_MASK 0x000000000000ffffULL - /****** CXL_PSL_ID_An ****************************************************/ #define CXL_PSL_ID_An_F (1ull << (63-31)) #define CXL_PSL_ID_An_L (1ull << (63-30)) @@ -376,11 +367,13 @@ struct cxl_afu_native { }; struct cxl_afu_guest { + struct cxl_afu *parent; u64 handle; phys_addr_t p2n_phys; u64 p2n_size; int max_ints; - struct mutex recovery_lock; + bool handle_err; + struct delayed_work work_err; int previous_state; }; @@ -524,6 +517,7 @@ struct cxl_context { bool pe_inserted; bool master; bool kernel; + bool real_mode; bool pending_irq; bool pending_fault; bool pending_afu_err; @@ -580,6 +574,7 @@ struct cxl { bool perst_loads_image; bool perst_select_user; bool perst_same_image; + bool psl_timebase_synced; }; int cxl_pci_alloc_one_irq(struct cxl *adapter); diff --git a/drivers/misc/cxl/fault.c b/drivers/misc/cxl/fault.c index 9a8650bcb..377e650a2 100644 --- a/drivers/misc/cxl/fault.c +++ b/drivers/misc/cxl/fault.c @@ -149,11 +149,13 @@ static void cxl_handle_page_fault(struct cxl_context *ctx, * update_mmu_cache() will not have loaded the hash since current->trap * is not a 0x400 or 0x300, so just call hash_page_mm() here. */ - access = _PAGE_PRESENT; + access = _PAGE_PRESENT | _PAGE_READ; if (dsisr & CXL_PSL_DSISR_An_S) - access |= _PAGE_RW; - if ((!ctx->kernel) || ~(dar & (1ULL << 63))) - access |= _PAGE_USER; + access |= _PAGE_WRITE; + + access |= _PAGE_PRIVILEGED; + if ((!ctx->kernel) || (REGION_ID(dar) == USER_REGION_ID)) + access &= ~_PAGE_PRIVILEGED; if (dsisr & DSISR_NOHPTE) inv_flags |= HPTE_NOHPTE_UPDATE; diff --git a/drivers/misc/cxl/guest.c b/drivers/misc/cxl/guest.c index 8213372de..bc8d0b987 100644 --- a/drivers/misc/cxl/guest.c +++ b/drivers/misc/cxl/guest.c @@ -178,6 +178,9 @@ static int afu_read_error_state(struct cxl_afu *afu, int *state_out) u64 state; int rc = 0; + if (!afu) + return -EIO; + rc = cxl_h_read_error_state(afu->guest->handle, &state); if (!rc) { WARN_ON(state != H_STATE_NORMAL && @@ -552,6 +555,17 @@ static int attach_afu_directed(struct cxl_context *ctx, u64 wed, u64 amr) elem->common.sstp0 = cpu_to_be64(ctx->sstp0); elem->common.sstp1 = cpu_to_be64(ctx->sstp1); + + /* + * Ensure we have at least one interrupt allocated to take faults for + * kernel contexts that may not have allocated any AFU IRQs at all: + */ + if (ctx->irqs.range[0] == 0) { + rc = afu_register_irqs(ctx, 0); + if (rc) + goto out_free; + } + for (r = 0; r < CXL_IRQ_RANGES; r++) { for (i = 0; i < ctx->irqs.range[r]; i++) { if (r == 0 && i == 0) { @@ -597,6 +611,7 @@ static int attach_afu_directed(struct cxl_context *ctx, u64 wed, u64 amr) enable_afu_irqs(ctx); } +out_free: free_page((u64)elem); return rc; } @@ -605,6 +620,9 @@ static int guest_attach_process(struct cxl_context *ctx, bool kernel, u64 wed, u { pr_devel("in %s\n", __func__); + if (ctx->real_mode) + return -EPERM; + ctx->kernel = kernel; if (ctx->afu->current_mode == CXL_MODE_DIRECTED) return attach_afu_directed(ctx, wed, amr); @@ -818,7 +836,6 @@ static int afu_update_state(struct cxl_afu *afu) switch (cur_state) { case H_STATE_NORMAL: afu->guest->previous_state = cur_state; - rc = 1; break; case H_STATE_DISABLE: @@ -834,7 +851,6 @@ static int afu_update_state(struct cxl_afu *afu) pci_error_handlers(afu, CXL_SLOT_RESET_EVENT, pci_channel_io_normal); pci_error_handlers(afu, CXL_RESUME_EVENT, 0); - rc = 1; } afu->guest->previous_state = 0; break; @@ -859,39 +875,30 @@ static int afu_update_state(struct cxl_afu *afu) return rc; } -static int afu_do_recovery(struct cxl_afu *afu) +static void afu_handle_errstate(struct work_struct *work) { - int rc; + struct cxl_afu_guest *afu_guest = + container_of(to_delayed_work(work), struct cxl_afu_guest, work_err); - /* many threads can arrive here, in case of detach_all for example. - * Only one needs to drive the recovery - */ - if (mutex_trylock(&afu->guest->recovery_lock)) { - rc = afu_update_state(afu); - mutex_unlock(&afu->guest->recovery_lock); - return rc; - } - return 0; + if (!afu_update_state(afu_guest->parent) && + afu_guest->previous_state == H_STATE_PERM_UNAVAILABLE) + return; + + if (afu_guest->handle_err == true) + schedule_delayed_work(&afu_guest->work_err, + msecs_to_jiffies(3000)); } static bool guest_link_ok(struct cxl *cxl, struct cxl_afu *afu) { int state; - if (afu) { - if (afu_read_error_state(afu, &state) || - state != H_STATE_NORMAL) { - if (afu_do_recovery(afu) > 0) { - /* check again in case we've just fixed it */ - if (!afu_read_error_state(afu, &state) && - state == H_STATE_NORMAL) - return true; - } - return false; - } + if (afu && (!afu_read_error_state(afu, &state))) { + if (state == H_STATE_NORMAL) + return true; } - return true; + return false; } static int afu_properties_look_ok(struct cxl_afu *afu) @@ -929,8 +936,6 @@ int cxl_guest_init_afu(struct cxl *adapter, int slice, struct device_node *afu_n return -ENOMEM; } - mutex_init(&afu->guest->recovery_lock); - if ((rc = dev_set_name(&afu->dev, "afu%i.%i", adapter->adapter_num, slice))) @@ -986,6 +991,15 @@ int cxl_guest_init_afu(struct cxl *adapter, int slice, struct device_node *afu_n afu->enabled = true; + /* + * wake up the cpu periodically to check the state + * of the AFU using "afu" stored in the guest structure. + */ + afu->guest->parent = afu; + afu->guest->handle_err = true; + INIT_DELAYED_WORK(&afu->guest->work_err, afu_handle_errstate); + schedule_delayed_work(&afu->guest->work_err, msecs_to_jiffies(1000)); + if ((rc = cxl_pci_vphb_add(afu))) dev_info(&afu->dev, "Can't register vPHB\n"); @@ -1014,6 +1028,10 @@ void cxl_guest_remove_afu(struct cxl_afu *afu) if (!afu) return; + /* flush and stop pending job */ + afu->guest->handle_err = false; + flush_delayed_work(&afu->guest->work_err); + cxl_pci_vphb_remove(afu); cxl_sysfs_afu_remove(afu); @@ -1101,6 +1119,12 @@ struct cxl *cxl_guest_init_adapter(struct device_node *np, struct platform_devic adapter->dev.release = release_adapter; dev_set_drvdata(&pdev->dev, adapter); + /* + * Hypervisor controls PSL timebase initialization (p1 register). + * On FW840, PSL is initialized. + */ + adapter->psl_timebase_synced = true; + if ((rc = cxl_of_read_adapter_handle(adapter, np))) goto err1; diff --git a/drivers/misc/cxl/native.c b/drivers/misc/cxl/native.c index ecf7557cd..55d8a1459 100644 --- a/drivers/misc/cxl/native.c +++ b/drivers/misc/cxl/native.c @@ -186,16 +186,25 @@ static int spa_max_procs(int spa_size) int cxl_alloc_spa(struct cxl_afu *afu) { + unsigned spa_size; + /* Work out how many pages to allocate */ afu->native->spa_order = 0; do { afu->native->spa_order++; - afu->native->spa_size = (1 << afu->native->spa_order) * PAGE_SIZE; + spa_size = (1 << afu->native->spa_order) * PAGE_SIZE; + + if (spa_size > 0x100000) { + dev_warn(&afu->dev, "num_of_processes too large for the SPA, limiting to %i (0x%x)\n", + afu->native->spa_max_procs, afu->native->spa_size); + afu->num_procs = afu->native->spa_max_procs; + break; + } + + afu->native->spa_size = spa_size; afu->native->spa_max_procs = spa_max_procs(afu->native->spa_size); } while (afu->native->spa_max_procs < afu->num_procs); - WARN_ON(afu->native->spa_size > 0x100000); /* Max size supported by the hardware */ - if (!(afu->native->spa = (struct cxl_process_element *) __get_free_pages(GFP_KERNEL | __GFP_ZERO, afu->native->spa_order))) { pr_err("cxl_alloc_spa: Unable to allocate scheduled process area\n"); @@ -486,8 +495,9 @@ static u64 calculate_sr(struct cxl_context *ctx) if (mfspr(SPRN_LPCR) & LPCR_TC) sr |= CXL_PSL_SR_An_TC; if (ctx->kernel) { - sr |= CXL_PSL_SR_An_R | (mfmsr() & MSR_SF); - sr |= CXL_PSL_SR_An_HV; + if (!ctx->real_mode) + sr |= CXL_PSL_SR_An_R; + sr |= (mfmsr() & MSR_SF) | CXL_PSL_SR_An_HV; } else { sr |= CXL_PSL_SR_An_PR | CXL_PSL_SR_An_R; sr &= ~(CXL_PSL_SR_An_HV); @@ -526,6 +536,15 @@ static int attach_afu_directed(struct cxl_context *ctx, u64 wed, u64 amr) ctx->elem->common.sstp0 = cpu_to_be64(ctx->sstp0); ctx->elem->common.sstp1 = cpu_to_be64(ctx->sstp1); + /* + * Ensure we have the multiplexed PSL interrupt set up to take faults + * for kernel contexts that may not have allocated any AFU IRQs at all: + */ + if (ctx->irqs.range[0] == 0) { + ctx->irqs.offset[0] = ctx->afu->native->psl_hwirq; + ctx->irqs.range[0] = 1; + } + for (r = 0; r < CXL_IRQ_RANGES; r++) { ctx->elem->ivte_offsets[r] = cpu_to_be16(ctx->irqs.offset[r]); ctx->elem->ivte_ranges[r] = cpu_to_be16(ctx->irqs.range[r]); diff --git a/drivers/misc/cxl/pci.c b/drivers/misc/cxl/pci.c index 2844e975b..a08fcc888 100644 --- a/drivers/misc/cxl/pci.c +++ b/drivers/misc/cxl/pci.c @@ -21,6 +21,7 @@ #include <asm/msi_bitmap.h> #include <asm/pnv-pci.h> #include <asm/io.h> +#include <asm/reg.h> #include "cxl.h" #include <misc/cxl.h> @@ -321,12 +322,43 @@ static void dump_afu_descriptor(struct cxl_afu *afu) #undef show_reg } +#define CAPP_UNIT0_ID 0xBA +#define CAPP_UNIT1_ID 0XBE + +static u64 get_capp_unit_id(struct device_node *np) +{ + u32 phb_index; + + /* + * For chips other than POWER8NVL, we only have CAPP 0, + * irrespective of which PHB is used. + */ + if (!pvr_version_is(PVR_POWER8NVL)) + return CAPP_UNIT0_ID; + + /* + * For POWER8NVL, assume CAPP 0 is attached to PHB0 and + * CAPP 1 is attached to PHB1. + */ + if (of_property_read_u32(np, "ibm,phb-index", &phb_index)) + return 0; + + if (phb_index == 0) + return CAPP_UNIT0_ID; + + if (phb_index == 1) + return CAPP_UNIT1_ID; + + return 0; +} + static int init_implementation_adapter_regs(struct cxl *adapter, struct pci_dev *dev) { struct device_node *np; const __be32 *prop; u64 psl_dsnctl; u64 chipid; + u64 capp_unit_id; if (!(np = pnv_pci_get_phb_node(dev))) return -ENODEV; @@ -336,10 +368,19 @@ static int init_implementation_adapter_regs(struct cxl *adapter, struct pci_dev if (!np) return -ENODEV; chipid = be32_to_cpup(prop); + capp_unit_id = get_capp_unit_id(np); of_node_put(np); + if (!capp_unit_id) { + pr_err("cxl: invalid capp unit id\n"); + return -ENODEV; + } + psl_dsnctl = 0x0000900000000000ULL; /* pteupd ttype, scdone */ + psl_dsnctl |= (0x2ULL << (63-38)); /* MMIO hang pulse: 256 us */ /* Tell PSL where to route data to */ - psl_dsnctl = 0x02E8900002000000ULL | (chipid << (63-5)); + psl_dsnctl |= (chipid << (63-5)); + psl_dsnctl |= (capp_unit_id << (63-13)); + cxl_p1_write(adapter, CXL_PSL_DSNDCTL, psl_dsnctl); cxl_p1_write(adapter, CXL_PSL_RESLCKTO, 0x20000000200ULL); /* snoop write mask */ @@ -355,22 +396,24 @@ static int init_implementation_adapter_regs(struct cxl *adapter, struct pci_dev #define TBSYNC_CNT(n) (((u64)n & 0x7) << (63-6)) #define _2048_250MHZ_CYCLES 1 -static int cxl_setup_psl_timebase(struct cxl *adapter, struct pci_dev *dev) +static void cxl_setup_psl_timebase(struct cxl *adapter, struct pci_dev *dev) { u64 psl_tb; int delta; unsigned int retry = 0; struct device_node *np; + adapter->psl_timebase_synced = false; + if (!(np = pnv_pci_get_phb_node(dev))) - return -ENODEV; + return; /* Do not fail when CAPP timebase sync is not supported by OPAL */ of_node_get(np); if (! of_get_property(np, "ibm,capp-timebase-sync", NULL)) { of_node_put(np); - pr_err("PSL: Timebase sync: OPAL support missing\n"); - return 0; + dev_info(&dev->dev, "PSL timebase inactive: OPAL support missing\n"); + return; } of_node_put(np); @@ -389,8 +432,8 @@ static int cxl_setup_psl_timebase(struct cxl *adapter, struct pci_dev *dev) do { msleep(1); if (retry++ > 5) { - pr_err("PSL: Timebase sync: giving up!\n"); - return -EIO; + dev_info(&dev->dev, "PSL timebase can't synchronize\n"); + return; } psl_tb = cxl_p1_read(adapter, CXL_PSL_Timebase); delta = mftb() - psl_tb; @@ -398,7 +441,8 @@ static int cxl_setup_psl_timebase(struct cxl *adapter, struct pci_dev *dev) delta = -delta; } while (tb_to_ns(delta) > 16000); - return 0; + adapter->psl_timebase_synced = true; + return; } static int init_implementation_afu_regs(struct cxl_afu *afu) @@ -1144,8 +1188,8 @@ static int cxl_configure_adapter(struct cxl *adapter, struct pci_dev *dev) if ((rc = pnv_phb_to_cxl_mode(dev, OPAL_PHB_CAPI_MODE_SNOOP_ON))) goto err; - if ((rc = cxl_setup_psl_timebase(adapter, dev))) - goto err; + /* Ignore error, adapter init is not dependant on timebase sync */ + cxl_setup_psl_timebase(adapter, dev); if ((rc = cxl_native_register_psl_err_irq(adapter))) goto err; diff --git a/drivers/misc/cxl/sysfs.c b/drivers/misc/cxl/sysfs.c index 25913c087..b043c20f1 100644 --- a/drivers/misc/cxl/sysfs.c +++ b/drivers/misc/cxl/sysfs.c @@ -57,6 +57,15 @@ static ssize_t image_loaded_show(struct device *device, return scnprintf(buf, PAGE_SIZE, "factory\n"); } +static ssize_t psl_timebase_synced_show(struct device *device, + struct device_attribute *attr, + char *buf) +{ + struct cxl *adapter = to_cxl_adapter(device); + + return scnprintf(buf, PAGE_SIZE, "%i\n", adapter->psl_timebase_synced); +} + static ssize_t reset_adapter_store(struct device *device, struct device_attribute *attr, const char *buf, size_t count) @@ -142,6 +151,7 @@ static struct device_attribute adapter_attrs[] = { __ATTR_RO(psl_revision), __ATTR_RO(base_image), __ATTR_RO(image_loaded), + __ATTR_RO(psl_timebase_synced), __ATTR_RW(load_image_on_perst), __ATTR_RW(perst_reloads_same_image), __ATTR(reset, S_IWUSR, NULL, reset_adapter_store), diff --git a/drivers/misc/eeprom/Kconfig b/drivers/misc/eeprom/Kconfig index cfc493c2e..c4e41c266 100644 --- a/drivers/misc/eeprom/Kconfig +++ b/drivers/misc/eeprom/Kconfig @@ -3,7 +3,6 @@ menu "EEPROM support" config EEPROM_AT24 tristate "I2C EEPROMs / RAMs / ROMs from most vendors" depends on I2C && SYSFS - select REGMAP select NVMEM help Enable this driver to get read/write support to most I2C EEPROMs @@ -32,7 +31,6 @@ config EEPROM_AT24 config EEPROM_AT25 tristate "SPI EEPROMs from most vendors" depends on SPI && SYSFS - select REGMAP select NVMEM help Enable this driver to get read/write support to most SPI EEPROMs, diff --git a/drivers/misc/eeprom/at24.c b/drivers/misc/eeprom/at24.c index 089d6943f..9ceb63b62 100644 --- a/drivers/misc/eeprom/at24.c +++ b/drivers/misc/eeprom/at24.c @@ -23,7 +23,6 @@ #include <linux/acpi.h> #include <linux/i2c.h> #include <linux/nvmem-provider.h> -#include <linux/regmap.h> #include <linux/platform_data/at24.h> /* @@ -69,7 +68,6 @@ struct at24_data { unsigned write_max; unsigned num_addresses; - struct regmap_config regmap_config; struct nvmem_config nvmem_config; struct nvmem_device *nvmem; @@ -245,17 +243,16 @@ static ssize_t at24_eeprom_read(struct at24_data *at24, char *buf, if (status == count) return count; - /* REVISIT: at HZ=100, this is sloooow */ - msleep(1); + usleep_range(1000, 1500); } while (time_before(read_time, timeout)); return -ETIMEDOUT; } -static ssize_t at24_read(struct at24_data *at24, - char *buf, loff_t off, size_t count) +static int at24_read(void *priv, unsigned int off, void *val, size_t count) { - ssize_t retval = 0; + struct at24_data *at24 = priv; + char *buf = val; if (unlikely(!count)) return count; @@ -267,23 +264,21 @@ static ssize_t at24_read(struct at24_data *at24, mutex_lock(&at24->lock); while (count) { - ssize_t status; + int status; status = at24_eeprom_read(at24, buf, off, count); - if (status <= 0) { - if (retval == 0) - retval = status; - break; + if (status < 0) { + mutex_unlock(&at24->lock); + return status; } buf += status; off += status; count -= status; - retval += status; } mutex_unlock(&at24->lock); - return retval; + return 0; } /* @@ -365,20 +360,19 @@ static ssize_t at24_eeprom_write(struct at24_data *at24, const char *buf, if (status == count) return count; - /* REVISIT: at HZ=100, this is sloooow */ - msleep(1); + usleep_range(1000, 1500); } while (time_before(write_time, timeout)); return -ETIMEDOUT; } -static ssize_t at24_write(struct at24_data *at24, const char *buf, loff_t off, - size_t count) +static int at24_write(void *priv, unsigned int off, void *val, size_t count) { - ssize_t retval = 0; + struct at24_data *at24 = priv; + char *buf = val; if (unlikely(!count)) - return count; + return -EINVAL; /* * Write data to chip, protecting against concurrent updates @@ -387,70 +381,23 @@ static ssize_t at24_write(struct at24_data *at24, const char *buf, loff_t off, mutex_lock(&at24->lock); while (count) { - ssize_t status; + int status; status = at24_eeprom_write(at24, buf, off, count); - if (status <= 0) { - if (retval == 0) - retval = status; - break; + if (status < 0) { + mutex_unlock(&at24->lock); + return status; } buf += status; off += status; count -= status; - retval += status; } mutex_unlock(&at24->lock); - return retval; -} - -/*-------------------------------------------------------------------------*/ - -/* - * Provide a regmap interface, which is registered with the NVMEM - * framework -*/ -static int at24_regmap_read(void *context, const void *reg, size_t reg_size, - void *val, size_t val_size) -{ - struct at24_data *at24 = context; - off_t offset = *(u32 *)reg; - int err; - - err = at24_read(at24, val, offset, val_size); - if (err) - return err; return 0; } -static int at24_regmap_write(void *context, const void *data, size_t count) -{ - struct at24_data *at24 = context; - const char *buf; - u32 offset; - size_t len; - int err; - - memcpy(&offset, data, sizeof(offset)); - buf = (const char *)data + sizeof(offset); - len = count - sizeof(offset); - - err = at24_write(at24, buf, offset, len); - if (err) - return err; - return 0; -} - -static const struct regmap_bus at24_regmap_bus = { - .read = at24_regmap_read, - .write = at24_regmap_write, - .reg_format_endian_default = REGMAP_ENDIAN_NATIVE, -}; - -/*-------------------------------------------------------------------------*/ - #ifdef CONFIG_OF static void at24_get_ofdata(struct i2c_client *client, struct at24_platform_data *chip) @@ -482,7 +429,6 @@ static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id) struct at24_data *at24; int err; unsigned i, num_addresses; - struct regmap *regmap; if (client->dev.platform_data) { chip = *(struct at24_platform_data *)client->dev.platform_data; @@ -544,10 +490,7 @@ static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id) } else { return -EPFNOSUPPORT; } - } - /* Use I2C operations unless we're stuck with SMBus extensions. */ - if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { if (i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WRITE_I2C_BLOCK)) { use_smbus_write = I2C_SMBUS_I2C_BLOCK_DATA; @@ -612,19 +555,6 @@ static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id) } } - at24->regmap_config.reg_bits = 32; - at24->regmap_config.val_bits = 8; - at24->regmap_config.reg_stride = 1; - at24->regmap_config.max_register = chip.byte_len - 1; - - regmap = devm_regmap_init(&client->dev, &at24_regmap_bus, at24, - &at24->regmap_config); - if (IS_ERR(regmap)) { - dev_err(&client->dev, "regmap init failed\n"); - err = PTR_ERR(regmap); - goto err_clients; - } - at24->nvmem_config.name = dev_name(&client->dev); at24->nvmem_config.dev = &client->dev; at24->nvmem_config.read_only = !writable; @@ -632,6 +562,12 @@ static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id) at24->nvmem_config.owner = THIS_MODULE; at24->nvmem_config.compat = true; at24->nvmem_config.base_dev = &client->dev; + at24->nvmem_config.reg_read = at24_read; + at24->nvmem_config.reg_write = at24_write; + at24->nvmem_config.priv = at24; + at24->nvmem_config.stride = 4; + at24->nvmem_config.word_size = 1; + at24->nvmem_config.size = chip.byte_len; at24->nvmem = nvmem_register(&at24->nvmem_config); diff --git a/drivers/misc/eeprom/at25.c b/drivers/misc/eeprom/at25.c index fa36a6e37..2c6c7c8e3 100644 --- a/drivers/misc/eeprom/at25.c +++ b/drivers/misc/eeprom/at25.c @@ -17,7 +17,6 @@ #include <linux/sched.h> #include <linux/nvmem-provider.h> -#include <linux/regmap.h> #include <linux/spi/spi.h> #include <linux/spi/eeprom.h> #include <linux/property.h> @@ -34,7 +33,6 @@ struct at25_data { struct mutex lock; struct spi_eeprom chip; unsigned addrlen; - struct regmap_config regmap_config; struct nvmem_config nvmem_config; struct nvmem_device *nvmem; }; @@ -65,14 +63,11 @@ struct at25_data { #define io_limit PAGE_SIZE /* bytes */ -static ssize_t -at25_ee_read( - struct at25_data *at25, - char *buf, - unsigned offset, - size_t count -) +static int at25_ee_read(void *priv, unsigned int offset, + void *val, size_t count) { + struct at25_data *at25 = priv; + char *buf = val; u8 command[EE_MAXADDRLEN + 1]; u8 *cp; ssize_t status; @@ -81,11 +76,11 @@ at25_ee_read( u8 instr; if (unlikely(offset >= at25->chip.byte_len)) - return 0; + return -EINVAL; if ((offset + count) > at25->chip.byte_len) count = at25->chip.byte_len - offset; if (unlikely(!count)) - return count; + return -EINVAL; cp = command; @@ -131,28 +126,14 @@ at25_ee_read( count, offset, (int) status); mutex_unlock(&at25->lock); - return status ? status : count; + return status; } -static int at25_regmap_read(void *context, const void *reg, size_t reg_size, - void *val, size_t val_size) +static int at25_ee_write(void *priv, unsigned int off, void *val, size_t count) { - struct at25_data *at25 = context; - off_t offset = *(u32 *)reg; - int err; - - err = at25_ee_read(at25, val, offset, val_size); - if (err) - return err; - return 0; -} - -static ssize_t -at25_ee_write(struct at25_data *at25, const char *buf, loff_t off, - size_t count) -{ - ssize_t status = 0; - unsigned written = 0; + struct at25_data *at25 = priv; + const char *buf = val; + int status = 0; unsigned buf_size; u8 *bounce; @@ -161,7 +142,7 @@ at25_ee_write(struct at25_data *at25, const char *buf, loff_t off, if ((off + count) > at25->chip.byte_len) count = at25->chip.byte_len - off; if (unlikely(!count)) - return count; + return -EINVAL; /* Temp buffer starts with command and address */ buf_size = at25->chip.page_size; @@ -256,40 +237,15 @@ at25_ee_write(struct at25_data *at25, const char *buf, loff_t off, off += segment; buf += segment; count -= segment; - written += segment; } while (count > 0); mutex_unlock(&at25->lock); kfree(bounce); - return written ? written : status; + return status; } -static int at25_regmap_write(void *context, const void *data, size_t count) -{ - struct at25_data *at25 = context; - const char *buf; - u32 offset; - size_t len; - int err; - - memcpy(&offset, data, sizeof(offset)); - buf = (const char *)data + sizeof(offset); - len = count - sizeof(offset); - - err = at25_ee_write(at25, buf, offset, len); - if (err) - return err; - return 0; -} - -static const struct regmap_bus at25_regmap_bus = { - .read = at25_regmap_read, - .write = at25_regmap_write, - .reg_format_endian_default = REGMAP_ENDIAN_NATIVE, -}; - /*-------------------------------------------------------------------------*/ static int at25_fw_to_chip(struct device *dev, struct spi_eeprom *chip) @@ -349,7 +305,6 @@ static int at25_probe(struct spi_device *spi) { struct at25_data *at25 = NULL; struct spi_eeprom chip; - struct regmap *regmap; int err; int sr; int addrlen; @@ -390,22 +345,10 @@ static int at25_probe(struct spi_device *spi) mutex_init(&at25->lock); at25->chip = chip; - at25->spi = spi_dev_get(spi); + at25->spi = spi; spi_set_drvdata(spi, at25); at25->addrlen = addrlen; - at25->regmap_config.reg_bits = 32; - at25->regmap_config.val_bits = 8; - at25->regmap_config.reg_stride = 1; - at25->regmap_config.max_register = chip.byte_len - 1; - - regmap = devm_regmap_init(&spi->dev, &at25_regmap_bus, at25, - &at25->regmap_config); - if (IS_ERR(regmap)) { - dev_err(&spi->dev, "regmap init failed\n"); - return PTR_ERR(regmap); - } - at25->nvmem_config.name = dev_name(&spi->dev); at25->nvmem_config.dev = &spi->dev; at25->nvmem_config.read_only = chip.flags & EE_READONLY; @@ -413,6 +356,12 @@ static int at25_probe(struct spi_device *spi) at25->nvmem_config.owner = THIS_MODULE; at25->nvmem_config.compat = true; at25->nvmem_config.base_dev = &spi->dev; + at25->nvmem_config.reg_read = at25_ee_read; + at25->nvmem_config.reg_write = at25_ee_write; + at25->nvmem_config.priv = at25; + at25->nvmem_config.stride = 4; + at25->nvmem_config.word_size = 1; + at25->nvmem_config.size = chip.byte_len; at25->nvmem = nvmem_register(&at25->nvmem_config); if (IS_ERR(at25->nvmem)) diff --git a/drivers/misc/eeprom/eeprom_93xx46.c b/drivers/misc/eeprom/eeprom_93xx46.c index 426fe2fd5..94cc035aa 100644 --- a/drivers/misc/eeprom/eeprom_93xx46.c +++ b/drivers/misc/eeprom/eeprom_93xx46.c @@ -20,7 +20,6 @@ #include <linux/slab.h> #include <linux/spi/spi.h> #include <linux/nvmem-provider.h> -#include <linux/regmap.h> #include <linux/eeprom_93xx46.h> #define OP_START 0x4 @@ -43,7 +42,6 @@ struct eeprom_93xx46_dev { struct spi_device *spi; struct eeprom_93xx46_platform_data *pdata; struct mutex lock; - struct regmap_config regmap_config; struct nvmem_config nvmem_config; struct nvmem_device *nvmem; int addrlen; @@ -60,11 +58,12 @@ static inline bool has_quirk_instruction_length(struct eeprom_93xx46_dev *edev) return edev->pdata->quirks & EEPROM_93XX46_QUIRK_INSTRUCTION_LENGTH; } -static ssize_t -eeprom_93xx46_read(struct eeprom_93xx46_dev *edev, char *buf, - unsigned off, size_t count) +static int eeprom_93xx46_read(void *priv, unsigned int off, + void *val, size_t count) { - ssize_t ret = 0; + struct eeprom_93xx46_dev *edev = priv; + char *buf = val; + int err = 0; if (unlikely(off >= edev->size)) return 0; @@ -84,7 +83,6 @@ eeprom_93xx46_read(struct eeprom_93xx46_dev *edev, char *buf, u16 cmd_addr = OP_READ << edev->addrlen; size_t nbytes = count; int bits; - int err; if (edev->addrlen == 7) { cmd_addr |= off & 0x7f; @@ -120,21 +118,20 @@ eeprom_93xx46_read(struct eeprom_93xx46_dev *edev, char *buf, if (err) { dev_err(&edev->spi->dev, "read %zu bytes at %d: err. %d\n", nbytes, (int)off, err); - ret = err; break; } buf += nbytes; off += nbytes; count -= nbytes; - ret += nbytes; } if (edev->pdata->finish) edev->pdata->finish(edev); mutex_unlock(&edev->lock); - return ret; + + return err; } static int eeprom_93xx46_ew(struct eeprom_93xx46_dev *edev, int is_on) @@ -230,10 +227,11 @@ eeprom_93xx46_write_word(struct eeprom_93xx46_dev *edev, return ret; } -static ssize_t -eeprom_93xx46_write(struct eeprom_93xx46_dev *edev, const char *buf, - loff_t off, size_t count) +static int eeprom_93xx46_write(void *priv, unsigned int off, + void *val, size_t count) { + struct eeprom_93xx46_dev *edev = priv; + char *buf = val; int i, ret, step = 1; if (unlikely(off >= edev->size)) @@ -275,52 +273,9 @@ eeprom_93xx46_write(struct eeprom_93xx46_dev *edev, const char *buf, /* erase/write disable */ eeprom_93xx46_ew(edev, 0); - return ret ? : count; -} - -/* - * Provide a regmap interface, which is registered with the NVMEM - * framework -*/ -static int eeprom_93xx46_regmap_read(void *context, const void *reg, - size_t reg_size, void *val, - size_t val_size) -{ - struct eeprom_93xx46_dev *eeprom_93xx46 = context; - off_t offset = *(u32 *)reg; - int err; - - err = eeprom_93xx46_read(eeprom_93xx46, val, offset, val_size); - if (err) - return err; - return 0; -} - -static int eeprom_93xx46_regmap_write(void *context, const void *data, - size_t count) -{ - struct eeprom_93xx46_dev *eeprom_93xx46 = context; - const char *buf; - u32 offset; - size_t len; - int err; - - memcpy(&offset, data, sizeof(offset)); - buf = (const char *)data + sizeof(offset); - len = count - sizeof(offset); - - err = eeprom_93xx46_write(eeprom_93xx46, buf, offset, len); - if (err) - return err; - return 0; + return ret; } -static const struct regmap_bus eeprom_93xx46_regmap_bus = { - .read = eeprom_93xx46_regmap_read, - .write = eeprom_93xx46_regmap_write, - .reg_format_endian_default = REGMAP_ENDIAN_NATIVE, -}; - static int eeprom_93xx46_eral(struct eeprom_93xx46_dev *edev) { struct eeprom_93xx46_platform_data *pd = edev->pdata; @@ -480,7 +435,6 @@ static int eeprom_93xx46_probe(struct spi_device *spi) { struct eeprom_93xx46_platform_data *pd; struct eeprom_93xx46_dev *edev; - struct regmap *regmap; int err; if (spi->dev.of_node) { @@ -511,24 +465,10 @@ static int eeprom_93xx46_probe(struct spi_device *spi) mutex_init(&edev->lock); - edev->spi = spi_dev_get(spi); + edev->spi = spi; edev->pdata = pd; edev->size = 128; - - edev->regmap_config.reg_bits = 32; - edev->regmap_config.val_bits = 8; - edev->regmap_config.reg_stride = 1; - edev->regmap_config.max_register = edev->size - 1; - - regmap = devm_regmap_init(&spi->dev, &eeprom_93xx46_regmap_bus, edev, - &edev->regmap_config); - if (IS_ERR(regmap)) { - dev_err(&spi->dev, "regmap init failed\n"); - err = PTR_ERR(regmap); - goto fail; - } - edev->nvmem_config.name = dev_name(&spi->dev); edev->nvmem_config.dev = &spi->dev; edev->nvmem_config.read_only = pd->flags & EE_READONLY; @@ -536,6 +476,12 @@ static int eeprom_93xx46_probe(struct spi_device *spi) edev->nvmem_config.owner = THIS_MODULE; edev->nvmem_config.compat = true; edev->nvmem_config.base_dev = &spi->dev; + edev->nvmem_config.reg_read = eeprom_93xx46_read; + edev->nvmem_config.reg_write = eeprom_93xx46_write; + edev->nvmem_config.priv = edev; + edev->nvmem_config.stride = 4; + edev->nvmem_config.word_size = 1; + edev->nvmem_config.size = edev->size; edev->nvmem = nvmem_register(&edev->nvmem_config); if (IS_ERR(edev->nvmem)) { diff --git a/drivers/misc/mei/bus.c b/drivers/misc/mei/bus.c index 038b6dd24..1f33fea92 100644 --- a/drivers/misc/mei/bus.c +++ b/drivers/misc/mei/bus.c @@ -589,6 +589,7 @@ static int mei_cl_device_probe(struct device *dev) struct mei_cl_device *cldev; struct mei_cl_driver *cldrv; const struct mei_cl_device_id *id; + int ret; cldev = to_mei_cl_device(dev); cldrv = to_mei_cl_driver(dev->driver); @@ -603,9 +604,12 @@ static int mei_cl_device_probe(struct device *dev) if (!id) return -ENODEV; - __module_get(THIS_MODULE); + ret = cldrv->probe(cldev, id); + if (ret) + return ret; - return cldrv->probe(cldev, id); + __module_get(THIS_MODULE); + return 0; } /** @@ -643,11 +647,8 @@ static ssize_t name_show(struct device *dev, struct device_attribute *a, char *buf) { struct mei_cl_device *cldev = to_mei_cl_device(dev); - size_t len; - len = snprintf(buf, PAGE_SIZE, "%s", cldev->name); - - return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len; + return scnprintf(buf, PAGE_SIZE, "%s", cldev->name); } static DEVICE_ATTR_RO(name); @@ -656,11 +657,8 @@ static ssize_t uuid_show(struct device *dev, struct device_attribute *a, { struct mei_cl_device *cldev = to_mei_cl_device(dev); const uuid_le *uuid = mei_me_cl_uuid(cldev->me_cl); - size_t len; - - len = snprintf(buf, PAGE_SIZE, "%pUl", uuid); - return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len; + return scnprintf(buf, PAGE_SIZE, "%pUl", uuid); } static DEVICE_ATTR_RO(uuid); @@ -669,11 +667,8 @@ static ssize_t version_show(struct device *dev, struct device_attribute *a, { struct mei_cl_device *cldev = to_mei_cl_device(dev); u8 version = mei_me_cl_ver(cldev->me_cl); - size_t len; - - len = snprintf(buf, PAGE_SIZE, "%02X", version); - return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len; + return scnprintf(buf, PAGE_SIZE, "%02X", version); } static DEVICE_ATTR_RO(version); @@ -682,10 +677,8 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *a, { struct mei_cl_device *cldev = to_mei_cl_device(dev); const uuid_le *uuid = mei_me_cl_uuid(cldev->me_cl); - size_t len; - len = snprintf(buf, PAGE_SIZE, "mei:%s:%pUl:", cldev->name, uuid); - return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len; + return scnprintf(buf, PAGE_SIZE, "mei:%s:%pUl:", cldev->name, uuid); } static DEVICE_ATTR_RO(modalias); diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c index 09f5280fa..641c1a566 100644 --- a/drivers/misc/mei/client.c +++ b/drivers/misc/mei/client.c @@ -727,6 +727,11 @@ static void mei_cl_wake_all(struct mei_cl *cl) cl_dbg(dev, cl, "Waking up waiting for event clients!\n"); wake_up_interruptible(&cl->ev_wait); } + /* synchronized under device mutex */ + if (waitqueue_active(&cl->wait)) { + cl_dbg(dev, cl, "Waking up ctrl write clients!\n"); + wake_up(&cl->wait); + } } /** @@ -879,12 +884,15 @@ static int __mei_cl_disconnect(struct mei_cl *cl) } mutex_unlock(&dev->device_lock); - wait_event_timeout(cl->wait, cl->state == MEI_FILE_DISCONNECT_REPLY, + wait_event_timeout(cl->wait, + cl->state == MEI_FILE_DISCONNECT_REPLY || + cl->state == MEI_FILE_DISCONNECTED, mei_secs_to_jiffies(MEI_CL_CONNECT_TIMEOUT)); mutex_lock(&dev->device_lock); rets = cl->status; - if (cl->state != MEI_FILE_DISCONNECT_REPLY) { + if (cl->state != MEI_FILE_DISCONNECT_REPLY && + cl->state != MEI_FILE_DISCONNECTED) { cl_dbg(dev, cl, "timeout on disconnect from FW client.\n"); rets = -ETIME; } @@ -1085,6 +1093,7 @@ int mei_cl_connect(struct mei_cl *cl, struct mei_me_client *me_cl, mutex_unlock(&dev->device_lock); wait_event_timeout(cl->wait, (cl->state == MEI_FILE_CONNECTED || + cl->state == MEI_FILE_DISCONNECTED || cl->state == MEI_FILE_DISCONNECT_REQUIRED || cl->state == MEI_FILE_DISCONNECT_REPLY), mei_secs_to_jiffies(MEI_CL_CONNECT_TIMEOUT)); @@ -1333,16 +1342,13 @@ int mei_cl_notify_request(struct mei_cl *cl, } mutex_unlock(&dev->device_lock); - wait_event_timeout(cl->wait, cl->notify_en == request, - mei_secs_to_jiffies(MEI_CL_CONNECT_TIMEOUT)); + wait_event_timeout(cl->wait, + cl->notify_en == request || !mei_cl_is_connected(cl), + mei_secs_to_jiffies(MEI_CL_CONNECT_TIMEOUT)); mutex_lock(&dev->device_lock); - if (cl->notify_en != request) { - mei_io_list_flush(&dev->ctrl_rd_list, cl); - mei_io_list_flush(&dev->ctrl_wr_list, cl); - if (!cl->status) - cl->status = -EFAULT; - } + if (cl->notify_en != request && !cl->status) + cl->status = -EFAULT; rets = cl->status; diff --git a/drivers/misc/mei/hbm.c b/drivers/misc/mei/hbm.c index 8fe1ef821..5aa606c8a 100644 --- a/drivers/misc/mei/hbm.c +++ b/drivers/misc/mei/hbm.c @@ -113,8 +113,6 @@ void mei_hbm_idle(struct mei_device *dev) */ void mei_hbm_reset(struct mei_device *dev) { - dev->me_client_index = 0; - mei_me_cl_rm_all(dev); mei_hbm_idle(dev); @@ -530,24 +528,22 @@ static void mei_hbm_cl_notify(struct mei_device *dev, * mei_hbm_prop_req - request property for a single client * * @dev: the device structure + * @start_idx: client index to start search * * Return: 0 on success and < 0 on failure */ - -static int mei_hbm_prop_req(struct mei_device *dev) +static int mei_hbm_prop_req(struct mei_device *dev, unsigned long start_idx) { - struct mei_msg_hdr *mei_hdr = &dev->wr_msg.hdr; struct hbm_props_request *prop_req; const size_t len = sizeof(struct hbm_props_request); - unsigned long next_client_index; + unsigned long addr; int ret; - next_client_index = find_next_bit(dev->me_clients_map, MEI_CLIENTS_MAX, - dev->me_client_index); + addr = find_next_bit(dev->me_clients_map, MEI_CLIENTS_MAX, start_idx); /* We got all client properties */ - if (next_client_index == MEI_CLIENTS_MAX) { + if (addr == MEI_CLIENTS_MAX) { dev->hbm_state = MEI_HBM_STARTED; mei_host_client_init(dev); @@ -560,7 +556,7 @@ static int mei_hbm_prop_req(struct mei_device *dev) memset(prop_req, 0, sizeof(struct hbm_props_request)); prop_req->hbm_cmd = HOST_CLIENT_PROPERTIES_REQ_CMD; - prop_req->me_addr = next_client_index; + prop_req->me_addr = addr; ret = mei_write_message(dev, mei_hdr, dev->wr_msg.data); if (ret) { @@ -570,7 +566,6 @@ static int mei_hbm_prop_req(struct mei_device *dev) } dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT; - dev->me_client_index = next_client_index; return 0; } @@ -1151,10 +1146,8 @@ int mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr) mei_hbm_me_cl_add(dev, props_res); - dev->me_client_index++; - /* request property for the next client */ - if (mei_hbm_prop_req(dev)) + if (mei_hbm_prop_req(dev, props_res->me_addr + 1)) return -EIO; break; @@ -1180,7 +1173,7 @@ int mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr) dev->hbm_state = MEI_HBM_CLIENT_PROPERTIES; /* first property request */ - if (mei_hbm_prop_req(dev)) + if (mei_hbm_prop_req(dev, 0)) return -EIO; break; diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index 859bdac22..c9e01021e 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h @@ -396,7 +396,6 @@ const char *mei_pg_state_str(enum mei_pg_state state); * @me_clients : list of FW clients * @me_clients_map : FW clients bit map * @host_clients_map : host clients id pool - * @me_client_index : last FW client index in enumeration * * @allow_fixed_address: allow user space to connect a fixed client * @override_fixed_address: force allow fixed address behavior @@ -486,7 +485,6 @@ struct mei_device { struct list_head me_clients; DECLARE_BITMAP(me_clients_map, MEI_CLIENTS_MAX); DECLARE_BITMAP(host_clients_map, MEI_CLIENTS_MAX); - unsigned long me_client_index; bool allow_fixed_address; bool override_fixed_address; diff --git a/drivers/misc/mic/Kconfig b/drivers/misc/mic/Kconfig index 2e4f3ba75..89e5917e1 100644 --- a/drivers/misc/mic/Kconfig +++ b/drivers/misc/mic/Kconfig @@ -132,6 +132,7 @@ config VOP tristate "VOP Driver" depends on 64BIT && PCI && X86 && VOP_BUS select VHOST_RING + select VIRTIO help This enables VOP (Virtio over PCIe) Driver support for the Intel Many Integrated Core (MIC) family of PCIe form factor coprocessor diff --git a/drivers/misc/mic/host/mic_boot.c b/drivers/misc/mic/host/mic_boot.c index 8c91c9950..e047efd83 100644 --- a/drivers/misc/mic/host/mic_boot.c +++ b/drivers/misc/mic/host/mic_boot.c @@ -76,7 +76,7 @@ static void __mic_free_irq(struct vop_device *vpdev, { struct mic_device *mdev = vpdev_to_mdev(&vpdev->dev); - return mic_free_irq(mdev, cookie, data); + mic_free_irq(mdev, cookie, data); } static void __mic_ack_interrupt(struct vop_device *vpdev, int num) @@ -272,7 +272,7 @@ ___mic_free_irq(struct scif_hw_dev *scdev, { struct mic_device *mdev = scdev_to_mdev(scdev); - return mic_free_irq(mdev, cookie, data); + mic_free_irq(mdev, cookie, data); } static void ___mic_ack_interrupt(struct scif_hw_dev *scdev, int num) @@ -362,7 +362,7 @@ _mic_request_threaded_irq(struct mbus_device *mbdev, static void _mic_free_irq(struct mbus_device *mbdev, struct mic_irq *cookie, void *data) { - return mic_free_irq(mbdev_to_mdev(mbdev), cookie, data); + mic_free_irq(mbdev_to_mdev(mbdev), cookie, data); } static void _mic_ack_interrupt(struct mbus_device *mbdev, int num) diff --git a/drivers/misc/mic/scif/scif_fence.c b/drivers/misc/mic/scif/scif_fence.c index 7f2c96f57..cac3bcc30 100644 --- a/drivers/misc/mic/scif/scif_fence.c +++ b/drivers/misc/mic/scif/scif_fence.c @@ -27,7 +27,8 @@ void scif_recv_mark(struct scif_dev *scifdev, struct scifmsg *msg) { struct scif_endpt *ep = (struct scif_endpt *)msg->payload[0]; - int mark, err; + int mark = 0; + int err; err = _scif_fence_mark(ep, &mark); if (err) diff --git a/drivers/misc/mic/vop/vop_vringh.c b/drivers/misc/mic/vop/vop_vringh.c index af57d2caa..88e45234d 100644 --- a/drivers/misc/mic/vop/vop_vringh.c +++ b/drivers/misc/mic/vop/vop_vringh.c @@ -950,11 +950,6 @@ static long vop_ioctl(struct file *f, unsigned int cmd, unsigned long arg) ret = -EINVAL; goto free_ret; } - /* Ensure desc has not changed between the two reads */ - if (memcmp(&dd, dd_config, sizeof(dd))) { - ret = -EINVAL; - goto free_ret; - } mutex_lock(&vdev->vdev_mutex); mutex_lock(&vi->vop_mutex); ret = vop_virtio_add_device(vdev, dd_config); diff --git a/drivers/misc/qcom-coincell.c b/drivers/misc/qcom-coincell.c index 7b4a2da48..829a61dbd 100644 --- a/drivers/misc/qcom-coincell.c +++ b/drivers/misc/qcom-coincell.c @@ -94,7 +94,8 @@ static int qcom_coincell_probe(struct platform_device *pdev) { struct device_node *node = pdev->dev.of_node; struct qcom_coincell chgr; - u32 rset, vset; + u32 rset = 0; + u32 vset = 0; bool enable; int rc; diff --git a/drivers/misc/sgi-gru/grukservices.c b/drivers/misc/sgi-gru/grukservices.c index 967b9dd24..030769018 100644 --- a/drivers/misc/sgi-gru/grukservices.c +++ b/drivers/misc/sgi-gru/grukservices.c @@ -718,8 +718,8 @@ cberr: static int send_message_put_nacked(void *cb, struct gru_message_queue_desc *mqd, void *mesg, int lines) { - unsigned long m, *val = mesg, gpa, save; - int ret; + unsigned long m; + int ret, loops = 200; /* experimentally determined */ m = mqd->mq_gpa + (gru_get_amo_value_head(cb) << 6); if (lines == 2) { @@ -735,22 +735,28 @@ static int send_message_put_nacked(void *cb, struct gru_message_queue_desc *mqd, return MQE_OK; /* - * Send a cross-partition interrupt to the SSI that contains the target - * message queue. Normally, the interrupt is automatically delivered by - * hardware but some error conditions require explicit delivery. - * Use the GRU to deliver the interrupt. Otherwise partition failures + * Send a noop message in order to deliver a cross-partition interrupt + * to the SSI that contains the target message queue. Normally, the + * interrupt is automatically delivered by hardware following mesq + * operations, but some error conditions require explicit delivery. + * The noop message will trigger delivery. Otherwise partition failures * could cause unrecovered errors. */ - gpa = uv_global_gru_mmr_address(mqd->interrupt_pnode, UVH_IPI_INT); - save = *val; - *val = uv_hub_ipi_value(mqd->interrupt_apicid, mqd->interrupt_vector, - dest_Fixed); - gru_vstore_phys(cb, gpa, gru_get_tri(mesg), IAA_REGISTER, IMA); - ret = gru_wait(cb); - *val = save; - if (ret != CBS_IDLE) - return MQE_UNEXPECTED_CB_ERR; - return MQE_OK; + do { + ret = send_noop_message(cb, mqd, mesg); + } while ((ret == MQIE_AGAIN || ret == MQE_CONGESTION) && (loops-- > 0)); + + if (ret == MQIE_AGAIN || ret == MQE_CONGESTION) { + /* + * Don't indicate to the app to resend the message, as it's + * already been successfully sent. We simply send an OK + * (rather than fail the send with MQE_UNEXPECTED_CB_ERR), + * assuming that the other side is receiving enough + * interrupts to get this message processed anyway. + */ + ret = MQE_OK; + } + return ret; } /* diff --git a/drivers/misc/sram.c b/drivers/misc/sram.c index 69cdabea9..f84b53d6c 100644 --- a/drivers/misc/sram.c +++ b/drivers/misc/sram.c @@ -364,8 +364,8 @@ static int sram_probe(struct platform_device *pdev) sram->virt_base = devm_ioremap(sram->dev, res->start, size); else sram->virt_base = devm_ioremap_wc(sram->dev, res->start, size); - if (IS_ERR(sram->virt_base)) - return PTR_ERR(sram->virt_base); + if (!sram->virt_base) + return -ENOMEM; sram->pool = devm_gen_pool_create(sram->dev, ilog2(SRAM_GRANULARITY), NUMA_NO_NODE, NULL); diff --git a/drivers/misc/ti-st/st_kim.c b/drivers/misc/ti-st/st_kim.c index c976d961b..3c4399251 100644 --- a/drivers/misc/ti-st/st_kim.c +++ b/drivers/misc/ti-st/st_kim.c @@ -78,7 +78,6 @@ static void validate_firmware_response(struct kim_data_s *kim_gdata) memcpy(kim_gdata->resp_buffer, kim_gdata->rx_skb->data, kim_gdata->rx_skb->len); - complete_all(&kim_gdata->kim_rcvd); kim_gdata->rx_state = ST_W4_PACKET_TYPE; kim_gdata->rx_skb = NULL; kim_gdata->rx_count = 0; |