Release 4.11 drivers/sbus/char/display7seg.c
/* display7seg.c - Driver implementation for the 7-segment display
* present on Sun Microsystems CP1400 and CP1500
*
* Copyright (c) 2000 Eric Brower (ebrower@usa.net)
*/
#include <linux/device.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/major.h>
#include <linux/miscdevice.h>
#include <linux/ioport.h> /* request_region */
#include <linux/slab.h>
#include <linux/mutex.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/atomic.h>
#include <linux/uaccess.h> /* put_/get_user */
#include <asm/io.h>
#include <asm/display7seg.h>
#define D7S_MINOR 193
#define DRIVER_NAME "d7s"
#define PFX DRIVER_NAME ": "
static DEFINE_MUTEX(d7s_mutex);
static int sol_compat = 0;
/* Solaris compatibility mode */
/* Solaris compatibility flag -
* The Solaris implementation omits support for several
* documented driver features (ref Sun doc 806-0180-03).
* By default, this module supports the documented driver
* abilities, rather than the Solaris implementation:
*
* 1) Device ALWAYS reverts to OBP-specified FLIPPED mode
* upon closure of device or module unload.
* 2) Device ioctls D7SIOCRD/D7SIOCWR honor toggling of
* FLIP bit
*
* If you wish the device to operate as under Solaris,
* omitting above features, set this parameter to non-zero.
*/
module_param(sol_compat, int, 0);
MODULE_PARM_DESC(sol_compat,
"Disables documented functionality omitted from Solaris driver");
MODULE_AUTHOR("Eric Brower <ebrower@usa.net>");
MODULE_DESCRIPTION("7-Segment Display driver for Sun Microsystems CP1400/1500");
MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("d7s");
struct d7s {
void __iomem *regs;
bool flipped;
};
struct d7s *d7s_device;
/*
* Register block address- see header for details
* -----------------------------------------
* | DP | ALARM | FLIP | 4 | 3 | 2 | 1 | 0 |
* -----------------------------------------
*
* DP - Toggles decimal point on/off
* ALARM - Toggles "Alarm" LED green/red
* FLIP - Inverts display for upside-down mounted board
* bits 0-4 - 7-segment display contents
*/
static atomic_t d7s_users = ATOMIC_INIT(0);
static int d7s_open(struct inode *inode, struct file *f)
{
if (D7S_MINOR != iminor(inode))
return -ENODEV;
atomic_inc(&d7s_users);
return 0;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Linus Torvalds (pre-git) | 32 | 84.21% | 1 | 33.33% |
Christoph Hellwig | 5 | 13.16% | 1 | 33.33% |
Al Viro | 1 | 2.63% | 1 | 33.33% |
Total | 38 | 100.00% | 3 | 100.00% |
static int d7s_release(struct inode *inode, struct file *f)
{
/* Reset flipped state to OBP default only if
* no other users have the device open and we
* are not operating in solaris-compat mode
*/
if (atomic_dec_and_test(&d7s_users) && !sol_compat) {
struct d7s *p = d7s_device;
u8 regval = 0;
regval = readb(p->regs);
if (p->flipped)
regval |= D7S_FLIP;
else
regval &= ~D7S_FLIP;
writeb(regval, p->regs);
}
return 0;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Linus Torvalds (pre-git) | 48 | 60.76% | 1 | 33.33% |
David S. Miller | 26 | 32.91% | 1 | 33.33% |
Christoph Hellwig | 5 | 6.33% | 1 | 33.33% |
Total | 79 | 100.00% | 3 | 100.00% |
static long d7s_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
struct d7s *p = d7s_device;
u8 regs = readb(p->regs);
int error = 0;
u8 ireg = 0;
if (D7S_MINOR != iminor(file_inode(file)))
return -ENODEV;
mutex_lock(&d7s_mutex);
switch (cmd) {
case D7SIOCWR:
/* assign device register values we mask-out D7S_FLIP
* if in sol_compat mode
*/
if (get_user(ireg, (int __user *) arg)) {
error = -EFAULT;
break;
}
if (sol_compat) {
if (regs & D7S_FLIP)
ireg |= D7S_FLIP;
else
ireg &= ~D7S_FLIP;
}
writeb(ireg, p->regs);
break;
case D7SIOCRD:
/* retrieve device register values
* NOTE: Solaris implementation returns D7S_FLIP bit
* as toggled by user, even though it does not honor it.
* This driver will not misinform you about the state
* of your hardware while in sol_compat mode
*/
if (put_user(regs, (int __user *) arg)) {
error = -EFAULT;
break;
}
break;
case D7SIOCTM:
/* toggle device mode-- flip display orientation */
regs ^= D7S_FLIP;
writeb(regs, p->regs);
break;
}
mutex_unlock(&d7s_mutex);
return error;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Linus Torvalds (pre-git) | 121 | 65.05% | 2 | 20.00% |
David S. Miller | 27 | 14.52% | 1 | 10.00% |
Christoph Hellwig | 20 | 10.75% | 1 | 10.00% |
Arnd Bergmann | 10 | 5.38% | 1 | 10.00% |
Al Viro | 6 | 3.23% | 3 | 30.00% |
Rasmus Villemoes | 1 | 0.54% | 1 | 10.00% |
Andrew Morton | 1 | 0.54% | 1 | 10.00% |
Total | 186 | 100.00% | 10 | 100.00% |
static const struct file_operations d7s_fops = {
.owner = THIS_MODULE,
.unlocked_ioctl = d7s_ioctl,
.compat_ioctl = d7s_ioctl,
.open = d7s_open,
.release = d7s_release,
.llseek = noop_llseek,
};
static struct miscdevice d7s_miscdev = {
.minor = D7S_MINOR,
.name = DRIVER_NAME,
.fops = &d7s_fops
};
static int d7s_probe(struct platform_device *op)
{
struct device_node *opts;
int err = -EINVAL;
struct d7s *p;
u8 regs;
if (d7s_device)
goto out;
p = devm_kzalloc(&op->dev, sizeof(*p), GFP_KERNEL);
err = -ENOMEM;
if (!p)
goto out;
p->regs = of_ioremap(&op->resource[0], 0, sizeof(u8), "d7s");
if (!p->regs) {
printk(KERN_ERR PFX "Cannot map chip registers\n");
goto out_free;
}
err = misc_register(&d7s_miscdev);
if (err) {
printk(KERN_ERR PFX "Unable to acquire miscdevice minor %i\n",
D7S_MINOR);
goto out_iounmap;
}
/* OBP option "d7s-flipped?" is honored as default for the
* device, and reset default when detached
*/
regs = readb(p->regs);
opts = of_find_node_by_path("/options");
if (opts &&
of_get_property(opts, "d7s-flipped?", NULL))
p->flipped = true;
if (p->flipped)
regs |= D7S_FLIP;
else
regs &= ~D7S_FLIP;
writeb(regs, p->regs);
printk(KERN_INFO PFX "7-Segment Display%s at [%s:0x%llx] %s\n",
op->dev.of_node->full_name,
(regs & D7S_FLIP) ? " (FLIPPED)" : "",
op->resource[0].start,
sol_compat ? "in sol_compat mode" : "");
dev_set_drvdata(&op->dev, p);
d7s_device = p;
err = 0;
out:
return err;
out_iounmap:
of_iounmap(&op->resource[0], p->regs, sizeof(u8));
out_free:
goto out;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
David S. Miller | 171 | 63.81% | 1 | 12.50% |
Linus Torvalds (pre-git) | 87 | 32.46% | 2 | 25.00% |
Himangi Saraogi | 6 | 2.24% | 1 | 12.50% |
Grant C. Likely | 2 | 0.75% | 2 | 25.00% |
Sam Ravnborg | 1 | 0.37% | 1 | 12.50% |
Chris Wilson | 1 | 0.37% | 1 | 12.50% |
Total | 268 | 100.00% | 8 | 100.00% |
static int d7s_remove(struct platform_device *op)
{
struct d7s *p = dev_get_drvdata(&op->dev);
u8 regs = readb(p->regs);
/* Honor OBP d7s-flipped? unless operating in solaris-compat mode */
if (sol_compat) {
if (p->flipped)
regs |= D7S_FLIP;
else
regs &= ~D7S_FLIP;
writeb(regs, p->regs);
}
misc_deregister(&d7s_miscdev);
of_iounmap(&op->resource[0], p->regs, sizeof(u8));
return 0;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
David S. Miller | 61 | 64.21% | 1 | 25.00% |
Linus Torvalds (pre-git) | 33 | 34.74% | 2 | 50.00% |
Grant C. Likely | 1 | 1.05% | 1 | 25.00% |
Total | 95 | 100.00% | 4 | 100.00% |
static const struct of_device_id d7s_match[] = {
{
.name = "display7seg",
},
{},
};
MODULE_DEVICE_TABLE(of, d7s_match);
static struct platform_driver d7s_driver = {
.driver = {
.name = DRIVER_NAME,
.of_match_table = d7s_match,
},
.probe = d7s_probe,
.remove = d7s_remove,
};
module_platform_driver(d7s_driver);
Overall Contributors
Person | Tokens | Prop | Commits | CommitProp |
Linus Torvalds (pre-git) | 433 | 46.56% | 3 | 9.38% |
David S. Miller | 370 | 39.78% | 4 | 12.50% |
Christoph Hellwig | 49 | 5.27% | 2 | 6.25% |
Arnd Bergmann | 22 | 2.37% | 2 | 6.25% |
Grant C. Likely | 10 | 1.08% | 4 | 12.50% |
Himangi Saraogi | 9 | 0.97% | 1 | 3.12% |
Rusty Russell | 8 | 0.86% | 1 | 3.12% |
Al Viro | 7 | 0.75% | 3 | 9.38% |
Linus Torvalds | 6 | 0.65% | 2 | 6.25% |
Randy Dunlap | 4 | 0.43% | 1 | 3.12% |
Tejun Heo | 3 | 0.32% | 1 | 3.12% |
Axel Lin | 2 | 0.22% | 1 | 3.12% |
Arun Sharma | 1 | 0.11% | 1 | 3.12% |
Chris Wilson | 1 | 0.11% | 1 | 3.12% |
Rasmus Villemoes | 1 | 0.11% | 1 | 3.12% |
Arjan van de Ven | 1 | 0.11% | 1 | 3.12% |
Andrew Morton | 1 | 0.11% | 1 | 3.12% |
Peter Osterlund | 1 | 0.11% | 1 | 3.12% |
Sam Ravnborg | 1 | 0.11% | 1 | 3.12% |
Total | 930 | 100.00% | 32 | 100.00% |
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.