Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

platform/x86: thinkpad_acpi: Convert platform driver to use dev_groups

Platform drivers have the option of having the platform core create and
remove any needed sysfs attribute files. So take advantage of that and
refactor the attributes management to avoid to register them "by hand".

Also, due to some attributes are optionals, refactor the code and move
the logic inside the "is_visible" callbacks of the attribute_group
structures.

Suggested-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Len Baker <len.baker@gmx.com>
Link: https://lore.kernel.org/r/20211023154036.6800-1-len.baker@gmx.com
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>

authored by

Len Baker and committed by
Hans de Goede
79f960e2 d477a907

+244 -284
+244 -284
drivers/platform/x86/thinkpad_acpi.c
··· 332 332 u32 battery_force_primary:1; 333 333 u32 input_device_registered:1; 334 334 u32 platform_drv_registered:1; 335 - u32 platform_drv_attrs_registered:1; 336 335 u32 sensors_pdrv_registered:1; 337 - u32 sensors_pdrv_attrs_registered:1; 338 336 u32 sensors_pdev_attrs_registered:1; 339 337 u32 hotkey_poll_active:1; 340 338 u32 has_adaptive_kbd:1; 339 + u32 kbd_lang:1; 341 340 } tp_features; 342 341 343 342 static struct { ··· 982 983 } 983 984 } 984 985 985 - static struct platform_driver tpacpi_pdriver = { 986 - .driver = { 987 - .name = TPACPI_DRVR_NAME, 988 - .pm = &tpacpi_pm, 989 - }, 990 - .shutdown = tpacpi_shutdown_handler, 991 - }; 992 - 993 - static struct platform_driver tpacpi_hwmon_pdriver = { 994 - .driver = { 995 - .name = TPACPI_HWMON_DRVR_NAME, 996 - }, 997 - }; 998 - 999 986 /************************************************************************* 1000 987 * sysfs support helpers 1001 988 */ ··· 1463 1478 } 1464 1479 static DRIVER_ATTR_RW(uwb_emulstate); 1465 1480 #endif 1466 - 1467 - /* --------------------------------------------------------------------- */ 1468 - 1469 - static struct driver_attribute *tpacpi_driver_attributes[] = { 1470 - &driver_attr_debug_level, &driver_attr_version, 1471 - &driver_attr_interface_version, 1472 - }; 1473 - 1474 - static int __init tpacpi_create_driver_attributes(struct device_driver *drv) 1475 - { 1476 - int i, res; 1477 - 1478 - i = 0; 1479 - res = 0; 1480 - while (!res && i < ARRAY_SIZE(tpacpi_driver_attributes)) { 1481 - res = driver_create_file(drv, tpacpi_driver_attributes[i]); 1482 - i++; 1483 - } 1484 - 1485 - #ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES 1486 - if (!res && dbg_wlswemul) 1487 - res = driver_create_file(drv, &driver_attr_wlsw_emulstate); 1488 - if (!res && dbg_bluetoothemul) 1489 - res = driver_create_file(drv, &driver_attr_bluetooth_emulstate); 1490 - if (!res && dbg_wwanemul) 1491 - res = driver_create_file(drv, &driver_attr_wwan_emulstate); 1492 - if (!res && dbg_uwbemul) 1493 - res = driver_create_file(drv, &driver_attr_uwb_emulstate); 1494 - #endif 1495 - 1496 - return res; 1497 - } 1498 - 1499 - static void tpacpi_remove_driver_attributes(struct device_driver *drv) 1500 - { 1501 - int i; 1502 - 1503 - for (i = 0; i < ARRAY_SIZE(tpacpi_driver_attributes); i++) 1504 - driver_remove_file(drv, tpacpi_driver_attributes[i]); 1505 - 1506 - #ifdef THINKPAD_ACPI_DEBUGFACILITIES 1507 - driver_remove_file(drv, &driver_attr_wlsw_emulstate); 1508 - driver_remove_file(drv, &driver_attr_bluetooth_emulstate); 1509 - driver_remove_file(drv, &driver_attr_wwan_emulstate); 1510 - driver_remove_file(drv, &driver_attr_uwb_emulstate); 1511 - #endif 1512 - } 1513 1481 1514 1482 /************************************************************************* 1515 1483 * Firmware Data ··· 2937 2999 NULL 2938 3000 }; 2939 3001 3002 + static umode_t hadaptive_kbd_attr_is_visible(struct kobject *kobj, 3003 + struct attribute *attr, int n) 3004 + { 3005 + return tp_features.has_adaptive_kbd ? attr->mode : 0; 3006 + } 3007 + 2940 3008 static const struct attribute_group adaptive_kbd_attr_group = { 3009 + .is_visible = hadaptive_kbd_attr_is_visible, 2941 3010 .attrs = adaptive_kbd_attributes, 2942 3011 }; 2943 3012 ··· 3039 3094 hotkey_poll_stop_sync(); 3040 3095 mutex_unlock(&hotkey_mutex); 3041 3096 #endif 3042 - sysfs_remove_group(&tpacpi_pdev->dev.kobj, &hotkey_attr_group); 3043 - 3044 3097 dbg_printk(TPACPI_DBG_EXIT | TPACPI_DBG_HKEY, 3045 3098 "restoring original HKEY status and mask\n"); 3046 3099 /* yes, there is a bitwise or below, we want the ··· 3433 3490 */ 3434 3491 if (acpi_evalf(hkey_handle, &hotkey_adaptive_all_mask, 3435 3492 "MHKA", "dd", 2)) { 3436 - if (hotkey_adaptive_all_mask != 0) { 3493 + if (hotkey_adaptive_all_mask != 0) 3437 3494 tp_features.has_adaptive_kbd = true; 3438 - res = sysfs_create_group( 3439 - &tpacpi_pdev->dev.kobj, 3440 - &adaptive_kbd_attr_group); 3441 - if (res) 3442 - goto err_exit; 3443 - } 3444 3495 } else { 3445 3496 tp_features.has_adaptive_kbd = false; 3446 3497 hotkey_adaptive_all_mask = 0x0U; ··· 3488 3551 } 3489 3552 3490 3553 tabletsw_state = hotkey_init_tablet_mode(); 3491 - res = sysfs_create_group(&tpacpi_pdev->dev.kobj, &hotkey_attr_group); 3492 - if (res) 3493 - goto err_exit; 3494 3554 3495 3555 /* Set up key map */ 3496 3556 keymap_id = tpacpi_check_quirks(tpacpi_keymap_qtable, ··· 3584 3650 return 0; 3585 3651 3586 3652 err_exit: 3587 - sysfs_remove_group(&tpacpi_pdev->dev.kobj, &hotkey_attr_group); 3588 - sysfs_remove_group(&tpacpi_pdev->dev.kobj, &adaptive_kbd_attr_group); 3589 - 3590 3653 return (res < 0) ? res : 1; 3591 3654 } 3592 3655 ··· 4315 4384 NULL 4316 4385 }; 4317 4386 4387 + static umode_t bluetooth_attr_is_visible(struct kobject *kobj, 4388 + struct attribute *attr, int n) 4389 + { 4390 + return tp_features.bluetooth ? attr->mode : 0; 4391 + } 4392 + 4318 4393 static const struct attribute_group bluetooth_attr_group = { 4394 + .is_visible = bluetooth_attr_is_visible, 4319 4395 .attrs = bluetooth_attributes, 4320 4396 }; 4321 4397 ··· 4344 4406 4345 4407 static void bluetooth_exit(void) 4346 4408 { 4347 - sysfs_remove_group(&tpacpi_pdev->dev.kobj, 4348 - &bluetooth_attr_group); 4349 - 4350 4409 tpacpi_destroy_rfkill(TPACPI_RFK_BLUETOOTH_SW_ID); 4351 - 4352 4410 bluetooth_shutdown(); 4353 4411 } 4354 4412 ··· 4458 4524 RFKILL_TYPE_BLUETOOTH, 4459 4525 TPACPI_RFK_BLUETOOTH_SW_NAME, 4460 4526 true); 4461 - if (res) 4462 - return res; 4463 - 4464 - res = sysfs_create_group(&tpacpi_pdev->dev.kobj, 4465 - &bluetooth_attr_group); 4466 - if (res) { 4467 - tpacpi_destroy_rfkill(TPACPI_RFK_BLUETOOTH_SW_ID); 4468 - return res; 4469 - } 4470 - 4471 - return 0; 4527 + return res; 4472 4528 } 4473 4529 4474 4530 /* procfs -------------------------------------------------------------- */ ··· 4565 4641 NULL 4566 4642 }; 4567 4643 4644 + static umode_t wan_attr_is_visible(struct kobject *kobj, struct attribute *attr, 4645 + int n) 4646 + { 4647 + return tp_features.wan ? attr->mode : 0; 4648 + } 4649 + 4568 4650 static const struct attribute_group wan_attr_group = { 4651 + .is_visible = wan_attr_is_visible, 4569 4652 .attrs = wan_attributes, 4570 4653 }; 4571 4654 ··· 4594 4663 4595 4664 static void wan_exit(void) 4596 4665 { 4597 - sysfs_remove_group(&tpacpi_pdev->dev.kobj, 4598 - &wan_attr_group); 4599 - 4600 4666 tpacpi_destroy_rfkill(TPACPI_RFK_WWAN_SW_ID); 4601 - 4602 4667 wan_shutdown(); 4603 4668 } 4604 4669 ··· 4638 4711 RFKILL_TYPE_WWAN, 4639 4712 TPACPI_RFK_WWAN_SW_NAME, 4640 4713 true); 4641 - if (res) 4642 - return res; 4643 - 4644 - res = sysfs_create_group(&tpacpi_pdev->dev.kobj, 4645 - &wan_attr_group); 4646 - 4647 - if (res) { 4648 - tpacpi_destroy_rfkill(TPACPI_RFK_WWAN_SW_ID); 4649 - return res; 4650 - } 4651 - 4652 - return 0; 4714 + return res; 4653 4715 } 4654 4716 4655 4717 /* procfs -------------------------------------------------------------- */ ··· 5539 5623 5540 5624 static DEVICE_ATTR_WO(cmos_command); 5541 5625 5626 + static struct attribute *cmos_attributes[] = { 5627 + &dev_attr_cmos_command.attr, 5628 + NULL 5629 + }; 5630 + 5631 + static umode_t cmos_attr_is_visible(struct kobject *kobj, 5632 + struct attribute *attr, int n) 5633 + { 5634 + return cmos_handle ? attr->mode : 0; 5635 + } 5636 + 5637 + static const struct attribute_group cmos_attr_group = { 5638 + .is_visible = cmos_attr_is_visible, 5639 + .attrs = cmos_attributes, 5640 + }; 5641 + 5542 5642 /* --------------------------------------------------------------------- */ 5543 5643 5544 5644 static int __init cmos_init(struct ibm_init_struct *iibm) 5545 5645 { 5546 - int res; 5547 - 5548 5646 vdbg_printk(TPACPI_DBG_INIT, 5549 - "initializing cmos commands subdriver\n"); 5647 + "initializing cmos commands subdriver\n"); 5550 5648 5551 5649 TPACPI_ACPIHANDLE_INIT(cmos); 5552 5650 5553 5651 vdbg_printk(TPACPI_DBG_INIT, "cmos commands are %s\n", 5554 - str_supported(cmos_handle != NULL)); 5652 + str_supported(cmos_handle != NULL)); 5555 5653 5556 - res = device_create_file(&tpacpi_pdev->dev, &dev_attr_cmos_command); 5557 - if (res) 5558 - return res; 5559 - 5560 - return (cmos_handle) ? 0 : 1; 5561 - } 5562 - 5563 - static void cmos_exit(void) 5564 - { 5565 - device_remove_file(&tpacpi_pdev->dev, &dev_attr_cmos_command); 5654 + return cmos_handle ? 0 : 1; 5566 5655 } 5567 5656 5568 5657 static int cmos_read(struct seq_file *m) ··· 5608 5687 .name = "cmos", 5609 5688 .read = cmos_read, 5610 5689 .write = cmos_write, 5611 - .exit = cmos_exit, 5612 5690 }; 5613 5691 5614 5692 /************************************************************************* ··· 6118 6198 }; 6119 6199 6120 6200 static enum thermal_access_mode thermal_read_mode; 6121 - static const struct attribute_group *thermal_attr_group; 6122 6201 static bool thermal_use_labels; 6123 6202 6124 6203 /* idx is zero-based */ ··· 6290 6371 NULL 6291 6372 }; 6292 6373 6293 - static const struct attribute_group thermal_temp_input16_group = { 6294 - .attrs = thermal_temp_input_attr 6295 - }; 6374 + static umode_t thermal_attr_is_visible(struct kobject *kobj, 6375 + struct attribute *attr, int n) 6376 + { 6377 + if (thermal_read_mode == TPACPI_THERMAL_NONE) 6378 + return 0; 6296 6379 6297 - static const struct attribute_group thermal_temp_input8_group = { 6298 - .attrs = &thermal_temp_input_attr[8] 6380 + if (attr == THERMAL_ATTRS(8) || attr == THERMAL_ATTRS(9) || 6381 + attr == THERMAL_ATTRS(10) || attr == THERMAL_ATTRS(11) || 6382 + attr == THERMAL_ATTRS(12) || attr == THERMAL_ATTRS(13) || 6383 + attr == THERMAL_ATTRS(14) || attr == THERMAL_ATTRS(15)) { 6384 + if (thermal_read_mode != TPACPI_THERMAL_TPEC_16) 6385 + return 0; 6386 + } 6387 + 6388 + return attr->mode; 6389 + } 6390 + 6391 + static const struct attribute_group thermal_attr_group = { 6392 + .is_visible = thermal_attr_is_visible, 6393 + .attrs = thermal_temp_input_attr, 6299 6394 }; 6300 6395 6301 6396 #undef THERMAL_SENSOR_ATTR_TEMP ··· 6333 6400 NULL 6334 6401 }; 6335 6402 6403 + static umode_t temp_label_attr_is_visible(struct kobject *kobj, 6404 + struct attribute *attr, int n) 6405 + { 6406 + return thermal_use_labels ? attr->mode : 0; 6407 + } 6408 + 6336 6409 static const struct attribute_group temp_label_attr_group = { 6410 + .is_visible = temp_label_attr_is_visible, 6337 6411 .attrs = temp_label_attributes, 6338 6412 }; 6339 6413 ··· 6351 6411 u8 t, ta1, ta2, ver = 0; 6352 6412 int i; 6353 6413 int acpi_tmp7; 6354 - int res; 6355 6414 6356 6415 vdbg_printk(TPACPI_DBG_INIT, "initializing thermal subdriver\n"); 6357 6416 ··· 6425 6486 str_supported(thermal_read_mode != TPACPI_THERMAL_NONE), 6426 6487 thermal_read_mode); 6427 6488 6428 - switch (thermal_read_mode) { 6429 - case TPACPI_THERMAL_TPEC_16: 6430 - thermal_attr_group = &thermal_temp_input16_group; 6431 - break; 6432 - case TPACPI_THERMAL_TPEC_8: 6433 - case TPACPI_THERMAL_ACPI_TMP07: 6434 - case TPACPI_THERMAL_ACPI_UPDT: 6435 - thermal_attr_group = &thermal_temp_input8_group; 6436 - break; 6437 - case TPACPI_THERMAL_NONE: 6438 - default: 6439 - return 1; 6440 - } 6441 - 6442 - res = sysfs_create_group(&tpacpi_hwmon->kobj, thermal_attr_group); 6443 - if (res) 6444 - return res; 6445 - 6446 - if (thermal_use_labels) { 6447 - res = sysfs_create_group(&tpacpi_hwmon->kobj, &temp_label_attr_group); 6448 - if (res) { 6449 - sysfs_remove_group(&tpacpi_hwmon->kobj, thermal_attr_group); 6450 - return res; 6451 - } 6452 - } 6453 - 6454 - return 0; 6455 - } 6456 - 6457 - static void thermal_exit(void) 6458 - { 6459 - if (thermal_attr_group) 6460 - sysfs_remove_group(&tpacpi_hwmon->kobj, thermal_attr_group); 6461 - 6462 - if (thermal_use_labels) 6463 - sysfs_remove_group(&tpacpi_hwmon->kobj, &temp_label_attr_group); 6489 + return thermal_read_mode == TPACPI_THERMAL_NONE ? 1 : 0; 6464 6490 } 6465 6491 6466 6492 static int thermal_read(struct seq_file *m) ··· 6452 6548 static struct ibm_struct thermal_driver_data = { 6453 6549 .name = "thermal", 6454 6550 .read = thermal_read, 6455 - .exit = thermal_exit, 6456 6551 }; 6457 6552 6458 6553 /************************************************************************* ··· 8626 8723 static DRIVER_ATTR_RW(fan_watchdog); 8627 8724 8628 8725 /* --------------------------------------------------------------------- */ 8726 + 8629 8727 static struct attribute *fan_attributes[] = { 8630 - &dev_attr_pwm1_enable.attr, &dev_attr_pwm1.attr, 8728 + &dev_attr_pwm1_enable.attr, 8729 + &dev_attr_pwm1.attr, 8631 8730 &dev_attr_fan1_input.attr, 8632 - NULL, /* for fan2_input */ 8731 + &dev_attr_fan2_input.attr, 8732 + &driver_attr_fan_watchdog.attr, 8633 8733 NULL 8634 8734 }; 8635 8735 8736 + static umode_t fan_attr_is_visible(struct kobject *kobj, struct attribute *attr, 8737 + int n) 8738 + { 8739 + if (fan_status_access_mode == TPACPI_FAN_NONE && 8740 + fan_control_access_mode == TPACPI_FAN_WR_NONE) 8741 + return 0; 8742 + 8743 + if (attr == &dev_attr_fan2_input.attr) { 8744 + if (!tp_features.second_fan) 8745 + return 0; 8746 + } 8747 + 8748 + return attr->mode; 8749 + } 8750 + 8636 8751 static const struct attribute_group fan_attr_group = { 8752 + .is_visible = fan_attr_is_visible, 8637 8753 .attrs = fan_attributes, 8638 8754 }; 8639 8755 ··· 8683 8761 8684 8762 static int __init fan_init(struct ibm_init_struct *iibm) 8685 8763 { 8686 - int rc; 8687 8764 unsigned long quirks; 8688 8765 8689 8766 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_FAN, ··· 8779 8858 fan_get_status_safe(NULL); 8780 8859 8781 8860 if (fan_status_access_mode != TPACPI_FAN_NONE || 8782 - fan_control_access_mode != TPACPI_FAN_WR_NONE) { 8783 - if (tp_features.second_fan) { 8784 - /* attach second fan tachometer */ 8785 - fan_attributes[ARRAY_SIZE(fan_attributes)-2] = 8786 - &dev_attr_fan2_input.attr; 8787 - } 8788 - rc = sysfs_create_group(&tpacpi_hwmon->kobj, 8789 - &fan_attr_group); 8790 - if (rc < 0) 8791 - return rc; 8792 - 8793 - rc = driver_create_file(&tpacpi_hwmon_pdriver.driver, 8794 - &driver_attr_fan_watchdog); 8795 - if (rc < 0) { 8796 - sysfs_remove_group(&tpacpi_hwmon->kobj, 8797 - &fan_attr_group); 8798 - return rc; 8799 - } 8861 + fan_control_access_mode != TPACPI_FAN_WR_NONE) 8800 8862 return 0; 8801 - } else 8802 - return 1; 8863 + 8864 + return 1; 8803 8865 } 8804 8866 8805 8867 static void fan_exit(void) 8806 8868 { 8807 8869 vdbg_printk(TPACPI_DBG_EXIT | TPACPI_DBG_FAN, 8808 8870 "cancelling any pending fan watchdog tasks\n"); 8809 - 8810 - /* FIXME: can we really do this unconditionally? */ 8811 - sysfs_remove_group(&tpacpi_hwmon->kobj, &fan_attr_group); 8812 - driver_remove_file(&tpacpi_hwmon_pdriver.driver, 8813 - &driver_attr_fan_watchdog); 8814 8871 8815 8872 cancel_delayed_work(&fan_watchdog_task); 8816 8873 flush_workqueue(tpacpi_wq); ··· 9851 9952 } 9852 9953 static DEVICE_ATTR_RO(palmsensor); 9853 9954 9955 + static struct attribute *proxsensor_attributes[] = { 9956 + &dev_attr_dytc_lapmode.attr, 9957 + &dev_attr_palmsensor.attr, 9958 + NULL 9959 + }; 9960 + 9961 + static umode_t proxsensor_attr_is_visible(struct kobject *kobj, 9962 + struct attribute *attr, int n) 9963 + { 9964 + if (attr == &dev_attr_dytc_lapmode.attr) { 9965 + /* 9966 + * Platforms before DYTC version 5 claim to have a lap sensor, 9967 + * but it doesn't work, so we ignore them. 9968 + */ 9969 + if (!has_lapsensor || dytc_version < 5) 9970 + return 0; 9971 + } else if (attr == &dev_attr_palmsensor.attr) { 9972 + if (!has_palmsensor) 9973 + return 0; 9974 + } 9975 + 9976 + return attr->mode; 9977 + } 9978 + 9979 + static const struct attribute_group proxsensor_attr_group = { 9980 + .is_visible = proxsensor_attr_is_visible, 9981 + .attrs = proxsensor_attributes, 9982 + }; 9983 + 9854 9984 static int tpacpi_proxsensor_init(struct ibm_init_struct *iibm) 9855 9985 { 9856 9986 int palm_err, lap_err, err; ··· 9898 9970 if (lap_err && (lap_err != -ENODEV)) 9899 9971 return lap_err; 9900 9972 9901 - if (has_palmsensor) { 9902 - err = sysfs_create_file(&tpacpi_pdev->dev.kobj, &dev_attr_palmsensor.attr); 9903 - if (err) 9904 - return err; 9905 - } 9906 - 9907 9973 /* Check if we know the DYTC version, if we don't then get it */ 9908 9974 if (!dytc_version) { 9909 9975 err = dytc_get_version(); 9910 9976 if (err) 9911 9977 return err; 9912 9978 } 9913 - /* 9914 - * Platforms before DYTC version 5 claim to have a lap sensor, but it doesn't work, so we 9915 - * ignore them 9916 - */ 9917 - if (has_lapsensor && (dytc_version >= 5)) { 9918 - err = sysfs_create_file(&tpacpi_pdev->dev.kobj, &dev_attr_dytc_lapmode.attr); 9919 - if (err) 9920 - return err; 9921 - } 9922 - return 0; 9923 - } 9924 9979 9925 - static void proxsensor_exit(void) 9926 - { 9927 - if (has_lapsensor) 9928 - sysfs_remove_file(&tpacpi_pdev->dev.kobj, &dev_attr_dytc_lapmode.attr); 9929 - if (has_palmsensor) 9930 - sysfs_remove_file(&tpacpi_pdev->dev.kobj, &dev_attr_palmsensor.attr); 9980 + return 0; 9931 9981 } 9932 9982 9933 9983 static struct ibm_struct proxsensor_driver_data = { 9934 9984 .name = "proximity-sensor", 9935 - .exit = proxsensor_exit, 9936 9985 }; 9937 9986 9938 9987 /************************************************************************* ··· 10326 10421 NULL 10327 10422 }; 10328 10423 10424 + static umode_t kbdlang_attr_is_visible(struct kobject *kobj, 10425 + struct attribute *attr, int n) 10426 + { 10427 + return tp_features.kbd_lang ? attr->mode : 0; 10428 + } 10429 + 10329 10430 static const struct attribute_group kbdlang_attr_group = { 10431 + .is_visible = kbdlang_attr_is_visible, 10330 10432 .attrs = kbdlang_attributes, 10331 10433 }; 10332 10434 ··· 10342 10430 int err, output; 10343 10431 10344 10432 err = get_keyboard_lang(&output); 10345 - /* 10346 - * If support isn't available (ENODEV) then don't return an error 10347 - * just don't create the sysfs group. 10348 - */ 10349 - if (err == -ENODEV) 10350 - return 0; 10351 - 10352 - if (err) 10353 - return err; 10354 - 10355 - /* Platform supports this feature - create the sysfs file */ 10356 - return sysfs_create_group(&tpacpi_pdev->dev.kobj, &kbdlang_attr_group); 10357 - } 10358 - 10359 - static void kbdlang_exit(void) 10360 - { 10361 - sysfs_remove_group(&tpacpi_pdev->dev.kobj, &kbdlang_attr_group); 10433 + tp_features.kbd_lang = !err; 10434 + return err; 10362 10435 } 10363 10436 10364 10437 static struct ibm_struct kbdlang_driver_data = { 10365 10438 .name = "kbdlang", 10366 - .exit = kbdlang_exit, 10367 10439 }; 10368 10440 10369 10441 /************************************************************************* ··· 10418 10522 } 10419 10523 static DEVICE_ATTR_RO(wwan_antenna_type); 10420 10524 10525 + static struct attribute *dprc_attributes[] = { 10526 + &dev_attr_wwan_antenna_type.attr, 10527 + NULL 10528 + }; 10529 + 10530 + static umode_t dprc_attr_is_visible(struct kobject *kobj, 10531 + struct attribute *attr, int n) 10532 + { 10533 + return has_antennatype ? attr->mode : 0; 10534 + } 10535 + 10536 + static const struct attribute_group dprc_attr_group = { 10537 + .is_visible = dprc_attr_is_visible, 10538 + .attrs = dprc_attributes, 10539 + }; 10540 + 10421 10541 static int tpacpi_dprc_init(struct ibm_init_struct *iibm) 10422 10542 { 10423 - int wwanantenna_err, err; 10543 + int err = get_wwan_antenna(&wwan_antennatype); 10424 10544 10425 - wwanantenna_err = get_wwan_antenna(&wwan_antennatype); 10426 10545 /* 10427 10546 * If support isn't available (ENODEV) then quit, but don't 10428 10547 * return an error. 10429 10548 */ 10430 - if (wwanantenna_err == -ENODEV) 10549 + if (err == -ENODEV) 10431 10550 return 0; 10432 10551 10433 - /* if there was an error return it */ 10434 - if (wwanantenna_err && (wwanantenna_err != -ENODEV)) 10435 - return wwanantenna_err; 10436 - else if (!wwanantenna_err) 10437 - has_antennatype = true; 10552 + /* If there was an error return it */ 10553 + if (err) 10554 + return err; 10438 10555 10439 - if (has_antennatype) { 10440 - err = sysfs_create_file(&tpacpi_pdev->dev.kobj, &dev_attr_wwan_antenna_type.attr); 10441 - if (err) 10442 - return err; 10443 - } 10556 + has_antennatype = true; 10444 10557 return 0; 10445 - } 10446 - 10447 - static void dprc_exit(void) 10448 - { 10449 - if (has_antennatype) 10450 - sysfs_remove_file(&tpacpi_pdev->dev.kobj, &dev_attr_wwan_antenna_type.attr); 10451 10558 } 10452 10559 10453 10560 static struct ibm_struct dprc_driver_data = { 10454 10561 .name = "dprc", 10455 - .exit = dprc_exit, 10562 + }; 10563 + 10564 + /* --------------------------------------------------------------------- */ 10565 + 10566 + static struct attribute *tpacpi_attributes[] = { 10567 + &driver_attr_debug_level.attr, 10568 + &driver_attr_version.attr, 10569 + &driver_attr_interface_version.attr, 10570 + #ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES 10571 + &driver_attr_wlsw_emulstate.attr, 10572 + &driver_attr_bluetooth_emulstate.attr, 10573 + &driver_attr_wwan_emulstate.attr, 10574 + &driver_attr_uwb_emulstate.attr, 10575 + #endif 10576 + NULL 10577 + }; 10578 + 10579 + #ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES 10580 + static umode_t tpacpi_attr_is_visible(struct kobject *kobj, 10581 + struct attribute *attr, int n) 10582 + { 10583 + if (attr == &driver_attr_wlsw_emulstate.attr) { 10584 + if (!dbg_wlswemul) 10585 + return 0; 10586 + } else if (attr == &driver_attr_bluetooth_emulstate.attr) { 10587 + if (!dbg_bluetoothemul) 10588 + return 0; 10589 + } else if (attr == &driver_attr_wwan_emulstate.attr) { 10590 + if (!dbg_wwanemul) 10591 + return 0; 10592 + } else if (attr == &driver_attr_uwb_emulstate.attr) { 10593 + if (!dbg_uwbemul) 10594 + return 0; 10595 + } 10596 + 10597 + return attr->mode; 10598 + } 10599 + #endif 10600 + 10601 + static const struct attribute_group tpacpi_attr_group = { 10602 + #ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES 10603 + .is_visible = tpacpi_attr_is_visible, 10604 + #endif 10605 + .attrs = tpacpi_attributes, 10606 + }; 10607 + 10608 + static const struct attribute_group *tpacpi_groups[] = { 10609 + &adaptive_kbd_attr_group, 10610 + &hotkey_attr_group, 10611 + &bluetooth_attr_group, 10612 + &wan_attr_group, 10613 + &cmos_attr_group, 10614 + &proxsensor_attr_group, 10615 + &kbdlang_attr_group, 10616 + &dprc_attr_group, 10617 + &tpacpi_attr_group, 10618 + NULL, 10619 + }; 10620 + 10621 + static const struct attribute_group *tpacpi_hwmon_groups[] = { 10622 + &thermal_attr_group, 10623 + &temp_label_attr_group, 10624 + &fan_attr_group, 10625 + NULL, 10626 + }; 10627 + 10628 + /**************************************************************************** 10629 + **************************************************************************** 10630 + * 10631 + * Platform drivers 10632 + * 10633 + **************************************************************************** 10634 + ****************************************************************************/ 10635 + 10636 + static struct platform_driver tpacpi_pdriver = { 10637 + .driver = { 10638 + .name = TPACPI_DRVR_NAME, 10639 + .pm = &tpacpi_pm, 10640 + .dev_groups = tpacpi_groups, 10641 + }, 10642 + .shutdown = tpacpi_shutdown_handler, 10643 + }; 10644 + 10645 + static struct platform_driver tpacpi_hwmon_pdriver = { 10646 + .driver = { 10647 + .name = TPACPI_HWMON_DRVR_NAME, 10648 + .dev_groups = tpacpi_hwmon_groups, 10649 + }, 10456 10650 }; 10457 10651 10458 10652 /**************************************************************************** ··· 11065 11079 11066 11080 for (i = 0; i < ARRAY_SIZE(ibms_init); i++) { 11067 11081 ibm = ibms_init[i].data; 11068 - WARN_ON(ibm == NULL); 11069 - 11070 11082 if (!ibm || !ibm->name) 11071 11083 continue; 11072 11084 ··· 11194 11210 11195 11211 if (tpacpi_hwmon) 11196 11212 hwmon_device_unregister(tpacpi_hwmon); 11197 - 11198 11213 if (tpacpi_sensors_pdev) 11199 11214 platform_device_unregister(tpacpi_sensors_pdev); 11200 11215 if (tpacpi_pdev) 11201 11216 platform_device_unregister(tpacpi_pdev); 11202 - 11203 - if (tp_features.sensors_pdrv_attrs_registered) 11204 - tpacpi_remove_driver_attributes(&tpacpi_hwmon_pdriver.driver); 11205 - if (tp_features.platform_drv_attrs_registered) 11206 - tpacpi_remove_driver_attributes(&tpacpi_pdriver.driver); 11207 - 11208 11217 if (tp_features.sensors_pdrv_registered) 11209 11218 platform_driver_unregister(&tpacpi_hwmon_pdriver); 11210 - 11211 11219 if (tp_features.platform_drv_registered) 11212 11220 platform_driver_unregister(&tpacpi_pdriver); 11213 - 11214 11221 if (proc_dir) 11215 11222 remove_proc_entry(TPACPI_PROC_DIR, acpi_root_dir); 11216 - 11217 11223 if (tpacpi_wq) 11218 11224 destroy_workqueue(tpacpi_wq); 11219 11225 ··· 11270 11296 return ret; 11271 11297 } 11272 11298 tp_features.sensors_pdrv_registered = 1; 11273 - 11274 - ret = tpacpi_create_driver_attributes(&tpacpi_pdriver.driver); 11275 - if (!ret) { 11276 - tp_features.platform_drv_attrs_registered = 1; 11277 - ret = tpacpi_create_driver_attributes( 11278 - &tpacpi_hwmon_pdriver.driver); 11279 - } 11280 - if (ret) { 11281 - pr_err("unable to create sysfs driver attributes\n"); 11282 - thinkpad_acpi_module_exit(); 11283 - return ret; 11284 - } 11285 - tp_features.sensors_pdrv_attrs_registered = 1; 11286 - 11287 11299 11288 11300 /* Device initialization */ 11289 11301 tpacpi_pdev = platform_device_register_simple(TPACPI_DRVR_NAME, -1,