Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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) }