Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
95d43905
Commit
95d43905
authored
Aug 29, 2008
by
David S. Miller
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
display7seg: Convert to pure OF device driver.
Signed-off-by:
David S. Miller
<
davem@davemloft.net
>
parent
0e52fe8c
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
146 additions
and
105 deletions
+146
-105
drivers/sbus/char/display7seg.c
drivers/sbus/char/display7seg.c
+146
-105
No files found.
drivers/sbus/char/display7seg.c
View file @
95d43905
/* $Id: display7seg.c,v 1.6 2002/01/08 16:00:16 davem Exp $
/* display7seg.c - Driver implementation for the 7-segment display
*
* present on Sun Microsystems CP1400 and CP1500
* display7seg - Driver implementation for the 7-segment display
* present on Sun Microsystems CP1400 and CP1500
*
*
* Copyright (c) 2000 Eric Brower (ebrower@usa.net)
* Copyright (c) 2000 Eric Brower (ebrower@usa.net)
*
*/
*/
#include <linux/kernel.h>
#include <linux/kernel.h>
...
@@ -16,22 +13,20 @@
...
@@ -16,22 +13,20 @@
#include <linux/miscdevice.h>
#include <linux/miscdevice.h>
#include <linux/ioport.h>
/* request_region */
#include <linux/ioport.h>
/* request_region */
#include <linux/smp_lock.h>
#include <linux/smp_lock.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <asm/atomic.h>
#include <asm/atomic.h>
#include <asm/ebus.h>
/* EBus device */
#include <asm/oplib.h>
/* OpenProm Library */
#include <asm/uaccess.h>
/* put_/get_user */
#include <asm/uaccess.h>
/* put_/get_user */
#include <asm/io.h>
#include <asm/io.h>
#include <asm/display7seg.h>
#include <asm/display7seg.h>
#define D7S_MINOR 193
#define D7S_MINOR 193
#define D
7S_OBPNAME "display7seg
"
#define D
RIVER_NAME "d7s
"
#define
D7S_DEVNAME "d7s
"
#define
PFX DRIVER_NAME ":
"
static
int
sol_compat
=
0
;
/* Solaris compatibility mode */
static
int
sol_compat
=
0
;
/* Solaris compatibility mode */
#ifdef MODULE
/* Solaris compatibility flag -
/* Solaris compatibility flag -
* The Solaris implementation omits support for several
* The Solaris implementation omits support for several
* documented driver features (ref Sun doc 806-0180-03).
* documented driver features (ref Sun doc 806-0180-03).
...
@@ -46,20 +41,20 @@ static int sol_compat = 0; /* Solaris compatibility mode */
...
@@ -46,20 +41,20 @@ static int sol_compat = 0; /* Solaris compatibility mode */
* If you wish the device to operate as under Solaris,
* If you wish the device to operate as under Solaris,
* omitting above features, set this parameter to non-zero.
* omitting above features, set this parameter to non-zero.
*/
*/
module_param
module_param
(
sol_compat
,
int
,
0
);
(
sol_compat
,
int
,
0
);
MODULE_PARM_DESC
(
sol_compat
,
MODULE_PARM_DESC
"Disables documented functionality omitted from Solaris driver"
);
(
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_AUTHOR
(
"Eric Brower <ebrower@usa.net>"
);
MODULE_DESCRIPTION
(
"7-Segment Display driver for Sun Microsystems CP1400/1500"
);
MODULE_LICENSE
(
"GPL"
);
MODULE_LICENSE
(
"GPL"
);
MODULE_SUPPORTED_DEVICE
MODULE_SUPPORTED_DEVICE
(
"d7s"
);
(
"d7s"
);
#endif
/* ifdef MODULE */
struct
d7s
{
void
__iomem
*
regs
;
bool
flipped
;
};
struct
d7s
*
d7s_device
;
/*
/*
* Register block address- see header for details
* Register block address- see header for details
...
@@ -72,22 +67,6 @@ MODULE_SUPPORTED_DEVICE
...
@@ -72,22 +67,6 @@ MODULE_SUPPORTED_DEVICE
* FLIP - Inverts display for upside-down mounted board
* FLIP - Inverts display for upside-down mounted board
* bits 0-4 - 7-segment display contents
* bits 0-4 - 7-segment display contents
*/
*/
static
void
__iomem
*
d7s_regs
;
static
inline
void
d7s_free
(
void
)
{
iounmap
(
d7s_regs
);
}
static
inline
int
d7s_obpflipped
(
void
)
{
int
opt_node
;
opt_node
=
prom_getchild
(
prom_root_node
);
opt_node
=
prom_searchsiblings
(
opt_node
,
"options"
);
return
((
-
1
!=
prom_getintdefault
(
opt_node
,
"d7s-flipped?"
,
-
1
))
?
0
:
1
);
}
static
atomic_t
d7s_users
=
ATOMIC_INIT
(
0
);
static
atomic_t
d7s_users
=
ATOMIC_INIT
(
0
);
static
int
d7s_open
(
struct
inode
*
inode
,
struct
file
*
f
)
static
int
d7s_open
(
struct
inode
*
inode
,
struct
file
*
f
)
...
@@ -106,12 +85,15 @@ static int d7s_release(struct inode *inode, struct file *f)
...
@@ -106,12 +85,15 @@ static int d7s_release(struct inode *inode, struct file *f)
* are not operating in solaris-compat mode
* are not operating in solaris-compat mode
*/
*/
if
(
atomic_dec_and_test
(
&
d7s_users
)
&&
!
sol_compat
)
{
if
(
atomic_dec_and_test
(
&
d7s_users
)
&&
!
sol_compat
)
{
int
regval
=
0
;
struct
d7s
*
p
=
d7s_device
;
u8
regval
=
0
;
regval
=
readb
(
d7s_regs
);
(
0
==
d7s_obpflipped
())
?
regval
=
readb
(
p
->
regs
);
writeb
(
regval
|=
D7S_FLIP
,
d7s_regs
)
:
if
(
p
->
flipped
)
writeb
(
regval
&=
~
D7S_FLIP
,
d7s_regs
);
regval
|=
D7S_FLIP
;
else
regval
&=
~
D7S_FLIP
;
writeb
(
regval
,
p
->
regs
);
}
}
return
0
;
return
0
;
...
@@ -119,9 +101,10 @@ static int d7s_release(struct inode *inode, struct file *f)
...
@@ -119,9 +101,10 @@ static int d7s_release(struct inode *inode, struct file *f)
static
long
d7s_ioctl
(
struct
file
*
file
,
unsigned
int
cmd
,
unsigned
long
arg
)
static
long
d7s_ioctl
(
struct
file
*
file
,
unsigned
int
cmd
,
unsigned
long
arg
)
{
{
__u8
regs
=
readb
(
d7s_regs
)
;
struct
d7s
*
p
=
d7s_device
;
__u8
ireg
=
0
;
u8
regs
=
readb
(
p
->
regs
)
;
int
error
=
0
;
int
error
=
0
;
u8
ireg
=
0
;
if
(
D7S_MINOR
!=
iminor
(
file
->
f_path
.
dentry
->
d_inode
))
if
(
D7S_MINOR
!=
iminor
(
file
->
f_path
.
dentry
->
d_inode
))
return
-
ENODEV
;
return
-
ENODEV
;
...
@@ -129,18 +112,20 @@ static long d7s_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
...
@@ -129,18 +112,20 @@ static long d7s_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
lock_kernel
();
lock_kernel
();
switch
(
cmd
)
{
switch
(
cmd
)
{
case
D7SIOCWR
:
case
D7SIOCWR
:
/* assign device register values
/* assign device register values
we mask-out D7S_FLIP
*
we mask-out D7S_FLIP
if in sol_compat mode
* if in sol_compat mode
*/
*/
if
(
get_user
(
ireg
,
(
int
__user
*
)
arg
))
{
if
(
get_user
(
ireg
,
(
int
__user
*
)
arg
))
{
error
=
-
EFAULT
;
error
=
-
EFAULT
;
break
;
break
;
}
}
if
(
0
!=
sol_compat
)
{
if
(
sol_compat
)
{
(
regs
&
D7S_FLIP
)
?
if
(
regs
&
D7S_FLIP
)
(
ireg
|=
D7S_FLIP
)
:
(
ireg
&=
~
D7S_FLIP
);
ireg
|=
D7S_FLIP
;
else
ireg
&=
~
D7S_FLIP
;
}
}
writeb
(
ireg
,
d7s_
regs
);
writeb
(
ireg
,
p
->
regs
);
break
;
break
;
case
D7SIOCRD
:
case
D7SIOCRD
:
...
@@ -158,9 +143,11 @@ static long d7s_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
...
@@ -158,9 +143,11 @@ static long d7s_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
case
D7SIOCTM
:
case
D7SIOCTM
:
/* toggle device mode-- flip display orientation */
/* toggle device mode-- flip display orientation */
(
regs
&
D7S_FLIP
)
?
if
(
regs
&
D7S_FLIP
)
(
regs
&=
~
D7S_FLIP
)
:
(
regs
|=
D7S_FLIP
);
regs
&=
~
D7S_FLIP
;
writeb
(
regs
,
d7s_regs
);
else
regs
|=
D7S_FLIP
;
writeb
(
regs
,
p
->
regs
);
break
;
break
;
};
};
unlock_kernel
();
unlock_kernel
();
...
@@ -176,69 +163,123 @@ static const struct file_operations d7s_fops = {
...
@@ -176,69 +163,123 @@ static const struct file_operations d7s_fops = {
.
release
=
d7s_release
,
.
release
=
d7s_release
,
};
};
static
struct
miscdevice
d7s_miscdev
=
{
D7S_MINOR
,
D7S_DEVNAME
,
&
d7s_fops
};
static
struct
miscdevice
d7s_miscdev
=
{
.
minor
=
D7S_MINOR
,
.
name
=
DRIVER_NAME
,
.
fops
=
&
d7s_fops
};
static
int
__init
d7s_init
(
void
)
static
int
__devinit
d7s_probe
(
struct
of_device
*
op
,
const
struct
of_device_id
*
match
)
{
{
struct
linux_ebus
*
ebus
=
NULL
;
struct
device_node
*
opts
;
struct
linux_ebus_device
*
edev
=
NULL
;
int
err
=
-
EINVAL
;
int
iTmp
=
0
,
regs
=
0
;
struct
d7s
*
p
;
u8
regs
;
for_each_ebus
(
ebus
)
{
for_each_ebusdev
(
edev
,
ebus
)
{
if
(
d7s_device
)
if
(
!
strcmp
(
edev
->
prom_node
->
name
,
D7S_OBPNAME
))
goto
out
;
goto
ebus_done
;
}
p
=
kzalloc
(
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
;
}
}
ebus_done:
err
=
misc_register
(
&
d7s_miscdev
);
if
(
!
edev
)
{
if
(
err
)
{
printk
(
"%s: unable to locate device
\n
"
,
D7S_DEVNAME
);
printk
(
KERN_ERR
PFX
"Unable to acquire miscdevice minor %i
\n
"
,
return
-
ENODEV
;
D7S_MINOR
);
goto
out_iounmap
;
}
}
d7s_regs
=
ioremap
(
edev
->
resource
[
0
].
start
,
sizeof
(
__u8
));
/* OBP option "d7s-flipped?" is honored as default for the
* device, and reset default when detached
iTmp
=
misc_register
(
&
d7s_miscdev
);
if
(
0
!=
iTmp
)
{
printk
(
"%s: unable to acquire miscdevice minor %i
\n
"
,
D7S_DEVNAME
,
D7S_MINOR
);
iounmap
(
d7s_regs
);
return
iTmp
;
}
/* OBP option "d7s-flipped?" is honored as default
* for the device, and reset default when detached
*/
*/
regs
=
readb
(
d7s_regs
);
regs
=
readb
(
p
->
regs
);
iTmp
=
d7s_obpflipped
();
opts
=
of_find_node_by_path
(
"/options"
);
(
0
==
iTmp
)
?
if
(
opts
&&
writeb
(
regs
|=
D7S_FLIP
,
d7s_regs
)
:
of_get_property
(
opts
,
"d7s-flipped?"
,
NULL
))
writeb
(
regs
&=
~
D7S_FLIP
,
d7s_regs
);
p
->
flipped
=
true
;
printk
(
"%s: 7-Segment Display%s at 0x%lx %s
\n
"
,
if
(
p
->
flipped
)
D7S_DEVNAME
,
regs
|=
D7S_FLIP
;
(
0
==
iTmp
)
?
(
" (FLIPPED)"
)
:
(
""
),
else
edev
->
resource
[
0
].
start
,
regs
&=
~
D7S_FLIP
;
(
0
!=
sol_compat
)
?
(
"in sol_compat mode"
)
:
(
""
));
writeb
(
regs
,
p
->
regs
);
return
0
;
printk
(
KERN_INFO
PFX
"7-Segment Display%s at [%s:0x%lx] %s
\n
"
,
op
->
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:
kfree
(
p
);
goto
out
;
}
}
static
void
__exit
d7s_cleanup
(
void
)
static
int
__devexit
d7s_remove
(
struct
of_device
*
op
)
{
{
int
regs
=
readb
(
d7s_regs
);
struct
d7s
*
p
=
dev_get_drvdata
(
&
op
->
dev
);
u8
regs
=
readb
(
p
->
regs
);
/* Honor OBP d7s-flipped? unless operating in solaris-compat mode */
/* Honor OBP d7s-flipped? unless operating in solaris-compat mode */
if
(
0
==
sol_compat
)
{
if
(
sol_compat
)
{
(
0
==
d7s_obpflipped
())
?
if
(
p
->
flipped
)
writeb
(
regs
|=
D7S_FLIP
,
d7s_regs
)
:
regs
|=
D7S_FLIP
;
writeb
(
regs
&=
~
D7S_FLIP
,
d7s_regs
);
else
regs
&=
~
D7S_FLIP
;
writeb
(
regs
,
p
->
regs
);
}
}
misc_deregister
(
&
d7s_miscdev
);
misc_deregister
(
&
d7s_miscdev
);
d7s_free
();
of_iounmap
(
&
op
->
resource
[
0
],
p
->
regs
,
sizeof
(
u8
));
kfree
(
p
);
return
0
;
}
static
struct
of_device_id
d7s_match
[]
=
{
{
.
name
=
"display7seg"
,
},
{},
};
MODULE_DEVICE_TABLE
(
of
,
d7s_match
);
static
struct
of_platform_driver
d7s_driver
=
{
.
name
=
DRIVER_NAME
,
.
match_table
=
d7s_match
,
.
probe
=
d7s_probe
,
.
remove
=
__devexit_p
(
d7s_remove
),
};
static
int
__init
d7s_init
(
void
)
{
return
of_register_driver
(
&
d7s_driver
,
&
of_bus_type
);
}
static
void
__exit
d7s_exit
(
void
)
{
of_unregister_driver
(
&
d7s_driver
);
}
}
module_init
(
d7s_init
);
module_init
(
d7s_init
);
module_exit
(
d7s_
cleanup
);
module_exit
(
d7s_
exit
);
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment