2009-03-25 00:25:27

by Greg KH

[permalink] [raw]
Subject: [GIT PATCH] driver core patches for 2.6.30 merge window

Here are the driver-core patches for the 2.6.30 merge window.

The final remanants of the big "bus_id" removal to use dev_name are in
here, they have all been send to the different subsystem maintainers and
either ignored for 6 months, or acked.

There is a bit of rework of struct device, moving some private fields
out of the public eye, so they don't get in trouble by using them
improperly (parisc had to be fixed up here because of this, that change
has been acked as well.)

The dynamic debug code has also been reworked and merged with existing
code, to hopefully make it easier for everyone to use properly.

And there's a new UIO driver, for some video-timestamp hardware, that is
already being used in the field by a number of crazy users.

Please pull from:
master.kernel.org:/pub/scm/linux/kernel/git/gregkh/driver-core-2.6.git/

All of these patches have been in the linux-next and mm trees for a
while.

The patches will be sent as a follow-on to this message to lkml for people
to see.

thanks,

greg k-h

------------

Documentation/DocBook/uio-howto.tmpl | 29 +-
Documentation/dynamic-debug-howto.txt | 240 ++++++++++
Documentation/kernel-parameters.txt | 5 -
arch/mips/basler/excite/excite_iodev.c | 27 +-
arch/powerpc/platforms/ps3/system-bus.c | 4 +-
drivers/acpi/dock.c | 2 +-
drivers/amba/bus.c | 4 +-
drivers/base/base.h | 31 ++
drivers/base/bus.c | 44 ++-
drivers/base/core.c | 108 +++--
drivers/base/dd.c | 40 +-
drivers/base/driver.c | 15 +-
drivers/base/firmware_class.c | 4 +-
drivers/base/platform.c | 60 ++-
drivers/base/power/main.c | 44 ++
drivers/base/power/power.h | 8 +
drivers/base/sys.c | 54 ++--
drivers/block/floppy.c | 3 +-
drivers/char/tpm/tpm_atmel.c | 28 +-
drivers/char/tpm/tpm_tis.c | 28 +-
drivers/char/vc_screen.c | 16 +-
drivers/char/vt.c | 5 +-
drivers/dio/dio.c | 4 +-
drivers/dma/dw_dmac.c | 2 +-
drivers/edac/cell_edac.c | 2 +-
drivers/edac/mpc85xx_edac.c | 2 +-
drivers/edac/mv64x60_edac.c | 8 +-
drivers/eisa/eisa-bus.c | 4 +-
drivers/gpio/bt8xxgpio.c | 2 +-
drivers/gpu/drm/drm_sysfs.c | 4 +-
drivers/i2c/i2c-core.c | 2 +-
drivers/ide/au1xxx-ide.c | 36 +-
drivers/isdn/gigaset/ser-gigaset.c | 3 +-
drivers/mca/mca-bus.c | 4 +-
drivers/media/radio/radio-tea5764.c | 3 +-
drivers/media/video/v4l2-device.c | 2 +-
drivers/mfd/mcp-core.c | 2 +-
drivers/mfd/ucb1x00-core.c | 2 +-
drivers/mmc/host/atmel-mci.c | 2 +-
drivers/mmc/host/of_mmc_spi.c | 2 +-
drivers/mtd/maps/pxa2xx-flash.c | 37 +-
drivers/mtd/nand/excite_nandflash.c | 25 +-
drivers/mtd/nand/ndfc.c | 2 +-
drivers/mtd/onenand/generic.c | 26 +-
drivers/net/arm/ks8695net.c | 2 +-
drivers/net/au1000_eth.c | 8 +-
drivers/net/bfin_mac.c | 12 +-
drivers/net/bmac.c | 2 +-
drivers/net/cpmac.c | 2 +-
drivers/net/declance.c | 6 +-
drivers/net/depca.c | 6 +-
drivers/net/ehea/ehea_main.c | 2 +-
drivers/net/jazzsonic.c | 6 +-
drivers/net/macb.c | 10 +-
drivers/net/macsonic.c | 15 +-
drivers/net/mipsnet.c | 26 +-
drivers/net/mv643xx_eth.c | 2 +-
drivers/net/sb1250-mac.c | 10 +-
drivers/net/smc911x.c | 2 +-
drivers/net/smc91x.c | 2 +-
drivers/net/smsc911x.c | 7 +-
drivers/net/smsc9420.c | 4 +-
drivers/net/tc35815.c | 4 +-
drivers/net/wimax/i2400m/driver.c | 2 +-
drivers/net/wimax/i2400m/usb-notif.c | 2 +-
drivers/net/xtsonic.c | 2 +-
drivers/pci/hotplug/cpqphp_sysfs.c | 3 +-
drivers/pcmcia/au1000_generic.c | 37 +-
drivers/pcmcia/i82365.c | 28 +-
drivers/pcmcia/m32r_cfc.c | 30 +-
drivers/pcmcia/m32r_pcc.c | 30 +-
drivers/pcmcia/rsrc_mgr.c | 2 +-
drivers/pcmcia/sa1100_generic.c | 38 ++-
drivers/pcmcia/tcic.c | 30 +-
drivers/pcmcia/vrc4171_card.c | 34 +-
drivers/rapidio/rio-driver.c | 2 +-
drivers/rtc/rtc-at91sam9.c | 4 +-
drivers/rtc/rtc-omap.c | 4 +-
drivers/rtc/rtc-twl4030.c | 2 +-
drivers/s390/cio/ccwgroup.c | 5 +-
drivers/s390/cio/chsc_sch.c | 4 +-
drivers/s390/cio/css.c | 4 +-
drivers/s390/cio/device.c | 13 +-
drivers/s390/net/qeth_l3_main.c | 2 +-
drivers/scsi/a4000t.c | 29 +-
drivers/scsi/bvme6000_scsi.c | 29 +-
drivers/scsi/mvme16x_scsi.c | 29 +-
drivers/serial/sunzilog.c | 4 +-
drivers/sh/maple/maple.c | 8 +-
drivers/sh/superhyway/superhyway.c | 4 +-
drivers/spi/atmel_spi.c | 8 +-
drivers/spi/mpc52xx_psc_spi.c | 2 +-
drivers/spi/omap2_mcspi.c | 2 +-
drivers/spi/omap_uwire.c | 12 +-
drivers/spi/orion_spi.c | 2 +-
drivers/spi/pxa2xx_spi.c | 4 +-
drivers/spi/spi_bfin5xx.c | 4 +-
drivers/spi/spi_gpio.c | 2 +-
drivers/spi/spi_imx.c | 5 +-
drivers/spi/spi_mpc83xx.c | 4 +-
drivers/spi/spi_txx9.c | 3 +-
drivers/tc/tc.c | 8 +-
drivers/uio/Kconfig | 18 +
drivers/uio/Makefile | 1 +
drivers/uio/uio.c | 25 +-
drivers/uio/uio_aec.c | 175 +++++++
drivers/usb/gadget/ci13xxx_udc.c | 2 +-
drivers/usb/gadget/imx_udc.c | 4 +-
drivers/usb/host/fhci-dbg.c | 2 +-
drivers/usb/host/fhci-hcd.c | 4 +-
drivers/video/au1100fb.c | 31 +-
drivers/video/au1200fb.c | 25 +-
drivers/video/pmag-ba-fb.c | 17 +-
drivers/video/pmagb-b-fb.c | 17 +-
drivers/video/ps3fb.c | 2 +-
drivers/video/sh_mobile_lcdcfb.c | 2 +-
drivers/video/tmiofb.c | 2 +-
drivers/watchdog/rm9k_wdt.c | 27 +-
drivers/zorro/zorro.c | 4 +-
fs/partitions/check.c | 10 +-
fs/sysfs/bin.c | 253 ++++++++++-
fs/sysfs/dir.c | 33 ++-
fs/sysfs/file.c | 26 +-
fs/sysfs/inode.c | 17 +
fs/sysfs/mount.c | 6 +-
fs/sysfs/sysfs.h | 3 +
include/asm-generic/vmlinux.lds.h | 15 +-
include/linux/console.h | 4 +-
include/linux/device.h | 38 +-
include/linux/dynamic_debug.h | 88 ++++
include/linux/dynamic_printk.h | 93 ----
include/linux/kernel.h | 7 +-
include/linux/kobject.h | 3 +
include/linux/mod_devicetable.h | 9 +
include/linux/platform_device.h | 7 +
include/linux/pm.h | 11 +
include/linux/uio_driver.h | 4 +
include/linux/wimax/debug.h | 2 +-
kernel/module.c | 25 +-
lib/Kconfig.debug | 74 ++--
lib/Makefile | 2 +-
lib/dynamic_debug.c | 769 +++++++++++++++++++++++++++++++
lib/dynamic_printk.c | 414 -----------------
lib/kobject.c | 2 +-
lib/kobject_uevent.c | 9 +-
net/bluetooth/hci_sysfs.c | 2 +-
net/bluetooth/rfcomm/tty.c | 5 +-
net/netfilter/nf_conntrack_pptp.c | 2 +-
scripts/Makefile.lib | 2 +-
scripts/mod/file2alias.c | 12 +
150 files changed, 2670 insertions(+), 1175 deletions(-)
create mode 100644 Documentation/dynamic-debug-howto.txt
create mode 100644 drivers/uio/uio_aec.c
create mode 100644 include/linux/dynamic_debug.h
delete mode 100644 include/linux/dynamic_printk.h
create mode 100644 lib/dynamic_debug.c
delete mode 100644 lib/dynamic_printk.c

---------------

Alex Chiang (2):
sysfs: sysfs_add_one WARNs with full path to duplicate filename
sysfs: only allow one scheduled removal callback per kobj

Arjan van de Ven (1):
kobject: don't block for each kobject_uevent

Brandon Philips (1):
uio: add the uio_aec driver

Cornelia Huck (1):
Driver core: Fix device_move() vs. dpm list ordering, v2

Dave Young (1):
driver-core: do not register a driver with bus_type not registered

Eric Miao (2):
platform: make better use of to_platform_{device,driver}() macros
platform: introduce module id table for platform devices

Eric W. Biederman (3):
sysfs: Take sysfs_mutex when fetching the root inode.
sysfs: reference sysfs_dirent from sysfs inodes
sysfs: don't block indefinitely for unmapped files.

Geert Uytterhoeven (1):
scsi/m68k: Kill NCR_700_detect() warnings

Greg Banks (2):
Dynamic debug: allow simple quoting of words
Dynamic debug: fix pr_fmt() build error

Greg Kroah-Hartman (5):
PS3: replace bus_id usage
driver core: create a private portion of struct device
driver core: move klist_children into private structure
driver core: move knode_driver into private structure
driver core: move knode_bus into private structure

Hans J. Koch (1):
UIO: Add name attributes for mappings and port regions

Hugh Dickins (1):
sysfs: fix some bin_vm_ops errors

Ian Abbott (1):
UIO: Take offset into account when determining number of pages that can be mapped

Jason Baron (2):
dynamic debug: combine dprintk and dynamic printk
dynamic debug: update docs

Kay Sievers (28):
edac: struct device - replace bus_id with dev_name(), dev_set_name()
spi: struct device - replace bus_id with dev_name(), dev_set_name()
video: struct device - replace bus_id with dev_name(), dev_set_name()
zorro: struct device - replace bus_id with dev_name(), dev_set_name()
mmc: struct device - replace bus_id with dev_name(), dev_set_name()
mtd: struct device - replace bus_id with dev_name(), dev_set_name()
pci: struct device - replace bus_id with dev_name(), dev_set_name()
rapidio: struct device - replace bus_id with dev_name(), dev_set_name()
s390: struct device - replace bus_id with dev_name(), dev_set_name()
serial: struct device - replace bus_id with dev_name(), dev_set_name()
sh: struct device - replace bus_id with dev_name(), dev_set_name()
tc: struct device - replace bus_id with dev_name(), dev_set_name()
pcmcia: struct device - replace bus_id with dev_name(), dev_set_name()
rtc: struct device - replace bus_id with dev_name(), dev_set_name()
net: struct device - replace bus_id with dev_name(), dev_set_name()
drm: struct device - replace bus_id with dev_name(), dev_set_name()
v4l: struct device - replace bus_id with dev_name(), dev_set_name()
amba: struct device - replace bus_id with dev_name(), dev_set_name()
dio: struct device - replace bus_id with dev_name(), dev_set_name()
dma: struct device - replace bus_id with dev_name(), dev_set_name()
eisa: struct device - replace bus_id with dev_name(), dev_set_name()
gpio: struct device - replace bus_id with dev_name(), dev_set_name()
mca: struct device - replace bus_id with dev_name(), dev_set_name()
mfd: struct device - replace bus_id with dev_name(), dev_set_name()
wimax: struct device - replace bus_id with dev_name(), dev_set_name()
usb: struct device - replace bus_id with dev_name(), dev_set_name()
driver core: get rid of struct device's bus_id string array
vcs: hook sysfs devices into object lifetime instead of "binding"

Ming Lei (6):
driver core: check bus->match without holding device lock
platform driver: fix incorrect use of 'platform_bus_type' with 'struct device_driver'
driver core: remove polling for driver_probe_done(v5)
driver core: move platform_data into platform_device
driver core: fix passing platform_data
Driver core: implement uevent suppress in kobject

Qinghuang Feng (1):
SYSFS: use standard magic.h for sysfs

Sachin Sant (1):
USB: FHCI: use dev_name() in place of bus_id.

Zhenwen Xu (1):
Driver core: some cleanup on drivers/base/sys.c


2009-03-25 00:29:55

by Greg KH

[permalink] [raw]
Subject: [PATCH 01/61] edac: struct device - replace bus_id with dev_name(), dev_set_name()

From: Kay Sievers <[email protected]>

Cc: [email protected]
Cc: [email protected]
Acked-by: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Kay Sievers <[email protected]>
---
drivers/edac/cell_edac.c | 2 +-
drivers/edac/mpc85xx_edac.c | 2 +-
drivers/edac/mv64x60_edac.c | 8 ++++----
3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/edac/cell_edac.c b/drivers/edac/cell_edac.c
index 24f3ca8..cb0f639 100644
--- a/drivers/edac/cell_edac.c
+++ b/drivers/edac/cell_edac.c
@@ -198,7 +198,7 @@ static int __devinit cell_edac_probe(struct platform_device *pdev)
mci->edac_cap = EDAC_FLAG_EC | EDAC_FLAG_SECDED;
mci->mod_name = "cell_edac";
mci->ctl_name = "MIC";
- mci->dev_name = pdev->dev.bus_id;
+ mci->dev_name = dev_name(&pdev->dev);
mci->edac_check = cell_edac_check;
cell_edac_init_csrows(mci);

diff --git a/drivers/edac/mpc85xx_edac.c b/drivers/edac/mpc85xx_edac.c
index 853ef37..4637a4a 100644
--- a/drivers/edac/mpc85xx_edac.c
+++ b/drivers/edac/mpc85xx_edac.c
@@ -218,7 +218,7 @@ static int __devinit mpc85xx_pci_err_probe(struct of_device *op,
pci->dev = &op->dev;
pci->mod_name = EDAC_MOD_STR;
pci->ctl_name = pdata->name;
- pci->dev_name = op->dev.bus_id;
+ pci->dev_name = dev_name(&op->dev);

if (edac_op_state == EDAC_OPSTATE_POLL)
pci->edac_check = mpc85xx_pci_check;
diff --git a/drivers/edac/mv64x60_edac.c b/drivers/edac/mv64x60_edac.c
index 083ce8d..5131aaa 100644
--- a/drivers/edac/mv64x60_edac.c
+++ b/drivers/edac/mv64x60_edac.c
@@ -121,7 +121,7 @@ static int __devinit mv64x60_pci_err_probe(struct platform_device *pdev)
pdata->irq = NO_IRQ;
platform_set_drvdata(pdev, pci);
pci->dev = &pdev->dev;
- pci->dev_name = pdev->dev.bus_id;
+ pci->dev_name = dev_name(&pdev->dev);
pci->mod_name = EDAC_MOD_STR;
pci->ctl_name = pdata->name;

@@ -294,7 +294,7 @@ static int __devinit mv64x60_sram_err_probe(struct platform_device *pdev)
pdata->irq = NO_IRQ;
edac_dev->dev = &pdev->dev;
platform_set_drvdata(pdev, edac_dev);
- edac_dev->dev_name = pdev->dev.bus_id;
+ edac_dev->dev_name = dev_name(&pdev->dev);

r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!r) {
@@ -462,7 +462,7 @@ static int __devinit mv64x60_cpu_err_probe(struct platform_device *pdev)
pdata->irq = NO_IRQ;
edac_dev->dev = &pdev->dev;
platform_set_drvdata(pdev, edac_dev);
- edac_dev->dev_name = pdev->dev.bus_id;
+ edac_dev->dev_name = dev_name(&pdev->dev);

r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!r) {
@@ -713,7 +713,7 @@ static int __devinit mv64x60_mc_err_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, mci);
pdata->name = "mv64x60_mc_err";
pdata->irq = NO_IRQ;
- mci->dev_name = pdev->dev.bus_id;
+ mci->dev_name = dev_name(&pdev->dev);
pdata->edac_idx = edac_mc_idx++;

r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
--
1.6.2

2009-03-25 00:30:30

by Greg KH

[permalink] [raw]
Subject: [PATCH 02/61] spi: struct device - replace bus_id with dev_name(), dev_set_name()

From: Kay Sievers <[email protected]>

Cc: [email protected]
Cc: [email protected]
Acked-by: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Kay Sievers <[email protected]>
---
drivers/spi/atmel_spi.c | 8 ++++----
drivers/spi/mpc52xx_psc_spi.c | 2 +-
drivers/spi/omap2_mcspi.c | 2 +-
drivers/spi/omap_uwire.c | 12 ++++++------
drivers/spi/orion_spi.c | 2 +-
drivers/spi/pxa2xx_spi.c | 4 ++--
drivers/spi/spi_bfin5xx.c | 4 ++--
drivers/spi/spi_gpio.c | 2 +-
drivers/spi/spi_imx.c | 5 +++--
drivers/spi/spi_mpc83xx.c | 4 ++--
drivers/spi/spi_txx9.c | 3 ++-
11 files changed, 25 insertions(+), 23 deletions(-)

diff --git a/drivers/spi/atmel_spi.c b/drivers/spi/atmel_spi.c
index 56ff3e6..12e443c 100644
--- a/drivers/spi/atmel_spi.c
+++ b/drivers/spi/atmel_spi.c
@@ -322,7 +322,7 @@ static void atmel_spi_next_message(struct spi_master *master)
spi = msg->spi;

dev_dbg(master->dev.parent, "start message %p for %s\n",
- msg, spi->dev.bus_id);
+ msg, dev_name(&spi->dev));

/* select chip if it's not still active */
if (as->stay) {
@@ -627,7 +627,7 @@ static int atmel_spi_setup(struct spi_device *spi)
if (!asd)
return -ENOMEM;

- ret = gpio_request(npcs_pin, spi->dev.bus_id);
+ ret = gpio_request(npcs_pin, dev_name(&spi->dev));
if (ret) {
kfree(asd);
return ret;
@@ -668,7 +668,7 @@ static int atmel_spi_transfer(struct spi_device *spi, struct spi_message *msg)
as = spi_master_get_devdata(spi->master);

dev_dbg(controller, "new message %p submitted for %s\n",
- msg, spi->dev.bus_id);
+ msg, dev_name(&spi->dev));

if (unlikely(list_empty(&msg->transfers)))
return -EINVAL;
@@ -803,7 +803,7 @@ static int __init atmel_spi_probe(struct platform_device *pdev)
as->clk = clk;

ret = request_irq(irq, atmel_spi_interrupt, 0,
- pdev->dev.bus_id, master);
+ dev_name(&pdev->dev), master);
if (ret)
goto out_unmap_regs;

diff --git a/drivers/spi/mpc52xx_psc_spi.c b/drivers/spi/mpc52xx_psc_spi.c
index 3b97803..68c77a9 100644
--- a/drivers/spi/mpc52xx_psc_spi.c
+++ b/drivers/spi/mpc52xx_psc_spi.c
@@ -429,7 +429,7 @@ static int __init mpc52xx_psc_spi_do_probe(struct device *dev, u32 regaddr,
INIT_LIST_HEAD(&mps->queue);

mps->workqueue = create_singlethread_workqueue(
- master->dev.parent->bus_id);
+ dev_name(master->dev.parent));
if (mps->workqueue == NULL) {
ret = -EBUSY;
goto free_irq;
diff --git a/drivers/spi/omap2_mcspi.c b/drivers/spi/omap2_mcspi.c
index 454a271..1c65e38 100644
--- a/drivers/spi/omap2_mcspi.c
+++ b/drivers/spi/omap2_mcspi.c
@@ -1003,7 +1003,7 @@ static int __init omap2_mcspi_probe(struct platform_device *pdev)
goto err1;
}
if (!request_mem_region(r->start, (r->end - r->start) + 1,
- pdev->dev.bus_id)) {
+ dev_name(&pdev->dev))) {
status = -EBUSY;
goto err1;
}
diff --git a/drivers/spi/omap_uwire.c b/drivers/spi/omap_uwire.c
index bab6ff0..60b5381 100644
--- a/drivers/spi/omap_uwire.c
+++ b/drivers/spi/omap_uwire.c
@@ -245,7 +245,7 @@ static int uwire_txrx(struct spi_device *spi, struct spi_transfer *t)

#ifdef VERBOSE
pr_debug("%s: write-%d =%04x\n",
- spi->dev.bus_id, bits, val);
+ dev_name(&spi->dev), bits, val);
#endif
if (wait_uwire_csr_flag(CSRB, 0, 0))
goto eio;
@@ -305,7 +305,7 @@ static int uwire_txrx(struct spi_device *spi, struct spi_transfer *t)
status += bytes;
#ifdef VERBOSE
pr_debug("%s: read-%d =%04x\n",
- spi->dev.bus_id, bits, val);
+ dev_name(&spi->dev), bits, val);
#endif

}
@@ -331,7 +331,7 @@ static int uwire_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
uwire = spi_master_get_devdata(spi->master);

if (spi->chip_select > 3) {
- pr_debug("%s: cs%d?\n", spi->dev.bus_id, spi->chip_select);
+ pr_debug("%s: cs%d?\n", dev_name(&spi->dev), spi->chip_select);
status = -ENODEV;
goto done;
}
@@ -343,7 +343,7 @@ static int uwire_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
bits = 8;

if (bits > 16) {
- pr_debug("%s: wordsize %d?\n", spi->dev.bus_id, bits);
+ pr_debug("%s: wordsize %d?\n", dev_name(&spi->dev), bits);
status = -ENODEV;
goto done;
}
@@ -378,7 +378,7 @@ static int uwire_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
hz = t->speed_hz;

if (!hz) {
- pr_debug("%s: zero speed?\n", spi->dev.bus_id);
+ pr_debug("%s: zero speed?\n", dev_name(&spi->dev));
status = -EINVAL;
goto done;
}
@@ -406,7 +406,7 @@ static int uwire_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
}
if (div1_idx == 4) {
pr_debug("%s: lowest clock %ld, need %d\n",
- spi->dev.bus_id, rate / 10 / 8, hz);
+ dev_name(&spi->dev), rate / 10 / 8, hz);
status = -EDOM;
goto done;
}
diff --git a/drivers/spi/orion_spi.c b/drivers/spi/orion_spi.c
index 014becb..c8b0bab 100644
--- a/drivers/spi/orion_spi.c
+++ b/drivers/spi/orion_spi.c
@@ -496,7 +496,7 @@ static int __init orion_spi_probe(struct platform_device *pdev)
}

if (!request_mem_region(r->start, (r->end - r->start) + 1,
- pdev->dev.bus_id)) {
+ dev_name(&pdev->dev))) {
status = -EBUSY;
goto out;
}
diff --git a/drivers/spi/pxa2xx_spi.c b/drivers/spi/pxa2xx_spi.c
index d0fc4ca..ec24f2d 100644
--- a/drivers/spi/pxa2xx_spi.c
+++ b/drivers/spi/pxa2xx_spi.c
@@ -1333,7 +1333,7 @@ static int __init init_queue(struct driver_data *drv_data)

INIT_WORK(&drv_data->pump_messages, pump_messages);
drv_data->workqueue = create_singlethread_workqueue(
- drv_data->master->dev.parent->bus_id);
+ dev_name(drv_data->master->dev.parent));
if (drv_data->workqueue == NULL)
return -EBUSY;

@@ -1462,7 +1462,7 @@ static int __init pxa2xx_spi_probe(struct platform_device *pdev)
drv_data->mask_sr = SSSR_TINT | SSSR_RFS | SSSR_TFS | SSSR_ROR;
}

- status = request_irq(ssp->irq, ssp_int, 0, dev->bus_id, drv_data);
+ status = request_irq(ssp->irq, ssp_int, 0, dev_name(dev), drv_data);
if (status < 0) {
dev_err(&pdev->dev, "cannot get IRQ %d\n", ssp->irq);
goto out_error_master_alloc;
diff --git a/drivers/spi/spi_bfin5xx.c b/drivers/spi/spi_bfin5xx.c
index 7fea3cf..3410b0c 100644
--- a/drivers/spi/spi_bfin5xx.c
+++ b/drivers/spi/spi_bfin5xx.c
@@ -1160,8 +1160,8 @@ static inline int init_queue(struct driver_data *drv_data)

/* init messages workqueue */
INIT_WORK(&drv_data->pump_messages, pump_messages);
- drv_data->workqueue =
- create_singlethread_workqueue(drv_data->master->dev.parent->bus_id);
+ drv_data->workqueue = create_singlethread_workqueue(
+ dev_name(drv_data->master->dev.parent));
if (drv_data->workqueue == NULL)
return -EBUSY;

diff --git a/drivers/spi/spi_gpio.c b/drivers/spi/spi_gpio.c
index f5ed972..d2866c2 100644
--- a/drivers/spi/spi_gpio.c
+++ b/drivers/spi/spi_gpio.c
@@ -191,7 +191,7 @@ static int spi_gpio_setup(struct spi_device *spi)
return -EINVAL;

if (!spi->controller_state) {
- status = gpio_request(cs, spi->dev.bus_id);
+ status = gpio_request(cs, dev_name(&spi->dev));
if (status)
return status;
status = gpio_direction_output(cs, spi->mode & SPI_CS_HIGH);
diff --git a/drivers/spi/spi_imx.c b/drivers/spi/spi_imx.c
index 269a55e..0480d8b 100644
--- a/drivers/spi/spi_imx.c
+++ b/drivers/spi/spi_imx.c
@@ -1381,7 +1381,7 @@ static int __init init_queue(struct driver_data *drv_data)

INIT_WORK(&drv_data->work, pump_messages);
drv_data->workqueue = create_singlethread_workqueue(
- drv_data->master->dev.parent->bus_id);
+ dev_name(drv_data->master->dev.parent));
if (drv_data->workqueue == NULL)
return -EBUSY;

@@ -1525,7 +1525,8 @@ static int __init spi_imx_probe(struct platform_device *pdev)
status = -ENODEV;
goto err_no_irqres;
}
- status = request_irq(irq, spi_int, IRQF_DISABLED, dev->bus_id, drv_data);
+ status = request_irq(irq, spi_int, IRQF_DISABLED,
+ dev_name(dev), drv_data);
if (status < 0) {
dev_err(&pdev->dev, "probe - cannot get IRQ (%d)\n", status);
goto err_no_irqres;
diff --git a/drivers/spi/spi_mpc83xx.c b/drivers/spi/spi_mpc83xx.c
index ac0e3e4..44a2b46 100644
--- a/drivers/spi/spi_mpc83xx.c
+++ b/drivers/spi/spi_mpc83xx.c
@@ -637,7 +637,7 @@ static int __init mpc83xx_spi_probe(struct platform_device *dev)
INIT_LIST_HEAD(&mpc83xx_spi->queue);

mpc83xx_spi->workqueue = create_singlethread_workqueue(
- master->dev.parent->bus_id);
+ dev_name(master->dev.parent));
if (mpc83xx_spi->workqueue == NULL) {
ret = -EBUSY;
goto free_irq;
@@ -649,7 +649,7 @@ static int __init mpc83xx_spi_probe(struct platform_device *dev)

printk(KERN_INFO
"%s: MPC83xx SPI Controller driver at 0x%p (irq = %d)\n",
- dev->dev.bus_id, mpc83xx_spi->base, mpc83xx_spi->irq);
+ dev_name(&dev->dev), mpc83xx_spi->base, mpc83xx_spi->irq);

return ret;

diff --git a/drivers/spi/spi_txx9.c b/drivers/spi/spi_txx9.c
index 2296f37..29cbb06 100644
--- a/drivers/spi/spi_txx9.c
+++ b/drivers/spi/spi_txx9.c
@@ -404,7 +404,8 @@ static int __init txx9spi_probe(struct platform_device *dev)
if (ret)
goto exit;

- c->workqueue = create_singlethread_workqueue(master->dev.parent->bus_id);
+ c->workqueue = create_singlethread_workqueue(
+ dev_name(master->dev.parent));
if (!c->workqueue)
goto exit_busy;
c->last_chipselect = -1;
--
1.6.2

2009-03-25 00:30:57

by Greg KH

[permalink] [raw]
Subject: [PATCH 03/61] video: struct device - replace bus_id with dev_name(), dev_set_name()

From: Kay Sievers <[email protected]>

Acked-by: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Kay Sievers <[email protected]>
---
drivers/video/pmag-ba-fb.c | 17 +++++++++--------
drivers/video/pmagb-b-fb.c | 17 +++++++++--------
drivers/video/ps3fb.c | 2 +-
drivers/video/sh_mobile_lcdcfb.c | 2 +-
drivers/video/tmiofb.c | 2 +-
5 files changed, 21 insertions(+), 19 deletions(-)

diff --git a/drivers/video/pmag-ba-fb.c b/drivers/video/pmag-ba-fb.c
index 3a3f80f..0573ec6 100644
--- a/drivers/video/pmag-ba-fb.c
+++ b/drivers/video/pmag-ba-fb.c
@@ -151,7 +151,7 @@ static int __init pmagbafb_probe(struct device *dev)

info = framebuffer_alloc(sizeof(struct pmagbafb_par), dev);
if (!info) {
- printk(KERN_ERR "%s: Cannot allocate memory\n", dev->bus_id);
+ printk(KERN_ERR "%s: Cannot allocate memory\n", dev_name(dev));
return -ENOMEM;
}

@@ -160,7 +160,7 @@ static int __init pmagbafb_probe(struct device *dev)

if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) {
printk(KERN_ERR "%s: Cannot allocate color map\n",
- dev->bus_id);
+ dev_name(dev));
err = -ENOMEM;
goto err_alloc;
}
@@ -173,8 +173,9 @@ static int __init pmagbafb_probe(struct device *dev)
/* Request the I/O MEM resource. */
start = tdev->resource.start;
len = tdev->resource.end - start + 1;
- if (!request_mem_region(start, len, dev->bus_id)) {
- printk(KERN_ERR "%s: Cannot reserve FB region\n", dev->bus_id);
+ if (!request_mem_region(start, len, dev_name(dev))) {
+ printk(KERN_ERR "%s: Cannot reserve FB region\n",
+ dev_name(dev));
err = -EBUSY;
goto err_cmap;
}
@@ -183,7 +184,7 @@ static int __init pmagbafb_probe(struct device *dev)
info->fix.mmio_start = start;
par->mmio = ioremap_nocache(info->fix.mmio_start, info->fix.mmio_len);
if (!par->mmio) {
- printk(KERN_ERR "%s: Cannot map MMIO\n", dev->bus_id);
+ printk(KERN_ERR "%s: Cannot map MMIO\n", dev_name(dev));
err = -ENOMEM;
goto err_resource;
}
@@ -194,7 +195,7 @@ static int __init pmagbafb_probe(struct device *dev)
info->screen_base = ioremap_nocache(info->fix.smem_start,
info->fix.smem_len);
if (!info->screen_base) {
- printk(KERN_ERR "%s: Cannot map FB\n", dev->bus_id);
+ printk(KERN_ERR "%s: Cannot map FB\n", dev_name(dev));
err = -ENOMEM;
goto err_mmio_map;
}
@@ -205,14 +206,14 @@ static int __init pmagbafb_probe(struct device *dev)
err = register_framebuffer(info);
if (err < 0) {
printk(KERN_ERR "%s: Cannot register framebuffer\n",
- dev->bus_id);
+ dev_name(dev));
goto err_smem_map;
}

get_device(dev);

pr_info("fb%d: %s frame buffer device at %s\n",
- info->node, info->fix.id, dev->bus_id);
+ info->node, info->fix.id, dev_name(dev));

return 0;

diff --git a/drivers/video/pmagb-b-fb.c b/drivers/video/pmagb-b-fb.c
index 9b80597..9874872 100644
--- a/drivers/video/pmagb-b-fb.c
+++ b/drivers/video/pmagb-b-fb.c
@@ -258,7 +258,7 @@ static int __init pmagbbfb_probe(struct device *dev)

info = framebuffer_alloc(sizeof(struct pmagbbfb_par), dev);
if (!info) {
- printk(KERN_ERR "%s: Cannot allocate memory\n", dev->bus_id);
+ printk(KERN_ERR "%s: Cannot allocate memory\n", dev_name(dev));
return -ENOMEM;
}

@@ -267,7 +267,7 @@ static int __init pmagbbfb_probe(struct device *dev)

if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) {
printk(KERN_ERR "%s: Cannot allocate color map\n",
- dev->bus_id);
+ dev_name(dev));
err = -ENOMEM;
goto err_alloc;
}
@@ -280,8 +280,9 @@ static int __init pmagbbfb_probe(struct device *dev)
/* Request the I/O MEM resource. */
start = tdev->resource.start;
len = tdev->resource.end - start + 1;
- if (!request_mem_region(start, len, dev->bus_id)) {
- printk(KERN_ERR "%s: Cannot reserve FB region\n", dev->bus_id);
+ if (!request_mem_region(start, len, dev_name(dev))) {
+ printk(KERN_ERR "%s: Cannot reserve FB region\n",
+ dev_name(dev));
err = -EBUSY;
goto err_cmap;
}
@@ -290,7 +291,7 @@ static int __init pmagbbfb_probe(struct device *dev)
info->fix.mmio_start = start;
par->mmio = ioremap_nocache(info->fix.mmio_start, info->fix.mmio_len);
if (!par->mmio) {
- printk(KERN_ERR "%s: Cannot map MMIO\n", dev->bus_id);
+ printk(KERN_ERR "%s: Cannot map MMIO\n", dev_name(dev));
err = -ENOMEM;
goto err_resource;
}
@@ -301,7 +302,7 @@ static int __init pmagbbfb_probe(struct device *dev)
info->fix.smem_start = start + PMAGB_B_FBMEM;
par->smem = ioremap_nocache(info->fix.smem_start, info->fix.smem_len);
if (!par->smem) {
- printk(KERN_ERR "%s: Cannot map FB\n", dev->bus_id);
+ printk(KERN_ERR "%s: Cannot map FB\n", dev_name(dev));
err = -ENOMEM;
goto err_mmio_map;
}
@@ -316,7 +317,7 @@ static int __init pmagbbfb_probe(struct device *dev)
err = register_framebuffer(info);
if (err < 0) {
printk(KERN_ERR "%s: Cannot register framebuffer\n",
- dev->bus_id);
+ dev_name(dev));
goto err_smem_map;
}

@@ -328,7 +329,7 @@ static int __init pmagbbfb_probe(struct device *dev)
par->osc1 / 1000, par->osc1 % 1000);

pr_info("fb%d: %s frame buffer device at %s\n",
- info->node, info->fix.id, dev->bus_id);
+ info->node, info->fix.id, dev_name(dev));
pr_info("fb%d: Osc0: %s, Osc1: %s, Osc%u selected\n",
info->node, freq0, par->osc1 ? freq1 : "disabled",
par->osc1 != 0);
diff --git a/drivers/video/ps3fb.c b/drivers/video/ps3fb.c
index 87f826e..e00c1df 100644
--- a/drivers/video/ps3fb.c
+++ b/drivers/video/ps3fb.c
@@ -1213,7 +1213,7 @@ static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev)
dev->core.driver_data = info;

dev_info(info->device, "%s %s, using %u KiB of video memory\n",
- dev_driver_string(info->dev), info->dev->bus_id,
+ dev_driver_string(info->dev), dev_name(info->dev),
info->fix.smem_len >> 10);

task = kthread_run(ps3fbd, info, DEVICE_NAME);
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
index 2c5d069..1d2636a 100644
--- a/drivers/video/sh_mobile_lcdcfb.c
+++ b/drivers/video/sh_mobile_lcdcfb.c
@@ -687,7 +687,7 @@ static int __init sh_mobile_lcdc_probe(struct platform_device *pdev)
}

error = request_irq(i, sh_mobile_lcdc_irq, IRQF_DISABLED,
- pdev->dev.bus_id, priv);
+ dev_name(&pdev->dev), priv);
if (error) {
dev_err(&pdev->dev, "unable to request irq\n");
goto err1;
diff --git a/drivers/video/tmiofb.c b/drivers/video/tmiofb.c
index 7baf2dd..a1eb086 100644
--- a/drivers/video/tmiofb.c
+++ b/drivers/video/tmiofb.c
@@ -751,7 +751,7 @@ static int __devinit tmiofb_probe(struct platform_device *dev)
}

retval = request_irq(irq, &tmiofb_irq, IRQF_DISABLED,
- dev->dev.bus_id, info);
+ dev_name(&dev->dev), info);

if (retval)
goto err_request_irq;
--
1.6.2

2009-03-25 00:31:23

by Greg KH

[permalink] [raw]
Subject: [PATCH 04/61] zorro: struct device - replace bus_id with dev_name(), dev_set_name()

From: Kay Sievers <[email protected]>

Acked-by: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Kay Sievers <[email protected]>
---
drivers/zorro/zorro.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/zorro/zorro.c b/drivers/zorro/zorro.c
index a1585d6..d45fb34 100644
--- a/drivers/zorro/zorro.c
+++ b/drivers/zorro/zorro.c
@@ -140,7 +140,7 @@ static int __init zorro_init(void)

/* Initialize the Zorro bus */
INIT_LIST_HEAD(&zorro_bus.devices);
- strcpy(zorro_bus.dev.bus_id, "zorro");
+ dev_set_name(&zorro_bus.dev, "zorro");
error = device_register(&zorro_bus.dev);
if (error) {
pr_err("Zorro: Error registering zorro_bus\n");
@@ -167,7 +167,7 @@ static int __init zorro_init(void)
if (request_resource(zorro_find_parent_resource(z), &z->resource))
pr_err("Zorro: Address space collision on device %s %pR\n",
z->name, &z->resource);
- sprintf(z->dev.bus_id, "%02x", i);
+ dev_set_name(&z->dev, "%02x", i);
z->dev.parent = &zorro_bus.dev;
z->dev.bus = &zorro_bus_type;
error = device_register(&z->dev);
--
1.6.2

2009-03-25 00:31:40

by Greg KH

[permalink] [raw]
Subject: [PATCH 05/61] mmc: struct device - replace bus_id with dev_name(), dev_set_name()

From: Kay Sievers <[email protected]>

Cc: [email protected]
Acked-by: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Kay Sievers <[email protected]>
---
drivers/mmc/host/atmel-mci.c | 2 +-
drivers/mmc/host/of_mmc_spi.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c
index 2b1196e..e94e920 100644
--- a/drivers/mmc/host/atmel-mci.c
+++ b/drivers/mmc/host/atmel-mci.c
@@ -1603,7 +1603,7 @@ static int __init atmci_probe(struct platform_device *pdev)

tasklet_init(&host->tasklet, atmci_tasklet_func, (unsigned long)host);

- ret = request_irq(irq, atmci_interrupt, 0, pdev->dev.bus_id, host);
+ ret = request_irq(irq, atmci_interrupt, 0, dev_name(&pdev->dev), host);
if (ret)
goto err_request_irq;

diff --git a/drivers/mmc/host/of_mmc_spi.c b/drivers/mmc/host/of_mmc_spi.c
index fb2921f..0c44d56 100644
--- a/drivers/mmc/host/of_mmc_spi.c
+++ b/drivers/mmc/host/of_mmc_spi.c
@@ -103,7 +103,7 @@ struct mmc_spi_platform_data *mmc_spi_get_pdata(struct spi_device *spi)
if (!gpio_is_valid(oms->gpios[i]))
continue;

- ret = gpio_request(oms->gpios[i], dev->bus_id);
+ ret = gpio_request(oms->gpios[i], dev_name(dev));
if (ret < 0) {
oms->gpios[i] = -EINVAL;
continue;
--
1.6.2

2009-03-25 00:31:55

by Greg KH

[permalink] [raw]
Subject: [PATCH 06/61] mtd: struct device - replace bus_id with dev_name(), dev_set_name()

From: Kay Sievers <[email protected]>

Cc: [email protected]
Cc: [email protected]
Acked-by: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Kay Sievers <[email protected]>
---
drivers/mtd/nand/ndfc.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/mtd/nand/ndfc.c b/drivers/mtd/nand/ndfc.c
index 582cf80..89bf85a 100644
--- a/drivers/mtd/nand/ndfc.c
+++ b/drivers/mtd/nand/ndfc.c
@@ -187,7 +187,7 @@ static int ndfc_chip_init(struct ndfc_controller *ndfc,
return -ENODEV;

ndfc->mtd.name = kasprintf(GFP_KERNEL, "%s.%s",
- ndfc->ofdev->dev.bus_id, flash_np->name);
+ dev_name(&ndfc->ofdev->dev), flash_np->name);
if (!ndfc->mtd.name) {
ret = -ENOMEM;
goto err;
--
1.6.2

2009-03-25 00:32:38

by Greg KH

[permalink] [raw]
Subject: [PATCH 08/61] rapidio: struct device - replace bus_id with dev_name(), dev_set_name()

From: Kay Sievers <[email protected]>

Cc: [email protected]
Acked-by: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Kay Sievers <[email protected]>
---
drivers/rapidio/rio-driver.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/rapidio/rio-driver.c b/drivers/rapidio/rio-driver.c
index addb87c..3222fa3 100644
--- a/drivers/rapidio/rio-driver.c
+++ b/drivers/rapidio/rio-driver.c
@@ -193,7 +193,7 @@ static int rio_match_bus(struct device *dev, struct device_driver *drv)
}

static struct device rio_bus = {
- .bus_id = "rapidio",
+ .init_name = "rapidio",
};

struct bus_type rio_bus_type = {
--
1.6.2

2009-03-25 00:32:56

by Greg KH

[permalink] [raw]
Subject: [PATCH 09/61] s390: struct device - replace bus_id with dev_name(), dev_set_name()

From: Kay Sievers <[email protected]>

Cc: [email protected]
Cc: [email protected]
Acked-by: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Kay Sievers <[email protected]>
---
drivers/s390/net/qeth_l3_main.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c
index 3d04920..0dcc036 100644
--- a/drivers/s390/net/qeth_l3_main.c
+++ b/drivers/s390/net/qeth_l3_main.c
@@ -1038,7 +1038,7 @@ static int qeth_l3_setadapter_parms(struct qeth_card *card)
rc = qeth_query_setadapterparms(card);
if (rc) {
QETH_DBF_MESSAGE(2, "%s couldn't set adapter parameters: "
- "0x%x\n", card->gdev->dev.bus_id, rc);
+ "0x%x\n", dev_name(&card->gdev->dev), rc);
return rc;
}
if (qeth_adp_supported(card, IPA_SETADP_ALTER_MAC_ADDRESS)) {
--
1.6.2

2009-03-25 00:32:23

by Greg KH

[permalink] [raw]
Subject: [PATCH 07/61] pci: struct device - replace bus_id with dev_name(), dev_set_name()

From: Kay Sievers <[email protected]>

Cc: [email protected]
Cc: [email protected]
Acked-by: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Kay Sievers <[email protected]>
---
drivers/pci/hotplug/cpqphp_sysfs.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/drivers/pci/hotplug/cpqphp_sysfs.c b/drivers/pci/hotplug/cpqphp_sysfs.c
index a13abf5..8450f4a 100644
--- a/drivers/pci/hotplug/cpqphp_sysfs.c
+++ b/drivers/pci/hotplug/cpqphp_sysfs.c
@@ -225,7 +225,8 @@ void cpqhp_shutdown_debugfs(void)

void cpqhp_create_debugfs_files(struct controller *ctrl)
{
- ctrl->dentry = debugfs_create_file(ctrl->pci_dev->dev.bus_id, S_IRUGO, root, ctrl, &debug_ops);
+ ctrl->dentry = debugfs_create_file(dev_name(&ctrl->pci_dev->dev),
+ S_IRUGO, root, ctrl, &debug_ops);
}

void cpqhp_remove_debugfs_files(struct controller *ctrl)
--
1.6.2

2009-03-25 00:33:27

by Greg KH

[permalink] [raw]
Subject: [PATCH 10/61] serial: struct device - replace bus_id with dev_name(), dev_set_name()

From: Kay Sievers <[email protected]>

Cc: [email protected]
Acked-by: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Kay Sievers <[email protected]>
---
drivers/serial/sunzilog.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c
index 45a299f..e09d3ce 100644
--- a/drivers/serial/sunzilog.c
+++ b/drivers/serial/sunzilog.c
@@ -1438,12 +1438,12 @@ static int __devinit zs_probe(struct of_device *op, const struct of_device_id *m
} else {
printk(KERN_INFO "%s: Keyboard at MMIO 0x%llx (irq = %d) "
"is a %s\n",
- op->dev.bus_id,
+ dev_name(&op->dev),
(unsigned long long) up[0].port.mapbase,
op->irqs[0], sunzilog_type(&up[0].port));
printk(KERN_INFO "%s: Mouse at MMIO 0x%llx (irq = %d) "
"is a %s\n",
- op->dev.bus_id,
+ dev_name(&op->dev),
(unsigned long long) up[1].port.mapbase,
op->irqs[0], sunzilog_type(&up[1].port));
kbm_inst++;
--
1.6.2

2009-03-25 00:34:01

by Greg KH

[permalink] [raw]
Subject: [PATCH 12/61] tc: struct device - replace bus_id with dev_name(), dev_set_name()

From: Kay Sievers <[email protected]>

Cc: [email protected]
Acked-by: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Kay Sievers <[email protected]>
---
drivers/tc/tc.c | 8 ++++----
1 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/tc/tc.c b/drivers/tc/tc.c
index f77f62a..e5bd447 100644
--- a/drivers/tc/tc.c
+++ b/drivers/tc/tc.c
@@ -86,7 +86,7 @@ static void __init tc_bus_add_devices(struct tc_bus *tbus)
slot);
goto out_err;
}
- sprintf(tdev->dev.bus_id, "tc%x", slot);
+ dev_set_name(&tdev->dev, "tc%x", slot);
tdev->bus = tbus;
tdev->dev.parent = &tbus->dev;
tdev->dev.bus = &tc_bus_type;
@@ -104,7 +104,7 @@ static void __init tc_bus_add_devices(struct tc_bus *tbus)
tdev->vendor[8] = 0;
tdev->name[8] = 0;

- pr_info("%s: %s %s %s\n", tdev->dev.bus_id, tdev->vendor,
+ pr_info("%s: %s %s %s\n", dev_name(&tdev->dev), tdev->vendor,
tdev->name, tdev->firmware);

devsize = readb(module + offset + TC_SLOT_SIZE);
@@ -118,7 +118,7 @@ static void __init tc_bus_add_devices(struct tc_bus *tbus)
} else {
printk(KERN_ERR "%s: Cannot provide slot space "
"(%dMiB required, up to %dMiB supported)\n",
- tdev->dev.bus_id, devsize >> 20,
+ dev_name(&tdev->dev), devsize >> 20,
max(slotsize, extslotsize) >> 20);
kfree(tdev);
goto out_err;
@@ -146,7 +146,7 @@ static int __init tc_init(void)
return 0;

INIT_LIST_HEAD(&tc_bus.devices);
- strcpy(tc_bus.dev.bus_id, "tc");
+ dev_set_name(&tc_bus.dev, "tc");
device_register(&tc_bus.dev);

if (tc_bus.info.slot_size) {
--
1.6.2

2009-03-25 00:33:43

by Greg KH

[permalink] [raw]
Subject: [PATCH 11/61] sh: struct device - replace bus_id with dev_name(), dev_set_name()

From: Kay Sievers <[email protected]>

Acked-by: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Kay Sievers <[email protected]>
---
drivers/sh/maple/maple.c | 8 ++++----
drivers/sh/superhyway/superhyway.c | 4 ++--
2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/sh/maple/maple.c b/drivers/sh/maple/maple.c
index 63f0de2..7e1257a 100644
--- a/drivers/sh/maple/maple.c
+++ b/drivers/sh/maple/maple.c
@@ -424,7 +424,7 @@ static void maple_attach_driver(struct maple_device *mdev)
/* Do this silently - as not a real device */
function = 0;
mdev->driver = &maple_dummy_driver;
- sprintf(mdev->dev.bus_id, "%d:0.port", mdev->port);
+ dev_set_name(&mdev->dev, "%d:0.port", mdev->port);
} else {
printk(KERN_INFO
"Maple bus at (%d, %d): Function 0x%lX\n",
@@ -440,8 +440,8 @@ static void maple_attach_driver(struct maple_device *mdev)
"No maple driver found.\n");
mdev->driver = &maple_dummy_driver;
}
- sprintf(mdev->dev.bus_id, "%d:0%d.%lX", mdev->port,
- mdev->unit, function);
+ dev_set_name(&mdev->dev, "%d:0%d.%lX", mdev->port,
+ mdev->unit, function);
}
mdev->function = function;
mdev->dev.release = &maple_release_device;
@@ -780,7 +780,7 @@ struct bus_type maple_bus_type = {
EXPORT_SYMBOL_GPL(maple_bus_type);

static struct device maple_bus = {
- .bus_id = "maple",
+ .init_name = "maple",
.release = maple_bus_release,
};

diff --git a/drivers/sh/superhyway/superhyway.c b/drivers/sh/superhyway/superhyway.c
index 4d0282b..2d9e7f3 100644
--- a/drivers/sh/superhyway/superhyway.c
+++ b/drivers/sh/superhyway/superhyway.c
@@ -22,7 +22,7 @@
static int superhyway_devices;

static struct device superhyway_bus_device = {
- .bus_id = "superhyway",
+ .init_name = "superhyway",
};

static void superhyway_device_release(struct device *dev)
@@ -83,7 +83,7 @@ int superhyway_add_device(unsigned long base, struct superhyway_device *sdev,
dev->id.id = dev->vcr.mod_id;

sprintf(dev->name, "SuperHyway device %04x", dev->id.id);
- sprintf(dev->dev.bus_id, "%02x", superhyway_devices);
+ dev_set_name(&dev->dev, "%02x", superhyway_devices);

superhyway_devices++;

--
1.6.2

2009-03-25 00:34:23

by Greg KH

[permalink] [raw]
Subject: [PATCH 13/61] pcmcia: struct device - replace bus_id with dev_name(), dev_set_name()

From: Kay Sievers <[email protected]>

Cc: Dominik Brodowski <[email protected]>
Cc: [email protected]
Acked-by: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Kay Sievers <[email protected]>
---
drivers/pcmcia/rsrc_mgr.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/pcmcia/rsrc_mgr.c b/drivers/pcmcia/rsrc_mgr.c
index c0e2afc..e592e0e 100644
--- a/drivers/pcmcia/rsrc_mgr.c
+++ b/drivers/pcmcia/rsrc_mgr.c
@@ -153,7 +153,7 @@ static struct resource *iodyn_find_io_region(unsigned long base, int num,
unsigned long align, struct pcmcia_socket *s)
{
struct resource *res = make_resource(0, num, IORESOURCE_IO,
- s->dev.bus_id);
+ dev_name(&s->dev));
struct pcmcia_align_data data;
unsigned long min = base;
int ret;
--
1.6.2

2009-03-25 00:34:56

by Greg KH

[permalink] [raw]
Subject: [PATCH 16/61] drm: struct device - replace bus_id with dev_name(), dev_set_name()

From: Kay Sievers <[email protected]>

Cc: [email protected]
Acked-by: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Kay Sievers <[email protected]>
---
drivers/gpu/drm/drm_sysfs.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
index 5aa6780..186d081 100644
--- a/drivers/gpu/drm/drm_sysfs.c
+++ b/drivers/gpu/drm/drm_sysfs.c
@@ -359,8 +359,8 @@ int drm_sysfs_connector_add(struct drm_connector *connector)
DRM_DEBUG("adding \"%s\" to sysfs\n",
drm_get_connector_name(connector));

- snprintf(connector->kdev.bus_id, BUS_ID_SIZE, "card%d-%s",
- dev->primary->index, drm_get_connector_name(connector));
+ dev_set_name(&connector->kdev, "card%d-%s",
+ dev->primary->index, drm_get_connector_name(connector));
ret = device_register(&connector->kdev);

if (ret) {
--
1.6.2

2009-03-25 00:34:39

by Greg KH

[permalink] [raw]
Subject: [PATCH 14/61] rtc: struct device - replace bus_id with dev_name(), dev_set_name()

From: Kay Sievers <[email protected]>

Cc: [email protected]
Cc: [email protected]
Signed-off-by: Kay Sievers <[email protected]>
Signed-off-by: Alessandro Zummo <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/rtc/rtc-at91sam9.c | 4 ++--
drivers/rtc/rtc-omap.c | 4 ++--
drivers/rtc/rtc-twl4030.c | 2 +-
3 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/rtc/rtc-at91sam9.c b/drivers/rtc/rtc-at91sam9.c
index d5e4e63..86c61f1 100644
--- a/drivers/rtc/rtc-at91sam9.c
+++ b/drivers/rtc/rtc-at91sam9.c
@@ -351,7 +351,7 @@ static int __init at91_rtc_probe(struct platform_device *pdev)
/* register irq handler after we know what name we'll use */
ret = request_irq(AT91_ID_SYS, at91_rtc_interrupt,
IRQF_DISABLED | IRQF_SHARED,
- rtc->rtcdev->dev.bus_id, rtc);
+ dev_name(&rtc->rtcdev->dev), rtc);
if (ret) {
dev_dbg(&pdev->dev, "can't share IRQ %d?\n", AT91_ID_SYS);
rtc_device_unregister(rtc->rtcdev);
@@ -366,7 +366,7 @@ static int __init at91_rtc_probe(struct platform_device *pdev)

if (gpbr_readl(rtc) == 0)
dev_warn(&pdev->dev, "%s: SET TIME!\n",
- rtc->rtcdev->dev.bus_id);
+ dev_name(&rtc->rtcdev->dev));

return 0;

diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c
index 2cbeb07..bd1ce8e 100644
--- a/drivers/rtc/rtc-omap.c
+++ b/drivers/rtc/rtc-omap.c
@@ -377,13 +377,13 @@ static int __init omap_rtc_probe(struct platform_device *pdev)

/* handle periodic and alarm irqs */
if (request_irq(omap_rtc_timer, rtc_irq, IRQF_DISABLED,
- rtc->dev.bus_id, rtc)) {
+ dev_name(&rtc->dev), rtc)) {
pr_debug("%s: RTC timer interrupt IRQ%d already claimed\n",
pdev->name, omap_rtc_timer);
goto fail0;
}
if (request_irq(omap_rtc_alarm, rtc_irq, IRQF_DISABLED,
- rtc->dev.bus_id, rtc)) {
+ dev_name(&rtc->dev), rtc)) {
pr_debug("%s: RTC alarm interrupt IRQ%d already claimed\n",
pdev->name, omap_rtc_alarm);
goto fail1;
diff --git a/drivers/rtc/rtc-twl4030.c b/drivers/rtc/rtc-twl4030.c
index ad35f76..a6341e4 100644
--- a/drivers/rtc/rtc-twl4030.c
+++ b/drivers/rtc/rtc-twl4030.c
@@ -426,7 +426,7 @@ static int __devinit twl4030_rtc_probe(struct platform_device *pdev)

ret = request_irq(irq, twl4030_rtc_interrupt,
IRQF_TRIGGER_RISING,
- rtc->dev.bus_id, rtc);
+ dev_name(&rtc->dev), rtc);
if (ret < 0) {
dev_err(&pdev->dev, "IRQ is not free.\n");
goto out1;
--
1.6.2

2009-03-25 00:35:45

by Greg KH

[permalink] [raw]
Subject: [PATCH 17/61] v4l: struct device - replace bus_id with dev_name(), dev_set_name()

From: Kay Sievers <[email protected]>

Cc: [email protected]
Cc: [email protected]
Acked-by: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Kay Sievers <[email protected]>
---
drivers/media/radio/radio-tea5764.c | 3 ++-
drivers/media/video/v4l2-device.c | 2 +-
2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/media/radio/radio-tea5764.c b/drivers/media/radio/radio-tea5764.c
index 4d35308..3936238 100644
--- a/drivers/media/radio/radio-tea5764.c
+++ b/drivers/media/radio/radio-tea5764.c
@@ -298,7 +298,8 @@ static int vidioc_querycap(struct file *file, void *priv,

strlcpy(v->driver, dev->dev.driver->name, sizeof(v->driver));
strlcpy(v->card, dev->name, sizeof(v->card));
- snprintf(v->bus_info, sizeof(v->bus_info), "I2C:%s", dev->dev.bus_id);
+ snprintf(v->bus_info, sizeof(v->bus_info),
+ "I2C:%s", dev_name(&dev->dev));
v->version = RADIO_VERSION;
v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
return 0;
diff --git a/drivers/media/video/v4l2-device.c b/drivers/media/video/v4l2-device.c
index cf9d4c7..8a4b74f 100644
--- a/drivers/media/video/v4l2-device.c
+++ b/drivers/media/video/v4l2-device.c
@@ -34,7 +34,7 @@ int v4l2_device_register(struct device *dev, struct v4l2_device *v4l2_dev)
spin_lock_init(&v4l2_dev->lock);
v4l2_dev->dev = dev;
snprintf(v4l2_dev->name, sizeof(v4l2_dev->name), "%s %s",
- dev->driver->name, dev->bus_id);
+ dev->driver->name, dev_name(dev));
dev_set_drvdata(dev, v4l2_dev);
return 0;
}
--
1.6.2

2009-03-25 00:36:00

by Greg KH

[permalink] [raw]
Subject: [PATCH 18/61] amba: struct device - replace bus_id with dev_name(), dev_set_name()

From: Kay Sievers <[email protected]>

Acked-by: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Kay Sievers <[email protected]>
---
drivers/amba/bus.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c
index 00c46e0..3d763fd 100644
--- a/drivers/amba/bus.c
+++ b/drivers/amba/bus.c
@@ -210,7 +210,7 @@ int amba_device_register(struct amba_device *dev, struct resource *parent)
dev->dev.release = amba_device_release;
dev->dev.bus = &amba_bustype;
dev->dev.dma_mask = &dev->dma_mask;
- dev->res.name = dev->dev.bus_id;
+ dev->res.name = dev_name(&dev->dev);

if (!dev->dev.coherent_dma_mask && dev->dma_mask)
dev_warn(&dev->dev, "coherent dma mask is unset\n");
@@ -294,7 +294,7 @@ static int amba_find_match(struct device *dev, void *data)
if (d->parent)
r &= d->parent == dev->parent;
if (d->busid)
- r &= strcmp(dev->bus_id, d->busid) == 0;
+ r &= strcmp(dev_name(dev), d->busid) == 0;

if (r) {
get_device(dev);
--
1.6.2

2009-03-25 00:36:26

by Greg KH

[permalink] [raw]
Subject: [PATCH 20/61] dma: struct device - replace bus_id with dev_name(), dev_set_name()

From: Kay Sievers <[email protected]>

Cc: Dan Williams <[email protected]>
Acked-by: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Kay Sievers <[email protected]>
---
drivers/dma/dw_dmac.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c
index a97c07e..20ad3d2 100644
--- a/drivers/dma/dw_dmac.c
+++ b/drivers/dma/dw_dmac.c
@@ -1011,7 +1011,7 @@ static int __init dw_probe(struct platform_device *pdev)
dma_writel(dw, CFG, DW_CFG_DMA_EN);

printk(KERN_INFO "%s: DesignWare DMA Controller, %d channels\n",
- pdev->dev.bus_id, dw->dma.chancnt);
+ dev_name(&pdev->dev), dw->dma.chancnt);

dma_async_device_register(&dw->dma);

--
1.6.2

2009-03-25 00:36:42

by Greg KH

[permalink] [raw]
Subject: [PATCH 15/61] net: struct device - replace bus_id with dev_name(), dev_set_name()

From: Kay Sievers <[email protected]>

Cc: [email protected]
Cc: [email protected]
Acked-by: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Kay Sievers <[email protected]>
---
drivers/net/arm/ks8695net.c | 2 +-
drivers/net/au1000_eth.c | 8 ++++----
drivers/net/bfin_mac.c | 12 ++++++------
drivers/net/bmac.c | 2 +-
drivers/net/cpmac.c | 2 +-
drivers/net/declance.c | 6 +++---
drivers/net/depca.c | 6 +++---
drivers/net/ehea/ehea_main.c | 2 +-
drivers/net/jazzsonic.c | 6 ++++--
drivers/net/macb.c | 10 +++++-----
drivers/net/macsonic.c | 15 ++++++++-------
drivers/net/mv643xx_eth.c | 2 +-
drivers/net/sb1250-mac.c | 10 +++++-----
drivers/net/smc911x.c | 2 +-
drivers/net/smc91x.c | 2 +-
drivers/net/smsc911x.c | 7 ++++---
drivers/net/smsc9420.c | 4 ++--
drivers/net/tc35815.c | 4 ++--
drivers/net/xtsonic.c | 2 +-
19 files changed, 54 insertions(+), 50 deletions(-)

diff --git a/drivers/net/arm/ks8695net.c b/drivers/net/arm/ks8695net.c
index f3a1274..35cd264 100644
--- a/drivers/net/arm/ks8695net.c
+++ b/drivers/net/arm/ks8695net.c
@@ -1059,7 +1059,7 @@ ks8695_get_drvinfo(struct net_device *ndev, struct ethtool_drvinfo *info)
{
strlcpy(info->driver, MODULENAME, sizeof(info->driver));
strlcpy(info->version, MODULEVERSION, sizeof(info->version));
- strlcpy(info->bus_info, ndev->dev.parent->bus_id,
+ strlcpy(info->bus_info, dev_name(ndev->dev.parent),
sizeof(info->bus_info));
}

diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c
index 9c875bb..79aec32 100644
--- a/drivers/net/au1000_eth.c
+++ b/drivers/net/au1000_eth.c
@@ -355,8 +355,8 @@ static int mii_probe (struct net_device *dev)
/* now we are supposed to have a proper phydev, to attach to... */
BUG_ON(phydev->attached_dev);

- phydev = phy_connect(dev, phydev->dev.bus_id, &au1000_adjust_link, 0,
- PHY_INTERFACE_MODE_MII);
+ phydev = phy_connect(dev, dev_name(&phydev->dev), &au1000_adjust_link,
+ 0, PHY_INTERFACE_MODE_MII);

if (IS_ERR(phydev)) {
printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name);
@@ -381,8 +381,8 @@ static int mii_probe (struct net_device *dev)
aup->phy_dev = phydev;

printk(KERN_INFO "%s: attached PHY driver [%s] "
- "(mii_bus:phy_addr=%s, irq=%d)\n",
- dev->name, phydev->drv->name, phydev->dev.bus_id, phydev->irq);
+ "(mii_bus:phy_addr=%s, irq=%d)\n", dev->name,
+ phydev->drv->name, dev_name(&phydev->dev), phydev->irq);

return 0;
}
diff --git a/drivers/net/bfin_mac.c b/drivers/net/bfin_mac.c
index 78e31aa..9afe809 100644
--- a/drivers/net/bfin_mac.c
+++ b/drivers/net/bfin_mac.c
@@ -415,11 +415,11 @@ static int mii_probe(struct net_device *dev)
}

#if defined(CONFIG_BFIN_MAC_RMII)
- phydev = phy_connect(dev, phydev->dev.bus_id, &bfin_mac_adjust_link, 0,
- PHY_INTERFACE_MODE_RMII);
+ phydev = phy_connect(dev, dev_name(&phydev->dev), &bfin_mac_adjust_link,
+ 0, PHY_INTERFACE_MODE_RMII);
#else
- phydev = phy_connect(dev, phydev->dev.bus_id, &bfin_mac_adjust_link, 0,
- PHY_INTERFACE_MODE_MII);
+ phydev = phy_connect(dev, dev_name(&phydev->dev), &bfin_mac_adjust_link,
+ 0, PHY_INTERFACE_MODE_MII);
#endif

if (IS_ERR(phydev)) {
@@ -447,7 +447,7 @@ static int mii_probe(struct net_device *dev)
printk(KERN_INFO "%s: attached PHY driver [%s] "
"(mii_bus:phy_addr=%s, irq=%d, mdc_clk=%dHz(mdc_div=%d)"
"@sclk=%dMHz)\n",
- DRV_NAME, phydev->drv->name, phydev->dev.bus_id, phydev->irq,
+ DRV_NAME, phydev->drv->name, dev_name(&phydev->dev), phydev->irq,
MDC_CLK, mdc_div, sclk/1000000);

return 0;
@@ -488,7 +488,7 @@ static void bfin_mac_ethtool_getdrvinfo(struct net_device *dev,
strcpy(info->driver, DRV_NAME);
strcpy(info->version, DRV_VERSION);
strcpy(info->fw_version, "N/A");
- strcpy(info->bus_info, dev->dev.bus_id);
+ strcpy(info->bus_info, dev_name(&dev->dev));
}

static struct ethtool_ops bfin_mac_ethtool_ops = {
diff --git a/drivers/net/bmac.c b/drivers/net/bmac.c
index 8a546a3..1ab5837 100644
--- a/drivers/net/bmac.c
+++ b/drivers/net/bmac.c
@@ -1240,7 +1240,7 @@ static void bmac_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *inf
{
struct bmac_data *bp = netdev_priv(dev);
strcpy(info->driver, "bmac");
- strcpy(info->bus_info, bp->mdev->ofdev.dev.bus_id);
+ strcpy(info->bus_info, dev_name(&bp->mdev->ofdev.dev));
}

static const struct ethtool_ops bmac_ethtool_ops = {
diff --git a/drivers/net/cpmac.c b/drivers/net/cpmac.c
index f665487..79741c5 100644
--- a/drivers/net/cpmac.c
+++ b/drivers/net/cpmac.c
@@ -1161,7 +1161,7 @@ static int __devinit cpmac_probe(struct platform_device *pdev)
priv->msg_enable = netif_msg_init(debug_level, 0xff);
memcpy(dev->dev_addr, pdata->dev_addr, sizeof(dev->dev_addr));

- priv->phy = phy_connect(dev, cpmac_mii->phy_map[phy_id]->dev.bus_id,
+ priv->phy = phy_connect(dev, dev_name(&cpmac_mii->phy_map[phy_id]->dev),
&cpmac_adjust_link, 0, PHY_INTERFACE_MODE_MII);
if (IS_ERR(priv->phy)) {
if (netif_msg_drv(priv))
diff --git a/drivers/net/declance.c b/drivers/net/declance.c
index 7ce3053..861c867 100644
--- a/drivers/net/declance.c
+++ b/drivers/net/declance.c
@@ -1027,7 +1027,7 @@ static int __init dec_lance_probe(struct device *bdev, const int type)
printk(version);

if (bdev)
- snprintf(name, sizeof(name), "%s", bdev->bus_id);
+ snprintf(name, sizeof(name), "%s", dev_name(bdev));
else {
i = 0;
dev = root_lance_dev;
@@ -1105,10 +1105,10 @@ static int __init dec_lance_probe(struct device *bdev, const int type)

start = to_tc_dev(bdev)->resource.start;
len = to_tc_dev(bdev)->resource.end - start + 1;
- if (!request_mem_region(start, len, bdev->bus_id)) {
+ if (!request_mem_region(start, len, dev_name(bdev))) {
printk(KERN_ERR
"%s: Unable to reserve MMIO resource\n",
- bdev->bus_id);
+ dev_name(bdev));
ret = -EBUSY;
goto err_out_dev;
}
diff --git a/drivers/net/depca.c b/drivers/net/depca.c
index e4cef49..55625db 100644
--- a/drivers/net/depca.c
+++ b/drivers/net/depca.c
@@ -606,8 +606,8 @@ static int __init depca_hw_init (struct net_device *dev, struct device *device)
if (!mem_start || lp->adapter < DEPCA || lp->adapter >=unknown)
return -ENXIO;

- printk ("%s: %s at 0x%04lx",
- device->bus_id, depca_signature[lp->adapter], ioaddr);
+ printk("%s: %s at 0x%04lx",
+ dev_name(device), depca_signature[lp->adapter], ioaddr);

switch (lp->depca_bus) {
#ifdef CONFIG_MCA
@@ -669,7 +669,7 @@ static int __init depca_hw_init (struct net_device *dev, struct device *device)

spin_lock_init(&lp->lock);
sprintf(lp->adapter_name, "%s (%s)",
- depca_signature[lp->adapter], device->bus_id);
+ depca_signature[lp->adapter], dev_name(device));
status = -EBUSY;

/* Initialisation Block */
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c
index dfe9226..8e7c165 100644
--- a/drivers/net/ehea/ehea_main.c
+++ b/drivers/net/ehea/ehea_main.c
@@ -3040,7 +3040,7 @@ static struct device *ehea_register_port(struct ehea_port *port,
port->ofdev.dev.parent = &port->adapter->ofdev->dev;
port->ofdev.dev.bus = &ibmebus_bus_type;

- sprintf(port->ofdev.dev.bus_id, "port%d", port_name_cnt++);
+ dev_set_name(&port->ofdev.dev, "port%d", port_name_cnt++);
port->ofdev.dev.release = logical_port_release;

ret = of_device_register(&port->ofdev);
diff --git a/drivers/net/jazzsonic.c b/drivers/net/jazzsonic.c
index 334ff9e..14248cf 100644
--- a/drivers/net/jazzsonic.c
+++ b/drivers/net/jazzsonic.c
@@ -131,7 +131,8 @@ static int __init sonic_probe1(struct net_device *dev)
if (sonic_debug && version_printed++ == 0)
printk(version);

- printk(KERN_INFO "%s: Sonic ethernet found at 0x%08lx, ", lp->device->bus_id, dev->base_addr);
+ printk(KERN_INFO "%s: Sonic ethernet found at 0x%08lx, ",
+ dev_name(lp->device), dev->base_addr);

/*
* Put the sonic into software reset, then
@@ -156,7 +157,8 @@ static int __init sonic_probe1(struct net_device *dev)
if ((lp->descriptors = dma_alloc_coherent(lp->device,
SIZEOF_SONIC_DESC * SONIC_BUS_SCALE(lp->dma_bitmode),
&lp->descriptors_laddr, GFP_KERNEL)) == NULL) {
- printk(KERN_ERR "%s: couldn't alloc DMA memory for descriptors.\n", lp->device->bus_id);
+ printk(KERN_ERR "%s: couldn't alloc DMA memory for descriptors.\n",
+ dev_name(lp->device));
goto out;
}

diff --git a/drivers/net/macb.c b/drivers/net/macb.c
index f6c4936..f408654 100644
--- a/drivers/net/macb.c
+++ b/drivers/net/macb.c
@@ -211,10 +211,10 @@ static int macb_mii_probe(struct net_device *dev)

/* attach the mac to the phy */
if (pdata && pdata->is_rmii) {
- phydev = phy_connect(dev, phydev->dev.bus_id,
+ phydev = phy_connect(dev, dev_name(&phydev->dev),
&macb_handle_link_change, 0, PHY_INTERFACE_MODE_RMII);
} else {
- phydev = phy_connect(dev, phydev->dev.bus_id,
+ phydev = phy_connect(dev, dev_name(&phydev->dev),
&macb_handle_link_change, 0, PHY_INTERFACE_MODE_MII);
}

@@ -1077,7 +1077,7 @@ static void macb_get_drvinfo(struct net_device *dev,

strcpy(info->driver, bp->pdev->dev.driver->name);
strcpy(info->version, "$Revision: 1.14 $");
- strcpy(info->bus_info, bp->pdev->dev.bus_id);
+ strcpy(info->bus_info, dev_name(&bp->pdev->dev));
}

static struct ethtool_ops macb_ethtool_ops = {
@@ -1234,8 +1234,8 @@ static int __init macb_probe(struct platform_device *pdev)

phydev = bp->phy_dev;
printk(KERN_INFO "%s: attached PHY driver [%s] "
- "(mii_bus:phy_addr=%s, irq=%d)\n",
- dev->name, phydev->drv->name, phydev->dev.bus_id, phydev->irq);
+ "(mii_bus:phy_addr=%s, irq=%d)\n", dev->name,
+ phydev->drv->name, dev_name(&phydev->dev), phydev->irq);

return 0;

diff --git a/drivers/net/macsonic.c b/drivers/net/macsonic.c
index 205bb05..527166e 100644
--- a/drivers/net/macsonic.c
+++ b/drivers/net/macsonic.c
@@ -176,7 +176,8 @@ static int __init macsonic_init(struct net_device *dev)
if ((lp->descriptors = dma_alloc_coherent(lp->device,
SIZEOF_SONIC_DESC * SONIC_BUS_SCALE(lp->dma_bitmode),
&lp->descriptors_laddr, GFP_KERNEL)) == NULL) {
- printk(KERN_ERR "%s: couldn't alloc DMA memory for descriptors.\n", lp->device->bus_id);
+ printk(KERN_ERR "%s: couldn't alloc DMA memory for descriptors.\n",
+ dev_name(lp->device));
return -ENOMEM;
}

@@ -337,7 +338,7 @@ static int __init mac_onboard_sonic_probe(struct net_device *dev)
sonic_version_printed = 1;
}
printk(KERN_INFO "%s: onboard / comm-slot SONIC at 0x%08lx\n",
- lp->device->bus_id, dev->base_addr);
+ dev_name(lp->device), dev->base_addr);

/* The PowerBook's SONIC is 16 bit always. */
if (macintosh_config->ident == MAC_MODEL_PB520) {
@@ -370,10 +371,10 @@ static int __init mac_onboard_sonic_probe(struct net_device *dev)
}
printk(KERN_INFO
"%s: revision 0x%04x, using %d bit DMA and register offset %d\n",
- lp->device->bus_id, sr, lp->dma_bitmode?32:16, lp->reg_offset);
+ dev_name(lp->device), sr, lp->dma_bitmode?32:16, lp->reg_offset);

#if 0 /* This is sometimes useful to find out how MacOS configured the card. */
- printk(KERN_INFO "%s: DCR: 0x%04x, DCR2: 0x%04x\n", lp->device->bus_id,
+ printk(KERN_INFO "%s: DCR: 0x%04x, DCR2: 0x%04x\n", dev_name(lp->device),
SONIC_READ(SONIC_DCR) & 0xffff, SONIC_READ(SONIC_DCR2) & 0xffff);
#endif

@@ -525,12 +526,12 @@ static int __init mac_nubus_sonic_probe(struct net_device *dev)
sonic_version_printed = 1;
}
printk(KERN_INFO "%s: %s in slot %X\n",
- lp->device->bus_id, ndev->board->name, ndev->board->slot);
+ dev_name(lp->device), ndev->board->name, ndev->board->slot);
printk(KERN_INFO "%s: revision 0x%04x, using %d bit DMA and register offset %d\n",
- lp->device->bus_id, SONIC_READ(SONIC_SR), dma_bitmode?32:16, reg_offset);
+ dev_name(lp->device), SONIC_READ(SONIC_SR), dma_bitmode?32:16, reg_offset);

#if 0 /* This is sometimes useful to find out how MacOS configured the card. */
- printk(KERN_INFO "%s: DCR: 0x%04x, DCR2: 0x%04x\n", lp->device->bus_id,
+ printk(KERN_INFO "%s: DCR: 0x%04x, DCR2: 0x%04x\n", dev_name(lp->device),
SONIC_READ(SONIC_DCR) & 0xffff, SONIC_READ(SONIC_DCR2) & 0xffff);
#endif

diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index b0bc3bc..fe4e158 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -2588,7 +2588,7 @@ static void phy_init(struct mv643xx_eth_private *mp, int speed, int duplex)

phy_reset(mp);

- phy_attach(mp->dev, phy->dev.bus_id, 0, PHY_INTERFACE_MODE_GMII);
+ phy_attach(mp->dev, dev_name(&phy->dev), 0, PHY_INTERFACE_MODE_GMII);

if (speed == 0) {
phy->autoneg = AUTONEG_ENABLE;
diff --git a/drivers/net/sb1250-mac.c b/drivers/net/sb1250-mac.c
index 31e38fa..845431c 100644
--- a/drivers/net/sb1250-mac.c
+++ b/drivers/net/sb1250-mac.c
@@ -2478,7 +2478,7 @@ static int sbmac_mii_probe(struct net_device *dev)
return -ENXIO;
}

- phy_dev = phy_connect(dev, phy_dev->dev.bus_id, &sbmac_mii_poll, 0,
+ phy_dev = phy_connect(dev, dev_name(&phy_dev->dev), &sbmac_mii_poll, 0,
PHY_INTERFACE_MODE_GMII);
if (IS_ERR(phy_dev)) {
printk(KERN_ERR "%s: could not attach to PHY\n", dev->name);
@@ -2500,7 +2500,7 @@ static int sbmac_mii_probe(struct net_device *dev)

pr_info("%s: attached PHY driver [%s] (mii_bus:phy_addr=%s, irq=%d)\n",
dev->name, phy_dev->drv->name,
- phy_dev->dev.bus_id, phy_dev->irq);
+ dev_name(&phy_dev->dev), phy_dev->irq);

sc->phy_dev = phy_dev;

@@ -2697,7 +2697,7 @@ static int __init sbmac_probe(struct platform_device *pldev)
sbm_base = ioremap_nocache(res->start, res->end - res->start + 1);
if (!sbm_base) {
printk(KERN_ERR "%s: unable to map device registers\n",
- pldev->dev.bus_id);
+ dev_name(&pldev->dev));
err = -ENOMEM;
goto out_out;
}
@@ -2708,7 +2708,7 @@ static int __init sbmac_probe(struct platform_device *pldev)
* If we find a zero, skip this MAC.
*/
sbmac_orig_hwaddr = __raw_readq(sbm_base + R_MAC_ETHERNET_ADDR);
- pr_debug("%s: %sconfiguring MAC at 0x%08Lx\n", pldev->dev.bus_id,
+ pr_debug("%s: %sconfiguring MAC at 0x%08Lx\n", dev_name(&pldev->dev),
sbmac_orig_hwaddr ? "" : "not ", (long long)res->start);
if (sbmac_orig_hwaddr == 0) {
err = 0;
@@ -2721,7 +2721,7 @@ static int __init sbmac_probe(struct platform_device *pldev)
dev = alloc_etherdev(sizeof(struct sbmac_softc));
if (!dev) {
printk(KERN_ERR "%s: unable to allocate etherdev\n",
- pldev->dev.bus_id);
+ dev_name(&pldev->dev));
err = -ENOMEM;
goto out_unmap;
}
diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c
index 223cde0..2936103 100644
--- a/drivers/net/smc911x.c
+++ b/drivers/net/smc911x.c
@@ -1545,7 +1545,7 @@ smc911x_ethtool_getdrvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
{
strncpy(info->driver, CARDNAME, sizeof(info->driver));
strncpy(info->version, version, sizeof(info->version));
- strncpy(info->bus_info, dev->dev.parent->bus_id, sizeof(info->bus_info));
+ strncpy(info->bus_info, dev_name(dev->dev.parent), sizeof(info->bus_info));
}

static int smc911x_ethtool_nwayreset(struct net_device *dev)
diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c
index b215a8d..0b6da95 100644
--- a/drivers/net/smc91x.c
+++ b/drivers/net/smc91x.c
@@ -1614,7 +1614,7 @@ smc_ethtool_getdrvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
{
strncpy(info->driver, CARDNAME, sizeof(info->driver));
strncpy(info->version, version, sizeof(info->version));
- strncpy(info->bus_info, dev->dev.parent->bus_id, sizeof(info->bus_info));
+ strncpy(info->bus_info, dev_name(dev->dev.parent), sizeof(info->bus_info));
}

static int smc_ethtool_nwayreset(struct net_device *dev)
diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c
index d1590ac..ab18ee0 100644
--- a/drivers/net/smsc911x.c
+++ b/drivers/net/smsc911x.c
@@ -769,7 +769,7 @@ static int smsc911x_mii_probe(struct net_device *dev)
return -ENODEV;
}

- phydev = phy_connect(dev, phydev->dev.bus_id,
+ phydev = phy_connect(dev, dev_name(&phydev->dev),
&smsc911x_phy_adjust_link, 0, pdata->config.phy_interface);

if (IS_ERR(phydev)) {
@@ -778,7 +778,8 @@ static int smsc911x_mii_probe(struct net_device *dev)
}

pr_info("%s: attached PHY driver [%s] (mii_bus:phy_addr=%s, irq=%d)\n",
- dev->name, phydev->drv->name, phydev->dev.bus_id, phydev->irq);
+ dev->name, phydev->drv->name,
+ dev_name(&phydev->dev), phydev->irq);

/* mask with MAC supported features */
phydev->supported &= (PHY_BASIC_FEATURES | SUPPORTED_Pause |
@@ -1549,7 +1550,7 @@ static void smsc911x_ethtool_getdrvinfo(struct net_device *dev,
{
strlcpy(info->driver, SMSC_CHIPNAME, sizeof(info->driver));
strlcpy(info->version, SMSC_DRV_VERSION, sizeof(info->version));
- strlcpy(info->bus_info, dev->dev.parent->bus_id,
+ strlcpy(info->bus_info, dev_name(dev->dev.parent),
sizeof(info->bus_info));
}

diff --git a/drivers/net/smsc9420.c b/drivers/net/smsc9420.c
index 4e15ae0..72f1348 100644
--- a/drivers/net/smsc9420.c
+++ b/drivers/net/smsc9420.c
@@ -1160,7 +1160,7 @@ static int smsc9420_mii_probe(struct net_device *dev)
smsc_info(PROBE, "PHY addr %d, phy_id 0x%08X", phydev->addr,
phydev->phy_id);

- phydev = phy_connect(dev, phydev->dev.bus_id,
+ phydev = phy_connect(dev, dev_name(&phydev->dev),
&smsc9420_phy_adjust_link, 0, PHY_INTERFACE_MODE_MII);

if (IS_ERR(phydev)) {
@@ -1169,7 +1169,7 @@ static int smsc9420_mii_probe(struct net_device *dev)
}

pr_info("%s: attached PHY driver [%s] (mii_bus:phy_addr=%s, irq=%d)\n",
- dev->name, phydev->drv->name, phydev->dev.bus_id, phydev->irq);
+ dev->name, phydev->drv->name, dev_name(&phydev->dev), phydev->irq);

/* mask with MAC supported features */
phydev->supported &= (PHY_BASIC_FEATURES | SUPPORTED_Pause |
diff --git a/drivers/net/tc35815.c b/drivers/net/tc35815.c
index bcd0e60..e1f8eb9 100644
--- a/drivers/net/tc35815.c
+++ b/drivers/net/tc35815.c
@@ -725,7 +725,7 @@ static int tc_mii_probe(struct net_device *dev)
}

/* attach the mac to the phy */
- phydev = phy_connect(dev, phydev->dev.bus_id,
+ phydev = phy_connect(dev, dev_name(&phydev->dev),
&tc_handle_link_change, 0,
lp->chiptype == TC35815_TX4939 ?
PHY_INTERFACE_MODE_RMII : PHY_INTERFACE_MODE_MII);
@@ -735,7 +735,7 @@ static int tc_mii_probe(struct net_device *dev)
}
printk(KERN_INFO "%s: attached PHY driver [%s] "
"(mii_bus:phy_addr=%s, id=%x)\n",
- dev->name, phydev->drv->name, phydev->dev.bus_id,
+ dev->name, phydev->drv->name, dev_name(&phydev->dev),
phydev->phy_id);

/* mask with MAC supported features */
diff --git a/drivers/net/xtsonic.c b/drivers/net/xtsonic.c
index 03a3f34..a12a721 100644
--- a/drivers/net/xtsonic.c
+++ b/drivers/net/xtsonic.c
@@ -183,7 +183,7 @@ static int __init sonic_probe1(struct net_device *dev)

if (lp->descriptors == NULL) {
printk(KERN_ERR "%s: couldn't alloc DMA memory for "
- " descriptors.\n", lp->device->bus_id);
+ " descriptors.\n", dev_name(lp->device));
goto out;
}

--
1.6.2

2009-03-25 00:37:05

by Greg KH

[permalink] [raw]
Subject: [PATCH 21/61] eisa: struct device - replace bus_id with dev_name(), dev_set_name()

From: Kay Sievers <[email protected]>

Acked-by: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Kay Sievers <[email protected]>
---
drivers/eisa/eisa-bus.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/eisa/eisa-bus.c b/drivers/eisa/eisa-bus.c
index c950bf8..66958b3 100644
--- a/drivers/eisa/eisa-bus.c
+++ b/drivers/eisa/eisa-bus.c
@@ -200,7 +200,7 @@ static int __init eisa_init_device (struct eisa_root_device *root,
edev->dev.bus = &eisa_bus_type;
edev->dev.dma_mask = &edev->dma_mask;
edev->dev.coherent_dma_mask = edev->dma_mask;
- sprintf (edev->dev.bus_id, "%02X:%02X", root->bus_nr, slot);
+ dev_set_name(&edev->dev, "%02X:%02X", root->bus_nr, slot);

for (i = 0; i < EISA_MAX_RESOURCES; i++) {
#ifdef CONFIG_EISA_NAMES
@@ -301,7 +301,7 @@ static int __init eisa_probe (struct eisa_root_device *root)
struct eisa_device *edev;

printk (KERN_INFO "EISA: Probing bus %d at %s\n",
- root->bus_nr, root->dev->bus_id);
+ root->bus_nr, dev_name(root->dev));

/* First try to get hold of slot 0. If there is no device
* here, simply fail, unless root->force_probe is set. */
--
1.6.2

2009-03-25 00:37:37

by Greg KH

[permalink] [raw]
Subject: [PATCH 22/61] gpio: struct device - replace bus_id with dev_name(), dev_set_name()

From: Kay Sievers <[email protected]>

Cc: Michael Buesch <[email protected]>
Acked-by: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Kay Sievers <[email protected]>
---
drivers/gpio/bt8xxgpio.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/gpio/bt8xxgpio.c b/drivers/gpio/bt8xxgpio.c
index 7a11682..984b587 100644
--- a/drivers/gpio/bt8xxgpio.c
+++ b/drivers/gpio/bt8xxgpio.c
@@ -160,7 +160,7 @@ static void bt8xxgpio_gpio_setup(struct bt8xxgpio *bg)
{
struct gpio_chip *c = &bg->gpio;

- c->label = bg->pdev->dev.bus_id;
+ c->label = dev_name(&bg->pdev->dev);
c->owner = THIS_MODULE;
c->direction_input = bt8xxgpio_gpio_direction_input;
c->get = bt8xxgpio_gpio_get;
--
1.6.2

2009-03-25 00:37:53

by Greg KH

[permalink] [raw]
Subject: [PATCH 19/61] dio: struct device - replace bus_id with dev_name(), dev_set_name()

From: Kay Sievers <[email protected]>

Acked-by: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Kay Sievers <[email protected]>
---
drivers/dio/dio.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/dio/dio.c b/drivers/dio/dio.c
index 10c3c49..55dd88d 100644
--- a/drivers/dio/dio.c
+++ b/drivers/dio/dio.c
@@ -182,7 +182,7 @@ static int __init dio_init(void)

/* Initialize the DIO bus */
INIT_LIST_HEAD(&dio_bus.devices);
- strcpy(dio_bus.dev.bus_id, "dio");
+ dev_set_name(&dio_bus.dev, "dio");
error = device_register(&dio_bus.dev);
if (error) {
pr_err("DIO: Error registering dio_bus\n");
@@ -237,7 +237,7 @@ static int __init dio_init(void)
dev->scode = scode;
dev->resource.start = pa;
dev->resource.end = pa + DIO_SIZE(scode, va);
- sprintf(dev->dev.bus_id,"%02x", scode);
+ dev_set_name(&dev->dev, "%02x", scode);

/* read the ID byte(s) and encode if necessary. */
prid = DIO_ID(va);
--
1.6.2

2009-03-25 00:38:23

by Greg KH

[permalink] [raw]
Subject: [PATCH 23/61] mca: struct device - replace bus_id with dev_name(), dev_set_name()

From: Kay Sievers <[email protected]>

Cc: [email protected]
Acked-by: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Kay Sievers <[email protected]>
---
drivers/mca/mca-bus.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/mca/mca-bus.c b/drivers/mca/mca-bus.c
index ef2dbfe..ada5ebb 100644
--- a/drivers/mca/mca-bus.c
+++ b/drivers/mca/mca-bus.c
@@ -110,7 +110,7 @@ int __init mca_register_device(int bus, struct mca_device *mca_dev)

mca_dev->dev.parent = &mca_bus->dev;
mca_dev->dev.bus = &mca_bus_type;
- sprintf (mca_dev->dev.bus_id, "%02d:%02X", bus, mca_dev->slot);
+ dev_set_name(&mca_dev->dev, "%02d:%02X", bus, mca_dev->slot);
mca_dev->dma_mask = mca_bus->default_dma_mask;
mca_dev->dev.dma_mask = &mca_dev->dma_mask;
mca_dev->dev.coherent_dma_mask = mca_dev->dma_mask;
@@ -151,7 +151,7 @@ struct mca_bus * __devinit mca_attach_bus(int bus)
if (!mca_bus)
return NULL;

- sprintf(mca_bus->dev.bus_id,"mca%d",bus);
+ dev_set_name(&mca_bus->dev, "mca%d", bus);
sprintf(mca_bus->name,"Host %s MCA Bridge", bus ? "Secondary" : "Primary");
if (device_register(&mca_bus->dev)) {
kfree(mca_bus);
--
1.6.2

2009-03-25 00:38:41

by Greg KH

[permalink] [raw]
Subject: [PATCH 24/61] mfd: struct device - replace bus_id with dev_name(), dev_set_name()

From: Kay Sievers <[email protected]>

Cc: [email protected]
Acked-by: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Kay Sievers <[email protected]>
---
drivers/mfd/mcp-core.c | 2 +-
drivers/mfd/ucb1x00-core.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/mfd/mcp-core.c b/drivers/mfd/mcp-core.c
index 6063dc2..57271cb 100644
--- a/drivers/mfd/mcp-core.c
+++ b/drivers/mfd/mcp-core.c
@@ -214,7 +214,7 @@ EXPORT_SYMBOL(mcp_host_alloc);

int mcp_host_register(struct mcp *mcp)
{
- strcpy(mcp->attached_device.bus_id, "mcp0");
+ dev_set_name(&mcp->attached_device, "mcp0");
return device_register(&mcp->attached_device);
}
EXPORT_SYMBOL(mcp_host_register);
diff --git a/drivers/mfd/ucb1x00-core.c b/drivers/mfd/ucb1x00-core.c
index 6860c92..fea9085 100644
--- a/drivers/mfd/ucb1x00-core.c
+++ b/drivers/mfd/ucb1x00-core.c
@@ -492,7 +492,7 @@ static int ucb1x00_probe(struct mcp *mcp)

ucb->dev.class = &ucb1x00_class;
ucb->dev.parent = &mcp->attached_device;
- strlcpy(ucb->dev.bus_id, "ucb1x00", sizeof(ucb->dev.bus_id));
+ dev_set_name(&ucb->dev, "ucb1x00");

spin_lock_init(&ucb->lock);
spin_lock_init(&ucb->io_lock);
--
1.6.2

2009-03-25 00:38:56

by Greg KH

[permalink] [raw]
Subject: [PATCH 25/61] wimax: struct device - replace bus_id with dev_name(), dev_set_name()

From: Kay Sievers <[email protected]>

Cc: [email protected]
Cc: [email protected]
Acked-by: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Kay Sievers <[email protected]>
---
drivers/net/wimax/i2400m/driver.c | 2 +-
drivers/net/wimax/i2400m/usb-notif.c | 2 +-
include/linux/wimax/debug.h | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wimax/i2400m/driver.c b/drivers/net/wimax/i2400m/driver.c
index e80a0b6..d58b971 100644
--- a/drivers/net/wimax/i2400m/driver.c
+++ b/drivers/net/wimax/i2400m/driver.c
@@ -613,7 +613,7 @@ int i2400m_setup(struct i2400m *i2400m, enum i2400m_bri bm_flags)
d_fnstart(3, dev, "(i2400m %p)\n", i2400m);

snprintf(wimax_dev->name, sizeof(wimax_dev->name),
- "i2400m-%s:%s", dev->bus->name, dev->bus_id);
+ "i2400m-%s:%s", dev->bus->name, dev_name(dev));

i2400m->bm_cmd_buf = kzalloc(I2400M_BM_CMD_BUF_SIZE, GFP_KERNEL);
if (i2400m->bm_cmd_buf == NULL) {
diff --git a/drivers/net/wimax/i2400m/usb-notif.c b/drivers/net/wimax/i2400m/usb-notif.c
index 9702c22..0528879 100644
--- a/drivers/net/wimax/i2400m/usb-notif.c
+++ b/drivers/net/wimax/i2400m/usb-notif.c
@@ -102,7 +102,7 @@ int i2400mu_notification_grok(struct i2400mu *i2400mu, const void *buf,
dev_err(dev, "HW BUG? Unknown/unexpected data in notification "
"message (%zu bytes)\n", buf_len);
snprintf(prefix, sizeof(prefix), "%s %s: ",
- dev_driver_string(dev) , dev->bus_id);
+ dev_driver_string(dev) , dev_name(dev));
if (buf_len > 64) {
print_hex_dump(KERN_ERR, prefix, DUMP_PREFIX_OFFSET,
8, 4, buf, 64, 0);
diff --git a/include/linux/wimax/debug.h b/include/linux/wimax/debug.h
index ba0c493..c703e03 100644
--- a/include/linux/wimax/debug.h
+++ b/include/linux/wimax/debug.h
@@ -178,7 +178,7 @@ void __d_head(char *head, size_t head_size,
WARN_ON(1);
} else
snprintf(head, head_size, "%s %s: ",
- dev_driver_string(dev), dev->bus_id);
+ dev_driver_string(dev), dev_name(dev));
}


--
1.6.2

2009-03-25 00:39:24

by Greg KH

[permalink] [raw]
Subject: [PATCH 27/61] PS3: replace bus_id usage

These simple debug statments should be using dev_dbg() instead of
accessing bus_id directly (or they should use device_name).

As bus_id is going away, this patch is necessary.

Acked-by: Geoff Levand <[email protected]>
Cc: Kay Sievers <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
arch/powerpc/platforms/ps3/system-bus.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/platforms/ps3/system-bus.c b/arch/powerpc/platforms/ps3/system-bus.c
index 58311a8..a705fff 100644
--- a/arch/powerpc/platforms/ps3/system-bus.c
+++ b/arch/powerpc/platforms/ps3/system-bus.c
@@ -376,7 +376,7 @@ static int ps3_system_bus_probe(struct device *_dev)
struct ps3_system_bus_driver *drv;

BUG_ON(!dev);
- pr_debug(" -> %s:%d: %s\n", __func__, __LINE__, _dev->bus_id);
+ dev_dbg(_dev, "%s:%d\n", __func__, __LINE__);

drv = ps3_system_bus_dev_to_system_bus_drv(dev);
BUG_ON(!drv);
@@ -398,7 +398,7 @@ static int ps3_system_bus_remove(struct device *_dev)
struct ps3_system_bus_driver *drv;

BUG_ON(!dev);
- pr_debug(" -> %s:%d: %s\n", __func__, __LINE__, _dev->bus_id);
+ dev_dbg(_dev, "%s:%d\n", __func__, __LINE__);

drv = ps3_system_bus_dev_to_system_bus_drv(dev);
BUG_ON(!drv);
--
1.6.2

2009-03-25 00:39:40

by Greg KH

[permalink] [raw]
Subject: [PATCH 26/61] usb: struct device - replace bus_id with dev_name(), dev_set_name()

From: Kay Sievers <[email protected]>

Acked-by: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Kay Sievers <[email protected]>
---
drivers/usb/gadget/ci13xxx_udc.c | 2 +-
drivers/usb/gadget/imx_udc.c | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/gadget/ci13xxx_udc.c b/drivers/usb/gadget/ci13xxx_udc.c
index bebf911..7f4e5eb 100644
--- a/drivers/usb/gadget/ci13xxx_udc.c
+++ b/drivers/usb/gadget/ci13xxx_udc.c
@@ -2626,7 +2626,7 @@ static int udc_probe(struct device *dev, void __iomem *regs, const char *name)
INIT_LIST_HEAD(&udc->gadget.ep_list);
udc->gadget.ep0 = NULL;

- strcpy(udc->gadget.dev.bus_id, "gadget");
+ dev_set_name(&udc->gadget.dev, "gadget");
udc->gadget.dev.dma_mask = dev->dma_mask;
udc->gadget.dev.parent = dev;
udc->gadget.dev.release = udc_release;
diff --git a/drivers/usb/gadget/imx_udc.c b/drivers/usb/gadget/imx_udc.c
index 77c5d0a..cd67ac7 100644
--- a/drivers/usb/gadget/imx_udc.c
+++ b/drivers/usb/gadget/imx_udc.c
@@ -1186,8 +1186,8 @@ static struct imx_udc_struct controller = {
.ep0 = &controller.imx_ep[0].ep,
.name = driver_name,
.dev = {
- .bus_id = "gadget",
- },
+ .init_name = "gadget",
+ },
},

.imx_ep[0] = {
--
1.6.2

2009-03-25 00:40:36

by Greg KH

[permalink] [raw]
Subject: [PATCH 29/61] driver core: get rid of struct device's bus_id string array

From: Kay Sievers <[email protected]>

Now that all users of bus_id is gone, we can remove it from struct
device.

Signed-off-by: Kay Sievers <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/base/core.c | 39 +++++++++++++++++++--------------------
include/linux/device.h | 4 +---
include/linux/kobject.h | 2 ++
lib/kobject.c | 2 +-
4 files changed, 23 insertions(+), 24 deletions(-)

diff --git a/drivers/base/core.c b/drivers/base/core.c
index f3eae63..059966b 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -777,17 +777,12 @@ static void device_remove_class_symlinks(struct device *dev)
int dev_set_name(struct device *dev, const char *fmt, ...)
{
va_list vargs;
- char *s;
+ int err;

va_start(vargs, fmt);
- vsnprintf(dev->bus_id, sizeof(dev->bus_id), fmt, vargs);
+ err = kobject_set_name_vargs(&dev->kobj, fmt, vargs);
va_end(vargs);
-
- /* ewww... some of these buggers have / in the name... */
- while ((s = strchr(dev->bus_id, '/')))
- *s = '!';
-
- return 0;
+ return err;
}
EXPORT_SYMBOL_GPL(dev_set_name);

@@ -864,12 +859,17 @@ int device_add(struct device *dev)
if (!dev)
goto done;

- /* Temporarily support init_name if it is set.
- * It will override bus_id for now */
- if (dev->init_name)
- dev_set_name(dev, "%s", dev->init_name);
+ /*
+ * for statically allocated devices, which should all be converted
+ * some day, we need to initialize the name. We prevent reading back
+ * the name, and force the use of dev_name()
+ */
+ if (dev->init_name) {
+ dev_set_name(dev, dev->init_name);
+ dev->init_name = NULL;
+ }

- if (!strlen(dev->bus_id))
+ if (!dev_name(dev))
goto done;

pr_debug("device: '%s': %s\n", dev_name(dev), __func__);
@@ -1348,7 +1348,10 @@ struct device *device_create_vargs(struct class *class, struct device *parent,
dev->release = device_create_release;
dev_set_drvdata(dev, drvdata);

- vsnprintf(dev->bus_id, BUS_ID_SIZE, fmt, args);
+ retval = kobject_set_name_vargs(&dev->kobj, fmt, args);
+ if (retval)
+ goto error;
+
retval = device_register(dev);
if (retval)
goto error;
@@ -1452,19 +1455,15 @@ int device_rename(struct device *dev, char *new_name)
old_class_name = make_class_name(dev->class->name, &dev->kobj);
#endif

- old_device_name = kmalloc(BUS_ID_SIZE, GFP_KERNEL);
+ old_device_name = kstrdup(dev_name(dev), GFP_KERNEL);
if (!old_device_name) {
error = -ENOMEM;
goto out;
}
- strlcpy(old_device_name, dev->bus_id, BUS_ID_SIZE);
- strlcpy(dev->bus_id, new_name, BUS_ID_SIZE);

error = kobject_rename(&dev->kobj, new_name);
- if (error) {
- strlcpy(dev->bus_id, old_device_name, BUS_ID_SIZE);
+ if (error)
goto out;
- }

#ifdef CONFIG_SYSFS_DEPRECATED
if (old_class_name) {
diff --git a/include/linux/device.h b/include/linux/device.h
index 47f343c..d5706c4 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -374,7 +374,6 @@ struct device {
struct device *parent;

struct kobject kobj;
- char bus_id[BUS_ID_SIZE]; /* position on parent bus */
unsigned uevent_suppress:1;
const char *init_name; /* initial name of the device */
struct device_type *type;
@@ -427,8 +426,7 @@ struct device {

static inline const char *dev_name(const struct device *dev)
{
- /* will be changed into kobject_name(&dev->kobj) in the near future */
- return dev->bus_id;
+ return kobject_name(&dev->kobj);
}

extern int dev_set_name(struct device *dev, const char *name, ...)
diff --git a/include/linux/kobject.h b/include/linux/kobject.h
index 5437ac0..c9c214d 100644
--- a/include/linux/kobject.h
+++ b/include/linux/kobject.h
@@ -72,6 +72,8 @@ struct kobject {

extern int kobject_set_name(struct kobject *kobj, const char *name, ...)
__attribute__((format(printf, 2, 3)));
+extern int kobject_set_name_vargs(struct kobject *kobj, const char *fmt,
+ va_list vargs);

static inline const char *kobject_name(const struct kobject *kobj)
{
diff --git a/lib/kobject.c b/lib/kobject.c
index 0487d1f..a6dec32 100644
--- a/lib/kobject.c
+++ b/lib/kobject.c
@@ -212,7 +212,7 @@ static int kobject_add_internal(struct kobject *kobj)
* @fmt: format string used to build the name
* @vargs: vargs to format the string.
*/
-static int kobject_set_name_vargs(struct kobject *kobj, const char *fmt,
+int kobject_set_name_vargs(struct kobject *kobj, const char *fmt,
va_list vargs)
{
const char *old_name = kobj->name;
--
1.6.2

2009-03-25 00:39:57

by Greg KH

[permalink] [raw]
Subject: [PATCH 28/61] USB: FHCI: use dev_name() in place of bus_id.

From: Sachin Sant <[email protected]>

Replace references to bus_id with dev_name() to fix fhci driver build break.

drivers/usb/host/fhci-hcd.c:586: error: struct device has no member named bus_id
drivers/usb/host/fhci-hcd.c:653: error: struct device has no member named bus_id
drivers/usb/host/fhci-dbg.c:111: error: struct device has no member named bus_id

Signed-off-by: Sachin Sant <[email protected]>
Acked-by: Anton Vorontsov <[email protected]>
Cc: Kay Sievers <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/usb/host/fhci-dbg.c | 2 +-
drivers/usb/host/fhci-hcd.c | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/host/fhci-dbg.c b/drivers/usb/host/fhci-dbg.c
index 34e14ed..ea8a425 100644
--- a/drivers/usb/host/fhci-dbg.c
+++ b/drivers/usb/host/fhci-dbg.c
@@ -108,7 +108,7 @@ void fhci_dfs_create(struct fhci_hcd *fhci)
{
struct device *dev = fhci_to_hcd(fhci)->self.controller;

- fhci->dfs_root = debugfs_create_dir(dev->bus_id, NULL);
+ fhci->dfs_root = debugfs_create_dir(dev_name(dev), NULL);
if (!fhci->dfs_root) {
WARN_ON(1);
return;
diff --git a/drivers/usb/host/fhci-hcd.c b/drivers/usb/host/fhci-hcd.c
index ba622cc..0951818 100644
--- a/drivers/usb/host/fhci-hcd.c
+++ b/drivers/usb/host/fhci-hcd.c
@@ -583,7 +583,7 @@ static int __devinit of_fhci_probe(struct of_device *ofdev,
if (sprop && strcmp(sprop, "host"))
return -ENODEV;

- hcd = usb_create_hcd(&fhci_driver, dev, dev->bus_id);
+ hcd = usb_create_hcd(&fhci_driver, dev, dev_name(dev));
if (!hcd) {
dev_err(dev, "could not create hcd\n");
return -ENOMEM;
@@ -650,7 +650,7 @@ static int __devinit of_fhci_probe(struct of_device *ofdev,
}
}

- ret = gpio_request(gpio, dev->bus_id);
+ ret = gpio_request(gpio, dev_name(dev));
if (ret) {
dev_err(dev, "failed to request gpio %d", i);
goto err_gpios;
--
1.6.2

2009-03-25 00:40:53

by Greg KH

[permalink] [raw]
Subject: [PATCH 30/61] SYSFS: use standard magic.h for sysfs

From: Qinghuang Feng <[email protected]>

SYSFS_MAGIC has been added into magic.h, so only use that definition
in magic.h to avoid potential consistency problem.

Signed-off-by: Qinghuang Feng <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
fs/sysfs/mount.c | 3 +--
1 files changed, 1 insertions(+), 2 deletions(-)

diff --git a/fs/sysfs/mount.c b/fs/sysfs/mount.c
index ab343e3..8133ca3 100644
--- a/fs/sysfs/mount.c
+++ b/fs/sysfs/mount.c
@@ -17,11 +17,10 @@
#include <linux/pagemap.h>
#include <linux/init.h>
#include <linux/module.h>
+#include <linux/magic.h>

#include "sysfs.h"

-/* Random magic number */
-#define SYSFS_MAGIC 0x62656572

static struct vfsmount *sysfs_mount;
struct super_block * sysfs_sb = NULL;
--
1.6.2

2009-03-25 00:41:16

by Greg KH

[permalink] [raw]
Subject: [PATCH 32/61] driver core: check bus->match without holding device lock

From: Ming Lei <[email protected]>

This patch moves bus->match out from driver_probe_device and
does not hold device lock to check the match between a device
and a driver.

The idea has been verified by the commit 6cd495860901,
which leads to a faster boot. But the commit 6cd495860901 has
the following drawbacks: 1),only does the quick check in
the path of __driver_attach->driver_probe_device, not in other
paths; 2),for a matched device and driver, check the same match
twice. It is a waste of cpu ,especially for some drivers with long
device id table (eg. usb-storage driver).

This patch adds a helper of driver_match_device to check the match
in all paths, and testes the match only once.

Signed-off-by: Ming Lei <[email protected]>
Acked-by: Cornelia Huck <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/base/base.h | 5 +++++
drivers/base/bus.c | 2 +-
drivers/base/dd.c | 19 +++++++------------
3 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/drivers/base/base.h b/drivers/base/base.h
index 9f50f1b..ca2b037 100644
--- a/drivers/base/base.h
+++ b/drivers/base/base.h
@@ -86,6 +86,11 @@ extern void bus_remove_driver(struct device_driver *drv);

extern void driver_detach(struct device_driver *drv);
extern int driver_probe_device(struct device_driver *drv, struct device *dev);
+static inline int driver_match_device(struct device_driver *drv,
+ struct device *dev)
+{
+ return drv->bus->match && drv->bus->match(dev, drv);
+}

extern void sysdev_shutdown(void);

diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index 83f32b8..8547b78 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -198,7 +198,7 @@ static ssize_t driver_bind(struct device_driver *drv,
int err = -ENODEV;

dev = bus_find_device_by_name(bus, NULL, buf);
- if (dev && dev->driver == NULL) {
+ if (dev && dev->driver == NULL && driver_match_device(drv, dev)) {
if (dev->parent) /* Needed for USB */
down(&dev->parent->sem);
down(&dev->sem);
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index 1352312..3f32df7 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -189,14 +189,8 @@ int wait_for_device_probe(void)
* @drv: driver to bind a device to
* @dev: device to try to bind to the driver
*
- * First, we call the bus's match function, if one present, which should
- * compare the device IDs the driver supports with the device IDs of the
- * device. Note we don't do this ourselves because we don't know the
- * format of the ID structures, nor what is to be considered a match and
- * what is not.
- *
- * This function returns 1 if a match is found, -ENODEV if the device is
- * not registered, and 0 otherwise.
+ * This function returns -ENODEV if the device is not registered,
+ * 1 if the device is bound sucessfully 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.
@@ -207,21 +201,22 @@ int driver_probe_device(struct device_driver *drv, struct device *dev)

if (!device_is_registered(dev))
return -ENODEV;
- if (drv->bus->match && !drv->bus->match(dev, drv))
- goto done;

pr_debug("bus: '%s': %s: matched device %s with driver %s\n",
drv->bus->name, __func__, dev_name(dev), drv->name);

ret = really_probe(dev, drv);

-done:
return ret;
}

static int __device_attach(struct device_driver *drv, void *data)
{
struct device *dev = data;
+
+ if (!driver_match_device(drv, dev))
+ return 0;
+
return driver_probe_device(drv, dev);
}

@@ -274,7 +269,7 @@ static int __driver_attach(struct device *dev, void *data)
* is an error.
*/

- if (drv->bus->match && !drv->bus->match(dev, drv))
+ if (!driver_match_device(drv, dev))
return 0;

if (dev->parent) /* Needed for USB */
--
1.6.2

2009-03-25 00:41:34

by Greg KH

[permalink] [raw]
Subject: [PATCH 31/61] sysfs: Take sysfs_mutex when fetching the root inode.

From: Eric W. Biederman <[email protected]>

sysfs_get_inode ultimately calls sysfs_count_nlink when the a
directory inode is fectched. sysfs_count_nlink needs to be
called under the sysfs_mutex to guard against the unlikely
but possible scenario that the root directory is changing
as we are counting the number entries in it, and just in
general to be consistent.

Signed-off-by: Eric W. Biederman <[email protected]>
Acked-by: Tejun Heo <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
fs/sysfs/mount.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/fs/sysfs/mount.c b/fs/sysfs/mount.c
index 8133ca3..84ef378 100644
--- a/fs/sysfs/mount.c
+++ b/fs/sysfs/mount.c
@@ -52,7 +52,9 @@ static int sysfs_fill_super(struct super_block *sb, void *data, int silent)
sysfs_sb = sb;

/* get root inode, initialize and unlock it */
+ mutex_lock(&sysfs_mutex);
inode = sysfs_get_inode(&sysfs_root);
+ mutex_unlock(&sysfs_mutex);
if (!inode) {
pr_debug("sysfs: could not get root inode\n");
return -ENOMEM;
--
1.6.2

2009-03-25 00:41:52

by Greg KH

[permalink] [raw]
Subject: [PATCH 33/61] platform: make better use of to_platform_{device,driver}() macros

From: Eric Miao <[email protected]>

This helps the code look more consistent and cleaner.

Signed-off-by: Eric Miao <[email protected]>
Cc: Kay Sievers <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/base/platform.c | 21 +++++++++------------
drivers/block/floppy.c | 3 +--
drivers/isdn/gigaset/ser-gigaset.c | 3 +--
3 files changed, 11 insertions(+), 16 deletions(-)

diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 349a101..62a8768 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -603,9 +603,8 @@ static int platform_uevent(struct device *dev, struct kobj_uevent_env *env)
*/
static int platform_match(struct device *dev, struct device_driver *drv)
{
- struct platform_device *pdev;
+ struct platform_device *pdev = to_platform_device(dev);

- pdev = container_of(dev, struct platform_device, dev);
return (strcmp(pdev->name, drv->name) == 0);
}

@@ -623,26 +622,24 @@ static int platform_legacy_suspend(struct device *dev, pm_message_t mesg)

static int platform_legacy_suspend_late(struct device *dev, pm_message_t mesg)
{
- struct platform_driver *drv = to_platform_driver(dev->driver);
- struct platform_device *pdev;
+ struct platform_driver *pdrv = to_platform_driver(dev->driver);
+ struct platform_device *pdev = to_platform_device(dev);
int ret = 0;

- pdev = container_of(dev, struct platform_device, dev);
- if (dev->driver && drv->suspend_late)
- ret = drv->suspend_late(pdev, mesg);
+ if (dev->driver && pdrv->suspend_late)
+ ret = pdrv->suspend_late(pdev, mesg);

return ret;
}

static int platform_legacy_resume_early(struct device *dev)
{
- struct platform_driver *drv = to_platform_driver(dev->driver);
- struct platform_device *pdev;
+ struct platform_driver *pdrv = to_platform_driver(dev->driver);
+ struct platform_device *pdev = to_platform_device(dev);
int ret = 0;

- pdev = container_of(dev, struct platform_device, dev);
- if (dev->driver && drv->resume_early)
- ret = drv->resume_early(pdev);
+ if (dev->driver && pdrv->resume_early)
+ ret = pdrv->resume_early(pdev);

return ret;
}
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index 83d8ed3..c2c95e6 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -4135,10 +4135,9 @@ static int have_no_fdc = -ENODEV;
static ssize_t floppy_cmos_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
- struct platform_device *p;
+ struct platform_device *p = to_platform_device(dev);
int drive;

- p = container_of(dev, struct platform_device,dev);
drive = p->id;
return sprintf(buf, "%X\n", UDP->cmos);
}
diff --git a/drivers/isdn/gigaset/ser-gigaset.c b/drivers/isdn/gigaset/ser-gigaset.c
index ac245e7..3071a52 100644
--- a/drivers/isdn/gigaset/ser-gigaset.c
+++ b/drivers/isdn/gigaset/ser-gigaset.c
@@ -389,8 +389,7 @@ static void gigaset_freecshw(struct cardstate *cs)

static void gigaset_device_release(struct device *dev)
{
- struct platform_device *pdev =
- container_of(dev, struct platform_device, dev);
+ struct platform_device *pdev = to_platform_device(dev);

/* adapted from platform_device_release() in drivers/base/platform.c */
//FIXME is this actually necessary?
--
1.6.2

2009-03-25 00:42:17

by Greg KH

[permalink] [raw]
Subject: [PATCH 34/61] platform: introduce module id table for platform devices

From: Eric Miao <[email protected]>

Now platform_device is being widely used on SoC processors where the
peripherals are attached to the system bus, which is simple enough.

However, silicon IPs for these SoCs are usually shared heavily across
a family of processors, even products from different companies. This
makes the original simple driver name based matching insufficient, or
simply not straight-forward.

Introduce a module id table for platform devices, and makes it clear
that a platform driver is able to support some shared IP and handle
slight differences across different platforms (by 'driver_data').
Module alias is handled automatically when a MODULE_DEVICE_TABLE()
is defined.

To not disturb the current platform drivers too much, the matched id
entry is recorded and can be retrieved by platform_get_device_id().

Signed-off-by: Eric Miao <[email protected]>
Cc: Kay Sievers <[email protected]>
Cc: Ben Dooks <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/base/platform.c | 23 ++++++++++++++++++++++-
include/linux/mod_devicetable.h | 9 +++++++++
include/linux/platform_device.h | 6 ++++++
scripts/mod/file2alias.c | 12 ++++++++++++
4 files changed, 49 insertions(+), 1 deletions(-)

diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 62a8768..ec993aa 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -584,10 +584,25 @@ static int platform_uevent(struct device *dev, struct kobj_uevent_env *env)
{
struct platform_device *pdev = to_platform_device(dev);

- add_uevent_var(env, "MODALIAS=platform:%s", pdev->name);
+ add_uevent_var(env, "MODALIAS=%s%s", PLATFORM_MODULE_PREFIX,
+ (pdev->id_entry) ? pdev->id_entry->name : pdev->name);
return 0;
}

+static const struct platform_device_id *platform_match_id(
+ struct platform_device_id *id,
+ struct platform_device *pdev)
+{
+ while (id->name[0]) {
+ if (strcmp(pdev->name, id->name) == 0) {
+ pdev->id_entry = id;
+ return id;
+ }
+ id++;
+ }
+ return NULL;
+}
+
/**
* platform_match - bind platform device to platform driver.
* @dev: device.
@@ -604,7 +619,13 @@ static int platform_uevent(struct device *dev, struct kobj_uevent_env *env)
static int platform_match(struct device *dev, struct device_driver *drv)
{
struct platform_device *pdev = to_platform_device(dev);
+ struct platform_driver *pdrv = to_platform_driver(drv);
+
+ /* match against the id table first */
+ if (pdrv->id_table)
+ return platform_match_id(pdrv->id_table, pdev) != NULL;

+ /* fall-back to driver name match */
return (strcmp(pdev->name, drv->name) == 0);
}

diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
index fde8667..1bf5900 100644
--- a/include/linux/mod_devicetable.h
+++ b/include/linux/mod_devicetable.h
@@ -454,4 +454,13 @@ struct dmi_system_id {

#define DMI_MATCH(a, b) { a, b }

+#define PLATFORM_NAME_SIZE 20
+#define PLATFORM_MODULE_PREFIX "platform:"
+
+struct platform_device_id {
+ char name[PLATFORM_NAME_SIZE];
+ kernel_ulong_t driver_data
+ __attribute__((aligned(sizeof(kernel_ulong_t))));
+};
+
#endif /* LINUX_MOD_DEVICETABLE_H */
diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h
index 9a34269..76aef7b 100644
--- a/include/linux/platform_device.h
+++ b/include/linux/platform_device.h
@@ -12,6 +12,7 @@
#define _PLATFORM_DEVICE_H_

#include <linux/device.h>
+#include <linux/mod_devicetable.h>

struct platform_device {
const char * name;
@@ -19,8 +20,12 @@ struct platform_device {
struct device dev;
u32 num_resources;
struct resource * resource;
+
+ struct platform_device_id *id_entry;
};

+#define platform_get_device_id(pdev) ((pdev)->id_entry)
+
#define to_platform_device(x) container_of((x), struct platform_device, dev)

extern int platform_device_register(struct platform_device *);
@@ -56,6 +61,7 @@ struct platform_driver {
int (*resume_early)(struct platform_device *);
int (*resume)(struct platform_device *);
struct device_driver driver;
+ struct platform_device_id *id_table;
};

extern int platform_driver_register(struct platform_driver *);
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
index 4eea60b..a334428 100644
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -710,6 +710,14 @@ static int do_dmi_entry(const char *filename, struct dmi_system_id *id,
strcat(alias, ":");
return 1;
}
+
+static int do_platform_entry(const char *filename,
+ struct platform_device_id *id, char *alias)
+{
+ sprintf(alias, PLATFORM_MODULE_PREFIX "%s", id->name);
+ return 1;
+}
+
/* Ignore any prefix, eg. some architectures prepend _ */
static inline int sym_is(const char *symbol, const char *name)
{
@@ -849,6 +857,10 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
do_table(symval, sym->st_size,
sizeof(struct dmi_system_id), "dmi",
do_dmi_entry, mod);
+ else if (sym_is(symname, "__mod_platform_device_table"))
+ do_table(symval, sym->st_size,
+ sizeof(struct platform_device_id), "platform",
+ do_platform_entry, mod);
free(zeros);
}

--
1.6.2

2009-03-25 00:42:46

by Greg KH

[permalink] [raw]
Subject: [PATCH 35/61] UIO: Add name attributes for mappings and port regions

From: Hans J. Koch <[email protected]>

If a UIO device has several memory mappings, it can be difficult for userspace
to find the right one. The situation becomes even worse if the UIO driver can
handle different versions of a card that have different numbers of mappings.
Benedikt Spranger has such cards and pointed this out to me. Thanks, Bene!

To address this problem, this patch adds "name" sysfs attributes for each
mapping. Userspace can use these to clearly identify each mapping. The name
string is optional. If a driver doesn't set it, an empty string will be
returned, so this patch won't break existing drivers.

The same problem exists for port region information, so a "name" attribute is
added there, too.

Signed-off-by: Hans J. Koch <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
Documentation/DocBook/uio-howto.tmpl | 29 +++++++++++++++++++++++++----
drivers/uio/uio.c | 22 ++++++++++++++++++++++
include/linux/uio_driver.h | 4 ++++
3 files changed, 51 insertions(+), 4 deletions(-)

diff --git a/Documentation/DocBook/uio-howto.tmpl b/Documentation/DocBook/uio-howto.tmpl
index 52e1b79..8f6e3b2 100644
--- a/Documentation/DocBook/uio-howto.tmpl
+++ b/Documentation/DocBook/uio-howto.tmpl
@@ -42,6 +42,13 @@ GPL version 2.

<revhistory>
<revision>
+ <revnumber>0.8</revnumber>
+ <date>2008-12-24</date>
+ <authorinitials>hjk</authorinitials>
+ <revremark>Added name attributes in mem and portio sysfs directories.
+ </revremark>
+ </revision>
+ <revision>
<revnumber>0.7</revnumber>
<date>2008-12-23</date>
<authorinitials>hjk</authorinitials>
@@ -303,12 +310,19 @@ interested in translating it, please email me
appear if the size of the mapping is not 0.
</para>
<para>
- Each <filename>mapX/</filename> directory contains two read-only files
- that show start address and size of the memory:
+ Each <filename>mapX/</filename> directory contains four read-only files
+ that show attributes of the memory:
</para>
<itemizedlist>
<listitem>
<para>
+ <filename>name</filename>: A string identifier for this mapping. This
+ is optional, the string can be empty. Drivers can set this to make it
+ easier for userspace to find the correct mapping.
+ </para>
+</listitem>
+<listitem>
+ <para>
<filename>addr</filename>: The address of memory that can be mapped.
</para>
</listitem>
@@ -366,12 +380,19 @@ offset = N * getpagesize();
<filename>/sys/class/uio/uioX/portio/</filename>.
</para>
<para>
- Each <filename>portX/</filename> directory contains three read-only
- files that show start, size, and type of the port region:
+ Each <filename>portX/</filename> directory contains four read-only
+ files that show name, start, size, and type of the port region:
</para>
<itemizedlist>
<listitem>
<para>
+ <filename>name</filename>: A string identifier for this port region.
+ The string is optional and can be empty. Drivers can set it to make it
+ easier for userspace to find a certain port region.
+ </para>
+</listitem>
+<listitem>
+ <para>
<filename>start</filename>: The first port of this region.
</para>
</listitem>
diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c
index 4ca85a1..68a4965 100644
--- a/drivers/uio/uio.c
+++ b/drivers/uio/uio.c
@@ -61,6 +61,14 @@ struct uio_map {
};
#define to_map(map) container_of(map, struct uio_map, kobj)

+static ssize_t map_name_show(struct uio_mem *mem, char *buf)
+{
+ if (unlikely(!mem->name))
+ mem->name = "";
+
+ return sprintf(buf, "%s\n", mem->name);
+}
+
static ssize_t map_addr_show(struct uio_mem *mem, char *buf)
{
return sprintf(buf, "0x%lx\n", mem->addr);
@@ -82,6 +90,8 @@ struct map_sysfs_entry {
ssize_t (*store)(struct uio_mem *, const char *, size_t);
};

+static struct map_sysfs_entry name_attribute =
+ __ATTR(name, S_IRUGO, map_name_show, NULL);
static struct map_sysfs_entry addr_attribute =
__ATTR(addr, S_IRUGO, map_addr_show, NULL);
static struct map_sysfs_entry size_attribute =
@@ -90,6 +100,7 @@ static struct map_sysfs_entry offset_attribute =
__ATTR(offset, S_IRUGO, map_offset_show, NULL);

static struct attribute *attrs[] = {
+ &name_attribute.attr,
&addr_attribute.attr,
&size_attribute.attr,
&offset_attribute.attr,
@@ -133,6 +144,14 @@ struct uio_portio {
};
#define to_portio(portio) container_of(portio, struct uio_portio, kobj)

+static ssize_t portio_name_show(struct uio_port *port, char *buf)
+{
+ if (unlikely(!port->name))
+ port->name = "";
+
+ return sprintf(buf, "%s\n", port->name);
+}
+
static ssize_t portio_start_show(struct uio_port *port, char *buf)
{
return sprintf(buf, "0x%lx\n", port->start);
@@ -159,6 +178,8 @@ struct portio_sysfs_entry {
ssize_t (*store)(struct uio_port *, const char *, size_t);
};

+static struct portio_sysfs_entry portio_name_attribute =
+ __ATTR(name, S_IRUGO, portio_name_show, NULL);
static struct portio_sysfs_entry portio_start_attribute =
__ATTR(start, S_IRUGO, portio_start_show, NULL);
static struct portio_sysfs_entry portio_size_attribute =
@@ -167,6 +188,7 @@ static struct portio_sysfs_entry portio_porttype_attribute =
__ATTR(porttype, S_IRUGO, portio_porttype_show, NULL);

static struct attribute *portio_attrs[] = {
+ &portio_name_attribute.attr,
&portio_start_attribute.attr,
&portio_size_attribute.attr,
&portio_porttype_attribute.attr,
diff --git a/include/linux/uio_driver.h b/include/linux/uio_driver.h
index a0bb6bd..5dcc9ff 100644
--- a/include/linux/uio_driver.h
+++ b/include/linux/uio_driver.h
@@ -22,6 +22,7 @@ struct uio_map;

/**
* struct uio_mem - description of a UIO memory region
+ * @name: name of the memory region for identification
* @addr: address of the device's memory
* @size: size of IO
* @memtype: type of memory addr points to
@@ -29,6 +30,7 @@ struct uio_map;
* @map: for use by the UIO core only.
*/
struct uio_mem {
+ const char *name;
unsigned long addr;
unsigned long size;
int memtype;
@@ -42,12 +44,14 @@ struct uio_portio;

/**
* struct uio_port - description of a UIO port region
+ * @name: name of the port region for identification
* @start: start of port region
* @size: size of port region
* @porttype: type of port (see UIO_PORT_* below)
* @portio: for use by the UIO core only.
*/
struct uio_port {
+ const char *name;
unsigned long start;
unsigned long size;
int porttype;
--
1.6.2

2009-03-25 00:43:10

by Greg KH

[permalink] [raw]
Subject: [PATCH 36/61] uio: add the uio_aec driver

From: Brandon Philips <[email protected]>

UIO driver for the Adrienne Electronics Corporation PCI time code
device.

This device differs from other UIO devices since it uses I/O ports instead of
memory mapped I/O. In order to make it possible for UIO to work with this
device a utility, uioport, can be used to read and write the ports.

uioport is designed to be a setuid program and checks the permissions of
the /dev/uio* node and if the user has write permissions it will use
iopl and out*/in* to access the device.

[1] git clone git://ifup.org/philips/uioport.git

Signed-off-by: Brandon Philips <[email protected]>
Signed-off-by: Hans J. Koch <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/uio/Kconfig | 18 +++++
drivers/uio/Makefile | 1 +
drivers/uio/uio_aec.c | 175 +++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 194 insertions(+), 0 deletions(-)
create mode 100644 drivers/uio/uio_aec.c

diff --git a/drivers/uio/Kconfig b/drivers/uio/Kconfig
index 04b954c..7f86534 100644
--- a/drivers/uio/Kconfig
+++ b/drivers/uio/Kconfig
@@ -58,6 +58,24 @@ config UIO_SMX

If you compile this as a module, it will be called uio_smx.

+config UIO_AEC
+ tristate "AEC video timestamp device"
+ depends on PCI
+ default n
+ help
+
+ UIO driver for the Adrienne Electronics Corporation PCI time
+ code device.
+
+ This device differs from other UIO devices since it uses I/O
+ ports instead of memory mapped I/O. In order to make it
+ possible for UIO to work with this device a utility, uioport,
+ can be used to read and write the ports:
+
+ git clone git://ifup.org/philips/uioport.git
+
+ If you compile this as a module, it will be called uio_aec.
+
config UIO_SERCOS3
tristate "Automata Sercos III PCI card driver"
default n
diff --git a/drivers/uio/Makefile b/drivers/uio/Makefile
index e695581..5c2586d 100644
--- a/drivers/uio/Makefile
+++ b/drivers/uio/Makefile
@@ -3,4 +3,5 @@ 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
diff --git a/drivers/uio/uio_aec.c b/drivers/uio/uio_aec.c
new file mode 100644
index 0000000..b7830e9
--- /dev/null
+++ b/drivers/uio/uio_aec.c
@@ -0,0 +1,175 @@
+/*
+ * uio_aec.c -- simple driver for Adrienne Electronics Corp time code PCI device
+ *
+ * Copyright (C) 2008 Brandon Philips <[email protected]>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/cdev.h>
+#include <linux/fs.h>
+#include <linux/io.h>
+#include <linux/uaccess.h>
+#include <linux/uio_driver.h>
+
+#define PCI_VENDOR_ID_AEC 0xaecb
+#define PCI_DEVICE_ID_AEC_VITCLTC 0x6250
+
+#define INT_ENABLE_ADDR 0xFC
+#define INT_ENABLE 0x10
+#define INT_DISABLE 0x0
+
+#define INT_MASK_ADDR 0x2E
+#define INT_MASK_ALL 0x3F
+
+#define INTA_DRVR_ADDR 0xFE
+#define INTA_ENABLED_FLAG 0x08
+#define INTA_FLAG 0x01
+
+#define MAILBOX 0x0F
+
+static struct pci_device_id ids[] = {
+ { PCI_DEVICE(PCI_VENDOR_ID_AEC, PCI_DEVICE_ID_AEC_VITCLTC), },
+ { 0, }
+};
+MODULE_DEVICE_TABLE(pci, ids);
+
+static irqreturn_t aectc_irq(int irq, struct uio_info *dev_info)
+{
+ void __iomem *int_flag = dev_info->priv + INTA_DRVR_ADDR;
+ unsigned char status = ioread8(int_flag);
+
+
+ if ((status & INTA_ENABLED_FLAG) && (status & INTA_FLAG)) {
+ /* application writes 0x00 to 0x2F to get next interrupt */
+ status = ioread8(dev_info->priv + MAILBOX);
+ return IRQ_HANDLED;
+ }
+
+ return IRQ_NONE;
+}
+
+static void print_board_data(struct pci_dev *pdev, struct uio_info *i)
+{
+ dev_info(&pdev->dev, "PCI-TC board vendor: %x%x number: %x%x"
+ " revision: %c%c\n",
+ ioread8(i->priv + 0x01),
+ ioread8(i->priv + 0x00),
+ ioread8(i->priv + 0x03),
+ ioread8(i->priv + 0x02),
+ ioread8(i->priv + 0x06),
+ ioread8(i->priv + 0x07));
+}
+
+static int __devinit probe(struct pci_dev *pdev, const struct pci_device_id *id)
+{
+ struct uio_info *info;
+ int ret;
+
+ info = kzalloc(sizeof(struct uio_info), GFP_KERNEL);
+ if (!info)
+ return -ENOMEM;
+
+ if (pci_enable_device(pdev))
+ goto out_free;
+
+ if (pci_request_regions(pdev, "aectc"))
+ goto out_disable;
+
+ info->name = "aectc";
+ info->port[0].start = pci_resource_start(pdev, 0);
+ if (!info->port[0].start)
+ goto out_release;
+ info->priv = pci_iomap(pdev, 0, 0);
+ if (!info->priv)
+ goto out_release;
+ info->port[0].size = pci_resource_len(pdev, 0);
+ info->port[0].porttype = UIO_PORT_GPIO;
+
+ info->version = "0.0.1";
+ info->irq = pdev->irq;
+ info->irq_flags = IRQF_SHARED;
+ info->handler = aectc_irq;
+
+ print_board_data(pdev, info);
+ ret = uio_register_device(&pdev->dev, info);
+ if (ret)
+ goto out_unmap;
+
+ iowrite32(INT_ENABLE, info->priv + INT_ENABLE_ADDR);
+ iowrite8(INT_MASK_ALL, info->priv + INT_MASK_ADDR);
+ if (!(ioread8(info->priv + INTA_DRVR_ADDR)
+ & INTA_ENABLED_FLAG))
+ dev_err(&pdev->dev, "aectc: interrupts not enabled\n");
+
+ pci_set_drvdata(pdev, info);
+
+ return 0;
+
+out_unmap:
+ pci_iounmap(pdev, info->priv);
+out_release:
+ pci_release_regions(pdev);
+out_disable:
+ pci_disable_device(pdev);
+out_free:
+ kfree(info);
+ return -ENODEV;
+}
+
+static void remove(struct pci_dev *pdev)
+{
+ struct uio_info *info = pci_get_drvdata(pdev);
+
+ /* disable interrupts */
+ iowrite8(INT_DISABLE, info->priv + INT_MASK_ADDR);
+ iowrite32(INT_DISABLE, info->priv + INT_ENABLE_ADDR);
+ /* read mailbox to ensure board drops irq */
+ ioread8(info->priv + MAILBOX);
+
+ uio_unregister_device(info);
+ pci_release_regions(pdev);
+ pci_disable_device(pdev);
+ pci_set_drvdata(pdev, NULL);
+ iounmap(info->priv);
+
+ kfree(info);
+}
+
+static struct pci_driver pci_driver = {
+ .name = "aectc",
+ .id_table = ids,
+ .probe = probe,
+ .remove = remove,
+};
+
+static int __init aectc_init(void)
+{
+ return pci_register_driver(&pci_driver);
+}
+
+static void __exit aectc_exit(void)
+{
+ pci_unregister_driver(&pci_driver);
+}
+
+MODULE_LICENSE("GPL");
+
+module_init(aectc_init);
+module_exit(aectc_exit);
--
1.6.2

2009-03-25 00:43:34

by Greg KH

[permalink] [raw]
Subject: [PATCH 37/61] UIO: Take offset into account when determining number of pages that can be mapped

From: Ian Abbott <[email protected]>

If a UIO memory region does not start on a page boundary but straddles one,
the number of actual pages that overlap the memory region may be calculated
incorrectly because the offset isn't taken into account. If userspace sets
the mmap length to offset+size, it may fail with -EINVAL if UIO thinks it's
trying to allocate too many pages.

Signed-off-by: Ian Abbott <[email protected]>
Cc: Hans J. Koch <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/uio/uio.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c
index 68a4965..03efb06 100644
--- a/drivers/uio/uio.c
+++ b/drivers/uio/uio.c
@@ -708,7 +708,8 @@ static int uio_mmap(struct file *filep, struct vm_area_struct *vma)
return -EINVAL;

requested_pages = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
- actual_pages = (idev->info->mem[mi].size + PAGE_SIZE -1) >> PAGE_SHIFT;
+ actual_pages = ((idev->info->mem[mi].addr & ~PAGE_MASK)
+ + idev->info->mem[mi].size + PAGE_SIZE -1) >> PAGE_SHIFT;
if (requested_pages > actual_pages)
return -EINVAL;

--
1.6.2

2009-03-25 00:43:51

by Greg KH

[permalink] [raw]
Subject: [PATCH 38/61] platform driver: fix incorrect use of 'platform_bus_type' with 'struct device_driver'

From: Ming Lei <[email protected]>

This patch fixes the bug reported in
http://bugzilla.kernel.org/show_bug.cgi?id=11681.

"Lots of device drivers register a 'struct device_driver' with
the '.bus' member set to '&platform_bus_type'. This is wrong,
since the platform_bus functions expect the 'struct device_driver'
to be wrapped up in a 'struct platform_driver' which provides
some additional callbacks (like suspend_late, resume_early).
The effect may be that platform_suspend_late() uses bogus data
outside the device_driver struct as a pointer pointer to the
device driver's suspend_late() function or other hard to
reproduce failures."(Lothar Wassmann)

Signed-off-by: Ming Lei <[email protected]>
Acked-by: Henrique de Moraes Holschuh <[email protected]>
Acked-by: David Brownell <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
arch/mips/basler/excite/excite_iodev.c | 27 +++++++++++-----------
drivers/char/tpm/tpm_atmel.c | 28 ++++++++++++++++-------
drivers/char/tpm/tpm_tis.c | 28 ++++++++++++++++-------
drivers/ide/au1xxx-ide.c | 36 +++++++++++++++---------------
drivers/mtd/maps/pxa2xx-flash.c | 37 ++++++++++++++++---------------
drivers/mtd/nand/excite_nandflash.c | 25 +++++++++++----------
drivers/mtd/onenand/generic.c | 26 +++++++++++-----------
drivers/net/mipsnet.c | 26 +++++++++++----------
drivers/pcmcia/au1000_generic.c | 37 ++++++++++++++++++++-----------
drivers/pcmcia/i82365.c | 28 ++++++++++++++++------
drivers/pcmcia/m32r_cfc.c | 30 +++++++++++++++++-------
drivers/pcmcia/m32r_pcc.c | 30 +++++++++++++++++-------
drivers/pcmcia/sa1100_generic.c | 38 +++++++++++++++++++++++--------
drivers/pcmcia/tcic.c | 30 +++++++++++++++++-------
drivers/pcmcia/vrc4171_card.c | 34 ++++++++++++++++++++--------
drivers/scsi/a4000t.c | 26 +++++++++++----------
drivers/scsi/bvme6000_scsi.c | 26 +++++++++++----------
drivers/scsi/mvme16x_scsi.c | 26 +++++++++++----------
drivers/video/au1100fb.c | 31 +++++++++++++------------
drivers/video/au1200fb.c | 25 +++++++++++---------
drivers/watchdog/rm9k_wdt.c | 27 ++++++++++------------
21 files changed, 371 insertions(+), 250 deletions(-)

diff --git a/arch/mips/basler/excite/excite_iodev.c b/arch/mips/basler/excite/excite_iodev.c
index a1e3526..dfbfd7e 100644
--- a/arch/mips/basler/excite/excite_iodev.c
+++ b/arch/mips/basler/excite/excite_iodev.c
@@ -33,8 +33,8 @@


static const struct resource *iodev_get_resource(struct platform_device *, const char *, unsigned int);
-static int __init iodev_probe(struct device *);
-static int __exit iodev_remove(struct device *);
+static int __init iodev_probe(struct platform_device *);
+static int __exit iodev_remove(struct platform_device *);
static int iodev_open(struct inode *, struct file *);
static int iodev_release(struct inode *, struct file *);
static ssize_t iodev_read(struct file *, char __user *, size_t s, loff_t *);
@@ -65,13 +65,13 @@ static struct miscdevice miscdev =
.fops = &fops
};

-static struct device_driver iodev_driver =
-{
- .name = (char *) iodev_name,
- .bus = &platform_bus_type,
- .owner = THIS_MODULE,
+static struct platform_driver iodev_driver = {
+ .driver = {
+ .name = iodev_name,
+ .owner = THIS_MODULE,
+ },
.probe = iodev_probe,
- .remove = __exit_p(iodev_remove)
+ .remove = __devexit_p(iodev_remove),
};


@@ -89,11 +89,10 @@ iodev_get_resource(struct platform_device *pdv, const char *name,


/* No hotplugging on the platform bus - use __init */
-static int __init iodev_probe(struct device *dev)
+static int __init iodev_probe(struct platform_device *dev)
{
- struct platform_device * const pdv = to_platform_device(dev);
const struct resource * const ri =
- iodev_get_resource(pdv, IODEV_RESOURCE_IRQ, IORESOURCE_IRQ);
+ iodev_get_resource(dev, IODEV_RESOURCE_IRQ, IORESOURCE_IRQ);

if (unlikely(!ri))
return -ENXIO;
@@ -104,7 +103,7 @@ static int __init iodev_probe(struct device *dev)



-static int __exit iodev_remove(struct device *dev)
+static int __exit iodev_remove(struct platform_device *dev)
{
return misc_deregister(&miscdev);
}
@@ -160,14 +159,14 @@ static irqreturn_t iodev_irqhdl(int irq, void *ctxt)

static int __init iodev_init_module(void)
{
- return driver_register(&iodev_driver);
+ return platform_driver_register(&iodev_driver);
}



static void __exit iodev_cleanup_module(void)
{
- driver_unregister(&iodev_driver);
+ platform_driver_unregister(&iodev_driver);
}

module_init(iodev_init_module);
diff --git a/drivers/char/tpm/tpm_atmel.c b/drivers/char/tpm/tpm_atmel.c
index d0e7926..c64a1bc 100644
--- a/drivers/char/tpm/tpm_atmel.c
+++ b/drivers/char/tpm/tpm_atmel.c
@@ -168,12 +168,22 @@ static void atml_plat_remove(void)
}
}

-static struct device_driver atml_drv = {
- .name = "tpm_atmel",
- .bus = &platform_bus_type,
- .owner = THIS_MODULE,
- .suspend = tpm_pm_suspend,
- .resume = tpm_pm_resume,
+static int tpm_atml_suspend(struct platform_device *dev, pm_message_t msg)
+{
+ return tpm_pm_suspend(&dev->dev, msg);
+}
+
+static int tpm_atml_resume(struct platform_device *dev)
+{
+ return tpm_pm_resume(&dev->dev);
+}
+static struct platform_driver atml_drv = {
+ .driver = {
+ .name = "tpm_atmel",
+ .owner = THIS_MODULE,
+ },
+ .suspend = tpm_atml_suspend,
+ .resume = tpm_atml_resume,
};

static int __init init_atmel(void)
@@ -184,7 +194,7 @@ static int __init init_atmel(void)
unsigned long base;
struct tpm_chip *chip;

- rc = driver_register(&atml_drv);
+ rc = platform_driver_register(&atml_drv);
if (rc)
return rc;

@@ -223,13 +233,13 @@ err_rel_reg:
atmel_release_region(base,
region_size);
err_unreg_drv:
- driver_unregister(&atml_drv);
+ platform_driver_unregister(&atml_drv);
return rc;
}

static void __exit cleanup_atmel(void)
{
- driver_unregister(&atml_drv);
+ platform_driver_unregister(&atml_drv);
atml_plat_remove();
}

diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c
index 717af7a..aec1931 100644
--- a/drivers/char/tpm/tpm_tis.c
+++ b/drivers/char/tpm/tpm_tis.c
@@ -654,12 +654,22 @@ module_param_string(hid, tpm_pnp_tbl[TIS_HID_USR_IDX].id,
sizeof(tpm_pnp_tbl[TIS_HID_USR_IDX].id), 0444);
MODULE_PARM_DESC(hid, "Set additional specific HID for this driver to probe");

-static struct device_driver tis_drv = {
- .name = "tpm_tis",
- .bus = &platform_bus_type,
- .owner = THIS_MODULE,
- .suspend = tpm_pm_suspend,
- .resume = tpm_pm_resume,
+static int tpm_tis_suspend(struct platform_device *dev, pm_message_t msg)
+{
+ return tpm_pm_suspend(&dev->dev, msg);
+}
+
+static int tpm_tis_resume(struct platform_device *dev)
+{
+ return tpm_pm_resume(&dev->dev);
+}
+static struct platform_driver tis_drv = {
+ .driver = {
+ .name = "tpm_tis",
+ .owner = THIS_MODULE,
+ },
+ .suspend = tpm_tis_suspend,
+ .resume = tpm_tis_resume,
};

static struct platform_device *pdev;
@@ -672,14 +682,14 @@ static int __init init_tis(void)
int rc;

if (force) {
- rc = driver_register(&tis_drv);
+ rc = platform_driver_register(&tis_drv);
if (rc < 0)
return rc;
if (IS_ERR(pdev=platform_device_register_simple("tpm_tis", -1, NULL, 0)))
return PTR_ERR(pdev);
if((rc=tpm_tis_init(&pdev->dev, TIS_MEM_BASE, TIS_MEM_LEN, 0)) != 0) {
platform_device_unregister(pdev);
- driver_unregister(&tis_drv);
+ platform_driver_unregister(&tis_drv);
}
return rc;
}
@@ -711,7 +721,7 @@ static void __exit cleanup_tis(void)

if (force) {
platform_device_unregister(pdev);
- driver_unregister(&tis_drv);
+ platform_driver_unregister(&tis_drv);
} else
pnp_unregister_driver(&tis_pnp_driver);
}
diff --git a/drivers/ide/au1xxx-ide.c b/drivers/ide/au1xxx-ide.c
index 79a2dfe..154ec2c 100644
--- a/drivers/ide/au1xxx-ide.c
+++ b/drivers/ide/au1xxx-ide.c
@@ -536,9 +536,8 @@ static const struct ide_port_info au1xxx_port_info = {
#endif
};

-static int au_ide_probe(struct device *dev)
+static int au_ide_probe(struct platform_device *dev)
{
- struct platform_device *pdev = to_platform_device(dev);
_auide_hwif *ahwif = &auide_hwif;
struct resource *res;
struct ide_host *host;
@@ -552,23 +551,23 @@ static int au_ide_probe(struct device *dev)
#endif

memset(&auide_hwif, 0, sizeof(_auide_hwif));
- ahwif->irq = platform_get_irq(pdev, 0);
+ ahwif->irq = platform_get_irq(dev, 0);

- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ res = platform_get_resource(dev, IORESOURCE_MEM, 0);

if (res == NULL) {
- pr_debug("%s %d: no base address\n", DRV_NAME, pdev->id);
+ pr_debug("%s %d: no base address\n", DRV_NAME, dev->id);
ret = -ENODEV;
goto out;
}
if (ahwif->irq < 0) {
- pr_debug("%s %d: no IRQ\n", DRV_NAME, pdev->id);
+ pr_debug("%s %d: no IRQ\n", DRV_NAME, dev->id);
ret = -ENODEV;
goto out;
}

if (!request_mem_region(res->start, res->end - res->start + 1,
- pdev->name)) {
+ dev->name)) {
pr_debug("%s: request_mem_region failed\n", DRV_NAME);
ret = -EBUSY;
goto out;
@@ -583,7 +582,7 @@ static int au_ide_probe(struct device *dev)
memset(&hw, 0, sizeof(hw));
auide_setup_ports(&hw, ahwif);
hw.irq = ahwif->irq;
- hw.dev = dev;
+ hw.dev = &dev->dev;
hw.chipset = ide_au1xxx;

ret = ide_host_add(&au1xxx_port_info, hws, &host);
@@ -592,7 +591,7 @@ static int au_ide_probe(struct device *dev)

auide_hwif.hwif = host->ports[0];

- dev_set_drvdata(dev, host);
+ platform_set_drvdata(dev, host);

printk(KERN_INFO "Au1xxx IDE(builtin) configured for %s\n", mode );

@@ -600,38 +599,39 @@ static int au_ide_probe(struct device *dev)
return ret;
}

-static int au_ide_remove(struct device *dev)
+static int au_ide_remove(struct platform_device *dev)
{
- struct platform_device *pdev = to_platform_device(dev);
struct resource *res;
- struct ide_host *host = dev_get_drvdata(dev);
+ struct ide_host *host = platform_get_drvdata(dev);
_auide_hwif *ahwif = &auide_hwif;

ide_host_remove(host);

iounmap((void *)ahwif->regbase);

- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ res = platform_get_resource(dev, IORESOURCE_MEM, 0);
release_mem_region(res->start, res->end - res->start + 1);

return 0;
}

-static struct device_driver au1200_ide_driver = {
- .name = "au1200-ide",
- .bus = &platform_bus_type,
+static struct platform_driver au1200_ide_driver = {
+ .driver = {
+ .name = "au1200-ide",
+ .owner = THIS_MODULE,
+ },
.probe = au_ide_probe,
.remove = au_ide_remove,
};

static int __init au_ide_init(void)
{
- return driver_register(&au1200_ide_driver);
+ return platform_driver_register(&au1200_ide_driver);
}

static void __exit au_ide_exit(void)
{
- driver_unregister(&au1200_ide_driver);
+ platform_driver_unregister(&au1200_ide_driver);
}

MODULE_LICENSE("GPL");
diff --git a/drivers/mtd/maps/pxa2xx-flash.c b/drivers/mtd/maps/pxa2xx-flash.c
index 771139c..e9026cb 100644
--- a/drivers/mtd/maps/pxa2xx-flash.c
+++ b/drivers/mtd/maps/pxa2xx-flash.c
@@ -41,9 +41,8 @@ struct pxa2xx_flash_info {
static const char *probes[] = { "RedBoot", "cmdlinepart", NULL };


-static int __init pxa2xx_flash_probe(struct device *dev)
+static int __init pxa2xx_flash_probe(struct platform_device *pdev)
{
- struct platform_device *pdev = to_platform_device(dev);
struct flash_platform_data *flash = pdev->dev.platform_data;
struct pxa2xx_flash_info *info;
struct mtd_partition *parts;
@@ -114,15 +113,15 @@ static int __init pxa2xx_flash_probe(struct device *dev)
add_mtd_device(info->mtd);
}

- dev_set_drvdata(dev, info);
+ platform_set_drvdata(pdev, info);
return 0;
}

-static int __exit pxa2xx_flash_remove(struct device *dev)
+static int __exit pxa2xx_flash_remove(struct platform_device *dev)
{
- struct pxa2xx_flash_info *info = dev_get_drvdata(dev);
+ struct pxa2xx_flash_info *info = platform_get_drvdata(dev);

- dev_set_drvdata(dev, NULL);
+ platform_set_drvdata(dev, NULL);

#ifdef CONFIG_MTD_PARTITIONS
if (info->nr_parts)
@@ -141,9 +140,9 @@ static int __exit pxa2xx_flash_remove(struct device *dev)
}

#ifdef CONFIG_PM
-static int pxa2xx_flash_suspend(struct device *dev, pm_message_t state)
+static int pxa2xx_flash_suspend(struct platform_device *dev, pm_message_t state)
{
- struct pxa2xx_flash_info *info = dev_get_drvdata(dev);
+ struct pxa2xx_flash_info *info = platform_get_drvdata(dev);
int ret = 0;

if (info->mtd && info->mtd->suspend)
@@ -151,17 +150,17 @@ static int pxa2xx_flash_suspend(struct device *dev, pm_message_t state)
return ret;
}

-static int pxa2xx_flash_resume(struct device *dev)
+static int pxa2xx_flash_resume(struct platform_device *dev)
{
- struct pxa2xx_flash_info *info = dev_get_drvdata(dev);
+ struct pxa2xx_flash_info *info = platform_get_drvdata(dev);

if (info->mtd && info->mtd->resume)
info->mtd->resume(info->mtd);
return 0;
}
-static void pxa2xx_flash_shutdown(struct device *dev)
+static void pxa2xx_flash_shutdown(struct platform_device *dev)
{
- struct pxa2xx_flash_info *info = dev_get_drvdata(dev);
+ struct pxa2xx_flash_info *info = platform_get_drvdata(dev);

if (info && info->mtd->suspend(info->mtd) == 0)
info->mtd->resume(info->mtd);
@@ -172,11 +171,13 @@ static void pxa2xx_flash_shutdown(struct device *dev)
#define pxa2xx_flash_shutdown NULL
#endif

-static struct device_driver pxa2xx_flash_driver = {
- .name = "pxa2xx-flash",
- .bus = &platform_bus_type,
+static struct platform_driver pxa2xx_flash_driver = {
+ .driver = {
+ .name = "pxa2xx-flash",
+ .owner = THIS_MODULE,
+ },
.probe = pxa2xx_flash_probe,
- .remove = __exit_p(pxa2xx_flash_remove),
+ .remove = __devexit_p(pxa2xx_flash_remove),
.suspend = pxa2xx_flash_suspend,
.resume = pxa2xx_flash_resume,
.shutdown = pxa2xx_flash_shutdown,
@@ -184,12 +185,12 @@ static struct device_driver pxa2xx_flash_driver = {

static int __init init_pxa2xx_flash(void)
{
- return driver_register(&pxa2xx_flash_driver);
+ return platform_driver_register(&pxa2xx_flash_driver);
}

static void __exit cleanup_pxa2xx_flash(void)
{
- driver_unregister(&pxa2xx_flash_driver);
+ platform_driver_unregister(&pxa2xx_flash_driver);
}

module_init(init_pxa2xx_flash);
diff --git a/drivers/mtd/nand/excite_nandflash.c b/drivers/mtd/nand/excite_nandflash.c
index ced14b5..72446fb 100644
--- a/drivers/mtd/nand/excite_nandflash.c
+++ b/drivers/mtd/nand/excite_nandflash.c
@@ -128,11 +128,11 @@ static int excite_nand_devready(struct mtd_info *mtd)
* The binding to the mtd and all allocated
* resources are released.
*/
-static int __exit excite_nand_remove(struct device *dev)
+static int __exit excite_nand_remove(struct platform_device *dev)
{
- struct excite_nand_drvdata * const this = dev_get_drvdata(dev);
+ struct excite_nand_drvdata * const this = platform_get_drvdata(dev);

- dev_set_drvdata(dev, NULL);
+ platform_set_drvdata(dev, NULL);

if (unlikely(!this)) {
printk(KERN_ERR "%s: called %s without private data!!",
@@ -159,9 +159,8 @@ static int __exit excite_nand_remove(struct device *dev)
* it can allocate all necessary resources then calls the
* nand layer to look for devices.
*/
-static int __init excite_nand_probe(struct device *dev)
+static int __init excite_nand_probe(struct platform_device *pdev)
{
- struct platform_device * const pdev = to_platform_device(dev);
struct excite_nand_drvdata *drvdata; /* private driver data */
struct nand_chip *board_chip; /* private flash chip data */
struct mtd_info *board_mtd; /* mtd info for this board */
@@ -175,7 +174,7 @@ static int __init excite_nand_probe(struct device *dev)
}

/* bind private data into driver */
- dev_set_drvdata(dev, drvdata);
+ platform_set_drvdata(pdev, drvdata);

/* allocate and map the resource */
drvdata->regs =
@@ -219,23 +218,25 @@ static int __init excite_nand_probe(struct device *dev)
return 0;
}

-static struct device_driver excite_nand_driver = {
- .name = "excite_nand",
- .bus = &platform_bus_type,
+static struct platform_driver excite_nand_driver = {
+ .driver = {
+ .name = "excite_nand",
+ .owner = THIS_MODULE,
+ },
.probe = excite_nand_probe,
- .remove = __exit_p(excite_nand_remove)
+ .remove = __devexit_p(excite_nand_remove)
};

static int __init excite_nand_init(void)
{
pr_info("Basler eXcite nand flash driver Version "
EXCITE_NANDFLASH_VERSION "\n");
- return driver_register(&excite_nand_driver);
+ return platform_driver_register(&excite_nand_driver);
}

static void __exit excite_nand_exit(void)
{
- driver_unregister(&excite_nand_driver);
+ platform_driver_unregister(&excite_nand_driver);
}

module_init(excite_nand_init);
diff --git a/drivers/mtd/onenand/generic.c b/drivers/mtd/onenand/generic.c
index 5b69e77..3a496c3 100644
--- a/drivers/mtd/onenand/generic.c
+++ b/drivers/mtd/onenand/generic.c
@@ -36,10 +36,9 @@ struct onenand_info {
struct onenand_chip onenand;
};

-static int __devinit generic_onenand_probe(struct device *dev)
+static int __devinit generic_onenand_probe(struct platform_device *pdev)
{
struct onenand_info *info;
- struct platform_device *pdev = to_platform_device(dev);
struct flash_platform_data *pdata = pdev->dev.platform_data;
struct resource *res = pdev->resource;
unsigned long size = res->end - res->start + 1;
@@ -49,7 +48,7 @@ static int __devinit generic_onenand_probe(struct device *dev)
if (!info)
return -ENOMEM;

- if (!request_mem_region(res->start, size, dev->driver->name)) {
+ if (!request_mem_region(res->start, size, pdev->dev.driver->name)) {
err = -EBUSY;
goto out_free_info;
}
@@ -82,7 +81,7 @@ static int __devinit generic_onenand_probe(struct device *dev)
#endif
err = add_mtd_device(&info->mtd);

- dev_set_drvdata(&pdev->dev, info);
+ platform_set_drvdata(pdev, info);

return 0;

@@ -96,14 +95,13 @@ out_free_info:
return err;
}

-static int __devexit generic_onenand_remove(struct device *dev)
+static int __devexit generic_onenand_remove(struct platform_device *pdev)
{
- struct platform_device *pdev = to_platform_device(dev);
- struct onenand_info *info = dev_get_drvdata(&pdev->dev);
+ struct onenand_info *info = platform_get_drvdata(pdev);
struct resource *res = pdev->resource;
unsigned long size = res->end - res->start + 1;

- dev_set_drvdata(&pdev->dev, NULL);
+ platform_set_drvdata(pdev, NULL);

if (info) {
if (info->parts)
@@ -120,9 +118,11 @@ static int __devexit generic_onenand_remove(struct device *dev)
return 0;
}

-static struct device_driver generic_onenand_driver = {
- .name = DRIVER_NAME,
- .bus = &platform_bus_type,
+static struct platform_driver generic_onenand_driver = {
+ .driver = {
+ .name = DRIVER_NAME,
+ .owner = THIS_MODULE,
+ },
.probe = generic_onenand_probe,
.remove = __devexit_p(generic_onenand_remove),
};
@@ -131,12 +131,12 @@ MODULE_ALIAS(DRIVER_NAME);

static int __init generic_onenand_init(void)
{
- return driver_register(&generic_onenand_driver);
+ return platform_driver_register(&generic_onenand_driver);
}

static void __exit generic_onenand_exit(void)
{
- driver_unregister(&generic_onenand_driver);
+ platform_driver_unregister(&generic_onenand_driver);
}

module_init(generic_onenand_init);
diff --git a/drivers/net/mipsnet.c b/drivers/net/mipsnet.c
index 4e7a5fa..664835b 100644
--- a/drivers/net/mipsnet.c
+++ b/drivers/net/mipsnet.c
@@ -237,7 +237,7 @@ static void mipsnet_set_mclist(struct net_device *dev)
{
}

-static int __init mipsnet_probe(struct device *dev)
+static int __init mipsnet_probe(struct platform_device *dev)
{
struct net_device *netdev;
int err;
@@ -248,7 +248,7 @@ static int __init mipsnet_probe(struct device *dev)
goto out;
}

- dev_set_drvdata(dev, netdev);
+ platform_set_drvdata(dev, netdev);

netdev->open = mipsnet_open;
netdev->stop = mipsnet_close;
@@ -293,23 +293,25 @@ out:
return err;
}

-static int __devexit mipsnet_device_remove(struct device *device)
+static int __devexit mipsnet_device_remove(struct platform_device *device)
{
- struct net_device *dev = dev_get_drvdata(device);
+ struct net_device *dev = platform_get_drvdata(device);

unregister_netdev(dev);
release_region(dev->base_addr, sizeof(struct mipsnet_regs));
free_netdev(dev);
- dev_set_drvdata(device, NULL);
+ platform_set_drvdata(device, NULL);

return 0;
}

-static struct device_driver mipsnet_driver = {
- .name = mipsnet_string,
- .bus = &platform_bus_type,
- .probe = mipsnet_probe,
- .remove = __devexit_p(mipsnet_device_remove),
+static struct platform_driver mipsnet_driver = {
+ .driver = {
+ .name = mipsnet_string,
+ .owner = THIS_MODULE,
+ },
+ .probe = mipsnet_probe,
+ .remove = __devexit_p(mipsnet_device_remove),
};

static int __init mipsnet_init_module(void)
@@ -319,7 +321,7 @@ static int __init mipsnet_init_module(void)
printk(KERN_INFO "MIPSNet Ethernet driver. Version: %s. "
"(c)2005 MIPS Technologies, Inc.\n", MIPSNET_VERSION);

- err = driver_register(&mipsnet_driver);
+ err = platform_driver_register(&mipsnet_driver);
if (err)
printk(KERN_ERR "Driver registration failed\n");

@@ -328,7 +330,7 @@ static int __init mipsnet_init_module(void)

static void __exit mipsnet_exit_module(void)
{
- driver_unregister(&mipsnet_driver);
+ platform_driver_unregister(&mipsnet_driver);
}

module_init(mipsnet_init_module);
diff --git a/drivers/pcmcia/au1000_generic.c b/drivers/pcmcia/au1000_generic.c
index fc1de46..9001334 100644
--- a/drivers/pcmcia/au1000_generic.c
+++ b/drivers/pcmcia/au1000_generic.c
@@ -468,13 +468,13 @@ out:
return ret;
}

-int au1x00_drv_pcmcia_remove(struct device *dev)
+int au1x00_drv_pcmcia_remove(struct platform_device *dev)
{
- struct skt_dev_info *sinfo = dev_get_drvdata(dev);
+ struct skt_dev_info *sinfo = platform_get_drvdata(dev);
int i;

mutex_lock(&pcmcia_sockets_lock);
- dev_set_drvdata(dev, NULL);
+ platform_set_drvdata(dev, NULL);

for (i = 0; i < sinfo->nskt; i++) {
struct au1000_pcmcia_socket *skt = PCMCIA_SOCKET(i);
@@ -498,13 +498,13 @@ int au1x00_drv_pcmcia_remove(struct device *dev)
* PCMCIA "Driver" API
*/

-static int au1x00_drv_pcmcia_probe(struct device *dev)
+static int au1x00_drv_pcmcia_probe(struct platform_device *dev)
{
int i, ret = -ENODEV;

mutex_lock(&pcmcia_sockets_lock);
for (i=0; i < ARRAY_SIZE(au1x00_pcmcia_hw_init); i++) {
- ret = au1x00_pcmcia_hw_init[i](dev);
+ ret = au1x00_pcmcia_hw_init[i](&dev->dev);
if (ret == 0)
break;
}
@@ -512,14 +512,26 @@ static int au1x00_drv_pcmcia_probe(struct device *dev)
return ret;
}

+static int au1x00_drv_pcmcia_suspend(struct platform_device *dev,
+ pm_message_t state)
+{
+ return pcmcia_socket_dev_suspend(&dev->dev, state);
+}
+
+static int au1x00_drv_pcmcia_resume(struct platform_device *dev)
+{
+ return pcmcia_socket_dev_resume(&dev->dev);
+}

-static struct device_driver au1x00_pcmcia_driver = {
+static struct platform_driver au1x00_pcmcia_driver = {
+ .driver = {
+ .name = "au1x00-pcmcia",
+ .owner = THIS_MODULE,
+ },
.probe = au1x00_drv_pcmcia_probe,
.remove = au1x00_drv_pcmcia_remove,
- .name = "au1x00-pcmcia",
- .bus = &platform_bus_type,
- .suspend = pcmcia_socket_dev_suspend,
- .resume = pcmcia_socket_dev_resume,
+ .suspend = au1x00_drv_pcmcia_suspend,
+ .resume = au1x00_drv_pcmcia_resume,
};


@@ -533,8 +545,7 @@ static struct device_driver au1x00_pcmcia_driver = {
static int __init au1x00_pcmcia_init(void)
{
int error = 0;
- if ((error = driver_register(&au1x00_pcmcia_driver)))
- return error;
+ error = platform_driver_register(&au1x00_pcmcia_driver);
return error;
}

@@ -544,7 +555,7 @@ static int __init au1x00_pcmcia_init(void)
*/
static void __exit au1x00_pcmcia_exit(void)
{
- driver_unregister(&au1x00_pcmcia_driver);
+ platform_driver_unregister(&au1x00_pcmcia_driver);
}

module_init(au1x00_pcmcia_init);
diff --git a/drivers/pcmcia/i82365.c b/drivers/pcmcia/i82365.c
index 71653ab..40d4953 100644
--- a/drivers/pcmcia/i82365.c
+++ b/drivers/pcmcia/i82365.c
@@ -1238,6 +1238,16 @@ static int pcic_init(struct pcmcia_socket *s)
return 0;
}

+static int i82365_drv_pcmcia_suspend(struct platform_device *dev,
+ pm_message_t state)
+{
+ return pcmcia_socket_dev_suspend(&dev->dev, state);
+}
+
+static int i82365_drv_pcmcia_resume(struct platform_device *dev)
+{
+ return pcmcia_socket_dev_resume(&dev->dev);
+}
static struct pccard_operations pcic_operations = {
.init = pcic_init,
.get_status = pcic_get_status,
@@ -1248,11 +1258,13 @@ static struct pccard_operations pcic_operations = {

/*====================================================================*/

-static struct device_driver i82365_driver = {
- .name = "i82365",
- .bus = &platform_bus_type,
- .suspend = pcmcia_socket_dev_suspend,
- .resume = pcmcia_socket_dev_resume,
+static struct platform_driver i82365_driver = {
+ .driver = {
+ .name = "i82365",
+ .owner = THIS_MODULE,
+ },
+ .suspend = i82365_drv_pcmcia_suspend,
+ .resume = i82365_drv_pcmcia_resume,
};

static struct platform_device *i82365_device;
@@ -1261,7 +1273,7 @@ static int __init init_i82365(void)
{
int i, ret;

- ret = driver_register(&i82365_driver);
+ ret = platform_driver_register(&i82365_driver);
if (ret)
goto err_out;

@@ -1337,7 +1349,7 @@ err_dev_unregister:
pnp_disable_dev(i82365_pnpdev);
#endif
err_driver_unregister:
- driver_unregister(&i82365_driver);
+ platform_driver_unregister(&i82365_driver);
err_out:
return ret;
} /* init_i82365 */
@@ -1365,7 +1377,7 @@ static void __exit exit_i82365(void)
if (i82365_pnpdev)
pnp_disable_dev(i82365_pnpdev);
#endif
- driver_unregister(&i82365_driver);
+ platform_driver_unregister(&i82365_driver);
} /* exit_i82365 */

module_init(init_i82365);
diff --git a/drivers/pcmcia/m32r_cfc.c b/drivers/pcmcia/m32r_cfc.c
index 2ab4f22..62b4ecc 100644
--- a/drivers/pcmcia/m32r_cfc.c
+++ b/drivers/pcmcia/m32r_cfc.c
@@ -696,13 +696,25 @@ static struct pccard_operations pcc_operations = {
.set_mem_map = pcc_set_mem_map,
};

+static int cfc_drv_pcmcia_suspend(struct platform_device *dev,
+ pm_message_t state)
+{
+ return pcmcia_socket_dev_suspend(&dev->dev, state);
+}
+
+static int cfc_drv_pcmcia_resume(struct platform_device *dev)
+{
+ return pcmcia_socket_dev_resume(&dev->dev);
+}
/*====================================================================*/

-static struct device_driver pcc_driver = {
- .name = "cfc",
- .bus = &platform_bus_type,
- .suspend = pcmcia_socket_dev_suspend,
- .resume = pcmcia_socket_dev_resume,
+static struct platform_driver pcc_driver = {
+ .driver = {
+ .name = "cfc",
+ .owner = THIS_MODULE,
+ },
+ .suspend = cfc_drv_pcmcia_suspend,
+ .resume = cfc_drv_pcmcia_resume,
};

static struct platform_device pcc_device = {
@@ -716,13 +728,13 @@ static int __init init_m32r_pcc(void)
{
int i, ret;

- ret = driver_register(&pcc_driver);
+ ret = platform_driver_register(&pcc_driver);
if (ret)
return ret;

ret = platform_device_register(&pcc_device);
if (ret){
- driver_unregister(&pcc_driver);
+ platform_driver_unregister(&pcc_driver);
return ret;
}

@@ -754,7 +766,7 @@ static int __init init_m32r_pcc(void)
if (pcc_sockets == 0) {
printk("socket is not found.\n");
platform_device_unregister(&pcc_device);
- driver_unregister(&pcc_driver);
+ platform_driver_unregister(&pcc_driver);
return -ENODEV;
}

@@ -802,7 +814,7 @@ static void __exit exit_m32r_pcc(void)
if (poll_interval != 0)
del_timer_sync(&poll_timer);

- driver_unregister(&pcc_driver);
+ platform_driver_unregister(&pcc_driver);
} /* exit_m32r_pcc */

module_init(init_m32r_pcc);
diff --git a/drivers/pcmcia/m32r_pcc.c b/drivers/pcmcia/m32r_pcc.c
index 2f108c2..12034b4 100644
--- a/drivers/pcmcia/m32r_pcc.c
+++ b/drivers/pcmcia/m32r_pcc.c
@@ -672,13 +672,25 @@ static struct pccard_operations pcc_operations = {
.set_mem_map = pcc_set_mem_map,
};

+static int pcc_drv_pcmcia_suspend(struct platform_device *dev,
+ pm_message_t state)
+{
+ return pcmcia_socket_dev_suspend(&dev->dev, state);
+}
+
+static int pcc_drv_pcmcia_resume(struct platform_device *dev)
+{
+ return pcmcia_socket_dev_resume(&dev->dev);
+}
/*====================================================================*/

-static struct device_driver pcc_driver = {
- .name = "pcc",
- .bus = &platform_bus_type,
- .suspend = pcmcia_socket_dev_suspend,
- .resume = pcmcia_socket_dev_resume,
+static struct platform_driver pcc_driver = {
+ .driver = {
+ .name = "pcc",
+ .owner = THIS_MODULE,
+ },
+ .suspend = pcc_drv_pcmcia_suspend,
+ .resume = pcc_drv_pcmcia_resume,
};

static struct platform_device pcc_device = {
@@ -692,13 +704,13 @@ static int __init init_m32r_pcc(void)
{
int i, ret;

- ret = driver_register(&pcc_driver);
+ ret = platform_driver_register(&pcc_driver);
if (ret)
return ret;

ret = platform_device_register(&pcc_device);
if (ret){
- driver_unregister(&pcc_driver);
+ platform_driver_unregister(&pcc_driver);
return ret;
}

@@ -715,7 +727,7 @@ static int __init init_m32r_pcc(void)
if (pcc_sockets == 0) {
printk("socket is not found.\n");
platform_device_unregister(&pcc_device);
- driver_unregister(&pcc_driver);
+ platform_driver_unregister(&pcc_driver);
return -ENODEV;
}

@@ -763,7 +775,7 @@ static void __exit exit_m32r_pcc(void)
if (poll_interval != 0)
del_timer_sync(&poll_timer);

- driver_unregister(&pcc_driver);
+ platform_driver_unregister(&pcc_driver);
} /* exit_m32r_pcc */

module_init(init_m32r_pcc);
diff --git a/drivers/pcmcia/sa1100_generic.c b/drivers/pcmcia/sa1100_generic.c
index c5b2a44..d8da5ac 100644
--- a/drivers/pcmcia/sa1100_generic.c
+++ b/drivers/pcmcia/sa1100_generic.c
@@ -65,7 +65,7 @@ static int (*sa11x0_pcmcia_hw_init[])(struct device *dev) = {
#endif
};

-static int sa11x0_drv_pcmcia_probe(struct device *dev)
+static int sa11x0_drv_pcmcia_probe(struct platform_device *dev)
{
int i, ret = -ENODEV;

@@ -73,7 +73,7 @@ static int sa11x0_drv_pcmcia_probe(struct device *dev)
* Initialise any "on-board" PCMCIA sockets.
*/
for (i = 0; i < ARRAY_SIZE(sa11x0_pcmcia_hw_init); i++) {
- ret = sa11x0_pcmcia_hw_init[i](dev);
+ ret = sa11x0_pcmcia_hw_init[i](&dev->dev);
if (ret == 0)
break;
}
@@ -81,13 +81,31 @@ static int sa11x0_drv_pcmcia_probe(struct device *dev)
return ret;
}

-static struct device_driver sa11x0_pcmcia_driver = {
+static int sa11x0_drv_pcmcia_remove(struct platform_device *dev)
+{
+ return soc_common_drv_pcmcia_remove(&dev->dev);
+}
+
+static int sa11x0_drv_pcmcia_suspend(struct platform_device *dev,
+ pm_message_t state)
+{
+ return pcmcia_socket_dev_suspend(&dev->dev, state);
+}
+
+static int sa11x0_drv_pcmcia_resume(struct platform_device *dev)
+{
+ return pcmcia_socket_dev_resume(&dev->dev);
+}
+
+static struct platform_driver sa11x0_pcmcia_driver = {
+ .driver = {
+ .name = "sa11x0-pcmcia",
+ .owner = THIS_MODULE,
+ },
.probe = sa11x0_drv_pcmcia_probe,
- .remove = soc_common_drv_pcmcia_remove,
- .name = "sa11x0-pcmcia",
- .bus = &platform_bus_type,
- .suspend = pcmcia_socket_dev_suspend,
- .resume = pcmcia_socket_dev_resume,
+ .remove = sa11x0_drv_pcmcia_remove,
+ .suspend = sa11x0_drv_pcmcia_suspend,
+ .resume = sa11x0_drv_pcmcia_resume,
};

/* sa11x0_pcmcia_init()
@@ -100,7 +118,7 @@ static struct device_driver sa11x0_pcmcia_driver = {
*/
static int __init sa11x0_pcmcia_init(void)
{
- return driver_register(&sa11x0_pcmcia_driver);
+ return platform_driver_register(&sa11x0_pcmcia_driver);
}

/* sa11x0_pcmcia_exit()
@@ -110,7 +128,7 @@ static int __init sa11x0_pcmcia_init(void)
*/
static void __exit sa11x0_pcmcia_exit(void)
{
- driver_unregister(&sa11x0_pcmcia_driver);
+ platform_driver_unregister(&sa11x0_pcmcia_driver);
}

MODULE_AUTHOR("John Dorsey <[email protected]>");
diff --git a/drivers/pcmcia/tcic.c b/drivers/pcmcia/tcic.c
index 2a613e9..9ad97ea 100644
--- a/drivers/pcmcia/tcic.c
+++ b/drivers/pcmcia/tcic.c
@@ -363,13 +363,25 @@ static int __init get_tcic_id(void)
return id;
}

+static int tcic_drv_pcmcia_suspend(struct platform_device *dev,
+ pm_message_t state)
+{
+ return pcmcia_socket_dev_suspend(&dev->dev, state);
+}
+
+static int tcic_drv_pcmcia_resume(struct platform_device *dev)
+{
+ return pcmcia_socket_dev_resume(&dev->dev);
+}
/*====================================================================*/

-static struct device_driver tcic_driver = {
- .name = "tcic-pcmcia",
- .bus = &platform_bus_type,
- .suspend = pcmcia_socket_dev_suspend,
- .resume = pcmcia_socket_dev_resume,
+static struct platform_driver tcic_driver = {
+ .driver = {
+ .name = "tcic-pcmcia",
+ .owner = THIS_MODULE,
+ },
+ .suspend = tcic_drv_pcmcia_suspend,
+ .resume = tcic_drv_pcmcia_resume,
};

static struct platform_device tcic_device = {
@@ -383,7 +395,7 @@ static int __init init_tcic(void)
int i, sock, ret = 0;
u_int mask, scan;

- if (driver_register(&tcic_driver))
+ if (platform_driver_register(&tcic_driver))
return -1;

printk(KERN_INFO "Databook TCIC-2 PCMCIA probe: ");
@@ -391,7 +403,7 @@ static int __init init_tcic(void)

if (!request_region(tcic_base, 16, "tcic-2")) {
printk("could not allocate ports,\n ");
- driver_unregister(&tcic_driver);
+ platform_driver_unregister(&tcic_driver);
return -ENODEV;
}
else {
@@ -414,7 +426,7 @@ static int __init init_tcic(void)
if (sock == 0) {
printk("not found.\n");
release_region(tcic_base, 16);
- driver_unregister(&tcic_driver);
+ platform_driver_unregister(&tcic_driver);
return -ENODEV;
}

@@ -542,7 +554,7 @@ static void __exit exit_tcic(void)
}

platform_device_unregister(&tcic_device);
- driver_unregister(&tcic_driver);
+ platform_driver_unregister(&tcic_driver);
} /* exit_tcic */

/*====================================================================*/
diff --git a/drivers/pcmcia/vrc4171_card.c b/drivers/pcmcia/vrc4171_card.c
index b2c4124..659421d 100644
--- a/drivers/pcmcia/vrc4171_card.c
+++ b/drivers/pcmcia/vrc4171_card.c
@@ -704,24 +704,37 @@ static int __devinit vrc4171_card_setup(char *options)

__setup("vrc4171_card=", vrc4171_card_setup);

-static struct device_driver vrc4171_card_driver = {
- .name = vrc4171_card_name,
- .bus = &platform_bus_type,
- .suspend = pcmcia_socket_dev_suspend,
- .resume = pcmcia_socket_dev_resume,
+static int vrc4171_card_suspend(struct platform_device *dev,
+ pm_message_t state)
+{
+ return pcmcia_socket_dev_suspend(&dev->dev, state);
+}
+
+static int vrc4171_card_resume(struct platform_device *dev)
+{
+ return pcmcia_socket_dev_resume(&dev->dev);
+}
+
+static struct platform_driver vrc4171_card_driver = {
+ .driver = {
+ .name = vrc4171_card_name,
+ .owner = THIS_MODULE,
+ },
+ .suspend = vrc4171_card_suspend,
+ .resume = vrc4171_card_resume,
};

static int __devinit vrc4171_card_init(void)
{
int retval;

- retval = driver_register(&vrc4171_card_driver);
+ retval = platform_driver_register(&vrc4171_card_driver);
if (retval < 0)
return retval;

retval = platform_device_register(&vrc4171_card_device);
if (retval < 0) {
- driver_unregister(&vrc4171_card_driver);
+ platform_driver_unregister(&vrc4171_card_driver);
return retval;
}

@@ -735,11 +748,12 @@ static int __devinit vrc4171_card_init(void)
if (retval < 0) {
vrc4171_remove_sockets();
platform_device_unregister(&vrc4171_card_device);
- driver_unregister(&vrc4171_card_driver);
+ platform_driver_unregister(&vrc4171_card_driver);
return retval;
}

- printk(KERN_INFO "%s, connected to IRQ %d\n", vrc4171_card_driver.name, vrc4171_irq);
+ printk(KERN_INFO "%s, connected to IRQ %d\n",
+ vrc4171_card_driver.driver.name, vrc4171_irq);

return 0;
}
@@ -749,7 +763,7 @@ static void __devexit vrc4171_card_exit(void)
free_irq(vrc4171_irq, vrc4171_sockets);
vrc4171_remove_sockets();
platform_device_unregister(&vrc4171_card_device);
- driver_unregister(&vrc4171_card_driver);
+ platform_driver_unregister(&vrc4171_card_driver);
}

module_init(vrc4171_card_init);
diff --git a/drivers/scsi/a4000t.c b/drivers/scsi/a4000t.c
index d4bda20..6d25aca 100644
--- a/drivers/scsi/a4000t.c
+++ b/drivers/scsi/a4000t.c
@@ -35,7 +35,7 @@ static struct platform_device *a4000t_scsi_device;

#define A4000T_SCSI_ADDR 0xdd0040

-static int __devinit a4000t_probe(struct device *dev)
+static int __devinit a4000t_probe(struct platform_device *dev)
{
struct Scsi_Host *host;
struct NCR_700_Host_Parameters *hostdata;
@@ -78,7 +78,7 @@ static int __devinit a4000t_probe(struct device *dev)
goto out_put_host;
}

- dev_set_drvdata(dev, host);
+ platform_set_drvdata(dev, host);
scsi_scan_host(host);

return 0;
@@ -93,9 +93,9 @@ static int __devinit a4000t_probe(struct device *dev)
return -ENODEV;
}

-static __devexit int a4000t_device_remove(struct device *dev)
+static __devexit int a4000t_device_remove(struct platform_device *dev)
{
- struct Scsi_Host *host = dev_get_drvdata(dev);
+ struct Scsi_Host *host = platform_get_drvdata(dev);
struct NCR_700_Host_Parameters *hostdata = shost_priv(host);

scsi_remove_host(host);
@@ -108,25 +108,27 @@ static __devexit int a4000t_device_remove(struct device *dev)
return 0;
}

-static struct device_driver a4000t_scsi_driver = {
- .name = "a4000t-scsi",
- .bus = &platform_bus_type,
- .probe = a4000t_probe,
- .remove = __devexit_p(a4000t_device_remove),
+static struct platform_driver a4000t_scsi_driver = {
+ .driver = {
+ .name = "a4000t-scsi",
+ .owner = THIS_MODULE,
+ },
+ .probe = a4000t_probe,
+ .remove = __devexit_p(a4000t_device_remove),
};

static int __init a4000t_scsi_init(void)
{
int err;

- err = driver_register(&a4000t_scsi_driver);
+ err = platform_driver_register(&a4000t_scsi_driver);
if (err)
return err;

a4000t_scsi_device = platform_device_register_simple("a4000t-scsi",
-1, NULL, 0);
if (IS_ERR(a4000t_scsi_device)) {
- driver_unregister(&a4000t_scsi_driver);
+ platform_driver_register(&a4000t_scsi_driver);
return PTR_ERR(a4000t_scsi_device);
}

@@ -136,7 +138,7 @@ static int __init a4000t_scsi_init(void)
static void __exit a4000t_scsi_exit(void)
{
platform_device_unregister(a4000t_scsi_device);
- driver_unregister(&a4000t_scsi_driver);
+ platform_driver_unregister(&a4000t_scsi_driver);
}

module_init(a4000t_scsi_init);
diff --git a/drivers/scsi/bvme6000_scsi.c b/drivers/scsi/bvme6000_scsi.c
index d858f3d..9e9a82b 100644
--- a/drivers/scsi/bvme6000_scsi.c
+++ b/drivers/scsi/bvme6000_scsi.c
@@ -34,7 +34,7 @@ static struct scsi_host_template bvme6000_scsi_driver_template = {
static struct platform_device *bvme6000_scsi_device;

static __devinit int
-bvme6000_probe(struct device *dev)
+bvme6000_probe(struct platform_device *dev)
{
struct Scsi_Host *host;
struct NCR_700_Host_Parameters *hostdata;
@@ -73,7 +73,7 @@ bvme6000_probe(struct device *dev)
goto out_put_host;
}

- dev_set_drvdata(dev, host);
+ platform_set_drvdata(dev, host);
scsi_scan_host(host);

return 0;
@@ -87,9 +87,9 @@ bvme6000_probe(struct device *dev)
}

static __devexit int
-bvme6000_device_remove(struct device *dev)
+bvme6000_device_remove(struct platform_device *dev)
{
- struct Scsi_Host *host = dev_get_drvdata(dev);
+ struct Scsi_Host *host = platform_get_drvdata(dev);
struct NCR_700_Host_Parameters *hostdata = shost_priv(host);

scsi_remove_host(host);
@@ -100,25 +100,27 @@ bvme6000_device_remove(struct device *dev)
return 0;
}

-static struct device_driver bvme6000_scsi_driver = {
- .name = "bvme6000-scsi",
- .bus = &platform_bus_type,
- .probe = bvme6000_probe,
- .remove = __devexit_p(bvme6000_device_remove),
+static struct platform_driver bvme6000_scsi_driver = {
+ .driver = {
+ .name = "bvme6000-scsi",
+ .owner = THIS_MODULE,
+ },
+ .probe = bvme6000_probe,
+ .remove = __devexit_p(bvme6000_device_remove),
};

static int __init bvme6000_scsi_init(void)
{
int err;

- err = driver_register(&bvme6000_scsi_driver);
+ err = platform_driver_register(&bvme6000_scsi_driver);
if (err)
return err;

bvme6000_scsi_device = platform_device_register_simple("bvme6000-scsi",
-1, NULL, 0);
if (IS_ERR(bvme6000_scsi_device)) {
- driver_unregister(&bvme6000_scsi_driver);
+ platform_driver_unregister(&bvme6000_scsi_driver);
return PTR_ERR(bvme6000_scsi_device);
}

@@ -128,7 +130,7 @@ static int __init bvme6000_scsi_init(void)
static void __exit bvme6000_scsi_exit(void)
{
platform_device_unregister(bvme6000_scsi_device);
- driver_unregister(&bvme6000_scsi_driver);
+ platform_driver_unregister(&bvme6000_scsi_driver);
}

module_init(bvme6000_scsi_init);
diff --git a/drivers/scsi/mvme16x_scsi.c b/drivers/scsi/mvme16x_scsi.c
index b264b49..7794fc1 100644
--- a/drivers/scsi/mvme16x_scsi.c
+++ b/drivers/scsi/mvme16x_scsi.c
@@ -34,7 +34,7 @@ static struct scsi_host_template mvme16x_scsi_driver_template = {
static struct platform_device *mvme16x_scsi_device;

static __devinit int
-mvme16x_probe(struct device *dev)
+mvme16x_probe(struct platform_device *dev)
{
struct Scsi_Host * host = NULL;
struct NCR_700_Host_Parameters *hostdata;
@@ -88,7 +88,7 @@ mvme16x_probe(struct device *dev)
out_be32(0xfff4202c, v);
}

- dev_set_drvdata(dev, host);
+ platform_set_drvdata(dev, host);
scsi_scan_host(host);

return 0;
@@ -102,9 +102,9 @@ mvme16x_probe(struct device *dev)
}

static __devexit int
-mvme16x_device_remove(struct device *dev)
+mvme16x_device_remove(struct platform_device *dev)
{
- struct Scsi_Host *host = dev_get_drvdata(dev);
+ struct Scsi_Host *host = platform_get_drvdata(dev);
struct NCR_700_Host_Parameters *hostdata = shost_priv(host);

/* Disable scsi chip ints */
@@ -123,25 +123,27 @@ mvme16x_device_remove(struct device *dev)
return 0;
}

-static struct device_driver mvme16x_scsi_driver = {
- .name = "mvme16x-scsi",
- .bus = &platform_bus_type,
- .probe = mvme16x_probe,
- .remove = __devexit_p(mvme16x_device_remove),
+static struct platform_driver mvme16x_scsi_driver = {
+ .driver = {
+ .name = "mvme16x-scsi",
+ .owner = THIS_MODULE,
+ },
+ .probe = mvme16x_probe,
+ .remove = __devexit_p(mvme16x_device_remove),
};

static int __init mvme16x_scsi_init(void)
{
int err;

- err = driver_register(&mvme16x_scsi_driver);
+ err = platform_driver_register(&mvme16x_scsi_driver);
if (err)
return err;

mvme16x_scsi_device = platform_device_register_simple("mvme16x-scsi",
-1, NULL, 0);
if (IS_ERR(mvme16x_scsi_device)) {
- driver_unregister(&mvme16x_scsi_driver);
+ platform_driver_unregister(&mvme16x_scsi_driver);
return PTR_ERR(mvme16x_scsi_device);
}

@@ -151,7 +153,7 @@ static int __init mvme16x_scsi_init(void)
static void __exit mvme16x_scsi_exit(void)
{
platform_device_unregister(mvme16x_scsi_device);
- driver_unregister(&mvme16x_scsi_driver);
+ platform_driver_unregister(&mvme16x_scsi_driver);
}

module_init(mvme16x_scsi_init);
diff --git a/drivers/video/au1100fb.c b/drivers/video/au1100fb.c
index 62bd444..378f277 100644
--- a/drivers/video/au1100fb.c
+++ b/drivers/video/au1100fb.c
@@ -457,7 +457,7 @@ static struct fb_ops au1100fb_ops =

/* AU1100 LCD controller device driver */

-static int __init au1100fb_drv_probe(struct device *dev)
+static int __init au1100fb_drv_probe(struct platform_device *dev)
{
struct au1100fb_device *fbdev = NULL;
struct resource *regs_res;
@@ -475,7 +475,7 @@ static int __init au1100fb_drv_probe(struct device *dev)

fbdev->panel = &known_lcd_panels[drv_info.panel_idx];

- dev_set_drvdata(dev, (void*)fbdev);
+ platform_set_drvdata(dev, (void *)fbdev);

/* Allocate region for our registers and map them */
if (!(regs_res = platform_get_resource(to_platform_device(dev),
@@ -583,19 +583,19 @@ failed:
fb_dealloc_cmap(&fbdev->info.cmap);
}
kfree(fbdev);
- dev_set_drvdata(dev, NULL);
+ platform_set_drvdata(dev, NULL);

return 0;
}

-int au1100fb_drv_remove(struct device *dev)
+int au1100fb_drv_remove(struct platform_device *dev)
{
struct au1100fb_device *fbdev = NULL;

if (!dev)
return -ENODEV;

- fbdev = (struct au1100fb_device*) dev_get_drvdata(dev);
+ fbdev = (struct au1100fb_device *) platform_get_drvdata(dev);

#if !defined(CONFIG_FRAMEBUFFER_CONSOLE) && defined(CONFIG_LOGO)
au1100fb_fb_blank(VESA_POWERDOWN, &fbdev->info);
@@ -620,9 +620,9 @@ int au1100fb_drv_remove(struct device *dev)
static u32 sys_clksrc;
static struct au1100fb_regs fbregs;

-int au1100fb_drv_suspend(struct device *dev, pm_message_t state)
+int au1100fb_drv_suspend(struct platform_device *dev, pm_message_t state)
{
- struct au1100fb_device *fbdev = dev_get_drvdata(dev);
+ struct au1100fb_device *fbdev = platform_get_drvdata(dev);

if (!fbdev)
return 0;
@@ -641,9 +641,9 @@ int au1100fb_drv_suspend(struct device *dev, pm_message_t state)
return 0;
}

-int au1100fb_drv_resume(struct device *dev)
+int au1100fb_drv_resume(struct platform_device *dev)
{
- struct au1100fb_device *fbdev = dev_get_drvdata(dev);
+ struct au1100fb_device *fbdev = platform_get_drvdata(dev);

if (!fbdev)
return 0;
@@ -663,10 +663,11 @@ int au1100fb_drv_resume(struct device *dev)
#define au1100fb_drv_resume NULL
#endif

-static struct device_driver au1100fb_driver = {
- .name = "au1100-lcd",
- .bus = &platform_bus_type,
-
+static struct platform_driver au1100fb_driver = {
+ .driver = {
+ .name = "au1100-lcd",
+ .owner = THIS_MODULE,
+ },
.probe = au1100fb_drv_probe,
.remove = au1100fb_drv_remove,
.suspend = au1100fb_drv_suspend,
@@ -753,12 +754,12 @@ int __init au1100fb_init(void)
return ret;
}

- return driver_register(&au1100fb_driver);
+ return platform_driver_register(&au1100fb_driver);
}

void __exit au1100fb_cleanup(void)
{
- driver_unregister(&au1100fb_driver);
+ platform_driver_unregister(&au1100fb_driver);

kfree(drv_info.opt_mode);
}
diff --git a/drivers/video/au1200fb.c b/drivers/video/au1200fb.c
index 03e57ef..0d96f1d 100644
--- a/drivers/video/au1200fb.c
+++ b/drivers/video/au1200fb.c
@@ -1622,7 +1622,7 @@ static int au1200fb_init_fbinfo(struct au1200fb_device *fbdev)

/* AU1200 LCD controller device driver */

-static int au1200fb_drv_probe(struct device *dev)
+static int au1200fb_drv_probe(struct platform_device *dev)
{
struct au1200fb_device *fbdev;
unsigned long page;
@@ -1645,7 +1645,7 @@ static int au1200fb_drv_probe(struct device *dev)
/* Allocate the framebuffer to the maximum screen size */
fbdev->fb_len = (win->w[plane].xres * win->w[plane].yres * bpp) / 8;

- fbdev->fb_mem = dma_alloc_noncoherent(dev,
+ fbdev->fb_mem = dma_alloc_noncoherent(&dev->dev,
PAGE_ALIGN(fbdev->fb_len),
&fbdev->fb_phys, GFP_KERNEL);
if (!fbdev->fb_mem) {
@@ -1715,7 +1715,7 @@ failed:
return ret;
}

-static int au1200fb_drv_remove(struct device *dev)
+static int au1200fb_drv_remove(struct platform_device *dev)
{
struct au1200fb_device *fbdev;
int plane;
@@ -1733,7 +1733,8 @@ static int au1200fb_drv_remove(struct device *dev)
/* Clean up all probe data */
unregister_framebuffer(&fbdev->fb_info);
if (fbdev->fb_mem)
- dma_free_noncoherent(dev, PAGE_ALIGN(fbdev->fb_len),
+ dma_free_noncoherent(&dev->dev,
+ PAGE_ALIGN(fbdev->fb_len),
fbdev->fb_mem, fbdev->fb_phys);
if (fbdev->fb_info.cmap.len != 0)
fb_dealloc_cmap(&fbdev->fb_info.cmap);
@@ -1747,22 +1748,24 @@ static int au1200fb_drv_remove(struct device *dev)
}

#ifdef CONFIG_PM
-static int au1200fb_drv_suspend(struct device *dev, u32 state, u32 level)
+static int au1200fb_drv_suspend(struct platform_device *dev, u32 state)
{
/* TODO */
return 0;
}

-static int au1200fb_drv_resume(struct device *dev, u32 level)
+static int au1200fb_drv_resume(struct platform_device *dev)
{
/* TODO */
return 0;
}
#endif /* CONFIG_PM */

-static struct device_driver au1200fb_driver = {
- .name = "au1200-lcd",
- .bus = &platform_bus_type,
+static struct platform_driver au1200fb_driver = {
+ .driver = {
+ .name = "au1200-lcd",
+ .owner = THIS_MODULE,
+ },
.probe = au1200fb_drv_probe,
.remove = au1200fb_drv_remove,
#ifdef CONFIG_PM
@@ -1906,12 +1909,12 @@ static int __init au1200fb_init(void)
printk(KERN_INFO "Power management device entry for the au1200fb loaded.\n");
#endif

- return driver_register(&au1200fb_driver);
+ return platform_driver_register(&au1200fb_driver);
}

static void __exit au1200fb_cleanup(void)
{
- driver_unregister(&au1200fb_driver);
+ platform_driver_unregister(&au1200fb_driver);
}

module_init(au1200fb_init);
diff --git a/drivers/watchdog/rm9k_wdt.c b/drivers/watchdog/rm9k_wdt.c
index f1ae372..cce1982 100644
--- a/drivers/watchdog/rm9k_wdt.c
+++ b/drivers/watchdog/rm9k_wdt.c
@@ -59,8 +59,8 @@ static long wdt_gpi_ioctl(struct file *, unsigned int, unsigned long);
static int wdt_gpi_notify(struct notifier_block *, unsigned long, void *);
static const struct resource *wdt_gpi_get_resource(struct platform_device *,
const char *, unsigned int);
-static int __init wdt_gpi_probe(struct device *);
-static int __exit wdt_gpi_remove(struct device *);
+static int __init wdt_gpi_probe(struct platform_device *);
+static int __exit wdt_gpi_remove(struct platform_device *);


static const char wdt_gpi_name[] = "wdt_gpi";
@@ -346,10 +346,9 @@ static const struct resource *wdt_gpi_get_resource(struct platform_device *pdv,
}

/* No hotplugging on the platform bus - use __init */
-static int __init wdt_gpi_probe(struct device *dev)
+static int __init wdt_gpi_probe(struct platform_device *pdv)
{
int res;
- struct platform_device * const pdv = to_platform_device(dev);
const struct resource
* const rr = wdt_gpi_get_resource(pdv, WDT_RESOURCE_REGS,
IORESOURCE_MEM),
@@ -374,7 +373,7 @@ static int __init wdt_gpi_probe(struct device *dev)
return res;
}

-static int __exit wdt_gpi_remove(struct device *dev)
+static int __exit wdt_gpi_remove(struct platform_device *dev)
{
int res;

@@ -387,15 +386,13 @@ static int __exit wdt_gpi_remove(struct device *dev)


/* Device driver init & exit */
-static struct device_driver wdt_gpi_driver = {
- .name = (char *) wdt_gpi_name,
- .bus = &platform_bus_type,
- .owner = THIS_MODULE,
+static struct platform_driver wgt_gpi_driver = {
+ .driver = {
+ .name = wdt_gpi_name,
+ .owner = THIS_MODULE,
+ },
.probe = wdt_gpi_probe,
- .remove = __exit_p(wdt_gpi_remove),
- .shutdown = NULL,
- .suspend = NULL,
- .resume = NULL,
+ .remove = __devexit_p(wdt_gpi_remove),
};

static int __init wdt_gpi_init_module(void)
@@ -403,12 +400,12 @@ static int __init wdt_gpi_init_module(void)
atomic_set(&opencnt, 1);
if (timeout > MAX_TIMEOUT_SECONDS)
timeout = MAX_TIMEOUT_SECONDS;
- return driver_register(&wdt_gpi_driver);
+ return platform_driver_register(&wdt_gpi_driver);
}

static void __exit wdt_gpi_cleanup_module(void)
{
- driver_unregister(&wdt_gpi_driver);
+ platform_driver_unregister(&wdt_gpi_driver);
}

module_init(wdt_gpi_init_module);
--
1.6.2

2009-03-25 00:44:20

by Greg KH

[permalink] [raw]
Subject: [PATCH 40/61] driver-core: do not register a driver with bus_type not registered

From: Dave Young <[email protected]>

If the bus_type is not registerd, driver_register to that bus will cause oops.

I found this bug when test built-in usb serial drivers (ie. aircable driver)
with 'nousb' cmdline params.

In this patch:
1. set the bus->p=NULL when bus_register failed and unregisterd.
2. if bus->p is NULL, driver_register BUG_ON will be triggered.

Signed-off-by: Dave Young <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/base/bus.c | 2 ++
drivers/base/driver.c | 2 ++
2 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index 8547b78..11463c0 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -932,6 +932,7 @@ bus_uevent_fail:
kset_unregister(&bus->p->subsys);
kfree(bus->p);
out:
+ bus->p = NULL;
return retval;
}
EXPORT_SYMBOL_GPL(bus_register);
@@ -953,6 +954,7 @@ void bus_unregister(struct bus_type *bus)
bus_remove_file(bus, &bus_attr_uevent);
kset_unregister(&bus->p->subsys);
kfree(bus->p);
+ bus->p = NULL;
}
EXPORT_SYMBOL_GPL(bus_unregister);

diff --git a/drivers/base/driver.c b/drivers/base/driver.c
index 1e2bda7..2889ad5 100644
--- a/drivers/base/driver.c
+++ b/drivers/base/driver.c
@@ -216,6 +216,8 @@ int driver_register(struct device_driver *drv)
int ret;
struct device_driver *other;

+ BUG_ON(!drv->bus->p);
+
if ((drv->bus->probe && drv->probe) ||
(drv->bus->remove && drv->remove) ||
(drv->bus->shutdown && drv->shutdown))
--
1.6.2

2009-03-25 00:44:38

by Greg KH

[permalink] [raw]
Subject: [PATCH 39/61] scsi/m68k: Kill NCR_700_detect() warnings

From: Geert Uytterhoeven <[email protected]>

The patch from Ming Lei <[email protected]> entitled:
platform driver: fix incorrect use of 'platform_bus_type' with 'struct devic
introduced the following warnings on m68k, as `dev' is now a `struct
platform_device *' instead of a `struct device *':

| drivers/scsi/a4000t.c:64: warning: passing argument 3 of 'NCR_700_detect' from incompatible pointer type
| drivers/scsi/mvme16x_scsi.c:67: warning: passing argument 3 of 'NCR_700_detect' from incompatible pointer type
| drivers/scsi/bvme6000_scsi.c:61: warning: passing argument 3 of 'NCR_700_detect' from incompatible pointer type

I think the below is missing (untested on real hardware).

Signed-off-by: Geert Uytterhoeven <[email protected]>
Cc: Ming Lei <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/scsi/a4000t.c | 3 ++-
drivers/scsi/bvme6000_scsi.c | 3 ++-
drivers/scsi/mvme16x_scsi.c | 3 ++-
3 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/a4000t.c b/drivers/scsi/a4000t.c
index 6d25aca..61af3d9 100644
--- a/drivers/scsi/a4000t.c
+++ b/drivers/scsi/a4000t.c
@@ -61,7 +61,8 @@ static int __devinit a4000t_probe(struct platform_device *dev)
hostdata->dcntl_extra = EA_710;

/* and register the chip */
- host = NCR_700_detect(&a4000t_scsi_driver_template, hostdata, dev);
+ host = NCR_700_detect(&a4000t_scsi_driver_template, hostdata,
+ &dev->dev);
if (!host) {
printk(KERN_ERR "a4000t-scsi: No host detected; "
"board configuration problem?\n");
diff --git a/drivers/scsi/bvme6000_scsi.c b/drivers/scsi/bvme6000_scsi.c
index 9e9a82b..5799cb5 100644
--- a/drivers/scsi/bvme6000_scsi.c
+++ b/drivers/scsi/bvme6000_scsi.c
@@ -58,7 +58,8 @@ bvme6000_probe(struct platform_device *dev)
hostdata->ctest7_extra = CTEST7_TT1;

/* and register the chip */
- host = NCR_700_detect(&bvme6000_scsi_driver_template, hostdata, dev);
+ host = NCR_700_detect(&bvme6000_scsi_driver_template, hostdata,
+ &dev->dev);
if (!host) {
printk(KERN_ERR "bvme6000-scsi: No host detected; "
"board configuration problem?\n");
diff --git a/drivers/scsi/mvme16x_scsi.c b/drivers/scsi/mvme16x_scsi.c
index 7794fc1..b5fbfd6 100644
--- a/drivers/scsi/mvme16x_scsi.c
+++ b/drivers/scsi/mvme16x_scsi.c
@@ -64,7 +64,8 @@ mvme16x_probe(struct platform_device *dev)
hostdata->ctest7_extra = CTEST7_TT1;

/* and register the chip */
- host = NCR_700_detect(&mvme16x_scsi_driver_template, hostdata, dev);
+ host = NCR_700_detect(&mvme16x_scsi_driver_template, hostdata,
+ &dev->dev);
if (!host) {
printk(KERN_ERR "mvme16x-scsi: No host detected; "
"board configuration problem?\n");
--
1.6.2

2009-03-25 00:44:54

by Greg KH

[permalink] [raw]
Subject: [PATCH 41/61] sysfs: sysfs_add_one WARNs with full path to duplicate filename

From: Alex Chiang <[email protected]>

sysfs: sysfs_add_one WARNs with full path to duplicate filename

As a debugging aid, it can be useful to know the full path to a
duplicate file being created in sysfs.

We now will display warnings such as:

sysfs: cannot create duplicate filename '/foo'

when attempting to create multiple files named 'foo' in the sysfs
root, or:

sysfs: cannot create duplicate filename '/bus/pci/slots/5/foo'

when attempting to create multiple files named 'foo' under a
given directory in sysfs.

The path displayed is always a relative path to sysfs_root. The
leading '/' in the path name refers to the sysfs_root mount
point, and should not be confused with the "real" '/'.

Thanks to Alex Williamson for essentially writing sysfs_pathname.

Cc: Alex Williamson <[email protected]>
Signed-off-by: Alex Chiang <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
fs/sysfs/dir.c | 32 ++++++++++++++++++++++++++++++--
1 files changed, 30 insertions(+), 2 deletions(-)

diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c
index 82d3b79..f13d852 100644
--- a/fs/sysfs/dir.c
+++ b/fs/sysfs/dir.c
@@ -434,6 +434,26 @@ int __sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd)
}

/**
+ * sysfs_pathname - return full path to sysfs dirent
+ * @sd: sysfs_dirent whose path we want
+ * @path: caller allocated buffer
+ *
+ * Gives the name "/" to the sysfs_root entry; any path returned
+ * is relative to wherever sysfs is mounted.
+ *
+ * XXX: does no error checking on @path size
+ */
+static char *sysfs_pathname(struct sysfs_dirent *sd, char *path)
+{
+ if (sd->s_parent) {
+ sysfs_pathname(sd->s_parent, path);
+ strcat(path, "/");
+ }
+ strcat(path, sd->s_name);
+ return path;
+}
+
+/**
* sysfs_add_one - add sysfs_dirent to parent
* @acxt: addrm context to use
* @sd: sysfs_dirent to be added
@@ -458,8 +478,16 @@ int sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd)
int ret;

ret = __sysfs_add_one(acxt, sd);
- WARN(ret == -EEXIST, KERN_WARNING "sysfs: duplicate filename '%s' "
- "can not be created\n", sd->s_name);
+ if (ret == -EEXIST) {
+ char *path = kzalloc(PATH_MAX, GFP_KERNEL);
+ WARN(1, KERN_WARNING
+ "sysfs: cannot create duplicate filename '%s'\n",
+ (path == NULL) ? sd->s_name :
+ strcat(strcat(sysfs_pathname(acxt->parent_sd, path), "/"),
+ sd->s_name));
+ kfree(path);
+ }
+
return ret;
}

--
1.6.2

2009-03-25 00:45:25

by Greg KH

[permalink] [raw]
Subject: [PATCH 42/61] sysfs: reference sysfs_dirent from sysfs inodes

From: Eric W. Biederman <[email protected]>

The sysfs_dirent serves as both an inode and a directory entry
for sysfs. To prevent the sysfs inode numbers from being freed
prematurely hold a reference to sysfs_dirent from the sysfs inode.

[[email protected]: add comment]
Signed-off-by: Eric W. Biederman <[email protected]>
Cc: Tejun Heo <[email protected]>
Cc: Al Viro <[email protected]>
Cc: Cornelia Huck <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
fs/sysfs/inode.c | 17 +++++++++++++++++
fs/sysfs/mount.c | 1 +
fs/sysfs/sysfs.h | 1 +
3 files changed, 19 insertions(+), 0 deletions(-)

diff --git a/fs/sysfs/inode.c b/fs/sysfs/inode.c
index dfa3d94..555f0ff 100644
--- a/fs/sysfs/inode.c
+++ b/fs/sysfs/inode.c
@@ -147,6 +147,7 @@ static void sysfs_init_inode(struct sysfs_dirent *sd, struct inode *inode)
{
struct bin_attribute *bin_attr;

+ inode->i_private = sysfs_get(sd);
inode->i_mapping->a_ops = &sysfs_aops;
inode->i_mapping->backing_dev_info = &sysfs_backing_dev_info;
inode->i_op = &sysfs_inode_operations;
@@ -214,6 +215,22 @@ struct inode * sysfs_get_inode(struct sysfs_dirent *sd)
return inode;
}

+/*
+ * The sysfs_dirent serves as both an inode and a directory entry for sysfs.
+ * To prevent the sysfs inode numbers from being freed prematurely we take a
+ * reference to sysfs_dirent from the sysfs inode. A
+ * super_operations.delete_inode() implementation is needed to drop that
+ * reference upon inode destruction.
+ */
+void sysfs_delete_inode(struct inode *inode)
+{
+ struct sysfs_dirent *sd = inode->i_private;
+
+ truncate_inode_pages(&inode->i_data, 0);
+ clear_inode(inode);
+ sysfs_put(sd);
+}
+
int sysfs_hash_and_remove(struct sysfs_dirent *dir_sd, const char *name)
{
struct sysfs_addrm_cxt acxt;
diff --git a/fs/sysfs/mount.c b/fs/sysfs/mount.c
index 84ef378..4974995 100644
--- a/fs/sysfs/mount.c
+++ b/fs/sysfs/mount.c
@@ -29,6 +29,7 @@ struct kmem_cache *sysfs_dir_cachep;
static const struct super_operations sysfs_ops = {
.statfs = simple_statfs,
.drop_inode = generic_delete_inode,
+ .delete_inode = sysfs_delete_inode,
};

struct sysfs_dirent sysfs_root = {
diff --git a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h
index 93c6d6b..9055d04 100644
--- a/fs/sysfs/sysfs.h
+++ b/fs/sysfs/sysfs.h
@@ -145,6 +145,7 @@ static inline void __sysfs_put(struct sysfs_dirent *sd)
* inode.c
*/
struct inode *sysfs_get_inode(struct sysfs_dirent *sd);
+void sysfs_delete_inode(struct inode *inode);
int sysfs_setattr(struct dentry *dentry, struct iattr *iattr);
int sysfs_hash_and_remove(struct sysfs_dirent *dir_sd, const char *name);
int sysfs_inode_init(void);
--
1.6.2

2009-03-25 00:45:49

by Greg KH

[permalink] [raw]
Subject: [PATCH 43/61] driver core: remove polling for driver_probe_done(v5)

From: Ming Lei <[email protected]>

This patch removes 100ms polling for driver_probe_done in
wait_for_device_probe(), and uses wait_event() instead.
Removing polling in fs initialization may lead to
a faster boot.

This patch also changes the return type of wait_for_device_done()
from int to void.

This patch is against Arjan's patch in linux-next tree.

Signed-off-by: Ming Lei <[email protected]>
Acked-by: Cornelia Huck <[email protected]>
Reviewed-by: Arjan van de Ven <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/base/dd.c | 8 ++------
include/linux/device.h | 2 +-
2 files changed, 3 insertions(+), 7 deletions(-)

diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index 3f32df7..0dfd08c 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -172,16 +172,12 @@ int driver_probe_done(void)
/**
* wait_for_device_probe
* Wait for device probing to be completed.
- *
- * Note: this function polls at 100 msec intervals.
*/
-int wait_for_device_probe(void)
+void wait_for_device_probe(void)
{
/* wait for the known devices to complete their probing */
- while (driver_probe_done() != 0)
- msleep(100);
+ wait_event(probe_waitqueue, atomic_read(&probe_count) == 0);
async_synchronize_full();
- return 0;
}

/**
diff --git a/include/linux/device.h b/include/linux/device.h
index d5706c4..c56b154 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -147,7 +147,7 @@ extern void put_driver(struct device_driver *drv);
extern struct device_driver *driver_find(const char *name,
struct bus_type *bus);
extern int driver_probe_done(void);
-extern int wait_for_device_probe(void);
+extern void wait_for_device_probe(void);


/* sysfs interface for exporting driver attributes */
--
1.6.2

2009-03-25 00:46:14

by Greg KH

[permalink] [raw]
Subject: [PATCH 44/61] driver core: create a private portion of struct device

This is to be used to move things out of struct device that no code
outside of the driver core should ever touch.

Cc: Kay Sievers <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/base/base.h | 12 ++++++++++++
drivers/base/core.c | 9 +++++++++
include/linux/device.h | 3 +++
3 files changed, 24 insertions(+), 0 deletions(-)

diff --git a/drivers/base/base.h b/drivers/base/base.h
index ca2b037..62a2cb5 100644
--- a/drivers/base/base.h
+++ b/drivers/base/base.h
@@ -63,6 +63,18 @@ struct class_private {
#define to_class(obj) \
container_of(obj, struct class_private, class_subsys.kobj)

+/**
+ * struct device_private - structure to hold the private to the driver core portions of the device structure.
+ *
+ * @device - pointer back to the struct class that this structure is
+ * associated with.
+ *
+ * Nothing outside of the driver core should ever touch these fields.
+ */
+struct device_private {
+ struct device *device;
+};
+
/* initialisation functions */
extern int devices_init(void);
extern int buses_init(void);
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 059966b..16d8599 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -109,6 +109,7 @@ static struct sysfs_ops dev_sysfs_ops = {
static void device_release(struct kobject *kobj)
{
struct device *dev = to_dev(kobj);
+ struct device_private *p = dev->p;

if (dev->release)
dev->release(dev);
@@ -120,6 +121,7 @@ static void device_release(struct kobject *kobj)
WARN(1, KERN_ERR "Device '%s' does not have a release() "
"function, it is broken and must be fixed.\n",
dev_name(dev));
+ kfree(p);
}

static struct kobj_type device_ktype = {
@@ -859,6 +861,13 @@ int device_add(struct device *dev)
if (!dev)
goto done;

+ dev->p = kzalloc(sizeof(*dev->p), GFP_KERNEL);
+ if (!dev->p) {
+ error = -ENOMEM;
+ goto done;
+ }
+ dev->p->device = dev;
+
/*
* for statically allocated devices, which should all be converted
* some day, we need to initialize the name. We prevent reading back
diff --git a/include/linux/device.h b/include/linux/device.h
index c56b154..4cf063f 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -28,6 +28,7 @@
#define BUS_ID_SIZE 20

struct device;
+struct device_private;
struct device_driver;
struct driver_private;
struct class;
@@ -373,6 +374,8 @@ struct device {
struct klist_node knode_bus;
struct device *parent;

+ struct device_private *p;
+
struct kobject kobj;
unsigned uevent_suppress:1;
const char *init_name; /* initial name of the device */
--
1.6.2

2009-03-25 00:46:34

by Greg KH

[permalink] [raw]
Subject: [PATCH 45/61] driver core: move klist_children into private structure

Nothing outside of the driver core should ever touch klist_children, or
knode_parent, so move them out of the public eye.

Cc: Kay Sievers <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/base/base.h | 6 ++++++
drivers/base/core.c | 39 +++++++++++++++++++++++++--------------
include/linux/device.h | 2 --
3 files changed, 31 insertions(+), 16 deletions(-)

diff --git a/drivers/base/base.h b/drivers/base/base.h
index 62a2cb5..7c4fafc 100644
--- a/drivers/base/base.h
+++ b/drivers/base/base.h
@@ -66,14 +66,20 @@ struct class_private {
/**
* struct device_private - structure to hold the private to the driver core portions of the device structure.
*
+ * @klist_children - klist containing all children of this device
+ * @knode_parent - node in sibling list
* @device - pointer back to the struct class that this structure is
* associated with.
*
* Nothing outside of the driver core should ever touch these fields.
*/
struct device_private {
+ struct klist klist_children;
+ struct klist_node knode_parent;
struct device *device;
};
+#define to_device_private_parent(obj) \
+ container_of(obj, struct device_private, knode_parent)

/* initialisation functions */
extern int devices_init(void);
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 16d8599..a90f56f 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -509,14 +509,16 @@ EXPORT_SYMBOL_GPL(device_schedule_callback_owner);

static void klist_children_get(struct klist_node *n)
{
- struct device *dev = container_of(n, struct device, knode_parent);
+ struct device_private *p = to_device_private_parent(n);
+ struct device *dev = p->device;

get_device(dev);
}

static void klist_children_put(struct klist_node *n)
{
- struct device *dev = container_of(n, struct device, knode_parent);
+ struct device_private *p = to_device_private_parent(n);
+ struct device *dev = p->device;

put_device(dev);
}
@@ -540,8 +542,6 @@ void device_initialize(struct device *dev)
{
dev->kobj.kset = devices_kset;
kobject_init(&dev->kobj, &device_ktype);
- klist_init(&dev->klist_children, klist_children_get,
- klist_children_put);
INIT_LIST_HEAD(&dev->dma_pools);
init_MUTEX(&dev->sem);
spin_lock_init(&dev->devres_lock);
@@ -867,6 +867,8 @@ int device_add(struct device *dev)
goto done;
}
dev->p->device = dev;
+ klist_init(&dev->p->klist_children, klist_children_get,
+ klist_children_put);

/*
* for statically allocated devices, which should all be converted
@@ -937,7 +939,8 @@ int device_add(struct device *dev)
kobject_uevent(&dev->kobj, KOBJ_ADD);
bus_attach_device(dev);
if (parent)
- klist_add_tail(&dev->knode_parent, &parent->klist_children);
+ klist_add_tail(&dev->p->knode_parent,
+ &parent->p->klist_children);

if (dev->class) {
mutex_lock(&dev->class->p->class_mutex);
@@ -1051,7 +1054,7 @@ void device_del(struct device *dev)
device_pm_remove(dev);
dpm_sysfs_remove(dev);
if (parent)
- klist_del(&dev->knode_parent);
+ klist_del(&dev->p->knode_parent);
if (MAJOR(dev->devt)) {
device_remove_sys_dev_entry(dev);
device_remove_file(dev, &devt_attr);
@@ -1112,7 +1115,14 @@ void device_unregister(struct device *dev)
static struct device *next_device(struct klist_iter *i)
{
struct klist_node *n = klist_next(i);
- return n ? container_of(n, struct device, knode_parent) : NULL;
+ struct device *dev = NULL;
+ struct device_private *p;
+
+ if (n) {
+ p = to_device_private_parent(n);
+ dev = p->device;
+ }
+ return dev;
}

/**
@@ -1134,7 +1144,7 @@ int device_for_each_child(struct device *parent, void *data,
struct device *child;
int error = 0;

- klist_iter_init(&parent->klist_children, &i);
+ klist_iter_init(&parent->p->klist_children, &i);
while ((child = next_device(&i)) && !error)
error = fn(child, data);
klist_iter_exit(&i);
@@ -1165,7 +1175,7 @@ struct device *device_find_child(struct device *parent, void *data,
if (!parent)
return NULL;

- klist_iter_init(&parent->klist_children, &i);
+ klist_iter_init(&parent->p->klist_children, &i);
while ((child = next_device(&i)))
if (match(child, data) && get_device(child))
break;
@@ -1578,9 +1588,10 @@ int device_move(struct device *dev, struct device *new_parent)
old_parent = dev->parent;
dev->parent = new_parent;
if (old_parent)
- klist_remove(&dev->knode_parent);
+ klist_remove(&dev->p->knode_parent);
if (new_parent) {
- klist_add_tail(&dev->knode_parent, &new_parent->klist_children);
+ klist_add_tail(&dev->p->knode_parent,
+ &new_parent->p->klist_children);
set_dev_node(dev, dev_to_node(new_parent));
}

@@ -1592,11 +1603,11 @@ int device_move(struct device *dev, struct device *new_parent)
device_move_class_links(dev, new_parent, old_parent);
if (!kobject_move(&dev->kobj, &old_parent->kobj)) {
if (new_parent)
- klist_remove(&dev->knode_parent);
+ klist_remove(&dev->p->knode_parent);
dev->parent = old_parent;
if (old_parent) {
- klist_add_tail(&dev->knode_parent,
- &old_parent->klist_children);
+ klist_add_tail(&dev->p->knode_parent,
+ &old_parent->p->klist_children);
set_dev_node(dev, dev_to_node(old_parent));
}
}
diff --git a/include/linux/device.h b/include/linux/device.h
index 4cf063f..808d808 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -368,8 +368,6 @@ struct device_dma_parameters {
};

struct device {
- struct klist klist_children;
- struct klist_node knode_parent; /* node in sibling list */
struct klist_node knode_driver;
struct klist_node knode_bus;
struct device *parent;
--
1.6.2

2009-03-25 00:46:51

by Greg KH

[permalink] [raw]
Subject: [PATCH 46/61] driver core: move knode_driver into private structure

Nothing outside of the driver core should ever touch knode_driver, so
move it out of the public eye.

Cc: Kay Sievers <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/base/base.h | 4 ++++
drivers/base/dd.c | 13 ++++++++-----
drivers/base/driver.c | 13 ++++++++++---
include/linux/device.h | 1 -
4 files changed, 22 insertions(+), 9 deletions(-)

diff --git a/drivers/base/base.h b/drivers/base/base.h
index 7c4fafc..4fc5fd3 100644
--- a/drivers/base/base.h
+++ b/drivers/base/base.h
@@ -68,6 +68,7 @@ struct class_private {
*
* @klist_children - klist containing all children of this device
* @knode_parent - node in sibling list
+ * @knode_driver - node in driver list
* @device - pointer back to the struct class that this structure is
* associated with.
*
@@ -76,10 +77,13 @@ struct class_private {
struct device_private {
struct klist klist_children;
struct klist_node knode_parent;
+ struct klist_node knode_driver;
struct device *device;
};
#define to_device_private_parent(obj) \
container_of(obj, struct device_private, knode_parent)
+#define to_device_private_driver(obj) \
+ container_of(obj, struct device_private, knode_driver)

/* initialisation functions */
extern int devices_init(void);
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index 0dfd08c..f17c326 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -30,7 +30,7 @@

static void driver_bound(struct device *dev)
{
- if (klist_node_attached(&dev->knode_driver)) {
+ if (klist_node_attached(&dev->p->knode_driver)) {
printk(KERN_WARNING "%s: device %s already bound\n",
__func__, kobject_name(&dev->kobj));
return;
@@ -43,7 +43,7 @@ static void driver_bound(struct device *dev)
blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
BUS_NOTIFY_BOUND_DRIVER, dev);

- klist_add_tail(&dev->knode_driver, &dev->driver->p->klist_devices);
+ klist_add_tail(&dev->p->knode_driver, &dev->driver->p->klist_devices);
}

static int driver_sysfs_add(struct device *dev)
@@ -318,7 +318,7 @@ static void __device_release_driver(struct device *dev)
drv->remove(dev);
devres_release_all(dev);
dev->driver = NULL;
- klist_remove(&dev->knode_driver);
+ klist_remove(&dev->p->knode_driver);
}
}

@@ -348,6 +348,7 @@ EXPORT_SYMBOL_GPL(device_release_driver);
*/
void driver_detach(struct device_driver *drv)
{
+ struct device_private *dev_prv;
struct device *dev;

for (;;) {
@@ -356,8 +357,10 @@ void driver_detach(struct device_driver *drv)
spin_unlock(&drv->p->klist_devices.k_lock);
break;
}
- dev = list_entry(drv->p->klist_devices.k_list.prev,
- struct device, knode_driver.n_node);
+ dev_prv = list_entry(drv->p->klist_devices.k_list.prev,
+ struct device_private,
+ knode_driver.n_node);
+ dev = dev_prv->device;
get_device(dev);
spin_unlock(&drv->p->klist_devices.k_lock);

diff --git a/drivers/base/driver.c b/drivers/base/driver.c
index 2889ad5..c51f11b 100644
--- a/drivers/base/driver.c
+++ b/drivers/base/driver.c
@@ -19,7 +19,14 @@
static struct device *next_device(struct klist_iter *i)
{
struct klist_node *n = klist_next(i);
- return n ? container_of(n, struct device, knode_driver) : NULL;
+ struct device *dev = NULL;
+ struct device_private *dev_prv;
+
+ if (n) {
+ dev_prv = to_device_private_driver(n);
+ dev = dev_prv->device;
+ }
+ return dev;
}

/**
@@ -42,7 +49,7 @@ int driver_for_each_device(struct device_driver *drv, struct device *start,
return -EINVAL;

klist_iter_init_node(&drv->p->klist_devices, &i,
- start ? &start->knode_driver : NULL);
+ start ? &start->p->knode_driver : NULL);
while ((dev = next_device(&i)) && !error)
error = fn(dev, data);
klist_iter_exit(&i);
@@ -76,7 +83,7 @@ struct device *driver_find_device(struct device_driver *drv,
return NULL;

klist_iter_init_node(&drv->p->klist_devices, &i,
- (start ? &start->knode_driver : NULL));
+ (start ? &start->p->knode_driver : NULL));
while ((dev = next_device(&i)))
if (match(dev, data) && get_device(dev))
break;
diff --git a/include/linux/device.h b/include/linux/device.h
index 808d808..83e241f 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -368,7 +368,6 @@ struct device_dma_parameters {
};

struct device {
- struct klist_node knode_driver;
struct klist_node knode_bus;
struct device *parent;

--
1.6.2

2009-03-25 00:47:21

by Greg KH

[permalink] [raw]
Subject: [PATCH 47/61] driver core: move knode_bus into private structure

Nothing outside of the driver core should ever touch knode_bus, so
move it out of the public eye.

Cc: Kay Sievers <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/base/base.h | 4 ++++
drivers/base/bus.c | 40 +++++++++++++++++++++++++++-------------
include/linux/device.h | 1 -
3 files changed, 31 insertions(+), 14 deletions(-)

diff --git a/drivers/base/base.h b/drivers/base/base.h
index 4fc5fd3..ddc9749 100644
--- a/drivers/base/base.h
+++ b/drivers/base/base.h
@@ -69,6 +69,7 @@ struct class_private {
* @klist_children - klist containing all children of this device
* @knode_parent - node in sibling list
* @knode_driver - node in driver list
+ * @knode_bus - node in bus list
* @device - pointer back to the struct class that this structure is
* associated with.
*
@@ -78,12 +79,15 @@ struct device_private {
struct klist klist_children;
struct klist_node knode_parent;
struct klist_node knode_driver;
+ struct klist_node knode_bus;
struct device *device;
};
#define to_device_private_parent(obj) \
container_of(obj, struct device_private, knode_parent)
#define to_device_private_driver(obj) \
container_of(obj, struct device_private, knode_driver)
+#define to_device_private_bus(obj) \
+ container_of(obj, struct device_private, knode_bus)

/* initialisation functions */
extern int devices_init(void);
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index 11463c0..dc030f1 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -253,7 +253,14 @@ static ssize_t store_drivers_probe(struct bus_type *bus,
static struct device *next_device(struct klist_iter *i)
{
struct klist_node *n = klist_next(i);
- return n ? container_of(n, struct device, knode_bus) : NULL;
+ struct device *dev = NULL;
+ struct device_private *dev_prv;
+
+ if (n) {
+ dev_prv = to_device_private_bus(n);
+ dev = dev_prv->device;
+ }
+ return dev;
}

/**
@@ -286,7 +293,7 @@ int bus_for_each_dev(struct bus_type *bus, struct device *start,
return -EINVAL;

klist_iter_init_node(&bus->p->klist_devices, &i,
- (start ? &start->knode_bus : NULL));
+ (start ? &start->p->knode_bus : NULL));
while ((dev = next_device(&i)) && !error)
error = fn(dev, data);
klist_iter_exit(&i);
@@ -320,7 +327,7 @@ struct device *bus_find_device(struct bus_type *bus,
return NULL;

klist_iter_init_node(&bus->p->klist_devices, &i,
- (start ? &start->knode_bus : NULL));
+ (start ? &start->p->knode_bus : NULL));
while ((dev = next_device(&i)))
if (match(dev, data) && get_device(dev))
break;
@@ -507,7 +514,8 @@ void bus_attach_device(struct device *dev)
ret = device_attach(dev);
WARN_ON(ret < 0);
if (ret >= 0)
- klist_add_tail(&dev->knode_bus, &bus->p->klist_devices);
+ klist_add_tail(&dev->p->knode_bus,
+ &bus->p->klist_devices);
}
}

@@ -528,8 +536,8 @@ void bus_remove_device(struct device *dev)
sysfs_remove_link(&dev->bus->p->devices_kset->kobj,
dev_name(dev));
device_remove_attrs(dev->bus, dev);
- if (klist_node_attached(&dev->knode_bus))
- klist_del(&dev->knode_bus);
+ if (klist_node_attached(&dev->p->knode_bus))
+ klist_del(&dev->p->knode_bus);

pr_debug("bus: '%s': remove device %s\n",
dev->bus->name, dev_name(dev));
@@ -831,14 +839,16 @@ static void bus_remove_attrs(struct bus_type *bus)

static void klist_devices_get(struct klist_node *n)
{
- struct device *dev = container_of(n, struct device, knode_bus);
+ struct device_private *dev_prv = to_device_private_bus(n);
+ struct device *dev = dev_prv->device;

get_device(dev);
}

static void klist_devices_put(struct klist_node *n)
{
- struct device *dev = container_of(n, struct device, knode_bus);
+ struct device_private *dev_prv = to_device_private_bus(n);
+ struct device *dev = dev_prv->device;

put_device(dev);
}
@@ -995,18 +1005,20 @@ static void device_insertion_sort_klist(struct device *a, struct list_head *list
{
struct list_head *pos;
struct klist_node *n;
+ struct device_private *dev_prv;
struct device *b;

list_for_each(pos, list) {
n = container_of(pos, struct klist_node, n_node);
- b = container_of(n, struct device, knode_bus);
+ dev_prv = to_device_private_bus(n);
+ b = dev_prv->device;
if (compare(a, b) <= 0) {
- list_move_tail(&a->knode_bus.n_node,
- &b->knode_bus.n_node);
+ list_move_tail(&a->p->knode_bus.n_node,
+ &b->p->knode_bus.n_node);
return;
}
}
- list_move_tail(&a->knode_bus.n_node, list);
+ list_move_tail(&a->p->knode_bus.n_node, list);
}

void bus_sort_breadthfirst(struct bus_type *bus,
@@ -1016,6 +1028,7 @@ void bus_sort_breadthfirst(struct bus_type *bus,
LIST_HEAD(sorted_devices);
struct list_head *pos, *tmp;
struct klist_node *n;
+ struct device_private *dev_prv;
struct device *dev;
struct klist *device_klist;

@@ -1024,7 +1037,8 @@ void bus_sort_breadthfirst(struct bus_type *bus,
spin_lock(&device_klist->k_lock);
list_for_each_safe(pos, tmp, &device_klist->k_list) {
n = container_of(pos, struct klist_node, n_node);
- dev = container_of(n, struct device, knode_bus);
+ dev_prv = to_device_private_bus(n);
+ dev = dev_prv->device;
device_insertion_sort_klist(dev, &sorted_devices, compare);
}
list_splice(&sorted_devices, &device_klist->k_list);
diff --git a/include/linux/device.h b/include/linux/device.h
index 83e241f..5a64775 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -368,7 +368,6 @@ struct device_dma_parameters {
};

struct device {
- struct klist_node knode_bus;
struct device *parent;

struct device_private *p;
--
1.6.2

2009-03-25 00:47:38

by Greg KH

[permalink] [raw]
Subject: [PATCH 48/61] sysfs: don't block indefinitely for unmapped files.

From: Eric W. Biederman <[email protected]>

Modify sysfs bin files so that we can remove the bin file while they are
still mapped. When the kobject is removed we unmap the bin file and
arrange for future accesses to the mapping to receive SIGBUS.

Implementing this prevents a nasty DOS when pci devices are hot plugged
and unplugged. Where if any of their resources were mmaped the kernel
could not free up their pci resources or release their pci data
structures.

[[email protected]: remove unused var]
Signed-off-by: Eric W. Biederman <[email protected]>
Cc: Jesse Barnes <[email protected]>
Acked-by: Tejun Heo <[email protected]>
Cc: Kay Sievers <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
fs/sysfs/bin.c | 184 ++++++++++++++++++++++++++++++++++++++++++++++++++----
fs/sysfs/dir.c | 1 +
fs/sysfs/sysfs.h | 2 +
3 files changed, 174 insertions(+), 13 deletions(-)

diff --git a/fs/sysfs/bin.c b/fs/sysfs/bin.c
index f2c478c..96cc2bf 100644
--- a/fs/sysfs/bin.c
+++ b/fs/sysfs/bin.c
@@ -21,15 +21,28 @@
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/mutex.h>
+#include <linux/mm.h>

#include <asm/uaccess.h>

#include "sysfs.h"

+/*
+ * There's one bin_buffer for each open file.
+ *
+ * filp->private_data points to bin_buffer and
+ * sysfs_dirent->s_bin_attr.buffers points to a the bin_buffer s
+ * sysfs_dirent->s_bin_attr.buffers is protected by sysfs_bin_lock
+ */
+static DEFINE_MUTEX(sysfs_bin_lock);
+
struct bin_buffer {
- struct mutex mutex;
- void *buffer;
- int mmapped;
+ struct mutex mutex;
+ void *buffer;
+ int mmapped;
+ struct vm_operations_struct *vm_ops;
+ struct file *file;
+ struct hlist_node list;
};

static int
@@ -168,29 +181,148 @@ out_free:
return count;
}

+static void bin_vma_open(struct vm_area_struct *vma)
+{
+ struct file *file = vma->vm_file;
+ struct bin_buffer *bb = file->private_data;
+ struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
+
+ if (!bb->vm_ops || !bb->vm_ops->open)
+ return;
+
+ if (!sysfs_get_active_two(attr_sd))
+ return;
+
+ bb->vm_ops->open(vma);
+
+ sysfs_put_active_two(attr_sd);
+}
+
+static void bin_vma_close(struct vm_area_struct *vma)
+{
+ struct file *file = vma->vm_file;
+ struct bin_buffer *bb = file->private_data;
+ struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
+
+ if (!bb->vm_ops || !bb->vm_ops->close)
+ return;
+
+ if (!sysfs_get_active_two(attr_sd))
+ return;
+
+ bb->vm_ops->close(vma);
+
+ sysfs_put_active_two(attr_sd);
+}
+
+static int bin_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
+{
+ struct file *file = vma->vm_file;
+ struct bin_buffer *bb = file->private_data;
+ struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
+ int ret;
+
+ if (!bb->vm_ops || !bb->vm_ops->fault)
+ return VM_FAULT_SIGBUS;
+
+ if (!sysfs_get_active_two(attr_sd))
+ return VM_FAULT_SIGBUS;
+
+ ret = bb->vm_ops->fault(vma, vmf);
+
+ sysfs_put_active_two(attr_sd);
+ return ret;
+}
+
+static int bin_page_mkwrite(struct vm_area_struct *vma, struct page *page)
+{
+ struct file *file = vma->vm_file;
+ struct bin_buffer *bb = file->private_data;
+ struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
+ int ret;
+
+ if (!bb->vm_ops || !bb->vm_ops->page_mkwrite)
+ return -EINVAL;
+
+ if (!sysfs_get_active_two(attr_sd))
+ return -EINVAL;
+
+ ret = bb->vm_ops->page_mkwrite(vma, page);
+
+ sysfs_put_active_two(attr_sd);
+ return ret;
+}
+
+static int bin_access(struct vm_area_struct *vma, unsigned long addr,
+ void *buf, int len, int write)
+{
+ struct file *file = vma->vm_file;
+ struct bin_buffer *bb = file->private_data;
+ struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
+ int ret;
+
+ if (!bb->vm_ops || !bb->vm_ops->access)
+ return -EINVAL;
+
+ if (!sysfs_get_active_two(attr_sd))
+ return -EINVAL;
+
+ ret = bb->vm_ops->access(vma, addr, buf, len, write);
+
+ sysfs_put_active_two(attr_sd);
+ return ret;
+}
+
+static struct vm_operations_struct bin_vm_ops = {
+ .open = bin_vma_open,
+ .close = bin_vma_close,
+ .fault = bin_fault,
+ .page_mkwrite = bin_page_mkwrite,
+ .access = bin_access,
+};
+
static int mmap(struct file *file, struct vm_area_struct *vma)
{
struct bin_buffer *bb = file->private_data;
struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
struct bin_attribute *attr = attr_sd->s_bin_attr.bin_attr;
struct kobject *kobj = attr_sd->s_parent->s_dir.kobj;
+ struct vm_operations_struct *vm_ops;
int rc;

mutex_lock(&bb->mutex);

/* need attr_sd for attr, its parent for kobj */
+ rc = -ENODEV;
if (!sysfs_get_active_two(attr_sd))
- return -ENODEV;
+ goto out_unlock;

rc = -EINVAL;
- if (attr->mmap)
- rc = attr->mmap(kobj, attr, vma);
+ if (!attr->mmap)
+ goto out_put;

- if (rc == 0 && !bb->mmapped)
- bb->mmapped = 1;
- else
- sysfs_put_active_two(attr_sd);
+ rc = attr->mmap(kobj, attr, vma);
+ vm_ops = vma->vm_ops;
+ vma->vm_ops = &bin_vm_ops;
+ if (rc)
+ goto out_put;

+ rc = -EINVAL;
+ if (bb->mmapped && bb->vm_ops != vma->vm_ops)
+ goto out_put;
+
+#ifdef CONFIG_NUMA
+ rc = -EINVAL;
+ if (vm_ops && ((vm_ops->set_policy || vm_ops->get_policy || vm_ops->migrate)))
+ goto out_put;
+#endif
+
+ rc = 0;
+ bb->mmapped = 1;
+ bb->vm_ops = vm_ops;
+out_put:
+ sysfs_put_active_two(attr_sd);
+out_unlock:
mutex_unlock(&bb->mutex);

return rc;
@@ -223,8 +355,13 @@ static int open(struct inode * inode, struct file * file)
goto err_out;

mutex_init(&bb->mutex);
+ bb->file = file;
file->private_data = bb;

+ mutex_lock(&sysfs_bin_lock);
+ hlist_add_head(&bb->list, &attr_sd->s_bin_attr.buffers);
+ mutex_unlock(&sysfs_bin_lock);
+
/* open succeeded, put active references */
sysfs_put_active_two(attr_sd);
return 0;
@@ -237,11 +374,12 @@ static int open(struct inode * inode, struct file * file)

static int release(struct inode * inode, struct file * file)
{
- struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
struct bin_buffer *bb = file->private_data;

- if (bb->mmapped)
- sysfs_put_active_two(attr_sd);
+ mutex_lock(&sysfs_bin_lock);
+ hlist_del(&bb->list);
+ mutex_unlock(&sysfs_bin_lock);
+
kfree(bb->buffer);
kfree(bb);
return 0;
@@ -256,6 +394,26 @@ const struct file_operations bin_fops = {
.release = release,
};

+
+void unmap_bin_file(struct sysfs_dirent *attr_sd)
+{
+ struct bin_buffer *bb;
+ struct hlist_node *tmp;
+
+ if (sysfs_type(attr_sd) != SYSFS_KOBJ_BIN_ATTR)
+ return;
+
+ mutex_lock(&sysfs_bin_lock);
+
+ hlist_for_each_entry(bb, tmp, &attr_sd->s_bin_attr.buffers, list) {
+ struct inode *inode = bb->file->f_path.dentry->d_inode;
+
+ unmap_mapping_range(inode->i_mapping, 0, 0, 1);
+ }
+
+ mutex_unlock(&sysfs_bin_lock);
+}
+
/**
* sysfs_create_bin_file - create binary file for object.
* @kobj: object.
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c
index f13d852..66aeb4f 100644
--- a/fs/sysfs/dir.c
+++ b/fs/sysfs/dir.c
@@ -609,6 +609,7 @@ void sysfs_addrm_finish(struct sysfs_addrm_cxt *acxt)

sysfs_drop_dentry(sd);
sysfs_deactivate(sd);
+ unmap_bin_file(sd);
sysfs_put(sd);
}
}
diff --git a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h
index 9055d04..3fa0d98 100644
--- a/fs/sysfs/sysfs.h
+++ b/fs/sysfs/sysfs.h
@@ -28,6 +28,7 @@ struct sysfs_elem_attr {

struct sysfs_elem_bin_attr {
struct bin_attribute *bin_attr;
+ struct hlist_head buffers;
};

/*
@@ -164,6 +165,7 @@ int sysfs_add_file_mode(struct sysfs_dirent *dir_sd,
* bin.c
*/
extern const struct file_operations bin_fops;
+void unmap_bin_file(struct sysfs_dirent *attr_sd);

/*
* symlink.c
--
1.6.2

2009-03-25 00:47:58

by Greg KH

[permalink] [raw]
Subject: [PATCH 49/61] driver core: move platform_data into platform_device

From: Ming Lei <[email protected]>

This patch moves platform_data from struct device into
struct platform_device, based on the two ideas:

1. Now all platform_driver is registered by platform_driver_register,
which makes probe()/release()/... of platform_driver passed parameter
of platform_device *, so platform driver can get platform_data from
platform_device;

2. Other kind of devices do not need to use platform_data, we can
decrease size of device if moving it to platform_device.

Taking into consideration of thousands of files to be fixed and they
can't be finished in one night(maybe it will take a long time), so we
keep platform_data in device to allow two kind of cases coexist until
all platform devices pass its platfrom data from
platform_device->platform_data.

All patches to do this kind of conversion are welcome.

Signed-off-by: Ming Lei <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/base/platform.c | 3 +++
include/linux/device.h | 9 +++++++--
include/linux/platform_device.h | 1 +
3 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index ec993aa..c5ac81d 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -217,6 +217,7 @@ int platform_device_add_data(struct platform_device *pdev, const void *data,
if (d) {
memcpy(d, data, size);
pdev->dev.platform_data = d;
+ pdev->platform_data = d;
}
return d ? 0 : -ENOMEM;
}
@@ -246,6 +247,8 @@ int platform_device_add(struct platform_device *pdev)
else
dev_set_name(&pdev->dev, pdev->name);

+ pdev->platform_data = pdev->dev.platform_data;
+
for (i = 0; i < pdev->num_resources; i++) {
struct resource *p, *r = &pdev->resource[i];

diff --git a/include/linux/device.h b/include/linux/device.h
index 5a64775..4bea53f 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -385,8 +385,13 @@ struct device {
struct device_driver *driver; /* which driver has allocated this
device */
void *driver_data; /* data private to the driver */
- void *platform_data; /* Platform specific data, device
- core doesn't touch it */
+
+ void *platform_data; /* We will remove platform_data
+ field if all platform devices
+ pass its platform specific data
+ from platform_device->platform_data,
+ other kind of devices should not
+ use platform_data. */
struct dev_pm_info power;

#ifdef CONFIG_NUMA
diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h
index 76aef7b..76e470a 100644
--- a/include/linux/platform_device.h
+++ b/include/linux/platform_device.h
@@ -20,6 +20,7 @@ struct platform_device {
struct device dev;
u32 num_resources;
struct resource * resource;
+ void *platform_data;

struct platform_device_id *id_entry;
};
--
1.6.2

2009-03-25 00:48:27

by Greg KH

[permalink] [raw]
Subject: [PATCH 50/61] driver core: fix passing platform_data

From: Ming Lei <[email protected]>

We will remove platform_data field from struct device until
all platform devices pass its specific data from platfom_device
and all platform drivers use platform specific data passed by
platform_device->platform_data. This kind of conversion will
need a long time, for thousands of files is affected.

To make the conversion easily, we allow platform specific data
passed by struct device or struct platform_device and platform
driver may use it from struct device or struct platform_device.

Signed-off-by: Ming Lei <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/base/platform.c | 15 ++++++++++++++-
1 files changed, 14 insertions(+), 1 deletions(-)

diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index c5ac81d..d2198f6 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -247,7 +247,20 @@ int platform_device_add(struct platform_device *pdev)
else
dev_set_name(&pdev->dev, pdev->name);

- pdev->platform_data = pdev->dev.platform_data;
+ /* We will remove platform_data field from struct device
+ * if all platform devices pass its platform specific data
+ * from platform_device. The conversion is going to be a
+ * long time, so we allow the two cases coexist to make
+ * this kind of fix more easily*/
+ if (pdev->platform_data && pdev->dev.platform_data) {
+ printk(KERN_ERR
+ "%s: use which platform_data?\n",
+ dev_name(&pdev->dev));
+ } else if (pdev->platform_data) {
+ pdev->dev.platform_data = pdev->platform_data;
+ } else if (pdev->dev.platform_data) {
+ pdev->platform_data = pdev->dev.platform_data;
+ }

for (i = 0; i < pdev->num_resources; i++) {
struct resource *p, *r = &pdev->resource[i];
--
1.6.2

2009-03-25 00:48:44

by Greg KH

[permalink] [raw]
Subject: [PATCH 51/61] vcs: hook sysfs devices into object lifetime instead of "binding"

From: Kay Sievers <[email protected]>

During bootup performance tracing I noticed many occurrences of
vca* device creation and removal, leading to the usual userspace
uevent processing, which are, in this case, rather pointless.

A simple test showing the kernel timing (not including all the
work userspace has to do), gives us these numbers:
$ time for i in `seq 1000`; do echo a > /dev/tty2; done
real 0m1.142s
user 0m0.015s
sys 0m0.540s

If we move the hook for the vcs* driver core devices from the
tty "binding" to the vc allocation/deallocation, which is what
the vcs* devices represent, we get the following numbers:
$ time for i in `seq 1000`; do echo a > /dev/tty2; done
real 0m0.152s
user 0m0.030s
sys 0m0.072s

Cc: Alan Cox <[email protected]>
Signed-off-by: Kay Sievers <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/char/vc_screen.c | 16 ++++++++--------
drivers/char/vt.c | 5 +++--
include/linux/console.h | 4 ++--
3 files changed, 13 insertions(+), 12 deletions(-)

diff --git a/drivers/char/vc_screen.c b/drivers/char/vc_screen.c
index 4f3b3f9..d94d25c 100644
--- a/drivers/char/vc_screen.c
+++ b/drivers/char/vc_screen.c
@@ -479,18 +479,18 @@ static const struct file_operations vcs_fops = {

static struct class *vc_class;

-void vcs_make_sysfs(struct tty_struct *tty)
+void vcs_make_sysfs(int index)
{
- device_create(vc_class, NULL, MKDEV(VCS_MAJOR, tty->index + 1), NULL,
- "vcs%u", tty->index + 1);
- device_create(vc_class, NULL, MKDEV(VCS_MAJOR, tty->index + 129), NULL,
- "vcsa%u", tty->index + 1);
+ device_create(vc_class, NULL, MKDEV(VCS_MAJOR, index + 1), NULL,
+ "vcs%u", index + 1);
+ device_create(vc_class, NULL, MKDEV(VCS_MAJOR, index + 129), NULL,
+ "vcsa%u", index + 1);
}

-void vcs_remove_sysfs(struct tty_struct *tty)
+void vcs_remove_sysfs(int index)
{
- device_destroy(vc_class, MKDEV(VCS_MAJOR, tty->index + 1));
- device_destroy(vc_class, MKDEV(VCS_MAJOR, tty->index + 129));
+ device_destroy(vc_class, MKDEV(VCS_MAJOR, index + 1));
+ device_destroy(vc_class, MKDEV(VCS_MAJOR, index + 129));
}

int __init vcs_init(void)
diff --git a/drivers/char/vt.c b/drivers/char/vt.c
index 7900bd6..2c1d133 100644
--- a/drivers/char/vt.c
+++ b/drivers/char/vt.c
@@ -778,6 +778,7 @@ int vc_allocate(unsigned int currcons) /* return 0 on success */
}
vc->vc_kmalloced = 1;
vc_init(vc, vc->vc_rows, vc->vc_cols, 1);
+ vcs_make_sysfs(currcons);
atomic_notifier_call_chain(&vt_notifier_list, VT_ALLOCATE, &param);
}
return 0;
@@ -987,7 +988,9 @@ void vc_deallocate(unsigned int currcons)
if (vc_cons_allocated(currcons)) {
struct vc_data *vc = vc_cons[currcons].d;
struct vt_notifier_param param = { .vc = vc };
+
atomic_notifier_call_chain(&vt_notifier_list, VT_DEALLOCATE, &param);
+ vcs_remove_sysfs(currcons);
vc->vc_sw->con_deinit(vc);
put_pid(vc->vt_pid);
module_put(vc->vc_sw->owner);
@@ -2775,7 +2778,6 @@ static int con_open(struct tty_struct *tty, struct file *filp)
tty->termios->c_iflag |= IUTF8;
else
tty->termios->c_iflag &= ~IUTF8;
- vcs_make_sysfs(tty);
release_console_sem();
return ret;
}
@@ -2795,7 +2797,6 @@ static void con_shutdown(struct tty_struct *tty)
BUG_ON(vc == NULL);
acquire_console_sem();
vc->vc_tty = NULL;
- vcs_remove_sysfs(tty);
release_console_sem();
tty_shutdown(tty);
}
diff --git a/include/linux/console.h b/include/linux/console.h
index a67a90c..dcca533 100644
--- a/include/linux/console.h
+++ b/include/linux/console.h
@@ -137,8 +137,8 @@ extern void resume_console(void);
int mda_console_init(void);
void prom_con_init(void);

-void vcs_make_sysfs(struct tty_struct *tty);
-void vcs_remove_sysfs(struct tty_struct *tty);
+void vcs_make_sysfs(int index);
+void vcs_remove_sysfs(int index);

/* Some debug stub to catch some of the obvious races in the VT code */
#if 1
--
1.6.2

2009-03-25 00:49:01

by Greg KH

[permalink] [raw]
Subject: [PATCH 52/61] Driver core: implement uevent suppress in kobject

From: Ming Lei <[email protected]>

This patch implements uevent suppress in kobject and removes it
from struct device, based on the following ideas:

1,Uevent sending should be one attribute of kobject, so suppressing it
in kobject layer is more natural than in device layer. By this way,
we can do it for other objects embedded with kobject.

2,It may save several bytes for each instance of struct device.(On my
omap3(32bit ARM) based box, can save 8bytes per device object)

This patch also introduces dev_set|get_uevent_suppress() helpers to
set and query uevent_suppress attribute in case to help kobject
as private part of struct device in future.

[This version is against the latest driver-core patch set of Greg,please
ignore the last version.]

Signed-off-by: Ming Lei <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/acpi/dock.c | 2 +-
drivers/base/core.c | 2 --
drivers/base/firmware_class.c | 4 ++--
drivers/i2c/i2c-core.c | 2 +-
drivers/s390/cio/chsc_sch.c | 4 ++--
drivers/s390/cio/css.c | 4 ++--
drivers/s390/cio/device.c | 4 ++--
fs/partitions/check.c | 10 +++++-----
include/linux/device.h | 11 ++++++++++-
include/linux/kobject.h | 1 +
lib/kobject_uevent.c | 7 +++++++
11 files changed, 33 insertions(+), 18 deletions(-)

diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c
index 35094f2..7af7db1 100644
--- a/drivers/acpi/dock.c
+++ b/drivers/acpi/dock.c
@@ -977,7 +977,7 @@ static int dock_add(acpi_handle handle)
sizeof(struct dock_station *));

/* we want the dock device to send uevents */
- dock_device->dev.uevent_suppress = 0;
+ dev_set_uevent_suppress(&dock_device->dev, 0);

if (is_dock(handle))
dock_station->flags |= DOCK_IS_DOCK;
diff --git a/drivers/base/core.c b/drivers/base/core.c
index a90f56f..95c67ff 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -136,8 +136,6 @@ static int dev_uevent_filter(struct kset *kset, struct kobject *kobj)

if (ktype == &device_ktype) {
struct device *dev = to_dev(kobj);
- if (dev->uevent_suppress)
- return 0;
if (dev->bus)
return 1;
if (dev->class)
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index 44699d9..d3a59c6 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -319,7 +319,7 @@ static int fw_register_device(struct device **dev_p, const char *fw_name,
f_dev->parent = device;
f_dev->class = &firmware_class;
dev_set_drvdata(f_dev, fw_priv);
- f_dev->uevent_suppress = 1;
+ dev_set_uevent_suppress(f_dev, 1);
retval = device_register(f_dev);
if (retval) {
dev_err(device, "%s: device_register failed\n", __func__);
@@ -366,7 +366,7 @@ static int fw_setup_device(struct firmware *fw, struct device **dev_p,
}

if (uevent)
- f_dev->uevent_suppress = 0;
+ dev_set_uevent_suppress(f_dev, 0);
*dev_p = f_dev;
goto out;

diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index e7d9848..fbb9030 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -841,7 +841,7 @@ int i2c_attach_client(struct i2c_client *client)

if (client->driver && !is_newstyle_driver(client->driver)) {
client->dev.release = i2c_client_release;
- client->dev.uevent_suppress = 1;
+ dev_set_uevent_suppress(&client->dev, 1);
} else
client->dev.release = i2c_client_dev_release;

diff --git a/drivers/s390/cio/chsc_sch.c b/drivers/s390/cio/chsc_sch.c
index 0a2f2ed..93eca17 100644
--- a/drivers/s390/cio/chsc_sch.c
+++ b/drivers/s390/cio/chsc_sch.c
@@ -84,8 +84,8 @@ static int chsc_subchannel_probe(struct subchannel *sch)
kfree(private);
} else {
sch->private = private;
- if (sch->dev.uevent_suppress) {
- sch->dev.uevent_suppress = 0;
+ if (dev_get_uevent_suppress(&sch->dev)) {
+ dev_set_uevent_suppress(&sch->dev, 0);
kobject_uevent(&sch->dev.kobj, KOBJ_ADD);
}
}
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c
index 8019288..427d11d 100644
--- a/drivers/s390/cio/css.c
+++ b/drivers/s390/cio/css.c
@@ -272,7 +272,7 @@ static int css_register_subchannel(struct subchannel *sch)
* the subchannel driver can decide itself when it wants to inform
* userspace of its existence.
*/
- sch->dev.uevent_suppress = 1;
+ dev_set_uevent_suppress(&sch->dev, 1);
css_update_ssd_info(sch);
/* make it known to the system */
ret = css_sch_device_register(sch);
@@ -287,7 +287,7 @@ static int css_register_subchannel(struct subchannel *sch)
* a fitting driver module may be loaded based on the
* modalias.
*/
- sch->dev.uevent_suppress = 0;
+ dev_set_uevent_suppress(&sch->dev, 0);
kobject_uevent(&sch->dev.kobj, KOBJ_ADD);
}
return ret;
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index 23d5752..611d2e0 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -981,7 +981,7 @@ io_subchannel_register(struct work_struct *work)
* Now we know this subchannel will stay, we can throw
* our delayed uevent.
*/
- sch->dev.uevent_suppress = 0;
+ dev_set_uevent_suppress(&sch->dev, 0);
kobject_uevent(&sch->dev.kobj, KOBJ_ADD);
/* make it known to the system */
ret = ccw_device_register(cdev);
@@ -1243,7 +1243,7 @@ static int io_subchannel_probe(struct subchannel *sch)
* the ccw_device and exit. This happens for all early
* devices, e.g. the console.
*/
- sch->dev.uevent_suppress = 0;
+ dev_set_uevent_suppress(&sch->dev, 0);
kobject_uevent(&sch->dev.kobj, KOBJ_ADD);
cdev->dev.groups = ccwdev_attr_groups;
device_initialize(&cdev->dev);
diff --git a/fs/partitions/check.c b/fs/partitions/check.c
index 6d72024..38e337d 100644
--- a/fs/partitions/check.c
+++ b/fs/partitions/check.c
@@ -400,7 +400,7 @@ struct hd_struct *add_partition(struct gendisk *disk, int partno,
pdev->devt = devt;

/* delay uevent until 'holders' subdir is created */
- pdev->uevent_suppress = 1;
+ dev_set_uevent_suppress(pdev, 1);
err = device_add(pdev);
if (err)
goto out_put;
@@ -410,7 +410,7 @@ struct hd_struct *add_partition(struct gendisk *disk, int partno,
if (!p->holder_dir)
goto out_del;

- pdev->uevent_suppress = 0;
+ dev_set_uevent_suppress(pdev, 0);
if (flags & ADDPART_FLAG_WHOLEDISK) {
err = device_create_file(pdev, &dev_attr_whole_disk);
if (err)
@@ -422,7 +422,7 @@ struct hd_struct *add_partition(struct gendisk *disk, int partno,
rcu_assign_pointer(ptbl->part[partno], p);

/* suppress uevent if the disk supresses it */
- if (!ddev->uevent_suppress)
+ if (!dev_get_uevent_suppress(pdev))
kobject_uevent(&pdev->kobj, KOBJ_ADD);

return p;
@@ -455,7 +455,7 @@ void register_disk(struct gendisk *disk)
dev_set_name(ddev, disk->disk_name);

/* delay uevents, until we scanned partition table */
- ddev->uevent_suppress = 1;
+ dev_set_uevent_suppress(ddev, 1);

if (device_add(ddev))
return;
@@ -490,7 +490,7 @@ void register_disk(struct gendisk *disk)

exit:
/* announce disk after possible partitions are created */
- ddev->uevent_suppress = 0;
+ dev_set_uevent_suppress(ddev, 0);
kobject_uevent(&ddev->kobj, KOBJ_ADD);

/* announce possible partitions */
diff --git a/include/linux/device.h b/include/linux/device.h
index 4bea53f..914c101 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -373,7 +373,6 @@ struct device {
struct device_private *p;

struct kobject kobj;
- unsigned uevent_suppress:1;
const char *init_name; /* initial name of the device */
struct device_type *type;

@@ -465,6 +464,16 @@ static inline void dev_set_drvdata(struct device *dev, void *data)
dev->driver_data = data;
}

+static inline unsigned int dev_get_uevent_suppress(const struct device *dev)
+{
+ return dev->kobj.uevent_suppress;
+}
+
+static inline void dev_set_uevent_suppress(struct device *dev, int val)
+{
+ dev->kobj.uevent_suppress = val;
+}
+
static inline int device_is_registered(struct device *dev)
{
return dev->kobj.state_in_sysfs;
diff --git a/include/linux/kobject.h b/include/linux/kobject.h
index c9c214d..58ae8e0 100644
--- a/include/linux/kobject.h
+++ b/include/linux/kobject.h
@@ -68,6 +68,7 @@ struct kobject {
unsigned int state_in_sysfs:1;
unsigned int state_add_uevent_sent:1;
unsigned int state_remove_uevent_sent:1;
+ unsigned int uevent_suppress:1;
};

extern int kobject_set_name(struct kobject *kobj, const char *name, ...)
diff --git a/lib/kobject_uevent.c b/lib/kobject_uevent.c
index 318328d..b2181cc 100644
--- a/lib/kobject_uevent.c
+++ b/lib/kobject_uevent.c
@@ -118,6 +118,13 @@ int kobject_uevent_env(struct kobject *kobj, enum kobject_action action,
kset = top_kobj->kset;
uevent_ops = kset->uevent_ops;

+ /* skip the event, if uevent_suppress is set*/
+ if (kobj->uevent_suppress) {
+ pr_debug("kobject: '%s' (%p): %s: uevent_suppress "
+ "caused the event to drop!\n",
+ kobject_name(kobj), kobj, __func__);
+ return 0;
+ }
/* skip the event, if the filter returns zero. */
if (uevent_ops && uevent_ops->filter)
if (!uevent_ops->filter(kset, kobj)) {
--
1.6.2

2009-03-25 00:49:26

by Greg KH

[permalink] [raw]
Subject: [PATCH 53/61] Driver core: some cleanup on drivers/base/sys.c

From: Zhenwen Xu <[email protected]>

do some cleanup on drivers/base/sys.c


Signed-off-by: Zhenwen Xu <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/base/sys.c | 54 ++++++++++++++++++++++++++--------------------------
1 files changed, 27 insertions(+), 27 deletions(-)

diff --git a/drivers/base/sys.c b/drivers/base/sys.c
index b428c8c..cbd36cf 100644
--- a/drivers/base/sys.c
+++ b/drivers/base/sys.c
@@ -30,10 +30,10 @@


static ssize_t
-sysdev_show(struct kobject * kobj, struct attribute * attr, char * buffer)
+sysdev_show(struct kobject *kobj, struct attribute *attr, char *buffer)
{
- struct sys_device * sysdev = to_sysdev(kobj);
- struct sysdev_attribute * sysdev_attr = to_sysdev_attr(attr);
+ struct sys_device *sysdev = to_sysdev(kobj);
+ struct sysdev_attribute *sysdev_attr = to_sysdev_attr(attr);

if (sysdev_attr->show)
return sysdev_attr->show(sysdev, sysdev_attr, buffer);
@@ -42,11 +42,11 @@ sysdev_show(struct kobject * kobj, struct attribute * attr, char * buffer)


static ssize_t
-sysdev_store(struct kobject * kobj, struct attribute * attr,
- const char * buffer, size_t count)
+sysdev_store(struct kobject *kobj, struct attribute *attr,
+ const char *buffer, size_t count)
{
- struct sys_device * sysdev = to_sysdev(kobj);
- struct sysdev_attribute * sysdev_attr = to_sysdev_attr(attr);
+ struct sys_device *sysdev = to_sysdev(kobj);
+ struct sysdev_attribute *sysdev_attr = to_sysdev_attr(attr);

if (sysdev_attr->store)
return sysdev_attr->store(sysdev, sysdev_attr, buffer, count);
@@ -63,13 +63,13 @@ static struct kobj_type ktype_sysdev = {
};


-int sysdev_create_file(struct sys_device * s, struct sysdev_attribute * a)
+int sysdev_create_file(struct sys_device *s, struct sysdev_attribute *a)
{
return sysfs_create_file(&s->kobj, &a->attr);
}


-void sysdev_remove_file(struct sys_device * s, struct sysdev_attribute * a)
+void sysdev_remove_file(struct sys_device *s, struct sysdev_attribute *a)
{
sysfs_remove_file(&s->kobj, &a->attr);
}
@@ -84,7 +84,7 @@ EXPORT_SYMBOL_GPL(sysdev_remove_file);
static ssize_t sysdev_class_show(struct kobject *kobj, struct attribute *attr,
char *buffer)
{
- struct sysdev_class * class = to_sysdev_class(kobj);
+ struct sysdev_class *class = to_sysdev_class(kobj);
struct sysdev_class_attribute *class_attr = to_sysdev_class_attr(attr);

if (class_attr->show)
@@ -95,8 +95,8 @@ static ssize_t sysdev_class_show(struct kobject *kobj, struct attribute *attr,
static ssize_t sysdev_class_store(struct kobject *kobj, struct attribute *attr,
const char *buffer, size_t count)
{
- struct sysdev_class * class = to_sysdev_class(kobj);
- struct sysdev_class_attribute * class_attr = to_sysdev_class_attr(attr);
+ struct sysdev_class *class = to_sysdev_class(kobj);
+ struct sysdev_class_attribute *class_attr = to_sysdev_class_attr(attr);

if (class_attr->store)
return class_attr->store(class, buffer, count);
@@ -128,7 +128,7 @@ EXPORT_SYMBOL_GPL(sysdev_class_remove_file);

static struct kset *system_kset;

-int sysdev_class_register(struct sysdev_class * cls)
+int sysdev_class_register(struct sysdev_class *cls)
{
pr_debug("Registering sysdev class '%s'\n", cls->name);

@@ -141,7 +141,7 @@ int sysdev_class_register(struct sysdev_class * cls)
return kset_register(&cls->kset);
}

-void sysdev_class_unregister(struct sysdev_class * cls)
+void sysdev_class_unregister(struct sysdev_class *cls)
{
pr_debug("Unregistering sysdev class '%s'\n",
kobject_name(&cls->kset.kobj));
@@ -203,8 +203,8 @@ int sysdev_driver_register(struct sysdev_class *cls, struct sysdev_driver *drv)
* @cls: Class driver belongs to.
* @drv: Driver.
*/
-void sysdev_driver_unregister(struct sysdev_class * cls,
- struct sysdev_driver * drv)
+void sysdev_driver_unregister(struct sysdev_class *cls,
+ struct sysdev_driver *drv)
{
mutex_lock(&sysdev_drivers_lock);
list_del_init(&drv->entry);
@@ -229,10 +229,10 @@ EXPORT_SYMBOL_GPL(sysdev_driver_unregister);
* @sysdev: device in question
*
*/
-int sysdev_register(struct sys_device * sysdev)
+int sysdev_register(struct sys_device *sysdev)
{
int error;
- struct sysdev_class * cls = sysdev->cls;
+ struct sysdev_class *cls = sysdev->cls;

if (!cls)
return -EINVAL;
@@ -252,7 +252,7 @@ int sysdev_register(struct sys_device * sysdev)
sysdev->id);

if (!error) {
- struct sysdev_driver * drv;
+ struct sysdev_driver *drv;

pr_debug("Registering sys device '%s'\n",
kobject_name(&sysdev->kobj));
@@ -274,9 +274,9 @@ int sysdev_register(struct sys_device * sysdev)
return error;
}

-void sysdev_unregister(struct sys_device * sysdev)
+void sysdev_unregister(struct sys_device *sysdev)
{
- struct sysdev_driver * drv;
+ struct sysdev_driver *drv;

mutex_lock(&sysdev_drivers_lock);
list_for_each_entry(drv, &sysdev->cls->drivers, entry) {
@@ -305,19 +305,19 @@ void sysdev_unregister(struct sys_device * sysdev)
*/
void sysdev_shutdown(void)
{
- struct sysdev_class * cls;
+ struct sysdev_class *cls;

pr_debug("Shutting Down System Devices\n");

mutex_lock(&sysdev_drivers_lock);
list_for_each_entry_reverse(cls, &system_kset->list, kset.kobj.entry) {
- struct sys_device * sysdev;
+ struct sys_device *sysdev;

pr_debug("Shutting down type '%s':\n",
kobject_name(&cls->kset.kobj));

list_for_each_entry(sysdev, &cls->kset.list, kobj.entry) {
- struct sysdev_driver * drv;
+ struct sysdev_driver *drv;
pr_debug(" %s\n", kobject_name(&sysdev->kobj));

/* Call auxillary drivers first */
@@ -364,7 +364,7 @@ static void __sysdev_resume(struct sys_device *dev)
*/
int sysdev_suspend(pm_message_t state)
{
- struct sysdev_class * cls;
+ struct sysdev_class *cls;
struct sys_device *sysdev, *err_dev;
struct sysdev_driver *drv, *err_drv;
int ret;
@@ -442,12 +442,12 @@ EXPORT_SYMBOL_GPL(sysdev_suspend);
*/
int sysdev_resume(void)
{
- struct sysdev_class * cls;
+ struct sysdev_class *cls;

pr_debug("Resuming System Devices\n");

list_for_each_entry(cls, &system_kset->list, kset.kobj.entry) {
- struct sys_device * sysdev;
+ struct sys_device *sysdev;

pr_debug("Resuming type '%s':\n",
kobject_name(&cls->kset.kobj));
--
1.6.2

2009-03-25 00:49:43

by Greg KH

[permalink] [raw]
Subject: [PATCH 54/61] Driver core: Fix device_move() vs. dpm list ordering, v2

From: Cornelia Huck <[email protected]>

dpm_list currently relies on the fact that child devices will
be registered after their parents to get a correct suspend
order. Using device_move() however destroys this assumption, as
an already registered device may be moved under a newly registered
one.

This patch adds a new argument to device_move(), allowing callers
to specify how dpm_list should be adapted.

Signed-off-by: Cornelia Huck <[email protected]>
Acked-by: Alan Stern <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/base/core.c | 19 ++++++++++++++++++-
drivers/base/power/main.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
drivers/base/power/power.h | 8 ++++++++
drivers/s390/cio/device.c | 9 +++++----
include/linux/device.h | 3 ++-
include/linux/pm.h | 11 +++++++++++
net/bluetooth/hci_sysfs.c | 2 +-
net/bluetooth/rfcomm/tty.c | 5 +++--
8 files changed, 92 insertions(+), 9 deletions(-)

diff --git a/drivers/base/core.c b/drivers/base/core.c
index 95c67ff..e73c92d 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -1561,8 +1561,10 @@ out:
* device_move - moves a device to a new parent
* @dev: the pointer to the struct device to be moved
* @new_parent: the new parent of the device (can by NULL)
+ * @dpm_order: how to reorder the dpm_list
*/
-int device_move(struct device *dev, struct device *new_parent)
+int device_move(struct device *dev, struct device *new_parent,
+ enum dpm_order dpm_order)
{
int error;
struct device *old_parent;
@@ -1572,6 +1574,7 @@ int device_move(struct device *dev, struct device *new_parent)
if (!dev)
return -EINVAL;

+ device_pm_lock();
new_parent = get_device(new_parent);
new_parent_kobj = get_device_parent(dev, new_parent);

@@ -1613,9 +1616,23 @@ int device_move(struct device *dev, struct device *new_parent)
put_device(new_parent);
goto out;
}
+ switch (dpm_order) {
+ case DPM_ORDER_NONE:
+ break;
+ case DPM_ORDER_DEV_AFTER_PARENT:
+ device_pm_move_after(dev, new_parent);
+ break;
+ case DPM_ORDER_PARENT_BEFORE_DEV:
+ device_pm_move_before(new_parent, dev);
+ break;
+ case DPM_ORDER_DEV_LAST:
+ device_pm_move_last(dev);
+ break;
+ }
out_put:
put_device(old_parent);
out:
+ device_pm_unlock();
put_device(dev);
return error;
}
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index 2d14f4a..e255341 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -107,6 +107,50 @@ void device_pm_remove(struct device *dev)
}

/**
+ * device_pm_move_before - move device in dpm_list
+ * @deva: Device to move in dpm_list
+ * @devb: Device @deva should come before
+ */
+void device_pm_move_before(struct device *deva, struct device *devb)
+{
+ pr_debug("PM: Moving %s:%s before %s:%s\n",
+ deva->bus ? deva->bus->name : "No Bus",
+ kobject_name(&deva->kobj),
+ devb->bus ? devb->bus->name : "No Bus",
+ kobject_name(&devb->kobj));
+ /* Delete deva from dpm_list and reinsert before devb. */
+ list_move_tail(&deva->power.entry, &devb->power.entry);
+}
+
+/**
+ * device_pm_move_after - move device in dpm_list
+ * @deva: Device to move in dpm_list
+ * @devb: Device @deva should come after
+ */
+void device_pm_move_after(struct device *deva, struct device *devb)
+{
+ pr_debug("PM: Moving %s:%s after %s:%s\n",
+ deva->bus ? deva->bus->name : "No Bus",
+ kobject_name(&deva->kobj),
+ devb->bus ? devb->bus->name : "No Bus",
+ kobject_name(&devb->kobj));
+ /* Delete deva from dpm_list and reinsert after devb. */
+ list_move(&deva->power.entry, &devb->power.entry);
+}
+
+/**
+ * device_pm_move_last - move device to end of dpm_list
+ * @dev: Device to move in dpm_list
+ */
+void device_pm_move_last(struct device *dev)
+{
+ pr_debug("PM: Moving %s:%s to end of list\n",
+ dev->bus ? dev->bus->name : "No Bus",
+ kobject_name(&dev->kobj));
+ list_move_tail(&dev->power.entry, &dpm_list);
+}
+
+/**
* pm_op - execute the PM operation appropiate for given PM event
* @dev: Device.
* @ops: PM operations to choose from.
diff --git a/drivers/base/power/power.h b/drivers/base/power/power.h
index 41f51fa..c7cb4fc 100644
--- a/drivers/base/power/power.h
+++ b/drivers/base/power/power.h
@@ -18,11 +18,19 @@ static inline struct device *to_device(struct list_head *entry)

extern void device_pm_add(struct device *);
extern void device_pm_remove(struct device *);
+extern void device_pm_move_before(struct device *, struct device *);
+extern void device_pm_move_after(struct device *, struct device *);
+extern void device_pm_move_last(struct device *);

#else /* CONFIG_PM_SLEEP */

static inline void device_pm_add(struct device *dev) {}
static inline void device_pm_remove(struct device *dev) {}
+static inline void device_pm_move_before(struct device *deva,
+ struct device *devb) {}
+static inline void device_pm_move_after(struct device *deva,
+ struct device *devb) {}
+static inline void device_pm_move_last(struct device *dev) {}

#endif

diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index 611d2e0..e28f8ae 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -799,7 +799,7 @@ static void sch_attach_disconnected_device(struct subchannel *sch,
return;
other_sch = to_subchannel(cdev->dev.parent);
/* Note: device_move() changes cdev->dev.parent */
- ret = device_move(&cdev->dev, &sch->dev);
+ ret = device_move(&cdev->dev, &sch->dev, DPM_ORDER_PARENT_BEFORE_DEV);
if (ret) {
CIO_MSG_EVENT(0, "Moving disconnected device 0.%x.%04x failed "
"(ret=%d)!\n", cdev->private->dev_id.ssid,
@@ -830,7 +830,7 @@ static void sch_attach_orphaned_device(struct subchannel *sch,
* Try to move the ccw device to its new subchannel.
* Note: device_move() changes cdev->dev.parent
*/
- ret = device_move(&cdev->dev, &sch->dev);
+ ret = device_move(&cdev->dev, &sch->dev, DPM_ORDER_PARENT_BEFORE_DEV);
if (ret) {
CIO_MSG_EVENT(0, "Moving device 0.%x.%04x from orphanage "
"failed (ret=%d)!\n",
@@ -897,7 +897,8 @@ void ccw_device_move_to_orphanage(struct work_struct *work)
* ccw device can take its place on the subchannel.
* Note: device_move() changes cdev->dev.parent
*/
- ret = device_move(&cdev->dev, &css->pseudo_subchannel->dev);
+ ret = device_move(&cdev->dev, &css->pseudo_subchannel->dev,
+ DPM_ORDER_NONE);
if (ret) {
CIO_MSG_EVENT(0, "Moving device 0.%x.%04x to orphanage failed "
"(ret=%d)!\n", cdev->private->dev_id.ssid,
@@ -1129,7 +1130,7 @@ static void ccw_device_move_to_sch(struct work_struct *work)
* Try to move the ccw device to its new subchannel.
* Note: device_move() changes cdev->dev.parent
*/
- rc = device_move(&cdev->dev, &sch->dev);
+ rc = device_move(&cdev->dev, &sch->dev, DPM_ORDER_PARENT_BEFORE_DEV);
mutex_unlock(&sch->reg_mutex);
if (rc) {
CIO_MSG_EVENT(0, "Moving device 0.%x.%04x to subchannel "
diff --git a/include/linux/device.h b/include/linux/device.h
index 914c101..f98d0cf 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -494,7 +494,8 @@ extern int device_for_each_child(struct device *dev, void *data,
extern struct device *device_find_child(struct device *dev, void *data,
int (*match)(struct device *dev, void *data));
extern int device_rename(struct device *dev, char *new_name);
-extern int device_move(struct device *dev, struct device *new_parent);
+extern int device_move(struct device *dev, struct device *new_parent,
+ enum dpm_order dpm_order);

/*
* Root device objects for grouping under /sys/devices
diff --git a/include/linux/pm.h b/include/linux/pm.h
index 24ba5f6..1d4e2d2 100644
--- a/include/linux/pm.h
+++ b/include/linux/pm.h
@@ -400,6 +400,9 @@ extern void __suspend_report_result(const char *function, void *fn, int ret);

#else /* !CONFIG_PM_SLEEP */

+#define device_pm_lock() do {} while (0)
+#define device_pm_unlock() do {} while (0)
+
static inline int device_suspend(pm_message_t state)
{
return 0;
@@ -409,6 +412,14 @@ static inline int device_suspend(pm_message_t state)

#endif /* !CONFIG_PM_SLEEP */

+/* How to reorder dpm_list after device_move() */
+enum dpm_order {
+ DPM_ORDER_NONE,
+ DPM_ORDER_DEV_AFTER_PARENT,
+ DPM_ORDER_PARENT_BEFORE_DEV,
+ DPM_ORDER_DEV_LAST,
+};
+
/*
* Global Power Management flags
* Used to keep APM and ACPI from both being active
diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c
index 1a1f916..ed82796 100644
--- a/net/bluetooth/hci_sysfs.c
+++ b/net/bluetooth/hci_sysfs.c
@@ -140,7 +140,7 @@ static void del_conn(struct work_struct *work)
dev = device_find_child(&conn->dev, NULL, __match_tty);
if (!dev)
break;
- device_move(dev, NULL);
+ device_move(dev, NULL, DPM_ORDER_DEV_LAST);
put_device(dev);
}

diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c
index d030c69..abdc703 100644
--- a/net/bluetooth/rfcomm/tty.c
+++ b/net/bluetooth/rfcomm/tty.c
@@ -731,7 +731,8 @@ static int rfcomm_tty_open(struct tty_struct *tty, struct file *filp)
remove_wait_queue(&dev->wait, &wait);

if (err == 0)
- device_move(dev->tty_dev, rfcomm_get_device(dev));
+ device_move(dev->tty_dev, rfcomm_get_device(dev),
+ DPM_ORDER_DEV_AFTER_PARENT);

rfcomm_tty_copy_pending(dev);

@@ -751,7 +752,7 @@ static void rfcomm_tty_close(struct tty_struct *tty, struct file *filp)

if (atomic_dec_and_test(&dev->opened)) {
if (dev->tty_dev->parent)
- device_move(dev->tty_dev, NULL);
+ device_move(dev->tty_dev, NULL, DPM_ORDER_DEV_LAST);

/* Close DLC and dettach TTY */
rfcomm_dlc_close(dev->dlc, 0);
--
1.6.2

2009-03-25 00:50:04

by Greg KH

[permalink] [raw]
Subject: [PATCH 55/61] sysfs: only allow one scheduled removal callback per kobj

From: Alex Chiang <[email protected]>

The only way for a sysfs attribute to remove itself (without
deadlock) is to use the sysfs_schedule_callback() interface.

Vegard Nossum discovered that a poorly written sysfs ->store
callback can repeatedly schedule remove callbacks on the same
device over and over, e.g.

$ while true ; do echo 1 > /sys/devices/.../remove ; done

If the 'remove' attribute uses the sysfs_schedule_callback API
and also does not protect itself from concurrent accesses, its
callback handler will be called multiple times, and will
eventually attempt to perform operations on a freed kobject,
leading to many problems.

Instead of requiring all callers of sysfs_schedule_callback to
implement their own synchronization, provide the protection in
the infrastructure.

Now, sysfs_schedule_callback will only allow one scheduled
callback per kobject. On subsequent calls with the same kobject,
return -EAGAIN.

This is a short term fix. The long term fix is to allow sysfs
attributes to remove themselves directly, without any of this
callback hokey pokey.

[[email protected]: s390 ccwgroup bits]

Reported-by: [email protected]
Signed-off-by: Alex Chiang <[email protected]>
Acked-by: Cornelia Huck <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/s390/cio/ccwgroup.c | 5 +++--
fs/sysfs/file.c | 26 +++++++++++++++++++++++---
2 files changed, 26 insertions(+), 5 deletions(-)

diff --git a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c
index 918e6fc..b91c171 100644
--- a/drivers/s390/cio/ccwgroup.c
+++ b/drivers/s390/cio/ccwgroup.c
@@ -104,8 +104,9 @@ ccwgroup_ungroup_store(struct device *dev, struct device_attribute *attr, const
rc = device_schedule_callback(dev, ccwgroup_ungroup_callback);
out:
if (rc) {
- /* Release onoff "lock" when ungrouping failed. */
- atomic_set(&gdev->onoff, 0);
+ if (rc != -EAGAIN)
+ /* Release onoff "lock" when ungrouping failed. */
+ atomic_set(&gdev->onoff, 0);
return rc;
}
return count;
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
index 1f4a3f8..289c43a 100644
--- a/fs/sysfs/file.c
+++ b/fs/sysfs/file.c
@@ -659,13 +659,16 @@ void sysfs_remove_file_from_group(struct kobject *kobj,
EXPORT_SYMBOL_GPL(sysfs_remove_file_from_group);

struct sysfs_schedule_callback_struct {
- struct kobject *kobj;
+ struct list_head workq_list;
+ struct kobject *kobj;
void (*func)(void *);
void *data;
struct module *owner;
struct work_struct work;
};

+static DEFINE_MUTEX(sysfs_workq_mutex);
+static LIST_HEAD(sysfs_workq);
static void sysfs_schedule_callback_work(struct work_struct *work)
{
struct sysfs_schedule_callback_struct *ss = container_of(work,
@@ -674,6 +677,9 @@ static void sysfs_schedule_callback_work(struct work_struct *work)
(ss->func)(ss->data);
kobject_put(ss->kobj);
module_put(ss->owner);
+ mutex_lock(&sysfs_workq_mutex);
+ list_del(&ss->workq_list);
+ mutex_unlock(&sysfs_workq_mutex);
kfree(ss);
}

@@ -695,15 +701,25 @@ static void sysfs_schedule_callback_work(struct work_struct *work)
* until @func returns.
*
* Returns 0 if the request was submitted, -ENOMEM if storage could not
- * be allocated, -ENODEV if a reference to @owner isn't available.
+ * be allocated, -ENODEV if a reference to @owner isn't available,
+ * -EAGAIN if a callback has already been scheduled for @kobj.
*/
int sysfs_schedule_callback(struct kobject *kobj, void (*func)(void *),
void *data, struct module *owner)
{
- struct sysfs_schedule_callback_struct *ss;
+ struct sysfs_schedule_callback_struct *ss, *tmp;

if (!try_module_get(owner))
return -ENODEV;
+
+ mutex_lock(&sysfs_workq_mutex);
+ list_for_each_entry_safe(ss, tmp, &sysfs_workq, workq_list)
+ if (ss->kobj == kobj) {
+ mutex_unlock(&sysfs_workq_mutex);
+ return -EAGAIN;
+ }
+ mutex_unlock(&sysfs_workq_mutex);
+
ss = kmalloc(sizeof(*ss), GFP_KERNEL);
if (!ss) {
module_put(owner);
@@ -715,6 +731,10 @@ int sysfs_schedule_callback(struct kobject *kobj, void (*func)(void *),
ss->data = data;
ss->owner = owner;
INIT_WORK(&ss->work, sysfs_schedule_callback_work);
+ INIT_LIST_HEAD(&ss->workq_list);
+ mutex_lock(&sysfs_workq_mutex);
+ list_add_tail(&ss->workq_list, &sysfs_workq);
+ mutex_unlock(&sysfs_workq_mutex);
schedule_work(&ss->work);
return 0;
}
--
1.6.2

2009-03-25 00:50:41

by Greg KH

[permalink] [raw]
Subject: [PATCH 56/61] kobject: don't block for each kobject_uevent

From: Arjan van de Ven <[email protected]>

Right now, the kobject_uevent code blocks for each uevent that's being
generated, due to using (for hystoric reasons) UHM_WAIT_EXEC as flag to
call_usermode_helper(). Specifically, the effect is that each uevent
that is being sent causes the code to wake up keventd, then block until
keventd has processed the work. Needless to say, this happens many times
during the system boot.

This patches changes that to UHN_NO_WAIT (brilliant name for a constant
btw) so that we only schedule the work to fire the uevent message, but
do not wait for keventd to process the work.

This removes one of the bottlenecks during boot; each one of them is
only a small effect, but the sum of them does add up.

[Note, distros that need this are broken, they should be setting
CONFIG_UEVENT_HELPER_PATH to "", that way this code path will never be
excuted at all -- gregkh]

Signed-off-by: Arjan van de Ven <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
lib/kobject_uevent.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/lib/kobject_uevent.c b/lib/kobject_uevent.c
index b2181cc..e68e743 100644
--- a/lib/kobject_uevent.c
+++ b/lib/kobject_uevent.c
@@ -255,7 +255,7 @@ int kobject_uevent_env(struct kobject *kobj, enum kobject_action action,
goto exit;

retval = call_usermodehelper(argv[0], argv,
- env->envp, UMH_WAIT_EXEC);
+ env->envp, UMH_NO_WAIT);
}

exit:
--
1.6.2

2009-03-25 00:50:57

by Greg KH

[permalink] [raw]
Subject: [PATCH 57/61] sysfs: fix some bin_vm_ops errors

From: Hugh Dickins <[email protected]>

Commit 86c9508eb1c0ce5aa07b5cf1d36b60c54efc3d7a
"sysfs: don't block indefinitely for unmapped files" in linux-next
crashes the PowerMac G5 when X starts up. It's caught out by the way
powerpc's pci_mmap of legacy_mem uses shmem_zero_setup(), substituting
a new vma->vm_file whose private_data no longer points to the bin_buffer
(substitution done because some versions of X crash if that mmap fails).

The fix to this is straightforward: the original vm_file is fput() in
that case, so this mmap won't block sysfs at all, so just don't switch
over to bin_vm_ops if vm_file has changed.

But more fixes made before realizing that was the problem:-

It should not be an error if bin_page_mkwrite() finds no underlying
page_mkwrite().

Check that a file already mmap'ed has the same underlying vm_ops
_before_ pointing vma->vm_ops at bin_vm_ops.

If the file being mmap'ed is a shmem/tmpfs file, don't fail the mmap
on CONFIG_NUMA=y, just because that has a set_policy and get_policy:
provide bin_set_policy, bin_get_policy and bin_migrate.

Signed-off-by: Hugh Dickins <[email protected]>
Acked-by: Eric Biederman <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
fs/sysfs/bin.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++++------
1 files changed, 79 insertions(+), 10 deletions(-)

diff --git a/fs/sysfs/bin.c b/fs/sysfs/bin.c
index 96cc2bf..07703d3 100644
--- a/fs/sysfs/bin.c
+++ b/fs/sysfs/bin.c
@@ -241,9 +241,12 @@ static int bin_page_mkwrite(struct vm_area_struct *vma, struct page *page)
struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
int ret;

- if (!bb->vm_ops || !bb->vm_ops->page_mkwrite)
+ if (!bb->vm_ops)
return -EINVAL;

+ if (!bb->vm_ops->page_mkwrite)
+ return 0;
+
if (!sysfs_get_active_two(attr_sd))
return -EINVAL;

@@ -273,12 +276,78 @@ static int bin_access(struct vm_area_struct *vma, unsigned long addr,
return ret;
}

+#ifdef CONFIG_NUMA
+static int bin_set_policy(struct vm_area_struct *vma, struct mempolicy *new)
+{
+ struct file *file = vma->vm_file;
+ struct bin_buffer *bb = file->private_data;
+ struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
+ int ret;
+
+ if (!bb->vm_ops || !bb->vm_ops->set_policy)
+ return 0;
+
+ if (!sysfs_get_active_two(attr_sd))
+ return -EINVAL;
+
+ ret = bb->vm_ops->set_policy(vma, new);
+
+ sysfs_put_active_two(attr_sd);
+ return ret;
+}
+
+static struct mempolicy *bin_get_policy(struct vm_area_struct *vma,
+ unsigned long addr)
+{
+ struct file *file = vma->vm_file;
+ struct bin_buffer *bb = file->private_data;
+ struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
+ struct mempolicy *pol;
+
+ if (!bb->vm_ops || !bb->vm_ops->get_policy)
+ return vma->vm_policy;
+
+ if (!sysfs_get_active_two(attr_sd))
+ return vma->vm_policy;
+
+ pol = bb->vm_ops->get_policy(vma, addr);
+
+ sysfs_put_active_two(attr_sd);
+ return pol;
+}
+
+static int bin_migrate(struct vm_area_struct *vma, const nodemask_t *from,
+ const nodemask_t *to, unsigned long flags)
+{
+ struct file *file = vma->vm_file;
+ struct bin_buffer *bb = file->private_data;
+ struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
+ int ret;
+
+ if (!bb->vm_ops || !bb->vm_ops->migrate)
+ return 0;
+
+ if (!sysfs_get_active_two(attr_sd))
+ return 0;
+
+ ret = bb->vm_ops->migrate(vma, from, to, flags);
+
+ sysfs_put_active_two(attr_sd);
+ return ret;
+}
+#endif
+
static struct vm_operations_struct bin_vm_ops = {
.open = bin_vma_open,
.close = bin_vma_close,
.fault = bin_fault,
.page_mkwrite = bin_page_mkwrite,
.access = bin_access,
+#ifdef CONFIG_NUMA
+ .set_policy = bin_set_policy,
+ .get_policy = bin_get_policy,
+ .migrate = bin_migrate,
+#endif
};

static int mmap(struct file *file, struct vm_area_struct *vma)
@@ -287,7 +356,6 @@ static int mmap(struct file *file, struct vm_area_struct *vma)
struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
struct bin_attribute *attr = attr_sd->s_bin_attr.bin_attr;
struct kobject *kobj = attr_sd->s_parent->s_dir.kobj;
- struct vm_operations_struct *vm_ops;
int rc;

mutex_lock(&bb->mutex);
@@ -302,24 +370,25 @@ static int mmap(struct file *file, struct vm_area_struct *vma)
goto out_put;

rc = attr->mmap(kobj, attr, vma);
- vm_ops = vma->vm_ops;
- vma->vm_ops = &bin_vm_ops;
if (rc)
goto out_put;

- rc = -EINVAL;
- if (bb->mmapped && bb->vm_ops != vma->vm_ops)
+ /*
+ * PowerPC's pci_mmap of legacy_mem uses shmem_zero_setup()
+ * to satisfy versions of X which crash if the mmap fails: that
+ * substitutes a new vm_file, and we don't then want bin_vm_ops.
+ */
+ if (vma->vm_file != file)
goto out_put;

-#ifdef CONFIG_NUMA
rc = -EINVAL;
- if (vm_ops && ((vm_ops->set_policy || vm_ops->get_policy || vm_ops->migrate)))
+ if (bb->mmapped && bb->vm_ops != vma->vm_ops)
goto out_put;
-#endif

rc = 0;
bb->mmapped = 1;
- bb->vm_ops = vm_ops;
+ bb->vm_ops = vma->vm_ops;
+ vma->vm_ops = &bin_vm_ops;
out_put:
sysfs_put_active_two(attr_sd);
out_unlock:
--
1.6.2

2009-03-25 00:51:23

by Greg KH

[permalink] [raw]
Subject: [PATCH 58/61] dynamic debug: combine dprintk and dynamic printk

From: Jason Baron <[email protected]>

This patch combines Greg Bank's dprintk() work with the existing dynamic
printk patchset, we are now calling it 'dynamic debug'.

The new feature of this patchset is a richer /debugfs control file interface,
(an example output from my system is at the bottom), which allows fined grained
control over the the debug output. The output can be controlled by function,
file, module, format string, and line number.

for example, enabled all debug messages in module 'nf_conntrack':

echo -n 'module nf_conntrack +p' > /mnt/debugfs/dynamic_debug/control

to disable them:

echo -n 'module nf_conntrack -p' > /mnt/debugfs/dynamic_debug/control

A further explanation can be found in the documentation patch.

Signed-off-by: Greg Banks <[email protected]>
Signed-off-by: Jason Baron <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
Documentation/kernel-parameters.txt | 5 -
include/asm-generic/vmlinux.lds.h | 15 +-
include/linux/device.h | 2 +-
include/linux/dynamic_debug.h | 88 ++++
include/linux/dynamic_printk.h | 93 -----
include/linux/kernel.h | 4 +-
kernel/module.c | 25 +-
lib/Kconfig.debug | 2 +-
lib/Makefile | 2 +-
lib/dynamic_debug.c | 756 +++++++++++++++++++++++++++++++++++
lib/dynamic_printk.c | 414 -------------------
net/netfilter/nf_conntrack_pptp.c | 2 +-
scripts/Makefile.lib | 2 +-
13 files changed, 867 insertions(+), 543 deletions(-)
create mode 100644 include/linux/dynamic_debug.h
delete mode 100644 include/linux/dynamic_printk.h
create mode 100644 lib/dynamic_debug.c
delete mode 100644 lib/dynamic_printk.c

diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 54f21a5..3a1aa8a 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -1816,11 +1816,6 @@ and is between 256 and 4096 characters. It is defined in the file
autoconfiguration.
Ranges are in pairs (memory base and size).

- dynamic_printk Enables pr_debug()/dev_dbg() calls if
- CONFIG_DYNAMIC_PRINTK_DEBUG has been enabled.
- These can also be switched on/off via
- <debugfs>/dynamic_printk/modules
-
print-fatal-signals=
[KNL] debug: print fatal signals
print-fatal-signals=1: print segfault info to
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index c61fab1..aca40b9 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -80,6 +80,11 @@
VMLINUX_SYMBOL(__start___tracepoints) = .; \
*(__tracepoints) \
VMLINUX_SYMBOL(__stop___tracepoints) = .; \
+ /* implement dynamic printk debug */ \
+ . = ALIGN(8); \
+ VMLINUX_SYMBOL(__start___verbose) = .; \
+ *(__verbose) \
+ VMLINUX_SYMBOL(__stop___verbose) = .; \
LIKELY_PROFILE() \
BRANCH_PROFILE()

@@ -309,15 +314,7 @@
CPU_DISCARD(init.data) \
CPU_DISCARD(init.rodata) \
MEM_DISCARD(init.data) \
- MEM_DISCARD(init.rodata) \
- /* implement dynamic printk debug */ \
- VMLINUX_SYMBOL(__start___verbose_strings) = .; \
- *(__verbose_strings) \
- VMLINUX_SYMBOL(__stop___verbose_strings) = .; \
- . = ALIGN(8); \
- VMLINUX_SYMBOL(__start___verbose) = .; \
- *(__verbose) \
- VMLINUX_SYMBOL(__stop___verbose) = .;
+ MEM_DISCARD(init.rodata)

#define INIT_TEXT \
*(.init.text) \
diff --git a/include/linux/device.h b/include/linux/device.h
index f98d0cf..2918c0e 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -582,7 +582,7 @@ extern const char *dev_driver_string(const struct device *dev);
#if defined(DEBUG)
#define dev_dbg(dev, format, arg...) \
dev_printk(KERN_DEBUG , dev , format , ## arg)
-#elif defined(CONFIG_DYNAMIC_PRINTK_DEBUG)
+#elif defined(CONFIG_DYNAMIC_DEBUG)
#define dev_dbg(dev, format, ...) do { \
dynamic_dev_dbg(dev, format, ##__VA_ARGS__); \
} while (0)
diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h
new file mode 100644
index 0000000..07781aa
--- /dev/null
+++ b/include/linux/dynamic_debug.h
@@ -0,0 +1,88 @@
+#ifndef _DYNAMIC_DEBUG_H
+#define _DYNAMIC_DEBUG_H
+
+/* dynamic_printk_enabled, and dynamic_printk_enabled2 are bitmasks in which
+ * bit n is set to 1 if any modname hashes into the bucket n, 0 otherwise. They
+ * use independent hash functions, to reduce the chance of false positives.
+ */
+extern long long dynamic_debug_enabled;
+extern long long dynamic_debug_enabled2;
+
+/*
+ * An instance of this structure is created in a special
+ * ELF section at every dynamic debug callsite. At runtime,
+ * the special section is treated as an array of these.
+ */
+struct _ddebug {
+ /*
+ * These fields are used to drive the user interface
+ * for selecting and displaying debug callsites.
+ */
+ const char *modname;
+ const char *function;
+ const char *filename;
+ const char *format;
+ char primary_hash;
+ char secondary_hash;
+ unsigned int lineno:24;
+ /*
+ * The flags field controls the behaviour at the callsite.
+ * The bits here are changed dynamically when the user
+ * writes commands to <debugfs>/dynamic_debug/ddebug
+ */
+#define _DPRINTK_FLAGS_PRINT (1<<0) /* printk() a message using the format */
+#define _DPRINTK_FLAGS_DEFAULT 0
+ unsigned int flags:8;
+} __attribute__((aligned(8)));
+
+
+int ddebug_add_module(struct _ddebug *tab, unsigned int n,
+ const char *modname);
+
+#if defined(CONFIG_DYNAMIC_DEBUG)
+extern int ddebug_remove_module(char *mod_name);
+
+#define __dynamic_dbg_enabled(dd) ({ \
+ int __ret = 0; \
+ if (unlikely((dynamic_debug_enabled & (1LL << DEBUG_HASH)) && \
+ (dynamic_debug_enabled2 & (1LL << DEBUG_HASH2)))) \
+ if (unlikely(dd.flags)) \
+ __ret = 1; \
+ __ret; })
+
+#define dynamic_pr_debug(fmt, ...) do { \
+ static struct _ddebug descriptor \
+ __used \
+ __attribute__((section("__verbose"), aligned(8))) = \
+ { KBUILD_MODNAME, __func__, __FILE__, fmt, DEBUG_HASH, \
+ DEBUG_HASH2, __LINE__, _DPRINTK_FLAGS_DEFAULT }; \
+ if (__dynamic_dbg_enabled(descriptor)) \
+ printk(KERN_DEBUG KBUILD_MODNAME ":" fmt, \
+ ##__VA_ARGS__); \
+ } while (0)
+
+
+#define dynamic_dev_dbg(dev, fmt, ...) do { \
+ static struct _ddebug descriptor \
+ __used \
+ __attribute__((section("__verbose"), aligned(8))) = \
+ { KBUILD_MODNAME, __func__, __FILE__, fmt, DEBUG_HASH, \
+ DEBUG_HASH2, __LINE__, _DPRINTK_FLAGS_DEFAULT }; \
+ if (__dynamic_dbg_enabled(descriptor)) \
+ dev_printk(KERN_DEBUG, dev, \
+ KBUILD_MODNAME ": " fmt, \
+ ##__VA_ARGS__); \
+ } while (0)
+
+#else
+
+static inline int ddebug_remove_module(char *mod)
+{
+ return 0;
+}
+
+#define dynamic_pr_debug(fmt, ...) do { } while (0)
+#define dynamic_dev_dbg(dev, format, ...) do { } while (0)
+#endif
+
+#endif
diff --git a/include/linux/dynamic_printk.h b/include/linux/dynamic_printk.h
deleted file mode 100644
index 2d528d0..0000000
--- a/include/linux/dynamic_printk.h
+++ /dev/null
@@ -1,93 +0,0 @@
-#ifndef _DYNAMIC_PRINTK_H
-#define _DYNAMIC_PRINTK_H
-
-#define DYNAMIC_DEBUG_HASH_BITS 6
-#define DEBUG_HASH_TABLE_SIZE (1 << DYNAMIC_DEBUG_HASH_BITS)
-
-#define TYPE_BOOLEAN 1
-
-#define DYNAMIC_ENABLED_ALL 0
-#define DYNAMIC_ENABLED_NONE 1
-#define DYNAMIC_ENABLED_SOME 2
-
-extern int dynamic_enabled;
-
-/* dynamic_printk_enabled, and dynamic_printk_enabled2 are bitmasks in which
- * bit n is set to 1 if any modname hashes into the bucket n, 0 otherwise. They
- * use independent hash functions, to reduce the chance of false positives.
- */
-extern long long dynamic_printk_enabled;
-extern long long dynamic_printk_enabled2;
-
-struct mod_debug {
- char *modname;
- char *logical_modname;
- char *flag_names;
- int type;
- int hash;
- int hash2;
-} __attribute__((aligned(8)));
-
-int register_dynamic_debug_module(char *mod_name, int type, char *share_name,
- char *flags, int hash, int hash2);
-
-#if defined(CONFIG_DYNAMIC_PRINTK_DEBUG)
-extern int unregister_dynamic_debug_module(char *mod_name);
-extern int __dynamic_dbg_enabled_helper(char *modname, int type,
- int value, int hash);
-
-#define __dynamic_dbg_enabled(module, type, value, level, hash) ({ \
- int __ret = 0; \
- if (unlikely((dynamic_printk_enabled & (1LL << DEBUG_HASH)) && \
- (dynamic_printk_enabled2 & (1LL << DEBUG_HASH2)))) \
- __ret = __dynamic_dbg_enabled_helper(module, type, \
- value, hash);\
- __ret; })
-
-#define dynamic_pr_debug(fmt, ...) do { \
- static char mod_name[] \
- __attribute__((section("__verbose_strings"))) \
- = KBUILD_MODNAME; \
- static struct mod_debug descriptor \
- __used \
- __attribute__((section("__verbose"), aligned(8))) = \
- { mod_name, mod_name, NULL, TYPE_BOOLEAN, DEBUG_HASH, DEBUG_HASH2 };\
- if (__dynamic_dbg_enabled(KBUILD_MODNAME, TYPE_BOOLEAN, \
- 0, 0, DEBUG_HASH)) \
- printk(KERN_DEBUG KBUILD_MODNAME ":" fmt, \
- ##__VA_ARGS__); \
- } while (0)
-
-#define dynamic_dev_dbg(dev, format, ...) do { \
- static char mod_name[] \
- __attribute__((section("__verbose_strings"))) \
- = KBUILD_MODNAME; \
- static struct mod_debug descriptor \
- __used \
- __attribute__((section("__verbose"), aligned(8))) = \
- { mod_name, mod_name, NULL, TYPE_BOOLEAN, DEBUG_HASH, DEBUG_HASH2 };\
- if (__dynamic_dbg_enabled(KBUILD_MODNAME, TYPE_BOOLEAN, \
- 0, 0, DEBUG_HASH)) \
- dev_printk(KERN_DEBUG, dev, \
- KBUILD_MODNAME ": " format, \
- ##__VA_ARGS__); \
- } while (0)
-
-#else
-
-static inline int unregister_dynamic_debug_module(const char *mod_name)
-{
- return 0;
-}
-static inline int __dynamic_dbg_enabled_helper(char *modname, int type,
- int value, int hash)
-{
- return 0;
-}
-
-#define __dynamic_dbg_enabled(module, type, value, level, hash) ({ 0; })
-#define dynamic_pr_debug(fmt, ...) do { } while (0)
-#define dynamic_dev_dbg(dev, format, ...) do { } while (0)
-#endif
-
-#endif
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index 7fa3718..b5496ec 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -16,7 +16,7 @@
#include <linux/log2.h>
#include <linux/typecheck.h>
#include <linux/ratelimit.h>
-#include <linux/dynamic_printk.h>
+#include <linux/dynamic_debug.h>
#include <asm/byteorder.h>
#include <asm/bug.h>

@@ -358,7 +358,7 @@ static inline char *pack_hex_byte(char *buf, u8 byte)
#if defined(DEBUG)
#define pr_debug(fmt, ...) \
printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
-#elif defined(CONFIG_DYNAMIC_PRINTK_DEBUG)
+#elif defined(CONFIG_DYNAMIC_DEBUG)
#define pr_debug(fmt, ...) do { \
dynamic_pr_debug(pr_fmt(fmt), ##__VA_ARGS__); \
} while (0)
diff --git a/kernel/module.c b/kernel/module.c
index 1196f5d..7767223 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -822,7 +822,7 @@ SYSCALL_DEFINE2(delete_module, const char __user *, name_user,
mutex_lock(&module_mutex);
/* Store the name of the last unloaded module for diagnostic purposes */
strlcpy(last_unloaded_module, mod->name, sizeof(last_unloaded_module));
- unregister_dynamic_debug_module(mod->name);
+ ddebug_remove_module(mod->name);
free_module(mod);

out:
@@ -1827,19 +1827,13 @@ static inline void add_kallsyms(struct module *mod,
}
#endif /* CONFIG_KALLSYMS */

-static void dynamic_printk_setup(struct mod_debug *debug, unsigned int num)
+static void dynamic_debug_setup(struct _ddebug *debug, unsigned int num)
{
-#ifdef CONFIG_DYNAMIC_PRINTK_DEBUG
- unsigned int i;
-
- for (i = 0; i < num; i++) {
- register_dynamic_debug_module(debug[i].modname,
- debug[i].type,
- debug[i].logical_modname,
- debug[i].flag_names,
- debug[i].hash, debug[i].hash2);
- }
-#endif /* CONFIG_DYNAMIC_PRINTK_DEBUG */
+#ifdef CONFIG_DYNAMIC_DEBUG
+ if (ddebug_add_module(debug, num, debug->modname))
+ printk(KERN_ERR "dynamic debug error adding module: %s\n",
+ debug->modname);
+#endif
}

static void *module_alloc_update_bounds(unsigned long size)
@@ -2213,12 +2207,13 @@ static noinline struct module *load_module(void __user *umod,
add_kallsyms(mod, sechdrs, symindex, strindex, secstrings);

if (!mod->taints) {
- struct mod_debug *debug;
+ struct _ddebug *debug;
unsigned int num_debug;

debug = section_objs(hdr, sechdrs, secstrings, "__verbose",
sizeof(*debug), &num_debug);
- dynamic_printk_setup(debug, num_debug);
+ if (debug)
+ dynamic_debug_setup(debug, num_debug);
}

/* sechdrs[0].sh_size is always zero */
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 1bcf9cd..0dd1c04 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -847,7 +847,7 @@ config BUILD_DOCSRC

Say N if you are unsure.

-config DYNAMIC_PRINTK_DEBUG
+config DYNAMIC_DEBUG
bool "Enable dynamic printk() call support"
default n
depends on PRINTK
diff --git a/lib/Makefile b/lib/Makefile
index 32b0e64..8633d6b 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -82,7 +82,7 @@ obj-$(CONFIG_HAVE_LMB) += lmb.o

obj-$(CONFIG_HAVE_ARCH_TRACEHOOK) += syscall.o

-obj-$(CONFIG_DYNAMIC_PRINTK_DEBUG) += dynamic_printk.o
+obj-$(CONFIG_DYNAMIC_DEBUG) += dynamic_debug.o

hostprogs-y := gen_crc32table
clean-files := crc32table.h
diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
new file mode 100644
index 0000000..9e123ae
--- /dev/null
+++ b/lib/dynamic_debug.c
@@ -0,0 +1,756 @@
+/*
+ * lib/dynamic_debug.c
+ *
+ * make pr_debug()/dev_dbg() calls runtime configurable based upon their
+ * source module.
+ *
+ * Copyright (C) 2008 Jason Baron <[email protected]>
+ * By Greg Banks <[email protected]>
+ * Copyright (c) 2008 Silicon Graphics Inc. All Rights Reserved.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/kallsyms.h>
+#include <linux/version.h>
+#include <linux/types.h>
+#include <linux/mutex.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include <linux/list.h>
+#include <linux/sysctl.h>
+#include <linux/ctype.h>
+#include <linux/uaccess.h>
+#include <linux/dynamic_debug.h>
+#include <linux/debugfs.h>
+
+extern struct _ddebug __start___verbose[];
+extern struct _ddebug __stop___verbose[];
+
+/* dynamic_debug_enabled, and dynamic_debug_enabled2 are bitmasks in which
+ * bit n is set to 1 if any modname hashes into the bucket n, 0 otherwise. They
+ * use independent hash functions, to reduce the chance of false positives.
+ */
+long long dynamic_debug_enabled;
+EXPORT_SYMBOL_GPL(dynamic_debug_enabled);
+long long dynamic_debug_enabled2;
+EXPORT_SYMBOL_GPL(dynamic_debug_enabled2);
+
+struct ddebug_table {
+ struct list_head link;
+ char *mod_name;
+ unsigned int num_ddebugs;
+ unsigned int num_enabled;
+ struct _ddebug *ddebugs;
+};
+
+struct ddebug_query {
+ const char *filename;
+ const char *module;
+ const char *function;
+ const char *format;
+ unsigned int first_lineno, last_lineno;
+};
+
+struct ddebug_iter {
+ struct ddebug_table *table;
+ unsigned int idx;
+};
+
+static DEFINE_MUTEX(ddebug_lock);
+static LIST_HEAD(ddebug_tables);
+static int verbose = 0;
+
+/* Return the last part of a pathname */
+static inline const char *basename(const char *path)
+{
+ const char *tail = strrchr(path, '/');
+ return tail ? tail+1 : path;
+}
+
+/* format a string into buf[] which describes the _ddebug's flags */
+static char *ddebug_describe_flags(struct _ddebug *dp, char *buf,
+ size_t maxlen)
+{
+ char *p = buf;
+
+ BUG_ON(maxlen < 4);
+ if (dp->flags & _DPRINTK_FLAGS_PRINT)
+ *p++ = 'p';
+ if (p == buf)
+ *p++ = '-';
+ *p = '\0';
+
+ return buf;
+}
+
+/*
+ * must be called with ddebug_lock held
+ */
+
+static int disabled_hash(char hash, bool first_table)
+{
+ struct ddebug_table *dt;
+ char table_hash_value;
+
+ list_for_each_entry(dt, &ddebug_tables, link) {
+ if (first_table)
+ table_hash_value = dt->ddebugs->primary_hash;
+ else
+ table_hash_value = dt->ddebugs->secondary_hash;
+ if (dt->num_enabled && (hash == table_hash_value))
+ return 0;
+ }
+ return 1;
+}
+
+/*
+ * Search the tables for _ddebug's which match the given
+ * `query' and apply the `flags' and `mask' to them. Tells
+ * the user which ddebug's were changed, or whether none
+ * were matched.
+ */
+static void ddebug_change(const struct ddebug_query *query,
+ unsigned int flags, unsigned int mask)
+{
+ int i;
+ struct ddebug_table *dt;
+ unsigned int newflags;
+ unsigned int nfound = 0;
+ char flagbuf[8];
+
+ /* search for matching ddebugs */
+ mutex_lock(&ddebug_lock);
+ list_for_each_entry(dt, &ddebug_tables, link) {
+
+ /* match against the module name */
+ if (query->module != NULL &&
+ strcmp(query->module, dt->mod_name))
+ continue;
+
+ for (i = 0 ; i < dt->num_ddebugs ; i++) {
+ struct _ddebug *dp = &dt->ddebugs[i];
+
+ /* match against the source filename */
+ if (query->filename != NULL &&
+ strcmp(query->filename, dp->filename) &&
+ strcmp(query->filename, basename(dp->filename)))
+ continue;
+
+ /* match against the function */
+ if (query->function != NULL &&
+ strcmp(query->function, dp->function))
+ continue;
+
+ /* match against the format */
+ if (query->format != NULL &&
+ strstr(dp->format, query->format) == NULL)
+ continue;
+
+ /* match against the line number range */
+ if (query->first_lineno &&
+ dp->lineno < query->first_lineno)
+ continue;
+ if (query->last_lineno &&
+ dp->lineno > query->last_lineno)
+ continue;
+
+ nfound++;
+
+ newflags = (dp->flags & mask) | flags;
+ if (newflags == dp->flags)
+ continue;
+
+ if (!newflags)
+ dt->num_enabled--;
+ else if (!dp-flags)
+ dt->num_enabled++;
+ dp->flags = newflags;
+ if (newflags) {
+ dynamic_debug_enabled |=
+ (1LL << dp->primary_hash);
+ dynamic_debug_enabled2 |=
+ (1LL << dp->secondary_hash);
+ } else {
+ if (disabled_hash(dp->primary_hash, true))
+ dynamic_debug_enabled &=
+ ~(1LL << dp->primary_hash);
+ if (disabled_hash(dp->secondary_hash, false))
+ dynamic_debug_enabled2 &=
+ ~(1LL << dp->secondary_hash);
+ }
+ if (verbose)
+ printk(KERN_INFO
+ "ddebug: changed %s:%d [%s]%s %s\n",
+ dp->filename, dp->lineno,
+ dt->mod_name, dp->function,
+ ddebug_describe_flags(dp, flagbuf,
+ sizeof(flagbuf)));
+ }
+ }
+ mutex_unlock(&ddebug_lock);
+
+ if (!nfound && verbose)
+ printk(KERN_INFO "ddebug: no matches for query\n");
+}
+
+/*
+ * Wrapper around strsep() to collapse the multiple empty tokens
+ * that it returns when fed sequences of separator characters.
+ * Now, if we had strtok_r()...
+ */
+static inline char *nearly_strtok_r(char **p, const char *sep)
+{
+ char *r;
+
+ while ((r = strsep(p, sep)) != NULL && *r == '\0')
+ ;
+ return r;
+}
+
+/*
+ * Split the buffer `buf' into space-separated words.
+ * Return the number of such words or <0 on error.
+ */
+static int ddebug_tokenize(char *buf, char *words[], int maxwords)
+{
+ int nwords = 0;
+
+ while (nwords < maxwords &&
+ (words[nwords] = nearly_strtok_r(&buf, " \t\r\n")) != NULL)
+ nwords++;
+ if (buf)
+ return -EINVAL; /* ran out of words[] before bytes */
+
+ if (verbose) {
+ int i;
+ printk(KERN_INFO "%s: split into words:", __func__);
+ for (i = 0 ; i < nwords ; i++)
+ printk(" \"%s\"", words[i]);
+ printk("\n");
+ }
+
+ return nwords;
+}
+
+/*
+ * Parse a single line number. Note that the empty string ""
+ * is treated as a special case and converted to zero, which
+ * is later treated as a "don't care" value.
+ */
+static inline int parse_lineno(const char *str, unsigned int *val)
+{
+ char *end = NULL;
+ BUG_ON(str == NULL);
+ if (*str == '\0') {
+ *val = 0;
+ return 0;
+ }
+ *val = simple_strtoul(str, &end, 10);
+ return end == NULL || end == str || *end != '\0' ? -EINVAL : 0;
+}
+
+/*
+ * Undo octal escaping in a string, inplace. This is useful to
+ * allow the user to express a query which matches a format
+ * containing embedded spaces.
+ */
+#define isodigit(c) ((c) >= '0' && (c) <= '7')
+static char *unescape(char *str)
+{
+ char *in = str;
+ char *out = str;
+
+ while (*in) {
+ if (*in == '\\') {
+ if (in[1] == '\\') {
+ *out++ = '\\';
+ in += 2;
+ continue;
+ } else if (in[1] == 't') {
+ *out++ = '\t';
+ in += 2;
+ continue;
+ } else if (in[1] == 'n') {
+ *out++ = '\n';
+ in += 2;
+ continue;
+ } else if (isodigit(in[1]) &&
+ isodigit(in[2]) &&
+ isodigit(in[3])) {
+ *out++ = ((in[1] - '0')<<6) |
+ ((in[2] - '0')<<3) |
+ (in[3] - '0');
+ in += 4;
+ continue;
+ }
+ }
+ *out++ = *in++;
+ }
+ *out = '\0';
+
+ return str;
+}
+
+/*
+ * Parse words[] as a ddebug query specification, which is a series
+ * of (keyword, value) pairs chosen from these possibilities:
+ *
+ * func <function-name>
+ * file <full-pathname>
+ * file <base-filename>
+ * module <module-name>
+ * format <escaped-string-to-find-in-format>
+ * line <lineno>
+ * line <first-lineno>-<last-lineno> // where either may be empty
+ */
+static int ddebug_parse_query(char *words[], int nwords,
+ struct ddebug_query *query)
+{
+ unsigned int i;
+
+ /* check we have an even number of words */
+ if (nwords % 2 != 0)
+ return -EINVAL;
+ memset(query, 0, sizeof(*query));
+
+ for (i = 0 ; i < nwords ; i += 2) {
+ if (!strcmp(words[i], "func"))
+ query->function = words[i+1];
+ else if (!strcmp(words[i], "file"))
+ query->filename = words[i+1];
+ else if (!strcmp(words[i], "module"))
+ query->module = words[i+1];
+ else if (!strcmp(words[i], "format"))
+ query->format = unescape(words[i+1]);
+ else if (!strcmp(words[i], "line")) {
+ char *first = words[i+1];
+ char *last = strchr(first, '-');
+ if (last)
+ *last++ = '\0';
+ if (parse_lineno(first, &query->first_lineno) < 0)
+ return -EINVAL;
+ if (last != NULL) {
+ /* range <first>-<last> */
+ if (parse_lineno(last, &query->last_lineno) < 0)
+ return -EINVAL;
+ } else {
+ query->last_lineno = query->first_lineno;
+ }
+ } else {
+ if (verbose)
+ printk(KERN_ERR "%s: unknown keyword \"%s\"\n",
+ __func__, words[i]);
+ return -EINVAL;
+ }
+ }
+
+ if (verbose)
+ printk(KERN_INFO "%s: q->function=\"%s\" q->filename=\"%s\" "
+ "q->module=\"%s\" q->format=\"%s\" q->lineno=%u-%u\n",
+ __func__, query->function, query->filename,
+ query->module, query->format, query->first_lineno,
+ query->last_lineno);
+
+ return 0;
+}
+
+/*
+ * Parse `str' as a flags specification, format [-+=][p]+.
+ * Sets up *maskp and *flagsp to be used when changing the
+ * flags fields of matched _ddebug's. Returns 0 on success
+ * or <0 on error.
+ */
+static int ddebug_parse_flags(const char *str, unsigned int *flagsp,
+ unsigned int *maskp)
+{
+ unsigned flags = 0;
+ int op = '=';
+
+ switch (*str) {
+ case '+':
+ case '-':
+ case '=':
+ op = *str++;
+ break;
+ default:
+ return -EINVAL;
+ }
+ if (verbose)
+ printk(KERN_INFO "%s: op='%c'\n", __func__, op);
+
+ for ( ; *str ; ++str) {
+ switch (*str) {
+ case 'p':
+ flags |= _DPRINTK_FLAGS_PRINT;
+ break;
+ default:
+ return -EINVAL;
+ }
+ }
+ if (flags == 0)
+ return -EINVAL;
+ if (verbose)
+ printk(KERN_INFO "%s: flags=0x%x\n", __func__, flags);
+
+ /* calculate final *flagsp, *maskp according to mask and op */
+ switch (op) {
+ case '=':
+ *maskp = 0;
+ *flagsp = flags;
+ break;
+ case '+':
+ *maskp = ~0U;
+ *flagsp = flags;
+ break;
+ case '-':
+ *maskp = ~flags;
+ *flagsp = 0;
+ break;
+ }
+ if (verbose)
+ printk(KERN_INFO "%s: *flagsp=0x%x *maskp=0x%x\n",
+ __func__, *flagsp, *maskp);
+ return 0;
+}
+
+/*
+ * File_ops->write method for <debugfs>/dynamic_debug/conrol. Gathers the
+ * command text from userspace, parses and executes it.
+ */
+static ssize_t ddebug_proc_write(struct file *file, const char __user *ubuf,
+ size_t len, loff_t *offp)
+{
+ unsigned int flags = 0, mask = 0;
+ struct ddebug_query query;
+#define MAXWORDS 9
+ int nwords;
+ char *words[MAXWORDS];
+ char tmpbuf[256];
+
+ if (len == 0)
+ return 0;
+ /* we don't check *offp -- multiple writes() are allowed */
+ if (len > sizeof(tmpbuf)-1)
+ return -E2BIG;
+ if (copy_from_user(tmpbuf, ubuf, len))
+ return -EFAULT;
+ tmpbuf[len] = '\0';
+ if (verbose)
+ printk(KERN_INFO "%s: read %d bytes from userspace\n",
+ __func__, (int)len);
+
+ nwords = ddebug_tokenize(tmpbuf, words, MAXWORDS);
+ if (nwords < 0)
+ return -EINVAL;
+ if (ddebug_parse_query(words, nwords-1, &query))
+ return -EINVAL;
+ if (ddebug_parse_flags(words[nwords-1], &flags, &mask))
+ return -EINVAL;
+
+ /* actually go and implement the change */
+ ddebug_change(&query, flags, mask);
+
+ *offp += len;
+ return len;
+}
+
+/*
+ * Set the iterator to point to the first _ddebug object
+ * and return a pointer to that first object. Returns
+ * NULL if there are no _ddebugs at all.
+ */
+static struct _ddebug *ddebug_iter_first(struct ddebug_iter *iter)
+{
+ if (list_empty(&ddebug_tables)) {
+ iter->table = NULL;
+ iter->idx = 0;
+ return NULL;
+ }
+ iter->table = list_entry(ddebug_tables.next,
+ struct ddebug_table, link);
+ iter->idx = 0;
+ return &iter->table->ddebugs[iter->idx];
+}
+
+/*
+ * Advance the iterator to point to the next _ddebug
+ * object from the one the iterator currently points at,
+ * and returns a pointer to the new _ddebug. Returns
+ * NULL if the iterator has seen all the _ddebugs.
+ */
+static struct _ddebug *ddebug_iter_next(struct ddebug_iter *iter)
+{
+ if (iter->table == NULL)
+ return NULL;
+ if (++iter->idx == iter->table->num_ddebugs) {
+ /* iterate to next table */
+ iter->idx = 0;
+ if (list_is_last(&iter->table->link, &ddebug_tables)) {
+ iter->table = NULL;
+ return NULL;
+ }
+ iter->table = list_entry(iter->table->link.next,
+ struct ddebug_table, link);
+ }
+ return &iter->table->ddebugs[iter->idx];
+}
+
+/*
+ * Seq_ops start method. Called at the start of every
+ * read() call from userspace. Takes the ddebug_lock and
+ * seeks the seq_file's iterator to the given position.
+ */
+static void *ddebug_proc_start(struct seq_file *m, loff_t *pos)
+{
+ struct ddebug_iter *iter = m->private;
+ struct _ddebug *dp;
+ int n = *pos;
+
+ if (verbose)
+ printk(KERN_INFO "%s: called m=%p *pos=%lld\n",
+ __func__, m, (unsigned long long)*pos);
+
+ mutex_lock(&ddebug_lock);
+
+ if (!n)
+ return SEQ_START_TOKEN;
+ if (n < 0)
+ return NULL;
+ dp = ddebug_iter_first(iter);
+ while (dp != NULL && --n > 0)
+ dp = ddebug_iter_next(iter);
+ return dp;
+}
+
+/*
+ * Seq_ops next method. Called several times within a read()
+ * call from userspace, with ddebug_lock held. Walks to the
+ * next _ddebug object with a special case for the header line.
+ */
+static void *ddebug_proc_next(struct seq_file *m, void *p, loff_t *pos)
+{
+ struct ddebug_iter *iter = m->private;
+ struct _ddebug *dp;
+
+ if (verbose)
+ printk(KERN_INFO "%s: called m=%p p=%p *pos=%lld\n",
+ __func__, m, p, (unsigned long long)*pos);
+
+ if (p == SEQ_START_TOKEN)
+ dp = ddebug_iter_first(iter);
+ else
+ dp = ddebug_iter_next(iter);
+ ++*pos;
+ return dp;
+}
+
+/*
+ * Seq_ops show method. Called several times within a read()
+ * call from userspace, with ddebug_lock held. Formats the
+ * current _ddebug as a single human-readable line, with a
+ * special case for the header line.
+ */
+static int ddebug_proc_show(struct seq_file *m, void *p)
+{
+ struct ddebug_iter *iter = m->private;
+ struct _ddebug *dp = p;
+ char flagsbuf[8];
+
+ if (verbose)
+ printk(KERN_INFO "%s: called m=%p p=%p\n",
+ __func__, m, p);
+
+ if (p == SEQ_START_TOKEN) {
+ seq_puts(m,
+ "# filename:lineno [module]function flags format\n");
+ return 0;
+ }
+
+ seq_printf(m, "%s:%u [%s]%s %s \"",
+ dp->filename, dp->lineno,
+ iter->table->mod_name, dp->function,
+ ddebug_describe_flags(dp, flagsbuf, sizeof(flagsbuf)));
+ seq_escape(m, dp->format, "\t\r\n\"");
+ seq_puts(m, "\"\n");
+
+ return 0;
+}
+
+/*
+ * Seq_ops stop method. Called at the end of each read()
+ * call from userspace. Drops ddebug_lock.
+ */
+static void ddebug_proc_stop(struct seq_file *m, void *p)
+{
+ if (verbose)
+ printk(KERN_INFO "%s: called m=%p p=%p\n",
+ __func__, m, p);
+ mutex_unlock(&ddebug_lock);
+}
+
+static const struct seq_operations ddebug_proc_seqops = {
+ .start = ddebug_proc_start,
+ .next = ddebug_proc_next,
+ .show = ddebug_proc_show,
+ .stop = ddebug_proc_stop
+};
+
+/*
+ * File_ops->open method for <debugfs>/dynamic_debug/control. Does the seq_file
+ * setup dance, and also creates an iterator to walk the _ddebugs.
+ * Note that we create a seq_file always, even for O_WRONLY files
+ * where it's not needed, as doing so simplifies the ->release method.
+ */
+static int ddebug_proc_open(struct inode *inode, struct file *file)
+{
+ struct ddebug_iter *iter;
+ int err;
+
+ if (verbose)
+ printk(KERN_INFO "%s: called\n", __func__);
+
+ iter = kzalloc(sizeof(*iter), GFP_KERNEL);
+ if (iter == NULL)
+ return -ENOMEM;
+
+ err = seq_open(file, &ddebug_proc_seqops);
+ if (err) {
+ kfree(iter);
+ return err;
+ }
+ ((struct seq_file *) file->private_data)->private = iter;
+ return 0;
+}
+
+static const struct file_operations ddebug_proc_fops = {
+ .owner = THIS_MODULE,
+ .open = ddebug_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release_private,
+ .write = ddebug_proc_write
+};
+
+/*
+ * Allocate a new ddebug_table for the given module
+ * and add it to the global list.
+ */
+int ddebug_add_module(struct _ddebug *tab, unsigned int n,
+ const char *name)
+{
+ struct ddebug_table *dt;
+ char *new_name;
+
+ dt = kzalloc(sizeof(*dt), GFP_KERNEL);
+ if (dt == NULL)
+ return -ENOMEM;
+ new_name = kstrdup(name, GFP_KERNEL);
+ if (new_name == NULL) {
+ kfree(dt);
+ return -ENOMEM;
+ }
+ dt->mod_name = new_name;
+ dt->num_ddebugs = n;
+ dt->num_enabled = 0;
+ dt->ddebugs = tab;
+
+ mutex_lock(&ddebug_lock);
+ list_add_tail(&dt->link, &ddebug_tables);
+ mutex_unlock(&ddebug_lock);
+
+ if (verbose)
+ printk(KERN_INFO "%u debug prints in module %s\n",
+ n, dt->mod_name);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(ddebug_add_module);
+
+static void ddebug_table_free(struct ddebug_table *dt)
+{
+ list_del_init(&dt->link);
+ kfree(dt->mod_name);
+ kfree(dt);
+}
+
+/*
+ * Called in response to a module being unloaded. Removes
+ * any ddebug_table's which point at the module.
+ */
+int ddebug_remove_module(char *mod_name)
+{
+ struct ddebug_table *dt, *nextdt;
+ int ret = -ENOENT;
+
+ if (verbose)
+ printk(KERN_INFO "%s: removing module \"%s\"\n",
+ __func__, mod_name);
+
+ mutex_lock(&ddebug_lock);
+ list_for_each_entry_safe(dt, nextdt, &ddebug_tables, link) {
+ if (!strcmp(dt->mod_name, mod_name)) {
+ ddebug_table_free(dt);
+ ret = 0;
+ }
+ }
+ mutex_unlock(&ddebug_lock);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(ddebug_remove_module);
+
+static void ddebug_remove_all_tables(void)
+{
+ mutex_lock(&ddebug_lock);
+ while (!list_empty(&ddebug_tables)) {
+ struct ddebug_table *dt = list_entry(ddebug_tables.next,
+ struct ddebug_table,
+ link);
+ ddebug_table_free(dt);
+ }
+ mutex_unlock(&ddebug_lock);
+}
+
+static int __init dynamic_debug_init(void)
+{
+ struct dentry *dir, *file;
+ struct _ddebug *iter, *iter_start;
+ const char *modname = NULL;
+ int ret = 0;
+ int n = 0;
+
+ dir = debugfs_create_dir("dynamic_debug", NULL);
+ if (!dir)
+ return -ENOMEM;
+ file = debugfs_create_file("control", 0644, dir, NULL,
+ &ddebug_proc_fops);
+ if (!file) {
+ debugfs_remove(dir);
+ return -ENOMEM;
+ }
+ if (__start___verbose != __stop___verbose) {
+ iter = __start___verbose;
+ modname = iter->modname;
+ iter_start = iter;
+ for (; iter < __stop___verbose; iter++) {
+ if (strcmp(modname, iter->modname)) {
+ ret = ddebug_add_module(iter_start, n, modname);
+ if (ret)
+ goto out_free;
+ n = 0;
+ modname = iter->modname;
+ iter_start = iter;
+ }
+ n++;
+ }
+ ret = ddebug_add_module(iter_start, n, modname);
+ }
+out_free:
+ if (ret) {
+ ddebug_remove_all_tables();
+ debugfs_remove(dir);
+ debugfs_remove(file);
+ }
+ return 0;
+}
+module_init(dynamic_debug_init);
diff --git a/lib/dynamic_printk.c b/lib/dynamic_printk.c
deleted file mode 100644
index 165a197..0000000
--- a/lib/dynamic_printk.c
+++ /dev/null
@@ -1,414 +0,0 @@
-/*
- * lib/dynamic_printk.c
- *
- * make pr_debug()/dev_dbg() calls runtime configurable based upon their
- * their source module.
- *
- * Copyright (C) 2008 Red Hat, Inc., Jason Baron <[email protected]>
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/uaccess.h>
-#include <linux/seq_file.h>
-#include <linux/debugfs.h>
-#include <linux/fs.h>
-
-extern struct mod_debug __start___verbose[];
-extern struct mod_debug __stop___verbose[];
-
-struct debug_name {
- struct hlist_node hlist;
- struct hlist_node hlist2;
- int hash1;
- int hash2;
- char *name;
- int enable;
- int type;
-};
-
-static int nr_entries;
-static int num_enabled;
-int dynamic_enabled = DYNAMIC_ENABLED_NONE;
-static struct hlist_head module_table[DEBUG_HASH_TABLE_SIZE] =
- { [0 ... DEBUG_HASH_TABLE_SIZE-1] = HLIST_HEAD_INIT };
-static struct hlist_head module_table2[DEBUG_HASH_TABLE_SIZE] =
- { [0 ... DEBUG_HASH_TABLE_SIZE-1] = HLIST_HEAD_INIT };
-static DECLARE_MUTEX(debug_list_mutex);
-
-/* dynamic_printk_enabled, and dynamic_printk_enabled2 are bitmasks in which
- * bit n is set to 1 if any modname hashes into the bucket n, 0 otherwise. They
- * use independent hash functions, to reduce the chance of false positives.
- */
-long long dynamic_printk_enabled;
-EXPORT_SYMBOL_GPL(dynamic_printk_enabled);
-long long dynamic_printk_enabled2;
-EXPORT_SYMBOL_GPL(dynamic_printk_enabled2);
-
-/* returns the debug module pointer. */
-static struct debug_name *find_debug_module(char *module_name)
-{
- int i;
- struct hlist_head *head;
- struct hlist_node *node;
- struct debug_name *element;
-
- element = NULL;
- for (i = 0; i < DEBUG_HASH_TABLE_SIZE; i++) {
- head = &module_table[i];
- hlist_for_each_entry_rcu(element, node, head, hlist)
- if (!strcmp(element->name, module_name))
- return element;
- }
- return NULL;
-}
-
-/* returns the debug module pointer. */
-static struct debug_name *find_debug_module_hash(char *module_name, int hash)
-{
- struct hlist_head *head;
- struct hlist_node *node;
- struct debug_name *element;
-
- element = NULL;
- head = &module_table[hash];
- hlist_for_each_entry_rcu(element, node, head, hlist)
- if (!strcmp(element->name, module_name))
- return element;
- return NULL;
-}
-
-/* caller must hold mutex*/
-static int __add_debug_module(char *mod_name, int hash, int hash2)
-{
- struct debug_name *new;
- char *module_name;
- int ret = 0;
-
- if (find_debug_module(mod_name)) {
- ret = -EINVAL;
- goto out;
- }
- module_name = kmalloc(strlen(mod_name) + 1, GFP_KERNEL);
- if (!module_name) {
- ret = -ENOMEM;
- goto out;
- }
- module_name = strcpy(module_name, mod_name);
- module_name[strlen(mod_name)] = '\0';
- new = kzalloc(sizeof(struct debug_name), GFP_KERNEL);
- if (!new) {
- kfree(module_name);
- ret = -ENOMEM;
- goto out;
- }
- INIT_HLIST_NODE(&new->hlist);
- INIT_HLIST_NODE(&new->hlist2);
- new->name = module_name;
- new->hash1 = hash;
- new->hash2 = hash2;
- hlist_add_head_rcu(&new->hlist, &module_table[hash]);
- hlist_add_head_rcu(&new->hlist2, &module_table2[hash2]);
- nr_entries++;
-out:
- return ret;
-}
-
-int unregister_dynamic_debug_module(char *mod_name)
-{
- struct debug_name *element;
- int ret = 0;
-
- down(&debug_list_mutex);
- element = find_debug_module(mod_name);
- if (!element) {
- ret = -EINVAL;
- goto out;
- }
- hlist_del_rcu(&element->hlist);
- hlist_del_rcu(&element->hlist2);
- synchronize_rcu();
- kfree(element->name);
- if (element->enable)
- num_enabled--;
- kfree(element);
- nr_entries--;
-out:
- up(&debug_list_mutex);
- return ret;
-}
-EXPORT_SYMBOL_GPL(unregister_dynamic_debug_module);
-
-int register_dynamic_debug_module(char *mod_name, int type, char *share_name,
- char *flags, int hash, int hash2)
-{
- struct debug_name *elem;
- int ret = 0;
-
- down(&debug_list_mutex);
- elem = find_debug_module(mod_name);
- if (!elem) {
- if (__add_debug_module(mod_name, hash, hash2))
- goto out;
- elem = find_debug_module(mod_name);
- if (dynamic_enabled == DYNAMIC_ENABLED_ALL &&
- !strcmp(mod_name, share_name)) {
- elem->enable = true;
- num_enabled++;
- }
- }
- elem->type |= type;
-out:
- up(&debug_list_mutex);
- return ret;
-}
-EXPORT_SYMBOL_GPL(register_dynamic_debug_module);
-
-int __dynamic_dbg_enabled_helper(char *mod_name, int type, int value, int hash)
-{
- struct debug_name *elem;
- int ret = 0;
-
- if (dynamic_enabled == DYNAMIC_ENABLED_ALL)
- return 1;
- rcu_read_lock();
- elem = find_debug_module_hash(mod_name, hash);
- if (elem && elem->enable)
- ret = 1;
- rcu_read_unlock();
- return ret;
-}
-EXPORT_SYMBOL_GPL(__dynamic_dbg_enabled_helper);
-
-static void set_all(bool enable)
-{
- struct debug_name *e;
- struct hlist_node *node;
- int i;
- long long enable_mask;
-
- for (i = 0; i < DEBUG_HASH_TABLE_SIZE; i++) {
- if (module_table[i].first != NULL) {
- hlist_for_each_entry(e, node, &module_table[i], hlist) {
- e->enable = enable;
- }
- }
- }
- if (enable)
- enable_mask = ULLONG_MAX;
- else
- enable_mask = 0;
- dynamic_printk_enabled = enable_mask;
- dynamic_printk_enabled2 = enable_mask;
-}
-
-static int disabled_hash(int i, bool first_table)
-{
- struct debug_name *e;
- struct hlist_node *node;
-
- if (first_table) {
- hlist_for_each_entry(e, node, &module_table[i], hlist) {
- if (e->enable)
- return 0;
- }
- } else {
- hlist_for_each_entry(e, node, &module_table2[i], hlist2) {
- if (e->enable)
- return 0;
- }
- }
- return 1;
-}
-
-static ssize_t pr_debug_write(struct file *file, const char __user *buf,
- size_t length, loff_t *ppos)
-{
- char *buffer, *s, *value_str, *setting_str;
- int err, value;
- struct debug_name *elem = NULL;
- int all = 0;
-
- if (length > PAGE_SIZE || length < 0)
- return -EINVAL;
-
- buffer = (char *)__get_free_page(GFP_KERNEL);
- if (!buffer)
- return -ENOMEM;
-
- err = -EFAULT;
- if (copy_from_user(buffer, buf, length))
- goto out;
-
- err = -EINVAL;
- if (length < PAGE_SIZE)
- buffer[length] = '\0';
- else if (buffer[PAGE_SIZE-1])
- goto out;
-
- err = -EINVAL;
- down(&debug_list_mutex);
-
- if (strncmp("set", buffer, 3))
- goto out_up;
- s = buffer + 3;
- setting_str = strsep(&s, "=");
- if (s == NULL)
- goto out_up;
- setting_str = strstrip(setting_str);
- value_str = strsep(&s, " ");
- if (s == NULL)
- goto out_up;
- s = strstrip(s);
- if (!strncmp(s, "all", 3))
- all = 1;
- else
- elem = find_debug_module(s);
- if (!strncmp(setting_str, "enable", 6)) {
- value = !!simple_strtol(value_str, NULL, 10);
- if (all) {
- if (value) {
- set_all(true);
- num_enabled = nr_entries;
- dynamic_enabled = DYNAMIC_ENABLED_ALL;
- } else {
- set_all(false);
- num_enabled = 0;
- dynamic_enabled = DYNAMIC_ENABLED_NONE;
- }
- err = 0;
- } else if (elem) {
- if (value && (elem->enable == 0)) {
- dynamic_printk_enabled |= (1LL << elem->hash1);
- dynamic_printk_enabled2 |= (1LL << elem->hash2);
- elem->enable = 1;
- num_enabled++;
- dynamic_enabled = DYNAMIC_ENABLED_SOME;
- err = 0;
- printk(KERN_DEBUG
- "debugging enabled for module %s\n",
- elem->name);
- } else if (!value && (elem->enable == 1)) {
- elem->enable = 0;
- num_enabled--;
- if (disabled_hash(elem->hash1, true))
- dynamic_printk_enabled &=
- ~(1LL << elem->hash1);
- if (disabled_hash(elem->hash2, false))
- dynamic_printk_enabled2 &=
- ~(1LL << elem->hash2);
- if (num_enabled)
- dynamic_enabled = DYNAMIC_ENABLED_SOME;
- else
- dynamic_enabled = DYNAMIC_ENABLED_NONE;
- err = 0;
- printk(KERN_DEBUG
- "debugging disabled for module %s\n",
- elem->name);
- }
- }
- }
- if (!err)
- err = length;
-out_up:
- up(&debug_list_mutex);
-out:
- free_page((unsigned long)buffer);
- return err;
-}
-
-static void *pr_debug_seq_start(struct seq_file *f, loff_t *pos)
-{
- return (*pos < DEBUG_HASH_TABLE_SIZE) ? pos : NULL;
-}
-
-static void *pr_debug_seq_next(struct seq_file *s, void *v, loff_t *pos)
-{
- (*pos)++;
- if (*pos >= DEBUG_HASH_TABLE_SIZE)
- return NULL;
- return pos;
-}
-
-static void pr_debug_seq_stop(struct seq_file *s, void *v)
-{
- /* Nothing to do */
-}
-
-static int pr_debug_seq_show(struct seq_file *s, void *v)
-{
- struct hlist_head *head;
- struct hlist_node *node;
- struct debug_name *elem;
- unsigned int i = *(loff_t *) v;
-
- rcu_read_lock();
- head = &module_table[i];
- hlist_for_each_entry_rcu(elem, node, head, hlist) {
- seq_printf(s, "%s enabled=%d", elem->name, elem->enable);
- seq_printf(s, "\n");
- }
- rcu_read_unlock();
- return 0;
-}
-
-static struct seq_operations pr_debug_seq_ops = {
- .start = pr_debug_seq_start,
- .next = pr_debug_seq_next,
- .stop = pr_debug_seq_stop,
- .show = pr_debug_seq_show
-};
-
-static int pr_debug_open(struct inode *inode, struct file *filp)
-{
- return seq_open(filp, &pr_debug_seq_ops);
-}
-
-static const struct file_operations pr_debug_operations = {
- .open = pr_debug_open,
- .read = seq_read,
- .write = pr_debug_write,
- .llseek = seq_lseek,
- .release = seq_release,
-};
-
-static int __init dynamic_printk_init(void)
-{
- struct dentry *dir, *file;
- struct mod_debug *iter;
- unsigned long value;
-
- dir = debugfs_create_dir("dynamic_printk", NULL);
- if (!dir)
- return -ENOMEM;
- file = debugfs_create_file("modules", 0644, dir, NULL,
- &pr_debug_operations);
- if (!file) {
- debugfs_remove(dir);
- return -ENOMEM;
- }
- for (value = (unsigned long)__start___verbose;
- value < (unsigned long)__stop___verbose;
- value += sizeof(struct mod_debug)) {
- iter = (struct mod_debug *)value;
- register_dynamic_debug_module(iter->modname,
- iter->type,
- iter->logical_modname,
- iter->flag_names, iter->hash, iter->hash2);
- }
- if (dynamic_enabled == DYNAMIC_ENABLED_ALL)
- set_all(true);
- return 0;
-}
-module_init(dynamic_printk_init);
-/* may want to move this earlier so we can get traces as early as possible */
-
-static int __init dynamic_printk_setup(char *str)
-{
- if (str)
- return -ENOENT;
- dynamic_enabled = DYNAMIC_ENABLED_ALL;
- return 0;
-}
-/* Use early_param(), so we can get debug output as early as possible */
-early_param("dynamic_printk", dynamic_printk_setup);
diff --git a/net/netfilter/nf_conntrack_pptp.c b/net/netfilter/nf_conntrack_pptp.c
index 9e169ef..12bd09d 100644
--- a/net/netfilter/nf_conntrack_pptp.c
+++ b/net/netfilter/nf_conntrack_pptp.c
@@ -66,7 +66,7 @@ void
struct nf_conntrack_expect *exp) __read_mostly;
EXPORT_SYMBOL_GPL(nf_nat_pptp_hook_expectfn);

-#if defined(DEBUG) || defined(CONFIG_DYNAMIC_PRINTK_DEBUG)
+#if defined(DEBUG) || defined(CONFIG_DYNAMIC_DEBUG)
/* PptpControlMessageType names */
const char *const pptp_msg_name[] = {
"UNKNOWN_MESSAGE",
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index e063657..c18fa15 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -97,7 +97,7 @@ modname_flags = $(if $(filter 1,$(words $(modname))),\
-D"KBUILD_MODNAME=KBUILD_STR($(call name-fix,$(modname)))")

#hash values
-ifdef CONFIG_DYNAMIC_PRINTK_DEBUG
+ifdef CONFIG_DYNAMIC_DEBUG
debug_flags = -D"DEBUG_HASH=$(shell ./scripts/basic/hash djb2 $(@D)$(modname))"\
-D"DEBUG_HASH2=$(shell ./scripts/basic/hash r5 $(@D)$(modname))"
else
--
1.6.2

2009-03-25 00:51:58

by Greg KH

[permalink] [raw]
Subject: [PATCH 59/61] dynamic debug: update docs

From: Jason Baron <[email protected]>

updates the documentation for 'dynamic debug' feature.

Signed-off-by: Greg Banks <[email protected]>
Signed-off-by: Jason Baron <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
Documentation/dynamic-debug-howto.txt | 232 +++++++++++++++++++++++++++++++++
lib/Kconfig.debug | 72 ++++++-----
2 files changed, 273 insertions(+), 31 deletions(-)
create mode 100644 Documentation/dynamic-debug-howto.txt

diff --git a/Documentation/dynamic-debug-howto.txt b/Documentation/dynamic-debug-howto.txt
new file mode 100644
index 0000000..6839482
--- /dev/null
+++ b/Documentation/dynamic-debug-howto.txt
@@ -0,0 +1,232 @@
+
+Introduction
+============
+
+This document describes how to use the dynamic debug (ddebug) feature.
+
+Dynamic debug is designed to allow you to dynamically enable/disable kernel
+code to obtain additional kernel information. Currently, if
+CONFIG_DYNAMIC_DEBUG is set, then all pr_debug()/dev_debug() calls can be
+dynamically enabled per-callsite.
+
+Dynamic debug has even more useful features:
+
+ * Simple query language allows turning on and off debugging statements by
+ matching any combination of:
+
+ - source filename
+ - function name
+ - line number (including ranges of line numbers)
+ - module name
+ - format string
+
+ * Provides a debugfs control file: <debugfs>/dynamic_debug/control which can be
+ read to display the complete list of known debug statements, to help guide you
+
+Controlling dynamic debug Behaviour
+===============================
+
+The behaviour of pr_debug()/dev_debug()s are controlled via writing to a
+control file in the 'debugfs' filesystem. Thus, you must first mount the debugfs
+filesystem, in order to make use of this feature. Subsequently, we refer to the
+control file as: <debugfs>/dynamic_debug/control. For example, if you want to
+enable printing from source file 'svcsock.c', line 1603 you simply do:
+
+nullarbor:~ # echo 'file svcsock.c line 1603 +p' >
+ <debugfs>/dynamic_debug/control
+
+If you make a mistake with the syntax, the write will fail thus:
+
+nullarbor:~ # echo 'file svcsock.c wtf 1 +p' >
+ <debugfs>/dynamic_debug/control
+-bash: echo: write error: Invalid argument
+
+Viewing Dynamic Debug Behaviour
+===========================
+
+You can view the currently configured behaviour of all the debug statements
+via:
+
+nullarbor:~ # cat <debugfs>/dynamic_debug/control
+# filename:lineno [module]function flags format
+/usr/src/packages/BUILD/sgi-enhancednfs-1.4/default/net/sunrpc/svc_rdma.c:323 [svcxprt_rdma]svc_rdma_cleanup - "SVCRDMA\040Module\040Removed,\040deregister\040RPC\040RDMA\040transport\012"
+/usr/src/packages/BUILD/sgi-enhancednfs-1.4/default/net/sunrpc/svc_rdma.c:341 [svcxprt_rdma]svc_rdma_init - "\011max_inline\040\040\040\040\040\040\040:\040%d\012"
+/usr/src/packages/BUILD/sgi-enhancednfs-1.4/default/net/sunrpc/svc_rdma.c:340 [svcxprt_rdma]svc_rdma_init - "\011sq_depth\040\040\040\040\040\040\040\040\040:\040%d\012"
+/usr/src/packages/BUILD/sgi-enhancednfs-1.4/default/net/sunrpc/svc_rdma.c:338 [svcxprt_rdma]svc_rdma_init - "\011max_requests\040\040\040\040\040:\040%d\012"
+...
+
+
+You can also apply standard Unix text manipulation filters to this
+data, e.g.
+
+nullarbor:~ # grep -i rdma <debugfs>/dynamic_debug/control | wc -l
+62
+
+nullarbor:~ # grep -i tcp <debugfs>/dynamic_debug/control | wc -l
+42
+
+Note in particular that the third column shows the enabled behaviour
+flags for each debug statement callsite (see below for definitions of the
+flags). The default value, no extra behaviour enabled, is "-". So
+you can view all the debug statement callsites with any non-default flags:
+
+nullarbor:~ # awk '$3 != "-"' <debugfs>/dynamic_debug/control
+# filename:lineno [module]function flags format
+/usr/src/packages/BUILD/sgi-enhancednfs-1.4/default/net/sunrpc/svcsock.c:1603 [sunrpc]svc_send p "svc_process:\040st_sendto\040returned\040%d\012"
+
+
+Command Language Reference
+==========================
+
+At the lexical level, a command comprises a sequence of words separated
+by whitespace characters. Note that newlines are treated as word
+separators and do *not* end a command or allow multiple commands to
+be done together. So these are all equivalent:
+
+nullarbor:~ # echo -c 'file svcsock.c line 1603 +p' >
+ <debugfs>/dynamic_debug/control
+nullarbor:~ # echo -c ' file svcsock.c line 1603 +p ' >
+ <debugfs>/dynamic_debug/control
+nullarbor:~ # echo -c 'file svcsock.c\nline 1603 +p' >
+ <debugfs>/dynamic_debug/control
+nullarbor:~ # echo -n 'file svcsock.c line 1603 +p' >
+ <debugfs>/dynamic_debug/control
+
+Commands are bounded by a write() system call. If you want to do
+multiple commands you need to do a separate "echo" for each, like:
+
+nullarbor:~ # echo 'file svcsock.c line 1603 +p' > /proc/dprintk ;\
+> echo 'file svcsock.c line 1563 +p' > /proc/dprintk
+
+or even like:
+
+nullarbor:~ # (
+> echo 'file svcsock.c line 1603 +p' ;\
+> echo 'file svcsock.c line 1563 +p' ;\
+> ) > /proc/dprintk
+
+At the syntactical level, a command comprises a sequence of match
+specifications, followed by a flags change specification.
+
+command ::= match-spec* flags-spec
+
+The match-spec's are used to choose a subset of the known dprintk()
+callsites to which to apply the flags-spec. Think of them as a query
+with implicit ANDs between each pair. Note that an empty list of
+match-specs is possible, but is not very useful because it will not
+match any debug statement callsites.
+
+A match specification comprises a keyword, which controls the attribute
+of the callsite to be compared, and a value to compare against. Possible
+keywords are:
+
+match-spec ::= 'func' string |
+ 'file' string |
+ 'module' string |
+ 'format' string |
+ 'line' line-range
+
+line-range ::= lineno |
+ '-'lineno |
+ lineno'-' |
+ lineno'-'lineno
+// Note: line-range cannot contain space, e.g.
+// "1-30" is valid range but "1 - 30" is not.
+
+lineno ::= unsigned-int
+
+The meanings of each keyword are:
+
+func
+ The given string is compared against the function name
+ of each callsite. Example:
+
+ func svc_tcp_accept
+
+file
+ The given string is compared against either the full
+ pathname or the basename of the source file of each
+ callsite. Examples:
+
+ file svcsock.c
+ file /usr/src/packages/BUILD/sgi-enhancednfs-1.4/default/net/sunrpc/svcsock.c
+
+module
+ The given string is compared against the module name
+ of each callsite. The module name is the string as
+ seen in "lsmod", i.e. without the directory or the .ko
+ suffix and with '-' changed to '_'. Examples:
+
+ module sunrpc
+ module nfsd
+
+format
+ The given string is searched for in the dynamic debug format
+ string. Note that the string does not need to match the
+ entire format, only some part. Whitespace and other
+ special characters can be escaped using C octal character
+ escape \ooo notation, e.g. the space character is \040.
+ Examples:
+
+ format svcrdma: // many of the NFS/RDMA server dprintks
+ format readahead // some dprintks in the readahead cache
+ format nfsd:\040SETATTR // how to match a format with whitespace
+
+line
+ The given line number or range of line numbers is compared
+ against the line number of each dprintk() callsite. A single
+ line number matches the callsite line number exactly. A
+ range of line numbers matches any callsite between the first
+ and last line number inclusive. An empty first number means
+ the first line in the file, an empty line number means the
+ last number in the file. Examples:
+
+ line 1603 // exactly line 1603
+ line 1600-1605 // the six lines from line 1600 to line 1605
+ line -1605 // the 1605 lines from line 1 to line 1605
+ line 1600- // all lines from line 1600 to the end of the file
+
+The flags specification comprises a change operation followed
+by one or more flag characters. The change operation is one
+of the characters:
+
+-
+ remove the given flags
+
++
+ add the given flags
+
+=
+ set the flags to the given flags
+
+The flags are:
+
+p
+ Causes a printk() message to be emitted to dmesg
+
+Note the regexp ^[-+=][scp]+$ matches a flags specification.
+Note also that there is no convenient syntax to remove all
+the flags at once, you need to use "-psc".
+
+Examples
+========
+
+// enable the message at line 1603 of file svcsock.c
+nullarbor:~ # echo -n 'file svcsock.c line 1603 +p' >
+ <debugfs>/dynamic_debug/control
+
+// enable all the messages in file svcsock.c
+nullarbor:~ # echo -n 'file svcsock.c +p' >
+ <debugfs>/dynamic_debug/control
+
+// enable all the messages in the NFS server module
+nullarbor:~ # echo -n 'module nfsd +p' >
+ <debugfs>/dynamic_debug/control
+
+// enable all 12 messages in the function svc_process()
+nullarbor:~ # echo -n 'func svc_process +p' >
+ <debugfs>/dynamic_debug/control
+
+// disable all 12 messages in the function svc_process()
+nullarbor:~ # echo -n 'func svc_process -p' >
+ <debugfs>/dynamic_debug/control
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 0dd1c04..8fee0a1 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -848,59 +848,69 @@ config BUILD_DOCSRC
Say N if you are unsure.

config DYNAMIC_DEBUG
- bool "Enable dynamic printk() call support"
+ bool "Enable dynamic printk() support"
default n
depends on PRINTK
+ depends on DEBUG_FS
select PRINTK_DEBUG
help

Compiles debug level messages into the kernel, which would not
otherwise be available at runtime. These messages can then be
- enabled/disabled on a per module basis. This mechanism implicitly
- enables all pr_debug() and dev_dbg() calls. The impact of this
- compile option is a larger kernel text size of about 2%.
+ enabled/disabled based on various levels of scope - per source file,
+ function, module, format string, and line number. This mechanism
+ implicitly enables all pr_debug() and dev_dbg() calls. The impact of
+ this compile option is a larger kernel text size of about 2%.

Usage:

- Dynamic debugging is controlled by the debugfs file,
- dynamic_printk/modules. This file contains a list of the modules that
- can be enabled. The format of the file is the module name, followed
- by a set of flags that can be enabled. The first flag is always the
- 'enabled' flag. For example:
+ Dynamic debugging is controlled via the 'dynamic_debug/ddebug' file,
+ which is contained in the 'debugfs' filesystem. Thus, the debugfs
+ filesystem must first be mounted before making use of this feature.
+ We refer the control file as: <debugfs>/dynamic_debug/ddebug. This
+ file contains a list of the debug statements that can be enabled. The
+ format for each line of the file is:

- <module_name> <enabled=0/1>
- .
- .
- .
+ filename:lineno [module]function flags format

- <module_name> : Name of the module in which the debug call resides
- <enabled=0/1> : whether the messages are enabled or not
+ filename : source file of the debug statement
+ lineno : line number of the debug statement
+ module : module that contains the debug statement
+ function : function that contains the debug statement
+ flags : 'p' means the line is turned 'on' for printing
+ format : the format used for the debug statement

From a live system:

- snd_hda_intel enabled=0
- fixup enabled=0
- driver enabled=0
+ nullarbor:~ # cat <debugfs>/dynamic_debug/ddebug
+ # filename:lineno [module]function flags format
+ fs/aio.c:222 [aio]__put_ioctx - "__put_ioctx:\040freeing\040%p\012"
+ fs/aio.c:248 [aio]ioctx_alloc - "ENOMEM:\040nr_events\040too\040high\012"
+ fs/aio.c:1770 [aio]sys_io_cancel - "calling\040cancel\012"

- Enable a module:
+ Example usage:

- $echo "set enabled=1 <module_name>" > dynamic_printk/modules
+ // enable the message at line 1603 of file svcsock.c
+ nullarbor:~ # echo -n 'file svcsock.c line 1603 +p' >
+ <debugfs>/dynamic_debug/ddebug

- Disable a module:
+ // enable all the messages in file svcsock.c
+ nullarbor:~ # echo -n 'file svcsock.c +p' >
+ <debugfs>/dynamic_debug/ddebug

- $echo "set enabled=0 <module_name>" > dynamic_printk/modules
+ // enable all the messages in the NFS server module
+ nullarbor:~ # echo -n 'module nfsd +p' >
+ <debugfs>/dynamic_debug/ddebug

- Enable all modules:
+ // enable all 12 messages in the function svc_process()
+ nullarbor:~ # echo -n 'func svc_process +p' >
+ <debugfs>/dynamic_debug/ddebug

- $echo "set enabled=1 all" > dynamic_printk/modules
+ // disable all 12 messages in the function svc_process()
+ nullarbor:~ # echo -n 'func svc_process -p' >
+ <debugfs>/dynamic_debug/ddebug

- Disable all modules:
-
- $echo "set enabled=0 all" > dynamic_printk/modules
-
- Finally, passing "dynamic_printk" at the command line enables
- debugging for all modules. This mode can be turned off via the above
- disable command.
+ See Documentation/dynamic-debug-howto.txt for additional information.

source "samples/Kconfig"

--
1.6.2

2009-03-25 00:51:40

by Greg KH

[permalink] [raw]
Subject: [PATCH 60/61] Dynamic debug: allow simple quoting of words

From: Greg Banks <[email protected]>

Allow simple quoting of words in the dynamic debug control language.

This allows more natural specification when using the control language
to match against printk formats, e.g

#echo -n 'format "Setting node for non-present cpu" +p' >
/mnt/debugfs/dynamic_debug/control

instead of

#echo -n 'format Setting\040node\040for\040non-present\040cpu +p' >
/mnt/debugfs/dynamic_debug/control

Adjust the dynamic debug documention to describe that and provide a
new example. Adjust the existing examples in the documentation to
reflect the current whitespace escaping behaviour when reading the
control file. Fix some minor documentation trailing whitespace.

Signed-off-by: Greg Banks <[email protected]>
Acked-by: Jason Baron <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
Documentation/dynamic-debug-howto.txt | 20 +++++++++----
lib/dynamic_debug.c | 53 ++++++++++++++++++++------------
2 files changed, 47 insertions(+), 26 deletions(-)

diff --git a/Documentation/dynamic-debug-howto.txt b/Documentation/dynamic-debug-howto.txt
index 6839482..674c566 100644
--- a/Documentation/dynamic-debug-howto.txt
+++ b/Documentation/dynamic-debug-howto.txt
@@ -49,10 +49,10 @@ via:

nullarbor:~ # cat <debugfs>/dynamic_debug/control
# filename:lineno [module]function flags format
-/usr/src/packages/BUILD/sgi-enhancednfs-1.4/default/net/sunrpc/svc_rdma.c:323 [svcxprt_rdma]svc_rdma_cleanup - "SVCRDMA\040Module\040Removed,\040deregister\040RPC\040RDMA\040transport\012"
-/usr/src/packages/BUILD/sgi-enhancednfs-1.4/default/net/sunrpc/svc_rdma.c:341 [svcxprt_rdma]svc_rdma_init - "\011max_inline\040\040\040\040\040\040\040:\040%d\012"
-/usr/src/packages/BUILD/sgi-enhancednfs-1.4/default/net/sunrpc/svc_rdma.c:340 [svcxprt_rdma]svc_rdma_init - "\011sq_depth\040\040\040\040\040\040\040\040\040:\040%d\012"
-/usr/src/packages/BUILD/sgi-enhancednfs-1.4/default/net/sunrpc/svc_rdma.c:338 [svcxprt_rdma]svc_rdma_init - "\011max_requests\040\040\040\040\040:\040%d\012"
+/usr/src/packages/BUILD/sgi-enhancednfs-1.4/default/net/sunrpc/svc_rdma.c:323 [svcxprt_rdma]svc_rdma_cleanup - "SVCRDMA Module Removed, deregister RPC RDMA transport\012"
+/usr/src/packages/BUILD/sgi-enhancednfs-1.4/default/net/sunrpc/svc_rdma.c:341 [svcxprt_rdma]svc_rdma_init - "\011max_inline : %d\012"
+/usr/src/packages/BUILD/sgi-enhancednfs-1.4/default/net/sunrpc/svc_rdma.c:340 [svcxprt_rdma]svc_rdma_init - "\011sq_depth : %d\012"
+/usr/src/packages/BUILD/sgi-enhancednfs-1.4/default/net/sunrpc/svc_rdma.c:338 [svcxprt_rdma]svc_rdma_init - "\011max_requests : %d\012"
...


@@ -72,7 +72,7 @@ you can view all the debug statement callsites with any non-default flags:

nullarbor:~ # awk '$3 != "-"' <debugfs>/dynamic_debug/control
# filename:lineno [module]function flags format
-/usr/src/packages/BUILD/sgi-enhancednfs-1.4/default/net/sunrpc/svcsock.c:1603 [sunrpc]svc_send p "svc_process:\040st_sendto\040returned\040%d\012"
+/usr/src/packages/BUILD/sgi-enhancednfs-1.4/default/net/sunrpc/svcsock.c:1603 [sunrpc]svc_send p "svc_process: st_sendto returned %d\012"


Command Language Reference
@@ -166,11 +166,15 @@ format
entire format, only some part. Whitespace and other
special characters can be escaped using C octal character
escape \ooo notation, e.g. the space character is \040.
+ Alternatively, the string can be enclosed in double quote
+ characters (") or single quote characters (').
Examples:

format svcrdma: // many of the NFS/RDMA server dprintks
format readahead // some dprintks in the readahead cache
- format nfsd:\040SETATTR // how to match a format with whitespace
+ format nfsd:\040SETATTR // one way to match a format with whitespace
+ format "nfsd: SETATTR" // a neater way to match a format with whitespace
+ format 'nfsd: SETATTR' // yet another way to match a format with whitespace

line
The given line number or range of line numbers is compared
@@ -230,3 +234,7 @@ nullarbor:~ # echo -n 'func svc_process +p' >
// disable all 12 messages in the function svc_process()
nullarbor:~ # echo -n 'func svc_process -p' >
<debugfs>/dynamic_debug/control
+
+// enable messages for NFS calls READ, READLINK, READDIR and READDIR+.
+nullarbor:~ # echo -n 'format "nfsd: READ" +p' >
+ <debugfs>/dynamic_debug/control
diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index 9e123ae..833139c 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -196,32 +196,45 @@ static void ddebug_change(const struct ddebug_query *query,
}

/*
- * Wrapper around strsep() to collapse the multiple empty tokens
- * that it returns when fed sequences of separator characters.
- * Now, if we had strtok_r()...
- */
-static inline char *nearly_strtok_r(char **p, const char *sep)
-{
- char *r;
-
- while ((r = strsep(p, sep)) != NULL && *r == '\0')
- ;
- return r;
-}
-
-/*
* Split the buffer `buf' into space-separated words.
- * Return the number of such words or <0 on error.
+ * Handles simple " and ' quoting, i.e. without nested,
+ * embedded or escaped \". Return the number of words
+ * or <0 on error.
*/
static int ddebug_tokenize(char *buf, char *words[], int maxwords)
{
int nwords = 0;

- while (nwords < maxwords &&
- (words[nwords] = nearly_strtok_r(&buf, " \t\r\n")) != NULL)
- nwords++;
- if (buf)
- return -EINVAL; /* ran out of words[] before bytes */
+ while (*buf) {
+ char *end;
+
+ /* Skip leading whitespace */
+ while (*buf && isspace(*buf))
+ buf++;
+ if (!*buf)
+ break; /* oh, it was trailing whitespace */
+
+ /* Run `end' over a word, either whitespace separated or quoted */
+ if (*buf == '"' || *buf == '\'') {
+ int quote = *buf++;
+ for (end = buf ; *end && *end != quote ; end++)
+ ;
+ if (!*end)
+ return -EINVAL; /* unclosed quote */
+ } else {
+ for (end = buf ; *end && !isspace(*end) ; end++)
+ ;
+ BUG_ON(end == buf);
+ }
+ /* Here `buf' is the start of the word, `end' is one past the end */
+
+ if (nwords == maxwords)
+ return -EINVAL; /* ran out of words[] before bytes */
+ if (*end)
+ *end++ = '\0'; /* terminate the word */
+ words[nwords++] = buf;
+ buf = end;
+ }

if (verbose) {
int i;
--
1.6.2

2009-03-25 00:52:28

by Greg KH

[permalink] [raw]
Subject: [PATCH 61/61] Dynamic debug: fix pr_fmt() build error

From: Greg Banks <[email protected]>

When CONFIG_DYNAMIC_DEBUG is enabled, allow callers of pr_debug()
to provide their own definition of pr_fmt() even if that definition
uses tricks like

#define pr_fmt(fmt) "%s:" fmt, __func__

Signed-off-by: Greg Banks <[email protected]>
Cc: Jason Baron <[email protected]>
Acked-by: Geert Uytterhoeven <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
include/linux/dynamic_debug.h | 4 ++--
include/linux/kernel.h | 3 ++-
2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h
index 07781aa..baabf33 100644
--- a/include/linux/dynamic_debug.h
+++ b/include/linux/dynamic_debug.h
@@ -57,7 +57,7 @@ extern int ddebug_remove_module(char *mod_name);
{ KBUILD_MODNAME, __func__, __FILE__, fmt, DEBUG_HASH, \
DEBUG_HASH2, __LINE__, _DPRINTK_FLAGS_DEFAULT }; \
if (__dynamic_dbg_enabled(descriptor)) \
- printk(KERN_DEBUG KBUILD_MODNAME ":" fmt, \
+ printk(KERN_DEBUG KBUILD_MODNAME ":" pr_fmt(fmt), \
##__VA_ARGS__); \
} while (0)

@@ -70,7 +70,7 @@ extern int ddebug_remove_module(char *mod_name);
DEBUG_HASH2, __LINE__, _DPRINTK_FLAGS_DEFAULT }; \
if (__dynamic_dbg_enabled(descriptor)) \
dev_printk(KERN_DEBUG, dev, \
- KBUILD_MODNAME ": " fmt, \
+ KBUILD_MODNAME ": " pr_fmt(fmt),\
##__VA_ARGS__); \
} while (0)

diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index b5496ec..914918a 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -359,8 +359,9 @@ static inline char *pack_hex_byte(char *buf, u8 byte)
#define pr_debug(fmt, ...) \
printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
#elif defined(CONFIG_DYNAMIC_DEBUG)
+/* dynamic_pr_debug() uses pr_fmt() internally so we don't need it here */
#define pr_debug(fmt, ...) do { \
- dynamic_pr_debug(pr_fmt(fmt), ##__VA_ARGS__); \
+ dynamic_pr_debug(fmt, ##__VA_ARGS__); \
} while (0)
#else
#define pr_debug(fmt, ...) \
--
1.6.2

2009-03-25 01:26:20

by Perez-Gonzalez, Inaky

[permalink] [raw]
Subject: RE: [PATCH 25/61] wimax: struct device - replace bus_id with dev_name(), dev_set_name()


>From: Greg Kroah-Hartman [[email protected]]
>Subject: [PATCH 25/61] wimax: struct device - replace bus_id with dev_name(), dev_set_name()

This is posted already in net-next, (347707baa77d273d79258303e00200d40cf3b323)

2009-03-25 03:31:42

by Stephen Hemminger

[permalink] [raw]
Subject: Re: [PATCH 15/61] net: struct device - replace bus_id with dev_name(), dev_set_name()

On Tue, 24 Mar 2009 17:26:19 -0700
Greg Kroah-Hartman <[email protected]> wrote:

> From: Kay Sievers <[email protected]>
>
> Cc: [email protected]
> Cc: [email protected]
> Acked-by: Greg Kroah-Hartman <[email protected]>
> Signed-off-by: Kay Sievers <[email protected]>
> ---
> drivers/net/arm/ks8695net.c | 2 +-
> drivers/net/au1000_eth.c | 8 ++++----
> drivers/net/bfin_mac.c | 12 ++++++------
> drivers/net/bmac.c | 2 +-
> drivers/net/cpmac.c | 2 +-
> drivers/net/declance.c | 6 +++---
> drivers/net/depca.c | 6 +++---
> drivers/net/ehea/ehea_main.c | 2 +-
> drivers/net/jazzsonic.c | 6 ++++--
> drivers/net/macb.c | 10 +++++-----
> drivers/net/macsonic.c | 15 ++++++++-------
> drivers/net/mv643xx_eth.c | 2 +-
> drivers/net/sb1250-mac.c | 10 +++++-----
> drivers/net/smc911x.c | 2 +-
> drivers/net/smc91x.c | 2 +-
> drivers/net/smsc911x.c | 7 ++++---
> drivers/net/smsc9420.c | 4 ++--
> drivers/net/tc35815.c | 4 ++--
> drivers/net/xtsonic.c | 2 +-
> 19 files changed, 54 insertions(+), 50 deletions(-)
>

I know this is needed, but could please put some more explicit rational
in changelog.

2009-03-25 04:31:40

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH 15/61] net: struct device - replace bus_id with dev_name(), dev_set_name()

On Tue, Mar 24, 2009 at 08:31:11PM -0700, Stephen Hemminger wrote:
> On Tue, 24 Mar 2009 17:26:19 -0700
> Greg Kroah-Hartman <[email protected]> wrote:
>
> > From: Kay Sievers <[email protected]>
> >
> > Cc: [email protected]
> > Cc: [email protected]
> > Acked-by: Greg Kroah-Hartman <[email protected]>
> > Signed-off-by: Kay Sievers <[email protected]>
> > ---
> > drivers/net/arm/ks8695net.c | 2 +-
> > drivers/net/au1000_eth.c | 8 ++++----
> > drivers/net/bfin_mac.c | 12 ++++++------
> > drivers/net/bmac.c | 2 +-
> > drivers/net/cpmac.c | 2 +-
> > drivers/net/declance.c | 6 +++---
> > drivers/net/depca.c | 6 +++---
> > drivers/net/ehea/ehea_main.c | 2 +-
> > drivers/net/jazzsonic.c | 6 ++++--
> > drivers/net/macb.c | 10 +++++-----
> > drivers/net/macsonic.c | 15 ++++++++-------
> > drivers/net/mv643xx_eth.c | 2 +-
> > drivers/net/sb1250-mac.c | 10 +++++-----
> > drivers/net/smc911x.c | 2 +-
> > drivers/net/smc91x.c | 2 +-
> > drivers/net/smsc911x.c | 7 ++++---
> > drivers/net/smsc9420.c | 4 ++--
> > drivers/net/tc35815.c | 4 ++--
> > drivers/net/xtsonic.c | 2 +-
> > 19 files changed, 54 insertions(+), 50 deletions(-)
> >
>
> I know this is needed, but could please put some more explicit rational
> in changelog.

bus_id is going away, much more rational isn't really needed :)

thanks,

greg k-h

2009-03-25 06:29:57

by David Miller

[permalink] [raw]
Subject: Re: [PATCH 15/61] net: struct device - replace bus_id with dev_name(), dev_set_name()

From: Greg Kroah-Hartman <[email protected]>
Date: Tue, 24 Mar 2009 17:26:19 -0700

> From: Kay Sievers <[email protected]>
>
> Cc: [email protected]
> Cc: [email protected]
> Acked-by: Greg Kroah-Hartman <[email protected]>
> Signed-off-by: Kay Sievers <[email protected]>

None of this patch applies to net-next-2.6

Probably because, just like the wimax case, these changes
are already there.

2009-03-25 09:35:15

by Kay Sievers

[permalink] [raw]
Subject: Re: [PATCH 15/61] net: struct device - replace bus_id with dev_name(), dev_set_name()

On Wed, Mar 25, 2009 at 07:29, David Miller <[email protected]> wrote:
> From: Greg Kroah-Hartman <[email protected]>
> Date: Tue, 24 Mar 2009 17:26:19 -0700
>
>> From: Kay Sievers <[email protected]>
>>
>> Cc: [email protected]
>> Cc: [email protected]
>> Acked-by: Greg Kroah-Hartman <[email protected]>
>> Signed-off-by: Kay Sievers <[email protected]>
>
> None of this patch applies to net-next-2.6
>
> Probably because, just like the wimax case, these changes
> are already there.

Yeah, I think -next handles duplicate and completely indentical
patches from differnt trees just fine, so that all has been in -next
for a while, and while it was still in Greg's tree when the other tree
merged it.

This patch is in your -next tree:
http://git.kernel.org/?p=linux/kernel/git/davem/net-next-2.6.git;a=commit;h=db1d7bf70f42124f73675fca62fe32f3ab1111b4

The problem with -next is that if some tree is dropped because of a
non-trivial conflict, and Greg removes merged patches, later patches
in Greg's tree may fail because of missing changes. Maybe we need some
kind of annotation with the -next logic to handle such cases better?

Thanks,
Kay

2009-03-25 10:51:19

by Ingo Molnar

[permalink] [raw]
Subject: Re: [PATCH 58/61] dynamic debug: combine dprintk and dynamic printk


* Greg Kroah-Hartman <[email protected]> wrote:

> From: Jason Baron <[email protected]>
>
> This patch combines Greg Bank's dprintk() work with the existing
> dynamic printk patchset, we are now calling it 'dynamic debug'.
>
> The new feature of this patchset is a richer /debugfs control file
> interface, (an example output from my system is at the bottom),
> which allows fined grained control over the the debug output. The
> output can be controlled by function, file, module, format string,
> and line number.

Hm, dunno this overlaps quite a bit with existing tracing
facilities.

There seems to be serious consolidation potential here, if you want
to reduce code and want to cooperate with existing tracing
facilities.

In particlar, this facility seems to be a subset of what is already
possible via trace_printk(). We could make every dprintk() site show
up in /debug/tracing/events/dprintk/, and make it possible to toggle
them on/off individually.

Furthermore it would also be possible to use the user-defined per
tracepoint filter expression facility. That way each dprintk site
can be (optionally) tailored individually.

For example we could enable such use:

echo 'pid == 1234' > /debug/tracing/events/dprintk/fs/lockd/svc4proc.c:71/filter
echo 1 > /debug/tracing/events/dprintk/fs/lockd/svc4proc.c:71/enabled

To tailor the following dprintk() in fs/lockd/svc4proc.c (line 71):

static __be32
nlm4svc_proc_null(struct svc_rqst *rqstp, void *argp, void *resp)
{
dprintk("lockd: NULL called\n");
return rpc_success;
}

To only be printed for PID 1234.

Per subsystem filters would be available too. The subsystem
maintainers dont have to do anything but place dprintk() calls -
they'll show up under /debug/tracing/events/dprintk/ automatically.

Would you be interested in this?

Ingo

2009-03-25 13:24:20

by Jason Baron

[permalink] [raw]
Subject: Re: [PATCH 58/61] dynamic debug: combine dprintk and dynamic printk

On Wed, Mar 25, 2009 at 11:50:23AM +0100, Ingo Molnar wrote:
> * Greg Kroah-Hartman <[email protected]> wrote:
>
> > From: Jason Baron <[email protected]>
> >
> > This patch combines Greg Bank's dprintk() work with the existing
> > dynamic printk patchset, we are now calling it 'dynamic debug'.
> >
> > The new feature of this patchset is a richer /debugfs control file
> > interface, (an example output from my system is at the bottom),
> > which allows fined grained control over the the debug output. The
> > output can be controlled by function, file, module, format string,
> > and line number.
>
> Hm, dunno this overlaps quite a bit with existing tracing
> facilities.
>
> There seems to be serious consolidation potential here, if you want
> to reduce code and want to cooperate with existing tracing
> facilities.
>

we're definitely interested in consolidation...i had posted an optional
flag for toggling to use trace_printk() instead of printk() before...

> In particlar, this facility seems to be a subset of what is already
> possible via trace_printk(). We could make every dprintk() site show
> up in /debug/tracing/events/dprintk/, and make it possible to toggle
> them on/off individually.
>
> Furthermore it would also be possible to use the user-defined per
> tracepoint filter expression facility. That way each dprintk site
> can be (optionally) tailored individually.

we currently can toggle them individually, but not by pid.

>
> For example we could enable such use:
>
> echo 'pid == 1234' > /debug/tracing/events/dprintk/fs/lockd/svc4proc.c:71/filter
> echo 1 > /debug/tracing/events/dprintk/fs/lockd/svc4proc.c:71/enabled
>
> To tailor the following dprintk() in fs/lockd/svc4proc.c (line 71):
>
> static __be32
> nlm4svc_proc_null(struct svc_rqst *rqstp, void *argp, void *resp)
> {
> dprintk("lockd: NULL called\n");
> return rpc_success;
> }
>
> To only be printed for PID 1234.
>
> Per subsystem filters would be available too. The subsystem
> maintainers dont have to do anything but place dprintk() calls -
> they'll show up under /debug/tracing/events/dprintk/ automatically.
>
> Would you be interested in this?
>

I don't think we want a tracepoint for each of these sites. note that
this facility ties into 'pr_debug' and 'dev_debug' as well...however i
think what you're suggesting is perhaps a new type of event that can
handle this case. Instead of register/unregistering to enable the event,
we can simply set a variable that is associated with each call site. is
this what you are suggesting? If so, i think this would be a nice way to
go...I would however, perhaps want an optional flag that makes these
into printk() and not trace_printk() for certain situations...

With respect to 2.6.30, I'm away next week, so maybe we can keep what we
already have for 2.6.30, and look at this integration for 2.6.31?

thanks,

-Jason