diff options
author | Alexander Shiyan <shc_work@mail.ru> | 2013-07-31 06:55:45 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-07-31 21:09:35 -0400 |
commit | 85c996907473e4ef824774b97b26499adf66521f (patch) | |
tree | ba1d87ea9bb219d4828e9d87888f3df4d4fcdf23 /drivers/tty/serial/sccnxp.c | |
parent | ea4c39beace859139bc184a1aebdccdc12c04a2e (diff) |
serial: sccnxp: Add DT support
Add DT support to the SCCNCP serial driver.
Signed-off-by: Alexander Shiyan <shc_work@mail.ru>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty/serial/sccnxp.c')
-rw-r--r-- | drivers/tty/serial/sccnxp.c | 46 |
1 files changed, 37 insertions, 9 deletions
diff --git a/drivers/tty/serial/sccnxp.c b/drivers/tty/serial/sccnxp.c index 49e9bbfe6cab..67f73d1a8e7b 100644 --- a/drivers/tty/serial/sccnxp.c +++ b/drivers/tty/serial/sccnxp.c | |||
@@ -20,6 +20,8 @@ | |||
20 | #include <linux/module.h> | 20 | #include <linux/module.h> |
21 | #include <linux/device.h> | 21 | #include <linux/device.h> |
22 | #include <linux/console.h> | 22 | #include <linux/console.h> |
23 | #include <linux/of.h> | ||
24 | #include <linux/of_device.h> | ||
23 | #include <linux/serial_core.h> | 25 | #include <linux/serial_core.h> |
24 | #include <linux/serial.h> | 26 | #include <linux/serial.h> |
25 | #include <linux/io.h> | 27 | #include <linux/io.h> |
@@ -853,10 +855,25 @@ static const struct platform_device_id sccnxp_id_table[] = { | |||
853 | }; | 855 | }; |
854 | MODULE_DEVICE_TABLE(platform, sccnxp_id_table); | 856 | MODULE_DEVICE_TABLE(platform, sccnxp_id_table); |
855 | 857 | ||
858 | static const struct of_device_id sccnxp_dt_id_table[] = { | ||
859 | { .compatible = "nxp,sc2681", .data = &sc2681, }, | ||
860 | { .compatible = "nxp,sc2691", .data = &sc2691, }, | ||
861 | { .compatible = "nxp,sc2692", .data = &sc2692, }, | ||
862 | { .compatible = "nxp,sc2891", .data = &sc2891, }, | ||
863 | { .compatible = "nxp,sc2892", .data = &sc2892, }, | ||
864 | { .compatible = "nxp,sc28202", .data = &sc28202, }, | ||
865 | { .compatible = "nxp,sc68681", .data = &sc68681, }, | ||
866 | { .compatible = "nxp,sc68692", .data = &sc68692, }, | ||
867 | { } | ||
868 | }; | ||
869 | MODULE_DEVICE_TABLE(of, sccnxp_dt_id_table); | ||
870 | |||
856 | static int sccnxp_probe(struct platform_device *pdev) | 871 | static int sccnxp_probe(struct platform_device *pdev) |
857 | { | 872 | { |
858 | struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 873 | struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
859 | struct sccnxp_pdata *pdata = dev_get_platdata(&pdev->dev); | 874 | struct sccnxp_pdata *pdata = dev_get_platdata(&pdev->dev); |
875 | const struct of_device_id *of_id = | ||
876 | of_match_device(sccnxp_dt_id_table, &pdev->dev); | ||
860 | int i, ret, uartclk; | 877 | int i, ret, uartclk; |
861 | struct sccnxp_port *s; | 878 | struct sccnxp_port *s; |
862 | void __iomem *membase; | 879 | void __iomem *membase; |
@@ -875,7 +892,22 @@ static int sccnxp_probe(struct platform_device *pdev) | |||
875 | 892 | ||
876 | spin_lock_init(&s->lock); | 893 | spin_lock_init(&s->lock); |
877 | 894 | ||
878 | s->chip = (struct sccnxp_chip *)pdev->id_entry->driver_data; | 895 | if (of_id) { |
896 | s->chip = (struct sccnxp_chip *)of_id->data; | ||
897 | |||
898 | of_property_read_u32(pdev->dev.of_node, "poll-interval", | ||
899 | &s->pdata.poll_time_us); | ||
900 | of_property_read_u32(pdev->dev.of_node, "reg-shift", | ||
901 | &s->pdata.reg_shift); | ||
902 | of_property_read_u32_array(pdev->dev.of_node, | ||
903 | "nxp,sccnxp-io-cfg", | ||
904 | s->pdata.mctrl_cfg, s->chip->nr); | ||
905 | } else { | ||
906 | s->chip = (struct sccnxp_chip *)pdev->id_entry->driver_data; | ||
907 | |||
908 | if (pdata) | ||
909 | memcpy(&s->pdata, pdata, sizeof(struct sccnxp_pdata)); | ||
910 | } | ||
879 | 911 | ||
880 | s->regulator = devm_regulator_get(&pdev->dev, "vcc"); | 912 | s->regulator = devm_regulator_get(&pdev->dev, "vcc"); |
881 | if (!IS_ERR(s->regulator)) { | 913 | if (!IS_ERR(s->regulator)) { |
@@ -906,16 +938,11 @@ static int sccnxp_probe(struct platform_device *pdev) | |||
906 | goto err_out; | 938 | goto err_out; |
907 | } | 939 | } |
908 | 940 | ||
909 | if (pdata) | ||
910 | memcpy(&s->pdata, pdata, sizeof(struct sccnxp_pdata)); | ||
911 | |||
912 | if (s->pdata.poll_time_us) { | 941 | if (s->pdata.poll_time_us) { |
913 | dev_info(&pdev->dev, "Using poll mode, resolution %u usecs\n", | 942 | dev_info(&pdev->dev, "Using poll mode, resolution %u usecs\n", |
914 | s->pdata.poll_time_us); | 943 | s->pdata.poll_time_us); |
915 | s->poll = 1; | 944 | s->poll = 1; |
916 | } | 945 | } else { |
917 | |||
918 | if (!s->poll) { | ||
919 | s->irq = platform_get_irq(pdev, 0); | 946 | s->irq = platform_get_irq(pdev, 0); |
920 | if (s->irq < 0) { | 947 | if (s->irq < 0) { |
921 | dev_err(&pdev->dev, "Missing irq resource data\n"); | 948 | dev_err(&pdev->dev, "Missing irq resource data\n"); |
@@ -1016,8 +1043,9 @@ static int sccnxp_remove(struct platform_device *pdev) | |||
1016 | 1043 | ||
1017 | static struct platform_driver sccnxp_uart_driver = { | 1044 | static struct platform_driver sccnxp_uart_driver = { |
1018 | .driver = { | 1045 | .driver = { |
1019 | .name = SCCNXP_NAME, | 1046 | .name = SCCNXP_NAME, |
1020 | .owner = THIS_MODULE, | 1047 | .owner = THIS_MODULE, |
1048 | .of_match_table = sccnxp_dt_id_table, | ||
1021 | }, | 1049 | }, |
1022 | .probe = sccnxp_probe, | 1050 | .probe = sccnxp_probe, |
1023 | .remove = sccnxp_remove, | 1051 | .remove = sccnxp_remove, |