0001
0002
0003
0004
0005
0006
0007 #include <linux/delay.h>
0008 #include <linux/err.h>
0009 #include <linux/init.h>
0010 #include <linux/interrupt.h>
0011 #include <linux/io.h>
0012 #include <linux/irqchip.h>
0013 #include <linux/irqdomain.h>
0014 #include <linux/mailbox_client.h>
0015 #include <linux/module.h>
0016 #include <linux/of.h>
0017 #include <linux/of_device.h>
0018 #include <linux/platform_device.h>
0019 #include <linux/pm_domain.h>
0020 #include <linux/slab.h>
0021 #include <linux/soc/qcom/irq.h>
0022 #include <linux/spinlock.h>
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065 #define MPM_REG_ENABLE 0
0066 #define MPM_REG_FALLING_EDGE 1
0067 #define MPM_REG_RISING_EDGE 2
0068 #define MPM_REG_POLARITY 3
0069 #define MPM_REG_STATUS 4
0070
0071
0072 struct mpm_gic_map {
0073 int pin;
0074 irq_hw_number_t hwirq;
0075 };
0076
0077 struct qcom_mpm_priv {
0078 void __iomem *base;
0079 raw_spinlock_t lock;
0080 struct mbox_client mbox_client;
0081 struct mbox_chan *mbox_chan;
0082 struct mpm_gic_map *maps;
0083 unsigned int map_cnt;
0084 unsigned int reg_stride;
0085 struct irq_domain *domain;
0086 struct generic_pm_domain genpd;
0087 };
0088
0089 static u32 qcom_mpm_read(struct qcom_mpm_priv *priv, unsigned int reg,
0090 unsigned int index)
0091 {
0092 unsigned int offset = (reg * priv->reg_stride + index + 2) * 4;
0093
0094 return readl_relaxed(priv->base + offset);
0095 }
0096
0097 static void qcom_mpm_write(struct qcom_mpm_priv *priv, unsigned int reg,
0098 unsigned int index, u32 val)
0099 {
0100 unsigned int offset = (reg * priv->reg_stride + index + 2) * 4;
0101
0102 writel_relaxed(val, priv->base + offset);
0103
0104
0105 wmb();
0106 }
0107
0108 static void qcom_mpm_enable_irq(struct irq_data *d, bool en)
0109 {
0110 struct qcom_mpm_priv *priv = d->chip_data;
0111 int pin = d->hwirq;
0112 unsigned int index = pin / 32;
0113 unsigned int shift = pin % 32;
0114 unsigned long flags, val;
0115
0116 raw_spin_lock_irqsave(&priv->lock, flags);
0117
0118 val = qcom_mpm_read(priv, MPM_REG_ENABLE, index);
0119 __assign_bit(shift, &val, en);
0120 qcom_mpm_write(priv, MPM_REG_ENABLE, index, val);
0121
0122 raw_spin_unlock_irqrestore(&priv->lock, flags);
0123 }
0124
0125 static void qcom_mpm_mask(struct irq_data *d)
0126 {
0127 qcom_mpm_enable_irq(d, false);
0128
0129 if (d->parent_data)
0130 irq_chip_mask_parent(d);
0131 }
0132
0133 static void qcom_mpm_unmask(struct irq_data *d)
0134 {
0135 qcom_mpm_enable_irq(d, true);
0136
0137 if (d->parent_data)
0138 irq_chip_unmask_parent(d);
0139 }
0140
0141 static void mpm_set_type(struct qcom_mpm_priv *priv, bool set, unsigned int reg,
0142 unsigned int index, unsigned int shift)
0143 {
0144 unsigned long flags, val;
0145
0146 raw_spin_lock_irqsave(&priv->lock, flags);
0147
0148 val = qcom_mpm_read(priv, reg, index);
0149 __assign_bit(shift, &val, set);
0150 qcom_mpm_write(priv, reg, index, val);
0151
0152 raw_spin_unlock_irqrestore(&priv->lock, flags);
0153 }
0154
0155 static int qcom_mpm_set_type(struct irq_data *d, unsigned int type)
0156 {
0157 struct qcom_mpm_priv *priv = d->chip_data;
0158 int pin = d->hwirq;
0159 unsigned int index = pin / 32;
0160 unsigned int shift = pin % 32;
0161
0162 if (type & IRQ_TYPE_EDGE_RISING)
0163 mpm_set_type(priv, true, MPM_REG_RISING_EDGE, index, shift);
0164 else
0165 mpm_set_type(priv, false, MPM_REG_RISING_EDGE, index, shift);
0166
0167 if (type & IRQ_TYPE_EDGE_FALLING)
0168 mpm_set_type(priv, true, MPM_REG_FALLING_EDGE, index, shift);
0169 else
0170 mpm_set_type(priv, false, MPM_REG_FALLING_EDGE, index, shift);
0171
0172 if (type & IRQ_TYPE_LEVEL_HIGH)
0173 mpm_set_type(priv, true, MPM_REG_POLARITY, index, shift);
0174 else
0175 mpm_set_type(priv, false, MPM_REG_POLARITY, index, shift);
0176
0177 if (!d->parent_data)
0178 return 0;
0179
0180 if (type & IRQ_TYPE_EDGE_BOTH)
0181 type = IRQ_TYPE_EDGE_RISING;
0182
0183 if (type & IRQ_TYPE_LEVEL_MASK)
0184 type = IRQ_TYPE_LEVEL_HIGH;
0185
0186 return irq_chip_set_type_parent(d, type);
0187 }
0188
0189 static struct irq_chip qcom_mpm_chip = {
0190 .name = "mpm",
0191 .irq_eoi = irq_chip_eoi_parent,
0192 .irq_mask = qcom_mpm_mask,
0193 .irq_unmask = qcom_mpm_unmask,
0194 .irq_retrigger = irq_chip_retrigger_hierarchy,
0195 .irq_set_type = qcom_mpm_set_type,
0196 .irq_set_affinity = irq_chip_set_affinity_parent,
0197 .flags = IRQCHIP_MASK_ON_SUSPEND |
0198 IRQCHIP_SKIP_SET_WAKE,
0199 };
0200
0201 static struct mpm_gic_map *get_mpm_gic_map(struct qcom_mpm_priv *priv, int pin)
0202 {
0203 struct mpm_gic_map *maps = priv->maps;
0204 int i;
0205
0206 for (i = 0; i < priv->map_cnt; i++) {
0207 if (maps[i].pin == pin)
0208 return &maps[i];
0209 }
0210
0211 return NULL;
0212 }
0213
0214 static int qcom_mpm_alloc(struct irq_domain *domain, unsigned int virq,
0215 unsigned int nr_irqs, void *data)
0216 {
0217 struct qcom_mpm_priv *priv = domain->host_data;
0218 struct irq_fwspec *fwspec = data;
0219 struct irq_fwspec parent_fwspec;
0220 struct mpm_gic_map *map;
0221 irq_hw_number_t pin;
0222 unsigned int type;
0223 int ret;
0224
0225 ret = irq_domain_translate_twocell(domain, fwspec, &pin, &type);
0226 if (ret)
0227 return ret;
0228
0229 ret = irq_domain_set_hwirq_and_chip(domain, virq, pin,
0230 &qcom_mpm_chip, priv);
0231 if (ret)
0232 return ret;
0233
0234 map = get_mpm_gic_map(priv, pin);
0235 if (map == NULL)
0236 return irq_domain_disconnect_hierarchy(domain->parent, virq);
0237
0238 if (type & IRQ_TYPE_EDGE_BOTH)
0239 type = IRQ_TYPE_EDGE_RISING;
0240
0241 if (type & IRQ_TYPE_LEVEL_MASK)
0242 type = IRQ_TYPE_LEVEL_HIGH;
0243
0244 parent_fwspec.fwnode = domain->parent->fwnode;
0245 parent_fwspec.param_count = 3;
0246 parent_fwspec.param[0] = 0;
0247 parent_fwspec.param[1] = map->hwirq;
0248 parent_fwspec.param[2] = type;
0249
0250 return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs,
0251 &parent_fwspec);
0252 }
0253
0254 static const struct irq_domain_ops qcom_mpm_ops = {
0255 .alloc = qcom_mpm_alloc,
0256 .free = irq_domain_free_irqs_common,
0257 .translate = irq_domain_translate_twocell,
0258 };
0259
0260
0261 static irqreturn_t qcom_mpm_handler(int irq, void *dev_id)
0262 {
0263 struct qcom_mpm_priv *priv = dev_id;
0264 unsigned long enable, pending;
0265 irqreturn_t ret = IRQ_NONE;
0266 unsigned long flags;
0267 int i, j;
0268
0269 for (i = 0; i < priv->reg_stride; i++) {
0270 raw_spin_lock_irqsave(&priv->lock, flags);
0271 enable = qcom_mpm_read(priv, MPM_REG_ENABLE, i);
0272 pending = qcom_mpm_read(priv, MPM_REG_STATUS, i);
0273 pending &= enable;
0274 raw_spin_unlock_irqrestore(&priv->lock, flags);
0275
0276 for_each_set_bit(j, &pending, 32) {
0277 unsigned int pin = 32 * i + j;
0278 struct irq_desc *desc = irq_resolve_mapping(priv->domain, pin);
0279 struct irq_data *d = &desc->irq_data;
0280
0281 if (!irqd_is_level_type(d))
0282 irq_set_irqchip_state(d->irq,
0283 IRQCHIP_STATE_PENDING, true);
0284 ret = IRQ_HANDLED;
0285 }
0286 }
0287
0288 return ret;
0289 }
0290
0291 static int mpm_pd_power_off(struct generic_pm_domain *genpd)
0292 {
0293 struct qcom_mpm_priv *priv = container_of(genpd, struct qcom_mpm_priv,
0294 genpd);
0295 int i, ret;
0296
0297 for (i = 0; i < priv->reg_stride; i++)
0298 qcom_mpm_write(priv, MPM_REG_STATUS, i, 0);
0299
0300
0301 ret = mbox_send_message(priv->mbox_chan, NULL);
0302 if (ret < 0)
0303 return ret;
0304
0305 return 0;
0306 }
0307
0308 static bool gic_hwirq_is_mapped(struct mpm_gic_map *maps, int cnt, u32 hwirq)
0309 {
0310 int i;
0311
0312 for (i = 0; i < cnt; i++)
0313 if (maps[i].hwirq == hwirq)
0314 return true;
0315
0316 return false;
0317 }
0318
0319 static int qcom_mpm_init(struct device_node *np, struct device_node *parent)
0320 {
0321 struct platform_device *pdev = of_find_device_by_node(np);
0322 struct device *dev = &pdev->dev;
0323 struct irq_domain *parent_domain;
0324 struct generic_pm_domain *genpd;
0325 struct qcom_mpm_priv *priv;
0326 unsigned int pin_cnt;
0327 int i, irq;
0328 int ret;
0329
0330 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
0331 if (!priv)
0332 return -ENOMEM;
0333
0334 ret = of_property_read_u32(np, "qcom,mpm-pin-count", &pin_cnt);
0335 if (ret) {
0336 dev_err(dev, "failed to read qcom,mpm-pin-count: %d\n", ret);
0337 return ret;
0338 }
0339
0340 priv->reg_stride = DIV_ROUND_UP(pin_cnt, 32);
0341
0342 ret = of_property_count_u32_elems(np, "qcom,mpm-pin-map");
0343 if (ret < 0) {
0344 dev_err(dev, "failed to read qcom,mpm-pin-map: %d\n", ret);
0345 return ret;
0346 }
0347
0348 if (ret % 2) {
0349 dev_err(dev, "invalid qcom,mpm-pin-map\n");
0350 return -EINVAL;
0351 }
0352
0353 priv->map_cnt = ret / 2;
0354 priv->maps = devm_kcalloc(dev, priv->map_cnt, sizeof(*priv->maps),
0355 GFP_KERNEL);
0356 if (!priv->maps)
0357 return -ENOMEM;
0358
0359 for (i = 0; i < priv->map_cnt; i++) {
0360 u32 pin, hwirq;
0361
0362 of_property_read_u32_index(np, "qcom,mpm-pin-map", i * 2, &pin);
0363 of_property_read_u32_index(np, "qcom,mpm-pin-map", i * 2 + 1, &hwirq);
0364
0365 if (gic_hwirq_is_mapped(priv->maps, i, hwirq)) {
0366 dev_warn(dev, "failed to map pin %d as GIC hwirq %d is already mapped\n",
0367 pin, hwirq);
0368 continue;
0369 }
0370
0371 priv->maps[i].pin = pin;
0372 priv->maps[i].hwirq = hwirq;
0373 }
0374
0375 raw_spin_lock_init(&priv->lock);
0376
0377 priv->base = devm_platform_ioremap_resource(pdev, 0);
0378 if (IS_ERR(priv->base))
0379 return PTR_ERR(priv->base);
0380
0381 for (i = 0; i < priv->reg_stride; i++) {
0382 qcom_mpm_write(priv, MPM_REG_ENABLE, i, 0);
0383 qcom_mpm_write(priv, MPM_REG_FALLING_EDGE, i, 0);
0384 qcom_mpm_write(priv, MPM_REG_RISING_EDGE, i, 0);
0385 qcom_mpm_write(priv, MPM_REG_POLARITY, i, 0);
0386 qcom_mpm_write(priv, MPM_REG_STATUS, i, 0);
0387 }
0388
0389 irq = platform_get_irq(pdev, 0);
0390 if (irq < 0)
0391 return irq;
0392
0393 genpd = &priv->genpd;
0394 genpd->flags = GENPD_FLAG_IRQ_SAFE;
0395 genpd->power_off = mpm_pd_power_off;
0396
0397 genpd->name = devm_kasprintf(dev, GFP_KERNEL, "%s", dev_name(dev));
0398 if (!genpd->name)
0399 return -ENOMEM;
0400
0401 ret = pm_genpd_init(genpd, NULL, false);
0402 if (ret) {
0403 dev_err(dev, "failed to init genpd: %d\n", ret);
0404 return ret;
0405 }
0406
0407 ret = of_genpd_add_provider_simple(np, genpd);
0408 if (ret) {
0409 dev_err(dev, "failed to add genpd provider: %d\n", ret);
0410 goto remove_genpd;
0411 }
0412
0413 priv->mbox_client.dev = dev;
0414 priv->mbox_chan = mbox_request_channel(&priv->mbox_client, 0);
0415 if (IS_ERR(priv->mbox_chan)) {
0416 ret = PTR_ERR(priv->mbox_chan);
0417 dev_err(dev, "failed to acquire IPC channel: %d\n", ret);
0418 return ret;
0419 }
0420
0421 parent_domain = irq_find_host(parent);
0422 if (!parent_domain) {
0423 dev_err(dev, "failed to find MPM parent domain\n");
0424 ret = -ENXIO;
0425 goto free_mbox;
0426 }
0427
0428 priv->domain = irq_domain_create_hierarchy(parent_domain,
0429 IRQ_DOMAIN_FLAG_QCOM_MPM_WAKEUP, pin_cnt,
0430 of_node_to_fwnode(np), &qcom_mpm_ops, priv);
0431 if (!priv->domain) {
0432 dev_err(dev, "failed to create MPM domain\n");
0433 ret = -ENOMEM;
0434 goto free_mbox;
0435 }
0436
0437 irq_domain_update_bus_token(priv->domain, DOMAIN_BUS_WAKEUP);
0438
0439 ret = devm_request_irq(dev, irq, qcom_mpm_handler, IRQF_NO_SUSPEND,
0440 "qcom_mpm", priv);
0441 if (ret) {
0442 dev_err(dev, "failed to request irq: %d\n", ret);
0443 goto remove_domain;
0444 }
0445
0446 return 0;
0447
0448 remove_domain:
0449 irq_domain_remove(priv->domain);
0450 free_mbox:
0451 mbox_free_channel(priv->mbox_chan);
0452 remove_genpd:
0453 pm_genpd_remove(genpd);
0454 return ret;
0455 }
0456
0457 IRQCHIP_PLATFORM_DRIVER_BEGIN(qcom_mpm)
0458 IRQCHIP_MATCH("qcom,mpm", qcom_mpm_init)
0459 IRQCHIP_PLATFORM_DRIVER_END(qcom_mpm)
0460 MODULE_DESCRIPTION("Qualcomm Technologies, Inc. MSM Power Manager");
0461 MODULE_LICENSE("GPL v2");