OLD | NEW |
1 /* | 1 /* |
2 * This file is part of the flashrom project. | 2 * This file is part of the flashrom project. |
3 * | 3 * |
4 * Copyright (C) 2000 Silicon Integrated System Corporation | 4 * Copyright (C) 2000 Silicon Integrated System Corporation |
5 * Copyright (C) 2004 Tyan Corp <yhlu@tyan.com> | 5 * Copyright (C) 2004 Tyan Corp <yhlu@tyan.com> |
6 * Copyright (C) 2005-2008 coresystems GmbH | 6 * Copyright (C) 2005-2008 coresystems GmbH |
7 * Copyright (C) 2008,2009 Carl-Daniel Hailfinger | 7 * Copyright (C) 2008,2009 Carl-Daniel Hailfinger |
8 * | 8 * |
9 * This program is free software; you can redistribute it and/or modify | 9 * This program is free software; you can redistribute it and/or modify |
10 * it under the terms of the GNU General Public License as published by | 10 * it under the terms of the GNU General Public License as published by |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
117 unsigned long flashbase; | 117 unsigned long flashbase; |
118 | 118 |
119 /* Is writing allowed with this programmer? */ | 119 /* Is writing allowed with this programmer? */ |
120 int programmer_may_write; | 120 int programmer_may_write; |
121 | 121 |
122 const struct programmer_entry programmer_table[] = { | 122 const struct programmer_entry programmer_table[] = { |
123 #if CONFIG_INTERNAL == 1 | 123 #if CONFIG_INTERNAL == 1 |
124 { | 124 { |
125 .name = "internal", | 125 .name = "internal", |
126 .init = internal_init, | 126 .init = internal_init, |
| 127 /* called implicitly using shutdown callback */ |
127 .shutdown = internal_shutdown, | 128 .shutdown = internal_shutdown, |
128 .map_flash_region = physmap, | 129 .map_flash_region = physmap, |
129 .unmap_flash_region = physunmap, | 130 .unmap_flash_region = physunmap, |
130 .chip_readb = internal_chip_readb, | 131 .chip_readb = internal_chip_readb, |
131 .chip_readw = internal_chip_readw, | 132 .chip_readw = internal_chip_readw, |
132 .chip_readl = internal_chip_readl, | 133 .chip_readl = internal_chip_readl, |
133 .chip_readn = internal_chip_readn, | 134 .chip_readn = internal_chip_readn, |
134 .chip_writeb = internal_chip_writeb, | 135 .chip_writeb = internal_chip_writeb, |
135 .chip_writew = internal_chip_writew, | 136 .chip_writew = internal_chip_writew, |
136 .chip_writel = internal_chip_writel, | 137 .chip_writel = internal_chip_writel, |
(...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
477 static int shutdown_fn_count = 0; | 478 static int shutdown_fn_count = 0; |
478 struct shutdown_func_data { | 479 struct shutdown_func_data { |
479 void (*func) (void *data); | 480 void (*func) (void *data); |
480 void *data; | 481 void *data; |
481 } static shutdown_fn[SHUTDOWN_MAXFN]; | 482 } static shutdown_fn[SHUTDOWN_MAXFN]; |
482 /* Initialize to 0 to make sure nobody registers a shutdown function before | 483 /* Initialize to 0 to make sure nobody registers a shutdown function before |
483 * programmer init. | 484 * programmer init. |
484 */ | 485 */ |
485 static int may_register_shutdown = 0; | 486 static int may_register_shutdown = 0; |
486 | 487 |
| 488 static int programmer_shutdown_done = 0; |
| 489 |
487 /* Register a function to be executed on programmer shutdown. | 490 /* Register a function to be executed on programmer shutdown. |
488 * The advantage over atexit() is that you can supply a void pointer which will | 491 * The advantage over atexit() is that you can supply a void pointer which will |
489 * be used as parameter to the registered function upon programmer shutdown. | 492 * be used as parameter to the registered function upon programmer shutdown. |
490 * This pointer can point to arbitrary data used by said function, e.g. undo | 493 * This pointer can point to arbitrary data used by said function, e.g. undo |
491 * information for GPIO settings etc. If unneeded, set data=NULL. | 494 * information for GPIO settings etc. If unneeded, set data=NULL. |
492 * Please note that the first (void *data) belongs to the function signature of | 495 * Please note that the first (void *data) belongs to the function signature of |
493 * the function passed as first parameter. | 496 * the function passed as first parameter. |
494 */ | 497 */ |
495 int register_shutdown(void (*function) (void *data), void *data) | 498 int register_shutdown(void (*function) (void *data), void *data) |
496 { | 499 { |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
570 int i = --chip_restore_fn_count; | 573 int i = --chip_restore_fn_count; |
571 rc |= chip_restore_fn[i].func(chip_restore_fn[i].flash, | 574 rc |= chip_restore_fn[i].func(chip_restore_fn[i].flash, |
572 chip_restore_fn[i].status); | 575 chip_restore_fn[i].status); |
573 } | 576 } |
574 | 577 |
575 return rc; | 578 return rc; |
576 } | 579 } |
577 | 580 |
578 int programmer_shutdown(void) | 581 int programmer_shutdown(void) |
579 { | 582 { |
| 583 if (programmer_shutdown_done) { |
| 584 msg_gdbg("%s: shutdown has already been done\n", __func__); |
| 585 return -1; |
| 586 } |
| 587 |
| 588 msg_gdbg("%s: carrying out %d shutdown callbacks\n", |
| 589 __func__, shutdown_fn_count); |
| 590 |
580 /* Registering shutdown functions is no longer allowed. */ | 591 /* Registering shutdown functions is no longer allowed. */ |
581 may_register_shutdown = 0; | 592 may_register_shutdown = 0; |
582 while (shutdown_fn_count > 0) { | 593 while (shutdown_fn_count > 0) { |
583 int i = --shutdown_fn_count; | 594 int i = --shutdown_fn_count; |
584 shutdown_fn[i].func(shutdown_fn[i].data); | 595 shutdown_fn[i].func(shutdown_fn[i].data); |
585 } | 596 } |
586 return programmer_table[programmer].shutdown(); | 597 return programmer_table[programmer].shutdown(); |
587 } | 598 } |
588 | 599 |
589 void *programmer_map_flash_region(const char *descr, unsigned long phys_addr, | 600 void *programmer_map_flash_region(const char *descr, unsigned long phys_addr, |
(...skipping 1418 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2008 out_nofree: | 2019 out_nofree: |
2009 chip_restore(); /* must be done before programmer_shutdown() */ | 2020 chip_restore(); /* must be done before programmer_shutdown() */ |
2010 /* | 2021 /* |
2011 * programmer_shutdown() call is moved to cli_mfg() in chromium os | 2022 * programmer_shutdown() call is moved to cli_mfg() in chromium os |
2012 * tree. This is because some operations, such as write protection, | 2023 * tree. This is because some operations, such as write protection, |
2013 * requires programmer_shutdown() but does not call doit(). | 2024 * requires programmer_shutdown() but does not call doit(). |
2014 */ | 2025 */ |
2015 // programmer_shutdown(); | 2026 // programmer_shutdown(); |
2016 return ret; | 2027 return ret; |
2017 } | 2028 } |
OLD | NEW |