diff options
author | Linus Walleij <linus.walleij@linaro.org> | 2016-11-19 16:15:18 +0100 |
---|---|---|
committer | Lee Jones <lee.jones@linaro.org> | 2016-11-21 13:54:28 +0100 |
commit | 40a3a0f2ba633fa219f69aef0fd0dcdd6e5756b0 (patch) | |
tree | b45701d72461e0b2e5ad977479c40566519d37b9 /drivers/mfd/pm8921-core.c | |
parent | Linux 4.9-rc1 (diff) | |
download | linux-40a3a0f2ba633fa219f69aef0fd0dcdd6e5756b0.tar.xz linux-40a3a0f2ba633fa219f69aef0fd0dcdd6e5756b0.zip |
mfd: qcom-pm8xxx: Clean up PM8XXX namespace
The Kconfig and file naming for the PM8xxx driver is totally
confusing:
- Kconfig options MFD_PM8XXX and MFD_PM8921_CORE, some in-kernel
users depending on or selecting either at random.
- A driver file named pm8921-core.c even if it is indeed
used by the whole PM8xxx family of chips.
- An irqchip named pm8xxx since it was (I guess) realized that
the driver was generic for all pm8xxx PMICs.
As I may want to add support for PM8901 this is starting to get
really messy. Fix this situation by:
- Remove the MFD_PM8921_CORE symbol and rely solely on MFD_PM8XXX
and convert all users, including LEDs Kconfig and ARM defconfigs
for qcom and multi_v7 to use that single symbol.
- Renaming the driver to qcom-pm8xxx.c to fit along the two
other qcom* prefixed drivers.
- Rename functions withing the driver from 8921 to 8xxx to
indicate it is generic.
- Just drop the =m config from the pxa_defconfig, I have no clue
why it is even there, it is not a Qualcomm platform. (Possibly
older Kconfig noise from saveconfig.)
Cc: Stephen Boyd <sboyd@codeaurora.org>
Cc: Neil Armstrong <narmstrong@baylibre.com>
Cc: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Reviewed-by: Andy Gross <andy.gross@linaro.org>
Acked-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Acked-by: Jacek Anaszewski <j.anaszewski@samsung.com>
Acked-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
Diffstat (limited to 'drivers/mfd/pm8921-core.c')
-rw-r--r-- | drivers/mfd/pm8921-core.c | 429 |
1 files changed, 0 insertions, 429 deletions
diff --git a/drivers/mfd/pm8921-core.c b/drivers/mfd/pm8921-core.c deleted file mode 100644 index 0e3a2ea25942..000000000000 --- a/drivers/mfd/pm8921-core.c +++ /dev/null @@ -1,429 +0,0 @@ -/* - * Copyright (c) 2011, Code Aurora Forum. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#define pr_fmt(fmt) "%s: " fmt, __func__ - -#include <linux/kernel.h> -#include <linux/interrupt.h> -#include <linux/irqchip/chained_irq.h> -#include <linux/irq.h> -#include <linux/irqdomain.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/slab.h> -#include <linux/err.h> -#include <linux/ssbi.h> -#include <linux/regmap.h> -#include <linux/of_platform.h> -#include <linux/mfd/core.h> - -#define SSBI_REG_ADDR_IRQ_BASE 0x1BB - -#define SSBI_REG_ADDR_IRQ_ROOT (SSBI_REG_ADDR_IRQ_BASE + 0) -#define SSBI_REG_ADDR_IRQ_M_STATUS1 (SSBI_REG_ADDR_IRQ_BASE + 1) -#define SSBI_REG_ADDR_IRQ_M_STATUS2 (SSBI_REG_ADDR_IRQ_BASE + 2) -#define SSBI_REG_ADDR_IRQ_M_STATUS3 (SSBI_REG_ADDR_IRQ_BASE + 3) -#define SSBI_REG_ADDR_IRQ_M_STATUS4 (SSBI_REG_ADDR_IRQ_BASE + 4) -#define SSBI_REG_ADDR_IRQ_BLK_SEL (SSBI_REG_ADDR_IRQ_BASE + 5) -#define SSBI_REG_ADDR_IRQ_IT_STATUS (SSBI_REG_ADDR_IRQ_BASE + 6) -#define SSBI_REG_ADDR_IRQ_CONFIG (SSBI_REG_ADDR_IRQ_BASE + 7) -#define SSBI_REG_ADDR_IRQ_RT_STATUS (SSBI_REG_ADDR_IRQ_BASE + 8) - -#define PM_IRQF_LVL_SEL 0x01 /* level select */ -#define PM_IRQF_MASK_FE 0x02 /* mask falling edge */ -#define PM_IRQF_MASK_RE 0x04 /* mask rising edge */ -#define PM_IRQF_CLR 0x08 /* clear interrupt */ -#define PM_IRQF_BITS_MASK 0x70 -#define PM_IRQF_BITS_SHIFT 4 -#define PM_IRQF_WRITE 0x80 - -#define PM_IRQF_MASK_ALL (PM_IRQF_MASK_FE | \ - PM_IRQF_MASK_RE) - -#define REG_HWREV 0x002 /* PMIC4 revision */ -#define REG_HWREV_2 0x0E8 /* PMIC4 revision 2 */ - -#define PM8921_NR_IRQS 256 - -struct pm_irq_chip { - struct regmap *regmap; - spinlock_t pm_irq_lock; - struct irq_domain *irqdomain; - unsigned int num_irqs; - unsigned int num_blocks; - unsigned int num_masters; - u8 config[0]; -}; - -static int pm8xxx_read_block_irq(struct pm_irq_chip *chip, unsigned int bp, - unsigned int *ip) -{ - int rc; - - spin_lock(&chip->pm_irq_lock); - rc = regmap_write(chip->regmap, SSBI_REG_ADDR_IRQ_BLK_SEL, bp); - if (rc) { - pr_err("Failed Selecting Block %d rc=%d\n", bp, rc); - goto bail; - } - - rc = regmap_read(chip->regmap, SSBI_REG_ADDR_IRQ_IT_STATUS, ip); - if (rc) - pr_err("Failed Reading Status rc=%d\n", rc); -bail: - spin_unlock(&chip->pm_irq_lock); - return rc; -} - -static int -pm8xxx_config_irq(struct pm_irq_chip *chip, unsigned int bp, unsigned int cp) -{ - int rc; - - spin_lock(&chip->pm_irq_lock); - rc = regmap_write(chip->regmap, SSBI_REG_ADDR_IRQ_BLK_SEL, bp); - if (rc) { - pr_err("Failed Selecting Block %d rc=%d\n", bp, rc); - goto bail; - } - - cp |= PM_IRQF_WRITE; - rc = regmap_write(chip->regmap, SSBI_REG_ADDR_IRQ_CONFIG, cp); - if (rc) - pr_err("Failed Configuring IRQ rc=%d\n", rc); -bail: - spin_unlock(&chip->pm_irq_lock); - return rc; -} - -static int pm8xxx_irq_block_handler(struct pm_irq_chip *chip, int block) -{ - int pmirq, irq, i, ret = 0; - unsigned int bits; - - ret = pm8xxx_read_block_irq(chip, block, &bits); - if (ret) { - pr_err("Failed reading %d block ret=%d", block, ret); - return ret; - } - if (!bits) { - pr_err("block bit set in master but no irqs: %d", block); - return 0; - } - - /* Check IRQ bits */ - for (i = 0; i < 8; i++) { - if (bits & (1 << i)) { - pmirq = block * 8 + i; - irq = irq_find_mapping(chip->irqdomain, pmirq); - generic_handle_irq(irq); - } - } - return 0; -} - -static int pm8xxx_irq_master_handler(struct pm_irq_chip *chip, int master) -{ - unsigned int blockbits; - int block_number, i, ret = 0; - - ret = regmap_read(chip->regmap, SSBI_REG_ADDR_IRQ_M_STATUS1 + master, - &blockbits); - if (ret) { - pr_err("Failed to read master %d ret=%d\n", master, ret); - return ret; - } - if (!blockbits) { - pr_err("master bit set in root but no blocks: %d", master); - return 0; - } - - for (i = 0; i < 8; i++) - if (blockbits & (1 << i)) { - block_number = master * 8 + i; /* block # */ - ret |= pm8xxx_irq_block_handler(chip, block_number); - } - return ret; -} - -static void pm8xxx_irq_handler(struct irq_desc *desc) -{ - struct pm_irq_chip *chip = irq_desc_get_handler_data(desc); - struct irq_chip *irq_chip = irq_desc_get_chip(desc); - unsigned int root; - int i, ret, masters = 0; - - chained_irq_enter(irq_chip, desc); - - ret = regmap_read(chip->regmap, SSBI_REG_ADDR_IRQ_ROOT, &root); - if (ret) { - pr_err("Can't read root status ret=%d\n", ret); - return; - } - - /* on pm8xxx series masters start from bit 1 of the root */ - masters = root >> 1; - - /* Read allowed masters for blocks. */ - for (i = 0; i < chip->num_masters; i++) - if (masters & (1 << i)) - pm8xxx_irq_master_handler(chip, i); - - chained_irq_exit(irq_chip, desc); -} - -static void pm8xxx_irq_mask_ack(struct irq_data *d) -{ - struct pm_irq_chip *chip = irq_data_get_irq_chip_data(d); - unsigned int pmirq = irqd_to_hwirq(d); - u8 block, config; - - block = pmirq / 8; - - config = chip->config[pmirq] | PM_IRQF_MASK_ALL | PM_IRQF_CLR; - pm8xxx_config_irq(chip, block, config); -} - -static void pm8xxx_irq_unmask(struct irq_data *d) -{ - struct pm_irq_chip *chip = irq_data_get_irq_chip_data(d); - unsigned int pmirq = irqd_to_hwirq(d); - u8 block, config; - - block = pmirq / 8; - - config = chip->config[pmirq]; - pm8xxx_config_irq(chip, block, config); -} - -static int pm8xxx_irq_set_type(struct irq_data *d, unsigned int flow_type) -{ - struct pm_irq_chip *chip = irq_data_get_irq_chip_data(d); - unsigned int pmirq = irqd_to_hwirq(d); - int irq_bit; - u8 block, config; - - block = pmirq / 8; - irq_bit = pmirq % 8; - - chip->config[pmirq] = (irq_bit << PM_IRQF_BITS_SHIFT) - | PM_IRQF_MASK_ALL; - if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) { - if (flow_type & IRQF_TRIGGER_RISING) - chip->config[pmirq] &= ~PM_IRQF_MASK_RE; - if (flow_type & IRQF_TRIGGER_FALLING) - chip->config[pmirq] &= ~PM_IRQF_MASK_FE; - } else { - chip->config[pmirq] |= PM_IRQF_LVL_SEL; - - if (flow_type & IRQF_TRIGGER_HIGH) - chip->config[pmirq] &= ~PM_IRQF_MASK_RE; - else - chip->config[pmirq] &= ~PM_IRQF_MASK_FE; - } - - config = chip->config[pmirq] | PM_IRQF_CLR; - return pm8xxx_config_irq(chip, block, config); -} - -static int pm8xxx_irq_get_irqchip_state(struct irq_data *d, - enum irqchip_irq_state which, - bool *state) -{ - struct pm_irq_chip *chip = irq_data_get_irq_chip_data(d); - unsigned int pmirq = irqd_to_hwirq(d); - unsigned int bits; - int irq_bit; - u8 block; - int rc; - - if (which != IRQCHIP_STATE_LINE_LEVEL) - return -EINVAL; - - block = pmirq / 8; - irq_bit = pmirq % 8; - - spin_lock(&chip->pm_irq_lock); - rc = regmap_write(chip->regmap, SSBI_REG_ADDR_IRQ_BLK_SEL, block); - if (rc) { - pr_err("Failed Selecting Block %d rc=%d\n", block, rc); - goto bail; - } - - rc = regmap_read(chip->regmap, SSBI_REG_ADDR_IRQ_RT_STATUS, &bits); - if (rc) { - pr_err("Failed Reading Status rc=%d\n", rc); - goto bail; - } - - *state = !!(bits & BIT(irq_bit)); -bail: - spin_unlock(&chip->pm_irq_lock); - - return rc; -} - -static struct irq_chip pm8xxx_irq_chip = { - .name = "pm8xxx", - .irq_mask_ack = pm8xxx_irq_mask_ack, - .irq_unmask = pm8xxx_irq_unmask, - .irq_set_type = pm8xxx_irq_set_type, - .irq_get_irqchip_state = pm8xxx_irq_get_irqchip_state, - .flags = IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_SKIP_SET_WAKE, -}; - -static int pm8xxx_irq_domain_map(struct irq_domain *d, unsigned int irq, - irq_hw_number_t hwirq) -{ - struct pm_irq_chip *chip = d->host_data; - - irq_set_chip_and_handler(irq, &pm8xxx_irq_chip, handle_level_irq); - irq_set_chip_data(irq, chip); - irq_set_noprobe(irq); - - return 0; -} - -static const struct irq_domain_ops pm8xxx_irq_domain_ops = { - .xlate = irq_domain_xlate_twocell, - .map = pm8xxx_irq_domain_map, -}; - -static const struct regmap_config ssbi_regmap_config = { - .reg_bits = 16, - .val_bits = 8, - .max_register = 0x3ff, - .fast_io = true, - .reg_read = ssbi_reg_read, - .reg_write = ssbi_reg_write -}; - -static const struct of_device_id pm8921_id_table[] = { - { .compatible = "qcom,pm8018", }, - { .compatible = "qcom,pm8058", }, - { .compatible = "qcom,pm8921", }, - { } -}; -MODULE_DEVICE_TABLE(of, pm8921_id_table); - -static int pm8921_probe(struct platform_device *pdev) -{ - struct regmap *regmap; - int irq, rc; - unsigned int val; - u32 rev; - struct pm_irq_chip *chip; - unsigned int nirqs = PM8921_NR_IRQS; - - irq = platform_get_irq(pdev, 0); - if (irq < 0) - return irq; - - regmap = devm_regmap_init(&pdev->dev, NULL, pdev->dev.parent, - &ssbi_regmap_config); - if (IS_ERR(regmap)) - return PTR_ERR(regmap); - - /* Read PMIC chip revision */ - rc = regmap_read(regmap, REG_HWREV, &val); - if (rc) { - pr_err("Failed to read hw rev reg %d:rc=%d\n", REG_HWREV, rc); - return rc; - } - pr_info("PMIC revision 1: %02X\n", val); - rev = val; - - /* Read PMIC chip revision 2 */ - rc = regmap_read(regmap, REG_HWREV_2, &val); - if (rc) { - pr_err("Failed to read hw rev 2 reg %d:rc=%d\n", - REG_HWREV_2, rc); - return rc; - } - pr_info("PMIC revision 2: %02X\n", val); - rev |= val << BITS_PER_BYTE; - - chip = devm_kzalloc(&pdev->dev, sizeof(*chip) + - sizeof(chip->config[0]) * nirqs, - GFP_KERNEL); - if (!chip) - return -ENOMEM; - - platform_set_drvdata(pdev, chip); - chip->regmap = regmap; - chip->num_irqs = nirqs; - chip->num_blocks = DIV_ROUND_UP(chip->num_irqs, 8); - chip->num_masters = DIV_ROUND_UP(chip->num_blocks, 8); - spin_lock_init(&chip->pm_irq_lock); - - chip->irqdomain = irq_domain_add_linear(pdev->dev.of_node, nirqs, - &pm8xxx_irq_domain_ops, - chip); - if (!chip->irqdomain) - return -ENODEV; - - irq_set_chained_handler_and_data(irq, pm8xxx_irq_handler, chip); - irq_set_irq_wake(irq, 1); - - rc = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev); - if (rc) { - irq_set_chained_handler_and_data(irq, NULL, NULL); - irq_domain_remove(chip->irqdomain); - } - - return rc; -} - -static int pm8921_remove_child(struct device *dev, void *unused) -{ - platform_device_unregister(to_platform_device(dev)); - return 0; -} - -static int pm8921_remove(struct platform_device *pdev) -{ - int irq = platform_get_irq(pdev, 0); - struct pm_irq_chip *chip = platform_get_drvdata(pdev); - - device_for_each_child(&pdev->dev, NULL, pm8921_remove_child); - irq_set_chained_handler_and_data(irq, NULL, NULL); - irq_domain_remove(chip->irqdomain); - - return 0; -} - -static struct platform_driver pm8921_driver = { - .probe = pm8921_probe, - .remove = pm8921_remove, - .driver = { - .name = "pm8921-core", - .of_match_table = pm8921_id_table, - }, -}; - -static int __init pm8921_init(void) -{ - return platform_driver_register(&pm8921_driver); -} -subsys_initcall(pm8921_init); - -static void __exit pm8921_exit(void) -{ - platform_driver_unregister(&pm8921_driver); -} -module_exit(pm8921_exit); - -MODULE_LICENSE("GPL v2"); -MODULE_DESCRIPTION("PMIC 8921 core driver"); -MODULE_VERSION("1.0"); -MODULE_ALIAS("platform:pm8921-core"); |