Lines 32-39
Link Here
|
32 |
#include <linux/uaccess.h> |
32 |
#include <linux/uaccess.h> |
33 |
#include <linux/input.h> |
33 |
#include <linux/input.h> |
34 |
#include <linux/rfkill.h> |
34 |
#include <linux/rfkill.h> |
35 |
#include <linux/pci.h> |
|
|
36 |
#include <linux/pci_hotplug.h> |
37 |
|
35 |
|
38 |
#define EEEPC_LAPTOP_VERSION "0.1" |
36 |
#define EEEPC_LAPTOP_VERSION "0.1" |
39 |
|
37 |
|
Lines 66-72
enum {
Link Here
|
66 |
DISABLE_ASL_HWCF = 0x0800 |
64 |
DISABLE_ASL_HWCF = 0x0800 |
67 |
}; |
65 |
}; |
68 |
|
66 |
|
69 |
enum { |
67 |
enum eeepc_cm { |
70 |
CM_ASL_WLAN = 0, |
68 |
CM_ASL_WLAN = 0, |
71 |
CM_ASL_BLUETOOTH, |
69 |
CM_ASL_BLUETOOTH, |
72 |
CM_ASL_IRDA, |
70 |
CM_ASL_IRDA, |
Lines 139-156
struct eeepc_hotk {
Link Here
|
139 |
u16 event_count[128]; /* count for each event */ |
137 |
u16 event_count[128]; /* count for each event */ |
140 |
struct input_dev *inputdev; |
138 |
struct input_dev *inputdev; |
141 |
u16 *keycode_map; |
139 |
u16 *keycode_map; |
142 |
struct rfkill *wlan_rfkill; |
|
|
143 |
struct rfkill *bluetooth_rfkill; |
144 |
struct rfkill *wwan3g_rfkill; |
145 |
struct rfkill *wimax_rfkill; |
146 |
struct hotplug_slot *hotplug_slot; |
147 |
struct mutex hotplug_lock; |
148 |
}; |
140 |
}; |
149 |
|
141 |
|
150 |
/* The actual device the driver binds to */ |
142 |
/* The actual device the driver binds to */ |
151 |
static struct eeepc_hotk *ehotk; |
143 |
static struct eeepc_hotk *ehotk; |
152 |
|
144 |
|
153 |
/* Platform device/driver */ |
|
|
154 |
static int eeepc_hotk_thaw(struct device *device); |
145 |
static int eeepc_hotk_thaw(struct device *device); |
155 |
static int eeepc_hotk_restore(struct device *device); |
146 |
static int eeepc_hotk_restore(struct device *device); |
156 |
|
147 |
|
Lines 222-236
static struct acpi_driver eeepc_hotk_driver = {
Link Here
|
222 |
}, |
213 |
}, |
223 |
}; |
214 |
}; |
224 |
|
215 |
|
225 |
/* PCI hotplug ops */ |
|
|
226 |
static int eeepc_get_adapter_status(struct hotplug_slot *slot, u8 *value); |
227 |
|
228 |
static struct hotplug_slot_ops eeepc_hotplug_slot_ops = { |
229 |
.owner = THIS_MODULE, |
230 |
.get_adapter_status = eeepc_get_adapter_status, |
231 |
.get_power_status = eeepc_get_adapter_status, |
232 |
}; |
233 |
|
234 |
/* The backlight device /sys/class/backlight */ |
216 |
/* The backlight device /sys/class/backlight */ |
235 |
static struct backlight_device *eeepc_backlight_device; |
217 |
static struct backlight_device *eeepc_backlight_device; |
236 |
|
218 |
|
Lines 247-252
static struct backlight_ops eeepcbl_ops = {
Link Here
|
247 |
.update_status = update_bl_status, |
229 |
.update_status = update_bl_status, |
248 |
}; |
230 |
}; |
249 |
|
231 |
|
|
|
232 |
|
233 |
/* |
234 |
* Rfkill |
235 |
*/ |
236 |
|
237 |
struct eeepc_rfkill_t { |
238 |
const char *name; |
239 |
enum rfkill_type type; |
240 |
enum eeepc_cm cm; |
241 |
struct rfkill *rf; |
242 |
}; |
243 |
|
244 |
static struct eeepc_rfkill_t eeepc_rfkill[] = { |
245 |
{ |
246 |
.name = "eeepc-wlan", |
247 |
.type = RFKILL_TYPE_WLAN, |
248 |
.cm = CM_ASL_WLAN, |
249 |
}, |
250 |
{ |
251 |
.name = "eeepc-bluetooth", |
252 |
.type = RFKILL_TYPE_BLUETOOTH, |
253 |
.cm = CM_ASL_BLUETOOTH, |
254 |
}, |
255 |
{ |
256 |
.name = "eeepc-wwan3g", |
257 |
.type = RFKILL_TYPE_WWAN, |
258 |
.cm = CM_ASL_3G, |
259 |
}, |
260 |
{ |
261 |
.name = "eeepc-wimax", |
262 |
.type = RFKILL_TYPE_WIMAX, |
263 |
.cm = CM_ASL_WIMAX, |
264 |
}, |
265 |
}; |
266 |
|
267 |
static int eeepc_rfkill_set(void *data, bool blocked); |
268 |
static struct rfkill_ops eeepc_rfkill_ops = { |
269 |
.set_block = eeepc_rfkill_set, |
270 |
}; |
271 |
|
250 |
MODULE_AUTHOR("Corentin Chary, Eric Cooper"); |
272 |
MODULE_AUTHOR("Corentin Chary, Eric Cooper"); |
251 |
MODULE_DESCRIPTION(EEEPC_HOTK_NAME); |
273 |
MODULE_DESCRIPTION(EEEPC_HOTK_NAME); |
252 |
MODULE_LICENSE("GPL"); |
274 |
MODULE_LICENSE("GPL"); |
Lines 329-363
static int update_bl_status(struct backlight_device *bd)
Link Here
|
329 |
return set_brightness(bd, bd->props.brightness); |
351 |
return set_brightness(bd, bd->props.brightness); |
330 |
} |
352 |
} |
331 |
|
353 |
|
332 |
/* |
|
|
333 |
* Rfkill helpers |
334 |
*/ |
335 |
|
336 |
static bool eeepc_wlan_rfkill_blocked(void) |
337 |
{ |
338 |
if (get_acpi(CM_ASL_WLAN) == 1) |
339 |
return false; |
340 |
return true; |
341 |
} |
342 |
|
343 |
static int eeepc_rfkill_set(void *data, bool blocked) |
344 |
{ |
345 |
unsigned long asl = (unsigned long)data; |
346 |
return set_acpi(asl, !blocked); |
347 |
} |
348 |
|
349 |
static const struct rfkill_ops eeepc_rfkill_ops = { |
350 |
.set_block = eeepc_rfkill_set, |
351 |
}; |
352 |
|
353 |
static void __devinit eeepc_enable_camera(void) |
354 |
static void __devinit eeepc_enable_camera(void) |
354 |
{ |
355 |
{ |
355 |
/* |
356 |
/* |
356 |
* If the following call to set_acpi() fails, it's because there's no |
357 |
* If the following call to set_acpi() fails, it's because there's no |
357 |
* camera so we can ignore the error. |
358 |
* camera so we can ignore the error. |
358 |
*/ |
359 |
*/ |
359 |
if (get_acpi(CM_ASL_CAMERA) == 0) |
360 |
set_acpi(CM_ASL_CAMERA, 1); |
360 |
set_acpi(CM_ASL_CAMERA, 1); |
|
|
361 |
} |
361 |
} |
362 |
|
362 |
|
363 |
/* |
363 |
/* |
Lines 631-701
static int notify_brn(void)
Link Here
|
631 |
return -1; |
631 |
return -1; |
632 |
} |
632 |
} |
633 |
|
633 |
|
634 |
static int eeepc_get_adapter_status(struct hotplug_slot *hotplug_slot, |
|
|
635 |
u8 *value) |
636 |
{ |
637 |
int val = get_acpi(CM_ASL_WLAN); |
638 |
|
639 |
if (val == 1 || val == 0) |
640 |
*value = val; |
641 |
else |
642 |
return -EINVAL; |
643 |
|
644 |
return 0; |
645 |
} |
646 |
|
647 |
static void eeepc_rfkill_hotplug(void) |
648 |
{ |
649 |
struct pci_dev *dev; |
650 |
struct pci_bus *bus; |
651 |
bool blocked = eeepc_wlan_rfkill_blocked(); |
652 |
|
653 |
if (ehotk->wlan_rfkill) |
654 |
rfkill_set_sw_state(ehotk->wlan_rfkill, blocked); |
655 |
|
656 |
mutex_lock(&ehotk->hotplug_lock); |
657 |
|
658 |
if (ehotk->hotplug_slot) { |
659 |
bus = pci_find_bus(0, 1); |
660 |
if (!bus) { |
661 |
pr_warning("Unable to find PCI bus 1?\n"); |
662 |
goto out_unlock; |
663 |
} |
664 |
|
665 |
if (!blocked) { |
666 |
dev = pci_get_slot(bus, 0); |
667 |
if (dev) { |
668 |
/* Device already present */ |
669 |
pci_dev_put(dev); |
670 |
goto out_unlock; |
671 |
} |
672 |
dev = pci_scan_single_device(bus, 0); |
673 |
if (dev) { |
674 |
pci_bus_assign_resources(bus); |
675 |
if (pci_bus_add_device(dev)) |
676 |
pr_err("Unable to hotplug wifi\n"); |
677 |
} |
678 |
} else { |
679 |
dev = pci_get_slot(bus, 0); |
680 |
if (dev) { |
681 |
pci_remove_bus_device(dev); |
682 |
pci_dev_put(dev); |
683 |
} |
684 |
} |
685 |
} |
686 |
|
687 |
out_unlock: |
688 |
mutex_unlock(&ehotk->hotplug_lock); |
689 |
} |
690 |
|
691 |
static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data) |
692 |
{ |
693 |
if (event != ACPI_NOTIFY_BUS_CHECK) |
694 |
return; |
695 |
|
696 |
eeepc_rfkill_hotplug(); |
697 |
} |
698 |
|
699 |
static void eeepc_hotk_notify(struct acpi_device *device, u32 event) |
634 |
static void eeepc_hotk_notify(struct acpi_device *device, u32 event) |
700 |
{ |
635 |
{ |
701 |
static struct key_entry *key; |
636 |
static struct key_entry *key; |
Lines 745-871
static void eeepc_hotk_notify(struct acpi_device *device, u32 event)
Link Here
|
745 |
} |
680 |
} |
746 |
} |
681 |
} |
747 |
|
682 |
|
748 |
static int eeepc_register_rfkill_notifier(char *node) |
|
|
749 |
{ |
750 |
acpi_status status = AE_OK; |
751 |
acpi_handle handle; |
752 |
|
753 |
status = acpi_get_handle(NULL, node, &handle); |
754 |
|
755 |
if (ACPI_SUCCESS(status)) { |
756 |
status = acpi_install_notify_handler(handle, |
757 |
ACPI_SYSTEM_NOTIFY, |
758 |
eeepc_rfkill_notify, |
759 |
NULL); |
760 |
if (ACPI_FAILURE(status)) |
761 |
pr_warning("Failed to register notify on %s\n", node); |
762 |
} else |
763 |
return -ENODEV; |
764 |
|
765 |
return 0; |
766 |
} |
767 |
|
768 |
static void eeepc_unregister_rfkill_notifier(char *node) |
769 |
{ |
770 |
acpi_status status = AE_OK; |
771 |
acpi_handle handle; |
772 |
|
773 |
status = acpi_get_handle(NULL, node, &handle); |
774 |
|
775 |
if (ACPI_SUCCESS(status)) { |
776 |
status = acpi_remove_notify_handler(handle, |
777 |
ACPI_SYSTEM_NOTIFY, |
778 |
eeepc_rfkill_notify); |
779 |
if (ACPI_FAILURE(status)) |
780 |
pr_err("Error removing rfkill notify handler %s\n", |
781 |
node); |
782 |
} |
783 |
} |
784 |
|
785 |
static void eeepc_cleanup_pci_hotplug(struct hotplug_slot *hotplug_slot) |
786 |
{ |
787 |
kfree(hotplug_slot->info); |
788 |
kfree(hotplug_slot); |
789 |
} |
790 |
|
791 |
static int eeepc_setup_pci_hotplug(void) |
792 |
{ |
793 |
int ret = -ENOMEM; |
794 |
struct pci_bus *bus = pci_find_bus(0, 1); |
795 |
|
796 |
if (!bus) { |
797 |
pr_err("Unable to find wifi PCI bus\n"); |
798 |
return -ENODEV; |
799 |
} |
800 |
|
801 |
ehotk->hotplug_slot = kzalloc(sizeof(struct hotplug_slot), GFP_KERNEL); |
802 |
if (!ehotk->hotplug_slot) |
803 |
goto error_slot; |
804 |
|
805 |
ehotk->hotplug_slot->info = kzalloc(sizeof(struct hotplug_slot_info), |
806 |
GFP_KERNEL); |
807 |
if (!ehotk->hotplug_slot->info) |
808 |
goto error_info; |
809 |
|
810 |
ehotk->hotplug_slot->private = ehotk; |
811 |
ehotk->hotplug_slot->release = &eeepc_cleanup_pci_hotplug; |
812 |
ehotk->hotplug_slot->ops = &eeepc_hotplug_slot_ops; |
813 |
eeepc_get_adapter_status(ehotk->hotplug_slot, |
814 |
&ehotk->hotplug_slot->info->adapter_status); |
815 |
|
816 |
ret = pci_hp_register(ehotk->hotplug_slot, bus, 0, "eeepc-wifi"); |
817 |
if (ret) { |
818 |
pr_err("Unable to register hotplug slot - %d\n", ret); |
819 |
goto error_register; |
820 |
} |
821 |
|
822 |
return 0; |
823 |
|
824 |
error_register: |
825 |
kfree(ehotk->hotplug_slot->info); |
826 |
error_info: |
827 |
kfree(ehotk->hotplug_slot); |
828 |
ehotk->hotplug_slot = NULL; |
829 |
error_slot: |
830 |
return ret; |
831 |
} |
832 |
|
833 |
static int eeepc_hotk_thaw(struct device *device) |
834 |
{ |
835 |
if (ehotk->wlan_rfkill) { |
836 |
bool wlan; |
837 |
|
838 |
/* |
839 |
* Work around bios bug - acpi _PTS turns off the wireless led |
840 |
* during suspend. Normally it restores it on resume, but |
841 |
* we should kick it ourselves in case hibernation is aborted. |
842 |
*/ |
843 |
wlan = get_acpi(CM_ASL_WLAN); |
844 |
set_acpi(CM_ASL_WLAN, wlan); |
845 |
} |
846 |
|
847 |
return 0; |
848 |
} |
849 |
|
850 |
static int eeepc_hotk_restore(struct device *device) |
851 |
{ |
852 |
/* Refresh both wlan rfkill state and pci hotplug */ |
853 |
if (ehotk->wlan_rfkill) |
854 |
eeepc_rfkill_hotplug(); |
855 |
|
856 |
if (ehotk->bluetooth_rfkill) |
857 |
rfkill_set_sw_state(ehotk->bluetooth_rfkill, |
858 |
get_acpi(CM_ASL_BLUETOOTH) != 1); |
859 |
if (ehotk->wwan3g_rfkill) |
860 |
rfkill_set_sw_state(ehotk->wwan3g_rfkill, |
861 |
get_acpi(CM_ASL_3G) != 1); |
862 |
if (ehotk->wimax_rfkill) |
863 |
rfkill_set_sw_state(ehotk->wimax_rfkill, |
864 |
get_acpi(CM_ASL_WIMAX) != 1); |
865 |
|
866 |
return 0; |
867 |
} |
868 |
|
869 |
/* |
683 |
/* |
870 |
* Hwmon |
684 |
* Hwmon |
871 |
*/ |
685 |
*/ |
Lines 971-1018
static struct attribute_group hwmon_attribute_group = {
Link Here
|
971 |
}; |
785 |
}; |
972 |
|
786 |
|
973 |
/* |
787 |
/* |
974 |
* exit/init |
788 |
* Rfkill |
975 |
*/ |
789 |
*/ |
976 |
static void eeepc_backlight_exit(void) |
790 |
static int eeepc_rfkill_set(void *data, bool blocked) |
977 |
{ |
791 |
{ |
978 |
if (eeepc_backlight_device) |
792 |
enum eeepc_cm cm = (enum eeepc_cm)data; |
979 |
backlight_device_unregister(eeepc_backlight_device); |
793 |
return set_acpi(cm, !blocked); |
980 |
eeepc_backlight_device = NULL; |
|
|
981 |
} |
794 |
} |
982 |
|
795 |
|
983 |
static void eeepc_rfkill_exit(void) |
796 |
static int eeepc_hotk_restore(struct device *device) |
984 |
{ |
797 |
{ |
985 |
eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P5"); |
798 |
struct eeepc_rfkill_t *i; |
986 |
eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P6"); |
799 |
for(i = &(eeepc_rfkill[0]); |
987 |
eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P7"); |
800 |
i < &(eeepc_rfkill[sizeof(eeepc_rfkill)/sizeof(struct eeepc_rfkill_t)]); |
988 |
if (ehotk->wlan_rfkill) { |
801 |
++i) |
989 |
rfkill_unregister(ehotk->wlan_rfkill); |
802 |
{ |
990 |
rfkill_destroy(ehotk->wlan_rfkill); |
803 |
if ( i->rf ) |
991 |
ehotk->wlan_rfkill = NULL; |
804 |
rfkill_set_sw_state(i->rf, get_acpi(i->cm) != 1); |
992 |
} |
|
|
993 |
/* |
994 |
* Refresh pci hotplug in case the rfkill state was changed after |
995 |
* eeepc_unregister_rfkill_notifier() |
996 |
*/ |
997 |
eeepc_rfkill_hotplug(); |
998 |
if (ehotk->hotplug_slot) |
999 |
pci_hp_deregister(ehotk->hotplug_slot); |
1000 |
|
1001 |
if (ehotk->bluetooth_rfkill) { |
1002 |
rfkill_unregister(ehotk->bluetooth_rfkill); |
1003 |
rfkill_destroy(ehotk->bluetooth_rfkill); |
1004 |
ehotk->bluetooth_rfkill = NULL; |
1005 |
} |
1006 |
if (ehotk->wwan3g_rfkill) { |
1007 |
rfkill_unregister(ehotk->wwan3g_rfkill); |
1008 |
rfkill_destroy(ehotk->wwan3g_rfkill); |
1009 |
ehotk->wwan3g_rfkill = NULL; |
1010 |
} |
805 |
} |
1011 |
if (ehotk->wimax_rfkill) { |
806 |
return 0; |
1012 |
rfkill_unregister(ehotk->wimax_rfkill); |
807 |
} |
1013 |
rfkill_destroy(ehotk->wimax_rfkill); |
808 |
|
1014 |
ehotk->wimax_rfkill = NULL; |
809 |
static int eeepc_hotk_thaw(struct device *device) |
|
|
810 |
{ |
811 |
if (eeepc_rfkill[0].rf) { |
812 |
/* |
813 |
* Work around bios bug - acpi _PTS turns off the wireless led |
814 |
* during suspend. Normally it restores it on resume, but |
815 |
* we should kick it ourselves in case hibernation is aborted. |
816 |
*/ |
817 |
set_acpi(CM_ASL_WLAN, get_acpi(CM_ASL_WLAN)); |
1015 |
} |
818 |
} |
|
|
819 |
|
820 |
return 0; |
821 |
} |
822 |
|
823 |
|
824 |
/* |
825 |
* exit/init |
826 |
*/ |
827 |
static void eeepc_backlight_exit(void) |
828 |
{ |
829 |
if (eeepc_backlight_device) |
830 |
backlight_device_unregister(eeepc_backlight_device); |
831 |
eeepc_backlight_device = NULL; |
1016 |
} |
832 |
} |
1017 |
|
833 |
|
1018 |
static void eeepc_input_exit(void) |
834 |
static void eeepc_input_exit(void) |
Lines 1034-1121
static void eeepc_hwmon_exit(void)
Link Here
|
1034 |
eeepc_hwmon_device = NULL; |
850 |
eeepc_hwmon_device = NULL; |
1035 |
} |
851 |
} |
1036 |
|
852 |
|
1037 |
static int eeepc_new_rfkill(struct rfkill **rfkill, |
853 |
static void eeepc_rfkill_exit(void) |
1038 |
const char *name, struct device *dev, |
|
|
1039 |
enum rfkill_type type, int cm) |
1040 |
{ |
854 |
{ |
1041 |
int result; |
855 |
struct eeepc_rfkill_t *i; |
1042 |
|
856 |
for(i = &(eeepc_rfkill[0]); |
1043 |
result = get_acpi(cm); |
857 |
i < &(eeepc_rfkill[sizeof(eeepc_rfkill)/sizeof(struct eeepc_rfkill_t)]); |
1044 |
if (result < 0) |
858 |
++i) |
1045 |
return result; |
859 |
{ |
1046 |
|
860 |
if ( i->rf ) |
1047 |
*rfkill = rfkill_alloc(name, dev, type, |
861 |
{ |
1048 |
&eeepc_rfkill_ops, (void *)(unsigned long)cm); |
862 |
rfkill_unregister(i->rf); |
1049 |
|
863 |
rfkill_destroy(i->rf); |
1050 |
if (!*rfkill) |
864 |
i->rf = NULL; |
1051 |
return -EINVAL; |
865 |
} |
1052 |
|
|
|
1053 |
rfkill_init_sw_state(*rfkill, get_acpi(cm) != 1); |
1054 |
result = rfkill_register(*rfkill); |
1055 |
if (result) { |
1056 |
rfkill_destroy(*rfkill); |
1057 |
*rfkill = NULL; |
1058 |
return result; |
1059 |
} |
866 |
} |
1060 |
return 0; |
|
|
1061 |
} |
1062 |
|
1063 |
|
1064 |
static int eeepc_rfkill_init(struct device *dev) |
1065 |
{ |
1066 |
int result = 0; |
1067 |
|
1068 |
mutex_init(&ehotk->hotplug_lock); |
1069 |
|
1070 |
result = eeepc_new_rfkill(&ehotk->wlan_rfkill, |
1071 |
"eeepc-wlan", dev, |
1072 |
RFKILL_TYPE_WLAN, CM_ASL_WLAN); |
1073 |
|
1074 |
if (result && result != -ENODEV) |
1075 |
goto exit; |
1076 |
|
1077 |
result = eeepc_new_rfkill(&ehotk->bluetooth_rfkill, |
1078 |
"eeepc-bluetooth", dev, |
1079 |
RFKILL_TYPE_BLUETOOTH, CM_ASL_BLUETOOTH); |
1080 |
|
1081 |
if (result && result != -ENODEV) |
1082 |
goto exit; |
1083 |
|
1084 |
result = eeepc_new_rfkill(&ehotk->wwan3g_rfkill, |
1085 |
"eeepc-wwan3g", dev, |
1086 |
RFKILL_TYPE_WWAN, CM_ASL_3G); |
1087 |
|
1088 |
if (result && result != -ENODEV) |
1089 |
goto exit; |
1090 |
|
1091 |
result = eeepc_new_rfkill(&ehotk->wimax_rfkill, |
1092 |
"eeepc-wimax", dev, |
1093 |
RFKILL_TYPE_WIMAX, CM_ASL_WIMAX); |
1094 |
|
1095 |
if (result && result != -ENODEV) |
1096 |
goto exit; |
1097 |
|
1098 |
result = eeepc_setup_pci_hotplug(); |
1099 |
/* |
1100 |
* If we get -EBUSY then something else is handling the PCI hotplug - |
1101 |
* don't fail in this case |
1102 |
*/ |
1103 |
if (result == -EBUSY) |
1104 |
result = 0; |
1105 |
|
1106 |
eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P5"); |
1107 |
eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P6"); |
1108 |
eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P7"); |
1109 |
/* |
1110 |
* Refresh pci hotplug in case the rfkill state was changed during |
1111 |
* setup. |
1112 |
*/ |
1113 |
eeepc_rfkill_hotplug(); |
1114 |
|
1115 |
exit: |
1116 |
if (result && result != -ENODEV) |
1117 |
eeepc_rfkill_exit(); |
1118 |
return result; |
1119 |
} |
867 |
} |
1120 |
|
868 |
|
1121 |
static int eeepc_backlight_init(struct device *dev) |
869 |
static int eeepc_backlight_init(struct device *dev) |
Lines 1190-1202
static int eeepc_input_init(struct device *dev)
Link Here
|
1190 |
return 0; |
938 |
return 0; |
1191 |
} |
939 |
} |
1192 |
|
940 |
|
|
|
941 |
static int eeepc_rfkill_new(struct eeepc_rfkill_t *rfk, |
942 |
struct device *dev) |
943 |
{ |
944 |
int ret = 0; |
945 |
if ( get_acpi(rfk->cm) < 0 ) |
946 |
{ |
947 |
ret = -ENODEV; |
948 |
goto eeepc_rfkill_new_end; |
949 |
} |
950 |
|
951 |
rfk->rf = rfkill_alloc(rfk->name, |
952 |
dev, |
953 |
rfk->type, |
954 |
&eeepc_rfkill_ops, |
955 |
(void *)rfk->cm); |
956 |
if ( unlikely(!(rfk->rf)) ) |
957 |
{ |
958 |
pr_notice("can't alloc rfkill for %s", rfk->name); |
959 |
ret = -EINVAL; |
960 |
goto eeepc_rfkill_new_end; |
961 |
} |
962 |
|
963 |
rfkill_init_sw_state(rfk->rf, get_acpi(rfk->cm) != 1); |
964 |
ret = rfkill_register(rfk->rf); |
965 |
if ( unlikely(ret) ) |
966 |
{ |
967 |
pr_notice("can't register rfkill for %s", rfk->name); |
968 |
rfkill_destroy(rfk->rf); |
969 |
rfk->rf = NULL; |
970 |
} |
971 |
|
972 |
eeepc_rfkill_new_end: |
973 |
return ret; |
974 |
} |
975 |
|
976 |
static int eeepc_rfkill_init(struct device *dev) |
977 |
{ |
978 |
int ret = 0; |
979 |
struct eeepc_rfkill_t *i; |
980 |
for(i = &(eeepc_rfkill[0]); |
981 |
i < &(eeepc_rfkill[sizeof(eeepc_rfkill)/sizeof(struct eeepc_rfkill_t)]); |
982 |
++i) |
983 |
{ |
984 |
ret = eeepc_rfkill_new(i, dev); |
985 |
if ( ret ) |
986 |
{ |
987 |
if (unlikely(ret != -ENODEV)) |
988 |
break; |
989 |
else |
990 |
ret = 0; |
991 |
} |
992 |
} |
993 |
return ret; |
994 |
} |
995 |
|
1193 |
static int __devinit eeepc_hotk_add(struct acpi_device *device) |
996 |
static int __devinit eeepc_hotk_add(struct acpi_device *device) |
1194 |
{ |
997 |
{ |
1195 |
struct device *dev; |
998 |
struct device *dev; |
1196 |
int result; |
999 |
int result; |
1197 |
|
1000 |
|
1198 |
if (!device) |
1001 |
if (!device) |
1199 |
return -EINVAL; |
1002 |
return -EINVAL; |
1200 |
pr_notice(EEEPC_HOTK_NAME "\n"); |
1003 |
pr_notice(EEEPC_HOTK_NAME "\n"); |
1201 |
ehotk = kzalloc(sizeof(struct eeepc_hotk), GFP_KERNEL); |
1004 |
ehotk = kzalloc(sizeof(struct eeepc_hotk), GFP_KERNEL); |
1202 |
if (!ehotk) |
1005 |
if (!ehotk) |
Lines 1249-1255
static int __devinit eeepc_hotk_add(struct acpi_device *device)
Link Here
|
1249 |
goto fail_hwmon; |
1052 |
goto fail_hwmon; |
1250 |
|
1053 |
|
1251 |
result = eeepc_rfkill_init(dev); |
1054 |
result = eeepc_rfkill_init(dev); |
1252 |
if (result) |
1055 |
if (unlikely(result)) |
1253 |
goto fail_rfkill; |
1056 |
goto fail_rfkill; |
1254 |
|
1057 |
|
1255 |
return 0; |
1058 |
return 0; |
Lines 1278-1287
fail_platform_driver:
Link Here
|
1278 |
static int eeepc_hotk_remove(struct acpi_device *device, int type) |
1081 |
static int eeepc_hotk_remove(struct acpi_device *device, int type) |
1279 |
{ |
1082 |
{ |
1280 |
if (!device || !acpi_driver_data(device)) |
1083 |
if (!device || !acpi_driver_data(device)) |
1281 |
return -EINVAL; |
1084 |
return -EINVAL; |
1282 |
|
1085 |
|
1283 |
eeepc_backlight_exit(); |
|
|
1284 |
eeepc_rfkill_exit(); |
1086 |
eeepc_rfkill_exit(); |
|
|
1087 |
eeepc_backlight_exit(); |
1285 |
eeepc_input_exit(); |
1088 |
eeepc_input_exit(); |
1286 |
eeepc_hwmon_exit(); |
1089 |
eeepc_hwmon_exit(); |
1287 |
sysfs_remove_group(&platform_device->dev.kobj, |
1090 |
sysfs_remove_group(&platform_device->dev.kobj, |