From 11fa8da5fb14b23ff796c09d61a162a27deeb04f Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Wed, 25 Sep 2013 20:39:46 +0800 Subject: ideapad_laptop: introduce #ifdef CONFIG_PM_SLEEP for PM specific code ideapad_acpi_resume() and ideapad_pm is meaningful only if CONFIG_PM_SLEEP is set. Thus introduce #ifdef for this piece of code. Signed-off-by: Zhang Rui CC: Matthew Garrett CC: Ike Panhc Signed-off-by: Rafael J. Wysocki --- drivers/platform/x86/ideapad-laptop.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/platform') diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c index 89c4519..5021c55 100644 --- a/drivers/platform/x86/ideapad-laptop.c +++ b/drivers/platform/x86/ideapad-laptop.c @@ -901,6 +901,7 @@ static void ideapad_acpi_notify(struct acpi_device *adevice, u32 event) } } +#ifdef CONFIG_PM_SLEEP static int ideapad_acpi_resume(struct device *device) { ideapad_sync_rfk_state(ideapad_priv); @@ -909,6 +910,7 @@ static int ideapad_acpi_resume(struct device *device) } static SIMPLE_DEV_PM_OPS(ideapad_pm, NULL, ideapad_acpi_resume); +#endif static struct acpi_driver ideapad_acpi_driver = { .name = "ideapad_acpi", @@ -917,7 +919,9 @@ static struct acpi_driver ideapad_acpi_driver = { .ops.add = ideapad_acpi_add, .ops.remove = ideapad_acpi_remove, .ops.notify = ideapad_acpi_notify, +#ifdef CONFIG_PM_SLEEP .drv.pm = &ideapad_pm, +#endif .owner = THIS_MODULE, }; module_acpi_driver(ideapad_acpi_driver); -- cgit v1.1 From 469f64349c5e7bd072d1ca5a72b8f2a80ef118f2 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Wed, 25 Sep 2013 20:39:47 +0800 Subject: ideapad_laptop: introduce struct acpi_device pointer to ideapad_private structure Introduce struct acpi_device pointer to ideapad_private structure. At the same time, replace all adevice with adev to be short and consistent. Signed-off-by: Zhang Rui CC: Matthew Garrett CC: Ike Panhc Signed-off-by: Rafael J. Wysocki --- drivers/platform/x86/ideapad-laptop.c | 48 ++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 23 deletions(-) (limited to 'drivers/platform') diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c index 5021c55..edd3656 100644 --- a/drivers/platform/x86/ideapad-laptop.c +++ b/drivers/platform/x86/ideapad-laptop.c @@ -73,6 +73,7 @@ enum { }; struct ideapad_private { + struct acpi_device *adev; struct rfkill *rfk[IDEAPAD_RFKILL_DEV_NUM]; struct platform_device *platform_device; struct input_dev *inputdev; @@ -468,9 +469,9 @@ static void ideapad_sync_rfk_state(struct ideapad_private *priv) rfkill_set_hw_state(priv->rfk[i], hw_blocked); } -static int ideapad_register_rfkill(struct acpi_device *adevice, int dev) +static int ideapad_register_rfkill(struct acpi_device *adev, int dev) { - struct ideapad_private *priv = dev_get_drvdata(&adevice->dev); + struct ideapad_private *priv = dev_get_drvdata(&adev->dev); int ret; unsigned long sw_blocked; @@ -482,7 +483,7 @@ static int ideapad_register_rfkill(struct acpi_device *adevice, int dev) return 0; } - priv->rfk[dev] = rfkill_alloc(ideapad_rfk_data[dev].name, &adevice->dev, + priv->rfk[dev] = rfkill_alloc(ideapad_rfk_data[dev].name, &adev->dev, ideapad_rfk_data[dev].type, &ideapad_rfk_ops, (void *)(long)dev); if (!priv->rfk[dev]) @@ -504,9 +505,9 @@ static int ideapad_register_rfkill(struct acpi_device *adevice, int dev) return 0; } -static void ideapad_unregister_rfkill(struct acpi_device *adevice, int dev) +static void ideapad_unregister_rfkill(struct acpi_device *adev, int dev) { - struct ideapad_private *priv = dev_get_drvdata(&adevice->dev); + struct ideapad_private *priv = dev_get_drvdata(&adev->dev); if (!priv->rfk[dev]) return; @@ -761,13 +762,13 @@ static const struct acpi_device_id ideapad_device_ids[] = { }; MODULE_DEVICE_TABLE(acpi, ideapad_device_ids); -static void ideapad_sync_touchpad_state(struct acpi_device *adevice) +static void ideapad_sync_touchpad_state(struct acpi_device *adev) { - struct ideapad_private *priv = dev_get_drvdata(&adevice->dev); + struct ideapad_private *priv = dev_get_drvdata(&adev->dev); unsigned long value; /* Without reading from EC touchpad LED doesn't switch state */ - if (!read_ec_data(adevice->handle, VPCCMD_R_TOUCHPAD, &value)) { + if (!read_ec_data(adev->handle, VPCCMD_R_TOUCHPAD, &value)) { /* Some IdeaPads don't really turn off touchpad - they only * switch the LED state. We (de)activate KBC AUX port to turn * touchpad off and on. We send KEY_TOUCHPAD_OFF and @@ -779,22 +780,23 @@ static void ideapad_sync_touchpad_state(struct acpi_device *adevice) } } -static int ideapad_acpi_add(struct acpi_device *adevice) +static int ideapad_acpi_add(struct acpi_device *adev) { int ret, i; int cfg; struct ideapad_private *priv; - if (read_method_int(adevice->handle, "_CFG", &cfg)) + if (read_method_int(adev->handle, "_CFG", &cfg)) return -ENODEV; priv = kzalloc(sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; - dev_set_drvdata(&adevice->dev, priv); + dev_set_drvdata(&adev->dev, priv); ideapad_priv = priv; - ideapad_handle = adevice->handle; + ideapad_handle = adev->handle; priv->cfg = cfg; + priv->adev = adev; ret = ideapad_platform_init(priv); if (ret) @@ -810,12 +812,12 @@ static int ideapad_acpi_add(struct acpi_device *adevice) for (i = 0; i < IDEAPAD_RFKILL_DEV_NUM; i++) { if (test_bit(ideapad_rfk_data[i].cfgbit, &priv->cfg)) - ideapad_register_rfkill(adevice, i); + ideapad_register_rfkill(adev, i); else priv->rfk[i] = NULL; } ideapad_sync_rfk_state(priv); - ideapad_sync_touchpad_state(adevice); + ideapad_sync_touchpad_state(adev); if (!acpi_video_backlight_support()) { ret = ideapad_backlight_init(priv); @@ -827,7 +829,7 @@ static int ideapad_acpi_add(struct acpi_device *adevice) backlight_failed: for (i = 0; i < IDEAPAD_RFKILL_DEV_NUM; i++) - ideapad_unregister_rfkill(adevice, i); + ideapad_unregister_rfkill(adev, i); ideapad_input_exit(priv); input_failed: ideapad_debugfs_exit(priv); @@ -838,27 +840,27 @@ platform_failed: return ret; } -static int ideapad_acpi_remove(struct acpi_device *adevice) +static int ideapad_acpi_remove(struct acpi_device *adev) { - struct ideapad_private *priv = dev_get_drvdata(&adevice->dev); + struct ideapad_private *priv = dev_get_drvdata(&adev->dev); int i; ideapad_backlight_exit(priv); for (i = 0; i < IDEAPAD_RFKILL_DEV_NUM; i++) - ideapad_unregister_rfkill(adevice, i); + ideapad_unregister_rfkill(adev, i); ideapad_input_exit(priv); ideapad_debugfs_exit(priv); ideapad_platform_exit(priv); - dev_set_drvdata(&adevice->dev, NULL); + dev_set_drvdata(&adev->dev, NULL); kfree(priv); return 0; } -static void ideapad_acpi_notify(struct acpi_device *adevice, u32 event) +static void ideapad_acpi_notify(struct acpi_device *adev, u32 event) { - struct ideapad_private *priv = dev_get_drvdata(&adevice->dev); - acpi_handle handle = adevice->handle; + struct ideapad_private *priv = dev_get_drvdata(&adev->dev); + acpi_handle handle = adev->handle; unsigned long vpc1, vpc2, vpc_bit; if (read_ec_data(handle, VPCCMD_R_VPC1, &vpc1)) @@ -880,7 +882,7 @@ static void ideapad_acpi_notify(struct acpi_device *adevice, u32 event) ideapad_input_report(priv, vpc_bit); break; case 5: - ideapad_sync_touchpad_state(adevice); + ideapad_sync_touchpad_state(adev); break; case 4: ideapad_backlight_notify_brightness(priv); -- cgit v1.1 From 75a11f11a49da9862ff2fbae75428076571cebe4 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Wed, 25 Sep 2013 20:39:48 +0800 Subject: ideapad_laptop: convert internal function calls to use ideapad_private as parameter As struct ideapad_private has all the information needed for any operations, convert ideapad_register_rfkill()/ideapad_unregister_rfkill() and ideapad_sync_touchpad_state() to use struct ideapad_private as the parameter, to be consistent with the others. Signed-off-by: Zhang Rui CC: Matthew Garrett CC: Ike Panhc Signed-off-by: Rafael J. Wysocki --- drivers/platform/x86/ideapad-laptop.c | 38 +++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 17 deletions(-) (limited to 'drivers/platform') diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c index edd3656..70fb5ba 100644 --- a/drivers/platform/x86/ideapad-laptop.c +++ b/drivers/platform/x86/ideapad-laptop.c @@ -469,9 +469,8 @@ static void ideapad_sync_rfk_state(struct ideapad_private *priv) rfkill_set_hw_state(priv->rfk[i], hw_blocked); } -static int ideapad_register_rfkill(struct acpi_device *adev, int dev) +static int ideapad_register_rfkill(struct ideapad_private *priv, int dev) { - struct ideapad_private *priv = dev_get_drvdata(&adev->dev); int ret; unsigned long sw_blocked; @@ -483,8 +482,10 @@ static int ideapad_register_rfkill(struct acpi_device *adev, int dev) return 0; } - priv->rfk[dev] = rfkill_alloc(ideapad_rfk_data[dev].name, &adev->dev, - ideapad_rfk_data[dev].type, &ideapad_rfk_ops, + priv->rfk[dev] = rfkill_alloc(ideapad_rfk_data[dev].name, + &priv->adev->dev, + ideapad_rfk_data[dev].type, + &ideapad_rfk_ops, (void *)(long)dev); if (!priv->rfk[dev]) return -ENOMEM; @@ -505,10 +506,8 @@ static int ideapad_register_rfkill(struct acpi_device *adev, int dev) return 0; } -static void ideapad_unregister_rfkill(struct acpi_device *adev, int dev) +static void ideapad_unregister_rfkill(struct ideapad_private *priv, int dev) { - struct ideapad_private *priv = dev_get_drvdata(&adev->dev); - if (!priv->rfk[dev]) return; @@ -762,13 +761,12 @@ static const struct acpi_device_id ideapad_device_ids[] = { }; MODULE_DEVICE_TABLE(acpi, ideapad_device_ids); -static void ideapad_sync_touchpad_state(struct acpi_device *adev) +static void ideapad_sync_touchpad_state(struct ideapad_private *priv) { - struct ideapad_private *priv = dev_get_drvdata(&adev->dev); unsigned long value; /* Without reading from EC touchpad LED doesn't switch state */ - if (!read_ec_data(adev->handle, VPCCMD_R_TOUCHPAD, &value)) { + if (!read_ec_data(priv->adev->handle, VPCCMD_R_TOUCHPAD, &value)) { /* Some IdeaPads don't really turn off touchpad - they only * switch the LED state. We (de)activate KBC AUX port to turn * touchpad off and on. We send KEY_TOUCHPAD_OFF and @@ -812,12 +810,12 @@ static int ideapad_acpi_add(struct acpi_device *adev) for (i = 0; i < IDEAPAD_RFKILL_DEV_NUM; i++) { if (test_bit(ideapad_rfk_data[i].cfgbit, &priv->cfg)) - ideapad_register_rfkill(adev, i); + ideapad_register_rfkill(priv, i); else priv->rfk[i] = NULL; } ideapad_sync_rfk_state(priv); - ideapad_sync_touchpad_state(adev); + ideapad_sync_touchpad_state(priv); if (!acpi_video_backlight_support()) { ret = ideapad_backlight_init(priv); @@ -829,7 +827,7 @@ static int ideapad_acpi_add(struct acpi_device *adev) backlight_failed: for (i = 0; i < IDEAPAD_RFKILL_DEV_NUM; i++) - ideapad_unregister_rfkill(adev, i); + ideapad_unregister_rfkill(priv, i); ideapad_input_exit(priv); input_failed: ideapad_debugfs_exit(priv); @@ -847,7 +845,7 @@ static int ideapad_acpi_remove(struct acpi_device *adev) ideapad_backlight_exit(priv); for (i = 0; i < IDEAPAD_RFKILL_DEV_NUM; i++) - ideapad_unregister_rfkill(adev, i); + ideapad_unregister_rfkill(priv, i); ideapad_input_exit(priv); ideapad_debugfs_exit(priv); ideapad_platform_exit(priv); @@ -882,7 +880,7 @@ static void ideapad_acpi_notify(struct acpi_device *adev, u32 event) ideapad_input_report(priv, vpc_bit); break; case 5: - ideapad_sync_touchpad_state(adev); + ideapad_sync_touchpad_state(priv); break; case 4: ideapad_backlight_notify_brightness(priv); @@ -906,8 +904,14 @@ static void ideapad_acpi_notify(struct acpi_device *adev, u32 event) #ifdef CONFIG_PM_SLEEP static int ideapad_acpi_resume(struct device *device) { - ideapad_sync_rfk_state(ideapad_priv); - ideapad_sync_touchpad_state(to_acpi_device(device)); + struct ideapad_private *priv; + + if (!device) + return -EINVAL; + priv = dev_get_drvdata(device); + + ideapad_sync_rfk_state(priv); + ideapad_sync_touchpad_state(priv); return 0; } -- cgit v1.1 From 331e0ea243ed15bbf0958f46861505f2065e99f8 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Wed, 25 Sep 2013 20:39:49 +0800 Subject: ideapad_laptop: remove ideapad_handle and ideapad_priv The current code use ideapad_handle and ideapad_priv to store some information for the ideapad device. But as they are global/static variables, the driver will be broken if there are more than one ideapad ACPI device node on a platform. Although this does not happen for now and may not happen in the future, but still, this is a software bug. Remove these two variables in this patch. Signed-off-by: Zhang Rui CC: Matthew Garrett CC: Ike Panhc Signed-off-by: Rafael J. Wysocki --- drivers/platform/x86/ideapad-laptop.c | 114 ++++++++++++++++++++-------------- 1 file changed, 69 insertions(+), 45 deletions(-) (limited to 'drivers/platform') diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c index 70fb5ba..cad48b5 100644 --- a/drivers/platform/x86/ideapad-laptop.c +++ b/drivers/platform/x86/ideapad-laptop.c @@ -72,9 +72,15 @@ enum { VPCCMD_W_BL_POWER = 0x33, }; +struct ideapad_rfk_priv { + int dev; + struct ideapad_private *priv; +}; + struct ideapad_private { struct acpi_device *adev; struct rfkill *rfk[IDEAPAD_RFKILL_DEV_NUM]; + struct ideapad_rfk_priv rfk_priv[IDEAPAD_RFKILL_DEV_NUM]; struct platform_device *platform_device; struct input_dev *inputdev; struct backlight_device *blightdev; @@ -82,8 +88,6 @@ struct ideapad_private { unsigned long cfg; }; -static acpi_handle ideapad_handle; -static struct ideapad_private *ideapad_priv; static bool no_bt_rfkill; module_param(no_bt_rfkill, bool, 0444); MODULE_PARM_DESC(no_bt_rfkill, "No rfkill for bluetooth."); @@ -201,34 +205,38 @@ static int write_ec_cmd(acpi_handle handle, int cmd, unsigned long data) */ static int debugfs_status_show(struct seq_file *s, void *data) { + struct ideapad_private *priv = s->private; unsigned long value; - if (!read_ec_data(ideapad_handle, VPCCMD_R_BL_MAX, &value)) + if (!priv) + return -EINVAL; + + if (!read_ec_data(priv->adev->handle, VPCCMD_R_BL_MAX, &value)) seq_printf(s, "Backlight max:\t%lu\n", value); - if (!read_ec_data(ideapad_handle, VPCCMD_R_BL, &value)) + if (!read_ec_data(priv->adev->handle, VPCCMD_R_BL, &value)) seq_printf(s, "Backlight now:\t%lu\n", value); - if (!read_ec_data(ideapad_handle, VPCCMD_R_BL_POWER, &value)) + if (!read_ec_data(priv->adev->handle, VPCCMD_R_BL_POWER, &value)) seq_printf(s, "BL power value:\t%s\n", value ? "On" : "Off"); seq_printf(s, "=====================\n"); - if (!read_ec_data(ideapad_handle, VPCCMD_R_RF, &value)) + if (!read_ec_data(priv->adev->handle, VPCCMD_R_RF, &value)) seq_printf(s, "Radio status:\t%s(%lu)\n", value ? "On" : "Off", value); - if (!read_ec_data(ideapad_handle, VPCCMD_R_WIFI, &value)) + if (!read_ec_data(priv->adev->handle, VPCCMD_R_WIFI, &value)) seq_printf(s, "Wifi status:\t%s(%lu)\n", value ? "On" : "Off", value); - if (!read_ec_data(ideapad_handle, VPCCMD_R_BT, &value)) + if (!read_ec_data(priv->adev->handle, VPCCMD_R_BT, &value)) seq_printf(s, "BT status:\t%s(%lu)\n", value ? "On" : "Off", value); - if (!read_ec_data(ideapad_handle, VPCCMD_R_3G, &value)) + if (!read_ec_data(priv->adev->handle, VPCCMD_R_3G, &value)) seq_printf(s, "3G status:\t%s(%lu)\n", value ? "On" : "Off", value); seq_printf(s, "=====================\n"); - if (!read_ec_data(ideapad_handle, VPCCMD_R_TOUCHPAD, &value)) + if (!read_ec_data(priv->adev->handle, VPCCMD_R_TOUCHPAD, &value)) seq_printf(s, "Touchpad status:%s(%lu)\n", value ? "On" : "Off", value); - if (!read_ec_data(ideapad_handle, VPCCMD_R_CAMERA, &value)) + if (!read_ec_data(priv->adev->handle, VPCCMD_R_CAMERA, &value)) seq_printf(s, "Camera status:\t%s(%lu)\n", value ? "On" : "Off", value); @@ -237,7 +245,7 @@ static int debugfs_status_show(struct seq_file *s, void *data) static int debugfs_status_open(struct inode *inode, struct file *file) { - return single_open(file, debugfs_status_show, NULL); + return single_open(file, debugfs_status_show, inode->i_private); } static const struct file_operations debugfs_status_fops = { @@ -250,21 +258,23 @@ static const struct file_operations debugfs_status_fops = { static int debugfs_cfg_show(struct seq_file *s, void *data) { - if (!ideapad_priv) { + struct ideapad_private *priv = s->private; + + if (!priv) { seq_printf(s, "cfg: N/A\n"); } else { seq_printf(s, "cfg: 0x%.8lX\n\nCapability: ", - ideapad_priv->cfg); - if (test_bit(CFG_BT_BIT, &ideapad_priv->cfg)) + priv->cfg); + if (test_bit(CFG_BT_BIT, &priv->cfg)) seq_printf(s, "Bluetooth "); - if (test_bit(CFG_3G_BIT, &ideapad_priv->cfg)) + if (test_bit(CFG_3G_BIT, &priv->cfg)) seq_printf(s, "3G "); - if (test_bit(CFG_WIFI_BIT, &ideapad_priv->cfg)) + if (test_bit(CFG_WIFI_BIT, &priv->cfg)) seq_printf(s, "Wireless "); - if (test_bit(CFG_CAMERA_BIT, &ideapad_priv->cfg)) + if (test_bit(CFG_CAMERA_BIT, &priv->cfg)) seq_printf(s, "Camera "); seq_printf(s, "\nGraphic: "); - switch ((ideapad_priv->cfg)&0x700) { + switch ((priv->cfg)&0x700) { case 0x100: seq_printf(s, "Intel"); break; @@ -288,7 +298,7 @@ static int debugfs_cfg_show(struct seq_file *s, void *data) static int debugfs_cfg_open(struct inode *inode, struct file *file) { - return single_open(file, debugfs_cfg_show, NULL); + return single_open(file, debugfs_cfg_show, inode->i_private); } static const struct file_operations debugfs_cfg_fops = { @@ -309,14 +319,14 @@ static int ideapad_debugfs_init(struct ideapad_private *priv) goto errout; } - node = debugfs_create_file("cfg", S_IRUGO, priv->debug, NULL, + node = debugfs_create_file("cfg", S_IRUGO, priv->debug, priv, &debugfs_cfg_fops); if (!node) { pr_err("failed to create cfg in debugfs"); goto errout; } - node = debugfs_create_file("status", S_IRUGO, priv->debug, NULL, + node = debugfs_create_file("status", S_IRUGO, priv->debug, priv, &debugfs_status_fops); if (!node) { pr_err("failed to create status in debugfs"); @@ -343,8 +353,9 @@ static ssize_t show_ideapad_cam(struct device *dev, char *buf) { unsigned long result; + struct ideapad_private *priv = dev_get_drvdata(dev); - if (read_ec_data(ideapad_handle, VPCCMD_R_CAMERA, &result)) + if (read_ec_data(priv->adev->handle, VPCCMD_R_CAMERA, &result)) return sprintf(buf, "-1\n"); return sprintf(buf, "%lu\n", result); } @@ -354,12 +365,13 @@ static ssize_t store_ideapad_cam(struct device *dev, const char *buf, size_t count) { int ret, state; + struct ideapad_private *priv = dev_get_drvdata(dev); if (!count) return 0; if (sscanf(buf, "%i", &state) != 1) return -EINVAL; - ret = write_ec_cmd(ideapad_handle, VPCCMD_W_CAMERA, state); + ret = write_ec_cmd(priv->adev->handle, VPCCMD_W_CAMERA, state); if (ret < 0) return -EIO; return count; @@ -372,8 +384,9 @@ static ssize_t show_ideapad_fan(struct device *dev, char *buf) { unsigned long result; + struct ideapad_private *priv = dev_get_drvdata(dev); - if (read_ec_data(ideapad_handle, VPCCMD_R_FAN, &result)) + if (read_ec_data(priv->adev->handle, VPCCMD_R_FAN, &result)) return sprintf(buf, "-1\n"); return sprintf(buf, "%lu\n", result); } @@ -383,6 +396,7 @@ static ssize_t store_ideapad_fan(struct device *dev, const char *buf, size_t count) { int ret, state; + struct ideapad_private *priv = dev_get_drvdata(dev); if (!count) return 0; @@ -390,7 +404,7 @@ static ssize_t store_ideapad_fan(struct device *dev, return -EINVAL; if (state < 0 || state > 4 || state == 3) return -EINVAL; - ret = write_ec_cmd(ideapad_handle, VPCCMD_W_FAN, state); + ret = write_ec_cmd(priv->adev->handle, VPCCMD_W_FAN, state); if (ret < 0) return -EIO; return count; @@ -416,7 +430,8 @@ static umode_t ideapad_is_visible(struct kobject *kobj, supported = test_bit(CFG_CAMERA_BIT, &(priv->cfg)); else if (attr == &dev_attr_fan_mode.attr) { unsigned long value; - supported = !read_ec_data(ideapad_handle, VPCCMD_R_FAN, &value); + supported = !read_ec_data(priv->adev->handle, VPCCMD_R_FAN, + &value); } else supported = true; @@ -446,9 +461,9 @@ const struct ideapad_rfk_data ideapad_rfk_data[] = { static int ideapad_rfk_set(void *data, bool blocked) { - unsigned long opcode = (unsigned long)data; + struct ideapad_rfk_priv *priv = data; - return write_ec_cmd(ideapad_handle, opcode, !blocked); + return write_ec_cmd(priv->priv->adev->handle, priv->dev, !blocked); } static struct rfkill_ops ideapad_rfk_ops = { @@ -460,7 +475,7 @@ static void ideapad_sync_rfk_state(struct ideapad_private *priv) unsigned long hw_blocked; int i; - if (read_ec_data(ideapad_handle, VPCCMD_R_RF, &hw_blocked)) + if (read_ec_data(priv->adev->handle, VPCCMD_R_RF, &hw_blocked)) return; hw_blocked = !hw_blocked; @@ -477,20 +492,22 @@ static int ideapad_register_rfkill(struct ideapad_private *priv, int dev) if (no_bt_rfkill && (ideapad_rfk_data[dev].type == RFKILL_TYPE_BLUETOOTH)) { /* Force to enable bluetooth when no_bt_rfkill=1 */ - write_ec_cmd(ideapad_handle, + write_ec_cmd(priv->adev->handle, ideapad_rfk_data[dev].opcode, 1); return 0; } + priv->rfk_priv[dev].dev = dev; + priv->rfk_priv[dev].priv = priv; priv->rfk[dev] = rfkill_alloc(ideapad_rfk_data[dev].name, &priv->adev->dev, ideapad_rfk_data[dev].type, &ideapad_rfk_ops, - (void *)(long)dev); + &priv->rfk_priv[dev]); if (!priv->rfk[dev]) return -ENOMEM; - if (read_ec_data(ideapad_handle, ideapad_rfk_data[dev].opcode-1, + if (read_ec_data(priv->adev->handle, ideapad_rfk_data[dev].opcode-1, &sw_blocked)) { rfkill_init_sw_state(priv->rfk[dev], 0); } else { @@ -623,7 +640,7 @@ static void ideapad_input_novokey(struct ideapad_private *priv) { unsigned long long_pressed; - if (read_ec_data(ideapad_handle, VPCCMD_R_NOVO, &long_pressed)) + if (read_ec_data(priv->adev->handle, VPCCMD_R_NOVO, &long_pressed)) return; if (long_pressed) ideapad_input_report(priv, 17); @@ -635,7 +652,7 @@ static void ideapad_check_special_buttons(struct ideapad_private *priv) { unsigned long bit, value; - read_ec_data(ideapad_handle, VPCCMD_R_SPECIAL_BUTTONS, &value); + read_ec_data(priv->adev->handle, VPCCMD_R_SPECIAL_BUTTONS, &value); for (bit = 0; bit < 16; bit++) { if (test_bit(bit, &value)) { @@ -662,19 +679,28 @@ static void ideapad_check_special_buttons(struct ideapad_private *priv) */ static int ideapad_backlight_get_brightness(struct backlight_device *blightdev) { + struct ideapad_private *priv = bl_get_data(blightdev); unsigned long now; - if (read_ec_data(ideapad_handle, VPCCMD_R_BL, &now)) + if (!priv) + return -EINVAL; + + if (read_ec_data(priv->adev->handle, VPCCMD_R_BL, &now)) return -EIO; return now; } static int ideapad_backlight_update_status(struct backlight_device *blightdev) { - if (write_ec_cmd(ideapad_handle, VPCCMD_W_BL, + struct ideapad_private *priv = bl_get_data(blightdev); + + if (!priv) + return -EINVAL; + + if (write_ec_cmd(priv->adev->handle, VPCCMD_W_BL, blightdev->props.brightness)) return -EIO; - if (write_ec_cmd(ideapad_handle, VPCCMD_W_BL_POWER, + if (write_ec_cmd(priv->adev->handle, VPCCMD_W_BL_POWER, blightdev->props.power == FB_BLANK_POWERDOWN ? 0 : 1)) return -EIO; @@ -692,11 +718,11 @@ static int ideapad_backlight_init(struct ideapad_private *priv) struct backlight_properties props; unsigned long max, now, power; - if (read_ec_data(ideapad_handle, VPCCMD_R_BL_MAX, &max)) + if (read_ec_data(priv->adev->handle, VPCCMD_R_BL_MAX, &max)) return -EIO; - if (read_ec_data(ideapad_handle, VPCCMD_R_BL, &now)) + if (read_ec_data(priv->adev->handle, VPCCMD_R_BL, &now)) return -EIO; - if (read_ec_data(ideapad_handle, VPCCMD_R_BL_POWER, &power)) + if (read_ec_data(priv->adev->handle, VPCCMD_R_BL_POWER, &power)) return -EIO; memset(&props, 0, sizeof(struct backlight_properties)); @@ -734,7 +760,7 @@ static void ideapad_backlight_notify_power(struct ideapad_private *priv) if (!blightdev) return; - if (read_ec_data(ideapad_handle, VPCCMD_R_BL_POWER, &power)) + if (read_ec_data(priv->adev->handle, VPCCMD_R_BL_POWER, &power)) return; blightdev->props.power = power ? FB_BLANK_UNBLANK : FB_BLANK_POWERDOWN; } @@ -745,7 +771,7 @@ static void ideapad_backlight_notify_brightness(struct ideapad_private *priv) /* if we control brightness via acpi video driver */ if (priv->blightdev == NULL) { - read_ec_data(ideapad_handle, VPCCMD_R_BL, &now); + read_ec_data(priv->adev->handle, VPCCMD_R_BL, &now); return; } @@ -791,8 +817,6 @@ static int ideapad_acpi_add(struct acpi_device *adev) if (!priv) return -ENOMEM; dev_set_drvdata(&adev->dev, priv); - ideapad_priv = priv; - ideapad_handle = adev->handle; priv->cfg = cfg; priv->adev = adev; -- cgit v1.1 From b5c37b798f2d29b9b2926e0abf008a13ce6c91fe Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Wed, 25 Sep 2013 20:39:50 +0800 Subject: ideapad_laptop: convert ideapad device/driver to platform bus This patch does two things, 1. enumerate the ideapad device node to platform bus. 2. convert the current driver from ACPI bus to platform bus. Note, with this patch, the platform device node created by ACPI, with the name VPC2004:00, is used as the parent device of the input, backlight, rfkill sysfs class device. Plus the ideapad_platform private sysfs attributes, i.e. camera_power and fan_mode, are also moved to the new platform device node. The previous platform device node "ideapad" is removed. Signed-off-by: Zhang Rui CC: Matthew Garrett CC: Ike Panhc Signed-off-by: Rafael J. Wysocki --- drivers/platform/x86/ideapad-laptop.c | 194 ++++++++++++++++------------------ 1 file changed, 92 insertions(+), 102 deletions(-) (limited to 'drivers/platform') diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c index cad48b5..6788acc 100644 --- a/drivers/platform/x86/ideapad-laptop.c +++ b/drivers/platform/x86/ideapad-laptop.c @@ -500,7 +500,7 @@ static int ideapad_register_rfkill(struct ideapad_private *priv, int dev) priv->rfk_priv[dev].priv = priv; priv->rfk[dev] = rfkill_alloc(ideapad_rfk_data[dev].name, - &priv->adev->dev, + &priv->platform_device->dev, ideapad_rfk_data[dev].type, &ideapad_rfk_ops, &priv->rfk_priv[dev]); @@ -535,37 +535,16 @@ static void ideapad_unregister_rfkill(struct ideapad_private *priv, int dev) /* * Platform device */ -static int ideapad_platform_init(struct ideapad_private *priv) +static int ideapad_sysfs_init(struct ideapad_private *priv) { - int result; - - priv->platform_device = platform_device_alloc("ideapad", -1); - if (!priv->platform_device) - return -ENOMEM; - platform_set_drvdata(priv->platform_device, priv); - - result = platform_device_add(priv->platform_device); - if (result) - goto fail_platform_device; - - result = sysfs_create_group(&priv->platform_device->dev.kobj, + return sysfs_create_group(&priv->platform_device->dev.kobj, &ideapad_attribute_group); - if (result) - goto fail_sysfs; - return 0; - -fail_sysfs: - platform_device_del(priv->platform_device); -fail_platform_device: - platform_device_put(priv->platform_device); - return result; } -static void ideapad_platform_exit(struct ideapad_private *priv) +static void ideapad_sysfs_exit(struct ideapad_private *priv) { sysfs_remove_group(&priv->platform_device->dev.kobj, &ideapad_attribute_group); - platform_device_unregister(priv->platform_device); } /* @@ -781,12 +760,6 @@ static void ideapad_backlight_notify_brightness(struct ideapad_private *priv) /* * module init/exit */ -static const struct acpi_device_id ideapad_device_ids[] = { - { "VPC2004", 0}, - { "", 0}, -}; -MODULE_DEVICE_TABLE(acpi, ideapad_device_ids); - static void ideapad_sync_touchpad_state(struct ideapad_private *priv) { unsigned long value; @@ -804,11 +777,61 @@ static void ideapad_sync_touchpad_state(struct ideapad_private *priv) } } -static int ideapad_acpi_add(struct acpi_device *adev) +static void ideapad_acpi_notify(acpi_handle handle, u32 event, void *data) +{ + struct ideapad_private *priv = data; + unsigned long vpc1, vpc2, vpc_bit; + + if (read_ec_data(handle, VPCCMD_R_VPC1, &vpc1)) + return; + if (read_ec_data(handle, VPCCMD_R_VPC2, &vpc2)) + return; + + vpc1 = (vpc2 << 8) | vpc1; + for (vpc_bit = 0; vpc_bit < 16; vpc_bit++) { + if (test_bit(vpc_bit, &vpc1)) { + switch (vpc_bit) { + case 9: + ideapad_sync_rfk_state(priv); + break; + case 13: + case 11: + case 7: + case 6: + ideapad_input_report(priv, vpc_bit); + break; + case 5: + ideapad_sync_touchpad_state(priv); + break; + case 4: + ideapad_backlight_notify_brightness(priv); + break; + case 3: + ideapad_input_novokey(priv); + break; + case 2: + ideapad_backlight_notify_power(priv); + break; + case 0: + ideapad_check_special_buttons(priv); + break; + default: + pr_info("Unknown event: %lu\n", vpc_bit); + } + } + } +} + +static int ideapad_acpi_add(struct platform_device *pdev) { int ret, i; int cfg; struct ideapad_private *priv; + struct acpi_device *adev; + + ret = acpi_bus_get_device(ACPI_HANDLE(&pdev->dev), &adev); + if (ret) + return -ENODEV; if (read_method_int(adev->handle, "_CFG", &cfg)) return -ENODEV; @@ -816,13 +839,15 @@ static int ideapad_acpi_add(struct acpi_device *adev) priv = kzalloc(sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; - dev_set_drvdata(&adev->dev, priv); + + dev_set_drvdata(&pdev->dev, priv); priv->cfg = cfg; priv->adev = adev; + priv->platform_device = pdev; - ret = ideapad_platform_init(priv); + ret = ideapad_sysfs_init(priv); if (ret) - goto platform_failed; + goto sysfs_failed; ret = ideapad_debugfs_init(priv); if (ret) @@ -846,9 +871,14 @@ static int ideapad_acpi_add(struct acpi_device *adev) if (ret && ret != -ENODEV) goto backlight_failed; } + ret = acpi_install_notify_handler(adev->handle, + ACPI_DEVICE_NOTIFY, ideapad_acpi_notify, priv); + if (ret) + goto notification_failed; return 0; - +notification_failed: + ideapad_backlight_exit(priv); backlight_failed: for (i = 0; i < IDEAPAD_RFKILL_DEV_NUM; i++) ideapad_unregister_rfkill(priv, i); @@ -856,75 +886,31 @@ backlight_failed: input_failed: ideapad_debugfs_exit(priv); debugfs_failed: - ideapad_platform_exit(priv); -platform_failed: + ideapad_sysfs_exit(priv); +sysfs_failed: kfree(priv); return ret; } -static int ideapad_acpi_remove(struct acpi_device *adev) +static int ideapad_acpi_remove(struct platform_device *pdev) { - struct ideapad_private *priv = dev_get_drvdata(&adev->dev); + struct ideapad_private *priv = dev_get_drvdata(&pdev->dev); int i; + acpi_remove_notify_handler(priv->adev->handle, + ACPI_DEVICE_NOTIFY, ideapad_acpi_notify); ideapad_backlight_exit(priv); for (i = 0; i < IDEAPAD_RFKILL_DEV_NUM; i++) ideapad_unregister_rfkill(priv, i); ideapad_input_exit(priv); ideapad_debugfs_exit(priv); - ideapad_platform_exit(priv); - dev_set_drvdata(&adev->dev, NULL); + ideapad_sysfs_exit(priv); + dev_set_drvdata(&pdev->dev, NULL); kfree(priv); return 0; } -static void ideapad_acpi_notify(struct acpi_device *adev, u32 event) -{ - struct ideapad_private *priv = dev_get_drvdata(&adev->dev); - acpi_handle handle = adev->handle; - unsigned long vpc1, vpc2, vpc_bit; - - if (read_ec_data(handle, VPCCMD_R_VPC1, &vpc1)) - return; - if (read_ec_data(handle, VPCCMD_R_VPC2, &vpc2)) - return; - - vpc1 = (vpc2 << 8) | vpc1; - for (vpc_bit = 0; vpc_bit < 16; vpc_bit++) { - if (test_bit(vpc_bit, &vpc1)) { - switch (vpc_bit) { - case 9: - ideapad_sync_rfk_state(priv); - break; - case 13: - case 11: - case 7: - case 6: - ideapad_input_report(priv, vpc_bit); - break; - case 5: - ideapad_sync_touchpad_state(priv); - break; - case 4: - ideapad_backlight_notify_brightness(priv); - break; - case 3: - ideapad_input_novokey(priv); - break; - case 2: - ideapad_backlight_notify_power(priv); - break; - case 0: - ideapad_check_special_buttons(priv); - break; - default: - pr_info("Unknown event: %lu\n", vpc_bit); - } - } - } -} - #ifdef CONFIG_PM_SLEEP static int ideapad_acpi_resume(struct device *device) { @@ -938,23 +924,27 @@ static int ideapad_acpi_resume(struct device *device) ideapad_sync_touchpad_state(priv); return 0; } - -static SIMPLE_DEV_PM_OPS(ideapad_pm, NULL, ideapad_acpi_resume); #endif +static SIMPLE_DEV_PM_OPS(ideapad_pm, NULL, ideapad_acpi_resume); -static struct acpi_driver ideapad_acpi_driver = { - .name = "ideapad_acpi", - .class = "IdeaPad", - .ids = ideapad_device_ids, - .ops.add = ideapad_acpi_add, - .ops.remove = ideapad_acpi_remove, - .ops.notify = ideapad_acpi_notify, -#ifdef CONFIG_PM_SLEEP - .drv.pm = &ideapad_pm, -#endif - .owner = THIS_MODULE, +static const struct acpi_device_id ideapad_device_ids[] = { + { "VPC2004", 0}, + { "", 0}, }; -module_acpi_driver(ideapad_acpi_driver); +MODULE_DEVICE_TABLE(acpi, ideapad_device_ids); + +static struct platform_driver ideapad_acpi_driver = { + .probe = ideapad_acpi_add, + .remove = ideapad_acpi_remove, + .driver = { + .name = "ideapad_acpi", + .owner = THIS_MODULE, + .pm = &ideapad_pm, + .acpi_match_table = ACPI_PTR(ideapad_device_ids), + }, +}; + +module_platform_driver(ideapad_acpi_driver); MODULE_AUTHOR("David Woodhouse "); MODULE_DESCRIPTION("IdeaPad ACPI Extras"); -- cgit v1.1