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:
Olof Johansson 2013-06-07 17:01:42 -07:00
commit e56c60c374
12 changed files with 972 additions and 495 deletions

View file

@ -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;
}