Skip to content

Commit

Permalink
[PATCH] dcdbas: convert to the new platform device interface
Browse files Browse the repository at this point in the history
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: Dmitry Torokhov <dtor@mail.ru>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
  • Loading branch information
Dmitry Torokhov authored and Linus Torvalds committed Mar 22, 2006
1 parent d049761 commit a7f3ea7
Showing 1 changed file with 88 additions and 22 deletions.
110 changes: 88 additions & 22 deletions drivers/firmware/dcdbas.c
Original file line number Diff line number Diff line change
Expand Up @@ -530,50 +530,107 @@ static DCDBAS_DEV_ATTR_RW(host_control_action);
static DCDBAS_DEV_ATTR_RW(host_control_smi_type);
static DCDBAS_DEV_ATTR_RW(host_control_on_shutdown);

static struct device_attribute *dcdbas_dev_attrs[] = {
&dev_attr_smi_data_buf_size,
&dev_attr_smi_data_buf_phys_addr,
&dev_attr_smi_request,
&dev_attr_host_control_action,
&dev_attr_host_control_smi_type,
&dev_attr_host_control_on_shutdown,
static struct attribute *dcdbas_dev_attrs[] = {
&dev_attr_smi_data_buf_size.attr,
&dev_attr_smi_data_buf_phys_addr.attr,
&dev_attr_smi_request.attr,
&dev_attr_host_control_action.attr,
&dev_attr_host_control_smi_type.attr,
&dev_attr_host_control_on_shutdown.attr,
NULL
};

/**
* dcdbas_init: initialize driver
*/
static int __init dcdbas_init(void)
static struct attribute_group dcdbas_attr_group = {
.attrs = dcdbas_dev_attrs,
};

static int __devinit dcdbas_probe(struct platform_device *dev)
{
int i;
int i, error;

host_control_action = HC_ACTION_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.
* This is done by setting the DMA mask below.
*/
dcdbas_pdev->dev.coherent_dma_mask = DMA_32BIT_MASK;
dcdbas_pdev->dev.dma_mask = &dcdbas_pdev->dev.coherent_dma_mask;

error = sysfs_create_group(&dev->dev.kobj, &dcdbas_attr_group);
if (error)
return error;

for (i = 0; dcdbas_bin_attrs[i]; i++) {
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]);
sysfs_create_group(&dev->dev.kobj, &dcdbas_attr_group);
return error;
}
}

register_reboot_notifier(&dcdbas_reboot_nb);

dev_info(&dev->dev, "%s (version %s)\n",
DRIVER_DESCRIPTION, DRIVER_VERSION);

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_create_bin_file(&dcdbas_pdev->dev.kobj,
dcdbas_bin_attrs[i]);
sysfs_remove_bin_file(&dev->dev.kobj, dcdbas_bin_attrs[i]);
sysfs_remove_group(&dev->dev.kobj, &dcdbas_attr_group);

for (i = 0; dcdbas_dev_attrs[i]; i++)
device_create_file(&dcdbas_pdev->dev, dcdbas_dev_attrs[i]);
return 0;
}

dev_info(&dcdbas_pdev->dev, "%s (version %s)\n",
DRIVER_DESCRIPTION, DRIVER_VERSION);
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;
}

/**
Expand All @@ -588,6 +645,15 @@ static void __exit dcdbas_exit(void)
unregister_reboot_notifier(&dcdbas_reboot_nb);
smi_data_buf_free();
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);
Expand Down

0 comments on commit a7f3ea7

Please sign in to comment.