xref: /openbmc/linux/drivers/mfd/ab8500-core.c (revision 4b106fb9895c7edba2acd41c152e8f6edf724651)
162579266SRabin Vincent /*
262579266SRabin Vincent  * Copyright (C) ST-Ericsson SA 2010
362579266SRabin Vincent  *
462579266SRabin Vincent  * License Terms: GNU General Public License v2
562579266SRabin Vincent  * Author: Srinidhi Kasagar <srinidhi.kasagar@stericsson.com>
662579266SRabin Vincent  * Author: Rabin Vincent <rabin.vincent@stericsson.com>
7adceed62SMattias Wallin  * Author: Mattias Wallin <mattias.wallin@stericsson.com>
862579266SRabin Vincent  */
962579266SRabin Vincent 
1062579266SRabin Vincent #include <linux/kernel.h>
1162579266SRabin Vincent #include <linux/slab.h>
1262579266SRabin Vincent #include <linux/init.h>
1362579266SRabin Vincent #include <linux/irq.h>
1406e589efSLee Jones #include <linux/irqdomain.h>
1562579266SRabin Vincent #include <linux/delay.h>
1662579266SRabin Vincent #include <linux/interrupt.h>
1762579266SRabin Vincent #include <linux/module.h>
1862579266SRabin Vincent #include <linux/platform_device.h>
1962579266SRabin Vincent #include <linux/mfd/core.h>
2047c16975SMattias Wallin #include <linux/mfd/abx500.h>
21ee66e653SLinus Walleij #include <linux/mfd/abx500/ab8500.h>
2200441b5eSLee Jones #include <linux/mfd/abx500/ab8500-bm.h>
23d28f1db8SLee Jones #include <linux/mfd/dbx500-prcmu.h>
24549931f9SSundar R Iyer #include <linux/regulator/ab8500.h>
256bc4a568SLee Jones #include <linux/of.h>
266bc4a568SLee Jones #include <linux/of_device.h>
2762579266SRabin Vincent 
2862579266SRabin Vincent /*
2962579266SRabin Vincent  * Interrupt register offsets
3062579266SRabin Vincent  * Bank : 0x0E
3162579266SRabin Vincent  */
3247c16975SMattias Wallin #define AB8500_IT_SOURCE1_REG		0x00
3347c16975SMattias Wallin #define AB8500_IT_SOURCE2_REG		0x01
3447c16975SMattias Wallin #define AB8500_IT_SOURCE3_REG		0x02
3547c16975SMattias Wallin #define AB8500_IT_SOURCE4_REG		0x03
3647c16975SMattias Wallin #define AB8500_IT_SOURCE5_REG		0x04
3747c16975SMattias Wallin #define AB8500_IT_SOURCE6_REG		0x05
3847c16975SMattias Wallin #define AB8500_IT_SOURCE7_REG		0x06
3947c16975SMattias Wallin #define AB8500_IT_SOURCE8_REG		0x07
40d6255529SLinus Walleij #define AB9540_IT_SOURCE13_REG		0x0C
4147c16975SMattias Wallin #define AB8500_IT_SOURCE19_REG		0x12
4247c16975SMattias Wallin #define AB8500_IT_SOURCE20_REG		0x13
4347c16975SMattias Wallin #define AB8500_IT_SOURCE21_REG		0x14
4447c16975SMattias Wallin #define AB8500_IT_SOURCE22_REG		0x15
4547c16975SMattias Wallin #define AB8500_IT_SOURCE23_REG		0x16
4647c16975SMattias Wallin #define AB8500_IT_SOURCE24_REG		0x17
4762579266SRabin Vincent 
4862579266SRabin Vincent /*
4962579266SRabin Vincent  * latch registers
5062579266SRabin Vincent  */
5147c16975SMattias Wallin #define AB8500_IT_LATCH1_REG		0x20
5247c16975SMattias Wallin #define AB8500_IT_LATCH2_REG		0x21
5347c16975SMattias Wallin #define AB8500_IT_LATCH3_REG		0x22
5447c16975SMattias Wallin #define AB8500_IT_LATCH4_REG		0x23
5547c16975SMattias Wallin #define AB8500_IT_LATCH5_REG		0x24
5647c16975SMattias Wallin #define AB8500_IT_LATCH6_REG		0x25
5747c16975SMattias Wallin #define AB8500_IT_LATCH7_REG		0x26
5847c16975SMattias Wallin #define AB8500_IT_LATCH8_REG		0x27
5947c16975SMattias Wallin #define AB8500_IT_LATCH9_REG		0x28
6047c16975SMattias Wallin #define AB8500_IT_LATCH10_REG		0x29
6192d50a41SMattias Wallin #define AB8500_IT_LATCH12_REG		0x2B
62d6255529SLinus Walleij #define AB9540_IT_LATCH13_REG		0x2C
6347c16975SMattias Wallin #define AB8500_IT_LATCH19_REG		0x32
6447c16975SMattias Wallin #define AB8500_IT_LATCH20_REG		0x33
6547c16975SMattias Wallin #define AB8500_IT_LATCH21_REG		0x34
6647c16975SMattias Wallin #define AB8500_IT_LATCH22_REG		0x35
6747c16975SMattias Wallin #define AB8500_IT_LATCH23_REG		0x36
6847c16975SMattias Wallin #define AB8500_IT_LATCH24_REG		0x37
6962579266SRabin Vincent 
7062579266SRabin Vincent /*
7162579266SRabin Vincent  * mask registers
7262579266SRabin Vincent  */
7362579266SRabin Vincent 
7447c16975SMattias Wallin #define AB8500_IT_MASK1_REG		0x40
7547c16975SMattias Wallin #define AB8500_IT_MASK2_REG		0x41
7647c16975SMattias Wallin #define AB8500_IT_MASK3_REG		0x42
7747c16975SMattias Wallin #define AB8500_IT_MASK4_REG		0x43
7847c16975SMattias Wallin #define AB8500_IT_MASK5_REG		0x44
7947c16975SMattias Wallin #define AB8500_IT_MASK6_REG		0x45
8047c16975SMattias Wallin #define AB8500_IT_MASK7_REG		0x46
8147c16975SMattias Wallin #define AB8500_IT_MASK8_REG		0x47
8247c16975SMattias Wallin #define AB8500_IT_MASK9_REG		0x48
8347c16975SMattias Wallin #define AB8500_IT_MASK10_REG		0x49
8447c16975SMattias Wallin #define AB8500_IT_MASK11_REG		0x4A
8547c16975SMattias Wallin #define AB8500_IT_MASK12_REG		0x4B
8647c16975SMattias Wallin #define AB8500_IT_MASK13_REG		0x4C
8747c16975SMattias Wallin #define AB8500_IT_MASK14_REG		0x4D
8847c16975SMattias Wallin #define AB8500_IT_MASK15_REG		0x4E
8947c16975SMattias Wallin #define AB8500_IT_MASK16_REG		0x4F
9047c16975SMattias Wallin #define AB8500_IT_MASK17_REG		0x50
9147c16975SMattias Wallin #define AB8500_IT_MASK18_REG		0x51
9247c16975SMattias Wallin #define AB8500_IT_MASK19_REG		0x52
9347c16975SMattias Wallin #define AB8500_IT_MASK20_REG		0x53
9447c16975SMattias Wallin #define AB8500_IT_MASK21_REG		0x54
9547c16975SMattias Wallin #define AB8500_IT_MASK22_REG		0x55
9647c16975SMattias Wallin #define AB8500_IT_MASK23_REG		0x56
9747c16975SMattias Wallin #define AB8500_IT_MASK24_REG		0x57
98a29264b6SLee Jones #define AB8500_IT_MASK25_REG		0x58
9962579266SRabin Vincent 
1007ccfe9b1SMichel JAOUEN /*
1017ccfe9b1SMichel JAOUEN  * latch hierarchy registers
1027ccfe9b1SMichel JAOUEN  */
1037ccfe9b1SMichel JAOUEN #define AB8500_IT_LATCHHIER1_REG	0x60
1047ccfe9b1SMichel JAOUEN #define AB8500_IT_LATCHHIER2_REG	0x61
1057ccfe9b1SMichel JAOUEN #define AB8500_IT_LATCHHIER3_REG	0x62
1067ccfe9b1SMichel JAOUEN 
1077ccfe9b1SMichel JAOUEN #define AB8500_IT_LATCHHIER_NUM		3
1087ccfe9b1SMichel JAOUEN 
10947c16975SMattias Wallin #define AB8500_REV_REG			0x80
1100f620837SLinus Walleij #define AB8500_IC_NAME_REG		0x82
111e5c238c3SMattias Wallin #define AB8500_SWITCH_OFF_STATUS	0x00
11262579266SRabin Vincent 
113b4a31037SAndrew Lynn #define AB8500_TURN_ON_STATUS		0x00
114b4a31037SAndrew Lynn 
115f04a9d8aSRajkumar Kasirajan #define AB8500_CH_USBCH_STAT1_REG	0x02
116f04a9d8aSRajkumar Kasirajan #define VBUS_DET_DBNC100		0x02
117f04a9d8aSRajkumar Kasirajan #define VBUS_DET_DBNC1			0x01
118f04a9d8aSRajkumar Kasirajan 
119f04a9d8aSRajkumar Kasirajan static DEFINE_SPINLOCK(on_stat_lock);
120f04a9d8aSRajkumar Kasirajan static u8 turn_on_stat_mask = 0xFF;
121f04a9d8aSRajkumar Kasirajan static u8 turn_on_stat_set;
1226ef9418cSRickard Andersson static bool no_bm; /* No battery management */
1236ef9418cSRickard Andersson module_param(no_bm, bool, S_IRUGO);
1246ef9418cSRickard Andersson 
125d6255529SLinus Walleij #define AB9540_MODEM_CTRL2_REG			0x23
126d6255529SLinus Walleij #define AB9540_MODEM_CTRL2_SWDBBRSTN_BIT	BIT(2)
127d6255529SLinus Walleij 
12862579266SRabin Vincent /*
12962579266SRabin Vincent  * Map interrupt numbers to the LATCH and MASK register offsets, Interrupt
1302ced445eSLinus Walleij  * numbers are indexed into this array with (num / 8). The interupts are
1312ced445eSLinus Walleij  * defined in linux/mfd/ab8500.h
13262579266SRabin Vincent  *
13362579266SRabin Vincent  * This is one off from the register names, i.e. AB8500_IT_MASK1_REG is at
13462579266SRabin Vincent  * offset 0.
13562579266SRabin Vincent  */
1362ced445eSLinus Walleij /* AB8500 support */
13762579266SRabin Vincent static const int ab8500_irq_regoffset[AB8500_NUM_IRQ_REGS] = {
13892d50a41SMattias Wallin 	0, 1, 2, 3, 4, 6, 7, 8, 9, 11, 18, 19, 20, 21,
13962579266SRabin Vincent };
14062579266SRabin Vincent 
141a29264b6SLee Jones /* AB9540 / AB8505 support */
142d6255529SLinus Walleij static const int ab9540_irq_regoffset[AB9540_NUM_IRQ_REGS] = {
143a29264b6SLee Jones 	0, 1, 2, 3, 4, 6, 7, 8, 9, 11, 18, 19, 20, 21, 12, 13, 24, 5, 22, 23
144d6255529SLinus Walleij };
145d6255529SLinus Walleij 
1460f620837SLinus Walleij static const char ab8500_version_str[][7] = {
1470f620837SLinus Walleij 	[AB8500_VERSION_AB8500] = "AB8500",
1480f620837SLinus Walleij 	[AB8500_VERSION_AB8505] = "AB8505",
1490f620837SLinus Walleij 	[AB8500_VERSION_AB9540] = "AB9540",
1500f620837SLinus Walleij 	[AB8500_VERSION_AB8540] = "AB8540",
1510f620837SLinus Walleij };
1520f620837SLinus Walleij 
153822672a7SLee Jones static int ab8500_prcmu_write(struct ab8500 *ab8500, u16 addr, u8 data)
154d28f1db8SLee Jones {
155d28f1db8SLee Jones 	int ret;
156d28f1db8SLee Jones 
157d28f1db8SLee Jones 	ret = prcmu_abb_write((u8)(addr >> 8), (u8)(addr & 0xFF), &data, 1);
158d28f1db8SLee Jones 	if (ret < 0)
159d28f1db8SLee Jones 		dev_err(ab8500->dev, "prcmu i2c error %d\n", ret);
160d28f1db8SLee Jones 	return ret;
161d28f1db8SLee Jones }
162d28f1db8SLee Jones 
163822672a7SLee Jones static int ab8500_prcmu_write_masked(struct ab8500 *ab8500, u16 addr, u8 mask,
164d28f1db8SLee Jones 	u8 data)
165d28f1db8SLee Jones {
166d28f1db8SLee Jones 	int ret;
167d28f1db8SLee Jones 
168d28f1db8SLee Jones 	ret = prcmu_abb_write_masked((u8)(addr >> 8), (u8)(addr & 0xFF), &data,
169d28f1db8SLee Jones 		&mask, 1);
170d28f1db8SLee Jones 	if (ret < 0)
171d28f1db8SLee Jones 		dev_err(ab8500->dev, "prcmu i2c error %d\n", ret);
172d28f1db8SLee Jones 	return ret;
173d28f1db8SLee Jones }
174d28f1db8SLee Jones 
175822672a7SLee Jones static int ab8500_prcmu_read(struct ab8500 *ab8500, u16 addr)
176d28f1db8SLee Jones {
177d28f1db8SLee Jones 	int ret;
178d28f1db8SLee Jones 	u8 data;
179d28f1db8SLee Jones 
180d28f1db8SLee Jones 	ret = prcmu_abb_read((u8)(addr >> 8), (u8)(addr & 0xFF), &data, 1);
181d28f1db8SLee Jones 	if (ret < 0) {
182d28f1db8SLee Jones 		dev_err(ab8500->dev, "prcmu i2c error %d\n", ret);
183d28f1db8SLee Jones 		return ret;
184d28f1db8SLee Jones 	}
185d28f1db8SLee Jones 	return (int)data;
186d28f1db8SLee Jones }
187d28f1db8SLee Jones 
18847c16975SMattias Wallin static int ab8500_get_chip_id(struct device *dev)
18947c16975SMattias Wallin {
1906bce7bf1SMattias Wallin 	struct ab8500 *ab8500;
1916bce7bf1SMattias Wallin 
1926bce7bf1SMattias Wallin 	if (!dev)
1936bce7bf1SMattias Wallin 		return -EINVAL;
1946bce7bf1SMattias Wallin 	ab8500 = dev_get_drvdata(dev->parent);
1956bce7bf1SMattias Wallin 	return ab8500 ? (int)ab8500->chip_id : -EINVAL;
19647c16975SMattias Wallin }
19747c16975SMattias Wallin 
19847c16975SMattias Wallin static int set_register_interruptible(struct ab8500 *ab8500, u8 bank,
19947c16975SMattias Wallin 	u8 reg, u8 data)
20062579266SRabin Vincent {
20162579266SRabin Vincent 	int ret;
20247c16975SMattias Wallin 	/*
20347c16975SMattias Wallin 	 * Put the u8 bank and u8 register together into a an u16.
20447c16975SMattias Wallin 	 * The bank on higher 8 bits and register in lower 8 bits.
20547c16975SMattias Wallin 	 * */
20647c16975SMattias Wallin 	u16 addr = ((u16)bank) << 8 | reg;
20762579266SRabin Vincent 
20862579266SRabin Vincent 	dev_vdbg(ab8500->dev, "wr: addr %#x <= %#x\n", addr, data);
20962579266SRabin Vincent 
210392cbd1eSRabin Vincent 	mutex_lock(&ab8500->lock);
21147c16975SMattias Wallin 
21247c16975SMattias Wallin 	ret = ab8500->write(ab8500, addr, data);
21347c16975SMattias Wallin 	if (ret < 0)
21447c16975SMattias Wallin 		dev_err(ab8500->dev, "failed to write reg %#x: %d\n",
21547c16975SMattias Wallin 			addr, ret);
21647c16975SMattias Wallin 	mutex_unlock(&ab8500->lock);
21747c16975SMattias Wallin 
21847c16975SMattias Wallin 	return ret;
21947c16975SMattias Wallin }
22047c16975SMattias Wallin 
22147c16975SMattias Wallin static int ab8500_set_register(struct device *dev, u8 bank,
22247c16975SMattias Wallin 	u8 reg, u8 value)
22347c16975SMattias Wallin {
224112a80d2SJonas Aaberg 	int ret;
22547c16975SMattias Wallin 	struct ab8500 *ab8500 = dev_get_drvdata(dev->parent);
22647c16975SMattias Wallin 
227112a80d2SJonas Aaberg 	atomic_inc(&ab8500->transfer_ongoing);
228112a80d2SJonas Aaberg 	ret = set_register_interruptible(ab8500, bank, reg, value);
229112a80d2SJonas Aaberg 	atomic_dec(&ab8500->transfer_ongoing);
230112a80d2SJonas Aaberg 	return ret;
23147c16975SMattias Wallin }
23247c16975SMattias Wallin 
23347c16975SMattias Wallin static int get_register_interruptible(struct ab8500 *ab8500, u8 bank,
23447c16975SMattias Wallin 	u8 reg, u8 *value)
23547c16975SMattias Wallin {
23647c16975SMattias Wallin 	int ret;
23747c16975SMattias Wallin 	/* put the u8 bank and u8 reg together into a an u16.
23847c16975SMattias Wallin 	 * bank on higher 8 bits and reg in lower */
23947c16975SMattias Wallin 	u16 addr = ((u16)bank) << 8 | reg;
24047c16975SMattias Wallin 
241392cbd1eSRabin Vincent 	mutex_lock(&ab8500->lock);
24247c16975SMattias Wallin 
24347c16975SMattias Wallin 	ret = ab8500->read(ab8500, addr);
24447c16975SMattias Wallin 	if (ret < 0)
24547c16975SMattias Wallin 		dev_err(ab8500->dev, "failed to read reg %#x: %d\n",
24647c16975SMattias Wallin 			addr, ret);
24747c16975SMattias Wallin 	else
24847c16975SMattias Wallin 		*value = ret;
24947c16975SMattias Wallin 
25047c16975SMattias Wallin 	mutex_unlock(&ab8500->lock);
25147c16975SMattias Wallin 	dev_vdbg(ab8500->dev, "rd: addr %#x => data %#x\n", addr, ret);
25247c16975SMattias Wallin 
25347c16975SMattias Wallin 	return ret;
25447c16975SMattias Wallin }
25547c16975SMattias Wallin 
25647c16975SMattias Wallin static int ab8500_get_register(struct device *dev, u8 bank,
25747c16975SMattias Wallin 	u8 reg, u8 *value)
25847c16975SMattias Wallin {
259112a80d2SJonas Aaberg 	int ret;
26047c16975SMattias Wallin 	struct ab8500 *ab8500 = dev_get_drvdata(dev->parent);
26147c16975SMattias Wallin 
262112a80d2SJonas Aaberg 	atomic_inc(&ab8500->transfer_ongoing);
263112a80d2SJonas Aaberg 	ret = get_register_interruptible(ab8500, bank, reg, value);
264112a80d2SJonas Aaberg 	atomic_dec(&ab8500->transfer_ongoing);
265112a80d2SJonas Aaberg 	return ret;
26647c16975SMattias Wallin }
26747c16975SMattias Wallin 
26847c16975SMattias Wallin static int mask_and_set_register_interruptible(struct ab8500 *ab8500, u8 bank,
26947c16975SMattias Wallin 	u8 reg, u8 bitmask, u8 bitvalues)
27047c16975SMattias Wallin {
27147c16975SMattias Wallin 	int ret;
27247c16975SMattias Wallin 	/* put the u8 bank and u8 reg together into a an u16.
27347c16975SMattias Wallin 	 * bank on higher 8 bits and reg in lower */
27447c16975SMattias Wallin 	u16 addr = ((u16)bank) << 8 | reg;
27547c16975SMattias Wallin 
276392cbd1eSRabin Vincent 	mutex_lock(&ab8500->lock);
27747c16975SMattias Wallin 
278bc628fd1SMattias Nilsson 	if (ab8500->write_masked == NULL) {
279bc628fd1SMattias Nilsson 		u8 data;
280bc628fd1SMattias Nilsson 
28147c16975SMattias Wallin 		ret = ab8500->read(ab8500, addr);
28247c16975SMattias Wallin 		if (ret < 0) {
28347c16975SMattias Wallin 			dev_err(ab8500->dev, "failed to read reg %#x: %d\n",
28447c16975SMattias Wallin 				addr, ret);
28547c16975SMattias Wallin 			goto out;
28647c16975SMattias Wallin 		}
28747c16975SMattias Wallin 
28847c16975SMattias Wallin 		data = (u8)ret;
28947c16975SMattias Wallin 		data = (~bitmask & data) | (bitmask & bitvalues);
29047c16975SMattias Wallin 
29162579266SRabin Vincent 		ret = ab8500->write(ab8500, addr, data);
29262579266SRabin Vincent 		if (ret < 0)
29362579266SRabin Vincent 			dev_err(ab8500->dev, "failed to write reg %#x: %d\n",
29462579266SRabin Vincent 				addr, ret);
29562579266SRabin Vincent 
296bc628fd1SMattias Nilsson 		dev_vdbg(ab8500->dev, "mask: addr %#x => data %#x\n", addr,
297bc628fd1SMattias Nilsson 			data);
298bc628fd1SMattias Nilsson 		goto out;
299bc628fd1SMattias Nilsson 	}
300bc628fd1SMattias Nilsson 	ret = ab8500->write_masked(ab8500, addr, bitmask, bitvalues);
301bc628fd1SMattias Nilsson 	if (ret < 0)
302bc628fd1SMattias Nilsson 		dev_err(ab8500->dev, "failed to modify reg %#x: %d\n", addr,
303bc628fd1SMattias Nilsson 			ret);
30462579266SRabin Vincent out:
30562579266SRabin Vincent 	mutex_unlock(&ab8500->lock);
30662579266SRabin Vincent 	return ret;
30762579266SRabin Vincent }
30847c16975SMattias Wallin 
30947c16975SMattias Wallin static int ab8500_mask_and_set_register(struct device *dev,
31047c16975SMattias Wallin 	u8 bank, u8 reg, u8 bitmask, u8 bitvalues)
31147c16975SMattias Wallin {
312112a80d2SJonas Aaberg 	int ret;
31347c16975SMattias Wallin 	struct ab8500 *ab8500 = dev_get_drvdata(dev->parent);
31447c16975SMattias Wallin 
315112a80d2SJonas Aaberg 	atomic_inc(&ab8500->transfer_ongoing);
316112a80d2SJonas Aaberg 	ret= mask_and_set_register_interruptible(ab8500, bank, reg,
31747c16975SMattias Wallin 						 bitmask, bitvalues);
318112a80d2SJonas Aaberg 	atomic_dec(&ab8500->transfer_ongoing);
319112a80d2SJonas Aaberg 	return ret;
32047c16975SMattias Wallin }
32147c16975SMattias Wallin 
32247c16975SMattias Wallin static struct abx500_ops ab8500_ops = {
32347c16975SMattias Wallin 	.get_chip_id = ab8500_get_chip_id,
32447c16975SMattias Wallin 	.get_register = ab8500_get_register,
32547c16975SMattias Wallin 	.set_register = ab8500_set_register,
32647c16975SMattias Wallin 	.get_register_page = NULL,
32747c16975SMattias Wallin 	.set_register_page = NULL,
32847c16975SMattias Wallin 	.mask_and_set_register = ab8500_mask_and_set_register,
32947c16975SMattias Wallin 	.event_registers_startup_state_get = NULL,
33047c16975SMattias Wallin 	.startup_irq_enabled = NULL,
3311d843a6cSMian Yousaf Kaukab 	.dump_all_banks = ab8500_dump_all_banks,
33247c16975SMattias Wallin };
33362579266SRabin Vincent 
3349505a0a0SMark Brown static void ab8500_irq_lock(struct irq_data *data)
33562579266SRabin Vincent {
3369505a0a0SMark Brown 	struct ab8500 *ab8500 = irq_data_get_irq_chip_data(data);
33762579266SRabin Vincent 
33862579266SRabin Vincent 	mutex_lock(&ab8500->irq_lock);
339112a80d2SJonas Aaberg 	atomic_inc(&ab8500->transfer_ongoing);
34062579266SRabin Vincent }
34162579266SRabin Vincent 
3429505a0a0SMark Brown static void ab8500_irq_sync_unlock(struct irq_data *data)
34362579266SRabin Vincent {
3449505a0a0SMark Brown 	struct ab8500 *ab8500 = irq_data_get_irq_chip_data(data);
34562579266SRabin Vincent 	int i;
34662579266SRabin Vincent 
3472ced445eSLinus Walleij 	for (i = 0; i < ab8500->mask_size; i++) {
34862579266SRabin Vincent 		u8 old = ab8500->oldmask[i];
34962579266SRabin Vincent 		u8 new = ab8500->mask[i];
35062579266SRabin Vincent 		int reg;
35162579266SRabin Vincent 
35262579266SRabin Vincent 		if (new == old)
35362579266SRabin Vincent 			continue;
35462579266SRabin Vincent 
3550f620837SLinus Walleij 		/*
3560f620837SLinus Walleij 		 * Interrupt register 12 doesn't exist prior to AB8500 version
3570f620837SLinus Walleij 		 * 2.0
3580f620837SLinus Walleij 		 */
3590f620837SLinus Walleij 		if (ab8500->irq_reg_offset[i] == 11 &&
3600f620837SLinus Walleij 			is_ab8500_1p1_or_earlier(ab8500))
36192d50a41SMattias Wallin 			continue;
36292d50a41SMattias Wallin 
36362579266SRabin Vincent 		ab8500->oldmask[i] = new;
36462579266SRabin Vincent 
3652ced445eSLinus Walleij 		reg = AB8500_IT_MASK1_REG + ab8500->irq_reg_offset[i];
36647c16975SMattias Wallin 		set_register_interruptible(ab8500, AB8500_INTERRUPT, reg, new);
36762579266SRabin Vincent 	}
368112a80d2SJonas Aaberg 	atomic_dec(&ab8500->transfer_ongoing);
36962579266SRabin Vincent 	mutex_unlock(&ab8500->irq_lock);
37062579266SRabin Vincent }
37162579266SRabin Vincent 
3729505a0a0SMark Brown static void ab8500_irq_mask(struct irq_data *data)
37362579266SRabin Vincent {
3749505a0a0SMark Brown 	struct ab8500 *ab8500 = irq_data_get_irq_chip_data(data);
37506e589efSLee Jones 	int offset = data->hwirq;
37662579266SRabin Vincent 	int index = offset / 8;
37762579266SRabin Vincent 	int mask = 1 << (offset % 8);
37862579266SRabin Vincent 
37962579266SRabin Vincent 	ab8500->mask[index] |= mask;
3809c677b9bSLee Jones 
3819c677b9bSLee Jones 	/* The AB8500 GPIOs have two interrupts each (rising & falling). */
3829c677b9bSLee Jones 	if (offset >= AB8500_INT_GPIO6R && offset <= AB8500_INT_GPIO41R)
3839c677b9bSLee Jones 		ab8500->mask[index + 2] |= mask;
3849c677b9bSLee Jones 	if (offset >= AB9540_INT_GPIO50R && offset <= AB9540_INT_GPIO54R)
3859c677b9bSLee Jones 		ab8500->mask[index + 1] |= mask;
3869c677b9bSLee Jones 	if (offset == AB8540_INT_GPIO43R || offset == AB8540_INT_GPIO44R)
387e2ddf46aSLinus Walleij 		/* Here the falling IRQ is one bit lower */
388e2ddf46aSLinus Walleij 		ab8500->mask[index] |= (mask << 1);
38962579266SRabin Vincent }
39062579266SRabin Vincent 
3919505a0a0SMark Brown static void ab8500_irq_unmask(struct irq_data *data)
39262579266SRabin Vincent {
3939505a0a0SMark Brown 	struct ab8500 *ab8500 = irq_data_get_irq_chip_data(data);
3949c677b9bSLee Jones 	unsigned int type = irqd_get_trigger_type(data);
39506e589efSLee Jones 	int offset = data->hwirq;
39662579266SRabin Vincent 	int index = offset / 8;
39762579266SRabin Vincent 	int mask = 1 << (offset % 8);
39862579266SRabin Vincent 
3999c677b9bSLee Jones 	if (type & IRQ_TYPE_EDGE_RISING)
40062579266SRabin Vincent 		ab8500->mask[index] &= ~mask;
4019c677b9bSLee Jones 
4029c677b9bSLee Jones 	/* The AB8500 GPIOs have two interrupts each (rising & falling). */
4039c677b9bSLee Jones 	if (type & IRQ_TYPE_EDGE_FALLING) {
4049c677b9bSLee Jones 		if (offset >= AB8500_INT_GPIO6R && offset <= AB8500_INT_GPIO41R)
4059c677b9bSLee Jones 			ab8500->mask[index + 2] &= ~mask;
4069c677b9bSLee Jones 		else if (offset >= AB9540_INT_GPIO50R && offset <= AB9540_INT_GPIO54R)
4079c677b9bSLee Jones 			ab8500->mask[index + 1] &= ~mask;
4089c677b9bSLee Jones 		else if (offset == AB8540_INT_GPIO43R || offset == AB8540_INT_GPIO44R)
409e2ddf46aSLinus Walleij 			/* Here the falling IRQ is one bit lower */
410e2ddf46aSLinus Walleij 			ab8500->mask[index] &= ~(mask << 1);
4119c677b9bSLee Jones 		else
4129c677b9bSLee Jones 			ab8500->mask[index] &= ~mask;
413e2ddf46aSLinus Walleij 	} else {
4149c677b9bSLee Jones 		/* Satisfies the case where type is not set. */
41562579266SRabin Vincent 		ab8500->mask[index] &= ~mask;
41662579266SRabin Vincent 	}
417e2ddf46aSLinus Walleij }
41862579266SRabin Vincent 
41940f6e5a2SLee Jones static int ab8500_irq_set_type(struct irq_data *data, unsigned int type)
42040f6e5a2SLee Jones {
42140f6e5a2SLee Jones 	return 0;
42262579266SRabin Vincent }
42362579266SRabin Vincent 
42462579266SRabin Vincent static struct irq_chip ab8500_irq_chip = {
42562579266SRabin Vincent 	.name			= "ab8500",
4269505a0a0SMark Brown 	.irq_bus_lock		= ab8500_irq_lock,
4279505a0a0SMark Brown 	.irq_bus_sync_unlock	= ab8500_irq_sync_unlock,
4289505a0a0SMark Brown 	.irq_mask		= ab8500_irq_mask,
429e6f9306eSVirupax Sadashivpetimath 	.irq_disable		= ab8500_irq_mask,
4309505a0a0SMark Brown 	.irq_unmask		= ab8500_irq_unmask,
43140f6e5a2SLee Jones 	.irq_set_type		= ab8500_irq_set_type,
43262579266SRabin Vincent };
43362579266SRabin Vincent 
4347ccfe9b1SMichel JAOUEN static int ab8500_handle_hierarchical_line(struct ab8500 *ab8500,
4357ccfe9b1SMichel JAOUEN 					int latch_offset, u8 latch_val)
4367ccfe9b1SMichel JAOUEN {
4377ccfe9b1SMichel JAOUEN 	int int_bit = __ffs(latch_val);
4387ccfe9b1SMichel JAOUEN 	int line, i;
4397ccfe9b1SMichel JAOUEN 
4407ccfe9b1SMichel JAOUEN 	do {
4417ccfe9b1SMichel JAOUEN 		int_bit = __ffs(latch_val);
4427ccfe9b1SMichel JAOUEN 
4437ccfe9b1SMichel JAOUEN 		for (i = 0; i < ab8500->mask_size; i++)
4447ccfe9b1SMichel JAOUEN 			if (ab8500->irq_reg_offset[i] == latch_offset)
4457ccfe9b1SMichel JAOUEN 				break;
4467ccfe9b1SMichel JAOUEN 
4477ccfe9b1SMichel JAOUEN 		if (i >= ab8500->mask_size) {
4487ccfe9b1SMichel JAOUEN 			dev_err(ab8500->dev, "Register offset 0x%2x not declared\n",
4497ccfe9b1SMichel JAOUEN 					latch_offset);
4507ccfe9b1SMichel JAOUEN 			return -ENXIO;
4517ccfe9b1SMichel JAOUEN 		}
4527ccfe9b1SMichel JAOUEN 
4537ccfe9b1SMichel JAOUEN 		line = (i << 3) + int_bit;
4547ccfe9b1SMichel JAOUEN 		latch_val &= ~(1 << int_bit);
4557ccfe9b1SMichel JAOUEN 
456e2ddf46aSLinus Walleij 		/*
457e2ddf46aSLinus Walleij 		 * This handles the falling edge hwirqs from the GPIO
458e2ddf46aSLinus Walleij 		 * lines. Route them back to the line registered for the
459e2ddf46aSLinus Walleij 		 * rising IRQ, as this is merely a flag for the same IRQ
460e2ddf46aSLinus Walleij 		 * in linux terms.
461e2ddf46aSLinus Walleij 		 */
462e2ddf46aSLinus Walleij 		if (line >= AB8500_INT_GPIO6F && line <= AB8500_INT_GPIO41F)
463e2ddf46aSLinus Walleij 			line -= 16;
464e2ddf46aSLinus Walleij 		if (line >= AB9540_INT_GPIO50F && line <= AB9540_INT_GPIO54F)
465e2ddf46aSLinus Walleij 			line -= 8;
466e2ddf46aSLinus Walleij 		if (line == AB8540_INT_GPIO43F || line == AB8540_INT_GPIO44F)
467e2ddf46aSLinus Walleij 			line += 1;
468e2ddf46aSLinus Walleij 
4697ccfe9b1SMichel JAOUEN 		handle_nested_irq(ab8500->irq_base + line);
4707ccfe9b1SMichel JAOUEN 	} while (latch_val);
4717ccfe9b1SMichel JAOUEN 
4727ccfe9b1SMichel JAOUEN 	return 0;
4737ccfe9b1SMichel JAOUEN }
4747ccfe9b1SMichel JAOUEN 
4757ccfe9b1SMichel JAOUEN static int ab8500_handle_hierarchical_latch(struct ab8500 *ab8500,
4767ccfe9b1SMichel JAOUEN 					int hier_offset, u8 hier_val)
4777ccfe9b1SMichel JAOUEN {
4787ccfe9b1SMichel JAOUEN 	int latch_bit, status;
4797ccfe9b1SMichel JAOUEN 	u8 latch_offset, latch_val;
4807ccfe9b1SMichel JAOUEN 
4817ccfe9b1SMichel JAOUEN 	do {
4827ccfe9b1SMichel JAOUEN 		latch_bit = __ffs(hier_val);
4837ccfe9b1SMichel JAOUEN 		latch_offset = (hier_offset << 3) + latch_bit;
4847ccfe9b1SMichel JAOUEN 
4857ccfe9b1SMichel JAOUEN 		/* Fix inconsistent ITFromLatch25 bit mapping... */
4867ccfe9b1SMichel JAOUEN 		if (unlikely(latch_offset == 17))
4877ccfe9b1SMichel JAOUEN 			latch_offset = 24;
4887ccfe9b1SMichel JAOUEN 
4897ccfe9b1SMichel JAOUEN 		status = get_register_interruptible(ab8500,
4907ccfe9b1SMichel JAOUEN 				AB8500_INTERRUPT,
4917ccfe9b1SMichel JAOUEN 				AB8500_IT_LATCH1_REG + latch_offset,
4927ccfe9b1SMichel JAOUEN 				&latch_val);
4937ccfe9b1SMichel JAOUEN 		if (status < 0 || latch_val == 0)
4947ccfe9b1SMichel JAOUEN 			goto discard;
4957ccfe9b1SMichel JAOUEN 
4967ccfe9b1SMichel JAOUEN 		status = ab8500_handle_hierarchical_line(ab8500,
4977ccfe9b1SMichel JAOUEN 				latch_offset, latch_val);
4987ccfe9b1SMichel JAOUEN 		if (status < 0)
4997ccfe9b1SMichel JAOUEN 			return status;
5007ccfe9b1SMichel JAOUEN discard:
5017ccfe9b1SMichel JAOUEN 		hier_val &= ~(1 << latch_bit);
5027ccfe9b1SMichel JAOUEN 	} while (hier_val);
5037ccfe9b1SMichel JAOUEN 
5047ccfe9b1SMichel JAOUEN 	return 0;
5057ccfe9b1SMichel JAOUEN }
5067ccfe9b1SMichel JAOUEN 
5077ccfe9b1SMichel JAOUEN static irqreturn_t ab8500_hierarchical_irq(int irq, void *dev)
5087ccfe9b1SMichel JAOUEN {
5097ccfe9b1SMichel JAOUEN 	struct ab8500 *ab8500 = dev;
5107ccfe9b1SMichel JAOUEN 	u8 i;
5117ccfe9b1SMichel JAOUEN 
5127ccfe9b1SMichel JAOUEN 	dev_vdbg(ab8500->dev, "interrupt\n");
5137ccfe9b1SMichel JAOUEN 
5147ccfe9b1SMichel JAOUEN 	/*  Hierarchical interrupt version */
5157ccfe9b1SMichel JAOUEN 	for (i = 0; i < AB8500_IT_LATCHHIER_NUM; i++) {
5167ccfe9b1SMichel JAOUEN 		int status;
5177ccfe9b1SMichel JAOUEN 		u8 hier_val;
5187ccfe9b1SMichel JAOUEN 
5197ccfe9b1SMichel JAOUEN 		status = get_register_interruptible(ab8500, AB8500_INTERRUPT,
5207ccfe9b1SMichel JAOUEN 			AB8500_IT_LATCHHIER1_REG + i, &hier_val);
5217ccfe9b1SMichel JAOUEN 		if (status < 0 || hier_val == 0)
5227ccfe9b1SMichel JAOUEN 			continue;
5237ccfe9b1SMichel JAOUEN 
5247ccfe9b1SMichel JAOUEN 		status = ab8500_handle_hierarchical_latch(ab8500, i, hier_val);
5257ccfe9b1SMichel JAOUEN 		if (status < 0)
5267ccfe9b1SMichel JAOUEN 			break;
5277ccfe9b1SMichel JAOUEN 	}
5287ccfe9b1SMichel JAOUEN 	return IRQ_HANDLED;
5297ccfe9b1SMichel JAOUEN }
5307ccfe9b1SMichel JAOUEN 
53180633f05SLee Jones /**
53280633f05SLee Jones  * ab8500_irq_get_virq(): Map an interrupt on a chip to a virtual IRQ
53380633f05SLee Jones  *
53480633f05SLee Jones  * @ab8500: ab8500_irq controller to operate on.
53580633f05SLee Jones  * @irq: index of the interrupt requested in the chip IRQs
53680633f05SLee Jones  *
53780633f05SLee Jones  * Useful for drivers to request their own IRQs.
53880633f05SLee Jones  */
53980633f05SLee Jones static int ab8500_irq_get_virq(struct ab8500 *ab8500, int irq)
54080633f05SLee Jones {
54180633f05SLee Jones 	if (!ab8500)
54280633f05SLee Jones 		return -EINVAL;
54380633f05SLee Jones 
54480633f05SLee Jones 	return irq_create_mapping(ab8500->domain, irq);
54580633f05SLee Jones }
54680633f05SLee Jones 
54762579266SRabin Vincent static irqreturn_t ab8500_irq(int irq, void *dev)
54862579266SRabin Vincent {
54962579266SRabin Vincent 	struct ab8500 *ab8500 = dev;
55062579266SRabin Vincent 	int i;
55162579266SRabin Vincent 
55262579266SRabin Vincent 	dev_vdbg(ab8500->dev, "interrupt\n");
55362579266SRabin Vincent 
554112a80d2SJonas Aaberg 	atomic_inc(&ab8500->transfer_ongoing);
555112a80d2SJonas Aaberg 
5562ced445eSLinus Walleij 	for (i = 0; i < ab8500->mask_size; i++) {
5572ced445eSLinus Walleij 		int regoffset = ab8500->irq_reg_offset[i];
55862579266SRabin Vincent 		int status;
55947c16975SMattias Wallin 		u8 value;
56062579266SRabin Vincent 
5610f620837SLinus Walleij 		/*
5620f620837SLinus Walleij 		 * Interrupt register 12 doesn't exist prior to AB8500 version
5630f620837SLinus Walleij 		 * 2.0
5640f620837SLinus Walleij 		 */
5650f620837SLinus Walleij 		if (regoffset == 11 && is_ab8500_1p1_or_earlier(ab8500))
56692d50a41SMattias Wallin 			continue;
56792d50a41SMattias Wallin 
56847c16975SMattias Wallin 		status = get_register_interruptible(ab8500, AB8500_INTERRUPT,
56947c16975SMattias Wallin 			AB8500_IT_LATCH1_REG + regoffset, &value);
57047c16975SMattias Wallin 		if (status < 0 || value == 0)
57162579266SRabin Vincent 			continue;
57262579266SRabin Vincent 
57362579266SRabin Vincent 		do {
57488aec4f7SMattias Wallin 			int bit = __ffs(value);
57562579266SRabin Vincent 			int line = i * 8 + bit;
5760a37fc56SLee Jones 			int virq = ab8500_irq_get_virq(ab8500, line);
57762579266SRabin Vincent 
5780a37fc56SLee Jones 			handle_nested_irq(virq);
5798f0eb43bSBengt Jonsson 			ab8500_debug_register_interrupt(line);
58047c16975SMattias Wallin 			value &= ~(1 << bit);
581112a80d2SJonas Aaberg 
58247c16975SMattias Wallin 		} while (value);
58362579266SRabin Vincent 	}
584112a80d2SJonas Aaberg 	atomic_dec(&ab8500->transfer_ongoing);
58562579266SRabin Vincent 	return IRQ_HANDLED;
58662579266SRabin Vincent }
58762579266SRabin Vincent 
58806e589efSLee Jones static int ab8500_irq_map(struct irq_domain *d, unsigned int virq,
58906e589efSLee Jones 				irq_hw_number_t hwirq)
59006e589efSLee Jones {
59106e589efSLee Jones 	struct ab8500 *ab8500 = d->host_data;
59206e589efSLee Jones 
59306e589efSLee Jones 	if (!ab8500)
59406e589efSLee Jones 		return -EINVAL;
59506e589efSLee Jones 
59606e589efSLee Jones 	irq_set_chip_data(virq, ab8500);
59706e589efSLee Jones 	irq_set_chip_and_handler(virq, &ab8500_irq_chip,
59806e589efSLee Jones 				handle_simple_irq);
59906e589efSLee Jones 	irq_set_nested_thread(virq, 1);
60006e589efSLee Jones #ifdef CONFIG_ARM
60106e589efSLee Jones 	set_irq_flags(virq, IRQF_VALID);
60206e589efSLee Jones #else
60306e589efSLee Jones 	irq_set_noprobe(virq);
60406e589efSLee Jones #endif
60562579266SRabin Vincent 
60662579266SRabin Vincent 	return 0;
60762579266SRabin Vincent }
60862579266SRabin Vincent 
60906e589efSLee Jones static struct irq_domain_ops ab8500_irq_ops = {
61006e589efSLee Jones         .map    = ab8500_irq_map,
61106e589efSLee Jones         .xlate  = irq_domain_xlate_twocell,
61206e589efSLee Jones };
61306e589efSLee Jones 
61406e589efSLee Jones static int ab8500_irq_init(struct ab8500 *ab8500, struct device_node *np)
61562579266SRabin Vincent {
6162ced445eSLinus Walleij 	int num_irqs;
61762579266SRabin Vincent 
618d6255529SLinus Walleij 	if (is_ab9540(ab8500))
619d6255529SLinus Walleij 		num_irqs = AB9540_NR_IRQS;
620a982362cSBengt Jonsson 	else if (is_ab8505(ab8500))
621a982362cSBengt Jonsson 		num_irqs = AB8505_NR_IRQS;
622d6255529SLinus Walleij 	else
6232ced445eSLinus Walleij 		num_irqs = AB8500_NR_IRQS;
6242ced445eSLinus Walleij 
625f1d11f39SLinus Walleij 	/* If ->irq_base is zero this will give a linear mapping */
626f1d11f39SLinus Walleij 	ab8500->domain = irq_domain_add_simple(NULL,
627f1d11f39SLinus Walleij 			num_irqs, ab8500->irq_base,
628f1d11f39SLinus Walleij 			&ab8500_irq_ops, ab8500);
62906e589efSLee Jones 
63006e589efSLee Jones 	if (!ab8500->domain) {
63106e589efSLee Jones 		dev_err(ab8500->dev, "Failed to create irqdomain\n");
63206e589efSLee Jones 		return -ENOSYS;
63306e589efSLee Jones 	}
63406e589efSLee Jones 
63506e589efSLee Jones 	return 0;
63662579266SRabin Vincent }
63762579266SRabin Vincent 
638112a80d2SJonas Aaberg int ab8500_suspend(struct ab8500 *ab8500)
639112a80d2SJonas Aaberg {
640112a80d2SJonas Aaberg 	if (atomic_read(&ab8500->transfer_ongoing))
641112a80d2SJonas Aaberg 		return -EINVAL;
642112a80d2SJonas Aaberg 	else
643112a80d2SJonas Aaberg 		return 0;
644112a80d2SJonas Aaberg }
645112a80d2SJonas Aaberg 
646a9e9ce4cSBill Pemberton static struct resource ab8500_gpadc_resources[] = {
64762579266SRabin Vincent 	{
64862579266SRabin Vincent 		.name	= "HW_CONV_END",
64962579266SRabin Vincent 		.start	= AB8500_INT_GP_HW_ADC_CONV_END,
65062579266SRabin Vincent 		.end	= AB8500_INT_GP_HW_ADC_CONV_END,
65162579266SRabin Vincent 		.flags	= IORESOURCE_IRQ,
65262579266SRabin Vincent 	},
65362579266SRabin Vincent 	{
65462579266SRabin Vincent 		.name	= "SW_CONV_END",
65562579266SRabin Vincent 		.start	= AB8500_INT_GP_SW_ADC_CONV_END,
65662579266SRabin Vincent 		.end	= AB8500_INT_GP_SW_ADC_CONV_END,
65762579266SRabin Vincent 		.flags	= IORESOURCE_IRQ,
65862579266SRabin Vincent 	},
65962579266SRabin Vincent };
66062579266SRabin Vincent 
661*4b106fb9SLee Jones static struct resource ab8505_gpadc_resources[] = {
662c0eda9aeSLee Jones 	{
663c0eda9aeSLee Jones 		.name	= "SW_CONV_END",
664c0eda9aeSLee Jones 		.start	= AB8500_INT_GP_SW_ADC_CONV_END,
665c0eda9aeSLee Jones 		.end	= AB8500_INT_GP_SW_ADC_CONV_END,
666c0eda9aeSLee Jones 		.flags	= IORESOURCE_IRQ,
667c0eda9aeSLee Jones 	},
668c0eda9aeSLee Jones };
669c0eda9aeSLee Jones 
670a9e9ce4cSBill Pemberton static struct resource ab8500_rtc_resources[] = {
67162579266SRabin Vincent 	{
67262579266SRabin Vincent 		.name	= "60S",
67362579266SRabin Vincent 		.start	= AB8500_INT_RTC_60S,
67462579266SRabin Vincent 		.end	= AB8500_INT_RTC_60S,
67562579266SRabin Vincent 		.flags	= IORESOURCE_IRQ,
67662579266SRabin Vincent 	},
67762579266SRabin Vincent 	{
67862579266SRabin Vincent 		.name	= "ALARM",
67962579266SRabin Vincent 		.start	= AB8500_INT_RTC_ALARM,
68062579266SRabin Vincent 		.end	= AB8500_INT_RTC_ALARM,
68162579266SRabin Vincent 		.flags	= IORESOURCE_IRQ,
68262579266SRabin Vincent 	},
68362579266SRabin Vincent };
68462579266SRabin Vincent 
685a9e9ce4cSBill Pemberton static struct resource ab8500_poweronkey_db_resources[] = {
68677686517SSundar R Iyer 	{
68777686517SSundar R Iyer 		.name	= "ONKEY_DBF",
68877686517SSundar R Iyer 		.start	= AB8500_INT_PON_KEY1DB_F,
68977686517SSundar R Iyer 		.end	= AB8500_INT_PON_KEY1DB_F,
69077686517SSundar R Iyer 		.flags	= IORESOURCE_IRQ,
69177686517SSundar R Iyer 	},
69277686517SSundar R Iyer 	{
69377686517SSundar R Iyer 		.name	= "ONKEY_DBR",
69477686517SSundar R Iyer 		.start	= AB8500_INT_PON_KEY1DB_R,
69577686517SSundar R Iyer 		.end	= AB8500_INT_PON_KEY1DB_R,
69677686517SSundar R Iyer 		.flags	= IORESOURCE_IRQ,
69777686517SSundar R Iyer 	},
69877686517SSundar R Iyer };
69977686517SSundar R Iyer 
700a9e9ce4cSBill Pemberton static struct resource ab8500_av_acc_detect_resources[] = {
701e098adedSMattias Wallin 	{
7026af75ecdSLinus Walleij 	       .name = "ACC_DETECT_1DB_F",
7036af75ecdSLinus Walleij 	       .start = AB8500_INT_ACC_DETECT_1DB_F,
7046af75ecdSLinus Walleij 	       .end = AB8500_INT_ACC_DETECT_1DB_F,
705e098adedSMattias Wallin 	       .flags = IORESOURCE_IRQ,
706e098adedSMattias Wallin 	},
707e098adedSMattias Wallin 	{
7086af75ecdSLinus Walleij 	       .name = "ACC_DETECT_1DB_R",
7096af75ecdSLinus Walleij 	       .start = AB8500_INT_ACC_DETECT_1DB_R,
7106af75ecdSLinus Walleij 	       .end = AB8500_INT_ACC_DETECT_1DB_R,
711e098adedSMattias Wallin 	       .flags = IORESOURCE_IRQ,
712e098adedSMattias Wallin 	},
713e098adedSMattias Wallin 	{
7146af75ecdSLinus Walleij 	       .name = "ACC_DETECT_21DB_F",
7156af75ecdSLinus Walleij 	       .start = AB8500_INT_ACC_DETECT_21DB_F,
7166af75ecdSLinus Walleij 	       .end = AB8500_INT_ACC_DETECT_21DB_F,
7176af75ecdSLinus Walleij 	       .flags = IORESOURCE_IRQ,
7186af75ecdSLinus Walleij 	},
7196af75ecdSLinus Walleij 	{
7206af75ecdSLinus Walleij 	       .name = "ACC_DETECT_21DB_R",
7216af75ecdSLinus Walleij 	       .start = AB8500_INT_ACC_DETECT_21DB_R,
7226af75ecdSLinus Walleij 	       .end = AB8500_INT_ACC_DETECT_21DB_R,
7236af75ecdSLinus Walleij 	       .flags = IORESOURCE_IRQ,
7246af75ecdSLinus Walleij 	},
7256af75ecdSLinus Walleij 	{
7266af75ecdSLinus Walleij 	       .name = "ACC_DETECT_22DB_F",
7276af75ecdSLinus Walleij 	       .start = AB8500_INT_ACC_DETECT_22DB_F,
7286af75ecdSLinus Walleij 	       .end = AB8500_INT_ACC_DETECT_22DB_F,
7296af75ecdSLinus Walleij 	       .flags = IORESOURCE_IRQ,
7306af75ecdSLinus Walleij 	},
7316af75ecdSLinus Walleij 	{
7326af75ecdSLinus Walleij 	       .name = "ACC_DETECT_22DB_R",
7336af75ecdSLinus Walleij 	       .start = AB8500_INT_ACC_DETECT_22DB_R,
7346af75ecdSLinus Walleij 	       .end = AB8500_INT_ACC_DETECT_22DB_R,
7356af75ecdSLinus Walleij 	       .flags = IORESOURCE_IRQ,
7366af75ecdSLinus Walleij 	},
7376af75ecdSLinus Walleij };
7386af75ecdSLinus Walleij 
739a9e9ce4cSBill Pemberton static struct resource ab8500_charger_resources[] = {
7406af75ecdSLinus Walleij 	{
741e098adedSMattias Wallin 		.name = "MAIN_CH_UNPLUG_DET",
742e098adedSMattias Wallin 		.start = AB8500_INT_MAIN_CH_UNPLUG_DET,
743e098adedSMattias Wallin 		.end = AB8500_INT_MAIN_CH_UNPLUG_DET,
744e098adedSMattias Wallin 		.flags = IORESOURCE_IRQ,
745e098adedSMattias Wallin 	},
746e098adedSMattias Wallin 	{
747e098adedSMattias Wallin 		.name = "MAIN_CHARGE_PLUG_DET",
748e098adedSMattias Wallin 		.start = AB8500_INT_MAIN_CH_PLUG_DET,
749e098adedSMattias Wallin 		.end = AB8500_INT_MAIN_CH_PLUG_DET,
750e098adedSMattias Wallin 		.flags = IORESOURCE_IRQ,
751e098adedSMattias Wallin 	},
752e098adedSMattias Wallin 	{
753e098adedSMattias Wallin 		.name = "VBUS_DET_R",
754e098adedSMattias Wallin 		.start = AB8500_INT_VBUS_DET_R,
755e098adedSMattias Wallin 		.end = AB8500_INT_VBUS_DET_R,
756e098adedSMattias Wallin 		.flags = IORESOURCE_IRQ,
757e098adedSMattias Wallin 	},
758e098adedSMattias Wallin 	{
7596af75ecdSLinus Walleij 		.name = "VBUS_DET_F",
7606af75ecdSLinus Walleij 		.start = AB8500_INT_VBUS_DET_F,
7616af75ecdSLinus Walleij 		.end = AB8500_INT_VBUS_DET_F,
762e098adedSMattias Wallin 		.flags = IORESOURCE_IRQ,
763e098adedSMattias Wallin 	},
764e098adedSMattias Wallin 	{
7656af75ecdSLinus Walleij 		.name = "USB_LINK_STATUS",
7666af75ecdSLinus Walleij 		.start = AB8500_INT_USB_LINK_STATUS,
7676af75ecdSLinus Walleij 		.end = AB8500_INT_USB_LINK_STATUS,
7686af75ecdSLinus Walleij 		.flags = IORESOURCE_IRQ,
7696af75ecdSLinus Walleij 	},
7706af75ecdSLinus Walleij 	{
771e098adedSMattias Wallin 		.name = "VBUS_OVV",
772e098adedSMattias Wallin 		.start = AB8500_INT_VBUS_OVV,
773e098adedSMattias Wallin 		.end = AB8500_INT_VBUS_OVV,
774e098adedSMattias Wallin 		.flags = IORESOURCE_IRQ,
775e098adedSMattias Wallin 	},
776e098adedSMattias Wallin 	{
7776af75ecdSLinus Walleij 		.name = "USB_CH_TH_PROT_R",
7786af75ecdSLinus Walleij 		.start = AB8500_INT_USB_CH_TH_PROT_R,
7796af75ecdSLinus Walleij 		.end = AB8500_INT_USB_CH_TH_PROT_R,
780e098adedSMattias Wallin 		.flags = IORESOURCE_IRQ,
781e098adedSMattias Wallin 	},
782e098adedSMattias Wallin 	{
7836af75ecdSLinus Walleij 		.name = "USB_CH_TH_PROT_F",
7846af75ecdSLinus Walleij 		.start = AB8500_INT_USB_CH_TH_PROT_F,
7856af75ecdSLinus Walleij 		.end = AB8500_INT_USB_CH_TH_PROT_F,
786e098adedSMattias Wallin 		.flags = IORESOURCE_IRQ,
787e098adedSMattias Wallin 	},
788e098adedSMattias Wallin 	{
7896af75ecdSLinus Walleij 		.name = "MAIN_EXT_CH_NOT_OK",
7906af75ecdSLinus Walleij 		.start = AB8500_INT_MAIN_EXT_CH_NOT_OK,
7916af75ecdSLinus Walleij 		.end = AB8500_INT_MAIN_EXT_CH_NOT_OK,
7926af75ecdSLinus Walleij 		.flags = IORESOURCE_IRQ,
7936af75ecdSLinus Walleij 	},
7946af75ecdSLinus Walleij 	{
7956af75ecdSLinus Walleij 		.name = "MAIN_CH_TH_PROT_R",
7966af75ecdSLinus Walleij 		.start = AB8500_INT_MAIN_CH_TH_PROT_R,
7976af75ecdSLinus Walleij 		.end = AB8500_INT_MAIN_CH_TH_PROT_R,
7986af75ecdSLinus Walleij 		.flags = IORESOURCE_IRQ,
7996af75ecdSLinus Walleij 	},
8006af75ecdSLinus Walleij 	{
8016af75ecdSLinus Walleij 		.name = "MAIN_CH_TH_PROT_F",
8026af75ecdSLinus Walleij 		.start = AB8500_INT_MAIN_CH_TH_PROT_F,
8036af75ecdSLinus Walleij 		.end = AB8500_INT_MAIN_CH_TH_PROT_F,
8046af75ecdSLinus Walleij 		.flags = IORESOURCE_IRQ,
8056af75ecdSLinus Walleij 	},
8066af75ecdSLinus Walleij 	{
8076af75ecdSLinus Walleij 		.name = "USB_CHARGER_NOT_OKR",
808a982362cSBengt Jonsson 		.start = AB8500_INT_USB_CHARGER_NOT_OKR,
809a982362cSBengt Jonsson 		.end = AB8500_INT_USB_CHARGER_NOT_OKR,
8106af75ecdSLinus Walleij 		.flags = IORESOURCE_IRQ,
8116af75ecdSLinus Walleij 	},
8126af75ecdSLinus Walleij 	{
8136af75ecdSLinus Walleij 		.name = "CH_WD_EXP",
8146af75ecdSLinus Walleij 		.start = AB8500_INT_CH_WD_EXP,
8156af75ecdSLinus Walleij 		.end = AB8500_INT_CH_WD_EXP,
8166af75ecdSLinus Walleij 		.flags = IORESOURCE_IRQ,
8176af75ecdSLinus Walleij 	},
81834c11a70SPaer-Olof Haakansson 	{
81934c11a70SPaer-Olof Haakansson 		.name = "VBUS_CH_DROP_END",
82034c11a70SPaer-Olof Haakansson 		.start = AB8500_INT_VBUS_CH_DROP_END,
82134c11a70SPaer-Olof Haakansson 		.end = AB8500_INT_VBUS_CH_DROP_END,
82234c11a70SPaer-Olof Haakansson 		.flags = IORESOURCE_IRQ,
82334c11a70SPaer-Olof Haakansson 	},
8246af75ecdSLinus Walleij };
8256af75ecdSLinus Walleij 
826a9e9ce4cSBill Pemberton static struct resource ab8500_btemp_resources[] = {
8276af75ecdSLinus Walleij 	{
8286af75ecdSLinus Walleij 		.name = "BAT_CTRL_INDB",
8296af75ecdSLinus Walleij 		.start = AB8500_INT_BAT_CTRL_INDB,
8306af75ecdSLinus Walleij 		.end = AB8500_INT_BAT_CTRL_INDB,
831e098adedSMattias Wallin 		.flags = IORESOURCE_IRQ,
832e098adedSMattias Wallin 	},
833e098adedSMattias Wallin 	{
834e098adedSMattias Wallin 		.name = "BTEMP_LOW",
835e098adedSMattias Wallin 		.start = AB8500_INT_BTEMP_LOW,
836e098adedSMattias Wallin 		.end = AB8500_INT_BTEMP_LOW,
837e098adedSMattias Wallin 		.flags = IORESOURCE_IRQ,
838e098adedSMattias Wallin 	},
839e098adedSMattias Wallin 	{
840e098adedSMattias Wallin 		.name = "BTEMP_HIGH",
841e098adedSMattias Wallin 		.start = AB8500_INT_BTEMP_HIGH,
842e098adedSMattias Wallin 		.end = AB8500_INT_BTEMP_HIGH,
843e098adedSMattias Wallin 		.flags = IORESOURCE_IRQ,
844e098adedSMattias Wallin 	},
845e098adedSMattias Wallin 	{
8466af75ecdSLinus Walleij 		.name = "BTEMP_LOW_MEDIUM",
8476af75ecdSLinus Walleij 		.start = AB8500_INT_BTEMP_LOW_MEDIUM,
8486af75ecdSLinus Walleij 		.end = AB8500_INT_BTEMP_LOW_MEDIUM,
849e098adedSMattias Wallin 		.flags = IORESOURCE_IRQ,
850e098adedSMattias Wallin 	},
851e098adedSMattias Wallin 	{
8526af75ecdSLinus Walleij 		.name = "BTEMP_MEDIUM_HIGH",
8536af75ecdSLinus Walleij 		.start = AB8500_INT_BTEMP_MEDIUM_HIGH,
8546af75ecdSLinus Walleij 		.end = AB8500_INT_BTEMP_MEDIUM_HIGH,
855e098adedSMattias Wallin 		.flags = IORESOURCE_IRQ,
856e098adedSMattias Wallin 	},
857e098adedSMattias Wallin };
858e098adedSMattias Wallin 
859a9e9ce4cSBill Pemberton static struct resource ab8500_fg_resources[] = {
8606af75ecdSLinus Walleij 	{
8616af75ecdSLinus Walleij 		.name = "NCONV_ACCU",
8626af75ecdSLinus Walleij 		.start = AB8500_INT_CCN_CONV_ACC,
8636af75ecdSLinus Walleij 		.end = AB8500_INT_CCN_CONV_ACC,
8646af75ecdSLinus Walleij 		.flags = IORESOURCE_IRQ,
8656af75ecdSLinus Walleij 	},
8666af75ecdSLinus Walleij 	{
8676af75ecdSLinus Walleij 		.name = "BATT_OVV",
8686af75ecdSLinus Walleij 		.start = AB8500_INT_BATT_OVV,
8696af75ecdSLinus Walleij 		.end = AB8500_INT_BATT_OVV,
8706af75ecdSLinus Walleij 		.flags = IORESOURCE_IRQ,
8716af75ecdSLinus Walleij 	},
8726af75ecdSLinus Walleij 	{
8736af75ecdSLinus Walleij 		.name = "LOW_BAT_F",
8746af75ecdSLinus Walleij 		.start = AB8500_INT_LOW_BAT_F,
8756af75ecdSLinus Walleij 		.end = AB8500_INT_LOW_BAT_F,
8766af75ecdSLinus Walleij 		.flags = IORESOURCE_IRQ,
8776af75ecdSLinus Walleij 	},
8786af75ecdSLinus Walleij 	{
8796af75ecdSLinus Walleij 		.name = "LOW_BAT_R",
8806af75ecdSLinus Walleij 		.start = AB8500_INT_LOW_BAT_R,
8816af75ecdSLinus Walleij 		.end = AB8500_INT_LOW_BAT_R,
8826af75ecdSLinus Walleij 		.flags = IORESOURCE_IRQ,
8836af75ecdSLinus Walleij 	},
8846af75ecdSLinus Walleij 	{
8856af75ecdSLinus Walleij 		.name = "CC_INT_CALIB",
8866af75ecdSLinus Walleij 		.start = AB8500_INT_CC_INT_CALIB,
8876af75ecdSLinus Walleij 		.end = AB8500_INT_CC_INT_CALIB,
8886af75ecdSLinus Walleij 		.flags = IORESOURCE_IRQ,
8896af75ecdSLinus Walleij 	},
890a982362cSBengt Jonsson 	{
891a982362cSBengt Jonsson 		.name = "CCEOC",
892a982362cSBengt Jonsson 		.start = AB8500_INT_CCEOC,
893a982362cSBengt Jonsson 		.end = AB8500_INT_CCEOC,
894a982362cSBengt Jonsson 		.flags = IORESOURCE_IRQ,
895a982362cSBengt Jonsson 	},
8966af75ecdSLinus Walleij };
8976af75ecdSLinus Walleij 
898a9e9ce4cSBill Pemberton static struct resource ab8500_chargalg_resources[] = {};
8996af75ecdSLinus Walleij 
900df720647SAxel Lin #ifdef CONFIG_DEBUG_FS
901a9e9ce4cSBill Pemberton static struct resource ab8500_debug_resources[] = {
902e098adedSMattias Wallin 	{
903e098adedSMattias Wallin 		.name	= "IRQ_FIRST",
904e098adedSMattias Wallin 		.start	= AB8500_INT_MAIN_EXT_CH_NOT_OK,
905e098adedSMattias Wallin 		.end	= AB8500_INT_MAIN_EXT_CH_NOT_OK,
906e098adedSMattias Wallin 		.flags	= IORESOURCE_IRQ,
907e098adedSMattias Wallin 	},
908e098adedSMattias Wallin 	{
909e098adedSMattias Wallin 		.name	= "IRQ_LAST",
910a982362cSBengt Jonsson 		.start	= AB8500_INT_XTAL32K_KO,
911a982362cSBengt Jonsson 		.end	= AB8500_INT_XTAL32K_KO,
912e098adedSMattias Wallin 		.flags	= IORESOURCE_IRQ,
913e098adedSMattias Wallin 	},
914e098adedSMattias Wallin };
915df720647SAxel Lin #endif
916e098adedSMattias Wallin 
917a9e9ce4cSBill Pemberton static struct resource ab8500_usb_resources[] = {
918e098adedSMattias Wallin 	{
919e098adedSMattias Wallin 		.name = "ID_WAKEUP_R",
920e098adedSMattias Wallin 		.start = AB8500_INT_ID_WAKEUP_R,
921e098adedSMattias Wallin 		.end = AB8500_INT_ID_WAKEUP_R,
922e098adedSMattias Wallin 		.flags = IORESOURCE_IRQ,
923e098adedSMattias Wallin 	},
924e098adedSMattias Wallin 	{
925e098adedSMattias Wallin 		.name = "ID_WAKEUP_F",
926e098adedSMattias Wallin 		.start = AB8500_INT_ID_WAKEUP_F,
927e098adedSMattias Wallin 		.end = AB8500_INT_ID_WAKEUP_F,
928e098adedSMattias Wallin 		.flags = IORESOURCE_IRQ,
929e098adedSMattias Wallin 	},
930e098adedSMattias Wallin 	{
931e098adedSMattias Wallin 		.name = "VBUS_DET_F",
932e098adedSMattias Wallin 		.start = AB8500_INT_VBUS_DET_F,
933e098adedSMattias Wallin 		.end = AB8500_INT_VBUS_DET_F,
934e098adedSMattias Wallin 		.flags = IORESOURCE_IRQ,
935e098adedSMattias Wallin 	},
936e098adedSMattias Wallin 	{
937e098adedSMattias Wallin 		.name = "VBUS_DET_R",
938e098adedSMattias Wallin 		.start = AB8500_INT_VBUS_DET_R,
939e098adedSMattias Wallin 		.end = AB8500_INT_VBUS_DET_R,
940e098adedSMattias Wallin 		.flags = IORESOURCE_IRQ,
941e098adedSMattias Wallin 	},
94292d50a41SMattias Wallin 	{
94392d50a41SMattias Wallin 		.name = "USB_LINK_STATUS",
94492d50a41SMattias Wallin 		.start = AB8500_INT_USB_LINK_STATUS,
94592d50a41SMattias Wallin 		.end = AB8500_INT_USB_LINK_STATUS,
94692d50a41SMattias Wallin 		.flags = IORESOURCE_IRQ,
94792d50a41SMattias Wallin 	},
9486af75ecdSLinus Walleij 	{
9496af75ecdSLinus Walleij 		.name = "USB_ADP_PROBE_PLUG",
9506af75ecdSLinus Walleij 		.start = AB8500_INT_ADP_PROBE_PLUG,
9516af75ecdSLinus Walleij 		.end = AB8500_INT_ADP_PROBE_PLUG,
9526af75ecdSLinus Walleij 		.flags = IORESOURCE_IRQ,
9536af75ecdSLinus Walleij 	},
9546af75ecdSLinus Walleij 	{
9556af75ecdSLinus Walleij 		.name = "USB_ADP_PROBE_UNPLUG",
9566af75ecdSLinus Walleij 		.start = AB8500_INT_ADP_PROBE_UNPLUG,
9576af75ecdSLinus Walleij 		.end = AB8500_INT_ADP_PROBE_UNPLUG,
9586af75ecdSLinus Walleij 		.flags = IORESOURCE_IRQ,
9596af75ecdSLinus Walleij 	},
960e098adedSMattias Wallin };
961e098adedSMattias Wallin 
962a9e9ce4cSBill Pemberton static struct resource ab8505_iddet_resources[] = {
96344f72e53SVirupax Sadashivpetimath 	{
96444f72e53SVirupax Sadashivpetimath 		.name  = "KeyDeglitch",
96544f72e53SVirupax Sadashivpetimath 		.start = AB8505_INT_KEYDEGLITCH,
96644f72e53SVirupax Sadashivpetimath 		.end   = AB8505_INT_KEYDEGLITCH,
96744f72e53SVirupax Sadashivpetimath 		.flags = IORESOURCE_IRQ,
96844f72e53SVirupax Sadashivpetimath 	},
96944f72e53SVirupax Sadashivpetimath 	{
97044f72e53SVirupax Sadashivpetimath 		.name  = "KP",
97144f72e53SVirupax Sadashivpetimath 		.start = AB8505_INT_KP,
97244f72e53SVirupax Sadashivpetimath 		.end   = AB8505_INT_KP,
97344f72e53SVirupax Sadashivpetimath 		.flags = IORESOURCE_IRQ,
97444f72e53SVirupax Sadashivpetimath 	},
97544f72e53SVirupax Sadashivpetimath 	{
97644f72e53SVirupax Sadashivpetimath 		.name  = "IKP",
97744f72e53SVirupax Sadashivpetimath 		.start = AB8505_INT_IKP,
97844f72e53SVirupax Sadashivpetimath 		.end   = AB8505_INT_IKP,
97944f72e53SVirupax Sadashivpetimath 		.flags = IORESOURCE_IRQ,
98044f72e53SVirupax Sadashivpetimath 	},
98144f72e53SVirupax Sadashivpetimath 	{
98244f72e53SVirupax Sadashivpetimath 		.name  = "IKR",
98344f72e53SVirupax Sadashivpetimath 		.start = AB8505_INT_IKR,
98444f72e53SVirupax Sadashivpetimath 		.end   = AB8505_INT_IKR,
98544f72e53SVirupax Sadashivpetimath 		.flags = IORESOURCE_IRQ,
98644f72e53SVirupax Sadashivpetimath 	},
98744f72e53SVirupax Sadashivpetimath 	{
98844f72e53SVirupax Sadashivpetimath 		.name  = "KeyStuck",
98944f72e53SVirupax Sadashivpetimath 		.start = AB8505_INT_KEYSTUCK,
99044f72e53SVirupax Sadashivpetimath 		.end   = AB8505_INT_KEYSTUCK,
99144f72e53SVirupax Sadashivpetimath 		.flags = IORESOURCE_IRQ,
99244f72e53SVirupax Sadashivpetimath 	},
99344f72e53SVirupax Sadashivpetimath };
99444f72e53SVirupax Sadashivpetimath 
995a9e9ce4cSBill Pemberton static struct resource ab8500_temp_resources[] = {
996e098adedSMattias Wallin 	{
997151621a7SHongbo Zhang 		.name  = "ABX500_TEMP_WARM",
998e098adedSMattias Wallin 		.start = AB8500_INT_TEMP_WARM,
999e098adedSMattias Wallin 		.end   = AB8500_INT_TEMP_WARM,
1000e098adedSMattias Wallin 		.flags = IORESOURCE_IRQ,
1001e098adedSMattias Wallin 	},
1002e098adedSMattias Wallin };
1003e098adedSMattias Wallin 
1004a9e9ce4cSBill Pemberton static struct mfd_cell ab8500_bm_devs[] = {
10056ef9418cSRickard Andersson 	{
10066ef9418cSRickard Andersson 		.name = "ab8500-charger",
10074aef72dbSRajanikanth H.V 		.of_compatible = "stericsson,ab8500-charger",
10086ef9418cSRickard Andersson 		.num_resources = ARRAY_SIZE(ab8500_charger_resources),
10096ef9418cSRickard Andersson 		.resources = ab8500_charger_resources,
10104aef72dbSRajanikanth H.V 		.platform_data = &ab8500_bm_data,
10114aef72dbSRajanikanth H.V 		.pdata_size = sizeof(ab8500_bm_data),
10126ef9418cSRickard Andersson 	},
10136ef9418cSRickard Andersson 	{
10146ef9418cSRickard Andersson 		.name = "ab8500-btemp",
1015bd9e8ab2SRajanikanth H.V 		.of_compatible = "stericsson,ab8500-btemp",
10166ef9418cSRickard Andersson 		.num_resources = ARRAY_SIZE(ab8500_btemp_resources),
10176ef9418cSRickard Andersson 		.resources = ab8500_btemp_resources,
1018bd9e8ab2SRajanikanth H.V 		.platform_data = &ab8500_bm_data,
1019bd9e8ab2SRajanikanth H.V 		.pdata_size = sizeof(ab8500_bm_data),
10206ef9418cSRickard Andersson 	},
10216ef9418cSRickard Andersson 	{
10226ef9418cSRickard Andersson 		.name = "ab8500-fg",
1023e0f1abebSRajanikanth H.V 		.of_compatible = "stericsson,ab8500-fg",
10246ef9418cSRickard Andersson 		.num_resources = ARRAY_SIZE(ab8500_fg_resources),
10256ef9418cSRickard Andersson 		.resources = ab8500_fg_resources,
1026e0f1abebSRajanikanth H.V 		.platform_data = &ab8500_bm_data,
1027e0f1abebSRajanikanth H.V 		.pdata_size = sizeof(ab8500_bm_data),
10286ef9418cSRickard Andersson 	},
10296ef9418cSRickard Andersson 	{
10306ef9418cSRickard Andersson 		.name = "ab8500-chargalg",
1031a12810abSRajanikanth H.V 		.of_compatible = "stericsson,ab8500-chargalg",
10326ef9418cSRickard Andersson 		.num_resources = ARRAY_SIZE(ab8500_chargalg_resources),
10336ef9418cSRickard Andersson 		.resources = ab8500_chargalg_resources,
1034a12810abSRajanikanth H.V 		.platform_data = &ab8500_bm_data,
1035a12810abSRajanikanth H.V 		.pdata_size = sizeof(ab8500_bm_data),
10366ef9418cSRickard Andersson 	},
10376ef9418cSRickard Andersson };
10386ef9418cSRickard Andersson 
1039a9e9ce4cSBill Pemberton static struct mfd_cell ab8500_devs[] = {
1040*4b106fb9SLee Jones #ifdef CONFIG_DEBUG_FS
1041d6255529SLinus Walleij 	{
1042*4b106fb9SLee Jones 		.name = "ab8500-debug",
1043*4b106fb9SLee Jones 		.of_compatible = "stericsson,ab8500-debug",
1044*4b106fb9SLee Jones 		.num_resources = ARRAY_SIZE(ab8500_debug_resources),
1045*4b106fb9SLee Jones 		.resources = ab8500_debug_resources,
1046*4b106fb9SLee Jones 	},
1047*4b106fb9SLee Jones #endif
1048*4b106fb9SLee Jones 	{
1049*4b106fb9SLee Jones 		.name = "ab8500-sysctrl",
1050*4b106fb9SLee Jones 		.of_compatible = "stericsson,ab8500-sysctrl",
1051*4b106fb9SLee Jones 	},
1052*4b106fb9SLee Jones 	{
1053*4b106fb9SLee Jones 		.name = "ab8500-regulator",
1054*4b106fb9SLee Jones 		.of_compatible = "stericsson,ab8500-regulator",
1055*4b106fb9SLee Jones 	},
1056*4b106fb9SLee Jones 	{
1057*4b106fb9SLee Jones 		.name = "abx500-clk",
1058*4b106fb9SLee Jones 		.of_compatible = "stericsson,abx500-clk",
1059*4b106fb9SLee Jones 	},
1060*4b106fb9SLee Jones 	{
1061*4b106fb9SLee Jones 		.name = "ab8500-gpadc",
1062*4b106fb9SLee Jones 		.num_resources = ARRAY_SIZE(ab8500_gpadc_resources),
1063*4b106fb9SLee Jones 		.resources = ab8500_gpadc_resources,
1064*4b106fb9SLee Jones 	},
1065*4b106fb9SLee Jones 	{
1066*4b106fb9SLee Jones 		.name = "ab8500-rtc",
1067*4b106fb9SLee Jones 		.of_compatible = "stericsson,ab8500-rtc",
1068*4b106fb9SLee Jones 		.num_resources = ARRAY_SIZE(ab8500_rtc_resources),
1069*4b106fb9SLee Jones 		.resources = ab8500_rtc_resources,
1070*4b106fb9SLee Jones 	},
1071*4b106fb9SLee Jones 	{
1072*4b106fb9SLee Jones 		.name = "ab8500-acc-det",
1073*4b106fb9SLee Jones 		.of_compatible = "stericsson,ab8500-acc-det",
1074*4b106fb9SLee Jones 		.num_resources = ARRAY_SIZE(ab8500_av_acc_detect_resources),
1075*4b106fb9SLee Jones 		.resources = ab8500_av_acc_detect_resources,
1076*4b106fb9SLee Jones 	},
1077*4b106fb9SLee Jones 	{
1078*4b106fb9SLee Jones 
1079*4b106fb9SLee Jones 		.name = "ab8500-poweron-key",
1080*4b106fb9SLee Jones 		.of_compatible = "stericsson,ab8500-poweron-key",
1081*4b106fb9SLee Jones 		.num_resources = ARRAY_SIZE(ab8500_poweronkey_db_resources),
1082*4b106fb9SLee Jones 		.resources = ab8500_poweronkey_db_resources,
1083*4b106fb9SLee Jones 	},
1084*4b106fb9SLee Jones 	{
1085*4b106fb9SLee Jones 		.name = "ab8500-pwm",
1086*4b106fb9SLee Jones 		.of_compatible = "stericsson,ab8500-pwm",
1087*4b106fb9SLee Jones 		.id = 1,
1088*4b106fb9SLee Jones 	},
1089*4b106fb9SLee Jones 	{
1090*4b106fb9SLee Jones 		.name = "ab8500-pwm",
1091*4b106fb9SLee Jones 		.of_compatible = "stericsson,ab8500-pwm",
1092*4b106fb9SLee Jones 		.id = 2,
1093*4b106fb9SLee Jones 	},
1094*4b106fb9SLee Jones 	{
1095*4b106fb9SLee Jones 		.name = "ab8500-pwm",
1096*4b106fb9SLee Jones 		.of_compatible = "stericsson,ab8500-pwm",
1097*4b106fb9SLee Jones 		.id = 3,
1098*4b106fb9SLee Jones 	},
1099*4b106fb9SLee Jones 	{
1100*4b106fb9SLee Jones 		.name = "ab8500-leds",
1101*4b106fb9SLee Jones 		.of_compatible = "stericsson,ab8500-leds",
1102*4b106fb9SLee Jones 	},
1103*4b106fb9SLee Jones 	{
1104*4b106fb9SLee Jones 		.name = "ab8500-denc",
1105*4b106fb9SLee Jones 		.of_compatible = "stericsson,ab8500-denc",
1106*4b106fb9SLee Jones 	},
1107*4b106fb9SLee Jones 	{
1108*4b106fb9SLee Jones 		.name = "ab8500-gpio",
1109bad76991SLee Jones 		.of_compatible = "stericsson,ab8500-gpio",
1110d6255529SLinus Walleij 	},
1111d6255529SLinus Walleij 	{
1112*4b106fb9SLee Jones 		.name = "abx500-temp",
1113*4b106fb9SLee Jones 		.of_compatible = "stericsson,abx500-temp",
1114*4b106fb9SLee Jones 		.num_resources = ARRAY_SIZE(ab8500_temp_resources),
1115*4b106fb9SLee Jones 		.resources = ab8500_temp_resources,
1116*4b106fb9SLee Jones 	},
1117*4b106fb9SLee Jones 	{
1118d6255529SLinus Walleij 		.name = "ab8500-usb",
1119d6255529SLinus Walleij 		.num_resources = ARRAY_SIZE(ab8500_usb_resources),
1120d6255529SLinus Walleij 		.resources = ab8500_usb_resources,
1121d6255529SLinus Walleij 	},
112244f72e53SVirupax Sadashivpetimath 	{
112344f72e53SVirupax Sadashivpetimath 		.name = "ab8500-codec",
1124*4b106fb9SLee Jones 	},
1125*4b106fb9SLee Jones };
1126*4b106fb9SLee Jones 
1127*4b106fb9SLee Jones static struct mfd_cell ab9540_devs[] = {
1128*4b106fb9SLee Jones #ifdef CONFIG_DEBUG_FS
1129*4b106fb9SLee Jones 	{
1130*4b106fb9SLee Jones 		.name = "ab8500-debug",
1131*4b106fb9SLee Jones 		.num_resources = ARRAY_SIZE(ab8500_debug_resources),
1132*4b106fb9SLee Jones 		.resources = ab8500_debug_resources,
1133*4b106fb9SLee Jones 	},
1134*4b106fb9SLee Jones #endif
1135*4b106fb9SLee Jones 	{
1136*4b106fb9SLee Jones 		.name = "ab8500-sysctrl",
1137*4b106fb9SLee Jones 	},
1138*4b106fb9SLee Jones 	{
1139*4b106fb9SLee Jones 		.name = "ab8500-regulator",
114044f72e53SVirupax Sadashivpetimath 	},
1141c0eda9aeSLee Jones 	{
1142c0eda9aeSLee Jones 		.name = "ab8500-gpadc",
1143c0eda9aeSLee Jones 		.of_compatible = "stericsson,ab8500-gpadc",
1144c0eda9aeSLee Jones 		.num_resources = ARRAY_SIZE(ab8500_gpadc_resources),
1145c0eda9aeSLee Jones 		.resources = ab8500_gpadc_resources,
1146c0eda9aeSLee Jones 	},
1147*4b106fb9SLee Jones 	{
1148*4b106fb9SLee Jones 		.name = "ab8500-rtc",
1149*4b106fb9SLee Jones 		.num_resources = ARRAY_SIZE(ab8500_rtc_resources),
1150*4b106fb9SLee Jones 		.resources = ab8500_rtc_resources,
1151*4b106fb9SLee Jones 	},
1152*4b106fb9SLee Jones 	{
1153*4b106fb9SLee Jones 		.name = "ab8500-acc-det",
1154*4b106fb9SLee Jones 		.num_resources = ARRAY_SIZE(ab8500_av_acc_detect_resources),
1155*4b106fb9SLee Jones 		.resources = ab8500_av_acc_detect_resources,
1156*4b106fb9SLee Jones 	},
1157*4b106fb9SLee Jones 	{
1158*4b106fb9SLee Jones 		.name = "ab8500-poweron-key",
1159*4b106fb9SLee Jones 		.num_resources = ARRAY_SIZE(ab8500_poweronkey_db_resources),
1160*4b106fb9SLee Jones 		.resources = ab8500_poweronkey_db_resources,
1161*4b106fb9SLee Jones 	},
1162*4b106fb9SLee Jones 	{
1163*4b106fb9SLee Jones 		.name = "ab8500-pwm",
1164*4b106fb9SLee Jones 		.id = 1,
1165*4b106fb9SLee Jones 	},
1166*4b106fb9SLee Jones 	{
1167*4b106fb9SLee Jones 		.name = "ab8500-leds",
1168*4b106fb9SLee Jones 	},
1169*4b106fb9SLee Jones 	{
1170*4b106fb9SLee Jones 		.name = "abx500-temp",
1171*4b106fb9SLee Jones 		.num_resources = ARRAY_SIZE(ab8500_temp_resources),
1172*4b106fb9SLee Jones 		.resources = ab8500_temp_resources,
1173*4b106fb9SLee Jones 	},
1174d6255529SLinus Walleij 	{
1175e64d905eSLee Jones 		.name = "pinctrl-ab9540",
1176e64d905eSLee Jones 		.of_compatible = "stericsson,ab9540-gpio",
1177d6255529SLinus Walleij 	},
1178d6255529SLinus Walleij 	{
1179d6255529SLinus Walleij 		.name = "ab9540-usb",
1180d6255529SLinus Walleij 		.num_resources = ARRAY_SIZE(ab8500_usb_resources),
1181d6255529SLinus Walleij 		.resources = ab8500_usb_resources,
1182d6255529SLinus Walleij 	},
118344f72e53SVirupax Sadashivpetimath 	{
118444f72e53SVirupax Sadashivpetimath 		.name = "ab9540-codec",
118544f72e53SVirupax Sadashivpetimath 	},
1186c0eda9aeSLee Jones 	{
1187c0eda9aeSLee Jones 		.name = "ab-iddet",
1188c0eda9aeSLee Jones 		.num_resources = ARRAY_SIZE(ab8505_iddet_resources),
1189c0eda9aeSLee Jones 		.resources = ab8505_iddet_resources,
1190c0eda9aeSLee Jones 	},
119144f72e53SVirupax Sadashivpetimath };
119244f72e53SVirupax Sadashivpetimath 
1193c0eda9aeSLee Jones /* Device list for ab8505  */
1194c0eda9aeSLee Jones static struct mfd_cell ab8505_devs[] = {
1195*4b106fb9SLee Jones #ifdef CONFIG_DEBUG_FS
1196*4b106fb9SLee Jones 	{
1197*4b106fb9SLee Jones 		.name = "ab8500-debug",
1198*4b106fb9SLee Jones 		.num_resources = ARRAY_SIZE(ab8500_debug_resources),
1199*4b106fb9SLee Jones 		.resources = ab8500_debug_resources,
1200*4b106fb9SLee Jones 	},
1201*4b106fb9SLee Jones #endif
1202*4b106fb9SLee Jones 	{
1203*4b106fb9SLee Jones 		.name = "ab8500-sysctrl",
1204*4b106fb9SLee Jones 	},
1205*4b106fb9SLee Jones 	{
1206*4b106fb9SLee Jones 		.name = "ab8500-regulator",
1207*4b106fb9SLee Jones 	},
1208*4b106fb9SLee Jones 	{
1209*4b106fb9SLee Jones 		.name = "ab8500-gpadc",
1210*4b106fb9SLee Jones 		.num_resources = ARRAY_SIZE(ab8505_gpadc_resources),
1211*4b106fb9SLee Jones 		.resources = ab8505_gpadc_resources,
1212*4b106fb9SLee Jones 	},
1213*4b106fb9SLee Jones 	{
1214*4b106fb9SLee Jones 		.name = "ab8500-rtc",
1215*4b106fb9SLee Jones 		.num_resources = ARRAY_SIZE(ab8500_rtc_resources),
1216*4b106fb9SLee Jones 		.resources = ab8500_rtc_resources,
1217*4b106fb9SLee Jones 	},
1218*4b106fb9SLee Jones 	{
1219*4b106fb9SLee Jones 		.name = "ab8500-acc-det",
1220*4b106fb9SLee Jones 		.num_resources = ARRAY_SIZE(ab8500_av_acc_detect_resources),
1221*4b106fb9SLee Jones 		.resources = ab8500_av_acc_detect_resources,
1222*4b106fb9SLee Jones 	},
1223*4b106fb9SLee Jones 	{
1224*4b106fb9SLee Jones 		.name = "ab8500-poweron-key",
1225*4b106fb9SLee Jones 		.num_resources = ARRAY_SIZE(ab8500_poweronkey_db_resources),
1226*4b106fb9SLee Jones 		.resources = ab8500_poweronkey_db_resources,
1227*4b106fb9SLee Jones 	},
1228*4b106fb9SLee Jones 	{
1229*4b106fb9SLee Jones 		.name = "ab8500-pwm",
1230*4b106fb9SLee Jones 		.id = 1,
1231*4b106fb9SLee Jones 	},
1232*4b106fb9SLee Jones 	{
1233*4b106fb9SLee Jones 		.name = "ab8500-leds",
1234*4b106fb9SLee Jones 	},
1235*4b106fb9SLee Jones 	{
1236*4b106fb9SLee Jones 		.name = "ab8500-gpio",
1237*4b106fb9SLee Jones 	},
1238*4b106fb9SLee Jones 	{
1239*4b106fb9SLee Jones 		.name = "ab8500-usb",
1240*4b106fb9SLee Jones 		.num_resources = ARRAY_SIZE(ab8500_usb_resources),
1241*4b106fb9SLee Jones 		.resources = ab8500_usb_resources,
1242*4b106fb9SLee Jones 	},
1243*4b106fb9SLee Jones 	{
1244*4b106fb9SLee Jones 		.name = "ab8500-codec",
1245*4b106fb9SLee Jones 	},
1246c0eda9aeSLee Jones 	{
1247c0eda9aeSLee Jones 		.name = "ab-iddet",
1248c0eda9aeSLee Jones 		.num_resources = ARRAY_SIZE(ab8505_iddet_resources),
1249c0eda9aeSLee Jones 		.resources = ab8505_iddet_resources,
1250c0eda9aeSLee Jones 	},
1251c0eda9aeSLee Jones };
1252c0eda9aeSLee Jones 
1253c0eda9aeSLee Jones static struct mfd_cell ab8540_devs[] = {
1254*4b106fb9SLee Jones #ifdef CONFIG_DEBUG_FS
1255*4b106fb9SLee Jones 	{
1256*4b106fb9SLee Jones 		.name = "ab8500-debug",
1257*4b106fb9SLee Jones 		.num_resources = ARRAY_SIZE(ab8500_debug_resources),
1258*4b106fb9SLee Jones 		.resources = ab8500_debug_resources,
1259*4b106fb9SLee Jones 	},
1260*4b106fb9SLee Jones #endif
1261*4b106fb9SLee Jones 	{
1262*4b106fb9SLee Jones 		.name = "ab8500-sysctrl",
1263*4b106fb9SLee Jones 	},
1264*4b106fb9SLee Jones 	{
1265*4b106fb9SLee Jones 		.name = "ab8500-regulator",
1266*4b106fb9SLee Jones 	},
1267*4b106fb9SLee Jones 	{
1268*4b106fb9SLee Jones 		.name = "ab8500-gpadc",
1269*4b106fb9SLee Jones 		.num_resources = ARRAY_SIZE(ab8505_gpadc_resources),
1270*4b106fb9SLee Jones 		.resources = ab8505_gpadc_resources,
1271*4b106fb9SLee Jones 	},
1272*4b106fb9SLee Jones 	{
1273*4b106fb9SLee Jones 		.name = "ab8500-rtc",
1274*4b106fb9SLee Jones 		.num_resources = ARRAY_SIZE(ab8500_rtc_resources),
1275*4b106fb9SLee Jones 		.resources = ab8500_rtc_resources,
1276*4b106fb9SLee Jones 	},
1277*4b106fb9SLee Jones 	{
1278*4b106fb9SLee Jones 		.name = "ab8500-acc-det",
1279*4b106fb9SLee Jones 		.num_resources = ARRAY_SIZE(ab8500_av_acc_detect_resources),
1280*4b106fb9SLee Jones 		.resources = ab8500_av_acc_detect_resources,
1281*4b106fb9SLee Jones 	},
1282*4b106fb9SLee Jones 	{
1283*4b106fb9SLee Jones 		.name = "ab8500-poweron-key",
1284*4b106fb9SLee Jones 		.num_resources = ARRAY_SIZE(ab8500_poweronkey_db_resources),
1285*4b106fb9SLee Jones 		.resources = ab8500_poweronkey_db_resources,
1286*4b106fb9SLee Jones 	},
1287*4b106fb9SLee Jones 	{
1288*4b106fb9SLee Jones 		.name = "ab8500-pwm",
1289*4b106fb9SLee Jones 		.id = 1,
1290*4b106fb9SLee Jones 	},
1291*4b106fb9SLee Jones 	{
1292*4b106fb9SLee Jones 		.name = "ab8500-leds",
1293*4b106fb9SLee Jones 	},
1294*4b106fb9SLee Jones 	{
1295*4b106fb9SLee Jones 		.name = "abx500-temp",
1296*4b106fb9SLee Jones 		.num_resources = ARRAY_SIZE(ab8500_temp_resources),
1297*4b106fb9SLee Jones 		.resources = ab8500_temp_resources,
1298*4b106fb9SLee Jones 	},
1299c0eda9aeSLee Jones 	{
1300c0eda9aeSLee Jones 		.name = "ab8500-gpio",
1301c0eda9aeSLee Jones 	},
1302c0eda9aeSLee Jones 	{
1303c0eda9aeSLee Jones 		.name = "ab8540-usb",
1304c0eda9aeSLee Jones 		.num_resources = ARRAY_SIZE(ab8500_usb_resources),
1305c0eda9aeSLee Jones 		.resources = ab8500_usb_resources,
1306c0eda9aeSLee Jones 	},
1307c0eda9aeSLee Jones 	{
1308c0eda9aeSLee Jones 		.name = "ab8540-codec",
1309c0eda9aeSLee Jones 	},
1310c0eda9aeSLee Jones 	{
131144f72e53SVirupax Sadashivpetimath 		.name = "ab-iddet",
131244f72e53SVirupax Sadashivpetimath 		.num_resources = ARRAY_SIZE(ab8505_iddet_resources),
131344f72e53SVirupax Sadashivpetimath 		.resources = ab8505_iddet_resources,
131444f72e53SVirupax Sadashivpetimath 	},
1315d6255529SLinus Walleij };
1316d6255529SLinus Walleij 
1317cca69b67SMattias Wallin static ssize_t show_chip_id(struct device *dev,
1318cca69b67SMattias Wallin 				struct device_attribute *attr, char *buf)
1319cca69b67SMattias Wallin {
1320cca69b67SMattias Wallin 	struct ab8500 *ab8500;
1321cca69b67SMattias Wallin 
1322cca69b67SMattias Wallin 	ab8500 = dev_get_drvdata(dev);
1323cca69b67SMattias Wallin 	return sprintf(buf, "%#x\n", ab8500 ? ab8500->chip_id : -EINVAL);
1324cca69b67SMattias Wallin }
1325cca69b67SMattias Wallin 
1326e5c238c3SMattias Wallin /*
1327e5c238c3SMattias Wallin  * ab8500 has switched off due to (SWITCH_OFF_STATUS):
1328e5c238c3SMattias Wallin  * 0x01 Swoff bit programming
1329e5c238c3SMattias Wallin  * 0x02 Thermal protection activation
1330e5c238c3SMattias Wallin  * 0x04 Vbat lower then BattOk falling threshold
1331e5c238c3SMattias Wallin  * 0x08 Watchdog expired
1332e5c238c3SMattias Wallin  * 0x10 Non presence of 32kHz clock
1333e5c238c3SMattias Wallin  * 0x20 Battery level lower than power on reset threshold
1334e5c238c3SMattias Wallin  * 0x40 Power on key 1 pressed longer than 10 seconds
1335e5c238c3SMattias Wallin  * 0x80 DB8500 thermal shutdown
1336e5c238c3SMattias Wallin  */
1337e5c238c3SMattias Wallin static ssize_t show_switch_off_status(struct device *dev,
1338e5c238c3SMattias Wallin 				struct device_attribute *attr, char *buf)
1339e5c238c3SMattias Wallin {
1340e5c238c3SMattias Wallin 	int ret;
1341e5c238c3SMattias Wallin 	u8 value;
1342e5c238c3SMattias Wallin 	struct ab8500 *ab8500;
1343e5c238c3SMattias Wallin 
1344e5c238c3SMattias Wallin 	ab8500 = dev_get_drvdata(dev);
1345e5c238c3SMattias Wallin 	ret = get_register_interruptible(ab8500, AB8500_RTC,
1346e5c238c3SMattias Wallin 		AB8500_SWITCH_OFF_STATUS, &value);
1347e5c238c3SMattias Wallin 	if (ret < 0)
1348e5c238c3SMattias Wallin 		return ret;
1349e5c238c3SMattias Wallin 	return sprintf(buf, "%#x\n", value);
1350e5c238c3SMattias Wallin }
1351e5c238c3SMattias Wallin 
1352f04a9d8aSRajkumar Kasirajan /* use mask and set to override the register turn_on_stat value */
1353f04a9d8aSRajkumar Kasirajan void ab8500_override_turn_on_stat(u8 mask, u8 set)
1354f04a9d8aSRajkumar Kasirajan {
1355f04a9d8aSRajkumar Kasirajan 	spin_lock(&on_stat_lock);
1356f04a9d8aSRajkumar Kasirajan 	turn_on_stat_mask = mask;
1357f04a9d8aSRajkumar Kasirajan 	turn_on_stat_set = set;
1358f04a9d8aSRajkumar Kasirajan 	spin_unlock(&on_stat_lock);
1359f04a9d8aSRajkumar Kasirajan }
1360f04a9d8aSRajkumar Kasirajan 
1361b4a31037SAndrew Lynn /*
1362b4a31037SAndrew Lynn  * ab8500 has turned on due to (TURN_ON_STATUS):
1363b4a31037SAndrew Lynn  * 0x01 PORnVbat
1364b4a31037SAndrew Lynn  * 0x02 PonKey1dbF
1365b4a31037SAndrew Lynn  * 0x04 PonKey2dbF
1366b4a31037SAndrew Lynn  * 0x08 RTCAlarm
1367b4a31037SAndrew Lynn  * 0x10 MainChDet
1368b4a31037SAndrew Lynn  * 0x20 VbusDet
1369b4a31037SAndrew Lynn  * 0x40 UsbIDDetect
1370b4a31037SAndrew Lynn  * 0x80 Reserved
1371b4a31037SAndrew Lynn  */
1372b4a31037SAndrew Lynn static ssize_t show_turn_on_status(struct device *dev,
1373b4a31037SAndrew Lynn 				struct device_attribute *attr, char *buf)
1374b4a31037SAndrew Lynn {
1375b4a31037SAndrew Lynn 	int ret;
1376b4a31037SAndrew Lynn 	u8 value;
1377b4a31037SAndrew Lynn 	struct ab8500 *ab8500;
1378b4a31037SAndrew Lynn 
1379b4a31037SAndrew Lynn 	ab8500 = dev_get_drvdata(dev);
1380b4a31037SAndrew Lynn 	ret = get_register_interruptible(ab8500, AB8500_SYS_CTRL1_BLOCK,
1381b4a31037SAndrew Lynn 		AB8500_TURN_ON_STATUS, &value);
1382b4a31037SAndrew Lynn 	if (ret < 0)
1383b4a31037SAndrew Lynn 		return ret;
1384f04a9d8aSRajkumar Kasirajan 
1385f04a9d8aSRajkumar Kasirajan 	/*
1386f04a9d8aSRajkumar Kasirajan 	 * In L9540, turn_on_status register is not updated correctly if
1387f04a9d8aSRajkumar Kasirajan 	 * the device is rebooted with AC/USB charger connected. Due to
1388f04a9d8aSRajkumar Kasirajan 	 * this, the device boots android instead of entering into charge
1389f04a9d8aSRajkumar Kasirajan 	 * only mode. Read the AC/USB status register to detect the charger
1390f04a9d8aSRajkumar Kasirajan 	 * presence and update the turn on status manually.
1391f04a9d8aSRajkumar Kasirajan 	 */
1392f04a9d8aSRajkumar Kasirajan 	if (is_ab9540(ab8500)) {
1393f04a9d8aSRajkumar Kasirajan 		spin_lock(&on_stat_lock);
1394f04a9d8aSRajkumar Kasirajan 		value = (value & turn_on_stat_mask) | turn_on_stat_set;
1395f04a9d8aSRajkumar Kasirajan 		spin_unlock(&on_stat_lock);
1396f04a9d8aSRajkumar Kasirajan 	}
1397f04a9d8aSRajkumar Kasirajan 
1398b4a31037SAndrew Lynn 	return sprintf(buf, "%#x\n", value);
1399b4a31037SAndrew Lynn }
1400b4a31037SAndrew Lynn 
1401d6255529SLinus Walleij static ssize_t show_ab9540_dbbrstn(struct device *dev,
1402d6255529SLinus Walleij 				struct device_attribute *attr, char *buf)
1403d6255529SLinus Walleij {
1404d6255529SLinus Walleij 	struct ab8500 *ab8500;
1405d6255529SLinus Walleij 	int ret;
1406d6255529SLinus Walleij 	u8 value;
1407d6255529SLinus Walleij 
1408d6255529SLinus Walleij 	ab8500 = dev_get_drvdata(dev);
1409d6255529SLinus Walleij 
1410d6255529SLinus Walleij 	ret = get_register_interruptible(ab8500, AB8500_REGU_CTRL2,
1411d6255529SLinus Walleij 		AB9540_MODEM_CTRL2_REG, &value);
1412d6255529SLinus Walleij 	if (ret < 0)
1413d6255529SLinus Walleij 		return ret;
1414d6255529SLinus Walleij 
1415d6255529SLinus Walleij 	return sprintf(buf, "%d\n",
1416d6255529SLinus Walleij 			(value & AB9540_MODEM_CTRL2_SWDBBRSTN_BIT) ? 1 : 0);
1417d6255529SLinus Walleij }
1418d6255529SLinus Walleij 
1419d6255529SLinus Walleij static ssize_t store_ab9540_dbbrstn(struct device *dev,
1420d6255529SLinus Walleij 	struct device_attribute *attr, const char *buf, size_t count)
1421d6255529SLinus Walleij {
1422d6255529SLinus Walleij 	struct ab8500 *ab8500;
1423d6255529SLinus Walleij 	int ret = count;
1424d6255529SLinus Walleij 	int err;
1425d6255529SLinus Walleij 	u8 bitvalues;
1426d6255529SLinus Walleij 
1427d6255529SLinus Walleij 	ab8500 = dev_get_drvdata(dev);
1428d6255529SLinus Walleij 
1429d6255529SLinus Walleij 	if (count > 0) {
1430d6255529SLinus Walleij 		switch (buf[0]) {
1431d6255529SLinus Walleij 		case '0':
1432d6255529SLinus Walleij 			bitvalues = 0;
1433d6255529SLinus Walleij 			break;
1434d6255529SLinus Walleij 		case '1':
1435d6255529SLinus Walleij 			bitvalues = AB9540_MODEM_CTRL2_SWDBBRSTN_BIT;
1436d6255529SLinus Walleij 			break;
1437d6255529SLinus Walleij 		default:
1438d6255529SLinus Walleij 			goto exit;
1439d6255529SLinus Walleij 		}
1440d6255529SLinus Walleij 
1441d6255529SLinus Walleij 		err = mask_and_set_register_interruptible(ab8500,
1442d6255529SLinus Walleij 			AB8500_REGU_CTRL2, AB9540_MODEM_CTRL2_REG,
1443d6255529SLinus Walleij 			AB9540_MODEM_CTRL2_SWDBBRSTN_BIT, bitvalues);
1444d6255529SLinus Walleij 		if (err)
1445d6255529SLinus Walleij 			dev_info(ab8500->dev,
1446d6255529SLinus Walleij 				"Failed to set DBBRSTN %c, err %#x\n",
1447d6255529SLinus Walleij 				buf[0], err);
1448d6255529SLinus Walleij 	}
1449d6255529SLinus Walleij 
1450d6255529SLinus Walleij exit:
1451d6255529SLinus Walleij 	return ret;
1452d6255529SLinus Walleij }
1453d6255529SLinus Walleij 
1454cca69b67SMattias Wallin static DEVICE_ATTR(chip_id, S_IRUGO, show_chip_id, NULL);
1455e5c238c3SMattias Wallin static DEVICE_ATTR(switch_off_status, S_IRUGO, show_switch_off_status, NULL);
1456b4a31037SAndrew Lynn static DEVICE_ATTR(turn_on_status, S_IRUGO, show_turn_on_status, NULL);
1457d6255529SLinus Walleij static DEVICE_ATTR(dbbrstn, S_IRUGO | S_IWUSR,
1458d6255529SLinus Walleij 			show_ab9540_dbbrstn, store_ab9540_dbbrstn);
1459cca69b67SMattias Wallin 
1460cca69b67SMattias Wallin static struct attribute *ab8500_sysfs_entries[] = {
1461cca69b67SMattias Wallin 	&dev_attr_chip_id.attr,
1462e5c238c3SMattias Wallin 	&dev_attr_switch_off_status.attr,
1463b4a31037SAndrew Lynn 	&dev_attr_turn_on_status.attr,
1464cca69b67SMattias Wallin 	NULL,
1465cca69b67SMattias Wallin };
1466cca69b67SMattias Wallin 
1467d6255529SLinus Walleij static struct attribute *ab9540_sysfs_entries[] = {
1468d6255529SLinus Walleij 	&dev_attr_chip_id.attr,
1469d6255529SLinus Walleij 	&dev_attr_switch_off_status.attr,
1470d6255529SLinus Walleij 	&dev_attr_turn_on_status.attr,
1471d6255529SLinus Walleij 	&dev_attr_dbbrstn.attr,
1472d6255529SLinus Walleij 	NULL,
1473d6255529SLinus Walleij };
1474d6255529SLinus Walleij 
1475cca69b67SMattias Wallin static struct attribute_group ab8500_attr_group = {
1476cca69b67SMattias Wallin 	.attrs	= ab8500_sysfs_entries,
1477cca69b67SMattias Wallin };
1478cca69b67SMattias Wallin 
1479d6255529SLinus Walleij static struct attribute_group ab9540_attr_group = {
1480d6255529SLinus Walleij 	.attrs	= ab9540_sysfs_entries,
1481d6255529SLinus Walleij };
1482d6255529SLinus Walleij 
1483f791be49SBill Pemberton static int ab8500_probe(struct platform_device *pdev)
148462579266SRabin Vincent {
1485b04c530cSJonas Aaberg 	static char *switch_off_status[] = {
1486b04c530cSJonas Aaberg 		"Swoff bit programming",
1487b04c530cSJonas Aaberg 		"Thermal protection activation",
1488b04c530cSJonas Aaberg 		"Vbat lower then BattOk falling threshold",
1489b04c530cSJonas Aaberg 		"Watchdog expired",
1490b04c530cSJonas Aaberg 		"Non presence of 32kHz clock",
1491b04c530cSJonas Aaberg 		"Battery level lower than power on reset threshold",
1492b04c530cSJonas Aaberg 		"Power on key 1 pressed longer than 10 seconds",
1493b04c530cSJonas Aaberg 		"DB8500 thermal shutdown"};
1494d28f1db8SLee Jones 	struct ab8500_platform_data *plat = dev_get_platdata(&pdev->dev);
1495d28f1db8SLee Jones 	const struct platform_device_id *platid = platform_get_device_id(pdev);
14966bc4a568SLee Jones 	enum ab8500_version version = AB8500_VERSION_UNDEFINED;
14976bc4a568SLee Jones 	struct device_node *np = pdev->dev.of_node;
1498d28f1db8SLee Jones 	struct ab8500 *ab8500;
1499d28f1db8SLee Jones 	struct resource *resource;
150062579266SRabin Vincent 	int ret;
150162579266SRabin Vincent 	int i;
150247c16975SMattias Wallin 	u8 value;
150362579266SRabin Vincent 
15048c4203cbSLee Jones 	ab8500 = devm_kzalloc(&pdev->dev, sizeof *ab8500, GFP_KERNEL);
1505d28f1db8SLee Jones 	if (!ab8500)
1506d28f1db8SLee Jones 		return -ENOMEM;
1507d28f1db8SLee Jones 
150862579266SRabin Vincent 	if (plat)
150962579266SRabin Vincent 		ab8500->irq_base = plat->irq_base;
151062579266SRabin Vincent 
1511d28f1db8SLee Jones 	ab8500->dev = &pdev->dev;
1512d28f1db8SLee Jones 
1513d28f1db8SLee Jones 	resource = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
15148c4203cbSLee Jones 	if (!resource)
15158c4203cbSLee Jones 		return -ENODEV;
1516d28f1db8SLee Jones 
1517d28f1db8SLee Jones 	ab8500->irq = resource->start;
1518d28f1db8SLee Jones 
1519822672a7SLee Jones 	ab8500->read = ab8500_prcmu_read;
1520822672a7SLee Jones 	ab8500->write = ab8500_prcmu_write;
1521822672a7SLee Jones 	ab8500->write_masked = ab8500_prcmu_write_masked;
1522d28f1db8SLee Jones 
152362579266SRabin Vincent 	mutex_init(&ab8500->lock);
152462579266SRabin Vincent 	mutex_init(&ab8500->irq_lock);
1525112a80d2SJonas Aaberg 	atomic_set(&ab8500->transfer_ongoing, 0);
152662579266SRabin Vincent 
1527d28f1db8SLee Jones 	platform_set_drvdata(pdev, ab8500);
1528d28f1db8SLee Jones 
15296bc4a568SLee Jones 	if (platid)
15306bc4a568SLee Jones 		version = platid->driver_data;
15316bc4a568SLee Jones 
15320f620837SLinus Walleij 	if (version != AB8500_VERSION_UNDEFINED)
15330f620837SLinus Walleij 		ab8500->version = version;
15340f620837SLinus Walleij 	else {
15350f620837SLinus Walleij 		ret = get_register_interruptible(ab8500, AB8500_MISC,
15360f620837SLinus Walleij 			AB8500_IC_NAME_REG, &value);
15370f620837SLinus Walleij 		if (ret < 0)
15388c4203cbSLee Jones 			return ret;
15390f620837SLinus Walleij 
15400f620837SLinus Walleij 		ab8500->version = value;
15410f620837SLinus Walleij 	}
15420f620837SLinus Walleij 
154347c16975SMattias Wallin 	ret = get_register_interruptible(ab8500, AB8500_MISC,
154447c16975SMattias Wallin 		AB8500_REV_REG, &value);
154562579266SRabin Vincent 	if (ret < 0)
15468c4203cbSLee Jones 		return ret;
154762579266SRabin Vincent 
154847c16975SMattias Wallin 	ab8500->chip_id = value;
154962579266SRabin Vincent 
15500f620837SLinus Walleij 	dev_info(ab8500->dev, "detected chip, %s rev. %1x.%1x\n",
15510f620837SLinus Walleij 			ab8500_version_str[ab8500->version],
15520f620837SLinus Walleij 			ab8500->chip_id >> 4,
15530f620837SLinus Walleij 			ab8500->chip_id & 0x0F);
15540f620837SLinus Walleij 
1555d6255529SLinus Walleij 	/* Configure AB8500 or AB9540 IRQ */
1556a982362cSBengt Jonsson 	if (is_ab9540(ab8500) || is_ab8505(ab8500)) {
1557d6255529SLinus Walleij 		ab8500->mask_size = AB9540_NUM_IRQ_REGS;
1558d6255529SLinus Walleij 		ab8500->irq_reg_offset = ab9540_irq_regoffset;
1559d6255529SLinus Walleij 	} else {
15602ced445eSLinus Walleij 		ab8500->mask_size = AB8500_NUM_IRQ_REGS;
15612ced445eSLinus Walleij 		ab8500->irq_reg_offset = ab8500_irq_regoffset;
1562d6255529SLinus Walleij 	}
15638c4203cbSLee Jones 	ab8500->mask = devm_kzalloc(&pdev->dev, ab8500->mask_size, GFP_KERNEL);
15642ced445eSLinus Walleij 	if (!ab8500->mask)
15652ced445eSLinus Walleij 		return -ENOMEM;
15668c4203cbSLee Jones 	ab8500->oldmask = devm_kzalloc(&pdev->dev, ab8500->mask_size, GFP_KERNEL);
15678c4203cbSLee Jones 	if (!ab8500->oldmask)
15688c4203cbSLee Jones 		return -ENOMEM;
15698c4203cbSLee Jones 
1570e5c238c3SMattias Wallin 	/*
1571e5c238c3SMattias Wallin 	 * ab8500 has switched off due to (SWITCH_OFF_STATUS):
1572e5c238c3SMattias Wallin 	 * 0x01 Swoff bit programming
1573e5c238c3SMattias Wallin 	 * 0x02 Thermal protection activation
1574e5c238c3SMattias Wallin 	 * 0x04 Vbat lower then BattOk falling threshold
1575e5c238c3SMattias Wallin 	 * 0x08 Watchdog expired
1576e5c238c3SMattias Wallin 	 * 0x10 Non presence of 32kHz clock
1577e5c238c3SMattias Wallin 	 * 0x20 Battery level lower than power on reset threshold
1578e5c238c3SMattias Wallin 	 * 0x40 Power on key 1 pressed longer than 10 seconds
1579e5c238c3SMattias Wallin 	 * 0x80 DB8500 thermal shutdown
1580e5c238c3SMattias Wallin 	 */
1581e5c238c3SMattias Wallin 
1582e5c238c3SMattias Wallin 	ret = get_register_interruptible(ab8500, AB8500_RTC,
1583e5c238c3SMattias Wallin 		AB8500_SWITCH_OFF_STATUS, &value);
1584e5c238c3SMattias Wallin 	if (ret < 0)
1585e5c238c3SMattias Wallin 		return ret;
1586b04c530cSJonas Aaberg 	dev_info(ab8500->dev, "switch off cause(s) (%#x): ", value);
1587b04c530cSJonas Aaberg 
1588b04c530cSJonas Aaberg 	if (value) {
1589b04c530cSJonas Aaberg 		for (i = 0; i < ARRAY_SIZE(switch_off_status); i++) {
1590b04c530cSJonas Aaberg 			if (value & 1)
1591b04c530cSJonas Aaberg 				printk(KERN_CONT " \"%s\"",
1592b04c530cSJonas Aaberg 				       switch_off_status[i]);
1593b04c530cSJonas Aaberg 			value = value >> 1;
1594b04c530cSJonas Aaberg 
1595b04c530cSJonas Aaberg 		}
1596b04c530cSJonas Aaberg 		printk(KERN_CONT "\n");
1597b04c530cSJonas Aaberg 	} else {
1598b04c530cSJonas Aaberg 		printk(KERN_CONT " None\n");
1599b04c530cSJonas Aaberg 	}
1600e5c238c3SMattias Wallin 
160162579266SRabin Vincent 	if (plat && plat->init)
160262579266SRabin Vincent 		plat->init(ab8500);
1603f04a9d8aSRajkumar Kasirajan 	if (is_ab9540(ab8500)) {
1604f04a9d8aSRajkumar Kasirajan 		ret = get_register_interruptible(ab8500, AB8500_CHARGER,
1605f04a9d8aSRajkumar Kasirajan 			AB8500_CH_USBCH_STAT1_REG, &value);
1606f04a9d8aSRajkumar Kasirajan 		if (ret < 0)
1607f04a9d8aSRajkumar Kasirajan 			return ret;
1608f04a9d8aSRajkumar Kasirajan 		if ((value & VBUS_DET_DBNC1) && (value & VBUS_DET_DBNC100))
1609f04a9d8aSRajkumar Kasirajan 			ab8500_override_turn_on_stat(~AB8500_POW_KEY_1_ON,
1610f04a9d8aSRajkumar Kasirajan 						     AB8500_VBUS_DET);
1611f04a9d8aSRajkumar Kasirajan 	}
161262579266SRabin Vincent 
161362579266SRabin Vincent 	/* Clear and mask all interrupts */
16142ced445eSLinus Walleij 	for (i = 0; i < ab8500->mask_size; i++) {
16150f620837SLinus Walleij 		/*
16160f620837SLinus Walleij 		 * Interrupt register 12 doesn't exist prior to AB8500 version
16170f620837SLinus Walleij 		 * 2.0
16180f620837SLinus Walleij 		 */
16190f620837SLinus Walleij 		if (ab8500->irq_reg_offset[i] == 11 &&
16200f620837SLinus Walleij 				is_ab8500_1p1_or_earlier(ab8500))
162192d50a41SMattias Wallin 			continue;
162262579266SRabin Vincent 
162347c16975SMattias Wallin 		get_register_interruptible(ab8500, AB8500_INTERRUPT,
16242ced445eSLinus Walleij 			AB8500_IT_LATCH1_REG + ab8500->irq_reg_offset[i],
162592d50a41SMattias Wallin 			&value);
162647c16975SMattias Wallin 		set_register_interruptible(ab8500, AB8500_INTERRUPT,
16272ced445eSLinus Walleij 			AB8500_IT_MASK1_REG + ab8500->irq_reg_offset[i], 0xff);
162862579266SRabin Vincent 	}
162962579266SRabin Vincent 
163047c16975SMattias Wallin 	ret = abx500_register_ops(ab8500->dev, &ab8500_ops);
163147c16975SMattias Wallin 	if (ret)
16328c4203cbSLee Jones 		return ret;
163347c16975SMattias Wallin 
16342ced445eSLinus Walleij 	for (i = 0; i < ab8500->mask_size; i++)
163562579266SRabin Vincent 		ab8500->mask[i] = ab8500->oldmask[i] = 0xff;
163662579266SRabin Vincent 
163706e589efSLee Jones 	ret = ab8500_irq_init(ab8500, np);
163862579266SRabin Vincent 	if (ret)
16398c4203cbSLee Jones 		return ret;
164062579266SRabin Vincent 
16417ccfe9b1SMichel JAOUEN 	/*  Activate this feature only in ab9540 */
16427ccfe9b1SMichel JAOUEN 	/*  till tests are done on ab8500 1p2 or later*/
164306e589efSLee Jones 	if (is_ab9540(ab8500)) {
16448c4203cbSLee Jones 		ret = devm_request_threaded_irq(&pdev->dev, ab8500->irq, NULL,
16457ccfe9b1SMichel JAOUEN 						ab8500_hierarchical_irq,
16467ccfe9b1SMichel JAOUEN 						IRQF_ONESHOT | IRQF_NO_SUSPEND,
16477ccfe9b1SMichel JAOUEN 						"ab8500", ab8500);
164806e589efSLee Jones 	}
164906e589efSLee Jones 	else {
16508c4203cbSLee Jones 		ret = devm_request_threaded_irq(&pdev->dev, ab8500->irq, NULL,
16517ccfe9b1SMichel JAOUEN 						ab8500_irq,
16524f079985SMattias Wallin 						IRQF_ONESHOT | IRQF_NO_SUSPEND,
16534f079985SMattias Wallin 						"ab8500", ab8500);
165462579266SRabin Vincent 		if (ret)
16558c4203cbSLee Jones 			return ret;
165662579266SRabin Vincent 	}
165762579266SRabin Vincent 
1658d6255529SLinus Walleij 	if (is_ab9540(ab8500))
1659d6255529SLinus Walleij 		ret = mfd_add_devices(ab8500->dev, 0, ab9540_devs,
1660d6255529SLinus Walleij 				ARRAY_SIZE(ab9540_devs), NULL,
166155692af5SMark Brown 				ab8500->irq_base, ab8500->domain);
1662c0eda9aeSLee Jones 	else if (is_ab8540(ab8500))
1663c0eda9aeSLee Jones 		ret = mfd_add_devices(ab8500->dev, 0, ab8540_devs,
1664c0eda9aeSLee Jones 			      ARRAY_SIZE(ab8540_devs), NULL,
1665c0eda9aeSLee Jones 			      ab8500->irq_base, ab8500->domain);
1666c0eda9aeSLee Jones 	else if (is_ab8505(ab8500))
1667c0eda9aeSLee Jones 		ret = mfd_add_devices(ab8500->dev, 0, ab8505_devs,
1668c0eda9aeSLee Jones 			      ARRAY_SIZE(ab8505_devs), NULL,
1669c0eda9aeSLee Jones 			      ab8500->irq_base, ab8500->domain);
1670d6255529SLinus Walleij 	else
1671549931f9SSundar R Iyer 		ret = mfd_add_devices(ab8500->dev, 0, ab8500_devs,
167244f72e53SVirupax Sadashivpetimath 				ARRAY_SIZE(ab8500_devs), NULL,
167355692af5SMark Brown 				ab8500->irq_base, ab8500->domain);
16746bc4a568SLee Jones 	if (ret)
16758c4203cbSLee Jones 		return ret;
167644f72e53SVirupax Sadashivpetimath 
16776ef9418cSRickard Andersson 	if (!no_bm) {
16786ef9418cSRickard Andersson 		/* Add battery management devices */
16796ef9418cSRickard Andersson 		ret = mfd_add_devices(ab8500->dev, 0, ab8500_bm_devs,
16806ef9418cSRickard Andersson 				      ARRAY_SIZE(ab8500_bm_devs), NULL,
168155692af5SMark Brown 				      ab8500->irq_base, ab8500->domain);
16826ef9418cSRickard Andersson 		if (ret)
16836ef9418cSRickard Andersson 			dev_err(ab8500->dev, "error adding bm devices\n");
16846ef9418cSRickard Andersson 	}
16856ef9418cSRickard Andersson 
1686d6255529SLinus Walleij 	if (is_ab9540(ab8500))
1687d6255529SLinus Walleij 		ret = sysfs_create_group(&ab8500->dev->kobj,
1688d6255529SLinus Walleij 					&ab9540_attr_group);
1689d6255529SLinus Walleij 	else
1690d6255529SLinus Walleij 		ret = sysfs_create_group(&ab8500->dev->kobj,
1691d6255529SLinus Walleij 					&ab8500_attr_group);
1692cca69b67SMattias Wallin 	if (ret)
1693cca69b67SMattias Wallin 		dev_err(ab8500->dev, "error creating sysfs entries\n");
169406e589efSLee Jones 
169562579266SRabin Vincent 	return ret;
169662579266SRabin Vincent }
169762579266SRabin Vincent 
16984740f73fSBill Pemberton static int ab8500_remove(struct platform_device *pdev)
169962579266SRabin Vincent {
1700d28f1db8SLee Jones 	struct ab8500 *ab8500 = platform_get_drvdata(pdev);
1701d28f1db8SLee Jones 
1702d6255529SLinus Walleij 	if (is_ab9540(ab8500))
1703d6255529SLinus Walleij 		sysfs_remove_group(&ab8500->dev->kobj, &ab9540_attr_group);
1704d6255529SLinus Walleij 	else
1705cca69b67SMattias Wallin 		sysfs_remove_group(&ab8500->dev->kobj, &ab8500_attr_group);
170606e589efSLee Jones 
170762579266SRabin Vincent 	mfd_remove_devices(ab8500->dev);
170862579266SRabin Vincent 
170962579266SRabin Vincent 	return 0;
171062579266SRabin Vincent }
171162579266SRabin Vincent 
1712d28f1db8SLee Jones static const struct platform_device_id ab8500_id[] = {
1713d28f1db8SLee Jones 	{ "ab8500-core", AB8500_VERSION_AB8500 },
1714d28f1db8SLee Jones 	{ "ab8505-i2c", AB8500_VERSION_AB8505 },
1715d28f1db8SLee Jones 	{ "ab9540-i2c", AB8500_VERSION_AB9540 },
1716d28f1db8SLee Jones 	{ "ab8540-i2c", AB8500_VERSION_AB8540 },
1717d28f1db8SLee Jones 	{ }
1718d28f1db8SLee Jones };
1719d28f1db8SLee Jones 
1720d28f1db8SLee Jones static struct platform_driver ab8500_core_driver = {
1721d28f1db8SLee Jones 	.driver = {
1722d28f1db8SLee Jones 		.name = "ab8500-core",
1723d28f1db8SLee Jones 		.owner = THIS_MODULE,
1724d28f1db8SLee Jones 	},
1725d28f1db8SLee Jones 	.probe	= ab8500_probe,
172684449216SBill Pemberton 	.remove	= ab8500_remove,
1727d28f1db8SLee Jones 	.id_table = ab8500_id,
1728d28f1db8SLee Jones };
1729d28f1db8SLee Jones 
1730d28f1db8SLee Jones static int __init ab8500_core_init(void)
1731d28f1db8SLee Jones {
1732d28f1db8SLee Jones 	return platform_driver_register(&ab8500_core_driver);
1733d28f1db8SLee Jones }
1734d28f1db8SLee Jones 
1735d28f1db8SLee Jones static void __exit ab8500_core_exit(void)
1736d28f1db8SLee Jones {
1737d28f1db8SLee Jones 	platform_driver_unregister(&ab8500_core_driver);
1738d28f1db8SLee Jones }
1739ba7cbc3eSLee Jones core_initcall(ab8500_core_init);
1740d28f1db8SLee Jones module_exit(ab8500_core_exit);
1741d28f1db8SLee Jones 
1742adceed62SMattias Wallin MODULE_AUTHOR("Mattias Wallin, Srinidhi Kasagar, Rabin Vincent");
174362579266SRabin Vincent MODULE_DESCRIPTION("AB8500 MFD core");
174462579266SRabin Vincent MODULE_LICENSE("GPL v2");
1745