Messages in this thread | | | From | "Yang, Fei" <> | Subject | RE: [PATCH] mfd: add Intel Broxton Whiskey Cove PMIC driver | Date | Wed, 29 Apr 2015 16:55:31 +0000 |
| |
> +/* Whiskey Cove PMIC share same ACPI ID between different platforms */ > +#define BROXTON_PMIC_WC_HRV 4 > +static int bxtwc_probe(struct platform_device *pdev) { > + int ret; > + struct resource *res; > + struct intel_soc_pmic *pmic; > + acpi_status status; > + unsigned long long hrv; > + acpi_handle handle = ACPI_HANDLE(&pdev->dev); > + > + status = acpi_evaluate_integer(handle, "_HRV", NULL, &hrv); > + if (ACPI_FAILURE(status)) { > + dev_err(&pdev->dev, "ACPI error when get _HRV\n"); > + return -ENODEV; > + } > + if (hrv != BROXTON_PMIC_WC_HRV) { > + dev_err(&pdev->dev, "Wrong _HRV %llu\n", hrv); > + return -ENODEV; > + } > + > + res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); > + if (!res) { > + dev_err(&pdev->dev, "No irq resource?\n"); > + return -ENOENT; > + } > + > + pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL); > + if (!pmic) > + return -ENOMEM; > + > + dev_set_drvdata(&pdev->dev, pmic); > + pmic->irq = res->start; > + pmic->dev = &pdev->dev; > + pmic->default_i2c_addr = BXTWC_DEVICE1_ADDR; > + > + pmic->regmap = devm_regmap_init_pmic_ipc(pmic, &bxtwc_regmap_config); > + if (IS_ERR(pmic->regmap)) { > + ret = PTR_ERR(pmic->regmap); > + dev_err(&pdev->dev, "Fail to init pmic ipc regmap: %d\n", ret); > + return ret; > + } > + > + ret = regmap_add_irq_chip(pmic->regmap, pmic->irq, > + IRQF_ONESHOT | IRQF_SHARED, > + 0, &bxtwc_regmap_irq_chip, > + &pmic->irq_chip_data); > + if (ret) { > + dev_err(&pdev->dev, "Fail to add irq chip\n"); > + goto err_irq_chip; > + }
I ran into a kernel panic in regmap_exit in case the above regmap_add_irq_chip call failed. I don't see other PMIC drivers is calling regmap_exit, can you investigate if that is necessary?
> +err_irq_chip: > + regmap_exit(pmic->regmap); > + > + return ret; > +} > + > +static int bxtwc_remove(struct platform_device *pdev) { > + struct intel_soc_pmic *pmic = dev_get_drvdata(&pdev->dev); > + > + sysfs_remove_group(&pdev->dev.kobj, &bxtwc_group); > + mfd_remove_devices(&pdev->dev); > + regmap_del_irq_chip(pmic->irq, pmic->irq_chip_data); > + regmap_del_irq_chip(pmic->irq, pmic->irq_chip_data_level2); > + regmap_exit(pmic->regmap);
Please investigate if regmap_exit call is necessary.
> + return 0;
| |