diff options
Diffstat (limited to 'drivers/mfd/intel_soc_pmic_bxtwc.c')
-rw-r--r-- | drivers/mfd/intel_soc_pmic_bxtwc.c | 195 |
1 files changed, 120 insertions, 75 deletions
diff --git a/drivers/mfd/intel_soc_pmic_bxtwc.c b/drivers/mfd/intel_soc_pmic_bxtwc.c index 8dac0d41f64f..9d89171d83f9 100644 --- a/drivers/mfd/intel_soc_pmic_bxtwc.c +++ b/drivers/mfd/intel_soc_pmic_bxtwc.c @@ -6,17 +6,27 @@ */ #include <linux/acpi.h> +#include <linux/array_size.h> #include <linux/bits.h> #include <linux/delay.h> +#include <linux/device.h> #include <linux/err.h> +#include <linux/errno.h> +#include <linux/gfp_types.h> #include <linux/interrupt.h> -#include <linux/kernel.h> +#include <linux/ioport.h> +#include <linux/kstrtox.h> #include <linux/mfd/core.h> #include <linux/mfd/intel_soc_pmic.h> #include <linux/mfd/intel_soc_pmic_bxtwc.h> +#include <linux/mod_devicetable.h> #include <linux/module.h> - -#include <asm/intel_scu_ipc.h> +#include <linux/platform_data/x86/intel_scu_ipc.h> +#include <linux/platform_device.h> +#include <linux/pm.h> +#include <linux/regmap.h> +#include <linux/sysfs.h> +#include <linux/types.h> /* PMIC device registers */ #define REG_ADDR_MASK GENMASK(15, 8) @@ -138,7 +148,7 @@ static const struct regmap_irq bxtwc_regmap_irqs_crit[] = { REGMAP_IRQ_REG(BXTWC_CRIT_IRQ, 0, GENMASK(1, 0)), }; -static struct regmap_irq_chip bxtwc_regmap_irq_chip = { +static const struct regmap_irq_chip bxtwc_regmap_irq_chip = { .name = "bxtwc_irq_chip", .status_base = BXTWC_IRQLVL1, .mask_base = BXTWC_MIRQLVL1, @@ -147,8 +157,9 @@ static struct regmap_irq_chip bxtwc_regmap_irq_chip = { .num_regs = 1, }; -static struct regmap_irq_chip bxtwc_regmap_irq_chip_pwrbtn = { +static const struct regmap_irq_chip bxtwc_regmap_irq_chip_pwrbtn = { .name = "bxtwc_irq_chip_pwrbtn", + .domain_suffix = "PWRBTN", .status_base = BXTWC_PWRBTNIRQ, .mask_base = BXTWC_MPWRBTNIRQ, .irqs = bxtwc_regmap_irqs_pwrbtn, @@ -156,8 +167,9 @@ static struct regmap_irq_chip bxtwc_regmap_irq_chip_pwrbtn = { .num_regs = 1, }; -static struct regmap_irq_chip bxtwc_regmap_irq_chip_tmu = { +static const struct regmap_irq_chip bxtwc_regmap_irq_chip_tmu = { .name = "bxtwc_irq_chip_tmu", + .domain_suffix = "TMU", .status_base = BXTWC_TMUIRQ, .mask_base = BXTWC_MTMUIRQ, .irqs = bxtwc_regmap_irqs_tmu, @@ -165,8 +177,9 @@ static struct regmap_irq_chip bxtwc_regmap_irq_chip_tmu = { .num_regs = 1, }; -static struct regmap_irq_chip bxtwc_regmap_irq_chip_bcu = { +static const struct regmap_irq_chip bxtwc_regmap_irq_chip_bcu = { .name = "bxtwc_irq_chip_bcu", + .domain_suffix = "BCU", .status_base = BXTWC_BCUIRQ, .mask_base = BXTWC_MBCUIRQ, .irqs = bxtwc_regmap_irqs_bcu, @@ -174,8 +187,9 @@ static struct regmap_irq_chip bxtwc_regmap_irq_chip_bcu = { .num_regs = 1, }; -static struct regmap_irq_chip bxtwc_regmap_irq_chip_adc = { +static const struct regmap_irq_chip bxtwc_regmap_irq_chip_adc = { .name = "bxtwc_irq_chip_adc", + .domain_suffix = "ADC", .status_base = BXTWC_ADCIRQ, .mask_base = BXTWC_MADCIRQ, .irqs = bxtwc_regmap_irqs_adc, @@ -183,8 +197,9 @@ static struct regmap_irq_chip bxtwc_regmap_irq_chip_adc = { .num_regs = 1, }; -static struct regmap_irq_chip bxtwc_regmap_irq_chip_chgr = { +static const struct regmap_irq_chip bxtwc_regmap_irq_chip_chgr = { .name = "bxtwc_irq_chip_chgr", + .domain_suffix = "CHGR", .status_base = BXTWC_CHGR0IRQ, .mask_base = BXTWC_MCHGR0IRQ, .irqs = bxtwc_regmap_irqs_chgr, @@ -192,8 +207,9 @@ static struct regmap_irq_chip bxtwc_regmap_irq_chip_chgr = { .num_regs = 2, }; -static struct regmap_irq_chip bxtwc_regmap_irq_chip_crit = { +static const struct regmap_irq_chip bxtwc_regmap_irq_chip_crit = { .name = "bxtwc_irq_chip_crit", + .domain_suffix = "CRIT", .status_base = BXTWC_CRITIRQ, .mask_base = BXTWC_MCRITIRQ, .irqs = bxtwc_regmap_irqs_crit, @@ -232,43 +248,54 @@ static const struct resource tmu_resources[] = { static struct mfd_cell bxt_wc_dev[] = { { - .name = "bxt_wcove_gpadc", - .num_resources = ARRAY_SIZE(adc_resources), - .resources = adc_resources, - }, - { .name = "bxt_wcove_thermal", .num_resources = ARRAY_SIZE(thermal_resources), .resources = thermal_resources, }, { - .name = "bxt_wcove_usbc", - .num_resources = ARRAY_SIZE(usbc_resources), - .resources = usbc_resources, + .name = "bxt_wcove_gpio", + .num_resources = ARRAY_SIZE(gpio_resources), + .resources = gpio_resources, }, { - .name = "bxt_wcove_ext_charger", - .num_resources = ARRAY_SIZE(charger_resources), - .resources = charger_resources, + .name = "bxt_wcove_region", + }, +}; + +static const struct mfd_cell bxt_wc_tmu_dev[] = { + { + .name = "bxt_wcove_tmu", + .num_resources = ARRAY_SIZE(tmu_resources), + .resources = tmu_resources, }, +}; + +static const struct mfd_cell bxt_wc_bcu_dev[] = { { .name = "bxt_wcove_bcu", .num_resources = ARRAY_SIZE(bcu_resources), .resources = bcu_resources, }, +}; + +static const struct mfd_cell bxt_wc_adc_dev[] = { { - .name = "bxt_wcove_tmu", - .num_resources = ARRAY_SIZE(tmu_resources), - .resources = tmu_resources, + .name = "bxt_wcove_gpadc", + .num_resources = ARRAY_SIZE(adc_resources), + .resources = adc_resources, }, +}; +static struct mfd_cell bxt_wc_chgr_dev[] = { { - .name = "bxt_wcove_gpio", - .num_resources = ARRAY_SIZE(gpio_resources), - .resources = gpio_resources, + .name = "bxt_wcove_usbc", + .num_resources = ARRAY_SIZE(usbc_resources), + .resources = usbc_resources, }, { - .name = "bxt_wcove_region", + .name = "bxt_wcove_ext_charger", + .num_resources = ARRAY_SIZE(charger_resources), + .resources = charger_resources, }, }; @@ -348,6 +375,7 @@ static ssize_t addr_store(struct device *dev, return count; } +static DEVICE_ATTR_ADMIN_RW(addr); static ssize_t val_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -384,23 +412,14 @@ static ssize_t val_store(struct device *dev, } return count; } - -static DEVICE_ATTR_ADMIN_RW(addr); static DEVICE_ATTR_ADMIN_RW(val); + static struct attribute *bxtwc_attrs[] = { &dev_attr_addr.attr, &dev_attr_val.attr, NULL }; - -static const struct attribute_group bxtwc_group = { - .attrs = bxtwc_attrs, -}; - -static const struct attribute_group *bxtwc_groups[] = { - &bxtwc_group, - NULL -}; +ATTRIBUTE_GROUPS(bxtwc); static const struct regmap_config bxtwc_regmap_config = { .reg_bits = 16, @@ -415,15 +434,39 @@ static int bxtwc_add_chained_irq_chip(struct intel_soc_pmic *pmic, const struct regmap_irq_chip *chip, struct regmap_irq_chip_data **data) { - int irq; + struct device *dev = pmic->dev; + int irq, ret; irq = regmap_irq_get_virq(pdata, pirq); if (irq < 0) - return dev_err_probe(pmic->dev, irq, "Failed to get parent vIRQ(%d) for chip %s\n", + return dev_err_probe(dev, irq, "Failed to get parent vIRQ(%d) for chip %s\n", pirq, chip->name); - return devm_regmap_add_irq_chip(pmic->dev, pmic->regmap, irq, irq_flags, - 0, chip, data); + ret = devm_regmap_add_irq_chip(dev, pmic->regmap, irq, irq_flags, 0, chip, data); + if (ret) + return dev_err_probe(dev, ret, "Failed to add %s IRQ chip\n", chip->name); + + return 0; +} + +static int bxtwc_add_chained_devices(struct intel_soc_pmic *pmic, + const struct mfd_cell *cells, int n_devs, + struct regmap_irq_chip_data *pdata, + int pirq, int irq_flags, + const struct regmap_irq_chip *chip, + struct regmap_irq_chip_data **data) +{ + struct device *dev = pmic->dev; + struct irq_domain *domain; + int ret; + + ret = bxtwc_add_chained_irq_chip(pmic, pdata, pirq, irq_flags, chip, data); + if (ret) + return ret; + + domain = regmap_irq_get_domain(*data); + + return devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE, cells, n_devs, NULL, 0, domain); } static int bxtwc_probe(struct platform_device *pdev) @@ -467,48 +510,49 @@ static int bxtwc_probe(struct platform_device *pdev) if (ret) return dev_err_probe(dev, ret, "Failed to add IRQ chip\n"); + ret = bxtwc_add_chained_devices(pmic, bxt_wc_tmu_dev, ARRAY_SIZE(bxt_wc_tmu_dev), + pmic->irq_chip_data, + BXTWC_TMU_LVL1_IRQ, + IRQF_ONESHOT, + &bxtwc_regmap_irq_chip_tmu, + &pmic->irq_chip_data_tmu); + if (ret) + return ret; + ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data, BXTWC_PWRBTN_LVL1_IRQ, IRQF_ONESHOT, &bxtwc_regmap_irq_chip_pwrbtn, &pmic->irq_chip_data_pwrbtn); if (ret) - return dev_err_probe(dev, ret, "Failed to add PWRBTN IRQ chip\n"); - - ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data, - BXTWC_TMU_LVL1_IRQ, - IRQF_ONESHOT, - &bxtwc_regmap_irq_chip_tmu, - &pmic->irq_chip_data_tmu); - if (ret) - return dev_err_probe(dev, ret, "Failed to add TMU IRQ chip\n"); + return ret; - /* Add chained IRQ handler for BCU IRQs */ - ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data, - BXTWC_BCU_LVL1_IRQ, - IRQF_ONESHOT, - &bxtwc_regmap_irq_chip_bcu, - &pmic->irq_chip_data_bcu); + ret = bxtwc_add_chained_devices(pmic, bxt_wc_bcu_dev, ARRAY_SIZE(bxt_wc_bcu_dev), + pmic->irq_chip_data, + BXTWC_BCU_LVL1_IRQ, + IRQF_ONESHOT, + &bxtwc_regmap_irq_chip_bcu, + &pmic->irq_chip_data_bcu); if (ret) - return dev_err_probe(dev, ret, "Failed to add BUC IRQ chip\n"); + return ret; - /* Add chained IRQ handler for ADC IRQs */ - ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data, - BXTWC_ADC_LVL1_IRQ, - IRQF_ONESHOT, - &bxtwc_regmap_irq_chip_adc, - &pmic->irq_chip_data_adc); + ret = bxtwc_add_chained_devices(pmic, bxt_wc_adc_dev, ARRAY_SIZE(bxt_wc_adc_dev), + pmic->irq_chip_data, + BXTWC_ADC_LVL1_IRQ, + IRQF_ONESHOT, + &bxtwc_regmap_irq_chip_adc, + &pmic->irq_chip_data_adc); if (ret) - return dev_err_probe(dev, ret, "Failed to add ADC IRQ chip\n"); + return ret; - /* Add chained IRQ handler for CHGR IRQs */ - ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data, - BXTWC_CHGR_LVL1_IRQ, - IRQF_ONESHOT, - &bxtwc_regmap_irq_chip_chgr, - &pmic->irq_chip_data_chgr); + ret = bxtwc_add_chained_devices(pmic, bxt_wc_chgr_dev, ARRAY_SIZE(bxt_wc_chgr_dev), + pmic->irq_chip_data, + BXTWC_CHGR_LVL1_IRQ, + IRQF_ONESHOT, + &bxtwc_regmap_irq_chip_chgr, + &pmic->irq_chip_data_chgr); if (ret) - return dev_err_probe(dev, ret, "Failed to add CHGR IRQ chip\n"); + return ret; /* Add chained IRQ handler for CRIT IRQs */ ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data, @@ -517,7 +561,7 @@ static int bxtwc_probe(struct platform_device *pdev) &bxtwc_regmap_irq_chip_crit, &pmic->irq_chip_data_crit); if (ret) - return dev_err_probe(dev, ret, "Failed to add CRIT IRQ chip\n"); + return ret; ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE, bxt_wc_dev, ARRAY_SIZE(bxt_wc_dev), NULL, 0, NULL); @@ -572,7 +616,7 @@ static struct platform_driver bxtwc_driver = { .probe = bxtwc_probe, .shutdown = bxtwc_shutdown, .driver = { - .name = "BXTWC PMIC", + .name = "intel_soc_pmic_bxtwc", .pm = pm_sleep_ptr(&bxtwc_pm_ops), .acpi_match_table = bxtwc_acpi_ids, .dev_groups = bxtwc_groups, @@ -581,5 +625,6 @@ static struct platform_driver bxtwc_driver = { module_platform_driver(bxtwc_driver); +MODULE_DESCRIPTION("Intel Broxton Whiskey Cove PMIC MFD core driver"); MODULE_LICENSE("GPL v2"); MODULE_AUTHOR("Qipeng Zha <qipeng.zha@intel.com>"); |