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
240obj-$(CONFIG_INTEL_SOC_PMIC_BXTWC) += intel_soc_pmic_bxtwc.o240obj-$(CONFIG_INTEL_SOC_PMIC_BXTWC) += intel_soc_pmic_bxtwc.o
241obj-$(CONFIG_INTEL_SOC_PMIC_CHTWC) += intel_soc_pmic_chtwc.o241obj-$(CONFIG_INTEL_SOC_PMIC_CHTWC) += intel_soc_pmic_chtwc.o
242obj-$(CONFIG_INTEL_SOC_PMIC_CHTDC_TI) += intel_soc_pmic_chtdc_ti.o242obj-$(CONFIG_INTEL_SOC_PMIC_CHTDC_TI) += intel_soc_pmic_chtdc_ti.o
243obj-$(CONFIG_MFD_MT6397) += mt6397-core.o243mt6397-objs := mt6397-core.o mt6397-irq.o
244obj-$(CONFIG_MFD_MT6397) += mt6397.o
244 245
245obj-$(CONFIG_MFD_ALTERA_A10SR) += altera-a10sr.o246obj-$(CONFIG_MFD_ALTERA_A10SR) += altera-a10sr.o
246obj-$(CONFIG_MFD_ALTERA_SYSMGR) += altera-sysmgr.o247obj-$(CONFIG_MFD_ALTERA_SYSMGR) += altera-sysmgr.o
drivers/mfd/mt6397-core.c+0−146
@@ -18,10 +18,6 @@ · 17 unmodified lines
18#define MT6397_RTC_BASE 0xe00018#define MT6397_RTC_BASE 0xe000
19#define MT6397_RTC_SIZE 0x3e19#define MT6397_RTC_SIZE 0x3e
20 20
21#define MT6323_CHIP_ID 0x23
22#define MT6391_CHIP_ID 0x91
23#define MT6397_CHIP_ID 0x97
24
25static const struct resource mt6397_rtc_resources[] = {21static const struct resource mt6397_rtc_resources[] = {
26 {22 {
27 .start = MT6397_RTC_BASE,23 .start = MT6397_RTC_BASE,
@@ -86,148 +82,6 @@ static const struct mfd_cell mt6397_devs[] = { · 58 unmodified lines
86 }82 }
87};83};
88 84
89static 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
96static 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
108static 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
117static 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
127static 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
144static 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
153static 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
176static 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
186static 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
199static const struct irq_domain_ops mt6397_irq_domain_ops = {
200 .map = mt6397_irq_domain_map,
201};
202
203static 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
231#ifdef CONFIG_PM_SLEEP85#ifdef CONFIG_PM_SLEEP
232static int mt6397_irq_suspend(struct device *dev)86static int mt6397_irq_suspend(struct device *dev)
233{87{
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
17static 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
24static 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
36static 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
45static 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
55static 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
72static 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
81static 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
104static 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
114static 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
127static const struct irq_domain_ops mt6397_irq_domain_ops = {
128 .map = mt6397_irq_domain_map,
129};
130
131int 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
7#ifndef __MFD_MT6397_CORE_H__7#ifndef __MFD_MT6397_CORE_H__
8#define __MFD_MT6397_CORE_H__8#define __MFD_MT6397_CORE_H__
9 9
10enum chip_id {
11 MT6323_CHIP_ID = 0x23,
12 MT6391_CHIP_ID = 0x91,
13 MT6397_CHIP_ID = 0x97,
14};
15
10enum mt6397_irq_numbers {16enum mt6397_irq_numbers {
11 MT6397_IRQ_SPKL_AB = 0,17 MT6397_IRQ_SPKL_AB = 0,
12 MT6397_IRQ_SPKR_AB,18 MT6397_IRQ_SPKR_AB,
@@ -54,6 +60,9 @@ struct mt6397_chip { · 41 unmodified lines
54 u16 irq_masks_cache[2];60 u16 irq_masks_cache[2];
55 u16 int_con[2];61 u16 int_con[2];
56 u16 int_status[2];62 u16 int_status[2];
63 u16 chip_id;
57};64};
58 65
66int mt6397_irq_init(struct mt6397_chip *chip);
67
59#endif /* __MFD_MT6397_CORE_H__ */68#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