Skip to content

Commit

Permalink
Merge branch 'driver-core-next' of git://git.kernel.org/pub/scm/linux…
Browse files Browse the repository at this point in the history
…/kernel/git/gregkh/driver-core

* 'driver-core-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core: (38 commits)
  mm: memory hotplug: Check if pages are correctly reserved on a per-section basis
  Revert "memory hotplug: Correct page reservation checking"
  Update email address for stable patch submission
  dynamic_debug: fix undefined reference to `__netdev_printk'
  dynamic_debug: use a single printk() to emit messages
  dynamic_debug: remove num_enabled accounting
  dynamic_debug: consolidate repetitive struct _ddebug descriptor definitions
  uio: Support physical addresses >32 bits on 32-bit systems
  sysfs: add unsigned long cast to prevent compile warning
  drivers: base: print rejected matches with DEBUG_DRIVER
  memory hotplug: Correct page reservation checking
  memory hotplug: Refuse to add unaligned memory regions
  remove the messy code file Documentation/zh_CN/SubmitChecklist
  ARM: mxc: convert device creation to use platform_device_register_full
  new helper to create platform devices with dma mask
  docs/driver-model: Update device class docs
  docs/driver-model: Document device.groups
  kobj_uevent: Ignore if some listeners cannot handle message
  dynamic_debug: make netif_dbg() call __netdev_printk()
  dynamic_debug: make netdev_dbg() call __netdev_printk()
  ...
  • Loading branch information
torvalds committed Oct 25, 2011
2 parents 59e5253 + 2bbcb87 commit 2d03423
Show file tree
Hide file tree
Showing 29 changed files with 527 additions and 432 deletions.
2 changes: 1 addition & 1 deletion Documentation/DocBook/uio-howto.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -529,7 +529,7 @@ memory (e.g. allocated with <function>kmalloc()</function>). There's also
</para></listitem>

<listitem><para>
<varname>unsigned long addr</varname>: Required if the mapping is used.
<varname>phys_addr_t addr</varname>: Required if the mapping is used.
Fill in the address of your memory block. This address is the one that
appears in sysfs.
</para></listitem>
Expand Down
4 changes: 0 additions & 4 deletions Documentation/driver-model/binding.txt
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,6 @@ devclass_add_device is called to enumerate the device within the class
and actually register it with the class, which happens with the
class's register_dev callback.

NOTE: The device class structures and core routines to manipulate them
are not in the mainline kernel, so the discussion is still a bit
speculative.


Driver
~~~~~~
Expand Down
65 changes: 32 additions & 33 deletions Documentation/driver-model/device.txt
Original file line number Diff line number Diff line change
Expand Up @@ -45,33 +45,52 @@ struct device_attribute {
const char *buf, size_t count);
};

Attributes of devices can be exported via drivers using a simple
procfs-like interface.
Attributes of devices can be exported by a device driver through sysfs.

Please see Documentation/filesystems/sysfs.txt for more information
on how sysfs works.

As explained in Documentation/kobject.txt, device attributes must be be
created before the KOBJ_ADD uevent is generated. The only way to realize
that is by defining an attribute group.

Attributes are declared using a macro called DEVICE_ATTR:

#define DEVICE_ATTR(name,mode,show,store)

Example:

DEVICE_ATTR(power,0644,show_power,store_power);
static DEVICE_ATTR(type, 0444, show_type, NULL);
static DEVICE_ATTR(power, 0644, show_power, store_power);

This declares a structure of type struct device_attribute named
'dev_attr_power'. This can then be added and removed to the device's
directory using:
This declares two structures of type struct device_attribute with respective
names 'dev_attr_type' and 'dev_attr_power'. These two attributes can be
organized as follows into a group:

int device_create_file(struct device *device, struct device_attribute * entry);
void device_remove_file(struct device * dev, struct device_attribute * attr);
static struct attribute *dev_attrs[] = {
&dev_attr_type.attr,
&dev_attr_power.attr,
NULL,
};

Example:
static struct attribute_group dev_attr_group = {
.attrs = dev_attrs,
};

static const struct attribute_group *dev_attr_groups[] = {
&dev_attr_group,
NULL,
};

This array of groups can then be associated with a device by setting the
group pointer in struct device before device_register() is invoked:

device_create_file(dev,&dev_attr_power);
device_remove_file(dev,&dev_attr_power);
dev->groups = dev_attr_groups;
device_register(dev);

The file name will be 'power' with a mode of 0644 (-rw-r--r--).
The device_register() function will use the 'groups' pointer to create the
device attributes and the device_unregister() function will use this pointer
to remove the device attributes.

Word of warning: While the kernel allows device_create_file() and
device_remove_file() to be called on a device at any time, userspace has
Expand All @@ -84,24 +103,4 @@ not know about the new attributes.
This is important for device driver that need to publish additional
attributes for a device at driver probe time. If the device driver simply
calls device_create_file() on the device structure passed to it, then
userspace will never be notified of the new attributes. Instead, it should
probably use class_create() and class->dev_attrs to set up a list of
desired attributes in the modules_init function, and then in the .probe()
hook, and then use device_create() to create a new device as a child
of the probed device. The new device will generate a new uevent and
properly advertise the new attributes to userspace.

For example, if a driver wanted to add the following attributes:
struct device_attribute mydriver_attribs[] = {
__ATTR(port_count, 0444, port_count_show),
__ATTR(serial_number, 0444, serial_number_show),
NULL
};

Then in the module init function is would do:
mydriver_class = class_create(THIS_MODULE, "my_attrs");
mydriver_class.dev_attr = mydriver_attribs;

And assuming 'dev' is the struct device passed into the probe hook, the driver
probe function would do something like:
device_create(&mydriver_class, dev, chrdev, &private_data, "my_name");
userspace will never be notified of the new attributes.
10 changes: 9 additions & 1 deletion Documentation/filesystems/sysfs.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ sysfs - _The_ filesystem for exporting kernel objects.
Patrick Mochel <mochel@osdl.org>
Mike Murphy <mamurph@cs.clemson.edu>

Revised: 15 July 2010
Revised: 16 August 2011
Original: 10 January 2003


Expand Down Expand Up @@ -370,3 +370,11 @@ int driver_create_file(struct device_driver *, const struct driver_attribute *);
void driver_remove_file(struct device_driver *, const struct driver_attribute *);


Documentation
~~~~~~~~~~~~~

The sysfs directory structure and the attributes in each directory define an
ABI between the kernel and user space. As for any ABI, it is important that
this ABI is stable and properly documented. All new sysfs attributes must be
documented in Documentation/ABI. See also Documentation/ABI/README for more
information.
14 changes: 7 additions & 7 deletions Documentation/stable_kernel_rules.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,21 +24,21 @@ Rules on what kind of patches are accepted, and which ones are not, into the
Procedure for submitting patches to the -stable tree:

- Send the patch, after verifying that it follows the above rules, to
stable@kernel.org. You must note the upstream commit ID in the changelog
of your submission.
stable@vger.kernel.org. You must note the upstream commit ID in the
changelog of your submission.
- To have the patch automatically included in the stable tree, add the tag
Cc: stable@kernel.org
Cc: stable@vger.kernel.org
in the sign-off area. Once the patch is merged it will be applied to
the stable tree without anything else needing to be done by the author
or subsystem maintainer.
- If the patch requires other patches as prerequisites which can be
cherry-picked than this can be specified in the following format in
the sign-off area:

Cc: <stable@kernel.org> # .32.x: a1f84a3: sched: Check for idle
Cc: <stable@kernel.org> # .32.x: 1b9508f: sched: Rate-limit newidle
Cc: <stable@kernel.org> # .32.x: fd21073: sched: Fix affinity logic
Cc: <stable@kernel.org> # .32.x
Cc: <stable@vger.kernel.org> # .32.x: a1f84a3: sched: Check for idle
Cc: <stable@vger.kernel.org> # .32.x: 1b9508f: sched: Rate-limit newidle
Cc: <stable@vger.kernel.org> # .32.x: fd21073: sched: Fix affinity logic
Cc: <stable@vger.kernel.org> # .32.x
Signed-off-by: Ingo Molnar <mingo@elte.hu>

The tag sequence has the meaning of:
Expand Down
109 changes: 0 additions & 109 deletions Documentation/zh_CN/SubmitChecklist

This file was deleted.

6 changes: 6 additions & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -2294,6 +2294,12 @@ L: netdev@vger.kernel.org
S: Maintained
F: drivers/net/wan/dscc4.c

DYNAMIC DEBUG
M: Jason Baron <jbaron@redhat.com>
S: Maintained
F: lib/dynamic_debug.c
F: include/linux/dynamic_debug.h

DZ DECSTATION DZ11 SERIAL DRIVER
M: "Maciej W. Rozycki" <macro@linux-mips.org>
S: Maintained
Expand Down
53 changes: 0 additions & 53 deletions arch/arm/plat-mxc/devices.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,59 +37,6 @@ int __init mxc_register_device(struct platform_device *pdev, void *data)
return ret;
}

struct platform_device *__init imx_add_platform_device_dmamask(
const char *name, int id,
const struct resource *res, unsigned int num_resources,
const void *data, size_t size_data, u64 dmamask)
{
int ret = -ENOMEM;
struct platform_device *pdev;

pdev = platform_device_alloc(name, id);
if (!pdev)
goto err;

if (dmamask) {
/*
* This memory isn't freed when the device is put,
* I don't have a nice idea for that though. Conceptually
* dma_mask in struct device should not be a pointer.
* See http://thread.gmane.org/gmane.linux.kernel.pci/9081
*/
pdev->dev.dma_mask =
kmalloc(sizeof(*pdev->dev.dma_mask), GFP_KERNEL);
if (!pdev->dev.dma_mask)
/* ret is still -ENOMEM; */
goto err;

*pdev->dev.dma_mask = dmamask;
pdev->dev.coherent_dma_mask = dmamask;
}

if (res) {
ret = platform_device_add_resources(pdev, res, num_resources);
if (ret)
goto err;
}

if (data) {
ret = platform_device_add_data(pdev, data, size_data);
if (ret)
goto err;
}

ret = platform_device_add(pdev);
if (ret) {
err:
if (dmamask)
kfree(pdev->dev.dma_mask);
platform_device_put(pdev);
return ERR_PTR(ret);
}

return pdev;
}

struct device mxc_aips_bus = {
.init_name = "mxc_aips",
.parent = &platform_bus,
Expand Down
16 changes: 14 additions & 2 deletions arch/arm/plat-mxc/include/mach/devices-common.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,22 @@
extern struct device mxc_aips_bus;
extern struct device mxc_ahb_bus;

struct platform_device *imx_add_platform_device_dmamask(
static inline struct platform_device *imx_add_platform_device_dmamask(
const char *name, int id,
const struct resource *res, unsigned int num_resources,
const void *data, size_t size_data, u64 dmamask);
const void *data, size_t size_data, u64 dmamask)
{
struct platform_device_info pdevinfo = {
.name = name,
.id = id,
.res = res,
.num_res = num_resources,
.data = data,
.size_data = size_data,
.dma_mask = dmamask,
};
return platform_device_register_full(&pdevinfo);
}

static inline struct platform_device *imx_add_platform_device(
const char *name, int id,
Expand Down
5 changes: 3 additions & 2 deletions drivers/base/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1764,15 +1764,16 @@ void device_shutdown(void)

#ifdef CONFIG_PRINTK

static int __dev_printk(const char *level, const struct device *dev,
struct va_format *vaf)
int __dev_printk(const char *level, const struct device *dev,
struct va_format *vaf)
{
if (!dev)
return printk("%s(NULL device *): %pV", level, vaf);

return printk("%s%s %s: %pV",
level, dev_driver_string(dev), dev_name(dev), vaf);
}
EXPORT_SYMBOL(__dev_printk);

int dev_printk(const char *level, const struct device *dev,
const char *fmt, ...)
Expand Down
3 changes: 3 additions & 0 deletions drivers/base/dd.c
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,9 @@ static int really_probe(struct device *dev, struct device_driver *drv)
printk(KERN_WARNING
"%s: probe of %s failed with error %d\n",
drv->name, dev_name(dev), ret);
} else {
pr_debug("%s: probe of %s rejects match %d\n",
drv->name, dev_name(dev), ret);
}
/*
* Ignore errors returned by ->probe so that the next driver can try
Expand Down
Loading

0 comments on commit 2d03423

Please sign in to comment.