@@ -136,51 +136,112 @@ static struct osi_linux {
unsigned int known:1;
} osi_linux = { 0, 0, 0, 0};
-static void __init acpi_request_region (struct acpi_generic_address *addr,
+static int __init acpi_request_region(struct acpi_generic_address *addr,
unsigned int length, char *desc)
{
struct resource *res;
if (!addr->address || !length)
- return;
+ return 0;
if (addr->space_id == ACPI_ADR_SPACE_SYSTEM_IO)
res = request_region(addr->address, length, desc);
else if (addr->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY)
res = request_mem_region(addr->address, length, desc);
+ else
+ return 0;
+
+ if (res == NULL)
+ return -ENOMEM;
+ return 0;
}
-static int __init acpi_reserve_resources(void)
+static void __init acpi_release_region(struct acpi_generic_address *addr,
+ unsigned int length)
{
- acpi_request_region(&acpi_gbl_FADT.xpm1a_event_block, acpi_gbl_FADT.pm1_event_length,
- "ACPI PM1a_EVT_BLK");
-
- acpi_request_region(&acpi_gbl_FADT.xpm1b_event_block, acpi_gbl_FADT.pm1_event_length,
- "ACPI PM1b_EVT_BLK");
-
- acpi_request_region(&acpi_gbl_FADT.xpm1a_control_block, acpi_gbl_FADT.pm1_control_length,
- "ACPI PM1a_CNT_BLK");
-
- acpi_request_region(&acpi_gbl_FADT.xpm1b_control_block, acpi_gbl_FADT.pm1_control_length,
- "ACPI PM1b_CNT_BLK");
+ if (addr->space_id == ACPI_ADR_SPACE_SYSTEM_IO)
+ release_region(addr->address, length);
+ else
+ release_mem_region(addr->address, length);
+}
- if (acpi_gbl_FADT.pm_timer_length == 4)
- acpi_request_region(&acpi_gbl_FADT.xpm_timer_block, 4, "ACPI PM_TMR");
+static int __init acpi_reserve_resources(void)
+{
+ int ret;
+ ret = acpi_request_region(&acpi_gbl_FADT.xpm1a_event_block,
+ acpi_gbl_FADT.pm1_event_length, "ACPI PM1a_EVT_BLK");
+ if (ret != 0)
+ return ret;
+
+ ret = acpi_request_region(&acpi_gbl_FADT.xpm1b_event_block,
+ acpi_gbl_FADT.pm1_event_length, "ACPI PM1b_EVT_BLK");
+ if (ret != 0)
+ goto release_xpm1a_eb;
+
+ ret = acpi_request_region(&acpi_gbl_FADT.xpm1a_control_block,
+ acpi_gbl_FADT.pm1_control_length, "ACPI PM1a_CNT_BLK");
+ if (ret != 0)
+ goto release_xpm1b_eb;
+
+ ret = acpi_request_region(&acpi_gbl_FADT.xpm1b_control_block,
+ acpi_gbl_FADT.pm1_control_length, "ACPI PM1b_CNT_BLK");
+ if (ret != 0)
+ goto release_xpm1a_cb;
+
+ if (acpi_gbl_FADT.pm_timer_length == 4) {
+ ret = acpi_request_region(&acpi_gbl_FADT.xpm_timer_block, 4,
+ "ACPI PM_TMR");
+ if (ret != 0)
+ goto release_xpm1b_cb;
+ }
- acpi_request_region(&acpi_gbl_FADT.xpm2_control_block, acpi_gbl_FADT.pm2_control_length,
- "ACPI PM2_CNT_BLK");
+ ret = acpi_request_region(&acpi_gbl_FADT.xpm2_control_block,
+ acpi_gbl_FADT.pm2_control_length, "ACPI PM2_CNT_BLK");
+ if (ret != 0)
+ goto release_xpm_tb;
/* Length of GPE blocks must be a non-negative multiple of 2 */
- if (!(acpi_gbl_FADT.gpe0_block_length & 0x1))
- acpi_request_region(&acpi_gbl_FADT.xgpe0_block,
- acpi_gbl_FADT.gpe0_block_length, "ACPI GPE0_BLK");
-
- if (!(acpi_gbl_FADT.gpe1_block_length & 0x1))
- acpi_request_region(&acpi_gbl_FADT.xgpe1_block,
- acpi_gbl_FADT.gpe1_block_length, "ACPI GPE1_BLK");
+ if (!(acpi_gbl_FADT.gpe0_block_length & 0x1)) {
+ ret = acpi_request_region(&acpi_gbl_FADT.xgpe0_block,
+ acpi_gbl_FADT.gpe0_block_length,
+ "ACPI GPE0_BLK");
+ if (ret != 0)
+ goto release_xpm2_cb;
+ }
+ if (!(acpi_gbl_FADT.gpe1_block_length & 0x1)) {
+ ret = acpi_request_region(&acpi_gbl_FADT.xgpe1_block,
+ acpi_gbl_FADT.gpe1_block_length,
+ "ACPI GPE1_BLK");
+ if (ret != 0)
+ goto release_xgpe0_b;
+ }
return 0;
+
+release_xgpe0_b:
+ if (!(acpi_gbl_FADT.gpe0_block_length & 0x1))
+ acpi_release_region(&acpi_gbl_FADT.xgpe0_block,
+ acpi_gbl_FADT.gpe0_block_length);
+release_xpm2_cb:
+ acpi_release_region(&acpi_gbl_FADT.xpm2_control_block,
+ acpi_gbl_FADT.pm2_control_length);
+release_xpm_tb:
+ if (acpi_gbl_FADT.pm_timer_length == 4)
+ acpi_release_region(&acpi_gbl_FADT.xpm_timer_block, 4);
+release_xpm1b_cb:
+ acpi_release_region(&acpi_gbl_FADT.xpm1b_control_block,
+ acpi_gbl_FADT.pm1_control_length);
+release_xpm1a_cb:
+ acpi_release_region(&acpi_gbl_FADT.xpm1a_control_block,
+ acpi_gbl_FADT.pm1_control_length);
+release_xpm1b_eb:
+ acpi_release_region(&acpi_gbl_FADT.xpm1b_event_block,
+ acpi_gbl_FADT.pm1_event_length);
+release_xpm1a_eb:
+ acpi_release_region(&acpi_gbl_FADT.xpm1a_event_block,
+ acpi_gbl_FADT.pm1_event_length);
+ return ret;
}
device_initcall(acpi_reserve_resources);
request_(mem_)region may fail, clean up and produce an error. Signed-off-by: Roel Kluin <roel.kluin@gmail.com> --- Found with sed: http://kernelnewbies.org/roelkluin build, sparse and checkpatch tested. please review. -- To unsubscribe from this list: send the line "unsubscribe linux-acpi" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html