brintos

brintos / linux-shallow public Read only

0
0
Text · 15.6 KiB · 8b6285f Raw
621 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Copyright (c) 2011, Code Aurora Forum. All rights reserved.4 */5 6#define pr_fmt(fmt) "%s: " fmt, __func__7 8#include <linux/kernel.h>9#include <linux/interrupt.h>10#include <linux/irqchip/chained_irq.h>11#include <linux/irq.h>12#include <linux/irqdomain.h>13#include <linux/module.h>14#include <linux/platform_device.h>15#include <linux/slab.h>16#include <linux/err.h>17#include <linux/ssbi.h>18#include <linux/regmap.h>19#include <linux/of_platform.h>20#include <linux/mfd/core.h>21 22#define	SSBI_REG_ADDR_IRQ_BASE		0x1BB23 24#define	SSBI_REG_ADDR_IRQ_ROOT		(SSBI_REG_ADDR_IRQ_BASE + 0)25#define	SSBI_REG_ADDR_IRQ_M_STATUS1	(SSBI_REG_ADDR_IRQ_BASE + 1)26#define	SSBI_REG_ADDR_IRQ_M_STATUS2	(SSBI_REG_ADDR_IRQ_BASE + 2)27#define	SSBI_REG_ADDR_IRQ_M_STATUS3	(SSBI_REG_ADDR_IRQ_BASE + 3)28#define	SSBI_REG_ADDR_IRQ_M_STATUS4	(SSBI_REG_ADDR_IRQ_BASE + 4)29#define	SSBI_REG_ADDR_IRQ_BLK_SEL	(SSBI_REG_ADDR_IRQ_BASE + 5)30#define	SSBI_REG_ADDR_IRQ_IT_STATUS	(SSBI_REG_ADDR_IRQ_BASE + 6)31#define	SSBI_REG_ADDR_IRQ_CONFIG	(SSBI_REG_ADDR_IRQ_BASE + 7)32#define	SSBI_REG_ADDR_IRQ_RT_STATUS	(SSBI_REG_ADDR_IRQ_BASE + 8)33 34#define	PM8821_SSBI_REG_ADDR_IRQ_BASE	0x10035#define	PM8821_SSBI_REG_ADDR_IRQ_MASTER0 (PM8821_SSBI_REG_ADDR_IRQ_BASE + 0x30)36#define	PM8821_SSBI_REG_ADDR_IRQ_MASTER1 (PM8821_SSBI_REG_ADDR_IRQ_BASE + 0xb0)37#define	PM8821_SSBI_REG(m, b, offset) \38			((m == 0) ? \39			(PM8821_SSBI_REG_ADDR_IRQ_MASTER0 + b + offset) : \40			(PM8821_SSBI_REG_ADDR_IRQ_MASTER1 + b + offset))41#define	PM8821_SSBI_ADDR_IRQ_ROOT(m, b)		PM8821_SSBI_REG(m, b, 0x0)42#define	PM8821_SSBI_ADDR_IRQ_CLEAR(m, b)	PM8821_SSBI_REG(m, b, 0x01)43#define	PM8821_SSBI_ADDR_IRQ_MASK(m, b)		PM8821_SSBI_REG(m, b, 0x08)44#define	PM8821_SSBI_ADDR_IRQ_RT_STATUS(m, b)	PM8821_SSBI_REG(m, b, 0x0f)45 46#define	PM8821_BLOCKS_PER_MASTER	747 48#define	PM_IRQF_LVL_SEL			0x01	/* level select */49#define	PM_IRQF_MASK_FE			0x02	/* mask falling edge */50#define	PM_IRQF_MASK_RE			0x04	/* mask rising edge */51#define	PM_IRQF_CLR			0x08	/* clear interrupt */52#define	PM_IRQF_BITS_MASK		0x7053#define	PM_IRQF_BITS_SHIFT		454#define	PM_IRQF_WRITE			0x8055 56#define	PM_IRQF_MASK_ALL		(PM_IRQF_MASK_FE | \57					PM_IRQF_MASK_RE)58 59#define REG_HWREV		0x002  /* PMIC4 revision */60#define REG_HWREV_2		0x0E8  /* PMIC4 revision 2 */61 62#define PM8XXX_NR_IRQS		25663#define PM8821_NR_IRQS		11264 65struct pm_irq_data {66	int num_irqs;67	struct irq_chip *irq_chip;68	irq_handler_t irq_handler;69};70 71struct pm_irq_chip {72	struct regmap		*regmap;73	spinlock_t		pm_irq_lock;74	struct irq_domain	*irqdomain;75	unsigned int		num_blocks;76	unsigned int		num_masters;77	const struct pm_irq_data *pm_irq_data;78	/* MUST BE AT THE END OF THIS STRUCT */79	u8			config[];80};81 82static int pm8xxx_read_block_irq(struct pm_irq_chip *chip, unsigned int bp,83				 unsigned int *ip)84{85	int	rc;86 87	spin_lock(&chip->pm_irq_lock);88	rc = regmap_write(chip->regmap, SSBI_REG_ADDR_IRQ_BLK_SEL, bp);89	if (rc) {90		pr_err("Failed Selecting Block %d rc=%d\n", bp, rc);91		goto bail;92	}93 94	rc = regmap_read(chip->regmap, SSBI_REG_ADDR_IRQ_IT_STATUS, ip);95	if (rc)96		pr_err("Failed Reading Status rc=%d\n", rc);97bail:98	spin_unlock(&chip->pm_irq_lock);99	return rc;100}101 102static int103pm8xxx_config_irq(struct pm_irq_chip *chip, unsigned int bp, unsigned int cp)104{105	int	rc;106	unsigned long flags;107 108	spin_lock_irqsave(&chip->pm_irq_lock, flags);109	rc = regmap_write(chip->regmap, SSBI_REG_ADDR_IRQ_BLK_SEL, bp);110	if (rc) {111		pr_err("Failed Selecting Block %d rc=%d\n", bp, rc);112		goto bail;113	}114 115	cp |= PM_IRQF_WRITE;116	rc = regmap_write(chip->regmap, SSBI_REG_ADDR_IRQ_CONFIG, cp);117	if (rc)118		pr_err("Failed Configuring IRQ rc=%d\n", rc);119bail:120	spin_unlock_irqrestore(&chip->pm_irq_lock, flags);121	return rc;122}123 124static int pm8xxx_irq_block_handler(struct pm_irq_chip *chip, int block)125{126	int pmirq, i, ret = 0;127	unsigned int bits;128 129	ret = pm8xxx_read_block_irq(chip, block, &bits);130	if (ret) {131		pr_err("Failed reading %d block ret=%d", block, ret);132		return ret;133	}134	if (!bits) {135		pr_err("block bit set in master but no irqs: %d", block);136		return 0;137	}138 139	/* Check IRQ bits */140	for (i = 0; i < 8; i++) {141		if (bits & (1 << i)) {142			pmirq = block * 8 + i;143			generic_handle_domain_irq(chip->irqdomain, pmirq);144		}145	}146	return 0;147}148 149static int pm8xxx_irq_master_handler(struct pm_irq_chip *chip, int master)150{151	unsigned int blockbits;152	int block_number, i, ret = 0;153 154	ret = regmap_read(chip->regmap, SSBI_REG_ADDR_IRQ_M_STATUS1 + master,155			  &blockbits);156	if (ret) {157		pr_err("Failed to read master %d ret=%d\n", master, ret);158		return ret;159	}160	if (!blockbits) {161		pr_err("master bit set in root but no blocks: %d", master);162		return 0;163	}164 165	for (i = 0; i < 8; i++)166		if (blockbits & (1 << i)) {167			block_number = master * 8 + i;	/* block # */168			ret |= pm8xxx_irq_block_handler(chip, block_number);169		}170	return ret;171}172 173static irqreturn_t pm8xxx_irq_handler(int irq, void *data)174{175	struct pm_irq_chip *chip = data;176	unsigned int root;177	int	i, ret, masters = 0;178 179	ret = regmap_read(chip->regmap, SSBI_REG_ADDR_IRQ_ROOT, &root);180	if (ret) {181		pr_err("Can't read root status ret=%d\n", ret);182		return IRQ_NONE;183	}184 185	/* on pm8xxx series masters start from bit 1 of the root */186	masters = root >> 1;187 188	/* Read allowed masters for blocks. */189	for (i = 0; i < chip->num_masters; i++)190		if (masters & (1 << i))191			pm8xxx_irq_master_handler(chip, i);192 193	return IRQ_HANDLED;194}195 196static void pm8821_irq_block_handler(struct pm_irq_chip *chip,197				     int master, int block)198{199	int pmirq, i, ret;200	unsigned int bits;201 202	ret = regmap_read(chip->regmap,203			  PM8821_SSBI_ADDR_IRQ_ROOT(master, block), &bits);204	if (ret) {205		pr_err("Reading block %d failed ret=%d", block, ret);206		return;207	}208 209	/* Convert block offset to global block number */210	block += (master * PM8821_BLOCKS_PER_MASTER) - 1;211 212	/* Check IRQ bits */213	for (i = 0; i < 8; i++) {214		if (bits & BIT(i)) {215			pmirq = block * 8 + i;216			generic_handle_domain_irq(chip->irqdomain, pmirq);217		}218	}219}220 221static inline void pm8821_irq_master_handler(struct pm_irq_chip *chip,222					     int master, u8 master_val)223{224	int block;225 226	for (block = 1; block < 8; block++)227		if (master_val & BIT(block))228			pm8821_irq_block_handler(chip, master, block);229}230 231static irqreturn_t pm8821_irq_handler(int irq, void *data)232{233	struct pm_irq_chip *chip = data;234	unsigned int master;235	int ret;236 237	ret = regmap_read(chip->regmap,238			  PM8821_SSBI_REG_ADDR_IRQ_MASTER0, &master);239	if (ret) {240		pr_err("Failed to read master 0 ret=%d\n", ret);241		return IRQ_NONE;242	}243 244	/* bits 1 through 7 marks the first 7 blocks in master 0 */245	if (master & GENMASK(7, 1))246		pm8821_irq_master_handler(chip, 0, master);247 248	/* bit 0 marks if master 1 contains any bits */249	if (!(master & BIT(0)))250		return IRQ_NONE;251 252	ret = regmap_read(chip->regmap,253			  PM8821_SSBI_REG_ADDR_IRQ_MASTER1, &master);254	if (ret) {255		pr_err("Failed to read master 1 ret=%d\n", ret);256		return IRQ_NONE;257	}258 259	pm8821_irq_master_handler(chip, 1, master);260 261	return IRQ_HANDLED;262}263 264static void pm8xxx_irq_mask_ack(struct irq_data *d)265{266	struct pm_irq_chip *chip = irq_data_get_irq_chip_data(d);267	unsigned int pmirq = irqd_to_hwirq(d);268	u8	block, config;269 270	block = pmirq / 8;271 272	config = chip->config[pmirq] | PM_IRQF_MASK_ALL | PM_IRQF_CLR;273	pm8xxx_config_irq(chip, block, config);274}275 276static void pm8xxx_irq_unmask(struct irq_data *d)277{278	struct pm_irq_chip *chip = irq_data_get_irq_chip_data(d);279	unsigned int pmirq = irqd_to_hwirq(d);280	u8	block, config;281 282	block = pmirq / 8;283 284	config = chip->config[pmirq];285	pm8xxx_config_irq(chip, block, config);286}287 288static int pm8xxx_irq_set_type(struct irq_data *d, unsigned int flow_type)289{290	struct pm_irq_chip *chip = irq_data_get_irq_chip_data(d);291	unsigned int pmirq = irqd_to_hwirq(d);292	int irq_bit;293	u8 block, config;294 295	block = pmirq / 8;296	irq_bit  = pmirq % 8;297 298	chip->config[pmirq] = (irq_bit << PM_IRQF_BITS_SHIFT)299							| PM_IRQF_MASK_ALL;300	if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) {301		if (flow_type & IRQF_TRIGGER_RISING)302			chip->config[pmirq] &= ~PM_IRQF_MASK_RE;303		if (flow_type & IRQF_TRIGGER_FALLING)304			chip->config[pmirq] &= ~PM_IRQF_MASK_FE;305	} else {306		chip->config[pmirq] |= PM_IRQF_LVL_SEL;307 308		if (flow_type & IRQF_TRIGGER_HIGH)309			chip->config[pmirq] &= ~PM_IRQF_MASK_RE;310		else311			chip->config[pmirq] &= ~PM_IRQF_MASK_FE;312	}313 314	config = chip->config[pmirq] | PM_IRQF_CLR;315	return pm8xxx_config_irq(chip, block, config);316}317 318static int pm8xxx_irq_get_irqchip_state(struct irq_data *d,319					enum irqchip_irq_state which,320					bool *state)321{322	struct pm_irq_chip *chip = irq_data_get_irq_chip_data(d);323	unsigned int pmirq = irqd_to_hwirq(d);324	unsigned int bits;325	unsigned long flags;326	int irq_bit;327	u8 block;328	int rc;329 330	if (which != IRQCHIP_STATE_LINE_LEVEL)331		return -EINVAL;332 333	block = pmirq / 8;334	irq_bit = pmirq % 8;335 336	spin_lock_irqsave(&chip->pm_irq_lock, flags);337	rc = regmap_write(chip->regmap, SSBI_REG_ADDR_IRQ_BLK_SEL, block);338	if (rc) {339		pr_err("Failed Selecting Block %d rc=%d\n", block, rc);340		goto bail;341	}342 343	rc = regmap_read(chip->regmap, SSBI_REG_ADDR_IRQ_RT_STATUS, &bits);344	if (rc) {345		pr_err("Failed Reading Status rc=%d\n", rc);346		goto bail;347	}348 349	*state = !!(bits & BIT(irq_bit));350bail:351	spin_unlock_irqrestore(&chip->pm_irq_lock, flags);352 353	return rc;354}355 356static struct irq_chip pm8xxx_irq_chip = {357	.name		= "pm8xxx",358	.irq_mask_ack	= pm8xxx_irq_mask_ack,359	.irq_unmask	= pm8xxx_irq_unmask,360	.irq_set_type	= pm8xxx_irq_set_type,361	.irq_get_irqchip_state = pm8xxx_irq_get_irqchip_state,362	.flags		= IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_SKIP_SET_WAKE,363};364 365static void pm8xxx_irq_domain_map(struct pm_irq_chip *chip,366				  struct irq_domain *domain, unsigned int irq,367				  irq_hw_number_t hwirq, unsigned int type)368{369	irq_domain_set_info(domain, irq, hwirq, chip->pm_irq_data->irq_chip,370			    chip, handle_level_irq, NULL, NULL);371	irq_set_noprobe(irq);372}373 374static int pm8xxx_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,375				   unsigned int nr_irqs, void *data)376{377	struct pm_irq_chip *chip = domain->host_data;378	struct irq_fwspec *fwspec = data;379	irq_hw_number_t hwirq;380	unsigned int type;381	int ret, i;382 383	ret = irq_domain_translate_twocell(domain, fwspec, &hwirq, &type);384	if (ret)385		return ret;386 387	for (i = 0; i < nr_irqs; i++)388		pm8xxx_irq_domain_map(chip, domain, virq + i, hwirq + i, type);389 390	return 0;391}392 393static const struct irq_domain_ops pm8xxx_irq_domain_ops = {394	.alloc = pm8xxx_irq_domain_alloc,395	.free = irq_domain_free_irqs_common,396	.translate = irq_domain_translate_twocell,397};398 399static void pm8821_irq_mask_ack(struct irq_data *d)400{401	struct pm_irq_chip *chip = irq_data_get_irq_chip_data(d);402	unsigned int pmirq = irqd_to_hwirq(d);403	u8 block, master;404	int irq_bit, rc;405 406	block = pmirq / 8;407	master = block / PM8821_BLOCKS_PER_MASTER;408	irq_bit = pmirq % 8;409	block %= PM8821_BLOCKS_PER_MASTER;410 411	rc = regmap_update_bits(chip->regmap,412				PM8821_SSBI_ADDR_IRQ_MASK(master, block),413				BIT(irq_bit), BIT(irq_bit));414	if (rc) {415		pr_err("Failed to mask IRQ:%d rc=%d\n", pmirq, rc);416		return;417	}418 419	rc = regmap_update_bits(chip->regmap,420				PM8821_SSBI_ADDR_IRQ_CLEAR(master, block),421				BIT(irq_bit), BIT(irq_bit));422	if (rc)423		pr_err("Failed to CLEAR IRQ:%d rc=%d\n", pmirq, rc);424}425 426static void pm8821_irq_unmask(struct irq_data *d)427{428	struct pm_irq_chip *chip = irq_data_get_irq_chip_data(d);429	unsigned int pmirq = irqd_to_hwirq(d);430	int irq_bit, rc;431	u8 block, master;432 433	block = pmirq / 8;434	master = block / PM8821_BLOCKS_PER_MASTER;435	irq_bit = pmirq % 8;436	block %= PM8821_BLOCKS_PER_MASTER;437 438	rc = regmap_update_bits(chip->regmap,439				PM8821_SSBI_ADDR_IRQ_MASK(master, block),440				BIT(irq_bit), ~BIT(irq_bit));441	if (rc)442		pr_err("Failed to read/write unmask IRQ:%d rc=%d\n", pmirq, rc);443 444}445 446static int pm8821_irq_get_irqchip_state(struct irq_data *d,447					enum irqchip_irq_state which,448					bool *state)449{450	struct pm_irq_chip *chip = irq_data_get_irq_chip_data(d);451	int rc, pmirq = irqd_to_hwirq(d);452	u8 block, irq_bit, master;453	unsigned int bits;454 455	block = pmirq / 8;456	master = block / PM8821_BLOCKS_PER_MASTER;457	irq_bit = pmirq % 8;458	block %= PM8821_BLOCKS_PER_MASTER;459 460	rc = regmap_read(chip->regmap,461		PM8821_SSBI_ADDR_IRQ_RT_STATUS(master, block), &bits);462	if (rc) {463		pr_err("Reading Status of IRQ %d failed rc=%d\n", pmirq, rc);464		return rc;465	}466 467	*state = !!(bits & BIT(irq_bit));468 469	return rc;470}471 472static struct irq_chip pm8821_irq_chip = {473	.name		= "pm8821",474	.irq_mask_ack	= pm8821_irq_mask_ack,475	.irq_unmask	= pm8821_irq_unmask,476	.irq_get_irqchip_state = pm8821_irq_get_irqchip_state,477	.flags		= IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_SKIP_SET_WAKE,478};479 480static const struct regmap_config ssbi_regmap_config = {481	.reg_bits = 16,482	.val_bits = 8,483	.max_register = 0x3ff,484	.fast_io = true,485	.reg_read = ssbi_reg_read,486	.reg_write = ssbi_reg_write487};488 489static const struct pm_irq_data pm8xxx_data = {490	.num_irqs = PM8XXX_NR_IRQS,491	.irq_chip = &pm8xxx_irq_chip,492	.irq_handler = pm8xxx_irq_handler,493};494 495static const struct pm_irq_data pm8821_data = {496	.num_irqs = PM8821_NR_IRQS,497	.irq_chip = &pm8821_irq_chip,498	.irq_handler = pm8821_irq_handler,499};500 501static const struct of_device_id pm8xxx_id_table[] = {502	{ .compatible = "qcom,pm8058", .data = &pm8xxx_data},503	{ .compatible = "qcom,pm8821", .data = &pm8821_data},504	{ .compatible = "qcom,pm8921", .data = &pm8xxx_data},505	{ }506};507MODULE_DEVICE_TABLE(of, pm8xxx_id_table);508 509static int pm8xxx_probe(struct platform_device *pdev)510{511	const struct pm_irq_data *data;512	struct regmap *regmap;513	int irq, rc;514	unsigned int val;515	struct pm_irq_chip *chip;516 517	data = of_device_get_match_data(&pdev->dev);518	if (!data) {519		dev_err(&pdev->dev, "No matching driver data found\n");520		return -EINVAL;521	}522 523	irq = platform_get_irq(pdev, 0);524	if (irq < 0)525		return irq;526 527	regmap = devm_regmap_init(&pdev->dev, NULL, pdev->dev.parent,528				  &ssbi_regmap_config);529	if (IS_ERR(regmap))530		return PTR_ERR(regmap);531 532	/* Read PMIC chip revision */533	rc = regmap_read(regmap, REG_HWREV, &val);534	if (rc) {535		pr_err("Failed to read hw rev reg %d:rc=%d\n", REG_HWREV, rc);536		return rc;537	}538	pr_info("PMIC revision 1: %02X\n", val);539 540	/* Read PMIC chip revision 2 */541	rc = regmap_read(regmap, REG_HWREV_2, &val);542	if (rc) {543		pr_err("Failed to read hw rev 2 reg %d:rc=%d\n",544			REG_HWREV_2, rc);545		return rc;546	}547	pr_info("PMIC revision 2: %02X\n", val);548 549	chip = devm_kzalloc(&pdev->dev,550			    struct_size(chip, config, data->num_irqs),551			    GFP_KERNEL);552	if (!chip)553		return -ENOMEM;554 555	platform_set_drvdata(pdev, chip);556	chip->regmap = regmap;557	chip->num_blocks = DIV_ROUND_UP(data->num_irqs, 8);558	chip->num_masters = DIV_ROUND_UP(chip->num_blocks, 8);559	chip->pm_irq_data = data;560	spin_lock_init(&chip->pm_irq_lock);561 562	chip->irqdomain = irq_domain_add_linear(pdev->dev.of_node,563						data->num_irqs,564						&pm8xxx_irq_domain_ops,565						chip);566	if (!chip->irqdomain)567		return -ENODEV;568 569	rc = devm_request_irq(&pdev->dev, irq, data->irq_handler, 0, dev_name(&pdev->dev), chip);570	if (rc)571		return rc;572 573	irq_set_irq_wake(irq, 1);574 575	rc = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);576	if (rc)577		irq_domain_remove(chip->irqdomain);578 579	return rc;580}581 582static int pm8xxx_remove_child(struct device *dev, void *unused)583{584	platform_device_unregister(to_platform_device(dev));585	return 0;586}587 588static void pm8xxx_remove(struct platform_device *pdev)589{590	struct pm_irq_chip *chip = platform_get_drvdata(pdev);591 592	device_for_each_child(&pdev->dev, NULL, pm8xxx_remove_child);593	irq_domain_remove(chip->irqdomain);594}595 596static struct platform_driver pm8xxx_driver = {597	.probe		= pm8xxx_probe,598	.remove_new	= pm8xxx_remove,599	.driver		= {600		.name	= "pm8xxx-core",601		.of_match_table = pm8xxx_id_table,602	},603};604 605static int __init pm8xxx_init(void)606{607	return platform_driver_register(&pm8xxx_driver);608}609subsys_initcall(pm8xxx_init);610 611static void __exit pm8xxx_exit(void)612{613	platform_driver_unregister(&pm8xxx_driver);614}615module_exit(pm8xxx_exit);616 617MODULE_LICENSE("GPL v2");618MODULE_DESCRIPTION("PMIC 8xxx core driver");619MODULE_VERSION("1.0");620MODULE_ALIAS("platform:pm8xxx-core");621