diff options
Diffstat (limited to 'drivers')
87 files changed, 726 insertions, 475 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..ec555951176 100644 --- a/drivers/ata/ahci_platform.c +++ b/drivers/ata/ahci_platform.c @@ -65,7 +65,7 @@ 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];  	const struct ata_port_info *ppi[] = { &pi, NULL }; @@ -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/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/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/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/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/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..405c63b9d53 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -2118,8 +2118,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..68b756253f9 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -407,13 +407,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; @@ -1125,6 +1128,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 +1209,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..4f40f1ce1d8 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -1506,7 +1506,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..e9c2cfe45da 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -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_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 6651c36b6e8..d18b07adcff 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) { 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/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/radeon.h b/drivers/gpu/drm/radeon/radeon.h index b316b301152..fc5a1d642cb 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -784,8 +784,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 +854,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 +1144,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 +1241,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..d2d179267af 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c @@ -1999,6 +1999,10 @@ static int radeon_atombios_parse_power_table_1_3(struct radeon_device *rdev)  		rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE;  		switch (frev) {  		case 1: +			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].mclk =  				le16_to_cpu(power_info->info.asPowerPlayInfo[i].usMemoryClock); @@ -2035,6 +2039,10 @@ static int radeon_atombios_parse_power_table_1_3(struct radeon_device *rdev)  			state_index++;  			break;  		case 2: +			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].mclk =  				le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMemoryClock); @@ -2072,6 +2080,10 @@ static int radeon_atombios_parse_power_table_1_3(struct radeon_device *rdev)  			state_index++;  			break;  		case 3: +			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].mclk =  				le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMemoryClock); @@ -2257,7 +2269,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 +2389,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 +2482,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 +2564,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..ccaa243c144 100644 --- a/drivers/gpu/drm/radeon/radeon_cs.c +++ b/drivers/gpu/drm/radeon/radeon_cs.c @@ -222,7 +222,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 +233,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 +248,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 +260,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 +275,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_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/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/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/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/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/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/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/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/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/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/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/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/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/virtio/virtio_pci.c b/drivers/virtio/virtio_pci.c index 79a31e5b4b6..3d1bf41e889 100644 --- a/drivers/virtio/virtio_pci.c +++ b/drivers/virtio/virtio_pci.c @@ -594,11 +594,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 +686,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  |