Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core-2.6: (62 commits) msi-laptop: depends on RFKILL msi-laptop: Detect 3G device exists by standard ec command msi-laptop: Add resume method for set the SCM load again msi-laptop: Support some MSI 3G netbook that is need load SCM msi-laptop: Add threeg sysfs file for support query 3G state by standard 66/62 ec command msi-laptop: Support standard ec 66/62 command on MSI notebook and nebook Driver core: create lock/unlock functions for struct device sysfs: fix for thinko with sysfs_bin_attr_init() sysfs: Kill unused sysfs_sb variable. sysfs: Pass super_block to sysfs_get_inode driver core: Use sysfs_rename_link in device_rename sysfs: Implement sysfs_rename_link sysfs: Pack sysfs_dirent more tightly. sysfs: Serialize updates to the vfs inode sysfs: windfarm: init sysfs attributes sysfs: Use sysfs_attr_init and sysfs_bin_attr_init on module dynamic attributes sysfs: Document sysfs_attr_init and sysfs_bin_attr_init sysfs: Use sysfs_attr_init and sysfs_bin_attr_init on dynamic attributes sysfs: Use one lockdep class per sysfs attribute. sysfs: Only take active references on attributes. ...
This commit is contained in:
commit
e10154189f
@ -221,8 +221,8 @@ branches. These different branches are:
|
||||
- main 2.6.x kernel tree
|
||||
- 2.6.x.y -stable kernel tree
|
||||
- 2.6.x -git kernel patches
|
||||
- 2.6.x -mm kernel patches
|
||||
- subsystem specific kernel trees and patches
|
||||
- the 2.6.x -next kernel tree for integration tests
|
||||
|
||||
2.6.x kernel tree
|
||||
-----------------
|
||||
@ -232,7 +232,7 @@ process is as follows:
|
||||
- As soon as a new kernel is released a two weeks window is open,
|
||||
during this period of time maintainers can submit big diffs to
|
||||
Linus, usually the patches that have already been included in the
|
||||
-mm kernel for a few weeks. The preferred way to submit big changes
|
||||
-next kernel for a few weeks. The preferred way to submit big changes
|
||||
is using git (the kernel's source management tool, more information
|
||||
can be found at http://git.or.cz/) but plain patches are also just
|
||||
fine.
|
||||
@ -293,84 +293,43 @@ daily and represent the current state of Linus' tree. They are more
|
||||
experimental than -rc kernels since they are generated automatically
|
||||
without even a cursory glance to see if they are sane.
|
||||
|
||||
2.6.x -mm kernel patches
|
||||
------------------------
|
||||
These are experimental kernel patches released by Andrew Morton. Andrew
|
||||
takes all of the different subsystem kernel trees and patches and mushes
|
||||
them together, along with a lot of patches that have been plucked from
|
||||
the linux-kernel mailing list. This tree serves as a proving ground for
|
||||
new features and patches. Once a patch has proved its worth in -mm for
|
||||
a while Andrew or the subsystem maintainer pushes it on to Linus for
|
||||
inclusion in mainline.
|
||||
|
||||
It is heavily encouraged that all new patches get tested in the -mm tree
|
||||
before they are sent to Linus for inclusion in the main kernel tree. Code
|
||||
which does not make an appearance in -mm before the opening of the merge
|
||||
window will prove hard to merge into the mainline.
|
||||
|
||||
These kernels are not appropriate for use on systems that are supposed
|
||||
to be stable and they are more risky to run than any of the other
|
||||
branches.
|
||||
|
||||
If you wish to help out with the kernel development process, please test
|
||||
and use these kernel releases and provide feedback to the linux-kernel
|
||||
mailing list if you have any problems, and if everything works properly.
|
||||
|
||||
In addition to all the other experimental patches, these kernels usually
|
||||
also contain any changes in the mainline -git kernels available at the
|
||||
time of release.
|
||||
|
||||
The -mm kernels are not released on a fixed schedule, but usually a few
|
||||
-mm kernels are released in between each -rc kernel (1 to 3 is common).
|
||||
|
||||
Subsystem Specific kernel trees and patches
|
||||
-------------------------------------------
|
||||
A number of the different kernel subsystem developers expose their
|
||||
development trees so that others can see what is happening in the
|
||||
different areas of the kernel. These trees are pulled into the -mm
|
||||
kernel releases as described above.
|
||||
The maintainers of the various kernel subsystems --- and also many
|
||||
kernel subsystem developers --- expose their current state of
|
||||
development in source repositories. That way, others can see what is
|
||||
happening in the different areas of the kernel. In areas where
|
||||
development is rapid, a developer may be asked to base his submissions
|
||||
onto such a subsystem kernel tree so that conflicts between the
|
||||
submission and other already ongoing work are avoided.
|
||||
|
||||
Here is a list of some of the different kernel trees available:
|
||||
git trees:
|
||||
- Kbuild development tree, Sam Ravnborg <sam@ravnborg.org>
|
||||
git.kernel.org:/pub/scm/linux/kernel/git/sam/kbuild.git
|
||||
Most of these repositories are git trees, but there are also other SCMs
|
||||
in use, or patch queues being published as quilt series. Addresses of
|
||||
these subsystem repositories are listed in the MAINTAINERS file. Many
|
||||
of them can be browsed at http://git.kernel.org/.
|
||||
|
||||
- ACPI development tree, Len Brown <len.brown@intel.com>
|
||||
git.kernel.org:/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6.git
|
||||
Before a proposed patch is committed to such a subsystem tree, it is
|
||||
subject to review which primarily happens on mailing lists (see the
|
||||
respective section below). For several kernel subsystems, this review
|
||||
process is tracked with the tool patchwork. Patchwork offers a web
|
||||
interface which shows patch postings, any comments on a patch or
|
||||
revisions to it, and maintainers can mark patches as under review,
|
||||
accepted, or rejected. Most of these patchwork sites are listed at
|
||||
http://patchwork.kernel.org/ or http://patchwork.ozlabs.org/.
|
||||
|
||||
- Block development tree, Jens Axboe <jens.axboe@oracle.com>
|
||||
git.kernel.org:/pub/scm/linux/kernel/git/axboe/linux-2.6-block.git
|
||||
2.6.x -next kernel tree for integration tests
|
||||
---------------------------------------------
|
||||
Before updates from subsystem trees are merged into the mainline 2.6.x
|
||||
tree, they need to be integration-tested. For this purpose, a special
|
||||
testing repository exists into which virtually all subsystem trees are
|
||||
pulled on an almost daily basis:
|
||||
http://git.kernel.org/?p=linux/kernel/git/sfr/linux-next.git
|
||||
http://linux.f-seidel.de/linux-next/pmwiki/
|
||||
|
||||
- DRM development tree, Dave Airlie <airlied@linux.ie>
|
||||
git.kernel.org:/pub/scm/linux/kernel/git/airlied/drm-2.6.git
|
||||
This way, the -next kernel gives a summary outlook onto what will be
|
||||
expected to go into the mainline kernel at the next merge period.
|
||||
Adventurous testers are very welcome to runtime-test the -next kernel.
|
||||
|
||||
- ia64 development tree, Tony Luck <tony.luck@intel.com>
|
||||
git.kernel.org:/pub/scm/linux/kernel/git/aegl/linux-2.6.git
|
||||
|
||||
- infiniband, Roland Dreier <rolandd@cisco.com>
|
||||
git.kernel.org:/pub/scm/linux/kernel/git/roland/infiniband.git
|
||||
|
||||
- libata, Jeff Garzik <jgarzik@pobox.com>
|
||||
git.kernel.org:/pub/scm/linux/kernel/git/jgarzik/libata-dev.git
|
||||
|
||||
- network drivers, Jeff Garzik <jgarzik@pobox.com>
|
||||
git.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git
|
||||
|
||||
- pcmcia, Dominik Brodowski <linux@dominikbrodowski.net>
|
||||
git.kernel.org:/pub/scm/linux/kernel/git/brodo/pcmcia-2.6.git
|
||||
|
||||
- SCSI, James Bottomley <James.Bottomley@hansenpartnership.com>
|
||||
git.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6.git
|
||||
|
||||
- x86, Ingo Molnar <mingo@elte.hu>
|
||||
git://git.kernel.org/pub/scm/linux/kernel/git/x86/linux-2.6-x86.git
|
||||
|
||||
quilt trees:
|
||||
- USB, Driver Core, and I2C, Greg Kroah-Hartman <gregkh@suse.de>
|
||||
kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/
|
||||
|
||||
Other kernel trees can be found listed at http://git.kernel.org/ and in
|
||||
the MAINTAINERS file.
|
||||
|
||||
Bug Reporting
|
||||
-------------
|
||||
|
@ -266,7 +266,7 @@ kobj_type:
|
||||
|
||||
struct kobj_type {
|
||||
void (*release)(struct kobject *);
|
||||
struct sysfs_ops *sysfs_ops;
|
||||
const struct sysfs_ops *sysfs_ops;
|
||||
struct attribute **default_attrs;
|
||||
};
|
||||
|
||||
|
@ -204,7 +204,7 @@ void __init corgi_ssp_set_machinfo(struct corgissp_machinfo *machinfo)
|
||||
ssp_machinfo = machinfo;
|
||||
}
|
||||
|
||||
static int __init corgi_ssp_probe(struct platform_device *dev)
|
||||
static int __devinit corgi_ssp_probe(struct platform_device *dev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
|
@ -900,7 +900,7 @@ static struct platform_suspend_ops sharpsl_pm_ops = {
|
||||
};
|
||||
#endif
|
||||
|
||||
static int __init sharpsl_pm_probe(struct platform_device *pdev)
|
||||
static int __devinit sharpsl_pm_probe(struct platform_device *pdev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
|
@ -56,7 +56,7 @@ static const struct rfkill_ops h1940bt_rfkill_ops = {
|
||||
.set_block = h1940bt_set_block,
|
||||
};
|
||||
|
||||
static int __init h1940bt_probe(struct platform_device *pdev)
|
||||
static int __devinit h1940bt_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct rfkill *rfk;
|
||||
int ret = 0;
|
||||
|
@ -130,7 +130,7 @@ void jornada_ssp_end(void)
|
||||
};
|
||||
EXPORT_SYMBOL(jornada_ssp_end);
|
||||
|
||||
static int __init jornada_ssp_probe(struct platform_device *dev)
|
||||
static int __devinit jornada_ssp_probe(struct platform_device *dev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
|
@ -282,7 +282,7 @@ static ssize_t cache_show(struct kobject * kobj, struct attribute * attr, char *
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct sysfs_ops cache_sysfs_ops = {
|
||||
static const struct sysfs_ops cache_sysfs_ops = {
|
||||
.show = cache_show
|
||||
};
|
||||
|
||||
|
@ -58,13 +58,16 @@ static ssize_t raw_store(struct sys_device *dev,
|
||||
static SYSDEV_ATTR(ascii, 0200, NULL, ascii_store);
|
||||
static SYSDEV_ATTR(raw, 0200, NULL, raw_store);
|
||||
|
||||
static ssize_t map_seg7_show(struct sysdev_class *class, char *buf)
|
||||
static ssize_t map_seg7_show(struct sysdev_class *class,
|
||||
struct sysdev_class_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
memcpy(buf, &txx9_seg7map, sizeof(txx9_seg7map));
|
||||
return sizeof(txx9_seg7map);
|
||||
}
|
||||
|
||||
static ssize_t map_seg7_store(struct sysdev_class *class,
|
||||
struct sysdev_class_attribute *attr,
|
||||
const char *buf, size_t size)
|
||||
{
|
||||
if (size != sizeof(txx9_seg7map))
|
||||
|
@ -642,7 +642,7 @@ static struct kobj_attribute *cache_index_opt_attrs[] = {
|
||||
&cache_assoc_attr,
|
||||
};
|
||||
|
||||
static struct sysfs_ops cache_index_ops = {
|
||||
static const struct sysfs_ops cache_index_ops = {
|
||||
.show = cache_index_show,
|
||||
};
|
||||
|
||||
|
@ -1020,7 +1020,9 @@ out:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static ssize_t __ref rescan_store(struct sysdev_class *class, const char *buf,
|
||||
static ssize_t __ref rescan_store(struct sysdev_class *class,
|
||||
struct sysdev_class_attribute *attr,
|
||||
const char *buf,
|
||||
size_t count)
|
||||
{
|
||||
int rc;
|
||||
@ -1031,7 +1033,9 @@ static ssize_t __ref rescan_store(struct sysdev_class *class, const char *buf,
|
||||
static SYSDEV_CLASS_ATTR(rescan, 0200, NULL, rescan_store);
|
||||
#endif /* CONFIG_HOTPLUG_CPU */
|
||||
|
||||
static ssize_t dispatching_show(struct sysdev_class *class, char *buf)
|
||||
static ssize_t dispatching_show(struct sysdev_class *class,
|
||||
struct sysdev_class_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
ssize_t count;
|
||||
|
||||
@ -1041,7 +1045,9 @@ static ssize_t dispatching_show(struct sysdev_class *class, char *buf)
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t dispatching_store(struct sysdev_class *dev, const char *buf,
|
||||
static ssize_t dispatching_store(struct sysdev_class *dev,
|
||||
struct sysdev_class_attribute *attr,
|
||||
const char *buf,
|
||||
size_t count)
|
||||
{
|
||||
int val, rc;
|
||||
|
@ -1116,14 +1116,18 @@ static struct sys_device etr_port1_dev = {
|
||||
/*
|
||||
* ETR class attributes
|
||||
*/
|
||||
static ssize_t etr_stepping_port_show(struct sysdev_class *class, char *buf)
|
||||
static ssize_t etr_stepping_port_show(struct sysdev_class *class,
|
||||
struct sysdev_class_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
return sprintf(buf, "%i\n", etr_port0.esw.p);
|
||||
}
|
||||
|
||||
static SYSDEV_CLASS_ATTR(stepping_port, 0400, etr_stepping_port_show, NULL);
|
||||
|
||||
static ssize_t etr_stepping_mode_show(struct sysdev_class *class, char *buf)
|
||||
static ssize_t etr_stepping_mode_show(struct sysdev_class *class,
|
||||
struct sysdev_class_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
char *mode_str;
|
||||
|
||||
@ -1584,7 +1588,9 @@ static struct sysdev_class stp_sysclass = {
|
||||
.name = "stp",
|
||||
};
|
||||
|
||||
static ssize_t stp_ctn_id_show(struct sysdev_class *class, char *buf)
|
||||
static ssize_t stp_ctn_id_show(struct sysdev_class *class,
|
||||
struct sysdev_class_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
if (!stp_online)
|
||||
return -ENODATA;
|
||||
@ -1594,7 +1600,9 @@ static ssize_t stp_ctn_id_show(struct sysdev_class *class, char *buf)
|
||||
|
||||
static SYSDEV_CLASS_ATTR(ctn_id, 0400, stp_ctn_id_show, NULL);
|
||||
|
||||
static ssize_t stp_ctn_type_show(struct sysdev_class *class, char *buf)
|
||||
static ssize_t stp_ctn_type_show(struct sysdev_class *class,
|
||||
struct sysdev_class_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
if (!stp_online)
|
||||
return -ENODATA;
|
||||
@ -1603,7 +1611,9 @@ static ssize_t stp_ctn_type_show(struct sysdev_class *class, char *buf)
|
||||
|
||||
static SYSDEV_CLASS_ATTR(ctn_type, 0400, stp_ctn_type_show, NULL);
|
||||
|
||||
static ssize_t stp_dst_offset_show(struct sysdev_class *class, char *buf)
|
||||
static ssize_t stp_dst_offset_show(struct sysdev_class *class,
|
||||
struct sysdev_class_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
if (!stp_online || !(stp_info.vbits & 0x2000))
|
||||
return -ENODATA;
|
||||
@ -1612,7 +1622,9 @@ static ssize_t stp_dst_offset_show(struct sysdev_class *class, char *buf)
|
||||
|
||||
static SYSDEV_CLASS_ATTR(dst_offset, 0400, stp_dst_offset_show, NULL);
|
||||
|
||||
static ssize_t stp_leap_seconds_show(struct sysdev_class *class, char *buf)
|
||||
static ssize_t stp_leap_seconds_show(struct sysdev_class *class,
|
||||
struct sysdev_class_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
if (!stp_online || !(stp_info.vbits & 0x8000))
|
||||
return -ENODATA;
|
||||
@ -1621,7 +1633,9 @@ static ssize_t stp_leap_seconds_show(struct sysdev_class *class, char *buf)
|
||||
|
||||
static SYSDEV_CLASS_ATTR(leap_seconds, 0400, stp_leap_seconds_show, NULL);
|
||||
|
||||
static ssize_t stp_stratum_show(struct sysdev_class *class, char *buf)
|
||||
static ssize_t stp_stratum_show(struct sysdev_class *class,
|
||||
struct sysdev_class_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
if (!stp_online)
|
||||
return -ENODATA;
|
||||
@ -1630,7 +1644,9 @@ static ssize_t stp_stratum_show(struct sysdev_class *class, char *buf)
|
||||
|
||||
static SYSDEV_CLASS_ATTR(stratum, 0400, stp_stratum_show, NULL);
|
||||
|
||||
static ssize_t stp_time_offset_show(struct sysdev_class *class, char *buf)
|
||||
static ssize_t stp_time_offset_show(struct sysdev_class *class,
|
||||
struct sysdev_class_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
if (!stp_online || !(stp_info.vbits & 0x0800))
|
||||
return -ENODATA;
|
||||
@ -1639,7 +1655,9 @@ static ssize_t stp_time_offset_show(struct sysdev_class *class, char *buf)
|
||||
|
||||
static SYSDEV_CLASS_ATTR(time_offset, 0400, stp_time_offset_show, NULL);
|
||||
|
||||
static ssize_t stp_time_zone_offset_show(struct sysdev_class *class, char *buf)
|
||||
static ssize_t stp_time_zone_offset_show(struct sysdev_class *class,
|
||||
struct sysdev_class_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
if (!stp_online || !(stp_info.vbits & 0x4000))
|
||||
return -ENODATA;
|
||||
@ -1649,7 +1667,9 @@ static ssize_t stp_time_zone_offset_show(struct sysdev_class *class, char *buf)
|
||||
static SYSDEV_CLASS_ATTR(time_zone_offset, 0400,
|
||||
stp_time_zone_offset_show, NULL);
|
||||
|
||||
static ssize_t stp_timing_mode_show(struct sysdev_class *class, char *buf)
|
||||
static ssize_t stp_timing_mode_show(struct sysdev_class *class,
|
||||
struct sysdev_class_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
if (!stp_online)
|
||||
return -ENODATA;
|
||||
@ -1658,7 +1678,9 @@ static ssize_t stp_timing_mode_show(struct sysdev_class *class, char *buf)
|
||||
|
||||
static SYSDEV_CLASS_ATTR(timing_mode, 0400, stp_timing_mode_show, NULL);
|
||||
|
||||
static ssize_t stp_timing_state_show(struct sysdev_class *class, char *buf)
|
||||
static ssize_t stp_timing_state_show(struct sysdev_class *class,
|
||||
struct sysdev_class_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
if (!stp_online)
|
||||
return -ENODATA;
|
||||
@ -1667,12 +1689,15 @@ static ssize_t stp_timing_state_show(struct sysdev_class *class, char *buf)
|
||||
|
||||
static SYSDEV_CLASS_ATTR(timing_state, 0400, stp_timing_state_show, NULL);
|
||||
|
||||
static ssize_t stp_online_show(struct sysdev_class *class, char *buf)
|
||||
static ssize_t stp_online_show(struct sysdev_class *class,
|
||||
struct sysdev_class_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
return sprintf(buf, "%i\n", stp_online);
|
||||
}
|
||||
|
||||
static ssize_t stp_online_store(struct sysdev_class *class,
|
||||
struct sysdev_class_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
unsigned int value;
|
||||
|
@ -326,7 +326,7 @@ static struct attribute *sq_sysfs_attrs[] = {
|
||||
NULL,
|
||||
};
|
||||
|
||||
static struct sysfs_ops sq_sysfs_ops = {
|
||||
static const struct sysfs_ops sq_sysfs_ops = {
|
||||
.show = sq_sysfs_show,
|
||||
.store = sq_sysfs_store,
|
||||
};
|
||||
|
@ -903,7 +903,7 @@ static ssize_t store(struct kobject *kobj, struct attribute *attr,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct sysfs_ops sysfs_ops = {
|
||||
static const struct sysfs_ops sysfs_ops = {
|
||||
.show = show,
|
||||
.store = store,
|
||||
};
|
||||
|
@ -2044,6 +2044,7 @@ static __init void mce_init_banks(void)
|
||||
struct mce_bank *b = &mce_banks[i];
|
||||
struct sysdev_attribute *a = &b->attr;
|
||||
|
||||
sysfs_attr_init(&a->attr);
|
||||
a->attr.name = b->attrname;
|
||||
snprintf(b->attrname, ATTR_LEN, "bank%d", i);
|
||||
|
||||
|
@ -388,7 +388,7 @@ static ssize_t store(struct kobject *kobj, struct attribute *attr,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct sysfs_ops threshold_ops = {
|
||||
static const struct sysfs_ops threshold_ops = {
|
||||
.show = show,
|
||||
.store = store,
|
||||
};
|
||||
|
@ -278,7 +278,7 @@ static struct attribute *integrity_attrs[] = {
|
||||
NULL,
|
||||
};
|
||||
|
||||
static struct sysfs_ops integrity_ops = {
|
||||
static const struct sysfs_ops integrity_ops = {
|
||||
.show = &integrity_attr_show,
|
||||
.store = &integrity_attr_store,
|
||||
};
|
||||
|
@ -450,7 +450,7 @@ static void blk_release_queue(struct kobject *kobj)
|
||||
kmem_cache_free(blk_requestq_cachep, q);
|
||||
}
|
||||
|
||||
static struct sysfs_ops queue_sysfs_ops = {
|
||||
static const struct sysfs_ops queue_sysfs_ops = {
|
||||
.show = queue_attr_show,
|
||||
.store = queue_attr_store,
|
||||
};
|
||||
|
@ -892,7 +892,7 @@ elv_attr_store(struct kobject *kobj, struct attribute *attr,
|
||||
return error;
|
||||
}
|
||||
|
||||
static struct sysfs_ops elv_sysfs_ops = {
|
||||
static const struct sysfs_ops elv_sysfs_ops = {
|
||||
.show = elv_attr_show,
|
||||
.store = elv_attr_store,
|
||||
};
|
||||
|
@ -101,6 +101,7 @@ static void acpi_table_attr_init(struct acpi_table_attr *table_attr,
|
||||
struct acpi_table_header *header = NULL;
|
||||
struct acpi_table_attr *attr = NULL;
|
||||
|
||||
sysfs_attr_init(&table_attr->attr.attr);
|
||||
if (table_header->signature[0] != '\0')
|
||||
memcpy(table_attr->name, table_header->signature,
|
||||
ACPI_NAME_SIZE);
|
||||
@ -475,6 +476,7 @@ void acpi_irq_stats_init(void)
|
||||
goto fail;
|
||||
strncpy(name, buffer, strlen(buffer) + 1);
|
||||
|
||||
sysfs_attr_init(&counter_attrs[i].attr);
|
||||
counter_attrs[i].attr.name = name;
|
||||
counter_attrs[i].attr.mode = 0644;
|
||||
counter_attrs[i].show = counter_show;
|
||||
|
@ -81,7 +81,7 @@ static struct fb_ops cfag12864bfb_ops = {
|
||||
.fb_mmap = cfag12864bfb_mmap,
|
||||
};
|
||||
|
||||
static int __init cfag12864bfb_probe(struct platform_device *device)
|
||||
static int __devinit cfag12864bfb_probe(struct platform_device *device)
|
||||
{
|
||||
int ret = -EINVAL;
|
||||
struct fb_info *info = framebuffer_alloc(0, &device->dev);
|
||||
|
@ -3,35 +3,50 @@ menu "Generic Driver Options"
|
||||
config UEVENT_HELPER_PATH
|
||||
string "path to uevent helper"
|
||||
depends on HOTPLUG
|
||||
default "/sbin/hotplug"
|
||||
default ""
|
||||
help
|
||||
Path to uevent helper program forked by the kernel for
|
||||
every uevent.
|
||||
Before the switch to the netlink-based uevent source, this was
|
||||
used to hook hotplug scripts into kernel device events. It
|
||||
usually pointed to a shell script at /sbin/hotplug.
|
||||
This should not be used today, because usual systems create
|
||||
many events at bootup or device discovery in a very short time
|
||||
frame. One forked process per event can create so many processes
|
||||
that it creates a high system load, or on smaller systems
|
||||
it is known to create out-of-memory situations during bootup.
|
||||
|
||||
config DEVTMPFS
|
||||
bool "Create a kernel maintained /dev tmpfs (EXPERIMENTAL)"
|
||||
bool "Maintain a devtmpfs filesystem to mount at /dev"
|
||||
depends on HOTPLUG && SHMEM && TMPFS
|
||||
help
|
||||
This creates a tmpfs filesystem, and mounts it at bootup
|
||||
and mounts it at /dev. The kernel driver core creates device
|
||||
nodes for all registered devices in that filesystem. All device
|
||||
nodes are owned by root and have the default mode of 0600.
|
||||
Userspace can add and delete the nodes as needed. This is
|
||||
intended to simplify bootup, and make it possible to delay
|
||||
the initial coldplug at bootup done by udev in userspace.
|
||||
It should also provide a simpler way for rescue systems
|
||||
to bring up a kernel with dynamic major/minor numbers.
|
||||
Meaningful symlinks, permissions and device ownership must
|
||||
still be handled by userspace.
|
||||
If unsure, say N here.
|
||||
This creates a tmpfs filesystem instance early at bootup.
|
||||
In this filesystem, the kernel driver core maintains device
|
||||
nodes with their default names and permissions for all
|
||||
registered devices with an assigned major/minor number.
|
||||
Userspace can modify the filesystem content as needed, add
|
||||
symlinks, and apply needed permissions.
|
||||
It provides a fully functional /dev directory, where usually
|
||||
udev runs on top, managing permissions and adding meaningful
|
||||
symlinks.
|
||||
In very limited environments, it may provide a sufficient
|
||||
functional /dev without any further help. It also allows simple
|
||||
rescue systems, and reliably handles dynamic major/minor numbers.
|
||||
|
||||
config DEVTMPFS_MOUNT
|
||||
bool "Automount devtmpfs at /dev"
|
||||
bool "Automount devtmpfs at /dev, after the kernel mounted the rootfs"
|
||||
depends on DEVTMPFS
|
||||
help
|
||||
This will mount devtmpfs at /dev if the kernel mounts the root
|
||||
filesystem. It will not affect initramfs based mounting.
|
||||
If unsure, say N here.
|
||||
This will instruct the kernel to automatically mount the
|
||||
devtmpfs filesystem at /dev, directly after the kernel has
|
||||
mounted the root filesystem. The behavior can be overridden
|
||||
with the commandline parameter: devtmpfs.mount=0|1.
|
||||
This option does not affect initramfs based booting, here
|
||||
the devtmpfs filesystem always needs to be mounted manually
|
||||
after the roots is mounted.
|
||||
With this option enabled, it allows to bring up a system in
|
||||
rescue mode with init=/bin/sh, even when the /dev directory
|
||||
on the rootfs is completely empty.
|
||||
|
||||
config STANDALONE
|
||||
bool "Select only drivers that don't need compile-time external firmware" if EXPERIMENTAL
|
||||
|
@ -70,7 +70,7 @@ static ssize_t drv_attr_store(struct kobject *kobj, struct attribute *attr,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct sysfs_ops driver_sysfs_ops = {
|
||||
static const struct sysfs_ops driver_sysfs_ops = {
|
||||
.show = drv_attr_show,
|
||||
.store = drv_attr_store,
|
||||
};
|
||||
@ -115,7 +115,7 @@ static ssize_t bus_attr_store(struct kobject *kobj, struct attribute *attr,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct sysfs_ops bus_sysfs_ops = {
|
||||
static const struct sysfs_ops bus_sysfs_ops = {
|
||||
.show = bus_attr_show,
|
||||
.store = bus_attr_store,
|
||||
};
|
||||
@ -154,7 +154,7 @@ static int bus_uevent_filter(struct kset *kset, struct kobject *kobj)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct kset_uevent_ops bus_uevent_ops = {
|
||||
static const struct kset_uevent_ops bus_uevent_ops = {
|
||||
.filter = bus_uevent_filter,
|
||||
};
|
||||
|
||||
@ -173,10 +173,10 @@ static ssize_t driver_unbind(struct device_driver *drv,
|
||||
dev = bus_find_device_by_name(bus, NULL, buf);
|
||||
if (dev && dev->driver == drv) {
|
||||
if (dev->parent) /* Needed for USB */
|
||||
down(&dev->parent->sem);
|
||||
device_lock(dev->parent);
|
||||
device_release_driver(dev);
|
||||
if (dev->parent)
|
||||
up(&dev->parent->sem);
|
||||
device_unlock(dev->parent);
|
||||
err = count;
|
||||
}
|
||||
put_device(dev);
|
||||
@ -200,12 +200,12 @@ static ssize_t driver_bind(struct device_driver *drv,
|
||||
dev = bus_find_device_by_name(bus, NULL, buf);
|
||||
if (dev && dev->driver == NULL && driver_match_device(drv, dev)) {
|
||||
if (dev->parent) /* Needed for USB */
|
||||
down(&dev->parent->sem);
|
||||
down(&dev->sem);
|
||||
device_lock(dev->parent);
|
||||
device_lock(dev);
|
||||
err = driver_probe_device(drv, dev);
|
||||
up(&dev->sem);
|
||||
device_unlock(dev);
|
||||
if (dev->parent)
|
||||
up(&dev->parent->sem);
|
||||
device_unlock(dev->parent);
|
||||
|
||||
if (err > 0) {
|
||||
/* success */
|
||||
@ -744,10 +744,10 @@ static int __must_check bus_rescan_devices_helper(struct device *dev,
|
||||
|
||||
if (!dev->driver) {
|
||||
if (dev->parent) /* Needed for USB */
|
||||
down(&dev->parent->sem);
|
||||
device_lock(dev->parent);
|
||||
ret = device_attach(dev);
|
||||
if (dev->parent)
|
||||
up(&dev->parent->sem);
|
||||
device_unlock(dev->parent);
|
||||
}
|
||||
return ret < 0 ? ret : 0;
|
||||
}
|
||||
@ -779,10 +779,10 @@ int device_reprobe(struct device *dev)
|
||||
{
|
||||
if (dev->driver) {
|
||||
if (dev->parent) /* Needed for USB */
|
||||
down(&dev->parent->sem);
|
||||
device_lock(dev->parent);
|
||||
device_release_driver(dev);
|
||||
if (dev->parent)
|
||||
up(&dev->parent->sem);
|
||||
device_unlock(dev->parent);
|
||||
}
|
||||
return bus_rescan_devices_helper(dev, NULL);
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ static ssize_t class_attr_show(struct kobject *kobj, struct attribute *attr,
|
||||
ssize_t ret = -EIO;
|
||||
|
||||
if (class_attr->show)
|
||||
ret = class_attr->show(cp->class, buf);
|
||||
ret = class_attr->show(cp->class, class_attr, buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -43,7 +43,7 @@ static ssize_t class_attr_store(struct kobject *kobj, struct attribute *attr,
|
||||
ssize_t ret = -EIO;
|
||||
|
||||
if (class_attr->store)
|
||||
ret = class_attr->store(cp->class, buf, count);
|
||||
ret = class_attr->store(cp->class, class_attr, buf, count);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -63,7 +63,7 @@ static void class_release(struct kobject *kobj)
|
||||
kfree(cp);
|
||||
}
|
||||
|
||||
static struct sysfs_ops class_sysfs_ops = {
|
||||
static const struct sysfs_ops class_sysfs_ops = {
|
||||
.show = class_attr_show,
|
||||
.store = class_attr_store,
|
||||
};
|
||||
@ -490,6 +490,16 @@ void class_interface_unregister(struct class_interface *class_intf)
|
||||
class_put(parent);
|
||||
}
|
||||
|
||||
ssize_t show_class_attr_string(struct class *class, struct class_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct class_attribute_string *cs;
|
||||
cs = container_of(attr, struct class_attribute_string, attr);
|
||||
return snprintf(buf, PAGE_SIZE, "%s\n", cs->str);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL_GPL(show_class_attr_string);
|
||||
|
||||
struct class_compat {
|
||||
struct kobject *kobj;
|
||||
};
|
||||
|
@ -100,7 +100,7 @@ static ssize_t dev_attr_store(struct kobject *kobj, struct attribute *attr,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct sysfs_ops dev_sysfs_ops = {
|
||||
static const struct sysfs_ops dev_sysfs_ops = {
|
||||
.show = dev_attr_show,
|
||||
.store = dev_attr_store,
|
||||
};
|
||||
@ -252,7 +252,7 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj,
|
||||
return retval;
|
||||
}
|
||||
|
||||
static struct kset_uevent_ops device_uevent_ops = {
|
||||
static const struct kset_uevent_ops device_uevent_ops = {
|
||||
.filter = dev_uevent_filter,
|
||||
.name = dev_uevent_name,
|
||||
.uevent = dev_uevent,
|
||||
@ -306,15 +306,10 @@ static ssize_t store_uevent(struct device *dev, struct device_attribute *attr,
|
||||
{
|
||||
enum kobject_action action;
|
||||
|
||||
if (kobject_action_type(buf, count, &action) == 0) {
|
||||
if (kobject_action_type(buf, count, &action) == 0)
|
||||
kobject_uevent(&dev->kobj, action);
|
||||
goto out;
|
||||
}
|
||||
|
||||
dev_err(dev, "uevent: unsupported action-string; this will "
|
||||
"be ignored in a future kernel version\n");
|
||||
kobject_uevent(&dev->kobj, KOBJ_ADD);
|
||||
out:
|
||||
else
|
||||
dev_err(dev, "uevent: unknown action-string\n");
|
||||
return count;
|
||||
}
|
||||
|
||||
@ -607,6 +602,7 @@ static struct kobject *get_device_parent(struct device *dev,
|
||||
int retval;
|
||||
|
||||
if (dev->class) {
|
||||
static DEFINE_MUTEX(gdp_mutex);
|
||||
struct kobject *kobj = NULL;
|
||||
struct kobject *parent_kobj;
|
||||
struct kobject *k;
|
||||
@ -623,6 +619,8 @@ static struct kobject *get_device_parent(struct device *dev,
|
||||
else
|
||||
parent_kobj = &parent->kobj;
|
||||
|
||||
mutex_lock(&gdp_mutex);
|
||||
|
||||
/* find our class-directory at the parent and reference it */
|
||||
spin_lock(&dev->class->p->class_dirs.list_lock);
|
||||
list_for_each_entry(k, &dev->class->p->class_dirs.list, entry)
|
||||
@ -631,20 +629,26 @@ static struct kobject *get_device_parent(struct device *dev,
|
||||
break;
|
||||
}
|
||||
spin_unlock(&dev->class->p->class_dirs.list_lock);
|
||||
if (kobj)
|
||||
if (kobj) {
|
||||
mutex_unlock(&gdp_mutex);
|
||||
return kobj;
|
||||
}
|
||||
|
||||
/* or create a new class-directory at the parent device */
|
||||
k = kobject_create();
|
||||
if (!k)
|
||||
if (!k) {
|
||||
mutex_unlock(&gdp_mutex);
|
||||
return NULL;
|
||||
}
|
||||
k->kset = &dev->class->p->class_dirs;
|
||||
retval = kobject_add(k, parent_kobj, "%s", dev->class->name);
|
||||
if (retval < 0) {
|
||||
mutex_unlock(&gdp_mutex);
|
||||
kobject_put(k);
|
||||
return NULL;
|
||||
}
|
||||
/* do not emit an uevent for this simple "glue" directory */
|
||||
mutex_unlock(&gdp_mutex);
|
||||
return k;
|
||||
}
|
||||
|
||||
@ -1574,22 +1578,16 @@ int device_rename(struct device *dev, char *new_name)
|
||||
if (old_class_name) {
|
||||
new_class_name = make_class_name(dev->class->name, &dev->kobj);
|
||||
if (new_class_name) {
|
||||
error = sysfs_create_link_nowarn(&dev->parent->kobj,
|
||||
&dev->kobj,
|
||||
new_class_name);
|
||||
if (error)
|
||||
goto out;
|
||||
sysfs_remove_link(&dev->parent->kobj, old_class_name);
|
||||
error = sysfs_rename_link(&dev->parent->kobj,
|
||||
&dev->kobj,
|
||||
old_class_name,
|
||||
new_class_name);
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (dev->class) {
|
||||
error = sysfs_create_link_nowarn(&dev->class->p->class_subsys.kobj,
|
||||
&dev->kobj, dev_name(dev));
|
||||
if (error)
|
||||
goto out;
|
||||
sysfs_remove_link(&dev->class->p->class_subsys.kobj,
|
||||
old_device_name);
|
||||
error = sysfs_rename_link(&dev->class->p->class_subsys.kobj,
|
||||
&dev->kobj, old_device_name, new_name);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -13,8 +13,11 @@
|
||||
|
||||
#include "base.h"
|
||||
|
||||
static struct sysdev_class_attribute *cpu_sysdev_class_attrs[];
|
||||
|
||||
struct sysdev_class cpu_sysdev_class = {
|
||||
.name = "cpu",
|
||||
.attrs = cpu_sysdev_class_attrs,
|
||||
};
|
||||
EXPORT_SYMBOL(cpu_sysdev_class);
|
||||
|
||||
@ -76,34 +79,24 @@ void unregister_cpu(struct cpu *cpu)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ARCH_CPU_PROBE_RELEASE
|
||||
static ssize_t cpu_probe_store(struct class *class, const char *buf,
|
||||
static ssize_t cpu_probe_store(struct sys_device *dev,
|
||||
struct sysdev_attribute *attr,
|
||||
const char *buf,
|
||||
size_t count)
|
||||
{
|
||||
return arch_cpu_probe(buf, count);
|
||||
}
|
||||
|
||||
static ssize_t cpu_release_store(struct class *class, const char *buf,
|
||||
static ssize_t cpu_release_store(struct sys_device *dev,
|
||||
struct sysdev_attribute *attr,
|
||||
const char *buf,
|
||||
size_t count)
|
||||
{
|
||||
return arch_cpu_release(buf, count);
|
||||
}
|
||||
|
||||
static CLASS_ATTR(probe, S_IWUSR, NULL, cpu_probe_store);
|
||||
static CLASS_ATTR(release, S_IWUSR, NULL, cpu_release_store);
|
||||
|
||||
int __init cpu_probe_release_init(void)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = sysfs_create_file(&cpu_sysdev_class.kset.kobj,
|
||||
&class_attr_probe.attr);
|
||||
if (!rc)
|
||||
rc = sysfs_create_file(&cpu_sysdev_class.kset.kobj,
|
||||
&class_attr_release.attr);
|
||||
|
||||
return rc;
|
||||
}
|
||||
device_initcall(cpu_probe_release_init);
|
||||
static SYSDEV_ATTR(probe, S_IWUSR, NULL, cpu_probe_store);
|
||||
static SYSDEV_ATTR(release, S_IWUSR, NULL, cpu_release_store);
|
||||
#endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */
|
||||
|
||||
#else /* ... !CONFIG_HOTPLUG_CPU */
|
||||
@ -141,31 +134,39 @@ static SYSDEV_ATTR(crash_notes, 0400, show_crash_notes, NULL);
|
||||
/*
|
||||
* Print cpu online, possible, present, and system maps
|
||||
*/
|
||||
static ssize_t print_cpus_map(char *buf, const struct cpumask *map)
|
||||
|
||||
struct cpu_attr {
|
||||
struct sysdev_class_attribute attr;
|
||||
const struct cpumask *const * const map;
|
||||
};
|
||||
|
||||
static ssize_t show_cpus_attr(struct sysdev_class *class,
|
||||
struct sysdev_class_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
int n = cpulist_scnprintf(buf, PAGE_SIZE-2, map);
|
||||
struct cpu_attr *ca = container_of(attr, struct cpu_attr, attr);
|
||||
int n = cpulist_scnprintf(buf, PAGE_SIZE-2, *(ca->map));
|
||||
|
||||
buf[n++] = '\n';
|
||||
buf[n] = '\0';
|
||||
return n;
|
||||
}
|
||||
|
||||
#define print_cpus_func(type) \
|
||||
static ssize_t print_cpus_##type(struct sysdev_class *class, char *buf) \
|
||||
{ \
|
||||
return print_cpus_map(buf, cpu_##type##_mask); \
|
||||
} \
|
||||
static struct sysdev_class_attribute attr_##type##_map = \
|
||||
_SYSDEV_CLASS_ATTR(type, 0444, print_cpus_##type, NULL)
|
||||
#define _CPU_ATTR(name, map) \
|
||||
{ _SYSDEV_CLASS_ATTR(name, 0444, show_cpus_attr, NULL), map }
|
||||
|
||||
print_cpus_func(online);
|
||||
print_cpus_func(possible);
|
||||
print_cpus_func(present);
|
||||
/* Keep in sync with cpu_sysdev_class_attrs */
|
||||
static struct cpu_attr cpu_attrs[] = {
|
||||
_CPU_ATTR(online, &cpu_online_mask),
|
||||
_CPU_ATTR(possible, &cpu_possible_mask),
|
||||
_CPU_ATTR(present, &cpu_present_mask),
|
||||
};
|
||||
|
||||
/*
|
||||
* Print values for NR_CPUS and offlined cpus
|
||||
*/
|
||||
static ssize_t print_cpus_kernel_max(struct sysdev_class *class, char *buf)
|
||||
static ssize_t print_cpus_kernel_max(struct sysdev_class *class,
|
||||
struct sysdev_class_attribute *attr, char *buf)
|
||||
{
|
||||
int n = snprintf(buf, PAGE_SIZE-2, "%d\n", NR_CPUS - 1);
|
||||
return n;
|
||||
@ -175,7 +176,8 @@ static SYSDEV_CLASS_ATTR(kernel_max, 0444, print_cpus_kernel_max, NULL);
|
||||
/* arch-optional setting to enable display of offline cpus >= nr_cpu_ids */
|
||||
unsigned int total_cpus;
|
||||
|
||||
static ssize_t print_cpus_offline(struct sysdev_class *class, char *buf)
|
||||
static ssize_t print_cpus_offline(struct sysdev_class *class,
|
||||
struct sysdev_class_attribute *attr, char *buf)
|
||||
{
|
||||
int n = 0, len = PAGE_SIZE-2;
|
||||
cpumask_var_t offline;
|
||||
@ -204,29 +206,6 @@ static ssize_t print_cpus_offline(struct sysdev_class *class, char *buf)
|
||||
}
|
||||
static SYSDEV_CLASS_ATTR(offline, 0444, print_cpus_offline, NULL);
|
||||
|
||||
static struct sysdev_class_attribute *cpu_state_attr[] = {
|
||||
&attr_online_map,
|
||||
&attr_possible_map,
|
||||
&attr_present_map,
|
||||
&attr_kernel_max,
|
||||
&attr_offline,
|
||||
};
|
||||
|
||||
static int cpu_states_init(void)
|
||||
{
|
||||
int i;
|
||||
int err = 0;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(cpu_state_attr); i++) {
|
||||
int ret;
|
||||
ret = sysdev_class_create_file(&cpu_sysdev_class,
|
||||
cpu_state_attr[i]);
|
||||
if (!err)
|
||||
err = ret;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* register_cpu - Setup a sysfs device for a CPU.
|
||||
* @cpu - cpu->hotpluggable field set to 1 will generate a control file in
|
||||
@ -272,9 +251,6 @@ int __init cpu_dev_init(void)
|
||||
int err;
|
||||
|
||||
err = sysdev_class_register(&cpu_sysdev_class);
|
||||
if (!err)
|
||||
err = cpu_states_init();
|
||||
|
||||
#if defined(CONFIG_SCHED_MC) || defined(CONFIG_SCHED_SMT)
|
||||
if (!err)
|
||||
err = sched_create_sysfs_power_savings_entries(&cpu_sysdev_class);
|
||||
@ -282,3 +258,16 @@ int __init cpu_dev_init(void)
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static struct sysdev_class_attribute *cpu_sysdev_class_attrs[] = {
|
||||
#ifdef CONFIG_ARCH_CPU_PROBE_RELEASE
|
||||
&attr_probe,
|
||||
&attr_release,
|
||||
#endif
|
||||
&cpu_attrs[0].attr,
|
||||
&cpu_attrs[1].attr,
|
||||
&cpu_attrs[2].attr,
|
||||
&attr_kernel_max,
|
||||
&attr_offline,
|
||||
NULL
|
||||
};
|
||||
|
@ -85,7 +85,7 @@ static void driver_sysfs_remove(struct device *dev)
|
||||
* for before calling this. (It is ok to call with no other effort
|
||||
* from a driver's probe() method.)
|
||||
*
|
||||
* This function must be called with @dev->sem held.
|
||||
* This function must be called with the device lock held.
|
||||
*/
|
||||
int device_bind_driver(struct device *dev)
|
||||
{
|
||||
@ -190,8 +190,8 @@ EXPORT_SYMBOL_GPL(wait_for_device_probe);
|
||||
* This function returns -ENODEV if the device is not registered,
|
||||
* 1 if the device is bound successfully and 0 otherwise.
|
||||
*
|
||||
* This function must be called with @dev->sem held. When called for a
|
||||
* USB interface, @dev->parent->sem must be held as well.
|
||||
* This function must be called with @dev lock held. When called for a
|
||||
* USB interface, @dev->parent lock must be held as well.
|
||||
*/
|
||||
int driver_probe_device(struct device_driver *drv, struct device *dev)
|
||||
{
|
||||
@ -233,13 +233,13 @@ static int __device_attach(struct device_driver *drv, void *data)
|
||||
* 0 if no matching driver was found;
|
||||
* -ENODEV if the device is not registered.
|
||||
*
|
||||
* When called for a USB interface, @dev->parent->sem must be held.
|
||||
* When called for a USB interface, @dev->parent lock must be held.
|
||||
*/
|
||||
int device_attach(struct device *dev)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
down(&dev->sem);
|
||||
device_lock(dev);
|
||||
if (dev->driver) {
|
||||
ret = device_bind_driver(dev);
|
||||
if (ret == 0)
|
||||
@ -253,7 +253,7 @@ int device_attach(struct device *dev)
|
||||
ret = bus_for_each_drv(dev->bus, NULL, dev, __device_attach);
|
||||
pm_runtime_put_sync(dev);
|
||||
}
|
||||
up(&dev->sem);
|
||||
device_unlock(dev);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(device_attach);
|
||||
@ -276,13 +276,13 @@ static int __driver_attach(struct device *dev, void *data)
|
||||
return 0;
|
||||
|
||||
if (dev->parent) /* Needed for USB */
|
||||
down(&dev->parent->sem);
|
||||
down(&dev->sem);
|
||||
device_lock(dev->parent);
|
||||
device_lock(dev);
|
||||
if (!dev->driver)
|
||||
driver_probe_device(drv, dev);
|
||||
up(&dev->sem);
|
||||
device_unlock(dev);
|
||||
if (dev->parent)
|
||||
up(&dev->parent->sem);
|
||||
device_unlock(dev->parent);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -303,8 +303,8 @@ int driver_attach(struct device_driver *drv)
|
||||
EXPORT_SYMBOL_GPL(driver_attach);
|
||||
|
||||
/*
|
||||
* __device_release_driver() must be called with @dev->sem held.
|
||||
* When called for a USB interface, @dev->parent->sem must be held as well.
|
||||
* __device_release_driver() must be called with @dev lock held.
|
||||
* When called for a USB interface, @dev->parent lock must be held as well.
|
||||
*/
|
||||
static void __device_release_driver(struct device *dev)
|
||||
{
|
||||
@ -343,7 +343,7 @@ static void __device_release_driver(struct device *dev)
|
||||
* @dev: device.
|
||||
*
|
||||
* Manually detach device from driver.
|
||||
* When called for a USB interface, @dev->parent->sem must be held.
|
||||
* When called for a USB interface, @dev->parent lock must be held.
|
||||
*/
|
||||
void device_release_driver(struct device *dev)
|
||||
{
|
||||
@ -352,9 +352,9 @@ void device_release_driver(struct device *dev)
|
||||
* within their ->remove callback for the same device, they
|
||||
* will deadlock right here.
|
||||
*/
|
||||
down(&dev->sem);
|
||||
device_lock(dev);
|
||||
__device_release_driver(dev);
|
||||
up(&dev->sem);
|
||||
device_unlock(dev);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(device_release_driver);
|
||||
|
||||
@ -381,13 +381,13 @@ void driver_detach(struct device_driver *drv)
|
||||
spin_unlock(&drv->p->klist_devices.k_lock);
|
||||
|
||||
if (dev->parent) /* Needed for USB */
|
||||
down(&dev->parent->sem);
|
||||
down(&dev->sem);
|
||||
device_lock(dev->parent);
|
||||
device_lock(dev);
|
||||
if (dev->driver == drv)
|
||||
__device_release_driver(dev);
|
||||
up(&dev->sem);
|
||||
device_unlock(dev);
|
||||
if (dev->parent)
|
||||
up(&dev->parent->sem);
|
||||
device_unlock(dev->parent);
|
||||
put_device(dev);
|
||||
}
|
||||
}
|
||||
|
@ -301,6 +301,19 @@ int devtmpfs_delete_node(struct device *dev)
|
||||
if (dentry->d_inode) {
|
||||
err = vfs_getattr(nd.path.mnt, dentry, &stat);
|
||||
if (!err && dev_mynode(dev, dentry->d_inode, &stat)) {
|
||||
struct iattr newattrs;
|
||||
/*
|
||||
* before unlinking this node, reset permissions
|
||||
* of possible references like hardlinks
|
||||
*/
|
||||
newattrs.ia_uid = 0;
|
||||
newattrs.ia_gid = 0;
|
||||
newattrs.ia_mode = stat.mode & ~0777;
|
||||
newattrs.ia_valid =
|
||||
ATTR_UID|ATTR_GID|ATTR_MODE;
|
||||
mutex_lock(&dentry->d_inode->i_mutex);
|
||||
notify_change(dentry, &newattrs);
|
||||
mutex_unlock(&dentry->d_inode->i_mutex);
|
||||
err = vfs_unlink(nd.path.dentry->d_inode,
|
||||
dentry);
|
||||
if (!err || err == -ENOENT)
|
||||
|
@ -19,7 +19,6 @@
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/highmem.h>
|
||||
#include <linux/firmware.h>
|
||||
#include "base.h"
|
||||
|
||||
#define to_dev(obj) container_of(obj, struct device, kobj)
|
||||
|
||||
@ -69,7 +68,9 @@ fw_load_abort(struct firmware_priv *fw_priv)
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
firmware_timeout_show(struct class *class, char *buf)
|
||||
firmware_timeout_show(struct class *class,
|
||||
struct class_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
return sprintf(buf, "%d\n", loading_timeout);
|
||||
}
|
||||
@ -87,7 +88,9 @@ firmware_timeout_show(struct class *class, char *buf)
|
||||
* Note: zero means 'wait forever'.
|
||||
**/
|
||||
static ssize_t
|
||||
firmware_timeout_store(struct class *class, const char *buf, size_t count)
|
||||
firmware_timeout_store(struct class *class,
|
||||
struct class_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
loading_timeout = simple_strtol(buf, NULL, 10);
|
||||
if (loading_timeout < 0)
|
||||
@ -610,7 +613,7 @@ request_firmware_work_func(void *arg)
|
||||
}
|
||||
|
||||
/**
|
||||
* request_firmware_nowait: asynchronous version of request_firmware
|
||||
* request_firmware_nowait - asynchronous version of request_firmware
|
||||
* @module: module requesting the firmware
|
||||
* @uevent: sends uevent to copy the firmware image if this flag
|
||||
* is non-zero else the firmware copy must be done manually.
|
||||
|
@ -44,7 +44,7 @@ static int memory_uevent(struct kset *kset, struct kobject *obj, struct kobj_uev
|
||||
return retval;
|
||||
}
|
||||
|
||||
static struct kset_uevent_ops memory_uevent_ops = {
|
||||
static const struct kset_uevent_ops memory_uevent_ops = {
|
||||
.name = memory_uevent_name,
|
||||
.uevent = memory_uevent,
|
||||
};
|
||||
@ -309,17 +309,18 @@ static SYSDEV_ATTR(removable, 0444, show_mem_removable, NULL);
|
||||
* Block size attribute stuff
|
||||
*/
|
||||
static ssize_t
|
||||
print_block_size(struct class *class, char *buf)
|
||||
print_block_size(struct sysdev_class *class, struct sysdev_class_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
return sprintf(buf, "%#lx\n", (unsigned long)PAGES_PER_SECTION * PAGE_SIZE);
|
||||
}
|
||||
|
||||
static CLASS_ATTR(block_size_bytes, 0444, print_block_size, NULL);
|
||||
static SYSDEV_CLASS_ATTR(block_size_bytes, 0444, print_block_size, NULL);
|
||||
|
||||
static int block_size_init(void)
|
||||
{
|
||||
return sysfs_create_file(&memory_sysdev_class.kset.kobj,
|
||||
&class_attr_block_size_bytes.attr);
|
||||
&attr_block_size_bytes.attr);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -330,7 +331,8 @@ static int block_size_init(void)
|
||||
*/
|
||||
#ifdef CONFIG_ARCH_MEMORY_PROBE
|
||||
static ssize_t
|
||||
memory_probe_store(struct class *class, const char *buf, size_t count)
|
||||
memory_probe_store(struct class *class, struct class_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
u64 phys_addr;
|
||||
int nid;
|
||||
@ -367,7 +369,9 @@ static inline int memory_probe_init(void)
|
||||
|
||||
/* Soft offline a page */
|
||||
static ssize_t
|
||||
store_soft_offline_page(struct class *class, const char *buf, size_t count)
|
||||
store_soft_offline_page(struct class *class,
|
||||
struct class_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
int ret;
|
||||
u64 pfn;
|
||||
@ -384,7 +388,9 @@ store_soft_offline_page(struct class *class, const char *buf, size_t count)
|
||||
|
||||
/* Forcibly offline a page, including killing processes. */
|
||||
static ssize_t
|
||||
store_hard_offline_page(struct class *class, const char *buf, size_t count)
|
||||
store_hard_offline_page(struct class *class,
|
||||
struct class_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
int ret;
|
||||
u64 pfn;
|
||||
|
@ -16,8 +16,11 @@
|
||||
#include <linux/device.h>
|
||||
#include <linux/swap.h>
|
||||
|
||||
static struct sysdev_class_attribute *node_state_attrs[];
|
||||
|
||||
static struct sysdev_class node_class = {
|
||||
.name = "node",
|
||||
.attrs = node_state_attrs,
|
||||
};
|
||||
|
||||
|
||||
@ -544,76 +547,52 @@ static ssize_t print_nodes_state(enum node_states state, char *buf)
|
||||
return n;
|
||||
}
|
||||
|
||||
static ssize_t print_nodes_possible(struct sysdev_class *class, char *buf)
|
||||
{
|
||||
return print_nodes_state(N_POSSIBLE, buf);
|
||||
}
|
||||
|
||||
static ssize_t print_nodes_online(struct sysdev_class *class, char *buf)
|
||||
{
|
||||
return print_nodes_state(N_ONLINE, buf);
|
||||
}
|
||||
|
||||
static ssize_t print_nodes_has_normal_memory(struct sysdev_class *class,
|
||||
char *buf)
|
||||
{
|
||||
return print_nodes_state(N_NORMAL_MEMORY, buf);
|
||||
}
|
||||
|
||||
static ssize_t print_nodes_has_cpu(struct sysdev_class *class, char *buf)
|
||||
{
|
||||
return print_nodes_state(N_CPU, buf);
|
||||
}
|
||||
|
||||
static SYSDEV_CLASS_ATTR(possible, 0444, print_nodes_possible, NULL);
|
||||
static SYSDEV_CLASS_ATTR(online, 0444, print_nodes_online, NULL);
|
||||
static SYSDEV_CLASS_ATTR(has_normal_memory, 0444, print_nodes_has_normal_memory,
|
||||
NULL);
|
||||
static SYSDEV_CLASS_ATTR(has_cpu, 0444, print_nodes_has_cpu, NULL);
|
||||
|
||||
#ifdef CONFIG_HIGHMEM
|
||||
static ssize_t print_nodes_has_high_memory(struct sysdev_class *class,
|
||||
char *buf)
|
||||
{
|
||||
return print_nodes_state(N_HIGH_MEMORY, buf);
|
||||
}
|
||||
|
||||
static SYSDEV_CLASS_ATTR(has_high_memory, 0444, print_nodes_has_high_memory,
|
||||
NULL);
|
||||
#endif
|
||||
|
||||
struct sysdev_class_attribute *node_state_attr[] = {
|
||||
&attr_possible,
|
||||
&attr_online,
|
||||
&attr_has_normal_memory,
|
||||
#ifdef CONFIG_HIGHMEM
|
||||
&attr_has_high_memory,
|
||||
#endif
|
||||
&attr_has_cpu,
|
||||
struct node_attr {
|
||||
struct sysdev_class_attribute attr;
|
||||
enum node_states state;
|
||||
};
|
||||
|
||||
static int node_states_init(void)
|
||||
static ssize_t show_node_state(struct sysdev_class *class,
|
||||
struct sysdev_class_attribute *attr, char *buf)
|
||||
{
|
||||
int i;
|
||||
int err = 0;
|
||||
|
||||
for (i = 0; i < NR_NODE_STATES; i++) {
|
||||
int ret;
|
||||
ret = sysdev_class_create_file(&node_class, node_state_attr[i]);
|
||||
if (!err)
|
||||
err = ret;
|
||||
}
|
||||
return err;
|
||||
struct node_attr *na = container_of(attr, struct node_attr, attr);
|
||||
return print_nodes_state(na->state, buf);
|
||||
}
|
||||
|
||||
#define _NODE_ATTR(name, state) \
|
||||
{ _SYSDEV_CLASS_ATTR(name, 0444, show_node_state, NULL), state }
|
||||
|
||||
static struct node_attr node_state_attr[] = {
|
||||
_NODE_ATTR(possible, N_POSSIBLE),
|
||||
_NODE_ATTR(online, N_ONLINE),
|
||||
_NODE_ATTR(has_normal_memory, N_NORMAL_MEMORY),
|
||||
_NODE_ATTR(has_cpu, N_CPU),
|
||||
#ifdef CONFIG_HIGHMEM
|
||||
_NODE_ATTR(has_high_memory, N_HIGH_MEMORY),
|
||||
#endif
|
||||
};
|
||||
|
||||
static struct sysdev_class_attribute *node_state_attrs[] = {
|
||||
&node_state_attr[0].attr,
|
||||
&node_state_attr[1].attr,
|
||||
&node_state_attr[2].attr,
|
||||
&node_state_attr[3].attr,
|
||||
#ifdef CONFIG_HIGHMEM
|
||||
&node_state_attr[4].attr,
|
||||
#endif
|
||||
NULL
|
||||
};
|
||||
|
||||
#define NODE_CALLBACK_PRI 2 /* lower than SLAB */
|
||||
static int __init register_node_type(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
BUILD_BUG_ON(ARRAY_SIZE(node_state_attr) != NR_NODE_STATES);
|
||||
BUILD_BUG_ON(ARRAY_SIZE(node_state_attrs)-1 != NR_NODE_STATES);
|
||||
|
||||
ret = sysdev_class_register(&node_class);
|
||||
if (!ret) {
|
||||
ret = node_states_init();
|
||||
hotplug_memory_notifier(node_memory_callback,
|
||||
NODE_CALLBACK_PRI);
|
||||
}
|
||||
|
@ -128,7 +128,7 @@ struct platform_object {
|
||||
};
|
||||
|
||||
/**
|
||||
* platform_device_put
|
||||
* platform_device_put - destroy a platform device
|
||||
* @pdev: platform device to free
|
||||
*
|
||||
* Free all memory associated with a platform device. This function must
|
||||
@ -152,7 +152,7 @@ static void platform_device_release(struct device *dev)
|
||||
}
|
||||
|
||||
/**
|
||||
* platform_device_alloc
|
||||
* platform_device_alloc - create a platform device
|
||||
* @name: base name of the device we're adding
|
||||
* @id: instance id
|
||||
*
|
||||
@ -177,7 +177,7 @@ struct platform_device *platform_device_alloc(const char *name, int id)
|
||||
EXPORT_SYMBOL_GPL(platform_device_alloc);
|
||||
|
||||
/**
|
||||
* platform_device_add_resources
|
||||
* platform_device_add_resources - add resources to a platform device
|
||||
* @pdev: platform device allocated by platform_device_alloc to add resources to
|
||||
* @res: set of resources that needs to be allocated for the device
|
||||
* @num: number of resources
|
||||
@ -202,7 +202,7 @@ int platform_device_add_resources(struct platform_device *pdev,
|
||||
EXPORT_SYMBOL_GPL(platform_device_add_resources);
|
||||
|
||||
/**
|
||||
* platform_device_add_data
|
||||
* platform_device_add_data - add platform-specific data to a platform device
|
||||
* @pdev: platform device allocated by platform_device_alloc to add resources to
|
||||
* @data: platform specific data for this platform device
|
||||
* @size: size of platform specific data
|
||||
@ -344,7 +344,7 @@ void platform_device_unregister(struct platform_device *pdev)
|
||||
EXPORT_SYMBOL_GPL(platform_device_unregister);
|
||||
|
||||
/**
|
||||
* platform_device_register_simple
|
||||
* platform_device_register_simple - add a platform-level device and its resources
|
||||
* @name: base name of the device we're adding
|
||||
* @id: instance id
|
||||
* @res: set of resources that needs to be allocated for the device
|
||||
@ -396,7 +396,7 @@ error:
|
||||
EXPORT_SYMBOL_GPL(platform_device_register_simple);
|
||||
|
||||
/**
|
||||
* platform_device_register_data
|
||||
* platform_device_register_data - add a platform-level device with platform-specific data
|
||||
* @parent: parent device for the device we're adding
|
||||
* @name: base name of the device we're adding
|
||||
* @id: instance id
|
||||
@ -473,7 +473,7 @@ static void platform_drv_shutdown(struct device *_dev)
|
||||
}
|
||||
|
||||
/**
|
||||
* platform_driver_register
|
||||
* platform_driver_register - register a driver for platform-level devices
|
||||
* @drv: platform driver structure
|
||||
*/
|
||||
int platform_driver_register(struct platform_driver *drv)
|
||||
@ -491,7 +491,7 @@ int platform_driver_register(struct platform_driver *drv)
|
||||
EXPORT_SYMBOL_GPL(platform_driver_register);
|
||||
|
||||
/**
|
||||
* platform_driver_unregister
|
||||
* platform_driver_unregister - unregister a driver for platform-level devices
|
||||
* @drv: platform driver structure
|
||||
*/
|
||||
void platform_driver_unregister(struct platform_driver *drv)
|
||||
@ -548,6 +548,64 @@ int __init_or_module platform_driver_probe(struct platform_driver *drv,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(platform_driver_probe);
|
||||
|
||||
/**
|
||||
* platform_create_bundle - register driver and create corresponding device
|
||||
* @driver: platform driver structure
|
||||
* @probe: the driver probe routine, probably from an __init section
|
||||
* @res: set of resources that needs to be allocated for the device
|
||||
* @n_res: number of resources
|
||||
* @data: platform specific data for this platform device
|
||||
* @size: size of platform specific data
|
||||
*
|
||||
* Use this in legacy-style modules that probe hardware directly and
|
||||
* register a single platform device and corresponding platform driver.
|
||||
*/
|
||||
struct platform_device * __init_or_module platform_create_bundle(
|
||||
struct platform_driver *driver,
|
||||
int (*probe)(struct platform_device *),
|
||||
struct resource *res, unsigned int n_res,
|
||||
const void *data, size_t size)
|
||||
{
|
||||
struct platform_device *pdev;
|
||||
int error;
|
||||
|
||||
pdev = platform_device_alloc(driver->driver.name, -1);
|
||||
if (!pdev) {
|
||||
error = -ENOMEM;
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
if (res) {
|
||||
error = platform_device_add_resources(pdev, res, n_res);
|
||||
if (error)
|
||||
goto err_pdev_put;
|
||||
}
|
||||
|
||||
if (data) {
|
||||
error = platform_device_add_data(pdev, data, size);
|
||||
if (error)
|
||||
goto err_pdev_put;
|
||||
}
|
||||
|
||||
error = platform_device_add(pdev);
|
||||
if (error)
|
||||
goto err_pdev_put;
|
||||
|
||||
error = platform_driver_probe(driver, probe);
|
||||
if (error)
|
||||
goto err_pdev_del;
|
||||
|
||||
return pdev;
|
||||
|
||||
err_pdev_del:
|
||||
platform_device_del(pdev);
|
||||
err_pdev_put:
|
||||
platform_device_put(pdev);
|
||||
err_out:
|
||||
return ERR_PTR(error);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(platform_create_bundle);
|
||||
|
||||
/* modalias support enables more hands-off userspace setup:
|
||||
* (a) environment variable lets new-style hotplug events work once system is
|
||||
* fully running: "modprobe $MODALIAS"
|
||||
@ -578,7 +636,7 @@ static int platform_uevent(struct device *dev, struct kobj_uevent_env *env)
|
||||
}
|
||||
|
||||
static const struct platform_device_id *platform_match_id(
|
||||
struct platform_device_id *id,
|
||||
const struct platform_device_id *id,
|
||||
struct platform_device *pdev)
|
||||
{
|
||||
while (id->name[0]) {
|
||||
|
@ -35,8 +35,8 @@
|
||||
* because children are guaranteed to be discovered after parents, and
|
||||
* are inserted at the back of the list on discovery.
|
||||
*
|
||||
* Since device_pm_add() may be called with a device semaphore held,
|
||||
* we must never try to acquire a device semaphore while holding
|
||||
* Since device_pm_add() may be called with a device lock held,
|
||||
* we must never try to acquire a device lock while holding
|
||||
* dpm_list_mutex.
|
||||
*/
|
||||
|
||||
@ -508,7 +508,7 @@ static int device_resume(struct device *dev, pm_message_t state, bool async)
|
||||
TRACE_RESUME(0);
|
||||
|
||||
dpm_wait(dev->parent, async);
|
||||
down(&dev->sem);
|
||||
device_lock(dev);
|
||||
|
||||
dev->power.status = DPM_RESUMING;
|
||||
|
||||
@ -543,7 +543,7 @@ static int device_resume(struct device *dev, pm_message_t state, bool async)
|
||||
}
|
||||
}
|
||||
End:
|
||||
up(&dev->sem);
|
||||
device_unlock(dev);
|
||||
complete_all(&dev->power.completion);
|
||||
|
||||
TRACE_RESUME(error);
|
||||
@ -629,7 +629,7 @@ static void dpm_resume(pm_message_t state)
|
||||
*/
|
||||
static void device_complete(struct device *dev, pm_message_t state)
|
||||
{
|
||||
down(&dev->sem);
|
||||
device_lock(dev);
|
||||
|
||||
if (dev->class && dev->class->pm && dev->class->pm->complete) {
|
||||
pm_dev_dbg(dev, state, "completing class ");
|
||||
@ -646,7 +646,7 @@ static void device_complete(struct device *dev, pm_message_t state)
|
||||
dev->bus->pm->complete(dev);
|
||||
}
|
||||
|
||||
up(&dev->sem);
|
||||
device_unlock(dev);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -809,7 +809,7 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async)
|
||||
int error = 0;
|
||||
|
||||
dpm_wait_for_children(dev, async);
|
||||
down(&dev->sem);
|
||||
device_lock(dev);
|
||||
|
||||
if (async_error)
|
||||
goto End;
|
||||
@ -849,7 +849,7 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async)
|
||||
dev->power.status = DPM_OFF;
|
||||
|
||||
End:
|
||||
up(&dev->sem);
|
||||
device_unlock(dev);
|
||||
complete_all(&dev->power.completion);
|
||||
|
||||
return error;
|
||||
@ -938,7 +938,7 @@ static int device_prepare(struct device *dev, pm_message_t state)
|
||||
{
|
||||
int error = 0;
|
||||
|
||||
down(&dev->sem);
|
||||
device_lock(dev);
|
||||
|
||||
if (dev->bus && dev->bus->pm && dev->bus->pm->prepare) {
|
||||
pm_dev_dbg(dev, state, "preparing ");
|
||||
@ -962,7 +962,7 @@ static int device_prepare(struct device *dev, pm_message_t state)
|
||||
suspend_report_result(dev->class->pm->prepare, error);
|
||||
}
|
||||
End:
|
||||
up(&dev->sem);
|
||||
device_unlock(dev);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ sysdev_store(struct kobject *kobj, struct attribute *attr,
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
static struct sysfs_ops sysfs_ops = {
|
||||
static const struct sysfs_ops sysfs_ops = {
|
||||
.show = sysdev_show,
|
||||
.store = sysdev_store,
|
||||
};
|
||||
@ -89,7 +89,7 @@ static ssize_t sysdev_class_show(struct kobject *kobj, struct attribute *attr,
|
||||
struct sysdev_class_attribute *class_attr = to_sysdev_class_attr(attr);
|
||||
|
||||
if (class_attr->show)
|
||||
return class_attr->show(class, buffer);
|
||||
return class_attr->show(class, class_attr, buffer);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
@ -100,11 +100,11 @@ static ssize_t sysdev_class_store(struct kobject *kobj, struct attribute *attr,
|
||||
struct sysdev_class_attribute *class_attr = to_sysdev_class_attr(attr);
|
||||
|
||||
if (class_attr->store)
|
||||
return class_attr->store(class, buffer, count);
|
||||
return class_attr->store(class, class_attr, buffer, count);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
static struct sysfs_ops sysfs_class_ops = {
|
||||
static const struct sysfs_ops sysfs_class_ops = {
|
||||
.show = sysdev_class_show,
|
||||
.store = sysdev_class_store,
|
||||
};
|
||||
@ -145,13 +145,20 @@ int sysdev_class_register(struct sysdev_class *cls)
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
return kset_register(&cls->kset);
|
||||
retval = kset_register(&cls->kset);
|
||||
if (!retval && cls->attrs)
|
||||
retval = sysfs_create_files(&cls->kset.kobj,
|
||||
(const struct attribute **)cls->attrs);
|
||||
return retval;
|
||||
}
|
||||
|
||||
void sysdev_class_unregister(struct sysdev_class *cls)
|
||||
{
|
||||
pr_debug("Unregistering sysdev class '%s'\n",
|
||||
kobject_name(&cls->kset.kobj));
|
||||
if (cls->attrs)
|
||||
sysfs_remove_files(&cls->kset.kobj,
|
||||
(const struct attribute **)cls->attrs);
|
||||
kset_unregister(&cls->kset);
|
||||
}
|
||||
|
||||
|
@ -476,7 +476,9 @@ static void class_osdblk_release(struct class *cls)
|
||||
kfree(cls);
|
||||
}
|
||||
|
||||
static ssize_t class_osdblk_list(struct class *c, char *data)
|
||||
static ssize_t class_osdblk_list(struct class *c,
|
||||
struct class_attribute *attr,
|
||||
char *data)
|
||||
{
|
||||
int n = 0;
|
||||
struct list_head *tmp;
|
||||
@ -500,7 +502,9 @@ static ssize_t class_osdblk_list(struct class *c, char *data)
|
||||
return n;
|
||||
}
|
||||
|
||||
static ssize_t class_osdblk_add(struct class *c, const char *buf, size_t count)
|
||||
static ssize_t class_osdblk_add(struct class *c,
|
||||
struct class_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct osdblk_device *osdev;
|
||||
ssize_t rc;
|
||||
@ -592,7 +596,9 @@ err_out_mod:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static ssize_t class_osdblk_remove(struct class *c, const char *buf,
|
||||
static ssize_t class_osdblk_remove(struct class *c,
|
||||
struct class_attribute *attr,
|
||||
const char *buf,
|
||||
size_t count)
|
||||
{
|
||||
struct osdblk_device *osdev = NULL;
|
||||
|
@ -284,7 +284,7 @@ static ssize_t kobj_pkt_store(struct kobject *kobj,
|
||||
return len;
|
||||
}
|
||||
|
||||
static struct sysfs_ops kobj_pkt_ops = {
|
||||
static const struct sysfs_ops kobj_pkt_ops = {
|
||||
.show = kobj_pkt_show,
|
||||
.store = kobj_pkt_store
|
||||
};
|
||||
@ -337,7 +337,9 @@ static void class_pktcdvd_release(struct class *cls)
|
||||
{
|
||||
kfree(cls);
|
||||
}
|
||||
static ssize_t class_pktcdvd_show_map(struct class *c, char *data)
|
||||
static ssize_t class_pktcdvd_show_map(struct class *c,
|
||||
struct class_attribute *attr,
|
||||
char *data)
|
||||
{
|
||||
int n = 0;
|
||||
int idx;
|
||||
@ -356,7 +358,9 @@ static ssize_t class_pktcdvd_show_map(struct class *c, char *data)
|
||||
return n;
|
||||
}
|
||||
|
||||
static ssize_t class_pktcdvd_store_add(struct class *c, const char *buf,
|
||||
static ssize_t class_pktcdvd_store_add(struct class *c,
|
||||
struct class_attribute *attr,
|
||||
const char *buf,
|
||||
size_t count)
|
||||
{
|
||||
unsigned int major, minor;
|
||||
@ -376,7 +380,9 @@ static ssize_t class_pktcdvd_store_add(struct class *c, const char *buf,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static ssize_t class_pktcdvd_store_remove(struct class *c, const char *buf,
|
||||
static ssize_t class_pktcdvd_store_remove(struct class *c,
|
||||
struct class_attribute *attr,
|
||||
const char *buf,
|
||||
size_t count)
|
||||
{
|
||||
unsigned int major, minor;
|
||||
|
@ -766,7 +766,7 @@ static void cpufreq_sysfs_release(struct kobject *kobj)
|
||||
complete(&policy->kobj_unregister);
|
||||
}
|
||||
|
||||
static struct sysfs_ops sysfs_ops = {
|
||||
static const struct sysfs_ops sysfs_ops = {
|
||||
.show = show,
|
||||
.store = store,
|
||||
};
|
||||
|
@ -22,6 +22,7 @@ static int __init cpuidle_sysfs_setup(char *unused)
|
||||
__setup("cpuidle_sysfs_switch", cpuidle_sysfs_setup);
|
||||
|
||||
static ssize_t show_available_governors(struct sysdev_class *class,
|
||||
struct sysdev_class_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
ssize_t i = 0;
|
||||
@ -41,6 +42,7 @@ out:
|
||||
}
|
||||
|
||||
static ssize_t show_current_driver(struct sysdev_class *class,
|
||||
struct sysdev_class_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
ssize_t ret;
|
||||
@ -56,6 +58,7 @@ static ssize_t show_current_driver(struct sysdev_class *class,
|
||||
}
|
||||
|
||||
static ssize_t show_current_governor(struct sysdev_class *class,
|
||||
struct sysdev_class_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
ssize_t ret;
|
||||
@ -71,6 +74,7 @@ static ssize_t show_current_governor(struct sysdev_class *class,
|
||||
}
|
||||
|
||||
static ssize_t store_current_governor(struct sysdev_class *class,
|
||||
struct sysdev_class_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
char gov_name[CPUIDLE_NAME_LEN];
|
||||
@ -191,7 +195,7 @@ static ssize_t cpuidle_store(struct kobject * kobj, struct attribute * attr,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct sysfs_ops cpuidle_sysfs_ops = {
|
||||
static const struct sysfs_ops cpuidle_sysfs_ops = {
|
||||
.show = cpuidle_show,
|
||||
.store = cpuidle_store,
|
||||
};
|
||||
@ -277,7 +281,7 @@ static ssize_t cpuidle_state_show(struct kobject * kobj,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct sysfs_ops cpuidle_state_sysfs_ops = {
|
||||
static const struct sysfs_ops cpuidle_state_sysfs_ops = {
|
||||
.show = cpuidle_state_show,
|
||||
};
|
||||
|
||||
|
@ -1138,7 +1138,7 @@ ioat_attr_show(struct kobject *kobj, struct attribute *attr, char *page)
|
||||
return entry->show(&chan->common, page);
|
||||
}
|
||||
|
||||
struct sysfs_ops ioat_sysfs_ops = {
|
||||
const struct sysfs_ops ioat_sysfs_ops = {
|
||||
.show = ioat_attr_show,
|
||||
};
|
||||
|
||||
|
@ -346,7 +346,7 @@ bool ioat_cleanup_preamble(struct ioat_chan_common *chan,
|
||||
unsigned long *phys_complete);
|
||||
void ioat_kobject_add(struct ioatdma_device *device, struct kobj_type *type);
|
||||
void ioat_kobject_del(struct ioatdma_device *device);
|
||||
extern struct sysfs_ops ioat_sysfs_ops;
|
||||
extern const struct sysfs_ops ioat_sysfs_ops;
|
||||
extern struct ioat_sysfs_entry ioat_version_attr;
|
||||
extern struct ioat_sysfs_entry ioat_cap_attr;
|
||||
#endif /* IOATDMA_H */
|
||||
|
@ -137,7 +137,7 @@ static ssize_t edac_dev_ctl_info_store(struct kobject *kobj,
|
||||
}
|
||||
|
||||
/* edac_dev file operations for an 'ctl_info' */
|
||||
static struct sysfs_ops device_ctl_info_ops = {
|
||||
static const struct sysfs_ops device_ctl_info_ops = {
|
||||
.show = edac_dev_ctl_info_show,
|
||||
.store = edac_dev_ctl_info_store
|
||||
};
|
||||
@ -373,7 +373,7 @@ static ssize_t edac_dev_instance_store(struct kobject *kobj,
|
||||
}
|
||||
|
||||
/* edac_dev file operations for an 'instance' */
|
||||
static struct sysfs_ops device_instance_ops = {
|
||||
static const struct sysfs_ops device_instance_ops = {
|
||||
.show = edac_dev_instance_show,
|
||||
.store = edac_dev_instance_store
|
||||
};
|
||||
@ -476,7 +476,7 @@ static ssize_t edac_dev_block_store(struct kobject *kobj,
|
||||
}
|
||||
|
||||
/* edac_dev file operations for a 'block' */
|
||||
static struct sysfs_ops device_block_ops = {
|
||||
static const struct sysfs_ops device_block_ops = {
|
||||
.show = edac_dev_block_show,
|
||||
.store = edac_dev_block_store
|
||||
};
|
||||
|
@ -245,7 +245,7 @@ static ssize_t csrowdev_store(struct kobject *kobj, struct attribute *attr,
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
static struct sysfs_ops csrowfs_ops = {
|
||||
static const struct sysfs_ops csrowfs_ops = {
|
||||
.show = csrowdev_show,
|
||||
.store = csrowdev_store
|
||||
};
|
||||
@ -575,7 +575,7 @@ static ssize_t mcidev_store(struct kobject *kobj, struct attribute *attr,
|
||||
}
|
||||
|
||||
/* Intermediate show/store table */
|
||||
static struct sysfs_ops mci_ops = {
|
||||
static const struct sysfs_ops mci_ops = {
|
||||
.show = mcidev_show,
|
||||
.store = mcidev_store
|
||||
};
|
||||
|
@ -121,7 +121,7 @@ static ssize_t edac_pci_instance_store(struct kobject *kobj,
|
||||
}
|
||||
|
||||
/* fs_ops table */
|
||||
static struct sysfs_ops pci_instance_ops = {
|
||||
static const struct sysfs_ops pci_instance_ops = {
|
||||
.show = edac_pci_instance_show,
|
||||
.store = edac_pci_instance_store
|
||||
};
|
||||
@ -261,7 +261,7 @@ static ssize_t edac_pci_dev_store(struct kobject *kobj,
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
static struct sysfs_ops edac_pci_sysfs_ops = {
|
||||
static const struct sysfs_ops edac_pci_sysfs_ops = {
|
||||
.show = edac_pci_dev_show,
|
||||
.store = edac_pci_dev_store
|
||||
};
|
||||
|
@ -33,7 +33,6 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/rwsem.h>
|
||||
#include <linux/semaphore.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/workqueue.h>
|
||||
@ -828,9 +827,9 @@ static int update_unit(struct device *dev, void *data)
|
||||
struct fw_driver *driver = (struct fw_driver *)dev->driver;
|
||||
|
||||
if (is_fw_unit(dev) && driver != NULL && driver->update != NULL) {
|
||||
down(&dev->sem);
|
||||
device_lock(dev);
|
||||
driver->update(unit);
|
||||
up(&dev->sem);
|
||||
device_unlock(dev);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -122,7 +122,7 @@ edd_attr_show(struct kobject * kobj, struct attribute *attr, char *buf)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct sysfs_ops edd_attr_ops = {
|
||||
static const struct sysfs_ops edd_attr_ops = {
|
||||
.show = edd_attr_show,
|
||||
};
|
||||
|
||||
|
@ -362,7 +362,7 @@ static ssize_t efivar_attr_store(struct kobject *kobj, struct attribute *attr,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct sysfs_ops efivar_attr_ops = {
|
||||
static const struct sysfs_ops efivar_attr_ops = {
|
||||
.show = efivar_attr_show,
|
||||
.store = efivar_attr_store,
|
||||
};
|
||||
|
@ -519,7 +519,7 @@ static ssize_t ibft_show_attribute(struct kobject *kobj,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct sysfs_ops ibft_attr_ops = {
|
||||
static const struct sysfs_ops ibft_attr_ops = {
|
||||
.show = ibft_show_attribute,
|
||||
};
|
||||
|
||||
|
@ -74,7 +74,7 @@ static struct attribute *def_attrs[] = {
|
||||
NULL
|
||||
};
|
||||
|
||||
static struct sysfs_ops memmap_attr_ops = {
|
||||
static const struct sysfs_ops memmap_attr_ops = {
|
||||
.show = memmap_attr_show,
|
||||
};
|
||||
|
||||
|
@ -623,7 +623,9 @@ static const struct attribute_group gpiochip_attr_group = {
|
||||
* /sys/class/gpio/unexport ... write-only
|
||||
* integer N ... number of GPIO to unexport
|
||||
*/
|
||||
static ssize_t export_store(struct class *class, const char *buf, size_t len)
|
||||
static ssize_t export_store(struct class *class,
|
||||
struct class_attribute *attr,
|
||||
const char *buf, size_t len)
|
||||
{
|
||||
long gpio;
|
||||
int status;
|
||||
@ -653,7 +655,9 @@ done:
|
||||
return status ? : len;
|
||||
}
|
||||
|
||||
static ssize_t unexport_store(struct class *class, const char *buf, size_t len)
|
||||
static ssize_t unexport_store(struct class *class,
|
||||
struct class_attribute *attr,
|
||||
const char *buf, size_t len)
|
||||
{
|
||||
long gpio;
|
||||
int status;
|
||||
|
@ -70,19 +70,17 @@ static int drm_class_resume(struct device *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Display the version of drm_core. This doesn't work right in current design */
|
||||
static ssize_t version_show(struct class *dev, char *buf)
|
||||
{
|
||||
return sprintf(buf, "%s %d.%d.%d %s\n", CORE_NAME, CORE_MAJOR,
|
||||
CORE_MINOR, CORE_PATCHLEVEL, CORE_DATE);
|
||||
}
|
||||
|
||||
static char *drm_devnode(struct device *dev, mode_t *mode)
|
||||
{
|
||||
return kasprintf(GFP_KERNEL, "dri/%s", dev_name(dev));
|
||||
}
|
||||
|
||||
static CLASS_ATTR(version, S_IRUGO, version_show, NULL);
|
||||
static CLASS_ATTR_STRING(version, S_IRUGO,
|
||||
CORE_NAME " "
|
||||
__stringify(CORE_MAJOR) "."
|
||||
__stringify(CORE_MINOR) "."
|
||||
__stringify(CORE_PATCHLEVEL) " "
|
||||
CORE_DATE);
|
||||
|
||||
/**
|
||||
* drm_sysfs_create - create a struct drm_sysfs_class structure
|
||||
@ -109,7 +107,7 @@ struct class *drm_sysfs_create(struct module *owner, char *name)
|
||||
class->suspend = drm_class_suspend;
|
||||
class->resume = drm_class_resume;
|
||||
|
||||
err = class_create_file(class, &class_attr_version);
|
||||
err = class_create_file(class, &class_attr_version.attr);
|
||||
if (err)
|
||||
goto err_out_class;
|
||||
|
||||
@ -132,7 +130,7 @@ void drm_sysfs_destroy(void)
|
||||
{
|
||||
if ((drm_class == NULL) || (IS_ERR(drm_class)))
|
||||
return;
|
||||
class_remove_file(drm_class, &class_attr_version);
|
||||
class_remove_file(drm_class, &class_attr_version.attr);
|
||||
class_destroy(drm_class);
|
||||
}
|
||||
|
||||
|
@ -128,7 +128,7 @@ static struct attribute *ttm_bo_global_attrs[] = {
|
||||
NULL
|
||||
};
|
||||
|
||||
static struct sysfs_ops ttm_bo_global_ops = {
|
||||
static const struct sysfs_ops ttm_bo_global_ops = {
|
||||
.show = &ttm_bo_global_show
|
||||
};
|
||||
|
||||
|
@ -152,7 +152,7 @@ static struct attribute *ttm_mem_zone_attrs[] = {
|
||||
NULL
|
||||
};
|
||||
|
||||
static struct sysfs_ops ttm_mem_zone_ops = {
|
||||
static const struct sysfs_ops ttm_mem_zone_ops = {
|
||||
.show = &ttm_mem_zone_show,
|
||||
.store = &ttm_mem_zone_store
|
||||
};
|
||||
|
@ -850,7 +850,7 @@ static const struct i2c_algorithm omap_i2c_algo = {
|
||||
.functionality = omap_i2c_func,
|
||||
};
|
||||
|
||||
static int __init
|
||||
static int __devinit
|
||||
omap_i2c_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct omap_i2c_dev *dev;
|
||||
|
@ -19,7 +19,6 @@
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/freezer.h>
|
||||
#include <linux/semaphore.h>
|
||||
#include <asm/atomic.h>
|
||||
|
||||
#include "csr.h"
|
||||
@ -1397,9 +1396,9 @@ static int update_pdrv(struct device *dev, void *data)
|
||||
pdrv = container_of(drv, struct hpsb_protocol_driver,
|
||||
driver);
|
||||
if (pdrv->update) {
|
||||
down(&ud->device.sem);
|
||||
device_lock(&ud->device);
|
||||
error = pdrv->update(ud);
|
||||
up(&ud->device.sem);
|
||||
device_unlock(&ud->device);
|
||||
}
|
||||
if (error)
|
||||
device_release_driver(&ud->device);
|
||||
|
@ -3597,7 +3597,7 @@ static ssize_t cm_show_counter(struct kobject *obj, struct attribute *attr,
|
||||
atomic_long_read(&group->counter[cm_attr->index]));
|
||||
}
|
||||
|
||||
static struct sysfs_ops cm_counter_ops = {
|
||||
static const struct sysfs_ops cm_counter_ops = {
|
||||
.show = cm_show_counter
|
||||
};
|
||||
|
||||
|
@ -79,7 +79,7 @@ static ssize_t port_attr_show(struct kobject *kobj,
|
||||
return port_attr->show(p, port_attr, buf);
|
||||
}
|
||||
|
||||
static struct sysfs_ops port_sysfs_ops = {
|
||||
static const struct sysfs_ops port_sysfs_ops = {
|
||||
.show = port_attr_show
|
||||
};
|
||||
|
||||
|
@ -1336,11 +1336,8 @@ static void ib_ucm_remove_one(struct ib_device *device)
|
||||
device_unregister(&ucm_dev->dev);
|
||||
}
|
||||
|
||||
static ssize_t show_abi_version(struct class *class, char *buf)
|
||||
{
|
||||
return sprintf(buf, "%d\n", IB_USER_CM_ABI_VERSION);
|
||||
}
|
||||
static CLASS_ATTR(abi_version, S_IRUGO, show_abi_version, NULL);
|
||||
static CLASS_ATTR_STRING(abi_version, S_IRUGO,
|
||||
__stringify(IB_USER_CM_ABI_VERSION));
|
||||
|
||||
static int __init ib_ucm_init(void)
|
||||
{
|
||||
@ -1353,7 +1350,7 @@ static int __init ib_ucm_init(void)
|
||||
goto error1;
|
||||
}
|
||||
|
||||
ret = class_create_file(&cm_class, &class_attr_abi_version);
|
||||
ret = class_create_file(&cm_class, &class_attr_abi_version.attr);
|
||||
if (ret) {
|
||||
printk(KERN_ERR "ucm: couldn't create abi_version attribute\n");
|
||||
goto error2;
|
||||
@ -1367,7 +1364,7 @@ static int __init ib_ucm_init(void)
|
||||
return 0;
|
||||
|
||||
error3:
|
||||
class_remove_file(&cm_class, &class_attr_abi_version);
|
||||
class_remove_file(&cm_class, &class_attr_abi_version.attr);
|
||||
error2:
|
||||
unregister_chrdev_region(IB_UCM_BASE_DEV, IB_UCM_MAX_DEVICES);
|
||||
error1:
|
||||
@ -1377,7 +1374,7 @@ error1:
|
||||
static void __exit ib_ucm_cleanup(void)
|
||||
{
|
||||
ib_unregister_client(&ucm_client);
|
||||
class_remove_file(&cm_class, &class_attr_abi_version);
|
||||
class_remove_file(&cm_class, &class_attr_abi_version.attr);
|
||||
unregister_chrdev_region(IB_UCM_BASE_DEV, IB_UCM_MAX_DEVICES);
|
||||
if (overflow_maj)
|
||||
unregister_chrdev_region(overflow_maj, IB_UCM_MAX_DEVICES);
|
||||
|
@ -965,11 +965,8 @@ static ssize_t show_port(struct device *dev, struct device_attribute *attr,
|
||||
}
|
||||
static DEVICE_ATTR(port, S_IRUGO, show_port, NULL);
|
||||
|
||||
static ssize_t show_abi_version(struct class *class, char *buf)
|
||||
{
|
||||
return sprintf(buf, "%d\n", IB_USER_MAD_ABI_VERSION);
|
||||
}
|
||||
static CLASS_ATTR(abi_version, S_IRUGO, show_abi_version, NULL);
|
||||
static CLASS_ATTR_STRING(abi_version, S_IRUGO,
|
||||
__stringify(IB_USER_MAD_ABI_VERSION));
|
||||
|
||||
static dev_t overflow_maj;
|
||||
static DECLARE_BITMAP(overflow_map, IB_UMAD_MAX_PORTS);
|
||||
@ -1194,7 +1191,7 @@ static int __init ib_umad_init(void)
|
||||
goto out_chrdev;
|
||||
}
|
||||
|
||||
ret = class_create_file(umad_class, &class_attr_abi_version);
|
||||
ret = class_create_file(umad_class, &class_attr_abi_version.attr);
|
||||
if (ret) {
|
||||
printk(KERN_ERR "user_mad: couldn't create abi_version attribute\n");
|
||||
goto out_class;
|
||||
|
@ -691,11 +691,8 @@ static ssize_t show_dev_abi_version(struct device *device,
|
||||
}
|
||||
static DEVICE_ATTR(abi_version, S_IRUGO, show_dev_abi_version, NULL);
|
||||
|
||||
static ssize_t show_abi_version(struct class *class, char *buf)
|
||||
{
|
||||
return sprintf(buf, "%d\n", IB_USER_VERBS_ABI_VERSION);
|
||||
}
|
||||
static CLASS_ATTR(abi_version, S_IRUGO, show_abi_version, NULL);
|
||||
static CLASS_ATTR_STRING(abi_version, S_IRUGO,
|
||||
__stringify(IB_USER_VERBS_ABI_VERSION));
|
||||
|
||||
static dev_t overflow_maj;
|
||||
static DECLARE_BITMAP(overflow_map, IB_UVERBS_MAX_DEVICES);
|
||||
@ -841,7 +838,7 @@ static int __init ib_uverbs_init(void)
|
||||
goto out_chrdev;
|
||||
}
|
||||
|
||||
ret = class_create_file(uverbs_class, &class_attr_abi_version);
|
||||
ret = class_create_file(uverbs_class, &class_attr_abi_version.attr);
|
||||
if (ret) {
|
||||
printk(KERN_ERR "user_verbs: couldn't create abi_version attribute\n");
|
||||
goto out_class;
|
||||
|
@ -321,6 +321,7 @@ int wf_register_sensor(struct wf_sensor *new_sr)
|
||||
kref_init(&new_sr->ref);
|
||||
list_add(&new_sr->link, &wf_sensors);
|
||||
|
||||
sysfs_attr_init(&new_sr->attr.attr);
|
||||
new_sr->attr.attr.name = new_sr->name;
|
||||
new_sr->attr.attr.mode = 0444;
|
||||
new_sr->attr.show = wf_show_sensor;
|
||||
|
@ -173,6 +173,7 @@ static struct smu_fan_control *smu_fan_create(struct device_node *node,
|
||||
|
||||
fct->fan_type = pwm_fan;
|
||||
fct->ctrl.type = pwm_fan ? WF_CONTROL_PWM_FAN : WF_CONTROL_RPM_FAN;
|
||||
sysfs_attr_init(&fct->ctrl.attr.attr);
|
||||
|
||||
/* We use the name & location here the same way we do for SMU sensors,
|
||||
* see the comment in windfarm_smu_sensors.c. The locations are a bit
|
||||
|
@ -75,7 +75,7 @@ static struct attribute *dm_attrs[] = {
|
||||
NULL,
|
||||
};
|
||||
|
||||
static struct sysfs_ops dm_sysfs_ops = {
|
||||
static const struct sysfs_ops dm_sysfs_ops = {
|
||||
.show = dm_attr_show,
|
||||
};
|
||||
|
||||
|
@ -2642,7 +2642,7 @@ static void rdev_free(struct kobject *ko)
|
||||
mdk_rdev_t *rdev = container_of(ko, mdk_rdev_t, kobj);
|
||||
kfree(rdev);
|
||||
}
|
||||
static struct sysfs_ops rdev_sysfs_ops = {
|
||||
static const struct sysfs_ops rdev_sysfs_ops = {
|
||||
.show = rdev_attr_show,
|
||||
.store = rdev_attr_store,
|
||||
};
|
||||
@ -4059,7 +4059,7 @@ static void md_free(struct kobject *ko)
|
||||
kfree(mddev);
|
||||
}
|
||||
|
||||
static struct sysfs_ops md_sysfs_ops = {
|
||||
static const struct sysfs_ops md_sysfs_ops = {
|
||||
.show = md_attr_show,
|
||||
.store = md_attr_store,
|
||||
};
|
||||
|
@ -1735,7 +1735,7 @@ static struct v4l2_int_device omap24xxcam = {
|
||||
*
|
||||
*/
|
||||
|
||||
static int __init omap24xxcam_probe(struct platform_device *pdev)
|
||||
static int __devinit omap24xxcam_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct omap24xxcam_device *cam;
|
||||
struct resource *mem;
|
||||
|
@ -497,12 +497,7 @@ static struct pci_driver phantom_pci_driver = {
|
||||
.resume = phantom_resume
|
||||
};
|
||||
|
||||
static ssize_t phantom_show_version(struct class *cls, char *buf)
|
||||
{
|
||||
return sprintf(buf, PHANTOM_VERSION "\n");
|
||||
}
|
||||
|
||||
static CLASS_ATTR(version, 0444, phantom_show_version, NULL);
|
||||
static CLASS_ATTR_STRING(version, 0444, PHANTOM_VERSION);
|
||||
|
||||
static int __init phantom_init(void)
|
||||
{
|
||||
@ -515,7 +510,7 @@ static int __init phantom_init(void)
|
||||
printk(KERN_ERR "phantom: can't register phantom class\n");
|
||||
goto err;
|
||||
}
|
||||
retval = class_create_file(phantom_class, &class_attr_version);
|
||||
retval = class_create_file(phantom_class, &class_attr_version.attr);
|
||||
if (retval) {
|
||||
printk(KERN_ERR "phantom: can't create sysfs version file\n");
|
||||
goto err_class;
|
||||
@ -541,7 +536,7 @@ static int __init phantom_init(void)
|
||||
err_unchr:
|
||||
unregister_chrdev_region(dev, PHANTOM_MAX_MINORS);
|
||||
err_attr:
|
||||
class_remove_file(phantom_class, &class_attr_version);
|
||||
class_remove_file(phantom_class, &class_attr_version.attr);
|
||||
err_class:
|
||||
class_destroy(phantom_class);
|
||||
err:
|
||||
@ -554,7 +549,7 @@ static void __exit phantom_exit(void)
|
||||
|
||||
unregister_chrdev_region(MKDEV(phantom_major, 0), PHANTOM_MAX_MINORS);
|
||||
|
||||
class_remove_file(phantom_class, &class_attr_version);
|
||||
class_remove_file(phantom_class, &class_attr_version.attr);
|
||||
class_destroy(phantom_class);
|
||||
|
||||
pr_debug("phantom: module successfully removed\n");
|
||||
|
@ -89,7 +89,8 @@ DEFINE_MUTEX(ubi_devices_mutex);
|
||||
static DEFINE_SPINLOCK(ubi_devices_lock);
|
||||
|
||||
/* "Show" method for files in '/<sysfs>/class/ubi/' */
|
||||
static ssize_t ubi_version_show(struct class *class, char *buf)
|
||||
static ssize_t ubi_version_show(struct class *class, struct class_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
return sprintf(buf, "%d\n", UBI_VERSION);
|
||||
}
|
||||
|
@ -51,7 +51,9 @@
|
||||
* "show" function for the bond_masters attribute.
|
||||
* The class parameter is ignored.
|
||||
*/
|
||||
static ssize_t bonding_show_bonds(struct class *cls, char *buf)
|
||||
static ssize_t bonding_show_bonds(struct class *cls,
|
||||
struct class_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct net *net = current->nsproxy->net_ns;
|
||||
struct bond_net *bn = net_generic(net, bond_net_id);
|
||||
@ -98,6 +100,7 @@ static struct net_device *bond_get_by_name(struct net *net, const char *ifname)
|
||||
*/
|
||||
|
||||
static ssize_t bonding_store_bonds(struct class *cls,
|
||||
struct class_attribute *attr,
|
||||
const char *buffer, size_t count)
|
||||
{
|
||||
struct net *net = current->nsproxy->net_ns;
|
||||
|
@ -1577,7 +1577,7 @@ static struct attribute * veth_pool_attrs[] = {
|
||||
NULL,
|
||||
};
|
||||
|
||||
static struct sysfs_ops veth_pool_ops = {
|
||||
static const struct sysfs_ops veth_pool_ops = {
|
||||
.show = veth_pool_show,
|
||||
.store = veth_pool_store,
|
||||
};
|
||||
|
@ -384,7 +384,7 @@ static struct attribute *veth_cnx_default_attrs[] = {
|
||||
NULL
|
||||
};
|
||||
|
||||
static struct sysfs_ops veth_cnx_sysfs_ops = {
|
||||
static const struct sysfs_ops veth_cnx_sysfs_ops = {
|
||||
.show = veth_cnx_attribute_show
|
||||
};
|
||||
|
||||
@ -441,7 +441,7 @@ static struct attribute *veth_port_default_attrs[] = {
|
||||
NULL
|
||||
};
|
||||
|
||||
static struct sysfs_ops veth_port_sysfs_ops = {
|
||||
static const struct sysfs_ops veth_port_sysfs_ops = {
|
||||
.show = veth_port_attribute_show
|
||||
};
|
||||
|
||||
|
@ -481,7 +481,7 @@ pdcspath_attr_store(struct kobject *kobj, struct attribute *attr,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct sysfs_ops pdcspath_attr_ops = {
|
||||
static const struct sysfs_ops pdcspath_attr_ops = {
|
||||
.show = pdcspath_attr_show,
|
||||
.store = pdcspath_attr_store,
|
||||
};
|
||||
|
@ -288,9 +288,9 @@ void pci_walk_bus(struct pci_bus *top, int (*cb)(struct pci_dev *, void *),
|
||||
next = dev->bus_list.next;
|
||||
|
||||
/* Run device routines with the device locked */
|
||||
down(&dev->dev.sem);
|
||||
device_lock(&dev->dev);
|
||||
retval = cb(dev, userdata);
|
||||
up(&dev->dev.sem);
|
||||
device_unlock(&dev->dev);
|
||||
if (retval)
|
||||
break;
|
||||
}
|
||||
|
@ -73,7 +73,7 @@ static void legacy_release(struct kobject *kobj)
|
||||
}
|
||||
|
||||
static struct kobj_type legacy_ktype = {
|
||||
.sysfs_ops = &(struct sysfs_ops){
|
||||
.sysfs_ops = &(const struct sysfs_ops){
|
||||
.store = legacy_store, .show = legacy_show
|
||||
},
|
||||
.release = &legacy_release,
|
||||
|
@ -642,6 +642,7 @@ void pci_create_legacy_files(struct pci_bus *b)
|
||||
if (!b->legacy_io)
|
||||
goto kzalloc_err;
|
||||
|
||||
sysfs_bin_attr_init(b->legacy_io);
|
||||
b->legacy_io->attr.name = "legacy_io";
|
||||
b->legacy_io->size = 0xffff;
|
||||
b->legacy_io->attr.mode = S_IRUSR | S_IWUSR;
|
||||
@ -654,6 +655,7 @@ void pci_create_legacy_files(struct pci_bus *b)
|
||||
goto legacy_io_err;
|
||||
|
||||
/* Allocated above after the legacy_io struct */
|
||||
sysfs_bin_attr_init(b->legacy_mem);
|
||||
b->legacy_mem = b->legacy_io + 1;
|
||||
b->legacy_mem->attr.name = "legacy_mem";
|
||||
b->legacy_mem->size = 1024*1024;
|
||||
@ -800,6 +802,7 @@ static int pci_create_attr(struct pci_dev *pdev, int num, int write_combine)
|
||||
if (res_attr) {
|
||||
char *res_attr_name = (char *)(res_attr + 1);
|
||||
|
||||
sysfs_bin_attr_init(res_attr);
|
||||
if (write_combine) {
|
||||
pdev->res_attr_wc[num] = res_attr;
|
||||
sprintf(res_attr_name, "resource%d_wc", num);
|
||||
@ -972,6 +975,7 @@ static int pci_create_capabilities_sysfs(struct pci_dev *dev)
|
||||
if (!attr)
|
||||
return -ENOMEM;
|
||||
|
||||
sysfs_bin_attr_init(attr);
|
||||
attr->size = dev->vpd->len;
|
||||
attr->attr.name = "vpd";
|
||||
attr->attr.mode = S_IRUSR | S_IWUSR;
|
||||
@ -1038,6 +1042,7 @@ int __must_check pci_create_sysfs_dev_files (struct pci_dev *pdev)
|
||||
retval = -ENOMEM;
|
||||
goto err_resource_files;
|
||||
}
|
||||
sysfs_bin_attr_init(attr);
|
||||
attr->size = rom_size;
|
||||
attr->attr.name = "rom";
|
||||
attr->attr.mode = S_IRUSR;
|
||||
|
@ -2486,7 +2486,7 @@ static int pci_dev_reset(struct pci_dev *dev, int probe)
|
||||
if (!probe) {
|
||||
pci_block_user_cfg_access(dev);
|
||||
/* block PM suspend, driver probe, etc. */
|
||||
down(&dev->dev.sem);
|
||||
device_lock(&dev->dev);
|
||||
}
|
||||
|
||||
rc = pci_dev_specific_reset(dev, probe);
|
||||
@ -2508,7 +2508,7 @@ static int pci_dev_reset(struct pci_dev *dev, int probe)
|
||||
rc = pci_parent_bus_reset(dev, probe);
|
||||
done:
|
||||
if (!probe) {
|
||||
up(&dev->dev.sem);
|
||||
device_unlock(&dev->dev);
|
||||
pci_unblock_user_cfg_access(dev);
|
||||
}
|
||||
|
||||
|
@ -29,7 +29,7 @@ static ssize_t pci_slot_attr_store(struct kobject *kobj,
|
||||
return attribute->store ? attribute->store(slot, buf, len) : -EIO;
|
||||
}
|
||||
|
||||
static struct sysfs_ops pci_slot_sysfs_ops = {
|
||||
static const struct sysfs_ops pci_slot_sysfs_ops = {
|
||||
.show = pci_slot_attr_show,
|
||||
.store = pci_slot_attr_store,
|
||||
};
|
||||
|
@ -971,9 +971,9 @@ static int runtime_suspend(struct device *dev)
|
||||
{
|
||||
int rc;
|
||||
|
||||
down(&dev->sem);
|
||||
device_lock(dev);
|
||||
rc = pcmcia_dev_suspend(dev, PMSG_SUSPEND);
|
||||
up(&dev->sem);
|
||||
device_unlock(dev);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -981,9 +981,9 @@ static int runtime_resume(struct device *dev)
|
||||
{
|
||||
int rc;
|
||||
|
||||
down(&dev->sem);
|
||||
device_lock(dev);
|
||||
rc = pcmcia_dev_resume(dev);
|
||||
up(&dev->sem);
|
||||
device_unlock(dev);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@ -150,6 +150,7 @@ config MSI_LAPTOP
|
||||
tristate "MSI Laptop Extras"
|
||||
depends on ACPI
|
||||
depends on BACKLIGHT_CLASS_DEVICE
|
||||
depends on RFKILL
|
||||
---help---
|
||||
This is a driver for laptops built by MSI (MICRO-STAR
|
||||
INTERNATIONAL):
|
||||
|
@ -57,7 +57,7 @@ enum hp_wmi_radio {
|
||||
HPWMI_WWAN = 2,
|
||||
};
|
||||
|
||||
static int __init hp_wmi_bios_setup(struct platform_device *device);
|
||||
static int __devinit hp_wmi_bios_setup(struct platform_device *device);
|
||||
static int __exit hp_wmi_bios_remove(struct platform_device *device);
|
||||
static int hp_wmi_resume_handler(struct device *device);
|
||||
|
||||
@ -447,7 +447,7 @@ static void cleanup_sysfs(struct platform_device *device)
|
||||
device_remove_file(&device->dev, &dev_attr_tablet);
|
||||
}
|
||||
|
||||
static int __init hp_wmi_bios_setup(struct platform_device *device)
|
||||
static int __devinit hp_wmi_bios_setup(struct platform_device *device)
|
||||
{
|
||||
int err;
|
||||
int wireless = hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 0, 0);
|
||||
|
@ -58,6 +58,7 @@
|
||||
#include <linux/dmi.h>
|
||||
#include <linux/backlight.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/rfkill.h>
|
||||
|
||||
#define MSI_DRIVER_VERSION "0.5"
|
||||
|
||||
@ -66,6 +67,20 @@
|
||||
#define MSI_EC_COMMAND_WIRELESS 0x10
|
||||
#define MSI_EC_COMMAND_LCD_LEVEL 0x11
|
||||
|
||||
#define MSI_STANDARD_EC_COMMAND_ADDRESS 0x2e
|
||||
#define MSI_STANDARD_EC_BLUETOOTH_MASK (1 << 0)
|
||||
#define MSI_STANDARD_EC_WEBCAM_MASK (1 << 1)
|
||||
#define MSI_STANDARD_EC_WLAN_MASK (1 << 3)
|
||||
#define MSI_STANDARD_EC_3G_MASK (1 << 4)
|
||||
|
||||
/* For set SCM load flag to disable BIOS fn key */
|
||||
#define MSI_STANDARD_EC_SCM_LOAD_ADDRESS 0x2d
|
||||
#define MSI_STANDARD_EC_SCM_LOAD_MASK (1 << 0)
|
||||
|
||||
static int msi_laptop_resume(struct platform_device *device);
|
||||
|
||||
#define MSI_STANDARD_EC_DEVICES_EXISTS_ADDRESS 0x2f
|
||||
|
||||
static int force;
|
||||
module_param(force, bool, 0);
|
||||
MODULE_PARM_DESC(force, "Force driver load, ignore DMI data");
|
||||
@ -74,6 +89,23 @@ static int auto_brightness;
|
||||
module_param(auto_brightness, int, 0);
|
||||
MODULE_PARM_DESC(auto_brightness, "Enable automatic brightness control (0: disabled; 1: enabled; 2: don't touch)");
|
||||
|
||||
static bool old_ec_model;
|
||||
static int wlan_s, bluetooth_s, threeg_s;
|
||||
static int threeg_exists;
|
||||
|
||||
/* Some MSI 3G netbook only have one fn key to control Wlan/Bluetooth/3G,
|
||||
* those netbook will load the SCM (windows app) to disable the original
|
||||
* Wlan/Bluetooth control by BIOS when user press fn key, then control
|
||||
* Wlan/Bluetooth/3G by SCM (software control by OS). Without SCM, user
|
||||
* cann't on/off 3G module on those 3G netbook.
|
||||
* On Linux, msi-laptop driver will do the same thing to disable the
|
||||
* original BIOS control, then might need use HAL or other userland
|
||||
* application to do the software control that simulate with SCM.
|
||||
* e.g. MSI N034 netbook
|
||||
*/
|
||||
static bool load_scm_model;
|
||||
static struct rfkill *rfk_wlan, *rfk_bluetooth, *rfk_threeg;
|
||||
|
||||
/* Hardware access */
|
||||
|
||||
static int set_lcd_level(int level)
|
||||
@ -130,6 +162,35 @@ static int set_auto_brightness(int enable)
|
||||
return ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, wdata, 2, NULL, 0, 1);
|
||||
}
|
||||
|
||||
static ssize_t set_device_state(const char *buf, size_t count, u8 mask)
|
||||
{
|
||||
int status;
|
||||
u8 wdata = 0, rdata;
|
||||
int result;
|
||||
|
||||
if (sscanf(buf, "%i", &status) != 1 || (status < 0 || status > 1))
|
||||
return -EINVAL;
|
||||
|
||||
/* read current device state */
|
||||
result = ec_read(MSI_STANDARD_EC_COMMAND_ADDRESS, &rdata);
|
||||
if (result < 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (!!(rdata & mask) != status) {
|
||||
/* reverse device bit */
|
||||
if (rdata & mask)
|
||||
wdata = rdata & ~mask;
|
||||
else
|
||||
wdata = rdata | mask;
|
||||
|
||||
result = ec_write(MSI_STANDARD_EC_COMMAND_ADDRESS, wdata);
|
||||
if (result < 0)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static int get_wireless_state(int *wlan, int *bluetooth)
|
||||
{
|
||||
u8 wdata = 0, rdata;
|
||||
@ -148,6 +209,38 @@ static int get_wireless_state(int *wlan, int *bluetooth)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_wireless_state_ec_standard(void)
|
||||
{
|
||||
u8 rdata;
|
||||
int result;
|
||||
|
||||
result = ec_read(MSI_STANDARD_EC_COMMAND_ADDRESS, &rdata);
|
||||
if (result < 0)
|
||||
return -1;
|
||||
|
||||
wlan_s = !!(rdata & MSI_STANDARD_EC_WLAN_MASK);
|
||||
|
||||
bluetooth_s = !!(rdata & MSI_STANDARD_EC_BLUETOOTH_MASK);
|
||||
|
||||
threeg_s = !!(rdata & MSI_STANDARD_EC_3G_MASK);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_threeg_exists(void)
|
||||
{
|
||||
u8 rdata;
|
||||
int result;
|
||||
|
||||
result = ec_read(MSI_STANDARD_EC_DEVICES_EXISTS_ADDRESS, &rdata);
|
||||
if (result < 0)
|
||||
return -1;
|
||||
|
||||
threeg_exists = !!(rdata & MSI_STANDARD_EC_3G_MASK);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Backlight device stuff */
|
||||
|
||||
static int bl_get_brightness(struct backlight_device *b)
|
||||
@ -176,26 +269,71 @@ static ssize_t show_wlan(struct device *dev,
|
||||
|
||||
int ret, enabled;
|
||||
|
||||
ret = get_wireless_state(&enabled, NULL);
|
||||
if (old_ec_model) {
|
||||
ret = get_wireless_state(&enabled, NULL);
|
||||
} else {
|
||||
ret = get_wireless_state_ec_standard();
|
||||
enabled = wlan_s;
|
||||
}
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return sprintf(buf, "%i\n", enabled);
|
||||
}
|
||||
|
||||
static ssize_t store_wlan(struct device *dev,
|
||||
struct device_attribute *attr, const char *buf, size_t count)
|
||||
{
|
||||
return set_device_state(buf, count, MSI_STANDARD_EC_WLAN_MASK);
|
||||
}
|
||||
|
||||
static ssize_t show_bluetooth(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
|
||||
int ret, enabled;
|
||||
|
||||
ret = get_wireless_state(NULL, &enabled);
|
||||
if (old_ec_model) {
|
||||
ret = get_wireless_state(NULL, &enabled);
|
||||
} else {
|
||||
ret = get_wireless_state_ec_standard();
|
||||
enabled = bluetooth_s;
|
||||
}
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return sprintf(buf, "%i\n", enabled);
|
||||
}
|
||||
|
||||
static ssize_t store_bluetooth(struct device *dev,
|
||||
struct device_attribute *attr, const char *buf, size_t count)
|
||||
{
|
||||
return set_device_state(buf, count, MSI_STANDARD_EC_BLUETOOTH_MASK);
|
||||
}
|
||||
|
||||
static ssize_t show_threeg(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
|
||||
int ret;
|
||||
|
||||
/* old msi ec not support 3G */
|
||||
if (old_ec_model)
|
||||
return -1;
|
||||
|
||||
ret = get_wireless_state_ec_standard();
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return sprintf(buf, "%i\n", threeg_s);
|
||||
}
|
||||
|
||||
static ssize_t store_threeg(struct device *dev,
|
||||
struct device_attribute *attr, const char *buf, size_t count)
|
||||
{
|
||||
return set_device_state(buf, count, MSI_STANDARD_EC_3G_MASK);
|
||||
}
|
||||
|
||||
static ssize_t show_lcd_level(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
@ -258,6 +396,7 @@ static DEVICE_ATTR(lcd_level, 0644, show_lcd_level, store_lcd_level);
|
||||
static DEVICE_ATTR(auto_brightness, 0644, show_auto_brightness, store_auto_brightness);
|
||||
static DEVICE_ATTR(bluetooth, 0444, show_bluetooth, NULL);
|
||||
static DEVICE_ATTR(wlan, 0444, show_wlan, NULL);
|
||||
static DEVICE_ATTR(threeg, 0444, show_threeg, NULL);
|
||||
|
||||
static struct attribute *msipf_attributes[] = {
|
||||
&dev_attr_lcd_level.attr,
|
||||
@ -275,7 +414,8 @@ static struct platform_driver msipf_driver = {
|
||||
.driver = {
|
||||
.name = "msi-laptop-pf",
|
||||
.owner = THIS_MODULE,
|
||||
}
|
||||
},
|
||||
.resume = msi_laptop_resume,
|
||||
};
|
||||
|
||||
static struct platform_device *msipf_device;
|
||||
@ -332,6 +472,192 @@ static struct dmi_system_id __initdata msi_dmi_table[] = {
|
||||
{ }
|
||||
};
|
||||
|
||||
static struct dmi_system_id __initdata msi_load_scm_models_dmi_table[] = {
|
||||
{
|
||||
.ident = "MSI N034",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR,
|
||||
"MICRO-STAR INTERNATIONAL CO., LTD"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "MS-N034"),
|
||||
DMI_MATCH(DMI_CHASSIS_VENDOR,
|
||||
"MICRO-STAR INTERNATIONAL CO., LTD")
|
||||
},
|
||||
.callback = dmi_check_cb
|
||||
},
|
||||
{ }
|
||||
};
|
||||
|
||||
static int rfkill_bluetooth_set(void *data, bool blocked)
|
||||
{
|
||||
/* Do something with blocked...*/
|
||||
/*
|
||||
* blocked == false is on
|
||||
* blocked == true is off
|
||||
*/
|
||||
if (blocked)
|
||||
set_device_state("0", 0, MSI_STANDARD_EC_BLUETOOTH_MASK);
|
||||
else
|
||||
set_device_state("1", 0, MSI_STANDARD_EC_BLUETOOTH_MASK);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rfkill_wlan_set(void *data, bool blocked)
|
||||
{
|
||||
if (blocked)
|
||||
set_device_state("0", 0, MSI_STANDARD_EC_WLAN_MASK);
|
||||
else
|
||||
set_device_state("1", 0, MSI_STANDARD_EC_WLAN_MASK);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rfkill_threeg_set(void *data, bool blocked)
|
||||
{
|
||||
if (blocked)
|
||||
set_device_state("0", 0, MSI_STANDARD_EC_3G_MASK);
|
||||
else
|
||||
set_device_state("1", 0, MSI_STANDARD_EC_3G_MASK);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct rfkill_ops rfkill_bluetooth_ops = {
|
||||
.set_block = rfkill_bluetooth_set
|
||||
};
|
||||
|
||||
static struct rfkill_ops rfkill_wlan_ops = {
|
||||
.set_block = rfkill_wlan_set
|
||||
};
|
||||
|
||||
static struct rfkill_ops rfkill_threeg_ops = {
|
||||
.set_block = rfkill_threeg_set
|
||||
};
|
||||
|
||||
static void rfkill_cleanup(void)
|
||||
{
|
||||
if (rfk_bluetooth) {
|
||||
rfkill_unregister(rfk_bluetooth);
|
||||
rfkill_destroy(rfk_bluetooth);
|
||||
}
|
||||
|
||||
if (rfk_threeg) {
|
||||
rfkill_unregister(rfk_threeg);
|
||||
rfkill_destroy(rfk_threeg);
|
||||
}
|
||||
|
||||
if (rfk_wlan) {
|
||||
rfkill_unregister(rfk_wlan);
|
||||
rfkill_destroy(rfk_wlan);
|
||||
}
|
||||
}
|
||||
|
||||
static int rfkill_init(struct platform_device *sdev)
|
||||
{
|
||||
/* add rfkill */
|
||||
int retval;
|
||||
|
||||
rfk_bluetooth = rfkill_alloc("msi-bluetooth", &sdev->dev,
|
||||
RFKILL_TYPE_BLUETOOTH,
|
||||
&rfkill_bluetooth_ops, NULL);
|
||||
if (!rfk_bluetooth) {
|
||||
retval = -ENOMEM;
|
||||
goto err_bluetooth;
|
||||
}
|
||||
retval = rfkill_register(rfk_bluetooth);
|
||||
if (retval)
|
||||
goto err_bluetooth;
|
||||
|
||||
rfk_wlan = rfkill_alloc("msi-wlan", &sdev->dev, RFKILL_TYPE_WLAN,
|
||||
&rfkill_wlan_ops, NULL);
|
||||
if (!rfk_wlan) {
|
||||
retval = -ENOMEM;
|
||||
goto err_wlan;
|
||||
}
|
||||
retval = rfkill_register(rfk_wlan);
|
||||
if (retval)
|
||||
goto err_wlan;
|
||||
|
||||
if (threeg_exists) {
|
||||
rfk_threeg = rfkill_alloc("msi-threeg", &sdev->dev,
|
||||
RFKILL_TYPE_WWAN, &rfkill_threeg_ops, NULL);
|
||||
if (!rfk_threeg) {
|
||||
retval = -ENOMEM;
|
||||
goto err_threeg;
|
||||
}
|
||||
retval = rfkill_register(rfk_threeg);
|
||||
if (retval)
|
||||
goto err_threeg;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_threeg:
|
||||
rfkill_destroy(rfk_threeg);
|
||||
if (rfk_wlan)
|
||||
rfkill_unregister(rfk_wlan);
|
||||
err_wlan:
|
||||
rfkill_destroy(rfk_wlan);
|
||||
if (rfk_bluetooth)
|
||||
rfkill_unregister(rfk_bluetooth);
|
||||
err_bluetooth:
|
||||
rfkill_destroy(rfk_bluetooth);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int msi_laptop_resume(struct platform_device *device)
|
||||
{
|
||||
u8 data;
|
||||
int result;
|
||||
|
||||
if (!load_scm_model)
|
||||
return 0;
|
||||
|
||||
/* set load SCM to disable hardware control by fn key */
|
||||
result = ec_read(MSI_STANDARD_EC_SCM_LOAD_ADDRESS, &data);
|
||||
if (result < 0)
|
||||
return result;
|
||||
|
||||
result = ec_write(MSI_STANDARD_EC_SCM_LOAD_ADDRESS,
|
||||
data | MSI_STANDARD_EC_SCM_LOAD_MASK);
|
||||
if (result < 0)
|
||||
return result;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int load_scm_model_init(struct platform_device *sdev)
|
||||
{
|
||||
u8 data;
|
||||
int result;
|
||||
|
||||
/* allow userland write sysfs file */
|
||||
dev_attr_bluetooth.store = store_bluetooth;
|
||||
dev_attr_wlan.store = store_wlan;
|
||||
dev_attr_threeg.store = store_threeg;
|
||||
dev_attr_bluetooth.attr.mode |= S_IWUSR;
|
||||
dev_attr_wlan.attr.mode |= S_IWUSR;
|
||||
dev_attr_threeg.attr.mode |= S_IWUSR;
|
||||
|
||||
/* disable hardware control by fn key */
|
||||
result = ec_read(MSI_STANDARD_EC_SCM_LOAD_ADDRESS, &data);
|
||||
if (result < 0)
|
||||
return result;
|
||||
|
||||
result = ec_write(MSI_STANDARD_EC_SCM_LOAD_ADDRESS,
|
||||
data | MSI_STANDARD_EC_SCM_LOAD_MASK);
|
||||
if (result < 0)
|
||||
return result;
|
||||
|
||||
/* initial rfkill */
|
||||
result = rfkill_init(sdev);
|
||||
if (result < 0)
|
||||
return result;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __init msi_init(void)
|
||||
{
|
||||
int ret;
|
||||
@ -339,8 +665,14 @@ static int __init msi_init(void)
|
||||
if (acpi_disabled)
|
||||
return -ENODEV;
|
||||
|
||||
if (!force && !dmi_check_system(msi_dmi_table))
|
||||
return -ENODEV;
|
||||
if (force || dmi_check_system(msi_dmi_table))
|
||||
old_ec_model = 1;
|
||||
|
||||
if (!old_ec_model)
|
||||
get_threeg_exists();
|
||||
|
||||
if (!old_ec_model && dmi_check_system(msi_load_scm_models_dmi_table))
|
||||
load_scm_model = 1;
|
||||
|
||||
if (auto_brightness < 0 || auto_brightness > 2)
|
||||
return -EINVAL;
|
||||
@ -374,10 +706,23 @@ static int __init msi_init(void)
|
||||
if (ret)
|
||||
goto fail_platform_device1;
|
||||
|
||||
if (load_scm_model && (load_scm_model_init(msipf_device) < 0)) {
|
||||
ret = -EINVAL;
|
||||
goto fail_platform_device1;
|
||||
}
|
||||
|
||||
ret = sysfs_create_group(&msipf_device->dev.kobj, &msipf_attribute_group);
|
||||
if (ret)
|
||||
goto fail_platform_device2;
|
||||
|
||||
if (!old_ec_model) {
|
||||
if (threeg_exists)
|
||||
ret = device_create_file(&msipf_device->dev,
|
||||
&dev_attr_threeg);
|
||||
if (ret)
|
||||
goto fail_platform_device2;
|
||||
}
|
||||
|
||||
/* Disable automatic brightness control by default because
|
||||
* this module was probably loaded to do brightness control in
|
||||
* software. */
|
||||
@ -412,10 +757,14 @@ static void __exit msi_cleanup(void)
|
||||
{
|
||||
|
||||
sysfs_remove_group(&msipf_device->dev.kobj, &msipf_attribute_group);
|
||||
if (!old_ec_model && threeg_exists)
|
||||
device_remove_file(&msipf_device->dev, &dev_attr_threeg);
|
||||
platform_device_unregister(msipf_device);
|
||||
platform_driver_unregister(&msipf_driver);
|
||||
backlight_device_unregister(msibl_device);
|
||||
|
||||
rfkill_cleanup();
|
||||
|
||||
/* Enable automatic brightness control again */
|
||||
if (auto_brightness != 2)
|
||||
set_auto_brightness(1);
|
||||
@ -435,3 +784,4 @@ MODULE_ALIAS("dmi:*:svnMICRO-STARINT'LCO.,LTD:pnMS-1013:pvr0131*:cvnMICRO-STARIN
|
||||
MODULE_ALIAS("dmi:*:svnMicro-StarInternational:pnMS-1058:pvr0581:rvnMSI:rnMS-1058:*:ct10:*");
|
||||
MODULE_ALIAS("dmi:*:svnMicro-StarInternational:pnMS-1412:*:rvnMSI:rnMS-1412:*:cvnMICRO-STARINT'LCO.,LTD:ct10:*");
|
||||
MODULE_ALIAS("dmi:*:svnNOTEBOOK:pnSAM2000:pvr0131*:cvnMICRO-STARINT'LCO.,LTD:ct10:*");
|
||||
MODULE_ALIAS("dmi:*:svnMICRO-STARINTERNATIONAL*:pnMS-N034:*");
|
||||
|
@ -226,7 +226,7 @@ static struct scsi_host_template sgiwd93_template = {
|
||||
.use_clustering = DISABLE_CLUSTERING,
|
||||
};
|
||||
|
||||
static int __init sgiwd93_probe(struct platform_device *pdev)
|
||||
static int __devinit sgiwd93_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct sgiwd93_platform_data *pd = pdev->dev.platform_data;
|
||||
unsigned char *wdregs = pd->wdregs;
|
||||
|
@ -64,7 +64,7 @@ static struct scsi_host_template snirm710_template = {
|
||||
.module = THIS_MODULE,
|
||||
};
|
||||
|
||||
static int __init snirm710_probe(struct platform_device *dev)
|
||||
static int __devinit snirm710_probe(struct platform_device *dev)
|
||||
{
|
||||
unsigned long base;
|
||||
struct NCR_700_Host_Parameters *hostdata;
|
||||
|
@ -770,13 +770,8 @@ static struct usb_driver oled_driver = {
|
||||
.id_table = id_table,
|
||||
};
|
||||
|
||||
static ssize_t version_show(struct class *dev, char *buf)
|
||||
{
|
||||
return sprintf(buf, ASUS_OLED_UNDERSCORE_NAME " %s\n",
|
||||
ASUS_OLED_VERSION);
|
||||
}
|
||||
|
||||
static CLASS_ATTR(version, S_IRUGO, version_show, NULL);
|
||||
static CLASS_ATTR_STRING(version, S_IRUGO,
|
||||
ASUS_OLED_UNDERSCORE_NAME " " ASUS_OLED_VERSION);
|
||||
|
||||
static int __init asus_oled_init(void)
|
||||
{
|
||||
@ -788,7 +783,7 @@ static int __init asus_oled_init(void)
|
||||
return PTR_ERR(oled_class);
|
||||
}
|
||||
|
||||
retval = class_create_file(oled_class, &class_attr_version);
|
||||
retval = class_create_file(oled_class, &class_attr_version.attr);
|
||||
if (retval) {
|
||||
err("Error creating class version file");
|
||||
goto error;
|
||||
@ -810,7 +805,7 @@ error:
|
||||
|
||||
static void __exit asus_oled_exit(void)
|
||||
{
|
||||
class_remove_file(oled_class, &class_attr_version);
|
||||
class_remove_file(oled_class, &class_attr_version.attr);
|
||||
class_destroy(oled_class);
|
||||
|
||||
usb_deregister(&oled_driver);
|
||||
|
@ -44,17 +44,6 @@ config UIO_PDRV_GENIRQ
|
||||
|
||||
If you don't know what to do here, say N.
|
||||
|
||||
config UIO_SMX
|
||||
tristate "SMX cryptengine UIO interface"
|
||||
help
|
||||
Userspace IO interface to the Cryptography engine found on the
|
||||
Nias Digital SMX boards. These will be available from Q4 2008
|
||||
from http://www.niasdigital.com. The userspace part of this
|
||||
driver will be released under the GPL at the same time as the
|
||||
hardware and will be able to be downloaded from the same site.
|
||||
|
||||
If you compile this as a module, it will be called uio_smx.
|
||||
|
||||
config UIO_AEC
|
||||
tristate "AEC video timestamp device"
|
||||
depends on PCI
|
||||
@ -74,6 +63,7 @@ config UIO_AEC
|
||||
|
||||
config UIO_SERCOS3
|
||||
tristate "Automata Sercos III PCI card driver"
|
||||
depends on PCI
|
||||
help
|
||||
Userspace I/O interface for the Sercos III PCI card from
|
||||
Automata GmbH. The userspace part of this driver will be
|
||||
@ -87,11 +77,21 @@ config UIO_SERCOS3
|
||||
config UIO_PCI_GENERIC
|
||||
tristate "Generic driver for PCI 2.3 and PCI Express cards"
|
||||
depends on PCI
|
||||
default n
|
||||
help
|
||||
Generic driver that you can bind, dynamically, to any
|
||||
PCI 2.3 compliant and PCI Express card. It is useful,
|
||||
primarily, for virtualization scenarios.
|
||||
If you compile this as a module, it will be called uio_pci_generic.
|
||||
|
||||
config UIO_NETX
|
||||
tristate "Hilscher NetX Card driver"
|
||||
depends on PCI
|
||||
help
|
||||
Driver for Hilscher NetX based fieldbus cards (cifX, comX).
|
||||
This driver requires a userspace component that comes with the card
|
||||
or is available from Hilscher (http://www.hilscher.com).
|
||||
|
||||
To compile this driver as a module, choose M here; the module
|
||||
will be called uio_netx.
|
||||
|
||||
endif
|
||||
|
@ -2,7 +2,7 @@ obj-$(CONFIG_UIO) += uio.o
|
||||
obj-$(CONFIG_UIO_CIF) += uio_cif.o
|
||||
obj-$(CONFIG_UIO_PDRV) += uio_pdrv.o
|
||||
obj-$(CONFIG_UIO_PDRV_GENIRQ) += uio_pdrv_genirq.o
|
||||
obj-$(CONFIG_UIO_SMX) += uio_smx.o
|
||||
obj-$(CONFIG_UIO_AEC) += uio_aec.o
|
||||
obj-$(CONFIG_UIO_SERCOS3) += uio_sercos3.o
|
||||
obj-$(CONFIG_UIO_PCI_GENERIC) += uio_pci_generic.o
|
||||
obj-$(CONFIG_UIO_NETX) += uio_netx.o
|
||||
|
@ -129,7 +129,7 @@ static ssize_t map_type_show(struct kobject *kobj, struct attribute *attr,
|
||||
return entry->show(mem, buf);
|
||||
}
|
||||
|
||||
static struct sysfs_ops map_sysfs_ops = {
|
||||
static const struct sysfs_ops map_sysfs_ops = {
|
||||
.show = map_type_show,
|
||||
};
|
||||
|
||||
@ -217,7 +217,7 @@ static ssize_t portio_type_show(struct kobject *kobj, struct attribute *attr,
|
||||
return entry->show(port, buf);
|
||||
}
|
||||
|
||||
static struct sysfs_ops portio_sysfs_ops = {
|
||||
static const struct sysfs_ops portio_sysfs_ops = {
|
||||
.show = portio_type_show,
|
||||
};
|
||||
|
||||
|
172
drivers/uio/uio_netx.c
Normal file
172
drivers/uio/uio_netx.c
Normal file
@ -0,0 +1,172 @@
|
||||
/*
|
||||
* UIO driver for Hilscher NetX based fieldbus cards (cifX, comX).
|
||||
* See http://www.hilscher.com for details.
|
||||
*
|
||||
* (C) 2007 Hans J. Koch <hjk@linutronix.de>
|
||||
* (C) 2008 Manuel Traut <manut@linutronix.de>
|
||||
*
|
||||
* Licensed under GPL version 2 only.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/device.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/uio_driver.h>
|
||||
|
||||
#define PCI_VENDOR_ID_HILSCHER 0x15CF
|
||||
#define PCI_DEVICE_ID_HILSCHER_NETX 0x0000
|
||||
#define PCI_SUBDEVICE_ID_NXSB_PCA 0x3235
|
||||
#define PCI_SUBDEVICE_ID_NXPCA 0x3335
|
||||
|
||||
#define DPM_HOST_INT_EN0 0xfff0
|
||||
#define DPM_HOST_INT_STAT0 0xffe0
|
||||
|
||||
#define DPM_HOST_INT_MASK 0xe600ffff
|
||||
#define DPM_HOST_INT_GLOBAL_EN 0x80000000
|
||||
|
||||
static irqreturn_t netx_handler(int irq, struct uio_info *dev_info)
|
||||
{
|
||||
void __iomem *int_enable_reg = dev_info->mem[0].internal_addr
|
||||
+ DPM_HOST_INT_EN0;
|
||||
void __iomem *int_status_reg = dev_info->mem[0].internal_addr
|
||||
+ DPM_HOST_INT_STAT0;
|
||||
|
||||
/* Is one of our interrupts enabled and active ? */
|
||||
if (!(ioread32(int_enable_reg) & ioread32(int_status_reg)
|
||||
& DPM_HOST_INT_MASK))
|
||||
return IRQ_NONE;
|
||||
|
||||
/* Disable interrupt */
|
||||
iowrite32(ioread32(int_enable_reg) & ~DPM_HOST_INT_GLOBAL_EN,
|
||||
int_enable_reg);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int __devinit netx_pci_probe(struct pci_dev *dev,
|
||||
const struct pci_device_id *id)
|
||||
{
|
||||
struct uio_info *info;
|
||||
int bar;
|
||||
|
||||
info = kzalloc(sizeof(struct uio_info), GFP_KERNEL);
|
||||
if (!info)
|
||||
return -ENOMEM;
|
||||
|
||||
if (pci_enable_device(dev))
|
||||
goto out_free;
|
||||
|
||||
if (pci_request_regions(dev, "netx"))
|
||||
goto out_disable;
|
||||
|
||||
switch (id->device) {
|
||||
case PCI_DEVICE_ID_HILSCHER_NETX:
|
||||
bar = 0;
|
||||
info->name = "netx";
|
||||
break;
|
||||
default:
|
||||
bar = 2;
|
||||
info->name = "netx_plx";
|
||||
}
|
||||
|
||||
/* BAR0 or 2 points to the card's dual port memory */
|
||||
info->mem[0].addr = pci_resource_start(dev, bar);
|
||||
if (!info->mem[0].addr)
|
||||
goto out_release;
|
||||
info->mem[0].internal_addr = ioremap(pci_resource_start(dev, bar),
|
||||
pci_resource_len(dev, bar));
|
||||
|
||||
if (!info->mem[0].internal_addr)
|
||||
goto out_release;
|
||||
|
||||
info->mem[0].size = pci_resource_len(dev, bar);
|
||||
info->mem[0].memtype = UIO_MEM_PHYS;
|
||||
info->irq = dev->irq;
|
||||
info->irq_flags = IRQF_SHARED;
|
||||
info->handler = netx_handler;
|
||||
info->version = "0.0.1";
|
||||
|
||||
/* Make sure all interrupts are disabled */
|
||||
iowrite32(0, info->mem[0].internal_addr + DPM_HOST_INT_EN0);
|
||||
|
||||
if (uio_register_device(&dev->dev, info))
|
||||
goto out_unmap;
|
||||
|
||||
pci_set_drvdata(dev, info);
|
||||
dev_info(&dev->dev, "Found %s card, registered UIO device.\n",
|
||||
info->name);
|
||||
|
||||
return 0;
|
||||
|
||||
out_unmap:
|
||||
iounmap(info->mem[0].internal_addr);
|
||||
out_release:
|
||||
pci_release_regions(dev);
|
||||
out_disable:
|
||||
pci_disable_device(dev);
|
||||
out_free:
|
||||
kfree(info);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static void netx_pci_remove(struct pci_dev *dev)
|
||||
{
|
||||
struct uio_info *info = pci_get_drvdata(dev);
|
||||
|
||||
/* Disable all interrupts */
|
||||
iowrite32(0, info->mem[0].internal_addr + DPM_HOST_INT_EN0);
|
||||
uio_unregister_device(info);
|
||||
pci_release_regions(dev);
|
||||
pci_disable_device(dev);
|
||||
pci_set_drvdata(dev, NULL);
|
||||
iounmap(info->mem[0].internal_addr);
|
||||
|
||||
kfree(info);
|
||||
}
|
||||
|
||||
static struct pci_device_id netx_pci_ids[] = {
|
||||
{
|
||||
.vendor = PCI_VENDOR_ID_HILSCHER,
|
||||
.device = PCI_DEVICE_ID_HILSCHER_NETX,
|
||||
.subvendor = 0,
|
||||
.subdevice = 0,
|
||||
},
|
||||
{
|
||||
.vendor = PCI_VENDOR_ID_PLX,
|
||||
.device = PCI_DEVICE_ID_PLX_9030,
|
||||
.subvendor = PCI_VENDOR_ID_PLX,
|
||||
.subdevice = PCI_SUBDEVICE_ID_NXSB_PCA,
|
||||
},
|
||||
{
|
||||
.vendor = PCI_VENDOR_ID_PLX,
|
||||
.device = PCI_DEVICE_ID_PLX_9030,
|
||||
.subvendor = PCI_VENDOR_ID_PLX,
|
||||
.subdevice = PCI_SUBDEVICE_ID_NXPCA,
|
||||
},
|
||||
{ 0, }
|
||||
};
|
||||
|
||||
static struct pci_driver netx_pci_driver = {
|
||||
.name = "netx",
|
||||
.id_table = netx_pci_ids,
|
||||
.probe = netx_pci_probe,
|
||||
.remove = netx_pci_remove,
|
||||
};
|
||||
|
||||
static int __init netx_init_module(void)
|
||||
{
|
||||
return pci_register_driver(&netx_pci_driver);
|
||||
}
|
||||
|
||||
static void __exit netx_exit_module(void)
|
||||
{
|
||||
pci_unregister_driver(&netx_pci_driver);
|
||||
}
|
||||
|
||||
module_init(netx_init_module);
|
||||
module_exit(netx_exit_module);
|
||||
|
||||
MODULE_DEVICE_TABLE(pci, netx_pci_ids);
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_AUTHOR("Hans J. Koch, Manuel Traut");
|
@ -1,140 +0,0 @@
|
||||
/*
|
||||
* UIO SMX Cryptengine driver.
|
||||
*
|
||||
* (C) 2008 Nias Digital P/L <bn@niasdigital.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/device.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/uio_driver.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#define DRV_NAME "smx-ce"
|
||||
#define DRV_VERSION "0.03"
|
||||
|
||||
#define SMX_CSR 0x00000000
|
||||
#define SMX_EnD 0x00000001
|
||||
#define SMX_RUN 0x00000002
|
||||
#define SMX_DRDY 0x00000004
|
||||
#define SMX_ERR 0x00000008
|
||||
|
||||
static irqreturn_t smx_handler(int irq, struct uio_info *dev_info)
|
||||
{
|
||||
void __iomem *csr = dev_info->mem[0].internal_addr + SMX_CSR;
|
||||
|
||||
u32 status = ioread32(csr);
|
||||
|
||||
if (!(status & SMX_DRDY))
|
||||
return IRQ_NONE;
|
||||
|
||||
/* Disable interrupt */
|
||||
iowrite32(status & ~SMX_DRDY, csr);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int __devinit smx_ce_probe(struct platform_device *dev)
|
||||
{
|
||||
|
||||
int ret = -ENODEV;
|
||||
struct uio_info *info;
|
||||
struct resource *regs;
|
||||
|
||||
info = kzalloc(sizeof(struct uio_info), GFP_KERNEL);
|
||||
if (!info)
|
||||
return -ENOMEM;
|
||||
|
||||
regs = platform_get_resource(dev, IORESOURCE_MEM, 0);
|
||||
if (!regs) {
|
||||
dev_err(&dev->dev, "No memory resource specified\n");
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
info->mem[0].addr = regs->start;
|
||||
if (!info->mem[0].addr) {
|
||||
dev_err(&dev->dev, "Invalid memory resource\n");
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
info->mem[0].size = regs->end - regs->start + 1;
|
||||
info->mem[0].internal_addr = ioremap(regs->start, info->mem[0].size);
|
||||
|
||||
if (!info->mem[0].internal_addr) {
|
||||
dev_err(&dev->dev, "Can't remap memory address range\n");
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
info->mem[0].memtype = UIO_MEM_PHYS;
|
||||
|
||||
info->name = "smx-ce";
|
||||
info->version = "0.03";
|
||||
|
||||
info->irq = platform_get_irq(dev, 0);
|
||||
if (info->irq < 0) {
|
||||
ret = info->irq;
|
||||
dev_err(&dev->dev, "No (or invalid) IRQ resource specified\n");
|
||||
goto out_unmap;
|
||||
}
|
||||
|
||||
info->irq_flags = IRQF_SHARED;
|
||||
info->handler = smx_handler;
|
||||
|
||||
platform_set_drvdata(dev, info);
|
||||
|
||||
ret = uio_register_device(&dev->dev, info);
|
||||
|
||||
if (ret)
|
||||
goto out_unmap;
|
||||
|
||||
return 0;
|
||||
|
||||
out_unmap:
|
||||
iounmap(info->mem[0].internal_addr);
|
||||
out_free:
|
||||
kfree(info);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __devexit smx_ce_remove(struct platform_device *dev)
|
||||
{
|
||||
struct uio_info *info = platform_get_drvdata(dev);
|
||||
|
||||
uio_unregister_device(info);
|
||||
platform_set_drvdata(dev, NULL);
|
||||
iounmap(info->mem[0].internal_addr);
|
||||
|
||||
kfree(info);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver smx_ce_driver = {
|
||||
.probe = smx_ce_probe,
|
||||
.remove = __devexit_p(smx_ce_remove),
|
||||
.driver = {
|
||||
.name = DRV_NAME,
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init smx_ce_init_module(void)
|
||||
{
|
||||
return platform_driver_register(&smx_ce_driver);
|
||||
}
|
||||
module_init(smx_ce_init_module);
|
||||
|
||||
static void __exit smx_ce_exit_module(void)
|
||||
{
|
||||
platform_driver_unregister(&smx_ce_driver);
|
||||
}
|
||||
module_exit(smx_ce_exit_module);
|
||||
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_VERSION(DRV_VERSION);
|
||||
MODULE_AUTHOR("Ben Nizette <bn@niasdigital.com>");
|
@ -489,10 +489,10 @@ void usb_driver_release_interface(struct usb_driver *driver,
|
||||
if (device_is_registered(dev)) {
|
||||
device_release_driver(dev);
|
||||
} else {
|
||||
down(&dev->sem);
|
||||
device_lock(dev);
|
||||
usb_unbind_interface(dev);
|
||||
dev->driver = NULL;
|
||||
up(&dev->sem);
|
||||
device_unlock(dev);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(usb_driver_release_interface);
|
||||
|
@ -74,13 +74,16 @@
|
||||
unsigned long beacon_timeout_ms = 500;
|
||||
|
||||
static
|
||||
ssize_t beacon_timeout_ms_show(struct class *class, char *buf)
|
||||
ssize_t beacon_timeout_ms_show(struct class *class,
|
||||
struct class_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
return scnprintf(buf, PAGE_SIZE, "%lu\n", beacon_timeout_ms);
|
||||
}
|
||||
|
||||
static
|
||||
ssize_t beacon_timeout_ms_store(struct class *class,
|
||||
struct class_attribute *attr,
|
||||
const char *buf, size_t size)
|
||||
{
|
||||
unsigned long bt;
|
||||
|
@ -62,12 +62,12 @@ int umc_controller_reset(struct umc_dev *umc)
|
||||
struct device *parent = umc->dev.parent;
|
||||
int ret = 0;
|
||||
|
||||
if(down_trylock(&parent->sem))
|
||||
if (device_trylock(parent))
|
||||
return -EAGAIN;
|
||||
ret = device_for_each_child(parent, parent, umc_bus_pre_reset_helper);
|
||||
if (ret >= 0)
|
||||
ret = device_for_each_child(parent, parent, umc_bus_post_reset_helper);
|
||||
up(&parent->sem);
|
||||
device_unlock(parent);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -366,12 +366,12 @@ struct dentry *uwb_dbg_create_pal_dir(struct uwb_pal *pal);
|
||||
|
||||
static inline void uwb_dev_lock(struct uwb_dev *uwb_dev)
|
||||
{
|
||||
down(&uwb_dev->dev.sem);
|
||||
device_lock(&uwb_dev->dev);
|
||||
}
|
||||
|
||||
static inline void uwb_dev_unlock(struct uwb_dev *uwb_dev)
|
||||
{
|
||||
up(&uwb_dev->dev.sem);
|
||||
device_unlock(&uwb_dev->dev);
|
||||
}
|
||||
|
||||
#endif /* #ifndef __UWB_INTERNAL_H__ */
|
||||
|
@ -615,8 +615,7 @@ ssize_t wlp_wss_attr_store(struct kobject *kobj, struct attribute *attr,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static
|
||||
struct sysfs_ops wss_sysfs_ops = {
|
||||
static const struct sysfs_ops wss_sysfs_ops = {
|
||||
.show = wlp_wss_attr_show,
|
||||
.store = wlp_wss_attr_store,
|
||||
};
|
||||
|
@ -1221,7 +1221,7 @@ free_unused_pages(unsigned int virtual_start, unsigned int virtual_end)
|
||||
printk("acornfb: freed %dK memory\n", mb_freed);
|
||||
}
|
||||
|
||||
static int __init acornfb_probe(struct platform_device *dev)
|
||||
static int __devinit acornfb_probe(struct platform_device *dev)
|
||||
{
|
||||
unsigned long size;
|
||||
u_int h_sync, v_sync;
|
||||
|
@ -504,7 +504,7 @@ static struct fb_ops arcfb_ops = {
|
||||
.fb_ioctl = arcfb_ioctl,
|
||||
};
|
||||
|
||||
static int __init arcfb_probe(struct platform_device *dev)
|
||||
static int __devinit arcfb_probe(struct platform_device *dev)
|
||||
{
|
||||
struct fb_info *info;
|
||||
int retval = -ENOMEM;
|
||||
|
@ -287,7 +287,7 @@ static struct fb_ops cobalt_lcd_fbops = {
|
||||
.fb_cursor = cobalt_lcdfb_cursor,
|
||||
};
|
||||
|
||||
static int __init cobalt_lcdfb_probe(struct platform_device *dev)
|
||||
static int __devinit cobalt_lcdfb_probe(struct platform_device *dev)
|
||||
{
|
||||
struct fb_info *info;
|
||||
struct resource *res;
|
||||
|
@ -210,7 +210,7 @@ static int __init efifb_setup(char *options)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __init efifb_probe(struct platform_device *dev)
|
||||
static int __devinit efifb_probe(struct platform_device *dev)
|
||||
{
|
||||
struct fb_info *info;
|
||||
int err;
|
||||
|
@ -602,7 +602,7 @@ static int epson1355fb_remove(struct platform_device *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __init epson1355fb_probe(struct platform_device *dev)
|
||||
int __devinit epson1355fb_probe(struct platform_device *dev)
|
||||
{
|
||||
struct epson1355_par *default_par;
|
||||
struct fb_info *info;
|
||||
|
@ -1128,7 +1128,7 @@ static int __init gbefb_setup(char *options)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __init gbefb_probe(struct platform_device *p_dev)
|
||||
static int __devinit gbefb_probe(struct platform_device *p_dev)
|
||||
{
|
||||
int i, ret = 0;
|
||||
struct fb_info *info;
|
||||
|
@ -551,7 +551,7 @@ static struct fb_ops hgafb_ops = {
|
||||
* Initialization
|
||||
*/
|
||||
|
||||
static int __init hgafb_probe(struct platform_device *pdev)
|
||||
static int __devinit hgafb_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct fb_info *info;
|
||||
|
||||
|
@ -325,7 +325,7 @@ static struct fb_ops hitfb_ops = {
|
||||
.fb_imageblit = cfb_imageblit,
|
||||
};
|
||||
|
||||
static int __init hitfb_probe(struct platform_device *dev)
|
||||
static int __devinit hitfb_probe(struct platform_device *dev)
|
||||
{
|
||||
unsigned short lcdclor, ldr3, ldvndr;
|
||||
struct fb_info *info;
|
||||
|
@ -341,7 +341,7 @@ static ssize_t manager_attr_store(struct kobject *kobj, struct attribute *attr,
|
||||
return manager_attr->store(manager, buf, size);
|
||||
}
|
||||
|
||||
static struct sysfs_ops manager_sysfs_ops = {
|
||||
static const struct sysfs_ops manager_sysfs_ops = {
|
||||
.show = manager_attr_show,
|
||||
.store = manager_attr_store,
|
||||
};
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user