Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
linux-davinci
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
linux
linux-davinci
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 - Driver implementation for the 7-segment display
* present on Sun Microsystems CP1400 and CP1500
/* 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/kernel.h>
...
...
@@ -16,22 +13,20 @@
#include <linux/miscdevice.h>
#include <linux/ioport.h>
/* request_region */
#include <linux/smp_lock.h>
#include <linux/of.h>
#include <linux/of_device.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/io.h>
#include <asm/display7seg.h>
#define D7S_MINOR 193
#define D
7S_OBPNAME "display7seg
"
#define
D7S_DEVNAME "d7s
"
#define D
RIVER_NAME "d7s
"
#define
PFX DRIVER_NAME ":
"
static
int
sol_compat
=
0
;
/* Solaris compatibility mode */
#ifdef MODULE
/* Solaris compatibility flag -
* The Solaris implementation omits support for several
* documented driver features (ref Sun doc 806-0180-03).
...
...
@@ -46,20 +41,20 @@ static int sol_compat = 0; /* Solaris compatibility mode */
* 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_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"
);
#endif
/* ifdef MODULE */
MODULE_SUPPORTED_DEVICE
(
"d7s"
);
struct
d7s
{
void
__iomem
*
regs
;
bool
flipped
;
};
struct
d7s
*
d7s_device
;
/*
* Register block address- see header for details
...
...
@@ -72,22 +67,6 @@ MODULE_SUPPORTED_DEVICE
* FLIP - Inverts display for upside-down mounted board
* 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
int
d7s_open
(
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
*/
if
(
atomic_dec_and_test
(
&
d7s_users
)
&&
!
sol_compat
)
{
int
regval
=
0
;
regval
=
readb
(
d7s_regs
);
(
0
==
d7s_obpflipped
())
?
writeb
(
regval
|=
D7S_FLIP
,
d7s_regs
)
:
writeb
(
regval
&=
~
D7S_FLIP
,
d7s_regs
);
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
;
...
...
@@ -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
)
{
__u8
regs
=
readb
(
d7s_regs
)
;
__u8
ireg
=
0
;
struct
d7s
*
p
=
d7s_device
;
u8
regs
=
readb
(
p
->
regs
)
;
int
error
=
0
;
u8
ireg
=
0
;
if
(
D7S_MINOR
!=
iminor
(
file
->
f_path
.
dentry
->
d_inode
))
return
-
ENODEV
;
...
...
@@ -129,18 +112,20 @@ static long d7s_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
lock_kernel
();
switch
(
cmd
)
{
case
D7SIOCWR
:
/* assign device register values
*
we mask-out D7S_FLIP
if in sol_compat mode
/* 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
(
0
!=
sol_compat
)
{
(
regs
&
D7S_FLIP
)
?
(
ireg
|=
D7S_FLIP
)
:
(
ireg
&=
~
D7S_FLIP
);
if
(
sol_compat
)
{
if
(
regs
&
D7S_FLIP
)
ireg
|=
D7S_FLIP
;
else
ireg
&=
~
D7S_FLIP
;
}
writeb
(
ireg
,
d7s_
regs
);
writeb
(
ireg
,
p
->
regs
);
break
;
case
D7SIOCRD
:
...
...
@@ -158,9 +143,11 @@ static long d7s_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
case
D7SIOCTM
:
/* toggle device mode-- flip display orientation */
(
regs
&
D7S_FLIP
)
?
(
regs
&=
~
D7S_FLIP
)
:
(
regs
|=
D7S_FLIP
);
writeb
(
regs
,
d7s_regs
);
if
(
regs
&
D7S_FLIP
)
regs
&=
~
D7S_FLIP
;
else
regs
|=
D7S_FLIP
;
writeb
(
regs
,
p
->
regs
);
break
;
};
unlock_kernel
();
...
...
@@ -176,69 +163,123 @@ static const struct file_operations d7s_fops = {
.
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
linux_ebus_device
*
edev
=
NULL
;
int
iTmp
=
0
,
regs
=
0
;
for_each_ebus
(
ebus
)
{
for_each_ebusdev
(
edev
,
ebus
)
{
if
(
!
strcmp
(
edev
->
prom_node
->
name
,
D7S_OBPNAME
))
goto
ebus_done
;
}
struct
device_node
*
opts
;
int
err
=
-
EINVAL
;
struct
d7s
*
p
;
u8
regs
;
if
(
d7s_device
)
goto
out
;
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:
if
(
!
edev
)
{
printk
(
"%s: unable to locate device
\n
"
,
D7S_DEVNAME
);
return
-
ENODEV
;
err
=
misc_register
(
&
d7s_miscdev
);
if
(
err
)
{
printk
(
KERN_ERR
PFX
"Unable to acquire miscdevice minor %i
\n
"
,
D7S_MINOR
);
goto
out_iounmap
;
}
d7s_regs
=
ioremap
(
edev
->
resource
[
0
].
start
,
sizeof
(
__u8
));
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
/* OBP option "d7s-flipped?" is honored as default for the
* device, and reset default when detached
*/
regs
=
readb
(
d7s_regs
);
iTmp
=
d7s_obpflipped
();
(
0
==
iTmp
)
?
writeb
(
regs
|=
D7S_FLIP
,
d7s_regs
)
:
writeb
(
regs
&=
~
D7S_FLIP
,
d7s_regs
);
printk
(
"%s: 7-Segment Display%s at 0x%lx %s
\n
"
,
D7S_DEVNAME
,
(
0
==
iTmp
)
?
(
" (FLIPPED)"
)
:
(
""
),
edev
->
resource
[
0
].
start
,
(
0
!=
sol_compat
)
?
(
"in sol_compat mode"
)
:
(
""
));
return
0
;
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%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 */
if
(
0
==
sol_compat
)
{
(
0
==
d7s_obpflipped
())
?
writeb
(
regs
|=
D7S_FLIP
,
d7s_regs
)
:
writeb
(
regs
&=
~
D7S_FLIP
,
d7s_regs
);
if
(
sol_compat
)
{
if
(
p
->
flipped
)
regs
|=
D7S_FLIP
;
else
regs
&=
~
D7S_FLIP
;
writeb
(
regs
,
p
->
regs
);
}
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_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