m32r_cfc.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789
  1. /*
  2. * drivers/pcmcia/m32r_cfc.c
  3. *
  4. * Device driver for the CFC functionality of M32R.
  5. *
  6. * Copyright (c) 2001, 2002, 2003, 2004
  7. * Hiroyuki Kondo, Naoto Sugai, Hayato Fujiwara
  8. */
  9. #include <linux/module.h>
  10. #include <linux/moduleparam.h>
  11. #include <linux/init.h>
  12. #include <linux/types.h>
  13. #include <linux/fcntl.h>
  14. #include <linux/string.h>
  15. #include <linux/kernel.h>
  16. #include <linux/errno.h>
  17. #include <linux/timer.h>
  18. #include <linux/ioport.h>
  19. #include <linux/delay.h>
  20. #include <linux/workqueue.h>
  21. #include <linux/interrupt.h>
  22. #include <linux/platform_device.h>
  23. #include <linux/bitops.h>
  24. #include <asm/irq.h>
  25. #include <asm/io.h>
  26. #include <pcmcia/ss.h>
  27. #undef MAX_IO_WIN /* FIXME */
  28. #define MAX_IO_WIN 1
  29. #undef MAX_WIN /* FIXME */
  30. #define MAX_WIN 1
  31. #include "m32r_cfc.h"
  32. /* Poll status interval -- 0 means default to interrupt */
  33. static int poll_interval = 0;
  34. typedef enum pcc_space { as_none = 0, as_comm, as_attr, as_io } pcc_as_t;
  35. typedef struct pcc_socket {
  36. u_short type, flags;
  37. struct pcmcia_socket socket;
  38. unsigned int number;
  39. unsigned int ioaddr;
  40. u_long mapaddr;
  41. u_long base; /* PCC register base */
  42. u_char cs_irq1, cs_irq2, intr;
  43. pccard_io_map io_map[MAX_IO_WIN];
  44. pccard_mem_map mem_map[MAX_WIN];
  45. u_char io_win;
  46. u_char mem_win;
  47. pcc_as_t current_space;
  48. u_char last_iodbex;
  49. #ifdef CONFIG_PROC_FS
  50. struct proc_dir_entry *proc;
  51. #endif
  52. } pcc_socket_t;
  53. static int pcc_sockets = 0;
  54. static pcc_socket_t socket[M32R_MAX_PCC] = {
  55. { 0, }, /* ... */
  56. };
  57. /*====================================================================*/
  58. static unsigned int pcc_get(u_short, unsigned int);
  59. static void pcc_set(u_short, unsigned int , unsigned int );
  60. static DEFINE_SPINLOCK(pcc_lock);
  61. #if !defined(CONFIG_PLAT_USRV)
  62. static inline u_long pcc_port2addr(unsigned long port, int size) {
  63. u_long addr = 0;
  64. u_long odd;
  65. if (size == 1) { /* byte access */
  66. odd = (port&1) << 11;
  67. port -= port & 1;
  68. addr = CFC_IO_MAPBASE_BYTE - CFC_IOPORT_BASE + odd + port;
  69. } else if (size == 2)
  70. addr = CFC_IO_MAPBASE_WORD - CFC_IOPORT_BASE + port;
  71. return addr;
  72. }
  73. #else /* CONFIG_PLAT_USRV */
  74. static inline u_long pcc_port2addr(unsigned long port, int size) {
  75. u_long odd;
  76. u_long addr = ((port - CFC_IOPORT_BASE) & 0xf000) << 8;
  77. if (size == 1) { /* byte access */
  78. odd = port & 1;
  79. port -= odd;
  80. odd <<= 11;
  81. addr = (addr | CFC_IO_MAPBASE_BYTE) + odd + (port & 0xfff);
  82. } else if (size == 2) /* word access */
  83. addr = (addr | CFC_IO_MAPBASE_WORD) + (port & 0xfff);
  84. return addr;
  85. }
  86. #endif /* CONFIG_PLAT_USRV */
  87. void pcc_ioread_byte(int sock, unsigned long port, void *buf, size_t size,
  88. size_t nmemb, int flag)
  89. {
  90. u_long addr;
  91. unsigned char *bp = (unsigned char *)buf;
  92. unsigned long flags;
  93. pr_debug("m32r_cfc: pcc_ioread_byte: sock=%d, port=%#lx, buf=%p, "
  94. "size=%u, nmemb=%d, flag=%d\n",
  95. sock, port, buf, size, nmemb, flag);
  96. addr = pcc_port2addr(port, 1);
  97. if (!addr) {
  98. printk("m32r_cfc:ioread_byte null port :%#lx\n",port);
  99. return;
  100. }
  101. pr_debug("m32r_cfc: pcc_ioread_byte: addr=%#lx\n", addr);
  102. spin_lock_irqsave(&pcc_lock, flags);
  103. /* read Byte */
  104. while (nmemb--)
  105. *bp++ = readb(addr);
  106. spin_unlock_irqrestore(&pcc_lock, flags);
  107. }
  108. void pcc_ioread_word(int sock, unsigned long port, void *buf, size_t size,
  109. size_t nmemb, int flag)
  110. {
  111. u_long addr;
  112. unsigned short *bp = (unsigned short *)buf;
  113. unsigned long flags;
  114. pr_debug("m32r_cfc: pcc_ioread_word: sock=%d, port=%#lx, "
  115. "buf=%p, size=%u, nmemb=%d, flag=%d\n",
  116. sock, port, buf, size, nmemb, flag);
  117. if (size != 2)
  118. printk("m32r_cfc: ioread_word :illigal size %u : %#lx\n", size,
  119. port);
  120. if (size == 9)
  121. printk("m32r_cfc: ioread_word :insw \n");
  122. addr = pcc_port2addr(port, 2);
  123. if (!addr) {
  124. printk("m32r_cfc:ioread_word null port :%#lx\n",port);
  125. return;
  126. }
  127. pr_debug("m32r_cfc: pcc_ioread_word: addr=%#lx\n", addr);
  128. spin_lock_irqsave(&pcc_lock, flags);
  129. /* read Word */
  130. while (nmemb--)
  131. *bp++ = readw(addr);
  132. spin_unlock_irqrestore(&pcc_lock, flags);
  133. }
  134. void pcc_iowrite_byte(int sock, unsigned long port, void *buf, size_t size,
  135. size_t nmemb, int flag)
  136. {
  137. u_long addr;
  138. unsigned char *bp = (unsigned char *)buf;
  139. unsigned long flags;
  140. pr_debug("m32r_cfc: pcc_iowrite_byte: sock=%d, port=%#lx, "
  141. "buf=%p, size=%u, nmemb=%d, flag=%d\n",
  142. sock, port, buf, size, nmemb, flag);
  143. /* write Byte */
  144. addr = pcc_port2addr(port, 1);
  145. if (!addr) {
  146. printk("m32r_cfc:iowrite_byte null port:%#lx\n",port);
  147. return;
  148. }
  149. pr_debug("m32r_cfc: pcc_iowrite_byte: addr=%#lx\n", addr);
  150. spin_lock_irqsave(&pcc_lock, flags);
  151. while (nmemb--)
  152. writeb(*bp++, addr);
  153. spin_unlock_irqrestore(&pcc_lock, flags);
  154. }
  155. void pcc_iowrite_word(int sock, unsigned long port, void *buf, size_t size,
  156. size_t nmemb, int flag)
  157. {
  158. u_long addr;
  159. unsigned short *bp = (unsigned short *)buf;
  160. unsigned long flags;
  161. pr_debug("m32r_cfc: pcc_iowrite_word: sock=%d, port=%#lx, "
  162. "buf=%p, size=%u, nmemb=%d, flag=%d\n",
  163. sock, port, buf, size, nmemb, flag);
  164. if(size != 2)
  165. printk("m32r_cfc: iowrite_word :illigal size %u : %#lx\n",
  166. size, port);
  167. if(size == 9)
  168. printk("m32r_cfc: iowrite_word :outsw \n");
  169. addr = pcc_port2addr(port, 2);
  170. if (!addr) {
  171. printk("m32r_cfc:iowrite_word null addr :%#lx\n",port);
  172. return;
  173. }
  174. #if 1
  175. if (addr & 1) {
  176. printk("m32r_cfc:iowrite_word port addr (%#lx):%#lx\n", port,
  177. addr);
  178. return;
  179. }
  180. #endif
  181. pr_debug("m32r_cfc: pcc_iowrite_word: addr=%#lx\n", addr);
  182. spin_lock_irqsave(&pcc_lock, flags);
  183. while (nmemb--)
  184. writew(*bp++, addr);
  185. spin_unlock_irqrestore(&pcc_lock, flags);
  186. }
  187. /*====================================================================*/
  188. #define IS_REGISTERED 0x2000
  189. #define IS_ALIVE 0x8000
  190. typedef struct pcc_t {
  191. char *name;
  192. u_short flags;
  193. } pcc_t;
  194. static pcc_t pcc[] = {
  195. #if !defined(CONFIG_PLAT_USRV)
  196. { "m32r_cfc", 0 }, { "", 0 },
  197. #else /* CONFIG_PLAT_USRV */
  198. { "m32r_cfc", 0 }, { "m32r_cfc", 0 }, { "m32r_cfc", 0 },
  199. { "m32r_cfc", 0 }, { "m32r_cfc", 0 }, { "", 0 },
  200. #endif /* CONFIG_PLAT_USRV */
  201. };
  202. static irqreturn_t pcc_interrupt(int, void *);
  203. /*====================================================================*/
  204. static struct timer_list poll_timer;
  205. static unsigned int pcc_get(u_short sock, unsigned int reg)
  206. {
  207. unsigned int val = inw(reg);
  208. pr_debug("m32r_cfc: pcc_get: reg(0x%08x)=0x%04x\n", reg, val);
  209. return val;
  210. }
  211. static void pcc_set(u_short sock, unsigned int reg, unsigned int data)
  212. {
  213. outw(data, reg);
  214. pr_debug("m32r_cfc: pcc_set: reg(0x%08x)=0x%04x\n", reg, data);
  215. }
  216. /*======================================================================
  217. See if a card is present, powered up, in IO mode, and already
  218. bound to a (non PC Card) Linux driver. We leave these alone.
  219. We make an exception for cards that seem to be serial devices.
  220. ======================================================================*/
  221. static int __init is_alive(u_short sock)
  222. {
  223. unsigned int stat;
  224. pr_debug("m32r_cfc: is_alive:\n");
  225. printk("CF: ");
  226. stat = pcc_get(sock, (unsigned int)PLD_CFSTS);
  227. if (!stat)
  228. printk("No ");
  229. printk("Card is detected at socket %d : stat = 0x%08x\n", sock, stat);
  230. pr_debug("m32r_cfc: is_alive: sock stat is 0x%04x\n", stat);
  231. return 0;
  232. }
  233. static void add_pcc_socket(ulong base, int irq, ulong mapaddr,
  234. unsigned int ioaddr)
  235. {
  236. pcc_socket_t *t = &socket[pcc_sockets];
  237. pr_debug("m32r_cfc: add_pcc_socket: base=%#lx, irq=%d, "
  238. "mapaddr=%#lx, ioaddr=%08x\n",
  239. base, irq, mapaddr, ioaddr);
  240. /* add sockets */
  241. t->ioaddr = ioaddr;
  242. t->mapaddr = mapaddr;
  243. #if !defined(CONFIG_PLAT_USRV)
  244. t->base = 0;
  245. t->flags = 0;
  246. t->cs_irq1 = irq; // insert irq
  247. t->cs_irq2 = irq + 1; // eject irq
  248. #else /* CONFIG_PLAT_USRV */
  249. t->base = base;
  250. t->flags = 0;
  251. t->cs_irq1 = 0; // insert irq
  252. t->cs_irq2 = 0; // eject irq
  253. #endif /* CONFIG_PLAT_USRV */
  254. if (is_alive(pcc_sockets))
  255. t->flags |= IS_ALIVE;
  256. /* add pcc */
  257. #if !defined(CONFIG_PLAT_USRV)
  258. request_region((unsigned int)PLD_CFRSTCR, 0x20, "m32r_cfc");
  259. #else /* CONFIG_PLAT_USRV */
  260. {
  261. unsigned int reg_base;
  262. reg_base = (unsigned int)PLD_CFRSTCR;
  263. reg_base |= pcc_sockets << 8;
  264. request_region(reg_base, 0x20, "m32r_cfc");
  265. }
  266. #endif /* CONFIG_PLAT_USRV */
  267. printk(KERN_INFO " %s ", pcc[pcc_sockets].name);
  268. printk("pcc at 0x%08lx\n", t->base);
  269. /* Update socket interrupt information, capabilities */
  270. t->socket.features |= (SS_CAP_PCCARD | SS_CAP_STATIC_MAP);
  271. t->socket.map_size = M32R_PCC_MAPSIZE;
  272. t->socket.io_offset = ioaddr; /* use for io access offset */
  273. t->socket.irq_mask = 0;
  274. #if !defined(CONFIG_PLAT_USRV)
  275. t->socket.pci_irq = PLD_IRQ_CFIREQ ; /* card interrupt */
  276. #else /* CONFIG_PLAT_USRV */
  277. t->socket.pci_irq = PLD_IRQ_CF0 + pcc_sockets;
  278. #endif /* CONFIG_PLAT_USRV */
  279. #ifndef CONFIG_PLAT_USRV
  280. /* insert interrupt */
  281. request_irq(irq, pcc_interrupt, 0, "m32r_cfc", pcc_interrupt);
  282. #ifndef CONFIG_PLAT_MAPPI3
  283. /* eject interrupt */
  284. request_irq(irq+1, pcc_interrupt, 0, "m32r_cfc", pcc_interrupt);
  285. #endif
  286. pr_debug("m32r_cfc: enable CFMSK, RDYSEL\n");
  287. pcc_set(pcc_sockets, (unsigned int)PLD_CFIMASK, 0x01);
  288. #endif /* CONFIG_PLAT_USRV */
  289. #if defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_USRV) || defined(CONFIG_PLAT_OPSPUT)
  290. pcc_set(pcc_sockets, (unsigned int)PLD_CFCR1, 0x0200);
  291. #endif
  292. pcc_sockets++;
  293. return;
  294. }
  295. /*====================================================================*/
  296. static irqreturn_t pcc_interrupt(int irq, void *dev)
  297. {
  298. int i;
  299. u_int events = 0;
  300. int handled = 0;
  301. pr_debug("m32r_cfc: pcc_interrupt: irq=%d, dev=%p\n", irq, dev);
  302. for (i = 0; i < pcc_sockets; i++) {
  303. if (socket[i].cs_irq1 != irq && socket[i].cs_irq2 != irq)
  304. continue;
  305. handled = 1;
  306. pr_debug("m32r_cfc: pcc_interrupt: socket %d irq 0x%02x ",
  307. i, irq);
  308. events |= SS_DETECT; /* insert or eject */
  309. if (events)
  310. pcmcia_parse_events(&socket[i].socket, events);
  311. }
  312. pr_debug("m32r_cfc: pcc_interrupt: done\n");
  313. return IRQ_RETVAL(handled);
  314. } /* pcc_interrupt */
  315. static void pcc_interrupt_wrapper(u_long data)
  316. {
  317. pr_debug("m32r_cfc: pcc_interrupt_wrapper:\n");
  318. pcc_interrupt(0, NULL);
  319. init_timer(&poll_timer);
  320. poll_timer.expires = jiffies + poll_interval;
  321. add_timer(&poll_timer);
  322. }
  323. /*====================================================================*/
  324. static int _pcc_get_status(u_short sock, u_int *value)
  325. {
  326. u_int status;
  327. pr_debug("m32r_cfc: _pcc_get_status:\n");
  328. status = pcc_get(sock, (unsigned int)PLD_CFSTS);
  329. *value = (status) ? SS_DETECT : 0;
  330. pr_debug("m32r_cfc: _pcc_get_status: status=0x%08x\n", status);
  331. #if defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_USRV) || defined(CONFIG_PLAT_OPSPUT)
  332. if ( status ) {
  333. /* enable CF power */
  334. status = inw((unsigned int)PLD_CPCR);
  335. if (!(status & PLD_CPCR_CF)) {
  336. pr_debug("m32r_cfc: _pcc_get_status: "
  337. "power on (CPCR=0x%08x)\n", status);
  338. status |= PLD_CPCR_CF;
  339. outw(status, (unsigned int)PLD_CPCR);
  340. udelay(100);
  341. }
  342. *value |= SS_POWERON;
  343. pcc_set(sock, (unsigned int)PLD_CFBUFCR,0);/* enable buffer */
  344. udelay(100);
  345. *value |= SS_READY; /* always ready */
  346. *value |= SS_3VCARD;
  347. } else {
  348. /* disable CF power */
  349. status = inw((unsigned int)PLD_CPCR);
  350. status &= ~PLD_CPCR_CF;
  351. outw(status, (unsigned int)PLD_CPCR);
  352. udelay(100);
  353. pr_debug("m32r_cfc: _pcc_get_status: "
  354. "power off (CPCR=0x%08x)\n", status);
  355. }
  356. #elif defined(CONFIG_PLAT_MAPPI2) || defined(CONFIG_PLAT_MAPPI3)
  357. if ( status ) {
  358. status = pcc_get(sock, (unsigned int)PLD_CPCR);
  359. if (status == 0) { /* power off */
  360. pcc_set(sock, (unsigned int)PLD_CPCR, 1);
  361. pcc_set(sock, (unsigned int)PLD_CFBUFCR,0); /* force buffer off for ZA-36 */
  362. udelay(50);
  363. }
  364. *value |= SS_POWERON;
  365. pcc_set(sock, (unsigned int)PLD_CFBUFCR,0);
  366. udelay(50);
  367. pcc_set(sock, (unsigned int)PLD_CFRSTCR, 0x0101);
  368. udelay(25); /* for IDE reset */
  369. pcc_set(sock, (unsigned int)PLD_CFRSTCR, 0x0100);
  370. mdelay(2); /* for IDE reset */
  371. *value |= SS_READY;
  372. *value |= SS_3VCARD;
  373. } else {
  374. /* disable CF power */
  375. pcc_set(sock, (unsigned int)PLD_CPCR, 0);
  376. udelay(100);
  377. pr_debug("m32r_cfc: _pcc_get_status: "
  378. "power off (CPCR=0x%08x)\n", status);
  379. }
  380. #else
  381. #error no platform configuration
  382. #endif
  383. pr_debug("m32r_cfc: _pcc_get_status: GetStatus(%d) = %#4.4x\n",
  384. sock, *value);
  385. return 0;
  386. } /* _get_status */
  387. /*====================================================================*/
  388. static int _pcc_set_socket(u_short sock, socket_state_t *state)
  389. {
  390. pr_debug("m32r_cfc: SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
  391. "io_irq %d, csc_mask %#2.2x)\n", sock, state->flags,
  392. state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
  393. #if defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_USRV) || defined(CONFIG_PLAT_OPSPUT) || defined(CONFIG_PLAT_MAPPI2) || defined(CONFIG_PLAT_MAPPI3)
  394. if (state->Vcc) {
  395. if ((state->Vcc != 50) && (state->Vcc != 33))
  396. return -EINVAL;
  397. /* accept 5V and 3.3V */
  398. }
  399. #endif
  400. if (state->flags & SS_RESET) {
  401. pr_debug(":RESET\n");
  402. pcc_set(sock,(unsigned int)PLD_CFRSTCR,0x101);
  403. }else{
  404. pcc_set(sock,(unsigned int)PLD_CFRSTCR,0x100);
  405. }
  406. if (state->flags & SS_OUTPUT_ENA){
  407. pr_debug(":OUTPUT_ENA\n");
  408. /* bit clear */
  409. pcc_set(sock,(unsigned int)PLD_CFBUFCR,0);
  410. } else {
  411. pcc_set(sock,(unsigned int)PLD_CFBUFCR,1);
  412. }
  413. if(state->flags & SS_IOCARD){
  414. pr_debug(":IOCARD");
  415. }
  416. if (state->flags & SS_PWR_AUTO) {
  417. pr_debug(":PWR_AUTO");
  418. }
  419. if (state->csc_mask & SS_DETECT)
  420. pr_debug(":csc-SS_DETECT");
  421. if (state->flags & SS_IOCARD) {
  422. if (state->csc_mask & SS_STSCHG)
  423. pr_debug(":STSCHG");
  424. } else {
  425. if (state->csc_mask & SS_BATDEAD)
  426. pr_debug(":BATDEAD");
  427. if (state->csc_mask & SS_BATWARN)
  428. pr_debug(":BATWARN");
  429. if (state->csc_mask & SS_READY)
  430. pr_debug(":READY");
  431. }
  432. pr_debug("\n");
  433. return 0;
  434. } /* _set_socket */
  435. /*====================================================================*/
  436. static int _pcc_set_io_map(u_short sock, struct pccard_io_map *io)
  437. {
  438. u_char map;
  439. pr_debug("m32r_cfc: SetIOMap(%d, %d, %#2.2x, %d ns, "
  440. "%#llx-%#llx)\n", sock, io->map, io->flags,
  441. io->speed, (unsigned long long)io->start,
  442. (unsigned long long)io->stop);
  443. map = io->map;
  444. return 0;
  445. } /* _set_io_map */
  446. /*====================================================================*/
  447. static int _pcc_set_mem_map(u_short sock, struct pccard_mem_map *mem)
  448. {
  449. u_char map = mem->map;
  450. u_long addr;
  451. pcc_socket_t *t = &socket[sock];
  452. pr_debug("m32r_cfc: SetMemMap(%d, %d, %#2.2x, %d ns, "
  453. "%#llx, %#x)\n", sock, map, mem->flags,
  454. mem->speed, (unsigned long long)mem->static_start,
  455. mem->card_start);
  456. /*
  457. * sanity check
  458. */
  459. if ((map > MAX_WIN) || (mem->card_start > 0x3ffffff)){
  460. return -EINVAL;
  461. }
  462. /*
  463. * de-activate
  464. */
  465. if ((mem->flags & MAP_ACTIVE) == 0) {
  466. t->current_space = as_none;
  467. return 0;
  468. }
  469. /*
  470. * Set mode
  471. */
  472. if (mem->flags & MAP_ATTRIB) {
  473. t->current_space = as_attr;
  474. } else {
  475. t->current_space = as_comm;
  476. }
  477. /*
  478. * Set address
  479. */
  480. addr = t->mapaddr + (mem->card_start & M32R_PCC_MAPMASK);
  481. mem->static_start = addr + mem->card_start;
  482. return 0;
  483. } /* _set_mem_map */
  484. #if 0 /* driver model ordering issue */
  485. /*======================================================================
  486. Routines for accessing socket information and register dumps via
  487. /proc/bus/pccard/...
  488. ======================================================================*/
  489. static ssize_t show_info(struct class_device *class_dev, char *buf)
  490. {
  491. pcc_socket_t *s = container_of(class_dev, struct pcc_socket,
  492. socket.dev);
  493. return sprintf(buf, "type: %s\nbase addr: 0x%08lx\n",
  494. pcc[s->type].name, s->base);
  495. }
  496. static ssize_t show_exca(struct class_device *class_dev, char *buf)
  497. {
  498. /* FIXME */
  499. return 0;
  500. }
  501. static CLASS_DEVICE_ATTR(info, S_IRUGO, show_info, NULL);
  502. static CLASS_DEVICE_ATTR(exca, S_IRUGO, show_exca, NULL);
  503. #endif
  504. /*====================================================================*/
  505. /* this is horribly ugly... proper locking needs to be done here at
  506. * some time... */
  507. #define LOCKED(x) do { \
  508. int retval; \
  509. unsigned long flags; \
  510. spin_lock_irqsave(&pcc_lock, flags); \
  511. retval = x; \
  512. spin_unlock_irqrestore(&pcc_lock, flags); \
  513. return retval; \
  514. } while (0)
  515. static int pcc_get_status(struct pcmcia_socket *s, u_int *value)
  516. {
  517. unsigned int sock = container_of(s, struct pcc_socket, socket)->number;
  518. if (socket[sock].flags & IS_ALIVE) {
  519. dev_dbg(&s->dev, "pcc_get_status: sock(%d) -EINVAL\n", sock);
  520. *value = 0;
  521. return -EINVAL;
  522. }
  523. dev_dbg(&s->dev, "pcc_get_status: sock(%d)\n", sock);
  524. LOCKED(_pcc_get_status(sock, value));
  525. }
  526. static int pcc_set_socket(struct pcmcia_socket *s, socket_state_t *state)
  527. {
  528. unsigned int sock = container_of(s, struct pcc_socket, socket)->number;
  529. if (socket[sock].flags & IS_ALIVE) {
  530. dev_dbg(&s->dev, "pcc_set_socket: sock(%d) -EINVAL\n", sock);
  531. return -EINVAL;
  532. }
  533. dev_dbg(&s->dev, "pcc_set_socket: sock(%d)\n", sock);
  534. LOCKED(_pcc_set_socket(sock, state));
  535. }
  536. static int pcc_set_io_map(struct pcmcia_socket *s, struct pccard_io_map *io)
  537. {
  538. unsigned int sock = container_of(s, struct pcc_socket, socket)->number;
  539. if (socket[sock].flags & IS_ALIVE) {
  540. dev_dbg(&s->dev, "pcc_set_io_map: sock(%d) -EINVAL\n", sock);
  541. return -EINVAL;
  542. }
  543. dev_dbg(&s->dev, "pcc_set_io_map: sock(%d)\n", sock);
  544. LOCKED(_pcc_set_io_map(sock, io));
  545. }
  546. static int pcc_set_mem_map(struct pcmcia_socket *s, struct pccard_mem_map *mem)
  547. {
  548. unsigned int sock = container_of(s, struct pcc_socket, socket)->number;
  549. if (socket[sock].flags & IS_ALIVE) {
  550. dev_dbg(&s->dev, "pcc_set_mem_map: sock(%d) -EINVAL\n", sock);
  551. return -EINVAL;
  552. }
  553. dev_dbg(&s->dev, "pcc_set_mem_map: sock(%d)\n", sock);
  554. LOCKED(_pcc_set_mem_map(sock, mem));
  555. }
  556. static int pcc_init(struct pcmcia_socket *s)
  557. {
  558. dev_dbg(&s->dev, "pcc_init()\n");
  559. return 0;
  560. }
  561. static struct pccard_operations pcc_operations = {
  562. .init = pcc_init,
  563. .get_status = pcc_get_status,
  564. .set_socket = pcc_set_socket,
  565. .set_io_map = pcc_set_io_map,
  566. .set_mem_map = pcc_set_mem_map,
  567. };
  568. /*====================================================================*/
  569. static struct platform_driver pcc_driver = {
  570. .driver = {
  571. .name = "cfc",
  572. },
  573. };
  574. static struct platform_device pcc_device = {
  575. .name = "cfc",
  576. .id = 0,
  577. };
  578. /*====================================================================*/
  579. static int __init init_m32r_pcc(void)
  580. {
  581. int i, ret;
  582. ret = platform_driver_register(&pcc_driver);
  583. if (ret)
  584. return ret;
  585. ret = platform_device_register(&pcc_device);
  586. if (ret){
  587. platform_driver_unregister(&pcc_driver);
  588. return ret;
  589. }
  590. #if defined(CONFIG_PLAT_MAPPI2) || defined(CONFIG_PLAT_MAPPI3)
  591. pcc_set(0, (unsigned int)PLD_CFCR0, 0x0f0f);
  592. pcc_set(0, (unsigned int)PLD_CFCR1, 0x0200);
  593. #endif
  594. pcc_sockets = 0;
  595. #if !defined(CONFIG_PLAT_USRV)
  596. add_pcc_socket(M32R_PCC0_BASE, PLD_IRQ_CFC_INSERT, CFC_ATTR_MAPBASE,
  597. CFC_IOPORT_BASE);
  598. #else /* CONFIG_PLAT_USRV */
  599. {
  600. ulong base, mapaddr;
  601. unsigned int ioaddr;
  602. for (i = 0 ; i < M32R_MAX_PCC ; i++) {
  603. base = (ulong)PLD_CFRSTCR;
  604. base = base | (i << 8);
  605. ioaddr = (i + 1) << 12;
  606. mapaddr = CFC_ATTR_MAPBASE | (i << 20);
  607. add_pcc_socket(base, 0, mapaddr, ioaddr);
  608. }
  609. }
  610. #endif /* CONFIG_PLAT_USRV */
  611. if (pcc_sockets == 0) {
  612. printk("socket is not found.\n");
  613. platform_device_unregister(&pcc_device);
  614. platform_driver_unregister(&pcc_driver);
  615. return -ENODEV;
  616. }
  617. /* Set up interrupt handler(s) */
  618. for (i = 0 ; i < pcc_sockets ; i++) {
  619. socket[i].socket.dev.parent = &pcc_device.dev;
  620. socket[i].socket.ops = &pcc_operations;
  621. socket[i].socket.resource_ops = &pccard_static_ops;
  622. socket[i].socket.owner = THIS_MODULE;
  623. socket[i].number = i;
  624. ret = pcmcia_register_socket(&socket[i].socket);
  625. if (!ret)
  626. socket[i].flags |= IS_REGISTERED;
  627. }
  628. /* Finally, schedule a polling interrupt */
  629. if (poll_interval != 0) {
  630. poll_timer.function = pcc_interrupt_wrapper;
  631. poll_timer.data = 0;
  632. init_timer(&poll_timer);
  633. poll_timer.expires = jiffies + poll_interval;
  634. add_timer(&poll_timer);
  635. }
  636. return 0;
  637. } /* init_m32r_pcc */
  638. static void __exit exit_m32r_pcc(void)
  639. {
  640. int i;
  641. for (i = 0; i < pcc_sockets; i++)
  642. if (socket[i].flags & IS_REGISTERED)
  643. pcmcia_unregister_socket(&socket[i].socket);
  644. platform_device_unregister(&pcc_device);
  645. if (poll_interval != 0)
  646. del_timer_sync(&poll_timer);
  647. platform_driver_unregister(&pcc_driver);
  648. } /* exit_m32r_pcc */
  649. module_init(init_m32r_pcc);
  650. module_exit(exit_m32r_pcc);
  651. MODULE_LICENSE("Dual MPL/GPL");
  652. /*====================================================================*/