diff options
Diffstat (limited to 'drivers')
330 files changed, 2894 insertions, 1372 deletions
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index 9628652e080..e0596954290 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -237,6 +237,16 @@ static int __acpi_bus_get_power(struct acpi_device *device, int *state)  	} else if (result == ACPI_STATE_D3_HOT) {  		result = ACPI_STATE_D3;  	} + +	/* +	 * If we were unsure about the device parent's power state up to this +	 * point, the fact that the device is in D0 implies that the parent has +	 * to be in D0 too. +	 */ +	if (device->parent && device->parent->power.state == ACPI_STATE_UNKNOWN +	    && result == ACPI_STATE_D0) +		device->parent->power.state = ACPI_STATE_D0; +  	*state = result;   out: diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c index fc180341462..40e38a06ba8 100644 --- a/drivers/acpi/power.c +++ b/drivers/acpi/power.c @@ -107,6 +107,7 @@ struct acpi_power_resource {  	/* List of devices relying on this power resource */  	struct acpi_power_resource_device *devices; +	struct mutex devices_lock;  };  static struct list_head acpi_power_resource_list; @@ -225,7 +226,6 @@ static void acpi_power_on_device(struct acpi_power_managed_device *device)  static int __acpi_power_on(struct acpi_power_resource *resource)  { -	struct acpi_power_resource_device *device_list = resource->devices;  	acpi_status status = AE_OK;  	status = acpi_evaluate_object(resource->device->handle, "_ON", NULL, NULL); @@ -238,19 +238,15 @@ static int __acpi_power_on(struct acpi_power_resource *resource)  	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Power resource [%s] turned on\n",  			  resource->name)); -	while (device_list) { -		acpi_power_on_device(device_list->device); - -		device_list = device_list->next; -	} -  	return 0;  }  static int acpi_power_on(acpi_handle handle)  {  	int result = 0; +	bool resume_device = false;  	struct acpi_power_resource *resource = NULL; +	struct acpi_power_resource_device *device_list;  	result = acpi_power_get_context(handle, &resource);  	if (result) @@ -266,10 +262,25 @@ static int acpi_power_on(acpi_handle handle)  		result = __acpi_power_on(resource);  		if (result)  			resource->ref_count--; +		else +			resume_device = true;  	}  	mutex_unlock(&resource->resource_lock); +	if (!resume_device) +		return result; + +	mutex_lock(&resource->devices_lock); + +	device_list = resource->devices; +	while (device_list) { +		acpi_power_on_device(device_list->device); +		device_list = device_list->next; +	} + +	mutex_unlock(&resource->devices_lock); +  	return result;  } @@ -355,7 +366,7 @@ static void __acpi_power_resource_unregister_device(struct device *dev,  	if (acpi_power_get_context(res_handle, &resource))  		return; -	mutex_lock(&resource->resource_lock); +	mutex_lock(&resource->devices_lock);  	prev = NULL;  	curr = resource->devices;  	while (curr) { @@ -372,7 +383,7 @@ static void __acpi_power_resource_unregister_device(struct device *dev,  		prev = curr;  		curr = curr->next;  	} -	mutex_unlock(&resource->resource_lock); +	mutex_unlock(&resource->devices_lock);  }  /* Unlink dev from all power resources in _PR0 */ @@ -414,10 +425,10 @@ static int __acpi_power_resource_register_device(  	power_resource_device->device = powered_device; -	mutex_lock(&resource->resource_lock); +	mutex_lock(&resource->devices_lock);  	power_resource_device->next = resource->devices;  	resource->devices = power_resource_device; -	mutex_unlock(&resource->resource_lock); +	mutex_unlock(&resource->devices_lock);  	return 0;  } @@ -462,7 +473,7 @@ int acpi_power_resource_register_device(struct device *dev, acpi_handle handle)  	return ret;  no_power_resource: -	printk(KERN_WARNING PREFIX "Invalid Power Resource to register!"); +	printk(KERN_DEBUG PREFIX "Invalid Power Resource to register!");  	return -ENODEV;  }  EXPORT_SYMBOL_GPL(acpi_power_resource_register_device); @@ -721,6 +732,7 @@ static int acpi_power_add(struct acpi_device *device)  	resource->device = device;  	mutex_init(&resource->resource_lock); +	mutex_init(&resource->devices_lock);  	strcpy(resource->name, device->pnp.bus_id);  	strcpy(acpi_device_name(device), ACPI_POWER_DEVICE_NAME);  	strcpy(acpi_device_class(device), ACPI_POWER_CLASS); diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index 2be8ef1d309..27cecd313e7 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -115,7 +115,7 @@ config SATA_SIL24  	  If unsure, say N.  config ATA_SFF -	bool "ATA SFF support" +	bool "ATA SFF support (for legacy IDE and PATA)"  	default y  	help  	  This option adds support for ATA controllers with SFF diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 062e6a1a248..7862d17976b 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -256,10 +256,21 @@ static const struct pci_device_id ahci_pci_tbl[] = {  	{ PCI_VDEVICE(INTEL, 0x8c07), board_ahci }, /* Lynx Point RAID */  	{ PCI_VDEVICE(INTEL, 0x8c0e), board_ahci }, /* Lynx Point RAID */  	{ PCI_VDEVICE(INTEL, 0x8c0f), board_ahci }, /* Lynx Point RAID */ +	{ PCI_VDEVICE(INTEL, 0x9c02), board_ahci }, /* Lynx Point-LP AHCI */ +	{ PCI_VDEVICE(INTEL, 0x9c03), board_ahci }, /* Lynx Point-LP AHCI */ +	{ PCI_VDEVICE(INTEL, 0x9c04), board_ahci }, /* Lynx Point-LP RAID */ +	{ PCI_VDEVICE(INTEL, 0x9c05), board_ahci }, /* Lynx Point-LP RAID */ +	{ PCI_VDEVICE(INTEL, 0x9c06), board_ahci }, /* Lynx Point-LP RAID */ +	{ PCI_VDEVICE(INTEL, 0x9c07), board_ahci }, /* Lynx Point-LP RAID */ +	{ PCI_VDEVICE(INTEL, 0x9c0e), board_ahci }, /* Lynx Point-LP RAID */ +	{ PCI_VDEVICE(INTEL, 0x9c0f), board_ahci }, /* Lynx Point-LP RAID */  	/* JMicron 360/1/3/5/6, match class to avoid IDE function */  	{ PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,  	  PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff, board_ahci_ign_iferr }, +	/* JMicron 362B and 362C have an AHCI function with IDE class code */ +	{ PCI_VDEVICE(JMICRON, 0x2362), board_ahci_ign_iferr }, +	{ PCI_VDEVICE(JMICRON, 0x236f), board_ahci_ign_iferr },  	/* ATI */  	{ PCI_VDEVICE(ATI, 0x4380), board_ahci_sb600 }, /* ATI SB600 */ @@ -385,6 +396,8 @@ static const struct pci_device_id ahci_pci_tbl[] = {  	  .driver_data = board_ahci_yes_fbs },			/* 88se9125 */  	{ PCI_DEVICE(0x1b4b, 0x917a),  	  .driver_data = board_ahci_yes_fbs },			/* 88se9172 */ +	{ PCI_DEVICE(0x1b4b, 0x9192), +	  .driver_data = board_ahci_yes_fbs },			/* 88se9172 on some Gigabyte */  	{ PCI_DEVICE(0x1b4b, 0x91a3),  	  .driver_data = board_ahci_yes_fbs }, @@ -392,7 +405,10 @@ static const struct pci_device_id ahci_pci_tbl[] = {  	{ PCI_VDEVICE(PROMISE, 0x3f20), board_ahci },	/* PDC42819 */  	/* Asmedia */ -	{ PCI_VDEVICE(ASMEDIA, 0x0612), board_ahci },	/* ASM1061 */ +	{ PCI_VDEVICE(ASMEDIA, 0x0601), board_ahci },	/* ASM1060 */ +	{ PCI_VDEVICE(ASMEDIA, 0x0602), board_ahci },	/* ASM1060 */ +	{ PCI_VDEVICE(ASMEDIA, 0x0611), board_ahci },	/* ASM1061 */ +	{ PCI_VDEVICE(ASMEDIA, 0x0612), board_ahci },	/* ASM1062 */  	/* Generic, PCI class code for AHCI */  	{ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h index c2594ddf25b..57eb1c212a4 100644 --- a/drivers/ata/ahci.h +++ b/drivers/ata/ahci.h @@ -320,6 +320,7 @@ extern struct device_attribute *ahci_sdev_attrs[];  extern struct ata_port_operations ahci_ops;  extern struct ata_port_operations ahci_pmp_retry_srst_ops; +unsigned int ahci_dev_classify(struct ata_port *ap);  void ahci_fill_cmd_slot(struct ahci_port_priv *pp, unsigned int tag,  			u32 opts);  void ahci_save_initial_config(struct device *dev, diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index 3c809bfbccf..ef773e12af7 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c @@ -329,6 +329,14 @@ 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 (Lynx Point-LP) */ +	{ 0x8086, 0x9c00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb }, +	/* SATA Controller IDE (Lynx Point-LP) */ +	{ 0x8086, 0x9c01, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb }, +	/* SATA Controller IDE (Lynx Point-LP) */ +	{ 0x8086, 0x9c08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, +	/* SATA Controller IDE (Lynx Point-LP) */ +	{ 0x8086, 0x9c09, 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/libahci.c b/drivers/ata/libahci.c index f9eaa82311a..555c07afa05 100644 --- a/drivers/ata/libahci.c +++ b/drivers/ata/libahci.c @@ -1139,7 +1139,7 @@ static void ahci_dev_config(struct ata_device *dev)  	}  } -static unsigned int ahci_dev_classify(struct ata_port *ap) +unsigned int ahci_dev_classify(struct ata_port *ap)  {  	void __iomem *port_mmio = ahci_port_base(ap);  	struct ata_taskfile tf; @@ -1153,6 +1153,7 @@ static unsigned int ahci_dev_classify(struct ata_port *ap)  	return ata_dev_classify(&tf);  } +EXPORT_SYMBOL_GPL(ahci_dev_classify);  void ahci_fill_cmd_slot(struct ahci_port_priv *pp, unsigned int tag,  			u32 opts) diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c index 902b5a45717..fd9ecf74e63 100644 --- a/drivers/ata/libata-acpi.c +++ b/drivers/ata/libata-acpi.c @@ -60,17 +60,7 @@ acpi_handle ata_ap_acpi_handle(struct ata_port *ap)  	if (ap->flags & ATA_FLAG_ACPI_SATA)  		return NULL; -	/* -	 * If acpi bind operation has already happened, we can get the handle -	 * for the port by checking the corresponding scsi_host device's -	 * firmware node, otherwise we will need to find out the handle from -	 * its parent's acpi node. -	 */ -	if (ap->scsi_host) -		return DEVICE_ACPI_HANDLE(&ap->scsi_host->shost_gendev); -	else -		return acpi_get_child(DEVICE_ACPI_HANDLE(ap->host->dev), -				ap->port_no); +	return acpi_get_child(DEVICE_ACPI_HANDLE(ap->host->dev), ap->port_no);  }  EXPORT_SYMBOL(ata_ap_acpi_handle); @@ -1101,6 +1091,9 @@ static int ata_acpi_bind_host(struct ata_port *ap, acpi_handle *handle)  	if (!*handle)  		return -ENODEV; +	if (ata_acpi_gtm(ap, &ap->__acpi_init_gtm) == 0) +		ap->pflags |= ATA_PFLAG_INIT_GTM_VALID; +  	return 0;  } diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index fadd5866d40..8e1039c8e15 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -4062,7 +4062,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {  	{ "_NEC DV5800A", 	NULL,		ATA_HORKAGE_NODMA },  	{ "SAMSUNG CD-ROM SN-124", "N001",	ATA_HORKAGE_NODMA },  	{ "Seagate STT20000A", NULL,		ATA_HORKAGE_NODMA }, -	{ "2GB ATA Flash Disk", "ADMA428M",	ATA_HORKAGE_NODMA }, +	{ " 2GB ATA Flash Disk", "ADMA428M",	ATA_HORKAGE_NODMA },  	/* Odd clown on sil3726/4726 PMPs */  	{ "Config  Disk",	NULL,		ATA_HORKAGE_DISABLE }, @@ -4128,6 +4128,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {  	/* Devices that do not need bridging limits applied */  	{ "MTRON MSP-SATA*",		NULL,	ATA_HORKAGE_BRIDGE_OK, }, +	{ "BUFFALO HD-QSU2/R5",		NULL,	ATA_HORKAGE_BRIDGE_OK, },  	/* Devices which aren't very happy with higher link speeds */  	{ "WD My Book",			NULL,	ATA_HORKAGE_1_5_GBPS, }, diff --git a/drivers/ata/pata_atiixp.c b/drivers/ata/pata_atiixp.c index 361c75cea57..24e51056ac2 100644 --- a/drivers/ata/pata_atiixp.c +++ b/drivers/ata/pata_atiixp.c @@ -20,6 +20,7 @@  #include <linux/delay.h>  #include <scsi/scsi_host.h>  #include <linux/libata.h> +#include <linux/dmi.h>  #define DRV_NAME "pata_atiixp"  #define DRV_VERSION "0.4.6" @@ -33,11 +34,26 @@ enum {  	ATIIXP_IDE_UDMA_MODE 	= 0x56  }; +static const struct dmi_system_id attixp_cable_override_dmi_table[] = { +	{ +		/* Board has onboard PATA<->SATA converters */ +		.ident = "MSI E350DM-E33", +		.matches = { +			DMI_MATCH(DMI_BOARD_VENDOR, "MSI"), +			DMI_MATCH(DMI_BOARD_NAME, "E350DM-E33(MS-7720)"), +		}, +	}, +	{ } +}; +  static int atiixp_cable_detect(struct ata_port *ap)  {  	struct pci_dev *pdev = to_pci_dev(ap->host->dev);  	u8 udma; +	if (dmi_check_system(attixp_cable_override_dmi_table)) +		return ATA_CBL_PATA40_SHORT; +  	/* Hack from drivers/ide/pci. Really we want to know how to do the  	   raw detection not play follow the bios mode guess */  	pci_read_config_byte(pdev, ATIIXP_IDE_UDMA_MODE + ap->port_no, &udma); diff --git a/drivers/base/dma-contiguous.c b/drivers/base/dma-contiguous.c index 78efb0306a4..34d94c762a1 100644 --- a/drivers/base/dma-contiguous.c +++ b/drivers/base/dma-contiguous.c @@ -250,7 +250,7 @@ int __init dma_declare_contiguous(struct device *dev, unsigned long size,  		return -EINVAL;  	/* Sanitise input arguments */ -	alignment = PAGE_SIZE << max(MAX_ORDER, pageblock_order); +	alignment = PAGE_SIZE << max(MAX_ORDER - 1, pageblock_order);  	base = ALIGN(base, alignment);  	size = ALIGN(size, alignment);  	limit &= ~(alignment - 1); diff --git a/drivers/block/drbd/drbd_bitmap.c b/drivers/block/drbd/drbd_bitmap.c index ba91b408aba..d8456649674 100644 --- a/drivers/block/drbd/drbd_bitmap.c +++ b/drivers/block/drbd/drbd_bitmap.c @@ -889,6 +889,7 @@ struct bm_aio_ctx {  	unsigned int done;  	unsigned flags;  #define BM_AIO_COPY_PAGES	1 +#define BM_WRITE_ALL_PAGES	2  	int error;  	struct kref kref;  }; @@ -1059,7 +1060,8 @@ static int bm_rw(struct drbd_conf *mdev, int rw, unsigned flags, unsigned lazy_w  		if (lazy_writeout_upper_idx && i == lazy_writeout_upper_idx)  			break;  		if (rw & WRITE) { -			if (bm_test_page_unchanged(b->bm_pages[i])) { +			if (!(flags & BM_WRITE_ALL_PAGES) && +			    bm_test_page_unchanged(b->bm_pages[i])) {  				dynamic_dev_dbg(DEV, "skipped bm write for idx %u\n", i);  				continue;  			} @@ -1141,6 +1143,17 @@ int drbd_bm_write(struct drbd_conf *mdev) __must_hold(local)  }  /** + * drbd_bm_write_all() - Write the whole bitmap to its on disk location. + * @mdev:	DRBD device. + * + * Will write all pages. + */ +int drbd_bm_write_all(struct drbd_conf *mdev) __must_hold(local) +{ +	return bm_rw(mdev, WRITE, BM_WRITE_ALL_PAGES, 0); +} + +/**   * drbd_bm_lazy_write_out() - Write bitmap pages 0 to @upper_idx-1, if they have changed.   * @mdev:	DRBD device.   * @upper_idx:	0: write all changed pages; +ve: page index to stop scanning for changed pages diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h index b2ca143d005..b953cc7c9c0 100644 --- a/drivers/block/drbd/drbd_int.h +++ b/drivers/block/drbd/drbd_int.h @@ -1469,6 +1469,7 @@ extern int  drbd_bm_e_weight(struct drbd_conf *mdev, unsigned long enr);  extern int  drbd_bm_write_page(struct drbd_conf *mdev, unsigned int idx) __must_hold(local);  extern int  drbd_bm_read(struct drbd_conf *mdev) __must_hold(local);  extern int  drbd_bm_write(struct drbd_conf *mdev) __must_hold(local); +extern int drbd_bm_write_all(struct drbd_conf *mdev) __must_hold(local);  extern int  drbd_bm_write_copy_pages(struct drbd_conf *mdev) __must_hold(local);  extern unsigned long drbd_bm_ALe_set_all(struct drbd_conf *mdev,  		unsigned long al_enr); diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index dbe6135a2ab..f93a0320e95 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c @@ -79,6 +79,7 @@ static int w_md_sync(struct drbd_conf *mdev, struct drbd_work *w, int unused);  static void md_sync_timer_fn(unsigned long data);  static int w_bitmap_io(struct drbd_conf *mdev, struct drbd_work *w, int unused);  static int w_go_diskless(struct drbd_conf *mdev, struct drbd_work *w, int unused); +static void _tl_clear(struct drbd_conf *mdev);  MODULE_AUTHOR("Philipp Reisner <phil@linbit.com>, "  	      "Lars Ellenberg <lars@linbit.com>"); @@ -432,19 +433,10 @@ static void _tl_restart(struct drbd_conf *mdev, enum drbd_req_event what)  	/* Actions operating on the disk state, also want to work on  	   requests that got barrier acked. */ -	switch (what) { -	case fail_frozen_disk_io: -	case restart_frozen_disk_io: -		list_for_each_safe(le, tle, &mdev->barrier_acked_requests) { -			req = list_entry(le, struct drbd_request, tl_requests); -			_req_mod(req, what); -		} -	case connection_lost_while_pending: -	case resend: -		break; -	default: -		dev_err(DEV, "what = %d in _tl_restart()\n", what); +	list_for_each_safe(le, tle, &mdev->barrier_acked_requests) { +		req = list_entry(le, struct drbd_request, tl_requests); +		_req_mod(req, what);  	}  } @@ -459,11 +451,16 @@ static void _tl_restart(struct drbd_conf *mdev, enum drbd_req_event what)   */  void tl_clear(struct drbd_conf *mdev)  { +	spin_lock_irq(&mdev->req_lock); +	_tl_clear(mdev); +	spin_unlock_irq(&mdev->req_lock); +} + +static void _tl_clear(struct drbd_conf *mdev) +{  	struct list_head *le, *tle;  	struct drbd_request *r; -	spin_lock_irq(&mdev->req_lock); -  	_tl_restart(mdev, connection_lost_while_pending);  	/* we expect this list to be empty. */ @@ -482,7 +479,6 @@ void tl_clear(struct drbd_conf *mdev)  	memset(mdev->app_reads_hash, 0, APP_R_HSIZE*sizeof(void *)); -	spin_unlock_irq(&mdev->req_lock);  }  void tl_restart(struct drbd_conf *mdev, enum drbd_req_event what) @@ -1476,12 +1472,12 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os,  	if (ns.susp_fen) {  		/* case1: The outdate peer handler is successful: */  		if (os.pdsk > D_OUTDATED  && ns.pdsk <= D_OUTDATED) { -			tl_clear(mdev);  			if (test_bit(NEW_CUR_UUID, &mdev->flags)) {  				drbd_uuid_new_current(mdev);  				clear_bit(NEW_CUR_UUID, &mdev->flags);  			}  			spin_lock_irq(&mdev->req_lock); +			_tl_clear(mdev);  			_drbd_set_state(_NS(mdev, susp_fen, 0), CS_VERBOSE, NULL);  			spin_unlock_irq(&mdev->req_lock);  		} diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c index fb9dce8daa2..edb490aad8b 100644 --- a/drivers/block/drbd/drbd_nl.c +++ b/drivers/block/drbd/drbd_nl.c @@ -674,8 +674,8 @@ enum determine_dev_size drbd_determine_dev_size(struct drbd_conf *mdev, enum dds  			 la_size_changed && md_moved ? "size changed and md moved" :  			 la_size_changed ? "size changed" : "md moved");  		/* next line implicitly does drbd_suspend_io()+drbd_resume_io() */ -		err = drbd_bitmap_io(mdev, &drbd_bm_write, -				"size changed", BM_LOCKED_MASK); +		err = drbd_bitmap_io(mdev, md_moved ? &drbd_bm_write_all : &drbd_bm_write, +				     "size changed", BM_LOCKED_MASK);  		if (err) {  			rv = dev_size_error;  			goto out; diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c index 910335c3092..01b2ac641c7 100644 --- a/drivers/block/drbd/drbd_req.c +++ b/drivers/block/drbd/drbd_req.c @@ -695,6 +695,12 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what,  		break;  	case resend: +		/* Simply complete (local only) READs. */ +		if (!(req->rq_state & RQ_WRITE) && !req->w.cb) { +			_req_may_be_done(req, m); +			break; +		} +  		/* If RQ_NET_OK is already set, we got a P_WRITE_ACK or P_RECV_ACK  		   before the connection loss (B&C only); only P_BARRIER_ACK was missing.  		   Trowing them out of the TL here by pretending we got a BARRIER_ACK @@ -834,7 +840,15 @@ static int drbd_make_request_common(struct drbd_conf *mdev, struct bio *bio, uns  		req->private_bio = NULL;  	}  	if (rw == WRITE) { -		remote = 1; +		/* Need to replicate writes.  Unless it is an empty flush, +		 * which is better mapped to a DRBD P_BARRIER packet, +		 * also for drbd wire protocol compatibility reasons. */ +		if (unlikely(size == 0)) { +			/* The only size==0 bios we expect are empty flushes. */ +			D_ASSERT(bio->bi_rw & REQ_FLUSH); +			remote = 0; +		} else +			remote = 1;  	} else {  		/* READ || READA */  		if (local) { @@ -870,8 +884,11 @@ static int drbd_make_request_common(struct drbd_conf *mdev, struct bio *bio, uns  	 * extent.  This waits for any resync activity in the corresponding  	 * resync extent to finish, and, if necessary, pulls in the target  	 * extent into the activity log, which involves further disk io because -	 * of transactional on-disk meta data updates. */ -	if (rw == WRITE && local && !test_bit(AL_SUSPENDED, &mdev->flags)) { +	 * of transactional on-disk meta data updates. +	 * Empty flushes don't need to go into the activity log, they can only +	 * flush data for pending writes which are already in there. */ +	if (rw == WRITE && local && size +	&& !test_bit(AL_SUSPENDED, &mdev->flags)) {  		req->rq_state |= RQ_IN_ACT_LOG;  		drbd_al_begin_io(mdev, sector);  	} @@ -994,7 +1011,10 @@ allocate_barrier:  	if (rw == WRITE && _req_conflicts(req))  		goto fail_conflicting; -	list_add_tail(&req->tl_requests, &mdev->newest_tle->requests); +	/* no point in adding empty flushes to the transfer log, +	 * they are mapped to drbd barriers already. */ +	if (likely(size!=0)) +		list_add_tail(&req->tl_requests, &mdev->newest_tle->requests);  	/* NOTE remote first: to get the concurrent write detection right,  	 * we must register the request before start of local IO.  */ @@ -1014,6 +1034,14 @@ allocate_barrier:  	    mdev->net_conf->on_congestion != OC_BLOCK && mdev->agreed_pro_version >= 96)  		maybe_pull_ahead(mdev); +	/* If this was a flush, queue a drbd barrier/start a new epoch. +	 * Unless the current epoch was empty anyways, or we are not currently +	 * replicating, in which case there is no point. */ +	if (unlikely(bio->bi_rw & REQ_FLUSH) +		&& mdev->newest_tle->n_writes +		&& drbd_should_do_remote(mdev->state)) +		queue_barrier(mdev); +  	spin_unlock_irq(&mdev->req_lock);  	kfree(b); /* if someone else has beaten us to it... */ diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c index 11f36e50213..fc2de5528dc 100644 --- a/drivers/bluetooth/ath3k.c +++ b/drivers/bluetooth/ath3k.c @@ -86,6 +86,7 @@ static struct usb_device_id ath3k_table[] = {  	/* Atheros AR5BBU22 with sflash firmware */  	{ USB_DEVICE(0x0489, 0xE03C) }, +	{ USB_DEVICE(0x0489, 0xE036) },  	{ }	/* Terminating entry */  }; @@ -109,6 +110,7 @@ static struct usb_device_id ath3k_blist_tbl[] = {  	/* Atheros AR5BBU22 with sflash firmware */  	{ USB_DEVICE(0x0489, 0xE03C), .driver_info = BTUSB_ATH3012 }, +	{ USB_DEVICE(0x0489, 0xE036), .driver_info = BTUSB_ATH3012 },  	{ }	/* Terminating entry */  }; diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index cef3bac1a54..654e248763e 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -52,6 +52,9 @@ static struct usb_device_id btusb_table[] = {  	/* Generic Bluetooth USB device */  	{ USB_DEVICE_INFO(0xe0, 0x01, 0x01) }, +	/* Apple-specific (Broadcom) devices */ +	{ USB_VENDOR_AND_INTERFACE_INFO(0x05ac, 0xff, 0x01, 0x01) }, +  	/* Broadcom SoftSailing reporting vendor specific */  	{ USB_DEVICE(0x0a5c, 0x21e1) }, @@ -94,16 +97,14 @@ static struct usb_device_id btusb_table[] = {  	/* Broadcom BCM20702A0 */  	{ USB_DEVICE(0x0489, 0xe042) }, -	{ USB_DEVICE(0x0a5c, 0x21e3) }, -	{ USB_DEVICE(0x0a5c, 0x21e6) }, -	{ USB_DEVICE(0x0a5c, 0x21e8) }, -	{ USB_DEVICE(0x0a5c, 0x21f3) }, -	{ USB_DEVICE(0x0a5c, 0x21f4) },  	{ USB_DEVICE(0x413c, 0x8197) },  	/* Foxconn - Hon Hai */  	{ USB_DEVICE(0x0489, 0xe033) }, +	/*Broadcom devices with vendor specific id */ +	{ USB_VENDOR_AND_INTERFACE_INFO(0x0a5c, 0xff, 0x01, 0x01) }, +  	{ }	/* Terminating entry */  }; @@ -141,6 +142,7 @@ static struct usb_device_id blacklist_table[] = {  	/* Atheros AR5BBU12 with sflash firmware */  	{ USB_DEVICE(0x0489, 0xe03c), .driver_info = BTUSB_ATH3012 }, +	{ USB_DEVICE(0x0489, 0xe036), .driver_info = BTUSB_ATH3012 },  	/* Broadcom BCM2035 */  	{ USB_DEVICE(0x0a5c, 0x2035), .driver_info = BTUSB_WRONG_SCO_MTU }, diff --git a/drivers/cpufreq/omap-cpufreq.c b/drivers/cpufreq/omap-cpufreq.c index 17fa04d08be..b47034e650a 100644 --- a/drivers/cpufreq/omap-cpufreq.c +++ b/drivers/cpufreq/omap-cpufreq.c @@ -218,7 +218,7 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)  	policy->cur = policy->min = policy->max = omap_getspeed(policy->cpu); -	if (atomic_inc_return(&freq_table_users) == 1) +	if (!freq_table)  		result = opp_init_cpufreq_table(mpu_dev, &freq_table);  	if (result) { @@ -227,6 +227,8 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)  		goto fail_ck;  	} +	atomic_inc_return(&freq_table_users); +  	result = cpufreq_frequency_table_cpuinfo(policy, freq_table);  	if (result)  		goto fail_table; diff --git a/drivers/crypto/caam/jr.c b/drivers/crypto/caam/jr.c index 53c8c51d588..93d14070141 100644 --- a/drivers/crypto/caam/jr.c +++ b/drivers/crypto/caam/jr.c @@ -63,7 +63,7 @@ static void caam_jr_dequeue(unsigned long devarg)  		head = ACCESS_ONCE(jrp->head); -		spin_lock_bh(&jrp->outlock); +		spin_lock(&jrp->outlock);  		sw_idx = tail = jrp->tail;  		hw_idx = jrp->out_ring_read_index; @@ -115,7 +115,7 @@ static void caam_jr_dequeue(unsigned long devarg)  			jrp->tail = tail;  		} -		spin_unlock_bh(&jrp->outlock); +		spin_unlock(&jrp->outlock);  		/* Finally, execute user's callback */  		usercall(dev, userdesc, userstatus, userarg); @@ -236,14 +236,14 @@ int caam_jr_enqueue(struct device *dev, u32 *desc,  		return -EIO;  	} -	spin_lock(&jrp->inplock); +	spin_lock_bh(&jrp->inplock);  	head = jrp->head;  	tail = ACCESS_ONCE(jrp->tail);  	if (!rd_reg32(&jrp->rregs->inpring_avail) ||  	    CIRC_SPACE(head, tail, JOBR_DEPTH) <= 0) { -		spin_unlock(&jrp->inplock); +		spin_unlock_bh(&jrp->inplock);  		dma_unmap_single(dev, desc_dma, desc_size, DMA_TO_DEVICE);  		return -EBUSY;  	} @@ -265,7 +265,7 @@ int caam_jr_enqueue(struct device *dev, u32 *desc,  	wr_reg32(&jrp->rregs->inpring_jobadd, 1); -	spin_unlock(&jrp->inplock); +	spin_unlock_bh(&jrp->inplock);  	return 0;  } diff --git a/drivers/crypto/caam/key_gen.c b/drivers/crypto/caam/key_gen.c index 002888185f1..d216cd3cc56 100644 --- a/drivers/crypto/caam/key_gen.c +++ b/drivers/crypto/caam/key_gen.c @@ -120,3 +120,4 @@ u32 gen_split_key(struct device *jrdev, u8 *key_out, int split_key_len,  	return ret;  } +EXPORT_SYMBOL(gen_split_key); diff --git a/drivers/crypto/hifn_795x.c b/drivers/crypto/hifn_795x.c index c9c4befb5a8..df14358d7fa 100644 --- a/drivers/crypto/hifn_795x.c +++ b/drivers/crypto/hifn_795x.c @@ -821,8 +821,8 @@ static int hifn_register_rng(struct hifn_device *dev)  	/*  	 * We must wait at least 256 Pk_clk cycles between two reads of the rng.  	 */ -	dev->rng_wait_time	= DIV_ROUND_UP(NSEC_PER_SEC, dev->pk_clk_freq) * -				  256; +	dev->rng_wait_time	= DIV_ROUND_UP_ULL(NSEC_PER_SEC, +						   dev->pk_clk_freq) * 256;  	dev->rng.name		= dev->name;  	dev->rng.data_present	= hifn_rng_data_present, diff --git a/drivers/extcon/extcon-max77693.c b/drivers/extcon/extcon-max77693.c index 920a609b2c3..38f9e52f358 100644 --- a/drivers/extcon/extcon-max77693.c +++ b/drivers/extcon/extcon-max77693.c @@ -669,13 +669,18 @@ static int __devinit max77693_muic_probe(struct platform_device *pdev)  	}  	info->dev = &pdev->dev;  	info->max77693 = max77693; -	info->max77693->regmap_muic = regmap_init_i2c(info->max77693->muic, -					 &max77693_muic_regmap_config); -	if (IS_ERR(info->max77693->regmap_muic)) { -		ret = PTR_ERR(info->max77693->regmap_muic); -		dev_err(max77693->dev, -			"failed to allocate register map: %d\n", ret); -		goto err_regmap; +	if (info->max77693->regmap_muic) +		dev_dbg(&pdev->dev, "allocate register map\n"); +	else { +		info->max77693->regmap_muic = devm_regmap_init_i2c( +						info->max77693->muic, +						&max77693_muic_regmap_config); +		if (IS_ERR(info->max77693->regmap_muic)) { +			ret = PTR_ERR(info->max77693->regmap_muic); +			dev_err(max77693->dev, +				"failed to allocate register map: %d\n", ret); +			goto err_regmap; +		}  	}  	platform_set_drvdata(pdev, info);  	mutex_init(&info->mutex); diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index b16c8a72a2e..ba7926f5c09 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -294,7 +294,7 @@ config GPIO_MAX732X_IRQ  config GPIO_MC9S08DZ60  	bool "MX35 3DS BOARD MC9S08DZ60 GPIO functions" -	depends on I2C && MACH_MX35_3DS +	depends on I2C=y && MACH_MX35_3DS  	help  	  Select this to enable the MC9S08DZ60 GPIO driver diff --git a/drivers/gpio/gpio-em.c b/drivers/gpio/gpio-em.c index ae37181798b..ec48ed51262 100644 --- a/drivers/gpio/gpio-em.c +++ b/drivers/gpio/gpio-em.c @@ -247,9 +247,9 @@ static int __devinit em_gio_irq_domain_init(struct em_gio_priv *p)  	p->irq_base = irq_alloc_descs(pdata->irq_base, 0,  				      pdata->number_of_pins, numa_node_id()); -	if (IS_ERR_VALUE(p->irq_base)) { +	if (p->irq_base < 0) {  		dev_err(&pdev->dev, "cannot get irq_desc\n"); -		return -ENXIO; +		return p->irq_base;  	}  	pr_debug("gio: hw base = %d, nr = %d, sw base = %d\n",  		 pdata->gpio_base, pdata->number_of_pins, p->irq_base); diff --git a/drivers/gpio/gpio-rdc321x.c b/drivers/gpio/gpio-rdc321x.c index e97016af644..b62d443e9a5 100644 --- a/drivers/gpio/gpio-rdc321x.c +++ b/drivers/gpio/gpio-rdc321x.c @@ -170,6 +170,7 @@ static int __devinit rdc321x_gpio_probe(struct platform_device *pdev)  	rdc321x_gpio_dev->reg2_data_base = r->start + 0x4;  	rdc321x_gpio_dev->chip.label = "rdc321x-gpio"; +	rdc321x_gpio_dev->chip.owner = THIS_MODULE;  	rdc321x_gpio_dev->chip.direction_input = rdc_gpio_direction_input;  	rdc321x_gpio_dev->chip.direction_output = rdc_gpio_config;  	rdc321x_gpio_dev->chip.get = rdc_gpio_get_value; diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c index a18c4aa68b1..f1a45997aea 100644 --- a/drivers/gpio/gpiolib-of.c +++ b/drivers/gpio/gpiolib-of.c @@ -82,7 +82,7 @@ int of_get_named_gpio_flags(struct device_node *np, const char *propname,  	gpiochip_find(&gg_data, of_gpiochip_find_and_xlate);  	of_node_put(gg_data.gpiospec.np); -	pr_debug("%s exited with status %d\n", __func__, ret); +	pr_debug("%s exited with status %d\n", __func__, gg_data.out_gpio);  	return gg_data.out_gpio;  }  EXPORT_SYMBOL(of_get_named_gpio_flags); diff --git a/drivers/gpu/drm/ast/ast_drv.c b/drivers/gpu/drm/ast/ast_drv.c index d0c4574ef49..36164806b9d 100644 --- a/drivers/gpu/drm/ast/ast_drv.c +++ b/drivers/gpu/drm/ast/ast_drv.c @@ -193,6 +193,9 @@ static const struct file_operations ast_fops = {  	.mmap = ast_mmap,  	.poll = drm_poll,  	.fasync = drm_fasync, +#ifdef CONFIG_COMPAT +	.compat_ioctl = drm_compat_ioctl, +#endif  	.read = drm_read,  }; diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c index 7282c081fb5..a712cafcfa1 100644 --- a/drivers/gpu/drm/ast/ast_mode.c +++ b/drivers/gpu/drm/ast/ast_mode.c @@ -841,7 +841,7 @@ int ast_cursor_init(struct drm_device *dev)  	ast->cursor_cache = obj;  	ast->cursor_cache_gpu_addr = gpu_addr; -	DRM_ERROR("pinned cursor cache at %llx\n", ast->cursor_cache_gpu_addr); +	DRM_DEBUG_KMS("pinned cursor cache at %llx\n", ast->cursor_cache_gpu_addr);  	return 0;  fail:  	return ret; diff --git a/drivers/gpu/drm/cirrus/cirrus_drv.c b/drivers/gpu/drm/cirrus/cirrus_drv.c index 7053140c659..b83a2d7ddd1 100644 --- a/drivers/gpu/drm/cirrus/cirrus_drv.c +++ b/drivers/gpu/drm/cirrus/cirrus_drv.c @@ -74,6 +74,9 @@ static const struct file_operations cirrus_driver_fops = {  	.unlocked_ioctl = drm_ioctl,  	.mmap = cirrus_mmap,  	.poll = drm_poll, +#ifdef CONFIG_COMPAT +	.compat_ioctl = drm_compat_ioctl, +#endif  	.fasync = drm_fasync,  };  static struct drm_driver driver = { diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 08a7aa722d6..6fbfc244748 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -1981,7 +1981,7 @@ int drm_mode_cursor_ioctl(struct drm_device *dev,  	if (!drm_core_check_feature(dev, DRIVER_MODESET))  		return -EINVAL; -	if (!req->flags) +	if (!req->flags || (~DRM_MODE_CURSOR_FLAGS & req->flags))  		return -EINVAL;  	mutex_lock(&dev->mode_config.mutex); diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index a8743c399e8..b7ee230572b 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -87,6 +87,9 @@ static struct edid_quirk {  	int product_id;  	u32 quirks;  } edid_quirk_list[] = { +	/* ASUS VW222S */ +	{ "ACI", 0x22a2, EDID_QUIRK_FORCE_REDUCED_BLANKING }, +  	/* Acer AL1706 */  	{ "ACR", 44358, EDID_QUIRK_PREFER_LARGE_60 },  	/* Acer F51 */ diff --git a/drivers/gpu/drm/exynos/Kconfig b/drivers/gpu/drm/exynos/Kconfig index 7f5096763b7..59a26e577b5 100644 --- a/drivers/gpu/drm/exynos/Kconfig +++ b/drivers/gpu/drm/exynos/Kconfig @@ -36,6 +36,6 @@ config DRM_EXYNOS_VIDI  config DRM_EXYNOS_G2D  	bool "Exynos DRM G2D" -	depends on DRM_EXYNOS +	depends on DRM_EXYNOS && !VIDEO_SAMSUNG_S5P_G2D  	help  	  Choose this option if you want to use Exynos G2D for DRM. diff --git a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c index 613bf8a5d9b..ae13febe0ea 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c +++ b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c @@ -163,6 +163,12 @@ static void exynos_gem_dmabuf_kunmap(struct dma_buf *dma_buf,  	/* TODO */  } +static int exynos_gem_dmabuf_mmap(struct dma_buf *dma_buf, +	struct vm_area_struct *vma) +{ +	return -ENOTTY; +} +  static struct dma_buf_ops exynos_dmabuf_ops = {  	.map_dma_buf		= exynos_gem_map_dma_buf,  	.unmap_dma_buf		= exynos_gem_unmap_dma_buf, @@ -170,6 +176,7 @@ static struct dma_buf_ops exynos_dmabuf_ops = {  	.kmap_atomic		= exynos_gem_dmabuf_kmap_atomic,  	.kunmap			= exynos_gem_dmabuf_kunmap,  	.kunmap_atomic		= exynos_gem_dmabuf_kunmap_atomic, +	.mmap			= exynos_gem_dmabuf_mmap,  	.release		= exynos_dmabuf_release,  }; diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c index ebacec6f1e4..d0707193745 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c @@ -160,7 +160,6 @@ static int exynos_drm_open(struct drm_device *dev, struct drm_file *file)  	if (!file_priv)  		return -ENOMEM; -	drm_prime_init_file_private(&file->prime);  	file->driver_priv = file_priv;  	return exynos_drm_subdrv_open(dev, file); @@ -184,7 +183,6 @@ static void exynos_drm_preclose(struct drm_device *dev,  			e->base.destroy(&e->base);  		}  	} -	drm_prime_destroy_file_private(&file->prime);  	spin_unlock_irqrestore(&dev->event_lock, flags);  	exynos_drm_subdrv_close(dev, file); @@ -241,6 +239,9 @@ static const struct file_operations exynos_drm_driver_fops = {  	.poll		= drm_poll,  	.read		= drm_read,  	.unlocked_ioctl	= drm_ioctl, +#ifdef CONFIG_COMPAT +	.compat_ioctl = drm_compat_ioctl, +#endif  	.release	= drm_release,  }; diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index a68d2b313f0..b19cd93e704 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c @@ -831,11 +831,6 @@ static int __devinit fimd_probe(struct platform_device *pdev)  	}  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -	if (!res) { -		dev_err(dev, "failed to find registers\n"); -		ret = -ENOENT; -		goto err_clk; -	}  	ctx->regs = devm_request_and_ioremap(&pdev->dev, res);  	if (!ctx->regs) { diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c b/drivers/gpu/drm/exynos/exynos_drm_g2d.c index d2d88f22a03..1065e90d091 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c +++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c @@ -129,7 +129,6 @@ struct g2d_runqueue_node {  struct g2d_data {  	struct device			*dev;  	struct clk			*gate_clk; -	struct resource			*regs_res;  	void __iomem			*regs;  	int				irq;  	struct workqueue_struct		*g2d_workq; @@ -751,7 +750,7 @@ static int __devinit g2d_probe(struct platform_device *pdev)  	struct exynos_drm_subdrv *subdrv;  	int ret; -	g2d = kzalloc(sizeof(*g2d), GFP_KERNEL); +	g2d = devm_kzalloc(&pdev->dev, sizeof(*g2d), GFP_KERNEL);  	if (!g2d) {  		dev_err(dev, "failed to allocate driver data\n");  		return -ENOMEM; @@ -759,10 +758,8 @@ static int __devinit g2d_probe(struct platform_device *pdev)  	g2d->runqueue_slab = kmem_cache_create("g2d_runqueue_slab",  			sizeof(struct g2d_runqueue_node), 0, 0, NULL); -	if (!g2d->runqueue_slab) { -		ret = -ENOMEM; -		goto err_free_mem; -	} +	if (!g2d->runqueue_slab) +		return -ENOMEM;  	g2d->dev = dev; @@ -794,38 +791,26 @@ static int __devinit g2d_probe(struct platform_device *pdev)  	pm_runtime_enable(dev);  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -	if (!res) { -		dev_err(dev, "failed to get I/O memory\n"); -		ret = -ENOENT; -		goto err_put_clk; -	} -	g2d->regs_res = request_mem_region(res->start, resource_size(res), -					   dev_name(dev)); -	if (!g2d->regs_res) { -		dev_err(dev, "failed to request I/O memory\n"); -		ret = -ENOENT; -		goto err_put_clk; -	} - -	g2d->regs = ioremap(res->start, resource_size(res)); +	g2d->regs = devm_request_and_ioremap(&pdev->dev, res);  	if (!g2d->regs) {  		dev_err(dev, "failed to remap I/O memory\n");  		ret = -ENXIO; -		goto err_release_res; +		goto err_put_clk;  	}  	g2d->irq = platform_get_irq(pdev, 0);  	if (g2d->irq < 0) {  		dev_err(dev, "failed to get irq\n");  		ret = g2d->irq; -		goto err_unmap_base; +		goto err_put_clk;  	} -	ret = request_irq(g2d->irq, g2d_irq_handler, 0, "drm_g2d", g2d); +	ret = devm_request_irq(&pdev->dev, g2d->irq, g2d_irq_handler, 0, +								"drm_g2d", g2d);  	if (ret < 0) {  		dev_err(dev, "irq request failed\n"); -		goto err_unmap_base; +		goto err_put_clk;  	}  	platform_set_drvdata(pdev, g2d); @@ -838,7 +823,7 @@ static int __devinit g2d_probe(struct platform_device *pdev)  	ret = exynos_drm_subdrv_register(subdrv);  	if (ret < 0) {  		dev_err(dev, "failed to register drm g2d device\n"); -		goto err_free_irq; +		goto err_put_clk;  	}  	dev_info(dev, "The exynos g2d(ver %d.%d) successfully probed\n", @@ -846,13 +831,6 @@ static int __devinit g2d_probe(struct platform_device *pdev)  	return 0; -err_free_irq: -	free_irq(g2d->irq, g2d); -err_unmap_base: -	iounmap(g2d->regs); -err_release_res: -	release_resource(g2d->regs_res); -	kfree(g2d->regs_res);  err_put_clk:  	pm_runtime_disable(dev);  	clk_put(g2d->gate_clk); @@ -862,8 +840,6 @@ err_destroy_workqueue:  	destroy_workqueue(g2d->g2d_workq);  err_destroy_slab:  	kmem_cache_destroy(g2d->runqueue_slab); -err_free_mem: -	kfree(g2d);  	return ret;  } @@ -873,24 +849,18 @@ static int __devexit g2d_remove(struct platform_device *pdev)  	cancel_work_sync(&g2d->runqueue_work);  	exynos_drm_subdrv_unregister(&g2d->subdrv); -	free_irq(g2d->irq, g2d);  	while (g2d->runqueue_node) {  		g2d_free_runqueue_node(g2d, g2d->runqueue_node);  		g2d->runqueue_node = g2d_get_runqueue_node(g2d);  	} -	iounmap(g2d->regs); -	release_resource(g2d->regs_res); -	kfree(g2d->regs_res); -  	pm_runtime_disable(&pdev->dev);  	clk_put(g2d->gate_clk);  	g2d_fini_cmdlist(g2d);  	destroy_workqueue(g2d->g2d_workq);  	kmem_cache_destroy(g2d->runqueue_slab); -	kfree(g2d);  	return 0;  } @@ -924,7 +894,7 @@ static int g2d_resume(struct device *dev)  }  #endif -SIMPLE_DEV_PM_OPS(g2d_pm_ops, g2d_suspend, g2d_resume); +static SIMPLE_DEV_PM_OPS(g2d_pm_ops, g2d_suspend, g2d_resume);  struct platform_driver g2d_driver = {  	.probe		= g2d_probe, diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c index f9efde40c09..a38051c95ec 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gem.c +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c @@ -122,7 +122,7 @@ fail:  		__free_page(pages[i]);  	drm_free_large(pages); -	return ERR_PTR(PTR_ERR(p)); +	return ERR_CAST(p);  }  static void exynos_gem_put_pages(struct drm_gem_object *obj, @@ -662,7 +662,7 @@ int exynos_drm_gem_dumb_create(struct drm_file *file_priv,  	 */  	args->pitch = args->width * ((args->bpp + 7) / 8); -	args->size = PAGE_ALIGN(args->pitch * args->height); +	args->size = args->pitch * args->height;  	exynos_gem_obj = exynos_drm_gem_create(dev, args->flags, args->size);  	if (IS_ERR(exynos_gem_obj)) diff --git a/drivers/gpu/drm/exynos/exynos_drm_hdmi.c b/drivers/gpu/drm/exynos/exynos_drm_hdmi.c index 8ffcdf8b9e2..3fdf0b65f47 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_hdmi.c @@ -345,7 +345,7 @@ static int __devinit exynos_drm_hdmi_probe(struct platform_device *pdev)  	DRM_DEBUG_KMS("%s\n", __FILE__); -	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); +	ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);  	if (!ctx) {  		DRM_LOG_KMS("failed to alloc common hdmi context.\n");  		return -ENOMEM; @@ -371,7 +371,6 @@ static int __devexit exynos_drm_hdmi_remove(struct platform_device *pdev)  	DRM_DEBUG_KMS("%s\n", __FILE__);  	exynos_drm_subdrv_unregister(&ctx->subdrv); -	kfree(ctx);  	return 0;  } diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c b/drivers/gpu/drm/exynos/exynos_drm_plane.c index b89829e5043..e1f94b746bd 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_plane.c +++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c @@ -29,7 +29,6 @@ static const uint32_t formats[] = {  	DRM_FORMAT_XRGB8888,  	DRM_FORMAT_ARGB8888,  	DRM_FORMAT_NV12, -	DRM_FORMAT_NV12M,  	DRM_FORMAT_NV12MT,  }; diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c index bb1550c4dd5..537027a74fd 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c @@ -633,7 +633,7 @@ static int __devinit vidi_probe(struct platform_device *pdev)  	DRM_DEBUG_KMS("%s\n", __FILE__); -	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); +	ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);  	if (!ctx)  		return -ENOMEM; @@ -673,8 +673,6 @@ static int __devexit vidi_remove(struct platform_device *pdev)  		ctx->raw_edid = NULL;  	} -	kfree(ctx); -  	return 0;  } diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c index 409e2ec1207..a6aea6f3ea1 100644 --- a/drivers/gpu/drm/exynos/exynos_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c @@ -2172,7 +2172,7 @@ static int __devinit hdmi_resources_init(struct hdmi_context *hdata)  	DRM_DEBUG_KMS("HDMI resource init\n"); -	memset(res, 0, sizeof *res); +	memset(res, 0, sizeof(*res));  	/* get clocks, power */  	res->hdmi = clk_get(dev, "hdmi"); @@ -2204,7 +2204,7 @@ static int __devinit hdmi_resources_init(struct hdmi_context *hdata)  	clk_set_parent(res->sclk_hdmi, res->sclk_pixel);  	res->regul_bulk = kzalloc(ARRAY_SIZE(supply) * -		sizeof res->regul_bulk[0], GFP_KERNEL); +		sizeof(res->regul_bulk[0]), GFP_KERNEL);  	if (!res->regul_bulk) {  		DRM_ERROR("failed to get memory for regulators\n");  		goto fail; @@ -2243,7 +2243,7 @@ static int hdmi_resources_cleanup(struct hdmi_context *hdata)  		clk_put(res->sclk_hdmi);  	if (!IS_ERR_OR_NULL(res->hdmi))  		clk_put(res->hdmi); -	memset(res, 0, sizeof *res); +	memset(res, 0, sizeof(*res));  	return 0;  } @@ -2312,11 +2312,6 @@ static int __devinit hdmi_probe(struct platform_device *pdev)  	}  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -	if (!res) { -		DRM_ERROR("failed to find registers\n"); -		ret = -ENOENT; -		goto err_resource; -	}  	hdata->regs = devm_request_and_ioremap(&pdev->dev, res);  	if (!hdata->regs) { diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c index 30fcc12f81d..25b97d5e5fc 100644 --- a/drivers/gpu/drm/exynos/exynos_mixer.c +++ b/drivers/gpu/drm/exynos/exynos_mixer.c @@ -236,11 +236,11 @@ static inline void vp_filter_set(struct mixer_resources *res,  static void vp_default_filter(struct mixer_resources *res)  {  	vp_filter_set(res, VP_POLY8_Y0_LL, -		filter_y_horiz_tap8, sizeof filter_y_horiz_tap8); +		filter_y_horiz_tap8, sizeof(filter_y_horiz_tap8));  	vp_filter_set(res, VP_POLY4_Y0_LL, -		filter_y_vert_tap4, sizeof filter_y_vert_tap4); +		filter_y_vert_tap4, sizeof(filter_y_vert_tap4));  	vp_filter_set(res, VP_POLY4_C0_LL, -		filter_cr_horiz_tap4, sizeof filter_cr_horiz_tap4); +		filter_cr_horiz_tap4, sizeof(filter_cr_horiz_tap4));  }  static void mixer_vsync_set_update(struct mixer_context *ctx, bool enable) diff --git a/drivers/gpu/drm/gma500/oaktrail_device.c b/drivers/gpu/drm/gma500/oaktrail_device.c index 0f9b7db80f6..cf49ba5a54b 100644 --- a/drivers/gpu/drm/gma500/oaktrail_device.c +++ b/drivers/gpu/drm/gma500/oaktrail_device.c @@ -476,6 +476,7 @@ static const struct psb_offset oaktrail_regmap[2] = {  		.pos = DSPAPOS,  		.surf = DSPASURF,  		.addr = MRST_DSPABASE, +		.base = MRST_DSPABASE,  		.status = PIPEASTAT,  		.linoff = DSPALINOFF,  		.tileoff = DSPATILEOFF, @@ -499,6 +500,7 @@ static const struct psb_offset oaktrail_regmap[2] = {  		.pos = DSPBPOS,  		.surf = DSPBSURF,  		.addr = DSPBBASE, +		.base = DSPBBASE,  		.status = PIPEBSTAT,  		.linoff = DSPBLINOFF,  		.tileoff = DSPBTILEOFF, diff --git a/drivers/gpu/drm/gma500/psb_intel_display.c b/drivers/gpu/drm/gma500/psb_intel_display.c index 30dc22a7156..8033526bb53 100644 --- a/drivers/gpu/drm/gma500/psb_intel_display.c +++ b/drivers/gpu/drm/gma500/psb_intel_display.c @@ -1362,6 +1362,9 @@ void psb_intel_crtc_init(struct drm_device *dev, int pipe,  	    (struct drm_connector **) (psb_intel_crtc + 1);  	psb_intel_crtc->mode_set.num_connectors = 0;  	psb_intel_cursor_init(dev, psb_intel_crtc); + +	/* Set to true so that the pipe is forced off on initial config. */ +	psb_intel_crtc->active = true;  }  int psb_intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, diff --git a/drivers/gpu/drm/i810/i810_dma.c b/drivers/gpu/drm/i810/i810_dma.c index 57d892eaaa6..463ec6871fe 100644 --- a/drivers/gpu/drm/i810/i810_dma.c +++ b/drivers/gpu/drm/i810/i810_dma.c @@ -115,6 +115,9 @@ static const struct file_operations i810_buffer_fops = {  	.unlocked_ioctl = drm_ioctl,  	.mmap = i810_mmap_buffers,  	.fasync = drm_fasync, +#ifdef CONFIG_COMPAT +	.compat_ioctl = drm_compat_ioctl, +#endif  	.llseek = noop_llseek,  }; diff --git a/drivers/gpu/drm/i810/i810_drv.c b/drivers/gpu/drm/i810/i810_drv.c index f9924ad04d0..48cfcca2b35 100644 --- a/drivers/gpu/drm/i810/i810_drv.c +++ b/drivers/gpu/drm/i810/i810_drv.c @@ -51,6 +51,9 @@ static const struct file_operations i810_driver_fops = {  	.mmap = drm_mmap,  	.poll = drm_poll,  	.fasync = drm_fasync, +#ifdef CONFIG_COMPAT +	.compat_ioctl = drm_compat_ioctl, +#endif  	.llseek = noop_llseek,  }; diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 9cf7dfe022b..914c0dfabe6 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1587,6 +1587,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)  	spin_lock_init(&dev_priv->irq_lock);  	spin_lock_init(&dev_priv->error_lock);  	spin_lock_init(&dev_priv->rps_lock); +	spin_lock_init(&dev_priv->dpio_lock);  	if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev))  		dev_priv->num_pipe = 3; diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index d9a5372ec56..60815b861ec 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -72,7 +72,7 @@ int i915_gem_init_aliasing_ppgtt(struct drm_device *dev)  	/* ppgtt PDEs reside in the global gtt pagetable, which has 512*1024  	 * entries. For aliasing ppgtt support we just steal them at the end for  	 * now. */ -	first_pd_entry_in_global_pt = 512*1024 - I915_PPGTT_PD_ENTRIES; +	first_pd_entry_in_global_pt = dev_priv->mm.gtt->gtt_total_entries - I915_PPGTT_PD_ENTRIES;  	ppgtt = kzalloc(sizeof(*ppgtt), GFP_KERNEL);  	if (!ppgtt) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 8a3828528b9..5249640cce1 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -2700,9 +2700,6 @@ void intel_irq_init(struct drm_device *dev)  			dev->driver->irq_handler = i8xx_irq_handler;  			dev->driver->irq_uninstall = i8xx_irq_uninstall;  		} else if (INTEL_INFO(dev)->gen == 3) { -			/* IIR "flip pending" means done if this bit is set */ -			I915_WRITE(ECOSKPD, _MASKED_BIT_DISABLE(ECO_FLIP_DONE)); -  			dev->driver->irq_preinstall = i915_irq_preinstall;  			dev->driver->irq_postinstall = i915_irq_postinstall;  			dev->driver->irq_uninstall = i915_irq_uninstall; diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index a69a3d0d3ac..bc2ad348e5d 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1376,7 +1376,8 @@ static void assert_pch_dp_disabled(struct drm_i915_private *dev_priv,  	     "PCH DP (0x%08x) enabled on transcoder %c, should be disabled\n",  	     reg, pipe_name(pipe)); -	WARN(HAS_PCH_IBX(dev_priv->dev) && (val & SDVO_PIPE_B_SELECT), +	WARN(HAS_PCH_IBX(dev_priv->dev) && (val & DP_PORT_EN) == 0 +	     && (val & DP_PIPEB_SELECT),  	     "IBX PCH dp port still using transcoder B\n");  } @@ -1384,11 +1385,12 @@ static void assert_pch_hdmi_disabled(struct drm_i915_private *dev_priv,  				     enum pipe pipe, int reg)  {  	u32 val = I915_READ(reg); -	WARN(hdmi_pipe_enabled(dev_priv, val, pipe), +	WARN(hdmi_pipe_enabled(dev_priv, pipe, val),  	     "PCH HDMI (0x%08x) enabled on transcoder %c, should be disabled\n",  	     reg, pipe_name(pipe)); -	WARN(HAS_PCH_IBX(dev_priv->dev) && (val & SDVO_PIPE_B_SELECT), +	WARN(HAS_PCH_IBX(dev_priv->dev) && (val & PORT_ENABLE) == 0 +	     && (val & SDVO_PIPE_B_SELECT),  	     "IBX PCH hdmi port still using transcoder B\n");  } @@ -1404,13 +1406,13 @@ static void assert_pch_ports_disabled(struct drm_i915_private *dev_priv,  	reg = PCH_ADPA;  	val = I915_READ(reg); -	WARN(adpa_pipe_enabled(dev_priv, val, pipe), +	WARN(adpa_pipe_enabled(dev_priv, pipe, val),  	     "PCH VGA enabled on transcoder %c, should be disabled\n",  	     pipe_name(pipe));  	reg = PCH_LVDS;  	val = I915_READ(reg); -	WARN(lvds_pipe_enabled(dev_priv, val, pipe), +	WARN(lvds_pipe_enabled(dev_priv, pipe, val),  	     "PCH LVDS enabled on transcoder %c, should be disabled\n",  	     pipe_name(pipe)); @@ -1872,7 +1874,7 @@ static void disable_pch_hdmi(struct drm_i915_private *dev_priv,  			     enum pipe pipe, int reg)  {  	u32 val = I915_READ(reg); -	if (hdmi_pipe_enabled(dev_priv, val, pipe)) { +	if (hdmi_pipe_enabled(dev_priv, pipe, val)) {  		DRM_DEBUG_KMS("Disabling pch HDMI %x on pipe %d\n",  			      reg, pipe);  		I915_WRITE(reg, val & ~PORT_ENABLE); @@ -1894,12 +1896,12 @@ static void intel_disable_pch_ports(struct drm_i915_private *dev_priv,  	reg = PCH_ADPA;  	val = I915_READ(reg); -	if (adpa_pipe_enabled(dev_priv, val, pipe)) +	if (adpa_pipe_enabled(dev_priv, pipe, val))  		I915_WRITE(reg, val & ~ADPA_DAC_ENABLE);  	reg = PCH_LVDS;  	val = I915_READ(reg); -	if (lvds_pipe_enabled(dev_priv, val, pipe)) { +	if (lvds_pipe_enabled(dev_priv, pipe, val)) {  		DRM_DEBUG_KMS("disable lvds on pipe %d val 0x%08x\n", pipe, val);  		I915_WRITE(reg, val & ~LVDS_PORT_EN);  		POSTING_READ(reg); diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index a6c426afaa7..ace757af913 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -2533,14 +2533,10 @@ intel_dp_init(struct drm_device *dev, int output_reg)  			break;  	} -	intel_dp_i2c_init(intel_dp, intel_connector, name); -  	/* Cache some DPCD data in the eDP case */  	if (is_edp(intel_dp)) { -		bool ret;  		struct edp_power_seq	cur, vbt;  		u32 pp_on, pp_off, pp_div; -		struct edid *edid;  		pp_on = I915_READ(PCH_PP_ON_DELAYS);  		pp_off = I915_READ(PCH_PP_OFF_DELAYS); @@ -2591,6 +2587,13 @@ intel_dp_init(struct drm_device *dev, int output_reg)  		DRM_DEBUG_KMS("backlight on delay %d, off delay %d\n",  			      intel_dp->backlight_on_delay, intel_dp->backlight_off_delay); +	} + +	intel_dp_i2c_init(intel_dp, intel_connector, name); + +	if (is_edp(intel_dp)) { +		bool ret; +		struct edid *edid;  		ironlake_edp_panel_vdd_on(intel_dp);  		ret = intel_dp_get_dpcd(intel_dp); diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index e05c0d3e344..e9a6f6aaed8 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -780,6 +780,14 @@ static const struct dmi_system_id intel_no_lvds[] = {  			DMI_MATCH(DMI_BOARD_NAME, "ZBOXSD-ID12/ID13"),  		},  	}, +	{ +		.callback = intel_no_lvds_dmi_callback, +		.ident = "Gigabyte GA-D525TUD", +		.matches = { +			DMI_MATCH(DMI_BOARD_VENDOR, "Gigabyte Technology Co., Ltd."), +			DMI_MATCH(DMI_BOARD_NAME, "D525TUD"), +		}, +	},  	{ }	/* terminating entry */  }; diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 3df4f5fa892..e019b236986 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -162,19 +162,12 @@ static u32 i915_read_blc_pwm_ctl(struct drm_i915_private *dev_priv)  	return val;  } -u32 intel_panel_get_max_backlight(struct drm_device *dev) +static u32 _intel_panel_get_max_backlight(struct drm_device *dev)  {  	struct drm_i915_private *dev_priv = dev->dev_private;  	u32 max;  	max = i915_read_blc_pwm_ctl(dev_priv); -	if (max == 0) { -		/* XXX add code here to query mode clock or hardware clock -		 * and program max PWM appropriately. -		 */ -		pr_warn_once("fixme: max PWM is zero\n"); -		return 1; -	}  	if (HAS_PCH_SPLIT(dev)) {  		max >>= 16; @@ -188,6 +181,22 @@ u32 intel_panel_get_max_backlight(struct drm_device *dev)  			max *= 0xff;  	} +	return max; +} + +u32 intel_panel_get_max_backlight(struct drm_device *dev) +{ +	u32 max; + +	max = _intel_panel_get_max_backlight(dev); +	if (max == 0) { +		/* XXX add code here to query mode clock or hardware clock +		 * and program max PWM appropriately. +		 */ +		pr_warn_once("fixme: max PWM is zero\n"); +		return 1; +	} +  	DRM_DEBUG_DRIVER("max backlight PWM = %d\n", max);  	return max;  } @@ -424,7 +433,11 @@ int intel_panel_setup_backlight(struct drm_device *dev)  	memset(&props, 0, sizeof(props));  	props.type = BACKLIGHT_RAW; -	props.max_brightness = intel_panel_get_max_backlight(dev); +	props.max_brightness = _intel_panel_get_max_backlight(dev); +	if (props.max_brightness == 0) { +		DRM_ERROR("Failed to get maximum backlight value\n"); +		return -ENODEV; +	}  	dev_priv->backlight =  		backlight_device_register("intel_backlight",  					  &connector->kdev, dev, diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 1881c8c83f0..ba8a27b1757 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -3672,6 +3672,9 @@ static void gen3_init_clock_gating(struct drm_device *dev)  	if (IS_PINEVIEW(dev))  		I915_WRITE(ECOSKPD, _MASKED_BIT_ENABLE(ECO_GATING_CX_ONLY)); + +	/* IIR "flip pending" means done if this bit is set */ +	I915_WRITE(ECOSKPD, _MASKED_BIT_DISABLE(ECO_FLIP_DONE));  }  static void i85x_init_clock_gating(struct drm_device *dev) diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index d81bb0bf288..123afd35761 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -2573,7 +2573,6 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob)  		hotplug_mask = intel_sdvo->is_sdvob ?  			SDVOB_HOTPLUG_INT_STATUS_I915 : SDVOC_HOTPLUG_INT_STATUS_I915;  	} -	dev_priv->hotplug_supported_mask |= hotplug_mask;  	drm_encoder_helper_add(&intel_encoder->base, &intel_sdvo_helper_funcs); @@ -2581,14 +2580,6 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob)  	if (!intel_sdvo_get_capabilities(intel_sdvo, &intel_sdvo->caps))  		goto err; -	/* Set up hotplug command - note paranoia about contents of reply. -	 * We assume that the hardware is in a sane state, and only touch -	 * the bits we think we understand. -	 */ -	intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_ACTIVE_HOT_PLUG, -			     &intel_sdvo->hotplug_active, 2); -	intel_sdvo->hotplug_active[0] &= ~0x3; -  	if (intel_sdvo_output_setup(intel_sdvo,  				    intel_sdvo->caps.output_flags) != true) {  		DRM_DEBUG_KMS("SDVO output failed to setup on %s\n", @@ -2596,6 +2587,12 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob)  		goto err;  	} +	/* Only enable the hotplug irq if we need it, to work around noisy +	 * hotplug lines. +	 */ +	if (intel_sdvo->hotplug_active[0]) +		dev_priv->hotplug_supported_mask |= hotplug_mask; +  	intel_sdvo_select_ddc_bus(dev_priv, intel_sdvo, sdvo_reg);  	/* Set the input timing to the screen. Assume always input 0. */ diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index cc8df4de2d9..7644f31a377 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -60,11 +60,11 @@ ivb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb,  	switch (fb->pixel_format) {  	case DRM_FORMAT_XBGR8888: -		sprctl |= SPRITE_FORMAT_RGBX888; +		sprctl |= SPRITE_FORMAT_RGBX888 | SPRITE_RGB_ORDER_RGBX;  		pixel_size = 4;  		break;  	case DRM_FORMAT_XRGB8888: -		sprctl |= SPRITE_FORMAT_RGBX888 | SPRITE_RGB_ORDER_RGBX; +		sprctl |= SPRITE_FORMAT_RGBX888;  		pixel_size = 4;  		break;  	case DRM_FORMAT_YUYV: diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.c b/drivers/gpu/drm/mgag200/mgag200_drv.c index ea1024d7997..e5f145d2cb3 100644 --- a/drivers/gpu/drm/mgag200/mgag200_drv.c +++ b/drivers/gpu/drm/mgag200/mgag200_drv.c @@ -84,6 +84,9 @@ static const struct file_operations mgag200_driver_fops = {  	.mmap = mgag200_mmap,  	.poll = drm_poll,  	.fasync = drm_fasync, +#ifdef CONFIG_COMPAT +	.compat_ioctl = drm_compat_ioctl, +#endif  	.read = drm_read,  }; diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index 69688ef5cf4..7e16dc5e646 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c @@ -598,7 +598,7 @@ nouveau_display_dumb_create(struct drm_file *file_priv, struct drm_device *dev,  	args->size = args->pitch * args->height;  	args->size = roundup(args->size, PAGE_SIZE); -	ret = nouveau_gem_new(dev, args->size, 0, TTM_PL_FLAG_VRAM, 0, 0, &bo); +	ret = nouveau_gem_new(dev, args->size, 0, NOUVEAU_GEM_DOMAIN_VRAM, 0, 0, &bo);  	if (ret)  		return ret; diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index 1866dbb4997..c61014442aa 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c @@ -736,9 +736,11 @@ nouveau_card_init(struct drm_device *dev)  			}  			break;  		case NV_C0: -			nvc0_copy_create(dev, 1); +			if (!(nv_rd32(dev, 0x022500) & 0x00000200)) +				nvc0_copy_create(dev, 1);  		case NV_D0: -			nvc0_copy_create(dev, 0); +			if (!(nv_rd32(dev, 0x022500) & 0x00000100)) +				nvc0_copy_create(dev, 0);  			break;  		default:  			break; diff --git a/drivers/gpu/drm/nouveau/nv50_gpio.c b/drivers/gpu/drm/nouveau/nv50_gpio.c index f429e6a8ca7..f0349053489 100644 --- a/drivers/gpu/drm/nouveau/nv50_gpio.c +++ b/drivers/gpu/drm/nouveau/nv50_gpio.c @@ -115,6 +115,9 @@ nv50_gpio_init(struct drm_device *dev)  {  	struct drm_nouveau_private *dev_priv = dev->dev_private; +	/* initialise gpios and routing to vbios defaults */ +	nouveau_gpio_reset(dev); +  	/* disable, and ack any pending gpio interrupts */  	nv_wr32(dev, 0xe050, 0x00000000);  	nv_wr32(dev, 0xe054, 0xffffffff); diff --git a/drivers/gpu/drm/nouveau/nvd0_display.c b/drivers/gpu/drm/nouveau/nvd0_display.c index dac525b2994..8a2fc89b776 100644 --- a/drivers/gpu/drm/nouveau/nvd0_display.c +++ b/drivers/gpu/drm/nouveau/nvd0_display.c @@ -1510,10 +1510,10 @@ nvd0_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *umode,  	case OUTPUT_DP:  		if (nv_connector->base.display_info.bpc == 6) {  			nv_encoder->dp.datarate = mode->clock * 18 / 8; -			syncs |= 0x00000140; +			syncs |= 0x00000002 << 6;  		} else {  			nv_encoder->dp.datarate = mode->clock * 24 / 8; -			syncs |= 0x00000180; +			syncs |= 0x00000005 << 6;  		}  		if (nv_encoder->dcb->sorconf.link & 1) diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index f4d4505fe83..e721e3087b9 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c @@ -258,7 +258,6 @@ void atombios_crtc_dpms(struct drm_crtc *crtc, int mode)  		radeon_crtc->enabled = true;  		/* adjust pm to dpms changes BEFORE enabling crtcs */  		radeon_pm_compute_clocks(rdev); -		/* disable crtc pair power gating before programming */  		if (ASIC_IS_DCE6(rdev) && !radeon_crtc->in_mode_set)  			atombios_powergate_crtc(crtc, ATOM_DISABLE);  		atombios_enable_crtc(crtc, ATOM_ENABLE); @@ -278,25 +277,8 @@ void atombios_crtc_dpms(struct drm_crtc *crtc, int mode)  			atombios_enable_crtc_memreq(crtc, ATOM_DISABLE);  		atombios_enable_crtc(crtc, ATOM_DISABLE);  		radeon_crtc->enabled = false; -		/* power gating is per-pair */ -		if (ASIC_IS_DCE6(rdev) && !radeon_crtc->in_mode_set) { -			struct drm_crtc *other_crtc; -			struct radeon_crtc *other_radeon_crtc; -			list_for_each_entry(other_crtc, &rdev->ddev->mode_config.crtc_list, head) { -				other_radeon_crtc = to_radeon_crtc(other_crtc); -				if (((radeon_crtc->crtc_id == 0) && (other_radeon_crtc->crtc_id == 1)) || -				    ((radeon_crtc->crtc_id == 1) && (other_radeon_crtc->crtc_id == 0)) || -				    ((radeon_crtc->crtc_id == 2) && (other_radeon_crtc->crtc_id == 3)) || -				    ((radeon_crtc->crtc_id == 3) && (other_radeon_crtc->crtc_id == 2)) || -				    ((radeon_crtc->crtc_id == 4) && (other_radeon_crtc->crtc_id == 5)) || -				    ((radeon_crtc->crtc_id == 5) && (other_radeon_crtc->crtc_id == 4))) { -					/* if both crtcs in the pair are off, enable power gating */ -					if (other_radeon_crtc->enabled == false) -						atombios_powergate_crtc(crtc, ATOM_ENABLE); -					break; -				} -			} -		} +		if (ASIC_IS_DCE6(rdev) && !radeon_crtc->in_mode_set) +			atombios_powergate_crtc(crtc, ATOM_ENABLE);  		/* adjust pm to dpms changes AFTER disabling crtcs */  		radeon_pm_compute_clocks(rdev);  		break; @@ -1497,14 +1479,98 @@ static void radeon_legacy_atom_fixup(struct drm_crtc *crtc)  	}  } +/** + * radeon_get_pll_use_mask - look up a mask of which pplls are in use + * + * @crtc: drm crtc + * + * Returns the mask of which PPLLs (Pixel PLLs) are in use. + */ +static u32 radeon_get_pll_use_mask(struct drm_crtc *crtc) +{ +	struct drm_device *dev = crtc->dev; +	struct drm_crtc *test_crtc; +	struct radeon_crtc *radeon_test_crtc; +	u32 pll_in_use = 0; + +	list_for_each_entry(test_crtc, &dev->mode_config.crtc_list, head) { +		if (crtc == test_crtc) +			continue; + +		radeon_test_crtc = to_radeon_crtc(test_crtc); +		if (radeon_test_crtc->pll_id != ATOM_PPLL_INVALID) +			pll_in_use |= (1 << radeon_test_crtc->pll_id); +	} +	return pll_in_use; +} + +/** + * radeon_get_shared_dp_ppll - return the PPLL used by another crtc for DP + * + * @crtc: drm crtc + * + * Returns the PPLL (Pixel PLL) used by another crtc/encoder which is + * also in DP mode.  For DP, a single PPLL can be used for all DP + * crtcs/encoders. + */ +static int radeon_get_shared_dp_ppll(struct drm_crtc *crtc) +{ +	struct drm_device *dev = crtc->dev; +	struct drm_encoder *test_encoder; +	struct radeon_crtc *radeon_test_crtc; + +	list_for_each_entry(test_encoder, &dev->mode_config.encoder_list, head) { +		if (test_encoder->crtc && (test_encoder->crtc != crtc)) { +			if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_encoder))) { +				/* for DP use the same PLL for all */ +				radeon_test_crtc = to_radeon_crtc(test_encoder->crtc); +				if (radeon_test_crtc->pll_id != ATOM_PPLL_INVALID) +					return radeon_test_crtc->pll_id; +			} +		} +	} +	return ATOM_PPLL_INVALID; +} + +/** + * radeon_atom_pick_pll - Allocate a PPLL for use by the crtc. + * + * @crtc: drm crtc + * + * Returns the PPLL (Pixel PLL) to be used by the crtc.  For DP monitors + * a single PPLL can be used for all DP crtcs/encoders.  For non-DP + * monitors a dedicated PPLL must be used.  If a particular board has + * an external DP PLL, return ATOM_PPLL_INVALID to skip PLL programming + * as there is no need to program the PLL itself.  If we are not able to + * allocate a PLL, return ATOM_PPLL_INVALID to skip PLL programming to + * avoid messing up an existing monitor. + * + * Asic specific PLL information + * + * DCE 6.1 + * - PPLL2 is only available to UNIPHYA (both DP and non-DP) + * - PPLL0, PPLL1 are available for UNIPHYB/C/D/E/F (both DP and non-DP) + * + * DCE 6.0 + * - PPLL0 is available to all UNIPHY (DP only) + * - PPLL1, PPLL2 are available for all UNIPHY (both DP and non-DP) and DAC + * + * DCE 5.0 + * - DCPLL is available to all UNIPHY (DP only) + * - PPLL1, PPLL2 are available for all UNIPHY (both DP and non-DP) and DAC + * + * DCE 3.0/4.0/4.1 + * - PPLL1, PPLL2 are available for all UNIPHY (both DP and non-DP) and DAC + * + */  static int radeon_atom_pick_pll(struct drm_crtc *crtc)  {  	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);  	struct drm_device *dev = crtc->dev;  	struct radeon_device *rdev = dev->dev_private;  	struct drm_encoder *test_encoder; -	struct drm_crtc *test_crtc; -	uint32_t pll_in_use = 0; +	u32 pll_in_use; +	int pll;  	if (ASIC_IS_DCE61(rdev)) {  		list_for_each_entry(test_encoder, &dev->mode_config.encoder_list, head) { @@ -1516,32 +1582,40 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc)  				if ((test_radeon_encoder->encoder_id ==  				     ENCODER_OBJECT_ID_INTERNAL_UNIPHY) && -				    (dig->linkb == false)) /* UNIPHY A uses PPLL2 */ +				    (dig->linkb == false)) +					/* UNIPHY A uses PPLL2 */  					return ATOM_PPLL2; +				else if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_encoder))) { +					/* UNIPHY B/C/D/E/F */ +					if (rdev->clock.dp_extclk) +						/* skip PPLL programming if using ext clock */ +						return ATOM_PPLL_INVALID; +					else { +						/* use the same PPLL for all DP monitors */ +						pll = radeon_get_shared_dp_ppll(crtc); +						if (pll != ATOM_PPLL_INVALID) +							return pll; +					} +				} +				break;  			}  		}  		/* UNIPHY B/C/D/E/F */ -		list_for_each_entry(test_crtc, &dev->mode_config.crtc_list, head) { -			struct radeon_crtc *radeon_test_crtc; - -			if (crtc == test_crtc) -				continue; - -			radeon_test_crtc = to_radeon_crtc(test_crtc); -			if ((radeon_test_crtc->pll_id == ATOM_PPLL0) || -			    (radeon_test_crtc->pll_id == ATOM_PPLL1)) -				pll_in_use |= (1 << radeon_test_crtc->pll_id); -		} -		if (!(pll_in_use & 4)) +		pll_in_use = radeon_get_pll_use_mask(crtc); +		if (!(pll_in_use & (1 << ATOM_PPLL0)))  			return ATOM_PPLL0; -		return ATOM_PPLL1; +		if (!(pll_in_use & (1 << ATOM_PPLL1))) +			return ATOM_PPLL1; +		DRM_ERROR("unable to allocate a PPLL\n"); +		return ATOM_PPLL_INVALID;  	} else if (ASIC_IS_DCE4(rdev)) {  		list_for_each_entry(test_encoder, &dev->mode_config.encoder_list, head) {  			if (test_encoder->crtc && (test_encoder->crtc == crtc)) {  				/* in DP mode, the DP ref clock can come from PPLL, DCPLL, or ext clock,  				 * depending on the asic:  				 * DCE4: PPLL or ext clock -				 * DCE5: DCPLL or ext clock +				 * DCE5: PPLL, DCPLL, or ext clock +				 * DCE6: PPLL, PPLL0, or ext clock  				 *  				 * Setting ATOM_PPLL_INVALID will cause SetPixelClock to skip  				 * PPLL/DCPLL programming and only program the DP DTO for the @@ -1549,31 +1623,34 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc)  				 */  				if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_encoder))) {  					if (rdev->clock.dp_extclk) +						/* skip PPLL programming if using ext clock */  						return ATOM_PPLL_INVALID;  					else if (ASIC_IS_DCE6(rdev)) +						/* use PPLL0 for all DP */  						return ATOM_PPLL0;  					else if (ASIC_IS_DCE5(rdev)) +						/* use DCPLL for all DP */  						return ATOM_DCPLL; +					else { +						/* use the same PPLL for all DP monitors */ +						pll = radeon_get_shared_dp_ppll(crtc); +						if (pll != ATOM_PPLL_INVALID) +							return pll; +					}  				} +				break;  			}  		} - -		/* otherwise, pick one of the plls */ -		list_for_each_entry(test_crtc, &dev->mode_config.crtc_list, head) { -			struct radeon_crtc *radeon_test_crtc; - -			if (crtc == test_crtc) -				continue; - -			radeon_test_crtc = to_radeon_crtc(test_crtc); -			if ((radeon_test_crtc->pll_id >= ATOM_PPLL1) && -			    (radeon_test_crtc->pll_id <= ATOM_PPLL2)) -				pll_in_use |= (1 << radeon_test_crtc->pll_id); -		} -		if (!(pll_in_use & 1)) +		/* all other cases */ +		pll_in_use = radeon_get_pll_use_mask(crtc); +		if (!(pll_in_use & (1 << ATOM_PPLL2))) +			return ATOM_PPLL2; +		if (!(pll_in_use & (1 << ATOM_PPLL1)))  			return ATOM_PPLL1; -		return ATOM_PPLL2; +		DRM_ERROR("unable to allocate a PPLL\n"); +		return ATOM_PPLL_INVALID;  	} else +		/* use PPLL1 or PPLL2 */  		return radeon_crtc->crtc_id;  } @@ -1682,9 +1759,22 @@ static void atombios_crtc_disable(struct drm_crtc *crtc)  	struct drm_device *dev = crtc->dev;  	struct radeon_device *rdev = dev->dev_private;  	struct radeon_atom_ss ss; +	int i;  	atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); +	for (i = 0; i < rdev->num_crtc; i++) { +		if (rdev->mode_info.crtcs[i] && +		    rdev->mode_info.crtcs[i]->enabled && +		    i != radeon_crtc->crtc_id && +		    radeon_crtc->pll_id == rdev->mode_info.crtcs[i]->pll_id) { +			/* one other crtc is using this pll don't turn +			 * off the pll +			 */ +			goto done; +		} +	} +  	switch (radeon_crtc->pll_id) {  	case ATOM_PPLL1:  	case ATOM_PPLL2: @@ -1701,7 +1791,8 @@ static void atombios_crtc_disable(struct drm_crtc *crtc)  	default:  		break;  	} -	radeon_crtc->pll_id = -1; +done: +	radeon_crtc->pll_id = ATOM_PPLL_INVALID;  }  static const struct drm_crtc_helper_funcs atombios_helper_funcs = { @@ -1750,6 +1841,6 @@ void radeon_atombios_init_crtc(struct drm_device *dev,  		else  			radeon_crtc->crtc_offset = 0;  	} -	radeon_crtc->pll_id = -1; +	radeon_crtc->pll_id = ATOM_PPLL_INVALID;  	drm_crtc_helper_add(&radeon_crtc->base, &atombios_helper_funcs);  } diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c index 7712cf5ab33..3623b98ed3f 100644 --- a/drivers/gpu/drm/radeon/atombios_dp.c +++ b/drivers/gpu/drm/radeon/atombios_dp.c @@ -577,30 +577,25 @@ int radeon_dp_get_panel_mode(struct drm_encoder *encoder,  	struct radeon_device *rdev = dev->dev_private;  	struct radeon_connector *radeon_connector = to_radeon_connector(connector);  	int panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE; +	u16 dp_bridge = radeon_connector_encoder_get_dp_bridge_encoder_id(connector); +	u8 tmp;  	if (!ASIC_IS_DCE4(rdev))  		return panel_mode; -	if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) == -	    ENCODER_OBJECT_ID_NUTMEG) -		panel_mode = DP_PANEL_MODE_INTERNAL_DP1_MODE; -	else if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) == -		 ENCODER_OBJECT_ID_TRAVIS) { -		u8 id[6]; -		int i; -		for (i = 0; i < 6; i++) -			id[i] = radeon_read_dpcd_reg(radeon_connector, 0x503 + i); -		if (id[0] == 0x73 && -		    id[1] == 0x69 && -		    id[2] == 0x76 && -		    id[3] == 0x61 && -		    id[4] == 0x72 && -		    id[5] == 0x54) +	if (dp_bridge != ENCODER_OBJECT_ID_NONE) { +		/* DP bridge chips */ +		tmp = radeon_read_dpcd_reg(radeon_connector, DP_EDP_CONFIGURATION_CAP); +		if (tmp & 1) +			panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE; +		else if ((dp_bridge == ENCODER_OBJECT_ID_NUTMEG) || +			 (dp_bridge == ENCODER_OBJECT_ID_TRAVIS))  			panel_mode = DP_PANEL_MODE_INTERNAL_DP1_MODE;  		else -			panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE; +			panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE;  	} else if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { -		u8 tmp = radeon_read_dpcd_reg(radeon_connector, DP_EDP_CONFIGURATION_CAP); +		/* eDP */ +		tmp = radeon_read_dpcd_reg(radeon_connector, DP_EDP_CONFIGURATION_CAP);  		if (tmp & 1)  			panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE;  	} diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c b/drivers/gpu/drm/radeon/atombios_encoders.c index f9bc27fe269..6e8803a1170 100644 --- a/drivers/gpu/drm/radeon/atombios_encoders.c +++ b/drivers/gpu/drm/radeon/atombios_encoders.c @@ -1379,6 +1379,8 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode)  	struct drm_device *dev = encoder->dev;  	struct radeon_device *rdev = dev->dev_private;  	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); +	struct drm_encoder *ext_encoder = radeon_get_external_encoder(encoder); +	struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;  	struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);  	struct radeon_connector *radeon_connector = NULL;  	struct radeon_connector_atom_dig *radeon_dig_connector = NULL; @@ -1390,19 +1392,37 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode)  	switch (mode) {  	case DRM_MODE_DPMS_ON: -		/* some early dce3.2 boards have a bug in their transmitter control table */ -		if ((rdev->family == CHIP_RV710) || (rdev->family == CHIP_RV730) || -		    ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) { -			if (ASIC_IS_DCE6(rdev)) { -				/* It seems we need to call ATOM_ENCODER_CMD_SETUP again -				 * before reenabling encoder on DPMS ON, otherwise we never -				 * get picture -				 */ -				atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_SETUP, 0); +		if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) { +			if (!connector) +				dig->panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE; +			else +				dig->panel_mode = radeon_dp_get_panel_mode(encoder, connector); + +			/* setup and enable the encoder */ +			atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_SETUP, 0); +			atombios_dig_encoder_setup(encoder, +						   ATOM_ENCODER_CMD_SETUP_PANEL_MODE, +						   dig->panel_mode); +			if (ext_encoder) { +				if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE61(rdev)) +					atombios_external_encoder_setup(encoder, ext_encoder, +									EXTERNAL_ENCODER_ACTION_V3_ENCODER_SETUP);  			}  			atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); -		} else { +		} else if (ASIC_IS_DCE4(rdev)) { +			/* setup and enable the encoder */ +			atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_SETUP, 0); +			/* enable the transmitter */ +			atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0);  			atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0); +		} else { +			/* setup and enable the encoder and transmitter */ +			atombios_dig_encoder_setup(encoder, ATOM_ENABLE, 0); +			atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP, 0, 0); +			atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); +			/* some early dce3.2 boards have a bug in their transmitter control table */ +			if ((rdev->family != CHIP_RV710) || (rdev->family != CHIP_RV730)) +				atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0);  		}  		if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) {  			if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { @@ -1420,10 +1440,19 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode)  	case DRM_MODE_DPMS_STANDBY:  	case DRM_MODE_DPMS_SUSPEND:  	case DRM_MODE_DPMS_OFF: -		if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) +		if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) { +			/* disable the transmitter */  			atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); -		else +		} else if (ASIC_IS_DCE4(rdev)) { +			/* disable the transmitter */ +			atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0); +			atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); +		} else { +			/* disable the encoder and transmitter */  			atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0); +			atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); +			atombios_dig_encoder_setup(encoder, ATOM_DISABLE, 0); +		}  		if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) {  			if (ASIC_IS_DCE4(rdev))  				atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_OFF, 0); @@ -1740,13 +1769,34 @@ static int radeon_atom_pick_dig_encoder(struct drm_encoder *encoder)  	struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);  	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);  	struct drm_encoder *test_encoder; -	struct radeon_encoder_atom_dig *dig; +	struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;  	uint32_t dig_enc_in_use = 0; -	/* DCE4/5 */ -	if (ASIC_IS_DCE4(rdev)) { -		dig = radeon_encoder->enc_priv; -		if (ASIC_IS_DCE41(rdev)) { +	if (ASIC_IS_DCE6(rdev)) { +		/* DCE6 */ +		switch (radeon_encoder->encoder_id) { +		case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: +			if (dig->linkb) +				return 1; +			else +				return 0; +			break; +		case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: +			if (dig->linkb) +				return 3; +			else +				return 2; +			break; +		case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: +			if (dig->linkb) +				return 5; +			else +				return 4; +			break; +		} +	} else if (ASIC_IS_DCE4(rdev)) { +		/* DCE4/5 */ +		if (ASIC_IS_DCE41(rdev) && !ASIC_IS_DCE61(rdev)) {  			/* ontario follows DCE4 */  			if (rdev->family == CHIP_PALM) {  				if (dig->linkb) @@ -1848,10 +1898,12 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder,  	struct drm_device *dev = encoder->dev;  	struct radeon_device *rdev = dev->dev_private;  	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); -	struct drm_encoder *ext_encoder = radeon_get_external_encoder(encoder);  	radeon_encoder->pixel_clock = adjusted_mode->clock; +	/* need to call this here rather than in prepare() since we need some crtc info */ +	radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); +  	if (ASIC_IS_AVIVO(rdev) && !ASIC_IS_DCE4(rdev)) {  		if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT | ATOM_DEVICE_TV_SUPPORT))  			atombios_yuv_setup(encoder, true); @@ -1870,38 +1922,7 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder,  	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:  	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:  	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: -		if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) { -			struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); -			struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; - -			if (!connector) -				dig->panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE; -			else -				dig->panel_mode = radeon_dp_get_panel_mode(encoder, connector); - -			/* setup and enable the encoder */ -			atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_SETUP, 0); -			atombios_dig_encoder_setup(encoder, -						   ATOM_ENCODER_CMD_SETUP_PANEL_MODE, -						   dig->panel_mode); -		} else if (ASIC_IS_DCE4(rdev)) { -			/* disable the transmitter */ -			atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); -			/* setup and enable the encoder */ -			atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_SETUP, 0); - -			/* enable the transmitter */ -			atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); -		} else { -			/* disable the encoder and transmitter */ -			atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); -			atombios_dig_encoder_setup(encoder, ATOM_DISABLE, 0); - -			/* setup and enable the encoder and transmitter */ -			atombios_dig_encoder_setup(encoder, ATOM_ENABLE, 0); -			atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP, 0, 0); -			atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); -		} +		/* handled in dpms */  		break;  	case ENCODER_OBJECT_ID_INTERNAL_DDI:  	case ENCODER_OBJECT_ID_INTERNAL_DVO1: @@ -1922,14 +1943,6 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder,  		break;  	} -	if (ext_encoder) { -		if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE61(rdev)) -			atombios_external_encoder_setup(encoder, ext_encoder, -							EXTERNAL_ENCODER_ACTION_V3_ENCODER_SETUP); -		else -			atombios_external_encoder_setup(encoder, ext_encoder, ATOM_ENABLE); -	} -  	atombios_apply_encoder_quirks(encoder, adjusted_mode);  	if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) { @@ -2116,7 +2129,6 @@ static void radeon_atom_encoder_prepare(struct drm_encoder *encoder)  	}  	radeon_atom_output_lock(encoder, true); -	radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF);  	if (connector) {  		struct radeon_connector *radeon_connector = to_radeon_connector(connector); @@ -2137,6 +2149,7 @@ static void radeon_atom_encoder_prepare(struct drm_encoder *encoder)  static void radeon_atom_encoder_commit(struct drm_encoder *encoder)  { +	/* need to call this here as we need the crtc set up */  	radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_ON);  	radeon_atom_output_lock(encoder, false);  } @@ -2177,14 +2190,7 @@ static void radeon_atom_encoder_disable(struct drm_encoder *encoder)  	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:  	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:  	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: -		if (ASIC_IS_DCE4(rdev)) -			/* disable the transmitter */ -			atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); -		else { -			/* disable the encoder and transmitter */ -			atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); -			atombios_dig_encoder_setup(encoder, ATOM_DISABLE, 0); -		} +		/* handled in dpms */  		break;  	case ENCODER_OBJECT_ID_INTERNAL_DDI:  	case ENCODER_OBJECT_ID_INTERNAL_DVO1: diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c index ab74e6b149e..f37676d7f21 100644 --- a/drivers/gpu/drm/radeon/r600_cs.c +++ b/drivers/gpu/drm/radeon/r600_cs.c @@ -63,6 +63,7 @@ struct r600_cs_track {  	u32			cb_color_size_idx[8]; /* unused */  	u32			cb_target_mask;  	u32			cb_shader_mask;  /* unused */ +	bool			is_resolve;  	u32			cb_color_size[8];  	u32			vgt_strmout_en;  	u32			vgt_strmout_buffer_en; @@ -315,7 +316,15 @@ static void r600_cs_track_init(struct r600_cs_track *track)  		track->cb_color_bo[i] = NULL;  		track->cb_color_bo_offset[i] = 0xFFFFFFFF;  		track->cb_color_bo_mc[i] = 0xFFFFFFFF; +		track->cb_color_frag_bo[i] = NULL; +		track->cb_color_frag_offset[i] = 0xFFFFFFFF; +		track->cb_color_tile_bo[i] = NULL; +		track->cb_color_tile_offset[i] = 0xFFFFFFFF; +		track->cb_color_mask[i] = 0xFFFFFFFF;  	} +	track->is_resolve = false; +	track->nsamples = 16; +	track->log_nsamples = 4;  	track->cb_target_mask = 0xFFFFFFFF;  	track->cb_shader_mask = 0xFFFFFFFF;  	track->cb_dirty = true; @@ -352,6 +361,8 @@ static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)  	volatile u32 *ib = p->ib.ptr;  	unsigned array_mode;  	u32 format; +	/* When resolve is used, the second colorbuffer has always 1 sample. */ +	unsigned nsamples = track->is_resolve && i == 1 ? 1 : track->nsamples;  	size = radeon_bo_size(track->cb_color_bo[i]) - track->cb_color_bo_offset[i];  	format = G_0280A0_FORMAT(track->cb_color_info[i]); @@ -375,7 +386,7 @@ static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)  	array_check.group_size = track->group_size;  	array_check.nbanks = track->nbanks;  	array_check.npipes = track->npipes; -	array_check.nsamples = track->nsamples; +	array_check.nsamples = nsamples;  	array_check.blocksize = r600_fmt_get_blocksize(format);  	if (r600_get_array_mode_alignment(&array_check,  					  &pitch_align, &height_align, &depth_align, &base_align)) { @@ -421,7 +432,7 @@ static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)  	/* check offset */  	tmp = r600_fmt_get_nblocksy(format, height) * r600_fmt_get_nblocksx(format, pitch) * -	      r600_fmt_get_blocksize(format) * track->nsamples; +	      r600_fmt_get_blocksize(format) * nsamples;  	switch (array_mode) {  	default:  	case V_0280A0_ARRAY_LINEAR_GENERAL: @@ -792,6 +803,12 @@ static int r600_cs_track_check(struct radeon_cs_parser *p)  	 */  	if (track->cb_dirty) {  		tmp = track->cb_target_mask; + +		/* We must check both colorbuffers for RESOLVE. */ +		if (track->is_resolve) { +			tmp |= 0xff; +		} +  		for (i = 0; i < 8; i++) {  			if ((tmp >> (i * 4)) & 0xF) {  				/* at least one component is enabled */ @@ -1281,6 +1298,11 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)  		track->nsamples = 1 << tmp;  		track->cb_dirty = true;  		break; +	case R_028808_CB_COLOR_CONTROL: +		tmp = G_028808_SPECIAL_OP(radeon_get_ib_value(p, idx)); +		track->is_resolve = tmp == V_028808_SPECIAL_RESOLVE_BOX; +		track->cb_dirty = true; +		break;  	case R_0280A0_CB_COLOR0_INFO:  	case R_0280A4_CB_COLOR1_INFO:  	case R_0280A8_CB_COLOR2_INFO: @@ -1416,7 +1438,7 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)  	case R_028118_CB_COLOR6_MASK:  	case R_02811C_CB_COLOR7_MASK:  		tmp = (reg - R_028100_CB_COLOR0_MASK) / 4; -		track->cb_color_mask[tmp] = ib[idx]; +		track->cb_color_mask[tmp] = radeon_get_ib_value(p, idx);  		if (G_0280A0_TILE_MODE(track->cb_color_info[tmp])) {  			track->cb_dirty = true;  		} diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h index bdb69a63062..fa6f37099ba 100644 --- a/drivers/gpu/drm/radeon/r600d.h +++ b/drivers/gpu/drm/radeon/r600d.h @@ -66,6 +66,14 @@  #define	CC_RB_BACKEND_DISABLE				0x98F4  #define		BACKEND_DISABLE(x)				((x) << 16) +#define R_028808_CB_COLOR_CONTROL			0x28808 +#define   S_028808_SPECIAL_OP(x)                       (((x) & 0x7) << 4) +#define   G_028808_SPECIAL_OP(x)                       (((x) >> 4) & 0x7) +#define   C_028808_SPECIAL_OP                          0xFFFFFF8F +#define     V_028808_SPECIAL_NORMAL                     0x00 +#define     V_028808_SPECIAL_DISABLE                    0x01 +#define     V_028808_SPECIAL_RESOLVE_BOX                0x07 +  #define	CB_COLOR0_BASE					0x28040  #define	CB_COLOR1_BASE					0x28044  #define	CB_COLOR2_BASE					0x28048 diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index d2e243867ac..7a3daebd732 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c @@ -1051,7 +1051,7 @@ int radeon_device_init(struct radeon_device *rdev,  	if (rdev->flags & RADEON_IS_AGP)  		rdev->need_dma32 = true;  	if ((rdev->flags & RADEON_IS_PCI) && -	    (rdev->family < CHIP_RS400)) +	    (rdev->family <= CHIP_RS740))  		rdev->need_dma32 = true;  	dma_bits = rdev->need_dma32 ? 32 : 40; @@ -1346,12 +1346,15 @@ retry:  		for (i = 0; i < RADEON_NUM_RINGS; ++i) {  			radeon_ring_restore(rdev, &rdev->ring[i],  					    ring_sizes[i], ring_data[i]); +			ring_sizes[i] = 0; +			ring_data[i] = NULL;  		}  		r = radeon_ib_ring_tests(rdev);  		if (r) {  			dev_err(rdev->dev, "ib ring test failed (%d).\n", r);  			if (saved) { +				saved = false;  				radeon_suspend(rdev);  				goto retry;  			} diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 27d22d709c9..8c593ea82c4 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -63,9 +63,10 @@   *   2.19.0 - r600-eg: MSAA textures   *   2.20.0 - r600-si: RADEON_INFO_TIMESTAMP query   *   2.21.0 - r600-r700: FMASK and CMASK + *   2.22.0 - r600 only: RESOLVE_BOX allowed   */  #define KMS_DRIVER_MAJOR	2 -#define KMS_DRIVER_MINOR	21 +#define KMS_DRIVER_MINOR	22  #define KMS_DRIVER_PATCHLEVEL	0  int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags);  int radeon_driver_unload_kms(struct drm_device *dev); diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c index 7b737b9339a..2a59375dbe5 100644 --- a/drivers/gpu/drm/radeon/radeon_fence.c +++ b/drivers/gpu/drm/radeon/radeon_fence.c @@ -131,7 +131,7 @@ int radeon_fence_emit(struct radeon_device *rdev,   */  void radeon_fence_process(struct radeon_device *rdev, int ring)  { -	uint64_t seq, last_seq; +	uint64_t seq, last_seq, last_emitted;  	unsigned count_loop = 0;  	bool wake = false; @@ -158,13 +158,15 @@ void radeon_fence_process(struct radeon_device *rdev, int ring)  	 */  	last_seq = atomic64_read(&rdev->fence_drv[ring].last_seq);  	do { +		last_emitted = rdev->fence_drv[ring].sync_seq[ring];  		seq = radeon_fence_read(rdev, ring);  		seq |= last_seq & 0xffffffff00000000LL;  		if (seq < last_seq) { -			seq += 0x100000000LL; +			seq &= 0xffffffff; +			seq |= last_emitted & 0xffffffff00000000LL;  		} -		if (seq == last_seq) { +		if (seq <= last_seq || seq > last_emitted) {  			break;  		}  		/* If we loop over we don't want to return without diff --git a/drivers/gpu/drm/radeon/reg_srcs/r600 b/drivers/gpu/drm/radeon/reg_srcs/r600 index f93e45d869f..20bfbda7b3f 100644 --- a/drivers/gpu/drm/radeon/reg_srcs/r600 +++ b/drivers/gpu/drm/radeon/reg_srcs/r600 @@ -744,7 +744,6 @@ r600 0x9400  0x00028C38 CB_CLRCMP_DST  0x00028C3C CB_CLRCMP_MSK  0x00028C34 CB_CLRCMP_SRC -0x00028808 CB_COLOR_CONTROL  0x0002842C CB_FOG_BLUE  0x00028428 CB_FOG_GREEN  0x00028424 CB_FOG_RED diff --git a/drivers/gpu/drm/savage/savage_drv.c b/drivers/gpu/drm/savage/savage_drv.c index d31d4cca9a4..c5a164337bd 100644 --- a/drivers/gpu/drm/savage/savage_drv.c +++ b/drivers/gpu/drm/savage/savage_drv.c @@ -43,6 +43,9 @@ static const struct file_operations savage_driver_fops = {  	.mmap = drm_mmap,  	.poll = drm_poll,  	.fasync = drm_fasync, +#ifdef CONFIG_COMPAT +	.compat_ioctl = drm_compat_ioctl, +#endif  	.llseek = noop_llseek,  }; diff --git a/drivers/gpu/drm/sis/sis_drv.c b/drivers/gpu/drm/sis/sis_drv.c index 7f119870147..867dc03000e 100644 --- a/drivers/gpu/drm/sis/sis_drv.c +++ b/drivers/gpu/drm/sis/sis_drv.c @@ -74,6 +74,9 @@ static const struct file_operations sis_driver_fops = {  	.mmap = drm_mmap,  	.poll = drm_poll,  	.fasync = drm_fasync, +#ifdef CONFIG_COMPAT +	.compat_ioctl = drm_compat_ioctl, +#endif  	.llseek = noop_llseek,  }; diff --git a/drivers/gpu/drm/tdfx/tdfx_drv.c b/drivers/gpu/drm/tdfx/tdfx_drv.c index 90f6b13acfa..a7f4d6bd133 100644 --- a/drivers/gpu/drm/tdfx/tdfx_drv.c +++ b/drivers/gpu/drm/tdfx/tdfx_drv.c @@ -49,6 +49,9 @@ static const struct file_operations tdfx_driver_fops = {  	.mmap = drm_mmap,  	.poll = drm_poll,  	.fasync = drm_fasync, +#ifdef CONFIG_COMPAT +	.compat_ioctl = drm_compat_ioctl, +#endif  	.llseek = noop_llseek,  }; diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c index 6e52069894b..9f84128505b 100644 --- a/drivers/gpu/drm/udl/udl_drv.c +++ b/drivers/gpu/drm/udl/udl_drv.c @@ -66,6 +66,9 @@ static const struct file_operations udl_driver_fops = {  	.unlocked_ioctl	= drm_ioctl,  	.release = drm_release,  	.fasync = drm_fasync, +#ifdef CONFIG_COMPAT +	.compat_ioctl = drm_compat_ioctl, +#endif  	.llseek = noop_llseek,  }; diff --git a/drivers/gpu/drm/via/via_drv.c b/drivers/gpu/drm/via/via_drv.c index e927b4c052f..af1b914b17e 100644 --- a/drivers/gpu/drm/via/via_drv.c +++ b/drivers/gpu/drm/via/via_drv.c @@ -65,6 +65,9 @@ static const struct file_operations via_driver_fops = {  	.mmap = drm_mmap,  	.poll = drm_poll,  	.fasync = drm_fasync, +#ifdef CONFIG_COMPAT +	.compat_ioctl = drm_compat_ioctl, +#endif  	.llseek = noop_llseek,  }; diff --git a/drivers/gpu/drm/vmwgfx/Kconfig b/drivers/gpu/drm/vmwgfx/Kconfig index 794ff67c570..b71bcd0bfbb 100644 --- a/drivers/gpu/drm/vmwgfx/Kconfig +++ b/drivers/gpu/drm/vmwgfx/Kconfig @@ -12,3 +12,11 @@ config DRM_VMWGFX  	  This is a KMS enabled DRM driver for the VMware SVGA2  	  virtual hardware.  	  The compiled module will be called "vmwgfx.ko". + +config DRM_VMWGFX_FBCON +	depends on DRM_VMWGFX +	bool "Enable framebuffer console under vmwgfx by default" +	help +	   Choose this option if you are shipping a new vmwgfx +	   userspace driver that supports using the kernel driver. + diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index 4d9edead01a..ba2c35dbf10 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c @@ -182,8 +182,9 @@ static struct pci_device_id vmw_pci_id_list[] = {  	{0x15ad, 0x0405, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VMWGFX_CHIP_SVGAII},  	{0, 0, 0}  }; +MODULE_DEVICE_TABLE(pci, vmw_pci_id_list); -static int enable_fbdev; +static int enable_fbdev = IS_ENABLED(CONFIG_DRM_VMWGFX_FBCON);  static int vmw_probe(struct pci_dev *, const struct pci_device_id *);  static void vmw_master_init(struct vmw_master *); @@ -1154,6 +1155,11 @@ static struct drm_driver driver = {  	.open = vmw_driver_open,  	.preclose = vmw_preclose,  	.postclose = vmw_postclose, + +	.dumb_create = vmw_dumb_create, +	.dumb_map_offset = vmw_dumb_map_offset, +	.dumb_destroy = vmw_dumb_destroy, +  	.fops = &vmwgfx_driver_fops,  	.name = VMWGFX_DRIVER_NAME,  	.desc = VMWGFX_DRIVER_DESC, diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index d0f2c079ee2..29c984ff7f2 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h @@ -645,6 +645,16 @@ int vmw_kms_readback(struct vmw_private *dev_priv,  int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data,  				struct drm_file *file_priv); +int vmw_dumb_create(struct drm_file *file_priv, +		    struct drm_device *dev, +		    struct drm_mode_create_dumb *args); + +int vmw_dumb_map_offset(struct drm_file *file_priv, +			struct drm_device *dev, uint32_t handle, +			uint64_t *offset); +int vmw_dumb_destroy(struct drm_file *file_priv, +		     struct drm_device *dev, +		     uint32_t handle);  /**   * Overlay control - vmwgfx_overlay.c   */ diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c index 22bf9a21ec7..2c6ffe0e2c0 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c @@ -1917,3 +1917,76 @@ err_ref:  	vmw_resource_unreference(&res);  	return ret;  } + + +int vmw_dumb_create(struct drm_file *file_priv, +		    struct drm_device *dev, +		    struct drm_mode_create_dumb *args) +{ +	struct vmw_private *dev_priv = vmw_priv(dev); +	struct vmw_master *vmaster = vmw_master(file_priv->master); +	struct vmw_user_dma_buffer *vmw_user_bo; +	struct ttm_buffer_object *tmp; +	int ret; + +	args->pitch = args->width * ((args->bpp + 7) / 8); +	args->size = args->pitch * args->height; + +	vmw_user_bo = kzalloc(sizeof(*vmw_user_bo), GFP_KERNEL); +	if (vmw_user_bo == NULL) +		return -ENOMEM; + +	ret = ttm_read_lock(&vmaster->lock, true); +	if (ret != 0) { +		kfree(vmw_user_bo); +		return ret; +	} + +	ret = vmw_dmabuf_init(dev_priv, &vmw_user_bo->dma, args->size, +			      &vmw_vram_sys_placement, true, +			      &vmw_user_dmabuf_destroy); +	if (ret != 0) +		goto out_no_dmabuf; + +	tmp = ttm_bo_reference(&vmw_user_bo->dma.base); +	ret = ttm_base_object_init(vmw_fpriv(file_priv)->tfile, +				   &vmw_user_bo->base, +				   false, +				   ttm_buffer_type, +				   &vmw_user_dmabuf_release, NULL); +	if (unlikely(ret != 0)) +		goto out_no_base_object; + +	args->handle = vmw_user_bo->base.hash.key; + +out_no_base_object: +	ttm_bo_unref(&tmp); +out_no_dmabuf: +	ttm_read_unlock(&vmaster->lock); +	return ret; +} + +int vmw_dumb_map_offset(struct drm_file *file_priv, +			struct drm_device *dev, uint32_t handle, +			uint64_t *offset) +{ +	struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile; +	struct vmw_dma_buffer *out_buf; +	int ret; + +	ret = vmw_user_dmabuf_lookup(tfile, handle, &out_buf); +	if (ret != 0) +		return -EINVAL; + +	*offset = out_buf->base.addr_space_offset; +	vmw_dmabuf_unreference(&out_buf); +	return 0; +} + +int vmw_dumb_destroy(struct drm_file *file_priv, +		     struct drm_device *dev, +		     uint32_t handle) +{ +	return ttm_ref_object_base_unref(vmw_fpriv(file_priv)->tfile, +					 handle, TTM_REF_USAGE); +} diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 60ea284407c..8bcd168fffa 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -996,7 +996,8 @@ static void hid_process_event(struct hid_device *hid, struct hid_field *field,  	struct hid_driver *hdrv = hid->driver;  	int ret; -	hid_dump_input(hid, usage, value); +	if (!list_empty(&hid->debug_list)) +		hid_dump_input(hid, usage, value);  	if (hdrv && hdrv->event && hid_match_usage(hid, usage)) {  		ret = hdrv->event(hid, field, usage, value); @@ -1558,7 +1559,9 @@ static const struct hid_device_id hid_have_special_driver[] = {  	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M610X) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_LCPOWER, USB_DEVICE_ID_LCPOWER_LC1000 ) }, - 	{ HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_TPKBD) }, +#if IS_ENABLED(CONFIG_HID_LENOVO_TPKBD) +	{ HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_TPKBD) }, +#endif  	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER_2) }, @@ -1624,7 +1627,6 @@ static const struct hid_device_id hid_have_special_driver[] = {  	{ HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_WKB2000) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_KEYBOARD) }, -	{ HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONE) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_ARVO) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_ISKU) }, diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c index 0f9c146fc00..4d524b5f52f 100644 --- a/drivers/hid/hid-logitech-dj.c +++ b/drivers/hid/hid-logitech-dj.c @@ -439,7 +439,7 @@ static int logi_dj_recv_query_paired_devices(struct dj_receiver_dev *djrcv_dev)  	struct dj_report *dj_report;  	int retval; -	dj_report = kzalloc(sizeof(dj_report), GFP_KERNEL); +	dj_report = kzalloc(sizeof(struct dj_report), GFP_KERNEL);  	if (!dj_report)  		return -ENOMEM;  	dj_report->report_id = REPORT_ID_DJ_SHORT; @@ -456,7 +456,7 @@ static int logi_dj_recv_switch_to_dj_mode(struct dj_receiver_dev *djrcv_dev,  	struct dj_report *dj_report;  	int retval; -	dj_report = kzalloc(sizeof(dj_report), GFP_KERNEL); +	dj_report = kzalloc(sizeof(struct dj_report), GFP_KERNEL);  	if (!dj_report)  		return -ENOMEM;  	dj_report->report_id = REPORT_ID_DJ_SHORT; diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index 903eef3d3e1..991e85c7325 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c @@ -70,6 +70,7 @@ static const struct hid_blacklist {  	{ USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_AXIS_295, HID_QUIRK_NOGET },  	{ USB_VENDOR_ID_DMI, USB_DEVICE_ID_DMI_ENC, HID_QUIRK_NOGET },  	{ USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700, HID_QUIRK_NOGET }, +	{ USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_NOGET },  	{ USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN, HID_QUIRK_NO_INIT_REPORTS },  	{ USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN1, HID_QUIRK_NO_INIT_REPORTS },  	{ USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN2, HID_QUIRK_NO_INIT_REPORTS }, diff --git a/drivers/hwmon/asus_atk0110.c b/drivers/hwmon/asus_atk0110.c index 351d1f4593e..4ee57894872 100644 --- a/drivers/hwmon/asus_atk0110.c +++ b/drivers/hwmon/asus_atk0110.c @@ -34,6 +34,12 @@ static const struct dmi_system_id __initconst atk_force_new_if[] = {  		.matches = {  			DMI_MATCH(DMI_BOARD_NAME, "SABERTOOTH X58")  		} +	}, { +		/* Old interface reads the same sensor for fan0 and fan1 */ +		.ident = "Asus M5A78L", +		.matches = { +			DMI_MATCH(DMI_BOARD_NAME, "M5A78L") +		}  	},  	{ }  }; diff --git a/drivers/hwmon/ina2xx.c b/drivers/hwmon/ina2xx.c index 7f3f4a38572..602148299f6 100644 --- a/drivers/hwmon/ina2xx.c +++ b/drivers/hwmon/ina2xx.c @@ -69,22 +69,6 @@ struct ina2xx_data {  	u16 regs[INA2XX_MAX_REGISTERS];  }; -int ina2xx_read_word(struct i2c_client *client, int reg) -{ -	int val = i2c_smbus_read_word_data(client, reg); -	if (unlikely(val < 0)) { -		dev_dbg(&client->dev, -			"Failed to read register: %d\n", reg); -		return val; -	} -	return be16_to_cpu(val); -} - -void ina2xx_write_word(struct i2c_client *client, int reg, int data) -{ -	i2c_smbus_write_word_data(client, reg, cpu_to_be16(data)); -} -  static struct ina2xx_data *ina2xx_update_device(struct device *dev)  {  	struct i2c_client *client = to_i2c_client(dev); @@ -102,7 +86,7 @@ static struct ina2xx_data *ina2xx_update_device(struct device *dev)  		/* Read all registers */  		for (i = 0; i < data->registers; i++) { -			int rv = ina2xx_read_word(client, i); +			int rv = i2c_smbus_read_word_swapped(client, i);  			if (rv < 0) {  				ret = ERR_PTR(rv);  				goto abort; @@ -279,22 +263,26 @@ static int ina2xx_probe(struct i2c_client *client,  	switch (data->kind) {  	case ina219:  		/* device configuration */ -		ina2xx_write_word(client, INA2XX_CONFIG, INA219_CONFIG_DEFAULT); +		i2c_smbus_write_word_swapped(client, INA2XX_CONFIG, +					     INA219_CONFIG_DEFAULT);  		/* set current LSB to 1mA, shunt is in uOhms */  		/* (equation 13 in datasheet) */ -		ina2xx_write_word(client, INA2XX_CALIBRATION, 40960000 / shunt); +		i2c_smbus_write_word_swapped(client, INA2XX_CALIBRATION, +					     40960000 / shunt);  		dev_info(&client->dev,  			 "power monitor INA219 (Rshunt = %li uOhm)\n", shunt);  		data->registers = INA219_REGISTERS;  		break;  	case ina226:  		/* device configuration */ -		ina2xx_write_word(client, INA2XX_CONFIG, INA226_CONFIG_DEFAULT); +		i2c_smbus_write_word_swapped(client, INA2XX_CONFIG, +					     INA226_CONFIG_DEFAULT);  		/* set current LSB to 1mA, shunt is in uOhms */  		/* (equation 1 in datasheet)*/ -		ina2xx_write_word(client, INA2XX_CALIBRATION, 5120000 / shunt); +		i2c_smbus_write_word_swapped(client, INA2XX_CALIBRATION, +					     5120000 / shunt);  		dev_info(&client->dev,  			 "power monitor INA226 (Rshunt = %li uOhm)\n", shunt);  		data->registers = INA226_REGISTERS; diff --git a/drivers/hwmon/twl4030-madc-hwmon.c b/drivers/hwmon/twl4030-madc-hwmon.c index 0018c7dd009..1a174f0a3cd 100644 --- a/drivers/hwmon/twl4030-madc-hwmon.c +++ b/drivers/hwmon/twl4030-madc-hwmon.c @@ -44,12 +44,13 @@ static ssize_t madc_read(struct device *dev,  			 struct device_attribute *devattr, char *buf)  {  	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); -	struct twl4030_madc_request req; +	struct twl4030_madc_request req = { +		.channels = 1 << attr->index, +		.method = TWL4030_MADC_SW2, +		.type = TWL4030_MADC_WAIT, +	};  	long val; -	req.channels = (1 << attr->index); -	req.method = TWL4030_MADC_SW2; -	req.func_cb = NULL;  	val = twl4030_madc_conversion(&req);  	if (val < 0)  		return val; diff --git a/drivers/i2c/algos/i2c-algo-pca.c b/drivers/i2c/algos/i2c-algo-pca.c index 73133b1063f..6f5f98d69af 100644 --- a/drivers/i2c/algos/i2c-algo-pca.c +++ b/drivers/i2c/algos/i2c-algo-pca.c @@ -476,17 +476,17 @@ static int pca_init(struct i2c_adapter *adap)  		/* To avoid integer overflow, use clock/100 for calculations */  		clock = pca_clock(pca_data) / 100; -		if (pca_data->i2c_clock > 10000) { +		if (pca_data->i2c_clock > 1000000) {  			mode = I2C_PCA_MODE_TURBO;  			min_tlow = 14;  			min_thi  = 5;  			raise_fall_time = 22; /* Raise 11e-8s, Fall 11e-8s */ -		} else if (pca_data->i2c_clock > 4000) { +		} else if (pca_data->i2c_clock > 400000) {  			mode = I2C_PCA_MODE_FASTP;  			min_tlow = 17;  			min_thi  = 9;  			raise_fall_time = 22; /* Raise 11e-8s, Fall 11e-8s */ -		} else if (pca_data->i2c_clock > 1000) { +		} else if (pca_data->i2c_clock > 100000) {  			mode = I2C_PCA_MODE_FAST;  			min_tlow = 44;  			min_thi  = 20; diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index b4aaa1bd672..970a1612e79 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -104,6 +104,7 @@ config I2C_I801  	    DH89xxCC (PCH)  	    Panther Point (PCH)  	    Lynx Point (PCH) +	    Lynx Point-LP (PCH)  	  This driver can also be built as a module.  If so, the module  	  will be called i2c-i801. @@ -354,9 +355,13 @@ config I2C_DAVINCI  	  devices such as DaVinci NIC.  	  For details please see http://www.ti.com/davinci +config I2C_DESIGNWARE_CORE +	tristate +  config I2C_DESIGNWARE_PLATFORM  	tristate "Synopsys DesignWare Platform"  	depends on HAVE_CLK +	select I2C_DESIGNWARE_CORE  	help  	  If you say yes to this option, support will be included for the  	  Synopsys DesignWare I2C adapter. Only master mode is supported. @@ -367,6 +372,7 @@ config I2C_DESIGNWARE_PLATFORM  config I2C_DESIGNWARE_PCI  	tristate "Synopsys DesignWare PCI"  	depends on PCI +	select I2C_DESIGNWARE_CORE  	help  	  If you say yes to this option, support will be included for the  	  Synopsys DesignWare I2C adapter. Only master mode is supported. diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile index ce3c2be7fb4..37c4182cc98 100644 --- a/drivers/i2c/busses/Makefile +++ b/drivers/i2c/busses/Makefile @@ -33,10 +33,11 @@ obj-$(CONFIG_I2C_AU1550)	+= i2c-au1550.o  obj-$(CONFIG_I2C_BLACKFIN_TWI)	+= i2c-bfin-twi.o  obj-$(CONFIG_I2C_CPM)		+= i2c-cpm.o  obj-$(CONFIG_I2C_DAVINCI)	+= i2c-davinci.o +obj-$(CONFIG_I2C_DESIGNWARE_CORE)	+= i2c-designware-core.o  obj-$(CONFIG_I2C_DESIGNWARE_PLATFORM)	+= i2c-designware-platform.o -i2c-designware-platform-objs := i2c-designware-platdrv.o i2c-designware-core.o +i2c-designware-platform-objs := i2c-designware-platdrv.o  obj-$(CONFIG_I2C_DESIGNWARE_PCI)	+= i2c-designware-pci.o -i2c-designware-pci-objs := i2c-designware-pcidrv.o i2c-designware-core.o +i2c-designware-pci-objs := i2c-designware-pcidrv.o  obj-$(CONFIG_I2C_EG20T)		+= i2c-eg20t.o  obj-$(CONFIG_I2C_GPIO)		+= i2c-gpio.o  obj-$(CONFIG_I2C_HIGHLANDER)	+= i2c-highlander.o diff --git a/drivers/i2c/busses/i2c-designware-core.c b/drivers/i2c/busses/i2c-designware-core.c index 1e48bec80ed..7b8ebbefb58 100644 --- a/drivers/i2c/busses/i2c-designware-core.c +++ b/drivers/i2c/busses/i2c-designware-core.c @@ -25,6 +25,7 @@   * ----------------------------------------------------------------------------   *   */ +#include <linux/export.h>  #include <linux/clk.h>  #include <linux/errno.h>  #include <linux/err.h> @@ -316,6 +317,7 @@ int i2c_dw_init(struct dw_i2c_dev *dev)  	dw_writel(dev, dev->master_cfg , DW_IC_CON);  	return 0;  } +EXPORT_SYMBOL_GPL(i2c_dw_init);  /*   * Waiting for bus not busy @@ -568,12 +570,14 @@ done:  	return ret;  } +EXPORT_SYMBOL_GPL(i2c_dw_xfer);  u32 i2c_dw_func(struct i2c_adapter *adap)  {  	struct dw_i2c_dev *dev = i2c_get_adapdata(adap);  	return dev->functionality;  } +EXPORT_SYMBOL_GPL(i2c_dw_func);  static u32 i2c_dw_read_clear_intrbits(struct dw_i2c_dev *dev)  { @@ -678,17 +682,20 @@ tx_aborted:  	return IRQ_HANDLED;  } +EXPORT_SYMBOL_GPL(i2c_dw_isr);  void i2c_dw_enable(struct dw_i2c_dev *dev)  {         /* Enable the adapter */  	dw_writel(dev, 1, DW_IC_ENABLE);  } +EXPORT_SYMBOL_GPL(i2c_dw_enable);  u32 i2c_dw_is_enabled(struct dw_i2c_dev *dev)  {  	return dw_readl(dev, DW_IC_ENABLE);  } +EXPORT_SYMBOL_GPL(i2c_dw_is_enabled);  void i2c_dw_disable(struct dw_i2c_dev *dev)  { @@ -699,18 +706,22 @@ void i2c_dw_disable(struct dw_i2c_dev *dev)  	dw_writel(dev, 0, DW_IC_INTR_MASK);  	dw_readl(dev, DW_IC_CLR_INTR);  } +EXPORT_SYMBOL_GPL(i2c_dw_disable);  void i2c_dw_clear_int(struct dw_i2c_dev *dev)  {  	dw_readl(dev, DW_IC_CLR_INTR);  } +EXPORT_SYMBOL_GPL(i2c_dw_clear_int);  void i2c_dw_disable_int(struct dw_i2c_dev *dev)  {  	dw_writel(dev, 0, DW_IC_INTR_MASK);  } +EXPORT_SYMBOL_GPL(i2c_dw_disable_int);  u32 i2c_dw_read_comp_param(struct dw_i2c_dev *dev)  {  	return dw_readl(dev, DW_IC_COMP_PARAM_1);  } +EXPORT_SYMBOL_GPL(i2c_dw_read_comp_param); diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index 898dcf9c7ad..33e9b0c09af 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c @@ -52,6 +52,7 @@    DH89xxCC (PCH)        0x2330     32     hard     yes     yes     yes    Panther Point (PCH)   0x1e22     32     hard     yes     yes     yes    Lynx Point (PCH)      0x8c22     32     hard     yes     yes     yes +  Lynx Point-LP (PCH)   0x9c22     32     hard     yes     yes     yes    Features supported by this driver:    Software PEC                     no @@ -155,6 +156,7 @@  #define PCI_DEVICE_ID_INTEL_DH89XXCC_SMBUS	0x2330  #define PCI_DEVICE_ID_INTEL_5_3400_SERIES_SMBUS	0x3b30  #define PCI_DEVICE_ID_INTEL_LYNXPOINT_SMBUS	0x8c22 +#define PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_SMBUS	0x9c22  struct i801_priv {  	struct i2c_adapter adapter; @@ -771,6 +773,7 @@ static DEFINE_PCI_DEVICE_TABLE(i801_ids) = {  	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_DH89XXCC_SMBUS) },  	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PANTHERPOINT_SMBUS) },  	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LYNXPOINT_SMBUS) }, +	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_SMBUS) },  	{ 0, }  }; diff --git a/drivers/i2c/busses/i2c-mxs.c b/drivers/i2c/busses/i2c-mxs.c index 088c5c1ed17..51f05b8520e 100644 --- a/drivers/i2c/busses/i2c-mxs.c +++ b/drivers/i2c/busses/i2c-mxs.c @@ -365,10 +365,6 @@ static int mxs_i2c_get_ofdata(struct mxs_i2c_dev *i2c)  	struct device_node *node = dev->of_node;  	int ret; -	if (!node) -		return -EINVAL; - -	i2c->speed = &mxs_i2c_95kHz_config;  	ret = of_property_read_u32(node, "clock-frequency", &speed);  	if (ret)  		dev_warn(dev, "No I2C speed selected, using 100kHz\n"); @@ -419,10 +415,13 @@ static int __devinit mxs_i2c_probe(struct platform_device *pdev)  		return err;  	i2c->dev = dev; +	i2c->speed = &mxs_i2c_95kHz_config; -	err = mxs_i2c_get_ofdata(i2c); -	if (err) -		return err; +	if (dev->of_node) { +		err = mxs_i2c_get_ofdata(i2c); +		if (err) +			return err; +	}  	platform_set_drvdata(pdev, i2c); diff --git a/drivers/i2c/busses/i2c-pnx.c b/drivers/i2c/busses/i2c-pnx.c index 5d54416770b..8488bddfe46 100644 --- a/drivers/i2c/busses/i2c-pnx.c +++ b/drivers/i2c/busses/i2c-pnx.c @@ -48,8 +48,9 @@ enum {  	mcntrl_afie = 0x00000002,  	mcntrl_naie = 0x00000004,  	mcntrl_drmie = 0x00000008, -	mcntrl_daie = 0x00000020, -	mcntrl_rffie = 0x00000040, +	mcntrl_drsie = 0x00000010, +	mcntrl_rffie = 0x00000020, +	mcntrl_daie = 0x00000040,  	mcntrl_tffie = 0x00000080,  	mcntrl_reset = 0x00000100,  	mcntrl_cdbmode = 0x00000400, @@ -290,31 +291,37 @@ static int i2c_pnx_master_rcv(struct i2c_pnx_algo_data *alg_data)  	 * or we didn't 'ask' for it yet.  	 */  	if (ioread32(I2C_REG_STS(alg_data)) & mstatus_rfe) { -		dev_dbg(&alg_data->adapter.dev, -			"%s(): Write dummy data to fill Rx-fifo...\n", -			__func__); +		/* 'Asking' is done asynchronously, e.g. dummy TX of several +		 * bytes is done before the first actual RX arrives in FIFO. +		 * Therefore, ordered bytes (via TX) are counted separately. +		 */ +		if (alg_data->mif.order) { +			dev_dbg(&alg_data->adapter.dev, +				"%s(): Write dummy data to fill Rx-fifo...\n", +				__func__); -		if (alg_data->mif.len == 1) { -			/* Last byte, do not acknowledge next rcv. */ -			val |= stop_bit; +			if (alg_data->mif.order == 1) { +				/* Last byte, do not acknowledge next rcv. */ +				val |= stop_bit; + +				/* +				 * Enable interrupt RFDAIE (data in Rx fifo), +				 * and disable DRMIE (need data for Tx) +				 */ +				ctl = ioread32(I2C_REG_CTL(alg_data)); +				ctl |= mcntrl_rffie | mcntrl_daie; +				ctl &= ~mcntrl_drmie; +				iowrite32(ctl, I2C_REG_CTL(alg_data)); +			}  			/* -			 * Enable interrupt RFDAIE (data in Rx fifo), -			 * and disable DRMIE (need data for Tx) +			 * Now we'll 'ask' for data: +			 * For each byte we want to receive, we must +			 * write a (dummy) byte to the Tx-FIFO.  			 */ -			ctl = ioread32(I2C_REG_CTL(alg_data)); -			ctl |= mcntrl_rffie | mcntrl_daie; -			ctl &= ~mcntrl_drmie; -			iowrite32(ctl, I2C_REG_CTL(alg_data)); +			iowrite32(val, I2C_REG_TX(alg_data)); +			alg_data->mif.order--;  		} - -		/* -		 * Now we'll 'ask' for data: -		 * For each byte we want to receive, we must -		 * write a (dummy) byte to the Tx-FIFO. -		 */ -		iowrite32(val, I2C_REG_TX(alg_data)); -  		return 0;  	} @@ -514,6 +521,7 @@ i2c_pnx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)  		alg_data->mif.buf = pmsg->buf;  		alg_data->mif.len = pmsg->len; +		alg_data->mif.order = pmsg->len;  		alg_data->mif.mode = (pmsg->flags & I2C_M_RD) ?  			I2C_SMBUS_READ : I2C_SMBUS_WRITE;  		alg_data->mif.ret = 0; @@ -566,6 +574,7 @@ i2c_pnx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)  	/* Cleanup to be sure... */  	alg_data->mif.buf = NULL;  	alg_data->mif.len = 0; +	alg_data->mif.order = 0;  	dev_dbg(&alg_data->adapter.dev, "%s(): exiting, stat = %x\n",  		__func__, ioread32(I2C_REG_STS(alg_data))); diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 2efa56c5ff2..2091ae8f539 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -637,6 +637,22 @@ static void i2c_adapter_dev_release(struct device *dev)  }  /* + * This function is only needed for mutex_lock_nested, so it is never + * called unless locking correctness checking is enabled. Thus we + * make it inline to avoid a compiler warning. That's what gcc ends up + * doing anyway. + */ +static inline unsigned int i2c_adapter_depth(struct i2c_adapter *adapter) +{ +	unsigned int depth = 0; + +	while ((adapter = i2c_parent_is_i2c_adapter(adapter))) +		depth++; + +	return depth; +} + +/*   * Let users instantiate I2C devices through sysfs. This can be used when   * platform initialization code doesn't contain the proper data for   * whatever reason. Also useful for drivers that do device detection and @@ -726,7 +742,8 @@ i2c_sysfs_delete_device(struct device *dev, struct device_attribute *attr,  	/* Make sure the device was added through sysfs */  	res = -ENOENT; -	mutex_lock(&adap->userspace_clients_lock); +	mutex_lock_nested(&adap->userspace_clients_lock, +			  i2c_adapter_depth(adap));  	list_for_each_entry_safe(client, next, &adap->userspace_clients,  				 detected) {  		if (client->addr == addr) { @@ -1073,7 +1090,8 @@ int i2c_del_adapter(struct i2c_adapter *adap)  		return res;  	/* Remove devices instantiated from sysfs */ -	mutex_lock(&adap->userspace_clients_lock); +	mutex_lock_nested(&adap->userspace_clients_lock, +			  i2c_adapter_depth(adap));  	list_for_each_entry_safe(client, next, &adap->userspace_clients,  				 detected) {  		dev_dbg(&adap->dev, "Removing %s at 0x%x\n", client->name, diff --git a/drivers/ide/ide-pm.c b/drivers/ide/ide-pm.c index 92406097efe..8d1e32d7cd9 100644 --- a/drivers/ide/ide-pm.c +++ b/drivers/ide/ide-pm.c @@ -4,7 +4,7 @@  int generic_ide_suspend(struct device *dev, pm_message_t mesg)  { -	ide_drive_t *drive = dev_get_drvdata(dev); +	ide_drive_t *drive = to_ide_device(dev);  	ide_drive_t *pair = ide_get_pair_dev(drive);  	ide_hwif_t *hwif = drive->hwif;  	struct request *rq; @@ -40,7 +40,7 @@ int generic_ide_suspend(struct device *dev, pm_message_t mesg)  int generic_ide_resume(struct device *dev)  { -	ide_drive_t *drive = dev_get_drvdata(dev); +	ide_drive_t *drive = to_ide_device(dev);  	ide_drive_t *pair = ide_get_pair_dev(drive);  	ide_hwif_t *hwif = drive->hwif;  	struct request *rq; diff --git a/drivers/iio/adc/at91_adc.c b/drivers/iio/adc/at91_adc.c index f61780a0237..3bd5540238a 100644 --- a/drivers/iio/adc/at91_adc.c +++ b/drivers/iio/adc/at91_adc.c @@ -617,7 +617,7 @@ static int __devinit at91_adc_probe(struct platform_device *pdev)  	st->adc_clk = clk_get(&pdev->dev, "adc_op_clk");  	if (IS_ERR(st->adc_clk)) {  		dev_err(&pdev->dev, "Failed to get the ADC clock.\n"); -		ret = PTR_ERR(st->clk); +		ret = PTR_ERR(st->adc_clk);  		goto error_disable_clk;  	} diff --git a/drivers/input/keyboard/imx_keypad.c b/drivers/input/keyboard/imx_keypad.c index ff4c0a87a25..ce68e361558 100644 --- a/drivers/input/keyboard/imx_keypad.c +++ b/drivers/input/keyboard/imx_keypad.c @@ -358,6 +358,7 @@ static void imx_keypad_inhibit(struct imx_keypad *keypad)  	/* Inhibit KDI and KRI interrupts. */  	reg_val = readw(keypad->mmio_base + KPSR);  	reg_val &= ~(KBD_STAT_KRIE | KBD_STAT_KDIE); +	reg_val |= KBD_STAT_KPKR | KBD_STAT_KPKD;  	writew(reg_val, keypad->mmio_base + KPSR);  	/* Colums as open drain and disable all rows */ @@ -515,7 +516,9 @@ static int __devinit imx_keypad_probe(struct platform_device *pdev)  	input_set_drvdata(input_dev, keypad);  	/* Ensure that the keypad will stay dormant until opened */ +	clk_enable(keypad->clk);  	imx_keypad_inhibit(keypad); +	clk_disable(keypad->clk);  	error = request_irq(irq, imx_keypad_irq_handler, 0,  			    pdev->name, keypad); diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index 5ec774d6c82..6918773ce02 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h @@ -177,6 +177,20 @@ static const struct dmi_system_id __initconst i8042_dmi_noloop_table[] = {  		},  	},  	{ +		/* Gigabyte T1005 - defines wrong chassis type ("Other") */ +		.matches = { +			DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"), +			DMI_MATCH(DMI_PRODUCT_NAME, "T1005"), +		}, +	}, +	{ +		/* Gigabyte T1005M/P - defines wrong chassis type ("Other") */ +		.matches = { +			DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"), +			DMI_MATCH(DMI_PRODUCT_NAME, "T1005M/P"), +		}, +	}, +	{  		.matches = {  			DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),  			DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv9700"), diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c index 002041975de..532d067a9e0 100644 --- a/drivers/input/tablet/wacom_wac.c +++ b/drivers/input/tablet/wacom_wac.c @@ -1848,7 +1848,10 @@ static const struct wacom_features wacom_features_0x2A =  	{ "Wacom Intuos5 M", WACOM_PKGLEN_INTUOS,  44704, 27940, 2047,  	  63, INTUOS5, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };  static const struct wacom_features wacom_features_0xF4 = -	{ "Wacom Cintiq 24HD",    WACOM_PKGLEN_INTUOS,   104480, 65600, 2047, +	{ "Wacom Cintiq 24HD",       WACOM_PKGLEN_INTUOS,   104480, 65600, 2047, +	  63, WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; +static const struct wacom_features wacom_features_0xF8 = +	{ "Wacom Cintiq 24HD touch", WACOM_PKGLEN_INTUOS,   104480, 65600, 2047,  	  63, WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };  static const struct wacom_features wacom_features_0x3F =  	{ "Wacom Cintiq 21UX",    WACOM_PKGLEN_INTUOS,    87200, 65600, 1023, @@ -2091,6 +2094,7 @@ const struct usb_device_id wacom_ids[] = {  	{ USB_DEVICE_WACOM(0xEF) },  	{ USB_DEVICE_WACOM(0x47) },  	{ USB_DEVICE_WACOM(0xF4) }, +	{ USB_DEVICE_WACOM(0xF8) },  	{ USB_DEVICE_WACOM(0xFA) },  	{ USB_DEVICE_LENOVO(0x6004) },  	{ } diff --git a/drivers/input/touchscreen/edt-ft5x06.c b/drivers/input/touchscreen/edt-ft5x06.c index 9afc777a40a..b06a5e3a665 100644 --- a/drivers/input/touchscreen/edt-ft5x06.c +++ b/drivers/input/touchscreen/edt-ft5x06.c @@ -602,6 +602,7 @@ edt_ft5x06_ts_teardown_debugfs(struct edt_ft5x06_ts_data *tsdata)  {  	if (tsdata->debug_dir)  		debugfs_remove_recursive(tsdata->debug_dir); +	kfree(tsdata->raw_buffer);  }  #else @@ -843,7 +844,6 @@ static int __devexit edt_ft5x06_ts_remove(struct i2c_client *client)  	if (gpio_is_valid(pdata->reset_pin))  		gpio_free(pdata->reset_pin); -	kfree(tsdata->raw_buffer);  	kfree(tsdata);  	return 0; diff --git a/drivers/isdn/hardware/mISDN/avmfritz.c b/drivers/isdn/hardware/mISDN/avmfritz.c index fa6ca473372..dceaec821b0 100644 --- a/drivers/isdn/hardware/mISDN/avmfritz.c +++ b/drivers/isdn/hardware/mISDN/avmfritz.c @@ -857,8 +857,9 @@ avm_bctrl(struct mISDNchannel *ch, u32 cmd, void *arg)  	switch (cmd) {  	case CLOSE_CHANNEL:  		test_and_clear_bit(FLG_OPEN, &bch->Flags); +		cancel_work_sync(&bch->workq);  		spin_lock_irqsave(&fc->lock, flags); -		mISDN_freebchannel(bch); +		mISDN_clear_bchannel(bch);  		modehdlc(bch, ISDN_P_NONE);  		spin_unlock_irqrestore(&fc->lock, flags);  		ch->protocol = ISDN_P_NONE; diff --git a/drivers/isdn/hardware/mISDN/hfcmulti.c b/drivers/isdn/hardware/mISDN/hfcmulti.c index 5e402cf2e79..f02794203bb 100644 --- a/drivers/isdn/hardware/mISDN/hfcmulti.c +++ b/drivers/isdn/hardware/mISDN/hfcmulti.c @@ -5059,6 +5059,7 @@ hfcmulti_init(struct hm_map *m, struct pci_dev *pdev,  				printk(KERN_INFO  				       "HFC-E1 #%d has overlapping B-channels on fragment #%d\n",  				       E1_cnt + 1, pt); +				kfree(hc);  				return -EINVAL;  			}  			maskcheck |= hc->bmask[pt]; @@ -5086,6 +5087,7 @@ hfcmulti_init(struct hm_map *m, struct pci_dev *pdev,  	if ((poll >> 1) > sizeof(hc->silence_data)) {  		printk(KERN_ERR "HFCMULTI error: silence_data too small, "  		       "please fix\n"); +		kfree(hc);  		return -EINVAL;  	}  	for (i = 0; i < (poll >> 1); i++) diff --git a/drivers/isdn/hardware/mISDN/mISDNipac.c b/drivers/isdn/hardware/mISDN/mISDNipac.c index 752e0825591..ccd7d851be2 100644 --- a/drivers/isdn/hardware/mISDN/mISDNipac.c +++ b/drivers/isdn/hardware/mISDN/mISDNipac.c @@ -1406,8 +1406,9 @@ hscx_bctrl(struct mISDNchannel *ch, u32 cmd, void *arg)  	switch (cmd) {  	case CLOSE_CHANNEL:  		test_and_clear_bit(FLG_OPEN, &bch->Flags); +		cancel_work_sync(&bch->workq);  		spin_lock_irqsave(hx->ip->hwlock, flags); -		mISDN_freebchannel(bch); +		mISDN_clear_bchannel(bch);  		hscx_mode(hx, ISDN_P_NONE);  		spin_unlock_irqrestore(hx->ip->hwlock, flags);  		ch->protocol = ISDN_P_NONE; diff --git a/drivers/isdn/hardware/mISDN/mISDNisar.c b/drivers/isdn/hardware/mISDN/mISDNisar.c index be5973ded6d..182ecf0626c 100644 --- a/drivers/isdn/hardware/mISDN/mISDNisar.c +++ b/drivers/isdn/hardware/mISDN/mISDNisar.c @@ -1588,8 +1588,9 @@ isar_bctrl(struct mISDNchannel *ch, u32 cmd, void *arg)  	switch (cmd) {  	case CLOSE_CHANNEL:  		test_and_clear_bit(FLG_OPEN, &bch->Flags); +		cancel_work_sync(&bch->workq);  		spin_lock_irqsave(ich->is->hwlock, flags); -		mISDN_freebchannel(bch); +		mISDN_clear_bchannel(bch);  		modeisar(ich, ISDN_P_NONE);  		spin_unlock_irqrestore(ich->is->hwlock, flags);  		ch->protocol = ISDN_P_NONE; diff --git a/drivers/isdn/hardware/mISDN/netjet.c b/drivers/isdn/hardware/mISDN/netjet.c index c3e3e768627..9bcade59eb7 100644 --- a/drivers/isdn/hardware/mISDN/netjet.c +++ b/drivers/isdn/hardware/mISDN/netjet.c @@ -812,8 +812,9 @@ nj_bctrl(struct mISDNchannel *ch, u32 cmd, void *arg)  	switch (cmd) {  	case CLOSE_CHANNEL:  		test_and_clear_bit(FLG_OPEN, &bch->Flags); +		cancel_work_sync(&bch->workq);  		spin_lock_irqsave(&card->lock, flags); -		mISDN_freebchannel(bch); +		mISDN_clear_bchannel(bch);  		mode_tiger(bc, ISDN_P_NONE);  		spin_unlock_irqrestore(&card->lock, flags);  		ch->protocol = ISDN_P_NONE; diff --git a/drivers/isdn/hardware/mISDN/w6692.c b/drivers/isdn/hardware/mISDN/w6692.c index 26a86b84609..335fe645500 100644 --- a/drivers/isdn/hardware/mISDN/w6692.c +++ b/drivers/isdn/hardware/mISDN/w6692.c @@ -1054,8 +1054,9 @@ w6692_bctrl(struct mISDNchannel *ch, u32 cmd, void *arg)  	switch (cmd) {  	case CLOSE_CHANNEL:  		test_and_clear_bit(FLG_OPEN, &bch->Flags); +		cancel_work_sync(&bch->workq);  		spin_lock_irqsave(&card->lock, flags); -		mISDN_freebchannel(bch); +		mISDN_clear_bchannel(bch);  		w6692_mode(bc, ISDN_P_NONE);  		spin_unlock_irqrestore(&card->lock, flags);  		ch->protocol = ISDN_P_NONE; diff --git a/drivers/isdn/mISDN/hwchannel.c b/drivers/isdn/mISDN/hwchannel.c index ef34fd40867..2602be23f34 100644 --- a/drivers/isdn/mISDN/hwchannel.c +++ b/drivers/isdn/mISDN/hwchannel.c @@ -148,17 +148,16 @@ mISDN_clear_bchannel(struct bchannel *ch)  	ch->next_minlen = ch->init_minlen;  	ch->maxlen = ch->init_maxlen;  	ch->next_maxlen = ch->init_maxlen; +	skb_queue_purge(&ch->rqueue); +	ch->rcount = 0;  }  EXPORT_SYMBOL(mISDN_clear_bchannel); -int +void  mISDN_freebchannel(struct bchannel *ch)  { +	cancel_work_sync(&ch->workq);  	mISDN_clear_bchannel(ch); -	skb_queue_purge(&ch->rqueue); -	ch->rcount = 0; -	flush_work_sync(&ch->workq); -	return 0;  }  EXPORT_SYMBOL(mISDN_freebchannel); diff --git a/drivers/mfd/88pm800.c b/drivers/mfd/88pm800.c index b67a3018b13..ce229ea933d 100644 --- a/drivers/mfd/88pm800.c +++ b/drivers/mfd/88pm800.c @@ -470,7 +470,8 @@ static int __devinit device_800_init(struct pm80x_chip *chip,  	ret =  	    mfd_add_devices(chip->dev, 0, &onkey_devs[0], -			    ARRAY_SIZE(onkey_devs), &onkey_resources[0], 0); +			    ARRAY_SIZE(onkey_devs), &onkey_resources[0], 0, +			    NULL);  	if (ret < 0) {  		dev_err(chip->dev, "Failed to add onkey subdev\n");  		goto out_dev; @@ -481,7 +482,7 @@ static int __devinit device_800_init(struct pm80x_chip *chip,  		rtc_devs[0].platform_data = pdata->rtc;  		rtc_devs[0].pdata_size = sizeof(struct pm80x_rtc_pdata);  		ret = mfd_add_devices(chip->dev, 0, &rtc_devs[0], -				      ARRAY_SIZE(rtc_devs), NULL, 0); +				      ARRAY_SIZE(rtc_devs), NULL, 0, NULL);  		if (ret < 0) {  			dev_err(chip->dev, "Failed to add rtc subdev\n");  			goto out_dev; diff --git a/drivers/mfd/88pm805.c b/drivers/mfd/88pm805.c index 6146583589f..c20a31136f0 100644 --- a/drivers/mfd/88pm805.c +++ b/drivers/mfd/88pm805.c @@ -216,7 +216,8 @@ static int __devinit device_805_init(struct pm80x_chip *chip)  	}  	ret = mfd_add_devices(chip->dev, 0, &codec_devs[0], -			      ARRAY_SIZE(codec_devs), &codec_resources[0], 0); +			      ARRAY_SIZE(codec_devs), &codec_resources[0], 0, +			      NULL);  	if (ret < 0) {  		dev_err(chip->dev, "Failed to add codec subdev\n");  		goto out_codec; diff --git a/drivers/mfd/88pm860x-core.c b/drivers/mfd/88pm860x-core.c index d09918cf1b1..b73f033b2c6 100644 --- a/drivers/mfd/88pm860x-core.c +++ b/drivers/mfd/88pm860x-core.c @@ -637,7 +637,7 @@ static void __devinit device_bk_init(struct pm860x_chip *chip,  			bk_devs[i].resources = &bk_resources[j];  			ret = mfd_add_devices(chip->dev, 0,  					      &bk_devs[i], 1, -					      &bk_resources[j], 0); +					      &bk_resources[j], 0, NULL);  			if (ret < 0) {  				dev_err(chip->dev, "Failed to add "  					"backlight subdev\n"); @@ -672,7 +672,7 @@ static void __devinit device_led_init(struct pm860x_chip *chip,  			led_devs[i].resources = &led_resources[j],  			ret = mfd_add_devices(chip->dev, 0,  					      &led_devs[i], 1, -					      &led_resources[j], 0); +					      &led_resources[j], 0, NULL);  			if (ret < 0) {  				dev_err(chip->dev, "Failed to add "  					"led subdev\n"); @@ -709,7 +709,7 @@ static void __devinit device_regulator_init(struct pm860x_chip *chip,  		regulator_devs[i].resources = ®ulator_resources[seq];  		ret = mfd_add_devices(chip->dev, 0, ®ulator_devs[i], 1, -				      ®ulator_resources[seq], 0); +				      ®ulator_resources[seq], 0, NULL);  		if (ret < 0) {  			dev_err(chip->dev, "Failed to add regulator subdev\n");  			goto out; @@ -733,7 +733,7 @@ static void __devinit device_rtc_init(struct pm860x_chip *chip,  	rtc_devs[0].resources = &rtc_resources[0];  	ret = mfd_add_devices(chip->dev, 0, &rtc_devs[0],  			      ARRAY_SIZE(rtc_devs), &rtc_resources[0], -			      chip->irq_base); +			      chip->irq_base, NULL);  	if (ret < 0)  		dev_err(chip->dev, "Failed to add rtc subdev\n");  } @@ -752,7 +752,7 @@ static void __devinit device_touch_init(struct pm860x_chip *chip,  	touch_devs[0].resources = &touch_resources[0];  	ret = mfd_add_devices(chip->dev, 0, &touch_devs[0],  			      ARRAY_SIZE(touch_devs), &touch_resources[0], -			      chip->irq_base); +			      chip->irq_base, NULL);  	if (ret < 0)  		dev_err(chip->dev, "Failed to add touch subdev\n");  } @@ -770,7 +770,7 @@ static void __devinit device_power_init(struct pm860x_chip *chip,  	power_devs[0].num_resources = ARRAY_SIZE(battery_resources);  	power_devs[0].resources = &battery_resources[0],  	ret = mfd_add_devices(chip->dev, 0, &power_devs[0], 1, -			      &battery_resources[0], chip->irq_base); +			      &battery_resources[0], chip->irq_base, NULL);  	if (ret < 0)  		dev_err(chip->dev, "Failed to add battery subdev\n"); @@ -779,7 +779,7 @@ static void __devinit device_power_init(struct pm860x_chip *chip,  	power_devs[1].num_resources = ARRAY_SIZE(charger_resources);  	power_devs[1].resources = &charger_resources[0],  	ret = mfd_add_devices(chip->dev, 0, &power_devs[1], 1, -			      &charger_resources[0], chip->irq_base); +			      &charger_resources[0], chip->irq_base, NULL);  	if (ret < 0)  		dev_err(chip->dev, "Failed to add charger subdev\n"); @@ -788,7 +788,7 @@ static void __devinit device_power_init(struct pm860x_chip *chip,  	power_devs[2].num_resources = ARRAY_SIZE(preg_resources);  	power_devs[2].resources = &preg_resources[0],  	ret = mfd_add_devices(chip->dev, 0, &power_devs[2], 1, -			      &preg_resources[0], chip->irq_base); +			      &preg_resources[0], chip->irq_base, NULL);  	if (ret < 0)  		dev_err(chip->dev, "Failed to add preg subdev\n");  } @@ -802,7 +802,7 @@ static void __devinit device_onkey_init(struct pm860x_chip *chip,  	onkey_devs[0].resources = &onkey_resources[0],  	ret = mfd_add_devices(chip->dev, 0, &onkey_devs[0],  			      ARRAY_SIZE(onkey_devs), &onkey_resources[0], -			      chip->irq_base); +			      chip->irq_base, NULL);  	if (ret < 0)  		dev_err(chip->dev, "Failed to add onkey subdev\n");  } @@ -815,7 +815,8 @@ static void __devinit device_codec_init(struct pm860x_chip *chip,  	codec_devs[0].num_resources = ARRAY_SIZE(codec_resources);  	codec_devs[0].resources = &codec_resources[0],  	ret = mfd_add_devices(chip->dev, 0, &codec_devs[0], -			      ARRAY_SIZE(codec_devs), &codec_resources[0], 0); +			      ARRAY_SIZE(codec_devs), &codec_resources[0], 0, +			      NULL);  	if (ret < 0)  		dev_err(chip->dev, "Failed to add codec subdev\n");  } diff --git a/drivers/mfd/aat2870-core.c b/drivers/mfd/aat2870-core.c index 44a3fdbadef..f1beb4971f8 100644 --- a/drivers/mfd/aat2870-core.c +++ b/drivers/mfd/aat2870-core.c @@ -424,7 +424,7 @@ static int aat2870_i2c_probe(struct i2c_client *client,  	}  	ret = mfd_add_devices(aat2870->dev, 0, aat2870_devs, -			      ARRAY_SIZE(aat2870_devs), NULL, 0); +			      ARRAY_SIZE(aat2870_devs), NULL, 0, NULL);  	if (ret != 0) {  		dev_err(aat2870->dev, "Failed to add subdev: %d\n", ret);  		goto out_disable; diff --git a/drivers/mfd/ab3100-core.c b/drivers/mfd/ab3100-core.c index 78fca2902c8..01781ae5d0d 100644 --- a/drivers/mfd/ab3100-core.c +++ b/drivers/mfd/ab3100-core.c @@ -946,7 +946,7 @@ static int __devinit ab3100_probe(struct i2c_client *client,  	}  	err = mfd_add_devices(&client->dev, 0, ab3100_devs, -		ARRAY_SIZE(ab3100_devs), NULL, 0); +			      ARRAY_SIZE(ab3100_devs), NULL, 0, NULL);  	ab3100_setup_debugfs(ab3100); diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c index 626b4ecaf64..47adf800024 100644 --- a/drivers/mfd/ab8500-core.c +++ b/drivers/mfd/ab8500-core.c @@ -1418,25 +1418,25 @@ static int __devinit ab8500_probe(struct platform_device *pdev)  	ret = mfd_add_devices(ab8500->dev, 0, abx500_common_devs,  			ARRAY_SIZE(abx500_common_devs), NULL, -			ab8500->irq_base); +			ab8500->irq_base, ab8500->domain);  	if (ret)  		goto out_freeirq;  	if (is_ab9540(ab8500))  		ret = mfd_add_devices(ab8500->dev, 0, ab9540_devs,  				ARRAY_SIZE(ab9540_devs), NULL, -				ab8500->irq_base); +				ab8500->irq_base, ab8500->domain);  	else  		ret = mfd_add_devices(ab8500->dev, 0, ab8500_devs,  				ARRAY_SIZE(ab8500_devs), NULL, -				ab8500->irq_base); +				ab8500->irq_base, ab8500->domain);  	if (ret)  		goto out_freeirq;  	if (is_ab9540(ab8500) || is_ab8505(ab8500))  		ret = mfd_add_devices(ab8500->dev, 0, ab9540_ab8505_devs,  				ARRAY_SIZE(ab9540_ab8505_devs), NULL, -				ab8500->irq_base); +				ab8500->irq_base, ab8500->domain);  	if (ret)  		goto out_freeirq; @@ -1444,7 +1444,7 @@ static int __devinit ab8500_probe(struct platform_device *pdev)  		/* Add battery management devices */  		ret = mfd_add_devices(ab8500->dev, 0, ab8500_bm_devs,  				      ARRAY_SIZE(ab8500_bm_devs), NULL, -				      ab8500->irq_base); +				      ab8500->irq_base, ab8500->domain);  		if (ret)  			dev_err(ab8500->dev, "error adding bm devices\n");  	} diff --git a/drivers/mfd/arizona-core.c b/drivers/mfd/arizona-core.c index c7983e86254..1b48f209480 100644 --- a/drivers/mfd/arizona-core.c +++ b/drivers/mfd/arizona-core.c @@ -316,7 +316,7 @@ int __devinit arizona_dev_init(struct arizona *arizona)  	}  	ret = mfd_add_devices(arizona->dev, -1, early_devs, -			      ARRAY_SIZE(early_devs), NULL, 0); +			      ARRAY_SIZE(early_devs), NULL, 0, NULL);  	if (ret != 0) {  		dev_err(dev, "Failed to add early children: %d\n", ret);  		return ret; @@ -516,11 +516,11 @@ int __devinit arizona_dev_init(struct arizona *arizona)  	switch (arizona->type) {  	case WM5102:  		ret = mfd_add_devices(arizona->dev, -1, wm5102_devs, -				      ARRAY_SIZE(wm5102_devs), NULL, 0); +				      ARRAY_SIZE(wm5102_devs), NULL, 0, NULL);  		break;  	case WM5110:  		ret = mfd_add_devices(arizona->dev, -1, wm5110_devs, -				      ARRAY_SIZE(wm5102_devs), NULL, 0); +				      ARRAY_SIZE(wm5102_devs), NULL, 0, NULL);  		break;  	} diff --git a/drivers/mfd/asic3.c b/drivers/mfd/asic3.c index 683e18a2332..62f0883a763 100644 --- a/drivers/mfd/asic3.c +++ b/drivers/mfd/asic3.c @@ -913,14 +913,14 @@ static int __init asic3_mfd_probe(struct platform_device *pdev,  	if (pdata->clock_rate) {  		ds1wm_pdata.clock_rate = pdata->clock_rate;  		ret = mfd_add_devices(&pdev->dev, pdev->id, -			&asic3_cell_ds1wm, 1, mem, asic->irq_base); +			&asic3_cell_ds1wm, 1, mem, asic->irq_base, NULL);  		if (ret < 0)  			goto out;  	}  	if (mem_sdio && (irq >= 0)) {  		ret = mfd_add_devices(&pdev->dev, pdev->id, -			&asic3_cell_mmc, 1, mem_sdio, irq); +			&asic3_cell_mmc, 1, mem_sdio, irq, NULL);  		if (ret < 0)  			goto out;  	} @@ -934,7 +934,7 @@ static int __init asic3_mfd_probe(struct platform_device *pdev,  			asic3_cell_leds[i].pdata_size = sizeof(pdata->leds[i]);  		}  		ret = mfd_add_devices(&pdev->dev, 0, -			asic3_cell_leds, ASIC3_NUM_LEDS, NULL, 0); +			asic3_cell_leds, ASIC3_NUM_LEDS, NULL, 0, NULL);  	}   out: diff --git a/drivers/mfd/cs5535-mfd.c b/drivers/mfd/cs5535-mfd.c index 3419e726de4..2b282133c72 100644 --- a/drivers/mfd/cs5535-mfd.c +++ b/drivers/mfd/cs5535-mfd.c @@ -149,7 +149,7 @@ static int __devinit cs5535_mfd_probe(struct pci_dev *pdev,  	}  	err = mfd_add_devices(&pdev->dev, -1, cs5535_mfd_cells, -			ARRAY_SIZE(cs5535_mfd_cells), NULL, 0); +			      ARRAY_SIZE(cs5535_mfd_cells), NULL, 0, NULL);  	if (err) {  		dev_err(&pdev->dev, "MFD add devices failed: %d\n", err);  		goto err_disable; diff --git a/drivers/mfd/da9052-core.c b/drivers/mfd/da9052-core.c index 2544910e1fd..a0a62b24621 100644 --- a/drivers/mfd/da9052-core.c +++ b/drivers/mfd/da9052-core.c @@ -803,7 +803,7 @@ int __devinit da9052_device_init(struct da9052 *da9052, u8 chip_id)  		dev_err(da9052->dev, "DA9052 ADC IRQ failed ret=%d\n", ret);  	ret = mfd_add_devices(da9052->dev, -1, da9052_subdev_info, -			      ARRAY_SIZE(da9052_subdev_info), NULL, 0); +			      ARRAY_SIZE(da9052_subdev_info), NULL, 0, NULL);  	if (ret)  		goto err; diff --git a/drivers/mfd/davinci_voicecodec.c b/drivers/mfd/davinci_voicecodec.c index 4e2af2cb2d2..45e83a68641 100644 --- a/drivers/mfd/davinci_voicecodec.c +++ b/drivers/mfd/davinci_voicecodec.c @@ -129,7 +129,7 @@ static int __init davinci_vc_probe(struct platform_device *pdev)  	cell->pdata_size = sizeof(*davinci_vc);  	ret = mfd_add_devices(&pdev->dev, pdev->id, davinci_vc->cells, -			      DAVINCI_VC_CELLS, NULL, 0); +			      DAVINCI_VC_CELLS, NULL, 0, NULL);  	if (ret != 0) {  		dev_err(&pdev->dev, "fail to register client devices\n");  		goto fail4; diff --git a/drivers/mfd/db8500-prcmu.c b/drivers/mfd/db8500-prcmu.c index 7040a008113..0e63cdd9b52 100644 --- a/drivers/mfd/db8500-prcmu.c +++ b/drivers/mfd/db8500-prcmu.c @@ -3010,7 +3010,7 @@ static int __devinit db8500_prcmu_probe(struct platform_device *pdev)  		prcmu_config_esram0_deep_sleep(ESRAM0_DEEP_SLEEP_STATE_RET);  	err = mfd_add_devices(&pdev->dev, 0, db8500_prcmu_devs, -			ARRAY_SIZE(db8500_prcmu_devs), NULL, 0); +			      ARRAY_SIZE(db8500_prcmu_devs), NULL, 0, NULL);  	if (err) {  		pr_err("prcmu: Failed to add subdevices\n");  		return err; diff --git a/drivers/mfd/htc-pasic3.c b/drivers/mfd/htc-pasic3.c index 04c7093d649..9e5453d21a6 100644 --- a/drivers/mfd/htc-pasic3.c +++ b/drivers/mfd/htc-pasic3.c @@ -168,7 +168,7 @@ static int __init pasic3_probe(struct platform_device *pdev)  		/* the first 5 PASIC3 registers control the DS1WM */  		ds1wm_resources[0].end = (5 << asic->bus_shift) - 1;  		ret = mfd_add_devices(&pdev->dev, pdev->id, -				&ds1wm_cell, 1, r, irq); +				      &ds1wm_cell, 1, r, irq, NULL);  		if (ret < 0)  			dev_warn(dev, "failed to register DS1WM\n");  	} @@ -176,7 +176,8 @@ static int __init pasic3_probe(struct platform_device *pdev)  	if (pdata && pdata->led_pdata) {  		led_cell.platform_data = pdata->led_pdata;  		led_cell.pdata_size = sizeof(struct pasic3_leds_machinfo); -		ret = mfd_add_devices(&pdev->dev, pdev->id, &led_cell, 1, r, 0); +		ret = mfd_add_devices(&pdev->dev, pdev->id, &led_cell, 1, r, +				      0, NULL);  		if (ret < 0)  			dev_warn(dev, "failed to register LED device\n");  	} diff --git a/drivers/mfd/intel_msic.c b/drivers/mfd/intel_msic.c index 59df5584cb5..266bdc5bd96 100644 --- a/drivers/mfd/intel_msic.c +++ b/drivers/mfd/intel_msic.c @@ -344,13 +344,13 @@ static int __devinit intel_msic_init_devices(struct intel_msic *msic)  			continue;  		ret = mfd_add_devices(&pdev->dev, -1, &msic_devs[i], 1, NULL, -				      pdata->irq[i]); +				      pdata->irq[i], NULL);  		if (ret)  			goto fail;  	}  	ret = mfd_add_devices(&pdev->dev, 0, msic_other_devs, -			      ARRAY_SIZE(msic_other_devs), NULL, 0); +			      ARRAY_SIZE(msic_other_devs), NULL, 0, NULL);  	if (ret)  		goto fail; diff --git a/drivers/mfd/janz-cmodio.c b/drivers/mfd/janz-cmodio.c index 2ea99989551..965c4801df8 100644 --- a/drivers/mfd/janz-cmodio.c +++ b/drivers/mfd/janz-cmodio.c @@ -147,7 +147,7 @@ static int __devinit cmodio_probe_submodules(struct cmodio_device *priv)  	}  	return mfd_add_devices(&pdev->dev, 0, priv->cells, -			       num_probed, NULL, pdev->irq); +			       num_probed, NULL, pdev->irq, NULL);  }  /* diff --git a/drivers/mfd/jz4740-adc.c b/drivers/mfd/jz4740-adc.c index 87662a17dec..c6b6d7dda51 100644 --- a/drivers/mfd/jz4740-adc.c +++ b/drivers/mfd/jz4740-adc.c @@ -287,7 +287,8 @@ static int __devinit jz4740_adc_probe(struct platform_device *pdev)  	writeb(0xff, adc->base + JZ_REG_ADC_CTRL);  	ret = mfd_add_devices(&pdev->dev, 0, jz4740_adc_cells, -		ARRAY_SIZE(jz4740_adc_cells), mem_base, irq_base); +			      ARRAY_SIZE(jz4740_adc_cells), mem_base, +			      irq_base, NULL);  	if (ret < 0)  		goto err_clk_put; diff --git a/drivers/mfd/lm3533-core.c b/drivers/mfd/lm3533-core.c index 0b2879b87fd..24212f45b20 100644 --- a/drivers/mfd/lm3533-core.c +++ b/drivers/mfd/lm3533-core.c @@ -393,7 +393,8 @@ static int __devinit lm3533_device_als_init(struct lm3533 *lm3533)  	lm3533_als_devs[0].platform_data = pdata->als;  	lm3533_als_devs[0].pdata_size = sizeof(*pdata->als); -	ret = mfd_add_devices(lm3533->dev, 0, lm3533_als_devs, 1, NULL, 0); +	ret = mfd_add_devices(lm3533->dev, 0, lm3533_als_devs, 1, NULL, +			      0, NULL);  	if (ret) {  		dev_err(lm3533->dev, "failed to add ALS device\n");  		return ret; @@ -422,7 +423,7 @@ static int __devinit lm3533_device_bl_init(struct lm3533 *lm3533)  	}  	ret = mfd_add_devices(lm3533->dev, 0, lm3533_bl_devs, -					pdata->num_backlights, NULL, 0); +			      pdata->num_backlights, NULL, 0, NULL);  	if (ret) {  		dev_err(lm3533->dev, "failed to add backlight devices\n");  		return ret; @@ -451,7 +452,7 @@ static int __devinit lm3533_device_led_init(struct lm3533 *lm3533)  	}  	ret = mfd_add_devices(lm3533->dev, 0, lm3533_led_devs, -						pdata->num_leds, NULL, 0); +			      pdata->num_leds, NULL, 0, NULL);  	if (ret) {  		dev_err(lm3533->dev, "failed to add LED devices\n");  		return ret; diff --git a/drivers/mfd/lpc_ich.c b/drivers/mfd/lpc_ich.c index 027cc8f8613..092ad4b44b6 100644 --- a/drivers/mfd/lpc_ich.c +++ b/drivers/mfd/lpc_ich.c @@ -750,7 +750,7 @@ gpe0_done:  	lpc_ich_finalize_cell(&lpc_ich_cells[LPC_GPIO], id);  	ret = mfd_add_devices(&dev->dev, -1, &lpc_ich_cells[LPC_GPIO], -				1, NULL, 0); +			      1, NULL, 0, NULL);  gpio_done:  	if (acpi_conflict) @@ -765,7 +765,6 @@ static int __devinit lpc_ich_init_wdt(struct pci_dev *dev,  	u32 base_addr_cfg;  	u32 base_addr;  	int ret; -	bool acpi_conflict = false;  	struct resource *res;  	/* Setup power management base register */ @@ -780,20 +779,11 @@ static int __devinit lpc_ich_init_wdt(struct pci_dev *dev,  	res = wdt_io_res(ICH_RES_IO_TCO);  	res->start = base_addr + ACPIBASE_TCO_OFF;  	res->end = base_addr + ACPIBASE_TCO_END; -	ret = acpi_check_resource_conflict(res); -	if (ret) { -		acpi_conflict = true; -		goto wdt_done; -	}  	res = wdt_io_res(ICH_RES_IO_SMI);  	res->start = base_addr + ACPIBASE_SMI_OFF;  	res->end = base_addr + ACPIBASE_SMI_END; -	ret = acpi_check_resource_conflict(res); -	if (ret) { -		acpi_conflict = true; -		goto wdt_done; -	} +  	lpc_ich_enable_acpi_space(dev);  	/* @@ -813,21 +803,13 @@ static int __devinit lpc_ich_init_wdt(struct pci_dev *dev,  		res = wdt_mem_res(ICH_RES_MEM_GCS);  		res->start = base_addr + ACPIBASE_GCS_OFF;  		res->end = base_addr + ACPIBASE_GCS_END; -		ret = acpi_check_resource_conflict(res); -		if (ret) { -			acpi_conflict = true; -			goto wdt_done; -		}  	}  	lpc_ich_finalize_cell(&lpc_ich_cells[LPC_WDT], id);  	ret = mfd_add_devices(&dev->dev, -1, &lpc_ich_cells[LPC_WDT], -				1, NULL, 0); +			      1, NULL, 0, NULL);  wdt_done: -	if (acpi_conflict) -		pr_warn("Resource conflict(s) found affecting %s\n", -				lpc_ich_cells[LPC_WDT].name);  	return ret;  } diff --git a/drivers/mfd/lpc_sch.c b/drivers/mfd/lpc_sch.c index 9f20abc5e39..f6b9c5c96b2 100644 --- a/drivers/mfd/lpc_sch.c +++ b/drivers/mfd/lpc_sch.c @@ -127,7 +127,8 @@ static int __devinit lpc_sch_probe(struct pci_dev *dev,  		lpc_sch_cells[i].id = id->device;  	ret = mfd_add_devices(&dev->dev, 0, -			lpc_sch_cells, ARRAY_SIZE(lpc_sch_cells), NULL, 0); +			      lpc_sch_cells, ARRAY_SIZE(lpc_sch_cells), NULL, +			      0, NULL);  	if (ret)  		goto out_dev; @@ -153,7 +154,8 @@ static int __devinit lpc_sch_probe(struct pci_dev *dev,  			tunnelcreek_cells[i].id = id->device;  		ret = mfd_add_devices(&dev->dev, 0, tunnelcreek_cells, -			ARRAY_SIZE(tunnelcreek_cells), NULL, 0); +				      ARRAY_SIZE(tunnelcreek_cells), NULL, +				      0, NULL);  	}  	return ret; diff --git a/drivers/mfd/max77686.c b/drivers/mfd/max77686.c index c03e12b5192..d9e24c849a0 100644 --- a/drivers/mfd/max77686.c +++ b/drivers/mfd/max77686.c @@ -126,7 +126,7 @@ static int max77686_i2c_probe(struct i2c_client *i2c,  	max77686_irq_init(max77686);  	ret = mfd_add_devices(max77686->dev, -1, max77686_devs, -			      ARRAY_SIZE(max77686_devs), NULL, 0); +			      ARRAY_SIZE(max77686_devs), NULL, 0, NULL);  	if (ret < 0)  		goto err_mfd; diff --git a/drivers/mfd/max77693-irq.c b/drivers/mfd/max77693-irq.c index 2b403569e0a..1029d018c73 100644 --- a/drivers/mfd/max77693-irq.c +++ b/drivers/mfd/max77693-irq.c @@ -137,6 +137,9 @@ static void max77693_irq_mask(struct irq_data *data)  	const struct max77693_irq_data *irq_data =  				irq_to_max77693_irq(max77693, data->irq); +	if (irq_data->group >= MAX77693_IRQ_GROUP_NR) +		return; +  	if (irq_data->group >= MUIC_INT1 && irq_data->group <= MUIC_INT3)  		max77693->irq_masks_cur[irq_data->group] &= ~irq_data->mask;  	else @@ -149,6 +152,9 @@ static void max77693_irq_unmask(struct irq_data *data)  	const struct max77693_irq_data *irq_data =  	    irq_to_max77693_irq(max77693, data->irq); +	if (irq_data->group >= MAX77693_IRQ_GROUP_NR) +		return; +  	if (irq_data->group >= MUIC_INT1 && irq_data->group <= MUIC_INT3)  		max77693->irq_masks_cur[irq_data->group] |= irq_data->mask;  	else @@ -200,7 +206,7 @@ static irqreturn_t max77693_irq_thread(int irq, void *data)  	if (irq_src & MAX77693_IRQSRC_MUIC)  		/* MUIC INT1 ~ INT3 */ -		max77693_bulk_read(max77693->regmap, MAX77693_MUIC_REG_INT1, +		max77693_bulk_read(max77693->regmap_muic, MAX77693_MUIC_REG_INT1,  			MAX77693_NUM_IRQ_MUIC_REGS, &irq_reg[MUIC_INT1]);  	/* Apply masking */ @@ -255,7 +261,8 @@ int max77693_irq_init(struct max77693_dev *max77693)  {  	struct irq_domain *domain;  	int i; -	int ret; +	int ret = 0; +	u8 intsrc_mask;  	mutex_init(&max77693->irqlock); @@ -287,19 +294,38 @@ int max77693_irq_init(struct max77693_dev *max77693)  					&max77693_irq_domain_ops, max77693);  	if (!domain) {  		dev_err(max77693->dev, "could not create irq domain\n"); -		return -ENODEV; +		ret = -ENODEV; +		goto err_irq;  	}  	max77693->irq_domain = domain; +	/* Unmask max77693 interrupt */ +	ret = max77693_read_reg(max77693->regmap, +			MAX77693_PMIC_REG_INTSRC_MASK, &intsrc_mask); +	if (ret < 0) { +		dev_err(max77693->dev, "fail to read PMIC register\n"); +		goto err_irq; +	} + +	intsrc_mask &= ~(MAX77693_IRQSRC_CHG); +	intsrc_mask &= ~(MAX77693_IRQSRC_FLASH); +	intsrc_mask &= ~(MAX77693_IRQSRC_MUIC); +	ret = max77693_write_reg(max77693->regmap, +			MAX77693_PMIC_REG_INTSRC_MASK, intsrc_mask); +	if (ret < 0) { +		dev_err(max77693->dev, "fail to write PMIC register\n"); +		goto err_irq; +	} +  	ret = request_threaded_irq(max77693->irq, NULL, max77693_irq_thread,  				   IRQF_TRIGGER_FALLING | IRQF_ONESHOT,  				   "max77693-irq", max77693); -  	if (ret)  		dev_err(max77693->dev, "Failed to request IRQ %d: %d\n",  			max77693->irq, ret); -	return 0; +err_irq: +	return ret;  }  void max77693_irq_exit(struct max77693_dev *max77693) diff --git a/drivers/mfd/max77693.c b/drivers/mfd/max77693.c index a1811cb50ec..cc5155e2049 100644 --- a/drivers/mfd/max77693.c +++ b/drivers/mfd/max77693.c @@ -152,6 +152,20 @@ static int max77693_i2c_probe(struct i2c_client *i2c,  	max77693->haptic = i2c_new_dummy(i2c->adapter, I2C_ADDR_HAPTIC);  	i2c_set_clientdata(max77693->haptic, max77693); +	/* +	 * Initialize register map for MUIC device because use regmap-muic +	 * instance of MUIC device when irq of max77693 is initialized +	 * before call max77693-muic probe() function. +	 */ +	max77693->regmap_muic = devm_regmap_init_i2c(max77693->muic, +					 &max77693_regmap_config); +	if (IS_ERR(max77693->regmap_muic)) { +		ret = PTR_ERR(max77693->regmap_muic); +		dev_err(max77693->dev, +			"failed to allocate register map: %d\n", ret); +		goto err_regmap; +	} +  	ret = max77693_irq_init(max77693);  	if (ret < 0)  		goto err_irq; @@ -159,7 +173,7 @@ static int max77693_i2c_probe(struct i2c_client *i2c,  	pm_runtime_set_active(max77693->dev);  	ret = mfd_add_devices(max77693->dev, -1, max77693_devs, -			ARRAY_SIZE(max77693_devs), NULL, 0); +			      ARRAY_SIZE(max77693_devs), NULL, 0, NULL);  	if (ret < 0)  		goto err_mfd; diff --git a/drivers/mfd/max8925-core.c b/drivers/mfd/max8925-core.c index 825a7f06d9b..ee53757beca 100644 --- a/drivers/mfd/max8925-core.c +++ b/drivers/mfd/max8925-core.c @@ -598,7 +598,7 @@ int __devinit max8925_device_init(struct max8925_chip *chip,  	ret = mfd_add_devices(chip->dev, 0, &rtc_devs[0],  			      ARRAY_SIZE(rtc_devs), -			      &rtc_resources[0], chip->irq_base); +			      &rtc_resources[0], chip->irq_base, NULL);  	if (ret < 0) {  		dev_err(chip->dev, "Failed to add rtc subdev\n");  		goto out; @@ -606,7 +606,7 @@ int __devinit max8925_device_init(struct max8925_chip *chip,  	ret = mfd_add_devices(chip->dev, 0, &onkey_devs[0],  			      ARRAY_SIZE(onkey_devs), -			      &onkey_resources[0], 0); +			      &onkey_resources[0], 0, NULL);  	if (ret < 0) {  		dev_err(chip->dev, "Failed to add onkey subdev\n");  		goto out_dev; @@ -615,7 +615,7 @@ int __devinit max8925_device_init(struct max8925_chip *chip,  	if (pdata) {  		ret = mfd_add_devices(chip->dev, 0, ®ulator_devs[0],  				      ARRAY_SIZE(regulator_devs), -				      ®ulator_resources[0], 0); +				      ®ulator_resources[0], 0, NULL);  		if (ret < 0) {  			dev_err(chip->dev, "Failed to add regulator subdev\n");  			goto out_dev; @@ -625,7 +625,7 @@ int __devinit max8925_device_init(struct max8925_chip *chip,  	if (pdata && pdata->backlight) {  		ret = mfd_add_devices(chip->dev, 0, &backlight_devs[0],  				      ARRAY_SIZE(backlight_devs), -				      &backlight_resources[0], 0); +				      &backlight_resources[0], 0, NULL);  		if (ret < 0) {  			dev_err(chip->dev, "Failed to add backlight subdev\n");  			goto out_dev; @@ -635,7 +635,7 @@ int __devinit max8925_device_init(struct max8925_chip *chip,  	if (pdata && pdata->power) {  		ret = mfd_add_devices(chip->dev, 0, &power_devs[0],  					ARRAY_SIZE(power_devs), -					&power_supply_resources[0], 0); +				      &power_supply_resources[0], 0, NULL);  		if (ret < 0) {  			dev_err(chip->dev, "Failed to add power supply "  				"subdev\n"); @@ -646,7 +646,7 @@ int __devinit max8925_device_init(struct max8925_chip *chip,  	if (pdata && pdata->touch) {  		ret = mfd_add_devices(chip->dev, 0, &touch_devs[0],  				      ARRAY_SIZE(touch_devs), -				      &touch_resources[0], 0); +				      &touch_resources[0], 0, NULL);  		if (ret < 0) {  			dev_err(chip->dev, "Failed to add touch subdev\n");  			goto out_dev; diff --git a/drivers/mfd/max8997.c b/drivers/mfd/max8997.c index 10b629c245b..f123517065e 100644 --- a/drivers/mfd/max8997.c +++ b/drivers/mfd/max8997.c @@ -160,7 +160,7 @@ static int max8997_i2c_probe(struct i2c_client *i2c,  	mfd_add_devices(max8997->dev, -1, max8997_devs,  			ARRAY_SIZE(max8997_devs), -			NULL, 0); +			NULL, 0, NULL);  	/*  	 * TODO: enable others (flash, muic, rtc, battery, ...) and diff --git a/drivers/mfd/max8998.c b/drivers/mfd/max8998.c index 6ef56d28c05..d7218cc9094 100644 --- a/drivers/mfd/max8998.c +++ b/drivers/mfd/max8998.c @@ -161,13 +161,13 @@ static int max8998_i2c_probe(struct i2c_client *i2c,  	switch (id->driver_data) {  	case TYPE_LP3974:  		ret = mfd_add_devices(max8998->dev, -1, -				lp3974_devs, ARRAY_SIZE(lp3974_devs), -				NULL, 0); +				      lp3974_devs, ARRAY_SIZE(lp3974_devs), +				      NULL, 0, NULL);  		break;  	case TYPE_MAX8998:  		ret = mfd_add_devices(max8998->dev, -1, -				max8998_devs, ARRAY_SIZE(max8998_devs), -				NULL, 0); +				      max8998_devs, ARRAY_SIZE(max8998_devs), +				      NULL, 0, NULL);  		break;  	default:  		ret = -EINVAL; diff --git a/drivers/mfd/mc13xxx-core.c b/drivers/mfd/mc13xxx-core.c index b801dc72f04..1ec79b54bd2 100644 --- a/drivers/mfd/mc13xxx-core.c +++ b/drivers/mfd/mc13xxx-core.c @@ -612,7 +612,7 @@ static int mc13xxx_add_subdevice_pdata(struct mc13xxx *mc13xxx,  	if (!cell.name)  		return -ENOMEM; -	return mfd_add_devices(mc13xxx->dev, -1, &cell, 1, NULL, 0); +	return mfd_add_devices(mc13xxx->dev, -1, &cell, 1, NULL, 0, NULL);  }  static int mc13xxx_add_subdevice(struct mc13xxx *mc13xxx, const char *format) diff --git a/drivers/mfd/mfd-core.c b/drivers/mfd/mfd-core.c index 0c3a01cde2f..f8b77711ad2 100644 --- a/drivers/mfd/mfd-core.c +++ b/drivers/mfd/mfd-core.c @@ -74,12 +74,11 @@ static int mfd_platform_add_cell(struct platform_device *pdev,  static int mfd_add_device(struct device *parent, int id,  			  const struct mfd_cell *cell,  			  struct resource *mem_base, -			  int irq_base) +			  int irq_base, struct irq_domain *domain)  {  	struct resource *res;  	struct platform_device *pdev;  	struct device_node *np = NULL; -	struct irq_domain *domain = NULL;  	int ret = -ENOMEM;  	int r; @@ -97,7 +96,6 @@ static int mfd_add_device(struct device *parent, int id,  		for_each_child_of_node(parent->of_node, np) {  			if (of_device_is_compatible(np, cell->of_compatible)) {  				pdev->dev.of_node = np; -				domain = irq_find_host(parent->of_node);  				break;  			}  		} @@ -177,7 +175,7 @@ fail_alloc:  int mfd_add_devices(struct device *parent, int id,  		    struct mfd_cell *cells, int n_devs,  		    struct resource *mem_base, -		    int irq_base) +		    int irq_base, struct irq_domain *domain)  {  	int i;  	int ret = 0; @@ -191,7 +189,8 @@ int mfd_add_devices(struct device *parent, int id,  	for (i = 0; i < n_devs; i++) {  		atomic_set(&cnts[i], 0);  		cells[i].usage_count = &cnts[i]; -		ret = mfd_add_device(parent, id, cells + i, mem_base, irq_base); +		ret = mfd_add_device(parent, id, cells + i, mem_base, +				     irq_base, domain);  		if (ret)  			break;  	} @@ -247,7 +246,8 @@ int mfd_clone_cell(const char *cell, const char **clones, size_t n_clones)  	for (i = 0; i < n_clones; i++) {  		cell_entry.name = clones[i];  		/* don't give up if a single call fails; just report error */ -		if (mfd_add_device(pdev->dev.parent, -1, &cell_entry, NULL, 0)) +		if (mfd_add_device(pdev->dev.parent, -1, &cell_entry, NULL, 0, +				   NULL))  			dev_err(dev, "failed to create platform device '%s'\n",  					clones[i]);  	} diff --git a/drivers/mfd/palmas.c b/drivers/mfd/palmas.c index c4a69f193a1..a345f9bb7b4 100644 --- a/drivers/mfd/palmas.c +++ b/drivers/mfd/palmas.c @@ -453,7 +453,8 @@ static int __devinit palmas_i2c_probe(struct i2c_client *i2c,  	ret = mfd_add_devices(palmas->dev, -1,  			      children, ARRAY_SIZE(palmas_children), -			      NULL, regmap_irq_chip_get_base(palmas->irq_data)); +			      NULL, regmap_irq_chip_get_base(palmas->irq_data), +			      NULL);  	kfree(children);  	if (ret < 0) diff --git a/drivers/mfd/rc5t583.c b/drivers/mfd/rc5t583.c index cdc1df7fa0e..3a8fa88567b 100644 --- a/drivers/mfd/rc5t583.c +++ b/drivers/mfd/rc5t583.c @@ -289,7 +289,7 @@ static int __devinit rc5t583_i2c_probe(struct i2c_client *i2c,  	}  	ret = mfd_add_devices(rc5t583->dev, -1, rc5t583_subdevs, -			ARRAY_SIZE(rc5t583_subdevs), NULL, 0); +			      ARRAY_SIZE(rc5t583_subdevs), NULL, 0, NULL);  	if (ret) {  		dev_err(&i2c->dev, "add mfd devices failed: %d\n", ret);  		goto err_add_devs; diff --git a/drivers/mfd/rdc321x-southbridge.c b/drivers/mfd/rdc321x-southbridge.c index 685d61e431a..0f70dce6116 100644 --- a/drivers/mfd/rdc321x-southbridge.c +++ b/drivers/mfd/rdc321x-southbridge.c @@ -87,7 +87,8 @@ static int __devinit rdc321x_sb_probe(struct pci_dev *pdev,  	rdc321x_wdt_pdata.sb_pdev = pdev;  	return mfd_add_devices(&pdev->dev, -1, -		rdc321x_sb_cells, ARRAY_SIZE(rdc321x_sb_cells), NULL, 0); +			       rdc321x_sb_cells, ARRAY_SIZE(rdc321x_sb_cells), +			       NULL, 0, NULL);  }  static void __devexit rdc321x_sb_remove(struct pci_dev *pdev) diff --git a/drivers/mfd/sec-core.c b/drivers/mfd/sec-core.c index 2988efde11e..49d361a618d 100644 --- a/drivers/mfd/sec-core.c +++ b/drivers/mfd/sec-core.c @@ -141,19 +141,19 @@ static int sec_pmic_probe(struct i2c_client *i2c,  	switch (sec_pmic->device_type) {  	case S5M8751X:  		ret = mfd_add_devices(sec_pmic->dev, -1, s5m8751_devs, -					ARRAY_SIZE(s5m8751_devs), NULL, 0); +				      ARRAY_SIZE(s5m8751_devs), NULL, 0, NULL);  		break;  	case S5M8763X:  		ret = mfd_add_devices(sec_pmic->dev, -1, s5m8763_devs, -					ARRAY_SIZE(s5m8763_devs), NULL, 0); +				      ARRAY_SIZE(s5m8763_devs), NULL, 0, NULL);  		break;  	case S5M8767X:  		ret = mfd_add_devices(sec_pmic->dev, -1, s5m8767_devs, -					ARRAY_SIZE(s5m8767_devs), NULL, 0); +				      ARRAY_SIZE(s5m8767_devs), NULL, 0, NULL);  		break;  	case S2MPS11X:  		ret = mfd_add_devices(sec_pmic->dev, -1, s2mps11_devs, -					ARRAY_SIZE(s2mps11_devs), NULL, 0); +				      ARRAY_SIZE(s2mps11_devs), NULL, 0, NULL);  		break;  	default:  		/* If this happens the probe function is problem */ diff --git a/drivers/mfd/sta2x11-mfd.c b/drivers/mfd/sta2x11-mfd.c index d31fed07aef..d35da6820be 100644 --- a/drivers/mfd/sta2x11-mfd.c +++ b/drivers/mfd/sta2x11-mfd.c @@ -407,7 +407,7 @@ static int __devinit sta2x11_mfd_probe(struct pci_dev *pdev,  			      sta2x11_mfd_bar0,  			      ARRAY_SIZE(sta2x11_mfd_bar0),  			      &pdev->resource[0], -			      0); +			      0, NULL);  	if (err) {  		dev_err(&pdev->dev, "mfd_add_devices[0] failed: %d\n", err);  		goto err_disable; @@ -417,7 +417,7 @@ static int __devinit sta2x11_mfd_probe(struct pci_dev *pdev,  			      sta2x11_mfd_bar1,  			      ARRAY_SIZE(sta2x11_mfd_bar1),  			      &pdev->resource[1], -			      0); +			      0, NULL);  	if (err) {  		dev_err(&pdev->dev, "mfd_add_devices[1] failed: %d\n", err);  		goto err_disable; diff --git a/drivers/mfd/stmpe.c b/drivers/mfd/stmpe.c index 2dd8d49cb30..c94f521f392 100644 --- a/drivers/mfd/stmpe.c +++ b/drivers/mfd/stmpe.c @@ -962,7 +962,7 @@ static int __devinit stmpe_add_device(struct stmpe *stmpe,  				      struct mfd_cell *cell, int irq)  {  	return mfd_add_devices(stmpe->dev, stmpe->pdata->id, cell, 1, -			       NULL, stmpe->irq_base + irq); +			       NULL, stmpe->irq_base + irq, NULL);  }  static int __devinit stmpe_devices_init(struct stmpe *stmpe) diff --git a/drivers/mfd/t7l66xb.c b/drivers/mfd/t7l66xb.c index 2d9e8799e73..b32940ec903 100644 --- a/drivers/mfd/t7l66xb.c +++ b/drivers/mfd/t7l66xb.c @@ -388,7 +388,7 @@ static int t7l66xb_probe(struct platform_device *dev)  	ret = mfd_add_devices(&dev->dev, dev->id,  			      t7l66xb_cells, ARRAY_SIZE(t7l66xb_cells), -			      iomem, t7l66xb->irq_base); +			      iomem, t7l66xb->irq_base, NULL);  	if (!ret)  		return 0; diff --git a/drivers/mfd/tc3589x.c b/drivers/mfd/tc3589x.c index 048bf0532a0..b56ba6b4329 100644 --- a/drivers/mfd/tc3589x.c +++ b/drivers/mfd/tc3589x.c @@ -262,8 +262,8 @@ static int __devinit tc3589x_device_init(struct tc3589x *tc3589x)  	if (blocks & TC3589x_BLOCK_GPIO) {  		ret = mfd_add_devices(tc3589x->dev, -1, tc3589x_dev_gpio, -				ARRAY_SIZE(tc3589x_dev_gpio), NULL, -				tc3589x->irq_base); +				      ARRAY_SIZE(tc3589x_dev_gpio), NULL, +				      tc3589x->irq_base, NULL);  		if (ret) {  			dev_err(tc3589x->dev, "failed to add gpio child\n");  			return ret; @@ -273,8 +273,8 @@ static int __devinit tc3589x_device_init(struct tc3589x *tc3589x)  	if (blocks & TC3589x_BLOCK_KEYPAD) {  		ret = mfd_add_devices(tc3589x->dev, -1, tc3589x_dev_keypad, -				ARRAY_SIZE(tc3589x_dev_keypad), NULL, -				tc3589x->irq_base); +				      ARRAY_SIZE(tc3589x_dev_keypad), NULL, +				      tc3589x->irq_base, NULL);  		if (ret) {  			dev_err(tc3589x->dev, "failed to keypad child\n");  			return ret; diff --git a/drivers/mfd/tc6387xb.c b/drivers/mfd/tc6387xb.c index d20a284ad4b..413c891102f 100644 --- a/drivers/mfd/tc6387xb.c +++ b/drivers/mfd/tc6387xb.c @@ -192,7 +192,7 @@ static int __devinit tc6387xb_probe(struct platform_device *dev)  	printk(KERN_INFO "Toshiba tc6387xb initialised\n");  	ret = mfd_add_devices(&dev->dev, dev->id, tc6387xb_cells, -			      ARRAY_SIZE(tc6387xb_cells), iomem, irq); +			      ARRAY_SIZE(tc6387xb_cells), iomem, irq, NULL);  	if (!ret)  		return 0; diff --git a/drivers/mfd/tc6393xb.c b/drivers/mfd/tc6393xb.c index 9612264f0e6..dcab026fcbb 100644 --- a/drivers/mfd/tc6393xb.c +++ b/drivers/mfd/tc6393xb.c @@ -700,8 +700,8 @@ static int __devinit tc6393xb_probe(struct platform_device *dev)  	tc6393xb_cells[TC6393XB_CELL_FB].pdata_size = sizeof(*tcpd->fb_data);  	ret = mfd_add_devices(&dev->dev, dev->id, -			tc6393xb_cells, ARRAY_SIZE(tc6393xb_cells), -			iomem, tcpd->irq_base); +			      tc6393xb_cells, ARRAY_SIZE(tc6393xb_cells), +			      iomem, tcpd->irq_base, NULL);  	if (!ret)  		return 0; diff --git a/drivers/mfd/ti-ssp.c b/drivers/mfd/ti-ssp.c index 4fb0e6c8e8f..7c3675a74f9 100644 --- a/drivers/mfd/ti-ssp.c +++ b/drivers/mfd/ti-ssp.c @@ -412,7 +412,7 @@ static int __devinit ti_ssp_probe(struct platform_device *pdev)  		cells[id].data_size	= data->pdata_size;  	} -	error = mfd_add_devices(dev, 0, cells, 2, NULL, 0); +	error = mfd_add_devices(dev, 0, cells, 2, NULL, 0, NULL);  	if (error < 0) {  		dev_err(dev, "cannot add mfd cells\n");  		goto error_enable; diff --git a/drivers/mfd/timberdale.c b/drivers/mfd/timberdale.c index a447f4ec11f..cccc626c83c 100644 --- a/drivers/mfd/timberdale.c +++ b/drivers/mfd/timberdale.c @@ -757,25 +757,25 @@ static int __devinit timb_probe(struct pci_dev *dev,  		err = mfd_add_devices(&dev->dev, -1,  			timberdale_cells_bar0_cfg0,  			ARRAY_SIZE(timberdale_cells_bar0_cfg0), -			&dev->resource[0], msix_entries[0].vector); +			&dev->resource[0], msix_entries[0].vector, NULL);  		break;  	case TIMB_HW_VER1:  		err = mfd_add_devices(&dev->dev, -1,  			timberdale_cells_bar0_cfg1,  			ARRAY_SIZE(timberdale_cells_bar0_cfg1), -			&dev->resource[0], msix_entries[0].vector); +			&dev->resource[0], msix_entries[0].vector, NULL);  		break;  	case TIMB_HW_VER2:  		err = mfd_add_devices(&dev->dev, -1,  			timberdale_cells_bar0_cfg2,  			ARRAY_SIZE(timberdale_cells_bar0_cfg2), -			&dev->resource[0], msix_entries[0].vector); +			&dev->resource[0], msix_entries[0].vector, NULL);  		break;  	case TIMB_HW_VER3:  		err = mfd_add_devices(&dev->dev, -1,  			timberdale_cells_bar0_cfg3,  			ARRAY_SIZE(timberdale_cells_bar0_cfg3), -			&dev->resource[0], msix_entries[0].vector); +			&dev->resource[0], msix_entries[0].vector, NULL);  		break;  	default:  		dev_err(&dev->dev, "Uknown IP setup: %d.%d.%d\n", @@ -792,7 +792,7 @@ static int __devinit timb_probe(struct pci_dev *dev,  	err = mfd_add_devices(&dev->dev, 0,  		timberdale_cells_bar1, ARRAY_SIZE(timberdale_cells_bar1), -		&dev->resource[1], msix_entries[0].vector); +		&dev->resource[1], msix_entries[0].vector, NULL);  	if (err) {  		dev_err(&dev->dev, "mfd_add_devices failed: %d\n", err);  		goto err_mfd2; @@ -803,7 +803,7 @@ static int __devinit timb_probe(struct pci_dev *dev,  		((priv->fw.config & TIMB_HW_VER_MASK) == TIMB_HW_VER3)) {  		err = mfd_add_devices(&dev->dev, 1, timberdale_cells_bar2,  			ARRAY_SIZE(timberdale_cells_bar2), -			&dev->resource[2], msix_entries[0].vector); +			&dev->resource[2], msix_entries[0].vector, NULL);  		if (err) {  			dev_err(&dev->dev, "mfd_add_devices failed: %d\n", err);  			goto err_mfd2; diff --git a/drivers/mfd/tps6105x.c b/drivers/mfd/tps6105x.c index a293b978e27..14051bdc714 100644 --- a/drivers/mfd/tps6105x.c +++ b/drivers/mfd/tps6105x.c @@ -188,7 +188,7 @@ static int __devinit tps6105x_probe(struct i2c_client *client,  	}  	ret = mfd_add_devices(&client->dev, 0, tps6105x_cells, -		ARRAY_SIZE(tps6105x_cells), NULL, 0); +			      ARRAY_SIZE(tps6105x_cells), NULL, 0, NULL);  	if (ret)  		goto fail; diff --git a/drivers/mfd/tps6507x.c b/drivers/mfd/tps6507x.c index 33ba7723c96..1b203499c74 100644 --- a/drivers/mfd/tps6507x.c +++ b/drivers/mfd/tps6507x.c @@ -100,7 +100,7 @@ static int tps6507x_i2c_probe(struct i2c_client *i2c,  	ret = mfd_add_devices(tps6507x->dev, -1,  			      tps6507x_devs, ARRAY_SIZE(tps6507x_devs), -			      NULL, 0); +			      NULL, 0, NULL);  	if (ret < 0)  		goto err; diff --git a/drivers/mfd/tps65090.c b/drivers/mfd/tps65090.c index 80e24f4b47b..50fd87c87a1 100644 --- a/drivers/mfd/tps65090.c +++ b/drivers/mfd/tps65090.c @@ -292,7 +292,7 @@ static int __devinit tps65090_i2c_probe(struct i2c_client *client,  	}  	ret = mfd_add_devices(tps65090->dev, -1, tps65090s, -		ARRAY_SIZE(tps65090s), NULL, 0); +			      ARRAY_SIZE(tps65090s), NULL, 0, NULL);  	if (ret) {  		dev_err(&client->dev, "add mfd devices failed with err: %d\n",  			ret); diff --git a/drivers/mfd/tps65217.c b/drivers/mfd/tps65217.c index 61c097a98f5..a95e9421b73 100644 --- a/drivers/mfd/tps65217.c +++ b/drivers/mfd/tps65217.c @@ -24,11 +24,18 @@  #include <linux/slab.h>  #include <linux/regmap.h>  #include <linux/err.h> -#include <linux/regulator/of_regulator.h> +#include <linux/of.h> +#include <linux/of_device.h>  #include <linux/mfd/core.h>  #include <linux/mfd/tps65217.h> +static struct mfd_cell tps65217s[] = { +	{ +		.name = "tps65217-pmic", +	}, +}; +  /**   * tps65217_reg_read: Read a single tps65217 register.   * @@ -133,83 +140,48 @@ int tps65217_clear_bits(struct tps65217 *tps, unsigned int reg,  }  EXPORT_SYMBOL_GPL(tps65217_clear_bits); -#ifdef CONFIG_OF -static struct of_regulator_match reg_matches[] = { -	{ .name = "dcdc1", .driver_data = (void *)TPS65217_DCDC_1 }, -	{ .name = "dcdc2", .driver_data = (void *)TPS65217_DCDC_2 }, -	{ .name = "dcdc3", .driver_data = (void *)TPS65217_DCDC_3 }, -	{ .name = "ldo1", .driver_data = (void *)TPS65217_LDO_1 }, -	{ .name = "ldo2", .driver_data = (void *)TPS65217_LDO_2 }, -	{ .name = "ldo3", .driver_data = (void *)TPS65217_LDO_3 }, -	{ .name = "ldo4", .driver_data = (void *)TPS65217_LDO_4 }, -}; - -static struct tps65217_board *tps65217_parse_dt(struct i2c_client *client) -{ -	struct device_node *node = client->dev.of_node; -	struct tps65217_board *pdata; -	struct device_node *regs; -	int count = ARRAY_SIZE(reg_matches); -	int ret, i; - -	regs = of_find_node_by_name(node, "regulators"); -	if (!regs) -		return NULL; - -	ret = of_regulator_match(&client->dev, regs, reg_matches, count); -	of_node_put(regs); -	if ((ret < 0) || (ret > count)) -		return NULL; - -	count = ret; -	pdata = devm_kzalloc(&client->dev, count * sizeof(*pdata), GFP_KERNEL); -	if (!pdata) -		return NULL; - -	for (i = 0; i < count; i++) { -		if (!reg_matches[i].init_data || !reg_matches[i].of_node) -			continue; - -		pdata->tps65217_init_data[i] = reg_matches[i].init_data; -		pdata->of_node[i] = reg_matches[i].of_node; -	} - -	return pdata; -} - -static struct of_device_id tps65217_of_match[] = { -	{ .compatible = "ti,tps65217", }, -	{ }, -}; -#else -static struct tps65217_board *tps65217_parse_dt(struct i2c_client *client) -{ -	return NULL; -} -#endif -  static struct regmap_config tps65217_regmap_config = {  	.reg_bits = 8,  	.val_bits = 8,  }; +static const struct of_device_id tps65217_of_match[] = { +	{ .compatible = "ti,tps65217", .data = (void *)TPS65217 }, +	{ /* sentinel */ }, +}; +  static int __devinit tps65217_probe(struct i2c_client *client,  				const struct i2c_device_id *ids)  {  	struct tps65217 *tps; -	struct regulator_init_data *reg_data; -	struct tps65217_board *pdata = client->dev.platform_data; -	int i, ret;  	unsigned int version; +	unsigned int chip_id = ids->driver_data; +	const struct of_device_id *match; +	int ret; + +	if (client->dev.of_node) { +		match = of_match_device(tps65217_of_match, &client->dev); +		if (!match) { +			dev_err(&client->dev, +				"Failed to find matching dt id\n"); +			return -EINVAL; +		} +		chip_id = (unsigned int)match->data; +	} -	if (!pdata && client->dev.of_node) -		pdata = tps65217_parse_dt(client); +	if (!chip_id) { +		dev_err(&client->dev, "id is null.\n"); +		return -ENODEV; +	}  	tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL);  	if (!tps)  		return -ENOMEM; -	tps->pdata = pdata; +	i2c_set_clientdata(client, tps); +	tps->dev = &client->dev; +	tps->id = chip_id; +  	tps->regmap = devm_regmap_init_i2c(client, &tps65217_regmap_config);  	if (IS_ERR(tps->regmap)) {  		ret = PTR_ERR(tps->regmap); @@ -218,8 +190,12 @@ static int __devinit tps65217_probe(struct i2c_client *client,  		return ret;  	} -	i2c_set_clientdata(client, tps); -	tps->dev = &client->dev; +	ret = mfd_add_devices(tps->dev, -1, tps65217s, +			      ARRAY_SIZE(tps65217s), NULL, 0, NULL); +	if (ret < 0) { +		dev_err(tps->dev, "mfd_add_devices failed: %d\n", ret); +		return ret; +	}  	ret = tps65217_reg_read(tps, TPS65217_REG_CHIPID, &version);  	if (ret < 0) { @@ -232,41 +208,21 @@ static int __devinit tps65217_probe(struct i2c_client *client,  			(version & TPS65217_CHIPID_CHIP_MASK) >> 4,  			version & TPS65217_CHIPID_REV_MASK); -	for (i = 0; i < TPS65217_NUM_REGULATOR; i++) { -		struct platform_device *pdev; - -		pdev = platform_device_alloc("tps65217-pmic", i); -		if (!pdev) { -			dev_err(tps->dev, "Cannot create regulator %d\n", i); -			continue; -		} - -		pdev->dev.parent = tps->dev; -		pdev->dev.of_node = pdata->of_node[i]; -		reg_data = pdata->tps65217_init_data[i]; -		platform_device_add_data(pdev, reg_data, sizeof(*reg_data)); -		tps->regulator_pdev[i] = pdev; - -		platform_device_add(pdev); -	} -  	return 0;  }  static int __devexit tps65217_remove(struct i2c_client *client)  {  	struct tps65217 *tps = i2c_get_clientdata(client); -	int i; -	for (i = 0; i < TPS65217_NUM_REGULATOR; i++) -		platform_device_unregister(tps->regulator_pdev[i]); +	mfd_remove_devices(tps->dev);  	return 0;  }  static const struct i2c_device_id tps65217_id_table[] = { -	{"tps65217", 0xF0}, -	{/* end of list */} +	{"tps65217", TPS65217}, +	{ /* sentinel */ }  };  MODULE_DEVICE_TABLE(i2c, tps65217_id_table); diff --git a/drivers/mfd/tps6586x.c b/drivers/mfd/tps6586x.c index 353c3481212..5f58370ccf5 100644 --- a/drivers/mfd/tps6586x.c +++ b/drivers/mfd/tps6586x.c @@ -493,7 +493,8 @@ static int __devinit tps6586x_i2c_probe(struct i2c_client *client,  	}  	ret = mfd_add_devices(tps6586x->dev, -1, -			tps6586x_cell, ARRAY_SIZE(tps6586x_cell), NULL, 0); +			      tps6586x_cell, ARRAY_SIZE(tps6586x_cell), +			      NULL, 0, NULL);  	if (ret < 0) {  		dev_err(&client->dev, "mfd_add_devices failed: %d\n", ret);  		goto err_mfd_add; diff --git a/drivers/mfd/tps65910.c b/drivers/mfd/tps65910.c index 1c563792c77..d3ce4d569de 100644 --- a/drivers/mfd/tps65910.c +++ b/drivers/mfd/tps65910.c @@ -254,7 +254,7 @@ static __devinit int tps65910_i2c_probe(struct i2c_client *i2c,  	ret = mfd_add_devices(tps65910->dev, -1,  			      tps65910s, ARRAY_SIZE(tps65910s), -			      NULL, 0); +			      NULL, 0, NULL);  	if (ret < 0) {  		dev_err(&i2c->dev, "mfd_add_devices failed: %d\n", ret);  		return ret; diff --git a/drivers/mfd/tps65912-core.c b/drivers/mfd/tps65912-core.c index 74fd8cb5f37..4658b5bdcd8 100644 --- a/drivers/mfd/tps65912-core.c +++ b/drivers/mfd/tps65912-core.c @@ -146,7 +146,7 @@ int tps65912_device_init(struct tps65912 *tps65912)  	ret = mfd_add_devices(tps65912->dev, -1,  			      tps65912s, ARRAY_SIZE(tps65912s), -			      NULL, 0); +			      NULL, 0, NULL);  	if (ret < 0)  		goto err; diff --git a/drivers/mfd/twl4030-audio.c b/drivers/mfd/twl4030-audio.c index 838ce4eb444..77c9acb1458 100644 --- a/drivers/mfd/twl4030-audio.c +++ b/drivers/mfd/twl4030-audio.c @@ -223,7 +223,7 @@ static int __devinit twl4030_audio_probe(struct platform_device *pdev)  	if (childs)  		ret = mfd_add_devices(&pdev->dev, pdev->id, audio->cells, -				      childs, NULL, 0); +				      childs, NULL, 0, NULL);  	else {  		dev_err(&pdev->dev, "No platform data found for childs\n");  		ret = -ENODEV; diff --git a/drivers/mfd/twl6040-core.c b/drivers/mfd/twl6040-core.c index b0fad0ffca5..3dca5c195a2 100644 --- a/drivers/mfd/twl6040-core.c +++ b/drivers/mfd/twl6040-core.c @@ -632,7 +632,7 @@ static int __devinit twl6040_probe(struct i2c_client *client,  	}  	ret = mfd_add_devices(&client->dev, -1, twl6040->cells, children, -			      NULL, 0); +			      NULL, 0, NULL);  	if (ret)  		goto mfd_err; diff --git a/drivers/mfd/vx855.c b/drivers/mfd/vx855.c index 872aff21e4b..b9a636d44c7 100644 --- a/drivers/mfd/vx855.c +++ b/drivers/mfd/vx855.c @@ -102,7 +102,7 @@ static __devinit int vx855_probe(struct pci_dev *pdev,  	vx855_gpio_resources[1].end = vx855_gpio_resources[1].start + 3;  	ret = mfd_add_devices(&pdev->dev, -1, vx855_cells, ARRAY_SIZE(vx855_cells), -			NULL, 0); +			NULL, 0, NULL);  	/* we always return -ENODEV here in order to enable other  	 * drivers like old, not-yet-platform_device ported i2c-viapro */ diff --git a/drivers/mfd/wl1273-core.c b/drivers/mfd/wl1273-core.c index f39b756df56..86e0e4309fc 100644 --- a/drivers/mfd/wl1273-core.c +++ b/drivers/mfd/wl1273-core.c @@ -241,7 +241,7 @@ static int __devinit wl1273_core_probe(struct i2c_client *client,  		__func__, children);  	r = mfd_add_devices(&client->dev, -1, core->cells, -			    children, NULL, 0); +			    children, NULL, 0, NULL);  	if (r)  		goto err; diff --git a/drivers/mfd/wm831x-core.c b/drivers/mfd/wm831x-core.c index 946698fd2dc..30173103594 100644 --- a/drivers/mfd/wm831x-core.c +++ b/drivers/mfd/wm831x-core.c @@ -1813,27 +1813,27 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)  	case WM8310:  		ret = mfd_add_devices(wm831x->dev, wm831x_num,  				      wm8310_devs, ARRAY_SIZE(wm8310_devs), -				      NULL, 0); +				      NULL, 0, NULL);  		break;  	case WM8311:  		ret = mfd_add_devices(wm831x->dev, wm831x_num,  				      wm8311_devs, ARRAY_SIZE(wm8311_devs), -				      NULL, 0); +				      NULL, 0, NULL);  		if (!pdata || !pdata->disable_touch)  			mfd_add_devices(wm831x->dev, wm831x_num,  					touch_devs, ARRAY_SIZE(touch_devs), -					NULL, 0); +					NULL, 0, NULL);  		break;  	case WM8312:  		ret = mfd_add_devices(wm831x->dev, wm831x_num,  				      wm8312_devs, ARRAY_SIZE(wm8312_devs), -				      NULL, 0); +				      NULL, 0, NULL);  		if (!pdata || !pdata->disable_touch)  			mfd_add_devices(wm831x->dev, wm831x_num,  					touch_devs, ARRAY_SIZE(touch_devs), -					NULL, 0); +					NULL, 0, NULL);  		break;  	case WM8320: @@ -1842,7 +1842,7 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)  	case WM8326:  		ret = mfd_add_devices(wm831x->dev, wm831x_num,  				      wm8320_devs, ARRAY_SIZE(wm8320_devs), -				      NULL, 0); +				      NULL, 0, NULL);  		break;  	default: @@ -1867,7 +1867,7 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)  	if (ret & WM831X_XTAL_ENA) {  		ret = mfd_add_devices(wm831x->dev, wm831x_num,  				      rtc_devs, ARRAY_SIZE(rtc_devs), -				      NULL, 0); +				      NULL, 0, NULL);  		if (ret != 0) {  			dev_err(wm831x->dev, "Failed to add RTC: %d\n", ret);  			goto err_irq; @@ -1880,7 +1880,7 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)  		/* Treat errors as non-critical */  		ret = mfd_add_devices(wm831x->dev, wm831x_num, backlight_devs,  				      ARRAY_SIZE(backlight_devs), NULL, -				      0); +				      0, NULL);  		if (ret < 0)  			dev_err(wm831x->dev, "Failed to add backlight: %d\n",  				ret); diff --git a/drivers/mfd/wm8400-core.c b/drivers/mfd/wm8400-core.c index 4b7d378551d..639ca359242 100644 --- a/drivers/mfd/wm8400-core.c +++ b/drivers/mfd/wm8400-core.c @@ -70,7 +70,7 @@ static int wm8400_register_codec(struct wm8400 *wm8400)  		.pdata_size = sizeof(*wm8400),  	}; -	return mfd_add_devices(wm8400->dev, -1, &cell, 1, NULL, 0); +	return mfd_add_devices(wm8400->dev, -1, &cell, 1, NULL, 0, NULL);  }  /* diff --git a/drivers/mfd/wm8994-core.c b/drivers/mfd/wm8994-core.c index eec74aa55fd..2febf88cfce 100644 --- a/drivers/mfd/wm8994-core.c +++ b/drivers/mfd/wm8994-core.c @@ -414,7 +414,7 @@ static __devinit int wm8994_device_init(struct wm8994 *wm8994, int irq)  	ret = mfd_add_devices(wm8994->dev, -1,  			      wm8994_regulator_devs,  			      ARRAY_SIZE(wm8994_regulator_devs), -			      NULL, 0); +			      NULL, 0, NULL);  	if (ret != 0) {  		dev_err(wm8994->dev, "Failed to add children: %d\n", ret);  		goto err; @@ -648,7 +648,7 @@ static __devinit int wm8994_device_init(struct wm8994 *wm8994, int irq)  	ret = mfd_add_devices(wm8994->dev, -1,  			      wm8994_devs, ARRAY_SIZE(wm8994_devs), -			      NULL, 0); +			      NULL, 0, NULL);  	if (ret != 0) {  		dev_err(wm8994->dev, "Failed to add children: %d\n", ret);  		goto err_irq; diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index f1c84decb19..172a768036d 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -1411,7 +1411,8 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)  		/* complete ongoing async transfer before issuing discard */  		if (card->host->areq)  			mmc_blk_issue_rw_rq(mq, NULL); -		if (req->cmd_flags & REQ_SECURE) +		if (req->cmd_flags & REQ_SECURE && +			!(card->quirks & MMC_QUIRK_SEC_ERASE_TRIM_BROKEN))  			ret = mmc_blk_issue_secdiscard_rq(mq, req);  		else  			ret = mmc_blk_issue_discard_rq(mq, req); @@ -1716,6 +1717,7 @@ force_ro_fail:  #define CID_MANFID_SANDISK	0x2  #define CID_MANFID_TOSHIBA	0x11  #define CID_MANFID_MICRON	0x13 +#define CID_MANFID_SAMSUNG	0x15  static const struct mmc_fixup blk_fixups[] =  { @@ -1752,6 +1754,28 @@ static const struct mmc_fixup blk_fixups[] =  	MMC_FIXUP(CID_NAME_ANY, CID_MANFID_MICRON, 0x200, add_quirk_mmc,  		  MMC_QUIRK_LONG_READ_TIME), +	/* +	 * On these Samsung MoviNAND parts, performing secure erase or +	 * secure trim can result in unrecoverable corruption due to a +	 * firmware bug. +	 */ +	MMC_FIXUP("M8G2FA", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, +		  MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), +	MMC_FIXUP("MAG4FA", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, +		  MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), +	MMC_FIXUP("MBG8FA", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, +		  MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), +	MMC_FIXUP("MCGAFA", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, +		  MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), +	MMC_FIXUP("VAL00M", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, +		  MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), +	MMC_FIXUP("VYL00M", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, +		  MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), +	MMC_FIXUP("KYL00M", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, +		  MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), +	MMC_FIXUP("VZL00M", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, +		  MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), +  	END_FIXUP  }; diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c index 322412cec4e..a53c7c478e0 100644 --- a/drivers/mmc/host/atmel-mci.c +++ b/drivers/mmc/host/atmel-mci.c @@ -81,6 +81,7 @@ struct atmel_mci_caps {  	bool	has_bad_data_ordering;  	bool	need_reset_after_xfer;  	bool	need_blksz_mul_4; +	bool	need_notbusy_for_read_ops;  };  struct atmel_mci_dma { @@ -1625,7 +1626,8 @@ static void atmci_tasklet_func(unsigned long priv)  				__func__);  			atmci_set_completed(host, EVENT_XFER_COMPLETE); -			if (host->data->flags & MMC_DATA_WRITE) { +			if (host->caps.need_notbusy_for_read_ops || +			   (host->data->flags & MMC_DATA_WRITE)) {  				atmci_writel(host, ATMCI_IER, ATMCI_NOTBUSY);  				state = STATE_WAITING_NOTBUSY;  			} else if (host->mrq->stop) { @@ -2218,6 +2220,7 @@ static void __init atmci_get_cap(struct atmel_mci *host)  	host->caps.has_bad_data_ordering = 1;  	host->caps.need_reset_after_xfer = 1;  	host->caps.need_blksz_mul_4 = 1; +	host->caps.need_notbusy_for_read_ops = 0;  	/* keep only major version number */  	switch (version & 0xf00) { @@ -2238,6 +2241,7 @@ static void __init atmci_get_cap(struct atmel_mci *host)  	case 0x200:  		host->caps.has_rwproof = 1;  		host->caps.need_blksz_mul_4 = 0; +		host->caps.need_notbusy_for_read_ops = 1;  	case 0x100:  		host->caps.has_bad_data_ordering = 0;  		host->caps.need_reset_after_xfer = 0; diff --git a/drivers/mmc/host/bfin_sdh.c b/drivers/mmc/host/bfin_sdh.c index 03666174ca4..a17dd7363ce 100644 --- a/drivers/mmc/host/bfin_sdh.c +++ b/drivers/mmc/host/bfin_sdh.c @@ -49,13 +49,6 @@  #define bfin_write_SDH_CFG		bfin_write_RSI_CFG  #endif -struct dma_desc_array { -	unsigned long	start_addr; -	unsigned short	cfg; -	unsigned short	x_count; -	short		x_modify; -} __packed; -  struct sdh_host {  	struct mmc_host		*mmc;  	spinlock_t		lock; diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index 72dc3cde646..af40d227bec 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -627,6 +627,7 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot)  {  	struct dw_mci *host = slot->host;  	u32 div; +	u32 clk_en_a;  	if (slot->clock != host->current_speed) {  		div = host->bus_hz / slot->clock; @@ -659,9 +660,11 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot)  		mci_send_cmd(slot,  			     SDMMC_CMD_UPD_CLK | SDMMC_CMD_PRV_DAT_WAIT, 0); -		/* enable clock */ -		mci_writel(host, CLKENA, ((SDMMC_CLKEN_ENABLE | -			   SDMMC_CLKEN_LOW_PWR) << slot->id)); +		/* enable clock; only low power if no SDIO */ +		clk_en_a = SDMMC_CLKEN_ENABLE << slot->id; +		if (!(mci_readl(host, INTMASK) & SDMMC_INT_SDIO(slot->id))) +			clk_en_a |= SDMMC_CLKEN_LOW_PWR << slot->id; +		mci_writel(host, CLKENA, clk_en_a);  		/* inform CIU */  		mci_send_cmd(slot, @@ -862,6 +865,30 @@ static int dw_mci_get_cd(struct mmc_host *mmc)  	return present;  } +/* + * Disable lower power mode. + * + * Low power mode will stop the card clock when idle.  According to the + * description of the CLKENA register we should disable low power mode + * for SDIO cards if we need SDIO interrupts to work. + * + * This function is fast if low power mode is already disabled. + */ +static void dw_mci_disable_low_power(struct dw_mci_slot *slot) +{ +	struct dw_mci *host = slot->host; +	u32 clk_en_a; +	const u32 clken_low_pwr = SDMMC_CLKEN_LOW_PWR << slot->id; + +	clk_en_a = mci_readl(host, CLKENA); + +	if (clk_en_a & clken_low_pwr) { +		mci_writel(host, CLKENA, clk_en_a & ~clken_low_pwr); +		mci_send_cmd(slot, SDMMC_CMD_UPD_CLK | +			     SDMMC_CMD_PRV_DAT_WAIT, 0); +	} +} +  static void dw_mci_enable_sdio_irq(struct mmc_host *mmc, int enb)  {  	struct dw_mci_slot *slot = mmc_priv(mmc); @@ -871,6 +898,14 @@ static void dw_mci_enable_sdio_irq(struct mmc_host *mmc, int enb)  	/* Enable/disable Slot Specific SDIO interrupt */  	int_mask = mci_readl(host, INTMASK);  	if (enb) { +		/* +		 * Turn off low power mode if it was enabled.  This is a bit of +		 * a heavy operation and we disable / enable IRQs a lot, so +		 * we'll leave low power mode disabled and it will get +		 * re-enabled again in dw_mci_setup_bus(). +		 */ +		dw_mci_disable_low_power(slot); +  		mci_writel(host, INTMASK,  			   (int_mask | SDMMC_INT_SDIO(slot->id)));  	} else { @@ -1429,22 +1464,10 @@ static void dw_mci_read_data_pio(struct dw_mci *host)  			nbytes += len;  			remain -= len;  		} while (remain); -		sg_miter->consumed = offset; +		sg_miter->consumed = offset;  		status = mci_readl(host, MINTSTS);  		mci_writel(host, RINTSTS, SDMMC_INT_RXDR); -		if (status & DW_MCI_DATA_ERROR_FLAGS) { -			host->data_status = status; -			data->bytes_xfered += nbytes; -			sg_miter_stop(sg_miter); -			host->sg = NULL; -			smp_wmb(); - -			set_bit(EVENT_DATA_ERROR, &host->pending_events); - -			tasklet_schedule(&host->tasklet); -			return; -		}  	} while (status & SDMMC_INT_RXDR); /*if the RXDR is ready read again*/  	data->bytes_xfered += nbytes; @@ -1497,23 +1520,10 @@ static void dw_mci_write_data_pio(struct dw_mci *host)  			nbytes += len;  			remain -= len;  		} while (remain); -		sg_miter->consumed = offset; +		sg_miter->consumed = offset;  		status = mci_readl(host, MINTSTS);  		mci_writel(host, RINTSTS, SDMMC_INT_TXDR); -		if (status & DW_MCI_DATA_ERROR_FLAGS) { -			host->data_status = status; -			data->bytes_xfered += nbytes; -			sg_miter_stop(sg_miter); -			host->sg = NULL; - -			smp_wmb(); - -			set_bit(EVENT_DATA_ERROR, &host->pending_events); - -			tasklet_schedule(&host->tasklet); -			return; -		}  	} while (status & SDMMC_INT_TXDR); /* if TXDR write again */  	data->bytes_xfered += nbytes; @@ -1547,12 +1557,11 @@ static void dw_mci_cmd_interrupt(struct dw_mci *host, u32 status)  static irqreturn_t dw_mci_interrupt(int irq, void *dev_id)  {  	struct dw_mci *host = dev_id; -	u32 status, pending; +	u32 pending;  	unsigned int pass_count = 0;  	int i;  	do { -		status = mci_readl(host, RINTSTS);  		pending = mci_readl(host, MINTSTS); /* read-only mask reg */  		/* @@ -1570,7 +1579,7 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id)  		if (pending & DW_MCI_CMD_ERROR_FLAGS) {  			mci_writel(host, RINTSTS, DW_MCI_CMD_ERROR_FLAGS); -			host->cmd_status = status; +			host->cmd_status = pending;  			smp_wmb();  			set_bit(EVENT_CMD_COMPLETE, &host->pending_events);  		} @@ -1578,18 +1587,16 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id)  		if (pending & DW_MCI_DATA_ERROR_FLAGS) {  			/* if there is an error report DATA_ERROR */  			mci_writel(host, RINTSTS, DW_MCI_DATA_ERROR_FLAGS); -			host->data_status = status; +			host->data_status = pending;  			smp_wmb();  			set_bit(EVENT_DATA_ERROR, &host->pending_events); -			if (!(pending & (SDMMC_INT_DTO | SDMMC_INT_DCRC | -					 SDMMC_INT_SBE | SDMMC_INT_EBE))) -				tasklet_schedule(&host->tasklet); +			tasklet_schedule(&host->tasklet);  		}  		if (pending & SDMMC_INT_DATA_OVER) {  			mci_writel(host, RINTSTS, SDMMC_INT_DATA_OVER);  			if (!host->data_status) -				host->data_status = status; +				host->data_status = pending;  			smp_wmb();  			if (host->dir_status == DW_MCI_RECV_STATUS) {  				if (host->sg != NULL) @@ -1613,7 +1620,7 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id)  		if (pending & SDMMC_INT_CMD_DONE) {  			mci_writel(host, RINTSTS, SDMMC_INT_CMD_DONE); -			dw_mci_cmd_interrupt(host, status); +			dw_mci_cmd_interrupt(host, pending);  		}  		if (pending & SDMMC_INT_CD) { diff --git a/drivers/mmc/host/mxs-mmc.c b/drivers/mmc/host/mxs-mmc.c index a51f9309ffb..ad3fcea1269 100644 --- a/drivers/mmc/host/mxs-mmc.c +++ b/drivers/mmc/host/mxs-mmc.c @@ -285,11 +285,11 @@ static irqreturn_t mxs_mmc_irq_handler(int irq, void *dev_id)  	writel(stat & MXS_MMC_IRQ_BITS,  	       host->base + HW_SSP_CTRL1(host) + STMP_OFFSET_REG_CLR); +	spin_unlock(&host->lock); +  	if ((stat & BM_SSP_CTRL1_SDIO_IRQ) && (stat & BM_SSP_CTRL1_SDIO_IRQ_EN))  		mmc_signal_sdio_irq(host->mmc); -	spin_unlock(&host->lock); -  	if (stat & BM_SSP_CTRL1_RESP_TIMEOUT_IRQ)  		cmd->error = -ETIMEDOUT;  	else if (stat & BM_SSP_CTRL1_RESP_ERR_IRQ) @@ -644,11 +644,6 @@ static void mxs_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable)  		       host->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_SET);  		writel(BM_SSP_CTRL1_SDIO_IRQ_EN,  		       host->base + HW_SSP_CTRL1(host) + STMP_OFFSET_REG_SET); - -		if (readl(host->base + HW_SSP_STATUS(host)) & -				BM_SSP_STATUS_SDIO_IRQ) -			mmc_signal_sdio_irq(host->mmc); -  	} else {  		writel(BM_SSP_CTRL0_SDIO_IRQ_CHECK,  		       host->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_CLR); @@ -657,6 +652,11 @@ static void mxs_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable)  	}  	spin_unlock_irqrestore(&host->lock, flags); + +	if (enable && readl(host->base + HW_SSP_STATUS(host)) & +			BM_SSP_STATUS_SDIO_IRQ) +		mmc_signal_sdio_irq(host->mmc); +  }  static const struct mmc_host_ops mxs_mmc_ops = { diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c index 50e08f03aa6..a5999a74496 100644 --- a/drivers/mmc/host/omap.c +++ b/drivers/mmc/host/omap.c @@ -668,7 +668,7 @@ mmc_omap_clk_timer(unsigned long data)  static void  mmc_omap_xfer_data(struct mmc_omap_host *host, int write)  { -	int n; +	int n, nwords;  	if (host->buffer_bytes_left == 0) {  		host->sg_idx++; @@ -678,15 +678,23 @@ mmc_omap_xfer_data(struct mmc_omap_host *host, int write)  	n = 64;  	if (n > host->buffer_bytes_left)  		n = host->buffer_bytes_left; + +	nwords = n / 2; +	nwords += n & 1; /* handle odd number of bytes to transfer */ +  	host->buffer_bytes_left -= n;  	host->total_bytes_left -= n;  	host->data->bytes_xfered += n;  	if (write) { -		__raw_writesw(host->virt_base + OMAP_MMC_REG(host, DATA), host->buffer, n); +		__raw_writesw(host->virt_base + OMAP_MMC_REG(host, DATA), +			      host->buffer, nwords);  	} else { -		__raw_readsw(host->virt_base + OMAP_MMC_REG(host, DATA), host->buffer, n); +		__raw_readsw(host->virt_base + OMAP_MMC_REG(host, DATA), +			     host->buffer, nwords);  	} + +	host->buffer += nwords;  }  static inline void mmc_omap_report_irq(u16 status) diff --git a/drivers/mmc/host/sdhci-esdhc.h b/drivers/mmc/host/sdhci-esdhc.h index b97b2f5dafd..d25f9ab9a54 100644 --- a/drivers/mmc/host/sdhci-esdhc.h +++ b/drivers/mmc/host/sdhci-esdhc.h @@ -48,14 +48,14 @@ static inline void esdhc_set_clock(struct sdhci_host *host, unsigned int clock)  	int div = 1;  	u32 temp; +	if (clock == 0) +		goto out; +  	temp = sdhci_readl(host, ESDHC_SYSTEM_CONTROL);  	temp &= ~(ESDHC_CLOCK_IPGEN | ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN  		| ESDHC_CLOCK_MASK);  	sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL); -	if (clock == 0) -		goto out; -  	while (host->max_clk / pre_div / 16 > clock && pre_div < 256)  		pre_div *= 2; diff --git a/drivers/mtd/ubi/vtbl.c b/drivers/mtd/ubi/vtbl.c index 437bc193e17..568307cc7ca 100644 --- a/drivers/mtd/ubi/vtbl.c +++ b/drivers/mtd/ubi/vtbl.c @@ -340,7 +340,7 @@ retry:  	 * of this LEB as it will be deleted and freed in 'ubi_add_to_av()'.  	 */  	err = ubi_add_to_av(ubi, ai, new_aeb->pnum, new_aeb->ec, vid_hdr, 0); -	kfree(new_aeb); +	kmem_cache_free(ai->aeb_slab_cache, new_aeb);  	ubi_free_vid_hdr(ubi, vid_hdr);  	return err; @@ -353,7 +353,7 @@ write_error:  		list_add(&new_aeb->u.list, &ai->erase);  		goto retry;  	} -	kfree(new_aeb); +	kmem_cache_free(ai->aeb_slab_cache, new_aeb);  out_free:  	ubi_free_vid_hdr(ubi, vid_hdr);  	return err; diff --git a/drivers/net/can/mcp251x.c b/drivers/net/can/mcp251x.c index a580db29e50..26e7129332a 100644 --- a/drivers/net/can/mcp251x.c +++ b/drivers/net/can/mcp251x.c @@ -83,6 +83,11 @@  #define INSTRUCTION_LOAD_TXB(n)	(0x40 + 2 * (n))  #define INSTRUCTION_READ_RXB(n)	(((n) == 0) ? 0x90 : 0x94)  #define INSTRUCTION_RESET	0xC0 +#define RTS_TXB0		0x01 +#define RTS_TXB1		0x02 +#define RTS_TXB2		0x04 +#define INSTRUCTION_RTS(n)	(0x80 | ((n) & 0x07)) +  /* MPC251x registers */  #define CANSTAT	      0x0e @@ -397,6 +402,7 @@ static void mcp251x_hw_tx_frame(struct spi_device *spi, u8 *buf,  static void mcp251x_hw_tx(struct spi_device *spi, struct can_frame *frame,  			  int tx_buf_idx)  { +	struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev);  	u32 sid, eid, exide, rtr;  	u8 buf[SPI_TRANSFER_BUF_LEN]; @@ -418,7 +424,10 @@ static void mcp251x_hw_tx(struct spi_device *spi, struct can_frame *frame,  	buf[TXBDLC_OFF] = (rtr << DLC_RTR_SHIFT) | frame->can_dlc;  	memcpy(buf + TXBDAT_OFF, frame->data, frame->can_dlc);  	mcp251x_hw_tx_frame(spi, buf, frame->can_dlc, tx_buf_idx); -	mcp251x_write_reg(spi, TXBCTRL(tx_buf_idx), TXBCTRL_TXREQ); + +	/* use INSTRUCTION_RTS, to avoid "repeated frame problem" */ +	priv->spi_tx_buf[0] = INSTRUCTION_RTS(1 << tx_buf_idx); +	mcp251x_spi_trans(priv->spi, 1);  }  static void mcp251x_hw_rx_frame(struct spi_device *spi, u8 *buf, diff --git a/drivers/net/can/sja1000/sja1000_platform.c b/drivers/net/can/sja1000/sja1000_platform.c index 4f50145f648..662c5f7eb0c 100644 --- a/drivers/net/can/sja1000/sja1000_platform.c +++ b/drivers/net/can/sja1000/sja1000_platform.c @@ -109,7 +109,9 @@ static int sp_probe(struct platform_device *pdev)  	priv = netdev_priv(dev);  	dev->irq = res_irq->start; -	priv->irq_flags = res_irq->flags & (IRQF_TRIGGER_MASK | IRQF_SHARED); +	priv->irq_flags = res_irq->flags & IRQF_TRIGGER_MASK; +	if (res_irq->flags & IORESOURCE_IRQ_SHAREABLE) +		priv->irq_flags |= IRQF_SHARED;  	priv->reg_base = addr;  	/* The CAN clock frequency is half the oscillator clock frequency */  	priv->can.clock.freq = pdata->osc_freq / 2; diff --git a/drivers/net/can/softing/softing_fw.c b/drivers/net/can/softing/softing_fw.c index 31059617567..b595d3422b9 100644 --- a/drivers/net/can/softing/softing_fw.c +++ b/drivers/net/can/softing/softing_fw.c @@ -150,7 +150,7 @@ int softing_load_fw(const char *file, struct softing *card,  	const uint8_t *mem, *end, *dat;  	uint16_t type, len;  	uint32_t addr; -	uint8_t *buf = NULL; +	uint8_t *buf = NULL, *new_buf;  	int buflen = 0;  	int8_t type_end = 0; @@ -199,11 +199,12 @@ int softing_load_fw(const char *file, struct softing *card,  		if (len > buflen) {  			/* align buflen */  			buflen = (len + (1024-1)) & ~(1024-1); -			buf = krealloc(buf, buflen, GFP_KERNEL); -			if (!buf) { +			new_buf = krealloc(buf, buflen, GFP_KERNEL); +			if (!new_buf) {  				ret = -ENOMEM;  				goto failed;  			} +			buf = new_buf;  		}  		/* verify record data */  		memcpy_fromio(buf, &dpram[addr + offset], len); diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h index 463b9ec57d8..6d1a24acb77 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h @@ -1708,9 +1708,6 @@ struct bnx2x_func_init_params {  			continue;		\  		else -#define for_each_napi_rx_queue(bp, var) \ -	for ((var) = 0; (var) < bp->num_napi_queues; (var)++) -  /* Skip OOO FP */  #define for_each_tx_queue(bp, var) \  	for ((var) = 0; (var) < BNX2X_NUM_QUEUES(bp); (var)++) \ diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index e879e19eb0d..af20c6ee2cd 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c @@ -2046,6 +2046,8 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode)  	 */  	bnx2x_setup_tc(bp->dev, bp->max_cos); +	/* Add all NAPI objects */ +	bnx2x_add_all_napi(bp);  	bnx2x_napi_enable(bp);  	/* set pf load just before approaching the MCP */ @@ -2408,6 +2410,8 @@ int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode)  		/* Disable HW interrupts, NAPI */  		bnx2x_netif_stop(bp, 1); +		/* Delete all NAPI objects */ +		bnx2x_del_all_napi(bp);  		/* Release IRQs */  		bnx2x_free_irq(bp); diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h index dfa757e7429..dfd86a55f1d 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h @@ -710,17 +710,15 @@ static inline u16 bnx2x_tx_avail(struct bnx2x *bp,  	prod = txdata->tx_bd_prod;  	cons = txdata->tx_bd_cons; -	/* NUM_TX_RINGS = number of "next-page" entries -	   It will be used as a threshold */ -	used = SUB_S16(prod, cons) + (s16)NUM_TX_RINGS; +	used = SUB_S16(prod, cons);  #ifdef BNX2X_STOP_ON_ERROR  	WARN_ON(used < 0); -	WARN_ON(used > bp->tx_ring_size); -	WARN_ON((bp->tx_ring_size - used) > MAX_TX_AVAIL); +	WARN_ON(used > txdata->tx_ring_size); +	WARN_ON((txdata->tx_ring_size - used) > MAX_TX_AVAIL);  #endif -	return (s16)(bp->tx_ring_size) - used; +	return (s16)(txdata->tx_ring_size) - used;  }  static inline int bnx2x_tx_queue_has_work(struct bnx2x_fp_txdata *txdata) @@ -792,7 +790,7 @@ static inline void bnx2x_add_all_napi(struct bnx2x *bp)  	bp->num_napi_queues = bp->num_queues;  	/* Add NAPI objects */ -	for_each_napi_rx_queue(bp, i) +	for_each_rx_queue(bp, i)  		netif_napi_add(bp->dev, &bnx2x_fp(bp, i, napi),  			       bnx2x_poll, BNX2X_NAPI_WEIGHT);  } @@ -801,7 +799,7 @@ static inline void bnx2x_del_all_napi(struct bnx2x *bp)  {  	int i; -	for_each_napi_rx_queue(bp, i) +	for_each_rx_queue(bp, i)  		netif_napi_del(&bnx2x_fp(bp, i, napi));  } @@ -1088,6 +1086,7 @@ static inline void bnx2x_init_txdata(struct bnx2x *bp,  	txdata->txq_index = txq_index;  	txdata->tx_cons_sb = tx_cons_sb;  	txdata->parent_fp = fp; +	txdata->tx_ring_size = IS_FCOE_FP(fp) ? MAX_TX_AVAIL : bp->tx_ring_size;  	DP(NETIF_MSG_IFUP, "created tx data cid %d, txq %d\n",  	   txdata->cid, txdata->txq_index); diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dump.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dump.h index 3e4cff9b1eb..b926f58e983 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dump.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dump.h @@ -401,11 +401,11 @@ static const struct reg_addr reg_addrs[] = {  	{ 0x70000, 8, RI_ALL_ONLINE },  	{ 0x70020, 8184, RI_ALL_OFFLINE },  	{ 0x78000, 8192, RI_E3E3B0_OFFLINE }, -	{ 0x85000, 3, RI_ALL_ONLINE }, -	{ 0x8501c, 7, RI_ALL_ONLINE }, -	{ 0x85048, 1, RI_ALL_ONLINE }, -	{ 0x85200, 32, RI_ALL_ONLINE }, -	{ 0xb0000, 16384, RI_E1H_ONLINE }, +	{ 0x85000, 3, RI_ALL_OFFLINE }, +	{ 0x8501c, 7, RI_ALL_OFFLINE }, +	{ 0x85048, 1, RI_ALL_OFFLINE }, +	{ 0x85200, 32, RI_ALL_OFFLINE }, +	{ 0xb0000, 16384, RI_E1H_OFFLINE },  	{ 0xc1000, 7, RI_ALL_ONLINE },  	{ 0xc103c, 2, RI_E2E3E3B0_ONLINE },  	{ 0xc1800, 2, RI_ALL_ONLINE }, @@ -581,17 +581,12 @@ static const struct reg_addr reg_addrs[] = {  	{ 0x140188, 3, RI_E1E1HE2E3_ONLINE },  	{ 0x140194, 13, RI_ALL_ONLINE },  	{ 0x140200, 6, RI_E1E1HE2E3_ONLINE }, -	{ 0x140220, 4, RI_E2E3_ONLINE }, -	{ 0x140240, 4, RI_E2E3_ONLINE },  	{ 0x140260, 4, RI_E2E3_ONLINE },  	{ 0x140280, 4, RI_E2E3_ONLINE }, -	{ 0x1402a0, 4, RI_E2E3_ONLINE }, -	{ 0x1402c0, 4, RI_E2E3_ONLINE },  	{ 0x1402e0, 2, RI_E2E3_ONLINE },  	{ 0x1402e8, 2, RI_E2E3E3B0_ONLINE },  	{ 0x1402f0, 9, RI_E2E3_ONLINE },  	{ 0x140314, 44, RI_E3B0_ONLINE }, -	{ 0x1403d0, 70, RI_E3B0_ONLINE },  	{ 0x144000, 4, RI_E1E1H_ONLINE },  	{ 0x148000, 4, RI_E1E1H_ONLINE },  	{ 0x14c000, 4, RI_E1E1H_ONLINE }, @@ -704,7 +699,6 @@ static const struct reg_addr reg_addrs[] = {  	{ 0x180398, 1, RI_E2E3E3B0_ONLINE },  	{ 0x1803a0, 5, RI_E2E3E3B0_ONLINE },  	{ 0x1803b4, 2, RI_E3E3B0_ONLINE }, -	{ 0x180400, 1, RI_ALL_ONLINE },  	{ 0x180404, 255, RI_E1E1H_OFFLINE },  	{ 0x181000, 4, RI_ALL_ONLINE },  	{ 0x181010, 1020, RI_ALL_OFFLINE }, @@ -800,9 +794,9 @@ static const struct reg_addr reg_addrs[] = {  	{ 0x1b905c, 1, RI_E3E3B0_ONLINE },  	{ 0x1b9064, 1, RI_E3B0_ONLINE },  	{ 0x1b9080, 10, RI_E3B0_ONLINE }, -	{ 0x1b9400, 14, RI_E2E3E3B0_ONLINE }, -	{ 0x1b943c, 19, RI_E2E3E3B0_ONLINE }, -	{ 0x1b9490, 10, RI_E2E3E3B0_ONLINE }, +	{ 0x1b9400, 14, RI_E2E3E3B0_OFFLINE }, +	{ 0x1b943c, 19, RI_E2E3E3B0_OFFLINE }, +	{ 0x1b9490, 10, RI_E2E3E3B0_OFFLINE },  	{ 0x1c0000, 2, RI_ALL_ONLINE },  	{ 0x200000, 65, RI_ALL_ONLINE },  	{ 0x20014c, 2, RI_E1HE2E3E3B0_ONLINE }, @@ -814,7 +808,6 @@ static const struct reg_addr reg_addrs[] = {  	{ 0x200398, 1, RI_E2E3E3B0_ONLINE },  	{ 0x2003a0, 1, RI_E2E3E3B0_ONLINE },  	{ 0x2003a8, 2, RI_E2E3E3B0_ONLINE }, -	{ 0x200400, 1, RI_ALL_ONLINE },  	{ 0x200404, 255, RI_E1E1H_OFFLINE },  	{ 0x202000, 4, RI_ALL_ONLINE },  	{ 0x202010, 2044, RI_ALL_OFFLINE }, @@ -921,7 +914,6 @@ static const struct reg_addr reg_addrs[] = {  	{ 0x280398, 1, RI_E2E3E3B0_ONLINE },  	{ 0x2803a0, 1, RI_E2E3E3B0_ONLINE },  	{ 0x2803a8, 2, RI_E2E3E3B0_ONLINE }, -	{ 0x280400, 1, RI_ALL_ONLINE },  	{ 0x280404, 255, RI_E1E1H_OFFLINE },  	{ 0x282000, 4, RI_ALL_ONLINE },  	{ 0x282010, 2044, RI_ALL_OFFLINE }, @@ -1031,7 +1023,6 @@ static const struct reg_addr reg_addrs[] = {  	{ 0x300398, 1, RI_E2E3E3B0_ONLINE },  	{ 0x3003a0, 1, RI_E2E3E3B0_ONLINE },  	{ 0x3003a8, 2, RI_E2E3E3B0_ONLINE }, -	{ 0x300400, 1, RI_ALL_ONLINE },  	{ 0x300404, 255, RI_E1E1H_OFFLINE },  	{ 0x302000, 4, RI_ALL_ONLINE },  	{ 0x302010, 2044, RI_ALL_OFFLINE }, diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c index fc4e0e3885b..ebf40cd7aa1 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c @@ -775,7 +775,7 @@ static void bnx2x_get_regs(struct net_device *dev,  	struct bnx2x *bp = netdev_priv(dev);  	struct dump_hdr dump_hdr = {0}; -	regs->version = 0; +	regs->version = 1;  	memset(p, 0, regs->len);  	if (!netif_running(bp->dev)) @@ -1587,6 +1587,12 @@ static int bnx2x_set_pauseparam(struct net_device *dev,  			bp->link_params.req_flow_ctrl[cfg_idx] =  				BNX2X_FLOW_CTRL_AUTO;  		} +		bp->link_params.req_fc_auto_adv = BNX2X_FLOW_CTRL_NONE; +		if (epause->rx_pause) +			bp->link_params.req_fc_auto_adv |= BNX2X_FLOW_CTRL_RX; + +		if (epause->tx_pause) +			bp->link_params.req_fc_auto_adv |= BNX2X_FLOW_CTRL_TX;  	}  	DP(BNX2X_MSG_ETHTOOL, @@ -2888,11 +2894,9 @@ static void bnx2x_get_channels(struct net_device *dev,   */  static void bnx2x_change_num_queues(struct bnx2x *bp, int num_rss)  { -	bnx2x_del_all_napi(bp);  	bnx2x_disable_msi(bp);  	BNX2X_NUM_QUEUES(bp) = num_rss + NON_ETH_CONTEXT_USE;  	bnx2x_set_int_mode(bp); -	bnx2x_add_all_napi(bp);  }  /** diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c index f4beb46c470..b046beb435b 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c @@ -2667,9 +2667,11 @@ int bnx2x_update_pfc(struct link_params *params,  		return bnx2x_status;  	DP(NETIF_MSG_LINK, "About to update PFC in BMAC\n"); -	if (CHIP_IS_E3(bp)) -		bnx2x_update_pfc_xmac(params, vars, 0); -	else { + +	if (CHIP_IS_E3(bp)) { +		if (vars->mac_type == MAC_TYPE_XMAC) +			bnx2x_update_pfc_xmac(params, vars, 0); +	} else {  		val = REG_RD(bp, MISC_REG_RESET_REG_2);  		if ((val &  		     (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << params->port)) @@ -5432,7 +5434,7 @@ static int bnx2x_get_link_speed_duplex(struct bnx2x_phy *phy,  		switch (speed_mask) {  		case GP_STATUS_10M:  			vars->line_speed = SPEED_10; -			if (vars->duplex == DUPLEX_FULL) +			if (is_duplex == DUPLEX_FULL)  				vars->link_status |= LINK_10TFD;  			else  				vars->link_status |= LINK_10THD; @@ -5440,7 +5442,7 @@ static int bnx2x_get_link_speed_duplex(struct bnx2x_phy *phy,  		case GP_STATUS_100M:  			vars->line_speed = SPEED_100; -			if (vars->duplex == DUPLEX_FULL) +			if (is_duplex == DUPLEX_FULL)  				vars->link_status |= LINK_100TXFD;  			else  				vars->link_status |= LINK_100TXHD; @@ -5449,7 +5451,7 @@ static int bnx2x_get_link_speed_duplex(struct bnx2x_phy *phy,  		case GP_STATUS_1G:  		case GP_STATUS_1G_KX:  			vars->line_speed = SPEED_1000; -			if (vars->duplex == DUPLEX_FULL) +			if (is_duplex == DUPLEX_FULL)  				vars->link_status |= LINK_1000TFD;  			else  				vars->link_status |= LINK_1000THD; @@ -5457,7 +5459,7 @@ static int bnx2x_get_link_speed_duplex(struct bnx2x_phy *phy,  		case GP_STATUS_2_5G:  			vars->line_speed = SPEED_2500; -			if (vars->duplex == DUPLEX_FULL) +			if (is_duplex == DUPLEX_FULL)  				vars->link_status |= LINK_2500TFD;  			else  				vars->link_status |= LINK_2500THD; @@ -5531,6 +5533,7 @@ static int bnx2x_link_settings_status(struct bnx2x_phy *phy,  	if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) {  		if (SINGLE_MEDIA_DIRECT(params)) { +			vars->duplex = duplex;  			bnx2x_flow_ctrl_resolve(phy, params, vars, gp_status);  			if (phy->req_line_speed == SPEED_AUTO_NEG)  				bnx2x_xgxs_an_resolve(phy, params, vars, @@ -5625,6 +5628,7 @@ static int bnx2x_warpcore_read_status(struct bnx2x_phy *phy,  					LINK_STATUS_PARALLEL_DETECTION_USED;  			}  			bnx2x_ext_phy_resolve_fc(phy, params, vars); +			vars->duplex = duplex;  		}  	} diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 02b5a343b19..211753e01f8 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -7561,8 +7561,14 @@ int bnx2x_set_mac_one(struct bnx2x *bp, u8 *mac,  	}  	rc = bnx2x_config_vlan_mac(bp, &ramrod_param); -	if (rc < 0) + +	if (rc == -EEXIST) { +		DP(BNX2X_MSG_SP, "Failed to schedule ADD operations: %d\n", rc); +		/* do not treat adding same MAC as error */ +		rc = 0; +	} else if (rc < 0)  		BNX2X_ERR("%s MAC failed\n", (set ? "Set" : "Del")); +  	return rc;  } @@ -8427,6 +8433,8 @@ unload_error:  	/* Disable HW interrupts, NAPI */  	bnx2x_netif_stop(bp, 1); +	/* Delete all NAPI objects */ +	bnx2x_del_all_napi(bp);  	/* Release IRQs */  	bnx2x_free_irq(bp); @@ -10292,13 +10300,11 @@ static void __devinit bnx2x_get_fcoe_info(struct bnx2x *bp)  				dev_info.port_hw_config[port].  				 fcoe_wwn_node_name_lower);  	} else if (!IS_MF_SD(bp)) { -		u32 cfg = MF_CFG_RD(bp, func_ext_config[func].func_cfg); -  		/*  		 * Read the WWN info only if the FCoE feature is enabled for  		 * this function.  		 */ -		if (cfg & MACP_FUNC_CFG_FLAGS_FCOE_OFFLOAD) +		if (BNX2X_MF_EXT_PROTOCOL_FCOE(bp) && !CHIP_IS_E1x(bp))  			bnx2x_get_ext_wwn_info(bp, func);  	} else if (IS_MF_FCOE_SD(bp)) @@ -11071,7 +11077,14 @@ static int bnx2x_set_uc_list(struct bnx2x *bp)  	netdev_for_each_uc_addr(ha, dev) {  		rc = bnx2x_set_mac_one(bp, bnx2x_uc_addr(ha), mac_obj, true,  				       BNX2X_UC_LIST_MAC, &ramrod_flags); -		if (rc < 0) { +		if (rc == -EEXIST) { +			DP(BNX2X_MSG_SP, +			   "Failed to schedule ADD operations: %d\n", rc); +			/* do not treat adding same MAC as error */ +			rc = 0; + +		} else if (rc < 0) { +  			BNX2X_ERR("Failed to schedule ADD operations: %d\n",  				  rc);  			return rc; @@ -11229,10 +11242,12 @@ static int bnx2x_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)  static void poll_bnx2x(struct net_device *dev)  {  	struct bnx2x *bp = netdev_priv(dev); +	int i; -	disable_irq(bp->pdev->irq); -	bnx2x_interrupt(bp->pdev->irq, dev); -	enable_irq(bp->pdev->irq); +	for_each_eth_queue(bp, i) { +		struct bnx2x_fastpath *fp = &bp->fp[i]; +		napi_schedule(&bnx2x_fp(bp, fp->index, napi)); +	}  }  #endif @@ -11899,9 +11914,6 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev,  	 */  	bnx2x_set_int_mode(bp); -	/* Add all NAPI objects */ -	bnx2x_add_all_napi(bp); -  	rc = register_netdev(dev);  	if (rc) {  		dev_err(&pdev->dev, "Cannot register net device\n"); @@ -11976,9 +11988,6 @@ static void __devexit bnx2x_remove_one(struct pci_dev *pdev)  	unregister_netdev(dev); -	/* Delete all NAPI objects */ -	bnx2x_del_all_napi(bp); -  	/* Power on: we can't let PCI layer write to us while we are in D3 */  	bnx2x_set_power_state(bp, PCI_D0); @@ -12025,6 +12034,8 @@ static int bnx2x_eeh_nic_unload(struct bnx2x *bp)  	bnx2x_tx_disable(bp);  	bnx2x_netif_stop(bp, 0); +	/* Delete all NAPI objects */ +	bnx2x_del_all_napi(bp);  	del_timer_sync(&bp->timer); diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c index 332db64dd5b..a1d0446b39b 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c @@ -101,6 +101,11 @@ static void bnx2x_hw_stats_post(struct bnx2x *bp)  	if (CHIP_REV_IS_SLOW(bp))  		return; +	/* Update MCP's statistics if possible */ +	if (bp->func_stx) +		memcpy(bnx2x_sp(bp, func_stats), &bp->func_stats, +		       sizeof(bp->func_stats)); +  	/* loader */  	if (bp->executer_idx) {  		int loader_idx = PMF_DMAE_C(bp); @@ -128,8 +133,6 @@ static void bnx2x_hw_stats_post(struct bnx2x *bp)  	} else if (bp->func_stx) {  		*stats_comp = 0; -		memcpy(bnx2x_sp(bp, func_stats), &bp->func_stats, -		       sizeof(bp->func_stats));  		bnx2x_post_dmae(bp, dmae, INIT_DMAE_C(bp));  	}  } @@ -1151,9 +1154,11 @@ static void bnx2x_stats_update(struct bnx2x *bp)  	if (bp->port.pmf)  		bnx2x_hw_stats_update(bp); -	if (bnx2x_storm_stats_update(bp) && (bp->stats_pending++ == 3)) { -		BNX2X_ERR("storm stats were not updated for 3 times\n"); -		bnx2x_panic(); +	if (bnx2x_storm_stats_update(bp)) { +		if (bp->stats_pending++ == 3) { +			BNX2X_ERR("storm stats were not updated for 3 times\n"); +			bnx2x_panic(); +		}  		return;  	} diff --git a/drivers/net/ethernet/cirrus/cs89x0.c b/drivers/net/ethernet/cirrus/cs89x0.c index 845b2020f29..13844695778 100644 --- a/drivers/net/ethernet/cirrus/cs89x0.c +++ b/drivers/net/ethernet/cirrus/cs89x0.c @@ -1243,6 +1243,7 @@ static void set_multicast_list(struct net_device *dev)  {  	struct net_local *lp = netdev_priv(dev);  	unsigned long flags; +	u16 cfg;  	spin_lock_irqsave(&lp->lock, flags);  	if (dev->flags & IFF_PROMISC) @@ -1260,11 +1261,10 @@ static void set_multicast_list(struct net_device *dev)  	/* in promiscuous mode, we accept errored packets,  	 * so we have to enable interrupts on them also  	 */ -	writereg(dev, PP_RxCFG, -		 (lp->curr_rx_cfg | -		  (lp->rx_mode == RX_ALL_ACCEPT) -		  ? (RX_CRC_ERROR_ENBL | RX_RUNT_ENBL | RX_EXTRA_DATA_ENBL) -		  : 0)); +	cfg = lp->curr_rx_cfg; +	if (lp->rx_mode == RX_ALL_ACCEPT) +		cfg |= RX_CRC_ERROR_ENBL | RX_RUNT_ENBL | RX_EXTRA_DATA_ENBL; +	writereg(dev, PP_RxCFG, cfg);  	spin_unlock_irqrestore(&lp->lock, flags);  } diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c index 7fac97b4bb5..8c63d06ab12 100644 --- a/drivers/net/ethernet/emulex/benet/be_cmds.c +++ b/drivers/net/ethernet/emulex/benet/be_cmds.c @@ -259,7 +259,7 @@ int be_process_mcc(struct be_adapter *adapter)  	int num = 0, status = 0;  	struct be_mcc_obj *mcc_obj = &adapter->mcc_obj; -	spin_lock_bh(&adapter->mcc_cq_lock); +	spin_lock(&adapter->mcc_cq_lock);  	while ((compl = be_mcc_compl_get(adapter))) {  		if (compl->flags & CQE_FLAGS_ASYNC_MASK) {  			/* Interpret flags as an async trailer */ @@ -280,7 +280,7 @@ int be_process_mcc(struct be_adapter *adapter)  	if (num)  		be_cq_notify(adapter, mcc_obj->cq.id, mcc_obj->rearm_cq, num); -	spin_unlock_bh(&adapter->mcc_cq_lock); +	spin_unlock(&adapter->mcc_cq_lock);  	return status;  } @@ -295,7 +295,9 @@ static int be_mcc_wait_compl(struct be_adapter *adapter)  		if (be_error(adapter))  			return -EIO; +		local_bh_disable();  		status = be_process_mcc(adapter); +		local_bh_enable();  		if (atomic_read(&mcc_obj->q.used) == 0)  			break; diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index 90a903d83d8..78b8aa8069f 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -3763,7 +3763,9 @@ static void be_worker(struct work_struct *work)  	/* when interrupts are not yet enabled, just reap any pending  	* mcc completions */  	if (!netif_running(adapter->netdev)) { +		local_bh_disable();  		be_process_mcc(adapter); +		local_bh_enable();  		goto reschedule;  	} diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c index 4605f724668..d3233f59a82 100644 --- a/drivers/net/ethernet/freescale/gianfar.c +++ b/drivers/net/ethernet/freescale/gianfar.c @@ -1041,7 +1041,7 @@ static int gfar_probe(struct platform_device *ofdev)  	if (priv->device_flags & FSL_GIANFAR_DEV_HAS_VLAN) {  		dev->hw_features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; -		dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; +		dev->features |= NETIF_F_HW_VLAN_RX;  	}  	if (priv->device_flags & FSL_GIANFAR_DEV_HAS_EXTENDED_HASH) { diff --git a/drivers/net/ethernet/i825xx/znet.c b/drivers/net/ethernet/i825xx/znet.c index bd1f1ef91e1..ba4e0cea350 100644 --- a/drivers/net/ethernet/i825xx/znet.c +++ b/drivers/net/ethernet/i825xx/znet.c @@ -139,8 +139,11 @@ struct znet_private {  /* Only one can be built-in;-> */  static struct net_device *znet_dev; +#define NETIDBLK_MAGIC		"NETIDBLK" +#define NETIDBLK_MAGIC_SIZE	8 +  struct netidblk { -	char magic[8];		/* The magic number (string) "NETIDBLK" */ +	char magic[NETIDBLK_MAGIC_SIZE];	/* The magic number (string) "NETIDBLK" */  	unsigned char netid[8]; /* The physical station address */  	char nettype, globalopt;  	char vendor[8];		/* The machine vendor and product name. */ @@ -373,14 +376,16 @@ static int __init znet_probe (void)  	struct znet_private *znet;  	struct net_device *dev;  	char *p; +	char *plast = phys_to_virt(0x100000 - NETIDBLK_MAGIC_SIZE);  	int err = -ENOMEM;  	/* This code scans the region 0xf0000 to 0xfffff for a "NETIDBLK". */ -	for(p = (char *)phys_to_virt(0xf0000); p < (char *)phys_to_virt(0x100000); p++) -		if (*p == 'N'  &&  strncmp(p, "NETIDBLK", 8) == 0) +	for(p = (char *)phys_to_virt(0xf0000); p <= plast; p++) +		if (*p == 'N' && +		    strncmp(p, NETIDBLK_MAGIC, NETIDBLK_MAGIC_SIZE) == 0)  			break; -	if (p >= (char *)phys_to_virt(0x100000)) { +	if (p > plast) {  		if (znet_debug > 1)  			printk(KERN_INFO "No Z-Note ethernet adaptor found.\n");  		return -ENODEV; diff --git a/drivers/net/ethernet/ibm/ibmveth.c b/drivers/net/ethernet/ibm/ibmveth.c index 9010cea68bc..b68d28a130e 100644 --- a/drivers/net/ethernet/ibm/ibmveth.c +++ b/drivers/net/ethernet/ibm/ibmveth.c @@ -472,14 +472,9 @@ static void ibmveth_cleanup(struct ibmveth_adapter *adapter)  	}  	if (adapter->rx_queue.queue_addr != NULL) { -		if (!dma_mapping_error(dev, adapter->rx_queue.queue_dma)) { -			dma_unmap_single(dev, -					adapter->rx_queue.queue_dma, -					adapter->rx_queue.queue_len, -					DMA_BIDIRECTIONAL); -			adapter->rx_queue.queue_dma = DMA_ERROR_CODE; -		} -		kfree(adapter->rx_queue.queue_addr); +		dma_free_coherent(dev, adapter->rx_queue.queue_len, +				  adapter->rx_queue.queue_addr, +				  adapter->rx_queue.queue_dma);  		adapter->rx_queue.queue_addr = NULL;  	} @@ -556,10 +551,13 @@ static int ibmveth_open(struct net_device *netdev)  		goto err_out;  	} +	dev = &adapter->vdev->dev; +  	adapter->rx_queue.queue_len = sizeof(struct ibmveth_rx_q_entry) *  						rxq_entries; -	adapter->rx_queue.queue_addr = kmalloc(adapter->rx_queue.queue_len, -						GFP_KERNEL); +	adapter->rx_queue.queue_addr = +	    dma_alloc_coherent(dev, adapter->rx_queue.queue_len, +			       &adapter->rx_queue.queue_dma, GFP_KERNEL);  	if (!adapter->rx_queue.queue_addr) {  		netdev_err(netdev, "unable to allocate rx queue pages\n"); @@ -567,19 +565,13 @@ static int ibmveth_open(struct net_device *netdev)  		goto err_out;  	} -	dev = &adapter->vdev->dev; -  	adapter->buffer_list_dma = dma_map_single(dev,  			adapter->buffer_list_addr, 4096, DMA_BIDIRECTIONAL);  	adapter->filter_list_dma = dma_map_single(dev,  			adapter->filter_list_addr, 4096, DMA_BIDIRECTIONAL); -	adapter->rx_queue.queue_dma = dma_map_single(dev, -			adapter->rx_queue.queue_addr, -			adapter->rx_queue.queue_len, DMA_BIDIRECTIONAL);  	if ((dma_mapping_error(dev, adapter->buffer_list_dma)) || -	    (dma_mapping_error(dev, adapter->filter_list_dma)) || -	    (dma_mapping_error(dev, adapter->rx_queue.queue_dma))) { +	    (dma_mapping_error(dev, adapter->filter_list_dma))) {  		netdev_err(netdev, "unable to map filter or buffer list "  			   "pages\n");  		rc = -ENOMEM; diff --git a/drivers/net/ethernet/intel/e1000e/e1000.h b/drivers/net/ethernet/intel/e1000e/e1000.h index cd153326c3c..cb3356c9af8 100644 --- a/drivers/net/ethernet/intel/e1000e/e1000.h +++ b/drivers/net/ethernet/intel/e1000e/e1000.h @@ -310,6 +310,7 @@ struct e1000_adapter {  	 */  	struct e1000_ring *tx_ring /* One per active queue */  						____cacheline_aligned_in_smp; +	u32 tx_fifo_limit;  	struct napi_struct napi; diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index 46c3b1f9ff8..d01a099475a 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -3517,6 +3517,15 @@ void e1000e_reset(struct e1000_adapter *adapter)  	}  	/* +	 * Alignment of Tx data is on an arbitrary byte boundary with the +	 * maximum size per Tx descriptor limited only to the transmit +	 * allocation of the packet buffer minus 96 bytes with an upper +	 * limit of 24KB due to receive synchronization limitations. +	 */ +	adapter->tx_fifo_limit = min_t(u32, ((er32(PBA) >> 16) << 10) - 96, +				       24 << 10); + +	/*  	 * Disable Adaptive Interrupt Moderation if 2 full packets cannot  	 * fit in receive buffer.  	 */ @@ -4785,12 +4794,9 @@ static bool e1000_tx_csum(struct e1000_ring *tx_ring, struct sk_buff *skb)  	return 1;  } -#define E1000_MAX_PER_TXD	8192 -#define E1000_MAX_TXD_PWR	12 -  static int e1000_tx_map(struct e1000_ring *tx_ring, struct sk_buff *skb,  			unsigned int first, unsigned int max_per_txd, -			unsigned int nr_frags, unsigned int mss) +			unsigned int nr_frags)  {  	struct e1000_adapter *adapter = tx_ring->adapter;  	struct pci_dev *pdev = adapter->pdev; @@ -5023,20 +5029,19 @@ static int __e1000_maybe_stop_tx(struct e1000_ring *tx_ring, int size)  static int e1000_maybe_stop_tx(struct e1000_ring *tx_ring, int size)  { +	BUG_ON(size > tx_ring->count); +  	if (e1000_desc_unused(tx_ring) >= size)  		return 0;  	return __e1000_maybe_stop_tx(tx_ring, size);  } -#define TXD_USE_COUNT(S, X) (((S) >> (X)) + 1)  static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,  				    struct net_device *netdev)  {  	struct e1000_adapter *adapter = netdev_priv(netdev);  	struct e1000_ring *tx_ring = adapter->tx_ring;  	unsigned int first; -	unsigned int max_per_txd = E1000_MAX_PER_TXD; -	unsigned int max_txd_pwr = E1000_MAX_TXD_PWR;  	unsigned int tx_flags = 0;  	unsigned int len = skb_headlen(skb);  	unsigned int nr_frags; @@ -5056,18 +5061,8 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,  	}  	mss = skb_shinfo(skb)->gso_size; -	/* -	 * The controller does a simple calculation to -	 * make sure there is enough room in the FIFO before -	 * initiating the DMA for each buffer.  The calc is: -	 * 4 = ceil(buffer len/mss).  To make sure we don't -	 * overrun the FIFO, adjust the max buffer len if mss -	 * drops. -	 */  	if (mss) {  		u8 hdr_len; -		max_per_txd = min(mss << 2, max_per_txd); -		max_txd_pwr = fls(max_per_txd) - 1;  		/*  		 * TSO Workaround for 82571/2/3 Controllers -- if skb->data @@ -5097,12 +5092,12 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,  		count++;  	count++; -	count += TXD_USE_COUNT(len, max_txd_pwr); +	count += DIV_ROUND_UP(len, adapter->tx_fifo_limit);  	nr_frags = skb_shinfo(skb)->nr_frags;  	for (f = 0; f < nr_frags; f++) -		count += TXD_USE_COUNT(skb_frag_size(&skb_shinfo(skb)->frags[f]), -				       max_txd_pwr); +		count += DIV_ROUND_UP(skb_frag_size(&skb_shinfo(skb)->frags[f]), +				      adapter->tx_fifo_limit);  	if (adapter->hw.mac.tx_pkt_filtering)  		e1000_transfer_dhcp_info(adapter, skb); @@ -5144,15 +5139,18 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,  		tx_flags |= E1000_TX_FLAGS_NO_FCS;  	/* if count is 0 then mapping error has occurred */ -	count = e1000_tx_map(tx_ring, skb, first, max_per_txd, nr_frags, mss); +	count = e1000_tx_map(tx_ring, skb, first, adapter->tx_fifo_limit, +			     nr_frags);  	if (count) {  		skb_tx_timestamp(skb);  		netdev_sent_queue(netdev, skb->len);  		e1000_tx_queue(tx_ring, tx_flags, count);  		/* Make sure there is space in the ring for the next send. */ -		e1000_maybe_stop_tx(tx_ring, MAX_SKB_FRAGS + 2); - +		e1000_maybe_stop_tx(tx_ring, +				    (MAX_SKB_FRAGS * +				     DIV_ROUND_UP(PAGE_SIZE, +						  adapter->tx_fifo_limit) + 2));  	} else {  		dev_kfree_skb_any(skb);  		tx_ring->buffer_info[first].time_stamp = 0; @@ -6327,8 +6325,8 @@ static int __devinit e1000_probe(struct pci_dev *pdev,  	adapter->hw.phy.autoneg_advertised = 0x2f;  	/* ring size defaults */ -	adapter->rx_ring->count = 256; -	adapter->tx_ring->count = 256; +	adapter->rx_ring->count = E1000_DEFAULT_RXD; +	adapter->tx_ring->count = E1000_DEFAULT_TXD;  	/*  	 * Initial Wake on LAN setting - If APM wake is enabled in diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c index 827b72dfce9..2f816c6aed7 100644 --- a/drivers/net/ethernet/mellanox/mlx4/main.c +++ b/drivers/net/ethernet/mellanox/mlx4/main.c @@ -1234,13 +1234,13 @@ static int mlx4_init_hca(struct mlx4_dev *dev)  				mlx4_info(dev, "non-primary physical function, skipping.\n");  			else  				mlx4_err(dev, "QUERY_FW command failed, aborting.\n"); -			goto unmap_bf; +			return err;  		}  		err = mlx4_load_fw(dev);  		if (err) {  			mlx4_err(dev, "Failed to start FW, aborting.\n"); -			goto unmap_bf; +			return err;  		}  		mlx4_cfg.log_pg_sz_m = 1; @@ -1304,7 +1304,7 @@ static int mlx4_init_hca(struct mlx4_dev *dev)  		err = mlx4_init_slave(dev);  		if (err) {  			mlx4_err(dev, "Failed to initialize slave\n"); -			goto unmap_bf; +			return err;  		}  		err = mlx4_slave_cap(dev); @@ -1324,7 +1324,7 @@ static int mlx4_init_hca(struct mlx4_dev *dev)  	err = mlx4_QUERY_ADAPTER(dev, &adapter);  	if (err) {  		mlx4_err(dev, "QUERY_ADAPTER command failed, aborting.\n"); -		goto err_close; +		goto unmap_bf;  	}  	priv->eq_table.inta_pin = adapter.inta_pin; @@ -1332,6 +1332,9 @@ static int mlx4_init_hca(struct mlx4_dev *dev)  	return 0; +unmap_bf: +	unmap_bf_area(dev); +  err_close:  	mlx4_close_hca(dev); @@ -1344,8 +1347,6 @@ err_stop_fw:  		mlx4_UNMAP_FA(dev);  		mlx4_free_icm(dev, priv->fw.fw_icm, 0);  	} -unmap_bf: -	unmap_bf_area(dev);  	return err;  } @@ -1996,7 +1997,8 @@ static int __mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id)  	}  slave_start: -	if (mlx4_cmd_init(dev)) { +	err = mlx4_cmd_init(dev); +	if (err) {  		mlx4_err(dev, "Failed to init command interface, aborting.\n");  		goto err_sriov;  	} diff --git a/drivers/net/ethernet/mellanox/mlx4/mcg.c b/drivers/net/ethernet/mellanox/mlx4/mcg.c index a018ea2a43d..e151c21baf2 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mcg.c +++ b/drivers/net/ethernet/mellanox/mlx4/mcg.c @@ -137,11 +137,11 @@ static int mlx4_GID_HASH(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *mailbox,  	return err;  } -static struct mlx4_promisc_qp *get_promisc_qp(struct mlx4_dev *dev, u8 pf_num, +static struct mlx4_promisc_qp *get_promisc_qp(struct mlx4_dev *dev, u8 port,  					      enum mlx4_steer_type steer,  					      u32 qpn)  { -	struct mlx4_steer *s_steer = &mlx4_priv(dev)->steer[pf_num]; +	struct mlx4_steer *s_steer = &mlx4_priv(dev)->steer[port - 1];  	struct mlx4_promisc_qp *pqp;  	list_for_each_entry(pqp, &s_steer->promisc_qps[steer], list) { @@ -182,7 +182,7 @@ static int new_steering_entry(struct mlx4_dev *dev, u8 port,  	/* If the given qpn is also a promisc qp,  	 * it should be inserted to duplicates list  	 */ -	pqp = get_promisc_qp(dev, 0, steer, qpn); +	pqp = get_promisc_qp(dev, port, steer, qpn);  	if (pqp) {  		dqp = kmalloc(sizeof *dqp, GFP_KERNEL);  		if (!dqp) { @@ -256,7 +256,7 @@ static int existing_steering_entry(struct mlx4_dev *dev, u8 port,  	s_steer = &mlx4_priv(dev)->steer[port - 1]; -	pqp = get_promisc_qp(dev, 0, steer, qpn); +	pqp = get_promisc_qp(dev, port, steer, qpn);  	if (!pqp)  		return 0; /* nothing to do */ @@ -302,7 +302,7 @@ static bool check_duplicate_entry(struct mlx4_dev *dev, u8 port,  	s_steer = &mlx4_priv(dev)->steer[port - 1];  	/* if qp is not promisc, it cannot be duplicated */ -	if (!get_promisc_qp(dev, 0, steer, qpn)) +	if (!get_promisc_qp(dev, port, steer, qpn))  		return false;  	/* The qp is promisc qp so it is a duplicate on this index @@ -352,7 +352,7 @@ static bool can_remove_steering_entry(struct mlx4_dev *dev, u8 port,  	members_count = be32_to_cpu(mgm->members_count) & 0xffffff;  	for (i = 0;  i < members_count; i++) {  		qpn = be32_to_cpu(mgm->qp[i]) & MGM_QPN_MASK; -		if (!get_promisc_qp(dev, 0, steer, qpn) && qpn != tqpn) { +		if (!get_promisc_qp(dev, port, steer, qpn) && qpn != tqpn) {  			/* the qp is not promisc, the entry can't be removed */  			goto out;  		} @@ -398,7 +398,7 @@ static int add_promisc_qp(struct mlx4_dev *dev, u8 port,  	mutex_lock(&priv->mcg_table.mutex); -	if (get_promisc_qp(dev, 0, steer, qpn)) { +	if (get_promisc_qp(dev, port, steer, qpn)) {  		err = 0;  /* Noting to do, already exists */  		goto out_mutex;  	} @@ -503,7 +503,7 @@ static int remove_promisc_qp(struct mlx4_dev *dev, u8 port,  	s_steer = &mlx4_priv(dev)->steer[port - 1];  	mutex_lock(&priv->mcg_table.mutex); -	pqp = get_promisc_qp(dev, 0, steer, qpn); +	pqp = get_promisc_qp(dev, port, steer, qpn);  	if (unlikely(!pqp)) {  		mlx4_warn(dev, "QP %x is not promiscuous QP\n", qpn);  		/* nothing to do */ @@ -650,13 +650,6 @@ static int find_entry(struct mlx4_dev *dev, u8 port,  	return err;  } -struct mlx4_net_trans_rule_hw_ctrl { -	__be32 ctrl; -	__be32 vf_vep_port; -	__be32 qpn; -	__be32 reserved; -}; -  static void trans_rule_ctrl_to_hw(struct mlx4_net_trans_rule *ctrl,  				  struct mlx4_net_trans_rule_hw_ctrl *hw)  { @@ -680,87 +673,18 @@ static void trans_rule_ctrl_to_hw(struct mlx4_net_trans_rule *ctrl,  	hw->qpn = cpu_to_be32(ctrl->qpn);  } -struct mlx4_net_trans_rule_hw_ib { -	u8	size; -	u8	rsvd1; -	__be16	id; -	u32	rsvd2; -	__be32	qpn; -	__be32	qpn_mask; -	u8	dst_gid[16]; -	u8	dst_gid_msk[16]; -} __packed; - -struct mlx4_net_trans_rule_hw_eth { -	u8	size; -	u8	rsvd; -	__be16	id; -	u8	rsvd1[6]; -	u8	dst_mac[6]; -	u16	rsvd2; -	u8	dst_mac_msk[6]; -	u16	rsvd3; -	u8	src_mac[6]; -	u16	rsvd4; -	u8	src_mac_msk[6]; -	u8      rsvd5; -	u8      ether_type_enable; -	__be16  ether_type; -	__be16  vlan_id_msk; -	__be16  vlan_id; -} __packed; - -struct mlx4_net_trans_rule_hw_tcp_udp { -	u8	size; -	u8	rsvd; -	__be16	id; -	__be16	rsvd1[3]; -	__be16	dst_port; -	__be16	rsvd2; -	__be16	dst_port_msk; -	__be16	rsvd3; -	__be16	src_port; -	__be16	rsvd4; -	__be16	src_port_msk; -} __packed; - -struct mlx4_net_trans_rule_hw_ipv4 { -	u8	size; -	u8	rsvd; -	__be16	id; -	__be32	rsvd1; -	__be32	dst_ip; -	__be32	dst_ip_msk; -	__be32	src_ip; -	__be32	src_ip_msk; -} __packed; - -struct _rule_hw { -	union { -		struct { -			u8 size; -			u8 rsvd; -			__be16 id; -		}; -		struct mlx4_net_trans_rule_hw_eth eth; -		struct mlx4_net_trans_rule_hw_ib ib; -		struct mlx4_net_trans_rule_hw_ipv4 ipv4; -		struct mlx4_net_trans_rule_hw_tcp_udp tcp_udp; -	}; +const u16 __sw_id_hw[] = { +	[MLX4_NET_TRANS_RULE_ID_ETH]     = 0xE001, +	[MLX4_NET_TRANS_RULE_ID_IB]      = 0xE005, +	[MLX4_NET_TRANS_RULE_ID_IPV6]    = 0xE003, +	[MLX4_NET_TRANS_RULE_ID_IPV4]    = 0xE002, +	[MLX4_NET_TRANS_RULE_ID_TCP]     = 0xE004, +	[MLX4_NET_TRANS_RULE_ID_UDP]     = 0xE006  };  static int parse_trans_rule(struct mlx4_dev *dev, struct mlx4_spec_list *spec,  			    struct _rule_hw *rule_hw)  { -	static const u16 __sw_id_hw[] = { -		[MLX4_NET_TRANS_RULE_ID_ETH]     = 0xE001, -		[MLX4_NET_TRANS_RULE_ID_IB]      = 0xE005, -		[MLX4_NET_TRANS_RULE_ID_IPV6]    = 0xE003, -		[MLX4_NET_TRANS_RULE_ID_IPV4]    = 0xE002, -		[MLX4_NET_TRANS_RULE_ID_TCP]     = 0xE004, -		[MLX4_NET_TRANS_RULE_ID_UDP]     = 0xE006 -	}; -  	static const size_t __rule_hw_sz[] = {  		[MLX4_NET_TRANS_RULE_ID_ETH] =  			sizeof(struct mlx4_net_trans_rule_hw_eth), diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h index 4d9df8f2a12..dba69d98734 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h @@ -690,6 +690,82 @@ struct mlx4_steer {  	struct list_head steer_entries[MLX4_NUM_STEERS];  }; +struct mlx4_net_trans_rule_hw_ctrl { +	__be32 ctrl; +	__be32 vf_vep_port; +	__be32 qpn; +	__be32 reserved; +}; + +struct mlx4_net_trans_rule_hw_ib { +	u8 size; +	u8 rsvd1; +	__be16 id; +	u32 rsvd2; +	__be32 qpn; +	__be32 qpn_mask; +	u8 dst_gid[16]; +	u8 dst_gid_msk[16]; +} __packed; + +struct mlx4_net_trans_rule_hw_eth { +	u8	size; +	u8	rsvd; +	__be16	id; +	u8	rsvd1[6]; +	u8	dst_mac[6]; +	u16	rsvd2; +	u8	dst_mac_msk[6]; +	u16	rsvd3; +	u8	src_mac[6]; +	u16	rsvd4; +	u8	src_mac_msk[6]; +	u8      rsvd5; +	u8      ether_type_enable; +	__be16  ether_type; +	__be16  vlan_id_msk; +	__be16  vlan_id; +} __packed; + +struct mlx4_net_trans_rule_hw_tcp_udp { +	u8	size; +	u8	rsvd; +	__be16	id; +	__be16	rsvd1[3]; +	__be16	dst_port; +	__be16	rsvd2; +	__be16	dst_port_msk; +	__be16	rsvd3; +	__be16	src_port; +	__be16	rsvd4; +	__be16	src_port_msk; +} __packed; + +struct mlx4_net_trans_rule_hw_ipv4 { +	u8	size; +	u8	rsvd; +	__be16	id; +	__be32	rsvd1; +	__be32	dst_ip; +	__be32	dst_ip_msk; +	__be32	src_ip; +	__be32	src_ip_msk; +} __packed; + +struct _rule_hw { +	union { +		struct { +			u8 size; +			u8 rsvd; +			__be16 id; +		}; +		struct mlx4_net_trans_rule_hw_eth eth; +		struct mlx4_net_trans_rule_hw_ib ib; +		struct mlx4_net_trans_rule_hw_ipv4 ipv4; +		struct mlx4_net_trans_rule_hw_tcp_udp tcp_udp; +	}; +}; +  struct mlx4_priv {  	struct mlx4_dev		dev; diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c index 94ceddd17ab..293c9e820c4 100644 --- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c +++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c @@ -42,6 +42,7 @@  #include <linux/mlx4/cmd.h>  #include <linux/mlx4/qp.h>  #include <linux/if_ether.h> +#include <linux/etherdevice.h>  #include "mlx4.h"  #include "fw.h" @@ -2776,18 +2777,133 @@ ex_put:  	return err;  } +/* + * MAC validation for Flow Steering rules. + * VF can attach rules only with a mac address which is assigned to it. + */ +static int validate_eth_header_mac(int slave, struct _rule_hw *eth_header, +				   struct list_head *rlist) +{ +	struct mac_res *res, *tmp; +	__be64 be_mac; + +	/* make sure it isn't multicast or broadcast mac*/ +	if (!is_multicast_ether_addr(eth_header->eth.dst_mac) && +	    !is_broadcast_ether_addr(eth_header->eth.dst_mac)) { +		list_for_each_entry_safe(res, tmp, rlist, list) { +			be_mac = cpu_to_be64(res->mac << 16); +			if (!memcmp(&be_mac, eth_header->eth.dst_mac, ETH_ALEN)) +				return 0; +		} +		pr_err("MAC %pM doesn't belong to VF %d, Steering rule rejected\n", +		       eth_header->eth.dst_mac, slave); +		return -EINVAL; +	} +	return 0; +} + +/* + * In case of missing eth header, append eth header with a MAC address + * assigned to the VF. + */ +static int add_eth_header(struct mlx4_dev *dev, int slave, +			  struct mlx4_cmd_mailbox *inbox, +			  struct list_head *rlist, int header_id) +{ +	struct mac_res *res, *tmp; +	u8 port; +	struct mlx4_net_trans_rule_hw_ctrl *ctrl; +	struct mlx4_net_trans_rule_hw_eth *eth_header; +	struct mlx4_net_trans_rule_hw_ipv4 *ip_header; +	struct mlx4_net_trans_rule_hw_tcp_udp *l4_header; +	__be64 be_mac = 0; +	__be64 mac_msk = cpu_to_be64(MLX4_MAC_MASK << 16); + +	ctrl = (struct mlx4_net_trans_rule_hw_ctrl *)inbox->buf; +	port = be32_to_cpu(ctrl->vf_vep_port) & 0xff; +	eth_header = (struct mlx4_net_trans_rule_hw_eth *)(ctrl + 1); + +	/* Clear a space in the inbox for eth header */ +	switch (header_id) { +	case MLX4_NET_TRANS_RULE_ID_IPV4: +		ip_header = +			(struct mlx4_net_trans_rule_hw_ipv4 *)(eth_header + 1); +		memmove(ip_header, eth_header, +			sizeof(*ip_header) + sizeof(*l4_header)); +		break; +	case MLX4_NET_TRANS_RULE_ID_TCP: +	case MLX4_NET_TRANS_RULE_ID_UDP: +		l4_header = (struct mlx4_net_trans_rule_hw_tcp_udp *) +			    (eth_header + 1); +		memmove(l4_header, eth_header, sizeof(*l4_header)); +		break; +	default: +		return -EINVAL; +	} +	list_for_each_entry_safe(res, tmp, rlist, list) { +		if (port == res->port) { +			be_mac = cpu_to_be64(res->mac << 16); +			break; +		} +	} +	if (!be_mac) { +		pr_err("Failed adding eth header to FS rule, Can't find matching MAC for port %d .\n", +		       port); +		return -EINVAL; +	} + +	memset(eth_header, 0, sizeof(*eth_header)); +	eth_header->size = sizeof(*eth_header) >> 2; +	eth_header->id = cpu_to_be16(__sw_id_hw[MLX4_NET_TRANS_RULE_ID_ETH]); +	memcpy(eth_header->dst_mac, &be_mac, ETH_ALEN); +	memcpy(eth_header->dst_mac_msk, &mac_msk, ETH_ALEN); + +	return 0; + +} +  int mlx4_QP_FLOW_STEERING_ATTACH_wrapper(struct mlx4_dev *dev, int slave,  					 struct mlx4_vhcr *vhcr,  					 struct mlx4_cmd_mailbox *inbox,  					 struct mlx4_cmd_mailbox *outbox,  					 struct mlx4_cmd_info *cmd)  { + +	struct mlx4_priv *priv = mlx4_priv(dev); +	struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker; +	struct list_head *rlist = &tracker->slave_list[slave].res_list[RES_MAC];  	int err; +	struct mlx4_net_trans_rule_hw_ctrl *ctrl; +	struct _rule_hw  *rule_header; +	int header_id;  	if (dev->caps.steering_mode !=  	    MLX4_STEERING_MODE_DEVICE_MANAGED)  		return -EOPNOTSUPP; +	ctrl = (struct mlx4_net_trans_rule_hw_ctrl *)inbox->buf; +	rule_header = (struct _rule_hw *)(ctrl + 1); +	header_id = map_hw_to_sw_id(be16_to_cpu(rule_header->id)); + +	switch (header_id) { +	case MLX4_NET_TRANS_RULE_ID_ETH: +		if (validate_eth_header_mac(slave, rule_header, rlist)) +			return -EINVAL; +		break; +	case MLX4_NET_TRANS_RULE_ID_IPV4: +	case MLX4_NET_TRANS_RULE_ID_TCP: +	case MLX4_NET_TRANS_RULE_ID_UDP: +		pr_warn("Can't attach FS rule without L2 headers, adding L2 header.\n"); +		if (add_eth_header(dev, slave, inbox, rlist, header_id)) +			return -EINVAL; +		vhcr->in_modifier += +			sizeof(struct mlx4_net_trans_rule_hw_eth) >> 2; +		break; +	default: +		pr_err("Corrupted mailbox.\n"); +		return -EINVAL; +	} +  	err = mlx4_cmd_imm(dev, inbox->dma, &vhcr->out_param,  			   vhcr->in_modifier, 0,  			   MLX4_QP_FLOW_STEERING_ATTACH, MLX4_CMD_TIME_CLASS_A, diff --git a/drivers/net/ethernet/seeq/sgiseeq.c b/drivers/net/ethernet/seeq/sgiseeq.c index bb8c8222122..4d15bf413bd 100644 --- a/drivers/net/ethernet/seeq/sgiseeq.c +++ b/drivers/net/ethernet/seeq/sgiseeq.c @@ -751,6 +751,7 @@ static int __devinit sgiseeq_probe(struct platform_device *pdev)  	sp->srings = sr;  	sp->rx_desc = sp->srings->rxvector;  	sp->tx_desc = sp->srings->txvector; +	spin_lock_init(&sp->tx_lock);  	/* A couple calculations now, saves many cycles later. */  	setup_rx_ring(dev, sp->rx_desc, SEEQ_RX_BUFFERS); diff --git a/drivers/net/ethernet/sfc/ethtool.c b/drivers/net/ethernet/sfc/ethtool.c index 8cba2df82b1..5faedd855b7 100644 --- a/drivers/net/ethernet/sfc/ethtool.c +++ b/drivers/net/ethernet/sfc/ethtool.c @@ -863,8 +863,8 @@ static int efx_ethtool_get_class_rule(struct efx_nic *efx,  				       &ip_entry->ip4dst, &ip_entry->pdst);  	if (rc != 0) {  		rc = efx_filter_get_ipv4_full( -			&spec, &proto, &ip_entry->ip4src, &ip_entry->psrc, -			&ip_entry->ip4dst, &ip_entry->pdst); +			&spec, &proto, &ip_entry->ip4dst, &ip_entry->pdst, +			&ip_entry->ip4src, &ip_entry->psrc);  		EFX_WARN_ON_PARANOID(rc);  		ip_mask->ip4src = ~0;  		ip_mask->psrc = ~0; diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h index e2d083228f3..719be3912aa 100644 --- a/drivers/net/ethernet/stmicro/stmmac/common.h +++ b/drivers/net/ethernet/stmicro/stmmac/common.h @@ -22,6 +22,9 @@    Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>  *******************************************************************************/ +#ifndef __COMMON_H__ +#define __COMMON_H__ +  #include <linux/etherdevice.h>  #include <linux/netdevice.h>  #include <linux/phy.h> @@ -366,3 +369,5 @@ extern void stmmac_set_mac(void __iomem *ioaddr, bool enable);  extern void dwmac_dma_flush_tx_fifo(void __iomem *ioaddr);  extern const struct stmmac_ring_mode_ops ring_mode_ops; + +#endif /* __COMMON_H__ */ diff --git a/drivers/net/ethernet/stmicro/stmmac/descs.h b/drivers/net/ethernet/stmicro/stmmac/descs.h index 9820ec842cc..223adf95fd0 100644 --- a/drivers/net/ethernet/stmicro/stmmac/descs.h +++ b/drivers/net/ethernet/stmicro/stmmac/descs.h @@ -20,6 +20,10 @@    Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>  *******************************************************************************/ + +#ifndef __DESCS_H__ +#define __DESCS_H__ +  struct dma_desc {  	/* Receive descriptor */  	union { @@ -166,3 +170,5 @@ enum tdes_csum_insertion {  					 * is not calculated */  	cic_full = 3,		/* IP header and pseudoheader */  }; + +#endif /* __DESCS_H__ */ diff --git a/drivers/net/ethernet/stmicro/stmmac/descs_com.h b/drivers/net/ethernet/stmicro/stmmac/descs_com.h index dd8d6e19dff..7ee9499a6e3 100644 --- a/drivers/net/ethernet/stmicro/stmmac/descs_com.h +++ b/drivers/net/ethernet/stmicro/stmmac/descs_com.h @@ -27,6 +27,9 @@    Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>  *******************************************************************************/ +#ifndef __DESC_COM_H__ +#define __DESC_COM_H__ +  #if defined(CONFIG_STMMAC_RING)  static inline void ehn_desc_rx_set_on_ring_chain(struct dma_desc *p, int end)  { @@ -124,3 +127,5 @@ static inline void norm_set_tx_desc_len(struct dma_desc *p, int len)  	p->des01.tx.buffer1_size = len;  }  #endif + +#endif /* __DESC_COM_H__ */ diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac100.h b/drivers/net/ethernet/stmicro/stmmac/dwmac100.h index 7c6d857a9cc..2ec6aeae349 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac100.h +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac100.h @@ -22,6 +22,9 @@    Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>  *******************************************************************************/ +#ifndef __DWMAC100_H__ +#define __DWMAC100_H__ +  #include <linux/phy.h>  #include "common.h" @@ -119,3 +122,5 @@ enum ttc_control {  #define DMA_MISSED_FRAME_M_CNTR	0x0000ffff	/* Missed Frame Couinter */  extern const struct stmmac_dma_ops dwmac100_dma_ops; + +#endif /* __DWMAC100_H__ */ diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h b/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h index f90fcb5f957..0e4cacedc1f 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h @@ -19,6 +19,8 @@    Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>  *******************************************************************************/ +#ifndef __DWMAC1000_H__ +#define __DWMAC1000_H__  #include <linux/phy.h>  #include "common.h" @@ -229,6 +231,7 @@ enum rtc_control {  #define GMAC_MMC_RX_CSUM_OFFLOAD   0x208  /* Synopsys Core versions */ -#define	DWMAC_CORE_3_40	34 +#define	DWMAC_CORE_3_40	0x34  extern const struct stmmac_dma_ops dwmac1000_dma_ops; +#endif /* __DWMAC1000_H__ */ diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h b/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h index e678ce39d01..e49c9a0fd6f 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h @@ -22,6 +22,9 @@    Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>  *******************************************************************************/ +#ifndef __DWMAC_DMA_H__ +#define __DWMAC_DMA_H__ +  /* DMA CRS Control and Status Register Mapping */  #define DMA_BUS_MODE		0x00001000	/* Bus Mode */  #define DMA_XMT_POLL_DEMAND	0x00001004	/* Transmit Poll Demand */ @@ -109,3 +112,5 @@ extern void dwmac_dma_start_rx(void __iomem *ioaddr);  extern void dwmac_dma_stop_rx(void __iomem *ioaddr);  extern int dwmac_dma_interrupt(void __iomem *ioaddr,  				struct stmmac_extra_stats *x); + +#endif /* __DWMAC_DMA_H__ */ diff --git a/drivers/net/ethernet/stmicro/stmmac/mmc.h b/drivers/net/ethernet/stmicro/stmmac/mmc.h index a38352024cb..67995ef2525 100644 --- a/drivers/net/ethernet/stmicro/stmmac/mmc.h +++ b/drivers/net/ethernet/stmicro/stmmac/mmc.h @@ -22,6 +22,9 @@    Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>  *******************************************************************************/ +#ifndef __MMC_H__ +#define __MMC_H__ +  /* MMC control register */  /* When set, all counter are reset */  #define MMC_CNTRL_COUNTER_RESET		0x1 @@ -129,3 +132,5 @@ struct stmmac_counters {  extern void dwmac_mmc_ctrl(void __iomem *ioaddr, unsigned int mode);  extern void dwmac_mmc_intr_all_mask(void __iomem *ioaddr);  extern void dwmac_mmc_read(void __iomem *ioaddr, struct stmmac_counters *mmc); + +#endif /* __MMC_H__ */ diff --git a/drivers/net/ethernet/stmicro/stmmac/mmc_core.c b/drivers/net/ethernet/stmicro/stmmac/mmc_core.c index c07cfe989f6..0c74a702d46 100644 --- a/drivers/net/ethernet/stmicro/stmmac/mmc_core.c +++ b/drivers/net/ethernet/stmicro/stmmac/mmc_core.c @@ -33,7 +33,7 @@  #define MMC_TX_INTR		0x00000108	/* MMC TX Interrupt */  #define MMC_RX_INTR_MASK	0x0000010c	/* MMC Interrupt Mask */  #define MMC_TX_INTR_MASK	0x00000110	/* MMC Interrupt Mask */ -#define MMC_DEFAUL_MASK		0xffffffff +#define MMC_DEFAULT_MASK		0xffffffff  /* MMC TX counter registers */ @@ -147,8 +147,8 @@ void dwmac_mmc_ctrl(void __iomem *ioaddr, unsigned int mode)  /* To mask all all interrupts.*/  void dwmac_mmc_intr_all_mask(void __iomem *ioaddr)  { -	writel(MMC_DEFAUL_MASK, ioaddr + MMC_RX_INTR_MASK); -	writel(MMC_DEFAUL_MASK, ioaddr + MMC_TX_INTR_MASK); +	writel(MMC_DEFAULT_MASK, ioaddr + MMC_RX_INTR_MASK); +	writel(MMC_DEFAULT_MASK, ioaddr + MMC_TX_INTR_MASK);  }  /* This reads the MAC core counters (if actaully supported). diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h index f2d3665430a..e872e1da313 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h @@ -20,6 +20,9 @@    Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>  *******************************************************************************/ +#ifndef __STMMAC_H__ +#define __STMMAC_H__ +  #define STMMAC_RESOURCE_NAME   "stmmaceth"  #define DRV_MODULE_VERSION	"March_2012" @@ -166,3 +169,5 @@ static inline void stmmac_unregister_pci(void)  {  }  #endif /* CONFIG_STMMAC_PCI */ + +#endif /* __STMMAC_H__ */ diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_timer.h b/drivers/net/ethernet/stmicro/stmmac/stmmac_timer.h index 6863590d184..aea9b14cdfb 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_timer.h +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_timer.h @@ -21,6 +21,8 @@    Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>  *******************************************************************************/ +#ifndef __STMMAC_TIMER_H__ +#define __STMMAC_TIMER_H__  struct stmmac_timer {  	void (*timer_start) (unsigned int new_freq); @@ -40,3 +42,5 @@ void stmmac_schedule(struct net_device *dev);  extern int tmu2_register_user(void *fnt, void *data);  extern void tmu2_unregister_user(void);  #endif + +#endif /* __STMMAC_TIMER_H__ */ diff --git a/drivers/net/ethernet/ti/davinci_mdio.c b/drivers/net/ethernet/ti/davinci_mdio.c index cd7ee204e94..a9ca4a03d31 100644 --- a/drivers/net/ethernet/ti/davinci_mdio.c +++ b/drivers/net/ethernet/ti/davinci_mdio.c @@ -394,8 +394,10 @@ static int __devexit davinci_mdio_remove(struct platform_device *pdev)  	struct device *dev = &pdev->dev;  	struct davinci_mdio_data *data = dev_get_drvdata(dev); -	if (data->bus) +	if (data->bus) { +		mdiobus_unregister(data->bus);  		mdiobus_free(data->bus); +	}  	if (data->clk)  		clk_put(data->clk); diff --git a/drivers/net/fddi/skfp/pmf.c b/drivers/net/fddi/skfp/pmf.c index 24d8566cfd8..441b4dc7945 100644 --- a/drivers/net/fddi/skfp/pmf.c +++ b/drivers/net/fddi/skfp/pmf.c @@ -673,7 +673,7 @@ void smt_add_para(struct s_smc *smc, struct s_pcon *pcon, u_short para,  			sm_pm_get_ls(smc,port_to_mib(smc,port))) ;  		break ;  	case SMT_P_REASON : -		* (u_long *) to = 0 ; +		*(u32 *)to = 0 ;  		sp_len = 4 ;  		goto sp_done ;  	case SMT_P1033 :			/* time stamp */ diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index 328397c6673..b1ba68f1a04 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c @@ -297,7 +297,7 @@ static int qmi_wwan_suspend(struct usb_interface *intf, pm_message_t message)  	if (ret < 0)  		goto err; -	if (info->subdriver && info->subdriver->suspend) +	if (intf == info->control && info->subdriver && info->subdriver->suspend)  		ret = info->subdriver->suspend(intf, message);  	if (ret < 0)  		usbnet_resume(intf); @@ -310,13 +310,14 @@ static int qmi_wwan_resume(struct usb_interface *intf)  	struct usbnet *dev = usb_get_intfdata(intf);  	struct qmi_wwan_state *info = (void *)&dev->data;  	int ret = 0; +	bool callsub = (intf == info->control && info->subdriver && info->subdriver->resume); -	if (info->subdriver && info->subdriver->resume) +	if (callsub)  		ret = info->subdriver->resume(intf);  	if (ret < 0)  		goto err;  	ret = usbnet_resume(intf); -	if (ret < 0 && info->subdriver && info->subdriver->resume && info->subdriver->suspend) +	if (ret < 0 && callsub && info->subdriver->suspend)  		info->subdriver->suspend(intf, PMSG_SUSPEND);  err:  	return ret; @@ -398,7 +399,6 @@ static const struct usb_device_id products[] = {  	/* 4. Gobi 1000 devices */  	{QMI_GOBI1K_DEVICE(0x05c6, 0x9212)},	/* Acer Gobi Modem Device */  	{QMI_GOBI1K_DEVICE(0x03f0, 0x1f1d)},	/* HP un2400 Gobi Modem Device */ -	{QMI_GOBI1K_DEVICE(0x03f0, 0x371d)},	/* HP un2430 Mobile Broadband Module */  	{QMI_GOBI1K_DEVICE(0x04da, 0x250d)},	/* Panasonic Gobi Modem device */  	{QMI_GOBI1K_DEVICE(0x413c, 0x8172)},	/* Dell Gobi Modem device */  	{QMI_GOBI1K_DEVICE(0x1410, 0xa001)},	/* Novatel Gobi Modem device */ @@ -413,7 +413,9 @@ static const struct usb_device_id products[] = {  	/* 5. Gobi 2000 and 3000 devices */  	{QMI_GOBI_DEVICE(0x413c, 0x8186)},	/* Dell Gobi 2000 Modem device (N0218, VU936) */ +	{QMI_GOBI_DEVICE(0x413c, 0x8194)},	/* Dell Gobi 3000 Composite */  	{QMI_GOBI_DEVICE(0x05c6, 0x920b)},	/* Generic Gobi 2000 Modem device */ +	{QMI_GOBI_DEVICE(0x05c6, 0x920d)},	/* Gobi 3000 Composite */  	{QMI_GOBI_DEVICE(0x05c6, 0x9225)},	/* Sony Gobi 2000 Modem device (N0279, VU730) */  	{QMI_GOBI_DEVICE(0x05c6, 0x9245)},	/* Samsung Gobi 2000 Modem device (VL176) */  	{QMI_GOBI_DEVICE(0x03f0, 0x251d)},	/* HP Gobi 2000 Modem device (VP412) */ @@ -438,9 +440,12 @@ static const struct usb_device_id products[] = {  	{QMI_GOBI_DEVICE(0x16d8, 0x8002)},	/* CMDTech Gobi 2000 Modem device (VU922) */  	{QMI_GOBI_DEVICE(0x05c6, 0x9205)},	/* Gobi 2000 Modem device */  	{QMI_GOBI_DEVICE(0x1199, 0x9013)},	/* Sierra Wireless Gobi 3000 Modem device (MC8355) */ +	{QMI_GOBI_DEVICE(0x03f0, 0x371d)},	/* HP un2430 Mobile Broadband Module */  	{QMI_GOBI_DEVICE(0x1199, 0x9015)},	/* Sierra Wireless Gobi 3000 Modem device */  	{QMI_GOBI_DEVICE(0x1199, 0x9019)},	/* Sierra Wireless Gobi 3000 Modem device */  	{QMI_GOBI_DEVICE(0x1199, 0x901b)},	/* Sierra Wireless MC7770 */ +	{QMI_GOBI_DEVICE(0x12d1, 0x14f1)},	/* Sony Gobi 3000 Composite */ +	{QMI_GOBI_DEVICE(0x1410, 0xa021)},	/* Foxconn Gobi 3000 Modem device (Novatel E396) */  	{ }					/* END */  }; diff --git a/drivers/net/usb/sierra_net.c b/drivers/net/usb/sierra_net.c index 7be49ea60b6..8e22417fa6c 100644 --- a/drivers/net/usb/sierra_net.c +++ b/drivers/net/usb/sierra_net.c @@ -656,7 +656,7 @@ static int sierra_net_get_fw_attr(struct usbnet *dev, u16 *datap)  		return -EIO;  	} -	*datap = *attrdata; +	*datap = le16_to_cpu(*attrdata);  	kfree(attrdata);  	return result; diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index 8531c1caac2..fc9f578a1e2 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -1201,19 +1201,26 @@ deferred:  }  EXPORT_SYMBOL_GPL(usbnet_start_xmit); -static void rx_alloc_submit(struct usbnet *dev, gfp_t flags) +static int rx_alloc_submit(struct usbnet *dev, gfp_t flags)  {  	struct urb	*urb;  	int		i; +	int		ret = 0;  	/* don't refill the queue all at once */  	for (i = 0; i < 10 && dev->rxq.qlen < RX_QLEN(dev); i++) {  		urb = usb_alloc_urb(0, flags);  		if (urb != NULL) { -			if (rx_submit(dev, urb, flags) == -ENOLINK) -				return; +			ret = rx_submit(dev, urb, flags); +			if (ret) +				goto err; +		} else { +			ret = -ENOMEM; +			goto err;  		}  	} +err: +	return ret;  }  /*-------------------------------------------------------------------------*/ @@ -1257,7 +1264,8 @@ static void usbnet_bh (unsigned long param)  		int	temp = dev->rxq.qlen;  		if (temp < RX_QLEN(dev)) { -			rx_alloc_submit(dev, GFP_ATOMIC); +			if (rx_alloc_submit(dev, GFP_ATOMIC) == -ENOLINK) +				return;  			if (temp != dev->rxq.qlen)  				netif_dbg(dev, link, dev->net,  					  "rxqlen %d --> %d\n", @@ -1573,7 +1581,7 @@ int usbnet_resume (struct usb_interface *intf)  				netif_device_present(dev->net) &&  				!timer_pending(&dev->delay) &&  				!test_bit(EVENT_RX_HALT, &dev->flags)) -					rx_alloc_submit(dev, GFP_KERNEL); +					rx_alloc_submit(dev, GFP_NOIO);  			if (!(dev->txq.qlen >= TX_QLEN(dev)))  				netif_tx_wake_all_queues(dev->net); diff --git a/drivers/net/wan/ixp4xx_hss.c b/drivers/net/wan/ixp4xx_hss.c index aaaca9aa229..3f575afd8cf 100644 --- a/drivers/net/wan/ixp4xx_hss.c +++ b/drivers/net/wan/ixp4xx_hss.c @@ -10,6 +10,7 @@  #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +#include <linux/module.h>  #include <linux/bitops.h>  #include <linux/cdev.h>  #include <linux/dma-mapping.h> diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c index 4026c906cc7..b7e0258887e 100644 --- a/drivers/net/wireless/ath/ath5k/eeprom.c +++ b/drivers/net/wireless/ath/ath5k/eeprom.c @@ -1482,7 +1482,7 @@ ath5k_eeprom_read_target_rate_pwr_info(struct ath5k_hw *ah, unsigned int mode)  	case AR5K_EEPROM_MODE_11A:  		offset += AR5K_EEPROM_TARGET_PWR_OFF_11A(ee->ee_version);  		rate_pcal_info = ee->ee_rate_tpwr_a; -		ee->ee_rate_target_pwr_num[mode] = AR5K_EEPROM_N_5GHZ_CHAN; +		ee->ee_rate_target_pwr_num[mode] = AR5K_EEPROM_N_5GHZ_RATE_CHAN;  		break;  	case AR5K_EEPROM_MODE_11B:  		offset += AR5K_EEPROM_TARGET_PWR_OFF_11B(ee->ee_version); diff --git a/drivers/net/wireless/ath/ath5k/eeprom.h b/drivers/net/wireless/ath/ath5k/eeprom.h index dc2bcfeadeb..94a9bbea687 100644 --- a/drivers/net/wireless/ath/ath5k/eeprom.h +++ b/drivers/net/wireless/ath/ath5k/eeprom.h @@ -182,6 +182,7 @@  #define AR5K_EEPROM_EEP_DELTA		10  #define AR5K_EEPROM_N_MODES		3  #define AR5K_EEPROM_N_5GHZ_CHAN		10 +#define AR5K_EEPROM_N_5GHZ_RATE_CHAN	8  #define AR5K_EEPROM_N_2GHZ_CHAN		3  #define AR5K_EEPROM_N_2GHZ_CHAN_2413	4  #define	AR5K_EEPROM_N_2GHZ_CHAN_MAX	4 diff --git a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c index 2c9f7d7ed4c..0ed3846f9cb 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c @@ -142,6 +142,7 @@ static int ar9003_paprd_setup_single_table(struct ath_hw *ah)  	};  	int training_power;  	int i, val; +	u32 am2pm_mask = ah->paprd_ratemask;  	if (IS_CHAN_2GHZ(ah->curchan))  		training_power = ar9003_get_training_power_2g(ah); @@ -158,10 +159,13 @@ static int ar9003_paprd_setup_single_table(struct ath_hw *ah)  	}  	ah->paprd_training_power = training_power; +	if (AR_SREV_9330(ah)) +		am2pm_mask = 0; +  	REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2AM, AR_PHY_PAPRD_AM2AM_MASK,  		      ah->paprd_ratemask);  	REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2PM, AR_PHY_PAPRD_AM2PM_MASK, -		      ah->paprd_ratemask); +		      am2pm_mask);  	REG_RMW_FIELD(ah, AR_PHY_PAPRD_HT40, AR_PHY_PAPRD_HT40_MASK,  		      ah->paprd_ratemask_ht40); @@ -782,6 +786,102 @@ int ar9003_paprd_setup_gain_table(struct ath_hw *ah, int chain)  }  EXPORT_SYMBOL(ar9003_paprd_setup_gain_table); +static bool ar9003_paprd_retrain_pa_in(struct ath_hw *ah, +				       struct ath9k_hw_cal_data *caldata, +				       int chain) +{ +	u32 *pa_in = caldata->pa_table[chain]; +	int capdiv_offset, quick_drop_offset; +	int capdiv2g, quick_drop; +	int count = 0; +	int i; + +	if (!AR_SREV_9485(ah) && !AR_SREV_9330(ah)) +		return false; + +	capdiv2g = REG_READ_FIELD(ah, AR_PHY_65NM_CH0_TXRF3, +				  AR_PHY_65NM_CH0_TXRF3_CAPDIV2G); + +	quick_drop = REG_READ_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3, +				    AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP); + +	if (quick_drop) +		quick_drop -= 0x40; + +	for (i = 0; i < NUM_BIN + 1; i++) { +		if (pa_in[i] == 1400) +			count++; +	} + +	if (AR_SREV_9485(ah)) { +		if (pa_in[23] < 800) { +			capdiv_offset = (int)((1000 - pa_in[23] + 75) / 150); +			capdiv2g += capdiv_offset; +			if (capdiv2g > 7) { +				capdiv2g = 7; +				if (pa_in[23] < 600) { +					quick_drop++; +					if (quick_drop > 0) +						quick_drop = 0; +				} +			} +		} else if (pa_in[23] == 1400) { +			quick_drop_offset = min_t(int, count / 3, 2); +			quick_drop += quick_drop_offset; +			capdiv2g += quick_drop_offset / 2; + +			if (capdiv2g > 7) +				capdiv2g = 7; + +			if (quick_drop > 0) { +				quick_drop = 0; +				capdiv2g -= quick_drop_offset; +				if (capdiv2g < 0) +					capdiv2g = 0; +			} +		} else { +			return false; +		} +	} else if (AR_SREV_9330(ah)) { +		if (pa_in[23] < 1000) { +			capdiv_offset = (1000 - pa_in[23]) / 100; +			capdiv2g += capdiv_offset; +			if (capdiv_offset > 3) { +				capdiv_offset = 1; +				quick_drop--; +			} + +			capdiv2g += capdiv_offset; +			if (capdiv2g > 6) +				capdiv2g = 6; +			if (quick_drop < -4) +				quick_drop = -4; +		} else if (pa_in[23] == 1400) { +			if (count > 3) { +				quick_drop++; +				capdiv2g -= count / 4; +				if (quick_drop > -2) +					quick_drop = -2; +			} else { +				capdiv2g--; +			} + +			if (capdiv2g < 0) +				capdiv2g = 0; +		} else { +			return false; +		} +	} + +	REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_TXRF3, +		      AR_PHY_65NM_CH0_TXRF3_CAPDIV2G, capdiv2g); +	REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3, +		      AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP, +		      quick_drop); + +	return true; +} +  int ar9003_paprd_create_curve(struct ath_hw *ah,  			      struct ath9k_hw_cal_data *caldata, int chain)  { @@ -817,6 +917,9 @@ int ar9003_paprd_create_curve(struct ath_hw *ah,  	if (!create_pa_curve(data_L, data_U, pa_table, small_signal_gain))  		status = -2; +	if (ar9003_paprd_retrain_pa_in(ah, caldata, chain)) +		status = -EINPROGRESS; +  	REG_CLR_BIT(ah, AR_PHY_PAPRD_TRAINER_STAT1,  		    AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE); diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h index 7bfbaf065a4..84d3d495686 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h @@ -625,6 +625,10 @@  #define AR_PHY_AIC_CTRL_4_B0	(AR_SM_BASE + 0x4c0)  #define AR_PHY_AIC_STAT_2_B0	(AR_SM_BASE + 0x4cc) +#define AR_PHY_65NM_CH0_TXRF3       0x16048 +#define AR_PHY_65NM_CH0_TXRF3_CAPDIV2G		0x0000001e +#define AR_PHY_65NM_CH0_TXRF3_CAPDIV2G_S	1 +  #define AR_PHY_65NM_CH0_SYNTH4      0x1608c  #define AR_PHY_SYNTH4_LONG_SHIFT_SELECT   (AR_SREV_9462(ah) ? 0x00000001 : 0x00000002)  #define AR_PHY_SYNTH4_LONG_SHIFT_SELECT_S (AR_SREV_9462(ah) ? 0 : 1) diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c index bacdb8fb4ef..9f83f71742a 100644 --- a/drivers/net/wireless/ath/ath9k/gpio.c +++ b/drivers/net/wireless/ath/ath9k/gpio.c @@ -341,7 +341,8 @@ void ath9k_btcoex_stop_gen_timer(struct ath_softc *sc)  {  	struct ath_btcoex *btcoex = &sc->btcoex; -	ath9k_gen_timer_stop(sc->sc_ah, btcoex->no_stomp_timer); +	if (btcoex->hw_timer_enabled) +		ath9k_gen_timer_stop(sc->sc_ah, btcoex->no_stomp_timer);  }  u16 ath9k_btcoex_aggr_limit(struct ath_softc *sc, u32 max_4ms_framelen) diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 60b6a9daff7..48af40151d2 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -463,9 +463,6 @@ static void ath9k_hw_init_config(struct ath_hw *ah)  		ah->config.spurchans[i][1] = AR_NO_SPUR;  	} -	/* PAPRD needs some more work to be enabled */ -	ah->config.paprd_disable = 1; -  	ah->config.rx_intr_mitigation = true;  	ah->config.pcieSerDesWrite = true; @@ -978,9 +975,6 @@ static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah,  	else  		imr_reg |= AR_IMR_TXOK; -	if (opmode == NL80211_IFTYPE_AP) -		imr_reg |= AR_IMR_MIB; -  	ENABLE_REGWRITE_BUFFER(ah);  	REG_WRITE(ah, AR_IMR, imr_reg); @@ -1778,6 +1772,8 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,  		/* Operating channel changed, reset channel calibration data */  		memset(caldata, 0, sizeof(*caldata));  		ath9k_init_nfcal_hist_buffer(ah, chan); +	} else if (caldata) { +		caldata->paprd_packet_sent = false;  	}  	ah->noise = ath9k_hw_getchan_noise(ah, chan); @@ -2502,7 +2498,8 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)  		pCap->tx_desc_len = sizeof(struct ar9003_txc);  		pCap->txs_len = sizeof(struct ar9003_txs);  		if (!ah->config.paprd_disable && -		    ah->eep_ops->get_eeprom(ah, EEP_PAPRD)) +		    ah->eep_ops->get_eeprom(ah, EEP_PAPRD) && +		    !AR_SREV_9462(ah))  			pCap->hw_caps |= ATH9K_HW_CAP_PAPRD;  	} else {  		pCap->tx_desc_len = sizeof(struct ath_desc); diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index ce7332c64ef..6599a75f01f 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -405,6 +405,7 @@ struct ath9k_hw_cal_data {  	int8_t iCoff;  	int8_t qCoff;  	bool rtt_done; +	bool paprd_packet_sent;  	bool paprd_done;  	bool nfcal_pending;  	bool nfcal_interference; diff --git a/drivers/net/wireless/ath/ath9k/link.c b/drivers/net/wireless/ath/ath9k/link.c index d4549e9aac5..825a29cc931 100644 --- a/drivers/net/wireless/ath/ath9k/link.c +++ b/drivers/net/wireless/ath/ath9k/link.c @@ -254,8 +254,9 @@ void ath_paprd_calibrate(struct work_struct *work)  	int chain_ok = 0;  	int chain;  	int len = 1800; +	int ret; -	if (!caldata) +	if (!caldata || !caldata->paprd_packet_sent || caldata->paprd_done)  		return;  	ath9k_ps_wakeup(sc); @@ -282,13 +283,6 @@ void ath_paprd_calibrate(struct work_struct *work)  			continue;  		chain_ok = 0; - -		ath_dbg(common, CALIBRATE, -			"Sending PAPRD frame for thermal measurement on chain %d\n", -			chain); -		if (!ath_paprd_send_frame(sc, skb, chain)) -			goto fail_paprd; -  		ar9003_paprd_setup_gain_table(ah, chain);  		ath_dbg(common, CALIBRATE, @@ -302,7 +296,13 @@ void ath_paprd_calibrate(struct work_struct *work)  			break;  		} -		if (ar9003_paprd_create_curve(ah, caldata, chain)) { +		ret = ar9003_paprd_create_curve(ah, caldata, chain); +		if (ret == -EINPROGRESS) { +			ath_dbg(common, CALIBRATE, +				"PAPRD curve on chain %d needs to be re-trained\n", +				chain); +			break; +		} else if (ret) {  			ath_dbg(common, CALIBRATE,  				"PAPRD create curve failed on chain %d\n",  				chain); diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 2c9da6b2ecb..0d4155aec48 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -2018,6 +2018,9 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,  	ath_dbg(common, XMIT, "TX complete: skb: %p\n", skb); +	if (sc->sc_ah->caldata) +		sc->sc_ah->caldata->paprd_packet_sent = true; +  	if (!(tx_flags & ATH_TX_ERROR))  		/* Frame was ACKed */  		tx_info->flags |= IEEE80211_TX_STAT_ACK; diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c index a299d42da8e..58f89fa9c9f 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c @@ -519,7 +519,7 @@ static void brcmf_usb_tx_complete(struct urb *urb)  	else  		devinfo->bus_pub.bus->dstats.tx_errors++; -	dev_kfree_skb(req->skb); +	brcmu_pkt_buf_free_skb(req->skb);  	req->skb = NULL;  	brcmf_usb_enq(devinfo, &devinfo->tx_freeq, req); @@ -540,7 +540,7 @@ static void brcmf_usb_rx_complete(struct urb *urb)  		devinfo->bus_pub.bus->dstats.rx_packets++;  	} else {  		devinfo->bus_pub.bus->dstats.rx_errors++; -		dev_kfree_skb(skb); +		brcmu_pkt_buf_free_skb(skb);  		brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req);  		return;  	} @@ -550,13 +550,15 @@ static void brcmf_usb_rx_complete(struct urb *urb)  		if (brcmf_proto_hdrpull(devinfo->dev, &ifidx, skb) != 0) {  			brcmf_dbg(ERROR, "rx protocol error\n");  			brcmu_pkt_buf_free_skb(skb); +			brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req);  			devinfo->bus_pub.bus->dstats.rx_errors++;  		} else {  			brcmf_rx_packet(devinfo->dev, ifidx, skb);  			brcmf_usb_rx_refill(devinfo, req);  		}  	} else { -		dev_kfree_skb(skb); +		brcmu_pkt_buf_free_skb(skb); +		brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req);  	}  	return; @@ -581,14 +583,13 @@ static void brcmf_usb_rx_refill(struct brcmf_usbdev_info *devinfo,  	usb_fill_bulk_urb(req->urb, devinfo->usbdev, devinfo->rx_pipe,  			  skb->data, skb_tailroom(skb), brcmf_usb_rx_complete,  			  req); -	req->urb->transfer_flags |= URB_ZERO_PACKET;  	req->devinfo = devinfo; +	brcmf_usb_enq(devinfo, &devinfo->rx_postq, req);  	ret = usb_submit_urb(req->urb, GFP_ATOMIC); -	if (ret == 0) { -		brcmf_usb_enq(devinfo, &devinfo->rx_postq, req); -	} else { -		dev_kfree_skb(req->skb); +	if (ret) { +		brcmf_usb_del_fromq(devinfo, req); +		brcmu_pkt_buf_free_skb(req->skb);  		req->skb = NULL;  		brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req);  	} @@ -683,23 +684,22 @@ static int brcmf_usb_tx(struct device *dev, struct sk_buff *skb)  	req = brcmf_usb_deq(devinfo, &devinfo->tx_freeq);  	if (!req) { +		brcmu_pkt_buf_free_skb(skb);  		brcmf_dbg(ERROR, "no req to send\n");  		return -ENOMEM;  	} -	if (!req->urb) { -		brcmf_dbg(ERROR, "no urb for req %p\n", req); -		return -ENOBUFS; -	}  	req->skb = skb;  	req->devinfo = devinfo;  	usb_fill_bulk_urb(req->urb, devinfo->usbdev, devinfo->tx_pipe,  			  skb->data, skb->len, brcmf_usb_tx_complete, req);  	req->urb->transfer_flags |= URB_ZERO_PACKET; +	brcmf_usb_enq(devinfo, &devinfo->tx_postq, req);  	ret = usb_submit_urb(req->urb, GFP_ATOMIC); -	if (!ret) { -		brcmf_usb_enq(devinfo, &devinfo->tx_postq, req); -	} else { +	if (ret) { +		brcmf_dbg(ERROR, "brcmf_usb_tx usb_submit_urb FAILED\n"); +		brcmf_usb_del_fromq(devinfo, req); +		brcmu_pkt_buf_free_skb(req->skb);  		req->skb = NULL;  		brcmf_usb_enq(devinfo, &devinfo->tx_freeq, req);  	} diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c index 28c5fbb4af2..c36e9231244 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c @@ -1876,16 +1876,17 @@ brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,  	}  	if (test_bit(WL_STATUS_CONNECTED, &cfg_priv->status)) { -		scb_val.val = cpu_to_le32(0); +		memset(&scb_val, 0, sizeof(scb_val));  		err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_RSSI, &scb_val,  				      sizeof(struct brcmf_scb_val_le)); -		if (err) +		if (err) {  			WL_ERR("Could not get rssi (%d)\n", err); - -		rssi = le32_to_cpu(scb_val.val); -		sinfo->filled |= STATION_INFO_SIGNAL; -		sinfo->signal = rssi; -		WL_CONN("RSSI %d dBm\n", rssi); +		} else { +			rssi = le32_to_cpu(scb_val.val); +			sinfo->filled |= STATION_INFO_SIGNAL; +			sinfo->signal = rssi; +			WL_CONN("RSSI %d dBm\n", rssi); +		}  	}  done: diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c index 192ad5c1fcc..a5edebeb0b4 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c @@ -1233,6 +1233,9 @@ uint brcms_reset(struct brcms_info *wl)  	/* dpc will not be rescheduled */  	wl->resched = false; +	/* inform publicly that interface is down */ +	wl->pub->up = false; +  	return 0;  } diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c index 95aa8e1683e..83324b32165 100644 --- a/drivers/net/wireless/ipw2x00/ipw2100.c +++ b/drivers/net/wireless/ipw2x00/ipw2100.c @@ -2042,7 +2042,8 @@ static void isr_indicate_associated(struct ipw2100_priv *priv, u32 status)  		return;  	}  	len = ETH_ALEN; -	ipw2100_get_ordinal(priv, IPW_ORD_STAT_ASSN_AP_BSSID, &bssid, &len); +	ret = ipw2100_get_ordinal(priv, IPW_ORD_STAT_ASSN_AP_BSSID, bssid, +				  &len);  	if (ret) {  		IPW_DEBUG_INFO("failed querying ordinals at line %d\n",  			       __LINE__); diff --git a/drivers/net/wireless/iwlwifi/dvm/debugfs.c b/drivers/net/wireless/iwlwifi/dvm/debugfs.c index 46782f1102a..a47b306b522 100644 --- a/drivers/net/wireless/iwlwifi/dvm/debugfs.c +++ b/drivers/net/wireless/iwlwifi/dvm/debugfs.c @@ -124,6 +124,9 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file,  	const struct fw_img *img;  	size_t bufsz; +	if (!iwl_is_ready_rf(priv)) +		return -EAGAIN; +  	/* default is to dump the entire data segment */  	if (!priv->dbgfs_sram_offset && !priv->dbgfs_sram_len) {  		priv->dbgfs_sram_offset = 0x800000; diff --git a/drivers/net/wireless/iwlwifi/pcie/internal.h b/drivers/net/wireless/iwlwifi/pcie/internal.h index d9694c58208..4ffc18dc3a5 100644 --- a/drivers/net/wireless/iwlwifi/pcie/internal.h +++ b/drivers/net/wireless/iwlwifi/pcie/internal.h @@ -350,7 +350,7 @@ int iwl_queue_space(const struct iwl_queue *q);  /*****************************************************  * Error handling  ******************************************************/ -int iwl_dump_fh(struct iwl_trans *trans, char **buf, bool display); +int iwl_dump_fh(struct iwl_trans *trans, char **buf);  void iwl_dump_csr(struct iwl_trans *trans);  /***************************************************** diff --git a/drivers/net/wireless/iwlwifi/pcie/rx.c b/drivers/net/wireless/iwlwifi/pcie/rx.c index 39a6ca1f009..d1a61ba6247 100644 --- a/drivers/net/wireless/iwlwifi/pcie/rx.c +++ b/drivers/net/wireless/iwlwifi/pcie/rx.c @@ -555,7 +555,7 @@ static void iwl_irq_handle_error(struct iwl_trans *trans)  	}  	iwl_dump_csr(trans); -	iwl_dump_fh(trans, NULL, false); +	iwl_dump_fh(trans, NULL);  	iwl_op_mode_nic_error(trans->op_mode);  } diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c index 939c2f78df5..1e86ea2266d 100644 --- a/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c @@ -1649,13 +1649,9 @@ static const char *get_fh_string(int cmd)  #undef IWL_CMD  } -int iwl_dump_fh(struct iwl_trans *trans, char **buf, bool display) +int iwl_dump_fh(struct iwl_trans *trans, char **buf)  {  	int i; -#ifdef CONFIG_IWLWIFI_DEBUG -	int pos = 0; -	size_t bufsz = 0; -#endif  	static const u32 fh_tbl[] = {  		FH_RSCSR_CHNL0_STTS_WPTR_REG,  		FH_RSCSR_CHNL0_RBDCB_BASE_REG, @@ -1667,29 +1663,35 @@ int iwl_dump_fh(struct iwl_trans *trans, char **buf, bool display)  		FH_TSSR_TX_STATUS_REG,  		FH_TSSR_TX_ERROR_REG  	}; -#ifdef CONFIG_IWLWIFI_DEBUG -	if (display) { -		bufsz = ARRAY_SIZE(fh_tbl) * 48 + 40; + +#ifdef CONFIG_IWLWIFI_DEBUGFS +	if (buf) { +		int pos = 0; +		size_t bufsz = ARRAY_SIZE(fh_tbl) * 48 + 40; +  		*buf = kmalloc(bufsz, GFP_KERNEL);  		if (!*buf)  			return -ENOMEM; +  		pos += scnprintf(*buf + pos, bufsz - pos,  				"FH register values:\n"); -		for (i = 0; i < ARRAY_SIZE(fh_tbl); i++) { + +		for (i = 0; i < ARRAY_SIZE(fh_tbl); i++)  			pos += scnprintf(*buf + pos, bufsz - pos,  				"  %34s: 0X%08x\n",  				get_fh_string(fh_tbl[i]),  				iwl_read_direct32(trans, fh_tbl[i])); -		} +  		return pos;  	}  #endif +  	IWL_ERR(trans, "FH register values:\n"); -	for (i = 0; i <  ARRAY_SIZE(fh_tbl); i++) { +	for (i = 0; i <  ARRAY_SIZE(fh_tbl); i++)  		IWL_ERR(trans, "  %34s: 0X%08x\n",  			get_fh_string(fh_tbl[i]),  			iwl_read_direct32(trans, fh_tbl[i])); -	} +  	return 0;  } @@ -1982,11 +1984,11 @@ static ssize_t iwl_dbgfs_fh_reg_read(struct file *file,  				     size_t count, loff_t *ppos)  {  	struct iwl_trans *trans = file->private_data; -	char *buf; +	char *buf = NULL;  	int pos = 0;  	ssize_t ret = -EFAULT; -	ret = pos = iwl_dump_fh(trans, &buf, true); +	ret = pos = iwl_dump_fh(trans, &buf);  	if (buf) {  		ret = simple_read_from_buffer(user_buf,  					      count, ppos, buf, pos); diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c index e970897f6ab..4cb234349fb 100644 --- a/drivers/net/wireless/libertas/if_sdio.c +++ b/drivers/net/wireless/libertas/if_sdio.c @@ -1326,6 +1326,11 @@ static int if_sdio_suspend(struct device *dev)  	mmc_pm_flag_t flags = sdio_get_host_pm_caps(func); +	/* If we're powered off anyway, just let the mmc layer remove the +	 * card. */ +	if (!lbs_iface_active(card->priv)) +		return -ENOSYS; +  	dev_info(dev, "%s: suspend: PM flags = 0x%x\n",  		 sdio_func_id(func), flags); diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c index c68adec3cc8..565527aee0e 100644 --- a/drivers/net/wireless/mwifiex/cmdevt.c +++ b/drivers/net/wireless/mwifiex/cmdevt.c @@ -170,7 +170,20 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv,  	cmd_code = le16_to_cpu(host_cmd->command);  	cmd_size = le16_to_cpu(host_cmd->size); -	skb_trim(cmd_node->cmd_skb, cmd_size); +	/* Adjust skb length */ +	if (cmd_node->cmd_skb->len > cmd_size) +		/* +		 * cmd_size is less than sizeof(struct host_cmd_ds_command). +		 * Trim off the unused portion. +		 */ +		skb_trim(cmd_node->cmd_skb, cmd_size); +	else if (cmd_node->cmd_skb->len < cmd_size) +		/* +		 * cmd_size is larger than sizeof(struct host_cmd_ds_command) +		 * because we have appended custom IE TLV. Increase skb length +		 * accordingly. +		 */ +		skb_put(cmd_node->cmd_skb, cmd_size - cmd_node->cmd_skb->len);  	do_gettimeofday(&tstamp);  	dev_dbg(adapter->dev, "cmd: DNLD_CMD: (%lu.%lu): %#x, act %#x, len %d," diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index 8b9dbd76a25..64328af496f 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c @@ -1611,6 +1611,7 @@ static int rt2400pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)  static int rt2400pci_probe_hw(struct rt2x00_dev *rt2x00dev)  {  	int retval; +	u32 reg;  	/*  	 * Allocate eeprom data. @@ -1624,6 +1625,14 @@ static int rt2400pci_probe_hw(struct rt2x00_dev *rt2x00dev)  		return retval;  	/* +	 * Enable rfkill polling by setting GPIO direction of the +	 * rfkill switch GPIO pin correctly. +	 */ +	rt2x00pci_register_read(rt2x00dev, GPIOCSR, ®); +	rt2x00_set_field32(®, GPIOCSR_BIT8, 1); +	rt2x00pci_register_write(rt2x00dev, GPIOCSR, reg); + +	/*  	 * Initialize hw specifications.  	 */  	retval = rt2400pci_probe_hw_mode(rt2x00dev); diff --git a/drivers/net/wireless/rt2x00/rt2400pci.h b/drivers/net/wireless/rt2x00/rt2400pci.h index d3a4a68cc43..7564ae992b7 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.h +++ b/drivers/net/wireless/rt2x00/rt2400pci.h @@ -670,6 +670,7 @@  #define GPIOCSR_BIT5			FIELD32(0x00000020)  #define GPIOCSR_BIT6			FIELD32(0x00000040)  #define GPIOCSR_BIT7			FIELD32(0x00000080) +#define GPIOCSR_BIT8			FIELD32(0x00000100)  /*   * BBPPCSR: BBP Pin control register. diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index d2cf8a4bc8b..3de0406735f 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c @@ -1929,6 +1929,7 @@ static int rt2500pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)  static int rt2500pci_probe_hw(struct rt2x00_dev *rt2x00dev)  {  	int retval; +	u32 reg;  	/*  	 * Allocate eeprom data. @@ -1942,6 +1943,14 @@ static int rt2500pci_probe_hw(struct rt2x00_dev *rt2x00dev)  		return retval;  	/* +	 * Enable rfkill polling by setting GPIO direction of the +	 * rfkill switch GPIO pin correctly. +	 */ +	rt2x00pci_register_read(rt2x00dev, GPIOCSR, ®); +	rt2x00_set_field32(®, GPIOCSR_DIR0, 1); +	rt2x00pci_register_write(rt2x00dev, GPIOCSR, reg); + +	/*  	 * Initialize hw specifications.  	 */  	retval = rt2500pci_probe_hw_mode(rt2x00dev); diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 3aae36bb0a9..89fee311d8f 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c @@ -283,7 +283,7 @@ static int rt2500usb_rfkill_poll(struct rt2x00_dev *rt2x00dev)  	u16 reg;  	rt2500usb_register_read(rt2x00dev, MAC_CSR19, ®); -	return rt2x00_get_field32(reg, MAC_CSR19_BIT7); +	return rt2x00_get_field16(reg, MAC_CSR19_BIT7);  }  #ifdef CONFIG_RT2X00_LIB_LEDS @@ -1768,6 +1768,7 @@ static int rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)  static int rt2500usb_probe_hw(struct rt2x00_dev *rt2x00dev)  {  	int retval; +	u16 reg;  	/*  	 * Allocate eeprom data. @@ -1781,6 +1782,14 @@ static int rt2500usb_probe_hw(struct rt2x00_dev *rt2x00dev)  		return retval;  	/* +	 * Enable rfkill polling by setting GPIO direction of the +	 * rfkill switch GPIO pin correctly. +	 */ +	rt2500usb_register_read(rt2x00dev, MAC_CSR19, ®); +	rt2x00_set_field16(®, MAC_CSR19_BIT8, 0); +	rt2500usb_register_write(rt2x00dev, MAC_CSR19, reg); + +	/*  	 * Initialize hw specifications.  	 */  	retval = rt2500usb_probe_hw_mode(rt2x00dev); diff --git a/drivers/net/wireless/rt2x00/rt2500usb.h b/drivers/net/wireless/rt2x00/rt2500usb.h index b493306a7ee..196bd5103e4 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.h +++ b/drivers/net/wireless/rt2x00/rt2500usb.h @@ -189,14 +189,15 @@   * MAC_CSR19: GPIO control register.   */  #define MAC_CSR19			0x0426 -#define MAC_CSR19_BIT0			FIELD32(0x0001) -#define MAC_CSR19_BIT1			FIELD32(0x0002) -#define MAC_CSR19_BIT2			FIELD32(0x0004) -#define MAC_CSR19_BIT3			FIELD32(0x0008) -#define MAC_CSR19_BIT4			FIELD32(0x0010) -#define MAC_CSR19_BIT5			FIELD32(0x0020) -#define MAC_CSR19_BIT6			FIELD32(0x0040) -#define MAC_CSR19_BIT7			FIELD32(0x0080) +#define MAC_CSR19_BIT0			FIELD16(0x0001) +#define MAC_CSR19_BIT1			FIELD16(0x0002) +#define MAC_CSR19_BIT2			FIELD16(0x0004) +#define MAC_CSR19_BIT3			FIELD16(0x0008) +#define MAC_CSR19_BIT4			FIELD16(0x0010) +#define MAC_CSR19_BIT5			FIELD16(0x0020) +#define MAC_CSR19_BIT6			FIELD16(0x0040) +#define MAC_CSR19_BIT7			FIELD16(0x0080) +#define MAC_CSR19_BIT8			FIELD16(0x0100)  /*   * MAC_CSR20: LED control register. diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index cb8c2aca54e..b93516d832f 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -4089,6 +4089,7 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)  		rt2800_register_write(rt2x00dev, LDO_CFG0, reg);  		msleep(1);  		rt2800_register_read(rt2x00dev, LDO_CFG0, ®); +		rt2x00_set_field32(®, LDO_CFG0_LDO_CORE_VLEVEL, 0);  		rt2x00_set_field32(®, LDO_CFG0_BGSEL, 1);  		rt2800_register_write(rt2x00dev, LDO_CFG0, reg);  	} diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index 98aa426a356..4765bbd654c 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c @@ -983,6 +983,7 @@ static int rt2800pci_validate_eeprom(struct rt2x00_dev *rt2x00dev)  static int rt2800pci_probe_hw(struct rt2x00_dev *rt2x00dev)  {  	int retval; +	u32 reg;  	/*  	 * Allocate eeprom data. @@ -996,6 +997,14 @@ static int rt2800pci_probe_hw(struct rt2x00_dev *rt2x00dev)  		return retval;  	/* +	 * Enable rfkill polling by setting GPIO direction of the +	 * rfkill switch GPIO pin correctly. +	 */ +	rt2x00pci_register_read(rt2x00dev, GPIO_CTRL_CFG, ®); +	rt2x00_set_field32(®, GPIO_CTRL_CFG_GPIOD_BIT2, 1); +	rt2x00pci_register_write(rt2x00dev, GPIO_CTRL_CFG, reg); + +	/*  	 * Initialize hw specifications.  	 */  	retval = rt2800_probe_hw_mode(rt2x00dev); diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 6cf336595e2..6b4226b7161 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -667,8 +667,16 @@ static void rt2800usb_fill_rxdone(struct queue_entry *entry,  	skb_pull(entry->skb, RXINFO_DESC_SIZE);  	/* -	 * FIXME: we need to check for rx_pkt_len validity +	 * Check for rx_pkt_len validity. Return if invalid, leaving +	 * rxdesc->size zeroed out by the upper level.  	 */ +	if (unlikely(rx_pkt_len == 0 || +			rx_pkt_len > entry->queue->data_size)) { +		ERROR(entry->queue->rt2x00dev, +			"Bad frame size %d, forcing to 0\n", rx_pkt_len); +		return; +	} +  	rxd = (__le32 *)(entry->skb->data + rx_pkt_len);  	/* @@ -736,6 +744,7 @@ static int rt2800usb_validate_eeprom(struct rt2x00_dev *rt2x00dev)  static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev)  {  	int retval; +	u32 reg;  	/*  	 * Allocate eeprom data. @@ -749,6 +758,14 @@ static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev)  		return retval;  	/* +	 * Enable rfkill polling by setting GPIO direction of the +	 * rfkill switch GPIO pin correctly. +	 */ +	rt2x00usb_register_read(rt2x00dev, GPIO_CTRL_CFG, ®); +	rt2x00_set_field32(®, GPIO_CTRL_CFG_GPIOD_BIT2, 1); +	rt2x00usb_register_write(rt2x00dev, GPIO_CTRL_CFG, reg); + +	/*  	 * Initialize hw specifications.  	 */  	retval = rt2800_probe_hw_mode(rt2x00dev); @@ -1157,6 +1174,8 @@ static struct usb_device_id rt2800usb_device_table[] = {  	{ USB_DEVICE(0x1690, 0x0744) },  	{ USB_DEVICE(0x1690, 0x0761) },  	{ USB_DEVICE(0x1690, 0x0764) }, +	/* ASUS */ +	{ USB_DEVICE(0x0b05, 0x179d) },  	/* Cisco */  	{ USB_DEVICE(0x167b, 0x4001) },  	/* EnGenius */ @@ -1222,7 +1241,6 @@ static struct usb_device_id rt2800usb_device_table[] = {  	{ USB_DEVICE(0x0b05, 0x1760) },  	{ USB_DEVICE(0x0b05, 0x1761) },  	{ USB_DEVICE(0x0b05, 0x1790) }, -	{ USB_DEVICE(0x0b05, 0x179d) },  	/* AzureWave */  	{ USB_DEVICE(0x13d3, 0x3262) },  	{ USB_DEVICE(0x13d3, 0x3284) }, diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index a6b88bd4a1a..3f07e36f462 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -629,7 +629,7 @@ void rt2x00lib_rxdone(struct queue_entry *entry, gfp_t gfp)  	 */  	if (unlikely(rxdesc.size == 0 ||  		     rxdesc.size > entry->queue->data_size)) { -		WARNING(rt2x00dev, "Wrong frame size %d max %d.\n", +		ERROR(rt2x00dev, "Wrong frame size %d max %d.\n",  			rxdesc.size, entry->queue->data_size);  		dev_kfree_skb(entry->skb);  		goto renew_skb; diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index 3f7bc5cadf9..b8ec9616392 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c @@ -2832,6 +2832,7 @@ static int rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)  static int rt61pci_probe_hw(struct rt2x00_dev *rt2x00dev)  {  	int retval; +	u32 reg;  	/*  	 * Disable power saving. @@ -2850,6 +2851,14 @@ static int rt61pci_probe_hw(struct rt2x00_dev *rt2x00dev)  		return retval;  	/* +	 * Enable rfkill polling by setting GPIO direction of the +	 * rfkill switch GPIO pin correctly. +	 */ +	rt2x00pci_register_read(rt2x00dev, MAC_CSR13, ®); +	rt2x00_set_field32(®, MAC_CSR13_BIT13, 1); +	rt2x00pci_register_write(rt2x00dev, MAC_CSR13, reg); + +	/*  	 * Initialize hw specifications.  	 */  	retval = rt61pci_probe_hw_mode(rt2x00dev); diff --git a/drivers/net/wireless/rt2x00/rt61pci.h b/drivers/net/wireless/rt2x00/rt61pci.h index e3cd6db76b0..8f3da5a5676 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.h +++ b/drivers/net/wireless/rt2x00/rt61pci.h @@ -372,6 +372,7 @@ struct hw_pairwise_ta_entry {  #define MAC_CSR13_BIT10			FIELD32(0x00000400)  #define MAC_CSR13_BIT11			FIELD32(0x00000800)  #define MAC_CSR13_BIT12			FIELD32(0x00001000) +#define MAC_CSR13_BIT13			FIELD32(0x00002000)  /*   * MAC_CSR14: LED control register. diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index ba6e434b859..248436c13ce 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c @@ -2177,6 +2177,7 @@ static int rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)  static int rt73usb_probe_hw(struct rt2x00_dev *rt2x00dev)  {  	int retval; +	u32 reg;  	/*  	 * Allocate eeprom data. @@ -2190,6 +2191,14 @@ static int rt73usb_probe_hw(struct rt2x00_dev *rt2x00dev)  		return retval;  	/* +	 * Enable rfkill polling by setting GPIO direction of the +	 * rfkill switch GPIO pin correctly. +	 */ +	rt2x00usb_register_read(rt2x00dev, MAC_CSR13, ®); +	rt2x00_set_field32(®, MAC_CSR13_BIT15, 0); +	rt2x00usb_register_write(rt2x00dev, MAC_CSR13, reg); + +	/*  	 * Initialize hw specifications.  	 */  	retval = rt73usb_probe_hw_mode(rt2x00dev); diff --git a/drivers/net/wireless/rt2x00/rt73usb.h b/drivers/net/wireless/rt2x00/rt73usb.h index 9f6b470414d..df1cc116b83 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.h +++ b/drivers/net/wireless/rt2x00/rt73usb.h @@ -282,6 +282,9 @@ struct hw_pairwise_ta_entry {  #define MAC_CSR13_BIT10			FIELD32(0x00000400)  #define MAC_CSR13_BIT11			FIELD32(0x00000800)  #define MAC_CSR13_BIT12			FIELD32(0x00001000) +#define MAC_CSR13_BIT13			FIELD32(0x00002000) +#define MAC_CSR13_BIT14			FIELD32(0x00004000) +#define MAC_CSR13_BIT15			FIELD32(0x00008000)  /*   * MAC_CSR14: LED control register. diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index 30899901aef..650f79a1f2b 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c @@ -57,8 +57,7 @@  static const struct ethtool_ops xennet_ethtool_ops;  struct netfront_cb { -	struct page *page; -	unsigned offset; +	int pull_to;  };  #define NETFRONT_SKB_CB(skb)	((struct netfront_cb *)((skb)->cb)) @@ -867,15 +866,9 @@ static int handle_incoming_queue(struct net_device *dev,  	struct sk_buff *skb;  	while ((skb = __skb_dequeue(rxq)) != NULL) { -		struct page *page = NETFRONT_SKB_CB(skb)->page; -		void *vaddr = page_address(page); -		unsigned offset = NETFRONT_SKB_CB(skb)->offset; - -		memcpy(skb->data, vaddr + offset, -		       skb_headlen(skb)); +		int pull_to = NETFRONT_SKB_CB(skb)->pull_to; -		if (page != skb_frag_page(&skb_shinfo(skb)->frags[0])) -			__free_page(page); +		__pskb_pull_tail(skb, pull_to - skb_headlen(skb));  		/* Ethernet work: Delayed to here as it peeks the header. */  		skb->protocol = eth_type_trans(skb, dev); @@ -913,7 +906,6 @@ static int xennet_poll(struct napi_struct *napi, int budget)  	struct sk_buff_head errq;  	struct sk_buff_head tmpq;  	unsigned long flags; -	unsigned int len;  	int err;  	spin_lock(&np->rx_lock); @@ -955,24 +947,13 @@ err:  			}  		} -		NETFRONT_SKB_CB(skb)->page = -			skb_frag_page(&skb_shinfo(skb)->frags[0]); -		NETFRONT_SKB_CB(skb)->offset = rx->offset; - -		len = rx->status; -		if (len > RX_COPY_THRESHOLD) -			len = RX_COPY_THRESHOLD; -		skb_put(skb, len); +		NETFRONT_SKB_CB(skb)->pull_to = rx->status; +		if (NETFRONT_SKB_CB(skb)->pull_to > RX_COPY_THRESHOLD) +			NETFRONT_SKB_CB(skb)->pull_to = RX_COPY_THRESHOLD; -		if (rx->status > len) { -			skb_shinfo(skb)->frags[0].page_offset = -				rx->offset + len; -			skb_frag_size_set(&skb_shinfo(skb)->frags[0], rx->status - len); -			skb->data_len = rx->status - len; -		} else { -			__skb_fill_page_desc(skb, 0, NULL, 0, 0); -			skb_shinfo(skb)->nr_frags = 0; -		} +		skb_shinfo(skb)->frags[0].page_offset = rx->offset; +		skb_frag_size_set(&skb_shinfo(skb)->frags[0], rx->status); +		skb->data_len = rx->status;  		i = xennet_fill_frags(np, skb, &tmpq); @@ -999,7 +980,7 @@ err:  		 * receive throughout using the standard receive  		 * buffer size was cut by 25%(!!!).  		 */ -		skb->truesize += skb->data_len - (RX_COPY_THRESHOLD - len); +		skb->truesize += skb->data_len - RX_COPY_THRESHOLD;  		skb->len += skb->data_len;  		if (rx->flags & XEN_NETRXF_csum_blank) diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index 5270f1a9932..d6fd6b6d9d4 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c @@ -280,8 +280,12 @@ static long local_pci_probe(void *_ddi)  {  	struct drv_dev_and_id *ddi = _ddi;  	struct device *dev = &ddi->dev->dev; +	struct device *parent = dev->parent;  	int rc; +	/* The parent bridge must be in active state when probing */ +	if (parent) +		pm_runtime_get_sync(parent);  	/* Unbound PCI devices are always set to disabled and suspended.  	 * During probe, the device is set to enabled and active and the  	 * usage count is incremented.  If the driver supports runtime PM, @@ -298,6 +302,8 @@ static long local_pci_probe(void *_ddi)  		pm_runtime_set_suspended(dev);  		pm_runtime_put_noidle(dev);  	} +	if (parent) +		pm_runtime_put(parent);  	return rc;  } diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index 6869009c739..02d107b1528 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c @@ -458,6 +458,40 @@ boot_vga_show(struct device *dev, struct device_attribute *attr, char *buf)  }  struct device_attribute vga_attr = __ATTR_RO(boot_vga); +static void +pci_config_pm_runtime_get(struct pci_dev *pdev) +{ +	struct device *dev = &pdev->dev; +	struct device *parent = dev->parent; + +	if (parent) +		pm_runtime_get_sync(parent); +	pm_runtime_get_noresume(dev); +	/* +	 * pdev->current_state is set to PCI_D3cold during suspending, +	 * so wait until suspending completes +	 */ +	pm_runtime_barrier(dev); +	/* +	 * Only need to resume devices in D3cold, because config +	 * registers are still accessible for devices suspended but +	 * not in D3cold. +	 */ +	if (pdev->current_state == PCI_D3cold) +		pm_runtime_resume(dev); +} + +static void +pci_config_pm_runtime_put(struct pci_dev *pdev) +{ +	struct device *dev = &pdev->dev; +	struct device *parent = dev->parent; + +	pm_runtime_put(dev); +	if (parent) +		pm_runtime_put_sync(parent); +} +  static ssize_t  pci_read_config(struct file *filp, struct kobject *kobj,  		struct bin_attribute *bin_attr, @@ -484,6 +518,8 @@ pci_read_config(struct file *filp, struct kobject *kobj,  		size = count;  	} +	pci_config_pm_runtime_get(dev); +  	if ((off & 1) && size) {  		u8 val;  		pci_user_read_config_byte(dev, off, &val); @@ -529,6 +565,8 @@ pci_read_config(struct file *filp, struct kobject *kobj,  		--size;  	} +	pci_config_pm_runtime_put(dev); +  	return count;  } @@ -549,6 +587,8 @@ pci_write_config(struct file* filp, struct kobject *kobj,  		count = size;  	} +	pci_config_pm_runtime_get(dev); +  	if ((off & 1) && size) {  		pci_user_write_config_byte(dev, off, data[off - init_off]);  		off++; @@ -587,6 +627,8 @@ pci_write_config(struct file* filp, struct kobject *kobj,  		--size;  	} +	pci_config_pm_runtime_put(dev); +  	return count;  } diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index f3ea977a5b1..ab4bf5a4c2f 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -1941,6 +1941,7 @@ void pci_pm_init(struct pci_dev *dev)  	dev->pm_cap = pm;  	dev->d3_delay = PCI_PM_D3_WAIT;  	dev->d3cold_delay = PCI_PM_D3COLD_WAIT; +	dev->d3cold_allowed = true;  	dev->d1_support = false;  	dev->d2_support = false; diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c index 3a7eefcb270..e76b44777db 100644 --- a/drivers/pci/pcie/portdrv_pci.c +++ b/drivers/pci/pcie/portdrv_pci.c @@ -140,9 +140,17 @@ static int pcie_port_runtime_resume(struct device *dev)  {  	return 0;  } + +static int pcie_port_runtime_idle(struct device *dev) +{ +	/* Delay for a short while to prevent too frequent suspend/resume */ +	pm_schedule_suspend(dev, 10); +	return -EBUSY; +}  #else  #define pcie_port_runtime_suspend	NULL  #define pcie_port_runtime_resume	NULL +#define pcie_port_runtime_idle		NULL  #endif  static const struct dev_pm_ops pcie_portdrv_pm_ops = { @@ -155,6 +163,7 @@ static const struct dev_pm_ops pcie_portdrv_pm_ops = {  	.resume_noirq	= pcie_port_resume_noirq,  	.runtime_suspend = pcie_port_runtime_suspend,  	.runtime_resume = pcie_port_runtime_resume, +	.runtime_idle	= pcie_port_runtime_idle,  };  #define PCIE_PORTDRV_PM_OPS	(&pcie_portdrv_pm_ops) @@ -200,6 +209,11 @@ static int __devinit pcie_portdrv_probe(struct pci_dev *dev,  		return status;  	pci_save_state(dev); +	/* +	 * D3cold may not work properly on some PCIe port, so disable +	 * it by default. +	 */ +	dev->d3cold_allowed = false;  	if (!pci_match_id(port_runtime_pm_black_list, dev))  		pm_runtime_put_noidle(&dev->dev); diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 6c143b4497c..9f8a6b79a8e 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -144,15 +144,13 @@ static inline unsigned long decode_bar(struct pci_dev *dev, u32 bar)  	case PCI_BASE_ADDRESS_MEM_TYPE_32:  		break;  	case PCI_BASE_ADDRESS_MEM_TYPE_1M: -		dev_info(&dev->dev, "1M mem BAR treated as 32-bit BAR\n"); +		/* 1M mem BAR treated as 32-bit BAR */  		break;  	case PCI_BASE_ADDRESS_MEM_TYPE_64:  		flags |= IORESOURCE_MEM_64;  		break;  	default: -		dev_warn(&dev->dev, -			 "mem unknown type %x treated as 32-bit BAR\n", -			 mem_type); +		/* mem unknown type treated as 32-bit BAR */  		break;  	}  	return flags; @@ -173,9 +171,11 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,  	u32 l, sz, mask;  	u16 orig_cmd;  	struct pci_bus_region region; +	bool bar_too_big = false, bar_disabled = false;  	mask = type ? PCI_ROM_ADDRESS_MASK : ~0; +	/* No printks while decoding is disabled! */  	if (!dev->mmio_always_on) {  		pci_read_config_word(dev, PCI_COMMAND, &orig_cmd);  		pci_write_config_word(dev, PCI_COMMAND, @@ -240,8 +240,7 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,  			goto fail;  		if ((sizeof(resource_size_t) < 8) && (sz64 > 0x100000000ULL)) { -			dev_err(&dev->dev, "reg %x: can't handle 64-bit BAR\n", -				pos); +			bar_too_big = true;  			goto fail;  		} @@ -252,12 +251,11 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,  			region.start = 0;  			region.end = sz64;  			pcibios_bus_to_resource(dev, res, ®ion); +			bar_disabled = true;  		} else {  			region.start = l64;  			region.end = l64 + sz64;  			pcibios_bus_to_resource(dev, res, ®ion); -			dev_printk(KERN_DEBUG, &dev->dev, "reg %x: %pR\n", -				   pos, res);  		}  	} else {  		sz = pci_size(l, sz, mask); @@ -268,18 +266,23 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,  		region.start = l;  		region.end = l + sz;  		pcibios_bus_to_resource(dev, res, ®ion); - -		dev_printk(KERN_DEBUG, &dev->dev, "reg %x: %pR\n", pos, res);  	} - out: +	goto out; + + +fail: +	res->flags = 0; +out:  	if (!dev->mmio_always_on)  		pci_write_config_word(dev, PCI_COMMAND, orig_cmd); +	if (bar_too_big) +		dev_err(&dev->dev, "reg %x: can't handle 64-bit BAR\n", pos); +	if (res->flags && !bar_disabled) +		dev_printk(KERN_DEBUG, &dev->dev, "reg %x: %pR\n", pos, res); +  	return (res->flags & IORESOURCE_MEM_64) ? 1 : 0; - fail: -	res->flags = 0; -	goto out;  }  static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom) diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c index 3782e1cd369..934d861a323 100644 --- a/drivers/platform/x86/acer-wmi.c +++ b/drivers/platform/x86/acer-wmi.c @@ -2196,10 +2196,8 @@ static int __init acer_wmi_init(void)  		interface->capability &= ~ACER_CAP_BRIGHTNESS;  		pr_info("Brightness must be controlled by acpi video driver\n");  	} else { -#ifdef CONFIG_ACPI_VIDEO  		pr_info("Disabling ACPI video driver\n");  		acpi_video_unregister(); -#endif  	}  	if (wmi_has_guid(WMID_GUID3)) { diff --git a/drivers/platform/x86/apple-gmux.c b/drivers/platform/x86/apple-gmux.c index dfb1a92ce94..db8f63841b4 100644 --- a/drivers/platform/x86/apple-gmux.c +++ b/drivers/platform/x86/apple-gmux.c @@ -101,7 +101,7 @@ static void gmux_pio_write32(struct apple_gmux_data *gmux_data, int port,  	for (i = 0; i < 4; i++) {  		tmpval = (val >> (i * 8)) & 0xff; -		outb(tmpval, port + i); +		outb(tmpval, gmux_data->iostart + port + i);  	}  } @@ -142,8 +142,9 @@ static u8 gmux_index_read8(struct apple_gmux_data *gmux_data, int port)  	u8 val;  	mutex_lock(&gmux_data->index_lock); -	outb((port & 0xff), gmux_data->iostart + GMUX_PORT_READ);  	gmux_index_wait_ready(gmux_data); +	outb((port & 0xff), gmux_data->iostart + GMUX_PORT_READ); +	gmux_index_wait_complete(gmux_data);  	val = inb(gmux_data->iostart + GMUX_PORT_VALUE);  	mutex_unlock(&gmux_data->index_lock); @@ -166,8 +167,9 @@ static u32 gmux_index_read32(struct apple_gmux_data *gmux_data, int port)  	u32 val;  	mutex_lock(&gmux_data->index_lock); -	outb((port & 0xff), gmux_data->iostart + GMUX_PORT_READ);  	gmux_index_wait_ready(gmux_data); +	outb((port & 0xff), gmux_data->iostart + GMUX_PORT_READ); +	gmux_index_wait_complete(gmux_data);  	val = inl(gmux_data->iostart + GMUX_PORT_VALUE);  	mutex_unlock(&gmux_data->index_lock); @@ -461,18 +463,22 @@ static int __devinit gmux_probe(struct pnp_dev *pnp,  	ver_release = gmux_read8(gmux_data, GMUX_PORT_VERSION_RELEASE);  	if (ver_major == 0xff && ver_minor == 0xff && ver_release == 0xff) {  		if (gmux_is_indexed(gmux_data)) { +			u32 version;  			mutex_init(&gmux_data->index_lock);  			gmux_data->indexed = true; +			version = gmux_read32(gmux_data, +				GMUX_PORT_VERSION_MAJOR); +			ver_major = (version >> 24) & 0xff; +			ver_minor = (version >> 16) & 0xff; +			ver_release = (version >> 8) & 0xff;  		} else {  			pr_info("gmux device not present\n");  			ret = -ENODEV;  			goto err_release;  		} -		pr_info("Found indexed gmux\n"); -	} else { -		pr_info("Found gmux version %d.%d.%d\n", ver_major, ver_minor, -			ver_release);  	} +	pr_info("Found gmux version %d.%d.%d [%s]\n", ver_major, ver_minor, +		ver_release, (gmux_data->indexed ? "indexed" : "classic"));  	memset(&props, 0, sizeof(props));  	props.type = BACKLIGHT_PLATFORM; @@ -505,9 +511,7 @@ static int __devinit gmux_probe(struct pnp_dev *pnp,  	 * Disable the other backlight choices.  	 */  	acpi_video_dmi_promote_vendor(); -#if defined (CONFIG_ACPI_VIDEO) || defined (CONFIG_ACPI_VIDEO_MODULE)  	acpi_video_unregister(); -#endif  	apple_bl_unregister();  	gmux_data->power_state = VGA_SWITCHEROO_ON; @@ -593,9 +597,7 @@ static void __devexit gmux_remove(struct pnp_dev *pnp)  	kfree(gmux_data);  	acpi_video_dmi_demote_vendor(); -#if defined (CONFIG_ACPI_VIDEO) || defined (CONFIG_ACPI_VIDEO_MODULE)  	acpi_video_register(); -#endif  	apple_bl_register();  } diff --git a/drivers/platform/x86/asus-laptop.c b/drivers/platform/x86/asus-laptop.c index e38f91be0b1..4b568df5664 100644 --- a/drivers/platform/x86/asus-laptop.c +++ b/drivers/platform/x86/asus-laptop.c @@ -85,7 +85,7 @@ static char *wled_type = "unknown";  static char *bled_type = "unknown";  module_param(wled_type, charp, 0444); -MODULE_PARM_DESC(wlan_status, "Set the wled type on boot " +MODULE_PARM_DESC(wled_type, "Set the wled type on boot "  		 "(unknown, led or rfkill). "  		 "default is unknown"); @@ -863,9 +863,9 @@ static ssize_t show_infos(struct device *dev,  	 * The significance of others is yet to be found.  	 * If we don't find the method, we assume the device are present.  	 */ -	rv = acpi_evaluate_integer(asus->handle, "HRWS", NULL, &temp); +	rv = acpi_evaluate_integer(asus->handle, "HWRS", NULL, &temp);  	if (!ACPI_FAILURE(rv)) -		len += sprintf(page + len, "HRWS value         : %#x\n", +		len += sprintf(page + len, "HWRS value         : %#x\n",  			       (uint) temp);  	/*  	 * Another value for userspace: the ASYM method returns 0x02 for @@ -1751,9 +1751,9 @@ static int asus_laptop_get_info(struct asus_laptop *asus)  	 * The significance of others is yet to be found.  	 */  	status = -	    acpi_evaluate_integer(asus->handle, "HRWS", NULL, &hwrs_result); +	    acpi_evaluate_integer(asus->handle, "HWRS", NULL, &hwrs_result);  	if (!ACPI_FAILURE(status)) -		pr_notice("  HRWS returned %x", (int)hwrs_result); +		pr_notice("  HWRS returned %x", (int)hwrs_result);  	if (!acpi_check_handle(asus->handle, METHOD_WL_STATUS, NULL))  		asus->have_rsts = true; diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c index 2eb9fe8e8ef..c0e9ff489b2 100644 --- a/drivers/platform/x86/asus-wmi.c +++ b/drivers/platform/x86/asus-wmi.c @@ -47,9 +47,7 @@  #include <linux/thermal.h>  #include <acpi/acpi_bus.h>  #include <acpi/acpi_drivers.h> -#ifdef CONFIG_ACPI_VIDEO  #include <acpi/video.h> -#endif  #include "asus-wmi.h" @@ -1704,10 +1702,8 @@ static int asus_wmi_add(struct platform_device *pdev)  	if (asus->driver->quirks->wmi_backlight_power)  		acpi_video_dmi_promote_vendor();  	if (!acpi_video_backlight_support()) { -#ifdef CONFIG_ACPI_VIDEO  		pr_info("Disabling ACPI video driver\n");  		acpi_video_unregister(); -#endif  		err = asus_wmi_backlight_init(asus);  		if (err && err != -ENODEV)  			goto fail_backlight; diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index dab91b48d22..5ca264179f4 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c @@ -610,12 +610,12 @@ static void eeepc_rfkill_hotplug(struct eeepc_laptop *eeepc, acpi_handle handle)  		if (!bus) {  			pr_warn("Unable to find PCI bus 1?\n"); -			goto out_unlock; +			goto out_put_dev;  		}  		if (pci_bus_read_config_dword(bus, 0, PCI_VENDOR_ID, &l)) {  			pr_err("Unable to read PCI config space?\n"); -			goto out_unlock; +			goto out_put_dev;  		}  		absent = (l == 0xffffffff); @@ -627,7 +627,7 @@ static void eeepc_rfkill_hotplug(struct eeepc_laptop *eeepc, acpi_handle handle)  				absent ? "absent" : "present");  			pr_warn("skipped wireless hotplug as probably "  				"inappropriate for this model\n"); -			goto out_unlock; +			goto out_put_dev;  		}  		if (!blocked) { @@ -635,7 +635,7 @@ static void eeepc_rfkill_hotplug(struct eeepc_laptop *eeepc, acpi_handle handle)  			if (dev) {  				/* Device already present */  				pci_dev_put(dev); -				goto out_unlock; +				goto out_put_dev;  			}  			dev = pci_scan_single_device(bus, 0);  			if (dev) { @@ -650,6 +650,8 @@ static void eeepc_rfkill_hotplug(struct eeepc_laptop *eeepc, acpi_handle handle)  				pci_dev_put(dev);  			}  		} +out_put_dev: +		pci_dev_put(port);  	}  out_unlock: diff --git a/drivers/platform/x86/samsung-laptop.c b/drivers/platform/x86/samsung-laptop.c index c1ca7bcebb6..dd90d15f521 100644 --- a/drivers/platform/x86/samsung-laptop.c +++ b/drivers/platform/x86/samsung-laptop.c @@ -26,9 +26,7 @@  #include <linux/seq_file.h>  #include <linux/debugfs.h>  #include <linux/ctype.h> -#ifdef CONFIG_ACPI_VIDEO  #include <acpi/video.h> -#endif  /*   * This driver is needed because a number of Samsung laptops do not hook @@ -1558,9 +1556,7 @@ static int __init samsung_init(void)  		samsung->handle_backlight = false;  	} else if (samsung->quirks->broken_acpi_video) {  		pr_info("Disabling ACPI video driver\n"); -#ifdef CONFIG_ACPI_VIDEO  		acpi_video_unregister(); -#endif  	}  #endif diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index 80e37794931..52daaa816e5 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -545,7 +545,7 @@ TPACPI_HANDLE(hkey, ec, "\\_SB.HKEY",	/* 600e/x, 770e, 770x */   */  static int acpi_evalf(acpi_handle handle, -		      void *res, char *method, char *fmt, ...) +		      int *res, char *method, char *fmt, ...)  {  	char *fmt0 = fmt;  	struct acpi_object_list params; @@ -606,7 +606,7 @@ static int acpi_evalf(acpi_handle handle,  		success = (status == AE_OK &&  			   out_obj.type == ACPI_TYPE_INTEGER);  		if (success && res) -			*(int *)res = out_obj.integer.value; +			*res = out_obj.integer.value;  		break;  	case 'v':		/* void */  		success = status == AE_OK; @@ -7386,17 +7386,18 @@ static int fan_get_status(u8 *status)  	 * Add TPACPI_FAN_RD_ACPI_FANS ? */  	switch (fan_status_access_mode) { -	case TPACPI_FAN_RD_ACPI_GFAN: +	case TPACPI_FAN_RD_ACPI_GFAN: {  		/* 570, 600e/x, 770e, 770x */ +		int res; -		if (unlikely(!acpi_evalf(gfan_handle, &s, NULL, "d"))) +		if (unlikely(!acpi_evalf(gfan_handle, &res, NULL, "d")))  			return -EIO;  		if (likely(status)) -			*status = s & 0x07; +			*status = res & 0x07;  		break; - +	}  	case TPACPI_FAN_RD_TPEC:  		/* all except 570, 600e/x, 770e, 770x */  		if (unlikely(!acpi_ec_read(fan_status_offset, &s))) diff --git a/drivers/pwm/pwm-tiecap.c b/drivers/pwm/pwm-tiecap.c index 0b66d0f2592..4b6688909fe 100644 --- a/drivers/pwm/pwm-tiecap.c +++ b/drivers/pwm/pwm-tiecap.c @@ -100,6 +100,13 @@ static int ecap_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,  		writel(period_cycles, pc->mmio_base + CAP3);  	} +	if (!test_bit(PWMF_ENABLED, &pwm->flags)) { +		reg_val = readw(pc->mmio_base + ECCTL2); +		/* Disable APWM mode to put APWM output Low */ +		reg_val &= ~ECCTL2_APWM_MODE; +		writew(reg_val, pc->mmio_base + ECCTL2); +	} +  	pm_runtime_put_sync(pc->chip.dev);  	return 0;  } diff --git a/drivers/pwm/pwm-tiehrpwm.c b/drivers/pwm/pwm-tiehrpwm.c index c3756d1be19..b1996bcd5b7 100644 --- a/drivers/pwm/pwm-tiehrpwm.c +++ b/drivers/pwm/pwm-tiehrpwm.c @@ -104,6 +104,7 @@ struct ehrpwm_pwm_chip {  	struct pwm_chip	chip;  	unsigned int	clk_rate;  	void __iomem	*mmio_base; +	unsigned long period_cycles[NUM_PWM_CHANNEL];  };  static inline struct ehrpwm_pwm_chip *to_ehrpwm_pwm_chip(struct pwm_chip *chip) @@ -210,6 +211,7 @@ static int ehrpwm_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,  	unsigned long long c;  	unsigned long period_cycles, duty_cycles;  	unsigned short ps_divval, tb_divval; +	int i;  	if (period_ns < 0 || duty_ns < 0 || period_ns > NSEC_PER_SEC)  		return -ERANGE; @@ -229,6 +231,28 @@ static int ehrpwm_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,  		duty_cycles = (unsigned long)c;  	} +	/* +	 * Period values should be same for multiple PWM channels as IP uses +	 * same period register for multiple channels. +	 */ +	for (i = 0; i < NUM_PWM_CHANNEL; i++) { +		if (pc->period_cycles[i] && +				(pc->period_cycles[i] != period_cycles)) { +			/* +			 * Allow channel to reconfigure period if no other +			 * channels being configured. +			 */ +			if (i == pwm->hwpwm) +				continue; + +			dev_err(chip->dev, "Period value conflicts with channel %d\n", +					i); +			return -EINVAL; +		} +	} + +	pc->period_cycles[pwm->hwpwm] = period_cycles; +  	/* Configure clock prescaler to support Low frequency PWM wave */  	if (set_prescale_div(period_cycles/PERIOD_MAX, &ps_divval,  				&tb_divval)) { @@ -320,10 +344,15 @@ static void ehrpwm_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)  static void ehrpwm_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)  { +	struct ehrpwm_pwm_chip *pc = to_ehrpwm_pwm_chip(chip); +  	if (test_bit(PWMF_ENABLED, &pwm->flags)) {  		dev_warn(chip->dev, "Removing PWM device without disabling\n");  		pm_runtime_put_sync(chip->dev);  	} + +	/* set period value to zero on free */ +	pc->period_cycles[pwm->hwpwm] = 0;  }  static const struct pwm_ops ehrpwm_pwm_ops = { diff --git a/drivers/regulator/tps65217-regulator.c b/drivers/regulator/tps65217-regulator.c index 6caa222af77..ab00cab905b 100644 --- a/drivers/regulator/tps65217-regulator.c +++ b/drivers/regulator/tps65217-regulator.c @@ -22,6 +22,7 @@  #include <linux/err.h>  #include <linux/platform_device.h> +#include <linux/regulator/of_regulator.h>  #include <linux/regulator/driver.h>  #include <linux/regulator/machine.h>  #include <linux/mfd/tps65217.h> @@ -281,37 +282,130 @@ static const struct regulator_desc regulators[] = {  			   NULL),  }; +#ifdef CONFIG_OF +static struct of_regulator_match reg_matches[] = { +	{ .name = "dcdc1", .driver_data = (void *)TPS65217_DCDC_1 }, +	{ .name = "dcdc2", .driver_data = (void *)TPS65217_DCDC_2 }, +	{ .name = "dcdc3", .driver_data = (void *)TPS65217_DCDC_3 }, +	{ .name = "ldo1", .driver_data = (void *)TPS65217_LDO_1 }, +	{ .name = "ldo2", .driver_data = (void *)TPS65217_LDO_2 }, +	{ .name = "ldo3", .driver_data = (void *)TPS65217_LDO_3 }, +	{ .name = "ldo4", .driver_data = (void *)TPS65217_LDO_4 }, +}; + +static struct tps65217_board *tps65217_parse_dt(struct platform_device *pdev) +{ +	struct tps65217 *tps = dev_get_drvdata(pdev->dev.parent); +	struct device_node *node = tps->dev->of_node; +	struct tps65217_board *pdata; +	struct device_node *regs; +	int i, count; + +	regs = of_find_node_by_name(node, "regulators"); +	if (!regs) +		return NULL; + +	count = of_regulator_match(pdev->dev.parent, regs, +				reg_matches, TPS65217_NUM_REGULATOR); +	of_node_put(regs); +	if ((count < 0) || (count > TPS65217_NUM_REGULATOR)) +		return NULL; + +	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); +	if (!pdata) +		return NULL; + +	for (i = 0; i < count; i++) { +		if (!reg_matches[i].init_data || !reg_matches[i].of_node) +			continue; + +		pdata->tps65217_init_data[i] = reg_matches[i].init_data; +		pdata->of_node[i] = reg_matches[i].of_node; +	} + +	return pdata; +} +#else +static struct tps65217_board *tps65217_parse_dt(struct platform_device *pdev) +{ +	return NULL; +} +#endif +  static int __devinit tps65217_regulator_probe(struct platform_device *pdev)  { +	struct tps65217 *tps = dev_get_drvdata(pdev->dev.parent); +	struct tps65217_board *pdata = dev_get_platdata(tps->dev); +	struct regulator_init_data *reg_data;  	struct regulator_dev *rdev; -	struct tps65217 *tps; -	struct tps_info *info = &tps65217_pmic_regs[pdev->id];  	struct regulator_config config = { }; +	int i, ret; -	/* Already set by core driver */ -	tps = dev_to_tps65217(pdev->dev.parent); -	tps->info[pdev->id] = info; +	if (tps->dev->of_node) +		pdata = tps65217_parse_dt(pdev); -	config.dev = &pdev->dev; -	config.of_node = pdev->dev.of_node; -	config.init_data = pdev->dev.platform_data; -	config.driver_data = tps; +	if (!pdata) { +		dev_err(&pdev->dev, "Platform data not found\n"); +		return -EINVAL; +	} + +	if (tps65217_chip_id(tps) != TPS65217) { +		dev_err(&pdev->dev, "Invalid tps chip version\n"); +		return -ENODEV; +	} + +	platform_set_drvdata(pdev, tps); + +	for (i = 0; i < TPS65217_NUM_REGULATOR; i++) { + +		reg_data = pdata->tps65217_init_data[i]; -	rdev = regulator_register(®ulators[pdev->id], &config); -	if (IS_ERR(rdev)) -		return PTR_ERR(rdev); +		/* +		 * Regulator API handles empty constraints but not NULL +		 * constraints +		 */ +		if (!reg_data) +			continue; -	platform_set_drvdata(pdev, rdev); +		/* Register the regulators */ +		tps->info[i] = &tps65217_pmic_regs[i]; +		config.dev = tps->dev; +		config.init_data = reg_data; +		config.driver_data = tps; +		config.regmap = tps->regmap; +		if (tps->dev->of_node) +			config.of_node = pdata->of_node[i]; + +		rdev = regulator_register(®ulators[i], &config); +		if (IS_ERR(rdev)) { +			dev_err(tps->dev, "failed to register %s regulator\n", +				pdev->name); +			ret = PTR_ERR(rdev); +			goto err_unregister_regulator; +		} + +		/* Save regulator for cleanup */ +		tps->rdev[i] = rdev; +	}  	return 0; + +err_unregister_regulator: +	while (--i >= 0) +		regulator_unregister(tps->rdev[i]); + +	return ret;  }  static int __devexit tps65217_regulator_remove(struct platform_device *pdev)  { -	struct regulator_dev *rdev = platform_get_drvdata(pdev); +	struct tps65217 *tps = platform_get_drvdata(pdev); +	unsigned int i; + +	for (i = 0; i < TPS65217_NUM_REGULATOR; i++) +		regulator_unregister(tps->rdev[i]);  	platform_set_drvdata(pdev, NULL); -	regulator_unregister(rdev);  	return 0;  } diff --git a/drivers/rtc/rtc-at91sam9.c b/drivers/rtc/rtc-at91sam9.c index 831868904e0..1dd61f402b0 100644 --- a/drivers/rtc/rtc-at91sam9.c +++ b/drivers/rtc/rtc-at91sam9.c @@ -58,6 +58,7 @@ struct sam9_rtc {  	struct rtc_device	*rtcdev;  	u32			imr;  	void __iomem		*gpbr; +	int 			irq;  };  #define rtt_readl(rtc, field) \ @@ -292,7 +293,7 @@ static int __devinit at91_rtc_probe(struct platform_device *pdev)  {  	struct resource	*r, *r_gpbr;  	struct sam9_rtc	*rtc; -	int		ret; +	int		ret, irq;  	u32		mr;  	r = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -302,10 +303,18 @@ static int __devinit at91_rtc_probe(struct platform_device *pdev)  		return -ENODEV;  	} +	irq = platform_get_irq(pdev, 0); +	if (irq < 0) { +		dev_err(&pdev->dev, "failed to get interrupt resource\n"); +		return irq; +	} +  	rtc = kzalloc(sizeof *rtc, GFP_KERNEL);  	if (!rtc)  		return -ENOMEM; +	rtc->irq = irq; +  	/* platform setup code should have handled this; sigh */  	if (!device_can_wakeup(&pdev->dev))  		device_init_wakeup(&pdev->dev, 1); @@ -345,11 +354,10 @@ static int __devinit at91_rtc_probe(struct platform_device *pdev)  	}  	/* register irq handler after we know what name we'll use */ -	ret = request_irq(AT91_ID_SYS, at91_rtc_interrupt, -				IRQF_SHARED, +	ret = request_irq(rtc->irq, at91_rtc_interrupt, IRQF_SHARED,  				dev_name(&rtc->rtcdev->dev), rtc);  	if (ret) { -		dev_dbg(&pdev->dev, "can't share IRQ %d?\n", AT91_ID_SYS); +		dev_dbg(&pdev->dev, "can't share IRQ %d?\n", rtc->irq);  		rtc_device_unregister(rtc->rtcdev);  		goto fail_register;  	} @@ -386,7 +394,7 @@ static int __devexit at91_rtc_remove(struct platform_device *pdev)  	/* disable all interrupts */  	rtt_writel(rtc, MR, mr & ~(AT91_RTT_ALMIEN | AT91_RTT_RTTINCIEN)); -	free_irq(AT91_ID_SYS, rtc); +	free_irq(rtc->irq, rtc);  	rtc_device_unregister(rtc->rtcdev); @@ -423,7 +431,7 @@ static int at91_rtc_suspend(struct platform_device *pdev,  	rtc->imr = mr & (AT91_RTT_ALMIEN | AT91_RTT_RTTINCIEN);  	if (rtc->imr) {  		if (device_may_wakeup(&pdev->dev) && (mr & AT91_RTT_ALMIEN)) { -			enable_irq_wake(AT91_ID_SYS); +			enable_irq_wake(rtc->irq);  			/* don't let RTTINC cause wakeups */  			if (mr & AT91_RTT_RTTINCIEN)  				rtt_writel(rtc, MR, mr & ~AT91_RTT_RTTINCIEN); @@ -441,7 +449,7 @@ static int at91_rtc_resume(struct platform_device *pdev)  	if (rtc->imr) {  		if (device_may_wakeup(&pdev->dev)) -			disable_irq_wake(AT91_ID_SYS); +			disable_irq_wake(rtc->irq);  		mr = rtt_readl(rtc, MR);  		rtt_writel(rtc, MR, mr | rtc->imr);  	} diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c index 40a826a7295..2fb2b9ea97e 100644 --- a/drivers/s390/block/dasd_eckd.c +++ b/drivers/s390/block/dasd_eckd.c @@ -3804,7 +3804,7 @@ dasd_eckd_ioctl(struct dasd_block *block, unsigned int cmd, void __user *argp)  	case BIODASDSYMMIO:  		return dasd_symm_io(device, argp);  	default: -		return -ENOIOCTLCMD; +		return -ENOTTY;  	}  } diff --git a/drivers/s390/block/dasd_ioctl.c b/drivers/s390/block/dasd_ioctl.c index cceae70279f..654c6921a6d 100644 --- a/drivers/s390/block/dasd_ioctl.c +++ b/drivers/s390/block/dasd_ioctl.c @@ -498,12 +498,9 @@ int dasd_ioctl(struct block_device *bdev, fmode_t mode,  		break;  	default:  		/* if the discipline has an ioctl method try it. */ -		if (base->discipline->ioctl) { +		rc = -ENOTTY; +		if (base->discipline->ioctl)  			rc = base->discipline->ioctl(block, cmd, argp); -			if (rc == -ENOIOCTLCMD) -				rc = -EINVAL; -		} else -			rc = -EINVAL;  	}  	dasd_put_device(base);  	return rc; diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index dc27598785e..ed38454228c 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -4066,7 +4066,6 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)  	spin_lock_init(&instance->cmd_pool_lock);  	spin_lock_init(&instance->hba_lock);  	spin_lock_init(&instance->completion_lock); -	spin_lock_init(&poll_aen_lock);  	mutex_init(&instance->aen_mutex);  	mutex_init(&instance->reset_mutex); @@ -5392,6 +5391,8 @@ static int __init megasas_init(void)  	printk(KERN_INFO "megasas: %s %s\n", MEGASAS_VERSION,  	       MEGASAS_EXT_VERSION); +	spin_lock_init(&poll_aen_lock); +  	support_poll_for_event = 2;  	support_device_change = 1; diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.c b/drivers/scsi/mpt2sas/mpt2sas_base.c index 9d46fcbe775..b25757d1e91 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_base.c +++ b/drivers/scsi/mpt2sas/mpt2sas_base.c @@ -2424,10 +2424,13 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc,  int sleep_flag)  	}  	/* command line tunables  for max controller queue depth */ -	if (max_queue_depth != -1) -		max_request_credit = (max_queue_depth < facts->RequestCredit) -		    ? max_queue_depth : facts->RequestCredit; -	else +	if (max_queue_depth != -1 && max_queue_depth != 0) { +		max_request_credit = min_t(u16, max_queue_depth + +			ioc->hi_priority_depth + ioc->internal_depth, +			facts->RequestCredit); +		if (max_request_credit > MAX_HBA_QUEUE_DEPTH) +			max_request_credit =  MAX_HBA_QUEUE_DEPTH; +	} else  		max_request_credit = min_t(u16, facts->RequestCredit,  		    MAX_HBA_QUEUE_DEPTH); @@ -2502,7 +2505,7 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc,  int sleep_flag)  	/* set the scsi host can_queue depth  	 * with some internal commands that could be outstanding  	 */ -	ioc->shost->can_queue = ioc->scsiio_depth - (2); +	ioc->shost->can_queue = ioc->scsiio_depth;  	dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "scsi host: "  	    "can_queue depth (%d)\n", ioc->name, ioc->shost->can_queue)); diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index 4a6381c8725..de2337f255a 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c @@ -42,6 +42,8 @@  #include <trace/events/scsi.h> +static void scsi_eh_done(struct scsi_cmnd *scmd); +  #define SENSE_TIMEOUT		(10*HZ)  /* @@ -241,6 +243,14 @@ static int scsi_check_sense(struct scsi_cmnd *scmd)  	if (! scsi_command_normalize_sense(scmd, &sshdr))  		return FAILED;	/* no valid sense data */ +	if (scmd->cmnd[0] == TEST_UNIT_READY && scmd->scsi_done != scsi_eh_done) +		/* +		 * nasty: for mid-layer issued TURs, we need to return the +		 * actual sense data without any recovery attempt.  For eh +		 * issued ones, we need to try to recover and interpret +		 */ +		return SUCCESS; +  	if (scsi_sense_is_deferred(&sshdr))  		return NEEDS_RETRY; diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index ffd77739ae3..faa790fba13 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -776,7 +776,6 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)  	}  	if (req->cmd_type == REQ_TYPE_BLOCK_PC) { /* SG_IO ioctl from block level */ -		req->errors = result;  		if (result) {  			if (sense_valid && req->sense) {  				/* @@ -792,6 +791,10 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)  			if (!sense_deferred)  				error = __scsi_error_from_host_byte(cmd, result);  		} +		/* +		 * __scsi_error_from_host_byte may have reset the host_byte +		 */ +		req->errors = cmd->result;  		req->resid_len = scsi_get_resid(cmd); diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index 56a93794c47..d947ffc20ce 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -764,6 +764,16 @@ static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result,  	sdev->model = (char *) (sdev->inquiry + 16);  	sdev->rev = (char *) (sdev->inquiry + 32); +	if (strncmp(sdev->vendor, "ATA     ", 8) == 0) { +		/* +		 * sata emulation layer device.  This is a hack to work around +		 * the SATL power management specifications which state that +		 * when the SATL detects the device has gone into standby +		 * mode, it shall respond with NOT READY. +		 */ +		sdev->allow_restart = 1; +	} +  	if (*bflags & BLIST_ISROM) {  		sdev->type = TYPE_ROM;  		sdev->removable = 1; diff --git a/drivers/spi/spi-bcm63xx.c b/drivers/spi/spi-bcm63xx.c index ea0aaa3f13d..a9f4049c676 100644 --- a/drivers/spi/spi-bcm63xx.c +++ b/drivers/spi/spi-bcm63xx.c @@ -47,6 +47,8 @@ struct bcm63xx_spi {  	/* Platform data */  	u32			speed_hz;  	unsigned		fifo_size; +	unsigned int		msg_type_shift; +	unsigned int		msg_ctl_width;  	/* Data buffers */  	const unsigned char	*tx_ptr; @@ -221,13 +223,20 @@ static unsigned int bcm63xx_txrx_bufs(struct spi_device *spi,  	msg_ctl = (t->len << SPI_BYTE_CNT_SHIFT);  	if (t->rx_buf && t->tx_buf) -		msg_ctl |= (SPI_FD_RW << SPI_MSG_TYPE_SHIFT); +		msg_ctl |= (SPI_FD_RW << bs->msg_type_shift);  	else if (t->rx_buf) -		msg_ctl |= (SPI_HD_R << SPI_MSG_TYPE_SHIFT); +		msg_ctl |= (SPI_HD_R << bs->msg_type_shift);  	else if (t->tx_buf) -		msg_ctl |= (SPI_HD_W << SPI_MSG_TYPE_SHIFT); +		msg_ctl |= (SPI_HD_W << bs->msg_type_shift); -	bcm_spi_writew(bs, msg_ctl, SPI_MSG_CTL); +	switch (bs->msg_ctl_width) { +	case 8: +		bcm_spi_writeb(bs, msg_ctl, SPI_MSG_CTL); +		break; +	case 16: +		bcm_spi_writew(bs, msg_ctl, SPI_MSG_CTL); +		break; +	}  	/* Issue the transfer */  	cmd = SPI_CMD_START_IMMEDIATE; @@ -406,9 +415,21 @@ static int __devinit bcm63xx_spi_probe(struct platform_device *pdev)  	master->transfer_one_message = bcm63xx_spi_transfer_one;  	master->mode_bits = MODEBITS;  	bs->speed_hz = pdata->speed_hz; +	bs->msg_type_shift = pdata->msg_type_shift; +	bs->msg_ctl_width = pdata->msg_ctl_width;  	bs->tx_io = (u8 *)(bs->regs + bcm63xx_spireg(SPI_MSG_DATA));  	bs->rx_io = (const u8 *)(bs->regs + bcm63xx_spireg(SPI_RX_DATA)); +	switch (bs->msg_ctl_width) { +	case 8: +	case 16: +		break; +	default: +		dev_err(dev, "unsupported MSG_CTL width: %d\n", +			 bs->msg_ctl_width); +		goto out_clk_disable; +	} +  	/* Initialize hardware */  	clk_enable(bs->clk);  	bcm_spi_writeb(bs, SPI_INTR_CLEAR_ALL, SPI_INT_STATUS); diff --git a/drivers/staging/android/android_alarm.h b/drivers/staging/android/android_alarm.h index d0cafd63719..f2ffd963f1c 100644 --- a/drivers/staging/android/android_alarm.h +++ b/drivers/staging/android/android_alarm.h @@ -51,10 +51,12 @@ enum android_alarm_return_flags {  #define ANDROID_ALARM_WAIT                  _IO('a', 1)  #define ALARM_IOW(c, type, size)            _IOW('a', (c) | ((type) << 4), size) +#define ALARM_IOR(c, type, size)            _IOR('a', (c) | ((type) << 4), size) +  /* Set alarm */  #define ANDROID_ALARM_SET(type)             ALARM_IOW(2, type, struct timespec)  #define ANDROID_ALARM_SET_AND_WAIT(type)    ALARM_IOW(3, type, struct timespec) -#define ANDROID_ALARM_GET_TIME(type)        ALARM_IOW(4, type, struct timespec) +#define ANDROID_ALARM_GET_TIME(type)        ALARM_IOR(4, type, struct timespec)  #define ANDROID_ALARM_SET_RTC               _IOW('a', 5, struct timespec)  #define ANDROID_ALARM_BASE_CMD(cmd)         (cmd & ~(_IOC(0, 0, 0xf0, 0)))  #define ANDROID_ALARM_IOCTL_TO_TYPE(cmd)    (_IOC_NR(cmd) >> 4) diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c index 6c81e377262..cc8931fde83 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.c +++ b/drivers/staging/comedi/drivers/amplc_dio200.c @@ -1412,6 +1412,13 @@ static int __devinit dio200_attach_pci(struct comedi_device *dev,  		dev_err(dev->class_dev, "BUG! cannot determine board type!\n");  		return -EINVAL;  	} +	/* +	 * Need to 'get' the PCI device to match the 'put' in dio200_detach(). +	 * TODO: Remove the pci_dev_get() and matching pci_dev_put() once +	 * support for manual attachment of PCI devices via dio200_attach() +	 * has been removed. +	 */ +	pci_dev_get(pci_dev);  	return dio200_pci_common_attach(dev, pci_dev);  } diff --git a/drivers/staging/comedi/drivers/amplc_pc236.c b/drivers/staging/comedi/drivers/amplc_pc236.c index aabba9886b7..f5028790303 100644 --- a/drivers/staging/comedi/drivers/amplc_pc236.c +++ b/drivers/staging/comedi/drivers/amplc_pc236.c @@ -565,6 +565,13 @@ static int __devinit pc236_attach_pci(struct comedi_device *dev,  		dev_err(dev->class_dev, "BUG! cannot determine board type!\n");  		return -EINVAL;  	} +	/* +	 * Need to 'get' the PCI device to match the 'put' in pc236_detach(). +	 * TODO: Remove the pci_dev_get() and matching pci_dev_put() once +	 * support for manual attachment of PCI devices via pc236_attach() +	 * has been removed. +	 */ +	pci_dev_get(pci_dev);  	return pc236_pci_common_attach(dev, pci_dev);  } diff --git a/drivers/staging/comedi/drivers/amplc_pc263.c b/drivers/staging/comedi/drivers/amplc_pc263.c index 40ec1ffebba..8191c4e28e0 100644 --- a/drivers/staging/comedi/drivers/amplc_pc263.c +++ b/drivers/staging/comedi/drivers/amplc_pc263.c @@ -298,6 +298,13 @@ static int __devinit pc263_attach_pci(struct comedi_device *dev,  		dev_err(dev->class_dev, "BUG! cannot determine board type!\n");  		return -EINVAL;  	} +	/* +	 * Need to 'get' the PCI device to match the 'put' in pc263_detach(). +	 * TODO: Remove the pci_dev_get() and matching pci_dev_put() once +	 * support for manual attachment of PCI devices via pc263_attach() +	 * has been removed. +	 */ +	pci_dev_get(pci_dev);  	return pc263_pci_common_attach(dev, pci_dev);  } diff --git a/drivers/staging/comedi/drivers/amplc_pci224.c b/drivers/staging/comedi/drivers/amplc_pci224.c index 4e17f13e57f..8bf109e7bb0 100644 --- a/drivers/staging/comedi/drivers/amplc_pci224.c +++ b/drivers/staging/comedi/drivers/amplc_pci224.c @@ -1503,6 +1503,13 @@ pci224_attach_pci(struct comedi_device *dev, struct pci_dev *pci_dev)  			DRIVER_NAME ": BUG! cannot determine board type!\n");  		return -EINVAL;  	} +	/* +	 * Need to 'get' the PCI device to match the 'put' in pci224_detach(). +	 * TODO: Remove the pci_dev_get() and matching pci_dev_put() once +	 * support for manual attachment of PCI devices via pci224_attach() +	 * has been removed. +	 */ +	pci_dev_get(pci_dev);  	return pci224_attach_common(dev, pci_dev, NULL);  } diff --git a/drivers/staging/comedi/drivers/amplc_pci230.c b/drivers/staging/comedi/drivers/amplc_pci230.c index 1b67d0c61fa..66e74bd1226 100644 --- a/drivers/staging/comedi/drivers/amplc_pci230.c +++ b/drivers/staging/comedi/drivers/amplc_pci230.c @@ -2925,6 +2925,13 @@ static int __devinit pci230_attach_pci(struct comedi_device *dev,  			"amplc_pci230: BUG! cannot determine board type!\n");  		return -EINVAL;  	} +	/* +	 * Need to 'get' the PCI device to match the 'put' in pci230_detach(). +	 * TODO: Remove the pci_dev_get() and matching pci_dev_put() once +	 * support for manual attachment of PCI devices via pci230_attach() +	 * has been removed. +	 */ +	pci_dev_get(pci_dev);  	return pci230_attach_common(dev, pci_dev);  } diff --git a/drivers/staging/comedi/drivers/das08.c b/drivers/staging/comedi/drivers/das08.c index 874e02e4766..67a914a10b5 100644 --- a/drivers/staging/comedi/drivers/das08.c +++ b/drivers/staging/comedi/drivers/das08.c @@ -378,7 +378,7 @@ das08jr_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,  	int chan;  	lsb = data[0] & 0xff; -	msb = (data[0] >> 8) & 0xf; +	msb = (data[0] >> 8) & 0xff;  	chan = CR_CHAN(insn->chanspec); @@ -623,7 +623,7 @@ static const struct das08_board_struct das08_boards[] = {  		.ai = das08_ai_rinsn,  		.ai_nbits = 16,  		.ai_pg = das08_pg_none, -		.ai_encoding = das08_encode12, +		.ai_encoding = das08_encode16,  		.ao = das08jr_ao_winsn,  		.ao_nbits = 16,  		.di = das08jr_di_rbits, @@ -922,6 +922,13 @@ das08_attach_pci(struct comedi_device *dev, struct pci_dev *pdev)  		dev_err(dev->class_dev, "BUG! cannot determine board type!\n");  		return -EINVAL;  	} +	/* +	 * Need to 'get' the PCI device to match the 'put' in das08_detach(). +	 * TODO: Remove the pci_dev_get() and matching pci_dev_put() once +	 * support for manual attachment of PCI devices via das08_attach() +	 * has been removed. +	 */ +	pci_dev_get(pdev);  	return das08_pci_attach_common(dev, pdev);  } diff --git a/drivers/staging/iio/accel/lis3l02dq_ring.c b/drivers/staging/iio/accel/lis3l02dq_ring.c index 18d108fd967..f3da59063ed 100644 --- a/drivers/staging/iio/accel/lis3l02dq_ring.c +++ b/drivers/staging/iio/accel/lis3l02dq_ring.c @@ -121,8 +121,10 @@ static int lis3l02dq_get_buffer_element(struct iio_dev *indio_dev,  	if (rx_array == NULL)  		return -ENOMEM;  	ret = lis3l02dq_read_all(indio_dev, rx_array); -	if (ret < 0) +	if (ret < 0) { +		kfree(rx_array);  		return ret; +	}  	for (i = 0; i < scan_count; i++)  		data[i] = combine_8_to_16(rx_array[i*4+1],  					rx_array[i*4+3]); diff --git a/drivers/staging/iio/adc/ad7192.c b/drivers/staging/iio/adc/ad7192.c index 095837285f4..19a064d649e 100644 --- a/drivers/staging/iio/adc/ad7192.c +++ b/drivers/staging/iio/adc/ad7192.c @@ -647,6 +647,8 @@ static ssize_t ad7192_write_frequency(struct device *dev,  	ret = strict_strtoul(buf, 10, &lval);  	if (ret)  		return ret; +	if (lval == 0) +		return -EINVAL;  	mutex_lock(&indio_dev->mlock);  	if (iio_buffer_enabled(indio_dev)) { diff --git a/drivers/staging/iio/gyro/adis16260_core.c b/drivers/staging/iio/gyro/adis16260_core.c index 93aa431287a..eb8e9d69efd 100644 --- a/drivers/staging/iio/gyro/adis16260_core.c +++ b/drivers/staging/iio/gyro/adis16260_core.c @@ -195,6 +195,8 @@ static ssize_t adis16260_write_frequency(struct device *dev,  	ret = strict_strtol(buf, 10, &val);  	if (ret)  		return ret; +	if (val == 0) +		return -EINVAL;  	mutex_lock(&indio_dev->mlock);  	if (spi_get_device_id(st->us)) { diff --git a/drivers/staging/iio/imu/adis16400_core.c b/drivers/staging/iio/imu/adis16400_core.c index 1f4c17779b5..a618327e06e 100644 --- a/drivers/staging/iio/imu/adis16400_core.c +++ b/drivers/staging/iio/imu/adis16400_core.c @@ -234,6 +234,8 @@ static ssize_t adis16400_write_frequency(struct device *dev,  	ret = strict_strtol(buf, 10, &val);  	if (ret)  		return ret; +	if (val == 0) +		return -EINVAL;  	mutex_lock(&indio_dev->mlock); diff --git a/drivers/staging/iio/meter/ade7753.c b/drivers/staging/iio/meter/ade7753.c index f04ece7fbc2..3ccff189f25 100644 --- a/drivers/staging/iio/meter/ade7753.c +++ b/drivers/staging/iio/meter/ade7753.c @@ -425,6 +425,8 @@ static ssize_t ade7753_write_frequency(struct device *dev,  	ret = strict_strtol(buf, 10, &val);  	if (ret)  		return ret; +	if (val == 0) +		return -EINVAL;  	mutex_lock(&indio_dev->mlock); diff --git a/drivers/staging/iio/meter/ade7754.c b/drivers/staging/iio/meter/ade7754.c index 6cee28a5e87..abb1e9c8d09 100644 --- a/drivers/staging/iio/meter/ade7754.c +++ b/drivers/staging/iio/meter/ade7754.c @@ -445,6 +445,8 @@ static ssize_t ade7754_write_frequency(struct device *dev,  	ret = strict_strtol(buf, 10, &val);  	if (ret)  		return ret; +	if (val == 0) +		return -EINVAL;  	mutex_lock(&indio_dev->mlock); diff --git a/drivers/staging/iio/meter/ade7759.c b/drivers/staging/iio/meter/ade7759.c index b3f7e0fa961..eb0a2a98f38 100644 --- a/drivers/staging/iio/meter/ade7759.c +++ b/drivers/staging/iio/meter/ade7759.c @@ -385,6 +385,8 @@ static ssize_t ade7759_write_frequency(struct device *dev,  	ret = strict_strtol(buf, 10, &val);  	if (ret)  		return ret; +	if (val == 0) +		return -EINVAL;  	mutex_lock(&indio_dev->mlock); diff --git a/drivers/staging/nvec/nvec.c b/drivers/staging/nvec/nvec.c index 695ea35f75b..d0a7e408efe 100644 --- a/drivers/staging/nvec/nvec.c +++ b/drivers/staging/nvec/nvec.c @@ -837,7 +837,7 @@ static int __devinit tegra_nvec_probe(struct platform_device *pdev)  	}  	ret = mfd_add_devices(nvec->dev, -1, nvec_devices, -			      ARRAY_SIZE(nvec_devices), base, 0); +			      ARRAY_SIZE(nvec_devices), base, 0, NULL);  	if (ret)  		dev_err(nvec->dev, "error adding subdevices\n"); diff --git a/drivers/staging/omapdrm/omap_connector.c b/drivers/staging/omapdrm/omap_connector.c index 5e2856c0e0b..55e9c865585 100644 --- a/drivers/staging/omapdrm/omap_connector.c +++ b/drivers/staging/omapdrm/omap_connector.c @@ -48,13 +48,20 @@ static inline void copy_timings_omap_to_drm(struct drm_display_mode *mode,  	mode->vsync_end = mode->vsync_start + timings->vsw;  	mode->vtotal = mode->vsync_end + timings->vbp; -	/* note: whether or not it is interlaced, +/- h/vsync, etc, -	 * which should be set in the mode flags, is not exposed in -	 * the omap_video_timings struct.. but hdmi driver tracks -	 * those separately so all we have to have to set the mode -	 * is the way to recover these timings values, and the -	 * omap_dss_driver would do the rest. -	 */ +	mode->flags = 0; + +	if (timings->interlace) +		mode->flags |= DRM_MODE_FLAG_INTERLACE; + +	if (timings->hsync_level == OMAPDSS_SIG_ACTIVE_HIGH) +		mode->flags |= DRM_MODE_FLAG_PHSYNC; +	else +		mode->flags |= DRM_MODE_FLAG_NHSYNC; + +	if (timings->vsync_level == OMAPDSS_SIG_ACTIVE_HIGH) +		mode->flags |= DRM_MODE_FLAG_PVSYNC; +	else +		mode->flags |= DRM_MODE_FLAG_NVSYNC;  }  static inline void copy_timings_drm_to_omap(struct omap_video_timings *timings, @@ -71,6 +78,22 @@ static inline void copy_timings_drm_to_omap(struct omap_video_timings *timings,  	timings->vfp = mode->vsync_start - mode->vdisplay;  	timings->vsw = mode->vsync_end - mode->vsync_start;  	timings->vbp = mode->vtotal - mode->vsync_end; + +	timings->interlace = !!(mode->flags & DRM_MODE_FLAG_INTERLACE); + +	if (mode->flags & DRM_MODE_FLAG_PHSYNC) +		timings->hsync_level = OMAPDSS_SIG_ACTIVE_HIGH; +	else +		timings->hsync_level = OMAPDSS_SIG_ACTIVE_LOW; + +	if (mode->flags & DRM_MODE_FLAG_PVSYNC) +		timings->vsync_level = OMAPDSS_SIG_ACTIVE_HIGH; +	else +		timings->vsync_level = OMAPDSS_SIG_ACTIVE_LOW; + +	timings->data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE; +	timings->de_level = OMAPDSS_SIG_ACTIVE_HIGH; +	timings->sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES;  }  static void omap_connector_dpms(struct drm_connector *connector, int mode) @@ -187,7 +210,7 @@ static int omap_connector_get_modes(struct drm_connector *connector)  		}  	} else {  		struct drm_display_mode *mode = drm_mode_create(dev); -		struct omap_video_timings timings; +		struct omap_video_timings timings = {0};  		dssdrv->get_timings(dssdev, &timings); @@ -291,7 +314,7 @@ void omap_connector_mode_set(struct drm_connector *connector,  	struct omap_connector *omap_connector = to_omap_connector(connector);  	struct omap_dss_device *dssdev = omap_connector->dssdev;  	struct omap_dss_driver *dssdrv = dssdev->driver; -	struct omap_video_timings timings; +	struct omap_video_timings timings = {0};  	copy_timings_drm_to_omap(&timings, mode); diff --git a/drivers/staging/ozwpan/ozcdev.c b/drivers/staging/ozwpan/ozcdev.c index d9832194580..758ce0a8d82 100644 --- a/drivers/staging/ozwpan/ozcdev.c +++ b/drivers/staging/ozwpan/ozcdev.c @@ -8,6 +8,7 @@  #include <linux/cdev.h>  #include <linux/uaccess.h>  #include <linux/netdevice.h> +#include <linux/etherdevice.h>  #include <linux/poll.h>  #include <linux/sched.h>  #include "ozconfig.h" @@ -213,7 +214,7 @@ static int oz_set_active_pd(u8 *addr)  		if (old_pd)  			oz_pd_put(old_pd);  	} else { -		if (!memcmp(addr, "\0\0\0\0\0\0", sizeof(addr))) { +		if (is_zero_ether_addr(addr)) {  			spin_lock_bh(&g_cdev.lock);  			pd = g_cdev.active_pd;  			g_cdev.active_pd = 0; diff --git a/drivers/staging/rtl8712/recv_linux.c b/drivers/staging/rtl8712/recv_linux.c index 0e26d5f6cf2..495ee1205e0 100644 --- a/drivers/staging/rtl8712/recv_linux.c +++ b/drivers/staging/rtl8712/recv_linux.c @@ -117,13 +117,8 @@ void r8712_recv_indicatepkt(struct _adapter *padapter,  	if (skb == NULL)  		goto _recv_indicatepkt_drop;  	skb->data = precv_frame->u.hdr.rx_data; -#ifdef NET_SKBUFF_DATA_USES_OFFSET -	skb->tail = (sk_buff_data_t)(precv_frame->u.hdr.rx_tail - -		     precv_frame->u.hdr.rx_head); -#else -	skb->tail = (sk_buff_data_t)precv_frame->u.hdr.rx_tail; -#endif  	skb->len = precv_frame->u.hdr.len; +	skb_set_tail_pointer(skb, skb->len);  	if ((pattrib->tcpchk_valid == 1) && (pattrib->tcp_chkrpt == 1))  		skb->ip_summed = CHECKSUM_UNNECESSARY;  	else diff --git a/drivers/staging/vt6656/dpc.c b/drivers/staging/vt6656/dpc.c index e4bdf2a2b58..3aa895ec650 100644 --- a/drivers/staging/vt6656/dpc.c +++ b/drivers/staging/vt6656/dpc.c @@ -200,7 +200,7 @@ s_vProcessRxMACHeader (      } else if (!compare_ether_addr(pbyRxBuffer, &pDevice->abySNAP_RFC1042[0])) {          cbHeaderSize += 6;          pwType = (PWORD) (pbyRxBufferAddr + cbHeaderSize); -	if ((*pwType == cpu_to_le16(ETH_P_IPX)) || +	if ((*pwType == cpu_to_be16(ETH_P_IPX)) ||  	    (*pwType == cpu_to_le16(0xF380))) {  		cbHeaderSize -= 8;              pwType = (PWORD) (pbyRxBufferAddr + cbHeaderSize); diff --git a/drivers/staging/vt6656/rxtx.c b/drivers/staging/vt6656/rxtx.c index bb464527fc1..b6e04e7b629 100644 --- a/drivers/staging/vt6656/rxtx.c +++ b/drivers/staging/vt6656/rxtx.c @@ -1699,7 +1699,7 @@ s_bPacketToWirelessUsb(      // 802.1H      if (ntohs(psEthHeader->wType) > ETH_DATA_LEN) {  	if (pDevice->dwDiagRefCount == 0) { -		if ((psEthHeader->wType == cpu_to_le16(ETH_P_IPX)) || +		if ((psEthHeader->wType == cpu_to_be16(ETH_P_IPX)) ||  		    (psEthHeader->wType == cpu_to_le16(0xF380))) {  			memcpy((PBYTE) (pbyPayloadHead),  			       abySNAP_Bridgetunnel, 6); @@ -2838,10 +2838,10 @@ int nsDMA_tx_packet(PSDevice pDevice, unsigned int uDMAIdx, struct sk_buff *skb)      Packet_Type = skb->data[ETH_HLEN+1];      Descriptor_type = skb->data[ETH_HLEN+1+1+2];      Key_info = (skb->data[ETH_HLEN+1+1+2+1] << 8)|(skb->data[ETH_HLEN+1+1+2+2]); -    if (pDevice->sTxEthHeader.wType == cpu_to_le16(ETH_P_PAE)) { -	/* 802.1x OR eapol-key challenge frame transfer */ -	if (((Protocol_Version == 1) || (Protocol_Version == 2)) && -		(Packet_Type == 3)) { +	if (pDevice->sTxEthHeader.wType == cpu_to_be16(ETH_P_PAE)) { +		/* 802.1x OR eapol-key challenge frame transfer */ +		if (((Protocol_Version == 1) || (Protocol_Version == 2)) && +			(Packet_Type == 3)) {                          bTxeapol_key = TRUE;                         if(!(Key_info & BIT3) &&  //WPA or RSN group-key challenge  			   (Key_info & BIT8) && (Key_info & BIT9)) {    //send 2/2 key @@ -2987,19 +2987,19 @@ int nsDMA_tx_packet(PSDevice pDevice, unsigned int uDMAIdx, struct sk_buff *skb)          }      } -    if (pDevice->sTxEthHeader.wType == cpu_to_le16(ETH_P_PAE)) { -        if (pDevice->byBBType != BB_TYPE_11A) { -            pDevice->wCurrentRate = RATE_1M; -            pDevice->byACKRate = RATE_1M; -            pDevice->byTopCCKBasicRate = RATE_1M; -            pDevice->byTopOFDMBasicRate = RATE_6M; -        } else { -            pDevice->wCurrentRate = RATE_6M; -            pDevice->byACKRate = RATE_6M; -            pDevice->byTopCCKBasicRate = RATE_1M; -            pDevice->byTopOFDMBasicRate = RATE_6M; -        } -    } +	if (pDevice->sTxEthHeader.wType == cpu_to_be16(ETH_P_PAE)) { +		if (pDevice->byBBType != BB_TYPE_11A) { +			pDevice->wCurrentRate = RATE_1M; +			pDevice->byACKRate = RATE_1M; +			pDevice->byTopCCKBasicRate = RATE_1M; +			pDevice->byTopOFDMBasicRate = RATE_6M; +		} else { +			pDevice->wCurrentRate = RATE_6M; +			pDevice->byACKRate = RATE_6M; +			pDevice->byTopCCKBasicRate = RATE_1M; +			pDevice->byTopOFDMBasicRate = RATE_6M; +		} +	}      DBG_PRT(MSG_LEVEL_DEBUG,  	    KERN_INFO "dma_tx: pDevice->wCurrentRate = %d\n", @@ -3015,7 +3015,7 @@ int nsDMA_tx_packet(PSDevice pDevice, unsigned int uDMAIdx, struct sk_buff *skb)      if (bNeedEncryption == TRUE) {          DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ntohs Pkt Type=%04x\n", ntohs(pDevice->sTxEthHeader.wType)); -	if ((pDevice->sTxEthHeader.wType) == cpu_to_le16(ETH_P_PAE)) { +	if ((pDevice->sTxEthHeader.wType) == cpu_to_be16(ETH_P_PAE)) {  		bNeedEncryption = FALSE;              DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Pkt Type=%04x\n", (pDevice->sTxEthHeader.wType));              if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && (pMgmt->eCurrState == WMAC_STATE_ASSOC)) { diff --git a/drivers/staging/wlan-ng/cfg80211.c b/drivers/staging/wlan-ng/cfg80211.c index fabff4d650e..0970127344e 100644 --- a/drivers/staging/wlan-ng/cfg80211.c +++ b/drivers/staging/wlan-ng/cfg80211.c @@ -327,9 +327,9 @@ int prism2_get_station(struct wiphy *wiphy, struct net_device *dev,  	return result;  } -int prism2_scan(struct wiphy *wiphy, struct net_device *dev, -		struct cfg80211_scan_request *request) +int prism2_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)  { +	struct net_device *dev = request->wdev->netdev;  	struct prism2_wiphy_private *priv = wiphy_priv(wiphy);  	wlandevice_t *wlandev = dev->ml_priv;  	struct p80211msg_dot11req_scan msg1; diff --git a/drivers/staging/zcache/zcache-main.c b/drivers/staging/zcache/zcache-main.c index c214977b4ab..52b43b7b83d 100644 --- a/drivers/staging/zcache/zcache-main.c +++ b/drivers/staging/zcache/zcache-main.c @@ -1251,13 +1251,12 @@ static int zcache_pampd_get_data_and_free(char *data, size_t *bufsize, bool raw,  					void *pampd, struct tmem_pool *pool,  					struct tmem_oid *oid, uint32_t index)  { -	int ret = 0; -  	BUG_ON(!is_ephemeral(pool)); -	zbud_decompress((struct page *)(data), pampd); +	if (zbud_decompress((struct page *)(data), pampd) < 0) +		return -EINVAL;  	zbud_free_and_delist((struct zbud_hdr *)pampd);  	atomic_dec(&zcache_curr_eph_pampd_count); -	return ret; +	return 0;  }  /* diff --git a/drivers/target/iscsi/iscsi_target_login.c b/drivers/target/iscsi/iscsi_target_login.c index 0694d9b1bce..6aba4395e8d 100644 --- a/drivers/target/iscsi/iscsi_target_login.c +++ b/drivers/target/iscsi/iscsi_target_login.c @@ -221,6 +221,7 @@ static int iscsi_login_zero_tsih_s1(  {  	struct iscsi_session *sess = NULL;  	struct iscsi_login_req *pdu = (struct iscsi_login_req *)buf; +	int ret;  	sess = kzalloc(sizeof(struct iscsi_session), GFP_KERNEL);  	if (!sess) { @@ -257,9 +258,17 @@ static int iscsi_login_zero_tsih_s1(  		return -ENOMEM;  	}  	spin_lock(&sess_idr_lock); -	idr_get_new(&sess_idr, NULL, &sess->session_index); +	ret = idr_get_new(&sess_idr, NULL, &sess->session_index);  	spin_unlock(&sess_idr_lock); +	if (ret < 0) { +		pr_err("idr_get_new() for sess_idr failed\n"); +		iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR, +				ISCSI_LOGIN_STATUS_NO_RESOURCES); +		kfree(sess); +		return -ENOMEM; +	} +  	sess->creation_time = get_jiffies_64();  	spin_lock_init(&sess->session_stats_lock);  	/* diff --git a/drivers/target/target_core_alua.c b/drivers/target/target_core_alua.c index 91799973081..41641ba5482 100644 --- a/drivers/target/target_core_alua.c +++ b/drivers/target/target_core_alua.c @@ -218,6 +218,13 @@ int target_emulate_set_target_port_groups(struct se_cmd *cmd)  		cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;  		return -EINVAL;  	} +	if (cmd->data_length < 4) { +		pr_warn("SET TARGET PORT GROUPS parameter list length %u too" +			" small\n", cmd->data_length); +		cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; +		return -EINVAL; +	} +  	buf = transport_kmap_data_sg(cmd);  	/* diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index cf2c66f3c11..9fc9a6006ca 100644 --- a/drivers/target/target_core_device.c +++ b/drivers/target/target_core_device.c @@ -669,6 +669,13 @@ int target_report_luns(struct se_cmd *se_cmd)  	unsigned char *buf;  	u32 lun_count = 0, offset = 8, i; +	if (se_cmd->data_length < 16) { +		pr_warn("REPORT LUNS allocation length %u too small\n", +			se_cmd->data_length); +		se_cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; +		return -EINVAL; +	} +  	buf = transport_kmap_data_sg(se_cmd);  	if (!buf)  		return -ENOMEM; diff --git a/drivers/target/target_core_iblock.c b/drivers/target/target_core_iblock.c index 76db75e836e..9ba495477fd 100644 --- a/drivers/target/target_core_iblock.c +++ b/drivers/target/target_core_iblock.c @@ -325,17 +325,30 @@ static int iblock_execute_unmap(struct se_cmd *cmd)  	struct iblock_dev *ibd = dev->dev_ptr;  	unsigned char *buf, *ptr = NULL;  	sector_t lba; -	int size = cmd->data_length; +	int size;  	u32 range;  	int ret = 0;  	int dl, bd_dl; +	if (cmd->data_length < 8) { +		pr_warn("UNMAP parameter list length %u too small\n", +			cmd->data_length); +		cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; +		return -EINVAL; +	} +  	buf = transport_kmap_data_sg(cmd);  	dl = get_unaligned_be16(&buf[0]);  	bd_dl = get_unaligned_be16(&buf[2]); -	size = min(size - 8, bd_dl); +	size = cmd->data_length - 8; +	if (bd_dl > size) +		pr_warn("UNMAP parameter list length %u too small, ignoring bd_dl %u\n", +			cmd->data_length, bd_dl); +	else +		size = bd_dl; +  	if (size / 16 > dev->se_sub_dev->se_dev_attrib.max_unmap_block_desc_count) {  		cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;  		ret = -EINVAL; diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c index 1e946502c37..956c84c6b66 100644 --- a/drivers/target/target_core_pr.c +++ b/drivers/target/target_core_pr.c @@ -1540,6 +1540,14 @@ static int core_scsi3_decode_spec_i_port(  	tidh_new->dest_local_nexus = 1;  	list_add_tail(&tidh_new->dest_list, &tid_dest_list); +	if (cmd->data_length < 28) { +		pr_warn("SPC-PR: Received PR OUT parameter list" +			" length too small: %u\n", cmd->data_length); +		cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; +		ret = -EINVAL; +		goto out; +	} +  	buf = transport_kmap_data_sg(cmd);  	/*  	 * For a PERSISTENT RESERVE OUT specify initiator ports payload, diff --git a/drivers/target/target_core_pscsi.c b/drivers/target/target_core_pscsi.c index 5552fa7426b..9d7ce3daa26 100644 --- a/drivers/target/target_core_pscsi.c +++ b/drivers/target/target_core_pscsi.c @@ -667,7 +667,8 @@ static void pscsi_free_device(void *p)  	kfree(pdv);  } -static int pscsi_transport_complete(struct se_cmd *cmd, struct scatterlist *sg) +static void pscsi_transport_complete(struct se_cmd *cmd, struct scatterlist *sg, +				     unsigned char *sense_buffer)  {  	struct pscsi_dev_virt *pdv = cmd->se_dev->dev_ptr;  	struct scsi_device *sd = pdv->pdv_sd; @@ -679,7 +680,7 @@ static int pscsi_transport_complete(struct se_cmd *cmd, struct scatterlist *sg)  	 * not been allocated because TCM is handling the emulation directly.  	 */  	if (!pt) -		return 0; +		return;  	cdb = &pt->pscsi_cdb[0];  	result = pt->pscsi_result; @@ -687,11 +688,11 @@ static int pscsi_transport_complete(struct se_cmd *cmd, struct scatterlist *sg)  	 * Hack to make sure that Write-Protect modepage is set if R/O mode is  	 * forced.  	 */ +	if (!cmd->se_deve || !cmd->data_length) +		goto after_mode_sense; +  	if (((cdb[0] == MODE_SENSE) || (cdb[0] == MODE_SENSE_10)) &&  	     (status_byte(result) << 1) == SAM_STAT_GOOD) { -		if (!cmd->se_deve) -			goto after_mode_sense; -  		if (cmd->se_deve->lun_flags & TRANSPORT_LUNFLAGS_READ_ONLY) {  			unsigned char *buf = transport_kmap_data_sg(cmd); @@ -708,7 +709,7 @@ static int pscsi_transport_complete(struct se_cmd *cmd, struct scatterlist *sg)  	}  after_mode_sense: -	if (sd->type != TYPE_TAPE) +	if (sd->type != TYPE_TAPE || !cmd->data_length)  		goto after_mode_select;  	/* @@ -750,10 +751,10 @@ after_mode_sense:  	}  after_mode_select: -	if (status_byte(result) & CHECK_CONDITION) -		return 1; - -	return 0; +	if (sense_buffer && (status_byte(result) & CHECK_CONDITION)) { +		memcpy(sense_buffer, pt->pscsi_sense, TRANSPORT_SENSE_BUFFER); +		cmd->se_cmd_flags |= SCF_TRANSPORT_TASK_SENSE; +	}  }  enum { @@ -1184,13 +1185,6 @@ fail:  	return -ENOMEM;  } -static unsigned char *pscsi_get_sense_buffer(struct se_cmd *cmd) -{ -	struct pscsi_plugin_task *pt = cmd->priv; - -	return pt->pscsi_sense; -} -  /*	pscsi_get_device_rev():   *   * @@ -1273,7 +1267,6 @@ static struct se_subsystem_api pscsi_template = {  	.check_configfs_dev_params = pscsi_check_configfs_dev_params,  	.set_configfs_dev_params = pscsi_set_configfs_dev_params,  	.show_configfs_dev_params = pscsi_show_configfs_dev_params, -	.get_sense_buffer	= pscsi_get_sense_buffer,  	.get_device_rev		= pscsi_get_device_rev,  	.get_device_type	= pscsi_get_device_type,  	.get_blocks		= pscsi_get_blocks, diff --git a/drivers/target/target_core_spc.c b/drivers/target/target_core_spc.c index 4c861de538c..388a922c8f6 100644 --- a/drivers/target/target_core_spc.c +++ b/drivers/target/target_core_spc.c @@ -877,9 +877,11 @@ static int spc_emulate_modesense(struct se_cmd *cmd)  static int spc_emulate_request_sense(struct se_cmd *cmd)  {  	unsigned char *cdb = cmd->t_task_cdb; -	unsigned char *buf; +	unsigned char *rbuf;  	u8 ua_asc = 0, ua_ascq = 0; -	int err = 0; +	unsigned char buf[SE_SENSE_BUF]; + +	memset(buf, 0, SE_SENSE_BUF);  	if (cdb[1] & 0x01) {  		pr_err("REQUEST_SENSE description emulation not" @@ -888,20 +890,21 @@ static int spc_emulate_request_sense(struct se_cmd *cmd)  		return -ENOSYS;  	} -	buf = transport_kmap_data_sg(cmd); - -	if (!core_scsi3_ua_clear_for_request_sense(cmd, &ua_asc, &ua_ascq)) { +	rbuf = transport_kmap_data_sg(cmd); +	if (cmd->scsi_sense_reason != 0) { +		/* +		 * Out of memory.  We will fail with CHECK CONDITION, so +		 * we must not clear the unit attention condition. +		 */ +		target_complete_cmd(cmd, CHECK_CONDITION); +		return 0; +	} else if (!core_scsi3_ua_clear_for_request_sense(cmd, &ua_asc, &ua_ascq)) {  		/*  		 * CURRENT ERROR, UNIT ATTENTION  		 */  		buf[0] = 0x70;  		buf[SPC_SENSE_KEY_OFFSET] = UNIT_ATTENTION; -		if (cmd->data_length < 18) { -			buf[7] = 0x00; -			err = -EINVAL; -			goto end; -		}  		/*  		 * The Additional Sense Code (ASC) from the UNIT ATTENTION  		 */ @@ -915,11 +918,6 @@ static int spc_emulate_request_sense(struct se_cmd *cmd)  		buf[0] = 0x70;  		buf[SPC_SENSE_KEY_OFFSET] = NO_SENSE; -		if (cmd->data_length < 18) { -			buf[7] = 0x00; -			err = -EINVAL; -			goto end; -		}  		/*  		 * NO ADDITIONAL SENSE INFORMATION  		 */ @@ -927,8 +925,11 @@ static int spc_emulate_request_sense(struct se_cmd *cmd)  		buf[7] = 0x0A;  	} -end: -	transport_kunmap_data_sg(cmd); +	if (rbuf) { +		memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length)); +		transport_kunmap_data_sg(cmd); +	} +  	target_complete_cmd(cmd, GOOD);  	return 0;  } diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 4de3186dc44..269f5448839 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -567,6 +567,34 @@ static void target_complete_failure_work(struct work_struct *work)  	transport_generic_request_failure(cmd);  } +/* + * Used when asking transport to copy Sense Data from the underlying + * Linux/SCSI struct scsi_cmnd + */ +static unsigned char *transport_get_sense_buffer(struct se_cmd *cmd) +{ +	unsigned char *buffer = cmd->sense_buffer; +	struct se_device *dev = cmd->se_dev; +	u32 offset = 0; + +	WARN_ON(!cmd->se_lun); + +	if (!dev) +		return NULL; + +	if (cmd->se_cmd_flags & SCF_SENT_CHECK_CONDITION) +		return NULL; + +	offset = cmd->se_tfo->set_fabric_sense_len(cmd, TRANSPORT_SENSE_BUFFER); + +	/* Automatically padded */ +	cmd->scsi_sense_length = TRANSPORT_SENSE_BUFFER + offset; + +	pr_debug("HBA_[%u]_PLUG[%s]: Requesting sense for SAM STATUS: 0x%02x\n", +		dev->se_hba->hba_id, dev->transport->name, cmd->scsi_status); +	return &buffer[offset]; +} +  void target_complete_cmd(struct se_cmd *cmd, u8 scsi_status)  {  	struct se_device *dev = cmd->se_dev; @@ -580,11 +608,11 @@ void target_complete_cmd(struct se_cmd *cmd, u8 scsi_status)  	cmd->transport_state &= ~CMD_T_BUSY;  	if (dev && dev->transport->transport_complete) { -		if (dev->transport->transport_complete(cmd, -				cmd->t_data_sg) != 0) { -			cmd->se_cmd_flags |= SCF_TRANSPORT_TASK_SENSE; +		dev->transport->transport_complete(cmd, +				cmd->t_data_sg, +				transport_get_sense_buffer(cmd)); +		if (cmd->se_cmd_flags & SCF_TRANSPORT_TASK_SENSE)  			success = 1; -		}  	}  	/* @@ -1181,15 +1209,20 @@ int target_cmd_size_check(struct se_cmd *cmd, unsigned int size)  			/* Returns CHECK_CONDITION + INVALID_CDB_FIELD */  			goto out_invalid_cdb_field;  		} - +		/* +		 * For the overflow case keep the existing fabric provided +		 * ->data_length.  Otherwise for the underflow case, reset +		 * ->data_length to the smaller SCSI expected data transfer +		 * length. +		 */  		if (size > cmd->data_length) {  			cmd->se_cmd_flags |= SCF_OVERFLOW_BIT;  			cmd->residual_count = (size - cmd->data_length);  		} else {  			cmd->se_cmd_flags |= SCF_UNDERFLOW_BIT;  			cmd->residual_count = (cmd->data_length - size); +			cmd->data_length = size;  		} -		cmd->data_length = size;  	}  	return 0; @@ -1816,61 +1849,6 @@ execute:  EXPORT_SYMBOL(target_execute_cmd);  /* - * Used to obtain Sense Data from underlying Linux/SCSI struct scsi_cmnd - */ -static int transport_get_sense_data(struct se_cmd *cmd) -{ -	unsigned char *buffer = cmd->sense_buffer, *sense_buffer = NULL; -	struct se_device *dev = cmd->se_dev; -	unsigned long flags; -	u32 offset = 0; - -	WARN_ON(!cmd->se_lun); - -	if (!dev) -		return 0; - -	spin_lock_irqsave(&cmd->t_state_lock, flags); -	if (cmd->se_cmd_flags & SCF_SENT_CHECK_CONDITION) { -		spin_unlock_irqrestore(&cmd->t_state_lock, flags); -		return 0; -	} - -	if (!(cmd->se_cmd_flags & SCF_TRANSPORT_TASK_SENSE)) -		goto out; - -	if (!dev->transport->get_sense_buffer) { -		pr_err("dev->transport->get_sense_buffer is NULL\n"); -		goto out; -	} - -	sense_buffer = dev->transport->get_sense_buffer(cmd); -	if (!sense_buffer) { -		pr_err("ITT 0x%08x cmd %p: Unable to locate" -			" sense buffer for task with sense\n", -			cmd->se_tfo->get_task_tag(cmd), cmd); -		goto out; -	} - -	spin_unlock_irqrestore(&cmd->t_state_lock, flags); - -	offset = cmd->se_tfo->set_fabric_sense_len(cmd, TRANSPORT_SENSE_BUFFER); - -	memcpy(&buffer[offset], sense_buffer, TRANSPORT_SENSE_BUFFER); - -	/* Automatically padded */ -	cmd->scsi_sense_length = TRANSPORT_SENSE_BUFFER + offset; - -	pr_debug("HBA_[%u]_PLUG[%s]: Set SAM STATUS: 0x%02x and sense\n", -		dev->se_hba->hba_id, dev->transport->name, cmd->scsi_status); -	return 0; - -out: -	spin_unlock_irqrestore(&cmd->t_state_lock, flags); -	return -1; -} - -/*   * Process all commands up to the last received ORDERED task attribute which   * requires another blocking boundary   */ @@ -1985,7 +1963,7 @@ static void transport_handle_queue_full(  static void target_complete_ok_work(struct work_struct *work)  {  	struct se_cmd *cmd = container_of(work, struct se_cmd, work); -	int reason = 0, ret; +	int ret;  	/*  	 * Check if we need to move delayed/dormant tasks from cmds on the @@ -2002,23 +1980,19 @@ static void target_complete_ok_work(struct work_struct *work)  		schedule_work(&cmd->se_dev->qf_work_queue);  	/* -	 * Check if we need to retrieve a sense buffer from +	 * Check if we need to send a sense buffer from  	 * the struct se_cmd in question.  	 */  	if (cmd->se_cmd_flags & SCF_TRANSPORT_TASK_SENSE) { -		if (transport_get_sense_data(cmd) < 0) -			reason = TCM_NON_EXISTENT_LUN; - -		if (cmd->scsi_status) { -			ret = transport_send_check_condition_and_sense( -					cmd, reason, 1); -			if (ret == -EAGAIN || ret == -ENOMEM) -				goto queue_full; +		WARN_ON(!cmd->scsi_status); +		ret = transport_send_check_condition_and_sense( +					cmd, 0, 1); +		if (ret == -EAGAIN || ret == -ENOMEM) +			goto queue_full; -			transport_lun_remove_cmd(cmd); -			transport_cmd_check_stop_to_fabric(cmd); -			return; -		} +		transport_lun_remove_cmd(cmd); +		transport_cmd_check_stop_to_fabric(cmd); +		return;  	}  	/*  	 * Check for a callback, used by amongst other things @@ -2216,7 +2190,6 @@ void *transport_kmap_data_sg(struct se_cmd *cmd)  	struct page **pages;  	int i; -	BUG_ON(!sg);  	/*  	 * We need to take into account a possible offset here for fabrics like  	 * tcm_loop who may be using a contig buffer from the SCSI midlayer for @@ -2224,13 +2197,17 @@ void *transport_kmap_data_sg(struct se_cmd *cmd)  	 */  	if (!cmd->t_data_nents)  		return NULL; -	else if (cmd->t_data_nents == 1) + +	BUG_ON(!sg); +	if (cmd->t_data_nents == 1)  		return kmap(sg_page(sg)) + sg->offset;  	/* >1 page. use vmap */  	pages = kmalloc(sizeof(*pages) * cmd->t_data_nents, GFP_KERNEL); -	if (!pages) +	if (!pages) { +		cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;  		return NULL; +	}  	/* convert sg[] to pages[] */  	for_each_sg(cmd->t_data_sg, sg, cmd->t_data_nents, i) { @@ -2239,8 +2216,10 @@ void *transport_kmap_data_sg(struct se_cmd *cmd)  	cmd->t_data_vmap = vmap(pages, cmd->t_data_nents,  VM_MAP, PAGE_KERNEL);  	kfree(pages); -	if (!cmd->t_data_vmap) +	if (!cmd->t_data_vmap) { +		cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;  		return NULL; +	}  	return cmd->t_data_vmap + cmd->t_data_sg[0].offset;  } @@ -2326,19 +2305,14 @@ int transport_generic_new_cmd(struct se_cmd *cmd)  	 * into the fabric for data transfers, go ahead and complete it right  	 * away.  	 */ -	if (!cmd->data_length) { +	if (!cmd->data_length && +	    cmd->t_task_cdb[0] != REQUEST_SENSE && +	    cmd->se_dev->transport->transport_type != TRANSPORT_PLUGIN_PHBA_PDEV) {  		spin_lock_irq(&cmd->t_state_lock);  		cmd->t_state = TRANSPORT_COMPLETE;  		cmd->transport_state |= CMD_T_ACTIVE;  		spin_unlock_irq(&cmd->t_state_lock); -		if (cmd->t_task_cdb[0] == REQUEST_SENSE) { -			u8 ua_asc = 0, ua_ascq = 0; - -			core_scsi3_ua_clear_for_request_sense(cmd, -					&ua_asc, &ua_ascq); -		} -  		INIT_WORK(&cmd->work, target_complete_ok_work);  		queue_work(target_completion_wq, &cmd->work);  		return 0; diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index d5c689d6217..e309e8b0aab 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c @@ -132,6 +132,7 @@  #define  UCR4_OREN  	 (1<<1)  /* Receiver overrun interrupt enable */  #define  UCR4_DREN  	 (1<<0)  /* Recv data ready interrupt enable */  #define  UFCR_RXTL_SHF   0       /* Receiver trigger level shift */ +#define  UFCR_DCEDTE	 (1<<6)  /* DCE/DTE mode select */  #define  UFCR_RFDIV      (7<<7)  /* Reference freq divider mask */  #define  UFCR_RFDIV_REG(x)	(((x) < 7 ? 6 - (x) : 6) << 7)  #define  UFCR_TXTL_SHF   10      /* Transmitter trigger level shift */ @@ -667,22 +668,11 @@ static void imx_break_ctl(struct uart_port *port, int break_state)  static int imx_setup_ufcr(struct imx_port *sport, unsigned int mode)  {  	unsigned int val; -	unsigned int ufcr_rfdiv; - -	/* set receiver / transmitter trigger level. -	 * RFDIV is set such way to satisfy requested uartclk value -	 */ -	val = TXTL << 10 | RXTL; -	ufcr_rfdiv = (clk_get_rate(sport->clk_per) + sport->port.uartclk / 2) -			/ sport->port.uartclk; - -	if(!ufcr_rfdiv) -		ufcr_rfdiv = 1; - -	val |= UFCR_RFDIV_REG(ufcr_rfdiv); +	/* set receiver / transmitter trigger level */ +	val = readl(sport->port.membase + UFCR) & (UFCR_RFDIV | UFCR_DCEDTE); +	val |= TXTL << UFCR_TXTL_SHF | RXTL;  	writel(val, sport->port.membase + UFCR); -  	return 0;  } @@ -754,6 +744,7 @@ static int imx_startup(struct uart_port *port)  		}  	} +	spin_lock_irqsave(&sport->port.lock, flags);  	/*  	 * Finally, clear and enable interrupts  	 */ @@ -807,7 +798,6 @@ static int imx_startup(struct uart_port *port)  	/*  	 * Enable modem status interrupts  	 */ -	spin_lock_irqsave(&sport->port.lock,flags);  	imx_enable_ms(&sport->port);  	spin_unlock_irqrestore(&sport->port.lock,flags); @@ -837,10 +827,13 @@ static void imx_shutdown(struct uart_port *port)  {  	struct imx_port *sport = (struct imx_port *)port;  	unsigned long temp; +	unsigned long flags; +	spin_lock_irqsave(&sport->port.lock, flags);  	temp = readl(sport->port.membase + UCR2);  	temp &= ~(UCR2_TXEN);  	writel(temp, sport->port.membase + UCR2); +	spin_unlock_irqrestore(&sport->port.lock, flags);  	if (USE_IRDA(sport)) {  		struct imxuart_platform_data *pdata; @@ -869,12 +862,14 @@ static void imx_shutdown(struct uart_port *port)  	 * Disable all interrupts, port and break condition.  	 */ +	spin_lock_irqsave(&sport->port.lock, flags);  	temp = readl(sport->port.membase + UCR1);  	temp &= ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN);  	if (USE_IRDA(sport))  		temp &= ~(UCR1_IREN);  	writel(temp, sport->port.membase + UCR1); +	spin_unlock_irqrestore(&sport->port.lock, flags);  }  static void @@ -1217,6 +1212,9 @@ imx_console_write(struct console *co, const char *s, unsigned int count)  	struct imx_port *sport = imx_ports[co->index];  	struct imx_port_ucrs old_ucr;  	unsigned int ucr1; +	unsigned long flags; + +	spin_lock_irqsave(&sport->port.lock, flags);  	/*  	 *	First, save UCR1/2/3 and then disable interrupts @@ -1242,6 +1240,8 @@ imx_console_write(struct console *co, const char *s, unsigned int count)  	while (!(readl(sport->port.membase + USR2) & USR2_TXDC));  	imx_port_ucrs_restore(&sport->port, &old_ucr); + +	spin_unlock_irqrestore(&sport->port.lock, flags);  }  /* diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index 65a55abb791..5f0cb417b73 100644 --- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c @@ -109,12 +109,14 @@ static struct usb_driver wdm_driver;  /* return intfdata if we own the interface, else look up intf in the list */  static struct wdm_device *wdm_find_device(struct usb_interface *intf)  { -	struct wdm_device *desc = NULL; +	struct wdm_device *desc;  	spin_lock(&wdm_device_list_lock);  	list_for_each_entry(desc, &wdm_device_list, device_list)  		if (desc->intf == intf) -			break; +			goto found; +	desc = NULL; +found:  	spin_unlock(&wdm_device_list_lock);  	return desc; @@ -122,12 +124,14 @@ static struct wdm_device *wdm_find_device(struct usb_interface *intf)  static struct wdm_device *wdm_find_device_by_minor(int minor)  { -	struct wdm_device *desc = NULL; +	struct wdm_device *desc;  	spin_lock(&wdm_device_list_lock);  	list_for_each_entry(desc, &wdm_device_list, device_list)  		if (desc->intf->minor == minor) -			break; +			goto found; +	desc = NULL; +found:  	spin_unlock(&wdm_device_list_lock);  	return desc; diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index 2dbb5154f35..fdefd9c7f7a 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c @@ -71,6 +71,10 @@ static const struct usb_device_id usb_quirk_list[] = {  	{ USB_DEVICE(0x04b4, 0x0526), .driver_info =  			USB_QUIRK_CONFIG_INTF_STRINGS }, +	/* Microchip Joss Optical infrared touchboard device */ +	{ USB_DEVICE(0x04d8, 0x000c), .driver_info = +			USB_QUIRK_CONFIG_INTF_STRINGS }, +  	/* Samsung Android phone modem - ID conflict with SPH-I500 */  	{ USB_DEVICE(0x04e8, 0x6601), .driver_info =  			USB_QUIRK_CONFIG_INTF_STRINGS }, diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index bed2c161546..b415c0c859d 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -440,16 +440,21 @@ static int __devinit dwc3_probe(struct platform_device *pdev)  		dev_err(dev, "missing IRQ\n");  		return -ENODEV;  	} -	dwc->xhci_resources[1] = *res; +	dwc->xhci_resources[1].start = res->start; +	dwc->xhci_resources[1].end = res->end; +	dwc->xhci_resources[1].flags = res->flags; +	dwc->xhci_resources[1].name = res->name;  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);  	if (!res) {  		dev_err(dev, "missing memory resource\n");  		return -ENODEV;  	} -	dwc->xhci_resources[0] = *res; +	dwc->xhci_resources[0].start = res->start;  	dwc->xhci_resources[0].end = dwc->xhci_resources[0].start +  					DWC3_XHCI_REGS_END; +	dwc->xhci_resources[0].flags = res->flags; +	dwc->xhci_resources[0].name = res->name;  	 /*  	  * Request memory region but exclude xHCI regs, diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index 1bba97ba218..d7da073a23f 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c @@ -792,7 +792,6 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc,  		transferred = min_t(u32, ur->length,  				transfer_size - length);  		memcpy(ur->buf, dwc->ep0_bounce, transferred); -		dwc->ep0_bounced = false;  	} else {  		transferred = ur->length - length;  	} diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index ba444e7f9c4..c9e729a4bf6 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -263,8 +263,11 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req,  	if (req->request.status == -EINPROGRESS)  		req->request.status = status; -	usb_gadget_unmap_request(&dwc->gadget, &req->request, -			req->direction); +	if (dwc->ep0_bounced && dep->number == 0) +		dwc->ep0_bounced = false; +	else +		usb_gadget_unmap_request(&dwc->gadget, &req->request, +				req->direction);  	dev_dbg(dwc->dev, "request %p from %s completed %d/%d ===> %d\n",  			req, dep->name, req->request.actual, @@ -1017,6 +1020,7 @@ static void __dwc3_gadget_start_isoc(struct dwc3 *dwc,  	if (list_empty(&dep->request_list)) {  		dev_vdbg(dwc->dev, "ISOC ep %s run out for requests.\n",  			dep->name); +		dep->flags |= DWC3_EP_PENDING_REQUEST;  		return;  	} @@ -1078,6 +1082,19 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req)  	 *  	 */  	if (dep->flags & DWC3_EP_PENDING_REQUEST) { +		int	ret; + +		/* +		 * If xfernotready is already elapsed and it is a case +		 * of isoc transfer, then issue END TRANSFER, so that +		 * you can receive xfernotready again and can have +		 * notion of current microframe. +		 */ +		if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) { +			dwc3_stop_active_transfer(dwc, dep->number); +			return 0; +		} +  		ret = __dwc3_gadget_kick_transfer(dep, 0, true);  		if (ret && ret != -EBUSY)  			dev_dbg(dwc->dev, "%s: failed to kick transfers\n", diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c index af931282843..89d90b5fb78 100644 --- a/drivers/usb/gadget/at91_udc.c +++ b/drivers/usb/gadget/at91_udc.c @@ -475,8 +475,7 @@ static int at91_ep_enable(struct usb_ep *_ep,  	unsigned long	flags;  	if (!_ep || !ep -			|| !desc || ep->ep.desc -			|| _ep->name == ep0name +			|| !desc || _ep->name == ep0name  			|| desc->bDescriptorType != USB_DT_ENDPOINT  			|| (maxpacket = usb_endpoint_maxp(desc)) == 0  			|| maxpacket > ep->maxpacket) { @@ -531,7 +530,6 @@ ok:  	tmp |= AT91_UDP_EPEDS;  	__raw_writel(tmp, ep->creg); -	ep->ep.desc = desc;  	ep->ep.maxpacket = maxpacket;  	/* @@ -1636,7 +1634,6 @@ static int at91_start(struct usb_gadget *gadget,  	udc->driver = driver;  	udc->gadget.dev.driver = &driver->driver;  	udc->gadget.dev.of_node = udc->pdev->dev.of_node; -	dev_set_drvdata(&udc->gadget.dev, &driver->driver);  	udc->enabled = 1;  	udc->selfpowered = 1; @@ -1657,7 +1654,6 @@ static int at91_stop(struct usb_gadget *gadget,  	spin_unlock_irqrestore(&udc->lock, flags);  	udc->gadget.dev.driver = NULL; -	dev_set_drvdata(&udc->gadget.dev, NULL);  	udc->driver = NULL;  	DBG("unbound from %s\n", driver->driver.name); diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index 91916f693ff..0f7541be28f 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c @@ -1918,6 +1918,27 @@ done:  	return retval;  } +/* usb 3.0 root hub device descriptor */ +struct { +	struct usb_bos_descriptor bos; +	struct usb_ss_cap_descriptor ss_cap; +} __packed usb3_bos_desc = { + +	.bos = { +		.bLength		= USB_DT_BOS_SIZE, +		.bDescriptorType	= USB_DT_BOS, +		.wTotalLength		= cpu_to_le16(sizeof(usb3_bos_desc)), +		.bNumDeviceCaps		= 1, +	}, +	.ss_cap = { +		.bLength		= USB_DT_USB_SS_CAP_SIZE, +		.bDescriptorType	= USB_DT_DEVICE_CAPABILITY, +		.bDevCapabilityType	= USB_SS_CAP_TYPE, +		.wSpeedSupported	= cpu_to_le16(USB_5GBPS_OPERATION), +		.bFunctionalitySupport	= ilog2(USB_5GBPS_OPERATION), +	}, +}; +  static inline void  ss_hub_descriptor(struct usb_hub_descriptor *desc)  { @@ -2008,6 +2029,18 @@ static int dummy_hub_control(  		else  			hub_descriptor((struct usb_hub_descriptor *) buf);  		break; + +	case DeviceRequest | USB_REQ_GET_DESCRIPTOR: +		if (hcd->speed != HCD_USB3) +			goto error; + +		if ((wValue >> 8) != USB_DT_BOS) +			goto error; + +		memcpy(buf, &usb3_bos_desc, sizeof(usb3_bos_desc)); +		retval = sizeof(usb3_bos_desc); +		break; +  	case GetHubStatus:  		*(__le32 *) buf = cpu_to_le32(0);  		break; @@ -2505,10 +2538,8 @@ static int dummy_hcd_probe(struct platform_device *pdev)  	hs_hcd->has_tt = 1;  	retval = usb_add_hcd(hs_hcd, 0, 0); -	if (retval != 0) { -		usb_put_hcd(hs_hcd); -		return retval; -	} +	if (retval) +		goto put_usb2_hcd;  	if (mod_data.is_super_speed) {  		ss_hcd = usb_create_shared_hcd(&dummy_hcd, &pdev->dev, @@ -2527,6 +2558,8 @@ static int dummy_hcd_probe(struct platform_device *pdev)  put_usb3_hcd:  	usb_put_hcd(ss_hcd);  dealloc_usb2_hcd: +	usb_remove_hcd(hs_hcd); +put_usb2_hcd:  	usb_put_hcd(hs_hcd);  	the_controller.hs_hcd = the_controller.ss_hcd = NULL;  	return retval; diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c index 8adc79d1b40..829aba75a6d 100644 --- a/drivers/usb/gadget/f_fs.c +++ b/drivers/usb/gadget/f_fs.c @@ -34,11 +34,15 @@  /* Debugging ****************************************************************/  #ifdef VERBOSE_DEBUG +#ifndef pr_vdebug  #  define pr_vdebug pr_debug +#endif /* pr_vdebug */  #  define ffs_dump_mem(prefix, ptr, len) \  	print_hex_dump_bytes(pr_fmt(prefix ": "), DUMP_PREFIX_NONE, ptr, len)  #else +#ifndef pr_vdebug  #  define pr_vdebug(...)                 do { } while (0) +#endif /* pr_vdebug */  #  define ffs_dump_mem(prefix, ptr, len) do { } while (0)  #endif /* VERBOSE_DEBUG */ diff --git a/drivers/usb/gadget/u_serial.c b/drivers/usb/gadget/u_serial.c index 5b3f5fffea9..da6d479ff9a 100644 --- a/drivers/usb/gadget/u_serial.c +++ b/drivers/usb/gadget/u_serial.c @@ -132,11 +132,15 @@ static unsigned	n_ports;  #ifdef VERBOSE_DEBUG +#ifndef pr_vdebug  #define pr_vdebug(fmt, arg...) \  	pr_debug(fmt, ##arg) +#endif /* pr_vdebug */  #else +#ifndef pr_vdebig  #define pr_vdebug(fmt, arg...) \  	({ if (0) pr_debug(fmt, ##arg); }) +#endif /* pr_vdebug */  #endif  /*-------------------------------------------------------------------------*/ diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index 9bc39ca460c..4b66374bdc8 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c @@ -128,9 +128,17 @@ qh_refresh (struct ehci_hcd *ehci, struct ehci_qh *qh)  	else {  		qtd = list_entry (qh->qtd_list.next,  				struct ehci_qtd, qtd_list); -		/* first qtd may already be partially processed */ -		if (cpu_to_hc32(ehci, qtd->qtd_dma) == qh->hw->hw_current) +		/* +		 * first qtd may already be partially processed. +		 * If we come here during unlink, the QH overlay region +		 * might have reference to the just unlinked qtd. The +		 * qtd is updated in qh_completions(). Update the QH +		 * overlay here. +		 */ +		if (cpu_to_hc32(ehci, qtd->qtd_dma) == qh->hw->hw_current) { +			qh->hw->hw_qtd_next = qtd->hw_next;  			qtd = NULL; +		}  	}  	if (qtd) diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c index a665b3eaa74..aaa8d2bce21 100644 --- a/drivers/usb/host/ohci-at91.c +++ b/drivers/usb/host/ohci-at91.c @@ -570,6 +570,16 @@ static int __devinit ohci_hcd_at91_drv_probe(struct platform_device *pdev)  	if (pdata) {  		at91_for_each_port(i) { +			/* +			 * do not configure PIO if not in relation with +			 * real USB port on board +			 */ +			if (i >= pdata->ports) { +				pdata->vbus_pin[i] = -EINVAL; +				pdata->overcurrent_pin[i] = -EINVAL; +				break; +			} +  			if (!gpio_is_valid(pdata->vbus_pin[i]))  				continue;  			gpio = pdata->vbus_pin[i]; diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c index c5e9e4a76f1..966d1484ee7 100644 --- a/drivers/usb/host/pci-quirks.c +++ b/drivers/usb/host/pci-quirks.c @@ -75,7 +75,9 @@  #define	NB_PIF0_PWRDOWN_1	0x01100013  #define USB_INTEL_XUSB2PR      0xD0 +#define USB_INTEL_USB2PRM      0xD4  #define USB_INTEL_USB3_PSSEN   0xD8 +#define USB_INTEL_USB3PRM      0xDC  static struct amd_chipset_info {  	struct pci_dev	*nb_dev; @@ -772,10 +774,18 @@ void usb_enable_xhci_ports(struct pci_dev *xhci_pdev)  		return;  	} -	ports_available = 0xffffffff; +	/* Read USB3PRM, the USB 3.0 Port Routing Mask Register +	 * Indicate the ports that can be changed from OS. +	 */ +	pci_read_config_dword(xhci_pdev, USB_INTEL_USB3PRM, +			&ports_available); + +	dev_dbg(&xhci_pdev->dev, "Configurable ports to enable SuperSpeed: 0x%x\n", +			ports_available); +  	/* Write USB3_PSSEN, the USB 3.0 Port SuperSpeed Enable -	 * Register, to turn on SuperSpeed terminations for all -	 * available ports. +	 * Register, to turn on SuperSpeed terminations for the +	 * switchable ports.  	 */  	pci_write_config_dword(xhci_pdev, USB_INTEL_USB3_PSSEN,  			cpu_to_le32(ports_available)); @@ -785,7 +795,16 @@ void usb_enable_xhci_ports(struct pci_dev *xhci_pdev)  	dev_dbg(&xhci_pdev->dev, "USB 3.0 ports that are now enabled "  			"under xHCI: 0x%x\n", ports_available); -	ports_available = 0xffffffff; +	/* Read XUSB2PRM, xHCI USB 2.0 Port Routing Mask Register +	 * Indicate the USB 2.0 ports to be controlled by the xHCI host. +	 */ + +	pci_read_config_dword(xhci_pdev, USB_INTEL_USB2PRM, +			&ports_available); + +	dev_dbg(&xhci_pdev->dev, "Configurable USB 2.0 ports to hand over to xCHI: 0x%x\n", +			ports_available); +  	/* Write XUSB2PR, the xHC USB 2.0 Port Routing Register, to  	 * switch the USB 2.0 power and data lines over to the xHCI  	 * host. @@ -822,12 +841,12 @@ static void __devinit quirk_usb_handoff_xhci(struct pci_dev *pdev)  	void __iomem *op_reg_base;  	u32 val;  	int timeout; +	int len = pci_resource_len(pdev, 0);  	if (!mmio_resource_enabled(pdev, 0))  		return; -	base = ioremap_nocache(pci_resource_start(pdev, 0), -				pci_resource_len(pdev, 0)); +	base = ioremap_nocache(pci_resource_start(pdev, 0), len);  	if (base == NULL)  		return; @@ -837,9 +856,17 @@ static void __devinit quirk_usb_handoff_xhci(struct pci_dev *pdev)  	 */  	ext_cap_offset = xhci_find_next_cap_offset(base, XHCI_HCC_PARAMS_OFFSET);  	do { +		if ((ext_cap_offset + sizeof(val)) > len) { +			/* We're reading garbage from the controller */ +			dev_warn(&pdev->dev, +				 "xHCI controller failing to respond"); +			return; +		} +  		if (!ext_cap_offset)  			/* We've reached the end of the extended capabilities */  			goto hc_init; +  		val = readl(base + ext_cap_offset);  		if (XHCI_EXT_CAPS_ID(val) == XHCI_EXT_CAPS_LEGACY)  			break; @@ -870,9 +897,10 @@ static void __devinit quirk_usb_handoff_xhci(struct pci_dev *pdev)  	/* Disable any BIOS SMIs and clear all SMI events*/  	writel(val, base + ext_cap_offset + XHCI_LEGACY_CONTROL_OFFSET); +hc_init:  	if (usb_is_intel_switchable_xhci(pdev))  		usb_enable_xhci_ports(pdev); -hc_init: +  	op_reg_base = base + XHCI_HC_LENGTH(readl(base));  	/* Wait for the host controller to be ready before writing any diff --git a/drivers/usb/host/pci-quirks.h b/drivers/usb/host/pci-quirks.h index ef004a5de20..7f69a39163c 100644 --- a/drivers/usb/host/pci-quirks.h +++ b/drivers/usb/host/pci-quirks.h @@ -15,6 +15,7 @@ void usb_disable_xhci_ports(struct pci_dev *xhci_pdev);  static inline void usb_amd_quirk_pll_disable(void) {}  static inline void usb_amd_quirk_pll_enable(void) {}  static inline void usb_amd_dev_put(void) {} +static inline void usb_disable_xhci_ports(struct pci_dev *xhci_pdev) {}  #endif  /* CONFIG_PCI */  #endif  /*  __LINUX_USB_PCI_QUIRKS_H  */ diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index 5896f0588d4..aa90ad4d4fd 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c @@ -493,11 +493,48 @@ static void xhci_hub_report_link_state(u32 *status, u32 status_reg)  		 * when this bit is set.  		 */  		pls |= USB_PORT_STAT_CONNECTION; +	} else { +		/* +		 * If CAS bit isn't set but the Port is already at +		 * Compliance Mode, fake a connection so the USB core +		 * notices the Compliance state and resets the port. +		 * This resolves an issue generated by the SN65LVPE502CP +		 * in which sometimes the port enters compliance mode +		 * caused by a delay on the host-device negotiation. +		 */ +		if (pls == USB_SS_PORT_LS_COMP_MOD) +			pls |= USB_PORT_STAT_CONNECTION;  	} +  	/* update status field */  	*status |= pls;  } +/* + * Function for Compliance Mode Quirk. + * + * This Function verifies if all xhc USB3 ports have entered U0, if so, + * the compliance mode timer is deleted. A port won't enter + * compliance mode if it has previously entered U0. + */ +void xhci_del_comp_mod_timer(struct xhci_hcd *xhci, u32 status, u16 wIndex) +{ +	u32 all_ports_seen_u0 = ((1 << xhci->num_usb3_ports)-1); +	bool port_in_u0 = ((status & PORT_PLS_MASK) == XDEV_U0); + +	if (!(xhci->quirks & XHCI_COMP_MODE_QUIRK)) +		return; + +	if ((xhci->port_status_u0 != all_ports_seen_u0) && port_in_u0) { +		xhci->port_status_u0 |= 1 << wIndex; +		if (xhci->port_status_u0 == all_ports_seen_u0) { +			del_timer_sync(&xhci->comp_mode_recovery_timer); +			xhci_dbg(xhci, "All USB3 ports have entered U0 already!\n"); +			xhci_dbg(xhci, "Compliance Mode Recovery Timer Deleted.\n"); +		} +	} +} +  int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,  		u16 wIndex, char *buf, u16 wLength)  { @@ -651,6 +688,11 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,  		/* Update Port Link State for super speed ports*/  		if (hcd->speed == HCD_USB3) {  			xhci_hub_report_link_state(&status, temp); +			/* +			 * Verify if all USB3 Ports Have entered U0 already. +			 * Delete Compliance Mode Timer if so. +			 */ +			xhci_del_comp_mod_timer(xhci, temp, wIndex);  		}  		if (bus_state->port_c_suspend & (1 << wIndex))  			status |= 1 << USB_PORT_FEAT_C_SUSPEND; diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c index 689bc18b051..df90fe51b4a 100644 --- a/drivers/usb/host/xhci-plat.c +++ b/drivers/usb/host/xhci-plat.c @@ -118,7 +118,7 @@ static int xhci_plat_probe(struct platform_device *pdev)  		goto put_hcd;  	} -	hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); +	hcd->regs = ioremap_nocache(hcd->rsrc_start, hcd->rsrc_len);  	if (!hcd->regs) {  		dev_dbg(&pdev->dev, "error mapping memory\n");  		ret = -EFAULT; diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 66bc5c3985f..a4b0ce13fa0 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -26,6 +26,7 @@  #include <linux/module.h>  #include <linux/moduleparam.h>  #include <linux/slab.h> +#include <linux/dmi.h>  #include "xhci.h" @@ -399,6 +400,95 @@ static void xhci_msix_sync_irqs(struct xhci_hcd *xhci)  #endif +static void compliance_mode_recovery(unsigned long arg) +{ +	struct xhci_hcd *xhci; +	struct usb_hcd *hcd; +	u32 temp; +	int i; + +	xhci = (struct xhci_hcd *)arg; + +	for (i = 0; i < xhci->num_usb3_ports; i++) { +		temp = xhci_readl(xhci, xhci->usb3_ports[i]); +		if ((temp & PORT_PLS_MASK) == USB_SS_PORT_LS_COMP_MOD) { +			/* +			 * Compliance Mode Detected. Letting USB Core +			 * handle the Warm Reset +			 */ +			xhci_dbg(xhci, "Compliance Mode Detected->Port %d!\n", +					i + 1); +			xhci_dbg(xhci, "Attempting Recovery routine!\n"); +			hcd = xhci->shared_hcd; + +			if (hcd->state == HC_STATE_SUSPENDED) +				usb_hcd_resume_root_hub(hcd); + +			usb_hcd_poll_rh_status(hcd); +		} +	} + +	if (xhci->port_status_u0 != ((1 << xhci->num_usb3_ports)-1)) +		mod_timer(&xhci->comp_mode_recovery_timer, +			jiffies + msecs_to_jiffies(COMP_MODE_RCVRY_MSECS)); +} + +/* + * Quirk to work around issue generated by the SN65LVPE502CP USB3.0 re-driver + * that causes ports behind that hardware to enter compliance mode sometimes. + * The quirk creates a timer that polls every 2 seconds the link state of + * each host controller's port and recovers it by issuing a Warm reset + * if Compliance mode is detected, otherwise the port will become "dead" (no + * device connections or disconnections will be detected anymore). Becasue no + * status event is generated when entering compliance mode (per xhci spec), + * this quirk is needed on systems that have the failing hardware installed. + */ +static void compliance_mode_recovery_timer_init(struct xhci_hcd *xhci) +{ +	xhci->port_status_u0 = 0; +	init_timer(&xhci->comp_mode_recovery_timer); + +	xhci->comp_mode_recovery_timer.data = (unsigned long) xhci; +	xhci->comp_mode_recovery_timer.function = compliance_mode_recovery; +	xhci->comp_mode_recovery_timer.expires = jiffies + +			msecs_to_jiffies(COMP_MODE_RCVRY_MSECS); + +	set_timer_slack(&xhci->comp_mode_recovery_timer, +			msecs_to_jiffies(COMP_MODE_RCVRY_MSECS)); +	add_timer(&xhci->comp_mode_recovery_timer); +	xhci_dbg(xhci, "Compliance Mode Recovery Timer Initialized.\n"); +} + +/* + * This function identifies the systems that have installed the SN65LVPE502CP + * USB3.0 re-driver and that need the Compliance Mode Quirk. + * Systems: + * Vendor: Hewlett-Packard -> System Models: Z420, Z620 and Z820 + */ +static bool compliance_mode_recovery_timer_quirk_check(void) +{ +	const char *dmi_product_name, *dmi_sys_vendor; + +	dmi_product_name = dmi_get_system_info(DMI_PRODUCT_NAME); +	dmi_sys_vendor = dmi_get_system_info(DMI_SYS_VENDOR); + +	if (!(strstr(dmi_sys_vendor, "Hewlett-Packard"))) +		return false; + +	if (strstr(dmi_product_name, "Z420") || +			strstr(dmi_product_name, "Z620") || +			strstr(dmi_product_name, "Z820")) +		return true; + +	return false; +} + +static int xhci_all_ports_seen_u0(struct xhci_hcd *xhci) +{ +	return (xhci->port_status_u0 == ((1 << xhci->num_usb3_ports)-1)); +} + +  /*   * Initialize memory for HCD and xHC (one-time init).   * @@ -422,6 +512,12 @@ int xhci_init(struct usb_hcd *hcd)  	retval = xhci_mem_init(xhci, GFP_KERNEL);  	xhci_dbg(xhci, "Finished xhci_init\n"); +	/* Initializing Compliance Mode Recovery Data If Needed */ +	if (compliance_mode_recovery_timer_quirk_check()) { +		xhci->quirks |= XHCI_COMP_MODE_QUIRK; +		compliance_mode_recovery_timer_init(xhci); +	} +  	return retval;  } @@ -631,6 +727,11 @@ void xhci_stop(struct usb_hcd *hcd)  	del_timer_sync(&xhci->event_ring_timer);  #endif +	/* Deleting Compliance Mode Recovery Timer */ +	if ((xhci->quirks & XHCI_COMP_MODE_QUIRK) && +			(!(xhci_all_ports_seen_u0(xhci)))) +		del_timer_sync(&xhci->comp_mode_recovery_timer); +  	if (xhci->quirks & XHCI_AMD_PLL_FIX)  		usb_amd_dev_put(); @@ -661,7 +762,7 @@ void xhci_shutdown(struct usb_hcd *hcd)  {  	struct xhci_hcd *xhci = hcd_to_xhci(hcd); -	if (xhci->quirks && XHCI_SPURIOUS_REBOOT) +	if (xhci->quirks & XHCI_SPURIOUS_REBOOT)  		usb_disable_xhci_ports(to_pci_dev(hcd->self.controller));  	spin_lock_irq(&xhci->lock); @@ -808,6 +909,16 @@ int xhci_suspend(struct xhci_hcd *xhci)  	}  	spin_unlock_irq(&xhci->lock); +	/* +	 * Deleting Compliance Mode Recovery Timer because the xHCI Host +	 * is about to be suspended. +	 */ +	if ((xhci->quirks & XHCI_COMP_MODE_QUIRK) && +			(!(xhci_all_ports_seen_u0(xhci)))) { +		del_timer_sync(&xhci->comp_mode_recovery_timer); +		xhci_dbg(xhci, "Compliance Mode Recovery Timer Deleted!\n"); +	} +  	/* step 5: remove core well power */  	/* synchronize irq when using MSI-X */  	xhci_msix_sync_irqs(xhci); @@ -940,6 +1051,16 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)  		usb_hcd_resume_root_hub(hcd);  		usb_hcd_resume_root_hub(xhci->shared_hcd);  	} + +	/* +	 * If system is subject to the Quirk, Compliance Mode Timer needs to +	 * be re-initialized Always after a system resume. Ports are subject +	 * to suffer the Compliance Mode issue again. It doesn't matter if +	 * ports have entered previously to U0 before system's suspension. +	 */ +	if (xhci->quirks & XHCI_COMP_MODE_QUIRK) +		compliance_mode_recovery_timer_init(xhci); +  	return retval;  }  #endif	/* CONFIG_PM */ diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index e81ccfa3552..e44e2d3c83b 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1510,6 +1510,7 @@ struct xhci_hcd {  #define XHCI_LPM_SUPPORT	(1 << 11)  #define XHCI_INTEL_HOST		(1 << 12)  #define XHCI_SPURIOUS_REBOOT	(1 << 13) +#define XHCI_COMP_MODE_QUIRK	(1 << 14)  	unsigned int		num_active_eps;  	unsigned int		limit_active_eps;  	/* There are two roothubs to keep track of bus suspend info for */ @@ -1526,6 +1527,11 @@ struct xhci_hcd {  	unsigned		sw_lpm_support:1;  	/* support xHCI 1.0 spec USB2 hardware LPM */  	unsigned		hw_lpm_support:1; +	/* Compliance Mode Recovery Data */ +	struct timer_list	comp_mode_recovery_timer; +	u32			port_status_u0; +/* Compliance Mode Timer Triggered every 2 seconds */ +#define COMP_MODE_RCVRY_MSECS 2000  };  /* convert between an HCD pointer and the corresponding EHCI_HCD */ diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index d385e8a8187..3df6a76b851 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c @@ -2177,7 +2177,7 @@ static int musb_urb_enqueue(  	 * we only have work to do in the former case.  	 */  	spin_lock_irqsave(&musb->lock, flags); -	if (hep->hcpriv) { +	if (hep->hcpriv || !next_urb(qh)) {  		/* some concurrent activity submitted another urb to hep...  		 * odd, rare, error prone, but legal.  		 */ diff --git a/drivers/usb/musb/musbhsdma.c b/drivers/usb/musb/musbhsdma.c index 444b9ee0649..0fc6ca6bc60 100644 --- a/drivers/usb/musb/musbhsdma.c +++ b/drivers/usb/musb/musbhsdma.c @@ -388,7 +388,7 @@ dma_controller_create(struct musb *musb, void __iomem *base)  	struct platform_device *pdev = to_platform_device(dev);  	int irq = platform_get_irq_byname(pdev, "dma"); -	if (irq == 0) { +	if (irq <= 0) {  		dev_err(dev, "No DMA interrupt line!\n");  		return NULL;  	} diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 6d77d2cb938..dcc05fdb01b 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -703,6 +703,7 @@ static struct usb_device_id id_table_combined [] = {  	{ USB_DEVICE(FTDI_VID, FTDI_PCDJ_DAC2_PID) },  	{ USB_DEVICE(FTDI_VID, FTDI_RRCIRKITS_LOCOBUFFER_PID) },  	{ USB_DEVICE(FTDI_VID, FTDI_ASK_RDR400_PID) }, +	{ USB_DEVICE(FTDI_VID, FTDI_NZR_SEM_USB_PID) },  	{ USB_DEVICE(ICOM_VID, ICOM_ID_1_PID) },  	{ USB_DEVICE(ICOM_VID, ICOM_OPC_U_UC_PID) },  	{ USB_DEVICE(ICOM_VID, ICOM_ID_RP2C1_PID) }, @@ -803,13 +804,32 @@ static struct usb_device_id id_table_combined [] = {  		.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },  	{ USB_DEVICE(ADI_VID, ADI_GNICEPLUS_PID),  		.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, -	{ USB_DEVICE(MICROCHIP_VID, MICROCHIP_USB_BOARD_PID) }, +	{ USB_DEVICE_AND_INTERFACE_INFO(MICROCHIP_VID, MICROCHIP_USB_BOARD_PID, +					USB_CLASS_VENDOR_SPEC, +					USB_SUBCLASS_VENDOR_SPEC, 0x00) },  	{ USB_DEVICE(JETI_VID, JETI_SPC1201_PID) },  	{ USB_DEVICE(MARVELL_VID, MARVELL_SHEEVAPLUG_PID),  		.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },  	{ USB_DEVICE(LARSENBRUSGAARD_VID, LB_ALTITRACK_PID) },  	{ USB_DEVICE(GN_OTOMETRICS_VID, AURICAL_USB_PID) }, +	{ USB_DEVICE(FTDI_VID, PI_C865_PID) }, +	{ USB_DEVICE(FTDI_VID, PI_C857_PID) }, +	{ USB_DEVICE(PI_VID, PI_C866_PID) }, +	{ USB_DEVICE(PI_VID, PI_C663_PID) }, +	{ USB_DEVICE(PI_VID, PI_C725_PID) }, +	{ USB_DEVICE(PI_VID, PI_E517_PID) }, +	{ USB_DEVICE(PI_VID, PI_C863_PID) },  	{ USB_DEVICE(PI_VID, PI_E861_PID) }, +	{ USB_DEVICE(PI_VID, PI_C867_PID) }, +	{ USB_DEVICE(PI_VID, PI_E609_PID) }, +	{ USB_DEVICE(PI_VID, PI_E709_PID) }, +	{ USB_DEVICE(PI_VID, PI_100F_PID) }, +	{ USB_DEVICE(PI_VID, PI_1011_PID) }, +	{ USB_DEVICE(PI_VID, PI_1012_PID) }, +	{ USB_DEVICE(PI_VID, PI_1013_PID) }, +	{ USB_DEVICE(PI_VID, PI_1014_PID) }, +	{ USB_DEVICE(PI_VID, PI_1015_PID) }, +	{ USB_DEVICE(PI_VID, PI_1016_PID) },  	{ USB_DEVICE(KONDO_VID, KONDO_USB_SERIAL_PID) },  	{ USB_DEVICE(BAYER_VID, BAYER_CONTOUR_CABLE_PID) },  	{ USB_DEVICE(FTDI_VID, MARVELL_OPENRD_PID), diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h index 5dd96ca6c38..41fe5826100 100644 --- a/drivers/usb/serial/ftdi_sio_ids.h +++ b/drivers/usb/serial/ftdi_sio_ids.h @@ -75,6 +75,9 @@  #define FTDI_OPENDCC_GATEWAY_PID	0xBFDB  #define FTDI_OPENDCC_GBM_PID	0xBFDC +/* NZR SEM 16+ USB (http://www.nzr.de) */ +#define FTDI_NZR_SEM_USB_PID	0xC1E0	/* NZR SEM-LOG16+ */ +  /*   * RR-CirKits LocoBuffer USB (http://www.rr-cirkits.com)   */ @@ -539,7 +542,10 @@  /*   * Microchip Technology, Inc.   * - * MICROCHIP_VID (0x04D8) and MICROCHIP_USB_BOARD_PID (0x000A) are also used by: + * MICROCHIP_VID (0x04D8) and MICROCHIP_USB_BOARD_PID (0x000A) are + * used by single function CDC ACM class based firmware demo + * applications.  The VID/PID has also been used in firmware + * emulating FTDI serial chips by:   * Hornby Elite - Digital Command Control Console   * http://www.hornby.com/hornby-dcc/controllers/   */ @@ -791,8 +797,27 @@   * Physik Instrumente   * http://www.physikinstrumente.com/en/products/   */ +/* These two devices use the VID of FTDI */ +#define PI_C865_PID	0xe0a0  /* PI C-865 Piezomotor Controller */ +#define PI_C857_PID	0xe0a1  /* PI Encoder Trigger Box */ +  #define PI_VID              0x1a72  /* Vendor ID */ -#define PI_E861_PID         0x1008  /* E-861 piezo controller USB connection */ +#define PI_C866_PID	0x1000  /* PI C-866 Piezomotor Controller */ +#define PI_C663_PID	0x1001  /* PI C-663 Mercury-Step */ +#define PI_C725_PID	0x1002  /* PI C-725 Piezomotor Controller */ +#define PI_E517_PID	0x1005  /* PI E-517 Digital Piezo Controller Operation Module */ +#define PI_C863_PID	0x1007  /* PI C-863 */ +#define PI_E861_PID	0x1008  /* PI E-861 Piezomotor Controller */ +#define PI_C867_PID	0x1009  /* PI C-867 Piezomotor Controller */ +#define PI_E609_PID	0x100D  /* PI E-609 Digital Piezo Controller */ +#define PI_E709_PID	0x100E  /* PI E-709 Digital Piezo Controller */ +#define PI_100F_PID	0x100F  /* PI Digital Piezo Controller */ +#define PI_1011_PID	0x1011  /* PI Digital Piezo Controller */ +#define PI_1012_PID	0x1012  /* PI Motion Controller */ +#define PI_1013_PID	0x1013  /* PI Motion Controller */ +#define PI_1014_PID	0x1014  /* PI Device */ +#define PI_1015_PID	0x1015  /* PI Device */ +#define PI_1016_PID	0x1016  /* PI Digital Servo Module */  /*   * Kondo Kagaku Co.Ltd. diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 3229368eaab..53bd5f491c5 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -886,8 +886,6 @@ static const struct usb_device_id option_ids[] = {  	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1010, 0xff, 0xff, 0xff),  	  .driver_info = (kernel_ulong_t)&net_intf4_blacklist },  	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1012, 0xff, 0xff, 0xff) }, -	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1018, 0xff, 0xff, 0xff), -	  .driver_info = (kernel_ulong_t)&net_intf3_blacklist },  	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1057, 0xff, 0xff, 0xff) },  	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1058, 0xff, 0xff, 0xff) },  	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1059, 0xff, 0xff, 0xff) }, @@ -1092,6 +1090,10 @@ static const struct usb_device_id option_ids[] = {  	 .driver_info = (kernel_ulong_t)&zte_ad3812_z_blacklist },  	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MC2716, 0xff, 0xff, 0xff),  	 .driver_info = (kernel_ulong_t)&zte_mc2716_z_blacklist }, +	{ USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff, 0x02, 0x01) }, +	{ USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff, 0x02, 0x05) }, +	{ USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff, 0x86, 0x10) }, +  	{ USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) },  	{ USB_DEVICE(DLINK_VENDOR_ID, DLINK_PRODUCT_DWM_652) },  	{ USB_DEVICE(ALINK_VENDOR_ID, DLINK_PRODUCT_DWM_652_U5) }, /* Yes, ALINK_VENDOR_ID */ diff --git a/drivers/video/auo_k190x.c b/drivers/video/auo_k190x.c index 77da6a2f43d..c03ecdd31e4 100644 --- a/drivers/video/auo_k190x.c +++ b/drivers/video/auo_k190x.c @@ -987,7 +987,6 @@ err_regfb:  	fb_dealloc_cmap(&info->cmap);  err_cmap:  	fb_deferred_io_cleanup(info); -	kfree(info->fbdefio);  err_defio:  	vfree((void *)info->screen_base);  err_irq: @@ -1022,7 +1021,6 @@ int  __devexit auok190x_common_remove(struct platform_device *pdev)  	fb_dealloc_cmap(&info->cmap);  	fb_deferred_io_cleanup(info); -	kfree(info->fbdefio);  	vfree((void *)info->screen_base); diff --git a/drivers/video/console/bitblit.c b/drivers/video/console/bitblit.c index 28b1a834906..61b182bf32a 100644 --- a/drivers/video/console/bitblit.c +++ b/drivers/video/console/bitblit.c @@ -162,7 +162,7 @@ static void bit_putcs(struct vc_data *vc, struct fb_info *info,  	image.depth = 1;  	if (attribute) { -		buf = kmalloc(cellsize, GFP_KERNEL); +		buf = kmalloc(cellsize, GFP_ATOMIC);  		if (!buf)  			return;  	} diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index 88e92041d8f..fdefa8fd72c 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c @@ -449,7 +449,7 @@ static int __init fb_console_setup(char *this_opt)  	while ((options = strsep(&this_opt, ",")) != NULL) {  		if (!strncmp(options, "font:", 5)) -			strcpy(fontname, options + 5); +			strlcpy(fontname, options + 5, sizeof(fontname));  		if (!strncmp(options, "scrollback:", 11)) {  			options += 11; diff --git a/drivers/video/mb862xx/mb862xxfbdrv.c b/drivers/video/mb862xx/mb862xxfbdrv.c index 00ce1f34b49..57d940be5f3 100644 --- a/drivers/video/mb862xx/mb862xxfbdrv.c +++ b/drivers/video/mb862xx/mb862xxfbdrv.c @@ -328,6 +328,8 @@ static int mb862xxfb_ioctl(struct fb_info *fbi, unsigned int cmd,  	case MB862XX_L1_SET_CFG:  		if (copy_from_user(l1_cfg, argp, sizeof(*l1_cfg)))  			return -EFAULT; +		if (l1_cfg->dh == 0 || l1_cfg->dw == 0) +			return -EINVAL;  		if ((l1_cfg->sw >= l1_cfg->dw) && (l1_cfg->sh >= l1_cfg->dh)) {  			/* downscaling */  			outreg(cap, GC_CAP_CSC, diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c index 5d31699fbd3..f43bfe17b3b 100644 --- a/drivers/video/omap2/dss/sdi.c +++ b/drivers/video/omap2/dss/sdi.c @@ -105,6 +105,20 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)  	sdi_config_lcd_manager(dssdev); +	/* +	 * LCLK and PCLK divisors are located in shadow registers, and we +	 * normally write them to DISPC registers when enabling the output. +	 * However, SDI uses pck-free as source clock for its PLL, and pck-free +	 * is affected by the divisors. And as we need the PLL before enabling +	 * the output, we need to write the divisors early. +	 * +	 * It seems just writing to the DISPC register is enough, and we don't +	 * need to care about the shadow register mechanism for pck-free. The +	 * exact reason for this is unknown. +	 */ +	dispc_mgr_set_clock_div(dssdev->manager->id, +			&sdi.mgr_config.clock_info); +  	dss_sdi_init(dssdev->phy.sdi.datapairs);  	r = dss_sdi_enable();  	if (r) diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c index 08ec1a7103f..fc671d3d800 100644 --- a/drivers/video/omap2/omapfb/omapfb-main.c +++ b/drivers/video/omap2/omapfb/omapfb-main.c @@ -1192,7 +1192,7 @@ static int _setcolreg(struct fb_info *fbi, u_int regno, u_int red, u_int green,  			break;  		if (regno < 16) { -			u16 pal; +			u32 pal;  			pal = ((red >> (16 - var->red.length)) <<  					var->red.offset) |  				((green >> (16 - var->green.length)) << diff --git a/drivers/watchdog/booke_wdt.c b/drivers/watchdog/booke_wdt.c index 3fe82d0e8ca..5b06d31ab6a 100644 --- a/drivers/watchdog/booke_wdt.c +++ b/drivers/watchdog/booke_wdt.c @@ -166,18 +166,17 @@ static long booke_wdt_ioctl(struct file *file,  	switch (cmd) {  	case WDIOC_GETSUPPORT: -		if (copy_to_user((void *)arg, &ident, sizeof(ident))) -			return -EFAULT; +		return copy_to_user(p, &ident, sizeof(ident)) ? -EFAULT : 0;  	case WDIOC_GETSTATUS:  		return put_user(0, p);  	case WDIOC_GETBOOTSTATUS:  		/* XXX: something is clearing TSR */  		tmp = mfspr(SPRN_TSR) & TSR_WRS(3);  		/* returns CARDRESET if last reset was caused by the WDT */ -		return (tmp ? WDIOF_CARDRESET : 0); +		return put_user((tmp ? WDIOF_CARDRESET : 0), p);  	case WDIOC_SETOPTIONS:  		if (get_user(tmp, p)) -			return -EINVAL; +			return -EFAULT;  		if (tmp == WDIOS_ENABLECARD) {  			booke_wdt_ping();  			break; diff --git a/drivers/watchdog/da9052_wdt.c b/drivers/watchdog/da9052_wdt.c index 3f75129eb0a..f7abbaeebca 100644 --- a/drivers/watchdog/da9052_wdt.c +++ b/drivers/watchdog/da9052_wdt.c @@ -21,7 +21,6 @@  #include <linux/types.h>  #include <linux/kernel.h>  #include <linux/jiffies.h> -#include <linux/delay.h>  #include <linux/mfd/da9052/reg.h>  #include <linux/mfd/da9052/da9052.h> diff --git a/drivers/xen/platform-pci.c b/drivers/xen/platform-pci.c index d4c50d63acb..97ca359ae2b 100644 --- a/drivers/xen/platform-pci.c +++ b/drivers/xen/platform-pci.c @@ -101,19 +101,6 @@ static int platform_pci_resume(struct pci_dev *pdev)  	return 0;  } -static void __devinit prepare_shared_info(void) -{ -#ifdef CONFIG_KEXEC -	unsigned long addr; -	struct shared_info *hvm_shared_info; - -	addr = alloc_xen_mmio(PAGE_SIZE); -	hvm_shared_info = ioremap(addr, PAGE_SIZE); -	memset(hvm_shared_info, 0, PAGE_SIZE); -	xen_hvm_prepare_kexec(hvm_shared_info, addr >> PAGE_SHIFT); -#endif -} -  static int __devinit platform_pci_init(struct pci_dev *pdev,  				       const struct pci_device_id *ent)  { @@ -151,8 +138,6 @@ static int __devinit platform_pci_init(struct pci_dev *pdev,  	platform_mmio = mmio_addr;  	platform_mmiolen = mmio_len; -	prepare_shared_info(); -  	if (!xen_have_vector_callback) {  		ret = xen_allocate_irq(pdev);  		if (ret) { diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c index 1afb4fba11b..4d519488d30 100644 --- a/drivers/xen/swiotlb-xen.c +++ b/drivers/xen/swiotlb-xen.c @@ -232,7 +232,7 @@ xen_swiotlb_alloc_coherent(struct device *hwdev, size_t size,  		return ret;  	if (hwdev && hwdev->coherent_dma_mask) -		dma_mask = hwdev->coherent_dma_mask; +		dma_mask = dma_alloc_coherent_mask(hwdev, flags);  	phys = virt_to_phys(ret);  	dev_addr = xen_phys_to_bus(phys); diff --git a/drivers/xen/xen-pciback/pci_stub.c b/drivers/xen/xen-pciback/pci_stub.c index 097e536e867..03342728bf2 100644 --- a/drivers/xen/xen-pciback/pci_stub.c +++ b/drivers/xen/xen-pciback/pci_stub.c @@ -353,16 +353,16 @@ static int __devinit pcistub_init_device(struct pci_dev *dev)  	if (err)  		goto config_release; -	dev_dbg(&dev->dev, "reseting (FLR, D3, etc) the device\n"); -	__pci_reset_function_locked(dev); -  	/* We need the device active to save the state. */  	dev_dbg(&dev->dev, "save state of device\n");  	pci_save_state(dev);  	dev_data->pci_saved_state = pci_store_saved_state(dev);  	if (!dev_data->pci_saved_state)  		dev_err(&dev->dev, "Could not store PCI conf saved state!\n"); - +	else { +		dev_dbg(&dev->dev, "reseting (FLR, D3, etc) the device\n"); +		__pci_reset_function_locked(dev); +	}  	/* Now disable the device (this also ensures some private device  	 * data is setup before we export)  	 */  |