History

mfd: mt6397: Extract IRQ related code from core driver

In order to support different types of irq design, we decide to add separate irq drivers for different design and keep mt6397 mfd core simple and reusable to all generations of PMICs so far.

Hsin-Hsiung Wang committed 7 years ago

Commit a4872e81 parent 708cb5c4 files · +192 −147Browse files

Unified · Split

4 files
  1. drivers/mfd/Makefile +2 −1
  2. drivers/mfd/mt6397-core.c +0 −146
  3. drivers/mfd/mt6397-irq.c +181 −0
  4. include/linux/mfd/mt6397/core.h +9 −0
drivers/mfd/Makefile+2−1
@@ -240,7 +240,8 @@ obj-$(CONFIG_INTEL_SOC_PMIC) += intel-soc-pmic.o · 239 unmodified lines
240240 obj-$(CONFIG_INTEL_SOC_PMIC_BXTWC) += intel_soc_pmic_bxtwc.o
241241 obj-$(CONFIG_INTEL_SOC_PMIC_CHTWC) += intel_soc_pmic_chtwc.o
242242 obj-$(CONFIG_INTEL_SOC_PMIC_CHTDC_TI) += intel_soc_pmic_chtdc_ti.o
243−obj-$(CONFIG_MFD_MT6397) += mt6397-core.o
243+mt6397-objs := mt6397-core.o mt6397-irq.o
244+obj-$(CONFIG_MFD_MT6397) += mt6397.o
244245
245246 obj-$(CONFIG_MFD_ALTERA_A10SR) += altera-a10sr.o
246247 obj-$(CONFIG_MFD_ALTERA_SYSMGR) += altera-sysmgr.o
drivers/mfd/mt6397-core.c+0−146
@@ -18,10 +18,6 @@ · 17 unmodified lines
1818 #define MT6397_RTC_BASE 0xe000
1919 #define MT6397_RTC_SIZE 0x3e
2020
21−#define MT6323_CHIP_ID 0x23
22−#define MT6391_CHIP_ID 0x91
23−#define MT6397_CHIP_ID 0x97
24−
2521 static const struct resource mt6397_rtc_resources[] = {
2622 {
2723 .start = MT6397_RTC_BASE,
@@ -86,148 +82,6 @@ static const struct mfd_cell mt6397_devs[] = { · 58 unmodified lines
8682 }
8783 };
8884
89−static void mt6397_irq_lock(struct irq_data *data)
90−{
91− struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(data);
92−
93− mutex_lock(&mt6397->irqlock);
94−}
95−
96−static void mt6397_irq_sync_unlock(struct irq_data *data)
97−{
98− struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(data);
99−
100− regmap_write(mt6397->regmap, mt6397->int_con[0],
101− mt6397->irq_masks_cur[0]);
102− regmap_write(mt6397->regmap, mt6397->int_con[1],
103− mt6397->irq_masks_cur[1]);
104−
105− mutex_unlock(&mt6397->irqlock);
106−}
107−
108−static void mt6397_irq_disable(struct irq_data *data)
109−{
110− struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(data);
111− int shift = data->hwirq & 0xf;
112− int reg = data->hwirq >> 4;
113−
114− mt6397->irq_masks_cur[reg] &= ~BIT(shift);
115−}
116−
117−static void mt6397_irq_enable(struct irq_data *data)
118−{
119− struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(data);
120− int shift = data->hwirq & 0xf;
121− int reg = data->hwirq >> 4;
122−
123− mt6397->irq_masks_cur[reg] |= BIT(shift);
124−}
125−
126−#ifdef CONFIG_PM_SLEEP
127−static int mt6397_irq_set_wake(struct irq_data *irq_data, unsigned int on)
128−{
129− struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(irq_data);
130− int shift = irq_data->hwirq & 0xf;
131− int reg = irq_data->hwirq >> 4;
132−
133− if (on)
134− mt6397->wake_mask[reg] |= BIT(shift);
135− else
136− mt6397->wake_mask[reg] &= ~BIT(shift);
137−
138− return 0;
139−}
140−#else
141−#define mt6397_irq_set_wake NULL
142−#endif
143−
144−static struct irq_chip mt6397_irq_chip = {
145− .name = "mt6397-irq",
146− .irq_bus_lock = mt6397_irq_lock,
147− .irq_bus_sync_unlock = mt6397_irq_sync_unlock,
148− .irq_enable = mt6397_irq_enable,
149− .irq_disable = mt6397_irq_disable,
150− .irq_set_wake = mt6397_irq_set_wake,
151−};
152−
153−static void mt6397_irq_handle_reg(struct mt6397_chip *mt6397, int reg,
154− int irqbase)
155−{
156− unsigned int status;
157− int i, irq, ret;
158−
159− ret = regmap_read(mt6397->regmap, reg, &status);
160− if (ret) {
161− dev_err(mt6397->dev, "Failed to read irq status: %d\n", ret);
162− return;
163− }
164−
165− for (i = 0; i < 16; i++) {
166− if (status & BIT(i)) {
167− irq = irq_find_mapping(mt6397->irq_domain, irqbase + i);
168− if (irq)
169− handle_nested_irq(irq);
170− }
171− }
172−
173− regmap_write(mt6397->regmap, reg, status);
174−}
175−
176−static irqreturn_t mt6397_irq_thread(int irq, void *data)
177−{
178− struct mt6397_chip *mt6397 = data;
179−
180− mt6397_irq_handle_reg(mt6397, mt6397->int_status[0], 0);
181− mt6397_irq_handle_reg(mt6397, mt6397->int_status[1], 16);
182−
183− return IRQ_HANDLED;
184−}
185−
186−static int mt6397_irq_domain_map(struct irq_domain *d, unsigned int irq,
187− irq_hw_number_t hw)
188−{
189− struct mt6397_chip *mt6397 = d->host_data;
190−
191− irq_set_chip_data(irq, mt6397);
192− irq_set_chip_and_handler(irq, &mt6397_irq_chip, handle_level_irq);
193− irq_set_nested_thread(irq, 1);
194− irq_set_noprobe(irq);
195−
196− return 0;
197−}
198−
199−static const struct irq_domain_ops mt6397_irq_domain_ops = {
200− .map = mt6397_irq_domain_map,
201−};
202−
203−static int mt6397_irq_init(struct mt6397_chip *mt6397)
204−{
205− int ret;
206−
207− mutex_init(&mt6397->irqlock);
208−
209− /* Mask all interrupt sources */
210− regmap_write(mt6397->regmap, mt6397->int_con[0], 0x0);
211− regmap_write(mt6397->regmap, mt6397->int_con[1], 0x0);
212−
213− mt6397->irq_domain = irq_domain_add_linear(mt6397->dev->of_node,
214− MT6397_IRQ_NR, &mt6397_irq_domain_ops, mt6397);
215− if (!mt6397->irq_domain) {
216− dev_err(mt6397->dev, "could not create irq domain\n");
217− return -ENOMEM;
218− }
219−
220− ret = devm_request_threaded_irq(mt6397->dev, mt6397->irq, NULL,
221− mt6397_irq_thread, IRQF_ONESHOT, "mt6397-pmic", mt6397);
222− if (ret) {
223− dev_err(mt6397->dev, "failed to register irq=%d; err: %d\n",
224− mt6397->irq, ret);
225− return ret;
226− }
227−
228− return 0;
229−}
230−
23185 #ifdef CONFIG_PM_SLEEP
23286 static int mt6397_irq_suspend(struct device *dev)
23387 {
drivers/mfd/mt6397-irq.c+181−0
@@ -0,0 +1,181 @@
1+// SPDX-License-Identifier: GPL-2.0
2+//
3+// Copyright (c) 2019 MediaTek Inc.
4+
5+#include <linux/interrupt.h>
6+#include <linux/module.h>
7+#include <linux/of.h>
8+#include <linux/of_device.h>
9+#include <linux/of_irq.h>
10+#include <linux/platform_device.h>
11+#include <linux/regmap.h>
12+#include <linux/mfd/mt6323/core.h>
13+#include <linux/mfd/mt6323/registers.h>
14+#include <linux/mfd/mt6397/core.h>
15+#include <linux/mfd/mt6397/registers.h>
16+
17+static void mt6397_irq_lock(struct irq_data *data)
18+{
19+ struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(data);
20+
21+ mutex_lock(&mt6397->irqlock);
22+}
23+
24+static void mt6397_irq_sync_unlock(struct irq_data *data)
25+{
26+ struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(data);
27+
28+ regmap_write(mt6397->regmap, mt6397->int_con[0],
29+ mt6397->irq_masks_cur[0]);
30+ regmap_write(mt6397->regmap, mt6397->int_con[1],
31+ mt6397->irq_masks_cur[1]);
32+
33+ mutex_unlock(&mt6397->irqlock);
34+}
35+
36+static void mt6397_irq_disable(struct irq_data *data)
37+{
38+ struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(data);
39+ int shift = data->hwirq & 0xf;
40+ int reg = data->hwirq >> 4;
41+
42+ mt6397->irq_masks_cur[reg] &= ~BIT(shift);
43+}
44+
45+static void mt6397_irq_enable(struct irq_data *data)
46+{
47+ struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(data);
48+ int shift = data->hwirq & 0xf;
49+ int reg = data->hwirq >> 4;
50+
51+ mt6397->irq_masks_cur[reg] |= BIT(shift);
52+}
53+
54+#ifdef CONFIG_PM_SLEEP
55+static int mt6397_irq_set_wake(struct irq_data *irq_data, unsigned int on)
56+{
57+ struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(irq_data);
58+ int shift = irq_data->hwirq & 0xf;
59+ int reg = irq_data->hwirq >> 4;
60+
61+ if (on)
62+ mt6397->wake_mask[reg] |= BIT(shift);
63+ else
64+ mt6397->wake_mask[reg] &= ~BIT(shift);
65+
66+ return 0;
67+}
68+#else
69+#define mt6397_irq_set_wake NULL
70+#endif
71+
72+static struct irq_chip mt6397_irq_chip = {
73+ .name = "mt6397-irq",
74+ .irq_bus_lock = mt6397_irq_lock,
75+ .irq_bus_sync_unlock = mt6397_irq_sync_unlock,
76+ .irq_enable = mt6397_irq_enable,
77+ .irq_disable = mt6397_irq_disable,
78+ .irq_set_wake = mt6397_irq_set_wake,
79+};
80+
81+static void mt6397_irq_handle_reg(struct mt6397_chip *mt6397, int reg,
82+ int irqbase)
83+{
84+ unsigned int status;
85+ int i, irq, ret;
86+
87+ ret = regmap_read(mt6397->regmap, reg, &status);
88+ if (ret) {
89+ dev_err(mt6397->dev, "Failed to read irq status: %d\n", ret);
90+ return;
91+ }
92+
93+ for (i = 0; i < 16; i++) {
94+ if (status & BIT(i)) {
95+ irq = irq_find_mapping(mt6397->irq_domain, irqbase + i);
96+ if (irq)
97+ handle_nested_irq(irq);
98+ }
99+ }
100+
101+ regmap_write(mt6397->regmap, reg, status);
102+}
103+
104+static irqreturn_t mt6397_irq_thread(int irq, void *data)
105+{
106+ struct mt6397_chip *mt6397 = data;
107+
108+ mt6397_irq_handle_reg(mt6397, mt6397->int_status[0], 0);
109+ mt6397_irq_handle_reg(mt6397, mt6397->int_status[1], 16);
110+
111+ return IRQ_HANDLED;
112+}
113+
114+static int mt6397_irq_domain_map(struct irq_domain *d, unsigned int irq,
115+ irq_hw_number_t hw)
116+{
117+ struct mt6397_chip *mt6397 = d->host_data;
118+
119+ irq_set_chip_data(irq, mt6397);
120+ irq_set_chip_and_handler(irq, &mt6397_irq_chip, handle_level_irq);
121+ irq_set_nested_thread(irq, 1);
122+ irq_set_noprobe(irq);
123+
124+ return 0;
125+}
126+
127+static const struct irq_domain_ops mt6397_irq_domain_ops = {
128+ .map = mt6397_irq_domain_map,
129+};
130+
131+int mt6397_irq_init(struct mt6397_chip *chip)
132+{
133+ int ret;
134+
135+ mutex_init(&chip->irqlock);
136+
137+ switch (chip->chip_id) {
138+ case MT6323_CHIP_ID:
139+ chip->int_con[0] = MT6323_INT_CON0;
140+ chip->int_con[1] = MT6323_INT_CON1;
141+ chip->int_status[0] = MT6323_INT_STATUS0;
142+ chip->int_status[1] = MT6323_INT_STATUS1;
143+ break;
144+
145+ case MT6391_CHIP_ID:
146+ case MT6397_CHIP_ID:
147+ chip->int_con[0] = MT6397_INT_CON0;
148+ chip->int_con[1] = MT6397_INT_CON1;
149+ chip->int_status[0] = MT6397_INT_STATUS0;
150+ chip->int_status[1] = MT6397_INT_STATUS1;
151+ break;
152+
153+ default:
154+ dev_err(chip->dev, "unsupported chip: 0x%x\n", chip->chip_id);
155+ return -ENODEV;
156+ }
157+
158+ /* Mask all interrupt sources */
159+ regmap_write(chip->regmap, chip->int_con[0], 0x0);
160+ regmap_write(chip->regmap, chip->int_con[1], 0x0);
161+
162+ chip->irq_domain = irq_domain_add_linear(chip->dev->of_node,
163+ MT6397_IRQ_NR,
164+ &mt6397_irq_domain_ops,
165+ chip);
166+ if (!chip->irq_domain) {
167+ dev_err(chip->dev, "could not create irq domain\n");
168+ return -ENOMEM;
169+ }
170+
171+ ret = devm_request_threaded_irq(chip->dev, chip->irq, NULL,
172+ mt6397_irq_thread, IRQF_ONESHOT,
173+ "mt6397-pmic", chip);
174+ if (ret) {
175+ dev_err(chip->dev, "failed to register irq=%d; err: %d\n",
176+ chip->irq, ret);
177+ return ret;
178+ }
179+
180+ return 0;
181+}
include/linux/mfd/mt6397/core.h+9−0
@@ -7,6 +7,12 @@ · 6 unmodified lines
77 #ifndef __MFD_MT6397_CORE_H__
88 #define __MFD_MT6397_CORE_H__
99
10+enum chip_id {
11+ MT6323_CHIP_ID = 0x23,
12+ MT6391_CHIP_ID = 0x91,
13+ MT6397_CHIP_ID = 0x97,
14+};
15+
1016 enum mt6397_irq_numbers {
1117 MT6397_IRQ_SPKL_AB = 0,
1218 MT6397_IRQ_SPKR_AB,
@@ -54,6 +60,9 @@ struct mt6397_chip { · 41 unmodified lines
5460 u16 irq_masks_cache[2];
5561 u16 int_con[2];
5662 u16 int_status[2];
63+ u16 chip_id;
5764 };
5865
66+int mt6397_irq_init(struct mt6397_chip *chip);
67+
5968 #endif /* __MFD_MT6397_CORE_H__ */

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t