diff options
Diffstat (limited to 'drivers')
266 files changed, 2554 insertions, 2032 deletions
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index 73b2909dddf..0e8e2de2ed3 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -224,7 +224,6 @@ static void lapic_timer_state_broadcast(struct acpi_processor *pr,  /*   * Suspend / resume control   */ -static int acpi_idle_suspend;  static u32 saved_bm_rld;  static void acpi_idle_bm_rld_save(void) @@ -243,21 +242,13 @@ static void acpi_idle_bm_rld_restore(void)  int acpi_processor_suspend(struct acpi_device * device, pm_message_t state)  { -	if (acpi_idle_suspend == 1) -		return 0; -  	acpi_idle_bm_rld_save(); -	acpi_idle_suspend = 1;  	return 0;  }  int acpi_processor_resume(struct acpi_device * device)  { -	if (acpi_idle_suspend == 0) -		return 0; -  	acpi_idle_bm_rld_restore(); -	acpi_idle_suspend = 0;  	return 0;  } @@ -763,13 +754,6 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev,  	local_irq_disable(); -	/* Do not access any ACPI IO ports in suspend path */ -	if (acpi_idle_suspend) { -		local_irq_enable(); -		cpu_relax(); -		return -EINVAL; -	} -  	lapic_timer_state_broadcast(pr, cx, 1);  	kt1 = ktime_get_real();  	acpi_idle_do_entry(cx); @@ -810,13 +794,6 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,  	local_irq_disable(); -	if (acpi_idle_suspend) { -		local_irq_enable(); -		cpu_relax(); -		return -EINVAL; -	} - -  	if (cx->entry_method != ACPI_CSTATE_FFH) {  		current_thread_info()->status &= ~TS_POLLING;  		/* @@ -895,12 +872,6 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,  	if (unlikely(!pr))  		return -EINVAL; - -	if (acpi_idle_suspend) { -		cpu_relax(); -		return -EINVAL; -	} -  	if (!cx->bm_sts_skip && acpi_idle_bm_check()) {  		if (drv->safe_state_index >= 0) {  			return drv->states[drv->safe_state_index].enter(dev, diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index fb7b90b0592..cf26222a93c 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -390,6 +390,9 @@ static const struct pci_device_id ahci_pci_tbl[] = {  	/* Promise */  	{ PCI_VDEVICE(PROMISE, 0x3f20), board_ahci },	/* PDC42819 */ +	/* Asmedia */ +	{ PCI_VDEVICE(ASMEDIA, 0x0612), board_ahci },	/* ASM1061 */ +  	/* Generic, PCI class code for AHCI */  	{ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,  	  PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff, board_ahci }, diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c index 004f2ce3dc7..43b875810d1 100644 --- a/drivers/ata/ahci_platform.c +++ b/drivers/ata/ahci_platform.c @@ -65,9 +65,9 @@ static struct scsi_host_template ahci_platform_sht = {  static int __init ahci_probe(struct platform_device *pdev)  {  	struct device *dev = &pdev->dev; -	struct ahci_platform_data *pdata = dev->platform_data; +	struct ahci_platform_data *pdata = dev_get_platdata(dev);  	const struct platform_device_id *id = platform_get_device_id(pdev); -	struct ata_port_info pi = ahci_port_info[id->driver_data]; +	struct ata_port_info pi = ahci_port_info[id ? id->driver_data : 0];  	const struct ata_port_info *ppi[] = { &pi, NULL };  	struct ahci_host_priv *hpriv;  	struct ata_host *host; @@ -191,7 +191,7 @@ err0:  static int __devexit ahci_remove(struct platform_device *pdev)  {  	struct device *dev = &pdev->dev; -	struct ahci_platform_data *pdata = dev->platform_data; +	struct ahci_platform_data *pdata = dev_get_platdata(dev);  	struct ata_host *host = dev_get_drvdata(dev);  	ata_host_detach(host); diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index f22957c2769..a9b28203800 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -2883,7 +2883,7 @@ int ata_eh_reset(struct ata_link *link, int classify,  	    sata_scr_read(link, SCR_STATUS, &sstatus))  		rc = -ERESTART; -	if (rc == -ERESTART || try >= max_tries) { +	if (try >= max_tries) {  		/*  		 * Thaw host port even if reset failed, so that the port  		 * can be retried on the next phy event.  This risks @@ -2909,6 +2909,16 @@ int ata_eh_reset(struct ata_link *link, int classify,  		ata_eh_acquire(ap);  	} +	/* +	 * While disks spinup behind PMP, some controllers fail sending SRST. +	 * They need to be reset - as well as the PMP - before retrying. +	 */ +	if (rc == -ERESTART) { +		if (ata_is_host_link(link)) +			ata_eh_thaw_port(ap); +		goto out; +	} +  	if (try == max_tries - 1) {  		sata_down_spd_limit(link, 0);  		if (slave) diff --git a/drivers/ata/libata-pmp.c b/drivers/ata/libata-pmp.c index 104462dbc52..21b80c555c6 100644 --- a/drivers/ata/libata-pmp.c +++ b/drivers/ata/libata-pmp.c @@ -389,12 +389,9 @@ static void sata_pmp_quirks(struct ata_port *ap)  			/* link reports offline after LPM */  			link->flags |= ATA_LFLAG_NO_LPM; -			/* Class code report is unreliable and SRST -			 * times out under certain configurations. -			 */ +			/* Class code report is unreliable. */  			if (link->pmp < 5) -				link->flags |= ATA_LFLAG_NO_SRST | -					       ATA_LFLAG_ASSUME_ATA; +				link->flags |= ATA_LFLAG_ASSUME_ATA;  			/* port 5 is for SEMB device and it doesn't like SRST */  			if (link->pmp == 5) diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 72a9770ac42..2a5412e7e9c 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -1217,6 +1217,10 @@ void ata_scsi_slave_destroy(struct scsi_device *sdev)  /**   *	__ata_change_queue_depth - helper for ata_scsi_change_queue_depth + *	@ap: ATA port to which the device change the queue depth + *	@sdev: SCSI device to configure queue depth for + *	@queue_depth: new queue depth + *	@reason: calling context   *   *	libsas and libata have different approaches for associating a sdev to   *	its ata_port. diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index 63d53277d6a..4cadfa28f94 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c @@ -2533,10 +2533,12 @@ static int ata_pci_init_one(struct pci_dev *pdev,  	if (rc)  		goto out; +#ifdef CONFIG_ATA_BMDMA  	if (bmdma)  		/* prepare and activate BMDMA host */  		rc = ata_pci_bmdma_prepare_host(pdev, ppi, &host);  	else +#endif  		/* prepare and activate SFF host */  		rc = ata_pci_sff_prepare_host(pdev, ppi, &host);  	if (rc) @@ -2544,10 +2546,12 @@ static int ata_pci_init_one(struct pci_dev *pdev,  	host->private_data = host_priv;  	host->flags |= hflags; +#ifdef CONFIG_ATA_BMDMA  	if (bmdma) {  		pci_set_master(pdev);  		rc = ata_pci_sff_activate_host(host, ata_bmdma_interrupt, sht);  	} else +#endif  		rc = ata_pci_sff_activate_host(host, ata_sff_interrupt, sht);  out:  	if (rc == 0) diff --git a/drivers/ata/pata_of_platform.c b/drivers/ata/pata_of_platform.c index a72ab0dde4e..2a472c5bb7d 100644 --- a/drivers/ata/pata_of_platform.c +++ b/drivers/ata/pata_of_platform.c @@ -52,7 +52,7 @@ static int __devinit pata_of_platform_probe(struct platform_device *ofdev)  	}  	ret = of_irq_to_resource(dn, 0, &irq_res); -	if (ret == NO_IRQ) +	if (!ret)  		irq_res.start = irq_res.end = 0;  	else  		irq_res.flags = 0; diff --git a/drivers/ata/sata_sis.c b/drivers/ata/sata_sis.c index 447d9c05fb5..95ec435f0eb 100644 --- a/drivers/ata/sata_sis.c +++ b/drivers/ata/sata_sis.c @@ -104,7 +104,7 @@ static const struct ata_port_info sis_port_info = {  };  MODULE_AUTHOR("Uwe Koziolek"); -MODULE_DESCRIPTION("low-level driver for Silicon Integratad Systems SATA controller"); +MODULE_DESCRIPTION("low-level driver for Silicon Integrated Systems SATA controller");  MODULE_LICENSE("GPL");  MODULE_DEVICE_TABLE(pci, sis_pci_tbl);  MODULE_VERSION(DRV_VERSION); diff --git a/drivers/base/core.c b/drivers/base/core.c index 82c865452c7..d8b3d89db04 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -22,6 +22,7 @@  #include <linux/kallsyms.h>  #include <linux/mutex.h>  #include <linux/async.h> +#include <linux/pm_runtime.h>  #include "base.h"  #include "power/power.h" @@ -1742,6 +1743,8 @@ void device_shutdown(void)  		 */  		list_del_init(&dev->kobj.entry);  		spin_unlock(&devices_kset->list_lock); +		/* Disable all device's runtime power management */ +		pm_runtime_disable(dev);  		if (dev->bus && dev->bus->shutdown) {  			dev_dbg(dev, "shutdown\n"); diff --git a/drivers/base/node.c b/drivers/base/node.c index 793f796c4da..5693ecee9a4 100644 --- a/drivers/base/node.c +++ b/drivers/base/node.c @@ -127,12 +127,13 @@ static ssize_t node_read_meminfo(struct sys_device * dev,  		       nid, K(node_page_state(nid, NR_WRITEBACK)),  		       nid, K(node_page_state(nid, NR_FILE_PAGES)),  		       nid, K(node_page_state(nid, NR_FILE_MAPPED)), -		       nid, K(node_page_state(nid, NR_ANON_PAGES)  #ifdef CONFIG_TRANSPARENT_HUGEPAGE +		       nid, K(node_page_state(nid, NR_ANON_PAGES)  			+ node_page_state(nid, NR_ANON_TRANSPARENT_HUGEPAGES) * -			HPAGE_PMD_NR +			HPAGE_PMD_NR), +#else +		       nid, K(node_page_state(nid, NR_ANON_PAGES)),  #endif -		       ),  		       nid, K(node_page_state(nid, NR_SHMEM)),  		       nid, node_page_state(nid, NR_KERNEL_STACK) *  				THREAD_SIZE / 1024, @@ -143,13 +144,14 @@ static ssize_t node_read_meminfo(struct sys_device * dev,  		       nid, K(node_page_state(nid, NR_SLAB_RECLAIMABLE) +  				node_page_state(nid, NR_SLAB_UNRECLAIMABLE)),  		       nid, K(node_page_state(nid, NR_SLAB_RECLAIMABLE)), -		       nid, K(node_page_state(nid, NR_SLAB_UNRECLAIMABLE))  #ifdef CONFIG_TRANSPARENT_HUGEPAGE +		       nid, K(node_page_state(nid, NR_SLAB_UNRECLAIMABLE))  			, nid,  			K(node_page_state(nid, NR_ANON_TRANSPARENT_HUGEPAGES) * -			HPAGE_PMD_NR) +			HPAGE_PMD_NR)); +#else +		       nid, K(node_page_state(nid, NR_SLAB_UNRECLAIMABLE)));  #endif -		       );  	n += hugetlb_report_node_meminfo(nid, buf + n);  	return n;  } diff --git a/drivers/base/power/clock_ops.c b/drivers/base/power/clock_ops.c index 5f0f85d5c57..428e55e012d 100644 --- a/drivers/base/power/clock_ops.c +++ b/drivers/base/power/clock_ops.c @@ -229,7 +229,8 @@ int pm_clk_suspend(struct device *dev)  	list_for_each_entry_reverse(ce, &psd->clock_list, node) {  		if (ce->status < PCE_STATUS_ERROR) { -			clk_disable(ce->clk); +			if (ce->status == PCE_STATUS_ENABLED) +				clk_disable(ce->clk);  			ce->status = PCE_STATUS_ACQUIRED;  		}  	} diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index 7fa098464da..c3d2dfcf438 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -920,7 +920,8 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async)   End:  	if (!error) {  		dev->power.is_suspended = true; -		if (dev->power.wakeup_path && dev->parent) +		if (dev->power.wakeup_path +		    && dev->parent && !dev->parent->power.ignore_children)  			dev->parent->power.wakeup_path = true;  	} diff --git a/drivers/base/power/opp.c b/drivers/base/power/opp.c index 434a6c01167..95706fa24c7 100644 --- a/drivers/base/power/opp.c +++ b/drivers/base/power/opp.c @@ -669,7 +669,7 @@ struct srcu_notifier_head *opp_get_notifier(struct device *dev)  	struct device_opp *dev_opp = find_device_opp(dev);  	if (IS_ERR(dev_opp)) -		return ERR_PTR(PTR_ERR(dev_opp)); /* matching type */ +		return ERR_CAST(dev_opp); /* matching type */  	return &dev_opp->head;  } diff --git a/drivers/base/power/qos.c b/drivers/base/power/qos.c index 30a94eadc20..86de6c50fc4 100644 --- a/drivers/base/power/qos.c +++ b/drivers/base/power/qos.c @@ -212,11 +212,9 @@ int dev_pm_qos_add_request(struct device *dev, struct dev_pm_qos_request *req,  	if (!dev || !req) /*guard against callers passing in null */  		return -EINVAL; -	if (dev_pm_qos_request_active(req)) { -		WARN(1, KERN_ERR "dev_pm_qos_add_request() called for already " -			"added request\n"); +	if (WARN(dev_pm_qos_request_active(req), +		 "%s() called for already added request\n", __func__))  		return -EINVAL; -	}  	req->dev = dev; @@ -271,11 +269,9 @@ int dev_pm_qos_update_request(struct dev_pm_qos_request *req,  	if (!req) /*guard against callers passing in null */  		return -EINVAL; -	if (!dev_pm_qos_request_active(req)) { -		WARN(1, KERN_ERR "dev_pm_qos_update_request() called for " -			"unknown object\n"); +	if (WARN(!dev_pm_qos_request_active(req), +		 "%s() called for unknown object\n", __func__))  		return -EINVAL; -	}  	mutex_lock(&dev_pm_qos_mtx); @@ -312,11 +308,9 @@ int dev_pm_qos_remove_request(struct dev_pm_qos_request *req)  	if (!req) /*guard against callers passing in null */  		return -EINVAL; -	if (!dev_pm_qos_request_active(req)) { -		WARN(1, KERN_ERR "dev_pm_qos_remove_request() called for " -			"unknown object\n"); +	if (WARN(!dev_pm_qos_request_active(req), +		 "%s() called for unknown object\n", __func__))  		return -EINVAL; -	}  	mutex_lock(&dev_pm_qos_mtx); diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 486f94ef24d..8004ac30a7a 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -24,6 +24,7 @@  #include <linux/interrupt.h>  #include <linux/types.h>  #include <linux/pci.h> +#include <linux/pci-aspm.h>  #include <linux/kernel.h>  #include <linux/slab.h>  #include <linux/delay.h> @@ -4319,6 +4320,10 @@ static int __devinit cciss_pci_init(ctlr_info_t *h)  		dev_warn(&h->pdev->dev, "controller appears to be disabled\n");  		return -ENODEV;  	} + +	pci_disable_link_state(h->pdev, PCIE_LINK_STATE_L0S | +				PCIE_LINK_STATE_L1 | PCIE_LINK_STATE_CLKPM); +  	err = pci_enable_device(h->pdev);  	if (err) {  		dev_warn(&h->pdev->dev, "Unable to Enable PCI device\n"); @@ -5158,6 +5163,7 @@ reinit_after_soft_reset:  	h->cciss_max_sectors = 8192;  	rebuild_lun_table(h, 1, 0); +	cciss_engage_scsi(h);  	h->busy_initializing = 0;  	return 1; diff --git a/drivers/block/cciss_scsi.c b/drivers/block/cciss_scsi.c index 951a4e33b92..e820b68d2f6 100644 --- a/drivers/block/cciss_scsi.c +++ b/drivers/block/cciss_scsi.c @@ -1720,5 +1720,6 @@ static int  cciss_eh_abort_handler(struct scsi_cmnd *scsicmd)  /* If no tape support, then these become defined out of existence */  #define cciss_scsi_setup(cntl_num) +#define cciss_engage_scsi(h)  #endif /* CONFIG_CISS_SCSI_TAPE */ diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 3d806820280..68b205a9338 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -161,17 +161,19 @@ static struct loop_func_table *xfer_funcs[MAX_LO_CRYPT] = {  	&xor_funcs  }; -static loff_t get_loop_size(struct loop_device *lo, struct file *file) +static loff_t get_size(loff_t offset, loff_t sizelimit, struct file *file)  { -	loff_t size, offset, loopsize; +	loff_t size, loopsize;  	/* Compute loopsize in bytes */  	size = i_size_read(file->f_mapping->host); -	offset = lo->lo_offset;  	loopsize = size - offset; -	if (lo->lo_sizelimit > 0 && lo->lo_sizelimit < loopsize) -		loopsize = lo->lo_sizelimit; +	/* offset is beyond i_size, wierd but possible */ +	if (loopsize < 0) +		return 0; +	if (sizelimit > 0 && sizelimit < loopsize) +		loopsize = sizelimit;  	/*  	 * Unfortunately, if we want to do I/O on the device,  	 * the number of 512-byte sectors has to fit into a sector_t. @@ -179,17 +181,25 @@ static loff_t get_loop_size(struct loop_device *lo, struct file *file)  	return loopsize >> 9;  } +static loff_t get_loop_size(struct loop_device *lo, struct file *file) +{ +	return get_size(lo->lo_offset, lo->lo_sizelimit, file); +} +  static int -figure_loop_size(struct loop_device *lo) +figure_loop_size(struct loop_device *lo, loff_t offset, loff_t sizelimit)  { -	loff_t size = get_loop_size(lo, lo->lo_backing_file); +	loff_t size = get_size(offset, sizelimit, lo->lo_backing_file);  	sector_t x = (sector_t)size;  	if (unlikely((loff_t)x != size))  		return -EFBIG; - +	if (lo->lo_offset != offset) +		lo->lo_offset = offset; +	if (lo->lo_sizelimit != sizelimit) +		lo->lo_sizelimit = sizelimit;  	set_capacity(lo->lo_disk, x); -	return 0;					 +	return 0;  }  static inline int @@ -372,7 +382,8 @@ do_lo_receive(struct loop_device *lo,  	if (retval < 0)  		return retval; - +	if (retval != bvec->bv_len) +		return -EIO;  	return 0;  } @@ -1058,9 +1069,7 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info)  	if (lo->lo_offset != info->lo_offset ||  	    lo->lo_sizelimit != info->lo_sizelimit) { -		lo->lo_offset = info->lo_offset; -		lo->lo_sizelimit = info->lo_sizelimit; -		if (figure_loop_size(lo)) +		if (figure_loop_size(lo, info->lo_offset, info->lo_sizelimit))  			return -EFBIG;  	}  	loop_config_discard(lo); @@ -1246,7 +1255,7 @@ static int loop_set_capacity(struct loop_device *lo, struct block_device *bdev)  	err = -ENXIO;  	if (unlikely(lo->lo_state != Lo_bound))  		goto out; -	err = figure_loop_size(lo); +	err = figure_loop_size(lo, lo->lo_offset, lo->lo_sizelimit);  	if (unlikely(err))  		goto out;  	sec = get_capacity(lo->lo_disk); @@ -1284,13 +1293,19 @@ static int lo_ioctl(struct block_device *bdev, fmode_t mode,  			goto out_unlocked;  		break;  	case LOOP_SET_STATUS: -		err = loop_set_status_old(lo, (struct loop_info __user *) arg); +		err = -EPERM; +		if ((mode & FMODE_WRITE) || capable(CAP_SYS_ADMIN)) +			err = loop_set_status_old(lo, +					(struct loop_info __user *)arg);  		break;  	case LOOP_GET_STATUS:  		err = loop_get_status_old(lo, (struct loop_info __user *) arg);  		break;  	case LOOP_SET_STATUS64: -		err = loop_set_status64(lo, (struct loop_info64 __user *) arg); +		err = -EPERM; +		if ((mode & FMODE_WRITE) || capable(CAP_SYS_ADMIN)) +			err = loop_set_status64(lo, +					(struct loop_info64 __user *) arg);  		break;  	case LOOP_GET_STATUS64:  		err = loop_get_status64(lo, (struct loop_info64 __user *) arg); diff --git a/drivers/block/paride/pg.c b/drivers/block/paride/pg.c index 6b9a2000d56..a79fb4f7ff6 100644 --- a/drivers/block/paride/pg.c +++ b/drivers/block/paride/pg.c @@ -630,6 +630,7 @@ static ssize_t pg_read(struct file *filp, char __user *buf, size_t count, loff_t  		if (dev->status & 0x10)  			return -ETIME; +	memset(&hdr, 0, sizeof(hdr));  	hdr.magic = PG_MAGIC;  	hdr.dlen = dev->dlen;  	copy = 0; diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index f9b726091ad..fe4ebc375b3 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -100,6 +100,9 @@ static struct usb_device_id btusb_table[] = {  	/* Canyon CN-BTU1 with HID interfaces */  	{ USB_DEVICE(0x0c10, 0x0000) }, +	/* Broadcom BCM20702A0 */ +	{ USB_DEVICE(0x413c, 0x8197) }, +  	{ }	/* Terminating entry */  }; diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c index 66cd0b8096c..c92424ca1a5 100644 --- a/drivers/char/agp/intel-gtt.c +++ b/drivers/char/agp/intel-gtt.c @@ -1186,10 +1186,11 @@ static void gen6_cleanup(void)  /* Certain Gen5 chipsets require require idling the GPU before   * unmapping anything from the GTT when VT-d is enabled.   */ -extern int intel_iommu_gfx_mapped;  static inline int needs_idle_maps(void)  { +#ifdef CONFIG_INTEL_IOMMU  	const unsigned short gpu_devid = intel_private.pcidev->device; +	extern int intel_iommu_gfx_mapped;  	/* Query intel_iommu to see if we need the workaround. Presumably that  	 * was loaded first. @@ -1198,7 +1199,7 @@ static inline int needs_idle_maps(void)  	     gpu_devid == PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG) &&  	     intel_iommu_gfx_mapped)  		return 1; - +#endif  	return 0;  } @@ -1236,7 +1237,7 @@ static int i9xx_setup(void)  		intel_private.gtt_bus_addr = reg_addr + gtt_offset;  	} -	if (needs_idle_maps()); +	if (needs_idle_maps())  		intel_private.base.do_idle_maps = 1;  	intel_i9xx_setup_flush(); diff --git a/drivers/char/random.c b/drivers/char/random.c index 63e19ba56bb..6035ab8d5ef 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -941,7 +941,7 @@ void get_random_bytes(void *buf, int nbytes)  		if (!arch_get_random_long(&v))  			break; -		memcpy(buf, &v, chunk); +		memcpy(p, &v, chunk);  		p += chunk;  		nbytes -= chunk;  	} diff --git a/drivers/cpufreq/db8500-cpufreq.c b/drivers/cpufreq/db8500-cpufreq.c index edaa987621e..f5002015d82 100644 --- a/drivers/cpufreq/db8500-cpufreq.c +++ b/drivers/cpufreq/db8500-cpufreq.c @@ -109,7 +109,7 @@ static unsigned int db8500_cpufreq_getspeed(unsigned int cpu)  static int __cpuinit db8500_cpufreq_init(struct cpufreq_policy *policy)  { -	int res; +	int i, res;  	BUILD_BUG_ON(ARRAY_SIZE(idx2opp) + 1 != ARRAY_SIZE(freq_table)); @@ -120,8 +120,8 @@ static int __cpuinit db8500_cpufreq_init(struct cpufreq_policy *policy)  			freq_table[3].frequency = 1000000;  	}  	pr_info("db8500-cpufreq : Available frequencies:\n"); -	while (freq_table[i].frequency != CPUFREQ_TABLE_END) -		pr_info("  %d Mhz\n", freq_table[i++].frequency/1000); +	for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++) +		pr_info("  %d Mhz\n", freq_table[i].frequency/1000);  	/* get policy fields based on the table */  	res = cpufreq_frequency_table_cpuinfo(policy, freq_table); diff --git a/drivers/devfreq/Kconfig b/drivers/devfreq/Kconfig index 643b055ed3c..8f049103708 100644 --- a/drivers/devfreq/Kconfig +++ b/drivers/devfreq/Kconfig @@ -1,36 +1,29 @@ -config ARCH_HAS_DEVFREQ -	bool -	depends on ARCH_HAS_OPP -	help -	  Denotes that the architecture supports DEVFREQ. If the architecture -	  supports multiple OPP entries per device and the frequency of the -	  devices with OPPs may be altered dynamically, the architecture -	  supports DEVFREQ. -  menuconfig PM_DEVFREQ  	bool "Generic Dynamic Voltage and Frequency Scaling (DVFS) support" -	depends on PM_OPP && ARCH_HAS_DEVFREQ  	help -	  With OPP support, a device may have a list of frequencies and -	  voltages available. DEVFREQ, a generic DVFS framework can be -	  registered for a device with OPP support in order to let the -	  governor provided to DEVFREQ choose an operating frequency -	  based on the OPP's list and the policy given with DEVFREQ. +	  A device may have a list of frequencies and voltages available. +	  devfreq, a generic DVFS framework can be registered for a device +	  in order to let the governor provided to devfreq choose an +	  operating frequency based on the device driver's policy. -	  Each device may have its own governor and policy. DEVFREQ can +	  Each device may have its own governor and policy. Devfreq can  	  reevaluate the device state periodically and/or based on the -	  OPP list changes (each frequency/voltage pair in OPP may be -	  disabled or enabled). +	  notification to "nb", a notifier block, of devfreq. -	  Like some CPUs with CPUFREQ, a device may have multiple clocks. +	  Like some CPUs with CPUfreq, a device may have multiple clocks.  	  However, because the clock frequencies of a single device are -	  determined by the single device's state, an instance of DEVFREQ +	  determined by the single device's state, an instance of devfreq  	  is attached to a single device and returns a "representative" -	  clock frequency from the OPP of the device, which is also attached -	  to a device by 1-to-1. The device registering DEVFREQ takes the -	  responsiblity to "interpret" the frequency listed in OPP and +	  clock frequency of the device, which is also attached +	  to a device by 1-to-1. The device registering devfreq takes the +	  responsiblity to "interpret" the representative frequency and  	  to set its every clock accordingly with the "target" callback -	  given to DEVFREQ. +	  given to devfreq. + +	  When OPP is used with the devfreq device, it is recommended to +	  register devfreq's nb to the OPP's notifier head.  If OPP is +	  used with the devfreq device, you may use OPP helper +	  functions defined in devfreq.h.  if PM_DEVFREQ diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index 5d15b812377..59d24e9cb8c 100644 --- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c @@ -15,7 +15,9 @@  #include <linux/errno.h>  #include <linux/err.h>  #include <linux/init.h> +#include <linux/module.h>  #include <linux/slab.h> +#include <linux/stat.h>  #include <linux/opp.h>  #include <linux/devfreq.h>  #include <linux/workqueue.h> @@ -416,10 +418,14 @@ out:   */  int devfreq_remove_device(struct devfreq *devfreq)  { +	bool central_polling; +  	if (!devfreq)  		return -EINVAL; -	if (!devfreq->governor->no_central_polling) { +	central_polling = !devfreq->governor->no_central_polling; + +	if (central_polling) {  		mutex_lock(&devfreq_list_lock);  		while (wait_remove_device == devfreq) {  			mutex_unlock(&devfreq_list_lock); @@ -431,7 +437,7 @@ int devfreq_remove_device(struct devfreq *devfreq)  	mutex_lock(&devfreq->lock);  	_remove_devfreq(devfreq, false); /* it unlocks devfreq->lock */ -	if (!devfreq->governor->no_central_polling) +	if (central_polling)  		mutex_unlock(&devfreq_list_lock);  	return 0; diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c index bcb1126e3d0..153980be4ee 100644 --- a/drivers/firmware/dmi_scan.c +++ b/drivers/firmware/dmi_scan.c @@ -585,14 +585,12 @@ int dmi_name_in_serial(const char *str)  }  /** - *	dmi_name_in_vendors - Check if string is anywhere in the DMI vendor information. + *	dmi_name_in_vendors - Check if string is in the DMI system or board vendor name   *	@str: 	Case sensitive Name   */  int dmi_name_in_vendors(const char *str)  { -	static int fields[] = { DMI_BIOS_VENDOR, DMI_BIOS_VERSION, DMI_SYS_VENDOR, -				DMI_PRODUCT_NAME, DMI_PRODUCT_VERSION, DMI_BOARD_VENDOR, -				DMI_BOARD_NAME, DMI_BOARD_VERSION, DMI_NONE }; +	static int fields[] = { DMI_SYS_VENDOR, DMI_BOARD_VENDOR, DMI_NONE };  	int i;  	for (i = 0; fields[i] != DMI_NONE; i++) {  		int f = fields[i]; diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index 0e49d87f6c6..0b056297917 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -148,13 +148,17 @@ static int _get_gpio_dataout(struct gpio_bank *bank, int gpio)  	return (__raw_readl(reg) & GPIO_BIT(bank, gpio)) != 0;  } -#define MOD_REG_BIT(reg, bit_mask, set)	\ -do {	\ -	int l = __raw_readl(base + reg); \ -	if (set) l |= bit_mask; \ -	else l &= ~bit_mask; \ -	__raw_writel(l, base + reg); \ -} while(0) +static inline void _gpio_rmw(void __iomem *base, u32 reg, u32 mask, bool set) +{ +	int l = __raw_readl(base + reg); + +	if (set)  +		l |= mask; +	else +		l &= ~mask; + +	__raw_writel(l, base + reg); +}  /**   * _set_gpio_debounce - low level gpio debounce time @@ -210,28 +214,28 @@ static inline void set_24xx_gpio_triggering(struct gpio_bank *bank, int gpio,  	u32 gpio_bit = 1 << gpio;  	if (cpu_is_omap44xx()) { -		MOD_REG_BIT(OMAP4_GPIO_LEVELDETECT0, gpio_bit, -			trigger & IRQ_TYPE_LEVEL_LOW); -		MOD_REG_BIT(OMAP4_GPIO_LEVELDETECT1, gpio_bit, -			trigger & IRQ_TYPE_LEVEL_HIGH); -		MOD_REG_BIT(OMAP4_GPIO_RISINGDETECT, gpio_bit, -			trigger & IRQ_TYPE_EDGE_RISING); -		MOD_REG_BIT(OMAP4_GPIO_FALLINGDETECT, gpio_bit, -			trigger & IRQ_TYPE_EDGE_FALLING); +		_gpio_rmw(base, OMAP4_GPIO_LEVELDETECT0, gpio_bit, +			  trigger & IRQ_TYPE_LEVEL_LOW); +		_gpio_rmw(base, OMAP4_GPIO_LEVELDETECT1, gpio_bit, +			  trigger & IRQ_TYPE_LEVEL_HIGH); +		_gpio_rmw(base, OMAP4_GPIO_RISINGDETECT, gpio_bit, +			  trigger & IRQ_TYPE_EDGE_RISING); +		_gpio_rmw(base, OMAP4_GPIO_FALLINGDETECT, gpio_bit, +			  trigger & IRQ_TYPE_EDGE_FALLING);  	} else { -		MOD_REG_BIT(OMAP24XX_GPIO_LEVELDETECT0, gpio_bit, -			trigger & IRQ_TYPE_LEVEL_LOW); -		MOD_REG_BIT(OMAP24XX_GPIO_LEVELDETECT1, gpio_bit, -			trigger & IRQ_TYPE_LEVEL_HIGH); -		MOD_REG_BIT(OMAP24XX_GPIO_RISINGDETECT, gpio_bit, -			trigger & IRQ_TYPE_EDGE_RISING); -		MOD_REG_BIT(OMAP24XX_GPIO_FALLINGDETECT, gpio_bit, -			trigger & IRQ_TYPE_EDGE_FALLING); +		_gpio_rmw(base, OMAP24XX_GPIO_LEVELDETECT0, gpio_bit, +			  trigger & IRQ_TYPE_LEVEL_LOW); +		_gpio_rmw(base, OMAP24XX_GPIO_LEVELDETECT1, gpio_bit, +			  trigger & IRQ_TYPE_LEVEL_HIGH); +		_gpio_rmw(base, OMAP24XX_GPIO_RISINGDETECT, gpio_bit, +			  trigger & IRQ_TYPE_EDGE_RISING); +		_gpio_rmw(base, OMAP24XX_GPIO_FALLINGDETECT, gpio_bit, +			  trigger & IRQ_TYPE_EDGE_FALLING);  	}  	if (likely(!(bank->non_wakeup_gpios & gpio_bit))) {  		if (cpu_is_omap44xx()) { -			MOD_REG_BIT(OMAP4_GPIO_IRQWAKEN0, gpio_bit, -				trigger != 0); +			_gpio_rmw(base, OMAP4_GPIO_IRQWAKEN0, gpio_bit, +				  trigger != 0);  		} else {  			/*  			 * GPIO wakeup request can only be generated on edge @@ -1086,6 +1090,11 @@ omap_mpuio_alloc_gc(struct gpio_bank *bank, unsigned int irq_start,  	gc = irq_alloc_generic_chip("MPUIO", 1, irq_start, bank->base,  				    handle_simple_irq); +	if (!gc) { +		dev_err(bank->dev, "Memory alloc failed for gc\n"); +		return; +	} +  	ct = gc->chip_types;  	/* NOTE: No ack required, reading IRQ status clears it. */ diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c index 0550dcb8581..147df8ae79d 100644 --- a/drivers/gpio/gpio-pca953x.c +++ b/drivers/gpio/gpio-pca953x.c @@ -596,9 +596,6 @@ static int __devinit device_pca953x_init(struct pca953x_chip *chip, int invert)  	/* set platform specific polarity inversion */  	ret = pca953x_write_reg(chip, PCA953X_INVERT, invert); -	if (ret) -		goto out; -	return 0;  out:  	return ret;  } @@ -640,7 +637,7 @@ static int __devinit pca953x_probe(struct i2c_client *client,  	struct pca953x_platform_data *pdata;  	struct pca953x_chip *chip;  	int irq_base=0, invert=0; -	int ret = 0; +	int ret;  	chip = kzalloc(sizeof(struct pca953x_chip), GFP_KERNEL);  	if (chip == NULL) @@ -673,10 +670,10 @@ static int __devinit pca953x_probe(struct i2c_client *client,  	pca953x_setup_gpio(chip, id->driver_data & PCA_GPIO_MASK);  	if (chip->chip_type == PCA953X_TYPE) -		device_pca953x_init(chip, invert); -	else if (chip->chip_type == PCA957X_TYPE) -		device_pca957x_init(chip, invert); +		ret = device_pca953x_init(chip, invert);  	else +		ret = device_pca957x_init(chip, invert); +	if (ret)  		goto out_failed;  	ret = pca953x_irq_setup(chip, id, irq_base); diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index 785127cb281..1368826ef28 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -9,7 +9,6 @@ menuconfig DRM  	depends on (AGP || AGP=n) && !EMULATED_CMPXCHG && MMU  	select I2C  	select I2C_ALGOBIT -	select SLOW_WORK  	help  	  Kernel-level support for the Direct Rendering Infrastructure (DRI)  	  introduced in XFree86 4.0. If you say Y here, you need to select @@ -96,6 +95,7 @@ config DRM_I915  	select FB_CFB_IMAGEBLIT  	# i915 depends on ACPI_VIDEO when ACPI is enabled  	# but for select to work, need to select ACPI_VIDEO's dependencies, ick +	select BACKLIGHT_LCD_SUPPORT if ACPI  	select BACKLIGHT_CLASS_DEVICE if ACPI  	select VIDEO_OUTPUT_CONTROL if ACPI  	select INPUT if ACPI diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 9a2e2a14b3b..8323fc38984 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -1873,6 +1873,10 @@ int drm_mode_dirtyfb_ioctl(struct drm_device *dev,  	}  	if (num_clips && clips_ptr) { +		if (num_clips < 0 || num_clips > DRM_MODE_FB_DIRTY_MAX_CLIPS) { +			ret = -EINVAL; +			goto out_err1; +		}  		clips = kzalloc(num_clips * sizeof(*clips), GFP_KERNEL);  		if (!clips) {  			ret = -ENOMEM; @@ -2118,8 +2122,10 @@ struct drm_property *drm_property_create(struct drm_device *dev, int flags,  	property->num_values = num_values;  	INIT_LIST_HEAD(&property->enum_blob_list); -	if (name) +	if (name) {  		strncpy(property->name, name, DRM_PROP_NAME_LEN); +		property->name[DRM_PROP_NAME_LEN-1] = '\0'; +	}  	list_add_tail(&property->head, &dev->mode_config.property_list);  	return property; diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index 2957636161e..3969f7553fe 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c @@ -484,6 +484,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)  	struct drm_connector *save_connectors, *connector;  	int count = 0, ro, fail = 0;  	struct drm_crtc_helper_funcs *crtc_funcs; +	struct drm_mode_set save_set;  	int ret = 0;  	int i; @@ -556,6 +557,12 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)  		save_connectors[count++] = *connector;  	} +	save_set.crtc = set->crtc; +	save_set.mode = &set->crtc->mode; +	save_set.x = set->crtc->x; +	save_set.y = set->crtc->y; +	save_set.fb = set->crtc->fb; +  	/* We should be able to check here if the fb has the same properties  	 * and then just flip_or_move it */  	if (set->crtc->fb != set->fb) { @@ -721,6 +728,12 @@ fail:  		*connector = save_connectors[count++];  	} +	/* Try to restore the config */ +	if (mode_changed && +	    !drm_crtc_helper_set_mode(save_set.crtc, save_set.mode, save_set.x, +				      save_set.y, save_set.fb)) +		DRM_ERROR("failed to restore config after modeset failure\n"); +  	kfree(save_connectors);  	kfree(save_encoders);  	kfree(save_crtcs); diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c index d067c12ba94..1c7a1c0d3ed 100644 --- a/drivers/gpu/drm/drm_debugfs.c +++ b/drivers/gpu/drm/drm_debugfs.c @@ -118,7 +118,10 @@ int drm_debugfs_create_files(struct drm_info_list *files, int count,  		tmp->minor = minor;  		tmp->dent = ent;  		tmp->info_ent = &files[i]; -		list_add(&(tmp->list), &(minor->debugfs_nodes.list)); + +		mutex_lock(&minor->debugfs_lock); +		list_add(&tmp->list, &minor->debugfs_list); +		mutex_unlock(&minor->debugfs_lock);  	}  	return 0; @@ -146,7 +149,8 @@ int drm_debugfs_init(struct drm_minor *minor, int minor_id,  	char name[64];  	int ret; -	INIT_LIST_HEAD(&minor->debugfs_nodes.list); +	INIT_LIST_HEAD(&minor->debugfs_list); +	mutex_init(&minor->debugfs_lock);  	sprintf(name, "%d", minor_id);  	minor->debugfs_root = debugfs_create_dir(name, root);  	if (!minor->debugfs_root) { @@ -192,8 +196,9 @@ int drm_debugfs_remove_files(struct drm_info_list *files, int count,  	struct drm_info_node *tmp;  	int i; +	mutex_lock(&minor->debugfs_lock);  	for (i = 0; i < count; i++) { -		list_for_each_safe(pos, q, &minor->debugfs_nodes.list) { +		list_for_each_safe(pos, q, &minor->debugfs_list) {  			tmp = list_entry(pos, struct drm_info_node, list);  			if (tmp->info_ent == &files[i]) {  				debugfs_remove(tmp->dent); @@ -202,6 +207,7 @@ int drm_debugfs_remove_files(struct drm_info_list *files, int count,  			}  		}  	} +	mutex_unlock(&minor->debugfs_lock);  	return 0;  }  EXPORT_SYMBOL(drm_debugfs_remove_files); diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index fc81af9dbf4..40c187c60f4 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -125,7 +125,7 @@ static struct drm_ioctl_desc drm_ioctls[] = {  	DRM_IOCTL_DEF(DRM_IOCTL_SG_ALLOC, drm_sg_alloc_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),  	DRM_IOCTL_DEF(DRM_IOCTL_SG_FREE, drm_sg_free, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), -	DRM_IOCTL_DEF(DRM_IOCTL_WAIT_VBLANK, drm_wait_vblank, 0), +	DRM_IOCTL_DEF(DRM_IOCTL_WAIT_VBLANK, drm_wait_vblank, DRM_UNLOCKED),  	DRM_IOCTL_DEF(DRM_IOCTL_MODESET_CTL, drm_modeset_ctl, 0), diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index cb3794a00f9..44a5d0ad8b7 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -110,10 +110,7 @@ static void vblank_disable_and_save(struct drm_device *dev, int crtc)  	/* Prevent vblank irq processing while disabling vblank irqs,  	 * so no updates of timestamps or count can happen after we've  	 * disabled. Needed to prevent races in case of delayed irq's. -	 * Disable preemption, so vblank_time_lock is held as short as -	 * possible, even under a kernel with PREEMPT_RT patches.  	 */ -	preempt_disable();  	spin_lock_irqsave(&dev->vblank_time_lock, irqflags);  	dev->driver->disable_vblank(dev, crtc); @@ -164,7 +161,6 @@ static void vblank_disable_and_save(struct drm_device *dev, int crtc)  	clear_vblank_timestamps(dev, crtc);  	spin_unlock_irqrestore(&dev->vblank_time_lock, irqflags); -	preempt_enable();  }  static void vblank_disable_fn(unsigned long arg) @@ -407,13 +403,16 @@ int drm_irq_uninstall(struct drm_device *dev)  	/*  	 * Wake up any waiters so they don't hang.  	 */ -	spin_lock_irqsave(&dev->vbl_lock, irqflags); -	for (i = 0; i < dev->num_crtcs; i++) { -		DRM_WAKEUP(&dev->vbl_queue[i]); -		dev->vblank_enabled[i] = 0; -		dev->last_vblank[i] = dev->driver->get_vblank_counter(dev, i); +	if (dev->num_crtcs) { +		spin_lock_irqsave(&dev->vbl_lock, irqflags); +		for (i = 0; i < dev->num_crtcs; i++) { +			DRM_WAKEUP(&dev->vbl_queue[i]); +			dev->vblank_enabled[i] = 0; +			dev->last_vblank[i] = +				dev->driver->get_vblank_counter(dev, i); +		} +		spin_unlock_irqrestore(&dev->vbl_lock, irqflags);  	} -	spin_unlock_irqrestore(&dev->vbl_lock, irqflags);  	if (!irq_enabled)  		return -EINVAL; @@ -886,10 +885,6 @@ int drm_vblank_get(struct drm_device *dev, int crtc)  	spin_lock_irqsave(&dev->vbl_lock, irqflags);  	/* Going from 0->1 means we have to enable interrupts again */  	if (atomic_add_return(1, &dev->vblank_refcount[crtc]) == 1) { -		/* Disable preemption while holding vblank_time_lock. Do -		 * it explicitely to guard against PREEMPT_RT kernel. -		 */ -		preempt_disable();  		spin_lock_irqsave(&dev->vblank_time_lock, irqflags2);  		if (!dev->vblank_enabled[crtc]) {  			/* Enable vblank irqs under vblank_time_lock protection. @@ -909,7 +904,6 @@ int drm_vblank_get(struct drm_device *dev, int crtc)  			}  		}  		spin_unlock_irqrestore(&dev->vblank_time_lock, irqflags2); -		preempt_enable();  	} else {  		if (!dev->vblank_enabled[crtc]) {  			atomic_dec(&dev->vblank_refcount[crtc]); @@ -1125,6 +1119,7 @@ static int drm_queue_vblank_event(struct drm_device *dev, int pipe,  		trace_drm_vblank_event_delivered(current->pid, pipe,  						 vblwait->request.sequence);  	} else { +		/* drm_handle_vblank_events will call drm_vblank_put */  		list_add_tail(&e->base.link, &dev->vblank_event_list);  		vblwait->reply.sequence = vblwait->request.sequence;  	} @@ -1205,8 +1200,12 @@ int drm_wait_vblank(struct drm_device *dev, void *data,  		goto done;  	} -	if (flags & _DRM_VBLANK_EVENT) +	if (flags & _DRM_VBLANK_EVENT) { +		/* must hold on to the vblank ref until the event fires +		 * drm_vblank_put will be called asynchronously +		 */  		return drm_queue_vblank_event(dev, crtc, vblwait, file_priv); +	}  	if ((flags & _DRM_VBLANK_NEXTONMISS) &&  	    (seq - vblwait->request.sequence) <= (1<<23)) { diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index d14b44e13f5..d09a6e02dc9 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -636,11 +636,16 @@ static int i915_ringbuffer_info(struct seq_file *m, void *data)  	struct drm_device *dev = node->minor->dev;  	drm_i915_private_t *dev_priv = dev->dev_private;  	struct intel_ring_buffer *ring; +	int ret;  	ring = &dev_priv->ring[(uintptr_t)node->info_ent->data];  	if (ring->size == 0)  		return 0; +	ret = mutex_lock_interruptible(&dev->struct_mutex); +	if (ret) +		return ret; +  	seq_printf(m, "Ring %s:\n", ring->name);  	seq_printf(m, "  Head :    %08x\n", I915_READ_HEAD(ring) & HEAD_ADDR);  	seq_printf(m, "  Tail :    %08x\n", I915_READ_TAIL(ring) & TAIL_ADDR); @@ -654,6 +659,8 @@ static int i915_ringbuffer_info(struct seq_file *m, void *data)  	seq_printf(m, "  Control : %08x\n", I915_READ_CTL(ring));  	seq_printf(m, "  Start :   %08x\n", I915_READ_START(ring)); +	mutex_unlock(&dev->struct_mutex); +  	return 0;  } @@ -842,7 +849,16 @@ static int i915_rstdby_delays(struct seq_file *m, void *unused)  	struct drm_info_node *node = (struct drm_info_node *) m->private;  	struct drm_device *dev = node->minor->dev;  	drm_i915_private_t *dev_priv = dev->dev_private; -	u16 crstanddelay = I915_READ16(CRSTANDVID); +	u16 crstanddelay; +	int ret; + +	ret = mutex_lock_interruptible(&dev->struct_mutex); +	if (ret) +		return ret; + +	crstanddelay = I915_READ16(CRSTANDVID); + +	mutex_unlock(&dev->struct_mutex);  	seq_printf(m, "w/ctx: %d, w/o ctx: %d\n", (crstanddelay >> 8) & 0x3f, (crstanddelay & 0x3f)); @@ -940,7 +956,11 @@ static int i915_delayfreq_table(struct seq_file *m, void *unused)  	struct drm_device *dev = node->minor->dev;  	drm_i915_private_t *dev_priv = dev->dev_private;  	u32 delayfreq; -	int i; +	int ret, i; + +	ret = mutex_lock_interruptible(&dev->struct_mutex); +	if (ret) +		return ret;  	for (i = 0; i < 16; i++) {  		delayfreq = I915_READ(PXVFREQ_BASE + i * 4); @@ -948,6 +968,8 @@ static int i915_delayfreq_table(struct seq_file *m, void *unused)  			   (delayfreq & PXVFREQ_PX_MASK) >> PXVFREQ_PX_SHIFT);  	} +	mutex_unlock(&dev->struct_mutex); +  	return 0;  } @@ -962,13 +984,19 @@ static int i915_inttoext_table(struct seq_file *m, void *unused)  	struct drm_device *dev = node->minor->dev;  	drm_i915_private_t *dev_priv = dev->dev_private;  	u32 inttoext; -	int i; +	int ret, i; + +	ret = mutex_lock_interruptible(&dev->struct_mutex); +	if (ret) +		return ret;  	for (i = 1; i <= 32; i++) {  		inttoext = I915_READ(INTTOEXT_BASE_ILK + i * 4);  		seq_printf(m, "INTTOEXT%02d: 0x%08x\n", i, inttoext);  	} +	mutex_unlock(&dev->struct_mutex); +  	return 0;  } @@ -977,9 +1005,19 @@ static int i915_drpc_info(struct seq_file *m, void *unused)  	struct drm_info_node *node = (struct drm_info_node *) m->private;  	struct drm_device *dev = node->minor->dev;  	drm_i915_private_t *dev_priv = dev->dev_private; -	u32 rgvmodectl = I915_READ(MEMMODECTL); -	u32 rstdbyctl = I915_READ(RSTDBYCTL); -	u16 crstandvid = I915_READ16(CRSTANDVID); +	u32 rgvmodectl, rstdbyctl; +	u16 crstandvid; +	int ret; + +	ret = mutex_lock_interruptible(&dev->struct_mutex); +	if (ret) +		return ret; + +	rgvmodectl = I915_READ(MEMMODECTL); +	rstdbyctl = I915_READ(RSTDBYCTL); +	crstandvid = I915_READ16(CRSTANDVID); + +	mutex_unlock(&dev->struct_mutex);  	seq_printf(m, "HD boost: %s\n", (rgvmodectl & MEMMODE_BOOST_EN) ?  		   "yes" : "no"); @@ -1167,9 +1205,16 @@ static int i915_gfxec(struct seq_file *m, void *unused)  	struct drm_info_node *node = (struct drm_info_node *) m->private;  	struct drm_device *dev = node->minor->dev;  	drm_i915_private_t *dev_priv = dev->dev_private; +	int ret; + +	ret = mutex_lock_interruptible(&dev->struct_mutex); +	if (ret) +		return ret;  	seq_printf(m, "GFXEC: %ld\n", (unsigned long)I915_READ(0x112f4)); +	mutex_unlock(&dev->struct_mutex); +  	return 0;  } @@ -1506,7 +1551,10 @@ drm_add_fake_info_node(struct drm_minor *minor,  	node->minor = minor;  	node->dent = ent;  	node->info_ent = (void *) key; -	list_add(&node->list, &minor->debugfs_nodes.list); + +	mutex_lock(&minor->debugfs_lock); +	list_add(&node->list, &minor->debugfs_list); +	mutex_unlock(&minor->debugfs_lock);  	return 0;  } diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index cc531bb59c2..15bfa9145d2 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -68,7 +68,7 @@ module_param_named(i915_enable_rc6, i915_enable_rc6, int, 0600);  MODULE_PARM_DESC(i915_enable_rc6,  		"Enable power-saving render C-state 6 (default: true)"); -unsigned int i915_enable_fbc __read_mostly = -1; +int i915_enable_fbc __read_mostly = -1;  module_param_named(i915_enable_fbc, i915_enable_fbc, int, 0600);  MODULE_PARM_DESC(i915_enable_fbc,  		"Enable frame buffer compression for power savings " @@ -80,7 +80,7 @@ MODULE_PARM_DESC(lvds_downclock,  		"Use panel (LVDS/eDP) downclocking for power savings "  		"(default: false)"); -unsigned int i915_panel_use_ssc __read_mostly = -1; +int i915_panel_use_ssc __read_mostly = -1;  module_param_named(lvds_use_ssc, i915_panel_use_ssc, int, 0600);  MODULE_PARM_DESC(lvds_use_ssc,  		"Use Spread Spectrum Clock with panels [LVDS/eDP] " @@ -107,7 +107,7 @@ static struct drm_driver driver;  extern int intel_agp_enabled;  #define INTEL_VGA_DEVICE(id, info) {		\ -	.class = PCI_CLASS_DISPLAY_VGA << 8,	\ +	.class = PCI_BASE_CLASS_DISPLAY << 16,	\  	.class_mask = 0xff0000,			\  	.vendor = 0x8086,			\  	.device = id,				\ @@ -789,8 +789,8 @@ static struct vm_operations_struct i915_gem_vm_ops = {  };  static struct drm_driver driver = { -	/* don't use mtrr's here, the Xserver or user space app should -	 * deal with them for intel hardware. +	/* Don't use MTRRs here; the Xserver or userspace app should +	 * deal with them for Intel hardware.  	 */  	.driver_features =  	    DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | /* DRIVER_USE_MTRR |*/ diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 06a37f4fd74..4a9c1b97980 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -126,6 +126,9 @@ struct drm_i915_master_private {  	struct _drm_i915_sarea *sarea_priv;  };  #define I915_FENCE_REG_NONE -1 +#define I915_MAX_NUM_FENCES 16 +/* 16 fences + sign bit for FENCE_REG_NONE */ +#define I915_MAX_NUM_FENCE_BITS 5  struct drm_i915_fence_reg {  	struct list_head lru_list; @@ -168,7 +171,7 @@ struct drm_i915_error_state {  	u32 instdone1;  	u32 seqno;  	u64 bbaddr; -	u64 fence[16]; +	u64 fence[I915_MAX_NUM_FENCES];  	struct timeval time;  	struct drm_i915_error_object {  		int page_count; @@ -182,7 +185,7 @@ struct drm_i915_error_state {  		u32 gtt_offset;  		u32 read_domains;  		u32 write_domain; -		s32 fence_reg:5; +		s32 fence_reg:I915_MAX_NUM_FENCE_BITS;  		s32 pinned:2;  		u32 tiling:2;  		u32 dirty:1; @@ -375,7 +378,7 @@ typedef struct drm_i915_private {  	struct notifier_block lid_notifier;  	int crt_ddc_pin; -	struct drm_i915_fence_reg fence_regs[16]; /* assume 965 */ +	struct drm_i915_fence_reg fence_regs[I915_MAX_NUM_FENCES]; /* assume 965 */  	int fence_reg_start; /* 4 if userland hasn't ioctl'd us yet */  	int num_fence_regs; /* 8 on pre-965, 16 otherwise */ @@ -506,7 +509,7 @@ typedef struct drm_i915_private {  	u8 saveAR[21];  	u8 saveDACMASK;  	u8 saveCR[37]; -	uint64_t saveFENCE[16]; +	uint64_t saveFENCE[I915_MAX_NUM_FENCES];  	u32 saveCURACNTR;  	u32 saveCURAPOS;  	u32 saveCURABASE; @@ -777,10 +780,8 @@ struct drm_i915_gem_object {  	 * Fence register bits (if any) for this object.  Will be set  	 * as needed when mapped into the GTT.  	 * Protected by dev->struct_mutex. -	 * -	 * Size: 4 bits for 16 fences + sign (for FENCE_REG_NONE)  	 */ -	signed int fence_reg:5; +	signed int fence_reg:I915_MAX_NUM_FENCE_BITS;  	/**  	 * Advice: are the backing pages purgeable? @@ -999,10 +1000,10 @@ extern int i915_panel_ignore_lid __read_mostly;  extern unsigned int i915_powersave __read_mostly;  extern unsigned int i915_semaphores __read_mostly;  extern unsigned int i915_lvds_downclock __read_mostly; -extern unsigned int i915_panel_use_ssc __read_mostly; +extern int i915_panel_use_ssc __read_mostly;  extern int i915_vbt_sdvo_panel_type __read_mostly;  extern unsigned int i915_enable_rc6 __read_mostly; -extern unsigned int i915_enable_fbc __read_mostly; +extern int i915_enable_fbc __read_mostly;  extern bool i915_enable_hangcheck __read_mostly;  extern int i915_suspend(struct drm_device *dev, pm_message_t state); diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 6651c36b6e8..8359dc77704 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1396,7 +1396,7 @@ i915_gem_mmap_gtt(struct drm_file *file,  	if (obj->base.size > dev_priv->mm.gtt_mappable_end) {  		ret = -E2BIG; -		goto unlock; +		goto out;  	}  	if (obj->madv != I915_MADV_WILLNEED) { @@ -1745,7 +1745,7 @@ static void i915_gem_reset_fences(struct drm_device *dev)  	struct drm_i915_private *dev_priv = dev->dev_private;  	int i; -	for (i = 0; i < 16; i++) { +	for (i = 0; i < dev_priv->num_fence_regs; i++) {  		struct drm_i915_fence_reg *reg = &dev_priv->fence_regs[i];  		struct drm_i915_gem_object *obj = reg->obj; @@ -3512,9 +3512,11 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data,  			 * so emit a request to do so.  			 */  			request = kzalloc(sizeof(*request), GFP_KERNEL); -			if (request) +			if (request) {  				ret = i915_add_request(obj->ring, NULL, request); -			else +				if (ret) +					kfree(request); +			} else  				ret = -ENOMEM;  		} @@ -3613,7 +3615,7 @@ struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev,  	obj->base.write_domain = I915_GEM_DOMAIN_CPU;  	obj->base.read_domains = I915_GEM_DOMAIN_CPU; -	if (IS_GEN6(dev)) { +	if (IS_GEN6(dev) || IS_GEN7(dev)) {  		/* On Gen6, we can have the GPU use the LLC (the CPU  		 * cache) for about a 10% performance improvement  		 * compared to uncached.  Graphics requests other than @@ -3877,7 +3879,7 @@ i915_gem_load(struct drm_device *dev)  	INIT_LIST_HEAD(&dev_priv->mm.gtt_list);  	for (i = 0; i < I915_NUM_RINGS; i++)  		init_ring_lists(&dev_priv->ring[i]); -	for (i = 0; i < 16; i++) +	for (i = 0; i < I915_MAX_NUM_FENCES; i++)  		INIT_LIST_HEAD(&dev_priv->fence_regs[i].lru_list);  	INIT_DELAYED_WORK(&dev_priv->mm.retire_work,  			  i915_gem_retire_work_handler); diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 9ee2729fe5c..b40004b5597 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -824,6 +824,7 @@ static void i915_gem_record_fences(struct drm_device *dev,  	/* Fences */  	switch (INTEL_INFO(dev)->gen) { +	case 7:  	case 6:  		for (i = 0; i < 16; i++)  			error->fence[i] = I915_READ64(FENCE_REG_SANDYBRIDGE_0 + (i * 8)); diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 5a09416e611..b080cc82400 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -1553,12 +1553,21 @@   */  #define   PP_READY		(1 << 30)  #define   PP_SEQUENCE_NONE	(0 << 28) -#define   PP_SEQUENCE_ON	(1 << 28) -#define   PP_SEQUENCE_OFF	(2 << 28) -#define   PP_SEQUENCE_MASK	0x30000000 +#define   PP_SEQUENCE_POWER_UP	(1 << 28) +#define   PP_SEQUENCE_POWER_DOWN (2 << 28) +#define   PP_SEQUENCE_MASK	(3 << 28) +#define   PP_SEQUENCE_SHIFT	28  #define   PP_CYCLE_DELAY_ACTIVE	(1 << 27) -#define   PP_SEQUENCE_STATE_ON_IDLE (1 << 3)  #define   PP_SEQUENCE_STATE_MASK 0x0000000f +#define   PP_SEQUENCE_STATE_OFF_IDLE	(0x0 << 0) +#define   PP_SEQUENCE_STATE_OFF_S0_1	(0x1 << 0) +#define   PP_SEQUENCE_STATE_OFF_S0_2	(0x2 << 0) +#define   PP_SEQUENCE_STATE_OFF_S0_3	(0x3 << 0) +#define   PP_SEQUENCE_STATE_ON_IDLE	(0x8 << 0) +#define   PP_SEQUENCE_STATE_ON_S1_0	(0x9 << 0) +#define   PP_SEQUENCE_STATE_ON_S1_2	(0xa << 0) +#define   PP_SEQUENCE_STATE_ON_S1_3	(0xb << 0) +#define   PP_SEQUENCE_STATE_RESET	(0xf << 0)  #define PP_CONTROL	0x61204  #define   POWER_TARGET_ON	(1 << 0)  #define PP_ON_DELAYS	0x61208 @@ -3444,6 +3453,10 @@  #define  GT_FIFO_FREE_ENTRIES			0x120008  #define    GT_FIFO_NUM_RESERVED_ENTRIES		20 +#define GEN6_UCGCTL2				0x9404 +# define GEN6_RCPBUNIT_CLOCK_GATE_DISABLE		(1 << 12) +# define GEN6_RCCUNIT_CLOCK_GATE_DISABLE		(1 << 11) +  #define GEN6_RPNSWREQ				0xA008  #define   GEN6_TURBO_DISABLE			(1<<31)  #define   GEN6_FREQUENCY(x)			((x)<<25) diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c index f8f602d7665..7886e4fb60e 100644 --- a/drivers/gpu/drm/i915/i915_suspend.c +++ b/drivers/gpu/drm/i915/i915_suspend.c @@ -370,6 +370,7 @@ static void i915_save_modeset_reg(struct drm_device *dev)  	/* Fences */  	switch (INTEL_INFO(dev)->gen) { +	case 7:  	case 6:  		for (i = 0; i < 16; i++)  			dev_priv->saveFENCE[i] = I915_READ64(FENCE_REG_SANDYBRIDGE_0 + (i * 8)); @@ -404,6 +405,7 @@ static void i915_restore_modeset_reg(struct drm_device *dev)  	/* Fences */  	switch (INTEL_INFO(dev)->gen) { +	case 7:  	case 6:  		for (i = 0; i < 16; i++)  			I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + (i * 8), dev_priv->saveFENCE[i]); diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 981b1f1c04d..e77a863a383 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2933,7 +2933,8 @@ static void ironlake_pch_enable(struct drm_crtc *crtc)  	/* For PCH DP, enable TRANS_DP_CTL */  	if (HAS_PCH_CPT(dev) && -	    intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT)) { +	    (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT) || +	     intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP))) {  		u32 bpc = (I915_READ(PIPECONF(pipe)) & PIPE_BPC_MASK) >> 5;  		reg = TRANS_DP_CTL(pipe);  		temp = I915_READ(reg); @@ -4711,7 +4712,7 @@ static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc,  				lvds_bpc = 6;  			if (lvds_bpc < display_bpc) { -				DRM_DEBUG_DRIVER("clamping display bpc (was %d) to LVDS (%d)\n", display_bpc, lvds_bpc); +				DRM_DEBUG_KMS("clamping display bpc (was %d) to LVDS (%d)\n", display_bpc, lvds_bpc);  				display_bpc = lvds_bpc;  			}  			continue; @@ -4722,7 +4723,7 @@ static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc,  			unsigned int edp_bpc = dev_priv->edp.bpp / 3;  			if (edp_bpc < display_bpc) { -				DRM_DEBUG_DRIVER("clamping display bpc (was %d) to eDP (%d)\n", display_bpc, edp_bpc); +				DRM_DEBUG_KMS("clamping display bpc (was %d) to eDP (%d)\n", display_bpc, edp_bpc);  				display_bpc = edp_bpc;  			}  			continue; @@ -4737,7 +4738,7 @@ static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc,  			/* Don't use an invalid EDID bpc value */  			if (connector->display_info.bpc &&  			    connector->display_info.bpc < display_bpc) { -				DRM_DEBUG_DRIVER("clamping display bpc (was %d) to EDID reported max of %d\n", display_bpc, connector->display_info.bpc); +				DRM_DEBUG_KMS("clamping display bpc (was %d) to EDID reported max of %d\n", display_bpc, connector->display_info.bpc);  				display_bpc = connector->display_info.bpc;  			}  		} @@ -4748,10 +4749,10 @@ static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc,  		 */  		if (intel_encoder->type == INTEL_OUTPUT_HDMI) {  			if (display_bpc > 8 && display_bpc < 12) { -				DRM_DEBUG_DRIVER("forcing bpc to 12 for HDMI\n"); +				DRM_DEBUG_KMS("forcing bpc to 12 for HDMI\n");  				display_bpc = 12;  			} else { -				DRM_DEBUG_DRIVER("forcing bpc to 8 for HDMI\n"); +				DRM_DEBUG_KMS("forcing bpc to 8 for HDMI\n");  				display_bpc = 8;  			}  		} @@ -4789,8 +4790,8 @@ static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc,  	display_bpc = min(display_bpc, bpc); -	DRM_DEBUG_DRIVER("setting pipe bpc to %d (max display bpc %d)\n", -			 bpc, display_bpc); +	DRM_DEBUG_KMS("setting pipe bpc to %d (max display bpc %d)\n", +		      bpc, display_bpc);  	*pipe_bpp = display_bpc * 3; @@ -5671,7 +5672,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,  	pipeconf &= ~PIPECONF_DITHER_TYPE_MASK;  	if ((is_lvds && dev_priv->lvds_dither) || dither) {  		pipeconf |= PIPECONF_DITHER_EN; -		pipeconf |= PIPECONF_DITHER_TYPE_ST1; +		pipeconf |= PIPECONF_DITHER_TYPE_SP;  	}  	if (is_dp || intel_encoder_is_pch_edp(&has_edp_encoder->base)) {  		intel_dp_set_m_n(crtc, mode, adjusted_mode); @@ -8148,6 +8149,20 @@ static void gen6_init_clock_gating(struct drm_device *dev)  	I915_WRITE(WM2_LP_ILK, 0);  	I915_WRITE(WM1_LP_ILK, 0); +	/* According to the BSpec vol1g, bit 12 (RCPBUNIT) clock +	 * gating disable must be set.  Failure to set it results in +	 * flickering pixels due to Z write ordering failures after +	 * some amount of runtime in the Mesa "fire" demo, and Unigine +	 * Sanctuary and Tropics, and apparently anything else with +	 * alpha test or pixel discard. +	 * +	 * According to the spec, bit 11 (RCCUNIT) must also be set, +	 * but we didn't debug actual testcases to find it out. +	 */ +	I915_WRITE(GEN6_UCGCTL2, +		   GEN6_RCPBUNIT_CLOCK_GATE_DISABLE | +		   GEN6_RCCUNIT_CLOCK_GATE_DISABLE); +  	/*  	 * According to the spec the following bits should be  	 * set in order to enable memory self-refresh and fbc: diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 09b318b0227..4d0358fad93 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -59,7 +59,6 @@ struct intel_dp {  	struct i2c_algo_dp_aux_data algo;  	bool is_pch_edp;  	uint8_t	train_set[4]; -	uint8_t link_status[DP_LINK_STATUS_SIZE];  	int panel_power_up_delay;  	int panel_power_down_delay;  	int panel_power_cycle_delay; @@ -68,7 +67,6 @@ struct intel_dp {  	struct drm_display_mode *panel_fixed_mode;  /* for eDP */  	struct delayed_work panel_vdd_work;  	bool want_panel_vdd; -	unsigned long panel_off_jiffies;  };  /** @@ -157,16 +155,12 @@ intel_edp_link_config(struct intel_encoder *intel_encoder,  static int  intel_dp_max_lane_count(struct intel_dp *intel_dp)  { -	int max_lane_count = 4; - -	if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11) { -		max_lane_count = intel_dp->dpcd[DP_MAX_LANE_COUNT] & 0x1f; -		switch (max_lane_count) { -		case 1: case 2: case 4: -			break; -		default: -			max_lane_count = 4; -		} +	int max_lane_count = intel_dp->dpcd[DP_MAX_LANE_COUNT] & 0x1f; +	switch (max_lane_count) { +	case 1: case 2: case 4: +		break; +	default: +		max_lane_count = 4;  	}  	return max_lane_count;  } @@ -768,12 +762,11 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode,  			continue;  		intel_dp = enc_to_intel_dp(encoder); -		if (intel_dp->base.type == INTEL_OUTPUT_DISPLAYPORT) { +		if (intel_dp->base.type == INTEL_OUTPUT_DISPLAYPORT || +		    intel_dp->base.type == INTEL_OUTPUT_EDP) +		{  			lane_count = intel_dp->lane_count;  			break; -		} else if (is_edp(intel_dp)) { -			lane_count = dev_priv->edp.lanes; -			break;  		}  	} @@ -810,6 +803,7 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,  		  struct drm_display_mode *adjusted_mode)  {  	struct drm_device *dev = encoder->dev; +	struct drm_i915_private *dev_priv = dev->dev_private;  	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);  	struct drm_crtc *crtc = intel_dp->base.base.crtc;  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc); @@ -822,18 +816,31 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,  			ironlake_edp_pll_off(encoder);  	} -	intel_dp->DP = DP_VOLTAGE_0_4 | DP_PRE_EMPHASIS_0; -	intel_dp->DP |= intel_dp->color_range; +	/* +	 * There are three kinds of DP registers: +	 * +	 * 	IBX PCH +	 * 	CPU +	 * 	CPT PCH +	 * +	 * IBX PCH and CPU are the same for almost everything, +	 * except that the CPU DP PLL is configured in this +	 * register +	 * +	 * CPT PCH is quite different, having many bits moved +	 * to the TRANS_DP_CTL register instead. That +	 * configuration happens (oddly) in ironlake_pch_enable +	 */ -	if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) -		intel_dp->DP |= DP_SYNC_HS_HIGH; -	if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) -		intel_dp->DP |= DP_SYNC_VS_HIGH; +	/* Preserve the BIOS-computed detected bit. This is +	 * supposed to be read-only. +	 */ +	intel_dp->DP = I915_READ(intel_dp->output_reg) & DP_DETECTED; +	intel_dp->DP |=  DP_VOLTAGE_0_4 | DP_PRE_EMPHASIS_0; -	if (HAS_PCH_CPT(dev) && !is_cpu_edp(intel_dp)) -		intel_dp->DP |= DP_LINK_TRAIN_OFF_CPT; -	else -		intel_dp->DP |= DP_LINK_TRAIN_OFF; +	/* Handle DP bits in common between all three register formats */ + +	intel_dp->DP |= DP_VOLTAGE_0_4 | DP_PRE_EMPHASIS_0;  	switch (intel_dp->lane_count) {  	case 1: @@ -852,59 +859,106 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,  		intel_dp->DP |= DP_AUDIO_OUTPUT_ENABLE;  		intel_write_eld(encoder, adjusted_mode);  	} -  	memset(intel_dp->link_configuration, 0, DP_LINK_CONFIGURATION_SIZE);  	intel_dp->link_configuration[0] = intel_dp->link_bw;  	intel_dp->link_configuration[1] = intel_dp->lane_count;  	intel_dp->link_configuration[8] = DP_SET_ANSI_8B10B; -  	/*  	 * Check for DPCD version > 1.1 and enhanced framing support  	 */  	if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11 &&  	    (intel_dp->dpcd[DP_MAX_LANE_COUNT] & DP_ENHANCED_FRAME_CAP)) {  		intel_dp->link_configuration[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN; -		intel_dp->DP |= DP_ENHANCED_FRAMING;  	} -	/* CPT DP's pipe select is decided in TRANS_DP_CTL */ -	if (intel_crtc->pipe == 1 && !HAS_PCH_CPT(dev)) -		intel_dp->DP |= DP_PIPEB_SELECT; +	/* Split out the IBX/CPU vs CPT settings */ -	if (is_cpu_edp(intel_dp)) { -		/* don't miss out required setting for eDP */ -		intel_dp->DP |= DP_PLL_ENABLE; -		if (adjusted_mode->clock < 200000) -			intel_dp->DP |= DP_PLL_FREQ_160MHZ; -		else -			intel_dp->DP |= DP_PLL_FREQ_270MHZ; +	if (!HAS_PCH_CPT(dev) || is_cpu_edp(intel_dp)) { +		intel_dp->DP |= intel_dp->color_range; + +		if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) +			intel_dp->DP |= DP_SYNC_HS_HIGH; +		if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) +			intel_dp->DP |= DP_SYNC_VS_HIGH; +		intel_dp->DP |= DP_LINK_TRAIN_OFF; + +		if (intel_dp->link_configuration[1] & DP_LANE_COUNT_ENHANCED_FRAME_EN) +			intel_dp->DP |= DP_ENHANCED_FRAMING; + +		if (intel_crtc->pipe == 1) +			intel_dp->DP |= DP_PIPEB_SELECT; + +		if (is_cpu_edp(intel_dp)) { +			/* don't miss out required setting for eDP */ +			intel_dp->DP |= DP_PLL_ENABLE; +			if (adjusted_mode->clock < 200000) +				intel_dp->DP |= DP_PLL_FREQ_160MHZ; +			else +				intel_dp->DP |= DP_PLL_FREQ_270MHZ; +		} +	} else { +		intel_dp->DP |= DP_LINK_TRAIN_OFF_CPT;  	}  } -static void ironlake_wait_panel_off(struct intel_dp *intel_dp) +#define IDLE_ON_MASK		(PP_ON | 0 	  | PP_SEQUENCE_MASK | 0                     | PP_SEQUENCE_STATE_MASK) +#define IDLE_ON_VALUE   	(PP_ON | 0 	  | PP_SEQUENCE_NONE | 0                     | PP_SEQUENCE_STATE_ON_IDLE) + +#define IDLE_OFF_MASK		(PP_ON | 0        | PP_SEQUENCE_MASK | 0                     | PP_SEQUENCE_STATE_MASK) +#define IDLE_OFF_VALUE		(0     | 0        | PP_SEQUENCE_NONE | 0                     | PP_SEQUENCE_STATE_OFF_IDLE) + +#define IDLE_CYCLE_MASK		(PP_ON | 0        | PP_SEQUENCE_MASK | PP_CYCLE_DELAY_ACTIVE | PP_SEQUENCE_STATE_MASK) +#define IDLE_CYCLE_VALUE	(0     | 0        | PP_SEQUENCE_NONE | 0                     | PP_SEQUENCE_STATE_OFF_IDLE) + +static void ironlake_wait_panel_status(struct intel_dp *intel_dp, +				       u32 mask, +				       u32 value)  { -	unsigned long	off_time; -	unsigned long	delay; +	struct drm_device *dev = intel_dp->base.base.dev; +	struct drm_i915_private *dev_priv = dev->dev_private; -	DRM_DEBUG_KMS("Wait for panel power off time\n"); +	DRM_DEBUG_KMS("mask %08x value %08x status %08x control %08x\n", +		      mask, value, +		      I915_READ(PCH_PP_STATUS), +		      I915_READ(PCH_PP_CONTROL)); -	if (ironlake_edp_have_panel_power(intel_dp) || -	    ironlake_edp_have_panel_vdd(intel_dp)) -	{ -		DRM_DEBUG_KMS("Panel still on, no delay needed\n"); -		return; +	if (_wait_for((I915_READ(PCH_PP_STATUS) & mask) == value, 5000, 10)) { +		DRM_ERROR("Panel status timeout: status %08x control %08x\n", +			  I915_READ(PCH_PP_STATUS), +			  I915_READ(PCH_PP_CONTROL));  	} +} -	off_time = intel_dp->panel_off_jiffies + msecs_to_jiffies(intel_dp->panel_power_down_delay); -	if (time_after(jiffies, off_time)) { -		DRM_DEBUG_KMS("Time already passed"); -		return; -	} -	delay = jiffies_to_msecs(off_time - jiffies); -	if (delay > intel_dp->panel_power_down_delay) -		delay = intel_dp->panel_power_down_delay; -	DRM_DEBUG_KMS("Waiting an additional %ld ms\n", delay); -	msleep(delay); +static void ironlake_wait_panel_on(struct intel_dp *intel_dp) +{ +	DRM_DEBUG_KMS("Wait for panel power on\n"); +	ironlake_wait_panel_status(intel_dp, IDLE_ON_MASK, IDLE_ON_VALUE); +} + +static void ironlake_wait_panel_off(struct intel_dp *intel_dp) +{ +	DRM_DEBUG_KMS("Wait for panel power off time\n"); +	ironlake_wait_panel_status(intel_dp, IDLE_OFF_MASK, IDLE_OFF_VALUE); +} + +static void ironlake_wait_panel_power_cycle(struct intel_dp *intel_dp) +{ +	DRM_DEBUG_KMS("Wait for panel power cycle\n"); +	ironlake_wait_panel_status(intel_dp, IDLE_CYCLE_MASK, IDLE_CYCLE_VALUE); +} + + +/* Read the current pp_control value, unlocking the register if it + * is locked + */ + +static  u32 ironlake_get_pp_control(struct drm_i915_private *dev_priv) +{ +	u32	control = I915_READ(PCH_PP_CONTROL); + +	control &= ~PANEL_UNLOCK_MASK; +	control |= PANEL_UNLOCK_REGS; +	return control;  }  static void ironlake_edp_panel_vdd_on(struct intel_dp *intel_dp) @@ -921,15 +975,16 @@ static void ironlake_edp_panel_vdd_on(struct intel_dp *intel_dp)  	     "eDP VDD already requested on\n");  	intel_dp->want_panel_vdd = true; +  	if (ironlake_edp_have_panel_vdd(intel_dp)) {  		DRM_DEBUG_KMS("eDP VDD already on\n");  		return;  	} -	ironlake_wait_panel_off(intel_dp); -	pp = I915_READ(PCH_PP_CONTROL); -	pp &= ~PANEL_UNLOCK_MASK; -	pp |= PANEL_UNLOCK_REGS; +	if (!ironlake_edp_have_panel_power(intel_dp)) +		ironlake_wait_panel_power_cycle(intel_dp); + +	pp = ironlake_get_pp_control(dev_priv);  	pp |= EDP_FORCE_VDD;  	I915_WRITE(PCH_PP_CONTROL, pp);  	POSTING_READ(PCH_PP_CONTROL); @@ -952,9 +1007,7 @@ static void ironlake_panel_vdd_off_sync(struct intel_dp *intel_dp)  	u32 pp;  	if (!intel_dp->want_panel_vdd && ironlake_edp_have_panel_vdd(intel_dp)) { -		pp = I915_READ(PCH_PP_CONTROL); -		pp &= ~PANEL_UNLOCK_MASK; -		pp |= PANEL_UNLOCK_REGS; +		pp = ironlake_get_pp_control(dev_priv);  		pp &= ~EDP_FORCE_VDD;  		I915_WRITE(PCH_PP_CONTROL, pp);  		POSTING_READ(PCH_PP_CONTROL); @@ -962,7 +1015,8 @@ static void ironlake_panel_vdd_off_sync(struct intel_dp *intel_dp)  		/* Make sure sequencer is idle before allowing subsequent activity */  		DRM_DEBUG_KMS("PCH_PP_STATUS: 0x%08x PCH_PP_CONTROL: 0x%08x\n",  			      I915_READ(PCH_PP_STATUS), I915_READ(PCH_PP_CONTROL)); -		intel_dp->panel_off_jiffies = jiffies; + +		msleep(intel_dp->panel_power_down_delay);  	}  } @@ -972,9 +1026,9 @@ static void ironlake_panel_vdd_work(struct work_struct *__work)  						 struct intel_dp, panel_vdd_work);  	struct drm_device *dev = intel_dp->base.base.dev; -	mutex_lock(&dev->struct_mutex); +	mutex_lock(&dev->mode_config.mutex);  	ironlake_panel_vdd_off_sync(intel_dp); -	mutex_unlock(&dev->struct_mutex); +	mutex_unlock(&dev->mode_config.mutex);  }  static void ironlake_edp_panel_vdd_off(struct intel_dp *intel_dp, bool sync) @@ -984,7 +1038,7 @@ static void ironlake_edp_panel_vdd_off(struct intel_dp *intel_dp, bool sync)  	DRM_DEBUG_KMS("Turn eDP VDD off %d\n", intel_dp->want_panel_vdd);  	WARN(!intel_dp->want_panel_vdd, "eDP VDD not forced on"); -	 +  	intel_dp->want_panel_vdd = false;  	if (sync) { @@ -1000,23 +1054,25 @@ static void ironlake_edp_panel_vdd_off(struct intel_dp *intel_dp, bool sync)  	}  } -/* Returns true if the panel was already on when called */  static void ironlake_edp_panel_on(struct intel_dp *intel_dp)  {  	struct drm_device *dev = intel_dp->base.base.dev;  	struct drm_i915_private *dev_priv = dev->dev_private; -	u32 pp, idle_on_mask = PP_ON | PP_SEQUENCE_STATE_ON_IDLE; +	u32 pp;  	if (!is_edp(intel_dp))  		return; -	if (ironlake_edp_have_panel_power(intel_dp)) + +	DRM_DEBUG_KMS("Turn eDP power on\n"); + +	if (ironlake_edp_have_panel_power(intel_dp)) { +		DRM_DEBUG_KMS("eDP power already on\n");  		return; +	} -	ironlake_wait_panel_off(intel_dp); -	pp = I915_READ(PCH_PP_CONTROL); -	pp &= ~PANEL_UNLOCK_MASK; -	pp |= PANEL_UNLOCK_REGS; +	ironlake_wait_panel_power_cycle(intel_dp); +	pp = ironlake_get_pp_control(dev_priv);  	if (IS_GEN5(dev)) {  		/* ILK workaround: disable reset around power sequence */  		pp &= ~PANEL_POWER_RESET; @@ -1025,13 +1081,13 @@ static void ironlake_edp_panel_on(struct intel_dp *intel_dp)  	}  	pp |= POWER_TARGET_ON; +	if (!IS_GEN5(dev)) +		pp |= PANEL_POWER_RESET; +  	I915_WRITE(PCH_PP_CONTROL, pp);  	POSTING_READ(PCH_PP_CONTROL); -	if (wait_for((I915_READ(PCH_PP_STATUS) & idle_on_mask) == idle_on_mask, -		     5000)) -		DRM_ERROR("panel on wait timed out: 0x%08x\n", -			  I915_READ(PCH_PP_STATUS)); +	ironlake_wait_panel_on(intel_dp);  	if (IS_GEN5(dev)) {  		pp |= PANEL_POWER_RESET; /* restore panel reset bit */ @@ -1040,46 +1096,25 @@ static void ironlake_edp_panel_on(struct intel_dp *intel_dp)  	}  } -static void ironlake_edp_panel_off(struct drm_encoder *encoder) +static void ironlake_edp_panel_off(struct intel_dp *intel_dp)  { -	struct intel_dp *intel_dp = enc_to_intel_dp(encoder); -	struct drm_device *dev = encoder->dev; +	struct drm_device *dev = intel_dp->base.base.dev;  	struct drm_i915_private *dev_priv = dev->dev_private; -	u32 pp, idle_off_mask = PP_ON | PP_SEQUENCE_MASK | -		PP_CYCLE_DELAY_ACTIVE | PP_SEQUENCE_STATE_MASK; +	u32 pp;  	if (!is_edp(intel_dp))  		return; -	pp = I915_READ(PCH_PP_CONTROL); -	pp &= ~PANEL_UNLOCK_MASK; -	pp |= PANEL_UNLOCK_REGS; -	if (IS_GEN5(dev)) { -		/* ILK workaround: disable reset around power sequence */ -		pp &= ~PANEL_POWER_RESET; -		I915_WRITE(PCH_PP_CONTROL, pp); -		POSTING_READ(PCH_PP_CONTROL); -	} +	DRM_DEBUG_KMS("Turn eDP power off\n"); -	intel_dp->panel_off_jiffies = jiffies; +	WARN(intel_dp->want_panel_vdd, "Cannot turn power off while VDD is on\n"); -	if (IS_GEN5(dev)) { -		pp &= ~POWER_TARGET_ON; -		I915_WRITE(PCH_PP_CONTROL, pp); -		POSTING_READ(PCH_PP_CONTROL); -		pp &= ~POWER_TARGET_ON; -		I915_WRITE(PCH_PP_CONTROL, pp); -		POSTING_READ(PCH_PP_CONTROL); -		msleep(intel_dp->panel_power_cycle_delay); - -		if (wait_for((I915_READ(PCH_PP_STATUS) & idle_off_mask) == 0, 5000)) -			DRM_ERROR("panel off wait timed out: 0x%08x\n", -				  I915_READ(PCH_PP_STATUS)); +	pp = ironlake_get_pp_control(dev_priv); +	pp &= ~(POWER_TARGET_ON | EDP_FORCE_VDD | PANEL_POWER_RESET | EDP_BLC_ENABLE); +	I915_WRITE(PCH_PP_CONTROL, pp); +	POSTING_READ(PCH_PP_CONTROL); -		pp |= PANEL_POWER_RESET; /* restore panel reset bit */ -		I915_WRITE(PCH_PP_CONTROL, pp); -		POSTING_READ(PCH_PP_CONTROL); -	} +	ironlake_wait_panel_off(intel_dp);  }  static void ironlake_edp_backlight_on(struct intel_dp *intel_dp) @@ -1099,9 +1134,7 @@ static void ironlake_edp_backlight_on(struct intel_dp *intel_dp)  	 * allowing it to appear.  	 */  	msleep(intel_dp->backlight_on_delay); -	pp = I915_READ(PCH_PP_CONTROL); -	pp &= ~PANEL_UNLOCK_MASK; -	pp |= PANEL_UNLOCK_REGS; +	pp = ironlake_get_pp_control(dev_priv);  	pp |= EDP_BLC_ENABLE;  	I915_WRITE(PCH_PP_CONTROL, pp);  	POSTING_READ(PCH_PP_CONTROL); @@ -1117,9 +1150,7 @@ static void ironlake_edp_backlight_off(struct intel_dp *intel_dp)  		return;  	DRM_DEBUG_KMS("\n"); -	pp = I915_READ(PCH_PP_CONTROL); -	pp &= ~PANEL_UNLOCK_MASK; -	pp |= PANEL_UNLOCK_REGS; +	pp = ironlake_get_pp_control(dev_priv);  	pp &= ~EDP_BLC_ENABLE;  	I915_WRITE(PCH_PP_CONTROL, pp);  	POSTING_READ(PCH_PP_CONTROL); @@ -1187,17 +1218,18 @@ static void intel_dp_prepare(struct drm_encoder *encoder)  {  	struct intel_dp *intel_dp = enc_to_intel_dp(encoder); +	ironlake_edp_backlight_off(intel_dp); +	ironlake_edp_panel_off(intel_dp); +  	/* Wake up the sink first */  	ironlake_edp_panel_vdd_on(intel_dp);  	intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON); +	intel_dp_link_down(intel_dp);  	ironlake_edp_panel_vdd_off(intel_dp, false);  	/* Make sure the panel is off before trying to  	 * change the mode  	 */ -	ironlake_edp_backlight_off(intel_dp); -	intel_dp_link_down(intel_dp); -	ironlake_edp_panel_off(encoder);  }  static void intel_dp_commit(struct drm_encoder *encoder) @@ -1211,7 +1243,6 @@ static void intel_dp_commit(struct drm_encoder *encoder)  	intel_dp_start_link_train(intel_dp);  	ironlake_edp_panel_on(intel_dp);  	ironlake_edp_panel_vdd_off(intel_dp, true); -  	intel_dp_complete_link_train(intel_dp);  	ironlake_edp_backlight_on(intel_dp); @@ -1230,16 +1261,20 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode)  	uint32_t dp_reg = I915_READ(intel_dp->output_reg);  	if (mode != DRM_MODE_DPMS_ON) { +		ironlake_edp_backlight_off(intel_dp); +		ironlake_edp_panel_off(intel_dp); +  		ironlake_edp_panel_vdd_on(intel_dp); -		if (is_edp(intel_dp)) -			ironlake_edp_backlight_off(intel_dp);  		intel_dp_sink_dpms(intel_dp, mode);  		intel_dp_link_down(intel_dp); -		ironlake_edp_panel_off(encoder); -		if (is_edp(intel_dp) && !is_pch_edp(intel_dp)) -			ironlake_edp_pll_off(encoder);  		ironlake_edp_panel_vdd_off(intel_dp, false); + +		if (is_cpu_edp(intel_dp)) +			ironlake_edp_pll_off(encoder);  	} else { +		if (is_cpu_edp(intel_dp)) +			ironlake_edp_pll_on(encoder); +  		ironlake_edp_panel_vdd_on(intel_dp);  		intel_dp_sink_dpms(intel_dp, mode);  		if (!(dp_reg & DP_PORT_EN)) { @@ -1247,7 +1282,6 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode)  			ironlake_edp_panel_on(intel_dp);  			ironlake_edp_panel_vdd_off(intel_dp, true);  			intel_dp_complete_link_train(intel_dp); -			ironlake_edp_backlight_on(intel_dp);  		} else  			ironlake_edp_panel_vdd_off(intel_dp, false);  		ironlake_edp_backlight_on(intel_dp); @@ -1285,11 +1319,11 @@ intel_dp_aux_native_read_retry(struct intel_dp *intel_dp, uint16_t address,   * link status information   */  static bool -intel_dp_get_link_status(struct intel_dp *intel_dp) +intel_dp_get_link_status(struct intel_dp *intel_dp, uint8_t link_status[DP_LINK_STATUS_SIZE])  {  	return intel_dp_aux_native_read_retry(intel_dp,  					      DP_LANE0_1_STATUS, -					      intel_dp->link_status, +					      link_status,  					      DP_LINK_STATUS_SIZE);  } @@ -1301,27 +1335,25 @@ intel_dp_link_status(uint8_t link_status[DP_LINK_STATUS_SIZE],  }  static uint8_t -intel_get_adjust_request_voltage(uint8_t link_status[DP_LINK_STATUS_SIZE], +intel_get_adjust_request_voltage(uint8_t adjust_request[2],  				 int lane)  { -	int	    i = DP_ADJUST_REQUEST_LANE0_1 + (lane >> 1);  	int	    s = ((lane & 1) ?  			 DP_ADJUST_VOLTAGE_SWING_LANE1_SHIFT :  			 DP_ADJUST_VOLTAGE_SWING_LANE0_SHIFT); -	uint8_t l = intel_dp_link_status(link_status, i); +	uint8_t l = adjust_request[lane>>1];  	return ((l >> s) & 3) << DP_TRAIN_VOLTAGE_SWING_SHIFT;  }  static uint8_t -intel_get_adjust_request_pre_emphasis(uint8_t link_status[DP_LINK_STATUS_SIZE], +intel_get_adjust_request_pre_emphasis(uint8_t adjust_request[2],  				      int lane)  { -	int	    i = DP_ADJUST_REQUEST_LANE0_1 + (lane >> 1);  	int	    s = ((lane & 1) ?  			 DP_ADJUST_PRE_EMPHASIS_LANE1_SHIFT :  			 DP_ADJUST_PRE_EMPHASIS_LANE0_SHIFT); -	uint8_t l = intel_dp_link_status(link_status, i); +	uint8_t l = adjust_request[lane>>1];  	return ((l >> s) & 3) << DP_TRAIN_PRE_EMPHASIS_SHIFT;  } @@ -1344,6 +1376,7 @@ static char	*link_train_names[] = {   * a maximum voltage of 800mV and a maximum pre-emphasis of 6dB   */  #define I830_DP_VOLTAGE_MAX	    DP_TRAIN_VOLTAGE_SWING_800 +#define I830_DP_VOLTAGE_MAX_CPT	    DP_TRAIN_VOLTAGE_SWING_1200  static uint8_t  intel_dp_pre_emphasis_max(uint8_t voltage_swing) @@ -1362,15 +1395,18 @@ intel_dp_pre_emphasis_max(uint8_t voltage_swing)  }  static void -intel_get_adjust_train(struct intel_dp *intel_dp) +intel_get_adjust_train(struct intel_dp *intel_dp, uint8_t link_status[DP_LINK_STATUS_SIZE])  { +	struct drm_device *dev = intel_dp->base.base.dev;  	uint8_t v = 0;  	uint8_t p = 0;  	int lane; +	uint8_t	*adjust_request = link_status + (DP_ADJUST_REQUEST_LANE0_1 - DP_LANE0_1_STATUS); +	int voltage_max;  	for (lane = 0; lane < intel_dp->lane_count; lane++) { -		uint8_t this_v = intel_get_adjust_request_voltage(intel_dp->link_status, lane); -		uint8_t this_p = intel_get_adjust_request_pre_emphasis(intel_dp->link_status, lane); +		uint8_t this_v = intel_get_adjust_request_voltage(adjust_request, lane); +		uint8_t this_p = intel_get_adjust_request_pre_emphasis(adjust_request, lane);  		if (this_v > v)  			v = this_v; @@ -1378,8 +1414,12 @@ intel_get_adjust_train(struct intel_dp *intel_dp)  			p = this_p;  	} -	if (v >= I830_DP_VOLTAGE_MAX) -		v = I830_DP_VOLTAGE_MAX | DP_TRAIN_MAX_SWING_REACHED; +	if (HAS_PCH_CPT(dev) && !is_cpu_edp(intel_dp)) +		voltage_max = I830_DP_VOLTAGE_MAX_CPT; +	else +		voltage_max = I830_DP_VOLTAGE_MAX; +	if (v >= voltage_max) +		v = voltage_max | DP_TRAIN_MAX_SWING_REACHED;  	if (p >= intel_dp_pre_emphasis_max(v))  		p = intel_dp_pre_emphasis_max(v) | DP_TRAIN_MAX_PRE_EMPHASIS_REACHED; @@ -1389,7 +1429,7 @@ intel_get_adjust_train(struct intel_dp *intel_dp)  }  static uint32_t -intel_dp_signal_levels(uint8_t train_set, int lane_count) +intel_dp_signal_levels(uint8_t train_set)  {  	uint32_t	signal_levels = 0; @@ -1458,9 +1498,8 @@ static uint8_t  intel_get_lane_status(uint8_t link_status[DP_LINK_STATUS_SIZE],  		      int lane)  { -	int i = DP_LANE0_1_STATUS + (lane >> 1);  	int s = (lane & 1) * 4; -	uint8_t l = intel_dp_link_status(link_status, i); +	uint8_t l = link_status[lane>>1];  	return (l >> s) & 0xf;  } @@ -1485,18 +1524,18 @@ intel_clock_recovery_ok(uint8_t link_status[DP_LINK_STATUS_SIZE], int lane_count  			 DP_LANE_CHANNEL_EQ_DONE|\  			 DP_LANE_SYMBOL_LOCKED)  static bool -intel_channel_eq_ok(struct intel_dp *intel_dp) +intel_channel_eq_ok(struct intel_dp *intel_dp, uint8_t link_status[DP_LINK_STATUS_SIZE])  {  	uint8_t lane_align;  	uint8_t lane_status;  	int lane; -	lane_align = intel_dp_link_status(intel_dp->link_status, +	lane_align = intel_dp_link_status(link_status,  					  DP_LANE_ALIGN_STATUS_UPDATED);  	if ((lane_align & DP_INTERLANE_ALIGN_DONE) == 0)  		return false;  	for (lane = 0; lane < intel_dp->lane_count; lane++) { -		lane_status = intel_get_lane_status(intel_dp->link_status, lane); +		lane_status = intel_get_lane_status(link_status, lane);  		if ((lane_status & CHANNEL_EQ_BITS) != CHANNEL_EQ_BITS)  			return false;  	} @@ -1521,8 +1560,9 @@ intel_dp_set_link_train(struct intel_dp *intel_dp,  	ret = intel_dp_aux_native_write(intel_dp,  					DP_TRAINING_LANE0_SET, -					intel_dp->train_set, 4); -	if (ret != 4) +					intel_dp->train_set, +					intel_dp->lane_count); +	if (ret != intel_dp->lane_count)  		return false;  	return true; @@ -1538,7 +1578,7 @@ intel_dp_start_link_train(struct intel_dp *intel_dp)  	int i;  	uint8_t voltage;  	bool clock_recovery = false; -	int tries; +	int voltage_tries, loop_tries;  	u32 reg;  	uint32_t DP = intel_dp->DP; @@ -1565,16 +1605,20 @@ intel_dp_start_link_train(struct intel_dp *intel_dp)  		DP &= ~DP_LINK_TRAIN_MASK;  	memset(intel_dp->train_set, 0, 4);  	voltage = 0xff; -	tries = 0; +	voltage_tries = 0; +	loop_tries = 0;  	clock_recovery = false;  	for (;;) {  		/* Use intel_dp->train_set[0] to set the voltage and pre emphasis values */ +		uint8_t	    link_status[DP_LINK_STATUS_SIZE];  		uint32_t    signal_levels; -		if (IS_GEN6(dev) && is_edp(intel_dp)) { + +		if (IS_GEN6(dev) && is_cpu_edp(intel_dp)) {  			signal_levels = intel_gen6_edp_signal_levels(intel_dp->train_set[0]);  			DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels;  		} else { -			signal_levels = intel_dp_signal_levels(intel_dp->train_set[0], intel_dp->lane_count); +			signal_levels = intel_dp_signal_levels(intel_dp->train_set[0]); +			DRM_DEBUG_KMS("training pattern 1 signal levels %08x\n", signal_levels);  			DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels;  		} @@ -1590,10 +1634,13 @@ intel_dp_start_link_train(struct intel_dp *intel_dp)  		/* Set training pattern 1 */  		udelay(100); -		if (!intel_dp_get_link_status(intel_dp)) +		if (!intel_dp_get_link_status(intel_dp, link_status)) { +			DRM_ERROR("failed to get link status\n");  			break; +		} -		if (intel_clock_recovery_ok(intel_dp->link_status, intel_dp->lane_count)) { +		if (intel_clock_recovery_ok(link_status, intel_dp->lane_count)) { +			DRM_DEBUG_KMS("clock recovery OK\n");  			clock_recovery = true;  			break;  		} @@ -1602,20 +1649,30 @@ intel_dp_start_link_train(struct intel_dp *intel_dp)  		for (i = 0; i < intel_dp->lane_count; i++)  			if ((intel_dp->train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0)  				break; -		if (i == intel_dp->lane_count) -			break; +		if (i == intel_dp->lane_count) { +			++loop_tries; +			if (loop_tries == 5) { +				DRM_DEBUG_KMS("too many full retries, give up\n"); +				break; +			} +			memset(intel_dp->train_set, 0, 4); +			voltage_tries = 0; +			continue; +		}  		/* Check to see if we've tried the same voltage 5 times */  		if ((intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) == voltage) { -			++tries; -			if (tries == 5) +			++voltage_tries; +			if (voltage_tries == 5) { +				DRM_DEBUG_KMS("too many voltage retries, give up\n");  				break; +			}  		} else -			tries = 0; +			voltage_tries = 0;  		voltage = intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK;  		/* Compute new intel_dp->train_set as requested by target */ -		intel_get_adjust_train(intel_dp); +		intel_get_adjust_train(intel_dp, link_status);  	}  	intel_dp->DP = DP; @@ -1638,6 +1695,7 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp)  	for (;;) {  		/* Use intel_dp->train_set[0] to set the voltage and pre emphasis values */  		uint32_t    signal_levels; +		uint8_t	    link_status[DP_LINK_STATUS_SIZE];  		if (cr_tries > 5) {  			DRM_ERROR("failed to train DP, aborting\n"); @@ -1645,11 +1703,11 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp)  			break;  		} -		if (IS_GEN6(dev) && is_edp(intel_dp)) { +		if (IS_GEN6(dev) && is_cpu_edp(intel_dp)) {  			signal_levels = intel_gen6_edp_signal_levels(intel_dp->train_set[0]);  			DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels;  		} else { -			signal_levels = intel_dp_signal_levels(intel_dp->train_set[0], intel_dp->lane_count); +			signal_levels = intel_dp_signal_levels(intel_dp->train_set[0]);  			DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels;  		} @@ -1665,17 +1723,17 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp)  			break;  		udelay(400); -		if (!intel_dp_get_link_status(intel_dp)) +		if (!intel_dp_get_link_status(intel_dp, link_status))  			break;  		/* Make sure clock is still ok */ -		if (!intel_clock_recovery_ok(intel_dp->link_status, intel_dp->lane_count)) { +		if (!intel_clock_recovery_ok(link_status, intel_dp->lane_count)) {  			intel_dp_start_link_train(intel_dp);  			cr_tries++;  			continue;  		} -		if (intel_channel_eq_ok(intel_dp)) { +		if (intel_channel_eq_ok(intel_dp, link_status)) {  			channel_eq = true;  			break;  		} @@ -1690,7 +1748,7 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp)  		}  		/* Compute new intel_dp->train_set as requested by target */ -		intel_get_adjust_train(intel_dp); +		intel_get_adjust_train(intel_dp, link_status);  		++tries;  	} @@ -1735,8 +1793,12 @@ intel_dp_link_down(struct intel_dp *intel_dp)  	msleep(17); -	if (is_edp(intel_dp)) -		DP |= DP_LINK_TRAIN_OFF; +	if (is_edp(intel_dp)) { +		if (HAS_PCH_CPT(dev) && !is_cpu_edp(intel_dp)) +			DP |= DP_LINK_TRAIN_OFF_CPT; +		else +			DP |= DP_LINK_TRAIN_OFF; +	}  	if (!HAS_PCH_CPT(dev) &&  	    I915_READ(intel_dp->output_reg) & DP_PIPEB_SELECT) { @@ -1822,6 +1884,7 @@ static void  intel_dp_check_link_status(struct intel_dp *intel_dp)  {  	u8 sink_irq_vector; +	u8 link_status[DP_LINK_STATUS_SIZE];  	if (intel_dp->dpms_mode != DRM_MODE_DPMS_ON)  		return; @@ -1830,7 +1893,7 @@ intel_dp_check_link_status(struct intel_dp *intel_dp)  		return;  	/* Try to read receiver status if the link appears to be up */ -	if (!intel_dp_get_link_status(intel_dp)) { +	if (!intel_dp_get_link_status(intel_dp, link_status)) {  		intel_dp_link_down(intel_dp);  		return;  	} @@ -1855,7 +1918,7 @@ intel_dp_check_link_status(struct intel_dp *intel_dp)  			DRM_DEBUG_DRIVER("CP or sink specific irq unhandled\n");  	} -	if (!intel_channel_eq_ok(intel_dp)) { +	if (!intel_channel_eq_ok(intel_dp, link_status)) {  		DRM_DEBUG_KMS("%s: channel EQ not ok, retraining\n",  			      drm_get_encoder_name(&intel_dp->base.base));  		intel_dp_start_link_train(intel_dp); @@ -2179,7 +2242,8 @@ intel_trans_dp_port_sel(struct drm_crtc *crtc)  			continue;  		intel_dp = enc_to_intel_dp(encoder); -		if (intel_dp->base.type == INTEL_OUTPUT_DISPLAYPORT) +		if (intel_dp->base.type == INTEL_OUTPUT_DISPLAYPORT || +		    intel_dp->base.type == INTEL_OUTPUT_EDP)  			return intel_dp->output_reg;  	} @@ -2321,7 +2385,7 @@ intel_dp_init(struct drm_device *dev, int output_reg)  		cur.t8 = (pp_on & PANEL_LIGHT_ON_DELAY_MASK) >>  			PANEL_LIGHT_ON_DELAY_SHIFT; -		 +  		cur.t9 = (pp_off & PANEL_LIGHT_OFF_DELAY_MASK) >>  			PANEL_LIGHT_OFF_DELAY_SHIFT; @@ -2354,11 +2418,10 @@ 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->panel_off_jiffies = jiffies - intel_dp->panel_power_down_delay; -  		ironlake_edp_panel_vdd_on(intel_dp);  		ret = intel_dp_get_dpcd(intel_dp);  		ironlake_edp_panel_vdd_off(intel_dp, false); +  		if (ret) {  			if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11)  				dev_priv->no_aux_handshake = diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 499d4c0dbee..21f60b7d69a 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -326,7 +326,8 @@ static int intel_panel_update_status(struct backlight_device *bd)  static int intel_panel_get_brightness(struct backlight_device *bd)  {  	struct drm_device *dev = bl_get_data(bd); -	return intel_panel_get_backlight(dev); +	struct drm_i915_private *dev_priv = dev->dev_private; +	return dev_priv->backlight_level;  }  static const struct backlight_ops intel_panel_bl_ops = { diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index 032a8209813..5fc201b49d3 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c @@ -640,10 +640,9 @@ static int  nv50_pll_set(struct drm_device *dev, uint32_t reg, uint32_t clk)  {  	struct drm_nouveau_private *dev_priv = dev->dev_private; -	uint32_t reg0 = nv_rd32(dev, reg + 0); -	uint32_t reg1 = nv_rd32(dev, reg + 4);  	struct nouveau_pll_vals pll;  	struct pll_lims pll_limits; +	u32 ctrl, mask, coef;  	int ret;  	ret = get_pll_limits(dev, reg, &pll_limits); @@ -654,15 +653,20 @@ nv50_pll_set(struct drm_device *dev, uint32_t reg, uint32_t clk)  	if (!clk)  		return -ERANGE; -	reg0 = (reg0 & 0xfff8ffff) | (pll.log2P << 16); -	reg1 = (reg1 & 0xffff0000) | (pll.N1 << 8) | pll.M1; - -	if (dev_priv->vbios.execute) { -		still_alive(); -		nv_wr32(dev, reg + 4, reg1); -		nv_wr32(dev, reg + 0, reg0); +	coef = pll.N1 << 8 | pll.M1; +	ctrl = pll.log2P << 16; +	mask = 0x00070000; +	if (reg == 0x004008) { +		mask |= 0x01f80000; +		ctrl |= (pll_limits.log2p_bias << 19); +		ctrl |= (pll.log2P << 22);  	} +	if (!dev_priv->vbios.execute) +		return 0; + +	nv_mask(dev, reg + 0, mask, ctrl); +	nv_wr32(dev, reg + 4, coef);  	return 0;  } diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 7226f419e17..7cc37e69086 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -148,7 +148,7 @@ set_placement_range(struct nouveau_bo *nvbo, uint32_t type)  	if (dev_priv->card_type == NV_10 &&  	    nvbo->tile_mode && (type & TTM_PL_FLAG_VRAM) && -	    nvbo->bo.mem.num_pages < vram_pages / 2) { +	    nvbo->bo.mem.num_pages < vram_pages / 4) {  		/*  		 * Make sure that the color and depth buffers are handled  		 * by independent memory controller units. Up to a 9x diff --git a/drivers/gpu/drm/nouveau/nouveau_channel.c b/drivers/gpu/drm/nouveau/nouveau_channel.c index a319d5646ea..bb6ec9ef867 100644 --- a/drivers/gpu/drm/nouveau/nouveau_channel.c +++ b/drivers/gpu/drm/nouveau/nouveau_channel.c @@ -158,6 +158,7 @@ nouveau_channel_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret,  	INIT_LIST_HEAD(&chan->nvsw.vbl_wait);  	INIT_LIST_HEAD(&chan->nvsw.flip);  	INIT_LIST_HEAD(&chan->fence.pending); +	spin_lock_init(&chan->fence.lock);  	/* setup channel's memory and vm */  	ret = nouveau_gpuobj_channel_init(chan, vram_handle, gart_handle); diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c index e0d275e1c96..cea6696b190 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c @@ -710,7 +710,7 @@ nouveau_connector_mode_valid(struct drm_connector *connector,  	case OUTPUT_DP:  		max_clock  = nv_encoder->dp.link_nr;  		max_clock *= nv_encoder->dp.link_bw; -		clock = clock * nouveau_connector_bpp(connector) / 8; +		clock = clock * nouveau_connector_bpp(connector) / 10;  		break;  	default:  		BUG_ON(1); diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c index 14a8627efe4..3a4cc32b9e4 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c @@ -487,6 +487,7 @@ int nouveau_fbcon_init(struct drm_device *dev)  {  	struct drm_nouveau_private *dev_priv = dev->dev_private;  	struct nouveau_fbdev *nfbdev; +	int preferred_bpp;  	int ret;  	nfbdev = kzalloc(sizeof(struct nouveau_fbdev), GFP_KERNEL); @@ -505,7 +506,15 @@ int nouveau_fbcon_init(struct drm_device *dev)  	}  	drm_fb_helper_single_add_all_connectors(&nfbdev->helper); -	drm_fb_helper_initial_config(&nfbdev->helper, 32); + +	if (dev_priv->vram_size <= 32 * 1024 * 1024) +		preferred_bpp = 8; +	else if (dev_priv->vram_size <= 64 * 1024 * 1024) +		preferred_bpp = 16; +	else +		preferred_bpp = 32; + +	drm_fb_helper_initial_config(&nfbdev->helper, preferred_bpp);  	return 0;  } diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c index 81116cfea27..2f6daae68b9 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fence.c +++ b/drivers/gpu/drm/nouveau/nouveau_fence.c @@ -539,8 +539,6 @@ nouveau_fence_channel_init(struct nouveau_channel *chan)  			return ret;  	} -	INIT_LIST_HEAD(&chan->fence.pending); -	spin_lock_init(&chan->fence.lock);  	atomic_set(&chan->fence.last_sequence_irq, 0);  	return 0;  } diff --git a/drivers/gpu/drm/nouveau/nouveau_i2c.c b/drivers/gpu/drm/nouveau/nouveau_i2c.c index c6143df48b9..d39b2202b19 100644 --- a/drivers/gpu/drm/nouveau/nouveau_i2c.c +++ b/drivers/gpu/drm/nouveau/nouveau_i2c.c @@ -333,7 +333,7 @@ nouveau_i2c_identify(struct drm_device *dev, const char *what,  	NV_DEBUG(dev, "Probing %ss on I2C bus: %d\n", what, index); -	for (i = 0; info[i].addr; i++) { +	for (i = 0; i2c && info[i].addr; i++) {  		if (nouveau_probe_i2c_addr(i2c, info[i].addr) &&  		    (!match || match(i2c, &info[i]))) {  			NV_INFO(dev, "Detected %s: %s\n", what, info[i].type); diff --git a/drivers/gpu/drm/nouveau/nouveau_perf.c b/drivers/gpu/drm/nouveau/nouveau_perf.c index 9f178aa9416..33d03fbf00d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_perf.c +++ b/drivers/gpu/drm/nouveau/nouveau_perf.c @@ -239,7 +239,7 @@ nouveau_perf_init(struct drm_device *dev)  	if(version == 0x15) {  		memtimings->timing =  				kcalloc(entries, sizeof(*memtimings->timing), GFP_KERNEL); -		if(!memtimings) { +		if (!memtimings->timing) {  			NV_WARN(dev,"Could not allocate memtiming table\n");  			return;  		} diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index 82478e0998e..d8831ab42bb 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c @@ -579,6 +579,14 @@ nouveau_card_init(struct drm_device *dev)  	if (ret)  		goto out_display_early; +	/* workaround an odd issue on nvc1 by disabling the device's +	 * nosnoop capability.  hopefully won't cause issues until a +	 * better fix is found - assuming there is one... +	 */ +	if (dev_priv->chipset == 0xc1) { +		nv_mask(dev, 0x00088080, 0x00000800, 0x00000000); +	} +  	nouveau_pm_init(dev);  	ret = engine->vram.init(dev); @@ -1102,12 +1110,13 @@ int nouveau_load(struct drm_device *dev, unsigned long flags)  	dev_priv->noaccel = !!nouveau_noaccel;  	if (nouveau_noaccel == -1) {  		switch (dev_priv->chipset) { -		case 0xc1: /* known broken */ -		case 0xc8: /* never tested */ +#if 0 +		case 0xXX: /* known broken */  			NV_INFO(dev, "acceleration disabled by default, pass "  				     "noaccel=0 to force enable\n");  			dev_priv->noaccel = true;  			break; +#endif  		default:  			dev_priv->noaccel = false;  			break; diff --git a/drivers/gpu/drm/nouveau/nv40_pm.c b/drivers/gpu/drm/nouveau/nv40_pm.c index bbc0b9c7e1f..e676b0d5347 100644 --- a/drivers/gpu/drm/nouveau/nv40_pm.c +++ b/drivers/gpu/drm/nouveau/nv40_pm.c @@ -57,12 +57,14 @@ read_pll_2(struct drm_device *dev, u32 reg)  	int P = (ctrl & 0x00070000) >> 16;  	u32 ref = 27000, clk = 0; -	if (ctrl & 0x80000000) +	if ((ctrl & 0x80000000) && M1) {  		clk = ref * N1 / M1; - -	if (!(ctrl & 0x00000100)) { -		if (ctrl & 0x40000000) -			clk = clk * N2 / M2; +		if ((ctrl & 0x40000100) == 0x40000000) { +			if (M2) +				clk = clk * N2 / M2; +			else +				clk = 0; +		}  	}  	return clk >> P; @@ -177,6 +179,11 @@ nv40_pm_clocks_pre(struct drm_device *dev, struct nouveau_pm_level *perflvl)  	}  	/* memory clock */ +	if (!perflvl->memory) { +		info->mpll_ctrl = 0x00000000; +		goto out; +	} +  	ret = nv40_calc_pll(dev, 0x004020, &pll, perflvl->memory,  			    &N1, &M1, &N2, &M2, &log2P);  	if (ret < 0) @@ -264,6 +271,9 @@ nv40_pm_clocks_set(struct drm_device *dev, void *pre_state)  	mdelay(5);  	nv_mask(dev, 0x00c040, 0x00000333, info->ctrl); +	if (!info->mpll_ctrl) +		goto resume; +  	/* wait for vblank start on active crtcs, disable memory access */  	for (i = 0; i < 2; i++) {  		if (!(crtc_mask & (1 << i))) diff --git a/drivers/gpu/drm/nouveau/nv50_graph.c b/drivers/gpu/drm/nouveau/nv50_graph.c index 8c979b31ff6..ac601f7c4e1 100644 --- a/drivers/gpu/drm/nouveau/nv50_graph.c +++ b/drivers/gpu/drm/nouveau/nv50_graph.c @@ -131,8 +131,8 @@ nv50_graph_init(struct drm_device *dev, int engine)  	NV_DEBUG(dev, "\n");  	/* master reset */ -	nv_mask(dev, 0x000200, 0x00200100, 0x00000000); -	nv_mask(dev, 0x000200, 0x00200100, 0x00200100); +	nv_mask(dev, 0x000200, 0x00201000, 0x00000000); +	nv_mask(dev, 0x000200, 0x00201000, 0x00201000);  	nv_wr32(dev, 0x40008c, 0x00000004); /* HW_CTX_SWITCH_ENABLED */  	/* reset/enable traps and interrupts */ diff --git a/drivers/gpu/drm/nouveau/nv50_grctx.c b/drivers/gpu/drm/nouveau/nv50_grctx.c index d05c2c3b244..4b46d696856 100644 --- a/drivers/gpu/drm/nouveau/nv50_grctx.c +++ b/drivers/gpu/drm/nouveau/nv50_grctx.c @@ -601,7 +601,7 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx)  					gr_def(ctx, offset + 0x1c, 0x00880000);  					break;  				case 0x86: -					gr_def(ctx, offset + 0x1c, 0x008c0000); +					gr_def(ctx, offset + 0x1c, 0x018c0000);  					break;  				case 0x92:  				case 0x96: diff --git a/drivers/gpu/drm/nouveau/nv50_vram.c b/drivers/gpu/drm/nouveau/nv50_vram.c index 9da23838e63..2e45e57fd86 100644 --- a/drivers/gpu/drm/nouveau/nv50_vram.c +++ b/drivers/gpu/drm/nouveau/nv50_vram.c @@ -160,7 +160,7 @@ nv50_vram_rblock(struct drm_device *dev)  	colbits  =  (r4 & 0x0000f000) >> 12;  	rowbitsa = ((r4 & 0x000f0000) >> 16) + 8;  	rowbitsb = ((r4 & 0x00f00000) >> 20) + 8; -	banks    = ((r4 & 0x01000000) ? 8 : 4); +	banks    = 1 << (((r4 & 0x03000000) >> 24) + 2);  	rowsize = parts * banks * (1 << colbits) * 8;  	predicted = rowsize << rowbitsa; diff --git a/drivers/gpu/drm/nouveau/nvc0_graph.c b/drivers/gpu/drm/nouveau/nvc0_graph.c index bbdbc51830c..a74e501afd2 100644 --- a/drivers/gpu/drm/nouveau/nvc0_graph.c +++ b/drivers/gpu/drm/nouveau/nvc0_graph.c @@ -157,8 +157,8 @@ nvc0_graph_create_context_mmio_list(struct nouveau_channel *chan)  	struct nvc0_graph_priv *priv = nv_engine(chan->dev, NVOBJ_ENGINE_GR);  	struct nvc0_graph_chan *grch = chan->engctx[NVOBJ_ENGINE_GR];  	struct drm_device *dev = chan->dev; +	struct drm_nouveau_private *dev_priv = dev->dev_private;  	int i = 0, gpc, tp, ret; -	u32 magic;  	ret = nouveau_gpuobj_new(dev, chan, 0x2000, 256, NVOBJ_FLAG_VM,  				 &grch->unk408004); @@ -207,14 +207,37 @@ nvc0_graph_create_context_mmio_list(struct nouveau_channel *chan)  	nv_wo32(grch->mmio, i++ * 4, 0x0041880c);  	nv_wo32(grch->mmio, i++ * 4, 0x80000018); -	magic = 0x02180000; -	nv_wo32(grch->mmio, i++ * 4, 0x00405830); -	nv_wo32(grch->mmio, i++ * 4, magic); -	for (gpc = 0; gpc < priv->gpc_nr; gpc++) { -		for (tp = 0; tp < priv->tp_nr[gpc]; tp++, magic += 0x0324) { -			u32 reg = 0x504520 + (gpc * 0x8000) + (tp * 0x0800); -			nv_wo32(grch->mmio, i++ * 4, reg); -			nv_wo32(grch->mmio, i++ * 4, magic); +	if (dev_priv->chipset != 0xc1) { +		u32 magic = 0x02180000; +		nv_wo32(grch->mmio, i++ * 4, 0x00405830); +		nv_wo32(grch->mmio, i++ * 4, magic); +		for (gpc = 0; gpc < priv->gpc_nr; gpc++) { +			for (tp = 0; tp < priv->tp_nr[gpc]; tp++) { +				u32 reg = TP_UNIT(gpc, tp, 0x520); +				nv_wo32(grch->mmio, i++ * 4, reg); +				nv_wo32(grch->mmio, i++ * 4, magic); +				magic += 0x0324; +			} +		} +	} else { +		u32 magic = 0x02180000; +		nv_wo32(grch->mmio, i++ * 4, 0x00405830); +		nv_wo32(grch->mmio, i++ * 4, magic | 0x0000218); +		nv_wo32(grch->mmio, i++ * 4, 0x004064c4); +		nv_wo32(grch->mmio, i++ * 4, 0x0086ffff); +		for (gpc = 0; gpc < priv->gpc_nr; gpc++) { +			for (tp = 0; tp < priv->tp_nr[gpc]; tp++) { +				u32 reg = TP_UNIT(gpc, tp, 0x520); +				nv_wo32(grch->mmio, i++ * 4, reg); +				nv_wo32(grch->mmio, i++ * 4, (1 << 28) | magic); +				magic += 0x0324; +			} +			for (tp = 0; tp < priv->tp_nr[gpc]; tp++) { +				u32 reg = TP_UNIT(gpc, tp, 0x544); +				nv_wo32(grch->mmio, i++ * 4, reg); +				nv_wo32(grch->mmio, i++ * 4, magic); +				magic += 0x0324; +			}  		}  	} diff --git a/drivers/gpu/drm/nouveau/nvc0_grctx.c b/drivers/gpu/drm/nouveau/nvc0_grctx.c index dd0e6a736b3..96b0b93d94c 100644 --- a/drivers/gpu/drm/nouveau/nvc0_grctx.c +++ b/drivers/gpu/drm/nouveau/nvc0_grctx.c @@ -1812,6 +1812,7 @@ nvc0_grctx_generate(struct nouveau_channel *chan)  		/* calculate first set of magics */  		memcpy(tpnr, priv->tp_nr, sizeof(priv->tp_nr)); +		gpc = -1;  		for (tp = 0; tp < priv->tp_total; tp++) {  			do {  				gpc = (gpc + 1) % priv->gpc_nr; @@ -1861,30 +1862,26 @@ nvc0_grctx_generate(struct nouveau_channel *chan)  	if (1) {  		u32 tp_mask = 0, tp_set = 0; -		u8  tpnr[GPC_MAX]; +		u8  tpnr[GPC_MAX], a, b;  		memcpy(tpnr, priv->tp_nr, sizeof(priv->tp_nr));  		for (gpc = 0; gpc < priv->gpc_nr; gpc++)  			tp_mask |= ((1 << priv->tp_nr[gpc]) - 1) << (gpc * 8); -		gpc = -1; -		for (i = 0, gpc = -1; i < 32; i++) { -			int ltp = i * (priv->tp_total - 1) / 32; - -			do { -				gpc = (gpc + 1) % priv->gpc_nr; -			} while (!tpnr[gpc]); -			tp = priv->tp_nr[gpc] - tpnr[gpc]--; +		for (i = 0, gpc = -1, b = -1; i < 32; i++) { +			a = (i * (priv->tp_total - 1)) / 32; +			if (a != b) { +				b = a; +				do { +					gpc = (gpc + 1) % priv->gpc_nr; +				} while (!tpnr[gpc]); +				tp = priv->tp_nr[gpc] - tpnr[gpc]--; -			tp_set |= 1 << ((gpc * 8) + tp); +				tp_set |= 1 << ((gpc * 8) + tp); +			} -			do { -				nv_wr32(dev, 0x406800 + (i * 0x20), tp_set); -				tp_set ^= tp_mask; -				nv_wr32(dev, 0x406c00 + (i * 0x20), tp_set); -				tp_set ^= tp_mask; -			} while (ltp == (++i * (priv->tp_total - 1) / 32)); -			i--; +			nv_wr32(dev, 0x406800 + (i * 0x20), tp_set); +			nv_wr32(dev, 0x406c00 + (i * 0x20), tp_set ^ tp_mask);  		}  	} diff --git a/drivers/gpu/drm/nouveau/nvc0_vram.c b/drivers/gpu/drm/nouveau/nvc0_vram.c index edbfe9360ae..ce984d573a5 100644 --- a/drivers/gpu/drm/nouveau/nvc0_vram.c +++ b/drivers/gpu/drm/nouveau/nvc0_vram.c @@ -43,7 +43,7 @@ static const u8 types[256] = {  	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  	0, 0, 0, 3, 3, 3, 3, 1, 1, 1, 1, 0, 0, 0, 0, 0,  	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, -	3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, +	3, 3, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3,  	3, 3, 0, 0, 0, 0, 0, 0, 3, 0, 0, 3, 0, 3, 0, 3,  	3, 0, 3, 3, 3, 3, 3, 0, 0, 3, 0, 3, 0, 3, 3, 0,  	3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 1, 1, 0 @@ -110,22 +110,26 @@ nvc0_vram_init(struct drm_device *dev)  	u32 bsize = nv_rd32(dev, 0x10f20c);  	u32 offset, length;  	bool uniform = true; -	int ret, i; +	int ret, part;  	NV_DEBUG(dev, "0x100800: 0x%08x\n", nv_rd32(dev, 0x100800));  	NV_DEBUG(dev, "parts 0x%08x bcast_mem_amount 0x%08x\n", parts, bsize);  	/* read amount of vram attached to each memory controller */ -	for (i = 0; i < parts; i++) { -		u32 psize = nv_rd32(dev, 0x11020c + (i * 0x1000)); +	part = 0; +	while (parts) { +		u32 psize = nv_rd32(dev, 0x11020c + (part++ * 0x1000)); +		if (psize == 0) +			continue; +		parts--; +  		if (psize != bsize) {  			if (psize < bsize)  				bsize = psize;  			uniform = false;  		} -		NV_DEBUG(dev, "%d: mem_amount 0x%08x\n", i, psize); - +		NV_DEBUG(dev, "%d: mem_amount 0x%08x\n", part, psize);  		dev_priv->vram_size += (u64)psize << 20;  	} diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index 87921c88a95..87631fede1f 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c @@ -1522,12 +1522,6 @@ static bool atombios_crtc_mode_fixup(struct drm_crtc *crtc,  				     struct drm_display_mode *mode,  				     struct drm_display_mode *adjusted_mode)  { -	struct drm_device *dev = crtc->dev; -	struct radeon_device *rdev = dev->dev_private; - -	/* adjust pm to upcoming mode change */ -	radeon_pm_compute_clocks(rdev); -  	if (!radeon_crtc_scaling_mode_fixup(crtc, mode, adjusted_mode))  		return false;  	return true; diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c index a0de48542f7..6fb335a4fdd 100644 --- a/drivers/gpu/drm/radeon/atombios_dp.c +++ b/drivers/gpu/drm/radeon/atombios_dp.c @@ -283,7 +283,7 @@ int radeon_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,  		}  	} -	DRM_ERROR("aux i2c too many retries, giving up\n"); +	DRM_DEBUG_KMS("aux i2c too many retries, giving up\n");  	return -EREMOTEIO;  } diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index e4c384b9511..1d603a3335d 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -157,6 +157,57 @@ int sumo_get_temp(struct radeon_device *rdev)  	return actual_temp * 1000;  } +void sumo_pm_init_profile(struct radeon_device *rdev) +{ +	int idx; + +	/* default */ +	rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_ps_idx = rdev->pm.default_power_state_index; +	rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index; +	rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_cm_idx = 0; +	rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_cm_idx = 0; + +	/* low,mid sh/mh */ +	if (rdev->flags & RADEON_IS_MOBILITY) +		idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 0); +	else +		idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0); + +	rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_ps_idx = idx; +	rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_ps_idx = idx; +	rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_cm_idx = 0; +	rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_cm_idx = 0; + +	rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_ps_idx = idx; +	rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_ps_idx = idx; +	rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_cm_idx = 0; +	rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_cm_idx = 0; + +	rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_ps_idx = idx; +	rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_ps_idx = idx; +	rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_cm_idx = 0; +	rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_cm_idx = 0; + +	rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_ps_idx = idx; +	rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_ps_idx = idx; +	rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_cm_idx = 0; +	rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_cm_idx = 0; + +	/* high sh/mh */ +	idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0); +	rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_ps_idx = idx; +	rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_ps_idx = idx; +	rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_cm_idx = 0; +	rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_cm_idx = +		rdev->pm.power_state[idx].num_clock_modes - 1; + +	rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_ps_idx = idx; +	rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_ps_idx = idx; +	rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_cm_idx = 0; +	rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_cm_idx = +		rdev->pm.power_state[idx].num_clock_modes - 1; +} +  void evergreen_pm_misc(struct radeon_device *rdev)  {  	int req_ps_idx = rdev->pm.requested_power_state_index; @@ -1219,7 +1270,7 @@ void evergreen_mc_program(struct radeon_device *rdev)  		WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR,  			rdev->mc.vram_end >> 12);  	} -	WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, 0); +	WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, rdev->vram_scratch.gpu_addr >> 12);  	if (rdev->flags & RADEON_IS_IGP) {  		tmp = RREG32(MC_FUS_VM_FB_OFFSET) & 0x000FFFFF;  		tmp |= ((rdev->mc.vram_end >> 20) & 0xF) << 24; diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c b/drivers/gpu/drm/radeon/evergreen_cs.c index 7fdfa8ea757..38e1bda73d3 100644 --- a/drivers/gpu/drm/radeon/evergreen_cs.c +++ b/drivers/gpu/drm/radeon/evergreen_cs.c @@ -480,21 +480,23 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)  		}  		break;  	case DB_Z_INFO: -		r = evergreen_cs_packet_next_reloc(p, &reloc); -		if (r) { -			dev_warn(p->dev, "bad SET_CONTEXT_REG " -					"0x%04X\n", reg); -			return -EINVAL; -		}  		track->db_z_info = radeon_get_ib_value(p, idx); -		ib[idx] &= ~Z_ARRAY_MODE(0xf); -		track->db_z_info &= ~Z_ARRAY_MODE(0xf); -		if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) { -			ib[idx] |= Z_ARRAY_MODE(ARRAY_2D_TILED_THIN1); -			track->db_z_info |= Z_ARRAY_MODE(ARRAY_2D_TILED_THIN1); -		} else { -			ib[idx] |= Z_ARRAY_MODE(ARRAY_1D_TILED_THIN1); -			track->db_z_info |= Z_ARRAY_MODE(ARRAY_1D_TILED_THIN1); +		if (!p->keep_tiling_flags) { +			r = evergreen_cs_packet_next_reloc(p, &reloc); +			if (r) { +				dev_warn(p->dev, "bad SET_CONTEXT_REG " +						"0x%04X\n", reg); +				return -EINVAL; +			} +			ib[idx] &= ~Z_ARRAY_MODE(0xf); +			track->db_z_info &= ~Z_ARRAY_MODE(0xf); +			if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) { +				ib[idx] |= Z_ARRAY_MODE(ARRAY_2D_TILED_THIN1); +				track->db_z_info |= Z_ARRAY_MODE(ARRAY_2D_TILED_THIN1); +			} else { +				ib[idx] |= Z_ARRAY_MODE(ARRAY_1D_TILED_THIN1); +				track->db_z_info |= Z_ARRAY_MODE(ARRAY_1D_TILED_THIN1); +			}  		}  		break;  	case DB_STENCIL_INFO: @@ -607,40 +609,44 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)  	case CB_COLOR5_INFO:  	case CB_COLOR6_INFO:  	case CB_COLOR7_INFO: -		r = evergreen_cs_packet_next_reloc(p, &reloc); -		if (r) { -			dev_warn(p->dev, "bad SET_CONTEXT_REG " -					"0x%04X\n", reg); -			return -EINVAL; -		}  		tmp = (reg - CB_COLOR0_INFO) / 0x3c;  		track->cb_color_info[tmp] = radeon_get_ib_value(p, idx); -		if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) { -			ib[idx] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1); -			track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1); -		} else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) { -			ib[idx] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1); -			track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1); +		if (!p->keep_tiling_flags) { +			r = evergreen_cs_packet_next_reloc(p, &reloc); +			if (r) { +				dev_warn(p->dev, "bad SET_CONTEXT_REG " +						"0x%04X\n", reg); +				return -EINVAL; +			} +			if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) { +				ib[idx] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1); +				track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1); +			} else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) { +				ib[idx] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1); +				track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1); +			}  		}  		break;  	case CB_COLOR8_INFO:  	case CB_COLOR9_INFO:  	case CB_COLOR10_INFO:  	case CB_COLOR11_INFO: -		r = evergreen_cs_packet_next_reloc(p, &reloc); -		if (r) { -			dev_warn(p->dev, "bad SET_CONTEXT_REG " -					"0x%04X\n", reg); -			return -EINVAL; -		}  		tmp = ((reg - CB_COLOR8_INFO) / 0x1c) + 8;  		track->cb_color_info[tmp] = radeon_get_ib_value(p, idx); -		if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) { -			ib[idx] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1); -			track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1); -		} else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) { -			ib[idx] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1); -			track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1); +		if (!p->keep_tiling_flags) { +			r = evergreen_cs_packet_next_reloc(p, &reloc); +			if (r) { +				dev_warn(p->dev, "bad SET_CONTEXT_REG " +						"0x%04X\n", reg); +				return -EINVAL; +			} +			if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) { +				ib[idx] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1); +				track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1); +			} else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) { +				ib[idx] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1); +				track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1); +			}  		}  		break;  	case CB_COLOR0_PITCH: @@ -1311,10 +1317,12 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p,  					return -EINVAL;  				}  				ib[idx+1+(i*8)+2] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); -				if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) -					ib[idx+1+(i*8)+1] |= TEX_ARRAY_MODE(ARRAY_2D_TILED_THIN1); -				else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) -					ib[idx+1+(i*8)+1] |= TEX_ARRAY_MODE(ARRAY_1D_TILED_THIN1); +				if (!p->keep_tiling_flags) { +					if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) +						ib[idx+1+(i*8)+1] |= TEX_ARRAY_MODE(ARRAY_2D_TILED_THIN1); +					else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) +						ib[idx+1+(i*8)+1] |= TEX_ARRAY_MODE(ARRAY_1D_TILED_THIN1); +				}  				texture = reloc->robj;  				/* tex mip base */  				r = evergreen_cs_packet_next_reloc(p, &reloc); diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c index 400b26df652..c93bc64707e 100644 --- a/drivers/gpu/drm/radeon/r300.c +++ b/drivers/gpu/drm/radeon/r300.c @@ -701,16 +701,21 @@ static int r300_packet0_check(struct radeon_cs_parser *p,  			return r;  		} -		if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) -			tile_flags |= R300_TXO_MACRO_TILE; -		if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) -			tile_flags |= R300_TXO_MICRO_TILE; -		else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO_SQUARE) -			tile_flags |= R300_TXO_MICRO_TILE_SQUARE; +		if (p->keep_tiling_flags) { +			ib[idx] = (idx_value & 31) | /* keep the 1st 5 bits */ +				  ((idx_value & ~31) + (u32)reloc->lobj.gpu_offset); +		} else { +			if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) +				tile_flags |= R300_TXO_MACRO_TILE; +			if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) +				tile_flags |= R300_TXO_MICRO_TILE; +			else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO_SQUARE) +				tile_flags |= R300_TXO_MICRO_TILE_SQUARE; -		tmp = idx_value + ((u32)reloc->lobj.gpu_offset); -		tmp |= tile_flags; -		ib[idx] = tmp; +			tmp = idx_value + ((u32)reloc->lobj.gpu_offset); +			tmp |= tile_flags; +			ib[idx] = tmp; +		}  		track->textures[i].robj = reloc->robj;  		track->tex_dirty = true;  		break; @@ -760,24 +765,26 @@ static int r300_packet0_check(struct radeon_cs_parser *p,  		/* RB3D_COLORPITCH1 */  		/* RB3D_COLORPITCH2 */  		/* RB3D_COLORPITCH3 */ -		r = r100_cs_packet_next_reloc(p, &reloc); -		if (r) { -			DRM_ERROR("No reloc for ib[%d]=0x%04X\n", -				  idx, reg); -			r100_cs_dump_packet(p, pkt); -			return r; -		} +		if (!p->keep_tiling_flags) { +			r = r100_cs_packet_next_reloc(p, &reloc); +			if (r) { +				DRM_ERROR("No reloc for ib[%d]=0x%04X\n", +					  idx, reg); +				r100_cs_dump_packet(p, pkt); +				return r; +			} -		if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) -			tile_flags |= R300_COLOR_TILE_ENABLE; -		if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) -			tile_flags |= R300_COLOR_MICROTILE_ENABLE; -		else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO_SQUARE) -			tile_flags |= R300_COLOR_MICROTILE_SQUARE_ENABLE; +			if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) +				tile_flags |= R300_COLOR_TILE_ENABLE; +			if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) +				tile_flags |= R300_COLOR_MICROTILE_ENABLE; +			else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO_SQUARE) +				tile_flags |= R300_COLOR_MICROTILE_SQUARE_ENABLE; -		tmp = idx_value & ~(0x7 << 16); -		tmp |= tile_flags; -		ib[idx] = tmp; +			tmp = idx_value & ~(0x7 << 16); +			tmp |= tile_flags; +			ib[idx] = tmp; +		}  		i = (reg - 0x4E38) >> 2;  		track->cb[i].pitch = idx_value & 0x3FFE;  		switch (((idx_value >> 21) & 0xF)) { @@ -843,25 +850,26 @@ static int r300_packet0_check(struct radeon_cs_parser *p,  		break;  	case 0x4F24:  		/* ZB_DEPTHPITCH */ -		r = r100_cs_packet_next_reloc(p, &reloc); -		if (r) { -			DRM_ERROR("No reloc for ib[%d]=0x%04X\n", -				  idx, reg); -			r100_cs_dump_packet(p, pkt); -			return r; -		} - -		if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) -			tile_flags |= R300_DEPTHMACROTILE_ENABLE; -		if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) -			tile_flags |= R300_DEPTHMICROTILE_TILED; -		else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO_SQUARE) -			tile_flags |= R300_DEPTHMICROTILE_TILED_SQUARE; +		if (!p->keep_tiling_flags) { +			r = r100_cs_packet_next_reloc(p, &reloc); +			if (r) { +				DRM_ERROR("No reloc for ib[%d]=0x%04X\n", +					  idx, reg); +				r100_cs_dump_packet(p, pkt); +				return r; +			} -		tmp = idx_value & ~(0x7 << 16); -		tmp |= tile_flags; -		ib[idx] = tmp; +			if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) +				tile_flags |= R300_DEPTHMACROTILE_ENABLE; +			if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) +				tile_flags |= R300_DEPTHMICROTILE_TILED; +			else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO_SQUARE) +				tile_flags |= R300_DEPTHMICROTILE_TILED_SQUARE; +			tmp = idx_value & ~(0x7 << 16); +			tmp |= tile_flags; +			ib[idx] = tmp; +		}  		track->zb.pitch = idx_value & 0x3FFC;  		track->zb_dirty = true;  		break; diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 19afc43ad17..9cdda0b3b08 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -288,24 +288,6 @@ void r600_pm_get_dynpm_state(struct radeon_device *rdev)  		  pcie_lanes);  } -static int r600_pm_get_type_index(struct radeon_device *rdev, -				  enum radeon_pm_state_type ps_type, -				  int instance) -{ -	int i; -	int found_instance = -1; - -	for (i = 0; i < rdev->pm.num_power_states; i++) { -		if (rdev->pm.power_state[i].type == ps_type) { -			found_instance++; -			if (found_instance == instance) -				return i; -		} -	} -	/* return default if no match */ -	return rdev->pm.default_power_state_index; -} -  void rs780_pm_init_profile(struct radeon_device *rdev)  {  	if (rdev->pm.num_power_states == 2) { @@ -421,6 +403,8 @@ void rs780_pm_init_profile(struct radeon_device *rdev)  void r600_pm_init_profile(struct radeon_device *rdev)  { +	int idx; +  	if (rdev->family == CHIP_R600) {  		/* XXX */  		/* default */ @@ -502,81 +486,43 @@ void r600_pm_init_profile(struct radeon_device *rdev)  			rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_cm_idx = 0;  			rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_cm_idx = 2;  			/* low sh */ -			if (rdev->flags & RADEON_IS_MOBILITY) { -				rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_ps_idx = -					r600_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 0); -				rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_ps_idx = -					r600_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 0); -				rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_cm_idx = 0; -				rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_cm_idx = 0; -			} else { -				rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_ps_idx = -					r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0); -				rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_ps_idx = -					r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0); -				rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_cm_idx = 0; -				rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_cm_idx = 0; -			} +			if (rdev->flags & RADEON_IS_MOBILITY) +				idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 0); +			else +				idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0); +			rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_ps_idx = idx; +			rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_ps_idx = idx; +			rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_cm_idx = 0; +			rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_cm_idx = 0;  			/* mid sh */ -			if (rdev->flags & RADEON_IS_MOBILITY) { -				rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_ps_idx = -					r600_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 0); -				rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_ps_idx = -					r600_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 0); -				rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_cm_idx = 0; -				rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_cm_idx = 1; -			} else { -				rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_ps_idx = -					r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0); -				rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_ps_idx = -					r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0); -				rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_cm_idx = 0; -				rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_cm_idx = 1; -			} +			rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_ps_idx = idx; +			rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_ps_idx = idx; +			rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_cm_idx = 0; +			rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_cm_idx = 1;  			/* high sh */ -			rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_ps_idx = -				r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0); -			rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_ps_idx = -				r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0); +			idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0); +			rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_ps_idx = idx; +			rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_ps_idx = idx;  			rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_cm_idx = 0;  			rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_cm_idx = 2;  			/* low mh */ -			if (rdev->flags & RADEON_IS_MOBILITY) { -				rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_ps_idx = -					r600_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 1); -				rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_ps_idx = -					r600_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 1); -				rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_cm_idx = 0; -				rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_cm_idx = 0; -			} else { -				rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_ps_idx = -					r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 1); -				rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_ps_idx = -					r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 1); -				rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_cm_idx = 0; -				rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_cm_idx = 0; -			} +			if (rdev->flags & RADEON_IS_MOBILITY) +				idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 1); +			else +				idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 1); +			rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_ps_idx = idx; +			rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_ps_idx = idx; +			rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_cm_idx = 0; +			rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_cm_idx = 0;  			/* mid mh */ -			if (rdev->flags & RADEON_IS_MOBILITY) { -				rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_ps_idx = -					r600_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 1); -				rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_ps_idx = -					r600_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 1); -				rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_cm_idx = 0; -				rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_cm_idx = 1; -			} else { -				rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_ps_idx = -					r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 1); -				rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_ps_idx = -					r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 1); -				rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_cm_idx = 0; -				rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_cm_idx = 1; -			} +			rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_ps_idx = idx; +			rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_ps_idx = idx; +			rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_cm_idx = 0; +			rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_cm_idx = 1;  			/* high mh */ -			rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_ps_idx = -				r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 1); -			rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_ps_idx = -				r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 1); +			idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 1); +			rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_ps_idx = idx; +			rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_ps_idx = idx;  			rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_cm_idx = 0;  			rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_cm_idx = 2;  		} diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c index 0a2e023c155..cb1acffd243 100644 --- a/drivers/gpu/drm/radeon/r600_cs.c +++ b/drivers/gpu/drm/radeon/r600_cs.c @@ -941,7 +941,8 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)  		track->db_depth_control = radeon_get_ib_value(p, idx);  		break;  	case R_028010_DB_DEPTH_INFO: -		if (r600_cs_packet_next_is_pkt3_nop(p)) { +		if (!p->keep_tiling_flags && +		    r600_cs_packet_next_is_pkt3_nop(p)) {  			r = r600_cs_packet_next_reloc(p, &reloc);  			if (r) {  				dev_warn(p->dev, "bad SET_CONTEXT_REG " @@ -992,7 +993,8 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)  	case R_0280B4_CB_COLOR5_INFO:  	case R_0280B8_CB_COLOR6_INFO:  	case R_0280BC_CB_COLOR7_INFO: -		if (r600_cs_packet_next_is_pkt3_nop(p)) { +		if (!p->keep_tiling_flags && +		     r600_cs_packet_next_is_pkt3_nop(p)) {  			r = r600_cs_packet_next_reloc(p, &reloc);  			if (r) {  				dev_err(p->dev, "bad SET_CONTEXT_REG 0x%04X\n", reg); @@ -1291,10 +1293,12 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p,  u32 idx,  	mip_offset <<= 8;  	word0 = radeon_get_ib_value(p, idx + 0); -	if (tiling_flags & RADEON_TILING_MACRO) -		word0 |= S_038000_TILE_MODE(V_038000_ARRAY_2D_TILED_THIN1); -	else if (tiling_flags & RADEON_TILING_MICRO) -		word0 |= S_038000_TILE_MODE(V_038000_ARRAY_1D_TILED_THIN1); +	if (!p->keep_tiling_flags) { +		if (tiling_flags & RADEON_TILING_MACRO) +			word0 |= S_038000_TILE_MODE(V_038000_ARRAY_2D_TILED_THIN1); +		else if (tiling_flags & RADEON_TILING_MICRO) +			word0 |= S_038000_TILE_MODE(V_038000_ARRAY_1D_TILED_THIN1); +	}  	word1 = radeon_get_ib_value(p, idx + 1);  	w0 = G_038000_TEX_WIDTH(word0) + 1;  	h0 = G_038004_TEX_HEIGHT(word1) + 1; @@ -1621,10 +1625,12 @@ static int r600_packet3_check(struct radeon_cs_parser *p,  					return -EINVAL;  				}  				base_offset = (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); -				if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) -					ib[idx+1+(i*7)+0] |= S_038000_TILE_MODE(V_038000_ARRAY_2D_TILED_THIN1); -				else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) -					ib[idx+1+(i*7)+0] |= S_038000_TILE_MODE(V_038000_ARRAY_1D_TILED_THIN1); +				if (!p->keep_tiling_flags) { +					if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) +						ib[idx+1+(i*7)+0] |= S_038000_TILE_MODE(V_038000_ARRAY_2D_TILED_THIN1); +					else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) +						ib[idx+1+(i*7)+0] |= S_038000_TILE_MODE(V_038000_ARRAY_1D_TILED_THIN1); +				}  				texture = reloc->robj;  				/* tex mip base */  				r = r600_cs_packet_next_reloc(p, &reloc); diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index b316b301152..8227e76b5c7 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -611,7 +611,8 @@ struct radeon_cs_parser {  	struct radeon_ib	*ib;  	void			*track;  	unsigned		family; -	int parser_error; +	int			parser_error; +	bool			keep_tiling_flags;  };  extern int radeon_cs_update_pages(struct radeon_cs_parser *p, int pg_idx); @@ -784,8 +785,7 @@ struct radeon_pm_clock_info {  struct radeon_power_state {  	enum radeon_pm_state_type type; -	/* XXX: use a define for num clock modes */ -	struct radeon_pm_clock_info clock_info[8]; +	struct radeon_pm_clock_info *clock_info;  	/* number of valid clock modes in this power state */  	int num_clock_modes;  	struct radeon_pm_clock_info *default_clock_mode; @@ -855,6 +855,9 @@ struct radeon_pm {  	struct device	        *int_hwmon_dev;  }; +int radeon_pm_get_type_index(struct radeon_device *rdev, +			     enum radeon_pm_state_type ps_type, +			     int instance);  /*   * Benchmarking @@ -1142,6 +1145,48 @@ struct r600_vram_scratch {  	u64				gpu_addr;  }; + +/* + * Mutex which allows recursive locking from the same process. + */ +struct radeon_mutex { +	struct mutex		mutex; +	struct task_struct	*owner; +	int			level; +}; + +static inline void radeon_mutex_init(struct radeon_mutex *mutex) +{ +	mutex_init(&mutex->mutex); +	mutex->owner = NULL; +	mutex->level = 0; +} + +static inline void radeon_mutex_lock(struct radeon_mutex *mutex) +{ +	if (mutex_trylock(&mutex->mutex)) { +		/* The mutex was unlocked before, so it's ours now */ +		mutex->owner = current; +	} else if (mutex->owner != current) { +		/* Another process locked the mutex, take it */ +		mutex_lock(&mutex->mutex); +		mutex->owner = current; +	} +	/* Otherwise the mutex was already locked by this process */ + +	mutex->level++; +} + +static inline void radeon_mutex_unlock(struct radeon_mutex *mutex) +{ +	if (--mutex->level > 0) +		return; + +	mutex->owner = NULL; +	mutex_unlock(&mutex->mutex); +} + +  /*   * Core structure, functions and helpers.   */ @@ -1197,7 +1242,7 @@ struct radeon_device {  	struct radeon_gem		gem;  	struct radeon_pm		pm;  	uint32_t			bios_scratch[RADEON_BIOS_NUM_SCRATCH]; -	struct mutex			cs_mutex; +	struct radeon_mutex		cs_mutex;  	struct radeon_wb		wb;  	struct radeon_dummy_page	dummy_page;  	bool				gpu_lockup; diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c index e2944566ffe..a2e1eae114e 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.c +++ b/drivers/gpu/drm/radeon/radeon_asic.c @@ -834,7 +834,7 @@ static struct radeon_asic sumo_asic = {  	.pm_misc = &evergreen_pm_misc,  	.pm_prepare = &evergreen_pm_prepare,  	.pm_finish = &evergreen_pm_finish, -	.pm_init_profile = &rs780_pm_init_profile, +	.pm_init_profile = &sumo_pm_init_profile,  	.pm_get_dynpm_state = &r600_pm_get_dynpm_state,  	.pre_page_flip = &evergreen_pre_page_flip,  	.page_flip = &evergreen_page_flip, diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index 85f14f0337e..59914842a72 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h @@ -413,6 +413,7 @@ extern int evergreen_cs_parse(struct radeon_cs_parser *p);  extern void evergreen_pm_misc(struct radeon_device *rdev);  extern void evergreen_pm_prepare(struct radeon_device *rdev);  extern void evergreen_pm_finish(struct radeon_device *rdev); +extern void sumo_pm_init_profile(struct radeon_device *rdev);  extern void evergreen_pre_page_flip(struct radeon_device *rdev, int crtc);  extern u32 evergreen_page_flip(struct radeon_device *rdev, int crtc, u64 crtc_base);  extern void evergreen_post_page_flip(struct radeon_device *rdev, int crtc); diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index 08d0b94332e..d24baf30efc 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c @@ -62,6 +62,87 @@ union atom_supported_devices {  	struct _ATOM_SUPPORTED_DEVICES_INFO_2d1 info_2d1;  }; +static void radeon_lookup_i2c_gpio_quirks(struct radeon_device *rdev, +					  ATOM_GPIO_I2C_ASSIGMENT *gpio, +					  u8 index) +{ +	/* r4xx mask is technically not used by the hw, so patch in the legacy mask bits */ +	if ((rdev->family == CHIP_R420) || +	    (rdev->family == CHIP_R423) || +	    (rdev->family == CHIP_RV410)) { +		if ((le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x0018) || +		    (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x0019) || +		    (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x001a)) { +			gpio->ucClkMaskShift = 0x19; +			gpio->ucDataMaskShift = 0x18; +		} +	} + +	/* some evergreen boards have bad data for this entry */ +	if (ASIC_IS_DCE4(rdev)) { +		if ((index == 7) && +		    (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x1936) && +		    (gpio->sucI2cId.ucAccess == 0)) { +			gpio->sucI2cId.ucAccess = 0x97; +			gpio->ucDataMaskShift = 8; +			gpio->ucDataEnShift = 8; +			gpio->ucDataY_Shift = 8; +			gpio->ucDataA_Shift = 8; +		} +	} + +	/* some DCE3 boards have bad data for this entry */ +	if (ASIC_IS_DCE3(rdev)) { +		if ((index == 4) && +		    (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x1fda) && +		    (gpio->sucI2cId.ucAccess == 0x94)) +			gpio->sucI2cId.ucAccess = 0x14; +	} +} + +static struct radeon_i2c_bus_rec radeon_get_bus_rec_for_i2c_gpio(ATOM_GPIO_I2C_ASSIGMENT *gpio) +{ +	struct radeon_i2c_bus_rec i2c; + +	memset(&i2c, 0, sizeof(struct radeon_i2c_bus_rec)); + +	i2c.mask_clk_reg = le16_to_cpu(gpio->usClkMaskRegisterIndex) * 4; +	i2c.mask_data_reg = le16_to_cpu(gpio->usDataMaskRegisterIndex) * 4; +	i2c.en_clk_reg = le16_to_cpu(gpio->usClkEnRegisterIndex) * 4; +	i2c.en_data_reg = le16_to_cpu(gpio->usDataEnRegisterIndex) * 4; +	i2c.y_clk_reg = le16_to_cpu(gpio->usClkY_RegisterIndex) * 4; +	i2c.y_data_reg = le16_to_cpu(gpio->usDataY_RegisterIndex) * 4; +	i2c.a_clk_reg = le16_to_cpu(gpio->usClkA_RegisterIndex) * 4; +	i2c.a_data_reg = le16_to_cpu(gpio->usDataA_RegisterIndex) * 4; +	i2c.mask_clk_mask = (1 << gpio->ucClkMaskShift); +	i2c.mask_data_mask = (1 << gpio->ucDataMaskShift); +	i2c.en_clk_mask = (1 << gpio->ucClkEnShift); +	i2c.en_data_mask = (1 << gpio->ucDataEnShift); +	i2c.y_clk_mask = (1 << gpio->ucClkY_Shift); +	i2c.y_data_mask = (1 << gpio->ucDataY_Shift); +	i2c.a_clk_mask = (1 << gpio->ucClkA_Shift); +	i2c.a_data_mask = (1 << gpio->ucDataA_Shift); + +	if (gpio->sucI2cId.sbfAccess.bfHW_Capable) +		i2c.hw_capable = true; +	else +		i2c.hw_capable = false; + +	if (gpio->sucI2cId.ucAccess == 0xa0) +		i2c.mm_i2c = true; +	else +		i2c.mm_i2c = false; + +	i2c.i2c_id = gpio->sucI2cId.ucAccess; + +	if (i2c.mask_clk_reg) +		i2c.valid = true; +	else +		i2c.valid = false; + +	return i2c; +} +  static struct radeon_i2c_bus_rec radeon_lookup_i2c_gpio(struct radeon_device *rdev,  							       uint8_t id)  { @@ -85,59 +166,10 @@ static struct radeon_i2c_bus_rec radeon_lookup_i2c_gpio(struct radeon_device *rd  		for (i = 0; i < num_indices; i++) {  			gpio = &i2c_info->asGPIO_Info[i]; -			/* some evergreen boards have bad data for this entry */ -			if (ASIC_IS_DCE4(rdev)) { -				if ((i == 7) && -				    (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x1936) && -				    (gpio->sucI2cId.ucAccess == 0)) { -					gpio->sucI2cId.ucAccess = 0x97; -					gpio->ucDataMaskShift = 8; -					gpio->ucDataEnShift = 8; -					gpio->ucDataY_Shift = 8; -					gpio->ucDataA_Shift = 8; -				} -			} - -			/* some DCE3 boards have bad data for this entry */ -			if (ASIC_IS_DCE3(rdev)) { -				if ((i == 4) && -				    (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x1fda) && -				    (gpio->sucI2cId.ucAccess == 0x94)) -					gpio->sucI2cId.ucAccess = 0x14; -			} +			radeon_lookup_i2c_gpio_quirks(rdev, gpio, i);  			if (gpio->sucI2cId.ucAccess == id) { -				i2c.mask_clk_reg = le16_to_cpu(gpio->usClkMaskRegisterIndex) * 4; -				i2c.mask_data_reg = le16_to_cpu(gpio->usDataMaskRegisterIndex) * 4; -				i2c.en_clk_reg = le16_to_cpu(gpio->usClkEnRegisterIndex) * 4; -				i2c.en_data_reg = le16_to_cpu(gpio->usDataEnRegisterIndex) * 4; -				i2c.y_clk_reg = le16_to_cpu(gpio->usClkY_RegisterIndex) * 4; -				i2c.y_data_reg = le16_to_cpu(gpio->usDataY_RegisterIndex) * 4; -				i2c.a_clk_reg = le16_to_cpu(gpio->usClkA_RegisterIndex) * 4; -				i2c.a_data_reg = le16_to_cpu(gpio->usDataA_RegisterIndex) * 4; -				i2c.mask_clk_mask = (1 << gpio->ucClkMaskShift); -				i2c.mask_data_mask = (1 << gpio->ucDataMaskShift); -				i2c.en_clk_mask = (1 << gpio->ucClkEnShift); -				i2c.en_data_mask = (1 << gpio->ucDataEnShift); -				i2c.y_clk_mask = (1 << gpio->ucClkY_Shift); -				i2c.y_data_mask = (1 << gpio->ucDataY_Shift); -				i2c.a_clk_mask = (1 << gpio->ucClkA_Shift); -				i2c.a_data_mask = (1 << gpio->ucDataA_Shift); - -				if (gpio->sucI2cId.sbfAccess.bfHW_Capable) -					i2c.hw_capable = true; -				else -					i2c.hw_capable = false; - -				if (gpio->sucI2cId.ucAccess == 0xa0) -					i2c.mm_i2c = true; -				else -					i2c.mm_i2c = false; - -				i2c.i2c_id = gpio->sucI2cId.ucAccess; - -				if (i2c.mask_clk_reg) -					i2c.valid = true; +				i2c = radeon_get_bus_rec_for_i2c_gpio(gpio);  				break;  			}  		} @@ -157,8 +189,6 @@ void radeon_atombios_i2c_init(struct radeon_device *rdev)  	int i, num_indices;  	char stmp[32]; -	memset(&i2c, 0, sizeof(struct radeon_i2c_bus_rec)); -  	if (atom_parse_data_header(ctx, index, &size, NULL, NULL, &data_offset)) {  		i2c_info = (struct _ATOM_GPIO_I2C_INFO *)(ctx->bios + data_offset); @@ -167,60 +197,12 @@ void radeon_atombios_i2c_init(struct radeon_device *rdev)  		for (i = 0; i < num_indices; i++) {  			gpio = &i2c_info->asGPIO_Info[i]; -			i2c.valid = false; -			/* some evergreen boards have bad data for this entry */ -			if (ASIC_IS_DCE4(rdev)) { -				if ((i == 7) && -				    (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x1936) && -				    (gpio->sucI2cId.ucAccess == 0)) { -					gpio->sucI2cId.ucAccess = 0x97; -					gpio->ucDataMaskShift = 8; -					gpio->ucDataEnShift = 8; -					gpio->ucDataY_Shift = 8; -					gpio->ucDataA_Shift = 8; -				} -			} - -			/* some DCE3 boards have bad data for this entry */ -			if (ASIC_IS_DCE3(rdev)) { -				if ((i == 4) && -				    (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x1fda) && -				    (gpio->sucI2cId.ucAccess == 0x94)) -					gpio->sucI2cId.ucAccess = 0x14; -			} +			radeon_lookup_i2c_gpio_quirks(rdev, gpio, i); -			i2c.mask_clk_reg = le16_to_cpu(gpio->usClkMaskRegisterIndex) * 4; -			i2c.mask_data_reg = le16_to_cpu(gpio->usDataMaskRegisterIndex) * 4; -			i2c.en_clk_reg = le16_to_cpu(gpio->usClkEnRegisterIndex) * 4; -			i2c.en_data_reg = le16_to_cpu(gpio->usDataEnRegisterIndex) * 4; -			i2c.y_clk_reg = le16_to_cpu(gpio->usClkY_RegisterIndex) * 4; -			i2c.y_data_reg = le16_to_cpu(gpio->usDataY_RegisterIndex) * 4; -			i2c.a_clk_reg = le16_to_cpu(gpio->usClkA_RegisterIndex) * 4; -			i2c.a_data_reg = le16_to_cpu(gpio->usDataA_RegisterIndex) * 4; -			i2c.mask_clk_mask = (1 << gpio->ucClkMaskShift); -			i2c.mask_data_mask = (1 << gpio->ucDataMaskShift); -			i2c.en_clk_mask = (1 << gpio->ucClkEnShift); -			i2c.en_data_mask = (1 << gpio->ucDataEnShift); -			i2c.y_clk_mask = (1 << gpio->ucClkY_Shift); -			i2c.y_data_mask = (1 << gpio->ucDataY_Shift); -			i2c.a_clk_mask = (1 << gpio->ucClkA_Shift); -			i2c.a_data_mask = (1 << gpio->ucDataA_Shift); +			i2c = radeon_get_bus_rec_for_i2c_gpio(gpio); -			if (gpio->sucI2cId.sbfAccess.bfHW_Capable) -				i2c.hw_capable = true; -			else -				i2c.hw_capable = false; - -			if (gpio->sucI2cId.ucAccess == 0xa0) -				i2c.mm_i2c = true; -			else -				i2c.mm_i2c = false; - -			i2c.i2c_id = gpio->sucI2cId.ucAccess; - -			if (i2c.mask_clk_reg) { -				i2c.valid = true; +			if (i2c.valid) {  				sprintf(stmp, "0x%x", i2c.i2c_id);  				rdev->i2c_bus[i] = radeon_i2c_create(rdev->ddev, &i2c, stmp);  			} @@ -1996,10 +1978,14 @@ static int radeon_atombios_parse_power_table_1_3(struct radeon_device *rdev)  		return state_index;  	/* last mode is usually default, array is low to high */  	for (i = 0; i < num_modes; i++) { +		rdev->pm.power_state[state_index].clock_info = +			kzalloc(sizeof(struct radeon_pm_clock_info) * 1, GFP_KERNEL); +		if (!rdev->pm.power_state[state_index].clock_info) +			return state_index; +		rdev->pm.power_state[state_index].num_clock_modes = 1;  		rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE;  		switch (frev) {  		case 1: -			rdev->pm.power_state[state_index].num_clock_modes = 1;  			rdev->pm.power_state[state_index].clock_info[0].mclk =  				le16_to_cpu(power_info->info.asPowerPlayInfo[i].usMemoryClock);  			rdev->pm.power_state[state_index].clock_info[0].sclk = @@ -2035,7 +2021,6 @@ static int radeon_atombios_parse_power_table_1_3(struct radeon_device *rdev)  			state_index++;  			break;  		case 2: -			rdev->pm.power_state[state_index].num_clock_modes = 1;  			rdev->pm.power_state[state_index].clock_info[0].mclk =  				le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMemoryClock);  			rdev->pm.power_state[state_index].clock_info[0].sclk = @@ -2072,7 +2057,6 @@ static int radeon_atombios_parse_power_table_1_3(struct radeon_device *rdev)  			state_index++;  			break;  		case 3: -			rdev->pm.power_state[state_index].num_clock_modes = 1;  			rdev->pm.power_state[state_index].clock_info[0].mclk =  				le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMemoryClock);  			rdev->pm.power_state[state_index].clock_info[0].sclk = @@ -2257,7 +2241,7 @@ static void radeon_atombios_parse_pplib_non_clock_info(struct radeon_device *rde  		rdev->pm.default_power_state_index = state_index;  		rdev->pm.power_state[state_index].default_clock_mode =  			&rdev->pm.power_state[state_index].clock_info[mode_index - 1]; -		if (ASIC_IS_DCE5(rdev)) { +		if (ASIC_IS_DCE5(rdev) && !(rdev->flags & RADEON_IS_IGP)) {  			/* NI chips post without MC ucode, so default clocks are strobe mode only */  			rdev->pm.default_sclk = rdev->pm.power_state[state_index].clock_info[0].sclk;  			rdev->pm.default_mclk = rdev->pm.power_state[state_index].clock_info[0].mclk; @@ -2377,17 +2361,31 @@ static int radeon_atombios_parse_power_table_4_5(struct radeon_device *rdev)  			 le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset) +  			 (power_state->v1.ucNonClockStateIndex *  			  power_info->pplib.ucNonClockSize)); -		for (j = 0; j < (power_info->pplib.ucStateEntrySize - 1); j++) { -			clock_info = (union pplib_clock_info *) -				(mode_info->atom_context->bios + data_offset + -				 le16_to_cpu(power_info->pplib.usClockInfoArrayOffset) + -				 (power_state->v1.ucClockStateIndices[j] * -				  power_info->pplib.ucClockInfoSize)); -			valid = radeon_atombios_parse_pplib_clock_info(rdev, -								       state_index, mode_index, -								       clock_info); -			if (valid) -				mode_index++; +		rdev->pm.power_state[i].clock_info = kzalloc(sizeof(struct radeon_pm_clock_info) * +							     ((power_info->pplib.ucStateEntrySize - 1) ? +							      (power_info->pplib.ucStateEntrySize - 1) : 1), +							     GFP_KERNEL); +		if (!rdev->pm.power_state[i].clock_info) +			return state_index; +		if (power_info->pplib.ucStateEntrySize - 1) { +			for (j = 0; j < (power_info->pplib.ucStateEntrySize - 1); j++) { +				clock_info = (union pplib_clock_info *) +					(mode_info->atom_context->bios + data_offset + +					 le16_to_cpu(power_info->pplib.usClockInfoArrayOffset) + +					 (power_state->v1.ucClockStateIndices[j] * +					  power_info->pplib.ucClockInfoSize)); +				valid = radeon_atombios_parse_pplib_clock_info(rdev, +									       state_index, mode_index, +									       clock_info); +				if (valid) +					mode_index++; +			} +		} else { +			rdev->pm.power_state[state_index].clock_info[0].mclk = +				rdev->clock.default_mclk; +			rdev->pm.power_state[state_index].clock_info[0].sclk = +				rdev->clock.default_sclk; +			mode_index++;  		}  		rdev->pm.power_state[state_index].num_clock_modes = mode_index;  		if (mode_index) { @@ -2456,18 +2454,32 @@ static int radeon_atombios_parse_power_table_6(struct radeon_device *rdev)  		non_clock_array_index = i; /* power_state->v2.nonClockInfoIndex */  		non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *)  			&non_clock_info_array->nonClockInfo[non_clock_array_index]; -		for (j = 0; j < power_state->v2.ucNumDPMLevels; j++) { -			clock_array_index = power_state->v2.clockInfoIndex[j]; -			/* XXX this might be an inagua bug... */ -			if (clock_array_index >= clock_info_array->ucNumEntries) -				continue; -			clock_info = (union pplib_clock_info *) -				&clock_info_array->clockInfo[clock_array_index]; -			valid = radeon_atombios_parse_pplib_clock_info(rdev, -								       state_index, mode_index, -								       clock_info); -			if (valid) -				mode_index++; +		rdev->pm.power_state[i].clock_info = kzalloc(sizeof(struct radeon_pm_clock_info) * +							     (power_state->v2.ucNumDPMLevels ? +							      power_state->v2.ucNumDPMLevels : 1), +							     GFP_KERNEL); +		if (!rdev->pm.power_state[i].clock_info) +			return state_index; +		if (power_state->v2.ucNumDPMLevels) { +			for (j = 0; j < power_state->v2.ucNumDPMLevels; j++) { +				clock_array_index = power_state->v2.clockInfoIndex[j]; +				/* XXX this might be an inagua bug... */ +				if (clock_array_index >= clock_info_array->ucNumEntries) +					continue; +				clock_info = (union pplib_clock_info *) +					&clock_info_array->clockInfo[clock_array_index]; +				valid = radeon_atombios_parse_pplib_clock_info(rdev, +									       state_index, mode_index, +									       clock_info); +				if (valid) +					mode_index++; +			} +		} else { +			rdev->pm.power_state[state_index].clock_info[0].mclk = +				rdev->clock.default_mclk; +			rdev->pm.power_state[state_index].clock_info[0].sclk = +				rdev->clock.default_sclk; +			mode_index++;  		}  		rdev->pm.power_state[state_index].num_clock_modes = mode_index;  		if (mode_index) { @@ -2524,19 +2536,23 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev)  	} else {  		rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state), GFP_KERNEL);  		if (rdev->pm.power_state) { -			/* add the default mode */ -			rdev->pm.power_state[state_index].type = -				POWER_STATE_TYPE_DEFAULT; -			rdev->pm.power_state[state_index].num_clock_modes = 1; -			rdev->pm.power_state[state_index].clock_info[0].mclk = rdev->clock.default_mclk; -			rdev->pm.power_state[state_index].clock_info[0].sclk = rdev->clock.default_sclk; -			rdev->pm.power_state[state_index].default_clock_mode = -				&rdev->pm.power_state[state_index].clock_info[0]; -			rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE; -			rdev->pm.power_state[state_index].pcie_lanes = 16; -			rdev->pm.default_power_state_index = state_index; -			rdev->pm.power_state[state_index].flags = 0; -			state_index++; +			rdev->pm.power_state[0].clock_info = +				kzalloc(sizeof(struct radeon_pm_clock_info) * 1, GFP_KERNEL); +			if (rdev->pm.power_state[0].clock_info) { +				/* add the default mode */ +				rdev->pm.power_state[state_index].type = +					POWER_STATE_TYPE_DEFAULT; +				rdev->pm.power_state[state_index].num_clock_modes = 1; +				rdev->pm.power_state[state_index].clock_info[0].mclk = rdev->clock.default_mclk; +				rdev->pm.power_state[state_index].clock_info[0].sclk = rdev->clock.default_sclk; +				rdev->pm.power_state[state_index].default_clock_mode = +					&rdev->pm.power_state[state_index].clock_info[0]; +				rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE; +				rdev->pm.power_state[state_index].pcie_lanes = 16; +				rdev->pm.default_power_state_index = state_index; +				rdev->pm.power_state[state_index].flags = 0; +				state_index++; +			}  		}  	} diff --git a/drivers/gpu/drm/radeon/radeon_benchmark.c b/drivers/gpu/drm/radeon/radeon_benchmark.c index 5cafc90de7f..17e1a9b2d8f 100644 --- a/drivers/gpu/drm/radeon/radeon_benchmark.c +++ b/drivers/gpu/drm/radeon/radeon_benchmark.c @@ -98,7 +98,7 @@ static void radeon_benchmark_move(struct radeon_device *rdev, unsigned size,  	struct radeon_bo *sobj = NULL;  	uint64_t saddr, daddr;  	int r, n; -	unsigned int time; +	int time;  	n = RADEON_BENCHMARK_ITERATIONS;  	r = radeon_bo_create(rdev, size, PAGE_SIZE, true, sdomain, &sobj); diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c index 8bf83c4b414..81fc100be7e 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c @@ -2563,14 +2563,17 @@ void radeon_combios_get_power_modes(struct radeon_device *rdev)  	/* allocate 2 power states */  	rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state) * 2, GFP_KERNEL); -	if (!rdev->pm.power_state) { -		rdev->pm.default_power_state_index = state_index; -		rdev->pm.num_power_states = 0; - -		rdev->pm.current_power_state_index = rdev->pm.default_power_state_index; -		rdev->pm.current_clock_mode_index = 0; -		return; -	} +	if (rdev->pm.power_state) { +		/* allocate 1 clock mode per state */ +		rdev->pm.power_state[0].clock_info = +			kzalloc(sizeof(struct radeon_pm_clock_info) * 1, GFP_KERNEL); +		rdev->pm.power_state[1].clock_info = +			kzalloc(sizeof(struct radeon_pm_clock_info) * 1, GFP_KERNEL); +		if (!rdev->pm.power_state[0].clock_info || +		    !rdev->pm.power_state[1].clock_info) +			goto pm_failed; +	} else +		goto pm_failed;  	/* check for a thermal chip */  	offset = combios_get_table_offset(dev, COMBIOS_OVERDRIVE_INFO_TABLE); @@ -2735,6 +2738,14 @@ default_mode:  	rdev->pm.current_power_state_index = rdev->pm.default_power_state_index;  	rdev->pm.current_clock_mode_index = 0; +	return; + +pm_failed: +	rdev->pm.default_power_state_index = state_index; +	rdev->pm.num_power_states = 0; + +	rdev->pm.current_power_state_index = rdev->pm.default_power_state_index; +	rdev->pm.current_clock_mode_index = 0;  }  void radeon_external_tmds_setup(struct drm_encoder *encoder) diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c index fae00c0d75a..29afd71e084 100644 --- a/drivers/gpu/drm/radeon/radeon_cs.c +++ b/drivers/gpu/drm/radeon/radeon_cs.c @@ -93,7 +93,7 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data)  {  	struct drm_radeon_cs *cs = data;  	uint64_t *chunk_array_ptr; -	unsigned size, i; +	unsigned size, i, flags = 0;  	if (!cs->num_chunks) {  		return 0; @@ -140,6 +140,10 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data)  			if (p->chunks[i].length_dw == 0)  				return -EINVAL;  		} +		if (p->chunks[i].chunk_id == RADEON_CHUNK_ID_FLAGS && +		    !p->chunks[i].length_dw) { +			return -EINVAL; +		}  		p->chunks[i].length_dw = user_chunk.length_dw;  		p->chunks[i].user_ptr = (void __user *)(unsigned long)user_chunk.chunk_data; @@ -155,6 +159,9 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data)  					       p->chunks[i].user_ptr, size)) {  				return -EFAULT;  			} +			if (p->chunks[i].chunk_id == RADEON_CHUNK_ID_FLAGS) { +				flags = p->chunks[i].kdata[0]; +			}  		} else {  			p->chunks[i].kpage[0] = kmalloc(PAGE_SIZE, GFP_KERNEL);  			p->chunks[i].kpage[1] = kmalloc(PAGE_SIZE, GFP_KERNEL); @@ -174,6 +181,8 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data)  			  p->chunks[p->chunk_ib_idx].length_dw);  		return -EINVAL;  	} + +	p->keep_tiling_flags = (flags & RADEON_CS_KEEP_TILING_FLAGS) != 0;  	return 0;  } @@ -222,7 +231,7 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)  	struct radeon_cs_chunk *ib_chunk;  	int r; -	mutex_lock(&rdev->cs_mutex); +	radeon_mutex_lock(&rdev->cs_mutex);  	/* initialize parser */  	memset(&parser, 0, sizeof(struct radeon_cs_parser));  	parser.filp = filp; @@ -233,14 +242,14 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)  	if (r) {  		DRM_ERROR("Failed to initialize parser !\n");  		radeon_cs_parser_fini(&parser, r); -		mutex_unlock(&rdev->cs_mutex); +		radeon_mutex_unlock(&rdev->cs_mutex);  		return r;  	}  	r =  radeon_ib_get(rdev, &parser.ib);  	if (r) {  		DRM_ERROR("Failed to get ib !\n");  		radeon_cs_parser_fini(&parser, r); -		mutex_unlock(&rdev->cs_mutex); +		radeon_mutex_unlock(&rdev->cs_mutex);  		return r;  	}  	r = radeon_cs_parser_relocs(&parser); @@ -248,7 +257,7 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)  		if (r != -ERESTARTSYS)  			DRM_ERROR("Failed to parse relocation %d!\n", r);  		radeon_cs_parser_fini(&parser, r); -		mutex_unlock(&rdev->cs_mutex); +		radeon_mutex_unlock(&rdev->cs_mutex);  		return r;  	}  	/* Copy the packet into the IB, the parser will read from the @@ -260,14 +269,14 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)  	if (r || parser.parser_error) {  		DRM_ERROR("Invalid command stream !\n");  		radeon_cs_parser_fini(&parser, r); -		mutex_unlock(&rdev->cs_mutex); +		radeon_mutex_unlock(&rdev->cs_mutex);  		return r;  	}  	r = radeon_cs_finish_pages(&parser);  	if (r) {  		DRM_ERROR("Invalid command stream !\n");  		radeon_cs_parser_fini(&parser, r); -		mutex_unlock(&rdev->cs_mutex); +		radeon_mutex_unlock(&rdev->cs_mutex);  		return r;  	}  	r = radeon_ib_schedule(rdev, parser.ib); @@ -275,7 +284,7 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)  		DRM_ERROR("Failed to schedule IB !\n");  	}  	radeon_cs_parser_fini(&parser, r); -	mutex_unlock(&rdev->cs_mutex); +	radeon_mutex_unlock(&rdev->cs_mutex);  	return r;  } diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index c33bc914d93..c4d00a17141 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c @@ -716,7 +716,7 @@ int radeon_device_init(struct radeon_device *rdev,  	/* mutex initialization are all done here so we  	 * can recall function without having locking issues */ -	mutex_init(&rdev->cs_mutex); +	radeon_mutex_init(&rdev->cs_mutex);  	mutex_init(&rdev->ib_pool.mutex);  	mutex_init(&rdev->cp.mutex);  	mutex_init(&rdev->dc_hw_i2c_mutex); @@ -955,6 +955,9 @@ int radeon_gpu_reset(struct radeon_device *rdev)  	int r;  	int resched; +	/* Prevent CS ioctl from interfering */ +	radeon_mutex_lock(&rdev->cs_mutex); +  	radeon_save_bios_scratch_regs(rdev);  	/* block TTM */  	resched = ttm_bo_lock_delayed_workqueue(&rdev->mman.bdev); @@ -967,10 +970,15 @@ int radeon_gpu_reset(struct radeon_device *rdev)  		radeon_restore_bios_scratch_regs(rdev);  		drm_helper_resume_force_mode(rdev->ddev);  		ttm_bo_unlock_delayed_workqueue(&rdev->mman.bdev, resched); -		return 0;  	} -	/* bad news, how to tell it to userspace ? */ -	dev_info(rdev->dev, "GPU reset failed\n"); + +	radeon_mutex_unlock(&rdev->cs_mutex); + +	if (r) { +		/* bad news, how to tell it to userspace ? */ +		dev_info(rdev->dev, "GPU reset failed\n"); +	} +  	return r;  } diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index a0b35e90948..71499fc3daf 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -53,9 +53,10 @@   *   2.9.0 - r600 tiling (s3tc,rgtc) working, SET_PREDICATION packet 3 on r600 + eg, backend query   *   2.10.0 - fusion 2D tiling   *   2.11.0 - backend map, initial compute support for the CS checker + *   2.12.0 - RADEON_CS_KEEP_TILING_FLAGS   */  #define KMS_DRIVER_MAJOR	2 -#define KMS_DRIVER_MINOR	11 +#define KMS_DRIVER_MINOR	12  #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_legacy_crtc.c b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c index 41a5d48e657..daadf211104 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c @@ -991,12 +991,6 @@ static bool radeon_crtc_mode_fixup(struct drm_crtc *crtc,  				   struct drm_display_mode *mode,  				   struct drm_display_mode *adjusted_mode)  { -	struct drm_device *dev = crtc->dev; -	struct radeon_device *rdev = dev->dev_private; - -	/* adjust pm to upcoming mode change */ -	radeon_pm_compute_clocks(rdev); -  	if (!radeon_crtc_scaling_mode_fixup(crtc, mode, adjusted_mode))  		return false;  	return true; diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index 6fabe89fa6a..78a665bd951 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c @@ -53,6 +53,24 @@ static void radeon_pm_set_clocks(struct radeon_device *rdev);  #define ACPI_AC_CLASS           "ac_adapter" +int radeon_pm_get_type_index(struct radeon_device *rdev, +			     enum radeon_pm_state_type ps_type, +			     int instance) +{ +	int i; +	int found_instance = -1; + +	for (i = 0; i < rdev->pm.num_power_states; i++) { +		if (rdev->pm.power_state[i].type == ps_type) { +			found_instance++; +			if (found_instance == instance) +				return i; +		} +	} +	/* return default if no match */ +	return rdev->pm.default_power_state_index; +} +  #ifdef CONFIG_ACPI  static int radeon_acpi_event(struct notifier_block *nb,  			     unsigned long val, diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index 617b64678fc..0bb0f5f713e 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -574,10 +574,16 @@ retry:  		return ret;  	spin_lock(&glob->lru_lock); + +	if (unlikely(list_empty(&bo->ddestroy))) { +		spin_unlock(&glob->lru_lock); +		return 0; +	} +  	ret = ttm_bo_reserve_locked(bo, interruptible,  				    no_wait_reserve, false, 0); -	if (unlikely(ret != 0) || list_empty(&bo->ddestroy)) { +	if (unlikely(ret != 0)) {  		spin_unlock(&glob->lru_lock);  		return ret;  	} diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index 03daefa7339..880e285d757 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c @@ -105,6 +105,10 @@ int vmw_du_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv,  	struct vmw_dma_buffer *dmabuf = NULL;  	int ret; +	/* A lot of the code assumes this */ +	if (handle && (width != 64 || height != 64)) +		return -EINVAL; +  	if (handle) {  		ret = vmw_user_surface_lookup_handle(dev_priv, tfile,  						     handle, &surface); @@ -410,8 +414,9 @@ static int do_surface_dirty_sou(struct vmw_private *dev_priv,  	top = clips->y1;  	bottom = clips->y2; -	clips_ptr = clips; -	for (i = 1; i < num_clips; i++, clips_ptr += inc) { +	/* skip the first clip rect */ +	for (i = 1, clips_ptr = clips + inc; +	     i < num_clips; i++, clips_ptr += inc) {  		left = min_t(int, left, (int)clips_ptr->x1);  		right = max_t(int, right, (int)clips_ptr->x2);  		top = min_t(int, top, (int)clips_ptr->y1); @@ -1323,7 +1328,10 @@ int vmw_kms_close(struct vmw_private *dev_priv)  	 * drm_encoder_cleanup which takes the lock we deadlock.  	 */  	drm_mode_config_cleanup(dev_priv->dev); -	vmw_kms_close_legacy_display_system(dev_priv); +	if (dev_priv->sou_priv) +		vmw_kms_close_screen_object_display(dev_priv); +	else +		vmw_kms_close_legacy_display_system(dev_priv);  	return 0;  } diff --git a/drivers/gpu/vga/vgaarb.c b/drivers/gpu/vga/vgaarb.c index c72f1c0b5e6..111d956d8e7 100644 --- a/drivers/gpu/vga/vgaarb.c +++ b/drivers/gpu/vga/vgaarb.c @@ -465,31 +465,29 @@ static void vga_arbiter_check_bridge_sharing(struct vga_device *vgadev)  	while (new_bus) {  		new_bridge = new_bus->self; -		if (new_bridge) { -			/* go through list of devices already registered */ -			list_for_each_entry(same_bridge_vgadev, &vga_list, list) { -				bus = same_bridge_vgadev->pdev->bus; -				bridge = bus->self; +		/* go through list of devices already registered */ +		list_for_each_entry(same_bridge_vgadev, &vga_list, list) { +			bus = same_bridge_vgadev->pdev->bus; +			bridge = bus->self; -				/* see if the share a bridge with this device */ -				if (new_bridge == bridge) { -					/* if their direct parent bridge is the same -					   as any bridge of this device then it can't be used -					   for that device */ -					same_bridge_vgadev->bridge_has_one_vga = false; -				} +			/* see if the share a bridge with this device */ +			if (new_bridge == bridge) { +				/* if their direct parent bridge is the same +				   as any bridge of this device then it can't be used +				   for that device */ +				same_bridge_vgadev->bridge_has_one_vga = false; +			} -				/* now iterate the previous devices bridge hierarchy */ -				/* if the new devices parent bridge is in the other devices -				   hierarchy then we can't use it to control this device */ -				while (bus) { -					bridge = bus->self; -					if (bridge) { -						if (bridge == vgadev->pdev->bus->self) -							vgadev->bridge_has_one_vga = false; -					} -					bus = bus->parent; +			/* now iterate the previous devices bridge hierarchy */ +			/* if the new devices parent bridge is in the other devices +			   hierarchy then we can't use it to control this device */ +			while (bus) { +				bridge = bus->self; +				if (bridge) { +					if (bridge == vgadev->pdev->bus->self) +						vgadev->bridge_has_one_vga = false;  				} +				bus = bus->parent;  			}  		}  		new_bus = new_bus->parent; @@ -993,14 +991,20 @@ static ssize_t vga_arb_write(struct file *file, const char __user * buf,  				uc = &priv->cards[i];  		} -		if (!uc) -			return -EINVAL; +		if (!uc) { +			ret_val = -EINVAL; +			goto done; +		} -		if (io_state & VGA_RSRC_LEGACY_IO && uc->io_cnt == 0) -			return -EINVAL; +		if (io_state & VGA_RSRC_LEGACY_IO && uc->io_cnt == 0) { +			ret_val = -EINVAL; +			goto done; +		} -		if (io_state & VGA_RSRC_LEGACY_MEM && uc->mem_cnt == 0) -			return -EINVAL; +		if (io_state & VGA_RSRC_LEGACY_MEM && uc->mem_cnt == 0) { +			ret_val = -EINVAL; +			goto done; +		}  		vga_put(pdev, io_state); diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 9ec854ae118..91be41f6080 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -315,7 +315,7 @@ config SENSORS_DS1621  config SENSORS_EXYNOS4_TMU  	tristate "Temperature sensor on Samsung EXYNOS4" -	depends on EXYNOS4_DEV_TMU +	depends on ARCH_EXYNOS4  	help  	  If you say yes here you get support for TMU (Thermal Managment  	  Unit) on SAMSUNG EXYNOS4 series of SoC. diff --git a/drivers/hwspinlock/u8500_hsem.c b/drivers/hwspinlock/u8500_hsem.c index 143461a95ae..86980fe0411 100644 --- a/drivers/hwspinlock/u8500_hsem.c +++ b/drivers/hwspinlock/u8500_hsem.c @@ -21,6 +21,7 @@   * General Public License for more details.   */ +#include <linux/module.h>  #include <linux/delay.h>  #include <linux/io.h>  #include <linux/pm_runtime.h> @@ -108,10 +109,8 @@ static int __devinit u8500_hsem_probe(struct platform_device *pdev)  		return -ENODEV;  	io_base = ioremap(res->start, resource_size(res)); -	if (!io_base) { -		ret = -ENOMEM; -		goto free_state; -	} +	if (!io_base) +		return -ENOMEM;  	/* make sure protocol 1 is selected */  	val = readl(io_base + HSEM_CTRL_REG); diff --git a/drivers/i2c/algos/i2c-algo-bit.c b/drivers/i2c/algos/i2c-algo-bit.c index 85584a547c2..525c7345fa0 100644 --- a/drivers/i2c/algos/i2c-algo-bit.c +++ b/drivers/i2c/algos/i2c-algo-bit.c @@ -488,7 +488,7 @@ static int bit_doAddress(struct i2c_adapter *i2c_adap, struct i2c_msg *msg)  	if (flags & I2C_M_TEN) {  		/* a ten bit address */ -		addr = 0xf0 | ((msg->addr >> 7) & 0x03); +		addr = 0xf0 | ((msg->addr >> 7) & 0x06);  		bit_dbg(2, &i2c_adap->dev, "addr0: %d\n", addr);  		/* try extended address code...*/  		ret = try_address(i2c_adap, addr, retries); @@ -498,7 +498,7 @@ static int bit_doAddress(struct i2c_adapter *i2c_adap, struct i2c_msg *msg)  			return -ENXIO;  		}  		/* the remaining 8 bit address */ -		ret = i2c_outb(i2c_adap, msg->addr & 0x7f); +		ret = i2c_outb(i2c_adap, msg->addr & 0xff);  		if ((ret != 1) && !nak_ok) {  			/* the chip did not ack / xmission error occurred */  			dev_err(&i2c_adap->dev, "died at 2nd address code\n"); diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 131079a3e29..1e5606185b4 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -539,8 +539,10 @@ i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info)  	client->dev.type = &i2c_client_type;  	client->dev.of_node = info->of_node; +	/* For 10-bit clients, add an arbitrary offset to avoid collisions */  	dev_set_name(&client->dev, "%d-%04x", i2c_adapter_id(adap), -		     client->addr); +		     client->addr | ((client->flags & I2C_CLIENT_TEN) +				     ? 0xa000 : 0));  	status = device_register(&client->dev);  	if (status)  		goto out_err; diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c index c90ce50b619..57a45ce84b2 100644 --- a/drivers/i2c/i2c-dev.c +++ b/drivers/i2c/i2c-dev.c @@ -579,7 +579,7 @@ static int i2cdev_detach_adapter(struct device *dev, void *dummy)  	return 0;  } -int i2cdev_notifier_call(struct notifier_block *nb, unsigned long action, +static int i2cdev_notifier_call(struct notifier_block *nb, unsigned long action,  			 void *data)  {  	struct device *dev = data; diff --git a/drivers/ide/cy82c693.c b/drivers/ide/cy82c693.c index 67cbcfa3512..847553fd8b9 100644 --- a/drivers/ide/cy82c693.c +++ b/drivers/ide/cy82c693.c @@ -1,7 +1,7 @@  /*   *  Copyright (C) 1998-2000 Andreas S. Krebs (akrebs@altavista.net), Maintainer   *  Copyright (C) 1998-2002 Andre Hedrick <andre@linux-ide.org>, Integrator - *  Copyright (C) 2007-2010 Bartlomiej Zolnierkiewicz + *  Copyright (C) 2007-2011 Bartlomiej Zolnierkiewicz   *   * CYPRESS CY82C693 chipset IDE controller   * @@ -90,7 +90,7 @@ static void cy82c693_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)  	u8 time_16, time_8;  	/* select primary or secondary channel */ -	if (hwif->index > 0) {  /* drive is on the secondary channel */ +	if (drive->dn > 1) {  /* drive is on the secondary channel */  		dev = pci_get_slot(dev->bus, dev->devfn+1);  		if (!dev) {  			printk(KERN_ERR "%s: tune_drive: " @@ -141,7 +141,7 @@ static void cy82c693_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)  		pci_write_config_byte(dev, CY82_IDE_SLAVE_IOW, time_16);  		pci_write_config_byte(dev, CY82_IDE_SLAVE_8BIT, time_8);  	} -	if (hwif->index > 0) +	if (drive->dn > 1)  		pci_dev_put(dev);  } diff --git a/drivers/ide/icside.c b/drivers/ide/icside.c index 4a697a238e2..8716066a2f2 100644 --- a/drivers/ide/icside.c +++ b/drivers/ide/icside.c @@ -521,8 +521,8 @@ icside_register_v6(struct icside_state *state, struct expansion_card *ec)  	if (ec->dma != NO_DMA && !request_dma(ec->dma, DRV_NAME)) {  		d.init_dma = icside_dma_init;  		d.port_ops = &icside_v6_port_ops; +	} else  		d.dma_ops = NULL; -	}  	ret = ide_host_register(host, &d, hws);  	if (ret) diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 04b09564bfa..8126824dacc 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -43,7 +43,6 @@  /* For SCSI -> ATAPI command conversion */  #include <scsi/scsi.h> -#include <linux/irq.h>  #include <linux/io.h>  #include <asm/byteorder.h>  #include <linux/uaccess.h> diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index 61fdf544fbd..3d42043fec5 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c @@ -35,7 +35,6 @@  #include <scsi/scsi_ioctl.h>  #include <asm/byteorder.h> -#include <linux/irq.h>  #include <linux/uaccess.h>  #include <linux/io.h>  #include <asm/unaligned.h> diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 7ecb1ade887..ce8237d3615 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -41,7 +41,6 @@  #include <scsi/scsi.h>  #include <asm/byteorder.h> -#include <linux/irq.h>  #include <linux/uaccess.h>  #include <linux/io.h>  #include <asm/unaligned.h> diff --git a/drivers/ide/piix.c b/drivers/ide/piix.c index b59d04c7205..1892e81fb00 100644 --- a/drivers/ide/piix.c +++ b/drivers/ide/piix.c @@ -331,7 +331,7 @@ static const struct ide_port_ops ich_port_ops = {  		.udma_mask	= udma,			\  	} -#define DECLARE_ICH_DEV(udma) \ +#define DECLARE_ICH_DEV(mwdma, udma) \  	{ \  		.name		= DRV_NAME, \  		.init_chipset	= init_chipset_ich, \ @@ -340,7 +340,7 @@ static const struct ide_port_ops ich_port_ops = {  		.port_ops	= &ich_port_ops, \  		.pio_mask	= ATA_PIO4, \  		.swdma_mask	= ATA_SWDMA2_ONLY, \ -		.mwdma_mask	= ATA_MWDMA12_ONLY, \ +		.mwdma_mask	= mwdma, \  		.udma_mask	= udma, \  	} @@ -362,13 +362,15 @@ static const struct ide_port_info piix_pci_info[] __devinitdata = {  	/* 2: PIIX4 */  	DECLARE_PIIX_DEV(ATA_UDMA2),  	/* 3: ICH0 */ -	DECLARE_ICH_DEV(ATA_UDMA2), +	DECLARE_ICH_DEV(ATA_MWDMA12_ONLY, ATA_UDMA2),  	/* 4: ICH */ -	DECLARE_ICH_DEV(ATA_UDMA4), +	DECLARE_ICH_DEV(ATA_MWDMA12_ONLY, ATA_UDMA4),  	/* 5: PIIX4 */  	DECLARE_PIIX_DEV(ATA_UDMA4), -	/* 6: ICH[2-7]/ICH[2-3]M/C-ICH/ICH5-SATA/ESB2/ICH8M */ -	DECLARE_ICH_DEV(ATA_UDMA5), +	/* 6: ICH[2-6]/ICH[2-3]M/C-ICH/ICH5-SATA/ESB2/ICH8M */ +	DECLARE_ICH_DEV(ATA_MWDMA12_ONLY, ATA_UDMA5), +	/* 7: ICH7/7-R, no MWDMA1 */ +	DECLARE_ICH_DEV(ATA_MWDMA2_ONLY, ATA_UDMA5),  };  /** @@ -438,9 +440,9 @@ static const struct pci_device_id piix_pci_tbl[] = {  #endif  	{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ESB_2),      6 },  	{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ICH6_19),    6 }, -	{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ICH7_21),    6 }, +	{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ICH7_21),    7 },  	{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_82801DB_1),  6 }, -	{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ESB2_18),    6 }, +	{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ESB2_18),    7 },  	{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ICH8_6),     6 },  	{ 0, },  }; diff --git a/drivers/ide/triflex.c b/drivers/ide/triflex.c index e53a1b78378..281c9142634 100644 --- a/drivers/ide/triflex.c +++ b/drivers/ide/triflex.c @@ -113,12 +113,26 @@ static const struct pci_device_id triflex_pci_tbl[] = {  };  MODULE_DEVICE_TABLE(pci, triflex_pci_tbl); +#ifdef CONFIG_PM +static int triflex_ide_pci_suspend(struct pci_dev *dev, pm_message_t state) +{ +	/* +	 * We must not disable or powerdown the device. +	 * APM bios refuses to suspend if IDE is not accessible. +	 */ +	pci_save_state(dev); +	return 0; +} +#else +#define triflex_ide_pci_suspend NULL +#endif +  static struct pci_driver triflex_pci_driver = {  	.name		= "TRIFLEX_IDE",  	.id_table	= triflex_pci_tbl,  	.probe		= triflex_init_one,  	.remove		= ide_pci_remove, -	.suspend	= ide_pci_suspend, +	.suspend	= triflex_ide_pci_suspend,  	.resume		= ide_pci_resume,  }; diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c index 09b93b11a27..e2a9867c19d 100644 --- a/drivers/input/mouse/elantech.c +++ b/drivers/input/mouse/elantech.c @@ -1210,18 +1210,28 @@ static int elantech_reconnect(struct psmouse *psmouse)   */  static int elantech_set_properties(struct elantech_data *etd)  { +	/* This represents the version of IC body. */  	int ver = (etd->fw_version & 0x0f0000) >> 16; +	/* Early version of Elan touchpads doesn't obey the rule. */  	if (etd->fw_version < 0x020030 || etd->fw_version == 0x020600)  		etd->hw_version = 1; -	else if (etd->fw_version < 0x150600) -		etd->hw_version = 2; -	else if (ver == 5) -		etd->hw_version = 3; -	else if (ver == 6) -		etd->hw_version = 4; -	else -		return -1; +	else { +		switch (ver) { +		case 2: +		case 4: +			etd->hw_version = 2; +			break; +		case 5: +			etd->hw_version = 3; +			break; +		case 6: +			etd->hw_version = 4; +			break; +		default: +			return -1; +		} +	}  	/*  	 * Turn on packet checking by default. diff --git a/drivers/input/serio/ams_delta_serio.c b/drivers/input/serio/ams_delta_serio.c index 4b2a42f9f0b..d4d08bd9205 100644 --- a/drivers/input/serio/ams_delta_serio.c +++ b/drivers/input/serio/ams_delta_serio.c @@ -24,6 +24,7 @@  #include <linux/irq.h>  #include <linux/serio.h>  #include <linux/slab.h> +#include <linux/module.h>  #include <asm/mach-types.h>  #include <plat/board-ams-delta.h> diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index bb9f5d31f0d..b4cfc6c8be8 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h @@ -431,6 +431,13 @@ static const struct dmi_system_id __initconst i8042_dmi_nomux_table[] = {  			DMI_MATCH(DMI_PRODUCT_NAME, "Vostro V13"),  		},  	}, +	{ +		/* Newer HP Pavilion dv4 models */ +		.matches = { +			DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), +			DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv4 Notebook PC"), +		}, +	},  	{ }  }; @@ -560,6 +567,13 @@ static const struct dmi_system_id __initconst i8042_dmi_notimeout_table[] = {  			DMI_MATCH(DMI_PRODUCT_NAME, "Vostro V13"),  		},  	}, +	{ +		/* Newer HP Pavilion dv4 models */ +		.matches = { +			DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), +			DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv4 Notebook PC"), +		}, +	},  	{ }  }; diff --git a/drivers/iommu/omap-iommu-debug.c b/drivers/iommu/omap-iommu-debug.c index 9c192e79f80..288da5c1499 100644 --- a/drivers/iommu/omap-iommu-debug.c +++ b/drivers/iommu/omap-iommu-debug.c @@ -10,6 +10,7 @@   * published by the Free Software Foundation.   */ +#include <linux/module.h>  #include <linux/err.h>  #include <linux/clk.h>  #include <linux/io.h> diff --git a/drivers/iommu/omap-iovmm.c b/drivers/iommu/omap-iovmm.c index e8fdb8830f6..46be456fcc0 100644 --- a/drivers/iommu/omap-iovmm.c +++ b/drivers/iommu/omap-iovmm.c @@ -10,6 +10,7 @@   * published by the Free Software Foundation.   */ +#include <linux/module.h>  #include <linux/err.h>  #include <linux/slab.h>  #include <linux/vmalloc.h> diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c index 661b692573e..6d5628bb060 100644 --- a/drivers/leds/led-class.c +++ b/drivers/leds/led-class.c @@ -270,11 +270,8 @@ void led_blink_set(struct led_classdev *led_cdev,  	del_timer_sync(&led_cdev->blink_timer);  	if (led_cdev->blink_set && -	    !led_cdev->blink_set(led_cdev, delay_on, delay_off)) { -		led_cdev->blink_delay_on = *delay_on; -		led_cdev->blink_delay_off = *delay_off; +	    !led_cdev->blink_set(led_cdev, delay_on, delay_off))  		return; -	}  	/* blink with 1 Hz as default if nothing specified */  	if (!*delay_on && !*delay_off) diff --git a/drivers/macintosh/via-macii.c b/drivers/macintosh/via-macii.c index 817f37a875c..c9570fcf1cc 100644 --- a/drivers/macintosh/via-macii.c +++ b/drivers/macintosh/via-macii.c @@ -159,7 +159,7 @@ int macii_init(void)  	err = macii_init_via();  	if (err) goto out; -	err = request_irq(IRQ_MAC_ADB, macii_interrupt, IRQ_FLG_LOCK, "ADB", +	err = request_irq(IRQ_MAC_ADB, macii_interrupt, 0, "ADB",  			  macii_interrupt);  	if (err) goto out; diff --git a/drivers/macintosh/via-maciisi.c b/drivers/macintosh/via-maciisi.c index 9ab5b0c34f0..34d02a91b29 100644 --- a/drivers/macintosh/via-maciisi.c +++ b/drivers/macintosh/via-maciisi.c @@ -122,8 +122,8 @@ maciisi_init(void)  		return err;  	} -	if (request_irq(IRQ_MAC_ADB, maciisi_interrupt, IRQ_FLG_LOCK | IRQ_FLG_FAST,  -			"ADB", maciisi_interrupt)) { +	if (request_irq(IRQ_MAC_ADB, maciisi_interrupt, 0, "ADB", +			maciisi_interrupt)) {  		printk(KERN_ERR "maciisi_init: can't get irq %d\n", IRQ_MAC_ADB);  		return -EAGAIN;  	} diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 472aedfb07c..297e2609217 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -3110,7 +3110,7 @@ static void handle_stripe(struct stripe_head *sh)  	struct r5dev *pdev, *qdev;  	clear_bit(STRIPE_HANDLE, &sh->state); -	if (test_and_set_bit(STRIPE_ACTIVE, &sh->state)) { +	if (test_and_set_bit_lock(STRIPE_ACTIVE, &sh->state)) {  		/* already being handled, ensure it gets handled  		 * again when current action finishes */  		set_bit(STRIPE_HANDLE, &sh->state); @@ -3159,10 +3159,14 @@ static void handle_stripe(struct stripe_head *sh)  	/* check if the array has lost more than max_degraded devices and,  	 * if so, some requests might need to be failed.  	 */ -	if (s.failed > conf->max_degraded && s.to_read+s.to_write+s.written) -		handle_failed_stripe(conf, sh, &s, disks, &s.return_bi); -	if (s.failed > conf->max_degraded && s.syncing) -		handle_failed_sync(conf, sh, &s); +	if (s.failed > conf->max_degraded) { +		sh->check_state = 0; +		sh->reconstruct_state = 0; +		if (s.to_read+s.to_write+s.written) +			handle_failed_stripe(conf, sh, &s, disks, &s.return_bi); +		if (s.syncing) +			handle_failed_sync(conf, sh, &s); +	}  	/*  	 * might be able to return some write requests if the parity blocks @@ -3371,7 +3375,7 @@ finish:  	return_io(s.return_bi); -	clear_bit(STRIPE_ACTIVE, &sh->state); +	clear_bit_unlock(STRIPE_ACTIVE, &sh->state);  }  static void raid5_activate_delayed(struct r5conf *conf) diff --git a/drivers/media/dvb/dvb-usb/mxl111sf-i2c.c b/drivers/media/dvb/dvb-usb/mxl111sf-i2c.c index 2e8c288258a..34434557ef6 100644 --- a/drivers/media/dvb/dvb-usb/mxl111sf-i2c.c +++ b/drivers/media/dvb/dvb-usb/mxl111sf-i2c.c @@ -398,7 +398,6 @@ static int mxl111sf_i2c_readagain(struct mxl111sf_state *state,  	u8 i2c_r_data[24];  	u8 i = 0;  	u8 fifo_status = 0; -	int ret;  	int status = 0;  	mxl_i2c("read %d bytes", count); @@ -418,7 +417,7 @@ static int mxl111sf_i2c_readagain(struct mxl111sf_state *state,  		i2c_w_data[4+(i*3)] = 0x00;  	} -	ret = mxl111sf_i2c_get_data(state, 0, i2c_w_data, i2c_r_data); +	mxl111sf_i2c_get_data(state, 0, i2c_w_data, i2c_r_data);  	/* Check for I2C NACK status */  	if (mxl111sf_i2c_check_status(state) == 1) { diff --git a/drivers/media/dvb/dvb-usb/mxl111sf-phy.c b/drivers/media/dvb/dvb-usb/mxl111sf-phy.c index 91dc1fc2825..b741b3a7a32 100644 --- a/drivers/media/dvb/dvb-usb/mxl111sf-phy.c +++ b/drivers/media/dvb/dvb-usb/mxl111sf-phy.c @@ -296,8 +296,7 @@ int mxl111sf_config_spi(struct mxl111sf_state *state, int onoff)  		goto fail;  	ret = mxl111sf_write_reg(state, 0x00, 0x00); -	if (mxl_fail(ret)) -		goto fail; +	mxl_fail(ret);  fail:  	return ret;  } @@ -328,11 +327,13 @@ int mxl111sf_idac_config(struct mxl111sf_state *state,  		/* set hysteresis value  reg: 0x0B<5:0> */  		ret = mxl111sf_write_reg(state, V6_IDAC_HYSTERESIS_REG,  					 (hysteresis_value & 0x3F)); +		mxl_fail(ret);  	}  	ret = mxl111sf_write_reg(state, V6_IDAC_SETTINGS_REG, val); +	mxl_fail(ret); -	return val; +	return ret;  }  /* diff --git a/drivers/media/video/s5k6aa.c b/drivers/media/video/s5k6aa.c index 2446736b787..0df7f2a4181 100644 --- a/drivers/media/video/s5k6aa.c +++ b/drivers/media/video/s5k6aa.c @@ -19,6 +19,7 @@  #include <linux/gpio.h>  #include <linux/i2c.h>  #include <linux/media.h> +#include <linux/module.h>  #include <linux/regulator/consumer.h>  #include <linux/slab.h> diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_dec.c b/drivers/media/video/s5p-mfc/s5p_mfc_dec.c index 725634d9736..844a4d7797b 100644 --- a/drivers/media/video/s5p-mfc/s5p_mfc_dec.c +++ b/drivers/media/video/s5p-mfc/s5p_mfc_dec.c @@ -220,8 +220,8 @@ static int vidioc_querycap(struct file *file, void *priv,  	strncpy(cap->card, dev->plat_dev->name, sizeof(cap->card) - 1);  	cap->bus_info[0] = 0;  	cap->version = KERNEL_VERSION(1, 0, 0); -	cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT -						    | V4L2_CAP_STREAMING; +	cap->capabilities = V4L2_CAP_VIDEO_CAPTURE_MPLANE | +			V4L2_CAP_VIDEO_OUTPUT_MPLANE | V4L2_CAP_STREAMING;  	return 0;  } diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_enc.c b/drivers/media/video/s5p-mfc/s5p_mfc_enc.c index ecef127dbc6..1e8cdb77d4b 100644 --- a/drivers/media/video/s5p-mfc/s5p_mfc_enc.c +++ b/drivers/media/video/s5p-mfc/s5p_mfc_enc.c @@ -785,8 +785,8 @@ static int vidioc_querycap(struct file *file, void *priv,  	strncpy(cap->card, dev->plat_dev->name, sizeof(cap->card) - 1);  	cap->bus_info[0] = 0;  	cap->version = KERNEL_VERSION(1, 0, 0); -	cap->capabilities = V4L2_CAP_VIDEO_CAPTURE -			  | V4L2_CAP_VIDEO_OUTPUT +	cap->capabilities = V4L2_CAP_VIDEO_CAPTURE_MPLANE +			  | V4L2_CAP_VIDEO_OUTPUT_MPLANE  			  | V4L2_CAP_STREAMING;  	return 0;  } diff --git a/drivers/media/video/uvc/uvc_ctrl.c b/drivers/media/video/uvc/uvc_ctrl.c index 10c2364f3e8..254d3268884 100644 --- a/drivers/media/video/uvc/uvc_ctrl.c +++ b/drivers/media/video/uvc/uvc_ctrl.c @@ -1016,7 +1016,8 @@ int uvc_query_v4l2_menu(struct uvc_video_chain *chain,  	menu_info = &mapping->menu_info[query_menu->index]; -	if (ctrl->info.flags & UVC_CTRL_FLAG_GET_RES) { +	if (mapping->data_type == UVC_CTRL_DATA_TYPE_BITMASK && +	    (ctrl->info.flags & UVC_CTRL_FLAG_GET_RES)) {  		s32 bitmap;  		if (!ctrl->cached) { @@ -1225,7 +1226,8 @@ int uvc_ctrl_set(struct uvc_video_chain *chain,  		/* Valid menu indices are reported by the GET_RES request for  		 * UVC controls that support it.  		 */ -		if (ctrl->info.flags & UVC_CTRL_FLAG_GET_RES) { +		if (mapping->data_type == UVC_CTRL_DATA_TYPE_BITMASK && +		    (ctrl->info.flags & UVC_CTRL_FLAG_GET_RES)) {  			if (!ctrl->cached) {  				ret = uvc_ctrl_populate_cache(chain, ctrl);  				if (ret < 0) diff --git a/drivers/media/video/v4l2-ctrls.c b/drivers/media/video/v4l2-ctrls.c index f17f92b86a3..0f415dade05 100644 --- a/drivers/media/video/v4l2-ctrls.c +++ b/drivers/media/video/v4l2-ctrls.c @@ -821,8 +821,8 @@ static void send_event(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl, u32 changes)  	fill_event(&ev, ctrl, changes);  	list_for_each_entry(sev, &ctrl->ev_subs, node) -		if (sev->fh && (sev->fh != fh || -				(sev->flags & V4L2_EVENT_SUB_FL_ALLOW_FEEDBACK))) +		if (sev->fh != fh || +		    (sev->flags & V4L2_EVENT_SUB_FL_ALLOW_FEEDBACK))  			v4l2_event_queue_fh(sev->fh, &ev);  } @@ -947,6 +947,7 @@ static void new_to_cur(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl,  			if (ctrl->cluster[0]->has_volatiles)  				ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;  		} +		fh = NULL;  	}  	if (changed || update_inactive) {  		/* If a control was changed that was not one of the controls diff --git a/drivers/media/video/v4l2-event.c b/drivers/media/video/v4l2-event.c index 46037f22552..c26ad963714 100644 --- a/drivers/media/video/v4l2-event.c +++ b/drivers/media/video/v4l2-event.c @@ -216,6 +216,9 @@ int v4l2_event_subscribe(struct v4l2_fh *fh,  	unsigned long flags;  	unsigned i; +	if (sub->type == V4L2_EVENT_ALL) +		return -EINVAL; +  	if (elems < 1)  		elems = 1;  	if (sub->type == V4L2_EVENT_CTRL) { @@ -283,6 +286,7 @@ int v4l2_event_unsubscribe(struct v4l2_fh *fh,  {  	struct v4l2_subscribed_event *sev;  	unsigned long flags; +	int i;  	if (sub->type == V4L2_EVENT_ALL) {  		v4l2_event_unsubscribe_all(fh); @@ -293,8 +297,12 @@ int v4l2_event_unsubscribe(struct v4l2_fh *fh,  	sev = v4l2_event_subscribed(fh, sub->type, sub->id);  	if (sev != NULL) { +		/* Remove any pending events for this subscription */ +		for (i = 0; i < sev->in_use; i++) { +			list_del(&sev->events[sev_pos(sev, i)].list); +			fh->navailable--; +		}  		list_del(&sev->list); -		sev->fh = NULL;  	}  	spin_unlock_irqrestore(&fh->vdev->fh_lock, flags); diff --git a/drivers/media/video/videobuf2-core.c b/drivers/media/video/videobuf2-core.c index 979e544388c..95a3f5e82ae 100644 --- a/drivers/media/video/videobuf2-core.c +++ b/drivers/media/video/videobuf2-core.c @@ -131,6 +131,7 @@ static void __setup_offsets(struct vb2_queue *q, unsigned int n)  			continue;  		for (plane = 0; plane < vb->num_planes; ++plane) { +			vb->v4l2_planes[plane].length = q->plane_sizes[plane];  			vb->v4l2_planes[plane].m.mem_offset = off;  			dprintk(3, "Buffer %d, plane %d offset 0x%08lx\n", @@ -264,6 +265,7 @@ static void __vb2_queue_free(struct vb2_queue *q, unsigned int buffers)  	q->num_buffers -= buffers;  	if (!q->num_buffers)  		q->memory = 0; +	INIT_LIST_HEAD(&q->queued_list);  }  /** @@ -296,14 +298,14 @@ static bool __buffer_in_use(struct vb2_queue *q, struct vb2_buffer *vb)  {  	unsigned int plane;  	for (plane = 0; plane < vb->num_planes; ++plane) { +		void *mem_priv = vb->planes[plane].mem_priv;  		/*  		 * If num_users() has not been provided, call_memop  		 * will return 0, apparently nobody cares about this  		 * case anyway. If num_users() returns more than 1,  		 * we are not the only user of the plane's memory.  		 */ -		if (call_memop(q, plane, num_users, -				vb->planes[plane].mem_priv) > 1) +		if (mem_priv && call_memop(q, plane, num_users, mem_priv) > 1)  			return true;  	}  	return false; diff --git a/drivers/mfd/ab5500-core.c b/drivers/mfd/ab5500-core.c index 4175544b491..ec10629a0b0 100644 --- a/drivers/mfd/ab5500-core.c +++ b/drivers/mfd/ab5500-core.c @@ -13,6 +13,7 @@   * TODO: Event handling with irq_chip. Waiting for PRCMU fw support.   */ +#include <linux/module.h>  #include <linux/mutex.h>  #include <linux/err.h>  #include <linux/platform_device.h> diff --git a/drivers/mfd/ab5500-debugfs.c b/drivers/mfd/ab5500-debugfs.c index 6be1fe6b5f9..43c0ebb8195 100644 --- a/drivers/mfd/ab5500-debugfs.c +++ b/drivers/mfd/ab5500-debugfs.c @@ -4,6 +4,7 @@   * Debugfs support for the AB5500 MFD driver   */ +#include <linux/export.h>  #include <linux/debugfs.h>  #include <linux/seq_file.h>  #include <linux/mfd/ab5500/ab5500.h> diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index d593878d66d..5664696f2d3 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -472,7 +472,7 @@ config BMP085  	  module will be called bmp085.  config PCH_PHUB -	tristate "Intel EG20T PCH / OKI SEMICONDUCTOR IOH(ML7213/ML7223) PHUB" +	tristate "Intel EG20T PCH/LAPIS Semicon IOH(ML7213/ML7223/ML7831) PHUB"  	depends on PCI  	help  	  This driver is for PCH(Platform controller Hub) PHUB(Packet Hub) of @@ -480,12 +480,13 @@ config PCH_PHUB  	  processor. The Topcliff has MAC address and Option ROM data in SROM.  	  This driver can access MAC address and Option ROM data in SROM. -	  This driver also can be used for OKI SEMICONDUCTOR IOH(Input/ -	  Output Hub), ML7213 and ML7223. -	  ML7213 IOH is for IVI(In-Vehicle Infotainment) use and ML7223 IOH is -	  for MP(Media Phone) use. -	  ML7213/ML7223 is companion chip for Intel Atom E6xx series. -	  ML7213/ML7223 is completely compatible for Intel EG20T PCH. +	  This driver also can be used for LAPIS Semiconductor's IOH, +	  ML7213/ML7223/ML7831. +	  ML7213 which is for IVI(In-Vehicle Infotainment) use. +	  ML7223 IOH is for MP(Media Phone) use. +	  ML7831 IOH is for general purpose use. +	  ML7213/ML7223/ML7831 is companion chip for Intel Atom E6xx series. +	  ML7213/ML7223/ML7831 is completely compatible for Intel EG20T PCH.  	  To compile this driver as a module, choose M here: the module will  	  be called pch_phub. diff --git a/drivers/misc/ad525x_dpot.h b/drivers/misc/ad525x_dpot.h index a662f5987b6..82b2cb77ae1 100644 --- a/drivers/misc/ad525x_dpot.h +++ b/drivers/misc/ad525x_dpot.h @@ -100,7 +100,7 @@ enum dpot_devid {  	AD5293_ID = DPOT_CONF(F_RDACS_RW | F_SPI_16BIT, BRDAC0, 10, 27),  	AD7376_ID = DPOT_CONF(F_RDACS_WONLY | F_AD_APPDATA | F_SPI_8BIT,  			BRDAC0, 7, 28), -	AD8400_ID = DPOT_CONF(F_RDACS_WONLY | F_AD_APPDATA | F_SPI_8BIT, +	AD8400_ID = DPOT_CONF(F_RDACS_WONLY | F_AD_APPDATA | F_SPI_16BIT,  			BRDAC0, 8, 29),  	AD8402_ID = DPOT_CONF(F_RDACS_WONLY | F_AD_APPDATA | F_SPI_16BIT,  			BRDAC0 | BRDAC1, 8, 30), diff --git a/drivers/misc/carma/carma-fpga-program.c b/drivers/misc/carma/carma-fpga-program.c index 7ce6065dc20..eb5cd28bc6d 100644 --- a/drivers/misc/carma/carma-fpga-program.c +++ b/drivers/misc/carma/carma-fpga-program.c @@ -945,8 +945,7 @@ static int fpga_of_remove(struct platform_device *op)  /* CTL-CPLD Version Register */  #define CTL_CPLD_VERSION	0x2000 -static int fpga_of_probe(struct platform_device *op, -			 const struct of_device_id *match) +static int fpga_of_probe(struct platform_device *op)  {  	struct device_node *of_node = op->dev.of_node;  	struct device *this_device; @@ -1107,7 +1106,7 @@ static struct of_device_id fpga_of_match[] = {  	{},  }; -static struct of_platform_driver fpga_of_driver = { +static struct platform_driver fpga_of_driver = {  	.probe		= fpga_of_probe,  	.remove		= fpga_of_remove,  	.driver		= { @@ -1124,12 +1123,12 @@ static struct of_platform_driver fpga_of_driver = {  static int __init fpga_init(void)  {  	led_trigger_register_simple("fpga", &ledtrig_fpga); -	return of_register_platform_driver(&fpga_of_driver); +	return platform_driver_register(&fpga_of_driver);  }  static void __exit fpga_exit(void)  { -	of_unregister_platform_driver(&fpga_of_driver); +	platform_driver_unregister(&fpga_of_driver);  	led_trigger_unregister_simple(ledtrig_fpga);  } diff --git a/drivers/misc/carma/carma-fpga.c b/drivers/misc/carma/carma-fpga.c index 3965821fef1..14e974b2a78 100644 --- a/drivers/misc/carma/carma-fpga.c +++ b/drivers/misc/carma/carma-fpga.c @@ -1249,8 +1249,7 @@ static bool dma_filter(struct dma_chan *chan, void *data)  	return true;  } -static int data_of_probe(struct platform_device *op, -			 const struct of_device_id *match) +static int data_of_probe(struct platform_device *op)  {  	struct device_node *of_node = op->dev.of_node;  	struct device *this_device; @@ -1401,7 +1400,7 @@ static struct of_device_id data_of_match[] = {  	{},  }; -static struct of_platform_driver data_of_driver = { +static struct platform_driver data_of_driver = {  	.probe		= data_of_probe,  	.remove		= data_of_remove,  	.driver		= { @@ -1417,12 +1416,12 @@ static struct of_platform_driver data_of_driver = {  static int __init data_init(void)  { -	return of_register_platform_driver(&data_of_driver); +	return platform_driver_register(&data_of_driver);  }  static void __exit data_exit(void)  { -	of_unregister_platform_driver(&data_of_driver); +	platform_driver_unregister(&data_of_driver);  }  MODULE_AUTHOR("Ira W. Snyder <iws@ovro.caltech.edu>"); diff --git a/drivers/misc/eeprom/Kconfig b/drivers/misc/eeprom/Kconfig index 26cf12ca7f5..701edf65897 100644 --- a/drivers/misc/eeprom/Kconfig +++ b/drivers/misc/eeprom/Kconfig @@ -85,7 +85,7 @@ config EEPROM_93XX46  config EEPROM_DIGSY_MTC_CFG  	bool "DigsyMTC display configuration EEPROMs device" -	depends on PPC_MPC5200_GPIO && GPIOLIB && SPI_GPIO +	depends on GPIO_MPC5200 && SPI_GPIO  	help  	  This option enables access to display configuration EEPROMs  	  on digsy_mtc board. You have to additionally select Microwire diff --git a/drivers/misc/pch_phub.c b/drivers/misc/pch_phub.c index dee33addcae..10fc4785dba 100644 --- a/drivers/misc/pch_phub.c +++ b/drivers/misc/pch_phub.c @@ -1,5 +1,5 @@  /* - * Copyright (C) 2010 OKI SEMICONDUCTOR CO., LTD. + * Copyright (C) 2011 LAPIS Semiconductor Co., Ltd.   *   * This program is free software; you can redistribute it and/or modify   * it under the terms of the GNU General Public License as published by @@ -41,10 +41,10 @@  #define PCH_PHUB_ROM_START_ADDR_EG20T 0x80 /* ROM data area start address offset  					      (Intel EG20T PCH)*/  #define PCH_PHUB_ROM_START_ADDR_ML7213 0x400 /* ROM data area start address -						offset(OKI SEMICONDUCTOR ML7213) +						offset(LAPIS Semicon ML7213)  					      */  #define PCH_PHUB_ROM_START_ADDR_ML7223 0x400 /* ROM data area start address -						offset(OKI SEMICONDUCTOR ML7223) +						offset(LAPIS Semicon ML7223)  					      */  /* MAX number of INT_REDUCE_CONTROL registers */ @@ -73,6 +73,9 @@  #define PCI_DEVICE_ID_ROHM_ML7223_mPHUB	0x8012 /* for Bus-m */  #define PCI_DEVICE_ID_ROHM_ML7223_nPHUB	0x8002 /* for Bus-n */ +/* Macros for ML7831 */ +#define PCI_DEVICE_ID_ROHM_ML7831_PHUB 0x8801 +  /* SROM ACCESS Macro */  #define PCH_WORD_ADDR_MASK (~((1 << 2) - 1)) @@ -115,6 +118,7 @@   * @pch_mac_start_address:		MAC address area start address   * @pch_opt_rom_start_address:		Option ROM start address   * @ioh_type:				Save IOH type + * @pdev:				pointer to pci device struct   */  struct pch_phub_reg {  	u32 phub_id_reg; @@ -136,6 +140,7 @@ struct pch_phub_reg {  	u32 pch_mac_start_address;  	u32 pch_opt_rom_start_address;  	int ioh_type; +	struct pci_dev *pdev;  };  /* SROM SPEC for MAC address assignment offset */ @@ -471,7 +476,7 @@ static int pch_phub_write_gbe_mac_addr(struct pch_phub_reg *chip, u8 *data)  	int retval;  	int i; -	if (chip->ioh_type == 1) /* EG20T */ +	if ((chip->ioh_type == 1) || (chip->ioh_type == 5)) /* EG20T or ML7831*/  		retval = pch_phub_gbe_serial_rom_conf(chip);  	else	/* ML7223 */  		retval = pch_phub_gbe_serial_rom_conf_mp(chip); @@ -498,6 +503,7 @@ static ssize_t pch_phub_bin_read(struct file *filp, struct kobject *kobj,  	unsigned int orom_size;  	int ret;  	int err; +	ssize_t rom_size;  	struct pch_phub_reg *chip =  		dev_get_drvdata(container_of(kobj, struct device, kobj)); @@ -509,6 +515,10 @@ static ssize_t pch_phub_bin_read(struct file *filp, struct kobject *kobj,  	}  	/* Get Rom signature */ +	chip->pch_phub_extrom_base_address = pci_map_rom(chip->pdev, &rom_size); +	if (!chip->pch_phub_extrom_base_address) +		goto exrom_map_err; +  	pch_phub_read_serial_rom(chip, chip->pch_opt_rom_start_address,  				(unsigned char *)&rom_signature);  	rom_signature &= 0xff; @@ -539,10 +549,13 @@ static ssize_t pch_phub_bin_read(struct file *filp, struct kobject *kobj,  		goto return_err;  	}  return_ok: +	pci_unmap_rom(chip->pdev, chip->pch_phub_extrom_base_address);  	mutex_unlock(&pch_phub_mutex);  	return addr_offset;  return_err: +	pci_unmap_rom(chip->pdev, chip->pch_phub_extrom_base_address); +exrom_map_err:  	mutex_unlock(&pch_phub_mutex);  return_err_nomutex:  	return err; @@ -555,6 +568,7 @@ static ssize_t pch_phub_bin_write(struct file *filp, struct kobject *kobj,  	int err;  	unsigned int addr_offset;  	int ret; +	ssize_t rom_size;  	struct pch_phub_reg *chip =  		dev_get_drvdata(container_of(kobj, struct device, kobj)); @@ -571,6 +585,12 @@ static ssize_t pch_phub_bin_write(struct file *filp, struct kobject *kobj,  		goto return_ok;  	} +	chip->pch_phub_extrom_base_address = pci_map_rom(chip->pdev, &rom_size); +	if (!chip->pch_phub_extrom_base_address) { +		err = -ENOMEM; +		goto exrom_map_err; +	} +  	for (addr_offset = 0; addr_offset < count; addr_offset++) {  		if (PCH_PHUB_OROM_SIZE < off + addr_offset)  			goto return_ok; @@ -585,10 +605,14 @@ static ssize_t pch_phub_bin_write(struct file *filp, struct kobject *kobj,  	}  return_ok: +	pci_unmap_rom(chip->pdev, chip->pch_phub_extrom_base_address);  	mutex_unlock(&pch_phub_mutex);  	return addr_offset;  return_err: +	pci_unmap_rom(chip->pdev, chip->pch_phub_extrom_base_address); + +exrom_map_err:  	mutex_unlock(&pch_phub_mutex);  	return err;  } @@ -598,8 +622,14 @@ static ssize_t show_pch_mac(struct device *dev, struct device_attribute *attr,  {  	u8 mac[8];  	struct pch_phub_reg *chip = dev_get_drvdata(dev); +	ssize_t rom_size; + +	chip->pch_phub_extrom_base_address = pci_map_rom(chip->pdev, &rom_size); +	if (!chip->pch_phub_extrom_base_address) +		return -ENOMEM;  	pch_phub_read_gbe_mac_addr(chip, mac); +	pci_unmap_rom(chip->pdev, chip->pch_phub_extrom_base_address);  	return sprintf(buf, "%pM\n", mac);  } @@ -608,6 +638,7 @@ static ssize_t store_pch_mac(struct device *dev, struct device_attribute *attr,  			     const char *buf, size_t count)  {  	u8 mac[6]; +	ssize_t rom_size;  	struct pch_phub_reg *chip = dev_get_drvdata(dev);  	if (count != 18) @@ -617,7 +648,12 @@ static ssize_t store_pch_mac(struct device *dev, struct device_attribute *attr,  		(u32 *)&mac[0], (u32 *)&mac[1], (u32 *)&mac[2], (u32 *)&mac[3],  		(u32 *)&mac[4], (u32 *)&mac[5]); +	chip->pch_phub_extrom_base_address = pci_map_rom(chip->pdev, &rom_size); +	if (!chip->pch_phub_extrom_base_address) +		return -ENOMEM; +  	pch_phub_write_gbe_mac_addr(chip, mac); +	pci_unmap_rom(chip->pdev, chip->pch_phub_extrom_base_address);  	return count;  } @@ -640,7 +676,6 @@ static int __devinit pch_phub_probe(struct pci_dev *pdev,  	int retval;  	int ret; -	ssize_t rom_size;  	struct pch_phub_reg *chip;  	chip = kzalloc(sizeof(struct pch_phub_reg), GFP_KERNEL); @@ -677,19 +712,7 @@ static int __devinit pch_phub_probe(struct pci_dev *pdev,  		"in pch_phub_base_address variable is %p\n", __func__,  		chip->pch_phub_base_address); -	if (id->driver_data != 3) { -		chip->pch_phub_extrom_base_address =\ -						   pci_map_rom(pdev, &rom_size); -		if (chip->pch_phub_extrom_base_address == 0) { -			dev_err(&pdev->dev, "%s: pci_map_rom FAILED", __func__); -			ret = -ENOMEM; -			goto err_pci_map; -		} -		dev_dbg(&pdev->dev, "%s : " -			"pci_map_rom SUCCESS and value in " -			"pch_phub_extrom_base_address variable is %p\n", -			__func__, chip->pch_phub_extrom_base_address); -	} +	chip->pdev = pdev; /* Save pci device struct */  	if (id->driver_data == 1) { /* EG20T PCH */  		const char *board_name; @@ -763,6 +786,22 @@ static int __devinit pch_phub_probe(struct pci_dev *pdev,  		chip->pch_opt_rom_start_address =\  						 PCH_PHUB_ROM_START_ADDR_ML7223;  		chip->pch_mac_start_address = PCH_PHUB_MAC_START_ADDR_ML7223; +	} else if (id->driver_data == 5) { /* ML7831 */ +		retval = sysfs_create_file(&pdev->dev.kobj, +					   &dev_attr_pch_mac.attr); +		if (retval) +			goto err_sysfs_create; + +		retval = sysfs_create_bin_file(&pdev->dev.kobj, &pch_bin_attr); +		if (retval) +			goto exit_bin_attr; + +		/* set the prefech value */ +		iowrite32(0x000affaa, chip->pch_phub_base_address + 0x14); +		/* set the interrupt delay value */ +		iowrite32(0x25, chip->pch_phub_base_address + 0x44); +		chip->pch_opt_rom_start_address = PCH_PHUB_ROM_START_ADDR_EG20T; +		chip->pch_mac_start_address = PCH_PHUB_MAC_START_ADDR_EG20T;  	}  	chip->ioh_type = id->driver_data; @@ -773,8 +812,6 @@ exit_bin_attr:  	sysfs_remove_file(&pdev->dev.kobj, &dev_attr_pch_mac.attr);  err_sysfs_create: -	pci_unmap_rom(pdev, chip->pch_phub_extrom_base_address); -err_pci_map:  	pci_iounmap(pdev, chip->pch_phub_base_address);  err_pci_iomap:  	pci_release_regions(pdev); @@ -792,7 +829,6 @@ static void __devexit pch_phub_remove(struct pci_dev *pdev)  	sysfs_remove_file(&pdev->dev.kobj, &dev_attr_pch_mac.attr);  	sysfs_remove_bin_file(&pdev->dev.kobj, &pch_bin_attr); -	pci_unmap_rom(pdev, chip->pch_phub_extrom_base_address);  	pci_iounmap(pdev, chip->pch_phub_base_address);  	pci_release_regions(pdev);  	pci_disable_device(pdev); @@ -847,6 +883,7 @@ static struct pci_device_id pch_phub_pcidev_id[] = {  	{ PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ROHM_ML7213_PHUB), 2,  },  	{ PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ROHM_ML7223_mPHUB), 3,  },  	{ PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ROHM_ML7223_nPHUB), 4,  }, +	{ PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ROHM_ML7831_PHUB), 5,  },  	{ }  };  MODULE_DEVICE_TABLE(pci, pch_phub_pcidev_id); @@ -873,5 +910,5 @@ static void __exit pch_phub_pci_exit(void)  module_init(pch_phub_pci_init);  module_exit(pch_phub_pci_exit); -MODULE_DESCRIPTION("Intel EG20T PCH/OKI SEMICONDUCTOR IOH(ML7213/ML7223) PHUB"); +MODULE_DESCRIPTION("Intel EG20T PCH/LAPIS Semiconductor IOH(ML7213/ML7223) PHUB");  MODULE_LICENSE("GPL"); diff --git a/drivers/misc/spear13xx_pcie_gadget.c b/drivers/misc/spear13xx_pcie_gadget.c index cfbddbef11d..43d073bc1d9 100644 --- a/drivers/misc/spear13xx_pcie_gadget.c +++ b/drivers/misc/spear13xx_pcie_gadget.c @@ -903,6 +903,6 @@ static void __exit spear_pcie_gadget_exit(void)  }  module_exit(spear_pcie_gadget_exit); -MODULE_ALIAS("pcie-gadget-spear"); +MODULE_ALIAS("platform:pcie-gadget-spear");  MODULE_AUTHOR("Pratyush Anand");  MODULE_LICENSE("GPL"); diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c index ae57769ba50..4b976f00ea8 100644 --- a/drivers/mmc/host/sdhci-esdhc-imx.c +++ b/drivers/mmc/host/sdhci-esdhc-imx.c @@ -32,6 +32,7 @@  /* VENDOR SPEC register */  #define SDHCI_VENDOR_SPEC		0xC0  #define  SDHCI_VENDOR_SPEC_SDIO_QUIRK	0x00000002 +#define SDHCI_WTMK_LVL			0x44  #define SDHCI_MIX_CTRL			0x48  /* @@ -476,6 +477,13 @@ static int __devinit sdhci_esdhc_imx_probe(struct platform_device *pdev)  	if (is_imx53_esdhc(imx_data))  		imx_data->flags |= ESDHC_FLAG_MULTIBLK_NO_INT; +	/* +	 * The imx6q ROM code will change the default watermark level setting +	 * to something insane.  Change it back here. +	 */ +	if (is_imx6q_usdhc(imx_data)) +		writel(0x08100810, host->ioaddr + SDHCI_WTMK_LVL); +  	boarddata = &imx_data->boarddata;  	if (sdhci_esdhc_imx_probe_dt(pdev, boarddata) < 0) {  		if (!host->mmc->parent->platform_data) { diff --git a/drivers/mtd/maps/bcm963xx-flash.c b/drivers/mtd/maps/bcm963xx-flash.c index 608967fe74c..736ca10ca9f 100644 --- a/drivers/mtd/maps/bcm963xx-flash.c +++ b/drivers/mtd/maps/bcm963xx-flash.c @@ -21,6 +21,7 @@  #include <linux/init.h>  #include <linux/kernel.h>  #include <linux/slab.h> +#include <linux/module.h>  #include <linux/mtd/map.h>  #include <linux/mtd/mtd.h>  #include <linux/mtd/partitions.h> diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 583f66cd5bb..654a5e94e0e 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -245,6 +245,8 @@ source "drivers/net/ethernet/Kconfig"  source "drivers/net/fddi/Kconfig" +source "drivers/net/hippi/Kconfig" +  config NET_SB1000  	tristate "General Instruments Surfboard 1000"  	depends on PNP diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c index 5a20804fdec..4ef7e2fd9fe 100644 --- a/drivers/net/bonding/bond_sysfs.c +++ b/drivers/net/bonding/bond_sysfs.c @@ -319,6 +319,13 @@ static ssize_t bonding_store_mode(struct device *d,  		goto out;  	} +	if (bond->slave_cnt > 0) { +		pr_err("unable to update mode of %s because it has slaves.\n", +			bond->dev->name); +		ret = -EPERM; +		goto out; +	} +  	new_value = bond_parse_parm(buf, bond_mode_tbl);  	if (new_value < 0)  {  		pr_err("%s: Ignoring invalid mode value %.*s.\n", diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 6486ab8c8fc..2f6361e949f 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -10548,33 +10548,38 @@ do {									\  int bnx2x_init_firmware(struct bnx2x *bp)  { -	const char *fw_file_name;  	struct bnx2x_fw_file_hdr *fw_hdr;  	int rc; -	if (CHIP_IS_E1(bp)) -		fw_file_name = FW_FILE_NAME_E1; -	else if (CHIP_IS_E1H(bp)) -		fw_file_name = FW_FILE_NAME_E1H; -	else if (!CHIP_IS_E1x(bp)) -		fw_file_name = FW_FILE_NAME_E2; -	else { -		BNX2X_ERR("Unsupported chip revision\n"); -		return -EINVAL; -	} -	BNX2X_DEV_INFO("Loading %s\n", fw_file_name); +	if (!bp->firmware) { +		const char *fw_file_name; -	rc = request_firmware(&bp->firmware, fw_file_name, &bp->pdev->dev); -	if (rc) { -		BNX2X_ERR("Can't load firmware file %s\n", fw_file_name); -		goto request_firmware_exit; -	} +		if (CHIP_IS_E1(bp)) +			fw_file_name = FW_FILE_NAME_E1; +		else if (CHIP_IS_E1H(bp)) +			fw_file_name = FW_FILE_NAME_E1H; +		else if (!CHIP_IS_E1x(bp)) +			fw_file_name = FW_FILE_NAME_E2; +		else { +			BNX2X_ERR("Unsupported chip revision\n"); +			return -EINVAL; +		} +		BNX2X_DEV_INFO("Loading %s\n", fw_file_name); -	rc = bnx2x_check_firmware(bp); -	if (rc) { -		BNX2X_ERR("Corrupt firmware file %s\n", fw_file_name); -		goto request_firmware_exit; +		rc = request_firmware(&bp->firmware, fw_file_name, +				      &bp->pdev->dev); +		if (rc) { +			BNX2X_ERR("Can't load firmware file %s\n", +				  fw_file_name); +			goto request_firmware_exit; +		} + +		rc = bnx2x_check_firmware(bp); +		if (rc) { +			BNX2X_ERR("Corrupt firmware file %s\n", fw_file_name); +			goto request_firmware_exit; +		}  	}  	fw_hdr = (struct bnx2x_fw_file_hdr *)bp->firmware->data; @@ -10630,6 +10635,7 @@ static void bnx2x_release_firmware(struct bnx2x *bp)  	kfree(bp->init_ops);  	kfree(bp->init_data);  	release_firmware(bp->firmware); +	bp->firmware = NULL;  } @@ -10925,6 +10931,8 @@ static void __devexit bnx2x_remove_one(struct pci_dev *pdev)  	if (bp->doorbells)  		iounmap(bp->doorbells); +	bnx2x_release_firmware(bp); +  	bnx2x_free_mem_bp(bp);  	free_netdev(dev); diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c index 0440425c83d..14517691f8d 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c @@ -5380,7 +5380,7 @@ static int bnx2x_func_hw_init(struct bnx2x *bp,  	rc = drv->init_fw(bp);  	if (rc) {  		BNX2X_ERR("Error loading firmware\n"); -		goto fw_init_err; +		goto init_err;  	}  	/* Handle the beginning of COMMON_XXX pases separatelly... */ @@ -5388,25 +5388,25 @@ static int bnx2x_func_hw_init(struct bnx2x *bp,  	case FW_MSG_CODE_DRV_LOAD_COMMON_CHIP:  		rc = bnx2x_func_init_cmn_chip(bp, drv);  		if (rc) -			goto init_hw_err; +			goto init_err;  		break;  	case FW_MSG_CODE_DRV_LOAD_COMMON:  		rc = bnx2x_func_init_cmn(bp, drv);  		if (rc) -			goto init_hw_err; +			goto init_err;  		break;  	case FW_MSG_CODE_DRV_LOAD_PORT:  		rc = bnx2x_func_init_port(bp, drv);  		if (rc) -			goto init_hw_err; +			goto init_err;  		break;  	case FW_MSG_CODE_DRV_LOAD_FUNCTION:  		rc = bnx2x_func_init_func(bp, drv);  		if (rc) -			goto init_hw_err; +			goto init_err;  		break;  	default: @@ -5414,10 +5414,7 @@ static int bnx2x_func_hw_init(struct bnx2x *bp,  		rc = -EINVAL;  	} -init_hw_err: -	drv->release_fw(bp); - -fw_init_err: +init_err:  	drv->gunzip_end(bp);  	/* In case of success, complete the comand immediatelly: no ramrods diff --git a/drivers/net/ethernet/cadence/Kconfig b/drivers/net/ethernet/cadence/Kconfig index 98849a1fc74..b48378a41e4 100644 --- a/drivers/net/ethernet/cadence/Kconfig +++ b/drivers/net/ethernet/cadence/Kconfig @@ -7,6 +7,7 @@ config HAVE_NET_MACB  config NET_ATMEL  	bool "Atmel devices" +	default y  	depends on HAVE_NET_MACB || (ARM && ARCH_AT91RM9200)  	---help---  	  If you have a network (Ethernet) card belonging to this class, say Y. diff --git a/drivers/net/ethernet/lantiq_etop.c b/drivers/net/ethernet/lantiq_etop.c index 6bb2b9506ca..0b3567ab812 100644 --- a/drivers/net/ethernet/lantiq_etop.c +++ b/drivers/net/ethernet/lantiq_etop.c @@ -34,6 +34,8 @@  #include <linux/init.h>  #include <linux/delay.h>  #include <linux/io.h> +#include <linux/dma-mapping.h> +#include <linux/module.h>  #include <asm/checksum.h> diff --git a/drivers/net/ethernet/marvell/sky2.c b/drivers/net/ethernet/marvell/sky2.c index fdc6c394c68..7803efa46eb 100644 --- a/drivers/net/ethernet/marvell/sky2.c +++ b/drivers/net/ethernet/marvell/sky2.c @@ -50,7 +50,7 @@  #include "sky2.h"  #define DRV_NAME		"sky2" -#define DRV_VERSION		"1.29" +#define DRV_VERSION		"1.30"  /*   * The Yukon II chipset takes 64 bit command blocks (called list elements) @@ -68,7 +68,7 @@  #define MAX_SKB_TX_LE	(2 + (sizeof(dma_addr_t)/sizeof(u32))*(MAX_SKB_FRAGS+1))  #define TX_MIN_PENDING		(MAX_SKB_TX_LE+1)  #define TX_MAX_PENDING		1024 -#define TX_DEF_PENDING		127 +#define TX_DEF_PENDING		63  #define TX_WATCHDOG		(5 * HZ)  #define NAPI_WEIGHT		64 @@ -869,6 +869,7 @@ static void sky2_wol_init(struct sky2_port *sky2)  	/* block receiver */  	sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_SET); +	sky2_read32(hw, B0_CTST);  }  static void sky2_set_tx_stfwd(struct sky2_hw *hw, unsigned port) @@ -1274,6 +1275,14 @@ static void rx_set_checksum(struct sky2_port *sky2)  		     ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM);  } +/* + * Fixed initial key as seed to RSS. + */ +static const uint32_t rss_init_key[10] = { +	0x7c3351da, 0x51c5cf4e,	0x44adbdd1, 0xe8d38d18,	0x48897c43, +	0xb1d60e7e, 0x6a3dd760, 0x01a2e453, 0x16f46f13, 0x1a0e7b30 +}; +  /* Enable/disable receive hash calculation (RSS) */  static void rx_set_rss(struct net_device *dev, u32 features)  { @@ -1289,12 +1298,9 @@ static void rx_set_rss(struct net_device *dev, u32 features)  	/* Program RSS initial values */  	if (features & NETIF_F_RXHASH) { -		u32 key[nkeys]; - -		get_random_bytes(key, nkeys * sizeof(u32));  		for (i = 0; i < nkeys; i++)  			sky2_write32(hw, SK_REG(sky2->port, RSS_KEY + i * 4), -				     key[i]); +				     rss_init_key[i]);  		/* Need to turn on (undocumented) flag to make hashing work  */  		sky2_write32(hw, SK_REG(sky2->port, RX_GMF_CTRL_T), @@ -1717,6 +1723,8 @@ static int sky2_setup_irq(struct sky2_hw *hw, const char *name)  	if (err)  		dev_err(&pdev->dev, "cannot assign irq %d\n", pdev->irq);  	else { +		hw->flags |= SKY2_HW_IRQ_SETUP; +  		napi_enable(&hw->napi);  		sky2_write32(hw, B0_IMSK, Y2_IS_BASE);  		sky2_read32(hw, B0_IMSK); @@ -1727,7 +1735,7 @@ static int sky2_setup_irq(struct sky2_hw *hw, const char *name)  /* Bring up network interface. */ -static int sky2_up(struct net_device *dev) +static int sky2_open(struct net_device *dev)  {  	struct sky2_port *sky2 = netdev_priv(dev);  	struct sky2_hw *hw = sky2->hw; @@ -1747,6 +1755,11 @@ static int sky2_up(struct net_device *dev)  	sky2_hw_up(sky2); +	if (hw->chip_id == CHIP_ID_YUKON_OPT || +	    hw->chip_id == CHIP_ID_YUKON_PRM || +	    hw->chip_id == CHIP_ID_YUKON_OP_2) +		imask |= Y2_IS_PHY_QLNK;	/* enable PHY Quick Link */ +  	/* Enable interrupts from phy/mac for port */  	imask = sky2_read32(hw, B0_IMSK);  	imask |= portirq_msk[port]; @@ -2040,6 +2053,8 @@ static void sky2_tx_reset(struct sky2_hw *hw, unsigned port)  	sky2_write32(hw, RB_ADDR(txqaddr[port], RB_CTRL), RB_RST_SET);  	sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_SET); + +	sky2_read32(hw, B0_CTST);  }  static void sky2_hw_down(struct sky2_port *sky2) @@ -2090,7 +2105,7 @@ static void sky2_hw_down(struct sky2_port *sky2)  }  /* Network shutdown */ -static int sky2_down(struct net_device *dev) +static int sky2_close(struct net_device *dev)  {  	struct sky2_port *sky2 = netdev_priv(dev);  	struct sky2_hw *hw = sky2->hw; @@ -2101,15 +2116,22 @@ static int sky2_down(struct net_device *dev)  	netif_info(sky2, ifdown, dev, "disabling interface\n"); -	/* Disable port IRQ */ -	sky2_write32(hw, B0_IMSK, -		     sky2_read32(hw, B0_IMSK) & ~portirq_msk[sky2->port]); -	sky2_read32(hw, B0_IMSK); -  	if (hw->ports == 1) { +		sky2_write32(hw, B0_IMSK, 0); +		sky2_read32(hw, B0_IMSK); +  		napi_disable(&hw->napi);  		free_irq(hw->pdev->irq, hw); +		hw->flags &= ~SKY2_HW_IRQ_SETUP;  	} else { +		u32 imask; + +		/* Disable port IRQ */ +		imask  = sky2_read32(hw, B0_IMSK); +		imask &= ~portirq_msk[sky2->port]; +		sky2_write32(hw, B0_IMSK, imask); +		sky2_read32(hw, B0_IMSK); +  		synchronize_irq(hw->pdev->irq);  		napi_synchronize(&hw->napi);  	} @@ -2587,7 +2609,7 @@ static inline void sky2_tx_done(struct net_device *dev, u16 last)  	if (netif_running(dev)) {  		sky2_tx_complete(sky2, last); -		/* Wake unless it's detached, and called e.g. from sky2_down() */ +		/* Wake unless it's detached, and called e.g. from sky2_close() */  		if (tx_avail(sky2) > MAX_SKB_TX_LE + 4)  			netif_wake_queue(dev);  	} @@ -3258,7 +3280,6 @@ static void sky2_reset(struct sky2_hw *hw)  	    hw->chip_id == CHIP_ID_YUKON_PRM ||  	    hw->chip_id == CHIP_ID_YUKON_OP_2) {  		u16 reg; -		u32 msk;  		if (hw->chip_id == CHIP_ID_YUKON_OPT && hw->chip_rev == 0) {  			/* disable PCI-E PHY power down (set PHY reg 0x80, bit 7 */ @@ -3281,11 +3302,6 @@ static void sky2_reset(struct sky2_hw *hw)  		sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);  		sky2_pci_write16(hw, PSM_CONFIG_REG4, reg); -		/* enable PHY Quick Link */ -		msk = sky2_read32(hw, B0_IMSK); -		msk |= Y2_IS_PHY_QLNK; -		sky2_write32(hw, B0_IMSK, msk); -  		/* check if PSMv2 was running before */  		reg = sky2_pci_read16(hw, PSM_CONFIG_REG3);  		if (reg & PCI_EXP_LNKCTL_ASPMC) @@ -3383,7 +3399,7 @@ static void sky2_detach(struct net_device *dev)  		netif_tx_lock(dev);  		netif_device_detach(dev);	/* stop txq */  		netif_tx_unlock(dev); -		sky2_down(dev); +		sky2_close(dev);  	}  } @@ -3393,7 +3409,7 @@ static int sky2_reattach(struct net_device *dev)  	int err = 0;  	if (netif_running(dev)) { -		err = sky2_up(dev); +		err = sky2_open(dev);  		if (err) {  			netdev_info(dev, "could not restart %d\n", err);  			dev_close(dev); @@ -3410,10 +3426,13 @@ static void sky2_all_down(struct sky2_hw *hw)  {  	int i; -	sky2_read32(hw, B0_IMSK); -	sky2_write32(hw, B0_IMSK, 0); -	synchronize_irq(hw->pdev->irq); -	napi_disable(&hw->napi); +	if (hw->flags & SKY2_HW_IRQ_SETUP) { +		sky2_read32(hw, B0_IMSK); +		sky2_write32(hw, B0_IMSK, 0); + +		synchronize_irq(hw->pdev->irq); +		napi_disable(&hw->napi); +	}  	for (i = 0; i < hw->ports; i++) {  		struct net_device *dev = hw->dev[i]; @@ -3446,11 +3465,12 @@ static void sky2_all_up(struct sky2_hw *hw)  		netif_wake_queue(dev);  	} -	sky2_write32(hw, B0_IMSK, imask); -	sky2_read32(hw, B0_IMSK); - -	sky2_read32(hw, B0_Y2_SP_LISR); -	napi_enable(&hw->napi); +	if (hw->flags & SKY2_HW_IRQ_SETUP) { +		sky2_write32(hw, B0_IMSK, imask); +		sky2_read32(hw, B0_IMSK); +		sky2_read32(hw, B0_Y2_SP_LISR); +		napi_enable(&hw->napi); +	}  }  static void sky2_restart(struct work_struct *work) @@ -4071,6 +4091,16 @@ static int sky2_set_coalesce(struct net_device *dev,  	return 0;  } +/* + * Hardware is limited to min of 128 and max of 2048 for ring size + * and  rounded up to next power of two + * to avoid division in modulus calclation + */ +static unsigned long roundup_ring_size(unsigned long pending) +{ +	return max(128ul, roundup_pow_of_two(pending+1)); +} +  static void sky2_get_ringparam(struct net_device *dev,  			       struct ethtool_ringparam *ering)  { @@ -4098,7 +4128,7 @@ static int sky2_set_ringparam(struct net_device *dev,  	sky2->rx_pending = ering->rx_pending;  	sky2->tx_pending = ering->tx_pending; -	sky2->tx_ring_size = roundup_pow_of_two(sky2->tx_pending+1); +	sky2->tx_ring_size = roundup_ring_size(sky2->tx_pending);  	return sky2_reattach(dev);  } @@ -4556,7 +4586,7 @@ static int sky2_device_event(struct notifier_block *unused,  	struct net_device *dev = ptr;  	struct sky2_port *sky2 = netdev_priv(dev); -	if (dev->netdev_ops->ndo_open != sky2_up || !sky2_debug) +	if (dev->netdev_ops->ndo_open != sky2_open || !sky2_debug)  		return NOTIFY_DONE;  	switch (event) { @@ -4621,8 +4651,8 @@ static __exit void sky2_debug_cleanup(void)     not allowing netpoll on second port */  static const struct net_device_ops sky2_netdev_ops[2] = {    { -	.ndo_open		= sky2_up, -	.ndo_stop		= sky2_down, +	.ndo_open		= sky2_open, +	.ndo_stop		= sky2_close,  	.ndo_start_xmit		= sky2_xmit_frame,  	.ndo_do_ioctl		= sky2_ioctl,  	.ndo_validate_addr	= eth_validate_addr, @@ -4638,8 +4668,8 @@ static const struct net_device_ops sky2_netdev_ops[2] = {  #endif    },    { -	.ndo_open		= sky2_up, -	.ndo_stop		= sky2_down, +	.ndo_open		= sky2_open, +	.ndo_stop		= sky2_close,  	.ndo_start_xmit		= sky2_xmit_frame,  	.ndo_do_ioctl		= sky2_ioctl,  	.ndo_validate_addr	= eth_validate_addr, @@ -4692,7 +4722,7 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw,  	spin_lock_init(&sky2->phy_lock);  	sky2->tx_pending = TX_DEF_PENDING; -	sky2->tx_ring_size = roundup_pow_of_two(TX_DEF_PENDING+1); +	sky2->tx_ring_size = roundup_ring_size(TX_DEF_PENDING);  	sky2->rx_pending = RX_DEF_PENDING;  	hw->dev[port] = dev; diff --git a/drivers/net/ethernet/marvell/sky2.h b/drivers/net/ethernet/marvell/sky2.h index 0af31b8b5f1..ff6f58bf822 100644 --- a/drivers/net/ethernet/marvell/sky2.h +++ b/drivers/net/ethernet/marvell/sky2.h @@ -2287,6 +2287,7 @@ struct sky2_hw {  #define SKY2_HW_RSS_BROKEN	0x00000100  #define SKY2_HW_VLAN_BROKEN     0x00000200  #define SKY2_HW_RSS_CHKSUM	0x00000400	/* RSS requires chksum */ +#define SKY2_HW_IRQ_SETUP	0x00000800  	u8	     	     chip_id;  	u8		     chip_rev; diff --git a/drivers/net/ethernet/mellanox/mlx4/en_rx.c b/drivers/net/ethernet/mellanox/mlx4/en_rx.c index b89c36dbf5b..c2df6c35860 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_rx.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_rx.c @@ -581,6 +581,7 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud  		 * Packet is OK - process it.  		 */  		length = be32_to_cpu(cqe->byte_cnt); +		length -= ring->fcs_del;  		ring->bytes += length;  		ring->packets++; @@ -813,8 +814,11 @@ static int mlx4_en_config_rss_qp(struct mlx4_en_priv *priv, int qpn,  	context->db_rec_addr = cpu_to_be64(ring->wqres.db.dma);  	/* Cancel FCS removal if FW allows */ -	if (mdev->dev->caps.flags & MLX4_DEV_CAP_FLAG_FCS_KEEP) +	if (mdev->dev->caps.flags & MLX4_DEV_CAP_FLAG_FCS_KEEP) {  		context->param3 |= cpu_to_be32(1 << 29); +		ring->fcs_del = ETH_FCS_LEN; +	} else +		ring->fcs_del = 0;  	err = mlx4_qp_to_ready(mdev->dev, &ring->wqres.mtt, context, qp, state);  	if (err) { diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h index 8fda331c65d..207b5add3ca 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h @@ -272,6 +272,7 @@ struct mlx4_en_rx_ring {  	u32 prod;  	u32 cons;  	u32 buf_size; +	u8  fcs_del;  	void *buf;  	void *rx_info;  	unsigned long bytes; diff --git a/drivers/net/ethernet/nvidia/forcedeth.c b/drivers/net/ethernet/nvidia/forcedeth.c index 1dca57013cb..1c61d36e657 100644 --- a/drivers/net/ethernet/nvidia/forcedeth.c +++ b/drivers/net/ethernet/nvidia/forcedeth.c @@ -609,7 +609,7 @@ struct nv_ethtool_str {  };  static const struct nv_ethtool_str nv_estats_str[] = { -	{ "tx_bytes" }, +	{ "tx_bytes" }, /* includes Ethernet FCS CRC */  	{ "tx_zero_rexmt" },  	{ "tx_one_rexmt" },  	{ "tx_many_rexmt" }, @@ -637,7 +637,7 @@ static const struct nv_ethtool_str nv_estats_str[] = {  	/* version 2 stats */  	{ "tx_deferral" },  	{ "tx_packets" }, -	{ "rx_bytes" }, +	{ "rx_bytes" }, /* includes Ethernet FCS CRC */  	{ "tx_pause" },  	{ "rx_pause" },  	{ "rx_drop_frame" }, @@ -649,7 +649,7 @@ static const struct nv_ethtool_str nv_estats_str[] = {  };  struct nv_ethtool_stats { -	u64 tx_bytes; +	u64 tx_bytes; /* should be ifconfig->tx_bytes + 4*tx_packets */  	u64 tx_zero_rexmt;  	u64 tx_one_rexmt;  	u64 tx_many_rexmt; @@ -670,14 +670,14 @@ struct nv_ethtool_stats {  	u64 rx_unicast;  	u64 rx_multicast;  	u64 rx_broadcast; -	u64 rx_packets; +	u64 rx_packets; /* should be ifconfig->rx_packets */  	u64 rx_errors_total;  	u64 tx_errors_total;  	/* version 2 stats */  	u64 tx_deferral; -	u64 tx_packets; -	u64 rx_bytes; +	u64 tx_packets; /* should be ifconfig->tx_packets */ +	u64 rx_bytes;   /* should be ifconfig->rx_bytes + 4*rx_packets */  	u64 tx_pause;  	u64 rx_pause;  	u64 rx_drop_frame; @@ -1706,10 +1706,17 @@ static struct net_device_stats *nv_get_stats(struct net_device *dev)  	if (np->driver_data & (DEV_HAS_STATISTICS_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_STATISTICS_V3)) {  		nv_get_hw_stats(dev); +		/* +		 * Note: because HW stats are not always available and +		 * for consistency reasons, the following ifconfig +		 * stats are managed by software: rx_bytes, tx_bytes, +		 * rx_packets and tx_packets. The related hardware +		 * stats reported by ethtool should be equivalent to +		 * these ifconfig stats, with 4 additional bytes per +		 * packet (Ethernet FCS CRC). +		 */ +  		/* copy to net_device stats */ -		dev->stats.tx_packets = np->estats.tx_packets; -		dev->stats.rx_bytes = np->estats.rx_bytes; -		dev->stats.tx_bytes = np->estats.tx_bytes;  		dev->stats.tx_fifo_errors = np->estats.tx_fifo_errors;  		dev->stats.tx_carrier_errors = np->estats.tx_carrier_errors;  		dev->stats.rx_crc_errors = np->estats.rx_crc_errors; @@ -2380,6 +2387,9 @@ static int nv_tx_done(struct net_device *dev, int limit)  				if (flags & NV_TX_ERROR) {  					if ((flags & NV_TX_RETRYERROR) && !(flags & NV_TX_RETRYCOUNT_MASK))  						nv_legacybackoff_reseed(dev); +				} else { +					dev->stats.tx_packets++; +					dev->stats.tx_bytes += np->get_tx_ctx->skb->len;  				}  				dev_kfree_skb_any(np->get_tx_ctx->skb);  				np->get_tx_ctx->skb = NULL; @@ -2390,6 +2400,9 @@ static int nv_tx_done(struct net_device *dev, int limit)  				if (flags & NV_TX2_ERROR) {  					if ((flags & NV_TX2_RETRYERROR) && !(flags & NV_TX2_RETRYCOUNT_MASK))  						nv_legacybackoff_reseed(dev); +				} else { +					dev->stats.tx_packets++; +					dev->stats.tx_bytes += np->get_tx_ctx->skb->len;  				}  				dev_kfree_skb_any(np->get_tx_ctx->skb);  				np->get_tx_ctx->skb = NULL; @@ -2429,6 +2442,9 @@ static int nv_tx_done_optimized(struct net_device *dev, int limit)  					else  						nv_legacybackoff_reseed(dev);  				} +			} else { +				dev->stats.tx_packets++; +				dev->stats.tx_bytes += np->get_tx_ctx->skb->len;  			}  			dev_kfree_skb_any(np->get_tx_ctx->skb); @@ -2678,6 +2694,7 @@ static int nv_rx_process(struct net_device *dev, int limit)  		skb->protocol = eth_type_trans(skb, dev);  		napi_gro_receive(&np->napi, skb);  		dev->stats.rx_packets++; +		dev->stats.rx_bytes += len;  next_pkt:  		if (unlikely(np->get_rx.orig++ == np->last_rx.orig))  			np->get_rx.orig = np->first_rx.orig; @@ -2761,6 +2778,7 @@ static int nv_rx_process_optimized(struct net_device *dev, int limit)  			}  			napi_gro_receive(&np->napi, skb);  			dev->stats.rx_packets++; +			dev->stats.rx_bytes += len;  		} else {  			dev_kfree_skb(skb);  		} diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_param.c b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_param.c index 9c075ea2682..9cb5f912e48 100644 --- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_param.c +++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_param.c @@ -18,8 +18,8 @@   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.   */ -#include <linux/module.h>	/* for __MODULE_STRING */  #include "pch_gbe.h" +#include <linux/module.h>	/* for __MODULE_STRING */  #define OPTION_UNSET   -1  #define OPTION_DISABLED 0 diff --git a/drivers/net/ethernet/rdc/r6040.c b/drivers/net/ethernet/rdc/r6040.c index 1fc01ca72b4..4bf68cfef39 100644 --- a/drivers/net/ethernet/rdc/r6040.c +++ b/drivers/net/ethernet/rdc/r6040.c @@ -940,7 +940,7 @@ static void r6040_multicast_list(struct net_device *dev)  	iowrite16(lp->mcr0, ioaddr + MCR0);  	/* Fill the MAC hash tables with their values */ -	if (lp->mcr0 && MCR0_HASH_EN) { +	if (lp->mcr0 & MCR0_HASH_EN) {  		iowrite16(hash_table[0], ioaddr + MAR0);  		iowrite16(hash_table[1], ioaddr + MAR1);  		iowrite16(hash_table[2], ioaddr + MAR2); diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 92b45f08858..6f06aa10f0d 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -1292,7 +1292,7 @@ static void __rtl8169_check_link_status(struct net_device *dev,  		netif_carrier_off(dev);  		netif_info(tp, ifdown, dev, "link down\n");  		if (pm) -			pm_schedule_suspend(&tp->pci_dev->dev, 100); +			pm_schedule_suspend(&tp->pci_dev->dev, 5000);  	}  	spin_unlock_irqrestore(&tp->lock, flags);  } diff --git a/drivers/net/ethernet/smsc/smsc911x.c b/drivers/net/ethernet/smsc/smsc911x.c index d2be42aafbe..8843071fe98 100644 --- a/drivers/net/ethernet/smsc/smsc911x.c +++ b/drivers/net/ethernet/smsc/smsc911x.c @@ -1937,6 +1937,7 @@ static int __devinit smsc911x_init(struct net_device *dev)  {  	struct smsc911x_data *pdata = netdev_priv(dev);  	unsigned int byte_test; +	unsigned int to = 100;  	SMSC_TRACE(pdata, probe, "Driver Parameters:");  	SMSC_TRACE(pdata, probe, "LAN base: 0x%08lX", @@ -1952,6 +1953,17 @@ static int __devinit smsc911x_init(struct net_device *dev)  		return -ENODEV;  	} +	/* +	 * poll the READY bit in PMT_CTRL. Any other access to the device is +	 * forbidden while this bit isn't set. Try for 100ms +	 */ +	while (!(smsc911x_reg_read(pdata, PMT_CTRL) & PMT_CTRL_READY_) && --to) +		udelay(1000); +	if (to == 0) { +		pr_err("Device not READY in 100ms aborting\n"); +		return -ENODEV; +	} +  	/* Check byte ordering */  	byte_test = smsc911x_reg_read(pdata, BYTE_TEST);  	SMSC_TRACE(pdata, probe, "BYTE_TEST: 0x%08X", byte_test); diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c index da66ac511c4..4d5402a1d26 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c @@ -39,10 +39,11 @@ static int dwmac1000_dma_init(void __iomem *ioaddr, int pbl, u32 dma_tx,  	/* DMA SW reset */  	value |= DMA_BUS_MODE_SFT_RESET;  	writel(value, ioaddr + DMA_BUS_MODE); -	limit = 15000; +	limit = 10;  	while (limit--) {  		if (!(readl(ioaddr + DMA_BUS_MODE) & DMA_BUS_MODE_SFT_RESET))  			break; +		mdelay(10);  	}  	if (limit < 0)  		return -EBUSY; diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c index 627f656b0f3..bc17fd08b55 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c @@ -41,10 +41,11 @@ static int dwmac100_dma_init(void __iomem *ioaddr, int pbl, u32 dma_tx,  	/* DMA SW reset */  	value |= DMA_BUS_MODE_SFT_RESET;  	writel(value, ioaddr + DMA_BUS_MODE); -	limit = 15000; +	limit = 10;  	while (limit--) {  		if (!(readl(ioaddr + DMA_BUS_MODE) & DMA_BUS_MODE_SFT_RESET))  			break; +		mdelay(10);  	}  	if (limit < 0)  		return -EBUSY; diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h index 9bafa6cf9e8..a140a8fbf05 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h @@ -72,7 +72,6 @@ struct stmmac_priv {  	spinlock_t lock;  	spinlock_t tx_lock;  	int wolopts; -	int wolenabled;  	int wol_irq;  #ifdef CONFIG_STMMAC_TIMER  	struct stmmac_timer *tm; @@ -80,6 +79,7 @@ struct stmmac_priv {  	struct plat_stmmacenet_data *plat;  	struct stmmac_counters mmc;  	struct dma_features dma_cap; +	int hw_cap_support;  };  extern int stmmac_mdio_unregister(struct net_device *ndev); diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c index e8eff09bbbd..0395f9eba80 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c @@ -430,6 +430,12 @@ static int stmmac_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)  	struct stmmac_priv *priv = netdev_priv(dev);  	u32 support = WAKE_MAGIC | WAKE_UCAST; +	/* By default almost all GMAC devices support the WoL via +	 * magic frame but we can disable it if the HW capability +	 * register shows no support for pmt_magic_frame. */ +	if ((priv->hw_cap_support) && (!priv->dma_cap.pmt_magic_frame)) +		wol->wolopts &= ~WAKE_MAGIC; +  	if (!device_can_wakeup(priv->device))  		return -EINVAL; diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 20546bbbb8d..8ea770a89f2 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -321,12 +321,10 @@ static int stmmac_init_phy(struct net_device *dev)  	}  	/* Stop Advertising 1000BASE Capability if interface is not GMII */ -	if ((interface) && ((interface == PHY_INTERFACE_MODE_MII) || -	    (interface == PHY_INTERFACE_MODE_RMII))) { -		phydev->supported &= (PHY_BASIC_FEATURES | SUPPORTED_Pause | -				      SUPPORTED_Asym_Pause); -		phydev->advertising = phydev->supported; -	} +	if ((interface == PHY_INTERFACE_MODE_MII) || +	    (interface == PHY_INTERFACE_MODE_RMII)) +		phydev->advertising &= ~(SUPPORTED_1000baseT_Half | +					 SUPPORTED_1000baseT_Full);  	/*  	 * Broken HW is sometimes missing the pull-up resistor on the @@ -807,8 +805,29 @@ static u32 stmmac_get_synopsys_id(struct stmmac_priv *priv)  	return 0;  } -/* New GMAC chips support a new register to indicate the - * presence of the optional feature/functions. +/** + * stmmac_selec_desc_mode + * @dev : device pointer + * Description: select the Enhanced/Alternate or Normal descriptors */ +static void stmmac_selec_desc_mode(struct stmmac_priv *priv) +{ +	if (priv->plat->enh_desc) { +		pr_info(" Enhanced/Alternate descriptors\n"); +		priv->hw->desc = &enh_desc_ops; +	} else { +		pr_info(" Normal descriptors\n"); +		priv->hw->desc = &ndesc_ops; +	} +} + +/** + * stmmac_get_hw_features + * @priv : private device pointer + * Description: + *  new GMAC chip generations have a new register to indicate the + *  presence of the optional feature/functions. + *  This can be also used to override the value passed through the + *  platform and necessary for old MAC10/100 and GMAC chips.   */  static int stmmac_get_hw_features(struct stmmac_priv *priv)  { @@ -829,7 +848,7 @@ static int stmmac_get_hw_features(struct stmmac_priv *priv)  			(hw_cap & DMA_HW_FEAT_RWKSEL) >> 9;  		priv->dma_cap.pmt_magic_frame =  			(hw_cap & DMA_HW_FEAT_MGKSEL) >> 10; -		/*MMC*/ +		/* MMC */  		priv->dma_cap.rmon = (hw_cap & DMA_HW_FEAT_MMCSEL) >> 11;  		/* IEEE 1588-2002*/  		priv->dma_cap.time_stamp = @@ -857,8 +876,7 @@ static int stmmac_get_hw_features(struct stmmac_priv *priv)  		priv->dma_cap.enh_desc =  			(hw_cap & DMA_HW_FEAT_ENHDESSEL) >> 24; -	} else -		pr_debug("\tNo HW DMA feature register supported"); +	}  	return hw_cap;  } @@ -913,6 +931,44 @@ static int stmmac_open(struct net_device *dev)  		goto open_error;  	} +	stmmac_get_synopsys_id(priv); + +	priv->hw_cap_support = stmmac_get_hw_features(priv); + +	if (priv->hw_cap_support) { +		pr_info(" Support DMA HW capability register"); + +		/* We can override some gmac/dma configuration fields: e.g. +		 * enh_desc, tx_coe (e.g. that are passed through the +		 * platform) with the values from the HW capability +		 * register (if supported). +		 */ +		priv->plat->enh_desc = priv->dma_cap.enh_desc; +		priv->plat->tx_coe = priv->dma_cap.tx_coe; +		priv->plat->pmt = priv->dma_cap.pmt_remote_wake_up; + +		/* By default disable wol on magic frame if not supported */ +		if (!priv->dma_cap.pmt_magic_frame) +			priv->wolopts &= ~WAKE_MAGIC; + +	} else +		pr_info(" No HW DMA feature register supported"); + +	/* Select the enhnaced/normal descriptor structures */ +	stmmac_selec_desc_mode(priv); + +	/* PMT module is not integrated in all the MAC devices. */ +	if (priv->plat->pmt) { +		pr_info(" Remote wake-up capable\n"); +		device_set_wakeup_capable(priv->device, 1); +	} + +	priv->rx_coe = priv->hw->mac->rx_coe(priv->ioaddr); +	if (priv->rx_coe) +		pr_info(" Checksum Offload Engine supported\n"); +	if (priv->plat->tx_coe) +		pr_info(" Checksum insertion supported\n"); +  	/* Create and initialize the TX/RX descriptors chains. */  	priv->dma_tx_size = STMMAC_ALIGN(dma_txsize);  	priv->dma_rx_size = STMMAC_ALIGN(dma_rxsize); @@ -935,15 +991,6 @@ static int stmmac_open(struct net_device *dev)  	/* Initialize the MAC Core */  	priv->hw->mac->core_init(priv->ioaddr); -	stmmac_get_synopsys_id(priv); - -	stmmac_get_hw_features(priv); - -	priv->rx_coe = priv->hw->mac->rx_coe(priv->ioaddr); -	if (priv->rx_coe) -		pr_info("stmmac: Rx Checksum Offload Engine supported\n"); -	if (priv->plat->tx_coe) -		pr_info("\tTX Checksum insertion supported\n");  	netdev_update_features(dev);  	/* Request the IRQ lines */ @@ -1489,9 +1536,7 @@ static int stmmac_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)  	if (!priv->phydev)  		return -EINVAL; -	spin_lock(&priv->lock);  	ret = phy_mii_ioctl(priv->phydev, rq, cmd); -	spin_unlock(&priv->lock);  	return ret;  } @@ -1558,7 +1603,7 @@ static int stmmac_sysfs_dma_cap_read(struct seq_file *seq, void *v)  	struct net_device *dev = seq->private;  	struct stmmac_priv *priv = netdev_priv(dev); -	if (!stmmac_get_hw_features(priv)) { +	if (!priv->hw_cap_support) {  		seq_printf(seq, "DMA HW features not supported\n");  		return 0;  	} @@ -1766,12 +1811,6 @@ static int stmmac_mac_device_setup(struct net_device *dev)  	if (!device)  		return -ENOMEM; -	if (priv->plat->enh_desc) { -		device->desc = &enh_desc_ops; -		pr_info("\tEnhanced descriptor structure\n"); -	} else -		device->desc = &ndesc_ops; -  	priv->hw = device;  	priv->hw->ring = &ring_mode_ops; @@ -1845,11 +1884,6 @@ static int stmmac_dvr_probe(struct platform_device *pdev)  	priv->ioaddr = addr; -	/* PMT module is not integrated in all the MAC devices. */ -	if (plat_dat->pmt) { -		pr_info("\tPMT module supported\n"); -		device_set_wakeup_capable(&pdev->dev, 1); -	}  	/*  	 * On some platforms e.g. SPEAr the wake up irq differs from the mac irq  	 * The external wake up irq can be passed through the platform code @@ -1862,7 +1896,6 @@ static int stmmac_dvr_probe(struct platform_device *pdev)  	if (priv->wol_irq == -ENXIO)  		priv->wol_irq = ndev->irq; -  	platform_set_drvdata(pdev, ndev);  	/* Set the I/O base addr */ @@ -1875,7 +1908,7 @@ static int stmmac_dvr_probe(struct platform_device *pdev)  			goto out_free_ndev;  	} -	/* MAC HW revice detection */ +	/* MAC HW device detection */  	ret = stmmac_mac_device_setup(ndev);  	if (ret < 0)  		goto out_plat_exit; @@ -1978,12 +2011,13 @@ static int stmmac_suspend(struct device *dev)  	if (!ndev || !netif_running(ndev))  		return 0; +	if (priv->phydev) +		phy_stop(priv->phydev); +  	spin_lock(&priv->lock);  	netif_device_detach(ndev);  	netif_stop_queue(ndev); -	if (priv->phydev) -		phy_stop(priv->phydev);  #ifdef CONFIG_STMMAC_TIMER  	priv->tm->timer_stop(); @@ -2041,12 +2075,13 @@ static int stmmac_resume(struct device *dev)  #endif  	napi_enable(&priv->napi); -	if (priv->phydev) -		phy_start(priv->phydev); -  	netif_start_queue(ndev);  	spin_unlock(&priv->lock); + +	if (priv->phydev) +		phy_start(priv->phydev); +  	return 0;  } diff --git a/drivers/net/ethernet/sun/sunhme.c b/drivers/net/ethernet/sun/sunhme.c index c517dac02ae..cf14ab9db57 100644 --- a/drivers/net/ethernet/sun/sunhme.c +++ b/drivers/net/ethernet/sun/sunhme.c @@ -2637,7 +2637,7 @@ static int __devinit happy_meal_sbus_probe_one(struct platform_device *op, int i  	sbus_dp = op->dev.parent->of_node;  	/* We can match PCI devices too, do not accept those here. */ -	if (strcmp(sbus_dp->name, "sbus")) +	if (strcmp(sbus_dp->name, "sbus") && strcmp(sbus_dp->name, "sbi"))  		return err;  	if (is_qfe) { diff --git a/drivers/net/ethernet/xilinx/ll_temac_main.c b/drivers/net/ethernet/xilinx/ll_temac_main.c index caf3659e173..2681b53820e 100644 --- a/drivers/net/ethernet/xilinx/ll_temac_main.c +++ b/drivers/net/ethernet/xilinx/ll_temac_main.c @@ -114,6 +114,7 @@ void temac_indirect_out32(struct temac_local *lp, int reg, u32 value)  		return;  	temac_iow(lp, XTE_LSW0_OFFSET, value);  	temac_iow(lp, XTE_CTL0_OFFSET, CNTLREG_WRITE_ENABLE_MASK | reg); +	temac_indirect_busywait(lp);  }  /** @@ -203,6 +204,9 @@ static void temac_dma_bd_release(struct net_device *ndev)  	struct temac_local *lp = netdev_priv(ndev);  	int i; +	/* Reset Local Link (DMA) */ +	lp->dma_out(lp, DMA_CONTROL_REG, DMA_CONTROL_RST); +  	for (i = 0; i < RX_BD_NUM; i++) {  		if (!lp->rx_skb[i])  			break; @@ -860,6 +864,8 @@ static int temac_open(struct net_device *ndev)  		phy_start(lp->phy_dev);  	} +	temac_device_reset(ndev); +  	rc = request_irq(lp->tx_irq, ll_temac_tx_irq, 0, ndev->name, ndev);  	if (rc)  		goto err_tx_irq; @@ -867,7 +873,6 @@ static int temac_open(struct net_device *ndev)  	if (rc)  		goto err_rx_irq; -	temac_device_reset(ndev);  	return 0;   err_rx_irq: diff --git a/drivers/net/hippi/Kconfig b/drivers/net/hippi/Kconfig index 7393eb732ee..95eb34fdbba 100644 --- a/drivers/net/hippi/Kconfig +++ b/drivers/net/hippi/Kconfig @@ -36,4 +36,4 @@ config ROADRUNNER_LARGE_RINGS  	  kernel code or by user space programs. Say Y here only if you have  	  the memory. -endif /* HIPPI */ +endif # HIPPI diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c index e81e22e3d1d..e6fed4d4cb7 100644 --- a/drivers/net/usb/asix.c +++ b/drivers/net/usb/asix.c @@ -36,7 +36,7 @@  #include <linux/usb/usbnet.h>  #include <linux/slab.h> -#define DRIVER_VERSION "26-Sep-2011" +#define DRIVER_VERSION "08-Nov-2011"  #define DRIVER_NAME "asix"  /* ASIX AX8817X based USB 2.0 Ethernet Devices */ @@ -163,7 +163,7 @@  #define MARVELL_CTRL_TXDELAY	0x0002  #define MARVELL_CTRL_RXDELAY	0x0080 -#define	PHY_MODE_RTL8211CL	0x0004 +#define	PHY_MODE_RTL8211CL	0x000C  /* This structure cannot exceed sizeof(unsigned long [5]) AKA 20 bytes */  struct asix_data { @@ -652,9 +652,17 @@ static u32 asix_get_phyid(struct usbnet *dev)  {  	int phy_reg;  	u32 phy_id; +	int i; -	phy_reg = asix_mdio_read(dev->net, dev->mii.phy_id, MII_PHYSID1); -	if (phy_reg < 0) +	/* Poll for the rare case the FW or phy isn't ready yet.  */ +	for (i = 0; i < 100; i++) { +		phy_reg = asix_mdio_read(dev->net, dev->mii.phy_id, MII_PHYSID1); +		if (phy_reg != 0 && phy_reg != 0xFFFF) +			break; +		mdelay(1); +	} + +	if (phy_reg <= 0 || phy_reg == 0xFFFF)  		return 0;  	phy_id = (phy_reg & 0xffff) << 16; @@ -1075,7 +1083,7 @@ static const struct net_device_ops ax88772_netdev_ops = {  static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf)  { -	int ret; +	int ret, embd_phy;  	struct asix_data *data = (struct asix_data *)&dev->data;  	u8 buf[ETH_ALEN];  	u32 phyid; @@ -1100,16 +1108,36 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf)  	dev->mii.reg_num_mask = 0x1f;  	dev->mii.phy_id = asix_get_phy_addr(dev); -	phyid = asix_get_phyid(dev); -	dbg("PHYID=0x%08x", phyid); -  	dev->net->netdev_ops = &ax88772_netdev_ops;  	dev->net->ethtool_ops = &ax88772_ethtool_ops; -	ret = ax88772_reset(dev); +	embd_phy = ((dev->mii.phy_id & 0x1f) == 0x10 ? 1 : 0); + +	/* Reset the PHY to normal operation mode */ +	ret = asix_write_cmd(dev, AX_CMD_SW_PHY_SELECT, embd_phy, 0, 0, NULL); +	if (ret < 0) { +		dbg("Select PHY #1 failed: %d", ret); +		return ret; +	} + +	ret = asix_sw_reset(dev, AX_SWRESET_IPPD | AX_SWRESET_PRL); +	if (ret < 0) +		return ret; + +	msleep(150); + +	ret = asix_sw_reset(dev, AX_SWRESET_CLEAR);  	if (ret < 0)  		return ret; +	msleep(150); + +	ret = asix_sw_reset(dev, embd_phy ? AX_SWRESET_IPRL : AX_SWRESET_PRTE); + +	/* Read PHYID register *AFTER* the PHY was reset properly */ +	phyid = asix_get_phyid(dev); +	dbg("PHYID=0x%08x", phyid); +  	/* Asix framing packs multiple eth frames into a 2K usb bulk transfer */  	if (dev->driver_info->flags & FLAG_FRAMING_AX) {  		/* hard_mtu  is still the default - the device does not support @@ -1220,6 +1248,7 @@ static int ax88178_reset(struct usbnet *dev)  	__le16 eeprom;  	u8 status;  	int gpio0 = 0; +	u32 phyid;  	asix_read_cmd(dev, AX_CMD_READ_GPIOS, 0, 0, 1, &status);  	dbg("GPIO Status: 0x%04x", status); @@ -1235,12 +1264,13 @@ static int ax88178_reset(struct usbnet *dev)  		data->ledmode = 0;  		gpio0 = 1;  	} else { -		data->phymode = le16_to_cpu(eeprom) & 7; +		data->phymode = le16_to_cpu(eeprom) & 0x7F;  		data->ledmode = le16_to_cpu(eeprom) >> 8;  		gpio0 = (le16_to_cpu(eeprom) & 0x80) ? 0 : 1;  	}  	dbg("GPIO0: %d, PhyMode: %d", gpio0, data->phymode); +	/* Power up external GigaPHY through AX88178 GPIO pin */  	asix_write_gpio(dev, AX_GPIO_RSE | AX_GPIO_GPO_1 | AX_GPIO_GPO1EN, 40);  	if ((le16_to_cpu(eeprom) >> 8) != 1) {  		asix_write_gpio(dev, 0x003c, 30); @@ -1252,6 +1282,13 @@ static int ax88178_reset(struct usbnet *dev)  		asix_write_gpio(dev, AX_GPIO_GPO1EN | AX_GPIO_GPO_1, 30);  	} +	/* Read PHYID register *AFTER* powering up PHY */ +	phyid = asix_get_phyid(dev); +	dbg("PHYID=0x%08x", phyid); + +	/* Set AX88178 to enable MII/GMII/RGMII interface for external PHY */ +	asix_write_cmd(dev, AX_CMD_SW_PHY_SELECT, 0, 0, 0, NULL); +  	asix_sw_reset(dev, 0);  	msleep(150); @@ -1396,7 +1433,6 @@ static int ax88178_bind(struct usbnet *dev, struct usb_interface *intf)  {  	int ret;  	u8 buf[ETH_ALEN]; -	u32 phyid;  	struct asix_data *data = (struct asix_data *)&dev->data;  	data->eeprom_len = AX88772_EEPROM_LEN; @@ -1423,12 +1459,12 @@ static int ax88178_bind(struct usbnet *dev, struct usb_interface *intf)  	dev->net->netdev_ops = &ax88178_netdev_ops;  	dev->net->ethtool_ops = &ax88178_ethtool_ops; -	phyid = asix_get_phyid(dev); -	dbg("PHYID=0x%08x", phyid); +	/* Blink LEDS so users know driver saw dongle */ +	asix_sw_reset(dev, 0); +	msleep(150); -	ret = ax88178_reset(dev); -	if (ret < 0) -		return ret; +	asix_sw_reset(dev, AX_SWRESET_PRL | AX_SWRESET_IPPD); +	msleep(150);  	/* Asix framing packs multiple eth frames into a 2K usb bulk transfer */  	if (dev->driver_info->flags & FLAG_FRAMING_AX) { diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c index c924ea2bce0..99ed6eb4dfa 100644 --- a/drivers/net/usb/cdc_ether.c +++ b/drivers/net/usb/cdc_ether.c @@ -567,7 +567,7 @@ static const struct usb_device_id	products [] = {  {  	USB_DEVICE_AND_INTERFACE_INFO(0x1004, 0x61aa, USB_CLASS_COMM,  			USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), -	.driver_info = (unsigned long)&wwan_info, +	.driver_info = 0,  },  /* diff --git a/drivers/net/usb/lg-vl600.c b/drivers/net/usb/lg-vl600.c index d43db32f947..9c26c6390d6 100644 --- a/drivers/net/usb/lg-vl600.c +++ b/drivers/net/usb/lg-vl600.c @@ -144,10 +144,11 @@ static int vl600_rx_fixup(struct usbnet *dev, struct sk_buff *skb)  	}  	frame = (struct vl600_frame_hdr *) buf->data; -	/* NOTE: Should check that frame->magic == 0x53544448? -	 * Otherwise if we receive garbage at the beginning of the frame -	 * we may end up allocating a huge buffer and saving all the -	 * future incoming data into it.  */ +	/* Yes, check that frame->magic == 0x53544448 (or 0x44544d48), +	 * otherwise we may run out of memory w/a bad packet */ +	if (ntohl(frame->magic) != 0x53544448 && +			ntohl(frame->magic) != 0x44544d48) +		goto error;  	if (buf->len < sizeof(*frame) ||  			buf->len != le32_to_cpup(&frame->len)) { @@ -296,6 +297,11 @@ encapsulate:  	 * overwrite the remaining fields.  	 */  	packet = (struct vl600_pkt_hdr *) skb->data; +	/* The VL600 wants IPv6 packets to have an IPv4 ethertype +	 * Since this modem only supports IPv4 and IPv6, just set all +	 * frames to 0x0800 (ETH_P_IP) +	 */ +	packet->h_proto = htons(ETH_P_IP);  	memset(&packet->dummy, 0, sizeof(packet->dummy));  	packet->len = cpu_to_le32(orig_len); @@ -308,21 +314,12 @@ encapsulate:  	if (skb->len < full_len) /* Pad */  		skb_put(skb, full_len - skb->len); -	/* The VL600 wants IPv6 packets to have an IPv4 ethertype -	 * Check if this is an IPv6 packet, and set the ethertype -	 * to 0x800 -	 */ -	if ((skb->data[sizeof(struct vl600_pkt_hdr *) + 0x22] & 0xf0) == 0x60) { -		skb->data[sizeof(struct vl600_pkt_hdr *) + 0x20] = 0x08; -		skb->data[sizeof(struct vl600_pkt_hdr *) + 0x21] = 0; -	} -  	return skb;  }  static const struct driver_info	vl600_info = {  	.description	= "LG VL600 modem", -	.flags		= FLAG_ETHER | FLAG_RX_ASSEMBLE, +	.flags		= FLAG_RX_ASSEMBLE | FLAG_WWAN,  	.bind		= vl600_bind,  	.unbind		= vl600_unbind,  	.status		= usbnet_cdc_status, diff --git a/drivers/net/usb/smsc75xx.c b/drivers/net/usb/smsc75xx.c index 22a7cf951e7..a5b9b12ef26 100644 --- a/drivers/net/usb/smsc75xx.c +++ b/drivers/net/usb/smsc75xx.c @@ -51,6 +51,7 @@  #define USB_VENDOR_ID_SMSC		(0x0424)  #define USB_PRODUCT_ID_LAN7500		(0x7500)  #define USB_PRODUCT_ID_LAN7505		(0x7505) +#define RXW_PADDING			2  #define check_warn(ret, fmt, args...) \  	({ if (ret < 0) netdev_warn(dev->net, fmt, ##args); }) @@ -1088,13 +1089,13 @@ static int smsc75xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb)  		memcpy(&rx_cmd_b, skb->data, sizeof(rx_cmd_b));  		le32_to_cpus(&rx_cmd_b); -		skb_pull(skb, 4 + NET_IP_ALIGN); +		skb_pull(skb, 4 + RXW_PADDING);  		packet = skb->data;  		/* get the packet length */ -		size = (rx_cmd_a & RX_CMD_A_LEN) - NET_IP_ALIGN; -		align_count = (4 - ((size + NET_IP_ALIGN) % 4)) % 4; +		size = (rx_cmd_a & RX_CMD_A_LEN) - RXW_PADDING; +		align_count = (4 - ((size + RXW_PADDING) % 4)) % 4;  		if (unlikely(rx_cmd_a & RX_CMD_A_RED)) {  			netif_dbg(dev, rx_err, dev->net, diff --git a/drivers/net/wireless/ath/regd.c b/drivers/net/wireless/ath/regd.c index 85fa9cc7350..65ecb5bab25 100644 --- a/drivers/net/wireless/ath/regd.c +++ b/drivers/net/wireless/ath/regd.c @@ -254,6 +254,8 @@ ath_reg_apply_active_scan_flags(struct wiphy *wiphy,  	int r;  	sband = wiphy->bands[IEEE80211_BAND_2GHZ]; +	if (!sband) +		return;  	/*  	 * If no country IE has been received always enable active scan diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c index 58ea0e5fabf..5f77cbe0b6a 100644 --- a/drivers/net/wireless/b43/xmit.c +++ b/drivers/net/wireless/b43/xmit.c @@ -175,6 +175,7 @@ void b43_generate_plcp_hdr(struct b43_plcp_hdr4 *plcp,  	}  } +/* TODO: verify if needed for SSLPN or LCN  */  static u16 b43_generate_tx_phy_ctl1(struct b43_wldev *dev, u8 bitrate)  {  	const struct b43_phy *phy = &dev->phy; @@ -256,6 +257,9 @@ int b43_generate_txhdr(struct b43_wldev *dev,  	unsigned int plcp_fragment_len;  	u32 mac_ctl = 0;  	u16 phy_ctl = 0; +	bool fill_phy_ctl1 = (phy->type == B43_PHYTYPE_LP || +			      phy->type == B43_PHYTYPE_N || +			      phy->type == B43_PHYTYPE_HT);  	u8 extra_ft = 0;  	struct ieee80211_rate *txrate;  	struct ieee80211_tx_rate *rates; @@ -531,7 +535,7 @@ int b43_generate_txhdr(struct b43_wldev *dev,  			extra_ft |= B43_TXH_EFT_RTSFB_CCK;  		if (rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS && -		    phy->type == B43_PHYTYPE_N) { +		    fill_phy_ctl1) {  			txhdr->phy_ctl1_rts = cpu_to_le16(  				b43_generate_tx_phy_ctl1(dev, rts_rate));  			txhdr->phy_ctl1_rts_fb = cpu_to_le16( @@ -552,7 +556,7 @@ int b43_generate_txhdr(struct b43_wldev *dev,  		break;  	} -	if (phy->type == B43_PHYTYPE_N) { +	if (fill_phy_ctl1) {  		txhdr->phy_ctl1 =  			cpu_to_le16(b43_generate_tx_phy_ctl1(dev, rate));  		txhdr->phy_ctl1_fb = @@ -736,7 +740,14 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)  	/* Link quality statistics */  	switch (chanstat & B43_RX_CHAN_PHYTYPE) { +	case B43_PHYTYPE_HT: +		/* TODO: is max the right choice? */ +		status.signal = max_t(__s8, +			max(rxhdr->phy_ht_power0, rxhdr->phy_ht_power1), +			rxhdr->phy_ht_power2); +		break;  	case B43_PHYTYPE_N: +		/* Broadcom has code for min and avg, but always uses max */  		if (rxhdr->power0 == 16 || rxhdr->power0 == 32)  			status.signal = max(rxhdr->power1, rxhdr->power2);  		else diff --git a/drivers/net/wireless/b43/xmit.h b/drivers/net/wireless/b43/xmit.h index 16c514d54af..98d90747836 100644 --- a/drivers/net/wireless/b43/xmit.h +++ b/drivers/net/wireless/b43/xmit.h @@ -249,6 +249,12 @@ struct b43_rxhdr_fw4 {  		} __packed;  	} __packed;  	union { +		/* HT-PHY */ +		struct { +			PAD_BYTES(1); +			__s8 phy_ht_power0; +		} __packed; +  		/* RSSI for N-PHYs */  		struct {  			__s8 power2; @@ -257,7 +263,15 @@ struct b43_rxhdr_fw4 {  		__le16 phy_status2;	/* PHY RX Status 2 */  	} __packed; -	__le16 phy_status3;	/* PHY RX Status 3 */ +	union { +		/* HT-PHY */ +		struct { +			__s8 phy_ht_power1; +			__s8 phy_ht_power2; +		} __packed; + +		__le16 phy_status3;	/* PHY RX Status 3 */ +	} __packed;  	union {  		/* Tested with 598.314, 644.1001 and 666.2 */  		struct { diff --git a/drivers/net/wireless/brcm80211/brcmsmac/dma.c b/drivers/net/wireless/brcm80211/brcmsmac/dma.c index b56a30297c2..6ebec8f4284 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/dma.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/dma.c @@ -358,13 +358,14 @@ static uint nrxdactive(struct dma_info *di, uint h, uint t)  static uint _dma_ctrlflags(struct dma_info *di, uint mask, uint flags)  { -	uint dmactrlflags = di->dma.dmactrlflags; +	uint dmactrlflags;  	if (di == NULL) { -		DMA_ERROR(("%s: _dma_ctrlflags: NULL dma handle\n", di->name)); +		DMA_ERROR(("_dma_ctrlflags: NULL dma handle\n"));  		return 0;  	} +	dmactrlflags = di->dma.dmactrlflags;  	dmactrlflags &= ~mask;  	dmactrlflags |= flags; diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index da3411057af..ce918980e97 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -990,29 +990,16 @@ static int iwl_trans_tx_stop(struct iwl_trans *trans)  	return 0;  } -static void iwl_trans_pcie_disable_sync_irq(struct iwl_trans *trans) +static void iwl_trans_pcie_stop_device(struct iwl_trans *trans)  {  	unsigned long flags; -	struct iwl_trans_pcie *trans_pcie = -		IWL_TRANS_GET_PCIE_TRANS(trans); +	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); +	/* tell the device to stop sending interrupts */  	spin_lock_irqsave(&trans->shrd->lock, flags);  	iwl_disable_interrupts(trans);  	spin_unlock_irqrestore(&trans->shrd->lock, flags); -	/* wait to make sure we flush pending tasklet*/ -	synchronize_irq(bus(trans)->irq); -	tasklet_kill(&trans_pcie->irq_tasklet); -} - -static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) -{ -	/* stop and reset the on-board processor */ -	iwl_write32(bus(trans), CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET); - -	/* tell the device to stop sending interrupts */ -	iwl_trans_pcie_disable_sync_irq(trans); -  	/* device going down, Stop using ICT table */  	iwl_disable_ict(trans); @@ -1039,6 +1026,20 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans)  	/* Stop the device, and put it in low power state */  	iwl_apm_stop(priv(trans)); + +	/* Upon stop, the APM issues an interrupt if HW RF kill is set. +	 * Clean again the interrupt here +	 */ +	spin_lock_irqsave(&trans->shrd->lock, flags); +	iwl_disable_interrupts(trans); +	spin_unlock_irqrestore(&trans->shrd->lock, flags); + +	/* wait to make sure we flush pending tasklet*/ +	synchronize_irq(bus(trans)->irq); +	tasklet_kill(&trans_pcie->irq_tasklet); + +	/* stop and reset the on-board processor */ +	iwl_write32(bus(trans), CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET);  }  static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c index 4fcd653bddc..a7f1ab28940 100644 --- a/drivers/net/wireless/libertas/cfg.c +++ b/drivers/net/wireless/libertas/cfg.c @@ -634,7 +634,7 @@ static int lbs_ret_scan(struct lbs_private *priv, unsigned long dummy,  			if (channel &&  			    !(channel->flags & IEEE80211_CHAN_DISABLED))  				cfg80211_inform_bss(wiphy, channel, -					bssid, le64_to_cpu(*(__le64 *)tsfdesc), +					bssid, get_unaligned_le64(tsfdesc),  					capa, intvl, ie, ielen,  					LBS_SCAN_RSSI_TO_MBM(rssi),  					GFP_KERNEL); diff --git a/drivers/net/wireless/libertas/if_spi.c b/drivers/net/wireless/libertas/if_spi.c index 11b69b300dc..728baa44525 100644 --- a/drivers/net/wireless/libertas/if_spi.c +++ b/drivers/net/wireless/libertas/if_spi.c @@ -995,6 +995,7 @@ static int if_spi_host_to_card(struct lbs_private *priv,  		spin_unlock_irqrestore(&card->buffer_lock, flags);  		break;  	default: +		kfree(packet);  		netdev_err(priv->dev, "can't transfer buffer of type %d\n",  			   type);  		err = -EINVAL; diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c index dae8dbb24a0..8d3ab378662 100644 --- a/drivers/net/wireless/mwifiex/scan.c +++ b/drivers/net/wireless/mwifiex/scan.c @@ -819,8 +819,10 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv,  			wildcard_ssid_tlv->header.len = cpu_to_le16(  				(u16) (ssid_len + sizeof(wildcard_ssid_tlv->  							 max_ssid_length))); -			wildcard_ssid_tlv->max_ssid_length = -				user_scan_in->ssid_list[ssid_idx].max_len; + +			/* max_ssid_length = 0 tells firmware to perform +			   specific scan for the SSID filled */ +			wildcard_ssid_tlv->max_ssid_length = 0;  			memcpy(wildcard_ssid_tlv->ssid,  			       user_scan_in->ssid_list[ssid_idx].ssid, @@ -1469,7 +1471,7 @@ mwifiex_update_curr_bss_params(struct mwifiex_private *priv, u8 *bssid,  			       s32 rssi, const u8 *ie_buf, size_t ie_len,  			       u16 beacon_period, u16 cap_info_bitmap, u8 band)  { -	struct mwifiex_bssdescriptor *bss_desc = NULL; +	struct mwifiex_bssdescriptor *bss_desc;  	int ret;  	unsigned long flags;  	u8 *beacon_ie; @@ -1484,6 +1486,7 @@ mwifiex_update_curr_bss_params(struct mwifiex_private *priv, u8 *bssid,  	beacon_ie = kmemdup(ie_buf, ie_len, GFP_KERNEL);  	if (!beacon_ie) { +		kfree(bss_desc);  		dev_err(priv->adapter->dev, " failed to alloc beacon_ie\n");  		return -ENOMEM;  	} diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index f1565792f27..377876315b8 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -919,6 +919,7 @@ static struct usb_device_id rt2800usb_device_table[] = {  	{ USB_DEVICE(0x050d, 0x935b) },  	/* Buffalo */  	{ USB_DEVICE(0x0411, 0x00e8) }, +	{ USB_DEVICE(0x0411, 0x0158) },  	{ USB_DEVICE(0x0411, 0x016f) },  	{ USB_DEVICE(0x0411, 0x01a2) },  	/* Corega */ diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 2ec5c00235e..99ff12d0c29 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -943,6 +943,7 @@ struct rt2x00_dev {  	 * Powersaving work  	 */  	struct delayed_work autowakeup_work; +	struct work_struct sleep_work;  	/*  	 * Data queue arrays for RX, TX, Beacon and ATIM. diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index e1fb2a8569b..edd317fa7c0 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -465,6 +465,23 @@ static u8 *rt2x00lib_find_ie(u8 *data, unsigned int len, u8 ie)  	return NULL;  } +static void rt2x00lib_sleep(struct work_struct *work) +{ +	struct rt2x00_dev *rt2x00dev = +	    container_of(work, struct rt2x00_dev, sleep_work); + +	if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) +		return; + +	/* +	 * Check again is powersaving is enabled, to prevent races from delayed +	 * work execution. +	 */ +	if (!test_bit(CONFIG_POWERSAVING, &rt2x00dev->flags)) +		rt2x00lib_config(rt2x00dev, &rt2x00dev->hw->conf, +				 IEEE80211_CONF_CHANGE_PS); +} +  static void rt2x00lib_rxdone_check_ps(struct rt2x00_dev *rt2x00dev,  				      struct sk_buff *skb,  				      struct rxdone_entry_desc *rxdesc) @@ -512,8 +529,7 @@ static void rt2x00lib_rxdone_check_ps(struct rt2x00_dev *rt2x00dev,  	cam |= (tim_ie->bitmap_ctrl & 0x01);  	if (!cam && !test_bit(CONFIG_POWERSAVING, &rt2x00dev->flags)) -		rt2x00lib_config(rt2x00dev, &rt2x00dev->hw->conf, -				 IEEE80211_CONF_CHANGE_PS); +		queue_work(rt2x00dev->workqueue, &rt2x00dev->sleep_work);  }  static int rt2x00lib_rxdone_read_signal(struct rt2x00_dev *rt2x00dev, @@ -1141,6 +1157,7 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)  	INIT_WORK(&rt2x00dev->intf_work, rt2x00lib_intf_scheduled);  	INIT_DELAYED_WORK(&rt2x00dev->autowakeup_work, rt2x00lib_autowakeup); +	INIT_WORK(&rt2x00dev->sleep_work, rt2x00lib_sleep);  	/*  	 * Let the driver probe the device to detect the capabilities. @@ -1197,6 +1214,7 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev)  	 */  	cancel_work_sync(&rt2x00dev->intf_work);  	cancel_delayed_work_sync(&rt2x00dev->autowakeup_work); +	cancel_work_sync(&rt2x00dev->sleep_work);  	if (rt2x00_is_usb(rt2x00dev)) {  		del_timer_sync(&rt2x00dev->txstatus_timer);  		cancel_work_sync(&rt2x00dev->rxdone_work); diff --git a/drivers/net/wireless/wl12xx/scan.c b/drivers/net/wireless/wl12xx/scan.c index 128ccb79318..fc29c671cf3 100644 --- a/drivers/net/wireless/wl12xx/scan.c +++ b/drivers/net/wireless/wl12xx/scan.c @@ -559,7 +559,7 @@ wl12xx_scan_sched_scan_ssid_list(struct wl1271 *wl,  						break;  					}  				/* Fail if SSID isn't present in the filters */ -				if (j == req->n_ssids) { +				if (j == cmd->n_ssids) {  					ret = -EINVAL;  					goto out_free;  				} diff --git a/drivers/of/irq.c b/drivers/of/irq.c index 6d3dd3988d0..791270b8bd1 100644 --- a/drivers/of/irq.c +++ b/drivers/of/irq.c @@ -60,27 +60,27 @@ EXPORT_SYMBOL_GPL(irq_of_parse_and_map);   */  struct device_node *of_irq_find_parent(struct device_node *child)  { -	struct device_node *p, *c = child; +	struct device_node *p;  	const __be32 *parp; -	if (!of_node_get(c)) +	if (!of_node_get(child))  		return NULL;  	do { -		parp = of_get_property(c, "interrupt-parent", NULL); +		parp = of_get_property(child, "interrupt-parent", NULL);  		if (parp == NULL) -			p = of_get_parent(c); +			p = of_get_parent(child);  		else {  			if (of_irq_workarounds & OF_IMAP_NO_PHANDLE)  				p = of_node_get(of_irq_dflt_pic);  			else  				p = of_find_node_by_phandle(be32_to_cpup(parp));  		} -		of_node_put(c); -		c = p; +		of_node_put(child); +		child = p;  	} while (p && of_get_property(p, "#interrupt-cells", NULL) == NULL); -	return (p == child) ? NULL : p; +	return p;  }  /** diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index b6f9749b4fa..f02b5235056 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -76,6 +76,7 @@ config PCI_IOV  config PCI_PRI  	bool "PCI PRI support" +	depends on PCI  	select PCI_ATS  	help  	  PRI is the PCI Page Request Interface. It allows PCI devices that are diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index 596172b4ae9..fce1c54a0c8 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c @@ -459,8 +459,17 @@ static int add_bridge(acpi_handle handle)  {  	acpi_status status;  	unsigned long long tmp; +	struct acpi_pci_root *root;  	acpi_handle dummy_handle; +	/* +	 * We shouldn't use this bridge if PCIe native hotplug control has been +	 * granted by the BIOS for it. +	 */ +	root = acpi_pci_find_root(handle); +	if (root && (root->osc_control_set & OSC_PCI_EXPRESS_NATIVE_HP_CONTROL)) +		return -ENODEV; +  	/* if the bridge doesn't have _STA, we assume it is always there */  	status = acpi_get_handle(handle, "_STA", &dummy_handle);  	if (ACPI_SUCCESS(status)) { @@ -1376,13 +1385,23 @@ static void handle_hotplug_event_func(acpi_handle handle, u32 type,  static acpi_status  find_root_bridges(acpi_handle handle, u32 lvl, void *context, void **rv)  { +	struct acpi_pci_root *root;  	int *count = (int *)context; -	if (acpi_is_root_bridge(handle)) { -		acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY, -				handle_hotplug_event_bridge, NULL); -			(*count)++; -	} +	if (!acpi_is_root_bridge(handle)) +		return AE_OK; + +	root = acpi_pci_find_root(handle); +	if (!root) +		return AE_OK; + +	if (root->osc_control_set & OSC_PCI_EXPRESS_NATIVE_HP_CONTROL) +		return AE_OK; + +	(*count)++; +	acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY, +				    handle_hotplug_event_bridge, NULL); +  	return AE_OK ;  } diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c index 1e9c9aacc3a..085dbb5fc16 100644 --- a/drivers/pci/hotplug/pciehp_ctrl.c +++ b/drivers/pci/hotplug/pciehp_ctrl.c @@ -213,9 +213,6 @@ static int board_added(struct slot *p_slot)  		goto err_exit;  	} -	/* Wait for 1 second after checking link training status */ -	msleep(1000); -  	/* Check for a power fault */  	if (ctrl->power_fault_detected || pciehp_query_power_fault(p_slot)) {  		ctrl_err(ctrl, "Power fault on slot %s\n", slot_name(p_slot)); diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index 96dc4734e4a..7b1414810ae 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c @@ -280,6 +280,14 @@ int pciehp_check_link_status(struct controller *ctrl)          else                  msleep(1000); +	/* +	 * Need to wait for 1000 ms after Data Link Layer Link Active +	 * (DLLLA) bit reads 1b before sending configuration request. +	 * We need it before checking Link Training (LT) bit becuase +	 * LT is still set even after DLLLA bit is set on some platform. +	 */ +	msleep(1000); +  	retval = pciehp_readw(ctrl, PCI_EXP_LNKSTA, &lnk_status);  	if (retval) {  		ctrl_err(ctrl, "Cannot read LNKSTATUS register\n"); @@ -294,6 +302,16 @@ int pciehp_check_link_status(struct controller *ctrl)  		return retval;  	} +	/* +	 * If the port supports Link speeds greater than 5.0 GT/s, we +	 * must wait for 100 ms after Link training completes before +	 * sending configuration request. +	 */ +	if (ctrl->pcie->port->subordinate->max_bus_speed > PCIE_SPEED_5_0GT) +		msleep(100); + +	pcie_update_link_speed(ctrl->pcie->port->subordinate, lnk_status); +  	return retval;  } @@ -484,7 +502,6 @@ int pciehp_power_on_slot(struct slot * slot)  	u16 slot_cmd;  	u16 cmd_mask;  	u16 slot_status; -	u16 lnk_status;  	int retval = 0;  	/* Clear sticky power-fault bit from previous power failures */ @@ -516,14 +533,6 @@ int pciehp_power_on_slot(struct slot * slot)  	ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__,  		 pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd); -	retval = pciehp_readw(ctrl, PCI_EXP_LNKSTA, &lnk_status); -	if (retval) { -		ctrl_err(ctrl, "%s: Cannot read LNKSTA register\n", -				__func__); -		return retval; -	} -	pcie_update_link_speed(ctrl->pcie->port->subordinate, lnk_status); -  	return retval;  } diff --git a/drivers/pci/hotplug/shpchp_core.c b/drivers/pci/hotplug/shpchp_core.c index aca972bbfb4..dd7e0c51a33 100644 --- a/drivers/pci/hotplug/shpchp_core.c +++ b/drivers/pci/hotplug/shpchp_core.c @@ -278,8 +278,8 @@ static int get_adapter_status (struct hotplug_slot *hotplug_slot, u8 *value)  static int is_shpc_capable(struct pci_dev *dev)  { -	if ((dev->vendor == PCI_VENDOR_ID_AMD) || (dev->device == -						PCI_DEVICE_ID_AMD_GOLAM_7450)) +	if (dev->vendor == PCI_VENDOR_ID_AMD && +	    dev->device == PCI_DEVICE_ID_AMD_GOLAM_7450)  		return 1;  	if (!pci_find_capability(dev, PCI_CAP_ID_SHPC))  		return 0; diff --git a/drivers/pci/hotplug/shpchp_hpc.c b/drivers/pci/hotplug/shpchp_hpc.c index 36547f0ce30..75ba2311b54 100644 --- a/drivers/pci/hotplug/shpchp_hpc.c +++ b/drivers/pci/hotplug/shpchp_hpc.c @@ -944,8 +944,8 @@ int shpc_init(struct controller *ctrl, struct pci_dev *pdev)  	ctrl->pci_dev = pdev;  /* pci_dev of the P2P bridge */  	ctrl_dbg(ctrl, "Hotplug Controller:\n"); -	if ((pdev->vendor == PCI_VENDOR_ID_AMD) || (pdev->device == -				PCI_DEVICE_ID_AMD_GOLAM_7450)) { +	if (pdev->vendor == PCI_VENDOR_ID_AMD && +	    pdev->device == PCI_DEVICE_ID_AMD_GOLAM_7450) {  		/* amd shpc driver doesn't use Base Offset; assume 0 */  		ctrl->mmio_base = pci_resource_start(pdev, 0);  		ctrl->mmio_size = pci_resource_len(pdev, 0); diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index ef566443f94..e17e2f8001d 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -2,23 +2,17 @@  # PINCTRL infrastructure and drivers  # -menuconfig PINCTRL -	bool "PINCTRL Support" +config PINCTRL +	bool  	depends on EXPERIMENTAL -	help -	  This enables the PINCTRL subsystem for controlling pins -	  on chip packages, for example multiplexing pins on primarily -	  PGA and BGA packages for systems on chip. - -	  If unsure, say N.  if PINCTRL +menu "Pin controllers" +	depends on PINCTRL +  config PINMUX  	bool "Support pinmux controllers" -	help -	  Say Y here if you want the pincontrol subsystem to handle pin -	  multiplexing drivers.  config DEBUG_PINCTRL  	bool "Debug PINCTRL calls" @@ -30,14 +24,12 @@ config PINMUX_SIRF  	bool "CSR SiRFprimaII pinmux driver"  	depends on ARCH_PRIMA2  	select PINMUX -	help -	  Say Y here to enable the SiRFprimaII pinmux driver  config PINMUX_U300  	bool "U300 pinmux driver"  	depends on ARCH_U300  	select PINMUX -	help -	  Say Y here to enable the U300 pinmux driver + +endmenu  endif diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index f4e3d82379d..7f43cf86d77 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig @@ -83,8 +83,10 @@ config DELL_LAPTOP  	depends on EXPERIMENTAL  	depends on BACKLIGHT_CLASS_DEVICE  	depends on RFKILL || RFKILL = n -	depends on POWER_SUPPLY  	depends on SERIO_I8042 +	select POWER_SUPPLY +	select LEDS_CLASS +	select NEW_LEDS  	default n  	---help---  	This driver adds support for rfkill and backlight control to Dell diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c index a43cfd906c6..d93e962f261 100644 --- a/drivers/platform/x86/dell-laptop.c +++ b/drivers/platform/x86/dell-laptop.c @@ -589,14 +589,14 @@ static const struct backlight_ops dell_ops = {  	.update_status  = dell_send_intensity,  }; -static void touchpad_led_on() +static void touchpad_led_on(void)  {  	int command = 0x97;  	char data = 1;  	i8042_command(&data, command | 1 << 12);  } -static void touchpad_led_off() +static void touchpad_led_off(void)  {  	int command = 0x97;  	char data = 2; diff --git a/drivers/ps3/ps3-vuart.c b/drivers/ps3/ps3-vuart.c index d9fb729535a..fb7300837fe 100644 --- a/drivers/ps3/ps3-vuart.c +++ b/drivers/ps3/ps3-vuart.c @@ -952,7 +952,7 @@ static int ps3_vuart_bus_interrupt_get(void)  	}  	result = request_irq(vuart_bus_priv.virq, ps3_vuart_irq_handler, -		IRQF_DISABLED, "vuart", &vuart_bus_priv); +		0, "vuart", &vuart_bus_priv);  	if (result) {  		pr_debug("%s:%d: request_irq failed (%d)\n", diff --git a/drivers/ps3/ps3stor_lib.c b/drivers/ps3/ps3stor_lib.c index cc328dec946..8c3f5adf1bc 100644 --- a/drivers/ps3/ps3stor_lib.c +++ b/drivers/ps3/ps3stor_lib.c @@ -167,7 +167,7 @@ int ps3stor_setup(struct ps3_storage_device *dev, irq_handler_t handler)  		goto fail_close_device;  	} -	error = request_irq(dev->irq, handler, IRQF_DISABLED, +	error = request_irq(dev->irq, handler, 0,  			    dev->sbd.core.driver->name, dev);  	if (error) {  		dev_err(&dev->sbd.core, "%s:%u: request_irq failed %d\n", diff --git a/drivers/regulator/tps65910-regulator.c b/drivers/regulator/tps65910-regulator.c index 66d2d60b436..b552aae55b4 100644 --- a/drivers/regulator/tps65910-regulator.c +++ b/drivers/regulator/tps65910-regulator.c @@ -664,10 +664,10 @@ static int tps65910_set_voltage_dcdc(struct regulator_dev *dev,  	switch (id) {  	case TPS65910_REG_VDD1: -		dcdc_mult = (selector / VDD1_2_NUM_VOLTS) + 1; +		dcdc_mult = (selector / VDD1_2_NUM_VOLT_FINE) + 1;  		if (dcdc_mult == 1)  			dcdc_mult--; -		vsel = (selector % VDD1_2_NUM_VOLTS) + 3; +		vsel = (selector % VDD1_2_NUM_VOLT_FINE) + 3;  		tps65910_modify_bits(pmic, TPS65910_VDD1,  				(dcdc_mult << VDD1_VGAIN_SEL_SHIFT), @@ -675,10 +675,10 @@ static int tps65910_set_voltage_dcdc(struct regulator_dev *dev,  		tps65910_reg_write(pmic, TPS65910_VDD1_OP, vsel);  		break;  	case TPS65910_REG_VDD2: -		dcdc_mult = (selector / VDD1_2_NUM_VOLTS) + 1; +		dcdc_mult = (selector / VDD1_2_NUM_VOLT_FINE) + 1;  		if (dcdc_mult == 1)  			dcdc_mult--; -		vsel = (selector % VDD1_2_NUM_VOLTS) + 3; +		vsel = (selector % VDD1_2_NUM_VOLT_FINE) + 3;  		tps65910_modify_bits(pmic, TPS65910_VDD2,  				(dcdc_mult << VDD2_VGAIN_SEL_SHIFT), @@ -756,9 +756,9 @@ static int tps65910_list_voltage_dcdc(struct regulator_dev *dev,  	switch (id) {  	case TPS65910_REG_VDD1:  	case TPS65910_REG_VDD2: -		mult = (selector / VDD1_2_NUM_VOLTS) + 1; +		mult = (selector / VDD1_2_NUM_VOLT_FINE) + 1;  		volt = VDD1_2_MIN_VOLT + -				(selector % VDD1_2_NUM_VOLTS) * VDD1_2_OFFSET; +				(selector % VDD1_2_NUM_VOLT_FINE) * VDD1_2_OFFSET;  		break;  	case TPS65911_REG_VDDCTRL:  		volt = VDDCTRL_MIN_VOLT + (selector * VDDCTRL_OFFSET); @@ -947,6 +947,8 @@ static __devinit int tps65910_probe(struct platform_device *pdev)  		if (i == TPS65910_REG_VDD1 || i == TPS65910_REG_VDD2) {  			pmic->desc[i].ops = &tps65910_ops_dcdc; +			pmic->desc[i].n_voltages = VDD1_2_NUM_VOLT_FINE * +							VDD1_2_NUM_VOLT_COARSE;  		} else if (i == TPS65910_REG_VDD3) {  			if (tps65910_chip_id(tps65910) == TPS65910)  				pmic->desc[i].ops = &tps65910_ops_vdd3; diff --git a/drivers/rtc/rtc-mrst.c b/drivers/rtc/rtc-mrst.c index d33544802a2..bb21f443fb7 100644 --- a/drivers/rtc/rtc-mrst.c +++ b/drivers/rtc/rtc-mrst.c @@ -76,12 +76,15 @@ static inline unsigned char vrtc_is_updating(void)  /*   * rtc_time's year contains the increment over 1900, but vRTC's YEAR   * register can't be programmed to value larger than 0x64, so vRTC - * driver chose to use 1960 (1970 is UNIX time start point) as the base, + * driver chose to use 1972 (1970 is UNIX time start point) as the base,   * and does the translation at read/write time.   * - * Why not just use 1970 as the offset? it's because using 1960 will + * Why not just use 1970 as the offset? it's because using 1972 will   * make it consistent in leap year setting for both vrtc and low-level - * physical rtc devices. + * physical rtc devices. Then why not use 1960 as the offset? If we use + * 1960, for a device's first use, its YEAR register is 0 and the system + * year will be parsed as 1960 which is not a valid UNIX time and will + * cause many applications to fail mysteriously.   */  static int mrst_read_time(struct device *dev, struct rtc_time *time)  { @@ -99,10 +102,10 @@ static int mrst_read_time(struct device *dev, struct rtc_time *time)  	time->tm_year = vrtc_cmos_read(RTC_YEAR);  	spin_unlock_irqrestore(&rtc_lock, flags); -	/* Adjust for the 1960/1900 */ -	time->tm_year += 60; +	/* Adjust for the 1972/1900 */ +	time->tm_year += 72;  	time->tm_mon--; -	return RTC_24H; +	return rtc_valid_tm(time);  }  static int mrst_set_time(struct device *dev, struct rtc_time *time) @@ -119,9 +122,9 @@ static int mrst_set_time(struct device *dev, struct rtc_time *time)  	min = time->tm_min;  	sec = time->tm_sec; -	if (yrs < 70 || yrs > 138) +	if (yrs < 72 || yrs > 138)  		return -EINVAL; -	yrs -= 60; +	yrs -= 72;  	spin_lock_irqsave(&rtc_lock, flags); diff --git a/drivers/rtc/rtc-puv3.c b/drivers/rtc/rtc-puv3.c index b3eba3cddd4..e4b6880aabd 100644 --- a/drivers/rtc/rtc-puv3.c +++ b/drivers/rtc/rtc-puv3.c @@ -220,7 +220,7 @@ static void puv3_rtc_enable(struct platform_device *pdev, int en)  	}  } -static int puv3_rtc_remove(struct platform_device *dev) +static int __devexit puv3_rtc_remove(struct platform_device *dev)  {  	struct rtc_device *rtc = platform_get_drvdata(dev); @@ -236,7 +236,7 @@ static int puv3_rtc_remove(struct platform_device *dev)  	return 0;  } -static int puv3_rtc_probe(struct platform_device *pdev) +static int __devinit puv3_rtc_probe(struct platform_device *pdev)  {  	struct rtc_device *rtc;  	struct resource *res; diff --git a/drivers/s390/char/zcore.c b/drivers/s390/char/zcore.c index 43068fbd0ba..1b6d9247fdc 100644 --- a/drivers/s390/char/zcore.c +++ b/drivers/s390/char/zcore.c @@ -641,6 +641,8 @@ static int __init zcore_init(void)  	if (ipl_info.type != IPL_TYPE_FCP_DUMP)  		return -ENODATA; +	if (OLDMEM_BASE) +		return -ENODATA;  	zcore_dbf = debug_register("zcore", 4, 1, 4 * sizeof(long));  	debug_register_view(zcore_dbf, &debug_sprintf_view); diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c index b77ae519d79..ec94f049e99 100644 --- a/drivers/s390/crypto/ap_bus.c +++ b/drivers/s390/crypto/ap_bus.c @@ -1271,18 +1271,16 @@ ap_config_timeout(unsigned long ptr)  }  /** - * ap_schedule_poll_timer(): Schedule poll timer. + * __ap_schedule_poll_timer(): Schedule poll timer.   *   * Set up the timer to run the poll tasklet   */ -static inline void ap_schedule_poll_timer(void) +static inline void __ap_schedule_poll_timer(void)  {  	ktime_t hr_time;  	spin_lock_bh(&ap_poll_timer_lock); -	if (ap_using_interrupts() || ap_suspend_flag) -		goto out; -	if (hrtimer_is_queued(&ap_poll_timer)) +	if (hrtimer_is_queued(&ap_poll_timer) || ap_suspend_flag)  		goto out;  	if (ktime_to_ns(hrtimer_expires_remaining(&ap_poll_timer)) <= 0) {  		hr_time = ktime_set(0, poll_timeout); @@ -1294,6 +1292,18 @@ out:  }  /** + * ap_schedule_poll_timer(): Schedule poll timer. + * + * Set up the timer to run the poll tasklet + */ +static inline void ap_schedule_poll_timer(void) +{ +	if (ap_using_interrupts()) +		return; +	__ap_schedule_poll_timer(); +} + +/**   * ap_poll_read(): Receive pending reply messages from an AP device.   * @ap_dev: pointer to the AP device   * @flags: pointer to control flags, bit 2^0 is set if another poll is @@ -1374,8 +1384,9 @@ static int ap_poll_write(struct ap_device *ap_dev, unsigned long *flags)  			*flags |= 1;  		*flags |= 2;  		break; -	case AP_RESPONSE_Q_FULL:  	case AP_RESPONSE_RESET_IN_PROGRESS: +		__ap_schedule_poll_timer(); +	case AP_RESPONSE_Q_FULL:  		*flags |= 2;  		break;  	case AP_RESPONSE_MESSAGE_TOO_BIG: diff --git a/drivers/s390/net/Kconfig b/drivers/s390/net/Kconfig index fa80ba1f034..9b66d2d1809 100644 --- a/drivers/s390/net/Kconfig +++ b/drivers/s390/net/Kconfig @@ -4,7 +4,7 @@ menu "S/390 network device drivers"  config LCS  	def_tristate m  	prompt "Lan Channel Station Interface" -	depends on CCW && NETDEVICES && (NET_ETHERNET || TR || FDDI) +	depends on CCW && NETDEVICES && (ETHERNET || TR || FDDI)  	help  	   Select this option if you want to use LCS networking on IBM System z.  	   This device driver supports Token Ring (IEEE 802.5), diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c index c28713da1ec..863fc219715 100644 --- a/drivers/s390/net/lcs.c +++ b/drivers/s390/net/lcs.c @@ -50,7 +50,7 @@  #include "lcs.h" -#if !defined(CONFIG_NET_ETHERNET) && \ +#if !defined(CONFIG_ETHERNET) && \      !defined(CONFIG_TR) && !defined(CONFIG_FDDI)  #error Cannot compile lcs.c without some net devices switched on.  #endif @@ -1634,7 +1634,7 @@ lcs_startlan_auto(struct lcs_card *card)  	int rc;  	LCS_DBF_TEXT(2, trace, "strtauto"); -#ifdef CONFIG_NET_ETHERNET +#ifdef CONFIG_ETHERNET  	card->lan_type = LCS_FRAME_TYPE_ENET;  	rc = lcs_send_startlan(card, LCS_INITIATOR_TCPIP);  	if (rc == 0) @@ -2166,7 +2166,7 @@ lcs_new_device(struct ccwgroup_device *ccwgdev)  		goto netdev_out;  	}  	switch (card->lan_type) { -#ifdef CONFIG_NET_ETHERNET +#ifdef CONFIG_ETHERNET  	case LCS_FRAME_TYPE_ENET:  		card->lan_type_trans = eth_type_trans;  		dev = alloc_etherdev(0); diff --git a/drivers/s390/net/netiucv.c b/drivers/s390/net/netiucv.c index 3251333a23d..b6a6356d09b 100644 --- a/drivers/s390/net/netiucv.c +++ b/drivers/s390/net/netiucv.c @@ -1994,6 +1994,8 @@ static struct net_device *netiucv_init_netdevice(char *username)  			   netiucv_setup_netdevice);  	if (!dev)  		return NULL; +	if (dev_alloc_name(dev, dev->name) < 0) +		goto out_netdev;  	privptr = netdev_priv(dev);  	privptr->fsm = init_fsm("netiucvdev", dev_state_names, diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h index b77c65ed138..4abc79d3963 100644 --- a/drivers/s390/net/qeth_core.h +++ b/drivers/s390/net/qeth_core.h @@ -236,8 +236,7 @@ static inline int qeth_is_ipa_enabled(struct qeth_ipa_info *ipa,  #define QETH_IN_BUF_COUNT_MAX 128  #define QETH_MAX_BUFFER_ELEMENTS(card) ((card)->qdio.in_buf_size >> 12)  #define QETH_IN_BUF_REQUEUE_THRESHOLD(card) \ -		((card)->ssqd.qdioac1 & AC1_SIGA_INPUT_NEEDED ? 1 : \ -		 ((card)->qdio.in_buf_pool.buf_count / 2)) +		 ((card)->qdio.in_buf_pool.buf_count / 2)  /* buffers we have to be behind before we get a PCI */  #define QETH_PCI_THRESHOLD_A(card) ((card)->qdio.in_buf_pool.buf_count+1) diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 81534437373..fff57de7894 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -881,7 +881,6 @@ EXPORT_SYMBOL_GPL(qeth_do_run_thread);  void qeth_schedule_recovery(struct qeth_card *card)  {  	QETH_CARD_TEXT(card, 2, "startrec"); -	WARN_ON(1);  	if (qeth_set_thread_start_bit(card, QETH_RECOVER_THREAD) == 0)  		schedule_work(&card->kernel_thread_starter);  } diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index e4c1176ee25..4d5307ddbe5 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -2756,11 +2756,13 @@ int inline qeth_l3_get_cast_type(struct qeth_card *card, struct sk_buff *skb)  	struct neighbour *n = NULL;  	struct dst_entry *dst; +	rcu_read_lock();  	dst = skb_dst(skb);  	if (dst)  		n = dst_get_neighbour(dst);  	if (n) {  		cast_type = n->type; +		rcu_read_unlock();  		if ((cast_type == RTN_BROADCAST) ||  		    (cast_type == RTN_MULTICAST) ||  		    (cast_type == RTN_ANYCAST)) @@ -2768,6 +2770,8 @@ int inline qeth_l3_get_cast_type(struct qeth_card *card, struct sk_buff *skb)  		else  			return RTN_UNSPEC;  	} +	rcu_read_unlock(); +  	/* try something else */  	if (skb->protocol == ETH_P_IPV6)  		return (skb_network_header(skb)[24] == 0xff) ? @@ -2847,6 +2851,8 @@ static void qeth_l3_fill_header(struct qeth_card *card, struct qeth_hdr *hdr,  	}  	hdr->hdr.l3.length = skb->len - sizeof(struct qeth_hdr); + +	rcu_read_lock();  	dst = skb_dst(skb);  	if (dst)  		n = dst_get_neighbour(dst); @@ -2893,6 +2899,7 @@ static void qeth_l3_fill_header(struct qeth_card *card, struct qeth_hdr *hdr,  				QETH_CAST_UNICAST | QETH_HDR_PASSTHRU;  		}  	} +	rcu_read_unlock();  }  static inline void qeth_l3_hdr_csum(struct qeth_card *card, diff --git a/drivers/s390/net/qeth_l3_sys.c b/drivers/s390/net/qeth_l3_sys.c index 0ea2fbfe0e9..d979bb26522 100644 --- a/drivers/s390/net/qeth_l3_sys.c +++ b/drivers/s390/net/qeth_l3_sys.c @@ -335,10 +335,10 @@ static ssize_t qeth_l3_dev_sniffer_store(struct device *dev,  					QETH_IN_BUF_COUNT_MAX)  				qeth_realloc_buffer_pool(card,  					QETH_IN_BUF_COUNT_MAX); -			break;  		} else  			rc = -EPERM; -	default:   /* fall through */ +		break; +	default:  		rc = -EINVAL;  	}  out: diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c index 4aa76d6f11d..705e13e470a 100644 --- a/drivers/scsi/aacraid/linit.c +++ b/drivers/scsi/aacraid/linit.c @@ -38,6 +38,7 @@  #include <linux/module.h>  #include <linux/moduleparam.h>  #include <linux/pci.h> +#include <linux/pci-aspm.h>  #include <linux/slab.h>  #include <linux/mutex.h>  #include <linux/spinlock.h> @@ -1109,6 +1110,9 @@ static int __devinit aac_probe_one(struct pci_dev *pdev,  		unique_id++;  	} +	pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1 | +			       PCIE_LINK_STATE_CLKPM); +  	error = pci_enable_device(pdev);  	if (error)  		goto out; diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index e76107b2ade..865d452542b 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c @@ -23,6 +23,7 @@  #include <linux/interrupt.h>  #include <linux/types.h>  #include <linux/pci.h> +#include <linux/pci-aspm.h>  #include <linux/kernel.h>  #include <linux/slab.h>  #include <linux/delay.h> @@ -3922,6 +3923,10 @@ static int __devinit hpsa_pci_init(struct ctlr_info *h)  		dev_warn(&h->pdev->dev, "controller appears to be disabled\n");  		return -ENODEV;  	} + +	pci_disable_link_state(h->pdev, PCIE_LINK_STATE_L0S | +			       PCIE_LINK_STATE_L1 | PCIE_LINK_STATE_CLKPM); +  	err = pci_enable_device(h->pdev);  	if (err) {  		dev_warn(&h->pdev->dev, "unable to enable PCI device\n"); diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c index 8889b1babca..4e041f6d808 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c +++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c @@ -2802,6 +2802,11 @@ _scsih_error_recovery_delete_devices(struct MPT2SAS_ADAPTER *ioc)  	if (ioc->is_driver_loading)  		return; + +	fw_event = kzalloc(sizeof(struct fw_event_work), GFP_ATOMIC); +	if (!fw_event) +		return; +  	fw_event->event = MPT2SAS_REMOVE_UNRESPONDING_DEVICES;  	fw_event->ioc = ioc;  	_scsih_fw_event_add(ioc, fw_event); diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 06bc26554a6..f85cfa6c47b 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -1409,6 +1409,8 @@ static void scsi_kill_request(struct request *req, struct request_queue *q)  	blk_start_request(req); +	scmd_printk(KERN_INFO, cmd, "killing request\n"); +  	sdev = cmd->device;  	starget = scsi_target(sdev);  	shost = sdev->host; @@ -1490,7 +1492,6 @@ static void scsi_request_fn(struct request_queue *q)  	struct request *req;  	if (!sdev) { -		printk("scsi: killing requests for dead queue\n");  		while ((req = blk_peek_request(q)) != NULL)  			scsi_kill_request(req, q);  		return; diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index 72273a0e566..b3c6d957fbd 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -319,11 +319,7 @@ static struct scsi_device *scsi_alloc_sdev(struct scsi_target *starget,  	return sdev;  out_device_destroy: -	scsi_device_set_state(sdev, SDEV_DEL); -	transport_destroy_device(&sdev->sdev_gendev); -	put_device(&sdev->sdev_dev); -	scsi_free_queue(sdev->request_queue); -	put_device(&sdev->sdev_gendev); +	__scsi_remove_device(sdev);  out:  	if (display_failure_msg)  		printk(ALLOC_FAILURE_MSG, __func__); diff --git a/drivers/sh/Makefile b/drivers/sh/Makefile index 24e6cec0ae8..67e272ab162 100644 --- a/drivers/sh/Makefile +++ b/drivers/sh/Makefile @@ -7,3 +7,11 @@ obj-$(CONFIG_HAVE_CLK)		+= clk/  obj-$(CONFIG_MAPLE)		+= maple/  obj-$(CONFIG_SUPERHYWAY)	+= superhyway/  obj-$(CONFIG_GENERIC_GPIO)	+= pfc.o + +# +# For the moment we only use this framework for ARM-based SH/R-Mobile +# platforms and generic SH. SH-based SH-Mobile platforms are still using +# an older framework that is pending up-porting, at which point this +# special casing can go away. +# +obj-$(CONFIG_SUPERH)$(CONFIG_ARCH_SHMOBILE)	+= pm_runtime.o diff --git a/drivers/sh/clk/core.c b/drivers/sh/clk/core.c index dc8d022c07a..db257a35e71 100644 --- a/drivers/sh/clk/core.c +++ b/drivers/sh/clk/core.c @@ -25,7 +25,6 @@  #include <linux/seq_file.h>  #include <linux/err.h>  #include <linux/io.h> -#include <linux/debugfs.h>  #include <linux/cpufreq.h>  #include <linux/clk.h>  #include <linux/sh_clk.h> @@ -173,6 +172,26 @@ long clk_rate_div_range_round(struct clk *clk, unsigned int div_min,  	return clk_rate_round_helper(&div_range_round);  } +static long clk_rate_mult_range_iter(unsigned int pos, +				      struct clk_rate_round_data *rounder) +{ +	return clk_get_rate(rounder->arg) * pos; +} + +long clk_rate_mult_range_round(struct clk *clk, unsigned int mult_min, +			       unsigned int mult_max, unsigned long rate) +{ +	struct clk_rate_round_data mult_range_round = { +		.min	= mult_min, +		.max	= mult_max, +		.func	= clk_rate_mult_range_iter, +		.arg	= clk_get_parent(clk), +		.rate	= rate, +	}; + +	return clk_rate_round_helper(&mult_range_round); +} +  int clk_rate_table_find(struct clk *clk,  			struct cpufreq_frequency_table *freq_table,  			unsigned long rate) @@ -205,9 +224,6 @@ int clk_reparent(struct clk *child, struct clk *parent)  		list_add(&child->sibling, &parent->children);  	child->parent = parent; -	/* now do the debugfs renaming to reattach the child -	   to the proper parent */ -  	return 0;  } @@ -665,89 +681,6 @@ static int __init clk_syscore_init(void)  subsys_initcall(clk_syscore_init);  #endif -/* - *	debugfs support to trace clock tree hierarchy and attributes - */ -static struct dentry *clk_debugfs_root; - -static int clk_debugfs_register_one(struct clk *c) -{ -	int err; -	struct dentry *d; -	struct clk *pa = c->parent; -	char s[255]; -	char *p = s; - -	p += sprintf(p, "%p", c); -	d = debugfs_create_dir(s, pa ? pa->dentry : clk_debugfs_root); -	if (!d) -		return -ENOMEM; -	c->dentry = d; - -	d = debugfs_create_u8("usecount", S_IRUGO, c->dentry, (u8 *)&c->usecount); -	if (!d) { -		err = -ENOMEM; -		goto err_out; -	} -	d = debugfs_create_u32("rate", S_IRUGO, c->dentry, (u32 *)&c->rate); -	if (!d) { -		err = -ENOMEM; -		goto err_out; -	} -	d = debugfs_create_x32("flags", S_IRUGO, c->dentry, (u32 *)&c->flags); -	if (!d) { -		err = -ENOMEM; -		goto err_out; -	} -	return 0; - -err_out: -	debugfs_remove_recursive(c->dentry); -	return err; -} - -static int clk_debugfs_register(struct clk *c) -{ -	int err; -	struct clk *pa = c->parent; - -	if (pa && !pa->dentry) { -		err = clk_debugfs_register(pa); -		if (err) -			return err; -	} - -	if (!c->dentry) { -		err = clk_debugfs_register_one(c); -		if (err) -			return err; -	} -	return 0; -} - -static int __init clk_debugfs_init(void) -{ -	struct clk *c; -	struct dentry *d; -	int err; - -	d = debugfs_create_dir("clock", NULL); -	if (!d) -		return -ENOMEM; -	clk_debugfs_root = d; - -	list_for_each_entry(c, &clock_list, node) { -		err = clk_debugfs_register(c); -		if (err) -			goto err_out; -	} -	return 0; -err_out: -	debugfs_remove_recursive(clk_debugfs_root); -	return err; -} -late_initcall(clk_debugfs_init); -  static int __init clk_late_init(void)  {  	unsigned long flags; diff --git a/drivers/sh/pm_runtime.c b/drivers/sh/pm_runtime.c new file mode 100644 index 00000000000..afe9282629b --- /dev/null +++ b/drivers/sh/pm_runtime.c @@ -0,0 +1,65 @@ +/* + * Runtime PM support code + * + *  Copyright (C) 2009-2010 Magnus Damm + * + * This file is subject to the terms and conditions of the GNU General Public + * License.  See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/io.h> +#include <linux/pm_runtime.h> +#include <linux/pm_domain.h> +#include <linux/pm_clock.h> +#include <linux/platform_device.h> +#include <linux/clk.h> +#include <linux/sh_clk.h> +#include <linux/bitmap.h> +#include <linux/slab.h> + +#ifdef CONFIG_PM_RUNTIME + +static int default_platform_runtime_idle(struct device *dev) +{ +	/* suspend synchronously to disable clocks immediately */ +	return pm_runtime_suspend(dev); +} + +static struct dev_pm_domain default_pm_domain = { +	.ops = { +		.runtime_suspend = pm_clk_suspend, +		.runtime_resume = pm_clk_resume, +		.runtime_idle = default_platform_runtime_idle, +		USE_PLATFORM_PM_SLEEP_OPS +	}, +}; + +#define DEFAULT_PM_DOMAIN_PTR	(&default_pm_domain) + +#else + +#define DEFAULT_PM_DOMAIN_PTR	NULL + +#endif /* CONFIG_PM_RUNTIME */ + +static struct pm_clk_notifier_block platform_bus_notifier = { +	.pm_domain = DEFAULT_PM_DOMAIN_PTR, +	.con_ids = { NULL, }, +}; + +static int __init sh_pm_runtime_init(void) +{ +	pm_clk_add_notifier(&platform_bus_type, &platform_bus_notifier); +	return 0; +} +core_initcall(sh_pm_runtime_init); + +static int __init sh_pm_runtime_late_init(void) +{ +	pm_genpd_poweroff_unused(); +	return 0; +} +late_initcall(sh_pm_runtime_late_init); diff --git a/drivers/spi/spi-atmel.c b/drivers/spi/spi-atmel.c index 79665e2e6ec..16d6a839c7f 100644 --- a/drivers/spi/spi-atmel.c +++ b/drivers/spi/spi-atmel.c @@ -907,7 +907,7 @@ static void atmel_spi_cleanup(struct spi_device *spi)  /*-------------------------------------------------------------------------*/ -static int __init atmel_spi_probe(struct platform_device *pdev) +static int __devinit atmel_spi_probe(struct platform_device *pdev)  {  	struct resource		*regs;  	int			irq; @@ -1003,7 +1003,7 @@ out_free:  	return ret;  } -static int __exit atmel_spi_remove(struct platform_device *pdev) +static int __devexit atmel_spi_remove(struct platform_device *pdev)  {  	struct spi_master	*master = platform_get_drvdata(pdev);  	struct atmel_spi	*as = spi_master_get_devdata(master); @@ -1072,6 +1072,7 @@ static struct platform_driver atmel_spi_driver = {  	},  	.suspend	= atmel_spi_suspend,  	.resume		= atmel_spi_resume, +	.probe		= atmel_spi_probe,  	.remove		= __exit_p(atmel_spi_remove),  };  module_platform_driver(atmel_spi_driver); diff --git a/drivers/spi/spi-pl022.c b/drivers/spi/spi-pl022.c index f103e470cb6..5559b229919 100644 --- a/drivers/spi/spi-pl022.c +++ b/drivers/spi/spi-pl022.c @@ -2184,6 +2184,12 @@ pl022_probe(struct amba_device *adev, const struct amba_id *id)  		goto  err_clk_prep;  	} +	status = clk_enable(pl022->clk); +	if (status) { +		dev_err(&adev->dev, "could not enable SSP/SPI bus clock\n"); +		goto err_no_clk_en; +	} +  	/* Disable SSP */  	writew((readw(SSP_CR1(pl022->virtbase)) & (~SSP_CR1_MASK_SSE)),  	       SSP_CR1(pl022->virtbase)); @@ -2237,6 +2243,8 @@ pl022_probe(struct amba_device *adev, const struct amba_id *id)  	free_irq(adev->irq[0], pl022);   err_no_irq: +	clk_disable(pl022->clk); + err_no_clk_en:  	clk_unprepare(pl022->clk);   err_clk_prep:  	clk_put(pl022->clk); diff --git a/drivers/staging/et131x/Kconfig b/drivers/staging/et131x/Kconfig index 9e1864c6dfd..8190f2aaf53 100644 --- a/drivers/staging/et131x/Kconfig +++ b/drivers/staging/et131x/Kconfig @@ -1,6 +1,7 @@  config ET131X  	tristate "Agere ET-1310 Gigabit Ethernet support" -	depends on PCI +	depends on PCI && NET && NETDEVICES +	select PHYLIB  	default n  	---help---  	  This driver supports Agere ET-1310 ethernet adapters. diff --git a/drivers/staging/et131x/et131x.c b/drivers/staging/et131x/et131x.c index f5f44a02456..0c1c6ca8c37 100644 --- a/drivers/staging/et131x/et131x.c +++ b/drivers/staging/et131x/et131x.c @@ -4469,6 +4469,12 @@ static int et131x_resume(struct device *dev)  	return 0;  } +static SIMPLE_DEV_PM_OPS(et131x_pm_ops, et131x_suspend, et131x_resume); +#define ET131X_PM_OPS (&et131x_pm_ops) +#else +#define ET131X_PM_OPS NULL +#endif +  /* ISR functions */  /** @@ -5470,12 +5476,6 @@ err_out:  	return result;  } -static SIMPLE_DEV_PM_OPS(et131x_pm_ops, et131x_suspend, et131x_resume); -#define ET131X_PM_OPS (&et131x_pm_ops) -#else -#define ET131X_PM_OPS NULL -#endif -  static DEFINE_PCI_DEVICE_TABLE(et131x_pci_table) = {  	{ PCI_VDEVICE(ATT, ET131X_PCI_DEVICE_ID_GIG), 0UL},  	{ PCI_VDEVICE(ATT, ET131X_PCI_DEVICE_ID_FAST), 0UL}, diff --git a/drivers/staging/iio/industrialio-core.c b/drivers/staging/iio/industrialio-core.c index 326e967d54e..26564094e33 100644 --- a/drivers/staging/iio/industrialio-core.c +++ b/drivers/staging/iio/industrialio-core.c @@ -242,6 +242,8 @@ static const struct file_operations iio_event_chrdev_fileops = {  static int iio_event_getfd(struct iio_dev *indio_dev)  { +	int fd; +  	if (indio_dev->event_interface == NULL)  		return -ENODEV; @@ -252,9 +254,15 @@ static int iio_event_getfd(struct iio_dev *indio_dev)  		return -EBUSY;  	}  	mutex_unlock(&indio_dev->event_interface->event_list_lock); -	return anon_inode_getfd("iio:event", +	fd = anon_inode_getfd("iio:event",  				&iio_event_chrdev_fileops,  				indio_dev->event_interface, O_RDONLY); +	if (fd < 0) { +		mutex_lock(&indio_dev->event_interface->event_list_lock); +		clear_bit(IIO_BUSY_BIT_POS, &ev_int->flags); +		mutex_unlock(&indio_dev->event_interface->event_list_lock); +	} +	return fd;  }  static int __init iio_init(void) diff --git a/drivers/staging/media/as102/as102_drv.c b/drivers/staging/media/as102/as102_drv.c index d335c7d6fa0..828526d4c28 100644 --- a/drivers/staging/media/as102/as102_drv.c +++ b/drivers/staging/media/as102/as102_drv.c @@ -32,8 +32,8 @@  #include "as102_fw.h"  #include "dvbdev.h" -int debug; -module_param_named(debug, debug, int, 0644); +int as102_debug; +module_param_named(debug, as102_debug, int, 0644);  MODULE_PARM_DESC(debug, "Turn on/off debugging (default: off)");  int dual_tuner; diff --git a/drivers/staging/media/as102/as102_drv.h b/drivers/staging/media/as102/as102_drv.h index bcda635b5a9..fd33f5a12dc 100644 --- a/drivers/staging/media/as102/as102_drv.h +++ b/drivers/staging/media/as102/as102_drv.h @@ -37,7 +37,8 @@ extern struct spi_driver as102_spi_driver;  #define DRIVER_FULL_NAME "Abilis Systems as10x usb driver"  #define DRIVER_NAME "as10x_usb" -extern int debug; +extern int as102_debug; +#define debug	as102_debug  #define dprintk(debug, args...) \  	do { if (debug) {	\ diff --git a/drivers/staging/octeon/ethernet-tx.c b/drivers/staging/octeon/ethernet-tx.c index b445cd63f90..2542c374390 100644 --- a/drivers/staging/octeon/ethernet-tx.c +++ b/drivers/staging/octeon/ethernet-tx.c @@ -275,7 +275,7 @@ int cvm_oct_xmit(struct sk_buff *skb, struct net_device *dev)  		CVM_OCT_SKB_CB(skb)[0] = hw_buffer.u64;  		for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {  			struct skb_frag_struct *fs = skb_shinfo(skb)->frags + i; -			hw_buffer.s.addr = XKPHYS_TO_PHYS((u64)(page_address(fs->page) + fs->page_offset)); +			hw_buffer.s.addr = XKPHYS_TO_PHYS((u64)(page_address(fs->page.p) + fs->page_offset));  			hw_buffer.s.size = fs->size;  			CVM_OCT_SKB_CB(skb)[i + 1] = hw_buffer.u64;  		} diff --git a/drivers/staging/slicoss/Kconfig b/drivers/staging/slicoss/Kconfig index 5cde96b2e6e..5c2a15b42df 100644 --- a/drivers/staging/slicoss/Kconfig +++ b/drivers/staging/slicoss/Kconfig @@ -1,6 +1,6 @@  config SLICOSS  	tristate "Alacritech Gigabit IS-NIC support" -	depends on PCI && X86 +	depends on PCI && X86 && NET  	default n  	help  	  This driver supports Alacritech's IS-NIC gigabit ethernet cards. diff --git a/drivers/tty/hvc/hvc_dcc.c b/drivers/tty/hvc/hvc_dcc.c index 435f6facbc2..44fbebab507 100644 --- a/drivers/tty/hvc/hvc_dcc.c +++ b/drivers/tty/hvc/hvc_dcc.c @@ -46,6 +46,7 @@ static inline char __dcc_getchar(void)  	asm volatile("mrc p14, 0, %0, c0, c5, 0	@ read comms data reg"  		: "=r" (__c)); +	isb();  	return __c;  } @@ -55,6 +56,7 @@ static inline void __dcc_putchar(char c)  	asm volatile("mcr p14, 0, %0, c0, c5, 0	@ write a char"  		: /* no output register */  		: "r" (c)); +	isb();  }  static int hvc_dcc_put_chars(uint32_t vt, const char *buf, int count) diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index 4cb0d0a3e57..fc7bbba585c 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -66,14 +66,16 @@  static int debug;  module_param(debug, int, 0600); -#define T1	(HZ/10) -#define T2	(HZ/3) -#define N2	3 +/* Defaults: these are from the specification */ + +#define T1	10		/* 100mS */ +#define T2	34		/* 333mS */ +#define N2	3		/* Retry 3 times */  /* Use long timers for testing at low speed with debug on */  #ifdef DEBUG_TIMING -#define T1	HZ -#define T2	(2 * HZ) +#define T1	100 +#define T2	200  #endif  /* diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index 5f479dada6f..925a1e547a8 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -1560,7 +1560,7 @@ config SERIAL_IFX6X60  	  Support for the IFX6x60 modem devices on Intel MID platforms.  config SERIAL_PCH_UART -	tristate "Intel EG20T PCH / OKI SEMICONDUCTOR IOH(ML7213/ML7223) UART" +	tristate "Intel EG20T PCH/LAPIS Semicon IOH(ML7213/ML7223/ML7831) UART"  	depends on PCI  	select SERIAL_CORE  	help @@ -1568,12 +1568,12 @@ config SERIAL_PCH_UART  	  which is an IOH(Input/Output Hub) for x86 embedded processor.  	  Enabling PCH_DMA, this PCH UART works as DMA mode. -	  This driver also can be used for OKI SEMICONDUCTOR IOH(Input/ -	  Output Hub), ML7213 and ML7223. -	  ML7213 IOH is for IVI(In-Vehicle Infotainment) use and ML7223 IOH is -	  for MP(Media Phone) use. -	  ML7213/ML7223 is companion chip for Intel Atom E6xx series. -	  ML7213/ML7223 is completely compatible for Intel EG20T PCH. +	  This driver also can be used for LAPIS Semiconductor IOH(Input/ +	  Output Hub), ML7213, ML7223 and ML7831. +	  ML7213 IOH is for IVI(In-Vehicle Infotainment) use, ML7223 IOH is +	  for MP(Media Phone) use and ML7831 IOH is for general purpose use. +	  ML7213/ML7223/ML7831 is companion chip for Intel Atom E6xx series. +	  ML7213/ML7223/ML7831 is completely compatible for Intel EG20T PCH.  config SERIAL_MSM_SMD  	bool "Enable tty device interface for some SMD ports" diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c index 4a0f86fa1e9..4c823f341d9 100644 --- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c @@ -228,7 +228,7 @@ void atmel_config_rs485(struct uart_port *port, struct serial_rs485 *rs485conf)  	if (rs485conf->flags & SER_RS485_ENABLED) {  		dev_dbg(port->dev, "Setting UART to RS485\n");  		atmel_port->tx_done_mask = ATMEL_US_TXEMPTY; -		if (rs485conf->flags & SER_RS485_RTS_AFTER_SEND) +		if ((rs485conf->delay_rts_after_send) > 0)  			UART_PUT_TTGR(port, rs485conf->delay_rts_after_send);  		mode |= ATMEL_US_USMODE_RS485;  	} else { @@ -304,7 +304,7 @@ static void atmel_set_mctrl(struct uart_port *port, u_int mctrl)  	if (atmel_port->rs485.flags & SER_RS485_ENABLED) {  		dev_dbg(port->dev, "Setting UART to RS485\n"); -		if (atmel_port->rs485.flags & SER_RS485_RTS_AFTER_SEND) +		if ((atmel_port->rs485.delay_rts_after_send) > 0)  			UART_PUT_TTGR(port,  					atmel_port->rs485.delay_rts_after_send);  		mode |= ATMEL_US_USMODE_RS485; @@ -1228,7 +1228,7 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios *termios,  	if (atmel_port->rs485.flags & SER_RS485_ENABLED) {  		dev_dbg(port->dev, "Setting UART to RS485\n"); -		if (atmel_port->rs485.flags & SER_RS485_RTS_AFTER_SEND) +		if ((atmel_port->rs485.delay_rts_after_send) > 0)  			UART_PUT_TTGR(port,  					atmel_port->rs485.delay_rts_after_send);  		mode |= ATMEL_US_USMODE_RS485; @@ -1447,16 +1447,6 @@ static void __devinit atmel_of_init_port(struct atmel_uart_port *atmel_port,  		rs485conf->delay_rts_after_send = rs485_delay[1];  		rs485conf->flags = 0; -		if (rs485conf->delay_rts_before_send == 0 && -		    rs485conf->delay_rts_after_send == 0) { -			rs485conf->flags |= SER_RS485_RTS_ON_SEND; -		} else { -			if (rs485conf->delay_rts_before_send) -				rs485conf->flags |= SER_RS485_RTS_BEFORE_SEND; -			if (rs485conf->delay_rts_after_send) -				rs485conf->flags |= SER_RS485_RTS_AFTER_SEND; -		} -  		if (of_get_property(np, "rs485-rx-during-tx", NULL))  			rs485conf->flags |= SER_RS485_RX_DURING_TX; diff --git a/drivers/tty/serial/crisv10.c b/drivers/tty/serial/crisv10.c index b7435043f2f..1dfba7b779c 100644 --- a/drivers/tty/serial/crisv10.c +++ b/drivers/tty/serial/crisv10.c @@ -3234,9 +3234,8 @@ rs_write(struct tty_struct *tty,  		e100_disable_rx(info);  		e100_enable_rx_irq(info);  #endif -		if ((info->rs485.flags & SER_RS485_RTS_BEFORE_SEND) && -			(info->rs485.delay_rts_before_send > 0)) -				msleep(info->rs485.delay_rts_before_send); +		if (info->rs485.delay_rts_before_send > 0) +			msleep(info->rs485.delay_rts_before_send);  	}  #endif /* CONFIG_ETRAX_RS485 */ @@ -3693,10 +3692,6 @@ rs_ioctl(struct tty_struct *tty,  		rs485data.delay_rts_before_send = rs485ctrl.delay_rts_before_send;  		rs485data.flags = 0; -		if (rs485data.delay_rts_before_send != 0) -			rs485data.flags |= SER_RS485_RTS_BEFORE_SEND; -		else -			rs485data.flags &= ~(SER_RS485_RTS_BEFORE_SEND);  		if (rs485ctrl.enabled)  			rs485data.flags |= SER_RS485_ENABLED; @@ -4531,7 +4526,6 @@ static int __init rs_init(void)  		/* Set sane defaults */  		info->rs485.flags &= ~(SER_RS485_RTS_ON_SEND);  		info->rs485.flags |= SER_RS485_RTS_AFTER_SEND; -		info->rs485.flags &= ~(SER_RS485_RTS_BEFORE_SEND);  		info->rs485.delay_rts_before_send = 0;  		info->rs485.flags &= ~(SER_RS485_ENABLED);  #endif diff --git a/drivers/tty/serial/mfd.c b/drivers/tty/serial/mfd.c index 286c386d9c4..e272d3919c6 100644 --- a/drivers/tty/serial/mfd.c +++ b/drivers/tty/serial/mfd.c @@ -884,7 +884,6 @@ serial_hsu_set_termios(struct uart_port *port, struct ktermios *termios,  {  	struct uart_hsu_port *up =  			container_of(port, struct uart_hsu_port, port); -	struct tty_struct *tty = port->state->port.tty;  	unsigned char cval, fcr = 0;  	unsigned long flags;  	unsigned int baud, quot; @@ -907,8 +906,7 @@ serial_hsu_set_termios(struct uart_port *port, struct ktermios *termios,  	}  	/* CMSPAR isn't supported by this driver */ -	if (tty) -		tty->termios->c_cflag &= ~CMSPAR; +	termios->c_cflag &= ~CMSPAR;  	if (termios->c_cflag & CSTOPB)  		cval |= UART_LCR_STOP; diff --git a/drivers/tty/serial/pch_uart.c b/drivers/tty/serial/pch_uart.c index 21febef926a..d6aba8c087e 100644 --- a/drivers/tty/serial/pch_uart.c +++ b/drivers/tty/serial/pch_uart.c @@ -1,5 +1,5 @@  /* - *Copyright (C) 2010 OKI SEMICONDUCTOR CO., LTD. + *Copyright (C) 2011 LAPIS Semiconductor Co., Ltd.   *   *This program is free software; you can redistribute it and/or modify   *it under the terms of the GNU General Public License as published by @@ -46,8 +46,8 @@ enum {  /* Set the max number of UART port   * Intel EG20T PCH: 4 port - * OKI SEMICONDUCTOR ML7213 IOH: 3 port - * OKI SEMICONDUCTOR ML7223 IOH: 2 port + * LAPIS Semiconductor ML7213 IOH: 3 port + * LAPIS Semiconductor ML7223 IOH: 2 port  */  #define PCH_UART_NR	4 @@ -258,6 +258,8 @@ enum pch_uart_num_t {  	pch_ml7213_uart2,  	pch_ml7223_uart0,  	pch_ml7223_uart1, +	pch_ml7831_uart0, +	pch_ml7831_uart1,  };  static struct pch_uart_driver_data drv_dat[] = { @@ -270,6 +272,8 @@ static struct pch_uart_driver_data drv_dat[] = {  	[pch_ml7213_uart2] = {PCH_UART_2LINE, 2},  	[pch_ml7223_uart0] = {PCH_UART_8LINE, 0},  	[pch_ml7223_uart1] = {PCH_UART_2LINE, 1}, +	[pch_ml7831_uart0] = {PCH_UART_8LINE, 0}, +	[pch_ml7831_uart1] = {PCH_UART_2LINE, 1},  };  static unsigned int default_baud = 9600; @@ -628,6 +632,7 @@ static void pch_request_dma(struct uart_port *port)  		dev_err(priv->port.dev, "%s:dma_request_channel FAILS(Rx)\n",  			__func__);  		dma_release_channel(priv->chan_tx); +		priv->chan_tx = NULL;  		return;  	} @@ -1215,8 +1220,7 @@ static void pch_uart_shutdown(struct uart_port *port)  		dev_err(priv->port.dev,  			"pch_uart_hal_set_fifo Failed(ret=%d)\n", ret); -	if (priv->use_dma_flag) -		pch_free_dma(port); +	pch_free_dma(port);  	free_irq(priv->port.irq, priv);  } @@ -1280,6 +1284,7 @@ static void pch_uart_set_termios(struct uart_port *port,  	if (rtn)  		goto out; +	pch_uart_set_mctrl(&priv->port, priv->port.mctrl);  	/* Don't rewrite B0 */  	if (tty_termios_baud_rate(termios))  		tty_termios_encode_baud_rate(termios, baud, baud); @@ -1552,6 +1557,10 @@ static DEFINE_PCI_DEVICE_TABLE(pch_uart_pci_id) = {  	 .driver_data = pch_ml7223_uart0},  	{PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x800D),  	 .driver_data = pch_ml7223_uart1}, +	{PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x8811), +	 .driver_data = pch_ml7831_uart0}, +	{PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x8812), +	 .driver_data = pch_ml7831_uart1},  	{0,},  }; diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 1945c70539c..aff9d612dff 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -207,6 +207,25 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = {  	},  	/* +	 * Common SH-2(A) SCIF definitions for ports with FIFO data +	 * count registers. +	 */ +	[SCIx_SH2_SCIF_FIFODATA_REGTYPE] = { +		[SCSMR]		= { 0x00, 16 }, +		[SCBRR]		= { 0x04,  8 }, +		[SCSCR]		= { 0x08, 16 }, +		[SCxTDR]	= { 0x0c,  8 }, +		[SCxSR]		= { 0x10, 16 }, +		[SCxRDR]	= { 0x14,  8 }, +		[SCFCR]		= { 0x18, 16 }, +		[SCFDR]		= { 0x1c, 16 }, +		[SCTFDR]	= sci_reg_invalid, +		[SCRFDR]	= sci_reg_invalid, +		[SCSPTR]	= { 0x20, 16 }, +		[SCLSR]		= { 0x24, 16 }, +	}, + +	/*  	 * Common SH-3 SCIF definitions.  	 */  	[SCIx_SH3_SCIF_REGTYPE] = { diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c index 512c49f98e8..8e0924f5544 100644 --- a/drivers/tty/tty_ldisc.c +++ b/drivers/tty/tty_ldisc.c @@ -36,6 +36,7 @@  #include <linux/kmod.h>  #include <linux/nsproxy.h> +#include <linux/ratelimit.h>  /*   *	This guards the refcounted line discipline lists. The lock @@ -547,15 +548,16 @@ static void tty_ldisc_flush_works(struct tty_struct *tty)  /**   *	tty_ldisc_wait_idle	-	wait for the ldisc to become idle   *	@tty: tty to wait for + *	@timeout: for how long to wait at most   *   *	Wait for the line discipline to become idle. The discipline must   *	have been halted for this to guarantee it remains idle.   */ -static int tty_ldisc_wait_idle(struct tty_struct *tty) +static int tty_ldisc_wait_idle(struct tty_struct *tty, long timeout)  { -	int ret; +	long ret;  	ret = wait_event_timeout(tty_ldisc_idle, -			atomic_read(&tty->ldisc->users) == 1, 5 * HZ); +			atomic_read(&tty->ldisc->users) == 1, timeout);  	if (ret < 0)  		return ret;  	return ret > 0 ? 0 : -EBUSY; @@ -665,7 +667,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc)  	tty_ldisc_flush_works(tty); -	retval = tty_ldisc_wait_idle(tty); +	retval = tty_ldisc_wait_idle(tty, 5 * HZ);  	tty_lock();  	mutex_lock(&tty->ldisc_mutex); @@ -762,8 +764,6 @@ static int tty_ldisc_reinit(struct tty_struct *tty, int ldisc)  	if (IS_ERR(ld))  		return -1; -	WARN_ON_ONCE(tty_ldisc_wait_idle(tty)); -  	tty_ldisc_close(tty, tty->ldisc);  	tty_ldisc_put(tty->ldisc);  	tty->ldisc = NULL; @@ -838,7 +838,7 @@ void tty_ldisc_hangup(struct tty_struct *tty)  	tty_unlock();  	cancel_work_sync(&tty->buf.work);  	mutex_unlock(&tty->ldisc_mutex); - +retry:  	tty_lock();  	mutex_lock(&tty->ldisc_mutex); @@ -847,6 +847,22 @@ void tty_ldisc_hangup(struct tty_struct *tty)  	   it means auditing a lot of other paths so this is  	   a FIXME */  	if (tty->ldisc) {	/* Not yet closed */ +		if (atomic_read(&tty->ldisc->users) != 1) { +			char cur_n[TASK_COMM_LEN], tty_n[64]; +			long timeout = 3 * HZ; +			tty_unlock(); + +			while (tty_ldisc_wait_idle(tty, timeout) == -EBUSY) { +				timeout = MAX_SCHEDULE_TIMEOUT; +				printk_ratelimited(KERN_WARNING +					"%s: waiting (%s) for %s took too long, but we keep waiting...\n", +					__func__, get_task_comm(cur_n, current), +					tty_name(tty, tty_n)); +			} +			mutex_unlock(&tty->ldisc_mutex); +			goto retry; +		} +  		if (reset == 0) {  			if (!tty_ldisc_reinit(tty, tty->termios->c_line)) diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 6960715c506..e8c564a5334 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -539,7 +539,6 @@ static void acm_port_down(struct acm *acm)  {  	int i; -	mutex_lock(&open_mutex);  	if (acm->dev) {  		usb_autopm_get_interface(acm->control);  		acm_set_control(acm, acm->ctrlout = 0); @@ -551,14 +550,15 @@ static void acm_port_down(struct acm *acm)  		acm->control->needs_remote_wakeup = 0;  		usb_autopm_put_interface(acm->control);  	} -	mutex_unlock(&open_mutex);  }  static void acm_tty_hangup(struct tty_struct *tty)  {  	struct acm *acm = tty->driver_data;  	tty_port_hangup(&acm->port); +	mutex_lock(&open_mutex);  	acm_port_down(acm); +	mutex_unlock(&open_mutex);  }  static void acm_tty_close(struct tty_struct *tty, struct file *filp) @@ -569,8 +569,9 @@ static void acm_tty_close(struct tty_struct *tty, struct file *filp)  	   shutdown */  	if (!acm)  		return; + +	mutex_lock(&open_mutex);  	if (tty_port_close_start(&acm->port, tty, filp) == 0) { -		mutex_lock(&open_mutex);  		if (!acm->dev) {  			tty_port_tty_set(&acm->port, NULL);  			acm_tty_unregister(acm); @@ -582,6 +583,7 @@ static void acm_tty_close(struct tty_struct *tty, struct file *filp)  	acm_port_down(acm);  	tty_port_close_end(&acm->port, tty);  	tty_port_tty_set(&acm->port, NULL); +	mutex_unlock(&open_mutex);  }  static int acm_tty_write(struct tty_struct *tty, diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 96f05b29c9a..79781461eec 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -813,6 +813,12 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)  					USB_PORT_FEAT_C_PORT_LINK_STATE);  		} +		if ((portchange & USB_PORT_STAT_C_BH_RESET) && +				hub_is_superspeed(hub->hdev)) { +			need_debounce_delay = true; +			clear_port_feature(hub->hdev, port1, +					USB_PORT_FEAT_C_BH_PORT_RESET); +		}  		/* We can forget about a "removed" device when there's a  		 * physical disconnect or the connect status changes.  		 */ diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index d6a8d8269bf..ecf12e15a7e 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c @@ -50,15 +50,42 @@ static const struct usb_device_id usb_quirk_list[] = {  	/* Logitech Webcam B/C500 */  	{ USB_DEVICE(0x046d, 0x0807), .driver_info = USB_QUIRK_RESET_RESUME }, +	/* Logitech Webcam C600 */ +	{ USB_DEVICE(0x046d, 0x0808), .driver_info = USB_QUIRK_RESET_RESUME }, +  	/* Logitech Webcam Pro 9000 */  	{ USB_DEVICE(0x046d, 0x0809), .driver_info = USB_QUIRK_RESET_RESUME }, +	/* Logitech Webcam C905 */ +	{ USB_DEVICE(0x046d, 0x080a), .driver_info = USB_QUIRK_RESET_RESUME }, + +	/* Logitech Webcam C210 */ +	{ USB_DEVICE(0x046d, 0x0819), .driver_info = USB_QUIRK_RESET_RESUME }, + +	/* Logitech Webcam C260 */ +	{ USB_DEVICE(0x046d, 0x081a), .driver_info = USB_QUIRK_RESET_RESUME }, +  	/* Logitech Webcam C310 */  	{ USB_DEVICE(0x046d, 0x081b), .driver_info = USB_QUIRK_RESET_RESUME }, +	/* Logitech Webcam C910 */ +	{ USB_DEVICE(0x046d, 0x0821), .driver_info = USB_QUIRK_RESET_RESUME }, + +	/* Logitech Webcam C160 */ +	{ USB_DEVICE(0x046d, 0x0824), .driver_info = USB_QUIRK_RESET_RESUME }, +  	/* Logitech Webcam C270 */  	{ USB_DEVICE(0x046d, 0x0825), .driver_info = USB_QUIRK_RESET_RESUME }, +	/* Logitech Quickcam Pro 9000 */ +	{ USB_DEVICE(0x046d, 0x0990), .driver_info = USB_QUIRK_RESET_RESUME }, + +	/* Logitech Quickcam E3500 */ +	{ USB_DEVICE(0x046d, 0x09a4), .driver_info = USB_QUIRK_RESET_RESUME }, + +	/* Logitech Quickcam Vision Pro */ +	{ USB_DEVICE(0x046d, 0x09a6), .driver_info = USB_QUIRK_RESET_RESUME }, +  	/* Logitech Harmony 700-series */  	{ USB_DEVICE(0x046d, 0xc122), .driver_info = USB_QUIRK_DELAY_INIT }, diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index fa824cfdd2e..25dbd8614e7 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1284,6 +1284,7 @@ static int __devinit dwc3_gadget_init_endpoints(struct dwc3 *dwc)  			int		ret;  			dep->endpoint.maxpacket = 1024; +			dep->endpoint.max_streams = 15;  			dep->endpoint.ops = &dwc3_gadget_ep_ops;  			list_add_tail(&dep->endpoint.ep_list,  					&dwc->gadget.ep_list); diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index a11dbc85d08..3162a7da872 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -470,7 +470,7 @@ config USB_LANGWELL  	   gadget drivers to also be dynamically linked.  config USB_EG20T -	tristate "Intel EG20T PCH/OKI SEMICONDUCTOR ML7213 IOH UDC" +	tristate "Intel EG20T PCH/LAPIS Semiconductor IOH(ML7213/ML7831) UDC"  	depends on PCI  	select USB_GADGET_DUALSPEED  	help @@ -486,10 +486,11 @@ config USB_EG20T  	  This driver dose not support interrupt transfer or isochronous  	  transfer modes. -	  This driver also can be used for OKI SEMICONDUCTOR's ML7213 which is +	  This driver also can be used for LAPIS Semiconductor's ML7213 which is  	  for IVI(In-Vehicle Infotainment) use. -	  ML7213 is companion chip for Intel Atom E6xx series. -	  ML7213 is completely compatible for Intel EG20T PCH. +	  ML7831 is for general purpose use. +	  ML7213/ML7831 is companion chip for Intel Atom E6xx series. +	  ML7213/ML7831 is completely compatible for Intel EG20T PCH.  config USB_CI13XXX_MSM  	tristate "MIPS USB CI13xxx for MSM" diff --git a/drivers/usb/gadget/ci13xxx_msm.c b/drivers/usb/gadget/ci13xxx_msm.c index 4eedfe55715..1fc612914c5 100644 --- a/drivers/usb/gadget/ci13xxx_msm.c +++ b/drivers/usb/gadget/ci13xxx_msm.c @@ -122,3 +122,5 @@ static int __init ci13xxx_msm_init(void)  	return platform_driver_register(&ci13xxx_msm_driver);  }  module_init(ci13xxx_msm_init); + +MODULE_LICENSE("GPL v2"); diff --git a/drivers/usb/gadget/ci13xxx_udc.c b/drivers/usb/gadget/ci13xxx_udc.c index 83428f56253..9a0c3979ff4 100644 --- a/drivers/usb/gadget/ci13xxx_udc.c +++ b/drivers/usb/gadget/ci13xxx_udc.c @@ -71,6 +71,9 @@  /******************************************************************************   * DEFINE   *****************************************************************************/ + +#define DMA_ADDR_INVALID	(~(dma_addr_t)0) +  /* ctrl register bank access */  static DEFINE_SPINLOCK(udc_lock); @@ -1434,7 +1437,7 @@ static int _hardware_enqueue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq)  		return -EALREADY;  	mReq->req.status = -EALREADY; -	if (length && !mReq->req.dma) { +	if (length && mReq->req.dma == DMA_ADDR_INVALID) {  		mReq->req.dma = \  			dma_map_single(mEp->device, mReq->req.buf,  				       length, mEp->dir ? DMA_TO_DEVICE : @@ -1453,7 +1456,7 @@ static int _hardware_enqueue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq)  				dma_unmap_single(mEp->device, mReq->req.dma,  					length, mEp->dir ? DMA_TO_DEVICE :  					DMA_FROM_DEVICE); -				mReq->req.dma = 0; +				mReq->req.dma = DMA_ADDR_INVALID;  				mReq->map     = 0;  			}  			return -ENOMEM; @@ -1549,7 +1552,7 @@ static int _hardware_dequeue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq)  	if (mReq->map) {  		dma_unmap_single(mEp->device, mReq->req.dma, mReq->req.length,  				 mEp->dir ? DMA_TO_DEVICE : DMA_FROM_DEVICE); -		mReq->req.dma = 0; +		mReq->req.dma = DMA_ADDR_INVALID;  		mReq->map     = 0;  	} @@ -1610,7 +1613,6 @@ __acquires(mEp->lock)   * @gadget: gadget   *   * This function returns an error code - * Caller must hold lock   */  static int _gadget_stop_activity(struct usb_gadget *gadget)  { @@ -2189,6 +2191,7 @@ static struct usb_request *ep_alloc_request(struct usb_ep *ep, gfp_t gfp_flags)  	mReq = kzalloc(sizeof(struct ci13xxx_req), gfp_flags);  	if (mReq != NULL) {  		INIT_LIST_HEAD(&mReq->queue); +		mReq->req.dma = DMA_ADDR_INVALID;  		mReq->ptr = dma_pool_alloc(mEp->td_pool, gfp_flags,  					   &mReq->dma); @@ -2328,7 +2331,7 @@ static int ep_dequeue(struct usb_ep *ep, struct usb_request *req)  	if (mReq->map) {  		dma_unmap_single(mEp->device, mReq->req.dma, mReq->req.length,  				 mEp->dir ? DMA_TO_DEVICE : DMA_FROM_DEVICE); -		mReq->req.dma = 0; +		mReq->req.dma = DMA_ADDR_INVALID;  		mReq->map     = 0;  	}  	req->status = -ECONNRESET; @@ -2500,12 +2503,12 @@ static int ci13xxx_wakeup(struct usb_gadget *_gadget)  	spin_lock_irqsave(udc->lock, flags);  	if (!udc->remote_wakeup) {  		ret = -EOPNOTSUPP; -		dbg_trace("remote wakeup feature is not enabled\n"); +		trace("remote wakeup feature is not enabled\n");  		goto out;  	}  	if (!hw_cread(CAP_PORTSC, PORTSC_SUSP)) {  		ret = -EINVAL; -		dbg_trace("port is not suspended\n"); +		trace("port is not suspended\n");  		goto out;  	}  	hw_cwrite(CAP_PORTSC, PORTSC_FPR, PORTSC_FPR); @@ -2703,7 +2706,9 @@ static int ci13xxx_stop(struct usb_gadget_driver *driver)  		if (udc->udc_driver->notify_event)  			udc->udc_driver->notify_event(udc,  			CI13XXX_CONTROLLER_STOPPED_EVENT); +		spin_unlock_irqrestore(udc->lock, flags);  		_gadget_stop_activity(&udc->gadget); +		spin_lock_irqsave(udc->lock, flags);  		pm_runtime_put(&udc->gadget.dev);  	} @@ -2850,7 +2855,7 @@ static int udc_probe(struct ci13xxx_udc_driver *driver, struct device *dev,  	struct ci13xxx *udc;  	int retval = 0; -	trace("%p, %p, %p", dev, regs, name); +	trace("%p, %p, %p", dev, regs, driver->name);  	if (dev == NULL || regs == NULL || driver == NULL ||  			driver->name == NULL) diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index 52583a23533..c39d58860fa 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c @@ -624,7 +624,8 @@ static int fsg_setup(struct usb_function *f,  		if (ctrl->bRequestType !=  		    (USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE))  			break; -		if (w_index != fsg->interface_number || w_value != 0) +		if (w_index != fsg->interface_number || w_value != 0 || +				w_length != 0)  			return -EDOM;  		/* @@ -639,7 +640,8 @@ static int fsg_setup(struct usb_function *f,  		if (ctrl->bRequestType !=  		    (USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE))  			break; -		if (w_index != fsg->interface_number || w_value != 0) +		if (w_index != fsg->interface_number || w_value != 0 || +				w_length != 1)  			return -EDOM;  		VDBG(fsg, "get max LUN\n");  		*(u8 *)req->buf = fsg->common->nluns - 1; diff --git a/drivers/usb/gadget/f_midi.c b/drivers/usb/gadget/f_midi.c index 67b222908cf..3797b3d6c62 100644 --- a/drivers/usb/gadget/f_midi.c +++ b/drivers/usb/gadget/f_midi.c @@ -95,7 +95,6 @@ static void f_midi_transmit(struct f_midi *midi, struct usb_request *req);  DECLARE_UAC_AC_HEADER_DESCRIPTOR(1);  DECLARE_USB_MIDI_OUT_JACK_DESCRIPTOR(1); -DECLARE_USB_MIDI_OUT_JACK_DESCRIPTOR(16);  DECLARE_USB_MS_ENDPOINT_DESCRIPTOR(16);  /* B.3.1  Standard AC Interface Descriptor */ @@ -140,26 +139,6 @@ static struct usb_ms_header_descriptor ms_header_desc __initdata = {  	/* .wTotalLength =	DYNAMIC */  }; -/* B.4.3  Embedded MIDI IN Jack Descriptor */ -static struct usb_midi_in_jack_descriptor jack_in_emb_desc = { -	.bLength =	      USB_DT_MIDI_IN_SIZE, -	.bDescriptorType =      USB_DT_CS_INTERFACE, -	.bDescriptorSubtype =   USB_MS_MIDI_IN_JACK, -	.bJackType =	    USB_MS_EMBEDDED, -	/* .bJackID =		DYNAMIC */ -}; - -/* B.4.4  Embedded MIDI OUT Jack Descriptor */ -static struct usb_midi_out_jack_descriptor_16 jack_out_emb_desc = { -	/* .bLength =		DYNAMIC */ -	.bDescriptorType =	USB_DT_CS_INTERFACE, -	.bDescriptorSubtype =	USB_MS_MIDI_OUT_JACK, -	.bJackType =		USB_MS_EMBEDDED, -	/* .bJackID =		DYNAMIC */ -	/* .bNrInputPins =	DYNAMIC */ -	/* .pins =		DYNAMIC */ -}; -  /* B.5.1  Standard Bulk OUT Endpoint Descriptor */  static struct usb_endpoint_descriptor bulk_out_desc = {  	.bLength =		USB_DT_ENDPOINT_AUDIO_SIZE, @@ -758,9 +737,11 @@ fail:  static int __init  f_midi_bind(struct usb_configuration *c, struct usb_function *f)  { -	struct usb_descriptor_header *midi_function[(MAX_PORTS * 2) + 12]; +	struct usb_descriptor_header **midi_function;  	struct usb_midi_in_jack_descriptor jack_in_ext_desc[MAX_PORTS]; +	struct usb_midi_in_jack_descriptor jack_in_emb_desc[MAX_PORTS];  	struct usb_midi_out_jack_descriptor_1 jack_out_ext_desc[MAX_PORTS]; +	struct usb_midi_out_jack_descriptor_1 jack_out_emb_desc[MAX_PORTS];  	struct usb_composite_dev *cdev = c->cdev;  	struct f_midi *midi = func_to_midi(f);  	int status, n, jack = 1, i = 0; @@ -798,6 +779,14 @@ f_midi_bind(struct usb_configuration *c, struct usb_function *f)  		goto fail;  	midi->out_ep->driver_data = cdev;	/* claim */ +	/* allocate temporary function list */ +	midi_function = kcalloc((MAX_PORTS * 4) + 9, sizeof(midi_function), +				GFP_KERNEL); +	if (!midi_function) { +		status = -ENOMEM; +		goto fail; +	} +  	/*  	 * construct the function's descriptor set. As the number of  	 * input and output MIDI ports is configurable, we have to do @@ -811,73 +800,74 @@ f_midi_bind(struct usb_configuration *c, struct usb_function *f)  	/* calculate the header's wTotalLength */  	n = USB_DT_MS_HEADER_SIZE -		+ (1 + midi->in_ports) * USB_DT_MIDI_IN_SIZE -		+ (1 + midi->out_ports) * USB_DT_MIDI_OUT_SIZE(1); +		+ (midi->in_ports + midi->out_ports) * +			(USB_DT_MIDI_IN_SIZE + USB_DT_MIDI_OUT_SIZE(1));  	ms_header_desc.wTotalLength = cpu_to_le16(n);  	midi_function[i++] = (struct usb_descriptor_header *) &ms_header_desc; -	/* we have one embedded IN jack */ -	jack_in_emb_desc.bJackID = jack++; -	midi_function[i++] = (struct usb_descriptor_header *) &jack_in_emb_desc; - -	/* and a dynamic amount of external IN jacks */ +	/* configure the external IN jacks, each linked to an embedded OUT jack */  	for (n = 0; n < midi->in_ports; n++) { -		struct usb_midi_in_jack_descriptor *ext = &jack_in_ext_desc[n]; +		struct usb_midi_in_jack_descriptor *in_ext = &jack_in_ext_desc[n]; +		struct usb_midi_out_jack_descriptor_1 *out_emb = &jack_out_emb_desc[n]; -		ext->bLength =			USB_DT_MIDI_IN_SIZE; -		ext->bDescriptorType =		USB_DT_CS_INTERFACE; -		ext->bDescriptorSubtype =	USB_MS_MIDI_IN_JACK; -		ext->bJackType =		USB_MS_EXTERNAL; -		ext->bJackID =			jack++; -		ext->iJack =			0; +		in_ext->bLength			= USB_DT_MIDI_IN_SIZE; +		in_ext->bDescriptorType		= USB_DT_CS_INTERFACE; +		in_ext->bDescriptorSubtype	= USB_MS_MIDI_IN_JACK; +		in_ext->bJackType		= USB_MS_EXTERNAL; +		in_ext->bJackID			= jack++; +		in_ext->iJack			= 0; +		midi_function[i++] = (struct usb_descriptor_header *) in_ext; -		midi_function[i++] = (struct usb_descriptor_header *) ext; -	} +		out_emb->bLength		= USB_DT_MIDI_OUT_SIZE(1); +		out_emb->bDescriptorType	= USB_DT_CS_INTERFACE; +		out_emb->bDescriptorSubtype	= USB_MS_MIDI_OUT_JACK; +		out_emb->bJackType		= USB_MS_EMBEDDED; +		out_emb->bJackID		= jack++; +		out_emb->bNrInputPins		= 1; +		out_emb->pins[0].baSourcePin	= 1; +		out_emb->pins[0].baSourceID	= in_ext->bJackID; +		out_emb->iJack			= 0; +		midi_function[i++] = (struct usb_descriptor_header *) out_emb; -	/* one embedded OUT jack ... */ -	jack_out_emb_desc.bLength = USB_DT_MIDI_OUT_SIZE(midi->in_ports); -	jack_out_emb_desc.bJackID = jack++; -	jack_out_emb_desc.bNrInputPins = midi->in_ports; -	/* ... which referencess all external IN jacks */ -	for (n = 0; n < midi->in_ports; n++) { -		jack_out_emb_desc.pins[n].baSourceID = jack_in_ext_desc[n].bJackID; -		jack_out_emb_desc.pins[n].baSourcePin =	1; +		/* link it to the endpoint */ +		ms_in_desc.baAssocJackID[n] = out_emb->bJackID;  	} -	midi_function[i++] = (struct usb_descriptor_header *) &jack_out_emb_desc; - -	/* and multiple external OUT jacks ... */ +	/* configure the external OUT jacks, each linked to an embedded IN jack */  	for (n = 0; n < midi->out_ports; n++) { -		struct usb_midi_out_jack_descriptor_1 *ext = &jack_out_ext_desc[n]; -		int m; +		struct usb_midi_in_jack_descriptor *in_emb = &jack_in_emb_desc[n]; +		struct usb_midi_out_jack_descriptor_1 *out_ext = &jack_out_ext_desc[n]; -		ext->bLength =			USB_DT_MIDI_OUT_SIZE(1); -		ext->bDescriptorType =		USB_DT_CS_INTERFACE; -		ext->bDescriptorSubtype =	USB_MS_MIDI_OUT_JACK; -		ext->bJackType =		USB_MS_EXTERNAL; -		ext->bJackID =			jack++; -		ext->bNrInputPins =		1; -		ext->iJack =			0; -		/* ... which all reference the same embedded IN jack */ -		for (m = 0; m < midi->out_ports; m++) { -			ext->pins[m].baSourceID =	jack_in_emb_desc.bJackID; -			ext->pins[m].baSourcePin =	1; -		} +		in_emb->bLength			= USB_DT_MIDI_IN_SIZE; +		in_emb->bDescriptorType		= USB_DT_CS_INTERFACE; +		in_emb->bDescriptorSubtype	= USB_MS_MIDI_IN_JACK; +		in_emb->bJackType		= USB_MS_EMBEDDED; +		in_emb->bJackID			= jack++; +		in_emb->iJack			= 0; +		midi_function[i++] = (struct usb_descriptor_header *) in_emb; -		midi_function[i++] = (struct usb_descriptor_header *) ext; +		out_ext->bLength =		USB_DT_MIDI_OUT_SIZE(1); +		out_ext->bDescriptorType =	USB_DT_CS_INTERFACE; +		out_ext->bDescriptorSubtype =	USB_MS_MIDI_OUT_JACK; +		out_ext->bJackType =		USB_MS_EXTERNAL; +		out_ext->bJackID =		jack++; +		out_ext->bNrInputPins =		1; +		out_ext->iJack =		0; +		out_ext->pins[0].baSourceID =	in_emb->bJackID; +		out_ext->pins[0].baSourcePin =	1; +		midi_function[i++] = (struct usb_descriptor_header *) out_ext; + +		/* link it to the endpoint */ +		ms_out_desc.baAssocJackID[n] = in_emb->bJackID;  	}  	/* configure the endpoint descriptors ... */  	ms_out_desc.bLength = USB_DT_MS_ENDPOINT_SIZE(midi->in_ports);  	ms_out_desc.bNumEmbMIDIJack = midi->in_ports; -	for (n = 0; n < midi->in_ports; n++) -		ms_out_desc.baAssocJackID[n] = jack_in_emb_desc.bJackID;  	ms_in_desc.bLength = USB_DT_MS_ENDPOINT_SIZE(midi->out_ports);  	ms_in_desc.bNumEmbMIDIJack = midi->out_ports; -	for (n = 0; n < midi->out_ports; n++) -		ms_in_desc.baAssocJackID[n] = jack_out_emb_desc.bJackID;  	/* ... and add them to the list */  	midi_function[i++] = (struct usb_descriptor_header *) &bulk_out_desc; @@ -901,6 +891,8 @@ f_midi_bind(struct usb_configuration *c, struct usb_function *f)  		f->descriptors = usb_copy_descriptors(midi_function);  	} +	kfree(midi_function); +  	return 0;  fail: diff --git a/drivers/usb/gadget/f_phonet.c b/drivers/usb/gadget/f_phonet.c index 34907703333..16a509ae517 100644 --- a/drivers/usb/gadget/f_phonet.c +++ b/drivers/usb/gadget/f_phonet.c @@ -346,7 +346,7 @@ static void pn_rx_complete(struct usb_ep *ep, struct usb_request *req)  		}  		skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page, -				skb->len == 0, req->actual); +				skb->len <= 1, req->actual);  		page = NULL;  		if (req->actual < req->length) { /* Last fragment */ diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c index f7e39b0365c..11b5196284a 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c @@ -859,7 +859,7 @@ static int class_setup_req(struct fsg_dev *fsg,  			if (ctrl->bRequestType != (USB_DIR_OUT |  					USB_TYPE_CLASS | USB_RECIP_INTERFACE))  				break; -			if (w_index != 0 || w_value != 0) { +			if (w_index != 0 || w_value != 0 || w_length != 0) {  				value = -EDOM;  				break;  			} @@ -875,7 +875,7 @@ static int class_setup_req(struct fsg_dev *fsg,  			if (ctrl->bRequestType != (USB_DIR_IN |  					USB_TYPE_CLASS | USB_RECIP_INTERFACE))  				break; -			if (w_index != 0 || w_value != 0) { +			if (w_index != 0 || w_value != 0 || w_length != 1) {  				value = -EDOM;  				break;  			} diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c index b2c44e1d581..b3b3d83b7c3 100644 --- a/drivers/usb/gadget/fsl_udc_core.c +++ b/drivers/usb/gadget/fsl_udc_core.c @@ -1717,7 +1717,7 @@ static void dtd_complete_irq(struct fsl_udc *udc)  static inline enum usb_device_speed portscx_device_speed(u32 reg)  { -	switch (speed & PORTSCX_PORT_SPEED_MASK) { +	switch (reg & PORTSCX_PORT_SPEED_MASK) {  	case PORTSCX_PORT_SPEED_HIGH:  		return USB_SPEED_HIGH;  	case PORTSCX_PORT_SPEED_FULL: @@ -2480,8 +2480,7 @@ static int __init fsl_udc_probe(struct platform_device *pdev)  #ifndef CONFIG_ARCH_MXC  	if (pdata->have_sysif_regs) -		usb_sys_regs = (struct usb_sys_interface *) -				((u32)dr_regs + USB_DR_SYS_OFFSET); +		usb_sys_regs = (void *)dr_regs + USB_DR_SYS_OFFSET;  #endif  	/* Initialize USB clocks */ diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c index a392ec0d2d5..6ccae2707e5 100644 --- a/drivers/usb/gadget/inode.c +++ b/drivers/usb/gadget/inode.c @@ -1730,8 +1730,9 @@ static void  gadgetfs_disconnect (struct usb_gadget *gadget)  {  	struct dev_data		*dev = get_gadget_data (gadget); +	unsigned long		flags; -	spin_lock (&dev->lock); +	spin_lock_irqsave (&dev->lock, flags);  	if (dev->state == STATE_DEV_UNCONNECTED)  		goto exit;  	dev->state = STATE_DEV_UNCONNECTED; @@ -1740,7 +1741,7 @@ gadgetfs_disconnect (struct usb_gadget *gadget)  	next_event (dev, GADGETFS_DISCONNECT);  	ep0_readable (dev);  exit: -	spin_unlock (&dev->lock); +	spin_unlock_irqrestore (&dev->lock, flags);  }  static void diff --git a/drivers/usb/gadget/pch_udc.c b/drivers/usb/gadget/pch_udc.c index 550d6dcdf10..5048a0c0764 100644 --- a/drivers/usb/gadget/pch_udc.c +++ b/drivers/usb/gadget/pch_udc.c @@ -1,5 +1,5 @@  /* - * Copyright (C) 2010 OKI SEMICONDUCTOR CO., LTD. + * Copyright (C) 2011 LAPIS Semiconductor Co., Ltd.   *   * This program is free software; you can redistribute it and/or modify   * it under the terms of the GNU General Public License as published by @@ -354,6 +354,7 @@ struct pch_udc_dev {  #define PCI_DEVICE_ID_INTEL_EG20T_UDC	0x8808  #define PCI_VENDOR_ID_ROHM		0x10DB  #define PCI_DEVICE_ID_ML7213_IOH_UDC	0x801D +#define PCI_DEVICE_ID_ML7831_IOH_UDC	0x8808  static const char	ep0_string[] = "ep0in";  static DEFINE_SPINLOCK(udc_stall_spinlock);	/* stall spin lock */ @@ -2970,6 +2971,11 @@ static DEFINE_PCI_DEVICE_TABLE(pch_udc_pcidev_id) = {  		.class = (PCI_CLASS_SERIAL_USB << 8) | 0xfe,  		.class_mask = 0xffffffff,  	}, +	{ +		PCI_DEVICE(PCI_VENDOR_ID_ROHM, PCI_DEVICE_ID_ML7831_IOH_UDC), +		.class = (PCI_CLASS_SERIAL_USB << 8) | 0xfe, +		.class_mask = 0xffffffff, +	},  	{ 0 },  }; @@ -2999,5 +3005,5 @@ static void __exit pch_udc_pci_exit(void)  module_exit(pch_udc_pci_exit);  MODULE_DESCRIPTION("Intel EG20T USB Device Controller"); -MODULE_AUTHOR("OKI SEMICONDUCTOR, <toshiharu-linux@dsn.okisemi.com>"); +MODULE_AUTHOR("LAPIS Semiconductor, <tomoya-linux@dsn.lapis-semi.com>");  MODULE_LICENSE("GPL"); diff --git a/drivers/usb/gadget/r8a66597-udc.c b/drivers/usb/gadget/r8a66597-udc.c index 68a826a1b86..24f84b210ce 100644 --- a/drivers/usb/gadget/r8a66597-udc.c +++ b/drivers/usb/gadget/r8a66597-udc.c @@ -1718,6 +1718,8 @@ static void r8a66597_fifo_flush(struct usb_ep *_ep)  	if (list_empty(&ep->queue) && !ep->busy) {  		pipe_stop(ep->r8a66597, ep->pipenum);  		r8a66597_bclr(ep->r8a66597, BCLR, ep->fifoctr); +		r8a66597_write(ep->r8a66597, ACLRM, ep->pipectr); +		r8a66597_write(ep->r8a66597, 0, ep->pipectr);  	}  	spin_unlock_irqrestore(&ep->r8a66597->lock, flags);  } @@ -1742,7 +1744,6 @@ static int r8a66597_start(struct usb_gadget *gadget,  		struct usb_gadget_driver *driver)  {  	struct r8a66597 *r8a66597 = gadget_to_r8a66597(gadget); -	int retval;  	if (!driver  			|| driver->speed != USB_SPEED_HIGH @@ -1752,16 +1753,7 @@ static int r8a66597_start(struct usb_gadget *gadget,  		return -ENODEV;  	/* hook up the driver */ -	driver->driver.bus = NULL;  	r8a66597->driver = driver; -	r8a66597->gadget.dev.driver = &driver->driver; - -	retval = device_add(&r8a66597->gadget.dev); -	if (retval) { -		dev_err(r8a66597_to_dev(r8a66597), "device_add error (%d)\n", -			retval); -		goto error; -	}  	init_controller(r8a66597);  	r8a66597_bset(r8a66597, VBSE, INTENB0); @@ -1775,12 +1767,6 @@ static int r8a66597_start(struct usb_gadget *gadget,  	}  	return 0; - -error: -	r8a66597->driver = NULL; -	r8a66597->gadget.dev.driver = NULL; - -	return retval;  }  static int r8a66597_stop(struct usb_gadget *gadget, @@ -1794,7 +1780,6 @@ static int r8a66597_stop(struct usb_gadget *gadget,  	disable_controller(r8a66597);  	spin_unlock_irqrestore(&r8a66597->lock, flags); -	device_del(&r8a66597->gadget.dev);  	r8a66597->driver = NULL;  	return 0;  } @@ -1845,6 +1830,7 @@ static int __exit r8a66597_remove(struct platform_device *pdev)  		clk_put(r8a66597->clk);  	}  #endif +	device_unregister(&r8a66597->gadget.dev);  	kfree(r8a66597);  	return 0;  } @@ -1924,13 +1910,17 @@ static int __init r8a66597_probe(struct platform_device *pdev)  	r8a66597->irq_sense_low = irq_trigger == IRQF_TRIGGER_LOW;  	r8a66597->gadget.ops = &r8a66597_gadget_ops; -	device_initialize(&r8a66597->gadget.dev);  	dev_set_name(&r8a66597->gadget.dev, "gadget");  	r8a66597->gadget.is_dualspeed = 1;  	r8a66597->gadget.dev.parent = &pdev->dev;  	r8a66597->gadget.dev.dma_mask = pdev->dev.dma_mask;  	r8a66597->gadget.dev.release = pdev->dev.release;  	r8a66597->gadget.name = udc_name; +	ret = device_register(&r8a66597->gadget.dev); +	if (ret < 0) { +		dev_err(&pdev->dev, "device_register failed\n"); +		goto clean_up; +	}  	init_timer(&r8a66597->timer);  	r8a66597->timer.function = r8a66597_timer; @@ -1945,7 +1935,7 @@ static int __init r8a66597_probe(struct platform_device *pdev)  			dev_err(&pdev->dev, "cannot get clock \"%s\"\n",  				clk_name);  			ret = PTR_ERR(r8a66597->clk); -			goto clean_up; +			goto clean_up_dev;  		}  		clk_enable(r8a66597->clk);  	} @@ -2014,7 +2004,9 @@ clean_up2:  		clk_disable(r8a66597->clk);  		clk_put(r8a66597->clk);  	} +clean_up_dev:  #endif +	device_unregister(&r8a66597->gadget.dev);  clean_up:  	if (r8a66597) {  		if (r8a66597->sudmac_reg) diff --git a/drivers/usb/gadget/udc-core.c b/drivers/usb/gadget/udc-core.c index 022baeca7c9..6939e17f458 100644 --- a/drivers/usb/gadget/udc-core.c +++ b/drivers/usb/gadget/udc-core.c @@ -210,10 +210,10 @@ static void usb_gadget_remove_driver(struct usb_udc *udc)  	kobject_uevent(&udc->dev.kobj, KOBJ_CHANGE);  	if (udc_is_newstyle(udc)) { -		usb_gadget_disconnect(udc->gadget); +		udc->driver->disconnect(udc->gadget);  		udc->driver->unbind(udc->gadget);  		usb_gadget_udc_stop(udc->gadget, udc->driver); - +		usb_gadget_disconnect(udc->gadget);  	} else {  		usb_gadget_stop(udc->gadget, udc->driver);  	} @@ -344,7 +344,7 @@ EXPORT_SYMBOL_GPL(usb_gadget_unregister_driver);  static ssize_t usb_udc_srp_store(struct device *dev,  		struct device_attribute *attr, const char *buf, size_t n)  { -	struct usb_udc		*udc = dev_get_drvdata(dev); +	struct usb_udc		*udc = container_of(dev, struct usb_udc, dev);  	if (sysfs_streq(buf, "1"))  		usb_gadget_wakeup(udc->gadget); @@ -378,7 +378,7 @@ static ssize_t usb_udc_speed_show(struct device *dev,  	return snprintf(buf, PAGE_SIZE, "%s\n",  			usb_speed_string(udc->gadget->speed));  } -static DEVICE_ATTR(speed, S_IRUSR, usb_udc_speed_show, NULL); +static DEVICE_ATTR(speed, S_IRUGO, usb_udc_speed_show, NULL);  #define USB_UDC_ATTR(name)					\  ssize_t usb_udc_##name##_show(struct device *dev,		\ @@ -389,7 +389,7 @@ ssize_t usb_udc_##name##_show(struct device *dev,		\  								\  	return snprintf(buf, PAGE_SIZE, "%d\n", gadget->name);	\  }								\ -static DEVICE_ATTR(name, S_IRUSR, usb_udc_##name##_show, NULL) +static DEVICE_ATTR(name, S_IRUGO, usb_udc_##name##_show, NULL)  static USB_UDC_ATTR(is_dualspeed);  static USB_UDC_ATTR(is_otg); diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index 2e829fae648..56a32033adb 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c @@ -1479,10 +1479,15 @@ iso_stream_schedule (  		/* NOTE:  assumes URB_ISO_ASAP, to limit complexity/bugs */ -		/* find a uframe slot with enough bandwidth */ -		next = start + period; -		for (; start < next; start++) { - +		/* find a uframe slot with enough bandwidth. +		 * Early uframes are more precious because full-speed +		 * iso IN transfers can't use late uframes, +		 * and therefore they should be allocated last. +		 */ +		next = start; +		start += period; +		do { +			start--;  			/* check schedule: enough space? */  			if (stream->highspeed) {  				if (itd_slot_ok(ehci, mod, start, @@ -1495,7 +1500,7 @@ iso_stream_schedule (  						start, sched, period))  					break;  			} -		} +		} while (start > next);  		/* no room in the schedule */  		if (start == next) { diff --git a/drivers/usb/host/ehci-xls.c b/drivers/usb/host/ehci-xls.c index 1078d6746d2..72f08196f8c 100644 --- a/drivers/usb/host/ehci-xls.c +++ b/drivers/usb/host/ehci-xls.c @@ -19,7 +19,7 @@ static int ehci_xls_setup(struct usb_hcd *hcd)  	ehci->caps = hcd->regs;  	ehci->regs = hcd->regs + -		HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase)); +		HC_LENGTH(ehci, ehci_readl(ehci, &ehci->caps->hc_capbase));  	dbg_hcs_params(ehci, "reset");  	dbg_hcc_params(ehci, "reset"); diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c index ba3a46b78b7..95a9fec38e8 100644 --- a/drivers/usb/host/ohci-at91.c +++ b/drivers/usb/host/ohci-at91.c @@ -223,6 +223,9 @@ static void ohci_at91_usb_set_power(struct at91_usbh_data *pdata, int port, int  	if (port < 0 || port >= 2)  		return; +	if (pdata->vbus_pin[port] <= 0) +		return; +  	gpio_set_value(pdata->vbus_pin[port], !pdata->vbus_pin_inverted ^ enable);  } @@ -231,6 +234,9 @@ static int ohci_at91_usb_get_power(struct at91_usbh_data *pdata, int port)  	if (port < 0 || port >= 2)  		return -EINVAL; +	if (pdata->vbus_pin[port] <= 0) +		return -EINVAL; +  	return gpio_get_value(pdata->vbus_pin[port]) ^ !pdata->vbus_pin_inverted;  } diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index 95d639cd5b8..4fa5d8c4d23 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -390,17 +390,14 @@ ohci_shutdown (struct usb_hcd *hcd)  	struct ohci_hcd *ohci;  	ohci = hcd_to_ohci (hcd); -	ohci_writel (ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable); -	ohci->hc_control = ohci_readl(ohci, &ohci->regs->control); +	ohci_writel(ohci, (u32) ~0, &ohci->regs->intrdisable); -	/* If the SHUTDOWN quirk is set, don't put the controller in RESET */ -	ohci->hc_control &= (ohci->flags & OHCI_QUIRK_SHUTDOWN ? -			OHCI_CTRL_RWC | OHCI_CTRL_HCFS : -			OHCI_CTRL_RWC); -	ohci_writel(ohci, ohci->hc_control, &ohci->regs->control); +	/* Software reset, after which the controller goes into SUSPEND */ +	ohci_writel(ohci, OHCI_HCR, &ohci->regs->cmdstatus); +	ohci_readl(ohci, &ohci->regs->cmdstatus);	/* flush the writes */ +	udelay(10); -	/* flush the writes */ -	(void) ohci_readl (ohci, &ohci->regs->control); +	ohci_writel(ohci, ohci->fminterval, &ohci->regs->fminterval);  }  static int check_ed(struct ohci_hcd *ohci, struct ed *ed) diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c index 847187df50a..6109810cc2d 100644 --- a/drivers/usb/host/ohci-pci.c +++ b/drivers/usb/host/ohci-pci.c @@ -175,28 +175,6 @@ static int ohci_quirk_amd700(struct usb_hcd *hcd)  	return 0;  } -/* nVidia controllers continue to drive Reset signalling on the bus - * even after system shutdown, wasting power.  This flag tells the - * shutdown routine to leave the controller OPERATIONAL instead of RESET. - */ -static int ohci_quirk_nvidia_shutdown(struct usb_hcd *hcd) -{ -	struct pci_dev *pdev = to_pci_dev(hcd->self.controller); -	struct ohci_hcd	*ohci = hcd_to_ohci(hcd); - -	/* Evidently nVidia fixed their later hardware; this is a guess at -	 * the changeover point. -	 */ -#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_USB		0x026d - -	if (pdev->device < PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_USB) { -		ohci->flags |= OHCI_QUIRK_SHUTDOWN; -		ohci_dbg(ohci, "enabled nVidia shutdown quirk\n"); -	} - -	return 0; -} -  static void sb800_prefetch(struct ohci_hcd *ohci, int on)  {  	struct pci_dev *pdev; @@ -260,10 +238,6 @@ static const struct pci_device_id ohci_pci_quirks[] = {  		PCI_DEVICE(PCI_VENDOR_ID_ATI, 0x4399),  		.driver_data = (unsigned long)ohci_quirk_amd700,  	}, -	{ -		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID), -		.driver_data = (unsigned long) ohci_quirk_nvidia_shutdown, -	},  	/* FIXME for some of the early AMD 760 southbridges, OHCI  	 * won't work at all.  blacklist them. diff --git a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h index 3a978a2130c..8ff6f7ea96f 100644 --- a/drivers/usb/host/ohci.h +++ b/drivers/usb/host/ohci.h @@ -410,7 +410,6 @@ struct ohci_hcd {  #define	OHCI_QUIRK_HUB_POWER	0x100			/* distrust firmware power/oc setup */  #define	OHCI_QUIRK_AMD_PLL	0x200			/* AMD PLL quirk*/  #define	OHCI_QUIRK_AMD_PREFETCH	0x400			/* pre-fetch for ISO transfer */ -#define	OHCI_QUIRK_SHUTDOWN	0x800			/* nVidia power bug */  	// there are also chip quirks/bugs in init logic  	struct work_struct	nec_work;	/* Worker for NEC quirk */ diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c index 27a3dec32fa..caf87428ca4 100644 --- a/drivers/usb/host/pci-quirks.c +++ b/drivers/usb/host/pci-quirks.c @@ -37,6 +37,7 @@  #define OHCI_INTRENABLE		0x10  #define OHCI_INTRDISABLE	0x14  #define OHCI_FMINTERVAL		0x34 +#define OHCI_HCFS		(3 << 6)	/* hc functional state */  #define OHCI_HCR		(1 << 0)	/* host controller reset */  #define OHCI_OCR		(1 << 3)	/* ownership change request */  #define OHCI_CTRL_RWC		(1 << 9)	/* remote wakeup connected */ @@ -466,6 +467,8 @@ static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev)  {  	void __iomem *base;  	u32 control; +	u32 fminterval; +	int cnt;  	if (!mmio_resource_enabled(pdev, 0))  		return; @@ -498,41 +501,32 @@ static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev)  	}  #endif -	/* reset controller, preserving RWC (and possibly IR) */ -	writel(control & OHCI_CTRL_MASK, base + OHCI_CONTROL); -	readl(base + OHCI_CONTROL); +	/* disable interrupts */ +	writel((u32) ~0, base + OHCI_INTRDISABLE); -	/* Some NVIDIA controllers stop working if kept in RESET for too long */ -	if (pdev->vendor == PCI_VENDOR_ID_NVIDIA) { -		u32 fminterval; -		int cnt; +	/* Reset the USB bus, if the controller isn't already in RESET */ +	if (control & OHCI_HCFS) { +		/* Go into RESET, preserving RWC (and possibly IR) */ +		writel(control & OHCI_CTRL_MASK, base + OHCI_CONTROL); +		readl(base + OHCI_CONTROL); -		/* drive reset for at least 50 ms (7.1.7.5) */ +		/* drive bus reset for at least 50 ms (7.1.7.5) */  		msleep(50); +	} -		/* software reset of the controller, preserving HcFmInterval */ -		fminterval = readl(base + OHCI_FMINTERVAL); -		writel(OHCI_HCR, base + OHCI_CMDSTATUS); +	/* software reset of the controller, preserving HcFmInterval */ +	fminterval = readl(base + OHCI_FMINTERVAL); +	writel(OHCI_HCR, base + OHCI_CMDSTATUS); -		/* reset requires max 10 us delay */ -		for (cnt = 30; cnt > 0; --cnt) {	/* ... allow extra time */ -			if ((readl(base + OHCI_CMDSTATUS) & OHCI_HCR) == 0) -				break; -			udelay(1); -		} -		writel(fminterval, base + OHCI_FMINTERVAL); - -		/* Now we're in the SUSPEND state with all devices reset -		 * and wakeups and interrupts disabled -		 */ +	/* reset requires max 10 us delay */ +	for (cnt = 30; cnt > 0; --cnt) {	/* ... allow extra time */ +		if ((readl(base + OHCI_CMDSTATUS) & OHCI_HCR) == 0) +			break; +		udelay(1);  	} +	writel(fminterval, base + OHCI_FMINTERVAL); -	/* -	 * disable interrupts -	 */ -	writel(~(u32)0, base + OHCI_INTRDISABLE); -	writel(~(u32)0, base + OHCI_INTRSTATUS); - +	/* Now the controller is safely in SUSPEND and nothing can wake it up */  	iounmap(base);  } @@ -627,7 +621,7 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev)  	void __iomem *base, *op_reg_base;  	u32	hcc_params, cap, val;  	u8	offset, cap_length; -	int	wait_time, delta, count = 256/4; +	int	wait_time, count = 256/4;  	if (!mmio_resource_enabled(pdev, 0))  		return; @@ -673,11 +667,10 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev)  		writel(val, op_reg_base + EHCI_USBCMD);  		wait_time = 2000; -		delta = 100;  		do {  			writel(0x3f, op_reg_base + EHCI_USBSTS); -			udelay(delta); -			wait_time -= delta; +			udelay(100); +			wait_time -= 100;  			val = readl(op_reg_base + EHCI_USBSTS);  			if ((val == ~(u32)0) || (val & EHCI_USBSTS_HALTED)) {  				break; diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 42a22b8e692..0e4b25fa3bc 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -982,7 +982,6 @@ int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *ud  	struct xhci_virt_device *dev;  	struct xhci_ep_ctx	*ep0_ctx;  	struct xhci_slot_ctx    *slot_ctx; -	struct xhci_input_control_ctx *ctrl_ctx;  	u32			port_num;  	struct usb_device *top_dev; @@ -994,12 +993,8 @@ int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *ud  		return -EINVAL;  	}  	ep0_ctx = xhci_get_ep_ctx(xhci, dev->in_ctx, 0); -	ctrl_ctx = xhci_get_input_control_ctx(xhci, dev->in_ctx);  	slot_ctx = xhci_get_slot_ctx(xhci, dev->in_ctx); -	/* 2) New slot context and endpoint 0 context are valid*/ -	ctrl_ctx->add_flags = cpu_to_le32(SLOT_FLAG | EP0_FLAG); -  	/* 3) Only the control endpoint is valid - one endpoint context */  	slot_ctx->dev_info |= cpu_to_le32(LAST_CTX(1) | udev->route);  	switch (udev->speed) { diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 2f8c17381c6..133ce302c86 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -816,23 +816,24 @@ void xhci_stop_endpoint_command_watchdog(unsigned long arg)  	struct xhci_ring *ring;  	struct xhci_td *cur_td;  	int ret, i, j; +	unsigned long flags;  	ep = (struct xhci_virt_ep *) arg;  	xhci = ep->xhci; -	spin_lock(&xhci->lock); +	spin_lock_irqsave(&xhci->lock, flags);  	ep->stop_cmds_pending--;  	if (xhci->xhc_state & XHCI_STATE_DYING) {  		xhci_dbg(xhci, "Stop EP timer ran, but another timer marked "  				"xHCI as DYING, exiting.\n"); -		spin_unlock(&xhci->lock); +		spin_unlock_irqrestore(&xhci->lock, flags);  		return;  	}  	if (!(ep->stop_cmds_pending == 0 && (ep->ep_state & EP_HALT_PENDING))) {  		xhci_dbg(xhci, "Stop EP timer ran, but no command pending, "  				"exiting.\n"); -		spin_unlock(&xhci->lock); +		spin_unlock_irqrestore(&xhci->lock, flags);  		return;  	} @@ -844,11 +845,11 @@ void xhci_stop_endpoint_command_watchdog(unsigned long arg)  	xhci->xhc_state |= XHCI_STATE_DYING;  	/* Disable interrupts from the host controller and start halting it */  	xhci_quiesce(xhci); -	spin_unlock(&xhci->lock); +	spin_unlock_irqrestore(&xhci->lock, flags);  	ret = xhci_halt(xhci); -	spin_lock(&xhci->lock); +	spin_lock_irqsave(&xhci->lock, flags);  	if (ret < 0) {  		/* This is bad; the host is not responding to commands and it's  		 * not allowing itself to be halted.  At least interrupts are @@ -896,7 +897,7 @@ void xhci_stop_endpoint_command_watchdog(unsigned long arg)  			}  		}  	} -	spin_unlock(&xhci->lock); +	spin_unlock_irqrestore(&xhci->lock, flags);  	xhci_dbg(xhci, "Calling usb_hc_died()\n");  	usb_hc_died(xhci_to_hcd(xhci)->primary_hcd);  	xhci_dbg(xhci, "xHCI host controller is dead.\n"); diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 1ff95a0df57..aa94c019579 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -799,7 +799,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)  	u32			command, temp = 0;  	struct usb_hcd		*hcd = xhci_to_hcd(xhci);  	struct usb_hcd		*secondary_hcd; -	int			retval; +	int			retval = 0;  	/* Wait a bit if either of the roothubs need to settle from the  	 * transition into bus suspend. @@ -809,6 +809,9 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)  				xhci->bus_state[1].next_statechange))  		msleep(100); +	set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); +	set_bit(HCD_FLAG_HW_ACCESSIBLE, &xhci->shared_hcd->flags); +  	spin_lock_irq(&xhci->lock);  	if (xhci->quirks & XHCI_RESET_ON_RESUME)  		hibernated = true; @@ -878,20 +881,13 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)  			return retval;  		xhci_dbg(xhci, "Start the primary HCD\n");  		retval = xhci_run(hcd->primary_hcd); -		if (retval) -			goto failed_restart; - -		xhci_dbg(xhci, "Start the secondary HCD\n"); -		retval = xhci_run(secondary_hcd);  		if (!retval) { -			set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); -			set_bit(HCD_FLAG_HW_ACCESSIBLE, -					&xhci->shared_hcd->flags); +			xhci_dbg(xhci, "Start the secondary HCD\n"); +			retval = xhci_run(secondary_hcd);  		} -failed_restart:  		hcd->state = HC_STATE_SUSPENDED;  		xhci->shared_hcd->state = HC_STATE_SUSPENDED; -		return retval; +		goto done;  	}  	/* step 4: set Run/Stop bit */ @@ -910,11 +906,14 @@ failed_restart:  	 * Running endpoints by ringing their doorbells  	 */ -	set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); -	set_bit(HCD_FLAG_HW_ACCESSIBLE, &xhci->shared_hcd->flags); -  	spin_unlock_irq(&xhci->lock); -	return 0; + + done: +	if (retval == 0) { +		usb_hcd_resume_root_hub(hcd); +		usb_hcd_resume_root_hub(xhci->shared_hcd); +	} +	return retval;  }  #endif	/* CONFIG_PM */ @@ -3504,6 +3503,10 @@ int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev)  	/* Otherwise, update the control endpoint ring enqueue pointer. */  	else  		xhci_copy_ep0_dequeue_into_input_ctx(xhci, udev); +	ctrl_ctx = xhci_get_input_control_ctx(xhci, virt_dev->in_ctx); +	ctrl_ctx->add_flags = cpu_to_le32(SLOT_FLAG | EP0_FLAG); +	ctrl_ctx->drop_flags = 0; +  	xhci_dbg(xhci, "Slot ID %d Input Context:\n", udev->slot_id);  	xhci_dbg_ctx(xhci, virt_dev->in_ctx, 2); @@ -3585,7 +3588,6 @@ int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev)  	virt_dev->address = (le32_to_cpu(slot_ctx->dev_state) & DEV_ADDR_MASK)  		+ 1;  	/* Zero the input context control for later use */ -	ctrl_ctx = xhci_get_input_control_ctx(xhci, virt_dev->in_ctx);  	ctrl_ctx->add_flags = 0;  	ctrl_ctx->drop_flags = 0; diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig index fc34b8b1191..07a03460a59 100644 --- a/drivers/usb/musb/Kconfig +++ b/drivers/usb/musb/Kconfig @@ -11,6 +11,7 @@ config USB_MUSB_HDRC  	select TWL4030_USB if MACH_OMAP_3430SDP  	select TWL6030_USB if MACH_OMAP_4430SDP || MACH_OMAP4_PANDA  	select USB_OTG_UTILS +	select USB_GADGET_DUALSPEED  	tristate 'Inventra Highspeed Dual Role Controller (TI, ADI, ...)'  	help  	  Say Y here if your system has a dual role high speed USB @@ -60,7 +61,7 @@ config USB_MUSB_BLACKFIN  config USB_MUSB_UX500  	tristate "U8500 and U5500" -	depends on (ARCH_U8500 && AB8500_USB) || (ARCH_U5500) +	depends on (ARCH_U8500 && AB8500_USB)  endchoice diff --git a/drivers/usb/musb/am35x.c b/drivers/usb/musb/am35x.c index 08f1d0b662a..e233d2b7d33 100644 --- a/drivers/usb/musb/am35x.c +++ b/drivers/usb/musb/am35x.c @@ -27,6 +27,7 @@   */  #include <linux/init.h> +#include <linux/module.h>  #include <linux/clk.h>  #include <linux/io.h>  #include <linux/platform_device.h> diff --git a/drivers/usb/musb/da8xx.c b/drivers/usb/musb/da8xx.c index 4da7492ddbd..2613bfdb09b 100644 --- a/drivers/usb/musb/da8xx.c +++ b/drivers/usb/musb/da8xx.c @@ -27,6 +27,7 @@   */  #include <linux/init.h> +#include <linux/module.h>  #include <linux/clk.h>  #include <linux/io.h>  #include <linux/platform_device.h> diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 12044c473c3..54958508679 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -1476,8 +1476,7 @@ static int __init musb_core_init(u16 musb_type, struct musb *musb)  /*-------------------------------------------------------------------------*/  #if defined(CONFIG_SOC_OMAP2430) || defined(CONFIG_SOC_OMAP3430) || \ -	defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_ARCH_U8500) || \ -	defined(CONFIG_ARCH_U5500) +	defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_ARCH_U8500)  static irqreturn_t generic_interrupt(int irq, void *__hci)  { diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index ae4a20acef6..d51043acfe1 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -1999,10 +1999,6 @@ static void stop_activity(struct musb *musb, struct usb_gadget_driver *driver)  					nuke(&hw_ep->ep_out, -ESHUTDOWN);  			}  		} - -		spin_unlock(&musb->lock); -		driver->disconnect(&musb->g); -		spin_lock(&musb->lock);  	}  } diff --git a/drivers/usb/renesas_usbhs/common.c b/drivers/usb/renesas_usbhs/common.c index d2e2efaba65..08c679c0dde 100644 --- a/drivers/usb/renesas_usbhs/common.c +++ b/drivers/usb/renesas_usbhs/common.c @@ -405,7 +405,7 @@ int usbhsc_drvcllbck_notify_hotplug(struct platform_device *pdev)  /*   *		platform functions   */ -static int __devinit usbhs_probe(struct platform_device *pdev) +static int usbhs_probe(struct platform_device *pdev)  {  	struct renesas_usbhs_platform_info *info = pdev->dev.platform_data;  	struct renesas_usbhs_driver_callback *dfunc; diff --git a/drivers/usb/renesas_usbhs/fifo.c b/drivers/usb/renesas_usbhs/fifo.c index 8da685e796d..ffdf5d15085 100644 --- a/drivers/usb/renesas_usbhs/fifo.c +++ b/drivers/usb/renesas_usbhs/fifo.c @@ -820,7 +820,7 @@ static int usbhsf_dma_prepare_push(struct usbhs_pkt *pkt, int *is_done)  	if (len % 4) /* 32bit alignment */  		goto usbhsf_pio_prepare_push; -	if ((*(u32 *) pkt->buf + pkt->actual) & 0x7) /* 8byte alignment */ +	if ((uintptr_t)(pkt->buf + pkt->actual) & 0x7) /* 8byte alignment */  		goto usbhsf_pio_prepare_push;  	/* get enable DMA fifo */ @@ -897,7 +897,7 @@ static int usbhsf_dma_try_pop(struct usbhs_pkt *pkt, int *is_done)  	if (!fifo)  		goto usbhsf_pio_prepare_pop; -	if ((*(u32 *) pkt->buf + pkt->actual) & 0x7) /* 8byte alignment */ +	if ((uintptr_t)(pkt->buf + pkt->actual) & 0x7) /* 8byte alignment */  		goto usbhsf_pio_prepare_pop;  	ret = usbhsf_fifo_select(pipe, fifo, 0); diff --git a/drivers/usb/renesas_usbhs/mod.h b/drivers/usb/renesas_usbhs/mod.h index 8ae3733031c..6c6875533f0 100644 --- a/drivers/usb/renesas_usbhs/mod.h +++ b/drivers/usb/renesas_usbhs/mod.h @@ -143,8 +143,8 @@ void usbhs_irq_callback_update(struct usbhs_priv *priv, struct usbhs_mod *mod);   */  #if	defined(CONFIG_USB_RENESAS_USBHS_HCD) || \  	defined(CONFIG_USB_RENESAS_USBHS_HCD_MODULE) -extern int __devinit usbhs_mod_host_probe(struct usbhs_priv *priv); -extern int __devexit usbhs_mod_host_remove(struct usbhs_priv *priv); +extern int usbhs_mod_host_probe(struct usbhs_priv *priv); +extern int usbhs_mod_host_remove(struct usbhs_priv *priv);  #else  static inline int usbhs_mod_host_probe(struct usbhs_priv *priv)  { @@ -157,8 +157,8 @@ static inline void usbhs_mod_host_remove(struct usbhs_priv *priv)  #if	defined(CONFIG_USB_RENESAS_USBHS_UDC) || \  	defined(CONFIG_USB_RENESAS_USBHS_UDC_MODULE) -extern int __devinit usbhs_mod_gadget_probe(struct usbhs_priv *priv); -extern void __devexit usbhs_mod_gadget_remove(struct usbhs_priv *priv); +extern int usbhs_mod_gadget_probe(struct usbhs_priv *priv); +extern void usbhs_mod_gadget_remove(struct usbhs_priv *priv);  #else  static inline int usbhs_mod_gadget_probe(struct usbhs_priv *priv)  { diff --git a/drivers/usb/renesas_usbhs/mod_gadget.c b/drivers/usb/renesas_usbhs/mod_gadget.c index 4cc7ee0babc..d9717e0bc1f 100644 --- a/drivers/usb/renesas_usbhs/mod_gadget.c +++ b/drivers/usb/renesas_usbhs/mod_gadget.c @@ -830,7 +830,7 @@ static int usbhsg_stop(struct usbhs_priv *priv)  	return usbhsg_try_stop(priv, USBHSG_STATUS_STARTED);  } -int __devinit usbhs_mod_gadget_probe(struct usbhs_priv *priv) +int usbhs_mod_gadget_probe(struct usbhs_priv *priv)  {  	struct usbhsg_gpriv *gpriv;  	struct usbhsg_uep *uep; @@ -927,7 +927,7 @@ usbhs_mod_gadget_probe_err_gpriv:  	return ret;  } -void __devexit usbhs_mod_gadget_remove(struct usbhs_priv *priv) +void usbhs_mod_gadget_remove(struct usbhs_priv *priv)  {  	struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv); diff --git a/drivers/usb/renesas_usbhs/mod_host.c b/drivers/usb/renesas_usbhs/mod_host.c index 1a7208a50af..bade761a1e5 100644 --- a/drivers/usb/renesas_usbhs/mod_host.c +++ b/drivers/usb/renesas_usbhs/mod_host.c @@ -103,7 +103,7 @@ struct usbhsh_hpriv {  	u32	port_stat;	/* USB_PORT_STAT_xxx */ -	struct completion	*done; +	struct completion	setup_ack_done;  	/* see usbhsh_req_alloc/free */  	struct list_head	ureq_link_active; @@ -355,6 +355,7 @@ static void usbhsh_device_free(struct usbhsh_hpriv *hpriv,  struct usbhsh_ep *usbhsh_endpoint_alloc(struct usbhsh_hpriv *hpriv,  					struct usbhsh_device *udev,  					struct usb_host_endpoint *ep, +					int dir_in_req,  					gfp_t mem_flags)  {  	struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); @@ -364,27 +365,38 @@ struct usbhsh_ep *usbhsh_endpoint_alloc(struct usbhsh_hpriv *hpriv,  	struct usbhs_pipe *pipe, *best_pipe;  	struct device *dev = usbhsh_hcd_to_dev(hcd);  	struct usb_endpoint_descriptor *desc = &ep->desc; -	int type, i; +	int type, i, dir_in;  	unsigned int min_usr; +	dir_in_req = !!dir_in_req; +  	uep = kzalloc(sizeof(struct usbhsh_ep), mem_flags);  	if (!uep) {  		dev_err(dev, "usbhsh_ep alloc fail\n");  		return NULL;  	} -	type = usb_endpoint_type(desc); + +	if (usb_endpoint_xfer_control(desc)) { +		best_pipe = usbhsh_hpriv_to_dcp(hpriv); +		goto usbhsh_endpoint_alloc_find_pipe; +	}  	/*  	 * find best pipe for endpoint  	 * see  	 *	HARDWARE LIMITATION  	 */ +	type = usb_endpoint_type(desc);  	min_usr = ~0;  	best_pipe = NULL; -	usbhs_for_each_pipe_with_dcp(pipe, priv, i) { +	usbhs_for_each_pipe(pipe, priv, i) {  		if (!usbhs_pipe_type_is(pipe, type))  			continue; +		dir_in = !!usbhs_pipe_is_dir_in(pipe); +		if (0 != (dir_in - dir_in_req)) +			continue; +  		info = usbhsh_pipe_info(pipe);  		if (min_usr > info->usr_cnt) { @@ -398,7 +410,7 @@ struct usbhsh_ep *usbhsh_endpoint_alloc(struct usbhsh_hpriv *hpriv,  		kfree(uep);  		return NULL;  	} - +usbhsh_endpoint_alloc_find_pipe:  	/*  	 * init uep  	 */ @@ -423,6 +435,7 @@ struct usbhsh_ep *usbhsh_endpoint_alloc(struct usbhsh_hpriv *hpriv,  	 * see  	 *  DCPMAXP/PIPEMAXP  	 */ +	usbhs_pipe_sequence_data0(uep->pipe);  	usbhs_pipe_config_update(uep->pipe,  				 usbhsh_device_number(hpriv, udev),  				 usb_endpoint_num(desc), @@ -430,7 +443,7 @@ struct usbhsh_ep *usbhsh_endpoint_alloc(struct usbhsh_hpriv *hpriv,  	dev_dbg(dev, "%s [%d-%s](%p)\n", __func__,  		usbhsh_device_number(hpriv, udev), -		usbhs_pipe_name(pipe), uep); +		usbhs_pipe_name(uep->pipe), uep);  	return uep;  } @@ -549,8 +562,7 @@ static void usbhsh_setup_stage_packet_push(struct usbhsh_hpriv *hpriv,  	 *	usbhsh_irq_setup_ack()  	 *	usbhsh_irq_setup_err()  	 */ -	DECLARE_COMPLETION(done); -	hpriv->done = &done; +	init_completion(&hpriv->setup_ack_done);  	/* copy original request */  	memcpy(&req, urb->setup_packet, sizeof(struct usb_ctrlrequest)); @@ -572,8 +584,7 @@ static void usbhsh_setup_stage_packet_push(struct usbhsh_hpriv *hpriv,  	/*  	 * wait setup packet ACK  	 */ -	wait_for_completion(&done); -	hpriv->done = NULL; +	wait_for_completion(&hpriv->setup_ack_done);  	dev_dbg(dev, "%s done\n", __func__);  } @@ -724,11 +735,11 @@ static int usbhsh_urb_enqueue(struct usb_hcd *hcd,  	struct usbhsh_device *udev, *new_udev = NULL;  	struct usbhs_pipe *pipe;  	struct usbhsh_ep *uep; +	int is_dir_in = usb_pipein(urb->pipe);  	int ret; -	dev_dbg(dev, "%s (%s)\n", -		__func__, usb_pipein(urb->pipe) ? "in" : "out"); +	dev_dbg(dev, "%s (%s)\n", __func__, is_dir_in ? "in" : "out");  	ret = usb_hcd_link_urb_to_ep(hcd, urb);  	if (ret) @@ -751,7 +762,8 @@ static int usbhsh_urb_enqueue(struct usb_hcd *hcd,  	 */  	uep = usbhsh_ep_to_uep(ep);  	if (!uep) { -		uep = usbhsh_endpoint_alloc(hpriv, udev, ep, mem_flags); +		uep = usbhsh_endpoint_alloc(hpriv, udev, ep, +					    is_dir_in, mem_flags);  		if (!uep)  			goto usbhsh_urb_enqueue_error_free_device;  	} @@ -1095,10 +1107,7 @@ static int usbhsh_irq_setup_ack(struct usbhs_priv *priv,  	dev_dbg(dev, "setup packet OK\n"); -	if (unlikely(!hpriv->done)) -		dev_err(dev, "setup ack happen without necessary data\n"); -	else -		complete(hpriv->done); /* see usbhsh_urb_enqueue() */ +	complete(&hpriv->setup_ack_done); /* see usbhsh_urb_enqueue() */  	return 0;  } @@ -1111,10 +1120,7 @@ static int usbhsh_irq_setup_err(struct usbhs_priv *priv,  	dev_dbg(dev, "setup packet Err\n"); -	if (unlikely(!hpriv->done)) -		dev_err(dev, "setup err happen without necessary data\n"); -	else -		complete(hpriv->done); /* see usbhsh_urb_enqueue() */ +	complete(&hpriv->setup_ack_done); /* see usbhsh_urb_enqueue() */  	return 0;  } @@ -1221,8 +1227,18 @@ static int usbhsh_stop(struct usbhs_priv *priv)  {  	struct usbhsh_hpriv *hpriv = usbhsh_priv_to_hpriv(priv);  	struct usb_hcd *hcd = usbhsh_hpriv_to_hcd(hpriv); +	struct usbhs_mod *mod = usbhs_mod_get_current(priv);  	struct device *dev = usbhs_priv_to_dev(priv); +	/* +	 * disable irq callback +	 */ +	mod->irq_attch	= NULL; +	mod->irq_dtch	= NULL; +	mod->irq_sack	= NULL; +	mod->irq_sign	= NULL; +	usbhs_irq_callback_update(priv, mod); +  	usb_remove_hcd(hcd);  	/* disable sys */ @@ -1235,7 +1251,7 @@ static int usbhsh_stop(struct usbhs_priv *priv)  	return 0;  } -int __devinit usbhs_mod_host_probe(struct usbhs_priv *priv) +int usbhs_mod_host_probe(struct usbhs_priv *priv)  {  	struct usbhsh_hpriv *hpriv;  	struct usb_hcd *hcd; @@ -1279,7 +1295,6 @@ int __devinit usbhs_mod_host_probe(struct usbhs_priv *priv)  	hpriv->mod.stop		= usbhsh_stop;  	hpriv->pipe_info	= pipe_info;  	hpriv->pipe_size	= pipe_size; -	hpriv->done		= NULL;  	usbhsh_req_list_init(hpriv);  	usbhsh_port_stat_init(hpriv); @@ -1299,7 +1314,7 @@ usbhs_mod_host_probe_err:  	return -ENOMEM;  } -int __devexit usbhs_mod_host_remove(struct usbhs_priv *priv) +int usbhs_mod_host_remove(struct usbhs_priv *priv)  {  	struct usbhsh_hpriv *hpriv = usbhsh_priv_to_hpriv(priv);  	struct usb_hcd *hcd = usbhsh_hpriv_to_hcd(hpriv); diff --git a/drivers/usb/serial/ark3116.c b/drivers/usb/serial/ark3116.c index 5cdb9d91227..18e875b92e0 100644 --- a/drivers/usb/serial/ark3116.c +++ b/drivers/usb/serial/ark3116.c @@ -42,7 +42,7 @@ static int debug;   * Version information   */ -#define DRIVER_VERSION "v0.6" +#define DRIVER_VERSION "v0.7"  #define DRIVER_AUTHOR "Bart Hartgers <bart.hartgers+ark3116@gmail.com>"  #define DRIVER_DESC "USB ARK3116 serial/IrDA driver"  #define DRIVER_DEV_DESC "ARK3116 RS232/IrDA" @@ -380,10 +380,6 @@ static int ark3116_open(struct tty_struct *tty, struct usb_serial_port *port)  		goto err_out;  	} -	/* setup termios */ -	if (tty) -		ark3116_set_termios(tty, port, NULL); -  	/* remove any data still left: also clears error state */  	ark3116_read_reg(serial, UART_RX, buf); @@ -406,6 +402,10 @@ static int ark3116_open(struct tty_struct *tty, struct usb_serial_port *port)  	/* enable DMA */  	ark3116_write_reg(port->serial, UART_FCR, UART_FCR_DMA_SELECT); +	/* setup termios */ +	if (tty) +		ark3116_set_termios(tty, port, NULL); +  err_out:  	kfree(buf);  	return result; diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 8fe034d2d3e..bd4298bb675 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -2104,13 +2104,19 @@ static void ftdi_set_termios(struct tty_struct *tty,  	cflag = termios->c_cflag; -	/* FIXME -For this cut I don't care if the line is really changing or -	   not  - so just do the change regardless  - should be able to -	   compare old_termios and tty->termios */ +	if (old_termios->c_cflag == termios->c_cflag +	    && old_termios->c_ispeed == termios->c_ispeed +	    && old_termios->c_ospeed == termios->c_ospeed) +		goto no_c_cflag_changes; +  	/* NOTE These routines can get interrupted by  	   ftdi_sio_read_bulk_callback  - need to examine what this means -  	   don't see any problems yet */ +	if ((old_termios->c_cflag & (CSIZE|PARODD|PARENB|CMSPAR|CSTOPB)) == +	    (termios->c_cflag & (CSIZE|PARODD|PARENB|CMSPAR|CSTOPB))) +		goto no_data_parity_stop_changes; +  	/* Set number of data bits, parity, stop bits */  	urb_value = 0; @@ -2151,6 +2157,7 @@ static void ftdi_set_termios(struct tty_struct *tty,  	}  	/* Now do the baudrate */ +no_data_parity_stop_changes:  	if ((cflag & CBAUD) == B0) {  		/* Disable flow control */  		if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0), @@ -2178,6 +2185,7 @@ static void ftdi_set_termios(struct tty_struct *tty,  	/* Set flow control */  	/* Note device also supports DTR/CD (ugh) and Xon/Xoff in hardware */ +no_c_cflag_changes:  	if (cflag & CRTSCTS) {  		dbg("%s Setting to CRTSCTS flow control", __func__);  		if (usb_control_msg(dev, diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 89ae1f65e1b..d865878c9f9 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -156,6 +156,7 @@ static void option_instat_callback(struct urb *urb);  #define HUAWEI_PRODUCT_K4511			0x14CC  #define HUAWEI_PRODUCT_ETS1220			0x1803  #define HUAWEI_PRODUCT_E353			0x1506 +#define HUAWEI_PRODUCT_E173S			0x1C05  #define QUANTA_VENDOR_ID			0x0408  #define QUANTA_PRODUCT_Q101			0xEA02 @@ -316,6 +317,9 @@ static void option_instat_callback(struct urb *urb);  #define ZTE_PRODUCT_AC8710			0xfff1  #define ZTE_PRODUCT_AC2726			0xfff5  #define ZTE_PRODUCT_AC8710T			0xffff +#define ZTE_PRODUCT_MC2718			0xffe8 +#define ZTE_PRODUCT_AD3812			0xffeb +#define ZTE_PRODUCT_MC2716			0xffed  #define BENQ_VENDOR_ID				0x04a5  #define BENQ_PRODUCT_H10			0x4068 @@ -468,6 +472,10 @@ static void option_instat_callback(struct urb *urb);  #define YUGA_PRODUCT_CLU528			0x260D  #define YUGA_PRODUCT_CLU526			0x260F +/* Viettel products */ +#define VIETTEL_VENDOR_ID			0x2262 +#define VIETTEL_PRODUCT_VT1000			0x0002 +  /* some devices interfaces need special handling due to a number of reasons */  enum option_blacklist_reason {  		OPTION_BLACKLIST_NONE = 0, @@ -500,6 +508,18 @@ static const struct option_blacklist_info zte_k3765_z_blacklist = {  	.reserved = BIT(4),  }; +static const struct option_blacklist_info zte_ad3812_z_blacklist = { +	.sendsetup = BIT(0) | BIT(1) | BIT(2), +}; + +static const struct option_blacklist_info zte_mc2718_z_blacklist = { +	.sendsetup = BIT(1) | BIT(2) | BIT(3) | BIT(4), +}; + +static const struct option_blacklist_info zte_mc2716_z_blacklist = { +	.sendsetup = BIT(1) | BIT(2) | BIT(3), +}; +  static const struct option_blacklist_info huawei_cdc12_blacklist = {  	.reserved = BIT(1) | BIT(2),  }; @@ -622,6 +642,7 @@ static const struct usb_device_id option_ids[] = {  	{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143D, 0xff, 0xff, 0xff) },  	{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143E, 0xff, 0xff, 0xff) },  	{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143F, 0xff, 0xff, 0xff) }, +	{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E173S, 0xff, 0xff, 0xff) },  	{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4505, 0xff, 0xff, 0xff),  		.driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist },  	{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3765, 0xff, 0xff, 0xff), @@ -1043,6 +1064,12 @@ static const struct usb_device_id option_ids[] = {  	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710, 0xff, 0xff, 0xff) },  	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC2726, 0xff, 0xff, 0xff) },  	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710T, 0xff, 0xff, 0xff) }, +	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MC2718, 0xff, 0xff, 0xff), +	 .driver_info = (kernel_ulong_t)&zte_mc2718_z_blacklist }, +	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AD3812, 0xff, 0xff, 0xff), +	 .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_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 */ @@ -1141,6 +1168,7 @@ static const struct usb_device_id option_ids[] = {  	{ USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU516) },  	{ USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU528) },  	{ USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU526) }, +	{ USB_DEVICE_AND_INTERFACE_INFO(VIETTEL_VENDOR_ID, VIETTEL_PRODUCT_VT1000, 0xff, 0xff, 0xff) },  	{ } /* Terminating entry */  };  MODULE_DEVICE_TABLE(usb, option_ids); diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index 56aa1e6cc38..329295615d0 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c @@ -91,7 +91,6 @@ static const struct usb_device_id id_table[] = {  	{ USB_DEVICE(SONY_VENDOR_ID, SONY_QN3USB_PRODUCT_ID) },  	{ USB_DEVICE(SANWA_VENDOR_ID, SANWA_PRODUCT_ID) },  	{ USB_DEVICE(ADLINK_VENDOR_ID, ADLINK_ND6530_PRODUCT_ID) }, -	{ USB_DEVICE(WINCHIPHEAD_VENDOR_ID, WINCHIPHEAD_USBSER_PRODUCT_ID) },  	{ USB_DEVICE(SMART_VENDOR_ID, SMART_PRODUCT_ID) },  	{ }					/* Terminating entry */  }; diff --git a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h index 3d10d7f0207..c38b8c00c06 100644 --- a/drivers/usb/serial/pl2303.h +++ b/drivers/usb/serial/pl2303.h @@ -145,10 +145,6 @@  #define ADLINK_VENDOR_ID		0x0b63  #define ADLINK_ND6530_PRODUCT_ID	0x6530 -/* WinChipHead USB->RS 232 adapter */ -#define WINCHIPHEAD_VENDOR_ID		0x4348 -#define WINCHIPHEAD_USBSER_PRODUCT_ID	0x5523 -  /* SMART USB Serial Adapter */  #define SMART_VENDOR_ID	0x0b8c  #define SMART_PRODUCT_ID	0x2303 diff --git a/drivers/usb/storage/ene_ub6250.c b/drivers/usb/storage/ene_ub6250.c index 9665f15f52a..b990726f144 100644 --- a/drivers/usb/storage/ene_ub6250.c +++ b/drivers/usb/storage/ene_ub6250.c @@ -1762,10 +1762,9 @@ static int ms_scsi_write(struct us_data *us, struct scsi_cmnd *srb)  		result = ene_send_scsi_cmd(us, FDIR_WRITE, scsi_sglist(srb), 1);  	} else {  		void *buf; -		int offset; +		int offset = 0;  		u16 PhyBlockAddr;  		u8 PageNum; -		u32 result;  		u16 len, oldphy, newphy;  		buf = kmalloc(blenByte, GFP_KERNEL); diff --git a/drivers/usb/storage/protocol.c b/drivers/usb/storage/protocol.c index 93c1a4d86f5..82dd834709c 100644 --- a/drivers/usb/storage/protocol.c +++ b/drivers/usb/storage/protocol.c @@ -59,7 +59,9 @@  void usb_stor_pad12_command(struct scsi_cmnd *srb, struct us_data *us)  { -	/* Pad the SCSI command with zeros out to 12 bytes +	/* +	 * Pad the SCSI command with zeros out to 12 bytes.  If the +	 * command already is 12 bytes or longer, leave it alone.  	 *  	 * NOTE: This only works because a scsi_cmnd struct field contains  	 * a unsigned char cmnd[16], so we know we have storage available @@ -67,9 +69,6 @@ void usb_stor_pad12_command(struct scsi_cmnd *srb, struct us_data *us)  	for (; srb->cmd_len<12; srb->cmd_len++)  		srb->cmnd[srb->cmd_len] = 0; -	/* set command length to 12 bytes */ -	srb->cmd_len = 12; -  	/* send the command to the transport layer */  	usb_stor_invoke_transport(srb, us);  } diff --git a/drivers/virtio/Kconfig b/drivers/virtio/Kconfig index 816ed08e7cf..1a61939b85f 100644 --- a/drivers/virtio/Kconfig +++ b/drivers/virtio/Kconfig @@ -37,7 +37,7 @@ config VIRTIO_BALLOON   config VIRTIO_MMIO   	tristate "Platform bus driver for memory mapped virtio devices (EXPERIMENTAL)" - 	depends on EXPERIMENTAL + 	depends on HAS_IOMEM && EXPERIMENTAL   	select VIRTIO   	select VIRTIO_RING   	---help--- diff --git a/drivers/virtio/virtio_mmio.c b/drivers/virtio/virtio_mmio.c index acc5e43c373..7317dc2ec42 100644 --- a/drivers/virtio/virtio_mmio.c +++ b/drivers/virtio/virtio_mmio.c @@ -118,7 +118,7 @@ static void vm_finalize_features(struct virtio_device *vdev)  	vring_transport_features(vdev);  	for (i = 0; i < ARRAY_SIZE(vdev->features); i++) { -		writel(i, vm_dev->base + VIRTIO_MMIO_GUEST_FEATURES_SET); +		writel(i, vm_dev->base + VIRTIO_MMIO_GUEST_FEATURES_SEL);  		writel(vdev->features[i],  				vm_dev->base + VIRTIO_MMIO_GUEST_FEATURES);  	} diff --git a/drivers/virtio/virtio_pci.c b/drivers/virtio/virtio_pci.c index 79a31e5b4b6..03d1984bd36 100644 --- a/drivers/virtio/virtio_pci.c +++ b/drivers/virtio/virtio_pci.c @@ -169,11 +169,29 @@ static void vp_set_status(struct virtio_device *vdev, u8 status)  	iowrite8(status, vp_dev->ioaddr + VIRTIO_PCI_STATUS);  } +/* wait for pending irq handlers */ +static void vp_synchronize_vectors(struct virtio_device *vdev) +{ +	struct virtio_pci_device *vp_dev = to_vp_device(vdev); +	int i; + +	if (vp_dev->intx_enabled) +		synchronize_irq(vp_dev->pci_dev->irq); + +	for (i = 0; i < vp_dev->msix_vectors; ++i) +		synchronize_irq(vp_dev->msix_entries[i].vector); +} +  static void vp_reset(struct virtio_device *vdev)  {  	struct virtio_pci_device *vp_dev = to_vp_device(vdev);  	/* 0 status means a reset. */  	iowrite8(0, vp_dev->ioaddr + VIRTIO_PCI_STATUS); +	/* Flush out the status write, and flush in device writes, +	 * including MSi-X interrupts, if any. */ +	ioread8(vp_dev->ioaddr + VIRTIO_PCI_STATUS); +	/* Flush pending VQ/configuration callbacks. */ +	vp_synchronize_vectors(vdev);  }  /* the notify function used when creating a virt queue */ @@ -594,11 +612,11 @@ static struct virtio_config_ops virtio_pci_config_ops = {  static void virtio_pci_release_dev(struct device *_d)  { -	struct virtio_device *dev = container_of(_d, struct virtio_device, -						 dev); -	struct virtio_pci_device *vp_dev = to_vp_device(dev); - -	kfree(vp_dev); +	/* +	 * No need for a release method as we allocate/free +	 * all devices together with the pci devices. +	 * Provide an empty one to avoid getting a warning from core. +	 */  }  /* the PCI probing function */ @@ -686,6 +704,7 @@ static void __devexit virtio_pci_remove(struct pci_dev *pci_dev)  	pci_iounmap(pci_dev, vp_dev->ioaddr);  	pci_release_regions(pci_dev);  	pci_disable_device(pci_dev); +	kfree(vp_dev);  }  #ifdef CONFIG_PM diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 6285867a935..79fd606b7cd 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -314,13 +314,6 @@ config NUC900_WATCHDOG  	  To compile this driver as a module, choose M here: the  	  module will be called nuc900_wdt. -config ADX_WATCHDOG -	tristate "Avionic Design Xanthos watchdog" -	depends on ARCH_PXA_ADX -	help -	  Say Y here if you want support for the watchdog timer on Avionic -	  Design Xanthos boards. -  config TS72XX_WATCHDOG  	tristate "TS-72XX SBC Watchdog"  	depends on MACH_TS72XX diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index 55bd5740e91..fe893e91935 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile @@ -51,7 +51,6 @@ obj-$(CONFIG_ORION_WATCHDOG) += orion_wdt.o  obj-$(CONFIG_COH901327_WATCHDOG) += coh901327_wdt.o  obj-$(CONFIG_STMP3XXX_WATCHDOG) += stmp3xxx_wdt.o  obj-$(CONFIG_NUC900_WATCHDOG) += nuc900_wdt.o -obj-$(CONFIG_ADX_WATCHDOG) += adx_wdt.o  obj-$(CONFIG_TS72XX_WATCHDOG) += ts72xx_wdt.o  obj-$(CONFIG_IMX2_WDT) += imx2_wdt.o diff --git a/drivers/watchdog/adx_wdt.c b/drivers/watchdog/adx_wdt.c deleted file mode 100644 index af6e6b16475..00000000000 --- a/drivers/watchdog/adx_wdt.c +++ /dev/null @@ -1,355 +0,0 @@ -/* - * Copyright (C) 2008-2009 Avionic Design GmbH - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include <linux/fs.h> -#include <linux/gfp.h> -#include <linux/io.h> -#include <linux/miscdevice.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/types.h> -#include <linux/uaccess.h> -#include <linux/watchdog.h> - -#define WATCHDOG_NAME "adx-wdt" - -/* register offsets */ -#define	ADX_WDT_CONTROL		0x00 -#define	ADX_WDT_CONTROL_ENABLE	(1 << 0) -#define	ADX_WDT_CONTROL_nRESET	(1 << 1) -#define	ADX_WDT_TIMEOUT		0x08 - -static struct platform_device *adx_wdt_dev; -static unsigned long driver_open; - -#define	WDT_STATE_STOP	0 -#define	WDT_STATE_START	1 - -struct adx_wdt { -	void __iomem *base; -	unsigned long timeout; -	unsigned int state; -	unsigned int wake; -	spinlock_t lock; -}; - -static const struct watchdog_info adx_wdt_info = { -	.identity = "Avionic Design Xanthos Watchdog", -	.options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, -}; - -static void adx_wdt_start_locked(struct adx_wdt *wdt) -{ -	u32 ctrl; - -	ctrl = readl(wdt->base + ADX_WDT_CONTROL); -	ctrl |= ADX_WDT_CONTROL_ENABLE; -	writel(ctrl, wdt->base + ADX_WDT_CONTROL); -	wdt->state = WDT_STATE_START; -} - -static void adx_wdt_start(struct adx_wdt *wdt) -{ -	unsigned long flags; - -	spin_lock_irqsave(&wdt->lock, flags); -	adx_wdt_start_locked(wdt); -	spin_unlock_irqrestore(&wdt->lock, flags); -} - -static void adx_wdt_stop_locked(struct adx_wdt *wdt) -{ -	u32 ctrl; - -	ctrl = readl(wdt->base + ADX_WDT_CONTROL); -	ctrl &= ~ADX_WDT_CONTROL_ENABLE; -	writel(ctrl, wdt->base + ADX_WDT_CONTROL); -	wdt->state = WDT_STATE_STOP; -} - -static void adx_wdt_stop(struct adx_wdt *wdt) -{ -	unsigned long flags; - -	spin_lock_irqsave(&wdt->lock, flags); -	adx_wdt_stop_locked(wdt); -	spin_unlock_irqrestore(&wdt->lock, flags); -} - -static void adx_wdt_set_timeout(struct adx_wdt *wdt, unsigned long seconds) -{ -	unsigned long timeout = seconds * 1000; -	unsigned long flags; -	unsigned int state; - -	spin_lock_irqsave(&wdt->lock, flags); -	state = wdt->state; -	adx_wdt_stop_locked(wdt); -	writel(timeout, wdt->base + ADX_WDT_TIMEOUT); - -	if (state == WDT_STATE_START) -		adx_wdt_start_locked(wdt); - -	wdt->timeout = timeout; -	spin_unlock_irqrestore(&wdt->lock, flags); -} - -static void adx_wdt_get_timeout(struct adx_wdt *wdt, unsigned long *seconds) -{ -	*seconds = wdt->timeout / 1000; -} - -static void adx_wdt_keepalive(struct adx_wdt *wdt) -{ -	unsigned long flags; - -	spin_lock_irqsave(&wdt->lock, flags); -	writel(wdt->timeout, wdt->base + ADX_WDT_TIMEOUT); -	spin_unlock_irqrestore(&wdt->lock, flags); -} - -static int adx_wdt_open(struct inode *inode, struct file *file) -{ -	struct adx_wdt *wdt = platform_get_drvdata(adx_wdt_dev); - -	if (test_and_set_bit(0, &driver_open)) -		return -EBUSY; - -	file->private_data = wdt; -	adx_wdt_set_timeout(wdt, 30); -	adx_wdt_start(wdt); - -	return nonseekable_open(inode, file); -} - -static int adx_wdt_release(struct inode *inode, struct file *file) -{ -	struct adx_wdt *wdt = file->private_data; - -	adx_wdt_stop(wdt); -	clear_bit(0, &driver_open); - -	return 0; -} - -static long adx_wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -{ -	struct adx_wdt *wdt = file->private_data; -	void __user *argp = (void __user *)arg; -	unsigned long __user *p = argp; -	unsigned long seconds = 0; -	unsigned int options; -	long ret = -EINVAL; - -	switch (cmd) { -	case WDIOC_GETSUPPORT: -		if (copy_to_user(argp, &adx_wdt_info, sizeof(adx_wdt_info))) -			return -EFAULT; -		else -			return 0; - -	case WDIOC_GETSTATUS: -	case WDIOC_GETBOOTSTATUS: -		return put_user(0, p); - -	case WDIOC_KEEPALIVE: -		adx_wdt_keepalive(wdt); -		return 0; - -	case WDIOC_SETTIMEOUT: -		if (get_user(seconds, p)) -			return -EFAULT; - -		adx_wdt_set_timeout(wdt, seconds); - -		/* fallthrough */ -	case WDIOC_GETTIMEOUT: -		adx_wdt_get_timeout(wdt, &seconds); -		return put_user(seconds, p); - -	case WDIOC_SETOPTIONS: -		if (copy_from_user(&options, argp, sizeof(options))) -			return -EFAULT; - -		if (options & WDIOS_DISABLECARD) { -			adx_wdt_stop(wdt); -			ret = 0; -		} - -		if (options & WDIOS_ENABLECARD) { -			adx_wdt_start(wdt); -			ret = 0; -		} - -		return ret; - -	default: -		break; -	} - -	return -ENOTTY; -} - -static ssize_t adx_wdt_write(struct file *file, const char __user *data, -		size_t len, loff_t *ppos) -{ -	struct adx_wdt *wdt = file->private_data; - -	if (len) -		adx_wdt_keepalive(wdt); - -	return len; -} - -static const struct file_operations adx_wdt_fops = { -	.owner = THIS_MODULE, -	.llseek = no_llseek, -	.open = adx_wdt_open, -	.release = adx_wdt_release, -	.unlocked_ioctl = adx_wdt_ioctl, -	.write = adx_wdt_write, -}; - -static struct miscdevice adx_wdt_miscdev = { -	.minor = WATCHDOG_MINOR, -	.name = "watchdog", -	.fops = &adx_wdt_fops, -}; - -static int __devinit adx_wdt_probe(struct platform_device *pdev) -{ -	struct resource *res; -	struct adx_wdt *wdt; -	int ret = 0; -	u32 ctrl; - -	wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL); -	if (!wdt) { -		dev_err(&pdev->dev, "cannot allocate WDT structure\n"); -		return -ENOMEM; -	} - -	spin_lock_init(&wdt->lock); - -	res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -	if (!res) { -		dev_err(&pdev->dev, "cannot obtain I/O memory region\n"); -		return -ENXIO; -	} - -	res = devm_request_mem_region(&pdev->dev, res->start, -			resource_size(res), res->name); -	if (!res) { -		dev_err(&pdev->dev, "cannot request I/O memory region\n"); -		return -ENXIO; -	} - -	wdt->base = devm_ioremap_nocache(&pdev->dev, res->start, -			resource_size(res)); -	if (!wdt->base) { -		dev_err(&pdev->dev, "cannot remap I/O memory region\n"); -		return -ENXIO; -	} - -	/* disable watchdog and reboot on timeout */ -	ctrl = readl(wdt->base + ADX_WDT_CONTROL); -	ctrl &= ~ADX_WDT_CONTROL_ENABLE; -	ctrl &= ~ADX_WDT_CONTROL_nRESET; -	writel(ctrl, wdt->base + ADX_WDT_CONTROL); - -	platform_set_drvdata(pdev, wdt); -	adx_wdt_dev = pdev; - -	ret = misc_register(&adx_wdt_miscdev); -	if (ret) { -		dev_err(&pdev->dev, "cannot register miscdev on minor %d " -				"(err=%d)\n", WATCHDOG_MINOR, ret); -		return ret; -	} - -	return 0; -} - -static int __devexit adx_wdt_remove(struct platform_device *pdev) -{ -	struct adx_wdt *wdt = platform_get_drvdata(pdev); - -	misc_deregister(&adx_wdt_miscdev); -	adx_wdt_stop(wdt); -	platform_set_drvdata(pdev, NULL); - -	return 0; -} - -static void adx_wdt_shutdown(struct platform_device *pdev) -{ -	struct adx_wdt *wdt = platform_get_drvdata(pdev); -	adx_wdt_stop(wdt); -} - -#ifdef CONFIG_PM -static int adx_wdt_suspend(struct device *dev) -{ -	struct platform_device *pdev = to_platform_device(dev); -	struct adx_wdt *wdt = platform_get_drvdata(pdev); - -	wdt->wake = (wdt->state == WDT_STATE_START) ? 1 : 0; -	adx_wdt_stop(wdt); - -	return 0; -} - -static int adx_wdt_resume(struct device *dev) -{ -	struct platform_device *pdev = to_platform_device(dev); -	struct adx_wdt *wdt = platform_get_drvdata(pdev); - -	if (wdt->wake) -		adx_wdt_start(wdt); - -	return 0; -} - -static const struct dev_pm_ops adx_wdt_pm_ops = { -	.suspend = adx_wdt_suspend, -	.resume = adx_wdt_resume, -}; - -#  define ADX_WDT_PM_OPS	(&adx_wdt_pm_ops) -#else -#  define ADX_WDT_PM_OPS	NULL -#endif - -static struct platform_driver adx_wdt_driver = { -	.probe = adx_wdt_probe, -	.remove = __devexit_p(adx_wdt_remove), -	.shutdown = adx_wdt_shutdown, -	.driver = { -		.name = WATCHDOG_NAME, -		.owner = THIS_MODULE, -		.pm = ADX_WDT_PM_OPS, -	}, -}; - -static int __init adx_wdt_init(void) -{ -	return platform_driver_register(&adx_wdt_driver); -} - -static void __exit adx_wdt_exit(void) -{ -	platform_driver_unregister(&adx_wdt_driver); -} - -module_init(adx_wdt_init); -module_exit(adx_wdt_exit); - -MODULE_DESCRIPTION("Avionic Design Xanthos Watchdog Driver"); -MODULE_LICENSE("GPL v2"); -MODULE_AUTHOR("Thierry Reding <thierry.reding@avionic-design.de>"); -MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c index 5de7e4fa5b8..a79e3840782 100644 --- a/drivers/watchdog/s3c2410_wdt.c +++ b/drivers/watchdog/s3c2410_wdt.c @@ -401,8 +401,8 @@ static int __devinit s3c2410wdt_probe(struct platform_device *pdev)  	dev_info(dev, "watchdog %sactive, reset %sabled, irq %sabled\n",  		 (wtcon & S3C2410_WTCON_ENABLE) ?  "" : "in", -		 (wtcon & S3C2410_WTCON_RSTEN) ? "" : "dis", -		 (wtcon & S3C2410_WTCON_INTEN) ? "" : "en"); +		 (wtcon & S3C2410_WTCON_RSTEN) ? "en" : "dis", +		 (wtcon & S3C2410_WTCON_INTEN) ? "en" : "dis");  	return 0; diff --git a/drivers/watchdog/wm831x_wdt.c b/drivers/watchdog/wm831x_wdt.c index 7be38556aed..e789a47db41 100644 --- a/drivers/watchdog/wm831x_wdt.c +++ b/drivers/watchdog/wm831x_wdt.c @@ -150,7 +150,7 @@ static int wm831x_wdt_set_timeout(struct watchdog_device *wdt_dev,  		if (wm831x_wdt_cfgs[i].time == timeout)  			break;  	if (i == ARRAY_SIZE(wm831x_wdt_cfgs)) -		ret = -EINVAL; +		return -EINVAL;  	ret = wm831x_reg_unlock(wm831x);  	if (ret == 0) { diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c index a767884a6c7..31ab82fda38 100644 --- a/drivers/xen/balloon.c +++ b/drivers/xen/balloon.c @@ -501,7 +501,7 @@ EXPORT_SYMBOL_GPL(balloon_set_new_target);   * alloc_xenballooned_pages - get pages that have been ballooned out   * @nr_pages: Number of pages to get   * @pages: pages returned - * @highmem: highmem or lowmem pages + * @highmem: allow highmem pages   * @return 0 on success, error otherwise   */  int alloc_xenballooned_pages(int nr_pages, struct page **pages, bool highmem) @@ -511,7 +511,7 @@ int alloc_xenballooned_pages(int nr_pages, struct page **pages, bool highmem)  	mutex_lock(&balloon_mutex);  	while (pgno < nr_pages) {  		page = balloon_retrieve(highmem); -		if (page && PageHighMem(page) == highmem) { +		if (page && (highmem || !PageHighMem(page))) {  			pages[pgno++] = page;  		} else {  			enum bp_state st; diff --git a/drivers/xen/gntalloc.c b/drivers/xen/gntalloc.c index f6832f46aea..e1c4c6e5b46 100644 --- a/drivers/xen/gntalloc.c +++ b/drivers/xen/gntalloc.c @@ -135,7 +135,7 @@ static int add_grefs(struct ioctl_gntalloc_alloc_gref *op,  		/* Grant foreign access to the page. */  		gref->gref_id = gnttab_grant_foreign_access(op->domid,  			pfn_to_mfn(page_to_pfn(gref->page)), readonly); -		if (gref->gref_id < 0) { +		if ((int)gref->gref_id < 0) {  			rc = gref->gref_id;  			goto undo;  		} @@ -280,7 +280,7 @@ static long gntalloc_ioctl_alloc(struct gntalloc_file_private_data *priv,  		goto out;  	} -	gref_ids = kzalloc(sizeof(gref_ids[0]) * op.count, GFP_TEMPORARY); +	gref_ids = kcalloc(op.count, sizeof(gref_ids[0]), GFP_TEMPORARY);  	if (!gref_ids) {  		rc = -ENOMEM;  		goto out; diff --git a/drivers/xen/gntdev.c b/drivers/xen/gntdev.c index 39871326afa..afca14d9042 100644 --- a/drivers/xen/gntdev.c +++ b/drivers/xen/gntdev.c @@ -114,11 +114,11 @@ static struct grant_map *gntdev_alloc_map(struct gntdev_priv *priv, int count)  	if (NULL == add)  		return NULL; -	add->grants    = kzalloc(sizeof(add->grants[0])    * count, GFP_KERNEL); -	add->map_ops   = kzalloc(sizeof(add->map_ops[0])   * count, GFP_KERNEL); -	add->unmap_ops = kzalloc(sizeof(add->unmap_ops[0]) * count, GFP_KERNEL); -	add->kmap_ops  = kzalloc(sizeof(add->kmap_ops[0])  * count, GFP_KERNEL); -	add->pages     = kzalloc(sizeof(add->pages[0])     * count, GFP_KERNEL); +	add->grants    = kcalloc(count, sizeof(add->grants[0]), GFP_KERNEL); +	add->map_ops   = kcalloc(count, sizeof(add->map_ops[0]), GFP_KERNEL); +	add->unmap_ops = kcalloc(count, sizeof(add->unmap_ops[0]), GFP_KERNEL); +	add->kmap_ops  = kcalloc(count, sizeof(add->kmap_ops[0]), GFP_KERNEL); +	add->pages     = kcalloc(count, sizeof(add->pages[0]), GFP_KERNEL);  	if (NULL == add->grants    ||  	    NULL == add->map_ops   ||  	    NULL == add->unmap_ops || diff --git a/drivers/xen/xenbus/xenbus_client.c b/drivers/xen/xenbus/xenbus_client.c index 81c3ce6b8bb..1906125eab4 100644 --- a/drivers/xen/xenbus/xenbus_client.c +++ b/drivers/xen/xenbus/xenbus_client.c @@ -35,6 +35,7 @@  #include <linux/vmalloc.h>  #include <linux/export.h>  #include <asm/xen/hypervisor.h> +#include <asm/xen/page.h>  #include <xen/interface/xen.h>  #include <xen/interface/event_channel.h>  #include <xen/events.h> @@ -436,19 +437,20 @@ EXPORT_SYMBOL_GPL(xenbus_free_evtchn);  int xenbus_map_ring_valloc(struct xenbus_device *dev, int gnt_ref, void **vaddr)  {  	struct gnttab_map_grant_ref op = { -		.flags = GNTMAP_host_map, +		.flags = GNTMAP_host_map | GNTMAP_contains_pte,  		.ref   = gnt_ref,  		.dom   = dev->otherend_id,  	};  	struct vm_struct *area; +	pte_t *pte;  	*vaddr = NULL; -	area = alloc_vm_area(PAGE_SIZE); +	area = alloc_vm_area(PAGE_SIZE, &pte);  	if (!area)  		return -ENOMEM; -	op.host_addr = (unsigned long)area->addr; +	op.host_addr = arbitrary_virt_to_machine(pte).maddr;  	if (HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1))  		BUG(); @@ -527,6 +529,7 @@ int xenbus_unmap_ring_vfree(struct xenbus_device *dev, void *vaddr)  	struct gnttab_unmap_grant_ref op = {  		.host_addr = (unsigned long)vaddr,  	}; +	unsigned int level;  	/* It'd be nice if linux/vmalloc.h provided a find_vm_area(void *addr)  	 * method so that we don't have to muck with vmalloc internals here. @@ -548,6 +551,8 @@ int xenbus_unmap_ring_vfree(struct xenbus_device *dev, void *vaddr)  	}  	op.handle = (grant_handle_t)area->phys_addr; +	op.host_addr = arbitrary_virt_to_machine( +		lookup_address((unsigned long)vaddr, &level)).maddr;  	if (HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1))  		BUG();  |