Commit a7f3ea72 authored by Dmitry Torokhov's avatar Dmitry Torokhov Committed by Linus Torvalds

[PATCH] dcdbas: convert to the new platform device interface

Do not use platform_device_register_simple() as it is going away, define
dcdbas_driver and implement ->probe() and ->remove() functions so manual
binding and unbinding will work with this driver.

Also switch to using attribute_group when creating sysfs attributes and
make sure to check and handle errors; explicitely remove attributes when
detaching driver.
Signed-off-by: default avatarDmitry Torokhov <dtor@mail.ru>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent d0497614
...@@ -530,30 +530,27 @@ static DCDBAS_DEV_ATTR_RW(host_control_action); ...@@ -530,30 +530,27 @@ static DCDBAS_DEV_ATTR_RW(host_control_action);
static DCDBAS_DEV_ATTR_RW(host_control_smi_type); static DCDBAS_DEV_ATTR_RW(host_control_smi_type);
static DCDBAS_DEV_ATTR_RW(host_control_on_shutdown); static DCDBAS_DEV_ATTR_RW(host_control_on_shutdown);
static struct device_attribute *dcdbas_dev_attrs[] = { static struct attribute *dcdbas_dev_attrs[] = {
&dev_attr_smi_data_buf_size, &dev_attr_smi_data_buf_size.attr,
&dev_attr_smi_data_buf_phys_addr, &dev_attr_smi_data_buf_phys_addr.attr,
&dev_attr_smi_request, &dev_attr_smi_request.attr,
&dev_attr_host_control_action, &dev_attr_host_control_action.attr,
&dev_attr_host_control_smi_type, &dev_attr_host_control_smi_type.attr,
&dev_attr_host_control_on_shutdown, &dev_attr_host_control_on_shutdown.attr,
NULL NULL
}; };
/** static struct attribute_group dcdbas_attr_group = {
* dcdbas_init: initialize driver .attrs = dcdbas_dev_attrs,
*/ };
static int __init dcdbas_init(void)
static int __devinit dcdbas_probe(struct platform_device *dev)
{ {
int i; int i, error;
host_control_action = HC_ACTION_NONE; host_control_action = HC_ACTION_NONE;
host_control_smi_type = HC_SMITYPE_NONE; host_control_smi_type = HC_SMITYPE_NONE;
dcdbas_pdev = platform_device_register_simple(DRIVER_NAME, -1, NULL, 0);
if (IS_ERR(dcdbas_pdev))
return PTR_ERR(dcdbas_pdev);
/* /*
* BIOS SMI calls require buffer addresses be in 32-bit address space. * BIOS SMI calls require buffer addresses be in 32-bit address space.
* This is done by setting the DMA mask below. * This is done by setting the DMA mask below.
...@@ -561,21 +558,81 @@ static int __init dcdbas_init(void) ...@@ -561,21 +558,81 @@ static int __init dcdbas_init(void)
dcdbas_pdev->dev.coherent_dma_mask = DMA_32BIT_MASK; dcdbas_pdev->dev.coherent_dma_mask = DMA_32BIT_MASK;
dcdbas_pdev->dev.dma_mask = &dcdbas_pdev->dev.coherent_dma_mask; dcdbas_pdev->dev.dma_mask = &dcdbas_pdev->dev.coherent_dma_mask;
register_reboot_notifier(&dcdbas_reboot_nb); error = sysfs_create_group(&dev->dev.kobj, &dcdbas_attr_group);
if (error)
return error;
for (i = 0; dcdbas_bin_attrs[i]; i++) for (i = 0; dcdbas_bin_attrs[i]; i++) {
sysfs_create_bin_file(&dcdbas_pdev->dev.kobj, error = sysfs_create_bin_file(&dev->dev.kobj,
dcdbas_bin_attrs[i]);
if (error) {
while (--i >= 0)
sysfs_remove_bin_file(&dev->dev.kobj,
dcdbas_bin_attrs[i]); dcdbas_bin_attrs[i]);
sysfs_create_group(&dev->dev.kobj, &dcdbas_attr_group);
return error;
}
}
for (i = 0; dcdbas_dev_attrs[i]; i++) register_reboot_notifier(&dcdbas_reboot_nb);
device_create_file(&dcdbas_pdev->dev, dcdbas_dev_attrs[i]);
dev_info(&dcdbas_pdev->dev, "%s (version %s)\n", dev_info(&dev->dev, "%s (version %s)\n",
DRIVER_DESCRIPTION, DRIVER_VERSION); DRIVER_DESCRIPTION, DRIVER_VERSION);
return 0; return 0;
} }
static int __devexit dcdbas_remove(struct platform_device *dev)
{
int i;
unregister_reboot_notifier(&dcdbas_reboot_nb);
for (i = 0; dcdbas_bin_attrs[i]; i++)
sysfs_remove_bin_file(&dev->dev.kobj, dcdbas_bin_attrs[i]);
sysfs_remove_group(&dev->dev.kobj, &dcdbas_attr_group);
return 0;
}
static struct platform_driver dcdbas_driver = {
.driver = {
.name = DRIVER_NAME,
.owner = THIS_MODULE,
},
.probe = dcdbas_probe,
.remove = __devexit_p(dcdbas_remove),
};
/**
* dcdbas_init: initialize driver
*/
static int __init dcdbas_init(void)
{
int error;
error = platform_driver_register(&dcdbas_driver);
if (error)
return error;
dcdbas_pdev = platform_device_alloc(DRIVER_NAME, -1);
if (!dcdbas_pdev) {
error = -ENOMEM;
goto err_unregister_driver;
}
error = platform_device_add(dcdbas_pdev);
if (error)
goto err_free_device;
return 0;
err_free_device:
platform_device_put(dcdbas_pdev);
err_unregister_driver:
platform_driver_unregister(&dcdbas_driver);
return error;
}
/** /**
* dcdbas_exit: perform driver cleanup * dcdbas_exit: perform driver cleanup
*/ */
...@@ -588,6 +645,15 @@ static void __exit dcdbas_exit(void) ...@@ -588,6 +645,15 @@ static void __exit dcdbas_exit(void)
unregister_reboot_notifier(&dcdbas_reboot_nb); unregister_reboot_notifier(&dcdbas_reboot_nb);
smi_data_buf_free(); smi_data_buf_free();
platform_device_unregister(dcdbas_pdev); platform_device_unregister(dcdbas_pdev);
platform_driver_unregister(&dcdbas_driver);
/*
* We have to free the buffer here instead of dcdbas_remove
* because only in module exit function we can be sure that
* all sysfs attributes belonging to this module have been
* released.
*/
smi_data_buf_free();
} }
module_init(dcdbas_init); module_init(dcdbas_init);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment