^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /* NXP PCF50633 Power Management Unit (PMU) driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * (C) 2006-2008 by Openmoko, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Author: Harald Welte <laforge@openmoko.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Balaji Rao <balajirrao@openmoko.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/mfd/pcf50633/core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/mfd/pcf50633/mbc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) int pcf50633_register_irq(struct pcf50633 *pcf, int irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) void (*handler) (int, void *), void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) if (irq < 0 || irq >= PCF50633_NUM_IRQ || !handler)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) if (WARN_ON(pcf->irq_handler[irq].handler))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) mutex_lock(&pcf->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) pcf->irq_handler[irq].handler = handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) pcf->irq_handler[irq].data = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) mutex_unlock(&pcf->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) EXPORT_SYMBOL_GPL(pcf50633_register_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) int pcf50633_free_irq(struct pcf50633 *pcf, int irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) if (irq < 0 || irq >= PCF50633_NUM_IRQ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) mutex_lock(&pcf->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) pcf->irq_handler[irq].handler = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) mutex_unlock(&pcf->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) EXPORT_SYMBOL_GPL(pcf50633_free_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) static int __pcf50633_irq_mask_set(struct pcf50633 *pcf, int irq, u8 mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) u8 reg, bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) int idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) idx = irq >> 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) reg = PCF50633_REG_INT1M + idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) bit = 1 << (irq & 0x07);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) pcf50633_reg_set_bit_mask(pcf, reg, bit, mask ? bit : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) mutex_lock(&pcf->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) if (mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) pcf->mask_regs[idx] |= bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) pcf->mask_regs[idx] &= ~bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) mutex_unlock(&pcf->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) int pcf50633_irq_mask(struct pcf50633 *pcf, int irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) dev_dbg(pcf->dev, "Masking IRQ %d\n", irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) return __pcf50633_irq_mask_set(pcf, irq, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) EXPORT_SYMBOL_GPL(pcf50633_irq_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) int pcf50633_irq_unmask(struct pcf50633 *pcf, int irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) dev_dbg(pcf->dev, "Unmasking IRQ %d\n", irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) return __pcf50633_irq_mask_set(pcf, irq, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) EXPORT_SYMBOL_GPL(pcf50633_irq_unmask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) int pcf50633_irq_mask_get(struct pcf50633 *pcf, int irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) u8 reg, bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) reg = irq >> 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) bits = 1 << (irq & 0x07);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) return pcf->mask_regs[reg] & bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) EXPORT_SYMBOL_GPL(pcf50633_irq_mask_get);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) static void pcf50633_irq_call_handler(struct pcf50633 *pcf, int irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) if (pcf->irq_handler[irq].handler)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) pcf->irq_handler[irq].handler(irq, pcf->irq_handler[irq].data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) /* Maximum amount of time ONKEY is held before emergency action is taken */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) #define PCF50633_ONKEY1S_TIMEOUT 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) static irqreturn_t pcf50633_irq(int irq, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) struct pcf50633 *pcf = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) int ret, i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) u8 pcf_int[5], chgstat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) /* Read the 5 INT regs in one transaction */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) ret = pcf50633_read_block(pcf, PCF50633_REG_INT1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) ARRAY_SIZE(pcf_int), pcf_int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) if (ret != ARRAY_SIZE(pcf_int)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) dev_err(pcf->dev, "Error reading INT registers\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) * If this doesn't ACK the interrupt to the chip, we'll be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) * called once again as we're level triggered.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) /* defeat 8s death from lowsys on A5 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) pcf50633_reg_write(pcf, PCF50633_REG_OOCSHDWN, 0x04);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) /* We immediately read the usb and adapter status. We thus make sure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) * only of USBINS/USBREM IRQ handlers are called */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) if (pcf_int[0] & (PCF50633_INT1_USBINS | PCF50633_INT1_USBREM)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) chgstat = pcf50633_reg_read(pcf, PCF50633_REG_MBCS2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) if (chgstat & (0x3 << 4))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) pcf_int[0] &= ~PCF50633_INT1_USBREM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) pcf_int[0] &= ~PCF50633_INT1_USBINS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) /* Make sure only one of ADPINS or ADPREM is set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) if (pcf_int[0] & (PCF50633_INT1_ADPINS | PCF50633_INT1_ADPREM)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) chgstat = pcf50633_reg_read(pcf, PCF50633_REG_MBCS2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) if (chgstat & (0x3 << 4))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) pcf_int[0] &= ~PCF50633_INT1_ADPREM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) pcf_int[0] &= ~PCF50633_INT1_ADPINS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) dev_dbg(pcf->dev, "INT1=0x%02x INT2=0x%02x INT3=0x%02x "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) "INT4=0x%02x INT5=0x%02x\n", pcf_int[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) pcf_int[1], pcf_int[2], pcf_int[3], pcf_int[4]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) /* Some revisions of the chip don't have a 8s standby mode on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) * ONKEY1S press. We try to manually do it in such cases. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) if ((pcf_int[0] & PCF50633_INT1_SECOND) && pcf->onkey1s_held) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) dev_info(pcf->dev, "ONKEY1S held for %d secs\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) pcf->onkey1s_held);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) if (pcf->onkey1s_held++ == PCF50633_ONKEY1S_TIMEOUT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) if (pcf->pdata->force_shutdown)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) pcf->pdata->force_shutdown(pcf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) if (pcf_int[2] & PCF50633_INT3_ONKEY1S) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) dev_info(pcf->dev, "ONKEY1S held\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) pcf->onkey1s_held = 1 ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) /* Unmask IRQ_SECOND */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) pcf50633_reg_clear_bits(pcf, PCF50633_REG_INT1M,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) PCF50633_INT1_SECOND);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) /* Unmask IRQ_ONKEYR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) pcf50633_reg_clear_bits(pcf, PCF50633_REG_INT2M,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) PCF50633_INT2_ONKEYR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) if ((pcf_int[1] & PCF50633_INT2_ONKEYR) && pcf->onkey1s_held) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) pcf->onkey1s_held = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) /* Mask SECOND and ONKEYR interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) if (pcf->mask_regs[0] & PCF50633_INT1_SECOND)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) pcf50633_reg_set_bit_mask(pcf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) PCF50633_REG_INT1M,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) PCF50633_INT1_SECOND,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) PCF50633_INT1_SECOND);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) if (pcf->mask_regs[1] & PCF50633_INT2_ONKEYR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) pcf50633_reg_set_bit_mask(pcf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) PCF50633_REG_INT2M,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) PCF50633_INT2_ONKEYR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) PCF50633_INT2_ONKEYR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) /* Have we just resumed ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) if (pcf->is_suspended) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) pcf->is_suspended = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) /* Set the resume reason filtering out non resumers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) for (i = 0; i < ARRAY_SIZE(pcf_int); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) pcf->resume_reason[i] = pcf_int[i] &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) pcf->pdata->resumers[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) /* Make sure we don't pass on any ONKEY events to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) * userspace now */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) pcf_int[1] &= ~(PCF50633_INT2_ONKEYR | PCF50633_INT2_ONKEYF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) for (i = 0; i < ARRAY_SIZE(pcf_int); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) /* Unset masked interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) pcf_int[i] &= ~pcf->mask_regs[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) for (j = 0; j < 8 ; j++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) if (pcf_int[i] & (1 << j))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) pcf50633_irq_call_handler(pcf, (i * 8) + j);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) int pcf50633_irq_suspend(struct pcf50633 *pcf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) u8 res[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) /* Make sure our interrupt handlers are not called
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) * henceforth */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) disable_irq(pcf->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) /* Save the masks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) ret = pcf50633_read_block(pcf, PCF50633_REG_INT1M,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) ARRAY_SIZE(pcf->suspend_irq_masks),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) pcf->suspend_irq_masks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) dev_err(pcf->dev, "error saving irq masks\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) /* Write wakeup irq masks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) for (i = 0; i < ARRAY_SIZE(res); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) res[i] = ~pcf->pdata->resumers[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) ret = pcf50633_write_block(pcf, PCF50633_REG_INT1M,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) ARRAY_SIZE(res), &res[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) dev_err(pcf->dev, "error writing wakeup irq masks\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) pcf->is_suspended = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) int pcf50633_irq_resume(struct pcf50633 *pcf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) /* Write the saved mask registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) ret = pcf50633_write_block(pcf, PCF50633_REG_INT1M,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) ARRAY_SIZE(pcf->suspend_irq_masks),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) pcf->suspend_irq_masks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) dev_err(pcf->dev, "Error restoring saved suspend masks\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) enable_irq(pcf->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) int pcf50633_irq_init(struct pcf50633 *pcf, int irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) pcf->irq = irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) /* Enable all interrupts except RTC SECOND */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) pcf->mask_regs[0] = 0x80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) pcf50633_reg_write(pcf, PCF50633_REG_INT1M, pcf->mask_regs[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) pcf50633_reg_write(pcf, PCF50633_REG_INT2M, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) pcf50633_reg_write(pcf, PCF50633_REG_INT3M, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) pcf50633_reg_write(pcf, PCF50633_REG_INT4M, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) pcf50633_reg_write(pcf, PCF50633_REG_INT5M, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) ret = request_threaded_irq(irq, NULL, pcf50633_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) IRQF_TRIGGER_LOW | IRQF_ONESHOT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) "pcf50633", pcf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) dev_err(pcf->dev, "Failed to request IRQ %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) if (enable_irq_wake(irq) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) dev_err(pcf->dev, "IRQ %u cannot be enabled as wake-up source"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) "in this hardware revision", irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) void pcf50633_irq_free(struct pcf50633 *pcf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) free_irq(pcf->irq, pcf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) }