diff options
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/ata/sata_fsl.c | 25 | ||||
| -rw-r--r-- | drivers/macintosh/rack-meter.c | 2 | ||||
| -rw-r--r-- | drivers/tty/hvc/hvcs.c | 74 | ||||
| -rw-r--r-- | drivers/tty/serial/ucc_uart.c | 67 | 
4 files changed, 97 insertions, 71 deletions
diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c index ef3ce26bb1f..0f91e583892 100644 --- a/drivers/ata/sata_fsl.c +++ b/drivers/ata/sata_fsl.c @@ -6,7 +6,7 @@   * Author: Ashish Kalra <ashish.kalra@freescale.com>   * Li Yang <leoli@freescale.com>   * - * Copyright (c) 2006-2007 Freescale Semiconductor, Inc. + * Copyright (c) 2006-2007, 2011 Freescale Semiconductor, Inc.   *   * This program is free software; you can redistribute  it and/or modify it   * under  the terms of  the GNU General  Public License as published by the @@ -157,7 +157,8 @@ enum {  	    IE_ON_SINGL_DEVICE_ERR | IE_ON_CMD_COMPLETE,  	EXT_INDIRECT_SEG_PRD_FLAG = (1 << 31), -	DATA_SNOOP_ENABLE = (1 << 22), +	DATA_SNOOP_ENABLE_V1 = (1 << 22), +	DATA_SNOOP_ENABLE_V2 = (1 << 28),  };  /* @@ -260,6 +261,7 @@ struct sata_fsl_host_priv {  	void __iomem *ssr_base;  	void __iomem *csr_base;  	int irq; +	int data_snoop;  };  static inline unsigned int sata_fsl_tag(unsigned int tag, @@ -312,7 +314,8 @@ static void sata_fsl_setup_cmd_hdr_entry(struct sata_fsl_port_priv *pp,  }  static unsigned int sata_fsl_fill_sg(struct ata_queued_cmd *qc, void *cmd_desc, -				     u32 *ttl, dma_addr_t cmd_desc_paddr) +				     u32 *ttl, dma_addr_t cmd_desc_paddr, +				     int data_snoop)  {  	struct scatterlist *sg;  	unsigned int num_prde = 0; @@ -362,8 +365,7 @@ static unsigned int sata_fsl_fill_sg(struct ata_queued_cmd *qc, void *cmd_desc,  		ttl_dwords += sg_len;  		prd->dba = cpu_to_le32(sg_addr); -		prd->ddc_and_ext = -		    cpu_to_le32(DATA_SNOOP_ENABLE | (sg_len & ~0x03)); +		prd->ddc_and_ext = cpu_to_le32(data_snoop | (sg_len & ~0x03));  		VPRINTK("sg_fill, ttl=%d, dba=0x%x, ddc=0x%x\n",  			ttl_dwords, prd->dba, prd->ddc_and_ext); @@ -378,7 +380,7 @@ static unsigned int sata_fsl_fill_sg(struct ata_queued_cmd *qc, void *cmd_desc,  		/* set indirect extension flag along with indirect ext. size */  		prd_ptr_to_indirect_ext->ddc_and_ext =  		    cpu_to_le32((EXT_INDIRECT_SEG_PRD_FLAG | -				 DATA_SNOOP_ENABLE | +				 data_snoop |  				 (indirect_ext_segment_sz & ~0x03)));  	} @@ -421,7 +423,8 @@ static void sata_fsl_qc_prep(struct ata_queued_cmd *qc)  	if (qc->flags & ATA_QCFLAG_DMAMAP)  		num_prde = sata_fsl_fill_sg(qc, (void *)cd, -					    &ttl_dwords, cd_paddr); +					    &ttl_dwords, cd_paddr, +					    host_priv->data_snoop);  	if (qc->tf.protocol == ATA_PROT_NCQ)  		desc_info |= FPDMA_QUEUED_CMD; @@ -1349,6 +1352,11 @@ static int sata_fsl_probe(struct platform_device *ofdev)  	}  	host_priv->irq = irq; +	if (of_device_is_compatible(ofdev->dev.of_node, "fsl,pq-sata-v2")) +		host_priv->data_snoop = DATA_SNOOP_ENABLE_V2; +	else +		host_priv->data_snoop = DATA_SNOOP_ENABLE_V1; +  	/* allocate host structure */  	host = ata_host_alloc_pinfo(&ofdev->dev, ppi, SATA_FSL_MAX_PORTS); @@ -1431,6 +1439,9 @@ static struct of_device_id fsl_sata_match[] = {  	{  		.compatible = "fsl,pq-sata",  	}, +	{ +		.compatible = "fsl,pq-sata-v2", +	},  	{},  }; diff --git a/drivers/macintosh/rack-meter.c b/drivers/macintosh/rack-meter.c index 39f660b2a60..2637c139777 100644 --- a/drivers/macintosh/rack-meter.c +++ b/drivers/macintosh/rack-meter.c @@ -283,7 +283,7 @@ static void __devinit rackmeter_init_cpu_sniffer(struct rackmeter *rm)  	}  } -static void __devexit rackmeter_stop_cpu_sniffer(struct rackmeter *rm) +static void rackmeter_stop_cpu_sniffer(struct rackmeter *rm)  {  	cancel_delayed_work_sync(&rm->cpu[0].sniffer);  	cancel_delayed_work_sync(&rm->cpu[1].sniffer); diff --git a/drivers/tty/hvc/hvcs.c b/drivers/tty/hvc/hvcs.c index bedc6c1b6fa..7e315b7f870 100644 --- a/drivers/tty/hvc/hvcs.c +++ b/drivers/tty/hvc/hvcs.c @@ -309,6 +309,7 @@ struct hvcs_struct {  static LIST_HEAD(hvcs_structs);  static DEFINE_SPINLOCK(hvcs_structs_lock); +static DEFINE_MUTEX(hvcs_init_mutex);  static void hvcs_unthrottle(struct tty_struct *tty);  static void hvcs_throttle(struct tty_struct *tty); @@ -340,6 +341,7 @@ static int __devinit hvcs_probe(struct vio_dev *dev,  static int __devexit hvcs_remove(struct vio_dev *dev);  static int __init hvcs_module_init(void);  static void __exit hvcs_module_exit(void); +static int __devinit hvcs_initialize(void);  #define HVCS_SCHED_READ	0x00000001  #define HVCS_QUICK_READ	0x00000002 @@ -762,7 +764,7 @@ static int __devinit hvcs_probe(  	const struct vio_device_id *id)  {  	struct hvcs_struct *hvcsd; -	int index; +	int index, rc;  	int retval;  	if (!dev || !id) { @@ -770,6 +772,13 @@ static int __devinit hvcs_probe(  		return -EPERM;  	} +	/* Make sure we are properly initialized */ +	rc = hvcs_initialize(); +	if (rc) { +		pr_err("HVCS: Failed to initialize core driver.\n"); +		return rc; +	} +  	/* early to avoid cleanup on failure */  	index = hvcs_get_index();  	if (index < 0) { @@ -1464,12 +1473,15 @@ static void hvcs_free_index_list(void)  	hvcs_index_count = 0;  } -static int __init hvcs_module_init(void) +static int __devinit hvcs_initialize(void)  { -	int rc; -	int num_ttys_to_alloc; +	int rc, num_ttys_to_alloc; -	printk(KERN_INFO "Initializing %s\n", hvcs_driver_string); +	mutex_lock(&hvcs_init_mutex); +	if (hvcs_task) { +		mutex_unlock(&hvcs_init_mutex); +		return 0; +	}  	/* Has the user specified an overload with an insmod param? */  	if (hvcs_parm_num_devs <= 0 || @@ -1528,35 +1540,13 @@ static int __init hvcs_module_init(void)  	hvcs_task = kthread_run(khvcsd, NULL, "khvcsd");  	if (IS_ERR(hvcs_task)) { -		printk(KERN_ERR "HVCS: khvcsd creation failed.  Driver not loaded.\n"); +		printk(KERN_ERR "HVCS: khvcsd creation failed.\n");  		rc = -EIO;  		goto kthread_fail;  	} - -	rc = vio_register_driver(&hvcs_vio_driver); -	if (rc) { -		printk(KERN_ERR "HVCS: can't register vio driver\n"); -		goto vio_fail; -	} - -	/* -	 * This needs to be done AFTER the vio_register_driver() call or else -	 * the kobjects won't be initialized properly. -	 */ -	rc = driver_create_file(&(hvcs_vio_driver.driver), &driver_attr_rescan); -	if (rc) { -		printk(KERN_ERR "HVCS: sysfs attr create failed\n"); -		goto attr_fail; -	} - -	printk(KERN_INFO "HVCS: driver module inserted.\n"); - +	mutex_unlock(&hvcs_init_mutex);  	return 0; -attr_fail: -	vio_unregister_driver(&hvcs_vio_driver); -vio_fail: -	kthread_stop(hvcs_task);  kthread_fail:  	kfree(hvcs_pi_buff);  buff_alloc_fail: @@ -1566,15 +1556,39 @@ register_fail:  index_fail:  	put_tty_driver(hvcs_tty_driver);  	hvcs_tty_driver = NULL; +	mutex_unlock(&hvcs_init_mutex);  	return rc;  } +static int __init hvcs_module_init(void) +{ +	int rc = vio_register_driver(&hvcs_vio_driver); +	if (rc) { +		printk(KERN_ERR "HVCS: can't register vio driver\n"); +		return rc; +	} + +	pr_info("HVCS: Driver registered.\n"); + +	/* This needs to be done AFTER the vio_register_driver() call or else +	 * the kobjects won't be initialized properly. +	 */ +	rc = driver_create_file(&(hvcs_vio_driver.driver), &driver_attr_rescan); +	if (rc) +		pr_warning(KERN_ERR "HVCS: Failed to create rescan file (err %d)\n", rc); + +	return 0; +} +  static void __exit hvcs_module_exit(void)  {  	/*  	 * This driver receives hvcs_remove callbacks for each device upon  	 * module removal.  	 */ +	vio_unregister_driver(&hvcs_vio_driver); +	if (!hvcs_task) +		return;  	/*  	 * This synchronous operation  will wake the khvcsd kthread if it is @@ -1589,8 +1603,6 @@ static void __exit hvcs_module_exit(void)  	driver_remove_file(&hvcs_vio_driver.driver, &driver_attr_rescan); -	vio_unregister_driver(&hvcs_vio_driver); -  	tty_unregister_driver(hvcs_tty_driver);  	hvcs_free_index_list(); diff --git a/drivers/tty/serial/ucc_uart.c b/drivers/tty/serial/ucc_uart.c index ff51dae1df0..c327218cad4 100644 --- a/drivers/tty/serial/ucc_uart.c +++ b/drivers/tty/serial/ucc_uart.c @@ -1269,13 +1269,12 @@ static int ucc_uart_probe(struct platform_device *ofdev)  	ret = of_address_to_resource(np, 0, &res);  	if (ret) {  		dev_err(&ofdev->dev, "missing 'reg' property in device tree\n"); -		kfree(qe_port); -		return ret; +		goto out_free;  	}  	if (!res.start) {  		dev_err(&ofdev->dev, "invalid 'reg' property in device tree\n"); -		kfree(qe_port); -		return -EINVAL; +		ret = -EINVAL; +		goto out_free;  	}  	qe_port->port.mapbase = res.start; @@ -1285,17 +1284,17 @@ static int ucc_uart_probe(struct platform_device *ofdev)  	if (!iprop) {  		iprop = of_get_property(np, "device-id", NULL);  		if (!iprop) { -			kfree(qe_port);  			dev_err(&ofdev->dev, "UCC is unspecified in "  				"device tree\n"); -			return -EINVAL; +			ret = -EINVAL; +			goto out_free;  		}  	}  	if ((*iprop < 1) || (*iprop > UCC_MAX_NUM)) {  		dev_err(&ofdev->dev, "no support for UCC%u\n", *iprop); -		kfree(qe_port); -		return -ENODEV; +		ret = -ENODEV; +		goto out_free;  	}  	qe_port->ucc_num = *iprop - 1; @@ -1309,16 +1308,16 @@ static int ucc_uart_probe(struct platform_device *ofdev)  	sprop = of_get_property(np, "rx-clock-name", NULL);  	if (!sprop) {  		dev_err(&ofdev->dev, "missing rx-clock-name in device tree\n"); -		kfree(qe_port); -		return -ENODEV; +		ret = -ENODEV; +		goto out_free;  	}  	qe_port->us_info.rx_clock = qe_clock_source(sprop);  	if ((qe_port->us_info.rx_clock < QE_BRG1) ||  	    (qe_port->us_info.rx_clock > QE_BRG16)) {  		dev_err(&ofdev->dev, "rx-clock-name must be a BRG for UART\n"); -		kfree(qe_port); -		return -ENODEV; +		ret = -ENODEV; +		goto out_free;  	}  #ifdef LOOPBACK @@ -1328,39 +1327,39 @@ static int ucc_uart_probe(struct platform_device *ofdev)  	sprop = of_get_property(np, "tx-clock-name", NULL);  	if (!sprop) {  		dev_err(&ofdev->dev, "missing tx-clock-name in device tree\n"); -		kfree(qe_port); -		return -ENODEV; +		ret = -ENODEV; +		goto out_free;  	}  	qe_port->us_info.tx_clock = qe_clock_source(sprop);  #endif  	if ((qe_port->us_info.tx_clock < QE_BRG1) ||  	    (qe_port->us_info.tx_clock > QE_BRG16)) {  		dev_err(&ofdev->dev, "tx-clock-name must be a BRG for UART\n"); -		kfree(qe_port); -		return -ENODEV; +		ret = -ENODEV; +		goto out_free;  	}  	/* Get the port number, numbered 0-3 */  	iprop = of_get_property(np, "port-number", NULL);  	if (!iprop) {  		dev_err(&ofdev->dev, "missing port-number in device tree\n"); -		kfree(qe_port); -		return -EINVAL; +		ret = -EINVAL; +		goto out_free;  	}  	qe_port->port.line = *iprop;  	if (qe_port->port.line >= UCC_MAX_UART) {  		dev_err(&ofdev->dev, "port-number must be 0-%u\n",  			UCC_MAX_UART - 1); -		kfree(qe_port); -		return -EINVAL; +		ret = -EINVAL; +		goto out_free;  	}  	qe_port->port.irq = irq_of_parse_and_map(np, 0);  	if (qe_port->port.irq == NO_IRQ) {  		dev_err(&ofdev->dev, "could not map IRQ for UCC%u\n",  		       qe_port->ucc_num + 1); -		kfree(qe_port); -		return -EINVAL; +		ret = -EINVAL; +		goto out_free;  	}  	/* @@ -1372,8 +1371,8 @@ static int ucc_uart_probe(struct platform_device *ofdev)  		np = of_find_node_by_type(NULL, "qe");  		if (!np) {  			dev_err(&ofdev->dev, "could not find 'qe' node\n"); -			kfree(qe_port); -			return -EINVAL; +			ret = -EINVAL; +			goto out_free;  		}  	} @@ -1381,8 +1380,8 @@ static int ucc_uart_probe(struct platform_device *ofdev)  	if (!iprop) {  		dev_err(&ofdev->dev,  		       "missing brg-frequency in device tree\n"); -		kfree(qe_port); -		return -EINVAL; +		ret = -EINVAL; +		goto out_np;  	}  	if (*iprop) @@ -1397,16 +1396,16 @@ static int ucc_uart_probe(struct platform_device *ofdev)  		if (!iprop) {  			dev_err(&ofdev->dev,  				"missing QE bus-frequency in device tree\n"); -			kfree(qe_port); -			return -EINVAL; +			ret = -EINVAL; +			goto out_np;  		}  		if (*iprop)  			qe_port->port.uartclk = *iprop / 2;  		else {  			dev_err(&ofdev->dev,  				"invalid QE bus-frequency in device tree\n"); -			kfree(qe_port); -			return -EINVAL; +			ret = -EINVAL; +			goto out_np;  		}  	} @@ -1444,8 +1443,7 @@ static int ucc_uart_probe(struct platform_device *ofdev)  	if (ret) {  		dev_err(&ofdev->dev, "could not add /dev/ttyQE%u\n",  		       qe_port->port.line); -		kfree(qe_port); -		return ret; +		goto out_np;  	}  	dev_set_drvdata(&ofdev->dev, qe_port); @@ -1459,6 +1457,11 @@ static int ucc_uart_probe(struct platform_device *ofdev)  	       SERIAL_QE_MINOR + qe_port->port.line);  	return 0; +out_np: +	of_node_put(np); +out_free: +	kfree(qe_port); +	return ret;  }  static int ucc_uart_remove(struct platform_device *ofdev)  |