hwmon: (ibmpowernv) Use platform 'id_table' to probe the device

The current driver probe() function assumes the sensor device to be
always present and gets executed every time if the driver is loaded,
but the appropriate hardware could not be present.

So, move the platform device creation as part of platform init code
and use the 'id_table' to check if the device is present or not.

Signed-off-by: Neelesh Gupta <neelegup@linux.vnet.ibm.com>
Acked-by: Michael Ellerman <mpe@ellerman.id.au>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
This commit is contained in:
Neelesh Gupta 2014-11-05 16:45:14 +05:30 committed by Guenter Roeck
parent 61bb53bcbd
commit 8de303bae4
2 changed files with 39 additions and 48 deletions

View File

@ -20,7 +20,9 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/of_platform.h>
#include <asm/opal.h> #include <asm/opal.h>
#include <asm/machdep.h>
static DEFINE_MUTEX(opal_sensor_mutex); static DEFINE_MUTEX(opal_sensor_mutex);
@ -64,3 +66,21 @@ int opal_get_sensor_data(u32 sensor_hndl, u32 *sensor_data)
return ret; return ret;
} }
EXPORT_SYMBOL_GPL(opal_get_sensor_data); EXPORT_SYMBOL_GPL(opal_get_sensor_data);
static __init int opal_sensor_init(void)
{
struct platform_device *pdev;
struct device_node *sensor;
sensor = of_find_node_by_path("/ibm,opal/sensors");
if (!sensor) {
pr_err("Opal node 'sensors' not found\n");
return -ENODEV;
}
pdev = of_platform_device_create(sensor, "opal-sensor", NULL);
of_node_put(sensor);
return PTR_ERR_OR_ZERO(pdev);
}
machine_subsys_initcall(powernv, opal_sensor_init);

View File

@ -74,9 +74,6 @@ struct platform_data {
u32 sensors_count; /* Total count of sensors from each group */ u32 sensors_count; /* Total count of sensors from each group */
}; };
/* Platform device representing all the ibmpowernv sensors */
static struct platform_device *pdevice;
static ssize_t show_sensor(struct device *dev, struct device_attribute *devattr, static ssize_t show_sensor(struct device *dev, struct device_attribute *devattr,
char *buf) char *buf)
{ {
@ -99,7 +96,7 @@ static ssize_t show_sensor(struct device *dev, struct device_attribute *devattr,
return sprintf(buf, "%u\n", x); return sprintf(buf, "%u\n", x);
} }
static int __init get_sensor_index_attr(const char *name, u32 *index, static int get_sensor_index_attr(const char *name, u32 *index,
char *attr) char *attr)
{ {
char *hash_pos = strchr(name, '#'); char *hash_pos = strchr(name, '#');
@ -136,7 +133,7 @@ static int __init get_sensor_index_attr(const char *name, u32 *index,
* which need to be mapped as fan2_input, temp1_max respectively before * which need to be mapped as fan2_input, temp1_max respectively before
* populating them inside hwmon device class. * populating them inside hwmon device class.
*/ */
static int __init create_hwmon_attr_name(struct device *dev, enum sensors type, static int create_hwmon_attr_name(struct device *dev, enum sensors type,
const char *node_name, const char *node_name,
char *hwmon_attr_name) char *hwmon_attr_name)
{ {
@ -172,7 +169,7 @@ static int __init create_hwmon_attr_name(struct device *dev, enum sensors type,
return 0; return 0;
} }
static int __init populate_attr_groups(struct platform_device *pdev) static int populate_attr_groups(struct platform_device *pdev)
{ {
struct platform_data *pdata = platform_get_drvdata(pdev); struct platform_data *pdata = platform_get_drvdata(pdev);
const struct attribute_group **pgroups = pdata->attr_groups; const struct attribute_group **pgroups = pdata->attr_groups;
@ -180,11 +177,6 @@ static int __init populate_attr_groups(struct platform_device *pdev)
enum sensors type; enum sensors type;
opal = of_find_node_by_path("/ibm,opal/sensors"); opal = of_find_node_by_path("/ibm,opal/sensors");
if (!opal) {
dev_dbg(&pdev->dev, "Opal node 'sensors' not found\n");
return -ENODEV;
}
for_each_child_of_node(opal, np) { for_each_child_of_node(opal, np) {
if (np->name == NULL) if (np->name == NULL)
continue; continue;
@ -221,7 +213,7 @@ static int __init populate_attr_groups(struct platform_device *pdev)
* to the name required by the higher 'hwmon' driver like fan1_input, temp1_max * to the name required by the higher 'hwmon' driver like fan1_input, temp1_max
* etc.. * etc..
*/ */
static int __init create_device_attrs(struct platform_device *pdev) static int create_device_attrs(struct platform_device *pdev)
{ {
struct platform_data *pdata = platform_get_drvdata(pdev); struct platform_data *pdata = platform_get_drvdata(pdev);
const struct attribute_group **pgroups = pdata->attr_groups; const struct attribute_group **pgroups = pdata->attr_groups;
@ -280,7 +272,7 @@ static int __init create_device_attrs(struct platform_device *pdev)
return err; return err;
} }
static int __init ibmpowernv_probe(struct platform_device *pdev) static int ibmpowernv_probe(struct platform_device *pdev)
{ {
struct platform_data *pdata; struct platform_data *pdata;
struct device *hwmon_dev; struct device *hwmon_dev;
@ -309,52 +301,31 @@ static int __init ibmpowernv_probe(struct platform_device *pdev)
return PTR_ERR_OR_ZERO(hwmon_dev); return PTR_ERR_OR_ZERO(hwmon_dev);
} }
static const struct platform_device_id opal_sensor_driver_ids[] = {
{
.name = "opal-sensor",
},
{ }
};
MODULE_DEVICE_TABLE(platform, opal_sensor_driver_ids);
static struct platform_driver ibmpowernv_driver = { static struct platform_driver ibmpowernv_driver = {
.driver = { .probe = ibmpowernv_probe,
.owner = THIS_MODULE, .id_table = opal_sensor_driver_ids,
.name = DRVNAME, .driver = {
.owner = THIS_MODULE,
.name = DRVNAME,
}, },
}; };
static int __init ibmpowernv_init(void) static int __init ibmpowernv_init(void)
{ {
int err; return platform_driver_register(&ibmpowernv_driver);
pdevice = platform_device_alloc(DRVNAME, 0);
if (!pdevice) {
pr_err("Device allocation failed\n");
err = -ENOMEM;
goto exit;
}
err = platform_device_add(pdevice);
if (err) {
pr_err("Device addition failed (%d)\n", err);
goto exit_device_put;
}
err = platform_driver_probe(&ibmpowernv_driver, ibmpowernv_probe);
if (err) {
if (err != -ENODEV)
pr_err("Platform driver probe failed (%d)\n", err);
goto exit_device_del;
}
return 0;
exit_device_del:
platform_device_del(pdevice);
exit_device_put:
platform_device_put(pdevice);
exit:
return err;
} }
static void __exit ibmpowernv_exit(void) static void __exit ibmpowernv_exit(void)
{ {
platform_driver_unregister(&ibmpowernv_driver); platform_driver_unregister(&ibmpowernv_driver);
platform_device_unregister(pdevice);
} }
MODULE_AUTHOR("Neelesh Gupta <neelegup@linux.vnet.ibm.com>"); MODULE_AUTHOR("Neelesh Gupta <neelegup@linux.vnet.ibm.com>");