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
  25struct tpm_atmel_priv {
  26        int region_size;
  27        int have_region;
  28        unsigned long base;
  29        void __iomem *iobase;
  30};
  31
  32#ifdef CONFIG_PPC64
  33
  34#include <asm/prom.h>
  35
  36#define atmel_getb(priv, offset) readb(priv->iobase + offset)
  37#define atmel_putb(val, priv, offset) writeb(val, priv->iobase + offset)
  38#define atmel_request_region request_mem_region
  39#define atmel_release_region release_mem_region
  40
  41static inline void atmel_put_base_addr(void __iomem *iobase)
  42{
  43        iounmap(iobase);
  44}
  45
  46static void __iomem * atmel_get_base_addr(unsigned long *base, int *region_size)
  47{
  48        struct device_node *dn;
  49        unsigned long address, size;
  50        const unsigned int *reg;
  51        int reglen;
  52        int naddrc;
  53        int nsizec;
  54
  55        dn = of_find_node_by_name(NULL, "tpm");
  56
  57        if (!dn)
  58                return NULL;
  59
  60        if (!of_device_is_compatible(dn, "AT97SC3201")) {
  61                of_node_put(dn);
  62                return NULL;
  63        }
  64
  65        reg = of_get_property(dn, "reg", &reglen);
  66        naddrc = of_n_addr_cells(dn);
  67        nsizec = of_n_size_cells(dn);
  68
  69        of_node_put(dn);
  70
  71
  72        if (naddrc == 2)
  73                address = ((unsigned long) reg[0] << 32) | reg[1];
  74        else
  75                address = reg[0];
  76
  77        if (nsizec == 2)
  78                size =
  79                    ((unsigned long) reg[naddrc] << 32) | reg[naddrc + 1];
  80        else
  81                size = reg[naddrc];
  82
  83        *base = address;
  84        *region_size = size;
  85        return ioremap(*base, *region_size);
  86}
  87#else
  88#define atmel_getb(chip, offset) inb(atmel_get_priv(chip)->base + offset)
  89#define atmel_putb(val, chip, offset) \
  90        outb(val, atmel_get_priv(chip)->base + offset)
  91#define atmel_request_region request_region
  92#define atmel_release_region release_region
  93/* Atmel definitions */
  94enum tpm_atmel_addr {
  95        TPM_ATMEL_BASE_ADDR_LO = 0x08,
  96        TPM_ATMEL_BASE_ADDR_HI = 0x09
  97};
  98
  99/* Verify this is a 1.1 Atmel TPM */
 100static int atmel_verify_tpm11(void)
 101{
 102
 103        /* verify that it is an Atmel part */
 104        if (tpm_read_index(TPM_ADDR, 4) != 'A' ||
 105            tpm_read_index(TPM_ADDR, 5) != 'T' ||
 106            tpm_read_index(TPM_ADDR, 6) != 'M' ||
 107            tpm_read_index(TPM_ADDR, 7) != 'L')
 108                return 1;
 109
 110        /* query chip for its version number */
 111        if (tpm_read_index(TPM_ADDR, 0x00) != 1 ||
 112            tpm_read_index(TPM_ADDR, 0x01) != 1)
 113                return 1;
 114
 115        /* This is an atmel supported part */
 116        return 0;
 117}
 118
 119static inline void atmel_put_base_addr(void __iomem *iobase)
 120{
 121}
 122
 123/* Determine where to talk to device */
 124static void __iomem * atmel_get_base_addr(unsigned long *base, int *region_size)
 125{
 126        int lo, hi;
 127
 128        if (atmel_verify_tpm11() != 0)
 129                return NULL;
 130
 131        lo = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_LO);
 132        hi = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_HI);
 133
 134        *base = (hi << 8) | lo;
 135        *region_size = 2;
 136
 137        return ioport_map(*base, *region_size);
 138}
 139#endif
 140