Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Open sidebar
OpenBMC Firmware
talos-obmc-linux
Commits
84860bf0
Commit
84860bf0
authored
19 years ago
by
Linus Torvalds
Browse files
Options
Download
Plain Diff
Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/driver-2.6
parents
8caf8915
6fbfddcb
Changes
244
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
198 additions
and
204 deletions
+198
-204
Documentation/Changes
Documentation/Changes
+1
-1
Documentation/DocBook/writing_usb_driver.tmpl
Documentation/DocBook/writing_usb_driver.tmpl
+1
-2
Documentation/driver-model/driver.txt
Documentation/driver-model/driver.txt
+6
-62
Documentation/driver-model/porting.txt
Documentation/driver-model/porting.txt
+1
-1
arch/arm/common/locomo.c
arch/arm/common/locomo.c
+2
-8
arch/arm/common/sa1111.c
arch/arm/common/sa1111.c
+2
-9
arch/arm/common/scoop.c
arch/arm/common/scoop.c
+11
-13
arch/arm/mach-pxa/corgi_ssp.c
arch/arm/mach-pxa/corgi_ssp.c
+11
-13
arch/arm/mach-sa1100/neponset.c
arch/arm/mach-sa1100/neponset.c
+12
-18
arch/i386/kernel/cpuid.c
arch/i386/kernel/cpuid.c
+1
-1
arch/i386/kernel/msr.c
arch/i386/kernel/msr.c
+1
-1
drivers/base/attribute_container.c
drivers/base/attribute_container.c
+2
-0
drivers/base/base.h
drivers/base/base.h
+12
-0
drivers/base/class.c
drivers/base/class.c
+100
-50
drivers/base/core.c
drivers/base/core.c
+19
-2
drivers/base/cpu.c
drivers/base/cpu.c
+1
-0
drivers/base/driver.c
drivers/base/driver.c
+2
-1
drivers/base/firmware.c
drivers/base/firmware.c
+3
-0
drivers/base/init.c
drivers/base/init.c
+2
-8
drivers/base/platform.c
drivers/base/platform.c
+8
-14
No files found.
Documentation/Changes
View file @
84860bf0
...
...
@@ -65,7 +65,7 @@ o isdn4k-utils 3.1pre1 # isdnctrl 2>&1|grep version
o nfs-utils 1.0.5 # showmount --version
o procps 3.2.0 # ps --version
o oprofile 0.9 # oprofiled --version
o udev 0
58
# udevinfo -V
o udev 0
71
# udevinfo -V
Kernel compilation
==================
...
...
This diff is collapsed.
Click to expand it.
Documentation/DocBook/writing_usb_driver.tmpl
View file @
84860bf0
...
...
@@ -345,8 +345,7 @@ if (!retval) {
<programlisting>
static inline void skel_delete (struct usb_skel *dev)
{
if (dev->bulk_in_buffer != NULL)
kfree (dev->bulk_in_buffer);
kfree (dev->bulk_in_buffer);
if (dev->bulk_out_buffer != NULL)
usb_buffer_free (dev->udev, dev->bulk_out_size,
dev->bulk_out_buffer,
...
...
This diff is collapsed.
Click to expand it.
Documentation/driver-model/driver.txt
View file @
84860bf0
...
...
@@ -14,8 +14,8 @@ struct device_driver {
int (*probe) (struct device * dev);
int (*remove) (struct device * dev);
int (*suspend) (struct device * dev, pm_message_t state
, u32 level
);
int (*resume) (struct device * dev
, u32 level
);
int (*suspend) (struct device * dev, pm_message_t state);
int (*resume) (struct device * dev);
};
...
...
@@ -194,69 +194,13 @@ device; i.e. anything in the device's driver_data field.
If the device is still present, it should quiesce the device and place
it into a supported low-power state.
int (*suspend) (struct device * dev, pm_message_t state
, u32 level
);
int (*suspend) (struct device * dev, pm_message_t state);
suspend is called to put the device in a low power state. There are
several stages to successfully suspending a device, which is denoted in
the @level parameter. Breaking the suspend transition into several
stages affords the platform flexibility in performing device power
management based on the requirements of the system and the
user-defined policy.
suspend is called to put the device in a low power state.
SUSPEND_NOTIFY notifies the device that a suspend transition is about
to happen. This happens on system power state transitions to verify
that all devices can successfully suspend.
int (*resume) (struct device * dev);
A driver may choose to fail on this call, which should cause the
entire suspend transition to fail. A driver should fail only if it
knows that the device will not be able to be resumed properly when the
system wakes up again. It could also fail if it somehow determines it
is in the middle of an operation too important to stop.
SUSPEND_DISABLE tells the device to stop I/O transactions. When it
stops transactions, or what it should do with unfinished transactions
is a policy of the driver. After this call, the driver should not
accept any other I/O requests.
SUSPEND_SAVE_STATE tells the device to save the context of the
hardware. This includes any bus-specific hardware state and
device-specific hardware state. A pointer to this saved state can be
stored in the device's saved_state field.
SUSPEND_POWER_DOWN tells the driver to place the device in the low
power state requested.
Whether suspend is called with a given level is a policy of the
platform. Some levels may be omitted; drivers must not assume the
reception of any level. However, all levels must be called in the
order above; i.e. notification will always come before disabling;
disabling the device will come before suspending the device.
All calls are made with interrupts enabled, except for the
SUSPEND_POWER_DOWN level.
int (*resume) (struct device * dev, u32 level);
Resume is used to bring a device back from a low power state. Like the
suspend transition, it happens in several stages.
RESUME_POWER_ON tells the driver to set the power state to the state
before the suspend call (The device could have already been in a low
power state before the suspend call to put in a lower power state).
RESUME_RESTORE_STATE tells the driver to restore the state saved by
the SUSPEND_SAVE_STATE suspend call.
RESUME_ENABLE tells the driver to start accepting I/O transactions
again. Depending on driver policy, the device may already have pending
I/O requests.
RESUME_POWER_ON is called with interrupts disabled. The other resume
levels are called with interrupts enabled.
As with the various suspend stages, the driver must not assume that
any other resume calls have been or will be made. Each call should be
self-contained and not dependent on any external state.
Resume is used to bring a device back from a low power state.
Attributes
...
...
This diff is collapsed.
Click to expand it.
Documentation/driver-model/porting.txt
View file @
84860bf0
...
...
@@ -350,7 +350,7 @@ When a driver is registered, the bus's list of devices is iterated
over. bus->match() is called for each device that is not already
claimed by a driver.
When a device is successfully bound to a d
evice
, device->driver is
When a device is successfully bound to a d
river
, device->driver is
set, the device is added to a per-driver list of devices, and a
symlink is created in the driver's sysfs directory that points to the
device's physical directory:
...
...
This diff is collapsed.
Click to expand it.
arch/arm/common/locomo.c
View file @
84860bf0
...
...
@@ -550,15 +550,12 @@ struct locomo_save_data {
u16
LCM_SPIMD
;
};
static
int
locomo_suspend
(
struct
device
*
dev
,
pm_message_t
state
,
u32
level
)
static
int
locomo_suspend
(
struct
device
*
dev
,
pm_message_t
state
)
{
struct
locomo
*
lchip
=
dev_get_drvdata
(
dev
);
struct
locomo_save_data
*
save
;
unsigned
long
flags
;
if
(
level
!=
SUSPEND_DISABLE
)
return
0
;
save
=
kmalloc
(
sizeof
(
struct
locomo_save_data
),
GFP_KERNEL
);
if
(
!
save
)
return
-
ENOMEM
;
...
...
@@ -597,16 +594,13 @@ static int locomo_suspend(struct device *dev, pm_message_t state, u32 level)
return
0
;
}
static
int
locomo_resume
(
struct
device
*
dev
,
u32
level
)
static
int
locomo_resume
(
struct
device
*
dev
)
{
struct
locomo
*
lchip
=
dev_get_drvdata
(
dev
);
struct
locomo_save_data
*
save
;
unsigned
long
r
;
unsigned
long
flags
;
if
(
level
!=
RESUME_ENABLE
)
return
0
;
save
=
(
struct
locomo_save_data
*
)
dev
->
power
.
saved_state
;
if
(
!
save
)
return
0
;
...
...
This diff is collapsed.
Click to expand it.
arch/arm/common/sa1111.c
View file @
84860bf0
...
...
@@ -801,7 +801,7 @@ struct sa1111_save_data {
#ifdef CONFIG_PM
static
int
sa1111_suspend
(
struct
device
*
dev
,
pm_message_t
state
,
u32
level
)
static
int
sa1111_suspend
(
struct
device
*
dev
,
pm_message_t
state
)
{
struct
sa1111
*
sachip
=
dev_get_drvdata
(
dev
);
struct
sa1111_save_data
*
save
;
...
...
@@ -809,9 +809,6 @@ static int sa1111_suspend(struct device *dev, pm_message_t state, u32 level)
unsigned
int
val
;
void
__iomem
*
base
;
if
(
level
!=
SUSPEND_DISABLE
)
return
0
;
save
=
kmalloc
(
sizeof
(
struct
sa1111_save_data
),
GFP_KERNEL
);
if
(
!
save
)
return
-
ENOMEM
;
...
...
@@ -856,23 +853,19 @@ static int sa1111_suspend(struct device *dev, pm_message_t state, u32 level)
/*
* sa1111_resume - Restore the SA1111 device state.
* @dev: device to restore
* @level: resume level
*
* Restore the general state of the SA1111; clock control and
* interrupt controller. Other parts of the SA1111 must be
* restored by their respective drivers, and must be called
* via LDM after this function.
*/
static
int
sa1111_resume
(
struct
device
*
dev
,
u32
level
)
static
int
sa1111_resume
(
struct
device
*
dev
)
{
struct
sa1111
*
sachip
=
dev_get_drvdata
(
dev
);
struct
sa1111_save_data
*
save
;
unsigned
long
flags
,
id
;
void
__iomem
*
base
;
if
(
level
!=
RESUME_ENABLE
)
return
0
;
save
=
(
struct
sa1111_save_data
*
)
dev
->
power
.
saved_state
;
if
(
!
save
)
return
0
;
...
...
This diff is collapsed.
Click to expand it.
arch/arm/common/scoop.c
View file @
84860bf0
...
...
@@ -102,26 +102,24 @@ static void check_scoop_reg(struct scoop_dev *sdev)
}
#ifdef CONFIG_PM
static
int
scoop_suspend
(
struct
device
*
dev
,
pm_message_t
state
,
uint32_t
level
)
static
int
scoop_suspend
(
struct
device
*
dev
,
pm_message_t
state
)
{
if
(
level
==
SUSPEND_POWER_DOWN
)
{
struct
scoop_dev
*
sdev
=
dev_get_drvdata
(
dev
);
struct
scoop_dev
*
sdev
=
dev_get_drvdata
(
dev
);
check_scoop_reg
(
sdev
);
sdev
->
scoop_gpwr
=
SCOOP_REG
(
sdev
->
base
,
SCOOP_GPWR
);
SCOOP_REG
(
sdev
->
base
,
SCOOP_GPWR
)
=
(
sdev
->
scoop_gpwr
&
~
sdev
->
suspend_clr
)
|
sdev
->
suspend_set
;
check_scoop_reg
(
sdev
);
sdev
->
scoop_gpwr
=
SCOOP_REG
(
sdev
->
base
,
SCOOP_GPWR
);
SCOOP_REG
(
sdev
->
base
,
SCOOP_GPWR
)
=
(
sdev
->
scoop_gpwr
&
~
sdev
->
suspend_clr
)
|
sdev
->
suspend_set
;
}
return
0
;
}
static
int
scoop_resume
(
struct
device
*
dev
,
uint32_t
level
)
static
int
scoop_resume
(
struct
device
*
dev
)
{
if
(
level
==
RESUME_POWER_ON
)
{
struct
scoop_dev
*
sdev
=
dev_get_drvdata
(
dev
);
struct
scoop_dev
*
sdev
=
dev_get_drvdata
(
dev
);
check_scoop_reg
(
sdev
);
SCOOP_REG
(
sdev
->
base
,
SCOOP_GPWR
)
=
sdev
->
scoop_gpwr
;
check_scoop_reg
(
sdev
);
SCOOP_REG
(
sdev
->
base
,
SCOOP_GPWR
)
=
sdev
->
scoop_gpwr
;
}
return
0
;
}
#else
...
...
This diff is collapsed.
Click to expand it.
arch/arm/mach-pxa/corgi_ssp.c
View file @
84860bf0
...
...
@@ -222,24 +222,22 @@ static int corgi_ssp_remove(struct device *dev)
return
0
;
}
static
int
corgi_ssp_suspend
(
struct
device
*
dev
,
pm_message_t
state
,
u32
level
)
static
int
corgi_ssp_suspend
(
struct
device
*
dev
,
pm_message_t
state
)
{
if
(
level
==
SUSPEND_POWER_DOWN
)
{
ssp_flush
(
&
corgi_ssp_dev
);
ssp_save_state
(
&
corgi_ssp_dev
,
&
corgi_ssp_state
);
}
ssp_flush
(
&
corgi_ssp_dev
);
ssp_save_state
(
&
corgi_ssp_dev
,
&
corgi_ssp_state
);
return
0
;
}
static
int
corgi_ssp_resume
(
struct
device
*
dev
,
u32
level
)
static
int
corgi_ssp_resume
(
struct
device
*
dev
)
{
if
(
level
==
RESUME_POWER_ON
)
{
GPSR
(
ssp_machinfo
->
cs_lcdcon
)
=
GPIO_bit
(
ssp_machinfo
->
cs_lcdcon
);
/* High - Disable LCD Control/Timing Gen */
GPSR
(
ssp_machinfo
->
cs_max1111
)
=
GPIO_bit
(
ssp_machinfo
->
cs_max1111
);
/* High - Disable MAX1111*/
GPSR
(
ssp_machinfo
->
cs_ads7846
)
=
GPIO_bit
(
ssp_machinfo
->
cs_ads7846
);
/* High - Disable ADS7846*/
ssp_restore_state
(
&
corgi_ssp_dev
,
&
corgi_ssp_state
);
ssp_enable
(
&
corgi_ssp_dev
);
}
GPSR
(
ssp_machinfo
->
cs_lcdcon
)
=
GPIO_bit
(
ssp_machinfo
->
cs_lcdcon
);
/* High - Disable LCD Control/Timing Gen */
GPSR
(
ssp_machinfo
->
cs_max1111
)
=
GPIO_bit
(
ssp_machinfo
->
cs_max1111
);
/* High - Disable MAX1111*/
GPSR
(
ssp_machinfo
->
cs_ads7846
)
=
GPIO_bit
(
ssp_machinfo
->
cs_ads7846
);
/* High - Disable ADS7846*/
ssp_restore_state
(
&
corgi_ssp_dev
,
&
corgi_ssp_state
);
ssp_enable
(
&
corgi_ssp_dev
);
return
0
;
}
...
...
This diff is collapsed.
Click to expand it.
arch/arm/mach-sa1100/neponset.c
View file @
84860bf0
...
...
@@ -178,33 +178,27 @@ static int neponset_probe(struct device *dev)
/*
* LDM power management.
*/
static
int
neponset_suspend
(
struct
device
*
dev
,
pm_message_t
state
,
u32
level
)
static
int
neponset_suspend
(
struct
device
*
dev
,
pm_message_t
state
)
{
/*
* Save state.
*/
if
(
level
==
SUSPEND_SAVE_STATE
||
level
==
SUSPEND_DISABLE
||
level
==
SUSPEND_POWER_DOWN
)
{
if
(
!
dev
->
power
.
saved_state
)
dev
->
power
.
saved_state
=
kmalloc
(
sizeof
(
unsigned
int
),
GFP_KERNEL
);
if
(
!
dev
->
power
.
saved_state
)
return
-
ENOMEM
;
*
(
unsigned
int
*
)
dev
->
power
.
saved_state
=
NCR_0
;
}
if
(
!
dev
->
power
.
saved_state
)
dev
->
power
.
saved_state
=
kmalloc
(
sizeof
(
unsigned
int
),
GFP_KERNEL
);
if
(
!
dev
->
power
.
saved_state
)
return
-
ENOMEM
;
*
(
unsigned
int
*
)
dev
->
power
.
saved_state
=
NCR_0
;
return
0
;
}
static
int
neponset_resume
(
struct
device
*
dev
,
u32
level
)
static
int
neponset_resume
(
struct
device
*
dev
)
{
if
(
level
==
RESUME_RESTORE_STATE
||
level
==
RESUME_ENABLE
)
{
if
(
dev
->
power
.
saved_state
)
{
NCR_0
=
*
(
unsigned
int
*
)
dev
->
power
.
saved_state
;
kfree
(
dev
->
power
.
saved_state
);
dev
->
power
.
saved_state
=
NULL
;
}
if
(
dev
->
power
.
saved_state
)
{
NCR_0
=
*
(
unsigned
int
*
)
dev
->
power
.
saved_state
;
kfree
(
dev
->
power
.
saved_state
);
dev
->
power
.
saved_state
=
NULL
;
}
return
0
;
...
...
This diff is collapsed.
Click to expand it.
arch/i386/kernel/cpuid.c
View file @
84860bf0
...
...
@@ -163,7 +163,7 @@ static int cpuid_class_device_create(int i)
int
err
=
0
;
struct
class_device
*
class_err
;
class_err
=
class_device_create
(
cpuid_class
,
MKDEV
(
CPUID_MAJOR
,
i
),
NULL
,
"cpu%d"
,
i
);
class_err
=
class_device_create
(
cpuid_class
,
NULL
,
MKDEV
(
CPUID_MAJOR
,
i
),
NULL
,
"cpu%d"
,
i
);
if
(
IS_ERR
(
class_err
))
err
=
PTR_ERR
(
class_err
);
return
err
;
...
...
This diff is collapsed.
Click to expand it.
arch/i386/kernel/msr.c
View file @
84860bf0
...
...
@@ -246,7 +246,7 @@ static int msr_class_device_create(int i)
int
err
=
0
;
struct
class_device
*
class_err
;
class_err
=
class_device_create
(
msr_class
,
MKDEV
(
MSR_MAJOR
,
i
),
NULL
,
"msr%d"
,
i
);
class_err
=
class_device_create
(
msr_class
,
NULL
,
MKDEV
(
MSR_MAJOR
,
i
),
NULL
,
"msr%d"
,
i
);
if
(
IS_ERR
(
class_err
))
err
=
PTR_ERR
(
class_err
);
return
err
;
...
...
This diff is collapsed.
Click to expand it.
drivers/base/attribute_container.c
View file @
84860bf0
...
...
@@ -19,6 +19,8 @@
#include <linux/list.h>
#include <linux/module.h>
#include "base.h"
/* This is a private structure used to tie the classdev and the
* container .. it should never be visible outside this file */
struct
internal_container
{
...
...
This diff is collapsed.
Click to expand it.
drivers/base/base.h
View file @
84860bf0
/* initialisation functions */
extern
int
devices_init
(
void
);
extern
int
buses_init
(
void
);
extern
int
classes_init
(
void
);
extern
int
firmware_init
(
void
);
extern
int
platform_bus_init
(
void
);
extern
int
system_bus_init
(
void
);
extern
int
cpu_dev_init
(
void
);
extern
int
attribute_container_init
(
void
);
extern
int
bus_add_device
(
struct
device
*
dev
);
extern
void
bus_remove_device
(
struct
device
*
dev
);
...
...
This diff is collapsed.
Click to expand it.
drivers/base/class.c
View file @
84860bf0
...
...
@@ -99,7 +99,8 @@ struct class * class_get(struct class * cls)
void
class_put
(
struct
class
*
cls
)
{
subsys_put
(
&
cls
->
subsys
);
if
(
cls
)
subsys_put
(
&
cls
->
subsys
);
}
...
...
@@ -165,14 +166,25 @@ void class_unregister(struct class * cls)
static
void
class_create_release
(
struct
class
*
cls
)
{
pr_debug
(
"%s called for %s
\n
"
,
__FUNCTION__
,
cls
->
name
);
kfree
(
cls
);
}
static
void
class_device_create_release
(
struct
class_device
*
class_dev
)
{
pr_debug
(
"%s called for %s
\n
"
,
__FUNCTION__
,
class_dev
->
class_id
);
kfree
(
class_dev
);
}
/* needed to allow these devices to have parent class devices */
static
int
class_device_create_hotplug
(
struct
class_device
*
class_dev
,
char
**
envp
,
int
num_envp
,
char
*
buffer
,
int
buffer_size
)
{
pr_debug
(
"%s called for %s
\n
"
,
__FUNCTION__
,
class_dev
->
class_id
);
return
0
;
}
/**
* class_create - create a struct class structure
* @owner: pointer to the module that is to "own" this struct class
...
...
@@ -301,10 +313,12 @@ static void class_dev_release(struct kobject * kobj)
kfree
(
cd
->
devt_attr
);
cd
->
devt_attr
=
NULL
;
if
(
cls
->
release
)
if
(
cd
->
release
)
cd
->
release
(
cd
);
else
if
(
cls
->
release
)
cls
->
release
(
cd
);
else
{
printk
(
KERN_ERR
"Device
class
'%s' does not have a release() function, "
printk
(
KERN_ERR
"
Class
Device '%s' does not have a release() function, "
"it is broken and must be fixed.
\n
"
,
cd
->
class_id
);
WARN_ON
(
1
);
...
...
@@ -382,14 +396,18 @@ static int class_hotplug(struct kset *kset, struct kobject *kobj, char **envp,
buffer
=
&
buffer
[
length
];
buffer_size
-=
length
;
if
(
class_dev
->
class
->
hotplug
)
{
/* have the bus specific function add its stuff */
retval
=
class_dev
->
class
->
hotplug
(
class_dev
,
envp
,
num_envp
,
buffer
,
buffer_size
);
if
(
retval
)
{
pr_debug
(
"%s - hotplug() returned %d
\n
"
,
__FUNCTION__
,
retval
);
}
if
(
class_dev
->
hotplug
)
{
/* have the class device specific function add its stuff */
retval
=
class_dev
->
hotplug
(
class_dev
,
envp
,
num_envp
,
buffer
,
buffer_size
);
if
(
retval
)
pr_debug
(
"class_dev->hotplug() returned %d
\n
"
,
retval
);
}
else
if
(
class_dev
->
class
->
hotplug
)
{
/* have the class specific function add its stuff */
retval
=
class_dev
->
class
->
hotplug
(
class_dev
,
envp
,
num_envp
,
buffer
,
buffer_size
);
if
(
retval
)
pr_debug
(
"class->hotplug() returned %d
\n
"
,
retval
);
}
return
retval
;
...
...
@@ -442,6 +460,13 @@ static ssize_t show_dev(struct class_device *class_dev, char *buf)
return
print_dev_t
(
buf
,
class_dev
->
devt
);
}
static
ssize_t
store_uevent
(
struct
class_device
*
class_dev
,
const
char
*
buf
,
size_t
count
)
{
kobject_hotplug
(
&
class_dev
->
kobj
,
KOBJ_ADD
);
return
count
;
}
void
class_device_initialize
(
struct
class_device
*
class_dev
)
{
kobj_set_kset_s
(
class_dev
,
class_obj_subsys
);
...
...
@@ -469,34 +494,45 @@ static char *make_class_name(struct class_device *class_dev)
int
class_device_add
(
struct
class_device
*
class_dev
)
{
struct
class
*
parent
=
NULL
;
struct
class_interface
*
class_intf
;
struct
class
*
parent_class
=
NULL
;
struct
class_device
*
parent_class_dev
=
NULL
;
struct
class_interface
*
class_intf
;
char
*
class_name
=
NULL
;
int
error
;
int
error
=
-
EINVAL
;
class_dev
=
class_device_get
(
class_dev
);
if
(
!
class_dev
)
return
-
EINVAL
;
if
(
!
strlen
(
class_dev
->
class_id
))
{
error
=
-
EINVAL
;
if
(
!
strlen
(
class_dev
->
class_id
))
goto
register_done
;
}
parent
=
class_get
(
class_dev
->
class
);
parent_class
=
class_get
(
class_dev
->
class
);
if
(
!
parent_class
)
goto
register_done
;
parent_class_dev
=
class_device_get
(
class_dev
->
parent
);
pr_debug
(
"CLASS: registering class device: ID = '%s'
\n
"
,
class_dev
->
class_id
);
/* first, register with generic layer. */
kobject_set_name
(
&
class_dev
->
kobj
,
"%s"
,
class_dev
->
class_id
);
if
(
parent
)
class_dev
->
kobj
.
parent
=
&
parent
->
subsys
.
kset
.
kobj
;
if
(
parent_class_dev
)
class_dev
->
kobj
.
parent
=
&
parent_class_dev
->
kobj
;
else
class_dev
->
kobj
.
parent
=
&
parent_class
->
subsys
.
kset
.
kobj
;
if
((
error
=
kobject_add
(
&
class_dev
->
kobj
)))
error
=
kobject_add
(
&
class_dev
->
kobj
);
if
(
error
)
goto
register_done
;
/* add the needed attributes to this device */
class_dev
->
uevent_attr
.
attr
.
name
=
"uevent"
;
class_dev
->
uevent_attr
.
attr
.
mode
=
S_IWUSR
;
class_dev
->
uevent_attr
.
attr
.
owner
=
parent_class
->
owner
;
class_dev
->
uevent_attr
.
store
=
store_uevent
;
class_device_create_file
(
class_dev
,
&
class_dev
->
uevent_attr
);
if
(
MAJOR
(
class_dev
->
devt
))
{
struct
class_device_attribute
*
attr
;
attr
=
kzalloc
(
sizeof
(
*
attr
),
GFP_KERNEL
);
...
...
@@ -505,12 +541,10 @@ int class_device_add(struct class_device *class_dev)
kobject_del
(
&
class_dev
->
kobj
);
goto
register_done
;
}
attr
->
attr
.
name
=
"dev"
;
attr
->
attr
.
mode
=
S_IRUGO
;
attr
->
attr
.
owner
=
parent
->
owner
;
attr
->
attr
.
owner
=
parent
_class
->
owner
;
attr
->
show
=
show_dev
;
attr
->
store
=
NULL
;
class_device_create_file
(
class_dev
,
attr
);
class_dev
->
devt_attr
=
attr
;
}
...
...
@@ -524,20 +558,23 @@ int class_device_add(struct class_device *class_dev)
class_name
);
}
kobject_hotplug
(
&
class_dev
->
kobj
,
KOBJ_ADD
);
/* notify any interfaces this device is now here */
if
(
parent
)
{
down
(
&
parent
->
sem
);
list_add_tail
(
&
class_dev
->
node
,
&
parent
->
children
);
list_for_each_entry
(
class_intf
,
&
parent
->
interfaces
,
node
)
if
(
parent
_class
)
{
down
(
&
parent
_class
->
sem
);
list_add_tail
(
&
class_dev
->
node
,
&
parent
_class
->
children
);
list_for_each_entry
(
class_intf
,
&
parent
_class
->
interfaces
,
node
)
if
(
class_intf
->
add
)
class_intf
->
add
(
class_dev
);
up
(
&
parent
->
sem
);
class_intf
->
add
(
class_dev
,
class_intf
);
up
(
&
parent
_class
->
sem
);
}
kobject_hotplug
(
&
class_dev
->
kobj
,
KOBJ_ADD
);
register_done:
if
(
error
&&
parent
)
class_put
(
parent
);
if
(
error
)
{
class_put
(
parent_class
);
class_device_put
(
parent_class_dev
);
}
class_device_put
(
class_dev
);
kfree
(
class_name
);
return
error
;
...
...
@@ -552,21 +589,28 @@ int class_device_register(struct class_device *class_dev)
/**
* class_device_create - creates a class device and registers it with sysfs
* @cs: pointer to the struct class that this device should be registered to.
* @parent: pointer to the parent struct class_device of this new device, if any.
* @dev: the dev_t for the char device to be added.
* @device: a pointer to a struct device that is assiociated with this class device.
* @fmt: string for the class device's name
*
* This function can be used by char device classes. A struct
* class_device will be created in sysfs, registered to the specified
* class. A "dev" file will be created, showing the dev_t for the
* device. The pointer to the struct class_device will be returned from
* the call. Any further sysfs files that might be required can be
* created using this pointer.
* class.
* A "dev" file will be created, showing the dev_t for the device, if
* the dev_t is not 0,0.
* If a pointer to a parent struct class_device is passed in, the newly
* created struct class_device will be a child of that device in sysfs.
* The pointer to the struct class_device will be returned from the
* call. Any further sysfs files that might be required can be created
* using this pointer.
*
* Note: the struct class passed to this function must have previously
* been created with a call to class_create().
*/
struct
class_device
*
class_device_create
(
struct
class
*
cls
,
dev_t
devt
,
struct
class_device
*
class_device_create
(
struct
class
*
cls
,
struct
class_device
*
parent
,
dev_t
devt
,
struct
device
*
device
,
char
*
fmt
,
...)
{
va_list
args
;
...
...
@@ -585,6 +629,9 @@ struct class_device *class_device_create(struct class *cls, dev_t devt,
class_dev
->
devt
=
devt
;
class_dev
->
dev
=
device
;
class_dev
->
class
=
cls
;
class_dev
->
parent
=
parent
;
class_dev
->
release
=
class_device_create_release
;
class_dev
->
hotplug
=
class_device_create_hotplug
;
va_start
(
args
,
fmt
);
vsnprintf
(
class_dev
->
class_id
,
BUS_ID_SIZE
,
fmt
,
args
);
...
...
@@ -602,17 +649,18 @@ struct class_device *class_device_create(struct class *cls, dev_t devt,
void
class_device_del
(
struct
class_device
*
class_dev
)
{
struct
class
*
parent
=
class_dev
->
class
;
struct
class_interface
*
class_intf
;
struct
class
*
parent_class
=
class_dev
->
class
;
struct
class_device
*
parent_device
=
class_dev
->
parent
;
struct
class_interface
*
class_intf
;
char
*
class_name
=
NULL
;
if
(
parent
)
{
down
(
&
parent
->
sem
);
if
(
parent
_class
)
{
down
(
&
parent
_class
->
sem
);
list_del_init
(
&
class_dev
->
node
);
list_for_each_entry
(
class_intf
,
&
parent
->
interfaces
,
node
)
list_for_each_entry
(
class_intf
,
&
parent
_class
->
interfaces
,
node
)
if
(
class_intf
->
remove
)
class_intf
->
remove
(
class_dev
);
up
(
&
parent
->
sem
);
class_intf
->
remove
(
class_dev
,
class_intf
);
up
(
&
parent
_class
->
sem
);
}
if
(
class_dev
->
dev
)
{
...
...
@@ -620,6 +668,7 @@ void class_device_del(struct class_device *class_dev)
sysfs_remove_link
(
&
class_dev
->
kobj
,
"device"
);
sysfs_remove_link
(
&
class_dev
->
dev
->
kobj
,
class_name
);
}
class_device_remove_file
(
class_dev
,
&
class_dev
->
uevent_attr
);
if
(
class_dev
->
devt_attr
)
class_device_remove_file
(
class_dev
,
class_dev
->
devt_attr
);
class_device_remove_attrs
(
class_dev
);
...
...
@@ -627,8 +676,8 @@ void class_device_del(struct class_device *class_dev)
kobject_hotplug
(
&
class_dev
->
kobj
,
KOBJ_REMOVE
);
kobject_del
(
&
class_dev
->
kobj
);
if
(
parent
)
class_put
(
parent
);
class_device_put
(
parent_device
);
class_put
(
parent
_class
);
kfree
(
class_name
);
}
...
...
@@ -708,7 +757,8 @@ struct class_device * class_device_get(struct class_device *class_dev)
void
class_device_put
(
struct
class_device
*
class_dev
)
{
kobject_put
(
&
class_dev
->
kobj
);
if
(
class_dev
)
kobject_put
(
&
class_dev
->
kobj
);
}
...
...
@@ -728,7 +778,7 @@ int class_interface_register(struct class_interface *class_intf)
list_add_tail
(
&
class_intf
->
node
,
&
parent
->
interfaces
);
if
(
class_intf
->
add
)
{
list_for_each_entry
(
class_dev
,
&
parent
->
children
,
node
)
class_intf
->
add
(
class_dev
);
class_intf
->
add
(
class_dev
,
class_intf
);
}
up
(
&
parent
->
sem
);
...
...
@@ -747,7 +797,7 @@ void class_interface_unregister(struct class_interface *class_intf)
list_del_init
(
&
class_intf
->
node
);
if
(
class_intf
->
remove
)
{
list_for_each_entry
(
class_dev
,
&
parent
->
children
,
node
)
class_intf
->
remove
(
class_dev
);
class_intf
->
remove
(
class_dev
,
class_intf
);
}
up
(
&
parent
->
sem
);
...
...
This diff is collapsed.
Click to expand it.
drivers/base/core.c
View file @
84860bf0
...
...
@@ -154,6 +154,13 @@ static struct kset_hotplug_ops device_hotplug_ops = {
.
hotplug
=
dev_hotplug
,
};
static
ssize_t
store_uevent
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
const
char
*
buf
,
size_t
count
)
{
kobject_hotplug
(
&
dev
->
kobj
,
KOBJ_ADD
);
return
count
;
}
/**
* device_subsys - structure to be registered with kobject core.
*/
...
...
@@ -225,6 +232,7 @@ void device_initialize(struct device *dev)
klist_children_put
);
INIT_LIST_HEAD
(
&
dev
->
dma_pools
);
init_MUTEX
(
&
dev
->
sem
);
device_init_wakeup
(
dev
,
0
);
}
/**
...
...
@@ -258,6 +266,14 @@ int device_add(struct device *dev)
if
((
error
=
kobject_add
(
&
dev
->
kobj
)))
goto
Error
;
dev
->
uevent_attr
.
attr
.
name
=
"uevent"
;
dev
->
uevent_attr
.
attr
.
mode
=
S_IWUSR
;
if
(
dev
->
driver
)
dev
->
uevent_attr
.
attr
.
owner
=
dev
->
driver
->
owner
;
dev
->
uevent_attr
.
store
=
store_uevent
;
device_create_file
(
dev
,
&
dev
->
uevent_attr
);
kobject_hotplug
(
&
dev
->
kobj
,
KOBJ_ADD
);
if
((
error
=
device_pm_add
(
dev
)))
goto
PMError
;
...
...
@@ -349,6 +365,7 @@ void device_del(struct device * dev)
if
(
parent
)
klist_del
(
&
dev
->
knode_parent
);
device_remove_file
(
dev
,
&
dev
->
uevent_attr
);
/* Notify the platform of the removal, in case they
* need to do anything...
...
...
@@ -390,11 +407,11 @@ static struct device * next_device(struct klist_iter * i)
/**
* device_for_each_child - device child iterator.
* @
dev:
parent struct device.
* @
parent:
parent struct device.
* @data: data for the callback.
* @fn: function to be called for each device.
*
* Iterate over @
dev
's child devices, and call @fn for each,
* Iterate over @
parent
's child devices, and call @fn for each,
* passing it @data.
*
* We check the return of @fn each time. If it returns anything
...
...
This diff is collapsed.
Click to expand it.
drivers/base/cpu.c
View file @
84860bf0
...
...
@@ -9,6 +9,7 @@
#include <linux/topology.h>
#include <linux/device.h>
#include "base.h"
struct
sysdev_class
cpu_sysdev_class
=
{
set_kset_name
(
"cpu"
),
...
...
This diff is collapsed.
Click to expand it.
drivers/base/driver.c
View file @
84860bf0
...
...
@@ -28,6 +28,7 @@ static struct device * next_device(struct klist_iter * i)
/**
* driver_for_each_device - Iterator for devices bound to a driver.
* @drv: Driver we're iterating.
* @start: Device to begin with
* @data: Data to pass to the callback.
* @fn: Function to call for each device.
*
...
...
@@ -57,7 +58,7 @@ EXPORT_SYMBOL_GPL(driver_for_each_device);
/**
* driver_find_device - device iterator for locating a particular device.
* @dr
iver
: The device's driver
* @dr
v
: The device's driver
* @start: Device to begin with
* @data: Data to pass to match function
* @match: Callback function to check device
...
...
This diff is collapsed.
Click to expand it.
drivers/base/firmware.c
View file @
84860bf0
...
...
@@ -11,6 +11,9 @@
#include <linux/kobject.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/device.h>
#include "base.h"
static
decl_subsys
(
firmware
,
NULL
,
NULL
);
...
...
This diff is collapsed.
Click to expand it.
drivers/base/init.c
View file @
84860bf0
...
...
@@ -10,14 +10,8 @@
#include <linux/device.h>
#include <linux/init.h>
extern
int
devices_init
(
void
);
extern
int
buses_init
(
void
);
extern
int
classes_init
(
void
);
extern
int
firmware_init
(
void
);
extern
int
platform_bus_init
(
void
);
extern
int
system_bus_init
(
void
);
extern
int
cpu_dev_init
(
void
);
extern
int
attribute_container_init
(
void
);
#include "base.h"
/**
* driver_init - initialize driver model.
*
...
...
This diff is collapsed.
Click to expand it.
drivers/base/platform.c
View file @
84860bf0
...
...
@@ -17,6 +17,8 @@
#include <linux/bootmem.h>
#include <linux/err.h>
#include "base.h"
struct
device
platform_bus
=
{
.
bus_id
=
"platform"
,
};
...
...
@@ -279,13 +281,9 @@ static int platform_suspend(struct device * dev, pm_message_t state)
{
int
ret
=
0
;
if
(
dev
->
driver
&&
dev
->
driver
->
suspend
)
{
ret
=
dev
->
driver
->
suspend
(
dev
,
state
,
SUSPEND_DISABLE
);
if
(
ret
==
0
)
ret
=
dev
->
driver
->
suspend
(
dev
,
state
,
SUSPEND_SAVE_STATE
);
if
(
ret
==
0
)
ret
=
dev
->
driver
->
suspend
(
dev
,
state
,
SUSPEND_POWER_DOWN
);
}
if
(
dev
->
driver
&&
dev
->
driver
->
suspend
)
ret
=
dev
->
driver
->
suspend
(
dev
,
state
);
return
ret
;
}
...
...
@@ -293,13 +291,9 @@ static int platform_resume(struct device * dev)
{
int
ret
=
0
;
if
(
dev
->
driver
&&
dev
->
driver
->
resume
)
{
ret
=
dev
->
driver
->
resume
(
dev
,
RESUME_POWER_ON
);
if
(
ret
==
0
)
ret
=
dev
->
driver
->
resume
(
dev
,
RESUME_RESTORE_STATE
);
if
(
ret
==
0
)
ret
=
dev
->
driver
->
resume
(
dev
,
RESUME_ENABLE
);
}
if
(
dev
->
driver
&&
dev
->
driver
->
resume
)
ret
=
dev
->
driver
->
resume
(
dev
);
return
ret
;
}
...
...
This diff is collapsed.
Click to expand it.
Prev
1
2
3
4
5
…
13
Next
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