162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * EISA "eeprom" support routines 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (C) 2001 Thomas Bogendoerfer <tsbogend at parisc-linux.org> 662306a36Sopenharmony_ci */ 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#include <linux/module.h> 962306a36Sopenharmony_ci#include <linux/init.h> 1062306a36Sopenharmony_ci#include <linux/kernel.h> 1162306a36Sopenharmony_ci#include <linux/miscdevice.h> 1262306a36Sopenharmony_ci#include <linux/slab.h> 1362306a36Sopenharmony_ci#include <linux/fs.h> 1462306a36Sopenharmony_ci#include <asm/io.h> 1562306a36Sopenharmony_ci#include <linux/uaccess.h> 1662306a36Sopenharmony_ci#include <asm/eisa_eeprom.h> 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ci#define EISA_EEPROM_MINOR 241 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_cistatic loff_t eisa_eeprom_llseek(struct file *file, loff_t offset, int origin) 2162306a36Sopenharmony_ci{ 2262306a36Sopenharmony_ci return fixed_size_llseek(file, offset, origin, HPEE_MAX_LENGTH); 2362306a36Sopenharmony_ci} 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_cistatic ssize_t eisa_eeprom_read(struct file * file, 2662306a36Sopenharmony_ci char __user *buf, size_t count, loff_t *ppos ) 2762306a36Sopenharmony_ci{ 2862306a36Sopenharmony_ci unsigned char *tmp; 2962306a36Sopenharmony_ci ssize_t ret; 3062306a36Sopenharmony_ci int i; 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_ci if (*ppos < 0 || *ppos >= HPEE_MAX_LENGTH) 3362306a36Sopenharmony_ci return 0; 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_ci count = *ppos + count < HPEE_MAX_LENGTH ? count : HPEE_MAX_LENGTH - *ppos; 3662306a36Sopenharmony_ci tmp = kmalloc(count, GFP_KERNEL); 3762306a36Sopenharmony_ci if (tmp) { 3862306a36Sopenharmony_ci for (i = 0; i < count; i++) 3962306a36Sopenharmony_ci tmp[i] = readb(eisa_eeprom_addr+(*ppos)++); 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_ci if (copy_to_user (buf, tmp, count)) 4262306a36Sopenharmony_ci ret = -EFAULT; 4362306a36Sopenharmony_ci else 4462306a36Sopenharmony_ci ret = count; 4562306a36Sopenharmony_ci kfree (tmp); 4662306a36Sopenharmony_ci } else 4762306a36Sopenharmony_ci ret = -ENOMEM; 4862306a36Sopenharmony_ci 4962306a36Sopenharmony_ci return ret; 5062306a36Sopenharmony_ci} 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_cistatic int eisa_eeprom_open(struct inode *inode, struct file *file) 5362306a36Sopenharmony_ci{ 5462306a36Sopenharmony_ci if (file->f_mode & FMODE_WRITE) 5562306a36Sopenharmony_ci return -EINVAL; 5662306a36Sopenharmony_ci 5762306a36Sopenharmony_ci return 0; 5862306a36Sopenharmony_ci} 5962306a36Sopenharmony_ci 6062306a36Sopenharmony_cistatic int eisa_eeprom_release(struct inode *inode, struct file *file) 6162306a36Sopenharmony_ci{ 6262306a36Sopenharmony_ci return 0; 6362306a36Sopenharmony_ci} 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_ci/* 6662306a36Sopenharmony_ci * The various file operations we support. 6762306a36Sopenharmony_ci */ 6862306a36Sopenharmony_cistatic const struct file_operations eisa_eeprom_fops = { 6962306a36Sopenharmony_ci .owner = THIS_MODULE, 7062306a36Sopenharmony_ci .llseek = eisa_eeprom_llseek, 7162306a36Sopenharmony_ci .read = eisa_eeprom_read, 7262306a36Sopenharmony_ci .open = eisa_eeprom_open, 7362306a36Sopenharmony_ci .release = eisa_eeprom_release, 7462306a36Sopenharmony_ci}; 7562306a36Sopenharmony_ci 7662306a36Sopenharmony_cistatic struct miscdevice eisa_eeprom_dev = { 7762306a36Sopenharmony_ci EISA_EEPROM_MINOR, 7862306a36Sopenharmony_ci "eisa_eeprom", 7962306a36Sopenharmony_ci &eisa_eeprom_fops 8062306a36Sopenharmony_ci}; 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_cistatic int __init eisa_eeprom_init(void) 8362306a36Sopenharmony_ci{ 8462306a36Sopenharmony_ci int retval; 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_ci if (!eisa_eeprom_addr) 8762306a36Sopenharmony_ci return -ENODEV; 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_ci retval = misc_register(&eisa_eeprom_dev); 9062306a36Sopenharmony_ci if (retval < 0) { 9162306a36Sopenharmony_ci printk(KERN_ERR "EISA EEPROM: cannot register misc device.\n"); 9262306a36Sopenharmony_ci return retval; 9362306a36Sopenharmony_ci } 9462306a36Sopenharmony_ci 9562306a36Sopenharmony_ci printk(KERN_INFO "EISA EEPROM at 0x%px\n", eisa_eeprom_addr); 9662306a36Sopenharmony_ci return 0; 9762306a36Sopenharmony_ci} 9862306a36Sopenharmony_ci 9962306a36Sopenharmony_ciMODULE_LICENSE("GPL"); 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_cimodule_init(eisa_eeprom_init); 102