io.c 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  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 <linux/io.h>
  13. #include <mach/edosk7705.h>
  14. #include <asm/addrspace.h>
  15. #define SMC_IOADDR 0xA2000000
  16. /* Map the Ethernet addresses as if it is at 0x300 - 0x320 */
  17. static unsigned long sh_edosk7705_isa_port2addr(unsigned long port)
  18. {
  19. /*
  20. * SMC91C96 registers are 4 byte aligned rather than the
  21. * usual 2 byte!
  22. */
  23. if (port >= 0x300 && port < 0x320)
  24. return SMC_IOADDR + ((port - 0x300) * 2);
  25. maybebadio(port);
  26. return port;
  27. }
  28. /* Trying to read / write bytes on odd-byte boundaries to the Ethernet
  29. * registers causes problems. So we bit-shift the value and read / write
  30. * in 2 byte chunks. Setting the low byte to 0 does not cause problems
  31. * now as odd byte writes are only made on the bit mask / interrupt
  32. * register. This may not be the case in future Mar-2003 SJD
  33. */
  34. unsigned char sh_edosk7705_inb(unsigned long port)
  35. {
  36. if (port >= 0x300 && port < 0x320 && port & 0x01)
  37. return __raw_readw(port - 1) >> 8;
  38. return __raw_readb(sh_edosk7705_isa_port2addr(port));
  39. }
  40. void sh_edosk7705_outb(unsigned char value, unsigned long port)
  41. {
  42. if (port >= 0x300 && port < 0x320 && port & 0x01) {
  43. __raw_writew(((unsigned short)value << 8), port - 1);
  44. return;
  45. }
  46. __raw_writeb(value, sh_edosk7705_isa_port2addr(port));
  47. }
  48. void sh_edosk7705_insb(unsigned long port, void *addr, unsigned long count)
  49. {
  50. unsigned char *p = addr;
  51. while (count--)
  52. *p++ = sh_edosk7705_inb(port);
  53. }
  54. void sh_edosk7705_outsb(unsigned long port, const void *addr, unsigned long count)
  55. {
  56. unsigned char *p = (unsigned char *)addr;
  57. while (count--)
  58. sh_edosk7705_outb(*p++, port);
  59. }