0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020 struct tpm_atmel_priv {
0021 int region_size;
0022 int have_region;
0023 unsigned long base;
0024 void __iomem *iobase;
0025 };
0026
0027 #ifdef CONFIG_PPC64
0028
0029 #include <asm/prom.h>
0030
0031 #define atmel_getb(priv, offset) readb(priv->iobase + offset)
0032 #define atmel_putb(val, priv, offset) writeb(val, priv->iobase + offset)
0033 #define atmel_request_region request_mem_region
0034 #define atmel_release_region release_mem_region
0035
0036 static inline void atmel_put_base_addr(void __iomem *iobase)
0037 {
0038 iounmap(iobase);
0039 }
0040
0041 static void __iomem * atmel_get_base_addr(unsigned long *base, int *region_size)
0042 {
0043 struct device_node *dn;
0044 unsigned long address, size;
0045 const unsigned int *reg;
0046 int reglen;
0047 int naddrc;
0048 int nsizec;
0049
0050 dn = of_find_node_by_name(NULL, "tpm");
0051
0052 if (!dn)
0053 return NULL;
0054
0055 if (!of_device_is_compatible(dn, "AT97SC3201")) {
0056 of_node_put(dn);
0057 return NULL;
0058 }
0059
0060 reg = of_get_property(dn, "reg", ®len);
0061 naddrc = of_n_addr_cells(dn);
0062 nsizec = of_n_size_cells(dn);
0063
0064 of_node_put(dn);
0065
0066
0067 if (naddrc == 2)
0068 address = ((unsigned long) reg[0] << 32) | reg[1];
0069 else
0070 address = reg[0];
0071
0072 if (nsizec == 2)
0073 size =
0074 ((unsigned long) reg[naddrc] << 32) | reg[naddrc + 1];
0075 else
0076 size = reg[naddrc];
0077
0078 *base = address;
0079 *region_size = size;
0080 return ioremap(*base, *region_size);
0081 }
0082 #else
0083 #define atmel_getb(chip, offset) inb(atmel_get_priv(chip)->base + offset)
0084 #define atmel_putb(val, chip, offset) \
0085 outb(val, atmel_get_priv(chip)->base + offset)
0086 #define atmel_request_region request_region
0087 #define atmel_release_region release_region
0088
0089 enum tpm_atmel_addr {
0090 TPM_ATMEL_BASE_ADDR_LO = 0x08,
0091 TPM_ATMEL_BASE_ADDR_HI = 0x09
0092 };
0093
0094 static inline int tpm_read_index(int base, int index)
0095 {
0096 outb(index, base);
0097 return inb(base+1) & 0xFF;
0098 }
0099
0100
0101 static int atmel_verify_tpm11(void)
0102 {
0103
0104
0105 if (tpm_read_index(TPM_ADDR, 4) != 'A' ||
0106 tpm_read_index(TPM_ADDR, 5) != 'T' ||
0107 tpm_read_index(TPM_ADDR, 6) != 'M' ||
0108 tpm_read_index(TPM_ADDR, 7) != 'L')
0109 return 1;
0110
0111
0112 if (tpm_read_index(TPM_ADDR, 0x00) != 1 ||
0113 tpm_read_index(TPM_ADDR, 0x01) != 1)
0114 return 1;
0115
0116
0117 return 0;
0118 }
0119
0120 static inline void atmel_put_base_addr(void __iomem *iobase)
0121 {
0122 }
0123
0124
0125 static void __iomem * atmel_get_base_addr(unsigned long *base, int *region_size)
0126 {
0127 int lo, hi;
0128
0129 if (atmel_verify_tpm11() != 0)
0130 return NULL;
0131
0132 lo = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_LO);
0133 hi = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_HI);
0134
0135 *base = (hi << 8) | lo;
0136 *region_size = 2;
0137
0138 return ioport_map(*base, *region_size);
0139 }
0140 #endif