linux/drivers/char/tpm/tpm_atmel.h
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2005 IBM Corporation
   3 *
   4 * Authors:
   5 * Kylene Hall <kjhall@us.ibm.com>
   6 *
   7 * Maintained by: <tpmdd-devel@lists.sourceforge.net>
   8 *
   9 * Device driver for TCG/TCPA TPM (trusted platform module).
  10 * Specifications at www.trustedcomputinggroup.org
  11 *
  12 * This program is free software; you can redistribute it and/or
  13 * modify it under the terms of the GNU General Public License as
  14 * published by the Free Software Foundation, version 2 of the
  15 * License.
  16 *
  17 * These difference are required on power because the device must be
  18 * discovered through the device tree and iomap must be used to get
  19 * around the need for holes in the io_page_mask.  This does not happen
  20 * automatically because the tpm is not a normal pci device and lives
  21 * under the root node.
  22 *
  23 */
  24
  25#ifdef CONFIG_PPC64
  26
  27#include <asm/prom.h>
  28
  29#define atmel_getb(chip, offset) readb(chip->vendor->iobase + offset);
  30#define atmel_putb(val, chip, offset) writeb(val, chip->vendor->iobase + offset)
  31#define atmel_request_region request_mem_region
  32#define atmel_release_region release_mem_region
  33
  34static inline void atmel_put_base_addr(void __iomem *iobase)
  35{
  36        iounmap(iobase);
  37}
  38
  39static void __iomem * atmel_get_base_addr(unsigned long *base, int *region_size)
  40{
  41        struct device_node *dn;
  42        unsigned long address, size;
  43        const unsigned int *reg;
  44        int reglen;
  45        int naddrc;
  46        int nsizec;
  47
  48        dn = of_find_node_by_name(NULL, "tpm");
  49
  50        if (!dn)
  51                return NULL;
  52
  53        if (!of_device_is_compatible(dn, "AT97SC3201")) {
  54                of_node_put(dn);
  55                return NULL;
  56        }
  57
  58        reg = of_get_property(dn, "reg", &reglen);
  59        naddrc = of_n_addr_cells(dn);
  60        nsizec = of_n_size_cells(dn);
  61
  62        of_node_put(dn);
  63
  64
  65        if (naddrc == 2)
  66                address = ((unsigned long) reg[0] << 32) | reg[1];
  67        else
  68                address = reg[0];
  69
  70        if (nsizec == 2)
  71                size =
  72                    ((unsigned long) reg[naddrc] << 32) | reg[naddrc + 1];
  73        else
  74                size = reg[naddrc];
  75
  76        *base = address;
  77        *region_size = size;
  78        return ioremap(*base, *region_size);
  79}
  80#else
  81#define atmel_getb(chip, offset) inb(chip->vendor->base + offset)
  82#define atmel_putb(val, chip, offset) outb(val, chip->vendor->base + offset)
  83#define atmel_request_region request_region
  84#define atmel_release_region release_region
  85/* Atmel definitions */
  86enum tpm_atmel_addr {
  87        TPM_ATMEL_BASE_ADDR_LO = 0x08,
  88        TPM_ATMEL_BASE_ADDR_HI = 0x09
  89};
  90
  91/* Verify this is a 1.1 Atmel TPM */
  92static int atmel_verify_tpm11(void)
  93{
  94
  95        /* verify that it is an Atmel part */
  96        if (tpm_read_index(TPM_ADDR, 4) != 'A' ||
  97            tpm_read_index(TPM_ADDR, 5) != 'T' ||
  98            tpm_read_index(TPM_ADDR, 6) != 'M' ||
  99            tpm_read_index(TPM_ADDR, 7) != 'L')
 100                return 1;
 101
 102        /* query chip for its version number */
 103        if (tpm_read_index(TPM_ADDR, 0x00) != 1 ||
 104            tpm_read_index(TPM_ADDR, 0x01) != 1)
 105                return 1;
 106
 107        /* This is an atmel supported part */
 108        return 0;
 109}
 110
 111static inline void atmel_put_base_addr(void __iomem *iobase)
 112{
 113}
 114
 115/* Determine where to talk to device */
 116static void __iomem * atmel_get_base_addr(unsigned long *base, int *region_size)
 117{
 118        int lo, hi;
 119
 120        if (atmel_verify_tpm11() != 0)
 121                return NULL;
 122
 123        lo = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_LO);
 124        hi = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_HI);
 125
 126        *base = (hi << 8) | lo;
 127        *region_size = 2;
 128
 129        return ioport_map(*base, *region_size);
 130}
 131#endif
 132