mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-29 03:01:39 -04:00
Merge tag 'zynq-clk-for-3.11' of git://git.xilinx.com/linux-xlnx into next/soc
From Michal Simek: arm: Xilinx Zynq clock changes for v3.11 Change Xilinx Zynq DT clock description which reflects logical abstraction of Zynq's clock tree. - Refactor PLL driver - Use new clock controller driver - Change timer and uart drivers * tag 'zynq-clk-for-3.11' of git://git.xilinx.com/linux-xlnx: clk: zynq: Remove deprecated clock code arm: zynq: Migrate platform to clock controller clk: zynq: Add clock controller driver clk: zynq: Factor out PLL driver Signed-off-by: Olof Johansson <[email protected]>
This commit is contained in:
commit
e56c60c374
12 changed files with 972 additions and 495 deletions
|
|
@ -14,6 +14,7 @@
|
|||
#include <linux/platform_device.h>
|
||||
#include <linux/serial.h>
|
||||
#include <linux/serial_core.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/tty.h>
|
||||
#include <linux/tty_flip.h>
|
||||
#include <linux/console.h>
|
||||
|
|
@ -138,6 +139,16 @@
|
|||
#define XUARTPS_SR_TXFULL 0x00000010 /* TX FIFO full */
|
||||
#define XUARTPS_SR_RXTRIG 0x00000001 /* Rx Trigger */
|
||||
|
||||
/**
|
||||
* struct xuartps - device data
|
||||
* @refclk Reference clock
|
||||
* @aperclk APB clock
|
||||
*/
|
||||
struct xuartps {
|
||||
struct clk *refclk;
|
||||
struct clk *aperclk;
|
||||
};
|
||||
|
||||
/**
|
||||
* xuartps_isr - Interrupt handler
|
||||
* @irq: Irq number
|
||||
|
|
@ -936,34 +947,55 @@ static int xuartps_probe(struct platform_device *pdev)
|
|||
int rc;
|
||||
struct uart_port *port;
|
||||
struct resource *res, *res2;
|
||||
struct clk *clk;
|
||||
struct xuartps *xuartps_data;
|
||||
|
||||
clk = of_clk_get(pdev->dev.of_node, 0);
|
||||
if (IS_ERR(clk)) {
|
||||
dev_err(&pdev->dev, "no clock specified\n");
|
||||
return PTR_ERR(clk);
|
||||
xuartps_data = kzalloc(sizeof(*xuartps_data), GFP_KERNEL);
|
||||
if (!xuartps_data)
|
||||
return -ENOMEM;
|
||||
|
||||
xuartps_data->aperclk = clk_get(&pdev->dev, "aper_clk");
|
||||
if (IS_ERR(xuartps_data->aperclk)) {
|
||||
dev_err(&pdev->dev, "aper_clk clock not found.\n");
|
||||
rc = PTR_ERR(xuartps_data->aperclk);
|
||||
goto err_out_free;
|
||||
}
|
||||
xuartps_data->refclk = clk_get(&pdev->dev, "ref_clk");
|
||||
if (IS_ERR(xuartps_data->refclk)) {
|
||||
dev_err(&pdev->dev, "ref_clk clock not found.\n");
|
||||
rc = PTR_ERR(xuartps_data->refclk);
|
||||
goto err_out_clk_put_aper;
|
||||
}
|
||||
|
||||
rc = clk_prepare_enable(clk);
|
||||
rc = clk_prepare_enable(xuartps_data->aperclk);
|
||||
if (rc) {
|
||||
dev_err(&pdev->dev, "could not enable clock\n");
|
||||
return -EBUSY;
|
||||
dev_err(&pdev->dev, "Unable to enable APER clock.\n");
|
||||
goto err_out_clk_put;
|
||||
}
|
||||
rc = clk_prepare_enable(xuartps_data->refclk);
|
||||
if (rc) {
|
||||
dev_err(&pdev->dev, "Unable to enable device clock.\n");
|
||||
goto err_out_clk_dis_aper;
|
||||
}
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!res)
|
||||
return -ENODEV;
|
||||
if (!res) {
|
||||
rc = -ENODEV;
|
||||
goto err_out_clk_disable;
|
||||
}
|
||||
|
||||
res2 = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
|
||||
if (!res2)
|
||||
return -ENODEV;
|
||||
if (!res2) {
|
||||
rc = -ENODEV;
|
||||
goto err_out_clk_disable;
|
||||
}
|
||||
|
||||
/* Initialize the port structure */
|
||||
port = xuartps_get_port();
|
||||
|
||||
if (!port) {
|
||||
dev_err(&pdev->dev, "Cannot get uart_port structure\n");
|
||||
return -ENODEV;
|
||||
rc = -ENODEV;
|
||||
goto err_out_clk_disable;
|
||||
} else {
|
||||
/* Register the port.
|
||||
* This function also registers this device with the tty layer
|
||||
|
|
@ -972,18 +1004,31 @@ static int xuartps_probe(struct platform_device *pdev)
|
|||
port->mapbase = res->start;
|
||||
port->irq = res2->start;
|
||||
port->dev = &pdev->dev;
|
||||
port->uartclk = clk_get_rate(clk);
|
||||
port->private_data = clk;
|
||||
port->uartclk = clk_get_rate(xuartps_data->refclk);
|
||||
port->private_data = xuartps_data;
|
||||
dev_set_drvdata(&pdev->dev, port);
|
||||
rc = uart_add_one_port(&xuartps_uart_driver, port);
|
||||
if (rc) {
|
||||
dev_err(&pdev->dev,
|
||||
"uart_add_one_port() failed; err=%i\n", rc);
|
||||
dev_set_drvdata(&pdev->dev, NULL);
|
||||
return rc;
|
||||
goto err_out_clk_disable;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
err_out_clk_disable:
|
||||
clk_disable_unprepare(xuartps_data->refclk);
|
||||
err_out_clk_dis_aper:
|
||||
clk_disable_unprepare(xuartps_data->aperclk);
|
||||
err_out_clk_put:
|
||||
clk_put(xuartps_data->refclk);
|
||||
err_out_clk_put_aper:
|
||||
clk_put(xuartps_data->aperclk);
|
||||
err_out_free:
|
||||
kfree(xuartps_data);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -995,14 +1040,18 @@ static int xuartps_probe(struct platform_device *pdev)
|
|||
static int xuartps_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct uart_port *port = dev_get_drvdata(&pdev->dev);
|
||||
struct clk *clk = port->private_data;
|
||||
struct xuartps *xuartps_data = port->private_data;
|
||||
int rc;
|
||||
|
||||
/* Remove the xuartps port from the serial core */
|
||||
rc = uart_remove_one_port(&xuartps_uart_driver, port);
|
||||
dev_set_drvdata(&pdev->dev, NULL);
|
||||
port->mapbase = 0;
|
||||
clk_disable_unprepare(clk);
|
||||
clk_disable_unprepare(xuartps_data->refclk);
|
||||
clk_disable_unprepare(xuartps_data->aperclk);
|
||||
clk_put(xuartps_data->refclk);
|
||||
clk_put(xuartps_data->aperclk);
|
||||
kfree(xuartps_data);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue