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
2cde4afa
Commit
2cde4afa
authored
Oct 10, 2007
by
Len Brown
Browse files
Options
Browse Files
Download
Plain Diff
Pull sony-2.6.24 into release branch
parents
e67c5d8d
fd1caaed
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
148 additions
and
56 deletions
+148
-56
drivers/misc/sony-laptop.c
drivers/misc/sony-laptop.c
+148
-56
No files found.
drivers/misc/sony-laptop.c
View file @
2cde4afa
...
...
@@ -1173,7 +1173,8 @@ static struct acpi_driver sony_nc_driver = {
#define SONYPI_TYPE3_OFFSET 0x12
struct
sony_pic_ioport
{
struct
acpi_resource_io
io
;
struct
acpi_resource_io
io1
;
struct
acpi_resource_io
io2
;
struct
list_head
list
;
};
...
...
@@ -1443,11 +1444,11 @@ static u8 sony_pic_call1(u8 dev)
{
u8
v1
,
v2
;
wait_on_command
(
inb_p
(
spic_dev
.
cur_ioport
->
io
.
minimum
+
4
)
&
2
,
wait_on_command
(
inb_p
(
spic_dev
.
cur_ioport
->
io
1
.
minimum
+
4
)
&
2
,
ITERATIONS_LONG
);
outb
(
dev
,
spic_dev
.
cur_ioport
->
io
.
minimum
+
4
);
v1
=
inb_p
(
spic_dev
.
cur_ioport
->
io
.
minimum
+
4
);
v2
=
inb_p
(
spic_dev
.
cur_ioport
->
io
.
minimum
);
outb
(
dev
,
spic_dev
.
cur_ioport
->
io
1
.
minimum
+
4
);
v1
=
inb_p
(
spic_dev
.
cur_ioport
->
io
1
.
minimum
+
4
);
v2
=
inb_p
(
spic_dev
.
cur_ioport
->
io
1
.
minimum
);
dprintk
(
"sony_pic_call1: 0x%.4x
\n
"
,
(
v2
<<
8
)
|
v1
);
return
v2
;
}
...
...
@@ -1456,13 +1457,13 @@ static u8 sony_pic_call2(u8 dev, u8 fn)
{
u8
v1
;
wait_on_command
(
inb_p
(
spic_dev
.
cur_ioport
->
io
.
minimum
+
4
)
&
2
,
wait_on_command
(
inb_p
(
spic_dev
.
cur_ioport
->
io
1
.
minimum
+
4
)
&
2
,
ITERATIONS_LONG
);
outb
(
dev
,
spic_dev
.
cur_ioport
->
io
.
minimum
+
4
);
wait_on_command
(
inb_p
(
spic_dev
.
cur_ioport
->
io
.
minimum
+
4
)
&
2
,
outb
(
dev
,
spic_dev
.
cur_ioport
->
io
1
.
minimum
+
4
);
wait_on_command
(
inb_p
(
spic_dev
.
cur_ioport
->
io
1
.
minimum
+
4
)
&
2
,
ITERATIONS_LONG
);
outb
(
fn
,
spic_dev
.
cur_ioport
->
io
.
minimum
);
v1
=
inb_p
(
spic_dev
.
cur_ioport
->
io
.
minimum
);
outb
(
fn
,
spic_dev
.
cur_ioport
->
io
1
.
minimum
);
v1
=
inb_p
(
spic_dev
.
cur_ioport
->
io
1
.
minimum
);
dprintk
(
"sony_pic_call2: 0x%.4x
\n
"
,
v1
);
return
v1
;
}
...
...
@@ -1471,13 +1472,13 @@ static u8 sony_pic_call3(u8 dev, u8 fn, u8 v)
{
u8
v1
;
wait_on_command
(
inb_p
(
spic_dev
.
cur_ioport
->
io
.
minimum
+
4
)
&
2
,
ITERATIONS_LONG
);
outb
(
dev
,
spic_dev
.
cur_ioport
->
io
.
minimum
+
4
);
wait_on_command
(
inb_p
(
spic_dev
.
cur_ioport
->
io
.
minimum
+
4
)
&
2
,
ITERATIONS_LONG
);
outb
(
fn
,
spic_dev
.
cur_ioport
->
io
.
minimum
);
wait_on_command
(
inb_p
(
spic_dev
.
cur_ioport
->
io
.
minimum
+
4
)
&
2
,
ITERATIONS_LONG
);
outb
(
v
,
spic_dev
.
cur_ioport
->
io
.
minimum
);
v1
=
inb_p
(
spic_dev
.
cur_ioport
->
io
.
minimum
);
wait_on_command
(
inb_p
(
spic_dev
.
cur_ioport
->
io
1
.
minimum
+
4
)
&
2
,
ITERATIONS_LONG
);
outb
(
dev
,
spic_dev
.
cur_ioport
->
io
1
.
minimum
+
4
);
wait_on_command
(
inb_p
(
spic_dev
.
cur_ioport
->
io
1
.
minimum
+
4
)
&
2
,
ITERATIONS_LONG
);
outb
(
fn
,
spic_dev
.
cur_ioport
->
io
1
.
minimum
);
wait_on_command
(
inb_p
(
spic_dev
.
cur_ioport
->
io
1
.
minimum
+
4
)
&
2
,
ITERATIONS_LONG
);
outb
(
v
,
spic_dev
.
cur_ioport
->
io
1
.
minimum
);
v1
=
inb_p
(
spic_dev
.
cur_ioport
->
io
1
.
minimum
);
dprintk
(
"sony_pic_call3: 0x%.4x
\n
"
,
v1
);
return
v1
;
}
...
...
@@ -2074,7 +2075,18 @@ sony_pic_read_possible_resource(struct acpi_resource *resource, void *context)
switch
(
resource
->
type
)
{
case
ACPI_RESOURCE_TYPE_START_DEPENDENT
:
{
/* start IO enumeration */
struct
sony_pic_ioport
*
ioport
=
kzalloc
(
sizeof
(
*
ioport
),
GFP_KERNEL
);
if
(
!
ioport
)
return
AE_ERROR
;
list_add
(
&
ioport
->
list
,
&
dev
->
ioports
);
return
AE_OK
;
}
case
ACPI_RESOURCE_TYPE_END_DEPENDENT
:
/* end IO enumeration */
return
AE_OK
;
case
ACPI_RESOURCE_TYPE_IRQ
:
...
...
@@ -2101,7 +2113,7 @@ sony_pic_read_possible_resource(struct acpi_resource *resource, void *context)
if
(
!
interrupt
)
return
AE_ERROR
;
list_add
_tail
(
&
interrupt
->
list
,
&
dev
->
interrupts
);
list_add
(
&
interrupt
->
list
,
&
dev
->
interrupts
);
interrupt
->
irq
.
triggering
=
p
->
triggering
;
interrupt
->
irq
.
polarity
=
p
->
polarity
;
interrupt
->
irq
.
sharable
=
p
->
sharable
;
...
...
@@ -2113,18 +2125,27 @@ sony_pic_read_possible_resource(struct acpi_resource *resource, void *context)
case
ACPI_RESOURCE_TYPE_IO
:
{
struct
acpi_resource_io
*
io
=
&
resource
->
data
.
io
;
struct
sony_pic_ioport
*
ioport
=
NULL
;
struct
sony_pic_ioport
*
ioport
=
list_first_entry
(
&
dev
->
ioports
,
struct
sony_pic_ioport
,
list
);
if
(
!
io
)
{
dprintk
(
"Blank IO resource
\n
"
);
return
AE_OK
;
}
ioport
=
kzalloc
(
sizeof
(
*
ioport
),
GFP_KERNEL
);
if
(
!
ioport
)
if
(
!
ioport
->
io1
.
minimum
)
{
memcpy
(
&
ioport
->
io1
,
io
,
sizeof
(
*
io
));
dprintk
(
"IO1 at 0x%.4x (0x%.2x)
\n
"
,
ioport
->
io1
.
minimum
,
ioport
->
io1
.
address_length
);
}
else
if
(
!
ioport
->
io2
.
minimum
)
{
memcpy
(
&
ioport
->
io2
,
io
,
sizeof
(
*
io
));
dprintk
(
"IO2 at 0x%.4x (0x%.2x)
\n
"
,
ioport
->
io2
.
minimum
,
ioport
->
io2
.
address_length
);
}
else
{
printk
(
KERN_ERR
DRV_PFX
"Unknown SPIC Type, more than 2 IO Ports
\n
"
);
return
AE_ERROR
;
list_add_tail
(
&
ioport
->
list
,
&
dev
->
ioports
);
memcpy
(
&
ioport
->
io
,
io
,
sizeof
(
*
io
));
}
return
AE_OK
;
}
default:
...
...
@@ -2199,10 +2220,22 @@ static int sony_pic_enable(struct acpi_device *device,
{
acpi_status
status
;
int
result
=
0
;
/* Type 1 resource layout is:
* IO
* IO
* IRQNoFlags
* End
*
* Type 2 and 3 resource layout is:
* IO
* IRQNoFlags
* End
*/
struct
{
struct
acpi_resource
io_res
;
struct
acpi_resource
irq_res
;
struct
acpi_resource
end
;
struct
acpi_resource
res1
;
struct
acpi_resource
res2
;
struct
acpi_resource
res3
;
struct
acpi_resource
res4
;
}
*
resource
;
struct
acpi_buffer
buffer
=
{
0
,
NULL
};
...
...
@@ -2217,21 +2250,49 @@ static int sony_pic_enable(struct acpi_device *device,
buffer
.
length
=
sizeof
(
*
resource
)
+
1
;
buffer
.
pointer
=
resource
;
/* setup io resource */
resource
->
io_res
.
type
=
ACPI_RESOURCE_TYPE_IO
;
resource
->
io_res
.
length
=
sizeof
(
struct
acpi_resource
);
memcpy
(
&
resource
->
io_res
.
data
.
io
,
&
ioport
->
io
,
sizeof
(
struct
acpi_resource_io
));
/* setup Type 1 resources */
if
(
spic_dev
.
model
==
SONYPI_DEVICE_TYPE1
)
{
/* setup irq resource */
resource
->
irq_res
.
type
=
ACPI_RESOURCE_TYPE_IRQ
;
resource
->
irq_res
.
length
=
sizeof
(
struct
acpi_resource
);
memcpy
(
&
resource
->
irq_res
.
data
.
irq
,
&
irq
->
irq
,
sizeof
(
struct
acpi_resource_irq
));
/* we requested a shared irq */
resource
->
irq_res
.
data
.
irq
.
sharable
=
ACPI_SHARED
;
/* setup io resources */
resource
->
res1
.
type
=
ACPI_RESOURCE_TYPE_IO
;
resource
->
res1
.
length
=
sizeof
(
struct
acpi_resource
);
memcpy
(
&
resource
->
res1
.
data
.
io
,
&
ioport
->
io1
,
sizeof
(
struct
acpi_resource_io
));
resource
->
end
.
type
=
ACPI_RESOURCE_TYPE_END_TAG
;
resource
->
res2
.
type
=
ACPI_RESOURCE_TYPE_IO
;
resource
->
res2
.
length
=
sizeof
(
struct
acpi_resource
);
memcpy
(
&
resource
->
res2
.
data
.
io
,
&
ioport
->
io2
,
sizeof
(
struct
acpi_resource_io
));
/* setup irq resource */
resource
->
res3
.
type
=
ACPI_RESOURCE_TYPE_IRQ
;
resource
->
res3
.
length
=
sizeof
(
struct
acpi_resource
);
memcpy
(
&
resource
->
res3
.
data
.
irq
,
&
irq
->
irq
,
sizeof
(
struct
acpi_resource_irq
));
/* we requested a shared irq */
resource
->
res3
.
data
.
irq
.
sharable
=
ACPI_SHARED
;
resource
->
res4
.
type
=
ACPI_RESOURCE_TYPE_END_TAG
;
}
/* setup Type 2/3 resources */
else
{
/* setup io resource */
resource
->
res1
.
type
=
ACPI_RESOURCE_TYPE_IO
;
resource
->
res1
.
length
=
sizeof
(
struct
acpi_resource
);
memcpy
(
&
resource
->
res1
.
data
.
io
,
&
ioport
->
io1
,
sizeof
(
struct
acpi_resource_io
));
/* setup irq resource */
resource
->
res2
.
type
=
ACPI_RESOURCE_TYPE_IRQ
;
resource
->
res2
.
length
=
sizeof
(
struct
acpi_resource
);
memcpy
(
&
resource
->
res2
.
data
.
irq
,
&
irq
->
irq
,
sizeof
(
struct
acpi_resource_irq
));
/* we requested a shared irq */
resource
->
res2
.
data
.
irq
.
sharable
=
ACPI_SHARED
;
resource
->
res3
.
type
=
ACPI_RESOURCE_TYPE_END_TAG
;
}
/* Attempt to set the resource */
dprintk
(
"Evaluating _SRS
\n
"
);
...
...
@@ -2239,7 +2300,7 @@ static int sony_pic_enable(struct acpi_device *device,
/* check for total failure */
if
(
ACPI_FAILURE
(
status
))
{
printk
(
KERN_ERR
DRV_PFX
"Error evaluating _SRS"
);
printk
(
KERN_ERR
DRV_PFX
"Error evaluating _SRS
\n
"
);
result
=
-
ENODEV
;
goto
end
;
}
...
...
@@ -2268,11 +2329,14 @@ static irqreturn_t sony_pic_irq(int irq, void *dev_id)
struct
sony_pic_dev
*
dev
=
(
struct
sony_pic_dev
*
)
dev_id
;
ev
=
inb_p
(
dev
->
cur_ioport
->
io
.
minimum
);
data_mask
=
inb_p
(
dev
->
cur_ioport
->
io
.
minimum
+
dev
->
evport_offset
);
ev
=
inb_p
(
dev
->
cur_ioport
->
io1
.
minimum
);
if
(
dev
->
cur_ioport
->
io2
.
minimum
)
data_mask
=
inb_p
(
dev
->
cur_ioport
->
io2
.
minimum
);
else
data_mask
=
inb_p
(
dev
->
cur_ioport
->
io1
.
minimum
+
dev
->
evport_offset
);
dprintk
(
"event ([%.2x] [%.2x]) at port 0x%.4x(+0x%.2x)
\n
"
,
ev
,
data_mask
,
dev
->
cur_ioport
->
io
.
minimum
,
dev
->
evport_offset
);
ev
,
data_mask
,
dev
->
cur_ioport
->
io
1
.
minimum
,
dev
->
evport_offset
);
if
(
ev
==
0x00
||
ev
==
0xff
)
return
IRQ_HANDLED
;
...
...
@@ -2323,8 +2387,11 @@ static int sony_pic_remove(struct acpi_device *device, int type)
}
free_irq
(
spic_dev
.
cur_irq
->
irq
.
interrupts
[
0
],
&
spic_dev
);
release_region
(
spic_dev
.
cur_ioport
->
io
.
minimum
,
spic_dev
.
cur_ioport
->
io
.
address_length
);
release_region
(
spic_dev
.
cur_ioport
->
io1
.
minimum
,
spic_dev
.
cur_ioport
->
io1
.
address_length
);
if
(
spic_dev
.
cur_ioport
->
io2
.
minimum
)
release_region
(
spic_dev
.
cur_ioport
->
io2
.
minimum
,
spic_dev
.
cur_ioport
->
io2
.
address_length
);
sonypi_compat_exit
();
...
...
@@ -2397,14 +2464,36 @@ static int sony_pic_add(struct acpi_device *device)
goto
err_remove_input
;
/* request io port */
list_for_each_entry
(
io
,
&
spic_dev
.
ioports
,
list
)
{
if
(
request_region
(
io
->
io
.
minimum
,
io
->
io
.
address_length
,
list_for_each_entry
_reverse
(
io
,
&
spic_dev
.
ioports
,
list
)
{
if
(
request_region
(
io
->
io
1
.
minimum
,
io
->
io1
.
address_length
,
"Sony Programable I/O Device"
))
{
dprintk
(
"I/O port: 0x%.4x (0x%.4x) + 0x%.2x
\n
"
,
io
->
io
.
minimum
,
io
->
io
.
maximum
,
io
->
io
.
address_length
);
spic_dev
.
cur_ioport
=
io
;
break
;
dprintk
(
"I/O port1: 0x%.4x (0x%.4x) + 0x%.2x
\n
"
,
io
->
io1
.
minimum
,
io
->
io1
.
maximum
,
io
->
io1
.
address_length
);
/* Type 1 have 2 ioports */
if
(
io
->
io2
.
minimum
)
{
if
(
request_region
(
io
->
io2
.
minimum
,
io
->
io2
.
address_length
,
"Sony Programable I/O Device"
))
{
dprintk
(
"I/O port2: 0x%.4x (0x%.4x) + 0x%.2x
\n
"
,
io
->
io2
.
minimum
,
io
->
io2
.
maximum
,
io
->
io2
.
address_length
);
spic_dev
.
cur_ioport
=
io
;
break
;
}
else
{
dprintk
(
"Unable to get I/O port2: "
"0x%.4x (0x%.4x) + 0x%.2x
\n
"
,
io
->
io2
.
minimum
,
io
->
io2
.
maximum
,
io
->
io2
.
address_length
);
release_region
(
io
->
io1
.
minimum
,
io
->
io1
.
address_length
);
}
}
else
{
spic_dev
.
cur_ioport
=
io
;
break
;
}
}
}
if
(
!
spic_dev
.
cur_ioport
)
{
...
...
@@ -2414,7 +2503,7 @@ static int sony_pic_add(struct acpi_device *device)
}
/* request IRQ */
list_for_each_entry
(
irq
,
&
spic_dev
.
interrupts
,
list
)
{
list_for_each_entry
_reverse
(
irq
,
&
spic_dev
.
interrupts
,
list
)
{
if
(
!
request_irq
(
irq
->
irq
.
interrupts
[
0
],
sony_pic_irq
,
IRQF_SHARED
,
"sony-laptop"
,
&
spic_dev
))
{
dprintk
(
"IRQ: %d - triggering: %d - "
...
...
@@ -2462,8 +2551,11 @@ static int sony_pic_add(struct acpi_device *device)
free_irq
(
spic_dev
.
cur_irq
->
irq
.
interrupts
[
0
],
&
spic_dev
);
err_release_region:
release_region
(
spic_dev
.
cur_ioport
->
io
.
minimum
,
spic_dev
.
cur_ioport
->
io
.
address_length
);
release_region
(
spic_dev
.
cur_ioport
->
io1
.
minimum
,
spic_dev
.
cur_ioport
->
io1
.
address_length
);
if
(
spic_dev
.
cur_ioport
->
io2
.
minimum
)
release_region
(
spic_dev
.
cur_ioport
->
io2
.
minimum
,
spic_dev
.
cur_ioport
->
io2
.
address_length
);
err_remove_compat:
sonypi_compat_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