Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7a192ec3 authored by Ming Lei's avatar Ming Lei Committed by Greg Kroah-Hartman
Browse files

platform driver: fix incorrect use of 'platform_bus_type' with 'struct 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: default avatarMing Lei <tom.leiming@gmail.com>
Acked-by: default avatarHenrique de Moraes Holschuh <hmh@hmh.eng.br>
Acked-by: default avatarDavid Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 6da2d377
Loading
Loading
Loading
Loading
+13 −14
Original line number Original line Diff line number Diff line
@@ -33,8 +33,8 @@




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


static struct device_driver iodev_driver =
static struct platform_driver iodev_driver = {
{
	.driver = {
	.name		= (char *) iodev_name,
		.name		= iodev_name,
	.bus		= &platform_bus_type,
		.owner		= THIS_MODULE,
		.owner		= THIS_MODULE,
	},
	.probe		= iodev_probe,
	.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 */
/* 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 =
	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))
	if (unlikely(!ri))
		return -ENXIO;
		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);
	return misc_deregister(&miscdev);
}
}
@@ -160,14 +159,14 @@ static irqreturn_t iodev_irqhdl(int irq, void *ctxt)


static int __init iodev_init_module(void)
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)
static void __exit iodev_cleanup_module(void)
{
{
	driver_unregister(&iodev_driver);
	platform_driver_unregister(&iodev_driver);
}
}


module_init(iodev_init_module);
module_init(iodev_init_module);
+19 −9
Original line number Original line Diff line number Diff line
@@ -168,12 +168,22 @@ static void atml_plat_remove(void)
	}
	}
}
}


static struct device_driver atml_drv = {
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",
		.name = "tpm_atmel",
	.bus = &platform_bus_type,
		.owner		= THIS_MODULE,
		.owner		= THIS_MODULE,
	.suspend = tpm_pm_suspend,
	},
	.resume = tpm_pm_resume,
	.suspend = tpm_atml_suspend,
	.resume = tpm_atml_resume,
};
};


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


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


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


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


+19 −9
Original line number Original line Diff line number Diff line
@@ -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);
		    sizeof(tpm_pnp_tbl[TIS_HID_USR_IDX].id), 0444);
MODULE_PARM_DESC(hid, "Set additional specific HID for this driver to probe");
MODULE_PARM_DESC(hid, "Set additional specific HID for this driver to probe");


static struct device_driver tis_drv = {
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",
		.name = "tpm_tis",
	.bus = &platform_bus_type,
		.owner		= THIS_MODULE,
		.owner		= THIS_MODULE,
	.suspend = tpm_pm_suspend,
	},
	.resume = tpm_pm_resume,
	.suspend = tpm_tis_suspend,
	.resume = tpm_tis_resume,
};
};


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


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


	if (force) {
	if (force) {
		platform_device_unregister(pdev);
		platform_device_unregister(pdev);
		driver_unregister(&tis_drv);
		platform_driver_unregister(&tis_drv);
	} else
	} else
		pnp_unregister_driver(&tis_pnp_driver);
		pnp_unregister_driver(&tis_pnp_driver);
}
}
+18 −18
Original line number Original line Diff line number Diff line
@@ -536,9 +536,8 @@ static const struct ide_port_info au1xxx_port_info = {
#endif
#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;
	_auide_hwif *ahwif = &auide_hwif;
	struct resource *res;
	struct resource *res;
	struct ide_host *host;
	struct ide_host *host;
@@ -552,23 +551,23 @@ static int au_ide_probe(struct device *dev)
#endif
#endif


	memset(&auide_hwif, 0, sizeof(_auide_hwif));
	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) {
	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;
		ret = -ENODEV;
		goto out;
		goto out;
	}
	}
	if (ahwif->irq < 0) {
	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;
		ret = -ENODEV;
		goto out;
		goto out;
	}
	}


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


	ret = ide_host_add(&au1xxx_port_info, hws, &host);
	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];
	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 );
	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;
	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 resource *res;
	struct ide_host *host = dev_get_drvdata(dev);
	struct ide_host *host = platform_get_drvdata(dev);
	_auide_hwif *ahwif = &auide_hwif;
	_auide_hwif *ahwif = &auide_hwif;


	ide_host_remove(host);
	ide_host_remove(host);


	iounmap((void *)ahwif->regbase);
	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);
	release_mem_region(res->start, res->end - res->start + 1);


	return 0;
	return 0;
}
}


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


static int __init au_ide_init(void)
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)
static void __exit au_ide_exit(void)
{
{
	driver_unregister(&au1200_ide_driver);
	platform_driver_unregister(&au1200_ide_driver);
}
}


MODULE_LICENSE("GPL");
MODULE_LICENSE("GPL");
+19 −18
Original line number Original line Diff line number Diff line
@@ -41,9 +41,8 @@ struct pxa2xx_flash_info {
static const char *probes[] = { "RedBoot", "cmdlinepart", NULL };
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 flash_platform_data *flash = pdev->dev.platform_data;
	struct pxa2xx_flash_info *info;
	struct pxa2xx_flash_info *info;
	struct mtd_partition *parts;
	struct mtd_partition *parts;
@@ -114,15 +113,15 @@ static int __init pxa2xx_flash_probe(struct device *dev)
		add_mtd_device(info->mtd);
		add_mtd_device(info->mtd);
	}
	}


	dev_set_drvdata(dev, info);
	platform_set_drvdata(pdev, info);
	return 0;
	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
#ifdef CONFIG_MTD_PARTITIONS
	if (info->nr_parts)
	if (info->nr_parts)
@@ -141,9 +140,9 @@ static int __exit pxa2xx_flash_remove(struct device *dev)
}
}


#ifdef CONFIG_PM
#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;
	int ret = 0;


	if (info->mtd && info->mtd->suspend)
	if (info->mtd && info->mtd->suspend)
@@ -151,17 +150,17 @@ static int pxa2xx_flash_suspend(struct device *dev, pm_message_t state)
	return ret;
	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)
	if (info->mtd && info->mtd->resume)
		info->mtd->resume(info->mtd);
		info->mtd->resume(info->mtd);
	return 0;
	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)
	if (info && info->mtd->suspend(info->mtd) == 0)
		info->mtd->resume(info->mtd);
		info->mtd->resume(info->mtd);
@@ -172,11 +171,13 @@ static void pxa2xx_flash_shutdown(struct device *dev)
#define pxa2xx_flash_shutdown NULL
#define pxa2xx_flash_shutdown NULL
#endif
#endif


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


static int __init init_pxa2xx_flash(void)
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)
static void __exit cleanup_pxa2xx_flash(void)
{
{
	driver_unregister(&pxa2xx_flash_driver);
	platform_driver_unregister(&pxa2xx_flash_driver);
}
}


module_init(init_pxa2xx_flash);
module_init(init_pxa2xx_flash);
Loading