Skip to content

Commit

Permalink
platform driver: fix incorrect use of 'platform_bus_type' with 'struc…
Browse files Browse the repository at this point in the history
…t device_driver'

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 <tom.leiming@gmail.com>
Acked-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Acked-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
  • Loading branch information
Ming Lei authored and Greg Kroah-Hartman committed Mar 24, 2009
1 parent 6da2d37 commit 7a192ec
Show file tree
Hide file tree
Showing 21 changed files with 371 additions and 250 deletions.
27 changes: 13 additions & 14 deletions arch/mips/basler/excite/excite_iodev.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 *);
Expand Down Expand Up @@ -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),
};


Expand All @@ -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;
Expand All @@ -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);
}
Expand Down Expand Up @@ -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);
Expand Down
28 changes: 19 additions & 9 deletions drivers/char/tpm/tpm_atmel.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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;

Expand Down Expand Up @@ -223,13 +233,13 @@ static int __init init_atmel(void)
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();
}

Expand Down
28 changes: 19 additions & 9 deletions drivers/char/tpm/tpm_tis.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
}
Expand Down Expand Up @@ -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);
}
Expand Down
36 changes: 18 additions & 18 deletions drivers/ide/au1xxx-ide.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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);
Expand All @@ -592,46 +591,47 @@ 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 );

out:
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");
Expand Down
37 changes: 19 additions & 18 deletions drivers/mtd/maps/pxa2xx-flash.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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)
Expand All @@ -141,27 +140,27 @@ 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)
ret = info->mtd->suspend(info->mtd);
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);
Expand All @@ -172,24 +171,26 @@ 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,
};

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);
Expand Down
Loading

0 comments on commit 7a192ec

Please sign in to comment.