io_interface_mux.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182
  1. /* IO interface mux allocator for ETRAX100LX.
  2. * Copyright 2004-2007, Axis Communications AB
  3. */
  4. /* C.f. ETRAX100LX Designer's Reference chapter 19.9 */
  5. #include <linux/kernel.h>
  6. #include <linux/slab.h>
  7. #include <linux/errno.h>
  8. #include <linux/module.h>
  9. #include <linux/init.h>
  10. #include <arch/svinto.h>
  11. #include <asm/io.h>
  12. #include <arch/io_interface_mux.h>
  13. #define DBG(s)
  14. /* Macro to access ETRAX 100 registers */
  15. #define SETS(var, reg, field, val) var = (var & ~IO_MASK_(reg##_, field##_)) | \
  16. IO_STATE_(reg##_, field##_, _##val)
  17. enum io_if_group {
  18. group_a = (1<<0),
  19. group_b = (1<<1),
  20. group_c = (1<<2),
  21. group_d = (1<<3),
  22. group_e = (1<<4),
  23. group_f = (1<<5)
  24. };
  25. struct watcher
  26. {
  27. void (*notify)(const unsigned int gpio_in_available,
  28. const unsigned int gpio_out_available,
  29. const unsigned char pa_available,
  30. const unsigned char pb_available);
  31. struct watcher *next;
  32. };
  33. struct if_group
  34. {
  35. enum io_if_group group;
  36. /* name - the name of the group 'A' to 'F' */
  37. char *name;
  38. /* used - a bit mask of all pins in the group in the order listed
  39. * in the tables in 19.9.1 to 19.9.6. Note that no
  40. * distinction is made between in, out and in/out pins. */
  41. unsigned int used;
  42. };
  43. struct interface
  44. {
  45. enum cris_io_interface ioif;
  46. /* name - the name of the interface */
  47. char *name;
  48. /* groups - OR'ed together io_if_group flags describing what pin groups
  49. * the interface uses pins in. */
  50. unsigned char groups;
  51. /* used - set when the interface is allocated. */
  52. unsigned char used;
  53. char *owner;
  54. /* group_a through group_f - bit masks describing what pins in the
  55. * pin groups the interface uses. */
  56. unsigned int group_a;
  57. unsigned int group_b;
  58. unsigned int group_c;
  59. unsigned int group_d;
  60. unsigned int group_e;
  61. unsigned int group_f;
  62. /* gpio_g_in, gpio_g_out, gpio_b - bit masks telling what pins in the
  63. * GPIO ports the interface uses. This could be reconstucted using
  64. * the group_X masks and a table of what pins the GPIO ports use,
  65. * but that would be messy. */
  66. unsigned int gpio_g_in;
  67. unsigned int gpio_g_out;
  68. unsigned char gpio_b;
  69. };
  70. static struct if_group if_groups[6] = {
  71. {
  72. .group = group_a,
  73. .name = "A",
  74. .used = 0,
  75. },
  76. {
  77. .group = group_b,
  78. .name = "B",
  79. .used = 0,
  80. },
  81. {
  82. .group = group_c,
  83. .name = "C",
  84. .used = 0,
  85. },
  86. {
  87. .group = group_d,
  88. .name = "D",
  89. .used = 0,
  90. },
  91. {
  92. .group = group_e,
  93. .name = "E",
  94. .used = 0,
  95. },
  96. {
  97. .group = group_f,
  98. .name = "F",
  99. .used = 0,
  100. }
  101. };
  102. /* The order in the array must match the order of enum
  103. * cris_io_interface in io_interface_mux.h */
  104. static struct interface interfaces[] = {
  105. /* Begin Non-multiplexed interfaces */
  106. {
  107. .ioif = if_eth,
  108. .name = "ethernet",
  109. .groups = 0,
  110. .group_a = 0,
  111. .group_b = 0,
  112. .group_c = 0,
  113. .group_d = 0,
  114. .group_e = 0,
  115. .group_f = 0,
  116. .gpio_g_in = 0,
  117. .gpio_g_out = 0,
  118. .gpio_b = 0
  119. },
  120. {
  121. .ioif = if_serial_0,
  122. .name = "serial_0",
  123. .groups = 0,
  124. .group_a = 0,
  125. .group_b = 0,
  126. .group_c = 0,
  127. .group_d = 0,
  128. .group_e = 0,
  129. .group_f = 0,
  130. .gpio_g_in = 0,
  131. .gpio_g_out = 0,
  132. .gpio_b = 0
  133. },
  134. /* End Non-multiplexed interfaces */
  135. {
  136. .ioif = if_serial_1,
  137. .name = "serial_1",
  138. .groups = group_e,
  139. .group_a = 0,
  140. .group_b = 0,
  141. .group_c = 0,
  142. .group_d = 0,
  143. .group_e = 0x0f,
  144. .group_f = 0,
  145. .gpio_g_in = 0x00000000,
  146. .gpio_g_out = 0x00000000,
  147. .gpio_b = 0x00
  148. },
  149. {
  150. .ioif = if_serial_2,
  151. .name = "serial_2",
  152. .groups = group_b,
  153. .group_a = 0,
  154. .group_b = 0x0f,
  155. .group_c = 0,
  156. .group_d = 0,
  157. .group_e = 0,
  158. .group_f = 0,
  159. .gpio_g_in = 0x000000c0,
  160. .gpio_g_out = 0x000000c0,
  161. .gpio_b = 0x00
  162. },
  163. {
  164. .ioif = if_serial_3,
  165. .name = "serial_3",
  166. .groups = group_c,
  167. .group_a = 0,
  168. .group_b = 0,
  169. .group_c = 0x0f,
  170. .group_d = 0,
  171. .group_e = 0,
  172. .group_f = 0,
  173. .gpio_g_in = 0xc0000000,
  174. .gpio_g_out = 0xc0000000,
  175. .gpio_b = 0x00
  176. },
  177. {
  178. .ioif = if_sync_serial_1,
  179. .name = "sync_serial_1",
  180. .groups = group_e | group_f,
  181. .group_a = 0,
  182. .group_b = 0,
  183. .group_c = 0,
  184. .group_d = 0,
  185. .group_e = 0x0f,
  186. .group_f = 0x10,
  187. .gpio_g_in = 0x00000000,
  188. .gpio_g_out = 0x00000000,
  189. .gpio_b = 0x10
  190. },
  191. {
  192. .ioif = if_sync_serial_3,
  193. .name = "sync_serial_3",
  194. .groups = group_c | group_f,
  195. .group_a = 0,
  196. .group_b = 0,
  197. .group_c = 0x0f,
  198. .group_d = 0,
  199. .group_e = 0,
  200. .group_f = 0x80,
  201. .gpio_g_in = 0xc0000000,
  202. .gpio_g_out = 0xc0000000,
  203. .gpio_b = 0x80
  204. },
  205. {
  206. .ioif = if_shared_ram,
  207. .name = "shared_ram",
  208. .groups = group_a,
  209. .group_a = 0x7f8ff,
  210. .group_b = 0,
  211. .group_c = 0,
  212. .group_d = 0,
  213. .group_e = 0,
  214. .group_f = 0,
  215. .gpio_g_in = 0x0000ff3e,
  216. .gpio_g_out = 0x0000ff38,
  217. .gpio_b = 0x00
  218. },
  219. {
  220. .ioif = if_shared_ram_w,
  221. .name = "shared_ram_w",
  222. .groups = group_a | group_d,
  223. .group_a = 0x7f8ff,
  224. .group_b = 0,
  225. .group_c = 0,
  226. .group_d = 0xff,
  227. .group_e = 0,
  228. .group_f = 0,
  229. .gpio_g_in = 0x00ffff3e,
  230. .gpio_g_out = 0x00ffff38,
  231. .gpio_b = 0x00
  232. },
  233. {
  234. .ioif = if_par_0,
  235. .name = "par_0",
  236. .groups = group_a,
  237. .group_a = 0x7fbff,
  238. .group_b = 0,
  239. .group_c = 0,
  240. .group_d = 0,
  241. .group_e = 0,
  242. .group_f = 0,
  243. .gpio_g_in = 0x0000ff3e,
  244. .gpio_g_out = 0x0000ff3e,
  245. .gpio_b = 0x00
  246. },
  247. {
  248. .ioif = if_par_1,
  249. .name = "par_1",
  250. .groups = group_d,
  251. .group_a = 0,
  252. .group_b = 0,
  253. .group_c = 0,
  254. .group_d = 0x7feff,
  255. .group_e = 0,
  256. .group_f = 0,
  257. .gpio_g_in = 0x3eff0000,
  258. .gpio_g_out = 0x3eff0000,
  259. .gpio_b = 0x00
  260. },
  261. {
  262. .ioif = if_par_w,
  263. .name = "par_w",
  264. .groups = group_a | group_d,
  265. .group_a = 0x7fbff,
  266. .group_b = 0,
  267. .group_c = 0,
  268. .group_d = 0xff,
  269. .group_e = 0,
  270. .group_f = 0,
  271. .gpio_g_in = 0x00ffff3e,
  272. .gpio_g_out = 0x00ffff3e,
  273. .gpio_b = 0x00
  274. },
  275. {
  276. .ioif = if_scsi8_0,
  277. .name = "scsi8_0",
  278. .groups = group_a | group_b | group_f,
  279. .group_a = 0x7ffff,
  280. .group_b = 0x0f,
  281. .group_c = 0,
  282. .group_d = 0,
  283. .group_e = 0,
  284. .group_f = 0x10,
  285. .gpio_g_in = 0x0000ffff,
  286. .gpio_g_out = 0x0000ffff,
  287. .gpio_b = 0x10
  288. },
  289. {
  290. .ioif = if_scsi8_1,
  291. .name = "scsi8_1",
  292. .groups = group_c | group_d | group_f,
  293. .group_a = 0,
  294. .group_b = 0,
  295. .group_c = 0x0f,
  296. .group_d = 0x7ffff,
  297. .group_e = 0,
  298. .group_f = 0x80,
  299. .gpio_g_in = 0xffff0000,
  300. .gpio_g_out = 0xffff0000,
  301. .gpio_b = 0x80
  302. },
  303. {
  304. .ioif = if_scsi_w,
  305. .name = "scsi_w",
  306. .groups = group_a | group_b | group_d | group_f,
  307. .group_a = 0x7ffff,
  308. .group_b = 0x0f,
  309. .group_c = 0,
  310. .group_d = 0x601ff,
  311. .group_e = 0,
  312. .group_f = 0x90,
  313. .gpio_g_in = 0x01ffffff,
  314. .gpio_g_out = 0x07ffffff,
  315. .gpio_b = 0x80
  316. },
  317. {
  318. .ioif = if_ata,
  319. .name = "ata",
  320. .groups = group_a | group_b | group_c | group_d,
  321. .group_a = 0x7ffff,
  322. .group_b = 0x0f,
  323. .group_c = 0x0f,
  324. .group_d = 0x7cfff,
  325. .group_e = 0,
  326. .group_f = 0,
  327. .gpio_g_in = 0xf9ffffff,
  328. .gpio_g_out = 0xffffffff,
  329. .gpio_b = 0x80
  330. },
  331. {
  332. .ioif = if_csp,
  333. .name = "csp",
  334. .groups = group_f,
  335. .group_a = 0,
  336. .group_b = 0,
  337. .group_c = 0,
  338. .group_d = 0,
  339. .group_e = 0,
  340. .group_f = 0xfc,
  341. .gpio_g_in = 0x00000000,
  342. .gpio_g_out = 0x00000000,
  343. .gpio_b = 0xfc
  344. },
  345. {
  346. .ioif = if_i2c,
  347. .name = "i2c",
  348. .groups = group_f,
  349. .group_a = 0,
  350. .group_b = 0,
  351. .group_c = 0,
  352. .group_d = 0,
  353. .group_e = 0,
  354. .group_f = 0x03,
  355. .gpio_g_in = 0x00000000,
  356. .gpio_g_out = 0x00000000,
  357. .gpio_b = 0x03
  358. },
  359. {
  360. .ioif = if_usb_1,
  361. .name = "usb_1",
  362. .groups = group_e | group_f,
  363. .group_a = 0,
  364. .group_b = 0,
  365. .group_c = 0,
  366. .group_d = 0,
  367. .group_e = 0x0f,
  368. .group_f = 0x2c,
  369. .gpio_g_in = 0x00000000,
  370. .gpio_g_out = 0x00000000,
  371. .gpio_b = 0x2c
  372. },
  373. {
  374. .ioif = if_usb_2,
  375. .name = "usb_2",
  376. .groups = group_d,
  377. .group_a = 0,
  378. .group_b = 0,
  379. .group_c = 0,
  380. .group_d = 0,
  381. .group_e = 0x33e00,
  382. .group_f = 0,
  383. .gpio_g_in = 0x3e000000,
  384. .gpio_g_out = 0x0c000000,
  385. .gpio_b = 0x00
  386. },
  387. /* GPIO pins */
  388. {
  389. .ioif = if_gpio_grp_a,
  390. .name = "gpio_a",
  391. .groups = group_a,
  392. .group_a = 0,
  393. .group_b = 0,
  394. .group_c = 0,
  395. .group_d = 0,
  396. .group_e = 0,
  397. .group_f = 0,
  398. .gpio_g_in = 0x0000ff3f,
  399. .gpio_g_out = 0x0000ff3f,
  400. .gpio_b = 0x00
  401. },
  402. {
  403. .ioif = if_gpio_grp_b,
  404. .name = "gpio_b",
  405. .groups = group_b,
  406. .group_a = 0,
  407. .group_b = 0,
  408. .group_c = 0,
  409. .group_d = 0,
  410. .group_e = 0,
  411. .group_f = 0,
  412. .gpio_g_in = 0x000000c0,
  413. .gpio_g_out = 0x000000c0,
  414. .gpio_b = 0x00
  415. },
  416. {
  417. .ioif = if_gpio_grp_c,
  418. .name = "gpio_c",
  419. .groups = group_c,
  420. .group_a = 0,
  421. .group_b = 0,
  422. .group_c = 0,
  423. .group_d = 0,
  424. .group_e = 0,
  425. .group_f = 0,
  426. .gpio_g_in = 0xc0000000,
  427. .gpio_g_out = 0xc0000000,
  428. .gpio_b = 0x00
  429. },
  430. {
  431. .ioif = if_gpio_grp_d,
  432. .name = "gpio_d",
  433. .groups = group_d,
  434. .group_a = 0,
  435. .group_b = 0,
  436. .group_c = 0,
  437. .group_d = 0,
  438. .group_e = 0,
  439. .group_f = 0,
  440. .gpio_g_in = 0x3fff0000,
  441. .gpio_g_out = 0x3fff0000,
  442. .gpio_b = 0x00
  443. },
  444. {
  445. .ioif = if_gpio_grp_e,
  446. .name = "gpio_e",
  447. .groups = group_e,
  448. .group_a = 0,
  449. .group_b = 0,
  450. .group_c = 0,
  451. .group_d = 0,
  452. .group_e = 0,
  453. .group_f = 0,
  454. .gpio_g_in = 0x00000000,
  455. .gpio_g_out = 0x00000000,
  456. .gpio_b = 0x00
  457. },
  458. {
  459. .ioif = if_gpio_grp_f,
  460. .name = "gpio_f",
  461. .groups = group_f,
  462. .group_a = 0,
  463. .group_b = 0,
  464. .group_c = 0,
  465. .group_d = 0,
  466. .group_e = 0,
  467. .group_f = 0,
  468. .gpio_g_in = 0x00000000,
  469. .gpio_g_out = 0x00000000,
  470. .gpio_b = 0xff
  471. }
  472. /* Array end */
  473. };
  474. static struct watcher *watchers = NULL;
  475. /* The pins that are free to use in the GPIO ports. */
  476. static unsigned int gpio_in_pins = 0xffffffff;
  477. static unsigned int gpio_out_pins = 0xffffffff;
  478. static unsigned char gpio_pb_pins = 0xff;
  479. static unsigned char gpio_pa_pins = 0xff;
  480. /* Identifiers for the owners of the GPIO pins. */
  481. static enum cris_io_interface gpio_pa_owners[8];
  482. static enum cris_io_interface gpio_pb_owners[8];
  483. static enum cris_io_interface gpio_pg_owners[32];
  484. static int cris_io_interface_init(void);
  485. static unsigned char clear_group_from_set(const unsigned char groups, struct if_group *group)
  486. {
  487. return (groups & ~group->group);
  488. }
  489. static struct if_group *get_group(const unsigned char groups)
  490. {
  491. int i;
  492. for (i = 0; i < ARRAY_SIZE(if_groups); i++) {
  493. if (groups & if_groups[i].group) {
  494. return &if_groups[i];
  495. }
  496. }
  497. return NULL;
  498. }
  499. static void notify_watchers(void)
  500. {
  501. struct watcher *w = watchers;
  502. DBG(printk("io_interface_mux: notifying watchers\n"));
  503. while (NULL != w) {
  504. w->notify((const unsigned int)gpio_in_pins,
  505. (const unsigned int)gpio_out_pins,
  506. (const unsigned char)gpio_pa_pins,
  507. (const unsigned char)gpio_pb_pins);
  508. w = w->next;
  509. }
  510. }
  511. int cris_request_io_interface(enum cris_io_interface ioif, const char *device_id)
  512. {
  513. int set_gen_config = 0;
  514. int set_gen_config_ii = 0;
  515. unsigned long int gens;
  516. unsigned long int gens_ii;
  517. struct if_group *grp;
  518. unsigned char group_set;
  519. unsigned long flags;
  520. int res = 0;
  521. (void)cris_io_interface_init();
  522. DBG(printk("cris_request_io_interface(%d, \"%s\")\n", ioif, device_id));
  523. if ((ioif >= if_max_interfaces) || (ioif < 0)) {
  524. printk(KERN_CRIT "cris_request_io_interface: Bad interface "
  525. "%u submitted for %s\n",
  526. ioif,
  527. device_id);
  528. return -EINVAL;
  529. }
  530. local_irq_save(flags);
  531. if (interfaces[ioif].used) {
  532. printk(KERN_CRIT "cris_io_interface: Cannot allocate interface "
  533. "%s for %s, in use by %s\n",
  534. interfaces[ioif].name,
  535. device_id,
  536. interfaces[ioif].owner);
  537. res = -EBUSY;
  538. goto exit;
  539. }
  540. /* Check that all required pins in the used groups are free
  541. * before allocating. */
  542. group_set = interfaces[ioif].groups;
  543. while (NULL != (grp = get_group(group_set))) {
  544. unsigned int if_group_use = 0;
  545. switch (grp->group) {
  546. case group_a:
  547. if_group_use = interfaces[ioif].group_a;
  548. break;
  549. case group_b:
  550. if_group_use = interfaces[ioif].group_b;
  551. break;
  552. case group_c:
  553. if_group_use = interfaces[ioif].group_c;
  554. break;
  555. case group_d:
  556. if_group_use = interfaces[ioif].group_d;
  557. break;
  558. case group_e:
  559. if_group_use = interfaces[ioif].group_e;
  560. break;
  561. case group_f:
  562. if_group_use = interfaces[ioif].group_f;
  563. break;
  564. default:
  565. BUG_ON(1);
  566. }
  567. if (if_group_use & grp->used) {
  568. printk(KERN_INFO "cris_request_io_interface: group "
  569. "%s needed by %s not available\n",
  570. grp->name, interfaces[ioif].name);
  571. res = -EBUSY;
  572. goto exit;
  573. }
  574. group_set = clear_group_from_set(group_set, grp);
  575. }
  576. /* Are the required GPIO pins available too? */
  577. if (((interfaces[ioif].gpio_g_in & gpio_in_pins) !=
  578. interfaces[ioif].gpio_g_in) ||
  579. ((interfaces[ioif].gpio_g_out & gpio_out_pins) !=
  580. interfaces[ioif].gpio_g_out) ||
  581. ((interfaces[ioif].gpio_b & gpio_pb_pins) !=
  582. interfaces[ioif].gpio_b)) {
  583. printk(KERN_CRIT "cris_request_io_interface: Could not get "
  584. "required pins for interface %u\n", ioif);
  585. res = -EBUSY;
  586. goto exit;
  587. }
  588. /* Check which registers need to be reconfigured. */
  589. gens = genconfig_shadow;
  590. gens_ii = gen_config_ii_shadow;
  591. set_gen_config = 1;
  592. switch (ioif)
  593. {
  594. /* Begin Non-multiplexed interfaces */
  595. case if_eth:
  596. /* fall through */
  597. case if_serial_0:
  598. set_gen_config = 0;
  599. break;
  600. /* End Non-multiplexed interfaces */
  601. case if_serial_1:
  602. set_gen_config_ii = 1;
  603. SETS(gens_ii, R_GEN_CONFIG_II, sermode1, async);
  604. break;
  605. case if_serial_2:
  606. SETS(gens, R_GEN_CONFIG, ser2, select);
  607. break;
  608. case if_serial_3:
  609. SETS(gens, R_GEN_CONFIG, ser3, select);
  610. set_gen_config_ii = 1;
  611. SETS(gens_ii, R_GEN_CONFIG_II, sermode3, async);
  612. break;
  613. case if_sync_serial_1:
  614. set_gen_config_ii = 1;
  615. SETS(gens_ii, R_GEN_CONFIG_II, sermode1, sync);
  616. break;
  617. case if_sync_serial_3:
  618. SETS(gens, R_GEN_CONFIG, ser3, select);
  619. set_gen_config_ii = 1;
  620. SETS(gens_ii, R_GEN_CONFIG_II, sermode3, sync);
  621. break;
  622. case if_shared_ram:
  623. SETS(gens, R_GEN_CONFIG, mio, select);
  624. break;
  625. case if_shared_ram_w:
  626. SETS(gens, R_GEN_CONFIG, mio_w, select);
  627. break;
  628. case if_par_0:
  629. SETS(gens, R_GEN_CONFIG, par0, select);
  630. break;
  631. case if_par_1:
  632. SETS(gens, R_GEN_CONFIG, par1, select);
  633. break;
  634. case if_par_w:
  635. SETS(gens, R_GEN_CONFIG, par0, select);
  636. SETS(gens, R_GEN_CONFIG, par_w, select);
  637. break;
  638. case if_scsi8_0:
  639. SETS(gens, R_GEN_CONFIG, scsi0, select);
  640. break;
  641. case if_scsi8_1:
  642. SETS(gens, R_GEN_CONFIG, scsi1, select);
  643. break;
  644. case if_scsi_w:
  645. SETS(gens, R_GEN_CONFIG, scsi0, select);
  646. SETS(gens, R_GEN_CONFIG, scsi0w, select);
  647. break;
  648. case if_ata:
  649. SETS(gens, R_GEN_CONFIG, ata, select);
  650. break;
  651. case if_csp:
  652. /* fall through */
  653. case if_i2c:
  654. set_gen_config = 0;
  655. break;
  656. case if_usb_1:
  657. SETS(gens, R_GEN_CONFIG, usb1, select);
  658. break;
  659. case if_usb_2:
  660. SETS(gens, R_GEN_CONFIG, usb2, select);
  661. break;
  662. case if_gpio_grp_a:
  663. /* GPIO groups are only accounted, don't do configuration changes. */
  664. /* fall through */
  665. case if_gpio_grp_b:
  666. /* fall through */
  667. case if_gpio_grp_c:
  668. /* fall through */
  669. case if_gpio_grp_d:
  670. /* fall through */
  671. case if_gpio_grp_e:
  672. /* fall through */
  673. case if_gpio_grp_f:
  674. set_gen_config = 0;
  675. break;
  676. default:
  677. printk(KERN_INFO "cris_request_io_interface: Bad interface "
  678. "%u submitted for %s\n",
  679. ioif, device_id);
  680. res = -EBUSY;
  681. goto exit;
  682. }
  683. /* All needed I/O pins and pin groups are free, allocate. */
  684. group_set = interfaces[ioif].groups;
  685. while (NULL != (grp = get_group(group_set))) {
  686. unsigned int if_group_use = 0;
  687. switch (grp->group) {
  688. case group_a:
  689. if_group_use = interfaces[ioif].group_a;
  690. break;
  691. case group_b:
  692. if_group_use = interfaces[ioif].group_b;
  693. break;
  694. case group_c:
  695. if_group_use = interfaces[ioif].group_c;
  696. break;
  697. case group_d:
  698. if_group_use = interfaces[ioif].group_d;
  699. break;
  700. case group_e:
  701. if_group_use = interfaces[ioif].group_e;
  702. break;
  703. case group_f:
  704. if_group_use = interfaces[ioif].group_f;
  705. break;
  706. default:
  707. BUG_ON(1);
  708. }
  709. grp->used |= if_group_use;
  710. group_set = clear_group_from_set(group_set, grp);
  711. }
  712. interfaces[ioif].used = 1;
  713. interfaces[ioif].owner = (char*)device_id;
  714. if (set_gen_config) {
  715. volatile int i;
  716. genconfig_shadow = gens;
  717. *R_GEN_CONFIG = genconfig_shadow;
  718. /* Wait 12 cycles before doing any DMA command */
  719. for(i = 6; i > 0; i--)
  720. nop();
  721. }
  722. if (set_gen_config_ii) {
  723. gen_config_ii_shadow = gens_ii;
  724. *R_GEN_CONFIG_II = gen_config_ii_shadow;
  725. }
  726. DBG(printk(KERN_DEBUG "GPIO pins: available before: "
  727. "g_in=0x%08x g_out=0x%08x pb=0x%02x\n",
  728. gpio_in_pins, gpio_out_pins, gpio_pb_pins));
  729. DBG(printk(KERN_DEBUG
  730. "grabbing pins: g_in=0x%08x g_out=0x%08x pb=0x%02x\n",
  731. interfaces[ioif].gpio_g_in,
  732. interfaces[ioif].gpio_g_out,
  733. interfaces[ioif].gpio_b));
  734. gpio_in_pins &= ~interfaces[ioif].gpio_g_in;
  735. gpio_out_pins &= ~interfaces[ioif].gpio_g_out;
  736. gpio_pb_pins &= ~interfaces[ioif].gpio_b;
  737. DBG(printk(KERN_DEBUG "GPIO pins: available after: "
  738. "g_in=0x%08x g_out=0x%08x pb=0x%02x\n",
  739. gpio_in_pins, gpio_out_pins, gpio_pb_pins));
  740. exit:
  741. local_irq_restore(flags);
  742. if (res == 0)
  743. notify_watchers();
  744. return res;
  745. }
  746. void cris_free_io_interface(enum cris_io_interface ioif)
  747. {
  748. struct if_group *grp;
  749. unsigned char group_set;
  750. unsigned long flags;
  751. (void)cris_io_interface_init();
  752. if ((ioif >= if_max_interfaces) || (ioif < 0)) {
  753. printk(KERN_CRIT "cris_free_io_interface: Bad interface %u\n",
  754. ioif);
  755. return;
  756. }
  757. local_irq_save(flags);
  758. if (!interfaces[ioif].used) {
  759. printk(KERN_CRIT "cris_free_io_interface: Freeing free interface %u\n",
  760. ioif);
  761. local_irq_restore(flags);
  762. return;
  763. }
  764. group_set = interfaces[ioif].groups;
  765. while (NULL != (grp = get_group(group_set))) {
  766. unsigned int if_group_use = 0;
  767. switch (grp->group) {
  768. case group_a:
  769. if_group_use = interfaces[ioif].group_a;
  770. break;
  771. case group_b:
  772. if_group_use = interfaces[ioif].group_b;
  773. break;
  774. case group_c:
  775. if_group_use = interfaces[ioif].group_c;
  776. break;
  777. case group_d:
  778. if_group_use = interfaces[ioif].group_d;
  779. break;
  780. case group_e:
  781. if_group_use = interfaces[ioif].group_e;
  782. break;
  783. case group_f:
  784. if_group_use = interfaces[ioif].group_f;
  785. break;
  786. default:
  787. BUG_ON(1);
  788. }
  789. if ((grp->used & if_group_use) != if_group_use)
  790. BUG_ON(1);
  791. grp->used = grp->used & ~if_group_use;
  792. group_set = clear_group_from_set(group_set, grp);
  793. }
  794. interfaces[ioif].used = 0;
  795. interfaces[ioif].owner = NULL;
  796. DBG(printk("GPIO pins: available before: g_in=0x%08x g_out=0x%08x pb=0x%02x\n",
  797. gpio_in_pins, gpio_out_pins, gpio_pb_pins));
  798. DBG(printk("freeing pins: g_in=0x%08x g_out=0x%08x pb=0x%02x\n",
  799. interfaces[ioif].gpio_g_in,
  800. interfaces[ioif].gpio_g_out,
  801. interfaces[ioif].gpio_b));
  802. gpio_in_pins |= interfaces[ioif].gpio_g_in;
  803. gpio_out_pins |= interfaces[ioif].gpio_g_out;
  804. gpio_pb_pins |= interfaces[ioif].gpio_b;
  805. DBG(printk("GPIO pins: available after: g_in=0x%08x g_out=0x%08x pb=0x%02x\n",
  806. gpio_in_pins, gpio_out_pins, gpio_pb_pins));
  807. local_irq_restore(flags);
  808. notify_watchers();
  809. }
  810. /* Create a bitmask from bit 0 (inclusive) to bit stop_bit
  811. (non-inclusive). stop_bit == 0 returns 0x0 */
  812. static inline unsigned int create_mask(const unsigned stop_bit)
  813. {
  814. /* Avoid overflow */
  815. if (stop_bit >= 32) {
  816. return 0xffffffff;
  817. }
  818. return (1<<stop_bit)-1;
  819. }
  820. /* port can be 'a', 'b' or 'g' */
  821. int cris_io_interface_allocate_pins(const enum cris_io_interface ioif,
  822. const char port,
  823. const unsigned start_bit,
  824. const unsigned stop_bit)
  825. {
  826. unsigned int i;
  827. unsigned int mask = 0;
  828. unsigned int tmp_mask;
  829. unsigned long int flags;
  830. enum cris_io_interface *owners;
  831. (void)cris_io_interface_init();
  832. DBG(printk("cris_io_interface_allocate_pins: if=%d port=%c start=%u stop=%u\n",
  833. ioif, port, start_bit, stop_bit));
  834. if (!((start_bit <= stop_bit) &&
  835. ((((port == 'a') || (port == 'b')) && (stop_bit < 8)) ||
  836. ((port == 'g') && (stop_bit < 32))))) {
  837. return -EINVAL;
  838. }
  839. mask = create_mask(stop_bit + 1);
  840. tmp_mask = create_mask(start_bit);
  841. mask &= ~tmp_mask;
  842. DBG(printk("cris_io_interface_allocate_pins: port=%c start=%u stop=%u mask=0x%08x\n",
  843. port, start_bit, stop_bit, mask));
  844. local_irq_save(flags);
  845. switch (port) {
  846. case 'a':
  847. if ((gpio_pa_pins & mask) != mask) {
  848. local_irq_restore(flags);
  849. return -EBUSY;
  850. }
  851. owners = gpio_pa_owners;
  852. gpio_pa_pins &= ~mask;
  853. break;
  854. case 'b':
  855. if ((gpio_pb_pins & mask) != mask) {
  856. local_irq_restore(flags);
  857. return -EBUSY;
  858. }
  859. owners = gpio_pb_owners;
  860. gpio_pb_pins &= ~mask;
  861. break;
  862. case 'g':
  863. if (((gpio_in_pins & mask) != mask) ||
  864. ((gpio_out_pins & mask) != mask)) {
  865. local_irq_restore(flags);
  866. return -EBUSY;
  867. }
  868. owners = gpio_pg_owners;
  869. gpio_in_pins &= ~mask;
  870. gpio_out_pins &= ~mask;
  871. break;
  872. default:
  873. local_irq_restore(flags);
  874. return -EINVAL;
  875. }
  876. for (i = start_bit; i <= stop_bit; i++) {
  877. owners[i] = ioif;
  878. }
  879. local_irq_restore(flags);
  880. notify_watchers();
  881. return 0;
  882. }
  883. /* port can be 'a', 'b' or 'g' */
  884. int cris_io_interface_free_pins(const enum cris_io_interface ioif,
  885. const char port,
  886. const unsigned start_bit,
  887. const unsigned stop_bit)
  888. {
  889. unsigned int i;
  890. unsigned int mask = 0;
  891. unsigned int tmp_mask;
  892. unsigned long int flags;
  893. enum cris_io_interface *owners;
  894. (void)cris_io_interface_init();
  895. if (!((start_bit <= stop_bit) &&
  896. ((((port == 'a') || (port == 'b')) && (stop_bit < 8)) ||
  897. ((port == 'g') && (stop_bit < 32))))) {
  898. return -EINVAL;
  899. }
  900. mask = create_mask(stop_bit + 1);
  901. tmp_mask = create_mask(start_bit);
  902. mask &= ~tmp_mask;
  903. DBG(printk("cris_io_interface_free_pins: port=%c start=%u stop=%u mask=0x%08x\n",
  904. port, start_bit, stop_bit, mask));
  905. local_irq_save(flags);
  906. switch (port) {
  907. case 'a':
  908. if ((~gpio_pa_pins & mask) != mask) {
  909. local_irq_restore(flags);
  910. printk(KERN_CRIT "cris_io_interface_free_pins: Freeing free pins");
  911. }
  912. owners = gpio_pa_owners;
  913. break;
  914. case 'b':
  915. if ((~gpio_pb_pins & mask) != mask) {
  916. local_irq_restore(flags);
  917. printk(KERN_CRIT "cris_io_interface_free_pins: Freeing free pins");
  918. }
  919. owners = gpio_pb_owners;
  920. break;
  921. case 'g':
  922. if (((~gpio_in_pins & mask) != mask) ||
  923. ((~gpio_out_pins & mask) != mask)) {
  924. local_irq_restore(flags);
  925. printk(KERN_CRIT "cris_io_interface_free_pins: Freeing free pins");
  926. }
  927. owners = gpio_pg_owners;
  928. break;
  929. default:
  930. owners = NULL; /* Cannot happen. Shut up, gcc! */
  931. }
  932. for (i = start_bit; i <= stop_bit; i++) {
  933. if (owners[i] != ioif) {
  934. printk(KERN_CRIT "cris_io_interface_free_pins: Freeing unowned pins");
  935. }
  936. }
  937. /* All was ok, change data. */
  938. switch (port) {
  939. case 'a':
  940. gpio_pa_pins |= mask;
  941. break;
  942. case 'b':
  943. gpio_pb_pins |= mask;
  944. break;
  945. case 'g':
  946. gpio_in_pins |= mask;
  947. gpio_out_pins |= mask;
  948. break;
  949. }
  950. for (i = start_bit; i <= stop_bit; i++) {
  951. owners[i] = if_unclaimed;
  952. }
  953. local_irq_restore(flags);
  954. notify_watchers();
  955. return 0;
  956. }
  957. int cris_io_interface_register_watcher(void (*notify)(const unsigned int gpio_in_available,
  958. const unsigned int gpio_out_available,
  959. const unsigned char pa_available,
  960. const unsigned char pb_available))
  961. {
  962. struct watcher *w;
  963. (void)cris_io_interface_init();
  964. if (NULL == notify) {
  965. return -EINVAL;
  966. }
  967. w = kmalloc(sizeof(*w), GFP_KERNEL);
  968. if (!w) {
  969. return -ENOMEM;
  970. }
  971. w->notify = notify;
  972. w->next = watchers;
  973. watchers = w;
  974. w->notify((const unsigned int)gpio_in_pins,
  975. (const unsigned int)gpio_out_pins,
  976. (const unsigned char)gpio_pa_pins,
  977. (const unsigned char)gpio_pb_pins);
  978. return 0;
  979. }
  980. void cris_io_interface_delete_watcher(void (*notify)(const unsigned int gpio_in_available,
  981. const unsigned int gpio_out_available,
  982. const unsigned char pa_available,
  983. const unsigned char pb_available))
  984. {
  985. struct watcher *w = watchers, *prev = NULL;
  986. (void)cris_io_interface_init();
  987. while ((NULL != w) && (w->notify != notify)){
  988. prev = w;
  989. w = w->next;
  990. }
  991. if (NULL != w) {
  992. if (NULL != prev) {
  993. prev->next = w->next;
  994. } else {
  995. watchers = w->next;
  996. }
  997. kfree(w);
  998. return;
  999. }
  1000. printk(KERN_WARNING "cris_io_interface_delete_watcher: Deleting unknown watcher 0x%p\n", notify);
  1001. }
  1002. static int cris_io_interface_init(void)
  1003. {
  1004. static int first = 1;
  1005. int i;
  1006. if (!first) {
  1007. return 0;
  1008. }
  1009. first = 0;
  1010. for (i = 0; i<8; i++) {
  1011. gpio_pa_owners[i] = if_unclaimed;
  1012. gpio_pb_owners[i] = if_unclaimed;
  1013. gpio_pg_owners[i] = if_unclaimed;
  1014. }
  1015. for (; i<32; i++) {
  1016. gpio_pg_owners[i] = if_unclaimed;
  1017. }
  1018. return 0;
  1019. }
  1020. module_init(cris_io_interface_init);
  1021. EXPORT_SYMBOL(cris_request_io_interface);
  1022. EXPORT_SYMBOL(cris_free_io_interface);
  1023. EXPORT_SYMBOL(cris_io_interface_allocate_pins);
  1024. EXPORT_SYMBOL(cris_io_interface_free_pins);
  1025. EXPORT_SYMBOL(cris_io_interface_register_watcher);
  1026. EXPORT_SYMBOL(cris_io_interface_delete_watcher);