io.c 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. /*
  2. * arch/sh/boards/renesas/edosk7705/io.c
  3. *
  4. * Copyright (C) 2001 Ian da Silva, Jeremy Siegel
  5. * Based largely on io_se.c.
  6. *
  7. * I/O routines for Hitachi EDOSK7705 board.
  8. *
  9. */
  10. #include <linux/kernel.h>
  11. #include <linux/types.h>
  12. #include <asm/io.h>
  13. #include <asm/edosk7705/io.h>
  14. #include <asm/addrspace.h>
  15. #define SMC_IOADDR 0xA2000000
  16. #define maybebadio(name,port) \
  17. printk("bad PC-like io %s for port 0x%lx at 0x%08x\n", \
  18. #name, (port), (__u32) __builtin_return_address(0))
  19. /* Map the Ethernet addresses as if it is at 0x300 - 0x320 */
  20. unsigned long sh_edosk7705_isa_port2addr(unsigned long port)
  21. {
  22. if (port >= 0x300 && port < 0x320) {
  23. /* SMC91C96 registers are 4 byte aligned rather than the
  24. * usual 2 byte!
  25. */
  26. return SMC_IOADDR + ( (port - 0x300) * 2);
  27. }
  28. maybebadio(sh_edosk7705_isa_port2addr, port);
  29. return port;
  30. }
  31. /* Trying to read / write bytes on odd-byte boundaries to the Ethernet
  32. * registers causes problems. So we bit-shift the value and read / write
  33. * in 2 byte chunks. Setting the low byte to 0 does not cause problems
  34. * now as odd byte writes are only made on the bit mask / interrupt
  35. * register. This may not be the case in future Mar-2003 SJD
  36. */
  37. unsigned char sh_edosk7705_inb(unsigned long port)
  38. {
  39. if (port >= 0x300 && port < 0x320 && port & 0x01) {
  40. return (volatile unsigned char)(generic_inw(port -1) >> 8);
  41. }
  42. return *(volatile unsigned char *)sh_edosk7705_isa_port2addr(port);
  43. }
  44. unsigned int sh_edosk7705_inl(unsigned long port)
  45. {
  46. return *(volatile unsigned long *)port;
  47. }
  48. void sh_edosk7705_outb(unsigned char value, unsigned long port)
  49. {
  50. if (port >= 0x300 && port < 0x320 && port & 0x01) {
  51. generic_outw(((unsigned short)value << 8), port -1);
  52. return;
  53. }
  54. *(volatile unsigned char *)sh_edosk7705_isa_port2addr(port) = value;
  55. }
  56. void sh_edosk7705_outl(unsigned int value, unsigned long port)
  57. {
  58. *(volatile unsigned long *)port = value;
  59. }
  60. void sh_edosk7705_insb(unsigned long port, void *addr, unsigned long count)
  61. {
  62. unsigned char *p = addr;
  63. while (count--) *p++ = sh_edosk7705_inb(port);
  64. }
  65. void sh_edosk7705_insl(unsigned long port, void *addr, unsigned long count)
  66. {
  67. unsigned long *p = (unsigned long*)addr;
  68. while (count--)
  69. *p++ = *(volatile unsigned long *)port;
  70. }
  71. void sh_edosk7705_outsb(unsigned long port, const void *addr, unsigned long count)
  72. {
  73. unsigned char *p = (unsigned char*)addr;
  74. while (count--) sh_edosk7705_outb(*p++, port);
  75. }
  76. void sh_edosk7705_outsl(unsigned long port, const void *addr, unsigned long count)
  77. {
  78. unsigned long *p = (unsigned long*)addr;
  79. while (count--) sh_edosk7705_outl(*p++, port);
  80. }