atmel-ebi.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * EBI driver for Atmel chips
  4. * inspired by the fsl weim bus driver
  5. *
  6. * Copyright (C) 2013 Jean-Jacques Hiblot <jjhiblot@traphandler.com>
  7. */
  8. #include <linux/clk.h>
  9. #include <linux/io.h>
  10. #include <linux/mfd/syscon.h>
  11. #include <linux/mfd/syscon/atmel-matrix.h>
  12. #include <linux/mfd/syscon/atmel-smc.h>
  13. #include <linux/init.h>
  14. #include <linux/of_device.h>
  15. #include <linux/regmap.h>
  16. #include <soc/at91/atmel-sfr.h>
  17. #define AT91_EBI_NUM_CS 8
  18. struct atmel_ebi_dev_config {
  19. int cs;
  20. struct atmel_smc_cs_conf smcconf;
  21. };
  22. struct atmel_ebi;
  23. struct atmel_ebi_dev {
  24. struct list_head node;
  25. struct atmel_ebi *ebi;
  26. u32 mode;
  27. int numcs;
  28. struct atmel_ebi_dev_config configs[];
  29. };
  30. struct atmel_ebi_caps {
  31. unsigned int available_cs;
  32. unsigned int ebi_csa_offs;
  33. const char *regmap_name;
  34. void (*get_config)(struct atmel_ebi_dev *ebid,
  35. struct atmel_ebi_dev_config *conf);
  36. int (*xlate_config)(struct atmel_ebi_dev *ebid,
  37. struct device_node *configs_np,
  38. struct atmel_ebi_dev_config *conf);
  39. void (*apply_config)(struct atmel_ebi_dev *ebid,
  40. struct atmel_ebi_dev_config *conf);
  41. };
  42. struct atmel_ebi {
  43. struct clk *clk;
  44. struct regmap *regmap;
  45. struct {
  46. struct regmap *regmap;
  47. struct clk *clk;
  48. const struct atmel_hsmc_reg_layout *layout;
  49. } smc;
  50. struct device *dev;
  51. const struct atmel_ebi_caps *caps;
  52. struct list_head devs;
  53. };
  54. struct atmel_smc_timing_xlate {
  55. const char *name;
  56. int (*converter)(struct atmel_smc_cs_conf *conf,
  57. unsigned int shift, unsigned int nycles);
  58. unsigned int shift;
  59. };
  60. #define ATMEL_SMC_SETUP_XLATE(nm, pos) \
  61. { .name = nm, .converter = atmel_smc_cs_conf_set_setup, .shift = pos}
  62. #define ATMEL_SMC_PULSE_XLATE(nm, pos) \
  63. { .name = nm, .converter = atmel_smc_cs_conf_set_pulse, .shift = pos}
  64. #define ATMEL_SMC_CYCLE_XLATE(nm, pos) \
  65. { .name = nm, .converter = atmel_smc_cs_conf_set_cycle, .shift = pos}
  66. static void at91sam9_ebi_get_config(struct atmel_ebi_dev *ebid,
  67. struct atmel_ebi_dev_config *conf)
  68. {
  69. atmel_smc_cs_conf_get(ebid->ebi->smc.regmap, conf->cs,
  70. &conf->smcconf);
  71. }
  72. static void sama5_ebi_get_config(struct atmel_ebi_dev *ebid,
  73. struct atmel_ebi_dev_config *conf)
  74. {
  75. atmel_hsmc_cs_conf_get(ebid->ebi->smc.regmap, ebid->ebi->smc.layout,
  76. conf->cs, &conf->smcconf);
  77. }
  78. static const struct atmel_smc_timing_xlate timings_xlate_table[] = {
  79. ATMEL_SMC_SETUP_XLATE("atmel,smc-ncs-rd-setup-ns",
  80. ATMEL_SMC_NCS_RD_SHIFT),
  81. ATMEL_SMC_SETUP_XLATE("atmel,smc-ncs-wr-setup-ns",
  82. ATMEL_SMC_NCS_WR_SHIFT),
  83. ATMEL_SMC_SETUP_XLATE("atmel,smc-nrd-setup-ns", ATMEL_SMC_NRD_SHIFT),
  84. ATMEL_SMC_SETUP_XLATE("atmel,smc-nwe-setup-ns", ATMEL_SMC_NWE_SHIFT),
  85. ATMEL_SMC_PULSE_XLATE("atmel,smc-ncs-rd-pulse-ns",
  86. ATMEL_SMC_NCS_RD_SHIFT),
  87. ATMEL_SMC_PULSE_XLATE("atmel,smc-ncs-wr-pulse-ns",
  88. ATMEL_SMC_NCS_WR_SHIFT),
  89. ATMEL_SMC_PULSE_XLATE("atmel,smc-nrd-pulse-ns", ATMEL_SMC_NRD_SHIFT),
  90. ATMEL_SMC_PULSE_XLATE("atmel,smc-nwe-pulse-ns", ATMEL_SMC_NWE_SHIFT),
  91. ATMEL_SMC_CYCLE_XLATE("atmel,smc-nrd-cycle-ns", ATMEL_SMC_NRD_SHIFT),
  92. ATMEL_SMC_CYCLE_XLATE("atmel,smc-nwe-cycle-ns", ATMEL_SMC_NWE_SHIFT),
  93. };
  94. static int atmel_ebi_xslate_smc_timings(struct atmel_ebi_dev *ebid,
  95. struct device_node *np,
  96. struct atmel_smc_cs_conf *smcconf)
  97. {
  98. unsigned int clk_rate = clk_get_rate(ebid->ebi->clk);
  99. unsigned int clk_period_ns = NSEC_PER_SEC / clk_rate;
  100. bool required = false;
  101. unsigned int ncycles;
  102. int ret, i;
  103. u32 val;
  104. ret = of_property_read_u32(np, "atmel,smc-tdf-ns", &val);
  105. if (!ret) {
  106. required = true;
  107. ncycles = DIV_ROUND_UP(val, clk_period_ns);
  108. if (ncycles > ATMEL_SMC_MODE_TDF_MAX) {
  109. ret = -EINVAL;
  110. goto out;
  111. }
  112. if (ncycles < ATMEL_SMC_MODE_TDF_MIN)
  113. ncycles = ATMEL_SMC_MODE_TDF_MIN;
  114. smcconf->mode |= ATMEL_SMC_MODE_TDF(ncycles);
  115. }
  116. for (i = 0; i < ARRAY_SIZE(timings_xlate_table); i++) {
  117. const struct atmel_smc_timing_xlate *xlate;
  118. xlate = &timings_xlate_table[i];
  119. ret = of_property_read_u32(np, xlate->name, &val);
  120. if (ret) {
  121. if (!required)
  122. continue;
  123. else
  124. break;
  125. }
  126. if (!required) {
  127. ret = -EINVAL;
  128. break;
  129. }
  130. ncycles = DIV_ROUND_UP(val, clk_period_ns);
  131. ret = xlate->converter(smcconf, xlate->shift, ncycles);
  132. if (ret)
  133. goto out;
  134. }
  135. out:
  136. if (ret) {
  137. dev_err(ebid->ebi->dev,
  138. "missing or invalid timings definition in %pOF",
  139. np);
  140. return ret;
  141. }
  142. return required;
  143. }
  144. static int atmel_ebi_xslate_smc_config(struct atmel_ebi_dev *ebid,
  145. struct device_node *np,
  146. struct atmel_ebi_dev_config *conf)
  147. {
  148. struct atmel_smc_cs_conf *smcconf = &conf->smcconf;
  149. bool required = false;
  150. const char *tmp_str;
  151. u32 tmp;
  152. int ret;
  153. ret = of_property_read_u32(np, "atmel,smc-bus-width", &tmp);
  154. if (!ret) {
  155. switch (tmp) {
  156. case 8:
  157. smcconf->mode |= ATMEL_SMC_MODE_DBW_8;
  158. break;
  159. case 16:
  160. smcconf->mode |= ATMEL_SMC_MODE_DBW_16;
  161. break;
  162. case 32:
  163. smcconf->mode |= ATMEL_SMC_MODE_DBW_32;
  164. break;
  165. default:
  166. return -EINVAL;
  167. }
  168. required = true;
  169. }
  170. if (of_property_read_bool(np, "atmel,smc-tdf-optimized")) {
  171. smcconf->mode |= ATMEL_SMC_MODE_TDFMODE_OPTIMIZED;
  172. required = true;
  173. }
  174. tmp_str = NULL;
  175. of_property_read_string(np, "atmel,smc-byte-access-type", &tmp_str);
  176. if (tmp_str && !strcmp(tmp_str, "write")) {
  177. smcconf->mode |= ATMEL_SMC_MODE_BAT_WRITE;
  178. required = true;
  179. }
  180. tmp_str = NULL;
  181. of_property_read_string(np, "atmel,smc-read-mode", &tmp_str);
  182. if (tmp_str && !strcmp(tmp_str, "nrd")) {
  183. smcconf->mode |= ATMEL_SMC_MODE_READMODE_NRD;
  184. required = true;
  185. }
  186. tmp_str = NULL;
  187. of_property_read_string(np, "atmel,smc-write-mode", &tmp_str);
  188. if (tmp_str && !strcmp(tmp_str, "nwe")) {
  189. smcconf->mode |= ATMEL_SMC_MODE_WRITEMODE_NWE;
  190. required = true;
  191. }
  192. tmp_str = NULL;
  193. of_property_read_string(np, "atmel,smc-exnw-mode", &tmp_str);
  194. if (tmp_str) {
  195. if (!strcmp(tmp_str, "frozen"))
  196. smcconf->mode |= ATMEL_SMC_MODE_EXNWMODE_FROZEN;
  197. else if (!strcmp(tmp_str, "ready"))
  198. smcconf->mode |= ATMEL_SMC_MODE_EXNWMODE_READY;
  199. else if (strcmp(tmp_str, "disabled"))
  200. return -EINVAL;
  201. required = true;
  202. }
  203. ret = of_property_read_u32(np, "atmel,smc-page-mode", &tmp);
  204. if (!ret) {
  205. switch (tmp) {
  206. case 4:
  207. smcconf->mode |= ATMEL_SMC_MODE_PS_4;
  208. break;
  209. case 8:
  210. smcconf->mode |= ATMEL_SMC_MODE_PS_8;
  211. break;
  212. case 16:
  213. smcconf->mode |= ATMEL_SMC_MODE_PS_16;
  214. break;
  215. case 32:
  216. smcconf->mode |= ATMEL_SMC_MODE_PS_32;
  217. break;
  218. default:
  219. return -EINVAL;
  220. }
  221. smcconf->mode |= ATMEL_SMC_MODE_PMEN;
  222. required = true;
  223. }
  224. ret = atmel_ebi_xslate_smc_timings(ebid, np, &conf->smcconf);
  225. if (ret < 0)
  226. return -EINVAL;
  227. if ((ret > 0 && !required) || (!ret && required)) {
  228. dev_err(ebid->ebi->dev, "missing atmel,smc- properties in %pOF",
  229. np);
  230. return -EINVAL;
  231. }
  232. return required;
  233. }
  234. static void at91sam9_ebi_apply_config(struct atmel_ebi_dev *ebid,
  235. struct atmel_ebi_dev_config *conf)
  236. {
  237. atmel_smc_cs_conf_apply(ebid->ebi->smc.regmap, conf->cs,
  238. &conf->smcconf);
  239. }
  240. static void sama5_ebi_apply_config(struct atmel_ebi_dev *ebid,
  241. struct atmel_ebi_dev_config *conf)
  242. {
  243. atmel_hsmc_cs_conf_apply(ebid->ebi->smc.regmap, ebid->ebi->smc.layout,
  244. conf->cs, &conf->smcconf);
  245. }
  246. static int atmel_ebi_dev_setup(struct atmel_ebi *ebi, struct device_node *np,
  247. int reg_cells)
  248. {
  249. const struct atmel_ebi_caps *caps = ebi->caps;
  250. struct atmel_ebi_dev_config conf = { };
  251. struct device *dev = ebi->dev;
  252. struct atmel_ebi_dev *ebid;
  253. unsigned long cslines = 0;
  254. int ret, numcs = 0, nentries, i;
  255. bool apply = false;
  256. u32 cs;
  257. nentries = of_property_count_elems_of_size(np, "reg",
  258. reg_cells * sizeof(u32));
  259. for (i = 0; i < nentries; i++) {
  260. ret = of_property_read_u32_index(np, "reg", i * reg_cells,
  261. &cs);
  262. if (ret)
  263. return ret;
  264. if (cs >= AT91_EBI_NUM_CS ||
  265. !(ebi->caps->available_cs & BIT(cs))) {
  266. dev_err(dev, "invalid reg property in %pOF\n", np);
  267. return -EINVAL;
  268. }
  269. if (!test_and_set_bit(cs, &cslines))
  270. numcs++;
  271. }
  272. if (!numcs) {
  273. dev_err(dev, "invalid reg property in %pOF\n", np);
  274. return -EINVAL;
  275. }
  276. ebid = devm_kzalloc(ebi->dev, struct_size(ebid, configs, numcs),
  277. GFP_KERNEL);
  278. if (!ebid)
  279. return -ENOMEM;
  280. ebid->ebi = ebi;
  281. ebid->numcs = numcs;
  282. ret = caps->xlate_config(ebid, np, &conf);
  283. if (ret < 0)
  284. return ret;
  285. else if (ret)
  286. apply = true;
  287. i = 0;
  288. for_each_set_bit(cs, &cslines, AT91_EBI_NUM_CS) {
  289. ebid->configs[i].cs = cs;
  290. if (apply) {
  291. conf.cs = cs;
  292. caps->apply_config(ebid, &conf);
  293. }
  294. caps->get_config(ebid, &ebid->configs[i]);
  295. /*
  296. * Attach the EBI device to the generic SMC logic if at least
  297. * one "atmel,smc-" property is present.
  298. */
  299. if (ebi->caps->ebi_csa_offs && apply)
  300. regmap_update_bits(ebi->regmap,
  301. ebi->caps->ebi_csa_offs,
  302. BIT(cs), 0);
  303. i++;
  304. }
  305. list_add_tail(&ebid->node, &ebi->devs);
  306. return 0;
  307. }
  308. static const struct atmel_ebi_caps at91sam9260_ebi_caps = {
  309. .available_cs = 0xff,
  310. .ebi_csa_offs = AT91SAM9260_MATRIX_EBICSA,
  311. .regmap_name = "atmel,matrix",
  312. .get_config = at91sam9_ebi_get_config,
  313. .xlate_config = atmel_ebi_xslate_smc_config,
  314. .apply_config = at91sam9_ebi_apply_config,
  315. };
  316. static const struct atmel_ebi_caps at91sam9261_ebi_caps = {
  317. .available_cs = 0xff,
  318. .ebi_csa_offs = AT91SAM9261_MATRIX_EBICSA,
  319. .regmap_name = "atmel,matrix",
  320. .get_config = at91sam9_ebi_get_config,
  321. .xlate_config = atmel_ebi_xslate_smc_config,
  322. .apply_config = at91sam9_ebi_apply_config,
  323. };
  324. static const struct atmel_ebi_caps at91sam9263_ebi0_caps = {
  325. .available_cs = 0x3f,
  326. .ebi_csa_offs = AT91SAM9263_MATRIX_EBI0CSA,
  327. .regmap_name = "atmel,matrix",
  328. .get_config = at91sam9_ebi_get_config,
  329. .xlate_config = atmel_ebi_xslate_smc_config,
  330. .apply_config = at91sam9_ebi_apply_config,
  331. };
  332. static const struct atmel_ebi_caps at91sam9263_ebi1_caps = {
  333. .available_cs = 0x7,
  334. .ebi_csa_offs = AT91SAM9263_MATRIX_EBI1CSA,
  335. .regmap_name = "atmel,matrix",
  336. .get_config = at91sam9_ebi_get_config,
  337. .xlate_config = atmel_ebi_xslate_smc_config,
  338. .apply_config = at91sam9_ebi_apply_config,
  339. };
  340. static const struct atmel_ebi_caps at91sam9rl_ebi_caps = {
  341. .available_cs = 0x3f,
  342. .ebi_csa_offs = AT91SAM9RL_MATRIX_EBICSA,
  343. .regmap_name = "atmel,matrix",
  344. .get_config = at91sam9_ebi_get_config,
  345. .xlate_config = atmel_ebi_xslate_smc_config,
  346. .apply_config = at91sam9_ebi_apply_config,
  347. };
  348. static const struct atmel_ebi_caps at91sam9g45_ebi_caps = {
  349. .available_cs = 0x3f,
  350. .ebi_csa_offs = AT91SAM9G45_MATRIX_EBICSA,
  351. .regmap_name = "atmel,matrix",
  352. .get_config = at91sam9_ebi_get_config,
  353. .xlate_config = atmel_ebi_xslate_smc_config,
  354. .apply_config = at91sam9_ebi_apply_config,
  355. };
  356. static const struct atmel_ebi_caps at91sam9x5_ebi_caps = {
  357. .available_cs = 0x3f,
  358. .ebi_csa_offs = AT91SAM9X5_MATRIX_EBICSA,
  359. .regmap_name = "atmel,matrix",
  360. .get_config = at91sam9_ebi_get_config,
  361. .xlate_config = atmel_ebi_xslate_smc_config,
  362. .apply_config = at91sam9_ebi_apply_config,
  363. };
  364. static const struct atmel_ebi_caps sama5d3_ebi_caps = {
  365. .available_cs = 0xf,
  366. .get_config = sama5_ebi_get_config,
  367. .xlate_config = atmel_ebi_xslate_smc_config,
  368. .apply_config = sama5_ebi_apply_config,
  369. };
  370. static const struct atmel_ebi_caps sam9x60_ebi_caps = {
  371. .available_cs = 0x3f,
  372. .ebi_csa_offs = AT91_SFR_CCFG_EBICSA,
  373. .regmap_name = "microchip,sfr",
  374. .get_config = at91sam9_ebi_get_config,
  375. .xlate_config = atmel_ebi_xslate_smc_config,
  376. .apply_config = at91sam9_ebi_apply_config,
  377. };
  378. static const struct of_device_id atmel_ebi_id_table[] = {
  379. {
  380. .compatible = "atmel,at91sam9260-ebi",
  381. .data = &at91sam9260_ebi_caps,
  382. },
  383. {
  384. .compatible = "atmel,at91sam9261-ebi",
  385. .data = &at91sam9261_ebi_caps,
  386. },
  387. {
  388. .compatible = "atmel,at91sam9263-ebi0",
  389. .data = &at91sam9263_ebi0_caps,
  390. },
  391. {
  392. .compatible = "atmel,at91sam9263-ebi1",
  393. .data = &at91sam9263_ebi1_caps,
  394. },
  395. {
  396. .compatible = "atmel,at91sam9rl-ebi",
  397. .data = &at91sam9rl_ebi_caps,
  398. },
  399. {
  400. .compatible = "atmel,at91sam9g45-ebi",
  401. .data = &at91sam9g45_ebi_caps,
  402. },
  403. {
  404. .compatible = "atmel,at91sam9x5-ebi",
  405. .data = &at91sam9x5_ebi_caps,
  406. },
  407. {
  408. .compatible = "atmel,sama5d3-ebi",
  409. .data = &sama5d3_ebi_caps,
  410. },
  411. {
  412. .compatible = "microchip,sam9x60-ebi",
  413. .data = &sam9x60_ebi_caps,
  414. },
  415. { /* sentinel */ }
  416. };
  417. static int atmel_ebi_dev_disable(struct atmel_ebi *ebi, struct device_node *np)
  418. {
  419. struct device *dev = ebi->dev;
  420. struct property *newprop;
  421. newprop = devm_kzalloc(dev, sizeof(*newprop), GFP_KERNEL);
  422. if (!newprop)
  423. return -ENOMEM;
  424. newprop->name = devm_kstrdup(dev, "status", GFP_KERNEL);
  425. if (!newprop->name)
  426. return -ENOMEM;
  427. newprop->value = devm_kstrdup(dev, "disabled", GFP_KERNEL);
  428. if (!newprop->value)
  429. return -ENOMEM;
  430. newprop->length = sizeof("disabled");
  431. return of_update_property(np, newprop);
  432. }
  433. static int atmel_ebi_probe(struct platform_device *pdev)
  434. {
  435. struct device *dev = &pdev->dev;
  436. struct device_node *child, *np = dev->of_node, *smc_np;
  437. const struct of_device_id *match;
  438. struct atmel_ebi *ebi;
  439. int ret, reg_cells;
  440. struct clk *clk;
  441. u32 val;
  442. match = of_match_device(atmel_ebi_id_table, dev);
  443. if (!match || !match->data)
  444. return -EINVAL;
  445. ebi = devm_kzalloc(dev, sizeof(*ebi), GFP_KERNEL);
  446. if (!ebi)
  447. return -ENOMEM;
  448. platform_set_drvdata(pdev, ebi);
  449. INIT_LIST_HEAD(&ebi->devs);
  450. ebi->caps = match->data;
  451. ebi->dev = dev;
  452. clk = devm_clk_get(dev, NULL);
  453. if (IS_ERR(clk))
  454. return PTR_ERR(clk);
  455. ebi->clk = clk;
  456. smc_np = of_parse_phandle(dev->of_node, "atmel,smc", 0);
  457. ebi->smc.regmap = syscon_node_to_regmap(smc_np);
  458. if (IS_ERR(ebi->smc.regmap)) {
  459. ret = PTR_ERR(ebi->smc.regmap);
  460. goto put_node;
  461. }
  462. ebi->smc.layout = atmel_hsmc_get_reg_layout(smc_np);
  463. if (IS_ERR(ebi->smc.layout)) {
  464. ret = PTR_ERR(ebi->smc.layout);
  465. goto put_node;
  466. }
  467. ebi->smc.clk = of_clk_get(smc_np, 0);
  468. if (IS_ERR(ebi->smc.clk)) {
  469. if (PTR_ERR(ebi->smc.clk) != -ENOENT) {
  470. ret = PTR_ERR(ebi->smc.clk);
  471. goto put_node;
  472. }
  473. ebi->smc.clk = NULL;
  474. }
  475. of_node_put(smc_np);
  476. ret = clk_prepare_enable(ebi->smc.clk);
  477. if (ret)
  478. return ret;
  479. /*
  480. * The sama5d3 does not provide an EBICSA register and thus does need
  481. * to access it.
  482. */
  483. if (ebi->caps->ebi_csa_offs) {
  484. ebi->regmap =
  485. syscon_regmap_lookup_by_phandle(np,
  486. ebi->caps->regmap_name);
  487. if (IS_ERR(ebi->regmap))
  488. return PTR_ERR(ebi->regmap);
  489. }
  490. ret = of_property_read_u32(np, "#address-cells", &val);
  491. if (ret) {
  492. dev_err(dev, "missing #address-cells property\n");
  493. return ret;
  494. }
  495. reg_cells = val;
  496. ret = of_property_read_u32(np, "#size-cells", &val);
  497. if (ret) {
  498. dev_err(dev, "missing #address-cells property\n");
  499. return ret;
  500. }
  501. reg_cells += val;
  502. for_each_available_child_of_node(np, child) {
  503. if (!of_find_property(child, "reg", NULL))
  504. continue;
  505. ret = atmel_ebi_dev_setup(ebi, child, reg_cells);
  506. if (ret) {
  507. dev_err(dev, "failed to configure EBI bus for %pOF, disabling the device",
  508. child);
  509. ret = atmel_ebi_dev_disable(ebi, child);
  510. if (ret) {
  511. of_node_put(child);
  512. return ret;
  513. }
  514. }
  515. }
  516. return of_platform_populate(np, NULL, NULL, dev);
  517. put_node:
  518. of_node_put(smc_np);
  519. return ret;
  520. }
  521. static __maybe_unused int atmel_ebi_resume(struct device *dev)
  522. {
  523. struct atmel_ebi *ebi = dev_get_drvdata(dev);
  524. struct atmel_ebi_dev *ebid;
  525. list_for_each_entry(ebid, &ebi->devs, node) {
  526. int i;
  527. for (i = 0; i < ebid->numcs; i++)
  528. ebid->ebi->caps->apply_config(ebid, &ebid->configs[i]);
  529. }
  530. return 0;
  531. }
  532. static SIMPLE_DEV_PM_OPS(atmel_ebi_pm_ops, NULL, atmel_ebi_resume);
  533. static struct platform_driver atmel_ebi_driver = {
  534. .driver = {
  535. .name = "atmel-ebi",
  536. .of_match_table = atmel_ebi_id_table,
  537. .pm = &atmel_ebi_pm_ops,
  538. },
  539. };
  540. builtin_platform_driver_probe(atmel_ebi_driver, atmel_ebi_probe);