diff options
-rw-r--r-- | drivers/staging/unisys/visorbus/visorchipset.c | 68 |
1 files changed, 40 insertions, 28 deletions
diff --git a/drivers/staging/unisys/visorbus/visorchipset.c b/drivers/staging/unisys/visorbus/visorchipset.c index afcd29135a68..0583b515171a 100644 --- a/drivers/staging/unisys/visorbus/visorchipset.c +++ b/drivers/staging/unisys/visorbus/visorchipset.c | |||
@@ -2290,16 +2290,25 @@ visorchipset_file_init(dev_t major_dev, struct visorchannel **controlvm_channel) | |||
2290 | return 0; | 2290 | return 0; |
2291 | } | 2291 | } |
2292 | 2292 | ||
2293 | static void | ||
2294 | visorchipset_file_cleanup(dev_t major_dev) | ||
2295 | { | ||
2296 | if (file_cdev.ops) | ||
2297 | cdev_del(&file_cdev); | ||
2298 | file_cdev.ops = NULL; | ||
2299 | unregister_chrdev_region(major_dev, 1); | ||
2300 | } | ||
2301 | |||
2293 | static int | 2302 | static int |
2294 | visorchipset_init(struct acpi_device *acpi_device) | 2303 | visorchipset_init(struct acpi_device *acpi_device) |
2295 | { | 2304 | { |
2296 | int rc = 0; | 2305 | int err = -ENODEV; |
2297 | u64 addr; | 2306 | u64 addr; |
2298 | uuid_le uuid = SPAR_CONTROLVM_CHANNEL_PROTOCOL_UUID; | 2307 | uuid_le uuid = SPAR_CONTROLVM_CHANNEL_PROTOCOL_UUID; |
2299 | 2308 | ||
2300 | addr = controlvm_get_channel_address(); | 2309 | addr = controlvm_get_channel_address(); |
2301 | if (!addr) | 2310 | if (!addr) |
2302 | return -ENODEV; | 2311 | goto error; |
2303 | 2312 | ||
2304 | memset(&busdev_notifiers, 0, sizeof(busdev_notifiers)); | 2313 | memset(&busdev_notifiers, 0, sizeof(busdev_notifiers)); |
2305 | memset(&controlvm_payload_info, 0, sizeof(controlvm_payload_info)); | 2314 | memset(&controlvm_payload_info, 0, sizeof(controlvm_payload_info)); |
@@ -2307,22 +2316,19 @@ visorchipset_init(struct acpi_device *acpi_device) | |||
2307 | controlvm_channel = visorchannel_create_with_lock(addr, 0, | 2316 | controlvm_channel = visorchannel_create_with_lock(addr, 0, |
2308 | GFP_KERNEL, uuid); | 2317 | GFP_KERNEL, uuid); |
2309 | if (!controlvm_channel) | 2318 | if (!controlvm_channel) |
2310 | return -ENODEV; | 2319 | goto error; |
2320 | |||
2311 | if (SPAR_CONTROLVM_CHANNEL_OK_CLIENT( | 2321 | if (SPAR_CONTROLVM_CHANNEL_OK_CLIENT( |
2312 | visorchannel_get_header(controlvm_channel))) { | 2322 | visorchannel_get_header(controlvm_channel))) { |
2313 | initialize_controlvm_payload(); | 2323 | initialize_controlvm_payload(); |
2314 | } else { | 2324 | } else { |
2315 | visorchannel_destroy(controlvm_channel); | 2325 | goto error_destroy_channel; |
2316 | controlvm_channel = NULL; | ||
2317 | return -ENODEV; | ||
2318 | } | 2326 | } |
2319 | 2327 | ||
2320 | major_dev = MKDEV(visorchipset_major, 0); | 2328 | major_dev = MKDEV(visorchipset_major, 0); |
2321 | rc = visorchipset_file_init(major_dev, &controlvm_channel); | 2329 | err = visorchipset_file_init(major_dev, &controlvm_channel); |
2322 | if (rc < 0) { | 2330 | if (err < 0) |
2323 | POSTCODE_LINUX_2(CHIPSET_INIT_FAILURE_PC, DIAG_SEVERITY_ERR); | 2331 | goto error_destroy_payload; |
2324 | goto cleanup; | ||
2325 | } | ||
2326 | 2332 | ||
2327 | memset(&g_chipset_msg_hdr, 0, sizeof(struct controlvm_message_header)); | 2333 | memset(&g_chipset_msg_hdr, 0, sizeof(struct controlvm_message_header)); |
2328 | 2334 | ||
@@ -2341,27 +2347,33 @@ visorchipset_init(struct acpi_device *acpi_device) | |||
2341 | visorchipset_platform_device.dev.devt = major_dev; | 2347 | visorchipset_platform_device.dev.devt = major_dev; |
2342 | if (platform_device_register(&visorchipset_platform_device) < 0) { | 2348 | if (platform_device_register(&visorchipset_platform_device) < 0) { |
2343 | POSTCODE_LINUX_2(DEVICE_REGISTER_FAILURE_PC, DIAG_SEVERITY_ERR); | 2349 | POSTCODE_LINUX_2(DEVICE_REGISTER_FAILURE_PC, DIAG_SEVERITY_ERR); |
2344 | rc = -ENODEV; | 2350 | err = -ENODEV; |
2345 | goto cleanup; | 2351 | goto error_cancel_work; |
2346 | } | 2352 | } |
2347 | POSTCODE_LINUX_2(CHIPSET_INIT_SUCCESS_PC, POSTCODE_SEVERITY_INFO); | 2353 | POSTCODE_LINUX_2(CHIPSET_INIT_SUCCESS_PC, POSTCODE_SEVERITY_INFO); |
2348 | 2354 | ||
2349 | rc = visorbus_init(); | 2355 | err = visorbus_init(); |
2350 | cleanup: | 2356 | if (err < 0) |
2351 | if (rc) { | 2357 | goto error_unregister; |
2352 | POSTCODE_LINUX_3(CHIPSET_INIT_FAILURE_PC, rc, | ||
2353 | POSTCODE_SEVERITY_ERR); | ||
2354 | } | ||
2355 | return rc; | ||
2356 | } | ||
2357 | 2358 | ||
2358 | static void | 2359 | return 0; |
2359 | visorchipset_file_cleanup(dev_t major_dev) | 2360 | |
2360 | { | 2361 | error_unregister: |
2361 | if (file_cdev.ops) | 2362 | platform_device_unregister(&visorchipset_platform_device); |
2362 | cdev_del(&file_cdev); | 2363 | |
2363 | file_cdev.ops = NULL; | 2364 | error_cancel_work: |
2364 | unregister_chrdev_region(major_dev, 1); | 2365 | cancel_delayed_work_sync(&periodic_controlvm_work); |
2366 | visorchipset_file_cleanup(major_dev); | ||
2367 | |||
2368 | error_destroy_payload: | ||
2369 | destroy_controlvm_payload_info(&controlvm_payload_info); | ||
2370 | |||
2371 | error_destroy_channel: | ||
2372 | visorchannel_destroy(controlvm_channel); | ||
2373 | |||
2374 | error: | ||
2375 | POSTCODE_LINUX_3(CHIPSET_INIT_FAILURE_PC, err, POSTCODE_SEVERITY_ERR); | ||
2376 | return err; | ||
2365 | } | 2377 | } |
2366 | 2378 | ||
2367 | static int | 2379 | static int |