diff options
Diffstat (limited to 'drivers')
266 files changed, 2430 insertions, 1842 deletions
diff --git a/drivers/acpi/apei/apei-base.c b/drivers/acpi/apei/apei-base.c index 00a783661d0..46f80e2c92f 100644 --- a/drivers/acpi/apei/apei-base.c +++ b/drivers/acpi/apei/apei-base.c @@ -590,6 +590,9 @@ static int apei_check_gar(struct acpi_generic_address *reg, u64 *paddr,  	if (bit_width == 32 && bit_offset == 0 && (*paddr & 0x03) == 0 &&  	    *access_bit_width < 32)  		*access_bit_width = 32; +	else if (bit_width == 64 && bit_offset == 0 && (*paddr & 0x07) == 0 && +	    *access_bit_width < 64) +		*access_bit_width = 64;  	if ((bit_width + bit_offset) > *access_bit_width) {  		pr_warning(FW_BUG APEI_PFX diff --git a/drivers/acpi/apei/cper.c b/drivers/acpi/apei/cper.c index e6defd86b42..1e5d8a40101 100644 --- a/drivers/acpi/apei/cper.c +++ b/drivers/acpi/apei/cper.c @@ -29,6 +29,7 @@  #include <linux/time.h>  #include <linux/cper.h>  #include <linux/acpi.h> +#include <linux/pci.h>  #include <linux/aer.h>  /* @@ -249,6 +250,10 @@ static const char *cper_pcie_port_type_strs[] = {  static void cper_print_pcie(const char *pfx, const struct cper_sec_pcie *pcie,  			    const struct acpi_hest_generic_data *gdata)  { +#ifdef CONFIG_ACPI_APEI_PCIEAER +	struct pci_dev *dev; +#endif +  	if (pcie->validation_bits & CPER_PCIE_VALID_PORT_TYPE)  		printk("%s""port_type: %d, %s\n", pfx, pcie->port_type,  		       pcie->port_type < ARRAY_SIZE(cper_pcie_port_type_strs) ? @@ -281,10 +286,18 @@ static void cper_print_pcie(const char *pfx, const struct cper_sec_pcie *pcie,  	"%s""bridge: secondary_status: 0x%04x, control: 0x%04x\n",  	pfx, pcie->bridge.secondary_status, pcie->bridge.control);  #ifdef CONFIG_ACPI_APEI_PCIEAER -	if (pcie->validation_bits & CPER_PCIE_VALID_AER_INFO) { -		struct aer_capability_regs *aer_regs = (void *)pcie->aer_info; -		cper_print_aer(pfx, gdata->error_severity, aer_regs); +	dev = pci_get_domain_bus_and_slot(pcie->device_id.segment, +			pcie->device_id.bus, pcie->device_id.function); +	if (!dev) { +		pr_err("PCI AER Cannot get PCI device %04x:%02x:%02x.%d\n", +			pcie->device_id.segment, pcie->device_id.bus, +			pcie->device_id.slot, pcie->device_id.function); +		return;  	} +	if (pcie->validation_bits & CPER_PCIE_VALID_AER_INFO) +		cper_print_aer(pfx, dev, gdata->error_severity, +				(struct aer_capability_regs *) pcie->aer_info); +	pci_dev_put(dev);  #endif  } diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 3ff26786154..bd22f8667ee 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -250,7 +250,7 @@ acpi_physical_address __init acpi_os_get_root_pointer(void)  		return acpi_rsdp;  #endif -	if (efi_enabled) { +	if (efi_enabled(EFI_CONFIG_TABLES)) {  		if (efi.acpi20 != EFI_INVALID_TABLE_ADDR)  			return efi.acpi20;  		else if (efi.acpi != EFI_INVALID_TABLE_ADDR) diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index f1a5da44591..ed9a1cc690b 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -958,6 +958,9 @@ static int acpi_processor_setup_cpuidle_cx(struct acpi_processor *pr)  		return -EINVAL;  	} +	if (!dev) +		return -EINVAL; +  	dev->cpu = pr->id;  	if (max_cstate == 0) @@ -1149,6 +1152,7 @@ int acpi_processor_cst_has_changed(struct acpi_processor *pr)  		}  		/* Populate Updated C-state information */ +		acpi_processor_get_power_info(pr);  		acpi_processor_setup_cpuidle_states(pr);  		/* Enable all cpuidle devices */ diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c index 836bfe06904..53e7ac9403a 100644 --- a/drivers/acpi/processor_perflib.c +++ b/drivers/acpi/processor_perflib.c @@ -340,6 +340,13 @@ static void amd_fixup_frequency(struct acpi_processor_px *px, int i)  	if ((boot_cpu_data.x86 == 0x10 && boot_cpu_data.x86_model < 10)  	    || boot_cpu_data.x86 == 0x11) {  		rdmsr(MSR_AMD_PSTATE_DEF_BASE + index, lo, hi); +		/* +		 * MSR C001_0064+: +		 * Bit 63: PstateEn. Read-write. If set, the P-state is valid. +		 */ +		if (!(hi & BIT(31))) +			return; +  		fid = lo & 0x3f;  		did = (lo >> 6) & 7;  		if (boot_cpu_data.x86 == 0x10) diff --git a/drivers/atm/iphase.h b/drivers/atm/iphase.h index 6a0955e6d4f..53ecac5a216 100644 --- a/drivers/atm/iphase.h +++ b/drivers/atm/iphase.h @@ -636,82 +636,82 @@ struct rx_buf_desc {  #define SEG_BASE IPHASE5575_FRAG_CONTROL_REG_BASE    #define REASS_BASE IPHASE5575_REASS_CONTROL_REG_BASE   -typedef volatile u_int  freg_t; +typedef volatile u_int	ffreg_t;  typedef u_int   rreg_t;  typedef struct _ffredn_t { -        freg_t  idlehead_high;  /* Idle cell header (high)              */ -        freg_t  idlehead_low;   /* Idle cell header (low)               */ -        freg_t  maxrate;        /* Maximum rate                         */ -        freg_t  stparms;        /* Traffic Management Parameters        */ -        freg_t  abrubr_abr;     /* ABRUBR Priority Byte 1, TCR Byte 0   */ -        freg_t  rm_type;        /*                                      */ -        u_int   filler5[0x17 - 0x06]; -        freg_t  cmd_reg;        /* Command register                     */ -        u_int   filler18[0x20 - 0x18]; -        freg_t  cbr_base;       /* CBR Pointer Base                     */ -        freg_t  vbr_base;       /* VBR Pointer Base                     */ -        freg_t  abr_base;       /* ABR Pointer Base                     */ -        freg_t  ubr_base;       /* UBR Pointer Base                     */ -        u_int   filler24; -        freg_t  vbrwq_base;     /* VBR Wait Queue Base                  */ -        freg_t  abrwq_base;     /* ABR Wait Queue Base                  */ -        freg_t  ubrwq_base;     /* UBR Wait Queue Base                  */ -        freg_t  vct_base;       /* Main VC Table Base                   */ -        freg_t  vcte_base;      /* Extended Main VC Table Base          */ -        u_int   filler2a[0x2C - 0x2A]; -        freg_t  cbr_tab_beg;    /* CBR Table Begin                      */ -        freg_t  cbr_tab_end;    /* CBR Table End                        */ -        freg_t  cbr_pointer;    /* CBR Pointer                          */ -        u_int   filler2f[0x30 - 0x2F]; -        freg_t  prq_st_adr;     /* Packet Ready Queue Start Address     */ -        freg_t  prq_ed_adr;     /* Packet Ready Queue End Address       */ -        freg_t  prq_rd_ptr;     /* Packet Ready Queue read pointer      */ -        freg_t  prq_wr_ptr;     /* Packet Ready Queue write pointer     */ -        freg_t  tcq_st_adr;     /* Transmit Complete Queue Start Address*/ -        freg_t  tcq_ed_adr;     /* Transmit Complete Queue End Address  */ -        freg_t  tcq_rd_ptr;     /* Transmit Complete Queue read pointer */ -        freg_t  tcq_wr_ptr;     /* Transmit Complete Queue write pointer*/ -        u_int   filler38[0x40 - 0x38]; -        freg_t  queue_base;     /* Base address for PRQ and TCQ         */ -        freg_t  desc_base;      /* Base address of descriptor table     */ -        u_int   filler42[0x45 - 0x42]; -        freg_t  mode_reg_0;     /* Mode register 0                      */ -        freg_t  mode_reg_1;     /* Mode register 1                      */ -        freg_t  intr_status_reg;/* Interrupt Status register            */ -        freg_t  mask_reg;       /* Mask Register                        */ -        freg_t  cell_ctr_high1; /* Total cell transfer count (high)     */ -        freg_t  cell_ctr_lo1;   /* Total cell transfer count (low)      */ -        freg_t  state_reg;      /* Status register                      */ -        u_int   filler4c[0x58 - 0x4c]; -        freg_t  curr_desc_num;  /* Contains the current descriptor num  */ -        freg_t  next_desc;      /* Next descriptor                      */ -        freg_t  next_vc;        /* Next VC                              */ -        u_int   filler5b[0x5d - 0x5b]; -        freg_t  present_slot_cnt;/* Present slot count                  */ -        u_int   filler5e[0x6a - 0x5e]; -        freg_t  new_desc_num;   /* New descriptor number                */ -        freg_t  new_vc;         /* New VC                               */ -        freg_t  sched_tbl_ptr;  /* Schedule table pointer               */ -        freg_t  vbrwq_wptr;     /* VBR wait queue write pointer         */ -        freg_t  vbrwq_rptr;     /* VBR wait queue read pointer          */ -        freg_t  abrwq_wptr;     /* ABR wait queue write pointer         */ -        freg_t  abrwq_rptr;     /* ABR wait queue read pointer          */ -        freg_t  ubrwq_wptr;     /* UBR wait queue write pointer         */ -        freg_t  ubrwq_rptr;     /* UBR wait queue read pointer          */ -        freg_t  cbr_vc;         /* CBR VC                               */ -        freg_t  vbr_sb_vc;      /* VBR SB VC                            */ -        freg_t  abr_sb_vc;      /* ABR SB VC                            */ -        freg_t  ubr_sb_vc;      /* UBR SB VC                            */ -        freg_t  vbr_next_link;  /* VBR next link                        */ -        freg_t  abr_next_link;  /* ABR next link                        */ -        freg_t  ubr_next_link;  /* UBR next link                        */ -        u_int   filler7a[0x7c-0x7a]; -        freg_t  out_rate_head;  /* Out of rate head                     */ -        u_int   filler7d[0xca-0x7d]; /* pad out to full address space   */ -        freg_t  cell_ctr_high1_nc;/* Total cell transfer count (high)   */ -        freg_t  cell_ctr_lo1_nc;/* Total cell transfer count (low)      */ -        u_int   fillercc[0x100-0xcc]; /* pad out to full address space   */ +	ffreg_t	idlehead_high;	/* Idle cell header (high)		*/ +	ffreg_t	idlehead_low;	/* Idle cell header (low)		*/ +	ffreg_t	maxrate;	/* Maximum rate				*/ +	ffreg_t	stparms;	/* Traffic Management Parameters	*/ +	ffreg_t	abrubr_abr;	/* ABRUBR Priority Byte 1, TCR Byte 0	*/ +	ffreg_t	rm_type;	/*					*/ +	u_int	filler5[0x17 - 0x06]; +	ffreg_t	cmd_reg;	/* Command register			*/ +	u_int	filler18[0x20 - 0x18]; +	ffreg_t	cbr_base;	/* CBR Pointer Base			*/ +	ffreg_t	vbr_base;	/* VBR Pointer Base			*/ +	ffreg_t	abr_base;	/* ABR Pointer Base			*/ +	ffreg_t	ubr_base;	/* UBR Pointer Base			*/ +	u_int	filler24; +	ffreg_t	vbrwq_base;	/* VBR Wait Queue Base			*/ +	ffreg_t	abrwq_base;	/* ABR Wait Queue Base			*/ +	ffreg_t	ubrwq_base;	/* UBR Wait Queue Base			*/ +	ffreg_t	vct_base;	/* Main VC Table Base			*/ +	ffreg_t	vcte_base;	/* Extended Main VC Table Base		*/ +	u_int	filler2a[0x2C - 0x2A]; +	ffreg_t	cbr_tab_beg;	/* CBR Table Begin			*/ +	ffreg_t	cbr_tab_end;	/* CBR Table End			*/ +	ffreg_t	cbr_pointer;	/* CBR Pointer				*/ +	u_int	filler2f[0x30 - 0x2F]; +	ffreg_t	prq_st_adr;	/* Packet Ready Queue Start Address	*/ +	ffreg_t	prq_ed_adr;	/* Packet Ready Queue End Address	*/ +	ffreg_t	prq_rd_ptr;	/* Packet Ready Queue read pointer	*/ +	ffreg_t	prq_wr_ptr;	/* Packet Ready Queue write pointer	*/ +	ffreg_t	tcq_st_adr;	/* Transmit Complete Queue Start Address*/ +	ffreg_t	tcq_ed_adr;	/* Transmit Complete Queue End Address	*/ +	ffreg_t	tcq_rd_ptr;	/* Transmit Complete Queue read pointer */ +	ffreg_t	tcq_wr_ptr;	/* Transmit Complete Queue write pointer*/ +	u_int	filler38[0x40 - 0x38]; +	ffreg_t	queue_base;	/* Base address for PRQ and TCQ		*/ +	ffreg_t	desc_base;	/* Base address of descriptor table	*/ +	u_int	filler42[0x45 - 0x42]; +	ffreg_t	mode_reg_0;	/* Mode register 0			*/ +	ffreg_t	mode_reg_1;	/* Mode register 1			*/ +	ffreg_t	intr_status_reg;/* Interrupt Status register		*/ +	ffreg_t	mask_reg;	/* Mask Register			*/ +	ffreg_t	cell_ctr_high1; /* Total cell transfer count (high)	*/ +	ffreg_t	cell_ctr_lo1;	/* Total cell transfer count (low)	*/ +	ffreg_t	state_reg;	/* Status register			*/ +	u_int	filler4c[0x58 - 0x4c]; +	ffreg_t	curr_desc_num;	/* Contains the current descriptor num	*/ +	ffreg_t	next_desc;	/* Next descriptor			*/ +	ffreg_t	next_vc;	/* Next VC				*/ +	u_int	filler5b[0x5d - 0x5b]; +	ffreg_t	present_slot_cnt;/* Present slot count			*/ +	u_int	filler5e[0x6a - 0x5e]; +	ffreg_t	new_desc_num;	/* New descriptor number		*/ +	ffreg_t	new_vc;		/* New VC				*/ +	ffreg_t	sched_tbl_ptr;	/* Schedule table pointer		*/ +	ffreg_t	vbrwq_wptr;	/* VBR wait queue write pointer		*/ +	ffreg_t	vbrwq_rptr;	/* VBR wait queue read pointer		*/ +	ffreg_t	abrwq_wptr;	/* ABR wait queue write pointer		*/ +	ffreg_t	abrwq_rptr;	/* ABR wait queue read pointer		*/ +	ffreg_t	ubrwq_wptr;	/* UBR wait queue write pointer		*/ +	ffreg_t	ubrwq_rptr;	/* UBR wait queue read pointer		*/ +	ffreg_t	cbr_vc;		/* CBR VC				*/ +	ffreg_t	vbr_sb_vc;	/* VBR SB VC				*/ +	ffreg_t	abr_sb_vc;	/* ABR SB VC				*/ +	ffreg_t	ubr_sb_vc;	/* UBR SB VC				*/ +	ffreg_t	vbr_next_link;	/* VBR next link			*/ +	ffreg_t	abr_next_link;	/* ABR next link			*/ +	ffreg_t	ubr_next_link;	/* UBR next link			*/ +	u_int	filler7a[0x7c-0x7a]; +	ffreg_t	out_rate_head;	/* Out of rate head			*/ +	u_int	filler7d[0xca-0x7d]; /* pad out to full address space	*/ +	ffreg_t	cell_ctr_high1_nc;/* Total cell transfer count (high)	*/ +	ffreg_t	cell_ctr_lo1_nc;/* Total cell transfer count (low)	*/ +	u_int	fillercc[0x100-0xcc]; /* pad out to full address space	 */  } ffredn_t;  typedef struct _rfredn_t { diff --git a/drivers/base/regmap/regmap-debugfs.c b/drivers/base/regmap/regmap-debugfs.c index 46a213a596e..d9a6c94ce42 100644 --- a/drivers/base/regmap/regmap-debugfs.c +++ b/drivers/base/regmap/regmap-debugfs.c @@ -121,8 +121,6 @@ static unsigned int regmap_debugfs_get_dump_start(struct regmap *map,  		c->max = p - 1;  		list_add_tail(&c->list,  			      &map->debugfs_off_cache); -	} else { -		return base;  	}  	/* diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index 42d5cb0f503..f00b059c057 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c @@ -1106,7 +1106,7 @@ EXPORT_SYMBOL_GPL(regmap_raw_write);   * @val_count: Number of registers to write   *   * This function is intended to be used for writing a large block of - * data to be device either in single transfer or multiple transfer. + * data to the device either in single transfer or multiple transfer.   *   * A value of zero will be returned on success, a negative errno will   * be returned in error cases. diff --git a/drivers/bcma/bcma_private.h b/drivers/bcma/bcma_private.h index 19e3fbfd575..cb0c4548857 100644 --- a/drivers/bcma/bcma_private.h +++ b/drivers/bcma/bcma_private.h @@ -94,11 +94,16 @@ void bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc);  #ifdef CONFIG_BCMA_DRIVER_GPIO  /* driver_gpio.c */  int bcma_gpio_init(struct bcma_drv_cc *cc); +int bcma_gpio_unregister(struct bcma_drv_cc *cc);  #else  static inline int bcma_gpio_init(struct bcma_drv_cc *cc)  {  	return -ENOTSUPP;  } +static inline int bcma_gpio_unregister(struct bcma_drv_cc *cc) +{ +	return 0; +}  #endif /* CONFIG_BCMA_DRIVER_GPIO */  #endif diff --git a/drivers/bcma/driver_chipcommon_nflash.c b/drivers/bcma/driver_chipcommon_nflash.c index dbda91e4dff..1f0b83e18f6 100644 --- a/drivers/bcma/driver_chipcommon_nflash.c +++ b/drivers/bcma/driver_chipcommon_nflash.c @@ -21,7 +21,7 @@ int bcma_nflash_init(struct bcma_drv_cc *cc)  	struct bcma_bus *bus = cc->core->bus;  	if (bus->chipinfo.id != BCMA_CHIP_ID_BCM4706 && -	    cc->core->id.rev != 0x38) { +	    cc->core->id.rev != 38) {  		bcma_err(bus, "NAND flash on unsupported board!\n");  		return -ENOTSUPP;  	} diff --git a/drivers/bcma/driver_gpio.c b/drivers/bcma/driver_gpio.c index 9a6f585da2d..71f755c06fc 100644 --- a/drivers/bcma/driver_gpio.c +++ b/drivers/bcma/driver_gpio.c @@ -96,3 +96,8 @@ int bcma_gpio_init(struct bcma_drv_cc *cc)  	return gpiochip_add(chip);  } + +int bcma_gpio_unregister(struct bcma_drv_cc *cc) +{ +	return gpiochip_remove(&cc->gpio); +} diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c index 4a92f647b58..324f9debda8 100644 --- a/drivers/bcma/main.c +++ b/drivers/bcma/main.c @@ -268,6 +268,13 @@ int bcma_bus_register(struct bcma_bus *bus)  void bcma_bus_unregister(struct bcma_bus *bus)  {  	struct bcma_device *cores[3]; +	int err; + +	err = bcma_gpio_unregister(&bus->drv_cc); +	if (err == -EBUSY) +		bcma_err(bus, "Some GPIOs are still in use.\n"); +	else if (err) +		bcma_err(bus, "Can not unregister GPIO driver: %i\n", err);  	cores[0] = bcma_find_core(bus, BCMA_CORE_MIPS_74K);  	cores[1] = bcma_find_core(bus, BCMA_CORE_PCIE); diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c index f58a4a4b4df..2b8303ad63c 100644 --- a/drivers/block/drbd/drbd_req.c +++ b/drivers/block/drbd/drbd_req.c @@ -168,7 +168,7 @@ static void wake_all_senders(struct drbd_tconn *tconn) {  }  /* must hold resource->req_lock */ -static void start_new_tl_epoch(struct drbd_tconn *tconn) +void start_new_tl_epoch(struct drbd_tconn *tconn)  {  	/* no point closing an epoch, if it is empty, anyways. */  	if (tconn->current_tle_writes == 0) diff --git a/drivers/block/drbd/drbd_req.h b/drivers/block/drbd/drbd_req.h index 016de6b8bb5..c08d22964d0 100644 --- a/drivers/block/drbd/drbd_req.h +++ b/drivers/block/drbd/drbd_req.h @@ -267,6 +267,7 @@ struct bio_and_error {  	int error;  }; +extern void start_new_tl_epoch(struct drbd_tconn *tconn);  extern void drbd_req_destroy(struct kref *kref);  extern void _req_may_be_done(struct drbd_request *req,  		struct bio_and_error *m); diff --git a/drivers/block/drbd/drbd_state.c b/drivers/block/drbd/drbd_state.c index 53bf6182bac..0fe220cfb9e 100644 --- a/drivers/block/drbd/drbd_state.c +++ b/drivers/block/drbd/drbd_state.c @@ -931,6 +931,7 @@ __drbd_set_state(struct drbd_conf *mdev, union drbd_state ns,  	enum drbd_state_rv rv = SS_SUCCESS;  	enum sanitize_state_warnings ssw;  	struct after_state_chg_work *ascw; +	bool did_remote, should_do_remote;  	os = drbd_read_state(mdev); @@ -981,11 +982,17 @@ __drbd_set_state(struct drbd_conf *mdev, union drbd_state ns,  	    (os.disk != D_DISKLESS && ns.disk == D_DISKLESS))  		atomic_inc(&mdev->local_cnt); +	did_remote = drbd_should_do_remote(mdev->state);  	mdev->state.i = ns.i; +	should_do_remote = drbd_should_do_remote(mdev->state);  	mdev->tconn->susp = ns.susp;  	mdev->tconn->susp_nod = ns.susp_nod;  	mdev->tconn->susp_fen = ns.susp_fen; +	/* put replicated vs not-replicated requests in seperate epochs */ +	if (did_remote != should_do_remote) +		start_new_tl_epoch(mdev->tconn); +  	if (os.disk == D_ATTACHING && ns.disk >= D_NEGOTIATING)  		drbd_print_uuids(mdev, "attached to UUIDs"); diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c index 9694dd99bbb..3fd10099045 100644 --- a/drivers/block/mtip32xx/mtip32xx.c +++ b/drivers/block/mtip32xx/mtip32xx.c @@ -626,12 +626,13 @@ static void mtip_timeout_function(unsigned long int data)  		}  	} -	if (cmdto_cnt && !test_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags)) { +	if (cmdto_cnt) {  		print_tags(port->dd, "timed out", tagaccum, cmdto_cnt); - -		mtip_restart_port(port); +		if (!test_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags)) { +			mtip_restart_port(port); +			wake_up_interruptible(&port->svc_wait); +		}  		clear_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags); -		wake_up_interruptible(&port->svc_wait);  	}  	if (port->ic_pause_timer) { @@ -3887,7 +3888,12 @@ static int mtip_block_remove(struct driver_data *dd)  	 * Delete our gendisk structure. This also removes the device  	 * from /dev  	 */ -	del_gendisk(dd->disk); +	if (dd->disk) { +		if (dd->disk->queue) +			del_gendisk(dd->disk); +		else +			put_disk(dd->disk); +	}  	spin_lock(&rssd_index_lock);  	ida_remove(&rssd_index_ida, dd->index); @@ -3921,7 +3927,13 @@ static int mtip_block_shutdown(struct driver_data *dd)  		"Shutting down %s ...\n", dd->disk->disk_name);  	/* Delete our gendisk structure, and cleanup the blk queue. */ -	del_gendisk(dd->disk); +	if (dd->disk) { +		if (dd->disk->queue) +			del_gendisk(dd->disk); +		else +			put_disk(dd->disk); +	} +  	spin_lock(&rssd_index_lock);  	ida_remove(&rssd_index_ida, dd->index); diff --git a/drivers/block/sunvdc.c b/drivers/block/sunvdc.c index 564156a8e57..5814deb6963 100644 --- a/drivers/block/sunvdc.c +++ b/drivers/block/sunvdc.c @@ -461,7 +461,7 @@ static int generic_request(struct vdc_port *port, u8 op, void *buf, int len)  	int op_len, err;  	void *req_buf; -	if (!(((u64)1 << ((u64)op - 1)) & port->operations)) +	if (!(((u64)1 << (u64)op) & port->operations))  		return -EOPNOTSUPP;  	switch (op) { diff --git a/drivers/block/xen-blkback/blkback.c b/drivers/block/xen-blkback/blkback.c index 74374fb762a..5ac841ff6cc 100644 --- a/drivers/block/xen-blkback/blkback.c +++ b/drivers/block/xen-blkback/blkback.c @@ -161,10 +161,12 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif,  static void make_response(struct xen_blkif *blkif, u64 id,  			  unsigned short op, int st); -#define foreach_grant(pos, rbtree, node) \ -	for ((pos) = container_of(rb_first((rbtree)), typeof(*(pos)), node); \ +#define foreach_grant_safe(pos, n, rbtree, node) \ +	for ((pos) = container_of(rb_first((rbtree)), typeof(*(pos)), node), \ +	     (n) = rb_next(&(pos)->node); \  	     &(pos)->node != NULL; \ -	     (pos) = container_of(rb_next(&(pos)->node), typeof(*(pos)), node)) +	     (pos) = container_of(n, typeof(*(pos)), node), \ +	     (n) = (&(pos)->node != NULL) ? rb_next(&(pos)->node) : NULL)  static void add_persistent_gnt(struct rb_root *root, @@ -217,10 +219,11 @@ static void free_persistent_gnts(struct rb_root *root, unsigned int num)  	struct gnttab_unmap_grant_ref unmap[BLKIF_MAX_SEGMENTS_PER_REQUEST];  	struct page *pages[BLKIF_MAX_SEGMENTS_PER_REQUEST];  	struct persistent_gnt *persistent_gnt; +	struct rb_node *n;  	int ret = 0;  	int segs_to_unmap = 0; -	foreach_grant(persistent_gnt, root, node) { +	foreach_grant_safe(persistent_gnt, n, root, node) {  		BUG_ON(persistent_gnt->handle ==  			BLKBACK_INVALID_HANDLE);  		gnttab_set_unmap_op(&unmap[segs_to_unmap], @@ -230,9 +233,6 @@ static void free_persistent_gnts(struct rb_root *root, unsigned int num)  			persistent_gnt->handle);  		pages[segs_to_unmap] = persistent_gnt->page; -		rb_erase(&persistent_gnt->node, root); -		kfree(persistent_gnt); -		num--;  		if (++segs_to_unmap == BLKIF_MAX_SEGMENTS_PER_REQUEST ||  			!rb_next(&persistent_gnt->node)) { @@ -241,6 +241,10 @@ static void free_persistent_gnts(struct rb_root *root, unsigned int num)  			BUG_ON(ret);  			segs_to_unmap = 0;  		} + +		rb_erase(&persistent_gnt->node, root); +		kfree(persistent_gnt); +		num--;  	}  	BUG_ON(num != 0);  } diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index 96e9b00db08..11043c18ac5 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c @@ -792,6 +792,7 @@ static void blkif_free(struct blkfront_info *info, int suspend)  {  	struct llist_node *all_gnts;  	struct grant *persistent_gnt; +	struct llist_node *n;  	/* Prevent new requests being issued until we fix things up. */  	spin_lock_irq(&info->io_lock); @@ -804,7 +805,7 @@ static void blkif_free(struct blkfront_info *info, int suspend)  	/* Remove all persistent grants */  	if (info->persistent_gnts_c) {  		all_gnts = llist_del_all(&info->persistent_gnts); -		llist_for_each_entry(persistent_gnt, all_gnts, node) { +		llist_for_each_entry_safe(persistent_gnt, n, all_gnts, node) {  			gnttab_end_foreign_access(persistent_gnt->gref, 0, 0UL);  			__free_page(pfn_to_page(persistent_gnt->pfn));  			kfree(persistent_gnt); @@ -835,7 +836,7 @@ static void blkif_free(struct blkfront_info *info, int suspend)  static void blkif_completion(struct blk_shadow *s, struct blkfront_info *info,  			     struct blkif_response *bret)  { -	int i; +	int i = 0;  	struct bio_vec *bvec;  	struct req_iterator iter;  	unsigned long flags; @@ -852,7 +853,8 @@ static void blkif_completion(struct blk_shadow *s, struct blkfront_info *info,  		 */  		rq_for_each_segment(bvec, s->request, iter) {  			BUG_ON((bvec->bv_offset + bvec->bv_len) > PAGE_SIZE); -			i = offset >> PAGE_SHIFT; +			if (bvec->bv_offset < offset) +				i++;  			BUG_ON(i >= s->req.u.rw.nr_segments);  			shared_data = kmap_atomic(  				pfn_to_page(s->grants_used[i]->pfn)); @@ -861,7 +863,7 @@ static void blkif_completion(struct blk_shadow *s, struct blkfront_info *info,  				bvec->bv_len);  			bvec_kunmap_irq(bvec_data, &flags);  			kunmap_atomic(shared_data); -			offset += bvec->bv_len; +			offset = bvec->bv_offset + bvec->bv_len;  		}  	}  	/* Add the persistent grant into the list of free grants */ diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c index b00000e8aef..33c9a44a967 100644 --- a/drivers/bluetooth/ath3k.c +++ b/drivers/bluetooth/ath3k.c @@ -77,10 +77,15 @@ static struct usb_device_id ath3k_table[] = {  	{ USB_DEVICE(0x0CF3, 0x311D) },  	{ USB_DEVICE(0x13d3, 0x3375) },  	{ USB_DEVICE(0x04CA, 0x3005) }, +	{ USB_DEVICE(0x04CA, 0x3006) }, +	{ USB_DEVICE(0x04CA, 0x3008) },  	{ USB_DEVICE(0x13d3, 0x3362) },  	{ USB_DEVICE(0x0CF3, 0xE004) },  	{ USB_DEVICE(0x0930, 0x0219) },  	{ USB_DEVICE(0x0489, 0xe057) }, +	{ USB_DEVICE(0x13d3, 0x3393) }, +	{ USB_DEVICE(0x0489, 0xe04e) }, +	{ USB_DEVICE(0x0489, 0xe056) },  	/* Atheros AR5BBU12 with sflash firmware */  	{ USB_DEVICE(0x0489, 0xE02C) }, @@ -104,10 +109,15 @@ static struct usb_device_id ath3k_blist_tbl[] = {  	{ USB_DEVICE(0x0cf3, 0x311D), .driver_info = BTUSB_ATH3012 },  	{ USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },  	{ USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 }, +	{ USB_DEVICE(0x04ca, 0x3006), .driver_info = BTUSB_ATH3012 }, +	{ USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 },  	{ USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 },  	{ USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 },  	{ USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 },  	{ USB_DEVICE(0x0489, 0xe057), .driver_info = BTUSB_ATH3012 }, +	{ USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 }, +	{ USB_DEVICE(0x0489, 0xe04e), .driver_info = BTUSB_ATH3012 }, +	{ USB_DEVICE(0x0489, 0xe056), .driver_info = BTUSB_ATH3012 },  	/* Atheros AR5BBU22 with sflash firmware */  	{ USB_DEVICE(0x0489, 0xE03C), .driver_info = BTUSB_ATH3012 }, diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index a1d4ede5b89..7e351e34547 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -135,10 +135,15 @@ static struct usb_device_id blacklist_table[] = {  	{ USB_DEVICE(0x0cf3, 0x311d), .driver_info = BTUSB_ATH3012 },  	{ USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },  	{ USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 }, +	{ USB_DEVICE(0x04ca, 0x3006), .driver_info = BTUSB_ATH3012 }, +	{ USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 },  	{ USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 },  	{ USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 },  	{ USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 },  	{ USB_DEVICE(0x0489, 0xe057), .driver_info = BTUSB_ATH3012 }, +	{ USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 }, +	{ USB_DEVICE(0x0489, 0xe04e), .driver_info = BTUSB_ATH3012 }, +	{ USB_DEVICE(0x0489, 0xe056), .driver_info = BTUSB_ATH3012 },  	/* Atheros AR5BBU12 with sflash firmware */  	{ USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE }, diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index 684b0d53764..ee4dbeafb37 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c @@ -2062,7 +2062,8 @@ static void virtcons_remove(struct virtio_device *vdev)  	/* Disable interrupts for vqs */  	vdev->config->reset(vdev);  	/* Finish up work that's lined up */ -	cancel_work_sync(&portdev->control_work); +	if (use_multiport(portdev)) +		cancel_work_sync(&portdev->control_work);  	list_for_each_entry_safe(port, port2, &portdev->ports, list)  		unplug_port(port); diff --git a/drivers/clk/mvebu/clk-cpu.c b/drivers/clk/mvebu/clk-cpu.c index ff004578a11..9dd2551a0a4 100644 --- a/drivers/clk/mvebu/clk-cpu.c +++ b/drivers/clk/mvebu/clk-cpu.c @@ -124,7 +124,7 @@ void __init of_cpu_clk_setup(struct device_node *node)  	clks = kzalloc(ncpus * sizeof(*clks), GFP_KERNEL);  	if (WARN_ON(!clks)) -		return; +		goto clks_out;  	for_each_node_by_type(dn, "cpu") {  		struct clk_init_data init; @@ -134,11 +134,11 @@ void __init of_cpu_clk_setup(struct device_node *node)  		int cpu, err;  		if (WARN_ON(!clk_name)) -			return; +			goto bail_out;  		err = of_property_read_u32(dn, "reg", &cpu);  		if (WARN_ON(err)) -			return; +			goto bail_out;  		sprintf(clk_name, "cpu%d", cpu);  		parent_clk = of_clk_get(node, 0); @@ -167,6 +167,9 @@ void __init of_cpu_clk_setup(struct device_node *node)  	return;  bail_out:  	kfree(clks); +	while(ncpus--) +		kfree(cpuclk[ncpus].clk_name); +clks_out:  	kfree(cpuclk);  } diff --git a/drivers/cpufreq/Kconfig.x86 b/drivers/cpufreq/Kconfig.x86 index 934854ae5eb..7227cd73404 100644 --- a/drivers/cpufreq/Kconfig.x86 +++ b/drivers/cpufreq/Kconfig.x86 @@ -106,7 +106,7 @@ config X86_POWERNOW_K7_ACPI  config X86_POWERNOW_K8  	tristate "AMD Opteron/Athlon64 PowerNow!"  	select CPU_FREQ_TABLE -	depends on ACPI && ACPI_PROCESSOR +	depends on ACPI && ACPI_PROCESSOR && X86_ACPI_CPUFREQ  	help  	  This adds the CPUFreq driver for K8/early Opteron/Athlon64 processors.  	  Support for K10 and newer processors is now in acpi-cpufreq. diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c index 0d048f6a2b2..7b0d49d78c6 100644 --- a/drivers/cpufreq/acpi-cpufreq.c +++ b/drivers/cpufreq/acpi-cpufreq.c @@ -1030,4 +1030,11 @@ MODULE_PARM_DESC(acpi_pstate_strict,  late_initcall(acpi_cpufreq_init);  module_exit(acpi_cpufreq_exit); +static const struct x86_cpu_id acpi_cpufreq_ids[] = { +	X86_FEATURE_MATCH(X86_FEATURE_ACPI), +	X86_FEATURE_MATCH(X86_FEATURE_HW_PSTATE), +	{} +}; +MODULE_DEVICE_TABLE(x86cpu, acpi_cpufreq_ids); +  MODULE_ALIAS("acpi"); diff --git a/drivers/cpufreq/cpufreq-cpu0.c b/drivers/cpufreq/cpufreq-cpu0.c index 52bf36d599f..debc5a7c8db 100644 --- a/drivers/cpufreq/cpufreq-cpu0.c +++ b/drivers/cpufreq/cpufreq-cpu0.c @@ -71,12 +71,15 @@ static int cpu0_set_target(struct cpufreq_policy *policy,  	}  	if (cpu_reg) { +		rcu_read_lock();  		opp = opp_find_freq_ceil(cpu_dev, &freq_Hz);  		if (IS_ERR(opp)) { +			rcu_read_unlock();  			pr_err("failed to find OPP for %ld\n", freq_Hz);  			return PTR_ERR(opp);  		}  		volt = opp_get_voltage(opp); +		rcu_read_unlock();  		tol = volt * voltage_tolerance / 100;  		volt_old = regulator_get_voltage(cpu_reg);  	} @@ -236,12 +239,14 @@ static int cpu0_cpufreq_driver_init(void)  		 */  		for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++)  			; +		rcu_read_lock();  		opp = opp_find_freq_exact(cpu_dev,  				freq_table[0].frequency * 1000, true);  		min_uV = opp_get_voltage(opp);  		opp = opp_find_freq_exact(cpu_dev,  				freq_table[i-1].frequency * 1000, true);  		max_uV = opp_get_voltage(opp); +		rcu_read_unlock();  		ret = regulator_set_voltage_time(cpu_reg, min_uV, max_uV);  		if (ret > 0)  			transition_latency += ret * 1000; diff --git a/drivers/cpufreq/omap-cpufreq.c b/drivers/cpufreq/omap-cpufreq.c index 1f3417a8322..97102b05843 100644 --- a/drivers/cpufreq/omap-cpufreq.c +++ b/drivers/cpufreq/omap-cpufreq.c @@ -110,13 +110,16 @@ static int omap_target(struct cpufreq_policy *policy,  	freq = ret;  	if (mpu_reg) { +		rcu_read_lock();  		opp = opp_find_freq_ceil(mpu_dev, &freq);  		if (IS_ERR(opp)) { +			rcu_read_unlock();  			dev_err(mpu_dev, "%s: unable to find MPU OPP for %d\n",  				__func__, freqs.new);  			return -EINVAL;  		}  		volt = opp_get_voltage(opp); +		rcu_read_unlock();  		tol = volt * OPP_TOLERANCE / 100;  		volt_old = regulator_get_voltage(mpu_reg);  	} diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index 53766f39aad..3b367973a80 100644 --- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c @@ -994,6 +994,11 @@ module_exit(devfreq_exit);   * @freq:	The frequency given to target function   * @flags:	Flags handed from devfreq framework.   * + * Locking: This function must be called under rcu_read_lock(). opp is a rcu + * protected pointer. The reason for the same is that the opp pointer which is + * returned will remain valid for use with opp_get_{voltage, freq} only while + * under the locked area. The pointer returned must be used prior to unlocking + * with rcu_read_unlock() to maintain the integrity of the pointer.   */  struct opp *devfreq_recommended_opp(struct device *dev, unsigned long *freq,  				    u32 flags) diff --git a/drivers/devfreq/exynos4_bus.c b/drivers/devfreq/exynos4_bus.c index 80c745e8308..46d94e9e95b 100644 --- a/drivers/devfreq/exynos4_bus.c +++ b/drivers/devfreq/exynos4_bus.c @@ -73,6 +73,16 @@ enum busclk_level_idx {  #define EX4210_LV_NUM	(LV_2 + 1)  #define EX4x12_LV_NUM	(LV_4 + 1) +/** + * struct busfreq_opp_info - opp information for bus + * @rate:	Frequency in hertz + * @volt:	Voltage in microvolts corresponding to this OPP + */ +struct busfreq_opp_info { +	unsigned long rate; +	unsigned long volt; +}; +  struct busfreq_data {  	enum exynos4_busf_type type;  	struct device *dev; @@ -80,7 +90,7 @@ struct busfreq_data {  	bool disabled;  	struct regulator *vdd_int;  	struct regulator *vdd_mif; /* Exynos4412/4212 only */ -	struct opp *curr_opp; +	struct busfreq_opp_info curr_oppinfo;  	struct exynos4_ppmu dmc[2];  	struct notifier_block pm_notifier; @@ -296,13 +306,14 @@ static unsigned int exynos4x12_clkdiv_sclkip[][3] = {  }; -static int exynos4210_set_busclk(struct busfreq_data *data, struct opp *opp) +static int exynos4210_set_busclk(struct busfreq_data *data, +				 struct busfreq_opp_info *oppi)  {  	unsigned int index;  	unsigned int tmp;  	for (index = LV_0; index < EX4210_LV_NUM; index++) -		if (opp_get_freq(opp) == exynos4210_busclk_table[index].clk) +		if (oppi->rate == exynos4210_busclk_table[index].clk)  			break;  	if (index == EX4210_LV_NUM) @@ -361,13 +372,14 @@ static int exynos4210_set_busclk(struct busfreq_data *data, struct opp *opp)  	return 0;  } -static int exynos4x12_set_busclk(struct busfreq_data *data, struct opp *opp) +static int exynos4x12_set_busclk(struct busfreq_data *data, +				 struct busfreq_opp_info *oppi)  {  	unsigned int index;  	unsigned int tmp;  	for (index = LV_0; index < EX4x12_LV_NUM; index++) -		if (opp_get_freq(opp) == exynos4x12_mifclk_table[index].clk) +		if (oppi->rate == exynos4x12_mifclk_table[index].clk)  			break;  	if (index == EX4x12_LV_NUM) @@ -576,11 +588,12 @@ static int exynos4x12_get_intspec(unsigned long mifclk)  	return -EINVAL;  } -static int exynos4_bus_setvolt(struct busfreq_data *data, struct opp *opp, -			       struct opp *oldopp) +static int exynos4_bus_setvolt(struct busfreq_data *data, +			       struct busfreq_opp_info *oppi, +			       struct busfreq_opp_info *oldoppi)  {  	int err = 0, tmp; -	unsigned long volt = opp_get_voltage(opp); +	unsigned long volt = oppi->volt;  	switch (data->type) {  	case TYPE_BUSF_EXYNOS4210: @@ -595,11 +608,11 @@ static int exynos4_bus_setvolt(struct busfreq_data *data, struct opp *opp,  		if (err)  			break; -		tmp = exynos4x12_get_intspec(opp_get_freq(opp)); +		tmp = exynos4x12_get_intspec(oppi->rate);  		if (tmp < 0) {  			err = tmp;  			regulator_set_voltage(data->vdd_mif, -					      opp_get_voltage(oldopp), +					      oldoppi->volt,  					      MAX_SAFEVOLT);  			break;  		} @@ -609,7 +622,7 @@ static int exynos4_bus_setvolt(struct busfreq_data *data, struct opp *opp,  		/*  Try to recover */  		if (err)  			regulator_set_voltage(data->vdd_mif, -					      opp_get_voltage(oldopp), +					      oldoppi->volt,  					      MAX_SAFEVOLT);  		break;  	default: @@ -626,17 +639,26 @@ static int exynos4_bus_target(struct device *dev, unsigned long *_freq,  	struct platform_device *pdev = container_of(dev, struct platform_device,  						    dev);  	struct busfreq_data *data = platform_get_drvdata(pdev); -	struct opp *opp = devfreq_recommended_opp(dev, _freq, flags); -	unsigned long freq = opp_get_freq(opp); -	unsigned long old_freq = opp_get_freq(data->curr_opp); +	struct opp *opp; +	unsigned long freq; +	unsigned long old_freq = data->curr_oppinfo.rate; +	struct busfreq_opp_info	new_oppinfo; -	if (IS_ERR(opp)) +	rcu_read_lock(); +	opp = devfreq_recommended_opp(dev, _freq, flags); +	if (IS_ERR(opp)) { +		rcu_read_unlock();  		return PTR_ERR(opp); +	} +	new_oppinfo.rate = opp_get_freq(opp); +	new_oppinfo.volt = opp_get_voltage(opp); +	rcu_read_unlock(); +	freq = new_oppinfo.rate;  	if (old_freq == freq)  		return 0; -	dev_dbg(dev, "targetting %lukHz %luuV\n", freq, opp_get_voltage(opp)); +	dev_dbg(dev, "targetting %lukHz %luuV\n", freq, new_oppinfo.volt);  	mutex_lock(&data->lock); @@ -644,17 +666,18 @@ static int exynos4_bus_target(struct device *dev, unsigned long *_freq,  		goto out;  	if (old_freq < freq) -		err = exynos4_bus_setvolt(data, opp, data->curr_opp); +		err = exynos4_bus_setvolt(data, &new_oppinfo, +					  &data->curr_oppinfo);  	if (err)  		goto out;  	if (old_freq != freq) {  		switch (data->type) {  		case TYPE_BUSF_EXYNOS4210: -			err = exynos4210_set_busclk(data, opp); +			err = exynos4210_set_busclk(data, &new_oppinfo);  			break;  		case TYPE_BUSF_EXYNOS4x12: -			err = exynos4x12_set_busclk(data, opp); +			err = exynos4x12_set_busclk(data, &new_oppinfo);  			break;  		default:  			err = -EINVAL; @@ -664,11 +687,12 @@ static int exynos4_bus_target(struct device *dev, unsigned long *_freq,  		goto out;  	if (old_freq > freq) -		err = exynos4_bus_setvolt(data, opp, data->curr_opp); +		err = exynos4_bus_setvolt(data, &new_oppinfo, +					  &data->curr_oppinfo);  	if (err)  		goto out; -	data->curr_opp = opp; +	data->curr_oppinfo = new_oppinfo;  out:  	mutex_unlock(&data->lock);  	return err; @@ -702,7 +726,7 @@ static int exynos4_bus_get_dev_status(struct device *dev,  	exynos4_read_ppmu(data);  	busier_dmc = exynos4_get_busier_dmc(data); -	stat->current_frequency = opp_get_freq(data->curr_opp); +	stat->current_frequency = data->curr_oppinfo.rate;  	if (busier_dmc)  		addr = S5P_VA_DMC1; @@ -933,6 +957,7 @@ static int exynos4_busfreq_pm_notifier_event(struct notifier_block *this,  	struct busfreq_data *data = container_of(this, struct busfreq_data,  						 pm_notifier);  	struct opp *opp; +	struct busfreq_opp_info	new_oppinfo;  	unsigned long maxfreq = ULONG_MAX;  	int err = 0; @@ -943,18 +968,29 @@ static int exynos4_busfreq_pm_notifier_event(struct notifier_block *this,  		data->disabled = true; +		rcu_read_lock();  		opp = opp_find_freq_floor(data->dev, &maxfreq); +		if (IS_ERR(opp)) { +			rcu_read_unlock(); +			dev_err(data->dev, "%s: unable to find a min freq\n", +				__func__); +			return PTR_ERR(opp); +		} +		new_oppinfo.rate = opp_get_freq(opp); +		new_oppinfo.volt = opp_get_voltage(opp); +		rcu_read_unlock(); -		err = exynos4_bus_setvolt(data, opp, data->curr_opp); +		err = exynos4_bus_setvolt(data, &new_oppinfo, +					  &data->curr_oppinfo);  		if (err)  			goto unlock;  		switch (data->type) {  		case TYPE_BUSF_EXYNOS4210: -			err = exynos4210_set_busclk(data, opp); +			err = exynos4210_set_busclk(data, &new_oppinfo);  			break;  		case TYPE_BUSF_EXYNOS4x12: -			err = exynos4x12_set_busclk(data, opp); +			err = exynos4x12_set_busclk(data, &new_oppinfo);  			break;  		default:  			err = -EINVAL; @@ -962,7 +998,7 @@ static int exynos4_busfreq_pm_notifier_event(struct notifier_block *this,  		if (err)  			goto unlock; -		data->curr_opp = opp; +		data->curr_oppinfo = new_oppinfo;  unlock:  		mutex_unlock(&data->lock);  		if (err) @@ -1027,13 +1063,17 @@ static int exynos4_busfreq_probe(struct platform_device *pdev)  		}  	} +	rcu_read_lock();  	opp = opp_find_freq_floor(dev, &exynos4_devfreq_profile.initial_freq);  	if (IS_ERR(opp)) { +		rcu_read_unlock();  		dev_err(dev, "Invalid initial frequency %lu kHz.\n",  			exynos4_devfreq_profile.initial_freq);  		return PTR_ERR(opp);  	} -	data->curr_opp = opp; +	data->curr_oppinfo.rate = opp_get_freq(opp); +	data->curr_oppinfo.volt = opp_get_voltage(opp); +	rcu_read_unlock();  	platform_set_drvdata(pdev, data); diff --git a/drivers/dma/imx-dma.c b/drivers/dma/imx-dma.c index dbf0e6f8de8..a7dcf78b1ff 100644 --- a/drivers/dma/imx-dma.c +++ b/drivers/dma/imx-dma.c @@ -684,9 +684,8 @@ static int imxdma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,  			break;  		} -		imxdmac->hw_chaining = 1; -		if (!imxdma_hw_chain(imxdmac)) -			return -EINVAL; +		imxdmac->hw_chaining = 0; +  		imxdmac->ccr_from_device = (mode | IMX_DMA_TYPE_FIFO) |  			((IMX_DMA_MEMSIZE_32 | IMX_DMA_TYPE_LINEAR) << 2) |  			CCR_REN; diff --git a/drivers/dma/ioat/dma_v3.c b/drivers/dma/ioat/dma_v3.c index e5fc944de1f..3e9d66920eb 100644 --- a/drivers/dma/ioat/dma_v3.c +++ b/drivers/dma/ioat/dma_v3.c @@ -951,7 +951,7 @@ static int ioat_xor_val_self_test(struct ioatdma_device *device)  			goto free_resources;  		}  	} -	dma_sync_single_for_device(dev, dest_dma, PAGE_SIZE, DMA_TO_DEVICE); +	dma_sync_single_for_device(dev, dest_dma, PAGE_SIZE, DMA_FROM_DEVICE);  	/* skip validate if the capability is not present */  	if (!dma_has_cap(DMA_XOR_VAL, dma_chan->device->cap_mask)) diff --git a/drivers/dma/tegra20-apb-dma.c b/drivers/dma/tegra20-apb-dma.c index c39e61bc817..3cad856fe67 100644 --- a/drivers/dma/tegra20-apb-dma.c +++ b/drivers/dma/tegra20-apb-dma.c @@ -266,6 +266,7 @@ static struct tegra_dma_desc *tegra_dma_desc_get(  		if (async_tx_test_ack(&dma_desc->txd)) {  			list_del(&dma_desc->node);  			spin_unlock_irqrestore(&tdc->lock, flags); +			dma_desc->txd.flags = 0;  			return dma_desc;  		}  	} @@ -1050,7 +1051,9 @@ struct dma_async_tx_descriptor *tegra_dma_prep_dma_cyclic(  					TEGRA_APBDMA_AHBSEQ_WRAP_SHIFT;  	ahb_seq |= TEGRA_APBDMA_AHBSEQ_BUS_WIDTH_32; -	csr |= TEGRA_APBDMA_CSR_FLOW | TEGRA_APBDMA_CSR_IE_EOC; +	csr |= TEGRA_APBDMA_CSR_FLOW; +	if (flags & DMA_PREP_INTERRUPT) +		csr |= TEGRA_APBDMA_CSR_IE_EOC;  	csr |= tdc->dma_sconfig.slave_id << TEGRA_APBDMA_CSR_REQ_SEL_SHIFT;  	apb_seq |= TEGRA_APBDMA_APBSEQ_WRAP_WORD_1; @@ -1095,7 +1098,8 @@ struct dma_async_tx_descriptor *tegra_dma_prep_dma_cyclic(  		mem += len;  	}  	sg_req->last_sg = true; -	dma_desc->txd.flags = 0; +	if (flags & DMA_CTRL_ACK) +		dma_desc->txd.flags = DMA_CTRL_ACK;  	/*  	 * Make sure that mode should not be conflicting with currently diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c index 281f566a551..d1e9eb191f2 100644 --- a/drivers/edac/edac_mc.c +++ b/drivers/edac/edac_mc.c @@ -340,7 +340,7 @@ struct mem_ctl_info *edac_mc_alloc(unsigned mc_num,  	/*  	 * Alocate and fill the csrow/channels structs  	 */ -	mci->csrows = kcalloc(sizeof(*mci->csrows), tot_csrows, GFP_KERNEL); +	mci->csrows = kcalloc(tot_csrows, sizeof(*mci->csrows), GFP_KERNEL);  	if (!mci->csrows)  		goto error;  	for (row = 0; row < tot_csrows; row++) { @@ -351,7 +351,7 @@ struct mem_ctl_info *edac_mc_alloc(unsigned mc_num,  		csr->csrow_idx = row;  		csr->mci = mci;  		csr->nr_channels = tot_channels; -		csr->channels = kcalloc(sizeof(*csr->channels), tot_channels, +		csr->channels = kcalloc(tot_channels, sizeof(*csr->channels),  					GFP_KERNEL);  		if (!csr->channels)  			goto error; @@ -369,7 +369,7 @@ struct mem_ctl_info *edac_mc_alloc(unsigned mc_num,  	/*  	 * Allocate and fill the dimm structs  	 */ -	mci->dimms  = kcalloc(sizeof(*mci->dimms), tot_dimms, GFP_KERNEL); +	mci->dimms  = kcalloc(tot_dimms, sizeof(*mci->dimms), GFP_KERNEL);  	if (!mci->dimms)  		goto error; diff --git a/drivers/edac/edac_pci_sysfs.c b/drivers/edac/edac_pci_sysfs.c index dc6e905ee1a..0056c4dae9d 100644 --- a/drivers/edac/edac_pci_sysfs.c +++ b/drivers/edac/edac_pci_sysfs.c @@ -256,7 +256,7 @@ static ssize_t edac_pci_dev_store(struct kobject *kobj,  	struct edac_pci_dev_attribute *edac_pci_dev;  	edac_pci_dev = (struct edac_pci_dev_attribute *)attr; -	if (edac_pci_dev->show) +	if (edac_pci_dev->store)  		return edac_pci_dev->store(edac_pci_dev->value, buffer, count);  	return -EIO;  } diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c index fd3ae6290d7..982f1f5f574 100644 --- a/drivers/firmware/dmi_scan.c +++ b/drivers/firmware/dmi_scan.c @@ -471,7 +471,7 @@ void __init dmi_scan_machine(void)  	char __iomem *p, *q;  	int rc; -	if (efi_enabled) { +	if (efi_enabled(EFI_CONFIG_TABLES)) {  		if (efi.smbios == EFI_INVALID_TABLE_ADDR)  			goto error; diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c index 7b1c37497c9..f5596db0cf5 100644 --- a/drivers/firmware/efivars.c +++ b/drivers/firmware/efivars.c @@ -674,7 +674,7 @@ static int efi_status_to_err(efi_status_t status)  		err = -EACCES;  		break;  	case EFI_NOT_FOUND: -		err = -ENOENT; +		err = -EIO;  		break;  	default:  		err = -EINVAL; @@ -793,6 +793,7 @@ static ssize_t efivarfs_file_write(struct file *file,  		spin_unlock(&efivars->lock);  		efivar_unregister(var);  		drop_nlink(inode); +		d_delete(file->f_dentry);  		dput(file->f_dentry);  	} else { @@ -994,7 +995,7 @@ static int efivarfs_unlink(struct inode *dir, struct dentry *dentry)  		list_del(&var->list);  		spin_unlock(&efivars->lock);  		efivar_unregister(var); -		drop_nlink(dir); +		drop_nlink(dentry->d_inode);  		dput(dentry);  		return 0;  	} @@ -1782,7 +1783,7 @@ efivars_init(void)  	printk(KERN_INFO "EFI Variables Facility v%s %s\n", EFIVARS_VERSION,  	       EFIVARS_DATE); -	if (!efi_enabled) +	if (!efi_enabled(EFI_RUNTIME_SERVICES))  		return 0;  	/* For now we'll register the efi directory at /sys/firmware/efi */ @@ -1822,7 +1823,7 @@ err_put:  static void __exit  efivars_exit(void)  { -	if (efi_enabled) { +	if (efi_enabled(EFI_RUNTIME_SERVICES)) {  		unregister_efivars(&__efivars);  		kobject_put(efi_kobj);  	} diff --git a/drivers/firmware/iscsi_ibft_find.c b/drivers/firmware/iscsi_ibft_find.c index 4da4eb9ae92..2224f1dc074 100644 --- a/drivers/firmware/iscsi_ibft_find.c +++ b/drivers/firmware/iscsi_ibft_find.c @@ -99,7 +99,7 @@ unsigned long __init find_ibft_region(unsigned long *sizep)  	/* iBFT 1.03 section 1.4.3.1 mandates that UEFI machines will  	 * only use ACPI for this */ -	if (!efi_enabled) +	if (!efi_enabled(EFI_BOOT))  		find_ibft_in_mem();  	if (ibft_addr) { diff --git a/drivers/gpu/drm/exynos/Kconfig b/drivers/gpu/drm/exynos/Kconfig index 1d1f1e5e33f..046bcda36ab 100644 --- a/drivers/gpu/drm/exynos/Kconfig +++ b/drivers/gpu/drm/exynos/Kconfig @@ -24,7 +24,7 @@ config DRM_EXYNOS_DMABUF  config DRM_EXYNOS_FIMD  	bool "Exynos DRM FIMD" -	depends on DRM_EXYNOS && !FB_S3C +	depends on DRM_EXYNOS && !FB_S3C && !ARCH_MULTIPLATFORM  	help  	  Choose this option if you want to use Exynos FIMD for DRM. @@ -48,7 +48,7 @@ config DRM_EXYNOS_G2D  config DRM_EXYNOS_IPP  	bool "Exynos DRM IPP" -	depends on DRM_EXYNOS +	depends on DRM_EXYNOS && !ARCH_MULTIPLATFORM  	help  	  Choose this option if you want to use IPP feature for DRM. diff --git a/drivers/gpu/drm/exynos/exynos_drm_connector.c b/drivers/gpu/drm/exynos/exynos_drm_connector.c index ab37437bad8..4c5b6859c9e 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_connector.c +++ b/drivers/gpu/drm/exynos/exynos_drm_connector.c @@ -18,7 +18,6 @@  #include "exynos_drm_drv.h"  #include "exynos_drm_encoder.h" -#define MAX_EDID 256  #define to_exynos_connector(x)	container_of(x, struct exynos_drm_connector,\  				drm_connector) @@ -96,7 +95,9 @@ static int exynos_drm_connector_get_modes(struct drm_connector *connector)  					to_exynos_connector(connector);  	struct exynos_drm_manager *manager = exynos_connector->manager;  	struct exynos_drm_display_ops *display_ops = manager->display_ops; -	unsigned int count; +	struct edid *edid = NULL; +	unsigned int count = 0; +	int ret;  	DRM_DEBUG_KMS("%s\n", __FILE__); @@ -114,27 +115,21 @@ static int exynos_drm_connector_get_modes(struct drm_connector *connector)  	 * because lcd panel has only one mode.  	 */  	if (display_ops->get_edid) { -		int ret; -		void *edid; - -		edid = kzalloc(MAX_EDID, GFP_KERNEL); -		if (!edid) { -			DRM_ERROR("failed to allocate edid\n"); -			return 0; +		edid = display_ops->get_edid(manager->dev, connector); +		if (IS_ERR_OR_NULL(edid)) { +			ret = PTR_ERR(edid); +			edid = NULL; +			DRM_ERROR("Panel operation get_edid failed %d\n", ret); +			goto out;  		} -		ret = display_ops->get_edid(manager->dev, connector, -						edid, MAX_EDID); -		if (ret < 0) { -			DRM_ERROR("failed to get edid data.\n"); -			kfree(edid); -			edid = NULL; -			return 0; +		count = drm_add_edid_modes(connector, edid); +		if (count < 0) { +			DRM_ERROR("Add edid modes failed %d\n", count); +			goto out;  		}  		drm_mode_connector_update_edid_property(connector, edid); -		count = drm_add_edid_modes(connector, edid); -		kfree(edid);  	} else {  		struct exynos_drm_panel_info *panel;  		struct drm_display_mode *mode = drm_mode_create(connector->dev); @@ -161,6 +156,8 @@ static int exynos_drm_connector_get_modes(struct drm_connector *connector)  		count = 1;  	} +out: +	kfree(edid);  	return count;  } diff --git a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c index 9df97714b6c..ba0a3aa7854 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c +++ b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c @@ -19,6 +19,7 @@  struct exynos_drm_dmabuf_attachment {  	struct sg_table sgt;  	enum dma_data_direction dir; +	bool is_mapped;  };  static int exynos_gem_attach_dma_buf(struct dma_buf *dmabuf, @@ -72,17 +73,10 @@ static struct sg_table *  	DRM_DEBUG_PRIME("%s\n", __FILE__); -	if (WARN_ON(dir == DMA_NONE)) -		return ERR_PTR(-EINVAL); -  	/* just return current sgt if already requested. */ -	if (exynos_attach->dir == dir) +	if (exynos_attach->dir == dir && exynos_attach->is_mapped)  		return &exynos_attach->sgt; -	/* reattaching is not allowed. */ -	if (WARN_ON(exynos_attach->dir != DMA_NONE)) -		return ERR_PTR(-EBUSY); -  	buf = gem_obj->buffer;  	if (!buf) {  		DRM_ERROR("buffer is null.\n"); @@ -107,13 +101,17 @@ static struct sg_table *  		wr = sg_next(wr);  	} -	nents = dma_map_sg(attach->dev, sgt->sgl, sgt->orig_nents, dir); -	if (!nents) { -		DRM_ERROR("failed to map sgl with iommu.\n"); -		sgt = ERR_PTR(-EIO); -		goto err_unlock; +	if (dir != DMA_NONE) { +		nents = dma_map_sg(attach->dev, sgt->sgl, sgt->orig_nents, dir); +		if (!nents) { +			DRM_ERROR("failed to map sgl with iommu.\n"); +			sg_free_table(sgt); +			sgt = ERR_PTR(-EIO); +			goto err_unlock; +		}  	} +	exynos_attach->is_mapped = true;  	exynos_attach->dir = dir;  	attach->priv = exynos_attach; diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h index b9e51bc09e8..4606fac7241 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.h +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h @@ -148,8 +148,8 @@ struct exynos_drm_overlay {  struct exynos_drm_display_ops {  	enum exynos_drm_output_type type;  	bool (*is_connected)(struct device *dev); -	int (*get_edid)(struct device *dev, struct drm_connector *connector, -				u8 *edid, int len); +	struct edid *(*get_edid)(struct device *dev, +			struct drm_connector *connector);  	void *(*get_panel)(struct device *dev);  	int (*check_timing)(struct device *dev, void *timing);  	int (*power_on)(struct device *dev, int mode); diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c b/drivers/gpu/drm/exynos/exynos_drm_g2d.c index 36c3905536a..9a4c08e7453 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c +++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c @@ -324,7 +324,7 @@ out:  	g2d_userptr = NULL;  } -dma_addr_t *g2d_userptr_get_dma_addr(struct drm_device *drm_dev, +static dma_addr_t *g2d_userptr_get_dma_addr(struct drm_device *drm_dev,  					unsigned long userptr,  					unsigned long size,  					struct drm_file *filp, diff --git a/drivers/gpu/drm/exynos/exynos_drm_hdmi.c b/drivers/gpu/drm/exynos/exynos_drm_hdmi.c index 850e9950b7d..28644539b30 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_hdmi.c @@ -108,18 +108,17 @@ static bool drm_hdmi_is_connected(struct device *dev)  	return false;  } -static int drm_hdmi_get_edid(struct device *dev, -		struct drm_connector *connector, u8 *edid, int len) +static struct edid *drm_hdmi_get_edid(struct device *dev, +			struct drm_connector *connector)  {  	struct drm_hdmi_context *ctx = to_context(dev);  	DRM_DEBUG_KMS("%s\n", __FILE__);  	if (hdmi_ops && hdmi_ops->get_edid) -		return hdmi_ops->get_edid(ctx->hdmi_ctx->ctx, connector, edid, -					  len); +		return hdmi_ops->get_edid(ctx->hdmi_ctx->ctx, connector); -	return 0; +	return NULL;  }  static int drm_hdmi_check_timing(struct device *dev, void *timing) diff --git a/drivers/gpu/drm/exynos/exynos_drm_hdmi.h b/drivers/gpu/drm/exynos/exynos_drm_hdmi.h index 784a7e9a766..d80516fc9ed 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_hdmi.h +++ b/drivers/gpu/drm/exynos/exynos_drm_hdmi.h @@ -30,8 +30,8 @@ struct exynos_drm_hdmi_context {  struct exynos_hdmi_ops {  	/* display */  	bool (*is_connected)(void *ctx); -	int (*get_edid)(void *ctx, struct drm_connector *connector, -			u8 *edid, int len); +	struct edid *(*get_edid)(void *ctx, +			struct drm_connector *connector);  	int (*check_timing)(void *ctx, void *timing);  	int (*power_on)(void *ctx, int mode); diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.c b/drivers/gpu/drm/exynos/exynos_drm_ipp.c index 0bda96454a0..1a556354e92 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_ipp.c +++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.c @@ -869,7 +869,7 @@ static void ipp_put_event(struct drm_exynos_ipp_cmd_node *c_node,  	}  } -void ipp_handle_cmd_work(struct device *dev, +static void ipp_handle_cmd_work(struct device *dev,  		struct exynos_drm_ippdrv *ippdrv,  		struct drm_exynos_ipp_cmd_work *cmd_work,  		struct drm_exynos_ipp_cmd_node *c_node) diff --git a/drivers/gpu/drm/exynos/exynos_drm_rotator.c b/drivers/gpu/drm/exynos/exynos_drm_rotator.c index e9e83ef688f..f976e29def6 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_rotator.c +++ b/drivers/gpu/drm/exynos/exynos_drm_rotator.c @@ -734,7 +734,7 @@ static int rotator_remove(struct platform_device *pdev)  	return 0;  } -struct rot_limit_table rot_limit_tbl = { +static struct rot_limit_table rot_limit_tbl = {  	.ycbcr420_2p = {  		.min_w = 32,  		.min_h = 32, @@ -751,7 +751,7 @@ struct rot_limit_table rot_limit_tbl = {  	},  }; -struct platform_device_id rotator_driver_ids[] = { +static struct platform_device_id rotator_driver_ids[] = {  	{  		.name		= "exynos-rot",  		.driver_data	= (unsigned long)&rot_limit_tbl, diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c index d0ca3c4e06c..13ccbd4bcfa 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c @@ -98,10 +98,12 @@ static bool vidi_display_is_connected(struct device *dev)  	return ctx->connected ? true : false;  } -static int vidi_get_edid(struct device *dev, struct drm_connector *connector, -				u8 *edid, int len) +static struct edid *vidi_get_edid(struct device *dev, +			struct drm_connector *connector)  {  	struct vidi_context *ctx = get_vidi_context(dev); +	struct edid *edid; +	int edid_len;  	DRM_DEBUG_KMS("%s\n", __FILE__); @@ -111,13 +113,18 @@ static int vidi_get_edid(struct device *dev, struct drm_connector *connector,  	 */  	if (!ctx->raw_edid) {  		DRM_DEBUG_KMS("raw_edid is null.\n"); -		return -EFAULT; +		return ERR_PTR(-EFAULT);  	} -	memcpy(edid, ctx->raw_edid, min((1 + ctx->raw_edid->extensions) -					* EDID_LENGTH, len)); +	edid_len = (1 + ctx->raw_edid->extensions) * EDID_LENGTH; +	edid = kzalloc(edid_len, GFP_KERNEL); +	if (!edid) { +		DRM_DEBUG_KMS("failed to allocate edid\n"); +		return ERR_PTR(-ENOMEM); +	} -	return 0; +	memcpy(edid, ctx->raw_edid, edid_len); +	return edid;  }  static void *vidi_get_panel(struct device *dev) @@ -514,7 +521,6 @@ int vidi_connection_ioctl(struct drm_device *drm_dev, void *data,  	struct exynos_drm_manager *manager;  	struct exynos_drm_display_ops *display_ops;  	struct drm_exynos_vidi_connection *vidi = data; -	struct edid *raw_edid;  	int edid_len;  	DRM_DEBUG_KMS("%s\n", __FILE__); @@ -551,11 +557,11 @@ int vidi_connection_ioctl(struct drm_device *drm_dev, void *data,  	}  	if (vidi->connection) { -		if (!vidi->edid) { -			DRM_DEBUG_KMS("edid data is null.\n"); +		struct edid *raw_edid  = (struct edid *)(uint32_t)vidi->edid; +		if (!drm_edid_is_valid(raw_edid)) { +			DRM_DEBUG_KMS("edid data is invalid.\n");  			return -EINVAL;  		} -		raw_edid = (struct edid *)(uint32_t)vidi->edid;  		edid_len = (1 + raw_edid->extensions) * EDID_LENGTH;  		ctx->raw_edid = kzalloc(edid_len, GFP_KERNEL);  		if (!ctx->raw_edid) { diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c index 41ff79d8ac8..fbab3c46860 100644 --- a/drivers/gpu/drm/exynos/exynos_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c @@ -34,7 +34,6 @@  #include <linux/regulator/consumer.h>  #include <linux/io.h>  #include <linux/of_gpio.h> -#include <plat/gpio-cfg.h>  #include <drm/exynos_drm.h> @@ -98,8 +97,7 @@ struct hdmi_context {  	void __iomem			*regs;  	void				*parent_ctx; -	int				external_irq; -	int				internal_irq; +	int				irq;  	struct i2c_client		*ddc_port;  	struct i2c_client		*hdmiphy_port; @@ -1391,8 +1389,7 @@ static bool hdmi_is_connected(void *ctx)  	return hdata->hpd;  } -static int hdmi_get_edid(void *ctx, struct drm_connector *connector, -				u8 *edid, int len) +static struct edid *hdmi_get_edid(void *ctx, struct drm_connector *connector)  {  	struct edid *raw_edid;  	struct hdmi_context *hdata = ctx; @@ -1400,22 +1397,18 @@ static int hdmi_get_edid(void *ctx, struct drm_connector *connector,  	DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);  	if (!hdata->ddc_port) -		return -ENODEV; +		return ERR_PTR(-ENODEV);  	raw_edid = drm_get_edid(connector, hdata->ddc_port->adapter); -	if (raw_edid) { -		hdata->dvi_mode = !drm_detect_hdmi_monitor(raw_edid); -		memcpy(edid, raw_edid, min((1 + raw_edid->extensions) -					* EDID_LENGTH, len)); -		DRM_DEBUG_KMS("%s : width[%d] x height[%d]\n", -			(hdata->dvi_mode ? "dvi monitor" : "hdmi monitor"), -			raw_edid->width_cm, raw_edid->height_cm); -		kfree(raw_edid); -	} else { -		return -ENODEV; -	} +	if (!raw_edid) +		return ERR_PTR(-ENODEV); -	return 0; +	hdata->dvi_mode = !drm_detect_hdmi_monitor(raw_edid); +	DRM_DEBUG_KMS("%s : width[%d] x height[%d]\n", +		(hdata->dvi_mode ? "dvi monitor" : "hdmi monitor"), +		raw_edid->width_cm, raw_edid->height_cm); + +	return raw_edid;  }  static int hdmi_v13_check_timing(struct fb_videomode *check_timing) @@ -1652,16 +1645,16 @@ static void hdmi_conf_reset(struct hdmi_context *hdata)  	/* resetting HDMI core */  	hdmi_reg_writemask(hdata, reg,  0, HDMI_CORE_SW_RSTOUT); -	mdelay(10); +	usleep_range(10000, 12000);  	hdmi_reg_writemask(hdata, reg, ~0, HDMI_CORE_SW_RSTOUT); -	mdelay(10); +	usleep_range(10000, 12000);  }  static void hdmi_conf_init(struct hdmi_context *hdata)  {  	struct hdmi_infoframe infoframe; -	/* disable HPD interrupts */ +	/* disable HPD interrupts from HDMI IP block, use GPIO instead */  	hdmi_reg_writemask(hdata, HDMI_INTC_CON, 0, HDMI_INTC_EN_GLOBAL |  		HDMI_INTC_EN_HPD_PLUG | HDMI_INTC_EN_HPD_UNPLUG); @@ -1779,7 +1772,7 @@ static void hdmi_v13_timing_apply(struct hdmi_context *hdata)  		u32 val = hdmi_reg_read(hdata, HDMI_V13_PHY_STATUS);  		if (val & HDMI_PHY_STATUS_READY)  			break; -		mdelay(1); +		usleep_range(1000, 2000);  	}  	/* steady state not achieved */  	if (tries == 0) { @@ -1946,7 +1939,7 @@ static void hdmi_v14_timing_apply(struct hdmi_context *hdata)  		u32 val = hdmi_reg_read(hdata, HDMI_PHY_STATUS_0);  		if (val & HDMI_PHY_STATUS_READY)  			break; -		mdelay(1); +		usleep_range(1000, 2000);  	}  	/* steady state not achieved */  	if (tries == 0) { @@ -1998,9 +1991,9 @@ static void hdmiphy_conf_reset(struct hdmi_context *hdata)  	/* reset hdmiphy */  	hdmi_reg_writemask(hdata, reg, ~0, HDMI_PHY_SW_RSTOUT); -	mdelay(10); +	usleep_range(10000, 12000);  	hdmi_reg_writemask(hdata, reg,  0, HDMI_PHY_SW_RSTOUT); -	mdelay(10); +	usleep_range(10000, 12000);  }  static void hdmiphy_poweron(struct hdmi_context *hdata) @@ -2048,7 +2041,7 @@ static void hdmiphy_conf_apply(struct hdmi_context *hdata)  		return;  	} -	mdelay(10); +	usleep_range(10000, 12000);  	/* operation mode */  	operation[0] = 0x1f; @@ -2170,6 +2163,13 @@ static void hdmi_commit(void *ctx)  	DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); +	mutex_lock(&hdata->hdmi_mutex); +	if (!hdata->powered) { +		mutex_unlock(&hdata->hdmi_mutex); +		return; +	} +	mutex_unlock(&hdata->hdmi_mutex); +  	hdmi_conf_apply(hdata);  } @@ -2265,7 +2265,7 @@ static struct exynos_hdmi_ops hdmi_ops = {  	.dpms		= hdmi_dpms,  }; -static irqreturn_t hdmi_external_irq_thread(int irq, void *arg) +static irqreturn_t hdmi_irq_thread(int irq, void *arg)  {  	struct exynos_drm_hdmi_context *ctx = arg;  	struct hdmi_context *hdata = ctx->ctx; @@ -2280,31 +2280,6 @@ static irqreturn_t hdmi_external_irq_thread(int irq, void *arg)  	return IRQ_HANDLED;  } -static irqreturn_t hdmi_internal_irq_thread(int irq, void *arg) -{ -	struct exynos_drm_hdmi_context *ctx = arg; -	struct hdmi_context *hdata = ctx->ctx; -	u32 intc_flag; - -	intc_flag = hdmi_reg_read(hdata, HDMI_INTC_FLAG); -	/* clearing flags for HPD plug/unplug */ -	if (intc_flag & HDMI_INTC_FLAG_HPD_UNPLUG) { -		DRM_DEBUG_KMS("unplugged\n"); -		hdmi_reg_writemask(hdata, HDMI_INTC_FLAG, ~0, -			HDMI_INTC_FLAG_HPD_UNPLUG); -	} -	if (intc_flag & HDMI_INTC_FLAG_HPD_PLUG) { -		DRM_DEBUG_KMS("plugged\n"); -		hdmi_reg_writemask(hdata, HDMI_INTC_FLAG, ~0, -			HDMI_INTC_FLAG_HPD_PLUG); -	} - -	if (ctx->drm_dev) -		drm_helper_hpd_irq_event(ctx->drm_dev); - -	return IRQ_HANDLED; -} -  static int hdmi_resources_init(struct hdmi_context *hdata)  {  	struct device *dev = hdata->dev; @@ -2555,39 +2530,24 @@ static int hdmi_probe(struct platform_device *pdev)  	hdata->hdmiphy_port = hdmi_hdmiphy; -	hdata->external_irq = gpio_to_irq(hdata->hpd_gpio); -	if (hdata->external_irq < 0) { -		DRM_ERROR("failed to get GPIO external irq\n"); -		ret = hdata->external_irq; -		goto err_hdmiphy; -	} - -	hdata->internal_irq = platform_get_irq(pdev, 0); -	if (hdata->internal_irq < 0) { -		DRM_ERROR("failed to get platform internal irq\n"); -		ret = hdata->internal_irq; +	hdata->irq = gpio_to_irq(hdata->hpd_gpio); +	if (hdata->irq < 0) { +		DRM_ERROR("failed to get GPIO irq\n"); +		ret = hdata->irq;  		goto err_hdmiphy;  	}  	hdata->hpd = gpio_get_value(hdata->hpd_gpio); -	ret = request_threaded_irq(hdata->external_irq, NULL, -			hdmi_external_irq_thread, IRQF_TRIGGER_RISING | +	ret = request_threaded_irq(hdata->irq, NULL, +			hdmi_irq_thread, IRQF_TRIGGER_RISING |  			IRQF_TRIGGER_FALLING | IRQF_ONESHOT, -			"hdmi_external", drm_hdmi_ctx); +			"hdmi", drm_hdmi_ctx);  	if (ret) { -		DRM_ERROR("failed to register hdmi external interrupt\n"); +		DRM_ERROR("failed to register hdmi interrupt\n");  		goto err_hdmiphy;  	} -	ret = request_threaded_irq(hdata->internal_irq, NULL, -			hdmi_internal_irq_thread, IRQF_ONESHOT, -			"hdmi_internal", drm_hdmi_ctx); -	if (ret) { -		DRM_ERROR("failed to register hdmi internal interrupt\n"); -		goto err_free_irq; -	} -  	/* Attach HDMI Driver to common hdmi. */  	exynos_hdmi_drv_attach(drm_hdmi_ctx); @@ -2598,8 +2558,6 @@ static int hdmi_probe(struct platform_device *pdev)  	return 0; -err_free_irq: -	free_irq(hdata->external_irq, drm_hdmi_ctx);  err_hdmiphy:  	i2c_del_driver(&hdmiphy_driver);  err_ddc: @@ -2617,8 +2575,7 @@ static int hdmi_remove(struct platform_device *pdev)  	pm_runtime_disable(dev); -	free_irq(hdata->internal_irq, hdata); -	free_irq(hdata->external_irq, hdata); +	free_irq(hdata->irq, hdata);  	/* hdmiphy i2c driver */ @@ -2637,8 +2594,7 @@ static int hdmi_suspend(struct device *dev)  	DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); -	disable_irq(hdata->internal_irq); -	disable_irq(hdata->external_irq); +	disable_irq(hdata->irq);  	hdata->hpd = false;  	if (ctx->drm_dev) @@ -2663,8 +2619,7 @@ static int hdmi_resume(struct device *dev)  	hdata->hpd = gpio_get_value(hdata->hpd_gpio); -	enable_irq(hdata->external_irq); -	enable_irq(hdata->internal_irq); +	enable_irq(hdata->irq);  	if (!pm_runtime_suspended(dev)) {  		DRM_DEBUG_KMS("%s : Already resumed\n", __func__); diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c index c187ea33b74..c414584bfba 100644 --- a/drivers/gpu/drm/exynos/exynos_mixer.c +++ b/drivers/gpu/drm/exynos/exynos_mixer.c @@ -600,7 +600,7 @@ static void vp_win_reset(struct mixer_context *ctx)  		/* waiting until VP_SRESET_PROCESSING is 0 */  		if (~vp_reg_read(res, VP_SRESET) & VP_SRESET_PROCESSING)  			break; -		mdelay(10); +		usleep_range(10000, 12000);  	}  	WARN(tries == 0, "failed to reset Video Processor\n");  } @@ -776,6 +776,13 @@ static void mixer_win_commit(void *ctx, int win)  	DRM_DEBUG_KMS("[%d] %s, win: %d\n", __LINE__, __func__, win); +	mutex_lock(&mixer_ctx->mixer_mutex); +	if (!mixer_ctx->powered) { +		mutex_unlock(&mixer_ctx->mixer_mutex); +		return; +	} +	mutex_unlock(&mixer_ctx->mixer_mutex); +  	if (win > 1 && mixer_ctx->vp_enabled)  		vp_video_buffer(mixer_ctx, win);  	else diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 7944d301518..9d4a2c2adf0 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -30,6 +30,7 @@  #include <linux/debugfs.h>  #include <linux/slab.h>  #include <linux/export.h> +#include <generated/utsrelease.h>  #include <drm/drmP.h>  #include "intel_drv.h"  #include "intel_ringbuffer.h" @@ -690,6 +691,7 @@ static int i915_error_state(struct seq_file *m, void *unused)  	seq_printf(m, "Time: %ld s %ld us\n", error->time.tv_sec,  		   error->time.tv_usec); +	seq_printf(m, "Kernel: " UTS_RELEASE);  	seq_printf(m, "PCI ID: 0x%04x\n", dev->pci_device);  	seq_printf(m, "EIR: 0x%08x\n", error->eir);  	seq_printf(m, "IER: 0x%08x\n", error->ier); diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index b401788e179..59afb7eb6db 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -533,6 +533,7 @@  #define MI_MODE		0x0209c  # define VS_TIMER_DISPATCH				(1 << 6)  # define MI_FLUSH_ENABLE				(1 << 12) +# define ASYNC_FLIP_PERF_DISABLE			(1 << 14)  #define GEN6_GT_MODE	0x20d0  #define   GEN6_GT_MODE_HI				(1 << 9) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index ae253e04c39..42ff97d667d 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -505,13 +505,25 @@ static int init_render_ring(struct intel_ring_buffer *ring)  	struct drm_i915_private *dev_priv = dev->dev_private;  	int ret = init_ring_common(ring); -	if (INTEL_INFO(dev)->gen > 3) { +	if (INTEL_INFO(dev)->gen > 3)  		I915_WRITE(MI_MODE, _MASKED_BIT_ENABLE(VS_TIMER_DISPATCH)); -		if (IS_GEN7(dev)) -			I915_WRITE(GFX_MODE_GEN7, -				   _MASKED_BIT_DISABLE(GFX_TLB_INVALIDATE_ALWAYS) | -				   _MASKED_BIT_ENABLE(GFX_REPLAY_MODE)); -	} + +	/* We need to disable the AsyncFlip performance optimisations in order +	 * to use MI_WAIT_FOR_EVENT within the CS. It should already be +	 * programmed to '1' on all products. +	 */ +	if (INTEL_INFO(dev)->gen >= 6) +		I915_WRITE(MI_MODE, _MASKED_BIT_ENABLE(ASYNC_FLIP_PERF_DISABLE)); + +	/* Required for the hardware to program scanline values for waiting */ +	if (INTEL_INFO(dev)->gen == 6) +		I915_WRITE(GFX_MODE, +			   _MASKED_BIT_ENABLE(GFX_TLB_INVALIDATE_ALWAYS)); + +	if (IS_GEN7(dev)) +		I915_WRITE(GFX_MODE_GEN7, +			   _MASKED_BIT_DISABLE(GFX_TLB_INVALIDATE_ALWAYS) | +			   _MASKED_BIT_ENABLE(GFX_REPLAY_MODE));  	if (INTEL_INFO(dev)->gen >= 5) {  		ret = init_pipe_control(ring); diff --git a/drivers/gpu/drm/nouveau/core/core/falcon.c b/drivers/gpu/drm/nouveau/core/core/falcon.c index 6b0843c3387..e05c1577758 100644 --- a/drivers/gpu/drm/nouveau/core/core/falcon.c +++ b/drivers/gpu/drm/nouveau/core/core/falcon.c @@ -73,8 +73,11 @@ _nouveau_falcon_init(struct nouveau_object *object)  	nv_debug(falcon, "data limit: %d\n", falcon->data.limit);  	/* wait for 'uc halted' to be signalled before continuing */ -	if (falcon->secret) { -		nv_wait(falcon, 0x008, 0x00000010, 0x00000010); +	if (falcon->secret && falcon->version < 4) { +		if (!falcon->version) +			nv_wait(falcon, 0x008, 0x00000010, 0x00000010); +		else +			nv_wait(falcon, 0x180, 0x80000000, 0);  		nv_wo32(falcon, 0x004, 0x00000010);  	} diff --git a/drivers/gpu/drm/nouveau/core/core/subdev.c b/drivers/gpu/drm/nouveau/core/core/subdev.c index f74c30aa33a..48f06378d3f 100644 --- a/drivers/gpu/drm/nouveau/core/core/subdev.c +++ b/drivers/gpu/drm/nouveau/core/core/subdev.c @@ -99,7 +99,7 @@ nouveau_subdev_create_(struct nouveau_object *parent,  	if (ret)  		return ret; -	mutex_init(&subdev->mutex); +	__mutex_init(&subdev->mutex, subname, &oclass->lock_class_key);  	subdev->name = subname;  	if (parent) { diff --git a/drivers/gpu/drm/nouveau/core/include/core/object.h b/drivers/gpu/drm/nouveau/core/include/core/object.h index 5982935ee23..106bb19fdd9 100644 --- a/drivers/gpu/drm/nouveau/core/include/core/object.h +++ b/drivers/gpu/drm/nouveau/core/include/core/object.h @@ -50,10 +50,13 @@ int  nouveau_object_fini(struct nouveau_object *, bool suspend);  extern struct nouveau_ofuncs nouveau_object_ofuncs; +/* Don't allocate dynamically, because lockdep needs lock_class_keys to be in + * ".data". */  struct nouveau_oclass {  	u32 handle; -	struct nouveau_ofuncs *ofuncs; -	struct nouveau_omthds *omthds; +	struct nouveau_ofuncs * const ofuncs; +	struct nouveau_omthds * const omthds; +	struct lock_class_key lock_class_key;  };  #define nv_oclass(o)    nv_object(o)->oclass diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/base.c b/drivers/gpu/drm/nouveau/core/subdev/fb/base.c index d6d16007ec1..d62045f454b 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/base.c +++ b/drivers/gpu/drm/nouveau/core/subdev/fb/base.c @@ -86,8 +86,8 @@ nouveau_fb_preinit(struct nouveau_fb *pfb)  			return ret;  	} -	if (!nouveau_mm_initialised(&pfb->tags) && tags) { -		ret = nouveau_mm_init(&pfb->tags, 0, ++tags, 1); +	if (!nouveau_mm_initialised(&pfb->tags)) { +		ret = nouveau_mm_init(&pfb->tags, 0, tags ? ++tags : 0, 1);  		if (ret)  			return ret;  	} diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv50.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nv50.c index 487cb8c6c20..eac236ed19b 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv50.c +++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nv50.c @@ -99,7 +99,7 @@ nv50_fb_vram_init(struct nouveau_fb *pfb)  	struct nouveau_bios *bios = nouveau_bios(device);  	const u32 rsvd_head = ( 256 * 1024) >> 12; /* vga memory */  	const u32 rsvd_tail = (1024 * 1024) >> 12; /* vbios etc */ -	u32 size; +	u32 size, tags = 0;  	int ret;  	pfb->ram.size = nv_rd32(pfb, 0x10020c); @@ -140,10 +140,11 @@ nv50_fb_vram_init(struct nouveau_fb *pfb)  			return ret;  		pfb->ram.ranks = (nv_rd32(pfb, 0x100200) & 0x4) ? 2 : 1; +		tags = nv_rd32(pfb, 0x100320);  		break;  	} -	return nv_rd32(pfb, 0x100320); +	return tags;  }  static int diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 69d7b1d0b9d..1699a9083a2 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -28,6 +28,7 @@   */  #include <core/engine.h> +#include <linux/swiotlb.h>  #include <subdev/fb.h>  #include <subdev/vm.h> diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index 8b090f1eb51..5e7aef23825 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -245,6 +245,8 @@ static int nouveau_drm_probe(struct pci_dev *pdev,  	return 0;  } +static struct lock_class_key drm_client_lock_class_key; +  static int  nouveau_drm_load(struct drm_device *dev, unsigned long flags)  { @@ -256,6 +258,7 @@ nouveau_drm_load(struct drm_device *dev, unsigned long flags)  	ret = nouveau_cli_create(pdev, "DRM", sizeof(*drm), (void**)&drm);  	if (ret)  		return ret; +	lockdep_set_class(&drm->client.mutex, &drm_client_lock_class_key);  	dev->dev_private = drm;  	drm->dev = dev; diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 4d0e60adbc6..a2d478e8692 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -1313,14 +1313,18 @@ void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *sav  				if (!(tmp & EVERGREEN_CRTC_BLANK_DATA_EN)) {  					radeon_wait_for_vblank(rdev, i);  					tmp |= EVERGREEN_CRTC_BLANK_DATA_EN; +					WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 1);  					WREG32(EVERGREEN_CRTC_BLANK_CONTROL + crtc_offsets[i], tmp); +					WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 0);  				}  			} else {  				tmp = RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i]);  				if (!(tmp & EVERGREEN_CRTC_DISP_READ_REQUEST_DISABLE)) {  					radeon_wait_for_vblank(rdev, i);  					tmp |= EVERGREEN_CRTC_DISP_READ_REQUEST_DISABLE; +					WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 1);  					WREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i], tmp); +					WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 0);  				}  			}  			/* wait for the next frame */ @@ -1345,6 +1349,8 @@ void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *sav  		blackout &= ~BLACKOUT_MODE_MASK;  		WREG32(MC_SHARED_BLACKOUT_CNTL, blackout | 1);  	} +	/* wait for the MC to settle */ +	udelay(100);  }  void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *save) @@ -1378,11 +1384,15 @@ void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *s  			if (ASIC_IS_DCE6(rdev)) {  				tmp = RREG32(EVERGREEN_CRTC_BLANK_CONTROL + crtc_offsets[i]);  				tmp |= EVERGREEN_CRTC_BLANK_DATA_EN; +				WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 1);  				WREG32(EVERGREEN_CRTC_BLANK_CONTROL + crtc_offsets[i], tmp); +				WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 0);  			} else {  				tmp = RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i]);  				tmp &= ~EVERGREEN_CRTC_DISP_READ_REQUEST_DISABLE; +				WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 1);  				WREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i], tmp); +				WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 0);  			}  			/* wait for the next frame */  			frame_count = radeon_get_vblank_counter(rdev, i); @@ -2036,9 +2046,20 @@ static void evergreen_gpu_init(struct radeon_device *rdev)  	WREG32(HDP_ADDR_CONFIG, gb_addr_config);  	WREG32(DMA_TILING_CONFIG, gb_addr_config); -	tmp = gb_addr_config & NUM_PIPES_MASK; -	tmp = r6xx_remap_render_backend(rdev, tmp, rdev->config.evergreen.max_backends, -					EVERGREEN_MAX_BACKENDS, disabled_rb_mask); +	if ((rdev->config.evergreen.max_backends == 1) && +	    (rdev->flags & RADEON_IS_IGP)) { +		if ((disabled_rb_mask & 3) == 1) { +			/* RB0 disabled, RB1 enabled */ +			tmp = 0x11111111; +		} else { +			/* RB1 disabled, RB0 enabled */ +			tmp = 0x00000000; +		} +	} else { +		tmp = gb_addr_config & NUM_PIPES_MASK; +		tmp = r6xx_remap_render_backend(rdev, tmp, rdev->config.evergreen.max_backends, +						EVERGREEN_MAX_BACKENDS, disabled_rb_mask); +	}  	WREG32(GB_BACKEND_MAP, tmp);  	WREG32(CGTS_SYS_TCC_DISABLE, 0); diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c b/drivers/gpu/drm/radeon/evergreen_cs.c index 7a445666e71..ee4cff534f1 100644 --- a/drivers/gpu/drm/radeon/evergreen_cs.c +++ b/drivers/gpu/drm/radeon/evergreen_cs.c @@ -2909,14 +2909,14 @@ int evergreen_dma_cs_parse(struct radeon_cs_parser *p)  				return -EINVAL;  			}  			if (tiled) { -				dst_offset = ib[idx+1]; +				dst_offset = radeon_get_ib_value(p, idx+1);  				dst_offset <<= 8;  				ib[idx+1] += (u32)(dst_reloc->lobj.gpu_offset >> 8);  				p->idx += count + 7;  			} else { -				dst_offset = ib[idx+1]; -				dst_offset |= ((u64)(ib[idx+2] & 0xff)) << 32; +				dst_offset = radeon_get_ib_value(p, idx+1); +				dst_offset |= ((u64)(radeon_get_ib_value(p, idx+2) & 0xff)) << 32;  				ib[idx+1] += (u32)(dst_reloc->lobj.gpu_offset & 0xfffffffc);  				ib[idx+2] += upper_32_bits(dst_reloc->lobj.gpu_offset) & 0xff; @@ -2954,12 +2954,12 @@ int evergreen_dma_cs_parse(struct radeon_cs_parser *p)  							DRM_ERROR("bad L2T, frame to fields DMA_PACKET_COPY\n");  							return -EINVAL;  						} -						dst_offset = ib[idx+1]; +						dst_offset = radeon_get_ib_value(p, idx+1);  						dst_offset <<= 8; -						dst2_offset = ib[idx+2]; +						dst2_offset = radeon_get_ib_value(p, idx+2);  						dst2_offset <<= 8; -						src_offset = ib[idx+8]; -						src_offset |= ((u64)(ib[idx+9] & 0xff)) << 32; +						src_offset = radeon_get_ib_value(p, idx+8); +						src_offset |= ((u64)(radeon_get_ib_value(p, idx+9) & 0xff)) << 32;  						if ((src_offset + (count * 4)) > radeon_bo_size(src_reloc->robj)) {  							dev_warn(p->dev, "DMA L2T, frame to fields src buffer too small (%llu %lu)\n",  								 src_offset + (count * 4), radeon_bo_size(src_reloc->robj)); @@ -3014,12 +3014,12 @@ int evergreen_dma_cs_parse(struct radeon_cs_parser *p)  							DRM_ERROR("bad L2T, broadcast DMA_PACKET_COPY\n");  							return -EINVAL;  						} -						dst_offset = ib[idx+1]; +						dst_offset = radeon_get_ib_value(p, idx+1);  						dst_offset <<= 8; -						dst2_offset = ib[idx+2]; +						dst2_offset = radeon_get_ib_value(p, idx+2);  						dst2_offset <<= 8; -						src_offset = ib[idx+8]; -						src_offset |= ((u64)(ib[idx+9] & 0xff)) << 32; +						src_offset = radeon_get_ib_value(p, idx+8); +						src_offset |= ((u64)(radeon_get_ib_value(p, idx+9) & 0xff)) << 32;  						if ((src_offset + (count * 4)) > radeon_bo_size(src_reloc->robj)) {  							dev_warn(p->dev, "DMA L2T, broadcast src buffer too small (%llu %lu)\n",  								 src_offset + (count * 4), radeon_bo_size(src_reloc->robj)); @@ -3046,22 +3046,22 @@ int evergreen_dma_cs_parse(struct radeon_cs_parser *p)  						/* detile bit */  						if (idx_value & (1 << 31)) {  							/* tiled src, linear dst */ -							src_offset = ib[idx+1]; +							src_offset = radeon_get_ib_value(p, idx+1);  							src_offset <<= 8;  							ib[idx+1] += (u32)(src_reloc->lobj.gpu_offset >> 8); -							dst_offset = ib[idx+7]; -							dst_offset |= ((u64)(ib[idx+8] & 0xff)) << 32; +							dst_offset = radeon_get_ib_value(p, idx+7); +							dst_offset |= ((u64)(radeon_get_ib_value(p, idx+8) & 0xff)) << 32;  							ib[idx+7] += (u32)(dst_reloc->lobj.gpu_offset & 0xfffffffc);  							ib[idx+8] += upper_32_bits(dst_reloc->lobj.gpu_offset) & 0xff;  						} else {  							/* linear src, tiled dst */ -							src_offset = ib[idx+7]; -							src_offset |= ((u64)(ib[idx+8] & 0xff)) << 32; +							src_offset = radeon_get_ib_value(p, idx+7); +							src_offset |= ((u64)(radeon_get_ib_value(p, idx+8) & 0xff)) << 32;  							ib[idx+7] += (u32)(src_reloc->lobj.gpu_offset & 0xfffffffc);  							ib[idx+8] += upper_32_bits(src_reloc->lobj.gpu_offset) & 0xff; -							dst_offset = ib[idx+1]; +							dst_offset = radeon_get_ib_value(p, idx+1);  							dst_offset <<= 8;  							ib[idx+1] += (u32)(dst_reloc->lobj.gpu_offset >> 8);  						} @@ -3098,12 +3098,12 @@ int evergreen_dma_cs_parse(struct radeon_cs_parser *p)  							DRM_ERROR("bad L2T, broadcast DMA_PACKET_COPY\n");  							return -EINVAL;  						} -						dst_offset = ib[idx+1]; +						dst_offset = radeon_get_ib_value(p, idx+1);  						dst_offset <<= 8; -						dst2_offset = ib[idx+2]; +						dst2_offset = radeon_get_ib_value(p, idx+2);  						dst2_offset <<= 8; -						src_offset = ib[idx+8]; -						src_offset |= ((u64)(ib[idx+9] & 0xff)) << 32; +						src_offset = radeon_get_ib_value(p, idx+8); +						src_offset |= ((u64)(radeon_get_ib_value(p, idx+9) & 0xff)) << 32;  						if ((src_offset + (count * 4)) > radeon_bo_size(src_reloc->robj)) {  							dev_warn(p->dev, "DMA L2T, broadcast src buffer too small (%llu %lu)\n",  								 src_offset + (count * 4), radeon_bo_size(src_reloc->robj)); @@ -3135,22 +3135,22 @@ int evergreen_dma_cs_parse(struct radeon_cs_parser *p)  						/* detile bit */  						if (idx_value & (1 << 31)) {  							/* tiled src, linear dst */ -							src_offset = ib[idx+1]; +							src_offset = radeon_get_ib_value(p, idx+1);  							src_offset <<= 8;  							ib[idx+1] += (u32)(src_reloc->lobj.gpu_offset >> 8); -							dst_offset = ib[idx+7]; -							dst_offset |= ((u64)(ib[idx+8] & 0xff)) << 32; +							dst_offset = radeon_get_ib_value(p, idx+7); +							dst_offset |= ((u64)(radeon_get_ib_value(p, idx+8) & 0xff)) << 32;  							ib[idx+7] += (u32)(dst_reloc->lobj.gpu_offset & 0xfffffffc);  							ib[idx+8] += upper_32_bits(dst_reloc->lobj.gpu_offset) & 0xff;  						} else {  							/* linear src, tiled dst */ -							src_offset = ib[idx+7]; -							src_offset |= ((u64)(ib[idx+8] & 0xff)) << 32; +							src_offset = radeon_get_ib_value(p, idx+7); +							src_offset |= ((u64)(radeon_get_ib_value(p, idx+8) & 0xff)) << 32;  							ib[idx+7] += (u32)(src_reloc->lobj.gpu_offset & 0xfffffffc);  							ib[idx+8] += upper_32_bits(src_reloc->lobj.gpu_offset) & 0xff; -							dst_offset = ib[idx+1]; +							dst_offset = radeon_get_ib_value(p, idx+1);  							dst_offset <<= 8;  							ib[idx+1] += (u32)(dst_reloc->lobj.gpu_offset >> 8);  						} @@ -3176,10 +3176,10 @@ int evergreen_dma_cs_parse(struct radeon_cs_parser *p)  					switch (misc) {  					case 0:  						/* L2L, byte */ -						src_offset = ib[idx+2]; -						src_offset |= ((u64)(ib[idx+4] & 0xff)) << 32; -						dst_offset = ib[idx+1]; -						dst_offset |= ((u64)(ib[idx+3] & 0xff)) << 32; +						src_offset = radeon_get_ib_value(p, idx+2); +						src_offset |= ((u64)(radeon_get_ib_value(p, idx+4) & 0xff)) << 32; +						dst_offset = radeon_get_ib_value(p, idx+1); +						dst_offset |= ((u64)(radeon_get_ib_value(p, idx+3) & 0xff)) << 32;  						if ((src_offset + count) > radeon_bo_size(src_reloc->robj)) {  							dev_warn(p->dev, "DMA L2L, byte src buffer too small (%llu %lu)\n",  								 src_offset + count, radeon_bo_size(src_reloc->robj)); @@ -3216,12 +3216,12 @@ int evergreen_dma_cs_parse(struct radeon_cs_parser *p)  							DRM_ERROR("bad L2L, dw, broadcast DMA_PACKET_COPY\n");  							return -EINVAL;  						} -						dst_offset = ib[idx+1]; -						dst_offset |= ((u64)(ib[idx+4] & 0xff)) << 32; -						dst2_offset = ib[idx+2]; -						dst2_offset |= ((u64)(ib[idx+5] & 0xff)) << 32; -						src_offset = ib[idx+3]; -						src_offset |= ((u64)(ib[idx+6] & 0xff)) << 32; +						dst_offset = radeon_get_ib_value(p, idx+1); +						dst_offset |= ((u64)(radeon_get_ib_value(p, idx+4) & 0xff)) << 32; +						dst2_offset = radeon_get_ib_value(p, idx+2); +						dst2_offset |= ((u64)(radeon_get_ib_value(p, idx+5) & 0xff)) << 32; +						src_offset = radeon_get_ib_value(p, idx+3); +						src_offset |= ((u64)(radeon_get_ib_value(p, idx+6) & 0xff)) << 32;  						if ((src_offset + (count * 4)) > radeon_bo_size(src_reloc->robj)) {  							dev_warn(p->dev, "DMA L2L, dw, broadcast src buffer too small (%llu %lu)\n",  								 src_offset + (count * 4), radeon_bo_size(src_reloc->robj)); @@ -3251,10 +3251,10 @@ int evergreen_dma_cs_parse(struct radeon_cs_parser *p)  					}  				} else {  					/* L2L, dw */ -					src_offset = ib[idx+2]; -					src_offset |= ((u64)(ib[idx+4] & 0xff)) << 32; -					dst_offset = ib[idx+1]; -					dst_offset |= ((u64)(ib[idx+3] & 0xff)) << 32; +					src_offset = radeon_get_ib_value(p, idx+2); +					src_offset |= ((u64)(radeon_get_ib_value(p, idx+4) & 0xff)) << 32; +					dst_offset = radeon_get_ib_value(p, idx+1); +					dst_offset |= ((u64)(radeon_get_ib_value(p, idx+3) & 0xff)) << 32;  					if ((src_offset + (count * 4)) > radeon_bo_size(src_reloc->robj)) {  						dev_warn(p->dev, "DMA L2L, dw src buffer too small (%llu %lu)\n",  							 src_offset + (count * 4), radeon_bo_size(src_reloc->robj)); @@ -3279,8 +3279,8 @@ int evergreen_dma_cs_parse(struct radeon_cs_parser *p)  				DRM_ERROR("bad DMA_PACKET_CONSTANT_FILL\n");  				return -EINVAL;  			} -			dst_offset = ib[idx+1]; -			dst_offset |= ((u64)(ib[idx+3] & 0x00ff0000)) << 16; +			dst_offset = radeon_get_ib_value(p, idx+1); +			dst_offset |= ((u64)(radeon_get_ib_value(p, idx+3) & 0x00ff0000)) << 16;  			if ((dst_offset + (count * 4)) > radeon_bo_size(dst_reloc->robj)) {  				dev_warn(p->dev, "DMA constant fill buffer too small (%llu %lu)\n",  					 dst_offset, radeon_bo_size(dst_reloc->robj)); diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index 59acabb45c9..835992d8d06 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c @@ -1216,7 +1216,7 @@ void cayman_dma_stop(struct radeon_device *rdev)  int cayman_dma_resume(struct radeon_device *rdev)  {  	struct radeon_ring *ring; -	u32 rb_cntl, dma_cntl; +	u32 rb_cntl, dma_cntl, ib_cntl;  	u32 rb_bufsz;  	u32 reg_offset, wb_offset;  	int i, r; @@ -1265,7 +1265,11 @@ int cayman_dma_resume(struct radeon_device *rdev)  		WREG32(DMA_RB_BASE + reg_offset, ring->gpu_addr >> 8);  		/* enable DMA IBs */ -		WREG32(DMA_IB_CNTL + reg_offset, DMA_IB_ENABLE | CMD_VMID_FORCE); +		ib_cntl = DMA_IB_ENABLE | CMD_VMID_FORCE; +#ifdef __BIG_ENDIAN +		ib_cntl |= DMA_IB_SWAP_ENABLE; +#endif +		WREG32(DMA_IB_CNTL + reg_offset, ib_cntl);  		dma_cntl = RREG32(DMA_CNTL + reg_offset);  		dma_cntl &= ~CTXEMPTY_INT_ENABLE; diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 3cb9d608937..becb03e8b32 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -1462,12 +1462,15 @@ u32 r6xx_remap_render_backend(struct radeon_device *rdev,  			      u32 disabled_rb_mask)  {  	u32 rendering_pipe_num, rb_num_width, req_rb_num; -	u32 pipe_rb_ratio, pipe_rb_remain; +	u32 pipe_rb_ratio, pipe_rb_remain, tmp;  	u32 data = 0, mask = 1 << (max_rb_num - 1);  	unsigned i, j;  	/* mask out the RBs that don't exist on that asic */ -	disabled_rb_mask |= (0xff << max_rb_num) & 0xff; +	tmp = disabled_rb_mask | ((0xff << max_rb_num) & 0xff); +	/* make sure at least one RB is available */ +	if ((tmp & 0xff) != 0xff) +		disabled_rb_mask = tmp;  	rendering_pipe_num = 1 << tiling_pipe_num;  	req_rb_num = total_max_rb_num - r600_count_pipe_bits(disabled_rb_mask); @@ -2313,7 +2316,7 @@ void r600_dma_stop(struct radeon_device *rdev)  int r600_dma_resume(struct radeon_device *rdev)  {  	struct radeon_ring *ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX]; -	u32 rb_cntl, dma_cntl; +	u32 rb_cntl, dma_cntl, ib_cntl;  	u32 rb_bufsz;  	int r; @@ -2353,7 +2356,11 @@ int r600_dma_resume(struct radeon_device *rdev)  	WREG32(DMA_RB_BASE, ring->gpu_addr >> 8);  	/* enable DMA IBs */ -	WREG32(DMA_IB_CNTL, DMA_IB_ENABLE); +	ib_cntl = DMA_IB_ENABLE; +#ifdef __BIG_ENDIAN +	ib_cntl |= DMA_IB_SWAP_ENABLE; +#endif +	WREG32(DMA_IB_CNTL, ib_cntl);  	dma_cntl = RREG32(DMA_CNTL);  	dma_cntl &= ~CTXEMPTY_INT_ENABLE; diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c index 69ec24ab8d6..9b2512bf1a4 100644 --- a/drivers/gpu/drm/radeon/r600_cs.c +++ b/drivers/gpu/drm/radeon/r600_cs.c @@ -2623,14 +2623,14 @@ int r600_dma_cs_parse(struct radeon_cs_parser *p)  				return -EINVAL;  			}  			if (tiled) { -				dst_offset = ib[idx+1]; +				dst_offset = radeon_get_ib_value(p, idx+1);  				dst_offset <<= 8;  				ib[idx+1] += (u32)(dst_reloc->lobj.gpu_offset >> 8);  				p->idx += count + 5;  			} else { -				dst_offset = ib[idx+1]; -				dst_offset |= ((u64)(ib[idx+2] & 0xff)) << 32; +				dst_offset = radeon_get_ib_value(p, idx+1); +				dst_offset |= ((u64)(radeon_get_ib_value(p, idx+2) & 0xff)) << 32;  				ib[idx+1] += (u32)(dst_reloc->lobj.gpu_offset & 0xfffffffc);  				ib[idx+2] += upper_32_bits(dst_reloc->lobj.gpu_offset) & 0xff; @@ -2658,32 +2658,32 @@ int r600_dma_cs_parse(struct radeon_cs_parser *p)  				/* detile bit */  				if (idx_value & (1 << 31)) {  					/* tiled src, linear dst */ -					src_offset = ib[idx+1]; +					src_offset = radeon_get_ib_value(p, idx+1);  					src_offset <<= 8;  					ib[idx+1] += (u32)(src_reloc->lobj.gpu_offset >> 8); -					dst_offset = ib[idx+5]; -					dst_offset |= ((u64)(ib[idx+6] & 0xff)) << 32; +					dst_offset = radeon_get_ib_value(p, idx+5); +					dst_offset |= ((u64)(radeon_get_ib_value(p, idx+6) & 0xff)) << 32;  					ib[idx+5] += (u32)(dst_reloc->lobj.gpu_offset & 0xfffffffc);  					ib[idx+6] += upper_32_bits(dst_reloc->lobj.gpu_offset) & 0xff;  				} else {  					/* linear src, tiled dst */ -					src_offset = ib[idx+5]; -					src_offset |= ((u64)(ib[idx+6] & 0xff)) << 32; +					src_offset = radeon_get_ib_value(p, idx+5); +					src_offset |= ((u64)(radeon_get_ib_value(p, idx+6) & 0xff)) << 32;  					ib[idx+5] += (u32)(src_reloc->lobj.gpu_offset & 0xfffffffc);  					ib[idx+6] += upper_32_bits(src_reloc->lobj.gpu_offset) & 0xff; -					dst_offset = ib[idx+1]; +					dst_offset = radeon_get_ib_value(p, idx+1);  					dst_offset <<= 8;  					ib[idx+1] += (u32)(dst_reloc->lobj.gpu_offset >> 8);  				}  				p->idx += 7;  			} else {  				if (p->family >= CHIP_RV770) { -					src_offset = ib[idx+2]; -					src_offset |= ((u64)(ib[idx+4] & 0xff)) << 32; -					dst_offset = ib[idx+1]; -					dst_offset |= ((u64)(ib[idx+3] & 0xff)) << 32; +					src_offset = radeon_get_ib_value(p, idx+2); +					src_offset |= ((u64)(radeon_get_ib_value(p, idx+4) & 0xff)) << 32; +					dst_offset = radeon_get_ib_value(p, idx+1); +					dst_offset |= ((u64)(radeon_get_ib_value(p, idx+3) & 0xff)) << 32;  					ib[idx+1] += (u32)(dst_reloc->lobj.gpu_offset & 0xfffffffc);  					ib[idx+2] += (u32)(src_reloc->lobj.gpu_offset & 0xfffffffc); @@ -2691,10 +2691,10 @@ int r600_dma_cs_parse(struct radeon_cs_parser *p)  					ib[idx+4] += upper_32_bits(src_reloc->lobj.gpu_offset) & 0xff;  					p->idx += 5;  				} else { -					src_offset = ib[idx+2]; -					src_offset |= ((u64)(ib[idx+3] & 0xff)) << 32; -					dst_offset = ib[idx+1]; -					dst_offset |= ((u64)(ib[idx+3] & 0xff0000)) << 16; +					src_offset = radeon_get_ib_value(p, idx+2); +					src_offset |= ((u64)(radeon_get_ib_value(p, idx+3) & 0xff)) << 32; +					dst_offset = radeon_get_ib_value(p, idx+1); +					dst_offset |= ((u64)(radeon_get_ib_value(p, idx+3) & 0xff0000)) << 16;  					ib[idx+1] += (u32)(dst_reloc->lobj.gpu_offset & 0xfffffffc);  					ib[idx+2] += (u32)(src_reloc->lobj.gpu_offset & 0xfffffffc); @@ -2724,8 +2724,8 @@ int r600_dma_cs_parse(struct radeon_cs_parser *p)  				DRM_ERROR("bad DMA_PACKET_WRITE\n");  				return -EINVAL;  			} -			dst_offset = ib[idx+1]; -			dst_offset |= ((u64)(ib[idx+3] & 0x00ff0000)) << 16; +			dst_offset = radeon_get_ib_value(p, idx+1); +			dst_offset |= ((u64)(radeon_get_ib_value(p, idx+3) & 0x00ff0000)) << 16;  			if ((dst_offset + (count * 4)) > radeon_bo_size(dst_reloc->robj)) {  				dev_warn(p->dev, "DMA constant fill buffer too small (%llu %lu)\n",  					 dst_offset + (count * 4), radeon_bo_size(dst_reloc->robj)); diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c index 9056fafb00e..0b202c07fe5 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.c +++ b/drivers/gpu/drm/radeon/radeon_asic.c @@ -1445,7 +1445,7 @@ static struct radeon_asic cayman_asic = {  	.vm = {  		.init = &cayman_vm_init,  		.fini = &cayman_vm_fini, -		.pt_ring_index = R600_RING_TYPE_DMA_INDEX, +		.pt_ring_index = RADEON_RING_TYPE_GFX_INDEX,  		.set_page = &cayman_vm_set_page,  	},  	.ring = { @@ -1572,7 +1572,7 @@ static struct radeon_asic trinity_asic = {  	.vm = {  		.init = &cayman_vm_init,  		.fini = &cayman_vm_fini, -		.pt_ring_index = R600_RING_TYPE_DMA_INDEX, +		.pt_ring_index = RADEON_RING_TYPE_GFX_INDEX,  		.set_page = &cayman_vm_set_page,  	},  	.ring = { @@ -1699,7 +1699,7 @@ static struct radeon_asic si_asic = {  	.vm = {  		.init = &si_vm_init,  		.fini = &si_vm_fini, -		.pt_ring_index = R600_RING_TYPE_DMA_INDEX, +		.pt_ring_index = RADEON_RING_TYPE_GFX_INDEX,  		.set_page = &si_vm_set_page,  	},  	.ring = { diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c index 33a56a09ff1..3e403bdda58 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c @@ -2470,6 +2470,14 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev)  								   1),  								  ATOM_DEVICE_CRT1_SUPPORT);  				} +				/* RV100 board with external TDMS bit mis-set. +				 * Actually uses internal TMDS, clear the bit. +				 */ +				if (dev->pdev->device == 0x5159 && +				    dev->pdev->subsystem_vendor == 0x1014 && +				    dev->pdev->subsystem_device == 0x029A) { +					tmp &= ~(1 << 4); +				}  				if ((tmp >> 4) & 0x1) {  					devices |= ATOM_DEVICE_DFP2_SUPPORT;  					radeon_add_legacy_encoder(dev, diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c index 469661fd190..5407459e56d 100644 --- a/drivers/gpu/drm/radeon/radeon_cs.c +++ b/drivers/gpu/drm/radeon/radeon_cs.c @@ -286,6 +286,8 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data)  			    p->chunks[p->chunk_ib_idx].kpage[1] == NULL) {  				kfree(p->chunks[p->chunk_ib_idx].kpage[0]);  				kfree(p->chunks[p->chunk_ib_idx].kpage[1]); +				p->chunks[p->chunk_ib_idx].kpage[0] = NULL; +				p->chunks[p->chunk_ib_idx].kpage[1] = NULL;  				return -ENOMEM;  			}  		} diff --git a/drivers/gpu/drm/radeon/radeon_cursor.c b/drivers/gpu/drm/radeon/radeon_cursor.c index ad6df625e8b..0d67674b64b 100644 --- a/drivers/gpu/drm/radeon/radeon_cursor.c +++ b/drivers/gpu/drm/radeon/radeon_cursor.c @@ -241,7 +241,8 @@ int radeon_crtc_cursor_move(struct drm_crtc *crtc,  		y = 0;  	} -	if (ASIC_IS_AVIVO(rdev)) { +	/* fixed on DCE6 and newer */ +	if (ASIC_IS_AVIVO(rdev) && !ASIC_IS_DCE6(rdev)) {  		int i = 0;  		struct drm_crtc *crtc_p; diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index edfc54e4184..0d6562bb0c9 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c @@ -429,7 +429,8 @@ bool radeon_card_posted(struct radeon_device *rdev)  {  	uint32_t reg; -	if (efi_enabled && rdev->pdev->subsystem_vendor == PCI_VENDOR_ID_APPLE) +	if (efi_enabled(EFI_BOOT) && +	    rdev->pdev->subsystem_vendor == PCI_VENDOR_ID_APPLE)  		return false;  	/* first check CRTCs */ diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 1da2386d7cf..05c96fa0b05 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c @@ -1115,14 +1115,16 @@ radeon_user_framebuffer_create(struct drm_device *dev,  	}  	radeon_fb = kzalloc(sizeof(*radeon_fb), GFP_KERNEL); -	if (radeon_fb == NULL) +	if (radeon_fb == NULL) { +		drm_gem_object_unreference_unlocked(obj);  		return ERR_PTR(-ENOMEM); +	}  	ret = radeon_framebuffer_init(dev, radeon_fb, mode_cmd, obj);  	if (ret) {  		kfree(radeon_fb);  		drm_gem_object_unreference_unlocked(obj); -		return NULL; +		return ERR_PTR(ret);  	}  	return &radeon_fb->base; diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c index 2430d80b187..cd72062d5a9 100644 --- a/drivers/gpu/drm/radeon/radeon_ring.c +++ b/drivers/gpu/drm/radeon/radeon_ring.c @@ -377,6 +377,9 @@ int radeon_ring_alloc(struct radeon_device *rdev, struct radeon_ring *ring, unsi  {  	int r; +	/* make sure we aren't trying to allocate more space than there is on the ring */ +	if (ndw > (ring->ring_size / 4)) +		return -ENOMEM;  	/* Align requested size with padding so unlock_commit can  	 * pad safely */  	ndw = (ndw + ring->align_mask) & ~ring->align_mask; diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c index 1d8ff2f850b..93f760e27a9 100644 --- a/drivers/gpu/drm/radeon/radeon_ttm.c +++ b/drivers/gpu/drm/radeon/radeon_ttm.c @@ -38,6 +38,7 @@  #include <drm/radeon_drm.h>  #include <linux/seq_file.h>  #include <linux/slab.h> +#include <linux/swiotlb.h>  #include "radeon_reg.h"  #include "radeon.h" diff --git a/drivers/gpu/drm/radeon/reg_srcs/cayman b/drivers/gpu/drm/radeon/reg_srcs/cayman index 0f656b111c1..a072fa8c46b 100644 --- a/drivers/gpu/drm/radeon/reg_srcs/cayman +++ b/drivers/gpu/drm/radeon/reg_srcs/cayman @@ -1,5 +1,6 @@  cayman 0x9400  0x0000802C GRBM_GFX_INDEX +0x00008040 WAIT_UNTIL  0x000084FC CP_STRMOUT_CNTL  0x000085F0 CP_COHER_CNTL  0x000085F4 CP_COHER_SIZE diff --git a/drivers/gpu/drm/radeon/rv515.c b/drivers/gpu/drm/radeon/rv515.c index 2bb6d0e84b3..435ed355136 100644 --- a/drivers/gpu/drm/radeon/rv515.c +++ b/drivers/gpu/drm/radeon/rv515.c @@ -336,6 +336,8 @@ void rv515_mc_stop(struct radeon_device *rdev, struct rv515_mc_save *save)  				WREG32(R600_CITF_CNTL, blackout);  		}  	} +	/* wait for the MC to settle */ +	udelay(100);  }  void rv515_mc_resume(struct radeon_device *rdev, struct rv515_mc_save *save) diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c index 44420fca7df..8be35c809c7 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_util.c +++ b/drivers/gpu/drm/ttm/ttm_bo_util.c @@ -429,7 +429,7 @@ static int ttm_buffer_object_transfer(struct ttm_buffer_object *bo,  	struct ttm_bo_device *bdev = bo->bdev;  	struct ttm_bo_driver *driver = bdev->driver; -	fbo = kzalloc(sizeof(*fbo), GFP_KERNEL); +	fbo = kmalloc(sizeof(*fbo), GFP_KERNEL);  	if (!fbo)  		return -ENOMEM; @@ -448,7 +448,12 @@ static int ttm_buffer_object_transfer(struct ttm_buffer_object *bo,  	fbo->vm_node = NULL;  	atomic_set(&fbo->cpu_writers, 0); -	fbo->sync_obj = driver->sync_obj_ref(bo->sync_obj); +	spin_lock(&bdev->fence_lock); +	if (bo->sync_obj) +		fbo->sync_obj = driver->sync_obj_ref(bo->sync_obj); +	else +		fbo->sync_obj = NULL; +	spin_unlock(&bdev->fence_lock);  	kref_init(&fbo->list_kref);  	kref_init(&fbo->kref);  	fbo->destroy = &ttm_transfered_destroy; @@ -661,13 +666,11 @@ int ttm_bo_move_accel_cleanup(struct ttm_buffer_object *bo,  		 */  		set_bit(TTM_BO_PRIV_FLAG_MOVING, &bo->priv_flags); - -		/* ttm_buffer_object_transfer accesses bo->sync_obj */ -		ret = ttm_buffer_object_transfer(bo, &ghost_obj);  		spin_unlock(&bdev->fence_lock);  		if (tmp_obj)  			driver->sync_obj_unref(&tmp_obj); +		ret = ttm_buffer_object_transfer(bo, &ghost_obj);  		if (ret)  			return ret; diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 4dfa605e2d1..34e25471aea 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -306,6 +306,9 @@  #define USB_VENDOR_ID_EZKEY		0x0518  #define USB_DEVICE_ID_BTC_8193		0x0002 +#define USB_VENDOR_ID_FORMOSA          0x147a +#define USB_DEVICE_ID_FORMOSA_IR_RECEIVER      0xe03e +  #define USB_VENDOR_ID_FREESCALE		0x15A2  #define USB_DEVICE_ID_FREESCALE_MX28	0x004F diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c index 12e4fdc810b..e766b5614ef 100644 --- a/drivers/hid/i2c-hid/i2c-hid.c +++ b/drivers/hid/i2c-hid/i2c-hid.c @@ -540,13 +540,24 @@ static int i2c_hid_output_raw_report(struct hid_device *hid, __u8 *buf,  {  	struct i2c_client *client = hid->driver_data;  	int report_id = buf[0]; +	int ret;  	if (report_type == HID_INPUT_REPORT)  		return -EINVAL; -	return i2c_hid_set_report(client, +	if (report_id) { +		buf++; +		count--; +	} + +	ret = i2c_hid_set_report(client,  				report_type == HID_FEATURE_REPORT ? 0x03 : 0x02,  				report_id, buf, count); + +	if (report_id && ret >= 0) +		ret++; /* add report_id to the number of transfered bytes */ + +	return ret;  }  static int i2c_hid_parse(struct hid_device *hid) diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index ac9e3522825..e0e6abf1cd3 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c @@ -70,6 +70,7 @@ static const struct hid_blacklist {  	{ USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_AXIS_295, HID_QUIRK_NOGET },  	{ USB_VENDOR_ID_DMI, USB_DEVICE_ID_DMI_ENC, HID_QUIRK_NOGET },  	{ USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700, HID_QUIRK_NOGET }, +	{ USB_VENDOR_ID_FORMOSA, USB_DEVICE_ID_FORMOSA_IR_RECEIVER, HID_QUIRK_NO_INIT_REPORTS },  	{ USB_VENDOR_ID_FREESCALE, USB_DEVICE_ID_FREESCALE_MX28, HID_QUIRK_NOGET },  	{ USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_NOGET },  	{ USB_VENDOR_ID_NOVATEK, USB_DEVICE_ID_NOVATEK_MOUSE, HID_QUIRK_NO_INIT_REPORTS }, diff --git a/drivers/i2c/busses/i2c-designware-core.c b/drivers/i2c/busses/i2c-designware-core.c index cbba7db9ad5..f5258c205de 100644 --- a/drivers/i2c/busses/i2c-designware-core.c +++ b/drivers/i2c/busses/i2c-designware-core.c @@ -34,6 +34,7 @@  #include <linux/io.h>  #include <linux/pm_runtime.h>  #include <linux/delay.h> +#include <linux/module.h>  #include "i2c-designware-core.h"  /* @@ -725,3 +726,6 @@ u32 i2c_dw_read_comp_param(struct dw_i2c_dev *dev)  	return dw_readl(dev, DW_IC_COMP_PARAM_1);  }  EXPORT_SYMBOL_GPL(i2c_dw_read_comp_param); + +MODULE_DESCRIPTION("Synopsys DesignWare I2C bus adapter core"); +MODULE_LICENSE("GPL"); diff --git a/drivers/i2c/busses/i2c-mxs.c b/drivers/i2c/busses/i2c-mxs.c index 1b1a936eccc..d6abaf2cf2e 100644 --- a/drivers/i2c/busses/i2c-mxs.c +++ b/drivers/i2c/busses/i2c-mxs.c @@ -127,7 +127,7 @@ struct mxs_i2c_dev {  	struct device *dev;  	void __iomem *regs;  	struct completion cmd_complete; -	u32 cmd_err; +	int cmd_err;  	struct i2c_adapter adapter;  	const struct mxs_i2c_speed_config *speed; @@ -316,7 +316,7 @@ static int mxs_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg,  	if (msg->len == 0)  		return -EINVAL; -	init_completion(&i2c->cmd_complete); +	INIT_COMPLETION(i2c->cmd_complete);  	i2c->cmd_err = 0;  	ret = mxs_i2c_dma_setup_xfer(adap, msg, flags); @@ -473,6 +473,8 @@ static int mxs_i2c_probe(struct platform_device *pdev)  	i2c->dev = dev;  	i2c->speed = &mxs_i2c_95kHz_config; +	init_completion(&i2c->cmd_complete); +  	if (dev->of_node) {  		err = mxs_i2c_get_ofdata(i2c);  		if (err) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 20d41bfa7c1..4cc2f0528c8 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -803,7 +803,7 @@ static int errata_omap3_i462(struct omap_i2c_dev *dev)  			if (stat & OMAP_I2C_STAT_AL) {  				dev_err(dev->dev, "Arbitration lost\n");  				dev->cmd_err |= OMAP_I2C_STAT_AL; -				omap_i2c_ack_stat(dev, OMAP_I2C_STAT_NACK); +				omap_i2c_ack_stat(dev, OMAP_I2C_STAT_AL);  			}  			return -EIO; @@ -963,7 +963,7 @@ omap_i2c_isr_thread(int this_irq, void *dev_id)  				i2c_omap_errata_i207(dev, stat);  			omap_i2c_ack_stat(dev, OMAP_I2C_STAT_RDR); -			break; +			continue;  		}  		if (stat & OMAP_I2C_STAT_RRDY) { @@ -989,7 +989,7 @@ omap_i2c_isr_thread(int this_irq, void *dev_id)  				break;  			omap_i2c_ack_stat(dev, OMAP_I2C_STAT_XDR); -			break; +			continue;  		}  		if (stat & OMAP_I2C_STAT_XRDY) { diff --git a/drivers/i2c/busses/i2c-sirf.c b/drivers/i2c/busses/i2c-sirf.c index 3f1818b8797..e03381aee34 100644 --- a/drivers/i2c/busses/i2c-sirf.c +++ b/drivers/i2c/busses/i2c-sirf.c @@ -12,6 +12,7 @@  #include <linux/slab.h>  #include <linux/platform_device.h>  #include <linux/i2c.h> +#include <linux/of_i2c.h>  #include <linux/clk.h>  #include <linux/err.h>  #include <linux/io.h> @@ -328,6 +329,7 @@ static int i2c_sirfsoc_probe(struct platform_device *pdev)  	adap->algo = &i2c_sirfsoc_algo;  	adap->algo_data = siic; +	adap->dev.of_node = pdev->dev.of_node;  	adap->dev.parent = &pdev->dev;  	adap->nr = pdev->id; @@ -371,6 +373,8 @@ static int i2c_sirfsoc_probe(struct platform_device *pdev)  	clk_disable(clk); +	of_i2c_register_devices(adap); +  	dev_info(&pdev->dev, " I2C adapter ready to operate\n");  	return 0; diff --git a/drivers/i2c/muxes/i2c-mux-pinctrl.c b/drivers/i2c/muxes/i2c-mux-pinctrl.c index 1e44d04d1b2..a43c0ce5e3d 100644 --- a/drivers/i2c/muxes/i2c-mux-pinctrl.c +++ b/drivers/i2c/muxes/i2c-mux-pinctrl.c @@ -167,7 +167,7 @@ static int i2c_mux_pinctrl_probe(struct platform_device *pdev)  	}  	mux->busses = devm_kzalloc(&pdev->dev, -				   sizeof(mux->busses) * mux->pdata->bus_count, +				   sizeof(*mux->busses) * mux->pdata->bus_count,  				   GFP_KERNEL);  	if (!mux->busses) {  		dev_err(&pdev->dev, "Cannot allocate busses\n"); diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c index 4ba384f1ab5..2df9414a72f 100644 --- a/drivers/idle/intel_idle.c +++ b/drivers/idle/intel_idle.c @@ -448,8 +448,6 @@ static int intel_idle_probe(void)  	else  		on_each_cpu(__setup_broadcast_timer, (void *)true, 1); -	register_cpu_notifier(&cpu_hotplug_notifier); -  	pr_debug(PREFIX "v" INTEL_IDLE_VERSION  		" model 0x%X\n", boot_cpu_data.x86_model); @@ -612,6 +610,7 @@ static int __init intel_idle_init(void)  			return retval;  		}  	} +	register_cpu_notifier(&cpu_hotplug_notifier);  	return 0;  } diff --git a/drivers/infiniband/hw/qib/qib_qp.c b/drivers/infiniband/hw/qib/qib_qp.c index 4850d03870c..35275099caf 100644 --- a/drivers/infiniband/hw/qib/qib_qp.c +++ b/drivers/infiniband/hw/qib/qib_qp.c @@ -263,20 +263,15 @@ static void remove_qp(struct qib_ibdev *dev, struct qib_qp *qp)  		struct qib_qp __rcu **qpp;  		qpp = &dev->qp_table[n]; -		q = rcu_dereference_protected(*qpp, -			lockdep_is_held(&dev->qpt_lock)); -		for (; q; qpp = &q->next) { +		for (; (q = rcu_dereference_protected(*qpp, +				lockdep_is_held(&dev->qpt_lock))) != NULL; +				qpp = &q->next)  			if (q == qp) {  				atomic_dec(&qp->refcount);  				*qpp = qp->next;  				rcu_assign_pointer(qp->next, NULL); -				q = rcu_dereference_protected(*qpp, -					lockdep_is_held(&dev->qpt_lock));  				break;  			} -			q = rcu_dereference_protected(*qpp, -				lockdep_is_held(&dev->qpt_lock)); -		}  	}  	spin_unlock_irqrestore(&dev->qpt_lock, flags); diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c index 03103d2bd64..67b0c1d2367 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c @@ -741,6 +741,9 @@ void ipoib_cm_send(struct net_device *dev, struct sk_buff *skb, struct ipoib_cm_  	tx_req->mapping = addr; +	skb_orphan(skb); +	skb_dst_drop(skb); +  	rc = post_send(priv, tx, tx->tx_head & (ipoib_sendq_size - 1),  		       addr, skb->len);  	if (unlikely(rc)) { @@ -752,9 +755,6 @@ void ipoib_cm_send(struct net_device *dev, struct sk_buff *skb, struct ipoib_cm_  		dev->trans_start = jiffies;  		++tx->tx_head; -		skb_orphan(skb); -		skb_dst_drop(skb); -  		if (++priv->tx_outstanding == ipoib_sendq_size) {  			ipoib_dbg(priv, "TX ring 0x%x full, stopping kernel net queue\n",  				  tx->qp->qp_num); diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c index a1bca70e20a..2cfa76f5d99 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c @@ -600,6 +600,9 @@ void ipoib_send(struct net_device *dev, struct sk_buff *skb,  		netif_stop_queue(dev);  	} +	skb_orphan(skb); +	skb_dst_drop(skb); +  	rc = post_send(priv, priv->tx_head & (ipoib_sendq_size - 1),  		       address->ah, qpn, tx_req, phead, hlen);  	if (unlikely(rc)) { @@ -615,9 +618,6 @@ void ipoib_send(struct net_device *dev, struct sk_buff *skb,  		address->last_send = priv->tx_head;  		++priv->tx_head; - -		skb_orphan(skb); -		skb_dst_drop(skb);  	}  	if (unlikely(priv->tx_outstanding > MAX_SEND_CQE)) diff --git a/drivers/input/input.c b/drivers/input/input.c index ce01332f7b3..c0446992892 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -1785,12 +1785,13 @@ static void devm_input_device_release(struct device *dev, void *res)   * its driver (or binding fails). Once managed input device is allocated,   * it is ready to be set up and registered in the same fashion as regular   * input device. There are no special devm_input_device_[un]register() - * variants, regular ones work with both managed and unmanaged devices. + * variants, regular ones work with both managed and unmanaged devices, + * should you need them. In most cases however, managed input device need + * not be explicitly unregistered or freed.   *   * NOTE: the owner device is set up as parent of input device and users   * should not override it.   */ -  struct input_dev *devm_input_allocate_device(struct device *dev)  {  	struct input_dev *input; @@ -2004,6 +2005,17 @@ static void devm_input_device_unregister(struct device *dev, void *res)   * Once device has been successfully registered it can be unregistered   * with input_unregister_device(); input_free_device() should not be   * called in this case. + * + * Note that this function is also used to register managed input devices + * (ones allocated with devm_input_allocate_device()). Such managed input + * devices need not be explicitly unregistered or freed, their tear down + * is controlled by the devres infrastructure. It is also worth noting + * that tear down of managed input devices is internally a 2-step process: + * registered managed input device is first unregistered, but stays in + * memory and can still handle input_event() calls (although events will + * not be delivered anywhere). The freeing of managed input device will + * happen later, when devres stack is unwound to the point where device + * allocation was made.   */  int input_register_device(struct input_dev *dev)  { diff --git a/drivers/input/joystick/analog.c b/drivers/input/joystick/analog.c index 358cd7ee905..7cd74e29cbc 100644 --- a/drivers/input/joystick/analog.c +++ b/drivers/input/joystick/analog.c @@ -162,7 +162,7 @@ static unsigned int get_time_pit(void)  #define GET_TIME(x)	do { x = get_cycles(); } while (0)  #define DELTA(x,y)	((y)-(x))  #define TIME_NAME	"PCC" -#elif defined(CONFIG_MN10300) +#elif defined(CONFIG_MN10300) || defined(CONFIG_TILE)  #define GET_TIME(x)	do { x = get_cycles(); } while (0)  #define DELTA(x, y)	((x) - (y))  #define TIME_NAME	"TSC" diff --git a/drivers/input/keyboard/lm8323.c b/drivers/input/keyboard/lm8323.c index 93c81266213..0de23f41b2d 100644 --- a/drivers/input/keyboard/lm8323.c +++ b/drivers/input/keyboard/lm8323.c @@ -398,7 +398,7 @@ static irqreturn_t lm8323_irq(int irq, void *_lm)  			lm8323_configure(lm);  		}  		for (i = 0; i < LM8323_NUM_PWMS; i++) { -			if (ints & (1 << (INT_PWM1 + i))) { +			if (ints & (INT_PWM1 << i)) {  				dev_vdbg(&lm->client->dev,  					 "pwm%d engine completed\n", i);  				pwm_done(&lm->pwm[i]); diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c index f92d34f45a1..aaf23aeae2e 100644 --- a/drivers/input/tablet/wacom_sys.c +++ b/drivers/input/tablet/wacom_sys.c @@ -553,10 +553,10 @@ static int wacom_set_device_mode(struct usb_interface *intf, int report_id, int  	if (!rep_data)  		return error; -	rep_data[0] = report_id; -	rep_data[1] = mode; -  	do { +		rep_data[0] = report_id; +		rep_data[1] = mode; +  		error = wacom_set_report(intf, WAC_HID_FEATURE_REPORT,  		                         report_id, rep_data, length, 1);  		if (error >= 0) diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c index 81837b0710a..faf10ba1ed9 100644 --- a/drivers/iommu/amd_iommu_init.c +++ b/drivers/iommu/amd_iommu_init.c @@ -975,6 +975,38 @@ static void __init free_iommu_all(void)  }  /* + * Family15h Model 10h-1fh erratum 746 (IOMMU Logging May Stall Translations) + * Workaround: + *     BIOS should disable L2B micellaneous clock gating by setting + *     L2_L2B_CK_GATE_CONTROL[CKGateL2BMiscDisable](D0F2xF4_x90[2]) = 1b + */ +static void __init amd_iommu_erratum_746_workaround(struct amd_iommu *iommu) +{ +	u32 value; + +	if ((boot_cpu_data.x86 != 0x15) || +	    (boot_cpu_data.x86_model < 0x10) || +	    (boot_cpu_data.x86_model > 0x1f)) +		return; + +	pci_write_config_dword(iommu->dev, 0xf0, 0x90); +	pci_read_config_dword(iommu->dev, 0xf4, &value); + +	if (value & BIT(2)) +		return; + +	/* Select NB indirect register 0x90 and enable writing */ +	pci_write_config_dword(iommu->dev, 0xf0, 0x90 | (1 << 8)); + +	pci_write_config_dword(iommu->dev, 0xf4, value | 0x4); +	pr_info("AMD-Vi: Applying erratum 746 workaround for IOMMU at %s\n", +		dev_name(&iommu->dev->dev)); + +	/* Clear the enable writing bit */ +	pci_write_config_dword(iommu->dev, 0xf0, 0x90); +} + +/*   * This function clues the initialization function for one IOMMU   * together and also allocates the command buffer and programs the   * hardware. It does NOT enable the IOMMU. This is done afterwards. @@ -1172,6 +1204,8 @@ static int iommu_init_pci(struct amd_iommu *iommu)  			iommu->stored_l2[i] = iommu_read_l2(iommu, i);  	} +	amd_iommu_erratum_746_workaround(iommu); +  	return pci_enable_device(iommu->dev);  } diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index b9d09115788..eca28014ef3 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c @@ -4234,6 +4234,21 @@ static struct iommu_ops intel_iommu_ops = {  	.pgsize_bitmap	= INTEL_IOMMU_PGSIZES,  }; +static void quirk_iommu_g4x_gfx(struct pci_dev *dev) +{ +	/* G4x/GM45 integrated gfx dmar support is totally busted. */ +	printk(KERN_INFO "DMAR: Disabling IOMMU for graphics on this chipset\n"); +	dmar_map_gfx = 0; +} + +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2a40, quirk_iommu_g4x_gfx); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e00, quirk_iommu_g4x_gfx); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e10, quirk_iommu_g4x_gfx); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e20, quirk_iommu_g4x_gfx); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e30, quirk_iommu_g4x_gfx); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e40, quirk_iommu_g4x_gfx); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e90, quirk_iommu_g4x_gfx); +  static void quirk_iommu_rwbf(struct pci_dev *dev)  {  	/* @@ -4242,12 +4257,6 @@ static void quirk_iommu_rwbf(struct pci_dev *dev)  	 */  	printk(KERN_INFO "DMAR: Forcing write-buffer flush capability\n");  	rwbf_quirk = 1; - -	/* https://bugzilla.redhat.com/show_bug.cgi?id=538163 */ -	if (dev->revision == 0x07) { -		printk(KERN_INFO "DMAR: Disabling IOMMU for graphics on this chipset\n"); -		dmar_map_gfx = 0; -	}  }  DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2a40, quirk_iommu_rwbf); diff --git a/drivers/isdn/gigaset/capi.c b/drivers/isdn/gigaset/capi.c index 68452b768da..03a0a01a405 100644 --- a/drivers/isdn/gigaset/capi.c +++ b/drivers/isdn/gigaset/capi.c @@ -248,6 +248,8 @@ static inline void dump_rawmsg(enum debuglevel level, const char *tag,  		CAPIMSG_APPID(data), CAPIMSG_MSGID(data), l,  		CAPIMSG_CONTROL(data));  	l -= 12; +	if (l <= 0) +		return;  	dbgline = kmalloc(3 * l, GFP_ATOMIC);  	if (!dbgline)  		return; diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c index 3d8984edeff..9e58dbd8d8c 100644 --- a/drivers/md/dm-raid.c +++ b/drivers/md/dm-raid.c @@ -340,24 +340,22 @@ static int validate_region_size(struct raid_set *rs, unsigned long region_size)  }  /* - * validate_rebuild_devices + * validate_raid_redundancy   * @rs   * - * Determine if the devices specified for rebuild can result in a valid - * usable array that is capable of rebuilding the given devices. + * Determine if there are enough devices in the array that haven't + * failed (or are being rebuilt) to form a usable array.   *   * Returns: 0 on success, -EINVAL on failure.   */ -static int validate_rebuild_devices(struct raid_set *rs) +static int validate_raid_redundancy(struct raid_set *rs)  {  	unsigned i, rebuild_cnt = 0;  	unsigned rebuilds_per_group, copies, d; -	if (!(rs->print_flags & DMPF_REBUILD)) -		return 0; -  	for (i = 0; i < rs->md.raid_disks; i++) -		if (!test_bit(In_sync, &rs->dev[i].rdev.flags)) +		if (!test_bit(In_sync, &rs->dev[i].rdev.flags) || +		    !rs->dev[i].rdev.sb_page)  			rebuild_cnt++;  	switch (rs->raid_type->level) { @@ -393,27 +391,24 @@ static int validate_rebuild_devices(struct raid_set *rs)  		 *          A    A    B    B    C  		 *          C    D    D    E    E  		 */ -		rebuilds_per_group = 0;  		for (i = 0; i < rs->md.raid_disks * copies; i++) { +			if (!(i % copies)) +				rebuilds_per_group = 0;  			d = i % rs->md.raid_disks; -			if (!test_bit(In_sync, &rs->dev[d].rdev.flags) && +			if ((!rs->dev[d].rdev.sb_page || +			     !test_bit(In_sync, &rs->dev[d].rdev.flags)) &&  			    (++rebuilds_per_group >= copies))  				goto too_many; -			if (!((i + 1) % copies)) -				rebuilds_per_group = 0;  		}  		break;  	default: -		DMERR("The rebuild parameter is not supported for %s", -		      rs->raid_type->name); -		rs->ti->error = "Rebuild not supported for this RAID type"; -		return -EINVAL; +		if (rebuild_cnt) +			return -EINVAL;  	}  	return 0;  too_many: -	rs->ti->error = "Too many rebuild devices specified";  	return -EINVAL;  } @@ -664,9 +659,6 @@ static int parse_raid_params(struct raid_set *rs, char **argv,  	}  	rs->md.dev_sectors = sectors_per_dev; -	if (validate_rebuild_devices(rs)) -		return -EINVAL; -  	/* Assume there are no metadata devices until the drives are parsed */  	rs->md.persistent = 0;  	rs->md.external = 1; @@ -995,28 +987,10 @@ static int super_validate(struct mddev *mddev, struct md_rdev *rdev)  static int analyse_superblocks(struct dm_target *ti, struct raid_set *rs)  {  	int ret; -	unsigned redundancy = 0;  	struct raid_dev *dev;  	struct md_rdev *rdev, *tmp, *freshest;  	struct mddev *mddev = &rs->md; -	switch (rs->raid_type->level) { -	case 1: -		redundancy = rs->md.raid_disks - 1; -		break; -	case 4: -	case 5: -	case 6: -		redundancy = rs->raid_type->parity_devs; -		break; -	case 10: -		redundancy = raid10_md_layout_to_copies(mddev->layout) - 1; -		break; -	default: -		ti->error = "Unknown RAID type"; -		return -EINVAL; -	} -  	freshest = NULL;  	rdev_for_each_safe(rdev, tmp, mddev) {  		/* @@ -1045,44 +1019,43 @@ static int analyse_superblocks(struct dm_target *ti, struct raid_set *rs)  			break;  		default:  			dev = container_of(rdev, struct raid_dev, rdev); -			if (redundancy--) { -				if (dev->meta_dev) -					dm_put_device(ti, dev->meta_dev); - -				dev->meta_dev = NULL; -				rdev->meta_bdev = NULL; +			if (dev->meta_dev) +				dm_put_device(ti, dev->meta_dev); -				if (rdev->sb_page) -					put_page(rdev->sb_page); +			dev->meta_dev = NULL; +			rdev->meta_bdev = NULL; -				rdev->sb_page = NULL; +			if (rdev->sb_page) +				put_page(rdev->sb_page); -				rdev->sb_loaded = 0; +			rdev->sb_page = NULL; -				/* -				 * We might be able to salvage the data device -				 * even though the meta device has failed.  For -				 * now, we behave as though '- -' had been -				 * set for this device in the table. -				 */ -				if (dev->data_dev) -					dm_put_device(ti, dev->data_dev); +			rdev->sb_loaded = 0; -				dev->data_dev = NULL; -				rdev->bdev = NULL; +			/* +			 * We might be able to salvage the data device +			 * even though the meta device has failed.  For +			 * now, we behave as though '- -' had been +			 * set for this device in the table. +			 */ +			if (dev->data_dev) +				dm_put_device(ti, dev->data_dev); -				list_del(&rdev->same_set); +			dev->data_dev = NULL; +			rdev->bdev = NULL; -				continue; -			} -			ti->error = "Failed to load superblock"; -			return ret; +			list_del(&rdev->same_set);  		}  	}  	if (!freshest)  		return 0; +	if (validate_raid_redundancy(rs)) { +		rs->ti->error = "Insufficient redundancy to activate array"; +		return -EINVAL; +	} +  	/*  	 * Validation of the freshest device provides the source of  	 * validation for the remaining devices. @@ -1432,7 +1405,7 @@ static void raid_resume(struct dm_target *ti)  static struct target_type raid_target = {  	.name = "raid", -	.version = {1, 4, 0}, +	.version = {1, 4, 1},  	.module = THIS_MODULE,  	.ctr = raid_ctr,  	.dtr = raid_dtr, diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c index 675ae527401..5409607d487 100644 --- a/drivers/md/dm-thin.c +++ b/drivers/md/dm-thin.c @@ -2746,19 +2746,9 @@ static int thin_iterate_devices(struct dm_target *ti,  	return 0;  } -/* - * A thin device always inherits its queue limits from its pool. - */ -static void thin_io_hints(struct dm_target *ti, struct queue_limits *limits) -{ -	struct thin_c *tc = ti->private; - -	*limits = bdev_get_queue(tc->pool_dev->bdev)->limits; -} -  static struct target_type thin_target = {  	.name = "thin", -	.version = {1, 6, 0}, +	.version = {1, 7, 0},  	.module	= THIS_MODULE,  	.ctr = thin_ctr,  	.dtr = thin_dtr, @@ -2767,7 +2757,6 @@ static struct target_type thin_target = {  	.postsuspend = thin_postsuspend,  	.status = thin_status,  	.iterate_devices = thin_iterate_devices, -	.io_hints = thin_io_hints,  };  /*----------------------------------------------------------------*/ diff --git a/drivers/md/dm.c b/drivers/md/dm.c index c72e4d5a961..314a0e2faf7 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -1188,6 +1188,7 @@ static int __clone_and_map_changing_extent_only(struct clone_info *ci,  {  	struct dm_target *ti;  	sector_t len; +	unsigned num_requests;  	do {  		ti = dm_table_find_target(ci->map, ci->sector); @@ -1200,7 +1201,8 @@ static int __clone_and_map_changing_extent_only(struct clone_info *ci,  		 * reconfiguration might also have changed that since the  		 * check was performed.  		 */ -		if (!get_num_requests || !get_num_requests(ti)) +		num_requests = get_num_requests ? get_num_requests(ti) : 0; +		if (!num_requests)  			return -EOPNOTSUPP;  		if (is_split_required && !is_split_required(ti)) @@ -1208,7 +1210,7 @@ static int __clone_and_map_changing_extent_only(struct clone_info *ci,  		else  			len = min(ci->sector_count, max_io_len(ci->sector, ti)); -		__issue_target_requests(ci, ti, ti->num_discard_requests, len); +		__issue_target_requests(ci, ti, num_requests, len);  		ci->sector += len;  	} while (ci->sector_count -= len); diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c index 49d95040096..0223ad255cb 100644 --- a/drivers/media/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb-core/dvb_frontend.c @@ -1820,7 +1820,7 @@ static int dvb_frontend_ioctl(struct file *file,  	struct dvb_frontend *fe = dvbdev->priv;  	struct dtv_frontend_properties *c = &fe->dtv_property_cache;  	struct dvb_frontend_private *fepriv = fe->frontend_priv; -	int err = -ENOTTY; +	int err = -EOPNOTSUPP;  	dev_dbg(fe->dvb->device, "%s: (%d)\n", __func__, _IOC_NR(cmd));  	if (fepriv->exit != DVB_FE_NO_EXIT) @@ -1938,7 +1938,7 @@ static int dvb_frontend_ioctl_properties(struct file *file,  		}  	} else -		err = -ENOTTY; +		err = -EOPNOTSUPP;  out:  	kfree(tvp); @@ -2071,7 +2071,7 @@ static int dvb_frontend_ioctl_legacy(struct file *file,  	struct dvb_frontend *fe = dvbdev->priv;  	struct dvb_frontend_private *fepriv = fe->frontend_priv;  	struct dtv_frontend_properties *c = &fe->dtv_property_cache; -	int err = -ENOTTY; +	int err = -EOPNOTSUPP;  	switch (cmd) {  	case FE_GET_INFO: { diff --git a/drivers/media/platform/coda.c b/drivers/media/platform/coda.c index 1cf8293c0fb..4a980e029ca 100644 --- a/drivers/media/platform/coda.c +++ b/drivers/media/platform/coda.c @@ -23,8 +23,8 @@  #include <linux/slab.h>  #include <linux/videodev2.h>  #include <linux/of.h> +#include <linux/platform_data/imx-iram.h> -#include <mach/iram.h>  #include <media/v4l2-ctrls.h>  #include <media/v4l2-device.h>  #include <media/v4l2-ioctl.h> diff --git a/drivers/media/radio/radio-keene.c b/drivers/media/radio/radio-keene.c index e10e525f33e..296941a9ae2 100644 --- a/drivers/media/radio/radio-keene.c +++ b/drivers/media/radio/radio-keene.c @@ -374,6 +374,7 @@ static int usb_keene_probe(struct usb_interface *intf,  	radio->vdev.ioctl_ops = &usb_keene_ioctl_ops;  	radio->vdev.lock = &radio->lock;  	radio->vdev.release = video_device_release_empty; +	radio->vdev.vfl_dir = VFL_DIR_TX;  	radio->usbdev = interface_to_usbdev(intf);  	radio->intf = intf; diff --git a/drivers/media/radio/radio-si4713.c b/drivers/media/radio/radio-si4713.c index a082e400ed0..1507c9d508d 100644 --- a/drivers/media/radio/radio-si4713.c +++ b/drivers/media/radio/radio-si4713.c @@ -250,6 +250,7 @@ static struct video_device radio_si4713_vdev_template = {  	.name			= "radio-si4713",  	.release		= video_device_release,  	.ioctl_ops		= &radio_si4713_ioctl_ops, +	.vfl_dir		= VFL_DIR_TX,  };  /* Platform driver interface */ diff --git a/drivers/media/radio/radio-wl1273.c b/drivers/media/radio/radio-wl1273.c index c48be195bba..cabbe3adf43 100644 --- a/drivers/media/radio/radio-wl1273.c +++ b/drivers/media/radio/radio-wl1273.c @@ -1971,6 +1971,7 @@ static struct video_device wl1273_viddev_template = {  	.ioctl_ops		= &wl1273_ioctl_ops,  	.name			= WL1273_FM_DRIVER_NAME,  	.release		= wl1273_vdev_release, +	.vfl_dir		= VFL_DIR_TX,  };  static int wl1273_fm_radio_remove(struct platform_device *pdev) diff --git a/drivers/media/radio/wl128x/fmdrv_v4l2.c b/drivers/media/radio/wl128x/fmdrv_v4l2.c index 048de453603..0a8ee8fab92 100644 --- a/drivers/media/radio/wl128x/fmdrv_v4l2.c +++ b/drivers/media/radio/wl128x/fmdrv_v4l2.c @@ -518,6 +518,16 @@ static struct video_device fm_viddev_template = {  	.ioctl_ops = &fm_drv_ioctl_ops,  	.name = FM_DRV_NAME,  	.release = video_device_release, +	/* +	 * To ensure both the tuner and modulator ioctls are accessible we +	 * set the vfl_dir to M2M to indicate this. +	 * +	 * It is not really a mem2mem device of course, but it can both receive +	 * and transmit using the same radio device. It's the only radio driver +	 * that does this and it should really be split in two radio devices, +	 * but that would affect applications using this driver. +	 */ +	.vfl_dir = VFL_DIR_M2M,  };  int fm_v4l2_init_video_device(struct fmdev *fmdev, int radio_nr) diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 47ad4e27087..ff553babf45 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -237,6 +237,7 @@ config MFD_TPS65910  	depends on I2C=y && GPIOLIB  	select MFD_CORE  	select REGMAP_I2C +	select REGMAP_IRQ  	select IRQ_DOMAIN  	help  	  if you say yes here you get support for the TPS65910 series of diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c index e1650badd10..4778bb124ef 100644 --- a/drivers/mfd/ab8500-core.c +++ b/drivers/mfd/ab8500-core.c @@ -19,6 +19,7 @@  #include <linux/mfd/core.h>  #include <linux/mfd/abx500.h>  #include <linux/mfd/abx500/ab8500.h> +#include <linux/mfd/abx500/ab8500-bm.h>  #include <linux/mfd/dbx500-prcmu.h>  #include <linux/regulator/ab8500.h>  #include <linux/of.h> diff --git a/drivers/mfd/arizona-core.c b/drivers/mfd/arizona-core.c index bc8a3edb6bb..222c03a5ddc 100644 --- a/drivers/mfd/arizona-core.c +++ b/drivers/mfd/arizona-core.c @@ -239,7 +239,12 @@ static int arizona_runtime_resume(struct device *dev)  		return ret;  	} -	regcache_sync(arizona->regmap); +	ret = regcache_sync(arizona->regmap); +	if (ret != 0) { +		dev_err(arizona->dev, "Failed to restore register cache\n"); +		regulator_disable(arizona->dcvdd); +		return ret; +	}  	return 0;  } diff --git a/drivers/mfd/arizona-irq.c b/drivers/mfd/arizona-irq.c index 74713bf5371..2bec5f0db3e 100644 --- a/drivers/mfd/arizona-irq.c +++ b/drivers/mfd/arizona-irq.c @@ -176,14 +176,7 @@ int arizona_irq_init(struct arizona *arizona)  		aod = &wm5102_aod;  		irq = &wm5102_irq; -		switch (arizona->rev) { -		case 0: -		case 1: -			ctrlif_error = false; -			break; -		default: -			break; -		} +		ctrlif_error = false;  		break;  #endif  #ifdef CONFIG_MFD_WM5110 @@ -191,14 +184,7 @@ int arizona_irq_init(struct arizona *arizona)  		aod = &wm5110_aod;  		irq = &wm5110_irq; -		switch (arizona->rev) { -		case 0: -		case 1: -			ctrlif_error = false; -			break; -		default: -			break; -		} +		ctrlif_error = false;  		break;  #endif  	default: diff --git a/drivers/mfd/da9052-i2c.c b/drivers/mfd/da9052-i2c.c index ac74a4d1dae..885e5678035 100644 --- a/drivers/mfd/da9052-i2c.c +++ b/drivers/mfd/da9052-i2c.c @@ -27,6 +27,66 @@  #include <linux/of_device.h>  #endif +/* I2C safe register check */ +static inline bool i2c_safe_reg(unsigned char reg) +{ +	switch (reg) { +	case DA9052_STATUS_A_REG: +	case DA9052_STATUS_B_REG: +	case DA9052_STATUS_C_REG: +	case DA9052_STATUS_D_REG: +	case DA9052_ADC_RES_L_REG: +	case DA9052_ADC_RES_H_REG: +	case DA9052_VDD_RES_REG: +	case DA9052_ICHG_AV_REG: +	case DA9052_TBAT_RES_REG: +	case DA9052_ADCIN4_RES_REG: +	case DA9052_ADCIN5_RES_REG: +	case DA9052_ADCIN6_RES_REG: +	case DA9052_TJUNC_RES_REG: +	case DA9052_TSI_X_MSB_REG: +	case DA9052_TSI_Y_MSB_REG: +	case DA9052_TSI_LSB_REG: +	case DA9052_TSI_Z_MSB_REG: +		return true; +	default: +		return false; +	} +} + +/* + * There is an issue with DA9052 and DA9053_AA/BA/BB PMIC where the PMIC + * gets lockup up or fails to respond following a system reset. + * This fix is to follow any read or write with a dummy read to a safe + * register. + */ +int da9052_i2c_fix(struct da9052 *da9052, unsigned char reg) +{ +	int val; + +	switch (da9052->chip_id) { +	case DA9052: +	case DA9053_AA: +	case DA9053_BA: +	case DA9053_BB: +		/* A dummy read to a safe register address. */ +	if (!i2c_safe_reg(reg)) +			return regmap_read(da9052->regmap, +					   DA9052_PARK_REGISTER, +					   &val); +		break; +	default: +		/* +		 * For other chips parking of I2C register +		 * to a safe place is not required. +		 */ +		break; +	} + +	return 0; +} +EXPORT_SYMBOL(da9052_i2c_fix); +  static int da9052_i2c_enable_multiwrite(struct da9052 *da9052)  {  	int reg_val, ret; @@ -83,6 +143,7 @@ static int da9052_i2c_probe(struct i2c_client *client,  	da9052->dev = &client->dev;  	da9052->chip_irq = client->irq; +	da9052->fix_io = da9052_i2c_fix;  	i2c_set_clientdata(client, da9052); diff --git a/drivers/mfd/db8500-prcmu.c b/drivers/mfd/db8500-prcmu.c index dc8826d8d69..268f45d4239 100644 --- a/drivers/mfd/db8500-prcmu.c +++ b/drivers/mfd/db8500-prcmu.c @@ -2524,7 +2524,7 @@ static bool read_mailbox_0(void)  		for (n = 0; n < NUM_PRCMU_WAKEUPS; n++) {  			if (ev & prcmu_irq_bit[n]) -				generic_handle_irq(IRQ_PRCMU_BASE + n); +				generic_handle_irq(irq_find_mapping(db8500_irq_domain, n));  		}  		r = true;  		break; @@ -2737,13 +2737,14 @@ static int db8500_irq_map(struct irq_domain *d, unsigned int virq,  }  static struct irq_domain_ops db8500_irq_ops = { -        .map    = db8500_irq_map, -        .xlate  = irq_domain_xlate_twocell, +	.map    = db8500_irq_map, +	.xlate  = irq_domain_xlate_twocell,  };  static int db8500_irq_init(struct device_node *np)  { -	int irq_base = -1; +	int irq_base = 0; +	int i;  	/* In the device tree case, just take some IRQs */  	if (!np) @@ -2758,6 +2759,10 @@ static int db8500_irq_init(struct device_node *np)  		return -ENOSYS;  	} +	/* All wakeups will be used, so create mappings for all */ +	for (i = 0; i < NUM_PRCMU_WAKEUPS; i++) +		irq_create_mapping(db8500_irq_domain, i); +  	return 0;  } diff --git a/drivers/mfd/max77686.c b/drivers/mfd/max77686.c index f6878f8db57..4d73963cd8f 100644 --- a/drivers/mfd/max77686.c +++ b/drivers/mfd/max77686.c @@ -93,15 +93,6 @@ static int max77686_i2c_probe(struct i2c_client *i2c,  	if (max77686 == NULL)  		return -ENOMEM; -	max77686->regmap = regmap_init_i2c(i2c, &max77686_regmap_config); -	if (IS_ERR(max77686->regmap)) { -		ret = PTR_ERR(max77686->regmap); -		dev_err(max77686->dev, "Failed to allocate register map: %d\n", -				ret); -		kfree(max77686); -		return ret; -	} -  	i2c_set_clientdata(i2c, max77686);  	max77686->dev = &i2c->dev;  	max77686->i2c = i2c; @@ -111,6 +102,15 @@ static int max77686_i2c_probe(struct i2c_client *i2c,  	max77686->irq_gpio = pdata->irq_gpio;  	max77686->irq = i2c->irq; +	max77686->regmap = regmap_init_i2c(i2c, &max77686_regmap_config); +	if (IS_ERR(max77686->regmap)) { +		ret = PTR_ERR(max77686->regmap); +		dev_err(max77686->dev, "Failed to allocate register map: %d\n", +				ret); +		kfree(max77686); +		return ret; +	} +  	if (regmap_read(max77686->regmap,  			 MAX77686_REG_DEVICE_ID, &data) < 0) {  		dev_err(max77686->dev, diff --git a/drivers/mfd/max77693.c b/drivers/mfd/max77693.c index cc5155e2049..9e60fed5ff8 100644 --- a/drivers/mfd/max77693.c +++ b/drivers/mfd/max77693.c @@ -114,35 +114,37 @@ static int max77693_i2c_probe(struct i2c_client *i2c,  	u8 reg_data;  	int ret = 0; +	if (!pdata) { +		dev_err(&i2c->dev, "No platform data found.\n"); +		return -EINVAL; +	} +  	max77693 = devm_kzalloc(&i2c->dev,  			sizeof(struct max77693_dev), GFP_KERNEL);  	if (max77693 == NULL)  		return -ENOMEM; -	max77693->regmap = devm_regmap_init_i2c(i2c, &max77693_regmap_config); -	if (IS_ERR(max77693->regmap)) { -		ret = PTR_ERR(max77693->regmap); -		dev_err(max77693->dev,"failed to allocate register map: %d\n", -				ret); -		goto err_regmap; -	} -  	i2c_set_clientdata(i2c, max77693);  	max77693->dev = &i2c->dev;  	max77693->i2c = i2c;  	max77693->irq = i2c->irq;  	max77693->type = id->driver_data; -	if (!pdata) -		goto err_regmap; +	max77693->regmap = devm_regmap_init_i2c(i2c, &max77693_regmap_config); +	if (IS_ERR(max77693->regmap)) { +		ret = PTR_ERR(max77693->regmap); +		dev_err(max77693->dev, "failed to allocate register map: %d\n", +				ret); +		return ret; +	}  	max77693->wakeup = pdata->wakeup; -	if (max77693_read_reg(max77693->regmap, -				MAX77693_PMIC_REG_PMIC_ID2, ®_data) < 0) { +	ret = max77693_read_reg(max77693->regmap, MAX77693_PMIC_REG_PMIC_ID2, +				®_data); +	if (ret < 0) {  		dev_err(max77693->dev, "device not found on this channel\n"); -		ret = -ENODEV; -		goto err_regmap; +		return ret;  	} else  		dev_info(max77693->dev, "device ID: 0x%x\n", reg_data); @@ -163,7 +165,7 @@ static int max77693_i2c_probe(struct i2c_client *i2c,  		ret = PTR_ERR(max77693->regmap_muic);  		dev_err(max77693->dev,  			"failed to allocate register map: %d\n", ret); -		goto err_regmap; +		goto err_regmap_muic;  	}  	ret = max77693_irq_init(max77693); @@ -184,9 +186,9 @@ static int max77693_i2c_probe(struct i2c_client *i2c,  err_mfd:  	max77693_irq_exit(max77693);  err_irq: +err_regmap_muic:  	i2c_unregister_device(max77693->muic);  	i2c_unregister_device(max77693->haptic); -err_regmap:  	return ret;  } diff --git a/drivers/mfd/pcf50633-core.c b/drivers/mfd/pcf50633-core.c index 64803f13bce..d11567307fb 100644 --- a/drivers/mfd/pcf50633-core.c +++ b/drivers/mfd/pcf50633-core.c @@ -208,6 +208,8 @@ static int pcf50633_probe(struct i2c_client *client,  	if (!pcf)  		return -ENOMEM; +	i2c_set_clientdata(client, pcf); +	pcf->dev = &client->dev;  	pcf->pdata = pdata;  	mutex_init(&pcf->lock); @@ -219,9 +221,6 @@ static int pcf50633_probe(struct i2c_client *client,  		return ret;  	} -	i2c_set_clientdata(client, pcf); -	pcf->dev = &client->dev; -  	version = pcf50633_reg_read(pcf, 0);  	variant = pcf50633_reg_read(pcf, 1);  	if (version < 0 || variant < 0) { diff --git a/drivers/mfd/rtl8411.c b/drivers/mfd/rtl8411.c index 89f046ca9e4..3d3b4addf81 100644 --- a/drivers/mfd/rtl8411.c +++ b/drivers/mfd/rtl8411.c @@ -112,6 +112,21 @@ static int rtl8411_card_power_off(struct rtsx_pcr *pcr, int card)  			BPP_LDO_POWB, BPP_LDO_SUSPEND);  } +static int rtl8411_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage) +{ +	u8 mask, val; + +	mask = (BPP_REG_TUNED18 << BPP_TUNED18_SHIFT_8411) | BPP_PAD_MASK; +	if (voltage == OUTPUT_3V3) +		val = (BPP_ASIC_3V3 << BPP_TUNED18_SHIFT_8411) | BPP_PAD_3V3; +	else if (voltage == OUTPUT_1V8) +		val = (BPP_ASIC_1V8 << BPP_TUNED18_SHIFT_8411) | BPP_PAD_1V8; +	else +		return -EINVAL; + +	return rtsx_pci_write_register(pcr, LDO_CTL, mask, val); +} +  static unsigned int rtl8411_cd_deglitch(struct rtsx_pcr *pcr)  {  	unsigned int card_exist; @@ -163,6 +178,18 @@ static unsigned int rtl8411_cd_deglitch(struct rtsx_pcr *pcr)  	return card_exist;  } +static int rtl8411_conv_clk_and_div_n(int input, int dir) +{ +	int output; + +	if (dir == CLK_TO_DIV_N) +		output = input * 4 / 5 - 2; +	else +		output = (input + 2) * 5 / 4; + +	return output; +} +  static const struct pcr_ops rtl8411_pcr_ops = {  	.extra_init_hw = rtl8411_extra_init_hw,  	.optimize_phy = NULL, @@ -172,7 +199,9 @@ static const struct pcr_ops rtl8411_pcr_ops = {  	.disable_auto_blink = rtl8411_disable_auto_blink,  	.card_power_on = rtl8411_card_power_on,  	.card_power_off = rtl8411_card_power_off, +	.switch_output_voltage = rtl8411_switch_output_voltage,  	.cd_deglitch = rtl8411_cd_deglitch, +	.conv_clk_and_div_n = rtl8411_conv_clk_and_div_n,  };  /* SD Pull Control Enable: diff --git a/drivers/mfd/rts5209.c b/drivers/mfd/rts5209.c index 283a4f14808..98fe0f39463 100644 --- a/drivers/mfd/rts5209.c +++ b/drivers/mfd/rts5209.c @@ -144,6 +144,25 @@ static int rts5209_card_power_off(struct rtsx_pcr *pcr, int card)  	return rtsx_pci_send_cmd(pcr, 100);  } +static int rts5209_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage) +{ +	int err; + +	if (voltage == OUTPUT_3V3) { +		err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4FC0 | 0x24); +		if (err < 0) +			return err; +	} else if (voltage == OUTPUT_1V8) { +		err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4C40 | 0x24); +		if (err < 0) +			return err; +	} else { +		return -EINVAL; +	} + +	return 0; +} +  static const struct pcr_ops rts5209_pcr_ops = {  	.extra_init_hw = rts5209_extra_init_hw,  	.optimize_phy = rts5209_optimize_phy, @@ -153,7 +172,9 @@ static const struct pcr_ops rts5209_pcr_ops = {  	.disable_auto_blink = rts5209_disable_auto_blink,  	.card_power_on = rts5209_card_power_on,  	.card_power_off = rts5209_card_power_off, +	.switch_output_voltage = rts5209_switch_output_voltage,  	.cd_deglitch = NULL, +	.conv_clk_and_div_n = NULL,  };  /* SD Pull Control Enable: diff --git a/drivers/mfd/rts5229.c b/drivers/mfd/rts5229.c index b9dbab266fd..29d889cbb9c 100644 --- a/drivers/mfd/rts5229.c +++ b/drivers/mfd/rts5229.c @@ -114,6 +114,25 @@ static int rts5229_card_power_off(struct rtsx_pcr *pcr, int card)  	return rtsx_pci_send_cmd(pcr, 100);  } +static int rts5229_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage) +{ +	int err; + +	if (voltage == OUTPUT_3V3) { +		err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4FC0 | 0x24); +		if (err < 0) +			return err; +	} else if (voltage == OUTPUT_1V8) { +		err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4C40 | 0x24); +		if (err < 0) +			return err; +	} else { +		return -EINVAL; +	} + +	return 0; +} +  static const struct pcr_ops rts5229_pcr_ops = {  	.extra_init_hw = rts5229_extra_init_hw,  	.optimize_phy = rts5229_optimize_phy, @@ -123,7 +142,9 @@ static const struct pcr_ops rts5229_pcr_ops = {  	.disable_auto_blink = rts5229_disable_auto_blink,  	.card_power_on = rts5229_card_power_on,  	.card_power_off = rts5229_card_power_off, +	.switch_output_voltage = rts5229_switch_output_voltage,  	.cd_deglitch = NULL, +	.conv_clk_and_div_n = NULL,  };  /* SD Pull Control Enable: diff --git a/drivers/mfd/rtsx_pcr.c b/drivers/mfd/rtsx_pcr.c index 7a7b0bda461..9fc57009e22 100644 --- a/drivers/mfd/rtsx_pcr.c +++ b/drivers/mfd/rtsx_pcr.c @@ -630,7 +630,10 @@ int rtsx_pci_switch_clock(struct rtsx_pcr *pcr, unsigned int card_clock,  	if (clk == pcr->cur_clock)  		return 0; -	N = (u8)(clk - 2); +	if (pcr->ops->conv_clk_and_div_n) +		N = (u8)pcr->ops->conv_clk_and_div_n(clk, CLK_TO_DIV_N); +	else +		N = (u8)(clk - 2);  	if ((clk <= 2) || (N > max_N))  		return -EINVAL; @@ -641,7 +644,14 @@ int rtsx_pci_switch_clock(struct rtsx_pcr *pcr, unsigned int card_clock,  	/* Make sure that the SSC clock div_n is equal or greater than min_N */  	div = CLK_DIV_1;  	while ((N < min_N) && (div < max_div)) { -		N = (N + 2) * 2 - 2; +		if (pcr->ops->conv_clk_and_div_n) { +			int dbl_clk = pcr->ops->conv_clk_and_div_n(N, +					DIV_N_TO_CLK) * 2; +			N = (u8)pcr->ops->conv_clk_and_div_n(dbl_clk, +					CLK_TO_DIV_N); +		} else { +			N = (N + 2) * 2 - 2; +		}  		div++;  	}  	dev_dbg(&(pcr->pci->dev), "N = %d, div = %d\n", N, div); @@ -703,6 +713,15 @@ int rtsx_pci_card_power_off(struct rtsx_pcr *pcr, int card)  }  EXPORT_SYMBOL_GPL(rtsx_pci_card_power_off); +int rtsx_pci_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage) +{ +	if (pcr->ops->switch_output_voltage) +		return pcr->ops->switch_output_voltage(pcr, voltage); + +	return 0; +} +EXPORT_SYMBOL_GPL(rtsx_pci_switch_output_voltage); +  unsigned int rtsx_pci_card_exist(struct rtsx_pcr *pcr)  {  	unsigned int val; @@ -767,10 +786,10 @@ static void rtsx_pci_card_detect(struct work_struct *work)  	spin_unlock_irqrestore(&pcr->lock, flags); -	if (card_detect & SD_EXIST) +	if ((card_detect & SD_EXIST) && pcr->slots[RTSX_SD_CARD].card_event)  		pcr->slots[RTSX_SD_CARD].card_event(  				pcr->slots[RTSX_SD_CARD].p_dev); -	if (card_detect & MS_EXIST) +	if ((card_detect & MS_EXIST) && pcr->slots[RTSX_MS_CARD].card_event)  		pcr->slots[RTSX_MS_CARD].card_event(  				pcr->slots[RTSX_MS_CARD].p_dev);  } diff --git a/drivers/mfd/tc3589x.c b/drivers/mfd/tc3589x.c index a06d66b929b..ecc092c7f74 100644 --- a/drivers/mfd/tc3589x.c +++ b/drivers/mfd/tc3589x.c @@ -219,25 +219,18 @@ static void tc3589x_irq_unmap(struct irq_domain *d, unsigned int virq)  }  static struct irq_domain_ops tc3589x_irq_ops = { -        .map    = tc3589x_irq_map, +	.map    = tc3589x_irq_map,  	.unmap  = tc3589x_irq_unmap, -        .xlate  = irq_domain_xlate_twocell, +	.xlate  = irq_domain_xlate_twocell,  };  static int tc3589x_irq_init(struct tc3589x *tc3589x, struct device_node *np)  {  	int base = tc3589x->irq_base; -	if (base) { -		tc3589x->domain = irq_domain_add_legacy( -			NULL, TC3589x_NR_INTERNAL_IRQS, base, -			0, &tc3589x_irq_ops, tc3589x); -	} -	else { -		tc3589x->domain = irq_domain_add_linear( -			np, TC3589x_NR_INTERNAL_IRQS, -			&tc3589x_irq_ops, tc3589x); -	} +	tc3589x->domain = irq_domain_add_simple( +		np, TC3589x_NR_INTERNAL_IRQS, base, +		&tc3589x_irq_ops, tc3589x);  	if (!tc3589x->domain) {  		dev_err(tc3589x->dev, "Failed to create irqdomain\n"); diff --git a/drivers/mfd/twl4030-power.c b/drivers/mfd/twl4030-power.c index 4dae241e501..dd362c1078e 100644 --- a/drivers/mfd/twl4030-power.c +++ b/drivers/mfd/twl4030-power.c @@ -159,7 +159,7 @@ out:  static int twl4030_write_script(u8 address, struct twl4030_ins *script,  				       int len)  { -	int err; +	int err = -EINVAL;  	for (; len; len--, address++, script++) {  		if (len == 1) { diff --git a/drivers/mfd/vexpress-config.c b/drivers/mfd/vexpress-config.c index fae15d88075..3c1723aa622 100644 --- a/drivers/mfd/vexpress-config.c +++ b/drivers/mfd/vexpress-config.c @@ -67,6 +67,7 @@ struct vexpress_config_bridge *vexpress_config_bridge_register(  	return bridge;  } +EXPORT_SYMBOL(vexpress_config_bridge_register);  void vexpress_config_bridge_unregister(struct vexpress_config_bridge *bridge)  { @@ -83,6 +84,7 @@ void vexpress_config_bridge_unregister(struct vexpress_config_bridge *bridge)  	while (!list_empty(&__bridge.transactions))  		cpu_relax();  } +EXPORT_SYMBOL(vexpress_config_bridge_unregister);  struct vexpress_config_func { @@ -142,6 +144,7 @@ struct vexpress_config_func *__vexpress_config_func_get(struct device *dev,  	return func;  } +EXPORT_SYMBOL(__vexpress_config_func_get);  void vexpress_config_func_put(struct vexpress_config_func *func)  { @@ -149,7 +152,7 @@ void vexpress_config_func_put(struct vexpress_config_func *func)  	of_node_put(func->bridge->node);  	kfree(func);  } - +EXPORT_SYMBOL(vexpress_config_func_put);  struct vexpress_config_trans {  	struct vexpress_config_func *func; @@ -229,6 +232,7 @@ void vexpress_config_complete(struct vexpress_config_bridge *bridge,  	complete(&trans->completion);  } +EXPORT_SYMBOL(vexpress_config_complete);  int vexpress_config_wait(struct vexpress_config_trans *trans)  { @@ -236,7 +240,7 @@ int vexpress_config_wait(struct vexpress_config_trans *trans)  	return trans->status;  } - +EXPORT_SYMBOL(vexpress_config_wait);  int vexpress_config_read(struct vexpress_config_func *func, int offset,  		u32 *data) diff --git a/drivers/mfd/vexpress-sysreg.c b/drivers/mfd/vexpress-sysreg.c index e5d8f63b252..77048b18439 100644 --- a/drivers/mfd/vexpress-sysreg.c +++ b/drivers/mfd/vexpress-sysreg.c @@ -313,19 +313,11 @@ static void vexpress_sysreg_config_complete(unsigned long data)  } -void __init vexpress_sysreg_early_init(void __iomem *base) +void __init vexpress_sysreg_setup(struct device_node *node)  { -	struct device_node *node = of_find_compatible_node(NULL, NULL, -			"arm,vexpress-sysreg"); - -	if (node) -		base = of_iomap(node, 0); - -	if (WARN_ON(!base)) +	if (WARN_ON(!vexpress_sysreg_base))  		return; -	vexpress_sysreg_base = base; -  	if (readl(vexpress_sysreg_base + SYS_MISC) & SYS_MISC_MASTERSITE)  		vexpress_master_site = VEXPRESS_SITE_DB2;  	else @@ -336,9 +328,23 @@ void __init vexpress_sysreg_early_init(void __iomem *base)  	WARN_ON(!vexpress_sysreg_config_bridge);  } +void __init vexpress_sysreg_early_init(void __iomem *base) +{ +	vexpress_sysreg_base = base; +	vexpress_sysreg_setup(NULL); +} +  void __init vexpress_sysreg_of_early_init(void)  { -	vexpress_sysreg_early_init(NULL); +	struct device_node *node = of_find_compatible_node(NULL, NULL, +			"arm,vexpress-sysreg"); + +	if (node) { +		vexpress_sysreg_base = of_iomap(node, 0); +		vexpress_sysreg_setup(node); +	} else { +		pr_info("vexpress-sysreg: No Device Tree node found."); +	}  } @@ -426,9 +432,11 @@ static int vexpress_sysreg_probe(struct platform_device *pdev)  		return -EBUSY;  	} -	if (!vexpress_sysreg_base) +	if (!vexpress_sysreg_base) {  		vexpress_sysreg_base = devm_ioremap(&pdev->dev, res->start,  				resource_size(res)); +		vexpress_sysreg_setup(pdev->dev.of_node); +	}  	if (!vexpress_sysreg_base) {  		dev_err(&pdev->dev, "Failed to obtain base address!\n"); diff --git a/drivers/mfd/wm5102-tables.c b/drivers/mfd/wm5102-tables.c index 088872ab633..1133a64c2dc 100644 --- a/drivers/mfd/wm5102-tables.c +++ b/drivers/mfd/wm5102-tables.c @@ -1882,7 +1882,7 @@ static bool wm5102_volatile_register(struct device *dev, unsigned int reg)  	}  } -#define WM5102_MAX_REGISTER 0x1a8fff +#define WM5102_MAX_REGISTER 0x1a9800  const struct regmap_config wm5102_spi_regmap = {  	.reg_bits = 32, diff --git a/drivers/mmc/host/mvsdio.c b/drivers/mmc/host/mvsdio.c index de4c20b3936..f8dd3610294 100644 --- a/drivers/mmc/host/mvsdio.c +++ b/drivers/mmc/host/mvsdio.c @@ -50,8 +50,6 @@ struct mvsd_host {  	struct timer_list timer;  	struct mmc_host *mmc;  	struct device *dev; -	struct resource *res; -	int irq;  	struct clk *clk;  	int gpio_card_detect;  	int gpio_write_protect; @@ -718,10 +716,6 @@ static int __init mvsd_probe(struct platform_device *pdev)  	if (!r || irq < 0 || !mvsd_data)  		return -ENXIO; -	r = request_mem_region(r->start, SZ_1K, DRIVER_NAME); -	if (!r) -		return -EBUSY; -  	mmc = mmc_alloc_host(sizeof(struct mvsd_host), &pdev->dev);  	if (!mmc) {  		ret = -ENOMEM; @@ -731,8 +725,8 @@ static int __init mvsd_probe(struct platform_device *pdev)  	host = mmc_priv(mmc);  	host->mmc = mmc;  	host->dev = &pdev->dev; -	host->res = r;  	host->base_clock = mvsd_data->clock / 2; +	host->clk = ERR_PTR(-EINVAL);  	mmc->ops = &mvsd_ops; @@ -752,7 +746,7 @@ static int __init mvsd_probe(struct platform_device *pdev)  	spin_lock_init(&host->lock); -	host->base = ioremap(r->start, SZ_4K); +	host->base = devm_request_and_ioremap(&pdev->dev, r);  	if (!host->base) {  		ret = -ENOMEM;  		goto out; @@ -765,44 +759,45 @@ static int __init mvsd_probe(struct platform_device *pdev)  	mvsd_power_down(host); -	ret = request_irq(irq, mvsd_irq, 0, DRIVER_NAME, host); +	ret = devm_request_irq(&pdev->dev, irq, mvsd_irq, 0, DRIVER_NAME, host);  	if (ret) {  		pr_err("%s: cannot assign irq %d\n", DRIVER_NAME, irq);  		goto out; -	} else -		host->irq = irq; +	}  	/* Not all platforms can gate the clock, so it is not  	   an error if the clock does not exists. */ -	host->clk = clk_get(&pdev->dev, NULL); -	if (!IS_ERR(host->clk)) { +	host->clk = devm_clk_get(&pdev->dev, NULL); +	if (!IS_ERR(host->clk))  		clk_prepare_enable(host->clk); -	}  	if (mvsd_data->gpio_card_detect) { -		ret = gpio_request(mvsd_data->gpio_card_detect, -				   DRIVER_NAME " cd"); +		ret = devm_gpio_request_one(&pdev->dev, +					    mvsd_data->gpio_card_detect, +					    GPIOF_IN, DRIVER_NAME " cd");  		if (ret == 0) { -			gpio_direction_input(mvsd_data->gpio_card_detect);  			irq = gpio_to_irq(mvsd_data->gpio_card_detect); -			ret = request_irq(irq, mvsd_card_detect_irq, -					  IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING, -					  DRIVER_NAME " cd", host); +			ret = devm_request_irq(&pdev->dev, irq, +					       mvsd_card_detect_irq, +					       IRQ_TYPE_EDGE_RISING | +					       IRQ_TYPE_EDGE_FALLING, +					       DRIVER_NAME " cd", host);  			if (ret == 0)  				host->gpio_card_detect =  					mvsd_data->gpio_card_detect;  			else -				gpio_free(mvsd_data->gpio_card_detect); +				devm_gpio_free(&pdev->dev, +					       mvsd_data->gpio_card_detect);  		}  	}  	if (!host->gpio_card_detect)  		mmc->caps |= MMC_CAP_NEEDS_POLL;  	if (mvsd_data->gpio_write_protect) { -		ret = gpio_request(mvsd_data->gpio_write_protect, -				   DRIVER_NAME " wp"); +		ret = devm_gpio_request_one(&pdev->dev, +					    mvsd_data->gpio_write_protect, +					    GPIOF_IN, DRIVER_NAME " wp");  		if (ret == 0) { -			gpio_direction_input(mvsd_data->gpio_write_protect);  			host->gpio_write_protect =  				mvsd_data->gpio_write_protect;  		} @@ -824,26 +819,11 @@ static int __init mvsd_probe(struct platform_device *pdev)  	return 0;  out: -	if (host) { -		if (host->irq) -			free_irq(host->irq, host); -		if (host->gpio_card_detect) { -			free_irq(gpio_to_irq(host->gpio_card_detect), host); -			gpio_free(host->gpio_card_detect); -		} -		if (host->gpio_write_protect) -			gpio_free(host->gpio_write_protect); -		if (host->base) -			iounmap(host->base); -	} -	if (r) -		release_resource(r); -	if (mmc) -		if (!IS_ERR_OR_NULL(host->clk)) { +	if (mmc) { +		if (!IS_ERR(host->clk))  			clk_disable_unprepare(host->clk); -			clk_put(host->clk); -		}  		mmc_free_host(mmc); +	}  	return ret;  } @@ -852,28 +832,16 @@ static int __exit mvsd_remove(struct platform_device *pdev)  {  	struct mmc_host *mmc = platform_get_drvdata(pdev); -	if (mmc) { -		struct mvsd_host *host = mmc_priv(mmc); +	struct mvsd_host *host = mmc_priv(mmc); -		if (host->gpio_card_detect) { -			free_irq(gpio_to_irq(host->gpio_card_detect), host); -			gpio_free(host->gpio_card_detect); -		} -		mmc_remove_host(mmc); -		free_irq(host->irq, host); -		if (host->gpio_write_protect) -			gpio_free(host->gpio_write_protect); -		del_timer_sync(&host->timer); -		mvsd_power_down(host); -		iounmap(host->base); -		release_resource(host->res); +	mmc_remove_host(mmc); +	del_timer_sync(&host->timer); +	mvsd_power_down(host); + +	if (!IS_ERR(host->clk)) +		clk_disable_unprepare(host->clk); +	mmc_free_host(mmc); -		if (!IS_ERR(host->clk)) { -			clk_disable_unprepare(host->clk); -			clk_put(host->clk); -		} -		mmc_free_host(mmc); -	}  	platform_set_drvdata(pdev, NULL);  	return 0;  } diff --git a/drivers/mmc/host/rtsx_pci_sdmmc.c b/drivers/mmc/host/rtsx_pci_sdmmc.c index 571915dfb21..f74b5adca64 100644 --- a/drivers/mmc/host/rtsx_pci_sdmmc.c +++ b/drivers/mmc/host/rtsx_pci_sdmmc.c @@ -1060,26 +1060,6 @@ static int sd_wait_voltage_stable_2(struct realtek_pci_sdmmc *host)  	return 0;  } -static int sd_change_bank_voltage(struct realtek_pci_sdmmc *host, u8 voltage) -{ -	struct rtsx_pcr *pcr = host->pcr; -	int err; - -	if (voltage == SD_IO_3V3) { -		err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4FC0 | 0x24); -		if (err < 0) -			return err; -	} else if (voltage == SD_IO_1V8) { -		err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4C40 | 0x24); -		if (err < 0) -			return err; -	} else { -		return -EINVAL; -	} - -	return 0; -} -  static int sdmmc_switch_voltage(struct mmc_host *mmc, struct mmc_ios *ios)  {  	struct realtek_pci_sdmmc *host = mmc_priv(mmc); @@ -1098,11 +1078,11 @@ static int sdmmc_switch_voltage(struct mmc_host *mmc, struct mmc_ios *ios)  	rtsx_pci_start_run(pcr);  	if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_330) -		voltage = SD_IO_3V3; +		voltage = OUTPUT_3V3;  	else -		voltage = SD_IO_1V8; +		voltage = OUTPUT_1V8; -	if (voltage == SD_IO_1V8) { +	if (voltage == OUTPUT_1V8) {  		err = rtsx_pci_write_register(pcr,  				SD30_DRIVE_SEL, 0x07, DRIVER_TYPE_B);  		if (err < 0) @@ -1113,11 +1093,11 @@ static int sdmmc_switch_voltage(struct mmc_host *mmc, struct mmc_ios *ios)  			goto out;  	} -	err = sd_change_bank_voltage(host, voltage); +	err = rtsx_pci_switch_output_voltage(pcr, voltage);  	if (err < 0)  		goto out; -	if (voltage == SD_IO_1V8) { +	if (voltage == OUTPUT_1V8) {  		err = sd_wait_voltage_stable_2(host);  		if (err < 0)  			goto out; diff --git a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig index 27f80cd8aef..46dcb54c32e 100644 --- a/drivers/mtd/devices/Kconfig +++ b/drivers/mtd/devices/Kconfig @@ -272,6 +272,7 @@ config MTD_DOCG3  	tristate "M-Systems Disk-On-Chip G3"  	select BCH  	select BCH_CONST_PARAMS +	select BITREVERSE  	---help---  	  This provides an MTD device driver for the M-Systems DiskOnChip  	  G3 devices. diff --git a/drivers/mtd/maps/physmap_of.c b/drivers/mtd/maps/physmap_of.c index 67cc73c18dd..7901d72c924 100644 --- a/drivers/mtd/maps/physmap_of.c +++ b/drivers/mtd/maps/physmap_of.c @@ -170,7 +170,7 @@ static int of_flash_probe(struct platform_device *dev)  	resource_size_t res_size;  	struct mtd_part_parser_data ppdata;  	bool map_indirect; -	const char *mtd_name; +	const char *mtd_name = NULL;  	match = of_match_device(of_flash_match, &dev->dev);  	if (!match) diff --git a/drivers/mtd/nand/bcm47xxnflash/ops_bcm4706.c b/drivers/mtd/nand/bcm47xxnflash/ops_bcm4706.c index 86c9a79b89b..595de4012e7 100644 --- a/drivers/mtd/nand/bcm47xxnflash/ops_bcm4706.c +++ b/drivers/mtd/nand/bcm47xxnflash/ops_bcm4706.c @@ -17,8 +17,8 @@  #include "bcm47xxnflash.h"  /* Broadcom uses 1'000'000 but it seems to be too many. Tests on WNDR4500 has - * shown 164 retries as maxiumum. */ -#define NFLASH_READY_RETRIES		1000 + * shown ~1000 retries as maxiumum. */ +#define NFLASH_READY_RETRIES		10000  #define NFLASH_SECTOR_SIZE		512 diff --git a/drivers/mtd/nand/davinci_nand.c b/drivers/mtd/nand/davinci_nand.c index 3502606f648..feae55c7b88 100644 --- a/drivers/mtd/nand/davinci_nand.c +++ b/drivers/mtd/nand/davinci_nand.c @@ -523,7 +523,7 @@ static struct nand_ecclayout hwecc4_2048 __initconst = {  static const struct of_device_id davinci_nand_of_match[] = {  	{.compatible = "ti,davinci-nand", },  	{}, -} +};  MODULE_DEVICE_TABLE(of, davinci_nand_of_match);  static struct davinci_nand_pdata diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 8323ac991ad..3766682a028 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -2857,8 +2857,11 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip,  	int i;  	int val; -	/* ONFI need to be probed in 8 bits mode */ -	WARN_ON(chip->options & NAND_BUSWIDTH_16); +	/* ONFI need to be probed in 8 bits mode, and 16 bits should be selected with NAND_BUSWIDTH_AUTO */ +	if (chip->options & NAND_BUSWIDTH_16) { +		pr_err("Trying ONFI probe in 16 bits mode, aborting !\n"); +		return 0; +	}  	/* Try ONFI for unknown chip or LP */  	chip->cmdfunc(mtd, NAND_CMD_READID, 0x20, -1);  	if (chip->read_byte(mtd) != 'O' || chip->read_byte(mtd) != 'N' || diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c index 1877ed7ca08..1c9e09fbdff 100644 --- a/drivers/net/bonding/bond_sysfs.c +++ b/drivers/net/bonding/bond_sysfs.c @@ -1053,6 +1053,7 @@ static ssize_t bonding_store_primary(struct device *d,  		pr_info("%s: Setting primary slave to None.\n",  			bond->dev->name);  		bond->primary_slave = NULL; +		memset(bond->params.primary, 0, sizeof(bond->params.primary));  		bond_select_active_slave(bond);  		goto out;  	} diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c index 5233b8f58d7..2282b1ae976 100644 --- a/drivers/net/can/c_can/c_can.c +++ b/drivers/net/can/c_can/c_can.c @@ -488,8 +488,12 @@ static void c_can_setup_receive_object(struct net_device *dev, int iface,  	priv->write_reg(priv, C_CAN_IFACE(MASK1_REG, iface),  			IFX_WRITE_LOW_16BIT(mask)); + +	/* According to C_CAN documentation, the reserved bit +	 * in IFx_MASK2 register is fixed 1 +	 */  	priv->write_reg(priv, C_CAN_IFACE(MASK2_REG, iface), -			IFX_WRITE_HIGH_16BIT(mask)); +			IFX_WRITE_HIGH_16BIT(mask) | BIT(13));  	priv->write_reg(priv, C_CAN_IFACE(ARB1_REG, iface),  			IFX_WRITE_LOW_16BIT(id)); @@ -960,7 +964,7 @@ static int c_can_handle_bus_err(struct net_device *dev,  		break;  	case LEC_ACK_ERROR:  		netdev_dbg(dev, "ack error\n"); -		cf->data[2] |= (CAN_ERR_PROT_LOC_ACK | +		cf->data[3] |= (CAN_ERR_PROT_LOC_ACK |  				CAN_ERR_PROT_LOC_ACK_DEL);  		break;  	case LEC_BIT1_ERROR: @@ -973,7 +977,7 @@ static int c_can_handle_bus_err(struct net_device *dev,  		break;  	case LEC_CRC_ERROR:  		netdev_dbg(dev, "CRC error\n"); -		cf->data[2] |= (CAN_ERR_PROT_LOC_CRC_SEQ | +		cf->data[3] |= (CAN_ERR_PROT_LOC_CRC_SEQ |  				CAN_ERR_PROT_LOC_CRC_DEL);  		break;  	default: diff --git a/drivers/net/can/pch_can.c b/drivers/net/can/pch_can.c index 7d1748575b1..5c314a96197 100644 --- a/drivers/net/can/pch_can.c +++ b/drivers/net/can/pch_can.c @@ -560,7 +560,7 @@ static void pch_can_error(struct net_device *ndev, u32 status)  		stats->rx_errors++;  		break;  	case PCH_CRC_ERR: -		cf->data[2] |= CAN_ERR_PROT_LOC_CRC_SEQ | +		cf->data[3] |= CAN_ERR_PROT_LOC_CRC_SEQ |  			       CAN_ERR_PROT_LOC_CRC_DEL;  		priv->can.can_stats.bus_error++;  		stats->rx_errors++; diff --git a/drivers/net/can/ti_hecc.c b/drivers/net/can/ti_hecc.c index f898c636372..300581b24ff 100644 --- a/drivers/net/can/ti_hecc.c +++ b/drivers/net/can/ti_hecc.c @@ -746,12 +746,12 @@ static int ti_hecc_error(struct net_device *ndev, int int_status,  		}  		if (err_status & HECC_CANES_CRCE) {  			hecc_set_bit(priv, HECC_CANES, HECC_CANES_CRCE); -			cf->data[2] |= CAN_ERR_PROT_LOC_CRC_SEQ | +			cf->data[3] |= CAN_ERR_PROT_LOC_CRC_SEQ |  					CAN_ERR_PROT_LOC_CRC_DEL;  		}  		if (err_status & HECC_CANES_ACKE) {  			hecc_set_bit(priv, HECC_CANES, HECC_CANES_ACKE); -			cf->data[2] |= CAN_ERR_PROT_LOC_ACK | +			cf->data[3] |= CAN_ERR_PROT_LOC_ACK |  					CAN_ERR_PROT_LOC_ACK_DEL;  		}  	} diff --git a/drivers/net/ethernet/3com/3c574_cs.c b/drivers/net/ethernet/3com/3c574_cs.c index 66df9363808..ffd8de28a76 100644 --- a/drivers/net/ethernet/3com/3c574_cs.c +++ b/drivers/net/ethernet/3com/3c574_cs.c @@ -432,7 +432,7 @@ static int tc574_config(struct pcmcia_device *link)  	netdev_info(dev, "%s at io %#3lx, irq %d, hw_addr %pM\n",  		    cardname, dev->base_addr, dev->irq, dev->dev_addr);  	netdev_info(dev, " %dK FIFO split %s Rx:Tx, %sMII interface.\n", -		    8 << config & Ram_size, +		    8 << (config & Ram_size),  		    ram_split[(config & Ram_split) >> Ram_split_shift],  		    config & Autoselect ? "autoselect " : ""); diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c index 56d3f697e0c..0035c01660b 100644 --- a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c +++ b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c @@ -21,7 +21,7 @@  #include "atl1c.h" -#define ATL1C_DRV_VERSION "1.0.1.0-NAPI" +#define ATL1C_DRV_VERSION "1.0.1.1-NAPI"  char atl1c_driver_name[] = "atl1c";  char atl1c_driver_version[] = ATL1C_DRV_VERSION; @@ -1652,6 +1652,7 @@ static int atl1c_alloc_rx_buffer(struct atl1c_adapter *adapter)  	u16 num_alloc = 0;  	u16 rfd_next_to_use, next_next;  	struct atl1c_rx_free_desc *rfd_desc; +	dma_addr_t mapping;  	next_next = rfd_next_to_use = rfd_ring->next_to_use;  	if (++next_next == rfd_ring->count) @@ -1678,9 +1679,18 @@ static int atl1c_alloc_rx_buffer(struct atl1c_adapter *adapter)  		ATL1C_SET_BUFFER_STATE(buffer_info, ATL1C_BUFFER_BUSY);  		buffer_info->skb = skb;  		buffer_info->length = adapter->rx_buffer_len; -		buffer_info->dma = pci_map_single(pdev, vir_addr, +		mapping = pci_map_single(pdev, vir_addr,  						buffer_info->length,  						PCI_DMA_FROMDEVICE); +		if (unlikely(pci_dma_mapping_error(pdev, mapping))) { +			dev_kfree_skb(skb); +			buffer_info->skb = NULL; +			buffer_info->length = 0; +			ATL1C_SET_BUFFER_STATE(buffer_info, ATL1C_BUFFER_FREE); +			netif_warn(adapter, rx_err, adapter->netdev, "RX pci_map_single failed"); +			break; +		} +		buffer_info->dma = mapping;  		ATL1C_SET_PCIMAP_TYPE(buffer_info, ATL1C_PCIMAP_SINGLE,  			ATL1C_PCIMAP_FROMDEVICE);  		rfd_desc->buffer_addr = cpu_to_le64(buffer_info->dma); @@ -2015,7 +2025,29 @@ check_sum:  	return 0;  } -static void atl1c_tx_map(struct atl1c_adapter *adapter, +static void atl1c_tx_rollback(struct atl1c_adapter *adpt, +			      struct atl1c_tpd_desc *first_tpd, +			      enum atl1c_trans_queue type) +{ +	struct atl1c_tpd_ring *tpd_ring = &adpt->tpd_ring[type]; +	struct atl1c_buffer *buffer_info; +	struct atl1c_tpd_desc *tpd; +	u16 first_index, index; + +	first_index = first_tpd - (struct atl1c_tpd_desc *)tpd_ring->desc; +	index = first_index; +	while (index != tpd_ring->next_to_use) { +		tpd = ATL1C_TPD_DESC(tpd_ring, index); +		buffer_info = &tpd_ring->buffer_info[index]; +		atl1c_clean_buffer(adpt->pdev, buffer_info, 0); +		memset(tpd, 0, sizeof(struct atl1c_tpd_desc)); +		if (++index == tpd_ring->count) +			index = 0; +	} +	tpd_ring->next_to_use = first_index; +} + +static int atl1c_tx_map(struct atl1c_adapter *adapter,  		      struct sk_buff *skb, struct atl1c_tpd_desc *tpd,  			enum atl1c_trans_queue type)  { @@ -2040,7 +2072,10 @@ static void atl1c_tx_map(struct atl1c_adapter *adapter,  		buffer_info->length = map_len;  		buffer_info->dma = pci_map_single(adapter->pdev,  					skb->data, hdr_len, PCI_DMA_TODEVICE); -		ATL1C_SET_BUFFER_STATE(buffer_info, ATL1C_BUFFER_BUSY); +		if (unlikely(pci_dma_mapping_error(adapter->pdev, +						   buffer_info->dma))) +			goto err_dma; +  		ATL1C_SET_PCIMAP_TYPE(buffer_info, ATL1C_PCIMAP_SINGLE,  			ATL1C_PCIMAP_TODEVICE);  		mapped_len += map_len; @@ -2062,6 +2097,10 @@ static void atl1c_tx_map(struct atl1c_adapter *adapter,  		buffer_info->dma =  			pci_map_single(adapter->pdev, skb->data + mapped_len,  					buffer_info->length, PCI_DMA_TODEVICE); +		if (unlikely(pci_dma_mapping_error(adapter->pdev, +						   buffer_info->dma))) +			goto err_dma; +  		ATL1C_SET_BUFFER_STATE(buffer_info, ATL1C_BUFFER_BUSY);  		ATL1C_SET_PCIMAP_TYPE(buffer_info, ATL1C_PCIMAP_SINGLE,  			ATL1C_PCIMAP_TODEVICE); @@ -2083,6 +2122,9 @@ static void atl1c_tx_map(struct atl1c_adapter *adapter,  						    frag, 0,  						    buffer_info->length,  						    DMA_TO_DEVICE); +		if (dma_mapping_error(&adapter->pdev->dev, buffer_info->dma)) +			goto err_dma; +  		ATL1C_SET_BUFFER_STATE(buffer_info, ATL1C_BUFFER_BUSY);  		ATL1C_SET_PCIMAP_TYPE(buffer_info, ATL1C_PCIMAP_PAGE,  			ATL1C_PCIMAP_TODEVICE); @@ -2095,6 +2137,13 @@ static void atl1c_tx_map(struct atl1c_adapter *adapter,  	/* The last buffer info contain the skb address,  	   so it will be free after unmap */  	buffer_info->skb = skb; + +	return 0; + +err_dma: +	buffer_info->dma = 0; +	buffer_info->length = 0; +	return -1;  }  static void atl1c_tx_queue(struct atl1c_adapter *adapter, struct sk_buff *skb, @@ -2157,10 +2206,18 @@ static netdev_tx_t atl1c_xmit_frame(struct sk_buff *skb,  	if (skb_network_offset(skb) != ETH_HLEN)  		tpd->word1 |= 1 << TPD_ETH_TYPE_SHIFT; /* Ethernet frame */ -	atl1c_tx_map(adapter, skb, tpd, type); -	atl1c_tx_queue(adapter, skb, tpd, type); +	if (atl1c_tx_map(adapter, skb, tpd, type) < 0) { +		netif_info(adapter, tx_done, adapter->netdev, +			   "tx-skb droppted due to dma error\n"); +		/* roll back tpd/buffer */ +		atl1c_tx_rollback(adapter, tpd, type); +		spin_unlock_irqrestore(&adapter->tx_lock, flags); +		dev_kfree_skb(skb); +	} else { +		atl1c_tx_queue(adapter, skb, tpd, type); +		spin_unlock_irqrestore(&adapter->tx_lock, flags); +	} -	spin_unlock_irqrestore(&adapter->tx_lock, flags);  	return NETDEV_TX_OK;  } diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index f771ddfba64..a5edac8df67 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c @@ -504,13 +504,11 @@ static int bnx2x_fill_frag_skb(struct bnx2x *bp, struct bnx2x_fastpath *fp,  		skb_shinfo(skb)->gso_size = bnx2x_set_lro_mss(bp,  					tpa_info->parsing_flags, len_on_bd); -		/* set for GRO */ -		if (fp->mode == TPA_MODE_GRO) -			skb_shinfo(skb)->gso_type = -			    (GET_FLAG(tpa_info->parsing_flags, -				      PARSING_FLAGS_OVER_ETHERNET_PROTOCOL) == -						PRS_FLAG_OVERETH_IPV6) ? -				SKB_GSO_TCPV6 : SKB_GSO_TCPV4; +		skb_shinfo(skb)->gso_type = +			(GET_FLAG(tpa_info->parsing_flags, +				  PARSING_FLAGS_OVER_ETHERNET_PROTOCOL) == +			 PRS_FLAG_OVERETH_IPV6) ? +			SKB_GSO_TCPV6 : SKB_GSO_TCPV4;  	} diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index 78ea90c40e1..bdb086934cd 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c @@ -1283,14 +1283,26 @@ static int tg3_phy_auxctl_write(struct tg3 *tp, int reg, u32 set)  	return tg3_writephy(tp, MII_TG3_AUX_CTRL, set | reg);  } -#define TG3_PHY_AUXCTL_SMDSP_ENABLE(tp) \ -	tg3_phy_auxctl_write((tp), MII_TG3_AUXCTL_SHDWSEL_AUXCTL, \ -			     MII_TG3_AUXCTL_ACTL_SMDSP_ENA | \ -			     MII_TG3_AUXCTL_ACTL_TX_6DB) +static int tg3_phy_toggle_auxctl_smdsp(struct tg3 *tp, bool enable) +{ +	u32 val; +	int err; -#define TG3_PHY_AUXCTL_SMDSP_DISABLE(tp) \ -	tg3_phy_auxctl_write((tp), MII_TG3_AUXCTL_SHDWSEL_AUXCTL, \ -			     MII_TG3_AUXCTL_ACTL_TX_6DB); +	err = tg3_phy_auxctl_read(tp, MII_TG3_AUXCTL_SHDWSEL_AUXCTL, &val); + +	if (err) +		return err; +	if (enable) + +		val |= MII_TG3_AUXCTL_ACTL_SMDSP_ENA; +	else +		val &= ~MII_TG3_AUXCTL_ACTL_SMDSP_ENA; + +	err = tg3_phy_auxctl_write((tp), MII_TG3_AUXCTL_SHDWSEL_AUXCTL, +				   val | MII_TG3_AUXCTL_ACTL_TX_6DB); + +	return err; +}  static int tg3_bmcr_reset(struct tg3 *tp)  { @@ -2223,7 +2235,7 @@ static void tg3_phy_apply_otp(struct tg3 *tp)  	otp = tp->phy_otp; -	if (TG3_PHY_AUXCTL_SMDSP_ENABLE(tp)) +	if (tg3_phy_toggle_auxctl_smdsp(tp, true))  		return;  	phy = ((otp & TG3_OTP_AGCTGT_MASK) >> TG3_OTP_AGCTGT_SHIFT); @@ -2248,7 +2260,7 @@ static void tg3_phy_apply_otp(struct tg3 *tp)  	      ((otp & TG3_OTP_RCOFF_MASK) >> TG3_OTP_RCOFF_SHIFT);  	tg3_phydsp_write(tp, MII_TG3_DSP_EXP97, phy); -	TG3_PHY_AUXCTL_SMDSP_DISABLE(tp); +	tg3_phy_toggle_auxctl_smdsp(tp, false);  }  static void tg3_phy_eee_adjust(struct tg3 *tp, u32 current_link_up) @@ -2284,9 +2296,9 @@ static void tg3_phy_eee_adjust(struct tg3 *tp, u32 current_link_up)  	if (!tp->setlpicnt) {  		if (current_link_up == 1 && -		   !TG3_PHY_AUXCTL_SMDSP_ENABLE(tp)) { +		   !tg3_phy_toggle_auxctl_smdsp(tp, true)) {  			tg3_phydsp_write(tp, MII_TG3_DSP_TAP26, 0x0000); -			TG3_PHY_AUXCTL_SMDSP_DISABLE(tp); +			tg3_phy_toggle_auxctl_smdsp(tp, false);  		}  		val = tr32(TG3_CPMU_EEE_MODE); @@ -2302,11 +2314,11 @@ static void tg3_phy_eee_enable(struct tg3 *tp)  	    (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||  	     GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||  	     tg3_flag(tp, 57765_CLASS)) && -	    !TG3_PHY_AUXCTL_SMDSP_ENABLE(tp)) { +	    !tg3_phy_toggle_auxctl_smdsp(tp, true)) {  		val = MII_TG3_DSP_TAP26_ALNOKO |  		      MII_TG3_DSP_TAP26_RMRXSTO;  		tg3_phydsp_write(tp, MII_TG3_DSP_TAP26, val); -		TG3_PHY_AUXCTL_SMDSP_DISABLE(tp); +		tg3_phy_toggle_auxctl_smdsp(tp, false);  	}  	val = tr32(TG3_CPMU_EEE_MODE); @@ -2450,7 +2462,7 @@ static int tg3_phy_reset_5703_4_5(struct tg3 *tp)  		tg3_writephy(tp, MII_CTRL1000,  			     CTL1000_AS_MASTER | CTL1000_ENABLE_MASTER); -		err = TG3_PHY_AUXCTL_SMDSP_ENABLE(tp); +		err = tg3_phy_toggle_auxctl_smdsp(tp, true);  		if (err)  			return err; @@ -2471,7 +2483,7 @@ static int tg3_phy_reset_5703_4_5(struct tg3 *tp)  	tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x8200);  	tg3_writephy(tp, MII_TG3_DSP_CONTROL, 0x0000); -	TG3_PHY_AUXCTL_SMDSP_DISABLE(tp); +	tg3_phy_toggle_auxctl_smdsp(tp, false);  	tg3_writephy(tp, MII_CTRL1000, phy9_orig); @@ -2572,10 +2584,10 @@ static int tg3_phy_reset(struct tg3 *tp)  out:  	if ((tp->phy_flags & TG3_PHYFLG_ADC_BUG) && -	    !TG3_PHY_AUXCTL_SMDSP_ENABLE(tp)) { +	    !tg3_phy_toggle_auxctl_smdsp(tp, true)) {  		tg3_phydsp_write(tp, 0x201f, 0x2aaa);  		tg3_phydsp_write(tp, 0x000a, 0x0323); -		TG3_PHY_AUXCTL_SMDSP_DISABLE(tp); +		tg3_phy_toggle_auxctl_smdsp(tp, false);  	}  	if (tp->phy_flags & TG3_PHYFLG_5704_A0_BUG) { @@ -2584,14 +2596,14 @@ out:  	}  	if (tp->phy_flags & TG3_PHYFLG_BER_BUG) { -		if (!TG3_PHY_AUXCTL_SMDSP_ENABLE(tp)) { +		if (!tg3_phy_toggle_auxctl_smdsp(tp, true)) {  			tg3_phydsp_write(tp, 0x000a, 0x310b);  			tg3_phydsp_write(tp, 0x201f, 0x9506);  			tg3_phydsp_write(tp, 0x401f, 0x14e2); -			TG3_PHY_AUXCTL_SMDSP_DISABLE(tp); +			tg3_phy_toggle_auxctl_smdsp(tp, false);  		}  	} else if (tp->phy_flags & TG3_PHYFLG_JITTER_BUG) { -		if (!TG3_PHY_AUXCTL_SMDSP_ENABLE(tp)) { +		if (!tg3_phy_toggle_auxctl_smdsp(tp, true)) {  			tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x000a);  			if (tp->phy_flags & TG3_PHYFLG_ADJUST_TRIM) {  				tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x110b); @@ -2600,7 +2612,7 @@ out:  			} else  				tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x010b); -			TG3_PHY_AUXCTL_SMDSP_DISABLE(tp); +			tg3_phy_toggle_auxctl_smdsp(tp, false);  		}  	} @@ -4009,7 +4021,7 @@ static int tg3_phy_autoneg_cfg(struct tg3 *tp, u32 advertise, u32 flowctrl)  	tw32(TG3_CPMU_EEE_MODE,  	     tr32(TG3_CPMU_EEE_MODE) & ~TG3_CPMU_EEEMD_LPI_ENABLE); -	err = TG3_PHY_AUXCTL_SMDSP_ENABLE(tp); +	err = tg3_phy_toggle_auxctl_smdsp(tp, true);  	if (!err) {  		u32 err2; @@ -4042,7 +4054,7 @@ static int tg3_phy_autoneg_cfg(struct tg3 *tp, u32 advertise, u32 flowctrl)  						 MII_TG3_DSP_CH34TP2_HIBW01);  		} -		err2 = TG3_PHY_AUXCTL_SMDSP_DISABLE(tp); +		err2 = tg3_phy_toggle_auxctl_smdsp(tp, false);  		if (!err)  			err = err2;  	} @@ -6950,6 +6962,9 @@ static void tg3_poll_controller(struct net_device *dev)  	int i;  	struct tg3 *tp = netdev_priv(dev); +	if (tg3_irq_sync(tp)) +		return; +  	for (i = 0; i < tp->irq_cnt; i++)  		tg3_interrupt(tp->napi[i].irq_vec, &tp->napi[i]);  } @@ -16367,6 +16382,7 @@ static int tg3_init_one(struct pci_dev *pdev,  	tp->pm_cap = pm_cap;  	tp->rx_mode = TG3_DEF_RX_MODE;  	tp->tx_mode = TG3_DEF_TX_MODE; +	tp->irq_sync = 1;  	if (tg3_debug > 0)  		tp->msg_enable = tg3_debug; diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c index a9b0830fb39..b9d4bb9530e 100644 --- a/drivers/net/ethernet/cadence/macb.c +++ b/drivers/net/ethernet/cadence/macb.c @@ -693,6 +693,11 @@ static int macb_poll(struct napi_struct *napi, int budget)  		 * get notified when new packets arrive.  		 */  		macb_writel(bp, IER, MACB_RX_INT_FLAGS); + +		/* Packets received while interrupts were disabled */ +		status = macb_readl(bp, RSR); +		if (unlikely(status)) +			napi_reschedule(napi);  	}  	/* TODO: Handle errors */ diff --git a/drivers/net/ethernet/calxeda/xgmac.c b/drivers/net/ethernet/calxeda/xgmac.c index b407043ce9b..f7f02900f65 100644 --- a/drivers/net/ethernet/calxeda/xgmac.c +++ b/drivers/net/ethernet/calxeda/xgmac.c @@ -548,6 +548,10 @@ static int desc_get_rx_status(struct xgmac_priv *priv, struct xgmac_dma_desc *p)  		return -1;  	} +	/* All frames should fit into a single buffer */ +	if (!(status & RXDESC_FIRST_SEG) || !(status & RXDESC_LAST_SEG)) +		return -1; +  	/* Check if packet has checksum already */  	if ((status & RXDESC_FRAME_TYPE) && (status & RXDESC_EXT_STATUS) &&  		!(ext_status & RXDESC_IP_PAYLOAD_MASK)) diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index f0718e1a836..c306df7d456 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -1994,9 +1994,20 @@ static int set_coalesce(struct net_device *dev, struct ethtool_coalesce *c)  {  	const struct port_info *pi = netdev_priv(dev);  	struct adapter *adap = pi->adapter; +	struct sge_rspq *q; +	int i; +	int r = 0; -	return set_rxq_intr_params(adap, &adap->sge.ethrxq[pi->first_qset].rspq, -			c->rx_coalesce_usecs, c->rx_max_coalesced_frames); +	for (i = pi->first_qset; i < pi->first_qset + pi->nqsets; i++) { +		q = &adap->sge.ethrxq[i].rspq; +		r = set_rxq_intr_params(adap, q, c->rx_coalesce_usecs, +			c->rx_max_coalesced_frames); +		if (r) { +			dev_err(&dev->dev, "failed to set coalesce %d\n", r); +			break; +		} +	} +	return r;  }  static int get_coalesce(struct net_device *dev, struct ethtool_coalesce *c) diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h index 4eba17b83ba..f1b3df167ff 100644 --- a/drivers/net/ethernet/emulex/benet/be.h +++ b/drivers/net/ethernet/emulex/benet/be.h @@ -36,13 +36,13 @@  #define DRV_VER			"4.4.161.0u"  #define DRV_NAME		"be2net" -#define BE_NAME			"ServerEngines BladeEngine2 10Gbps NIC" -#define BE3_NAME		"ServerEngines BladeEngine3 10Gbps NIC" -#define OC_NAME			"Emulex OneConnect 10Gbps NIC" +#define BE_NAME			"Emulex BladeEngine2" +#define BE3_NAME		"Emulex BladeEngine3" +#define OC_NAME			"Emulex OneConnect"  #define OC_NAME_BE		OC_NAME	"(be3)"  #define OC_NAME_LANCER		OC_NAME "(Lancer)"  #define OC_NAME_SH		OC_NAME "(Skyhawk)" -#define DRV_DESC		"ServerEngines BladeEngine 10Gbps NIC Driver" +#define DRV_DESC		"Emulex OneConnect 10Gbps NIC Driver"  #define BE_VENDOR_ID 		0x19a2  #define EMULEX_VENDOR_ID	0x10df diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index 5c995700e53..4d6f3c54427 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -25,7 +25,7 @@  MODULE_VERSION(DRV_VER);  MODULE_DEVICE_TABLE(pci, be_dev_ids);  MODULE_DESCRIPTION(DRV_DESC " " DRV_VER); -MODULE_AUTHOR("ServerEngines Corporation"); +MODULE_AUTHOR("Emulex Corporation");  MODULE_LICENSE("GPL");  static unsigned int num_vfs; diff --git a/drivers/net/ethernet/intel/e1000e/defines.h b/drivers/net/ethernet/intel/e1000e/defines.h index 02a12b69555..4dab6fc265a 100644 --- a/drivers/net/ethernet/intel/e1000e/defines.h +++ b/drivers/net/ethernet/intel/e1000e/defines.h @@ -232,6 +232,7 @@  #define E1000_CTRL_FRCDPX   0x00001000  /* Force Duplex */  #define E1000_CTRL_LANPHYPC_OVERRIDE 0x00010000 /* SW control of LANPHYPC */  #define E1000_CTRL_LANPHYPC_VALUE    0x00020000 /* SW value of LANPHYPC */ +#define E1000_CTRL_MEHE     0x00080000  /* Memory Error Handling Enable */  #define E1000_CTRL_SWDPIN0  0x00040000  /* SWDPIN 0 value */  #define E1000_CTRL_SWDPIN1  0x00080000  /* SWDPIN 1 value */  #define E1000_CTRL_SWDPIO0  0x00400000  /* SWDPIN 0 Input or output */ @@ -389,6 +390,12 @@  #define E1000_PBS_16K E1000_PBA_16K +/* Uncorrectable/correctable ECC Error counts and enable bits */ +#define E1000_PBECCSTS_CORR_ERR_CNT_MASK	0x000000FF +#define E1000_PBECCSTS_UNCORR_ERR_CNT_MASK	0x0000FF00 +#define E1000_PBECCSTS_UNCORR_ERR_CNT_SHIFT	8 +#define E1000_PBECCSTS_ECC_ENABLE		0x00010000 +  #define IFS_MAX       80  #define IFS_MIN       40  #define IFS_RATIO     4 @@ -408,6 +415,7 @@  #define E1000_ICR_RXSEQ         0x00000008 /* Rx sequence error */  #define E1000_ICR_RXDMT0        0x00000010 /* Rx desc min. threshold (0) */  #define E1000_ICR_RXT0          0x00000080 /* Rx timer intr (ring 0) */ +#define E1000_ICR_ECCER         0x00400000 /* Uncorrectable ECC Error */  #define E1000_ICR_INT_ASSERTED  0x80000000 /* If this bit asserted, the driver should claim the interrupt */  #define E1000_ICR_RXQ0          0x00100000 /* Rx Queue 0 Interrupt */  #define E1000_ICR_RXQ1          0x00200000 /* Rx Queue 1 Interrupt */ @@ -443,6 +451,7 @@  #define E1000_IMS_RXSEQ     E1000_ICR_RXSEQ     /* Rx sequence error */  #define E1000_IMS_RXDMT0    E1000_ICR_RXDMT0    /* Rx desc min. threshold */  #define E1000_IMS_RXT0      E1000_ICR_RXT0      /* Rx timer intr */ +#define E1000_IMS_ECCER     E1000_ICR_ECCER     /* Uncorrectable ECC Error */  #define E1000_IMS_RXQ0      E1000_ICR_RXQ0      /* Rx Queue 0 Interrupt */  #define E1000_IMS_RXQ1      E1000_ICR_RXQ1      /* Rx Queue 1 Interrupt */  #define E1000_IMS_TXQ0      E1000_ICR_TXQ0      /* Tx Queue 0 Interrupt */ diff --git a/drivers/net/ethernet/intel/e1000e/e1000.h b/drivers/net/ethernet/intel/e1000e/e1000.h index 6782a2eea1b..7e95f221d60 100644 --- a/drivers/net/ethernet/intel/e1000e/e1000.h +++ b/drivers/net/ethernet/intel/e1000e/e1000.h @@ -309,6 +309,8 @@ struct e1000_adapter {  	struct napi_struct napi; +	unsigned int uncorr_errors;	/* uncorrectable ECC errors */ +	unsigned int corr_errors;	/* correctable ECC errors */  	unsigned int restart_queue;  	u32 txd_cmd; diff --git a/drivers/net/ethernet/intel/e1000e/ethtool.c b/drivers/net/ethernet/intel/e1000e/ethtool.c index f95bc6ee1c2..fd4772a2691 100644 --- a/drivers/net/ethernet/intel/e1000e/ethtool.c +++ b/drivers/net/ethernet/intel/e1000e/ethtool.c @@ -108,6 +108,8 @@ static const struct e1000_stats e1000_gstrings_stats[] = {  	E1000_STAT("dropped_smbus", stats.mgpdc),  	E1000_STAT("rx_dma_failed", rx_dma_failed),  	E1000_STAT("tx_dma_failed", tx_dma_failed), +	E1000_STAT("uncorr_ecc_errors", uncorr_errors), +	E1000_STAT("corr_ecc_errors", corr_errors),  };  #define E1000_GLOBAL_STATS_LEN	ARRAY_SIZE(e1000_gstrings_stats) diff --git a/drivers/net/ethernet/intel/e1000e/hw.h b/drivers/net/ethernet/intel/e1000e/hw.h index cf217777586..b88676ff3d8 100644 --- a/drivers/net/ethernet/intel/e1000e/hw.h +++ b/drivers/net/ethernet/intel/e1000e/hw.h @@ -77,6 +77,7 @@ enum e1e_registers {  #define E1000_POEMB	E1000_PHY_CTRL	/* PHY OEM Bits */  	E1000_PBA      = 0x01000, /* Packet Buffer Allocation - RW */  	E1000_PBS      = 0x01008, /* Packet Buffer Size */ +	E1000_PBECCSTS = 0x0100C, /* Packet Buffer ECC Status - RW */  	E1000_EEMNGCTL = 0x01010, /* MNG EEprom Control */  	E1000_EEWR     = 0x0102C, /* EEPROM Write Register - RW */  	E1000_FLOP     = 0x0103C, /* FLASH Opcode Register */ diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.c b/drivers/net/ethernet/intel/e1000e/ich8lan.c index 97633654760..24d9f61956f 100644 --- a/drivers/net/ethernet/intel/e1000e/ich8lan.c +++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c @@ -3624,6 +3624,17 @@ static void e1000_initialize_hw_bits_ich8lan(struct e1000_hw *hw)  	if (hw->mac.type == e1000_ich8lan)  		reg |= (E1000_RFCTL_IPV6_EX_DIS | E1000_RFCTL_NEW_IPV6_EXT_DIS);  	ew32(RFCTL, reg); + +	/* Enable ECC on Lynxpoint */ +	if (hw->mac.type == e1000_pch_lpt) { +		reg = er32(PBECCSTS); +		reg |= E1000_PBECCSTS_ECC_ENABLE; +		ew32(PBECCSTS, reg); + +		reg = er32(CTRL); +		reg |= E1000_CTRL_MEHE; +		ew32(CTRL, reg); +	}  }  /** diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index fbf75fdca99..643c883dd79 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -1678,6 +1678,23 @@ static irqreturn_t e1000_intr_msi(int irq, void *data)  			mod_timer(&adapter->watchdog_timer, jiffies + 1);  	} +	/* Reset on uncorrectable ECC error */ +	if ((icr & E1000_ICR_ECCER) && (hw->mac.type == e1000_pch_lpt)) { +		u32 pbeccsts = er32(PBECCSTS); + +		adapter->corr_errors += +		    pbeccsts & E1000_PBECCSTS_CORR_ERR_CNT_MASK; +		adapter->uncorr_errors += +		    (pbeccsts & E1000_PBECCSTS_UNCORR_ERR_CNT_MASK) >> +		    E1000_PBECCSTS_UNCORR_ERR_CNT_SHIFT; + +		/* Do the reset outside of interrupt context */ +		schedule_work(&adapter->reset_task); + +		/* return immediately since reset is imminent */ +		return IRQ_HANDLED; +	} +  	if (napi_schedule_prep(&adapter->napi)) {  		adapter->total_tx_bytes = 0;  		adapter->total_tx_packets = 0; @@ -1741,6 +1758,23 @@ static irqreturn_t e1000_intr(int irq, void *data)  			mod_timer(&adapter->watchdog_timer, jiffies + 1);  	} +	/* Reset on uncorrectable ECC error */ +	if ((icr & E1000_ICR_ECCER) && (hw->mac.type == e1000_pch_lpt)) { +		u32 pbeccsts = er32(PBECCSTS); + +		adapter->corr_errors += +		    pbeccsts & E1000_PBECCSTS_CORR_ERR_CNT_MASK; +		adapter->uncorr_errors += +		    (pbeccsts & E1000_PBECCSTS_UNCORR_ERR_CNT_MASK) >> +		    E1000_PBECCSTS_UNCORR_ERR_CNT_SHIFT; + +		/* Do the reset outside of interrupt context */ +		schedule_work(&adapter->reset_task); + +		/* return immediately since reset is imminent */ +		return IRQ_HANDLED; +	} +  	if (napi_schedule_prep(&adapter->napi)) {  		adapter->total_tx_bytes = 0;  		adapter->total_tx_packets = 0; @@ -2104,6 +2138,8 @@ static void e1000_irq_enable(struct e1000_adapter *adapter)  	if (adapter->msix_entries) {  		ew32(EIAC_82574, adapter->eiac_mask & E1000_EIAC_MASK_82574);  		ew32(IMS, adapter->eiac_mask | E1000_IMS_OTHER | E1000_IMS_LSC); +	} else if (hw->mac.type == e1000_pch_lpt) { +		ew32(IMS, IMS_ENABLE_MASK | E1000_IMS_ECCER);  	} else {  		ew32(IMS, IMS_ENABLE_MASK);  	} @@ -4251,6 +4287,16 @@ static void e1000e_update_stats(struct e1000_adapter *adapter)  	adapter->stats.mgptc += er32(MGTPTC);  	adapter->stats.mgprc += er32(MGTPRC);  	adapter->stats.mgpdc += er32(MGTPDC); + +	/* Correctable ECC Errors */ +	if (hw->mac.type == e1000_pch_lpt) { +		u32 pbeccsts = er32(PBECCSTS); +		adapter->corr_errors += +		    pbeccsts & E1000_PBECCSTS_CORR_ERR_CNT_MASK; +		adapter->uncorr_errors += +		    (pbeccsts & E1000_PBECCSTS_UNCORR_ERR_CNT_MASK) >> +		    E1000_PBECCSTS_UNCORR_ERR_CNT_SHIFT; +	}  }  /** diff --git a/drivers/net/ethernet/intel/ixgbe/Makefile b/drivers/net/ethernet/intel/ixgbe/Makefile index f3a632bf8d9..687c83d1bda 100644 --- a/drivers/net/ethernet/intel/ixgbe/Makefile +++ b/drivers/net/ethernet/intel/ixgbe/Makefile @@ -32,7 +32,7 @@  obj-$(CONFIG_IXGBE) += ixgbe.o -ixgbe-objs := ixgbe_main.o ixgbe_common.o ixgbe_ethtool.o ixgbe_debugfs.o\ +ixgbe-objs := ixgbe_main.o ixgbe_common.o ixgbe_ethtool.o \                ixgbe_82599.o ixgbe_82598.o ixgbe_phy.o ixgbe_sriov.o \                ixgbe_mbx.o ixgbe_x540.o ixgbe_lib.o ixgbe_ptp.o @@ -40,4 +40,5 @@ ixgbe-$(CONFIG_IXGBE_DCB) +=  ixgbe_dcb.o ixgbe_dcb_82598.o \                                ixgbe_dcb_82599.o ixgbe_dcb_nl.o  ixgbe-$(CONFIG_IXGBE_HWMON) += ixgbe_sysfs.o +ixgbe-$(CONFIG_DEBUG_FS) += ixgbe_debugfs.o  ixgbe-$(CONFIG_FCOE:m=y) += ixgbe_fcoe.o diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_debugfs.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_debugfs.c index 50aa546b8c7..3504686d3af 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_debugfs.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_debugfs.c @@ -24,9 +24,6 @@    Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497  *******************************************************************************/ - -#ifdef CONFIG_DEBUG_FS -  #include <linux/debugfs.h>  #include <linux/module.h> @@ -277,5 +274,3 @@ void ixgbe_dbg_exit(void)  {  	debugfs_remove_recursive(ixgbe_dbg_root);  } - -#endif /* CONFIG_DEBUG_FS */ diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index 20a5af6d87d..b3e3294cfe5 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -1401,6 +1401,7 @@ static void ixgbe_set_rsc_gso_size(struct ixgbe_ring *ring,  	/* set gso_size to avoid messing up TCP MSS */  	skb_shinfo(skb)->gso_size = DIV_ROUND_UP((skb->len - hdr_len),  						 IXGBE_CB(skb)->append_cnt); +	skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4;  }  static void ixgbe_update_rsc_stats(struct ixgbe_ring *rx_ring, diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c index 1a751c9d09c..bb9256a1b0a 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c @@ -660,11 +660,11 @@ int ixgbe_ptp_hwtstamp_ioctl(struct ixgbe_adapter *adapter,  		break;  	case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:  		tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_L4_V1; -		tsync_rx_mtrl = IXGBE_RXMTRL_V1_SYNC_MSG; +		tsync_rx_mtrl |= IXGBE_RXMTRL_V1_SYNC_MSG;  		break;  	case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:  		tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_L4_V1; -		tsync_rx_mtrl = IXGBE_RXMTRL_V1_DELAY_REQ_MSG; +		tsync_rx_mtrl |= IXGBE_RXMTRL_V1_DELAY_REQ_MSG;  		break;  	case HWTSTAMP_FILTER_PTP_V2_EVENT:  	case HWTSTAMP_FILTER_PTP_V2_L2_EVENT: diff --git a/drivers/net/ethernet/mellanox/mlx4/en_tx.c b/drivers/net/ethernet/mellanox/mlx4/en_tx.c index 2b799f4f1c3..6771b69f40d 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_tx.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_tx.c @@ -630,10 +630,15 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)  		ring->tx_csum++;  	} -	/* Copy dst mac address to wqe */ -	ethh = (struct ethhdr *)skb->data; -	tx_desc->ctrl.srcrb_flags16[0] = get_unaligned((__be16 *)ethh->h_dest); -	tx_desc->ctrl.imm = get_unaligned((__be32 *)(ethh->h_dest + 2)); +	if (mlx4_is_mfunc(mdev->dev) || priv->validate_loopback) { +		/* Copy dst mac address to wqe. This allows loopback in eSwitch, +		 * so that VFs and PF can communicate with each other +		 */ +		ethh = (struct ethhdr *)skb->data; +		tx_desc->ctrl.srcrb_flags16[0] = get_unaligned((__be16 *)ethh->h_dest); +		tx_desc->ctrl.imm = get_unaligned((__be32 *)(ethh->h_dest + 2)); +	} +  	/* Handle LSO (TSO) packets */  	if (lso_header_size) {  		/* Mark opcode as LSO */ diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c index e1bafffbc3b..5163af31499 100644 --- a/drivers/net/ethernet/mellanox/mlx4/main.c +++ b/drivers/net/ethernet/mellanox/mlx4/main.c @@ -380,7 +380,7 @@ static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)  		}  	} -	if ((dev_cap->flags & +	if ((dev->caps.flags &  	    (MLX4_DEV_CAP_FLAG_64B_CQE | MLX4_DEV_CAP_FLAG_64B_EQE)) &&  	    mlx4_is_master(dev))  		dev->caps.function_caps |= MLX4_FUNC_CAP_64B_EQE_CQE; @@ -1790,15 +1790,8 @@ static void mlx4_enable_msi_x(struct mlx4_dev *dev)  	int i;  	if (msi_x) { -		/* In multifunction mode each function gets 2 msi-X vectors -		 * one for data path completions anf the other for asynch events -		 * or command completions */ -		if (mlx4_is_mfunc(dev)) { -			nreq = 2; -		} else { -			nreq = min_t(int, dev->caps.num_eqs - -				     dev->caps.reserved_eqs, nreq); -		} +		nreq = min_t(int, dev->caps.num_eqs - dev->caps.reserved_eqs, +			     nreq);  		entries = kcalloc(nreq, sizeof *entries, GFP_KERNEL);  		if (!entries) diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c index bc165f4d0f6..695667d471a 100644 --- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c +++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c @@ -144,7 +144,7 @@ void netxen_release_tx_buffers(struct netxen_adapter *adapter)  					 buffrag->length, PCI_DMA_TODEVICE);  			buffrag->dma = 0ULL;  		} -		for (j = 0; j < cmd_buf->frag_count; j++) { +		for (j = 1; j < cmd_buf->frag_count; j++) {  			buffrag++;  			if (buffrag->dma) {  				pci_unmap_page(adapter->pdev, buffrag->dma, diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c index 6098fd4adfe..69e321a6507 100644 --- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c +++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c @@ -1963,10 +1963,12 @@ unwind:  	while (--i >= 0) {  		nf = &pbuf->frag_array[i+1];  		pci_unmap_page(pdev, nf->dma, nf->length, PCI_DMA_TODEVICE); +		nf->dma = 0ULL;  	}  	nf = &pbuf->frag_array[0];  	pci_unmap_single(pdev, nf->dma, skb_headlen(skb), PCI_DMA_TODEVICE); +	nf->dma = 0ULL;  out_err:  	return -ENOMEM; diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c index 6f82812d0fa..09aa310b619 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c @@ -986,8 +986,13 @@ qlcnic_process_lro(struct qlcnic_adapter *adapter,  	th->seq = htonl(seq_number);  	length = skb->len; -	if (adapter->flags & QLCNIC_FW_LRO_MSS_CAP) +	if (adapter->flags & QLCNIC_FW_LRO_MSS_CAP) {  		skb_shinfo(skb)->gso_size = qlcnic_get_lro_sts_mss(sts_data1); +		if (skb->protocol == htons(ETH_P_IPV6)) +			skb_shinfo(skb)->gso_type = SKB_GSO_TCPV6; +		else +			skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4; +	}  	if (vid != 0xffff)  		__vlan_hwaccel_put_tag(skb, vid); diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index ed96f309bca..998974f7874 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -450,7 +450,6 @@ enum rtl8168_registers {  #define PWM_EN				(1 << 22)  #define RXDV_GATED_EN			(1 << 19)  #define EARLY_TALLY_EN			(1 << 16) -#define FORCE_CLK			(1 << 15) /* force clock request */  };  enum rtl_register_content { @@ -514,7 +513,6 @@ enum rtl_register_content {  	PMEnable	= (1 << 0),	/* Power Management Enable */  	/* Config2 register p. 25 */ -	ClkReqEn	= (1 << 7),	/* Clock Request Enable */  	MSIEnable	= (1 << 5),	/* 8169 only. Reserved in the 8168. */  	PCI_Clock_66MHz = 0x01,  	PCI_Clock_33MHz = 0x00, @@ -535,7 +533,6 @@ enum rtl_register_content {  	Spi_en		= (1 << 3),  	LanWake		= (1 << 1),	/* LanWake enable/disable */  	PMEStatus	= (1 << 0),	/* PME status can be reset by PCI RST# */ -	ASPM_en		= (1 << 0),	/* ASPM enable */  	/* TBICSR p.28 */  	TBIReset	= 0x80000000, @@ -684,7 +681,6 @@ enum features {  	RTL_FEATURE_WOL		= (1 << 0),  	RTL_FEATURE_MSI		= (1 << 1),  	RTL_FEATURE_GMII	= (1 << 2), -	RTL_FEATURE_FW_LOADED	= (1 << 3),  };  struct rtl8169_counters { @@ -1826,8 +1822,6 @@ static void rtl8169_rx_vlan_tag(struct RxDesc *desc, struct sk_buff *skb)  	if (opts2 & RxVlanTag)  		__vlan_hwaccel_put_tag(skb, swab16(opts2 & 0xffff)); - -	desc->opts2 = 0;  }  static int rtl8169_gset_tbi(struct net_device *dev, struct ethtool_cmd *cmd) @@ -2391,10 +2385,8 @@ static void rtl_apply_firmware(struct rtl8169_private *tp)  	struct rtl_fw *rtl_fw = tp->rtl_fw;  	/* TODO: release firmware once rtl_phy_write_fw signals failures. */ -	if (!IS_ERR_OR_NULL(rtl_fw)) { +	if (!IS_ERR_OR_NULL(rtl_fw))  		rtl_phy_write_fw(tp, rtl_fw); -		tp->features |= RTL_FEATURE_FW_LOADED; -	}  }  static void rtl_apply_firmware_cond(struct rtl8169_private *tp, u8 reg, u16 val) @@ -2405,31 +2397,6 @@ static void rtl_apply_firmware_cond(struct rtl8169_private *tp, u8 reg, u16 val)  		rtl_apply_firmware(tp);  } -static void r810x_aldps_disable(struct rtl8169_private *tp) -{ -	rtl_writephy(tp, 0x1f, 0x0000); -	rtl_writephy(tp, 0x18, 0x0310); -	msleep(100); -} - -static void r810x_aldps_enable(struct rtl8169_private *tp) -{ -	if (!(tp->features & RTL_FEATURE_FW_LOADED)) -		return; - -	rtl_writephy(tp, 0x1f, 0x0000); -	rtl_writephy(tp, 0x18, 0x8310); -} - -static void r8168_aldps_enable_1(struct rtl8169_private *tp) -{ -	if (!(tp->features & RTL_FEATURE_FW_LOADED)) -		return; - -	rtl_writephy(tp, 0x1f, 0x0000); -	rtl_w1w0_phy(tp, 0x15, 0x1000, 0x0000); -} -  static void rtl8169s_hw_phy_config(struct rtl8169_private *tp)  {  	static const struct phy_reg phy_reg_init[] = { @@ -3220,8 +3187,6 @@ static void rtl8168e_2_hw_phy_config(struct rtl8169_private *tp)  	rtl_w1w0_phy(tp, 0x10, 0x0000, 0x0400);  	rtl_writephy(tp, 0x1f, 0x0000); -	r8168_aldps_enable_1(tp); -  	/* Broken BIOS workaround: feed GigaMAC registers with MAC address. */  	rtl_rar_exgmac_set(tp, tp->dev->dev_addr);  } @@ -3296,8 +3261,6 @@ static void rtl8168f_1_hw_phy_config(struct rtl8169_private *tp)  	rtl_writephy(tp, 0x05, 0x8b85);  	rtl_w1w0_phy(tp, 0x06, 0x4000, 0x0000);  	rtl_writephy(tp, 0x1f, 0x0000); - -	r8168_aldps_enable_1(tp);  }  static void rtl8168f_2_hw_phy_config(struct rtl8169_private *tp) @@ -3305,8 +3268,6 @@ static void rtl8168f_2_hw_phy_config(struct rtl8169_private *tp)  	rtl_apply_firmware(tp);  	rtl8168f_hw_phy_config(tp); - -	r8168_aldps_enable_1(tp);  }  static void rtl8411_hw_phy_config(struct rtl8169_private *tp) @@ -3404,8 +3365,6 @@ static void rtl8411_hw_phy_config(struct rtl8169_private *tp)  	rtl_w1w0_phy(tp, 0x19, 0x0000, 0x0001);  	rtl_w1w0_phy(tp, 0x10, 0x0000, 0x0400);  	rtl_writephy(tp, 0x1f, 0x0000); - -	r8168_aldps_enable_1(tp);  }  static void rtl8168g_1_hw_phy_config(struct rtl8169_private *tp) @@ -3491,19 +3450,21 @@ static void rtl8105e_hw_phy_config(struct rtl8169_private *tp)  	};  	/* Disable ALDPS before ram code */ -	r810x_aldps_disable(tp); +	rtl_writephy(tp, 0x1f, 0x0000); +	rtl_writephy(tp, 0x18, 0x0310); +	msleep(100);  	rtl_apply_firmware(tp);  	rtl_writephy_batch(tp, phy_reg_init, ARRAY_SIZE(phy_reg_init)); - -	r810x_aldps_enable(tp);  }  static void rtl8402_hw_phy_config(struct rtl8169_private *tp)  {  	/* Disable ALDPS before setting firmware */ -	r810x_aldps_disable(tp); +	rtl_writephy(tp, 0x1f, 0x0000); +	rtl_writephy(tp, 0x18, 0x0310); +	msleep(20);  	rtl_apply_firmware(tp); @@ -3513,8 +3474,6 @@ static void rtl8402_hw_phy_config(struct rtl8169_private *tp)  	rtl_writephy(tp, 0x10, 0x401f);  	rtl_writephy(tp, 0x19, 0x7030);  	rtl_writephy(tp, 0x1f, 0x0000); - -	r810x_aldps_enable(tp);  }  static void rtl8106e_hw_phy_config(struct rtl8169_private *tp) @@ -3527,7 +3486,9 @@ static void rtl8106e_hw_phy_config(struct rtl8169_private *tp)  	};  	/* Disable ALDPS before ram code */ -	r810x_aldps_disable(tp); +	rtl_writephy(tp, 0x1f, 0x0000); +	rtl_writephy(tp, 0x18, 0x0310); +	msleep(100);  	rtl_apply_firmware(tp); @@ -3535,8 +3496,6 @@ static void rtl8106e_hw_phy_config(struct rtl8169_private *tp)  	rtl_writephy_batch(tp, phy_reg_init, ARRAY_SIZE(phy_reg_init));  	rtl_eri_write(tp, 0x1d0, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC); - -	r810x_aldps_enable(tp);  }  static void rtl_hw_phy_config(struct net_device *dev) @@ -5053,6 +5012,8 @@ static void rtl_hw_start_8168e_2(struct rtl8169_private *tp)  	RTL_W8(MaxTxPacketSize, EarlySize); +	rtl_disable_clock_request(pdev); +  	RTL_W32(TxConfig, RTL_R32(TxConfig) | TXCFG_AUTO_FIFO);  	RTL_W8(MCU, RTL_R8(MCU) & ~NOW_IS_OOB); @@ -5061,8 +5022,7 @@ static void rtl_hw_start_8168e_2(struct rtl8169_private *tp)  	RTL_W8(DLLPR, RTL_R8(DLLPR) | PFM_EN);  	RTL_W32(MISC, RTL_R32(MISC) | PWM_EN); -	RTL_W8(Config5, (RTL_R8(Config5) & ~Spi_en) | ASPM_en); -	RTL_W8(Config2, RTL_R8(Config2) | ClkReqEn); +	RTL_W8(Config5, RTL_R8(Config5) & ~Spi_en);  }  static void rtl_hw_start_8168f(struct rtl8169_private *tp) @@ -5087,12 +5047,13 @@ static void rtl_hw_start_8168f(struct rtl8169_private *tp)  	RTL_W8(MaxTxPacketSize, EarlySize); +	rtl_disable_clock_request(pdev); +  	RTL_W32(TxConfig, RTL_R32(TxConfig) | TXCFG_AUTO_FIFO);  	RTL_W8(MCU, RTL_R8(MCU) & ~NOW_IS_OOB);  	RTL_W8(DLLPR, RTL_R8(DLLPR) | PFM_EN); -	RTL_W32(MISC, RTL_R32(MISC) | PWM_EN | FORCE_CLK); -	RTL_W8(Config5, (RTL_R8(Config5) & ~Spi_en) | ASPM_en); -	RTL_W8(Config2, RTL_R8(Config2) | ClkReqEn); +	RTL_W32(MISC, RTL_R32(MISC) | PWM_EN); +	RTL_W8(Config5, RTL_R8(Config5) & ~Spi_en);  }  static void rtl_hw_start_8168f_1(struct rtl8169_private *tp) @@ -5149,10 +5110,8 @@ static void rtl_hw_start_8168g_1(struct rtl8169_private *tp)  	rtl_w1w0_eri(tp, 0xdc, ERIAR_MASK_0001, 0x01, 0x00, ERIAR_EXGMAC);  	RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); -	RTL_W32(MISC, (RTL_R32(MISC) | FORCE_CLK) & ~RXDV_GATED_EN); +	RTL_W32(MISC, RTL_R32(MISC) & ~RXDV_GATED_EN);  	RTL_W8(MaxTxPacketSize, EarlySize); -	RTL_W8(Config5, RTL_R8(Config5) | ASPM_en); -	RTL_W8(Config2, RTL_R8(Config2) | ClkReqEn);  	rtl_eri_write(tp, 0xc0, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC);  	rtl_eri_write(tp, 0xb8, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC); @@ -5368,9 +5327,6 @@ static void rtl_hw_start_8105e_1(struct rtl8169_private *tp)  	RTL_W8(MCU, RTL_R8(MCU) | EN_NDP | EN_OOB_RESET);  	RTL_W8(DLLPR, RTL_R8(DLLPR) | PFM_EN); -	RTL_W8(Config5, RTL_R8(Config5) | ASPM_en); -	RTL_W8(Config2, RTL_R8(Config2) | ClkReqEn); -	RTL_W32(MISC, RTL_R32(MISC) | FORCE_CLK);  	rtl_ephy_init(tp, e_info_8105e_1, ARRAY_SIZE(e_info_8105e_1));  } @@ -5396,9 +5352,6 @@ static void rtl_hw_start_8402(struct rtl8169_private *tp)  	RTL_W32(TxConfig, RTL_R32(TxConfig) | TXCFG_AUTO_FIFO);  	RTL_W8(MCU, RTL_R8(MCU) & ~NOW_IS_OOB); -	RTL_W8(Config5, RTL_R8(Config5) | ASPM_en); -	RTL_W8(Config2, RTL_R8(Config2) | ClkReqEn); -	RTL_W32(MISC, RTL_R32(MISC) | FORCE_CLK);  	rtl_ephy_init(tp, e_info_8402, ARRAY_SIZE(e_info_8402)); @@ -5420,10 +5373,7 @@ static void rtl_hw_start_8106(struct rtl8169_private *tp)  	/* Force LAN exit from ASPM if Rx/Tx are not idle */  	RTL_W32(FuncEvent, RTL_R32(FuncEvent) | 0x002800); -	RTL_W32(MISC, -		(RTL_R32(MISC) | DISABLE_LAN_EN | FORCE_CLK) & ~EARLY_TALLY_EN); -	RTL_W8(Config5, RTL_R8(Config5) | ASPM_en); -	RTL_W8(Config2, RTL_R8(Config2) | ClkReqEn); +	RTL_W32(MISC, (RTL_R32(MISC) | DISABLE_LAN_EN) & ~EARLY_TALLY_EN);  	RTL_W8(MCU, RTL_R8(MCU) | EN_NDP | EN_OOB_RESET);  	RTL_W8(DLLPR, RTL_R8(DLLPR) & ~PFM_EN);  } @@ -6064,8 +6014,6 @@ static int rtl_rx(struct net_device *dev, struct rtl8169_private *tp, u32 budget  			    !(status & (RxRWT | RxFOVF)) &&  			    (dev->features & NETIF_F_RXALL))  				goto process_pkt; - -			rtl8169_mark_to_asic(desc, rx_buf_sz);  		} else {  			struct sk_buff *skb;  			dma_addr_t addr; @@ -6086,16 +6034,14 @@ process_pkt:  			if (unlikely(rtl8169_fragmented_frame(status))) {  				dev->stats.rx_dropped++;  				dev->stats.rx_length_errors++; -				rtl8169_mark_to_asic(desc, rx_buf_sz); -				continue; +				goto release_descriptor;  			}  			skb = rtl8169_try_rx_copy(tp->Rx_databuff[entry],  						  tp, pkt_size, addr); -			rtl8169_mark_to_asic(desc, rx_buf_sz);  			if (!skb) {  				dev->stats.rx_dropped++; -				continue; +				goto release_descriptor;  			}  			rtl8169_rx_csum(skb, status); @@ -6111,13 +6057,10 @@ process_pkt:  			tp->rx_stats.bytes += pkt_size;  			u64_stats_update_end(&tp->rx_stats.syncp);  		} - -		/* Work around for AMD plateform. */ -		if ((desc->opts2 & cpu_to_le32(0xfffe000)) && -		    (tp->mac_version == RTL_GIGA_MAC_VER_05)) { -			desc->opts2 = 0; -			cur_rx++; -		} +release_descriptor: +		desc->opts2 = 0; +		wmb(); +		rtl8169_mark_to_asic(desc, rx_buf_sz);  	}  	count = cur_rx - tp->cur_rx; diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index f07c0612abf..b75f4b28689 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -69,7 +69,7 @@  #undef STMMAC_XMIT_DEBUG  /*#define STMMAC_XMIT_DEBUG*/ -#ifdef STMMAC_TX_DEBUG +#ifdef STMMAC_XMIT_DEBUG  #define TX_DBG(fmt, args...)  printk(fmt, ## args)  #else  #define TX_DBG(fmt, args...)  do { } while (0) diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c index 0376a5e6b2b..0b9829fe3ee 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c @@ -188,8 +188,6 @@ int stmmac_mdio_register(struct net_device *ndev)  		goto bus_register_fail;  	} -	priv->mii = new_bus; -  	found = 0;  	for (addr = 0; addr < PHY_MAX_ADDR; addr++) {  		struct phy_device *phydev = new_bus->phy_map[addr]; @@ -237,8 +235,14 @@ int stmmac_mdio_register(struct net_device *ndev)  		}  	} -	if (!found) +	if (!found) {  		pr_warning("%s: No PHY found\n", ndev->name); +		mdiobus_unregister(new_bus); +		mdiobus_free(new_bus); +		return -ENODEV; +	} + +	priv->mii = new_bus;  	return 0; diff --git a/drivers/net/ethernet/via/via-rhine.c b/drivers/net/ethernet/via/via-rhine.c index 7992b3e05d3..78ace59efd2 100644 --- a/drivers/net/ethernet/via/via-rhine.c +++ b/drivers/net/ethernet/via/via-rhine.c @@ -1801,7 +1801,7 @@ static void rhine_tx(struct net_device *dev)  					 rp->tx_skbuff[entry]->len,  					 PCI_DMA_TODEVICE);  		} -		dev_kfree_skb_irq(rp->tx_skbuff[entry]); +		dev_kfree_skb(rp->tx_skbuff[entry]);  		rp->tx_skbuff[entry] = NULL;  		entry = (++rp->dirty_tx) % TX_RING_SIZE;  	} @@ -2010,11 +2010,7 @@ static void rhine_slow_event_task(struct work_struct *work)  	if (intr_status & IntrPCIErr)  		netif_warn(rp, hw, dev, "PCI error\n"); -	napi_disable(&rp->napi); -	rhine_irq_disable(rp); -	/* Slow and safe. Consider __napi_schedule as a replacement ? */ -	napi_enable(&rp->napi); -	napi_schedule(&rp->napi); +	iowrite16(RHINE_EVENT & 0xffff, rp->base + IntrEnable);  out_unlock:  	mutex_unlock(&rp->task_lock); diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h index 5fd6f467432..e6fe0d80d61 100644 --- a/drivers/net/hyperv/hyperv_net.h +++ b/drivers/net/hyperv/hyperv_net.h @@ -84,7 +84,7 @@ struct hv_netvsc_packet {  };  struct netvsc_device_info { -	unsigned char mac_adr[6]; +	unsigned char mac_adr[ETH_ALEN];  	bool link_state;	/* 0 - link up, 1 - link down */  	int  ring_size;  }; diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c index f825a629a69..8264f0ef769 100644 --- a/drivers/net/hyperv/netvsc_drv.c +++ b/drivers/net/hyperv/netvsc_drv.c @@ -349,7 +349,7 @@ static int netvsc_set_mac_addr(struct net_device *ndev, void *p)  	struct net_device_context *ndevctx = netdev_priv(ndev);  	struct hv_device *hdev =  ndevctx->device_ctx;  	struct sockaddr *addr = p; -	char save_adr[14]; +	char save_adr[ETH_ALEN];  	unsigned char save_aatype;  	int err; diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c index 81f8f9e31db..fcbf680c3e6 100644 --- a/drivers/net/loopback.c +++ b/drivers/net/loopback.c @@ -77,6 +77,11 @@ static netdev_tx_t loopback_xmit(struct sk_buff *skb,  	skb_orphan(skb); +	/* Before queueing this packet to netif_rx(), +	 * make sure dst is refcounted. +	 */ +	skb_dst_force(skb); +  	skb->protocol = eth_type_trans(skb, dev);  	/* it's OK to use per_cpu_ptr() because BHs are off */ diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index 68a43fe602e..d3fb97d97cb 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c @@ -822,7 +822,10 @@ static int macvlan_changelink(struct net_device *dev,  static size_t macvlan_get_size(const struct net_device *dev)  { -	return nla_total_size(4); +	return (0 +		+ nla_total_size(4) /* IFLA_MACVLAN_MODE */ +		+ nla_total_size(2) /* IFLA_MACVLAN_FLAGS */ +		);  }  static int macvlan_fill_info(struct sk_buff *skb, diff --git a/drivers/net/phy/icplus.c b/drivers/net/phy/icplus.c index d5199cb4cae..b5ddd5077a8 100644 --- a/drivers/net/phy/icplus.c +++ b/drivers/net/phy/icplus.c @@ -36,8 +36,9 @@ MODULE_LICENSE("GPL");  /* IP101A/G - IP1001 */  #define IP10XX_SPEC_CTRL_STATUS		16	/* Spec. Control Register */ +#define IP1001_RXPHASE_SEL		(1<<0)	/* Add delay on RX_CLK */ +#define IP1001_TXPHASE_SEL		(1<<1)	/* Add delay on TX_CLK */  #define IP1001_SPEC_CTRL_STATUS_2	20	/* IP1001 Spec. Control Reg 2 */ -#define IP1001_PHASE_SEL_MASK		3	/* IP1001 RX/TXPHASE_SEL */  #define IP1001_APS_ON			11	/* IP1001 APS Mode  bit */  #define IP101A_G_APS_ON			2	/* IP101A/G APS Mode bit */  #define IP101A_G_IRQ_CONF_STATUS	0x11	/* Conf Info IRQ & Status Reg */ @@ -138,19 +139,24 @@ static int ip1001_config_init(struct phy_device *phydev)  	if (c < 0)  		return c; -	/* INTR pin used: speed/link/duplex will cause an interrupt */ -	c = phy_write(phydev, IP101A_G_IRQ_CONF_STATUS, IP101A_G_IRQ_DEFAULT); -	if (c < 0) -		return c; +	if ((phydev->interface == PHY_INTERFACE_MODE_RGMII) || +	    (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) || +	    (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) || +	    (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)) { -	if (phydev->interface == PHY_INTERFACE_MODE_RGMII) { -		/* Additional delay (2ns) used to adjust RX clock phase -		 * at RGMII interface */  		c = phy_read(phydev, IP10XX_SPEC_CTRL_STATUS);  		if (c < 0)  			return c; -		c |= IP1001_PHASE_SEL_MASK; +		c &= ~(IP1001_RXPHASE_SEL | IP1001_TXPHASE_SEL); + +		if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) +			c |= (IP1001_RXPHASE_SEL | IP1001_TXPHASE_SEL); +		else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) +			c |= IP1001_RXPHASE_SEL; +		else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) +			c |= IP1001_TXPHASE_SEL; +  		c = phy_write(phydev, IP10XX_SPEC_CTRL_STATUS, c);  		if (c < 0)  			return c; @@ -167,6 +173,11 @@ static int ip101a_g_config_init(struct phy_device *phydev)  	if (c < 0)  		return c; +	/* INTR pin used: speed/link/duplex will cause an interrupt */ +	c = phy_write(phydev, IP101A_G_IRQ_CONF_STATUS, IP101A_G_IRQ_DEFAULT); +	if (c < 0) +		return c; +  	/* Enable Auto Power Saving mode */  	c = phy_read(phydev, IP10XX_SPEC_CTRL_STATUS);  	c |= IP101A_G_APS_ON; diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c index 5d2a3f21588..22dec9c7ef0 100644 --- a/drivers/net/phy/marvell.c +++ b/drivers/net/phy/marvell.c @@ -353,15 +353,6 @@ static int m88e1111_config_init(struct phy_device *phydev)  	int err;  	int temp; -	/* Enable Fiber/Copper auto selection */ -	temp = phy_read(phydev, MII_M1111_PHY_EXT_SR); -	temp &= ~MII_M1111_HWCFG_FIBER_COPPER_AUTO; -	phy_write(phydev, MII_M1111_PHY_EXT_SR, temp); - -	temp = phy_read(phydev, MII_BMCR); -	temp |= BMCR_RESET; -	phy_write(phydev, MII_BMCR, temp); -  	if ((phydev->interface == PHY_INTERFACE_MODE_RGMII) ||  	    (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) ||  	    (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) || diff --git a/drivers/net/tun.c b/drivers/net/tun.c index af372d0957f..2917a86f4c4 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -109,11 +109,11 @@ struct tap_filter {  	unsigned char	addr[FLT_EXACT_COUNT][ETH_ALEN];  }; -/* 1024 is probably a high enough limit: modern hypervisors seem to support on - * the order of 100-200 CPUs so this leaves us some breathing space if we want - * to match a queue per guest CPU. - */ -#define MAX_TAP_QUEUES 1024 +/* DEFAULT_MAX_NUM_RSS_QUEUES were choosed to let the rx/tx queues allocated for + * the netdevice to be fit in one page. So we can make sure the success of + * memory allocation. TODO: increase the limit. */ +#define MAX_TAP_QUEUES DEFAULT_MAX_NUM_RSS_QUEUES +#define MAX_TAP_FLOWS  4096  #define TUN_FLOW_EXPIRE (3 * HZ) @@ -185,6 +185,8 @@ struct tun_struct {  	unsigned long ageing_time;  	unsigned int numdisabled;  	struct list_head disabled; +	void *security; +	u32 flow_count;  };  static inline u32 tun_hashfn(u32 rxhash) @@ -218,6 +220,7 @@ static struct tun_flow_entry *tun_flow_create(struct tun_struct *tun,  		e->queue_index = queue_index;  		e->tun = tun;  		hlist_add_head_rcu(&e->hash_link, head); +		++tun->flow_count;  	}  	return e;  } @@ -228,6 +231,7 @@ static void tun_flow_delete(struct tun_struct *tun, struct tun_flow_entry *e)  		  e->rxhash, e->queue_index);  	hlist_del_rcu(&e->hash_link);  	kfree_rcu(e, rcu); +	--tun->flow_count;  }  static void tun_flow_flush(struct tun_struct *tun) @@ -294,11 +298,12 @@ static void tun_flow_cleanup(unsigned long data)  }  static void tun_flow_update(struct tun_struct *tun, u32 rxhash, -			    u16 queue_index) +			    struct tun_file *tfile)  {  	struct hlist_head *head;  	struct tun_flow_entry *e;  	unsigned long delay = tun->ageing_time; +	u16 queue_index = tfile->queue_index;  	if (!rxhash)  		return; @@ -307,7 +312,9 @@ static void tun_flow_update(struct tun_struct *tun, u32 rxhash,  	rcu_read_lock(); -	if (tun->numqueues == 1) +	/* We may get a very small possibility of OOO during switching, not +	 * worth to optimize.*/ +	if (tun->numqueues == 1 || tfile->detached)  		goto unlock;  	e = tun_flow_find(head, rxhash); @@ -317,7 +324,8 @@ static void tun_flow_update(struct tun_struct *tun, u32 rxhash,  		e->updated = jiffies;  	} else {  		spin_lock_bh(&tun->lock); -		if (!tun_flow_find(head, rxhash)) +		if (!tun_flow_find(head, rxhash) && +		    tun->flow_count < MAX_TAP_FLOWS)  			tun_flow_create(tun, head, rxhash, queue_index);  		if (!timer_pending(&tun->flow_gc_timer)) @@ -406,21 +414,21 @@ static void __tun_detach(struct tun_file *tfile, bool clean)  	tun = rtnl_dereference(tfile->tun); -	if (tun) { +	if (tun && !tfile->detached) {  		u16 index = tfile->queue_index;  		BUG_ON(index >= tun->numqueues);  		dev = tun->dev;  		rcu_assign_pointer(tun->tfiles[index],  				   tun->tfiles[tun->numqueues - 1]); -		rcu_assign_pointer(tfile->tun, NULL);  		ntfile = rtnl_dereference(tun->tfiles[index]);  		ntfile->queue_index = index;  		--tun->numqueues; -		if (clean) +		if (clean) { +			rcu_assign_pointer(tfile->tun, NULL);  			sock_put(&tfile->sk); -		else +		} else  			tun_disable_queue(tun, tfile);  		synchronize_net(); @@ -434,10 +442,13 @@ static void __tun_detach(struct tun_file *tfile, bool clean)  	}  	if (clean) { -		if (tun && tun->numqueues == 0 && tun->numdisabled == 0 && -		    !(tun->flags & TUN_PERSIST)) -			if (tun->dev->reg_state == NETREG_REGISTERED) +		if (tun && tun->numqueues == 0 && tun->numdisabled == 0) { +			netif_carrier_off(tun->dev); + +			if (!(tun->flags & TUN_PERSIST) && +			    tun->dev->reg_state == NETREG_REGISTERED)  				unregister_netdevice(tun->dev); +		}  		BUG_ON(!test_bit(SOCK_EXTERNALLY_ALLOCATED,  				 &tfile->socket.flags)); @@ -465,6 +476,10 @@ static void tun_detach_all(struct net_device *dev)  		rcu_assign_pointer(tfile->tun, NULL);  		--tun->numqueues;  	} +	list_for_each_entry(tfile, &tun->disabled, next) { +		wake_up_all(&tfile->wq.wait); +		rcu_assign_pointer(tfile->tun, NULL); +	}  	BUG_ON(tun->numqueues != 0);  	synchronize_net(); @@ -490,8 +505,12 @@ static int tun_attach(struct tun_struct *tun, struct file *file)  	struct tun_file *tfile = file->private_data;  	int err; +	err = security_tun_dev_attach(tfile->socket.sk, tun->security); +	if (err < 0) +		goto out; +  	err = -EINVAL; -	if (rtnl_dereference(tfile->tun)) +	if (rtnl_dereference(tfile->tun) && !tfile->detached)  		goto out;  	err = -EBUSY; @@ -1190,7 +1209,7 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,  	tun->dev->stats.rx_packets++;  	tun->dev->stats.rx_bytes += len; -	tun_flow_update(tun, rxhash, tfile->queue_index); +	tun_flow_update(tun, rxhash, tfile);  	return total_len;  } @@ -1373,6 +1392,7 @@ static void tun_free_netdev(struct net_device *dev)  	BUG_ON(!(list_empty(&tun->disabled)));  	tun_flow_uninit(tun); +	security_tun_dev_free_security(tun->security);  	free_netdev(dev);  } @@ -1562,7 +1582,7 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)  		if (tun_not_capable(tun))  			return -EPERM; -		err = security_tun_dev_attach(tfile->socket.sk); +		err = security_tun_dev_open(tun->security);  		if (err < 0)  			return err; @@ -1577,6 +1597,8 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)  	else {  		char *name;  		unsigned long flags = 0; +		int queues = ifr->ifr_flags & IFF_MULTI_QUEUE ? +			     MAX_TAP_QUEUES : 1;  		if (!ns_capable(net->user_ns, CAP_NET_ADMIN))  			return -EPERM; @@ -1600,8 +1622,8 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)  			name = ifr->ifr_name;  		dev = alloc_netdev_mqs(sizeof(struct tun_struct), name, -				       tun_setup, -				       MAX_TAP_QUEUES, MAX_TAP_QUEUES); +				       tun_setup, queues, queues); +  		if (!dev)  			return -ENOMEM; @@ -1619,7 +1641,9 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)  		spin_lock_init(&tun->lock); -		security_tun_dev_post_create(&tfile->sk); +		err = security_tun_dev_alloc_security(&tun->security); +		if (err < 0) +			goto err_free_dev;  		tun_net_init(dev); @@ -1644,10 +1668,10 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)  		    device_create_file(&tun->dev->dev, &dev_attr_owner) ||  		    device_create_file(&tun->dev->dev, &dev_attr_group))  			pr_err("Failed to create tun sysfs files\n"); - -		netif_carrier_on(tun->dev);  	} +	netif_carrier_on(tun->dev); +  	tun_debug(KERN_INFO, tun, "tun_set_iff\n");  	if (ifr->ifr_flags & IFF_NO_PI) @@ -1789,19 +1813,24 @@ static int tun_set_queue(struct file *file, struct ifreq *ifr)  	if (ifr->ifr_flags & IFF_ATTACH_QUEUE) {  		tun = tfile->detached; -		if (!tun) +		if (!tun) {  			ret = -EINVAL; -		else -			ret = tun_attach(tun, file); +			goto unlock; +		} +		ret = security_tun_dev_attach_queue(tun->security); +		if (ret < 0) +			goto unlock; +		ret = tun_attach(tun, file);  	} else if (ifr->ifr_flags & IFF_DETACH_QUEUE) {  		tun = rtnl_dereference(tfile->tun); -		if (!tun || !(tun->flags & TUN_TAP_MQ)) +		if (!tun || !(tun->flags & TUN_TAP_MQ) || tfile->detached)  			ret = -EINVAL;  		else  			__tun_detach(tfile, false);  	} else  		ret = -EINVAL; +unlock:  	rtnl_unlock();  	return ret;  } diff --git a/drivers/net/usb/cdc_mbim.c b/drivers/net/usb/cdc_mbim.c index 42f51c71ec1..248d2dc765a 100644 --- a/drivers/net/usb/cdc_mbim.c +++ b/drivers/net/usb/cdc_mbim.c @@ -374,6 +374,21 @@ static const struct driver_info cdc_mbim_info = {  	.tx_fixup = cdc_mbim_tx_fixup,  }; +/* MBIM and NCM devices should not need a ZLP after NTBs with + * dwNtbOutMaxSize length. This driver_info is for the exceptional + * devices requiring it anyway, allowing them to be supported without + * forcing the performance penalty on all the sane devices. + */ +static const struct driver_info cdc_mbim_info_zlp = { +	.description = "CDC MBIM", +	.flags = FLAG_NO_SETINT | FLAG_MULTI_PACKET | FLAG_WWAN | FLAG_SEND_ZLP, +	.bind = cdc_mbim_bind, +	.unbind = cdc_mbim_unbind, +	.manage_power = cdc_mbim_manage_power, +	.rx_fixup = cdc_mbim_rx_fixup, +	.tx_fixup = cdc_mbim_tx_fixup, +}; +  static const struct usb_device_id mbim_devs[] = {  	/* This duplicate NCM entry is intentional. MBIM devices can  	 * be disguised as NCM by default, and this is necessary to @@ -385,6 +400,10 @@ static const struct usb_device_id mbim_devs[] = {  	{ USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_NCM, USB_CDC_PROTO_NONE),  	  .driver_info = (unsigned long)&cdc_mbim_info,  	}, +	/* Sierra Wireless MC7710 need ZLPs */ +	{ USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x68a2, USB_CLASS_COMM, USB_CDC_SUBCLASS_MBIM, USB_CDC_PROTO_NONE), +	  .driver_info = (unsigned long)&cdc_mbim_info_zlp, +	},  	{ USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_MBIM, USB_CDC_PROTO_NONE),  	  .driver_info = (unsigned long)&cdc_mbim_info,  	}, diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c index 71b6e92b8e9..00d3b2d3782 100644 --- a/drivers/net/usb/cdc_ncm.c +++ b/drivers/net/usb/cdc_ncm.c @@ -435,6 +435,13 @@ advance:  		len -= temp;  	} +	/* some buggy devices have an IAD but no CDC Union */ +	if (!ctx->union_desc && intf->intf_assoc && intf->intf_assoc->bInterfaceCount == 2) { +		ctx->control = intf; +		ctx->data = usb_ifnum_to_if(dev->udev, intf->cur_altsetting->desc.bInterfaceNumber + 1); +		dev_dbg(&intf->dev, "CDC Union missing - got slave from IAD\n"); +	} +  	/* check if we got everything */  	if ((ctx->control == NULL) || (ctx->data == NULL) ||  	    ((!ctx->mbim_desc) && ((ctx->ether_desc == NULL) || (ctx->control != intf)))) @@ -497,7 +504,8 @@ advance:  error2:  	usb_set_intfdata(ctx->control, NULL);  	usb_set_intfdata(ctx->data, NULL); -	usb_driver_release_interface(driver, ctx->data); +	if (ctx->data != ctx->control) +		usb_driver_release_interface(driver, ctx->data);  error:  	cdc_ncm_free((struct cdc_ncm_ctx *)dev->data[0]);  	dev->data[0] = 0; @@ -1155,6 +1163,20 @@ static const struct driver_info wwan_info = {  	.tx_fixup = cdc_ncm_tx_fixup,  }; +/* Same as wwan_info, but with FLAG_NOARP  */ +static const struct driver_info wwan_noarp_info = { +	.description = "Mobile Broadband Network Device (NO ARP)", +	.flags = FLAG_POINTTOPOINT | FLAG_NO_SETINT | FLAG_MULTI_PACKET +			| FLAG_WWAN | FLAG_NOARP, +	.bind = cdc_ncm_bind, +	.unbind = cdc_ncm_unbind, +	.check_connect = cdc_ncm_check_connect, +	.manage_power = usbnet_manage_power, +	.status = cdc_ncm_status, +	.rx_fixup = cdc_ncm_rx_fixup, +	.tx_fixup = cdc_ncm_tx_fixup, +}; +  static const struct usb_device_id cdc_devs[] = {  	/* Ericsson MBM devices like F5521gw */  	{ .match_flags = USB_DEVICE_ID_MATCH_INT_INFO @@ -1193,6 +1215,16 @@ static const struct usb_device_id cdc_devs[] = {  	{ USB_VENDOR_AND_INTERFACE_INFO(0x12d1, 0xff, 0x02, 0x46),  	  .driver_info = (unsigned long)&wwan_info,  	}, +	{ USB_VENDOR_AND_INTERFACE_INFO(0x12d1, 0xff, 0x02, 0x76), +	  .driver_info = (unsigned long)&wwan_info, +	}, + +	/* Infineon(now Intel) HSPA Modem platform */ +	{ USB_DEVICE_AND_INTERFACE_INFO(0x1519, 0x0443, +		USB_CLASS_COMM, +		USB_CDC_SUBCLASS_NCM, USB_CDC_PROTO_NONE), +	  .driver_info = (unsigned long)&wwan_noarp_info, +	},  	/* Generic CDC-NCM devices */  	{ USB_INTERFACE_INFO(USB_CLASS_COMM, diff --git a/drivers/net/usb/dm9601.c b/drivers/net/usb/dm9601.c index 3f554c1149f..d7e99445518 100644 --- a/drivers/net/usb/dm9601.c +++ b/drivers/net/usb/dm9601.c @@ -45,6 +45,12 @@  #define DM_MCAST_ADDR	0x16	/* 8 bytes */  #define DM_GPR_CTRL	0x1e  #define DM_GPR_DATA	0x1f +#define DM_CHIP_ID	0x2c +#define DM_MODE_CTRL	0x91	/* only on dm9620 */ + +/* chip id values */ +#define ID_DM9601	0 +#define ID_DM9620	1  #define DM_MAX_MCAST	64  #define DM_MCAST_SIZE	8 @@ -53,7 +59,6 @@  #define DM_RX_OVERHEAD	7	/* 3 byte header + 4 byte crc tail */  #define DM_TIMEOUT	1000 -  static int dm_read(struct usbnet *dev, u8 reg, u16 length, void *data)  {  	int err; @@ -84,32 +89,23 @@ static int dm_write(struct usbnet *dev, u8 reg, u16 length, void *data)  static int dm_write_reg(struct usbnet *dev, u8 reg, u8 value)  { -	return usbnet_write_cmd(dev, DM_WRITE_REGS, +	return usbnet_write_cmd(dev, DM_WRITE_REG,  				USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,  				value, reg, NULL, 0);  } -static void dm_write_async_helper(struct usbnet *dev, u8 reg, u8 value, -				  u16 length, void *data) +static void dm_write_async(struct usbnet *dev, u8 reg, u16 length, void *data)  {  	usbnet_write_cmd_async(dev, DM_WRITE_REGS,  			       USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, -			       value, reg, data, length); -} - -static void dm_write_async(struct usbnet *dev, u8 reg, u16 length, void *data) -{ -	netdev_dbg(dev->net, "dm_write_async() reg=0x%02x length=%d\n", reg, length); - -	dm_write_async_helper(dev, reg, 0, length, data); +			       0, reg, data, length);  }  static void dm_write_reg_async(struct usbnet *dev, u8 reg, u8 value)  { -	netdev_dbg(dev->net, "dm_write_reg_async() reg=0x%02x value=0x%02x\n", -		   reg, value); - -	dm_write_async_helper(dev, reg, value, 0, NULL); +	usbnet_write_cmd_async(dev, DM_WRITE_REG, +			       USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, +			       value, reg, NULL, 0);  }  static int dm_read_shared_word(struct usbnet *dev, int phy, u8 reg, __le16 *value) @@ -358,7 +354,7 @@ static const struct net_device_ops dm9601_netdev_ops = {  static int dm9601_bind(struct usbnet *dev, struct usb_interface *intf)  {  	int ret; -	u8 mac[ETH_ALEN]; +	u8 mac[ETH_ALEN], id;  	ret = usbnet_get_endpoints(dev, intf);  	if (ret) @@ -399,6 +395,24 @@ static int dm9601_bind(struct usbnet *dev, struct usb_interface *intf)  		__dm9601_set_mac_address(dev);  	} +	if (dm_read_reg(dev, DM_CHIP_ID, &id) < 0) { +		netdev_err(dev->net, "Error reading chip ID\n"); +		ret = -ENODEV; +		goto out; +	} + +	/* put dm9620 devices in dm9601 mode */ +	if (id == ID_DM9620) { +		u8 mode; + +		if (dm_read_reg(dev, DM_MODE_CTRL, &mode) < 0) { +			netdev_err(dev->net, "Error reading MODE_CTRL\n"); +			ret = -ENODEV; +			goto out; +		} +		dm_write_reg(dev, DM_MODE_CTRL, mode & 0x7f); +	} +  	/* power up phy */  	dm_write_reg(dev, DM_GPR_CTRL, 1);  	dm_write_reg(dev, DM_GPR_DATA, 0); @@ -581,6 +595,10 @@ static const struct usb_device_id products[] = {  	 USB_DEVICE(0x0a46, 0x9000),	/* DM9000E */  	 .driver_info = (unsigned long)&dm9601_info,  	 }, +	{ +	 USB_DEVICE(0x0a46, 0x9620),	/* DM9620 USB to Fast Ethernet Adapter */ +	 .driver_info = (unsigned long)&dm9601_info, +	 },  	{},			// END  }; diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index 6a1ca500e61..19d903598b0 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c @@ -351,6 +351,10 @@ static const struct usb_device_id products[] = {  		USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, USB_CLASS_VENDOR_SPEC, 1, 57),  		.driver_info        = (unsigned long)&qmi_wwan_info,  	}, +	{	/* HUAWEI_INTERFACE_NDIS_CONTROL_QUALCOMM */ +		USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, USB_CLASS_VENDOR_SPEC, 0x01, 0x69), +		.driver_info        = (unsigned long)&qmi_wwan_info, +	},  	/* 2. Combined interface devices matching on class+protocol */  	{	/* Huawei E367 and possibly others in "Windows mode" */ @@ -361,6 +365,14 @@ static const struct usb_device_id products[] = {  		USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, USB_CLASS_VENDOR_SPEC, 1, 17),  		.driver_info        = (unsigned long)&qmi_wwan_info,  	}, +	{	/* HUAWEI_NDIS_SINGLE_INTERFACE_VDF */ +		USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, USB_CLASS_VENDOR_SPEC, 0x01, 0x37), +		.driver_info        = (unsigned long)&qmi_wwan_info, +	}, +	{	/* HUAWEI_INTERFACE_NDIS_HW_QUALCOMM */ +		USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, USB_CLASS_VENDOR_SPEC, 0x01, 0x67), +		.driver_info        = (unsigned long)&qmi_wwan_info, +	},  	{	/* Pantech UML290, P4200 and more */  		USB_VENDOR_AND_INTERFACE_INFO(0x106c, USB_CLASS_VENDOR_SPEC, 0xf0, 0xff),  		.driver_info        = (unsigned long)&qmi_wwan_info, @@ -399,6 +411,7 @@ static const struct usb_device_id products[] = {  	},  	/* 3. Combined interface devices matching on interface number */ +	{QMI_FIXED_INTF(0x0408, 0xea42, 4)},	/* Yota / Megafon M100-1 */  	{QMI_FIXED_INTF(0x12d1, 0x140c, 1)},	/* Huawei E173 */  	{QMI_FIXED_INTF(0x19d2, 0x0002, 1)},  	{QMI_FIXED_INTF(0x19d2, 0x0012, 1)}, @@ -433,6 +446,7 @@ static const struct usb_device_id products[] = {  	{QMI_FIXED_INTF(0x19d2, 0x0199, 1)},	/* ZTE MF820S */  	{QMI_FIXED_INTF(0x19d2, 0x0200, 1)},  	{QMI_FIXED_INTF(0x19d2, 0x0257, 3)},	/* ZTE MF821 */ +	{QMI_FIXED_INTF(0x19d2, 0x0265, 4)},	/* ONDA MT8205 4G LTE */  	{QMI_FIXED_INTF(0x19d2, 0x0284, 4)},	/* ZTE MF880 */  	{QMI_FIXED_INTF(0x19d2, 0x0326, 4)},	/* ZTE MF821D */  	{QMI_FIXED_INTF(0x19d2, 0x1008, 4)},	/* ZTE (Vodafone) K3570-Z */ @@ -459,6 +473,8 @@ static const struct usb_device_id products[] = {  	{QMI_FIXED_INTF(0x1199, 0x68a2, 19)},	/* Sierra Wireless MC7710 in QMI mode */  	{QMI_FIXED_INTF(0x1199, 0x901c, 8)},    /* Sierra Wireless EM7700 */  	{QMI_FIXED_INTF(0x1bbb, 0x011e, 4)},	/* Telekom Speedstick LTE II (Alcatel One Touch L100V LTE) */ +	{QMI_FIXED_INTF(0x2357, 0x0201, 4)},	/* TP-LINK HSUPA Modem MA180 */ +	{QMI_FIXED_INTF(0x1bc7, 0x1200, 5)},	/* Telit LE920 */  	/* 4. Gobi 1000 devices */  	{QMI_GOBI1K_DEVICE(0x05c6, 0x9212)},	/* Acer Gobi Modem Device */ diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index 3d4bf01641b..5e33606c136 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -380,6 +380,12 @@ static int rx_submit (struct usbnet *dev, struct urb *urb, gfp_t flags)  	unsigned long		lockflags;  	size_t			size = dev->rx_urb_size; +	/* prevent rx skb allocation when error ratio is high */ +	if (test_bit(EVENT_RX_KILL, &dev->flags)) { +		usb_free_urb(urb); +		return -ENOLINK; +	} +  	skb = __netdev_alloc_skb_ip_align(dev->net, size, flags);  	if (!skb) {  		netif_dbg(dev, rx_err, dev->net, "no rx skb\n"); @@ -539,6 +545,17 @@ block:  		break;  	} +	/* stop rx if packet error rate is high */ +	if (++dev->pkt_cnt > 30) { +		dev->pkt_cnt = 0; +		dev->pkt_err = 0; +	} else { +		if (state == rx_cleanup) +			dev->pkt_err++; +		if (dev->pkt_err > 20) +			set_bit(EVENT_RX_KILL, &dev->flags); +	} +  	state = defer_bh(dev, skb, &dev->rxq, state);  	if (urb) { @@ -791,6 +808,11 @@ int usbnet_open (struct net_device *net)  		   (dev->driver_info->flags & FLAG_FRAMING_AX) ? "ASIX" :  		   "simple"); +	/* reset rx error state */ +	dev->pkt_cnt = 0; +	dev->pkt_err = 0; +	clear_bit(EVENT_RX_KILL, &dev->flags); +  	// delay posting reads until we're fully open  	tasklet_schedule (&dev->bh);  	if (info->manage_power) { @@ -1103,13 +1125,11 @@ netdev_tx_t usbnet_start_xmit (struct sk_buff *skb,  	if (info->tx_fixup) {  		skb = info->tx_fixup (dev, skb, GFP_ATOMIC);  		if (!skb) { -			if (netif_msg_tx_err(dev)) { -				netif_dbg(dev, tx_err, dev->net, "can't tx_fixup skb\n"); -				goto drop; -			} else { -				/* cdc_ncm collected packet; waits for more */ +			/* packet collected; minidriver waiting for more */ +			if (info->flags & FLAG_MULTI_PACKET)  				goto not_drop; -			} +			netif_dbg(dev, tx_err, dev->net, "can't tx_fixup skb\n"); +			goto drop;  		}  	}  	length = skb->len; @@ -1254,6 +1274,9 @@ static void usbnet_bh (unsigned long param)  		}  	} +	/* restart RX again after disabling due to high error rate */ +	clear_bit(EVENT_RX_KILL, &dev->flags); +  	// waiting for all pending urbs to complete?  	if (dev->wait) {  		if ((dev->txq.qlen + dev->rxq.qlen + dev->done.qlen) == 0) { @@ -1448,6 +1471,10 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)  		if ((dev->driver_info->flags & FLAG_WWAN) != 0)  			strcpy(net->name, "wwan%d"); +		/* devices that cannot do ARP */ +		if ((dev->driver_info->flags & FLAG_NOARP) != 0) +			net->flags |= IFF_NOARP; +  		/* maybe the remote can't receive an Ethernet MTU */  		if (net->mtu > (dev->hard_mtu - net->hard_header_len))  			net->mtu = dev->hard_mtu - net->hard_header_len; diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index a6fcf15adc4..35c00c5ea02 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -26,6 +26,7 @@  #include <linux/scatterlist.h>  #include <linux/if_vlan.h>  #include <linux/slab.h> +#include <linux/cpu.h>  static int napi_weight = 128;  module_param(napi_weight, int, 0444); @@ -123,6 +124,12 @@ struct virtnet_info {  	/* Does the affinity hint is set for virtqueues? */  	bool affinity_hint_set; + +	/* Per-cpu variable to show the mapping from CPU to virtqueue */ +	int __percpu *vq_index; + +	/* CPU hot plug notifier */ +	struct notifier_block nb;  };  struct skb_vnet_hdr { @@ -1013,32 +1020,75 @@ static int virtnet_vlan_rx_kill_vid(struct net_device *dev, u16 vid)  	return 0;  } -static void virtnet_set_affinity(struct virtnet_info *vi, bool set) +static void virtnet_clean_affinity(struct virtnet_info *vi, long hcpu)  {  	int i; +	int cpu; + +	if (vi->affinity_hint_set) { +		for (i = 0; i < vi->max_queue_pairs; i++) { +			virtqueue_set_affinity(vi->rq[i].vq, -1); +			virtqueue_set_affinity(vi->sq[i].vq, -1); +		} + +		vi->affinity_hint_set = false; +	} + +	i = 0; +	for_each_online_cpu(cpu) { +		if (cpu == hcpu) { +			*per_cpu_ptr(vi->vq_index, cpu) = -1; +		} else { +			*per_cpu_ptr(vi->vq_index, cpu) = +				++i % vi->curr_queue_pairs; +		} +	} +} + +static void virtnet_set_affinity(struct virtnet_info *vi) +{ +	int i; +	int cpu;  	/* In multiqueue mode, when the number of cpu is equal to the number of  	 * queue pairs, we let the queue pairs to be private to one cpu by  	 * setting the affinity hint to eliminate the contention.  	 */ -	if ((vi->curr_queue_pairs == 1 || -	     vi->max_queue_pairs != num_online_cpus()) && set) { -		if (vi->affinity_hint_set) -			set = false; -		else -			return; +	if (vi->curr_queue_pairs == 1 || +	    vi->max_queue_pairs != num_online_cpus()) { +		virtnet_clean_affinity(vi, -1); +		return;  	} -	for (i = 0; i < vi->max_queue_pairs; i++) { -		int cpu = set ? i : -1; +	i = 0; +	for_each_online_cpu(cpu) {  		virtqueue_set_affinity(vi->rq[i].vq, cpu);  		virtqueue_set_affinity(vi->sq[i].vq, cpu); +		*per_cpu_ptr(vi->vq_index, cpu) = i; +		i++;  	} -	if (set) -		vi->affinity_hint_set = true; -	else -		vi->affinity_hint_set = false; +	vi->affinity_hint_set = true; +} + +static int virtnet_cpu_callback(struct notifier_block *nfb, +			        unsigned long action, void *hcpu) +{ +	struct virtnet_info *vi = container_of(nfb, struct virtnet_info, nb); + +	switch(action & ~CPU_TASKS_FROZEN) { +	case CPU_ONLINE: +	case CPU_DOWN_FAILED: +	case CPU_DEAD: +		virtnet_set_affinity(vi); +		break; +	case CPU_DOWN_PREPARE: +		virtnet_clean_affinity(vi, (long)hcpu); +		break; +	default: +		break; +	} +	return NOTIFY_OK;  }  static void virtnet_get_ringparam(struct net_device *dev, @@ -1082,13 +1132,15 @@ static int virtnet_set_channels(struct net_device *dev,  	if (queue_pairs > vi->max_queue_pairs)  		return -EINVAL; +	get_online_cpus();  	err = virtnet_set_queues(vi, queue_pairs);  	if (!err) {  		netif_set_real_num_tx_queues(dev, queue_pairs);  		netif_set_real_num_rx_queues(dev, queue_pairs); -		virtnet_set_affinity(vi, true); +		virtnet_set_affinity(vi);  	} +	put_online_cpus();  	return err;  } @@ -1127,12 +1179,19 @@ static int virtnet_change_mtu(struct net_device *dev, int new_mtu)  /* To avoid contending a lock hold by a vcpu who would exit to host, select the   * txq based on the processor id. - * TODO: handle cpu hotplug.   */  static u16 virtnet_select_queue(struct net_device *dev, struct sk_buff *skb)  { -	int txq = skb_rx_queue_recorded(skb) ? skb_get_rx_queue(skb) : -		  smp_processor_id(); +	int txq; +	struct virtnet_info *vi = netdev_priv(dev); + +	if (skb_rx_queue_recorded(skb)) { +		txq = skb_get_rx_queue(skb); +	} else { +		txq = *__this_cpu_ptr(vi->vq_index); +		if (txq == -1) +			txq = 0; +	}  	while (unlikely(txq >= dev->real_num_tx_queues))  		txq -= dev->real_num_tx_queues; @@ -1248,7 +1307,7 @@ static void virtnet_del_vqs(struct virtnet_info *vi)  {  	struct virtio_device *vdev = vi->vdev; -	virtnet_set_affinity(vi, false); +	virtnet_clean_affinity(vi, -1);  	vdev->config->del_vqs(vdev); @@ -1371,7 +1430,10 @@ static int init_vqs(struct virtnet_info *vi)  	if (ret)  		goto err_free; -	virtnet_set_affinity(vi, true); +	get_online_cpus(); +	virtnet_set_affinity(vi); +	put_online_cpus(); +  	return 0;  err_free: @@ -1453,6 +1515,10 @@ static int virtnet_probe(struct virtio_device *vdev)  	if (vi->stats == NULL)  		goto free; +	vi->vq_index = alloc_percpu(int); +	if (vi->vq_index == NULL) +		goto free_stats; +  	mutex_init(&vi->config_lock);  	vi->config_enable = true;  	INIT_WORK(&vi->config_work, virtnet_config_changed_work); @@ -1476,7 +1542,7 @@ static int virtnet_probe(struct virtio_device *vdev)  	/* Allocate/initialize the rx/tx queues, and invoke find_vqs */  	err = init_vqs(vi);  	if (err) -		goto free_stats; +		goto free_index;  	netif_set_real_num_tx_queues(dev, 1);  	netif_set_real_num_rx_queues(dev, 1); @@ -1499,6 +1565,13 @@ static int virtnet_probe(struct virtio_device *vdev)  		}  	} +	vi->nb.notifier_call = &virtnet_cpu_callback; +	err = register_hotcpu_notifier(&vi->nb); +	if (err) { +		pr_debug("virtio_net: registering cpu notifier failed\n"); +		goto free_recv_bufs; +	} +  	/* Assume link up if device can't report link status,  	   otherwise get link status from config. */  	if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_STATUS)) { @@ -1520,6 +1593,8 @@ free_recv_bufs:  free_vqs:  	cancel_delayed_work_sync(&vi->refill);  	virtnet_del_vqs(vi); +free_index: +	free_percpu(vi->vq_index);  free_stats:  	free_percpu(vi->stats);  free: @@ -1543,6 +1618,8 @@ static void virtnet_remove(struct virtio_device *vdev)  {  	struct virtnet_info *vi = vdev->priv; +	unregister_hotcpu_notifier(&vi->nb); +  	/* Prevent config work handler from accessing the device. */  	mutex_lock(&vi->config_lock);  	vi->config_enable = false; @@ -1554,6 +1631,7 @@ static void virtnet_remove(struct virtio_device *vdev)  	flush_work(&vi->config_work); +	free_percpu(vi->vq_index);  	free_percpu(vi->stats);  	free_netdev(vi->dev);  } diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c index dc8913c6238..12c6440d164 100644 --- a/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/drivers/net/vmxnet3/vmxnet3_drv.c @@ -154,8 +154,7 @@ vmxnet3_check_link(struct vmxnet3_adapter *adapter, bool affectTxQueue)  	if (ret & 1) { /* Link is up. */  		printk(KERN_INFO "%s: NIC Link is Up %d Mbps\n",  		       adapter->netdev->name, adapter->link_speed); -		if (!netif_carrier_ok(adapter->netdev)) -			netif_carrier_on(adapter->netdev); +		netif_carrier_on(adapter->netdev);  		if (affectTxQueue) {  			for (i = 0; i < adapter->num_tx_queues; i++) @@ -165,8 +164,7 @@ vmxnet3_check_link(struct vmxnet3_adapter *adapter, bool affectTxQueue)  	} else {  		printk(KERN_INFO "%s: NIC Link is Down\n",  		       adapter->netdev->name); -		if (netif_carrier_ok(adapter->netdev)) -			netif_carrier_off(adapter->netdev); +		netif_carrier_off(adapter->netdev);  		if (affectTxQueue) {  			for (i = 0; i < adapter->num_tx_queues; i++) @@ -3061,6 +3059,7 @@ vmxnet3_probe_device(struct pci_dev *pdev,  	netif_set_real_num_tx_queues(adapter->netdev, adapter->num_tx_queues);  	netif_set_real_num_rx_queues(adapter->netdev, adapter->num_rx_queues); +	netif_carrier_off(netdev);  	err = register_netdev(netdev);  	if (err) { diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c index 8b0d8dcd762..56317b0fb6b 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c @@ -976,6 +976,8 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah,  					  AR_PHY_CL_TAB_1,  					  AR_PHY_CL_TAB_2 }; +	ar9003_hw_set_chain_masks(ah, ah->caps.rx_chainmask, ah->caps.tx_chainmask); +  	if (rtt) {  		if (!ar9003_hw_rtt_restore(ah, chan))  			run_rtt_cal = true; diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index ce19c09fa8e..3afc24bde6d 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c @@ -586,32 +586,19 @@ static void ar9003_hw_init_bb(struct ath_hw *ah,  	ath9k_hw_synth_delay(ah, chan, synthDelay);  } -static void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx) +void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx)  { -	switch (rx) { -	case 0x5: +	if (ah->caps.tx_chainmask == 5 || ah->caps.rx_chainmask == 5)  		REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,  			    AR_PHY_SWAP_ALT_CHAIN); -	case 0x3: -	case 0x1: -	case 0x2: -	case 0x7: -		REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx); -		REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx); -		break; -	default: -		break; -	} + +	REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx); +	REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx);  	if ((ah->caps.hw_caps & ATH9K_HW_CAP_APM) && (tx == 0x7)) -		REG_WRITE(ah, AR_SELFGEN_MASK, 0x3); -	else -		REG_WRITE(ah, AR_SELFGEN_MASK, tx); +		tx = 3; -	if (tx == 0x5) { -		REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP, -			    AR_PHY_SWAP_ALT_CHAIN); -	} +	REG_WRITE(ah, AR_SELFGEN_MASK, tx);  }  /* diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 86e26a19efd..42794c546a4 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -317,7 +317,6 @@ struct ath_rx {  	u32 *rxlink;  	u32 num_pkts;  	unsigned int rxfilter; -	spinlock_t rxbuflock;  	struct list_head rxbuf;  	struct ath_descdma rxdma;  	struct ath_buf *rx_bufptr; @@ -328,7 +327,6 @@ struct ath_rx {  int ath_startrecv(struct ath_softc *sc);  bool ath_stoprecv(struct ath_softc *sc); -void ath_flushrecv(struct ath_softc *sc);  u32 ath_calcrxfilter(struct ath_softc *sc);  int ath_rx_init(struct ath_softc *sc, int nbufs);  void ath_rx_cleanup(struct ath_softc *sc); @@ -646,7 +644,6 @@ void ath_ant_comb_update(struct ath_softc *sc);  enum sc_op_flags {  	SC_OP_INVALID,  	SC_OP_BEACONS, -	SC_OP_RXFLUSH,  	SC_OP_ANI_RUN,  	SC_OP_PRIM_STA_VIF,  	SC_OP_HW_RESET, diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index 531fffd801a..2ca355e94da 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c @@ -147,6 +147,7 @@ static struct ath_buf *ath9k_beacon_generate(struct ieee80211_hw *hw,  				 skb->len, DMA_TO_DEVICE);  		dev_kfree_skb_any(skb);  		bf->bf_buf_addr = 0; +		bf->bf_mpdu = NULL;  	}  	skb = ieee80211_beacon_get(hw, vif); @@ -359,7 +360,6 @@ void ath9k_beacon_tasklet(unsigned long data)  		return;  	bf = ath9k_beacon_generate(sc->hw, vif); -	WARN_ON(!bf);  	if (sc->beacon.bmisscnt != 0) {  		ath_dbg(common, BSTUCK, "resume beacon xmit after %u misses\n", diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index 13ff9edc240..e585fc827c5 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c @@ -861,7 +861,6 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf,  	RXS_ERR("RX-LENGTH-ERR", rx_len_err);  	RXS_ERR("RX-OOM-ERR", rx_oom_err);  	RXS_ERR("RX-RATE-ERR", rx_rate_err); -	RXS_ERR("RX-DROP-RXFLUSH", rx_drop_rxflush);  	RXS_ERR("RX-TOO-MANY-FRAGS", rx_too_many_frags_err);  	PHY_ERR("UNDERRUN ERR", ATH9K_PHYERR_UNDERRUN); diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h index 375c3b46411..6df2ab62dcb 100644 --- a/drivers/net/wireless/ath/ath9k/debug.h +++ b/drivers/net/wireless/ath/ath9k/debug.h @@ -216,7 +216,6 @@ struct ath_tx_stats {   * @rx_oom_err:  No. of frames dropped due to OOM issues.   * @rx_rate_err:  No. of frames dropped due to rate errors.   * @rx_too_many_frags_err:  Frames dropped due to too-many-frags received. - * @rx_drop_rxflush: No. of frames dropped due to RX-FLUSH.   * @rx_beacons:  No. of beacons received.   * @rx_frags:  No. of rx-fragements received.   */ @@ -235,7 +234,6 @@ struct ath_rx_stats {  	u32 rx_oom_err;  	u32 rx_rate_err;  	u32 rx_too_many_frags_err; -	u32 rx_drop_rxflush;  	u32 rx_beacons;  	u32 rx_frags;  }; diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.c b/drivers/net/wireless/ath/ath9k/htc_hst.c index 4a9570dfba7..aac4a406a51 100644 --- a/drivers/net/wireless/ath/ath9k/htc_hst.c +++ b/drivers/net/wireless/ath/ath9k/htc_hst.c @@ -344,6 +344,8 @@ void ath9k_htc_txcompletion_cb(struct htc_target *htc_handle,  			endpoint->ep_callbacks.tx(endpoint->ep_callbacks.priv,  						  skb, htc_hdr->endpoint_id,  						  txok); +		} else { +			kfree_skb(skb);  		}  	} diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 7f1a8e91c90..9d26fc56ca5 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -1066,6 +1066,7 @@ void ar9003_paprd_setup_gain_table(struct ath_hw *ah, int chain);  int ar9003_paprd_init_table(struct ath_hw *ah);  bool ar9003_paprd_is_done(struct ath_hw *ah);  bool ar9003_is_paprd_enabled(struct ath_hw *ah); +void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx);  /* Hardware family op attach helpers */  void ar5008_hw_attach_phy_ops(struct ath_hw *ah); diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index be30a9af152..dd91f8fdc01 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -182,7 +182,7 @@ static void ath_restart_work(struct ath_softc *sc)  	ath_start_ani(sc);  } -static bool ath_prepare_reset(struct ath_softc *sc, bool retry_tx, bool flush) +static bool ath_prepare_reset(struct ath_softc *sc, bool retry_tx)  {  	struct ath_hw *ah = sc->sc_ah;  	bool ret = true; @@ -202,14 +202,6 @@ static bool ath_prepare_reset(struct ath_softc *sc, bool retry_tx, bool flush)  	if (!ath_drain_all_txq(sc, retry_tx))  		ret = false; -	if (!flush) { -		if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) -			ath_rx_tasklet(sc, 1, true); -		ath_rx_tasklet(sc, 1, false); -	} else { -		ath_flushrecv(sc); -	} -  	return ret;  } @@ -262,11 +254,11 @@ static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan,  	struct ath_common *common = ath9k_hw_common(ah);  	struct ath9k_hw_cal_data *caldata = NULL;  	bool fastcc = true; -	bool flush = false;  	int r;  	__ath_cancel_work(sc); +	tasklet_disable(&sc->intr_tq);  	spin_lock_bh(&sc->sc_pcu_lock);  	if (!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) { @@ -276,11 +268,10 @@ static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan,  	if (!hchan) {  		fastcc = false; -		flush = true;  		hchan = ah->curchan;  	} -	if (!ath_prepare_reset(sc, retry_tx, flush)) +	if (!ath_prepare_reset(sc, retry_tx))  		fastcc = false;  	ath_dbg(common, CONFIG, "Reset to %u MHz, HT40: %d fastcc: %d\n", @@ -302,6 +293,8 @@ static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan,  out:  	spin_unlock_bh(&sc->sc_pcu_lock); +	tasklet_enable(&sc->intr_tq); +  	return r;  } @@ -804,7 +797,7 @@ static void ath9k_stop(struct ieee80211_hw *hw)  		ath9k_hw_cfg_gpio_input(ah, ah->led_pin);  	} -	ath_prepare_reset(sc, false, true); +	ath_prepare_reset(sc, false);  	if (sc->rx.frag) {  		dev_kfree_skb_any(sc->rx.frag); @@ -1833,6 +1826,9 @@ static u32 fill_chainmask(u32 cap, u32 new)  static bool validate_antenna_mask(struct ath_hw *ah, u32 val)  { +	if (AR_SREV_9300_20_OR_LATER(ah)) +		return true; +  	switch (val & 0x7) {  	case 0x1:  	case 0x3: diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index d4df98a938b..90752f24697 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c @@ -254,8 +254,6 @@ rx_init_fail:  static void ath_edma_start_recv(struct ath_softc *sc)  { -	spin_lock_bh(&sc->rx.rxbuflock); -  	ath9k_hw_rxena(sc->sc_ah);  	ath_rx_addbuffer_edma(sc, ATH9K_RX_QUEUE_HP, @@ -267,8 +265,6 @@ static void ath_edma_start_recv(struct ath_softc *sc)  	ath_opmode_init(sc);  	ath9k_hw_startpcureceive(sc->sc_ah, !!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)); - -	spin_unlock_bh(&sc->rx.rxbuflock);  }  static void ath_edma_stop_recv(struct ath_softc *sc) @@ -285,8 +281,6 @@ int ath_rx_init(struct ath_softc *sc, int nbufs)  	int error = 0;  	spin_lock_init(&sc->sc_pcu_lock); -	spin_lock_init(&sc->rx.rxbuflock); -	clear_bit(SC_OP_RXFLUSH, &sc->sc_flags);  	common->rx_bufsize = IEEE80211_MAX_MPDU_LEN / 2 +  			     sc->sc_ah->caps.rx_status_len; @@ -447,7 +441,6 @@ int ath_startrecv(struct ath_softc *sc)  		return 0;  	} -	spin_lock_bh(&sc->rx.rxbuflock);  	if (list_empty(&sc->rx.rxbuf))  		goto start_recv; @@ -468,26 +461,31 @@ start_recv:  	ath_opmode_init(sc);  	ath9k_hw_startpcureceive(ah, !!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)); -	spin_unlock_bh(&sc->rx.rxbuflock); -  	return 0;  } +static void ath_flushrecv(struct ath_softc *sc) +{ +	if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) +		ath_rx_tasklet(sc, 1, true); +	ath_rx_tasklet(sc, 1, false); +} +  bool ath_stoprecv(struct ath_softc *sc)  {  	struct ath_hw *ah = sc->sc_ah;  	bool stopped, reset = false; -	spin_lock_bh(&sc->rx.rxbuflock);  	ath9k_hw_abortpcurecv(ah);  	ath9k_hw_setrxfilter(ah, 0);  	stopped = ath9k_hw_stopdmarecv(ah, &reset); +	ath_flushrecv(sc); +  	if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)  		ath_edma_stop_recv(sc);  	else  		sc->rx.rxlink = NULL; -	spin_unlock_bh(&sc->rx.rxbuflock);  	if (!(ah->ah_flags & AH_UNPLUGGED) &&  	    unlikely(!stopped)) { @@ -499,15 +497,6 @@ bool ath_stoprecv(struct ath_softc *sc)  	return stopped && !reset;  } -void ath_flushrecv(struct ath_softc *sc) -{ -	set_bit(SC_OP_RXFLUSH, &sc->sc_flags); -	if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) -		ath_rx_tasklet(sc, 1, true); -	ath_rx_tasklet(sc, 1, false); -	clear_bit(SC_OP_RXFLUSH, &sc->sc_flags); -} -  static bool ath_beacon_dtim_pending_cab(struct sk_buff *skb)  {  	/* Check whether the Beacon frame has DTIM indicating buffered bc/mc */ @@ -744,6 +733,7 @@ static struct ath_buf *ath_get_next_rx_buf(struct ath_softc *sc,  			return NULL;  	} +	list_del(&bf->list);  	if (!bf->bf_mpdu)  		return bf; @@ -1059,16 +1049,12 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)  		dma_type = DMA_FROM_DEVICE;  	qtype = hp ? ATH9K_RX_QUEUE_HP : ATH9K_RX_QUEUE_LP; -	spin_lock_bh(&sc->rx.rxbuflock);  	tsf = ath9k_hw_gettsf64(ah);  	tsf_lower = tsf & 0xffffffff;  	do {  		bool decrypt_error = false; -		/* If handling rx interrupt and flush is in progress => exit */ -		if (test_bit(SC_OP_RXFLUSH, &sc->sc_flags) && (flush == 0)) -			break;  		memset(&rs, 0, sizeof(rs));  		if (edma) @@ -1111,15 +1097,6 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)  		ath_debug_stat_rx(sc, &rs); -		/* -		 * If we're asked to flush receive queue, directly -		 * chain it back at the queue without processing it. -		 */ -		if (test_bit(SC_OP_RXFLUSH, &sc->sc_flags)) { -			RX_STAT_INC(rx_drop_rxflush); -			goto requeue_drop_frag; -		} -  		memset(rxs, 0, sizeof(struct ieee80211_rx_status));  		rxs->mactime = (tsf & ~0xffffffffULL) | rs.rs_tstamp; @@ -1254,19 +1231,18 @@ requeue_drop_frag:  			sc->rx.frag = NULL;  		}  requeue: +		list_add_tail(&bf->list, &sc->rx.rxbuf); +		if (flush) +			continue; +  		if (edma) { -			list_add_tail(&bf->list, &sc->rx.rxbuf);  			ath_rx_edma_buf_link(sc, qtype);  		} else { -			list_move_tail(&bf->list, &sc->rx.rxbuf);  			ath_rx_buf_link(sc, bf); -			if (!flush) -				ath9k_hw_rxena(ah); +			ath9k_hw_rxena(ah);  		}  	} while (1); -	spin_unlock_bh(&sc->rx.rxbuflock); -  	if (!(ah->imask & ATH9K_INT_RXEOL)) {  		ah->imask |= (ATH9K_INT_RXEOL | ATH9K_INT_RXORN);  		ath9k_hw_set_interrupts(ah); diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c index 1fbd8ecbe2e..e5fd20994be 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c @@ -36,6 +36,7 @@  #include "debug.h"  #define N_TX_QUEUES	4 /* #tx queues on mac80211<->driver interface */ +#define BRCMS_FLUSH_TIMEOUT	500 /* msec */  /* Flags we support */  #define MAC_FILTERS (FIF_PROMISC_IN_BSS | \ @@ -708,16 +709,29 @@ static void brcms_ops_rfkill_poll(struct ieee80211_hw *hw)  	wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, blocked);  } +static bool brcms_tx_flush_completed(struct brcms_info *wl) +{ +	bool result; + +	spin_lock_bh(&wl->lock); +	result = brcms_c_tx_flush_completed(wl->wlc); +	spin_unlock_bh(&wl->lock); +	return result; +} +  static void brcms_ops_flush(struct ieee80211_hw *hw, bool drop)  {  	struct brcms_info *wl = hw->priv; +	int ret;  	no_printk("%s: drop = %s\n", __func__, drop ? "true" : "false"); -	/* wait for packet queue and dma fifos to run empty */ -	spin_lock_bh(&wl->lock); -	brcms_c_wait_for_tx_completion(wl->wlc, drop); -	spin_unlock_bh(&wl->lock); +	ret = wait_event_timeout(wl->tx_flush_wq, +				 brcms_tx_flush_completed(wl), +				 msecs_to_jiffies(BRCMS_FLUSH_TIMEOUT)); + +	brcms_dbg_mac80211(wl->wlc->hw->d11core, +			   "ret=%d\n", jiffies_to_msecs(ret));  }  static const struct ieee80211_ops brcms_ops = { @@ -772,6 +786,7 @@ void brcms_dpc(unsigned long data)   done:  	spin_unlock_bh(&wl->lock); +	wake_up(&wl->tx_flush_wq);  }  /* @@ -1020,6 +1035,8 @@ static struct brcms_info *brcms_attach(struct bcma_device *pdev)  	atomic_set(&wl->callbacks, 0); +	init_waitqueue_head(&wl->tx_flush_wq); +  	/* setup the bottom half handler */  	tasklet_init(&wl->tasklet, brcms_dpc, (unsigned long) wl); @@ -1407,9 +1424,10 @@ void brcms_add_timer(struct brcms_timer *t, uint ms, int periodic)  #endif  	t->ms = ms;  	t->periodic = (bool) periodic; -	t->set = true; - -	atomic_inc(&t->wl->callbacks); +	if (!t->set) { +		t->set = true; +		atomic_inc(&t->wl->callbacks); +	}  	ieee80211_queue_delayed_work(hw, &t->dly_wrk, msecs_to_jiffies(ms));  } @@ -1608,13 +1626,3 @@ bool brcms_rfkill_set_hw_state(struct brcms_info *wl)  	spin_lock_bh(&wl->lock);  	return blocked;  } - -/* - * precondition: perimeter lock has been acquired - */ -void brcms_msleep(struct brcms_info *wl, uint ms) -{ -	spin_unlock_bh(&wl->lock); -	msleep(ms); -	spin_lock_bh(&wl->lock); -} diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h index 9358bd5ebd3..947ccacf43e 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h @@ -68,6 +68,8 @@ struct brcms_info {  	spinlock_t lock;	/* per-device perimeter lock */  	spinlock_t isr_lock;	/* per-device ISR synchronization lock */ +	/* tx flush */ +	wait_queue_head_t tx_flush_wq;  	/* timer related fields */  	atomic_t callbacks;	/* # outstanding callback functions */ @@ -100,7 +102,6 @@ extern struct brcms_timer *brcms_init_timer(struct brcms_info *wl,  extern void brcms_free_timer(struct brcms_timer *timer);  extern void brcms_add_timer(struct brcms_timer *timer, uint ms, int periodic);  extern bool brcms_del_timer(struct brcms_timer *timer); -extern void brcms_msleep(struct brcms_info *wl, uint ms);  extern void brcms_dpc(unsigned long data);  extern void brcms_timer(struct brcms_timer *t);  extern void brcms_fatal_error(struct brcms_info *wl); diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c index 17594de4199..8b5839008af 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/main.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c @@ -1027,7 +1027,6 @@ brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs)  static bool  brcms_b_txstatus(struct brcms_hardware *wlc_hw, bool bound, bool *fatal)  { -	bool morepending = false;  	struct bcma_device *core;  	struct tx_status txstatus, *txs;  	u32 s1, s2; @@ -1041,23 +1040,20 @@ brcms_b_txstatus(struct brcms_hardware *wlc_hw, bool bound, bool *fatal)  	txs = &txstatus;  	core = wlc_hw->d11core;  	*fatal = false; -	s1 = bcma_read32(core, D11REGOFFS(frmtxstatus)); -	while (!(*fatal) -	       && (s1 & TXS_V)) { -		/* !give others some time to run! */ -		if (n >= max_tx_num) { -			morepending = true; -			break; -		} +	while (n < max_tx_num) { +		s1 = bcma_read32(core, D11REGOFFS(frmtxstatus));  		if (s1 == 0xffffffff) {  			brcms_err(core, "wl%d: %s: dead chip\n", wlc_hw->unit,  				  __func__);  			*fatal = true;  			return false;  		} -		s2 = bcma_read32(core, D11REGOFFS(frmtxstatus2)); +		/* only process when valid */ +		if (!(s1 & TXS_V)) +			break; +		s2 = bcma_read32(core, D11REGOFFS(frmtxstatus2));  		txs->status = s1 & TXS_STATUS_MASK;  		txs->frameid = (s1 & TXS_FID_MASK) >> TXS_FID_SHIFT;  		txs->sequence = s2 & TXS_SEQ_MASK; @@ -1065,15 +1061,12 @@ brcms_b_txstatus(struct brcms_hardware *wlc_hw, bool bound, bool *fatal)  		txs->lasttxtime = 0;  		*fatal = brcms_c_dotxstatus(wlc_hw->wlc, txs); - -		s1 = bcma_read32(core, D11REGOFFS(frmtxstatus)); +		if (*fatal == true) +			return false;  		n++;  	} -	if (*fatal) -		return false; - -	return morepending; +	return n >= max_tx_num;  }  static void brcms_c_tbtt(struct brcms_c_info *wlc) @@ -7518,25 +7511,16 @@ int brcms_c_get_curband(struct brcms_c_info *wlc)  	return wlc->band->bandunit;  } -void brcms_c_wait_for_tx_completion(struct brcms_c_info *wlc, bool drop) +bool brcms_c_tx_flush_completed(struct brcms_c_info *wlc)  { -	int timeout = 20;  	int i;  	/* Kick DMA to send any pending AMPDU */  	for (i = 0; i < ARRAY_SIZE(wlc->hw->di); i++)  		if (wlc->hw->di[i]) -			dma_txflush(wlc->hw->di[i]); - -	/* wait for queue and DMA fifos to run dry */ -	while (brcms_txpktpendtot(wlc) > 0) { -		brcms_msleep(wlc->wl, 1); - -		if (--timeout == 0) -			break; -	} +			dma_kick_tx(wlc->hw->di[i]); -	WARN_ON_ONCE(timeout == 0); +	return !brcms_txpktpendtot(wlc);  }  void brcms_c_set_beacon_listen_interval(struct brcms_c_info *wlc, u8 interval) diff --git a/drivers/net/wireless/brcm80211/brcmsmac/pub.h b/drivers/net/wireless/brcm80211/brcmsmac/pub.h index 4fb2834f4e6..b0f14b7b861 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/pub.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/pub.h @@ -314,8 +314,6 @@ extern void brcms_c_associate_upd(struct brcms_c_info *wlc, bool state);  extern void brcms_c_scan_start(struct brcms_c_info *wlc);  extern void brcms_c_scan_stop(struct brcms_c_info *wlc);  extern int brcms_c_get_curband(struct brcms_c_info *wlc); -extern void brcms_c_wait_for_tx_completion(struct brcms_c_info *wlc, -					   bool drop);  extern int brcms_c_set_channel(struct brcms_c_info *wlc, u16 channel);  extern int brcms_c_set_rate_limit(struct brcms_c_info *wlc, u16 srl, u16 lrl);  extern void brcms_c_get_current_rateset(struct brcms_c_info *wlc, @@ -332,5 +330,6 @@ extern int brcms_c_set_tx_power(struct brcms_c_info *wlc, int txpwr);  extern int brcms_c_get_tx_power(struct brcms_c_info *wlc);  extern bool brcms_c_check_radio_disabled(struct brcms_c_info *wlc);  extern void brcms_c_mute(struct brcms_c_info *wlc, bool on); +extern bool brcms_c_tx_flush_completed(struct brcms_c_info *wlc);  #endif				/* _BRCM_PUB_H_ */ diff --git a/drivers/net/wireless/iwlegacy/common.c b/drivers/net/wireless/iwlegacy/common.c index 7e16d10a7f1..90b8970eadf 100644 --- a/drivers/net/wireless/iwlegacy/common.c +++ b/drivers/net/wireless/iwlegacy/common.c @@ -3958,17 +3958,21 @@ il_connection_init_rx_config(struct il_priv *il)  	memset(&il->staging, 0, sizeof(il->staging)); -	if (!il->vif) { +	switch (il->iw_mode) { +	case NL80211_IFTYPE_UNSPECIFIED:  		il->staging.dev_type = RXON_DEV_TYPE_ESS; -	} else if (il->vif->type == NL80211_IFTYPE_STATION) { +		break; +	case NL80211_IFTYPE_STATION:  		il->staging.dev_type = RXON_DEV_TYPE_ESS;  		il->staging.filter_flags = RXON_FILTER_ACCEPT_GRP_MSK; -	} else if (il->vif->type == NL80211_IFTYPE_ADHOC) { +		break; +	case NL80211_IFTYPE_ADHOC:  		il->staging.dev_type = RXON_DEV_TYPE_IBSS;  		il->staging.flags = RXON_FLG_SHORT_PREAMBLE_MSK;  		il->staging.filter_flags =  		    RXON_FILTER_BCON_AWARE_MSK | RXON_FILTER_ACCEPT_GRP_MSK; -	} else { +		break; +	default:  		IL_ERR("Unsupported interface type %d\n", il->vif->type);  		return;  	} @@ -4550,8 +4554,7 @@ out:  EXPORT_SYMBOL(il_mac_add_interface);  static void -il_teardown_interface(struct il_priv *il, struct ieee80211_vif *vif, -		      bool mode_change) +il_teardown_interface(struct il_priv *il, struct ieee80211_vif *vif)  {  	lockdep_assert_held(&il->mutex); @@ -4560,9 +4563,7 @@ il_teardown_interface(struct il_priv *il, struct ieee80211_vif *vif,  		il_force_scan_end(il);  	} -	if (!mode_change) -		il_set_mode(il); - +	il_set_mode(il);  }  void @@ -4575,8 +4576,8 @@ il_mac_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)  	WARN_ON(il->vif != vif);  	il->vif = NULL; - -	il_teardown_interface(il, vif, false); +	il->iw_mode = NL80211_IFTYPE_UNSPECIFIED; +	il_teardown_interface(il, vif);  	memset(il->bssid, 0, ETH_ALEN);  	D_MAC80211("leave\n"); @@ -4685,18 +4686,10 @@ il_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,  	}  	/* success */ -	il_teardown_interface(il, vif, true);  	vif->type = newtype;  	vif->p2p = false; -	err = il_set_mode(il); -	WARN_ON(err); -	/* -	 * We've switched internally, but submitting to the -	 * device may have failed for some reason. Mask this -	 * error, because otherwise mac80211 will not switch -	 * (and set the interface type back) and we'll be -	 * out of sync with it. -	 */ +	il->iw_mode = newtype; +	il_teardown_interface(il, vif);  	err = 0;  out: diff --git a/drivers/net/wireless/iwlwifi/dvm/tx.c b/drivers/net/wireless/iwlwifi/dvm/tx.c index a790599fe2c..279796419ea 100644 --- a/drivers/net/wireless/iwlwifi/dvm/tx.c +++ b/drivers/net/wireless/iwlwifi/dvm/tx.c @@ -1079,6 +1079,8 @@ static void iwlagn_set_tx_status(struct iwl_priv *priv,  {  	u16 status = le16_to_cpu(tx_resp->status.status); +	info->flags &= ~IEEE80211_TX_CTL_AMPDU; +  	info->status.rates[0].count = tx_resp->failure_frame + 1;  	info->flags |= iwl_tx_status_to_mac80211(status);  	iwlagn_hwrate_to_tx_control(priv, le32_to_cpu(tx_resp->rate_n_flags), @@ -1151,6 +1153,13 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb,  			next_reclaimed = ssn;  		} +		if (tid != IWL_TID_NON_QOS) { +			priv->tid_data[sta_id][tid].next_reclaimed = +				next_reclaimed; +			IWL_DEBUG_TX_REPLY(priv, "Next reclaimed packet:%d\n", +						  next_reclaimed); +		} +  		iwl_trans_reclaim(priv->trans, txq_id, ssn, &skbs);  		iwlagn_check_ratid_empty(priv, sta_id, tid); @@ -1201,28 +1210,11 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb,  			if (!is_agg)  				iwlagn_non_agg_tx_status(priv, ctx, hdr->addr1); -			/* -			 * W/A for FW bug - the seq_ctl isn't updated when the -			 * queues are flushed. Fetch it from the packet itself -			 */ -			if (!is_agg && status == TX_STATUS_FAIL_FIFO_FLUSHED) { -				next_reclaimed = le16_to_cpu(hdr->seq_ctrl); -				next_reclaimed = -					SEQ_TO_SN(next_reclaimed + 0x10); -			} -  			is_offchannel_skb =  				(info->flags & IEEE80211_TX_CTL_TX_OFFCHAN);  			freed++;  		} -		if (tid != IWL_TID_NON_QOS) { -			priv->tid_data[sta_id][tid].next_reclaimed = -				next_reclaimed; -			IWL_DEBUG_TX_REPLY(priv, "Next reclaimed packet:%d\n", -					   next_reclaimed); -		} -  		WARN_ON(!is_agg && freed != 1);  		/* diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index efe525be27d..cdb11b3964e 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -1459,7 +1459,7 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid,  	struct cfg80211_ssid req_ssid;  	int ret, auth_type = 0;  	struct cfg80211_bss *bss = NULL; -	u8 is_scanning_required = 0, config_bands = 0; +	u8 is_scanning_required = 0;  	memset(&req_ssid, 0, sizeof(struct cfg80211_ssid)); @@ -1478,19 +1478,6 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid,  	/* disconnect before try to associate */  	mwifiex_deauthenticate(priv, NULL); -	if (channel) { -		if (mode == NL80211_IFTYPE_STATION) { -			if (channel->band == IEEE80211_BAND_2GHZ) -				config_bands = BAND_B | BAND_G | BAND_GN; -			else -				config_bands = BAND_A | BAND_AN; - -			if (!((config_bands | priv->adapter->fw_bands) & -			      ~priv->adapter->fw_bands)) -				priv->adapter->config_bands = config_bands; -		} -	} -  	/* As this is new association, clear locally stored  	 * keys and security related flags */  	priv->sec_info.wpa_enabled = false; @@ -1707,7 +1694,7 @@ static int mwifiex_set_ibss_params(struct mwifiex_private *priv,  		if (cfg80211_get_chandef_type(¶ms->chandef) !=  						NL80211_CHAN_NO_HT) -			config_bands |= BAND_GN; +			config_bands |= BAND_G | BAND_GN;  	} else {  		if (cfg80211_get_chandef_type(¶ms->chandef) ==  						NL80211_CHAN_NO_HT) diff --git a/drivers/net/wireless/mwifiex/pcie.c b/drivers/net/wireless/mwifiex/pcie.c index 13fbc4eb159..b879e1338a5 100644 --- a/drivers/net/wireless/mwifiex/pcie.c +++ b/drivers/net/wireless/mwifiex/pcie.c @@ -161,7 +161,7 @@ static int mwifiex_pcie_suspend(struct pci_dev *pdev, pm_message_t state)  	if (pdev) {  		card = (struct pcie_service_card *) pci_get_drvdata(pdev); -		if (!card || card->adapter) { +		if (!card || !card->adapter) {  			pr_err("Card or adapter structure is not valid\n");  			return 0;  		} diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c index 9189a32b784..973a9d90e9e 100644 --- a/drivers/net/wireless/mwifiex/scan.c +++ b/drivers/net/wireless/mwifiex/scan.c @@ -1563,7 +1563,7 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,  		dev_err(adapter->dev, "SCAN_RESP: too many AP returned (%d)\n",  			scan_rsp->number_of_sets);  		ret = -1; -		goto done; +		goto check_next_scan;  	}  	bytes_left = le16_to_cpu(scan_rsp->bss_descript_size); @@ -1634,7 +1634,8 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,  		if (!beacon_size || beacon_size > bytes_left) {  			bss_info += bytes_left;  			bytes_left = 0; -			return -1; +			ret = -1; +			goto check_next_scan;  		}  		/* Initialize the current working beacon pointer for this BSS @@ -1690,7 +1691,7 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,  				dev_err(priv->adapter->dev,  					"%s: bytes left < IE length\n",  					__func__); -				goto done; +				goto check_next_scan;  			}  			if (element_id == WLAN_EID_DS_PARAMS) {  				channel = *(current_ptr + sizeof(struct ieee_types_header)); @@ -1753,6 +1754,7 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,  		}  	} +check_next_scan:  	spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);  	if (list_empty(&adapter->scan_pending_q)) {  		spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags); @@ -1813,7 +1815,6 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,  		}  	} -done:  	return ret;  } diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c index 60e88b58039..f542bb8ccbc 100644 --- a/drivers/net/wireless/mwifiex/sta_ioctl.c +++ b/drivers/net/wireless/mwifiex/sta_ioctl.c @@ -283,6 +283,20 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss,  		if (ret)  			goto done; +		if (bss_desc) { +			u8 config_bands = 0; + +			if (mwifiex_band_to_radio_type((u8) bss_desc->bss_band) +			    == HostCmd_SCAN_RADIO_TYPE_BG) +				config_bands = BAND_B | BAND_G | BAND_GN; +			else +				config_bands = BAND_A | BAND_AN; + +			if (!((config_bands | adapter->fw_bands) & +			      ~adapter->fw_bands)) +				adapter->config_bands = config_bands; +		} +  		ret = mwifiex_check_network_compatibility(priv, bss_desc);  		if (ret)  			goto done; diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index 83564d36e80..a00a03ea4ec 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c @@ -318,20 +318,20 @@ struct mwl8k_sta {  #define MWL8K_STA(_sta) ((struct mwl8k_sta *)&((_sta)->drv_priv))  static const struct ieee80211_channel mwl8k_channels_24[] = { -	{ .center_freq = 2412, .hw_value = 1, }, -	{ .center_freq = 2417, .hw_value = 2, }, -	{ .center_freq = 2422, .hw_value = 3, }, -	{ .center_freq = 2427, .hw_value = 4, }, -	{ .center_freq = 2432, .hw_value = 5, }, -	{ .center_freq = 2437, .hw_value = 6, }, -	{ .center_freq = 2442, .hw_value = 7, }, -	{ .center_freq = 2447, .hw_value = 8, }, -	{ .center_freq = 2452, .hw_value = 9, }, -	{ .center_freq = 2457, .hw_value = 10, }, -	{ .center_freq = 2462, .hw_value = 11, }, -	{ .center_freq = 2467, .hw_value = 12, }, -	{ .center_freq = 2472, .hw_value = 13, }, -	{ .center_freq = 2484, .hw_value = 14, }, +	{ .band = IEEE80211_BAND_2GHZ, .center_freq = 2412, .hw_value = 1, }, +	{ .band = IEEE80211_BAND_2GHZ, .center_freq = 2417, .hw_value = 2, }, +	{ .band = IEEE80211_BAND_2GHZ, .center_freq = 2422, .hw_value = 3, }, +	{ .band = IEEE80211_BAND_2GHZ, .center_freq = 2427, .hw_value = 4, }, +	{ .band = IEEE80211_BAND_2GHZ, .center_freq = 2432, .hw_value = 5, }, +	{ .band = IEEE80211_BAND_2GHZ, .center_freq = 2437, .hw_value = 6, }, +	{ .band = IEEE80211_BAND_2GHZ, .center_freq = 2442, .hw_value = 7, }, +	{ .band = IEEE80211_BAND_2GHZ, .center_freq = 2447, .hw_value = 8, }, +	{ .band = IEEE80211_BAND_2GHZ, .center_freq = 2452, .hw_value = 9, }, +	{ .band = IEEE80211_BAND_2GHZ, .center_freq = 2457, .hw_value = 10, }, +	{ .band = IEEE80211_BAND_2GHZ, .center_freq = 2462, .hw_value = 11, }, +	{ .band = IEEE80211_BAND_2GHZ, .center_freq = 2467, .hw_value = 12, }, +	{ .band = IEEE80211_BAND_2GHZ, .center_freq = 2472, .hw_value = 13, }, +	{ .band = IEEE80211_BAND_2GHZ, .center_freq = 2484, .hw_value = 14, },  };  static const struct ieee80211_rate mwl8k_rates_24[] = { @@ -352,10 +352,10 @@ static const struct ieee80211_rate mwl8k_rates_24[] = {  };  static const struct ieee80211_channel mwl8k_channels_50[] = { -	{ .center_freq = 5180, .hw_value = 36, }, -	{ .center_freq = 5200, .hw_value = 40, }, -	{ .center_freq = 5220, .hw_value = 44, }, -	{ .center_freq = 5240, .hw_value = 48, }, +	{ .band = IEEE80211_BAND_5GHZ, .center_freq = 5180, .hw_value = 36, }, +	{ .band = IEEE80211_BAND_5GHZ, .center_freq = 5200, .hw_value = 40, }, +	{ .band = IEEE80211_BAND_5GHZ, .center_freq = 5220, .hw_value = 44, }, +	{ .band = IEEE80211_BAND_5GHZ, .center_freq = 5240, .hw_value = 48, },  };  static const struct ieee80211_rate mwl8k_rates_50[] = { diff --git a/drivers/net/wireless/rtlwifi/Kconfig b/drivers/net/wireless/rtlwifi/Kconfig index 21b1bbb93a7..b80bc461258 100644 --- a/drivers/net/wireless/rtlwifi/Kconfig +++ b/drivers/net/wireless/rtlwifi/Kconfig @@ -57,12 +57,12 @@ config RTL8192CU  config RTLWIFI  	tristate -	depends on RTL8192CE || RTL8192CU || RTL8192SE || RTL8192DE +	depends on RTL8192CE || RTL8192CU || RTL8192SE || RTL8192DE || RTL8723AE  	default m  config RTLWIFI_DEBUG  	bool "Additional debugging output" -	depends on RTL8192CE || RTL8192CU || RTL8192SE || RTL8192DE +	depends on RTL8192CE || RTL8192CU || RTL8192SE || RTL8192DE || RTL8723AE  	default y  config RTL8192C_COMMON diff --git a/drivers/net/wireless/rtlwifi/base.c b/drivers/net/wireless/rtlwifi/base.c index 4494d130b37..0f8b05185ed 100644 --- a/drivers/net/wireless/rtlwifi/base.c +++ b/drivers/net/wireless/rtlwifi/base.c @@ -1004,7 +1004,8 @@ u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx)  					 is_tx ? "Tx" : "Rx");  				if (is_tx) { -					rtl_lps_leave(hw); +					schedule_work(&rtlpriv-> +						      works.lps_leave_work);  					ppsc->last_delaylps_stamp_jiffies =  					    jiffies;  				} @@ -1014,7 +1015,7 @@ u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx)  		}  	} else if (ETH_P_ARP == ether_type) {  		if (is_tx) { -			rtl_lps_leave(hw); +			schedule_work(&rtlpriv->works.lps_leave_work);  			ppsc->last_delaylps_stamp_jiffies = jiffies;  		} @@ -1024,7 +1025,7 @@ u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx)  			 "802.1X %s EAPOL pkt!!\n", is_tx ? "Tx" : "Rx");  		if (is_tx) { -			rtl_lps_leave(hw); +			schedule_work(&rtlpriv->works.lps_leave_work);  			ppsc->last_delaylps_stamp_jiffies = jiffies;  		} diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c index f2ecdeb3a90..1535efda3d5 100644 --- a/drivers/net/wireless/rtlwifi/usb.c +++ b/drivers/net/wireless/rtlwifi/usb.c @@ -542,8 +542,8 @@ static void _rtl_rx_pre_process(struct ieee80211_hw *hw, struct sk_buff *skb)  	WARN_ON(skb_queue_empty(&rx_queue));  	while (!skb_queue_empty(&rx_queue)) {  		_skb = skb_dequeue(&rx_queue); -		_rtl_usb_rx_process_agg(hw, skb); -		ieee80211_rx_irqsafe(hw, skb); +		_rtl_usb_rx_process_agg(hw, _skb); +		ieee80211_rx_irqsafe(hw, _skb);  	}  } diff --git a/drivers/net/xen-netback/common.h b/drivers/net/xen-netback/common.h index 94b79c3338c..9d7f1723dd8 100644 --- a/drivers/net/xen-netback/common.h +++ b/drivers/net/xen-netback/common.h @@ -151,6 +151,9 @@ void xen_netbk_queue_tx_skb(struct xenvif *vif, struct sk_buff *skb);  /* Notify xenvif that ring now has space to send an skb to the frontend */  void xenvif_notify_tx_completion(struct xenvif *vif); +/* Prevent the device from generating any further traffic. */ +void xenvif_carrier_off(struct xenvif *vif); +  /* Returns number of ring slots required to send an skb to the frontend */  unsigned int xen_netbk_count_skb_slots(struct xenvif *vif, struct sk_buff *skb); diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c index b7d41f8c338..b8c5193bd42 100644 --- a/drivers/net/xen-netback/interface.c +++ b/drivers/net/xen-netback/interface.c @@ -343,17 +343,22 @@ err:  	return err;  } -void xenvif_disconnect(struct xenvif *vif) +void xenvif_carrier_off(struct xenvif *vif)  {  	struct net_device *dev = vif->dev; -	if (netif_carrier_ok(dev)) { -		rtnl_lock(); -		netif_carrier_off(dev); /* discard queued packets */ -		if (netif_running(dev)) -			xenvif_down(vif); -		rtnl_unlock(); -		xenvif_put(vif); -	} + +	rtnl_lock(); +	netif_carrier_off(dev); /* discard queued packets */ +	if (netif_running(dev)) +		xenvif_down(vif); +	rtnl_unlock(); +	xenvif_put(vif); +} + +void xenvif_disconnect(struct xenvif *vif) +{ +	if (netif_carrier_ok(vif->dev)) +		xenvif_carrier_off(vif);  	atomic_dec(&vif->refcnt);  	wait_event(vif->waiting_to_free, atomic_read(&vif->refcnt) == 0); diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c index f2d6b78d901..2b9520c46e9 100644 --- a/drivers/net/xen-netback/netback.c +++ b/drivers/net/xen-netback/netback.c @@ -147,7 +147,8 @@ void xen_netbk_remove_xenvif(struct xenvif *vif)  	atomic_dec(&netbk->netfront_count);  } -static void xen_netbk_idx_release(struct xen_netbk *netbk, u16 pending_idx); +static void xen_netbk_idx_release(struct xen_netbk *netbk, u16 pending_idx, +				  u8 status);  static void make_tx_response(struct xenvif *vif,  			     struct xen_netif_tx_request *txp,  			     s8       st); @@ -879,7 +880,7 @@ static void netbk_tx_err(struct xenvif *vif,  	do {  		make_tx_response(vif, txp, XEN_NETIF_RSP_ERROR); -		if (cons >= end) +		if (cons == end)  			break;  		txp = RING_GET_REQUEST(&vif->tx, cons++);  	} while (1); @@ -888,6 +889,13 @@ static void netbk_tx_err(struct xenvif *vif,  	xenvif_put(vif);  } +static void netbk_fatal_tx_err(struct xenvif *vif) +{ +	netdev_err(vif->dev, "fatal error; disabling device\n"); +	xenvif_carrier_off(vif); +	xenvif_put(vif); +} +  static int netbk_count_requests(struct xenvif *vif,  				struct xen_netif_tx_request *first,  				struct xen_netif_tx_request *txp, @@ -901,19 +909,22 @@ static int netbk_count_requests(struct xenvif *vif,  	do {  		if (frags >= work_to_do) { -			netdev_dbg(vif->dev, "Need more frags\n"); +			netdev_err(vif->dev, "Need more frags\n"); +			netbk_fatal_tx_err(vif);  			return -frags;  		}  		if (unlikely(frags >= MAX_SKB_FRAGS)) { -			netdev_dbg(vif->dev, "Too many frags\n"); +			netdev_err(vif->dev, "Too many frags\n"); +			netbk_fatal_tx_err(vif);  			return -frags;  		}  		memcpy(txp, RING_GET_REQUEST(&vif->tx, cons + frags),  		       sizeof(*txp));  		if (txp->size > first->size) { -			netdev_dbg(vif->dev, "Frags galore\n"); +			netdev_err(vif->dev, "Frag is bigger than frame.\n"); +			netbk_fatal_tx_err(vif);  			return -frags;  		} @@ -921,8 +932,9 @@ static int netbk_count_requests(struct xenvif *vif,  		frags++;  		if (unlikely((txp->offset + txp->size) > PAGE_SIZE)) { -			netdev_dbg(vif->dev, "txp->offset: %x, size: %u\n", +			netdev_err(vif->dev, "txp->offset: %x, size: %u\n",  				 txp->offset, txp->size); +			netbk_fatal_tx_err(vif);  			return -frags;  		}  	} while ((txp++)->flags & XEN_NETTXF_more_data); @@ -966,7 +978,7 @@ static struct gnttab_copy *xen_netbk_get_requests(struct xen_netbk *netbk,  		pending_idx = netbk->pending_ring[index];  		page = xen_netbk_alloc_page(netbk, skb, pending_idx);  		if (!page) -			return NULL; +			goto err;  		gop->source.u.ref = txp->gref;  		gop->source.domid = vif->domid; @@ -988,6 +1000,17 @@ static struct gnttab_copy *xen_netbk_get_requests(struct xen_netbk *netbk,  	}  	return gop; +err: +	/* Unwind, freeing all pages and sending error responses. */ +	while (i-- > start) { +		xen_netbk_idx_release(netbk, frag_get_pending_idx(&frags[i]), +				      XEN_NETIF_RSP_ERROR); +	} +	/* The head too, if necessary. */ +	if (start) +		xen_netbk_idx_release(netbk, pending_idx, XEN_NETIF_RSP_ERROR); + +	return NULL;  }  static int xen_netbk_tx_check_gop(struct xen_netbk *netbk, @@ -996,30 +1019,20 @@ static int xen_netbk_tx_check_gop(struct xen_netbk *netbk,  {  	struct gnttab_copy *gop = *gopp;  	u16 pending_idx = *((u16 *)skb->data); -	struct pending_tx_info *pending_tx_info = netbk->pending_tx_info; -	struct xenvif *vif = pending_tx_info[pending_idx].vif; -	struct xen_netif_tx_request *txp;  	struct skb_shared_info *shinfo = skb_shinfo(skb);  	int nr_frags = shinfo->nr_frags;  	int i, err, start;  	/* Check status of header. */  	err = gop->status; -	if (unlikely(err)) { -		pending_ring_idx_t index; -		index = pending_index(netbk->pending_prod++); -		txp = &pending_tx_info[pending_idx].req; -		make_tx_response(vif, txp, XEN_NETIF_RSP_ERROR); -		netbk->pending_ring[index] = pending_idx; -		xenvif_put(vif); -	} +	if (unlikely(err)) +		xen_netbk_idx_release(netbk, pending_idx, XEN_NETIF_RSP_ERROR);  	/* Skip first skb fragment if it is on same page as header fragment. */  	start = (frag_get_pending_idx(&shinfo->frags[0]) == pending_idx);  	for (i = start; i < nr_frags; i++) {  		int j, newerr; -		pending_ring_idx_t index;  		pending_idx = frag_get_pending_idx(&shinfo->frags[i]); @@ -1028,16 +1041,12 @@ static int xen_netbk_tx_check_gop(struct xen_netbk *netbk,  		if (likely(!newerr)) {  			/* Had a previous error? Invalidate this fragment. */  			if (unlikely(err)) -				xen_netbk_idx_release(netbk, pending_idx); +				xen_netbk_idx_release(netbk, pending_idx, XEN_NETIF_RSP_OKAY);  			continue;  		}  		/* Error on this fragment: respond to client with an error. */ -		txp = &netbk->pending_tx_info[pending_idx].req; -		make_tx_response(vif, txp, XEN_NETIF_RSP_ERROR); -		index = pending_index(netbk->pending_prod++); -		netbk->pending_ring[index] = pending_idx; -		xenvif_put(vif); +		xen_netbk_idx_release(netbk, pending_idx, XEN_NETIF_RSP_ERROR);  		/* Not the first error? Preceding frags already invalidated. */  		if (err) @@ -1045,10 +1054,10 @@ static int xen_netbk_tx_check_gop(struct xen_netbk *netbk,  		/* First error: invalidate header and preceding fragments. */  		pending_idx = *((u16 *)skb->data); -		xen_netbk_idx_release(netbk, pending_idx); +		xen_netbk_idx_release(netbk, pending_idx, XEN_NETIF_RSP_OKAY);  		for (j = start; j < i; j++) {  			pending_idx = frag_get_pending_idx(&shinfo->frags[j]); -			xen_netbk_idx_release(netbk, pending_idx); +			xen_netbk_idx_release(netbk, pending_idx, XEN_NETIF_RSP_OKAY);  		}  		/* Remember the error: invalidate all subsequent fragments. */ @@ -1082,7 +1091,7 @@ static void xen_netbk_fill_frags(struct xen_netbk *netbk, struct sk_buff *skb)  		/* Take an extra reference to offset xen_netbk_idx_release */  		get_page(netbk->mmap_pages[pending_idx]); -		xen_netbk_idx_release(netbk, pending_idx); +		xen_netbk_idx_release(netbk, pending_idx, XEN_NETIF_RSP_OKAY);  	}  } @@ -1095,7 +1104,8 @@ static int xen_netbk_get_extras(struct xenvif *vif,  	do {  		if (unlikely(work_to_do-- <= 0)) { -			netdev_dbg(vif->dev, "Missing extra info\n"); +			netdev_err(vif->dev, "Missing extra info\n"); +			netbk_fatal_tx_err(vif);  			return -EBADR;  		} @@ -1104,8 +1114,9 @@ static int xen_netbk_get_extras(struct xenvif *vif,  		if (unlikely(!extra.type ||  			     extra.type >= XEN_NETIF_EXTRA_TYPE_MAX)) {  			vif->tx.req_cons = ++cons; -			netdev_dbg(vif->dev, +			netdev_err(vif->dev,  				   "Invalid extra type: %d\n", extra.type); +			netbk_fatal_tx_err(vif);  			return -EINVAL;  		} @@ -1121,13 +1132,15 @@ static int netbk_set_skb_gso(struct xenvif *vif,  			     struct xen_netif_extra_info *gso)  {  	if (!gso->u.gso.size) { -		netdev_dbg(vif->dev, "GSO size must not be zero.\n"); +		netdev_err(vif->dev, "GSO size must not be zero.\n"); +		netbk_fatal_tx_err(vif);  		return -EINVAL;  	}  	/* Currently only TCPv4 S.O. is supported. */  	if (gso->u.gso.type != XEN_NETIF_GSO_TYPE_TCPV4) { -		netdev_dbg(vif->dev, "Bad GSO type %d.\n", gso->u.gso.type); +		netdev_err(vif->dev, "Bad GSO type %d.\n", gso->u.gso.type); +		netbk_fatal_tx_err(vif);  		return -EINVAL;  	} @@ -1264,9 +1277,25 @@ static unsigned xen_netbk_tx_build_gops(struct xen_netbk *netbk)  		/* Get a netif from the list with work to do. */  		vif = poll_net_schedule_list(netbk); +		/* This can sometimes happen because the test of +		 * list_empty(net_schedule_list) at the top of the +		 * loop is unlocked.  Just go back and have another +		 * look. +		 */  		if (!vif)  			continue; +		if (vif->tx.sring->req_prod - vif->tx.req_cons > +		    XEN_NETIF_TX_RING_SIZE) { +			netdev_err(vif->dev, +				   "Impossible number of requests. " +				   "req_prod %d, req_cons %d, size %ld\n", +				   vif->tx.sring->req_prod, vif->tx.req_cons, +				   XEN_NETIF_TX_RING_SIZE); +			netbk_fatal_tx_err(vif); +			continue; +		} +  		RING_FINAL_CHECK_FOR_REQUESTS(&vif->tx, work_to_do);  		if (!work_to_do) {  			xenvif_put(vif); @@ -1294,17 +1323,14 @@ static unsigned xen_netbk_tx_build_gops(struct xen_netbk *netbk)  			work_to_do = xen_netbk_get_extras(vif, extras,  							  work_to_do);  			idx = vif->tx.req_cons; -			if (unlikely(work_to_do < 0)) { -				netbk_tx_err(vif, &txreq, idx); +			if (unlikely(work_to_do < 0))  				continue; -			}  		}  		ret = netbk_count_requests(vif, &txreq, txfrags, work_to_do); -		if (unlikely(ret < 0)) { -			netbk_tx_err(vif, &txreq, idx - ret); +		if (unlikely(ret < 0))  			continue; -		} +  		idx += ret;  		if (unlikely(txreq.size < ETH_HLEN)) { @@ -1316,11 +1342,11 @@ static unsigned xen_netbk_tx_build_gops(struct xen_netbk *netbk)  		/* No crossing a page as the payload mustn't fragment. */  		if (unlikely((txreq.offset + txreq.size) > PAGE_SIZE)) { -			netdev_dbg(vif->dev, +			netdev_err(vif->dev,  				   "txreq.offset: %x, size: %u, end: %lu\n",  				   txreq.offset, txreq.size,  				   (txreq.offset&~PAGE_MASK) + txreq.size); -			netbk_tx_err(vif, &txreq, idx); +			netbk_fatal_tx_err(vif);  			continue;  		} @@ -1348,8 +1374,8 @@ static unsigned xen_netbk_tx_build_gops(struct xen_netbk *netbk)  			gso = &extras[XEN_NETIF_EXTRA_TYPE_GSO - 1];  			if (netbk_set_skb_gso(vif, skb, gso)) { +				/* Failure in netbk_set_skb_gso is fatal. */  				kfree_skb(skb); -				netbk_tx_err(vif, &txreq, idx);  				continue;  			}  		} @@ -1448,7 +1474,7 @@ static void xen_netbk_tx_submit(struct xen_netbk *netbk)  			txp->size -= data_len;  		} else {  			/* Schedule a response immediately. */ -			xen_netbk_idx_release(netbk, pending_idx); +			xen_netbk_idx_release(netbk, pending_idx, XEN_NETIF_RSP_OKAY);  		}  		if (txp->flags & XEN_NETTXF_csum_blank) @@ -1500,7 +1526,8 @@ static void xen_netbk_tx_action(struct xen_netbk *netbk)  	xen_netbk_tx_submit(netbk);  } -static void xen_netbk_idx_release(struct xen_netbk *netbk, u16 pending_idx) +static void xen_netbk_idx_release(struct xen_netbk *netbk, u16 pending_idx, +				  u8 status)  {  	struct xenvif *vif;  	struct pending_tx_info *pending_tx_info; @@ -1514,7 +1541,7 @@ static void xen_netbk_idx_release(struct xen_netbk *netbk, u16 pending_idx)  	vif = pending_tx_info->vif; -	make_tx_response(vif, &pending_tx_info->req, XEN_NETIF_RSP_OKAY); +	make_tx_response(vif, &pending_tx_info->req, status);  	index = pending_index(netbk->pending_prod++);  	netbk->pending_ring[index] = pending_idx; diff --git a/drivers/pci/pcie/aer/aerdrv_errprint.c b/drivers/pci/pcie/aer/aerdrv_errprint.c index 3ea51736f18..5ab14251839 100644 --- a/drivers/pci/pcie/aer/aerdrv_errprint.c +++ b/drivers/pci/pcie/aer/aerdrv_errprint.c @@ -23,6 +23,9 @@  #include "aerdrv.h" +#define CREATE_TRACE_POINTS +#include <trace/events/ras.h> +  #define AER_AGENT_RECEIVER		0  #define AER_AGENT_REQUESTER		1  #define AER_AGENT_COMPLETER		2 @@ -121,12 +124,11 @@ static const char *aer_agent_string[] = {  	"Transmitter ID"  }; -static void __aer_print_error(const char *prefix, +static void __aer_print_error(struct pci_dev *dev,  			      struct aer_err_info *info)  {  	int i, status;  	const char *errmsg = NULL; -  	status = (info->status & ~info->mask);  	for (i = 0; i < 32; i++) { @@ -141,26 +143,22 @@ static void __aer_print_error(const char *prefix,  				aer_uncorrectable_error_string[i] : NULL;  		if (errmsg) -			printk("%s""   [%2d] %-22s%s\n", prefix, i, errmsg, +			dev_err(&dev->dev, "   [%2d] %-22s%s\n", i, errmsg,  				info->first_error == i ? " (First)" : "");  		else -			printk("%s""   [%2d] Unknown Error Bit%s\n", prefix, i, -				info->first_error == i ? " (First)" : ""); +			dev_err(&dev->dev, "   [%2d] Unknown Error Bit%s\n", +				i, info->first_error == i ? " (First)" : "");  	}  }  void aer_print_error(struct pci_dev *dev, struct aer_err_info *info)  {  	int id = ((dev->bus->number << 8) | dev->devfn); -	char prefix[44]; - -	snprintf(prefix, sizeof(prefix), "%s%s %s: ", -		 (info->severity == AER_CORRECTABLE) ? KERN_WARNING : KERN_ERR, -		 dev_driver_string(&dev->dev), dev_name(&dev->dev));  	if (info->status == 0) { -		printk("%s""PCIe Bus Error: severity=%s, type=Unaccessible, " -			"id=%04x(Unregistered Agent ID)\n", prefix, +		dev_err(&dev->dev, +			"PCIe Bus Error: severity=%s, type=Unaccessible, " +			"id=%04x(Unregistered Agent ID)\n",  			aer_error_severity_string[info->severity], id);  	} else {  		int layer, agent; @@ -168,22 +166,24 @@ void aer_print_error(struct pci_dev *dev, struct aer_err_info *info)  		layer = AER_GET_LAYER_ERROR(info->severity, info->status);  		agent = AER_GET_AGENT(info->severity, info->status); -		printk("%s""PCIe Bus Error: severity=%s, type=%s, id=%04x(%s)\n", -			prefix, aer_error_severity_string[info->severity], +		dev_err(&dev->dev, +			"PCIe Bus Error: severity=%s, type=%s, id=%04x(%s)\n", +			aer_error_severity_string[info->severity],  			aer_error_layer[layer], id, aer_agent_string[agent]); -		printk("%s""  device [%04x:%04x] error status/mask=%08x/%08x\n", -			prefix, dev->vendor, dev->device, +		dev_err(&dev->dev, +			"  device [%04x:%04x] error status/mask=%08x/%08x\n", +			dev->vendor, dev->device,  			info->status, info->mask); -		__aer_print_error(prefix, info); +		__aer_print_error(dev, info);  		if (info->tlp_header_valid) {  			unsigned char *tlp = (unsigned char *) &info->tlp; -			printk("%s""  TLP Header:" +			dev_err(&dev->dev, "  TLP Header:"  				" %02x%02x%02x%02x %02x%02x%02x%02x"  				" %02x%02x%02x%02x %02x%02x%02x%02x\n", -				prefix, *(tlp + 3), *(tlp + 2), *(tlp + 1), *tlp, +				*(tlp + 3), *(tlp + 2), *(tlp + 1), *tlp,  				*(tlp + 7), *(tlp + 6), *(tlp + 5), *(tlp + 4),  				*(tlp + 11), *(tlp + 10), *(tlp + 9),  				*(tlp + 8), *(tlp + 15), *(tlp + 14), @@ -192,8 +192,11 @@ void aer_print_error(struct pci_dev *dev, struct aer_err_info *info)  	}  	if (info->id && info->error_dev_num > 1 && info->id == id) -		printk("%s""  Error of this Agent(%04x) is reported first\n", -			prefix, id); +		dev_err(&dev->dev, +			   "  Error of this Agent(%04x) is reported first\n", +			id); +	trace_aer_event(dev_name(&dev->dev), (info->status & ~info->mask), +			info->severity);  }  void aer_print_port_info(struct pci_dev *dev, struct aer_err_info *info) @@ -217,7 +220,7 @@ int cper_severity_to_aer(int cper_severity)  }  EXPORT_SYMBOL_GPL(cper_severity_to_aer); -void cper_print_aer(const char *prefix, int cper_severity, +void cper_print_aer(const char *prefix, struct pci_dev *dev, int cper_severity,  		    struct aer_capability_regs *aer)  {  	int aer_severity, layer, agent, status_strs_size, tlp_header_valid = 0; @@ -239,25 +242,27 @@ void cper_print_aer(const char *prefix, int cper_severity,  	}  	layer = AER_GET_LAYER_ERROR(aer_severity, status);  	agent = AER_GET_AGENT(aer_severity, status); -	printk("%s""aer_status: 0x%08x, aer_mask: 0x%08x\n", -	       prefix, status, mask); +	dev_err(&dev->dev, "aer_status: 0x%08x, aer_mask: 0x%08x\n", +	       status, mask);  	cper_print_bits(prefix, status, status_strs, status_strs_size); -	printk("%s""aer_layer=%s, aer_agent=%s\n", prefix, +	dev_err(&dev->dev, "aer_layer=%s, aer_agent=%s\n",  	       aer_error_layer[layer], aer_agent_string[agent]);  	if (aer_severity != AER_CORRECTABLE) -		printk("%s""aer_uncor_severity: 0x%08x\n", -		       prefix, aer->uncor_severity); +		dev_err(&dev->dev, "aer_uncor_severity: 0x%08x\n", +		       aer->uncor_severity);  	if (tlp_header_valid) {  		const unsigned char *tlp;  		tlp = (const unsigned char *)&aer->header_log; -		printk("%s""aer_tlp_header:" +		dev_err(&dev->dev, "aer_tlp_header:"  			" %02x%02x%02x%02x %02x%02x%02x%02x"  			" %02x%02x%02x%02x %02x%02x%02x%02x\n", -			prefix, *(tlp + 3), *(tlp + 2), *(tlp + 1), *tlp, +			*(tlp + 3), *(tlp + 2), *(tlp + 1), *tlp,  			*(tlp + 7), *(tlp + 6), *(tlp + 5), *(tlp + 4),  			*(tlp + 11), *(tlp + 10), *(tlp + 9),  			*(tlp + 8), *(tlp + 15), *(tlp + 14),  			*(tlp + 13), *(tlp + 12));  	} +	trace_aer_event(dev_name(&dev->dev), (status & ~mask), +			aer_severity);  }  #endif diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c index 7c0fd9252e6..84954a726a9 100644 --- a/drivers/pci/remove.c +++ b/drivers/pci/remove.c @@ -19,6 +19,8 @@ static void pci_free_resources(struct pci_dev *dev)  static void pci_stop_dev(struct pci_dev *dev)  { +	pci_pme_active(dev, false); +  	if (dev->is_added) {  		pci_proc_detach_device(dev);  		pci_remove_sysfs_dev_files(dev); diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index c31aeb01bb0..a5f3c8ca480 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -181,12 +181,11 @@ config PINCTRL_COH901  config PINCTRL_SAMSUNG  	bool -	depends on OF && GPIOLIB  	select PINMUX  	select PINCONF -config PINCTRL_EXYNOS4 -	bool "Pinctrl driver data for Exynos4 SoC" +config PINCTRL_EXYNOS +	bool "Pinctrl driver data for Samsung EXYNOS SoCs"  	depends on OF && GPIOLIB  	select PINCTRL_SAMSUNG diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile index fc4606f27dc..6e87e52eab5 100644 --- a/drivers/pinctrl/Makefile +++ b/drivers/pinctrl/Makefile @@ -36,7 +36,7 @@ obj-$(CONFIG_PINCTRL_TEGRA30)	+= pinctrl-tegra30.o  obj-$(CONFIG_PINCTRL_U300)	+= pinctrl-u300.o  obj-$(CONFIG_PINCTRL_COH901)	+= pinctrl-coh901.o  obj-$(CONFIG_PINCTRL_SAMSUNG)	+= pinctrl-samsung.o -obj-$(CONFIG_PINCTRL_EXYNOS4)	+= pinctrl-exynos.o +obj-$(CONFIG_PINCTRL_EXYNOS)	+= pinctrl-exynos.o  obj-$(CONFIG_PINCTRL_EXYNOS5440)	+= pinctrl-exynos5440.o  obj-$(CONFIG_PINCTRL_XWAY)	+= pinctrl-xway.o  obj-$(CONFIG_PINCTRL_LANTIQ)	+= pinctrl-lantiq.o diff --git a/drivers/pinctrl/mvebu/pinctrl-dove.c b/drivers/pinctrl/mvebu/pinctrl-dove.c index 69aba369728..428ea96a94d 100644 --- a/drivers/pinctrl/mvebu/pinctrl-dove.c +++ b/drivers/pinctrl/mvebu/pinctrl-dove.c @@ -588,7 +588,7 @@ static int dove_pinctrl_probe(struct platform_device *pdev)  {  	const struct of_device_id *match =  		of_match_device(dove_pinctrl_of_match, &pdev->dev); -	pdev->dev.platform_data = match->data; +	pdev->dev.platform_data = (void *)match->data;  	/*  	 * General MPP Configuration Register is part of pdma registers. diff --git a/drivers/pinctrl/mvebu/pinctrl-kirkwood.c b/drivers/pinctrl/mvebu/pinctrl-kirkwood.c index f12084e1805..cdd483df673 100644 --- a/drivers/pinctrl/mvebu/pinctrl-kirkwood.c +++ b/drivers/pinctrl/mvebu/pinctrl-kirkwood.c @@ -66,9 +66,9 @@ static struct mvebu_mpp_mode mv88f6xxx_mpp_modes[] = {  		MPP_VAR_FUNCTION(0x5, "sata0", "act",    V(0, 1, 1, 1, 1, 0)),  		MPP_VAR_FUNCTION(0xb, "lcd", "vsync",    V(0, 0, 0, 0, 1, 0))),  	MPP_MODE(6, -		MPP_VAR_FUNCTION(0x0, "sysrst", "out",   V(1, 1, 1, 1, 1, 1)), -		MPP_VAR_FUNCTION(0x1, "spi", "mosi",     V(1, 1, 1, 1, 1, 1)), -		MPP_VAR_FUNCTION(0x2, "ptp", "trig",     V(1, 1, 1, 1, 0, 0))), +		MPP_VAR_FUNCTION(0x1, "sysrst", "out",   V(1, 1, 1, 1, 1, 1)), +		MPP_VAR_FUNCTION(0x2, "spi", "mosi",     V(1, 1, 1, 1, 1, 1)), +		MPP_VAR_FUNCTION(0x3, "ptp", "trig",     V(1, 1, 1, 1, 0, 0))),  	MPP_MODE(7,  		MPP_VAR_FUNCTION(0x0, "gpo", NULL,       V(1, 1, 1, 1, 1, 1)),  		MPP_VAR_FUNCTION(0x1, "pex", "rsto",     V(1, 1, 1, 1, 0, 1)), @@ -458,7 +458,7 @@ static int kirkwood_pinctrl_probe(struct platform_device *pdev)  {  	const struct of_device_id *match =  		of_match_device(kirkwood_pinctrl_of_match, &pdev->dev); -	pdev->dev.platform_data = match->data; +	pdev->dev.platform_data = (void *)match->data;  	return mvebu_pinctrl_probe(pdev);  } diff --git a/drivers/pinctrl/pinctrl-exynos5440.c b/drivers/pinctrl/pinctrl-exynos5440.c index de05b64f0da..142729914c3 100644 --- a/drivers/pinctrl/pinctrl-exynos5440.c +++ b/drivers/pinctrl/pinctrl-exynos5440.c @@ -599,7 +599,7 @@ static int exynos5440_gpio_direction_output(struct gpio_chip *gc, unsigned offse  }  /* parse the pin numbers listed in the 'samsung,exynos5440-pins' property */ -static int __init exynos5440_pinctrl_parse_dt_pins(struct platform_device *pdev, +static int exynos5440_pinctrl_parse_dt_pins(struct platform_device *pdev,  			struct device_node *cfg_np, unsigned int **pin_list,  			unsigned int *npins)  { @@ -630,7 +630,7 @@ static int __init exynos5440_pinctrl_parse_dt_pins(struct platform_device *pdev,   * Parse the information about all the available pin groups and pin functions   * from device node of the pin-controller.   */ -static int __init exynos5440_pinctrl_parse_dt(struct platform_device *pdev, +static int exynos5440_pinctrl_parse_dt(struct platform_device *pdev,  				struct exynos5440_pinctrl_priv_data *priv)  {  	struct device *dev = &pdev->dev; @@ -723,7 +723,7 @@ static int __init exynos5440_pinctrl_parse_dt(struct platform_device *pdev,  }  /* register the pinctrl interface with the pinctrl subsystem */ -static int __init exynos5440_pinctrl_register(struct platform_device *pdev, +static int exynos5440_pinctrl_register(struct platform_device *pdev,  				struct exynos5440_pinctrl_priv_data *priv)  {  	struct device *dev = &pdev->dev; @@ -798,7 +798,7 @@ static int __init exynos5440_pinctrl_register(struct platform_device *pdev,  }  /* register the gpiolib interface with the gpiolib subsystem */ -static int __init exynos5440_gpiolib_register(struct platform_device *pdev, +static int exynos5440_gpiolib_register(struct platform_device *pdev,  				struct exynos5440_pinctrl_priv_data *priv)  {  	struct gpio_chip *gc; @@ -831,7 +831,7 @@ static int __init exynos5440_gpiolib_register(struct platform_device *pdev,  }  /* unregister the gpiolib interface with the gpiolib subsystem */ -static int __init exynos5440_gpiolib_unregister(struct platform_device *pdev, +static int exynos5440_gpiolib_unregister(struct platform_device *pdev,  				struct exynos5440_pinctrl_priv_data *priv)  {  	int ret = gpiochip_remove(priv->gc); diff --git a/drivers/pinctrl/pinctrl-mxs.c b/drivers/pinctrl/pinctrl-mxs.c index dd227d21dcf..23af9f1f9c3 100644 --- a/drivers/pinctrl/pinctrl-mxs.c +++ b/drivers/pinctrl/pinctrl-mxs.c @@ -146,7 +146,7 @@ free:  static void mxs_dt_free_map(struct pinctrl_dev *pctldev,  			    struct pinctrl_map *map, unsigned num_maps)  { -	int i; +	u32 i;  	for (i = 0; i < num_maps; i++) {  		if (map[i].type == PIN_MAP_TYPE_MUX_GROUP) @@ -203,7 +203,7 @@ static int mxs_pinctrl_enable(struct pinctrl_dev *pctldev, unsigned selector,  	void __iomem *reg;  	u8 bank, shift;  	u16 pin; -	int i; +	u32 i;  	for (i = 0; i < g->npins; i++) {  		bank = PINID_TO_BANK(g->pins[i]); @@ -256,7 +256,7 @@ static int mxs_pinconf_group_set(struct pinctrl_dev *pctldev,  	void __iomem *reg;  	u8 ma, vol, pull, bank, shift;  	u16 pin; -	int i; +	u32 i;  	ma = CONFIG_TO_MA(config);  	vol = CONFIG_TO_VOL(config); @@ -345,8 +345,7 @@ static int mxs_pinctrl_parse_group(struct platform_device *pdev,  	const char *propname = "fsl,pinmux-ids";  	char *group;  	int length = strlen(np->name) + SUFFIX_LEN; -	int i; -	u32 val; +	u32 val, i;  	group = devm_kzalloc(&pdev->dev, length, GFP_KERNEL);  	if (!group) diff --git a/drivers/pinctrl/pinctrl-nomadik.c b/drivers/pinctrl/pinctrl-nomadik.c index 1bb16ffb4e4..5767b18ebdf 100644 --- a/drivers/pinctrl/pinctrl-nomadik.c +++ b/drivers/pinctrl/pinctrl-nomadik.c @@ -676,7 +676,7 @@ int nmk_gpio_set_mode(int gpio, int gpio_mode)  }  EXPORT_SYMBOL(nmk_gpio_set_mode); -static int nmk_prcm_gpiocr_get_mode(struct pinctrl_dev *pctldev, int gpio) +static int __maybe_unused nmk_prcm_gpiocr_get_mode(struct pinctrl_dev *pctldev, int gpio)  {  	int i;  	u16 reg; diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c index f6a360b86eb..5c32e880bcb 100644 --- a/drivers/pinctrl/pinctrl-single.c +++ b/drivers/pinctrl/pinctrl-single.c @@ -30,7 +30,6 @@  #define PCS_MUX_BITS_NAME		"pinctrl-single,bits"  #define PCS_REG_NAME_LEN		((sizeof(unsigned long) * 2) + 1)  #define PCS_OFF_DISABLED		~0U -#define PCS_MAX_GPIO_VALUES		2  /**   * struct pcs_pingroup - pingroups for a function @@ -78,16 +77,6 @@ struct pcs_function {  };  /** - * struct pcs_gpio_range - pinctrl gpio range - * @range:	subrange of the GPIO number space - * @gpio_func:	gpio function value in the pinmux register - */ -struct pcs_gpio_range { -	struct pinctrl_gpio_range range; -	int gpio_func; -}; - -/**   * struct pcs_data - wrapper for data needed by pinctrl framework   * @pa:		pindesc array   * @cur:	index to current element @@ -414,26 +403,9 @@ static void pcs_disable(struct pinctrl_dev *pctldev, unsigned fselector,  }  static int pcs_request_gpio(struct pinctrl_dev *pctldev, -			    struct pinctrl_gpio_range *range, unsigned pin) +			struct pinctrl_gpio_range *range, unsigned offset)  { -	struct pcs_device *pcs = pinctrl_dev_get_drvdata(pctldev); -	struct pcs_gpio_range *gpio = NULL; -	int end, mux_bytes; -	unsigned data; - -	gpio = container_of(range, struct pcs_gpio_range, range); -	end = range->pin_base + range->npins - 1; -	if (pin < range->pin_base || pin > end) { -		dev_err(pctldev->dev, -			"pin %d isn't in the range of %d to %d\n", -			pin, range->pin_base, end); -		return -EINVAL; -	} -	mux_bytes = pcs->width / BITS_PER_BYTE; -	data = pcs->read(pcs->base + pin * mux_bytes) & ~pcs->fmask; -	data |= gpio->gpio_func; -	pcs->write(data, pcs->base + pin * mux_bytes); -	return 0; +	return -ENOTSUPP;  }  static struct pinmux_ops pcs_pinmux_ops = { @@ -907,49 +879,6 @@ static void pcs_free_resources(struct pcs_device *pcs)  static struct of_device_id pcs_of_match[]; -static int pcs_add_gpio_range(struct device_node *node, struct pcs_device *pcs) -{ -	struct pcs_gpio_range *gpio; -	struct device_node *child; -	struct resource r; -	const char name[] = "pinctrl-single"; -	u32 gpiores[PCS_MAX_GPIO_VALUES]; -	int ret, i = 0, mux_bytes = 0; - -	for_each_child_of_node(node, child) { -		ret = of_address_to_resource(child, 0, &r); -		if (ret < 0) -			continue; -		memset(gpiores, 0, sizeof(u32) * PCS_MAX_GPIO_VALUES); -		ret = of_property_read_u32_array(child, "pinctrl-single,gpio", -						 gpiores, PCS_MAX_GPIO_VALUES); -		if (ret < 0) -			continue; -		gpio = devm_kzalloc(pcs->dev, sizeof(*gpio), GFP_KERNEL); -		if (!gpio) { -			dev_err(pcs->dev, "failed to allocate pcs gpio\n"); -			return -ENOMEM; -		} -		gpio->range.name = devm_kzalloc(pcs->dev, sizeof(name), -						GFP_KERNEL); -		if (!gpio->range.name) { -			dev_err(pcs->dev, "failed to allocate range name\n"); -			return -ENOMEM; -		} -		memcpy((char *)gpio->range.name, name, sizeof(name)); - -		gpio->range.id = i++; -		gpio->range.base = gpiores[0]; -		gpio->gpio_func = gpiores[1]; -		mux_bytes = pcs->width / BITS_PER_BYTE; -		gpio->range.pin_base = (r.start - pcs->res->start) / mux_bytes; -		gpio->range.npins = (r.end - r.start) / mux_bytes + 1; - -		pinctrl_add_gpio_range(pcs->pctl, &gpio->range); -	} -	return 0; -} -  static int pcs_probe(struct platform_device *pdev)  {  	struct device_node *np = pdev->dev.of_node; @@ -1046,10 +975,6 @@ static int pcs_probe(struct platform_device *pdev)  		goto free;  	} -	ret = pcs_add_gpio_range(np, pcs); -	if (ret < 0) -		goto free; -  	dev_info(pcs->dev, "%i pins at pa %p size %u\n",  		 pcs->desc.npins, pcs->base, pcs->size); diff --git a/drivers/pinctrl/pinctrl-sirf.c b/drivers/pinctrl/pinctrl-sirf.c index 498b2ba905d..d02498b30c6 100644 --- a/drivers/pinctrl/pinctrl-sirf.c +++ b/drivers/pinctrl/pinctrl-sirf.c @@ -1246,6 +1246,22 @@ static void __iomem *sirfsoc_rsc_of_iomap(void)  	return of_iomap(np, 0);  } +static int sirfsoc_gpio_of_xlate(struct gpio_chip *gc, +       const struct of_phandle_args *gpiospec, +       u32 *flags) +{ +       if (gpiospec->args[0] > SIRFSOC_GPIO_NO_OF_BANKS * SIRFSOC_GPIO_BANK_SIZE) +               return -EINVAL; + +       if (gc != &sgpio_bank[gpiospec->args[0] / SIRFSOC_GPIO_BANK_SIZE].chip.gc) +               return -EINVAL; + +       if (flags) +               *flags = gpiospec->args[1]; + +       return gpiospec->args[0] % SIRFSOC_GPIO_BANK_SIZE; +} +  static int sirfsoc_pinmux_probe(struct platform_device *pdev)  {  	int ret; @@ -1736,6 +1752,8 @@ static int sirfsoc_gpio_probe(struct device_node *np)  		bank->chip.gc.ngpio = SIRFSOC_GPIO_BANK_SIZE;  		bank->chip.gc.label = kstrdup(np->full_name, GFP_KERNEL);  		bank->chip.gc.of_node = np; +		bank->chip.gc.of_xlate = sirfsoc_gpio_of_xlate; +		bank->chip.gc.of_gpio_n_cells = 2;  		bank->chip.regs = regs;  		bank->id = i;  		bank->is_marco = is_marco; diff --git a/drivers/platform/x86/ibm_rtl.c b/drivers/platform/x86/ibm_rtl.c index 7481146a5b4..97c2be195ef 100644 --- a/drivers/platform/x86/ibm_rtl.c +++ b/drivers/platform/x86/ibm_rtl.c @@ -244,7 +244,7 @@ static int __init ibm_rtl_init(void) {  	if (force)  		pr_warn("module loaded by force\n");  	/* first ensure that we are running on IBM HW */ -	else if (efi_enabled || !dmi_check_system(ibm_rtl_dmi_table)) +	else if (efi_enabled(EFI_BOOT) || !dmi_check_system(ibm_rtl_dmi_table))  		return -ENODEV;  	/* Get the address for the Extended BIOS Data Area */ diff --git a/drivers/platform/x86/samsung-laptop.c b/drivers/platform/x86/samsung-laptop.c index 71623a2ff3e..d1f03005317 100644 --- a/drivers/platform/x86/samsung-laptop.c +++ b/drivers/platform/x86/samsung-laptop.c @@ -26,6 +26,7 @@  #include <linux/seq_file.h>  #include <linux/debugfs.h>  #include <linux/ctype.h> +#include <linux/efi.h>  #include <acpi/video.h>  /* @@ -1544,6 +1545,9 @@ static int __init samsung_init(void)  	struct samsung_laptop *samsung;  	int ret; +	if (efi_enabled(EFI_BOOT)) +		return -ENODEV; +  	quirks = &samsung_unknown;  	if (!force && !dmi_check_system(samsung_dmi_table))  		return -ENODEV; diff --git a/drivers/regulator/dbx500-prcmu.c b/drivers/regulator/dbx500-prcmu.c index 261f3d2299b..89bd2faaef8 100644 --- a/drivers/regulator/dbx500-prcmu.c +++ b/drivers/regulator/dbx500-prcmu.c @@ -14,6 +14,7 @@  #include <linux/debugfs.h>  #include <linux/seq_file.h>  #include <linux/slab.h> +#include <linux/module.h>  #include "dbx500-prcmu.h" diff --git a/drivers/regulator/max77686.c b/drivers/regulator/max77686.c index b85040caaea..cca18a3c029 100644 --- a/drivers/regulator/max77686.c +++ b/drivers/regulator/max77686.c @@ -379,9 +379,10 @@ static struct regulator_desc regulators[] = {  };  #ifdef CONFIG_OF -static int max77686_pmic_dt_parse_pdata(struct max77686_dev *iodev, +static int max77686_pmic_dt_parse_pdata(struct platform_device *pdev,  					struct max77686_platform_data *pdata)  { +	struct max77686_dev *iodev = dev_get_drvdata(pdev->dev.parent);  	struct device_node *pmic_np, *regulators_np;  	struct max77686_regulator_data *rdata;  	struct of_regulator_match rmatch; @@ -390,15 +391,15 @@ static int max77686_pmic_dt_parse_pdata(struct max77686_dev *iodev,  	pmic_np = iodev->dev->of_node;  	regulators_np = of_find_node_by_name(pmic_np, "voltage-regulators");  	if (!regulators_np) { -		dev_err(iodev->dev, "could not find regulators sub-node\n"); +		dev_err(&pdev->dev, "could not find regulators sub-node\n");  		return -EINVAL;  	}  	pdata->num_regulators = ARRAY_SIZE(regulators); -	rdata = devm_kzalloc(iodev->dev, sizeof(*rdata) * +	rdata = devm_kzalloc(&pdev->dev, sizeof(*rdata) *  			     pdata->num_regulators, GFP_KERNEL);  	if (!rdata) { -		dev_err(iodev->dev, +		dev_err(&pdev->dev,  			"could not allocate memory for regulator data\n");  		return -ENOMEM;  	} @@ -407,7 +408,7 @@ static int max77686_pmic_dt_parse_pdata(struct max77686_dev *iodev,  		rmatch.name = regulators[i].name;  		rmatch.init_data = NULL;  		rmatch.of_node = NULL; -		of_regulator_match(iodev->dev, regulators_np, &rmatch, 1); +		of_regulator_match(&pdev->dev, regulators_np, &rmatch, 1);  		rdata[i].initdata = rmatch.init_data;  		rdata[i].of_node = rmatch.of_node;  	} @@ -417,7 +418,7 @@ static int max77686_pmic_dt_parse_pdata(struct max77686_dev *iodev,  	return 0;  }  #else -static int max77686_pmic_dt_parse_pdata(struct max77686_dev *iodev, +static int max77686_pmic_dt_parse_pdata(struct platform_device *pdev,  					struct max77686_platform_data *pdata)  {  	return 0; @@ -440,7 +441,7 @@ static int max77686_pmic_probe(struct platform_device *pdev)  	}  	if (iodev->dev->of_node) { -		ret = max77686_pmic_dt_parse_pdata(iodev, pdata); +		ret = max77686_pmic_dt_parse_pdata(pdev, pdata);  		if (ret)  			return ret;  	} diff --git a/drivers/regulator/max8907-regulator.c b/drivers/regulator/max8907-regulator.c index d1a77512d83..d40cf7fdb54 100644 --- a/drivers/regulator/max8907-regulator.c +++ b/drivers/regulator/max8907-regulator.c @@ -237,8 +237,7 @@ static int max8907_regulator_parse_dt(struct platform_device *pdev)  		return -EINVAL;  	} -	ret = of_regulator_match(pdev->dev.parent, regulators, -				 max8907_matches, +	ret = of_regulator_match(&pdev->dev, regulators, max8907_matches,  				 ARRAY_SIZE(max8907_matches));  	if (ret < 0) {  		dev_err(&pdev->dev, "Error parsing regulator init data: %d\n", diff --git a/drivers/regulator/max8997.c b/drivers/regulator/max8997.c index 02be7fcae32..836908ce505 100644 --- a/drivers/regulator/max8997.c +++ b/drivers/regulator/max8997.c @@ -934,7 +934,7 @@ static struct regulator_desc regulators[] = {  };  #ifdef CONFIG_OF -static int max8997_pmic_dt_parse_dvs_gpio(struct max8997_dev *iodev, +static int max8997_pmic_dt_parse_dvs_gpio(struct platform_device *pdev,  			struct max8997_platform_data *pdata,  			struct device_node *pmic_np)  { @@ -944,7 +944,7 @@ static int max8997_pmic_dt_parse_dvs_gpio(struct max8997_dev *iodev,  		gpio = of_get_named_gpio(pmic_np,  					"max8997,pmic-buck125-dvs-gpios", i);  		if (!gpio_is_valid(gpio)) { -			dev_err(iodev->dev, "invalid gpio[%d]: %d\n", i, gpio); +			dev_err(&pdev->dev, "invalid gpio[%d]: %d\n", i, gpio);  			return -EINVAL;  		}  		pdata->buck125_gpios[i] = gpio; @@ -952,22 +952,23 @@ static int max8997_pmic_dt_parse_dvs_gpio(struct max8997_dev *iodev,  	return 0;  } -static int max8997_pmic_dt_parse_pdata(struct max8997_dev *iodev, +static int max8997_pmic_dt_parse_pdata(struct platform_device *pdev,  					struct max8997_platform_data *pdata)  { +	struct max8997_dev *iodev = dev_get_drvdata(pdev->dev.parent);  	struct device_node *pmic_np, *regulators_np, *reg_np;  	struct max8997_regulator_data *rdata;  	unsigned int i, dvs_voltage_nr = 1, ret;  	pmic_np = iodev->dev->of_node;  	if (!pmic_np) { -		dev_err(iodev->dev, "could not find pmic sub-node\n"); +		dev_err(&pdev->dev, "could not find pmic sub-node\n");  		return -ENODEV;  	}  	regulators_np = of_find_node_by_name(pmic_np, "regulators");  	if (!regulators_np) { -		dev_err(iodev->dev, "could not find regulators sub-node\n"); +		dev_err(&pdev->dev, "could not find regulators sub-node\n");  		return -EINVAL;  	} @@ -976,11 +977,10 @@ static int max8997_pmic_dt_parse_pdata(struct max8997_dev *iodev,  	for_each_child_of_node(regulators_np, reg_np)  		pdata->num_regulators++; -	rdata = devm_kzalloc(iodev->dev, sizeof(*rdata) * +	rdata = devm_kzalloc(&pdev->dev, sizeof(*rdata) *  				pdata->num_regulators, GFP_KERNEL);  	if (!rdata) { -		dev_err(iodev->dev, "could not allocate memory for " -						"regulator data\n"); +		dev_err(&pdev->dev, "could not allocate memory for regulator data\n");  		return -ENOMEM;  	} @@ -991,14 +991,14 @@ static int max8997_pmic_dt_parse_pdata(struct max8997_dev *iodev,  				break;  		if (i == ARRAY_SIZE(regulators)) { -			dev_warn(iodev->dev, "don't know how to configure " -				"regulator %s\n", reg_np->name); +			dev_warn(&pdev->dev, "don't know how to configure regulator %s\n", +				 reg_np->name);  			continue;  		}  		rdata->id = i; -		rdata->initdata = of_get_regulator_init_data( -						iodev->dev, reg_np); +		rdata->initdata = of_get_regulator_init_data(&pdev->dev, +							     reg_np);  		rdata->reg_node = reg_np;  		rdata++;  	} @@ -1014,7 +1014,7 @@ static int max8997_pmic_dt_parse_pdata(struct max8997_dev *iodev,  	if (pdata->buck1_gpiodvs || pdata->buck2_gpiodvs ||  						pdata->buck5_gpiodvs) { -		ret = max8997_pmic_dt_parse_dvs_gpio(iodev, pdata, pmic_np); +		ret = max8997_pmic_dt_parse_dvs_gpio(pdev, pdata, pmic_np);  		if (ret)  			return -EINVAL; @@ -1025,8 +1025,7 @@ static int max8997_pmic_dt_parse_pdata(struct max8997_dev *iodev,  		} else {  			if (pdata->buck125_default_idx >= 8) {  				pdata->buck125_default_idx = 0; -				dev_info(iodev->dev, "invalid value for " -				"default dvs index, using 0 instead\n"); +				dev_info(&pdev->dev, "invalid value for default dvs index, using 0 instead\n");  			}  		} @@ -1040,28 +1039,28 @@ static int max8997_pmic_dt_parse_pdata(struct max8997_dev *iodev,  	if (of_property_read_u32_array(pmic_np,  				"max8997,pmic-buck1-dvs-voltage",  				pdata->buck1_voltage, dvs_voltage_nr)) { -		dev_err(iodev->dev, "buck1 voltages not specified\n"); +		dev_err(&pdev->dev, "buck1 voltages not specified\n");  		return -EINVAL;  	}  	if (of_property_read_u32_array(pmic_np,  				"max8997,pmic-buck2-dvs-voltage",  				pdata->buck2_voltage, dvs_voltage_nr)) { -		dev_err(iodev->dev, "buck2 voltages not specified\n"); +		dev_err(&pdev->dev, "buck2 voltages not specified\n");  		return -EINVAL;  	}  	if (of_property_read_u32_array(pmic_np,  				"max8997,pmic-buck5-dvs-voltage",  				pdata->buck5_voltage, dvs_voltage_nr)) { -		dev_err(iodev->dev, "buck5 voltages not specified\n"); +		dev_err(&pdev->dev, "buck5 voltages not specified\n");  		return -EINVAL;  	}  	return 0;  }  #else -static int max8997_pmic_dt_parse_pdata(struct max8997_dev *iodev, +static int max8997_pmic_dt_parse_pdata(struct platform_device *pdev,  					struct max8997_platform_data *pdata)  {  	return 0; @@ -1085,7 +1084,7 @@ static int max8997_pmic_probe(struct platform_device *pdev)  	}  	if (iodev->dev->of_node) { -		ret = max8997_pmic_dt_parse_pdata(iodev, pdata); +		ret = max8997_pmic_dt_parse_pdata(pdev, pdata);  		if (ret)  			return ret;  	} diff --git a/drivers/regulator/max8998.c b/drivers/regulator/max8998.c index 1f0df4046b8..0a8dd1cbee6 100644 --- a/drivers/regulator/max8998.c +++ b/drivers/regulator/max8998.c @@ -65,7 +65,7 @@ static const struct voltage_map_desc ldo9_voltage_map_desc = {  	.min = 2800000,	.step = 100000,	.max = 3100000,  };  static const struct voltage_map_desc ldo10_voltage_map_desc = { -	.min = 95000,	.step = 50000,	.max = 1300000, +	.min = 950000,	.step = 50000,	.max = 1300000,  };  static const struct voltage_map_desc ldo1213_voltage_map_desc = {  	.min = 800000,	.step = 100000,	.max = 3300000, diff --git a/drivers/regulator/of_regulator.c b/drivers/regulator/of_regulator.c index 6f684916fd7..66ca769287a 100644 --- a/drivers/regulator/of_regulator.c +++ b/drivers/regulator/of_regulator.c @@ -120,6 +120,12 @@ int of_regulator_match(struct device *dev, struct device_node *node,  	if (!dev || !node)  		return -EINVAL; +	for (i = 0; i < num_matches; i++) { +		struct of_regulator_match *match = &matches[i]; +		match->init_data = NULL; +		match->of_node = NULL; +	} +  	for_each_child_of_node(node, child) {  		name = of_get_property(child,  					"regulator-compatible", NULL); diff --git a/drivers/regulator/s2mps11.c b/drivers/regulator/s2mps11.c index bd062a2ffbe..cd9ea2ea182 100644 --- a/drivers/regulator/s2mps11.c +++ b/drivers/regulator/s2mps11.c @@ -174,9 +174,9 @@ static struct regulator_ops s2mps11_buck_ops = {  	.min_uV		= S2MPS11_BUCK_MIN2,			\  	.uV_step	= S2MPS11_BUCK_STEP2,			\  	.n_voltages	= S2MPS11_BUCK_N_VOLTAGES,		\ -	.vsel_reg	= S2MPS11_REG_B9CTRL2,			\ +	.vsel_reg	= S2MPS11_REG_B10CTRL2,			\  	.vsel_mask	= S2MPS11_BUCK_VSEL_MASK,		\ -	.enable_reg	= S2MPS11_REG_B9CTRL1,			\ +	.enable_reg	= S2MPS11_REG_B10CTRL1,			\  	.enable_mask	= S2MPS11_ENABLE_MASK			\  } diff --git a/drivers/regulator/tps65217-regulator.c b/drivers/regulator/tps65217-regulator.c index 73dce766412..df395187c06 100644 --- a/drivers/regulator/tps65217-regulator.c +++ b/drivers/regulator/tps65217-regulator.c @@ -305,8 +305,8 @@ static struct tps65217_board *tps65217_parse_dt(struct platform_device *pdev)  	if (!regs)  		return NULL; -	count = of_regulator_match(pdev->dev.parent, regs, -				reg_matches, TPS65217_NUM_REGULATOR); +	count = of_regulator_match(&pdev->dev, regs, reg_matches, +				   TPS65217_NUM_REGULATOR);  	of_node_put(regs);  	if ((count < 0) || (count > TPS65217_NUM_REGULATOR))  		return NULL; diff --git a/drivers/regulator/tps65910-regulator.c b/drivers/regulator/tps65910-regulator.c index 59c3770fa77..b0e4c0bc85c 100644 --- a/drivers/regulator/tps65910-regulator.c +++ b/drivers/regulator/tps65910-regulator.c @@ -998,7 +998,7 @@ static struct tps65910_board *tps65910_parse_dt_reg_data(  		return NULL;  	} -	ret = of_regulator_match(pdev->dev.parent, regulators, matches, count); +	ret = of_regulator_match(&pdev->dev, regulators, matches, count);  	if (ret < 0) {  		dev_err(&pdev->dev, "Error parsing regulator init data: %d\n",  			ret); diff --git a/drivers/regulator/tps80031-regulator.c b/drivers/regulator/tps80031-regulator.c index b15d711bc8c..9019d0e7ecb 100644 --- a/drivers/regulator/tps80031-regulator.c +++ b/drivers/regulator/tps80031-regulator.c @@ -728,7 +728,7 @@ static int tps80031_regulator_probe(struct platform_device *pdev)  			}  		}  		rdev = regulator_register(&ri->rinfo->desc, &config); -		if (IS_ERR_OR_NULL(rdev)) { +		if (IS_ERR(rdev)) {  			dev_err(&pdev->dev,  				"register regulator failed %s\n",  					ri->rinfo->desc.name); diff --git a/drivers/rtc/rtc-isl1208.c b/drivers/rtc/rtc-isl1208.c index afb7cfa85cc..c016ad81767 100644 --- a/drivers/rtc/rtc-isl1208.c +++ b/drivers/rtc/rtc-isl1208.c @@ -506,6 +506,7 @@ isl1208_rtc_interrupt(int irq, void *data)  {  	unsigned long timeout = jiffies + msecs_to_jiffies(1000);  	struct i2c_client *client = data; +	struct rtc_device *rtc = i2c_get_clientdata(client);  	int handled = 0, sr, err;  	/* @@ -528,6 +529,8 @@ isl1208_rtc_interrupt(int irq, void *data)  	if (sr & ISL1208_REG_SR_ALM) {  		dev_dbg(&client->dev, "alarm!\n"); +		rtc_update_irq(rtc, 1, RTC_IRQF | RTC_AF); +  		/* Clear the alarm */  		sr &= ~ISL1208_REG_SR_ALM;  		sr = i2c_smbus_write_byte_data(client, ISL1208_REG_SR, sr); diff --git a/drivers/rtc/rtc-pl031.c b/drivers/rtc/rtc-pl031.c index 08378e3cc21..81c5077feff 100644 --- a/drivers/rtc/rtc-pl031.c +++ b/drivers/rtc/rtc-pl031.c @@ -44,6 +44,7 @@  #define RTC_YMR		0x34	/* Year match register */  #define RTC_YLR		0x38	/* Year data load register */ +#define RTC_CR_EN	(1 << 0)	/* counter enable bit */  #define RTC_CR_CWEN	(1 << 26)	/* Clockwatch enable bit */  #define RTC_TCR_EN	(1 << 1) /* Periodic timer enable bit */ @@ -320,7 +321,7 @@ static int pl031_probe(struct amba_device *adev, const struct amba_id *id)  	struct pl031_local *ldata;  	struct pl031_vendor_data *vendor = id->data;  	struct rtc_class_ops *ops = &vendor->ops; -	unsigned long time; +	unsigned long time, data;  	ret = amba_request_regions(adev, NULL);  	if (ret) @@ -345,10 +346,13 @@ static int pl031_probe(struct amba_device *adev, const struct amba_id *id)  	dev_dbg(&adev->dev, "designer ID = 0x%02x\n", amba_manf(adev));  	dev_dbg(&adev->dev, "revision = 0x%01x\n", amba_rev(adev)); +	data = readl(ldata->base + RTC_CR);  	/* Enable the clockwatch on ST Variants */  	if (vendor->clockwatch) -		writel(readl(ldata->base + RTC_CR) | RTC_CR_CWEN, -		       ldata->base + RTC_CR); +		data |= RTC_CR_CWEN; +	else +		data |= RTC_CR_EN; +	writel(data, ldata->base + RTC_CR);  	/*  	 * On ST PL031 variants, the RTC reset value does not provide correct diff --git a/drivers/rtc/rtc-vt8500.c b/drivers/rtc/rtc-vt8500.c index 00c930f4b6f..2730533e2d2 100644 --- a/drivers/rtc/rtc-vt8500.c +++ b/drivers/rtc/rtc-vt8500.c @@ -137,7 +137,7 @@ static int vt8500_rtc_set_time(struct device *dev, struct rtc_time *tm)  		return -EINVAL;  	} -	writel((bin2bcd(tm->tm_year - 100) << DATE_YEAR_S) +	writel((bin2bcd(tm->tm_year % 100) << DATE_YEAR_S)  		| (bin2bcd(tm->tm_mon + 1) << DATE_MONTH_S)  		| (bin2bcd(tm->tm_mday))  		| ((tm->tm_year >= 200) << DATE_CENTURY_S), diff --git a/drivers/scsi/isci/init.c b/drivers/scsi/isci/init.c index d73fdcfeb45..2839baa82a5 100644 --- a/drivers/scsi/isci/init.c +++ b/drivers/scsi/isci/init.c @@ -633,7 +633,7 @@ static int isci_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)  		return -ENOMEM;  	pci_set_drvdata(pdev, pci_info); -	if (efi_enabled) +	if (efi_enabled(EFI_RUNTIME_SERVICES))  		orom = isci_get_efi_var(pdev);  	if (!orom) diff --git a/drivers/ssb/driver_gpio.c b/drivers/ssb/driver_gpio.c index 97ac0a38e3d..eb2753008ef 100644 --- a/drivers/ssb/driver_gpio.c +++ b/drivers/ssb/driver_gpio.c @@ -174,3 +174,15 @@ int ssb_gpio_init(struct ssb_bus *bus)  	return -1;  } + +int ssb_gpio_unregister(struct ssb_bus *bus) +{ +	if (ssb_chipco_available(&bus->chipco) || +	    ssb_extif_available(&bus->extif)) { +		return gpiochip_remove(&bus->gpio); +	} else { +		SSB_WARN_ON(1); +	} + +	return -1; +} diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c index 772ad9b5c30..24dc331b470 100644 --- a/drivers/ssb/main.c +++ b/drivers/ssb/main.c @@ -443,6 +443,15 @@ static void ssb_devices_unregister(struct ssb_bus *bus)  void ssb_bus_unregister(struct ssb_bus *bus)  { +	int err; + +	err = ssb_gpio_unregister(bus); +	if (err == -EBUSY) +		ssb_dprintk(KERN_ERR PFX "Some GPIOs are still in use.\n"); +	else if (err) +		ssb_dprintk(KERN_ERR PFX +			    "Can not unregister GPIO driver: %i\n", err); +  	ssb_buses_lock();  	ssb_devices_unregister(bus);  	list_del(&bus->list); diff --git a/drivers/ssb/ssb_private.h b/drivers/ssb/ssb_private.h index 6c10b66c796..da38305a2d2 100644 --- a/drivers/ssb/ssb_private.h +++ b/drivers/ssb/ssb_private.h @@ -252,11 +252,16 @@ static inline void ssb_extif_init(struct ssb_extif *extif)  #ifdef CONFIG_SSB_DRIVER_GPIO  extern int ssb_gpio_init(struct ssb_bus *bus); +extern int ssb_gpio_unregister(struct ssb_bus *bus);  #else /* CONFIG_SSB_DRIVER_GPIO */  static inline int ssb_gpio_init(struct ssb_bus *bus)  {  	return -ENOTSUPP;  } +static inline int ssb_gpio_unregister(struct ssb_bus *bus) +{ +	return 0; +}  #endif /* CONFIG_SSB_DRIVER_GPIO */  #endif /* LINUX_SSB_PRIVATE_H_ */ diff --git a/drivers/staging/iio/trigger/Kconfig b/drivers/staging/iio/trigger/Kconfig index 7d320755926..d44d3ad26fa 100644 --- a/drivers/staging/iio/trigger/Kconfig +++ b/drivers/staging/iio/trigger/Kconfig @@ -21,7 +21,6 @@ config IIO_GPIO_TRIGGER  config IIO_SYSFS_TRIGGER  	tristate "SYSFS trigger"  	depends on SYSFS -	depends on HAVE_IRQ_WORK  	select IRQ_WORK  	help  	  Provides support for using SYSFS entry as IIO triggers. diff --git a/drivers/staging/omapdrm/Kconfig b/drivers/staging/omapdrm/Kconfig index b724a413143..09f65dc3d2c 100644 --- a/drivers/staging/omapdrm/Kconfig +++ b/drivers/staging/omapdrm/Kconfig @@ -3,8 +3,8 @@ config DRM_OMAP  	tristate "OMAP DRM"  	depends on DRM && !CONFIG_FB_OMAP2  	depends on ARCH_OMAP2PLUS || ARCH_MULTIPLATFORM +	depends on OMAP2_DSS  	select DRM_KMS_HELPER -	select OMAP2_DSS  	select FB_SYS_FILLRECT  	select FB_SYS_COPYAREA  	select FB_SYS_IMAGEBLIT diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index e2695101bb9..f2aa7543d20 100644 --- a/drivers/target/target_core_device.c +++ b/drivers/target/target_core_device.c @@ -941,6 +941,8 @@ int se_dev_set_queue_depth(struct se_device *dev, u32 queue_depth)  int se_dev_set_fabric_max_sectors(struct se_device *dev, u32 fabric_max_sectors)  { +	int block_size = dev->dev_attrib.block_size; +  	if (dev->export_count) {  		pr_err("dev[%p]: Unable to change SE Device"  			" fabric_max_sectors while export_count is %d\n", @@ -978,8 +980,12 @@ int se_dev_set_fabric_max_sectors(struct se_device *dev, u32 fabric_max_sectors)  	/*  	 * Align max_sectors down to PAGE_SIZE to follow transport_allocate_data_tasks()  	 */ +	if (!block_size) { +		block_size = 512; +		pr_warn("Defaulting to 512 for zero block_size\n"); +	}  	fabric_max_sectors = se_dev_align_max_sectors(fabric_max_sectors, -						      dev->dev_attrib.block_size); +						      block_size);  	dev->dev_attrib.fabric_max_sectors = fabric_max_sectors;  	pr_debug("dev[%p]: SE Device max_sectors changed to %u\n", diff --git a/drivers/target/target_core_fabric_configfs.c b/drivers/target/target_core_fabric_configfs.c index 810263dfa4a..c57bbbc7a7d 100644 --- a/drivers/target/target_core_fabric_configfs.c +++ b/drivers/target/target_core_fabric_configfs.c @@ -754,6 +754,11 @@ static int target_fabric_port_link(  		return -EFAULT;  	} +	if (!(dev->dev_flags & DF_CONFIGURED)) { +		pr_err("se_device not configured yet, cannot port link\n"); +		return -ENODEV; +	} +  	tpg_ci = &lun_ci->ci_parent->ci_group->cg_item;  	se_tpg = container_of(to_config_group(tpg_ci),  				struct se_portal_group, tpg_group); diff --git a/drivers/target/target_core_sbc.c b/drivers/target/target_core_sbc.c index 26a6d183ccb..a664c664a31 100644 --- a/drivers/target/target_core_sbc.c +++ b/drivers/target/target_core_sbc.c @@ -58,11 +58,10 @@ sbc_emulate_readcapacity(struct se_cmd *cmd)  	buf[7] = dev->dev_attrib.block_size & 0xff;  	rbuf = transport_kmap_data_sg(cmd); -	if (!rbuf) -		return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; - -	memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length)); -	transport_kunmap_data_sg(cmd); +	if (rbuf) { +		memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length)); +		transport_kunmap_data_sg(cmd); +	}  	target_complete_cmd(cmd, GOOD);  	return 0; @@ -97,11 +96,10 @@ sbc_emulate_readcapacity_16(struct se_cmd *cmd)  		buf[14] = 0x80;  	rbuf = transport_kmap_data_sg(cmd); -	if (!rbuf) -		return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; - -	memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length)); -	transport_kunmap_data_sg(cmd); +	if (rbuf) { +		memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length)); +		transport_kunmap_data_sg(cmd); +	}  	target_complete_cmd(cmd, GOOD);  	return 0; diff --git a/drivers/target/target_core_spc.c b/drivers/target/target_core_spc.c index 84f9e96e8ac..2d88f087d96 100644 --- a/drivers/target/target_core_spc.c +++ b/drivers/target/target_core_spc.c @@ -641,11 +641,10 @@ spc_emulate_inquiry(struct se_cmd *cmd)  out:  	rbuf = transport_kmap_data_sg(cmd); -	if (!rbuf) -		return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; - -	memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length)); -	transport_kunmap_data_sg(cmd); +	if (rbuf) { +		memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length)); +		transport_kunmap_data_sg(cmd); +	}  	if (!ret)  		target_complete_cmd(cmd, GOOD); @@ -851,7 +850,7 @@ static sense_reason_t spc_emulate_modesense(struct se_cmd *cmd)  {  	struct se_device *dev = cmd->se_dev;  	char *cdb = cmd->t_task_cdb; -	unsigned char *buf, *map_buf; +	unsigned char buf[SE_MODE_PAGE_BUF], *rbuf;  	int type = dev->transport->get_device_type(dev);  	int ten = (cmd->t_task_cdb[0] == MODE_SENSE_10);  	bool dbd = !!(cdb[1] & 0x08); @@ -863,26 +862,8 @@ static sense_reason_t spc_emulate_modesense(struct se_cmd *cmd)  	int ret;  	int i; -	map_buf = transport_kmap_data_sg(cmd); -	if (!map_buf) -		return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; -	/* -	 * If SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC is not set, then we -	 * know we actually allocated a full page.  Otherwise, if the -	 * data buffer is too small, allocate a temporary buffer so we -	 * don't have to worry about overruns in all our INQUIRY -	 * emulation handling. -	 */ -	if (cmd->data_length < SE_MODE_PAGE_BUF && -	    (cmd->se_cmd_flags & SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC)) { -		buf = kzalloc(SE_MODE_PAGE_BUF, GFP_KERNEL); -		if (!buf) { -			transport_kunmap_data_sg(cmd); -			return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; -		} -	} else { -		buf = map_buf; -	} +	memset(buf, 0, SE_MODE_PAGE_BUF); +  	/*  	 * Skip over MODE DATA LENGTH + MEDIUM TYPE fields to byte 3 for  	 * MODE_SENSE_10 and byte 2 for MODE_SENSE (6). @@ -934,8 +915,6 @@ static sense_reason_t spc_emulate_modesense(struct se_cmd *cmd)  	if (page == 0x3f) {  		if (subpage != 0x00 && subpage != 0xff) {  			pr_warn("MODE_SENSE: Invalid subpage code: 0x%02x\n", subpage); -			kfree(buf); -			transport_kunmap_data_sg(cmd);  			return TCM_INVALID_CDB_FIELD;  		} @@ -972,7 +951,6 @@ static sense_reason_t spc_emulate_modesense(struct se_cmd *cmd)  		pr_err("MODE SENSE: unimplemented page/subpage: 0x%02x/0x%02x\n",  		       page, subpage); -	transport_kunmap_data_sg(cmd);  	return TCM_UNKNOWN_MODE_PAGE;  set_length: @@ -981,12 +959,12 @@ set_length:  	else  		buf[0] = length - 1; -	if (buf != map_buf) { -		memcpy(map_buf, buf, cmd->data_length); -		kfree(buf); +	rbuf = transport_kmap_data_sg(cmd); +	if (rbuf) { +		memcpy(rbuf, buf, min_t(u32, SE_MODE_PAGE_BUF, cmd->data_length)); +		transport_kunmap_data_sg(cmd);  	} -	transport_kunmap_data_sg(cmd);  	target_complete_cmd(cmd, GOOD);  	return 0;  } diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 4225d5e7213..8e64adf8e4d 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -39,6 +39,7 @@  #include <asm/unaligned.h>  #include <linux/platform_device.h>  #include <linux/workqueue.h> +#include <linux/pm_runtime.h>  #include <linux/usb.h>  #include <linux/usb/hcd.h> @@ -1025,6 +1026,49 @@ static int register_root_hub(struct usb_hcd *hcd)  	return retval;  } +/* + * usb_hcd_start_port_resume - a root-hub port is sending a resume signal + * @bus: the bus which the root hub belongs to + * @portnum: the port which is being resumed + * + * HCDs should call this function when they know that a resume signal is + * being sent to a root-hub port.  The root hub will be prevented from + * going into autosuspend until usb_hcd_end_port_resume() is called. + * + * The bus's private lock must be held by the caller. + */ +void usb_hcd_start_port_resume(struct usb_bus *bus, int portnum) +{ +	unsigned bit = 1 << portnum; + +	if (!(bus->resuming_ports & bit)) { +		bus->resuming_ports |= bit; +		pm_runtime_get_noresume(&bus->root_hub->dev); +	} +} +EXPORT_SYMBOL_GPL(usb_hcd_start_port_resume); + +/* + * usb_hcd_end_port_resume - a root-hub port has stopped sending a resume signal + * @bus: the bus which the root hub belongs to + * @portnum: the port which is being resumed + * + * HCDs should call this function when they know that a resume signal has + * stopped being sent to a root-hub port.  The root hub will be allowed to + * autosuspend again. + * + * The bus's private lock must be held by the caller. + */ +void usb_hcd_end_port_resume(struct usb_bus *bus, int portnum) +{ +	unsigned bit = 1 << portnum; + +	if (bus->resuming_ports & bit) { +		bus->resuming_ports &= ~bit; +		pm_runtime_put_noidle(&bus->root_hub->dev); +	} +} +EXPORT_SYMBOL_GPL(usb_hcd_end_port_resume);  /*-------------------------------------------------------------------------*/ diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 957ed2c4148..cbf7168e3ce 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -2838,6 +2838,23 @@ void usb_enable_ltm(struct usb_device *udev)  EXPORT_SYMBOL_GPL(usb_enable_ltm);  #ifdef	CONFIG_USB_SUSPEND +/* + * usb_disable_function_remotewakeup - disable usb3.0 + * device's function remote wakeup + * @udev: target device + * + * Assume there's only one function on the USB 3.0 + * device and disable remote wake for the first + * interface. FIXME if the interface association + * descriptor shows there's more than one function. + */ +static int usb_disable_function_remotewakeup(struct usb_device *udev) +{ +	return usb_control_msg(udev, usb_sndctrlpipe(udev, 0), +				USB_REQ_CLEAR_FEATURE, USB_RECIP_INTERFACE, +				USB_INTRF_FUNC_SUSPEND,	0, NULL, 0, +				USB_CTRL_SET_TIMEOUT); +}  /*   * usb_port_suspend - suspend a usb device's upstream port @@ -2955,12 +2972,19 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg)  		dev_dbg(hub->intfdev, "can't suspend port %d, status %d\n",  				port1, status);  		/* paranoia:  "should not happen" */ -		if (udev->do_remote_wakeup) -			(void) usb_control_msg(udev, usb_sndctrlpipe(udev, 0), -				USB_REQ_CLEAR_FEATURE, USB_RECIP_DEVICE, -				USB_DEVICE_REMOTE_WAKEUP, 0, -				NULL, 0, -				USB_CTRL_SET_TIMEOUT); +		if (udev->do_remote_wakeup) { +			if (!hub_is_superspeed(hub->hdev)) { +				(void) usb_control_msg(udev, +						usb_sndctrlpipe(udev, 0), +						USB_REQ_CLEAR_FEATURE, +						USB_RECIP_DEVICE, +						USB_DEVICE_REMOTE_WAKEUP, 0, +						NULL, 0, +						USB_CTRL_SET_TIMEOUT); +			} else +				(void) usb_disable_function_remotewakeup(udev); + +		}  		/* Try to enable USB2 hardware LPM again */  		if (udev->usb2_hw_lpm_capable == 1) @@ -3052,20 +3076,30 @@ static int finish_port_resume(struct usb_device *udev)  	 * udev->reset_resume  	 */  	} else if (udev->actconfig && !udev->reset_resume) { -		le16_to_cpus(&devstatus); -		if (devstatus & (1 << USB_DEVICE_REMOTE_WAKEUP)) { -			status = usb_control_msg(udev, -					usb_sndctrlpipe(udev, 0), -					USB_REQ_CLEAR_FEATURE, +		if (!hub_is_superspeed(udev->parent)) { +			le16_to_cpus(&devstatus); +			if (devstatus & (1 << USB_DEVICE_REMOTE_WAKEUP)) +				status = usb_control_msg(udev, +						usb_sndctrlpipe(udev, 0), +						USB_REQ_CLEAR_FEATURE,  						USB_RECIP_DEVICE, -					USB_DEVICE_REMOTE_WAKEUP, 0, -					NULL, 0, -					USB_CTRL_SET_TIMEOUT); -			if (status) -				dev_dbg(&udev->dev, -					"disable remote wakeup, status %d\n", -					status); +						USB_DEVICE_REMOTE_WAKEUP, 0, +						NULL, 0, +						USB_CTRL_SET_TIMEOUT); +		} else { +			status = usb_get_status(udev, USB_RECIP_INTERFACE, 0, +					&devstatus); +			le16_to_cpus(&devstatus); +			if (!status && devstatus & (USB_INTRF_STAT_FUNC_RW_CAP +					| USB_INTRF_STAT_FUNC_RW)) +				status = +					usb_disable_function_remotewakeup(udev);  		} + +		if (status) +			dev_dbg(&udev->dev, +				"disable remote wakeup, status %d\n", +				status);  		status = 0;  	}  	return status; diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 09537b2f100..b416a3fc995 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -797,6 +797,7 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)  			ehci->reset_done[i] = jiffies + msecs_to_jiffies(25);  			set_bit(i, &ehci->resuming_ports);  			ehci_dbg (ehci, "port %d remote wakeup\n", i + 1); +			usb_hcd_start_port_resume(&hcd->self, i);  			mod_timer(&hcd->rh_timer, ehci->reset_done[i]);  		}  	} diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index 4ccb97c0678..4d3b294f203 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c @@ -649,7 +649,11 @@ ehci_hub_status_data (struct usb_hcd *hcd, char *buf)  			status = STS_PCD;  		}  	} -	/* FIXME autosuspend idle root hubs */ + +	/* If a resume is in progress, make sure it can finish */ +	if (ehci->resuming_ports) +		mod_timer(&hcd->rh_timer, jiffies + msecs_to_jiffies(25)); +  	spin_unlock_irqrestore (&ehci->lock, flags);  	return status ? retval : 0;  } @@ -851,6 +855,7 @@ static int ehci_hub_control (  				/* resume signaling for 20 msec */  				ehci->reset_done[wIndex] = jiffies  						+ msecs_to_jiffies(20); +				usb_hcd_start_port_resume(&hcd->self, wIndex);  				/* check the port again */  				mod_timer(&ehci_to_hcd(ehci)->rh_timer,  						ehci->reset_done[wIndex]); @@ -862,6 +867,7 @@ static int ehci_hub_control (  				clear_bit(wIndex, &ehci->suspended_ports);  				set_bit(wIndex, &ehci->port_c_suspend);  				ehci->reset_done[wIndex] = 0; +				usb_hcd_end_port_resume(&hcd->self, wIndex);  				/* stop resume signaling */  				temp = ehci_readl(ehci, status_reg); @@ -950,6 +956,7 @@ static int ehci_hub_control (  			ehci->reset_done[wIndex] = 0;  			if (temp & PORT_PE)  				set_bit(wIndex, &ehci->port_c_suspend); +			usb_hcd_end_port_resume(&hcd->self, wIndex);  		}  		if (temp & PORT_OC) diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index 3d989028c83..fd252f0cfb3 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c @@ -1197,17 +1197,26 @@ static void start_iaa_cycle(struct ehci_hcd *ehci, bool nested)  	if (ehci->async_iaa || ehci->async_unlinking)  		return; -	/* Do all the waiting QHs at once */ -	ehci->async_iaa = ehci->async_unlink; -	ehci->async_unlink = NULL; -  	/* If the controller isn't running, we don't have to wait for it */  	if (unlikely(ehci->rh_state < EHCI_RH_RUNNING)) { + +		/* Do all the waiting QHs */ +		ehci->async_iaa = ehci->async_unlink; +		ehci->async_unlink = NULL; +  		if (!nested)		/* Avoid recursion */  			end_unlink_async(ehci);  	/* Otherwise start a new IAA cycle */  	} else if (likely(ehci->rh_state == EHCI_RH_RUNNING)) { +		struct ehci_qh		*qh; + +		/* Do only the first waiting QH (nVidia bug?) */ +		qh = ehci->async_unlink; +		ehci->async_iaa = qh; +		ehci->async_unlink = qh->unlink_next; +		qh->unlink_next = NULL; +  		/* Make sure the unlinks are all visible to the hardware */  		wmb(); @@ -1255,34 +1264,35 @@ static void end_unlink_async(struct ehci_hcd *ehci)  	}  } +static void start_unlink_async(struct ehci_hcd *ehci, struct ehci_qh *qh); +  static void unlink_empty_async(struct ehci_hcd *ehci)  { -	struct ehci_qh		*qh, *next; -	bool			stopped = (ehci->rh_state < EHCI_RH_RUNNING); +	struct ehci_qh		*qh; +	struct ehci_qh		*qh_to_unlink = NULL;  	bool			check_unlinks_later = false; +	int			count = 0; -	/* Unlink all the async QHs that have been empty for a timer cycle */ -	next = ehci->async->qh_next.qh; -	while (next) { -		qh = next; -		next = qh->qh_next.qh; - +	/* Find the last async QH which has been empty for a timer cycle */ +	for (qh = ehci->async->qh_next.qh; qh; qh = qh->qh_next.qh) {  		if (list_empty(&qh->qtd_list) &&  				qh->qh_state == QH_STATE_LINKED) { -			if (!stopped && qh->unlink_cycle == -					ehci->async_unlink_cycle) +			++count; +			if (qh->unlink_cycle == ehci->async_unlink_cycle)  				check_unlinks_later = true;  			else -				single_unlink_async(ehci, qh); +				qh_to_unlink = qh;  		}  	} -	/* Start a new IAA cycle if any QHs are waiting for it */ -	if (ehci->async_unlink) -		start_iaa_cycle(ehci, false); +	/* If nothing else is being unlinked, unlink the last empty QH */ +	if (!ehci->async_iaa && !ehci->async_unlink && qh_to_unlink) { +		start_unlink_async(ehci, qh_to_unlink); +		--count; +	} -	/* QHs that haven't been empty for long enough will be handled later */ -	if (check_unlinks_later) { +	/* Other QHs will be handled later */ +	if (count > 0) {  		ehci_enable_event(ehci, EHCI_HRTIMER_ASYNC_UNLINKS, true);  		++ehci->async_unlink_cycle;  	} diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index 69ebee73c0c..b476daf49f6 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c @@ -213,7 +213,7 @@ static inline unsigned char tt_start_uframe(struct ehci_hcd *ehci, __hc32 mask)  }  static const unsigned char -max_tt_usecs[] = { 125, 125, 125, 125, 125, 125, 30, 0 }; +max_tt_usecs[] = { 125, 125, 125, 125, 125, 125, 125, 25 };  /* carryover low/fullspeed bandwidth that crosses uframe boundries */  static inline void carryover_tt_bandwidth(unsigned short tt_usecs[8]) @@ -2212,11 +2212,11 @@ static void scan_isoc(struct ehci_hcd *ehci)  	}  	ehci->now_frame = now_frame; +	frame = ehci->last_iso_frame;  	for (;;) {  		union ehci_shadow	q, *q_p;  		__hc32			type, *hw_p; -		frame = ehci->last_iso_frame;  restart:  		/* scan each element in frame's queue for completions */  		q_p = &ehci->pshadow [frame]; @@ -2321,6 +2321,9 @@ restart:  		/* Stop when we have reached the current frame */  		if (frame == now_frame)  			break; -		ehci->last_iso_frame = (frame + 1) & fmask; + +		/* The last frame may still have active siTDs */ +		ehci->last_iso_frame = frame; +		frame = (frame + 1) & fmask;  	}  } diff --git a/drivers/usb/host/ehci-timer.c b/drivers/usb/host/ehci-timer.c index 20dbdcbe9b0..f904071d70d 100644 --- a/drivers/usb/host/ehci-timer.c +++ b/drivers/usb/host/ehci-timer.c @@ -113,14 +113,15 @@ static void ehci_poll_ASS(struct ehci_hcd *ehci)  	if (want != actual) { -		/* Poll again later, but give up after about 20 ms */ -		if (ehci->ASS_poll_count++ < 20) { -			ehci_enable_event(ehci, EHCI_HRTIMER_POLL_ASS, true); -			return; -		} -		ehci_dbg(ehci, "Waited too long for the async schedule status (%x/%x), giving up\n", -				want, actual); +		/* Poll again later */ +		ehci_enable_event(ehci, EHCI_HRTIMER_POLL_ASS, true); +		++ehci->ASS_poll_count; +		return;  	} + +	if (ehci->ASS_poll_count > 20) +		ehci_dbg(ehci, "ASS poll count reached %d\n", +				ehci->ASS_poll_count);  	ehci->ASS_poll_count = 0;  	/* The status is up-to-date; restart or stop the schedule as needed */ @@ -159,14 +160,14 @@ static void ehci_poll_PSS(struct ehci_hcd *ehci)  	if (want != actual) { -		/* Poll again later, but give up after about 20 ms */ -		if (ehci->PSS_poll_count++ < 20) { -			ehci_enable_event(ehci, EHCI_HRTIMER_POLL_PSS, true); -			return; -		} -		ehci_dbg(ehci, "Waited too long for the periodic schedule status (%x/%x), giving up\n", -				want, actual); +		/* Poll again later */ +		ehci_enable_event(ehci, EHCI_HRTIMER_POLL_PSS, true); +		return;  	} + +	if (ehci->PSS_poll_count > 20) +		ehci_dbg(ehci, "PSS poll count reached %d\n", +				ehci->PSS_poll_count);  	ehci->PSS_poll_count = 0;  	/* The status is up-to-date; restart or stop the schedule as needed */ diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c index a3b6d7104ae..4c338ec03a0 100644 --- a/drivers/usb/host/pci-quirks.c +++ b/drivers/usb/host/pci-quirks.c @@ -780,6 +780,7 @@ void usb_enable_xhci_ports(struct pci_dev *xhci_pdev)  				"defaulting to EHCI.\n");  		dev_warn(&xhci_pdev->dev,  				"USB 3.0 devices will work at USB 2.0 speeds.\n"); +		usb_disable_xhci_ports(xhci_pdev);  		return;  	} diff --git a/drivers/usb/host/uhci-hub.c b/drivers/usb/host/uhci-hub.c index 768d54295a2..15d13229ddb 100644 --- a/drivers/usb/host/uhci-hub.c +++ b/drivers/usb/host/uhci-hub.c @@ -116,6 +116,7 @@ static void uhci_finish_suspend(struct uhci_hcd *uhci, int port,  		}  	}  	clear_bit(port, &uhci->resuming_ports); +	usb_hcd_end_port_resume(&uhci_to_hcd(uhci)->self, port);  }  /* Wait for the UHCI controller in HP's iLO2 server management chip. @@ -167,6 +168,8 @@ static void uhci_check_ports(struct uhci_hcd *uhci)  				set_bit(port, &uhci->resuming_ports);  				uhci->ports_timeout = jiffies +  						msecs_to_jiffies(25); +				usb_hcd_start_port_resume( +						&uhci_to_hcd(uhci)->self, port);  				/* Make sure we see the port again  				 * after the resuming period is over. */ diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 59fb5c677db..7f76a49e90d 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -1698,7 +1698,7 @@ static void handle_port_status(struct xhci_hcd *xhci,  				faked_port_index + 1);  		if (slot_id && xhci->devs[slot_id])  			xhci_ring_device(xhci, slot_id); -		if (bus_state->port_remote_wakeup && (1 << faked_port_index)) { +		if (bus_state->port_remote_wakeup & (1 << faked_port_index)) {  			bus_state->port_remote_wakeup &=  				~(1 << faked_port_index);  			xhci_test_and_clear_bit(xhci, port_array, @@ -2589,6 +2589,8 @@ cleanup:  				(trb_comp_code != COMP_STALL &&  					trb_comp_code != COMP_BABBLE))  				xhci_urb_free_priv(xhci, urb_priv); +			else +				kfree(urb_priv);  			usb_hcd_unlink_urb_from_ep(bus_to_hcd(urb->dev->bus), urb);  			if ((urb->actual_length != urb->transfer_buffer_length && @@ -3108,7 +3110,7 @@ static u32 xhci_v1_0_td_remainder(int running_total, int trb_buff_len,  	 * running_total.  	 */  	packets_transferred = (running_total + trb_buff_len) / -		usb_endpoint_maxp(&urb->ep->desc); +		GET_MAX_PACKET(usb_endpoint_maxp(&urb->ep->desc));  	if ((total_packet_count - packets_transferred) > 31)  		return 31 << 17; @@ -3642,7 +3644,8 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags,  		td_len = urb->iso_frame_desc[i].length;  		td_remain_len = td_len;  		total_packet_count = DIV_ROUND_UP(td_len, -				usb_endpoint_maxp(&urb->ep->desc)); +				GET_MAX_PACKET( +					usb_endpoint_maxp(&urb->ep->desc)));  		/* A zero-length transfer still involves at least one packet. */  		if (total_packet_count == 0)  			total_packet_count++; @@ -3664,9 +3667,11 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags,  		td = urb_priv->td[i];  		for (j = 0; j < trbs_per_td; j++) {  			u32 remainder = 0; -			field = TRB_TBC(burst_count) | TRB_TLBPC(residue); +			field = 0;  			if (first_trb) { +				field = TRB_TBC(burst_count) | +					TRB_TLBPC(residue);  				/* Queue the isoc TRB */  				field |= TRB_TYPE(TRB_ISOC);  				/* Assume URB_ISO_ASAP is set */ diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index f14736f647f..edc0f0dcad8 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -60,6 +60,7 @@ static const struct usb_device_id id_table[] = {  	{ USB_DEVICE(0x0FCF, 0x1003) }, /* Dynastream ANT development board */  	{ USB_DEVICE(0x0FCF, 0x1004) }, /* Dynastream ANT2USB */  	{ USB_DEVICE(0x0FCF, 0x1006) }, /* Dynastream ANT development board */ +	{ USB_DEVICE(0x0FDE, 0xCA05) }, /* OWL Wireless Electricity Monitor CM-160 */  	{ USB_DEVICE(0x10A6, 0xAA26) }, /* Knock-off DCU-11 cable */  	{ USB_DEVICE(0x10AB, 0x10C5) }, /* Siemens MC60 Cable */  	{ USB_DEVICE(0x10B5, 0xAC70) }, /* Nokia CA-42 USB */ diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index ba68835d06a..90ceef1776c 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -584,6 +584,7 @@ static struct usb_device_id id_table_combined [] = {  	/*  	 * ELV devices:  	 */ +	{ USB_DEVICE(FTDI_ELV_VID, FTDI_ELV_WS300_PID) },  	{ USB_DEVICE(FTDI_VID, FTDI_ELV_USR_PID) },  	{ USB_DEVICE(FTDI_VID, FTDI_ELV_MSM1_PID) },  	{ USB_DEVICE(FTDI_VID, FTDI_ELV_KL100_PID) }, @@ -670,6 +671,7 @@ static struct usb_device_id id_table_combined [] = {  	{ USB_DEVICE(FTDI_VID, XSENS_CONVERTER_5_PID) },  	{ USB_DEVICE(FTDI_VID, XSENS_CONVERTER_6_PID) },  	{ USB_DEVICE(FTDI_VID, XSENS_CONVERTER_7_PID) }, +	{ USB_DEVICE(FTDI_VID, FTDI_OMNI1509) },  	{ USB_DEVICE(MOBILITY_VID, MOBILITY_USB_SERIAL_PID) },  	{ USB_DEVICE(FTDI_VID, FTDI_ACTIVE_ROBOTS_PID) },  	{ USB_DEVICE(FTDI_VID, FTDI_MHAM_KW_PID) }, diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h index fa5d5603827..9d359e189a6 100644 --- a/drivers/usb/serial/ftdi_sio_ids.h +++ b/drivers/usb/serial/ftdi_sio_ids.h @@ -147,6 +147,11 @@  #define XSENS_CONVERTER_6_PID	0xD38E  #define XSENS_CONVERTER_7_PID	0xD38F +/** + * Zolix (www.zolix.com.cb) product ids + */ +#define FTDI_OMNI1509			0xD491	/* Omni1509 embedded USB-serial */ +  /*   * NDI (www.ndigital.com) product ids   */ @@ -204,7 +209,7 @@  /*   * ELV USB devices submitted by Christian Abt of ELV (www.elv.de). - * All of these devices use FTDI's vendor ID (0x0403). + * Almost all of these devices use FTDI's vendor ID (0x0403).   * Further IDs taken from ELV Windows .inf file.   *   * The previously included PID for the UO 100 module was incorrect. @@ -212,6 +217,8 @@   *   * Armin Laeuger originally sent the PID for the UM 100 module.   */ +#define FTDI_ELV_VID	0x1B1F	/* ELV AG */ +#define FTDI_ELV_WS300_PID	0xC006	/* eQ3 WS 300 PC II */  #define FTDI_ELV_USR_PID	0xE000	/* ELV Universal-Sound-Recorder */  #define FTDI_ELV_MSM1_PID	0xE001	/* ELV Mini-Sound-Modul */  #define FTDI_ELV_KL100_PID	0xE002	/* ELV Kfz-Leistungsmesser KL 100 */ diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 0d9dac9e7f9..567bc77d639 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -242,6 +242,7 @@ static void option_instat_callback(struct urb *urb);  #define TELIT_PRODUCT_CC864_DUAL		0x1005  #define TELIT_PRODUCT_CC864_SINGLE		0x1006  #define TELIT_PRODUCT_DE910_DUAL		0x1010 +#define TELIT_PRODUCT_LE920			0x1200  /* ZTE PRODUCTS */  #define ZTE_VENDOR_ID				0x19d2 @@ -453,6 +454,10 @@ static void option_instat_callback(struct urb *urb);  #define TPLINK_VENDOR_ID			0x2357  #define TPLINK_PRODUCT_MA180			0x0201 +/* Changhong products */ +#define CHANGHONG_VENDOR_ID			0x2077 +#define CHANGHONG_PRODUCT_CH690			0x7001 +  /* some devices interfaces need special handling due to a number of reasons */  enum option_blacklist_reason {  		OPTION_BLACKLIST_NONE = 0, @@ -534,6 +539,11 @@ static const struct option_blacklist_info zte_1255_blacklist = {  	.reserved = BIT(3) | BIT(4),  }; +static const struct option_blacklist_info telit_le920_blacklist = { +	.sendsetup = BIT(0), +	.reserved = BIT(1) | BIT(5), +}; +  static const struct usb_device_id option_ids[] = {  	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) },  	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) }, @@ -784,6 +794,8 @@ static const struct usb_device_id option_ids[] = {  	{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_CC864_DUAL) },  	{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_CC864_SINGLE) },  	{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_DE910_DUAL) }, +	{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE920), +		.driver_info = (kernel_ulong_t)&telit_le920_blacklist },  	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622, 0xff, 0xff, 0xff) }, /* ZTE WCDMA products */  	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0002, 0xff, 0xff, 0xff),  		.driver_info = (kernel_ulong_t)&net_intf1_blacklist }, @@ -1318,6 +1330,7 @@ static const struct usb_device_id option_ids[] = {  	{ USB_DEVICE(PETATEL_VENDOR_ID, PETATEL_PRODUCT_NP10T) },  	{ USB_DEVICE(TPLINK_VENDOR_ID, TPLINK_PRODUCT_MA180),  	  .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, +	{ USB_DEVICE(CHANGHONG_VENDOR_ID, CHANGHONG_PRODUCT_CH690) },  	{ } /* Terminating entry */  };  MODULE_DEVICE_TABLE(usb, option_ids); diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c index aa148c21ea4..24662547dc5 100644 --- a/drivers/usb/serial/qcserial.c +++ b/drivers/usb/serial/qcserial.c @@ -53,6 +53,7 @@ static const struct usb_device_id id_table[] = {  	{DEVICE_G1K(0x05c6, 0x9221)},	/* Generic Gobi QDL device */  	{DEVICE_G1K(0x05c6, 0x9231)},	/* Generic Gobi QDL device */  	{DEVICE_G1K(0x1f45, 0x0001)},	/* Unknown Gobi QDL device */ +	{DEVICE_G1K(0x1bc7, 0x900e)},	/* Telit Gobi QDL device */  	/* Gobi 2000 devices */  	{USB_DEVICE(0x1410, 0xa010)},	/* Novatel Gobi 2000 QDL device */ diff --git a/drivers/usb/storage/initializers.c b/drivers/usb/storage/initializers.c index 105d900150c..16b0bf055ee 100644 --- a/drivers/usb/storage/initializers.c +++ b/drivers/usb/storage/initializers.c @@ -92,8 +92,8 @@ int usb_stor_ucr61s2b_init(struct us_data *us)  	return 0;  } -/* This places the HUAWEI E220 devices in multi-port mode */ -int usb_stor_huawei_e220_init(struct us_data *us) +/* This places the HUAWEI usb dongles in multi-port mode */ +static int usb_stor_huawei_feature_init(struct us_data *us)  {  	int result; @@ -104,3 +104,75 @@ int usb_stor_huawei_e220_init(struct us_data *us)  	US_DEBUGP("Huawei mode set result is %d\n", result);  	return 0;  } + +/* + * It will send a scsi switch command called rewind' to huawei dongle. + * When the dongle receives this command at the first time, + * it will reboot immediately. After rebooted, it will ignore this command. + * So it is  unnecessary to read its response. + */ +static int usb_stor_huawei_scsi_init(struct us_data *us) +{ +	int result = 0; +	int act_len = 0; +	struct bulk_cb_wrap *bcbw = (struct bulk_cb_wrap *) us->iobuf; +	char rewind_cmd[] = {0x11, 0x06, 0x20, 0x00, 0x00, 0x01, 0x01, 0x00, +			0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + +	bcbw->Signature = cpu_to_le32(US_BULK_CB_SIGN); +	bcbw->Tag = 0; +	bcbw->DataTransferLength = 0; +	bcbw->Flags = bcbw->Lun = 0; +	bcbw->Length = sizeof(rewind_cmd); +	memset(bcbw->CDB, 0, sizeof(bcbw->CDB)); +	memcpy(bcbw->CDB, rewind_cmd, sizeof(rewind_cmd)); + +	result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, bcbw, +					US_BULK_CB_WRAP_LEN, &act_len); +	US_DEBUGP("transfer actual length=%d, result=%d\n", act_len, result); +	return result; +} + +/* + * It tries to find the supported Huawei USB dongles. + * In Huawei, they assign the following product IDs + * for all of their mobile broadband dongles, + * including the new dongles in the future. + * So if the product ID is not included in this list, + * it means it is not Huawei's mobile broadband dongles. + */ +static int usb_stor_huawei_dongles_pid(struct us_data *us) +{ +	struct usb_interface_descriptor *idesc; +	int idProduct; + +	idesc = &us->pusb_intf->cur_altsetting->desc; +	idProduct = us->pusb_dev->descriptor.idProduct; +	/* The first port is CDROM, +	 * means the dongle in the single port mode, +	 * and a switch command is required to be sent. */ +	if (idesc && idesc->bInterfaceNumber == 0) { +		if ((idProduct == 0x1001) +			|| (idProduct == 0x1003) +			|| (idProduct == 0x1004) +			|| (idProduct >= 0x1401 && idProduct <= 0x1500) +			|| (idProduct >= 0x1505 && idProduct <= 0x1600) +			|| (idProduct >= 0x1c02 && idProduct <= 0x2202)) { +			return 1; +		} +	} +	return 0; +} + +int usb_stor_huawei_init(struct us_data *us) +{ +	int result = 0; + +	if (usb_stor_huawei_dongles_pid(us)) { +		if (us->pusb_dev->descriptor.idProduct >= 0x1446) +			result = usb_stor_huawei_scsi_init(us); +		else +			result = usb_stor_huawei_feature_init(us); +	} +	return result; +} diff --git a/drivers/usb/storage/initializers.h b/drivers/usb/storage/initializers.h index 529327fbb06..5376d4fc76f 100644 --- a/drivers/usb/storage/initializers.h +++ b/drivers/usb/storage/initializers.h @@ -46,5 +46,5 @@ int usb_stor_euscsi_init(struct us_data *us);   * flash reader */  int usb_stor_ucr61s2b_init(struct us_data *us); -/* This places the HUAWEI E220 devices in multi-port mode */ -int usb_stor_huawei_e220_init(struct us_data *us); +/* This places the HUAWEI usb dongles in multi-port mode */ +int usb_stor_huawei_init(struct us_data *us); diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index d305a5aa3a5..72923b56bbf 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -1527,335 +1527,10 @@ UNUSUAL_DEV(  0x1210, 0x0003, 0x0100, 0x0100,  /* Reported by fangxiaozhi <huananhu@huawei.com>   * This brings the HUAWEI data card devices into multi-port mode   */ -UNUSUAL_DEV(  0x12d1, 0x1001, 0x0000, 0x0000, +UNUSUAL_VENDOR_INTF(0x12d1, 0x08, 0x06, 0x50,  		"HUAWEI MOBILE",  		"Mass Storage", -		USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, -		0), -UNUSUAL_DEV(  0x12d1, 0x1003, 0x0000, 0x0000, -		"HUAWEI MOBILE", -		"Mass Storage", -		USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, -		0), -UNUSUAL_DEV(  0x12d1, 0x1004, 0x0000, 0x0000, -		"HUAWEI MOBILE", -		"Mass Storage", -		USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, -		0), -UNUSUAL_DEV(  0x12d1, 0x1401, 0x0000, 0x0000, -		"HUAWEI MOBILE", -		"Mass Storage", -		USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, -		0), -UNUSUAL_DEV(  0x12d1, 0x1402, 0x0000, 0x0000, -		"HUAWEI MOBILE", -		"Mass Storage", -		USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, -		0), -UNUSUAL_DEV(  0x12d1, 0x1403, 0x0000, 0x0000, -		"HUAWEI MOBILE", -		"Mass Storage", -		USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, -		0), -UNUSUAL_DEV(  0x12d1, 0x1404, 0x0000, 0x0000, -		"HUAWEI MOBILE", -		"Mass Storage", -		USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, -		0), -UNUSUAL_DEV(  0x12d1, 0x1405, 0x0000, 0x0000, -		"HUAWEI MOBILE", -		"Mass Storage", -		USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, -		0), -UNUSUAL_DEV(  0x12d1, 0x1406, 0x0000, 0x0000, -		"HUAWEI MOBILE", -		"Mass Storage", -		USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, -		0), -UNUSUAL_DEV(  0x12d1, 0x1407, 0x0000, 0x0000, -		"HUAWEI MOBILE", -		"Mass Storage", -		USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, -		0), -UNUSUAL_DEV(  0x12d1, 0x1408, 0x0000, 0x0000, -		"HUAWEI MOBILE", -		"Mass Storage", -		USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, -		0), -UNUSUAL_DEV(  0x12d1, 0x1409, 0x0000, 0x0000, -		"HUAWEI MOBILE", -		"Mass Storage", -		USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, -		0), -UNUSUAL_DEV(  0x12d1, 0x140A, 0x0000, 0x0000, -		"HUAWEI MOBILE", -		"Mass Storage", -		USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, -		0), -UNUSUAL_DEV(  0x12d1, 0x140B, 0x0000, 0x0000, -		"HUAWEI MOBILE", -		"Mass Storage", -		USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, -		0), -UNUSUAL_DEV(  0x12d1, 0x140C, 0x0000, 0x0000, -		"HUAWEI MOBILE", -		"Mass Storage", -		USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, -		0), -UNUSUAL_DEV(  0x12d1, 0x140D, 0x0000, 0x0000, -		"HUAWEI MOBILE", -		"Mass Storage", -		USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, -		0), -UNUSUAL_DEV(  0x12d1, 0x140E, 0x0000, 0x0000, -		"HUAWEI MOBILE", -		"Mass Storage", -		USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, -		0), -UNUSUAL_DEV(  0x12d1, 0x140F, 0x0000, 0x0000, -		"HUAWEI MOBILE", -		"Mass Storage", -		USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, -		0), -UNUSUAL_DEV(  0x12d1, 0x1410, 0x0000, 0x0000, -		"HUAWEI MOBILE", -		"Mass Storage", -		USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, -		0), -UNUSUAL_DEV(  0x12d1, 0x1411, 0x0000, 0x0000, -		"HUAWEI MOBILE", -		"Mass Storage", -		USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, -		0), -UNUSUAL_DEV(  0x12d1, 0x1412, 0x0000, 0x0000, -		"HUAWEI MOBILE", -		"Mass Storage", -		USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, -		0), -UNUSUAL_DEV(  0x12d1, 0x1413, 0x0000, 0x0000, -		"HUAWEI MOBILE", -		"Mass Storage", -		USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, -		0), -UNUSUAL_DEV(  0x12d1, 0x1414, 0x0000, 0x0000, -		"HUAWEI MOBILE", -		"Mass Storage", -		USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, -		0), -UNUSUAL_DEV(  0x12d1, 0x1415, 0x0000, 0x0000, -		"HUAWEI MOBILE", -		"Mass Storage", -		USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, -		0), -UNUSUAL_DEV(  0x12d1, 0x1416, 0x0000, 0x0000, -		"HUAWEI MOBILE", -		"Mass Storage", -		USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, -		0), -UNUSUAL_DEV(  0x12d1, 0x1417, 0x0000, 0x0000, -		"HUAWEI MOBILE", -		"Mass Storage", -		USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, -		0), -UNUSUAL_DEV(  0x12d1, 0x1418, 0x0000, 0x0000, -		"HUAWEI MOBILE", -		"Mass Storage", -		USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, -		0), -UNUSUAL_DEV(  0x12d1, 0x1419, 0x0000, 0x0000, -		"HUAWEI MOBILE", -		"Mass Storage", -		USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, -		0), -UNUSUAL_DEV(  0x12d1, 0x141A, 0x0000, 0x0000, -		"HUAWEI MOBILE", -		"Mass Storage", -		USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, -		0), -UNUSUAL_DEV(  0x12d1, 0x141B, 0x0000, 0x0000, -		"HUAWEI MOBILE", -		"Mass Storage", -		USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, -		0), -UNUSUAL_DEV(  0x12d1, 0x141C, 0x0000, 0x0000, -		"HUAWEI MOBILE", -		"Mass Storage", -		USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, -		0), -UNUSUAL_DEV(  0x12d1, 0x141D, 0x0000, 0x0000, -		"HUAWEI MOBILE", -		"Mass Storage", -		USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, -		0), -UNUSUAL_DEV(  0x12d1, 0x141E, 0x0000, 0x0000, -		"HUAWEI MOBILE", -		"Mass Storage", -		USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, -		0), -UNUSUAL_DEV(  0x12d1, 0x141F, 0x0000, 0x0000, -		"HUAWEI MOBILE", -		"Mass Storage", -		USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, -		0), -UNUSUAL_DEV(  0x12d1, 0x1420, 0x0000, 0x0000, -		"HUAWEI MOBILE", -		"Mass Storage", -		USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, -		0), -UNUSUAL_DEV(  0x12d1, 0x1421, 0x0000, 0x0000, -		"HUAWEI MOBILE", -		"Mass Storage", -		USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, -		0), -UNUSUAL_DEV(  0x12d1, 0x1422, 0x0000, 0x0000, -		"HUAWEI MOBILE", -		"Mass Storage", -		USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, -		0), -UNUSUAL_DEV(  0x12d1, 0x1423, 0x0000, 0x0000, -		"HUAWEI MOBILE", -		"Mass Storage", -		USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, -		0), -UNUSUAL_DEV(  0x12d1, 0x1424, 0x0000, 0x0000, -		"HUAWEI MOBILE", -		"Mass Storage", -		USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, -		0), -UNUSUAL_DEV(  0x12d1, 0x1425, 0x0000, 0x0000, -		"HUAWEI MOBILE", -		"Mass Storage", -		USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, -		0), -UNUSUAL_DEV(  0x12d1, 0x1426, 0x0000, 0x0000, -		"HUAWEI MOBILE", -		"Mass Storage", -		USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, -		0), -UNUSUAL_DEV(  0x12d1, 0x1427, 0x0000, 0x0000, -		"HUAWEI MOBILE", -		"Mass Storage", -		USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, -		0), -UNUSUAL_DEV(  0x12d1, 0x1428, 0x0000, 0x0000, -		"HUAWEI MOBILE", -		"Mass Storage", -		USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, -		0), -UNUSUAL_DEV(  0x12d1, 0x1429, 0x0000, 0x0000, -		"HUAWEI MOBILE", -		"Mass Storage", -		USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, -		0), -UNUSUAL_DEV(  0x12d1, 0x142A, 0x0000, 0x0000, -		"HUAWEI MOBILE", -		"Mass Storage", -		USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, -		0), -UNUSUAL_DEV(  0x12d1, 0x142B, 0x0000, 0x0000, -		"HUAWEI MOBILE", -		"Mass Storage", -		USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, -		0), -UNUSUAL_DEV(  0x12d1, 0x142C, 0x0000, 0x0000, -		"HUAWEI MOBILE", -		"Mass Storage", -		USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, -		0), -UNUSUAL_DEV(  0x12d1, 0x142D, 0x0000, 0x0000, -		"HUAWEI MOBILE", -		"Mass Storage", -		USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, -		0), -UNUSUAL_DEV(  0x12d1, 0x142E, 0x0000, 0x0000, -		"HUAWEI MOBILE", -		"Mass Storage", -		USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, -		0), -UNUSUAL_DEV(  0x12d1, 0x142F, 0x0000, 0x0000, -		"HUAWEI MOBILE", -		"Mass Storage", -		USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, -		0), -UNUSUAL_DEV(  0x12d1, 0x1430, 0x0000, 0x0000, -		"HUAWEI MOBILE", -		"Mass Storage", -		USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, -		0), -UNUSUAL_DEV(  0x12d1, 0x1431, 0x0000, 0x0000, -		"HUAWEI MOBILE", -		"Mass Storage", -		USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, -		0), -UNUSUAL_DEV(  0x12d1, 0x1432, 0x0000, 0x0000, -		"HUAWEI MOBILE", -		"Mass Storage", -		USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, -		0), -UNUSUAL_DEV(  0x12d1, 0x1433, 0x0000, 0x0000, -		"HUAWEI MOBILE", -		"Mass Storage", -		USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, -		0), -UNUSUAL_DEV(  0x12d1, 0x1434, 0x0000, 0x0000, -		"HUAWEI MOBILE", -		"Mass Storage", -		USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, -		0), -UNUSUAL_DEV(  0x12d1, 0x1435, 0x0000, 0x0000, -		"HUAWEI MOBILE", -		"Mass Storage", -		USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, -		0), -UNUSUAL_DEV(  0x12d1, 0x1436, 0x0000, 0x0000, -		"HUAWEI MOBILE", -		"Mass Storage", -		USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, -		0), -UNUSUAL_DEV(  0x12d1, 0x1437, 0x0000, 0x0000, -		"HUAWEI MOBILE", -		"Mass Storage", -		USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, -		0), -UNUSUAL_DEV(  0x12d1, 0x1438, 0x0000, 0x0000, -		"HUAWEI MOBILE", -		"Mass Storage", -		USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, -		0), -UNUSUAL_DEV(  0x12d1, 0x1439, 0x0000, 0x0000, -		"HUAWEI MOBILE", -		"Mass Storage", -		USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, -		0), -UNUSUAL_DEV(  0x12d1, 0x143A, 0x0000, 0x0000, -		"HUAWEI MOBILE", -		"Mass Storage", -		USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, -		0), -UNUSUAL_DEV(  0x12d1, 0x143B, 0x0000, 0x0000, -		"HUAWEI MOBILE", -		"Mass Storage", -		USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, -		0), -UNUSUAL_DEV(  0x12d1, 0x143C, 0x0000, 0x0000, -		"HUAWEI MOBILE", -		"Mass Storage", -		USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, -		0), -UNUSUAL_DEV(  0x12d1, 0x143D, 0x0000, 0x0000, -		"HUAWEI MOBILE", -		"Mass Storage", -		USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, -		0), -UNUSUAL_DEV(  0x12d1, 0x143E, 0x0000, 0x0000, -		"HUAWEI MOBILE", -		"Mass Storage", -		USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, -		0), -UNUSUAL_DEV(  0x12d1, 0x143F, 0x0000, 0x0000, -		"HUAWEI MOBILE", -		"Mass Storage", -		USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, +		USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_init,  		0),  /* Reported by Vilius Bilinkevicius <vilisas AT xxx DOT lt) */ diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index 31b3e1a61bb..cf09b6ba71f 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c @@ -120,6 +120,17 @@ MODULE_PARM_DESC(quirks, "supplemental list of device IDs and their quirks");  	.useTransport = use_transport,	\  } +#define UNUSUAL_VENDOR_INTF(idVendor, cl, sc, pr, \ +		vendor_name, product_name, use_protocol, use_transport, \ +		init_function, Flags) \ +{ \ +	.vendorName = vendor_name,	\ +	.productName = product_name,	\ +	.useProtocol = use_protocol,	\ +	.useTransport = use_transport,	\ +	.initFunction = init_function,	\ +} +  static struct us_unusual_dev us_unusual_dev_list[] = {  #	include "unusual_devs.h"  	{ }		/* Terminating entry */ @@ -131,6 +142,7 @@ static struct us_unusual_dev for_dynamic_ids =  #undef UNUSUAL_DEV  #undef COMPLIANT_DEV  #undef USUAL_DEV +#undef UNUSUAL_VENDOR_INTF  #ifdef CONFIG_LOCKDEP diff --git a/drivers/usb/storage/usual-tables.c b/drivers/usb/storage/usual-tables.c index b78a526910f..5ef8ce74aae 100644 --- a/drivers/usb/storage/usual-tables.c +++ b/drivers/usb/storage/usual-tables.c @@ -41,6 +41,20 @@  #define USUAL_DEV(useProto, useTrans) \  { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, useProto, useTrans) } +/* Define the device is matched with Vendor ID and interface descriptors */ +#define UNUSUAL_VENDOR_INTF(id_vendor, cl, sc, pr, \ +			vendorName, productName, useProtocol, useTransport, \ +			initFunction, flags) \ +{ \ +	.match_flags = USB_DEVICE_ID_MATCH_INT_INFO \ +				| USB_DEVICE_ID_MATCH_VENDOR, \ +	.idVendor    = (id_vendor), \ +	.bInterfaceClass = (cl), \ +	.bInterfaceSubClass = (sc), \ +	.bInterfaceProtocol = (pr), \ +	.driver_info = (flags) \ +} +  struct usb_device_id usb_storage_usb_ids[] = {  #	include "unusual_devs.h"  	{ }		/* Terminating entry */ @@ -50,6 +64,7 @@ MODULE_DEVICE_TABLE(usb, usb_storage_usb_ids);  #undef UNUSUAL_DEV  #undef COMPLIANT_DEV  #undef USUAL_DEV +#undef UNUSUAL_VENDOR_INTF  /*   * The table of devices to ignore diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c index ebd08b21b23..959b1cd89e6 100644 --- a/drivers/vhost/net.c +++ b/drivers/vhost/net.c @@ -165,12 +165,16 @@ static void tx_poll_stop(struct vhost_net *net)  }  /* Caller must have TX VQ lock */ -static void tx_poll_start(struct vhost_net *net, struct socket *sock) +static int tx_poll_start(struct vhost_net *net, struct socket *sock)  { +	int ret; +  	if (unlikely(net->tx_poll_state != VHOST_NET_POLL_STOPPED)) -		return; -	vhost_poll_start(net->poll + VHOST_NET_VQ_TX, sock->file); -	net->tx_poll_state = VHOST_NET_POLL_STARTED; +		return 0; +	ret = vhost_poll_start(net->poll + VHOST_NET_VQ_TX, sock->file); +	if (!ret) +		net->tx_poll_state = VHOST_NET_POLL_STARTED; +	return ret;  }  /* In case of DMA done not in order in lower device driver for some reason. @@ -642,20 +646,23 @@ static void vhost_net_disable_vq(struct vhost_net *n,  		vhost_poll_stop(n->poll + VHOST_NET_VQ_RX);  } -static void vhost_net_enable_vq(struct vhost_net *n, +static int vhost_net_enable_vq(struct vhost_net *n,  				struct vhost_virtqueue *vq)  {  	struct socket *sock; +	int ret;  	sock = rcu_dereference_protected(vq->private_data,  					 lockdep_is_held(&vq->mutex));  	if (!sock) -		return; +		return 0;  	if (vq == n->vqs + VHOST_NET_VQ_TX) {  		n->tx_poll_state = VHOST_NET_POLL_STOPPED; -		tx_poll_start(n, sock); +		ret = tx_poll_start(n, sock);  	} else -		vhost_poll_start(n->poll + VHOST_NET_VQ_RX, sock->file); +		ret = vhost_poll_start(n->poll + VHOST_NET_VQ_RX, sock->file); + +	return ret;  }  static struct socket *vhost_net_stop_vq(struct vhost_net *n, @@ -827,15 +834,18 @@ static long vhost_net_set_backend(struct vhost_net *n, unsigned index, int fd)  			r = PTR_ERR(ubufs);  			goto err_ubufs;  		} -		oldubufs = vq->ubufs; -		vq->ubufs = ubufs; +  		vhost_net_disable_vq(n, vq);  		rcu_assign_pointer(vq->private_data, sock); -		vhost_net_enable_vq(n, vq); -  		r = vhost_init_used(vq);  		if (r) -			goto err_vq; +			goto err_used; +		r = vhost_net_enable_vq(n, vq); +		if (r) +			goto err_used; + +		oldubufs = vq->ubufs; +		vq->ubufs = ubufs;  		n->tx_packets = 0;  		n->tx_zcopy_err = 0; @@ -859,6 +869,11 @@ static long vhost_net_set_backend(struct vhost_net *n, unsigned index, int fd)  	mutex_unlock(&n->dev.mutex);  	return 0; +err_used: +	rcu_assign_pointer(vq->private_data, oldsock); +	vhost_net_enable_vq(n, vq); +	if (ubufs) +		vhost_ubuf_put_and_wait(ubufs);  err_ubufs:  	fput(sock->file);  err_vq: diff --git a/drivers/vhost/tcm_vhost.c b/drivers/vhost/tcm_vhost.c index b20df5c829f..22321cf84fb 100644 --- a/drivers/vhost/tcm_vhost.c +++ b/drivers/vhost/tcm_vhost.c @@ -575,10 +575,8 @@ static void vhost_scsi_handle_vq(struct vhost_scsi *vs)  	/* Must use ioctl VHOST_SCSI_SET_ENDPOINT */  	tv_tpg = vs->vs_tpg; -	if (unlikely(!tv_tpg)) { -		pr_err("%s endpoint not set\n", __func__); +	if (unlikely(!tv_tpg))  		return; -	}  	mutex_lock(&vq->mutex);  	vhost_disable_notify(&vs->dev, vq); diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index 34389f75fe6..9759249e6d9 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c @@ -77,26 +77,38 @@ void vhost_poll_init(struct vhost_poll *poll, vhost_work_fn_t fn,  	init_poll_funcptr(&poll->table, vhost_poll_func);  	poll->mask = mask;  	poll->dev = dev; +	poll->wqh = NULL;  	vhost_work_init(&poll->work, fn);  }  /* Start polling a file. We add ourselves to file's wait queue. The caller must   * keep a reference to a file until after vhost_poll_stop is called. */ -void vhost_poll_start(struct vhost_poll *poll, struct file *file) +int vhost_poll_start(struct vhost_poll *poll, struct file *file)  {  	unsigned long mask; +	int ret = 0;  	mask = file->f_op->poll(file, &poll->table);  	if (mask)  		vhost_poll_wakeup(&poll->wait, 0, 0, (void *)mask); +	if (mask & POLLERR) { +		if (poll->wqh) +			remove_wait_queue(poll->wqh, &poll->wait); +		ret = -EINVAL; +	} + +	return ret;  }  /* Stop polling a file. After this function returns, it becomes safe to drop the   * file reference. You must also flush afterwards. */  void vhost_poll_stop(struct vhost_poll *poll)  { -	remove_wait_queue(poll->wqh, &poll->wait); +	if (poll->wqh) { +		remove_wait_queue(poll->wqh, &poll->wait); +		poll->wqh = NULL; +	}  }  static bool vhost_work_seq_done(struct vhost_dev *dev, struct vhost_work *work, @@ -792,7 +804,7 @@ long vhost_vring_ioctl(struct vhost_dev *d, int ioctl, void __user *argp)  		fput(filep);  	if (pollstart && vq->handle_kick) -		vhost_poll_start(&vq->poll, vq->kick); +		r = vhost_poll_start(&vq->poll, vq->kick);  	mutex_unlock(&vq->mutex); diff --git a/drivers/vhost/vhost.h b/drivers/vhost/vhost.h index 2639c58b23a..17261e277c0 100644 --- a/drivers/vhost/vhost.h +++ b/drivers/vhost/vhost.h @@ -42,7 +42,7 @@ void vhost_work_queue(struct vhost_dev *dev, struct vhost_work *work);  void vhost_poll_init(struct vhost_poll *poll, vhost_work_fn_t fn,  		     unsigned long mask, struct vhost_dev *dev); -void vhost_poll_start(struct vhost_poll *poll, struct file *file); +int vhost_poll_start(struct vhost_poll *poll, struct file *file);  void vhost_poll_stop(struct vhost_poll *poll);  void vhost_poll_flush(struct vhost_poll *poll);  void vhost_poll_queue(struct vhost_poll *poll); diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c index 12526787a7c..0abf2bf2083 100644 --- a/drivers/video/imxfb.c +++ b/drivers/video/imxfb.c @@ -139,6 +139,7 @@ struct imxfb_info {  	struct clk		*clk_ahb;  	struct clk		*clk_per;  	enum imxfb_type		devtype; +	bool			enabled;  	/*  	 * These are the addresses we mapped @@ -536,6 +537,10 @@ static void imxfb_exit_backlight(struct imxfb_info *fbi)  static void imxfb_enable_controller(struct imxfb_info *fbi)  { + +	if (fbi->enabled) +		return; +  	pr_debug("Enabling LCD controller\n");  	writel(fbi->screen_dma, fbi->regs + LCDC_SSA); @@ -556,6 +561,7 @@ static void imxfb_enable_controller(struct imxfb_info *fbi)  	clk_prepare_enable(fbi->clk_ipg);  	clk_prepare_enable(fbi->clk_ahb);  	clk_prepare_enable(fbi->clk_per); +	fbi->enabled = true;  	if (fbi->backlight_power)  		fbi->backlight_power(1); @@ -565,6 +571,9 @@ static void imxfb_enable_controller(struct imxfb_info *fbi)  static void imxfb_disable_controller(struct imxfb_info *fbi)  { +	if (!fbi->enabled) +		return; +  	pr_debug("Disabling LCD controller\n");  	if (fbi->backlight_power) @@ -575,6 +584,7 @@ static void imxfb_disable_controller(struct imxfb_info *fbi)  	clk_disable_unprepare(fbi->clk_per);  	clk_disable_unprepare(fbi->clk_ipg);  	clk_disable_unprepare(fbi->clk_ahb); +	fbi->enabled = false;  	writel(0, fbi->regs + LCDC_RMCR);  } @@ -729,6 +739,8 @@ static int __init imxfb_init_fbinfo(struct platform_device *pdev)  	memset(fbi, 0, sizeof(struct imxfb_info)); +	fbi->devtype = pdev->id_entry->driver_data; +  	strlcpy(info->fix.id, IMX_NAME, sizeof(info->fix.id));  	info->fix.type			= FB_TYPE_PACKED_PIXELS; @@ -789,7 +801,6 @@ static int __init imxfb_probe(struct platform_device *pdev)  		return -ENOMEM;  	fbi = info->par; -	fbi->devtype = pdev->id_entry->driver_data;  	if (!fb_mode)  		fb_mode = pdata->mode[0].mode.name; diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c index 18688c12e30..d7d66ef5cb5 100644 --- a/drivers/video/omap2/dss/dss_features.c +++ b/drivers/video/omap2/dss/dss_features.c @@ -538,6 +538,7 @@ static const enum dss_feat_id omap3630_dss_feat_list[] = {  	FEAT_ALPHA_FIXED_ZORDER,  	FEAT_FIFO_MERGE,  	FEAT_OMAP3_DSI_FIFO_BUG, +	FEAT_DPI_USES_VDDS_DSI,  };  static const enum dss_feat_id omap4430_es1_0_dss_feat_list[] = { diff --git a/drivers/xen/events.c b/drivers/xen/events.c index 0be4df39e95..74d77dfa5f6 100644 --- a/drivers/xen/events.c +++ b/drivers/xen/events.c @@ -840,7 +840,7 @@ int bind_evtchn_to_irq(unsigned int evtchn)  	if (irq == -1) {  		irq = xen_allocate_irq_dynamic(); -		if (irq == -1) +		if (irq < 0)  			goto out;  		irq_set_chip_and_handler_name(irq, &xen_dynamic_chip, @@ -944,7 +944,7 @@ int bind_virq_to_irq(unsigned int virq, unsigned int cpu)  	if (irq == -1) {  		irq = xen_allocate_irq_dynamic(); -		if (irq == -1) +		if (irq < 0)  			goto out;  		irq_set_chip_and_handler_name(irq, &xen_percpu_chip, diff --git a/drivers/xen/pcpu.c b/drivers/xen/pcpu.c index 067fcfa1723..5a27a4599a4 100644 --- a/drivers/xen/pcpu.c +++ b/drivers/xen/pcpu.c @@ -278,8 +278,7 @@ static int sync_pcpu(uint32_t cpu, uint32_t *max_cpu)  	 * Only those at cpu present map has its sys interface.  	 */  	if (info->flags & XEN_PCPU_FLAGS_INVALID) { -		if (pcpu) -			unregister_and_remove_pcpu(pcpu); +		unregister_and_remove_pcpu(pcpu);  		return 0;  	} diff --git a/drivers/xen/xen-pciback/pciback_ops.c b/drivers/xen/xen-pciback/pciback_ops.c index 97f5d264c31..37c1f825f51 100644 --- a/drivers/xen/xen-pciback/pciback_ops.c +++ b/drivers/xen/xen-pciback/pciback_ops.c @@ -135,7 +135,6 @@ int xen_pcibk_enable_msi(struct xen_pcibk_device *pdev,  			 struct pci_dev *dev, struct xen_pci_op *op)  {  	struct xen_pcibk_dev_data *dev_data; -	int otherend = pdev->xdev->otherend_id;  	int status;  	if (unlikely(verbose_request)) @@ -144,8 +143,9 @@ int xen_pcibk_enable_msi(struct xen_pcibk_device *pdev,  	status = pci_enable_msi(dev);  	if (status) { -		printk(KERN_ERR "error enable msi for guest %x status %x\n", -			otherend, status); +		pr_warn_ratelimited(DRV_NAME ": %s: error enabling MSI for guest %u: err %d\n", +				    pci_name(dev), pdev->xdev->otherend_id, +				    status);  		op->value = 0;  		return XEN_PCI_ERR_op_failed;  	} @@ -223,10 +223,10 @@ int xen_pcibk_enable_msix(struct xen_pcibk_device *pdev,  						pci_name(dev), i,  						op->msix_entries[i].vector);  		} -	} else { -		printk(KERN_WARNING DRV_NAME ": %s: failed to enable MSI-X: err %d!\n", -			pci_name(dev), result); -	} +	} else +		pr_warn_ratelimited(DRV_NAME ": %s: error enabling MSI-X for guest %u: err %d!\n", +				    pci_name(dev), pdev->xdev->otherend_id, +				    result);  	kfree(entries);  	op->value = result;  |