Lines Matching refs:ghes
46 #include <acpi/ghes.h>
97 static inline bool is_hest_type_generic_v2(struct ghes *ghes)
99 return ghes->generic->header.type == ACPI_HEST_TYPE_GENERIC_ERROR_V2;
109 static inline bool is_hest_sync_notify(struct ghes *ghes)
111 u8 notify_type = ghes->generic->notify.type;
212 static int map_gen_v2(struct ghes *ghes)
214 return apei_map_generic_address(&ghes->generic_v2->read_ack_register);
217 static void unmap_gen_v2(struct ghes *ghes)
219 apei_unmap_generic_address(&ghes->generic_v2->read_ack_register);
237 static struct ghes *ghes_new(struct acpi_hest_generic *generic)
239 struct ghes *ghes;
243 ghes = kzalloc(sizeof(*ghes), GFP_KERNEL);
244 if (!ghes)
247 ghes->generic = generic;
248 if (is_hest_type_generic_v2(ghes)) {
249 rc = map_gen_v2(ghes);
265 ghes->estatus = kmalloc(error_block_length, GFP_KERNEL);
266 if (!ghes->estatus) {
271 return ghes;
276 if (is_hest_type_generic_v2(ghes))
277 unmap_gen_v2(ghes);
279 kfree(ghes);
283 static void ghes_fini(struct ghes *ghes)
285 kfree(ghes->estatus);
286 apei_unmap_generic_address(&ghes->generic->error_status_address);
287 if (is_hest_type_generic_v2(ghes))
288 unmap_gen_v2(ghes);
333 static int __ghes_check_estatus(struct ghes *ghes,
343 if (len > ghes->generic->error_block_length) {
357 static int __ghes_peek_estatus(struct ghes *ghes,
361 struct acpi_hest_generic *g = ghes->generic;
399 static int ghes_read_estatus(struct ghes *ghes,
405 rc = __ghes_peek_estatus(ghes, estatus, buf_paddr, fixmap_idx);
409 rc = __ghes_check_estatus(ghes, estatus);
417 static void ghes_clear_estatus(struct ghes *ghes,
434 if (is_hest_type_generic_v2(ghes))
435 ghes_ack_error(ghes->generic_v2);
641 static bool ghes_do_proc(struct ghes *ghes,
650 bool sync = is_hest_sync_notify(ghes);
857 static void __ghes_panic(struct ghes *ghes,
861 __ghes_print_estatus(KERN_EMERG, ghes->generic, estatus);
863 ghes_clear_estatus(ghes, estatus, buf_paddr, fixmap_idx);
871 static int ghes_proc(struct ghes *ghes)
873 struct acpi_hest_generic_status *estatus = ghes->estatus;
877 rc = ghes_read_estatus(ghes, estatus, &buf_paddr, FIX_APEI_GHES_IRQ);
882 __ghes_panic(ghes, estatus, buf_paddr, FIX_APEI_GHES_IRQ);
885 if (ghes_print_estatus(NULL, ghes->generic, estatus))
886 ghes_estatus_cache_add(ghes->generic, estatus);
888 ghes_do_proc(ghes, estatus);
891 ghes_clear_estatus(ghes, estatus, buf_paddr, FIX_APEI_GHES_IRQ);
896 static void ghes_add_timer(struct ghes *ghes)
898 struct acpi_hest_generic *g = ghes->generic;
907 ghes->timer.expires = round_jiffies_relative(expire);
908 add_timer(&ghes->timer);
913 struct ghes *ghes = from_timer(ghes, t, timer);
917 ghes_proc(ghes);
919 if (!(ghes->flags & GHES_EXITING))
920 ghes_add_timer(ghes);
925 struct ghes *ghes = data;
930 rc = ghes_proc(ghes);
941 struct ghes *ghes;
947 list_for_each_entry_rcu(ghes, &ghes_hed, list) {
948 if (!ghes_proc(ghes))
998 task_work_pending = ghes_do_proc(estatus_node->ghes, estatus);
1045 static int ghes_in_nmi_queue_one_entry(struct ghes *ghes,
1057 rc = __ghes_peek_estatus(ghes, &tmp_header, &buf_paddr, fixmap_idx);
1059 ghes_clear_estatus(ghes, &tmp_header, buf_paddr, fixmap_idx);
1063 rc = __ghes_check_estatus(ghes, &tmp_header);
1065 ghes_clear_estatus(ghes, &tmp_header, buf_paddr, fixmap_idx);
1075 estatus_node->ghes = ghes;
1076 estatus_node->generic = ghes->generic;
1081 ghes_clear_estatus(ghes, estatus, buf_paddr, fixmap_idx);
1089 __ghes_panic(ghes, estatus, buf_paddr, fixmap_idx);
1092 ghes_clear_estatus(ghes, &tmp_header, buf_paddr, fixmap_idx);
1113 struct ghes *ghes;
1116 list_for_each_entry_rcu(ghes, rcu_list, list) {
1117 if (!ghes_in_nmi_queue_one_entry(ghes, fixmap_idx))
1147 static void ghes_sea_add(struct ghes *ghes)
1150 list_add_rcu(&ghes->list, &ghes_sea);
1154 static void ghes_sea_remove(struct ghes *ghes)
1157 list_del_rcu(&ghes->list);
1162 static inline void ghes_sea_add(struct ghes *ghes) { }
1163 static inline void ghes_sea_remove(struct ghes *ghes) { }
1192 static void ghes_nmi_add(struct ghes *ghes)
1196 register_nmi_handler(NMI_LOCAL, ghes_notify_nmi, 0, "ghes");
1197 list_add_rcu(&ghes->list, &ghes_nmi);
1201 static void ghes_nmi_remove(struct ghes *ghes)
1204 list_del_rcu(&ghes->list);
1206 unregister_nmi_handler(NMI_LOCAL, "ghes");
1209 * To synchronize with NMI handler, ghes can only be
1215 static inline void ghes_nmi_add(struct ghes *ghes) { }
1216 static inline void ghes_nmi_remove(struct ghes *ghes) { }
1224 static int __ghes_sdei_callback(struct ghes *ghes,
1227 if (!ghes_in_nmi_queue_one_entry(ghes, fixmap_idx)) {
1240 struct ghes *ghes = arg;
1244 err = __ghes_sdei_callback(ghes, FIX_APEI_GHES_SDEI_NORMAL);
1254 struct ghes *ghes = arg;
1258 err = __ghes_sdei_callback(ghes, FIX_APEI_GHES_SDEI_CRITICAL);
1264 static int apei_sdei_register_ghes(struct ghes *ghes)
1269 return sdei_register_ghes(ghes, ghes_sdei_normal_callback,
1273 static int apei_sdei_unregister_ghes(struct ghes *ghes)
1278 return sdei_unregister_ghes(ghes);
1284 struct ghes *ghes = NULL;
1340 ghes = ghes_new(generic);
1341 if (IS_ERR(ghes)) {
1342 rc = PTR_ERR(ghes);
1343 ghes = NULL;
1349 timer_setup(&ghes->timer, ghes_poll_func, 0);
1350 ghes_add_timer(ghes);
1354 rc = acpi_gsi_to_irq(generic->notify.vector, &ghes->irq);
1360 rc = request_irq(ghes->irq, ghes_irq_func, IRQF_SHARED,
1361 "GHES IRQ", ghes);
1375 list_add_rcu(&ghes->list, &ghes_hed);
1380 ghes_sea_add(ghes);
1383 ghes_nmi_add(ghes);
1386 rc = apei_sdei_register_ghes(ghes);
1394 platform_set_drvdata(ghes_dev, ghes);
1396 ghes_edac_register(ghes, &ghes_dev->dev);
1400 ghes_proc(ghes);
1406 if (ghes) {
1407 ghes_fini(ghes);
1408 kfree(ghes);
1416 struct ghes *ghes;
1419 ghes = platform_get_drvdata(ghes_dev);
1420 generic = ghes->generic;
1422 ghes->flags |= GHES_EXITING;
1425 del_timer_sync(&ghes->timer);
1428 free_irq(ghes->irq, ghes);
1435 list_del_rcu(&ghes->list);
1443 ghes_sea_remove(ghes);
1446 ghes_nmi_remove(ghes);
1449 rc = apei_sdei_unregister_ghes(ghes);
1458 ghes_fini(ghes);
1460 ghes_edac_unregister(ghes);
1462 kfree(ghes);