diff options
Diffstat (limited to 'drivers')
280 files changed, 2835 insertions, 1778 deletions
diff --git a/drivers/acpi/acpica/hwxface.c b/drivers/acpi/acpica/hwxface.c index ab513a972c9..a716fede4f2 100644 --- a/drivers/acpi/acpica/hwxface.c +++ b/drivers/acpi/acpica/hwxface.c @@ -74,7 +74,8 @@ acpi_status acpi_reset(void)  	/* Check if the reset register is supported */ -	if (!reset_reg->address) { +	if (!(acpi_gbl_FADT.flags & ACPI_FADT_RESET_REGISTER) || +	    !reset_reg->address) {  		return_ACPI_STATUS(AE_NOT_EXIST);  	} diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index ba14fb93c92..c3881b2eb8b 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -607,8 +607,7 @@ acpi_os_install_interrupt_handler(u32 gsi, acpi_osd_handler handler,  	acpi_irq_handler = handler;  	acpi_irq_context = context; -	if (request_threaded_irq(irq, NULL, acpi_irq, IRQF_SHARED, "acpi", -				 acpi_irq)) { +	if (request_irq(irq, acpi_irq, IRQF_SHARED, "acpi", acpi_irq)) {  		printk(KERN_ERR PREFIX "SCI (IRQ%d) allocation failed\n", irq);  		acpi_irq_handler = NULL;  		return AE_NOT_ACQUIRED; diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c index 7049a7d27c4..330bb4d7585 100644 --- a/drivers/acpi/power.c +++ b/drivers/acpi/power.c @@ -631,7 +631,7 @@ int acpi_power_get_inferred_state(struct acpi_device *device, int *state)  	 * We know a device's inferred power state when all the resources  	 * required for a given D-state are 'on'.  	 */ -	for (i = ACPI_STATE_D0; i < ACPI_STATE_D3; i++) { +	for (i = ACPI_STATE_D0; i < ACPI_STATE_D3_HOT; i++) {  		list = &device->power.states[i].resources;  		if (list->count < 1)  			continue; diff --git a/drivers/acpi/reboot.c b/drivers/acpi/reboot.c index c1d61243593..a6c77e8b37b 100644 --- a/drivers/acpi/reboot.c +++ b/drivers/acpi/reboot.c @@ -23,7 +23,8 @@ void acpi_reboot(void)  	/* Is the reset register supported? The spec says we should be  	 * checking the bit width and bit offset, but Windows ignores  	 * these fields */ -	/* Ignore also acpi_gbl_FADT.flags.ACPI_FADT_RESET_REGISTER */ +	if (!(acpi_gbl_FADT.flags & ACPI_FADT_RESET_REGISTER)) +		return;  	reset_value = acpi_gbl_FADT.reset_value; diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 767e2dcb961..7417267e88f 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -869,7 +869,7 @@ static int acpi_bus_get_power_flags(struct acpi_device *device)  	/*  	 * Enumerate supported power management states  	 */ -	for (i = ACPI_STATE_D0; i <= ACPI_STATE_D3; i++) { +	for (i = ACPI_STATE_D0; i <= ACPI_STATE_D3_HOT; i++) {  		struct acpi_device_power_state *ps = &device->power.states[i];  		char object_name[5] = { '_', 'P', 'R', '0' + i, '\0' }; @@ -884,21 +884,18 @@ static int acpi_bus_get_power_flags(struct acpi_device *device)  				acpi_bus_add_power_resource(ps->resources.handles[j]);  		} -		/* The exist of _PR3 indicates D3Cold support */ -		if (i == ACPI_STATE_D3) { -			status = acpi_get_handle(device->handle, object_name, &handle); -			if (ACPI_SUCCESS(status)) -				device->power.states[ACPI_STATE_D3_COLD].flags.valid = 1; -		} -  		/* Evaluate "_PSx" to see if we can do explicit sets */  		object_name[2] = 'S';  		status = acpi_get_handle(device->handle, object_name, &handle);  		if (ACPI_SUCCESS(status))  			ps->flags.explicit_set = 1; -		/* State is valid if we have some power control */ -		if (ps->resources.count || ps->flags.explicit_set) +		/* +		 * State is valid if there are means to put the device into it. +		 * D3hot is only valid if _PR3 present. +		 */ +		if (ps->resources.count || +		    (ps->flags.explicit_set && i < ACPI_STATE_D3_HOT))  			ps->flags.valid = 1;  		ps->power = -1;	/* Unknown - driver assigned */ diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index 1d661b5c328..eb6fd233764 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c @@ -28,23 +28,33 @@  #include "internal.h"  #include "sleep.h" +u8 wake_sleep_flags = ACPI_NO_OPTIONAL_METHODS;  static unsigned int gts, bfs; -module_param(gts, uint, 0644); -module_param(bfs, uint, 0644); -MODULE_PARM_DESC(gts, "Enable evaluation of _GTS on suspend."); -MODULE_PARM_DESC(bfs, "Enable evaluation of _BFS on resume".); - -static u8 wake_sleep_flags(void) +static int set_param_wake_flag(const char *val, struct kernel_param *kp)  { -	u8 flags = ACPI_NO_OPTIONAL_METHODS; +	int ret = param_set_int(val, kp); -	if (gts) -		flags |= ACPI_EXECUTE_GTS; -	if (bfs) -		flags |= ACPI_EXECUTE_BFS; +	if (ret) +		return ret; -	return flags; +	if (kp->arg == (const char *)>s) { +		if (gts) +			wake_sleep_flags |= ACPI_EXECUTE_GTS; +		else +			wake_sleep_flags &= ~ACPI_EXECUTE_GTS; +	} +	if (kp->arg == (const char *)&bfs) { +		if (bfs) +			wake_sleep_flags |= ACPI_EXECUTE_BFS; +		else +			wake_sleep_flags &= ~ACPI_EXECUTE_BFS; +	} +	return ret;  } +module_param_call(gts, set_param_wake_flag, param_get_int, >s, 0644); +module_param_call(bfs, set_param_wake_flag, param_get_int, &bfs, 0644); +MODULE_PARM_DESC(gts, "Enable evaluation of _GTS on suspend."); +MODULE_PARM_DESC(bfs, "Enable evaluation of _BFS on resume".);  static u8 sleep_states[ACPI_S_STATE_COUNT]; @@ -263,7 +273,6 @@ static int acpi_suspend_enter(suspend_state_t pm_state)  {  	acpi_status status = AE_OK;  	u32 acpi_state = acpi_target_sleep_state; -	u8 flags = wake_sleep_flags();  	int error;  	ACPI_FLUSH_CPU_CACHE(); @@ -271,7 +280,7 @@ static int acpi_suspend_enter(suspend_state_t pm_state)  	switch (acpi_state) {  	case ACPI_STATE_S1:  		barrier(); -		status = acpi_enter_sleep_state(acpi_state, flags); +		status = acpi_enter_sleep_state(acpi_state, wake_sleep_flags);  		break;  	case ACPI_STATE_S3: @@ -286,7 +295,7 @@ static int acpi_suspend_enter(suspend_state_t pm_state)  	acpi_write_bit_register(ACPI_BITREG_SCI_ENABLE, 1);  	/* Reprogram control registers and execute _BFS */ -	acpi_leave_sleep_state_prep(acpi_state, flags); +	acpi_leave_sleep_state_prep(acpi_state, wake_sleep_flags);  	/* ACPI 3.0 specs (P62) says that it's the responsibility  	 * of the OSPM to clear the status bit [ implying that the @@ -550,30 +559,27 @@ static int acpi_hibernation_begin(void)  static int acpi_hibernation_enter(void)  { -	u8 flags = wake_sleep_flags();  	acpi_status status = AE_OK;  	ACPI_FLUSH_CPU_CACHE();  	/* This shouldn't return.  If it returns, we have a problem */ -	status = acpi_enter_sleep_state(ACPI_STATE_S4, flags); +	status = acpi_enter_sleep_state(ACPI_STATE_S4, wake_sleep_flags);  	/* Reprogram control registers and execute _BFS */ -	acpi_leave_sleep_state_prep(ACPI_STATE_S4, flags); +	acpi_leave_sleep_state_prep(ACPI_STATE_S4, wake_sleep_flags);  	return ACPI_SUCCESS(status) ? 0 : -EFAULT;  }  static void acpi_hibernation_leave(void)  { -	u8 flags = wake_sleep_flags(); -  	/*  	 * If ACPI is not enabled by the BIOS and the boot kernel, we need to  	 * enable it here.  	 */  	acpi_enable();  	/* Reprogram control registers and execute _BFS */ -	acpi_leave_sleep_state_prep(ACPI_STATE_S4, flags); +	acpi_leave_sleep_state_prep(ACPI_STATE_S4, wake_sleep_flags);  	/* Check the hardware signature */  	if (facs && s4_hardware_signature != facs->hardware_signature) {  		printk(KERN_EMERG "ACPI: Hardware changed while hibernated, " @@ -828,12 +834,10 @@ static void acpi_power_off_prepare(void)  static void acpi_power_off(void)  { -	u8 flags = wake_sleep_flags(); -  	/* acpi_sleep_prepare(ACPI_STATE_S5) should have already been called */  	printk(KERN_DEBUG "%s called\n", __func__);  	local_irq_disable(); -	acpi_enter_sleep_state(ACPI_STATE_S5, flags); +	acpi_enter_sleep_state(ACPI_STATE_S5, wake_sleep_flags);  }  /* diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 79a1e9dd56d..ebaf67e4b2b 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -394,6 +394,8 @@ static const struct pci_device_id ahci_pci_tbl[] = {  	  .driver_data = board_ahci_yes_fbs },			/* 88se9128 */  	{ PCI_DEVICE(0x1b4b, 0x9125),  	  .driver_data = board_ahci_yes_fbs },			/* 88se9125 */ +	{ PCI_DEVICE(0x1b4b, 0x917a), +	  .driver_data = board_ahci_yes_fbs },			/* 88se9172 */  	{ PCI_DEVICE(0x1b4b, 0x91a3),  	  .driver_data = board_ahci_yes_fbs }, diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c index 0c86c77764b..9e419e1c200 100644 --- a/drivers/ata/ahci_platform.c +++ b/drivers/ata/ahci_platform.c @@ -280,6 +280,7 @@ static struct dev_pm_ops ahci_pm_ops = {  static const struct of_device_id ahci_of_match[] = {  	{ .compatible = "calxeda,hb-ahci", }, +	{ .compatible = "snps,spear-ahci", },  	{},  };  MODULE_DEVICE_TABLE(of, ahci_of_match); diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index 68013f96729..7857e8fd0a3 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c @@ -329,6 +329,8 @@ static const struct pci_device_id piix_pci_tbl[] = {  	{ 0x8086, 0x8c08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },  	/* SATA Controller IDE (Lynx Point) */  	{ 0x8086, 0x8c09, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, +	/* SATA Controller IDE (DH89xxCC) */ +	{ 0x8086, 0x2326, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },  	{ }	/* terminate list */  }; diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index e0bda9ff89c..23763a1ec57 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -95,7 +95,7 @@ static unsigned int ata_dev_set_xfermode(struct ata_device *dev);  static void ata_dev_xfermask(struct ata_device *dev);  static unsigned long ata_dev_blacklisted(const struct ata_device *dev); -unsigned int ata_print_id = 1; +atomic_t ata_print_id = ATOMIC_INIT(0);  struct ata_force_param {  	const char	*name; @@ -6029,7 +6029,7 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht)  	/* give ports names and add SCSI hosts */  	for (i = 0; i < host->n_ports; i++) -		host->ports[i]->print_id = ata_print_id++; +		host->ports[i]->print_id = atomic_inc_return(&ata_print_id);  	/* Create associated sysfs transport objects  */ diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index c61316e9d2f..d1fbd59ead1 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -3501,7 +3501,8 @@ static int ata_count_probe_trials_cb(struct ata_ering_entry *ent, void *void_arg  	u64 now = get_jiffies_64();  	int *trials = void_arg; -	if (ent->timestamp < now - min(now, interval)) +	if ((ent->eflags & ATA_EFLAG_OLD_ER) || +	    (ent->timestamp < now - min(now, interval)))  		return -1;  	(*trials)++; diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 1ee00c8b5b0..22226350cd0 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -3399,7 +3399,8 @@ int ata_scsi_add_hosts(struct ata_host *host, struct scsi_host_template *sht)  		 */  		shost->max_host_blocked = 1; -		rc = scsi_add_host(ap->scsi_host, &ap->tdev); +		rc = scsi_add_host_with_dma(ap->scsi_host, +						&ap->tdev, ap->host->dev);  		if (rc)  			goto err_add;  	} @@ -3838,18 +3839,25 @@ void ata_sas_port_stop(struct ata_port *ap)  }  EXPORT_SYMBOL_GPL(ata_sas_port_stop); -int ata_sas_async_port_init(struct ata_port *ap) +/** + * ata_sas_async_probe - simply schedule probing and return + * @ap: Port to probe + * + * For batch scheduling of probe for sas attached ata devices, assumes + * the port has already been through ata_sas_port_init() + */ +void ata_sas_async_probe(struct ata_port *ap)  { -	int rc = ap->ops->port_start(ap); - -	if (!rc) { -		ap->print_id = ata_print_id++; -		__ata_port_probe(ap); -	} +	__ata_port_probe(ap); +} +EXPORT_SYMBOL_GPL(ata_sas_async_probe); -	return rc; +int ata_sas_sync_probe(struct ata_port *ap) +{ +	return ata_port_probe(ap);  } -EXPORT_SYMBOL_GPL(ata_sas_async_port_init); +EXPORT_SYMBOL_GPL(ata_sas_sync_probe); +  /**   *	ata_sas_port_init - Initialize a SATA device @@ -3866,12 +3874,10 @@ int ata_sas_port_init(struct ata_port *ap)  {  	int rc = ap->ops->port_start(ap); -	if (!rc) { -		ap->print_id = ata_print_id++; -		rc = ata_port_probe(ap); -	} - -	return rc; +	if (rc) +		return rc; +	ap->print_id = atomic_inc_return(&ata_print_id); +	return 0;  }  EXPORT_SYMBOL_GPL(ata_sas_port_init); diff --git a/drivers/ata/libata-transport.c b/drivers/ata/libata-transport.c index 74aaee30e26..c3419048537 100644 --- a/drivers/ata/libata-transport.c +++ b/drivers/ata/libata-transport.c @@ -294,6 +294,7 @@ int ata_tport_add(struct device *parent,  	device_enable_async_suspend(dev);  	pm_runtime_set_active(dev);  	pm_runtime_enable(dev); +	pm_runtime_forbid(dev);  	transport_add_device(dev);  	transport_configure_device(dev); diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h index 2e26fcaf635..9d0fd0b7185 100644 --- a/drivers/ata/libata.h +++ b/drivers/ata/libata.h @@ -53,7 +53,7 @@ enum {  	ATA_DNXFER_QUIET	= (1 << 31),  }; -extern unsigned int ata_print_id; +extern atomic_t ata_print_id;  extern int atapi_passthru16;  extern int libata_fua;  extern int libata_noacpi; diff --git a/drivers/ata/pata_arasan_cf.c b/drivers/ata/pata_arasan_cf.c index fc2db2a89a6..3239517f4d9 100644 --- a/drivers/ata/pata_arasan_cf.c +++ b/drivers/ata/pata_arasan_cf.c @@ -943,9 +943,9 @@ static int arasan_cf_resume(struct device *dev)  	return 0;  } +#endif  static SIMPLE_DEV_PM_OPS(arasan_cf_pm_ops, arasan_cf_suspend, arasan_cf_resume); -#endif  static struct platform_driver arasan_cf_driver = {  	.probe		= arasan_cf_probe, @@ -953,9 +953,7 @@ static struct platform_driver arasan_cf_driver = {  	.driver		= {  		.name	= DRIVER_NAME,  		.owner	= THIS_MODULE, -#ifdef CONFIG_PM  		.pm	= &arasan_cf_pm_ops, -#endif  	},  }; diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index 38950ea8398..7336d4a7ab3 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -4025,7 +4025,8 @@ static int mv_platform_probe(struct platform_device *pdev)  	struct ata_host *host;  	struct mv_host_priv *hpriv;  	struct resource *res; -	int n_ports, rc; +	int n_ports = 0; +	int rc;  	ata_print_version_once(&pdev->dev, DRV_VERSION); diff --git a/drivers/bcma/sprom.c b/drivers/bcma/sprom.c index cdcf75c0954..3e2a6002aae 100644 --- a/drivers/bcma/sprom.c +++ b/drivers/bcma/sprom.c @@ -404,16 +404,19 @@ int bcma_sprom_get(struct bcma_bus *bus)  		return -EOPNOTSUPP;  	if (!bcma_sprom_ext_available(bus)) { +		bool sprom_onchip; +  		/*  		 * External SPROM takes precedence so check  		 * on-chip OTP only when no external SPROM  		 * is present.  		 */ -		if (bcma_sprom_onchip_available(bus)) { +		sprom_onchip = bcma_sprom_onchip_available(bus); +		if (sprom_onchip) {  			/* determine offset */  			offset = bcma_sprom_onchip_offset(bus);  		} -		if (!offset) { +		if (!offset || !sprom_onchip) {  			/*  			 * Maybe there is no SPROM on the device?  			 * Now we ask the arch code if there is some sprom diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index 0e4ef3de9d5..0d39f2f4294 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c @@ -375,6 +375,34 @@ static int init_vq(struct virtio_blk *vblk)  	return err;  } +/* + * Legacy naming scheme used for virtio devices.  We are stuck with it for + * virtio blk but don't ever use it for any new driver. + */ +static int virtblk_name_format(char *prefix, int index, char *buf, int buflen) +{ +	const int base = 'z' - 'a' + 1; +	char *begin = buf + strlen(prefix); +	char *end = buf + buflen; +	char *p; +	int unit; + +	p = end - 1; +	*p = '\0'; +	unit = base; +	do { +		if (p == begin) +			return -EINVAL; +		*--p = 'a' + (index % unit); +		index = (index / unit) - 1; +	} while (index >= 0); + +	memmove(begin, p, end - p); +	memcpy(buf, prefix, strlen(prefix)); + +	return 0; +} +  static int __devinit virtblk_probe(struct virtio_device *vdev)  {  	struct virtio_blk *vblk; @@ -443,18 +471,7 @@ static int __devinit virtblk_probe(struct virtio_device *vdev)  	q->queuedata = vblk; -	if (index < 26) { -		sprintf(vblk->disk->disk_name, "vd%c", 'a' + index % 26); -	} else if (index < (26 + 1) * 26) { -		sprintf(vblk->disk->disk_name, "vd%c%c", -			'a' + index / 26 - 1, 'a' + index % 26); -	} else { -		const unsigned int m1 = (index / 26 - 1) / 26 - 1; -		const unsigned int m2 = (index / 26 - 1) % 26; -		const unsigned int m3 =  index % 26; -		sprintf(vblk->disk->disk_name, "vd%c%c%c", -			'a' + m1, 'a' + m2, 'a' + m3); -	} +	virtblk_name_format("vd", index, vblk->disk->disk_name, DISK_NAME_LEN);  	vblk->disk->major = major;  	vblk->disk->first_minor = index_to_minor(index); diff --git a/drivers/block/xen-blkback/xenbus.c b/drivers/block/xen-blkback/xenbus.c index 89860f34a7e..4f66171c668 100644 --- a/drivers/block/xen-blkback/xenbus.c +++ b/drivers/block/xen-blkback/xenbus.c @@ -416,7 +416,7 @@ static void xen_blkbk_discard(struct xenbus_transaction xbt, struct backend_info  				    "discard-secure", "%d",  				    blkif->vbd.discard_secure);  		if (err) { -			dev_warn(dev-dev, "writing discard-secure (%d)", err); +			dev_warn(&dev->dev, "writing discard-secure (%d)", err);  			return;  		}  	} diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c index ae9edca7b56..57fd867553d 100644 --- a/drivers/bluetooth/ath3k.c +++ b/drivers/bluetooth/ath3k.c @@ -75,6 +75,8 @@ static struct usb_device_id ath3k_table[] = {  	{ USB_DEVICE(0x0CF3, 0x311D) },  	{ USB_DEVICE(0x13d3, 0x3375) },  	{ USB_DEVICE(0x04CA, 0x3005) }, +	{ USB_DEVICE(0x13d3, 0x3362) }, +	{ USB_DEVICE(0x0CF3, 0xE004) },  	/* Atheros AR5BBU12 with sflash firmware */  	{ USB_DEVICE(0x0489, 0xE02C) }, @@ -94,6 +96,8 @@ 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(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 }, +	{ USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 },  	{ }	/* Terminating entry */  }; diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 3311b812a0c..9217121362e 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -101,12 +101,16 @@ static struct usb_device_id btusb_table[] = {  	{ USB_DEVICE(0x0c10, 0x0000) },  	/* Broadcom BCM20702A0 */ +	{ USB_DEVICE(0x0489, 0xe042) },  	{ USB_DEVICE(0x0a5c, 0x21e3) },  	{ USB_DEVICE(0x0a5c, 0x21e6) },  	{ USB_DEVICE(0x0a5c, 0x21e8) },  	{ USB_DEVICE(0x0a5c, 0x21f3) },  	{ USB_DEVICE(0x413c, 0x8197) }, +	/* Foxconn - Hon Hai */ +	{ USB_DEVICE(0x0489, 0xe033) }, +  	{ }	/* Terminating entry */  }; @@ -133,6 +137,8 @@ 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(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 }, +	{ USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 },  	/* Atheros AR5BBU12 with sflash firmware */  	{ USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE }, diff --git a/drivers/crypto/ixp4xx_crypto.c b/drivers/crypto/ixp4xx_crypto.c index 0053d7ebb5c..8f3f74ce8c7 100644 --- a/drivers/crypto/ixp4xx_crypto.c +++ b/drivers/crypto/ixp4xx_crypto.c @@ -18,6 +18,7 @@  #include <linux/interrupt.h>  #include <linux/spinlock.h>  #include <linux/gfp.h> +#include <linux/module.h>  #include <crypto/ctr.h>  #include <crypto/des.h> diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c index dc641c79652..921039e56f8 100644 --- a/drivers/crypto/talitos.c +++ b/drivers/crypto/talitos.c @@ -124,6 +124,9 @@ struct talitos_private {  	void __iomem *reg;  	int irq[2]; +	/* SEC global registers lock  */ +	spinlock_t reg_lock ____cacheline_aligned; +  	/* SEC version geometry (from device tree node) */  	unsigned int num_channels;  	unsigned int chfifo_len; @@ -412,6 +415,7 @@ static void talitos_done_##name(unsigned long data)			\  {									\  	struct device *dev = (struct device *)data;			\  	struct talitos_private *priv = dev_get_drvdata(dev);		\ +	unsigned long flags;						\  									\  	if (ch_done_mask & 1)						\  		flush_channel(dev, 0, 0, 0);				\ @@ -427,8 +431,10 @@ static void talitos_done_##name(unsigned long data)			\  out:									\  	/* At this point, all completed channels have been processed */	\  	/* Unmask done interrupts for channels completed later on. */	\ +	spin_lock_irqsave(&priv->reg_lock, flags);			\  	setbits32(priv->reg + TALITOS_IMR, ch_done_mask);		\  	setbits32(priv->reg + TALITOS_IMR_LO, TALITOS_IMR_LO_INIT);	\ +	spin_unlock_irqrestore(&priv->reg_lock, flags);			\  }  DEF_TALITOS_DONE(4ch, TALITOS_ISR_4CHDONE)  DEF_TALITOS_DONE(ch0_2, TALITOS_ISR_CH_0_2_DONE) @@ -619,22 +625,28 @@ static irqreturn_t talitos_interrupt_##name(int irq, void *data)	       \  	struct device *dev = data;					       \  	struct talitos_private *priv = dev_get_drvdata(dev);		       \  	u32 isr, isr_lo;						       \ +	unsigned long flags;						       \  									       \ +	spin_lock_irqsave(&priv->reg_lock, flags);			       \  	isr = in_be32(priv->reg + TALITOS_ISR);				       \  	isr_lo = in_be32(priv->reg + TALITOS_ISR_LO);			       \  	/* Acknowledge interrupt */					       \  	out_be32(priv->reg + TALITOS_ICR, isr & (ch_done_mask | ch_err_mask)); \  	out_be32(priv->reg + TALITOS_ICR_LO, isr_lo);			       \  									       \ -	if (unlikely((isr & ~TALITOS_ISR_4CHDONE) & ch_err_mask || isr_lo))    \ -		talitos_error(dev, isr, isr_lo);			       \ -	else								       \ +	if (unlikely(isr & ch_err_mask || isr_lo)) {			       \ +		spin_unlock_irqrestore(&priv->reg_lock, flags);		       \ +		talitos_error(dev, isr & ch_err_mask, isr_lo);		       \ +	}								       \ +	else {								       \  		if (likely(isr & ch_done_mask)) {			       \  			/* mask further done interrupts. */		       \  			clrbits32(priv->reg + TALITOS_IMR, ch_done_mask);      \  			/* done_task will unmask done interrupts at exit */    \  			tasklet_schedule(&priv->done_task[tlet]);	       \  		}							       \ +		spin_unlock_irqrestore(&priv->reg_lock, flags);		       \ +	}								       \  									       \  	return (isr & (ch_done_mask | ch_err_mask) || isr_lo) ? IRQ_HANDLED :  \  								IRQ_NONE;      \ @@ -2719,6 +2731,8 @@ static int talitos_probe(struct platform_device *ofdev)  	priv->ofdev = ofdev; +	spin_lock_init(&priv->reg_lock); +  	err = talitos_probe_irq(ofdev);  	if (err)  		goto err_out; diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index cf9da362d64..ef378b5b17e 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -91,11 +91,10 @@ config DW_DMAC  config AT_HDMAC  	tristate "Atmel AHB DMA support" -	depends on ARCH_AT91SAM9RL || ARCH_AT91SAM9G45 +	depends on ARCH_AT91  	select DMA_ENGINE  	help -	  Support the Atmel AHB DMA controller.  This can be integrated in -	  chips such as the Atmel AT91SAM9RL. +	  Support the Atmel AHB DMA controller.  config FSL_DMA  	tristate "Freescale Elo and Elo Plus DMA support" diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c index c301a8ec31a..3d704abd791 100644 --- a/drivers/dma/amba-pl08x.c +++ b/drivers/dma/amba-pl08x.c @@ -1429,6 +1429,7 @@ static int pl08x_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,  			 * signal  			 */  			release_phy_channel(plchan); +			plchan->phychan_hold = 0;  		}  		/* Dequeue jobs and free LLIs */  		if (plchan->at) { diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c index 7aa58d20489..445fdf81169 100644 --- a/drivers/dma/at_hdmac.c +++ b/drivers/dma/at_hdmac.c @@ -221,10 +221,6 @@ static void atc_dostart(struct at_dma_chan *atchan, struct at_desc *first)  	vdbg_dump_regs(atchan); -	/* clear any pending interrupt */ -	while (dma_readl(atdma, EBCISR)) -		cpu_relax(); -  	channel_writel(atchan, SADDR, 0);  	channel_writel(atchan, DADDR, 0);  	channel_writel(atchan, CTRLA, 0); diff --git a/drivers/dma/imx-dma.c b/drivers/dma/imx-dma.c index a45b5d2a598..bb787d8e152 100644 --- a/drivers/dma/imx-dma.c +++ b/drivers/dma/imx-dma.c @@ -571,11 +571,14 @@ static void imxdma_tasklet(unsigned long data)  	if (desc->desc.callback)  		desc->desc.callback(desc->desc.callback_param); -	dma_cookie_complete(&desc->desc); - -	/* If we are dealing with a cyclic descriptor keep it on ld_active */ +	/* If we are dealing with a cyclic descriptor keep it on ld_active +	 * and dont mark the descripor as complete. +	 * Only in non-cyclic cases it would be marked as complete +	 */  	if (imxdma_chan_is_doing_cyclic(imxdmac))  		goto out; +	else +		dma_cookie_complete(&desc->desc);  	/* Free 2D slot if it was an interleaved transfer */  	if (imxdmac->enabled_2d) { diff --git a/drivers/dma/mxs-dma.c b/drivers/dma/mxs-dma.c index c81ef7e10e0..655d4ce6ed0 100644 --- a/drivers/dma/mxs-dma.c +++ b/drivers/dma/mxs-dma.c @@ -201,10 +201,6 @@ static struct mxs_dma_chan *to_mxs_dma_chan(struct dma_chan *chan)  static dma_cookie_t mxs_dma_tx_submit(struct dma_async_tx_descriptor *tx)  { -	struct mxs_dma_chan *mxs_chan = to_mxs_dma_chan(tx->chan); - -	mxs_dma_enable_chan(mxs_chan); -  	return dma_cookie_assign(tx);  } @@ -558,9 +554,9 @@ static enum dma_status mxs_dma_tx_status(struct dma_chan *chan,  static void mxs_dma_issue_pending(struct dma_chan *chan)  { -	/* -	 * Nothing to do. We only have a single descriptor. -	 */ +	struct mxs_dma_chan *mxs_chan = to_mxs_dma_chan(chan); + +	mxs_dma_enable_chan(mxs_chan);  }  static int __init mxs_dma_init(struct mxs_dma_engine *mxs_dma) diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index 282caf118be..2ee6e23930a 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -2225,12 +2225,9 @@ static inline void free_desc_list(struct list_head *list)  {  	struct dma_pl330_dmac *pdmac;  	struct dma_pl330_desc *desc; -	struct dma_pl330_chan *pch; +	struct dma_pl330_chan *pch = NULL;  	unsigned long flags; -	if (list_empty(list)) -		return; -  	/* Finish off the work list */  	list_for_each_entry(desc, list, node) {  		dma_async_tx_callback callback; @@ -2247,6 +2244,10 @@ static inline void free_desc_list(struct list_head *list)  		desc->pchan = NULL;  	} +	/* pch will be unset if list was empty */ +	if (!pch) +		return; +  	pdmac = pch->dmac;  	spin_lock_irqsave(&pdmac->pool_lock, flags); @@ -2257,12 +2258,9 @@ static inline void free_desc_list(struct list_head *list)  static inline void handle_cyclic_desc_list(struct list_head *list)  {  	struct dma_pl330_desc *desc; -	struct dma_pl330_chan *pch; +	struct dma_pl330_chan *pch = NULL;  	unsigned long flags; -	if (list_empty(list)) -		return; -  	list_for_each_entry(desc, list, node) {  		dma_async_tx_callback callback; @@ -2274,6 +2272,10 @@ static inline void handle_cyclic_desc_list(struct list_head *list)  			callback(desc->txd.callback_param);  	} +	/* pch will be unset if list was empty */ +	if (!pch) +		return; +  	spin_lock_irqsave(&pch->lock, flags);  	list_splice_tail_init(list, &pch->work_list);  	spin_unlock_irqrestore(&pch->lock, flags); @@ -2926,8 +2928,11 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)  	INIT_LIST_HEAD(&pd->channels);  	/* Initialize channel parameters */ -	num_chan = max(pdat ? pdat->nr_valid_peri : (u8)pi->pcfg.num_peri, -			(u8)pi->pcfg.num_chan); +	if (pdat) +		num_chan = max_t(int, pdat->nr_valid_peri, pi->pcfg.num_chan); +	else +		num_chan = max_t(int, pi->pcfg.num_peri, pi->pcfg.num_chan); +  	pdmac->peripherals = kzalloc(num_chan * sizeof(*pch), GFP_KERNEL);  	for (i = 0; i < num_chan; i++) { diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index bdd41d4bfa8..2ed1ac3513f 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c @@ -18,6 +18,7 @@  #include <linux/pm_runtime.h>  #include <linux/err.h>  #include <linux/amba/bus.h> +#include <linux/regulator/consumer.h>  #include <plat/ste_dma40.h> @@ -69,6 +70,22 @@ enum d40_command {  };  /* + * enum d40_events - The different Event Enables for the event lines. + * + * @D40_DEACTIVATE_EVENTLINE: De-activate Event line, stopping the logical chan. + * @D40_ACTIVATE_EVENTLINE: Activate the Event line, to start a logical chan. + * @D40_SUSPEND_REQ_EVENTLINE: Requesting for suspending a event line. + * @D40_ROUND_EVENTLINE: Status check for event line. + */ + +enum d40_events { +	D40_DEACTIVATE_EVENTLINE	= 0, +	D40_ACTIVATE_EVENTLINE		= 1, +	D40_SUSPEND_REQ_EVENTLINE	= 2, +	D40_ROUND_EVENTLINE		= 3 +}; + +/*   * These are the registers that has to be saved and later restored   * when the DMA hw is powered off.   * TODO: Add save/restore of D40_DREG_GCC on dma40 v3 or later, if that works. @@ -870,8 +887,8 @@ static void d40_save_restore_registers(struct d40_base *base, bool save)  }  #endif -static int d40_channel_execute_command(struct d40_chan *d40c, -				       enum d40_command command) +static int __d40_execute_command_phy(struct d40_chan *d40c, +				     enum d40_command command)  {  	u32 status;  	int i; @@ -880,6 +897,12 @@ static int d40_channel_execute_command(struct d40_chan *d40c,  	unsigned long flags;  	u32 wmask; +	if (command == D40_DMA_STOP) { +		ret = __d40_execute_command_phy(d40c, D40_DMA_SUSPEND_REQ); +		if (ret) +			return ret; +	} +  	spin_lock_irqsave(&d40c->base->execmd_lock, flags);  	if (d40c->phy_chan->num % 2 == 0) @@ -973,67 +996,109 @@ static void d40_term_all(struct d40_chan *d40c)  		}  	d40c->pending_tx = 0; -	d40c->busy = false;  } -static void __d40_config_set_event(struct d40_chan *d40c, bool enable, -				   u32 event, int reg) +static void __d40_config_set_event(struct d40_chan *d40c, +				   enum d40_events event_type, u32 event, +				   int reg)  {  	void __iomem *addr = chan_base(d40c) + reg;  	int tries; +	u32 status; + +	switch (event_type) { + +	case D40_DEACTIVATE_EVENTLINE: -	if (!enable) {  		writel((D40_DEACTIVATE_EVENTLINE << D40_EVENTLINE_POS(event))  		       | ~D40_EVENTLINE_MASK(event), addr); -		return; -	} +		break; + +	case D40_SUSPEND_REQ_EVENTLINE: +		status = (readl(addr) & D40_EVENTLINE_MASK(event)) >> +			  D40_EVENTLINE_POS(event); + +		if (status == D40_DEACTIVATE_EVENTLINE || +		    status == D40_SUSPEND_REQ_EVENTLINE) +			break; +		writel((D40_SUSPEND_REQ_EVENTLINE << D40_EVENTLINE_POS(event)) +		       | ~D40_EVENTLINE_MASK(event), addr); + +		for (tries = 0 ; tries < D40_SUSPEND_MAX_IT; tries++) { + +			status = (readl(addr) & D40_EVENTLINE_MASK(event)) >> +				  D40_EVENTLINE_POS(event); + +			cpu_relax(); +			/* +			 * Reduce the number of bus accesses while +			 * waiting for the DMA to suspend. +			 */ +			udelay(3); + +			if (status == D40_DEACTIVATE_EVENTLINE) +				break; +		} + +		if (tries == D40_SUSPEND_MAX_IT) { +			chan_err(d40c, +				"unable to stop the event_line chl %d (log: %d)" +				"status %x\n", d40c->phy_chan->num, +				 d40c->log_num, status); +		} +		break; + +	case D40_ACTIVATE_EVENTLINE:  	/*  	 * The hardware sometimes doesn't register the enable when src and dst  	 * event lines are active on the same logical channel.  Retry to ensure  	 * it does.  Usually only one retry is sufficient.  	 */ -	tries = 100; -	while (--tries) { -		writel((D40_ACTIVATE_EVENTLINE << D40_EVENTLINE_POS(event)) -		       | ~D40_EVENTLINE_MASK(event), addr); +		tries = 100; +		while (--tries) { +			writel((D40_ACTIVATE_EVENTLINE << +				D40_EVENTLINE_POS(event)) | +				~D40_EVENTLINE_MASK(event), addr); -		if (readl(addr) & D40_EVENTLINE_MASK(event)) -			break; -	} +			if (readl(addr) & D40_EVENTLINE_MASK(event)) +				break; +		} -	if (tries != 99) -		dev_dbg(chan2dev(d40c), -			"[%s] workaround enable S%cLNK (%d tries)\n", -			__func__, reg == D40_CHAN_REG_SSLNK ? 'S' : 'D', -			100 - tries); +		if (tries != 99) +			dev_dbg(chan2dev(d40c), +				"[%s] workaround enable S%cLNK (%d tries)\n", +				__func__, reg == D40_CHAN_REG_SSLNK ? 'S' : 'D', +				100 - tries); -	WARN_ON(!tries); -} +		WARN_ON(!tries); +		break; -static void d40_config_set_event(struct d40_chan *d40c, bool do_enable) -{ -	unsigned long flags; +	case D40_ROUND_EVENTLINE: +		BUG(); +		break; -	spin_lock_irqsave(&d40c->phy_chan->lock, flags); +	} +} +static void d40_config_set_event(struct d40_chan *d40c, +				 enum d40_events event_type) +{  	/* Enable event line connected to device (or memcpy) */  	if ((d40c->dma_cfg.dir ==  STEDMA40_PERIPH_TO_MEM) ||  	    (d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_PERIPH)) {  		u32 event = D40_TYPE_TO_EVENT(d40c->dma_cfg.src_dev_type); -		__d40_config_set_event(d40c, do_enable, event, +		__d40_config_set_event(d40c, event_type, event,  				       D40_CHAN_REG_SSLNK);  	}  	if (d40c->dma_cfg.dir !=  STEDMA40_PERIPH_TO_MEM) {  		u32 event = D40_TYPE_TO_EVENT(d40c->dma_cfg.dst_dev_type); -		__d40_config_set_event(d40c, do_enable, event, +		__d40_config_set_event(d40c, event_type, event,  				       D40_CHAN_REG_SDLNK);  	} - -	spin_unlock_irqrestore(&d40c->phy_chan->lock, flags);  }  static u32 d40_chan_has_events(struct d40_chan *d40c) @@ -1047,6 +1112,64 @@ static u32 d40_chan_has_events(struct d40_chan *d40c)  	return val;  } +static int +__d40_execute_command_log(struct d40_chan *d40c, enum d40_command command) +{ +	unsigned long flags; +	int ret = 0; +	u32 active_status; +	void __iomem *active_reg; + +	if (d40c->phy_chan->num % 2 == 0) +		active_reg = d40c->base->virtbase + D40_DREG_ACTIVE; +	else +		active_reg = d40c->base->virtbase + D40_DREG_ACTIVO; + + +	spin_lock_irqsave(&d40c->phy_chan->lock, flags); + +	switch (command) { +	case D40_DMA_STOP: +	case D40_DMA_SUSPEND_REQ: + +		active_status = (readl(active_reg) & +				 D40_CHAN_POS_MASK(d40c->phy_chan->num)) >> +				 D40_CHAN_POS(d40c->phy_chan->num); + +		if (active_status == D40_DMA_RUN) +			d40_config_set_event(d40c, D40_SUSPEND_REQ_EVENTLINE); +		else +			d40_config_set_event(d40c, D40_DEACTIVATE_EVENTLINE); + +		if (!d40_chan_has_events(d40c) && (command == D40_DMA_STOP)) +			ret = __d40_execute_command_phy(d40c, command); + +		break; + +	case D40_DMA_RUN: + +		d40_config_set_event(d40c, D40_ACTIVATE_EVENTLINE); +		ret = __d40_execute_command_phy(d40c, command); +		break; + +	case D40_DMA_SUSPENDED: +		BUG(); +		break; +	} + +	spin_unlock_irqrestore(&d40c->phy_chan->lock, flags); +	return ret; +} + +static int d40_channel_execute_command(struct d40_chan *d40c, +				       enum d40_command command) +{ +	if (chan_is_logical(d40c)) +		return __d40_execute_command_log(d40c, command); +	else +		return __d40_execute_command_phy(d40c, command); +} +  static u32 d40_get_prmo(struct d40_chan *d40c)  {  	static const unsigned int phy_map[] = { @@ -1149,15 +1272,7 @@ static int d40_pause(struct d40_chan *d40c)  	spin_lock_irqsave(&d40c->lock, flags);  	res = d40_channel_execute_command(d40c, D40_DMA_SUSPEND_REQ); -	if (res == 0) { -		if (chan_is_logical(d40c)) { -			d40_config_set_event(d40c, false); -			/* Resume the other logical channels if any */ -			if (d40_chan_has_events(d40c)) -				res = d40_channel_execute_command(d40c, -								  D40_DMA_RUN); -		} -	} +  	pm_runtime_mark_last_busy(d40c->base->dev);  	pm_runtime_put_autosuspend(d40c->base->dev);  	spin_unlock_irqrestore(&d40c->lock, flags); @@ -1174,45 +1289,17 @@ static int d40_resume(struct d40_chan *d40c)  	spin_lock_irqsave(&d40c->lock, flags);  	pm_runtime_get_sync(d40c->base->dev); -	if (d40c->base->rev == 0) -		if (chan_is_logical(d40c)) { -			res = d40_channel_execute_command(d40c, -							  D40_DMA_SUSPEND_REQ); -			goto no_suspend; -		}  	/* If bytes left to transfer or linked tx resume job */ -	if (d40_residue(d40c) || d40_tx_is_linked(d40c)) { - -		if (chan_is_logical(d40c)) -			d40_config_set_event(d40c, true); - +	if (d40_residue(d40c) || d40_tx_is_linked(d40c))  		res = d40_channel_execute_command(d40c, D40_DMA_RUN); -	} -no_suspend:  	pm_runtime_mark_last_busy(d40c->base->dev);  	pm_runtime_put_autosuspend(d40c->base->dev);  	spin_unlock_irqrestore(&d40c->lock, flags);  	return res;  } -static int d40_terminate_all(struct d40_chan *chan) -{ -	unsigned long flags; -	int ret = 0; - -	ret = d40_pause(chan); -	if (!ret && chan_is_physical(chan)) -		ret = d40_channel_execute_command(chan, D40_DMA_STOP); - -	spin_lock_irqsave(&chan->lock, flags); -	d40_term_all(chan); -	spin_unlock_irqrestore(&chan->lock, flags); - -	return ret; -} -  static dma_cookie_t d40_tx_submit(struct dma_async_tx_descriptor *tx)  {  	struct d40_chan *d40c = container_of(tx->chan, @@ -1232,20 +1319,6 @@ static dma_cookie_t d40_tx_submit(struct dma_async_tx_descriptor *tx)  static int d40_start(struct d40_chan *d40c)  { -	if (d40c->base->rev == 0) { -		int err; - -		if (chan_is_logical(d40c)) { -			err = d40_channel_execute_command(d40c, -							  D40_DMA_SUSPEND_REQ); -			if (err) -				return err; -		} -	} - -	if (chan_is_logical(d40c)) -		d40_config_set_event(d40c, true); -  	return d40_channel_execute_command(d40c, D40_DMA_RUN);  } @@ -1258,10 +1331,10 @@ static struct d40_desc *d40_queue_start(struct d40_chan *d40c)  	d40d = d40_first_queued(d40c);  	if (d40d != NULL) { -		if (!d40c->busy) +		if (!d40c->busy) {  			d40c->busy = true; - -		pm_runtime_get_sync(d40c->base->dev); +			pm_runtime_get_sync(d40c->base->dev); +		}  		/* Remove from queue */  		d40_desc_remove(d40d); @@ -1388,8 +1461,8 @@ static void dma_tasklet(unsigned long data)  	return; - err: -	/* Rescue manoeuvre if receiving double interrupts */ +err: +	/* Rescue manouver if receiving double interrupts */  	if (d40c->pending_tx > 0)  		d40c->pending_tx--;  	spin_unlock_irqrestore(&d40c->lock, flags); @@ -1770,7 +1843,6 @@ static int d40_config_memcpy(struct d40_chan *d40c)  	return 0;  } -  static int d40_free_dma(struct d40_chan *d40c)  { @@ -1806,43 +1878,18 @@ static int d40_free_dma(struct d40_chan *d40c)  	}  	pm_runtime_get_sync(d40c->base->dev); -	res = d40_channel_execute_command(d40c, D40_DMA_SUSPEND_REQ); +	res = d40_channel_execute_command(d40c, D40_DMA_STOP);  	if (res) { -		chan_err(d40c, "suspend failed\n"); +		chan_err(d40c, "stop failed\n");  		goto out;  	} -	if (chan_is_logical(d40c)) { -		/* Release logical channel, deactivate the event line */ +	d40_alloc_mask_free(phy, is_src, chan_is_logical(d40c) ? event : 0); -		d40_config_set_event(d40c, false); +	if (chan_is_logical(d40c))  		d40c->base->lookup_log_chans[d40c->log_num] = NULL; - -		/* -		 * Check if there are more logical allocation -		 * on this phy channel. -		 */ -		if (!d40_alloc_mask_free(phy, is_src, event)) { -			/* Resume the other logical channels if any */ -			if (d40_chan_has_events(d40c)) { -				res = d40_channel_execute_command(d40c, -								  D40_DMA_RUN); -				if (res) -					chan_err(d40c, -						"Executing RUN command\n"); -			} -			goto out; -		} -	} else { -		(void) d40_alloc_mask_free(phy, is_src, 0); -	} - -	/* Release physical channel */ -	res = d40_channel_execute_command(d40c, D40_DMA_STOP); -	if (res) { -		chan_err(d40c, "Failed to stop channel\n"); -		goto out; -	} +	else +		d40c->base->lookup_phy_chans[phy->num] = NULL;  	if (d40c->busy) {  		pm_runtime_mark_last_busy(d40c->base->dev); @@ -1852,7 +1899,6 @@ static int d40_free_dma(struct d40_chan *d40c)  	d40c->busy = false;  	d40c->phy_chan = NULL;  	d40c->configured = false; -	d40c->base->lookup_phy_chans[phy->num] = NULL;  out:  	pm_runtime_mark_last_busy(d40c->base->dev); @@ -2070,7 +2116,7 @@ d40_prep_sg(struct dma_chan *dchan, struct scatterlist *sg_src,  	if (sg_next(&sg_src[sg_len - 1]) == sg_src)  		desc->cyclic = true; -	if (direction != DMA_NONE) { +	if (direction != DMA_TRANS_NONE) {  		dma_addr_t dev_addr = d40_get_dev_addr(chan, direction);  		if (direction == DMA_DEV_TO_MEM) @@ -2371,6 +2417,31 @@ static void d40_issue_pending(struct dma_chan *chan)  	spin_unlock_irqrestore(&d40c->lock, flags);  } +static void d40_terminate_all(struct dma_chan *chan) +{ +	unsigned long flags; +	struct d40_chan *d40c = container_of(chan, struct d40_chan, chan); +	int ret; + +	spin_lock_irqsave(&d40c->lock, flags); + +	pm_runtime_get_sync(d40c->base->dev); +	ret = d40_channel_execute_command(d40c, D40_DMA_STOP); +	if (ret) +		chan_err(d40c, "Failed to stop channel\n"); + +	d40_term_all(d40c); +	pm_runtime_mark_last_busy(d40c->base->dev); +	pm_runtime_put_autosuspend(d40c->base->dev); +	if (d40c->busy) { +		pm_runtime_mark_last_busy(d40c->base->dev); +		pm_runtime_put_autosuspend(d40c->base->dev); +	} +	d40c->busy = false; + +	spin_unlock_irqrestore(&d40c->lock, flags); +} +  static int  dma40_config_to_halfchannel(struct d40_chan *d40c,  			    struct stedma40_half_channel_info *info, @@ -2551,7 +2622,8 @@ static int d40_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,  	switch (cmd) {  	case DMA_TERMINATE_ALL: -		return d40_terminate_all(d40c); +		d40_terminate_all(chan); +		return 0;  	case DMA_PAUSE:  		return d40_pause(d40c);  	case DMA_RESUME: @@ -2908,6 +2980,12 @@ static struct d40_base * __init d40_hw_detect_init(struct platform_device *pdev)  	dev_info(&pdev->dev, "hardware revision: %d @ 0x%x\n",  		 rev, res->start); +	if (rev < 2) { +		d40_err(&pdev->dev, "hardware revision: %d is not supported", +			rev); +		goto failure; +	} +  	plat_data = pdev->dev.platform_data;  	/* Count the number of logical channels in use */ @@ -2998,6 +3076,7 @@ failure:  	if (base) {  		kfree(base->lcla_pool.alloc_map); +		kfree(base->reg_val_backup_chan);  		kfree(base->lookup_log_chans);  		kfree(base->lookup_phy_chans);  		kfree(base->phy_res); diff --git a/drivers/dma/ste_dma40_ll.h b/drivers/dma/ste_dma40_ll.h index 8d3d490968a..51e8e5396e9 100644 --- a/drivers/dma/ste_dma40_ll.h +++ b/drivers/dma/ste_dma40_ll.h @@ -62,8 +62,6 @@  #define D40_SREG_ELEM_LOG_LIDX_MASK	(0xFF << D40_SREG_ELEM_LOG_LIDX_POS)  /* Link register */ -#define D40_DEACTIVATE_EVENTLINE	0x0 -#define D40_ACTIVATE_EVENTLINE		0x1  #define D40_EVENTLINE_POS(i)		(2 * i)  #define D40_EVENTLINE_MASK(i)		(0x3 << D40_EVENTLINE_POS(i)) diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c index d25599f2a3f..47408e802ab 100644 --- a/drivers/firmware/efivars.c +++ b/drivers/firmware/efivars.c @@ -191,6 +191,190 @@ utf16_strncmp(const efi_char16_t *a, const efi_char16_t *b, size_t len)  	}  } +static bool +validate_device_path(struct efi_variable *var, int match, u8 *buffer, +		     unsigned long len) +{ +	struct efi_generic_dev_path *node; +	int offset = 0; + +	node = (struct efi_generic_dev_path *)buffer; + +	if (len < sizeof(*node)) +		return false; + +	while (offset <= len - sizeof(*node) && +	       node->length >= sizeof(*node) && +		node->length <= len - offset) { +		offset += node->length; + +		if ((node->type == EFI_DEV_END_PATH || +		     node->type == EFI_DEV_END_PATH2) && +		    node->sub_type == EFI_DEV_END_ENTIRE) +			return true; + +		node = (struct efi_generic_dev_path *)(buffer + offset); +	} + +	/* +	 * If we're here then either node->length pointed past the end +	 * of the buffer or we reached the end of the buffer without +	 * finding a device path end node. +	 */ +	return false; +} + +static bool +validate_boot_order(struct efi_variable *var, int match, u8 *buffer, +		    unsigned long len) +{ +	/* An array of 16-bit integers */ +	if ((len % 2) != 0) +		return false; + +	return true; +} + +static bool +validate_load_option(struct efi_variable *var, int match, u8 *buffer, +		     unsigned long len) +{ +	u16 filepathlength; +	int i, desclength = 0, namelen; + +	namelen = utf16_strnlen(var->VariableName, sizeof(var->VariableName)); + +	/* Either "Boot" or "Driver" followed by four digits of hex */ +	for (i = match; i < match+4; i++) { +		if (var->VariableName[i] > 127 || +		    hex_to_bin(var->VariableName[i] & 0xff) < 0) +			return true; +	} + +	/* Reject it if there's 4 digits of hex and then further content */ +	if (namelen > match + 4) +		return false; + +	/* A valid entry must be at least 8 bytes */ +	if (len < 8) +		return false; + +	filepathlength = buffer[4] | buffer[5] << 8; + +	/* +	 * There's no stored length for the description, so it has to be +	 * found by hand +	 */ +	desclength = utf16_strsize((efi_char16_t *)(buffer + 6), len - 6) + 2; + +	/* Each boot entry must have a descriptor */ +	if (!desclength) +		return false; + +	/* +	 * If the sum of the length of the description, the claimed filepath +	 * length and the original header are greater than the length of the +	 * variable, it's malformed +	 */ +	if ((desclength + filepathlength + 6) > len) +		return false; + +	/* +	 * And, finally, check the filepath +	 */ +	return validate_device_path(var, match, buffer + desclength + 6, +				    filepathlength); +} + +static bool +validate_uint16(struct efi_variable *var, int match, u8 *buffer, +		unsigned long len) +{ +	/* A single 16-bit integer */ +	if (len != 2) +		return false; + +	return true; +} + +static bool +validate_ascii_string(struct efi_variable *var, int match, u8 *buffer, +		      unsigned long len) +{ +	int i; + +	for (i = 0; i < len; i++) { +		if (buffer[i] > 127) +			return false; + +		if (buffer[i] == 0) +			return true; +	} + +	return false; +} + +struct variable_validate { +	char *name; +	bool (*validate)(struct efi_variable *var, int match, u8 *data, +			 unsigned long len); +}; + +static const struct variable_validate variable_validate[] = { +	{ "BootNext", validate_uint16 }, +	{ "BootOrder", validate_boot_order }, +	{ "DriverOrder", validate_boot_order }, +	{ "Boot*", validate_load_option }, +	{ "Driver*", validate_load_option }, +	{ "ConIn", validate_device_path }, +	{ "ConInDev", validate_device_path }, +	{ "ConOut", validate_device_path }, +	{ "ConOutDev", validate_device_path }, +	{ "ErrOut", validate_device_path }, +	{ "ErrOutDev", validate_device_path }, +	{ "Timeout", validate_uint16 }, +	{ "Lang", validate_ascii_string }, +	{ "PlatformLang", validate_ascii_string }, +	{ "", NULL }, +}; + +static bool +validate_var(struct efi_variable *var, u8 *data, unsigned long len) +{ +	int i; +	u16 *unicode_name = var->VariableName; + +	for (i = 0; variable_validate[i].validate != NULL; i++) { +		const char *name = variable_validate[i].name; +		int match; + +		for (match = 0; ; match++) { +			char c = name[match]; +			u16 u = unicode_name[match]; + +			/* All special variables are plain ascii */ +			if (u > 127) +				return true; + +			/* Wildcard in the matching name means we've matched */ +			if (c == '*') +				return variable_validate[i].validate(var, +							     match, data, len); + +			/* Case sensitive match */ +			if (c != u) +				break; + +			/* Reached the end of the string while matching */ +			if (!c) +				return variable_validate[i].validate(var, +							     match, data, len); +		} +	} + +	return true; +} +  static efi_status_t  get_var_data_locked(struct efivars *efivars, struct efi_variable *var)  { @@ -324,6 +508,12 @@ efivar_store_raw(struct efivar_entry *entry, const char *buf, size_t count)  		return -EINVAL;  	} +	if ((new_var->Attributes & ~EFI_VARIABLE_MASK) != 0 || +	    validate_var(new_var, new_var->Data, new_var->DataSize) == false) { +		printk(KERN_ERR "efivars: Malformed variable content\n"); +		return -EINVAL; +	} +  	spin_lock(&efivars->lock);  	status = efivars->ops->set_variable(new_var->VariableName,  					    &new_var->VendorGuid, @@ -626,6 +816,12 @@ static ssize_t efivar_create(struct file *filp, struct kobject *kobj,  	if (!capable(CAP_SYS_ADMIN))  		return -EACCES; +	if ((new_var->Attributes & ~EFI_VARIABLE_MASK) != 0 || +	    validate_var(new_var, new_var->Data, new_var->DataSize) == false) { +		printk(KERN_ERR "efivars: Malformed variable content\n"); +		return -EINVAL; +	} +  	spin_lock(&efivars->lock);  	/* diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c index 5689ce62fd8..fc3ace3fd4c 100644 --- a/drivers/gpio/gpio-pxa.c +++ b/drivers/gpio/gpio-pxa.c @@ -64,6 +64,7 @@ struct pxa_gpio_chip {  	unsigned long	irq_mask;  	unsigned long	irq_edge_rise;  	unsigned long	irq_edge_fall; +	int (*set_wake)(unsigned int gpio, unsigned int on);  #ifdef CONFIG_PM  	unsigned long	saved_gplr; @@ -269,7 +270,8 @@ static void pxa_gpio_set(struct gpio_chip *chip, unsigned offset, int value)  				(value ? GPSR_OFFSET : GPCR_OFFSET));  } -static int __devinit pxa_init_gpio_chip(int gpio_end) +static int __devinit pxa_init_gpio_chip(int gpio_end, +					int (*set_wake)(unsigned int, unsigned int))  {  	int i, gpio, nbanks = gpio_to_bank(gpio_end) + 1;  	struct pxa_gpio_chip *chips; @@ -285,6 +287,7 @@ static int __devinit pxa_init_gpio_chip(int gpio_end)  		sprintf(chips[i].label, "gpio-%d", i);  		chips[i].regbase = gpio_reg_base + BANK_OFF(i); +		chips[i].set_wake = set_wake;  		c->base  = gpio;  		c->label = chips[i].label; @@ -412,6 +415,17 @@ static void pxa_mask_muxed_gpio(struct irq_data *d)  	writel_relaxed(gfer, c->regbase + GFER_OFFSET);  } +static int pxa_gpio_set_wake(struct irq_data *d, unsigned int on) +{ +	int gpio = pxa_irq_to_gpio(d->irq); +	struct pxa_gpio_chip *c = gpio_to_pxachip(gpio); + +	if (c->set_wake) +		return c->set_wake(gpio, on); +	else +		return 0; +} +  static void pxa_unmask_muxed_gpio(struct irq_data *d)  {  	int gpio = pxa_irq_to_gpio(d->irq); @@ -427,6 +441,7 @@ static struct irq_chip pxa_muxed_gpio_chip = {  	.irq_mask	= pxa_mask_muxed_gpio,  	.irq_unmask	= pxa_unmask_muxed_gpio,  	.irq_set_type	= pxa_gpio_irq_type, +	.irq_set_wake	= pxa_gpio_set_wake,  };  static int pxa_gpio_nums(void) @@ -471,6 +486,7 @@ static int __devinit pxa_gpio_probe(struct platform_device *pdev)  	struct pxa_gpio_chip *c;  	struct resource *res;  	struct clk *clk; +	struct pxa_gpio_platform_data *info;  	int gpio, irq, ret;  	int irq0 = 0, irq1 = 0, irq_mux, gpio_offset = 0; @@ -516,7 +532,8 @@ static int __devinit pxa_gpio_probe(struct platform_device *pdev)  	}  	/* Initialize GPIO chips */ -	pxa_init_gpio_chip(pxa_last_gpio); +	info = dev_get_platdata(&pdev->dev); +	pxa_init_gpio_chip(pxa_last_gpio, info ? info->gpio_set_wake : NULL);  	/* clear all GPIO edge detects */  	for_each_gpio_chip(gpio, c) { diff --git a/drivers/gpu/drm/drm_bufs.c b/drivers/gpu/drm/drm_bufs.c index 30372f7b2d4..348b367debe 100644 --- a/drivers/gpu/drm/drm_bufs.c +++ b/drivers/gpu/drm/drm_bufs.c @@ -1510,8 +1510,8 @@ int drm_freebufs(struct drm_device *dev, void *data,   * \param arg pointer to a drm_buf_map structure.   * \return zero on success or a negative number on failure.   * - * Maps the AGP, SG or PCI buffer region with do_mmap(), and copies information - * about each buffer into user space. For PCI buffers, it calls do_mmap() with + * Maps the AGP, SG or PCI buffer region with vm_mmap(), and copies information + * about each buffer into user space. For PCI buffers, it calls vm_mmap() with   * offset equal to 0, which drm_mmap() interpretes as PCI buffers and calls   * drm_mmap_dma().   */ @@ -1553,18 +1553,14 @@ int drm_mapbufs(struct drm_device *dev, void *data,  				retcode = -EINVAL;  				goto done;  			} -			down_write(¤t->mm->mmap_sem); -			virtual = do_mmap(file_priv->filp, 0, map->size, +			virtual = vm_mmap(file_priv->filp, 0, map->size,  					  PROT_READ | PROT_WRITE,  					  MAP_SHARED,  					  token); -			up_write(¤t->mm->mmap_sem);  		} else { -			down_write(¤t->mm->mmap_sem); -			virtual = do_mmap(file_priv->filp, 0, dma->byte_count, +			virtual = vm_mmap(file_priv->filp, 0, dma->byte_count,  					  PROT_READ | PROT_WRITE,  					  MAP_SHARED, 0); -			up_write(¤t->mm->mmap_sem);  		}  		if (virtual > -1024UL) {  			/* Real error */ diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 3519b6c174a..ee63a123235 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -3376,10 +3376,12 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,  	ret = crtc->funcs->page_flip(crtc, fb, e);  	if (ret) { -		spin_lock_irqsave(&dev->event_lock, flags); -		file_priv->event_space += sizeof e->event; -		spin_unlock_irqrestore(&dev->event_lock, flags); -		kfree(e); +		if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT) { +			spin_lock_irqsave(&dev->event_lock, flags); +			file_priv->event_space += sizeof e->event; +			spin_unlock_irqrestore(&dev->event_lock, flags); +			kfree(e); +		}  	}  out: diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c index cdfbf27b2b3..123de28f94e 100644 --- a/drivers/gpu/drm/drm_fops.c +++ b/drivers/gpu/drm/drm_fops.c @@ -507,12 +507,12 @@ int drm_release(struct inode *inode, struct file *filp)  	drm_events_release(file_priv); -	if (dev->driver->driver_features & DRIVER_GEM) -		drm_gem_release(dev, file_priv); -  	if (dev->driver->driver_features & DRIVER_MODESET)  		drm_fb_release(file_priv); +	if (dev->driver->driver_features & DRIVER_GEM) +		drm_gem_release(dev, file_priv); +  	mutex_lock(&dev->ctxlist_mutex);  	if (!list_empty(&dev->ctxlist)) {  		struct drm_ctx_list *pos, *n; diff --git a/drivers/gpu/drm/drm_usb.c b/drivers/gpu/drm/drm_usb.c index c8c83dad2ce..37c9a523dd1 100644 --- a/drivers/gpu/drm/drm_usb.c +++ b/drivers/gpu/drm/drm_usb.c @@ -1,6 +1,6 @@  #include "drmP.h"  #include <linux/usb.h> -#include <linux/export.h> +#include <linux/module.h>  int drm_get_usb_dev(struct usb_interface *interface,  		    const struct usb_device_id *id, @@ -114,3 +114,7 @@ void drm_usb_exit(struct drm_driver *driver,  	usb_deregister(udriver);  }  EXPORT_SYMBOL(drm_usb_exit); + +MODULE_AUTHOR("David Airlie"); +MODULE_DESCRIPTION("USB DRM support"); +MODULE_LICENSE("GPL and additional rights"); diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c index 26d51979116..1dffa8359f8 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gem.c +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c @@ -149,22 +149,12 @@ static int exynos_drm_gem_map_pages(struct drm_gem_object *obj,  	unsigned long pfn;  	if (exynos_gem_obj->flags & EXYNOS_BO_NONCONTIG) { -		unsigned long usize = buf->size; -  		if (!buf->pages)  			return -EINTR; -		while (usize > 0) { -			pfn = page_to_pfn(buf->pages[page_offset++]); -			vm_insert_mixed(vma, f_vaddr, pfn); -			f_vaddr += PAGE_SIZE; -			usize -= PAGE_SIZE; -		} - -		return 0; -	} - -	pfn = (buf->dma_addr >> PAGE_SHIFT) + page_offset; +		pfn = page_to_pfn(buf->pages[page_offset++]); +	} else +		pfn = (buf->dma_addr >> PAGE_SHIFT) + page_offset;  	return vm_insert_mixed(vma, f_vaddr, pfn);  } @@ -524,6 +514,8 @@ static int exynos_drm_gem_mmap_buffer(struct file *filp,  		if (!buffer->pages)  			return -EINVAL; +		vma->vm_flags |= VM_MIXEDMAP; +  		do {  			ret = vm_insert_page(vma, uaddr, buffer->pages[i++]);  			if (ret) { @@ -581,10 +573,8 @@ int exynos_drm_gem_mmap_ioctl(struct drm_device *dev, void *data,  	obj->filp->f_op = &exynos_drm_gem_fops;  	obj->filp->private_data = obj; -	down_write(¤t->mm->mmap_sem); -	addr = do_mmap(obj->filp, 0, args->size, +	addr = vm_mmap(obj->filp, 0, args->size,  			PROT_READ | PROT_WRITE, MAP_SHARED, 0); -	up_write(¤t->mm->mmap_sem);  	drm_gem_object_unreference_unlocked(obj); @@ -712,7 +702,6 @@ int exynos_drm_gem_dumb_destroy(struct drm_file *file_priv,  int exynos_drm_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)  {  	struct drm_gem_object *obj = vma->vm_private_data; -	struct exynos_drm_gem_obj *exynos_gem_obj = to_exynos_gem_obj(obj);  	struct drm_device *dev = obj->dev;  	unsigned long f_vaddr;  	pgoff_t page_offset; @@ -724,21 +713,10 @@ int exynos_drm_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)  	mutex_lock(&dev->struct_mutex); -	/* -	 * allocate all pages as desired size if user wants to allocate -	 * physically non-continuous memory. -	 */ -	if (exynos_gem_obj->flags & EXYNOS_BO_NONCONTIG) { -		ret = exynos_drm_gem_get_pages(obj); -		if (ret < 0) -			goto err; -	} -  	ret = exynos_drm_gem_map_pages(obj, vma, f_vaddr, page_offset);  	if (ret < 0)  		DRM_ERROR("failed to map pages.\n"); -err:  	mutex_unlock(&dev->struct_mutex);  	return convert_to_vm_err_msg(ret); diff --git a/drivers/gpu/drm/gma500/mdfld_dsi_output.h b/drivers/gpu/drm/gma500/mdfld_dsi_output.h index 21071cef92a..36eb0744841 100644 --- a/drivers/gpu/drm/gma500/mdfld_dsi_output.h +++ b/drivers/gpu/drm/gma500/mdfld_dsi_output.h @@ -29,7 +29,6 @@  #define __MDFLD_DSI_OUTPUT_H__  #include <linux/backlight.h> -#include <linux/version.h>  #include <drm/drmP.h>  #include <drm/drm.h>  #include <drm/drm_crtc.h> diff --git a/drivers/gpu/drm/i810/i810_dma.c b/drivers/gpu/drm/i810/i810_dma.c index 2c8a60c3b98..f920fb5e42b 100644 --- a/drivers/gpu/drm/i810/i810_dma.c +++ b/drivers/gpu/drm/i810/i810_dma.c @@ -129,6 +129,7 @@ static int i810_map_buffer(struct drm_buf *buf, struct drm_file *file_priv)  	if (buf_priv->currently_mapped == I810_BUF_MAPPED)  		return -EINVAL; +	/* This is all entirely broken */  	down_write(¤t->mm->mmap_sem);  	old_fops = file_priv->filp->f_op;  	file_priv->filp->f_op = &i810_buffer_fops; @@ -157,11 +158,8 @@ static int i810_unmap_buffer(struct drm_buf *buf)  	if (buf_priv->currently_mapped != I810_BUF_MAPPED)  		return -EINVAL; -	down_write(¤t->mm->mmap_sem); -	retcode = do_munmap(current->mm, -			    (unsigned long)buf_priv->virtual, +	retcode = vm_munmap((unsigned long)buf_priv->virtual,  			    (size_t) buf->total); -	up_write(¤t->mm->mmap_sem);  	buf_priv->currently_mapped = I810_BUF_UNMAPPED;  	buf_priv->virtual = NULL; diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 35462df7cef..a8db38617f4 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -1274,6 +1274,9 @@ static int i915_emon_status(struct seq_file *m, void *unused)  	unsigned long temp, chipset, gfx;  	int ret; +	if (!IS_GEN5(dev)) +		return -ENODEV; +  	ret = mutex_lock_interruptible(&dev->struct_mutex);  	if (ret)  		return ret; diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index a813f652fa1..068958cdd55 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1706,6 +1706,9 @@ void i915_update_gfx_val(struct drm_i915_private *dev_priv)  	unsigned long diffms;  	u32 count; +	if (dev_priv->info->gen != 5) +		return; +  	getrawmonotonic(&now);  	diff1 = timespec_sub(now, dev_priv->last_time2); @@ -2148,12 +2151,14 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)  	setup_timer(&dev_priv->hangcheck_timer, i915_hangcheck_elapsed,  		    (unsigned long) dev); -	spin_lock(&mchdev_lock); -	i915_mch_dev = dev_priv; -	dev_priv->mchdev_lock = &mchdev_lock; -	spin_unlock(&mchdev_lock); +	if (IS_GEN5(dev)) { +		spin_lock(&mchdev_lock); +		i915_mch_dev = dev_priv; +		dev_priv->mchdev_lock = &mchdev_lock; +		spin_unlock(&mchdev_lock); -	ips_ping_for_i915_load(); +		ips_ping_for_i915_load(); +	}  	return 0; diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 7bc4a40132a..dd87937e921 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1026,11 +1026,9 @@ i915_gem_mmap_ioctl(struct drm_device *dev, void *data,  	if (obj == NULL)  		return -ENOENT; -	down_write(¤t->mm->mmap_sem); -	addr = do_mmap(obj->filp, 0, args->size, +	addr = vm_mmap(obj->filp, 0, args->size,  		       PROT_READ | PROT_WRITE, MAP_SHARED,  		       args->offset); -	up_write(¤t->mm->mmap_sem);  	drm_gem_object_unreference_unlocked(obj);  	if (IS_ERR((void *)addr))  		return addr; diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 68ec0130a62..c77bfa9ad34 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -1116,6 +1116,11 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,  			return -EINVAL;  		} +		if (args->num_cliprects > UINT_MAX / sizeof(*cliprects)) { +			DRM_DEBUG("execbuf with %u cliprects\n", +				  args->num_cliprects); +			return -EINVAL; +		}  		cliprects = kmalloc(args->num_cliprects * sizeof(*cliprects),  				    GFP_KERNEL);  		if (cliprects == NULL) { @@ -1387,7 +1392,8 @@ i915_gem_execbuffer2(struct drm_device *dev, void *data,  	struct drm_i915_gem_exec_object2 *exec2_list = NULL;  	int ret; -	if (args->buffer_count < 1) { +	if (args->buffer_count < 1 || +	    args->buffer_count > UINT_MAX / sizeof(*exec2_list)) {  		DRM_DEBUG("execbuf2 with %d buffers\n", args->buffer_count);  		return -EINVAL;  	} diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index 0976137ab79..417ca99e697 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c @@ -449,8 +449,8 @@ intel_crt_detect(struct drm_connector *connector, bool force)  {  	struct drm_device *dev = connector->dev;  	struct intel_crt *crt = intel_attached_crt(connector); -	struct drm_crtc *crtc;  	enum drm_connector_status status; +	struct intel_load_detect_pipe tmp;  	if (I915_HAS_HOTPLUG(dev)) {  		if (intel_crt_detect_hotplug(connector)) { @@ -469,23 +469,16 @@ intel_crt_detect(struct drm_connector *connector, bool force)  		return connector->status;  	/* for pre-945g platforms use load detect */ -	crtc = crt->base.base.crtc; -	if (crtc && crtc->enabled) { -		status = intel_crt_load_detect(crt); -	} else { -		struct intel_load_detect_pipe tmp; - -		if (intel_get_load_detect_pipe(&crt->base, connector, NULL, -					       &tmp)) { -			if (intel_crt_detect_ddc(connector)) -				status = connector_status_connected; -			else -				status = intel_crt_load_detect(crt); -			intel_release_load_detect_pipe(&crt->base, connector, -						       &tmp); -		} else -			status = connector_status_unknown; -	} +	if (intel_get_load_detect_pipe(&crt->base, connector, NULL, +				       &tmp)) { +		if (intel_crt_detect_ddc(connector)) +			status = connector_status_connected; +		else +			status = intel_crt_load_detect(crt); +		intel_release_load_detect_pipe(&crt->base, connector, +					       &tmp); +	} else +		status = connector_status_unknown;  	return status;  } diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 4c844c68ec8..8c239f2d6bc 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -3078,8 +3078,11 @@ static bool intel_crtc_mode_fixup(struct drm_crtc *crtc,  			return false;  	} -	/* All interlaced capable intel hw wants timings in frames. */ -	drm_mode_set_crtcinfo(adjusted_mode, 0); +	/* All interlaced capable intel hw wants timings in frames. Note though +	 * that intel_lvds_mode_fixup does some funny tricks with the crtc +	 * timings, so we need to be careful not to clobber these.*/ +	if (!(adjusted_mode->private_flags & INTEL_MODE_CRTC_TIMINGS_SET)) +		drm_mode_set_crtcinfo(adjusted_mode, 0);  	return true;  } @@ -5385,9 +5388,6 @@ static void intel_decrease_pllclock(struct drm_crtc *crtc)  	struct drm_device *dev = crtc->dev;  	drm_i915_private_t *dev_priv = dev->dev_private;  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc); -	int pipe = intel_crtc->pipe; -	int dpll_reg = DPLL(pipe); -	int dpll = I915_READ(dpll_reg);  	if (HAS_PCH_SPLIT(dev))  		return; @@ -5400,10 +5400,15 @@ static void intel_decrease_pllclock(struct drm_crtc *crtc)  	 * the manual case.  	 */  	if (!HAS_PIPE_CXSR(dev) && intel_crtc->lowfreq_avail) { +		int pipe = intel_crtc->pipe; +		int dpll_reg = DPLL(pipe); +		int dpll; +  		DRM_DEBUG_DRIVER("downclocking LVDS\n");  		assert_panel_unlocked(dev_priv, pipe); +		dpll = I915_READ(dpll_reg);  		dpll |= DISPLAY_RATE_SELECT_FPA1;  		I915_WRITE(dpll_reg, dpll);  		intel_wait_for_vblank(dev, pipe); @@ -5793,7 +5798,13 @@ static int intel_gen6_queue_flip(struct drm_device *dev,  	OUT_RING(fb->pitches[0] | obj->tiling_mode);  	OUT_RING(obj->gtt_offset); -	pf = I915_READ(PF_CTL(intel_crtc->pipe)) & PF_ENABLE; +	/* Contrary to the suggestions in the documentation, +	 * "Enable Panel Fitter" does not seem to be required when page +	 * flipping with a non-native mode, and worse causes a normal +	 * modeset to fail. +	 * pf = I915_READ(PF_CTL(intel_crtc->pipe)) & PF_ENABLE; +	 */ +	pf = 0;  	pipesrc = I915_READ(PIPESRC(intel_crtc->pipe)) & 0x0fff0fff;  	OUT_RING(pf | pipesrc);  	ADVANCE_LP_RING(); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index c5bf8bebf0b..7a7cae77f0c 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -117,6 +117,10 @@  #define INTEL_MODE_PIXEL_MULTIPLIER_SHIFT (0x0)  #define INTEL_MODE_PIXEL_MULTIPLIER_MASK (0xf << INTEL_MODE_PIXEL_MULTIPLIER_SHIFT)  #define INTEL_MODE_DP_FORCE_6BPC (0x10) +/* This flag must be set by the encoder's mode_fixup if it changes the crtc + * timings in the mode to prevent the crtc fixup from overwriting them. + * Currently only lvds needs that. */ +#define INTEL_MODE_CRTC_TIMINGS_SET (0x20)  static inline void  intel_mode_set_pixel_multiplier(struct drm_display_mode *mode, diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c index 71ef2896be9..bf8690720a0 100644 --- a/drivers/gpu/drm/i915/intel_fb.c +++ b/drivers/gpu/drm/i915/intel_fb.c @@ -279,6 +279,8 @@ void intel_fb_restore_mode(struct drm_device *dev)  	struct drm_mode_config *config = &dev->mode_config;  	struct drm_plane *plane; +	mutex_lock(&dev->mode_config.mutex); +  	ret = drm_fb_helper_restore_fbdev_mode(&dev_priv->fbdev->helper);  	if (ret)  		DRM_DEBUG("failed to restore crtc mode\n"); @@ -286,4 +288,6 @@ void intel_fb_restore_mode(struct drm_device *dev)  	/* Be sure to shut off any planes that may be active */  	list_for_each_entry(plane, &config->plane_list, head)  		plane->funcs->disable_plane(plane); + +	mutex_unlock(&dev->mode_config.mutex);  } diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 7de2d3b85b3..1eef50d470d 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -136,7 +136,7 @@ static void i9xx_write_infoframe(struct drm_encoder *encoder,  	val &= ~VIDEO_DIP_SELECT_MASK; -	I915_WRITE(VIDEO_DIP_CTL, val | port | flags); +	I915_WRITE(VIDEO_DIP_CTL, VIDEO_DIP_ENABLE | val | port | flags);  	for (i = 0; i < len; i += 4) {  		I915_WRITE(VIDEO_DIP_DATA, *data); diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 17a4630cec8..9dee82350de 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -187,6 +187,8 @@ centre_horizontally(struct drm_display_mode *mode,  	mode->crtc_hsync_start = mode->crtc_hblank_start + sync_pos;  	mode->crtc_hsync_end = mode->crtc_hsync_start + sync_width; + +	mode->private_flags |= INTEL_MODE_CRTC_TIMINGS_SET;  }  static void @@ -208,6 +210,8 @@ centre_vertically(struct drm_display_mode *mode,  	mode->crtc_vsync_start = mode->crtc_vblank_start + sync_pos;  	mode->crtc_vsync_end = mode->crtc_vsync_start + sync_width; + +	mode->private_flags |= INTEL_MODE_CRTC_TIMINGS_SET;  }  static inline u32 panel_fitter_scaling(u32 source, u32 target) @@ -283,6 +287,8 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder,  	for_each_pipe(pipe)  		I915_WRITE(BCLRPAT(pipe), 0); +	drm_mode_set_crtcinfo(adjusted_mode, 0); +  	switch (intel_lvds->fitting_mode) {  	case DRM_MODE_SCALE_CENTER:  		/* @@ -744,7 +750,7 @@ static const struct dmi_system_id intel_no_lvds[] = {  		.ident = "Hewlett-Packard t5745",  		.matches = {  			DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"), -			DMI_MATCH(DMI_BOARD_NAME, "hp t5745"), +			DMI_MATCH(DMI_PRODUCT_NAME, "hp t5745"),  		},  	},  	{ @@ -752,7 +758,7 @@ static const struct dmi_system_id intel_no_lvds[] = {  		.ident = "Hewlett-Packard st5747",  		.matches = {  			DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"), -			DMI_MATCH(DMI_BOARD_NAME, "hp st5747"), +			DMI_MATCH(DMI_PRODUCT_NAME, "hp st5747"),  		},  	},  	{ diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index cad45ff8251..2b2e011e905 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -50,8 +50,6 @@ intel_fixed_panel_mode(struct drm_display_mode *fixed_mode,  	adjusted_mode->vtotal = fixed_mode->vtotal;  	adjusted_mode->clock = fixed_mode->clock; - -	drm_mode_set_crtcinfo(adjusted_mode, 0);  }  /* adjusted_mode has been preset to be the panel's fixed mode */ diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 12d9bc789df..b5ef7c145ee 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -418,6 +418,14 @@ static int init_render_ring(struct intel_ring_buffer *ring)  	if (INTEL_INFO(dev)->gen >= 6) {  		I915_WRITE(INSTPM,  			   INSTPM_FORCE_ORDERING << 16 | INSTPM_FORCE_ORDERING); + +		/* From the Sandybridge PRM, volume 1 part 3, page 24: +		 * "If this bit is set, STCunit will have LRA as replacement +		 *  policy. [...] This bit must be reset.  LRA replacement +		 *  policy is not supported." +		 */ +		I915_WRITE(CACHE_MODE_0, +			   CM0_STC_EVICT_DISABLE_LRA_SNB << CM0_MASK_SHIFT);  	}  	return ret; diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index c330efd59a0..3d9dfa57130 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -745,6 +745,7 @@ static void intel_sdvo_get_dtd_from_mode(struct intel_sdvo_dtd *dtd,  	uint16_t width, height;  	uint16_t h_blank_len, h_sync_len, v_blank_len, v_sync_len;  	uint16_t h_sync_offset, v_sync_offset; +	int mode_clock;  	width = mode->crtc_hdisplay;  	height = mode->crtc_vdisplay; @@ -759,7 +760,11 @@ static void intel_sdvo_get_dtd_from_mode(struct intel_sdvo_dtd *dtd,  	h_sync_offset = mode->crtc_hsync_start - mode->crtc_hblank_start;  	v_sync_offset = mode->crtc_vsync_start - mode->crtc_vblank_start; -	dtd->part1.clock = mode->clock / 10; +	mode_clock = mode->clock; +	mode_clock /= intel_mode_get_pixel_multiplier(mode) ?: 1; +	mode_clock /= 10; +	dtd->part1.clock = mode_clock; +  	dtd->part1.h_active = width & 0xff;  	dtd->part1.h_blank = h_blank_len & 0xff;  	dtd->part1.h_high = (((width >> 8) & 0xf) << 4) | @@ -1010,7 +1015,7 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,  	struct intel_sdvo *intel_sdvo = to_intel_sdvo(encoder);  	u32 sdvox;  	struct intel_sdvo_in_out_map in_out; -	struct intel_sdvo_dtd input_dtd; +	struct intel_sdvo_dtd input_dtd, output_dtd;  	int pixel_multiplier = intel_mode_get_pixel_multiplier(adjusted_mode);  	int rate; @@ -1035,20 +1040,13 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,  					  intel_sdvo->attached_output))  		return; -	/* We have tried to get input timing in mode_fixup, and filled into -	 * adjusted_mode. -	 */ -	if (intel_sdvo->is_tv || intel_sdvo->is_lvds) { -		input_dtd = intel_sdvo->input_dtd; -	} else { -		/* Set the output timing to the screen */ -		if (!intel_sdvo_set_target_output(intel_sdvo, -						  intel_sdvo->attached_output)) -			return; - -		intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode); -		(void) intel_sdvo_set_output_timing(intel_sdvo, &input_dtd); -	} +	/* lvds has a special fixed output timing. */ +	if (intel_sdvo->is_lvds) +		intel_sdvo_get_dtd_from_mode(&output_dtd, +					     intel_sdvo->sdvo_lvds_fixed_mode); +	else +		intel_sdvo_get_dtd_from_mode(&output_dtd, mode); +	(void) intel_sdvo_set_output_timing(intel_sdvo, &output_dtd);  	/* Set the input timing to the screen. Assume always input 0. */  	if (!intel_sdvo_set_target_input(intel_sdvo)) @@ -1066,6 +1064,10 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,  	    !intel_sdvo_set_tv_format(intel_sdvo))  		return; +	/* We have tried to get input timing in mode_fixup, and filled into +	 * adjusted_mode. +	 */ +	intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode);  	(void) intel_sdvo_set_input_timing(intel_sdvo, &input_dtd);  	switch (pixel_multiplier) { diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.c b/drivers/gpu/drm/nouveau/nouveau_acpi.c index 7814a760c16..284bd25d5d2 100644 --- a/drivers/gpu/drm/nouveau/nouveau_acpi.c +++ b/drivers/gpu/drm/nouveau/nouveau_acpi.c @@ -270,7 +270,7 @@ static bool nouveau_dsm_detect(void)  	struct acpi_buffer buffer = {sizeof(acpi_method_name), acpi_method_name};  	struct pci_dev *pdev = NULL;  	int has_dsm = 0; -	int has_optimus; +	int has_optimus = 0;  	int vga_count = 0;  	bool guid_valid;  	int retval; diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index 80963d05b54..0be4a815e70 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c @@ -6156,10 +6156,14 @@ dcb_fake_connectors(struct nvbios *bios)  	/* heuristic: if we ever get a non-zero connector field, assume  	 * that all the indices are valid and we don't need fake them. +	 * +	 * and, as usual, a blacklist of boards with bad bios data..  	 */ -	for (i = 0; i < dcbt->entries; i++) { -		if (dcbt->entry[i].connector) -			return; +	if (!nv_match_device(bios->dev, 0x0392, 0x107d, 0x20a2)) { +		for (i = 0; i < dcbt->entries; i++) { +			if (dcbt->entry[i].connector) +				return; +		}  	}  	/* no useful connector info available, we need to make it up diff --git a/drivers/gpu/drm/nouveau/nouveau_hdmi.c b/drivers/gpu/drm/nouveau/nouveau_hdmi.c index 59ea1c14eca..c3de3638452 100644 --- a/drivers/gpu/drm/nouveau/nouveau_hdmi.c +++ b/drivers/gpu/drm/nouveau/nouveau_hdmi.c @@ -32,7 +32,9 @@ static bool  hdmi_sor(struct drm_encoder *encoder)  {  	struct drm_nouveau_private *dev_priv = encoder->dev->dev_private; -	if (dev_priv->chipset < 0xa3) +	if (dev_priv->chipset <  0xa3 || +	    dev_priv->chipset == 0xaa || +	    dev_priv->chipset == 0xac)  		return false;  	return true;  } diff --git a/drivers/gpu/drm/nouveau/nouveau_pm.c b/drivers/gpu/drm/nouveau/nouveau_pm.c index 34d591b7d4e..da3e7c3abab 100644 --- a/drivers/gpu/drm/nouveau/nouveau_pm.c +++ b/drivers/gpu/drm/nouveau/nouveau_pm.c @@ -235,6 +235,7 @@ nouveau_pm_profile_set(struct drm_device *dev, const char *profile)  		return -EPERM;  	strncpy(string, profile, sizeof(string)); +	string[sizeof(string) - 1] = 0;  	if ((ptr = strchr(string, '\n')))  		*ptr = '\0'; diff --git a/drivers/gpu/drm/nouveau/nv10_gpio.c b/drivers/gpu/drm/nouveau/nv10_gpio.c index 550ad3fcf0a..9d79180069d 100644 --- a/drivers/gpu/drm/nouveau/nv10_gpio.c +++ b/drivers/gpu/drm/nouveau/nv10_gpio.c @@ -65,7 +65,7 @@ nv10_gpio_drive(struct drm_device *dev, int line, int dir, int out)  	if (line < 10) {  		line = (line - 2) * 4;  		reg  = NV_PCRTC_GPIO_EXT; -		mask = 0x00000003 << ((line - 2) * 4); +		mask = 0x00000003;  		data = (dir << 1) | out;  	} else  	if (line < 14) { diff --git a/drivers/gpu/drm/nouveau/nv50_sor.c b/drivers/gpu/drm/nouveau/nv50_sor.c index a7844ab6a50..27464021247 100644 --- a/drivers/gpu/drm/nouveau/nv50_sor.c +++ b/drivers/gpu/drm/nouveau/nv50_sor.c @@ -42,7 +42,7 @@ nv50_sor_dp_lane_map(struct drm_device *dev, struct dcb_entry *dcb, u8 lane)  	struct drm_nouveau_private *dev_priv = dev->dev_private;  	static const u8 nvaf[] = { 24, 16, 8, 0 }; /* thanks, apple.. */  	static const u8 nv50[] = { 16, 8, 0, 24 }; -	if (dev_priv->card_type == 0xaf) +	if (dev_priv->chipset == 0xaf)  		return nvaf[lane];  	return nv50[lane];  } diff --git a/drivers/gpu/drm/nouveau/nvc0_fb.c b/drivers/gpu/drm/nouveau/nvc0_fb.c index 5bf55038fd9..f704e942372 100644 --- a/drivers/gpu/drm/nouveau/nvc0_fb.c +++ b/drivers/gpu/drm/nouveau/nvc0_fb.c @@ -54,6 +54,11 @@ nvc0_mfb_isr(struct drm_device *dev)  			nvc0_mfb_subp_isr(dev, unit, subp);  		units &= ~(1 << unit);  	} + +	/* we do something horribly wrong and upset PMFB a lot, so mask off +	 * interrupts from it after the first one until it's fixed +	 */ +	nv_mask(dev, 0x000640, 0x02000000, 0x00000000);  }  static void diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index 2fab38f5a08..01d77d1554f 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c @@ -575,6 +575,9 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,  		if (rdev->family < CHIP_RV770)  			pll->flags |= RADEON_PLL_PREFER_MINM_OVER_MAXP; +		/* use frac fb div on APUs */ +		if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE61(rdev)) +			pll->flags |= RADEON_PLL_USE_FRAC_FB_DIV;  	} else {  		pll->flags |= RADEON_PLL_LEGACY; @@ -954,8 +957,8 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode  		break;  	} -	if (radeon_encoder->active_device & -	    (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT)) { +	if ((radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT)) || +	    (radeon_encoder_get_dp_bridge_encoder_id(encoder) != ENCODER_OBJECT_ID_NONE)) {  		struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;  		struct drm_connector *connector =  			radeon_get_connector_for_encoder(encoder); diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 87a2333c0c6..d02f13fdaa6 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -1135,7 +1135,7 @@ static void r600_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc  	}  	if (rdev->flags & RADEON_IS_AGP) {  		size_bf = mc->gtt_start; -		size_af = 0xFFFFFFFF - mc->gtt_end + 1; +		size_af = 0xFFFFFFFF - mc->gtt_end;  		if (size_bf > size_af) {  			if (mc->mc_vram_size > size_bf) {  				dev_warn(rdev->dev, "limiting VRAM\n"); @@ -1149,7 +1149,7 @@ static void r600_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc  				mc->real_vram_size = size_af;  				mc->mc_vram_size = size_af;  			} -			mc->vram_start = mc->gtt_end; +			mc->vram_start = mc->gtt_end + 1;  		}  		mc->vram_end = mc->vram_start + mc->mc_vram_size - 1;  		dev_info(rdev->dev, "VRAM: %lluM 0x%08llX - 0x%08llX (%lluM used)\n", diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index 71fa389e10f..2914c5761cf 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c @@ -1026,7 +1026,7 @@ radeon_dvi_detect(struct drm_connector *connector, bool force)  			encoder = obj_to_encoder(obj); -			if (encoder->encoder_type != DRM_MODE_ENCODER_DAC || +			if (encoder->encoder_type != DRM_MODE_ENCODER_DAC &&  			    encoder->encoder_type != DRM_MODE_ENCODER_TVDAC)  				continue; @@ -1056,6 +1056,7 @@ radeon_dvi_detect(struct drm_connector *connector, bool force)  	 * cases the DVI port is actually a virtual KVM port connected to the service  	 * processor.  	 */ +out:  	if ((!rdev->is_atom_bios) &&  	    (ret == connector_status_disconnected) &&  	    rdev->mode_info.bios_hardcoded_edid_size) { @@ -1063,7 +1064,6 @@ radeon_dvi_detect(struct drm_connector *connector, bool force)  		ret = connector_status_connected;  	} -out:  	/* updated in get modes as well since we need to know if it's analog or digital */  	radeon_connector_update_scratch_regs(connector, ret);  	return ret; diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index d18f0c4a988..ff28210dede 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c @@ -241,8 +241,8 @@ int radeon_wb_init(struct radeon_device *rdev)  				rdev->wb.use_event = true;  		}  	} -	/* always use writeback/events on NI */ -	if (ASIC_IS_DCE5(rdev)) { +	/* always use writeback/events on NI, APUs */ +	if (rdev->family >= CHIP_PALM) {  		rdev->wb.enabled = true;  		rdev->wb.use_event = true;  	} diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 8086c96e0b0..0a1d4bd65ed 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c @@ -533,7 +533,7 @@ static void radeon_crtc_init(struct drm_device *dev, int index)  		radeon_legacy_init_crtc(dev, radeon_crtc);  } -static const char *encoder_names[36] = { +static const char *encoder_names[37] = {  	"NONE",  	"INTERNAL_LVDS",  	"INTERNAL_TMDS1", @@ -570,6 +570,7 @@ static const char *encoder_names[36] = {  	"INTERNAL_UNIPHY2",  	"NUTMEG",  	"TRAVIS", +	"INTERNAL_VCE"  };  static const char *connector_names[15] = { diff --git a/drivers/gpu/drm/radeon/radeon_irq_kms.c b/drivers/gpu/drm/radeon/radeon_irq_kms.c index 170f1718d92..5df58d1aba0 100644 --- a/drivers/gpu/drm/radeon/radeon_irq_kms.c +++ b/drivers/gpu/drm/radeon/radeon_irq_kms.c @@ -149,6 +149,12 @@ static bool radeon_msi_ok(struct radeon_device *rdev)  	    (rdev->pdev->subsystem_device == 0x01fd))  		return true; +	/* RV515 seems to have MSI issues where it loses +	 * MSI rearms occasionally. This leads to lockups and freezes. +	 * disable it by default. +	 */ +	if (rdev->family == CHIP_RV515) +		return false;  	if (rdev->flags & RADEON_IS_IGP) {  		/* APUs work fine with MSIs */  		if (rdev->family >= CHIP_PALM) diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index cacec0e20ae..a8b001641e4 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c @@ -969,7 +969,7 @@ void r700_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc)  	}  	if (rdev->flags & RADEON_IS_AGP) {  		size_bf = mc->gtt_start; -		size_af = 0xFFFFFFFF - mc->gtt_end + 1; +		size_af = 0xFFFFFFFF - mc->gtt_end;  		if (size_bf > size_af) {  			if (mc->mc_vram_size > size_bf) {  				dev_warn(rdev->dev, "limiting VRAM\n"); @@ -983,7 +983,7 @@ void r700_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc)  				mc->real_vram_size = size_af;  				mc->mc_vram_size = size_af;  			} -			mc->vram_start = mc->gtt_end; +			mc->vram_start = mc->gtt_end + 1;  		}  		mc->vram_end = mc->vram_start + mc->mc_vram_size - 1;  		dev_info(rdev->dev, "VRAM: %lluM 0x%08llX - 0x%08llX (%lluM used)\n", diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index 0bad5ff651d..779f0b604fa 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c @@ -2989,8 +2989,8 @@ int si_rlc_init(struct radeon_device *rdev)  	}  	r = radeon_bo_pin(rdev->rlc.save_restore_obj, RADEON_GEM_DOMAIN_VRAM,  			  &rdev->rlc.save_restore_gpu_addr); +	radeon_bo_unreserve(rdev->rlc.save_restore_obj);  	if (r) { -		radeon_bo_unreserve(rdev->rlc.save_restore_obj);  		dev_warn(rdev->dev, "(%d) pin RLC sr bo failed\n", r);  		si_rlc_fini(rdev);  		return r; @@ -3013,9 +3013,8 @@ int si_rlc_init(struct radeon_device *rdev)  	}  	r = radeon_bo_pin(rdev->rlc.clear_state_obj, RADEON_GEM_DOMAIN_VRAM,  			  &rdev->rlc.clear_state_gpu_addr); +	radeon_bo_unreserve(rdev->rlc.clear_state_obj);  	if (r) { - -		radeon_bo_unreserve(rdev->rlc.clear_state_obj);  		dev_warn(rdev->dev, "(%d) pin RLC c bo failed\n", r);  		si_rlc_fini(rdev);  		return r; diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index a3d03325299..ffddcba32af 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -34,7 +34,7 @@ config HID  config HID_BATTERY_STRENGTH  	bool  	depends on HID && POWER_SUPPLY && HID = POWER_SUPPLY -	default y +	default n  config HIDRAW  	bool "/dev/hidraw raw HID device support" diff --git a/drivers/hid/hid-tivo.c b/drivers/hid/hid-tivo.c index de47039c708..9f85f827607 100644 --- a/drivers/hid/hid-tivo.c +++ b/drivers/hid/hid-tivo.c @@ -62,7 +62,7 @@ static int tivo_input_mapping(struct hid_device *hdev, struct hid_input *hi,  static const struct hid_device_id tivo_devices[] = {  	/* TiVo Slide Bluetooth remote, pairs with a Broadcom dongle */ -	{ HID_USB_DEVICE(USB_VENDOR_ID_TIVO, USB_DEVICE_ID_TIVO_SLIDE_BT) }, +	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_TIVO, USB_DEVICE_ID_TIVO_SLIDE_BT) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_TIVO, USB_DEVICE_ID_TIVO_SLIDE) },  	{ }  }; diff --git a/drivers/hsi/clients/hsi_char.c b/drivers/hsi/clients/hsi_char.c index 88a050df238..3ad91f6447d 100644 --- a/drivers/hsi/clients/hsi_char.c +++ b/drivers/hsi/clients/hsi_char.c @@ -123,7 +123,7 @@ struct hsc_client_data {  static unsigned int hsc_major;  /* Maximum buffer size that hsi_char will accept from userspace */  static unsigned int max_data_size = 0x1000; -module_param(max_data_size, uint, S_IRUSR | S_IWUSR); +module_param(max_data_size, uint, 0);  MODULE_PARM_DESC(max_data_size, "max read/write data size [4,8..65536] (^2)");  static void hsc_add_tail(struct hsc_channel *channel, struct hsi_msg *msg, diff --git a/drivers/hsi/hsi.c b/drivers/hsi/hsi.c index 4e2d79b7933..2d58f939d27 100644 --- a/drivers/hsi/hsi.c +++ b/drivers/hsi/hsi.c @@ -21,26 +21,13 @@   */  #include <linux/hsi/hsi.h>  #include <linux/compiler.h> -#include <linux/rwsem.h>  #include <linux/list.h> -#include <linux/spinlock.h>  #include <linux/kobject.h>  #include <linux/slab.h>  #include <linux/string.h> +#include <linux/notifier.h>  #include "hsi_core.h" -static struct device_type hsi_ctrl = { -	.name	= "hsi_controller", -}; - -static struct device_type hsi_cl = { -	.name	= "hsi_client", -}; - -static struct device_type hsi_port = { -	.name	= "hsi_port", -}; -  static ssize_t modalias_show(struct device *dev,  			struct device_attribute *a __maybe_unused, char *buf)  { @@ -54,8 +41,7 @@ static struct device_attribute hsi_bus_dev_attrs[] = {  static int hsi_bus_uevent(struct device *dev, struct kobj_uevent_env *env)  { -	if (dev->type == &hsi_cl) -		add_uevent_var(env, "MODALIAS=hsi:%s", dev_name(dev)); +	add_uevent_var(env, "MODALIAS=hsi:%s", dev_name(dev));  	return 0;  } @@ -80,12 +66,10 @@ static void hsi_client_release(struct device *dev)  static void hsi_new_client(struct hsi_port *port, struct hsi_board_info *info)  {  	struct hsi_client *cl; -	unsigned long flags;  	cl = kzalloc(sizeof(*cl), GFP_KERNEL);  	if (!cl)  		return; -	cl->device.type = &hsi_cl;  	cl->tx_cfg = info->tx_cfg;  	cl->rx_cfg = info->rx_cfg;  	cl->device.bus = &hsi_bus_type; @@ -93,14 +77,11 @@ static void hsi_new_client(struct hsi_port *port, struct hsi_board_info *info)  	cl->device.release = hsi_client_release;  	dev_set_name(&cl->device, info->name);  	cl->device.platform_data = info->platform_data; -	spin_lock_irqsave(&port->clock, flags); -	list_add_tail(&cl->link, &port->clients); -	spin_unlock_irqrestore(&port->clock, flags);  	if (info->archdata)  		cl->device.archdata = *info->archdata;  	if (device_register(&cl->device) < 0) {  		pr_err("hsi: failed to register client: %s\n", info->name); -		kfree(cl); +		put_device(&cl->device);  	}  } @@ -120,13 +101,6 @@ static void hsi_scan_board_info(struct hsi_controller *hsi)  static int hsi_remove_client(struct device *dev, void *data __maybe_unused)  { -	struct hsi_client *cl = to_hsi_client(dev); -	struct hsi_port *port = to_hsi_port(dev->parent); -	unsigned long flags; - -	spin_lock_irqsave(&port->clock, flags); -	list_del(&cl->link); -	spin_unlock_irqrestore(&port->clock, flags);  	device_unregister(dev);  	return 0; @@ -140,12 +114,17 @@ static int hsi_remove_port(struct device *dev, void *data __maybe_unused)  	return 0;  } -static void hsi_controller_release(struct device *dev __maybe_unused) +static void hsi_controller_release(struct device *dev)  { +	struct hsi_controller *hsi = to_hsi_controller(dev); + +	kfree(hsi->port); +	kfree(hsi);  } -static void hsi_port_release(struct device *dev __maybe_unused) +static void hsi_port_release(struct device *dev)  { +	kfree(to_hsi_port(dev));  }  /** @@ -170,20 +149,12 @@ int hsi_register_controller(struct hsi_controller *hsi)  	unsigned int i;  	int err; -	hsi->device.type = &hsi_ctrl; -	hsi->device.bus = &hsi_bus_type; -	hsi->device.release = hsi_controller_release; -	err = device_register(&hsi->device); +	err = device_add(&hsi->device);  	if (err < 0)  		return err;  	for (i = 0; i < hsi->num_ports; i++) { -		hsi->port[i].device.parent = &hsi->device; -		hsi->port[i].device.bus = &hsi_bus_type; -		hsi->port[i].device.release = hsi_port_release; -		hsi->port[i].device.type = &hsi_port; -		INIT_LIST_HEAD(&hsi->port[i].clients); -		spin_lock_init(&hsi->port[i].clock); -		err = device_register(&hsi->port[i].device); +		hsi->port[i]->device.parent = &hsi->device; +		err = device_add(&hsi->port[i]->device);  		if (err < 0)  			goto out;  	} @@ -192,7 +163,9 @@ int hsi_register_controller(struct hsi_controller *hsi)  	return 0;  out: -	hsi_unregister_controller(hsi); +	while (i-- > 0) +		device_del(&hsi->port[i]->device); +	device_del(&hsi->device);  	return err;  } @@ -223,6 +196,29 @@ static inline int hsi_dummy_cl(struct hsi_client *cl __maybe_unused)  }  /** + * hsi_put_controller - Free an HSI controller + * + * @hsi: Pointer to the HSI controller to freed + * + * HSI controller drivers should only use this function if they need + * to free their allocated hsi_controller structures before a successful + * call to hsi_register_controller. Other use is not allowed. + */ +void hsi_put_controller(struct hsi_controller *hsi) +{ +	unsigned int i; + +	if (!hsi) +		return; + +	for (i = 0; i < hsi->num_ports; i++) +		if (hsi->port && hsi->port[i]) +			put_device(&hsi->port[i]->device); +	put_device(&hsi->device); +} +EXPORT_SYMBOL_GPL(hsi_put_controller); + +/**   * hsi_alloc_controller - Allocate an HSI controller and its ports   * @n_ports: Number of ports on the HSI controller   * @flags: Kernel allocation flags @@ -232,55 +228,52 @@ static inline int hsi_dummy_cl(struct hsi_client *cl __maybe_unused)  struct hsi_controller *hsi_alloc_controller(unsigned int n_ports, gfp_t flags)  {  	struct hsi_controller	*hsi; -	struct hsi_port		*port; +	struct hsi_port		**port;  	unsigned int		i;  	if (!n_ports)  		return NULL; -	port = kzalloc(sizeof(*port)*n_ports, flags); -	if (!port) -		return NULL;  	hsi = kzalloc(sizeof(*hsi), flags);  	if (!hsi) -		goto out; -	for (i = 0; i < n_ports; i++) { -		dev_set_name(&port[i].device, "port%d", i); -		port[i].num = i; -		port[i].async = hsi_dummy_msg; -		port[i].setup = hsi_dummy_cl; -		port[i].flush = hsi_dummy_cl; -		port[i].start_tx = hsi_dummy_cl; -		port[i].stop_tx = hsi_dummy_cl; -		port[i].release = hsi_dummy_cl; -		mutex_init(&port[i].lock); +		return NULL; +	port = kzalloc(sizeof(*port)*n_ports, flags); +	if (!port) { +		kfree(hsi); +		return NULL;  	}  	hsi->num_ports = n_ports;  	hsi->port = port; +	hsi->device.release = hsi_controller_release; +	device_initialize(&hsi->device); + +	for (i = 0; i < n_ports; i++) { +		port[i] = kzalloc(sizeof(**port), flags); +		if (port[i] == NULL) +			goto out; +		port[i]->num = i; +		port[i]->async = hsi_dummy_msg; +		port[i]->setup = hsi_dummy_cl; +		port[i]->flush = hsi_dummy_cl; +		port[i]->start_tx = hsi_dummy_cl; +		port[i]->stop_tx = hsi_dummy_cl; +		port[i]->release = hsi_dummy_cl; +		mutex_init(&port[i]->lock); +		ATOMIC_INIT_NOTIFIER_HEAD(&port[i]->n_head); +		dev_set_name(&port[i]->device, "port%d", i); +		hsi->port[i]->device.release = hsi_port_release; +		device_initialize(&hsi->port[i]->device); +	}  	return hsi;  out: -	kfree(port); +	hsi_put_controller(hsi);  	return NULL;  }  EXPORT_SYMBOL_GPL(hsi_alloc_controller);  /** - * hsi_free_controller - Free an HSI controller - * @hsi: Pointer to HSI controller - */ -void hsi_free_controller(struct hsi_controller *hsi) -{ -	if (!hsi) -		return; - -	kfree(hsi->port); -	kfree(hsi); -} -EXPORT_SYMBOL_GPL(hsi_free_controller); - -/**   * hsi_free_msg - Free an HSI message   * @msg: Pointer to the HSI message   * @@ -414,37 +407,67 @@ void hsi_release_port(struct hsi_client *cl)  }  EXPORT_SYMBOL_GPL(hsi_release_port); -static int hsi_start_rx(struct hsi_client *cl, void *data __maybe_unused) +static int hsi_event_notifier_call(struct notifier_block *nb, +				unsigned long event, void *data __maybe_unused)  { -	if (cl->hsi_start_rx) -		(*cl->hsi_start_rx)(cl); +	struct hsi_client *cl = container_of(nb, struct hsi_client, nb); + +	(*cl->ehandler)(cl, event);  	return 0;  } -static int hsi_stop_rx(struct hsi_client *cl, void *data __maybe_unused) +/** + * hsi_register_port_event - Register a client to receive port events + * @cl: HSI client that wants to receive port events + * @cb: Event handler callback + * + * Clients should register a callback to be able to receive + * events from the ports. Registration should happen after + * claiming the port. + * The handler can be called in interrupt context. + * + * Returns -errno on error, or 0 on success. + */ +int hsi_register_port_event(struct hsi_client *cl, +			void (*handler)(struct hsi_client *, unsigned long))  { -	if (cl->hsi_stop_rx) -		(*cl->hsi_stop_rx)(cl); +	struct hsi_port *port = hsi_get_port(cl); -	return 0; +	if (!handler || cl->ehandler) +		return -EINVAL; +	if (!hsi_port_claimed(cl)) +		return -EACCES; +	cl->ehandler = handler; +	cl->nb.notifier_call = hsi_event_notifier_call; + +	return atomic_notifier_chain_register(&port->n_head, &cl->nb);  } +EXPORT_SYMBOL_GPL(hsi_register_port_event); -static int hsi_port_for_each_client(struct hsi_port *port, void *data, -				int (*fn)(struct hsi_client *cl, void *data)) +/** + * hsi_unregister_port_event - Stop receiving port events for a client + * @cl: HSI client that wants to stop receiving port events + * + * Clients should call this function before releasing their associated + * port. + * + * Returns -errno on error, or 0 on success. + */ +int hsi_unregister_port_event(struct hsi_client *cl)  { -	struct hsi_client *cl; +	struct hsi_port *port = hsi_get_port(cl); +	int err; -	spin_lock(&port->clock); -	list_for_each_entry(cl, &port->clients, link) { -		spin_unlock(&port->clock); -		(*fn)(cl, data); -		spin_lock(&port->clock); -	} -	spin_unlock(&port->clock); +	WARN_ON(!hsi_port_claimed(cl)); -	return 0; +	err = atomic_notifier_chain_unregister(&port->n_head, &cl->nb); +	if (!err) +		cl->ehandler = NULL; + +	return err;  } +EXPORT_SYMBOL_GPL(hsi_unregister_port_event);  /**   * hsi_event -Notifies clients about port events @@ -458,22 +481,12 @@ static int hsi_port_for_each_client(struct hsi_port *port, void *data,   * Events:   * HSI_EVENT_START_RX - Incoming wake line high   * HSI_EVENT_STOP_RX - Incoming wake line down + * + * Returns -errno on error, or 0 on success.   */ -void hsi_event(struct hsi_port *port, unsigned int event) +int hsi_event(struct hsi_port *port, unsigned long event)  { -	int (*fn)(struct hsi_client *cl, void *data); - -	switch (event) { -	case HSI_EVENT_START_RX: -		fn = hsi_start_rx; -		break; -	case HSI_EVENT_STOP_RX: -		fn = hsi_stop_rx; -		break; -	default: -		return; -	} -	hsi_port_for_each_client(port, NULL, fn); +	return atomic_notifier_call_chain(&port->n_head, event, NULL);  }  EXPORT_SYMBOL_GPL(hsi_event); diff --git a/drivers/hwmon/ad7314.c b/drivers/hwmon/ad7314.c index ce43642ef03..f85ce70d967 100644 --- a/drivers/hwmon/ad7314.c +++ b/drivers/hwmon/ad7314.c @@ -47,7 +47,7 @@ struct ad7314_data {  	u16 rx ____cacheline_aligned;  }; -static int ad7314_spi_read(struct ad7314_data *chip, s16 *data) +static int ad7314_spi_read(struct ad7314_data *chip)  {  	int ret; @@ -57,9 +57,7 @@ static int ad7314_spi_read(struct ad7314_data *chip, s16 *data)  		return ret;  	} -	*data = be16_to_cpu(chip->rx); - -	return ret; +	return be16_to_cpu(chip->rx);  }  static ssize_t ad7314_show_temperature(struct device *dev, @@ -70,12 +68,12 @@ static ssize_t ad7314_show_temperature(struct device *dev,  	s16 data;  	int ret; -	ret = ad7314_spi_read(chip, &data); +	ret = ad7314_spi_read(chip);  	if (ret < 0)  		return ret;  	switch (spi_get_device_id(chip->spi_dev)->driver_data) {  	case ad7314: -		data = (data & AD7314_TEMP_MASK) >> AD7314_TEMP_OFFSET; +		data = (ret & AD7314_TEMP_MASK) >> AD7314_TEMP_OFFSET;  		data = (data << 6) >> 6;  		return sprintf(buf, "%d\n", 250 * data); @@ -86,7 +84,7 @@ static ssize_t ad7314_show_temperature(struct device *dev,  		 * with a sign bit - which is a 14 bit 2's complement  		 * register.  1lsb - 31.25 milli degrees centigrade  		 */ -		data &= ADT7301_TEMP_MASK; +		data = ret & ADT7301_TEMP_MASK;  		data = (data << 2) >> 2;  		return sprintf(buf, "%d\n", diff --git a/drivers/hwmon/ads1015.c b/drivers/hwmon/ads1015.c index 7765e4f74ec..1958f03efd7 100644 --- a/drivers/hwmon/ads1015.c +++ b/drivers/hwmon/ads1015.c @@ -59,14 +59,11 @@ struct ads1015_data {  	struct ads1015_channel_data channel_data[ADS1015_CHANNELS];  }; -static int ads1015_read_value(struct i2c_client *client, unsigned int channel, -			      int *value) +static int ads1015_read_adc(struct i2c_client *client, unsigned int channel)  {  	u16 config; -	s16 conversion;  	struct ads1015_data *data = i2c_get_clientdata(client);  	unsigned int pga = data->channel_data[channel].pga; -	int fullscale;  	unsigned int data_rate = data->channel_data[channel].data_rate;  	unsigned int conversion_time_ms;  	int res; @@ -78,7 +75,6 @@ static int ads1015_read_value(struct i2c_client *client, unsigned int channel,  	if (res < 0)  		goto err_unlock;  	config = res; -	fullscale = fullscale_table[pga];  	conversion_time_ms = DIV_ROUND_UP(1000, data_rate_table[data_rate]);  	/* setup and start single conversion */ @@ -105,33 +101,36 @@ static int ads1015_read_value(struct i2c_client *client, unsigned int channel,  	}  	res = i2c_smbus_read_word_swapped(client, ADS1015_CONVERSION); -	if (res < 0) -		goto err_unlock; -	conversion = res; - -	mutex_unlock(&data->update_lock); - -	*value = DIV_ROUND_CLOSEST(conversion * fullscale, 0x7ff0); - -	return 0;  err_unlock:  	mutex_unlock(&data->update_lock);  	return res;  } +static int ads1015_reg_to_mv(struct i2c_client *client, unsigned int channel, +			     s16 reg) +{ +	struct ads1015_data *data = i2c_get_clientdata(client); +	unsigned int pga = data->channel_data[channel].pga; +	int fullscale = fullscale_table[pga]; + +	return DIV_ROUND_CLOSEST(reg * fullscale, 0x7ff0); +} +  /* sysfs callback function */  static ssize_t show_in(struct device *dev, struct device_attribute *da,  	char *buf)  {  	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);  	struct i2c_client *client = to_i2c_client(dev); -	int in;  	int res; +	int index = attr->index; -	res = ads1015_read_value(client, attr->index, &in); +	res = ads1015_read_adc(client, index); +	if (res < 0) +		return res; -	return (res < 0) ? res : sprintf(buf, "%d\n", in); +	return sprintf(buf, "%d\n", ads1015_reg_to_mv(client, index, res));  }  static const struct sensor_device_attribute ads1015_in[] = { diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c index 0d3141fbbc2..b9d512331ed 100644 --- a/drivers/hwmon/coretemp.c +++ b/drivers/hwmon/coretemp.c @@ -52,7 +52,7 @@ module_param_named(tjmax, force_tjmax, int, 0444);  MODULE_PARM_DESC(tjmax, "TjMax value in degrees Celsius");  #define BASE_SYSFS_ATTR_NO	2	/* Sysfs Base attr no for coretemp */ -#define NUM_REAL_CORES		16	/* Number of Real cores per cpu */ +#define NUM_REAL_CORES		32	/* Number of Real cores per cpu */  #define CORETEMP_NAME_LENGTH	17	/* String Length of attrs */  #define MAX_CORE_ATTRS		4	/* Maximum no of basic attrs */  #define TOTAL_ATTRS		(MAX_CORE_ATTRS + 1) @@ -709,6 +709,10 @@ static void __cpuinit put_core_offline(unsigned int cpu)  	indx = TO_ATTR_NO(cpu); +	/* The core id is too big, just return */ +	if (indx > MAX_CORE_DATA - 1) +		return; +  	if (pdata->core_data[indx] && pdata->core_data[indx]->cpu == cpu)  		coretemp_remove_core(pdata, &pdev->dev, indx); diff --git a/drivers/hwmon/fam15h_power.c b/drivers/hwmon/fam15h_power.c index b7494af1e4a..e8e18cab1fb 100644 --- a/drivers/hwmon/fam15h_power.c +++ b/drivers/hwmon/fam15h_power.c @@ -122,6 +122,41 @@ static bool __devinit fam15h_power_is_internal_node0(struct pci_dev *f4)  	return true;  } +/* + * Newer BKDG versions have an updated recommendation on how to properly + * initialize the running average range (was: 0xE, now: 0x9). This avoids + * counter saturations resulting in bogus power readings. + * We correct this value ourselves to cope with older BIOSes. + */ +static DEFINE_PCI_DEVICE_TABLE(affected_device) = { +	{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_15H_NB_F4) }, +	{ 0 } +}; + +static void __devinit tweak_runavg_range(struct pci_dev *pdev) +{ +	u32 val; + +	/* +	 * let this quirk apply only to the current version of the +	 * northbridge, since future versions may change the behavior +	 */ +	if (!pci_match_id(affected_device, pdev)) +		return; + +	pci_bus_read_config_dword(pdev->bus, +		PCI_DEVFN(PCI_SLOT(pdev->devfn), 5), +		REG_TDP_RUNNING_AVERAGE, &val); +	if ((val & 0xf) != 0xe) +		return; + +	val &= ~0xf; +	val |=  0x9; +	pci_bus_write_config_dword(pdev->bus, +		PCI_DEVFN(PCI_SLOT(pdev->devfn), 5), +		REG_TDP_RUNNING_AVERAGE, val); +} +  static void __devinit fam15h_power_init_data(struct pci_dev *f4,  					     struct fam15h_power_data *data)  { @@ -155,6 +190,13 @@ static int __devinit fam15h_power_probe(struct pci_dev *pdev,  	struct device *dev;  	int err; +	/* +	 * though we ignore every other northbridge, we still have to +	 * do the tweaking on _each_ node in MCM processors as the counters +	 * are working hand-in-hand +	 */ +	tweak_runavg_range(pdev); +  	if (!fam15h_power_is_internal_node0(pdev)) {  		err = -ENODEV;  		goto exit; diff --git a/drivers/i2c/busses/i2c-eg20t.c b/drivers/i2c/busses/i2c-eg20t.c index f086131cb1c..c811289b61e 100644 --- a/drivers/i2c/busses/i2c-eg20t.c +++ b/drivers/i2c/busses/i2c-eg20t.c @@ -324,7 +324,7 @@ static s32 pch_i2c_wait_for_xfer_complete(struct i2c_algo_pch_data *adap)  {  	long ret;  	ret = wait_event_timeout(pch_event, -			(adap->pch_event_flag != 0), msecs_to_jiffies(50)); +			(adap->pch_event_flag != 0), msecs_to_jiffies(1000));  	if (ret == 0) {  		pch_err(adap, "timeout: %x\n", adap->pch_event_flag); @@ -1063,6 +1063,6 @@ module_exit(pch_pci_exit);  MODULE_DESCRIPTION("Intel EG20T PCH/LAPIS Semico ML7213/ML7223/ML7831 IOH I2C");  MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Tomoya MORINAGA. <tomoya-linux@dsn.lapis-semi.com>"); +MODULE_AUTHOR("Tomoya MORINAGA. <tomoya.rohm@gmail.com>");  module_param(pch_i2c_speed, int, (S_IRUSR | S_IWUSR));  module_param(pch_clk, int, (S_IRUSR | S_IWUSR)); diff --git a/drivers/i2c/busses/i2c-mxs.c b/drivers/i2c/busses/i2c-mxs.c index 3d471d56bf1..76b8af44f63 100644 --- a/drivers/i2c/busses/i2c-mxs.c +++ b/drivers/i2c/busses/i2c-mxs.c @@ -227,6 +227,7 @@ static int mxs_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg,  		return -EINVAL;  	init_completion(&i2c->cmd_complete); +	i2c->cmd_err = 0;  	flags = stop ? MXS_I2C_CTRL0_POST_SEND_STOP : 0; @@ -252,6 +253,9 @@ static int mxs_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg,  	if (i2c->cmd_err == -ENXIO)  		mxs_i2c_reset(i2c); +	else +		writel(MXS_I2C_QUEUECTRL_QUEUE_RUN, +				i2c->regs + MXS_I2C_QUEUECTRL_CLR);  	dev_dbg(i2c->dev, "Done with err=%d\n", i2c->cmd_err); @@ -299,8 +303,6 @@ static irqreturn_t mxs_i2c_isr(int this_irq, void *dev_id)  		    MXS_I2C_CTRL1_SLAVE_STOP_IRQ | MXS_I2C_CTRL1_SLAVE_IRQ))  		/* MXS_I2C_CTRL1_OVERSIZE_XFER_TERM_IRQ is only for slaves */  		i2c->cmd_err = -EIO; -	else -		i2c->cmd_err = 0;  	is_last_cmd = (readl(i2c->regs + MXS_I2C_QUEUESTAT) &  		MXS_I2C_QUEUESTAT_WRITE_QUEUE_CNT_MASK) == 0; @@ -384,8 +386,6 @@ static int __devexit mxs_i2c_remove(struct platform_device *pdev)  	if (ret)  		return -EBUSY; -	writel(MXS_I2C_QUEUECTRL_QUEUE_RUN, -			i2c->regs + MXS_I2C_QUEUECTRL_CLR);  	writel(MXS_I2C_CTRL0_SFTRST, i2c->regs + MXS_I2C_CTRL0_SET);  	platform_set_drvdata(pdev, NULL); diff --git a/drivers/i2c/busses/i2c-pnx.c b/drivers/i2c/busses/i2c-pnx.c index 04be9f82e14..eb8ad538c79 100644 --- a/drivers/i2c/busses/i2c-pnx.c +++ b/drivers/i2c/busses/i2c-pnx.c @@ -546,8 +546,7 @@ static int i2c_pnx_controller_suspend(struct platform_device *pdev,  {  	struct i2c_pnx_algo_data *alg_data = platform_get_drvdata(pdev); -	/* FIXME: shouldn't this be clk_disable? */ -	clk_enable(alg_data->clk); +	clk_disable(alg_data->clk);  	return 0;  } diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c index e978635e60f..55e5ea62cce 100644 --- a/drivers/i2c/busses/i2c-tegra.c +++ b/drivers/i2c/busses/i2c-tegra.c @@ -516,6 +516,14 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,  	if (likely(i2c_dev->msg_err == I2C_ERR_NONE))  		return 0; +	/* +	 * NACK interrupt is generated before the I2C controller generates the +	 * STOP condition on the bus. So wait for 2 clock periods before resetting +	 * the controller so that STOP condition has been delivered properly. +	 */ +	if (i2c_dev->msg_err == I2C_ERR_NO_ACK) +		udelay(DIV_ROUND_UP(2 * 1000000, i2c_dev->bus_clk_rate)); +  	tegra_i2c_init(i2c_dev);  	if (i2c_dev->msg_err == I2C_ERR_NO_ACK) {  		if (msg->flags & I2C_M_IGNORE_NAK) diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c index 426bb7617ec..b0d0bc8a6fb 100644 --- a/drivers/infiniband/core/mad.c +++ b/drivers/infiniband/core/mad.c @@ -1854,6 +1854,8 @@ static bool generate_unmatched_resp(struct ib_mad_private *recv,  		response->mad.mad.mad_hdr.method = IB_MGMT_METHOD_GET_RESP;  		response->mad.mad.mad_hdr.status =  			cpu_to_be16(IB_MGMT_MAD_STATUS_UNSUPPORTED_METHOD_ATTRIB); +		if (recv->mad.mad.mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE) +			response->mad.mad.mad_hdr.status |= IB_SMP_DIRECTION;  		return true;  	} else { @@ -1869,6 +1871,7 @@ static void ib_mad_recv_done_handler(struct ib_mad_port_private *port_priv,  	struct ib_mad_list_head *mad_list;  	struct ib_mad_agent_private *mad_agent;  	int port_num; +	int ret = IB_MAD_RESULT_SUCCESS;  	mad_list = (struct ib_mad_list_head *)(unsigned long)wc->wr_id;  	qp_info = mad_list->mad_queue->qp_info; @@ -1952,8 +1955,6 @@ static void ib_mad_recv_done_handler(struct ib_mad_port_private *port_priv,  local:  	/* Give driver "right of first refusal" on incoming MAD */  	if (port_priv->device->process_mad) { -		int ret; -  		ret = port_priv->device->process_mad(port_priv->device, 0,  						     port_priv->port_num,  						     wc, &recv->grh, @@ -1981,7 +1982,8 @@ local:  		 * or via recv_handler in ib_mad_complete_recv()  		 */  		recv = NULL; -	} else if (generate_unmatched_resp(recv, response)) { +	} else if ((ret & IB_MAD_RESULT_SUCCESS) && +		   generate_unmatched_resp(recv, response)) {  		agent_send_response(&response->mad.mad, &recv->grh, wc,  				    port_priv->device, port_num, qp_info->qp->qp_num);  	} diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c index 669673e8143..b948b6dd5d5 100644 --- a/drivers/infiniband/hw/mlx4/main.c +++ b/drivers/infiniband/hw/mlx4/main.c @@ -247,7 +247,7 @@ static int ib_link_query_port(struct ib_device *ibdev, u8 port,  		err = mlx4_MAD_IFC(to_mdev(ibdev), 1, 1, port,  				   NULL, NULL, in_mad, out_mad);  		if (err) -			return err; +			goto out;  		/* Checking LinkSpeedActive for FDR-10 */  		if (out_mad->data[15] & 0x1) diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index 2d787796bf5..7faf4a7fcaa 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig @@ -380,8 +380,7 @@ config INPUT_TWL4030_VIBRA  config INPUT_TWL6040_VIBRA  	tristate "Support for TWL6040 Vibrator" -	depends on TWL4030_CORE -	select TWL6040_CORE +	depends on TWL6040_CORE  	select INPUT_FF_MEMLESS  	help  	  This option enables support for TWL6040 Vibrator Driver. diff --git a/drivers/input/misc/twl6040-vibra.c b/drivers/input/misc/twl6040-vibra.c index 45874fed523..14e94f56cb7 100644 --- a/drivers/input/misc/twl6040-vibra.c +++ b/drivers/input/misc/twl6040-vibra.c @@ -28,7 +28,7 @@  #include <linux/module.h>  #include <linux/platform_device.h>  #include <linux/workqueue.h> -#include <linux/i2c/twl.h> +#include <linux/input.h>  #include <linux/mfd/twl6040.h>  #include <linux/slab.h>  #include <linux/delay.h> @@ -257,7 +257,7 @@ static SIMPLE_DEV_PM_OPS(twl6040_vibra_pm_ops, twl6040_vibra_suspend, NULL);  static int __devinit twl6040_vibra_probe(struct platform_device *pdev)  { -	struct twl4030_vibra_data *pdata = pdev->dev.platform_data; +	struct twl6040_vibra_data *pdata = pdev->dev.platform_data;  	struct vibra_info *info;  	int ret; diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index 8081a0a5d60..a4b14a41cbf 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c @@ -274,7 +274,8 @@ static int synaptics_set_advanced_gesture_mode(struct psmouse *psmouse)  	static unsigned char param = 0xc8;  	struct synaptics_data *priv = psmouse->private; -	if (!SYN_CAP_ADV_GESTURE(priv->ext_cap_0c)) +	if (!(SYN_CAP_ADV_GESTURE(priv->ext_cap_0c) || +	      SYN_CAP_IMAGE_SENSOR(priv->ext_cap_0c)))  		return 0;  	if (psmouse_sliced_command(psmouse, SYN_QUE_MODEL)) diff --git a/drivers/leds/leds-atmel-pwm.c b/drivers/leds/leds-atmel-pwm.c index 800243b6037..64ad702a2ec 100644 --- a/drivers/leds/leds-atmel-pwm.c +++ b/drivers/leds/leds-atmel-pwm.c @@ -35,7 +35,7 @@ static void pwmled_brightness(struct led_classdev *cdev, enum led_brightness b)   * NOTE:  we reuse the platform_data structure of GPIO leds,   * but repurpose its "gpio" number as a PWM channel number.   */ -static int __init pwmled_probe(struct platform_device *pdev) +static int __devinit pwmled_probe(struct platform_device *pdev)  {  	const struct gpio_led_platform_data	*pdata;  	struct pwmled				*leds; diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index 97e73e555d1..17e2b472e16 100644 --- a/drivers/md/bitmap.c +++ b/drivers/md/bitmap.c @@ -1727,8 +1727,7 @@ int bitmap_create(struct mddev *mddev)  	bitmap->chunkshift = (ffz(~mddev->bitmap_info.chunksize)  			      - BITMAP_BLOCK_SHIFT); -	/* now that chunksize and chunkshift are set, we can use these macros */ -	chunks = (blocks + bitmap->chunkshift - 1) >> +	chunks = (blocks + (1 << bitmap->chunkshift) - 1) >>  			bitmap->chunkshift;  	pages = (chunks + PAGE_COUNTER_RATIO - 1) / PAGE_COUNTER_RATIO; diff --git a/drivers/md/bitmap.h b/drivers/md/bitmap.h index 55ca5aec84e..b44b0aba2d4 100644 --- a/drivers/md/bitmap.h +++ b/drivers/md/bitmap.h @@ -101,9 +101,6 @@ typedef __u16 bitmap_counter_t;  #define BITMAP_BLOCK_SHIFT 9 -/* how many blocks per chunk? (this is variable) */ -#define CHUNK_BLOCK_RATIO(bitmap) ((bitmap)->mddev->bitmap_info.chunksize >> BITMAP_BLOCK_SHIFT) -  #endif  /* diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c index b0ba52459ed..68965e66324 100644 --- a/drivers/md/dm-raid.c +++ b/drivers/md/dm-raid.c @@ -859,7 +859,7 @@ 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, *freshest; +	struct md_rdev *rdev, *tmp, *freshest;  	struct mddev *mddev = &rs->md;  	switch (rs->raid_type->level) { @@ -877,7 +877,7 @@ static int analyse_superblocks(struct dm_target *ti, struct raid_set *rs)  	}  	freshest = NULL; -	rdev_for_each(rdev, mddev) { +	rdev_for_each_safe(rdev, tmp, mddev) {  		if (!rdev->meta_bdev)  			continue; diff --git a/drivers/md/md.c b/drivers/md/md.c index b572e1e386c..477eb2e180c 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -7560,14 +7560,14 @@ void md_check_recovery(struct mddev *mddev)  		 * any transients in the value of "sync_action".  		 */  		set_bit(MD_RECOVERY_RUNNING, &mddev->recovery); -		clear_bit(MD_RECOVERY_NEEDED, &mddev->recovery);  		/* Clear some bits that don't mean anything, but  		 * might be left set  		 */  		clear_bit(MD_RECOVERY_INTR, &mddev->recovery);  		clear_bit(MD_RECOVERY_DONE, &mddev->recovery); -		if (test_bit(MD_RECOVERY_FROZEN, &mddev->recovery)) +		if (!test_and_clear_bit(MD_RECOVERY_NEEDED, &mddev->recovery) || +		    test_bit(MD_RECOVERY_FROZEN, &mddev->recovery))  			goto unlock;  		/* no recovery is running.  		 * remove any failed drives, then @@ -8140,7 +8140,8 @@ static int md_notify_reboot(struct notifier_block *this,  	for_each_mddev(mddev, tmp) {  		if (mddev_trylock(mddev)) { -			__md_stop_writes(mddev); +			if (mddev->pers) +				__md_stop_writes(mddev);  			mddev->safemode = 2;  			mddev_unlock(mddev);  		} diff --git a/drivers/media/common/tuners/xc5000.c b/drivers/media/common/tuners/xc5000.c index 7f98984e4fa..eab2ea42420 100644 --- a/drivers/media/common/tuners/xc5000.c +++ b/drivers/media/common/tuners/xc5000.c @@ -54,6 +54,7 @@ struct xc5000_priv {  	struct list_head hybrid_tuner_instance_list;  	u32 if_khz; +	u32 xtal_khz;  	u32 freq_hz;  	u32 bandwidth;  	u8  video_standard; @@ -214,9 +215,9 @@ static const struct xc5000_fw_cfg xc5000a_1_6_114 = {  	.size = 12401,  }; -static const struct xc5000_fw_cfg xc5000c_41_024_5_31875 = { -	.name = "dvb-fe-xc5000c-41.024.5-31875.fw", -	.size = 16503, +static const struct xc5000_fw_cfg xc5000c_41_024_5 = { +	.name = "dvb-fe-xc5000c-41.024.5.fw", +	.size = 16497,  };  static inline const struct xc5000_fw_cfg *xc5000_assign_firmware(int chip_id) @@ -226,7 +227,7 @@ static inline const struct xc5000_fw_cfg *xc5000_assign_firmware(int chip_id)  	case XC5000A:  		return &xc5000a_1_6_114;  	case XC5000C: -		return &xc5000c_41_024_5_31875; +		return &xc5000c_41_024_5;  	}  } @@ -572,6 +573,31 @@ static int xc_tune_channel(struct xc5000_priv *priv, u32 freq_hz, int mode)  	return found;  } +static int xc_set_xtal(struct dvb_frontend *fe) +{ +	struct xc5000_priv *priv = fe->tuner_priv; +	int ret = XC_RESULT_SUCCESS; + +	switch (priv->chip_id) { +	default: +	case XC5000A: +		/* 32.000 MHz xtal is default */ +		break; +	case XC5000C: +		switch (priv->xtal_khz) { +		default: +		case 32000: +			/* 32.000 MHz xtal is default */ +			break; +		case 31875: +			/* 31.875 MHz xtal configuration */ +			ret = xc_write_reg(priv, 0x000f, 0x8081); +			break; +		} +		break; +	} +	return ret; +}  static int xc5000_fwupload(struct dvb_frontend *fe)  { @@ -603,6 +629,8 @@ static int xc5000_fwupload(struct dvb_frontend *fe)  	} else {  		printk(KERN_INFO "xc5000: firmware uploading...\n");  		ret = xc_load_i2c_sequence(fe,  fw->data); +		if (XC_RESULT_SUCCESS == ret) +			ret = xc_set_xtal(fe);  		printk(KERN_INFO "xc5000: firmware upload complete...\n");  	} @@ -1164,6 +1192,9 @@ struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe,  		priv->if_khz = cfg->if_khz;  	} +	if (priv->xtal_khz == 0) +		priv->xtal_khz = cfg->xtal_khz; +  	if (priv->radio_input == 0)  		priv->radio_input = cfg->radio_input; diff --git a/drivers/media/common/tuners/xc5000.h b/drivers/media/common/tuners/xc5000.h index 3396f8e02b4..39a73bf0140 100644 --- a/drivers/media/common/tuners/xc5000.h +++ b/drivers/media/common/tuners/xc5000.h @@ -34,6 +34,7 @@ struct xc5000_config {  	u8   i2c_address;  	u32  if_khz;  	u8   radio_input; +	u32  xtal_khz;  	int chip_id;  }; diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c index 39696c6a4ed..0f64d718265 100644 --- a/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -1446,6 +1446,28 @@ static int set_delivery_system(struct dvb_frontend *fe, u32 desired_system)  				__func__);  			return -EINVAL;  		} +		/* +		 * Get a delivery system that is compatible with DVBv3 +		 * NOTE: in order for this to work with softwares like Kaffeine that +		 *	uses a DVBv5 call for DVB-S2 and a DVBv3 call to go back to +		 *	DVB-S, drivers that support both should put the SYS_DVBS entry +		 *	before the SYS_DVBS2, otherwise it won't switch back to DVB-S. +		 *	The real fix is that userspace applications should not use DVBv3 +		 *	and not trust on calling FE_SET_FRONTEND to switch the delivery +		 *	system. +		 */ +		ncaps = 0; +		while (fe->ops.delsys[ncaps] && ncaps < MAX_DELSYS) { +			if (fe->ops.delsys[ncaps] == desired_system) { +				delsys = desired_system; +				break; +			} +			ncaps++; +		} +		if (delsys == SYS_UNDEFINED) { +			dprintk("%s() Couldn't find a delivery system that matches %d\n", +				__func__, desired_system); +		}  	} else {  		/*  		 * This is a DVBv5 call. So, it likely knows the supported @@ -1494,9 +1516,10 @@ static int set_delivery_system(struct dvb_frontend *fe, u32 desired_system)  				__func__);  			return -EINVAL;  		} -		c->delivery_system = delsys;  	} +	c->delivery_system = delsys; +  	/*  	 * The DVBv3 or DVBv5 call is requesting a different system. So,  	 * emulation is needed. diff --git a/drivers/media/dvb/frontends/drxk_hard.c b/drivers/media/dvb/frontends/drxk_hard.c index 36d11756492..a414b1f2b6a 100644 --- a/drivers/media/dvb/frontends/drxk_hard.c +++ b/drivers/media/dvb/frontends/drxk_hard.c @@ -1520,8 +1520,10 @@ static int scu_command(struct drxk_state *state,  	dprintk(1, "\n");  	if ((cmd == 0) || ((parameterLen > 0) && (parameter == NULL)) || -	    ((resultLen > 0) && (result == NULL))) -		goto error; +	    ((resultLen > 0) && (result == NULL))) { +		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); +		return status; +	}  	mutex_lock(&state->mutex); diff --git a/drivers/media/rc/winbond-cir.c b/drivers/media/rc/winbond-cir.c index b09c5fae489..af526586fa2 100644 --- a/drivers/media/rc/winbond-cir.c +++ b/drivers/media/rc/winbond-cir.c @@ -1046,6 +1046,7 @@ wbcir_probe(struct pnp_dev *device, const struct pnp_device_id *dev_id)  		goto exit_unregister_led;  	} +	data->dev->driver_type = RC_DRIVER_IR_RAW;  	data->dev->driver_name = WBCIR_NAME;  	data->dev->input_name = WBCIR_NAME;  	data->dev->input_phys = "wbcir/cir0"; diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index f2479c5c0eb..ce1e7ba940f 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig @@ -492,7 +492,7 @@ config VIDEO_VS6624  config VIDEO_MT9M032  	tristate "MT9M032 camera sensor support" -	depends on I2C && VIDEO_V4L2 +	depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API  	select VIDEO_APTINA_PLL  	---help---  	  This driver supports MT9M032 camera sensors from Aptina, monochrome diff --git a/drivers/media/video/mt9m032.c b/drivers/media/video/mt9m032.c index 7636672c354..645973c5feb 100644 --- a/drivers/media/video/mt9m032.c +++ b/drivers/media/video/mt9m032.c @@ -392,10 +392,11 @@ static int mt9m032_set_pad_format(struct v4l2_subdev *subdev,  	}  	/* Scaling is not supported, the format is thus fixed. */ -	ret = mt9m032_get_pad_format(subdev, fh, fmt); +	fmt->format = *__mt9m032_get_pad_format(sensor, fh, fmt->which); +	ret = 0;  done: -	mutex_lock(&sensor->lock); +	mutex_unlock(&sensor->lock);  	return ret;  } diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 29f463cc09c..11e44386fa9 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -268,10 +268,17 @@ config TWL6030_PWM  	  This is used to control charging LED brightness.  config TWL6040_CORE -	bool -	depends on TWL4030_CORE && GENERIC_HARDIRQS +	bool "Support for TWL6040 audio codec" +	depends on I2C=y && GENERIC_HARDIRQS  	select MFD_CORE +	select REGMAP_I2C  	default n +	help +	  Say yes here if you want support for Texas Instruments TWL6040 audio +	  codec. +	  This driver provides common support for accessing the device, +	  additional drivers must be enabled in order to use the +	  functionality of the device (audio, vibra).  config MFD_STMPE  	bool "Support STMicroelectronics STMPE" diff --git a/drivers/mfd/asic3.c b/drivers/mfd/asic3.c index 1895cf9fab8..1582c3d9525 100644 --- a/drivers/mfd/asic3.c +++ b/drivers/mfd/asic3.c @@ -527,7 +527,9 @@ static void asic3_gpio_set(struct gpio_chip *chip,  static int asic3_gpio_to_irq(struct gpio_chip *chip, unsigned offset)  { -	return (offset < ASIC3_NUM_GPIOS) ? IRQ_BOARD_START + offset : -ENXIO; +	struct asic3 *asic = container_of(chip, struct asic3, gpio); + +	return (offset < ASIC3_NUM_GPIOS) ? asic->irq_base + offset : -ENXIO;  }  static __init int asic3_gpio_probe(struct platform_device *pdev, diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c index 95a2e546a48..7e96bb22972 100644 --- a/drivers/mfd/omap-usb-host.c +++ b/drivers/mfd/omap-usb-host.c @@ -25,7 +25,7 @@  #include <linux/clk.h>  #include <linux/dma-mapping.h>  #include <linux/spinlock.h> -#include <linux/gpio.h> +#include <plat/cpu.h>  #include <plat/usb.h>  #include <linux/pm_runtime.h> @@ -502,19 +502,6 @@ static void omap_usbhs_init(struct device *dev)  	pm_runtime_get_sync(dev);  	spin_lock_irqsave(&omap->lock, flags); -	if (pdata->ehci_data->phy_reset) { -		if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) -			gpio_request_one(pdata->ehci_data->reset_gpio_port[0], -					 GPIOF_OUT_INIT_LOW, "USB1 PHY reset"); - -		if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1])) -			gpio_request_one(pdata->ehci_data->reset_gpio_port[1], -					 GPIOF_OUT_INIT_LOW, "USB2 PHY reset"); - -		/* Hold the PHY in RESET for enough time till DIR is high */ -		udelay(10); -	} -  	omap->usbhs_rev = usbhs_read(omap->uhh_base, OMAP_UHH_REVISION);  	dev_dbg(dev, "OMAP UHH_REVISION 0x%x\n", omap->usbhs_rev); @@ -593,39 +580,10 @@ static void omap_usbhs_init(struct device *dev)  			usbhs_omap_tll_init(dev, OMAP_TLL_CHANNEL_COUNT);  	} -	if (pdata->ehci_data->phy_reset) { -		/* Hold the PHY in RESET for enough time till -		 * PHY is settled and ready -		 */ -		udelay(10); - -		if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) -			gpio_set_value -				(pdata->ehci_data->reset_gpio_port[0], 1); - -		if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1])) -			gpio_set_value -				(pdata->ehci_data->reset_gpio_port[1], 1); -	} -  	spin_unlock_irqrestore(&omap->lock, flags);  	pm_runtime_put_sync(dev);  } -static void omap_usbhs_deinit(struct device *dev) -{ -	struct usbhs_hcd_omap		*omap = dev_get_drvdata(dev); -	struct usbhs_omap_platform_data	*pdata = &omap->platdata; - -	if (pdata->ehci_data->phy_reset) { -		if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) -			gpio_free(pdata->ehci_data->reset_gpio_port[0]); - -		if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1])) -			gpio_free(pdata->ehci_data->reset_gpio_port[1]); -	} -} -  /**   * usbhs_omap_probe - initialize TI-based HCDs @@ -860,7 +818,6 @@ static int __devexit usbhs_omap_remove(struct platform_device *pdev)  {  	struct usbhs_hcd_omap *omap = platform_get_drvdata(pdev); -	omap_usbhs_deinit(&pdev->dev);  	iounmap(omap->tll_base);  	iounmap(omap->uhh_base);  	clk_put(omap->init_60m_fclk); diff --git a/drivers/mfd/rc5t583.c b/drivers/mfd/rc5t583.c index 99ef944c621..44afae0a69c 100644 --- a/drivers/mfd/rc5t583.c +++ b/drivers/mfd/rc5t583.c @@ -80,44 +80,6 @@ static struct mfd_cell rc5t583_subdevs[] = {  	{.name = "rc5t583-key",      }  }; -int rc5t583_write(struct device *dev, uint8_t reg, uint8_t val) -{ -	struct rc5t583 *rc5t583 = dev_get_drvdata(dev); -	return regmap_write(rc5t583->regmap, reg, val); -} - -int rc5t583_read(struct device *dev, uint8_t reg, uint8_t *val) -{ -	struct rc5t583 *rc5t583 = dev_get_drvdata(dev); -	unsigned int ival; -	int ret; -	ret = regmap_read(rc5t583->regmap, reg, &ival); -	if (!ret) -		*val = (uint8_t)ival; -	return ret; -} - -int rc5t583_set_bits(struct device *dev, unsigned int reg, -			unsigned int bit_mask) -{ -	struct rc5t583 *rc5t583 = dev_get_drvdata(dev); -	return regmap_update_bits(rc5t583->regmap, reg, bit_mask, bit_mask); -} - -int rc5t583_clear_bits(struct device *dev, unsigned int reg, -			unsigned int bit_mask) -{ -	struct rc5t583 *rc5t583 = dev_get_drvdata(dev); -	return regmap_update_bits(rc5t583->regmap, reg, bit_mask, 0); -} - -int rc5t583_update(struct device *dev, unsigned int reg, -		unsigned int val, unsigned int mask) -{ -	struct rc5t583 *rc5t583 = dev_get_drvdata(dev); -	return regmap_update_bits(rc5t583->regmap, reg, mask, val); -} -  static int __rc5t583_set_ext_pwrreq1_control(struct device *dev,  	int id, int ext_pwr, int slots)  { @@ -197,6 +159,7 @@ int rc5t583_ext_power_req_config(struct device *dev, int ds_id,  			ds_id, ext_pwr_req);  	return 0;  } +EXPORT_SYMBOL(rc5t583_ext_power_req_config);  static int rc5t583_clear_ext_power_req(struct rc5t583 *rc5t583,  	struct rc5t583_platform_data *pdata) diff --git a/drivers/mfd/twl6040-core.c b/drivers/mfd/twl6040-core.c index b2d8e512d3c..2d6bedadca0 100644 --- a/drivers/mfd/twl6040-core.c +++ b/drivers/mfd/twl6040-core.c @@ -30,7 +30,9 @@  #include <linux/platform_device.h>  #include <linux/gpio.h>  #include <linux/delay.h> -#include <linux/i2c/twl.h> +#include <linux/i2c.h> +#include <linux/regmap.h> +#include <linux/err.h>  #include <linux/mfd/core.h>  #include <linux/mfd/twl6040.h> @@ -39,7 +41,7 @@  int twl6040_reg_read(struct twl6040 *twl6040, unsigned int reg)  {  	int ret; -	u8 val = 0; +	unsigned int val;  	mutex_lock(&twl6040->io_mutex);  	/* Vibra control registers from cache */ @@ -47,7 +49,7 @@ int twl6040_reg_read(struct twl6040 *twl6040, unsigned int reg)  		     reg == TWL6040_REG_VIBCTLR)) {  		val = twl6040->vibra_ctrl_cache[VIBRACTRL_MEMBER(reg)];  	} else { -		ret = twl_i2c_read_u8(TWL_MODULE_AUDIO_VOICE, &val, reg); +		ret = regmap_read(twl6040->regmap, reg, &val);  		if (ret < 0) {  			mutex_unlock(&twl6040->io_mutex);  			return ret; @@ -64,7 +66,7 @@ int twl6040_reg_write(struct twl6040 *twl6040, unsigned int reg, u8 val)  	int ret;  	mutex_lock(&twl6040->io_mutex); -	ret = twl_i2c_write_u8(TWL_MODULE_AUDIO_VOICE, val, reg); +	ret = regmap_write(twl6040->regmap, reg, val);  	/* Cache the vibra control registers */  	if (reg == TWL6040_REG_VIBCTLL || reg == TWL6040_REG_VIBCTLR)  		twl6040->vibra_ctrl_cache[VIBRACTRL_MEMBER(reg)] = val; @@ -77,16 +79,9 @@ EXPORT_SYMBOL(twl6040_reg_write);  int twl6040_set_bits(struct twl6040 *twl6040, unsigned int reg, u8 mask)  {  	int ret; -	u8 val;  	mutex_lock(&twl6040->io_mutex); -	ret = twl_i2c_read_u8(TWL_MODULE_AUDIO_VOICE, &val, reg); -	if (ret) -		goto out; - -	val |= mask; -	ret = twl_i2c_write_u8(TWL_MODULE_AUDIO_VOICE, val, reg); -out: +	ret = regmap_update_bits(twl6040->regmap, reg, mask, mask);  	mutex_unlock(&twl6040->io_mutex);  	return ret;  } @@ -95,16 +90,9 @@ EXPORT_SYMBOL(twl6040_set_bits);  int twl6040_clear_bits(struct twl6040 *twl6040, unsigned int reg, u8 mask)  {  	int ret; -	u8 val;  	mutex_lock(&twl6040->io_mutex); -	ret = twl_i2c_read_u8(TWL_MODULE_AUDIO_VOICE, &val, reg); -	if (ret) -		goto out; - -	val &= ~mask; -	ret = twl_i2c_write_u8(TWL_MODULE_AUDIO_VOICE, val, reg); -out: +	ret = regmap_update_bits(twl6040->regmap, reg, mask, 0);  	mutex_unlock(&twl6040->io_mutex);  	return ret;  } @@ -494,32 +482,58 @@ static struct resource twl6040_codec_rsrc[] = {  	},  }; -static int __devinit twl6040_probe(struct platform_device *pdev) +static bool twl6040_readable_reg(struct device *dev, unsigned int reg)  { -	struct twl4030_audio_data *pdata = pdev->dev.platform_data; +	/* Register 0 is not readable */ +	if (!reg) +		return false; +	return true; +} + +static struct regmap_config twl6040_regmap_config = { +	.reg_bits = 8, +	.val_bits = 8, +	.max_register = TWL6040_REG_STATUS, /* 0x2e */ + +	.readable_reg = twl6040_readable_reg, +}; + +static int __devinit twl6040_probe(struct i2c_client *client, +				     const struct i2c_device_id *id) +{ +	struct twl6040_platform_data *pdata = client->dev.platform_data;  	struct twl6040 *twl6040;  	struct mfd_cell *cell = NULL;  	int ret, children = 0;  	if (!pdata) { -		dev_err(&pdev->dev, "Platform data is missing\n"); +		dev_err(&client->dev, "Platform data is missing\n");  		return -EINVAL;  	}  	/* In order to operate correctly we need valid interrupt config */ -	if (!pdata->naudint_irq || !pdata->irq_base) { -		dev_err(&pdev->dev, "Invalid IRQ configuration\n"); +	if (!client->irq || !pdata->irq_base) { +		dev_err(&client->dev, "Invalid IRQ configuration\n");  		return -EINVAL;  	} -	twl6040 = kzalloc(sizeof(struct twl6040), GFP_KERNEL); -	if (!twl6040) -		return -ENOMEM; +	twl6040 = devm_kzalloc(&client->dev, sizeof(struct twl6040), +			       GFP_KERNEL); +	if (!twl6040) { +		ret = -ENOMEM; +		goto err; +	} + +	twl6040->regmap = regmap_init_i2c(client, &twl6040_regmap_config); +	if (IS_ERR(twl6040->regmap)) { +		ret = PTR_ERR(twl6040->regmap); +		goto err; +	} -	platform_set_drvdata(pdev, twl6040); +	i2c_set_clientdata(client, twl6040); -	twl6040->dev = &pdev->dev; -	twl6040->irq = pdata->naudint_irq; +	twl6040->dev = &client->dev; +	twl6040->irq = client->irq;  	twl6040->irq_base = pdata->irq_base;  	mutex_init(&twl6040->mutex); @@ -588,12 +602,12 @@ static int __devinit twl6040_probe(struct platform_device *pdev)  	}  	if (children) { -		ret = mfd_add_devices(&pdev->dev, pdev->id, twl6040->cells, +		ret = mfd_add_devices(&client->dev, -1, twl6040->cells,  				      children, NULL, 0);  		if (ret)  			goto mfd_err;  	} else { -		dev_err(&pdev->dev, "No platform data found for children\n"); +		dev_err(&client->dev, "No platform data found for children\n");  		ret = -ENODEV;  		goto mfd_err;  	} @@ -608,14 +622,15 @@ gpio2_err:  	if (gpio_is_valid(twl6040->audpwron))  		gpio_free(twl6040->audpwron);  gpio1_err: -	platform_set_drvdata(pdev, NULL); -	kfree(twl6040); +	i2c_set_clientdata(client, NULL); +	regmap_exit(twl6040->regmap); +err:  	return ret;  } -static int __devexit twl6040_remove(struct platform_device *pdev) +static int __devexit twl6040_remove(struct i2c_client *client)  { -	struct twl6040 *twl6040 = platform_get_drvdata(pdev); +	struct twl6040 *twl6040 = i2c_get_clientdata(client);  	if (twl6040->power_count)  		twl6040_power(twl6040, 0); @@ -626,23 +641,30 @@ static int __devexit twl6040_remove(struct platform_device *pdev)  	free_irq(twl6040->irq_base + TWL6040_IRQ_READY, twl6040);  	twl6040_irq_exit(twl6040); -	mfd_remove_devices(&pdev->dev); -	platform_set_drvdata(pdev, NULL); -	kfree(twl6040); +	mfd_remove_devices(&client->dev); +	i2c_set_clientdata(client, NULL); +	regmap_exit(twl6040->regmap);  	return 0;  } -static struct platform_driver twl6040_driver = { +static const struct i2c_device_id twl6040_i2c_id[] = { +	{ "twl6040", 0, }, +	{ }, +}; +MODULE_DEVICE_TABLE(i2c, twl6040_i2c_id); + +static struct i2c_driver twl6040_driver = { +	.driver = { +		.name = "twl6040", +		.owner = THIS_MODULE, +	},  	.probe		= twl6040_probe,  	.remove		= __devexit_p(twl6040_remove), -	.driver		= { -		.owner	= THIS_MODULE, -		.name	= "twl6040", -	}, +	.id_table	= twl6040_i2c_id,  }; -module_platform_driver(twl6040_driver); +module_i2c_driver(twl6040_driver);  MODULE_DESCRIPTION("TWL6040 MFD");  MODULE_AUTHOR("Misael Lopez Cruz <misael.lopez@ti.com>"); diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index b1809650b7a..dabec556ebb 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -873,7 +873,7 @@ static int mmc_blk_issue_secdiscard_rq(struct mmc_queue *mq,  {  	struct mmc_blk_data *md = mq->data;  	struct mmc_card *card = md->queue.card; -	unsigned int from, nr, arg; +	unsigned int from, nr, arg, trim_arg, erase_arg;  	int err = 0, type = MMC_BLK_SECDISCARD;  	if (!(mmc_can_secure_erase_trim(card) || mmc_can_sanitize(card))) { @@ -881,20 +881,26 @@ static int mmc_blk_issue_secdiscard_rq(struct mmc_queue *mq,  		goto out;  	} +	from = blk_rq_pos(req); +	nr = blk_rq_sectors(req); +  	/* The sanitize operation is supported at v4.5 only */  	if (mmc_can_sanitize(card)) { -		err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, -				EXT_CSD_SANITIZE_START, 1, 0); -		goto out; +		erase_arg = MMC_ERASE_ARG; +		trim_arg = MMC_TRIM_ARG; +	} else { +		erase_arg = MMC_SECURE_ERASE_ARG; +		trim_arg = MMC_SECURE_TRIM1_ARG;  	} -	from = blk_rq_pos(req); -	nr = blk_rq_sectors(req); - -	if (mmc_can_trim(card) && !mmc_erase_group_aligned(card, from, nr)) -		arg = MMC_SECURE_TRIM1_ARG; -	else -		arg = MMC_SECURE_ERASE_ARG; +	if (mmc_erase_group_aligned(card, from, nr)) +		arg = erase_arg; +	else if (mmc_can_trim(card)) +		arg = trim_arg; +	else { +		err = -EINVAL; +		goto out; +	}  retry:  	if (card->quirks & MMC_QUIRK_INAND_CMD38) {  		err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, @@ -904,25 +910,41 @@ retry:  				 INAND_CMD38_ARG_SECERASE,  				 0);  		if (err) -			goto out; +			goto out_retry;  	} +  	err = mmc_erase(card, from, nr, arg); -	if (!err && arg == MMC_SECURE_TRIM1_ARG) { +	if (err == -EIO) +		goto out_retry; +	if (err) +		goto out; + +	if (arg == MMC_SECURE_TRIM1_ARG) {  		if (card->quirks & MMC_QUIRK_INAND_CMD38) {  			err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,  					 INAND_CMD38_ARG_EXT_CSD,  					 INAND_CMD38_ARG_SECTRIM2,  					 0);  			if (err) -				goto out; +				goto out_retry;  		} +  		err = mmc_erase(card, from, nr, MMC_SECURE_TRIM2_ARG); +		if (err == -EIO) +			goto out_retry; +		if (err) +			goto out;  	} -out: -	if (err == -EIO && !mmc_blk_reset(md, card->host, type)) + +	if (mmc_can_sanitize(card)) +		err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, +				 EXT_CSD_SANITIZE_START, 1, 0); +out_retry: +	if (err && !mmc_blk_reset(md, card->host, type))  		goto retry;  	if (!err)  		mmc_blk_reset_success(md, type); +out:  	spin_lock_irq(&md->lock);  	__blk_end_request(req, err, blk_rq_bytes(req));  	spin_unlock_irq(&md->lock); @@ -1802,7 +1824,7 @@ static void mmc_blk_remove(struct mmc_card *card)  }  #ifdef CONFIG_PM -static int mmc_blk_suspend(struct mmc_card *card, pm_message_t state) +static int mmc_blk_suspend(struct mmc_card *card)  {  	struct mmc_blk_data *part_md;  	struct mmc_blk_data *md = mmc_get_drvdata(card); diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c index 2517547b436..996f8e36e23 100644 --- a/drivers/mmc/card/queue.c +++ b/drivers/mmc/card/queue.c @@ -139,7 +139,7 @@ static void mmc_queue_setup_discard(struct request_queue *q,  	queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, q);  	q->limits.max_discard_sectors = max_discard; -	if (card->erased_byte == 0) +	if (card->erased_byte == 0 && !mmc_can_discard(card))  		q->limits.discard_zeroes_data = 1;  	q->limits.discard_granularity = card->pref_erase << 9;  	/* granularity must not be greater than max. discard */ diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c index 3f606068d55..c60cee92a2b 100644 --- a/drivers/mmc/core/bus.c +++ b/drivers/mmc/core/bus.c @@ -122,14 +122,14 @@ static int mmc_bus_remove(struct device *dev)  	return 0;  } -static int mmc_bus_suspend(struct device *dev, pm_message_t state) +static int mmc_bus_suspend(struct device *dev)  {  	struct mmc_driver *drv = to_mmc_driver(dev->driver);  	struct mmc_card *card = mmc_dev_to_card(dev);  	int ret = 0;  	if (dev->driver && drv->suspend) -		ret = drv->suspend(card, state); +		ret = drv->suspend(card);  	return ret;  } @@ -165,20 +165,14 @@ static int mmc_runtime_idle(struct device *dev)  	return pm_runtime_suspend(dev);  } +#endif /* !CONFIG_PM_RUNTIME */ +  static const struct dev_pm_ops mmc_bus_pm_ops = { -	.runtime_suspend	= mmc_runtime_suspend, -	.runtime_resume		= mmc_runtime_resume, -	.runtime_idle		= mmc_runtime_idle, +	SET_RUNTIME_PM_OPS(mmc_runtime_suspend, mmc_runtime_resume, +			mmc_runtime_idle) +	SET_SYSTEM_SLEEP_PM_OPS(mmc_bus_suspend, mmc_bus_resume)  }; -#define MMC_PM_OPS_PTR	(&mmc_bus_pm_ops) - -#else /* !CONFIG_PM_RUNTIME */ - -#define MMC_PM_OPS_PTR	NULL - -#endif /* !CONFIG_PM_RUNTIME */ -  static struct bus_type mmc_bus_type = {  	.name		= "mmc",  	.dev_attrs	= mmc_dev_attrs, @@ -186,9 +180,7 @@ static struct bus_type mmc_bus_type = {  	.uevent		= mmc_bus_uevent,  	.probe		= mmc_bus_probe,  	.remove		= mmc_bus_remove, -	.suspend	= mmc_bus_suspend, -	.resume		= mmc_bus_resume, -	.pm		= MMC_PM_OPS_PTR, +	.pm		= &mmc_bus_pm_ops,  };  int mmc_register_bus(void) diff --git a/drivers/mmc/core/cd-gpio.c b/drivers/mmc/core/cd-gpio.c index 29de31e260d..2c14be73254 100644 --- a/drivers/mmc/core/cd-gpio.c +++ b/drivers/mmc/core/cd-gpio.c @@ -12,6 +12,7 @@  #include <linux/gpio.h>  #include <linux/interrupt.h>  #include <linux/jiffies.h> +#include <linux/mmc/cd-gpio.h>  #include <linux/mmc/host.h>  #include <linux/module.h>  #include <linux/slab.h> diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 7474c47b9c0..ba821fe70bc 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -1409,7 +1409,10 @@ static unsigned int mmc_mmc_erase_timeout(struct mmc_card *card,  {  	unsigned int erase_timeout; -	if (card->ext_csd.erase_group_def & 1) { +	if (arg == MMC_DISCARD_ARG || +	    (arg == MMC_TRIM_ARG && card->ext_csd.rev >= 6)) { +		erase_timeout = card->ext_csd.trim_timeout; +	} else if (card->ext_csd.erase_group_def & 1) {  		/* High Capacity Erase Group Size uses HC timeouts */  		if (arg == MMC_TRIM_ARG)  			erase_timeout = card->ext_csd.trim_timeout; @@ -1681,8 +1684,6 @@ int mmc_can_trim(struct mmc_card *card)  {  	if (card->ext_csd.sec_feature_support & EXT_CSD_SEC_GB_CL_EN)  		return 1; -	if (mmc_can_discard(card)) -		return 1;  	return 0;  }  EXPORT_SYMBOL(mmc_can_trim); @@ -1701,6 +1702,8 @@ EXPORT_SYMBOL(mmc_can_discard);  int mmc_can_sanitize(struct mmc_card *card)  { +	if (!mmc_can_trim(card) && !mmc_can_erase(card)) +		return 0;  	if (card->ext_csd.sec_feature_support & EXT_CSD_SEC_SANITIZE)  		return 1;  	return 0; @@ -2235,6 +2238,7 @@ int mmc_cache_ctrl(struct mmc_host *host, u8 enable)  			mmc_card_is_removable(host))  		return err; +	mmc_claim_host(host);  	if (card && mmc_card_mmc(card) &&  			(card->ext_csd.cache_size > 0)) {  		enable = !!enable; @@ -2252,6 +2256,7 @@ int mmc_cache_ctrl(struct mmc_host *host, u8 enable)  				card->ext_csd.cache_ctrl = enable;  		}  	} +	mmc_release_host(host);  	return err;  } @@ -2269,49 +2274,32 @@ int mmc_suspend_host(struct mmc_host *host)  	cancel_delayed_work(&host->detect);  	mmc_flush_scheduled_work(); -	if (mmc_try_claim_host(host)) { -		err = mmc_cache_ctrl(host, 0); -		mmc_release_host(host); -	} else { -		err = -EBUSY; -	} +	err = mmc_cache_ctrl(host, 0);  	if (err)  		goto out;  	mmc_bus_get(host);  	if (host->bus_ops && !host->bus_dead) { -		/* -		 * A long response time is not acceptable for device drivers -		 * when doing suspend. Prevent mmc_claim_host in the suspend -		 * sequence, to potentially wait "forever" by trying to -		 * pre-claim the host. -		 */ -		if (mmc_try_claim_host(host)) { -			if (host->bus_ops->suspend) { -				err = host->bus_ops->suspend(host); -			} -			mmc_release_host(host); +		if (host->bus_ops->suspend) +			err = host->bus_ops->suspend(host); -			if (err == -ENOSYS || !host->bus_ops->resume) { -				/* -				 * We simply "remove" the card in this case. -				 * It will be redetected on resume.  (Calling -				 * bus_ops->remove() with a claimed host can -				 * deadlock.) -				 */ -				if (host->bus_ops->remove) -					host->bus_ops->remove(host); -				mmc_claim_host(host); -				mmc_detach_bus(host); -				mmc_power_off(host); -				mmc_release_host(host); -				host->pm_flags = 0; -				err = 0; -			} -		} else { -			err = -EBUSY; +		if (err == -ENOSYS || !host->bus_ops->resume) { +			/* +			 * We simply "remove" the card in this case. +			 * It will be redetected on resume.  (Calling +			 * bus_ops->remove() with a claimed host can +			 * deadlock.) +			 */ +			if (host->bus_ops->remove) +				host->bus_ops->remove(host); +			mmc_claim_host(host); +			mmc_detach_bus(host); +			mmc_power_off(host); +			mmc_release_host(host); +			host->pm_flags = 0; +			err = 0;  		}  	}  	mmc_bus_put(host); diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index bf3c9b456aa..ab3fc461710 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -526,8 +526,10 @@ static int dw_mci_submit_data_dma(struct dw_mci *host, struct mmc_data *data)  		return -ENODEV;  	sg_len = dw_mci_pre_dma_transfer(host, data, 0); -	if (sg_len < 0) +	if (sg_len < 0) { +		host->dma_ops->stop(host);  		return sg_len; +	}  	host->using_dma = 1; @@ -1879,7 +1881,8 @@ static void dw_mci_init_dma(struct dw_mci *host)  	if (!host->dma_ops)  		goto no_dma; -	if (host->dma_ops->init) { +	if (host->dma_ops->init && host->dma_ops->start && +	    host->dma_ops->stop && host->dma_ops->cleanup) {  		if (host->dma_ops->init(host)) {  			dev_err(&host->dev, "%s: Unable to initialize "  				"DMA Controller.\n", __func__); diff --git a/drivers/mmc/host/mxs-mmc.c b/drivers/mmc/host/mxs-mmc.c index b0f2ef98818..e3f5af96ab8 100644 --- a/drivers/mmc/host/mxs-mmc.c +++ b/drivers/mmc/host/mxs-mmc.c @@ -363,6 +363,7 @@ static void mxs_mmc_bc(struct mxs_mmc_host *host)  		goto out;  	dmaengine_submit(desc); +	dma_async_issue_pending(host->dmach);  	return;  out: @@ -403,6 +404,7 @@ static void mxs_mmc_ac(struct mxs_mmc_host *host)  		goto out;  	dmaengine_submit(desc); +	dma_async_issue_pending(host->dmach);  	return;  out: @@ -531,6 +533,7 @@ static void mxs_mmc_adtc(struct mxs_mmc_host *host)  		goto out;  	dmaengine_submit(desc); +	dma_async_issue_pending(host->dmach);  	return;  out:  	dev_warn(mmc_dev(host->mmc), diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 5c2b1c10af9..56d4499d438 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -249,7 +249,7 @@ static int omap_hsmmc_set_power(struct device *dev, int slot, int power_on,  	 * the pbias cell programming support is still missing when  	 * booting with Device tree  	 */ -	if (of_have_populated_dt() && !vdd) +	if (dev->of_node && !vdd)  		return 0;  	if (mmc_slot(host).before_set_reg) @@ -1549,7 +1549,7 @@ static void omap_hsmmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)  			 * can't be allowed when booting with device  			 * tree.  			 */ -			(!of_have_populated_dt())) { +			!host->dev->of_node) {  				/*  				 * The mmc_select_voltage fn of the core does  				 * not seem to set the power_mode to @@ -1741,7 +1741,7 @@ static const struct of_device_id omap_mmc_of_match[] = {  		.data = &omap4_reg_offset,  	},  	{}, -} +};  MODULE_DEVICE_TABLE(of, omap_mmc_of_match);  static struct omap_mmc_platform_data *of_get_hsmmc_pdata(struct device *dev) diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c index 6193a0d7bde..8abdaf6697a 100644 --- a/drivers/mmc/host/sdhci-esdhc-imx.c +++ b/drivers/mmc/host/sdhci-esdhc-imx.c @@ -467,8 +467,7 @@ static int __devinit sdhci_esdhc_imx_probe(struct platform_device *pdev)  	clk_prepare_enable(clk);  	pltfm_host->clk = clk; -	if (!is_imx25_esdhc(imx_data)) -		host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL; +	host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL;  	if (is_imx25_esdhc(imx_data) || is_imx35_esdhc(imx_data))  		/* Fix errata ENGcm07207 present on i.MX25 and i.MX35 */ diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 9aa77f3f04a..ccefdebeff1 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -147,7 +147,7 @@ static void sdhci_set_card_detection(struct sdhci_host *host, bool enable)  	u32 present, irqs;  	if ((host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION) || -	    !mmc_card_is_removable(host->mmc)) +	    (host->mmc->caps & MMC_CAP_NONREMOVABLE))  		return;  	present = sdhci_readl(host, SDHCI_PRESENT_STATE) & diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c index 75b1dde1635..9ec51cec2e1 100644 --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c @@ -266,6 +266,7 @@ int start_dma_without_bch_irq(struct gpmi_nand_data *this,  	desc->callback		= dma_irq_callback;  	desc->callback_param	= this;  	dmaengine_submit(desc); +	dma_async_issue_pending(get_dma_chan(this));  	/* Wait for the interrupt from the DMA block. */  	err = wait_for_completion_timeout(dma_c, msecs_to_jiffies(1000)); diff --git a/drivers/net/arcnet/arc-rimi.c b/drivers/net/arcnet/arc-rimi.c index 25197b698dd..b8b4c7ba884 100644 --- a/drivers/net/arcnet/arc-rimi.c +++ b/drivers/net/arcnet/arc-rimi.c @@ -89,16 +89,16 @@ static int __init arcrimi_probe(struct net_device *dev)  	BUGLVL(D_NORMAL) printk(VERSION);  	BUGLVL(D_NORMAL) printk("E-mail me if you actually test the RIM I driver, please!\n"); -	BUGMSG(D_NORMAL, "Given: node %02Xh, shmem %lXh, irq %d\n", +	BUGLVL(D_NORMAL) printk("Given: node %02Xh, shmem %lXh, irq %d\n",  	       dev->dev_addr[0], dev->mem_start, dev->irq);  	if (dev->mem_start <= 0 || dev->irq <= 0) { -		BUGMSG(D_NORMAL, "No autoprobe for RIM I; you " +		BUGLVL(D_NORMAL) printk("No autoprobe for RIM I; you "  		       "must specify the shmem and irq!\n");  		return -ENODEV;  	}  	if (dev->dev_addr[0] == 0) { -		BUGMSG(D_NORMAL, "You need to specify your card's station " +		BUGLVL(D_NORMAL) printk("You need to specify your card's station "  		       "ID!\n");  		return -ENODEV;  	} @@ -109,7 +109,7 @@ static int __init arcrimi_probe(struct net_device *dev)  	 * will be taken.  	 */  	if (!request_mem_region(dev->mem_start, MIRROR_SIZE, "arcnet (90xx)")) { -		BUGMSG(D_NORMAL, "Card memory already allocated\n"); +		BUGLVL(D_NORMAL) printk("Card memory already allocated\n");  		return -ENODEV;  	}  	return arcrimi_found(dev); diff --git a/drivers/net/caif/caif_hsi.c b/drivers/net/caif/caif_hsi.c index 9a66e2a910a..9c1c8cd5223 100644 --- a/drivers/net/caif/caif_hsi.c +++ b/drivers/net/caif/caif_hsi.c @@ -744,14 +744,14 @@ static void cfhsi_wake_up(struct work_struct *work)  		size_t fifo_occupancy = 0;  		/* Wakeup timeout */ -		dev_err(&cfhsi->ndev->dev, "%s: Timeout.\n", +		dev_dbg(&cfhsi->ndev->dev, "%s: Timeout.\n",  			__func__);  		/* Check FIFO to check if modem has sent something. */  		WARN_ON(cfhsi->dev->cfhsi_fifo_occupancy(cfhsi->dev,  					&fifo_occupancy)); -		dev_err(&cfhsi->ndev->dev, "%s: Bytes in FIFO: %u.\n", +		dev_dbg(&cfhsi->ndev->dev, "%s: Bytes in FIFO: %u.\n",  				__func__, (unsigned) fifo_occupancy);  		/* Check if we misssed the interrupt. */ @@ -1210,7 +1210,7 @@ int cfhsi_probe(struct platform_device *pdev)  static void cfhsi_shutdown(struct cfhsi *cfhsi)  { -	u8 *tx_buf, *rx_buf; +	u8 *tx_buf, *rx_buf, *flip_buf;  	/* Stop TXing */  	netif_tx_stop_all_queues(cfhsi->ndev); @@ -1234,7 +1234,7 @@ static void cfhsi_shutdown(struct cfhsi *cfhsi)  	/* Store bufferes: will be freed later. */  	tx_buf = cfhsi->tx_buf;  	rx_buf = cfhsi->rx_buf; - +	flip_buf = cfhsi->rx_flip_buf;  	/* Flush transmit queues. */  	cfhsi_abort_tx(cfhsi); @@ -1247,6 +1247,7 @@ static void cfhsi_shutdown(struct cfhsi *cfhsi)  	/* Free buffers. */  	kfree(tx_buf);  	kfree(rx_buf); +	kfree(flip_buf);  }  int cfhsi_remove(struct platform_device *pdev) diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c index 5234586dff1..629c4ba5d49 100644 --- a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c +++ b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c @@ -875,6 +875,7 @@ static int pcan_usb_pro_init(struct peak_usb_device *dev)  					    PCAN_USBPRO_INFO_FW,  					    &fi, sizeof(fi));  		if (err) { +			kfree(usb_if);  			dev_err(dev->netdev->dev.parent,  				"unable to read %s firmware info (err %d)\n",  				pcan_usb_pro.name, err); @@ -885,6 +886,7 @@ static int pcan_usb_pro_init(struct peak_usb_device *dev)  					    PCAN_USBPRO_INFO_BL,  					    &bi, sizeof(bi));  		if (err) { +			kfree(usb_if);  			dev_err(dev->netdev->dev.parent,  				"unable to read %s bootloader info (err %d)\n",  				pcan_usb_pro.name, err); diff --git a/drivers/net/dummy.c b/drivers/net/dummy.c index d5c6d92f1ee..442d91a2747 100644 --- a/drivers/net/dummy.c +++ b/drivers/net/dummy.c @@ -107,14 +107,14 @@ static int dummy_dev_init(struct net_device *dev)  	return 0;  } -static void dummy_dev_free(struct net_device *dev) +static void dummy_dev_uninit(struct net_device *dev)  {  	free_percpu(dev->dstats); -	free_netdev(dev);  }  static const struct net_device_ops dummy_netdev_ops = {  	.ndo_init		= dummy_dev_init, +	.ndo_uninit		= dummy_dev_uninit,  	.ndo_start_xmit		= dummy_xmit,  	.ndo_validate_addr	= eth_validate_addr,  	.ndo_set_rx_mode	= set_multicast_list, @@ -128,7 +128,7 @@ static void dummy_setup(struct net_device *dev)  	/* Initialize the device structure. */  	dev->netdev_ops = &dummy_netdev_ops; -	dev->destructor = dummy_dev_free; +	dev->destructor = free_netdev;  	/* Fill in device structure with ethernet-generic values. */  	dev->tx_queue_len = 0; diff --git a/drivers/net/ethernet/atheros/atlx/atl1.c b/drivers/net/ethernet/atheros/atlx/atl1.c index 40ac4143654..c926857e820 100644 --- a/drivers/net/ethernet/atheros/atlx/atl1.c +++ b/drivers/net/ethernet/atheros/atlx/atl1.c @@ -2476,7 +2476,7 @@ static irqreturn_t atl1_intr(int irq, void *data)  					"pcie phy link down %x\n", status);  			if (netif_running(adapter->netdev)) {	/* reset MAC */  				iowrite32(0, adapter->hw.hw_addr + REG_IMR); -				schedule_work(&adapter->pcie_dma_to_rst_task); +				schedule_work(&adapter->reset_dev_task);  				return IRQ_HANDLED;  			}  		} @@ -2488,7 +2488,7 @@ static irqreturn_t atl1_intr(int irq, void *data)  					"pcie DMA r/w error (status = 0x%x)\n",  					status);  			iowrite32(0, adapter->hw.hw_addr + REG_IMR); -			schedule_work(&adapter->pcie_dma_to_rst_task); +			schedule_work(&adapter->reset_dev_task);  			return IRQ_HANDLED;  		} @@ -2633,10 +2633,10 @@ static void atl1_down(struct atl1_adapter *adapter)  	atl1_clean_rx_ring(adapter);  } -static void atl1_tx_timeout_task(struct work_struct *work) +static void atl1_reset_dev_task(struct work_struct *work)  {  	struct atl1_adapter *adapter = -		container_of(work, struct atl1_adapter, tx_timeout_task); +		container_of(work, struct atl1_adapter, reset_dev_task);  	struct net_device *netdev = adapter->netdev;  	netif_device_detach(netdev); @@ -3038,12 +3038,10 @@ static int __devinit atl1_probe(struct pci_dev *pdev,  		    (unsigned long)adapter);  	adapter->phy_timer_pending = false; -	INIT_WORK(&adapter->tx_timeout_task, atl1_tx_timeout_task); +	INIT_WORK(&adapter->reset_dev_task, atl1_reset_dev_task);  	INIT_WORK(&adapter->link_chg_task, atlx_link_chg_task); -	INIT_WORK(&adapter->pcie_dma_to_rst_task, atl1_tx_timeout_task); -  	err = register_netdev(netdev);  	if (err)  		goto err_common; diff --git a/drivers/net/ethernet/atheros/atlx/atl1.h b/drivers/net/ethernet/atheros/atlx/atl1.h index 109d6da8be9..e04bf4d71e4 100644 --- a/drivers/net/ethernet/atheros/atlx/atl1.h +++ b/drivers/net/ethernet/atheros/atlx/atl1.h @@ -758,9 +758,8 @@ struct atl1_adapter {  	u16 link_speed;  	u16 link_duplex;  	spinlock_t lock; -	struct work_struct tx_timeout_task; +	struct work_struct reset_dev_task;  	struct work_struct link_chg_task; -	struct work_struct pcie_dma_to_rst_task;  	struct timer_list phy_config_timer;  	bool phy_timer_pending; diff --git a/drivers/net/ethernet/atheros/atlx/atlx.c b/drivers/net/ethernet/atheros/atlx/atlx.c index 3cd8837236d..c9e9dc57986 100644 --- a/drivers/net/ethernet/atheros/atlx/atlx.c +++ b/drivers/net/ethernet/atheros/atlx/atlx.c @@ -194,7 +194,7 @@ static void atlx_tx_timeout(struct net_device *netdev)  {  	struct atlx_adapter *adapter = netdev_priv(netdev);  	/* Do the reset outside of interrupt context */ -	schedule_work(&adapter->tx_timeout_task); +	schedule_work(&adapter->reset_dev_task);  }  /* diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c index ad95324dc04..64392ec410a 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c @@ -942,6 +942,12 @@ static int bnx2x_ets_e3b0_sp_pri_to_cos_set(const struct link_params *params,  	const u8 max_num_of_cos = (port) ? DCBX_E3B0_MAX_NUM_COS_PORT1 :  		DCBX_E3B0_MAX_NUM_COS_PORT0; +	if (pri >= max_num_of_cos) { +		DP(NETIF_MSG_LINK, "bnx2x_ets_e3b0_sp_pri_to_cos_set invalid " +		   "parameter Illegal strict priority\n"); +	    return -EINVAL; +	} +  	if (sp_pri_to_cos[pri] != DCBX_INVALID_COS) {  		DP(NETIF_MSG_LINK, "bnx2x_ets_e3b0_sp_pri_to_cos_set invalid "  				   "parameter There can't be two COS's with " @@ -949,12 +955,6 @@ static int bnx2x_ets_e3b0_sp_pri_to_cos_set(const struct link_params *params,  		return -EINVAL;  	} -	if (pri > max_num_of_cos) { -		DP(NETIF_MSG_LINK, "bnx2x_ets_e3b0_sp_pri_to_cos_set invalid " -		   "parameter Illegal strict priority\n"); -	    return -EINVAL; -	} -  	sp_pri_to_cos[pri] = cos_entry;  	return 0; diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index 062ac333fde..ceeab8e852e 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c @@ -879,8 +879,13 @@ static inline unsigned int tg3_has_work(struct tg3_napi *tnapi)  		if (sblk->status & SD_STATUS_LINK_CHG)  			work_exists = 1;  	} -	/* check for RX/TX work to do */ -	if (sblk->idx[0].tx_consumer != tnapi->tx_cons || + +	/* check for TX work to do */ +	if (sblk->idx[0].tx_consumer != tnapi->tx_cons) +		work_exists = 1; + +	/* check for RX work to do */ +	if (tnapi->rx_rcb_prod_idx &&  	    *(tnapi->rx_rcb_prod_idx) != tnapi->rx_rcb_ptr)  		work_exists = 1; @@ -6124,6 +6129,9 @@ static int tg3_poll_work(struct tg3_napi *tnapi, int work_done, int budget)  			return work_done;  	} +	if (!tnapi->rx_rcb_prod_idx) +		return work_done; +  	/* run RX thread, within the bounds set by NAPI.  	 * All RX "locking" is done by ensuring outside  	 * code synchronizes with tg3->napi.poll() @@ -7567,6 +7575,12 @@ static int tg3_alloc_consistent(struct tg3 *tp)  		 */  		switch (i) {  		default: +			if (tg3_flag(tp, ENABLE_RSS)) { +				tnapi->rx_rcb_prod_idx = NULL; +				break; +			} +			/* Fall through */ +		case 1:  			tnapi->rx_rcb_prod_idx = &sblk->idx[0].rx_producer;  			break;  		case 2: diff --git a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c index 63bfdd10bd6..abb6ce7c1b7 100644 --- a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c +++ b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c @@ -1150,6 +1150,48 @@ release_tpsram:  }  /** + * t3_synchronize_rx - wait for current Rx processing on a port to complete + * @adap: the adapter + * @p: the port + * + * Ensures that current Rx processing on any of the queues associated with + * the given port completes before returning.  We do this by acquiring and + * releasing the locks of the response queues associated with the port. + */ +static void t3_synchronize_rx(struct adapter *adap, const struct port_info *p) +{ +	int i; + +	for (i = p->first_qset; i < p->first_qset + p->nqsets; i++) { +		struct sge_rspq *q = &adap->sge.qs[i].rspq; + +		spin_lock_irq(&q->lock); +		spin_unlock_irq(&q->lock); +	} +} + +static void cxgb_vlan_mode(struct net_device *dev, netdev_features_t features) +{ +	struct port_info *pi = netdev_priv(dev); +	struct adapter *adapter = pi->adapter; + +	if (adapter->params.rev > 0) { +		t3_set_vlan_accel(adapter, 1 << pi->port_id, +				  features & NETIF_F_HW_VLAN_RX); +	} else { +		/* single control for all ports */ +		unsigned int i, have_vlans = features & NETIF_F_HW_VLAN_RX; + +		for_each_port(adapter, i) +			have_vlans |= +				adapter->port[i]->features & NETIF_F_HW_VLAN_RX; + +		t3_set_vlan_accel(adapter, 1, have_vlans); +	} +	t3_synchronize_rx(adapter, pi); +} + +/**   *	cxgb_up - enable the adapter   *	@adapter: adapter being enabled   * @@ -1161,7 +1203,7 @@ release_tpsram:   */  static int cxgb_up(struct adapter *adap)  { -	int err; +	int i, err;  	if (!(adap->flags & FULL_INIT_DONE)) {  		err = t3_check_fw_version(adap); @@ -1198,6 +1240,9 @@ static int cxgb_up(struct adapter *adap)  		if (err)  			goto out; +		for_each_port(adap, i) +			cxgb_vlan_mode(adap->port[i], adap->port[i]->features); +  		setup_rss(adap);  		if (!(adap->flags & NAPI_INIT))  			init_napi(adap); @@ -2508,48 +2553,6 @@ static int cxgb_set_mac_addr(struct net_device *dev, void *p)  	return 0;  } -/** - * t3_synchronize_rx - wait for current Rx processing on a port to complete - * @adap: the adapter - * @p: the port - * - * Ensures that current Rx processing on any of the queues associated with - * the given port completes before returning.  We do this by acquiring and - * releasing the locks of the response queues associated with the port. - */ -static void t3_synchronize_rx(struct adapter *adap, const struct port_info *p) -{ -	int i; - -	for (i = p->first_qset; i < p->first_qset + p->nqsets; i++) { -		struct sge_rspq *q = &adap->sge.qs[i].rspq; - -		spin_lock_irq(&q->lock); -		spin_unlock_irq(&q->lock); -	} -} - -static void cxgb_vlan_mode(struct net_device *dev, netdev_features_t features) -{ -	struct port_info *pi = netdev_priv(dev); -	struct adapter *adapter = pi->adapter; - -	if (adapter->params.rev > 0) { -		t3_set_vlan_accel(adapter, 1 << pi->port_id, -				  features & NETIF_F_HW_VLAN_RX); -	} else { -		/* single control for all ports */ -		unsigned int i, have_vlans = features & NETIF_F_HW_VLAN_RX; - -		for_each_port(adapter, i) -			have_vlans |= -				adapter->port[i]->features & NETIF_F_HW_VLAN_RX; - -		t3_set_vlan_accel(adapter, 1, have_vlans); -	} -	t3_synchronize_rx(adapter, pi); -} -  static netdev_features_t cxgb_fix_features(struct net_device *dev,  	netdev_features_t features)  { @@ -3353,9 +3356,6 @@ static int __devinit init_one(struct pci_dev *pdev,  	err = sysfs_create_group(&adapter->port[0]->dev.kobj,  				 &cxgb3_attr_group); -	for_each_port(adapter, i) -		cxgb_vlan_mode(adapter->port[i], adapter->port[i]->features); -  	print_port_info(adapter, ai);  	return 0; diff --git a/drivers/net/ethernet/dlink/dl2k.c b/drivers/net/ethernet/dlink/dl2k.c index b2dc2c81a14..2e09edb9cdf 100644 --- a/drivers/net/ethernet/dlink/dl2k.c +++ b/drivers/net/ethernet/dlink/dl2k.c @@ -1259,55 +1259,21 @@ rio_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)  {  	int phy_addr;  	struct netdev_private *np = netdev_priv(dev); -	struct mii_data *miidata = (struct mii_data *) &rq->ifr_ifru; - -	struct netdev_desc *desc; -	int i; +	struct mii_ioctl_data *miidata = if_mii(rq);  	phy_addr = np->phy_addr;  	switch (cmd) { -	case SIOCDEVPRIVATE: -		break; - -	case SIOCDEVPRIVATE + 1: -		miidata->out_value = mii_read (dev, phy_addr, miidata->reg_num); +	case SIOCGMIIPHY: +		miidata->phy_id = phy_addr;  		break; -	case SIOCDEVPRIVATE + 2: -		mii_write (dev, phy_addr, miidata->reg_num, miidata->in_value); +	case SIOCGMIIREG: +		miidata->val_out = mii_read (dev, phy_addr, miidata->reg_num);  		break; -	case SIOCDEVPRIVATE + 3: -		break; -	case SIOCDEVPRIVATE + 4: -		break; -	case SIOCDEVPRIVATE + 5: -		netif_stop_queue (dev); +	case SIOCSMIIREG: +		if (!capable(CAP_NET_ADMIN)) +			return -EPERM; +		mii_write (dev, phy_addr, miidata->reg_num, miidata->val_in);  		break; -	case SIOCDEVPRIVATE + 6: -		netif_wake_queue (dev); -		break; -	case SIOCDEVPRIVATE + 7: -		printk -		    ("tx_full=%x cur_tx=%lx old_tx=%lx cur_rx=%lx old_rx=%lx\n", -		     netif_queue_stopped(dev), np->cur_tx, np->old_tx, np->cur_rx, -		     np->old_rx); -		break; -	case SIOCDEVPRIVATE + 8: -		printk("TX ring:\n"); -		for (i = 0; i < TX_RING_SIZE; i++) { -			desc = &np->tx_ring[i]; -			printk -			    ("%02x:cur:%08x next:%08x status:%08x frag1:%08x frag0:%08x", -			     i, -			     (u32) (np->tx_ring_dma + i * sizeof (*desc)), -			     (u32)le64_to_cpu(desc->next_desc), -			     (u32)le64_to_cpu(desc->status), -			     (u32)(le64_to_cpu(desc->fraginfo) >> 32), -			     (u32)le64_to_cpu(desc->fraginfo)); -			printk ("\n"); -		} -		printk ("\n"); -		break; -  	default:  		return -EOPNOTSUPP;  	} diff --git a/drivers/net/ethernet/dlink/dl2k.h b/drivers/net/ethernet/dlink/dl2k.h index ba0adcafa55..30c2da3de54 100644 --- a/drivers/net/ethernet/dlink/dl2k.h +++ b/drivers/net/ethernet/dlink/dl2k.h @@ -365,13 +365,6 @@ struct ioctl_data {  	char *data;  }; -struct mii_data { -	__u16 reserved; -	__u16 reg_num; -	__u16 in_value; -	__u16 out_value; -}; -  /* The Rx and Tx buffer descriptors. */  struct netdev_desc {  	__le64 next_desc; diff --git a/drivers/net/ethernet/freescale/ucc_geth.c b/drivers/net/ethernet/freescale/ucc_geth.c index 17a46e76123..9ac14f80485 100644 --- a/drivers/net/ethernet/freescale/ucc_geth.c +++ b/drivers/net/ethernet/freescale/ucc_geth.c @@ -116,10 +116,10 @@ static struct ucc_geth_info ugeth_primary_info = {  	.maxGroupAddrInHash = 4,  	.maxIndAddrInHash = 4,  	.prel = 7, -	.maxFrameLength = 1518, +	.maxFrameLength = 1518+16, /* Add extra bytes for VLANs etc. */  	.minFrameLength = 64, -	.maxD1Length = 1520, -	.maxD2Length = 1520, +	.maxD1Length = 1520+16, /* Add extra bytes for VLANs etc. */ +	.maxD2Length = 1520+16, /* Add extra bytes for VLANs etc. */  	.vlantype = 0x8100,  	.ecamptr = ((uint32_t) NULL),  	.eventRegMask = UCCE_OTHER, diff --git a/drivers/net/ethernet/freescale/ucc_geth.h b/drivers/net/ethernet/freescale/ucc_geth.h index 2e395a2566b..f71b3e7b12d 100644 --- a/drivers/net/ethernet/freescale/ucc_geth.h +++ b/drivers/net/ethernet/freescale/ucc_geth.h @@ -877,7 +877,7 @@ struct ucc_geth_hardware_statistics {  /* Driver definitions */  #define TX_BD_RING_LEN                          0x10 -#define RX_BD_RING_LEN                          0x10 +#define RX_BD_RING_LEN                          0x20  #define TX_RING_MOD_MASK(size)                  (size-1)  #define RX_RING_MOD_MASK(size)                  (size-1) diff --git a/drivers/net/ethernet/ibm/ehea/ehea_main.c b/drivers/net/ethernet/ibm/ehea/ehea_main.c index 3516e17a399..c9069a28832 100644 --- a/drivers/net/ethernet/ibm/ehea/ehea_main.c +++ b/drivers/net/ethernet/ibm/ehea/ehea_main.c @@ -290,16 +290,18 @@ static void ehea_update_bcmc_registrations(void)  				arr[i].adh = adapter->handle;  				arr[i].port_id = port->logical_port_id; -				arr[i].reg_type = EHEA_BCMC_SCOPE_ALL | -						  EHEA_BCMC_MULTICAST | +				arr[i].reg_type = EHEA_BCMC_MULTICAST |  						  EHEA_BCMC_UNTAGGED; +				if (mc_entry->macaddr == 0) +					arr[i].reg_type |= EHEA_BCMC_SCOPE_ALL;  				arr[i++].macaddr = mc_entry->macaddr;  				arr[i].adh = adapter->handle;  				arr[i].port_id = port->logical_port_id; -				arr[i].reg_type = EHEA_BCMC_SCOPE_ALL | -						  EHEA_BCMC_MULTICAST | +				arr[i].reg_type = EHEA_BCMC_MULTICAST |  						  EHEA_BCMC_VLANID_ALL; +				if (mc_entry->macaddr == 0) +					arr[i].reg_type |= EHEA_BCMC_SCOPE_ALL;  				arr[i++].macaddr = mc_entry->macaddr;  				num_registrations -= 2;  			} @@ -1838,8 +1840,9 @@ static u64 ehea_multicast_reg_helper(struct ehea_port *port, u64 mc_mac_addr,  	u64 hret;  	u8 reg_type; -	reg_type = EHEA_BCMC_SCOPE_ALL | EHEA_BCMC_MULTICAST -		 | EHEA_BCMC_UNTAGGED; +	reg_type = EHEA_BCMC_MULTICAST | EHEA_BCMC_UNTAGGED; +	if (mc_mac_addr == 0) +		reg_type |= EHEA_BCMC_SCOPE_ALL;  	hret = ehea_h_reg_dereg_bcmc(port->adapter->handle,  				     port->logical_port_id, @@ -1847,8 +1850,9 @@ static u64 ehea_multicast_reg_helper(struct ehea_port *port, u64 mc_mac_addr,  	if (hret)  		goto out; -	reg_type = EHEA_BCMC_SCOPE_ALL | EHEA_BCMC_MULTICAST -		 | EHEA_BCMC_VLANID_ALL; +	reg_type = EHEA_BCMC_MULTICAST | EHEA_BCMC_VLANID_ALL; +	if (mc_mac_addr == 0) +		reg_type |= EHEA_BCMC_SCOPE_ALL;  	hret = ehea_h_reg_dereg_bcmc(port->adapter->handle,  				     port->logical_port_id, @@ -1898,7 +1902,7 @@ static void ehea_allmulti(struct net_device *dev, int enable)  				netdev_err(dev,  					   "failed enabling IFF_ALLMULTI\n");  		} -	} else +	} else {  		if (!enable) {  			/* Disable ALLMULTI */  			hret = ehea_multicast_reg_helper(port, 0, H_DEREG_BCMC); @@ -1908,6 +1912,7 @@ static void ehea_allmulti(struct net_device *dev, int enable)  				netdev_err(dev,  					   "failed disabling IFF_ALLMULTI\n");  		} +	}  }  static void ehea_add_multicast_entry(struct ehea_port *port, u8 *mc_mac_addr) @@ -1941,11 +1946,7 @@ static void ehea_set_multicast_list(struct net_device *dev)  	struct netdev_hw_addr *ha;  	int ret; -	if (port->promisc) { -		ehea_promiscuous(dev, 1); -		return; -	} -	ehea_promiscuous(dev, 0); +	ehea_promiscuous(dev, !!(dev->flags & IFF_PROMISC));  	if (dev->flags & IFF_ALLMULTI) {  		ehea_allmulti(dev, 1); @@ -2463,6 +2464,7 @@ static int ehea_down(struct net_device *dev)  		return 0;  	ehea_drop_multicast_list(dev); +	ehea_allmulti(dev, 0);  	ehea_broadcast_reg_helper(port, H_DEREG_BCMC);  	ehea_free_interrupts(dev); @@ -3261,6 +3263,7 @@ static int __devinit ehea_probe_adapter(struct platform_device *dev,  	struct ehea_adapter *adapter;  	const u64 *adapter_handle;  	int ret; +	int i;  	if (!dev || !dev->dev.of_node) {  		pr_err("Invalid ibmebus device probed\n"); @@ -3314,17 +3317,9 @@ static int __devinit ehea_probe_adapter(struct platform_device *dev,  	tasklet_init(&adapter->neq_tasklet, ehea_neq_tasklet,  		     (unsigned long)adapter); -	ret = ibmebus_request_irq(adapter->neq->attr.ist1, -				  ehea_interrupt_neq, IRQF_DISABLED, -				  "ehea_neq", adapter); -	if (ret) { -		dev_err(&dev->dev, "requesting NEQ IRQ failed\n"); -		goto out_kill_eq; -	} -  	ret = ehea_create_device_sysfs(dev);  	if (ret) -		goto out_free_irq; +		goto out_kill_eq;  	ret = ehea_setup_ports(adapter);  	if (ret) { @@ -3332,15 +3327,28 @@ static int __devinit ehea_probe_adapter(struct platform_device *dev,  		goto out_rem_dev_sysfs;  	} +	ret = ibmebus_request_irq(adapter->neq->attr.ist1, +				  ehea_interrupt_neq, IRQF_DISABLED, +				  "ehea_neq", adapter); +	if (ret) { +		dev_err(&dev->dev, "requesting NEQ IRQ failed\n"); +		goto out_shutdown_ports; +	} + +  	ret = 0;  	goto out; +out_shutdown_ports: +	for (i = 0; i < EHEA_MAX_PORTS; i++) +		if (adapter->port[i]) { +			ehea_shutdown_single_port(adapter->port[i]); +			adapter->port[i] = NULL; +		} +  out_rem_dev_sysfs:  	ehea_remove_device_sysfs(dev); -out_free_irq: -	ibmebus_free_irq(adapter->neq->attr.ist1, adapter); -  out_kill_eq:  	ehea_destroy_eq(adapter->neq); diff --git a/drivers/net/ethernet/ibm/ehea/ehea_phyp.h b/drivers/net/ethernet/ibm/ehea/ehea_phyp.h index 52c456ec4d6..8364815c32f 100644 --- a/drivers/net/ethernet/ibm/ehea/ehea_phyp.h +++ b/drivers/net/ethernet/ibm/ehea/ehea_phyp.h @@ -450,7 +450,7 @@ u64 ehea_h_modify_ehea_port(const u64 adapter_handle, const u16 port_num,  			    void *cb_addr);  #define H_REGBCMC_PN            EHEA_BMASK_IBM(48, 63) -#define H_REGBCMC_REGTYPE       EHEA_BMASK_IBM(61, 63) +#define H_REGBCMC_REGTYPE       EHEA_BMASK_IBM(60, 63)  #define H_REGBCMC_MACADDR       EHEA_BMASK_IBM(16, 63)  #define H_REGBCMC_VLANID        EHEA_BMASK_IBM(52, 63) diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.c b/drivers/net/ethernet/intel/e1000e/ich8lan.c index 64c76443a7a..b461c24945e 100644 --- a/drivers/net/ethernet/intel/e1000e/ich8lan.c +++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c @@ -1310,10 +1310,6 @@ static s32 e1000_oem_bits_config_ich8lan(struct e1000_hw *hw, bool d0_state)  		if (mac_reg & E1000_PHY_CTRL_D0A_LPLU)  			oem_reg |= HV_OEM_BITS_LPLU; - -		/* Set Restart auto-neg to activate the bits */ -		if (!hw->phy.ops.check_reset_block(hw)) -			oem_reg |= HV_OEM_BITS_RESTART_AN;  	} else {  		if (mac_reg & (E1000_PHY_CTRL_GBE_DISABLE |  			       E1000_PHY_CTRL_NOND0A_GBE_DISABLE)) @@ -1324,6 +1320,11 @@ static s32 e1000_oem_bits_config_ich8lan(struct e1000_hw *hw, bool d0_state)  			oem_reg |= HV_OEM_BITS_LPLU;  	} +	/* Set Restart auto-neg to activate the bits */ +	if ((d0_state || (hw->mac.type != e1000_pchlan)) && +	    !hw->phy.ops.check_reset_block(hw)) +		oem_reg |= HV_OEM_BITS_RESTART_AN; +  	ret_val = hw->phy.ops.write_reg_locked(hw, HV_OEM_BITS, oem_reg);  release: @@ -3682,7 +3683,11 @@ void e1000_suspend_workarounds_ich8lan(struct e1000_hw *hw)  	if (hw->mac.type >= e1000_pchlan) {  		e1000_oem_bits_config_ich8lan(hw, false); -		e1000_phy_hw_reset_ich8lan(hw); + +		/* Reset PHY to activate OEM bits on 82577/8 */ +		if (hw->mac.type == e1000_pchlan) +			e1000e_phy_hw_reset_generic(hw); +  		ret_val = hw->phy.ops.acquire(hw);  		if (ret_val)  			return; diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index 19ab2154802..9520a6ac1f3 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -3799,7 +3799,7 @@ static int e1000_test_msi_interrupt(struct e1000_adapter *adapter)  	/* fire an unusual interrupt on the test handler */  	ew32(ICS, E1000_ICS_RXSEQ);  	e1e_flush(); -	msleep(50); +	msleep(100);  	e1000_irq_disable(adapter); diff --git a/drivers/net/ethernet/intel/e1000e/param.c b/drivers/net/ethernet/intel/e1000e/param.c index ff796e42c3e..16adeb9418a 100644 --- a/drivers/net/ethernet/intel/e1000e/param.c +++ b/drivers/net/ethernet/intel/e1000e/param.c @@ -106,7 +106,7 @@ E1000_PARAM(RxAbsIntDelay, "Receive Absolute Interrupt Delay");  /*   * Interrupt Throttle Rate (interrupts/sec)   * - * Valid Range: 100-100000 (0=off, 1=dynamic, 3=dynamic conservative) + * Valid Range: 100-100000 or one of: 0=off, 1=dynamic, 3=dynamic conservative   */  E1000_PARAM(InterruptThrottleRate, "Interrupt Throttling Rate");  #define DEFAULT_ITR 3 @@ -344,53 +344,60 @@ void __devinit e1000e_check_options(struct e1000_adapter *adapter)  		if (num_InterruptThrottleRate > bd) {  			adapter->itr = InterruptThrottleRate[bd]; -			switch (adapter->itr) { -			case 0: -				e_info("%s turned off\n", opt.name); -				break; -			case 1: -				e_info("%s set to dynamic mode\n", opt.name); -				adapter->itr_setting = adapter->itr; -				adapter->itr = 20000; -				break; -			case 3: -				e_info("%s set to dynamic conservative mode\n", -					opt.name); -				adapter->itr_setting = adapter->itr; -				adapter->itr = 20000; -				break; -			case 4: -				e_info("%s set to simplified (2000-8000 ints) " -				       "mode\n", opt.name); -				adapter->itr_setting = 4; -				break; -			default: -				/* -				 * Save the setting, because the dynamic bits -				 * change itr. -				 */ -				if (e1000_validate_option(&adapter->itr, &opt, -							  adapter) && -				    (adapter->itr == 3)) { -					/* -					 * In case of invalid user value, -					 * default to conservative mode. -					 */ -					adapter->itr_setting = adapter->itr; -					adapter->itr = 20000; -				} else { -					/* -					 * Clear the lower two bits because -					 * they are used as control. -					 */ -					adapter->itr_setting = -						adapter->itr & ~3; -				} -				break; -			} + +			/* +			 * Make sure a message is printed for non-special +			 * values.  And in case of an invalid option, display +			 * warning, use default and got through itr/itr_setting +			 * adjustment logic below +			 */ +			if ((adapter->itr > 4) && +			    e1000_validate_option(&adapter->itr, &opt, adapter)) +				adapter->itr = opt.def;  		} else { -			adapter->itr_setting = opt.def; +			/* +			 * If no option specified, use default value and go +			 * through the logic below to adjust itr/itr_setting +			 */ +			adapter->itr = opt.def; + +			/* +			 * Make sure a message is printed for non-special +			 * default values +			 */ +			if (adapter->itr > 40) +				e_info("%s set to default %d\n", opt.name, +				       adapter->itr); +		} + +		adapter->itr_setting = adapter->itr; +		switch (adapter->itr) { +		case 0: +			e_info("%s turned off\n", opt.name); +			break; +		case 1: +			e_info("%s set to dynamic mode\n", opt.name); +			adapter->itr = 20000; +			break; +		case 3: +			e_info("%s set to dynamic conservative mode\n", +			       opt.name);  			adapter->itr = 20000; +			break; +		case 4: +			e_info("%s set to simplified (2000-8000 ints) mode\n", +			       opt.name); +			break; +		default: +			/* +			 * Save the setting, because the dynamic bits +			 * change itr. +			 * +			 * Clear the lower two bits because +			 * they are used as control. +			 */ +			adapter->itr_setting &= ~3; +			break;  		}  	}  	{ /* Interrupt Mode */ diff --git a/drivers/net/ethernet/intel/igbvf/netdev.c b/drivers/net/ethernet/intel/igbvf/netdev.c index d61ca2a732f..8ec74b07f94 100644 --- a/drivers/net/ethernet/intel/igbvf/netdev.c +++ b/drivers/net/ethernet/intel/igbvf/netdev.c @@ -2731,14 +2731,14 @@ static int __devinit igbvf_probe(struct pci_dev *pdev,  			netdev->addr_len);  	} -	if (!is_valid_ether_addr(netdev->perm_addr)) { +	if (!is_valid_ether_addr(netdev->dev_addr)) {  		dev_err(&pdev->dev, "Invalid MAC Address: %pM\n",  		        netdev->dev_addr);  		err = -EIO;  		goto err_hw_init;  	} -	memcpy(netdev->perm_addr, adapter->hw.mac.addr, netdev->addr_len); +	memcpy(netdev->perm_addr, netdev->dev_addr, netdev->addr_len);  	setup_timer(&adapter->watchdog_timer, &igbvf_watchdog,  	            (unsigned long) adapter); diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c index 77ea4b71653..bc07933d67d 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c @@ -437,6 +437,7 @@ int ixgbe_fcoe_ddp(struct ixgbe_adapter *adapter,  	 */  	if ((fh->fh_r_ctl == FC_RCTL_DD_SOL_DATA) &&  	    (fctl & FC_FC_END_SEQ)) { +		skb_linearize(skb);  		crc = (struct fcoe_crc_eof *)skb_put(skb, sizeof(*crc));  		crc->fcoe_eof = FC_EOF_T;  	} diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c index 027d7a75be3..ed1b47dc083 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c @@ -622,6 +622,16 @@ static int ixgbe_alloc_q_vector(struct ixgbe_adapter *adapter, int v_idx,  		if (adapter->hw.mac.type == ixgbe_mac_82599EB)  			set_bit(__IXGBE_RX_CSUM_UDP_ZERO_ERR, &ring->state); +#ifdef IXGBE_FCOE +		if (adapter->netdev->features & NETIF_F_FCOE_MTU) { +			struct ixgbe_ring_feature *f; +			f = &adapter->ring_feature[RING_F_FCOE]; +			if ((rxr_idx >= f->mask) && +			    (rxr_idx < f->mask + f->indices)) +				set_bit(__IXGBE_RX_FCOE_BUFSZ, &ring->state); +		} + +#endif /* IXGBE_FCOE */  		/* apply Rx specific ring traits */  		ring->count = adapter->rx_ring_count;  		ring->queue_index = rxr_idx; diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index 3e26b1f9ac7..88f6b2e9b72 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -3154,14 +3154,6 @@ static void ixgbe_set_rx_buffer_len(struct ixgbe_adapter *adapter)  			set_ring_rsc_enabled(rx_ring);  		else  			clear_ring_rsc_enabled(rx_ring); -#ifdef IXGBE_FCOE -		if (netdev->features & NETIF_F_FCOE_MTU) { -			struct ixgbe_ring_feature *f; -			f = &adapter->ring_feature[RING_F_FCOE]; -			if ((i >= f->mask) && (i < f->mask + f->indices)) -				set_bit(__IXGBE_RX_FCOE_BUFSZ, &rx_ring->state); -		} -#endif /* IXGBE_FCOE */  	}  } @@ -4836,7 +4828,9 @@ static int ixgbe_resume(struct pci_dev *pdev)  	pci_wake_from_d3(pdev, false); +	rtnl_lock();  	err = ixgbe_init_interrupt_scheme(adapter); +	rtnl_unlock();  	if (err) {  		e_dev_err("Cannot initialize interrupts for device\n");  		return err; @@ -4879,10 +4873,6 @@ static int __ixgbe_shutdown(struct pci_dev *pdev, bool *enable_wake)  	}  	ixgbe_clear_interrupt_scheme(adapter); -#ifdef CONFIG_DCB -	kfree(adapter->ixgbe_ieee_pfc); -	kfree(adapter->ixgbe_ieee_ets); -#endif  #ifdef CONFIG_PM  	retval = pci_save_state(pdev); @@ -4893,6 +4883,16 @@ static int __ixgbe_shutdown(struct pci_dev *pdev, bool *enable_wake)  	if (wufc) {  		ixgbe_set_rx_mode(netdev); +		/* +		 * enable the optics for both mult-speed fiber and +		 * 82599 SFP+ fiber as we can WoL. +		 */ +		if (hw->mac.ops.enable_tx_laser && +		    (hw->phy.multispeed_fiber || +		    (hw->mac.ops.get_media_type(hw) == ixgbe_media_type_fiber && +		     hw->mac.type == ixgbe_mac_82599EB))) +			hw->mac.ops.enable_tx_laser(hw); +  		/* turn on all-multi mode if wake on multicast is enabled */  		if (wufc & IXGBE_WUFC_MC) {  			fctrl = IXGBE_READ_REG(hw, IXGBE_FCTRL); @@ -7220,6 +7220,11 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev)  	ixgbe_release_hw_control(adapter); +#ifdef CONFIG_DCB +	kfree(adapter->ixgbe_ieee_pfc); +	kfree(adapter->ixgbe_ieee_ets); + +#endif  	iounmap(adapter->hw.hw_addr);  	pci_release_selected_regions(pdev, pci_select_bars(pdev,  				     IORESOURCE_MEM)); diff --git a/drivers/net/ethernet/marvell/sky2.c b/drivers/net/ethernet/marvell/sky2.c index c9b504e2dfc..487a6c8bd4e 100644 --- a/drivers/net/ethernet/marvell/sky2.c +++ b/drivers/net/ethernet/marvell/sky2.c @@ -2494,8 +2494,13 @@ static struct sk_buff *receive_copy(struct sky2_port *sky2,  		skb_copy_from_linear_data(re->skb, skb->data, length);  		skb->ip_summed = re->skb->ip_summed;  		skb->csum = re->skb->csum; +		skb->rxhash = re->skb->rxhash; +		skb->vlan_tci = re->skb->vlan_tci; +  		pci_dma_sync_single_for_device(sky2->hw->pdev, re->data_addr,  					       length, PCI_DMA_FROMDEVICE); +		re->skb->vlan_tci = 0; +		re->skb->rxhash = 0;  		re->skb->ip_summed = CHECKSUM_NONE;  		skb_put(skb, length);  	} @@ -2580,9 +2585,6 @@ static struct sk_buff *sky2_receive(struct net_device *dev,  	struct sk_buff *skb = NULL;  	u16 count = (status & GMR_FS_LEN) >> 16; -	if (status & GMR_FS_VLAN) -		count -= VLAN_HLEN;	/* Account for vlan tag */ -  	netif_printk(sky2, rx_status, KERN_DEBUG, dev,  		     "rx slot %u status 0x%x len %d\n",  		     sky2->rx_next, status, length); @@ -2590,6 +2592,9 @@ static struct sk_buff *sky2_receive(struct net_device *dev,  	sky2->rx_next = (sky2->rx_next + 1) % sky2->rx_pending;  	prefetch(sky2->rx_ring + sky2->rx_next); +	if (vlan_tx_tag_present(re->skb)) +		count -= VLAN_HLEN;	/* Account for vlan tag */ +  	/* This chip has hardware problems that generates bogus status.  	 * So do only marginal checking and expect higher level protocols  	 * to handle crap frames. @@ -2647,11 +2652,8 @@ static inline void sky2_tx_done(struct net_device *dev, u16 last)  }  static inline void sky2_skb_rx(const struct sky2_port *sky2, -			       u32 status, struct sk_buff *skb) +			       struct sk_buff *skb)  { -	if (status & GMR_FS_VLAN) -		__vlan_hwaccel_put_tag(skb, be16_to_cpu(sky2->rx_tag)); -  	if (skb->ip_summed == CHECKSUM_NONE)  		netif_receive_skb(skb);  	else @@ -2705,6 +2707,14 @@ static void sky2_rx_checksum(struct sky2_port *sky2, u32 status)  	}  } +static void sky2_rx_tag(struct sky2_port *sky2, u16 length) +{ +	struct sk_buff *skb; + +	skb = sky2->rx_ring[sky2->rx_next].skb; +	__vlan_hwaccel_put_tag(skb, be16_to_cpu(length)); +} +  static void sky2_rx_hash(struct sky2_port *sky2, u32 status)  {  	struct sk_buff *skb; @@ -2763,8 +2773,7 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx)  			}  			skb->protocol = eth_type_trans(skb, dev); - -			sky2_skb_rx(sky2, status, skb); +			sky2_skb_rx(sky2, skb);  			/* Stop after net poll weight */  			if (++work_done >= to_do) @@ -2772,11 +2781,11 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx)  			break;  		case OP_RXVLAN: -			sky2->rx_tag = length; +			sky2_rx_tag(sky2, length);  			break;  		case OP_RXCHKSVLAN: -			sky2->rx_tag = length; +			sky2_rx_tag(sky2, length);  			/* fall through */  		case OP_RXCHKS:  			if (likely(dev->features & NETIF_F_RXCSUM)) diff --git a/drivers/net/ethernet/marvell/sky2.h b/drivers/net/ethernet/marvell/sky2.h index ff6f58bf822..3c896ce80b7 100644 --- a/drivers/net/ethernet/marvell/sky2.h +++ b/drivers/net/ethernet/marvell/sky2.h @@ -2241,7 +2241,6 @@ struct sky2_port {  	u16		     rx_pending;  	u16		     rx_data_size;  	u16		     rx_nfrags; -	u16		     rx_tag;  	struct {  		unsigned long last; diff --git a/drivers/net/ethernet/micrel/ks8851.c b/drivers/net/ethernet/micrel/ks8851.c index c722aa607d0..f8dda009d3c 100644 --- a/drivers/net/ethernet/micrel/ks8851.c +++ b/drivers/net/ethernet/micrel/ks8851.c @@ -889,16 +889,17 @@ static int ks8851_net_stop(struct net_device *dev)  	netif_stop_queue(dev);  	mutex_lock(&ks->lock); +	/* turn off the IRQs and ack any outstanding */ +	ks8851_wrreg16(ks, KS_IER, 0x0000); +	ks8851_wrreg16(ks, KS_ISR, 0xffff); +	mutex_unlock(&ks->lock);  	/* stop any outstanding work */  	flush_work(&ks->irq_work);  	flush_work(&ks->tx_work);  	flush_work(&ks->rxctrl_work); -	/* turn off the IRQs and ack any outstanding */ -	ks8851_wrreg16(ks, KS_IER, 0x0000); -	ks8851_wrreg16(ks, KS_ISR, 0xffff); - +	mutex_lock(&ks->lock);  	/* shutdown RX process */  	ks8851_wrreg16(ks, KS_RXCR1, 0x0000); @@ -907,6 +908,7 @@ static int ks8851_net_stop(struct net_device *dev)  	/* set powermode to soft power down to save power */  	ks8851_set_powermode(ks, PMECR_PM_SOFTDOWN); +	mutex_unlock(&ks->lock);  	/* ensure any queued tx buffers are dumped */  	while (!skb_queue_empty(&ks->txq)) { @@ -918,7 +920,6 @@ static int ks8851_net_stop(struct net_device *dev)  		dev_kfree_skb(txb);  	} -	mutex_unlock(&ks->lock);  	return 0;  } @@ -1418,6 +1419,7 @@ static int __devinit ks8851_probe(struct spi_device *spi)  	struct net_device *ndev;  	struct ks8851_net *ks;  	int ret; +	unsigned cider;  	ndev = alloc_etherdev(sizeof(struct ks8851_net));  	if (!ndev) @@ -1484,8 +1486,8 @@ static int __devinit ks8851_probe(struct spi_device *spi)  	ks8851_soft_reset(ks, GRR_GSR);  	/* simple check for a valid chip being connected to the bus */ - -	if ((ks8851_rdreg16(ks, KS_CIDER) & ~CIDER_REV_MASK) != CIDER_ID) { +	cider = ks8851_rdreg16(ks, KS_CIDER); +	if ((cider & ~CIDER_REV_MASK) != CIDER_ID) {  		dev_err(&spi->dev, "failed to read device ID\n");  		ret = -ENODEV;  		goto err_id; @@ -1516,15 +1518,14 @@ static int __devinit ks8851_probe(struct spi_device *spi)  	}  	netdev_info(ndev, "revision %d, MAC %pM, IRQ %d, %s EEPROM\n", -		    CIDER_REV_GET(ks8851_rdreg16(ks, KS_CIDER)), -		    ndev->dev_addr, ndev->irq, +		    CIDER_REV_GET(cider), ndev->dev_addr, ndev->irq,  		    ks->rc_ccr & CCR_EEPROM ? "has" : "no");  	return 0;  err_netdev: -	free_irq(ndev->irq, ndev); +	free_irq(ndev->irq, ks);  err_id:  err_irq: diff --git a/drivers/net/ethernet/micrel/ks8851_mll.c b/drivers/net/ethernet/micrel/ks8851_mll.c index b8104d9f408..5ffde23ac8f 100644 --- a/drivers/net/ethernet/micrel/ks8851_mll.c +++ b/drivers/net/ethernet/micrel/ks8851_mll.c @@ -40,7 +40,7 @@  #define	DRV_NAME	"ks8851_mll"  static u8 KS_DEFAULT_MAC_ADDRESS[] = { 0x00, 0x10, 0xA1, 0x86, 0x95, 0x11 }; -#define MAX_RECV_FRAMES			32 +#define MAX_RECV_FRAMES			255  #define MAX_BUF_SIZE			2048  #define TX_BUF_SIZE			2000  #define RX_BUF_SIZE			2000 diff --git a/drivers/net/ethernet/micrel/ksz884x.c b/drivers/net/ethernet/micrel/ksz884x.c index ef723b185d8..eaf9ff0262a 100644 --- a/drivers/net/ethernet/micrel/ksz884x.c +++ b/drivers/net/ethernet/micrel/ksz884x.c @@ -5675,7 +5675,7 @@ static int netdev_set_mac_address(struct net_device *dev, void *addr)  		memcpy(hw->override_addr, mac->sa_data, ETH_ALEN);  	} -	memcpy(dev->dev_addr, mac->sa_data, MAX_ADDR_LEN); +	memcpy(dev->dev_addr, mac->sa_data, ETH_ALEN);  	interrupt = hw_block_intr(hw); diff --git a/drivers/net/ethernet/realtek/8139cp.c b/drivers/net/ethernet/realtek/8139cp.c index abc79076f86..b3287c0fe27 100644 --- a/drivers/net/ethernet/realtek/8139cp.c +++ b/drivers/net/ethernet/realtek/8139cp.c @@ -958,6 +958,11 @@ static inline void cp_start_hw (struct cp_private *cp)  	cpw8(Cmd, RxOn | TxOn);  } +static void cp_enable_irq(struct cp_private *cp) +{ +	cpw16_f(IntrMask, cp_intr_mask); +} +  static void cp_init_hw (struct cp_private *cp)  {  	struct net_device *dev = cp->dev; @@ -997,8 +1002,6 @@ static void cp_init_hw (struct cp_private *cp)  	cpw16(MultiIntr, 0); -	cpw16_f(IntrMask, cp_intr_mask); -  	cpw8_f(Cfg9346, Cfg9346_Lock);  } @@ -1130,6 +1133,8 @@ static int cp_open (struct net_device *dev)  	if (rc)  		goto err_out_hw; +	cp_enable_irq(cp); +  	netif_carrier_off(dev);  	mii_check_media(&cp->mii_if, netif_msg_link(cp), true);  	netif_start_queue(dev); @@ -2031,6 +2036,7 @@ static int cp_resume (struct pci_dev *pdev)  	/* FIXME: sh*t may happen if the Rx ring buffer is depleted */  	cp_init_rings_index (cp);  	cp_init_hw (cp); +	cp_enable_irq(cp);  	netif_start_queue (dev);  	spin_lock_irqsave (&cp->lock, flags); diff --git a/drivers/net/ethernet/smsc/smsc911x.c b/drivers/net/ethernet/smsc/smsc911x.c index 4a697102707..cd3defb11ff 100644 --- a/drivers/net/ethernet/smsc/smsc911x.c +++ b/drivers/net/ethernet/smsc/smsc911x.c @@ -1166,10 +1166,8 @@ smsc911x_rx_counterrors(struct net_device *dev, unsigned int rxstat)  /* Quickly dumps bad packets */  static void -smsc911x_rx_fastforward(struct smsc911x_data *pdata, unsigned int pktbytes) +smsc911x_rx_fastforward(struct smsc911x_data *pdata, unsigned int pktwords)  { -	unsigned int pktwords = (pktbytes + NET_IP_ALIGN + 3) >> 2; -  	if (likely(pktwords >= 4)) {  		unsigned int timeout = 500;  		unsigned int val; @@ -1233,7 +1231,7 @@ static int smsc911x_poll(struct napi_struct *napi, int budget)  			continue;  		} -		skb = netdev_alloc_skb(dev, pktlength + NET_IP_ALIGN); +		skb = netdev_alloc_skb(dev, pktwords << 2);  		if (unlikely(!skb)) {  			SMSC_WARN(pdata, rx_err,  				  "Unable to allocate skb for rx packet"); @@ -1243,14 +1241,12 @@ static int smsc911x_poll(struct napi_struct *napi, int budget)  			break;  		} -		skb->data = skb->head; -		skb_reset_tail_pointer(skb); +		pdata->ops->rx_readfifo(pdata, +				 (unsigned int *)skb->data, pktwords);  		/* Align IP on 16B boundary */  		skb_reserve(skb, NET_IP_ALIGN);  		skb_put(skb, pktlength - 4); -		pdata->ops->rx_readfifo(pdata, -				 (unsigned int *)skb->head, pktwords);  		skb->protocol = eth_type_trans(skb, dev);  		skb_checksum_none_assert(skb);  		netif_receive_skb(skb); @@ -1565,7 +1561,7 @@ static int smsc911x_open(struct net_device *dev)  	smsc911x_reg_write(pdata, FIFO_INT, temp);  	/* set RX Data offset to 2 bytes for alignment */ -	smsc911x_reg_write(pdata, RX_CFG, (2 << 8)); +	smsc911x_reg_write(pdata, RX_CFG, (NET_IP_ALIGN << 8));  	/* enable NAPI polling before enabling RX interrupts */  	napi_enable(&pdata->napi); @@ -2382,7 +2378,6 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev)  	SET_NETDEV_DEV(dev, &pdev->dev);  	pdata = netdev_priv(dev); -  	dev->irq = irq_res->start;  	irq_flags = irq_res->flags & IRQF_TRIGGER_MASK;  	pdata->ioaddr = ioremap_nocache(res->start, res_size); @@ -2446,7 +2441,7 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev)  	if (retval) {  		SMSC_WARN(pdata, probe,  			  "Unable to claim requested irq: %d", dev->irq); -		goto out_free_irq; +		goto out_disable_resources;  	}  	retval = register_netdev(dev); diff --git a/drivers/net/ethernet/sun/sungem.c b/drivers/net/ethernet/sun/sungem.c index 558409ff405..4ba96909671 100644 --- a/drivers/net/ethernet/sun/sungem.c +++ b/drivers/net/ethernet/sun/sungem.c @@ -2339,7 +2339,7 @@ static int gem_suspend(struct pci_dev *pdev, pm_message_t state)  	netif_device_detach(dev);  	/* Switch off chip, remember WOL setting */ -	gp->asleep_wol = gp->wake_on_lan; +	gp->asleep_wol = !!gp->wake_on_lan;  	gem_do_stop(dev, gp->asleep_wol);  	/* Unlock the network stack */ diff --git a/drivers/net/ethernet/ti/davinci_emac.c b/drivers/net/ethernet/ti/davinci_emac.c index 174a3348f67..08aff1a2087 100644 --- a/drivers/net/ethernet/ti/davinci_emac.c +++ b/drivers/net/ethernet/ti/davinci_emac.c @@ -1511,7 +1511,7 @@ static int emac_devioctl(struct net_device *ndev, struct ifreq *ifrq, int cmd)  static int match_first_device(struct device *dev, void *data)  { -	return 1; +	return !strncmp(dev_name(dev), "davinci_mdio", 12);  }  /** diff --git a/drivers/net/ethernet/ti/davinci_mdio.c b/drivers/net/ethernet/ti/davinci_mdio.c index 2757c7d6e63..e4e47088e26 100644 --- a/drivers/net/ethernet/ti/davinci_mdio.c +++ b/drivers/net/ethernet/ti/davinci_mdio.c @@ -181,6 +181,11 @@ static inline int wait_for_user_access(struct davinci_mdio_data *data)  		__davinci_mdio_reset(data);  		return -EAGAIN;  	} + +	reg = __raw_readl(®s->user[0].access); +	if ((reg & USERACCESS_GO) == 0) +		return 0; +  	dev_err(data->dev, "timed out waiting for user access\n");  	return -ETIMEDOUT;  } diff --git a/drivers/net/ethernet/ti/tlan.c b/drivers/net/ethernet/ti/tlan.c index 817ad3bc495..efd36691ce5 100644 --- a/drivers/net/ethernet/ti/tlan.c +++ b/drivers/net/ethernet/ti/tlan.c @@ -228,7 +228,7 @@ tlan_get_skb(const struct tlan_list *tag)  	unsigned long addr;  	addr = tag->buffer[9].address; -	addr |= (tag->buffer[8].address << 16) << 16; +	addr |= ((unsigned long) tag->buffer[8].address << 16) << 16;  	return (struct sk_buff *) addr;  } diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet.h b/drivers/net/ethernet/xilinx/xilinx_axienet.h index cc83af083fd..44b8d2bad8c 100644 --- a/drivers/net/ethernet/xilinx/xilinx_axienet.h +++ b/drivers/net/ethernet/xilinx/xilinx_axienet.h @@ -2,9 +2,7 @@   * Definitions for Xilinx Axi Ethernet device driver.   *   * Copyright (c) 2009 Secret Lab Technologies, Ltd. - * Copyright (c) 2010 Xilinx, Inc. All rights reserved. - * Copyright (c) 2012 Daniel Borkmann, <daniel.borkmann@tik.ee.ethz.ch> - * Copyright (c) 2012 Ariane Keller, <ariane.keller@tik.ee.ethz.ch> + * Copyright (c) 2010 - 2012 Xilinx, Inc. All rights reserved.   */  #ifndef XILINX_AXIENET_H diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c index 2fcbeba6814..9c365e192a3 100644 --- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c +++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c @@ -4,9 +4,9 @@   * Copyright (c) 2008 Nissin Systems Co., Ltd.,  Yoshio Kashiwagi   * Copyright (c) 2005-2008 DLA Systems,  David H. Lynch Jr. <dhlii@dlasys.net>   * Copyright (c) 2008-2009 Secret Lab Technologies Ltd. - * Copyright (c) 2010 Xilinx, Inc. All rights reserved. - * Copyright (c) 2012 Daniel Borkmann, <daniel.borkmann@tik.ee.ethz.ch> - * Copyright (c) 2012 Ariane Keller, <ariane.keller@tik.ee.ethz.ch> + * Copyright (c) 2010 - 2011 Michal Simek <monstr@monstr.eu> + * Copyright (c) 2010 - 2011 PetaLogix + * Copyright (c) 2010 - 2012 Xilinx, Inc. All rights reserved.   *   * This is a driver for the Xilinx Axi Ethernet which is used in the Virtex6   * and Spartan6. diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c b/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c index d70b6e79f6c..e90e1f46121 100644 --- a/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c +++ b/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c @@ -2,9 +2,9 @@   * MDIO bus driver for the Xilinx Axi Ethernet device   *   * Copyright (c) 2009 Secret Lab Technologies, Ltd. - * Copyright (c) 2010 Xilinx, Inc. All rights reserved. - * Copyright (c) 2012 Daniel Borkmann, <daniel.borkmann@tik.ee.ethz.ch> - * Copyright (c) 2012 Ariane Keller, <ariane.keller@tik.ee.ethz.ch> + * Copyright (c) 2010 - 2011 Michal Simek <monstr@monstr.eu> + * Copyright (c) 2010 - 2011 PetaLogix + * Copyright (c) 2010 - 2012 Xilinx, Inc. All rights reserved.   */  #include <linux/of_address.h> diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c index dd294783b5c..2d59138db7f 100644 --- a/drivers/net/hyperv/netvsc_drv.c +++ b/drivers/net/hyperv/netvsc_drv.c @@ -44,6 +44,7 @@ struct net_device_context {  	/* point back to our device context */  	struct hv_device *device_ctx;  	struct delayed_work dwork; +	struct work_struct work;  }; @@ -51,30 +52,22 @@ static int ring_size = 128;  module_param(ring_size, int, S_IRUGO);  MODULE_PARM_DESC(ring_size, "Ring buffer size (# of pages)"); -struct set_multicast_work { -	struct work_struct work; -	struct net_device *net; -}; -  static void do_set_multicast(struct work_struct *w)  { -	struct set_multicast_work *swk = -		container_of(w, struct set_multicast_work, work); -	struct net_device *net = swk->net; - -	struct net_device_context *ndevctx = netdev_priv(net); +	struct net_device_context *ndevctx = +		container_of(w, struct net_device_context, work);  	struct netvsc_device *nvdev;  	struct rndis_device *rdev;  	nvdev = hv_get_drvdata(ndevctx->device_ctx); -	if (nvdev == NULL) -		goto out; +	if (nvdev == NULL || nvdev->ndev == NULL) +		return;  	rdev = nvdev->extension;  	if (rdev == NULL) -		goto out; +		return; -	if (net->flags & IFF_PROMISC) +	if (nvdev->ndev->flags & IFF_PROMISC)  		rndis_filter_set_packet_filter(rdev,  			NDIS_PACKET_TYPE_PROMISCUOUS);  	else @@ -82,21 +75,13 @@ static void do_set_multicast(struct work_struct *w)  			NDIS_PACKET_TYPE_BROADCAST |  			NDIS_PACKET_TYPE_ALL_MULTICAST |  			NDIS_PACKET_TYPE_DIRECTED); - -out: -	kfree(w);  }  static void netvsc_set_multicast_list(struct net_device *net)  { -	struct set_multicast_work *swk = -		kmalloc(sizeof(struct set_multicast_work), GFP_ATOMIC); -	if (swk == NULL) -		return; +	struct net_device_context *net_device_ctx = netdev_priv(net); -	swk->net = net; -	INIT_WORK(&swk->work, do_set_multicast); -	schedule_work(&swk->work); +	schedule_work(&net_device_ctx->work);  }  static int netvsc_open(struct net_device *net) @@ -125,6 +110,8 @@ static int netvsc_close(struct net_device *net)  	netif_tx_disable(net); +	/* Make sure netvsc_set_multicast_list doesn't re-enable filter! */ +	cancel_work_sync(&net_device_ctx->work);  	ret = rndis_filter_close(device_obj);  	if (ret != 0)  		netdev_err(net, "unable to close device (ret %d).\n", ret); @@ -335,6 +322,7 @@ static int netvsc_change_mtu(struct net_device *ndev, int mtu)  	nvdev->start_remove = true;  	cancel_delayed_work_sync(&ndevctx->dwork); +	cancel_work_sync(&ndevctx->work);  	netif_tx_disable(ndev);  	rndis_filter_device_remove(hdev); @@ -403,6 +391,7 @@ static int netvsc_probe(struct hv_device *dev,  	net_device_ctx->device_ctx = dev;  	hv_set_drvdata(dev, net);  	INIT_DELAYED_WORK(&net_device_ctx->dwork, netvsc_send_garp); +	INIT_WORK(&net_device_ctx->work, do_set_multicast);  	net->netdev_ops = &device_ops; @@ -456,6 +445,7 @@ static int netvsc_remove(struct hv_device *dev)  	ndev_ctx = netdev_priv(net);  	cancel_delayed_work_sync(&ndev_ctx->dwork); +	cancel_work_sync(&ndev_ctx->work);  	/* Stop outbound asap */  	netif_tx_disable(net); diff --git a/drivers/net/phy/icplus.c b/drivers/net/phy/icplus.c index f08c85acf76..5ac46f5226f 100644 --- a/drivers/net/phy/icplus.c +++ b/drivers/net/phy/icplus.c @@ -40,6 +40,7 @@ MODULE_LICENSE("GPL");  #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 */  static int ip175c_config_init(struct phy_device *phydev)  { @@ -185,6 +186,15 @@ static int ip175c_config_aneg(struct phy_device *phydev)  	return 0;  } +static int ip101a_g_ack_interrupt(struct phy_device *phydev) +{ +	int err = phy_read(phydev, IP101A_G_IRQ_CONF_STATUS); +	if (err < 0) +		return err; + +	return 0; +} +  static struct phy_driver ip175c_driver = {  	.phy_id		= 0x02430d80,  	.name		= "ICPlus IP175C", @@ -204,7 +214,6 @@ static struct phy_driver ip1001_driver = {  	.phy_id_mask	= 0x0ffffff0,  	.features	= PHY_GBIT_FEATURES | SUPPORTED_Pause |  			  SUPPORTED_Asym_Pause, -	.flags		= PHY_HAS_INTERRUPT,  	.config_init	= &ip1001_config_init,  	.config_aneg	= &genphy_config_aneg,  	.read_status	= &genphy_read_status, @@ -220,6 +229,7 @@ static struct phy_driver ip101a_g_driver = {  	.features	= PHY_BASIC_FEATURES | SUPPORTED_Pause |  			  SUPPORTED_Asym_Pause,  	.flags		= PHY_HAS_INTERRUPT, +	.ack_interrupt	= ip101a_g_ack_interrupt,  	.config_init	= &ip101a_g_config_init,  	.config_aneg	= &genphy_config_aneg,  	.read_status	= &genphy_read_status, diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c index 33f8c51968b..21d7151fb0a 100644 --- a/drivers/net/ppp/ppp_generic.c +++ b/drivers/net/ppp/ppp_generic.c @@ -235,7 +235,7 @@ struct ppp_net {  /* Prototypes. */  static int ppp_unattached_ioctl(struct net *net, struct ppp_file *pf,  			struct file *file, unsigned int cmd, unsigned long arg); -static int ppp_xmit_process(struct ppp *ppp); +static void ppp_xmit_process(struct ppp *ppp);  static void ppp_send_frame(struct ppp *ppp, struct sk_buff *skb);  static void ppp_push(struct ppp *ppp);  static void ppp_channel_push(struct channel *pch); @@ -969,8 +969,7 @@ ppp_start_xmit(struct sk_buff *skb, struct net_device *dev)  	put_unaligned_be16(proto, pp);  	skb_queue_tail(&ppp->file.xq, skb); -	if (!ppp_xmit_process(ppp)) -		netif_stop_queue(dev); +	ppp_xmit_process(ppp);  	return NETDEV_TX_OK;   outf: @@ -1048,11 +1047,10 @@ static void ppp_setup(struct net_device *dev)   * Called to do any work queued up on the transmit side   * that can now be done.   */ -static int +static void  ppp_xmit_process(struct ppp *ppp)  {  	struct sk_buff *skb; -	int ret = 0;  	ppp_xmit_lock(ppp);  	if (!ppp->closing) { @@ -1062,13 +1060,12 @@ ppp_xmit_process(struct ppp *ppp)  			ppp_send_frame(ppp, skb);  		/* If there's no work left to do, tell the core net  		   code that we can accept some more. */ -		if (!ppp->xmit_pending && !skb_peek(&ppp->file.xq)) { +		if (!ppp->xmit_pending && !skb_peek(&ppp->file.xq))  			netif_wake_queue(ppp->dev); -			ret = 1; -		} +		else +			netif_stop_queue(ppp->dev);  	}  	ppp_xmit_unlock(ppp); -	return ret;  }  static inline struct sk_buff * diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c index 5ee032cafad..42b5151aa78 100644 --- a/drivers/net/usb/asix.c +++ b/drivers/net/usb/asix.c @@ -355,7 +355,7 @@ static struct sk_buff *asix_tx_fixup(struct usbnet *dev, struct sk_buff *skb,  	u32 packet_len;  	u32 padbytes = 0xffff0000; -	padlen = ((skb->len + 4) % 512) ? 0 : 4; +	padlen = ((skb->len + 4) & (dev->maxpacket - 1)) ? 0 : 4;  	if ((!skb_cloned(skb)) &&  	    ((headroom + tailroom) >= (4 + padlen))) { @@ -377,7 +377,7 @@ static struct sk_buff *asix_tx_fixup(struct usbnet *dev, struct sk_buff *skb,  	cpu_to_le32s(&packet_len);  	skb_copy_to_linear_data(skb, &packet_len, sizeof(packet_len)); -	if ((skb->len % 512) == 0) { +	if (padlen) {  		cpu_to_le32s(&padbytes);  		memcpy(skb_tail_pointer(skb), &padbytes, sizeof(padbytes));  		skb_put(skb, sizeof(padbytes)); diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index 552d24bf862..d316503b35d 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c @@ -365,6 +365,27 @@ static const struct driver_info	qmi_wwan_force_int4 = {  	.data		= BIT(4), /* interface whitelist bitmap */  }; +/* Sierra Wireless provide equally useless interface descriptors + * Devices in QMI mode can be switched between two different + * configurations: + *   a) USB interface #8 is QMI/wwan + *   b) USB interfaces #8, #19 and #20 are QMI/wwan + * + * Both configurations provide a number of other interfaces (serial++), + * some of which have the same endpoint configuration as we expect, so + * a whitelist or blacklist is necessary. + * + * FIXME: The below whitelist should include BIT(20).  It does not + * because I cannot get it to work... + */ +static const struct driver_info	qmi_wwan_sierra = { +	.description	= "Sierra Wireless wwan/QMI device", +	.flags		= FLAG_WWAN, +	.bind		= qmi_wwan_bind_gobi, +	.unbind		= qmi_wwan_unbind_shared, +	.manage_power	= qmi_wwan_manage_power, +	.data		= BIT(8) | BIT(19), /* interface whitelist bitmap */ +};  #define HUAWEI_VENDOR_ID	0x12D1  #define QMI_GOBI_DEVICE(vend, prod) \ @@ -445,6 +466,15 @@ static const struct usb_device_id products[] = {  		.bInterfaceProtocol = 0xff,  		.driver_info        = (unsigned long)&qmi_wwan_force_int4,  	}, +	{	/* Sierra Wireless MC77xx in QMI mode */ +		.match_flags	    = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, +		.idVendor           = 0x1199, +		.idProduct          = 0x68a2, +		.bInterfaceClass    = 0xff, +		.bInterfaceSubClass = 0xff, +		.bInterfaceProtocol = 0xff, +		.driver_info        = (unsigned long)&qmi_wwan_sierra, +	},  	{QMI_GOBI_DEVICE(0x05c6, 0x9212)},	/* Acer Gobi Modem Device */  	{QMI_GOBI_DEVICE(0x03f0, 0x1f1d)},	/* HP un2400 Gobi Modem Device */  	{QMI_GOBI_DEVICE(0x03f0, 0x371d)},	/* HP un2430 Mobile Broadband Module */ diff --git a/drivers/net/usb/smsc75xx.c b/drivers/net/usb/smsc75xx.c index 187d01ccb97..00103a8c5e0 100644 --- a/drivers/net/usb/smsc75xx.c +++ b/drivers/net/usb/smsc75xx.c @@ -98,7 +98,7 @@ static int __must_check smsc75xx_read_reg(struct usbnet *dev, u32 index,  	if (unlikely(ret < 0))  		netdev_warn(dev->net, -			"Failed to read register index 0x%08x", index); +			"Failed to read reg index 0x%08x: %d", index, ret);  	le32_to_cpus(buf);  	*data = *buf; @@ -128,7 +128,7 @@ static int __must_check smsc75xx_write_reg(struct usbnet *dev, u32 index,  	if (unlikely(ret < 0))  		netdev_warn(dev->net, -			"Failed to write register index 0x%08x", index); +			"Failed to write reg index 0x%08x: %d", index, ret);  	kfree(buf); @@ -171,7 +171,7 @@ static int smsc75xx_mdio_read(struct net_device *netdev, int phy_id, int idx)  	idx &= dev->mii.reg_num_mask;  	addr = ((phy_id << MII_ACCESS_PHY_ADDR_SHIFT) & MII_ACCESS_PHY_ADDR)  		| ((idx << MII_ACCESS_REG_ADDR_SHIFT) & MII_ACCESS_REG_ADDR) -		| MII_ACCESS_READ; +		| MII_ACCESS_READ | MII_ACCESS_BUSY;  	ret = smsc75xx_write_reg(dev, MII_ACCESS, addr);  	check_warn_goto_done(ret, "Error writing MII_ACCESS"); @@ -210,7 +210,7 @@ static void smsc75xx_mdio_write(struct net_device *netdev, int phy_id, int idx,  	idx &= dev->mii.reg_num_mask;  	addr = ((phy_id << MII_ACCESS_PHY_ADDR_SHIFT) & MII_ACCESS_PHY_ADDR)  		| ((idx << MII_ACCESS_REG_ADDR_SHIFT) & MII_ACCESS_REG_ADDR) -		| MII_ACCESS_WRITE; +		| MII_ACCESS_WRITE | MII_ACCESS_BUSY;  	ret = smsc75xx_write_reg(dev, MII_ACCESS, addr);  	check_warn_goto_done(ret, "Error writing MII_ACCESS"); @@ -508,9 +508,10 @@ static int smsc75xx_link_reset(struct usbnet *dev)  	u16 lcladv, rmtadv;  	int ret; -	/* clear interrupt status */ +	/* read and write to clear phy interrupt status */  	ret = smsc75xx_mdio_read(dev->net, mii->phy_id, PHY_INT_SRC);  	check_warn_return(ret, "Error reading PHY_INT_SRC"); +	smsc75xx_mdio_write(dev->net, mii->phy_id, PHY_INT_SRC, 0xffff);  	ret = smsc75xx_write_reg(dev, INT_STS, INT_STS_CLEAR_ALL);  	check_warn_return(ret, "Error writing INT_STS"); @@ -643,7 +644,7 @@ static int smsc75xx_set_mac_address(struct usbnet *dev)  static int smsc75xx_phy_initialize(struct usbnet *dev)  { -	int bmcr, timeout = 0; +	int bmcr, ret, timeout = 0;  	/* Initialize MII structure */  	dev->mii.dev = dev->net; @@ -651,6 +652,7 @@ static int smsc75xx_phy_initialize(struct usbnet *dev)  	dev->mii.mdio_write = smsc75xx_mdio_write;  	dev->mii.phy_id_mask = 0x1f;  	dev->mii.reg_num_mask = 0x1f; +	dev->mii.supports_gmii = 1;  	dev->mii.phy_id = SMSC75XX_INTERNAL_PHY_ID;  	/* reset phy and wait for reset to complete */ @@ -661,7 +663,7 @@ static int smsc75xx_phy_initialize(struct usbnet *dev)  		bmcr = smsc75xx_mdio_read(dev->net, dev->mii.phy_id, MII_BMCR);  		check_warn_return(bmcr, "Error reading MII_BMCR");  		timeout++; -	} while ((bmcr & MII_BMCR) && (timeout < 100)); +	} while ((bmcr & BMCR_RESET) && (timeout < 100));  	if (timeout >= 100) {  		netdev_warn(dev->net, "timeout on PHY Reset"); @@ -671,10 +673,13 @@ static int smsc75xx_phy_initialize(struct usbnet *dev)  	smsc75xx_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE,  		ADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP |  		ADVERTISE_PAUSE_ASYM); +	smsc75xx_mdio_write(dev->net, dev->mii.phy_id, MII_CTRL1000, +		ADVERTISE_1000FULL); -	/* read to clear */ -	smsc75xx_mdio_read(dev->net, dev->mii.phy_id, PHY_INT_SRC); -	check_warn_return(bmcr, "Error reading PHY_INT_SRC"); +	/* read and write to clear phy interrupt status */ +	ret = smsc75xx_mdio_read(dev->net, dev->mii.phy_id, PHY_INT_SRC); +	check_warn_return(ret, "Error reading PHY_INT_SRC"); +	smsc75xx_mdio_write(dev->net, dev->mii.phy_id, PHY_INT_SRC, 0xffff);  	smsc75xx_mdio_write(dev->net, dev->mii.phy_id, PHY_INT_MASK,  		PHY_INT_MASK_DEFAULT); @@ -946,6 +951,14 @@ static int smsc75xx_reset(struct usbnet *dev)  	ret = smsc75xx_write_reg(dev, INT_EP_CTL, buf);  	check_warn_return(ret, "Failed to write INT_EP_CTL: %d", ret); +	/* allow mac to detect speed and duplex from phy */ +	ret = smsc75xx_read_reg(dev, MAC_CR, &buf); +	check_warn_return(ret, "Failed to read MAC_CR: %d", ret); + +	buf |= (MAC_CR_ADD | MAC_CR_ASD); +	ret = smsc75xx_write_reg(dev, MAC_CR, buf); +	check_warn_return(ret, "Failed to write MAC_CR: %d", ret); +  	ret = smsc75xx_read_reg(dev, MAC_TX, &buf);  	check_warn_return(ret, "Failed to read MAC_TX: %d", ret); @@ -1051,6 +1064,7 @@ static int smsc75xx_bind(struct usbnet *dev, struct usb_interface *intf)  	dev->net->ethtool_ops = &smsc75xx_ethtool_ops;  	dev->net->flags |= IFF_MULTICAST;  	dev->net->hard_header_len += SMSC75XX_TX_OVERHEAD; +	dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len;  	return 0;  } @@ -1211,7 +1225,7 @@ static const struct driver_info smsc75xx_info = {  	.rx_fixup	= smsc75xx_rx_fixup,  	.tx_fixup	= smsc75xx_tx_fixup,  	.status		= smsc75xx_status, -	.flags		= FLAG_ETHER | FLAG_SEND_ZLP, +	.flags		= FLAG_ETHER | FLAG_SEND_ZLP | FLAG_LINK_INTR,  };  static const struct usb_device_id products[] = { diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c index 5f19f84d349..94ae66999f5 100644 --- a/drivers/net/usb/smsc95xx.c +++ b/drivers/net/usb/smsc95xx.c @@ -1017,6 +1017,7 @@ static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf)  	dev->net->ethtool_ops = &smsc95xx_ethtool_ops;  	dev->net->flags |= IFF_MULTICAST;  	dev->net->hard_header_len += SMSC95XX_TX_OVERHEAD_CSUM; +	dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len;  	return 0;  } @@ -1191,7 +1192,7 @@ static const struct driver_info smsc95xx_info = {  	.rx_fixup	= smsc95xx_rx_fixup,  	.tx_fixup	= smsc95xx_tx_fixup,  	.status		= smsc95xx_status, -	.flags		= FLAG_ETHER | FLAG_SEND_ZLP, +	.flags		= FLAG_ETHER | FLAG_SEND_ZLP | FLAG_LINK_INTR,  };  static const struct usb_device_id products[] = { diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index b7b3f5b0d40..2d927fb4adf 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -210,6 +210,7 @@ static int init_status (struct usbnet *dev, struct usb_interface *intf)  		} else {  			usb_fill_int_urb(dev->interrupt, dev->udev, pipe,  				buf, maxp, intr_complete, dev, period); +			dev->interrupt->transfer_flags |= URB_FREE_BUFFER;  			dev_dbg(&intf->dev,  				"status ep%din, %d bytes period %d\n",  				usb_pipeendpoint(pipe), maxp, period); @@ -1443,7 +1444,7 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)  	status = register_netdev (net);  	if (status) -		goto out3; +		goto out4;  	netif_info(dev, probe, dev->net,  		   "register '%s' at usb-%s-%s, %s, %pM\n",  		   udev->dev.driver->name, @@ -1461,6 +1462,8 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)  	return 0; +out4: +	usb_free_urb(dev->interrupt);  out3:  	if (info->unbind)  		info->unbind (dev, udev); diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 4de2760c593..af8acc85f4b 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -626,16 +626,15 @@ static netdev_tx_t start_xmit(struct sk_buff *skb, struct net_device *dev)  	/* This can happen with OOM and indirect buffers. */  	if (unlikely(capacity < 0)) {  		if (likely(capacity == -ENOMEM)) { -			if (net_ratelimit()) { +			if (net_ratelimit())  				dev_warn(&dev->dev,  					 "TX queue failure: out of memory\n"); -			} else { +		} else {  			dev->stats.tx_fifo_errors++;  			if (net_ratelimit())  				dev_warn(&dev->dev,  					 "Unexpected TX queue failure: %d\n",  					 capacity); -			}  		}  		dev->stats.tx_dropped++;  		kfree_skb(skb); diff --git a/drivers/net/wan/farsync.c b/drivers/net/wan/farsync.c index ebb9f24eefb..1a623183cbe 100644 --- a/drivers/net/wan/farsync.c +++ b/drivers/net/wan/farsync.c @@ -2483,6 +2483,7 @@ fst_add_one(struct pci_dev *pdev, const struct pci_device_id *ent)  		pr_err("Control memory remap failed\n");  		pci_release_regions(pdev);  		pci_disable_device(pdev); +		iounmap(card->mem);  		kfree(card);  		return -ENODEV;  	} diff --git a/drivers/net/wireless/ath/ath5k/ahb.c b/drivers/net/wireless/ath/ath5k/ahb.c index 8faa129da5a..aec33cc207f 100644 --- a/drivers/net/wireless/ath/ath5k/ahb.c +++ b/drivers/net/wireless/ath/ath5k/ahb.c @@ -19,6 +19,7 @@  #include <linux/nl80211.h>  #include <linux/platform_device.h>  #include <linux/etherdevice.h> +#include <linux/export.h>  #include <ar231x_platform.h>  #include "ath5k.h"  #include "debug.h" @@ -119,7 +120,7 @@ static int ath_ahb_probe(struct platform_device *pdev)  	if (res == NULL) {  		dev_err(&pdev->dev, "no IRQ resource found\n");  		ret = -ENXIO; -		goto err_out; +		goto err_iounmap;  	}  	irq = res->start; @@ -128,7 +129,7 @@ static int ath_ahb_probe(struct platform_device *pdev)  	if (hw == NULL) {  		dev_err(&pdev->dev, "no memory for ieee80211_hw\n");  		ret = -ENOMEM; -		goto err_out; +		goto err_iounmap;  	}  	ah = hw->priv; @@ -185,6 +186,8 @@ static int ath_ahb_probe(struct platform_device *pdev)   err_free_hw:  	ieee80211_free_hw(hw);  	platform_set_drvdata(pdev, NULL); + err_iounmap: +        iounmap(mem);   err_out:  	return ret;  } @@ -217,6 +220,7 @@ static int ath_ahb_remove(struct platform_device *pdev)  	}  	ath5k_deinit_ah(ah); +	iounmap(ah->iobase);  	platform_set_drvdata(pdev, NULL);  	ieee80211_free_hw(hw); diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c index d7d8e919914..aba088005b2 100644 --- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c @@ -869,7 +869,7 @@ static int ar5008_hw_process_ini(struct ath_hw *ah,  	ar5008_hw_set_channel_regs(ah, chan);  	ar5008_hw_init_chain_masks(ah);  	ath9k_olc_init(ah); -	ath9k_hw_apply_txpower(ah, chan); +	ath9k_hw_apply_txpower(ah, chan, false);  	/* Write analog registers */  	if (!ath9k_hw_set_rf_regs(ah, chan, freqIndex)) { diff --git a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c index 59647a3ceb7..3d400e8d653 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c @@ -54,7 +54,7 @@ void ar9003_paprd_enable(struct ath_hw *ah, bool val)  	if (val) {  		ah->paprd_table_write_done = true; -		ath9k_hw_apply_txpower(ah, chan); +		ath9k_hw_apply_txpower(ah, chan, false);  	}  	REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL0_B0, diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index bc992b237ae..deb6cfb2959 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c @@ -694,7 +694,7 @@ static int ar9003_hw_process_ini(struct ath_hw *ah,  	ar9003_hw_override_ini(ah);  	ar9003_hw_set_channel_regs(ah, chan);  	ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask); -	ath9k_hw_apply_txpower(ah, chan); +	ath9k_hw_apply_txpower(ah, chan, false);  	if (AR_SREV_9462(ah)) {  		if (REG_READ_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_0, diff --git a/drivers/net/wireless/ath/ath9k/eeprom_9287.c b/drivers/net/wireless/ath/ath9k/eeprom_9287.c index f272236d805..b34e8b2990b 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c @@ -824,6 +824,8 @@ static void ath9k_hw_ar9287_set_txpower(struct ath_hw *ah,  			regulatory->max_power_level = ratesArray[i];  	} +	ath9k_hw_update_regulatory_maxpower(ah); +  	if (test)  		return; diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 6c69e4e8b1c..fa84e37bf09 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -1454,7 +1454,7 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah,  		return false;  	}  	ath9k_hw_set_clockrate(ah); -	ath9k_hw_apply_txpower(ah, chan); +	ath9k_hw_apply_txpower(ah, chan, false);  	ath9k_hw_rfbus_done(ah);  	if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan)) @@ -2652,7 +2652,8 @@ static int get_antenna_gain(struct ath_hw *ah, struct ath9k_channel *chan)  	return ah->eep_ops->get_eeprom(ah, gain_param);  } -void ath9k_hw_apply_txpower(struct ath_hw *ah, struct ath9k_channel *chan) +void ath9k_hw_apply_txpower(struct ath_hw *ah, struct ath9k_channel *chan, +			    bool test)  {  	struct ath_regulatory *reg = ath9k_hw_regulatory(ah);  	struct ieee80211_channel *channel; @@ -2673,7 +2674,7 @@ void ath9k_hw_apply_txpower(struct ath_hw *ah, struct ath9k_channel *chan)  	ah->eep_ops->set_txpower(ah, chan,  				 ath9k_regd_get_ctl(reg, chan), -				 ant_reduction, new_pwr, false); +				 ant_reduction, new_pwr, test);  }  void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit, bool test) @@ -2686,7 +2687,7 @@ void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit, bool test)  	if (test)  		channel->max_power = MAX_RATE_POWER / 2; -	ath9k_hw_apply_txpower(ah, chan); +	ath9k_hw_apply_txpower(ah, chan, test);  	if (test)  		channel->max_power = DIV_ROUND_UP(reg->max_power_level, 2); diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index aa1680a0c7f..e88f182ff45 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -985,7 +985,8 @@ void ath9k_hw_name(struct ath_hw *ah, char *hw_name, size_t len);  /* PHY */  void ath9k_hw_get_delta_slope_vals(struct ath_hw *ah, u32 coef_scaled,  				   u32 *coef_mantissa, u32 *coef_exponent); -void ath9k_hw_apply_txpower(struct ath_hw *ah, struct ath9k_channel *chan); +void ath9k_hw_apply_txpower(struct ath_hw *ah, struct ath9k_channel *chan, +			    bool test);  /*   * Code Specific to AR5008, AR9001 or AR9002, diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 2504ab00558..798ea57252b 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1548,6 +1548,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)  	struct ath_hw *ah = sc->sc_ah;  	struct ath_common *common = ath9k_hw_common(ah);  	struct ieee80211_conf *conf = &hw->conf; +	bool reset_channel = false;  	ath9k_ps_wakeup(sc);  	mutex_lock(&sc->mutex); @@ -1556,6 +1557,12 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)  		sc->ps_idle = !!(conf->flags & IEEE80211_CONF_IDLE);  		if (sc->ps_idle)  			ath_cancel_work(sc); +		else +			/* +			 * The chip needs a reset to properly wake up from +			 * full sleep +			 */ +			reset_channel = ah->chip_fullsleep;  	}  	/* @@ -1584,7 +1591,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)  		}  	} -	if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { +	if ((changed & IEEE80211_CONF_CHANGE_CHANNEL) || reset_channel) {  		struct ieee80211_channel *curchan = hw->conf.channel;  		int pos = curchan->hw_value;  		int old_pos = -1; diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 834e6bc45e8..23eaa1b26eb 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -1820,6 +1820,7 @@ static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc,  	struct ath_frame_info *fi = get_frame_info(skb);  	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;  	struct ath_buf *bf; +	int fragno;  	u16 seqno;  	bf = ath_tx_get_buffer(sc); @@ -1831,9 +1832,16 @@ static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc,  	ATH_TXBUF_RESET(bf);  	if (tid) { +		fragno = le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG;  		seqno = tid->seq_next;  		hdr->seq_ctrl = cpu_to_le16(tid->seq_next << IEEE80211_SEQ_SEQ_SHIFT); -		INCR(tid->seq_next, IEEE80211_SEQ_MAX); + +		if (fragno) +			hdr->seq_ctrl |= cpu_to_le16(fragno); + +		if (!ieee80211_has_morefrags(hdr->frame_control)) +			INCR(tid->seq_next, IEEE80211_SEQ_MAX); +  		bf->bf_state.seqno = seqno;  	} diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index c79e6638c88..e4d6dc2e37d 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -4827,8 +4827,14 @@ static int b43_op_start(struct ieee80211_hw *hw)   out_mutex_unlock:  	mutex_unlock(&wl->mutex); -	/* reload configuration */ -	b43_op_config(hw, ~0); +	/* +	 * Configuration may have been overwritten during initialization. +	 * Reload the configuration, but only if initialization was +	 * successful. Reloading the configuration after a failed init +	 * may hang the system. +	 */ +	if (!err) +		b43_op_config(hw, ~0);  	return err;  } diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c index 4688904908e..758c115b556 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c @@ -108,9 +108,15 @@ static inline int brcmf_sdioh_f0_write_byte(struct brcmf_sdio_dev *sdiodev,  			sdio_release_host(sdfunc);  		}  	} else if (regaddr == SDIO_CCCR_ABORT) { +		sdfunc = kmemdup(sdiodev->func[0], sizeof(struct sdio_func), +				 GFP_KERNEL); +		if (!sdfunc) +			return -ENOMEM; +		sdfunc->num = 0;  		sdio_claim_host(sdfunc);  		sdio_writeb(sdfunc, *byte, regaddr, &err_ret);  		sdio_release_host(sdfunc); +		kfree(sdfunc);  	} else if (regaddr < 0xF0) {  		brcmf_dbg(ERROR, "F0 Wr:0x%02x: write disallowed\n", regaddr);  		err_ret = -EPERM; @@ -486,7 +492,7 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func,  			kfree(bus_if);  			return -ENOMEM;  		} -		sdiodev->func[0] = func->card->sdio_func[0]; +		sdiodev->func[0] = func;  		sdiodev->func[1] = func;  		sdiodev->bus_if = bus_if;  		bus_if->bus_priv.sdio = sdiodev; diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index 2bf5dda2929..eb3829b03cd 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c @@ -574,6 +574,8 @@ struct brcmf_sdio {  	struct task_struct *dpc_tsk;  	struct completion dpc_wait; +	struct list_head dpc_tsklst; +	spinlock_t dpc_tl_lock;  	struct semaphore sdsem; @@ -2594,29 +2596,58 @@ clkwait:  	return resched;  } +static inline void brcmf_sdbrcm_adddpctsk(struct brcmf_sdio *bus) +{ +	struct list_head *new_hd; +	unsigned long flags; + +	if (in_interrupt()) +		new_hd = kzalloc(sizeof(struct list_head), GFP_ATOMIC); +	else +		new_hd = kzalloc(sizeof(struct list_head), GFP_KERNEL); +	if (new_hd == NULL) +		return; + +	spin_lock_irqsave(&bus->dpc_tl_lock, flags); +	list_add_tail(new_hd, &bus->dpc_tsklst); +	spin_unlock_irqrestore(&bus->dpc_tl_lock, flags); +} +  static int brcmf_sdbrcm_dpc_thread(void *data)  {  	struct brcmf_sdio *bus = (struct brcmf_sdio *) data; +	struct list_head *cur_hd, *tmp_hd; +	unsigned long flags;  	allow_signal(SIGTERM);  	/* Run until signal received */  	while (1) {  		if (kthread_should_stop())  			break; -		if (!wait_for_completion_interruptible(&bus->dpc_wait)) { -			/* Call bus dpc unless it indicated down -			(then clean stop) */ -			if (bus->sdiodev->bus_if->state != BRCMF_BUS_DOWN) { -				if (brcmf_sdbrcm_dpc(bus)) -					complete(&bus->dpc_wait); -			} else { + +		if (list_empty(&bus->dpc_tsklst)) +			if (wait_for_completion_interruptible(&bus->dpc_wait)) +				break; + +		spin_lock_irqsave(&bus->dpc_tl_lock, flags); +		list_for_each_safe(cur_hd, tmp_hd, &bus->dpc_tsklst) { +			spin_unlock_irqrestore(&bus->dpc_tl_lock, flags); + +			if (bus->sdiodev->bus_if->state == BRCMF_BUS_DOWN) {  				/* after stopping the bus, exit thread */  				brcmf_sdbrcm_bus_stop(bus->sdiodev->dev);  				bus->dpc_tsk = NULL;  				break;  			} -		} else -			break; + +			if (brcmf_sdbrcm_dpc(bus)) +				brcmf_sdbrcm_adddpctsk(bus); + +			spin_lock_irqsave(&bus->dpc_tl_lock, flags); +			list_del(cur_hd); +			kfree(cur_hd); +		} +		spin_unlock_irqrestore(&bus->dpc_tl_lock, flags);  	}  	return 0;  } @@ -2669,8 +2700,10 @@ static int brcmf_sdbrcm_bus_txdata(struct device *dev, struct sk_buff *pkt)  	/* Schedule DPC if needed to send queued packet(s) */  	if (!bus->dpc_sched) {  		bus->dpc_sched = true; -		if (bus->dpc_tsk) +		if (bus->dpc_tsk) { +			brcmf_sdbrcm_adddpctsk(bus);  			complete(&bus->dpc_wait); +		}  	}  	return ret; @@ -3514,8 +3547,10 @@ void brcmf_sdbrcm_isr(void *arg)  		brcmf_dbg(ERROR, "isr w/o interrupt configured!\n");  	bus->dpc_sched = true; -	if (bus->dpc_tsk) +	if (bus->dpc_tsk) { +		brcmf_sdbrcm_adddpctsk(bus);  		complete(&bus->dpc_wait); +	}  }  static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus) @@ -3559,8 +3594,10 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus)  				bus->ipend = true;  				bus->dpc_sched = true; -				if (bus->dpc_tsk) +				if (bus->dpc_tsk) { +					brcmf_sdbrcm_adddpctsk(bus);  					complete(&bus->dpc_wait); +				}  			}  		} @@ -3897,6 +3934,8 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev)  	}  	/* Initialize DPC thread */  	init_completion(&bus->dpc_wait); +	INIT_LIST_HEAD(&bus->dpc_tsklst); +	spin_lock_init(&bus->dpc_tl_lock);  	bus->dpc_tsk = kthread_run(brcmf_sdbrcm_dpc_thread,  				   bus, "brcmf_dpc");  	if (IS_ERR(bus->dpc_tsk)) { diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c index 231ddf4a674..b4d92792c50 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/main.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c @@ -847,8 +847,7 @@ brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs)  	 */  	if (!(txs->status & TX_STATUS_AMPDU)  	    && (txs->status & TX_STATUS_INTERMEDIATE)) { -		wiphy_err(wlc->wiphy, "%s: INTERMEDIATE but not AMPDU\n", -			  __func__); +		BCMMSG(wlc->wiphy, "INTERMEDIATE but not AMPDU\n");  		return false;  	} @@ -7614,6 +7613,7 @@ brcms_c_recvctl(struct brcms_c_info *wlc, struct d11rxhdr *rxh,  {  	int len_mpdu;  	struct ieee80211_rx_status rx_status; +	struct ieee80211_hdr *hdr;  	memset(&rx_status, 0, sizeof(rx_status));  	prep_mac80211_status(wlc, rxh, p, &rx_status); @@ -7623,6 +7623,13 @@ brcms_c_recvctl(struct brcms_c_info *wlc, struct d11rxhdr *rxh,  	skb_pull(p, D11_PHY_HDR_LEN);  	__skb_trim(p, len_mpdu); +	/* unmute transmit */ +	if (wlc->hw->suspended_fifos) { +		hdr = (struct ieee80211_hdr *)p->data; +		if (ieee80211_is_beacon(hdr->frame_control)) +			brcms_b_mute(wlc->hw, false); +	} +  	memcpy(IEEE80211_SKB_RXCB(p), &rx_status, sizeof(rx_status));  	ieee80211_rx_irqsafe(wlc->pub->ieee_hw, p);  } diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c index 2b022571a85..1779db3aa2b 100644 --- a/drivers/net/wireless/ipw2x00/ipw2200.c +++ b/drivers/net/wireless/ipw2x00/ipw2200.c @@ -2191,6 +2191,7 @@ static int __ipw_send_cmd(struct ipw_priv *priv, struct host_cmd *cmd)  {  	int rc = 0;  	unsigned long flags; +	unsigned long now, end;  	spin_lock_irqsave(&priv->lock, flags);  	if (priv->status & STATUS_HCMD_ACTIVE) { @@ -2232,10 +2233,20 @@ static int __ipw_send_cmd(struct ipw_priv *priv, struct host_cmd *cmd)  	}  	spin_unlock_irqrestore(&priv->lock, flags); +	now = jiffies; +	end = now + HOST_COMPLETE_TIMEOUT; +again:  	rc = wait_event_interruptible_timeout(priv->wait_command_queue,  					      !(priv->  						status & STATUS_HCMD_ACTIVE), -					      HOST_COMPLETE_TIMEOUT); +					      end - now); +	if (rc < 0) { +		now = jiffies; +		if (time_before(now, end)) +			goto again; +		rc = 0; +	} +  	if (rc == 0) {  		spin_lock_irqsave(&priv->lock, flags);  		if (priv->status & STATUS_HCMD_ACTIVE) { diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index 5b0d888f746..8d80e233bc7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -46,8 +46,8 @@  #include "iwl-prph.h"  /* Highest firmware API version supported */ -#define IWL1000_UCODE_API_MAX 6 -#define IWL100_UCODE_API_MAX 6 +#define IWL1000_UCODE_API_MAX 5 +#define IWL100_UCODE_API_MAX 5  /* Oldest version we won't warn about */  #define IWL1000_UCODE_API_OK 5 @@ -226,5 +226,5 @@ const struct iwl_cfg iwl100_bg_cfg = {  	IWL_DEVICE_100,  }; -MODULE_FIRMWARE(IWL1000_MODULE_FIRMWARE(IWL1000_UCODE_API_MAX)); -MODULE_FIRMWARE(IWL100_MODULE_FIRMWARE(IWL100_UCODE_API_MAX)); +MODULE_FIRMWARE(IWL1000_MODULE_FIRMWARE(IWL1000_UCODE_API_OK)); +MODULE_FIRMWARE(IWL100_MODULE_FIRMWARE(IWL100_UCODE_API_OK)); diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index 5635b9e2c69..ea108622e0b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -51,10 +51,10 @@  #define IWL135_UCODE_API_MAX 6  /* Oldest version we won't warn about */ -#define IWL2030_UCODE_API_OK 5 -#define IWL2000_UCODE_API_OK 5 -#define IWL105_UCODE_API_OK 5 -#define IWL135_UCODE_API_OK 5 +#define IWL2030_UCODE_API_OK 6 +#define IWL2000_UCODE_API_OK 6 +#define IWL105_UCODE_API_OK 6 +#define IWL135_UCODE_API_OK 6  /* Lowest firmware API version supported */  #define IWL2030_UCODE_API_MIN 5 @@ -328,7 +328,7 @@ const struct iwl_cfg iwl135_bgn_cfg = {  	.ht_params = &iwl2000_ht_params,  }; -MODULE_FIRMWARE(IWL2000_MODULE_FIRMWARE(IWL2000_UCODE_API_MAX)); -MODULE_FIRMWARE(IWL2030_MODULE_FIRMWARE(IWL2030_UCODE_API_MAX)); -MODULE_FIRMWARE(IWL105_MODULE_FIRMWARE(IWL105_UCODE_API_MAX)); -MODULE_FIRMWARE(IWL135_MODULE_FIRMWARE(IWL135_UCODE_API_MAX)); +MODULE_FIRMWARE(IWL2000_MODULE_FIRMWARE(IWL2000_UCODE_API_OK)); +MODULE_FIRMWARE(IWL2030_MODULE_FIRMWARE(IWL2030_UCODE_API_OK)); +MODULE_FIRMWARE(IWL105_MODULE_FIRMWARE(IWL105_UCODE_API_OK)); +MODULE_FIRMWARE(IWL135_MODULE_FIRMWARE(IWL135_UCODE_API_OK)); diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index a805e97b89a..de0920c74cd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -51,6 +51,10 @@  #define IWL5000_UCODE_API_MAX 5  #define IWL5150_UCODE_API_MAX 2 +/* Oldest version we won't warn about */ +#define IWL5000_UCODE_API_OK 5 +#define IWL5150_UCODE_API_OK 2 +  /* Lowest firmware API version supported */  #define IWL5000_UCODE_API_MIN 1  #define IWL5150_UCODE_API_MIN 1 @@ -326,6 +330,7 @@ static const struct iwl_ht_params iwl5000_ht_params = {  #define IWL_DEVICE_5000						\  	.fw_name_pre = IWL5000_FW_PRE,				\  	.ucode_api_max = IWL5000_UCODE_API_MAX,			\ +	.ucode_api_ok = IWL5000_UCODE_API_OK,			\  	.ucode_api_min = IWL5000_UCODE_API_MIN,			\  	.max_inst_size = IWLAGN_RTC_INST_SIZE,			\  	.max_data_size = IWLAGN_RTC_DATA_SIZE,			\ @@ -371,6 +376,7 @@ const struct iwl_cfg iwl5350_agn_cfg = {  	.name = "Intel(R) WiMAX/WiFi Link 5350 AGN",  	.fw_name_pre = IWL5000_FW_PRE,  	.ucode_api_max = IWL5000_UCODE_API_MAX, +	.ucode_api_ok = IWL5000_UCODE_API_OK,  	.ucode_api_min = IWL5000_UCODE_API_MIN,  	.max_inst_size = IWLAGN_RTC_INST_SIZE,  	.max_data_size = IWLAGN_RTC_DATA_SIZE, @@ -386,6 +392,7 @@ const struct iwl_cfg iwl5350_agn_cfg = {  #define IWL_DEVICE_5150						\  	.fw_name_pre = IWL5150_FW_PRE,				\  	.ucode_api_max = IWL5150_UCODE_API_MAX,			\ +	.ucode_api_ok = IWL5150_UCODE_API_OK,			\  	.ucode_api_min = IWL5150_UCODE_API_MIN,			\  	.max_inst_size = IWLAGN_RTC_INST_SIZE,			\  	.max_data_size = IWLAGN_RTC_DATA_SIZE,			\ @@ -409,5 +416,5 @@ const struct iwl_cfg iwl5150_abg_cfg = {  	IWL_DEVICE_5150,  }; -MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_MAX)); -MODULE_FIRMWARE(IWL5150_MODULE_FIRMWARE(IWL5150_UCODE_API_MAX)); +MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_OK)); +MODULE_FIRMWARE(IWL5150_MODULE_FIRMWARE(IWL5150_UCODE_API_OK)); diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 64060cd738b..f0c91505a7f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -53,6 +53,8 @@  /* Oldest version we won't warn about */  #define IWL6000_UCODE_API_OK 4  #define IWL6000G2_UCODE_API_OK 5 +#define IWL6050_UCODE_API_OK 5 +#define IWL6000G2B_UCODE_API_OK 6  /* Lowest firmware API version supported */  #define IWL6000_UCODE_API_MIN 4 @@ -388,7 +390,7 @@ const struct iwl_cfg iwl6005_2agn_mow2_cfg = {  #define IWL_DEVICE_6030						\  	.fw_name_pre = IWL6030_FW_PRE,				\  	.ucode_api_max = IWL6000G2_UCODE_API_MAX,		\ -	.ucode_api_ok = IWL6000G2_UCODE_API_OK,			\ +	.ucode_api_ok = IWL6000G2B_UCODE_API_OK,		\  	.ucode_api_min = IWL6000G2_UCODE_API_MIN,		\  	.max_inst_size = IWL60_RTC_INST_SIZE,			\  	.max_data_size = IWL60_RTC_DATA_SIZE,			\ @@ -557,6 +559,6 @@ const struct iwl_cfg iwl6000_3agn_cfg = {  };  MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_OK)); -MODULE_FIRMWARE(IWL6050_MODULE_FIRMWARE(IWL6050_UCODE_API_MAX)); -MODULE_FIRMWARE(IWL6005_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX)); -MODULE_FIRMWARE(IWL6030_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX)); +MODULE_FIRMWARE(IWL6050_MODULE_FIRMWARE(IWL6050_UCODE_API_OK)); +MODULE_FIRMWARE(IWL6005_MODULE_FIRMWARE(IWL6000G2_UCODE_API_OK)); +MODULE_FIRMWARE(IWL6030_MODULE_FIRMWARE(IWL6000G2B_UCODE_API_OK)); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index f1226dbf789..2a9a16f901c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -863,7 +863,6 @@ static void iwl_bg_run_time_calib_work(struct work_struct *work)  void iwlagn_prepare_restart(struct iwl_priv *priv)  { -	struct iwl_rxon_context *ctx;  	bool bt_full_concurrent;  	u8 bt_ci_compliance;  	u8 bt_load; @@ -872,8 +871,6 @@ void iwlagn_prepare_restart(struct iwl_priv *priv)  	lockdep_assert_held(&priv->mutex); -	for_each_context(priv, ctx) -		ctx->vif = NULL;  	priv->is_open = 0;  	/* diff --git a/drivers/net/wireless/iwlwifi/iwl-fh.h b/drivers/net/wireless/iwlwifi/iwl-fh.h index 90208094b8e..74bce97a860 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fh.h +++ b/drivers/net/wireless/iwlwifi/iwl-fh.h @@ -104,15 +104,29 @@   * (see struct iwl_tfd_frame).  These 16 pointer registers are offset by 0x04   * bytes from one another.  Each TFD circular buffer in DRAM must be 256-byte   * aligned (address bits 0-7 must be 0). + * Later devices have 20 (5000 series) or 30 (higher) queues, but the registers + * for them are in different places.   *   * Bit fields in each pointer register:   *  27-0: TFD CB physical base address [35:8], must be 256-byte aligned   */ -#define FH_MEM_CBBC_LOWER_BOUND          (FH_MEM_LOWER_BOUND + 0x9D0) -#define FH_MEM_CBBC_UPPER_BOUND          (FH_MEM_LOWER_BOUND + 0xA10) +#define FH_MEM_CBBC_0_15_LOWER_BOUND		(FH_MEM_LOWER_BOUND + 0x9D0) +#define FH_MEM_CBBC_0_15_UPPER_BOUND		(FH_MEM_LOWER_BOUND + 0xA10) +#define FH_MEM_CBBC_16_19_LOWER_BOUND		(FH_MEM_LOWER_BOUND + 0xBF0) +#define FH_MEM_CBBC_16_19_UPPER_BOUND		(FH_MEM_LOWER_BOUND + 0xC00) +#define FH_MEM_CBBC_20_31_LOWER_BOUND		(FH_MEM_LOWER_BOUND + 0xB20) +#define FH_MEM_CBBC_20_31_UPPER_BOUND		(FH_MEM_LOWER_BOUND + 0xB80) -/* Find TFD CB base pointer for given queue (range 0-15). */ -#define FH_MEM_CBBC_QUEUE(x)  (FH_MEM_CBBC_LOWER_BOUND + (x) * 0x4) +/* Find TFD CB base pointer for given queue */ +static inline unsigned int FH_MEM_CBBC_QUEUE(unsigned int chnl) +{ +	if (chnl < 16) +		return FH_MEM_CBBC_0_15_LOWER_BOUND + 4 * chnl; +	if (chnl < 20) +		return FH_MEM_CBBC_16_19_LOWER_BOUND + 4 * (chnl - 16); +	WARN_ON_ONCE(chnl >= 32); +	return FH_MEM_CBBC_20_31_LOWER_BOUND + 4 * (chnl - 20); +}  /** diff --git a/drivers/net/wireless/iwlwifi/iwl-mac80211.c b/drivers/net/wireless/iwlwifi/iwl-mac80211.c index b6805f8e9a0..c24a7134a6f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-mac80211.c +++ b/drivers/net/wireless/iwlwifi/iwl-mac80211.c @@ -1244,6 +1244,7 @@ static int iwlagn_mac_add_interface(struct ieee80211_hw *hw,  	struct iwl_rxon_context *tmp, *ctx = NULL;  	int err;  	enum nl80211_iftype viftype = ieee80211_vif_type_p2p(vif); +	bool reset = false;  	IWL_DEBUG_MAC80211(priv, "enter: type %d, addr %pM\n",  			   viftype, vif->addr); @@ -1265,6 +1266,13 @@ static int iwlagn_mac_add_interface(struct ieee80211_hw *hw,  			tmp->interface_modes | tmp->exclusive_interface_modes;  		if (tmp->vif) { +			/* On reset we need to add the same interface again */ +			if (tmp->vif == vif) { +				reset = true; +				ctx = tmp; +				break; +			} +  			/* check if this busy context is exclusive */  			if (tmp->exclusive_interface_modes &  						BIT(tmp->vif->type)) { @@ -1291,7 +1299,7 @@ static int iwlagn_mac_add_interface(struct ieee80211_hw *hw,  	ctx->vif = vif;  	err = iwl_setup_interface(priv, ctx); -	if (!err) +	if (!err || reset)  		goto out;  	ctx->vif = NULL; diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h index 75dc20bd965..3b1069290fa 100644 --- a/drivers/net/wireless/iwlwifi/iwl-prph.h +++ b/drivers/net/wireless/iwlwifi/iwl-prph.h @@ -223,12 +223,33 @@  #define SCD_AIT			(SCD_BASE + 0x0c)  #define SCD_TXFACT		(SCD_BASE + 0x10)  #define SCD_ACTIVE		(SCD_BASE + 0x14) -#define SCD_QUEUE_WRPTR(x)	(SCD_BASE + 0x18 + (x) * 4) -#define SCD_QUEUE_RDPTR(x)	(SCD_BASE + 0x68 + (x) * 4)  #define SCD_QUEUECHAIN_SEL	(SCD_BASE + 0xe8)  #define SCD_AGGR_SEL		(SCD_BASE + 0x248)  #define SCD_INTERRUPT_MASK	(SCD_BASE + 0x108) -#define SCD_QUEUE_STATUS_BITS(x)	(SCD_BASE + 0x10c + (x) * 4) + +static inline unsigned int SCD_QUEUE_WRPTR(unsigned int chnl) +{ +	if (chnl < 20) +		return SCD_BASE + 0x18 + chnl * 4; +	WARN_ON_ONCE(chnl >= 32); +	return SCD_BASE + 0x284 + (chnl - 20) * 4; +} + +static inline unsigned int SCD_QUEUE_RDPTR(unsigned int chnl) +{ +	if (chnl < 20) +		return SCD_BASE + 0x68 + chnl * 4; +	WARN_ON_ONCE(chnl >= 32); +	return SCD_BASE + 0x2B4 + (chnl - 20) * 4; +} + +static inline unsigned int SCD_QUEUE_STATUS_BITS(unsigned int chnl) +{ +	if (chnl < 20) +		return SCD_BASE + 0x10c + chnl * 4; +	WARN_ON_ONCE(chnl >= 32); +	return SCD_BASE + 0x384 + (chnl - 20) * 4; +}  /*********************** END TX SCHEDULER *************************************/ diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c index 3fa1ecebadf..2fa879b015b 100644 --- a/drivers/net/wireless/libertas/cfg.c +++ b/drivers/net/wireless/libertas/cfg.c @@ -103,7 +103,7 @@ static const u32 cipher_suites[] = {   * Convert NL80211's auth_type to the one from Libertas, see chapter 5.9.1   * in the firmware spec   */ -static u8 lbs_auth_to_authtype(enum nl80211_auth_type auth_type) +static int lbs_auth_to_authtype(enum nl80211_auth_type auth_type)  {  	int ret = -ENOTSUPP; @@ -1411,7 +1411,12 @@ static int lbs_cfg_connect(struct wiphy *wiphy, struct net_device *dev,  		goto done;  	} -	lbs_set_authtype(priv, sme); +	ret = lbs_set_authtype(priv, sme); +	if (ret == -ENOTSUPP) { +		wiphy_err(wiphy, "unsupported authtype 0x%x\n", sme->auth_type); +		goto done; +	} +  	lbs_set_radio(priv, preamble, 1);  	/* Do the actual association */ diff --git a/drivers/net/wireless/mwifiex/pcie.h b/drivers/net/wireless/mwifiex/pcie.h index 445ff21772e..2f218f9a3fd 100644 --- a/drivers/net/wireless/mwifiex/pcie.h +++ b/drivers/net/wireless/mwifiex/pcie.h @@ -48,15 +48,15 @@  #define PCIE_HOST_INT_STATUS_MASK			0xC3C  #define PCIE_SCRATCH_2_REG				0xC40  #define PCIE_SCRATCH_3_REG				0xC44 -#define PCIE_SCRATCH_4_REG				0xCC0 -#define PCIE_SCRATCH_5_REG				0xCC4 -#define PCIE_SCRATCH_6_REG				0xCC8 -#define PCIE_SCRATCH_7_REG				0xCCC -#define PCIE_SCRATCH_8_REG				0xCD0 -#define PCIE_SCRATCH_9_REG				0xCD4 -#define PCIE_SCRATCH_10_REG				0xCD8 -#define PCIE_SCRATCH_11_REG				0xCDC -#define PCIE_SCRATCH_12_REG				0xCE0 +#define PCIE_SCRATCH_4_REG				0xCD0 +#define PCIE_SCRATCH_5_REG				0xCD4 +#define PCIE_SCRATCH_6_REG				0xCD8 +#define PCIE_SCRATCH_7_REG				0xCDC +#define PCIE_SCRATCH_8_REG				0xCE0 +#define PCIE_SCRATCH_9_REG				0xCE4 +#define PCIE_SCRATCH_10_REG				0xCE8 +#define PCIE_SCRATCH_11_REG				0xCEC +#define PCIE_SCRATCH_12_REG				0xCF0  #define CPU_INTR_DNLD_RDY				BIT(0)  #define CPU_INTR_DOOR_BELL				BIT(1) diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index 288b035a357..cc15fdb3606 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c @@ -1941,6 +1941,7 @@ void rtl_pci_disconnect(struct pci_dev *pdev)  		rtl_deinit_deferred_work(hw);  		rtlpriv->intf_ops->adapter_stop(hw);  	} +	rtlpriv->cfg->ops->disable_interrupt(hw);  	/*deinit rfkill */  	rtl_deinit_rfkill(hw); diff --git a/drivers/net/wireless/wl1251/main.c b/drivers/net/wireless/wl1251/main.c index 41302c7b1ad..d1afb8e3b2e 100644 --- a/drivers/net/wireless/wl1251/main.c +++ b/drivers/net/wireless/wl1251/main.c @@ -479,6 +479,7 @@ static void wl1251_op_stop(struct ieee80211_hw *hw)  	cancel_work_sync(&wl->irq_work);  	cancel_work_sync(&wl->tx_work);  	cancel_work_sync(&wl->filter_work); +	cancel_delayed_work_sync(&wl->elp_work);  	mutex_lock(&wl->mutex); diff --git a/drivers/net/wireless/wl1251/sdio.c b/drivers/net/wireless/wl1251/sdio.c index f78694295c3..1b851f650e0 100644 --- a/drivers/net/wireless/wl1251/sdio.c +++ b/drivers/net/wireless/wl1251/sdio.c @@ -315,8 +315,8 @@ static void __devexit wl1251_sdio_remove(struct sdio_func *func)  	if (wl->irq)  		free_irq(wl->irq, wl); -	kfree(wl_sdio);  	wl1251_free_hw(wl); +	kfree(wl_sdio);  	sdio_claim_host(func);  	sdio_release_irq(func); diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index 083a49fee56..165274c064b 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile @@ -42,6 +42,7 @@ obj-$(CONFIG_UNICORE32) += setup-bus.o setup-irq.o  obj-$(CONFIG_PARISC) += setup-bus.o  obj-$(CONFIG_SUPERH) += setup-bus.o setup-irq.o  obj-$(CONFIG_PPC) += setup-bus.o +obj-$(CONFIG_FRV) += setup-bus.o  obj-$(CONFIG_MIPS) += setup-bus.o setup-irq.o  obj-$(CONFIG_X86_VISWS) += setup-irq.o  obj-$(CONFIG_MN10300) += setup-bus.o diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index 0f150f271c2..1929c0c63b7 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c @@ -200,7 +200,7 @@ static pci_power_t acpi_pci_choose_state(struct pci_dev *pdev)  		return PCI_D1;  	case ACPI_STATE_D2:  		return PCI_D2; -	case ACPI_STATE_D3: +	case ACPI_STATE_D3_HOT:  		return PCI_D3hot;  	case ACPI_STATE_D3_COLD:  		return PCI_D3cold; @@ -223,7 +223,7 @@ static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state)  		[PCI_D0] = ACPI_STATE_D0,  		[PCI_D1] = ACPI_STATE_D1,  		[PCI_D2] = ACPI_STATE_D2, -		[PCI_D3hot] = ACPI_STATE_D3, +		[PCI_D3hot] = ACPI_STATE_D3_HOT,  		[PCI_D3cold] = ACPI_STATE_D3  	};  	int error = -EINVAL; diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index d20f1334792..111569ccab4 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -991,8 +991,8 @@ static void pci_restore_config_dword(struct pci_dev *pdev, int offset,  	}  } -static void pci_restore_config_space(struct pci_dev *pdev, int start, int end, -				     int retry) +static void pci_restore_config_space_range(struct pci_dev *pdev, +					   int start, int end, int retry)  {  	int index; @@ -1002,6 +1002,18 @@ static void pci_restore_config_space(struct pci_dev *pdev, int start, int end,  					 retry);  } +static void pci_restore_config_space(struct pci_dev *pdev) +{ +	if (pdev->hdr_type == PCI_HEADER_TYPE_NORMAL) { +		pci_restore_config_space_range(pdev, 10, 15, 0); +		/* Restore BARs before the command register. */ +		pci_restore_config_space_range(pdev, 4, 9, 10); +		pci_restore_config_space_range(pdev, 0, 3, 0); +	} else { +		pci_restore_config_space_range(pdev, 0, 15, 0); +	} +} +  /**    * pci_restore_state - Restore the saved state of a PCI device   * @dev: - PCI device that we're dealing with @@ -1015,13 +1027,7 @@ void pci_restore_state(struct pci_dev *dev)  	pci_restore_pcie_state(dev);  	pci_restore_ats_state(dev); -	pci_restore_config_space(dev, 10, 15, 0); -	/* -	 * The Base Address register should be programmed before the command -	 * register(s) -	 */ -	pci_restore_config_space(dev, 4, 9, 10); -	pci_restore_config_space(dev, 0, 3, 0); +	pci_restore_config_space(dev);  	pci_restore_pcix_state(dev);  	pci_restore_msi_state(dev); diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index ec3b8cc188a..df6296c5f47 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -908,10 +908,6 @@ static int pinctrl_groups_show(struct seq_file *s, void *what)  	const struct pinctrl_ops *ops = pctldev->desc->pctlops;  	unsigned selector = 0; -	/* No grouping */ -	if (!ops) -		return 0; -  	mutex_lock(&pinctrl_mutex);  	seq_puts(s, "registered pin groups:\n"); @@ -1225,6 +1221,19 @@ static void pinctrl_remove_device_debugfs(struct pinctrl_dev *pctldev)  #endif +static int pinctrl_check_ops(struct pinctrl_dev *pctldev) +{ +	const struct pinctrl_ops *ops = pctldev->desc->pctlops; + +	if (!ops || +	    !ops->list_groups || +	    !ops->get_group_name || +	    !ops->get_group_pins) +		return -EINVAL; + +	return 0; +} +  /**   * pinctrl_register() - register a pin controller device   * @pctldesc: descriptor for this pin controller @@ -1256,6 +1265,14 @@ struct pinctrl_dev *pinctrl_register(struct pinctrl_desc *pctldesc,  	INIT_LIST_HEAD(&pctldev->gpio_ranges);  	pctldev->dev = dev; +	/* check core ops for sanity */ +	ret = pinctrl_check_ops(pctldev); +	if (ret) { +		pr_err("%s pinctrl ops lacks necessary functions\n", +			pctldesc->name); +		goto out_err; +	} +  	/* If we're implementing pinmuxing, check the ops for sanity */  	if (pctldesc->pmxops) {  		ret = pinmux_check_ops(pctldev); diff --git a/drivers/platform/x86/acerhdf.c b/drivers/platform/x86/acerhdf.c index bc8384c6f3e..639db4d0aa7 100644 --- a/drivers/platform/x86/acerhdf.c +++ b/drivers/platform/x86/acerhdf.c @@ -50,7 +50,7 @@   */  #undef START_IN_KERNEL_MODE -#define DRV_VER "0.5.24" +#define DRV_VER "0.5.26"  /*   * According to the Atom N270 datasheet, @@ -83,8 +83,8 @@ static int kernelmode;  #endif  static unsigned int interval = 10; -static unsigned int fanon = 63000; -static unsigned int fanoff = 58000; +static unsigned int fanon = 60000; +static unsigned int fanoff = 53000;  static unsigned int verbose;  static unsigned int fanstate = ACERHDF_FAN_AUTO;  static char force_bios[16]; @@ -150,6 +150,8 @@ static const struct bios_settings_t bios_tbl[] = {  	{"Acer", "AOA150", "v0.3308", 0x55, 0x58, {0x20, 0x00} },  	{"Acer", "AOA150", "v0.3309", 0x55, 0x58, {0x20, 0x00} },  	{"Acer", "AOA150", "v0.3310", 0x55, 0x58, {0x20, 0x00} }, +	/* LT1005u */ +	{"Acer", "LT-10Q", "v0.3310", 0x55, 0x58, {0x20, 0x00} },  	/* Acer 1410 */  	{"Acer", "Aspire 1410", "v0.3108", 0x55, 0x58, {0x9e, 0x00} },  	{"Acer", "Aspire 1410", "v0.3113", 0x55, 0x58, {0x9e, 0x00} }, @@ -161,6 +163,7 @@ static const struct bios_settings_t bios_tbl[] = {  	{"Acer", "Aspire 1410", "v1.3303", 0x55, 0x58, {0x9e, 0x00} },  	{"Acer", "Aspire 1410", "v1.3308", 0x55, 0x58, {0x9e, 0x00} },  	{"Acer", "Aspire 1410", "v1.3310", 0x55, 0x58, {0x9e, 0x00} }, +	{"Acer", "Aspire 1410", "v1.3314", 0x55, 0x58, {0x9e, 0x00} },  	/* Acer 1810xx */  	{"Acer", "Aspire 1810TZ", "v0.3108", 0x55, 0x58, {0x9e, 0x00} },  	{"Acer", "Aspire 1810T",  "v0.3108", 0x55, 0x58, {0x9e, 0x00} }, @@ -183,29 +186,44 @@ static const struct bios_settings_t bios_tbl[] = {  	{"Acer", "Aspire 1810TZ", "v1.3310", 0x55, 0x58, {0x9e, 0x00} },  	{"Acer", "Aspire 1810T",  "v1.3310", 0x55, 0x58, {0x9e, 0x00} },  	{"Acer", "Aspire 1810TZ", "v1.3314", 0x55, 0x58, {0x9e, 0x00} }, +	{"Acer", "Aspire 1810T",  "v1.3314", 0x55, 0x58, {0x9e, 0x00} },  	/* Acer 531 */ +	{"Acer", "AO531h", "v0.3104", 0x55, 0x58, {0x20, 0x00} },  	{"Acer", "AO531h", "v0.3201", 0x55, 0x58, {0x20, 0x00} }, +	{"Acer", "AO531h", "v0.3304", 0x55, 0x58, {0x20, 0x00} }, +	/* Acer 751 */ +	{"Acer", "AO751h", "V0.3212", 0x55, 0x58, {0x21, 0x00} }, +	/* Acer 1825 */ +	{"Acer", "Aspire 1825PTZ", "V1.3118", 0x55, 0x58, {0x9e, 0x00} }, +	{"Acer", "Aspire 1825PTZ", "V1.3127", 0x55, 0x58, {0x9e, 0x00} }, +	/* Acer TravelMate 7730 */ +	{"Acer", "TravelMate 7730G", "v0.3509", 0x55, 0x58, {0xaf, 0x00} },  	/* Gateway */ -	{"Gateway", "AOA110", "v0.3103", 0x55, 0x58, {0x21, 0x00} }, -	{"Gateway", "AOA150", "v0.3103", 0x55, 0x58, {0x20, 0x00} }, -	{"Gateway", "LT31",   "v1.3103", 0x55, 0x58, {0x9e, 0x00} }, -	{"Gateway", "LT31",   "v1.3201", 0x55, 0x58, {0x9e, 0x00} }, -	{"Gateway", "LT31",   "v1.3302", 0x55, 0x58, {0x9e, 0x00} }, +	{"Gateway", "AOA110", "v0.3103",  0x55, 0x58, {0x21, 0x00} }, +	{"Gateway", "AOA150", "v0.3103",  0x55, 0x58, {0x20, 0x00} }, +	{"Gateway", "LT31",   "v1.3103",  0x55, 0x58, {0x9e, 0x00} }, +	{"Gateway", "LT31",   "v1.3201",  0x55, 0x58, {0x9e, 0x00} }, +	{"Gateway", "LT31",   "v1.3302",  0x55, 0x58, {0x9e, 0x00} }, +	{"Gateway", "LT31",   "v1.3303t", 0x55, 0x58, {0x9e, 0x00} },  	/* Packard Bell */ -	{"Packard Bell", "DOA150", "v0.3104", 0x55, 0x58, {0x21, 0x00} }, -	{"Packard Bell", "DOA150", "v0.3105", 0x55, 0x58, {0x20, 0x00} }, -	{"Packard Bell", "AOA110", "v0.3105", 0x55, 0x58, {0x21, 0x00} }, -	{"Packard Bell", "AOA150", "v0.3105", 0x55, 0x58, {0x20, 0x00} }, -	{"Packard Bell", "DOTMU",  "v1.3303", 0x55, 0x58, {0x9e, 0x00} }, -	{"Packard Bell", "DOTMU",  "v0.3120", 0x55, 0x58, {0x9e, 0x00} }, -	{"Packard Bell", "DOTMU",  "v0.3108", 0x55, 0x58, {0x9e, 0x00} }, -	{"Packard Bell", "DOTMU",  "v0.3113", 0x55, 0x58, {0x9e, 0x00} }, -	{"Packard Bell", "DOTMU",  "v0.3115", 0x55, 0x58, {0x9e, 0x00} }, -	{"Packard Bell", "DOTMU",  "v0.3117", 0x55, 0x58, {0x9e, 0x00} }, -	{"Packard Bell", "DOTMU",  "v0.3119", 0x55, 0x58, {0x9e, 0x00} }, -	{"Packard Bell", "DOTMU",  "v1.3204", 0x55, 0x58, {0x9e, 0x00} }, -	{"Packard Bell", "DOTMA",  "v1.3201", 0x55, 0x58, {0x9e, 0x00} }, -	{"Packard Bell", "DOTMA",  "v1.3302", 0x55, 0x58, {0x9e, 0x00} }, +	{"Packard Bell", "DOA150",  "v0.3104",  0x55, 0x58, {0x21, 0x00} }, +	{"Packard Bell", "DOA150",  "v0.3105",  0x55, 0x58, {0x20, 0x00} }, +	{"Packard Bell", "AOA110",  "v0.3105",  0x55, 0x58, {0x21, 0x00} }, +	{"Packard Bell", "AOA150",  "v0.3105",  0x55, 0x58, {0x20, 0x00} }, +	{"Packard Bell", "ENBFT",   "V1.3118",  0x55, 0x58, {0x9e, 0x00} }, +	{"Packard Bell", "ENBFT",   "V1.3127",  0x55, 0x58, {0x9e, 0x00} }, +	{"Packard Bell", "DOTMU",   "v1.3303",  0x55, 0x58, {0x9e, 0x00} }, +	{"Packard Bell", "DOTMU",   "v0.3120",  0x55, 0x58, {0x9e, 0x00} }, +	{"Packard Bell", "DOTMU",   "v0.3108",  0x55, 0x58, {0x9e, 0x00} }, +	{"Packard Bell", "DOTMU",   "v0.3113",  0x55, 0x58, {0x9e, 0x00} }, +	{"Packard Bell", "DOTMU",   "v0.3115",  0x55, 0x58, {0x9e, 0x00} }, +	{"Packard Bell", "DOTMU",   "v0.3117",  0x55, 0x58, {0x9e, 0x00} }, +	{"Packard Bell", "DOTMU",   "v0.3119",  0x55, 0x58, {0x9e, 0x00} }, +	{"Packard Bell", "DOTMU",   "v1.3204",  0x55, 0x58, {0x9e, 0x00} }, +	{"Packard Bell", "DOTMA",   "v1.3201",  0x55, 0x58, {0x9e, 0x00} }, +	{"Packard Bell", "DOTMA",   "v1.3302",  0x55, 0x58, {0x9e, 0x00} }, +	{"Packard Bell", "DOTMA",   "v1.3303t", 0x55, 0x58, {0x9e, 0x00} }, +	{"Packard Bell", "DOTVR46", "v1.3308",  0x55, 0x58, {0x9e, 0x00} },  	/* pewpew-terminator */  	{"", "", "", 0, 0, {0, 0} }  }; @@ -701,15 +719,20 @@ MODULE_LICENSE("GPL");  MODULE_AUTHOR("Peter Feuerer");  MODULE_DESCRIPTION("Aspire One temperature and fan driver");  MODULE_ALIAS("dmi:*:*Acer*:pnAOA*:"); +MODULE_ALIAS("dmi:*:*Acer*:pnAO751h*:");  MODULE_ALIAS("dmi:*:*Acer*:pnAspire*1410*:");  MODULE_ALIAS("dmi:*:*Acer*:pnAspire*1810*:"); +MODULE_ALIAS("dmi:*:*Acer*:pnAspire*1825PTZ:");  MODULE_ALIAS("dmi:*:*Acer*:pnAO531*:"); +MODULE_ALIAS("dmi:*:*Acer*:TravelMate*7730G:");  MODULE_ALIAS("dmi:*:*Gateway*:pnAOA*:");  MODULE_ALIAS("dmi:*:*Gateway*:pnLT31*:");  MODULE_ALIAS("dmi:*:*Packard*Bell*:pnAOA*:");  MODULE_ALIAS("dmi:*:*Packard*Bell*:pnDOA*:");  MODULE_ALIAS("dmi:*:*Packard*Bell*:pnDOTMU*:"); +MODULE_ALIAS("dmi:*:*Packard*Bell*:pnENBFT*:");  MODULE_ALIAS("dmi:*:*Packard*Bell*:pnDOTMA*:"); +MODULE_ALIAS("dmi:*:*Packard*Bell*:pnDOTVR46*:");  module_init(acerhdf_init);  module_exit(acerhdf_exit); diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c index a05fc9c955d..e6c08ee8d46 100644 --- a/drivers/platform/x86/dell-laptop.c +++ b/drivers/platform/x86/dell-laptop.c @@ -212,6 +212,7 @@ static struct dmi_system_id __devinitdata dell_quirks[] = {  		},  		.driver_data = &quirk_dell_vostro_v130,  	}, +	{ }  };  static struct calling_interface_buffer *buffer; diff --git a/drivers/platform/x86/intel_ips.c b/drivers/platform/x86/intel_ips.c index f7ba316e0ed..0ffdb3cde2b 100644 --- a/drivers/platform/x86/intel_ips.c +++ b/drivers/platform/x86/intel_ips.c @@ -1565,7 +1565,7 @@ static int ips_probe(struct pci_dev *dev, const struct pci_device_id *id)  		ips->poll_turbo_status = true;  	if (!ips_get_i915_syms(ips)) { -		dev_err(&dev->dev, "failed to get i915 symbols, graphics turbo disabled\n"); +		dev_info(&dev->dev, "failed to get i915 symbols, graphics turbo disabled until i915 loads\n");  		ips->gpu_turbo_enabled = false;  	} else {  		dev_dbg(&dev->dev, "graphics turbo enabled\n"); diff --git a/drivers/platform/x86/intel_mid_powerbtn.c b/drivers/platform/x86/intel_mid_powerbtn.c index 0a3594c7e91..bcbad8452a6 100644 --- a/drivers/platform/x86/intel_mid_powerbtn.c +++ b/drivers/platform/x86/intel_mid_powerbtn.c @@ -78,7 +78,7 @@ static int __devinit mfld_pb_probe(struct platform_device *pdev)  	input_set_capability(input, EV_KEY, KEY_POWER); -	error = request_threaded_irq(irq, NULL, mfld_pb_isr, 0, +	error = request_threaded_irq(irq, NULL, mfld_pb_isr, IRQF_NO_SUSPEND,  			DRIVER_NAME, input);  	if (error) {  		dev_err(&pdev->dev, "Unable to request irq %d for mfld power" diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index cd188ab72f7..c293d0cdb10 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c @@ -902,6 +902,7 @@ read_rtc:  		}  		ds1307->nvram->attr.name = "nvram";  		ds1307->nvram->attr.mode = S_IRUGO | S_IWUSR; +		sysfs_bin_attr_init(ds1307->nvram);  		ds1307->nvram->read = ds1307_nvram_read,  		ds1307->nvram->write = ds1307_nvram_write,  		ds1307->nvram->size = chip->nvram_size; diff --git a/drivers/rtc/rtc-mpc5121.c b/drivers/rtc/rtc-mpc5121.c index 42f5f829b3e..029e421baae 100644 --- a/drivers/rtc/rtc-mpc5121.c +++ b/drivers/rtc/rtc-mpc5121.c @@ -360,12 +360,11 @@ static int __devinit mpc5121_rtc_probe(struct platform_device *op)  						&mpc5200_rtc_ops, THIS_MODULE);  	} -	rtc->rtc->uie_unsupported = 1; -  	if (IS_ERR(rtc->rtc)) {  		err = PTR_ERR(rtc->rtc);  		goto out_free_irq;  	} +	rtc->rtc->uie_unsupported = 1;  	return 0; diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c index c21871a4e73..bc2e8a7c265 100644 --- a/drivers/s390/block/dasd_eckd.c +++ b/drivers/s390/block/dasd_eckd.c @@ -2844,6 +2844,7 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track(  	sector_t recid, trkid;  	unsigned int offs;  	unsigned int count, count_to_trk_end; +	int ret;  	basedev = block->base;  	if (rq_data_dir(req) == READ) { @@ -2884,8 +2885,8 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track(  	itcw = itcw_init(cqr->data, itcw_size, itcw_op, 0, ctidaw, 0);  	if (IS_ERR(itcw)) { -		dasd_sfree_request(cqr, startdev); -		return ERR_PTR(-EINVAL); +		ret = -EINVAL; +		goto out_error;  	}  	cqr->cpaddr = itcw_get_tcw(itcw);  	if (prepare_itcw(itcw, first_trk, last_trk, @@ -2897,8 +2898,8 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track(  		/* Clock not in sync and XRC is enabled.  		 * Try again later.  		 */ -		dasd_sfree_request(cqr, startdev); -		return ERR_PTR(-EAGAIN); +		ret = -EAGAIN; +		goto out_error;  	}  	len_to_track_end = 0;  	/* @@ -2937,8 +2938,10 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track(  					tidaw_flags = 0;  				last_tidaw = itcw_add_tidaw(itcw, tidaw_flags,  							    dst, part_len); -				if (IS_ERR(last_tidaw)) -					return ERR_PTR(-EINVAL); +				if (IS_ERR(last_tidaw)) { +					ret = -EINVAL; +					goto out_error; +				}  				dst += part_len;  			}  		} @@ -2947,8 +2950,10 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track(  			dst = page_address(bv->bv_page) + bv->bv_offset;  			last_tidaw = itcw_add_tidaw(itcw, 0x00,  						    dst, bv->bv_len); -			if (IS_ERR(last_tidaw)) -				return ERR_PTR(-EINVAL); +			if (IS_ERR(last_tidaw)) { +				ret = -EINVAL; +				goto out_error; +			}  		}  	}  	last_tidaw->flags |= TIDAW_FLAGS_LAST; @@ -2968,6 +2973,9 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track(  	cqr->buildclk = get_clock();  	cqr->status = DASD_CQR_FILLED;  	return cqr; +out_error: +	dasd_sfree_request(cqr, startdev); +	return ERR_PTR(ret);  }  static struct dasd_ccw_req *dasd_eckd_build_cp(struct dasd_device *startdev, diff --git a/drivers/s390/char/vmur.c b/drivers/s390/char/vmur.c index 85f4a9a5d12..73bef0bd394 100644 --- a/drivers/s390/char/vmur.c +++ b/drivers/s390/char/vmur.c @@ -903,7 +903,7 @@ static int ur_set_online(struct ccw_device *cdev)  		goto fail_urdev_put;  	} -	cdev_init(urd->char_device, &ur_fops); +	urd->char_device->ops = &ur_fops;  	urd->char_device->dev = MKDEV(major, minor);  	urd->char_device->owner = ur_fops.owner; diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 120955c6641..8334dadc681 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -1672,7 +1672,8 @@ static void qeth_configure_blkt_default(struct qeth_card *card, char *prcd)  {  	QETH_DBF_TEXT(SETUP, 2, "cfgblkt"); -	if (prcd[74] == 0xF0 && prcd[75] == 0xF0 && prcd[76] == 0xF5) { +	if (prcd[74] == 0xF0 && prcd[75] == 0xF0 && +	    (prcd[76] == 0xF5 || prcd[76] == 0xF6)) {  		card->info.blkt.time_total = 250;  		card->info.blkt.inter_packet = 5;  		card->info.blkt.inter_packet_jumbo = 15; @@ -4540,7 +4541,8 @@ static void qeth_determine_capabilities(struct qeth_card *card)  		goto out_offline;  	}  	qeth_configure_unitaddr(card, prcd); -	qeth_configure_blkt_default(card, prcd); +	if (ddev_offline) +		qeth_configure_blkt_default(card, prcd);  	kfree(prcd);  	rc = qdio_get_ssqd_desc(ddev, &card->ssqd); diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index e002cd466e9..467dc38246f 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -4549,8 +4549,12 @@ static int ipr_ata_slave_alloc(struct scsi_device *sdev)  	ENTER;  	if (sdev->sdev_target)  		sata_port = sdev->sdev_target->hostdata; -	if (sata_port) +	if (sata_port) {  		rc = ata_sas_port_init(sata_port->ap); +		if (rc == 0) +			rc = ata_sas_sync_probe(sata_port->ap); +	} +  	if (rc)  		ipr_slave_destroy(sdev); diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c index ef9560dff29..cc83b66d45b 100644 --- a/drivers/scsi/libfc/fc_lport.c +++ b/drivers/scsi/libfc/fc_lport.c @@ -1742,17 +1742,19 @@ void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp,  	mfs = ntohs(flp->fl_csp.sp_bb_data) &  		FC_SP_BB_DATA_MASK; -	if (mfs >= FC_SP_MIN_MAX_PAYLOAD && -	    mfs <= lport->mfs) { -		lport->mfs = mfs; -		fc_host_maxframe_size(lport->host) = mfs; -	} else { + +	if (mfs < FC_SP_MIN_MAX_PAYLOAD || mfs > FC_SP_MAX_MAX_PAYLOAD) {  		FC_LPORT_DBG(lport, "FLOGI bad mfs:%hu response, "  			     "lport->mfs:%hu\n", mfs, lport->mfs);  		fc_lport_error(lport, fp);  		goto err;  	} +	if (mfs <= lport->mfs) { +		lport->mfs = mfs; +		fc_host_maxframe_size(lport->host) = mfs; +	} +  	csp_flags = ntohs(flp->fl_csp.sp_features);  	r_a_tov = ntohl(flp->fl_csp.sp_r_a_tov);  	e_d_tov = ntohl(flp->fl_csp.sp_e_d_tov); diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c index bc0cecc6ad6..441d88ad99a 100644 --- a/drivers/scsi/libsas/sas_ata.c +++ b/drivers/scsi/libsas/sas_ata.c @@ -546,11 +546,12 @@ static struct ata_port_info sata_port_info = {  	.port_ops = &sas_sata_ops  }; -int sas_ata_init_host_and_port(struct domain_device *found_dev) +int sas_ata_init(struct domain_device *found_dev)  {  	struct sas_ha_struct *ha = found_dev->port->ha;  	struct Scsi_Host *shost = ha->core.shost;  	struct ata_port *ap; +	int rc;  	ata_host_init(&found_dev->sata_dev.ata_host,  		      ha->dev, @@ -567,8 +568,11 @@ int sas_ata_init_host_and_port(struct domain_device *found_dev)  	ap->private_data = found_dev;  	ap->cbl = ATA_CBL_SATA;  	ap->scsi_host = shost; -	/* publish initialized ata port */ -	smp_wmb(); +	rc = ata_sas_port_init(ap); +	if (rc) { +		ata_sas_port_destroy(ap); +		return rc; +	}  	found_dev->sata_dev.ap = ap;  	return 0; @@ -648,18 +652,13 @@ static void sas_get_ata_command_set(struct domain_device *dev)  void sas_probe_sata(struct asd_sas_port *port)  {  	struct domain_device *dev, *n; -	int err;  	mutex_lock(&port->ha->disco_mutex); -	list_for_each_entry_safe(dev, n, &port->disco_list, disco_list_node) { +	list_for_each_entry(dev, &port->disco_list, disco_list_node) {  		if (!dev_is_sata(dev))  			continue; -		err = sas_ata_init_host_and_port(dev); -		if (err) -			sas_fail_probe(dev, __func__, err); -		else -			ata_sas_async_port_init(dev->sata_dev.ap); +		ata_sas_async_probe(dev->sata_dev.ap);  	}  	mutex_unlock(&port->ha->disco_mutex); @@ -718,18 +717,6 @@ static void async_sas_ata_eh(void *data, async_cookie_t cookie)  	sas_put_device(dev);  } -static bool sas_ata_dev_eh_valid(struct domain_device *dev) -{ -	struct ata_port *ap; - -	if (!dev_is_sata(dev)) -		return false; -	ap = dev->sata_dev.ap; -	/* consume fully initialized ata ports */ -	smp_rmb(); -	return !!ap; -} -  void sas_ata_strategy_handler(struct Scsi_Host *shost)  {  	struct sas_ha_struct *sas_ha = SHOST_TO_SAS_HA(shost); @@ -753,7 +740,7 @@ void sas_ata_strategy_handler(struct Scsi_Host *shost)  		spin_lock(&port->dev_list_lock);  		list_for_each_entry(dev, &port->dev_list, dev_list_node) { -			if (!sas_ata_dev_eh_valid(dev)) +			if (!dev_is_sata(dev))  				continue;  			async_schedule_domain(async_sas_ata_eh, dev, &async);  		} diff --git a/drivers/scsi/libsas/sas_discover.c b/drivers/scsi/libsas/sas_discover.c index 36467967560..629a0865b13 100644 --- a/drivers/scsi/libsas/sas_discover.c +++ b/drivers/scsi/libsas/sas_discover.c @@ -72,6 +72,7 @@ static int sas_get_port_device(struct asd_sas_port *port)  	struct asd_sas_phy *phy;  	struct sas_rphy *rphy;  	struct domain_device *dev; +	int rc = -ENODEV;  	dev = sas_alloc_device();  	if (!dev) @@ -110,9 +111,16 @@ static int sas_get_port_device(struct asd_sas_port *port)  	sas_init_dev(dev); +	dev->port = port;  	switch (dev->dev_type) { -	case SAS_END_DEV:  	case SATA_DEV: +		rc = sas_ata_init(dev); +		if (rc) { +			rphy = NULL; +			break; +		} +		/* fall through */ +	case SAS_END_DEV:  		rphy = sas_end_device_alloc(port->port);  		break;  	case EDGE_DEV: @@ -131,19 +139,14 @@ static int sas_get_port_device(struct asd_sas_port *port)  	if (!rphy) {  		sas_put_device(dev); -		return -ENODEV; +		return rc;  	} -	spin_lock_irq(&port->phy_list_lock); -	list_for_each_entry(phy, &port->phy_list, port_phy_el) -		sas_phy_set_target(phy, dev); -	spin_unlock_irq(&port->phy_list_lock);  	rphy->identify.phy_identifier = phy->phy->identify.phy_identifier;  	memcpy(dev->sas_addr, port->attached_sas_addr, SAS_ADDR_SIZE);  	sas_fill_in_rphy(dev, rphy);  	sas_hash_addr(dev->hashed_sas_addr, dev->sas_addr);  	port->port_dev = dev; -	dev->port = port;  	dev->linkrate = port->linkrate;  	dev->min_linkrate = port->linkrate;  	dev->max_linkrate = port->linkrate; @@ -155,6 +158,7 @@ static int sas_get_port_device(struct asd_sas_port *port)  	sas_device_set_phy(dev, port->port);  	dev->rphy = rphy; +	get_device(&dev->rphy->dev);  	if (dev_is_sata(dev) || dev->dev_type == SAS_END_DEV)  		list_add_tail(&dev->disco_list_node, &port->disco_list); @@ -164,6 +168,11 @@ static int sas_get_port_device(struct asd_sas_port *port)  		spin_unlock_irq(&port->dev_list_lock);  	} +	spin_lock_irq(&port->phy_list_lock); +	list_for_each_entry(phy, &port->phy_list, port_phy_el) +		sas_phy_set_target(phy, dev); +	spin_unlock_irq(&port->phy_list_lock); +  	return 0;  } @@ -205,8 +214,7 @@ void sas_notify_lldd_dev_gone(struct domain_device *dev)  static void sas_probe_devices(struct work_struct *work)  {  	struct domain_device *dev, *n; -	struct sas_discovery_event *ev = -		container_of(work, struct sas_discovery_event, work); +	struct sas_discovery_event *ev = to_sas_discovery_event(work);  	struct asd_sas_port *port = ev->port;  	clear_bit(DISCE_PROBE, &port->disc.pending); @@ -255,6 +263,9 @@ void sas_free_device(struct kref *kref)  {  	struct domain_device *dev = container_of(kref, typeof(*dev), kref); +	put_device(&dev->rphy->dev); +	dev->rphy = NULL; +  	if (dev->parent)  		sas_put_device(dev->parent); @@ -291,8 +302,7 @@ static void sas_unregister_common_dev(struct asd_sas_port *port, struct domain_d  static void sas_destruct_devices(struct work_struct *work)  {  	struct domain_device *dev, *n; -	struct sas_discovery_event *ev = -		container_of(work, struct sas_discovery_event, work); +	struct sas_discovery_event *ev = to_sas_discovery_event(work);  	struct asd_sas_port *port = ev->port;  	clear_bit(DISCE_DESTRUCT, &port->disc.pending); @@ -302,7 +312,6 @@ static void sas_destruct_devices(struct work_struct *work)  		sas_remove_children(&dev->rphy->dev);  		sas_rphy_delete(dev->rphy); -		dev->rphy = NULL;  		sas_unregister_common_dev(port, dev);  	}  } @@ -314,11 +323,11 @@ void sas_unregister_dev(struct asd_sas_port *port, struct domain_device *dev)  		/* this rphy never saw sas_rphy_add */  		list_del_init(&dev->disco_list_node);  		sas_rphy_free(dev->rphy); -		dev->rphy = NULL;  		sas_unregister_common_dev(port, dev); +		return;  	} -	if (dev->rphy && !test_and_set_bit(SAS_DEV_DESTROY, &dev->state)) { +	if (!test_and_set_bit(SAS_DEV_DESTROY, &dev->state)) {  		sas_rphy_unlink(dev->rphy);  		list_move_tail(&dev->disco_list_node, &port->destroy_list);  		sas_discover_event(dev->port, DISCE_DESTRUCT); @@ -377,8 +386,7 @@ static void sas_discover_domain(struct work_struct *work)  {  	struct domain_device *dev;  	int error = 0; -	struct sas_discovery_event *ev = -		container_of(work, struct sas_discovery_event, work); +	struct sas_discovery_event *ev = to_sas_discovery_event(work);  	struct asd_sas_port *port = ev->port;  	clear_bit(DISCE_DISCOVER_DOMAIN, &port->disc.pending); @@ -419,8 +427,6 @@ static void sas_discover_domain(struct work_struct *work)  	if (error) {  		sas_rphy_free(dev->rphy); -		dev->rphy = NULL; -  		list_del_init(&dev->disco_list_node);  		spin_lock_irq(&port->dev_list_lock);  		list_del_init(&dev->dev_list_node); @@ -437,8 +443,7 @@ static void sas_discover_domain(struct work_struct *work)  static void sas_revalidate_domain(struct work_struct *work)  {  	int res = 0; -	struct sas_discovery_event *ev = -		container_of(work, struct sas_discovery_event, work); +	struct sas_discovery_event *ev = to_sas_discovery_event(work);  	struct asd_sas_port *port = ev->port;  	struct sas_ha_struct *ha = port->ha; @@ -466,21 +471,25 @@ static void sas_revalidate_domain(struct work_struct *work)  /* ---------- Events ---------- */ -static void sas_chain_work(struct sas_ha_struct *ha, struct work_struct *work) +static void sas_chain_work(struct sas_ha_struct *ha, struct sas_work *sw)  { -	/* chained work is not subject to SA_HA_DRAINING or SAS_HA_REGISTERED */ -	scsi_queue_work(ha->core.shost, work); +	/* chained work is not subject to SA_HA_DRAINING or +	 * SAS_HA_REGISTERED, because it is either submitted in the +	 * workqueue, or known to be submitted from a context that is +	 * not racing against draining +	 */ +	scsi_queue_work(ha->core.shost, &sw->work);  }  static void sas_chain_event(int event, unsigned long *pending, -			    struct work_struct *work, +			    struct sas_work *sw,  			    struct sas_ha_struct *ha)  {  	if (!test_and_set_bit(event, pending)) {  		unsigned long flags;  		spin_lock_irqsave(&ha->state_lock, flags); -		sas_chain_work(ha, work); +		sas_chain_work(ha, sw);  		spin_unlock_irqrestore(&ha->state_lock, flags);  	}  } @@ -519,7 +528,7 @@ void sas_init_disc(struct sas_discovery *disc, struct asd_sas_port *port)  	disc->pending = 0;  	for (i = 0; i < DISC_NUM_EVENTS; i++) { -		INIT_WORK(&disc->disc_work[i].work, sas_event_fns[i]); +		INIT_SAS_WORK(&disc->disc_work[i].work, sas_event_fns[i]);  		disc->disc_work[i].port = port;  	}  } diff --git a/drivers/scsi/libsas/sas_event.c b/drivers/scsi/libsas/sas_event.c index 16639bbae62..4e4292d210c 100644 --- a/drivers/scsi/libsas/sas_event.c +++ b/drivers/scsi/libsas/sas_event.c @@ -27,19 +27,21 @@  #include "sas_internal.h"  #include "sas_dump.h" -void sas_queue_work(struct sas_ha_struct *ha, struct work_struct *work) +void sas_queue_work(struct sas_ha_struct *ha, struct sas_work *sw)  {  	if (!test_bit(SAS_HA_REGISTERED, &ha->state))  		return; -	if (test_bit(SAS_HA_DRAINING, &ha->state)) -		list_add(&work->entry, &ha->defer_q); -	else -		scsi_queue_work(ha->core.shost, work); +	if (test_bit(SAS_HA_DRAINING, &ha->state)) { +		/* add it to the defer list, if not already pending */ +		if (list_empty(&sw->drain_node)) +			list_add(&sw->drain_node, &ha->defer_q); +	} else +		scsi_queue_work(ha->core.shost, &sw->work);  }  static void sas_queue_event(int event, unsigned long *pending, -			    struct work_struct *work, +			    struct sas_work *work,  			    struct sas_ha_struct *ha)  {  	if (!test_and_set_bit(event, pending)) { @@ -55,7 +57,7 @@ static void sas_queue_event(int event, unsigned long *pending,  void __sas_drain_work(struct sas_ha_struct *ha)  {  	struct workqueue_struct *wq = ha->core.shost->work_q; -	struct work_struct *w, *_w; +	struct sas_work *sw, *_sw;  	set_bit(SAS_HA_DRAINING, &ha->state);  	/* flush submitters */ @@ -66,9 +68,9 @@ void __sas_drain_work(struct sas_ha_struct *ha)  	spin_lock_irq(&ha->state_lock);  	clear_bit(SAS_HA_DRAINING, &ha->state); -	list_for_each_entry_safe(w, _w, &ha->defer_q, entry) { -		list_del_init(&w->entry); -		sas_queue_work(ha, w); +	list_for_each_entry_safe(sw, _sw, &ha->defer_q, drain_node) { +		list_del_init(&sw->drain_node); +		sas_queue_work(ha, sw);  	}  	spin_unlock_irq(&ha->state_lock);  } @@ -151,7 +153,7 @@ int sas_init_events(struct sas_ha_struct *sas_ha)  	int i;  	for (i = 0; i < HA_NUM_EVENTS; i++) { -		INIT_WORK(&sas_ha->ha_events[i].work, sas_ha_event_fns[i]); +		INIT_SAS_WORK(&sas_ha->ha_events[i].work, sas_ha_event_fns[i]);  		sas_ha->ha_events[i].ha = sas_ha;  	} diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c index 05acd9e35fc..caa0525d252 100644 --- a/drivers/scsi/libsas/sas_expander.c +++ b/drivers/scsi/libsas/sas_expander.c @@ -202,6 +202,7 @@ static void sas_set_ex_phy(struct domain_device *dev, int phy_id, void *rsp)  	u8 sas_addr[SAS_ADDR_SIZE];  	struct smp_resp *resp = rsp;  	struct discover_resp *dr = &resp->disc; +	struct sas_ha_struct *ha = dev->port->ha;  	struct expander_device *ex = &dev->ex_dev;  	struct ex_phy *phy = &ex->ex_phy[phy_id];  	struct sas_rphy *rphy = dev->rphy; @@ -209,6 +210,8 @@ static void sas_set_ex_phy(struct domain_device *dev, int phy_id, void *rsp)  	char *type;  	if (new_phy) { +		if (WARN_ON_ONCE(test_bit(SAS_HA_ATA_EH_ACTIVE, &ha->state))) +			return;  		phy->phy = sas_phy_alloc(&rphy->dev, phy_id);  		/* FIXME: error_handling */ @@ -233,6 +236,8 @@ static void sas_set_ex_phy(struct domain_device *dev, int phy_id, void *rsp)  	memcpy(sas_addr, phy->attached_sas_addr, SAS_ADDR_SIZE);  	phy->attached_dev_type = to_dev_type(dr); +	if (test_bit(SAS_HA_ATA_EH_ACTIVE, &ha->state)) +		goto out;  	phy->phy_id = phy_id;  	phy->linkrate = dr->linkrate;  	phy->attached_sata_host = dr->attached_sata_host; @@ -240,7 +245,14 @@ static void sas_set_ex_phy(struct domain_device *dev, int phy_id, void *rsp)  	phy->attached_sata_ps   = dr->attached_sata_ps;  	phy->attached_iproto = dr->iproto << 1;  	phy->attached_tproto = dr->tproto << 1; -	memcpy(phy->attached_sas_addr, dr->attached_sas_addr, SAS_ADDR_SIZE); +	/* help some expanders that fail to zero sas_address in the 'no +	 * device' case +	 */ +	if (phy->attached_dev_type == NO_DEVICE || +	    phy->linkrate < SAS_LINK_RATE_1_5_GBPS) +		memset(phy->attached_sas_addr, 0, SAS_ADDR_SIZE); +	else +		memcpy(phy->attached_sas_addr, dr->attached_sas_addr, SAS_ADDR_SIZE);  	phy->attached_phy_id = dr->attached_phy_id;  	phy->phy_change_count = dr->change_count;  	phy->routing_attr = dr->routing_attr; @@ -266,6 +278,7 @@ static void sas_set_ex_phy(struct domain_device *dev, int phy_id, void *rsp)  			return;  		} + out:  	switch (phy->attached_dev_type) {  	case SATA_PENDING:  		type = "stp pending"; @@ -304,7 +317,15 @@ static void sas_set_ex_phy(struct domain_device *dev, int phy_id, void *rsp)  	else  		return; -	SAS_DPRINTK("ex %016llx phy%02d:%c:%X attached: %016llx (%s)\n", +	/* if the attached device type changed and ata_eh is active, +	 * make sure we run revalidation when eh completes (see: +	 * sas_enable_revalidation) +	 */ +	if (test_bit(SAS_HA_ATA_EH_ACTIVE, &ha->state)) +		set_bit(DISCE_REVALIDATE_DOMAIN, &dev->port->disc.pending); + +	SAS_DPRINTK("%sex %016llx phy%02d:%c:%X attached: %016llx (%s)\n", +		    test_bit(SAS_HA_ATA_EH_ACTIVE, &ha->state) ? "ata: " : "",  		    SAS_ADDR(dev->sas_addr), phy->phy_id,  		    sas_route_char(dev, phy), phy->linkrate,  		    SAS_ADDR(phy->attached_sas_addr), type); @@ -776,13 +797,16 @@ static struct domain_device *sas_ex_discover_end_dev(  		if (res)  			goto out_free; +		sas_init_dev(child); +		res = sas_ata_init(child); +		if (res) +			goto out_free;  		rphy = sas_end_device_alloc(phy->port); -		if (unlikely(!rphy)) +		if (!rphy)  			goto out_free; -		sas_init_dev(child); -  		child->rphy = rphy; +		get_device(&rphy->dev);  		list_add_tail(&child->disco_list_node, &parent->port->disco_list); @@ -806,6 +830,7 @@ static struct domain_device *sas_ex_discover_end_dev(  		sas_init_dev(child);  		child->rphy = rphy; +		get_device(&rphy->dev);  		sas_fill_in_rphy(child, rphy);  		list_add_tail(&child->disco_list_node, &parent->port->disco_list); @@ -830,8 +855,6 @@ static struct domain_device *sas_ex_discover_end_dev(   out_list_del:  	sas_rphy_free(child->rphy); -	child->rphy = NULL; -  	list_del(&child->disco_list_node);  	spin_lock_irq(&parent->port->dev_list_lock);  	list_del(&child->dev_list_node); @@ -911,6 +934,7 @@ static struct domain_device *sas_ex_discover_expander(  	}  	port = parent->port;  	child->rphy = rphy; +	get_device(&rphy->dev);  	edev = rphy_to_expander_device(rphy);  	child->dev_type = phy->attached_dev_type;  	kref_get(&parent->kref); @@ -934,6 +958,7 @@ static struct domain_device *sas_ex_discover_expander(  	res = sas_discover_expander(child);  	if (res) { +		sas_rphy_delete(rphy);  		spin_lock_irq(&parent->port->dev_list_lock);  		list_del(&child->dev_list_node);  		spin_unlock_irq(&parent->port->dev_list_lock); @@ -1718,9 +1743,17 @@ static int sas_find_bcast_phy(struct domain_device *dev, int *phy_id,  		int phy_change_count = 0;  		res = sas_get_phy_change_count(dev, i, &phy_change_count); -		if (res) -			goto out; -		else if (phy_change_count != ex->ex_phy[i].phy_change_count) { +		switch (res) { +		case SMP_RESP_PHY_VACANT: +		case SMP_RESP_NO_PHY: +			continue; +		case SMP_RESP_FUNC_ACC: +			break; +		default: +			return res; +		} + +		if (phy_change_count != ex->ex_phy[i].phy_change_count) {  			if (update)  				ex->ex_phy[i].phy_change_count =  					phy_change_count; @@ -1728,8 +1761,7 @@ static int sas_find_bcast_phy(struct domain_device *dev, int *phy_id,  			return 0;  		}  	} -out: -	return res; +	return 0;  }  static int sas_get_ex_change_count(struct domain_device *dev, int *ecc) diff --git a/drivers/scsi/libsas/sas_init.c b/drivers/scsi/libsas/sas_init.c index 120bff64be3..10cb5ae3097 100644 --- a/drivers/scsi/libsas/sas_init.c +++ b/drivers/scsi/libsas/sas_init.c @@ -94,8 +94,7 @@ void sas_hash_addr(u8 *hashed, const u8 *sas_addr)  void sas_hae_reset(struct work_struct *work)  { -	struct sas_ha_event *ev = -		container_of(work, struct sas_ha_event, work); +	struct sas_ha_event *ev = to_sas_ha_event(work);  	struct sas_ha_struct *ha = ev->ha;  	clear_bit(HAE_RESET, &ha->pending); @@ -369,14 +368,14 @@ static void sas_phy_release(struct sas_phy *phy)  static void phy_reset_work(struct work_struct *work)  { -	struct sas_phy_data *d = container_of(work, typeof(*d), reset_work); +	struct sas_phy_data *d = container_of(work, typeof(*d), reset_work.work);  	d->reset_result = transport_sas_phy_reset(d->phy, d->hard_reset);  }  static void phy_enable_work(struct work_struct *work)  { -	struct sas_phy_data *d = container_of(work, typeof(*d), enable_work); +	struct sas_phy_data *d = container_of(work, typeof(*d), enable_work.work);  	d->enable_result = sas_phy_enable(d->phy, d->enable);  } @@ -389,8 +388,8 @@ static int sas_phy_setup(struct sas_phy *phy)  		return -ENOMEM;  	mutex_init(&d->event_lock); -	INIT_WORK(&d->reset_work, phy_reset_work); -	INIT_WORK(&d->enable_work, phy_enable_work); +	INIT_SAS_WORK(&d->reset_work, phy_reset_work); +	INIT_SAS_WORK(&d->enable_work, phy_enable_work);  	d->phy = phy;  	phy->hostdata = d; diff --git a/drivers/scsi/libsas/sas_internal.h b/drivers/scsi/libsas/sas_internal.h index f05c6387994..507e4cf12e5 100644 --- a/drivers/scsi/libsas/sas_internal.h +++ b/drivers/scsi/libsas/sas_internal.h @@ -45,10 +45,10 @@ struct sas_phy_data {  	struct mutex event_lock;  	int hard_reset;  	int reset_result; -	struct work_struct reset_work; +	struct sas_work reset_work;  	int enable;  	int enable_result; -	struct work_struct enable_work; +	struct sas_work enable_work;  };  void sas_scsi_recover_host(struct Scsi_Host *shost); @@ -80,7 +80,7 @@ void sas_porte_broadcast_rcvd(struct work_struct *work);  void sas_porte_link_reset_err(struct work_struct *work);  void sas_porte_timer_event(struct work_struct *work);  void sas_porte_hard_reset(struct work_struct *work); -void sas_queue_work(struct sas_ha_struct *ha, struct work_struct *work); +void sas_queue_work(struct sas_ha_struct *ha, struct sas_work *sw);  int sas_notify_lldd_dev_found(struct domain_device *);  void sas_notify_lldd_dev_gone(struct domain_device *); diff --git a/drivers/scsi/libsas/sas_phy.c b/drivers/scsi/libsas/sas_phy.c index dcfd4a9105c..521422e857a 100644 --- a/drivers/scsi/libsas/sas_phy.c +++ b/drivers/scsi/libsas/sas_phy.c @@ -32,8 +32,7 @@  static void sas_phye_loss_of_signal(struct work_struct *work)  { -	struct asd_sas_event *ev = -		container_of(work, struct asd_sas_event, work); +	struct asd_sas_event *ev = to_asd_sas_event(work);  	struct asd_sas_phy *phy = ev->phy;  	clear_bit(PHYE_LOSS_OF_SIGNAL, &phy->phy_events_pending); @@ -43,8 +42,7 @@ static void sas_phye_loss_of_signal(struct work_struct *work)  static void sas_phye_oob_done(struct work_struct *work)  { -	struct asd_sas_event *ev = -		container_of(work, struct asd_sas_event, work); +	struct asd_sas_event *ev = to_asd_sas_event(work);  	struct asd_sas_phy *phy = ev->phy;  	clear_bit(PHYE_OOB_DONE, &phy->phy_events_pending); @@ -53,8 +51,7 @@ static void sas_phye_oob_done(struct work_struct *work)  static void sas_phye_oob_error(struct work_struct *work)  { -	struct asd_sas_event *ev = -		container_of(work, struct asd_sas_event, work); +	struct asd_sas_event *ev = to_asd_sas_event(work);  	struct asd_sas_phy *phy = ev->phy;  	struct sas_ha_struct *sas_ha = phy->ha;  	struct asd_sas_port *port = phy->port; @@ -85,8 +82,7 @@ static void sas_phye_oob_error(struct work_struct *work)  static void sas_phye_spinup_hold(struct work_struct *work)  { -	struct asd_sas_event *ev = -		container_of(work, struct asd_sas_event, work); +	struct asd_sas_event *ev = to_asd_sas_event(work);  	struct asd_sas_phy *phy = ev->phy;  	struct sas_ha_struct *sas_ha = phy->ha;  	struct sas_internal *i = @@ -127,14 +123,12 @@ int sas_register_phys(struct sas_ha_struct *sas_ha)  		phy->error = 0;  		INIT_LIST_HEAD(&phy->port_phy_el);  		for (k = 0; k < PORT_NUM_EVENTS; k++) { -			INIT_WORK(&phy->port_events[k].work, -				  sas_port_event_fns[k]); +			INIT_SAS_WORK(&phy->port_events[k].work, sas_port_event_fns[k]);  			phy->port_events[k].phy = phy;  		}  		for (k = 0; k < PHY_NUM_EVENTS; k++) { -			INIT_WORK(&phy->phy_events[k].work, -				  sas_phy_event_fns[k]); +			INIT_SAS_WORK(&phy->phy_events[k].work, sas_phy_event_fns[k]);  			phy->phy_events[k].phy = phy;  		} @@ -144,8 +138,7 @@ int sas_register_phys(struct sas_ha_struct *sas_ha)  		spin_lock_init(&phy->sas_prim_lock);  		phy->frame_rcvd_size = 0; -		phy->phy = sas_phy_alloc(&sas_ha->core.shost->shost_gendev, -					 i); +		phy->phy = sas_phy_alloc(&sas_ha->core.shost->shost_gendev, i);  		if (!phy->phy)  			return -ENOMEM; diff --git a/drivers/scsi/libsas/sas_port.c b/drivers/scsi/libsas/sas_port.c index eb19c016d50..e884a8c58a0 100644 --- a/drivers/scsi/libsas/sas_port.c +++ b/drivers/scsi/libsas/sas_port.c @@ -123,7 +123,7 @@ static void sas_form_port(struct asd_sas_phy *phy)  	spin_unlock_irqrestore(&sas_ha->phy_port_lock, flags);  	if (!port->port) { -		port->port = sas_port_alloc(phy->phy->dev.parent, phy->id); +		port->port = sas_port_alloc(phy->phy->dev.parent, port->id);  		BUG_ON(!port->port);  		sas_port_add(port->port);  	} @@ -208,8 +208,7 @@ void sas_deform_port(struct asd_sas_phy *phy, int gone)  void sas_porte_bytes_dmaed(struct work_struct *work)  { -	struct asd_sas_event *ev = -		container_of(work, struct asd_sas_event, work); +	struct asd_sas_event *ev = to_asd_sas_event(work);  	struct asd_sas_phy *phy = ev->phy;  	clear_bit(PORTE_BYTES_DMAED, &phy->port_events_pending); @@ -219,8 +218,7 @@ void sas_porte_bytes_dmaed(struct work_struct *work)  void sas_porte_broadcast_rcvd(struct work_struct *work)  { -	struct asd_sas_event *ev = -		container_of(work, struct asd_sas_event, work); +	struct asd_sas_event *ev = to_asd_sas_event(work);  	struct asd_sas_phy *phy = ev->phy;  	unsigned long flags;  	u32 prim; @@ -237,8 +235,7 @@ void sas_porte_broadcast_rcvd(struct work_struct *work)  void sas_porte_link_reset_err(struct work_struct *work)  { -	struct asd_sas_event *ev = -		container_of(work, struct asd_sas_event, work); +	struct asd_sas_event *ev = to_asd_sas_event(work);  	struct asd_sas_phy *phy = ev->phy;  	clear_bit(PORTE_LINK_RESET_ERR, &phy->port_events_pending); @@ -248,8 +245,7 @@ void sas_porte_link_reset_err(struct work_struct *work)  void sas_porte_timer_event(struct work_struct *work)  { -	struct asd_sas_event *ev = -		container_of(work, struct asd_sas_event, work); +	struct asd_sas_event *ev = to_asd_sas_event(work);  	struct asd_sas_phy *phy = ev->phy;  	clear_bit(PORTE_TIMER_EVENT, &phy->port_events_pending); @@ -259,8 +255,7 @@ void sas_porte_timer_event(struct work_struct *work)  void sas_porte_hard_reset(struct work_struct *work)  { -	struct asd_sas_event *ev = -		container_of(work, struct asd_sas_event, work); +	struct asd_sas_event *ev = to_asd_sas_event(work);  	struct asd_sas_phy *phy = ev->phy;  	clear_bit(PORTE_HARD_RESET, &phy->port_events_pending); diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index ead6405f3e5..5dfd7495d1a 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -1638,7 +1638,7 @@ struct request_queue *__scsi_alloc_queue(struct Scsi_Host *shost,  					 request_fn_proc *request_fn)  {  	struct request_queue *q; -	struct device *dev = shost->shost_gendev.parent; +	struct device *dev = shost->dma_dev;  	q = blk_init_queue(request_fn, NULL);  	if (!q) diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 3ed748355b9..00c024039c9 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -74,7 +74,7 @@ config SPI_ATMEL  	  This selects a driver for the Atmel SPI Controller, present on  	  many AT32 (AVR32) and AT91 (ARM) chips. -config SPI_BFIN +config SPI_BFIN5XX  	tristate "SPI controller driver for ADI Blackfin5xx"  	depends on BLACKFIN  	help diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index a1d48e0ba3d..9d75d2198ff 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -15,7 +15,7 @@ obj-$(CONFIG_SPI_ATMEL)			+= spi-atmel.o  obj-$(CONFIG_SPI_ATH79)			+= spi-ath79.o  obj-$(CONFIG_SPI_AU1550)		+= spi-au1550.o  obj-$(CONFIG_SPI_BCM63XX)		+= spi-bcm63xx.o -obj-$(CONFIG_SPI_BFIN)			+= spi-bfin5xx.o +obj-$(CONFIG_SPI_BFIN5XX)		+= spi-bfin5xx.o  obj-$(CONFIG_SPI_BFIN_SPORT)		+= spi-bfin-sport.o  obj-$(CONFIG_SPI_BITBANG)		+= spi-bitbang.o  obj-$(CONFIG_SPI_BUTTERFLY)		+= spi-butterfly.o diff --git a/drivers/spi/spi-bcm63xx.c b/drivers/spi/spi-bcm63xx.c index f01b2648452..7491971139a 100644 --- a/drivers/spi/spi-bcm63xx.c +++ b/drivers/spi/spi-bcm63xx.c @@ -1,7 +1,7 @@  /*   * Broadcom BCM63xx SPI controller support   * - * Copyright (C) 2009-2011 Florian Fainelli <florian@openwrt.org> + * Copyright (C) 2009-2012 Florian Fainelli <florian@openwrt.org>   * Copyright (C) 2010 Tanguy Bouzeloc <tanguy.bouzeloc@efixo.com>   *   * This program is free software; you can redistribute it and/or @@ -30,6 +30,8 @@  #include <linux/spi/spi.h>  #include <linux/completion.h>  #include <linux/err.h> +#include <linux/workqueue.h> +#include <linux/pm_runtime.h>  #include <bcm63xx_dev_spi.h> @@ -37,8 +39,6 @@  #define DRV_VER		"0.1.2"  struct bcm63xx_spi { -	spinlock_t		lock; -	int			stopping;  	struct completion	done;  	void __iomem		*regs; @@ -96,17 +96,12 @@ static const unsigned bcm63xx_spi_freq_table[SPI_CLK_MASK][2] = {  	{   391000, SPI_CLK_0_391MHZ }  }; -static int bcm63xx_spi_setup_transfer(struct spi_device *spi, -				      struct spi_transfer *t) +static int bcm63xx_spi_check_transfer(struct spi_device *spi, +					struct spi_transfer *t)  { -	struct bcm63xx_spi *bs = spi_master_get_devdata(spi->master);  	u8 bits_per_word; -	u8 clk_cfg, reg; -	u32 hz; -	int i;  	bits_per_word = (t) ? t->bits_per_word : spi->bits_per_word; -	hz = (t) ? t->speed_hz : spi->max_speed_hz;  	if (bits_per_word != 8) {  		dev_err(&spi->dev, "%s, unsupported bits_per_word=%d\n",  			__func__, bits_per_word); @@ -119,6 +114,19 @@ static int bcm63xx_spi_setup_transfer(struct spi_device *spi,  		return -EINVAL;  	} +	return 0; +} + +static void bcm63xx_spi_setup_transfer(struct spi_device *spi, +				      struct spi_transfer *t) +{ +	struct bcm63xx_spi *bs = spi_master_get_devdata(spi->master); +	u32 hz; +	u8 clk_cfg, reg; +	int i; + +	hz = (t) ? t->speed_hz : spi->max_speed_hz; +  	/* Find the closest clock configuration */  	for (i = 0; i < SPI_CLK_MASK; i++) {  		if (hz <= bcm63xx_spi_freq_table[i][0]) { @@ -139,8 +147,6 @@ static int bcm63xx_spi_setup_transfer(struct spi_device *spi,  	bcm_spi_writeb(bs, reg, SPI_CLK_CFG);  	dev_dbg(&spi->dev, "Setting clock register to %02x (hz %d)\n",  		clk_cfg, hz); - -	return 0;  }  /* the spi->mode bits understood by this driver: */ @@ -153,9 +159,6 @@ static int bcm63xx_spi_setup(struct spi_device *spi)  	bs = spi_master_get_devdata(spi->master); -	if (bs->stopping) -		return -ESHUTDOWN; -  	if (!spi->bits_per_word)  		spi->bits_per_word = 8; @@ -165,7 +168,7 @@ static int bcm63xx_spi_setup(struct spi_device *spi)  		return -EINVAL;  	} -	ret = bcm63xx_spi_setup_transfer(spi, NULL); +	ret = bcm63xx_spi_check_transfer(spi, NULL);  	if (ret < 0) {  		dev_err(&spi->dev, "setup: unsupported mode bits %x\n",  			spi->mode & ~MODEBITS); @@ -190,28 +193,29 @@ static void bcm63xx_spi_fill_tx_fifo(struct bcm63xx_spi *bs)  	bs->remaining_bytes -= size;  } -static int bcm63xx_txrx_bufs(struct spi_device *spi, struct spi_transfer *t) +static unsigned int bcm63xx_txrx_bufs(struct spi_device *spi, +					struct spi_transfer *t)  {  	struct bcm63xx_spi *bs = spi_master_get_devdata(spi->master);  	u16 msg_ctl;  	u16 cmd; +	/* Disable the CMD_DONE interrupt */ +	bcm_spi_writeb(bs, 0, SPI_INT_MASK); +  	dev_dbg(&spi->dev, "txrx: tx %p, rx %p, len %d\n",  		t->tx_buf, t->rx_buf, t->len);  	/* Transmitter is inhibited */  	bs->tx_ptr = t->tx_buf;  	bs->rx_ptr = t->rx_buf; -	init_completion(&bs->done);  	if (t->tx_buf) {  		bs->remaining_bytes = t->len;  		bcm63xx_spi_fill_tx_fifo(bs);  	} -	/* Enable the command done interrupt which -	 * we use to determine completion of a command */ -	bcm_spi_writeb(bs, SPI_INTR_CMD_DONE, SPI_INT_MASK); +	init_completion(&bs->done);  	/* Fill in the Message control register */  	msg_ctl = (t->len << SPI_BYTE_CNT_SHIFT); @@ -230,33 +234,76 @@ static int bcm63xx_txrx_bufs(struct spi_device *spi, struct spi_transfer *t)  	cmd |= (0 << SPI_CMD_PREPEND_BYTE_CNT_SHIFT);  	cmd |= (spi->chip_select << SPI_CMD_DEVICE_ID_SHIFT);  	bcm_spi_writew(bs, cmd, SPI_CMD); -	wait_for_completion(&bs->done); -	/* Disable the CMD_DONE interrupt */ -	bcm_spi_writeb(bs, 0, SPI_INT_MASK); +	/* Enable the CMD_DONE interrupt */ +	bcm_spi_writeb(bs, SPI_INTR_CMD_DONE, SPI_INT_MASK);  	return t->len - bs->remaining_bytes;  } -static int bcm63xx_transfer(struct spi_device *spi, struct spi_message *m) +static int bcm63xx_spi_prepare_transfer(struct spi_master *master)  { -	struct bcm63xx_spi *bs = spi_master_get_devdata(spi->master); -	struct spi_transfer *t; -	int ret = 0; +	struct bcm63xx_spi *bs = spi_master_get_devdata(master); -	if (unlikely(list_empty(&m->transfers))) -		return -EINVAL; +	pm_runtime_get_sync(&bs->pdev->dev); -	if (bs->stopping) -		return -ESHUTDOWN; +	return 0; +} + +static int bcm63xx_spi_unprepare_transfer(struct spi_master *master) +{ +	struct bcm63xx_spi *bs = spi_master_get_devdata(master); + +	pm_runtime_put(&bs->pdev->dev); + +	return 0; +} + +static int bcm63xx_spi_transfer_one(struct spi_master *master, +					struct spi_message *m) +{ +	struct bcm63xx_spi *bs = spi_master_get_devdata(master); +	struct spi_transfer *t; +	struct spi_device *spi = m->spi; +	int status = 0; +	unsigned int timeout = 0;  	list_for_each_entry(t, &m->transfers, transfer_list) { -		ret += bcm63xx_txrx_bufs(spi, t); -	} +		unsigned int len = t->len; +		u8 rx_tail; -	m->complete(m->context); +		status = bcm63xx_spi_check_transfer(spi, t); +		if (status < 0) +			goto exit; -	return ret; +		/* configure adapter for a new transfer */ +		bcm63xx_spi_setup_transfer(spi, t); + +		while (len) { +			/* send the data */ +			len -= bcm63xx_txrx_bufs(spi, t); + +			timeout = wait_for_completion_timeout(&bs->done, HZ); +			if (!timeout) { +				status = -ETIMEDOUT; +				goto exit; +			} + +			/* read out all data */ +			rx_tail = bcm_spi_readb(bs, SPI_RX_TAIL); + +			/* Read out all the data */ +			if (rx_tail) +				memcpy_fromio(bs->rx_ptr, bs->rx_io, rx_tail); +		} + +		m->actual_length += t->len; +	} +exit: +	m->status = status; +	spi_finalize_current_message(master); + +	return 0;  }  /* This driver supports single master mode only. Hence @@ -267,39 +314,15 @@ static irqreturn_t bcm63xx_spi_interrupt(int irq, void *dev_id)  	struct spi_master *master = (struct spi_master *)dev_id;  	struct bcm63xx_spi *bs = spi_master_get_devdata(master);  	u8 intr; -	u16 cmd;  	/* Read interupts and clear them immediately */  	intr = bcm_spi_readb(bs, SPI_INT_STATUS);  	bcm_spi_writeb(bs, SPI_INTR_CLEAR_ALL, SPI_INT_STATUS);  	bcm_spi_writeb(bs, 0, SPI_INT_MASK); -	/* A tansfer completed */ -	if (intr & SPI_INTR_CMD_DONE) { -		u8 rx_tail; - -		rx_tail = bcm_spi_readb(bs, SPI_RX_TAIL); - -		/* Read out all the data */ -		if (rx_tail) -			memcpy_fromio(bs->rx_ptr, bs->rx_io, rx_tail); - -		/* See if there is more data to send */ -		if (bs->remaining_bytes > 0) { -			bcm63xx_spi_fill_tx_fifo(bs); - -			/* Start the transfer */ -			bcm_spi_writew(bs, SPI_HD_W << SPI_MSG_TYPE_SHIFT, -				       SPI_MSG_CTL); -			cmd = bcm_spi_readw(bs, SPI_CMD); -			cmd |= SPI_CMD_START_IMMEDIATE; -			cmd |= (0 << SPI_CMD_PREPEND_BYTE_CNT_SHIFT); -			bcm_spi_writeb(bs, SPI_INTR_CMD_DONE, SPI_INT_MASK); -			bcm_spi_writew(bs, cmd, SPI_CMD); -		} else { -			complete(&bs->done); -		} -	} +	/* A transfer completed */ +	if (intr & SPI_INTR_CMD_DONE) +		complete(&bs->done);  	return IRQ_HANDLED;  } @@ -345,7 +368,6 @@ static int __devinit bcm63xx_spi_probe(struct platform_device *pdev)  	}  	bs = spi_master_get_devdata(master); -	init_completion(&bs->done);  	platform_set_drvdata(pdev, master);  	bs->pdev = pdev; @@ -379,12 +401,13 @@ static int __devinit bcm63xx_spi_probe(struct platform_device *pdev)  	master->bus_num = pdata->bus_num;  	master->num_chipselect = pdata->num_chipselect;  	master->setup = bcm63xx_spi_setup; -	master->transfer = bcm63xx_transfer; +	master->prepare_transfer_hardware = bcm63xx_spi_prepare_transfer; +	master->unprepare_transfer_hardware = bcm63xx_spi_unprepare_transfer; +	master->transfer_one_message = bcm63xx_spi_transfer_one; +	master->mode_bits = MODEBITS;  	bs->speed_hz = pdata->speed_hz; -	bs->stopping = 0;  	bs->tx_io = (u8 *)(bs->regs + bcm63xx_spireg(SPI_MSG_DATA));  	bs->rx_io = (const u8 *)(bs->regs + bcm63xx_spireg(SPI_RX_DATA)); -	spin_lock_init(&bs->lock);  	/* Initialize hardware */  	clk_enable(bs->clk); @@ -418,18 +441,16 @@ static int __devexit bcm63xx_spi_remove(struct platform_device *pdev)  	struct spi_master *master = platform_get_drvdata(pdev);  	struct bcm63xx_spi *bs = spi_master_get_devdata(master); +	spi_unregister_master(master); +  	/* reset spi block */  	bcm_spi_writeb(bs, 0, SPI_INT_MASK); -	spin_lock(&bs->lock); -	bs->stopping = 1;  	/* HW shutdown */  	clk_disable(bs->clk);  	clk_put(bs->clk); -	spin_unlock(&bs->lock);  	platform_set_drvdata(pdev, 0); -	spi_unregister_master(master);  	return 0;  } diff --git a/drivers/spi/spi-bfin-sport.c b/drivers/spi/spi-bfin-sport.c index 248a2cc671a..1fe51198a62 100644 --- a/drivers/spi/spi-bfin-sport.c +++ b/drivers/spi/spi-bfin-sport.c @@ -252,19 +252,15 @@ static void  bfin_sport_spi_restore_state(struct bfin_sport_spi_master_data *drv_data)  {  	struct bfin_sport_spi_slave_data *chip = drv_data->cur_chip; -	unsigned int bits = (drv_data->ops == &bfin_sport_transfer_ops_u8 ? 7 : 15);  	bfin_sport_spi_disable(drv_data);  	dev_dbg(drv_data->dev, "restoring spi ctl state\n");  	bfin_write(&drv_data->regs->tcr1, chip->ctl_reg); -	bfin_write(&drv_data->regs->tcr2, bits);  	bfin_write(&drv_data->regs->tclkdiv, chip->baud); -	bfin_write(&drv_data->regs->tfsdiv, bits);  	SSYNC();  	bfin_write(&drv_data->regs->rcr1, chip->ctl_reg & ~(ITCLK | ITFS)); -	bfin_write(&drv_data->regs->rcr2, bits);  	SSYNC();  	bfin_sport_spi_cs_active(chip); @@ -420,11 +416,15 @@ bfin_sport_spi_pump_transfers(unsigned long data)  	drv_data->cs_change = transfer->cs_change;  	/* Bits per word setup */ -	bits_per_word = transfer->bits_per_word ? : message->spi->bits_per_word; -	if (bits_per_word == 8) -		drv_data->ops = &bfin_sport_transfer_ops_u8; -	else +	bits_per_word = transfer->bits_per_word ? : +		message->spi->bits_per_word ? : 8; +	if (bits_per_word % 16 == 0)  		drv_data->ops = &bfin_sport_transfer_ops_u16; +	else +		drv_data->ops = &bfin_sport_transfer_ops_u8; +	bfin_write(&drv_data->regs->tcr2, bits_per_word - 1); +	bfin_write(&drv_data->regs->tfsdiv, bits_per_word - 1); +	bfin_write(&drv_data->regs->rcr2, bits_per_word - 1);  	drv_data->state = RUNNING_STATE; @@ -598,11 +598,12 @@ bfin_sport_spi_setup(struct spi_device *spi)  			}  			chip->cs_chg_udelay = chip_info->cs_chg_udelay;  			chip->idle_tx_val = chip_info->idle_tx_val; -			spi->bits_per_word = chip_info->bits_per_word;  		}  	} -	if (spi->bits_per_word != 8 && spi->bits_per_word != 16) { +	if (spi->bits_per_word % 8) { +		dev_err(&spi->dev, "%d bits_per_word is not supported\n", +				spi->bits_per_word);  		ret = -EINVAL;  		goto error;  	} diff --git a/drivers/spi/spi-bfin5xx.c b/drivers/spi/spi-bfin5xx.c index 3b83ff8b1e2..9bb4d4af854 100644 --- a/drivers/spi/spi-bfin5xx.c +++ b/drivers/spi/spi-bfin5xx.c @@ -396,7 +396,7 @@ static irqreturn_t bfin_spi_pio_irq_handler(int irq, void *dev_id)  		/* last read */  		if (drv_data->rx) {  			dev_dbg(&drv_data->pdev->dev, "last read\n"); -			if (n_bytes % 2) { +			if (!(n_bytes % 2)) {  				u16 *buf = (u16 *)drv_data->rx;  				for (loop = 0; loop < n_bytes / 2; loop++)  					*buf++ = bfin_read(&drv_data->regs->rdbr); @@ -424,7 +424,7 @@ static irqreturn_t bfin_spi_pio_irq_handler(int irq, void *dev_id)  	if (drv_data->rx && drv_data->tx) {  		/* duplex */  		dev_dbg(&drv_data->pdev->dev, "duplex: write_TDBR\n"); -		if (n_bytes % 2) { +		if (!(n_bytes % 2)) {  			u16 *buf = (u16 *)drv_data->rx;  			u16 *buf2 = (u16 *)drv_data->tx;  			for (loop = 0; loop < n_bytes / 2; loop++) { @@ -442,7 +442,7 @@ static irqreturn_t bfin_spi_pio_irq_handler(int irq, void *dev_id)  	} else if (drv_data->rx) {  		/* read */  		dev_dbg(&drv_data->pdev->dev, "read: write_TDBR\n"); -		if (n_bytes % 2) { +		if (!(n_bytes % 2)) {  			u16 *buf = (u16 *)drv_data->rx;  			for (loop = 0; loop < n_bytes / 2; loop++) {  				*buf++ = bfin_read(&drv_data->regs->rdbr); @@ -458,7 +458,7 @@ static irqreturn_t bfin_spi_pio_irq_handler(int irq, void *dev_id)  	} else if (drv_data->tx) {  		/* write */  		dev_dbg(&drv_data->pdev->dev, "write: write_TDBR\n"); -		if (n_bytes % 2) { +		if (!(n_bytes % 2)) {  			u16 *buf = (u16 *)drv_data->tx;  			for (loop = 0; loop < n_bytes / 2; loop++) {  				bfin_read(&drv_data->regs->rdbr); @@ -587,6 +587,7 @@ static void bfin_spi_pump_transfers(unsigned long data)  	if (message->state == DONE_STATE) {  		dev_dbg(&drv_data->pdev->dev, "transfer: all done!\n");  		message->status = 0; +		bfin_spi_flush(drv_data);  		bfin_spi_giveback(drv_data);  		return;  	} @@ -870,8 +871,10 @@ static void bfin_spi_pump_transfers(unsigned long data)  		message->actual_length += drv_data->len_in_bytes;  		/* Move to next transfer of this msg */  		message->state = bfin_spi_next_transfer(drv_data); -		if (drv_data->cs_change) +		if (drv_data->cs_change && message->state != DONE_STATE) { +			bfin_spi_flush(drv_data);  			bfin_spi_cs_deactive(drv_data, chip); +		}  	}  	/* Schedule next transfer tasklet */ @@ -1026,7 +1029,6 @@ static int bfin_spi_setup(struct spi_device *spi)  		chip->cs_chg_udelay = chip_info->cs_chg_udelay;  		chip->idle_tx_val = chip_info->idle_tx_val;  		chip->pio_interrupt = chip_info->pio_interrupt; -		spi->bits_per_word = chip_info->bits_per_word;  	} else {  		/* force a default base state */  		chip->ctl_reg &= bfin_ctl_reg; diff --git a/drivers/spi/spi-ep93xx.c b/drivers/spi/spi-ep93xx.c index 6db2887852d..e8055073e84 100644 --- a/drivers/spi/spi-ep93xx.c +++ b/drivers/spi/spi-ep93xx.c @@ -545,13 +545,12 @@ static void ep93xx_spi_pio_transfer(struct ep93xx_spi *espi)   * in case of failure.   */  static struct dma_async_tx_descriptor * -ep93xx_spi_dma_prepare(struct ep93xx_spi *espi, enum dma_data_direction dir) +ep93xx_spi_dma_prepare(struct ep93xx_spi *espi, enum dma_transfer_direction dir)  {  	struct spi_transfer *t = espi->current_msg->state;  	struct dma_async_tx_descriptor *txd;  	enum dma_slave_buswidth buswidth;  	struct dma_slave_config conf; -	enum dma_transfer_direction slave_dirn;  	struct scatterlist *sg;  	struct sg_table *sgt;  	struct dma_chan *chan; @@ -567,14 +566,13 @@ ep93xx_spi_dma_prepare(struct ep93xx_spi *espi, enum dma_data_direction dir)  	memset(&conf, 0, sizeof(conf));  	conf.direction = dir; -	if (dir == DMA_FROM_DEVICE) { +	if (dir == DMA_DEV_TO_MEM) {  		chan = espi->dma_rx;  		buf = t->rx_buf;  		sgt = &espi->rx_sgt;  		conf.src_addr = espi->sspdr_phys;  		conf.src_addr_width = buswidth; -		slave_dirn = DMA_DEV_TO_MEM;  	} else {  		chan = espi->dma_tx;  		buf = t->tx_buf; @@ -582,7 +580,6 @@ ep93xx_spi_dma_prepare(struct ep93xx_spi *espi, enum dma_data_direction dir)  		conf.dst_addr = espi->sspdr_phys;  		conf.dst_addr_width = buswidth; -		slave_dirn = DMA_MEM_TO_DEV;  	}  	ret = dmaengine_slave_config(chan, &conf); @@ -633,8 +630,7 @@ ep93xx_spi_dma_prepare(struct ep93xx_spi *espi, enum dma_data_direction dir)  	if (!nents)  		return ERR_PTR(-ENOMEM); -	txd = dmaengine_prep_slave_sg(chan, sgt->sgl, nents, -					slave_dirn, DMA_CTRL_ACK); +	txd = dmaengine_prep_slave_sg(chan, sgt->sgl, nents, dir, DMA_CTRL_ACK);  	if (!txd) {  		dma_unmap_sg(chan->device->dev, sgt->sgl, sgt->nents, dir);  		return ERR_PTR(-ENOMEM); @@ -651,12 +647,12 @@ ep93xx_spi_dma_prepare(struct ep93xx_spi *espi, enum dma_data_direction dir)   * unmapped.   */  static void ep93xx_spi_dma_finish(struct ep93xx_spi *espi, -				  enum dma_data_direction dir) +				  enum dma_transfer_direction dir)  {  	struct dma_chan *chan;  	struct sg_table *sgt; -	if (dir == DMA_FROM_DEVICE) { +	if (dir == DMA_DEV_TO_MEM) {  		chan = espi->dma_rx;  		sgt = &espi->rx_sgt;  	} else { @@ -677,16 +673,16 @@ static void ep93xx_spi_dma_transfer(struct ep93xx_spi *espi)  	struct spi_message *msg = espi->current_msg;  	struct dma_async_tx_descriptor *rxd, *txd; -	rxd = ep93xx_spi_dma_prepare(espi, DMA_FROM_DEVICE); +	rxd = ep93xx_spi_dma_prepare(espi, DMA_DEV_TO_MEM);  	if (IS_ERR(rxd)) {  		dev_err(&espi->pdev->dev, "DMA RX failed: %ld\n", PTR_ERR(rxd));  		msg->status = PTR_ERR(rxd);  		return;  	} -	txd = ep93xx_spi_dma_prepare(espi, DMA_TO_DEVICE); +	txd = ep93xx_spi_dma_prepare(espi, DMA_MEM_TO_DEV);  	if (IS_ERR(txd)) { -		ep93xx_spi_dma_finish(espi, DMA_FROM_DEVICE); +		ep93xx_spi_dma_finish(espi, DMA_DEV_TO_MEM);  		dev_err(&espi->pdev->dev, "DMA TX failed: %ld\n", PTR_ERR(rxd));  		msg->status = PTR_ERR(txd);  		return; @@ -705,8 +701,8 @@ static void ep93xx_spi_dma_transfer(struct ep93xx_spi *espi)  	wait_for_completion(&espi->wait); -	ep93xx_spi_dma_finish(espi, DMA_TO_DEVICE); -	ep93xx_spi_dma_finish(espi, DMA_FROM_DEVICE); +	ep93xx_spi_dma_finish(espi, DMA_MEM_TO_DEV); +	ep93xx_spi_dma_finish(espi, DMA_DEV_TO_MEM);  }  /** diff --git a/drivers/spi/spi-pl022.c b/drivers/spi/spi-pl022.c index 09c925aaf32..400ae2121a2 100644 --- a/drivers/spi/spi-pl022.c +++ b/drivers/spi/spi-pl022.c @@ -1667,9 +1667,15 @@ static int calculate_effective_freq(struct pl022 *pl022, int freq, struct  	/* cpsdvsr = 254 & scr = 255 */  	min_tclk = spi_rate(rate, CPSDVR_MAX, SCR_MAX); -	if (!((freq <= max_tclk) && (freq >= min_tclk))) { +	if (freq > max_tclk) +		dev_warn(&pl022->adev->dev, +			"Max speed that can be programmed is %d Hz, you requested %d\n", +			max_tclk, freq); + +	if (freq < min_tclk) {  		dev_err(&pl022->adev->dev, -			"controller data is incorrect: out of range frequency"); +			"Requested frequency: %d Hz is less than minimum possible %d Hz\n", +			freq, min_tclk);  		return -EINVAL;  	} @@ -1681,26 +1687,37 @@ static int calculate_effective_freq(struct pl022 *pl022, int freq, struct  		while (scr <= SCR_MAX) {  			tmp = spi_rate(rate, cpsdvsr, scr); -			if (tmp > freq) +			if (tmp > freq) { +				/* we need lower freq */  				scr++; +				continue; +			} +  			/* -			 * If found exact value, update and break. -			 * If found more closer value, update and continue. +			 * If found exact value, mark found and break. +			 * If found more closer value, update and break.  			 */ -			else if ((tmp == freq) || (tmp > best_freq)) { +			if (tmp > best_freq) {  				best_freq = tmp;  				best_cpsdvsr = cpsdvsr;  				best_scr = scr;  				if (tmp == freq) -					break; +					found = 1;  			} -			scr++; +			/* +			 * increased scr will give lower rates, which are not +			 * required +			 */ +			break;  		}  		cpsdvsr += 2;  		scr = SCR_MIN;  	} +	WARN(!best_freq, "pl022: Matching cpsdvsr and scr not found for %d Hz rate \n", +			freq); +  	clk_freq->cpsdvsr = (u8) (best_cpsdvsr & 0xFF);  	clk_freq->scr = (u8) (best_scr & 0xFF);  	dev_dbg(&pl022->adev->dev, @@ -1823,9 +1840,12 @@ static int pl022_setup(struct spi_device *spi)  	} else  		chip->cs_control = chip_info->cs_control; -	if (bits <= 3) { -		/* PL022 doesn't support less than 4-bits */ +	/* Check bits per word with vendor specific range */ +	if ((bits <= 3) || (bits > pl022->vendor->max_bpw)) {  		status = -ENOTSUPP; +		dev_err(&spi->dev, "illegal data size for this controller!\n"); +		dev_err(&spi->dev, "This controller can only handle 4 <= n <= %d bit words\n", +				pl022->vendor->max_bpw);  		goto err_config_params;  	} else if (bits <= 8) {  		dev_dbg(&spi->dev, "4 <= n <=8 bits per word\n"); @@ -1838,20 +1858,10 @@ static int pl022_setup(struct spi_device *spi)  		chip->read = READING_U16;  		chip->write = WRITING_U16;  	} else { -		if (pl022->vendor->max_bpw >= 32) { -			dev_dbg(&spi->dev, "17 <= n <= 32 bits per word\n"); -			chip->n_bytes = 4; -			chip->read = READING_U32; -			chip->write = WRITING_U32; -		} else { -			dev_err(&spi->dev, -				"illegal data size for this controller!\n"); -			dev_err(&spi->dev, -				"a standard pl022 can only handle " -				"1 <= n <= 16 bit words\n"); -			status = -ENOTSUPP; -			goto err_config_params; -		} +		dev_dbg(&spi->dev, "17 <= n <= 32 bits per word\n"); +		chip->n_bytes = 4; +		chip->read = READING_U32; +		chip->write = WRITING_U32;  	}  	/* Now Initialize all register settings required for this chip */ diff --git a/drivers/staging/octeon/ethernet-rx.c b/drivers/staging/octeon/ethernet-rx.c index 400df8cbee5..d91751f9ffe 100644 --- a/drivers/staging/octeon/ethernet-rx.c +++ b/drivers/staging/octeon/ethernet-rx.c @@ -36,6 +36,7 @@  #include <linux/prefetch.h>  #include <linux/ratelimit.h>  #include <linux/smp.h> +#include <linux/interrupt.h>  #include <net/dst.h>  #ifdef CONFIG_XFRM  #include <linux/xfrm.h> diff --git a/drivers/staging/octeon/ethernet-tx.c b/drivers/staging/octeon/ethernet-tx.c index 56d74dc2fbd..91a97b3e45c 100644 --- a/drivers/staging/octeon/ethernet-tx.c +++ b/drivers/staging/octeon/ethernet-tx.c @@ -32,6 +32,7 @@  #include <linux/ip.h>  #include <linux/ratelimit.h>  #include <linux/string.h> +#include <linux/interrupt.h>  #include <net/dst.h>  #ifdef CONFIG_XFRM  #include <linux/xfrm.h> diff --git a/drivers/staging/octeon/ethernet.c b/drivers/staging/octeon/ethernet.c index 9112cd88215..60cba8194de 100644 --- a/drivers/staging/octeon/ethernet.c +++ b/drivers/staging/octeon/ethernet.c @@ -31,6 +31,7 @@  #include <linux/etherdevice.h>  #include <linux/phy.h>  #include <linux/slab.h> +#include <linux/interrupt.h>  #include <net/dst.h> diff --git a/drivers/staging/ozwpan/ozpd.c b/drivers/staging/ozwpan/ozpd.c index 2b45d3d1800..04cd57f2a6d 100644 --- a/drivers/staging/ozwpan/ozpd.c +++ b/drivers/staging/ozwpan/ozpd.c @@ -383,8 +383,6 @@ static void oz_tx_frame_free(struct oz_pd *pd, struct oz_tx_frame *f)  		pd->tx_pool = &f->link;  		pd->tx_pool_count++;  		f = 0; -	} else { -		kfree(f);  	}  	spin_unlock_bh(&pd->tx_frame_lock);  	if (f) diff --git a/drivers/staging/tidspbridge/core/tiomap3430.c b/drivers/staging/tidspbridge/core/tiomap3430.c index 7862513cc29..9cf29fcea11 100644 --- a/drivers/staging/tidspbridge/core/tiomap3430.c +++ b/drivers/staging/tidspbridge/core/tiomap3430.c @@ -79,10 +79,6 @@  #define OMAP343X_CONTROL_IVA2_BOOTADDR (OMAP2_CONTROL_GENERAL + 0x0190)  #define OMAP343X_CONTROL_IVA2_BOOTMOD (OMAP2_CONTROL_GENERAL + 0x0194) -#define OMAP343X_CTRL_REGADDR(reg) \ -	OMAP2_L4_IO_ADDRESS(OMAP343X_CTRL_BASE + (reg)) - -  /* Forward Declarations: */  static int bridge_brd_monitor(struct bridge_dev_context *dev_ctxt);  static int bridge_brd_read(struct bridge_dev_context *dev_ctxt, @@ -418,19 +414,27 @@ static int bridge_brd_start(struct bridge_dev_context *dev_ctxt,  		/* Assert RST1 i.e only the RST only for DSP megacell */  		if (!status) { +			/* +			 * XXX: ioremapping  MUST be removed once ctrl +			 * function is made available. +			 */ +			void __iomem *ctrl = ioremap(OMAP343X_CTRL_BASE, SZ_4K); +			if (!ctrl) +				return -ENOMEM; +  			(*pdata->dsp_prm_rmw_bits)(OMAP3430_RST1_IVA2_MASK,  					OMAP3430_RST1_IVA2_MASK, OMAP3430_IVA2_MOD,  					OMAP2_RM_RSTCTRL);  			/* Mask address with 1K for compatibility */  			__raw_writel(dsp_addr & OMAP3_IVA2_BOOTADDR_MASK, -					OMAP343X_CTRL_REGADDR( -					OMAP343X_CONTROL_IVA2_BOOTADDR)); +					ctrl + OMAP343X_CONTROL_IVA2_BOOTADDR);  			/*  			 * Set bootmode to self loop if dsp_debug flag is true  			 */  			__raw_writel((dsp_debug) ? OMAP3_IVA2_BOOTMOD_IDLE : 0, -					OMAP343X_CTRL_REGADDR( -					OMAP343X_CONTROL_IVA2_BOOTMOD)); +					ctrl + OMAP343X_CONTROL_IVA2_BOOTMOD); + +			iounmap(ctrl);  		}  	}  	if (!status) { diff --git a/drivers/staging/tidspbridge/core/wdt.c b/drivers/staging/tidspbridge/core/wdt.c index 70055c8111e..870f934f4f3 100644 --- a/drivers/staging/tidspbridge/core/wdt.c +++ b/drivers/staging/tidspbridge/core/wdt.c @@ -53,7 +53,10 @@ int dsp_wdt_init(void)  	int ret = 0;  	dsp_wdt.sm_wdt = NULL; -	dsp_wdt.reg_base = OMAP2_L4_IO_ADDRESS(OMAP34XX_WDT3_BASE); +	dsp_wdt.reg_base = ioremap(OMAP34XX_WDT3_BASE, SZ_4K); +	if (!dsp_wdt.reg_base) +		return -ENOMEM; +  	tasklet_init(&dsp_wdt.wdt3_tasklet, dsp_wdt_dpc, 0);  	dsp_wdt.fclk = clk_get(NULL, "wdt3_fck"); @@ -99,6 +102,9 @@ void dsp_wdt_exit(void)  	dsp_wdt.fclk = NULL;  	dsp_wdt.iclk = NULL;  	dsp_wdt.sm_wdt = NULL; + +	if (dsp_wdt.reg_base) +		iounmap(dsp_wdt.reg_base);  	dsp_wdt.reg_base = NULL;  } diff --git a/drivers/staging/zcache/Kconfig b/drivers/staging/zcache/Kconfig index 3ed2c8f656a..7048e01f081 100644 --- a/drivers/staging/zcache/Kconfig +++ b/drivers/staging/zcache/Kconfig @@ -2,7 +2,7 @@ config ZCACHE  	bool "Dynamic compression of swap pages and clean pagecache pages"  	# X86 dependency is because zsmalloc uses non-portable pte/tlb  	# functions -	depends on (CLEANCACHE || FRONTSWAP) && CRYPTO && X86 +	depends on (CLEANCACHE || FRONTSWAP) && CRYPTO=y && X86  	select ZSMALLOC  	select CRYPTO_LZO  	default n diff --git a/drivers/tty/amiserial.c b/drivers/tty/amiserial.c index 24145c30c9b..6cc4358f68c 100644 --- a/drivers/tty/amiserial.c +++ b/drivers/tty/amiserial.c @@ -1073,8 +1073,10 @@ static int set_serial_info(struct tty_struct *tty, struct serial_state *state,  		    (new_serial.close_delay != port->close_delay) ||  		    (new_serial.xmit_fifo_size != state->xmit_fifo_size) ||  		    ((new_serial.flags & ~ASYNC_USR_MASK) != -		     (port->flags & ~ASYNC_USR_MASK))) +		     (port->flags & ~ASYNC_USR_MASK))) { +			tty_unlock();  			return -EPERM; +		}  		port->flags = ((port->flags & ~ASYNC_USR_MASK) |  			       (new_serial.flags & ASYNC_USR_MASK));  		state->custom_divisor = new_serial.custom_divisor; diff --git a/drivers/tty/serial/clps711x.c b/drivers/tty/serial/clps711x.c index e6c3dbd781d..836fe273123 100644 --- a/drivers/tty/serial/clps711x.c +++ b/drivers/tty/serial/clps711x.c @@ -154,10 +154,9 @@ static irqreturn_t clps711xuart_int_tx(int irq, void *dev_id)  		port->x_char = 0;  		return IRQ_HANDLED;  	} -	if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { -		clps711xuart_stop_tx(port); -		return IRQ_HANDLED; -	} + +	if (uart_circ_empty(xmit) || uart_tx_stopped(port)) +		goto disable_tx_irq;  	count = port->fifosize >> 1;  	do { @@ -171,8 +170,11 @@ static irqreturn_t clps711xuart_int_tx(int irq, void *dev_id)  	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)  		uart_write_wakeup(port); -	if (uart_circ_empty(xmit)) -		clps711xuart_stop_tx(port); +	if (uart_circ_empty(xmit)) { +	disable_tx_irq: +		disable_irq_nosync(TX_IRQ(port)); +		tx_enabled(port) = 0; +	}  	return IRQ_HANDLED;  } diff --git a/drivers/tty/serial/pch_uart.c b/drivers/tty/serial/pch_uart.c index bbbec4a74cf..c2816f49480 100644 --- a/drivers/tty/serial/pch_uart.c +++ b/drivers/tty/serial/pch_uart.c @@ -1447,9 +1447,11 @@ static int pch_uart_verify_port(struct uart_port *port,  			__func__);  		return -EOPNOTSUPP;  #endif -		priv->use_dma = 1;  		priv->use_dma_flag = 1;  		dev_info(priv->port.dev, "PCH UART : Use DMA Mode\n"); +		if (!priv->use_dma) +			pch_request_dma(port); +		priv->use_dma = 1;  	}  	return 0; diff --git a/drivers/tty/serial/pmac_zilog.c b/drivers/tty/serial/pmac_zilog.c index 08ebe901bb5..654755a990d 100644 --- a/drivers/tty/serial/pmac_zilog.c +++ b/drivers/tty/serial/pmac_zilog.c @@ -469,7 +469,7 @@ static irqreturn_t pmz_interrupt(int irq, void *dev_id)  	tty = NULL;  	if (r3 & (CHAEXT | CHATxIP | CHARxIP)) {  		if (!ZS_IS_OPEN(uap_a)) { -			pmz_debug("ChanA interrupt while open !\n"); +			pmz_debug("ChanA interrupt while not open !\n");  			goto skip_a;  		}  		write_zsreg(uap_a, R0, RES_H_IUS); @@ -493,8 +493,8 @@ static irqreturn_t pmz_interrupt(int irq, void *dev_id)  	spin_lock(&uap_b->port.lock);  	tty = NULL;  	if (r3 & (CHBEXT | CHBTxIP | CHBRxIP)) { -		if (!ZS_IS_OPEN(uap_a)) { -			pmz_debug("ChanB interrupt while open !\n"); +		if (!ZS_IS_OPEN(uap_b)) { +			pmz_debug("ChanB interrupt while not open !\n");  			goto skip_b;  		}  		write_zsreg(uap_b, R0, RES_H_IUS); diff --git a/drivers/tty/vt/keyboard.c b/drivers/tty/vt/keyboard.c index 86dd1e302bb..29ca20dbd33 100644 --- a/drivers/tty/vt/keyboard.c +++ b/drivers/tty/vt/keyboard.c @@ -1085,15 +1085,21 @@ void vt_set_led_state(int console, int leds)   *   *	Handle console start. This is a wrapper for the VT layer   *	so that we can keep kbd knowledge internal + * + *	FIXME: We eventually need to hold the kbd lock here to protect + *	the LED updating. We can't do it yet because fn_hold calls stop_tty + *	and start_tty under the kbd_event_lock, while normal tty paths + *	don't hold the lock. We probably need to split out an LED lock + *	but not during an -rc release!   */  void vt_kbd_con_start(int console)  {  	struct kbd_struct * kbd = kbd_table + console; -	unsigned long flags; -	spin_lock_irqsave(&kbd_event_lock, flags); +/*	unsigned long flags; */ +/*	spin_lock_irqsave(&kbd_event_lock, flags); */  	clr_vc_kbd_led(kbd, VC_SCROLLOCK);  	set_leds(); -	spin_unlock_irqrestore(&kbd_event_lock, flags); +/*	spin_unlock_irqrestore(&kbd_event_lock, flags); */  }  /** @@ -1102,22 +1108,28 @@ void vt_kbd_con_start(int console)   *   *	Handle console stop. This is a wrapper for the VT layer   *	so that we can keep kbd knowledge internal + * + *	FIXME: We eventually need to hold the kbd lock here to protect + *	the LED updating. We can't do it yet because fn_hold calls stop_tty + *	and start_tty under the kbd_event_lock, while normal tty paths + *	don't hold the lock. We probably need to split out an LED lock + *	but not during an -rc release!   */  void vt_kbd_con_stop(int console)  {  	struct kbd_struct * kbd = kbd_table + console; -	unsigned long flags; -	spin_lock_irqsave(&kbd_event_lock, flags); +/*	unsigned long flags; */ +/*	spin_lock_irqsave(&kbd_event_lock, flags); */  	set_vc_kbd_led(kbd, VC_SCROLLOCK);  	set_leds(); -	spin_unlock_irqrestore(&kbd_event_lock, flags); +/*	spin_unlock_irqrestore(&kbd_event_lock, flags); */  }  /*   * This is the tasklet that updates LED state on all keyboards   * attached to the box. The reason we use tasklet is that we   * need to handle the scenario when keyboard handler is not - * registered yet but we already getting updates form VT to + * registered yet but we already getting updates from the VT to   * update led state.   */  static void kbd_bh(unsigned long dummy) diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index c6f6560d436..0bb2b3248da 100644 --- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c @@ -157,8 +157,9 @@ static void wdm_out_callback(struct urb *urb)  	spin_lock(&desc->iuspin);  	desc->werr = urb->status;  	spin_unlock(&desc->iuspin); -	clear_bit(WDM_IN_USE, &desc->flags);  	kfree(desc->outbuf); +	desc->outbuf = NULL; +	clear_bit(WDM_IN_USE, &desc->flags);  	wake_up(&desc->wait);  } @@ -338,7 +339,7 @@ static ssize_t wdm_write  	if (we < 0)  		return -EIO; -	desc->outbuf = buf = kmalloc(count, GFP_KERNEL); +	buf = kmalloc(count, GFP_KERNEL);  	if (!buf) {  		rv = -ENOMEM;  		goto outnl; @@ -406,10 +407,12 @@ static ssize_t wdm_write  	req->wIndex = desc->inum;  	req->wLength = cpu_to_le16(count);  	set_bit(WDM_IN_USE, &desc->flags); +	desc->outbuf = buf;  	rv = usb_submit_urb(desc->command, GFP_KERNEL);  	if (rv < 0) {  		kfree(buf); +		desc->outbuf = NULL;  		clear_bit(WDM_IN_USE, &desc->flags);  		dev_err(&desc->intf->dev, "Tx URB error: %d\n", rv);  	} else { diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c index 622b4a48e73..57ed9e400c0 100644 --- a/drivers/usb/core/hcd-pci.c +++ b/drivers/usb/core/hcd-pci.c @@ -493,6 +493,15 @@ static int hcd_pci_suspend_noirq(struct device *dev)  	pci_save_state(pci_dev); +	/* +	 * Some systems crash if an EHCI controller is in D3 during +	 * a sleep transition.  We have to leave such controllers in D0. +	 */ +	if (hcd->broken_pci_sleep) { +		dev_dbg(dev, "Staying in PCI D0\n"); +		return retval; +	} +  	/* If the root hub is dead rather than suspended, disallow remote  	 * wakeup.  usb_hc_died() should ensure that both hosts are marked as  	 * dying, so we only need to check the primary roothub. diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index a2aa9d652c6..ec6c97dadbe 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -1667,7 +1667,6 @@ void usb_disconnect(struct usb_device **pdev)  {  	struct usb_device	*udev = *pdev;  	int			i; -	struct usb_hcd		*hcd = bus_to_hcd(udev->bus);  	/* mark the device as inactive, so any further urb submissions for  	 * this device (and any of its children) will fail immediately. @@ -1690,9 +1689,7 @@ void usb_disconnect(struct usb_device **pdev)  	 * so that the hardware is now fully quiesced.  	 */  	dev_dbg (&udev->dev, "unregistering device\n"); -	mutex_lock(hcd->bandwidth_mutex);  	usb_disable_device(udev, 0); -	mutex_unlock(hcd->bandwidth_mutex);  	usb_hcd_synchronize_unlinks(udev);  	usb_remove_ep_devs(&udev->ep0); diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index aed3e07942d..ca717da3be9 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -1136,8 +1136,6 @@ void usb_disable_interface(struct usb_device *dev, struct usb_interface *intf,   * Deallocates hcd/hardware state for the endpoints (nuking all or most   * pending urbs) and usbcore state for the interfaces, so that usbcore   * must usb_set_configuration() before any interfaces could be used. - * - * Must be called with hcd->bandwidth_mutex held.   */  void usb_disable_device(struct usb_device *dev, int skip_ep0)  { @@ -1190,7 +1188,9 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0)  			usb_disable_endpoint(dev, i + USB_DIR_IN, false);  		}  		/* Remove endpoints from the host controller internal state */ +		mutex_lock(hcd->bandwidth_mutex);  		usb_hcd_alloc_bandwidth(dev, NULL, NULL, NULL); +		mutex_unlock(hcd->bandwidth_mutex);  		/* Second pass: remove endpoint pointers */  	}  	for (i = skip_ep0; i < 16; ++i) { @@ -1750,7 +1750,6 @@ free_interfaces:  	/* if it's already configured, clear out old state first.  	 * getting rid of old interfaces means unbinding their drivers.  	 */ -	mutex_lock(hcd->bandwidth_mutex);  	if (dev->state != USB_STATE_ADDRESS)  		usb_disable_device(dev, 1);	/* Skip ep0 */ @@ -1763,6 +1762,7 @@ free_interfaces:  	 * host controller will not allow submissions to dropped endpoints.  If  	 * this call fails, the device state is unchanged.  	 */ +	mutex_lock(hcd->bandwidth_mutex);  	ret = usb_hcd_alloc_bandwidth(dev, cp, NULL, NULL);  	if (ret < 0) {  		mutex_unlock(hcd->bandwidth_mutex); diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 7bd815a507e..99b58d84553 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -206,11 +206,11 @@ static void dwc3_free_event_buffers(struct dwc3 *dwc)  	for (i = 0; i < dwc->num_event_buffers; i++) {  		evt = dwc->ev_buffs[i]; -		if (evt) { +		if (evt)  			dwc3_free_one_event_buffer(dwc, evt); -			dwc->ev_buffs[i] = NULL; -		}  	} + +	kfree(dwc->ev_buffs);  }  /** diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index 25910e251c0..3584a169886 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c @@ -353,6 +353,9 @@ static int dwc3_ep0_handle_feature(struct dwc3 *dwc,  			dwc->test_mode_nr = wIndex >> 8;  			dwc->test_mode = true; +			break; +		default: +			return -EINVAL;  		}  		break; @@ -559,15 +562,20 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc,  	length = trb->size & DWC3_TRB_SIZE_MASK;  	if (dwc->ep0_bounced) { +		unsigned transfer_size = ur->length; +		unsigned maxp = ep0->endpoint.maxpacket; + +		transfer_size += (maxp - (transfer_size % maxp));  		transferred = min_t(u32, ur->length, -				ep0->endpoint.maxpacket - length); +				transfer_size - length);  		memcpy(ur->buf, dwc->ep0_bounce, transferred);  		dwc->ep0_bounced = false;  	} else {  		transferred = ur->length - length; -		ur->actual += transferred;  	} +	ur->actual += transferred; +  	if ((epnum & 1) && ur->actual < ur->length) {  		/* for some reason we did not get everything out */ diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c index 0c935d7c65b..9d7bcd91007 100644 --- a/drivers/usb/gadget/at91_udc.c +++ b/drivers/usb/gadget/at91_udc.c @@ -1863,8 +1863,8 @@ static int __devinit at91udc_probe(struct platform_device *pdev)  			mod_timer(&udc->vbus_timer,  				  jiffies + VBUS_POLL_TIMEOUT);  		} else { -			if (request_irq(udc->board.vbus_pin, at91_vbus_irq, -					0, driver_name, udc)) { +			if (request_irq(gpio_to_irq(udc->board.vbus_pin), +					at91_vbus_irq, 0, driver_name, udc)) {  				DBG("request vbus irq %d failed\n",  				    udc->board.vbus_pin);  				retval = -EBUSY; @@ -1886,7 +1886,7 @@ static int __devinit at91udc_probe(struct platform_device *pdev)  	return 0;  fail4:  	if (gpio_is_valid(udc->board.vbus_pin) && !udc->board.vbus_polled) -		free_irq(udc->board.vbus_pin, udc); +		free_irq(gpio_to_irq(udc->board.vbus_pin), udc);  fail3:  	if (gpio_is_valid(udc->board.vbus_pin))  		gpio_free(udc->board.vbus_pin); @@ -1924,7 +1924,7 @@ static int __exit at91udc_remove(struct platform_device *pdev)  	device_init_wakeup(&pdev->dev, 0);  	remove_debug_file(udc);  	if (gpio_is_valid(udc->board.vbus_pin)) { -		free_irq(udc->board.vbus_pin, udc); +		free_irq(gpio_to_irq(udc->board.vbus_pin), udc);  		gpio_free(udc->board.vbus_pin);  	}  	free_irq(udc->udp_irq, udc); diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index a6dfd216416..170cbe89d9f 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c @@ -927,7 +927,6 @@ static int dummy_udc_stop(struct usb_gadget *g,  	dum->driver = NULL; -	dummy_pullup(&dum->gadget, 0);  	return 0;  } diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c index 1cbba70836b..f52cb1ae45d 100644 --- a/drivers/usb/gadget/f_fs.c +++ b/drivers/usb/gadget/f_fs.c @@ -712,7 +712,7 @@ static long ffs_ep0_ioctl(struct file *file, unsigned code, unsigned long value)  	if (code == FUNCTIONFS_INTERFACE_REVMAP) {  		struct ffs_function *func = ffs->func;  		ret = func ? ffs_func_revmap_intf(func, value) : -ENODEV; -	} else if (gadget->ops->ioctl) { +	} else if (gadget && gadget->ops->ioctl) {  		ret = gadget->ops->ioctl(gadget, code, value);  	} else {  		ret = -ENOTTY; @@ -1382,6 +1382,7 @@ static void functionfs_unbind(struct ffs_data *ffs)  		ffs->ep0req = NULL;  		ffs->gadget = NULL;  		ffs_data_put(ffs); +		clear_bit(FFS_FL_BOUND, &ffs->flags);  	}  } diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index a371e966425..cb8c162cae5 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c @@ -2189,7 +2189,7 @@ unknown_cmnd:  		common->data_size_from_cmnd = 0;  		sprintf(unknown, "Unknown x%02x", common->cmnd[0]);  		reply = check_command(common, common->cmnd_size, -				      DATA_DIR_UNKNOWN, 0xff, 0, unknown); +				      DATA_DIR_UNKNOWN, ~0, 0, unknown);  		if (reply == 0) {  			common->curlun->sense_data = SS_INVALID_COMMAND;  			reply = -EINVAL; diff --git a/drivers/usb/gadget/f_rndis.c b/drivers/usb/gadget/f_rndis.c index 7b1cf18df5e..52343654f5d 100644 --- a/drivers/usb/gadget/f_rndis.c +++ b/drivers/usb/gadget/f_rndis.c @@ -500,6 +500,7 @@ rndis_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl)  			if (buf) {  				memcpy(req->buf, buf, n);  				req->complete = rndis_response_complete; +				req->context = rndis;  				rndis_free_response(rndis->config, buf);  				value = n;  			} diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c index 4fac5692774..a896d73f7a9 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c @@ -2579,7 +2579,7 @@ static int do_scsi_command(struct fsg_dev *fsg)  		fsg->data_size_from_cmnd = 0;  		sprintf(unknown, "Unknown x%02x", fsg->cmnd[0]);  		if ((reply = check_command(fsg, fsg->cmnd_size, -				DATA_DIR_UNKNOWN, 0xff, 0, unknown)) == 0) { +				DATA_DIR_UNKNOWN, ~0, 0, unknown)) == 0) {  			fsg->curlun->sense_data = SS_INVALID_COMMAND;  			reply = -EINVAL;  		} diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c index 5f94e79cd6b..55abfb6bd61 100644 --- a/drivers/usb/gadget/fsl_udc_core.c +++ b/drivers/usb/gadget/fsl_udc_core.c @@ -730,7 +730,7 @@ static void fsl_queue_td(struct fsl_ep *ep, struct fsl_req *req)  		: (1 << (ep_index(ep)));  	/* check if the pipe is empty */ -	if (!(list_empty(&ep->queue))) { +	if (!(list_empty(&ep->queue)) && !(ep_index(ep) == 0)) {  		/* Add td to the end */  		struct fsl_req *lastreq;  		lastreq = list_entry(ep->queue.prev, struct fsl_req, queue); @@ -918,10 +918,6 @@ fsl_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)  		return -ENOMEM;  	} -	/* Update ep0 state */ -	if ((ep_index(ep) == 0)) -		udc->ep0_state = DATA_STATE_XMIT; -  	/* irq handler advances the queue */  	if (req != NULL)  		list_add_tail(&req->queue, &ep->queue); @@ -1279,7 +1275,8 @@ static int ep0_prime_status(struct fsl_udc *udc, int direction)  		udc->ep0_dir = USB_DIR_OUT;  	ep = &udc->eps[0]; -	udc->ep0_state = WAIT_FOR_OUT_STATUS; +	if (udc->ep0_state != DATA_STATE_XMIT) +		udc->ep0_state = WAIT_FOR_OUT_STATUS;  	req->ep = ep;  	req->req.length = 0; @@ -1384,6 +1381,9 @@ static void ch9getstatus(struct fsl_udc *udc, u8 request_type, u16 value,  	list_add_tail(&req->queue, &ep->queue);  	udc->ep0_state = DATA_STATE_XMIT; +	if (ep0_prime_status(udc, EP_DIR_OUT)) +		ep0stall(udc); +  	return;  stall:  	ep0stall(udc); @@ -1492,6 +1492,14 @@ static void setup_received_irq(struct fsl_udc *udc,  		spin_lock(&udc->lock);  		udc->ep0_state = (setup->bRequestType & USB_DIR_IN)  				?  DATA_STATE_XMIT : DATA_STATE_RECV; +		/* +		 * If the data stage is IN, send status prime immediately. +		 * See 2.0 Spec chapter 8.5.3.3 for detail. +		 */ +		if (udc->ep0_state == DATA_STATE_XMIT) +			if (ep0_prime_status(udc, EP_DIR_OUT)) +				ep0stall(udc); +  	} else {  		/* No data phase, IN status from gadget */  		udc->ep0_dir = USB_DIR_IN; @@ -1520,9 +1528,8 @@ static void ep0_req_complete(struct fsl_udc *udc, struct fsl_ep *ep0,  	switch (udc->ep0_state) {  	case DATA_STATE_XMIT: -		/* receive status phase */ -		if (ep0_prime_status(udc, EP_DIR_OUT)) -			ep0stall(udc); +		/* already primed at setup_received_irq */ +		udc->ep0_state = WAIT_FOR_OUT_STATUS;  		break;  	case DATA_STATE_RECV:  		/* send status phase */ diff --git a/drivers/usb/gadget/g_ffs.c b/drivers/usb/gadget/g_ffs.c index 331cd6729d3..a85eaf40b94 100644 --- a/drivers/usb/gadget/g_ffs.c +++ b/drivers/usb/gadget/g_ffs.c @@ -161,7 +161,7 @@ static struct usb_composite_driver gfs_driver = {  static struct ffs_data *gfs_ffs_data;  static unsigned long gfs_registered; -static int  gfs_init(void) +static int __init gfs_init(void)  {  	ENTER(); @@ -169,7 +169,7 @@ static int  gfs_init(void)  }  module_init(gfs_init); -static void  gfs_exit(void) +static void __exit gfs_exit(void)  {  	ENTER(); diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c index 69295ba9d99..105b206cd84 100644 --- a/drivers/usb/gadget/s3c-hsotg.c +++ b/drivers/usb/gadget/s3c-hsotg.c @@ -340,7 +340,7 @@ static void s3c_hsotg_init_fifo(struct s3c_hsotg *hsotg)  	/* currently we allocate TX FIFOs for all possible endpoints,  	 * and assume that they are all the same size. */ -	for (ep = 0; ep <= 15; ep++) { +	for (ep = 1; ep <= 15; ep++) {  		val = addr;  		val |= size << S3C_DPTXFSIZn_DPTxFSize_SHIFT;  		addr += size; @@ -741,7 +741,7 @@ static void s3c_hsotg_start_req(struct s3c_hsotg *hsotg,  	/* write size / packets */  	writel(epsize, hsotg->regs + epsize_reg); -	if (using_dma(hsotg)) { +	if (using_dma(hsotg) && !continuing) {  		unsigned int dma_reg;  		/* write DMA address to control register, buffer already @@ -1696,10 +1696,12 @@ static void s3c_hsotg_set_ep_maxpacket(struct s3c_hsotg *hsotg,  	reg |= mpsval;  	writel(reg, regs + S3C_DIEPCTL(ep)); -	reg = readl(regs + S3C_DOEPCTL(ep)); -	reg &= ~S3C_DxEPCTL_MPS_MASK; -	reg |= mpsval; -	writel(reg, regs + S3C_DOEPCTL(ep)); +	if (ep) { +		reg = readl(regs + S3C_DOEPCTL(ep)); +		reg &= ~S3C_DxEPCTL_MPS_MASK; +		reg |= mpsval; +		writel(reg, regs + S3C_DOEPCTL(ep)); +	}  	return; @@ -1919,7 +1921,8 @@ static void s3c_hsotg_epint(struct s3c_hsotg *hsotg, unsigned int idx,  		    ints & S3C_DIEPMSK_TxFIFOEmpty) {  			dev_dbg(hsotg->dev, "%s: ep%d: TxFIFOEmpty\n",  				__func__, idx); -			s3c_hsotg_trytx(hsotg, hs_ep); +			if (!using_dma(hsotg)) +				s3c_hsotg_trytx(hsotg, hs_ep);  		}  	}  } diff --git a/drivers/usb/gadget/udc-core.c b/drivers/usb/gadget/udc-core.c index 56da49f31d6..e5e44f8cde9 100644 --- a/drivers/usb/gadget/udc-core.c +++ b/drivers/usb/gadget/udc-core.c @@ -263,9 +263,9 @@ static void usb_gadget_remove_driver(struct usb_udc *udc)  	if (udc_is_newstyle(udc)) {  		udc->driver->disconnect(udc->gadget); +		usb_gadget_disconnect(udc->gadget);  		udc->driver->unbind(udc->gadget);  		usb_gadget_udc_stop(udc->gadget, udc->driver); -		usb_gadget_disconnect(udc->gadget);  	} else {  		usb_gadget_stop(udc->gadget, udc->driver);  	} @@ -411,9 +411,13 @@ static ssize_t usb_udc_softconn_store(struct device *dev,  	struct usb_udc		*udc = container_of(dev, struct usb_udc, dev);  	if (sysfs_streq(buf, "connect")) { +		if (udc_is_newstyle(udc)) +			usb_gadget_udc_start(udc->gadget, udc->driver);  		usb_gadget_connect(udc->gadget);  	} else if (sysfs_streq(buf, "disconnect")) {  		usb_gadget_disconnect(udc->gadget); +		if (udc_is_newstyle(udc)) +			usb_gadget_udc_stop(udc->gadget, udc->driver);  	} else {  		dev_err(dev, "unsupported command '%s'\n", buf);  		return -EINVAL; diff --git a/drivers/usb/gadget/uvc.h b/drivers/usb/gadget/uvc.h index bc78c606c12..ca4e03a1c73 100644 --- a/drivers/usb/gadget/uvc.h +++ b/drivers/usb/gadget/uvc.h @@ -28,7 +28,7 @@  struct uvc_request_data  { -	unsigned int length; +	__s32 length;  	__u8 data[60];  }; diff --git a/drivers/usb/gadget/uvc_queue.c b/drivers/usb/gadget/uvc_queue.c index d776adb2da6..0cdf89d32a1 100644 --- a/drivers/usb/gadget/uvc_queue.c +++ b/drivers/usb/gadget/uvc_queue.c @@ -543,11 +543,11 @@ done:  	return ret;  } +/* called with queue->irqlock held.. */  static struct uvc_buffer *  uvc_queue_next_buffer(struct uvc_video_queue *queue, struct uvc_buffer *buf)  {  	struct uvc_buffer *nextbuf; -	unsigned long flags;  	if ((queue->flags & UVC_QUEUE_DROP_INCOMPLETE) &&  	    buf->buf.length != buf->buf.bytesused) { @@ -556,14 +556,12 @@ uvc_queue_next_buffer(struct uvc_video_queue *queue, struct uvc_buffer *buf)  		return buf;  	} -	spin_lock_irqsave(&queue->irqlock, flags);  	list_del(&buf->queue);  	if (!list_empty(&queue->irqqueue))  		nextbuf = list_first_entry(&queue->irqqueue, struct uvc_buffer,  					   queue);  	else  		nextbuf = NULL; -	spin_unlock_irqrestore(&queue->irqlock, flags);  	buf->buf.sequence = queue->sequence++;  	do_gettimeofday(&buf->buf.timestamp); diff --git a/drivers/usb/gadget/uvc_v4l2.c b/drivers/usb/gadget/uvc_v4l2.c index f6e083b5019..54d7ca559cb 100644 --- a/drivers/usb/gadget/uvc_v4l2.c +++ b/drivers/usb/gadget/uvc_v4l2.c @@ -39,7 +39,7 @@ uvc_send_response(struct uvc_device *uvc, struct uvc_request_data *data)  	if (data->length < 0)  		return usb_ep_set_halt(cdev->gadget->ep0); -	req->length = min(uvc->event_length, data->length); +	req->length = min_t(unsigned int, uvc->event_length, data->length);  	req->zero = data->length < uvc->event_length;  	req->dma = DMA_ADDR_INVALID; diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c index 3e7345172e0..d0a84bd3f3e 100644 --- a/drivers/usb/host/ehci-fsl.c +++ b/drivers/usb/host/ehci-fsl.c @@ -218,6 +218,9 @@ static void ehci_fsl_setup_phy(struct ehci_hcd *ehci,  	u32 portsc;  	struct usb_hcd *hcd = ehci_to_hcd(ehci);  	void __iomem *non_ehci = hcd->regs; +	struct fsl_usb2_platform_data *pdata; + +	pdata = hcd->self.controller->platform_data;  	portsc = ehci_readl(ehci, &ehci->regs->port_status[port_offset]);  	portsc &= ~(PORT_PTS_MSK | PORT_PTS_PTW); @@ -234,7 +237,9 @@ static void ehci_fsl_setup_phy(struct ehci_hcd *ehci,  		/* fall through */  	case FSL_USB2_PHY_UTMI:  		/* enable UTMI PHY */ -		setbits32(non_ehci + FSL_SOC_USB_CTRL, CTRL_UTMI_PHY_EN); +		if (pdata->have_sysif_regs) +			setbits32(non_ehci + FSL_SOC_USB_CTRL, +				  CTRL_UTMI_PHY_EN);  		portsc |= PORT_PTS_UTMI;  		break;  	case FSL_USB2_PHY_NONE: diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 806cc95317a..4a3bc5b7a06 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -858,8 +858,13 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)  		goto dead;  	} +	/* +	 * We don't use STS_FLR, but some controllers don't like it to +	 * remain on, so mask it out along with the other status bits. +	 */ +	masked_status = status & (INTR_MASK | STS_FLR); +  	/* Shared IRQ? */ -	masked_status = status & INTR_MASK;  	if (!masked_status || unlikely(ehci->rh_state == EHCI_RH_HALTED)) {  		spin_unlock(&ehci->lock);  		return IRQ_NONE; @@ -910,7 +915,7 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)  		pcd_status = status;  		/* resume root hub? */ -		if (!(cmd & CMD_RUN)) +		if (ehci->rh_state == EHCI_RH_SUSPENDED)  			usb_hcd_resume_root_hub(hcd);  		/* get per-port change detect bits */ diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c index bba9850f32f..5c78f9e7146 100644 --- a/drivers/usb/host/ehci-omap.c +++ b/drivers/usb/host/ehci-omap.c @@ -42,6 +42,7 @@  #include <plat/usb.h>  #include <linux/regulator/consumer.h>  #include <linux/pm_runtime.h> +#include <linux/gpio.h>  /* EHCI Register Set */  #define EHCI_INSNREG04					(0xA0) @@ -191,6 +192,19 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev)  		}  	} +	if (pdata->phy_reset) { +		if (gpio_is_valid(pdata->reset_gpio_port[0])) +			gpio_request_one(pdata->reset_gpio_port[0], +					 GPIOF_OUT_INIT_LOW, "USB1 PHY reset"); + +		if (gpio_is_valid(pdata->reset_gpio_port[1])) +			gpio_request_one(pdata->reset_gpio_port[1], +					 GPIOF_OUT_INIT_LOW, "USB2 PHY reset"); + +		/* Hold the PHY in RESET for enough time till DIR is high */ +		udelay(10); +	} +  	pm_runtime_enable(dev);  	pm_runtime_get_sync(dev); @@ -237,6 +251,19 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev)  	/* root ports should always stay powered */  	ehci_port_power(omap_ehci, 1); +	if (pdata->phy_reset) { +		/* Hold the PHY in RESET for enough time till +		 * PHY is settled and ready +		 */ +		udelay(10); + +		if (gpio_is_valid(pdata->reset_gpio_port[0])) +			gpio_set_value(pdata->reset_gpio_port[0], 1); + +		if (gpio_is_valid(pdata->reset_gpio_port[1])) +			gpio_set_value(pdata->reset_gpio_port[1], 1); +	} +  	return 0;  err_add_hcd: @@ -259,8 +286,9 @@ err_io:   */  static int ehci_hcd_omap_remove(struct platform_device *pdev)  { -	struct device *dev	= &pdev->dev; -	struct usb_hcd *hcd	= dev_get_drvdata(dev); +	struct device *dev				= &pdev->dev; +	struct usb_hcd *hcd				= dev_get_drvdata(dev); +	struct ehci_hcd_omap_platform_data *pdata	= dev->platform_data;  	usb_remove_hcd(hcd);  	disable_put_regulator(dev->platform_data); @@ -269,6 +297,13 @@ static int ehci_hcd_omap_remove(struct platform_device *pdev)  	pm_runtime_put_sync(dev);  	pm_runtime_disable(dev); +	if (pdata->phy_reset) { +		if (gpio_is_valid(pdata->reset_gpio_port[0])) +			gpio_free(pdata->reset_gpio_port[0]); + +		if (gpio_is_valid(pdata->reset_gpio_port[1])) +			gpio_free(pdata->reset_gpio_port[1]); +	}  	return 0;  } diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index 01bb7241d6e..fe8dc069164 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c @@ -144,6 +144,14 @@ static int ehci_pci_setup(struct usb_hcd *hcd)  			hcd->has_tt = 1;  			tdi_reset(ehci);  		} +		if (pdev->subsystem_vendor == PCI_VENDOR_ID_ASUSTEK) { +			/* EHCI #1 or #2 on 6 Series/C200 Series chipset */ +			if (pdev->device == 0x1c26 || pdev->device == 0x1c2d) { +				ehci_info(ehci, "broken D3 during system sleep on ASUS\n"); +				hcd->broken_pci_sleep = 1; +				device_set_wakeup_capable(&pdev->dev, false); +			} +		}  		break;  	case PCI_VENDOR_ID_TDI:  		if (pdev->device == PCI_DEVICE_ID_TDI_EHCI) { diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c index 73544bd440b..f214a80cdee 100644 --- a/drivers/usb/host/ehci-tegra.c +++ b/drivers/usb/host/ehci-tegra.c @@ -24,6 +24,7 @@  #include <linux/gpio.h>  #include <linux/of.h>  #include <linux/of_gpio.h> +#include <linux/pm_runtime.h>  #include <mach/usb_phy.h>  #include <mach/iomap.h> @@ -37,9 +38,7 @@ struct tegra_ehci_hcd {  	struct clk *emc_clk;  	struct usb_phy *transceiver;  	int host_resumed; -	int bus_suspended;  	int port_resuming; -	int power_down_on_bus_suspend;  	enum tegra_usb_phy_port_speed port_speed;  }; @@ -273,120 +272,6 @@ static void tegra_ehci_restart(struct usb_hcd *hcd)  	up_write(&ehci_cf_port_reset_rwsem);  } -static int tegra_usb_suspend(struct usb_hcd *hcd) -{ -	struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller); -	struct ehci_regs __iomem *hw = tegra->ehci->regs; -	unsigned long flags; - -	spin_lock_irqsave(&tegra->ehci->lock, flags); - -	tegra->port_speed = (readl(&hw->port_status[0]) >> 26) & 0x3; -	ehci_halt(tegra->ehci); -	clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); - -	spin_unlock_irqrestore(&tegra->ehci->lock, flags); - -	tegra_ehci_power_down(hcd); -	return 0; -} - -static int tegra_usb_resume(struct usb_hcd *hcd) -{ -	struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller); -	struct ehci_hcd	*ehci = hcd_to_ehci(hcd); -	struct ehci_regs __iomem *hw = ehci->regs; -	unsigned long val; - -	set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); -	tegra_ehci_power_up(hcd); - -	if (tegra->port_speed > TEGRA_USB_PHY_PORT_SPEED_HIGH) { -		/* Wait for the phy to detect new devices -		 * before we restart the controller */ -		msleep(10); -		goto restart; -	} - -	/* Force the phy to keep data lines in suspend state */ -	tegra_ehci_phy_restore_start(tegra->phy, tegra->port_speed); - -	/* Enable host mode */ -	tdi_reset(ehci); - -	/* Enable Port Power */ -	val = readl(&hw->port_status[0]); -	val |= PORT_POWER; -	writel(val, &hw->port_status[0]); -	udelay(10); - -	/* Check if the phy resume from LP0. When the phy resume from LP0 -	 * USB register will be reset. */ -	if (!readl(&hw->async_next)) { -		/* Program the field PTC based on the saved speed mode */ -		val = readl(&hw->port_status[0]); -		val &= ~PORT_TEST(~0); -		if (tegra->port_speed == TEGRA_USB_PHY_PORT_SPEED_HIGH) -			val |= PORT_TEST_FORCE; -		else if (tegra->port_speed == TEGRA_USB_PHY_PORT_SPEED_FULL) -			val |= PORT_TEST(6); -		else if (tegra->port_speed == TEGRA_USB_PHY_PORT_SPEED_LOW) -			val |= PORT_TEST(7); -		writel(val, &hw->port_status[0]); -		udelay(10); - -		/* Disable test mode by setting PTC field to NORMAL_OP */ -		val = readl(&hw->port_status[0]); -		val &= ~PORT_TEST(~0); -		writel(val, &hw->port_status[0]); -		udelay(10); -	} - -	/* Poll until CCS is enabled */ -	if (handshake(ehci, &hw->port_status[0], PORT_CONNECT, -						 PORT_CONNECT, 2000)) { -		pr_err("%s: timeout waiting for PORT_CONNECT\n", __func__); -		goto restart; -	} - -	/* Poll until PE is enabled */ -	if (handshake(ehci, &hw->port_status[0], PORT_PE, -						 PORT_PE, 2000)) { -		pr_err("%s: timeout waiting for USB_PORTSC1_PE\n", __func__); -		goto restart; -	} - -	/* Clear the PCI status, to avoid an interrupt taken upon resume */ -	val = readl(&hw->status); -	val |= STS_PCD; -	writel(val, &hw->status); - -	/* Put controller in suspend mode by writing 1 to SUSP bit of PORTSC */ -	val = readl(&hw->port_status[0]); -	if ((val & PORT_POWER) && (val & PORT_PE)) { -		val |= PORT_SUSPEND; -		writel(val, &hw->port_status[0]); - -		/* Wait until port suspend completes */ -		if (handshake(ehci, &hw->port_status[0], PORT_SUSPEND, -							 PORT_SUSPEND, 1000)) { -			pr_err("%s: timeout waiting for PORT_SUSPEND\n", -								__func__); -			goto restart; -		} -	} - -	tegra_ehci_phy_restore_end(tegra->phy); -	return 0; - -restart: -	if (tegra->port_speed <= TEGRA_USB_PHY_PORT_SPEED_HIGH) -		tegra_ehci_phy_restore_end(tegra->phy); - -	tegra_ehci_restart(hcd); -	return 0; -} -  static void tegra_ehci_shutdown(struct usb_hcd *hcd)  {  	struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller); @@ -434,36 +319,6 @@ static int tegra_ehci_setup(struct usb_hcd *hcd)  	return retval;  } -#ifdef CONFIG_PM -static int tegra_ehci_bus_suspend(struct usb_hcd *hcd) -{ -	struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller); -	int error_status = 0; - -	error_status = ehci_bus_suspend(hcd); -	if (!error_status && tegra->power_down_on_bus_suspend) { -		tegra_usb_suspend(hcd); -		tegra->bus_suspended = 1; -	} - -	return error_status; -} - -static int tegra_ehci_bus_resume(struct usb_hcd *hcd) -{ -	struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller); - -	if (tegra->bus_suspended && tegra->power_down_on_bus_suspend) { -		tegra_usb_resume(hcd); -		tegra->bus_suspended = 0; -	} - -	tegra_usb_phy_preresume(tegra->phy); -	tegra->port_resuming = 1; -	return ehci_bus_resume(hcd); -} -#endif -  struct temp_buffer {  	void *kmalloc_ptr;  	void *old_xfer_buffer; @@ -574,8 +429,8 @@ static const struct hc_driver tegra_ehci_hc_driver = {  	.hub_control		= tegra_ehci_hub_control,  	.clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,  #ifdef CONFIG_PM -	.bus_suspend		= tegra_ehci_bus_suspend, -	.bus_resume		= tegra_ehci_bus_resume, +	.bus_suspend		= ehci_bus_suspend, +	.bus_resume		= ehci_bus_resume,  #endif  	.relinquish_port	= ehci_relinquish_port,  	.port_handed_over	= ehci_port_handed_over, @@ -603,11 +458,187 @@ static int setup_vbus_gpio(struct platform_device *pdev)  		dev_err(&pdev->dev, "can't enable vbus\n");  		return err;  	} -	gpio_set_value(gpio, 1);  	return err;  } +#ifdef CONFIG_PM + +static int controller_suspend(struct device *dev) +{ +	struct tegra_ehci_hcd *tegra = +			platform_get_drvdata(to_platform_device(dev)); +	struct ehci_hcd	*ehci = tegra->ehci; +	struct usb_hcd *hcd = ehci_to_hcd(ehci); +	struct ehci_regs __iomem *hw = ehci->regs; +	unsigned long flags; + +	if (time_before(jiffies, ehci->next_statechange)) +		msleep(10); + +	spin_lock_irqsave(&ehci->lock, flags); + +	tegra->port_speed = (readl(&hw->port_status[0]) >> 26) & 0x3; +	ehci_halt(ehci); +	clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); + +	spin_unlock_irqrestore(&ehci->lock, flags); + +	tegra_ehci_power_down(hcd); +	return 0; +} + +static int controller_resume(struct device *dev) +{ +	struct tegra_ehci_hcd *tegra = +			platform_get_drvdata(to_platform_device(dev)); +	struct ehci_hcd	*ehci = tegra->ehci; +	struct usb_hcd *hcd = ehci_to_hcd(ehci); +	struct ehci_regs __iomem *hw = ehci->regs; +	unsigned long val; + +	set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); +	tegra_ehci_power_up(hcd); + +	if (tegra->port_speed > TEGRA_USB_PHY_PORT_SPEED_HIGH) { +		/* Wait for the phy to detect new devices +		 * before we restart the controller */ +		msleep(10); +		goto restart; +	} + +	/* Force the phy to keep data lines in suspend state */ +	tegra_ehci_phy_restore_start(tegra->phy, tegra->port_speed); + +	/* Enable host mode */ +	tdi_reset(ehci); + +	/* Enable Port Power */ +	val = readl(&hw->port_status[0]); +	val |= PORT_POWER; +	writel(val, &hw->port_status[0]); +	udelay(10); + +	/* Check if the phy resume from LP0. When the phy resume from LP0 +	 * USB register will be reset. */ +	if (!readl(&hw->async_next)) { +		/* Program the field PTC based on the saved speed mode */ +		val = readl(&hw->port_status[0]); +		val &= ~PORT_TEST(~0); +		if (tegra->port_speed == TEGRA_USB_PHY_PORT_SPEED_HIGH) +			val |= PORT_TEST_FORCE; +		else if (tegra->port_speed == TEGRA_USB_PHY_PORT_SPEED_FULL) +			val |= PORT_TEST(6); +		else if (tegra->port_speed == TEGRA_USB_PHY_PORT_SPEED_LOW) +			val |= PORT_TEST(7); +		writel(val, &hw->port_status[0]); +		udelay(10); + +		/* Disable test mode by setting PTC field to NORMAL_OP */ +		val = readl(&hw->port_status[0]); +		val &= ~PORT_TEST(~0); +		writel(val, &hw->port_status[0]); +		udelay(10); +	} + +	/* Poll until CCS is enabled */ +	if (handshake(ehci, &hw->port_status[0], PORT_CONNECT, +						 PORT_CONNECT, 2000)) { +		pr_err("%s: timeout waiting for PORT_CONNECT\n", __func__); +		goto restart; +	} + +	/* Poll until PE is enabled */ +	if (handshake(ehci, &hw->port_status[0], PORT_PE, +						 PORT_PE, 2000)) { +		pr_err("%s: timeout waiting for USB_PORTSC1_PE\n", __func__); +		goto restart; +	} + +	/* Clear the PCI status, to avoid an interrupt taken upon resume */ +	val = readl(&hw->status); +	val |= STS_PCD; +	writel(val, &hw->status); + +	/* Put controller in suspend mode by writing 1 to SUSP bit of PORTSC */ +	val = readl(&hw->port_status[0]); +	if ((val & PORT_POWER) && (val & PORT_PE)) { +		val |= PORT_SUSPEND; +		writel(val, &hw->port_status[0]); + +		/* Wait until port suspend completes */ +		if (handshake(ehci, &hw->port_status[0], PORT_SUSPEND, +							 PORT_SUSPEND, 1000)) { +			pr_err("%s: timeout waiting for PORT_SUSPEND\n", +								__func__); +			goto restart; +		} +	} + +	tegra_ehci_phy_restore_end(tegra->phy); +	goto done; + + restart: +	if (tegra->port_speed <= TEGRA_USB_PHY_PORT_SPEED_HIGH) +		tegra_ehci_phy_restore_end(tegra->phy); + +	tegra_ehci_restart(hcd); + + done: +	tegra_usb_phy_preresume(tegra->phy); +	tegra->port_resuming = 1; +	return 0; +} + +static int tegra_ehci_suspend(struct device *dev) +{ +	struct tegra_ehci_hcd *tegra = +			platform_get_drvdata(to_platform_device(dev)); +	struct usb_hcd *hcd = ehci_to_hcd(tegra->ehci); +	int rc = 0; + +	/* +	 * When system sleep is supported and USB controller wakeup is +	 * implemented: If the controller is runtime-suspended and the +	 * wakeup setting needs to be changed, call pm_runtime_resume(). +	 */ +	if (HCD_HW_ACCESSIBLE(hcd)) +		rc = controller_suspend(dev); +	return rc; +} + +static int tegra_ehci_resume(struct device *dev) +{ +	int rc; + +	rc = controller_resume(dev); +	if (rc == 0) { +		pm_runtime_disable(dev); +		pm_runtime_set_active(dev); +		pm_runtime_enable(dev); +	} +	return rc; +} + +static int tegra_ehci_runtime_suspend(struct device *dev) +{ +	return controller_suspend(dev); +} + +static int tegra_ehci_runtime_resume(struct device *dev) +{ +	return controller_resume(dev); +} + +static const struct dev_pm_ops tegra_ehci_pm_ops = { +	.suspend	= tegra_ehci_suspend, +	.resume		= tegra_ehci_resume, +	.runtime_suspend = tegra_ehci_runtime_suspend, +	.runtime_resume	= tegra_ehci_runtime_resume, +}; + +#endif +  static u64 tegra_ehci_dma_mask = DMA_BIT_MASK(32);  static int tegra_ehci_probe(struct platform_device *pdev) @@ -722,7 +753,6 @@ static int tegra_ehci_probe(struct platform_device *pdev)  	}  	tegra->host_resumed = 1; -	tegra->power_down_on_bus_suspend = pdata->power_down_on_bus_suspend;  	tegra->ehci = hcd_to_ehci(hcd);  	irq = platform_get_irq(pdev, 0); @@ -731,7 +761,6 @@ static int tegra_ehci_probe(struct platform_device *pdev)  		err = -ENODEV;  		goto fail;  	} -	set_irq_flags(irq, IRQF_VALID);  #ifdef CONFIG_USB_OTG_UTILS  	if (pdata->operating_mode == TEGRA_USB_OTG) { @@ -747,6 +776,14 @@ static int tegra_ehci_probe(struct platform_device *pdev)  		goto fail;  	} +	pm_runtime_set_active(&pdev->dev); +	pm_runtime_get_noresume(&pdev->dev); + +	/* Don't skip the pm_runtime_forbid call if wakeup isn't working */ +	/* if (!pdata->power_down_on_bus_suspend) */ +		pm_runtime_forbid(&pdev->dev); +	pm_runtime_enable(&pdev->dev); +	pm_runtime_put_sync(&pdev->dev);  	return err;  fail: @@ -773,33 +810,6 @@ fail_hcd:  	return err;  } -#ifdef CONFIG_PM -static int tegra_ehci_resume(struct platform_device *pdev) -{ -	struct tegra_ehci_hcd *tegra = platform_get_drvdata(pdev); -	struct usb_hcd *hcd = ehci_to_hcd(tegra->ehci); - -	if (tegra->bus_suspended) -		return 0; - -	return tegra_usb_resume(hcd); -} - -static int tegra_ehci_suspend(struct platform_device *pdev, pm_message_t state) -{ -	struct tegra_ehci_hcd *tegra = platform_get_drvdata(pdev); -	struct usb_hcd *hcd = ehci_to_hcd(tegra->ehci); - -	if (tegra->bus_suspended) -		return 0; - -	if (time_before(jiffies, tegra->ehci->next_statechange)) -		msleep(10); - -	return tegra_usb_suspend(hcd); -} -#endif -  static int tegra_ehci_remove(struct platform_device *pdev)  {  	struct tegra_ehci_hcd *tegra = platform_get_drvdata(pdev); @@ -808,6 +818,10 @@ static int tegra_ehci_remove(struct platform_device *pdev)  	if (tegra == NULL || hcd == NULL)  		return -EINVAL; +	pm_runtime_get_sync(&pdev->dev); +	pm_runtime_disable(&pdev->dev); +	pm_runtime_put_noidle(&pdev->dev); +  #ifdef CONFIG_USB_OTG_UTILS  	if (tegra->transceiver) {  		otg_set_host(tegra->transceiver->otg, NULL); @@ -848,13 +862,12 @@ static struct of_device_id tegra_ehci_of_match[] __devinitdata = {  static struct platform_driver tegra_ehci_driver = {  	.probe		= tegra_ehci_probe,  	.remove		= tegra_ehci_remove, -#ifdef CONFIG_PM -	.suspend	= tegra_ehci_suspend, -	.resume		= tegra_ehci_resume, -#endif  	.shutdown	= tegra_ehci_hcd_shutdown,  	.driver		= {  		.name	= "tegra-ehci",  		.of_match_table = tegra_ehci_of_match, +#ifdef CONFIG_PM +		.pm	= &tegra_ehci_pm_ops, +#endif  	}  }; diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c index 09f597ad6e0..13ebeca8e73 100644 --- a/drivers/usb/host/ohci-at91.c +++ b/drivers/usb/host/ohci-at91.c @@ -94,7 +94,7 @@ static void at91_stop_hc(struct platform_device *pdev)  /*-------------------------------------------------------------------------*/ -static void usb_hcd_at91_remove (struct usb_hcd *, struct platform_device *); +static void __devexit usb_hcd_at91_remove (struct usb_hcd *, struct platform_device *);  /* configure so an HC device and id are always provided */  /* always called with process context; sleeping is OK */ @@ -108,7 +108,7 @@ static void usb_hcd_at91_remove (struct usb_hcd *, struct platform_device *);   * then invokes the start() method for the HCD associated with it   * through the hotplug entry's driver_data.   */ -static int usb_hcd_at91_probe(const struct hc_driver *driver, +static int __devinit usb_hcd_at91_probe(const struct hc_driver *driver,  			struct platform_device *pdev)  {  	int retval; @@ -203,7 +203,7 @@ static int usb_hcd_at91_probe(const struct hc_driver *driver,   * context, "rmmod" or something similar.   *   */ -static void usb_hcd_at91_remove(struct usb_hcd *hcd, +static void __devexit usb_hcd_at91_remove(struct usb_hcd *hcd,  				struct platform_device *pdev)  {  	usb_remove_hcd(hcd); @@ -545,7 +545,7 @@ static int __devinit ohci_at91_of_init(struct platform_device *pdev)  /*-------------------------------------------------------------------------*/ -static int ohci_hcd_at91_drv_probe(struct platform_device *pdev) +static int __devinit ohci_hcd_at91_drv_probe(struct platform_device *pdev)  {  	struct at91_usbh_data	*pdata;  	int			i; @@ -620,7 +620,7 @@ static int ohci_hcd_at91_drv_probe(struct platform_device *pdev)  	return usb_hcd_at91_probe(&ohci_at91_hc_driver, pdev);  } -static int ohci_hcd_at91_drv_remove(struct platform_device *pdev) +static int __devexit ohci_hcd_at91_drv_remove(struct platform_device *pdev)  {  	struct at91_usbh_data	*pdata = pdev->dev.platform_data;  	int			i; @@ -696,7 +696,7 @@ MODULE_ALIAS("platform:at91_ohci");  static struct platform_driver ohci_hcd_at91_driver = {  	.probe		= ohci_hcd_at91_drv_probe, -	.remove		= ohci_hcd_at91_drv_remove, +	.remove		= __devexit_p(ohci_hcd_at91_drv_remove),  	.shutdown	= usb_hcd_platform_shutdown,  	.suspend	= ohci_hcd_at91_drv_suspend,  	.resume		= ohci_hcd_at91_drv_resume, diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c index 959145baf3c..9dcb68f04f0 100644 --- a/drivers/usb/misc/usbtest.c +++ b/drivers/usb/misc/usbtest.c @@ -423,7 +423,7 @@ alloc_sglist(int nents, int max, int vary)  	unsigned		i;  	unsigned		size = max; -	sg = kmalloc(nents * sizeof *sg, GFP_KERNEL); +	sg = kmalloc_array(nents, sizeof *sg, GFP_KERNEL);  	if (!sg)  		return NULL;  	sg_init_table(sg, nents); @@ -904,6 +904,9 @@ test_ctrl_queue(struct usbtest_dev *dev, struct usbtest_param *param)  	struct ctrl_ctx		context;  	int			i; +	if (param->sglen == 0 || param->iterations > UINT_MAX / param->sglen) +		return -EOPNOTSUPP; +  	spin_lock_init(&context.lock);  	context.dev = dev;  	init_completion(&context.complete); @@ -1981,8 +1984,6 @@ usbtest_ioctl(struct usb_interface *intf, unsigned int code, void *buf)  	/* queued control messaging */  	case 10: -		if (param->sglen == 0) -			break;  		retval = 0;  		dev_info(&intf->dev,  				"TEST 10:  queue %d control calls, %d times\n", @@ -2276,6 +2277,8 @@ usbtest_probe(struct usb_interface *intf, const struct usb_device_id *id)  			if (status < 0) {  				WARNING(dev, "couldn't get endpoints, %d\n",  						status); +				kfree(dev->buf); +				kfree(dev);  				return status;  			}  			/* may find bulk or ISO pipes */ diff --git a/drivers/usb/misc/yurex.c b/drivers/usb/misc/yurex.c index 897edda4227..70201462e19 100644 --- a/drivers/usb/misc/yurex.c +++ b/drivers/usb/misc/yurex.c @@ -99,9 +99,7 @@ static void yurex_delete(struct kref *kref)  	usb_put_dev(dev->udev);  	if (dev->cntl_urb) {  		usb_kill_urb(dev->cntl_urb); -		if (dev->cntl_req) -			usb_free_coherent(dev->udev, YUREX_BUF_SIZE, -				dev->cntl_req, dev->cntl_urb->setup_dma); +		kfree(dev->cntl_req);  		if (dev->cntl_buffer)  			usb_free_coherent(dev->udev, YUREX_BUF_SIZE,  				dev->cntl_buffer, dev->cntl_urb->transfer_dma); @@ -234,9 +232,7 @@ static int yurex_probe(struct usb_interface *interface, const struct usb_device_  	}  	/* allocate buffer for control req */ -	dev->cntl_req = usb_alloc_coherent(dev->udev, YUREX_BUF_SIZE, -					   GFP_KERNEL, -					   &dev->cntl_urb->setup_dma); +	dev->cntl_req = kmalloc(YUREX_BUF_SIZE, GFP_KERNEL);  	if (!dev->cntl_req) {  		err("Could not allocate cntl_req");  		goto error; @@ -286,7 +282,7 @@ static int yurex_probe(struct usb_interface *interface, const struct usb_device_  			 usb_rcvintpipe(dev->udev, dev->int_in_endpointAddr),  			 dev->int_buffer, YUREX_BUF_SIZE, yurex_interrupt,  			 dev, 1); -	dev->cntl_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; +	dev->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;  	if (usb_submit_urb(dev->urb, GFP_KERNEL)) {  		retval = -EIO;  		err("Could not submitting URB"); diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c index 97ab975fa44..768b4b55c81 100644 --- a/drivers/usb/musb/davinci.c +++ b/drivers/usb/musb/davinci.c @@ -386,7 +386,7 @@ static int davinci_musb_init(struct musb *musb)  	usb_nop_xceiv_register();  	musb->xceiv = usb_get_transceiver();  	if (!musb->xceiv) -		return -ENODEV; +		goto unregister;  	musb->mregs += DAVINCI_BASE_OFFSET; @@ -444,6 +444,7 @@ static int davinci_musb_init(struct musb *musb)  fail:  	usb_put_transceiver(musb->xceiv); +unregister:  	usb_nop_xceiv_unregister();  	return -ENODEV;  } diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 0f8b82918a4..66aaccf0449 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -137,6 +137,9 @@ static int musb_ulpi_read(struct usb_phy *phy, u32 offset)  	int	i = 0;  	u8	r;  	u8	power; +	int	ret; + +	pm_runtime_get_sync(phy->io_dev);  	/* Make sure the transceiver is not in low power mode */  	power = musb_readb(addr, MUSB_POWER); @@ -154,15 +157,22 @@ static int musb_ulpi_read(struct usb_phy *phy, u32 offset)  	while (!(musb_readb(addr, MUSB_ULPI_REG_CONTROL)  				& MUSB_ULPI_REG_CMPLT)) {  		i++; -		if (i == 10000) -			return -ETIMEDOUT; +		if (i == 10000) { +			ret = -ETIMEDOUT; +			goto out; +		}  	}  	r = musb_readb(addr, MUSB_ULPI_REG_CONTROL);  	r &= ~MUSB_ULPI_REG_CMPLT;  	musb_writeb(addr, MUSB_ULPI_REG_CONTROL, r); -	return musb_readb(addr, MUSB_ULPI_REG_DATA); +	ret = musb_readb(addr, MUSB_ULPI_REG_DATA); + +out: +	pm_runtime_put(phy->io_dev); + +	return ret;  }  static int musb_ulpi_write(struct usb_phy *phy, u32 offset, u32 data) @@ -171,6 +181,9 @@ static int musb_ulpi_write(struct usb_phy *phy, u32 offset, u32 data)  	int	i = 0;  	u8	r = 0;  	u8	power; +	int	ret = 0; + +	pm_runtime_get_sync(phy->io_dev);  	/* Make sure the transceiver is not in low power mode */  	power = musb_readb(addr, MUSB_POWER); @@ -184,15 +197,20 @@ static int musb_ulpi_write(struct usb_phy *phy, u32 offset, u32 data)  	while (!(musb_readb(addr, MUSB_ULPI_REG_CONTROL)  				& MUSB_ULPI_REG_CMPLT)) {  		i++; -		if (i == 10000) -			return -ETIMEDOUT; +		if (i == 10000) { +			ret = -ETIMEDOUT; +			goto out; +		}  	}  	r = musb_readb(addr, MUSB_ULPI_REG_CONTROL);  	r &= ~MUSB_ULPI_REG_CMPLT;  	musb_writeb(addr, MUSB_ULPI_REG_CONTROL, r); -	return 0; +out: +	pm_runtime_put(phy->io_dev); + +	return ret;  }  #else  #define musb_ulpi_read		NULL @@ -1904,14 +1922,17 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)  	if (!musb->isr) {  		status = -ENODEV; -		goto fail3; +		goto fail2;  	}  	if (!musb->xceiv->io_ops) { +		musb->xceiv->io_dev = musb->controller;  		musb->xceiv->io_priv = musb->mregs;  		musb->xceiv->io_ops = &musb_ulpi_access;  	} +	pm_runtime_get_sync(musb->controller); +  #ifndef CONFIG_MUSB_PIO_ONLY  	if (use_dma && dev->dma_mask) {  		struct dma_controller	*c; @@ -2023,6 +2044,8 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)  		goto fail5;  #endif +	pm_runtime_put(musb->controller); +  	dev_info(dev, "USB %s mode controller at %p using %s, IRQ %d\n",  			({char *s;  			 switch (musb->board_mode) { @@ -2047,6 +2070,9 @@ fail4:  		musb_gadget_cleanup(musb);  fail3: +	pm_runtime_put_sync(musb->controller); + +fail2:  	if (musb->irq_wake)  		device_init_wakeup(dev, 0);  	musb_platform_exit(musb); diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h index 93de517a32a..f4a40f001c8 100644 --- a/drivers/usb/musb/musb_core.h +++ b/drivers/usb/musb/musb_core.h @@ -449,7 +449,7 @@ struct musb {  	 * We added this flag to forcefully disable double  	 * buffering until we get it working.  	 */ -	unsigned                double_buffer_not_ok:1 __deprecated; +	unsigned                double_buffer_not_ok:1;  	struct musb_hdrc_config	*config; diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index 79cb0af779f..ef8d744800a 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c @@ -2098,7 +2098,7 @@ static int musb_cleanup_urb(struct urb *urb, struct musb_qh *qh)  	}  	/* turn off DMA requests, discard state, stop polling ... */ -	if (is_in) { +	if (ep->epnum && is_in) {  		/* giveback saves bulk toggle */  		csr = musb_h_flush_rxfifo(ep, 0); diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index 2ae0bb30999..c7785e81254 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c @@ -282,7 +282,8 @@ static void musb_otg_notifier_work(struct work_struct *data_notifier_work)  static int omap2430_musb_init(struct musb *musb)  { -	u32 l, status = 0; +	u32 l; +	int status = 0;  	struct device *dev = musb->controller;  	struct musb_hdrc_platform_data *plat = dev->platform_data;  	struct omap_musb_board_data *data = plat->board_data; @@ -301,7 +302,7 @@ static int omap2430_musb_init(struct musb *musb)  	status = pm_runtime_get_sync(dev);  	if (status < 0) { -		dev_err(dev, "pm_runtime_get_sync FAILED"); +		dev_err(dev, "pm_runtime_get_sync FAILED %d\n", status);  		goto err1;  	} @@ -333,6 +334,7 @@ static int omap2430_musb_init(struct musb *musb)  	setup_timer(&musb_idle_timer, musb_do_idle, (unsigned long) musb); +	pm_runtime_put_noidle(musb->controller);  	return 0;  err1: @@ -452,14 +454,14 @@ static int __devinit omap2430_probe(struct platform_device *pdev)  		goto err2;  	} +	pm_runtime_enable(&pdev->dev); +  	ret = platform_device_add(musb);  	if (ret) {  		dev_err(&pdev->dev, "failed to register musb device\n");  		goto err2;  	} -	pm_runtime_enable(&pdev->dev); -  	return 0;  err2: @@ -478,7 +480,6 @@ static int __devexit omap2430_remove(struct platform_device *pdev)  	platform_device_del(glue->musb);  	platform_device_put(glue->musb); -	pm_runtime_put(&pdev->dev);  	kfree(glue);  	return 0; @@ -491,11 +492,13 @@ static int omap2430_runtime_suspend(struct device *dev)  	struct omap2430_glue		*glue = dev_get_drvdata(dev);  	struct musb			*musb = glue_to_musb(glue); -	musb->context.otg_interfsel = musb_readl(musb->mregs, -						OTG_INTERFSEL); +	if (musb) { +		musb->context.otg_interfsel = musb_readl(musb->mregs, +				OTG_INTERFSEL); -	omap2430_low_level_exit(musb); -	usb_phy_set_suspend(musb->xceiv, 1); +		omap2430_low_level_exit(musb); +		usb_phy_set_suspend(musb->xceiv, 1); +	}  	return 0;  } @@ -505,11 +508,13 @@ static int omap2430_runtime_resume(struct device *dev)  	struct omap2430_glue		*glue = dev_get_drvdata(dev);  	struct musb			*musb = glue_to_musb(glue); -	omap2430_low_level_init(musb); -	musb_writel(musb->mregs, OTG_INTERFSEL, -					musb->context.otg_interfsel); +	if (musb) { +		omap2430_low_level_init(musb); +		musb_writel(musb->mregs, OTG_INTERFSEL, +				musb->context.otg_interfsel); -	usb_phy_set_suspend(musb->xceiv, 0); +		usb_phy_set_suspend(musb->xceiv, 0); +	}  	return 0;  } diff --git a/drivers/usb/otg/gpio_vbus.c b/drivers/usb/otg/gpio_vbus.c index 3ece43a2e4c..a0a2178974f 100644 --- a/drivers/usb/otg/gpio_vbus.c +++ b/drivers/usb/otg/gpio_vbus.c @@ -96,7 +96,7 @@ static void gpio_vbus_work(struct work_struct *work)  	struct gpio_vbus_data *gpio_vbus =  		container_of(work, struct gpio_vbus_data, work);  	struct gpio_vbus_mach_info *pdata = gpio_vbus->dev->platform_data; -	int gpio; +	int gpio, status;  	if (!gpio_vbus->phy.otg->gadget)  		return; @@ -108,7 +108,9 @@ static void gpio_vbus_work(struct work_struct *work)  	 */  	gpio = pdata->gpio_pullup;  	if (is_vbus_powered(pdata)) { +		status = USB_EVENT_VBUS;  		gpio_vbus->phy.state = OTG_STATE_B_PERIPHERAL; +		gpio_vbus->phy.last_event = status;  		usb_gadget_vbus_connect(gpio_vbus->phy.otg->gadget);  		/* drawing a "unit load" is *always* OK, except for OTG */ @@ -117,6 +119,9 @@ static void gpio_vbus_work(struct work_struct *work)  		/* optionally enable D+ pullup */  		if (gpio_is_valid(gpio))  			gpio_set_value(gpio, !pdata->gpio_pullup_inverted); + +		atomic_notifier_call_chain(&gpio_vbus->phy.notifier, +					   status, gpio_vbus->phy.otg->gadget);  	} else {  		/* optionally disable D+ pullup */  		if (gpio_is_valid(gpio)) @@ -125,7 +130,12 @@ static void gpio_vbus_work(struct work_struct *work)  		set_vbus_draw(gpio_vbus, 0);  		usb_gadget_vbus_disconnect(gpio_vbus->phy.otg->gadget); +		status = USB_EVENT_NONE;  		gpio_vbus->phy.state = OTG_STATE_B_IDLE; +		gpio_vbus->phy.last_event = status; + +		atomic_notifier_call_chain(&gpio_vbus->phy.notifier, +					   status, gpio_vbus->phy.otg->gadget);  	}  } @@ -287,6 +297,9 @@ static int __init gpio_vbus_probe(struct platform_device *pdev)  			irq, err);  		goto err_irq;  	} + +	ATOMIC_INIT_NOTIFIER_HEAD(&gpio_vbus->phy.notifier); +  	INIT_WORK(&gpio_vbus->work, gpio_vbus_work);  	gpio_vbus->vbus_draw = regulator_get(&pdev->dev, "vbus_draw"); diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index 0310e2df59f..ec30f95ef39 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -287,7 +287,8 @@ static int cp210x_get_config(struct usb_serial_port *port, u8 request,  	/* Issue the request, attempting to read 'size' bytes */  	result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),  				request, REQTYPE_DEVICE_TO_HOST, 0x0000, -				port_priv->bInterfaceNumber, buf, size, 300); +				port_priv->bInterfaceNumber, buf, size, +				USB_CTRL_GET_TIMEOUT);  	/* Convert data into an array of integers */  	for (i = 0; i < length; i++) @@ -340,12 +341,14 @@ static int cp210x_set_config(struct usb_serial_port *port, u8 request,  		result = usb_control_msg(serial->dev,  				usb_sndctrlpipe(serial->dev, 0),  				request, REQTYPE_HOST_TO_DEVICE, 0x0000, -				port_priv->bInterfaceNumber, buf, size, 300); +				port_priv->bInterfaceNumber, buf, size, +				USB_CTRL_SET_TIMEOUT);  	} else {  		result = usb_control_msg(serial->dev,  				usb_sndctrlpipe(serial->dev, 0),  				request, REQTYPE_HOST_TO_DEVICE, data[0], -				port_priv->bInterfaceNumber, NULL, 0, 300); +				port_priv->bInterfaceNumber, NULL, 0, +				USB_CTRL_SET_TIMEOUT);  	}  	kfree(buf); diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index fdd5aa2c8d8..8c8bf806f6f 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c @@ -221,7 +221,7 @@ static const struct sierra_iface_info typeB_interface_list = {  };  /* 'blacklist' of interfaces not served by this driver */ -static const u8 direct_ip_non_serial_ifaces[] = { 7, 8, 9, 10, 11 }; +static const u8 direct_ip_non_serial_ifaces[] = { 7, 8, 9, 10, 11, 19, 20 };  static const struct sierra_iface_info direct_ip_interface_blacklist = {  	.infolen = ARRAY_SIZE(direct_ip_non_serial_ifaces),  	.ifaceinfo = direct_ip_non_serial_ifaces, @@ -289,7 +289,6 @@ static const struct usb_device_id id_table[] = {  	{ USB_DEVICE(0x1199, 0x6856) },	/* Sierra Wireless AirCard 881 U */  	{ USB_DEVICE(0x1199, 0x6859) },	/* Sierra Wireless AirCard 885 E */  	{ USB_DEVICE(0x1199, 0x685A) },	/* Sierra Wireless AirCard 885 E */ -	{ USB_DEVICE(0x1199, 0x68A2) }, /* Sierra Wireless MC7710 */  	/* Sierra Wireless C885 */  	{ USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6880, 0xFF, 0xFF, 0xFF)},  	/* Sierra Wireless C888, Air Card 501, USB 303, USB 304 */ @@ -299,6 +298,9 @@ static const struct usb_device_id id_table[] = {  	/* Sierra Wireless HSPA Non-Composite Device */  	{ USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6892, 0xFF, 0xFF, 0xFF)},  	{ USB_DEVICE(0x1199, 0x6893) },	/* Sierra Wireless Device */ +	{ USB_DEVICE(0x1199, 0x68A2),   /* Sierra Wireless MC77xx in QMI mode */ +	  .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist +	},  	{ USB_DEVICE(0x1199, 0x68A3), 	/* Sierra Wireless Direct IP modems */  	  .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist  	}, diff --git a/drivers/uwb/hwa-rc.c b/drivers/uwb/hwa-rc.c index 66797e9c501..810c90ae2c5 100644 --- a/drivers/uwb/hwa-rc.c +++ b/drivers/uwb/hwa-rc.c @@ -645,7 +645,8 @@ void hwarc_neep_cb(struct urb *urb)  		dev_err(dev, "NEEP: URB error %d\n", urb->status);  	}  	result = usb_submit_urb(urb, GFP_ATOMIC); -	if (result < 0) { +	if (result < 0 && result != -ENODEV && result != -EPERM) { +		/* ignoring unrecoverable errors */  		dev_err(dev, "NEEP: Can't resubmit URB (%d) resetting device\n",  			result);  		goto error; diff --git a/drivers/uwb/neh.c b/drivers/uwb/neh.c index a269937be1b..8cb71bb333c 100644 --- a/drivers/uwb/neh.c +++ b/drivers/uwb/neh.c @@ -107,6 +107,7 @@ struct uwb_rc_neh {  	u8 evt_type;  	__le16 evt;  	u8 context; +	u8 completed;  	uwb_rc_cmd_cb_f cb;  	void *arg; @@ -409,6 +410,7 @@ static void uwb_rc_neh_grok_event(struct uwb_rc *rc, struct uwb_rceb *rceb, size  	struct device *dev = &rc->uwb_dev.dev;  	struct uwb_rc_neh *neh;  	struct uwb_rceb *notif; +	unsigned long flags;  	if (rceb->bEventContext == 0) {  		notif = kmalloc(size, GFP_ATOMIC); @@ -422,7 +424,11 @@ static void uwb_rc_neh_grok_event(struct uwb_rc *rc, struct uwb_rceb *rceb, size  	} else {  		neh = uwb_rc_neh_lookup(rc, rceb);  		if (neh) { -			del_timer_sync(&neh->timer); +			spin_lock_irqsave(&rc->neh_lock, flags); +			/* to guard against a timeout */ +			neh->completed = 1; +			del_timer(&neh->timer); +			spin_unlock_irqrestore(&rc->neh_lock, flags);  			uwb_rc_neh_cb(neh, rceb, size);  		} else  			dev_warn(dev, "event 0x%02x/%04x/%02x (%zu bytes): nobody cared\n", @@ -568,6 +574,10 @@ static void uwb_rc_neh_timer(unsigned long arg)  	unsigned long flags;  	spin_lock_irqsave(&rc->neh_lock, flags); +	if (neh->completed) { +		spin_unlock_irqrestore(&rc->neh_lock, flags); +		return; +	}  	if (neh->context)  		__uwb_rc_neh_rm(rc, neh);  	else diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c index f0da2c32fbd..1f21d2a1e52 100644 --- a/drivers/vhost/net.c +++ b/drivers/vhost/net.c @@ -238,7 +238,7 @@ static void handle_tx(struct vhost_net *net)  				vq->heads[vq->upend_idx].len = len;  				ubuf->callback = vhost_zerocopy_callback; -				ubuf->arg = vq->ubufs; +				ubuf->ctx = vq->ubufs;  				ubuf->desc = vq->upend_idx;  				msg.msg_control = ubuf;  				msg.msg_controllen = sizeof(ubuf); diff --git a/drivers/vhost/test.c b/drivers/vhost/test.c index fc9a1d75281..3de00d9fae2 100644 --- a/drivers/vhost/test.c +++ b/drivers/vhost/test.c @@ -155,7 +155,7 @@ static int vhost_test_release(struct inode *inode, struct file *f)  	vhost_test_stop(n, &private);  	vhost_test_flush(n); -	vhost_dev_cleanup(&n->dev); +	vhost_dev_cleanup(&n->dev, false);  	/* We do an extra flush before freeing memory,  	 * since jobs can re-queue themselves. */  	vhost_test_flush(n); diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index 947f00d8e09..51e4c1eeec4 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c @@ -1598,10 +1598,9 @@ void vhost_ubuf_put_and_wait(struct vhost_ubuf_ref *ubufs)  	kfree(ubufs);  } -void vhost_zerocopy_callback(void *arg) +void vhost_zerocopy_callback(struct ubuf_info *ubuf)  { -	struct ubuf_info *ubuf = arg; -	struct vhost_ubuf_ref *ubufs = ubuf->arg; +	struct vhost_ubuf_ref *ubufs = ubuf->ctx;  	struct vhost_virtqueue *vq = ubufs->vq;  	/* set len = 1 to mark this desc buffers done DMA */ diff --git a/drivers/vhost/vhost.h b/drivers/vhost/vhost.h index 8dcf4cca6bf..8de1fd5b8ef 100644 --- a/drivers/vhost/vhost.h +++ b/drivers/vhost/vhost.h @@ -188,7 +188,7 @@ bool vhost_enable_notify(struct vhost_dev *, struct vhost_virtqueue *);  int vhost_log_write(struct vhost_virtqueue *vq, struct vhost_log *log,  		    unsigned int log_num, u64 len); -void vhost_zerocopy_callback(void *arg); +void vhost_zerocopy_callback(struct ubuf_info *);  int vhost_zerocopy_signal_used(struct vhost_virtqueue *vq);  #define vq_err(vq, fmt, ...) do {                                  \ diff --git a/drivers/video/bfin-lq035q1-fb.c b/drivers/video/bfin-lq035q1-fb.c index 86922ac8441..353c02fe8a9 100644 --- a/drivers/video/bfin-lq035q1-fb.c +++ b/drivers/video/bfin-lq035q1-fb.c @@ -13,6 +13,7 @@  #include <linux/errno.h>  #include <linux/string.h>  #include <linux/fb.h> +#include <linux/gpio.h>  #include <linux/slab.h>  #include <linux/init.h>  #include <linux/types.h> diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c index 05f0a80818a..c2d05a8279f 100644 --- a/drivers/virtio/virtio_balloon.c +++ b/drivers/virtio/virtio_balloon.c @@ -28,6 +28,13 @@  #include <linux/slab.h>  #include <linux/module.h> +/* + * Balloon device works in 4K page units.  So each page is pointed to by + * multiple balloon pages.  All memory counters in this driver are in balloon + * page units. + */ +#define VIRTIO_BALLOON_PAGES_PER_PAGE (PAGE_SIZE >> VIRTIO_BALLOON_PFN_SHIFT) +  struct virtio_balloon  {  	struct virtio_device *vdev; @@ -42,8 +49,13 @@ struct virtio_balloon  	/* Waiting for host to ack the pages we released. */  	struct completion acked; -	/* The pages we've told the Host we're not using. */ +	/* Number of balloon pages we've told the Host we're not using. */  	unsigned int num_pages; +	/* +	 * The pages we've told the Host we're not using. +	 * Each page on this list adds VIRTIO_BALLOON_PAGES_PER_PAGE +	 * to num_pages above. +	 */  	struct list_head pages;  	/* The array of pfns we tell the Host about. */ @@ -66,7 +78,13 @@ static u32 page_to_balloon_pfn(struct page *page)  	BUILD_BUG_ON(PAGE_SHIFT < VIRTIO_BALLOON_PFN_SHIFT);  	/* Convert pfn from Linux page size to balloon page size. */ -	return pfn >> (PAGE_SHIFT - VIRTIO_BALLOON_PFN_SHIFT); +	return pfn * VIRTIO_BALLOON_PAGES_PER_PAGE; +} + +static struct page *balloon_pfn_to_page(u32 pfn) +{ +	BUG_ON(pfn % VIRTIO_BALLOON_PAGES_PER_PAGE); +	return pfn_to_page(pfn / VIRTIO_BALLOON_PAGES_PER_PAGE);  }  static void balloon_ack(struct virtqueue *vq) @@ -96,12 +114,23 @@ static void tell_host(struct virtio_balloon *vb, struct virtqueue *vq)  	wait_for_completion(&vb->acked);  } +static void set_page_pfns(u32 pfns[], struct page *page) +{ +	unsigned int i; + +	/* Set balloon pfns pointing at this page. +	 * Note that the first pfn points at start of the page. */ +	for (i = 0; i < VIRTIO_BALLOON_PAGES_PER_PAGE; i++) +		pfns[i] = page_to_balloon_pfn(page) + i; +} +  static void fill_balloon(struct virtio_balloon *vb, size_t num)  {  	/* We can only do one array worth at a time. */  	num = min(num, ARRAY_SIZE(vb->pfns)); -	for (vb->num_pfns = 0; vb->num_pfns < num; vb->num_pfns++) { +	for (vb->num_pfns = 0; vb->num_pfns < num; +	     vb->num_pfns += VIRTIO_BALLOON_PAGES_PER_PAGE) {  		struct page *page = alloc_page(GFP_HIGHUSER | __GFP_NORETRY |  					__GFP_NOMEMALLOC | __GFP_NOWARN);  		if (!page) { @@ -113,9 +142,9 @@ static void fill_balloon(struct virtio_balloon *vb, size_t num)  			msleep(200);  			break;  		} -		vb->pfns[vb->num_pfns] = page_to_balloon_pfn(page); +		set_page_pfns(vb->pfns + vb->num_pfns, page); +		vb->num_pages += VIRTIO_BALLOON_PAGES_PER_PAGE;  		totalram_pages--; -		vb->num_pages++;  		list_add(&page->lru, &vb->pages);  	} @@ -130,8 +159,9 @@ static void release_pages_by_pfn(const u32 pfns[], unsigned int num)  {  	unsigned int i; -	for (i = 0; i < num; i++) { -		__free_page(pfn_to_page(pfns[i])); +	/* Find pfns pointing at start of each page, get pages and free them. */ +	for (i = 0; i < num; i += VIRTIO_BALLOON_PAGES_PER_PAGE) { +		__free_page(balloon_pfn_to_page(pfns[i]));  		totalram_pages++;  	}  } @@ -143,11 +173,12 @@ static void leak_balloon(struct virtio_balloon *vb, size_t num)  	/* We can only do one array worth at a time. */  	num = min(num, ARRAY_SIZE(vb->pfns)); -	for (vb->num_pfns = 0; vb->num_pfns < num; vb->num_pfns++) { +	for (vb->num_pfns = 0; vb->num_pfns < num; +	     vb->num_pfns += VIRTIO_BALLOON_PAGES_PER_PAGE) {  		page = list_first_entry(&vb->pages, struct page, lru);  		list_del(&page->lru); -		vb->pfns[vb->num_pfns] = page_to_balloon_pfn(page); -		vb->num_pages--; +		set_page_pfns(vb->pfns + vb->num_pfns, page); +		vb->num_pages -= VIRTIO_BALLOON_PAGES_PER_PAGE;  	}  	/* @@ -234,11 +265,14 @@ static void virtballoon_changed(struct virtio_device *vdev)  static inline s64 towards_target(struct virtio_balloon *vb)  { -	u32 v; +	__le32 v; +	s64 target; +  	vb->vdev->config->get(vb->vdev,  			      offsetof(struct virtio_balloon_config, num_pages),  			      &v, sizeof(v)); -	return (s64)v - vb->num_pages; +	target = le32_to_cpu(v); +	return target - vb->num_pages;  }  static void update_balloon_size(struct virtio_balloon *vb) diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c index cbc7ceef278..9f13b897fd6 100644 --- a/drivers/watchdog/hpwdt.c +++ b/drivers/watchdog/hpwdt.c @@ -435,16 +435,16 @@ static void hpwdt_start(void)  {  	reload = SECS_TO_TICKS(soft_margin);  	iowrite16(reload, hpwdt_timer_reg); -	iowrite16(0x85, hpwdt_timer_con); +	iowrite8(0x85, hpwdt_timer_con);  }  static void hpwdt_stop(void)  {  	unsigned long data; -	data = ioread16(hpwdt_timer_con); +	data = ioread8(hpwdt_timer_con);  	data &= 0xFE; -	iowrite16(data, hpwdt_timer_con); +	iowrite8(data, hpwdt_timer_con);  }  static void hpwdt_ping(void) diff --git a/drivers/xen/events.c b/drivers/xen/events.c index 4b33acd8ed4..0a8a17cd80b 100644 --- a/drivers/xen/events.c +++ b/drivers/xen/events.c @@ -274,7 +274,7 @@ static unsigned int cpu_from_evtchn(unsigned int evtchn)  static bool pirq_check_eoi_map(unsigned irq)  { -	return test_bit(irq, pirq_eoi_map); +	return test_bit(pirq_from_irq(irq), pirq_eoi_map);  }  static bool pirq_needs_eoi_flag(unsigned irq) diff --git a/drivers/xen/gntdev.c b/drivers/xen/gntdev.c index 99d8151c824..1ffd03bf8e1 100644 --- a/drivers/xen/gntdev.c +++ b/drivers/xen/gntdev.c @@ -722,7 +722,7 @@ static int gntdev_mmap(struct file *flip, struct vm_area_struct *vma)  	vma->vm_flags |= VM_RESERVED|VM_DONTEXPAND;  	if (use_ptemod) -		vma->vm_flags |= VM_DONTCOPY|VM_PFNMAP; +		vma->vm_flags |= VM_DONTCOPY;  	vma->vm_private_data = map; diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c index b4d4eac761d..f100ce20b16 100644 --- a/drivers/xen/grant-table.c +++ b/drivers/xen/grant-table.c @@ -1029,6 +1029,7 @@ int gnttab_init(void)  	int i;  	unsigned int max_nr_glist_frames, nr_glist_frames;  	unsigned int nr_init_grefs; +	int ret;  	nr_grant_frames = 1;  	boot_max_nr_grant_frames = __max_nr_grant_frames(); @@ -1047,12 +1048,16 @@ int gnttab_init(void)  	nr_glist_frames = (nr_grant_frames * GREFS_PER_GRANT_FRAME + RPP - 1) / RPP;  	for (i = 0; i < nr_glist_frames; i++) {  		gnttab_list[i] = (grant_ref_t *)__get_free_page(GFP_KERNEL); -		if (gnttab_list[i] == NULL) +		if (gnttab_list[i] == NULL) { +			ret = -ENOMEM;  			goto ini_nomem; +		}  	} -	if (gnttab_resume() < 0) -		return -ENODEV; +	if (gnttab_resume() < 0) { +		ret = -ENODEV; +		goto ini_nomem; +	}  	nr_init_grefs = nr_grant_frames * GREFS_PER_GRANT_FRAME; @@ -1070,7 +1075,7 @@ int gnttab_init(void)  	for (i--; i >= 0; i--)  		free_page((unsigned long)gnttab_list[i]);  	kfree(gnttab_list); -	return -ENOMEM; +	return ret;  }  EXPORT_SYMBOL_GPL(gnttab_init); diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c index 9e14ae6cd49..412b96cc530 100644 --- a/drivers/xen/manage.c +++ b/drivers/xen/manage.c @@ -132,6 +132,7 @@ static void do_suspend(void)  	err = dpm_suspend_end(PMSG_FREEZE);  	if (err) {  		printk(KERN_ERR "dpm_suspend_end failed: %d\n", err); +		si.cancelled = 0;  		goto out_resume;  	} diff --git a/drivers/xen/xen-acpi-processor.c b/drivers/xen/xen-acpi-processor.c index 174b5653cd8..0b48579a9cd 100644 --- a/drivers/xen/xen-acpi-processor.c +++ b/drivers/xen/xen-acpi-processor.c @@ -128,7 +128,10 @@ static int push_cxx_to_hypervisor(struct acpi_processor *_pr)  			pr_debug("     C%d: %s %d uS\n",  				 cx->type, cx->desc, (u32)cx->latency);  		} -	} else +	} else if (ret != -EINVAL) +		/* EINVAL means the ACPI ID is incorrect - meaning the ACPI +		 * table is referencing a non-existing CPU - which can happen +		 * with broken ACPI tables. */  		pr_err(DRV_NAME "(CX): Hypervisor error (%d) for ACPI CPU%u\n",  		       ret, _pr->acpi_id); diff --git a/drivers/xen/xenbus/xenbus_probe_frontend.c b/drivers/xen/xenbus/xenbus_probe_frontend.c index f20c5f178b4..a31b54d4883 100644 --- a/drivers/xen/xenbus/xenbus_probe_frontend.c +++ b/drivers/xen/xenbus/xenbus_probe_frontend.c @@ -135,7 +135,7 @@ static int read_backend_details(struct xenbus_device *xendev)  	return xenbus_read_otherend_details(xendev, "backend-id", "backend");  } -static int is_device_connecting(struct device *dev, void *data) +static int is_device_connecting(struct device *dev, void *data, bool ignore_nonessential)  {  	struct xenbus_device *xendev = to_xenbus_device(dev);  	struct device_driver *drv = data; @@ -152,16 +152,41 @@ static int is_device_connecting(struct device *dev, void *data)  	if (drv && (dev->driver != drv))  		return 0; +	if (ignore_nonessential) { +		/* With older QEMU, for PVonHVM guests the guest config files +		 * could contain: vfb = [ 'vnc=1, vnclisten=0.0.0.0'] +		 * which is nonsensical as there is no PV FB (there can be +		 * a PVKB) running as HVM guest. */ + +		if ((strncmp(xendev->nodename, "device/vkbd", 11) == 0)) +			return 0; + +		if ((strncmp(xendev->nodename, "device/vfb", 10) == 0)) +			return 0; +	}  	xendrv = to_xenbus_driver(dev->driver);  	return (xendev->state < XenbusStateConnected ||  		(xendev->state == XenbusStateConnected &&  		 xendrv->is_ready && !xendrv->is_ready(xendev)));  } +static int essential_device_connecting(struct device *dev, void *data) +{ +	return is_device_connecting(dev, data, true /* ignore PV[KBB+FB] */); +} +static int non_essential_device_connecting(struct device *dev, void *data) +{ +	return is_device_connecting(dev, data, false); +} -static int exists_connecting_device(struct device_driver *drv) +static int exists_essential_connecting_device(struct device_driver *drv) +{ +	return bus_for_each_dev(&xenbus_frontend.bus, NULL, drv, +				essential_device_connecting); +} +static int exists_non_essential_connecting_device(struct device_driver *drv)  {  	return bus_for_each_dev(&xenbus_frontend.bus, NULL, drv, -				is_device_connecting); +				non_essential_device_connecting);  }  static int print_device_status(struct device *dev, void *data) @@ -192,6 +217,23 @@ static int print_device_status(struct device *dev, void *data)  /* We only wait for device setup after most initcalls have run. */  static int ready_to_wait_for_devices; +static bool wait_loop(unsigned long start, unsigned int max_delay, +		     unsigned int *seconds_waited) +{ +	if (time_after(jiffies, start + (*seconds_waited+5)*HZ)) { +		if (!*seconds_waited) +			printk(KERN_WARNING "XENBUS: Waiting for " +			       "devices to initialise: "); +		*seconds_waited += 5; +		printk("%us...", max_delay - *seconds_waited); +		if (*seconds_waited == max_delay) +			return true; +	} + +	schedule_timeout_interruptible(HZ/10); + +	return false; +}  /*   * On a 5-minute timeout, wait for all devices currently configured.  We need   * to do this to guarantee that the filesystems and / or network devices @@ -215,19 +257,14 @@ static void wait_for_devices(struct xenbus_driver *xendrv)  	if (!ready_to_wait_for_devices || !xen_domain())  		return; -	while (exists_connecting_device(drv)) { -		if (time_after(jiffies, start + (seconds_waited+5)*HZ)) { -			if (!seconds_waited) -				printk(KERN_WARNING "XENBUS: Waiting for " -				       "devices to initialise: "); -			seconds_waited += 5; -			printk("%us...", 300 - seconds_waited); -			if (seconds_waited == 300) -				break; -		} +	while (exists_non_essential_connecting_device(drv)) +		if (wait_loop(start, 30, &seconds_waited)) +			break; -		schedule_timeout_interruptible(HZ/10); -	} +	/* Skips PVKB and PVFB check.*/ +	while (exists_essential_connecting_device(drv)) +		if (wait_loop(start, 270, &seconds_waited)) +			break;  	if (seconds_waited)  		printk("\n");  |