2005-04-17 02:20:36 +04:00
/*
* Copyright ( C ) 2004 IBM Corporation
*
* Authors :
* Leendert van Doorn < leendert @ watson . ibm . com >
* Dave Safford < safford @ watson . ibm . com >
* Reiner Sailer < sailer @ watson . ibm . com >
* Kylene Hall < kjhall @ us . ibm . com >
*
* Maintained by : < tpmdd_devel @ lists . sourceforge . net >
*
* Device driver for TCG / TCPA TPM ( trusted platform module ) .
* Specifications at www . trustedcomputinggroup . org
*
* This program is free software ; you can redistribute it and / or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation , version 2 of the
* License .
*
*/
# include <linux/module.h>
# include <linux/pci.h>
# include <linux/delay.h>
# include <linux/fs.h>
# include <linux/miscdevice.h>
2005-11-01 18:14:05 +03:00
# include <linux/platform_device.h>
2006-03-25 14:07:35 +03:00
# include <linux/io.h>
2005-04-17 02:20:36 +04:00
2005-06-24 09:01:48 +04:00
enum tpm_timeout {
TPM_TIMEOUT = 5 , /* msecs */
} ;
2005-04-17 02:20:36 +04:00
/* TPM addresses */
2005-06-24 09:01:48 +04:00
enum tpm_addr {
2005-06-26 01:55:39 +04:00
TPM_SUPERIO_ADDR = 0x2E ,
2005-06-24 09:01:48 +04:00
TPM_ADDR = 0x4E ,
} ;
2005-06-24 09:02:00 +04:00
extern ssize_t tpm_show_pubek ( struct device * , struct device_attribute * attr ,
char * ) ;
extern ssize_t tpm_show_pcrs ( struct device * , struct device_attribute * attr ,
char * ) ;
extern ssize_t tpm_show_caps ( struct device * , struct device_attribute * attr ,
char * ) ;
extern ssize_t tpm_store_cancel ( struct device * , struct device_attribute * attr ,
const char * , size_t ) ;
2005-04-17 02:20:36 +04:00
struct tpm_chip ;
struct tpm_vendor_specific {
2006-04-22 13:37:26 +04:00
const u8 req_complete_mask ;
const u8 req_complete_val ;
const u8 req_canceled ;
2005-11-14 03:07:41 +03:00
void __iomem * iobase ; /* ioremapped address */
unsigned long base ; /* TPM base address */
int region_size ;
int have_region ;
2005-04-17 02:20:36 +04:00
int ( * recv ) ( struct tpm_chip * , u8 * , size_t ) ;
int ( * send ) ( struct tpm_chip * , u8 * , size_t ) ;
void ( * cancel ) ( struct tpm_chip * ) ;
2005-10-31 02:03:23 +03:00
u8 ( * status ) ( struct tpm_chip * ) ;
2005-04-17 02:20:36 +04:00
struct miscdevice miscdev ;
2005-06-24 09:02:00 +04:00
struct attribute_group * attr_group ;
2005-04-17 02:20:36 +04:00
} ;
struct tpm_chip {
2005-10-31 02:03:24 +03:00
struct device * dev ; /* Device stuff */
2005-04-17 02:20:36 +04:00
int dev_num ; /* /dev/tpm# */
int num_opens ; /* only one allowed */
int time_expired ;
/* Data passed to and from the tpm via the read/write calls */
u8 * data_buffer ;
atomic_t data_pending ;
struct semaphore buffer_mutex ;
struct timer_list user_read_timer ; /* user needs to claim result */
2005-11-14 03:07:43 +03:00
struct work_struct work ;
2005-04-17 02:20:36 +04:00
struct semaphore tpm_mutex ; /* tpm is processing */
2006-04-22 13:37:15 +04:00
struct tpm_vendor_specific vendor ;
2005-04-17 02:20:36 +04:00
2006-01-08 12:03:15 +03:00
struct dentry * * bios_dir ;
2005-04-17 02:20:36 +04:00
struct list_head list ;
} ;
2005-06-26 01:55:39 +04:00
static inline int tpm_read_index ( int base , int index )
2005-04-17 02:20:36 +04:00
{
2005-06-26 01:55:39 +04:00
outb ( index , base ) ;
return inb ( base + 1 ) & 0xFF ;
2005-04-17 02:20:36 +04:00
}
2005-06-26 01:55:39 +04:00
static inline void tpm_write_index ( int base , int index , int value )
2005-04-17 02:20:36 +04:00
{
2005-06-26 01:55:39 +04:00
outb ( index , base ) ;
outb ( value & 0xFF , base + 1 ) ;
2005-04-17 02:20:36 +04:00
}
2006-04-22 13:37:26 +04:00
extern struct tpm_chip * tpm_register_hardware ( struct device * ,
const struct tpm_vendor_specific * ) ;
2005-04-17 02:20:36 +04:00
extern int tpm_open ( struct inode * , struct file * ) ;
extern int tpm_release ( struct inode * , struct file * ) ;
extern ssize_t tpm_write ( struct file * , const char __user * , size_t ,
loff_t * ) ;
extern ssize_t tpm_read ( struct file * , char __user * , size_t , loff_t * ) ;
2005-10-31 02:03:24 +03:00
extern void tpm_remove_hardware ( struct device * ) ;
2005-10-31 02:03:25 +03:00
extern int tpm_pm_suspend ( struct device * , pm_message_t ) ;
extern int tpm_pm_resume ( struct device * ) ;
2006-01-08 12:03:15 +03:00
# ifdef CONFIG_ACPI
extern struct dentry * * tpm_bios_log_setup ( char * ) ;
extern void tpm_bios_log_teardown ( struct dentry * * ) ;
# else
static inline struct dentry * tpm_bios_log_setup ( char * name )
{
return NULL ;
}
static inline void tpm_bios_log_teardown ( struct dentry * * dir )
{
}
# endif