diff options
author | Olof Johansson <olof@lixom.net> | 2013-06-07 20:01:42 -0400 |
---|---|---|
committer | Olof Johansson <olof@lixom.net> | 2013-06-07 21:21:51 -0400 |
commit | e56c60c374bbcd343ed286c713116056bf3d6d36 (patch) | |
tree | 287370ef948fbd7b9dc45c54e7ed7d384258dd26 /drivers/tty | |
parent | f49024926236068bc3fe6848aaf87b914049013a (diff) | |
parent | 97c4e87d45498fb4d18c995721bba72345a7d257 (diff) |
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 <olof@lixom.net>
Diffstat (limited to 'drivers/tty')
-rw-r--r-- | drivers/tty/serial/xilinx_uartps.c | 85 |
1 files changed, 67 insertions, 18 deletions
diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c index 4e5c77834c50..a4a3028103e3 100644 --- a/drivers/tty/serial/xilinx_uartps.c +++ b/drivers/tty/serial/xilinx_uartps.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/platform_device.h> | 14 | #include <linux/platform_device.h> |
15 | #include <linux/serial.h> | 15 | #include <linux/serial.h> |
16 | #include <linux/serial_core.h> | 16 | #include <linux/serial_core.h> |
17 | #include <linux/slab.h> | ||
17 | #include <linux/tty.h> | 18 | #include <linux/tty.h> |
18 | #include <linux/tty_flip.h> | 19 | #include <linux/tty_flip.h> |
19 | #include <linux/console.h> | 20 | #include <linux/console.h> |
@@ -139,6 +140,16 @@ | |||
139 | #define XUARTPS_SR_RXTRIG 0x00000001 /* Rx Trigger */ | 140 | #define XUARTPS_SR_RXTRIG 0x00000001 /* Rx Trigger */ |
140 | 141 | ||
141 | /** | 142 | /** |
143 | * struct xuartps - device data | ||
144 | * @refclk Reference clock | ||
145 | * @aperclk APB clock | ||
146 | */ | ||
147 | struct xuartps { | ||
148 | struct clk *refclk; | ||
149 | struct clk *aperclk; | ||
150 | }; | ||
151 | |||
152 | /** | ||
142 | * xuartps_isr - Interrupt handler | 153 | * xuartps_isr - Interrupt handler |
143 | * @irq: Irq number | 154 | * @irq: Irq number |
144 | * @dev_id: Id of the port | 155 | * @dev_id: Id of the port |
@@ -936,34 +947,55 @@ static int xuartps_probe(struct platform_device *pdev) | |||
936 | int rc; | 947 | int rc; |
937 | struct uart_port *port; | 948 | struct uart_port *port; |
938 | struct resource *res, *res2; | 949 | struct resource *res, *res2; |
939 | struct clk *clk; | 950 | struct xuartps *xuartps_data; |
940 | 951 | ||
941 | clk = of_clk_get(pdev->dev.of_node, 0); | 952 | xuartps_data = kzalloc(sizeof(*xuartps_data), GFP_KERNEL); |
942 | if (IS_ERR(clk)) { | 953 | if (!xuartps_data) |
943 | dev_err(&pdev->dev, "no clock specified\n"); | 954 | return -ENOMEM; |
944 | return PTR_ERR(clk); | 955 | |
956 | xuartps_data->aperclk = clk_get(&pdev->dev, "aper_clk"); | ||
957 | if (IS_ERR(xuartps_data->aperclk)) { | ||
958 | dev_err(&pdev->dev, "aper_clk clock not found.\n"); | ||
959 | rc = PTR_ERR(xuartps_data->aperclk); | ||
960 | goto err_out_free; | ||
961 | } | ||
962 | xuartps_data->refclk = clk_get(&pdev->dev, "ref_clk"); | ||
963 | if (IS_ERR(xuartps_data->refclk)) { | ||
964 | dev_err(&pdev->dev, "ref_clk clock not found.\n"); | ||
965 | rc = PTR_ERR(xuartps_data->refclk); | ||
966 | goto err_out_clk_put_aper; | ||
945 | } | 967 | } |
946 | 968 | ||
947 | rc = clk_prepare_enable(clk); | 969 | rc = clk_prepare_enable(xuartps_data->aperclk); |
970 | if (rc) { | ||
971 | dev_err(&pdev->dev, "Unable to enable APER clock.\n"); | ||
972 | goto err_out_clk_put; | ||
973 | } | ||
974 | rc = clk_prepare_enable(xuartps_data->refclk); | ||
948 | if (rc) { | 975 | if (rc) { |
949 | dev_err(&pdev->dev, "could not enable clock\n"); | 976 | dev_err(&pdev->dev, "Unable to enable device clock.\n"); |
950 | return -EBUSY; | 977 | goto err_out_clk_dis_aper; |
951 | } | 978 | } |
952 | 979 | ||
953 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 980 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
954 | if (!res) | 981 | if (!res) { |
955 | return -ENODEV; | 982 | rc = -ENODEV; |
983 | goto err_out_clk_disable; | ||
984 | } | ||
956 | 985 | ||
957 | res2 = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | 986 | res2 = platform_get_resource(pdev, IORESOURCE_IRQ, 0); |
958 | if (!res2) | 987 | if (!res2) { |
959 | return -ENODEV; | 988 | rc = -ENODEV; |
989 | goto err_out_clk_disable; | ||
990 | } | ||
960 | 991 | ||
961 | /* Initialize the port structure */ | 992 | /* Initialize the port structure */ |
962 | port = xuartps_get_port(); | 993 | port = xuartps_get_port(); |
963 | 994 | ||
964 | if (!port) { | 995 | if (!port) { |
965 | dev_err(&pdev->dev, "Cannot get uart_port structure\n"); | 996 | dev_err(&pdev->dev, "Cannot get uart_port structure\n"); |
966 | return -ENODEV; | 997 | rc = -ENODEV; |
998 | goto err_out_clk_disable; | ||
967 | } else { | 999 | } else { |
968 | /* Register the port. | 1000 | /* Register the port. |
969 | * This function also registers this device with the tty layer | 1001 | * This function also registers this device with the tty layer |
@@ -972,18 +1004,31 @@ static int xuartps_probe(struct platform_device *pdev) | |||
972 | port->mapbase = res->start; | 1004 | port->mapbase = res->start; |
973 | port->irq = res2->start; | 1005 | port->irq = res2->start; |
974 | port->dev = &pdev->dev; | 1006 | port->dev = &pdev->dev; |
975 | port->uartclk = clk_get_rate(clk); | 1007 | port->uartclk = clk_get_rate(xuartps_data->refclk); |
976 | port->private_data = clk; | 1008 | port->private_data = xuartps_data; |
977 | dev_set_drvdata(&pdev->dev, port); | 1009 | dev_set_drvdata(&pdev->dev, port); |
978 | rc = uart_add_one_port(&xuartps_uart_driver, port); | 1010 | rc = uart_add_one_port(&xuartps_uart_driver, port); |
979 | if (rc) { | 1011 | if (rc) { |
980 | dev_err(&pdev->dev, | 1012 | dev_err(&pdev->dev, |
981 | "uart_add_one_port() failed; err=%i\n", rc); | 1013 | "uart_add_one_port() failed; err=%i\n", rc); |
982 | dev_set_drvdata(&pdev->dev, NULL); | 1014 | dev_set_drvdata(&pdev->dev, NULL); |
983 | return rc; | 1015 | goto err_out_clk_disable; |
984 | } | 1016 | } |
985 | return 0; | 1017 | return 0; |
986 | } | 1018 | } |
1019 | |||
1020 | err_out_clk_disable: | ||
1021 | clk_disable_unprepare(xuartps_data->refclk); | ||
1022 | err_out_clk_dis_aper: | ||
1023 | clk_disable_unprepare(xuartps_data->aperclk); | ||
1024 | err_out_clk_put: | ||
1025 | clk_put(xuartps_data->refclk); | ||
1026 | err_out_clk_put_aper: | ||
1027 | clk_put(xuartps_data->aperclk); | ||
1028 | err_out_free: | ||
1029 | kfree(xuartps_data); | ||
1030 | |||
1031 | return rc; | ||
987 | } | 1032 | } |
988 | 1033 | ||
989 | /** | 1034 | /** |
@@ -995,14 +1040,18 @@ static int xuartps_probe(struct platform_device *pdev) | |||
995 | static int xuartps_remove(struct platform_device *pdev) | 1040 | static int xuartps_remove(struct platform_device *pdev) |
996 | { | 1041 | { |
997 | struct uart_port *port = dev_get_drvdata(&pdev->dev); | 1042 | struct uart_port *port = dev_get_drvdata(&pdev->dev); |
998 | struct clk *clk = port->private_data; | 1043 | struct xuartps *xuartps_data = port->private_data; |
999 | int rc; | 1044 | int rc; |
1000 | 1045 | ||
1001 | /* Remove the xuartps port from the serial core */ | 1046 | /* Remove the xuartps port from the serial core */ |
1002 | rc = uart_remove_one_port(&xuartps_uart_driver, port); | 1047 | rc = uart_remove_one_port(&xuartps_uart_driver, port); |
1003 | dev_set_drvdata(&pdev->dev, NULL); | 1048 | dev_set_drvdata(&pdev->dev, NULL); |
1004 | port->mapbase = 0; | 1049 | port->mapbase = 0; |
1005 | clk_disable_unprepare(clk); | 1050 | clk_disable_unprepare(xuartps_data->refclk); |
1051 | clk_disable_unprepare(xuartps_data->aperclk); | ||
1052 | clk_put(xuartps_data->refclk); | ||
1053 | clk_put(xuartps_data->aperclk); | ||
1054 | kfree(xuartps_data); | ||
1006 | return rc; | 1055 | return rc; |
1007 | } | 1056 | } |
1008 | 1057 | ||