diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2015-04-08 17:26:21 -0400 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2015-04-08 17:26:21 -0400 |
commit | 462b69b1e43ceccab68a47d65b1e46520cd0fdc0 (patch) | |
tree | 3c961fcb5889c5ab14ab36d8ef7421fc96c95959 /drivers/net/ethernet/ibm/ehea/ehea_main.c | |
parent | d8bf368d0631d4bc2612d8bf2e4e8e74e620d0cc (diff) | |
parent | f22e6e847115abc3a0e2ad7bb18d243d42275af1 (diff) |
Merge branch 'linus' into irq/core to get the GIC updates which
conflict with pending GIC changes.
Conflicts:
drivers/usb/isp1760/isp1760-core.c
Diffstat (limited to 'drivers/net/ethernet/ibm/ehea/ehea_main.c')
-rw-r--r-- | drivers/net/ethernet/ibm/ehea/ehea_main.c | 246 |
1 files changed, 141 insertions, 105 deletions
diff --git a/drivers/net/ethernet/ibm/ehea/ehea_main.c b/drivers/net/ethernet/ibm/ehea/ehea_main.c index e8a1adb7a962..c05e50759621 100644 --- a/drivers/net/ethernet/ibm/ehea/ehea_main.c +++ b/drivers/net/ethernet/ibm/ehea/ehea_main.c | |||
@@ -3262,6 +3262,139 @@ static void ehea_remove_device_sysfs(struct platform_device *dev) | |||
3262 | device_remove_file(&dev->dev, &dev_attr_remove_port); | 3262 | device_remove_file(&dev->dev, &dev_attr_remove_port); |
3263 | } | 3263 | } |
3264 | 3264 | ||
3265 | static int ehea_reboot_notifier(struct notifier_block *nb, | ||
3266 | unsigned long action, void *unused) | ||
3267 | { | ||
3268 | if (action == SYS_RESTART) { | ||
3269 | pr_info("Reboot: freeing all eHEA resources\n"); | ||
3270 | ibmebus_unregister_driver(&ehea_driver); | ||
3271 | } | ||
3272 | return NOTIFY_DONE; | ||
3273 | } | ||
3274 | |||
3275 | static struct notifier_block ehea_reboot_nb = { | ||
3276 | .notifier_call = ehea_reboot_notifier, | ||
3277 | }; | ||
3278 | |||
3279 | static int ehea_mem_notifier(struct notifier_block *nb, | ||
3280 | unsigned long action, void *data) | ||
3281 | { | ||
3282 | int ret = NOTIFY_BAD; | ||
3283 | struct memory_notify *arg = data; | ||
3284 | |||
3285 | mutex_lock(&dlpar_mem_lock); | ||
3286 | |||
3287 | switch (action) { | ||
3288 | case MEM_CANCEL_OFFLINE: | ||
3289 | pr_info("memory offlining canceled"); | ||
3290 | /* Fall through: re-add canceled memory block */ | ||
3291 | |||
3292 | case MEM_ONLINE: | ||
3293 | pr_info("memory is going online"); | ||
3294 | set_bit(__EHEA_STOP_XFER, &ehea_driver_flags); | ||
3295 | if (ehea_add_sect_bmap(arg->start_pfn, arg->nr_pages)) | ||
3296 | goto out_unlock; | ||
3297 | ehea_rereg_mrs(); | ||
3298 | break; | ||
3299 | |||
3300 | case MEM_GOING_OFFLINE: | ||
3301 | pr_info("memory is going offline"); | ||
3302 | set_bit(__EHEA_STOP_XFER, &ehea_driver_flags); | ||
3303 | if (ehea_rem_sect_bmap(arg->start_pfn, arg->nr_pages)) | ||
3304 | goto out_unlock; | ||
3305 | ehea_rereg_mrs(); | ||
3306 | break; | ||
3307 | |||
3308 | default: | ||
3309 | break; | ||
3310 | } | ||
3311 | |||
3312 | ehea_update_firmware_handles(); | ||
3313 | ret = NOTIFY_OK; | ||
3314 | |||
3315 | out_unlock: | ||
3316 | mutex_unlock(&dlpar_mem_lock); | ||
3317 | return ret; | ||
3318 | } | ||
3319 | |||
3320 | static struct notifier_block ehea_mem_nb = { | ||
3321 | .notifier_call = ehea_mem_notifier, | ||
3322 | }; | ||
3323 | |||
3324 | static void ehea_crash_handler(void) | ||
3325 | { | ||
3326 | int i; | ||
3327 | |||
3328 | if (ehea_fw_handles.arr) | ||
3329 | for (i = 0; i < ehea_fw_handles.num_entries; i++) | ||
3330 | ehea_h_free_resource(ehea_fw_handles.arr[i].adh, | ||
3331 | ehea_fw_handles.arr[i].fwh, | ||
3332 | FORCE_FREE); | ||
3333 | |||
3334 | if (ehea_bcmc_regs.arr) | ||
3335 | for (i = 0; i < ehea_bcmc_regs.num_entries; i++) | ||
3336 | ehea_h_reg_dereg_bcmc(ehea_bcmc_regs.arr[i].adh, | ||
3337 | ehea_bcmc_regs.arr[i].port_id, | ||
3338 | ehea_bcmc_regs.arr[i].reg_type, | ||
3339 | ehea_bcmc_regs.arr[i].macaddr, | ||
3340 | 0, H_DEREG_BCMC); | ||
3341 | } | ||
3342 | |||
3343 | static atomic_t ehea_memory_hooks_registered; | ||
3344 | |||
3345 | /* Register memory hooks on probe of first adapter */ | ||
3346 | static int ehea_register_memory_hooks(void) | ||
3347 | { | ||
3348 | int ret = 0; | ||
3349 | |||
3350 | if (atomic_inc_and_test(&ehea_memory_hooks_registered)) | ||
3351 | return 0; | ||
3352 | |||
3353 | ret = ehea_create_busmap(); | ||
3354 | if (ret) { | ||
3355 | pr_info("ehea_create_busmap failed\n"); | ||
3356 | goto out; | ||
3357 | } | ||
3358 | |||
3359 | ret = register_reboot_notifier(&ehea_reboot_nb); | ||
3360 | if (ret) { | ||
3361 | pr_info("register_reboot_notifier failed\n"); | ||
3362 | goto out; | ||
3363 | } | ||
3364 | |||
3365 | ret = register_memory_notifier(&ehea_mem_nb); | ||
3366 | if (ret) { | ||
3367 | pr_info("register_memory_notifier failed\n"); | ||
3368 | goto out2; | ||
3369 | } | ||
3370 | |||
3371 | ret = crash_shutdown_register(ehea_crash_handler); | ||
3372 | if (ret) { | ||
3373 | pr_info("crash_shutdown_register failed\n"); | ||
3374 | goto out3; | ||
3375 | } | ||
3376 | |||
3377 | return 0; | ||
3378 | |||
3379 | out3: | ||
3380 | unregister_memory_notifier(&ehea_mem_nb); | ||
3381 | out2: | ||
3382 | unregister_reboot_notifier(&ehea_reboot_nb); | ||
3383 | out: | ||
3384 | return ret; | ||
3385 | } | ||
3386 | |||
3387 | static void ehea_unregister_memory_hooks(void) | ||
3388 | { | ||
3389 | if (atomic_read(&ehea_memory_hooks_registered)) | ||
3390 | return; | ||
3391 | |||
3392 | unregister_reboot_notifier(&ehea_reboot_nb); | ||
3393 | if (crash_shutdown_unregister(ehea_crash_handler)) | ||
3394 | pr_info("failed unregistering crash handler\n"); | ||
3395 | unregister_memory_notifier(&ehea_mem_nb); | ||
3396 | } | ||
3397 | |||
3265 | static int ehea_probe_adapter(struct platform_device *dev) | 3398 | static int ehea_probe_adapter(struct platform_device *dev) |
3266 | { | 3399 | { |
3267 | struct ehea_adapter *adapter; | 3400 | struct ehea_adapter *adapter; |
@@ -3269,6 +3402,10 @@ static int ehea_probe_adapter(struct platform_device *dev) | |||
3269 | int ret; | 3402 | int ret; |
3270 | int i; | 3403 | int i; |
3271 | 3404 | ||
3405 | ret = ehea_register_memory_hooks(); | ||
3406 | if (ret) | ||
3407 | return ret; | ||
3408 | |||
3272 | if (!dev || !dev->dev.of_node) { | 3409 | if (!dev || !dev->dev.of_node) { |
3273 | pr_err("Invalid ibmebus device probed\n"); | 3410 | pr_err("Invalid ibmebus device probed\n"); |
3274 | return -EINVAL; | 3411 | return -EINVAL; |
@@ -3392,81 +3529,6 @@ static int ehea_remove(struct platform_device *dev) | |||
3392 | return 0; | 3529 | return 0; |
3393 | } | 3530 | } |
3394 | 3531 | ||
3395 | static void ehea_crash_handler(void) | ||
3396 | { | ||
3397 | int i; | ||
3398 | |||
3399 | if (ehea_fw_handles.arr) | ||
3400 | for (i = 0; i < ehea_fw_handles.num_entries; i++) | ||
3401 | ehea_h_free_resource(ehea_fw_handles.arr[i].adh, | ||
3402 | ehea_fw_handles.arr[i].fwh, | ||
3403 | FORCE_FREE); | ||
3404 | |||
3405 | if (ehea_bcmc_regs.arr) | ||
3406 | for (i = 0; i < ehea_bcmc_regs.num_entries; i++) | ||
3407 | ehea_h_reg_dereg_bcmc(ehea_bcmc_regs.arr[i].adh, | ||
3408 | ehea_bcmc_regs.arr[i].port_id, | ||
3409 | ehea_bcmc_regs.arr[i].reg_type, | ||
3410 | ehea_bcmc_regs.arr[i].macaddr, | ||
3411 | 0, H_DEREG_BCMC); | ||
3412 | } | ||
3413 | |||
3414 | static int ehea_mem_notifier(struct notifier_block *nb, | ||
3415 | unsigned long action, void *data) | ||
3416 | { | ||
3417 | int ret = NOTIFY_BAD; | ||
3418 | struct memory_notify *arg = data; | ||
3419 | |||
3420 | mutex_lock(&dlpar_mem_lock); | ||
3421 | |||
3422 | switch (action) { | ||
3423 | case MEM_CANCEL_OFFLINE: | ||
3424 | pr_info("memory offlining canceled"); | ||
3425 | /* Readd canceled memory block */ | ||
3426 | case MEM_ONLINE: | ||
3427 | pr_info("memory is going online"); | ||
3428 | set_bit(__EHEA_STOP_XFER, &ehea_driver_flags); | ||
3429 | if (ehea_add_sect_bmap(arg->start_pfn, arg->nr_pages)) | ||
3430 | goto out_unlock; | ||
3431 | ehea_rereg_mrs(); | ||
3432 | break; | ||
3433 | case MEM_GOING_OFFLINE: | ||
3434 | pr_info("memory is going offline"); | ||
3435 | set_bit(__EHEA_STOP_XFER, &ehea_driver_flags); | ||
3436 | if (ehea_rem_sect_bmap(arg->start_pfn, arg->nr_pages)) | ||
3437 | goto out_unlock; | ||
3438 | ehea_rereg_mrs(); | ||
3439 | break; | ||
3440 | default: | ||
3441 | break; | ||
3442 | } | ||
3443 | |||
3444 | ehea_update_firmware_handles(); | ||
3445 | ret = NOTIFY_OK; | ||
3446 | |||
3447 | out_unlock: | ||
3448 | mutex_unlock(&dlpar_mem_lock); | ||
3449 | return ret; | ||
3450 | } | ||
3451 | |||
3452 | static struct notifier_block ehea_mem_nb = { | ||
3453 | .notifier_call = ehea_mem_notifier, | ||
3454 | }; | ||
3455 | |||
3456 | static int ehea_reboot_notifier(struct notifier_block *nb, | ||
3457 | unsigned long action, void *unused) | ||
3458 | { | ||
3459 | if (action == SYS_RESTART) { | ||
3460 | pr_info("Reboot: freeing all eHEA resources\n"); | ||
3461 | ibmebus_unregister_driver(&ehea_driver); | ||
3462 | } | ||
3463 | return NOTIFY_DONE; | ||
3464 | } | ||
3465 | |||
3466 | static struct notifier_block ehea_reboot_nb = { | ||
3467 | .notifier_call = ehea_reboot_notifier, | ||
3468 | }; | ||
3469 | |||
3470 | static int check_module_parm(void) | 3532 | static int check_module_parm(void) |
3471 | { | 3533 | { |
3472 | int ret = 0; | 3534 | int ret = 0; |
@@ -3520,26 +3582,10 @@ static int __init ehea_module_init(void) | |||
3520 | if (ret) | 3582 | if (ret) |
3521 | goto out; | 3583 | goto out; |
3522 | 3584 | ||
3523 | ret = ehea_create_busmap(); | ||
3524 | if (ret) | ||
3525 | goto out; | ||
3526 | |||
3527 | ret = register_reboot_notifier(&ehea_reboot_nb); | ||
3528 | if (ret) | ||
3529 | pr_info("failed registering reboot notifier\n"); | ||
3530 | |||
3531 | ret = register_memory_notifier(&ehea_mem_nb); | ||
3532 | if (ret) | ||
3533 | pr_info("failed registering memory remove notifier\n"); | ||
3534 | |||
3535 | ret = crash_shutdown_register(ehea_crash_handler); | ||
3536 | if (ret) | ||
3537 | pr_info("failed registering crash handler\n"); | ||
3538 | |||
3539 | ret = ibmebus_register_driver(&ehea_driver); | 3585 | ret = ibmebus_register_driver(&ehea_driver); |
3540 | if (ret) { | 3586 | if (ret) { |
3541 | pr_err("failed registering eHEA device driver on ebus\n"); | 3587 | pr_err("failed registering eHEA device driver on ebus\n"); |
3542 | goto out2; | 3588 | goto out; |
3543 | } | 3589 | } |
3544 | 3590 | ||
3545 | ret = driver_create_file(&ehea_driver.driver, | 3591 | ret = driver_create_file(&ehea_driver.driver, |
@@ -3547,32 +3593,22 @@ static int __init ehea_module_init(void) | |||
3547 | if (ret) { | 3593 | if (ret) { |
3548 | pr_err("failed to register capabilities attribute, ret=%d\n", | 3594 | pr_err("failed to register capabilities attribute, ret=%d\n", |
3549 | ret); | 3595 | ret); |
3550 | goto out3; | 3596 | goto out2; |
3551 | } | 3597 | } |
3552 | 3598 | ||
3553 | return ret; | 3599 | return ret; |
3554 | 3600 | ||
3555 | out3: | ||
3556 | ibmebus_unregister_driver(&ehea_driver); | ||
3557 | out2: | 3601 | out2: |
3558 | unregister_memory_notifier(&ehea_mem_nb); | 3602 | ibmebus_unregister_driver(&ehea_driver); |
3559 | unregister_reboot_notifier(&ehea_reboot_nb); | ||
3560 | crash_shutdown_unregister(ehea_crash_handler); | ||
3561 | out: | 3603 | out: |
3562 | return ret; | 3604 | return ret; |
3563 | } | 3605 | } |
3564 | 3606 | ||
3565 | static void __exit ehea_module_exit(void) | 3607 | static void __exit ehea_module_exit(void) |
3566 | { | 3608 | { |
3567 | int ret; | ||
3568 | |||
3569 | driver_remove_file(&ehea_driver.driver, &driver_attr_capabilities); | 3609 | driver_remove_file(&ehea_driver.driver, &driver_attr_capabilities); |
3570 | ibmebus_unregister_driver(&ehea_driver); | 3610 | ibmebus_unregister_driver(&ehea_driver); |
3571 | unregister_reboot_notifier(&ehea_reboot_nb); | 3611 | ehea_unregister_memory_hooks(); |
3572 | ret = crash_shutdown_unregister(ehea_crash_handler); | ||
3573 | if (ret) | ||
3574 | pr_info("failed unregistering crash handler\n"); | ||
3575 | unregister_memory_notifier(&ehea_mem_nb); | ||
3576 | kfree(ehea_fw_handles.arr); | 3612 | kfree(ehea_fw_handles.arr); |
3577 | kfree(ehea_bcmc_regs.arr); | 3613 | kfree(ehea_bcmc_regs.arr); |
3578 | ehea_destroy_busmap(); | 3614 | ehea_destroy_busmap(); |