diff options
author | Geert Uytterhoeven <geert+renesas@linux-m68k.org> | 2014-01-28 04:21:38 -0500 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2014-01-29 12:56:57 -0500 |
commit | 426ef76dd8a394a0e04d096941cd9acb49539a3e (patch) | |
tree | c6abc0e61b2b5e18fdbf45f982bb6b02067f3596 /drivers/spi/spi-rspi.c | |
parent | 29f397b739ceef90c8b848f6579cbacd088e896e (diff) |
spi: rspi: Add DT support
Signed-off-by: Geert Uytterhoeven <geert+renesas@linux-m68k.org>
Signed-off-by: Mark Brown <broonie@linaro.org>
Diffstat (limited to 'drivers/spi/spi-rspi.c')
-rw-r--r-- | drivers/spi/spi-rspi.c | 106 |
1 files changed, 77 insertions, 29 deletions
diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c index d79a7ed9b92e..e56fcb5f7f99 100644 --- a/drivers/spi/spi-rspi.c +++ b/drivers/spi/spi-rspi.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/clk.h> | 31 | #include <linux/clk.h> |
32 | #include <linux/dmaengine.h> | 32 | #include <linux/dmaengine.h> |
33 | #include <linux/dma-mapping.h> | 33 | #include <linux/dma-mapping.h> |
34 | #include <linux/of_device.h> | ||
34 | #include <linux/sh_dma.h> | 35 | #include <linux/sh_dma.h> |
35 | #include <linux/spi/spi.h> | 36 | #include <linux/spi/spi.h> |
36 | #include <linux/spi/rspi.h> | 37 | #include <linux/spi/rspi.h> |
@@ -985,6 +986,56 @@ static int rspi_remove(struct platform_device *pdev) | |||
985 | return 0; | 986 | return 0; |
986 | } | 987 | } |
987 | 988 | ||
989 | static const struct spi_ops rspi_ops = { | ||
990 | .set_config_register = rspi_set_config_register, | ||
991 | .transfer_one = rspi_transfer_one, | ||
992 | }; | ||
993 | |||
994 | static const struct spi_ops rspi_rz_ops = { | ||
995 | .set_config_register = rspi_rz_set_config_register, | ||
996 | .transfer_one = rspi_rz_transfer_one, | ||
997 | }; | ||
998 | |||
999 | static const struct spi_ops qspi_ops = { | ||
1000 | .set_config_register = qspi_set_config_register, | ||
1001 | .transfer_one = qspi_transfer_one, | ||
1002 | }; | ||
1003 | |||
1004 | #ifdef CONFIG_OF | ||
1005 | static const struct of_device_id rspi_of_match[] = { | ||
1006 | /* RSPI on legacy SH */ | ||
1007 | { .compatible = "renesas,rspi", .data = &rspi_ops }, | ||
1008 | /* RSPI on RZ/A1H */ | ||
1009 | { .compatible = "renesas,rspi-rz", .data = &rspi_rz_ops }, | ||
1010 | /* QSPI on R-Car Gen2 */ | ||
1011 | { .compatible = "renesas,qspi", .data = &qspi_ops }, | ||
1012 | { /* sentinel */ } | ||
1013 | }; | ||
1014 | |||
1015 | MODULE_DEVICE_TABLE(of, rspi_of_match); | ||
1016 | |||
1017 | static int rspi_parse_dt(struct device *dev, struct spi_master *master) | ||
1018 | { | ||
1019 | u32 num_cs; | ||
1020 | int error; | ||
1021 | |||
1022 | /* Parse DT properties */ | ||
1023 | error = of_property_read_u32(dev->of_node, "num-cs", &num_cs); | ||
1024 | if (error) { | ||
1025 | dev_err(dev, "of_property_read_u32 num-cs failed %d\n", error); | ||
1026 | return error; | ||
1027 | } | ||
1028 | |||
1029 | master->num_chipselect = num_cs; | ||
1030 | return 0; | ||
1031 | } | ||
1032 | #else | ||
1033 | static inline int rspi_parse_dt(struct device *dev, struct spi_master *master) | ||
1034 | { | ||
1035 | return -EINVAL; | ||
1036 | } | ||
1037 | #endif /* CONFIG_OF */ | ||
1038 | |||
988 | static int rspi_request_irq(struct device *dev, unsigned int irq, | 1039 | static int rspi_request_irq(struct device *dev, unsigned int irq, |
989 | irq_handler_t handler, const char *suffix, | 1040 | irq_handler_t handler, const char *suffix, |
990 | void *dev_id) | 1041 | void *dev_id) |
@@ -1004,16 +1055,9 @@ static int rspi_probe(struct platform_device *pdev) | |||
1004 | struct spi_master *master; | 1055 | struct spi_master *master; |
1005 | struct rspi_data *rspi; | 1056 | struct rspi_data *rspi; |
1006 | int ret; | 1057 | int ret; |
1007 | const struct rspi_plat_data *rspi_pd = dev_get_platdata(&pdev->dev); | 1058 | const struct of_device_id *of_id; |
1059 | const struct rspi_plat_data *rspi_pd; | ||
1008 | const struct spi_ops *ops; | 1060 | const struct spi_ops *ops; |
1009 | const struct platform_device_id *id_entry = pdev->id_entry; | ||
1010 | |||
1011 | ops = (struct spi_ops *)id_entry->driver_data; | ||
1012 | /* ops parameter check */ | ||
1013 | if (!ops->set_config_register) { | ||
1014 | dev_err(&pdev->dev, "there is no set_config_register\n"); | ||
1015 | return -ENODEV; | ||
1016 | } | ||
1017 | 1061 | ||
1018 | master = spi_alloc_master(&pdev->dev, sizeof(struct rspi_data)); | 1062 | master = spi_alloc_master(&pdev->dev, sizeof(struct rspi_data)); |
1019 | if (master == NULL) { | 1063 | if (master == NULL) { |
@@ -1021,6 +1065,28 @@ static int rspi_probe(struct platform_device *pdev) | |||
1021 | return -ENOMEM; | 1065 | return -ENOMEM; |
1022 | } | 1066 | } |
1023 | 1067 | ||
1068 | of_id = of_match_device(rspi_of_match, &pdev->dev); | ||
1069 | if (of_id) { | ||
1070 | ops = of_id->data; | ||
1071 | ret = rspi_parse_dt(&pdev->dev, master); | ||
1072 | if (ret) | ||
1073 | goto error1; | ||
1074 | } else { | ||
1075 | ops = (struct spi_ops *)pdev->id_entry->driver_data; | ||
1076 | rspi_pd = dev_get_platdata(&pdev->dev); | ||
1077 | if (rspi_pd && rspi_pd->num_chipselect) | ||
1078 | master->num_chipselect = rspi_pd->num_chipselect; | ||
1079 | else | ||
1080 | master->num_chipselect = 2; /* default */ | ||
1081 | }; | ||
1082 | |||
1083 | /* ops parameter check */ | ||
1084 | if (!ops->set_config_register) { | ||
1085 | dev_err(&pdev->dev, "there is no set_config_register\n"); | ||
1086 | ret = -ENODEV; | ||
1087 | goto error1; | ||
1088 | } | ||
1089 | |||
1024 | rspi = spi_master_get_devdata(master); | 1090 | rspi = spi_master_get_devdata(master); |
1025 | platform_set_drvdata(pdev, rspi); | 1091 | platform_set_drvdata(pdev, rspi); |
1026 | rspi->ops = ops; | 1092 | rspi->ops = ops; |
@@ -1048,11 +1114,6 @@ static int rspi_probe(struct platform_device *pdev) | |||
1048 | 1114 | ||
1049 | init_waitqueue_head(&rspi->wait); | 1115 | init_waitqueue_head(&rspi->wait); |
1050 | 1116 | ||
1051 | if (rspi_pd && rspi_pd->num_chipselect) | ||
1052 | master->num_chipselect = rspi_pd->num_chipselect; | ||
1053 | else | ||
1054 | master->num_chipselect = 2; /* default */ | ||
1055 | |||
1056 | master->bus_num = pdev->id; | 1117 | master->bus_num = pdev->id; |
1057 | master->setup = rspi_setup; | 1118 | master->setup = rspi_setup; |
1058 | master->transfer_one = ops->transfer_one; | 1119 | master->transfer_one = ops->transfer_one; |
@@ -1060,6 +1121,7 @@ static int rspi_probe(struct platform_device *pdev) | |||
1060 | master->prepare_message = rspi_prepare_message; | 1121 | master->prepare_message = rspi_prepare_message; |
1061 | master->unprepare_message = rspi_unprepare_message; | 1122 | master->unprepare_message = rspi_unprepare_message; |
1062 | master->mode_bits = SPI_CPHA | SPI_CPOL | SPI_LOOP; | 1123 | master->mode_bits = SPI_CPHA | SPI_CPOL | SPI_LOOP; |
1124 | master->dev.of_node = pdev->dev.of_node; | ||
1063 | 1125 | ||
1064 | ret = platform_get_irq_byname(pdev, "rx"); | 1126 | ret = platform_get_irq_byname(pdev, "rx"); |
1065 | if (ret < 0) { | 1127 | if (ret < 0) { |
@@ -1122,21 +1184,6 @@ error1: | |||
1122 | return ret; | 1184 | return ret; |
1123 | } | 1185 | } |
1124 | 1186 | ||
1125 | static struct spi_ops rspi_ops = { | ||
1126 | .set_config_register = rspi_set_config_register, | ||
1127 | .transfer_one = rspi_transfer_one, | ||
1128 | }; | ||
1129 | |||
1130 | static struct spi_ops rspi_rz_ops = { | ||
1131 | .set_config_register = rspi_rz_set_config_register, | ||
1132 | .transfer_one = rspi_rz_transfer_one, | ||
1133 | }; | ||
1134 | |||
1135 | static struct spi_ops qspi_ops = { | ||
1136 | .set_config_register = qspi_set_config_register, | ||
1137 | .transfer_one = qspi_transfer_one, | ||
1138 | }; | ||
1139 | |||
1140 | static struct platform_device_id spi_driver_ids[] = { | 1187 | static struct platform_device_id spi_driver_ids[] = { |
1141 | { "rspi", (kernel_ulong_t)&rspi_ops }, | 1188 | { "rspi", (kernel_ulong_t)&rspi_ops }, |
1142 | { "rspi-rz", (kernel_ulong_t)&rspi_rz_ops }, | 1189 | { "rspi-rz", (kernel_ulong_t)&rspi_rz_ops }, |
@@ -1153,6 +1200,7 @@ static struct platform_driver rspi_driver = { | |||
1153 | .driver = { | 1200 | .driver = { |
1154 | .name = "renesas_spi", | 1201 | .name = "renesas_spi", |
1155 | .owner = THIS_MODULE, | 1202 | .owner = THIS_MODULE, |
1203 | .of_match_table = of_match_ptr(rspi_of_match), | ||
1156 | }, | 1204 | }, |
1157 | }; | 1205 | }; |
1158 | module_platform_driver(rspi_driver); | 1206 | module_platform_driver(rspi_driver); |