16
16
#include <linux/module.h>
17
17
#include <linux/mtd/rawnand.h>
18
18
#include <linux/of_address.h>
19
+ #include <linux/of_device.h>
19
20
#include <linux/pinctrl/consumer.h>
20
21
#include <linux/platform_device.h>
21
22
#include <linux/regmap.h>
37
38
#define FMC2_MAX_SG 16
38
39
39
40
/* Max chip enable */
40
- #define FMC2_MAX_CE 2
41
+ #define FMC2_MAX_CE 4
41
42
42
43
/* Max ECC buffer length */
43
44
#define FMC2_MAX_ECC_BUF_LEN (FMC2_BCHDSRS_LEN * FMC2_MAX_SG)
@@ -243,6 +244,13 @@ static inline struct stm32_fmc2_nand *to_fmc2_nand(struct nand_chip *chip)
243
244
return container_of (chip , struct stm32_fmc2_nand , chip );
244
245
}
245
246
247
+ struct stm32_fmc2_nfc ;
248
+
249
+ struct stm32_fmc2_nfc_data {
250
+ int max_ncs ;
251
+ int (* set_cdev )(struct stm32_fmc2_nfc * nfc );
252
+ };
253
+
246
254
struct stm32_fmc2_nfc {
247
255
struct nand_controller base ;
248
256
struct stm32_fmc2_nand nand ;
@@ -256,6 +264,7 @@ struct stm32_fmc2_nfc {
256
264
phys_addr_t data_phys_addr [FMC2_MAX_CE ];
257
265
struct clk * clk ;
258
266
u8 irq_state ;
267
+ const struct stm32_fmc2_nfc_data * data ;
259
268
260
269
struct dma_chan * dma_tx_ch ;
261
270
struct dma_chan * dma_rx_ch ;
@@ -1809,7 +1818,7 @@ static int stm32_fmc2_nfc_parse_child(struct stm32_fmc2_nfc *nfc,
1809
1818
return ret ;
1810
1819
}
1811
1820
1812
- if (cs >= FMC2_MAX_CE ) {
1821
+ if (cs >= nfc -> data -> max_ncs ) {
1813
1822
dev_err (nfc -> dev , "invalid reg value: %d\n" , cs );
1814
1823
return - EINVAL ;
1815
1824
}
@@ -1915,9 +1924,17 @@ static int stm32_fmc2_nfc_probe(struct platform_device *pdev)
1915
1924
nand_controller_init (& nfc -> base );
1916
1925
nfc -> base .ops = & stm32_fmc2_nfc_controller_ops ;
1917
1926
1918
- ret = stm32_fmc2_nfc_set_cdev (nfc );
1919
- if (ret )
1920
- return ret ;
1927
+ nfc -> data = of_device_get_match_data (dev );
1928
+ if (!nfc -> data )
1929
+ return - EINVAL ;
1930
+
1931
+ if (nfc -> data -> set_cdev ) {
1932
+ ret = nfc -> data -> set_cdev (nfc );
1933
+ if (ret )
1934
+ return ret ;
1935
+ } else {
1936
+ nfc -> cdev = dev -> parent ;
1937
+ }
1921
1938
1922
1939
ret = stm32_fmc2_nfc_parse_dt (nfc );
1923
1940
if (ret )
@@ -1936,7 +1953,7 @@ static int stm32_fmc2_nfc_probe(struct platform_device *pdev)
1936
1953
if (nfc -> dev == nfc -> cdev )
1937
1954
start_region = 1 ;
1938
1955
1939
- for (chip_cs = 0 , mem_region = start_region ; chip_cs < FMC2_MAX_CE ;
1956
+ for (chip_cs = 0 , mem_region = start_region ; chip_cs < nfc -> data -> max_ncs ;
1940
1957
chip_cs ++ , mem_region += 3 ) {
1941
1958
if (!(nfc -> cs_assigned & BIT (chip_cs )))
1942
1959
continue ;
@@ -2092,7 +2109,7 @@ static int __maybe_unused stm32_fmc2_nfc_resume(struct device *dev)
2092
2109
2093
2110
stm32_fmc2_nfc_wp_disable (nand );
2094
2111
2095
- for (chip_cs = 0 ; chip_cs < FMC2_MAX_CE ; chip_cs ++ ) {
2112
+ for (chip_cs = 0 ; chip_cs < nfc -> data -> max_ncs ; chip_cs ++ ) {
2096
2113
if (!(nfc -> cs_assigned & BIT (chip_cs )))
2097
2114
continue ;
2098
2115
@@ -2105,9 +2122,28 @@ static int __maybe_unused stm32_fmc2_nfc_resume(struct device *dev)
2105
2122
static SIMPLE_DEV_PM_OPS (stm32_fmc2_nfc_pm_ops , stm32_fmc2_nfc_suspend ,
2106
2123
stm32_fmc2_nfc_resume ) ;
2107
2124
2125
+ static const struct stm32_fmc2_nfc_data stm32_fmc2_nfc_mp1_data = {
2126
+ .max_ncs = 2 ,
2127
+ .set_cdev = stm32_fmc2_nfc_set_cdev ,
2128
+ };
2129
+
2130
+ static const struct stm32_fmc2_nfc_data stm32_fmc2_nfc_mp25_data = {
2131
+ .max_ncs = 4 ,
2132
+ };
2133
+
2108
2134
static const struct of_device_id stm32_fmc2_nfc_match [] = {
2109
- {.compatible = "st,stm32mp15-fmc2" },
2110
- {.compatible = "st,stm32mp1-fmc2-nfc" },
2135
+ {
2136
+ .compatible = "st,stm32mp15-fmc2" ,
2137
+ .data = & stm32_fmc2_nfc_mp1_data ,
2138
+ },
2139
+ {
2140
+ .compatible = "st,stm32mp1-fmc2-nfc" ,
2141
+ .data = & stm32_fmc2_nfc_mp1_data ,
2142
+ },
2143
+ {
2144
+ .compatible = "st,stm32mp25-fmc2-nfc" ,
2145
+ .data = & stm32_fmc2_nfc_mp25_data ,
2146
+ },
2111
2147
{}
2112
2148
};
2113
2149
MODULE_DEVICE_TABLE (of , stm32_fmc2_nfc_match );
0 commit comments