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
Kirill Smelkov
linux
Commits
237f8aaf
Commit
237f8aaf
authored
Aug 27, 2008
by
David S. Miller
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
sparc: Convert uctrl driver to OF driver.
Signed-off-by:
David S. Miller
<
davem@davemloft.net
>
parent
a9540d34
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
121 additions
and
97 deletions
+121
-97
drivers/sbus/char/Kconfig
drivers/sbus/char/Kconfig
+1
-1
drivers/sbus/char/uctrl.c
drivers/sbus/char/uctrl.c
+120
-96
No files found.
drivers/sbus/char/Kconfig
View file @
237f8aaf
...
...
@@ -32,7 +32,7 @@ config OBP_FLASH
config TADPOLE_TS102_UCTRL
tristate "Tadpole TS102 Microcontroller support (EXPERIMENTAL)"
depends on EXPERIMENTAL
&& SPARC32
depends on EXPERIMENTAL
help
Say Y here to directly support the TS102 Microcontroller interface
on the Tadpole Sparcbook 3. This device handles power-management
...
...
drivers/sbus/char/uctrl.c
View file @
237f8aaf
/* $Id: uctrl.c,v 1.12 2001/10/08 22:19:51 davem Exp $
* uctrl.c: TS102 Microcontroller interface on Tadpole Sparcbook 3
/* uctrl.c: TS102 Microcontroller interface on Tadpole Sparcbook 3
*
* Copyright 1999 Derrick J Brashear (shadow@dementia.org)
* Copyright 2008 David S. Miller (davem@davemloft.net)
*/
#include <linux/module.h>
...
...
@@ -14,6 +14,8 @@
#include <linux/init.h>
#include <linux/miscdevice.h>
#include <linux/mm.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <asm/openprom.h>
#include <asm/oplib.h>
...
...
@@ -21,7 +23,6 @@
#include <asm/irq.h>
#include <asm/io.h>
#include <asm/pgtable.h>
#include <asm/sbus.h>
#define UCTRL_MINOR 174
...
...
@@ -33,26 +34,26 @@
#endif
struct
uctrl_regs
{
volatile
u32
uctrl_intr
;
volatile
u32
uctrl_data
;
volatile
u32
uctrl_stat
;
volatile
u32
uctrl_xxx
[
5
];
u32
uctrl_intr
;
u32
uctrl_data
;
u32
uctrl_stat
;
u32
uctrl_xxx
[
5
];
};
struct
ts102_regs
{
volatile
u32
card_a_intr
;
volatile
u32
card_a_stat
;
volatile
u32
card_a_ctrl
;
volatile
u32
card_a_xxx
;
volatile
u32
card_b_intr
;
volatile
u32
card_b_stat
;
volatile
u32
card_b_ctrl
;
volatile
u32
card_b_xxx
;
volatile
u32
uctrl_intr
;
volatile
u32
uctrl_data
;
volatile
u32
uctrl_stat
;
volatile
u32
uctrl_xxx
;
volatile
u32
ts102_xxx
[
4
];
u32
card_a_intr
;
u32
card_a_stat
;
u32
card_a_ctrl
;
u32
card_a_xxx
;
u32
card_b_intr
;
u32
card_b_stat
;
u32
card_b_ctrl
;
u32
card_b_xxx
;
u32
uctrl_intr
;
u32
uctrl_data
;
u32
uctrl_stat
;
u32
uctrl_xxx
;
u32
ts102_xxx
[
4
];
};
/* Bits for uctrl_intr register */
...
...
@@ -186,17 +187,15 @@ enum uctrl_opcode {
POWER_RESTART
=
0x83
,
};
struct
uctrl_driver
{
struct
uctrl_regs
*
regs
;
st
atic
st
ruct
uctrl_driver
{
struct
uctrl_regs
__iomem
*
regs
;
int
irq
;
int
pending
;
struct
uctrl_status
status
;
};
static
struct
uctrl_driver
drv
;
}
*
global_driver
;
static
void
uctrl_get_event_status
(
void
);
static
void
uctrl_get_external_status
(
void
);
static
void
uctrl_get_event_status
(
struct
uctrl_driver
*
);
static
void
uctrl_get_external_status
(
struct
uctrl_driver
*
);
static
int
uctrl_ioctl
(
struct
inode
*
inode
,
struct
file
*
file
,
...
...
@@ -213,16 +212,14 @@ static int
uctrl_open
(
struct
inode
*
inode
,
struct
file
*
file
)
{
lock_kernel
();
uctrl_get_event_status
();
uctrl_get_external_status
();
uctrl_get_event_status
(
global_driver
);
uctrl_get_external_status
(
global_driver
);
unlock_kernel
();
return
0
;
}
static
irqreturn_t
uctrl_interrupt
(
int
irq
,
void
*
dev_id
)
{
struct
uctrl_driver
*
driver
=
(
struct
uctrl_driver
*
)
dev_id
;
printk
(
"in uctrl_interrupt
\n
"
);
return
IRQ_HANDLED
;
}
...
...
@@ -244,11 +241,11 @@ static struct miscdevice uctrl_dev = {
{ \
unsigned int i; \
for (i = 0; i < 10000; i++) { \
if (UCTRL_STAT_TXNF_STA & driver->regs->uctrl_stat
) \
if (UCTRL_STAT_TXNF_STA & sbus_readl(&driver->regs->uctrl_stat)
) \
break; \
} \
dprintk(("write data 0x%02x\n", value)); \
driver->regs->uctrl_data = value
; \
sbus_writel(value, &driver->regs->uctrl_data)
; \
}
/* Wait for something to read, read it, then clear the bit */
...
...
@@ -257,24 +254,23 @@ static struct miscdevice uctrl_dev = {
unsigned int i; \
value = 0; \
for (i = 0; i < 10000; i++) { \
if ((UCTRL_STAT_RXNE_STA & driver->regs->uctrl_stat
) == 0) \
if ((UCTRL_STAT_RXNE_STA & sbus_readl(&driver->regs->uctrl_stat)
) == 0) \
break; \
udelay(1); \
} \
value =
driver->regs->uctrl_data
; \
value =
sbus_readl(&driver->regs->uctrl_data)
; \
dprintk(("read data 0x%02x\n", value)); \
driver->regs->uctrl_stat = UCTRL_STAT_RXNE_STA
; \
sbus_writel(UCTRL_STAT_RXNE_STA, &driver->regs->uctrl_stat)
; \
}
static
void
uctrl_do_txn
(
struct
uctrl_txn
*
txn
)
static
void
uctrl_do_txn
(
struct
uctrl_
driver
*
driver
,
struct
uctrl_
txn
*
txn
)
{
struct
uctrl_driver
*
driver
=
&
drv
;
int
stat
,
incnt
,
outcnt
,
bytecnt
,
intr
;
u32
byte
;
stat
=
driver
->
regs
->
uctrl_stat
;
intr
=
driver
->
regs
->
uctrl_intr
;
driver
->
regs
->
uctrl_stat
=
stat
;
stat
=
sbus_readl
(
&
driver
->
regs
->
uctrl_stat
)
;
intr
=
sbus_readl
(
&
driver
->
regs
->
uctrl_intr
)
;
sbus_writel
(
stat
,
&
driver
->
regs
->
uctrl_stat
)
;
dprintk
((
"interrupt stat 0x%x int 0x%x
\n
"
,
stat
,
intr
));
...
...
@@ -305,9 +301,8 @@ static void uctrl_do_txn(struct uctrl_txn *txn)
}
}
static
void
uctrl_get_event_status
(
void
)
static
void
uctrl_get_event_status
(
struct
uctrl_driver
*
driver
)
{
struct
uctrl_driver
*
driver
=
&
drv
;
struct
uctrl_txn
txn
;
u8
outbits
[
2
];
...
...
@@ -317,7 +312,7 @@ static void uctrl_get_event_status(void)
txn
.
inbuf
=
NULL
;
txn
.
outbuf
=
outbits
;
uctrl_do_txn
(
&
txn
);
uctrl_do_txn
(
driver
,
&
txn
);
dprintk
((
"bytes %x %x
\n
"
,
(
outbits
[
0
]
&
0xff
),
(
outbits
[
1
]
&
0xff
)));
driver
->
status
.
event_status
=
...
...
@@ -325,9 +320,8 @@ static void uctrl_get_event_status(void)
dprintk
((
"ev is %x
\n
"
,
driver
->
status
.
event_status
));
}
static
void
uctrl_get_external_status
(
void
)
static
void
uctrl_get_external_status
(
struct
uctrl_driver
*
driver
)
{
struct
uctrl_driver
*
driver
=
&
drv
;
struct
uctrl_txn
txn
;
u8
outbits
[
2
];
int
i
,
v
;
...
...
@@ -338,7 +332,7 @@ static void uctrl_get_external_status(void)
txn
.
inbuf
=
NULL
;
txn
.
outbuf
=
outbits
;
uctrl_do_txn
(
&
txn
);
uctrl_do_txn
(
driver
,
&
txn
);
dprintk
((
"bytes %x %x
\n
"
,
(
outbits
[
0
]
&
0xff
),
(
outbits
[
1
]
&
0xff
)));
driver
->
status
.
external_status
=
...
...
@@ -354,71 +348,101 @@ static void uctrl_get_external_status(void)
}
static
int
__init
ts102_uctrl_init
(
void
)
static
int
__devinit
uctrl_probe
(
struct
of_device
*
op
,
const
struct
of_device_id
*
match
)
{
struct
uctrl_driver
*
driver
=
&
drv
;
int
len
;
struct
linux_prom_irqs
tmp_irq
[
2
];
unsigned
int
vaddr
[
2
]
=
{
0
,
0
};
int
tmpnode
,
uctrlnode
=
prom_getchild
(
prom_root_node
);
int
err
;
struct
uctrl_driver
*
p
;
int
err
=
-
ENOMEM
;
tmpnode
=
prom_searchsiblings
(
uctrlnode
,
"obio"
);
p
=
kzalloc
(
sizeof
(
*
p
),
GFP_KERNEL
);
if
(
!
p
)
{
printk
(
KERN_ERR
"uctrl: Unable to allocate device struct.
\n
"
);
goto
out
;
}
if
(
tmpnode
)
uctrlnode
=
prom_getchild
(
tmpnode
);
p
->
regs
=
of_ioremap
(
&
op
->
resource
[
0
],
0
,
resource_size
(
&
op
->
resource
[
0
]),
"uctrl"
);
if
(
!
p
->
regs
)
{
printk
(
KERN_ERR
"uctrl: Unable to map registers.
\n
"
);
goto
out_free
;
}
uctrlnode
=
prom_searchsiblings
(
uctrlnode
,
"uctrl"
);
p
->
irq
=
op
->
irqs
[
0
];
err
=
request_irq
(
p
->
irq
,
uctrl_interrupt
,
0
,
"uctrl"
,
p
);
if
(
err
)
{
printk
(
KERN_ERR
"uctrl: Unable to register irq.
\n
"
);
goto
out_iounmap
;
}
if
(
!
uctrlnode
)
return
-
ENODEV
;
err
=
misc_register
(
&
uctrl_dev
);
if
(
err
)
{
printk
(
KERN_ERR
"uctrl: Unable to register misc device.
\n
"
);
goto
out_free_irq
;
}
/* the prom mapped it for us */
len
=
prom_getproperty
(
uctrlnode
,
"address"
,
(
void
*
)
vaddr
,
sizeof
(
vaddr
));
driver
->
regs
=
(
struct
uctrl_regs
*
)
vaddr
[
0
];
sbus_writel
(
UCTRL_INTR_RXNE_REQ
|
UCTRL_INTR_RXNE_MSK
,
&
p
->
regs
->
uctrl_intr
);
printk
(
KERN_INFO
"%s: uctrl regs[0x%p] (irq %d)
\n
"
,
op
->
node
->
full_name
,
p
->
regs
,
p
->
irq
);
uctrl_get_event_status
(
p
);
uctrl_get_external_status
(
p
);
len
=
prom_getproperty
(
uctrlnode
,
"intr"
,
(
char
*
)
tmp_irq
,
sizeof
(
tmp_irq
))
;
dev_set_drvdata
(
&
op
->
dev
,
p
);
global_driver
=
p
;
/* Flush device */
READUCTLDATA
(
len
)
;
out:
return
err
;
if
(
!
driver
->
irq
)
driver
->
irq
=
tmp_irq
[
0
].
pri
;
out_free_irq:
free_irq
(
p
->
irq
,
p
)
;
err
=
request_irq
(
driver
->
irq
,
uctrl_interrupt
,
0
,
"uctrl"
,
driver
);
if
(
err
)
{
printk
(
"%s: unable to register irq %d
\n
"
,
__func__
,
driver
->
irq
);
return
err
;
}
out_iounmap:
of_iounmap
(
&
op
->
resource
[
0
],
p
->
regs
,
resource_size
(
&
op
->
resource
[
0
]));
if
(
misc_register
(
&
uctrl_dev
))
{
printk
(
"%s: unable to get misc minor %d
\n
"
,
__func__
,
uctrl_dev
.
minor
);
free_irq
(
driver
->
irq
,
driver
);
return
-
ENODEV
;
}
out_free:
kfree
(
p
);
goto
out
;
}
driver
->
regs
->
uctrl_intr
=
UCTRL_INTR_RXNE_REQ
|
UCTRL_INTR_RXNE_MSK
;
printk
(
"uctrl: 0x%p (irq %d)
\n
"
,
driver
->
regs
,
driver
->
irq
);
uctrl_get_event_status
();
uctrl_get_external_status
();
return
0
;
static
int
__devexit
uctrl_remove
(
struct
of_device
*
op
)
{
struct
uctrl_driver
*
p
=
dev_get_drvdata
(
&
op
->
dev
);
if
(
p
)
{
misc_deregister
(
&
uctrl_dev
);
free_irq
(
p
->
irq
,
p
);
of_iounmap
(
&
op
->
resource
[
0
],
p
->
regs
,
resource_size
(
&
op
->
resource
[
0
]));
kfree
(
p
);
}
return
0
;
}
static
void
__exit
ts102_uctrl_cleanup
(
void
)
static
struct
of_device_id
uctrl_match
[]
=
{
{
.
name
=
"uctrl"
,
},
{},
};
MODULE_DEVICE_TABLE
(
of
,
uctrl_match
);
static
struct
of_platform_driver
uctrl_driver
=
{
.
name
=
"uctrl"
,
.
match_table
=
uctrl_match
,
.
probe
=
uctrl_probe
,
.
remove
=
__devexit_p
(
uctrl_remove
),
};
static
int
__init
uctrl_init
(
void
)
{
struct
uctrl_driver
*
driver
=
&
drv
;
return
of_register_driver
(
&
uctrl_driver
,
&
of_bus_type
);
}
misc_deregister
(
&
uctrl_dev
);
if
(
driver
->
irq
)
free_irq
(
driver
->
irq
,
driver
);
if
(
driver
->
regs
)
driver
->
regs
=
NULL
;
static
void
__exit
uctrl_exit
(
void
)
{
of_unregister_driver
(
&
uctrl_driver
);
}
module_init
(
ts102_
uctrl_init
);
module_exit
(
ts102_uctrl_cleanup
);
module_init
(
uctrl_init
);
module_exit
(
uctrl_exit
);
MODULE_LICENSE
(
"GPL"
);
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