diff options
Diffstat (limited to 'drivers')
181 files changed, 4161 insertions, 1507 deletions
diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c index ba9afeaa23ac..25d3aaebc10d 100644 --- a/drivers/acpi/ac.c +++ b/drivers/acpi/ac.c | |||
@@ -100,24 +100,7 @@ static const struct file_operations acpi_ac_fops = { | |||
100 | .release = single_release, | 100 | .release = single_release, |
101 | }; | 101 | }; |
102 | #endif | 102 | #endif |
103 | static int get_ac_property(struct power_supply *psy, | ||
104 | enum power_supply_property psp, | ||
105 | union power_supply_propval *val) | ||
106 | { | ||
107 | struct acpi_ac *ac = to_acpi_ac(psy); | ||
108 | switch (psp) { | ||
109 | case POWER_SUPPLY_PROP_ONLINE: | ||
110 | val->intval = ac->state; | ||
111 | break; | ||
112 | default: | ||
113 | return -EINVAL; | ||
114 | } | ||
115 | return 0; | ||
116 | } | ||
117 | 103 | ||
118 | static enum power_supply_property ac_props[] = { | ||
119 | POWER_SUPPLY_PROP_ONLINE, | ||
120 | }; | ||
121 | /* -------------------------------------------------------------------------- | 104 | /* -------------------------------------------------------------------------- |
122 | AC Adapter Management | 105 | AC Adapter Management |
123 | -------------------------------------------------------------------------- */ | 106 | -------------------------------------------------------------------------- */ |
@@ -140,6 +123,35 @@ static int acpi_ac_get_state(struct acpi_ac *ac) | |||
140 | return 0; | 123 | return 0; |
141 | } | 124 | } |
142 | 125 | ||
126 | /* -------------------------------------------------------------------------- | ||
127 | sysfs I/F | ||
128 | -------------------------------------------------------------------------- */ | ||
129 | static int get_ac_property(struct power_supply *psy, | ||
130 | enum power_supply_property psp, | ||
131 | union power_supply_propval *val) | ||
132 | { | ||
133 | struct acpi_ac *ac = to_acpi_ac(psy); | ||
134 | |||
135 | if (!ac) | ||
136 | return -ENODEV; | ||
137 | |||
138 | if (acpi_ac_get_state(ac)) | ||
139 | return -ENODEV; | ||
140 | |||
141 | switch (psp) { | ||
142 | case POWER_SUPPLY_PROP_ONLINE: | ||
143 | val->intval = ac->state; | ||
144 | break; | ||
145 | default: | ||
146 | return -EINVAL; | ||
147 | } | ||
148 | return 0; | ||
149 | } | ||
150 | |||
151 | static enum power_supply_property ac_props[] = { | ||
152 | POWER_SUPPLY_PROP_ONLINE, | ||
153 | }; | ||
154 | |||
143 | #ifdef CONFIG_ACPI_PROCFS_POWER | 155 | #ifdef CONFIG_ACPI_PROCFS_POWER |
144 | /* -------------------------------------------------------------------------- | 156 | /* -------------------------------------------------------------------------- |
145 | FS Interface (/proc) | 157 | FS Interface (/proc) |
diff --git a/drivers/acpi/apei/erst.c b/drivers/acpi/apei/erst.c index 1211c03149e8..5850d320404c 100644 --- a/drivers/acpi/apei/erst.c +++ b/drivers/acpi/apei/erst.c | |||
@@ -86,7 +86,7 @@ static struct erst_erange { | |||
86 | * It is used to provide exclusive accessing for ERST Error Log | 86 | * It is used to provide exclusive accessing for ERST Error Log |
87 | * Address Range too. | 87 | * Address Range too. |
88 | */ | 88 | */ |
89 | static DEFINE_SPINLOCK(erst_lock); | 89 | static DEFINE_RAW_SPINLOCK(erst_lock); |
90 | 90 | ||
91 | static inline int erst_errno(int command_status) | 91 | static inline int erst_errno(int command_status) |
92 | { | 92 | { |
@@ -421,9 +421,9 @@ ssize_t erst_get_record_count(void) | |||
421 | if (erst_disable) | 421 | if (erst_disable) |
422 | return -ENODEV; | 422 | return -ENODEV; |
423 | 423 | ||
424 | spin_lock_irqsave(&erst_lock, flags); | 424 | raw_spin_lock_irqsave(&erst_lock, flags); |
425 | count = __erst_get_record_count(); | 425 | count = __erst_get_record_count(); |
426 | spin_unlock_irqrestore(&erst_lock, flags); | 426 | raw_spin_unlock_irqrestore(&erst_lock, flags); |
427 | 427 | ||
428 | return count; | 428 | return count; |
429 | } | 429 | } |
@@ -456,9 +456,9 @@ int erst_get_next_record_id(u64 *record_id) | |||
456 | if (erst_disable) | 456 | if (erst_disable) |
457 | return -ENODEV; | 457 | return -ENODEV; |
458 | 458 | ||
459 | spin_lock_irqsave(&erst_lock, flags); | 459 | raw_spin_lock_irqsave(&erst_lock, flags); |
460 | rc = __erst_get_next_record_id(record_id); | 460 | rc = __erst_get_next_record_id(record_id); |
461 | spin_unlock_irqrestore(&erst_lock, flags); | 461 | raw_spin_unlock_irqrestore(&erst_lock, flags); |
462 | 462 | ||
463 | return rc; | 463 | return rc; |
464 | } | 464 | } |
@@ -624,17 +624,17 @@ int erst_write(const struct cper_record_header *record) | |||
624 | return -EINVAL; | 624 | return -EINVAL; |
625 | 625 | ||
626 | if (erst_erange.attr & ERST_RANGE_NVRAM) { | 626 | if (erst_erange.attr & ERST_RANGE_NVRAM) { |
627 | if (!spin_trylock_irqsave(&erst_lock, flags)) | 627 | if (!raw_spin_trylock_irqsave(&erst_lock, flags)) |
628 | return -EBUSY; | 628 | return -EBUSY; |
629 | rc = __erst_write_to_nvram(record); | 629 | rc = __erst_write_to_nvram(record); |
630 | spin_unlock_irqrestore(&erst_lock, flags); | 630 | raw_spin_unlock_irqrestore(&erst_lock, flags); |
631 | return rc; | 631 | return rc; |
632 | } | 632 | } |
633 | 633 | ||
634 | if (record->record_length > erst_erange.size) | 634 | if (record->record_length > erst_erange.size) |
635 | return -EINVAL; | 635 | return -EINVAL; |
636 | 636 | ||
637 | if (!spin_trylock_irqsave(&erst_lock, flags)) | 637 | if (!raw_spin_trylock_irqsave(&erst_lock, flags)) |
638 | return -EBUSY; | 638 | return -EBUSY; |
639 | memcpy(erst_erange.vaddr, record, record->record_length); | 639 | memcpy(erst_erange.vaddr, record, record->record_length); |
640 | rcd_erange = erst_erange.vaddr; | 640 | rcd_erange = erst_erange.vaddr; |
@@ -642,7 +642,7 @@ int erst_write(const struct cper_record_header *record) | |||
642 | memcpy(&rcd_erange->persistence_information, "ER", 2); | 642 | memcpy(&rcd_erange->persistence_information, "ER", 2); |
643 | 643 | ||
644 | rc = __erst_write_to_storage(0); | 644 | rc = __erst_write_to_storage(0); |
645 | spin_unlock_irqrestore(&erst_lock, flags); | 645 | raw_spin_unlock_irqrestore(&erst_lock, flags); |
646 | 646 | ||
647 | return rc; | 647 | return rc; |
648 | } | 648 | } |
@@ -696,9 +696,9 @@ ssize_t erst_read(u64 record_id, struct cper_record_header *record, | |||
696 | if (erst_disable) | 696 | if (erst_disable) |
697 | return -ENODEV; | 697 | return -ENODEV; |
698 | 698 | ||
699 | spin_lock_irqsave(&erst_lock, flags); | 699 | raw_spin_lock_irqsave(&erst_lock, flags); |
700 | len = __erst_read(record_id, record, buflen); | 700 | len = __erst_read(record_id, record, buflen); |
701 | spin_unlock_irqrestore(&erst_lock, flags); | 701 | raw_spin_unlock_irqrestore(&erst_lock, flags); |
702 | return len; | 702 | return len; |
703 | } | 703 | } |
704 | EXPORT_SYMBOL_GPL(erst_read); | 704 | EXPORT_SYMBOL_GPL(erst_read); |
@@ -719,20 +719,20 @@ ssize_t erst_read_next(struct cper_record_header *record, size_t buflen) | |||
719 | if (erst_disable) | 719 | if (erst_disable) |
720 | return -ENODEV; | 720 | return -ENODEV; |
721 | 721 | ||
722 | spin_lock_irqsave(&erst_lock, flags); | 722 | raw_spin_lock_irqsave(&erst_lock, flags); |
723 | rc = __erst_get_next_record_id(&record_id); | 723 | rc = __erst_get_next_record_id(&record_id); |
724 | if (rc) { | 724 | if (rc) { |
725 | spin_unlock_irqrestore(&erst_lock, flags); | 725 | raw_spin_unlock_irqrestore(&erst_lock, flags); |
726 | return rc; | 726 | return rc; |
727 | } | 727 | } |
728 | /* no more record */ | 728 | /* no more record */ |
729 | if (record_id == APEI_ERST_INVALID_RECORD_ID) { | 729 | if (record_id == APEI_ERST_INVALID_RECORD_ID) { |
730 | spin_unlock_irqrestore(&erst_lock, flags); | 730 | raw_spin_unlock_irqrestore(&erst_lock, flags); |
731 | return 0; | 731 | return 0; |
732 | } | 732 | } |
733 | 733 | ||
734 | len = __erst_read(record_id, record, buflen); | 734 | len = __erst_read(record_id, record, buflen); |
735 | spin_unlock_irqrestore(&erst_lock, flags); | 735 | raw_spin_unlock_irqrestore(&erst_lock, flags); |
736 | 736 | ||
737 | return len; | 737 | return len; |
738 | } | 738 | } |
@@ -746,12 +746,12 @@ int erst_clear(u64 record_id) | |||
746 | if (erst_disable) | 746 | if (erst_disable) |
747 | return -ENODEV; | 747 | return -ENODEV; |
748 | 748 | ||
749 | spin_lock_irqsave(&erst_lock, flags); | 749 | raw_spin_lock_irqsave(&erst_lock, flags); |
750 | if (erst_erange.attr & ERST_RANGE_NVRAM) | 750 | if (erst_erange.attr & ERST_RANGE_NVRAM) |
751 | rc = __erst_clear_from_nvram(record_id); | 751 | rc = __erst_clear_from_nvram(record_id); |
752 | else | 752 | else |
753 | rc = __erst_clear_from_storage(record_id); | 753 | rc = __erst_clear_from_storage(record_id); |
754 | spin_unlock_irqrestore(&erst_lock, flags); | 754 | raw_spin_unlock_irqrestore(&erst_lock, flags); |
755 | 755 | ||
756 | return rc; | 756 | return rc; |
757 | } | 757 | } |
diff --git a/drivers/acpi/apei/hest.c b/drivers/acpi/apei/hest.c index 1a3508a7fe03..daa7bc63f1d4 100644 --- a/drivers/acpi/apei/hest.c +++ b/drivers/acpi/apei/hest.c | |||
@@ -46,9 +46,9 @@ EXPORT_SYMBOL_GPL(hest_disable); | |||
46 | 46 | ||
47 | /* HEST table parsing */ | 47 | /* HEST table parsing */ |
48 | 48 | ||
49 | static struct acpi_table_hest *hest_tab; | 49 | static struct acpi_table_hest *__read_mostly hest_tab; |
50 | 50 | ||
51 | static int hest_esrc_len_tab[ACPI_HEST_TYPE_RESERVED] = { | 51 | static const int hest_esrc_len_tab[ACPI_HEST_TYPE_RESERVED] = { |
52 | [ACPI_HEST_TYPE_IA32_CHECK] = -1, /* need further calculation */ | 52 | [ACPI_HEST_TYPE_IA32_CHECK] = -1, /* need further calculation */ |
53 | [ACPI_HEST_TYPE_IA32_CORRECTED_CHECK] = -1, | 53 | [ACPI_HEST_TYPE_IA32_CORRECTED_CHECK] = -1, |
54 | [ACPI_HEST_TYPE_IA32_NMI] = sizeof(struct acpi_hest_ia_nmi), | 54 | [ACPI_HEST_TYPE_IA32_NMI] = sizeof(struct acpi_hest_ia_nmi), |
@@ -126,7 +126,7 @@ struct ghes_arr { | |||
126 | unsigned int count; | 126 | unsigned int count; |
127 | }; | 127 | }; |
128 | 128 | ||
129 | static int hest_parse_ghes_count(struct acpi_hest_header *hest_hdr, void *data) | 129 | static int __init hest_parse_ghes_count(struct acpi_hest_header *hest_hdr, void *data) |
130 | { | 130 | { |
131 | int *count = data; | 131 | int *count = data; |
132 | 132 | ||
@@ -135,7 +135,7 @@ static int hest_parse_ghes_count(struct acpi_hest_header *hest_hdr, void *data) | |||
135 | return 0; | 135 | return 0; |
136 | } | 136 | } |
137 | 137 | ||
138 | static int hest_parse_ghes(struct acpi_hest_header *hest_hdr, void *data) | 138 | static int __init hest_parse_ghes(struct acpi_hest_header *hest_hdr, void *data) |
139 | { | 139 | { |
140 | struct platform_device *ghes_dev; | 140 | struct platform_device *ghes_dev; |
141 | struct ghes_arr *ghes_arr = data; | 141 | struct ghes_arr *ghes_arr = data; |
@@ -165,7 +165,7 @@ err: | |||
165 | return rc; | 165 | return rc; |
166 | } | 166 | } |
167 | 167 | ||
168 | static int hest_ghes_dev_register(unsigned int ghes_count) | 168 | static int __init hest_ghes_dev_register(unsigned int ghes_count) |
169 | { | 169 | { |
170 | int rc, i; | 170 | int rc, i; |
171 | struct ghes_arr ghes_arr; | 171 | struct ghes_arr ghes_arr; |
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 95649d373071..9fb9d5ac939d 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c | |||
@@ -130,6 +130,8 @@ struct acpi_battery { | |||
130 | unsigned long flags; | 130 | unsigned long flags; |
131 | }; | 131 | }; |
132 | 132 | ||
133 | static int acpi_battery_update(struct acpi_battery *battery); | ||
134 | |||
133 | #define to_acpi_battery(x) container_of(x, struct acpi_battery, bat); | 135 | #define to_acpi_battery(x) container_of(x, struct acpi_battery, bat); |
134 | 136 | ||
135 | inline int acpi_battery_present(struct acpi_battery *battery) | 137 | inline int acpi_battery_present(struct acpi_battery *battery) |
@@ -184,6 +186,9 @@ static int acpi_battery_get_property(struct power_supply *psy, | |||
184 | int ret = 0; | 186 | int ret = 0; |
185 | struct acpi_battery *battery = to_acpi_battery(psy); | 187 | struct acpi_battery *battery = to_acpi_battery(psy); |
186 | 188 | ||
189 | if (acpi_battery_update(battery)) | ||
190 | return -ENODEV; | ||
191 | |||
187 | if (acpi_battery_present(battery)) { | 192 | if (acpi_battery_present(battery)) { |
188 | /* run battery update only if it is present */ | 193 | /* run battery update only if it is present */ |
189 | acpi_battery_get_state(battery); | 194 | acpi_battery_get_state(battery); |
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 372ff80b7b0c..302b31ed31f1 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c | |||
@@ -934,6 +934,9 @@ static struct dmi_system_id __initdata ec_dmi_table[] = { | |||
934 | ec_flag_msi, "MSI hardware", { | 934 | ec_flag_msi, "MSI hardware", { |
935 | DMI_MATCH(DMI_CHASSIS_VENDOR, "MICRO-Star")}, NULL}, | 935 | DMI_MATCH(DMI_CHASSIS_VENDOR, "MICRO-Star")}, NULL}, |
936 | { | 936 | { |
937 | ec_flag_msi, "MSI hardware", { | ||
938 | DMI_MATCH(DMI_CHASSIS_VENDOR, "MICRO-STAR")}, NULL}, | ||
939 | { | ||
937 | ec_validate_ecdt, "ASUS hardware", { | 940 | ec_validate_ecdt, "ASUS hardware", { |
938 | DMI_MATCH(DMI_BIOS_VENDOR, "ASUS") }, NULL}, | 941 | DMI_MATCH(DMI_BIOS_VENDOR, "ASUS") }, NULL}, |
939 | {}, | 942 | {}, |
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 966feddf6b1b..055d7b701fff 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c | |||
@@ -110,9 +110,6 @@ struct acpi_ioremap { | |||
110 | static LIST_HEAD(acpi_ioremaps); | 110 | static LIST_HEAD(acpi_ioremaps); |
111 | static DEFINE_SPINLOCK(acpi_ioremap_lock); | 111 | static DEFINE_SPINLOCK(acpi_ioremap_lock); |
112 | 112 | ||
113 | #define OSI_STRING_LENGTH_MAX 64 /* arbitrary */ | ||
114 | static char osi_setup_string[OSI_STRING_LENGTH_MAX]; | ||
115 | |||
116 | static void __init acpi_osi_setup_late(void); | 113 | static void __init acpi_osi_setup_late(void); |
117 | 114 | ||
118 | /* | 115 | /* |
@@ -152,8 +149,7 @@ static struct osi_linux { | |||
152 | unsigned int enable:1; | 149 | unsigned int enable:1; |
153 | unsigned int dmi:1; | 150 | unsigned int dmi:1; |
154 | unsigned int cmdline:1; | 151 | unsigned int cmdline:1; |
155 | unsigned int known:1; | 152 | } osi_linux = {0, 0, 0}; |
156 | } osi_linux = { 0, 0, 0, 0}; | ||
157 | 153 | ||
158 | static u32 acpi_osi_handler(acpi_string interface, u32 supported) | 154 | static u32 acpi_osi_handler(acpi_string interface, u32 supported) |
159 | { | 155 | { |
@@ -1055,13 +1051,53 @@ static int __init acpi_os_name_setup(char *str) | |||
1055 | 1051 | ||
1056 | __setup("acpi_os_name=", acpi_os_name_setup); | 1052 | __setup("acpi_os_name=", acpi_os_name_setup); |
1057 | 1053 | ||
1054 | #define OSI_STRING_LENGTH_MAX 64 /* arbitrary */ | ||
1055 | #define OSI_STRING_ENTRIES_MAX 16 /* arbitrary */ | ||
1056 | |||
1057 | struct osi_setup_entry { | ||
1058 | char string[OSI_STRING_LENGTH_MAX]; | ||
1059 | bool enable; | ||
1060 | }; | ||
1061 | |||
1062 | static struct osi_setup_entry __initdata osi_setup_entries[OSI_STRING_ENTRIES_MAX]; | ||
1063 | |||
1064 | void __init acpi_osi_setup(char *str) | ||
1065 | { | ||
1066 | struct osi_setup_entry *osi; | ||
1067 | bool enable = true; | ||
1068 | int i; | ||
1069 | |||
1070 | if (!acpi_gbl_create_osi_method) | ||
1071 | return; | ||
1072 | |||
1073 | if (str == NULL || *str == '\0') { | ||
1074 | printk(KERN_INFO PREFIX "_OSI method disabled\n"); | ||
1075 | acpi_gbl_create_osi_method = FALSE; | ||
1076 | return; | ||
1077 | } | ||
1078 | |||
1079 | if (*str == '!') { | ||
1080 | str++; | ||
1081 | enable = false; | ||
1082 | } | ||
1083 | |||
1084 | for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) { | ||
1085 | osi = &osi_setup_entries[i]; | ||
1086 | if (!strcmp(osi->string, str)) { | ||
1087 | osi->enable = enable; | ||
1088 | break; | ||
1089 | } else if (osi->string[0] == '\0') { | ||
1090 | osi->enable = enable; | ||
1091 | strncpy(osi->string, str, OSI_STRING_LENGTH_MAX); | ||
1092 | break; | ||
1093 | } | ||
1094 | } | ||
1095 | } | ||
1096 | |||
1058 | static void __init set_osi_linux(unsigned int enable) | 1097 | static void __init set_osi_linux(unsigned int enable) |
1059 | { | 1098 | { |
1060 | if (osi_linux.enable != enable) { | 1099 | if (osi_linux.enable != enable) |
1061 | osi_linux.enable = enable; | 1100 | osi_linux.enable = enable; |
1062 | printk(KERN_NOTICE PREFIX "%sed _OSI(Linux)\n", | ||
1063 | enable ? "Add": "Delet"); | ||
1064 | } | ||
1065 | 1101 | ||
1066 | if (osi_linux.enable) | 1102 | if (osi_linux.enable) |
1067 | acpi_osi_setup("Linux"); | 1103 | acpi_osi_setup("Linux"); |
@@ -1073,7 +1109,8 @@ static void __init set_osi_linux(unsigned int enable) | |||
1073 | 1109 | ||
1074 | static void __init acpi_cmdline_osi_linux(unsigned int enable) | 1110 | static void __init acpi_cmdline_osi_linux(unsigned int enable) |
1075 | { | 1111 | { |
1076 | osi_linux.cmdline = 1; /* cmdline set the default */ | 1112 | osi_linux.cmdline = 1; /* cmdline set the default and override DMI */ |
1113 | osi_linux.dmi = 0; | ||
1077 | set_osi_linux(enable); | 1114 | set_osi_linux(enable); |
1078 | 1115 | ||
1079 | return; | 1116 | return; |
@@ -1081,15 +1118,12 @@ static void __init acpi_cmdline_osi_linux(unsigned int enable) | |||
1081 | 1118 | ||
1082 | void __init acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d) | 1119 | void __init acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d) |
1083 | { | 1120 | { |
1084 | osi_linux.dmi = 1; /* DMI knows that this box asks OSI(Linux) */ | ||
1085 | |||
1086 | printk(KERN_NOTICE PREFIX "DMI detected: %s\n", d->ident); | 1121 | printk(KERN_NOTICE PREFIX "DMI detected: %s\n", d->ident); |
1087 | 1122 | ||
1088 | if (enable == -1) | 1123 | if (enable == -1) |
1089 | return; | 1124 | return; |
1090 | 1125 | ||
1091 | osi_linux.known = 1; /* DMI knows which OSI(Linux) default needed */ | 1126 | osi_linux.dmi = 1; /* DMI knows that this box asks OSI(Linux) */ |
1092 | |||
1093 | set_osi_linux(enable); | 1127 | set_osi_linux(enable); |
1094 | 1128 | ||
1095 | return; | 1129 | return; |
@@ -1104,37 +1138,44 @@ void __init acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d) | |||
1104 | */ | 1138 | */ |
1105 | static void __init acpi_osi_setup_late(void) | 1139 | static void __init acpi_osi_setup_late(void) |
1106 | { | 1140 | { |
1107 | char *str = osi_setup_string; | 1141 | struct osi_setup_entry *osi; |
1142 | char *str; | ||
1143 | int i; | ||
1144 | acpi_status status; | ||
1108 | 1145 | ||
1109 | if (*str == '\0') | 1146 | for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) { |
1110 | return; | 1147 | osi = &osi_setup_entries[i]; |
1148 | str = osi->string; | ||
1111 | 1149 | ||
1112 | if (!strcmp("!Linux", str)) { | 1150 | if (*str == '\0') |
1113 | acpi_cmdline_osi_linux(0); /* !enable */ | 1151 | break; |
1114 | } else if (*str == '!') { | 1152 | if (osi->enable) { |
1115 | if (acpi_remove_interface(++str) == AE_OK) | 1153 | status = acpi_install_interface(str); |
1116 | printk(KERN_INFO PREFIX "Deleted _OSI(%s)\n", str); | 1154 | |
1117 | } else if (!strcmp("Linux", str)) { | 1155 | if (ACPI_SUCCESS(status)) |
1118 | acpi_cmdline_osi_linux(1); /* enable */ | 1156 | printk(KERN_INFO PREFIX "Added _OSI(%s)\n", str); |
1119 | } else { | 1157 | } else { |
1120 | if (acpi_install_interface(str) == AE_OK) | 1158 | status = acpi_remove_interface(str); |
1121 | printk(KERN_INFO PREFIX "Added _OSI(%s)\n", str); | 1159 | |
1160 | if (ACPI_SUCCESS(status)) | ||
1161 | printk(KERN_INFO PREFIX "Deleted _OSI(%s)\n", str); | ||
1162 | } | ||
1122 | } | 1163 | } |
1123 | } | 1164 | } |
1124 | 1165 | ||
1125 | int __init acpi_osi_setup(char *str) | 1166 | static int __init osi_setup(char *str) |
1126 | { | 1167 | { |
1127 | if (str == NULL || *str == '\0') { | 1168 | if (str && !strcmp("Linux", str)) |
1128 | printk(KERN_INFO PREFIX "_OSI method disabled\n"); | 1169 | acpi_cmdline_osi_linux(1); |
1129 | acpi_gbl_create_osi_method = FALSE; | 1170 | else if (str && !strcmp("!Linux", str)) |
1130 | } else { | 1171 | acpi_cmdline_osi_linux(0); |
1131 | strncpy(osi_setup_string, str, OSI_STRING_LENGTH_MAX); | 1172 | else |
1132 | } | 1173 | acpi_osi_setup(str); |
1133 | 1174 | ||
1134 | return 1; | 1175 | return 1; |
1135 | } | 1176 | } |
1136 | 1177 | ||
1137 | __setup("acpi_osi=", acpi_osi_setup); | 1178 | __setup("acpi_osi=", osi_setup); |
1138 | 1179 | ||
1139 | /* enable serialization to combat AE_ALREADY_EXISTS errors */ | 1180 | /* enable serialization to combat AE_ALREADY_EXISTS errors */ |
1140 | static int __init acpi_serialize_setup(char *str) | 1181 | static int __init acpi_serialize_setup(char *str) |
@@ -1530,7 +1571,7 @@ acpi_status __init acpi_os_initialize(void) | |||
1530 | return AE_OK; | 1571 | return AE_OK; |
1531 | } | 1572 | } |
1532 | 1573 | ||
1533 | acpi_status acpi_os_initialize1(void) | 1574 | acpi_status __init acpi_os_initialize1(void) |
1534 | { | 1575 | { |
1535 | kacpid_wq = create_workqueue("kacpid"); | 1576 | kacpid_wq = create_workqueue("kacpid"); |
1536 | kacpi_notify_wq = create_workqueue("kacpi_notify"); | 1577 | kacpi_notify_wq = create_workqueue("kacpi_notify"); |
diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c index 67dedeed144c..4c9c2fb5d98f 100644 --- a/drivers/acpi/power.c +++ b/drivers/acpi/power.c | |||
@@ -213,11 +213,13 @@ static int acpi_power_on(acpi_handle handle) | |||
213 | resource->name)); | 213 | resource->name)); |
214 | } else { | 214 | } else { |
215 | result = __acpi_power_on(resource); | 215 | result = __acpi_power_on(resource); |
216 | if (result) | ||
217 | resource->ref_count--; | ||
216 | } | 218 | } |
217 | 219 | ||
218 | mutex_unlock(&resource->resource_lock); | 220 | mutex_unlock(&resource->resource_lock); |
219 | 221 | ||
220 | return 0; | 222 | return result; |
221 | } | 223 | } |
222 | 224 | ||
223 | static int acpi_power_off_device(acpi_handle handle) | 225 | static int acpi_power_off_device(acpi_handle handle) |
@@ -465,10 +467,12 @@ int acpi_power_transition(struct acpi_device *device, int state) | |||
465 | struct acpi_handle_list *tl = NULL; /* Target Resources */ | 467 | struct acpi_handle_list *tl = NULL; /* Target Resources */ |
466 | int i = 0; | 468 | int i = 0; |
467 | 469 | ||
468 | |||
469 | if (!device || (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3)) | 470 | if (!device || (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3)) |
470 | return -EINVAL; | 471 | return -EINVAL; |
471 | 472 | ||
473 | if (device->power.state == state) | ||
474 | return 0; | ||
475 | |||
472 | if ((device->power.state < ACPI_STATE_D0) | 476 | if ((device->power.state < ACPI_STATE_D0) |
473 | || (device->power.state > ACPI_STATE_D3)) | 477 | || (device->power.state > ACPI_STATE_D3)) |
474 | return -ENODEV; | 478 | return -ENODEV; |
@@ -488,10 +492,6 @@ int acpi_power_transition(struct acpi_device *device, int state) | |||
488 | goto end; | 492 | goto end; |
489 | } | 493 | } |
490 | 494 | ||
491 | if (device->power.state == state) { | ||
492 | goto end; | ||
493 | } | ||
494 | |||
495 | /* | 495 | /* |
496 | * Then we dereference all power resources used in the current list. | 496 | * Then we dereference all power resources used in the current list. |
497 | */ | 497 | */ |
diff --git a/drivers/acpi/processor_thermal.c b/drivers/acpi/processor_thermal.c index fde49b9b1d99..79cb65332894 100644 --- a/drivers/acpi/processor_thermal.c +++ b/drivers/acpi/processor_thermal.c | |||
@@ -156,15 +156,6 @@ static int cpufreq_set_cur_state(unsigned int cpu, int state) | |||
156 | return 0; | 156 | return 0; |
157 | } | 157 | } |
158 | 158 | ||
159 | static int acpi_thermal_cpufreq_increase(unsigned int cpu) | ||
160 | { | ||
161 | return -ENODEV; | ||
162 | } | ||
163 | static int acpi_thermal_cpufreq_decrease(unsigned int cpu) | ||
164 | { | ||
165 | return -ENODEV; | ||
166 | } | ||
167 | |||
168 | #endif | 159 | #endif |
169 | 160 | ||
170 | int acpi_processor_get_limit_info(struct acpi_processor *pr) | 161 | int acpi_processor_get_limit_info(struct acpi_processor *pr) |
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index 721d93b3ceee..febb153b5a68 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c | |||
@@ -27,8 +27,6 @@ | |||
27 | 27 | ||
28 | static u8 sleep_states[ACPI_S_STATE_COUNT]; | 28 | static u8 sleep_states[ACPI_S_STATE_COUNT]; |
29 | 29 | ||
30 | static u32 acpi_target_sleep_state = ACPI_STATE_S0; | ||
31 | |||
32 | static void acpi_sleep_tts_switch(u32 acpi_state) | 30 | static void acpi_sleep_tts_switch(u32 acpi_state) |
33 | { | 31 | { |
34 | union acpi_object in_arg = { ACPI_TYPE_INTEGER }; | 32 | union acpi_object in_arg = { ACPI_TYPE_INTEGER }; |
@@ -81,6 +79,8 @@ static int acpi_sleep_prepare(u32 acpi_state) | |||
81 | } | 79 | } |
82 | 80 | ||
83 | #ifdef CONFIG_ACPI_SLEEP | 81 | #ifdef CONFIG_ACPI_SLEEP |
82 | static u32 acpi_target_sleep_state = ACPI_STATE_S0; | ||
83 | |||
84 | /* | 84 | /* |
85 | * The ACPI specification wants us to save NVS memory regions during hibernation | 85 | * The ACPI specification wants us to save NVS memory regions during hibernation |
86 | * and to restore them during the subsequent resume. Windows does that also for | 86 | * and to restore them during the subsequent resume. Windows does that also for |
@@ -427,6 +427,14 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = { | |||
427 | DMI_MATCH(DMI_PRODUCT_NAME, "VPCEB1Z1E"), | 427 | DMI_MATCH(DMI_PRODUCT_NAME, "VPCEB1Z1E"), |
428 | }, | 428 | }, |
429 | }, | 429 | }, |
430 | { | ||
431 | .callback = init_nvs_nosave, | ||
432 | .ident = "Sony Vaio VGN-NW130D", | ||
433 | .matches = { | ||
434 | DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), | ||
435 | DMI_MATCH(DMI_PRODUCT_NAME, "VGN-NW130D"), | ||
436 | }, | ||
437 | }, | ||
430 | {}, | 438 | {}, |
431 | }; | 439 | }; |
432 | #endif /* CONFIG_SUSPEND */ | 440 | #endif /* CONFIG_SUSPEND */ |
diff --git a/drivers/atm/adummy.c b/drivers/atm/adummy.c index 46b94762125b..f9b983ae6877 100644 --- a/drivers/atm/adummy.c +++ b/drivers/atm/adummy.c | |||
@@ -154,7 +154,7 @@ static int __init adummy_init(void) | |||
154 | err = -ENOMEM; | 154 | err = -ENOMEM; |
155 | goto out; | 155 | goto out; |
156 | } | 156 | } |
157 | atm_dev = atm_dev_register(DEV_LABEL, &adummy_ops, -1, NULL); | 157 | atm_dev = atm_dev_register(DEV_LABEL, NULL, &adummy_ops, -1, NULL); |
158 | if (!atm_dev) { | 158 | if (!atm_dev) { |
159 | printk(KERN_ERR DEV_LABEL ": atm_dev_register() failed\n"); | 159 | printk(KERN_ERR DEV_LABEL ": atm_dev_register() failed\n"); |
160 | err = -ENODEV; | 160 | err = -ENODEV; |
diff --git a/drivers/atm/ambassador.c b/drivers/atm/ambassador.c index a33896a482e6..ffe9b655292e 100644 --- a/drivers/atm/ambassador.c +++ b/drivers/atm/ambassador.c | |||
@@ -2244,7 +2244,8 @@ static int __devinit amb_probe(struct pci_dev *pci_dev, const struct pci_device_ | |||
2244 | goto out_reset; | 2244 | goto out_reset; |
2245 | } | 2245 | } |
2246 | 2246 | ||
2247 | dev->atm_dev = atm_dev_register (DEV_LABEL, &amb_ops, -1, NULL); | 2247 | dev->atm_dev = atm_dev_register (DEV_LABEL, &pci_dev->dev, &amb_ops, -1, |
2248 | NULL); | ||
2248 | if (!dev->atm_dev) { | 2249 | if (!dev->atm_dev) { |
2249 | PRINTD (DBG_ERR, "failed to register Madge ATM adapter"); | 2250 | PRINTD (DBG_ERR, "failed to register Madge ATM adapter"); |
2250 | err = -EINVAL; | 2251 | err = -EINVAL; |
diff --git a/drivers/atm/atmtcp.c b/drivers/atm/atmtcp.c index b9101818b47b..2b464b631f22 100644 --- a/drivers/atm/atmtcp.c +++ b/drivers/atm/atmtcp.c | |||
@@ -366,7 +366,7 @@ static int atmtcp_create(int itf,int persist,struct atm_dev **result) | |||
366 | if (!dev_data) | 366 | if (!dev_data) |
367 | return -ENOMEM; | 367 | return -ENOMEM; |
368 | 368 | ||
369 | dev = atm_dev_register(DEV_LABEL,&atmtcp_v_dev_ops,itf,NULL); | 369 | dev = atm_dev_register(DEV_LABEL,NULL,&atmtcp_v_dev_ops,itf,NULL); |
370 | if (!dev) { | 370 | if (!dev) { |
371 | kfree(dev_data); | 371 | kfree(dev_data); |
372 | return itf == -1 ? -ENOMEM : -EBUSY; | 372 | return itf == -1 ? -ENOMEM : -EBUSY; |
diff --git a/drivers/atm/eni.c b/drivers/atm/eni.c index 97c5898cd76e..c495fae74200 100644 --- a/drivers/atm/eni.c +++ b/drivers/atm/eni.c | |||
@@ -2244,7 +2244,7 @@ static int __devinit eni_init_one(struct pci_dev *pci_dev, | |||
2244 | &zeroes); | 2244 | &zeroes); |
2245 | if (!cpu_zeroes) goto out1; | 2245 | if (!cpu_zeroes) goto out1; |
2246 | } | 2246 | } |
2247 | dev = atm_dev_register(DEV_LABEL,&ops,-1,NULL); | 2247 | dev = atm_dev_register(DEV_LABEL, &pci_dev->dev, &ops, -1, NULL); |
2248 | if (!dev) goto out2; | 2248 | if (!dev) goto out2; |
2249 | pci_set_drvdata(pci_dev, dev); | 2249 | pci_set_drvdata(pci_dev, dev); |
2250 | eni_dev->pci_dev = pci_dev; | 2250 | eni_dev->pci_dev = pci_dev; |
diff --git a/drivers/atm/firestream.c b/drivers/atm/firestream.c index 5d86bb803e94..7d912baf01d4 100644 --- a/drivers/atm/firestream.c +++ b/drivers/atm/firestream.c | |||
@@ -1911,7 +1911,7 @@ static int __devinit firestream_init_one (struct pci_dev *pci_dev, | |||
1911 | fs_dev, sizeof (struct fs_dev)); | 1911 | fs_dev, sizeof (struct fs_dev)); |
1912 | if (!fs_dev) | 1912 | if (!fs_dev) |
1913 | goto err_out; | 1913 | goto err_out; |
1914 | atm_dev = atm_dev_register("fs", &ops, -1, NULL); | 1914 | atm_dev = atm_dev_register("fs", &pci_dev->dev, &ops, -1, NULL); |
1915 | if (!atm_dev) | 1915 | if (!atm_dev) |
1916 | goto err_out_free_fs_dev; | 1916 | goto err_out_free_fs_dev; |
1917 | 1917 | ||
diff --git a/drivers/atm/fore200e.c b/drivers/atm/fore200e.c index c8fc69c85a06..962c309b40c0 100644 --- a/drivers/atm/fore200e.c +++ b/drivers/atm/fore200e.c | |||
@@ -2567,14 +2567,14 @@ release: | |||
2567 | 2567 | ||
2568 | 2568 | ||
2569 | static int __devinit | 2569 | static int __devinit |
2570 | fore200e_register(struct fore200e* fore200e) | 2570 | fore200e_register(struct fore200e* fore200e, struct device *parent) |
2571 | { | 2571 | { |
2572 | struct atm_dev* atm_dev; | 2572 | struct atm_dev* atm_dev; |
2573 | 2573 | ||
2574 | DPRINTK(2, "device %s being registered\n", fore200e->name); | 2574 | DPRINTK(2, "device %s being registered\n", fore200e->name); |
2575 | 2575 | ||
2576 | atm_dev = atm_dev_register(fore200e->bus->proc_name, &fore200e_ops, -1, | 2576 | atm_dev = atm_dev_register(fore200e->bus->proc_name, parent, &fore200e_ops, |
2577 | NULL); | 2577 | -1, NULL); |
2578 | if (atm_dev == NULL) { | 2578 | if (atm_dev == NULL) { |
2579 | printk(FORE200E "unable to register device %s\n", fore200e->name); | 2579 | printk(FORE200E "unable to register device %s\n", fore200e->name); |
2580 | return -ENODEV; | 2580 | return -ENODEV; |
@@ -2594,9 +2594,9 @@ fore200e_register(struct fore200e* fore200e) | |||
2594 | 2594 | ||
2595 | 2595 | ||
2596 | static int __devinit | 2596 | static int __devinit |
2597 | fore200e_init(struct fore200e* fore200e) | 2597 | fore200e_init(struct fore200e* fore200e, struct device *parent) |
2598 | { | 2598 | { |
2599 | if (fore200e_register(fore200e) < 0) | 2599 | if (fore200e_register(fore200e, parent) < 0) |
2600 | return -ENODEV; | 2600 | return -ENODEV; |
2601 | 2601 | ||
2602 | if (fore200e->bus->configure(fore200e) < 0) | 2602 | if (fore200e->bus->configure(fore200e) < 0) |
@@ -2662,7 +2662,7 @@ static int __devinit fore200e_sba_probe(struct platform_device *op, | |||
2662 | 2662 | ||
2663 | sprintf(fore200e->name, "%s-%d", bus->model_name, index); | 2663 | sprintf(fore200e->name, "%s-%d", bus->model_name, index); |
2664 | 2664 | ||
2665 | err = fore200e_init(fore200e); | 2665 | err = fore200e_init(fore200e, &op->dev); |
2666 | if (err < 0) { | 2666 | if (err < 0) { |
2667 | fore200e_shutdown(fore200e); | 2667 | fore200e_shutdown(fore200e); |
2668 | kfree(fore200e); | 2668 | kfree(fore200e); |
@@ -2740,7 +2740,7 @@ fore200e_pca_detect(struct pci_dev *pci_dev, const struct pci_device_id *pci_ent | |||
2740 | 2740 | ||
2741 | sprintf(fore200e->name, "%s-%d", bus->model_name, index); | 2741 | sprintf(fore200e->name, "%s-%d", bus->model_name, index); |
2742 | 2742 | ||
2743 | err = fore200e_init(fore200e); | 2743 | err = fore200e_init(fore200e, &pci_dev->dev); |
2744 | if (err < 0) { | 2744 | if (err < 0) { |
2745 | fore200e_shutdown(fore200e); | 2745 | fore200e_shutdown(fore200e); |
2746 | goto out_free; | 2746 | goto out_free; |
diff --git a/drivers/atm/he.c b/drivers/atm/he.c index 801e8b6e9d1f..6cf59bf281dc 100644 --- a/drivers/atm/he.c +++ b/drivers/atm/he.c | |||
@@ -366,7 +366,7 @@ he_init_one(struct pci_dev *pci_dev, const struct pci_device_id *pci_ent) | |||
366 | goto init_one_failure; | 366 | goto init_one_failure; |
367 | } | 367 | } |
368 | 368 | ||
369 | atm_dev = atm_dev_register(DEV_LABEL, &he_ops, -1, NULL); | 369 | atm_dev = atm_dev_register(DEV_LABEL, &pci_dev->dev, &he_ops, -1, NULL); |
370 | if (!atm_dev) { | 370 | if (!atm_dev) { |
371 | err = -ENODEV; | 371 | err = -ENODEV; |
372 | goto init_one_failure; | 372 | goto init_one_failure; |
diff --git a/drivers/atm/horizon.c b/drivers/atm/horizon.c index a95790452a68..24761e1d6642 100644 --- a/drivers/atm/horizon.c +++ b/drivers/atm/horizon.c | |||
@@ -2733,7 +2733,8 @@ static int __devinit hrz_probe(struct pci_dev *pci_dev, const struct pci_device_ | |||
2733 | PRINTD(DBG_INFO, "found Madge ATM adapter (hrz) at: IO %x, IRQ %u, MEM %p", | 2733 | PRINTD(DBG_INFO, "found Madge ATM adapter (hrz) at: IO %x, IRQ %u, MEM %p", |
2734 | iobase, irq, membase); | 2734 | iobase, irq, membase); |
2735 | 2735 | ||
2736 | dev->atm_dev = atm_dev_register(DEV_LABEL, &hrz_ops, -1, NULL); | 2736 | dev->atm_dev = atm_dev_register(DEV_LABEL, &pci_dev->dev, &hrz_ops, -1, |
2737 | NULL); | ||
2737 | if (!(dev->atm_dev)) { | 2738 | if (!(dev->atm_dev)) { |
2738 | PRINTD(DBG_ERR, "failed to register Madge ATM adapter"); | 2739 | PRINTD(DBG_ERR, "failed to register Madge ATM adapter"); |
2739 | err = -EINVAL; | 2740 | err = -EINVAL; |
diff --git a/drivers/atm/idt77252.c b/drivers/atm/idt77252.c index bce57328ddde..bfb7feee0400 100644 --- a/drivers/atm/idt77252.c +++ b/drivers/atm/idt77252.c | |||
@@ -3698,7 +3698,8 @@ idt77252_init_one(struct pci_dev *pcidev, const struct pci_device_id *id) | |||
3698 | goto err_out_iounmap; | 3698 | goto err_out_iounmap; |
3699 | } | 3699 | } |
3700 | 3700 | ||
3701 | dev = atm_dev_register("idt77252", &idt77252_ops, -1, NULL); | 3701 | dev = atm_dev_register("idt77252", &pcidev->dev, &idt77252_ops, -1, |
3702 | NULL); | ||
3702 | if (!dev) { | 3703 | if (!dev) { |
3703 | printk("%s: can't register atm device\n", card->name); | 3704 | printk("%s: can't register atm device\n", card->name); |
3704 | err = -EIO; | 3705 | err = -EIO; |
diff --git a/drivers/atm/iphase.c b/drivers/atm/iphase.c index 9309d4724e13..729254053758 100644 --- a/drivers/atm/iphase.c +++ b/drivers/atm/iphase.c | |||
@@ -3172,7 +3172,7 @@ static int __devinit ia_init_one(struct pci_dev *pdev, | |||
3172 | ret = -ENODEV; | 3172 | ret = -ENODEV; |
3173 | goto err_out_free_iadev; | 3173 | goto err_out_free_iadev; |
3174 | } | 3174 | } |
3175 | dev = atm_dev_register(DEV_LABEL, &ops, -1, NULL); | 3175 | dev = atm_dev_register(DEV_LABEL, &pdev->dev, &ops, -1, NULL); |
3176 | if (!dev) { | 3176 | if (!dev) { |
3177 | ret = -ENOMEM; | 3177 | ret = -ENOMEM; |
3178 | goto err_out_disable_dev; | 3178 | goto err_out_disable_dev; |
diff --git a/drivers/atm/lanai.c b/drivers/atm/lanai.c index cbe15a86c669..a395c9aab146 100644 --- a/drivers/atm/lanai.c +++ b/drivers/atm/lanai.c | |||
@@ -2591,7 +2591,7 @@ static int __devinit lanai_init_one(struct pci_dev *pci, | |||
2591 | return -ENOMEM; | 2591 | return -ENOMEM; |
2592 | } | 2592 | } |
2593 | 2593 | ||
2594 | atmdev = atm_dev_register(DEV_LABEL, &ops, -1, NULL); | 2594 | atmdev = atm_dev_register(DEV_LABEL, &pci->dev, &ops, -1, NULL); |
2595 | if (atmdev == NULL) { | 2595 | if (atmdev == NULL) { |
2596 | printk(KERN_ERR DEV_LABEL | 2596 | printk(KERN_ERR DEV_LABEL |
2597 | ": couldn't register atm device!\n"); | 2597 | ": couldn't register atm device!\n"); |
diff --git a/drivers/atm/nicstar.c b/drivers/atm/nicstar.c index 2f3516b7f118..6b313ee9231b 100644 --- a/drivers/atm/nicstar.c +++ b/drivers/atm/nicstar.c | |||
@@ -771,7 +771,8 @@ static int __devinit ns_init_card(int i, struct pci_dev *pcidev) | |||
771 | } | 771 | } |
772 | 772 | ||
773 | /* Register device */ | 773 | /* Register device */ |
774 | card->atmdev = atm_dev_register("nicstar", &atm_ops, -1, NULL); | 774 | card->atmdev = atm_dev_register("nicstar", &card->pcidev->dev, &atm_ops, |
775 | -1, NULL); | ||
775 | if (card->atmdev == NULL) { | 776 | if (card->atmdev == NULL) { |
776 | printk("nicstar%d: can't register device.\n", i); | 777 | printk("nicstar%d: can't register device.\n", i); |
777 | error = 17; | 778 | error = 17; |
diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c index 2e08c996fd30..73fb1c4f4cd4 100644 --- a/drivers/atm/solos-pci.c +++ b/drivers/atm/solos-pci.c | |||
@@ -166,7 +166,7 @@ static irqreturn_t solos_irq(int irq, void *dev_id); | |||
166 | static struct atm_vcc* find_vcc(struct atm_dev *dev, short vpi, int vci); | 166 | static struct atm_vcc* find_vcc(struct atm_dev *dev, short vpi, int vci); |
167 | static int list_vccs(int vci); | 167 | static int list_vccs(int vci); |
168 | static void release_vccs(struct atm_dev *dev); | 168 | static void release_vccs(struct atm_dev *dev); |
169 | static int atm_init(struct solos_card *); | 169 | static int atm_init(struct solos_card *, struct device *); |
170 | static void atm_remove(struct solos_card *); | 170 | static void atm_remove(struct solos_card *); |
171 | static int send_command(struct solos_card *card, int dev, const char *buf, size_t size); | 171 | static int send_command(struct solos_card *card, int dev, const char *buf, size_t size); |
172 | static void solos_bh(unsigned long); | 172 | static void solos_bh(unsigned long); |
@@ -1210,7 +1210,7 @@ static int fpga_probe(struct pci_dev *dev, const struct pci_device_id *id) | |||
1210 | if (db_firmware_upgrade) | 1210 | if (db_firmware_upgrade) |
1211 | flash_upgrade(card, 3); | 1211 | flash_upgrade(card, 3); |
1212 | 1212 | ||
1213 | err = atm_init(card); | 1213 | err = atm_init(card, &dev->dev); |
1214 | if (err) | 1214 | if (err) |
1215 | goto out_free_irq; | 1215 | goto out_free_irq; |
1216 | 1216 | ||
@@ -1233,7 +1233,7 @@ static int fpga_probe(struct pci_dev *dev, const struct pci_device_id *id) | |||
1233 | return err; | 1233 | return err; |
1234 | } | 1234 | } |
1235 | 1235 | ||
1236 | static int atm_init(struct solos_card *card) | 1236 | static int atm_init(struct solos_card *card, struct device *parent) |
1237 | { | 1237 | { |
1238 | int i; | 1238 | int i; |
1239 | 1239 | ||
@@ -1244,7 +1244,7 @@ static int atm_init(struct solos_card *card) | |||
1244 | skb_queue_head_init(&card->tx_queue[i]); | 1244 | skb_queue_head_init(&card->tx_queue[i]); |
1245 | skb_queue_head_init(&card->cli_queue[i]); | 1245 | skb_queue_head_init(&card->cli_queue[i]); |
1246 | 1246 | ||
1247 | card->atmdev[i] = atm_dev_register("solos-pci", &fpga_ops, -1, NULL); | 1247 | card->atmdev[i] = atm_dev_register("solos-pci", parent, &fpga_ops, -1, NULL); |
1248 | if (!card->atmdev[i]) { | 1248 | if (!card->atmdev[i]) { |
1249 | dev_err(&card->dev->dev, "Could not register ATM device %d\n", i); | 1249 | dev_err(&card->dev->dev, "Could not register ATM device %d\n", i); |
1250 | atm_remove(card); | 1250 | atm_remove(card); |
diff --git a/drivers/atm/zatm.c b/drivers/atm/zatm.c index 4e885d2da49c..624917902b65 100644 --- a/drivers/atm/zatm.c +++ b/drivers/atm/zatm.c | |||
@@ -1597,7 +1597,7 @@ static int __devinit zatm_init_one(struct pci_dev *pci_dev, | |||
1597 | goto out; | 1597 | goto out; |
1598 | } | 1598 | } |
1599 | 1599 | ||
1600 | dev = atm_dev_register(DEV_LABEL, &ops, -1, NULL); | 1600 | dev = atm_dev_register(DEV_LABEL, &pci_dev->dev, &ops, -1, NULL); |
1601 | if (!dev) | 1601 | if (!dev) |
1602 | goto out_free; | 1602 | goto out_free; |
1603 | 1603 | ||
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index 4f9e22f29138..657873e4328d 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c | |||
@@ -72,7 +72,7 @@ struct blk_shadow { | |||
72 | static DEFINE_MUTEX(blkfront_mutex); | 72 | static DEFINE_MUTEX(blkfront_mutex); |
73 | static const struct block_device_operations xlvbd_block_fops; | 73 | static const struct block_device_operations xlvbd_block_fops; |
74 | 74 | ||
75 | #define BLK_RING_SIZE __RING_SIZE((struct blkif_sring *)0, PAGE_SIZE) | 75 | #define BLK_RING_SIZE __CONST_RING_SIZE(blkif, PAGE_SIZE) |
76 | 76 | ||
77 | /* | 77 | /* |
78 | * We have one of these per vbd, whether ide, scsi or 'other'. They | 78 | * We have one of these per vbd, whether ide, scsi or 'other'. They |
diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c index 128cae4e8629..949ed09c6361 100644 --- a/drivers/bluetooth/ath3k.c +++ b/drivers/bluetooth/ath3k.c | |||
@@ -35,6 +35,10 @@ | |||
35 | static struct usb_device_id ath3k_table[] = { | 35 | static struct usb_device_id ath3k_table[] = { |
36 | /* Atheros AR3011 */ | 36 | /* Atheros AR3011 */ |
37 | { USB_DEVICE(0x0CF3, 0x3000) }, | 37 | { USB_DEVICE(0x0CF3, 0x3000) }, |
38 | |||
39 | /* Atheros AR3011 with sflash firmware*/ | ||
40 | { USB_DEVICE(0x0CF3, 0x3002) }, | ||
41 | |||
38 | { } /* Terminating entry */ | 42 | { } /* Terminating entry */ |
39 | }; | 43 | }; |
40 | 44 | ||
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index ab3894f742c3..1da773f899a2 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c | |||
@@ -99,6 +99,9 @@ static struct usb_device_id blacklist_table[] = { | |||
99 | /* Broadcom BCM2033 without firmware */ | 99 | /* Broadcom BCM2033 without firmware */ |
100 | { USB_DEVICE(0x0a5c, 0x2033), .driver_info = BTUSB_IGNORE }, | 100 | { USB_DEVICE(0x0a5c, 0x2033), .driver_info = BTUSB_IGNORE }, |
101 | 101 | ||
102 | /* Atheros 3011 with sflash firmware */ | ||
103 | { USB_DEVICE(0x0cf3, 0x3002), .driver_info = BTUSB_IGNORE }, | ||
104 | |||
102 | /* Broadcom BCM2035 */ | 105 | /* Broadcom BCM2035 */ |
103 | { USB_DEVICE(0x0a5c, 0x2035), .driver_info = BTUSB_WRONG_SCO_MTU }, | 106 | { USB_DEVICE(0x0a5c, 0x2035), .driver_info = BTUSB_WRONG_SCO_MTU }, |
104 | { USB_DEVICE(0x0a5c, 0x200a), .driver_info = BTUSB_WRONG_SCO_MTU }, | 107 | { USB_DEVICE(0x0a5c, 0x200a), .driver_info = BTUSB_WRONG_SCO_MTU }, |
@@ -239,7 +242,8 @@ static void btusb_intr_complete(struct urb *urb) | |||
239 | 242 | ||
240 | err = usb_submit_urb(urb, GFP_ATOMIC); | 243 | err = usb_submit_urb(urb, GFP_ATOMIC); |
241 | if (err < 0) { | 244 | if (err < 0) { |
242 | BT_ERR("%s urb %p failed to resubmit (%d)", | 245 | if (err != -EPERM) |
246 | BT_ERR("%s urb %p failed to resubmit (%d)", | ||
243 | hdev->name, urb, -err); | 247 | hdev->name, urb, -err); |
244 | usb_unanchor_urb(urb); | 248 | usb_unanchor_urb(urb); |
245 | } | 249 | } |
@@ -323,7 +327,8 @@ static void btusb_bulk_complete(struct urb *urb) | |||
323 | 327 | ||
324 | err = usb_submit_urb(urb, GFP_ATOMIC); | 328 | err = usb_submit_urb(urb, GFP_ATOMIC); |
325 | if (err < 0) { | 329 | if (err < 0) { |
326 | BT_ERR("%s urb %p failed to resubmit (%d)", | 330 | if (err != -EPERM) |
331 | BT_ERR("%s urb %p failed to resubmit (%d)", | ||
327 | hdev->name, urb, -err); | 332 | hdev->name, urb, -err); |
328 | usb_unanchor_urb(urb); | 333 | usb_unanchor_urb(urb); |
329 | } | 334 | } |
@@ -412,7 +417,8 @@ static void btusb_isoc_complete(struct urb *urb) | |||
412 | 417 | ||
413 | err = usb_submit_urb(urb, GFP_ATOMIC); | 418 | err = usb_submit_urb(urb, GFP_ATOMIC); |
414 | if (err < 0) { | 419 | if (err < 0) { |
415 | BT_ERR("%s urb %p failed to resubmit (%d)", | 420 | if (err != -EPERM) |
421 | BT_ERR("%s urb %p failed to resubmit (%d)", | ||
416 | hdev->name, urb, -err); | 422 | hdev->name, urb, -err); |
417 | usb_unanchor_urb(urb); | 423 | usb_unanchor_urb(urb); |
418 | } | 424 | } |
diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c index 9272c38dd3c6..16a2847b7cdb 100644 --- a/drivers/char/agp/intel-gtt.c +++ b/drivers/char/agp/intel-gtt.c | |||
@@ -812,8 +812,10 @@ static int intel_fake_agp_fetch_size(void) | |||
812 | 812 | ||
813 | static void i830_cleanup(void) | 813 | static void i830_cleanup(void) |
814 | { | 814 | { |
815 | kunmap(intel_private.i8xx_page); | 815 | if (intel_private.i8xx_flush_page) { |
816 | intel_private.i8xx_flush_page = NULL; | 816 | kunmap(intel_private.i8xx_flush_page); |
817 | intel_private.i8xx_flush_page = NULL; | ||
818 | } | ||
817 | 819 | ||
818 | __free_page(intel_private.i8xx_page); | 820 | __free_page(intel_private.i8xx_page); |
819 | intel_private.i8xx_page = NULL; | 821 | intel_private.i8xx_page = NULL; |
diff --git a/drivers/connector/connector.c b/drivers/connector/connector.c index e16c3fa8d2e3..05117f1ad867 100644 --- a/drivers/connector/connector.c +++ b/drivers/connector/connector.c | |||
@@ -36,6 +36,7 @@ | |||
36 | MODULE_LICENSE("GPL"); | 36 | MODULE_LICENSE("GPL"); |
37 | MODULE_AUTHOR("Evgeniy Polyakov <zbr@ioremap.net>"); | 37 | MODULE_AUTHOR("Evgeniy Polyakov <zbr@ioremap.net>"); |
38 | MODULE_DESCRIPTION("Generic userspace <-> kernelspace connector."); | 38 | MODULE_DESCRIPTION("Generic userspace <-> kernelspace connector."); |
39 | MODULE_ALIAS_NET_PF_PROTO(PF_NETLINK, NETLINK_CONNECTOR); | ||
39 | 40 | ||
40 | static struct cn_dev cdev; | 41 | static struct cn_dev cdev; |
41 | 42 | ||
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile index a8a84f4587f2..64b21f5cd740 100644 --- a/drivers/dma/Makefile +++ b/drivers/dma/Makefile | |||
@@ -1,8 +1,8 @@ | |||
1 | ifeq ($(CONFIG_DMADEVICES_DEBUG),y) | 1 | ifeq ($(CONFIG_DMADEVICES_DEBUG),y) |
2 | EXTRA_CFLAGS += -DDEBUG | 2 | ccflags-y += -DDEBUG |
3 | endif | 3 | endif |
4 | ifeq ($(CONFIG_DMADEVICES_VDEBUG),y) | 4 | ifeq ($(CONFIG_DMADEVICES_VDEBUG),y) |
5 | EXTRA_CFLAGS += -DVERBOSE_DEBUG | 5 | ccflags-y += -DVERBOSE_DEBUG |
6 | endif | 6 | endif |
7 | 7 | ||
8 | obj-$(CONFIG_DMA_ENGINE) += dmaengine.o | 8 | obj-$(CONFIG_DMA_ENGINE) += dmaengine.o |
diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c index a0f3e6a06e06..ea0ee81cff53 100644 --- a/drivers/dma/at_hdmac.c +++ b/drivers/dma/at_hdmac.c | |||
@@ -722,7 +722,7 @@ atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, | |||
722 | desc->lli.daddr = mem; | 722 | desc->lli.daddr = mem; |
723 | desc->lli.ctrla = ctrla | 723 | desc->lli.ctrla = ctrla |
724 | | ATC_DST_WIDTH(mem_width) | 724 | | ATC_DST_WIDTH(mem_width) |
725 | | len >> mem_width; | 725 | | len >> reg_width; |
726 | desc->lli.ctrlb = ctrlb; | 726 | desc->lli.ctrlb = ctrlb; |
727 | 727 | ||
728 | if (!first) { | 728 | if (!first) { |
diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c index 286c3ac6bdcc..e5e172d21692 100644 --- a/drivers/dma/fsldma.c +++ b/drivers/dma/fsldma.c | |||
@@ -50,9 +50,11 @@ static void dma_init(struct fsldma_chan *chan) | |||
50 | * EIE - Error interrupt enable | 50 | * EIE - Error interrupt enable |
51 | * EOSIE - End of segments interrupt enable (basic mode) | 51 | * EOSIE - End of segments interrupt enable (basic mode) |
52 | * EOLNIE - End of links interrupt enable | 52 | * EOLNIE - End of links interrupt enable |
53 | * BWC - Bandwidth sharing among channels | ||
53 | */ | 54 | */ |
54 | DMA_OUT(chan, &chan->regs->mr, FSL_DMA_MR_EIE | 55 | DMA_OUT(chan, &chan->regs->mr, FSL_DMA_MR_BWC |
55 | | FSL_DMA_MR_EOLNIE | FSL_DMA_MR_EOSIE, 32); | 56 | | FSL_DMA_MR_EIE | FSL_DMA_MR_EOLNIE |
57 | | FSL_DMA_MR_EOSIE, 32); | ||
56 | break; | 58 | break; |
57 | case FSL_DMA_IP_83XX: | 59 | case FSL_DMA_IP_83XX: |
58 | /* Set the channel to below modes: | 60 | /* Set the channel to below modes: |
diff --git a/drivers/dma/fsldma.h b/drivers/dma/fsldma.h index cb4d6ff51597..ba9f403c0fbe 100644 --- a/drivers/dma/fsldma.h +++ b/drivers/dma/fsldma.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2007 Freescale Semiconductor, Inc. All rights reserved. | 2 | * Copyright (C) 2007-2010 Freescale Semiconductor, Inc. All rights reserved. |
3 | * | 3 | * |
4 | * Author: | 4 | * Author: |
5 | * Zhang Wei <wei.zhang@freescale.com>, Jul 2007 | 5 | * Zhang Wei <wei.zhang@freescale.com>, Jul 2007 |
@@ -36,6 +36,13 @@ | |||
36 | #define FSL_DMA_MR_DAHE 0x00002000 | 36 | #define FSL_DMA_MR_DAHE 0x00002000 |
37 | #define FSL_DMA_MR_SAHE 0x00001000 | 37 | #define FSL_DMA_MR_SAHE 0x00001000 |
38 | 38 | ||
39 | /* | ||
40 | * Bandwidth/pause control determines how many bytes a given | ||
41 | * channel is allowed to transfer before the DMA engine pauses | ||
42 | * the current channel and switches to the next channel | ||
43 | */ | ||
44 | #define FSL_DMA_MR_BWC 0x08000000 | ||
45 | |||
39 | /* Special MR definition for MPC8349 */ | 46 | /* Special MR definition for MPC8349 */ |
40 | #define FSL_DMA_MR_EOTIE 0x00000080 | 47 | #define FSL_DMA_MR_EOTIE 0x00000080 |
41 | #define FSL_DMA_MR_PRC_RM 0x00000800 | 48 | #define FSL_DMA_MR_PRC_RM 0x00000800 |
diff --git a/drivers/dma/imx-dma.c b/drivers/dma/imx-dma.c index f629e4961af5..e53d438142bb 100644 --- a/drivers/dma/imx-dma.c +++ b/drivers/dma/imx-dma.c | |||
@@ -379,7 +379,7 @@ static int __init imxdma_probe(struct platform_device *pdev) | |||
379 | return 0; | 379 | return 0; |
380 | 380 | ||
381 | err_init: | 381 | err_init: |
382 | while (i-- >= 0) { | 382 | while (--i >= 0) { |
383 | struct imxdma_channel *imxdmac = &imxdma->channel[i]; | 383 | struct imxdma_channel *imxdmac = &imxdma->channel[i]; |
384 | imx_dma_free(imxdmac->imxdma_channel); | 384 | imx_dma_free(imxdmac->imxdma_channel); |
385 | } | 385 | } |
diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c index 01166a9c3241..d5a5d4d9c19b 100644 --- a/drivers/dma/imx-sdma.c +++ b/drivers/dma/imx-sdma.c | |||
@@ -907,7 +907,7 @@ static struct dma_async_tx_descriptor *sdma_prep_slave_sg( | |||
907 | struct sdma_buffer_descriptor *bd = &sdmac->bd[i]; | 907 | struct sdma_buffer_descriptor *bd = &sdmac->bd[i]; |
908 | int param; | 908 | int param; |
909 | 909 | ||
910 | bd->buffer_addr = sgl->dma_address; | 910 | bd->buffer_addr = sg->dma_address; |
911 | 911 | ||
912 | count = sg->length; | 912 | count = sg->length; |
913 | 913 | ||
@@ -1367,7 +1367,7 @@ static int __init sdma_module_init(void) | |||
1367 | { | 1367 | { |
1368 | return platform_driver_probe(&sdma_driver, sdma_probe); | 1368 | return platform_driver_probe(&sdma_driver, sdma_probe); |
1369 | } | 1369 | } |
1370 | subsys_initcall(sdma_module_init); | 1370 | module_init(sdma_module_init); |
1371 | 1371 | ||
1372 | MODULE_AUTHOR("Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>"); | 1372 | MODULE_AUTHOR("Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>"); |
1373 | MODULE_DESCRIPTION("i.MX SDMA driver"); | 1373 | MODULE_DESCRIPTION("i.MX SDMA driver"); |
diff --git a/drivers/dma/intel_mid_dma.c b/drivers/dma/intel_mid_dma.c index 338bc4eed1f3..3109bd94bc4f 100644 --- a/drivers/dma/intel_mid_dma.c +++ b/drivers/dma/intel_mid_dma.c | |||
@@ -1075,7 +1075,6 @@ static int mid_setup_dma(struct pci_dev *pdev) | |||
1075 | if (NULL == dma->dma_pool) { | 1075 | if (NULL == dma->dma_pool) { |
1076 | pr_err("ERR_MDMA:pci_pool_create failed\n"); | 1076 | pr_err("ERR_MDMA:pci_pool_create failed\n"); |
1077 | err = -ENOMEM; | 1077 | err = -ENOMEM; |
1078 | kfree(dma); | ||
1079 | goto err_dma_pool; | 1078 | goto err_dma_pool; |
1080 | } | 1079 | } |
1081 | 1080 | ||
@@ -1186,7 +1185,6 @@ err_engine: | |||
1186 | free_irq(pdev->irq, dma); | 1185 | free_irq(pdev->irq, dma); |
1187 | err_irq: | 1186 | err_irq: |
1188 | pci_pool_destroy(dma->dma_pool); | 1187 | pci_pool_destroy(dma->dma_pool); |
1189 | kfree(dma); | ||
1190 | err_dma_pool: | 1188 | err_dma_pool: |
1191 | pr_err("ERR_MDMA:setup_dma failed: %d\n", err); | 1189 | pr_err("ERR_MDMA:setup_dma failed: %d\n", err); |
1192 | return err; | 1190 | return err; |
@@ -1413,7 +1411,7 @@ static const struct dev_pm_ops intel_mid_dma_pm = { | |||
1413 | .runtime_idle = dma_runtime_idle, | 1411 | .runtime_idle = dma_runtime_idle, |
1414 | }; | 1412 | }; |
1415 | 1413 | ||
1416 | static struct pci_driver intel_mid_dma_pci = { | 1414 | static struct pci_driver intel_mid_dma_pci_driver = { |
1417 | .name = "Intel MID DMA", | 1415 | .name = "Intel MID DMA", |
1418 | .id_table = intel_mid_dma_ids, | 1416 | .id_table = intel_mid_dma_ids, |
1419 | .probe = intel_mid_dma_probe, | 1417 | .probe = intel_mid_dma_probe, |
@@ -1431,13 +1429,13 @@ static int __init intel_mid_dma_init(void) | |||
1431 | { | 1429 | { |
1432 | pr_debug("INFO_MDMA: LNW DMA Driver Version %s\n", | 1430 | pr_debug("INFO_MDMA: LNW DMA Driver Version %s\n", |
1433 | INTEL_MID_DMA_DRIVER_VERSION); | 1431 | INTEL_MID_DMA_DRIVER_VERSION); |
1434 | return pci_register_driver(&intel_mid_dma_pci); | 1432 | return pci_register_driver(&intel_mid_dma_pci_driver); |
1435 | } | 1433 | } |
1436 | fs_initcall(intel_mid_dma_init); | 1434 | fs_initcall(intel_mid_dma_init); |
1437 | 1435 | ||
1438 | static void __exit intel_mid_dma_exit(void) | 1436 | static void __exit intel_mid_dma_exit(void) |
1439 | { | 1437 | { |
1440 | pci_unregister_driver(&intel_mid_dma_pci); | 1438 | pci_unregister_driver(&intel_mid_dma_pci_driver); |
1441 | } | 1439 | } |
1442 | module_exit(intel_mid_dma_exit); | 1440 | module_exit(intel_mid_dma_exit); |
1443 | 1441 | ||
diff --git a/drivers/dma/ioat/Makefile b/drivers/dma/ioat/Makefile index 8997d3fb9051..0ff7270af25b 100644 --- a/drivers/dma/ioat/Makefile +++ b/drivers/dma/ioat/Makefile | |||
@@ -1,2 +1,2 @@ | |||
1 | obj-$(CONFIG_INTEL_IOATDMA) += ioatdma.o | 1 | obj-$(CONFIG_INTEL_IOATDMA) += ioatdma.o |
2 | ioatdma-objs := pci.o dma.o dma_v2.o dma_v3.o dca.o | 2 | ioatdma-y := pci.o dma.o dma_v2.o dma_v3.o dca.o |
diff --git a/drivers/dma/pch_dma.c b/drivers/dma/pch_dma.c index 92b679024fed..c064c89420d0 100644 --- a/drivers/dma/pch_dma.c +++ b/drivers/dma/pch_dma.c | |||
@@ -259,11 +259,6 @@ static void pdc_dostart(struct pch_dma_chan *pd_chan, struct pch_dma_desc* desc) | |||
259 | return; | 259 | return; |
260 | } | 260 | } |
261 | 261 | ||
262 | channel_writel(pd_chan, DEV_ADDR, desc->regs.dev_addr); | ||
263 | channel_writel(pd_chan, MEM_ADDR, desc->regs.mem_addr); | ||
264 | channel_writel(pd_chan, SIZE, desc->regs.size); | ||
265 | channel_writel(pd_chan, NEXT, desc->regs.next); | ||
266 | |||
267 | dev_dbg(chan2dev(&pd_chan->chan), "chan %d -> dev_addr: %x\n", | 262 | dev_dbg(chan2dev(&pd_chan->chan), "chan %d -> dev_addr: %x\n", |
268 | pd_chan->chan.chan_id, desc->regs.dev_addr); | 263 | pd_chan->chan.chan_id, desc->regs.dev_addr); |
269 | dev_dbg(chan2dev(&pd_chan->chan), "chan %d -> mem_addr: %x\n", | 264 | dev_dbg(chan2dev(&pd_chan->chan), "chan %d -> mem_addr: %x\n", |
@@ -273,10 +268,16 @@ static void pdc_dostart(struct pch_dma_chan *pd_chan, struct pch_dma_desc* desc) | |||
273 | dev_dbg(chan2dev(&pd_chan->chan), "chan %d -> next: %x\n", | 268 | dev_dbg(chan2dev(&pd_chan->chan), "chan %d -> next: %x\n", |
274 | pd_chan->chan.chan_id, desc->regs.next); | 269 | pd_chan->chan.chan_id, desc->regs.next); |
275 | 270 | ||
276 | if (list_empty(&desc->tx_list)) | 271 | if (list_empty(&desc->tx_list)) { |
272 | channel_writel(pd_chan, DEV_ADDR, desc->regs.dev_addr); | ||
273 | channel_writel(pd_chan, MEM_ADDR, desc->regs.mem_addr); | ||
274 | channel_writel(pd_chan, SIZE, desc->regs.size); | ||
275 | channel_writel(pd_chan, NEXT, desc->regs.next); | ||
277 | pdc_set_mode(&pd_chan->chan, DMA_CTL0_ONESHOT); | 276 | pdc_set_mode(&pd_chan->chan, DMA_CTL0_ONESHOT); |
278 | else | 277 | } else { |
278 | channel_writel(pd_chan, NEXT, desc->txd.phys); | ||
279 | pdc_set_mode(&pd_chan->chan, DMA_CTL0_SG); | 279 | pdc_set_mode(&pd_chan->chan, DMA_CTL0_SG); |
280 | } | ||
280 | 281 | ||
281 | val = dma_readl(pd, CTL2); | 282 | val = dma_readl(pd, CTL2); |
282 | val |= 1 << (DMA_CTL2_START_SHIFT_BITS + pd_chan->chan.chan_id); | 283 | val |= 1 << (DMA_CTL2_START_SHIFT_BITS + pd_chan->chan.chan_id); |
diff --git a/drivers/dma/ppc4xx/adma.c b/drivers/dma/ppc4xx/adma.c index 0d58a4a4487f..cef584533ee8 100644 --- a/drivers/dma/ppc4xx/adma.c +++ b/drivers/dma/ppc4xx/adma.c | |||
@@ -4449,9 +4449,8 @@ static int __devinit ppc440spe_adma_probe(struct platform_device *ofdev, | |||
4449 | 4449 | ||
4450 | if (!request_mem_region(res.start, resource_size(&res), | 4450 | if (!request_mem_region(res.start, resource_size(&res), |
4451 | dev_driver_string(&ofdev->dev))) { | 4451 | dev_driver_string(&ofdev->dev))) { |
4452 | dev_err(&ofdev->dev, "failed to request memory region " | 4452 | dev_err(&ofdev->dev, "failed to request memory region %pR\n", |
4453 | "(0x%016llx-0x%016llx)\n", | 4453 | &res); |
4454 | (u64)res.start, (u64)res.end); | ||
4455 | initcode = PPC_ADMA_INIT_MEMREG; | 4454 | initcode = PPC_ADMA_INIT_MEMREG; |
4456 | ret = -EBUSY; | 4455 | ret = -EBUSY; |
4457 | goto out; | 4456 | goto out; |
diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c index 8521401bbd75..eca9ba193e94 100644 --- a/drivers/edac/amd64_edac.c +++ b/drivers/edac/amd64_edac.c | |||
@@ -1572,7 +1572,7 @@ static int f10_match_to_this_node(struct amd64_pvt *pvt, int dram_range, | |||
1572 | debugf1(" HoleOffset=0x%x HoleValid=0x%x IntlvSel=0x%x\n", | 1572 | debugf1(" HoleOffset=0x%x HoleValid=0x%x IntlvSel=0x%x\n", |
1573 | hole_off, hole_valid, intlv_sel); | 1573 | hole_off, hole_valid, intlv_sel); |
1574 | 1574 | ||
1575 | if (intlv_en || | 1575 | if (intlv_en && |
1576 | (intlv_sel != ((sys_addr >> 12) & intlv_en))) | 1576 | (intlv_sel != ((sys_addr >> 12) & intlv_en))) |
1577 | return -EINVAL; | 1577 | return -EINVAL; |
1578 | 1578 | ||
diff --git a/drivers/edac/edac_core.h b/drivers/edac/edac_core.h index d7ca43a828bd..251440cd50a3 100644 --- a/drivers/edac/edac_core.h +++ b/drivers/edac/edac_core.h | |||
@@ -41,10 +41,10 @@ | |||
41 | #define MC_PROC_NAME_MAX_LEN 7 | 41 | #define MC_PROC_NAME_MAX_LEN 7 |
42 | 42 | ||
43 | #if PAGE_SHIFT < 20 | 43 | #if PAGE_SHIFT < 20 |
44 | #define PAGES_TO_MiB( pages ) ( ( pages ) >> ( 20 - PAGE_SHIFT ) ) | 44 | #define PAGES_TO_MiB(pages) ((pages) >> (20 - PAGE_SHIFT)) |
45 | #define MiB_TO_PAGES(mb) ((mb) >> (20 - PAGE_SHIFT)) | 45 | #define MiB_TO_PAGES(mb) ((mb) << (20 - PAGE_SHIFT)) |
46 | #else /* PAGE_SHIFT > 20 */ | 46 | #else /* PAGE_SHIFT > 20 */ |
47 | #define PAGES_TO_MiB( pages ) ( ( pages ) << ( PAGE_SHIFT - 20 ) ) | 47 | #define PAGES_TO_MiB(pages) ((pages) << (PAGE_SHIFT - 20)) |
48 | #define MiB_TO_PAGES(mb) ((mb) >> (PAGE_SHIFT - 20)) | 48 | #define MiB_TO_PAGES(mb) ((mb) >> (PAGE_SHIFT - 20)) |
49 | #endif | 49 | #endif |
50 | 50 | ||
diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c index ba6586a69ccc..795ea69c4d8f 100644 --- a/drivers/edac/edac_mc.c +++ b/drivers/edac/edac_mc.c | |||
@@ -586,14 +586,16 @@ struct mem_ctl_info *edac_mc_del_mc(struct device *dev) | |||
586 | return NULL; | 586 | return NULL; |
587 | } | 587 | } |
588 | 588 | ||
589 | /* marking MCI offline */ | ||
590 | mci->op_state = OP_OFFLINE; | ||
591 | |||
592 | del_mc_from_global_list(mci); | 589 | del_mc_from_global_list(mci); |
593 | mutex_unlock(&mem_ctls_mutex); | 590 | mutex_unlock(&mem_ctls_mutex); |
594 | 591 | ||
595 | /* flush workq processes and remove sysfs */ | 592 | /* flush workq processes */ |
596 | edac_mc_workq_teardown(mci); | 593 | edac_mc_workq_teardown(mci); |
594 | |||
595 | /* marking MCI offline */ | ||
596 | mci->op_state = OP_OFFLINE; | ||
597 | |||
598 | /* remove from sysfs */ | ||
597 | edac_remove_sysfs_mci_device(mci); | 599 | edac_remove_sysfs_mci_device(mci); |
598 | 600 | ||
599 | edac_printk(KERN_INFO, EDAC_MC, | 601 | edac_printk(KERN_INFO, EDAC_MC, |
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c index 84eb607d6c03..e3c8b60bd86b 100644 --- a/drivers/firewire/ohci.c +++ b/drivers/firewire/ohci.c | |||
@@ -242,6 +242,7 @@ static inline struct fw_ohci *fw_ohci(struct fw_card *card) | |||
242 | 242 | ||
243 | static char ohci_driver_name[] = KBUILD_MODNAME; | 243 | static char ohci_driver_name[] = KBUILD_MODNAME; |
244 | 244 | ||
245 | #define PCI_DEVICE_ID_AGERE_FW643 0x5901 | ||
245 | #define PCI_DEVICE_ID_JMICRON_JMB38X_FW 0x2380 | 246 | #define PCI_DEVICE_ID_JMICRON_JMB38X_FW 0x2380 |
246 | #define PCI_DEVICE_ID_TI_TSB12LV22 0x8009 | 247 | #define PCI_DEVICE_ID_TI_TSB12LV22 0x8009 |
247 | 248 | ||
@@ -253,18 +254,34 @@ static char ohci_driver_name[] = KBUILD_MODNAME; | |||
253 | 254 | ||
254 | /* In case of multiple matches in ohci_quirks[], only the first one is used. */ | 255 | /* In case of multiple matches in ohci_quirks[], only the first one is used. */ |
255 | static const struct { | 256 | static const struct { |
256 | unsigned short vendor, device, flags; | 257 | unsigned short vendor, device, revision, flags; |
257 | } ohci_quirks[] = { | 258 | } ohci_quirks[] = { |
258 | {PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_TSB12LV22, QUIRK_CYCLE_TIMER | | 259 | {PCI_VENDOR_ID_AL, PCI_ANY_ID, PCI_ANY_ID, |
259 | QUIRK_RESET_PACKET | | 260 | QUIRK_CYCLE_TIMER}, |
260 | QUIRK_NO_1394A}, | 261 | |
261 | {PCI_VENDOR_ID_TI, PCI_ANY_ID, QUIRK_RESET_PACKET}, | 262 | {PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_UNI_N_FW, PCI_ANY_ID, |
262 | {PCI_VENDOR_ID_AL, PCI_ANY_ID, QUIRK_CYCLE_TIMER}, | 263 | QUIRK_BE_HEADERS}, |
263 | {PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB38X_FW, QUIRK_NO_MSI}, | 264 | |
264 | {PCI_VENDOR_ID_NEC, PCI_ANY_ID, QUIRK_CYCLE_TIMER}, | 265 | {PCI_VENDOR_ID_ATT, PCI_DEVICE_ID_AGERE_FW643, 6, |
265 | {PCI_VENDOR_ID_VIA, PCI_ANY_ID, QUIRK_CYCLE_TIMER}, | 266 | QUIRK_NO_MSI}, |
266 | {PCI_VENDOR_ID_RICOH, PCI_ANY_ID, QUIRK_CYCLE_TIMER}, | 267 | |
267 | {PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_UNI_N_FW, QUIRK_BE_HEADERS}, | 268 | {PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB38X_FW, PCI_ANY_ID, |
269 | QUIRK_NO_MSI}, | ||
270 | |||
271 | {PCI_VENDOR_ID_NEC, PCI_ANY_ID, PCI_ANY_ID, | ||
272 | QUIRK_CYCLE_TIMER}, | ||
273 | |||
274 | {PCI_VENDOR_ID_RICOH, PCI_ANY_ID, PCI_ANY_ID, | ||
275 | QUIRK_CYCLE_TIMER}, | ||
276 | |||
277 | {PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_TSB12LV22, PCI_ANY_ID, | ||
278 | QUIRK_CYCLE_TIMER | QUIRK_RESET_PACKET | QUIRK_NO_1394A}, | ||
279 | |||
280 | {PCI_VENDOR_ID_TI, PCI_ANY_ID, PCI_ANY_ID, | ||
281 | QUIRK_RESET_PACKET}, | ||
282 | |||
283 | {PCI_VENDOR_ID_VIA, PCI_ANY_ID, PCI_ANY_ID, | ||
284 | QUIRK_CYCLE_TIMER | QUIRK_NO_MSI}, | ||
268 | }; | 285 | }; |
269 | 286 | ||
270 | /* This overrides anything that was found in ohci_quirks[]. */ | 287 | /* This overrides anything that was found in ohci_quirks[]. */ |
@@ -2927,9 +2944,11 @@ static int __devinit pci_probe(struct pci_dev *dev, | |||
2927 | } | 2944 | } |
2928 | 2945 | ||
2929 | for (i = 0; i < ARRAY_SIZE(ohci_quirks); i++) | 2946 | for (i = 0; i < ARRAY_SIZE(ohci_quirks); i++) |
2930 | if (ohci_quirks[i].vendor == dev->vendor && | 2947 | if ((ohci_quirks[i].vendor == dev->vendor) && |
2931 | (ohci_quirks[i].device == dev->device || | 2948 | (ohci_quirks[i].device == (unsigned short)PCI_ANY_ID || |
2932 | ohci_quirks[i].device == (unsigned short)PCI_ANY_ID)) { | 2949 | ohci_quirks[i].device == dev->device) && |
2950 | (ohci_quirks[i].revision == (unsigned short)PCI_ANY_ID || | ||
2951 | ohci_quirks[i].revision >= dev->revision)) { | ||
2933 | ohci->quirks = ohci_quirks[i].flags; | 2952 | ohci->quirks = ohci_quirks[i].flags; |
2934 | break; | 2953 | break; |
2935 | } | 2954 | } |
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 3143ac795eb0..082495bb08a7 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig | |||
@@ -230,11 +230,11 @@ config GPIO_STMPE | |||
230 | This enables support for the GPIOs found on the STMPE I/O | 230 | This enables support for the GPIOs found on the STMPE I/O |
231 | Expanders. | 231 | Expanders. |
232 | 232 | ||
233 | config GPIO_TC35892 | 233 | config GPIO_TC3589X |
234 | bool "TC35892 GPIOs" | 234 | bool "TC3589X GPIOs" |
235 | depends on MFD_TC35892 | 235 | depends on MFD_TC3589X |
236 | help | 236 | help |
237 | This enables support for the GPIOs found on the TC35892 | 237 | This enables support for the GPIOs found on the TC3589X |
238 | I/O Expander. | 238 | I/O Expander. |
239 | 239 | ||
240 | config GPIO_TWL4030 | 240 | config GPIO_TWL4030 |
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index bdf3ddec0652..39bfd7a37650 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile | |||
@@ -24,7 +24,7 @@ obj-$(CONFIG_GPIO_PCF857X) += pcf857x.o | |||
24 | obj-$(CONFIG_GPIO_PCH) += pch_gpio.o | 24 | obj-$(CONFIG_GPIO_PCH) += pch_gpio.o |
25 | obj-$(CONFIG_GPIO_PL061) += pl061.o | 25 | obj-$(CONFIG_GPIO_PL061) += pl061.o |
26 | obj-$(CONFIG_GPIO_STMPE) += stmpe-gpio.o | 26 | obj-$(CONFIG_GPIO_STMPE) += stmpe-gpio.o |
27 | obj-$(CONFIG_GPIO_TC35892) += tc35892-gpio.o | 27 | obj-$(CONFIG_GPIO_TC3589X) += tc3589x-gpio.o |
28 | obj-$(CONFIG_GPIO_TIMBERDALE) += timbgpio.o | 28 | obj-$(CONFIG_GPIO_TIMBERDALE) += timbgpio.o |
29 | obj-$(CONFIG_GPIO_TWL4030) += twl4030-gpio.o | 29 | obj-$(CONFIG_GPIO_TWL4030) += twl4030-gpio.o |
30 | obj-$(CONFIG_GPIO_UCB1400) += ucb1400_gpio.o | 30 | obj-$(CONFIG_GPIO_UCB1400) += ucb1400_gpio.o |
diff --git a/drivers/gpio/tc35892-gpio.c b/drivers/gpio/tc35892-gpio.c deleted file mode 100644 index 7e10c935a047..000000000000 --- a/drivers/gpio/tc35892-gpio.c +++ /dev/null | |||
@@ -1,389 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) ST-Ericsson SA 2010 | ||
3 | * | ||
4 | * License Terms: GNU General Public License, version 2 | ||
5 | * Author: Hanumath Prasad <hanumath.prasad@stericsson.com> for ST-Ericsson | ||
6 | * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson | ||
7 | */ | ||
8 | |||
9 | #include <linux/module.h> | ||
10 | #include <linux/init.h> | ||
11 | #include <linux/platform_device.h> | ||
12 | #include <linux/slab.h> | ||
13 | #include <linux/gpio.h> | ||
14 | #include <linux/irq.h> | ||
15 | #include <linux/interrupt.h> | ||
16 | #include <linux/mfd/tc35892.h> | ||
17 | |||
18 | /* | ||
19 | * These registers are modified under the irq bus lock and cached to avoid | ||
20 | * unnecessary writes in bus_sync_unlock. | ||
21 | */ | ||
22 | enum { REG_IBE, REG_IEV, REG_IS, REG_IE }; | ||
23 | |||
24 | #define CACHE_NR_REGS 4 | ||
25 | #define CACHE_NR_BANKS 3 | ||
26 | |||
27 | struct tc35892_gpio { | ||
28 | struct gpio_chip chip; | ||
29 | struct tc35892 *tc35892; | ||
30 | struct device *dev; | ||
31 | struct mutex irq_lock; | ||
32 | |||
33 | int irq_base; | ||
34 | |||
35 | /* Caches of interrupt control registers for bus_lock */ | ||
36 | u8 regs[CACHE_NR_REGS][CACHE_NR_BANKS]; | ||
37 | u8 oldregs[CACHE_NR_REGS][CACHE_NR_BANKS]; | ||
38 | }; | ||
39 | |||
40 | static inline struct tc35892_gpio *to_tc35892_gpio(struct gpio_chip *chip) | ||
41 | { | ||
42 | return container_of(chip, struct tc35892_gpio, chip); | ||
43 | } | ||
44 | |||
45 | static int tc35892_gpio_get(struct gpio_chip *chip, unsigned offset) | ||
46 | { | ||
47 | struct tc35892_gpio *tc35892_gpio = to_tc35892_gpio(chip); | ||
48 | struct tc35892 *tc35892 = tc35892_gpio->tc35892; | ||
49 | u8 reg = TC35892_GPIODATA0 + (offset / 8) * 2; | ||
50 | u8 mask = 1 << (offset % 8); | ||
51 | int ret; | ||
52 | |||
53 | ret = tc35892_reg_read(tc35892, reg); | ||
54 | if (ret < 0) | ||
55 | return ret; | ||
56 | |||
57 | return ret & mask; | ||
58 | } | ||
59 | |||
60 | static void tc35892_gpio_set(struct gpio_chip *chip, unsigned offset, int val) | ||
61 | { | ||
62 | struct tc35892_gpio *tc35892_gpio = to_tc35892_gpio(chip); | ||
63 | struct tc35892 *tc35892 = tc35892_gpio->tc35892; | ||
64 | u8 reg = TC35892_GPIODATA0 + (offset / 8) * 2; | ||
65 | unsigned pos = offset % 8; | ||
66 | u8 data[] = {!!val << pos, 1 << pos}; | ||
67 | |||
68 | tc35892_block_write(tc35892, reg, ARRAY_SIZE(data), data); | ||
69 | } | ||
70 | |||
71 | static int tc35892_gpio_direction_output(struct gpio_chip *chip, | ||
72 | unsigned offset, int val) | ||
73 | { | ||
74 | struct tc35892_gpio *tc35892_gpio = to_tc35892_gpio(chip); | ||
75 | struct tc35892 *tc35892 = tc35892_gpio->tc35892; | ||
76 | u8 reg = TC35892_GPIODIR0 + offset / 8; | ||
77 | unsigned pos = offset % 8; | ||
78 | |||
79 | tc35892_gpio_set(chip, offset, val); | ||
80 | |||
81 | return tc35892_set_bits(tc35892, reg, 1 << pos, 1 << pos); | ||
82 | } | ||
83 | |||
84 | static int tc35892_gpio_direction_input(struct gpio_chip *chip, | ||
85 | unsigned offset) | ||
86 | { | ||
87 | struct tc35892_gpio *tc35892_gpio = to_tc35892_gpio(chip); | ||
88 | struct tc35892 *tc35892 = tc35892_gpio->tc35892; | ||
89 | u8 reg = TC35892_GPIODIR0 + offset / 8; | ||
90 | unsigned pos = offset % 8; | ||
91 | |||
92 | return tc35892_set_bits(tc35892, reg, 1 << pos, 0); | ||
93 | } | ||
94 | |||
95 | static int tc35892_gpio_to_irq(struct gpio_chip *chip, unsigned offset) | ||
96 | { | ||
97 | struct tc35892_gpio *tc35892_gpio = to_tc35892_gpio(chip); | ||
98 | |||
99 | return tc35892_gpio->irq_base + offset; | ||
100 | } | ||
101 | |||
102 | static struct gpio_chip template_chip = { | ||
103 | .label = "tc35892", | ||
104 | .owner = THIS_MODULE, | ||
105 | .direction_input = tc35892_gpio_direction_input, | ||
106 | .get = tc35892_gpio_get, | ||
107 | .direction_output = tc35892_gpio_direction_output, | ||
108 | .set = tc35892_gpio_set, | ||
109 | .to_irq = tc35892_gpio_to_irq, | ||
110 | .can_sleep = 1, | ||
111 | }; | ||
112 | |||
113 | static int tc35892_gpio_irq_set_type(unsigned int irq, unsigned int type) | ||
114 | { | ||
115 | struct tc35892_gpio *tc35892_gpio = get_irq_chip_data(irq); | ||
116 | int offset = irq - tc35892_gpio->irq_base; | ||
117 | int regoffset = offset / 8; | ||
118 | int mask = 1 << (offset % 8); | ||
119 | |||
120 | if (type == IRQ_TYPE_EDGE_BOTH) { | ||
121 | tc35892_gpio->regs[REG_IBE][regoffset] |= mask; | ||
122 | return 0; | ||
123 | } | ||
124 | |||
125 | tc35892_gpio->regs[REG_IBE][regoffset] &= ~mask; | ||
126 | |||
127 | if (type == IRQ_TYPE_LEVEL_LOW || type == IRQ_TYPE_LEVEL_HIGH) | ||
128 | tc35892_gpio->regs[REG_IS][regoffset] |= mask; | ||
129 | else | ||
130 | tc35892_gpio->regs[REG_IS][regoffset] &= ~mask; | ||
131 | |||
132 | if (type == IRQ_TYPE_EDGE_RISING || type == IRQ_TYPE_LEVEL_HIGH) | ||
133 | tc35892_gpio->regs[REG_IEV][regoffset] |= mask; | ||
134 | else | ||
135 | tc35892_gpio->regs[REG_IEV][regoffset] &= ~mask; | ||
136 | |||
137 | return 0; | ||
138 | } | ||
139 | |||
140 | static void tc35892_gpio_irq_lock(unsigned int irq) | ||
141 | { | ||
142 | struct tc35892_gpio *tc35892_gpio = get_irq_chip_data(irq); | ||
143 | |||
144 | mutex_lock(&tc35892_gpio->irq_lock); | ||
145 | } | ||
146 | |||
147 | static void tc35892_gpio_irq_sync_unlock(unsigned int irq) | ||
148 | { | ||
149 | struct tc35892_gpio *tc35892_gpio = get_irq_chip_data(irq); | ||
150 | struct tc35892 *tc35892 = tc35892_gpio->tc35892; | ||
151 | static const u8 regmap[] = { | ||
152 | [REG_IBE] = TC35892_GPIOIBE0, | ||
153 | [REG_IEV] = TC35892_GPIOIEV0, | ||
154 | [REG_IS] = TC35892_GPIOIS0, | ||
155 | [REG_IE] = TC35892_GPIOIE0, | ||
156 | }; | ||
157 | int i, j; | ||
158 | |||
159 | for (i = 0; i < CACHE_NR_REGS; i++) { | ||
160 | for (j = 0; j < CACHE_NR_BANKS; j++) { | ||
161 | u8 old = tc35892_gpio->oldregs[i][j]; | ||
162 | u8 new = tc35892_gpio->regs[i][j]; | ||
163 | |||
164 | if (new == old) | ||
165 | continue; | ||
166 | |||
167 | tc35892_gpio->oldregs[i][j] = new; | ||
168 | tc35892_reg_write(tc35892, regmap[i] + j * 8, new); | ||
169 | } | ||
170 | } | ||
171 | |||
172 | mutex_unlock(&tc35892_gpio->irq_lock); | ||
173 | } | ||
174 | |||
175 | static void tc35892_gpio_irq_mask(unsigned int irq) | ||
176 | { | ||
177 | struct tc35892_gpio *tc35892_gpio = get_irq_chip_data(irq); | ||
178 | int offset = irq - tc35892_gpio->irq_base; | ||
179 | int regoffset = offset / 8; | ||
180 | int mask = 1 << (offset % 8); | ||
181 | |||
182 | tc35892_gpio->regs[REG_IE][regoffset] &= ~mask; | ||
183 | } | ||
184 | |||
185 | static void tc35892_gpio_irq_unmask(unsigned int irq) | ||
186 | { | ||
187 | struct tc35892_gpio *tc35892_gpio = get_irq_chip_data(irq); | ||
188 | int offset = irq - tc35892_gpio->irq_base; | ||
189 | int regoffset = offset / 8; | ||
190 | int mask = 1 << (offset % 8); | ||
191 | |||
192 | tc35892_gpio->regs[REG_IE][regoffset] |= mask; | ||
193 | } | ||
194 | |||
195 | static struct irq_chip tc35892_gpio_irq_chip = { | ||
196 | .name = "tc35892-gpio", | ||
197 | .bus_lock = tc35892_gpio_irq_lock, | ||
198 | .bus_sync_unlock = tc35892_gpio_irq_sync_unlock, | ||
199 | .mask = tc35892_gpio_irq_mask, | ||
200 | .unmask = tc35892_gpio_irq_unmask, | ||
201 | .set_type = tc35892_gpio_irq_set_type, | ||
202 | }; | ||
203 | |||
204 | static irqreturn_t tc35892_gpio_irq(int irq, void *dev) | ||
205 | { | ||
206 | struct tc35892_gpio *tc35892_gpio = dev; | ||
207 | struct tc35892 *tc35892 = tc35892_gpio->tc35892; | ||
208 | u8 status[CACHE_NR_BANKS]; | ||
209 | int ret; | ||
210 | int i; | ||
211 | |||
212 | ret = tc35892_block_read(tc35892, TC35892_GPIOMIS0, | ||
213 | ARRAY_SIZE(status), status); | ||
214 | if (ret < 0) | ||
215 | return IRQ_NONE; | ||
216 | |||
217 | for (i = 0; i < ARRAY_SIZE(status); i++) { | ||
218 | unsigned int stat = status[i]; | ||
219 | if (!stat) | ||
220 | continue; | ||
221 | |||
222 | while (stat) { | ||
223 | int bit = __ffs(stat); | ||
224 | int line = i * 8 + bit; | ||
225 | |||
226 | handle_nested_irq(tc35892_gpio->irq_base + line); | ||
227 | stat &= ~(1 << bit); | ||
228 | } | ||
229 | |||
230 | tc35892_reg_write(tc35892, TC35892_GPIOIC0 + i, status[i]); | ||
231 | } | ||
232 | |||
233 | return IRQ_HANDLED; | ||
234 | } | ||
235 | |||
236 | static int tc35892_gpio_irq_init(struct tc35892_gpio *tc35892_gpio) | ||
237 | { | ||
238 | int base = tc35892_gpio->irq_base; | ||
239 | int irq; | ||
240 | |||
241 | for (irq = base; irq < base + tc35892_gpio->chip.ngpio; irq++) { | ||
242 | set_irq_chip_data(irq, tc35892_gpio); | ||
243 | set_irq_chip_and_handler(irq, &tc35892_gpio_irq_chip, | ||
244 | handle_simple_irq); | ||
245 | set_irq_nested_thread(irq, 1); | ||
246 | #ifdef CONFIG_ARM | ||
247 | set_irq_flags(irq, IRQF_VALID); | ||
248 | #else | ||
249 | set_irq_noprobe(irq); | ||
250 | #endif | ||
251 | } | ||
252 | |||
253 | return 0; | ||
254 | } | ||
255 | |||
256 | static void tc35892_gpio_irq_remove(struct tc35892_gpio *tc35892_gpio) | ||
257 | { | ||
258 | int base = tc35892_gpio->irq_base; | ||
259 | int irq; | ||
260 | |||
261 | for (irq = base; irq < base + tc35892_gpio->chip.ngpio; irq++) { | ||
262 | #ifdef CONFIG_ARM | ||
263 | set_irq_flags(irq, 0); | ||
264 | #endif | ||
265 | set_irq_chip_and_handler(irq, NULL, NULL); | ||
266 | set_irq_chip_data(irq, NULL); | ||
267 | } | ||
268 | } | ||
269 | |||
270 | static int __devinit tc35892_gpio_probe(struct platform_device *pdev) | ||
271 | { | ||
272 | struct tc35892 *tc35892 = dev_get_drvdata(pdev->dev.parent); | ||
273 | struct tc35892_gpio_platform_data *pdata; | ||
274 | struct tc35892_gpio *tc35892_gpio; | ||
275 | int ret; | ||
276 | int irq; | ||
277 | |||
278 | pdata = tc35892->pdata->gpio; | ||
279 | if (!pdata) | ||
280 | return -ENODEV; | ||
281 | |||
282 | irq = platform_get_irq(pdev, 0); | ||
283 | if (irq < 0) | ||
284 | return irq; | ||
285 | |||
286 | tc35892_gpio = kzalloc(sizeof(struct tc35892_gpio), GFP_KERNEL); | ||
287 | if (!tc35892_gpio) | ||
288 | return -ENOMEM; | ||
289 | |||
290 | mutex_init(&tc35892_gpio->irq_lock); | ||
291 | |||
292 | tc35892_gpio->dev = &pdev->dev; | ||
293 | tc35892_gpio->tc35892 = tc35892; | ||
294 | |||
295 | tc35892_gpio->chip = template_chip; | ||
296 | tc35892_gpio->chip.ngpio = tc35892->num_gpio; | ||
297 | tc35892_gpio->chip.dev = &pdev->dev; | ||
298 | tc35892_gpio->chip.base = pdata->gpio_base; | ||
299 | |||
300 | tc35892_gpio->irq_base = tc35892->irq_base + TC35892_INT_GPIO(0); | ||
301 | |||
302 | /* Bring the GPIO module out of reset */ | ||
303 | ret = tc35892_set_bits(tc35892, TC35892_RSTCTRL, | ||
304 | TC35892_RSTCTRL_GPIRST, 0); | ||
305 | if (ret < 0) | ||
306 | goto out_free; | ||
307 | |||
308 | ret = tc35892_gpio_irq_init(tc35892_gpio); | ||
309 | if (ret) | ||
310 | goto out_free; | ||
311 | |||
312 | ret = request_threaded_irq(irq, NULL, tc35892_gpio_irq, IRQF_ONESHOT, | ||
313 | "tc35892-gpio", tc35892_gpio); | ||
314 | if (ret) { | ||
315 | dev_err(&pdev->dev, "unable to get irq: %d\n", ret); | ||
316 | goto out_removeirq; | ||
317 | } | ||
318 | |||
319 | ret = gpiochip_add(&tc35892_gpio->chip); | ||
320 | if (ret) { | ||
321 | dev_err(&pdev->dev, "unable to add gpiochip: %d\n", ret); | ||
322 | goto out_freeirq; | ||
323 | } | ||
324 | |||
325 | if (pdata->setup) | ||
326 | pdata->setup(tc35892, tc35892_gpio->chip.base); | ||
327 | |||
328 | platform_set_drvdata(pdev, tc35892_gpio); | ||
329 | |||
330 | return 0; | ||
331 | |||
332 | out_freeirq: | ||
333 | free_irq(irq, tc35892_gpio); | ||
334 | out_removeirq: | ||
335 | tc35892_gpio_irq_remove(tc35892_gpio); | ||
336 | out_free: | ||
337 | kfree(tc35892_gpio); | ||
338 | return ret; | ||
339 | } | ||
340 | |||
341 | static int __devexit tc35892_gpio_remove(struct platform_device *pdev) | ||
342 | { | ||
343 | struct tc35892_gpio *tc35892_gpio = platform_get_drvdata(pdev); | ||
344 | struct tc35892 *tc35892 = tc35892_gpio->tc35892; | ||
345 | struct tc35892_gpio_platform_data *pdata = tc35892->pdata->gpio; | ||
346 | int irq = platform_get_irq(pdev, 0); | ||
347 | int ret; | ||
348 | |||
349 | if (pdata->remove) | ||
350 | pdata->remove(tc35892, tc35892_gpio->chip.base); | ||
351 | |||
352 | ret = gpiochip_remove(&tc35892_gpio->chip); | ||
353 | if (ret < 0) { | ||
354 | dev_err(tc35892_gpio->dev, | ||
355 | "unable to remove gpiochip: %d\n", ret); | ||
356 | return ret; | ||
357 | } | ||
358 | |||
359 | free_irq(irq, tc35892_gpio); | ||
360 | tc35892_gpio_irq_remove(tc35892_gpio); | ||
361 | |||
362 | platform_set_drvdata(pdev, NULL); | ||
363 | kfree(tc35892_gpio); | ||
364 | |||
365 | return 0; | ||
366 | } | ||
367 | |||
368 | static struct platform_driver tc35892_gpio_driver = { | ||
369 | .driver.name = "tc35892-gpio", | ||
370 | .driver.owner = THIS_MODULE, | ||
371 | .probe = tc35892_gpio_probe, | ||
372 | .remove = __devexit_p(tc35892_gpio_remove), | ||
373 | }; | ||
374 | |||
375 | static int __init tc35892_gpio_init(void) | ||
376 | { | ||
377 | return platform_driver_register(&tc35892_gpio_driver); | ||
378 | } | ||
379 | subsys_initcall(tc35892_gpio_init); | ||
380 | |||
381 | static void __exit tc35892_gpio_exit(void) | ||
382 | { | ||
383 | platform_driver_unregister(&tc35892_gpio_driver); | ||
384 | } | ||
385 | module_exit(tc35892_gpio_exit); | ||
386 | |||
387 | MODULE_LICENSE("GPL v2"); | ||
388 | MODULE_DESCRIPTION("TC35892 GPIO driver"); | ||
389 | MODULE_AUTHOR("Hanumath Prasad, Rabin Vincent"); | ||
diff --git a/drivers/gpio/tc3589x-gpio.c b/drivers/gpio/tc3589x-gpio.c new file mode 100644 index 000000000000..180d584454fb --- /dev/null +++ b/drivers/gpio/tc3589x-gpio.c | |||
@@ -0,0 +1,389 @@ | |||
1 | /* | ||
2 | * Copyright (C) ST-Ericsson SA 2010 | ||
3 | * | ||
4 | * License Terms: GNU General Public License, version 2 | ||
5 | * Author: Hanumath Prasad <hanumath.prasad@stericsson.com> for ST-Ericsson | ||
6 | * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson | ||
7 | */ | ||
8 | |||
9 | #include <linux/module.h> | ||
10 | #include <linux/init.h> | ||
11 | #include <linux/platform_device.h> | ||
12 | #include <linux/slab.h> | ||
13 | #include <linux/gpio.h> | ||
14 | #include <linux/irq.h> | ||
15 | #include <linux/interrupt.h> | ||
16 | #include <linux/mfd/tc3589x.h> | ||
17 | |||
18 | /* | ||
19 | * These registers are modified under the irq bus lock and cached to avoid | ||
20 | * unnecessary writes in bus_sync_unlock. | ||
21 | */ | ||
22 | enum { REG_IBE, REG_IEV, REG_IS, REG_IE }; | ||
23 | |||
24 | #define CACHE_NR_REGS 4 | ||
25 | #define CACHE_NR_BANKS 3 | ||
26 | |||
27 | struct tc3589x_gpio { | ||
28 | struct gpio_chip chip; | ||
29 | struct tc3589x *tc3589x; | ||
30 | struct device *dev; | ||
31 | struct mutex irq_lock; | ||
32 | |||
33 | int irq_base; | ||
34 | |||
35 | /* Caches of interrupt control registers for bus_lock */ | ||
36 | u8 regs[CACHE_NR_REGS][CACHE_NR_BANKS]; | ||
37 | u8 oldregs[CACHE_NR_REGS][CACHE_NR_BANKS]; | ||
38 | }; | ||
39 | |||
40 | static inline struct tc3589x_gpio *to_tc3589x_gpio(struct gpio_chip *chip) | ||
41 | { | ||
42 | return container_of(chip, struct tc3589x_gpio, chip); | ||
43 | } | ||
44 | |||
45 | static int tc3589x_gpio_get(struct gpio_chip *chip, unsigned offset) | ||
46 | { | ||
47 | struct tc3589x_gpio *tc3589x_gpio = to_tc3589x_gpio(chip); | ||
48 | struct tc3589x *tc3589x = tc3589x_gpio->tc3589x; | ||
49 | u8 reg = TC3589x_GPIODATA0 + (offset / 8) * 2; | ||
50 | u8 mask = 1 << (offset % 8); | ||
51 | int ret; | ||
52 | |||
53 | ret = tc3589x_reg_read(tc3589x, reg); | ||
54 | if (ret < 0) | ||
55 | return ret; | ||
56 | |||
57 | return ret & mask; | ||
58 | } | ||
59 | |||
60 | static void tc3589x_gpio_set(struct gpio_chip *chip, unsigned offset, int val) | ||
61 | { | ||
62 | struct tc3589x_gpio *tc3589x_gpio = to_tc3589x_gpio(chip); | ||
63 | struct tc3589x *tc3589x = tc3589x_gpio->tc3589x; | ||
64 | u8 reg = TC3589x_GPIODATA0 + (offset / 8) * 2; | ||
65 | unsigned pos = offset % 8; | ||
66 | u8 data[] = {!!val << pos, 1 << pos}; | ||
67 | |||
68 | tc3589x_block_write(tc3589x, reg, ARRAY_SIZE(data), data); | ||
69 | } | ||
70 | |||
71 | static int tc3589x_gpio_direction_output(struct gpio_chip *chip, | ||
72 | unsigned offset, int val) | ||
73 | { | ||
74 | struct tc3589x_gpio *tc3589x_gpio = to_tc3589x_gpio(chip); | ||
75 | struct tc3589x *tc3589x = tc3589x_gpio->tc3589x; | ||
76 | u8 reg = TC3589x_GPIODIR0 + offset / 8; | ||
77 | unsigned pos = offset % 8; | ||
78 | |||
79 | tc3589x_gpio_set(chip, offset, val); | ||
80 | |||
81 | return tc3589x_set_bits(tc3589x, reg, 1 << pos, 1 << pos); | ||
82 | } | ||
83 | |||
84 | static int tc3589x_gpio_direction_input(struct gpio_chip *chip, | ||
85 | unsigned offset) | ||
86 | { | ||
87 | struct tc3589x_gpio *tc3589x_gpio = to_tc3589x_gpio(chip); | ||
88 | struct tc3589x *tc3589x = tc3589x_gpio->tc3589x; | ||
89 | u8 reg = TC3589x_GPIODIR0 + offset / 8; | ||
90 | unsigned pos = offset % 8; | ||
91 | |||
92 | return tc3589x_set_bits(tc3589x, reg, 1 << pos, 0); | ||
93 | } | ||
94 | |||
95 | static int tc3589x_gpio_to_irq(struct gpio_chip *chip, unsigned offset) | ||
96 | { | ||
97 | struct tc3589x_gpio *tc3589x_gpio = to_tc3589x_gpio(chip); | ||
98 | |||
99 | return tc3589x_gpio->irq_base + offset; | ||
100 | } | ||
101 | |||
102 | static struct gpio_chip template_chip = { | ||
103 | .label = "tc3589x", | ||
104 | .owner = THIS_MODULE, | ||
105 | .direction_input = tc3589x_gpio_direction_input, | ||
106 | .get = tc3589x_gpio_get, | ||
107 | .direction_output = tc3589x_gpio_direction_output, | ||
108 | .set = tc3589x_gpio_set, | ||
109 | .to_irq = tc3589x_gpio_to_irq, | ||
110 | .can_sleep = 1, | ||
111 | }; | ||
112 | |||
113 | static int tc3589x_gpio_irq_set_type(unsigned int irq, unsigned int type) | ||
114 | { | ||
115 | struct tc3589x_gpio *tc3589x_gpio = get_irq_chip_data(irq); | ||
116 | int offset = irq - tc3589x_gpio->irq_base; | ||
117 | int regoffset = offset / 8; | ||
118 | int mask = 1 << (offset % 8); | ||
119 | |||
120 | if (type == IRQ_TYPE_EDGE_BOTH) { | ||
121 | tc3589x_gpio->regs[REG_IBE][regoffset] |= mask; | ||
122 | return 0; | ||
123 | } | ||
124 | |||
125 | tc3589x_gpio->regs[REG_IBE][regoffset] &= ~mask; | ||
126 | |||
127 | if (type == IRQ_TYPE_LEVEL_LOW || type == IRQ_TYPE_LEVEL_HIGH) | ||
128 | tc3589x_gpio->regs[REG_IS][regoffset] |= mask; | ||
129 | else | ||
130 | tc3589x_gpio->regs[REG_IS][regoffset] &= ~mask; | ||
131 | |||
132 | if (type == IRQ_TYPE_EDGE_RISING || type == IRQ_TYPE_LEVEL_HIGH) | ||
133 | tc3589x_gpio->regs[REG_IEV][regoffset] |= mask; | ||
134 | else | ||
135 | tc3589x_gpio->regs[REG_IEV][regoffset] &= ~mask; | ||
136 | |||
137 | return 0; | ||
138 | } | ||
139 | |||
140 | static void tc3589x_gpio_irq_lock(unsigned int irq) | ||
141 | { | ||
142 | struct tc3589x_gpio *tc3589x_gpio = get_irq_chip_data(irq); | ||
143 | |||
144 | mutex_lock(&tc3589x_gpio->irq_lock); | ||
145 | } | ||
146 | |||
147 | static void tc3589x_gpio_irq_sync_unlock(unsigned int irq) | ||
148 | { | ||
149 | struct tc3589x_gpio *tc3589x_gpio = get_irq_chip_data(irq); | ||
150 | struct tc3589x *tc3589x = tc3589x_gpio->tc3589x; | ||
151 | static const u8 regmap[] = { | ||
152 | [REG_IBE] = TC3589x_GPIOIBE0, | ||
153 | [REG_IEV] = TC3589x_GPIOIEV0, | ||
154 | [REG_IS] = TC3589x_GPIOIS0, | ||
155 | [REG_IE] = TC3589x_GPIOIE0, | ||
156 | }; | ||
157 | int i, j; | ||
158 | |||
159 | for (i = 0; i < CACHE_NR_REGS; i++) { | ||
160 | for (j = 0; j < CACHE_NR_BANKS; j++) { | ||
161 | u8 old = tc3589x_gpio->oldregs[i][j]; | ||
162 | u8 new = tc3589x_gpio->regs[i][j]; | ||
163 | |||
164 | if (new == old) | ||
165 | continue; | ||
166 | |||
167 | tc3589x_gpio->oldregs[i][j] = new; | ||
168 | tc3589x_reg_write(tc3589x, regmap[i] + j * 8, new); | ||
169 | } | ||
170 | } | ||
171 | |||
172 | mutex_unlock(&tc3589x_gpio->irq_lock); | ||
173 | } | ||
174 | |||
175 | static void tc3589x_gpio_irq_mask(unsigned int irq) | ||
176 | { | ||
177 | struct tc3589x_gpio *tc3589x_gpio = get_irq_chip_data(irq); | ||
178 | int offset = irq - tc3589x_gpio->irq_base; | ||
179 | int regoffset = offset / 8; | ||
180 | int mask = 1 << (offset % 8); | ||
181 | |||
182 | tc3589x_gpio->regs[REG_IE][regoffset] &= ~mask; | ||
183 | } | ||
184 | |||
185 | static void tc3589x_gpio_irq_unmask(unsigned int irq) | ||
186 | { | ||
187 | struct tc3589x_gpio *tc3589x_gpio = get_irq_chip_data(irq); | ||
188 | int offset = irq - tc3589x_gpio->irq_base; | ||
189 | int regoffset = offset / 8; | ||
190 | int mask = 1 << (offset % 8); | ||
191 | |||
192 | tc3589x_gpio->regs[REG_IE][regoffset] |= mask; | ||
193 | } | ||
194 | |||
195 | static struct irq_chip tc3589x_gpio_irq_chip = { | ||
196 | .name = "tc3589x-gpio", | ||
197 | .bus_lock = tc3589x_gpio_irq_lock, | ||
198 | .bus_sync_unlock = tc3589x_gpio_irq_sync_unlock, | ||
199 | .mask = tc3589x_gpio_irq_mask, | ||
200 | .unmask = tc3589x_gpio_irq_unmask, | ||
201 | .set_type = tc3589x_gpio_irq_set_type, | ||
202 | }; | ||
203 | |||
204 | static irqreturn_t tc3589x_gpio_irq(int irq, void *dev) | ||
205 | { | ||
206 | struct tc3589x_gpio *tc3589x_gpio = dev; | ||
207 | struct tc3589x *tc3589x = tc3589x_gpio->tc3589x; | ||
208 | u8 status[CACHE_NR_BANKS]; | ||
209 | int ret; | ||
210 | int i; | ||
211 | |||
212 | ret = tc3589x_block_read(tc3589x, TC3589x_GPIOMIS0, | ||
213 | ARRAY_SIZE(status), status); | ||
214 | if (ret < 0) | ||
215 | return IRQ_NONE; | ||
216 | |||
217 | for (i = 0; i < ARRAY_SIZE(status); i++) { | ||
218 | unsigned int stat = status[i]; | ||
219 | if (!stat) | ||
220 | continue; | ||
221 | |||
222 | while (stat) { | ||
223 | int bit = __ffs(stat); | ||
224 | int line = i * 8 + bit; | ||
225 | |||
226 | handle_nested_irq(tc3589x_gpio->irq_base + line); | ||
227 | stat &= ~(1 << bit); | ||
228 | } | ||
229 | |||
230 | tc3589x_reg_write(tc3589x, TC3589x_GPIOIC0 + i, status[i]); | ||
231 | } | ||
232 | |||
233 | return IRQ_HANDLED; | ||
234 | } | ||
235 | |||
236 | static int tc3589x_gpio_irq_init(struct tc3589x_gpio *tc3589x_gpio) | ||
237 | { | ||
238 | int base = tc3589x_gpio->irq_base; | ||
239 | int irq; | ||
240 | |||
241 | for (irq = base; irq < base + tc3589x_gpio->chip.ngpio; irq++) { | ||
242 | set_irq_chip_data(irq, tc3589x_gpio); | ||
243 | set_irq_chip_and_handler(irq, &tc3589x_gpio_irq_chip, | ||
244 | handle_simple_irq); | ||
245 | set_irq_nested_thread(irq, 1); | ||
246 | #ifdef CONFIG_ARM | ||
247 | set_irq_flags(irq, IRQF_VALID); | ||
248 | #else | ||
249 | set_irq_noprobe(irq); | ||
250 | #endif | ||
251 | } | ||
252 | |||
253 | return 0; | ||
254 | } | ||
255 | |||
256 | static void tc3589x_gpio_irq_remove(struct tc3589x_gpio *tc3589x_gpio) | ||
257 | { | ||
258 | int base = tc3589x_gpio->irq_base; | ||
259 | int irq; | ||
260 | |||
261 | for (irq = base; irq < base + tc3589x_gpio->chip.ngpio; irq++) { | ||
262 | #ifdef CONFIG_ARM | ||
263 | set_irq_flags(irq, 0); | ||
264 | #endif | ||
265 | set_irq_chip_and_handler(irq, NULL, NULL); | ||
266 | set_irq_chip_data(irq, NULL); | ||
267 | } | ||
268 | } | ||
269 | |||
270 | static int __devinit tc3589x_gpio_probe(struct platform_device *pdev) | ||
271 | { | ||
272 | struct tc3589x *tc3589x = dev_get_drvdata(pdev->dev.parent); | ||
273 | struct tc3589x_gpio_platform_data *pdata; | ||
274 | struct tc3589x_gpio *tc3589x_gpio; | ||
275 | int ret; | ||
276 | int irq; | ||
277 | |||
278 | pdata = tc3589x->pdata->gpio; | ||
279 | if (!pdata) | ||
280 | return -ENODEV; | ||
281 | |||
282 | irq = platform_get_irq(pdev, 0); | ||
283 | if (irq < 0) | ||
284 | return irq; | ||
285 | |||
286 | tc3589x_gpio = kzalloc(sizeof(struct tc3589x_gpio), GFP_KERNEL); | ||
287 | if (!tc3589x_gpio) | ||
288 | return -ENOMEM; | ||
289 | |||
290 | mutex_init(&tc3589x_gpio->irq_lock); | ||
291 | |||
292 | tc3589x_gpio->dev = &pdev->dev; | ||
293 | tc3589x_gpio->tc3589x = tc3589x; | ||
294 | |||
295 | tc3589x_gpio->chip = template_chip; | ||
296 | tc3589x_gpio->chip.ngpio = tc3589x->num_gpio; | ||
297 | tc3589x_gpio->chip.dev = &pdev->dev; | ||
298 | tc3589x_gpio->chip.base = pdata->gpio_base; | ||
299 | |||
300 | tc3589x_gpio->irq_base = tc3589x->irq_base + TC3589x_INT_GPIO(0); | ||
301 | |||
302 | /* Bring the GPIO module out of reset */ | ||
303 | ret = tc3589x_set_bits(tc3589x, TC3589x_RSTCTRL, | ||
304 | TC3589x_RSTCTRL_GPIRST, 0); | ||
305 | if (ret < 0) | ||
306 | goto out_free; | ||
307 | |||
308 | ret = tc3589x_gpio_irq_init(tc3589x_gpio); | ||
309 | if (ret) | ||
310 | goto out_free; | ||
311 | |||
312 | ret = request_threaded_irq(irq, NULL, tc3589x_gpio_irq, IRQF_ONESHOT, | ||
313 | "tc3589x-gpio", tc3589x_gpio); | ||
314 | if (ret) { | ||
315 | dev_err(&pdev->dev, "unable to get irq: %d\n", ret); | ||
316 | goto out_removeirq; | ||
317 | } | ||
318 | |||
319 | ret = gpiochip_add(&tc3589x_gpio->chip); | ||
320 | if (ret) { | ||
321 | dev_err(&pdev->dev, "unable to add gpiochip: %d\n", ret); | ||
322 | goto out_freeirq; | ||
323 | } | ||
324 | |||
325 | if (pdata->setup) | ||
326 | pdata->setup(tc3589x, tc3589x_gpio->chip.base); | ||
327 | |||
328 | platform_set_drvdata(pdev, tc3589x_gpio); | ||
329 | |||
330 | return 0; | ||
331 | |||
332 | out_freeirq: | ||
333 | free_irq(irq, tc3589x_gpio); | ||
334 | out_removeirq: | ||
335 | tc3589x_gpio_irq_remove(tc3589x_gpio); | ||
336 | out_free: | ||
337 | kfree(tc3589x_gpio); | ||
338 | return ret; | ||
339 | } | ||
340 | |||
341 | static int __devexit tc3589x_gpio_remove(struct platform_device *pdev) | ||
342 | { | ||
343 | struct tc3589x_gpio *tc3589x_gpio = platform_get_drvdata(pdev); | ||
344 | struct tc3589x *tc3589x = tc3589x_gpio->tc3589x; | ||
345 | struct tc3589x_gpio_platform_data *pdata = tc3589x->pdata->gpio; | ||
346 | int irq = platform_get_irq(pdev, 0); | ||
347 | int ret; | ||
348 | |||
349 | if (pdata->remove) | ||
350 | pdata->remove(tc3589x, tc3589x_gpio->chip.base); | ||
351 | |||
352 | ret = gpiochip_remove(&tc3589x_gpio->chip); | ||
353 | if (ret < 0) { | ||
354 | dev_err(tc3589x_gpio->dev, | ||
355 | "unable to remove gpiochip: %d\n", ret); | ||
356 | return ret; | ||
357 | } | ||
358 | |||
359 | free_irq(irq, tc3589x_gpio); | ||
360 | tc3589x_gpio_irq_remove(tc3589x_gpio); | ||
361 | |||
362 | platform_set_drvdata(pdev, NULL); | ||
363 | kfree(tc3589x_gpio); | ||
364 | |||
365 | return 0; | ||
366 | } | ||
367 | |||
368 | static struct platform_driver tc3589x_gpio_driver = { | ||
369 | .driver.name = "tc3589x-gpio", | ||
370 | .driver.owner = THIS_MODULE, | ||
371 | .probe = tc3589x_gpio_probe, | ||
372 | .remove = __devexit_p(tc3589x_gpio_remove), | ||
373 | }; | ||
374 | |||
375 | static int __init tc3589x_gpio_init(void) | ||
376 | { | ||
377 | return platform_driver_register(&tc3589x_gpio_driver); | ||
378 | } | ||
379 | subsys_initcall(tc3589x_gpio_init); | ||
380 | |||
381 | static void __exit tc3589x_gpio_exit(void) | ||
382 | { | ||
383 | platform_driver_unregister(&tc3589x_gpio_driver); | ||
384 | } | ||
385 | module_exit(tc3589x_gpio_exit); | ||
386 | |||
387 | MODULE_LICENSE("GPL v2"); | ||
388 | MODULE_DESCRIPTION("TC3589x GPIO driver"); | ||
389 | MODULE_AUTHOR("Hanumath Prasad, Rabin Vincent"); | ||
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 6985cb1da72c..2baa6708e44c 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c | |||
@@ -156,12 +156,12 @@ static struct drm_conn_prop_enum_list drm_connector_enum_list[] = | |||
156 | { DRM_MODE_CONNECTOR_SVIDEO, "SVIDEO", 0 }, | 156 | { DRM_MODE_CONNECTOR_SVIDEO, "SVIDEO", 0 }, |
157 | { DRM_MODE_CONNECTOR_LVDS, "LVDS", 0 }, | 157 | { DRM_MODE_CONNECTOR_LVDS, "LVDS", 0 }, |
158 | { DRM_MODE_CONNECTOR_Component, "Component", 0 }, | 158 | { DRM_MODE_CONNECTOR_Component, "Component", 0 }, |
159 | { DRM_MODE_CONNECTOR_9PinDIN, "9-pin DIN", 0 }, | 159 | { DRM_MODE_CONNECTOR_9PinDIN, "DIN", 0 }, |
160 | { DRM_MODE_CONNECTOR_DisplayPort, "DisplayPort", 0 }, | 160 | { DRM_MODE_CONNECTOR_DisplayPort, "DP", 0 }, |
161 | { DRM_MODE_CONNECTOR_HDMIA, "HDMI Type A", 0 }, | 161 | { DRM_MODE_CONNECTOR_HDMIA, "HDMI-A", 0 }, |
162 | { DRM_MODE_CONNECTOR_HDMIB, "HDMI Type B", 0 }, | 162 | { DRM_MODE_CONNECTOR_HDMIB, "HDMI-B", 0 }, |
163 | { DRM_MODE_CONNECTOR_TV, "TV", 0 }, | 163 | { DRM_MODE_CONNECTOR_TV, "TV", 0 }, |
164 | { DRM_MODE_CONNECTOR_eDP, "Embedded DisplayPort", 0 }, | 164 | { DRM_MODE_CONNECTOR_eDP, "eDP", 0 }, |
165 | }; | 165 | }; |
166 | 166 | ||
167 | static struct drm_prop_enum_list drm_encoder_enum_list[] = | 167 | static struct drm_prop_enum_list drm_encoder_enum_list[] = |
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index 7ca59359fee2..bede10a03407 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c | |||
@@ -241,7 +241,7 @@ void drm_helper_disable_unused_functions(struct drm_device *dev) | |||
241 | } | 241 | } |
242 | 242 | ||
243 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | 243 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
244 | if (!drm_helper_encoder_in_use(encoder)) { | 244 | if (encoder->crtc && !drm_helper_encoder_in_use(encoder)) { |
245 | drm_encoder_disable(encoder); | 245 | drm_encoder_disable(encoder); |
246 | /* disconnector encoder from any connector */ | 246 | /* disconnector encoder from any connector */ |
247 | encoder->crtc = NULL; | 247 | encoder->crtc = NULL; |
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 9d3a5030b6e1..16d5155edad1 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c | |||
@@ -585,10 +585,13 @@ static int drm_queue_vblank_event(struct drm_device *dev, int pipe, | |||
585 | struct timeval now; | 585 | struct timeval now; |
586 | unsigned long flags; | 586 | unsigned long flags; |
587 | unsigned int seq; | 587 | unsigned int seq; |
588 | int ret; | ||
588 | 589 | ||
589 | e = kzalloc(sizeof *e, GFP_KERNEL); | 590 | e = kzalloc(sizeof *e, GFP_KERNEL); |
590 | if (e == NULL) | 591 | if (e == NULL) { |
591 | return -ENOMEM; | 592 | ret = -ENOMEM; |
593 | goto err_put; | ||
594 | } | ||
592 | 595 | ||
593 | e->pipe = pipe; | 596 | e->pipe = pipe; |
594 | e->base.pid = current->pid; | 597 | e->base.pid = current->pid; |
@@ -603,9 +606,8 @@ static int drm_queue_vblank_event(struct drm_device *dev, int pipe, | |||
603 | spin_lock_irqsave(&dev->event_lock, flags); | 606 | spin_lock_irqsave(&dev->event_lock, flags); |
604 | 607 | ||
605 | if (file_priv->event_space < sizeof e->event) { | 608 | if (file_priv->event_space < sizeof e->event) { |
606 | spin_unlock_irqrestore(&dev->event_lock, flags); | 609 | ret = -EBUSY; |
607 | kfree(e); | 610 | goto err_unlock; |
608 | return -ENOMEM; | ||
609 | } | 611 | } |
610 | 612 | ||
611 | file_priv->event_space -= sizeof e->event; | 613 | file_priv->event_space -= sizeof e->event; |
@@ -626,7 +628,7 @@ static int drm_queue_vblank_event(struct drm_device *dev, int pipe, | |||
626 | if ((seq - vblwait->request.sequence) <= (1 << 23)) { | 628 | if ((seq - vblwait->request.sequence) <= (1 << 23)) { |
627 | e->event.tv_sec = now.tv_sec; | 629 | e->event.tv_sec = now.tv_sec; |
628 | e->event.tv_usec = now.tv_usec; | 630 | e->event.tv_usec = now.tv_usec; |
629 | drm_vblank_put(dev, e->pipe); | 631 | drm_vblank_put(dev, pipe); |
630 | list_add_tail(&e->base.link, &e->base.file_priv->event_list); | 632 | list_add_tail(&e->base.link, &e->base.file_priv->event_list); |
631 | wake_up_interruptible(&e->base.file_priv->event_wait); | 633 | wake_up_interruptible(&e->base.file_priv->event_wait); |
632 | trace_drm_vblank_event_delivered(current->pid, pipe, | 634 | trace_drm_vblank_event_delivered(current->pid, pipe, |
@@ -638,6 +640,13 @@ static int drm_queue_vblank_event(struct drm_device *dev, int pipe, | |||
638 | spin_unlock_irqrestore(&dev->event_lock, flags); | 640 | spin_unlock_irqrestore(&dev->event_lock, flags); |
639 | 641 | ||
640 | return 0; | 642 | return 0; |
643 | |||
644 | err_unlock: | ||
645 | spin_unlock_irqrestore(&dev->event_lock, flags); | ||
646 | kfree(e); | ||
647 | err_put: | ||
648 | drm_vblank_put(dev, pipe); | ||
649 | return ret; | ||
641 | } | 650 | } |
642 | 651 | ||
643 | /** | 652 | /** |
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 7a26f4dd21ae..e6800819bca8 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
@@ -767,6 +767,9 @@ static int i915_getparam(struct drm_device *dev, void *data, | |||
767 | case I915_PARAM_HAS_BLT: | 767 | case I915_PARAM_HAS_BLT: |
768 | value = HAS_BLT(dev); | 768 | value = HAS_BLT(dev); |
769 | break; | 769 | break; |
770 | case I915_PARAM_HAS_COHERENT_RINGS: | ||
771 | value = 1; | ||
772 | break; | ||
770 | default: | 773 | default: |
771 | DRM_DEBUG_DRIVER("Unknown parameter %d\n", | 774 | DRM_DEBUG_DRIVER("Unknown parameter %d\n", |
772 | param->param); | 775 | param->param); |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 5e54821af996..275ec6ed43ae 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -4374,10 +4374,20 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data, | |||
4374 | * use this buffer rather sooner than later, so issuing the required | 4374 | * use this buffer rather sooner than later, so issuing the required |
4375 | * flush earlier is beneficial. | 4375 | * flush earlier is beneficial. |
4376 | */ | 4376 | */ |
4377 | if (obj->write_domain & I915_GEM_GPU_DOMAINS) | 4377 | if (obj->write_domain & I915_GEM_GPU_DOMAINS) { |
4378 | i915_gem_flush_ring(dev, file_priv, | 4378 | i915_gem_flush_ring(dev, file_priv, |
4379 | obj_priv->ring, | 4379 | obj_priv->ring, |
4380 | 0, obj->write_domain); | 4380 | 0, obj->write_domain); |
4381 | } else if (obj_priv->ring->outstanding_lazy_request) { | ||
4382 | /* This ring is not being cleared by active usage, | ||
4383 | * so emit a request to do so. | ||
4384 | */ | ||
4385 | u32 seqno = i915_add_request(dev, | ||
4386 | NULL, NULL, | ||
4387 | obj_priv->ring); | ||
4388 | if (seqno == 0) | ||
4389 | ret = -ENOMEM; | ||
4390 | } | ||
4381 | 4391 | ||
4382 | /* Update the active list for the hardware's current position. | 4392 | /* Update the active list for the hardware's current position. |
4383 | * Otherwise this only updates on a delayed timer or when irqs | 4393 | * Otherwise this only updates on a delayed timer or when irqs |
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 25ed911a3112..878fc766a12c 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
@@ -3033,6 +3033,7 @@ | |||
3033 | #define TRANS_DP_10BPC (1<<9) | 3033 | #define TRANS_DP_10BPC (1<<9) |
3034 | #define TRANS_DP_6BPC (2<<9) | 3034 | #define TRANS_DP_6BPC (2<<9) |
3035 | #define TRANS_DP_12BPC (3<<9) | 3035 | #define TRANS_DP_12BPC (3<<9) |
3036 | #define TRANS_DP_BPC_MASK (3<<9) | ||
3036 | #define TRANS_DP_VSYNC_ACTIVE_HIGH (1<<4) | 3037 | #define TRANS_DP_VSYNC_ACTIVE_HIGH (1<<4) |
3037 | #define TRANS_DP_VSYNC_ACTIVE_LOW 0 | 3038 | #define TRANS_DP_VSYNC_ACTIVE_LOW 0 |
3038 | #define TRANS_DP_HSYNC_ACTIVE_HIGH (1<<3) | 3039 | #define TRANS_DP_HSYNC_ACTIVE_HIGH (1<<3) |
diff --git a/drivers/gpu/drm/i915/intel_acpi.c b/drivers/gpu/drm/i915/intel_acpi.c index 65c88f9ba12c..2cb8e0b9f1ee 100644 --- a/drivers/gpu/drm/i915/intel_acpi.c +++ b/drivers/gpu/drm/i915/intel_acpi.c | |||
@@ -190,37 +190,6 @@ out: | |||
190 | kfree(output.pointer); | 190 | kfree(output.pointer); |
191 | } | 191 | } |
192 | 192 | ||
193 | static int intel_dsm_switchto(enum vga_switcheroo_client_id id) | ||
194 | { | ||
195 | return 0; | ||
196 | } | ||
197 | |||
198 | static int intel_dsm_power_state(enum vga_switcheroo_client_id id, | ||
199 | enum vga_switcheroo_state state) | ||
200 | { | ||
201 | return 0; | ||
202 | } | ||
203 | |||
204 | static int intel_dsm_init(void) | ||
205 | { | ||
206 | return 0; | ||
207 | } | ||
208 | |||
209 | static int intel_dsm_get_client_id(struct pci_dev *pdev) | ||
210 | { | ||
211 | if (intel_dsm_priv.dhandle == DEVICE_ACPI_HANDLE(&pdev->dev)) | ||
212 | return VGA_SWITCHEROO_IGD; | ||
213 | else | ||
214 | return VGA_SWITCHEROO_DIS; | ||
215 | } | ||
216 | |||
217 | static struct vga_switcheroo_handler intel_dsm_handler = { | ||
218 | .switchto = intel_dsm_switchto, | ||
219 | .power_state = intel_dsm_power_state, | ||
220 | .init = intel_dsm_init, | ||
221 | .get_client_id = intel_dsm_get_client_id, | ||
222 | }; | ||
223 | |||
224 | static bool intel_dsm_pci_probe(struct pci_dev *pdev) | 193 | static bool intel_dsm_pci_probe(struct pci_dev *pdev) |
225 | { | 194 | { |
226 | acpi_handle dhandle, intel_handle; | 195 | acpi_handle dhandle, intel_handle; |
@@ -276,11 +245,8 @@ void intel_register_dsm_handler(void) | |||
276 | { | 245 | { |
277 | if (!intel_dsm_detect()) | 246 | if (!intel_dsm_detect()) |
278 | return; | 247 | return; |
279 | |||
280 | vga_switcheroo_register_handler(&intel_dsm_handler); | ||
281 | } | 248 | } |
282 | 249 | ||
283 | void intel_unregister_dsm_handler(void) | 250 | void intel_unregister_dsm_handler(void) |
284 | { | 251 | { |
285 | vga_switcheroo_unregister_handler(); | ||
286 | } | 252 | } |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 255b52ee0091..d9b7092439ef 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -2120,9 +2120,11 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc) | |||
2120 | reg = TRANS_DP_CTL(pipe); | 2120 | reg = TRANS_DP_CTL(pipe); |
2121 | temp = I915_READ(reg); | 2121 | temp = I915_READ(reg); |
2122 | temp &= ~(TRANS_DP_PORT_SEL_MASK | | 2122 | temp &= ~(TRANS_DP_PORT_SEL_MASK | |
2123 | TRANS_DP_SYNC_MASK); | 2123 | TRANS_DP_SYNC_MASK | |
2124 | TRANS_DP_BPC_MASK); | ||
2124 | temp |= (TRANS_DP_OUTPUT_ENABLE | | 2125 | temp |= (TRANS_DP_OUTPUT_ENABLE | |
2125 | TRANS_DP_ENH_FRAMING); | 2126 | TRANS_DP_ENH_FRAMING); |
2127 | temp |= TRANS_DP_8BPC; | ||
2126 | 2128 | ||
2127 | if (crtc->mode.flags & DRM_MODE_FLAG_PHSYNC) | 2129 | if (crtc->mode.flags & DRM_MODE_FLAG_PHSYNC) |
2128 | temp |= TRANS_DP_HSYNC_ACTIVE_HIGH; | 2130 | temp |= TRANS_DP_HSYNC_ACTIVE_HIGH; |
@@ -2712,27 +2714,19 @@ fdi_reduce_ratio(u32 *num, u32 *den) | |||
2712 | } | 2714 | } |
2713 | } | 2715 | } |
2714 | 2716 | ||
2715 | #define DATA_N 0x800000 | ||
2716 | #define LINK_N 0x80000 | ||
2717 | |||
2718 | static void | 2717 | static void |
2719 | ironlake_compute_m_n(int bits_per_pixel, int nlanes, int pixel_clock, | 2718 | ironlake_compute_m_n(int bits_per_pixel, int nlanes, int pixel_clock, |
2720 | int link_clock, struct fdi_m_n *m_n) | 2719 | int link_clock, struct fdi_m_n *m_n) |
2721 | { | 2720 | { |
2722 | u64 temp; | ||
2723 | |||
2724 | m_n->tu = 64; /* default size */ | 2721 | m_n->tu = 64; /* default size */ |
2725 | 2722 | ||
2726 | temp = (u64) DATA_N * pixel_clock; | 2723 | /* BUG_ON(pixel_clock > INT_MAX / 36); */ |
2727 | temp = div_u64(temp, link_clock); | 2724 | m_n->gmch_m = bits_per_pixel * pixel_clock; |
2728 | m_n->gmch_m = div_u64(temp * bits_per_pixel, nlanes); | 2725 | m_n->gmch_n = link_clock * nlanes * 8; |
2729 | m_n->gmch_m >>= 3; /* convert to bytes_per_pixel */ | ||
2730 | m_n->gmch_n = DATA_N; | ||
2731 | fdi_reduce_ratio(&m_n->gmch_m, &m_n->gmch_n); | 2726 | fdi_reduce_ratio(&m_n->gmch_m, &m_n->gmch_n); |
2732 | 2727 | ||
2733 | temp = (u64) LINK_N * pixel_clock; | 2728 | m_n->link_m = pixel_clock; |
2734 | m_n->link_m = div_u64(temp, link_clock); | 2729 | m_n->link_n = link_clock; |
2735 | m_n->link_n = LINK_N; | ||
2736 | fdi_reduce_ratio(&m_n->link_m, &m_n->link_n); | 2730 | fdi_reduce_ratio(&m_n->link_m, &m_n->link_n); |
2737 | } | 2731 | } |
2738 | 2732 | ||
@@ -3716,6 +3710,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
3716 | 3710 | ||
3717 | /* FDI link */ | 3711 | /* FDI link */ |
3718 | if (HAS_PCH_SPLIT(dev)) { | 3712 | if (HAS_PCH_SPLIT(dev)) { |
3713 | int pixel_multiplier = intel_mode_get_pixel_multiplier(adjusted_mode); | ||
3719 | int lane = 0, link_bw, bpp; | 3714 | int lane = 0, link_bw, bpp; |
3720 | /* CPU eDP doesn't require FDI link, so just set DP M/N | 3715 | /* CPU eDP doesn't require FDI link, so just set DP M/N |
3721 | according to current link config */ | 3716 | according to current link config */ |
@@ -3799,6 +3794,8 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
3799 | 3794 | ||
3800 | intel_crtc->fdi_lanes = lane; | 3795 | intel_crtc->fdi_lanes = lane; |
3801 | 3796 | ||
3797 | if (pixel_multiplier > 1) | ||
3798 | link_bw *= pixel_multiplier; | ||
3802 | ironlake_compute_m_n(bpp, lane, target_clock, link_bw, &m_n); | 3799 | ironlake_compute_m_n(bpp, lane, target_clock, link_bw, &m_n); |
3803 | } | 3800 | } |
3804 | 3801 | ||
@@ -5236,6 +5233,55 @@ static const struct drm_crtc_funcs intel_crtc_funcs = { | |||
5236 | .page_flip = intel_crtc_page_flip, | 5233 | .page_flip = intel_crtc_page_flip, |
5237 | }; | 5234 | }; |
5238 | 5235 | ||
5236 | static void intel_sanitize_modesetting(struct drm_device *dev, | ||
5237 | int pipe, int plane) | ||
5238 | { | ||
5239 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
5240 | u32 reg, val; | ||
5241 | |||
5242 | if (HAS_PCH_SPLIT(dev)) | ||
5243 | return; | ||
5244 | |||
5245 | /* Who knows what state these registers were left in by the BIOS or | ||
5246 | * grub? | ||
5247 | * | ||
5248 | * If we leave the registers in a conflicting state (e.g. with the | ||
5249 | * display plane reading from the other pipe than the one we intend | ||
5250 | * to use) then when we attempt to teardown the active mode, we will | ||
5251 | * not disable the pipes and planes in the correct order -- leaving | ||
5252 | * a plane reading from a disabled pipe and possibly leading to | ||
5253 | * undefined behaviour. | ||
5254 | */ | ||
5255 | |||
5256 | reg = DSPCNTR(plane); | ||
5257 | val = I915_READ(reg); | ||
5258 | |||
5259 | if ((val & DISPLAY_PLANE_ENABLE) == 0) | ||
5260 | return; | ||
5261 | if (!!(val & DISPPLANE_SEL_PIPE_MASK) == pipe) | ||
5262 | return; | ||
5263 | |||
5264 | /* This display plane is active and attached to the other CPU pipe. */ | ||
5265 | pipe = !pipe; | ||
5266 | |||
5267 | /* Disable the plane and wait for it to stop reading from the pipe. */ | ||
5268 | I915_WRITE(reg, val & ~DISPLAY_PLANE_ENABLE); | ||
5269 | intel_flush_display_plane(dev, plane); | ||
5270 | |||
5271 | if (IS_GEN2(dev)) | ||
5272 | intel_wait_for_vblank(dev, pipe); | ||
5273 | |||
5274 | if (pipe == 0 && (dev_priv->quirks & QUIRK_PIPEA_FORCE)) | ||
5275 | return; | ||
5276 | |||
5277 | /* Switch off the pipe. */ | ||
5278 | reg = PIPECONF(pipe); | ||
5279 | val = I915_READ(reg); | ||
5280 | if (val & PIPECONF_ENABLE) { | ||
5281 | I915_WRITE(reg, val & ~PIPECONF_ENABLE); | ||
5282 | intel_wait_for_pipe_off(dev, pipe); | ||
5283 | } | ||
5284 | } | ||
5239 | 5285 | ||
5240 | static void intel_crtc_init(struct drm_device *dev, int pipe) | 5286 | static void intel_crtc_init(struct drm_device *dev, int pipe) |
5241 | { | 5287 | { |
@@ -5287,6 +5333,8 @@ static void intel_crtc_init(struct drm_device *dev, int pipe) | |||
5287 | 5333 | ||
5288 | setup_timer(&intel_crtc->idle_timer, intel_crtc_idle_timer, | 5334 | setup_timer(&intel_crtc->idle_timer, intel_crtc_idle_timer, |
5289 | (unsigned long)intel_crtc); | 5335 | (unsigned long)intel_crtc); |
5336 | |||
5337 | intel_sanitize_modesetting(dev, intel_crtc->pipe, intel_crtc->plane); | ||
5290 | } | 5338 | } |
5291 | 5339 | ||
5292 | int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, | 5340 | int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, |
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 300f64b4238b..df648cb4c296 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
@@ -1376,6 +1376,9 @@ intel_dp_link_down(struct intel_dp *intel_dp) | |||
1376 | struct drm_i915_private *dev_priv = dev->dev_private; | 1376 | struct drm_i915_private *dev_priv = dev->dev_private; |
1377 | uint32_t DP = intel_dp->DP; | 1377 | uint32_t DP = intel_dp->DP; |
1378 | 1378 | ||
1379 | if ((I915_READ(intel_dp->output_reg) & DP_PORT_EN) == 0) | ||
1380 | return; | ||
1381 | |||
1379 | DRM_DEBUG_KMS("\n"); | 1382 | DRM_DEBUG_KMS("\n"); |
1380 | 1383 | ||
1381 | if (is_edp(intel_dp)) { | 1384 | if (is_edp(intel_dp)) { |
@@ -1398,6 +1401,28 @@ intel_dp_link_down(struct intel_dp *intel_dp) | |||
1398 | 1401 | ||
1399 | if (is_edp(intel_dp)) | 1402 | if (is_edp(intel_dp)) |
1400 | DP |= DP_LINK_TRAIN_OFF; | 1403 | DP |= DP_LINK_TRAIN_OFF; |
1404 | |||
1405 | if (!HAS_PCH_CPT(dev) && | ||
1406 | I915_READ(intel_dp->output_reg) & DP_PIPEB_SELECT) { | ||
1407 | struct intel_crtc *intel_crtc = to_intel_crtc(intel_dp->base.base.crtc); | ||
1408 | /* Hardware workaround: leaving our transcoder select | ||
1409 | * set to transcoder B while it's off will prevent the | ||
1410 | * corresponding HDMI output on transcoder A. | ||
1411 | * | ||
1412 | * Combine this with another hardware workaround: | ||
1413 | * transcoder select bit can only be cleared while the | ||
1414 | * port is enabled. | ||
1415 | */ | ||
1416 | DP &= ~DP_PIPEB_SELECT; | ||
1417 | I915_WRITE(intel_dp->output_reg, DP); | ||
1418 | |||
1419 | /* Changes to enable or select take place the vblank | ||
1420 | * after being written. | ||
1421 | */ | ||
1422 | intel_wait_for_vblank(intel_dp->base.base.dev, | ||
1423 | intel_crtc->pipe); | ||
1424 | } | ||
1425 | |||
1401 | I915_WRITE(intel_dp->output_reg, DP & ~DP_PORT_EN); | 1426 | I915_WRITE(intel_dp->output_reg, DP & ~DP_PORT_EN); |
1402 | POSTING_READ(intel_dp->output_reg); | 1427 | POSTING_READ(intel_dp->output_reg); |
1403 | } | 1428 | } |
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index f79327fc6653..25bcedf386fd 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c | |||
@@ -68,7 +68,7 @@ static struct intel_lvds *intel_attached_lvds(struct drm_connector *connector) | |||
68 | /** | 68 | /** |
69 | * Sets the power state for the panel. | 69 | * Sets the power state for the panel. |
70 | */ | 70 | */ |
71 | static void intel_lvds_set_power(struct intel_lvds *intel_lvds, bool on) | 71 | static void intel_lvds_enable(struct intel_lvds *intel_lvds) |
72 | { | 72 | { |
73 | struct drm_device *dev = intel_lvds->base.base.dev; | 73 | struct drm_device *dev = intel_lvds->base.base.dev; |
74 | struct drm_i915_private *dev_priv = dev->dev_private; | 74 | struct drm_i915_private *dev_priv = dev->dev_private; |
@@ -82,26 +82,61 @@ static void intel_lvds_set_power(struct intel_lvds *intel_lvds, bool on) | |||
82 | lvds_reg = LVDS; | 82 | lvds_reg = LVDS; |
83 | } | 83 | } |
84 | 84 | ||
85 | if (on) { | 85 | I915_WRITE(lvds_reg, I915_READ(lvds_reg) | LVDS_PORT_EN); |
86 | I915_WRITE(lvds_reg, I915_READ(lvds_reg) | LVDS_PORT_EN); | ||
87 | I915_WRITE(ctl_reg, I915_READ(ctl_reg) | POWER_TARGET_ON); | ||
88 | intel_panel_set_backlight(dev, dev_priv->backlight_level); | ||
89 | } else { | ||
90 | dev_priv->backlight_level = intel_panel_get_backlight(dev); | ||
91 | |||
92 | intel_panel_set_backlight(dev, 0); | ||
93 | I915_WRITE(ctl_reg, I915_READ(ctl_reg) & ~POWER_TARGET_ON); | ||
94 | 86 | ||
95 | if (intel_lvds->pfit_control) { | 87 | if (intel_lvds->pfit_dirty) { |
96 | if (wait_for((I915_READ(PP_STATUS) & PP_ON) == 0, 1000)) | 88 | /* |
97 | DRM_ERROR("timed out waiting for panel to power off\n"); | 89 | * Enable automatic panel scaling so that non-native modes |
98 | I915_WRITE(PFIT_CONTROL, 0); | 90 | * fill the screen. The panel fitter should only be |
99 | intel_lvds->pfit_control = 0; | 91 | * adjusted whilst the pipe is disabled, according to |
92 | * register description and PRM. | ||
93 | */ | ||
94 | DRM_DEBUG_KMS("applying panel-fitter: %x, %x\n", | ||
95 | intel_lvds->pfit_control, | ||
96 | intel_lvds->pfit_pgm_ratios); | ||
97 | if (wait_for((I915_READ(PP_STATUS) & PP_ON) == 0, 1000)) { | ||
98 | DRM_ERROR("timed out waiting for panel to power off\n"); | ||
99 | } else { | ||
100 | I915_WRITE(PFIT_PGM_RATIOS, intel_lvds->pfit_pgm_ratios); | ||
101 | I915_WRITE(PFIT_CONTROL, intel_lvds->pfit_control); | ||
100 | intel_lvds->pfit_dirty = false; | 102 | intel_lvds->pfit_dirty = false; |
101 | } | 103 | } |
104 | } | ||
105 | |||
106 | I915_WRITE(ctl_reg, I915_READ(ctl_reg) | POWER_TARGET_ON); | ||
107 | POSTING_READ(lvds_reg); | ||
108 | |||
109 | intel_panel_set_backlight(dev, dev_priv->backlight_level); | ||
110 | } | ||
102 | 111 | ||
103 | I915_WRITE(lvds_reg, I915_READ(lvds_reg) & ~LVDS_PORT_EN); | 112 | static void intel_lvds_disable(struct intel_lvds *intel_lvds) |
113 | { | ||
114 | struct drm_device *dev = intel_lvds->base.base.dev; | ||
115 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
116 | u32 ctl_reg, lvds_reg; | ||
117 | |||
118 | if (HAS_PCH_SPLIT(dev)) { | ||
119 | ctl_reg = PCH_PP_CONTROL; | ||
120 | lvds_reg = PCH_LVDS; | ||
121 | } else { | ||
122 | ctl_reg = PP_CONTROL; | ||
123 | lvds_reg = LVDS; | ||
124 | } | ||
125 | |||
126 | dev_priv->backlight_level = intel_panel_get_backlight(dev); | ||
127 | intel_panel_set_backlight(dev, 0); | ||
128 | |||
129 | I915_WRITE(ctl_reg, I915_READ(ctl_reg) & ~POWER_TARGET_ON); | ||
130 | |||
131 | if (intel_lvds->pfit_control) { | ||
132 | if (wait_for((I915_READ(PP_STATUS) & PP_ON) == 0, 1000)) | ||
133 | DRM_ERROR("timed out waiting for panel to power off\n"); | ||
134 | |||
135 | I915_WRITE(PFIT_CONTROL, 0); | ||
136 | intel_lvds->pfit_dirty = true; | ||
104 | } | 137 | } |
138 | |||
139 | I915_WRITE(lvds_reg, I915_READ(lvds_reg) & ~LVDS_PORT_EN); | ||
105 | POSTING_READ(lvds_reg); | 140 | POSTING_READ(lvds_reg); |
106 | } | 141 | } |
107 | 142 | ||
@@ -110,9 +145,9 @@ static void intel_lvds_dpms(struct drm_encoder *encoder, int mode) | |||
110 | struct intel_lvds *intel_lvds = to_intel_lvds(encoder); | 145 | struct intel_lvds *intel_lvds = to_intel_lvds(encoder); |
111 | 146 | ||
112 | if (mode == DRM_MODE_DPMS_ON) | 147 | if (mode == DRM_MODE_DPMS_ON) |
113 | intel_lvds_set_power(intel_lvds, true); | 148 | intel_lvds_enable(intel_lvds); |
114 | else | 149 | else |
115 | intel_lvds_set_power(intel_lvds, false); | 150 | intel_lvds_disable(intel_lvds); |
116 | 151 | ||
117 | /* XXX: We never power down the LVDS pairs. */ | 152 | /* XXX: We never power down the LVDS pairs. */ |
118 | } | 153 | } |
@@ -411,43 +446,18 @@ static void intel_lvds_commit(struct drm_encoder *encoder) | |||
411 | /* Always do a full power on as we do not know what state | 446 | /* Always do a full power on as we do not know what state |
412 | * we were left in. | 447 | * we were left in. |
413 | */ | 448 | */ |
414 | intel_lvds_set_power(intel_lvds, true); | 449 | intel_lvds_enable(intel_lvds); |
415 | } | 450 | } |
416 | 451 | ||
417 | static void intel_lvds_mode_set(struct drm_encoder *encoder, | 452 | static void intel_lvds_mode_set(struct drm_encoder *encoder, |
418 | struct drm_display_mode *mode, | 453 | struct drm_display_mode *mode, |
419 | struct drm_display_mode *adjusted_mode) | 454 | struct drm_display_mode *adjusted_mode) |
420 | { | 455 | { |
421 | struct drm_device *dev = encoder->dev; | ||
422 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
423 | struct intel_lvds *intel_lvds = to_intel_lvds(encoder); | ||
424 | |||
425 | /* | 456 | /* |
426 | * The LVDS pin pair will already have been turned on in the | 457 | * The LVDS pin pair will already have been turned on in the |
427 | * intel_crtc_mode_set since it has a large impact on the DPLL | 458 | * intel_crtc_mode_set since it has a large impact on the DPLL |
428 | * settings. | 459 | * settings. |
429 | */ | 460 | */ |
430 | |||
431 | if (HAS_PCH_SPLIT(dev)) | ||
432 | return; | ||
433 | |||
434 | if (!intel_lvds->pfit_dirty) | ||
435 | return; | ||
436 | |||
437 | /* | ||
438 | * Enable automatic panel scaling so that non-native modes fill the | ||
439 | * screen. Should be enabled before the pipe is enabled, according to | ||
440 | * register description and PRM. | ||
441 | */ | ||
442 | DRM_DEBUG_KMS("applying panel-fitter: %x, %x\n", | ||
443 | intel_lvds->pfit_control, | ||
444 | intel_lvds->pfit_pgm_ratios); | ||
445 | if (wait_for((I915_READ(PP_STATUS) & PP_ON) == 0, 1000)) | ||
446 | DRM_ERROR("timed out waiting for panel to power off\n"); | ||
447 | |||
448 | I915_WRITE(PFIT_PGM_RATIOS, intel_lvds->pfit_pgm_ratios); | ||
449 | I915_WRITE(PFIT_CONTROL, intel_lvds->pfit_control); | ||
450 | intel_lvds->pfit_dirty = false; | ||
451 | } | 461 | } |
452 | 462 | ||
453 | /** | 463 | /** |
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index b83306f9244b..89a65be8a3f3 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c | |||
@@ -156,23 +156,25 @@ static int init_ring_common(struct drm_device *dev, | |||
156 | 156 | ||
157 | /* G45 ring initialization fails to reset head to zero */ | 157 | /* G45 ring initialization fails to reset head to zero */ |
158 | if (head != 0) { | 158 | if (head != 0) { |
159 | DRM_ERROR("%s head not reset to zero " | 159 | DRM_DEBUG_KMS("%s head not reset to zero " |
160 | "ctl %08x head %08x tail %08x start %08x\n", | 160 | "ctl %08x head %08x tail %08x start %08x\n", |
161 | ring->name, | 161 | ring->name, |
162 | I915_READ_CTL(ring), | 162 | I915_READ_CTL(ring), |
163 | I915_READ_HEAD(ring), | 163 | I915_READ_HEAD(ring), |
164 | I915_READ_TAIL(ring), | 164 | I915_READ_TAIL(ring), |
165 | I915_READ_START(ring)); | 165 | I915_READ_START(ring)); |
166 | 166 | ||
167 | I915_WRITE_HEAD(ring, 0); | 167 | I915_WRITE_HEAD(ring, 0); |
168 | 168 | ||
169 | DRM_ERROR("%s head forced to zero " | 169 | if (I915_READ_HEAD(ring) & HEAD_ADDR) { |
170 | "ctl %08x head %08x tail %08x start %08x\n", | 170 | DRM_ERROR("failed to set %s head to zero " |
171 | ring->name, | 171 | "ctl %08x head %08x tail %08x start %08x\n", |
172 | I915_READ_CTL(ring), | 172 | ring->name, |
173 | I915_READ_HEAD(ring), | 173 | I915_READ_CTL(ring), |
174 | I915_READ_TAIL(ring), | 174 | I915_READ_HEAD(ring), |
175 | I915_READ_START(ring)); | 175 | I915_READ_TAIL(ring), |
176 | I915_READ_START(ring)); | ||
177 | } | ||
176 | } | 178 | } |
177 | 179 | ||
178 | I915_WRITE_CTL(ring, | 180 | I915_WRITE_CTL(ring, |
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index a3552594ccc4..4d7a2e1bdb90 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
@@ -878,12 +878,15 @@ void r600_pcie_gart_tlb_flush(struct radeon_device *rdev) | |||
878 | u32 tmp; | 878 | u32 tmp; |
879 | 879 | ||
880 | /* flush hdp cache so updates hit vram */ | 880 | /* flush hdp cache so updates hit vram */ |
881 | if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740)) { | 881 | if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740) && |
882 | !(rdev->flags & RADEON_IS_AGP)) { | ||
882 | void __iomem *ptr = (void *)rdev->gart.table.vram.ptr; | 883 | void __iomem *ptr = (void *)rdev->gart.table.vram.ptr; |
883 | u32 tmp; | 884 | u32 tmp; |
884 | 885 | ||
885 | /* r7xx hw bug. write to HDP_DEBUG1 followed by fb read | 886 | /* r7xx hw bug. write to HDP_DEBUG1 followed by fb read |
886 | * rather than write to HDP_REG_COHERENCY_FLUSH_CNTL | 887 | * rather than write to HDP_REG_COHERENCY_FLUSH_CNTL |
888 | * This seems to cause problems on some AGP cards. Just use the old | ||
889 | * method for them. | ||
887 | */ | 890 | */ |
888 | WREG32(HDP_DEBUG1, 0); | 891 | WREG32(HDP_DEBUG1, 0); |
889 | tmp = readl((void __iomem *)ptr); | 892 | tmp = readl((void __iomem *)ptr); |
@@ -1195,8 +1198,10 @@ void r600_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc) | |||
1195 | mc->vram_end, mc->real_vram_size >> 20); | 1198 | mc->vram_end, mc->real_vram_size >> 20); |
1196 | } else { | 1199 | } else { |
1197 | u64 base = 0; | 1200 | u64 base = 0; |
1198 | if (rdev->flags & RADEON_IS_IGP) | 1201 | if (rdev->flags & RADEON_IS_IGP) { |
1199 | base = (RREG32(MC_VM_FB_LOCATION) & 0xFFFF) << 24; | 1202 | base = RREG32(MC_VM_FB_LOCATION) & 0xFFFF; |
1203 | base <<= 24; | ||
1204 | } | ||
1200 | radeon_vram_location(rdev, &rdev->mc, base); | 1205 | radeon_vram_location(rdev, &rdev->mc, base); |
1201 | rdev->mc.gtt_base_align = 0; | 1206 | rdev->mc.gtt_base_align = 0; |
1202 | radeon_gtt_location(rdev, mc); | 1207 | radeon_gtt_location(rdev, mc); |
@@ -3483,10 +3488,12 @@ int r600_debugfs_mc_info_init(struct radeon_device *rdev) | |||
3483 | void r600_ioctl_wait_idle(struct radeon_device *rdev, struct radeon_bo *bo) | 3488 | void r600_ioctl_wait_idle(struct radeon_device *rdev, struct radeon_bo *bo) |
3484 | { | 3489 | { |
3485 | /* r7xx hw bug. write to HDP_DEBUG1 followed by fb read | 3490 | /* r7xx hw bug. write to HDP_DEBUG1 followed by fb read |
3486 | * rather than write to HDP_REG_COHERENCY_FLUSH_CNTL | 3491 | * rather than write to HDP_REG_COHERENCY_FLUSH_CNTL. |
3492 | * This seems to cause problems on some AGP cards. Just use the old | ||
3493 | * method for them. | ||
3487 | */ | 3494 | */ |
3488 | if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740) && | 3495 | if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740) && |
3489 | rdev->vram_scratch.ptr) { | 3496 | rdev->vram_scratch.ptr && !(rdev->flags & RADEON_IS_AGP)) { |
3490 | void __iomem *ptr = (void *)rdev->vram_scratch.ptr; | 3497 | void __iomem *ptr = (void *)rdev->vram_scratch.ptr; |
3491 | u32 tmp; | 3498 | u32 tmp; |
3492 | 3499 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index d8ac1849180d..e12e79326cb1 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c | |||
@@ -286,7 +286,7 @@ void radeon_vram_location(struct radeon_device *rdev, struct radeon_mc *mc, u64 | |||
286 | mc->mc_vram_size = mc->aper_size; | 286 | mc->mc_vram_size = mc->aper_size; |
287 | } | 287 | } |
288 | mc->vram_end = mc->vram_start + mc->mc_vram_size - 1; | 288 | mc->vram_end = mc->vram_start + mc->mc_vram_size - 1; |
289 | dev_info(rdev->dev, "VRAM: %lluM 0x%08llX - 0x%08llX (%lluM used)\n", | 289 | dev_info(rdev->dev, "VRAM: %lluM 0x%016llX - 0x%016llX (%lluM used)\n", |
290 | mc->mc_vram_size >> 20, mc->vram_start, | 290 | mc->mc_vram_size >> 20, mc->vram_start, |
291 | mc->vram_end, mc->real_vram_size >> 20); | 291 | mc->vram_end, mc->real_vram_size >> 20); |
292 | } | 292 | } |
@@ -323,7 +323,7 @@ void radeon_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc) | |||
323 | mc->gtt_start = (mc->vram_end + 1 + mc->gtt_base_align) & ~mc->gtt_base_align; | 323 | mc->gtt_start = (mc->vram_end + 1 + mc->gtt_base_align) & ~mc->gtt_base_align; |
324 | } | 324 | } |
325 | mc->gtt_end = mc->gtt_start + mc->gtt_size - 1; | 325 | mc->gtt_end = mc->gtt_start + mc->gtt_size - 1; |
326 | dev_info(rdev->dev, "GTT: %lluM 0x%08llX - 0x%08llX\n", | 326 | dev_info(rdev->dev, "GTT: %lluM 0x%016llX - 0x%016llX\n", |
327 | mc->gtt_size >> 20, mc->gtt_start, mc->gtt_end); | 327 | mc->gtt_size >> 20, mc->gtt_start, mc->gtt_end); |
328 | } | 328 | } |
329 | 329 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index 1d067743fee0..a598d0049aa5 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c | |||
@@ -69,7 +69,7 @@ void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain) | |||
69 | u32 c = 0; | 69 | u32 c = 0; |
70 | 70 | ||
71 | rbo->placement.fpfn = 0; | 71 | rbo->placement.fpfn = 0; |
72 | rbo->placement.lpfn = rbo->rdev->mc.active_vram_size >> PAGE_SHIFT; | 72 | rbo->placement.lpfn = 0; |
73 | rbo->placement.placement = rbo->placements; | 73 | rbo->placement.placement = rbo->placements; |
74 | rbo->placement.busy_placement = rbo->placements; | 74 | rbo->placement.busy_placement = rbo->placements; |
75 | if (domain & RADEON_GEM_DOMAIN_VRAM) | 75 | if (domain & RADEON_GEM_DOMAIN_VRAM) |
@@ -91,7 +91,8 @@ int radeon_bo_create(struct radeon_device *rdev, struct drm_gem_object *gobj, | |||
91 | { | 91 | { |
92 | struct radeon_bo *bo; | 92 | struct radeon_bo *bo; |
93 | enum ttm_bo_type type; | 93 | enum ttm_bo_type type; |
94 | int page_align = roundup(byte_align, PAGE_SIZE) >> PAGE_SHIFT; | 94 | unsigned long page_align = roundup(byte_align, PAGE_SIZE) >> PAGE_SHIFT; |
95 | unsigned long max_size = 0; | ||
95 | int r; | 96 | int r; |
96 | 97 | ||
97 | if (unlikely(rdev->mman.bdev.dev_mapping == NULL)) { | 98 | if (unlikely(rdev->mman.bdev.dev_mapping == NULL)) { |
@@ -104,6 +105,14 @@ int radeon_bo_create(struct radeon_device *rdev, struct drm_gem_object *gobj, | |||
104 | } | 105 | } |
105 | *bo_ptr = NULL; | 106 | *bo_ptr = NULL; |
106 | 107 | ||
108 | /* maximun bo size is the minimun btw visible vram and gtt size */ | ||
109 | max_size = min(rdev->mc.visible_vram_size, rdev->mc.gtt_size); | ||
110 | if ((page_align << PAGE_SHIFT) >= max_size) { | ||
111 | printk(KERN_WARNING "%s:%d alloc size %ldM bigger than %ldMb limit\n", | ||
112 | __func__, __LINE__, page_align >> (20 - PAGE_SHIFT), max_size >> 20); | ||
113 | return -ENOMEM; | ||
114 | } | ||
115 | |||
107 | retry: | 116 | retry: |
108 | bo = kzalloc(sizeof(struct radeon_bo), GFP_KERNEL); | 117 | bo = kzalloc(sizeof(struct radeon_bo), GFP_KERNEL); |
109 | if (bo == NULL) | 118 | if (bo == NULL) |
diff --git a/drivers/hwmon/adm1026.c b/drivers/hwmon/adm1026.c index 4bf969c0a32b..be0fdd58aa29 100644 --- a/drivers/hwmon/adm1026.c +++ b/drivers/hwmon/adm1026.c | |||
@@ -916,27 +916,27 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr, | |||
916 | int nr = sensor_attr->index; | 916 | int nr = sensor_attr->index; |
917 | struct i2c_client *client = to_i2c_client(dev); | 917 | struct i2c_client *client = to_i2c_client(dev); |
918 | struct adm1026_data *data = i2c_get_clientdata(client); | 918 | struct adm1026_data *data = i2c_get_clientdata(client); |
919 | int val, orig_div, new_div, shift; | 919 | int val, orig_div, new_div; |
920 | 920 | ||
921 | val = simple_strtol(buf, NULL, 10); | 921 | val = simple_strtol(buf, NULL, 10); |
922 | new_div = DIV_TO_REG(val); | 922 | new_div = DIV_TO_REG(val); |
923 | if (new_div == 0) { | 923 | |
924 | return -EINVAL; | ||
925 | } | ||
926 | mutex_lock(&data->update_lock); | 924 | mutex_lock(&data->update_lock); |
927 | orig_div = data->fan_div[nr]; | 925 | orig_div = data->fan_div[nr]; |
928 | data->fan_div[nr] = DIV_FROM_REG(new_div); | 926 | data->fan_div[nr] = DIV_FROM_REG(new_div); |
929 | 927 | ||
930 | if (nr < 4) { /* 0 <= nr < 4 */ | 928 | if (nr < 4) { /* 0 <= nr < 4 */ |
931 | shift = 2 * nr; | ||
932 | adm1026_write_value(client, ADM1026_REG_FAN_DIV_0_3, | 929 | adm1026_write_value(client, ADM1026_REG_FAN_DIV_0_3, |
933 | ((DIV_TO_REG(orig_div) & (~(0x03 << shift))) | | 930 | (DIV_TO_REG(data->fan_div[0]) << 0) | |
934 | (new_div << shift))); | 931 | (DIV_TO_REG(data->fan_div[1]) << 2) | |
932 | (DIV_TO_REG(data->fan_div[2]) << 4) | | ||
933 | (DIV_TO_REG(data->fan_div[3]) << 6)); | ||
935 | } else { /* 3 < nr < 8 */ | 934 | } else { /* 3 < nr < 8 */ |
936 | shift = 2 * (nr - 4); | ||
937 | adm1026_write_value(client, ADM1026_REG_FAN_DIV_4_7, | 935 | adm1026_write_value(client, ADM1026_REG_FAN_DIV_4_7, |
938 | ((DIV_TO_REG(orig_div) & (~(0x03 << (2 * shift)))) | | 936 | (DIV_TO_REG(data->fan_div[4]) << 0) | |
939 | (new_div << shift))); | 937 | (DIV_TO_REG(data->fan_div[5]) << 2) | |
938 | (DIV_TO_REG(data->fan_div[6]) << 4) | | ||
939 | (DIV_TO_REG(data->fan_div[7]) << 6)); | ||
940 | } | 940 | } |
941 | 941 | ||
942 | if (data->fan_div[nr] != orig_div) { | 942 | if (data->fan_div[nr] != orig_div) { |
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c index 14a5d981be7d..a428a9264195 100644 --- a/drivers/hwmon/it87.c +++ b/drivers/hwmon/it87.c | |||
@@ -187,6 +187,7 @@ static const u8 IT87_REG_FANX_MIN[] = { 0x1b, 0x1c, 0x1d, 0x85, 0x87 }; | |||
187 | #define IT87_REG_FAN_MAIN_CTRL 0x13 | 187 | #define IT87_REG_FAN_MAIN_CTRL 0x13 |
188 | #define IT87_REG_FAN_CTL 0x14 | 188 | #define IT87_REG_FAN_CTL 0x14 |
189 | #define IT87_REG_PWM(nr) (0x15 + (nr)) | 189 | #define IT87_REG_PWM(nr) (0x15 + (nr)) |
190 | #define IT87_REG_PWM_DUTY(nr) (0x63 + (nr) * 8) | ||
190 | 191 | ||
191 | #define IT87_REG_VIN(nr) (0x20 + (nr)) | 192 | #define IT87_REG_VIN(nr) (0x20 + (nr)) |
192 | #define IT87_REG_TEMP(nr) (0x29 + (nr)) | 193 | #define IT87_REG_TEMP(nr) (0x29 + (nr)) |
@@ -251,12 +252,16 @@ struct it87_data { | |||
251 | u8 fan_main_ctrl; /* Register value */ | 252 | u8 fan_main_ctrl; /* Register value */ |
252 | u8 fan_ctl; /* Register value */ | 253 | u8 fan_ctl; /* Register value */ |
253 | 254 | ||
254 | /* The following 3 arrays correspond to the same registers. The | 255 | /* The following 3 arrays correspond to the same registers up to |
255 | * meaning of bits 6-0 depends on the value of bit 7, and we want | 256 | * the IT8720F. The meaning of bits 6-0 depends on the value of bit |
256 | * to preserve settings on mode changes, so we have to track all | 257 | * 7, and we want to preserve settings on mode changes, so we have |
257 | * values separately. */ | 258 | * to track all values separately. |
259 | * Starting with the IT8721F, the manual PWM duty cycles are stored | ||
260 | * in separate registers (8-bit values), so the separate tracking | ||
261 | * is no longer needed, but it is still done to keep the driver | ||
262 | * simple. */ | ||
258 | u8 pwm_ctrl[3]; /* Register value */ | 263 | u8 pwm_ctrl[3]; /* Register value */ |
259 | u8 pwm_duty[3]; /* Manual PWM value set by user (bit 6-0) */ | 264 | u8 pwm_duty[3]; /* Manual PWM value set by user */ |
260 | u8 pwm_temp_map[3]; /* PWM to temp. chan. mapping (bits 1-0) */ | 265 | u8 pwm_temp_map[3]; /* PWM to temp. chan. mapping (bits 1-0) */ |
261 | 266 | ||
262 | /* Automatic fan speed control registers */ | 267 | /* Automatic fan speed control registers */ |
@@ -832,7 +837,9 @@ static ssize_t set_pwm_enable(struct device *dev, | |||
832 | data->fan_main_ctrl); | 837 | data->fan_main_ctrl); |
833 | } else { | 838 | } else { |
834 | if (val == 1) /* Manual mode */ | 839 | if (val == 1) /* Manual mode */ |
835 | data->pwm_ctrl[nr] = data->pwm_duty[nr]; | 840 | data->pwm_ctrl[nr] = data->type == it8721 ? |
841 | data->pwm_temp_map[nr] : | ||
842 | data->pwm_duty[nr]; | ||
836 | else /* Automatic mode */ | 843 | else /* Automatic mode */ |
837 | data->pwm_ctrl[nr] = 0x80 | data->pwm_temp_map[nr]; | 844 | data->pwm_ctrl[nr] = 0x80 | data->pwm_temp_map[nr]; |
838 | it87_write_value(data, IT87_REG_PWM(nr), data->pwm_ctrl[nr]); | 845 | it87_write_value(data, IT87_REG_PWM(nr), data->pwm_ctrl[nr]); |
@@ -858,12 +865,25 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, | |||
858 | return -EINVAL; | 865 | return -EINVAL; |
859 | 866 | ||
860 | mutex_lock(&data->update_lock); | 867 | mutex_lock(&data->update_lock); |
861 | data->pwm_duty[nr] = pwm_to_reg(data, val); | 868 | if (data->type == it8721) { |
862 | /* If we are in manual mode, write the duty cycle immediately; | 869 | /* If we are in automatic mode, the PWM duty cycle register |
863 | * otherwise, just store it for later use. */ | 870 | * is read-only so we can't write the value */ |
864 | if (!(data->pwm_ctrl[nr] & 0x80)) { | 871 | if (data->pwm_ctrl[nr] & 0x80) { |
865 | data->pwm_ctrl[nr] = data->pwm_duty[nr]; | 872 | mutex_unlock(&data->update_lock); |
866 | it87_write_value(data, IT87_REG_PWM(nr), data->pwm_ctrl[nr]); | 873 | return -EBUSY; |
874 | } | ||
875 | data->pwm_duty[nr] = pwm_to_reg(data, val); | ||
876 | it87_write_value(data, IT87_REG_PWM_DUTY(nr), | ||
877 | data->pwm_duty[nr]); | ||
878 | } else { | ||
879 | data->pwm_duty[nr] = pwm_to_reg(data, val); | ||
880 | /* If we are in manual mode, write the duty cycle immediately; | ||
881 | * otherwise, just store it for later use. */ | ||
882 | if (!(data->pwm_ctrl[nr] & 0x80)) { | ||
883 | data->pwm_ctrl[nr] = data->pwm_duty[nr]; | ||
884 | it87_write_value(data, IT87_REG_PWM(nr), | ||
885 | data->pwm_ctrl[nr]); | ||
886 | } | ||
867 | } | 887 | } |
868 | mutex_unlock(&data->update_lock); | 888 | mutex_unlock(&data->update_lock); |
869 | return count; | 889 | return count; |
@@ -1958,7 +1978,10 @@ static void __devinit it87_init_device(struct platform_device *pdev) | |||
1958 | * channels to use when later setting to automatic mode later. | 1978 | * channels to use when later setting to automatic mode later. |
1959 | * Use a 1:1 mapping by default (we are clueless.) | 1979 | * Use a 1:1 mapping by default (we are clueless.) |
1960 | * In both cases, the value can (and should) be changed by the user | 1980 | * In both cases, the value can (and should) be changed by the user |
1961 | * prior to switching to a different mode. */ | 1981 | * prior to switching to a different mode. |
1982 | * Note that this is no longer needed for the IT8721F and later, as | ||
1983 | * these have separate registers for the temperature mapping and the | ||
1984 | * manual duty cycle. */ | ||
1962 | for (i = 0; i < 3; i++) { | 1985 | for (i = 0; i < 3; i++) { |
1963 | data->pwm_temp_map[i] = i; | 1986 | data->pwm_temp_map[i] = i; |
1964 | data->pwm_duty[i] = 0x7f; /* Full speed */ | 1987 | data->pwm_duty[i] = 0x7f; /* Full speed */ |
@@ -2034,10 +2057,16 @@ static void __devinit it87_init_device(struct platform_device *pdev) | |||
2034 | static void it87_update_pwm_ctrl(struct it87_data *data, int nr) | 2057 | static void it87_update_pwm_ctrl(struct it87_data *data, int nr) |
2035 | { | 2058 | { |
2036 | data->pwm_ctrl[nr] = it87_read_value(data, IT87_REG_PWM(nr)); | 2059 | data->pwm_ctrl[nr] = it87_read_value(data, IT87_REG_PWM(nr)); |
2037 | if (data->pwm_ctrl[nr] & 0x80) /* Automatic mode */ | 2060 | if (data->type == it8721) { |
2038 | data->pwm_temp_map[nr] = data->pwm_ctrl[nr] & 0x03; | 2061 | data->pwm_temp_map[nr] = data->pwm_ctrl[nr] & 0x03; |
2039 | else /* Manual mode */ | 2062 | data->pwm_duty[nr] = it87_read_value(data, |
2040 | data->pwm_duty[nr] = data->pwm_ctrl[nr] & 0x7f; | 2063 | IT87_REG_PWM_DUTY(nr)); |
2064 | } else { | ||
2065 | if (data->pwm_ctrl[nr] & 0x80) /* Automatic mode */ | ||
2066 | data->pwm_temp_map[nr] = data->pwm_ctrl[nr] & 0x03; | ||
2067 | else /* Manual mode */ | ||
2068 | data->pwm_duty[nr] = data->pwm_ctrl[nr] & 0x7f; | ||
2069 | } | ||
2041 | 2070 | ||
2042 | if (has_old_autopwm(data)) { | 2071 | if (has_old_autopwm(data)) { |
2043 | int i; | 2072 | int i; |
diff --git a/drivers/hwmon/ltc4215.c b/drivers/hwmon/ltc4215.c index 00d975eb5b83..c7e6d8e81656 100644 --- a/drivers/hwmon/ltc4215.c +++ b/drivers/hwmon/ltc4215.c | |||
@@ -205,7 +205,6 @@ LTC4215_ALARM(curr1_max_alarm, (1 << 2), LTC4215_STATUS); | |||
205 | 205 | ||
206 | /* Power (virtual) */ | 206 | /* Power (virtual) */ |
207 | LTC4215_POWER(power1_input); | 207 | LTC4215_POWER(power1_input); |
208 | LTC4215_ALARM(power1_alarm, (1 << 3), LTC4215_STATUS); | ||
209 | 208 | ||
210 | /* Input Voltage */ | 209 | /* Input Voltage */ |
211 | LTC4215_VOLTAGE(in1_input, LTC4215_ADIN); | 210 | LTC4215_VOLTAGE(in1_input, LTC4215_ADIN); |
@@ -214,6 +213,7 @@ LTC4215_ALARM(in1_min_alarm, (1 << 1), LTC4215_STATUS); | |||
214 | 213 | ||
215 | /* Output Voltage */ | 214 | /* Output Voltage */ |
216 | LTC4215_VOLTAGE(in2_input, LTC4215_SOURCE); | 215 | LTC4215_VOLTAGE(in2_input, LTC4215_SOURCE); |
216 | LTC4215_ALARM(in2_min_alarm, (1 << 3), LTC4215_STATUS); | ||
217 | 217 | ||
218 | /* Finally, construct an array of pointers to members of the above objects, | 218 | /* Finally, construct an array of pointers to members of the above objects, |
219 | * as required for sysfs_create_group() | 219 | * as required for sysfs_create_group() |
@@ -223,13 +223,13 @@ static struct attribute *ltc4215_attributes[] = { | |||
223 | &sensor_dev_attr_curr1_max_alarm.dev_attr.attr, | 223 | &sensor_dev_attr_curr1_max_alarm.dev_attr.attr, |
224 | 224 | ||
225 | &sensor_dev_attr_power1_input.dev_attr.attr, | 225 | &sensor_dev_attr_power1_input.dev_attr.attr, |
226 | &sensor_dev_attr_power1_alarm.dev_attr.attr, | ||
227 | 226 | ||
228 | &sensor_dev_attr_in1_input.dev_attr.attr, | 227 | &sensor_dev_attr_in1_input.dev_attr.attr, |
229 | &sensor_dev_attr_in1_max_alarm.dev_attr.attr, | 228 | &sensor_dev_attr_in1_max_alarm.dev_attr.attr, |
230 | &sensor_dev_attr_in1_min_alarm.dev_attr.attr, | 229 | &sensor_dev_attr_in1_min_alarm.dev_attr.attr, |
231 | 230 | ||
232 | &sensor_dev_attr_in2_input.dev_attr.attr, | 231 | &sensor_dev_attr_in2_input.dev_attr.attr, |
232 | &sensor_dev_attr_in2_min_alarm.dev_attr.attr, | ||
233 | 233 | ||
234 | NULL, | 234 | NULL, |
235 | }; | 235 | }; |
diff --git a/drivers/i2c/busses/i2c-intel-mid.c b/drivers/i2c/busses/i2c-intel-mid.c index 80f70d3a744d..c71492782bbd 100644 --- a/drivers/i2c/busses/i2c-intel-mid.c +++ b/drivers/i2c/busses/i2c-intel-mid.c | |||
@@ -999,7 +999,7 @@ static int __devinit intel_mid_i2c_probe(struct pci_dev *dev, | |||
999 | 999 | ||
1000 | /* Initialize struct members */ | 1000 | /* Initialize struct members */ |
1001 | snprintf(mrst->adap.name, sizeof(mrst->adap.name), | 1001 | snprintf(mrst->adap.name, sizeof(mrst->adap.name), |
1002 | "MRST/Medfield I2C at %lx", start); | 1002 | "Intel MID I2C at %lx", start); |
1003 | mrst->adap.owner = THIS_MODULE; | 1003 | mrst->adap.owner = THIS_MODULE; |
1004 | mrst->adap.algo = &intel_mid_i2c_algorithm; | 1004 | mrst->adap.algo = &intel_mid_i2c_algorithm; |
1005 | mrst->adap.dev.parent = &dev->dev; | 1005 | mrst->adap.dev.parent = &dev->dev; |
diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c index 41665d2f9f93..c131d58bcb50 100644 --- a/drivers/idle/intel_idle.c +++ b/drivers/idle/intel_idle.c | |||
@@ -273,8 +273,6 @@ static int intel_idle_probe(void) | |||
273 | 273 | ||
274 | pr_debug(PREFIX "MWAIT substates: 0x%x\n", mwait_substates); | 274 | pr_debug(PREFIX "MWAIT substates: 0x%x\n", mwait_substates); |
275 | 275 | ||
276 | if (boot_cpu_has(X86_FEATURE_ARAT)) /* Always Reliable APIC Timer */ | ||
277 | lapic_timer_reliable_states = 0xFFFFFFFF; | ||
278 | 276 | ||
279 | if (boot_cpu_data.x86 != 6) /* family 6 */ | 277 | if (boot_cpu_data.x86 != 6) /* family 6 */ |
280 | return -ENODEV; | 278 | return -ENODEV; |
@@ -286,8 +284,6 @@ static int intel_idle_probe(void) | |||
286 | case 0x1F: /* Core i7 and i5 Processor - Nehalem */ | 284 | case 0x1F: /* Core i7 and i5 Processor - Nehalem */ |
287 | case 0x2E: /* Nehalem-EX Xeon */ | 285 | case 0x2E: /* Nehalem-EX Xeon */ |
288 | case 0x2F: /* Westmere-EX Xeon */ | 286 | case 0x2F: /* Westmere-EX Xeon */ |
289 | lapic_timer_reliable_states = (1 << 1); /* C1 */ | ||
290 | |||
291 | case 0x25: /* Westmere */ | 287 | case 0x25: /* Westmere */ |
292 | case 0x2C: /* Westmere */ | 288 | case 0x2C: /* Westmere */ |
293 | cpuidle_state_table = nehalem_cstates; | 289 | cpuidle_state_table = nehalem_cstates; |
@@ -295,7 +291,6 @@ static int intel_idle_probe(void) | |||
295 | 291 | ||
296 | case 0x1C: /* 28 - Atom Processor */ | 292 | case 0x1C: /* 28 - Atom Processor */ |
297 | case 0x26: /* 38 - Lincroft Atom Processor */ | 293 | case 0x26: /* 38 - Lincroft Atom Processor */ |
298 | lapic_timer_reliable_states = (1 << 1); /* C1 */ | ||
299 | cpuidle_state_table = atom_cstates; | 294 | cpuidle_state_table = atom_cstates; |
300 | break; | 295 | break; |
301 | 296 | ||
@@ -303,10 +298,6 @@ static int intel_idle_probe(void) | |||
303 | case 0x2D: /* SNB Xeon */ | 298 | case 0x2D: /* SNB Xeon */ |
304 | cpuidle_state_table = snb_cstates; | 299 | cpuidle_state_table = snb_cstates; |
305 | break; | 300 | break; |
306 | #ifdef FUTURE_USE | ||
307 | case 0x17: /* 23 - Core 2 Duo */ | ||
308 | lapic_timer_reliable_states = (1 << 2) | (1 << 1); /* C2, C1 */ | ||
309 | #endif | ||
310 | 301 | ||
311 | default: | 302 | default: |
312 | pr_debug(PREFIX "does not run on family %d model %d\n", | 303 | pr_debug(PREFIX "does not run on family %d model %d\n", |
@@ -314,6 +305,9 @@ static int intel_idle_probe(void) | |||
314 | return -ENODEV; | 305 | return -ENODEV; |
315 | } | 306 | } |
316 | 307 | ||
308 | if (boot_cpu_has(X86_FEATURE_ARAT)) /* Always Reliable APIC Timer */ | ||
309 | lapic_timer_reliable_states = 0xFFFFFFFF; | ||
310 | |||
317 | pr_debug(PREFIX "v" INTEL_IDLE_VERSION | 311 | pr_debug(PREFIX "v" INTEL_IDLE_VERSION |
318 | " model 0x%X\n", boot_cpu_data.x86_model); | 312 | " model 0x%X\n", boot_cpu_data.x86_model); |
319 | 313 | ||
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c index b342248aec05..c42699285f8e 100644 --- a/drivers/infiniband/core/uverbs_cmd.c +++ b/drivers/infiniband/core/uverbs_cmd.c | |||
@@ -893,68 +893,81 @@ out: | |||
893 | return ret ? ret : in_len; | 893 | return ret ? ret : in_len; |
894 | } | 894 | } |
895 | 895 | ||
896 | static int copy_wc_to_user(void __user *dest, struct ib_wc *wc) | ||
897 | { | ||
898 | struct ib_uverbs_wc tmp; | ||
899 | |||
900 | tmp.wr_id = wc->wr_id; | ||
901 | tmp.status = wc->status; | ||
902 | tmp.opcode = wc->opcode; | ||
903 | tmp.vendor_err = wc->vendor_err; | ||
904 | tmp.byte_len = wc->byte_len; | ||
905 | tmp.ex.imm_data = (__u32 __force) wc->ex.imm_data; | ||
906 | tmp.qp_num = wc->qp->qp_num; | ||
907 | tmp.src_qp = wc->src_qp; | ||
908 | tmp.wc_flags = wc->wc_flags; | ||
909 | tmp.pkey_index = wc->pkey_index; | ||
910 | tmp.slid = wc->slid; | ||
911 | tmp.sl = wc->sl; | ||
912 | tmp.dlid_path_bits = wc->dlid_path_bits; | ||
913 | tmp.port_num = wc->port_num; | ||
914 | tmp.reserved = 0; | ||
915 | |||
916 | if (copy_to_user(dest, &tmp, sizeof tmp)) | ||
917 | return -EFAULT; | ||
918 | |||
919 | return 0; | ||
920 | } | ||
921 | |||
896 | ssize_t ib_uverbs_poll_cq(struct ib_uverbs_file *file, | 922 | ssize_t ib_uverbs_poll_cq(struct ib_uverbs_file *file, |
897 | const char __user *buf, int in_len, | 923 | const char __user *buf, int in_len, |
898 | int out_len) | 924 | int out_len) |
899 | { | 925 | { |
900 | struct ib_uverbs_poll_cq cmd; | 926 | struct ib_uverbs_poll_cq cmd; |
901 | struct ib_uverbs_poll_cq_resp *resp; | 927 | struct ib_uverbs_poll_cq_resp resp; |
928 | u8 __user *header_ptr; | ||
929 | u8 __user *data_ptr; | ||
902 | struct ib_cq *cq; | 930 | struct ib_cq *cq; |
903 | struct ib_wc *wc; | 931 | struct ib_wc wc; |
904 | int ret = 0; | 932 | int ret; |
905 | int i; | ||
906 | int rsize; | ||
907 | 933 | ||
908 | if (copy_from_user(&cmd, buf, sizeof cmd)) | 934 | if (copy_from_user(&cmd, buf, sizeof cmd)) |
909 | return -EFAULT; | 935 | return -EFAULT; |
910 | 936 | ||
911 | wc = kmalloc(cmd.ne * sizeof *wc, GFP_KERNEL); | ||
912 | if (!wc) | ||
913 | return -ENOMEM; | ||
914 | |||
915 | rsize = sizeof *resp + cmd.ne * sizeof(struct ib_uverbs_wc); | ||
916 | resp = kmalloc(rsize, GFP_KERNEL); | ||
917 | if (!resp) { | ||
918 | ret = -ENOMEM; | ||
919 | goto out_wc; | ||
920 | } | ||
921 | |||
922 | cq = idr_read_cq(cmd.cq_handle, file->ucontext, 0); | 937 | cq = idr_read_cq(cmd.cq_handle, file->ucontext, 0); |
923 | if (!cq) { | 938 | if (!cq) |
924 | ret = -EINVAL; | 939 | return -EINVAL; |
925 | goto out; | ||
926 | } | ||
927 | 940 | ||
928 | resp->count = ib_poll_cq(cq, cmd.ne, wc); | 941 | /* we copy a struct ib_uverbs_poll_cq_resp to user space */ |
942 | header_ptr = (void __user *)(unsigned long) cmd.response; | ||
943 | data_ptr = header_ptr + sizeof resp; | ||
929 | 944 | ||
930 | put_cq_read(cq); | 945 | memset(&resp, 0, sizeof resp); |
946 | while (resp.count < cmd.ne) { | ||
947 | ret = ib_poll_cq(cq, 1, &wc); | ||
948 | if (ret < 0) | ||
949 | goto out_put; | ||
950 | if (!ret) | ||
951 | break; | ||
952 | |||
953 | ret = copy_wc_to_user(data_ptr, &wc); | ||
954 | if (ret) | ||
955 | goto out_put; | ||
931 | 956 | ||
932 | for (i = 0; i < resp->count; i++) { | 957 | data_ptr += sizeof(struct ib_uverbs_wc); |
933 | resp->wc[i].wr_id = wc[i].wr_id; | 958 | ++resp.count; |
934 | resp->wc[i].status = wc[i].status; | ||
935 | resp->wc[i].opcode = wc[i].opcode; | ||
936 | resp->wc[i].vendor_err = wc[i].vendor_err; | ||
937 | resp->wc[i].byte_len = wc[i].byte_len; | ||
938 | resp->wc[i].ex.imm_data = (__u32 __force) wc[i].ex.imm_data; | ||
939 | resp->wc[i].qp_num = wc[i].qp->qp_num; | ||
940 | resp->wc[i].src_qp = wc[i].src_qp; | ||
941 | resp->wc[i].wc_flags = wc[i].wc_flags; | ||
942 | resp->wc[i].pkey_index = wc[i].pkey_index; | ||
943 | resp->wc[i].slid = wc[i].slid; | ||
944 | resp->wc[i].sl = wc[i].sl; | ||
945 | resp->wc[i].dlid_path_bits = wc[i].dlid_path_bits; | ||
946 | resp->wc[i].port_num = wc[i].port_num; | ||
947 | } | 959 | } |
948 | 960 | ||
949 | if (copy_to_user((void __user *) (unsigned long) cmd.response, resp, rsize)) | 961 | if (copy_to_user(header_ptr, &resp, sizeof resp)) { |
950 | ret = -EFAULT; | 962 | ret = -EFAULT; |
963 | goto out_put; | ||
964 | } | ||
951 | 965 | ||
952 | out: | 966 | ret = in_len; |
953 | kfree(resp); | ||
954 | 967 | ||
955 | out_wc: | 968 | out_put: |
956 | kfree(wc); | 969 | put_cq_read(cq); |
957 | return ret ? ret : in_len; | 970 | return ret; |
958 | } | 971 | } |
959 | 972 | ||
960 | ssize_t ib_uverbs_req_notify_cq(struct ib_uverbs_file *file, | 973 | ssize_t ib_uverbs_req_notify_cq(struct ib_uverbs_file *file, |
diff --git a/drivers/input/joystick/turbografx.c b/drivers/input/joystick/turbografx.c index d53b9e900234..27b6a3ce18ca 100644 --- a/drivers/input/joystick/turbografx.c +++ b/drivers/input/joystick/turbografx.c | |||
@@ -245,6 +245,7 @@ static struct tgfx __init *tgfx_probe(int parport, int *n_buttons, int n_devs) | |||
245 | goto err_free_tgfx; | 245 | goto err_free_tgfx; |
246 | } | 246 | } |
247 | 247 | ||
248 | parport_put_port(pp); | ||
248 | return tgfx; | 249 | return tgfx; |
249 | 250 | ||
250 | err_free_dev: | 251 | err_free_dev: |
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index b8c51b9781db..c76bd3183beb 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig | |||
@@ -179,6 +179,22 @@ config KEYBOARD_GPIO | |||
179 | To compile this driver as a module, choose M here: the | 179 | To compile this driver as a module, choose M here: the |
180 | module will be called gpio_keys. | 180 | module will be called gpio_keys. |
181 | 181 | ||
182 | config KEYBOARD_GPIO_POLLED | ||
183 | tristate "Polled GPIO buttons" | ||
184 | depends on GENERIC_GPIO | ||
185 | select INPUT_POLLDEV | ||
186 | help | ||
187 | This driver implements support for buttons connected | ||
188 | to GPIO pins that are not capable of generating interrupts. | ||
189 | |||
190 | Say Y here if your device has buttons connected | ||
191 | directly to such GPIO pins. Your board-specific | ||
192 | setup logic must also provide a platform device, | ||
193 | with configuration data saying which GPIOs are used. | ||
194 | |||
195 | To compile this driver as a module, choose M here: the | ||
196 | module will be called gpio_keys_polled. | ||
197 | |||
182 | config KEYBOARD_TCA6416 | 198 | config KEYBOARD_TCA6416 |
183 | tristate "TCA6416 Keypad Support" | 199 | tristate "TCA6416 Keypad Support" |
184 | depends on I2C | 200 | depends on I2C |
@@ -443,6 +459,16 @@ config KEYBOARD_OMAP4 | |||
443 | To compile this driver as a module, choose M here: the | 459 | To compile this driver as a module, choose M here: the |
444 | module will be called omap4-keypad. | 460 | module will be called omap4-keypad. |
445 | 461 | ||
462 | config KEYBOARD_TC3589X | ||
463 | tristate "TC3589X Keypad support" | ||
464 | depends on MFD_TC3589X | ||
465 | help | ||
466 | Say Y here if you want to use the keypad controller on | ||
467 | TC35892/3 I/O expander. | ||
468 | |||
469 | To compile this driver as a module, choose M here: the | ||
470 | module will be called tc3589x-keypad. | ||
471 | |||
446 | config KEYBOARD_TNETV107X | 472 | config KEYBOARD_TNETV107X |
447 | tristate "TI TNETV107X keypad support" | 473 | tristate "TI TNETV107X keypad support" |
448 | depends on ARCH_DAVINCI_TNETV107X | 474 | depends on ARCH_DAVINCI_TNETV107X |
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile index a34452e8ebe2..2aa6ce248b71 100644 --- a/drivers/input/keyboard/Makefile +++ b/drivers/input/keyboard/Makefile | |||
@@ -14,6 +14,7 @@ obj-$(CONFIG_KEYBOARD_BFIN) += bf54x-keys.o | |||
14 | obj-$(CONFIG_KEYBOARD_DAVINCI) += davinci_keyscan.o | 14 | obj-$(CONFIG_KEYBOARD_DAVINCI) += davinci_keyscan.o |
15 | obj-$(CONFIG_KEYBOARD_EP93XX) += ep93xx_keypad.o | 15 | obj-$(CONFIG_KEYBOARD_EP93XX) += ep93xx_keypad.o |
16 | obj-$(CONFIG_KEYBOARD_GPIO) += gpio_keys.o | 16 | obj-$(CONFIG_KEYBOARD_GPIO) += gpio_keys.o |
17 | obj-$(CONFIG_KEYBOARD_GPIO_POLLED) += gpio_keys_polled.o | ||
17 | obj-$(CONFIG_KEYBOARD_TCA6416) += tca6416-keypad.o | 18 | obj-$(CONFIG_KEYBOARD_TCA6416) += tca6416-keypad.o |
18 | obj-$(CONFIG_KEYBOARD_HIL) += hil_kbd.o | 19 | obj-$(CONFIG_KEYBOARD_HIL) += hil_kbd.o |
19 | obj-$(CONFIG_KEYBOARD_HIL_OLD) += hilkbd.o | 20 | obj-$(CONFIG_KEYBOARD_HIL_OLD) += hilkbd.o |
@@ -40,6 +41,7 @@ obj-$(CONFIG_KEYBOARD_SH_KEYSC) += sh_keysc.o | |||
40 | obj-$(CONFIG_KEYBOARD_STMPE) += stmpe-keypad.o | 41 | obj-$(CONFIG_KEYBOARD_STMPE) += stmpe-keypad.o |
41 | obj-$(CONFIG_KEYBOARD_STOWAWAY) += stowaway.o | 42 | obj-$(CONFIG_KEYBOARD_STOWAWAY) += stowaway.o |
42 | obj-$(CONFIG_KEYBOARD_SUNKBD) += sunkbd.o | 43 | obj-$(CONFIG_KEYBOARD_SUNKBD) += sunkbd.o |
44 | obj-$(CONFIG_KEYBOARD_TC3589X) += tc3589x-keypad.o | ||
43 | obj-$(CONFIG_KEYBOARD_TNETV107X) += tnetv107x-keypad.o | 45 | obj-$(CONFIG_KEYBOARD_TNETV107X) += tnetv107x-keypad.o |
44 | obj-$(CONFIG_KEYBOARD_TWL4030) += twl4030_keypad.o | 46 | obj-$(CONFIG_KEYBOARD_TWL4030) += twl4030_keypad.o |
45 | obj-$(CONFIG_KEYBOARD_XTKBD) += xtkbd.o | 47 | obj-$(CONFIG_KEYBOARD_XTKBD) += xtkbd.o |
diff --git a/drivers/input/keyboard/gpio_keys_polled.c b/drivers/input/keyboard/gpio_keys_polled.c new file mode 100644 index 000000000000..4c17aff20657 --- /dev/null +++ b/drivers/input/keyboard/gpio_keys_polled.c | |||
@@ -0,0 +1,261 @@ | |||
1 | /* | ||
2 | * Driver for buttons on GPIO lines not capable of generating interrupts | ||
3 | * | ||
4 | * Copyright (C) 2007-2010 Gabor Juhos <juhosg@openwrt.org> | ||
5 | * Copyright (C) 2010 Nuno Goncalves <nunojpg@gmail.com> | ||
6 | * | ||
7 | * This file was based on: /drivers/input/misc/cobalt_btns.c | ||
8 | * Copyright (C) 2007 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp> | ||
9 | * | ||
10 | * also was based on: /drivers/input/keyboard/gpio_keys.c | ||
11 | * Copyright 2005 Phil Blundell | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or modify | ||
14 | * it under the terms of the GNU General Public License version 2 as | ||
15 | * published by the Free Software Foundation. | ||
16 | */ | ||
17 | |||
18 | #include <linux/kernel.h> | ||
19 | #include <linux/module.h> | ||
20 | #include <linux/init.h> | ||
21 | #include <linux/slab.h> | ||
22 | #include <linux/input.h> | ||
23 | #include <linux/input-polldev.h> | ||
24 | #include <linux/ioport.h> | ||
25 | #include <linux/platform_device.h> | ||
26 | #include <linux/gpio.h> | ||
27 | #include <linux/gpio_keys.h> | ||
28 | |||
29 | #define DRV_NAME "gpio-keys-polled" | ||
30 | |||
31 | struct gpio_keys_button_data { | ||
32 | int last_state; | ||
33 | int count; | ||
34 | int threshold; | ||
35 | int can_sleep; | ||
36 | }; | ||
37 | |||
38 | struct gpio_keys_polled_dev { | ||
39 | struct input_polled_dev *poll_dev; | ||
40 | struct device *dev; | ||
41 | struct gpio_keys_platform_data *pdata; | ||
42 | struct gpio_keys_button_data data[0]; | ||
43 | }; | ||
44 | |||
45 | static void gpio_keys_polled_check_state(struct input_dev *input, | ||
46 | struct gpio_keys_button *button, | ||
47 | struct gpio_keys_button_data *bdata) | ||
48 | { | ||
49 | int state; | ||
50 | |||
51 | if (bdata->can_sleep) | ||
52 | state = !!gpio_get_value_cansleep(button->gpio); | ||
53 | else | ||
54 | state = !!gpio_get_value(button->gpio); | ||
55 | |||
56 | if (state != bdata->last_state) { | ||
57 | unsigned int type = button->type ?: EV_KEY; | ||
58 | |||
59 | input_event(input, type, button->code, | ||
60 | !!(state ^ button->active_low)); | ||
61 | input_sync(input); | ||
62 | bdata->count = 0; | ||
63 | bdata->last_state = state; | ||
64 | } | ||
65 | } | ||
66 | |||
67 | static void gpio_keys_polled_poll(struct input_polled_dev *dev) | ||
68 | { | ||
69 | struct gpio_keys_polled_dev *bdev = dev->private; | ||
70 | struct gpio_keys_platform_data *pdata = bdev->pdata; | ||
71 | struct input_dev *input = dev->input; | ||
72 | int i; | ||
73 | |||
74 | for (i = 0; i < bdev->pdata->nbuttons; i++) { | ||
75 | struct gpio_keys_button_data *bdata = &bdev->data[i]; | ||
76 | |||
77 | if (bdata->count < bdata->threshold) | ||
78 | bdata->count++; | ||
79 | else | ||
80 | gpio_keys_polled_check_state(input, &pdata->buttons[i], | ||
81 | bdata); | ||
82 | } | ||
83 | } | ||
84 | |||
85 | static void gpio_keys_polled_open(struct input_polled_dev *dev) | ||
86 | { | ||
87 | struct gpio_keys_polled_dev *bdev = dev->private; | ||
88 | struct gpio_keys_platform_data *pdata = bdev->pdata; | ||
89 | |||
90 | if (pdata->enable) | ||
91 | pdata->enable(bdev->dev); | ||
92 | } | ||
93 | |||
94 | static void gpio_keys_polled_close(struct input_polled_dev *dev) | ||
95 | { | ||
96 | struct gpio_keys_polled_dev *bdev = dev->private; | ||
97 | struct gpio_keys_platform_data *pdata = bdev->pdata; | ||
98 | |||
99 | if (pdata->disable) | ||
100 | pdata->disable(bdev->dev); | ||
101 | } | ||
102 | |||
103 | static int __devinit gpio_keys_polled_probe(struct platform_device *pdev) | ||
104 | { | ||
105 | struct gpio_keys_platform_data *pdata = pdev->dev.platform_data; | ||
106 | struct device *dev = &pdev->dev; | ||
107 | struct gpio_keys_polled_dev *bdev; | ||
108 | struct input_polled_dev *poll_dev; | ||
109 | struct input_dev *input; | ||
110 | int error; | ||
111 | int i; | ||
112 | |||
113 | if (!pdata || !pdata->poll_interval) | ||
114 | return -EINVAL; | ||
115 | |||
116 | bdev = kzalloc(sizeof(struct gpio_keys_polled_dev) + | ||
117 | pdata->nbuttons * sizeof(struct gpio_keys_button_data), | ||
118 | GFP_KERNEL); | ||
119 | if (!bdev) { | ||
120 | dev_err(dev, "no memory for private data\n"); | ||
121 | return -ENOMEM; | ||
122 | } | ||
123 | |||
124 | poll_dev = input_allocate_polled_device(); | ||
125 | if (!poll_dev) { | ||
126 | dev_err(dev, "no memory for polled device\n"); | ||
127 | error = -ENOMEM; | ||
128 | goto err_free_bdev; | ||
129 | } | ||
130 | |||
131 | poll_dev->private = bdev; | ||
132 | poll_dev->poll = gpio_keys_polled_poll; | ||
133 | poll_dev->poll_interval = pdata->poll_interval; | ||
134 | poll_dev->open = gpio_keys_polled_open; | ||
135 | poll_dev->close = gpio_keys_polled_close; | ||
136 | |||
137 | input = poll_dev->input; | ||
138 | |||
139 | input->evbit[0] = BIT(EV_KEY); | ||
140 | input->name = pdev->name; | ||
141 | input->phys = DRV_NAME"/input0"; | ||
142 | input->dev.parent = &pdev->dev; | ||
143 | |||
144 | input->id.bustype = BUS_HOST; | ||
145 | input->id.vendor = 0x0001; | ||
146 | input->id.product = 0x0001; | ||
147 | input->id.version = 0x0100; | ||
148 | |||
149 | for (i = 0; i < pdata->nbuttons; i++) { | ||
150 | struct gpio_keys_button *button = &pdata->buttons[i]; | ||
151 | struct gpio_keys_button_data *bdata = &bdev->data[i]; | ||
152 | unsigned int gpio = button->gpio; | ||
153 | unsigned int type = button->type ?: EV_KEY; | ||
154 | |||
155 | if (button->wakeup) { | ||
156 | dev_err(dev, DRV_NAME " does not support wakeup\n"); | ||
157 | error = -EINVAL; | ||
158 | goto err_free_gpio; | ||
159 | } | ||
160 | |||
161 | error = gpio_request(gpio, | ||
162 | button->desc ? button->desc : DRV_NAME); | ||
163 | if (error) { | ||
164 | dev_err(dev, "unable to claim gpio %u, err=%d\n", | ||
165 | gpio, error); | ||
166 | goto err_free_gpio; | ||
167 | } | ||
168 | |||
169 | error = gpio_direction_input(gpio); | ||
170 | if (error) { | ||
171 | dev_err(dev, | ||
172 | "unable to set direction on gpio %u, err=%d\n", | ||
173 | gpio, error); | ||
174 | goto err_free_gpio; | ||
175 | } | ||
176 | |||
177 | bdata->can_sleep = gpio_cansleep(gpio); | ||
178 | bdata->last_state = -1; | ||
179 | bdata->threshold = DIV_ROUND_UP(button->debounce_interval, | ||
180 | pdata->poll_interval); | ||
181 | |||
182 | input_set_capability(input, type, button->code); | ||
183 | } | ||
184 | |||
185 | bdev->poll_dev = poll_dev; | ||
186 | bdev->dev = dev; | ||
187 | bdev->pdata = pdata; | ||
188 | platform_set_drvdata(pdev, bdev); | ||
189 | |||
190 | error = input_register_polled_device(poll_dev); | ||
191 | if (error) { | ||
192 | dev_err(dev, "unable to register polled device, err=%d\n", | ||
193 | error); | ||
194 | goto err_free_gpio; | ||
195 | } | ||
196 | |||
197 | /* report initial state of the buttons */ | ||
198 | for (i = 0; i < pdata->nbuttons; i++) | ||
199 | gpio_keys_polled_check_state(input, &pdata->buttons[i], | ||
200 | &bdev->data[i]); | ||
201 | |||
202 | return 0; | ||
203 | |||
204 | err_free_gpio: | ||
205 | while (--i >= 0) | ||
206 | gpio_free(pdata->buttons[i].gpio); | ||
207 | |||
208 | input_free_polled_device(poll_dev); | ||
209 | |||
210 | err_free_bdev: | ||
211 | kfree(bdev); | ||
212 | |||
213 | platform_set_drvdata(pdev, NULL); | ||
214 | return error; | ||
215 | } | ||
216 | |||
217 | static int __devexit gpio_keys_polled_remove(struct platform_device *pdev) | ||
218 | { | ||
219 | struct gpio_keys_polled_dev *bdev = platform_get_drvdata(pdev); | ||
220 | struct gpio_keys_platform_data *pdata = bdev->pdata; | ||
221 | int i; | ||
222 | |||
223 | input_unregister_polled_device(bdev->poll_dev); | ||
224 | |||
225 | for (i = 0; i < pdata->nbuttons; i++) | ||
226 | gpio_free(pdata->buttons[i].gpio); | ||
227 | |||
228 | input_free_polled_device(bdev->poll_dev); | ||
229 | |||
230 | kfree(bdev); | ||
231 | platform_set_drvdata(pdev, NULL); | ||
232 | |||
233 | return 0; | ||
234 | } | ||
235 | |||
236 | static struct platform_driver gpio_keys_polled_driver = { | ||
237 | .probe = gpio_keys_polled_probe, | ||
238 | .remove = __devexit_p(gpio_keys_polled_remove), | ||
239 | .driver = { | ||
240 | .name = DRV_NAME, | ||
241 | .owner = THIS_MODULE, | ||
242 | }, | ||
243 | }; | ||
244 | |||
245 | static int __init gpio_keys_polled_init(void) | ||
246 | { | ||
247 | return platform_driver_register(&gpio_keys_polled_driver); | ||
248 | } | ||
249 | |||
250 | static void __exit gpio_keys_polled_exit(void) | ||
251 | { | ||
252 | platform_driver_unregister(&gpio_keys_polled_driver); | ||
253 | } | ||
254 | |||
255 | module_init(gpio_keys_polled_init); | ||
256 | module_exit(gpio_keys_polled_exit); | ||
257 | |||
258 | MODULE_LICENSE("GPL v2"); | ||
259 | MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>"); | ||
260 | MODULE_DESCRIPTION("Polled GPIO Buttons driver"); | ||
261 | MODULE_ALIAS("platform:" DRV_NAME); | ||
diff --git a/drivers/input/keyboard/tc3589x-keypad.c b/drivers/input/keyboard/tc3589x-keypad.c new file mode 100644 index 000000000000..69dc0cb20a00 --- /dev/null +++ b/drivers/input/keyboard/tc3589x-keypad.c | |||
@@ -0,0 +1,472 @@ | |||
1 | /* | ||
2 | * Copyright (C) ST-Ericsson SA 2010 | ||
3 | * | ||
4 | * Author: Jayeeta Banerjee <jayeeta.banerjee@stericsson.com> | ||
5 | * Author: Sundar Iyer <sundar.iyer@stericsson.com> | ||
6 | * | ||
7 | * License Terms: GNU General Public License, version 2 | ||
8 | * | ||
9 | * TC35893 MFD Keypad Controller driver | ||
10 | */ | ||
11 | |||
12 | #include <linux/module.h> | ||
13 | #include <linux/init.h> | ||
14 | #include <linux/interrupt.h> | ||
15 | #include <linux/input.h> | ||
16 | #include <linux/platform_device.h> | ||
17 | #include <linux/input/matrix_keypad.h> | ||
18 | #include <linux/i2c.h> | ||
19 | #include <linux/slab.h> | ||
20 | #include <linux/mfd/tc3589x.h> | ||
21 | |||
22 | /* Maximum supported keypad matrix row/columns size */ | ||
23 | #define TC3589x_MAX_KPROW 8 | ||
24 | #define TC3589x_MAX_KPCOL 12 | ||
25 | |||
26 | /* keypad related Constants */ | ||
27 | #define TC3589x_MAX_DEBOUNCE_SETTLE 0xFF | ||
28 | #define DEDICATED_KEY_VAL 0xFF | ||
29 | |||
30 | /* Pull up/down masks */ | ||
31 | #define TC3589x_NO_PULL_MASK 0x0 | ||
32 | #define TC3589x_PULL_DOWN_MASK 0x1 | ||
33 | #define TC3589x_PULL_UP_MASK 0x2 | ||
34 | #define TC3589x_PULLUP_ALL_MASK 0xAA | ||
35 | #define TC3589x_IO_PULL_VAL(index, mask) ((mask)<<((index)%4)*2)) | ||
36 | |||
37 | /* Bit masks for IOCFG register */ | ||
38 | #define IOCFG_BALLCFG 0x01 | ||
39 | #define IOCFG_IG 0x08 | ||
40 | |||
41 | #define KP_EVCODE_COL_MASK 0x0F | ||
42 | #define KP_EVCODE_ROW_MASK 0x70 | ||
43 | #define KP_RELEASE_EVT_MASK 0x80 | ||
44 | |||
45 | #define KP_ROW_SHIFT 4 | ||
46 | |||
47 | #define KP_NO_VALID_KEY_MASK 0x7F | ||
48 | |||
49 | /* bit masks for RESTCTRL register */ | ||
50 | #define TC3589x_KBDRST 0x2 | ||
51 | #define TC3589x_IRQRST 0x10 | ||
52 | #define TC3589x_RESET_ALL 0x1B | ||
53 | |||
54 | /* KBDMFS register bit mask */ | ||
55 | #define TC3589x_KBDMFS_EN 0x1 | ||
56 | |||
57 | /* CLKEN register bitmask */ | ||
58 | #define KPD_CLK_EN 0x1 | ||
59 | |||
60 | /* RSTINTCLR register bit mask */ | ||
61 | #define IRQ_CLEAR 0x1 | ||
62 | |||
63 | /* bit masks for keyboard interrupts*/ | ||
64 | #define TC3589x_EVT_LOSS_INT 0x8 | ||
65 | #define TC3589x_EVT_INT 0x4 | ||
66 | #define TC3589x_KBD_LOSS_INT 0x2 | ||
67 | #define TC3589x_KBD_INT 0x1 | ||
68 | |||
69 | /* bit masks for keyboard interrupt clear*/ | ||
70 | #define TC3589x_EVT_INT_CLR 0x2 | ||
71 | #define TC3589x_KBD_INT_CLR 0x1 | ||
72 | |||
73 | #define TC3589x_KBD_KEYMAP_SIZE 64 | ||
74 | |||
75 | /** | ||
76 | * struct tc_keypad - data structure used by keypad driver | ||
77 | * @input: pointer to input device object | ||
78 | * @board: keypad platform device | ||
79 | * @krow: number of rows | ||
80 | * @kcol: number of coloumns | ||
81 | * @keymap: matrix scan code table for keycodes | ||
82 | */ | ||
83 | struct tc_keypad { | ||
84 | struct tc3589x *tc3589x; | ||
85 | struct input_dev *input; | ||
86 | const struct tc3589x_keypad_platform_data *board; | ||
87 | unsigned int krow; | ||
88 | unsigned int kcol; | ||
89 | unsigned short keymap[TC3589x_KBD_KEYMAP_SIZE]; | ||
90 | bool keypad_stopped; | ||
91 | }; | ||
92 | |||
93 | static int __devinit tc3589x_keypad_init_key_hardware(struct tc_keypad *keypad) | ||
94 | { | ||
95 | int ret; | ||
96 | struct tc3589x *tc3589x = keypad->tc3589x; | ||
97 | u8 settle_time = keypad->board->settle_time; | ||
98 | u8 dbounce_period = keypad->board->debounce_period; | ||
99 | u8 rows = keypad->board->krow & 0xf; /* mask out the nibble */ | ||
100 | u8 column = keypad->board->kcol & 0xf; /* mask out the nibble */ | ||
101 | |||
102 | /* validate platform configurations */ | ||
103 | if (keypad->board->kcol > TC3589x_MAX_KPCOL || | ||
104 | keypad->board->krow > TC3589x_MAX_KPROW || | ||
105 | keypad->board->debounce_period > TC3589x_MAX_DEBOUNCE_SETTLE || | ||
106 | keypad->board->settle_time > TC3589x_MAX_DEBOUNCE_SETTLE) | ||
107 | return -EINVAL; | ||
108 | |||
109 | /* configure KBDSIZE 4 LSbits for cols and 4 MSbits for rows */ | ||
110 | ret = tc3589x_reg_write(tc3589x, TC3589x_KBDSIZE, | ||
111 | (rows << KP_ROW_SHIFT) | column); | ||
112 | if (ret < 0) | ||
113 | return ret; | ||
114 | |||
115 | /* configure dedicated key config, no dedicated key selected */ | ||
116 | ret = tc3589x_reg_write(tc3589x, TC3589x_KBCFG_LSB, DEDICATED_KEY_VAL); | ||
117 | if (ret < 0) | ||
118 | return ret; | ||
119 | |||
120 | ret = tc3589x_reg_write(tc3589x, TC3589x_KBCFG_MSB, DEDICATED_KEY_VAL); | ||
121 | if (ret < 0) | ||
122 | return ret; | ||
123 | |||
124 | /* Configure settle time */ | ||
125 | ret = tc3589x_reg_write(tc3589x, TC3589x_KBDSETTLE_REG, settle_time); | ||
126 | if (ret < 0) | ||
127 | return ret; | ||
128 | |||
129 | /* Configure debounce time */ | ||
130 | ret = tc3589x_reg_write(tc3589x, TC3589x_KBDBOUNCE, dbounce_period); | ||
131 | if (ret < 0) | ||
132 | return ret; | ||
133 | |||
134 | /* Start of initialise keypad GPIOs */ | ||
135 | ret = tc3589x_set_bits(tc3589x, TC3589x_IOCFG, 0x0, IOCFG_IG); | ||
136 | if (ret < 0) | ||
137 | return ret; | ||
138 | |||
139 | /* Configure pull-up resistors for all row GPIOs */ | ||
140 | ret = tc3589x_reg_write(tc3589x, TC3589x_IOPULLCFG0_LSB, | ||
141 | TC3589x_PULLUP_ALL_MASK); | ||
142 | if (ret < 0) | ||
143 | return ret; | ||
144 | |||
145 | ret = tc3589x_reg_write(tc3589x, TC3589x_IOPULLCFG0_MSB, | ||
146 | TC3589x_PULLUP_ALL_MASK); | ||
147 | if (ret < 0) | ||
148 | return ret; | ||
149 | |||
150 | /* Configure pull-up resistors for all column GPIOs */ | ||
151 | ret = tc3589x_reg_write(tc3589x, TC3589x_IOPULLCFG1_LSB, | ||
152 | TC3589x_PULLUP_ALL_MASK); | ||
153 | if (ret < 0) | ||
154 | return ret; | ||
155 | |||
156 | ret = tc3589x_reg_write(tc3589x, TC3589x_IOPULLCFG1_MSB, | ||
157 | TC3589x_PULLUP_ALL_MASK); | ||
158 | if (ret < 0) | ||
159 | return ret; | ||
160 | |||
161 | ret = tc3589x_reg_write(tc3589x, TC3589x_IOPULLCFG2_LSB, | ||
162 | TC3589x_PULLUP_ALL_MASK); | ||
163 | |||
164 | return ret; | ||
165 | } | ||
166 | |||
167 | #define TC35893_DATA_REGS 4 | ||
168 | #define TC35893_KEYCODE_FIFO_EMPTY 0x7f | ||
169 | #define TC35893_KEYCODE_FIFO_CLEAR 0xff | ||
170 | #define TC35893_KEYPAD_ROW_SHIFT 0x3 | ||
171 | |||
172 | static irqreturn_t tc3589x_keypad_irq(int irq, void *dev) | ||
173 | { | ||
174 | struct tc_keypad *keypad = dev; | ||
175 | struct tc3589x *tc3589x = keypad->tc3589x; | ||
176 | u8 i, row_index, col_index, kbd_code, up; | ||
177 | u8 code; | ||
178 | |||
179 | for (i = 0; i < TC35893_DATA_REGS * 2; i++) { | ||
180 | kbd_code = tc3589x_reg_read(tc3589x, TC3589x_EVTCODE_FIFO); | ||
181 | |||
182 | /* loop till fifo is empty and no more keys are pressed */ | ||
183 | if (kbd_code == TC35893_KEYCODE_FIFO_EMPTY || | ||
184 | kbd_code == TC35893_KEYCODE_FIFO_CLEAR) | ||
185 | continue; | ||
186 | |||
187 | /* valid key is found */ | ||
188 | col_index = kbd_code & KP_EVCODE_COL_MASK; | ||
189 | row_index = (kbd_code & KP_EVCODE_ROW_MASK) >> KP_ROW_SHIFT; | ||
190 | code = MATRIX_SCAN_CODE(row_index, col_index, | ||
191 | TC35893_KEYPAD_ROW_SHIFT); | ||
192 | up = kbd_code & KP_RELEASE_EVT_MASK; | ||
193 | |||
194 | input_event(keypad->input, EV_MSC, MSC_SCAN, code); | ||
195 | input_report_key(keypad->input, keypad->keymap[code], !up); | ||
196 | input_sync(keypad->input); | ||
197 | } | ||
198 | |||
199 | /* clear IRQ */ | ||
200 | tc3589x_set_bits(tc3589x, TC3589x_KBDIC, | ||
201 | 0x0, TC3589x_EVT_INT_CLR | TC3589x_KBD_INT_CLR); | ||
202 | /* enable IRQ */ | ||
203 | tc3589x_set_bits(tc3589x, TC3589x_KBDMSK, | ||
204 | 0x0, TC3589x_EVT_LOSS_INT | TC3589x_EVT_INT); | ||
205 | |||
206 | return IRQ_HANDLED; | ||
207 | } | ||
208 | |||
209 | static int tc3589x_keypad_enable(struct tc_keypad *keypad) | ||
210 | { | ||
211 | struct tc3589x *tc3589x = keypad->tc3589x; | ||
212 | int ret; | ||
213 | |||
214 | /* pull the keypad module out of reset */ | ||
215 | ret = tc3589x_set_bits(tc3589x, TC3589x_RSTCTRL, TC3589x_KBDRST, 0x0); | ||
216 | if (ret < 0) | ||
217 | return ret; | ||
218 | |||
219 | /* configure KBDMFS */ | ||
220 | ret = tc3589x_set_bits(tc3589x, TC3589x_KBDMFS, 0x0, TC3589x_KBDMFS_EN); | ||
221 | if (ret < 0) | ||
222 | return ret; | ||
223 | |||
224 | /* enable the keypad clock */ | ||
225 | ret = tc3589x_set_bits(tc3589x, TC3589x_CLKEN, 0x0, KPD_CLK_EN); | ||
226 | if (ret < 0) | ||
227 | return ret; | ||
228 | |||
229 | /* clear pending IRQs */ | ||
230 | ret = tc3589x_set_bits(tc3589x, TC3589x_RSTINTCLR, 0x0, 0x1); | ||
231 | if (ret < 0) | ||
232 | return ret; | ||
233 | |||
234 | /* enable the IRQs */ | ||
235 | ret = tc3589x_set_bits(tc3589x, TC3589x_KBDMSK, 0x0, | ||
236 | TC3589x_EVT_LOSS_INT | TC3589x_EVT_INT); | ||
237 | if (ret < 0) | ||
238 | return ret; | ||
239 | |||
240 | keypad->keypad_stopped = false; | ||
241 | |||
242 | return ret; | ||
243 | } | ||
244 | |||
245 | static int tc3589x_keypad_disable(struct tc_keypad *keypad) | ||
246 | { | ||
247 | struct tc3589x *tc3589x = keypad->tc3589x; | ||
248 | int ret; | ||
249 | |||
250 | /* clear IRQ */ | ||
251 | ret = tc3589x_set_bits(tc3589x, TC3589x_KBDIC, | ||
252 | 0x0, TC3589x_EVT_INT_CLR | TC3589x_KBD_INT_CLR); | ||
253 | if (ret < 0) | ||
254 | return ret; | ||
255 | |||
256 | /* disable all interrupts */ | ||
257 | ret = tc3589x_set_bits(tc3589x, TC3589x_KBDMSK, | ||
258 | ~(TC3589x_EVT_LOSS_INT | TC3589x_EVT_INT), 0x0); | ||
259 | if (ret < 0) | ||
260 | return ret; | ||
261 | |||
262 | /* disable the keypad module */ | ||
263 | ret = tc3589x_set_bits(tc3589x, TC3589x_CLKEN, 0x1, 0x0); | ||
264 | if (ret < 0) | ||
265 | return ret; | ||
266 | |||
267 | /* put the keypad module into reset */ | ||
268 | ret = tc3589x_set_bits(tc3589x, TC3589x_RSTCTRL, TC3589x_KBDRST, 0x1); | ||
269 | |||
270 | keypad->keypad_stopped = true; | ||
271 | |||
272 | return ret; | ||
273 | } | ||
274 | |||
275 | static int tc3589x_keypad_open(struct input_dev *input) | ||
276 | { | ||
277 | int error; | ||
278 | struct tc_keypad *keypad = input_get_drvdata(input); | ||
279 | |||
280 | /* enable the keypad module */ | ||
281 | error = tc3589x_keypad_enable(keypad); | ||
282 | if (error < 0) { | ||
283 | dev_err(&input->dev, "failed to enable keypad module\n"); | ||
284 | return error; | ||
285 | } | ||
286 | |||
287 | error = tc3589x_keypad_init_key_hardware(keypad); | ||
288 | if (error < 0) { | ||
289 | dev_err(&input->dev, "failed to configure keypad module\n"); | ||
290 | return error; | ||
291 | } | ||
292 | |||
293 | return 0; | ||
294 | } | ||
295 | |||
296 | static void tc3589x_keypad_close(struct input_dev *input) | ||
297 | { | ||
298 | struct tc_keypad *keypad = input_get_drvdata(input); | ||
299 | |||
300 | /* disable the keypad module */ | ||
301 | tc3589x_keypad_disable(keypad); | ||
302 | } | ||
303 | |||
304 | static int __devinit tc3589x_keypad_probe(struct platform_device *pdev) | ||
305 | { | ||
306 | struct tc3589x *tc3589x = dev_get_drvdata(pdev->dev.parent); | ||
307 | struct tc_keypad *keypad; | ||
308 | struct input_dev *input; | ||
309 | const struct tc3589x_keypad_platform_data *plat; | ||
310 | int error, irq; | ||
311 | |||
312 | plat = tc3589x->pdata->keypad; | ||
313 | if (!plat) { | ||
314 | dev_err(&pdev->dev, "invalid keypad platform data\n"); | ||
315 | return -EINVAL; | ||
316 | } | ||
317 | |||
318 | irq = platform_get_irq(pdev, 0); | ||
319 | if (irq < 0) | ||
320 | return irq; | ||
321 | |||
322 | keypad = kzalloc(sizeof(struct tc_keypad), GFP_KERNEL); | ||
323 | input = input_allocate_device(); | ||
324 | if (!keypad || !input) { | ||
325 | dev_err(&pdev->dev, "failed to allocate keypad memory\n"); | ||
326 | error = -ENOMEM; | ||
327 | goto err_free_mem; | ||
328 | } | ||
329 | |||
330 | keypad->board = plat; | ||
331 | keypad->input = input; | ||
332 | keypad->tc3589x = tc3589x; | ||
333 | |||
334 | input->id.bustype = BUS_I2C; | ||
335 | input->name = pdev->name; | ||
336 | input->dev.parent = &pdev->dev; | ||
337 | |||
338 | input->keycode = keypad->keymap; | ||
339 | input->keycodesize = sizeof(keypad->keymap[0]); | ||
340 | input->keycodemax = ARRAY_SIZE(keypad->keymap); | ||
341 | |||
342 | input->open = tc3589x_keypad_open; | ||
343 | input->close = tc3589x_keypad_close; | ||
344 | |||
345 | input_set_drvdata(input, keypad); | ||
346 | |||
347 | input_set_capability(input, EV_MSC, MSC_SCAN); | ||
348 | |||
349 | __set_bit(EV_KEY, input->evbit); | ||
350 | if (!plat->no_autorepeat) | ||
351 | __set_bit(EV_REP, input->evbit); | ||
352 | |||
353 | matrix_keypad_build_keymap(plat->keymap_data, 0x3, | ||
354 | input->keycode, input->keybit); | ||
355 | |||
356 | error = request_threaded_irq(irq, NULL, | ||
357 | tc3589x_keypad_irq, plat->irqtype, | ||
358 | "tc3589x-keypad", keypad); | ||
359 | if (error < 0) { | ||
360 | dev_err(&pdev->dev, | ||
361 | "Could not allocate irq %d,error %d\n", | ||
362 | irq, error); | ||
363 | goto err_free_mem; | ||
364 | } | ||
365 | |||
366 | error = input_register_device(input); | ||
367 | if (error) { | ||
368 | dev_err(&pdev->dev, "Could not register input device\n"); | ||
369 | goto err_free_irq; | ||
370 | } | ||
371 | |||
372 | /* let platform decide if keypad is a wakeup source or not */ | ||
373 | device_init_wakeup(&pdev->dev, plat->enable_wakeup); | ||
374 | device_set_wakeup_capable(&pdev->dev, plat->enable_wakeup); | ||
375 | |||
376 | platform_set_drvdata(pdev, keypad); | ||
377 | |||
378 | return 0; | ||
379 | |||
380 | err_free_irq: | ||
381 | free_irq(irq, keypad); | ||
382 | err_free_mem: | ||
383 | input_free_device(input); | ||
384 | kfree(keypad); | ||
385 | return error; | ||
386 | } | ||
387 | |||
388 | static int __devexit tc3589x_keypad_remove(struct platform_device *pdev) | ||
389 | { | ||
390 | struct tc_keypad *keypad = platform_get_drvdata(pdev); | ||
391 | int irq = platform_get_irq(pdev, 0); | ||
392 | |||
393 | if (!keypad->keypad_stopped) | ||
394 | tc3589x_keypad_disable(keypad); | ||
395 | |||
396 | free_irq(irq, keypad); | ||
397 | |||
398 | input_unregister_device(keypad->input); | ||
399 | |||
400 | kfree(keypad); | ||
401 | |||
402 | return 0; | ||
403 | } | ||
404 | |||
405 | #ifdef CONFIG_PM | ||
406 | static int tc3589x_keypad_suspend(struct device *dev) | ||
407 | { | ||
408 | struct platform_device *pdev = to_platform_device(dev); | ||
409 | struct tc_keypad *keypad = platform_get_drvdata(pdev); | ||
410 | int irq = platform_get_irq(pdev, 0); | ||
411 | |||
412 | /* keypad is already off; we do nothing */ | ||
413 | if (keypad->keypad_stopped) | ||
414 | return 0; | ||
415 | |||
416 | /* if device is not a wakeup source, disable it for powersave */ | ||
417 | if (!device_may_wakeup(&pdev->dev)) | ||
418 | tc3589x_keypad_disable(keypad); | ||
419 | else | ||
420 | enable_irq_wake(irq); | ||
421 | |||
422 | return 0; | ||
423 | } | ||
424 | |||
425 | static int tc3589x_keypad_resume(struct device *dev) | ||
426 | { | ||
427 | struct platform_device *pdev = to_platform_device(dev); | ||
428 | struct tc_keypad *keypad = platform_get_drvdata(pdev); | ||
429 | int irq = platform_get_irq(pdev, 0); | ||
430 | |||
431 | if (!keypad->keypad_stopped) | ||
432 | return 0; | ||
433 | |||
434 | /* enable the device to resume normal operations */ | ||
435 | if (!device_may_wakeup(&pdev->dev)) | ||
436 | tc3589x_keypad_enable(keypad); | ||
437 | else | ||
438 | disable_irq_wake(irq); | ||
439 | |||
440 | return 0; | ||
441 | } | ||
442 | |||
443 | static const SIMPLE_DEV_PM_OPS(tc3589x_keypad_dev_pm_ops, | ||
444 | tc3589x_keypad_suspend, tc3589x_keypad_resume); | ||
445 | #endif | ||
446 | |||
447 | static struct platform_driver tc3589x_keypad_driver = { | ||
448 | .driver.name = "tc3589x-keypad", | ||
449 | .driver.owner = THIS_MODULE, | ||
450 | #ifdef CONFIG_PM | ||
451 | .driver.pm = &tc3589x_keypad_dev_pm_ops, | ||
452 | #endif | ||
453 | .probe = tc3589x_keypad_probe, | ||
454 | .remove = __devexit_p(tc3589x_keypad_remove), | ||
455 | }; | ||
456 | |||
457 | static int __init tc3589x_keypad_init(void) | ||
458 | { | ||
459 | return platform_driver_register(&tc3589x_keypad_driver); | ||
460 | } | ||
461 | module_init(tc3589x_keypad_init); | ||
462 | |||
463 | static void __exit tc3589x_keypad_exit(void) | ||
464 | { | ||
465 | return platform_driver_unregister(&tc3589x_keypad_driver); | ||
466 | } | ||
467 | module_exit(tc3589x_keypad_exit); | ||
468 | |||
469 | MODULE_LICENSE("GPL v2"); | ||
470 | MODULE_AUTHOR("Jayeeta Banerjee/Sundar Iyer"); | ||
471 | MODULE_DESCRIPTION("TC35893 Keypad Driver"); | ||
472 | MODULE_ALIAS("platform:tc3589x-keypad") | ||
diff --git a/drivers/input/mouse/synaptics.h b/drivers/input/mouse/synaptics.h index 613a3652f98f..0aefaa885871 100644 --- a/drivers/input/mouse/synaptics.h +++ b/drivers/input/mouse/synaptics.h | |||
@@ -51,7 +51,8 @@ | |||
51 | #define SYN_EXT_CAP_REQUESTS(c) (((c) & 0x700000) >> 20) | 51 | #define SYN_EXT_CAP_REQUESTS(c) (((c) & 0x700000) >> 20) |
52 | #define SYN_CAP_MULTI_BUTTON_NO(ec) (((ec) & 0x00f000) >> 12) | 52 | #define SYN_CAP_MULTI_BUTTON_NO(ec) (((ec) & 0x00f000) >> 12) |
53 | #define SYN_CAP_PRODUCT_ID(ec) (((ec) & 0xff0000) >> 16) | 53 | #define SYN_CAP_PRODUCT_ID(ec) (((ec) & 0xff0000) >> 16) |
54 | #define SYN_CAP_CLICKPAD(ex0c) ((ex0c) & 0x100100) | 54 | #define SYN_CAP_CLICKPAD(ex0c) ((ex0c) & 0x100000) /* 1-button ClickPad */ |
55 | #define SYN_CAP_CLICKPAD2BTN(ex0c) ((ex0c) & 0x000100) /* 2-button ClickPad */ | ||
55 | #define SYN_CAP_MAX_DIMENSIONS(ex0c) ((ex0c) & 0x020000) | 56 | #define SYN_CAP_MAX_DIMENSIONS(ex0c) ((ex0c) & 0x020000) |
56 | 57 | ||
57 | /* synaptics modes query bits */ | 58 | /* synaptics modes query bits */ |
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c index b3252ef1e279..4852b440960a 100644 --- a/drivers/input/tablet/wacom_wac.c +++ b/drivers/input/tablet/wacom_wac.c | |||
@@ -1436,6 +1436,12 @@ static struct wacom_features wacom_features_0xD2 = | |||
1436 | { "Wacom Bamboo Craft", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, 63, BAMBOO_PT }; | 1436 | { "Wacom Bamboo Craft", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, 63, BAMBOO_PT }; |
1437 | static struct wacom_features wacom_features_0xD3 = | 1437 | static struct wacom_features wacom_features_0xD3 = |
1438 | { "Wacom Bamboo 2FG 6x8", WACOM_PKGLEN_BBFUN, 21648, 13530, 1023, 63, BAMBOO_PT }; | 1438 | { "Wacom Bamboo 2FG 6x8", WACOM_PKGLEN_BBFUN, 21648, 13530, 1023, 63, BAMBOO_PT }; |
1439 | static struct wacom_features wacom_features_0xD8 = | ||
1440 | { "Wacom Bamboo Comic 2FG", WACOM_PKGLEN_BBFUN, 21648, 13530, 1023, 63, BAMBOO_PT }; | ||
1441 | static struct wacom_features wacom_features_0xDA = | ||
1442 | { "Wacom Bamboo 2FG 4x5 SE", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, 63, BAMBOO_PT }; | ||
1443 | static struct wacom_features wacom_features_0xDB = | ||
1444 | { "Wacom Bamboo 2FG 6x8 SE", WACOM_PKGLEN_BBFUN, 21648, 13530, 1023, 63, BAMBOO_PT }; | ||
1439 | 1445 | ||
1440 | #define USB_DEVICE_WACOM(prod) \ | 1446 | #define USB_DEVICE_WACOM(prod) \ |
1441 | USB_DEVICE(USB_VENDOR_ID_WACOM, prod), \ | 1447 | USB_DEVICE(USB_VENDOR_ID_WACOM, prod), \ |
@@ -1504,6 +1510,9 @@ const struct usb_device_id wacom_ids[] = { | |||
1504 | { USB_DEVICE_WACOM(0xD1) }, | 1510 | { USB_DEVICE_WACOM(0xD1) }, |
1505 | { USB_DEVICE_WACOM(0xD2) }, | 1511 | { USB_DEVICE_WACOM(0xD2) }, |
1506 | { USB_DEVICE_WACOM(0xD3) }, | 1512 | { USB_DEVICE_WACOM(0xD3) }, |
1513 | { USB_DEVICE_WACOM(0xD8) }, | ||
1514 | { USB_DEVICE_WACOM(0xDA) }, | ||
1515 | { USB_DEVICE_WACOM(0xDB) }, | ||
1507 | { USB_DEVICE_WACOM(0xF0) }, | 1516 | { USB_DEVICE_WACOM(0xF0) }, |
1508 | { USB_DEVICE_WACOM(0xCC) }, | 1517 | { USB_DEVICE_WACOM(0xCC) }, |
1509 | { USB_DEVICE_WACOM(0x90) }, | 1518 | { USB_DEVICE_WACOM(0x90) }, |
diff --git a/drivers/input/touchscreen/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c index f45f80f6d336..73fd6642b681 100644 --- a/drivers/input/touchscreen/usbtouchscreen.c +++ b/drivers/input/touchscreen/usbtouchscreen.c | |||
@@ -178,6 +178,7 @@ static const struct usb_device_id usbtouch_devices[] = { | |||
178 | 178 | ||
179 | #ifdef CONFIG_TOUCHSCREEN_USB_ITM | 179 | #ifdef CONFIG_TOUCHSCREEN_USB_ITM |
180 | {USB_DEVICE(0x0403, 0xf9e9), .driver_info = DEVTYPE_ITM}, | 180 | {USB_DEVICE(0x0403, 0xf9e9), .driver_info = DEVTYPE_ITM}, |
181 | {USB_DEVICE(0x16e3, 0xf9e9), .driver_info = DEVTYPE_ITM}, | ||
181 | #endif | 182 | #endif |
182 | 183 | ||
183 | #ifdef CONFIG_TOUCHSCREEN_USB_ETURBO | 184 | #ifdef CONFIG_TOUCHSCREEN_USB_ETURBO |
diff --git a/drivers/md/md.c b/drivers/md/md.c index 84c46a161927..e71c5fa527f5 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -371,10 +371,15 @@ static void md_end_flush(struct bio *bio, int err) | |||
371 | bio_put(bio); | 371 | bio_put(bio); |
372 | } | 372 | } |
373 | 373 | ||
374 | static void submit_flushes(mddev_t *mddev) | 374 | static void md_submit_flush_data(struct work_struct *ws); |
375 | |||
376 | static void submit_flushes(struct work_struct *ws) | ||
375 | { | 377 | { |
378 | mddev_t *mddev = container_of(ws, mddev_t, flush_work); | ||
376 | mdk_rdev_t *rdev; | 379 | mdk_rdev_t *rdev; |
377 | 380 | ||
381 | INIT_WORK(&mddev->flush_work, md_submit_flush_data); | ||
382 | atomic_set(&mddev->flush_pending, 1); | ||
378 | rcu_read_lock(); | 383 | rcu_read_lock(); |
379 | list_for_each_entry_rcu(rdev, &mddev->disks, same_set) | 384 | list_for_each_entry_rcu(rdev, &mddev->disks, same_set) |
380 | if (rdev->raid_disk >= 0 && | 385 | if (rdev->raid_disk >= 0 && |
@@ -397,6 +402,8 @@ static void submit_flushes(mddev_t *mddev) | |||
397 | rdev_dec_pending(rdev, mddev); | 402 | rdev_dec_pending(rdev, mddev); |
398 | } | 403 | } |
399 | rcu_read_unlock(); | 404 | rcu_read_unlock(); |
405 | if (atomic_dec_and_test(&mddev->flush_pending)) | ||
406 | queue_work(md_wq, &mddev->flush_work); | ||
400 | } | 407 | } |
401 | 408 | ||
402 | static void md_submit_flush_data(struct work_struct *ws) | 409 | static void md_submit_flush_data(struct work_struct *ws) |
@@ -404,8 +411,6 @@ static void md_submit_flush_data(struct work_struct *ws) | |||
404 | mddev_t *mddev = container_of(ws, mddev_t, flush_work); | 411 | mddev_t *mddev = container_of(ws, mddev_t, flush_work); |
405 | struct bio *bio = mddev->flush_bio; | 412 | struct bio *bio = mddev->flush_bio; |
406 | 413 | ||
407 | atomic_set(&mddev->flush_pending, 1); | ||
408 | |||
409 | if (bio->bi_size == 0) | 414 | if (bio->bi_size == 0) |
410 | /* an empty barrier - all done */ | 415 | /* an empty barrier - all done */ |
411 | bio_endio(bio, 0); | 416 | bio_endio(bio, 0); |
@@ -414,10 +419,9 @@ static void md_submit_flush_data(struct work_struct *ws) | |||
414 | if (mddev->pers->make_request(mddev, bio)) | 419 | if (mddev->pers->make_request(mddev, bio)) |
415 | generic_make_request(bio); | 420 | generic_make_request(bio); |
416 | } | 421 | } |
417 | if (atomic_dec_and_test(&mddev->flush_pending)) { | 422 | |
418 | mddev->flush_bio = NULL; | 423 | mddev->flush_bio = NULL; |
419 | wake_up(&mddev->sb_wait); | 424 | wake_up(&mddev->sb_wait); |
420 | } | ||
421 | } | 425 | } |
422 | 426 | ||
423 | void md_flush_request(mddev_t *mddev, struct bio *bio) | 427 | void md_flush_request(mddev_t *mddev, struct bio *bio) |
@@ -429,13 +433,8 @@ void md_flush_request(mddev_t *mddev, struct bio *bio) | |||
429 | mddev->flush_bio = bio; | 433 | mddev->flush_bio = bio; |
430 | spin_unlock_irq(&mddev->write_lock); | 434 | spin_unlock_irq(&mddev->write_lock); |
431 | 435 | ||
432 | atomic_set(&mddev->flush_pending, 1); | 436 | INIT_WORK(&mddev->flush_work, submit_flushes); |
433 | INIT_WORK(&mddev->flush_work, md_submit_flush_data); | 437 | queue_work(md_wq, &mddev->flush_work); |
434 | |||
435 | submit_flushes(mddev); | ||
436 | |||
437 | if (atomic_dec_and_test(&mddev->flush_pending)) | ||
438 | queue_work(md_wq, &mddev->flush_work); | ||
439 | } | 438 | } |
440 | EXPORT_SYMBOL(md_flush_request); | 439 | EXPORT_SYMBOL(md_flush_request); |
441 | 440 | ||
@@ -5160,7 +5159,7 @@ static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info) | |||
5160 | PTR_ERR(rdev)); | 5159 | PTR_ERR(rdev)); |
5161 | return PTR_ERR(rdev); | 5160 | return PTR_ERR(rdev); |
5162 | } | 5161 | } |
5163 | /* set save_raid_disk if appropriate */ | 5162 | /* set saved_raid_disk if appropriate */ |
5164 | if (!mddev->persistent) { | 5163 | if (!mddev->persistent) { |
5165 | if (info->state & (1<<MD_DISK_SYNC) && | 5164 | if (info->state & (1<<MD_DISK_SYNC) && |
5166 | info->raid_disk < mddev->raid_disks) | 5165 | info->raid_disk < mddev->raid_disks) |
@@ -5170,7 +5169,10 @@ static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info) | |||
5170 | } else | 5169 | } else |
5171 | super_types[mddev->major_version]. | 5170 | super_types[mddev->major_version]. |
5172 | validate_super(mddev, rdev); | 5171 | validate_super(mddev, rdev); |
5173 | rdev->saved_raid_disk = rdev->raid_disk; | 5172 | if (test_bit(In_sync, &rdev->flags)) |
5173 | rdev->saved_raid_disk = rdev->raid_disk; | ||
5174 | else | ||
5175 | rdev->saved_raid_disk = -1; | ||
5174 | 5176 | ||
5175 | clear_bit(In_sync, &rdev->flags); /* just to be sure */ | 5177 | clear_bit(In_sync, &rdev->flags); /* just to be sure */ |
5176 | if (info->state & (1<<MD_DISK_WRITEMOSTLY)) | 5178 | if (info->state & (1<<MD_DISK_WRITEMOSTLY)) |
@@ -6042,9 +6044,8 @@ static int md_thread(void * arg) | |||
6042 | || kthread_should_stop(), | 6044 | || kthread_should_stop(), |
6043 | thread->timeout); | 6045 | thread->timeout); |
6044 | 6046 | ||
6045 | clear_bit(THREAD_WAKEUP, &thread->flags); | 6047 | if (test_and_clear_bit(THREAD_WAKEUP, &thread->flags)) |
6046 | 6048 | thread->run(thread->mddev); | |
6047 | thread->run(thread->mddev); | ||
6048 | } | 6049 | } |
6049 | 6050 | ||
6050 | return 0; | 6051 | return 0; |
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index c67aa54694ae..0641674827f0 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c | |||
@@ -2397,13 +2397,13 @@ static int run(mddev_t *mddev) | |||
2397 | return 0; | 2397 | return 0; |
2398 | 2398 | ||
2399 | out_free_conf: | 2399 | out_free_conf: |
2400 | md_unregister_thread(mddev->thread); | ||
2400 | if (conf->r10bio_pool) | 2401 | if (conf->r10bio_pool) |
2401 | mempool_destroy(conf->r10bio_pool); | 2402 | mempool_destroy(conf->r10bio_pool); |
2402 | safe_put_page(conf->tmppage); | 2403 | safe_put_page(conf->tmppage); |
2403 | kfree(conf->mirrors); | 2404 | kfree(conf->mirrors); |
2404 | kfree(conf); | 2405 | kfree(conf); |
2405 | mddev->private = NULL; | 2406 | mddev->private = NULL; |
2406 | md_unregister_thread(mddev->thread); | ||
2407 | out: | 2407 | out: |
2408 | return -EIO; | 2408 | return -EIO; |
2409 | } | 2409 | } |
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 3a1493b8b5e5..e8e704f52746 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig | |||
@@ -218,12 +218,12 @@ config MFD_STMPE | |||
218 | Keypad: stmpe-keypad | 218 | Keypad: stmpe-keypad |
219 | Touchscreen: stmpe-ts | 219 | Touchscreen: stmpe-ts |
220 | 220 | ||
221 | config MFD_TC35892 | 221 | config MFD_TC3589X |
222 | bool "Support Toshiba TC35892" | 222 | bool "Support Toshiba TC35892 and variants" |
223 | depends on I2C=y && GENERIC_HARDIRQS | 223 | depends on I2C=y && GENERIC_HARDIRQS |
224 | select MFD_CORE | 224 | select MFD_CORE |
225 | help | 225 | help |
226 | Support for the Toshiba TC35892 I/O Expander. | 226 | Support for the Toshiba TC35892 and variants I/O Expander. |
227 | 227 | ||
228 | This driver provides common support for accessing the device, | 228 | This driver provides common support for accessing the device, |
229 | additional drivers must be enabled in order to use the | 229 | additional drivers must be enabled in order to use the |
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index f54b3659abbb..e590d1e44cf0 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile | |||
@@ -16,7 +16,7 @@ obj-$(CONFIG_MFD_DAVINCI_VOICECODEC) += davinci_voicecodec.o | |||
16 | obj-$(CONFIG_MFD_DM355EVM_MSP) += dm355evm_msp.o | 16 | obj-$(CONFIG_MFD_DM355EVM_MSP) += dm355evm_msp.o |
17 | 17 | ||
18 | obj-$(CONFIG_MFD_STMPE) += stmpe.o | 18 | obj-$(CONFIG_MFD_STMPE) += stmpe.o |
19 | obj-$(CONFIG_MFD_TC35892) += tc35892.o | 19 | obj-$(CONFIG_MFD_TC3589X) += tc3589x.o |
20 | obj-$(CONFIG_MFD_T7L66XB) += t7l66xb.o tmio_core.o | 20 | obj-$(CONFIG_MFD_T7L66XB) += t7l66xb.o tmio_core.o |
21 | obj-$(CONFIG_MFD_TC6387XB) += tc6387xb.o tmio_core.o | 21 | obj-$(CONFIG_MFD_TC6387XB) += tc6387xb.o tmio_core.o |
22 | obj-$(CONFIG_MFD_TC6393XB) += tc6393xb.o tmio_core.o | 22 | obj-$(CONFIG_MFD_TC6393XB) += tc6393xb.o tmio_core.o |
diff --git a/drivers/mfd/tc35892.c b/drivers/mfd/tc35892.c deleted file mode 100644 index e619e2a55997..000000000000 --- a/drivers/mfd/tc35892.c +++ /dev/null | |||
@@ -1,345 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) ST-Ericsson SA 2010 | ||
3 | * | ||
4 | * License Terms: GNU General Public License, version 2 | ||
5 | * Author: Hanumath Prasad <hanumath.prasad@stericsson.com> for ST-Ericsson | ||
6 | * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson | ||
7 | */ | ||
8 | |||
9 | #include <linux/module.h> | ||
10 | #include <linux/interrupt.h> | ||
11 | #include <linux/irq.h> | ||
12 | #include <linux/slab.h> | ||
13 | #include <linux/i2c.h> | ||
14 | #include <linux/mfd/core.h> | ||
15 | #include <linux/mfd/tc35892.h> | ||
16 | |||
17 | /** | ||
18 | * tc35892_reg_read() - read a single TC35892 register | ||
19 | * @tc35892: Device to read from | ||
20 | * @reg: Register to read | ||
21 | */ | ||
22 | int tc35892_reg_read(struct tc35892 *tc35892, u8 reg) | ||
23 | { | ||
24 | int ret; | ||
25 | |||
26 | ret = i2c_smbus_read_byte_data(tc35892->i2c, reg); | ||
27 | if (ret < 0) | ||
28 | dev_err(tc35892->dev, "failed to read reg %#x: %d\n", | ||
29 | reg, ret); | ||
30 | |||
31 | return ret; | ||
32 | } | ||
33 | EXPORT_SYMBOL_GPL(tc35892_reg_read); | ||
34 | |||
35 | /** | ||
36 | * tc35892_reg_read() - write a single TC35892 register | ||
37 | * @tc35892: Device to write to | ||
38 | * @reg: Register to read | ||
39 | * @data: Value to write | ||
40 | */ | ||
41 | int tc35892_reg_write(struct tc35892 *tc35892, u8 reg, u8 data) | ||
42 | { | ||
43 | int ret; | ||
44 | |||
45 | ret = i2c_smbus_write_byte_data(tc35892->i2c, reg, data); | ||
46 | if (ret < 0) | ||
47 | dev_err(tc35892->dev, "failed to write reg %#x: %d\n", | ||
48 | reg, ret); | ||
49 | |||
50 | return ret; | ||
51 | } | ||
52 | EXPORT_SYMBOL_GPL(tc35892_reg_write); | ||
53 | |||
54 | /** | ||
55 | * tc35892_block_read() - read multiple TC35892 registers | ||
56 | * @tc35892: Device to read from | ||
57 | * @reg: First register | ||
58 | * @length: Number of registers | ||
59 | * @values: Buffer to write to | ||
60 | */ | ||
61 | int tc35892_block_read(struct tc35892 *tc35892, u8 reg, u8 length, u8 *values) | ||
62 | { | ||
63 | int ret; | ||
64 | |||
65 | ret = i2c_smbus_read_i2c_block_data(tc35892->i2c, reg, length, values); | ||
66 | if (ret < 0) | ||
67 | dev_err(tc35892->dev, "failed to read regs %#x: %d\n", | ||
68 | reg, ret); | ||
69 | |||
70 | return ret; | ||
71 | } | ||
72 | EXPORT_SYMBOL_GPL(tc35892_block_read); | ||
73 | |||
74 | /** | ||
75 | * tc35892_block_write() - write multiple TC35892 registers | ||
76 | * @tc35892: Device to write to | ||
77 | * @reg: First register | ||
78 | * @length: Number of registers | ||
79 | * @values: Values to write | ||
80 | */ | ||
81 | int tc35892_block_write(struct tc35892 *tc35892, u8 reg, u8 length, | ||
82 | const u8 *values) | ||
83 | { | ||
84 | int ret; | ||
85 | |||
86 | ret = i2c_smbus_write_i2c_block_data(tc35892->i2c, reg, length, | ||
87 | values); | ||
88 | if (ret < 0) | ||
89 | dev_err(tc35892->dev, "failed to write regs %#x: %d\n", | ||
90 | reg, ret); | ||
91 | |||
92 | return ret; | ||
93 | } | ||
94 | EXPORT_SYMBOL_GPL(tc35892_block_write); | ||
95 | |||
96 | /** | ||
97 | * tc35892_set_bits() - set the value of a bitfield in a TC35892 register | ||
98 | * @tc35892: Device to write to | ||
99 | * @reg: Register to write | ||
100 | * @mask: Mask of bits to set | ||
101 | * @values: Value to set | ||
102 | */ | ||
103 | int tc35892_set_bits(struct tc35892 *tc35892, u8 reg, u8 mask, u8 val) | ||
104 | { | ||
105 | int ret; | ||
106 | |||
107 | mutex_lock(&tc35892->lock); | ||
108 | |||
109 | ret = tc35892_reg_read(tc35892, reg); | ||
110 | if (ret < 0) | ||
111 | goto out; | ||
112 | |||
113 | ret &= ~mask; | ||
114 | ret |= val; | ||
115 | |||
116 | ret = tc35892_reg_write(tc35892, reg, ret); | ||
117 | |||
118 | out: | ||
119 | mutex_unlock(&tc35892->lock); | ||
120 | return ret; | ||
121 | } | ||
122 | EXPORT_SYMBOL_GPL(tc35892_set_bits); | ||
123 | |||
124 | static struct resource gpio_resources[] = { | ||
125 | { | ||
126 | .start = TC35892_INT_GPIIRQ, | ||
127 | .end = TC35892_INT_GPIIRQ, | ||
128 | .flags = IORESOURCE_IRQ, | ||
129 | }, | ||
130 | }; | ||
131 | |||
132 | static struct mfd_cell tc35892_devs[] = { | ||
133 | { | ||
134 | .name = "tc35892-gpio", | ||
135 | .num_resources = ARRAY_SIZE(gpio_resources), | ||
136 | .resources = &gpio_resources[0], | ||
137 | }, | ||
138 | }; | ||
139 | |||
140 | static irqreturn_t tc35892_irq(int irq, void *data) | ||
141 | { | ||
142 | struct tc35892 *tc35892 = data; | ||
143 | int status; | ||
144 | |||
145 | status = tc35892_reg_read(tc35892, TC35892_IRQST); | ||
146 | if (status < 0) | ||
147 | return IRQ_NONE; | ||
148 | |||
149 | while (status) { | ||
150 | int bit = __ffs(status); | ||
151 | |||
152 | handle_nested_irq(tc35892->irq_base + bit); | ||
153 | status &= ~(1 << bit); | ||
154 | } | ||
155 | |||
156 | /* | ||
157 | * A dummy read or write (to any register) appears to be necessary to | ||
158 | * have the last interrupt clear (for example, GPIO IC write) take | ||
159 | * effect. | ||
160 | */ | ||
161 | tc35892_reg_read(tc35892, TC35892_IRQST); | ||
162 | |||
163 | return IRQ_HANDLED; | ||
164 | } | ||
165 | |||
166 | static void tc35892_irq_dummy(unsigned int irq) | ||
167 | { | ||
168 | /* No mask/unmask at this level */ | ||
169 | } | ||
170 | |||
171 | static struct irq_chip tc35892_irq_chip = { | ||
172 | .name = "tc35892", | ||
173 | .mask = tc35892_irq_dummy, | ||
174 | .unmask = tc35892_irq_dummy, | ||
175 | }; | ||
176 | |||
177 | static int tc35892_irq_init(struct tc35892 *tc35892) | ||
178 | { | ||
179 | int base = tc35892->irq_base; | ||
180 | int irq; | ||
181 | |||
182 | for (irq = base; irq < base + TC35892_NR_INTERNAL_IRQS; irq++) { | ||
183 | set_irq_chip_data(irq, tc35892); | ||
184 | set_irq_chip_and_handler(irq, &tc35892_irq_chip, | ||
185 | handle_edge_irq); | ||
186 | set_irq_nested_thread(irq, 1); | ||
187 | #ifdef CONFIG_ARM | ||
188 | set_irq_flags(irq, IRQF_VALID); | ||
189 | #else | ||
190 | set_irq_noprobe(irq); | ||
191 | #endif | ||
192 | } | ||
193 | |||
194 | return 0; | ||
195 | } | ||
196 | |||
197 | static void tc35892_irq_remove(struct tc35892 *tc35892) | ||
198 | { | ||
199 | int base = tc35892->irq_base; | ||
200 | int irq; | ||
201 | |||
202 | for (irq = base; irq < base + TC35892_NR_INTERNAL_IRQS; irq++) { | ||
203 | #ifdef CONFIG_ARM | ||
204 | set_irq_flags(irq, 0); | ||
205 | #endif | ||
206 | set_irq_chip_and_handler(irq, NULL, NULL); | ||
207 | set_irq_chip_data(irq, NULL); | ||
208 | } | ||
209 | } | ||
210 | |||
211 | static int tc35892_chip_init(struct tc35892 *tc35892) | ||
212 | { | ||
213 | int manf, ver, ret; | ||
214 | |||
215 | manf = tc35892_reg_read(tc35892, TC35892_MANFCODE); | ||
216 | if (manf < 0) | ||
217 | return manf; | ||
218 | |||
219 | ver = tc35892_reg_read(tc35892, TC35892_VERSION); | ||
220 | if (ver < 0) | ||
221 | return ver; | ||
222 | |||
223 | if (manf != TC35892_MANFCODE_MAGIC) { | ||
224 | dev_err(tc35892->dev, "unknown manufacturer: %#x\n", manf); | ||
225 | return -EINVAL; | ||
226 | } | ||
227 | |||
228 | dev_info(tc35892->dev, "manufacturer: %#x, version: %#x\n", manf, ver); | ||
229 | |||
230 | /* Put everything except the IRQ module into reset */ | ||
231 | ret = tc35892_reg_write(tc35892, TC35892_RSTCTRL, | ||
232 | TC35892_RSTCTRL_TIMRST | ||
233 | | TC35892_RSTCTRL_ROTRST | ||
234 | | TC35892_RSTCTRL_KBDRST | ||
235 | | TC35892_RSTCTRL_GPIRST); | ||
236 | if (ret < 0) | ||
237 | return ret; | ||
238 | |||
239 | /* Clear the reset interrupt. */ | ||
240 | return tc35892_reg_write(tc35892, TC35892_RSTINTCLR, 0x1); | ||
241 | } | ||
242 | |||
243 | static int __devinit tc35892_probe(struct i2c_client *i2c, | ||
244 | const struct i2c_device_id *id) | ||
245 | { | ||
246 | struct tc35892_platform_data *pdata = i2c->dev.platform_data; | ||
247 | struct tc35892 *tc35892; | ||
248 | int ret; | ||
249 | |||
250 | if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA | ||
251 | | I2C_FUNC_SMBUS_I2C_BLOCK)) | ||
252 | return -EIO; | ||
253 | |||
254 | tc35892 = kzalloc(sizeof(struct tc35892), GFP_KERNEL); | ||
255 | if (!tc35892) | ||
256 | return -ENOMEM; | ||
257 | |||
258 | mutex_init(&tc35892->lock); | ||
259 | |||
260 | tc35892->dev = &i2c->dev; | ||
261 | tc35892->i2c = i2c; | ||
262 | tc35892->pdata = pdata; | ||
263 | tc35892->irq_base = pdata->irq_base; | ||
264 | tc35892->num_gpio = id->driver_data; | ||
265 | |||
266 | i2c_set_clientdata(i2c, tc35892); | ||
267 | |||
268 | ret = tc35892_chip_init(tc35892); | ||
269 | if (ret) | ||
270 | goto out_free; | ||
271 | |||
272 | ret = tc35892_irq_init(tc35892); | ||
273 | if (ret) | ||
274 | goto out_free; | ||
275 | |||
276 | ret = request_threaded_irq(tc35892->i2c->irq, NULL, tc35892_irq, | ||
277 | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, | ||
278 | "tc35892", tc35892); | ||
279 | if (ret) { | ||
280 | dev_err(tc35892->dev, "failed to request IRQ: %d\n", ret); | ||
281 | goto out_removeirq; | ||
282 | } | ||
283 | |||
284 | ret = mfd_add_devices(tc35892->dev, -1, tc35892_devs, | ||
285 | ARRAY_SIZE(tc35892_devs), NULL, | ||
286 | tc35892->irq_base); | ||
287 | if (ret) { | ||
288 | dev_err(tc35892->dev, "failed to add children\n"); | ||
289 | goto out_freeirq; | ||
290 | } | ||
291 | |||
292 | return 0; | ||
293 | |||
294 | out_freeirq: | ||
295 | free_irq(tc35892->i2c->irq, tc35892); | ||
296 | out_removeirq: | ||
297 | tc35892_irq_remove(tc35892); | ||
298 | out_free: | ||
299 | kfree(tc35892); | ||
300 | return ret; | ||
301 | } | ||
302 | |||
303 | static int __devexit tc35892_remove(struct i2c_client *client) | ||
304 | { | ||
305 | struct tc35892 *tc35892 = i2c_get_clientdata(client); | ||
306 | |||
307 | mfd_remove_devices(tc35892->dev); | ||
308 | |||
309 | free_irq(tc35892->i2c->irq, tc35892); | ||
310 | tc35892_irq_remove(tc35892); | ||
311 | |||
312 | kfree(tc35892); | ||
313 | |||
314 | return 0; | ||
315 | } | ||
316 | |||
317 | static const struct i2c_device_id tc35892_id[] = { | ||
318 | { "tc35892", 24 }, | ||
319 | { } | ||
320 | }; | ||
321 | MODULE_DEVICE_TABLE(i2c, tc35892_id); | ||
322 | |||
323 | static struct i2c_driver tc35892_driver = { | ||
324 | .driver.name = "tc35892", | ||
325 | .driver.owner = THIS_MODULE, | ||
326 | .probe = tc35892_probe, | ||
327 | .remove = __devexit_p(tc35892_remove), | ||
328 | .id_table = tc35892_id, | ||
329 | }; | ||
330 | |||
331 | static int __init tc35892_init(void) | ||
332 | { | ||
333 | return i2c_add_driver(&tc35892_driver); | ||
334 | } | ||
335 | subsys_initcall(tc35892_init); | ||
336 | |||
337 | static void __exit tc35892_exit(void) | ||
338 | { | ||
339 | i2c_del_driver(&tc35892_driver); | ||
340 | } | ||
341 | module_exit(tc35892_exit); | ||
342 | |||
343 | MODULE_LICENSE("GPL v2"); | ||
344 | MODULE_DESCRIPTION("TC35892 MFD core driver"); | ||
345 | MODULE_AUTHOR("Hanumath Prasad, Rabin Vincent"); | ||
diff --git a/drivers/mfd/tc3589x.c b/drivers/mfd/tc3589x.c new file mode 100644 index 000000000000..729dbeed2ce0 --- /dev/null +++ b/drivers/mfd/tc3589x.c | |||
@@ -0,0 +1,422 @@ | |||
1 | /* | ||
2 | * Copyright (C) ST-Ericsson SA 2010 | ||
3 | * | ||
4 | * License Terms: GNU General Public License, version 2 | ||
5 | * Author: Hanumath Prasad <hanumath.prasad@stericsson.com> for ST-Ericsson | ||
6 | * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson | ||
7 | */ | ||
8 | |||
9 | #include <linux/module.h> | ||
10 | #include <linux/interrupt.h> | ||
11 | #include <linux/irq.h> | ||
12 | #include <linux/slab.h> | ||
13 | #include <linux/i2c.h> | ||
14 | #include <linux/mfd/core.h> | ||
15 | #include <linux/mfd/tc3589x.h> | ||
16 | |||
17 | #define TC3589x_CLKMODE_MODCTL_SLEEP 0x0 | ||
18 | #define TC3589x_CLKMODE_MODCTL_OPERATION (1 << 0) | ||
19 | |||
20 | /** | ||
21 | * tc3589x_reg_read() - read a single TC3589x register | ||
22 | * @tc3589x: Device to read from | ||
23 | * @reg: Register to read | ||
24 | */ | ||
25 | int tc3589x_reg_read(struct tc3589x *tc3589x, u8 reg) | ||
26 | { | ||
27 | int ret; | ||
28 | |||
29 | ret = i2c_smbus_read_byte_data(tc3589x->i2c, reg); | ||
30 | if (ret < 0) | ||
31 | dev_err(tc3589x->dev, "failed to read reg %#x: %d\n", | ||
32 | reg, ret); | ||
33 | |||
34 | return ret; | ||
35 | } | ||
36 | EXPORT_SYMBOL_GPL(tc3589x_reg_read); | ||
37 | |||
38 | /** | ||
39 | * tc3589x_reg_read() - write a single TC3589x register | ||
40 | * @tc3589x: Device to write to | ||
41 | * @reg: Register to read | ||
42 | * @data: Value to write | ||
43 | */ | ||
44 | int tc3589x_reg_write(struct tc3589x *tc3589x, u8 reg, u8 data) | ||
45 | { | ||
46 | int ret; | ||
47 | |||
48 | ret = i2c_smbus_write_byte_data(tc3589x->i2c, reg, data); | ||
49 | if (ret < 0) | ||
50 | dev_err(tc3589x->dev, "failed to write reg %#x: %d\n", | ||
51 | reg, ret); | ||
52 | |||
53 | return ret; | ||
54 | } | ||
55 | EXPORT_SYMBOL_GPL(tc3589x_reg_write); | ||
56 | |||
57 | /** | ||
58 | * tc3589x_block_read() - read multiple TC3589x registers | ||
59 | * @tc3589x: Device to read from | ||
60 | * @reg: First register | ||
61 | * @length: Number of registers | ||
62 | * @values: Buffer to write to | ||
63 | */ | ||
64 | int tc3589x_block_read(struct tc3589x *tc3589x, u8 reg, u8 length, u8 *values) | ||
65 | { | ||
66 | int ret; | ||
67 | |||
68 | ret = i2c_smbus_read_i2c_block_data(tc3589x->i2c, reg, length, values); | ||
69 | if (ret < 0) | ||
70 | dev_err(tc3589x->dev, "failed to read regs %#x: %d\n", | ||
71 | reg, ret); | ||
72 | |||
73 | return ret; | ||
74 | } | ||
75 | EXPORT_SYMBOL_GPL(tc3589x_block_read); | ||
76 | |||
77 | /** | ||
78 | * tc3589x_block_write() - write multiple TC3589x registers | ||
79 | * @tc3589x: Device to write to | ||
80 | * @reg: First register | ||
81 | * @length: Number of registers | ||
82 | * @values: Values to write | ||
83 | */ | ||
84 | int tc3589x_block_write(struct tc3589x *tc3589x, u8 reg, u8 length, | ||
85 | const u8 *values) | ||
86 | { | ||
87 | int ret; | ||
88 | |||
89 | ret = i2c_smbus_write_i2c_block_data(tc3589x->i2c, reg, length, | ||
90 | values); | ||
91 | if (ret < 0) | ||
92 | dev_err(tc3589x->dev, "failed to write regs %#x: %d\n", | ||
93 | reg, ret); | ||
94 | |||
95 | return ret; | ||
96 | } | ||
97 | EXPORT_SYMBOL_GPL(tc3589x_block_write); | ||
98 | |||
99 | /** | ||
100 | * tc3589x_set_bits() - set the value of a bitfield in a TC3589x register | ||
101 | * @tc3589x: Device to write to | ||
102 | * @reg: Register to write | ||
103 | * @mask: Mask of bits to set | ||
104 | * @values: Value to set | ||
105 | */ | ||
106 | int tc3589x_set_bits(struct tc3589x *tc3589x, u8 reg, u8 mask, u8 val) | ||
107 | { | ||
108 | int ret; | ||
109 | |||
110 | mutex_lock(&tc3589x->lock); | ||
111 | |||
112 | ret = tc3589x_reg_read(tc3589x, reg); | ||
113 | if (ret < 0) | ||
114 | goto out; | ||
115 | |||
116 | ret &= ~mask; | ||
117 | ret |= val; | ||
118 | |||
119 | ret = tc3589x_reg_write(tc3589x, reg, ret); | ||
120 | |||
121 | out: | ||
122 | mutex_unlock(&tc3589x->lock); | ||
123 | return ret; | ||
124 | } | ||
125 | EXPORT_SYMBOL_GPL(tc3589x_set_bits); | ||
126 | |||
127 | static struct resource gpio_resources[] = { | ||
128 | { | ||
129 | .start = TC3589x_INT_GPIIRQ, | ||
130 | .end = TC3589x_INT_GPIIRQ, | ||
131 | .flags = IORESOURCE_IRQ, | ||
132 | }, | ||
133 | }; | ||
134 | |||
135 | static struct resource keypad_resources[] = { | ||
136 | { | ||
137 | .start = TC3589x_INT_KBDIRQ, | ||
138 | .end = TC3589x_INT_KBDIRQ, | ||
139 | .flags = IORESOURCE_IRQ, | ||
140 | }, | ||
141 | }; | ||
142 | |||
143 | static struct mfd_cell tc3589x_dev_gpio[] = { | ||
144 | { | ||
145 | .name = "tc3589x-gpio", | ||
146 | .num_resources = ARRAY_SIZE(gpio_resources), | ||
147 | .resources = &gpio_resources[0], | ||
148 | }, | ||
149 | }; | ||
150 | |||
151 | static struct mfd_cell tc3589x_dev_keypad[] = { | ||
152 | { | ||
153 | .name = "tc3589x-keypad", | ||
154 | .num_resources = ARRAY_SIZE(keypad_resources), | ||
155 | .resources = &keypad_resources[0], | ||
156 | }, | ||
157 | }; | ||
158 | |||
159 | static irqreturn_t tc3589x_irq(int irq, void *data) | ||
160 | { | ||
161 | struct tc3589x *tc3589x = data; | ||
162 | int status; | ||
163 | |||
164 | again: | ||
165 | status = tc3589x_reg_read(tc3589x, TC3589x_IRQST); | ||
166 | if (status < 0) | ||
167 | return IRQ_NONE; | ||
168 | |||
169 | while (status) { | ||
170 | int bit = __ffs(status); | ||
171 | |||
172 | handle_nested_irq(tc3589x->irq_base + bit); | ||
173 | status &= ~(1 << bit); | ||
174 | } | ||
175 | |||
176 | /* | ||
177 | * A dummy read or write (to any register) appears to be necessary to | ||
178 | * have the last interrupt clear (for example, GPIO IC write) take | ||
179 | * effect. In such a case, recheck for any interrupt which is still | ||
180 | * pending. | ||
181 | */ | ||
182 | status = tc3589x_reg_read(tc3589x, TC3589x_IRQST); | ||
183 | if (status) | ||
184 | goto again; | ||
185 | |||
186 | return IRQ_HANDLED; | ||
187 | } | ||
188 | |||
189 | static int tc3589x_irq_init(struct tc3589x *tc3589x) | ||
190 | { | ||
191 | int base = tc3589x->irq_base; | ||
192 | int irq; | ||
193 | |||
194 | for (irq = base; irq < base + TC3589x_NR_INTERNAL_IRQS; irq++) { | ||
195 | set_irq_chip_data(irq, tc3589x); | ||
196 | set_irq_chip_and_handler(irq, &dummy_irq_chip, | ||
197 | handle_edge_irq); | ||
198 | set_irq_nested_thread(irq, 1); | ||
199 | #ifdef CONFIG_ARM | ||
200 | set_irq_flags(irq, IRQF_VALID); | ||
201 | #else | ||
202 | set_irq_noprobe(irq); | ||
203 | #endif | ||
204 | } | ||
205 | |||
206 | return 0; | ||
207 | } | ||
208 | |||
209 | static void tc3589x_irq_remove(struct tc3589x *tc3589x) | ||
210 | { | ||
211 | int base = tc3589x->irq_base; | ||
212 | int irq; | ||
213 | |||
214 | for (irq = base; irq < base + TC3589x_NR_INTERNAL_IRQS; irq++) { | ||
215 | #ifdef CONFIG_ARM | ||
216 | set_irq_flags(irq, 0); | ||
217 | #endif | ||
218 | set_irq_chip_and_handler(irq, NULL, NULL); | ||
219 | set_irq_chip_data(irq, NULL); | ||
220 | } | ||
221 | } | ||
222 | |||
223 | static int tc3589x_chip_init(struct tc3589x *tc3589x) | ||
224 | { | ||
225 | int manf, ver, ret; | ||
226 | |||
227 | manf = tc3589x_reg_read(tc3589x, TC3589x_MANFCODE); | ||
228 | if (manf < 0) | ||
229 | return manf; | ||
230 | |||
231 | ver = tc3589x_reg_read(tc3589x, TC3589x_VERSION); | ||
232 | if (ver < 0) | ||
233 | return ver; | ||
234 | |||
235 | if (manf != TC3589x_MANFCODE_MAGIC) { | ||
236 | dev_err(tc3589x->dev, "unknown manufacturer: %#x\n", manf); | ||
237 | return -EINVAL; | ||
238 | } | ||
239 | |||
240 | dev_info(tc3589x->dev, "manufacturer: %#x, version: %#x\n", manf, ver); | ||
241 | |||
242 | /* | ||
243 | * Put everything except the IRQ module into reset; | ||
244 | * also spare the GPIO module for any pin initialization | ||
245 | * done during pre-kernel boot | ||
246 | */ | ||
247 | ret = tc3589x_reg_write(tc3589x, TC3589x_RSTCTRL, | ||
248 | TC3589x_RSTCTRL_TIMRST | ||
249 | | TC3589x_RSTCTRL_ROTRST | ||
250 | | TC3589x_RSTCTRL_KBDRST); | ||
251 | if (ret < 0) | ||
252 | return ret; | ||
253 | |||
254 | /* Clear the reset interrupt. */ | ||
255 | return tc3589x_reg_write(tc3589x, TC3589x_RSTINTCLR, 0x1); | ||
256 | } | ||
257 | |||
258 | static int __devinit tc3589x_device_init(struct tc3589x *tc3589x) | ||
259 | { | ||
260 | int ret = 0; | ||
261 | unsigned int blocks = tc3589x->pdata->block; | ||
262 | |||
263 | if (blocks & TC3589x_BLOCK_GPIO) { | ||
264 | ret = mfd_add_devices(tc3589x->dev, -1, tc3589x_dev_gpio, | ||
265 | ARRAY_SIZE(tc3589x_dev_gpio), NULL, | ||
266 | tc3589x->irq_base); | ||
267 | if (ret) { | ||
268 | dev_err(tc3589x->dev, "failed to add gpio child\n"); | ||
269 | return ret; | ||
270 | } | ||
271 | dev_info(tc3589x->dev, "added gpio block\n"); | ||
272 | } | ||
273 | |||
274 | if (blocks & TC3589x_BLOCK_KEYPAD) { | ||
275 | ret = mfd_add_devices(tc3589x->dev, -1, tc3589x_dev_keypad, | ||
276 | ARRAY_SIZE(tc3589x_dev_keypad), NULL, | ||
277 | tc3589x->irq_base); | ||
278 | if (ret) { | ||
279 | dev_err(tc3589x->dev, "failed to keypad child\n"); | ||
280 | return ret; | ||
281 | } | ||
282 | dev_info(tc3589x->dev, "added keypad block\n"); | ||
283 | } | ||
284 | |||
285 | return ret; | ||
286 | } | ||
287 | |||
288 | static int __devinit tc3589x_probe(struct i2c_client *i2c, | ||
289 | const struct i2c_device_id *id) | ||
290 | { | ||
291 | struct tc3589x_platform_data *pdata = i2c->dev.platform_data; | ||
292 | struct tc3589x *tc3589x; | ||
293 | int ret; | ||
294 | |||
295 | if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA | ||
296 | | I2C_FUNC_SMBUS_I2C_BLOCK)) | ||
297 | return -EIO; | ||
298 | |||
299 | tc3589x = kzalloc(sizeof(struct tc3589x), GFP_KERNEL); | ||
300 | if (!tc3589x) | ||
301 | return -ENOMEM; | ||
302 | |||
303 | mutex_init(&tc3589x->lock); | ||
304 | |||
305 | tc3589x->dev = &i2c->dev; | ||
306 | tc3589x->i2c = i2c; | ||
307 | tc3589x->pdata = pdata; | ||
308 | tc3589x->irq_base = pdata->irq_base; | ||
309 | tc3589x->num_gpio = id->driver_data; | ||
310 | |||
311 | i2c_set_clientdata(i2c, tc3589x); | ||
312 | |||
313 | ret = tc3589x_chip_init(tc3589x); | ||
314 | if (ret) | ||
315 | goto out_free; | ||
316 | |||
317 | ret = tc3589x_irq_init(tc3589x); | ||
318 | if (ret) | ||
319 | goto out_free; | ||
320 | |||
321 | ret = request_threaded_irq(tc3589x->i2c->irq, NULL, tc3589x_irq, | ||
322 | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, | ||
323 | "tc3589x", tc3589x); | ||
324 | if (ret) { | ||
325 | dev_err(tc3589x->dev, "failed to request IRQ: %d\n", ret); | ||
326 | goto out_removeirq; | ||
327 | } | ||
328 | |||
329 | ret = tc3589x_device_init(tc3589x); | ||
330 | if (ret) { | ||
331 | dev_err(tc3589x->dev, "failed to add child devices\n"); | ||
332 | goto out_freeirq; | ||
333 | } | ||
334 | |||
335 | return 0; | ||
336 | |||
337 | out_freeirq: | ||
338 | free_irq(tc3589x->i2c->irq, tc3589x); | ||
339 | out_removeirq: | ||
340 | tc3589x_irq_remove(tc3589x); | ||
341 | out_free: | ||
342 | kfree(tc3589x); | ||
343 | return ret; | ||
344 | } | ||
345 | |||
346 | static int __devexit tc3589x_remove(struct i2c_client *client) | ||
347 | { | ||
348 | struct tc3589x *tc3589x = i2c_get_clientdata(client); | ||
349 | |||
350 | mfd_remove_devices(tc3589x->dev); | ||
351 | |||
352 | free_irq(tc3589x->i2c->irq, tc3589x); | ||
353 | tc3589x_irq_remove(tc3589x); | ||
354 | |||
355 | kfree(tc3589x); | ||
356 | |||
357 | return 0; | ||
358 | } | ||
359 | |||
360 | static int tc3589x_suspend(struct device *dev) | ||
361 | { | ||
362 | struct tc3589x *tc3589x = dev_get_drvdata(dev); | ||
363 | struct i2c_client *client = tc3589x->i2c; | ||
364 | int ret = 0; | ||
365 | |||
366 | /* put the system to sleep mode */ | ||
367 | if (!device_may_wakeup(&client->dev)) | ||
368 | ret = tc3589x_reg_write(tc3589x, TC3589x_CLKMODE, | ||
369 | TC3589x_CLKMODE_MODCTL_SLEEP); | ||
370 | |||
371 | return ret; | ||
372 | } | ||
373 | |||
374 | static int tc3589x_resume(struct device *dev) | ||
375 | { | ||
376 | struct tc3589x *tc3589x = dev_get_drvdata(dev); | ||
377 | struct i2c_client *client = tc3589x->i2c; | ||
378 | int ret = 0; | ||
379 | |||
380 | /* enable the system into operation */ | ||
381 | if (!device_may_wakeup(&client->dev)) | ||
382 | ret = tc3589x_reg_write(tc3589x, TC3589x_CLKMODE, | ||
383 | TC3589x_CLKMODE_MODCTL_OPERATION); | ||
384 | |||
385 | return ret; | ||
386 | } | ||
387 | |||
388 | static const SIMPLE_DEV_PM_OPS(tc3589x_dev_pm_ops, tc3589x_suspend, | ||
389 | tc3589x_resume); | ||
390 | |||
391 | static const struct i2c_device_id tc3589x_id[] = { | ||
392 | { "tc3589x", 24 }, | ||
393 | { } | ||
394 | }; | ||
395 | MODULE_DEVICE_TABLE(i2c, tc3589x_id); | ||
396 | |||
397 | static struct i2c_driver tc3589x_driver = { | ||
398 | .driver.name = "tc3589x", | ||
399 | .driver.owner = THIS_MODULE, | ||
400 | #ifdef CONFIG_PM | ||
401 | .driver.pm = &tc3589x_dev_pm_ops, | ||
402 | #endif | ||
403 | .probe = tc3589x_probe, | ||
404 | .remove = __devexit_p(tc3589x_remove), | ||
405 | .id_table = tc3589x_id, | ||
406 | }; | ||
407 | |||
408 | static int __init tc3589x_init(void) | ||
409 | { | ||
410 | return i2c_add_driver(&tc3589x_driver); | ||
411 | } | ||
412 | subsys_initcall(tc3589x_init); | ||
413 | |||
414 | static void __exit tc3589x_exit(void) | ||
415 | { | ||
416 | i2c_del_driver(&tc3589x_driver); | ||
417 | } | ||
418 | module_exit(tc3589x_exit); | ||
419 | |||
420 | MODULE_LICENSE("GPL v2"); | ||
421 | MODULE_DESCRIPTION("TC3589x MFD core driver"); | ||
422 | MODULE_AUTHOR("Hanumath Prasad, Rabin Vincent"); | ||
diff --git a/drivers/mtd/maps/pxa2xx-flash.c b/drivers/mtd/maps/pxa2xx-flash.c index dd90880048cf..d8ae634d347e 100644 --- a/drivers/mtd/maps/pxa2xx-flash.c +++ b/drivers/mtd/maps/pxa2xx-flash.c | |||
@@ -51,7 +51,7 @@ struct pxa2xx_flash_info { | |||
51 | static const char *probes[] = { "RedBoot", "cmdlinepart", NULL }; | 51 | static const char *probes[] = { "RedBoot", "cmdlinepart", NULL }; |
52 | 52 | ||
53 | 53 | ||
54 | static int __init pxa2xx_flash_probe(struct platform_device *pdev) | 54 | static int __devinit pxa2xx_flash_probe(struct platform_device *pdev) |
55 | { | 55 | { |
56 | struct flash_platform_data *flash = pdev->dev.platform_data; | 56 | struct flash_platform_data *flash = pdev->dev.platform_data; |
57 | struct pxa2xx_flash_info *info; | 57 | struct pxa2xx_flash_info *info; |
diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index cd41c58b5bbd..15682ec8530e 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c | |||
@@ -7,7 +7,6 @@ | |||
7 | * it under the terms of the GNU General Public License version 2 as | 7 | * it under the terms of the GNU General Public License version 2 as |
8 | * published by the Free Software Foundation. | 8 | * published by the Free Software Foundation. |
9 | */ | 9 | */ |
10 | #define CONFIG_MTD_NAND_OMAP_HWECC | ||
11 | 10 | ||
12 | #include <linux/platform_device.h> | 11 | #include <linux/platform_device.h> |
13 | #include <linux/dma-mapping.h> | 12 | #include <linux/dma-mapping.h> |
diff --git a/drivers/net/b44.c b/drivers/net/b44.c index c6e86315b3f8..2e2b76258ab4 100644 --- a/drivers/net/b44.c +++ b/drivers/net/b44.c | |||
@@ -381,11 +381,11 @@ static void b44_set_flow_ctrl(struct b44 *bp, u32 local, u32 remote) | |||
381 | __b44_set_flow_ctrl(bp, pause_enab); | 381 | __b44_set_flow_ctrl(bp, pause_enab); |
382 | } | 382 | } |
383 | 383 | ||
384 | #ifdef SSB_DRIVER_MIPS | 384 | #ifdef CONFIG_BCM47XX |
385 | extern char *nvram_get(char *name); | 385 | #include <asm/mach-bcm47xx/nvram.h> |
386 | static void b44_wap54g10_workaround(struct b44 *bp) | 386 | static void b44_wap54g10_workaround(struct b44 *bp) |
387 | { | 387 | { |
388 | const char *str; | 388 | char buf[20]; |
389 | u32 val; | 389 | u32 val; |
390 | int err; | 390 | int err; |
391 | 391 | ||
@@ -394,10 +394,9 @@ static void b44_wap54g10_workaround(struct b44 *bp) | |||
394 | * see https://dev.openwrt.org/ticket/146 | 394 | * see https://dev.openwrt.org/ticket/146 |
395 | * check and reset bit "isolate" | 395 | * check and reset bit "isolate" |
396 | */ | 396 | */ |
397 | str = nvram_get("boardnum"); | 397 | if (nvram_getenv("boardnum", buf, sizeof(buf)) < 0) |
398 | if (!str) | ||
399 | return; | 398 | return; |
400 | if (simple_strtoul(str, NULL, 0) == 2) { | 399 | if (simple_strtoul(buf, NULL, 0) == 2) { |
401 | err = __b44_readphy(bp, 0, MII_BMCR, &val); | 400 | err = __b44_readphy(bp, 0, MII_BMCR, &val); |
402 | if (err) | 401 | if (err) |
403 | goto error; | 402 | goto error; |
diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c index 36eca1ce75d4..e4465d222a7d 100644 --- a/drivers/net/benet/be_cmds.c +++ b/drivers/net/benet/be_cmds.c | |||
@@ -1235,7 +1235,7 @@ int be_cmd_multicast_set(struct be_adapter *adapter, u32 if_id, | |||
1235 | 1235 | ||
1236 | i = 0; | 1236 | i = 0; |
1237 | netdev_for_each_mc_addr(ha, netdev) | 1237 | netdev_for_each_mc_addr(ha, netdev) |
1238 | memcpy(req->mac[i].byte, ha->addr, ETH_ALEN); | 1238 | memcpy(req->mac[i++].byte, ha->addr, ETH_ALEN); |
1239 | } else { | 1239 | } else { |
1240 | req->promiscuous = 1; | 1240 | req->promiscuous = 1; |
1241 | } | 1241 | } |
diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index 863e73a85fbe..d255428122fc 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h | |||
@@ -20,8 +20,8 @@ | |||
20 | * (you will need to reboot afterwards) */ | 20 | * (you will need to reboot afterwards) */ |
21 | /* #define BNX2X_STOP_ON_ERROR */ | 21 | /* #define BNX2X_STOP_ON_ERROR */ |
22 | 22 | ||
23 | #define DRV_MODULE_VERSION "1.60.00-4" | 23 | #define DRV_MODULE_VERSION "1.60.01-0" |
24 | #define DRV_MODULE_RELDATE "2010/11/01" | 24 | #define DRV_MODULE_RELDATE "2010/11/12" |
25 | #define BNX2X_BC_VER 0x040200 | 25 | #define BNX2X_BC_VER 0x040200 |
26 | 26 | ||
27 | #define BNX2X_MULTI_QUEUE | 27 | #define BNX2X_MULTI_QUEUE |
diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index 94d5f59d5a6f..0af361e4e3d1 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c | |||
@@ -1782,15 +1782,15 @@ exit_lbl: | |||
1782 | } | 1782 | } |
1783 | #endif | 1783 | #endif |
1784 | 1784 | ||
1785 | static inline void bnx2x_set_pbd_gso_e2(struct sk_buff *skb, | 1785 | static inline void bnx2x_set_pbd_gso_e2(struct sk_buff *skb, u32 *parsing_data, |
1786 | struct eth_tx_parse_bd_e2 *pbd, | 1786 | u32 xmit_type) |
1787 | u32 xmit_type) | ||
1788 | { | 1787 | { |
1789 | pbd->parsing_data |= cpu_to_le16(skb_shinfo(skb)->gso_size) << | 1788 | *parsing_data |= (skb_shinfo(skb)->gso_size << |
1790 | ETH_TX_PARSE_BD_E2_LSO_MSS_SHIFT; | 1789 | ETH_TX_PARSE_BD_E2_LSO_MSS_SHIFT) & |
1790 | ETH_TX_PARSE_BD_E2_LSO_MSS; | ||
1791 | if ((xmit_type & XMIT_GSO_V6) && | 1791 | if ((xmit_type & XMIT_GSO_V6) && |
1792 | (ipv6_hdr(skb)->nexthdr == NEXTHDR_IPV6)) | 1792 | (ipv6_hdr(skb)->nexthdr == NEXTHDR_IPV6)) |
1793 | pbd->parsing_data |= ETH_TX_PARSE_BD_E2_IPV6_WITH_EXT_HDR; | 1793 | *parsing_data |= ETH_TX_PARSE_BD_E2_IPV6_WITH_EXT_HDR; |
1794 | } | 1794 | } |
1795 | 1795 | ||
1796 | /** | 1796 | /** |
@@ -1835,15 +1835,15 @@ static inline void bnx2x_set_pbd_gso(struct sk_buff *skb, | |||
1835 | * @return header len | 1835 | * @return header len |
1836 | */ | 1836 | */ |
1837 | static inline u8 bnx2x_set_pbd_csum_e2(struct bnx2x *bp, struct sk_buff *skb, | 1837 | static inline u8 bnx2x_set_pbd_csum_e2(struct bnx2x *bp, struct sk_buff *skb, |
1838 | struct eth_tx_parse_bd_e2 *pbd, | 1838 | u32 *parsing_data, u32 xmit_type) |
1839 | u32 xmit_type) | ||
1840 | { | 1839 | { |
1841 | pbd->parsing_data |= cpu_to_le16(tcp_hdrlen(skb)/4) << | 1840 | *parsing_data |= ((tcp_hdrlen(skb)/4) << |
1842 | ETH_TX_PARSE_BD_E2_TCP_HDR_LENGTH_DW_SHIFT; | 1841 | ETH_TX_PARSE_BD_E2_TCP_HDR_LENGTH_DW_SHIFT) & |
1842 | ETH_TX_PARSE_BD_E2_TCP_HDR_LENGTH_DW; | ||
1843 | 1843 | ||
1844 | pbd->parsing_data |= cpu_to_le16(((unsigned char *)tcp_hdr(skb) - | 1844 | *parsing_data |= ((((u8 *)tcp_hdr(skb) - skb->data) / 2) << |
1845 | skb->data) / 2) << | 1845 | ETH_TX_PARSE_BD_E2_TCP_HDR_START_OFFSET_W_SHIFT) & |
1846 | ETH_TX_PARSE_BD_E2_TCP_HDR_START_OFFSET_W_SHIFT; | 1846 | ETH_TX_PARSE_BD_E2_TCP_HDR_START_OFFSET_W; |
1847 | 1847 | ||
1848 | return skb_transport_header(skb) + tcp_hdrlen(skb) - skb->data; | 1848 | return skb_transport_header(skb) + tcp_hdrlen(skb) - skb->data; |
1849 | } | 1849 | } |
@@ -1912,6 +1912,7 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
1912 | struct eth_tx_bd *tx_data_bd, *total_pkt_bd = NULL; | 1912 | struct eth_tx_bd *tx_data_bd, *total_pkt_bd = NULL; |
1913 | struct eth_tx_parse_bd_e1x *pbd_e1x = NULL; | 1913 | struct eth_tx_parse_bd_e1x *pbd_e1x = NULL; |
1914 | struct eth_tx_parse_bd_e2 *pbd_e2 = NULL; | 1914 | struct eth_tx_parse_bd_e2 *pbd_e2 = NULL; |
1915 | u32 pbd_e2_parsing_data = 0; | ||
1915 | u16 pkt_prod, bd_prod; | 1916 | u16 pkt_prod, bd_prod; |
1916 | int nbd, fp_index; | 1917 | int nbd, fp_index; |
1917 | dma_addr_t mapping; | 1918 | dma_addr_t mapping; |
@@ -2033,8 +2034,9 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
2033 | memset(pbd_e2, 0, sizeof(struct eth_tx_parse_bd_e2)); | 2034 | memset(pbd_e2, 0, sizeof(struct eth_tx_parse_bd_e2)); |
2034 | /* Set PBD in checksum offload case */ | 2035 | /* Set PBD in checksum offload case */ |
2035 | if (xmit_type & XMIT_CSUM) | 2036 | if (xmit_type & XMIT_CSUM) |
2036 | hlen = bnx2x_set_pbd_csum_e2(bp, | 2037 | hlen = bnx2x_set_pbd_csum_e2(bp, skb, |
2037 | skb, pbd_e2, xmit_type); | 2038 | &pbd_e2_parsing_data, |
2039 | xmit_type); | ||
2038 | } else { | 2040 | } else { |
2039 | pbd_e1x = &fp->tx_desc_ring[bd_prod].parse_bd_e1x; | 2041 | pbd_e1x = &fp->tx_desc_ring[bd_prod].parse_bd_e1x; |
2040 | memset(pbd_e1x, 0, sizeof(struct eth_tx_parse_bd_e1x)); | 2042 | memset(pbd_e1x, 0, sizeof(struct eth_tx_parse_bd_e1x)); |
@@ -2076,10 +2078,18 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
2076 | bd_prod = bnx2x_tx_split(bp, fp, tx_buf, &tx_start_bd, | 2078 | bd_prod = bnx2x_tx_split(bp, fp, tx_buf, &tx_start_bd, |
2077 | hlen, bd_prod, ++nbd); | 2079 | hlen, bd_prod, ++nbd); |
2078 | if (CHIP_IS_E2(bp)) | 2080 | if (CHIP_IS_E2(bp)) |
2079 | bnx2x_set_pbd_gso_e2(skb, pbd_e2, xmit_type); | 2081 | bnx2x_set_pbd_gso_e2(skb, &pbd_e2_parsing_data, |
2082 | xmit_type); | ||
2080 | else | 2083 | else |
2081 | bnx2x_set_pbd_gso(skb, pbd_e1x, xmit_type); | 2084 | bnx2x_set_pbd_gso(skb, pbd_e1x, xmit_type); |
2082 | } | 2085 | } |
2086 | |||
2087 | /* Set the PBD's parsing_data field if not zero | ||
2088 | * (for the chips newer than 57711). | ||
2089 | */ | ||
2090 | if (pbd_e2_parsing_data) | ||
2091 | pbd_e2->parsing_data = cpu_to_le32(pbd_e2_parsing_data); | ||
2092 | |||
2083 | tx_data_bd = (struct eth_tx_bd *)tx_start_bd; | 2093 | tx_data_bd = (struct eth_tx_bd *)tx_start_bd; |
2084 | 2094 | ||
2085 | /* Handle fragmented skb */ | 2095 | /* Handle fragmented skb */ |
diff --git a/drivers/net/bnx2x/bnx2x_init_ops.h b/drivers/net/bnx2x/bnx2x_init_ops.h index a306b0e46b61..66df29fcf751 100644 --- a/drivers/net/bnx2x/bnx2x_init_ops.h +++ b/drivers/net/bnx2x/bnx2x_init_ops.h | |||
@@ -838,7 +838,7 @@ static void bnx2x_qm_init_ptr_table(struct bnx2x *bp, int qm_cid_count, | |||
838 | /**************************************************************************** | 838 | /**************************************************************************** |
839 | * SRC initializations | 839 | * SRC initializations |
840 | ****************************************************************************/ | 840 | ****************************************************************************/ |
841 | 841 | #ifdef BCM_CNIC | |
842 | /* called during init func stage */ | 842 | /* called during init func stage */ |
843 | static void bnx2x_src_init_t2(struct bnx2x *bp, struct src_ent *t2, | 843 | static void bnx2x_src_init_t2(struct bnx2x *bp, struct src_ent *t2, |
844 | dma_addr_t t2_mapping, int src_cid_count) | 844 | dma_addr_t t2_mapping, int src_cid_count) |
@@ -862,5 +862,5 @@ static void bnx2x_src_init_t2(struct bnx2x *bp, struct src_ent *t2, | |||
862 | U64_HI((u64)t2_mapping + | 862 | U64_HI((u64)t2_mapping + |
863 | (src_cid_count-1) * sizeof(struct src_ent))); | 863 | (src_cid_count-1) * sizeof(struct src_ent))); |
864 | } | 864 | } |
865 | 865 | #endif | |
866 | #endif /* BNX2X_INIT_OPS_H */ | 866 | #endif /* BNX2X_INIT_OPS_H */ |
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 71a169740d05..d0ea760ce419 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
@@ -171,7 +171,7 @@ MODULE_PARM_DESC(resend_igmp, "Number of IGMP membership reports to send on link | |||
171 | /*----------------------------- Global variables ----------------------------*/ | 171 | /*----------------------------- Global variables ----------------------------*/ |
172 | 172 | ||
173 | #ifdef CONFIG_NET_POLL_CONTROLLER | 173 | #ifdef CONFIG_NET_POLL_CONTROLLER |
174 | cpumask_var_t netpoll_block_tx; | 174 | atomic_t netpoll_block_tx = ATOMIC_INIT(0); |
175 | #endif | 175 | #endif |
176 | 176 | ||
177 | static const char * const version = | 177 | static const char * const version = |
@@ -1576,7 +1576,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | |||
1576 | 1576 | ||
1577 | /* If this is the first slave, then we need to set the master's hardware | 1577 | /* If this is the first slave, then we need to set the master's hardware |
1578 | * address to be the same as the slave's. */ | 1578 | * address to be the same as the slave's. */ |
1579 | if (bond->slave_cnt == 0) | 1579 | if (is_zero_ether_addr(bond->dev->dev_addr)) |
1580 | memcpy(bond->dev->dev_addr, slave_dev->dev_addr, | 1580 | memcpy(bond->dev->dev_addr, slave_dev->dev_addr, |
1581 | slave_dev->addr_len); | 1581 | slave_dev->addr_len); |
1582 | 1582 | ||
@@ -5299,13 +5299,6 @@ static int __init bonding_init(void) | |||
5299 | if (res) | 5299 | if (res) |
5300 | goto out; | 5300 | goto out; |
5301 | 5301 | ||
5302 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
5303 | if (!alloc_cpumask_var(&netpoll_block_tx, GFP_KERNEL)) { | ||
5304 | res = -ENOMEM; | ||
5305 | goto out; | ||
5306 | } | ||
5307 | #endif | ||
5308 | |||
5309 | res = register_pernet_subsys(&bond_net_ops); | 5302 | res = register_pernet_subsys(&bond_net_ops); |
5310 | if (res) | 5303 | if (res) |
5311 | goto out; | 5304 | goto out; |
@@ -5334,9 +5327,6 @@ err: | |||
5334 | rtnl_link_unregister(&bond_link_ops); | 5327 | rtnl_link_unregister(&bond_link_ops); |
5335 | err_link: | 5328 | err_link: |
5336 | unregister_pernet_subsys(&bond_net_ops); | 5329 | unregister_pernet_subsys(&bond_net_ops); |
5337 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
5338 | free_cpumask_var(netpoll_block_tx); | ||
5339 | #endif | ||
5340 | goto out; | 5330 | goto out; |
5341 | 5331 | ||
5342 | } | 5332 | } |
@@ -5353,7 +5343,10 @@ static void __exit bonding_exit(void) | |||
5353 | unregister_pernet_subsys(&bond_net_ops); | 5343 | unregister_pernet_subsys(&bond_net_ops); |
5354 | 5344 | ||
5355 | #ifdef CONFIG_NET_POLL_CONTROLLER | 5345 | #ifdef CONFIG_NET_POLL_CONTROLLER |
5356 | free_cpumask_var(netpoll_block_tx); | 5346 | /* |
5347 | * Make sure we don't have an imbalance on our netpoll blocking | ||
5348 | */ | ||
5349 | WARN_ON(atomic_read(&netpoll_block_tx)); | ||
5357 | #endif | 5350 | #endif |
5358 | } | 5351 | } |
5359 | 5352 | ||
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h index 4eedb12df6ca..c2f081352a03 100644 --- a/drivers/net/bonding/bonding.h +++ b/drivers/net/bonding/bonding.h | |||
@@ -119,26 +119,22 @@ | |||
119 | 119 | ||
120 | 120 | ||
121 | #ifdef CONFIG_NET_POLL_CONTROLLER | 121 | #ifdef CONFIG_NET_POLL_CONTROLLER |
122 | extern cpumask_var_t netpoll_block_tx; | 122 | extern atomic_t netpoll_block_tx; |
123 | 123 | ||
124 | static inline void block_netpoll_tx(void) | 124 | static inline void block_netpoll_tx(void) |
125 | { | 125 | { |
126 | preempt_disable(); | 126 | atomic_inc(&netpoll_block_tx); |
127 | BUG_ON(cpumask_test_and_set_cpu(smp_processor_id(), | ||
128 | netpoll_block_tx)); | ||
129 | } | 127 | } |
130 | 128 | ||
131 | static inline void unblock_netpoll_tx(void) | 129 | static inline void unblock_netpoll_tx(void) |
132 | { | 130 | { |
133 | BUG_ON(!cpumask_test_and_clear_cpu(smp_processor_id(), | 131 | atomic_dec(&netpoll_block_tx); |
134 | netpoll_block_tx)); | ||
135 | preempt_enable(); | ||
136 | } | 132 | } |
137 | 133 | ||
138 | static inline int is_netpoll_tx_blocked(struct net_device *dev) | 134 | static inline int is_netpoll_tx_blocked(struct net_device *dev) |
139 | { | 135 | { |
140 | if (unlikely(dev->priv_flags & IFF_IN_NETPOLL)) | 136 | if (unlikely(dev->priv_flags & IFF_IN_NETPOLL)) |
141 | return cpumask_test_cpu(smp_processor_id(), netpoll_block_tx); | 137 | return atomic_read(&netpoll_block_tx); |
142 | return 0; | 138 | return 0; |
143 | } | 139 | } |
144 | #else | 140 | #else |
diff --git a/drivers/net/caif/caif_shm_u5500.c b/drivers/net/caif/caif_shm_u5500.c index 1cd90da86f13..5f771ab712c4 100644 --- a/drivers/net/caif/caif_shm_u5500.c +++ b/drivers/net/caif/caif_shm_u5500.c | |||
@@ -5,13 +5,13 @@ | |||
5 | * License terms: GNU General Public License (GPL) version 2 | 5 | * License terms: GNU General Public License (GPL) version 2 |
6 | */ | 6 | */ |
7 | 7 | ||
8 | #define pr_fmt(fmt) KBUILD_MODNAME ":" __func__ "():" fmt | 8 | #define pr_fmt(fmt) KBUILD_MODNAME ":" fmt |
9 | 9 | ||
10 | #include <linux/version.h> | 10 | #include <linux/version.h> |
11 | #include <linux/init.h> | 11 | #include <linux/init.h> |
12 | #include <linux/module.h> | 12 | #include <linux/module.h> |
13 | #include <linux/netdevice.h> | 13 | #include <linux/netdevice.h> |
14 | #include <mach/mbox.h> | 14 | #include <mach/mbox-db5500.h> |
15 | #include <net/caif/caif_shm.h> | 15 | #include <net/caif/caif_shm.h> |
16 | 16 | ||
17 | MODULE_LICENSE("GPL"); | 17 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/net/caif/caif_shmcore.c b/drivers/net/caif/caif_shmcore.c index 19f9c0656667..80511167f35b 100644 --- a/drivers/net/caif/caif_shmcore.c +++ b/drivers/net/caif/caif_shmcore.c | |||
@@ -6,7 +6,7 @@ | |||
6 | * License terms: GNU General Public License (GPL) version 2 | 6 | * License terms: GNU General Public License (GPL) version 2 |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #define pr_fmt(fmt) KBUILD_MODNAME ":" __func__ "():" fmt | 9 | #define pr_fmt(fmt) KBUILD_MODNAME ":" fmt |
10 | 10 | ||
11 | #include <linux/spinlock.h> | 11 | #include <linux/spinlock.h> |
12 | #include <linux/sched.h> | 12 | #include <linux/sched.h> |
diff --git a/drivers/net/cxgb4/t4_hw.c b/drivers/net/cxgb4/t4_hw.c index bb813d94aea8..e97521c801ea 100644 --- a/drivers/net/cxgb4/t4_hw.c +++ b/drivers/net/cxgb4/t4_hw.c | |||
@@ -2408,7 +2408,7 @@ int t4_alloc_mac_filt(struct adapter *adap, unsigned int mbox, | |||
2408 | if (index < NEXACT_MAC) | 2408 | if (index < NEXACT_MAC) |
2409 | ret++; | 2409 | ret++; |
2410 | else if (hash) | 2410 | else if (hash) |
2411 | *hash |= (1 << hash_mac_addr(addr[i])); | 2411 | *hash |= (1ULL << hash_mac_addr(addr[i])); |
2412 | } | 2412 | } |
2413 | return ret; | 2413 | return ret; |
2414 | } | 2414 | } |
diff --git a/drivers/net/cxgb4vf/cxgb4vf_main.c b/drivers/net/cxgb4vf/cxgb4vf_main.c index d887a76cd39d..6bf464afa90e 100644 --- a/drivers/net/cxgb4vf/cxgb4vf_main.c +++ b/drivers/net/cxgb4vf/cxgb4vf_main.c | |||
@@ -2269,6 +2269,7 @@ static void __devinit cfg_queues(struct adapter *adapter) | |||
2269 | { | 2269 | { |
2270 | struct sge *s = &adapter->sge; | 2270 | struct sge *s = &adapter->sge; |
2271 | int q10g, n10g, qidx, pidx, qs; | 2271 | int q10g, n10g, qidx, pidx, qs; |
2272 | size_t iqe_size; | ||
2272 | 2273 | ||
2273 | /* | 2274 | /* |
2274 | * We should not be called till we know how many Queue Sets we can | 2275 | * We should not be called till we know how many Queue Sets we can |
@@ -2313,6 +2314,13 @@ static void __devinit cfg_queues(struct adapter *adapter) | |||
2313 | s->ethqsets = qidx; | 2314 | s->ethqsets = qidx; |
2314 | 2315 | ||
2315 | /* | 2316 | /* |
2317 | * The Ingress Queue Entry Size for our various Response Queues needs | ||
2318 | * to be big enough to accommodate the largest message we can receive | ||
2319 | * from the chip/firmware; which is 64 bytes ... | ||
2320 | */ | ||
2321 | iqe_size = 64; | ||
2322 | |||
2323 | /* | ||
2316 | * Set up default Queue Set parameters ... Start off with the | 2324 | * Set up default Queue Set parameters ... Start off with the |
2317 | * shortest interrupt holdoff timer. | 2325 | * shortest interrupt holdoff timer. |
2318 | */ | 2326 | */ |
@@ -2320,7 +2328,7 @@ static void __devinit cfg_queues(struct adapter *adapter) | |||
2320 | struct sge_eth_rxq *rxq = &s->ethrxq[qs]; | 2328 | struct sge_eth_rxq *rxq = &s->ethrxq[qs]; |
2321 | struct sge_eth_txq *txq = &s->ethtxq[qs]; | 2329 | struct sge_eth_txq *txq = &s->ethtxq[qs]; |
2322 | 2330 | ||
2323 | init_rspq(&rxq->rspq, 0, 0, 1024, L1_CACHE_BYTES); | 2331 | init_rspq(&rxq->rspq, 0, 0, 1024, iqe_size); |
2324 | rxq->fl.size = 72; | 2332 | rxq->fl.size = 72; |
2325 | txq->q.size = 1024; | 2333 | txq->q.size = 1024; |
2326 | } | 2334 | } |
@@ -2329,8 +2337,7 @@ static void __devinit cfg_queues(struct adapter *adapter) | |||
2329 | * The firmware event queue is used for link state changes and | 2337 | * The firmware event queue is used for link state changes and |
2330 | * notifications of TX DMA completions. | 2338 | * notifications of TX DMA completions. |
2331 | */ | 2339 | */ |
2332 | init_rspq(&s->fw_evtq, SGE_TIMER_RSTRT_CNTR, 0, 512, | 2340 | init_rspq(&s->fw_evtq, SGE_TIMER_RSTRT_CNTR, 0, 512, iqe_size); |
2333 | L1_CACHE_BYTES); | ||
2334 | 2341 | ||
2335 | /* | 2342 | /* |
2336 | * The forwarded interrupt queue is used when we're in MSI interrupt | 2343 | * The forwarded interrupt queue is used when we're in MSI interrupt |
@@ -2346,7 +2353,7 @@ static void __devinit cfg_queues(struct adapter *adapter) | |||
2346 | * any time ... | 2353 | * any time ... |
2347 | */ | 2354 | */ |
2348 | init_rspq(&s->intrq, SGE_TIMER_RSTRT_CNTR, 0, MSIX_ENTRIES + 1, | 2355 | init_rspq(&s->intrq, SGE_TIMER_RSTRT_CNTR, 0, MSIX_ENTRIES + 1, |
2349 | L1_CACHE_BYTES); | 2356 | iqe_size); |
2350 | } | 2357 | } |
2351 | 2358 | ||
2352 | /* | 2359 | /* |
diff --git a/drivers/net/ehea/ehea_ethtool.c b/drivers/net/ehea/ehea_ethtool.c index 75b099ce49c9..1f37ee6b2a26 100644 --- a/drivers/net/ehea/ehea_ethtool.c +++ b/drivers/net/ehea/ehea_ethtool.c | |||
@@ -261,6 +261,13 @@ static void ehea_get_ethtool_stats(struct net_device *dev, | |||
261 | 261 | ||
262 | } | 262 | } |
263 | 263 | ||
264 | static int ehea_set_flags(struct net_device *dev, u32 data) | ||
265 | { | ||
266 | return ethtool_op_set_flags(dev, data, ETH_FLAG_LRO | ||
267 | | ETH_FLAG_TXVLAN | ||
268 | | ETH_FLAG_RXVLAN); | ||
269 | } | ||
270 | |||
264 | const struct ethtool_ops ehea_ethtool_ops = { | 271 | const struct ethtool_ops ehea_ethtool_ops = { |
265 | .get_settings = ehea_get_settings, | 272 | .get_settings = ehea_get_settings, |
266 | .get_drvinfo = ehea_get_drvinfo, | 273 | .get_drvinfo = ehea_get_drvinfo, |
@@ -273,6 +280,8 @@ const struct ethtool_ops ehea_ethtool_ops = { | |||
273 | .get_ethtool_stats = ehea_get_ethtool_stats, | 280 | .get_ethtool_stats = ehea_get_ethtool_stats, |
274 | .get_rx_csum = ehea_get_rx_csum, | 281 | .get_rx_csum = ehea_get_rx_csum, |
275 | .set_settings = ehea_set_settings, | 282 | .set_settings = ehea_set_settings, |
283 | .get_flags = ethtool_op_get_flags, | ||
284 | .set_flags = ehea_set_flags, | ||
276 | .nway_reset = ehea_nway_reset, /* Restart autonegotiation */ | 285 | .nway_reset = ehea_nway_reset, /* Restart autonegotiation */ |
277 | }; | 286 | }; |
278 | 287 | ||
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index 3d0af08483a1..b95f087cd5a9 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c | |||
@@ -683,7 +683,7 @@ static void ehea_proc_skb(struct ehea_port_res *pr, struct ehea_cqe *cqe, | |||
683 | int vlan_extracted = ((cqe->status & EHEA_CQE_VLAN_TAG_XTRACT) && | 683 | int vlan_extracted = ((cqe->status & EHEA_CQE_VLAN_TAG_XTRACT) && |
684 | pr->port->vgrp); | 684 | pr->port->vgrp); |
685 | 685 | ||
686 | if (use_lro) { | 686 | if (skb->dev->features & NETIF_F_LRO) { |
687 | if (vlan_extracted) | 687 | if (vlan_extracted) |
688 | lro_vlan_hwaccel_receive_skb(&pr->lro_mgr, skb, | 688 | lro_vlan_hwaccel_receive_skb(&pr->lro_mgr, skb, |
689 | pr->port->vgrp, | 689 | pr->port->vgrp, |
@@ -787,7 +787,7 @@ static int ehea_proc_rwqes(struct net_device *dev, | |||
787 | } | 787 | } |
788 | cqe = ehea_poll_rq1(qp, &wqe_index); | 788 | cqe = ehea_poll_rq1(qp, &wqe_index); |
789 | } | 789 | } |
790 | if (use_lro) | 790 | if (dev->features & NETIF_F_LRO) |
791 | lro_flush_all(&pr->lro_mgr); | 791 | lro_flush_all(&pr->lro_mgr); |
792 | 792 | ||
793 | pr->rx_packets += processed; | 793 | pr->rx_packets += processed; |
@@ -3278,6 +3278,9 @@ struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter, | |||
3278 | | NETIF_F_LLTX; | 3278 | | NETIF_F_LLTX; |
3279 | dev->watchdog_timeo = EHEA_WATCH_DOG_TIMEOUT; | 3279 | dev->watchdog_timeo = EHEA_WATCH_DOG_TIMEOUT; |
3280 | 3280 | ||
3281 | if (use_lro) | ||
3282 | dev->features |= NETIF_F_LRO; | ||
3283 | |||
3281 | INIT_WORK(&port->reset_task, ehea_reset_port); | 3284 | INIT_WORK(&port->reset_task, ehea_reset_port); |
3282 | 3285 | ||
3283 | ret = register_netdev(dev); | 3286 | ret = register_netdev(dev); |
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c index a466ef91dd43..aa28b270c045 100644 --- a/drivers/net/enic/enic_main.c +++ b/drivers/net/enic/enic_main.c | |||
@@ -1962,7 +1962,8 @@ static void enic_poll_controller(struct net_device *netdev) | |||
1962 | case VNIC_DEV_INTR_MODE_MSIX: | 1962 | case VNIC_DEV_INTR_MODE_MSIX: |
1963 | for (i = 0; i < enic->rq_count; i++) { | 1963 | for (i = 0; i < enic->rq_count; i++) { |
1964 | intr = enic_msix_rq_intr(enic, i); | 1964 | intr = enic_msix_rq_intr(enic, i); |
1965 | enic_isr_msix_rq(enic->msix_entry[intr].vector, enic); | 1965 | enic_isr_msix_rq(enic->msix_entry[intr].vector, |
1966 | &enic->napi[i]); | ||
1966 | } | 1967 | } |
1967 | intr = enic_msix_wq_intr(enic, i); | 1968 | intr = enic_msix_wq_intr(enic, i); |
1968 | enic_isr_msix_wq(enic->msix_entry[intr].vector, enic); | 1969 | enic_isr_msix_wq(enic->msix_entry[intr].vector, enic); |
diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c index ab9f675c5b8b..fe337bd121aa 100644 --- a/drivers/net/ifb.c +++ b/drivers/net/ifb.c | |||
@@ -104,6 +104,8 @@ static void ri_tasklet(unsigned long dev) | |||
104 | rcu_read_unlock(); | 104 | rcu_read_unlock(); |
105 | dev_kfree_skb(skb); | 105 | dev_kfree_skb(skb); |
106 | stats->tx_dropped++; | 106 | stats->tx_dropped++; |
107 | if (skb_queue_len(&dp->tq) != 0) | ||
108 | goto resched; | ||
107 | break; | 109 | break; |
108 | } | 110 | } |
109 | rcu_read_unlock(); | 111 | rcu_read_unlock(); |
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index fbad4d819608..eee0b298bd36 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c | |||
@@ -4771,6 +4771,9 @@ void ixgbe_clear_interrupt_scheme(struct ixgbe_adapter *adapter) | |||
4771 | adapter->rx_ring[i] = NULL; | 4771 | adapter->rx_ring[i] = NULL; |
4772 | } | 4772 | } |
4773 | 4773 | ||
4774 | adapter->num_tx_queues = 0; | ||
4775 | adapter->num_rx_queues = 0; | ||
4776 | |||
4774 | ixgbe_free_q_vectors(adapter); | 4777 | ixgbe_free_q_vectors(adapter); |
4775 | ixgbe_reset_interrupt_capability(adapter); | 4778 | ixgbe_reset_interrupt_capability(adapter); |
4776 | } | 4779 | } |
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig index cb3d13e4e074..35fda5ac8120 100644 --- a/drivers/net/phy/Kconfig +++ b/drivers/net/phy/Kconfig | |||
@@ -64,7 +64,7 @@ config BCM63XX_PHY | |||
64 | config ICPLUS_PHY | 64 | config ICPLUS_PHY |
65 | tristate "Drivers for ICPlus PHYs" | 65 | tristate "Drivers for ICPlus PHYs" |
66 | ---help--- | 66 | ---help--- |
67 | Currently supports the IP175C PHY. | 67 | Currently supports the IP175C and IP1001 PHYs. |
68 | 68 | ||
69 | config REALTEK_PHY | 69 | config REALTEK_PHY |
70 | tristate "Drivers for Realtek PHYs" | 70 | tristate "Drivers for Realtek PHYs" |
diff --git a/drivers/net/phy/icplus.c b/drivers/net/phy/icplus.c index c1d2d251fe8b..9a09e24c30bc 100644 --- a/drivers/net/phy/icplus.c +++ b/drivers/net/phy/icplus.c | |||
@@ -30,7 +30,7 @@ | |||
30 | #include <asm/irq.h> | 30 | #include <asm/irq.h> |
31 | #include <asm/uaccess.h> | 31 | #include <asm/uaccess.h> |
32 | 32 | ||
33 | MODULE_DESCRIPTION("ICPlus IP175C PHY driver"); | 33 | MODULE_DESCRIPTION("ICPlus IP175C/IC1001 PHY drivers"); |
34 | MODULE_AUTHOR("Michael Barkowski"); | 34 | MODULE_AUTHOR("Michael Barkowski"); |
35 | MODULE_LICENSE("GPL"); | 35 | MODULE_LICENSE("GPL"); |
36 | 36 | ||
@@ -89,6 +89,33 @@ static int ip175c_config_init(struct phy_device *phydev) | |||
89 | return 0; | 89 | return 0; |
90 | } | 90 | } |
91 | 91 | ||
92 | static int ip1001_config_init(struct phy_device *phydev) | ||
93 | { | ||
94 | int err, value; | ||
95 | |||
96 | /* Software Reset PHY */ | ||
97 | value = phy_read(phydev, MII_BMCR); | ||
98 | value |= BMCR_RESET; | ||
99 | err = phy_write(phydev, MII_BMCR, value); | ||
100 | if (err < 0) | ||
101 | return err; | ||
102 | |||
103 | do { | ||
104 | value = phy_read(phydev, MII_BMCR); | ||
105 | } while (value & BMCR_RESET); | ||
106 | |||
107 | /* Additional delay (2ns) used to adjust RX clock phase | ||
108 | * at GMII/ RGMII interface */ | ||
109 | value = phy_read(phydev, 16); | ||
110 | value |= 0x3; | ||
111 | |||
112 | err = phy_write(phydev, 16, value); | ||
113 | if (err < 0) | ||
114 | return err; | ||
115 | |||
116 | return err; | ||
117 | } | ||
118 | |||
92 | static int ip175c_read_status(struct phy_device *phydev) | 119 | static int ip175c_read_status(struct phy_device *phydev) |
93 | { | 120 | { |
94 | if (phydev->addr == 4) /* WAN port */ | 121 | if (phydev->addr == 4) /* WAN port */ |
@@ -121,21 +148,43 @@ static struct phy_driver ip175c_driver = { | |||
121 | .driver = { .owner = THIS_MODULE,}, | 148 | .driver = { .owner = THIS_MODULE,}, |
122 | }; | 149 | }; |
123 | 150 | ||
124 | static int __init ip175c_init(void) | 151 | static struct phy_driver ip1001_driver = { |
152 | .phy_id = 0x02430d90, | ||
153 | .name = "ICPlus IP1001", | ||
154 | .phy_id_mask = 0x0ffffff0, | ||
155 | .features = PHY_GBIT_FEATURES | SUPPORTED_Pause | | ||
156 | SUPPORTED_Asym_Pause, | ||
157 | .config_init = &ip1001_config_init, | ||
158 | .config_aneg = &genphy_config_aneg, | ||
159 | .read_status = &genphy_read_status, | ||
160 | .suspend = genphy_suspend, | ||
161 | .resume = genphy_resume, | ||
162 | .driver = { .owner = THIS_MODULE,}, | ||
163 | }; | ||
164 | |||
165 | static int __init icplus_init(void) | ||
125 | { | 166 | { |
167 | int ret = 0; | ||
168 | |||
169 | ret = phy_driver_register(&ip1001_driver); | ||
170 | if (ret < 0) | ||
171 | return -ENODEV; | ||
172 | |||
126 | return phy_driver_register(&ip175c_driver); | 173 | return phy_driver_register(&ip175c_driver); |
127 | } | 174 | } |
128 | 175 | ||
129 | static void __exit ip175c_exit(void) | 176 | static void __exit icplus_exit(void) |
130 | { | 177 | { |
178 | phy_driver_unregister(&ip1001_driver); | ||
131 | phy_driver_unregister(&ip175c_driver); | 179 | phy_driver_unregister(&ip175c_driver); |
132 | } | 180 | } |
133 | 181 | ||
134 | module_init(ip175c_init); | 182 | module_init(icplus_init); |
135 | module_exit(ip175c_exit); | 183 | module_exit(icplus_exit); |
136 | 184 | ||
137 | static struct mdio_device_id __maybe_unused icplus_tbl[] = { | 185 | static struct mdio_device_id __maybe_unused icplus_tbl[] = { |
138 | { 0x02430d80, 0x0ffffff0 }, | 186 | { 0x02430d80, 0x0ffffff0 }, |
187 | { 0x02430d90, 0x0ffffff0 }, | ||
139 | { } | 188 | { } |
140 | }; | 189 | }; |
141 | 190 | ||
diff --git a/drivers/net/pppoe.c b/drivers/net/pppoe.c index d72fb0519a2a..78c0e3c9b2b5 100644 --- a/drivers/net/pppoe.c +++ b/drivers/net/pppoe.c | |||
@@ -948,7 +948,7 @@ static int __pppoe_xmit(struct sock *sk, struct sk_buff *skb) | |||
948 | 948 | ||
949 | abort: | 949 | abort: |
950 | kfree_skb(skb); | 950 | kfree_skb(skb); |
951 | return 0; | 951 | return 1; |
952 | } | 952 | } |
953 | 953 | ||
954 | /************************************************************************ | 954 | /************************************************************************ |
diff --git a/drivers/net/qlge/qlge.h b/drivers/net/qlge/qlge.h index 22821398fc63..9787dff90d3f 100644 --- a/drivers/net/qlge/qlge.h +++ b/drivers/net/qlge/qlge.h | |||
@@ -2083,6 +2083,7 @@ struct ql_adapter { | |||
2083 | u32 mailbox_in; | 2083 | u32 mailbox_in; |
2084 | u32 mailbox_out; | 2084 | u32 mailbox_out; |
2085 | struct mbox_params idc_mbc; | 2085 | struct mbox_params idc_mbc; |
2086 | struct mutex mpi_mutex; | ||
2086 | 2087 | ||
2087 | int tx_ring_size; | 2088 | int tx_ring_size; |
2088 | int rx_ring_size; | 2089 | int rx_ring_size; |
diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c index 528eaef5308f..2555b1d34f34 100644 --- a/drivers/net/qlge/qlge_main.c +++ b/drivers/net/qlge/qlge_main.c | |||
@@ -4629,6 +4629,7 @@ static int __devinit ql_init_device(struct pci_dev *pdev, | |||
4629 | INIT_DELAYED_WORK(&qdev->mpi_idc_work, ql_mpi_idc_work); | 4629 | INIT_DELAYED_WORK(&qdev->mpi_idc_work, ql_mpi_idc_work); |
4630 | INIT_DELAYED_WORK(&qdev->mpi_core_to_log, ql_mpi_core_to_log); | 4630 | INIT_DELAYED_WORK(&qdev->mpi_core_to_log, ql_mpi_core_to_log); |
4631 | init_completion(&qdev->ide_completion); | 4631 | init_completion(&qdev->ide_completion); |
4632 | mutex_init(&qdev->mpi_mutex); | ||
4632 | 4633 | ||
4633 | if (!cards_found) { | 4634 | if (!cards_found) { |
4634 | dev_info(&pdev->dev, "%s\n", DRV_STRING); | 4635 | dev_info(&pdev->dev, "%s\n", DRV_STRING); |
diff --git a/drivers/net/qlge/qlge_mpi.c b/drivers/net/qlge/qlge_mpi.c index 0e7c7c7ee164..a2e919bcb3c6 100644 --- a/drivers/net/qlge/qlge_mpi.c +++ b/drivers/net/qlge/qlge_mpi.c | |||
@@ -534,6 +534,7 @@ static int ql_mailbox_command(struct ql_adapter *qdev, struct mbox_params *mbcp) | |||
534 | int status; | 534 | int status; |
535 | unsigned long count; | 535 | unsigned long count; |
536 | 536 | ||
537 | mutex_lock(&qdev->mpi_mutex); | ||
537 | 538 | ||
538 | /* Begin polled mode for MPI */ | 539 | /* Begin polled mode for MPI */ |
539 | ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16)); | 540 | ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16)); |
@@ -603,6 +604,7 @@ done: | |||
603 | end: | 604 | end: |
604 | /* End polled mode for MPI */ | 605 | /* End polled mode for MPI */ |
605 | ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16) | INTR_MASK_PI); | 606 | ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16) | INTR_MASK_PI); |
607 | mutex_unlock(&qdev->mpi_mutex); | ||
606 | return status; | 608 | return status; |
607 | } | 609 | } |
608 | 610 | ||
@@ -1099,9 +1101,7 @@ int ql_wait_fifo_empty(struct ql_adapter *qdev) | |||
1099 | static int ql_set_port_cfg(struct ql_adapter *qdev) | 1101 | static int ql_set_port_cfg(struct ql_adapter *qdev) |
1100 | { | 1102 | { |
1101 | int status; | 1103 | int status; |
1102 | rtnl_lock(); | ||
1103 | status = ql_mb_set_port_cfg(qdev); | 1104 | status = ql_mb_set_port_cfg(qdev); |
1104 | rtnl_unlock(); | ||
1105 | if (status) | 1105 | if (status) |
1106 | return status; | 1106 | return status; |
1107 | status = ql_idc_wait(qdev); | 1107 | status = ql_idc_wait(qdev); |
@@ -1122,9 +1122,7 @@ void ql_mpi_port_cfg_work(struct work_struct *work) | |||
1122 | container_of(work, struct ql_adapter, mpi_port_cfg_work.work); | 1122 | container_of(work, struct ql_adapter, mpi_port_cfg_work.work); |
1123 | int status; | 1123 | int status; |
1124 | 1124 | ||
1125 | rtnl_lock(); | ||
1126 | status = ql_mb_get_port_cfg(qdev); | 1125 | status = ql_mb_get_port_cfg(qdev); |
1127 | rtnl_unlock(); | ||
1128 | if (status) { | 1126 | if (status) { |
1129 | netif_err(qdev, drv, qdev->ndev, | 1127 | netif_err(qdev, drv, qdev->ndev, |
1130 | "Bug: Failed to get port config data.\n"); | 1128 | "Bug: Failed to get port config data.\n"); |
@@ -1167,7 +1165,6 @@ void ql_mpi_idc_work(struct work_struct *work) | |||
1167 | u32 aen; | 1165 | u32 aen; |
1168 | int timeout; | 1166 | int timeout; |
1169 | 1167 | ||
1170 | rtnl_lock(); | ||
1171 | aen = mbcp->mbox_out[1] >> 16; | 1168 | aen = mbcp->mbox_out[1] >> 16; |
1172 | timeout = (mbcp->mbox_out[1] >> 8) & 0xf; | 1169 | timeout = (mbcp->mbox_out[1] >> 8) & 0xf; |
1173 | 1170 | ||
@@ -1231,7 +1228,6 @@ void ql_mpi_idc_work(struct work_struct *work) | |||
1231 | } | 1228 | } |
1232 | break; | 1229 | break; |
1233 | } | 1230 | } |
1234 | rtnl_unlock(); | ||
1235 | } | 1231 | } |
1236 | 1232 | ||
1237 | void ql_mpi_work(struct work_struct *work) | 1233 | void ql_mpi_work(struct work_struct *work) |
@@ -1242,7 +1238,7 @@ void ql_mpi_work(struct work_struct *work) | |||
1242 | struct mbox_params *mbcp = &mbc; | 1238 | struct mbox_params *mbcp = &mbc; |
1243 | int err = 0; | 1239 | int err = 0; |
1244 | 1240 | ||
1245 | rtnl_lock(); | 1241 | mutex_lock(&qdev->mpi_mutex); |
1246 | /* Begin polled mode for MPI */ | 1242 | /* Begin polled mode for MPI */ |
1247 | ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16)); | 1243 | ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16)); |
1248 | 1244 | ||
@@ -1259,7 +1255,7 @@ void ql_mpi_work(struct work_struct *work) | |||
1259 | 1255 | ||
1260 | /* End polled mode for MPI */ | 1256 | /* End polled mode for MPI */ |
1261 | ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16) | INTR_MASK_PI); | 1257 | ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16) | INTR_MASK_PI); |
1262 | rtnl_unlock(); | 1258 | mutex_unlock(&qdev->mpi_mutex); |
1263 | ql_enable_completion_interrupt(qdev, 0); | 1259 | ql_enable_completion_interrupt(qdev, 0); |
1264 | } | 1260 | } |
1265 | 1261 | ||
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 7d33ef4bcb4a..53b13deade95 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c | |||
@@ -744,26 +744,36 @@ static void rtl8169_xmii_reset_enable(void __iomem *ioaddr) | |||
744 | mdio_write(ioaddr, MII_BMCR, val & 0xffff); | 744 | mdio_write(ioaddr, MII_BMCR, val & 0xffff); |
745 | } | 745 | } |
746 | 746 | ||
747 | static void rtl8169_check_link_status(struct net_device *dev, | 747 | static void __rtl8169_check_link_status(struct net_device *dev, |
748 | struct rtl8169_private *tp, | 748 | struct rtl8169_private *tp, |
749 | void __iomem *ioaddr) | 749 | void __iomem *ioaddr, |
750 | bool pm) | ||
750 | { | 751 | { |
751 | unsigned long flags; | 752 | unsigned long flags; |
752 | 753 | ||
753 | spin_lock_irqsave(&tp->lock, flags); | 754 | spin_lock_irqsave(&tp->lock, flags); |
754 | if (tp->link_ok(ioaddr)) { | 755 | if (tp->link_ok(ioaddr)) { |
755 | /* This is to cancel a scheduled suspend if there's one. */ | 756 | /* This is to cancel a scheduled suspend if there's one. */ |
756 | pm_request_resume(&tp->pci_dev->dev); | 757 | if (pm) |
758 | pm_request_resume(&tp->pci_dev->dev); | ||
757 | netif_carrier_on(dev); | 759 | netif_carrier_on(dev); |
758 | netif_info(tp, ifup, dev, "link up\n"); | 760 | netif_info(tp, ifup, dev, "link up\n"); |
759 | } else { | 761 | } else { |
760 | netif_carrier_off(dev); | 762 | netif_carrier_off(dev); |
761 | netif_info(tp, ifdown, dev, "link down\n"); | 763 | netif_info(tp, ifdown, dev, "link down\n"); |
762 | pm_schedule_suspend(&tp->pci_dev->dev, 100); | 764 | if (pm) |
765 | pm_schedule_suspend(&tp->pci_dev->dev, 100); | ||
763 | } | 766 | } |
764 | spin_unlock_irqrestore(&tp->lock, flags); | 767 | spin_unlock_irqrestore(&tp->lock, flags); |
765 | } | 768 | } |
766 | 769 | ||
770 | static void rtl8169_check_link_status(struct net_device *dev, | ||
771 | struct rtl8169_private *tp, | ||
772 | void __iomem *ioaddr) | ||
773 | { | ||
774 | __rtl8169_check_link_status(dev, tp, ioaddr, false); | ||
775 | } | ||
776 | |||
767 | #define WAKE_ANY (WAKE_PHY | WAKE_MAGIC | WAKE_UCAST | WAKE_BCAST | WAKE_MCAST) | 777 | #define WAKE_ANY (WAKE_PHY | WAKE_MAGIC | WAKE_UCAST | WAKE_BCAST | WAKE_MCAST) |
768 | 778 | ||
769 | static u32 __rtl8169_get_wol(struct rtl8169_private *tp) | 779 | static u32 __rtl8169_get_wol(struct rtl8169_private *tp) |
@@ -4600,7 +4610,7 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance) | |||
4600 | } | 4610 | } |
4601 | 4611 | ||
4602 | if (status & LinkChg) | 4612 | if (status & LinkChg) |
4603 | rtl8169_check_link_status(dev, tp, ioaddr); | 4613 | __rtl8169_check_link_status(dev, tp, ioaddr, true); |
4604 | 4614 | ||
4605 | /* We need to see the lastest version of tp->intr_mask to | 4615 | /* We need to see the lastest version of tp->intr_mask to |
4606 | * avoid ignoring an MSI interrupt and having to wait for | 4616 | * avoid ignoring an MSI interrupt and having to wait for |
@@ -4890,11 +4900,7 @@ static int rtl8169_runtime_idle(struct device *device) | |||
4890 | struct net_device *dev = pci_get_drvdata(pdev); | 4900 | struct net_device *dev = pci_get_drvdata(pdev); |
4891 | struct rtl8169_private *tp = netdev_priv(dev); | 4901 | struct rtl8169_private *tp = netdev_priv(dev); |
4892 | 4902 | ||
4893 | if (!tp->TxDescArray) | 4903 | return tp->TxDescArray ? -EBUSY : 0; |
4894 | return 0; | ||
4895 | |||
4896 | rtl8169_check_link_status(dev, tp, tp->mmio_addr); | ||
4897 | return -EBUSY; | ||
4898 | } | 4904 | } |
4899 | 4905 | ||
4900 | static const struct dev_pm_ops rtl8169_pm_ops = { | 4906 | static const struct dev_pm_ops rtl8169_pm_ops = { |
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c index 05df20e47976..fb83cdd94643 100644 --- a/drivers/net/sfc/efx.c +++ b/drivers/net/sfc/efx.c | |||
@@ -197,7 +197,9 @@ MODULE_PARM_DESC(debug, "Bitmapped debugging message enable value"); | |||
197 | 197 | ||
198 | static void efx_remove_channels(struct efx_nic *efx); | 198 | static void efx_remove_channels(struct efx_nic *efx); |
199 | static void efx_remove_port(struct efx_nic *efx); | 199 | static void efx_remove_port(struct efx_nic *efx); |
200 | static void efx_init_napi(struct efx_nic *efx); | ||
200 | static void efx_fini_napi(struct efx_nic *efx); | 201 | static void efx_fini_napi(struct efx_nic *efx); |
202 | static void efx_fini_napi_channel(struct efx_channel *channel); | ||
201 | static void efx_fini_struct(struct efx_nic *efx); | 203 | static void efx_fini_struct(struct efx_nic *efx); |
202 | static void efx_start_all(struct efx_nic *efx); | 204 | static void efx_start_all(struct efx_nic *efx); |
203 | static void efx_stop_all(struct efx_nic *efx); | 205 | static void efx_stop_all(struct efx_nic *efx); |
@@ -335,8 +337,10 @@ void efx_process_channel_now(struct efx_channel *channel) | |||
335 | 337 | ||
336 | /* Disable interrupts and wait for ISRs to complete */ | 338 | /* Disable interrupts and wait for ISRs to complete */ |
337 | efx_nic_disable_interrupts(efx); | 339 | efx_nic_disable_interrupts(efx); |
338 | if (efx->legacy_irq) | 340 | if (efx->legacy_irq) { |
339 | synchronize_irq(efx->legacy_irq); | 341 | synchronize_irq(efx->legacy_irq); |
342 | efx->legacy_irq_enabled = false; | ||
343 | } | ||
340 | if (channel->irq) | 344 | if (channel->irq) |
341 | synchronize_irq(channel->irq); | 345 | synchronize_irq(channel->irq); |
342 | 346 | ||
@@ -351,6 +355,8 @@ void efx_process_channel_now(struct efx_channel *channel) | |||
351 | efx_channel_processed(channel); | 355 | efx_channel_processed(channel); |
352 | 356 | ||
353 | napi_enable(&channel->napi_str); | 357 | napi_enable(&channel->napi_str); |
358 | if (efx->legacy_irq) | ||
359 | efx->legacy_irq_enabled = true; | ||
354 | efx_nic_enable_interrupts(efx); | 360 | efx_nic_enable_interrupts(efx); |
355 | } | 361 | } |
356 | 362 | ||
@@ -426,6 +432,7 @@ efx_alloc_channel(struct efx_nic *efx, int i, struct efx_channel *old_channel) | |||
426 | 432 | ||
427 | *channel = *old_channel; | 433 | *channel = *old_channel; |
428 | 434 | ||
435 | channel->napi_dev = NULL; | ||
429 | memset(&channel->eventq, 0, sizeof(channel->eventq)); | 436 | memset(&channel->eventq, 0, sizeof(channel->eventq)); |
430 | 437 | ||
431 | rx_queue = &channel->rx_queue; | 438 | rx_queue = &channel->rx_queue; |
@@ -736,9 +743,13 @@ efx_realloc_channels(struct efx_nic *efx, u32 rxq_entries, u32 txq_entries) | |||
736 | if (rc) | 743 | if (rc) |
737 | goto rollback; | 744 | goto rollback; |
738 | 745 | ||
746 | efx_init_napi(efx); | ||
747 | |||
739 | /* Destroy old channels */ | 748 | /* Destroy old channels */ |
740 | for (i = 0; i < efx->n_channels; i++) | 749 | for (i = 0; i < efx->n_channels; i++) { |
750 | efx_fini_napi_channel(other_channel[i]); | ||
741 | efx_remove_channel(other_channel[i]); | 751 | efx_remove_channel(other_channel[i]); |
752 | } | ||
742 | out: | 753 | out: |
743 | /* Free unused channel structures */ | 754 | /* Free unused channel structures */ |
744 | for (i = 0; i < efx->n_channels; i++) | 755 | for (i = 0; i < efx->n_channels; i++) |
@@ -1400,6 +1411,8 @@ static void efx_start_all(struct efx_nic *efx) | |||
1400 | efx_start_channel(channel); | 1411 | efx_start_channel(channel); |
1401 | } | 1412 | } |
1402 | 1413 | ||
1414 | if (efx->legacy_irq) | ||
1415 | efx->legacy_irq_enabled = true; | ||
1403 | efx_nic_enable_interrupts(efx); | 1416 | efx_nic_enable_interrupts(efx); |
1404 | 1417 | ||
1405 | /* Switch to event based MCDI completions after enabling interrupts. | 1418 | /* Switch to event based MCDI completions after enabling interrupts. |
@@ -1460,8 +1473,10 @@ static void efx_stop_all(struct efx_nic *efx) | |||
1460 | 1473 | ||
1461 | /* Disable interrupts and wait for ISR to complete */ | 1474 | /* Disable interrupts and wait for ISR to complete */ |
1462 | efx_nic_disable_interrupts(efx); | 1475 | efx_nic_disable_interrupts(efx); |
1463 | if (efx->legacy_irq) | 1476 | if (efx->legacy_irq) { |
1464 | synchronize_irq(efx->legacy_irq); | 1477 | synchronize_irq(efx->legacy_irq); |
1478 | efx->legacy_irq_enabled = false; | ||
1479 | } | ||
1465 | efx_for_each_channel(channel, efx) { | 1480 | efx_for_each_channel(channel, efx) { |
1466 | if (channel->irq) | 1481 | if (channel->irq) |
1467 | synchronize_irq(channel->irq); | 1482 | synchronize_irq(channel->irq); |
@@ -1593,7 +1608,7 @@ static int efx_ioctl(struct net_device *net_dev, struct ifreq *ifr, int cmd) | |||
1593 | * | 1608 | * |
1594 | **************************************************************************/ | 1609 | **************************************************************************/ |
1595 | 1610 | ||
1596 | static int efx_init_napi(struct efx_nic *efx) | 1611 | static void efx_init_napi(struct efx_nic *efx) |
1597 | { | 1612 | { |
1598 | struct efx_channel *channel; | 1613 | struct efx_channel *channel; |
1599 | 1614 | ||
@@ -1602,18 +1617,21 @@ static int efx_init_napi(struct efx_nic *efx) | |||
1602 | netif_napi_add(channel->napi_dev, &channel->napi_str, | 1617 | netif_napi_add(channel->napi_dev, &channel->napi_str, |
1603 | efx_poll, napi_weight); | 1618 | efx_poll, napi_weight); |
1604 | } | 1619 | } |
1605 | return 0; | 1620 | } |
1621 | |||
1622 | static void efx_fini_napi_channel(struct efx_channel *channel) | ||
1623 | { | ||
1624 | if (channel->napi_dev) | ||
1625 | netif_napi_del(&channel->napi_str); | ||
1626 | channel->napi_dev = NULL; | ||
1606 | } | 1627 | } |
1607 | 1628 | ||
1608 | static void efx_fini_napi(struct efx_nic *efx) | 1629 | static void efx_fini_napi(struct efx_nic *efx) |
1609 | { | 1630 | { |
1610 | struct efx_channel *channel; | 1631 | struct efx_channel *channel; |
1611 | 1632 | ||
1612 | efx_for_each_channel(channel, efx) { | 1633 | efx_for_each_channel(channel, efx) |
1613 | if (channel->napi_dev) | 1634 | efx_fini_napi_channel(channel); |
1614 | netif_napi_del(&channel->napi_str); | ||
1615 | channel->napi_dev = NULL; | ||
1616 | } | ||
1617 | } | 1635 | } |
1618 | 1636 | ||
1619 | /************************************************************************** | 1637 | /************************************************************************** |
@@ -2335,9 +2353,7 @@ static int efx_pci_probe_main(struct efx_nic *efx) | |||
2335 | if (rc) | 2353 | if (rc) |
2336 | goto fail1; | 2354 | goto fail1; |
2337 | 2355 | ||
2338 | rc = efx_init_napi(efx); | 2356 | efx_init_napi(efx); |
2339 | if (rc) | ||
2340 | goto fail2; | ||
2341 | 2357 | ||
2342 | rc = efx->type->init(efx); | 2358 | rc = efx->type->init(efx); |
2343 | if (rc) { | 2359 | if (rc) { |
@@ -2368,7 +2384,6 @@ static int efx_pci_probe_main(struct efx_nic *efx) | |||
2368 | efx->type->fini(efx); | 2384 | efx->type->fini(efx); |
2369 | fail3: | 2385 | fail3: |
2370 | efx_fini_napi(efx); | 2386 | efx_fini_napi(efx); |
2371 | fail2: | ||
2372 | efx_remove_all(efx); | 2387 | efx_remove_all(efx); |
2373 | fail1: | 2388 | fail1: |
2374 | return rc; | 2389 | return rc; |
diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index 0a7e26d73b52..b137c889152b 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h | |||
@@ -621,6 +621,7 @@ struct efx_filter_state; | |||
621 | * @pci_dev: The PCI device | 621 | * @pci_dev: The PCI device |
622 | * @type: Controller type attributes | 622 | * @type: Controller type attributes |
623 | * @legacy_irq: IRQ number | 623 | * @legacy_irq: IRQ number |
624 | * @legacy_irq_enabled: Are IRQs enabled on NIC (INT_EN_KER register)? | ||
624 | * @workqueue: Workqueue for port reconfigures and the HW monitor. | 625 | * @workqueue: Workqueue for port reconfigures and the HW monitor. |
625 | * Work items do not hold and must not acquire RTNL. | 626 | * Work items do not hold and must not acquire RTNL. |
626 | * @workqueue_name: Name of workqueue | 627 | * @workqueue_name: Name of workqueue |
@@ -709,6 +710,7 @@ struct efx_nic { | |||
709 | struct pci_dev *pci_dev; | 710 | struct pci_dev *pci_dev; |
710 | const struct efx_nic_type *type; | 711 | const struct efx_nic_type *type; |
711 | int legacy_irq; | 712 | int legacy_irq; |
713 | bool legacy_irq_enabled; | ||
712 | struct workqueue_struct *workqueue; | 714 | struct workqueue_struct *workqueue; |
713 | char workqueue_name[16]; | 715 | char workqueue_name[16]; |
714 | struct work_struct reset_work; | 716 | struct work_struct reset_work; |
diff --git a/drivers/net/sfc/nic.c b/drivers/net/sfc/nic.c index 41c36b9a4244..67cb0c96838c 100644 --- a/drivers/net/sfc/nic.c +++ b/drivers/net/sfc/nic.c | |||
@@ -1418,6 +1418,12 @@ static irqreturn_t efx_legacy_interrupt(int irq, void *dev_id) | |||
1418 | u32 queues; | 1418 | u32 queues; |
1419 | int syserr; | 1419 | int syserr; |
1420 | 1420 | ||
1421 | /* Could this be ours? If interrupts are disabled then the | ||
1422 | * channel state may not be valid. | ||
1423 | */ | ||
1424 | if (!efx->legacy_irq_enabled) | ||
1425 | return result; | ||
1426 | |||
1421 | /* Read the ISR which also ACKs the interrupts */ | 1427 | /* Read the ISR which also ACKs the interrupts */ |
1422 | efx_readd(efx, ®, FR_BZ_INT_ISR0); | 1428 | efx_readd(efx, ®, FR_BZ_INT_ISR0); |
1423 | queues = EFX_EXTRACT_DWORD(reg, 0, 31); | 1429 | queues = EFX_EXTRACT_DWORD(reg, 0, 31); |
diff --git a/drivers/net/stmmac/stmmac_main.c b/drivers/net/stmmac/stmmac_main.c index 06bc6034ce81..2114837809e7 100644 --- a/drivers/net/stmmac/stmmac_main.c +++ b/drivers/net/stmmac/stmmac_main.c | |||
@@ -1509,6 +1509,8 @@ static int stmmac_probe(struct net_device *dev) | |||
1509 | pr_warning("\tno valid MAC address;" | 1509 | pr_warning("\tno valid MAC address;" |
1510 | "please, use ifconfig or nwhwconfig!\n"); | 1510 | "please, use ifconfig or nwhwconfig!\n"); |
1511 | 1511 | ||
1512 | spin_lock_init(&priv->lock); | ||
1513 | |||
1512 | ret = register_netdev(dev); | 1514 | ret = register_netdev(dev); |
1513 | if (ret) { | 1515 | if (ret) { |
1514 | pr_err("%s: ERROR %i registering the device\n", | 1516 | pr_err("%s: ERROR %i registering the device\n", |
@@ -1520,8 +1522,6 @@ static int stmmac_probe(struct net_device *dev) | |||
1520 | dev->name, (dev->features & NETIF_F_SG) ? "on" : "off", | 1522 | dev->name, (dev->features & NETIF_F_SG) ? "on" : "off", |
1521 | (dev->features & NETIF_F_HW_CSUM) ? "on" : "off"); | 1523 | (dev->features & NETIF_F_HW_CSUM) ? "on" : "off"); |
1522 | 1524 | ||
1523 | spin_lock_init(&priv->lock); | ||
1524 | |||
1525 | return ret; | 1525 | return ret; |
1526 | } | 1526 | } |
1527 | 1527 | ||
diff --git a/drivers/net/tulip/dmfe.c b/drivers/net/tulip/dmfe.c index a9f7d5d1a269..7064e035757a 100644 --- a/drivers/net/tulip/dmfe.c +++ b/drivers/net/tulip/dmfe.c | |||
@@ -688,9 +688,6 @@ static netdev_tx_t dmfe_start_xmit(struct sk_buff *skb, | |||
688 | 688 | ||
689 | DMFE_DBUG(0, "dmfe_start_xmit", 0); | 689 | DMFE_DBUG(0, "dmfe_start_xmit", 0); |
690 | 690 | ||
691 | /* Resource flag check */ | ||
692 | netif_stop_queue(dev); | ||
693 | |||
694 | /* Too large packet check */ | 691 | /* Too large packet check */ |
695 | if (skb->len > MAX_PACKET_SIZE) { | 692 | if (skb->len > MAX_PACKET_SIZE) { |
696 | pr_err("big packet = %d\n", (u16)skb->len); | 693 | pr_err("big packet = %d\n", (u16)skb->len); |
@@ -698,6 +695,9 @@ static netdev_tx_t dmfe_start_xmit(struct sk_buff *skb, | |||
698 | return NETDEV_TX_OK; | 695 | return NETDEV_TX_OK; |
699 | } | 696 | } |
700 | 697 | ||
698 | /* Resource flag check */ | ||
699 | netif_stop_queue(dev); | ||
700 | |||
701 | spin_lock_irqsave(&db->lock, flags); | 701 | spin_lock_irqsave(&db->lock, flags); |
702 | 702 | ||
703 | /* No Tx resource check, it never happen nromally */ | 703 | /* No Tx resource check, it never happen nromally */ |
diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index 62e9e8dc8190..812edf85d6d3 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c | |||
@@ -958,10 +958,6 @@ static void packetizeRx(struct hso_net *odev, unsigned char *ip_pkt, | |||
958 | /* Packet is complete. Inject into stack. */ | 958 | /* Packet is complete. Inject into stack. */ |
959 | /* We have IP packet here */ | 959 | /* We have IP packet here */ |
960 | odev->skb_rx_buf->protocol = cpu_to_be16(ETH_P_IP); | 960 | odev->skb_rx_buf->protocol = cpu_to_be16(ETH_P_IP); |
961 | /* don't check it */ | ||
962 | odev->skb_rx_buf->ip_summed = | ||
963 | CHECKSUM_UNNECESSARY; | ||
964 | |||
965 | skb_reset_mac_header(odev->skb_rx_buf); | 961 | skb_reset_mac_header(odev->skb_rx_buf); |
966 | 962 | ||
967 | /* Ship it off to the kernel */ | 963 | /* Ship it off to the kernel */ |
diff --git a/drivers/net/wan/hd64572.c b/drivers/net/wan/hd64572.c index ea476cbd38b5..e305274f83fb 100644 --- a/drivers/net/wan/hd64572.c +++ b/drivers/net/wan/hd64572.c | |||
@@ -293,6 +293,7 @@ static inline void sca_tx_done(port_t *port) | |||
293 | struct net_device *dev = port->netdev; | 293 | struct net_device *dev = port->netdev; |
294 | card_t* card = port->card; | 294 | card_t* card = port->card; |
295 | u8 stat; | 295 | u8 stat; |
296 | unsigned count = 0; | ||
296 | 297 | ||
297 | spin_lock(&port->lock); | 298 | spin_lock(&port->lock); |
298 | 299 | ||
@@ -316,10 +317,12 @@ static inline void sca_tx_done(port_t *port) | |||
316 | dev->stats.tx_bytes += readw(&desc->len); | 317 | dev->stats.tx_bytes += readw(&desc->len); |
317 | } | 318 | } |
318 | writeb(0, &desc->stat); /* Free descriptor */ | 319 | writeb(0, &desc->stat); /* Free descriptor */ |
320 | count++; | ||
319 | port->txlast = (port->txlast + 1) % card->tx_ring_buffers; | 321 | port->txlast = (port->txlast + 1) % card->tx_ring_buffers; |
320 | } | 322 | } |
321 | 323 | ||
322 | netif_wake_queue(dev); | 324 | if (count) |
325 | netif_wake_queue(dev); | ||
323 | spin_unlock(&port->lock); | 326 | spin_unlock(&port->lock); |
324 | } | 327 | } |
325 | 328 | ||
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 8251946842e6..42ed923cdb1a 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c | |||
@@ -1917,7 +1917,8 @@ ath5k_beacon_send(struct ath5k_softc *sc) | |||
1917 | sc->bmisscount = 0; | 1917 | sc->bmisscount = 0; |
1918 | } | 1918 | } |
1919 | 1919 | ||
1920 | if (sc->opmode == NL80211_IFTYPE_AP && sc->num_ap_vifs > 1) { | 1920 | if ((sc->opmode == NL80211_IFTYPE_AP && sc->num_ap_vifs > 1) || |
1921 | sc->opmode == NL80211_IFTYPE_MESH_POINT) { | ||
1921 | u64 tsf = ath5k_hw_get_tsf64(ah); | 1922 | u64 tsf = ath5k_hw_get_tsf64(ah); |
1922 | u32 tsftu = TSF_TO_TU(tsf); | 1923 | u32 tsftu = TSF_TO_TU(tsf); |
1923 | int slot = ((tsftu % sc->bintval) * ATH_BCBUF) / sc->bintval; | 1924 | int slot = ((tsftu % sc->bintval) * ATH_BCBUF) / sc->bintval; |
@@ -1949,8 +1950,9 @@ ath5k_beacon_send(struct ath5k_softc *sc) | |||
1949 | /* NB: hw still stops DMA, so proceed */ | 1950 | /* NB: hw still stops DMA, so proceed */ |
1950 | } | 1951 | } |
1951 | 1952 | ||
1952 | /* refresh the beacon for AP mode */ | 1953 | /* refresh the beacon for AP or MESH mode */ |
1953 | if (sc->opmode == NL80211_IFTYPE_AP) | 1954 | if (sc->opmode == NL80211_IFTYPE_AP || |
1955 | sc->opmode == NL80211_IFTYPE_MESH_POINT) | ||
1954 | ath5k_beacon_update(sc->hw, vif); | 1956 | ath5k_beacon_update(sc->hw, vif); |
1955 | 1957 | ||
1956 | ath5k_hw_set_txdp(ah, sc->bhalq, bf->daddr); | 1958 | ath5k_hw_set_txdp(ah, sc->bhalq, bf->daddr); |
@@ -2851,7 +2853,8 @@ static int ath5k_add_interface(struct ieee80211_hw *hw, | |||
2851 | 2853 | ||
2852 | /* Assign the vap/adhoc to a beacon xmit slot. */ | 2854 | /* Assign the vap/adhoc to a beacon xmit slot. */ |
2853 | if ((avf->opmode == NL80211_IFTYPE_AP) || | 2855 | if ((avf->opmode == NL80211_IFTYPE_AP) || |
2854 | (avf->opmode == NL80211_IFTYPE_ADHOC)) { | 2856 | (avf->opmode == NL80211_IFTYPE_ADHOC) || |
2857 | (avf->opmode == NL80211_IFTYPE_MESH_POINT)) { | ||
2855 | int slot; | 2858 | int slot; |
2856 | 2859 | ||
2857 | WARN_ON(list_empty(&sc->bcbuf)); | 2860 | WARN_ON(list_empty(&sc->bcbuf)); |
@@ -2870,7 +2873,7 @@ static int ath5k_add_interface(struct ieee80211_hw *hw, | |||
2870 | sc->bslot[avf->bslot] = vif; | 2873 | sc->bslot[avf->bslot] = vif; |
2871 | if (avf->opmode == NL80211_IFTYPE_AP) | 2874 | if (avf->opmode == NL80211_IFTYPE_AP) |
2872 | sc->num_ap_vifs++; | 2875 | sc->num_ap_vifs++; |
2873 | else | 2876 | else if (avf->opmode == NL80211_IFTYPE_ADHOC) |
2874 | sc->num_adhoc_vifs++; | 2877 | sc->num_adhoc_vifs++; |
2875 | } | 2878 | } |
2876 | 2879 | ||
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index c4182359bee4..a7b82f0085d2 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | |||
@@ -55,6 +55,8 @@ | |||
55 | #define SUB_NUM_CTL_MODES_AT_5G_40 2 /* excluding HT40, EXT-OFDM */ | 55 | #define SUB_NUM_CTL_MODES_AT_5G_40 2 /* excluding HT40, EXT-OFDM */ |
56 | #define SUB_NUM_CTL_MODES_AT_2G_40 3 /* excluding HT40, EXT-OFDM, EXT-CCK */ | 56 | #define SUB_NUM_CTL_MODES_AT_2G_40 3 /* excluding HT40, EXT-OFDM, EXT-CCK */ |
57 | 57 | ||
58 | #define CTL(_tpower, _flag) ((_tpower) | ((_flag) << 6)) | ||
59 | |||
58 | static const struct ar9300_eeprom ar9300_default = { | 60 | static const struct ar9300_eeprom ar9300_default = { |
59 | .eepromVersion = 2, | 61 | .eepromVersion = 2, |
60 | .templateVersion = 2, | 62 | .templateVersion = 2, |
@@ -290,20 +292,21 @@ static const struct ar9300_eeprom ar9300_default = { | |||
290 | } | 292 | } |
291 | }, | 293 | }, |
292 | .ctlPowerData_2G = { | 294 | .ctlPowerData_2G = { |
293 | { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, | 295 | { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, |
294 | { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, | 296 | { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, |
295 | { { {60, 1}, {60, 0}, {60, 0}, {60, 1} } }, | 297 | { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } }, |
296 | 298 | ||
297 | { { {60, 1}, {60, 0}, {0, 0}, {0, 0} } }, | 299 | { { CTL(60, 1), CTL(60, 0), CTL(0, 0), CTL(0, 0) } }, |
298 | { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, | 300 | { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, |
299 | { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, | 301 | { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, |
300 | 302 | ||
301 | { { {60, 0}, {60, 1}, {60, 1}, {60, 0} } }, | 303 | { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0) } }, |
302 | { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, | 304 | { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, |
303 | { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, | 305 | { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, |
304 | 306 | ||
305 | { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, | 307 | { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, |
306 | { { {60, 0}, {60, 1}, {60, 1}, {60, 1} } }, | 308 | { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } }, |
309 | { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } }, | ||
307 | }, | 310 | }, |
308 | .modalHeader5G = { | 311 | .modalHeader5G = { |
309 | /* 4 idle,t1,t2,b (4 bits per setting) */ | 312 | /* 4 idle,t1,t2,b (4 bits per setting) */ |
@@ -568,56 +571,56 @@ static const struct ar9300_eeprom ar9300_default = { | |||
568 | .ctlPowerData_5G = { | 571 | .ctlPowerData_5G = { |
569 | { | 572 | { |
570 | { | 573 | { |
571 | {60, 1}, {60, 1}, {60, 1}, {60, 1}, | 574 | CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1), |
572 | {60, 1}, {60, 1}, {60, 1}, {60, 0}, | 575 | CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0), |
573 | } | 576 | } |
574 | }, | 577 | }, |
575 | { | 578 | { |
576 | { | 579 | { |
577 | {60, 1}, {60, 1}, {60, 1}, {60, 1}, | 580 | CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1), |
578 | {60, 1}, {60, 1}, {60, 1}, {60, 0}, | 581 | CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0), |
579 | } | 582 | } |
580 | }, | 583 | }, |
581 | { | 584 | { |
582 | { | 585 | { |
583 | {60, 0}, {60, 1}, {60, 0}, {60, 1}, | 586 | CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1), |
584 | {60, 1}, {60, 1}, {60, 1}, {60, 1}, | 587 | CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1), |
585 | } | 588 | } |
586 | }, | 589 | }, |
587 | { | 590 | { |
588 | { | 591 | { |
589 | {60, 0}, {60, 1}, {60, 1}, {60, 0}, | 592 | CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0), |
590 | {60, 1}, {60, 0}, {60, 0}, {60, 0}, | 593 | CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0), |
591 | } | 594 | } |
592 | }, | 595 | }, |
593 | { | 596 | { |
594 | { | 597 | { |
595 | {60, 1}, {60, 1}, {60, 1}, {60, 0}, | 598 | CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0), |
596 | {60, 0}, {60, 0}, {60, 0}, {60, 0}, | 599 | CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0), |
597 | } | 600 | } |
598 | }, | 601 | }, |
599 | { | 602 | { |
600 | { | 603 | { |
601 | {60, 1}, {60, 1}, {60, 1}, {60, 1}, | 604 | CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1), |
602 | {60, 1}, {60, 0}, {60, 0}, {60, 0}, | 605 | CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0), |
603 | } | 606 | } |
604 | }, | 607 | }, |
605 | { | 608 | { |
606 | { | 609 | { |
607 | {60, 1}, {60, 1}, {60, 1}, {60, 1}, | 610 | CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1), |
608 | {60, 1}, {60, 1}, {60, 1}, {60, 1}, | 611 | CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1), |
609 | } | 612 | } |
610 | }, | 613 | }, |
611 | { | 614 | { |
612 | { | 615 | { |
613 | {60, 1}, {60, 1}, {60, 0}, {60, 1}, | 616 | CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1), |
614 | {60, 1}, {60, 1}, {60, 1}, {60, 0}, | 617 | CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0), |
615 | } | 618 | } |
616 | }, | 619 | }, |
617 | { | 620 | { |
618 | { | 621 | { |
619 | {60, 1}, {60, 0}, {60, 1}, {60, 1}, | 622 | CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1), |
620 | {60, 1}, {60, 1}, {60, 0}, {60, 1}, | 623 | CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1), |
621 | } | 624 | } |
622 | }, | 625 | }, |
623 | } | 626 | } |
@@ -1827,9 +1830,9 @@ static u16 ar9003_hw_get_direct_edge_power(struct ar9300_eeprom *eep, | |||
1827 | struct cal_ctl_data_5g *ctl_5g = eep->ctlPowerData_5G; | 1830 | struct cal_ctl_data_5g *ctl_5g = eep->ctlPowerData_5G; |
1828 | 1831 | ||
1829 | if (is2GHz) | 1832 | if (is2GHz) |
1830 | return ctl_2g[idx].ctlEdges[edge].tPower; | 1833 | return CTL_EDGE_TPOWER(ctl_2g[idx].ctlEdges[edge]); |
1831 | else | 1834 | else |
1832 | return ctl_5g[idx].ctlEdges[edge].tPower; | 1835 | return CTL_EDGE_TPOWER(ctl_5g[idx].ctlEdges[edge]); |
1833 | } | 1836 | } |
1834 | 1837 | ||
1835 | static u16 ar9003_hw_get_indirect_edge_power(struct ar9300_eeprom *eep, | 1838 | static u16 ar9003_hw_get_indirect_edge_power(struct ar9300_eeprom *eep, |
@@ -1847,12 +1850,12 @@ static u16 ar9003_hw_get_indirect_edge_power(struct ar9300_eeprom *eep, | |||
1847 | 1850 | ||
1848 | if (is2GHz) { | 1851 | if (is2GHz) { |
1849 | if (ath9k_hw_fbin2freq(ctl_freqbin[edge - 1], 1) < freq && | 1852 | if (ath9k_hw_fbin2freq(ctl_freqbin[edge - 1], 1) < freq && |
1850 | ctl_2g[idx].ctlEdges[edge - 1].flag) | 1853 | CTL_EDGE_FLAGS(ctl_2g[idx].ctlEdges[edge - 1])) |
1851 | return ctl_2g[idx].ctlEdges[edge - 1].tPower; | 1854 | return CTL_EDGE_TPOWER(ctl_2g[idx].ctlEdges[edge - 1]); |
1852 | } else { | 1855 | } else { |
1853 | if (ath9k_hw_fbin2freq(ctl_freqbin[edge - 1], 0) < freq && | 1856 | if (ath9k_hw_fbin2freq(ctl_freqbin[edge - 1], 0) < freq && |
1854 | ctl_5g[idx].ctlEdges[edge - 1].flag) | 1857 | CTL_EDGE_FLAGS(ctl_5g[idx].ctlEdges[edge - 1])) |
1855 | return ctl_5g[idx].ctlEdges[edge - 1].tPower; | 1858 | return CTL_EDGE_TPOWER(ctl_5g[idx].ctlEdges[edge - 1]); |
1856 | } | 1859 | } |
1857 | 1860 | ||
1858 | return AR9300_MAX_RATE_POWER; | 1861 | return AR9300_MAX_RATE_POWER; |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h index 3c533bb983c7..655b3033396c 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h | |||
@@ -261,17 +261,12 @@ struct cal_tgt_pow_ht { | |||
261 | u8 tPow2x[14]; | 261 | u8 tPow2x[14]; |
262 | } __packed; | 262 | } __packed; |
263 | 263 | ||
264 | struct cal_ctl_edge_pwr { | ||
265 | u8 tPower:6, | ||
266 | flag:2; | ||
267 | } __packed; | ||
268 | |||
269 | struct cal_ctl_data_2g { | 264 | struct cal_ctl_data_2g { |
270 | struct cal_ctl_edge_pwr ctlEdges[AR9300_NUM_BAND_EDGES_2G]; | 265 | u8 ctlEdges[AR9300_NUM_BAND_EDGES_2G]; |
271 | } __packed; | 266 | } __packed; |
272 | 267 | ||
273 | struct cal_ctl_data_5g { | 268 | struct cal_ctl_data_5g { |
274 | struct cal_ctl_edge_pwr ctlEdges[AR9300_NUM_BAND_EDGES_5G]; | 269 | u8 ctlEdges[AR9300_NUM_BAND_EDGES_5G]; |
275 | } __packed; | 270 | } __packed; |
276 | 271 | ||
277 | struct ar9300_eeprom { | 272 | struct ar9300_eeprom { |
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 170d44a35ccb..0963071e8f90 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/device.h> | 21 | #include <linux/device.h> |
22 | #include <linux/leds.h> | 22 | #include <linux/leds.h> |
23 | #include <linux/completion.h> | 23 | #include <linux/completion.h> |
24 | #include <linux/pm_qos_params.h> | ||
24 | 25 | ||
25 | #include "debug.h" | 26 | #include "debug.h" |
26 | #include "common.h" | 27 | #include "common.h" |
@@ -328,7 +329,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp); | |||
328 | struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype); | 329 | struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype); |
329 | void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq); | 330 | void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq); |
330 | int ath_tx_setup(struct ath_softc *sc, int haltype); | 331 | int ath_tx_setup(struct ath_softc *sc, int haltype); |
331 | void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx); | 332 | bool ath_drain_all_txq(struct ath_softc *sc, bool retry_tx); |
332 | void ath_draintxq(struct ath_softc *sc, | 333 | void ath_draintxq(struct ath_softc *sc, |
333 | struct ath_txq *txq, bool retry_tx); | 334 | struct ath_txq *txq, bool retry_tx); |
334 | void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an); | 335 | void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an); |
@@ -646,6 +647,8 @@ struct ath_softc { | |||
646 | struct ath_descdma txsdma; | 647 | struct ath_descdma txsdma; |
647 | 648 | ||
648 | struct ath_ant_comb ant_comb; | 649 | struct ath_ant_comb ant_comb; |
650 | |||
651 | struct pm_qos_request_list pm_qos_req; | ||
649 | }; | 652 | }; |
650 | 653 | ||
651 | struct ath_wiphy { | 654 | struct ath_wiphy { |
@@ -675,7 +678,6 @@ static inline void ath_read_cachesize(struct ath_common *common, int *csz) | |||
675 | } | 678 | } |
676 | 679 | ||
677 | extern struct ieee80211_ops ath9k_ops; | 680 | extern struct ieee80211_ops ath9k_ops; |
678 | extern struct pm_qos_request_list ath9k_pm_qos_req; | ||
679 | extern int modparam_nohwcrypt; | 681 | extern int modparam_nohwcrypt; |
680 | extern int led_blink; | 682 | extern int led_blink; |
681 | 683 | ||
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.c b/drivers/net/wireless/ath/ath9k/eeprom.c index 1266333f586d..2bbf94d0191e 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom.c +++ b/drivers/net/wireless/ath/ath9k/eeprom.c | |||
@@ -240,16 +240,16 @@ u16 ath9k_hw_get_max_edge_power(u16 freq, struct cal_ctl_edges *pRdEdgesPower, | |||
240 | for (i = 0; (i < num_band_edges) && | 240 | for (i = 0; (i < num_band_edges) && |
241 | (pRdEdgesPower[i].bChannel != AR5416_BCHAN_UNUSED); i++) { | 241 | (pRdEdgesPower[i].bChannel != AR5416_BCHAN_UNUSED); i++) { |
242 | if (freq == ath9k_hw_fbin2freq(pRdEdgesPower[i].bChannel, is2GHz)) { | 242 | if (freq == ath9k_hw_fbin2freq(pRdEdgesPower[i].bChannel, is2GHz)) { |
243 | twiceMaxEdgePower = pRdEdgesPower[i].tPower; | 243 | twiceMaxEdgePower = CTL_EDGE_TPOWER(pRdEdgesPower[i].ctl); |
244 | break; | 244 | break; |
245 | } else if ((i > 0) && | 245 | } else if ((i > 0) && |
246 | (freq < ath9k_hw_fbin2freq(pRdEdgesPower[i].bChannel, | 246 | (freq < ath9k_hw_fbin2freq(pRdEdgesPower[i].bChannel, |
247 | is2GHz))) { | 247 | is2GHz))) { |
248 | if (ath9k_hw_fbin2freq(pRdEdgesPower[i - 1].bChannel, | 248 | if (ath9k_hw_fbin2freq(pRdEdgesPower[i - 1].bChannel, |
249 | is2GHz) < freq && | 249 | is2GHz) < freq && |
250 | pRdEdgesPower[i - 1].flag) { | 250 | CTL_EDGE_FLAGS(pRdEdgesPower[i - 1].ctl)) { |
251 | twiceMaxEdgePower = | 251 | twiceMaxEdgePower = |
252 | pRdEdgesPower[i - 1].tPower; | 252 | CTL_EDGE_TPOWER(pRdEdgesPower[i - 1].ctl); |
253 | } | 253 | } |
254 | break; | 254 | break; |
255 | } | 255 | } |
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.h b/drivers/net/wireless/ath/ath9k/eeprom.h index dacb45e1b906..dd59f09441a3 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom.h +++ b/drivers/net/wireless/ath/ath9k/eeprom.h | |||
@@ -233,6 +233,18 @@ | |||
233 | 233 | ||
234 | #define AR9287_CHECKSUM_LOCATION (AR9287_EEP_START_LOC + 1) | 234 | #define AR9287_CHECKSUM_LOCATION (AR9287_EEP_START_LOC + 1) |
235 | 235 | ||
236 | #define CTL_EDGE_TPOWER(_ctl) ((_ctl) & 0x3f) | ||
237 | #define CTL_EDGE_FLAGS(_ctl) (((_ctl) >> 6) & 0x03) | ||
238 | |||
239 | #define LNA_CTL_BUF_MODE BIT(0) | ||
240 | #define LNA_CTL_ISEL_LO BIT(1) | ||
241 | #define LNA_CTL_ISEL_HI BIT(2) | ||
242 | #define LNA_CTL_BUF_IN BIT(3) | ||
243 | #define LNA_CTL_FEM_BAND BIT(4) | ||
244 | #define LNA_CTL_LOCAL_BIAS BIT(5) | ||
245 | #define LNA_CTL_FORCE_XPA BIT(6) | ||
246 | #define LNA_CTL_USE_ANT1 BIT(7) | ||
247 | |||
236 | enum eeprom_param { | 248 | enum eeprom_param { |
237 | EEP_NFTHRESH_5, | 249 | EEP_NFTHRESH_5, |
238 | EEP_NFTHRESH_2, | 250 | EEP_NFTHRESH_2, |
@@ -378,10 +390,7 @@ struct modal_eep_header { | |||
378 | u8 xatten2Margin[AR5416_MAX_CHAINS]; | 390 | u8 xatten2Margin[AR5416_MAX_CHAINS]; |
379 | u8 ob_ch1; | 391 | u8 ob_ch1; |
380 | u8 db_ch1; | 392 | u8 db_ch1; |
381 | u8 useAnt1:1, | 393 | u8 lna_ctl; |
382 | force_xpaon:1, | ||
383 | local_bias:1, | ||
384 | femBandSelectUsed:1, xlnabufin:1, xlnaisel:2, xlnabufmode:1; | ||
385 | u8 miscBits; | 394 | u8 miscBits; |
386 | u16 xpaBiasLvlFreq[3]; | 395 | u16 xpaBiasLvlFreq[3]; |
387 | u8 futureModal[6]; | 396 | u8 futureModal[6]; |
@@ -535,18 +544,10 @@ struct cal_target_power_ht { | |||
535 | u8 tPow2x[8]; | 544 | u8 tPow2x[8]; |
536 | } __packed; | 545 | } __packed; |
537 | 546 | ||
538 | |||
539 | #ifdef __BIG_ENDIAN_BITFIELD | ||
540 | struct cal_ctl_edges { | ||
541 | u8 bChannel; | ||
542 | u8 flag:2, tPower:6; | ||
543 | } __packed; | ||
544 | #else | ||
545 | struct cal_ctl_edges { | 547 | struct cal_ctl_edges { |
546 | u8 bChannel; | 548 | u8 bChannel; |
547 | u8 tPower:6, flag:2; | 549 | u8 ctl; |
548 | } __packed; | 550 | } __packed; |
549 | #endif | ||
550 | 551 | ||
551 | struct cal_data_op_loop_ar9287 { | 552 | struct cal_data_op_loop_ar9287 { |
552 | u8 pwrPdg[2][5]; | 553 | u8 pwrPdg[2][5]; |
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_def.c b/drivers/net/wireless/ath/ath9k/eeprom_def.c index 76b4d65472dd..a3ccb1b9638d 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_def.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c | |||
@@ -451,9 +451,10 @@ static void ath9k_hw_def_set_board_values(struct ath_hw *ah, | |||
451 | ath9k_hw_analog_shift_rmw(ah, AR_AN_TOP2, | 451 | ath9k_hw_analog_shift_rmw(ah, AR_AN_TOP2, |
452 | AR_AN_TOP2_LOCALBIAS, | 452 | AR_AN_TOP2_LOCALBIAS, |
453 | AR_AN_TOP2_LOCALBIAS_S, | 453 | AR_AN_TOP2_LOCALBIAS_S, |
454 | pModal->local_bias); | 454 | !!(pModal->lna_ctl & |
455 | LNA_CTL_LOCAL_BIAS)); | ||
455 | REG_RMW_FIELD(ah, AR_PHY_XPA_CFG, AR_PHY_FORCE_XPA_CFG, | 456 | REG_RMW_FIELD(ah, AR_PHY_XPA_CFG, AR_PHY_FORCE_XPA_CFG, |
456 | pModal->force_xpaon); | 457 | !!(pModal->lna_ctl & LNA_CTL_FORCE_XPA)); |
457 | } | 458 | } |
458 | 459 | ||
459 | REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH, | 460 | REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH, |
@@ -1062,15 +1063,19 @@ static void ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah, | |||
1062 | case 1: | 1063 | case 1: |
1063 | break; | 1064 | break; |
1064 | case 2: | 1065 | case 2: |
1065 | scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN; | 1066 | if (scaledPower > REDUCE_SCALED_POWER_BY_TWO_CHAIN) |
1067 | scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN; | ||
1068 | else | ||
1069 | scaledPower = 0; | ||
1066 | break; | 1070 | break; |
1067 | case 3: | 1071 | case 3: |
1068 | scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN; | 1072 | if (scaledPower > REDUCE_SCALED_POWER_BY_THREE_CHAIN) |
1073 | scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN; | ||
1074 | else | ||
1075 | scaledPower = 0; | ||
1069 | break; | 1076 | break; |
1070 | } | 1077 | } |
1071 | 1078 | ||
1072 | scaledPower = max((u16)0, scaledPower); | ||
1073 | |||
1074 | if (IS_CHAN_2GHZ(chan)) { | 1079 | if (IS_CHAN_2GHZ(chan)) { |
1075 | numCtlModes = ARRAY_SIZE(ctlModesFor11g) - | 1080 | numCtlModes = ARRAY_SIZE(ctlModesFor11g) - |
1076 | SUB_NUM_CTL_MODES_AT_2G_40; | 1081 | SUB_NUM_CTL_MODES_AT_2G_40; |
@@ -1428,9 +1433,9 @@ static u8 ath9k_hw_def_get_num_ant_config(struct ath_hw *ah, | |||
1428 | 1433 | ||
1429 | num_ant_config = 1; | 1434 | num_ant_config = 1; |
1430 | 1435 | ||
1431 | if (pBase->version >= 0x0E0D) | 1436 | if (pBase->version >= 0x0E0D && |
1432 | if (pModal->useAnt1) | 1437 | (pModal->lna_ctl & LNA_CTL_USE_ANT1)) |
1433 | num_ant_config += 1; | 1438 | num_ant_config += 1; |
1434 | 1439 | ||
1435 | return num_ant_config; | 1440 | return num_ant_config; |
1436 | } | 1441 | } |
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index dfb6560dab92..0de3c3d3c245 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c | |||
@@ -1024,6 +1024,13 @@ static int ath9k_hif_usb_suspend(struct usb_interface *interface, | |||
1024 | struct hif_device_usb *hif_dev = | 1024 | struct hif_device_usb *hif_dev = |
1025 | (struct hif_device_usb *) usb_get_intfdata(interface); | 1025 | (struct hif_device_usb *) usb_get_intfdata(interface); |
1026 | 1026 | ||
1027 | /* | ||
1028 | * The device has to be set to FULLSLEEP mode in case no | ||
1029 | * interface is up. | ||
1030 | */ | ||
1031 | if (!(hif_dev->flags & HIF_USB_START)) | ||
1032 | ath9k_htc_suspend(hif_dev->htc_handle); | ||
1033 | |||
1027 | ath9k_hif_usb_dealloc_urbs(hif_dev); | 1034 | ath9k_hif_usb_dealloc_urbs(hif_dev); |
1028 | 1035 | ||
1029 | return 0; | 1036 | return 0; |
diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index 75ecf6a30d25..c3b561daa6c1 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h | |||
@@ -455,6 +455,8 @@ u32 ath9k_htc_calcrxfilter(struct ath9k_htc_priv *priv); | |||
455 | void ath9k_htc_ps_wakeup(struct ath9k_htc_priv *priv); | 455 | void ath9k_htc_ps_wakeup(struct ath9k_htc_priv *priv); |
456 | void ath9k_htc_ps_restore(struct ath9k_htc_priv *priv); | 456 | void ath9k_htc_ps_restore(struct ath9k_htc_priv *priv); |
457 | void ath9k_ps_work(struct work_struct *work); | 457 | void ath9k_ps_work(struct work_struct *work); |
458 | bool ath9k_htc_setpower(struct ath9k_htc_priv *priv, | ||
459 | enum ath9k_power_mode mode); | ||
458 | 460 | ||
459 | void ath9k_start_rfkill_poll(struct ath9k_htc_priv *priv); | 461 | void ath9k_start_rfkill_poll(struct ath9k_htc_priv *priv); |
460 | void ath9k_init_leds(struct ath9k_htc_priv *priv); | 462 | void ath9k_init_leds(struct ath9k_htc_priv *priv); |
@@ -464,6 +466,7 @@ int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev, | |||
464 | u16 devid, char *product); | 466 | u16 devid, char *product); |
465 | void ath9k_htc_disconnect_device(struct htc_target *htc_handle, bool hotunplug); | 467 | void ath9k_htc_disconnect_device(struct htc_target *htc_handle, bool hotunplug); |
466 | #ifdef CONFIG_PM | 468 | #ifdef CONFIG_PM |
469 | void ath9k_htc_suspend(struct htc_target *htc_handle); | ||
467 | int ath9k_htc_resume(struct htc_target *htc_handle); | 470 | int ath9k_htc_resume(struct htc_target *htc_handle); |
468 | #endif | 471 | #endif |
469 | #ifdef CONFIG_ATH9K_HTC_DEBUGFS | 472 | #ifdef CONFIG_ATH9K_HTC_DEBUGFS |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index 7c8a38d04561..8776f49ffd41 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c | |||
@@ -891,6 +891,12 @@ void ath9k_htc_disconnect_device(struct htc_target *htc_handle, bool hotunplug) | |||
891 | } | 891 | } |
892 | 892 | ||
893 | #ifdef CONFIG_PM | 893 | #ifdef CONFIG_PM |
894 | |||
895 | void ath9k_htc_suspend(struct htc_target *htc_handle) | ||
896 | { | ||
897 | ath9k_htc_setpower(htc_handle->drv_priv, ATH9K_PM_FULL_SLEEP); | ||
898 | } | ||
899 | |||
894 | int ath9k_htc_resume(struct htc_target *htc_handle) | 900 | int ath9k_htc_resume(struct htc_target *htc_handle) |
895 | { | 901 | { |
896 | int ret; | 902 | int ret; |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 9a3be8da755d..51977caca47f 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c | |||
@@ -63,8 +63,8 @@ static enum htc_phymode ath9k_htc_get_curmode(struct ath9k_htc_priv *priv, | |||
63 | return mode; | 63 | return mode; |
64 | } | 64 | } |
65 | 65 | ||
66 | static bool ath9k_htc_setpower(struct ath9k_htc_priv *priv, | 66 | bool ath9k_htc_setpower(struct ath9k_htc_priv *priv, |
67 | enum ath9k_power_mode mode) | 67 | enum ath9k_power_mode mode) |
68 | { | 68 | { |
69 | bool ret; | 69 | bool ret; |
70 | 70 | ||
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 6ebc68bca91f..c7fbe25cc128 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c | |||
@@ -2044,7 +2044,8 @@ u32 ath9k_hw_gpio_get(struct ath_hw *ah, u32 gpio) | |||
2044 | val = REG_READ(ah, AR7010_GPIO_IN); | 2044 | val = REG_READ(ah, AR7010_GPIO_IN); |
2045 | return (MS(val, AR7010_GPIO_IN_VAL) & AR_GPIO_BIT(gpio)) == 0; | 2045 | return (MS(val, AR7010_GPIO_IN_VAL) & AR_GPIO_BIT(gpio)) == 0; |
2046 | } else if (AR_SREV_9300_20_OR_LATER(ah)) | 2046 | } else if (AR_SREV_9300_20_OR_LATER(ah)) |
2047 | return MS_REG_READ(AR9300, gpio) != 0; | 2047 | return (MS(REG_READ(ah, AR_GPIO_IN), AR9300_GPIO_IN_VAL) & |
2048 | AR_GPIO_BIT(gpio)) != 0; | ||
2048 | else if (AR_SREV_9271(ah)) | 2049 | else if (AR_SREV_9271(ah)) |
2049 | return MS_REG_READ(AR9271, gpio) != 0; | 2050 | return MS_REG_READ(AR9271, gpio) != 0; |
2050 | else if (AR_SREV_9287_11_OR_LATER(ah)) | 2051 | else if (AR_SREV_9287_11_OR_LATER(ah)) |
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 92bc5c5f4876..14b8ab386daf 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c | |||
@@ -15,7 +15,6 @@ | |||
15 | */ | 15 | */ |
16 | 16 | ||
17 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
18 | #include <linux/pm_qos_params.h> | ||
19 | 18 | ||
20 | #include "ath9k.h" | 19 | #include "ath9k.h" |
21 | 20 | ||
@@ -180,8 +179,6 @@ static const struct ath_ops ath9k_common_ops = { | |||
180 | .write = ath9k_iowrite32, | 179 | .write = ath9k_iowrite32, |
181 | }; | 180 | }; |
182 | 181 | ||
183 | struct pm_qos_request_list ath9k_pm_qos_req; | ||
184 | |||
185 | /**************************/ | 182 | /**************************/ |
186 | /* Initialization */ | 183 | /* Initialization */ |
187 | /**************************/ | 184 | /**************************/ |
@@ -664,6 +661,8 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) | |||
664 | hw->flags |= IEEE80211_HW_MFP_CAPABLE; | 661 | hw->flags |= IEEE80211_HW_MFP_CAPABLE; |
665 | 662 | ||
666 | hw->wiphy->interface_modes = | 663 | hw->wiphy->interface_modes = |
664 | BIT(NL80211_IFTYPE_P2P_GO) | | ||
665 | BIT(NL80211_IFTYPE_P2P_CLIENT) | | ||
667 | BIT(NL80211_IFTYPE_AP) | | 666 | BIT(NL80211_IFTYPE_AP) | |
668 | BIT(NL80211_IFTYPE_WDS) | | 667 | BIT(NL80211_IFTYPE_WDS) | |
669 | BIT(NL80211_IFTYPE_STATION) | | 668 | BIT(NL80211_IFTYPE_STATION) | |
@@ -759,7 +758,7 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid, | |||
759 | ath_init_leds(sc); | 758 | ath_init_leds(sc); |
760 | ath_start_rfkill_poll(sc); | 759 | ath_start_rfkill_poll(sc); |
761 | 760 | ||
762 | pm_qos_add_request(&ath9k_pm_qos_req, PM_QOS_CPU_DMA_LATENCY, | 761 | pm_qos_add_request(&sc->pm_qos_req, PM_QOS_CPU_DMA_LATENCY, |
763 | PM_QOS_DEFAULT_VALUE); | 762 | PM_QOS_DEFAULT_VALUE); |
764 | 763 | ||
765 | return 0; | 764 | return 0; |
@@ -830,7 +829,7 @@ void ath9k_deinit_device(struct ath_softc *sc) | |||
830 | } | 829 | } |
831 | 830 | ||
832 | ieee80211_unregister_hw(hw); | 831 | ieee80211_unregister_hw(hw); |
833 | pm_qos_remove_request(&ath9k_pm_qos_req); | 832 | pm_qos_remove_request(&sc->pm_qos_req); |
834 | ath_rx_cleanup(sc); | 833 | ath_rx_cleanup(sc); |
835 | ath_tx_cleanup(sc); | 834 | ath_tx_cleanup(sc); |
836 | ath9k_deinit_softc(sc); | 835 | ath9k_deinit_softc(sc); |
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c index 8c13479b17cd..c996963ab339 100644 --- a/drivers/net/wireless/ath/ath9k/mac.c +++ b/drivers/net/wireless/ath/ath9k/mac.c | |||
@@ -703,8 +703,7 @@ int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds, | |||
703 | rs->rs_phyerr = phyerr; | 703 | rs->rs_phyerr = phyerr; |
704 | } else if (ads.ds_rxstatus8 & AR_DecryptCRCErr) | 704 | } else if (ads.ds_rxstatus8 & AR_DecryptCRCErr) |
705 | rs->rs_status |= ATH9K_RXERR_DECRYPT; | 705 | rs->rs_status |= ATH9K_RXERR_DECRYPT; |
706 | else if ((ads.ds_rxstatus8 & AR_MichaelErr) && | 706 | else if (ads.ds_rxstatus8 & AR_MichaelErr) |
707 | rs->rs_keyix != ATH9K_RXKEYIX_INVALID) | ||
708 | rs->rs_status |= ATH9K_RXERR_MIC; | 707 | rs->rs_status |= ATH9K_RXERR_MIC; |
709 | else if (ads.ds_rxstatus8 & AR_KeyMiss) | 708 | else if (ads.ds_rxstatus8 & AR_KeyMiss) |
710 | rs->rs_status |= ATH9K_RXERR_DECRYPT; | 709 | rs->rs_status |= ATH9K_RXERR_DECRYPT; |
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 25d3ef4c338e..c0c3464d3a86 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -15,7 +15,6 @@ | |||
15 | */ | 15 | */ |
16 | 16 | ||
17 | #include <linux/nl80211.h> | 17 | #include <linux/nl80211.h> |
18 | #include <linux/pm_qos_params.h> | ||
19 | #include "ath9k.h" | 18 | #include "ath9k.h" |
20 | #include "btcoex.h" | 19 | #include "btcoex.h" |
21 | 20 | ||
@@ -245,11 +244,12 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, | |||
245 | * the relevant bits of the h/w. | 244 | * the relevant bits of the h/w. |
246 | */ | 245 | */ |
247 | ath9k_hw_set_interrupts(ah, 0); | 246 | ath9k_hw_set_interrupts(ah, 0); |
248 | ath_drain_all_txq(sc, false); | 247 | stopped = ath_drain_all_txq(sc, false); |
249 | 248 | ||
250 | spin_lock_bh(&sc->rx.pcu_lock); | 249 | spin_lock_bh(&sc->rx.pcu_lock); |
251 | 250 | ||
252 | stopped = ath_stoprecv(sc); | 251 | if (!ath_stoprecv(sc)) |
252 | stopped = false; | ||
253 | 253 | ||
254 | /* XXX: do not flush receive queue here. We don't want | 254 | /* XXX: do not flush receive queue here. We don't want |
255 | * to flush data frames already in queue because of | 255 | * to flush data frames already in queue because of |
@@ -1244,7 +1244,7 @@ static int ath9k_start(struct ieee80211_hw *hw) | |||
1244 | ath9k_btcoex_timer_resume(sc); | 1244 | ath9k_btcoex_timer_resume(sc); |
1245 | } | 1245 | } |
1246 | 1246 | ||
1247 | pm_qos_update_request(&ath9k_pm_qos_req, 55); | 1247 | pm_qos_update_request(&sc->pm_qos_req, 55); |
1248 | 1248 | ||
1249 | mutex_unlock: | 1249 | mutex_unlock: |
1250 | mutex_unlock(&sc->mutex); | 1250 | mutex_unlock(&sc->mutex); |
@@ -1423,7 +1423,7 @@ static void ath9k_stop(struct ieee80211_hw *hw) | |||
1423 | 1423 | ||
1424 | sc->sc_flags |= SC_OP_INVALID; | 1424 | sc->sc_flags |= SC_OP_INVALID; |
1425 | 1425 | ||
1426 | pm_qos_update_request(&ath9k_pm_qos_req, PM_QOS_DEFAULT_VALUE); | 1426 | pm_qos_update_request(&sc->pm_qos_req, PM_QOS_DEFAULT_VALUE); |
1427 | 1427 | ||
1428 | mutex_unlock(&sc->mutex); | 1428 | mutex_unlock(&sc->mutex); |
1429 | 1429 | ||
@@ -1520,7 +1520,6 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw, | |||
1520 | struct ath_softc *sc = aphy->sc; | 1520 | struct ath_softc *sc = aphy->sc; |
1521 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 1521 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
1522 | struct ath_vif *avp = (void *)vif->drv_priv; | 1522 | struct ath_vif *avp = (void *)vif->drv_priv; |
1523 | int i; | ||
1524 | 1523 | ||
1525 | ath_print(common, ATH_DBG_CONFIG, "Detach Interface\n"); | 1524 | ath_print(common, ATH_DBG_CONFIG, "Detach Interface\n"); |
1526 | 1525 | ||
@@ -1534,21 +1533,24 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw, | |||
1534 | if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) || | 1533 | if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) || |
1535 | (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) || | 1534 | (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) || |
1536 | (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT)) { | 1535 | (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT)) { |
1536 | /* Disable SWBA interrupt */ | ||
1537 | sc->sc_ah->imask &= ~ATH9K_INT_SWBA; | ||
1537 | ath9k_ps_wakeup(sc); | 1538 | ath9k_ps_wakeup(sc); |
1539 | ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_ah->imask); | ||
1538 | ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); | 1540 | ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); |
1539 | ath9k_ps_restore(sc); | 1541 | ath9k_ps_restore(sc); |
1542 | tasklet_kill(&sc->bcon_tasklet); | ||
1540 | } | 1543 | } |
1541 | 1544 | ||
1542 | ath_beacon_return(sc, avp); | 1545 | ath_beacon_return(sc, avp); |
1543 | sc->sc_flags &= ~SC_OP_BEACONS; | 1546 | sc->sc_flags &= ~SC_OP_BEACONS; |
1544 | 1547 | ||
1545 | for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++) { | 1548 | if (sc->nbcnvifs) { |
1546 | if (sc->beacon.bslot[i] == vif) { | 1549 | /* Re-enable SWBA interrupt */ |
1547 | printk(KERN_DEBUG "%s: vif had allocated beacon " | 1550 | sc->sc_ah->imask |= ATH9K_INT_SWBA; |
1548 | "slot\n", __func__); | 1551 | ath9k_ps_wakeup(sc); |
1549 | sc->beacon.bslot[i] = NULL; | 1552 | ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_ah->imask); |
1550 | sc->beacon.bslot_aphy[i] = NULL; | 1553 | ath9k_ps_restore(sc); |
1551 | } | ||
1552 | } | 1554 | } |
1553 | 1555 | ||
1554 | sc->nvifs--; | 1556 | sc->nvifs--; |
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index 1a62e351ec77..fdc2ec52b42f 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c | |||
@@ -838,6 +838,10 @@ static bool ath9k_rx_accept(struct ath_common *common, | |||
838 | struct ath_rx_status *rx_stats, | 838 | struct ath_rx_status *rx_stats, |
839 | bool *decrypt_error) | 839 | bool *decrypt_error) |
840 | { | 840 | { |
841 | #define is_mc_or_valid_tkip_keyix ((is_mc || \ | ||
842 | (rx_stats->rs_keyix != ATH9K_RXKEYIX_INVALID && \ | ||
843 | test_bit(rx_stats->rs_keyix, common->tkip_keymap)))) | ||
844 | |||
841 | struct ath_hw *ah = common->ah; | 845 | struct ath_hw *ah = common->ah; |
842 | __le16 fc; | 846 | __le16 fc; |
843 | u8 rx_status_len = ah->caps.rx_status_len; | 847 | u8 rx_status_len = ah->caps.rx_status_len; |
@@ -879,15 +883,18 @@ static bool ath9k_rx_accept(struct ath_common *common, | |||
879 | if (rx_stats->rs_status & ATH9K_RXERR_DECRYPT) { | 883 | if (rx_stats->rs_status & ATH9K_RXERR_DECRYPT) { |
880 | *decrypt_error = true; | 884 | *decrypt_error = true; |
881 | } else if (rx_stats->rs_status & ATH9K_RXERR_MIC) { | 885 | } else if (rx_stats->rs_status & ATH9K_RXERR_MIC) { |
886 | bool is_mc; | ||
882 | /* | 887 | /* |
883 | * The MIC error bit is only valid if the frame | 888 | * The MIC error bit is only valid if the frame |
884 | * is not a control frame or fragment, and it was | 889 | * is not a control frame or fragment, and it was |
885 | * decrypted using a valid TKIP key. | 890 | * decrypted using a valid TKIP key. |
886 | */ | 891 | */ |
892 | is_mc = !!is_multicast_ether_addr(hdr->addr1); | ||
893 | |||
887 | if (!ieee80211_is_ctl(fc) && | 894 | if (!ieee80211_is_ctl(fc) && |
888 | !ieee80211_has_morefrags(fc) && | 895 | !ieee80211_has_morefrags(fc) && |
889 | !(le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG) && | 896 | !(le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG) && |
890 | test_bit(rx_stats->rs_keyix, common->tkip_keymap)) | 897 | is_mc_or_valid_tkip_keyix) |
891 | rxs->flag |= RX_FLAG_MMIC_ERROR; | 898 | rxs->flag |= RX_FLAG_MMIC_ERROR; |
892 | else | 899 | else |
893 | rx_stats->rs_status &= ~ATH9K_RXERR_MIC; | 900 | rx_stats->rs_status &= ~ATH9K_RXERR_MIC; |
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h index dddf579aacf1..2c6a22fbb0f0 100644 --- a/drivers/net/wireless/ath/ath9k/reg.h +++ b/drivers/net/wireless/ath/ath9k/reg.h | |||
@@ -984,11 +984,13 @@ enum { | |||
984 | #define AR9287_GPIO_IN_VAL_S 11 | 984 | #define AR9287_GPIO_IN_VAL_S 11 |
985 | #define AR9271_GPIO_IN_VAL 0xFFFF0000 | 985 | #define AR9271_GPIO_IN_VAL 0xFFFF0000 |
986 | #define AR9271_GPIO_IN_VAL_S 16 | 986 | #define AR9271_GPIO_IN_VAL_S 16 |
987 | #define AR9300_GPIO_IN_VAL 0x0001FFFF | ||
988 | #define AR9300_GPIO_IN_VAL_S 0 | ||
989 | #define AR7010_GPIO_IN_VAL 0x0000FFFF | 987 | #define AR7010_GPIO_IN_VAL 0x0000FFFF |
990 | #define AR7010_GPIO_IN_VAL_S 0 | 988 | #define AR7010_GPIO_IN_VAL_S 0 |
991 | 989 | ||
990 | #define AR_GPIO_IN 0x404c | ||
991 | #define AR9300_GPIO_IN_VAL 0x0001FFFF | ||
992 | #define AR9300_GPIO_IN_VAL_S 0 | ||
993 | |||
992 | #define AR_GPIO_OE_OUT (AR_SREV_9300_20_OR_LATER(ah) ? 0x4050 : 0x404c) | 994 | #define AR_GPIO_OE_OUT (AR_SREV_9300_20_OR_LATER(ah) ? 0x4050 : 0x404c) |
993 | #define AR_GPIO_OE_OUT_DRV 0x3 | 995 | #define AR_GPIO_OE_OUT_DRV 0x3 |
994 | #define AR_GPIO_OE_OUT_DRV_NO 0x0 | 996 | #define AR_GPIO_OE_OUT_DRV_NO 0x0 |
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index f2ade2402ce2..aff04789f794 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
@@ -1120,7 +1120,7 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx) | |||
1120 | } | 1120 | } |
1121 | } | 1121 | } |
1122 | 1122 | ||
1123 | void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx) | 1123 | bool ath_drain_all_txq(struct ath_softc *sc, bool retry_tx) |
1124 | { | 1124 | { |
1125 | struct ath_hw *ah = sc->sc_ah; | 1125 | struct ath_hw *ah = sc->sc_ah; |
1126 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 1126 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
@@ -1128,7 +1128,7 @@ void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx) | |||
1128 | int i, npend = 0; | 1128 | int i, npend = 0; |
1129 | 1129 | ||
1130 | if (sc->sc_flags & SC_OP_INVALID) | 1130 | if (sc->sc_flags & SC_OP_INVALID) |
1131 | return; | 1131 | return true; |
1132 | 1132 | ||
1133 | /* Stop beacon queue */ | 1133 | /* Stop beacon queue */ |
1134 | ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); | 1134 | ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); |
@@ -1142,25 +1142,15 @@ void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx) | |||
1142 | } | 1142 | } |
1143 | } | 1143 | } |
1144 | 1144 | ||
1145 | if (npend) { | 1145 | if (npend) |
1146 | int r; | 1146 | ath_print(common, ATH_DBG_FATAL, "Failed to stop TX DMA!\n"); |
1147 | |||
1148 | ath_print(common, ATH_DBG_FATAL, | ||
1149 | "Failed to stop TX DMA. Resetting hardware!\n"); | ||
1150 | |||
1151 | spin_lock_bh(&sc->sc_resetlock); | ||
1152 | r = ath9k_hw_reset(ah, sc->sc_ah->curchan, ah->caldata, false); | ||
1153 | if (r) | ||
1154 | ath_print(common, ATH_DBG_FATAL, | ||
1155 | "Unable to reset hardware; reset status %d\n", | ||
1156 | r); | ||
1157 | spin_unlock_bh(&sc->sc_resetlock); | ||
1158 | } | ||
1159 | 1147 | ||
1160 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { | 1148 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { |
1161 | if (ATH_TXQ_SETUP(sc, i)) | 1149 | if (ATH_TXQ_SETUP(sc, i)) |
1162 | ath_draintxq(sc, &sc->tx.txq[i], retry_tx); | 1150 | ath_draintxq(sc, &sc->tx.txq[i], retry_tx); |
1163 | } | 1151 | } |
1152 | |||
1153 | return !npend; | ||
1164 | } | 1154 | } |
1165 | 1155 | ||
1166 | void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq) | 1156 | void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq) |
diff --git a/drivers/net/wireless/ath/carl9170/fw.c b/drivers/net/wireless/ath/carl9170/fw.c index ae6c006bbc56..546b4e4ec5ea 100644 --- a/drivers/net/wireless/ath/carl9170/fw.c +++ b/drivers/net/wireless/ath/carl9170/fw.c | |||
@@ -291,7 +291,8 @@ static int carl9170_fw(struct ar9170 *ar, const __u8 *data, size_t len) | |||
291 | 291 | ||
292 | if (SUPP(CARL9170FW_WLANTX_CAB)) { | 292 | if (SUPP(CARL9170FW_WLANTX_CAB)) { |
293 | ar->hw->wiphy->interface_modes |= | 293 | ar->hw->wiphy->interface_modes |= |
294 | BIT(NL80211_IFTYPE_AP); | 294 | BIT(NL80211_IFTYPE_AP) | |
295 | BIT(NL80211_IFTYPE_P2P_GO); | ||
295 | } | 296 | } |
296 | } | 297 | } |
297 | 298 | ||
diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c index a314c2c2bfbe..dc7b30b170d0 100644 --- a/drivers/net/wireless/ath/carl9170/main.c +++ b/drivers/net/wireless/ath/carl9170/main.c | |||
@@ -1631,7 +1631,8 @@ void *carl9170_alloc(size_t priv_size) | |||
1631 | * supports these modes. The code which will add the | 1631 | * supports these modes. The code which will add the |
1632 | * additional interface_modes is in fw.c. | 1632 | * additional interface_modes is in fw.c. |
1633 | */ | 1633 | */ |
1634 | hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); | 1634 | hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | |
1635 | BIT(NL80211_IFTYPE_P2P_CLIENT); | ||
1635 | 1636 | ||
1636 | hw->flags |= IEEE80211_HW_RX_INCLUDES_FCS | | 1637 | hw->flags |= IEEE80211_HW_RX_INCLUDES_FCS | |
1637 | IEEE80211_HW_REPORTS_TX_ACK_STATUS | | 1638 | IEEE80211_HW_REPORTS_TX_ACK_STATUS | |
diff --git a/drivers/net/wireless/ath/carl9170/tx.c b/drivers/net/wireless/ath/carl9170/tx.c index b575c865142d..7e6506a77bbb 100644 --- a/drivers/net/wireless/ath/carl9170/tx.c +++ b/drivers/net/wireless/ath/carl9170/tx.c | |||
@@ -810,7 +810,7 @@ static int carl9170_tx_prepare(struct ar9170 *ar, struct sk_buff *skb) | |||
810 | 810 | ||
811 | mac_tmp = cpu_to_le16(AR9170_TX_MAC_HW_DURATION | | 811 | mac_tmp = cpu_to_le16(AR9170_TX_MAC_HW_DURATION | |
812 | AR9170_TX_MAC_BACKOFF); | 812 | AR9170_TX_MAC_BACKOFF); |
813 | mac_tmp |= cpu_to_le16((hw_queue << AR9170_TX_MAC_QOS_S) && | 813 | mac_tmp |= cpu_to_le16((hw_queue << AR9170_TX_MAC_QOS_S) & |
814 | AR9170_TX_MAC_QOS); | 814 | AR9170_TX_MAC_QOS); |
815 | 815 | ||
816 | no_ack = !!(info->flags & IEEE80211_TX_CTL_NO_ACK); | 816 | no_ack = !!(info->flags & IEEE80211_TX_CTL_NO_ACK); |
diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c index e5685dc317a8..b4de0ca10feb 100644 --- a/drivers/net/wireless/libertas/if_sdio.c +++ b/drivers/net/wireless/libertas/if_sdio.c | |||
@@ -1170,7 +1170,6 @@ static void if_sdio_remove(struct sdio_func *func) | |||
1170 | lbs_deb_sdio("call remove card\n"); | 1170 | lbs_deb_sdio("call remove card\n"); |
1171 | lbs_stop_card(card->priv); | 1171 | lbs_stop_card(card->priv); |
1172 | lbs_remove_card(card->priv); | 1172 | lbs_remove_card(card->priv); |
1173 | card->priv->surpriseremoved = 1; | ||
1174 | 1173 | ||
1175 | flush_workqueue(card->workqueue); | 1174 | flush_workqueue(card->workqueue); |
1176 | destroy_workqueue(card->workqueue); | 1175 | destroy_workqueue(card->workqueue); |
diff --git a/drivers/net/wireless/libertas/if_spi.c b/drivers/net/wireless/libertas/if_spi.c index 79bcb4e5d2ca..ecd4d04b2c3c 100644 --- a/drivers/net/wireless/libertas/if_spi.c +++ b/drivers/net/wireless/libertas/if_spi.c | |||
@@ -1055,7 +1055,6 @@ static int __devexit libertas_spi_remove(struct spi_device *spi) | |||
1055 | lbs_stop_card(priv); | 1055 | lbs_stop_card(priv); |
1056 | lbs_remove_card(priv); /* will call free_netdev */ | 1056 | lbs_remove_card(priv); /* will call free_netdev */ |
1057 | 1057 | ||
1058 | priv->surpriseremoved = 1; | ||
1059 | free_irq(spi->irq, card); | 1058 | free_irq(spi->irq, card); |
1060 | if_spi_terminate_spi_thread(card); | 1059 | if_spi_terminate_spi_thread(card); |
1061 | if (card->pdata->teardown) | 1060 | if (card->pdata->teardown) |
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c index 46b88b118c99..fcd1bbfc632d 100644 --- a/drivers/net/wireless/libertas/main.c +++ b/drivers/net/wireless/libertas/main.c | |||
@@ -915,8 +915,6 @@ void lbs_remove_card(struct lbs_private *priv) | |||
915 | 915 | ||
916 | lbs_free_adapter(priv); | 916 | lbs_free_adapter(priv); |
917 | lbs_cfg_free(priv); | 917 | lbs_cfg_free(priv); |
918 | |||
919 | priv->dev = NULL; | ||
920 | free_netdev(dev); | 918 | free_netdev(dev); |
921 | 919 | ||
922 | lbs_deb_leave(LBS_DEB_MAIN); | 920 | lbs_deb_leave(LBS_DEB_MAIN); |
diff --git a/drivers/net/wireless/orinoco/main.c b/drivers/net/wireless/orinoco/main.c index e8e2d0f4763d..f3d396e7544b 100644 --- a/drivers/net/wireless/orinoco/main.c +++ b/drivers/net/wireless/orinoco/main.c | |||
@@ -1392,10 +1392,9 @@ static void orinoco_process_scan_results(struct work_struct *work) | |||
1392 | orinoco_add_hostscan_results(priv, buf, len); | 1392 | orinoco_add_hostscan_results(priv, buf, len); |
1393 | 1393 | ||
1394 | kfree(buf); | 1394 | kfree(buf); |
1395 | } else if (priv->scan_request) { | 1395 | } else { |
1396 | /* Either abort or complete the scan */ | 1396 | /* Either abort or complete the scan */ |
1397 | cfg80211_scan_done(priv->scan_request, (len < 0)); | 1397 | orinoco_scan_done(priv, (len < 0)); |
1398 | priv->scan_request = NULL; | ||
1399 | } | 1398 | } |
1400 | 1399 | ||
1401 | spin_lock_irqsave(&priv->scan_lock, flags); | 1400 | spin_lock_irqsave(&priv->scan_lock, flags); |
@@ -1684,6 +1683,8 @@ static int __orinoco_down(struct orinoco_private *priv) | |||
1684 | hermes_write_regn(hw, EVACK, 0xffff); | 1683 | hermes_write_regn(hw, EVACK, 0xffff); |
1685 | } | 1684 | } |
1686 | 1685 | ||
1686 | orinoco_scan_done(priv, true); | ||
1687 | |||
1687 | /* firmware will have to reassociate */ | 1688 | /* firmware will have to reassociate */ |
1688 | netif_carrier_off(dev); | 1689 | netif_carrier_off(dev); |
1689 | priv->last_linkstatus = 0xffff; | 1690 | priv->last_linkstatus = 0xffff; |
@@ -1762,10 +1763,7 @@ void orinoco_reset(struct work_struct *work) | |||
1762 | orinoco_unlock(priv, &flags); | 1763 | orinoco_unlock(priv, &flags); |
1763 | 1764 | ||
1764 | /* Scanning support: Notify scan cancellation */ | 1765 | /* Scanning support: Notify scan cancellation */ |
1765 | if (priv->scan_request) { | 1766 | orinoco_scan_done(priv, true); |
1766 | cfg80211_scan_done(priv->scan_request, 1); | ||
1767 | priv->scan_request = NULL; | ||
1768 | } | ||
1769 | 1767 | ||
1770 | if (priv->hard_reset) { | 1768 | if (priv->hard_reset) { |
1771 | err = (*priv->hard_reset)(priv); | 1769 | err = (*priv->hard_reset)(priv); |
@@ -1813,6 +1811,12 @@ static int __orinoco_commit(struct orinoco_private *priv) | |||
1813 | struct net_device *dev = priv->ndev; | 1811 | struct net_device *dev = priv->ndev; |
1814 | int err = 0; | 1812 | int err = 0; |
1815 | 1813 | ||
1814 | /* If we've called commit, we are reconfiguring or bringing the | ||
1815 | * interface up. Maintaining countermeasures across this would | ||
1816 | * be confusing, so note that we've disabled them. The port will | ||
1817 | * be enabled later in orinoco_commit or __orinoco_up. */ | ||
1818 | priv->tkip_cm_active = 0; | ||
1819 | |||
1816 | err = orinoco_hw_program_rids(priv); | 1820 | err = orinoco_hw_program_rids(priv); |
1817 | 1821 | ||
1818 | /* FIXME: what about netif_tx_lock */ | 1822 | /* FIXME: what about netif_tx_lock */ |
diff --git a/drivers/net/wireless/orinoco/orinoco_cs.c b/drivers/net/wireless/orinoco/orinoco_cs.c index 71b3d68b9403..32954c4b243a 100644 --- a/drivers/net/wireless/orinoco/orinoco_cs.c +++ b/drivers/net/wireless/orinoco/orinoco_cs.c | |||
@@ -151,20 +151,20 @@ orinoco_cs_config(struct pcmcia_device *link) | |||
151 | goto failed; | 151 | goto failed; |
152 | } | 152 | } |
153 | 153 | ||
154 | ret = pcmcia_request_irq(link, orinoco_interrupt); | ||
155 | if (ret) | ||
156 | goto failed; | ||
157 | |||
158 | /* We initialize the hermes structure before completing PCMCIA | ||
159 | * configuration just in case the interrupt handler gets | ||
160 | * called. */ | ||
161 | mem = ioport_map(link->resource[0]->start, | 154 | mem = ioport_map(link->resource[0]->start, |
162 | resource_size(link->resource[0])); | 155 | resource_size(link->resource[0])); |
163 | if (!mem) | 156 | if (!mem) |
164 | goto failed; | 157 | goto failed; |
165 | 158 | ||
159 | /* We initialize the hermes structure before completing PCMCIA | ||
160 | * configuration just in case the interrupt handler gets | ||
161 | * called. */ | ||
166 | hermes_struct_init(hw, mem, HERMES_16BIT_REGSPACING); | 162 | hermes_struct_init(hw, mem, HERMES_16BIT_REGSPACING); |
167 | 163 | ||
164 | ret = pcmcia_request_irq(link, orinoco_interrupt); | ||
165 | if (ret) | ||
166 | goto failed; | ||
167 | |||
168 | ret = pcmcia_enable_device(link); | 168 | ret = pcmcia_enable_device(link); |
169 | if (ret) | 169 | if (ret) |
170 | goto failed; | 170 | goto failed; |
diff --git a/drivers/net/wireless/orinoco/scan.c b/drivers/net/wireless/orinoco/scan.c index 4300d9db7d8c..86cb54c842e7 100644 --- a/drivers/net/wireless/orinoco/scan.c +++ b/drivers/net/wireless/orinoco/scan.c | |||
@@ -229,3 +229,11 @@ void orinoco_add_hostscan_results(struct orinoco_private *priv, | |||
229 | priv->scan_request = NULL; | 229 | priv->scan_request = NULL; |
230 | } | 230 | } |
231 | } | 231 | } |
232 | |||
233 | void orinoco_scan_done(struct orinoco_private *priv, bool abort) | ||
234 | { | ||
235 | if (priv->scan_request) { | ||
236 | cfg80211_scan_done(priv->scan_request, abort); | ||
237 | priv->scan_request = NULL; | ||
238 | } | ||
239 | } | ||
diff --git a/drivers/net/wireless/orinoco/scan.h b/drivers/net/wireless/orinoco/scan.h index 2dc4e046dbdb..27281fb0a6dc 100644 --- a/drivers/net/wireless/orinoco/scan.h +++ b/drivers/net/wireless/orinoco/scan.h | |||
@@ -16,5 +16,6 @@ void orinoco_add_extscan_result(struct orinoco_private *priv, | |||
16 | void orinoco_add_hostscan_results(struct orinoco_private *dev, | 16 | void orinoco_add_hostscan_results(struct orinoco_private *dev, |
17 | unsigned char *buf, | 17 | unsigned char *buf, |
18 | size_t len); | 18 | size_t len); |
19 | void orinoco_scan_done(struct orinoco_private *priv, bool abort); | ||
19 | 20 | ||
20 | #endif /* _ORINOCO_SCAN_H_ */ | 21 | #endif /* _ORINOCO_SCAN_H_ */ |
diff --git a/drivers/net/wireless/orinoco/spectrum_cs.c b/drivers/net/wireless/orinoco/spectrum_cs.c index fb859a5ad2eb..db34c282e59b 100644 --- a/drivers/net/wireless/orinoco/spectrum_cs.c +++ b/drivers/net/wireless/orinoco/spectrum_cs.c | |||
@@ -214,21 +214,21 @@ spectrum_cs_config(struct pcmcia_device *link) | |||
214 | goto failed; | 214 | goto failed; |
215 | } | 215 | } |
216 | 216 | ||
217 | ret = pcmcia_request_irq(link, orinoco_interrupt); | ||
218 | if (ret) | ||
219 | goto failed; | ||
220 | |||
221 | /* We initialize the hermes structure before completing PCMCIA | ||
222 | * configuration just in case the interrupt handler gets | ||
223 | * called. */ | ||
224 | mem = ioport_map(link->resource[0]->start, | 217 | mem = ioport_map(link->resource[0]->start, |
225 | resource_size(link->resource[0])); | 218 | resource_size(link->resource[0])); |
226 | if (!mem) | 219 | if (!mem) |
227 | goto failed; | 220 | goto failed; |
228 | 221 | ||
222 | /* We initialize the hermes structure before completing PCMCIA | ||
223 | * configuration just in case the interrupt handler gets | ||
224 | * called. */ | ||
229 | hermes_struct_init(hw, mem, HERMES_16BIT_REGSPACING); | 225 | hermes_struct_init(hw, mem, HERMES_16BIT_REGSPACING); |
230 | hw->eeprom_pda = true; | 226 | hw->eeprom_pda = true; |
231 | 227 | ||
228 | ret = pcmcia_request_irq(link, orinoco_interrupt); | ||
229 | if (ret) | ||
230 | goto failed; | ||
231 | |||
232 | ret = pcmcia_enable_device(link); | 232 | ret = pcmcia_enable_device(link); |
233 | if (ret) | 233 | if (ret) |
234 | goto failed; | 234 | goto failed; |
diff --git a/drivers/net/wireless/orinoco/wext.c b/drivers/net/wireless/orinoco/wext.c index 93505f93bf97..e5afabee60d1 100644 --- a/drivers/net/wireless/orinoco/wext.c +++ b/drivers/net/wireless/orinoco/wext.c | |||
@@ -911,10 +911,10 @@ static int orinoco_ioctl_set_auth(struct net_device *dev, | |||
911 | */ | 911 | */ |
912 | if (param->value) { | 912 | if (param->value) { |
913 | priv->tkip_cm_active = 1; | 913 | priv->tkip_cm_active = 1; |
914 | ret = hermes_enable_port(hw, 0); | 914 | ret = hermes_disable_port(hw, 0); |
915 | } else { | 915 | } else { |
916 | priv->tkip_cm_active = 0; | 916 | priv->tkip_cm_active = 0; |
917 | ret = hermes_disable_port(hw, 0); | 917 | ret = hermes_enable_port(hw, 0); |
918 | } | 918 | } |
919 | break; | 919 | break; |
920 | 920 | ||
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index 458bb57914a3..cdbeec9f83ea 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c | |||
@@ -66,8 +66,8 @@ struct netfront_cb { | |||
66 | 66 | ||
67 | #define GRANT_INVALID_REF 0 | 67 | #define GRANT_INVALID_REF 0 |
68 | 68 | ||
69 | #define NET_TX_RING_SIZE __RING_SIZE((struct xen_netif_tx_sring *)0, PAGE_SIZE) | 69 | #define NET_TX_RING_SIZE __CONST_RING_SIZE(xen_netif_tx, PAGE_SIZE) |
70 | #define NET_RX_RING_SIZE __RING_SIZE((struct xen_netif_rx_sring *)0, PAGE_SIZE) | 70 | #define NET_RX_RING_SIZE __CONST_RING_SIZE(xen_netif_rx, PAGE_SIZE) |
71 | #define TX_MAX_TARGET min_t(int, NET_RX_RING_SIZE, 256) | 71 | #define TX_MAX_TARGET min_t(int, NET_RX_RING_SIZE, 256) |
72 | 72 | ||
73 | struct netfront_info { | 73 | struct netfront_info { |
diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig index c80a7a6e7698..de886f3dfd39 100644 --- a/drivers/pcmcia/Kconfig +++ b/drivers/pcmcia/Kconfig | |||
@@ -215,7 +215,8 @@ config PCMCIA_PXA2XX | |||
215 | depends on (ARCH_LUBBOCK || MACH_MAINSTONE || PXA_SHARPSL \ | 215 | depends on (ARCH_LUBBOCK || MACH_MAINSTONE || PXA_SHARPSL \ |
216 | || MACH_ARMCORE || ARCH_PXA_PALM || TRIZEPS_PCMCIA \ | 216 | || MACH_ARMCORE || ARCH_PXA_PALM || TRIZEPS_PCMCIA \ |
217 | || ARCOM_PCMCIA || ARCH_PXA_ESERIES || MACH_STARGATE2 \ | 217 | || ARCOM_PCMCIA || ARCH_PXA_ESERIES || MACH_STARGATE2 \ |
218 | || MACH_VPAC270 || MACH_BALLOON3) | 218 | || MACH_VPAC270 || MACH_BALLOON3 || MACH_COLIBRI \ |
219 | || MACH_COLIBRI320) | ||
219 | select PCMCIA_SOC_COMMON | 220 | select PCMCIA_SOC_COMMON |
220 | help | 221 | help |
221 | Say Y here to include support for the PXA2xx PCMCIA controller | 222 | Say Y here to include support for the PXA2xx PCMCIA controller |
diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile index 8d9386a22eb3..9a44a90dcf7a 100644 --- a/drivers/pcmcia/Makefile +++ b/drivers/pcmcia/Makefile | |||
@@ -70,6 +70,8 @@ pxa2xx-obj-$(CONFIG_MACH_E740) += pxa2xx_e740.o | |||
70 | pxa2xx-obj-$(CONFIG_MACH_STARGATE2) += pxa2xx_stargate2.o | 70 | pxa2xx-obj-$(CONFIG_MACH_STARGATE2) += pxa2xx_stargate2.o |
71 | pxa2xx-obj-$(CONFIG_MACH_VPAC270) += pxa2xx_vpac270.o | 71 | pxa2xx-obj-$(CONFIG_MACH_VPAC270) += pxa2xx_vpac270.o |
72 | pxa2xx-obj-$(CONFIG_MACH_BALLOON3) += pxa2xx_balloon3.o | 72 | pxa2xx-obj-$(CONFIG_MACH_BALLOON3) += pxa2xx_balloon3.o |
73 | pxa2xx-obj-$(CONFIG_MACH_COLIBRI) += pxa2xx_colibri.o | ||
74 | pxa2xx-obj-$(CONFIG_MACH_COLIBRI320) += pxa2xx_colibri.o | ||
73 | 75 | ||
74 | obj-$(CONFIG_PCMCIA_PXA2XX) += pxa2xx_base.o $(pxa2xx-obj-y) | 76 | obj-$(CONFIG_PCMCIA_PXA2XX) += pxa2xx_base.o $(pxa2xx-obj-y) |
75 | 77 | ||
diff --git a/drivers/pcmcia/pxa2xx_balloon3.c b/drivers/pcmcia/pxa2xx_balloon3.c index dbbdd0063202..453c54c97612 100644 --- a/drivers/pcmcia/pxa2xx_balloon3.c +++ b/drivers/pcmcia/pxa2xx_balloon3.c | |||
@@ -39,12 +39,10 @@ static struct pcmcia_irqs irqs[] = { | |||
39 | static int balloon3_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | 39 | static int balloon3_pcmcia_hw_init(struct soc_pcmcia_socket *skt) |
40 | { | 40 | { |
41 | uint16_t ver; | 41 | uint16_t ver; |
42 | int ret; | ||
43 | static void __iomem *fpga_ver; | ||
44 | 42 | ||
45 | ver = __raw_readw(BALLOON3_FPGA_VER); | 43 | ver = __raw_readw(BALLOON3_FPGA_VER); |
46 | if (ver > 0x0201) | 44 | if (ver < 0x4f08) |
47 | pr_warn("The FPGA code, version 0x%04x, is newer than rel-0.3. " | 45 | pr_warn("The FPGA code, version 0x%04x, is too old. " |
48 | "PCMCIA/CF support might be broken in this version!", | 46 | "PCMCIA/CF support might be broken in this version!", |
49 | ver); | 47 | ver); |
50 | 48 | ||
@@ -97,8 +95,9 @@ static void balloon3_pcmcia_socket_state(struct soc_pcmcia_socket *skt, | |||
97 | static int balloon3_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, | 95 | static int balloon3_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, |
98 | const socket_state_t *state) | 96 | const socket_state_t *state) |
99 | { | 97 | { |
100 | __raw_writew((state->flags & SS_RESET) ? BALLOON3_CF_RESET : 0, | 98 | __raw_writew(BALLOON3_CF_RESET, BALLOON3_CF_CONTROL_REG | |
101 | BALLOON3_CF_CONTROL_REG); | 99 | ((state->flags & SS_RESET) ? |
100 | BALLOON3_FPGA_SETnCLR : 0)); | ||
102 | return 0; | 101 | return 0; |
103 | } | 102 | } |
104 | 103 | ||
diff --git a/drivers/pcmcia/pxa2xx_base.c b/drivers/pcmcia/pxa2xx_base.c index ae07b4db8a6e..3755e7c8c715 100644 --- a/drivers/pcmcia/pxa2xx_base.c +++ b/drivers/pcmcia/pxa2xx_base.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/platform_device.h> | 26 | #include <linux/platform_device.h> |
27 | 27 | ||
28 | #include <mach/hardware.h> | 28 | #include <mach/hardware.h> |
29 | #include <mach/smemc.h> | ||
29 | #include <asm/io.h> | 30 | #include <asm/io.h> |
30 | #include <asm/irq.h> | 31 | #include <asm/irq.h> |
31 | #include <asm/system.h> | 32 | #include <asm/system.h> |
@@ -116,37 +117,49 @@ static inline u_int pxa2xx_pcmcia_cmd_time(u_int mem_clk_10khz, | |||
116 | 117 | ||
117 | static int pxa2xx_pcmcia_set_mcmem( int sock, int speed, int clock ) | 118 | static int pxa2xx_pcmcia_set_mcmem( int sock, int speed, int clock ) |
118 | { | 119 | { |
119 | MCMEM(sock) = ((pxa2xx_mcxx_setup(speed, clock) | 120 | uint32_t val; |
121 | |||
122 | val = ((pxa2xx_mcxx_setup(speed, clock) | ||
120 | & MCXX_SETUP_MASK) << MCXX_SETUP_SHIFT) | 123 | & MCXX_SETUP_MASK) << MCXX_SETUP_SHIFT) |
121 | | ((pxa2xx_mcxx_asst(speed, clock) | 124 | | ((pxa2xx_mcxx_asst(speed, clock) |
122 | & MCXX_ASST_MASK) << MCXX_ASST_SHIFT) | 125 | & MCXX_ASST_MASK) << MCXX_ASST_SHIFT) |
123 | | ((pxa2xx_mcxx_hold(speed, clock) | 126 | | ((pxa2xx_mcxx_hold(speed, clock) |
124 | & MCXX_HOLD_MASK) << MCXX_HOLD_SHIFT); | 127 | & MCXX_HOLD_MASK) << MCXX_HOLD_SHIFT); |
125 | 128 | ||
129 | __raw_writel(val, MCMEM(sock)); | ||
130 | |||
126 | return 0; | 131 | return 0; |
127 | } | 132 | } |
128 | 133 | ||
129 | static int pxa2xx_pcmcia_set_mcio( int sock, int speed, int clock ) | 134 | static int pxa2xx_pcmcia_set_mcio( int sock, int speed, int clock ) |
130 | { | 135 | { |
131 | MCIO(sock) = ((pxa2xx_mcxx_setup(speed, clock) | 136 | uint32_t val; |
137 | |||
138 | val = ((pxa2xx_mcxx_setup(speed, clock) | ||
132 | & MCXX_SETUP_MASK) << MCXX_SETUP_SHIFT) | 139 | & MCXX_SETUP_MASK) << MCXX_SETUP_SHIFT) |
133 | | ((pxa2xx_mcxx_asst(speed, clock) | 140 | | ((pxa2xx_mcxx_asst(speed, clock) |
134 | & MCXX_ASST_MASK) << MCXX_ASST_SHIFT) | 141 | & MCXX_ASST_MASK) << MCXX_ASST_SHIFT) |
135 | | ((pxa2xx_mcxx_hold(speed, clock) | 142 | | ((pxa2xx_mcxx_hold(speed, clock) |
136 | & MCXX_HOLD_MASK) << MCXX_HOLD_SHIFT); | 143 | & MCXX_HOLD_MASK) << MCXX_HOLD_SHIFT); |
137 | 144 | ||
145 | __raw_writel(val, MCIO(sock)); | ||
146 | |||
138 | return 0; | 147 | return 0; |
139 | } | 148 | } |
140 | 149 | ||
141 | static int pxa2xx_pcmcia_set_mcatt( int sock, int speed, int clock ) | 150 | static int pxa2xx_pcmcia_set_mcatt( int sock, int speed, int clock ) |
142 | { | 151 | { |
143 | MCATT(sock) = ((pxa2xx_mcxx_setup(speed, clock) | 152 | uint32_t val; |
153 | |||
154 | val = ((pxa2xx_mcxx_setup(speed, clock) | ||
144 | & MCXX_SETUP_MASK) << MCXX_SETUP_SHIFT) | 155 | & MCXX_SETUP_MASK) << MCXX_SETUP_SHIFT) |
145 | | ((pxa2xx_mcxx_asst(speed, clock) | 156 | | ((pxa2xx_mcxx_asst(speed, clock) |
146 | & MCXX_ASST_MASK) << MCXX_ASST_SHIFT) | 157 | & MCXX_ASST_MASK) << MCXX_ASST_SHIFT) |
147 | | ((pxa2xx_mcxx_hold(speed, clock) | 158 | | ((pxa2xx_mcxx_hold(speed, clock) |
148 | & MCXX_HOLD_MASK) << MCXX_HOLD_SHIFT); | 159 | & MCXX_HOLD_MASK) << MCXX_HOLD_SHIFT); |
149 | 160 | ||
161 | __raw_writel(val, MCATT(sock)); | ||
162 | |||
150 | return 0; | 163 | return 0; |
151 | } | 164 | } |
152 | 165 | ||
@@ -166,8 +179,8 @@ static int pxa2xx_pcmcia_set_mcxx(struct soc_pcmcia_socket *skt, unsigned int cl | |||
166 | 179 | ||
167 | static int pxa2xx_pcmcia_set_timing(struct soc_pcmcia_socket *skt) | 180 | static int pxa2xx_pcmcia_set_timing(struct soc_pcmcia_socket *skt) |
168 | { | 181 | { |
169 | unsigned int clk = get_memclk_frequency_10khz(); | 182 | unsigned long clk = clk_get_rate(skt->clk); |
170 | return pxa2xx_pcmcia_set_mcxx(skt, clk); | 183 | return pxa2xx_pcmcia_set_mcxx(skt, clk / 10000); |
171 | } | 184 | } |
172 | 185 | ||
173 | #ifdef CONFIG_CPU_FREQ | 186 | #ifdef CONFIG_CPU_FREQ |
@@ -205,19 +218,18 @@ pxa2xx_pcmcia_frequency_change(struct soc_pcmcia_socket *skt, | |||
205 | static void pxa2xx_configure_sockets(struct device *dev) | 218 | static void pxa2xx_configure_sockets(struct device *dev) |
206 | { | 219 | { |
207 | struct pcmcia_low_level *ops = dev->platform_data; | 220 | struct pcmcia_low_level *ops = dev->platform_data; |
208 | |||
209 | /* | 221 | /* |
210 | * We have at least one socket, so set MECR:CIT | 222 | * We have at least one socket, so set MECR:CIT |
211 | * (Card Is There) | 223 | * (Card Is There) |
212 | */ | 224 | */ |
213 | MECR |= MECR_CIT; | 225 | uint32_t mecr = MECR_CIT; |
214 | 226 | ||
215 | /* Set MECR:NOS (Number Of Sockets) */ | 227 | /* Set MECR:NOS (Number Of Sockets) */ |
216 | if ((ops->first + ops->nr) > 1 || | 228 | if ((ops->first + ops->nr) > 1 || |
217 | machine_is_viper() || machine_is_arcom_zeus()) | 229 | machine_is_viper() || machine_is_arcom_zeus()) |
218 | MECR |= MECR_NOS; | 230 | mecr |= MECR_NOS; |
219 | else | 231 | |
220 | MECR &= ~MECR_NOS; | 232 | __raw_writel(mecr, MECR); |
221 | } | 233 | } |
222 | 234 | ||
223 | static const char *skt_names[] = { | 235 | static const char *skt_names[] = { |
@@ -270,24 +282,41 @@ static int pxa2xx_drv_pcmcia_probe(struct platform_device *dev) | |||
270 | struct pcmcia_low_level *ops; | 282 | struct pcmcia_low_level *ops; |
271 | struct skt_dev_info *sinfo; | 283 | struct skt_dev_info *sinfo; |
272 | struct soc_pcmcia_socket *skt; | 284 | struct soc_pcmcia_socket *skt; |
285 | struct clk *clk; | ||
273 | 286 | ||
274 | ops = (struct pcmcia_low_level *)dev->dev.platform_data; | 287 | ops = (struct pcmcia_low_level *)dev->dev.platform_data; |
275 | if (!ops) | 288 | if (!ops) { |
289 | ret = -ENODEV; | ||
290 | goto err0; | ||
291 | } | ||
292 | |||
293 | if (cpu_is_pxa320() && ops->nr > 1) { | ||
294 | dev_err(&dev->dev, "pxa320 supports only one pcmcia slot"); | ||
295 | ret = -EINVAL; | ||
296 | goto err0; | ||
297 | } | ||
298 | |||
299 | clk = clk_get(&dev->dev, NULL); | ||
300 | if (!clk) | ||
276 | return -ENODEV; | 301 | return -ENODEV; |
277 | 302 | ||
278 | pxa2xx_drv_pcmcia_ops(ops); | 303 | pxa2xx_drv_pcmcia_ops(ops); |
279 | 304 | ||
280 | sinfo = kzalloc(SKT_DEV_INFO_SIZE(ops->nr), GFP_KERNEL); | 305 | sinfo = kzalloc(SKT_DEV_INFO_SIZE(ops->nr), GFP_KERNEL); |
281 | if (!sinfo) | 306 | if (!sinfo) { |
307 | clk_put(clk); | ||
282 | return -ENOMEM; | 308 | return -ENOMEM; |
309 | } | ||
283 | 310 | ||
284 | sinfo->nskt = ops->nr; | 311 | sinfo->nskt = ops->nr; |
312 | sinfo->clk = clk; | ||
285 | 313 | ||
286 | /* Initialize processor specific parameters */ | 314 | /* Initialize processor specific parameters */ |
287 | for (i = 0; i < ops->nr; i++) { | 315 | for (i = 0; i < ops->nr; i++) { |
288 | skt = &sinfo->skt[i]; | 316 | skt = &sinfo->skt[i]; |
289 | 317 | ||
290 | skt->nr = ops->first + i; | 318 | skt->nr = ops->first + i; |
319 | skt->clk = clk; | ||
291 | skt->ops = ops; | 320 | skt->ops = ops; |
292 | skt->socket.owner = ops->owner; | 321 | skt->socket.owner = ops->owner; |
293 | skt->socket.dev.parent = &dev->dev; | 322 | skt->socket.dev.parent = &dev->dev; |
@@ -295,18 +324,26 @@ static int pxa2xx_drv_pcmcia_probe(struct platform_device *dev) | |||
295 | 324 | ||
296 | ret = pxa2xx_drv_pcmcia_add_one(skt); | 325 | ret = pxa2xx_drv_pcmcia_add_one(skt); |
297 | if (ret) | 326 | if (ret) |
298 | break; | 327 | goto err1; |
299 | } | 328 | } |
300 | 329 | ||
301 | if (ret) { | 330 | if (ret) { |
302 | while (--i >= 0) | 331 | while (--i >= 0) |
303 | soc_pcmcia_remove_one(&sinfo->skt[i]); | 332 | soc_pcmcia_remove_one(&sinfo->skt[i]); |
304 | kfree(sinfo); | 333 | kfree(sinfo); |
334 | clk_put(clk); | ||
305 | } else { | 335 | } else { |
306 | pxa2xx_configure_sockets(&dev->dev); | 336 | pxa2xx_configure_sockets(&dev->dev); |
307 | dev_set_drvdata(&dev->dev, sinfo); | 337 | dev_set_drvdata(&dev->dev, sinfo); |
308 | } | 338 | } |
309 | 339 | ||
340 | return 0; | ||
341 | |||
342 | err1: | ||
343 | while (--i >= 0) | ||
344 | soc_pcmcia_remove_one(&sinfo->skt[i]); | ||
345 | kfree(sinfo); | ||
346 | err0: | ||
310 | return ret; | 347 | return ret; |
311 | } | 348 | } |
312 | 349 | ||
@@ -320,6 +357,7 @@ static int pxa2xx_drv_pcmcia_remove(struct platform_device *dev) | |||
320 | for (i = 0; i < sinfo->nskt; i++) | 357 | for (i = 0; i < sinfo->nskt; i++) |
321 | soc_pcmcia_remove_one(&sinfo->skt[i]); | 358 | soc_pcmcia_remove_one(&sinfo->skt[i]); |
322 | 359 | ||
360 | clk_put(sinfo->clk); | ||
323 | kfree(sinfo); | 361 | kfree(sinfo); |
324 | return 0; | 362 | return 0; |
325 | } | 363 | } |
diff --git a/drivers/pcmcia/pxa2xx_colibri.c b/drivers/pcmcia/pxa2xx_colibri.c new file mode 100644 index 000000000000..c3f72192af66 --- /dev/null +++ b/drivers/pcmcia/pxa2xx_colibri.c | |||
@@ -0,0 +1,229 @@ | |||
1 | /* | ||
2 | * linux/drivers/pcmcia/pxa2xx_colibri.c | ||
3 | * | ||
4 | * Driver for Toradex Colibri PXA270 CF socket | ||
5 | * | ||
6 | * Copyright (C) 2010 Marek Vasut <marek.vasut@gmail.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | * | ||
12 | */ | ||
13 | |||
14 | #include <linux/module.h> | ||
15 | #include <linux/platform_device.h> | ||
16 | #include <linux/delay.h> | ||
17 | #include <linux/gpio.h> | ||
18 | |||
19 | #include <asm/mach-types.h> | ||
20 | |||
21 | #include "soc_common.h" | ||
22 | |||
23 | #define COLIBRI270_RESET_GPIO 53 | ||
24 | #define COLIBRI270_PPEN_GPIO 107 | ||
25 | #define COLIBRI270_BVD1_GPIO 83 | ||
26 | #define COLIBRI270_BVD2_GPIO 82 | ||
27 | #define COLIBRI270_DETECT_GPIO 84 | ||
28 | #define COLIBRI270_READY_GPIO 1 | ||
29 | |||
30 | #define COLIBRI320_RESET_GPIO 77 | ||
31 | #define COLIBRI320_PPEN_GPIO 57 | ||
32 | #define COLIBRI320_BVD1_GPIO 53 | ||
33 | #define COLIBRI320_BVD2_GPIO 79 | ||
34 | #define COLIBRI320_DETECT_GPIO 81 | ||
35 | #define COLIBRI320_READY_GPIO 29 | ||
36 | |||
37 | static struct { | ||
38 | int reset_gpio; | ||
39 | int ppen_gpio; | ||
40 | int bvd1_gpio; | ||
41 | int bvd2_gpio; | ||
42 | int detect_gpio; | ||
43 | int ready_gpio; | ||
44 | } colibri_pcmcia_gpio; | ||
45 | |||
46 | static struct pcmcia_irqs colibri_irqs[] = { | ||
47 | { | ||
48 | .sock = 0, | ||
49 | .str = "PCMCIA CD" | ||
50 | }, | ||
51 | }; | ||
52 | |||
53 | static int colibri_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | ||
54 | { | ||
55 | int ret; | ||
56 | |||
57 | ret = gpio_request(colibri_pcmcia_gpio.detect_gpio, "DETECT"); | ||
58 | if (ret) | ||
59 | goto err1; | ||
60 | ret = gpio_direction_input(colibri_pcmcia_gpio.detect_gpio); | ||
61 | if (ret) | ||
62 | goto err2; | ||
63 | |||
64 | ret = gpio_request(colibri_pcmcia_gpio.ready_gpio, "READY"); | ||
65 | if (ret) | ||
66 | goto err2; | ||
67 | ret = gpio_direction_input(colibri_pcmcia_gpio.ready_gpio); | ||
68 | if (ret) | ||
69 | goto err3; | ||
70 | |||
71 | ret = gpio_request(colibri_pcmcia_gpio.bvd1_gpio, "BVD1"); | ||
72 | if (ret) | ||
73 | goto err3; | ||
74 | ret = gpio_direction_input(colibri_pcmcia_gpio.bvd1_gpio); | ||
75 | if (ret) | ||
76 | goto err4; | ||
77 | |||
78 | ret = gpio_request(colibri_pcmcia_gpio.bvd2_gpio, "BVD2"); | ||
79 | if (ret) | ||
80 | goto err4; | ||
81 | ret = gpio_direction_input(colibri_pcmcia_gpio.bvd2_gpio); | ||
82 | if (ret) | ||
83 | goto err5; | ||
84 | |||
85 | ret = gpio_request(colibri_pcmcia_gpio.ppen_gpio, "PPEN"); | ||
86 | if (ret) | ||
87 | goto err5; | ||
88 | ret = gpio_direction_output(colibri_pcmcia_gpio.ppen_gpio, 0); | ||
89 | if (ret) | ||
90 | goto err6; | ||
91 | |||
92 | ret = gpio_request(colibri_pcmcia_gpio.reset_gpio, "RESET"); | ||
93 | if (ret) | ||
94 | goto err6; | ||
95 | ret = gpio_direction_output(colibri_pcmcia_gpio.reset_gpio, 1); | ||
96 | if (ret) | ||
97 | goto err7; | ||
98 | |||
99 | colibri_irqs[0].irq = gpio_to_irq(colibri_pcmcia_gpio.detect_gpio); | ||
100 | skt->socket.pci_irq = gpio_to_irq(colibri_pcmcia_gpio.ready_gpio); | ||
101 | |||
102 | return soc_pcmcia_request_irqs(skt, colibri_irqs, | ||
103 | ARRAY_SIZE(colibri_irqs)); | ||
104 | |||
105 | err7: | ||
106 | gpio_free(colibri_pcmcia_gpio.detect_gpio); | ||
107 | err6: | ||
108 | gpio_free(colibri_pcmcia_gpio.ready_gpio); | ||
109 | err5: | ||
110 | gpio_free(colibri_pcmcia_gpio.bvd1_gpio); | ||
111 | err4: | ||
112 | gpio_free(colibri_pcmcia_gpio.bvd2_gpio); | ||
113 | err3: | ||
114 | gpio_free(colibri_pcmcia_gpio.reset_gpio); | ||
115 | err2: | ||
116 | gpio_free(colibri_pcmcia_gpio.ppen_gpio); | ||
117 | err1: | ||
118 | return ret; | ||
119 | } | ||
120 | |||
121 | static void colibri_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) | ||
122 | { | ||
123 | gpio_free(colibri_pcmcia_gpio.detect_gpio); | ||
124 | gpio_free(colibri_pcmcia_gpio.ready_gpio); | ||
125 | gpio_free(colibri_pcmcia_gpio.bvd1_gpio); | ||
126 | gpio_free(colibri_pcmcia_gpio.bvd2_gpio); | ||
127 | gpio_free(colibri_pcmcia_gpio.reset_gpio); | ||
128 | gpio_free(colibri_pcmcia_gpio.ppen_gpio); | ||
129 | } | ||
130 | |||
131 | static void colibri_pcmcia_socket_state(struct soc_pcmcia_socket *skt, | ||
132 | struct pcmcia_state *state) | ||
133 | { | ||
134 | |||
135 | state->detect = !!gpio_get_value(colibri_pcmcia_gpio.detect_gpio); | ||
136 | state->ready = !!gpio_get_value(colibri_pcmcia_gpio.ready_gpio); | ||
137 | state->bvd1 = !!gpio_get_value(colibri_pcmcia_gpio.bvd1_gpio); | ||
138 | state->bvd2 = !!gpio_get_value(colibri_pcmcia_gpio.bvd2_gpio); | ||
139 | state->wrprot = 0; | ||
140 | state->vs_3v = 1; | ||
141 | state->vs_Xv = 0; | ||
142 | } | ||
143 | |||
144 | static int | ||
145 | colibri_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, | ||
146 | const socket_state_t *state) | ||
147 | { | ||
148 | gpio_set_value(colibri_pcmcia_gpio.ppen_gpio, | ||
149 | !(state->Vcc == 33 && state->Vpp < 50)); | ||
150 | gpio_set_value(colibri_pcmcia_gpio.reset_gpio, state->flags & SS_RESET); | ||
151 | return 0; | ||
152 | } | ||
153 | |||
154 | static void colibri_pcmcia_socket_init(struct soc_pcmcia_socket *skt) | ||
155 | { | ||
156 | } | ||
157 | |||
158 | static void colibri_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) | ||
159 | { | ||
160 | } | ||
161 | |||
162 | static struct pcmcia_low_level colibri_pcmcia_ops = { | ||
163 | .owner = THIS_MODULE, | ||
164 | |||
165 | .first = 0, | ||
166 | .nr = 1, | ||
167 | |||
168 | .hw_init = colibri_pcmcia_hw_init, | ||
169 | .hw_shutdown = colibri_pcmcia_hw_shutdown, | ||
170 | |||
171 | .socket_state = colibri_pcmcia_socket_state, | ||
172 | .configure_socket = colibri_pcmcia_configure_socket, | ||
173 | |||
174 | .socket_init = colibri_pcmcia_socket_init, | ||
175 | .socket_suspend = colibri_pcmcia_socket_suspend, | ||
176 | }; | ||
177 | |||
178 | static struct platform_device *colibri_pcmcia_device; | ||
179 | |||
180 | static int __init colibri_pcmcia_init(void) | ||
181 | { | ||
182 | int ret; | ||
183 | |||
184 | colibri_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1); | ||
185 | if (!colibri_pcmcia_device) | ||
186 | return -ENOMEM; | ||
187 | |||
188 | /* Colibri PXA270 */ | ||
189 | if (machine_is_colibri()) { | ||
190 | colibri_pcmcia_gpio.reset_gpio = COLIBRI270_RESET_GPIO; | ||
191 | colibri_pcmcia_gpio.ppen_gpio = COLIBRI270_PPEN_GPIO; | ||
192 | colibri_pcmcia_gpio.bvd1_gpio = COLIBRI270_BVD1_GPIO; | ||
193 | colibri_pcmcia_gpio.bvd2_gpio = COLIBRI270_BVD2_GPIO; | ||
194 | colibri_pcmcia_gpio.detect_gpio = COLIBRI270_DETECT_GPIO; | ||
195 | colibri_pcmcia_gpio.ready_gpio = COLIBRI270_READY_GPIO; | ||
196 | /* Colibri PXA320 */ | ||
197 | } else if (machine_is_colibri320()) { | ||
198 | colibri_pcmcia_gpio.reset_gpio = COLIBRI320_RESET_GPIO; | ||
199 | colibri_pcmcia_gpio.ppen_gpio = COLIBRI320_PPEN_GPIO; | ||
200 | colibri_pcmcia_gpio.bvd1_gpio = COLIBRI320_BVD1_GPIO; | ||
201 | colibri_pcmcia_gpio.bvd2_gpio = COLIBRI320_BVD2_GPIO; | ||
202 | colibri_pcmcia_gpio.detect_gpio = COLIBRI320_DETECT_GPIO; | ||
203 | colibri_pcmcia_gpio.ready_gpio = COLIBRI320_READY_GPIO; | ||
204 | } | ||
205 | |||
206 | ret = platform_device_add_data(colibri_pcmcia_device, | ||
207 | &colibri_pcmcia_ops, sizeof(colibri_pcmcia_ops)); | ||
208 | |||
209 | if (!ret) | ||
210 | ret = platform_device_add(colibri_pcmcia_device); | ||
211 | |||
212 | if (ret) | ||
213 | platform_device_put(colibri_pcmcia_device); | ||
214 | |||
215 | return ret; | ||
216 | } | ||
217 | |||
218 | static void __exit colibri_pcmcia_exit(void) | ||
219 | { | ||
220 | platform_device_unregister(colibri_pcmcia_device); | ||
221 | } | ||
222 | |||
223 | module_init(colibri_pcmcia_init); | ||
224 | module_exit(colibri_pcmcia_exit); | ||
225 | |||
226 | MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>"); | ||
227 | MODULE_DESCRIPTION("PCMCIA support for Toradex Colibri PXA270/PXA320"); | ||
228 | MODULE_ALIAS("platform:pxa2xx-pcmcia"); | ||
229 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/pcmcia/soc_common.h b/drivers/pcmcia/soc_common.h index bbcd5385a221..9daa73615c8b 100644 --- a/drivers/pcmcia/soc_common.h +++ b/drivers/pcmcia/soc_common.h | |||
@@ -10,6 +10,7 @@ | |||
10 | #define _ASM_ARCH_PCMCIA | 10 | #define _ASM_ARCH_PCMCIA |
11 | 11 | ||
12 | /* include the world */ | 12 | /* include the world */ |
13 | #include <linux/clk.h> | ||
13 | #include <linux/cpufreq.h> | 14 | #include <linux/cpufreq.h> |
14 | #include <pcmcia/ss.h> | 15 | #include <pcmcia/ss.h> |
15 | #include <pcmcia/cistpl.h> | 16 | #include <pcmcia/cistpl.h> |
@@ -29,6 +30,7 @@ struct soc_pcmcia_socket { | |||
29 | * Info from low level handler | 30 | * Info from low level handler |
30 | */ | 31 | */ |
31 | unsigned int nr; | 32 | unsigned int nr; |
33 | struct clk *clk; | ||
32 | 34 | ||
33 | /* | 35 | /* |
34 | * Core PCMCIA state | 36 | * Core PCMCIA state |
@@ -56,6 +58,7 @@ struct soc_pcmcia_socket { | |||
56 | 58 | ||
57 | struct skt_dev_info { | 59 | struct skt_dev_info { |
58 | int nskt; | 60 | int nskt; |
61 | struct clk *clk; | ||
59 | struct soc_pcmcia_socket skt[0]; | 62 | struct soc_pcmcia_socket skt[0]; |
60 | }; | 63 | }; |
61 | 64 | ||
diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c index 2d73dfcecdbb..57313f4658bc 100644 --- a/drivers/pnp/pnpacpi/core.c +++ b/drivers/pnp/pnpacpi/core.c | |||
@@ -180,7 +180,7 @@ struct pnp_protocol pnpacpi_protocol = { | |||
180 | }; | 180 | }; |
181 | EXPORT_SYMBOL(pnpacpi_protocol); | 181 | EXPORT_SYMBOL(pnpacpi_protocol); |
182 | 182 | ||
183 | static char *pnpacpi_get_id(struct acpi_device *device) | 183 | static char *__init pnpacpi_get_id(struct acpi_device *device) |
184 | { | 184 | { |
185 | struct acpi_hardware_id *id; | 185 | struct acpi_hardware_id *id; |
186 | 186 | ||
diff --git a/drivers/regulator/tps6586x-regulator.c b/drivers/regulator/tps6586x-regulator.c index 51237fbb1bbb..6d20b0454a1d 100644 --- a/drivers/regulator/tps6586x-regulator.c +++ b/drivers/regulator/tps6586x-regulator.c | |||
@@ -231,8 +231,7 @@ static int tps6586x_dvm_voltages[] = { | |||
231 | }; | 231 | }; |
232 | 232 | ||
233 | #define TPS6586X_REGULATOR(_id, vdata, _ops, vreg, shift, nbits, \ | 233 | #define TPS6586X_REGULATOR(_id, vdata, _ops, vreg, shift, nbits, \ |
234 | ereg0, ebit0, ereg1, ebit1, goreg, gobit) \ | 234 | ereg0, ebit0, ereg1, ebit1) \ |
235 | { \ | ||
236 | .desc = { \ | 235 | .desc = { \ |
237 | .name = "REG-" #_id, \ | 236 | .name = "REG-" #_id, \ |
238 | .ops = &tps6586x_regulator_##_ops, \ | 237 | .ops = &tps6586x_regulator_##_ops, \ |
@@ -248,18 +247,26 @@ static int tps6586x_dvm_voltages[] = { | |||
248 | .enable_bit[0] = (ebit0), \ | 247 | .enable_bit[0] = (ebit0), \ |
249 | .enable_reg[1] = TPS6586X_SUPPLY##ereg1, \ | 248 | .enable_reg[1] = TPS6586X_SUPPLY##ereg1, \ |
250 | .enable_bit[1] = (ebit1), \ | 249 | .enable_bit[1] = (ebit1), \ |
251 | .voltages = tps6586x_##vdata##_voltages, \ | 250 | .voltages = tps6586x_##vdata##_voltages, |
252 | } | 251 | |
252 | #define TPS6586X_REGULATOR_DVM_GOREG(goreg, gobit) \ | ||
253 | .go_reg = TPS6586X_##goreg, \ | ||
254 | .go_bit = (gobit), | ||
253 | 255 | ||
254 | #define TPS6586X_LDO(_id, vdata, vreg, shift, nbits, \ | 256 | #define TPS6586X_LDO(_id, vdata, vreg, shift, nbits, \ |
255 | ereg0, ebit0, ereg1, ebit1) \ | 257 | ereg0, ebit0, ereg1, ebit1) \ |
258 | { \ | ||
256 | TPS6586X_REGULATOR(_id, vdata, ldo_ops, vreg, shift, nbits, \ | 259 | TPS6586X_REGULATOR(_id, vdata, ldo_ops, vreg, shift, nbits, \ |
257 | ereg0, ebit0, ereg1, ebit1, 0, 0) | 260 | ereg0, ebit0, ereg1, ebit1) \ |
261 | } | ||
258 | 262 | ||
259 | #define TPS6586X_DVM(_id, vdata, vreg, shift, nbits, \ | 263 | #define TPS6586X_DVM(_id, vdata, vreg, shift, nbits, \ |
260 | ereg0, ebit0, ereg1, ebit1, goreg, gobit) \ | 264 | ereg0, ebit0, ereg1, ebit1, goreg, gobit) \ |
265 | { \ | ||
261 | TPS6586X_REGULATOR(_id, vdata, dvm_ops, vreg, shift, nbits, \ | 266 | TPS6586X_REGULATOR(_id, vdata, dvm_ops, vreg, shift, nbits, \ |
262 | ereg0, ebit0, ereg1, ebit1, goreg, gobit) | 267 | ereg0, ebit0, ereg1, ebit1) \ |
268 | TPS6586X_REGULATOR_DVM_GOREG(goreg, gobit) \ | ||
269 | } | ||
263 | 270 | ||
264 | static struct tps6586x_regulator tps6586x_regulator[] = { | 271 | static struct tps6586x_regulator tps6586x_regulator[] = { |
265 | TPS6586X_LDO(LDO_0, ldo, SUPPLYV1, 5, 3, ENC, 0, END, 0), | 272 | TPS6586X_LDO(LDO_0, ldo, SUPPLYV1, 5, 3, ENC, 0, END, 0), |
@@ -267,11 +274,11 @@ static struct tps6586x_regulator tps6586x_regulator[] = { | |||
267 | TPS6586X_LDO(LDO_5, ldo, SUPPLYV6, 0, 3, ENE, 6, ENE, 6), | 274 | TPS6586X_LDO(LDO_5, ldo, SUPPLYV6, 0, 3, ENE, 6, ENE, 6), |
268 | TPS6586X_LDO(LDO_6, ldo, SUPPLYV3, 0, 3, ENC, 4, END, 4), | 275 | TPS6586X_LDO(LDO_6, ldo, SUPPLYV3, 0, 3, ENC, 4, END, 4), |
269 | TPS6586X_LDO(LDO_7, ldo, SUPPLYV3, 3, 3, ENC, 5, END, 5), | 276 | TPS6586X_LDO(LDO_7, ldo, SUPPLYV3, 3, 3, ENC, 5, END, 5), |
270 | TPS6586X_LDO(LDO_8, ldo, SUPPLYV1, 5, 3, ENC, 6, END, 6), | 277 | TPS6586X_LDO(LDO_8, ldo, SUPPLYV2, 5, 3, ENC, 6, END, 6), |
271 | TPS6586X_LDO(LDO_9, ldo, SUPPLYV6, 3, 3, ENE, 7, ENE, 7), | 278 | TPS6586X_LDO(LDO_9, ldo, SUPPLYV6, 3, 3, ENE, 7, ENE, 7), |
272 | TPS6586X_LDO(LDO_RTC, ldo, SUPPLYV4, 3, 3, ENE, 7, ENE, 7), | 279 | TPS6586X_LDO(LDO_RTC, ldo, SUPPLYV4, 3, 3, V4, 7, V4, 7), |
273 | TPS6586X_LDO(LDO_1, dvm, SUPPLYV1, 0, 5, ENC, 1, END, 1), | 280 | TPS6586X_LDO(LDO_1, dvm, SUPPLYV1, 0, 5, ENC, 1, END, 1), |
274 | TPS6586X_LDO(SM_2, sm2, SUPPLYV2, 0, 5, ENC, 1, END, 1), | 281 | TPS6586X_LDO(SM_2, sm2, SUPPLYV2, 0, 5, ENC, 7, END, 7), |
275 | 282 | ||
276 | TPS6586X_DVM(LDO_2, dvm, LDO2BV1, 0, 5, ENA, 3, ENB, 3, VCC2, 6), | 283 | TPS6586X_DVM(LDO_2, dvm, LDO2BV1, 0, 5, ENA, 3, ENB, 3, VCC2, 6), |
277 | TPS6586X_DVM(LDO_4, ldo4, LDO4V1, 0, 5, ENC, 3, END, 3, VCC1, 6), | 284 | TPS6586X_DVM(LDO_4, ldo4, LDO4V1, 0, 5, ENC, 3, END, 3, VCC1, 6), |
@@ -290,6 +297,10 @@ static inline int tps6586x_regulator_preinit(struct device *parent, | |||
290 | uint8_t val1, val2; | 297 | uint8_t val1, val2; |
291 | int ret; | 298 | int ret; |
292 | 299 | ||
300 | if (ri->enable_reg[0] == ri->enable_reg[1] && | ||
301 | ri->enable_bit[0] == ri->enable_bit[1]) | ||
302 | return 0; | ||
303 | |||
293 | ret = tps6586x_read(parent, ri->enable_reg[0], &val1); | 304 | ret = tps6586x_read(parent, ri->enable_reg[0], &val1); |
294 | if (ret) | 305 | if (ret) |
295 | return ret; | 306 | return ret; |
@@ -298,14 +309,14 @@ static inline int tps6586x_regulator_preinit(struct device *parent, | |||
298 | if (ret) | 309 | if (ret) |
299 | return ret; | 310 | return ret; |
300 | 311 | ||
301 | if (!(val2 & ri->enable_bit[1])) | 312 | if (!(val2 & (1 << ri->enable_bit[1]))) |
302 | return 0; | 313 | return 0; |
303 | 314 | ||
304 | /* | 315 | /* |
305 | * The regulator is on, but it's enabled with the bit we don't | 316 | * The regulator is on, but it's enabled with the bit we don't |
306 | * want to use, so we switch the enable bits | 317 | * want to use, so we switch the enable bits |
307 | */ | 318 | */ |
308 | if (!(val1 & ri->enable_bit[0])) { | 319 | if (!(val1 & (1 << ri->enable_bit[0]))) { |
309 | ret = tps6586x_set_bits(parent, ri->enable_reg[0], | 320 | ret = tps6586x_set_bits(parent, ri->enable_reg[0], |
310 | 1 << ri->enable_bit[0]); | 321 | 1 << ri->enable_bit[0]); |
311 | if (ret) | 322 | if (ret) |
diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c index d37c7331f244..0bcd5806bd9a 100644 --- a/drivers/s390/scsi/zfcp_erp.c +++ b/drivers/s390/scsi/zfcp_erp.c | |||
@@ -156,6 +156,8 @@ static int zfcp_erp_required_act(int want, struct zfcp_adapter *adapter, | |||
156 | if (!(a_status & ZFCP_STATUS_COMMON_RUNNING) || | 156 | if (!(a_status & ZFCP_STATUS_COMMON_RUNNING) || |
157 | a_status & ZFCP_STATUS_COMMON_ERP_FAILED) | 157 | a_status & ZFCP_STATUS_COMMON_ERP_FAILED) |
158 | return 0; | 158 | return 0; |
159 | if (p_status & ZFCP_STATUS_COMMON_NOESC) | ||
160 | return need; | ||
159 | if (!(a_status & ZFCP_STATUS_COMMON_UNBLOCKED)) | 161 | if (!(a_status & ZFCP_STATUS_COMMON_UNBLOCKED)) |
160 | need = ZFCP_ERP_ACTION_REOPEN_ADAPTER; | 162 | need = ZFCP_ERP_ACTION_REOPEN_ADAPTER; |
161 | /* fall through */ | 163 | /* fall through */ |
@@ -188,6 +190,9 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need, u32 act_status, | |||
188 | atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, | 190 | atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, |
189 | &zfcp_sdev->status); | 191 | &zfcp_sdev->status); |
190 | erp_action = &zfcp_sdev->erp_action; | 192 | erp_action = &zfcp_sdev->erp_action; |
193 | memset(erp_action, 0, sizeof(struct zfcp_erp_action)); | ||
194 | erp_action->port = port; | ||
195 | erp_action->sdev = sdev; | ||
191 | if (!(atomic_read(&zfcp_sdev->status) & | 196 | if (!(atomic_read(&zfcp_sdev->status) & |
192 | ZFCP_STATUS_COMMON_RUNNING)) | 197 | ZFCP_STATUS_COMMON_RUNNING)) |
193 | act_status |= ZFCP_STATUS_ERP_CLOSE_ONLY; | 198 | act_status |= ZFCP_STATUS_ERP_CLOSE_ONLY; |
@@ -200,6 +205,8 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need, u32 act_status, | |||
200 | zfcp_erp_action_dismiss_port(port); | 205 | zfcp_erp_action_dismiss_port(port); |
201 | atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &port->status); | 206 | atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &port->status); |
202 | erp_action = &port->erp_action; | 207 | erp_action = &port->erp_action; |
208 | memset(erp_action, 0, sizeof(struct zfcp_erp_action)); | ||
209 | erp_action->port = port; | ||
203 | if (!(atomic_read(&port->status) & ZFCP_STATUS_COMMON_RUNNING)) | 210 | if (!(atomic_read(&port->status) & ZFCP_STATUS_COMMON_RUNNING)) |
204 | act_status |= ZFCP_STATUS_ERP_CLOSE_ONLY; | 211 | act_status |= ZFCP_STATUS_ERP_CLOSE_ONLY; |
205 | break; | 212 | break; |
@@ -209,6 +216,7 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need, u32 act_status, | |||
209 | zfcp_erp_action_dismiss_adapter(adapter); | 216 | zfcp_erp_action_dismiss_adapter(adapter); |
210 | atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &adapter->status); | 217 | atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &adapter->status); |
211 | erp_action = &adapter->erp_action; | 218 | erp_action = &adapter->erp_action; |
219 | memset(erp_action, 0, sizeof(struct zfcp_erp_action)); | ||
212 | if (!(atomic_read(&adapter->status) & | 220 | if (!(atomic_read(&adapter->status) & |
213 | ZFCP_STATUS_COMMON_RUNNING)) | 221 | ZFCP_STATUS_COMMON_RUNNING)) |
214 | act_status |= ZFCP_STATUS_ERP_CLOSE_ONLY; | 222 | act_status |= ZFCP_STATUS_ERP_CLOSE_ONLY; |
@@ -218,10 +226,7 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need, u32 act_status, | |||
218 | return NULL; | 226 | return NULL; |
219 | } | 227 | } |
220 | 228 | ||
221 | memset(erp_action, 0, sizeof(struct zfcp_erp_action)); | ||
222 | erp_action->adapter = adapter; | 229 | erp_action->adapter = adapter; |
223 | erp_action->port = port; | ||
224 | erp_action->sdev = sdev; | ||
225 | erp_action->action = need; | 230 | erp_action->action = need; |
226 | erp_action->status = act_status; | 231 | erp_action->status = act_status; |
227 | 232 | ||
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index be0317457147..2eb7dd56ab80 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c | |||
@@ -851,7 +851,7 @@ struct zfcp_fsf_req *zfcp_fsf_abort_fcp_cmnd(struct scsi_cmnd *scmnd) | |||
851 | 851 | ||
852 | zfcp_qdio_set_sbale_last(qdio, &req->qdio_req); | 852 | zfcp_qdio_set_sbale_last(qdio, &req->qdio_req); |
853 | 853 | ||
854 | req->data = zfcp_sdev; | 854 | req->data = sdev; |
855 | req->handler = zfcp_fsf_abort_fcp_command_handler; | 855 | req->handler = zfcp_fsf_abort_fcp_command_handler; |
856 | req->qtcb->header.lun_handle = zfcp_sdev->lun_handle; | 856 | req->qtcb->header.lun_handle = zfcp_sdev->lun_handle; |
857 | req->qtcb->header.port_handle = zfcp_sdev->port->handle; | 857 | req->qtcb->header.port_handle = zfcp_sdev->port->handle; |
@@ -2069,8 +2069,6 @@ static void zfcp_fsf_fcp_cmnd_handler(struct zfcp_fsf_req *req) | |||
2069 | struct fcp_resp_with_ext *fcp_rsp; | 2069 | struct fcp_resp_with_ext *fcp_rsp; |
2070 | unsigned long flags; | 2070 | unsigned long flags; |
2071 | 2071 | ||
2072 | zfcp_fsf_fcp_handler_common(req); | ||
2073 | |||
2074 | read_lock_irqsave(&req->adapter->abort_lock, flags); | 2072 | read_lock_irqsave(&req->adapter->abort_lock, flags); |
2075 | 2073 | ||
2076 | scpnt = req->data; | 2074 | scpnt = req->data; |
@@ -2079,6 +2077,8 @@ static void zfcp_fsf_fcp_cmnd_handler(struct zfcp_fsf_req *req) | |||
2079 | return; | 2077 | return; |
2080 | } | 2078 | } |
2081 | 2079 | ||
2080 | zfcp_fsf_fcp_handler_common(req); | ||
2081 | |||
2082 | if (unlikely(req->status & ZFCP_STATUS_FSFREQ_ERROR)) { | 2082 | if (unlikely(req->status & ZFCP_STATUS_FSFREQ_ERROR)) { |
2083 | set_host_byte(scpnt, DID_TRANSPORT_DISRUPTED); | 2083 | set_host_byte(scpnt, DID_TRANSPORT_DISRUPTED); |
2084 | goto skip_fsfstatus; | 2084 | goto skip_fsfstatus; |
@@ -2170,12 +2170,13 @@ int zfcp_fsf_fcp_cmnd(struct scsi_cmnd *scsi_cmnd) | |||
2170 | struct zfcp_adapter *adapter = zfcp_sdev->port->adapter; | 2170 | struct zfcp_adapter *adapter = zfcp_sdev->port->adapter; |
2171 | struct zfcp_qdio *qdio = adapter->qdio; | 2171 | struct zfcp_qdio *qdio = adapter->qdio; |
2172 | struct fsf_qtcb_bottom_io *io; | 2172 | struct fsf_qtcb_bottom_io *io; |
2173 | unsigned long flags; | ||
2173 | 2174 | ||
2174 | if (unlikely(!(atomic_read(&zfcp_sdev->status) & | 2175 | if (unlikely(!(atomic_read(&zfcp_sdev->status) & |
2175 | ZFCP_STATUS_COMMON_UNBLOCKED))) | 2176 | ZFCP_STATUS_COMMON_UNBLOCKED))) |
2176 | return -EBUSY; | 2177 | return -EBUSY; |
2177 | 2178 | ||
2178 | spin_lock(&qdio->req_q_lock); | 2179 | spin_lock_irqsave(&qdio->req_q_lock, flags); |
2179 | if (atomic_read(&qdio->req_q_free) <= 0) { | 2180 | if (atomic_read(&qdio->req_q_free) <= 0) { |
2180 | atomic_inc(&qdio->req_q_full); | 2181 | atomic_inc(&qdio->req_q_full); |
2181 | goto out; | 2182 | goto out; |
@@ -2239,7 +2240,7 @@ failed_scsi_cmnd: | |||
2239 | zfcp_fsf_req_free(req); | 2240 | zfcp_fsf_req_free(req); |
2240 | scsi_cmnd->host_scribble = NULL; | 2241 | scsi_cmnd->host_scribble = NULL; |
2241 | out: | 2242 | out: |
2242 | spin_unlock(&qdio->req_q_lock); | 2243 | spin_unlock_irqrestore(&qdio->req_q_lock, flags); |
2243 | return retval; | 2244 | return retval; |
2244 | } | 2245 | } |
2245 | 2246 | ||
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c index 6bd2dbc4c316..63529ed801eb 100644 --- a/drivers/s390/scsi/zfcp_scsi.c +++ b/drivers/s390/scsi/zfcp_scsi.c | |||
@@ -76,8 +76,8 @@ static void zfcp_scsi_command_fail(struct scsi_cmnd *scpnt, int result) | |||
76 | scpnt->scsi_done(scpnt); | 76 | scpnt->scsi_done(scpnt); |
77 | } | 77 | } |
78 | 78 | ||
79 | static int zfcp_scsi_queuecommand_lck(struct scsi_cmnd *scpnt, | 79 | static |
80 | void (*done) (struct scsi_cmnd *)) | 80 | int zfcp_scsi_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *scpnt) |
81 | { | 81 | { |
82 | struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(scpnt->device); | 82 | struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(scpnt->device); |
83 | struct zfcp_adapter *adapter = zfcp_sdev->port->adapter; | 83 | struct zfcp_adapter *adapter = zfcp_sdev->port->adapter; |
@@ -87,7 +87,6 @@ static int zfcp_scsi_queuecommand_lck(struct scsi_cmnd *scpnt, | |||
87 | /* reset the status for this request */ | 87 | /* reset the status for this request */ |
88 | scpnt->result = 0; | 88 | scpnt->result = 0; |
89 | scpnt->host_scribble = NULL; | 89 | scpnt->host_scribble = NULL; |
90 | scpnt->scsi_done = done; | ||
91 | 90 | ||
92 | scsi_result = fc_remote_port_chkready(rport); | 91 | scsi_result = fc_remote_port_chkready(rport); |
93 | if (unlikely(scsi_result)) { | 92 | if (unlikely(scsi_result)) { |
@@ -127,8 +126,6 @@ static int zfcp_scsi_queuecommand_lck(struct scsi_cmnd *scpnt, | |||
127 | return ret; | 126 | return ret; |
128 | } | 127 | } |
129 | 128 | ||
130 | static DEF_SCSI_QCMD(zfcp_scsi_queuecommand) | ||
131 | |||
132 | static int zfcp_scsi_slave_alloc(struct scsi_device *sdev) | 129 | static int zfcp_scsi_slave_alloc(struct scsi_device *sdev) |
133 | { | 130 | { |
134 | struct fc_rport *rport = starget_to_rport(scsi_target(sdev)); | 131 | struct fc_rport *rport = starget_to_rport(scsi_target(sdev)); |
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index b2fb2b2a6e70..a6dea08664fc 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c | |||
@@ -90,11 +90,7 @@ static const struct pci_device_id hpsa_pci_device_id[] = { | |||
90 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3252}, | 90 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3252}, |
91 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3253}, | 91 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3253}, |
92 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3254}, | 92 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3254}, |
93 | #define PCI_DEVICE_ID_HP_CISSF 0x333f | 93 | {PCI_VENDOR_ID_HP, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, |
94 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSF, 0x103C, 0x333F}, | ||
95 | {PCI_VENDOR_ID_HP, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, | ||
96 | PCI_CLASS_STORAGE_RAID << 8, 0xffff << 8, 0}, | ||
97 | {PCI_VENDOR_ID_COMPAQ, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, | ||
98 | PCI_CLASS_STORAGE_RAID << 8, 0xffff << 8, 0}, | 94 | PCI_CLASS_STORAGE_RAID << 8, 0xffff << 8, 0}, |
99 | {0,} | 95 | {0,} |
100 | }; | 96 | }; |
@@ -113,8 +109,6 @@ static struct board_type products[] = { | |||
113 | {0x3249103C, "Smart Array P812", &SA5_access}, | 109 | {0x3249103C, "Smart Array P812", &SA5_access}, |
114 | {0x324a103C, "Smart Array P712m", &SA5_access}, | 110 | {0x324a103C, "Smart Array P712m", &SA5_access}, |
115 | {0x324b103C, "Smart Array P711m", &SA5_access}, | 111 | {0x324b103C, "Smart Array P711m", &SA5_access}, |
116 | {0x3233103C, "StorageWorks P1210m", &SA5_access}, | ||
117 | {0x333F103C, "StorageWorks P1210m", &SA5_access}, | ||
118 | {0x3250103C, "Smart Array", &SA5_access}, | 112 | {0x3250103C, "Smart Array", &SA5_access}, |
119 | {0x3250113C, "Smart Array", &SA5_access}, | 113 | {0x3250113C, "Smart Array", &SA5_access}, |
120 | {0x3250123C, "Smart Array", &SA5_access}, | 114 | {0x3250123C, "Smart Array", &SA5_access}, |
diff --git a/drivers/scsi/osd/osd_initiator.c b/drivers/scsi/osd/osd_initiator.c index 0433ea6f27c9..b37c8a3c1bb0 100644 --- a/drivers/scsi/osd/osd_initiator.c +++ b/drivers/scsi/osd/osd_initiator.c | |||
@@ -951,8 +951,8 @@ static int _osd_req_finalize_cdb_cont(struct osd_request *or, const u8 *cap_key) | |||
951 | /* create a bio for continuation segment */ | 951 | /* create a bio for continuation segment */ |
952 | bio = bio_map_kern(req_q, or->cdb_cont.buff, or->cdb_cont.total_bytes, | 952 | bio = bio_map_kern(req_q, or->cdb_cont.buff, or->cdb_cont.total_bytes, |
953 | GFP_KERNEL); | 953 | GFP_KERNEL); |
954 | if (unlikely(!bio)) | 954 | if (IS_ERR(bio)) |
955 | return -ENOMEM; | 955 | return PTR_ERR(bio); |
956 | 956 | ||
957 | bio->bi_rw |= REQ_WRITE; | 957 | bio->bi_rw |= REQ_WRITE; |
958 | 958 | ||
diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c index 5e76a624cb08..300d59f389da 100644 --- a/drivers/scsi/pmcraid.c +++ b/drivers/scsi/pmcraid.c | |||
@@ -62,6 +62,7 @@ | |||
62 | static unsigned int pmcraid_debug_log; | 62 | static unsigned int pmcraid_debug_log; |
63 | static unsigned int pmcraid_disable_aen; | 63 | static unsigned int pmcraid_disable_aen; |
64 | static unsigned int pmcraid_log_level = IOASC_LOG_LEVEL_MUST; | 64 | static unsigned int pmcraid_log_level = IOASC_LOG_LEVEL_MUST; |
65 | static unsigned int pmcraid_enable_msix; | ||
65 | 66 | ||
66 | /* | 67 | /* |
67 | * Data structures to support multiple adapters by the LLD. | 68 | * Data structures to support multiple adapters by the LLD. |
@@ -4691,7 +4692,8 @@ pmcraid_register_interrupt_handler(struct pmcraid_instance *pinstance) | |||
4691 | int rc; | 4692 | int rc; |
4692 | struct pci_dev *pdev = pinstance->pdev; | 4693 | struct pci_dev *pdev = pinstance->pdev; |
4693 | 4694 | ||
4694 | if (pci_find_capability(pdev, PCI_CAP_ID_MSIX)) { | 4695 | if ((pmcraid_enable_msix) && |
4696 | (pci_find_capability(pdev, PCI_CAP_ID_MSIX))) { | ||
4695 | int num_hrrq = PMCRAID_NUM_MSIX_VECTORS; | 4697 | int num_hrrq = PMCRAID_NUM_MSIX_VECTORS; |
4696 | struct msix_entry entries[PMCRAID_NUM_MSIX_VECTORS]; | 4698 | struct msix_entry entries[PMCRAID_NUM_MSIX_VECTORS]; |
4697 | int i; | 4699 | int i; |
diff --git a/drivers/scsi/pmcraid.h b/drivers/scsi/pmcraid.h index 1134279604e8..4db210d93947 100644 --- a/drivers/scsi/pmcraid.h +++ b/drivers/scsi/pmcraid.h | |||
@@ -42,7 +42,7 @@ | |||
42 | */ | 42 | */ |
43 | #define PMCRAID_DRIVER_NAME "PMC MaxRAID" | 43 | #define PMCRAID_DRIVER_NAME "PMC MaxRAID" |
44 | #define PMCRAID_DEVFILE "pmcsas" | 44 | #define PMCRAID_DEVFILE "pmcsas" |
45 | #define PMCRAID_DRIVER_VERSION "2.0.3" | 45 | #define PMCRAID_DRIVER_VERSION "1.0.3" |
46 | #define PMCRAID_DRIVER_DATE __DATE__ | 46 | #define PMCRAID_DRIVER_DATE __DATE__ |
47 | 47 | ||
48 | #define PMCRAID_FW_VERSION_1 0x002 | 48 | #define PMCRAID_FW_VERSION_1 0x002 |
@@ -333,11 +333,9 @@ struct pmcraid_config_table_entry { | |||
333 | __u8 lun[PMCRAID_LUN_LEN]; | 333 | __u8 lun[PMCRAID_LUN_LEN]; |
334 | } __attribute__((packed, aligned(4))); | 334 | } __attribute__((packed, aligned(4))); |
335 | 335 | ||
336 | /* extended configuration table sizes are of 64 bytes in size */ | 336 | /* extended configuration table sizes are also of 32 bytes in size */ |
337 | #define PMCRAID_CFGTE_EXT_SIZE 32 | ||
338 | struct pmcraid_config_table_entry_ext { | 337 | struct pmcraid_config_table_entry_ext { |
339 | struct pmcraid_config_table_entry cfgte; | 338 | struct pmcraid_config_table_entry cfgte; |
340 | __u8 cfgte_ext[PMCRAID_CFGTE_EXT_SIZE]; | ||
341 | }; | 339 | }; |
342 | 340 | ||
343 | /* resource types (config_table_entry.resource_type values) */ | 341 | /* resource types (config_table_entry.resource_type values) */ |
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 3a22effced5f..9ce539d4557e 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h | |||
@@ -2409,7 +2409,6 @@ struct qla_hw_data { | |||
2409 | uint32_t enable_target_reset :1; | 2409 | uint32_t enable_target_reset :1; |
2410 | uint32_t enable_lip_full_login :1; | 2410 | uint32_t enable_lip_full_login :1; |
2411 | uint32_t enable_led_scheme :1; | 2411 | uint32_t enable_led_scheme :1; |
2412 | uint32_t inta_enabled :1; | ||
2413 | uint32_t msi_enabled :1; | 2412 | uint32_t msi_enabled :1; |
2414 | uint32_t msix_enabled :1; | 2413 | uint32_t msix_enabled :1; |
2415 | uint32_t disable_serdes :1; | 2414 | uint32_t disable_serdes :1; |
diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c index 5f94430b42f0..4c1ba6263eb3 100644 --- a/drivers/scsi/qla2xxx/qla_iocb.c +++ b/drivers/scsi/qla2xxx/qla_iocb.c | |||
@@ -1061,6 +1061,7 @@ qla24xx_build_scsi_crc_2_iocbs(srb_t *sp, struct cmd_type_crc_2 *cmd_pkt, | |||
1061 | fcp_cmnd->additional_cdb_len |= 2; | 1061 | fcp_cmnd->additional_cdb_len |= 2; |
1062 | 1062 | ||
1063 | int_to_scsilun(sp->cmd->device->lun, &fcp_cmnd->lun); | 1063 | int_to_scsilun(sp->cmd->device->lun, &fcp_cmnd->lun); |
1064 | host_to_fcp_swap((uint8_t *)&fcp_cmnd->lun, sizeof(fcp_cmnd->lun)); | ||
1064 | memcpy(fcp_cmnd->cdb, cmd->cmnd, cmd->cmd_len); | 1065 | memcpy(fcp_cmnd->cdb, cmd->cmnd, cmd->cmd_len); |
1065 | cmd_pkt->fcp_cmnd_dseg_len = cpu_to_le16(fcp_cmnd_len); | 1066 | cmd_pkt->fcp_cmnd_dseg_len = cpu_to_le16(fcp_cmnd_len); |
1066 | cmd_pkt->fcp_cmnd_dseg_address[0] = cpu_to_le32( | 1067 | cmd_pkt->fcp_cmnd_dseg_address[0] = cpu_to_le32( |
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index 1f06ddd9bdd1..7f77898486a9 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c | |||
@@ -2491,14 +2491,15 @@ skip_msix: | |||
2491 | skip_msi: | 2491 | skip_msi: |
2492 | 2492 | ||
2493 | ret = request_irq(ha->pdev->irq, ha->isp_ops->intr_handler, | 2493 | ret = request_irq(ha->pdev->irq, ha->isp_ops->intr_handler, |
2494 | IRQF_SHARED, QLA2XXX_DRIVER_NAME, rsp); | 2494 | ha->flags.msi_enabled ? 0 : IRQF_SHARED, |
2495 | QLA2XXX_DRIVER_NAME, rsp); | ||
2495 | if (ret) { | 2496 | if (ret) { |
2496 | qla_printk(KERN_WARNING, ha, | 2497 | qla_printk(KERN_WARNING, ha, |
2497 | "Failed to reserve interrupt %d already in use.\n", | 2498 | "Failed to reserve interrupt %d already in use.\n", |
2498 | ha->pdev->irq); | 2499 | ha->pdev->irq); |
2499 | goto fail; | 2500 | goto fail; |
2500 | } | 2501 | } |
2501 | ha->flags.inta_enabled = 1; | 2502 | |
2502 | clear_risc_ints: | 2503 | clear_risc_ints: |
2503 | 2504 | ||
2504 | /* | 2505 | /* |
diff --git a/drivers/scsi/qla2xxx/qla_nx.c b/drivers/scsi/qla2xxx/qla_nx.c index 8d9edfb39803..ae2acacc0003 100644 --- a/drivers/scsi/qla2xxx/qla_nx.c +++ b/drivers/scsi/qla2xxx/qla_nx.c | |||
@@ -2749,6 +2749,7 @@ sufficient_dsds: | |||
2749 | goto queuing_error_fcp_cmnd; | 2749 | goto queuing_error_fcp_cmnd; |
2750 | 2750 | ||
2751 | int_to_scsilun(sp->cmd->device->lun, &cmd_pkt->lun); | 2751 | int_to_scsilun(sp->cmd->device->lun, &cmd_pkt->lun); |
2752 | host_to_fcp_swap((uint8_t *)&cmd_pkt->lun, sizeof(cmd_pkt->lun)); | ||
2752 | 2753 | ||
2753 | /* build FCP_CMND IU */ | 2754 | /* build FCP_CMND IU */ |
2754 | memset(ctx->fcp_cmnd, 0, sizeof(struct fcp_cmnd)); | 2755 | memset(ctx->fcp_cmnd, 0, sizeof(struct fcp_cmnd)); |
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 1644eabaafeb..2c0876c81a3f 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c | |||
@@ -829,7 +829,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) | |||
829 | { | 829 | { |
830 | scsi_qla_host_t *vha = shost_priv(cmd->device->host); | 830 | scsi_qla_host_t *vha = shost_priv(cmd->device->host); |
831 | srb_t *sp; | 831 | srb_t *sp; |
832 | int ret; | 832 | int ret = SUCCESS; |
833 | unsigned int id, lun; | 833 | unsigned int id, lun; |
834 | unsigned long flags; | 834 | unsigned long flags; |
835 | int wait = 0; | 835 | int wait = 0; |
@@ -2064,6 +2064,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
2064 | ha->init_cb_size = sizeof(struct mid_init_cb_81xx); | 2064 | ha->init_cb_size = sizeof(struct mid_init_cb_81xx); |
2065 | ha->gid_list_info_size = 8; | 2065 | ha->gid_list_info_size = 8; |
2066 | ha->optrom_size = OPTROM_SIZE_82XX; | 2066 | ha->optrom_size = OPTROM_SIZE_82XX; |
2067 | ha->nvram_npiv_size = QLA_MAX_VPORTS_QLA25XX; | ||
2067 | ha->isp_ops = &qla82xx_isp_ops; | 2068 | ha->isp_ops = &qla82xx_isp_ops; |
2068 | ha->flash_conf_off = FARX_ACCESS_FLASH_CONF; | 2069 | ha->flash_conf_off = FARX_ACCESS_FLASH_CONF; |
2069 | ha->flash_data_off = FARX_ACCESS_FLASH_DATA; | 2070 | ha->flash_data_off = FARX_ACCESS_FLASH_DATA; |
diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h index 8edbccb3232d..cf0075a2d0c2 100644 --- a/drivers/scsi/qla2xxx/qla_version.h +++ b/drivers/scsi/qla2xxx/qla_version.h | |||
@@ -7,9 +7,9 @@ | |||
7 | /* | 7 | /* |
8 | * Driver version | 8 | * Driver version |
9 | */ | 9 | */ |
10 | #define QLA2XXX_VERSION "8.03.04-k0" | 10 | #define QLA2XXX_VERSION "8.03.05-k0" |
11 | 11 | ||
12 | #define QLA_DRIVER_MAJOR_VER 8 | 12 | #define QLA_DRIVER_MAJOR_VER 8 |
13 | #define QLA_DRIVER_MINOR_VER 3 | 13 | #define QLA_DRIVER_MINOR_VER 3 |
14 | #define QLA_DRIVER_PATCH_VER 4 | 14 | #define QLA_DRIVER_PATCH_VER 5 |
15 | #define QLA_DRIVER_BETA_VER 0 | 15 | #define QLA_DRIVER_BETA_VER 0 |
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index 824b8fc03ce5..30ac116186f5 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c | |||
@@ -615,7 +615,7 @@ static int scsi_try_bus_device_reset(struct scsi_cmnd *scmd) | |||
615 | return rtn; | 615 | return rtn; |
616 | } | 616 | } |
617 | 617 | ||
618 | static int __scsi_try_to_abort_cmd(struct scsi_cmnd *scmd) | 618 | static int scsi_try_to_abort_cmd(struct scsi_cmnd *scmd) |
619 | { | 619 | { |
620 | if (!scmd->device->host->hostt->eh_abort_handler) | 620 | if (!scmd->device->host->hostt->eh_abort_handler) |
621 | return FAILED; | 621 | return FAILED; |
@@ -623,31 +623,9 @@ static int __scsi_try_to_abort_cmd(struct scsi_cmnd *scmd) | |||
623 | return scmd->device->host->hostt->eh_abort_handler(scmd); | 623 | return scmd->device->host->hostt->eh_abort_handler(scmd); |
624 | } | 624 | } |
625 | 625 | ||
626 | /** | ||
627 | * scsi_try_to_abort_cmd - Ask host to abort a running command. | ||
628 | * @scmd: SCSI cmd to abort from Lower Level. | ||
629 | * | ||
630 | * Notes: | ||
631 | * This function will not return until the user's completion function | ||
632 | * has been called. there is no timeout on this operation. if the | ||
633 | * author of the low-level driver wishes this operation to be timed, | ||
634 | * they can provide this facility themselves. helper functions in | ||
635 | * scsi_error.c can be supplied to make this easier to do. | ||
636 | */ | ||
637 | static int scsi_try_to_abort_cmd(struct scsi_cmnd *scmd) | ||
638 | { | ||
639 | /* | ||
640 | * scsi_done was called just after the command timed out and before | ||
641 | * we had a chance to process it. (db) | ||
642 | */ | ||
643 | if (scmd->serial_number == 0) | ||
644 | return SUCCESS; | ||
645 | return __scsi_try_to_abort_cmd(scmd); | ||
646 | } | ||
647 | |||
648 | static void scsi_abort_eh_cmnd(struct scsi_cmnd *scmd) | 626 | static void scsi_abort_eh_cmnd(struct scsi_cmnd *scmd) |
649 | { | 627 | { |
650 | if (__scsi_try_to_abort_cmd(scmd) != SUCCESS) | 628 | if (scsi_try_to_abort_cmd(scmd) != SUCCESS) |
651 | if (scsi_try_bus_device_reset(scmd) != SUCCESS) | 629 | if (scsi_try_bus_device_reset(scmd) != SUCCESS) |
652 | if (scsi_try_target_reset(scmd) != SUCCESS) | 630 | if (scsi_try_target_reset(scmd) != SUCCESS) |
653 | if (scsi_try_bus_reset(scmd) != SUCCESS) | 631 | if (scsi_try_bus_reset(scmd) != SUCCESS) |
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index eafeeda6e194..5b6bbaea59fe 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c | |||
@@ -1403,11 +1403,6 @@ static void scsi_softirq_done(struct request *rq) | |||
1403 | 1403 | ||
1404 | INIT_LIST_HEAD(&cmd->eh_entry); | 1404 | INIT_LIST_HEAD(&cmd->eh_entry); |
1405 | 1405 | ||
1406 | /* | ||
1407 | * Set the serial numbers back to zero | ||
1408 | */ | ||
1409 | cmd->serial_number = 0; | ||
1410 | |||
1411 | atomic_inc(&cmd->device->iodone_cnt); | 1406 | atomic_inc(&cmd->device->iodone_cnt); |
1412 | if (cmd->result) | 1407 | if (cmd->result) |
1413 | atomic_inc(&cmd->device->ioerr_cnt); | 1408 | atomic_inc(&cmd->device->ioerr_cnt); |
diff --git a/drivers/serial/kgdboc.c b/drivers/serial/kgdboc.c index 3374618300af..25a8bc565f40 100644 --- a/drivers/serial/kgdboc.c +++ b/drivers/serial/kgdboc.c | |||
@@ -90,7 +90,8 @@ static DECLARE_WORK(kgdboc_restore_input_work, kgdboc_restore_input_helper); | |||
90 | 90 | ||
91 | static void kgdboc_restore_input(void) | 91 | static void kgdboc_restore_input(void) |
92 | { | 92 | { |
93 | schedule_work(&kgdboc_restore_input_work); | 93 | if (likely(system_state == SYSTEM_RUNNING)) |
94 | schedule_work(&kgdboc_restore_input_work); | ||
94 | } | 95 | } |
95 | 96 | ||
96 | static int kgdboc_register_kbd(char **cptr) | 97 | static int kgdboc_register_kbd(char **cptr) |
diff --git a/drivers/spi/dw_spi.c b/drivers/spi/dw_spi.c index 90439314cf67..0838c79861e4 100644 --- a/drivers/spi/dw_spi.c +++ b/drivers/spi/dw_spi.c | |||
@@ -413,6 +413,11 @@ static void poll_transfer(struct dw_spi *dws) | |||
413 | { | 413 | { |
414 | while (dws->write(dws)) | 414 | while (dws->write(dws)) |
415 | dws->read(dws); | 415 | dws->read(dws); |
416 | /* | ||
417 | * There is a possibility that the last word of a transaction | ||
418 | * will be lost if data is not ready. Re-read to solve this issue. | ||
419 | */ | ||
420 | dws->read(dws); | ||
416 | 421 | ||
417 | transfer_complete(dws); | 422 | transfer_complete(dws); |
418 | } | 423 | } |
diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig index 67eb3770868f..5a7c8f1d76c6 100644 --- a/drivers/usb/Kconfig +++ b/drivers/usb/Kconfig | |||
@@ -41,6 +41,7 @@ config USB_ARCH_HAS_OHCI | |||
41 | default y if MFD_TC6393XB | 41 | default y if MFD_TC6393XB |
42 | default y if ARCH_W90X900 | 42 | default y if ARCH_W90X900 |
43 | default y if ARCH_DAVINCI_DA8XX | 43 | default y if ARCH_DAVINCI_DA8XX |
44 | default y if ARCH_CNS3XXX | ||
44 | # PPC: | 45 | # PPC: |
45 | default y if STB03xxx | 46 | default y if STB03xxx |
46 | default y if PPC_MPC52xx | 47 | default y if PPC_MPC52xx |
@@ -66,6 +67,7 @@ config USB_ARCH_HAS_EHCI | |||
66 | default y if ARCH_AT91SAM9G45 | 67 | default y if ARCH_AT91SAM9G45 |
67 | default y if ARCH_MXC | 68 | default y if ARCH_MXC |
68 | default y if ARCH_OMAP3 | 69 | default y if ARCH_OMAP3 |
70 | default y if ARCH_CNS3XXX | ||
69 | default PCI | 71 | default PCI |
70 | 72 | ||
71 | # ARM SA1111 chips have a non-PCI based "OHCI-compatible" USB host interface. | 73 | # ARM SA1111 chips have a non-PCI based "OHCI-compatible" USB host interface. |
diff --git a/drivers/usb/atm/usbatm.c b/drivers/usb/atm/usbatm.c index 05bf5a27b5b0..989e16e4ab5c 100644 --- a/drivers/usb/atm/usbatm.c +++ b/drivers/usb/atm/usbatm.c | |||
@@ -951,7 +951,9 @@ static int usbatm_atm_init(struct usbatm_data *instance) | |||
951 | * condition: callbacks we register can be executed at once, before we have | 951 | * condition: callbacks we register can be executed at once, before we have |
952 | * initialized the struct atm_dev. To protect against this, all callbacks | 952 | * initialized the struct atm_dev. To protect against this, all callbacks |
953 | * abort if atm_dev->dev_data is NULL. */ | 953 | * abort if atm_dev->dev_data is NULL. */ |
954 | atm_dev = atm_dev_register(instance->driver_name, &usbatm_atm_devops, -1, NULL); | 954 | atm_dev = atm_dev_register(instance->driver_name, |
955 | &instance->usb_intf->dev, &usbatm_atm_devops, | ||
956 | -1, NULL); | ||
955 | if (!atm_dev) { | 957 | if (!atm_dev) { |
956 | usb_err(instance, "%s: failed to register ATM device!\n", __func__); | 958 | usb_err(instance, "%s: failed to register ATM device!\n", __func__); |
957 | return -1; | 959 | return -1; |
@@ -966,14 +968,6 @@ static int usbatm_atm_init(struct usbatm_data *instance) | |||
966 | /* temp init ATM device, set to 128kbit */ | 968 | /* temp init ATM device, set to 128kbit */ |
967 | atm_dev->link_rate = 128 * 1000 / 424; | 969 | atm_dev->link_rate = 128 * 1000 / 424; |
968 | 970 | ||
969 | ret = sysfs_create_link(&atm_dev->class_dev.kobj, | ||
970 | &instance->usb_intf->dev.kobj, "device"); | ||
971 | if (ret) { | ||
972 | atm_err(instance, "%s: sysfs_create_link failed: %d\n", | ||
973 | __func__, ret); | ||
974 | goto fail_sysfs; | ||
975 | } | ||
976 | |||
977 | if (instance->driver->atm_start && ((ret = instance->driver->atm_start(instance, atm_dev)) < 0)) { | 971 | if (instance->driver->atm_start && ((ret = instance->driver->atm_start(instance, atm_dev)) < 0)) { |
978 | atm_err(instance, "%s: atm_start failed: %d!\n", __func__, ret); | 972 | atm_err(instance, "%s: atm_start failed: %d!\n", __func__, ret); |
979 | goto fail; | 973 | goto fail; |
@@ -992,8 +986,6 @@ static int usbatm_atm_init(struct usbatm_data *instance) | |||
992 | return 0; | 986 | return 0; |
993 | 987 | ||
994 | fail: | 988 | fail: |
995 | sysfs_remove_link(&atm_dev->class_dev.kobj, "device"); | ||
996 | fail_sysfs: | ||
997 | instance->atm_dev = NULL; | 989 | instance->atm_dev = NULL; |
998 | atm_dev_deregister(atm_dev); /* usbatm_atm_dev_close will eventually be called */ | 990 | atm_dev_deregister(atm_dev); /* usbatm_atm_dev_close will eventually be called */ |
999 | return ret; | 991 | return ret; |
@@ -1329,7 +1321,6 @@ void usbatm_usb_disconnect(struct usb_interface *intf) | |||
1329 | 1321 | ||
1330 | /* ATM finalize */ | 1322 | /* ATM finalize */ |
1331 | if (instance->atm_dev) { | 1323 | if (instance->atm_dev) { |
1332 | sysfs_remove_link(&instance->atm_dev->class_dev.kobj, "device"); | ||
1333 | atm_dev_deregister(instance->atm_dev); | 1324 | atm_dev_deregister(instance->atm_dev); |
1334 | instance->atm_dev = NULL; | 1325 | instance->atm_dev = NULL; |
1335 | } | 1326 | } |
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 6f4f8e6a40c7..f8970d151d2a 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig | |||
@@ -147,6 +147,14 @@ config USB_W90X900_EHCI | |||
147 | ---help--- | 147 | ---help--- |
148 | Enables support for the W90X900 USB controller | 148 | Enables support for the W90X900 USB controller |
149 | 149 | ||
150 | config USB_CNS3XXX_EHCI | ||
151 | bool "Cavium CNS3XXX EHCI Module" | ||
152 | depends on USB_EHCI_HCD && ARCH_CNS3XXX | ||
153 | ---help--- | ||
154 | Enable support for the CNS3XXX SOC's on-chip EHCI controller. | ||
155 | It is needed for high-speed (480Mbit/sec) USB 2.0 device | ||
156 | support. | ||
157 | |||
150 | config USB_OXU210HP_HCD | 158 | config USB_OXU210HP_HCD |
151 | tristate "OXU210HP HCD support" | 159 | tristate "OXU210HP HCD support" |
152 | depends on USB | 160 | depends on USB |
@@ -286,6 +294,13 @@ config USB_OHCI_HCD_SSB | |||
286 | 294 | ||
287 | If unsure, say N. | 295 | If unsure, say N. |
288 | 296 | ||
297 | config USB_CNS3XXX_OHCI | ||
298 | bool "Cavium CNS3XXX OHCI Module" | ||
299 | depends on USB_OHCI_HCD && ARCH_CNS3XXX | ||
300 | ---help--- | ||
301 | Enable support for the CNS3XXX SOC's on-chip OHCI controller. | ||
302 | It is needed for low-speed USB 1.0 device support. | ||
303 | |||
289 | config USB_OHCI_BIG_ENDIAN_DESC | 304 | config USB_OHCI_BIG_ENDIAN_DESC |
290 | bool | 305 | bool |
291 | depends on USB_OHCI_HCD | 306 | depends on USB_OHCI_HCD |
diff --git a/drivers/usb/host/ehci-cns3xxx.c b/drivers/usb/host/ehci-cns3xxx.c new file mode 100644 index 000000000000..708a05b5d258 --- /dev/null +++ b/drivers/usb/host/ehci-cns3xxx.c | |||
@@ -0,0 +1,171 @@ | |||
1 | /* | ||
2 | * Copyright 2008 Cavium Networks | ||
3 | * | ||
4 | * This file is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License, Version 2, as | ||
6 | * published by the Free Software Foundation. | ||
7 | */ | ||
8 | |||
9 | #include <linux/platform_device.h> | ||
10 | #include <linux/atomic.h> | ||
11 | #include <mach/cns3xxx.h> | ||
12 | #include <mach/pm.h> | ||
13 | |||
14 | static int cns3xxx_ehci_init(struct usb_hcd *hcd) | ||
15 | { | ||
16 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); | ||
17 | int retval; | ||
18 | |||
19 | /* | ||
20 | * EHCI and OHCI share the same clock and power, | ||
21 | * resetting twice would cause the 1st controller been reset. | ||
22 | * Therefore only do power up at the first up device, and | ||
23 | * power down at the last down device. | ||
24 | * | ||
25 | * Set USB AHB INCR length to 16 | ||
26 | */ | ||
27 | if (atomic_inc_return(&usb_pwr_ref) == 1) { | ||
28 | cns3xxx_pwr_power_up(1 << PM_PLL_HM_PD_CTRL_REG_OFFSET_PLL_USB); | ||
29 | cns3xxx_pwr_clk_en(1 << PM_CLK_GATE_REG_OFFSET_USB_HOST); | ||
30 | cns3xxx_pwr_soft_rst(1 << PM_SOFT_RST_REG_OFFST_USB_HOST); | ||
31 | __raw_writel((__raw_readl(MISC_CHIP_CONFIG_REG) | (0X2 << 24)), | ||
32 | MISC_CHIP_CONFIG_REG); | ||
33 | } | ||
34 | |||
35 | ehci->caps = hcd->regs; | ||
36 | ehci->regs = hcd->regs | ||
37 | + HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase)); | ||
38 | ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); | ||
39 | |||
40 | hcd->has_tt = 0; | ||
41 | ehci_reset(ehci); | ||
42 | |||
43 | retval = ehci_init(hcd); | ||
44 | if (retval) | ||
45 | return retval; | ||
46 | |||
47 | ehci_port_power(ehci, 0); | ||
48 | |||
49 | return retval; | ||
50 | } | ||
51 | |||
52 | static const struct hc_driver cns3xxx_ehci_hc_driver = { | ||
53 | .description = hcd_name, | ||
54 | .product_desc = "CNS3XXX EHCI Host Controller", | ||
55 | .hcd_priv_size = sizeof(struct ehci_hcd), | ||
56 | .irq = ehci_irq, | ||
57 | .flags = HCD_MEMORY | HCD_USB2, | ||
58 | .reset = cns3xxx_ehci_init, | ||
59 | .start = ehci_run, | ||
60 | .stop = ehci_stop, | ||
61 | .shutdown = ehci_shutdown, | ||
62 | .urb_enqueue = ehci_urb_enqueue, | ||
63 | .urb_dequeue = ehci_urb_dequeue, | ||
64 | .endpoint_disable = ehci_endpoint_disable, | ||
65 | .endpoint_reset = ehci_endpoint_reset, | ||
66 | .get_frame_number = ehci_get_frame, | ||
67 | .hub_status_data = ehci_hub_status_data, | ||
68 | .hub_control = ehci_hub_control, | ||
69 | #ifdef CONFIG_PM | ||
70 | .bus_suspend = ehci_bus_suspend, | ||
71 | .bus_resume = ehci_bus_resume, | ||
72 | #endif | ||
73 | .relinquish_port = ehci_relinquish_port, | ||
74 | .port_handed_over = ehci_port_handed_over, | ||
75 | |||
76 | .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, | ||
77 | }; | ||
78 | |||
79 | static int cns3xxx_ehci_probe(struct platform_device *pdev) | ||
80 | { | ||
81 | struct device *dev = &pdev->dev; | ||
82 | struct usb_hcd *hcd; | ||
83 | const struct hc_driver *driver = &cns3xxx_ehci_hc_driver; | ||
84 | struct resource *res; | ||
85 | int irq; | ||
86 | int retval; | ||
87 | |||
88 | if (usb_disabled()) | ||
89 | return -ENODEV; | ||
90 | |||
91 | res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | ||
92 | if (!res) { | ||
93 | dev_err(dev, "Found HC with no IRQ.\n"); | ||
94 | return -ENODEV; | ||
95 | } | ||
96 | irq = res->start; | ||
97 | |||
98 | hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev)); | ||
99 | if (!hcd) | ||
100 | return -ENOMEM; | ||
101 | |||
102 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
103 | if (!res) { | ||
104 | dev_err(dev, "Found HC with no register addr.\n"); | ||
105 | retval = -ENODEV; | ||
106 | goto err1; | ||
107 | } | ||
108 | |||
109 | hcd->rsrc_start = res->start; | ||
110 | hcd->rsrc_len = res->end - res->start + 1; | ||
111 | |||
112 | if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, | ||
113 | driver->description)) { | ||
114 | dev_dbg(dev, "controller already in use\n"); | ||
115 | retval = -EBUSY; | ||
116 | goto err1; | ||
117 | } | ||
118 | |||
119 | hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); | ||
120 | if (hcd->regs == NULL) { | ||
121 | dev_dbg(dev, "error mapping memory\n"); | ||
122 | retval = -EFAULT; | ||
123 | goto err2; | ||
124 | } | ||
125 | |||
126 | retval = usb_add_hcd(hcd, irq, IRQF_SHARED); | ||
127 | if (retval == 0) | ||
128 | return retval; | ||
129 | |||
130 | iounmap(hcd->regs); | ||
131 | err2: | ||
132 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | ||
133 | err1: | ||
134 | usb_put_hcd(hcd); | ||
135 | |||
136 | return retval; | ||
137 | } | ||
138 | |||
139 | static int cns3xxx_ehci_remove(struct platform_device *pdev) | ||
140 | { | ||
141 | struct usb_hcd *hcd = platform_get_drvdata(pdev); | ||
142 | |||
143 | usb_remove_hcd(hcd); | ||
144 | iounmap(hcd->regs); | ||
145 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | ||
146 | |||
147 | /* | ||
148 | * EHCI and OHCI share the same clock and power, | ||
149 | * resetting twice would cause the 1st controller been reset. | ||
150 | * Therefore only do power up at the first up device, and | ||
151 | * power down at the last down device. | ||
152 | */ | ||
153 | if (atomic_dec_return(&usb_pwr_ref) == 0) | ||
154 | cns3xxx_pwr_clk_dis(1 << PM_CLK_GATE_REG_OFFSET_USB_HOST); | ||
155 | |||
156 | usb_put_hcd(hcd); | ||
157 | |||
158 | platform_set_drvdata(pdev, NULL); | ||
159 | |||
160 | return 0; | ||
161 | } | ||
162 | |||
163 | MODULE_ALIAS("platform:cns3xxx-ehci"); | ||
164 | |||
165 | static struct platform_driver cns3xxx_ehci_driver = { | ||
166 | .probe = cns3xxx_ehci_probe, | ||
167 | .remove = cns3xxx_ehci_remove, | ||
168 | .driver = { | ||
169 | .name = "cns3xxx-ehci", | ||
170 | }, | ||
171 | }; | ||
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index e9062806d4a2..d0c8f7c03e05 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c | |||
@@ -1216,6 +1216,11 @@ MODULE_LICENSE ("GPL"); | |||
1216 | #define PLATFORM_DRIVER ehci_octeon_driver | 1216 | #define PLATFORM_DRIVER ehci_octeon_driver |
1217 | #endif | 1217 | #endif |
1218 | 1218 | ||
1219 | #ifdef CONFIG_USB_CNS3XXX_EHCI | ||
1220 | #include "ehci-cns3xxx.c" | ||
1221 | #define PLATFORM_DRIVER cns3xxx_ehci_driver | ||
1222 | #endif | ||
1223 | |||
1219 | #if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) && \ | 1224 | #if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) && \ |
1220 | !defined(PS3_SYSTEM_BUS_DRIVER) && !defined(OF_PLATFORM_DRIVER) && \ | 1225 | !defined(PS3_SYSTEM_BUS_DRIVER) && !defined(OF_PLATFORM_DRIVER) && \ |
1221 | !defined(XILINX_OF_PLATFORM_DRIVER) | 1226 | !defined(XILINX_OF_PLATFORM_DRIVER) |
diff --git a/drivers/usb/host/ohci-cns3xxx.c b/drivers/usb/host/ohci-cns3xxx.c new file mode 100644 index 000000000000..f05ef87e934c --- /dev/null +++ b/drivers/usb/host/ohci-cns3xxx.c | |||
@@ -0,0 +1,165 @@ | |||
1 | /* | ||
2 | * Copyright 2008 Cavium Networks | ||
3 | * | ||
4 | * This file is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License, Version 2, as | ||
6 | * published by the Free Software Foundation. | ||
7 | */ | ||
8 | |||
9 | #include <linux/platform_device.h> | ||
10 | #include <linux/atomic.h> | ||
11 | #include <mach/cns3xxx.h> | ||
12 | #include <mach/pm.h> | ||
13 | |||
14 | static int __devinit | ||
15 | cns3xxx_ohci_start(struct usb_hcd *hcd) | ||
16 | { | ||
17 | struct ohci_hcd *ohci = hcd_to_ohci(hcd); | ||
18 | int ret; | ||
19 | |||
20 | /* | ||
21 | * EHCI and OHCI share the same clock and power, | ||
22 | * resetting twice would cause the 1st controller been reset. | ||
23 | * Therefore only do power up at the first up device, and | ||
24 | * power down at the last down device. | ||
25 | * | ||
26 | * Set USB AHB INCR length to 16 | ||
27 | */ | ||
28 | if (atomic_inc_return(&usb_pwr_ref) == 1) { | ||
29 | cns3xxx_pwr_power_up(1 << PM_PLL_HM_PD_CTRL_REG_OFFSET_PLL_USB); | ||
30 | cns3xxx_pwr_clk_en(1 << PM_CLK_GATE_REG_OFFSET_USB_HOST); | ||
31 | cns3xxx_pwr_soft_rst(1 << PM_SOFT_RST_REG_OFFST_USB_HOST); | ||
32 | __raw_writel((__raw_readl(MISC_CHIP_CONFIG_REG) | (0X2 << 24)), | ||
33 | MISC_CHIP_CONFIG_REG); | ||
34 | } | ||
35 | |||
36 | ret = ohci_init(ohci); | ||
37 | if (ret < 0) | ||
38 | return ret; | ||
39 | |||
40 | ohci->num_ports = 1; | ||
41 | |||
42 | ret = ohci_run(ohci); | ||
43 | if (ret < 0) { | ||
44 | err("can't start %s", hcd->self.bus_name); | ||
45 | ohci_stop(hcd); | ||
46 | return ret; | ||
47 | } | ||
48 | return 0; | ||
49 | } | ||
50 | |||
51 | static const struct hc_driver cns3xxx_ohci_hc_driver = { | ||
52 | .description = hcd_name, | ||
53 | .product_desc = "CNS3XXX OHCI Host controller", | ||
54 | .hcd_priv_size = sizeof(struct ohci_hcd), | ||
55 | .irq = ohci_irq, | ||
56 | .flags = HCD_USB11 | HCD_MEMORY, | ||
57 | .start = cns3xxx_ohci_start, | ||
58 | .stop = ohci_stop, | ||
59 | .shutdown = ohci_shutdown, | ||
60 | .urb_enqueue = ohci_urb_enqueue, | ||
61 | .urb_dequeue = ohci_urb_dequeue, | ||
62 | .endpoint_disable = ohci_endpoint_disable, | ||
63 | .get_frame_number = ohci_get_frame, | ||
64 | .hub_status_data = ohci_hub_status_data, | ||
65 | .hub_control = ohci_hub_control, | ||
66 | #ifdef CONFIG_PM | ||
67 | .bus_suspend = ohci_bus_suspend, | ||
68 | .bus_resume = ohci_bus_resume, | ||
69 | #endif | ||
70 | .start_port_reset = ohci_start_port_reset, | ||
71 | }; | ||
72 | |||
73 | static int cns3xxx_ohci_probe(struct platform_device *pdev) | ||
74 | { | ||
75 | struct device *dev = &pdev->dev; | ||
76 | struct usb_hcd *hcd; | ||
77 | const struct hc_driver *driver = &cns3xxx_ohci_hc_driver; | ||
78 | struct resource *res; | ||
79 | int irq; | ||
80 | int retval; | ||
81 | |||
82 | if (usb_disabled()) | ||
83 | return -ENODEV; | ||
84 | |||
85 | res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | ||
86 | if (!res) { | ||
87 | dev_err(dev, "Found HC with no IRQ.\n"); | ||
88 | return -ENODEV; | ||
89 | } | ||
90 | irq = res->start; | ||
91 | |||
92 | hcd = usb_create_hcd(driver, dev, dev_name(dev)); | ||
93 | if (!hcd) | ||
94 | return -ENOMEM; | ||
95 | |||
96 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
97 | if (!res) { | ||
98 | dev_err(dev, "Found HC with no register addr.\n"); | ||
99 | retval = -ENODEV; | ||
100 | goto err1; | ||
101 | } | ||
102 | hcd->rsrc_start = res->start; | ||
103 | hcd->rsrc_len = res->end - res->start + 1; | ||
104 | |||
105 | if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, | ||
106 | driver->description)) { | ||
107 | dev_dbg(dev, "controller already in use\n"); | ||
108 | retval = -EBUSY; | ||
109 | goto err1; | ||
110 | } | ||
111 | |||
112 | hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); | ||
113 | if (!hcd->regs) { | ||
114 | dev_dbg(dev, "error mapping memory\n"); | ||
115 | retval = -EFAULT; | ||
116 | goto err2; | ||
117 | } | ||
118 | |||
119 | ohci_hcd_init(hcd_to_ohci(hcd)); | ||
120 | |||
121 | retval = usb_add_hcd(hcd, irq, IRQF_SHARED); | ||
122 | if (retval == 0) | ||
123 | return retval; | ||
124 | |||
125 | iounmap(hcd->regs); | ||
126 | err2: | ||
127 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | ||
128 | err1: | ||
129 | usb_put_hcd(hcd); | ||
130 | return retval; | ||
131 | } | ||
132 | |||
133 | static int cns3xxx_ohci_remove(struct platform_device *pdev) | ||
134 | { | ||
135 | struct usb_hcd *hcd = platform_get_drvdata(pdev); | ||
136 | |||
137 | usb_remove_hcd(hcd); | ||
138 | iounmap(hcd->regs); | ||
139 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | ||
140 | |||
141 | /* | ||
142 | * EHCI and OHCI share the same clock and power, | ||
143 | * resetting twice would cause the 1st controller been reset. | ||
144 | * Therefore only do power up at the first up device, and | ||
145 | * power down at the last down device. | ||
146 | */ | ||
147 | if (atomic_dec_return(&usb_pwr_ref) == 0) | ||
148 | cns3xxx_pwr_clk_dis(1 << PM_CLK_GATE_REG_OFFSET_USB_HOST); | ||
149 | |||
150 | usb_put_hcd(hcd); | ||
151 | |||
152 | platform_set_drvdata(pdev, NULL); | ||
153 | |||
154 | return 0; | ||
155 | } | ||
156 | |||
157 | MODULE_ALIAS("platform:cns3xxx-ohci"); | ||
158 | |||
159 | static struct platform_driver ohci_hcd_cns3xxx_driver = { | ||
160 | .probe = cns3xxx_ohci_probe, | ||
161 | .remove = cns3xxx_ohci_remove, | ||
162 | .driver = { | ||
163 | .name = "cns3xxx-ohci", | ||
164 | }, | ||
165 | }; | ||
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index 5179acb7aa2f..5cb6731ba443 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c | |||
@@ -1111,6 +1111,11 @@ MODULE_LICENSE ("GPL"); | |||
1111 | #define PLATFORM_DRIVER ohci_octeon_driver | 1111 | #define PLATFORM_DRIVER ohci_octeon_driver |
1112 | #endif | 1112 | #endif |
1113 | 1113 | ||
1114 | #ifdef CONFIG_USB_CNS3XXX_OHCI | ||
1115 | #include "ohci-cns3xxx.c" | ||
1116 | #define PLATFORM_DRIVER ohci_hcd_cns3xxx_driver | ||
1117 | #endif | ||
1118 | |||
1114 | #if !defined(PCI_DRIVER) && \ | 1119 | #if !defined(PCI_DRIVER) && \ |
1115 | !defined(PLATFORM_DRIVER) && \ | 1120 | !defined(PLATFORM_DRIVER) && \ |
1116 | !defined(OMAP1_PLATFORM_DRIVER) && \ | 1121 | !defined(OMAP1_PLATFORM_DRIVER) && \ |
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index 94701ff3a23a..159c77a5746f 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c | |||
@@ -884,6 +884,7 @@ static int log_write(void __user *log_base, | |||
884 | int r; | 884 | int r; |
885 | if (!write_length) | 885 | if (!write_length) |
886 | return 0; | 886 | return 0; |
887 | write_length += write_address % VHOST_PAGE_SIZE; | ||
887 | write_address /= VHOST_PAGE_SIZE; | 888 | write_address /= VHOST_PAGE_SIZE; |
888 | for (;;) { | 889 | for (;;) { |
889 | u64 base = (u64)(unsigned long)log_base; | 890 | u64 base = (u64)(unsigned long)log_base; |
@@ -897,7 +898,7 @@ static int log_write(void __user *log_base, | |||
897 | if (write_length <= VHOST_PAGE_SIZE) | 898 | if (write_length <= VHOST_PAGE_SIZE) |
898 | break; | 899 | break; |
899 | write_length -= VHOST_PAGE_SIZE; | 900 | write_length -= VHOST_PAGE_SIZE; |
900 | write_address += VHOST_PAGE_SIZE; | 901 | write_address += 1; |
901 | } | 902 | } |
902 | return r; | 903 | return r; |
903 | } | 904 | } |
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 27c1fb4b1e0d..ab77297fbed2 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig | |||
@@ -1850,6 +1850,16 @@ config FB_PXA_PARAMETERS | |||
1850 | 1850 | ||
1851 | <file:Documentation/fb/pxafb.txt> describes the available parameters. | 1851 | <file:Documentation/fb/pxafb.txt> describes the available parameters. |
1852 | 1852 | ||
1853 | config PXA3XX_GCU | ||
1854 | tristate "PXA3xx 2D graphics accelerator driver" | ||
1855 | depends on FB_PXA | ||
1856 | help | ||
1857 | Kernelspace driver for the 2D graphics controller unit (GCU) | ||
1858 | found on PXA3xx processors. There is a counterpart driver in the | ||
1859 | DirectFB suite, see http://www.directfb.org/ | ||
1860 | |||
1861 | If you compile this as a module, it will be called pxa3xx_gcu. | ||
1862 | |||
1853 | config FB_MBX | 1863 | config FB_MBX |
1854 | tristate "2700G LCD framebuffer support" | 1864 | tristate "2700G LCD framebuffer support" |
1855 | depends on FB && ARCH_PXA | 1865 | depends on FB && ARCH_PXA |
diff --git a/drivers/video/Makefile b/drivers/video/Makefile index 485e8ed1318c..9260a898f343 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile | |||
@@ -100,6 +100,7 @@ obj-$(CONFIG_FB_CIRRUS) += cirrusfb.o | |||
100 | obj-$(CONFIG_FB_ASILIANT) += asiliantfb.o | 100 | obj-$(CONFIG_FB_ASILIANT) += asiliantfb.o |
101 | obj-$(CONFIG_FB_PXA) += pxafb.o | 101 | obj-$(CONFIG_FB_PXA) += pxafb.o |
102 | obj-$(CONFIG_FB_PXA168) += pxa168fb.o | 102 | obj-$(CONFIG_FB_PXA168) += pxa168fb.o |
103 | obj-$(CONFIG_PXA3XX_GCU) += pxa3xx-gcu.o | ||
103 | obj-$(CONFIG_FB_W100) += w100fb.o | 104 | obj-$(CONFIG_FB_W100) += w100fb.o |
104 | obj-$(CONFIG_FB_TMIO) += tmiofb.o | 105 | obj-$(CONFIG_FB_TMIO) += tmiofb.o |
105 | obj-$(CONFIG_FB_AU1100) += au1100fb.o | 106 | obj-$(CONFIG_FB_AU1100) += au1100fb.o |
diff --git a/drivers/video/modedb.c b/drivers/video/modedb.c index 0a4dbdc1693a..de450c1fb869 100644 --- a/drivers/video/modedb.c +++ b/drivers/video/modedb.c | |||
@@ -855,6 +855,7 @@ const struct fb_videomode *fb_find_nearest_mode(const struct fb_videomode *mode, | |||
855 | abs(cmode->yres - mode->yres); | 855 | abs(cmode->yres - mode->yres); |
856 | if (diff > d) { | 856 | if (diff > d) { |
857 | diff = d; | 857 | diff = d; |
858 | diff_refresh = abs(cmode->refresh - mode->refresh); | ||
858 | best = cmode; | 859 | best = cmode; |
859 | } else if (diff == d) { | 860 | } else if (diff == d) { |
860 | d = abs(cmode->refresh - mode->refresh); | 861 | d = abs(cmode->refresh - mode->refresh); |
diff --git a/drivers/video/pxa3xx-gcu.c b/drivers/video/pxa3xx-gcu.c new file mode 100644 index 000000000000..b81168df253d --- /dev/null +++ b/drivers/video/pxa3xx-gcu.c | |||
@@ -0,0 +1,772 @@ | |||
1 | /* | ||
2 | * pxa3xx-gc.c - Linux kernel module for PXA3xx graphics controllers | ||
3 | * | ||
4 | * This driver needs a DirectFB counterpart in user space, communication | ||
5 | * is handled via mmap()ed memory areas and an ioctl. | ||
6 | * | ||
7 | * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de> | ||
8 | * Copyright (c) 2009 Janine Kropp <nin@directfb.org> | ||
9 | * Copyright (c) 2009 Denis Oliver Kropp <dok@directfb.org> | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU General Public License as published by | ||
13 | * the Free Software Foundation; either version 2 of the License, or | ||
14 | * (at your option) any later version. | ||
15 | * | ||
16 | * This program is distributed in the hope that it will be useful, | ||
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
19 | * GNU General Public License for more details. | ||
20 | * | ||
21 | * You should have received a copy of the GNU General Public License | ||
22 | * along with this program; if not, write to the Free Software | ||
23 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
24 | */ | ||
25 | |||
26 | /* | ||
27 | * WARNING: This controller is attached to System Bus 2 of the PXA which | ||
28 | * needs its arbiter to be enabled explictly (CKENB & 1<<9). | ||
29 | * There is currently no way to do this from Linux, so you need to teach | ||
30 | * your bootloader for now. | ||
31 | */ | ||
32 | |||
33 | #include <linux/module.h> | ||
34 | #include <linux/version.h> | ||
35 | |||
36 | #include <linux/platform_device.h> | ||
37 | #include <linux/dma-mapping.h> | ||
38 | #include <linux/miscdevice.h> | ||
39 | #include <linux/interrupt.h> | ||
40 | #include <linux/spinlock.h> | ||
41 | #include <linux/uaccess.h> | ||
42 | #include <linux/ioctl.h> | ||
43 | #include <linux/delay.h> | ||
44 | #include <linux/sched.h> | ||
45 | #include <linux/slab.h> | ||
46 | #include <linux/clk.h> | ||
47 | #include <linux/fs.h> | ||
48 | #include <linux/io.h> | ||
49 | |||
50 | #include "pxa3xx-gcu.h" | ||
51 | |||
52 | #define DRV_NAME "pxa3xx-gcu" | ||
53 | #define MISCDEV_MINOR 197 | ||
54 | |||
55 | #define REG_GCCR 0x00 | ||
56 | #define GCCR_SYNC_CLR (1 << 9) | ||
57 | #define GCCR_BP_RST (1 << 8) | ||
58 | #define GCCR_ABORT (1 << 6) | ||
59 | #define GCCR_STOP (1 << 4) | ||
60 | |||
61 | #define REG_GCISCR 0x04 | ||
62 | #define REG_GCIECR 0x08 | ||
63 | #define REG_GCRBBR 0x20 | ||
64 | #define REG_GCRBLR 0x24 | ||
65 | #define REG_GCRBHR 0x28 | ||
66 | #define REG_GCRBTR 0x2C | ||
67 | #define REG_GCRBEXHR 0x30 | ||
68 | |||
69 | #define IE_EOB (1 << 0) | ||
70 | #define IE_EEOB (1 << 5) | ||
71 | #define IE_ALL 0xff | ||
72 | |||
73 | #define SHARED_SIZE PAGE_ALIGN(sizeof(struct pxa3xx_gcu_shared)) | ||
74 | |||
75 | /* #define PXA3XX_GCU_DEBUG */ | ||
76 | /* #define PXA3XX_GCU_DEBUG_TIMER */ | ||
77 | |||
78 | #ifdef PXA3XX_GCU_DEBUG | ||
79 | #define QDUMP(msg) \ | ||
80 | do { \ | ||
81 | QPRINT(priv, KERN_DEBUG, msg); \ | ||
82 | } while (0) | ||
83 | #else | ||
84 | #define QDUMP(msg) do {} while (0) | ||
85 | #endif | ||
86 | |||
87 | #define QERROR(msg) \ | ||
88 | do { \ | ||
89 | QPRINT(priv, KERN_ERR, msg); \ | ||
90 | } while (0) | ||
91 | |||
92 | struct pxa3xx_gcu_batch { | ||
93 | struct pxa3xx_gcu_batch *next; | ||
94 | u32 *ptr; | ||
95 | dma_addr_t phys; | ||
96 | unsigned long length; | ||
97 | }; | ||
98 | |||
99 | struct pxa3xx_gcu_priv { | ||
100 | void __iomem *mmio_base; | ||
101 | struct clk *clk; | ||
102 | struct pxa3xx_gcu_shared *shared; | ||
103 | dma_addr_t shared_phys; | ||
104 | struct resource *resource_mem; | ||
105 | struct miscdevice misc_dev; | ||
106 | struct file_operations misc_fops; | ||
107 | wait_queue_head_t wait_idle; | ||
108 | wait_queue_head_t wait_free; | ||
109 | spinlock_t spinlock; | ||
110 | struct timeval base_time; | ||
111 | |||
112 | struct pxa3xx_gcu_batch *free; | ||
113 | |||
114 | struct pxa3xx_gcu_batch *ready; | ||
115 | struct pxa3xx_gcu_batch *ready_last; | ||
116 | struct pxa3xx_gcu_batch *running; | ||
117 | }; | ||
118 | |||
119 | static inline unsigned long | ||
120 | gc_readl(struct pxa3xx_gcu_priv *priv, unsigned int off) | ||
121 | { | ||
122 | return __raw_readl(priv->mmio_base + off); | ||
123 | } | ||
124 | |||
125 | static inline void | ||
126 | gc_writel(struct pxa3xx_gcu_priv *priv, unsigned int off, unsigned long val) | ||
127 | { | ||
128 | __raw_writel(val, priv->mmio_base + off); | ||
129 | } | ||
130 | |||
131 | #define QPRINT(priv, level, msg) \ | ||
132 | do { \ | ||
133 | struct timeval tv; \ | ||
134 | struct pxa3xx_gcu_shared *shared = priv->shared; \ | ||
135 | u32 base = gc_readl(priv, REG_GCRBBR); \ | ||
136 | \ | ||
137 | do_gettimeofday(&tv); \ | ||
138 | \ | ||
139 | printk(level "%ld.%03ld.%03ld - %-17s: %-21s (%s, " \ | ||
140 | "STATUS " \ | ||
141 | "0x%02lx, B 0x%08lx [%ld], E %5ld, H %5ld, " \ | ||
142 | "T %5ld)\n", \ | ||
143 | tv.tv_sec - priv->base_time.tv_sec, \ | ||
144 | tv.tv_usec / 1000, tv.tv_usec % 1000, \ | ||
145 | __func__, msg, \ | ||
146 | shared->hw_running ? "running" : " idle", \ | ||
147 | gc_readl(priv, REG_GCISCR), \ | ||
148 | gc_readl(priv, REG_GCRBBR), \ | ||
149 | gc_readl(priv, REG_GCRBLR), \ | ||
150 | (gc_readl(priv, REG_GCRBEXHR) - base) / 4, \ | ||
151 | (gc_readl(priv, REG_GCRBHR) - base) / 4, \ | ||
152 | (gc_readl(priv, REG_GCRBTR) - base) / 4); \ | ||
153 | } while (0) | ||
154 | |||
155 | static void | ||
156 | pxa3xx_gcu_reset(struct pxa3xx_gcu_priv *priv) | ||
157 | { | ||
158 | QDUMP("RESET"); | ||
159 | |||
160 | /* disable interrupts */ | ||
161 | gc_writel(priv, REG_GCIECR, 0); | ||
162 | |||
163 | /* reset hardware */ | ||
164 | gc_writel(priv, REG_GCCR, GCCR_ABORT); | ||
165 | gc_writel(priv, REG_GCCR, 0); | ||
166 | |||
167 | memset(priv->shared, 0, SHARED_SIZE); | ||
168 | priv->shared->buffer_phys = priv->shared_phys; | ||
169 | priv->shared->magic = PXA3XX_GCU_SHARED_MAGIC; | ||
170 | |||
171 | do_gettimeofday(&priv->base_time); | ||
172 | |||
173 | /* set up the ring buffer pointers */ | ||
174 | gc_writel(priv, REG_GCRBLR, 0); | ||
175 | gc_writel(priv, REG_GCRBBR, priv->shared_phys); | ||
176 | gc_writel(priv, REG_GCRBTR, priv->shared_phys); | ||
177 | |||
178 | /* enable all IRQs except EOB */ | ||
179 | gc_writel(priv, REG_GCIECR, IE_ALL & ~IE_EOB); | ||
180 | } | ||
181 | |||
182 | static void | ||
183 | dump_whole_state(struct pxa3xx_gcu_priv *priv) | ||
184 | { | ||
185 | struct pxa3xx_gcu_shared *sh = priv->shared; | ||
186 | u32 base = gc_readl(priv, REG_GCRBBR); | ||
187 | |||
188 | QDUMP("DUMP"); | ||
189 | |||
190 | printk(KERN_DEBUG "== PXA3XX-GCU DUMP ==\n" | ||
191 | "%s, STATUS 0x%02lx, B 0x%08lx [%ld], E %5ld, H %5ld, T %5ld\n", | ||
192 | sh->hw_running ? "running" : "idle ", | ||
193 | gc_readl(priv, REG_GCISCR), | ||
194 | gc_readl(priv, REG_GCRBBR), | ||
195 | gc_readl(priv, REG_GCRBLR), | ||
196 | (gc_readl(priv, REG_GCRBEXHR) - base) / 4, | ||
197 | (gc_readl(priv, REG_GCRBHR) - base) / 4, | ||
198 | (gc_readl(priv, REG_GCRBTR) - base) / 4); | ||
199 | } | ||
200 | |||
201 | static void | ||
202 | flush_running(struct pxa3xx_gcu_priv *priv) | ||
203 | { | ||
204 | struct pxa3xx_gcu_batch *running = priv->running; | ||
205 | struct pxa3xx_gcu_batch *next; | ||
206 | |||
207 | while (running) { | ||
208 | next = running->next; | ||
209 | running->next = priv->free; | ||
210 | priv->free = running; | ||
211 | running = next; | ||
212 | } | ||
213 | |||
214 | priv->running = NULL; | ||
215 | } | ||
216 | |||
217 | static void | ||
218 | run_ready(struct pxa3xx_gcu_priv *priv) | ||
219 | { | ||
220 | unsigned int num = 0; | ||
221 | struct pxa3xx_gcu_shared *shared = priv->shared; | ||
222 | struct pxa3xx_gcu_batch *ready = priv->ready; | ||
223 | |||
224 | QDUMP("Start"); | ||
225 | |||
226 | BUG_ON(!ready); | ||
227 | |||
228 | shared->buffer[num++] = 0x05000000; | ||
229 | |||
230 | while (ready) { | ||
231 | shared->buffer[num++] = 0x00000001; | ||
232 | shared->buffer[num++] = ready->phys; | ||
233 | ready = ready->next; | ||
234 | } | ||
235 | |||
236 | shared->buffer[num++] = 0x05000000; | ||
237 | priv->running = priv->ready; | ||
238 | priv->ready = priv->ready_last = NULL; | ||
239 | gc_writel(priv, REG_GCRBLR, 0); | ||
240 | shared->hw_running = 1; | ||
241 | |||
242 | /* ring base address */ | ||
243 | gc_writel(priv, REG_GCRBBR, shared->buffer_phys); | ||
244 | |||
245 | /* ring tail address */ | ||
246 | gc_writel(priv, REG_GCRBTR, shared->buffer_phys + num * 4); | ||
247 | |||
248 | /* ring length */ | ||
249 | gc_writel(priv, REG_GCRBLR, ((num + 63) & ~63) * 4); | ||
250 | } | ||
251 | |||
252 | static irqreturn_t | ||
253 | pxa3xx_gcu_handle_irq(int irq, void *ctx) | ||
254 | { | ||
255 | struct pxa3xx_gcu_priv *priv = ctx; | ||
256 | struct pxa3xx_gcu_shared *shared = priv->shared; | ||
257 | u32 status = gc_readl(priv, REG_GCISCR) & IE_ALL; | ||
258 | |||
259 | QDUMP("-Interrupt"); | ||
260 | |||
261 | if (!status) | ||
262 | return IRQ_NONE; | ||
263 | |||
264 | spin_lock(&priv->spinlock); | ||
265 | shared->num_interrupts++; | ||
266 | |||
267 | if (status & IE_EEOB) { | ||
268 | QDUMP(" [EEOB]"); | ||
269 | |||
270 | flush_running(priv); | ||
271 | wake_up_all(&priv->wait_free); | ||
272 | |||
273 | if (priv->ready) { | ||
274 | run_ready(priv); | ||
275 | } else { | ||
276 | /* There is no more data prepared by the userspace. | ||
277 | * Set hw_running = 0 and wait for the next userspace | ||
278 | * kick-off */ | ||
279 | shared->num_idle++; | ||
280 | shared->hw_running = 0; | ||
281 | |||
282 | QDUMP(" '-> Idle."); | ||
283 | |||
284 | /* set ring buffer length to zero */ | ||
285 | gc_writel(priv, REG_GCRBLR, 0); | ||
286 | |||
287 | wake_up_all(&priv->wait_idle); | ||
288 | } | ||
289 | |||
290 | shared->num_done++; | ||
291 | } else { | ||
292 | QERROR(" [???]"); | ||
293 | dump_whole_state(priv); | ||
294 | } | ||
295 | |||
296 | /* Clear the interrupt */ | ||
297 | gc_writel(priv, REG_GCISCR, status); | ||
298 | spin_unlock(&priv->spinlock); | ||
299 | |||
300 | return IRQ_HANDLED; | ||
301 | } | ||
302 | |||
303 | static int | ||
304 | pxa3xx_gcu_wait_idle(struct pxa3xx_gcu_priv *priv) | ||
305 | { | ||
306 | int ret = 0; | ||
307 | |||
308 | QDUMP("Waiting for idle..."); | ||
309 | |||
310 | /* Does not need to be atomic. There's a lock in user space, | ||
311 | * but anyhow, this is just for statistics. */ | ||
312 | priv->shared->num_wait_idle++; | ||
313 | |||
314 | while (priv->shared->hw_running) { | ||
315 | int num = priv->shared->num_interrupts; | ||
316 | u32 rbexhr = gc_readl(priv, REG_GCRBEXHR); | ||
317 | |||
318 | ret = wait_event_interruptible_timeout(priv->wait_idle, | ||
319 | !priv->shared->hw_running, HZ*4); | ||
320 | |||
321 | if (ret < 0) | ||
322 | break; | ||
323 | |||
324 | if (ret > 0) | ||
325 | continue; | ||
326 | |||
327 | if (gc_readl(priv, REG_GCRBEXHR) == rbexhr && | ||
328 | priv->shared->num_interrupts == num) { | ||
329 | QERROR("TIMEOUT"); | ||
330 | ret = -ETIMEDOUT; | ||
331 | break; | ||
332 | } | ||
333 | } | ||
334 | |||
335 | QDUMP("done"); | ||
336 | |||
337 | return ret; | ||
338 | } | ||
339 | |||
340 | static int | ||
341 | pxa3xx_gcu_wait_free(struct pxa3xx_gcu_priv *priv) | ||
342 | { | ||
343 | int ret = 0; | ||
344 | |||
345 | QDUMP("Waiting for free..."); | ||
346 | |||
347 | /* Does not need to be atomic. There's a lock in user space, | ||
348 | * but anyhow, this is just for statistics. */ | ||
349 | priv->shared->num_wait_free++; | ||
350 | |||
351 | while (!priv->free) { | ||
352 | u32 rbexhr = gc_readl(priv, REG_GCRBEXHR); | ||
353 | |||
354 | ret = wait_event_interruptible_timeout(priv->wait_free, | ||
355 | priv->free, HZ*4); | ||
356 | |||
357 | if (ret < 0) | ||
358 | break; | ||
359 | |||
360 | if (ret > 0) | ||
361 | continue; | ||
362 | |||
363 | if (gc_readl(priv, REG_GCRBEXHR) == rbexhr) { | ||
364 | QERROR("TIMEOUT"); | ||
365 | ret = -ETIMEDOUT; | ||
366 | break; | ||
367 | } | ||
368 | } | ||
369 | |||
370 | QDUMP("done"); | ||
371 | |||
372 | return ret; | ||
373 | } | ||
374 | |||
375 | /* Misc device layer */ | ||
376 | |||
377 | static ssize_t | ||
378 | pxa3xx_gcu_misc_write(struct file *filp, const char *buff, | ||
379 | size_t count, loff_t *offp) | ||
380 | { | ||
381 | int ret; | ||
382 | unsigned long flags; | ||
383 | struct pxa3xx_gcu_batch *buffer; | ||
384 | struct pxa3xx_gcu_priv *priv = | ||
385 | container_of(filp->f_op, struct pxa3xx_gcu_priv, misc_fops); | ||
386 | |||
387 | int words = count / 4; | ||
388 | |||
389 | /* Does not need to be atomic. There's a lock in user space, | ||
390 | * but anyhow, this is just for statistics. */ | ||
391 | priv->shared->num_writes++; | ||
392 | |||
393 | priv->shared->num_words += words; | ||
394 | |||
395 | /* Last word reserved for batch buffer end command */ | ||
396 | if (words >= PXA3XX_GCU_BATCH_WORDS) | ||
397 | return -E2BIG; | ||
398 | |||
399 | /* Wait for a free buffer */ | ||
400 | if (!priv->free) { | ||
401 | ret = pxa3xx_gcu_wait_free(priv); | ||
402 | if (ret < 0) | ||
403 | return ret; | ||
404 | } | ||
405 | |||
406 | /* | ||
407 | * Get buffer from free list | ||
408 | */ | ||
409 | spin_lock_irqsave(&priv->spinlock, flags); | ||
410 | |||
411 | buffer = priv->free; | ||
412 | priv->free = buffer->next; | ||
413 | |||
414 | spin_unlock_irqrestore(&priv->spinlock, flags); | ||
415 | |||
416 | |||
417 | /* Copy data from user into buffer */ | ||
418 | ret = copy_from_user(buffer->ptr, buff, words * 4); | ||
419 | if (ret) { | ||
420 | spin_lock_irqsave(&priv->spinlock, flags); | ||
421 | buffer->next = priv->free; | ||
422 | priv->free = buffer; | ||
423 | spin_unlock_irqrestore(&priv->spinlock, flags); | ||
424 | return ret; | ||
425 | } | ||
426 | |||
427 | buffer->length = words; | ||
428 | |||
429 | /* Append batch buffer end command */ | ||
430 | buffer->ptr[words] = 0x01000000; | ||
431 | |||
432 | /* | ||
433 | * Add buffer to ready list | ||
434 | */ | ||
435 | spin_lock_irqsave(&priv->spinlock, flags); | ||
436 | |||
437 | buffer->next = NULL; | ||
438 | |||
439 | if (priv->ready) { | ||
440 | BUG_ON(priv->ready_last == NULL); | ||
441 | |||
442 | priv->ready_last->next = buffer; | ||
443 | } else | ||
444 | priv->ready = buffer; | ||
445 | |||
446 | priv->ready_last = buffer; | ||
447 | |||
448 | if (!priv->shared->hw_running) | ||
449 | run_ready(priv); | ||
450 | |||
451 | spin_unlock_irqrestore(&priv->spinlock, flags); | ||
452 | |||
453 | return words * 4; | ||
454 | } | ||
455 | |||
456 | |||
457 | static long | ||
458 | pxa3xx_gcu_misc_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | ||
459 | { | ||
460 | unsigned long flags; | ||
461 | struct pxa3xx_gcu_priv *priv = | ||
462 | container_of(filp->f_op, struct pxa3xx_gcu_priv, misc_fops); | ||
463 | |||
464 | switch (cmd) { | ||
465 | case PXA3XX_GCU_IOCTL_RESET: | ||
466 | spin_lock_irqsave(&priv->spinlock, flags); | ||
467 | pxa3xx_gcu_reset(priv); | ||
468 | spin_unlock_irqrestore(&priv->spinlock, flags); | ||
469 | return 0; | ||
470 | |||
471 | case PXA3XX_GCU_IOCTL_WAIT_IDLE: | ||
472 | return pxa3xx_gcu_wait_idle(priv); | ||
473 | } | ||
474 | |||
475 | return -ENOSYS; | ||
476 | } | ||
477 | |||
478 | static int | ||
479 | pxa3xx_gcu_misc_mmap(struct file *filp, struct vm_area_struct *vma) | ||
480 | { | ||
481 | unsigned int size = vma->vm_end - vma->vm_start; | ||
482 | struct pxa3xx_gcu_priv *priv = | ||
483 | container_of(filp->f_op, struct pxa3xx_gcu_priv, misc_fops); | ||
484 | |||
485 | switch (vma->vm_pgoff) { | ||
486 | case 0: | ||
487 | /* hand out the shared data area */ | ||
488 | if (size != SHARED_SIZE) | ||
489 | return -EINVAL; | ||
490 | |||
491 | return dma_mmap_coherent(NULL, vma, | ||
492 | priv->shared, priv->shared_phys, size); | ||
493 | |||
494 | case SHARED_SIZE >> PAGE_SHIFT: | ||
495 | /* hand out the MMIO base for direct register access | ||
496 | * from userspace */ | ||
497 | if (size != resource_size(priv->resource_mem)) | ||
498 | return -EINVAL; | ||
499 | |||
500 | vma->vm_flags |= VM_IO; | ||
501 | vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); | ||
502 | |||
503 | return io_remap_pfn_range(vma, vma->vm_start, | ||
504 | priv->resource_mem->start >> PAGE_SHIFT, | ||
505 | size, vma->vm_page_prot); | ||
506 | } | ||
507 | |||
508 | return -EINVAL; | ||
509 | } | ||
510 | |||
511 | |||
512 | #ifdef PXA3XX_GCU_DEBUG_TIMER | ||
513 | static struct timer_list pxa3xx_gcu_debug_timer; | ||
514 | |||
515 | static void pxa3xx_gcu_debug_timedout(unsigned long ptr) | ||
516 | { | ||
517 | struct pxa3xx_gcu_priv *priv = (struct pxa3xx_gcu_priv *) ptr; | ||
518 | |||
519 | QERROR("Timer DUMP"); | ||
520 | |||
521 | /* init the timer structure */ | ||
522 | init_timer(&pxa3xx_gcu_debug_timer); | ||
523 | pxa3xx_gcu_debug_timer.function = pxa3xx_gcu_debug_timedout; | ||
524 | pxa3xx_gcu_debug_timer.data = ptr; | ||
525 | pxa3xx_gcu_debug_timer.expires = jiffies + 5*HZ; /* one second */ | ||
526 | |||
527 | add_timer(&pxa3xx_gcu_debug_timer); | ||
528 | } | ||
529 | |||
530 | static void pxa3xx_gcu_init_debug_timer(void) | ||
531 | { | ||
532 | pxa3xx_gcu_debug_timedout((unsigned long) &pxa3xx_gcu_debug_timer); | ||
533 | } | ||
534 | #else | ||
535 | static inline void pxa3xx_gcu_init_debug_timer(void) {} | ||
536 | #endif | ||
537 | |||
538 | static int | ||
539 | add_buffer(struct platform_device *dev, | ||
540 | struct pxa3xx_gcu_priv *priv) | ||
541 | { | ||
542 | struct pxa3xx_gcu_batch *buffer; | ||
543 | |||
544 | buffer = kzalloc(sizeof(struct pxa3xx_gcu_batch), GFP_KERNEL); | ||
545 | if (!buffer) | ||
546 | return -ENOMEM; | ||
547 | |||
548 | buffer->ptr = dma_alloc_coherent(&dev->dev, PXA3XX_GCU_BATCH_WORDS * 4, | ||
549 | &buffer->phys, GFP_KERNEL); | ||
550 | if (!buffer->ptr) { | ||
551 | kfree(buffer); | ||
552 | return -ENOMEM; | ||
553 | } | ||
554 | |||
555 | buffer->next = priv->free; | ||
556 | |||
557 | priv->free = buffer; | ||
558 | |||
559 | return 0; | ||
560 | } | ||
561 | |||
562 | static void | ||
563 | free_buffers(struct platform_device *dev, | ||
564 | struct pxa3xx_gcu_priv *priv) | ||
565 | { | ||
566 | struct pxa3xx_gcu_batch *next, *buffer = priv->free; | ||
567 | |||
568 | while (buffer) { | ||
569 | next = buffer->next; | ||
570 | |||
571 | dma_free_coherent(&dev->dev, PXA3XX_GCU_BATCH_WORDS * 4, | ||
572 | buffer->ptr, buffer->phys); | ||
573 | |||
574 | kfree(buffer); | ||
575 | |||
576 | buffer = next; | ||
577 | } | ||
578 | |||
579 | priv->free = NULL; | ||
580 | } | ||
581 | |||
582 | static int __devinit | ||
583 | pxa3xx_gcu_probe(struct platform_device *dev) | ||
584 | { | ||
585 | int i, ret, irq; | ||
586 | struct resource *r; | ||
587 | struct pxa3xx_gcu_priv *priv; | ||
588 | |||
589 | priv = kzalloc(sizeof(struct pxa3xx_gcu_priv), GFP_KERNEL); | ||
590 | if (!priv) | ||
591 | return -ENOMEM; | ||
592 | |||
593 | for (i = 0; i < 8; i++) { | ||
594 | ret = add_buffer(dev, priv); | ||
595 | if (ret) { | ||
596 | dev_err(&dev->dev, "failed to allocate DMA memory\n"); | ||
597 | goto err_free_priv; | ||
598 | } | ||
599 | } | ||
600 | |||
601 | init_waitqueue_head(&priv->wait_idle); | ||
602 | init_waitqueue_head(&priv->wait_free); | ||
603 | spin_lock_init(&priv->spinlock); | ||
604 | |||
605 | /* we allocate the misc device structure as part of our own allocation, | ||
606 | * so we can get a pointer to our priv structure later on with | ||
607 | * container_of(). This isn't really necessary as we have a fixed minor | ||
608 | * number anyway, but this is to avoid statics. */ | ||
609 | |||
610 | priv->misc_fops.owner = THIS_MODULE; | ||
611 | priv->misc_fops.write = pxa3xx_gcu_misc_write; | ||
612 | priv->misc_fops.unlocked_ioctl = pxa3xx_gcu_misc_ioctl; | ||
613 | priv->misc_fops.mmap = pxa3xx_gcu_misc_mmap; | ||
614 | |||
615 | priv->misc_dev.minor = MISCDEV_MINOR, | ||
616 | priv->misc_dev.name = DRV_NAME, | ||
617 | priv->misc_dev.fops = &priv->misc_fops, | ||
618 | |||
619 | /* register misc device */ | ||
620 | ret = misc_register(&priv->misc_dev); | ||
621 | if (ret < 0) { | ||
622 | dev_err(&dev->dev, "misc_register() for minor %d failed\n", | ||
623 | MISCDEV_MINOR); | ||
624 | goto err_free_priv; | ||
625 | } | ||
626 | |||
627 | /* handle IO resources */ | ||
628 | r = platform_get_resource(dev, IORESOURCE_MEM, 0); | ||
629 | if (r == NULL) { | ||
630 | dev_err(&dev->dev, "no I/O memory resource defined\n"); | ||
631 | ret = -ENODEV; | ||
632 | goto err_misc_deregister; | ||
633 | } | ||
634 | |||
635 | if (!request_mem_region(r->start, resource_size(r), dev->name)) { | ||
636 | dev_err(&dev->dev, "failed to request I/O memory\n"); | ||
637 | ret = -EBUSY; | ||
638 | goto err_misc_deregister; | ||
639 | } | ||
640 | |||
641 | priv->mmio_base = ioremap_nocache(r->start, resource_size(r)); | ||
642 | if (!priv->mmio_base) { | ||
643 | dev_err(&dev->dev, "failed to map I/O memory\n"); | ||
644 | ret = -EBUSY; | ||
645 | goto err_free_mem_region; | ||
646 | } | ||
647 | |||
648 | /* allocate dma memory */ | ||
649 | priv->shared = dma_alloc_coherent(&dev->dev, SHARED_SIZE, | ||
650 | &priv->shared_phys, GFP_KERNEL); | ||
651 | |||
652 | if (!priv->shared) { | ||
653 | dev_err(&dev->dev, "failed to allocate DMA memory\n"); | ||
654 | ret = -ENOMEM; | ||
655 | goto err_free_io; | ||
656 | } | ||
657 | |||
658 | /* enable the clock */ | ||
659 | priv->clk = clk_get(&dev->dev, NULL); | ||
660 | if (IS_ERR(priv->clk)) { | ||
661 | dev_err(&dev->dev, "failed to get clock\n"); | ||
662 | ret = -ENODEV; | ||
663 | goto err_free_dma; | ||
664 | } | ||
665 | |||
666 | ret = clk_enable(priv->clk); | ||
667 | if (ret < 0) { | ||
668 | dev_err(&dev->dev, "failed to enable clock\n"); | ||
669 | goto err_put_clk; | ||
670 | } | ||
671 | |||
672 | /* request the IRQ */ | ||
673 | irq = platform_get_irq(dev, 0); | ||
674 | if (irq < 0) { | ||
675 | dev_err(&dev->dev, "no IRQ defined\n"); | ||
676 | ret = -ENODEV; | ||
677 | goto err_put_clk; | ||
678 | } | ||
679 | |||
680 | ret = request_irq(irq, pxa3xx_gcu_handle_irq, | ||
681 | IRQF_DISABLED, DRV_NAME, priv); | ||
682 | if (ret) { | ||
683 | dev_err(&dev->dev, "request_irq failed\n"); | ||
684 | ret = -EBUSY; | ||
685 | goto err_put_clk; | ||
686 | } | ||
687 | |||
688 | platform_set_drvdata(dev, priv); | ||
689 | priv->resource_mem = r; | ||
690 | pxa3xx_gcu_reset(priv); | ||
691 | pxa3xx_gcu_init_debug_timer(); | ||
692 | |||
693 | dev_info(&dev->dev, "registered @0x%p, DMA 0x%p (%d bytes), IRQ %d\n", | ||
694 | (void *) r->start, (void *) priv->shared_phys, | ||
695 | SHARED_SIZE, irq); | ||
696 | return 0; | ||
697 | |||
698 | err_put_clk: | ||
699 | clk_disable(priv->clk); | ||
700 | clk_put(priv->clk); | ||
701 | |||
702 | err_free_dma: | ||
703 | dma_free_coherent(&dev->dev, SHARED_SIZE, | ||
704 | priv->shared, priv->shared_phys); | ||
705 | |||
706 | err_free_io: | ||
707 | iounmap(priv->mmio_base); | ||
708 | |||
709 | err_free_mem_region: | ||
710 | release_mem_region(r->start, resource_size(r)); | ||
711 | |||
712 | err_misc_deregister: | ||
713 | misc_deregister(&priv->misc_dev); | ||
714 | |||
715 | err_free_priv: | ||
716 | platform_set_drvdata(dev, NULL); | ||
717 | free_buffers(dev, priv); | ||
718 | kfree(priv); | ||
719 | return ret; | ||
720 | } | ||
721 | |||
722 | static int __devexit | ||
723 | pxa3xx_gcu_remove(struct platform_device *dev) | ||
724 | { | ||
725 | struct pxa3xx_gcu_priv *priv = platform_get_drvdata(dev); | ||
726 | struct resource *r = priv->resource_mem; | ||
727 | |||
728 | pxa3xx_gcu_wait_idle(priv); | ||
729 | |||
730 | misc_deregister(&priv->misc_dev); | ||
731 | dma_free_coherent(&dev->dev, SHARED_SIZE, | ||
732 | priv->shared, priv->shared_phys); | ||
733 | iounmap(priv->mmio_base); | ||
734 | release_mem_region(r->start, resource_size(r)); | ||
735 | platform_set_drvdata(dev, NULL); | ||
736 | clk_disable(priv->clk); | ||
737 | free_buffers(dev, priv); | ||
738 | kfree(priv); | ||
739 | |||
740 | return 0; | ||
741 | } | ||
742 | |||
743 | static struct platform_driver pxa3xx_gcu_driver = { | ||
744 | .probe = pxa3xx_gcu_probe, | ||
745 | .remove = __devexit_p(pxa3xx_gcu_remove), | ||
746 | .driver = { | ||
747 | .owner = THIS_MODULE, | ||
748 | .name = DRV_NAME, | ||
749 | }, | ||
750 | }; | ||
751 | |||
752 | static int __init | ||
753 | pxa3xx_gcu_init(void) | ||
754 | { | ||
755 | return platform_driver_register(&pxa3xx_gcu_driver); | ||
756 | } | ||
757 | |||
758 | static void __exit | ||
759 | pxa3xx_gcu_exit(void) | ||
760 | { | ||
761 | platform_driver_unregister(&pxa3xx_gcu_driver); | ||
762 | } | ||
763 | |||
764 | module_init(pxa3xx_gcu_init); | ||
765 | module_exit(pxa3xx_gcu_exit); | ||
766 | |||
767 | MODULE_DESCRIPTION("PXA3xx graphics controller unit driver"); | ||
768 | MODULE_LICENSE("GPL"); | ||
769 | MODULE_ALIAS_MISCDEV(MISCDEV_MINOR); | ||
770 | MODULE_AUTHOR("Janine Kropp <nin@directfb.org>, " | ||
771 | "Denis Oliver Kropp <dok@directfb.org>, " | ||
772 | "Daniel Mack <daniel@caiaq.de>"); | ||
diff --git a/drivers/video/pxa3xx-gcu.h b/drivers/video/pxa3xx-gcu.h new file mode 100644 index 000000000000..0428ed03dc49 --- /dev/null +++ b/drivers/video/pxa3xx-gcu.h | |||
@@ -0,0 +1,38 @@ | |||
1 | #ifndef __PXA3XX_GCU_H__ | ||
2 | #define __PXA3XX_GCU_H__ | ||
3 | |||
4 | #include <linux/types.h> | ||
5 | |||
6 | /* Number of 32bit words in display list (ring buffer). */ | ||
7 | #define PXA3XX_GCU_BUFFER_WORDS ((256 * 1024 - 256) / 4) | ||
8 | |||
9 | /* To be increased when breaking the ABI */ | ||
10 | #define PXA3XX_GCU_SHARED_MAGIC 0x30000001 | ||
11 | |||
12 | #define PXA3XX_GCU_BATCH_WORDS 8192 | ||
13 | |||
14 | struct pxa3xx_gcu_shared { | ||
15 | u32 buffer[PXA3XX_GCU_BUFFER_WORDS]; | ||
16 | |||
17 | bool hw_running; | ||
18 | |||
19 | unsigned long buffer_phys; | ||
20 | |||
21 | unsigned int num_words; | ||
22 | unsigned int num_writes; | ||
23 | unsigned int num_done; | ||
24 | unsigned int num_interrupts; | ||
25 | unsigned int num_wait_idle; | ||
26 | unsigned int num_wait_free; | ||
27 | unsigned int num_idle; | ||
28 | |||
29 | u32 magic; | ||
30 | }; | ||
31 | |||
32 | /* Initialization and synchronization. | ||
33 | * Hardware is started upon write(). */ | ||
34 | #define PXA3XX_GCU_IOCTL_RESET _IO('G', 0) | ||
35 | #define PXA3XX_GCU_IOCTL_WAIT_IDLE _IO('G', 2) | ||
36 | |||
37 | #endif /* __PXA3XX_GCU_H__ */ | ||
38 | |||