@@ -129,24 +129,24 @@ static int nic78bx_probe(struct platform_device *pdev)
if (!led_data)
return -ENOMEM;
- led_data->pdev = pdev;
- platform_set_drvdata(pdev, led_data);
-
io_rc = platform_get_resource(pdev, IORESOURCE_IO, 0);
if (!io_rc) {
+ ret = -EINVAL;
dev_err(dev, "missing IO resources\n");
- return -EINVAL;
+ goto err_get_res;
}
if (resource_size(io_rc) < NIC78BX_USER_LED_IO_SIZE) {
dev_err(dev, "IO region too small\n");
- return -EINVAL;
+ ret = -EINVAL;
+ goto err_res_size;
}
if (!devm_request_region(dev, io_rc->start, resource_size(io_rc),
KBUILD_MODNAME)) {
+ ret = -EBUSY;
dev_err(dev, "failed to get IO region\n");
- return -EBUSY;
+ goto err_request_region;
}
led_data->io_base = io_rc->start;
@@ -157,13 +157,27 @@ static int nic78bx_probe(struct platform_device *pdev)
ret = devm_led_classdev_register(dev, &nic78bx_leds[i].cdev);
if (ret)
- return ret;
+ goto err_led_classdev_register;
}
/* Unlock LED register */
outb(NIC78BX_UNLOCK_VALUE,
led_data->io_base + NIC78BX_LOCK_REG_OFFSET);
+ led_data->pdev = pdev;
+ platform_set_drvdata(pdev, led_data);
+ return 0;
+
+err_led_classdev_register:
+ i -= 1;
+ while (i >= 0)
+ devm_led_classdev_unregister(dev, &nic78bx_leds[i--].cdev);
+ devm_release_region(dev, io_rc->start, resource_size(io_rc));
+err_request_region:
+err_res_size:
+ release_resource(io_rc);
+err_get_res:
+ devm_kfree(dev, led_data);
return ret;
}
@@ -171,6 +185,9 @@ static int nic78bx_remove(struct platform_device *pdev)
{
struct nic78bx_led_data *led_data = platform_get_drvdata(pdev);
+ if (IS_ERR_OR_NULL(led_data))
+ return PTR_ERR(led_data);
+
/* Lock LED register */
outb(NIC78BX_LOCK_VALUE,
led_data->io_base + NIC78BX_LOCK_REG_OFFSET);