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 ef3ce26bb1f0..0f91e583892e 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 39f660b2a60d..2637c139777b 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 bedc6c1b6fa5..7e315b7f8700 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 ff51dae1df0c..c327218cad44 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) |