mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-29 11:11:45 -04:00
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc
* 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc: (62 commits) powerpc/85xx: Fix signedness bug in cache-sram powerpc/fsl: 85xx: document cache sram bindings powerpc/fsl: define binding for fsl mpic interrupt controllers powerpc/fsl_msi: Handle msi-available-ranges better drivers/serial/ucc_uart.c: Add of_node_put to avoid memory leak powerpc/85xx: Fix SPE float to integer conversion failure powerpc/85xx: Update sata controller compatible for p1022ds board ATA: Add FSL sata v2 controller support powerpc/mpc8xxx_gpio: simplify searching for 'fsl, qoriq-gpio' compatiable powerpc/8xx: remove obsolete mgsuvd board powerpc/82xx: rename and update mgcoge board support powerpc/83xx: rename and update kmeter1 powerpc/85xx: Workaroudn e500 CPU erratum A005 powerpc/fsl_pci: Add support for FSL PCIe controllers v2.x powerpc/85xx: Fix writing to spin table 'cpu-release-addr' on ppc64e powerpc/pseries: Disable MSI using new interface if possible powerpc: Enable GENERIC_HARDIRQS_NO_DEPRECATED. powerpc: core irq_data conversion. powerpc: sysdev/xilinx_intc irq_data conversion. powerpc: sysdev/uic irq_data conversion. ... Fix up conflicts in arch/powerpc/sysdev/fsl_msi.c (due to getting rid of of_platform_driver in arch/powerpc)
This commit is contained in:
commit
0a95d92c00
101 changed files with 2437 additions and 1394 deletions
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Reference in a new issue