aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2012-03-25 18:56:30 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2012-03-25 18:57:10 -0400
commit7256ecc2b7b91b4212ccc5511cb12254bdf806d0 (patch)
tree1a39b3de03cfc92c5b5dedfb01174d17b49df18a
parent18bbff9f679cd470db66402fdb9c577b34324183 (diff)
parent6ed3e2acc7995625625592abe8cd3383c34a471b (diff)
Merge branch 'sa11x0-mcp' into sa11x0
Conflicts: arch/arm/mach-sa1100/assabet.c arch/arm/mach-sa1100/collie.c arch/arm/mach-sa1100/generic.c arch/arm/mach-sa1100/lart.c arch/arm/mach-sa1100/shannon.c
-rw-r--r--arch/arm/mach-sa1100/assabet.c15
-rw-r--r--arch/arm/mach-sa1100/cerf.c1
-rw-r--r--arch/arm/mach-sa1100/collie.c11
-rw-r--r--arch/arm/mach-sa1100/generic.c13
-rw-r--r--arch/arm/mach-sa1100/generic.h1
-rw-r--r--arch/arm/mach-sa1100/include/mach/mcp.h2
-rw-r--r--arch/arm/mach-sa1100/lart.c1
-rw-r--r--arch/arm/mach-sa1100/shannon.c1
-rw-r--r--arch/arm/mach-sa1100/simpad.c8
-rw-r--r--drivers/mfd/Kconfig5
-rw-r--r--drivers/mfd/mcp-core.c49
-rw-r--r--drivers/mfd/mcp-sa11x0.c198
-rw-r--r--drivers/mfd/ucb1x00-assabet.c46
-rw-r--r--drivers/mfd/ucb1x00-core.c433
-rw-r--r--drivers/mfd/ucb1x00-ts.c39
-rw-r--r--include/linux/mfd/mcp.h14
-rw-r--r--include/linux/mfd/ucb1x00.h38
17 files changed, 518 insertions, 357 deletions
diff --git a/arch/arm/mach-sa1100/assabet.c b/arch/arm/mach-sa1100/assabet.c
index c3f5064df4bf..e708a93a7ddb 100644
--- a/arch/arm/mach-sa1100/assabet.c
+++ b/arch/arm/mach-sa1100/assabet.c
@@ -15,6 +15,7 @@
15#include <linux/errno.h> 15#include <linux/errno.h>
16#include <linux/ioport.h> 16#include <linux/ioport.h>
17#include <linux/serial_core.h> 17#include <linux/serial_core.h>
18#include <linux/mfd/ucb1x00.h>
18#include <linux/mtd/mtd.h> 19#include <linux/mtd/mtd.h>
19#include <linux/mtd/partitions.h> 20#include <linux/mtd/partitions.h>
20#include <linux/delay.h> 21#include <linux/delay.h>
@@ -71,6 +72,12 @@ void ASSABET_BCR_frob(unsigned int mask, unsigned int val)
71 72
72EXPORT_SYMBOL(ASSABET_BCR_frob); 73EXPORT_SYMBOL(ASSABET_BCR_frob);
73 74
75static void assabet_ucb1x00_reset(enum ucb1x00_reset state)
76{
77 if (state == UCB_RST_PROBE)
78 ASSABET_BCR_set(ASSABET_BCR_CODEC_RST);
79}
80
74 81
75/* 82/*
76 * Assabet flash support code. 83 * Assabet flash support code.
@@ -167,9 +174,15 @@ static struct irda_platform_data assabet_irda_data = {
167 .set_speed = assabet_irda_set_speed, 174 .set_speed = assabet_irda_set_speed,
168}; 175};
169 176
177static struct ucb1x00_plat_data assabet_ucb1x00_data = {
178 .reset = assabet_ucb1x00_reset,
179 .gpio_base = -1,
180};
181
170static struct mcp_plat_data assabet_mcp_data = { 182static struct mcp_plat_data assabet_mcp_data = {
171 .mccr0 = MCCR0_ADM, 183 .mccr0 = MCCR0_ADM,
172 .sclk_rate = 11981000, 184 .sclk_rate = 11981000,
185 .codec_pdata = &assabet_ucb1x00_data,
173}; 186};
174 187
175static void assabet_lcd_set_visual(u32 visual) 188static void assabet_lcd_set_visual(u32 visual)
@@ -309,6 +322,8 @@ static void __init assabet_init(void)
309 PPDR |= PPC_TXD3 | PPC_TXD1; 322 PPDR |= PPC_TXD3 | PPC_TXD1;
310 PPSR |= PPC_TXD3 | PPC_TXD1; 323 PPSR |= PPC_TXD3 | PPC_TXD1;
311 324
325 sa11x0_ppc_configure_mcp();
326
312 if (machine_has_neponset()) { 327 if (machine_has_neponset()) {
313 /* 328 /*
314 * Angel sets this, but other bootloaders may not. 329 * Angel sets this, but other bootloaders may not.
diff --git a/arch/arm/mach-sa1100/cerf.c b/arch/arm/mach-sa1100/cerf.c
index c2f9ba3a9578..8015604cfc22 100644
--- a/arch/arm/mach-sa1100/cerf.c
+++ b/arch/arm/mach-sa1100/cerf.c
@@ -121,6 +121,7 @@ static struct mcp_plat_data cerf_mcp_data = {
121 121
122static void __init cerf_init(void) 122static void __init cerf_init(void)
123{ 123{
124 sa11x0_ppc_configure_mcp();
124 platform_add_devices(cerf_devices, ARRAY_SIZE(cerf_devices)); 125 platform_add_devices(cerf_devices, ARRAY_SIZE(cerf_devices));
125 sa11x0_register_mtd(&cerf_flash_data, &cerf_flash_resource, 1); 126 sa11x0_register_mtd(&cerf_flash_data, &cerf_flash_resource, 1);
126 sa11x0_register_mcp(&cerf_mcp_data); 127 sa11x0_register_mcp(&cerf_mcp_data);
diff --git a/arch/arm/mach-sa1100/collie.c b/arch/arm/mach-sa1100/collie.c
index 841041e11815..d4339d639475 100644
--- a/arch/arm/mach-sa1100/collie.c
+++ b/arch/arm/mach-sa1100/collie.c
@@ -22,6 +22,7 @@
22#include <linux/tty.h> 22#include <linux/tty.h>
23#include <linux/delay.h> 23#include <linux/delay.h>
24#include <linux/platform_device.h> 24#include <linux/platform_device.h>
25#include <linux/mfd/ucb1x00.h>
25#include <linux/mtd/mtd.h> 26#include <linux/mtd/mtd.h>
26#include <linux/mtd/partitions.h> 27#include <linux/mtd/partitions.h>
27#include <linux/timer.h> 28#include <linux/timer.h>
@@ -83,10 +84,14 @@ static struct scoop_pcmcia_config collie_pcmcia_config = {
83 .num_devs = 1, 84 .num_devs = 1,
84}; 85};
85 86
87static struct ucb1x00_plat_data collie_ucb1x00_data = {
88 .gpio_base = COLLIE_TC35143_GPIO_BASE,
89};
90
86static struct mcp_plat_data collie_mcp_data = { 91static struct mcp_plat_data collie_mcp_data = {
87 .mccr0 = MCCR0_ADM | MCCR0_ExtClk, 92 .mccr0 = MCCR0_ADM | MCCR0_ExtClk,
88 .sclk_rate = 9216000, 93 .sclk_rate = 9216000,
89 .gpio_base = COLLIE_TC35143_GPIO_BASE, 94 .codec_pdata = &collie_ucb1x00_data,
90}; 95};
91 96
92/* 97/*
@@ -341,6 +346,10 @@ static void __init collie_init(void)
341 346
342 collie_power_resource[0].start = gpio_to_irq(COLLIE_GPIO_AC_IN); 347 collie_power_resource[0].start = gpio_to_irq(COLLIE_GPIO_AC_IN);
343 collie_power_resource[0].end = gpio_to_irq(COLLIE_GPIO_AC_IN); 348 collie_power_resource[0].end = gpio_to_irq(COLLIE_GPIO_AC_IN);
349
350 sa11x0_ppc_configure_mcp();
351
352
344 platform_scoop_config = &collie_pcmcia_config; 353 platform_scoop_config = &collie_pcmcia_config;
345 354
346 ret = platform_add_devices(devices, ARRAY_SIZE(devices)); 355 ret = platform_add_devices(devices, ARRAY_SIZE(devices));
diff --git a/arch/arm/mach-sa1100/generic.c b/arch/arm/mach-sa1100/generic.c
index 0296d69622ac..97e9bdf7f297 100644
--- a/arch/arm/mach-sa1100/generic.c
+++ b/arch/arm/mach-sa1100/generic.c
@@ -195,7 +195,8 @@ static struct platform_device sa11x0uart3_device = {
195 195
196static struct resource sa11x0mcp_resources[] = { 196static struct resource sa11x0mcp_resources[] = {
197 [0] = DEFINE_RES_MEM(__PREG(Ser4MCCR0), SZ_64K), 197 [0] = DEFINE_RES_MEM(__PREG(Ser4MCCR0), SZ_64K),
198 [1] = DEFINE_RES_IRQ(IRQ_Ser4MCP), 198 [1] = DEFINE_RES_MEM(__PREG(Ser4MCCR1), 4),
199 [2] = DEFINE_RES_IRQ(IRQ_Ser4MCP),
199}; 200};
200 201
201static u64 sa11x0mcp_dma_mask = 0xffffffffUL; 202static u64 sa11x0mcp_dma_mask = 0xffffffffUL;
@@ -211,6 +212,16 @@ static struct platform_device sa11x0mcp_device = {
211 .resource = sa11x0mcp_resources, 212 .resource = sa11x0mcp_resources,
212}; 213};
213 214
215void __init sa11x0_ppc_configure_mcp(void)
216{
217 /* Setup the PPC unit for the MCP */
218 PPDR &= ~PPC_RXD4;
219 PPDR |= PPC_TXD4 | PPC_SCLK | PPC_SFRM;
220 PSDR |= PPC_RXD4;
221 PSDR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
222 PPSR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
223}
224
214void sa11x0_register_mcp(struct mcp_plat_data *data) 225void sa11x0_register_mcp(struct mcp_plat_data *data)
215{ 226{
216 sa11x0_register_device(&sa11x0mcp_device, data); 227 sa11x0_register_device(&sa11x0mcp_device, data);
diff --git a/arch/arm/mach-sa1100/generic.h b/arch/arm/mach-sa1100/generic.h
index 5c68be858e0c..9eb3b3cd5a63 100644
--- a/arch/arm/mach-sa1100/generic.h
+++ b/arch/arm/mach-sa1100/generic.h
@@ -36,6 +36,7 @@ struct irda_platform_data;
36void sa11x0_register_irda(struct irda_platform_data *irda); 36void sa11x0_register_irda(struct irda_platform_data *irda);
37 37
38struct mcp_plat_data; 38struct mcp_plat_data;
39void sa11x0_ppc_configure_mcp(void);
39void sa11x0_register_mcp(struct mcp_plat_data *data); 40void sa11x0_register_mcp(struct mcp_plat_data *data);
40 41
41struct sa1100fb_mach_info; 42struct sa1100fb_mach_info;
diff --git a/arch/arm/mach-sa1100/include/mach/mcp.h b/arch/arm/mach-sa1100/include/mach/mcp.h
index ed1a331508a7..4b2860ae3828 100644
--- a/arch/arm/mach-sa1100/include/mach/mcp.h
+++ b/arch/arm/mach-sa1100/include/mach/mcp.h
@@ -16,7 +16,7 @@ struct mcp_plat_data {
16 u32 mccr0; 16 u32 mccr0;
17 u32 mccr1; 17 u32 mccr1;
18 unsigned int sclk_rate; 18 unsigned int sclk_rate;
19 int gpio_base; 19 void *codec_pdata;
20}; 20};
21 21
22#endif 22#endif
diff --git a/arch/arm/mach-sa1100/lart.c b/arch/arm/mach-sa1100/lart.c
index 463a322a425b..570f75fb73a2 100644
--- a/arch/arm/mach-sa1100/lart.c
+++ b/arch/arm/mach-sa1100/lart.c
@@ -107,6 +107,7 @@ static void __init lart_init(void)
107 if (inf) 107 if (inf)
108 sa11x0_register_lcd(inf); 108 sa11x0_register_lcd(inf);
109 109
110 sa11x0_ppc_configure_mcp();
110 sa11x0_register_mcp(&lart_mcp_data); 111 sa11x0_register_mcp(&lart_mcp_data);
111} 112}
112 113
diff --git a/arch/arm/mach-sa1100/shannon.c b/arch/arm/mach-sa1100/shannon.c
index 77b2b9b522ac..08bb1228961f 100644
--- a/arch/arm/mach-sa1100/shannon.c
+++ b/arch/arm/mach-sa1100/shannon.c
@@ -72,6 +72,7 @@ static struct sa1100fb_mach_info shannon_lcd_info = {
72 72
73static void __init shannon_init(void) 73static void __init shannon_init(void)
74{ 74{
75 sa11x0_ppc_configure_mcp();
75 sa11x0_register_lcd(&shannon_lcd_info); 76 sa11x0_register_lcd(&shannon_lcd_info);
76 sa11x0_register_mtd(&shannon_flash_data, &shannon_flash_resource, 1); 77 sa11x0_register_mtd(&shannon_flash_data, &shannon_flash_resource, 1);
77 sa11x0_register_mcp(&shannon_mcp_data); 78 sa11x0_register_mcp(&shannon_mcp_data);
diff --git a/arch/arm/mach-sa1100/simpad.c b/arch/arm/mach-sa1100/simpad.c
index cdb9d197c092..3da4c1f11cf5 100644
--- a/arch/arm/mach-sa1100/simpad.c
+++ b/arch/arm/mach-sa1100/simpad.c
@@ -10,6 +10,7 @@
10#include <linux/string.h> 10#include <linux/string.h>
11#include <linux/pm.h> 11#include <linux/pm.h>
12#include <linux/platform_device.h> 12#include <linux/platform_device.h>
13#include <linux/mfd/ucb1x00.h>
13#include <linux/mtd/mtd.h> 14#include <linux/mtd/mtd.h>
14#include <linux/mtd/partitions.h> 15#include <linux/mtd/partitions.h>
15#include <linux/io.h> 16#include <linux/io.h>
@@ -180,10 +181,14 @@ static struct resource simpad_flash_resources [] = {
180 DEFINE_RES_MEM(SA1100_CS1_PHYS, SZ_16M), 181 DEFINE_RES_MEM(SA1100_CS1_PHYS, SZ_16M),
181}; 182};
182 183
184static struct ucb1x00_plat_data simpad_ucb1x00_data = {
185 .gpio_base = SIMPAD_UCB1X00_GPIO_BASE,
186};
187
183static struct mcp_plat_data simpad_mcp_data = { 188static struct mcp_plat_data simpad_mcp_data = {
184 .mccr0 = MCCR0_ADM, 189 .mccr0 = MCCR0_ADM,
185 .sclk_rate = 11981000, 190 .sclk_rate = 11981000,
186 .gpio_base = SIMPAD_UCB1X00_GPIO_BASE, 191 .codec_pdata = &simpad_ucb1x00_data,
187}; 192};
188 193
189 194
@@ -369,6 +374,7 @@ static int __init simpad_init(void)
369 374
370 pm_power_off = simpad_power_off; 375 pm_power_off = simpad_power_off;
371 376
377 sa11x0_ppc_configure_mcp();
372 sa11x0_register_mtd(&simpad_flash_data, simpad_flash_resources, 378 sa11x0_register_mtd(&simpad_flash_data, simpad_flash_resources,
373 ARRAY_SIZE(simpad_flash_resources)); 379 ARRAY_SIZE(simpad_flash_resources));
374 sa11x0_register_mcp(&simpad_mcp_data); 380 sa11x0_register_mcp(&simpad_mcp_data);
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index cd13e9f2f5e6..28a301b28579 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -847,8 +847,9 @@ config MCP_SA11X0
847 847
848# Chip drivers 848# Chip drivers
849config MCP_UCB1200 849config MCP_UCB1200
850 tristate "Support for UCB1200 / UCB1300" 850 bool "Support for UCB1200 / UCB1300"
851 depends on MCP 851 depends on MCP_SA11X0
852 select MCP
852 853
853config MCP_UCB1200_TS 854config MCP_UCB1200_TS
854 tristate "Touchscreen interface support" 855 tristate "Touchscreen interface support"
diff --git a/drivers/mfd/mcp-core.c b/drivers/mfd/mcp-core.c
index 86cc3f7841cd..6acf2e03f2ba 100644
--- a/drivers/mfd/mcp-core.c
+++ b/drivers/mfd/mcp-core.c
@@ -19,7 +19,6 @@
19#include <linux/string.h> 19#include <linux/string.h>
20#include <linux/mfd/mcp.h> 20#include <linux/mfd/mcp.h>
21 21
22#include <mach/dma.h>
23#include <asm/system.h> 22#include <asm/system.h>
24 23
25 24
@@ -48,39 +47,11 @@ static int mcp_bus_remove(struct device *dev)
48 return 0; 47 return 0;
49} 48}
50 49
51static int mcp_bus_suspend(struct device *dev, pm_message_t state)
52{
53 struct mcp *mcp = to_mcp(dev);
54 int ret = 0;
55
56 if (dev->driver) {
57 struct mcp_driver *drv = to_mcp_driver(dev->driver);
58
59 ret = drv->suspend(mcp, state);
60 }
61 return ret;
62}
63
64static int mcp_bus_resume(struct device *dev)
65{
66 struct mcp *mcp = to_mcp(dev);
67 int ret = 0;
68
69 if (dev->driver) {
70 struct mcp_driver *drv = to_mcp_driver(dev->driver);
71
72 ret = drv->resume(mcp);
73 }
74 return ret;
75}
76
77static struct bus_type mcp_bus_type = { 50static struct bus_type mcp_bus_type = {
78 .name = "mcp", 51 .name = "mcp",
79 .match = mcp_bus_match, 52 .match = mcp_bus_match,
80 .probe = mcp_bus_probe, 53 .probe = mcp_bus_probe,
81 .remove = mcp_bus_remove, 54 .remove = mcp_bus_remove,
82 .suspend = mcp_bus_suspend,
83 .resume = mcp_bus_resume,
84}; 55};
85 56
86/** 57/**
@@ -208,6 +179,7 @@ struct mcp *mcp_host_alloc(struct device *parent, size_t size)
208 mcp = kzalloc(sizeof(struct mcp) + size, GFP_KERNEL); 179 mcp = kzalloc(sizeof(struct mcp) + size, GFP_KERNEL);
209 if (mcp) { 180 if (mcp) {
210 spin_lock_init(&mcp->lock); 181 spin_lock_init(&mcp->lock);
182 device_initialize(&mcp->attached_device);
211 mcp->attached_device.parent = parent; 183 mcp->attached_device.parent = parent;
212 mcp->attached_device.bus = &mcp_bus_type; 184 mcp->attached_device.bus = &mcp_bus_type;
213 mcp->attached_device.dma_mask = parent->dma_mask; 185 mcp->attached_device.dma_mask = parent->dma_mask;
@@ -217,18 +189,25 @@ struct mcp *mcp_host_alloc(struct device *parent, size_t size)
217} 189}
218EXPORT_SYMBOL(mcp_host_alloc); 190EXPORT_SYMBOL(mcp_host_alloc);
219 191
220int mcp_host_register(struct mcp *mcp) 192int mcp_host_add(struct mcp *mcp, void *pdata)
221{ 193{
194 mcp->attached_device.platform_data = pdata;
222 dev_set_name(&mcp->attached_device, "mcp0"); 195 dev_set_name(&mcp->attached_device, "mcp0");
223 return device_register(&mcp->attached_device); 196 return device_add(&mcp->attached_device);
197}
198EXPORT_SYMBOL(mcp_host_add);
199
200void mcp_host_del(struct mcp *mcp)
201{
202 device_del(&mcp->attached_device);
224} 203}
225EXPORT_SYMBOL(mcp_host_register); 204EXPORT_SYMBOL(mcp_host_del);
226 205
227void mcp_host_unregister(struct mcp *mcp) 206void mcp_host_free(struct mcp *mcp)
228{ 207{
229 device_unregister(&mcp->attached_device); 208 put_device(&mcp->attached_device);
230} 209}
231EXPORT_SYMBOL(mcp_host_unregister); 210EXPORT_SYMBOL(mcp_host_free);
232 211
233int mcp_driver_register(struct mcp_driver *mcpdrv) 212int mcp_driver_register(struct mcp_driver *mcpdrv)
234{ 213{
diff --git a/drivers/mfd/mcp-sa11x0.c b/drivers/mfd/mcp-sa11x0.c
index 02c53a0766c4..1c0ceacaa1f6 100644
--- a/drivers/mfd/mcp-sa11x0.c
+++ b/drivers/mfd/mcp-sa11x0.c
@@ -13,51 +13,61 @@
13 */ 13 */
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/io.h>
16#include <linux/errno.h> 17#include <linux/errno.h>
17#include <linux/kernel.h> 18#include <linux/kernel.h>
18#include <linux/delay.h> 19#include <linux/delay.h>
19#include <linux/spinlock.h> 20#include <linux/spinlock.h>
20#include <linux/platform_device.h> 21#include <linux/platform_device.h>
22#include <linux/pm.h>
21#include <linux/mfd/mcp.h> 23#include <linux/mfd/mcp.h>
22 24
23#include <mach/dma.h>
24#include <mach/hardware.h> 25#include <mach/hardware.h>
25#include <asm/mach-types.h> 26#include <asm/mach-types.h>
26#include <asm/system.h> 27#include <asm/system.h>
27#include <mach/mcp.h> 28#include <mach/mcp.h>
28 29
29#include <mach/assabet.h> 30#define DRIVER_NAME "sa11x0-mcp"
30
31 31
32struct mcp_sa11x0 { 32struct mcp_sa11x0 {
33 u32 mccr0; 33 void __iomem *base0;
34 u32 mccr1; 34 void __iomem *base1;
35 u32 mccr0;
36 u32 mccr1;
35}; 37};
36 38
39/* Register offsets */
40#define MCCR0(m) ((m)->base0 + 0x00)
41#define MCDR0(m) ((m)->base0 + 0x08)
42#define MCDR1(m) ((m)->base0 + 0x0c)
43#define MCDR2(m) ((m)->base0 + 0x10)
44#define MCSR(m) ((m)->base0 + 0x18)
45#define MCCR1(m) ((m)->base1 + 0x00)
46
37#define priv(mcp) ((struct mcp_sa11x0 *)mcp_priv(mcp)) 47#define priv(mcp) ((struct mcp_sa11x0 *)mcp_priv(mcp))
38 48
39static void 49static void
40mcp_sa11x0_set_telecom_divisor(struct mcp *mcp, unsigned int divisor) 50mcp_sa11x0_set_telecom_divisor(struct mcp *mcp, unsigned int divisor)
41{ 51{
42 unsigned int mccr0; 52 struct mcp_sa11x0 *m = priv(mcp);
43 53
44 divisor /= 32; 54 divisor /= 32;
45 55
46 mccr0 = Ser4MCCR0 & ~0x00007f00; 56 m->mccr0 &= ~0x00007f00;
47 mccr0 |= divisor << 8; 57 m->mccr0 |= divisor << 8;
48 Ser4MCCR0 = mccr0; 58 writel_relaxed(m->mccr0, MCCR0(m));
49} 59}
50 60
51static void 61static void
52mcp_sa11x0_set_audio_divisor(struct mcp *mcp, unsigned int divisor) 62mcp_sa11x0_set_audio_divisor(struct mcp *mcp, unsigned int divisor)
53{ 63{
54 unsigned int mccr0; 64 struct mcp_sa11x0 *m = priv(mcp);
55 65
56 divisor /= 32; 66 divisor /= 32;
57 67
58 mccr0 = Ser4MCCR0 & ~0x0000007f; 68 m->mccr0 &= ~0x0000007f;
59 mccr0 |= divisor; 69 m->mccr0 |= divisor;
60 Ser4MCCR0 = mccr0; 70 writel_relaxed(m->mccr0, MCCR0(m));
61} 71}
62 72
63/* 73/*
@@ -69,14 +79,15 @@ mcp_sa11x0_set_audio_divisor(struct mcp *mcp, unsigned int divisor)
69static void 79static void
70mcp_sa11x0_write(struct mcp *mcp, unsigned int reg, unsigned int val) 80mcp_sa11x0_write(struct mcp *mcp, unsigned int reg, unsigned int val)
71{ 81{
82 struct mcp_sa11x0 *m = priv(mcp);
72 int ret = -ETIME; 83 int ret = -ETIME;
73 int i; 84 int i;
74 85
75 Ser4MCDR2 = reg << 17 | MCDR2_Wr | (val & 0xffff); 86 writel_relaxed(reg << 17 | MCDR2_Wr | (val & 0xffff), MCDR2(m));
76 87
77 for (i = 0; i < 2; i++) { 88 for (i = 0; i < 2; i++) {
78 udelay(mcp->rw_timeout); 89 udelay(mcp->rw_timeout);
79 if (Ser4MCSR & MCSR_CWC) { 90 if (readl_relaxed(MCSR(m)) & MCSR_CWC) {
80 ret = 0; 91 ret = 0;
81 break; 92 break;
82 } 93 }
@@ -95,15 +106,16 @@ mcp_sa11x0_write(struct mcp *mcp, unsigned int reg, unsigned int val)
95static unsigned int 106static unsigned int
96mcp_sa11x0_read(struct mcp *mcp, unsigned int reg) 107mcp_sa11x0_read(struct mcp *mcp, unsigned int reg)
97{ 108{
109 struct mcp_sa11x0 *m = priv(mcp);
98 int ret = -ETIME; 110 int ret = -ETIME;
99 int i; 111 int i;
100 112
101 Ser4MCDR2 = reg << 17 | MCDR2_Rd; 113 writel_relaxed(reg << 17 | MCDR2_Rd, MCDR2(m));
102 114
103 for (i = 0; i < 2; i++) { 115 for (i = 0; i < 2; i++) {
104 udelay(mcp->rw_timeout); 116 udelay(mcp->rw_timeout);
105 if (Ser4MCSR & MCSR_CRC) { 117 if (readl_relaxed(MCSR(m)) & MCSR_CRC) {
106 ret = Ser4MCDR2 & 0xffff; 118 ret = readl_relaxed(MCDR2(m)) & 0xffff;
107 break; 119 break;
108 } 120 }
109 } 121 }
@@ -116,13 +128,19 @@ mcp_sa11x0_read(struct mcp *mcp, unsigned int reg)
116 128
117static void mcp_sa11x0_enable(struct mcp *mcp) 129static void mcp_sa11x0_enable(struct mcp *mcp)
118{ 130{
119 Ser4MCSR = -1; 131 struct mcp_sa11x0 *m = priv(mcp);
120 Ser4MCCR0 |= MCCR0_MCE; 132
133 writel(-1, MCSR(m));
134 m->mccr0 |= MCCR0_MCE;
135 writel_relaxed(m->mccr0, MCCR0(m));
121} 136}
122 137
123static void mcp_sa11x0_disable(struct mcp *mcp) 138static void mcp_sa11x0_disable(struct mcp *mcp)
124{ 139{
125 Ser4MCCR0 &= ~MCCR0_MCE; 140 struct mcp_sa11x0 *m = priv(mcp);
141
142 m->mccr0 &= ~MCCR0_MCE;
143 writel_relaxed(m->mccr0, MCCR0(m));
126} 144}
127 145
128/* 146/*
@@ -137,55 +155,64 @@ static struct mcp_ops mcp_sa11x0 = {
137 .disable = mcp_sa11x0_disable, 155 .disable = mcp_sa11x0_disable,
138}; 156};
139 157
140static int mcp_sa11x0_probe(struct platform_device *pdev) 158static int mcp_sa11x0_probe(struct platform_device *dev)
141{ 159{
142 struct mcp_plat_data *data = pdev->dev.platform_data; 160 struct mcp_plat_data *data = dev->dev.platform_data;
161 struct resource *mem0, *mem1;
162 struct mcp_sa11x0 *m;
143 struct mcp *mcp; 163 struct mcp *mcp;
144 int ret; 164 int ret;
145 165
146 if (!data) 166 if (!data)
147 return -ENODEV; 167 return -ENODEV;
148 168
149 if (!request_mem_region(0x80060000, 0x60, "sa11x0-mcp")) 169 mem0 = platform_get_resource(dev, IORESOURCE_MEM, 0);
150 return -EBUSY; 170 mem1 = platform_get_resource(dev, IORESOURCE_MEM, 1);
171 if (!mem0 || !mem1)
172 return -ENXIO;
173
174 if (!request_mem_region(mem0->start, resource_size(mem0),
175 DRIVER_NAME)) {
176 ret = -EBUSY;
177 goto err_mem0;
178 }
151 179
152 mcp = mcp_host_alloc(&pdev->dev, sizeof(struct mcp_sa11x0)); 180 if (!request_mem_region(mem1->start, resource_size(mem1),
181 DRIVER_NAME)) {
182 ret = -EBUSY;
183 goto err_mem1;
184 }
185
186 mcp = mcp_host_alloc(&dev->dev, sizeof(struct mcp_sa11x0));
153 if (!mcp) { 187 if (!mcp) {
154 ret = -ENOMEM; 188 ret = -ENOMEM;
155 goto release; 189 goto err_alloc;
156 } 190 }
157 191
158 mcp->owner = THIS_MODULE; 192 mcp->owner = THIS_MODULE;
159 mcp->ops = &mcp_sa11x0; 193 mcp->ops = &mcp_sa11x0;
160 mcp->sclk_rate = data->sclk_rate; 194 mcp->sclk_rate = data->sclk_rate;
161 mcp->dma_audio_rd = DMA_Ser4MCP0Rd;
162 mcp->dma_audio_wr = DMA_Ser4MCP0Wr;
163 mcp->dma_telco_rd = DMA_Ser4MCP1Rd;
164 mcp->dma_telco_wr = DMA_Ser4MCP1Wr;
165 mcp->gpio_base = data->gpio_base;
166 195
167 platform_set_drvdata(pdev, mcp); 196 m = priv(mcp);
197 m->mccr0 = data->mccr0 | 0x7f7f;
198 m->mccr1 = data->mccr1;
168 199
169 if (machine_is_assabet()) { 200 m->base0 = ioremap(mem0->start, resource_size(mem0));
170 ASSABET_BCR_set(ASSABET_BCR_CODEC_RST); 201 m->base1 = ioremap(mem1->start, resource_size(mem1));
202 if (!m->base0 || !m->base1) {
203 ret = -ENOMEM;
204 goto err_ioremap;
171 } 205 }
172 206
173 /* 207 platform_set_drvdata(dev, mcp);
174 * Setup the PPC unit correctly.
175 */
176 PPDR &= ~PPC_RXD4;
177 PPDR |= PPC_TXD4 | PPC_SCLK | PPC_SFRM;
178 PSDR |= PPC_RXD4;
179 PSDR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
180 PPSR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
181 208
182 /* 209 /*
183 * Initialise device. Note that we initially 210 * Initialise device. Note that we initially
184 * set the sampling rate to minimum. 211 * set the sampling rate to minimum.
185 */ 212 */
186 Ser4MCSR = -1; 213 writel_relaxed(-1, MCSR(m));
187 Ser4MCCR1 = data->mccr1; 214 writel_relaxed(m->mccr1, MCCR1(m));
188 Ser4MCCR0 = data->mccr0 | 0x7f7f; 215 writel_relaxed(m->mccr0, MCCR0(m));
189 216
190 /* 217 /*
191 * Calculate the read/write timeout (us) from the bit clock 218 * Calculate the read/write timeout (us) from the bit clock
@@ -195,62 +222,90 @@ static int mcp_sa11x0_probe(struct platform_device *pdev)
195 mcp->rw_timeout = (64 * 3 * 1000000 + mcp->sclk_rate - 1) / 222 mcp->rw_timeout = (64 * 3 * 1000000 + mcp->sclk_rate - 1) /
196 mcp->sclk_rate; 223 mcp->sclk_rate;
197 224
198 ret = mcp_host_register(mcp); 225 ret = mcp_host_add(mcp, data->codec_pdata);
199 if (ret == 0) 226 if (ret == 0)
200 goto out; 227 return 0;
201 228
202 release: 229 platform_set_drvdata(dev, NULL);
203 release_mem_region(0x80060000, 0x60);
204 platform_set_drvdata(pdev, NULL);
205 230
206 out: 231 err_ioremap:
232 iounmap(m->base1);
233 iounmap(m->base0);
234 mcp_host_free(mcp);
235 err_alloc:
236 release_mem_region(mem1->start, resource_size(mem1));
237 err_mem1:
238 release_mem_region(mem0->start, resource_size(mem0));
239 err_mem0:
207 return ret; 240 return ret;
208} 241}
209 242
210static int mcp_sa11x0_remove(struct platform_device *dev) 243static int mcp_sa11x0_remove(struct platform_device *dev)
211{ 244{
212 struct mcp *mcp = platform_get_drvdata(dev); 245 struct mcp *mcp = platform_get_drvdata(dev);
246 struct mcp_sa11x0 *m = priv(mcp);
247 struct resource *mem0, *mem1;
248
249 if (m->mccr0 & MCCR0_MCE)
250 dev_warn(&dev->dev,
251 "device left active (missing disable call?)\n");
252
253 mem0 = platform_get_resource(dev, IORESOURCE_MEM, 0);
254 mem1 = platform_get_resource(dev, IORESOURCE_MEM, 1);
213 255
214 platform_set_drvdata(dev, NULL); 256 platform_set_drvdata(dev, NULL);
215 mcp_host_unregister(mcp); 257 mcp_host_del(mcp);
216 release_mem_region(0x80060000, 0x60); 258 iounmap(m->base1);
259 iounmap(m->base0);
260 mcp_host_free(mcp);
261 release_mem_region(mem1->start, resource_size(mem1));
262 release_mem_region(mem0->start, resource_size(mem0));
217 263
218 return 0; 264 return 0;
219} 265}
220 266
221static int mcp_sa11x0_suspend(struct platform_device *dev, pm_message_t state) 267#ifdef CONFIG_PM_SLEEP
268static int mcp_sa11x0_suspend(struct device *dev)
222{ 269{
223 struct mcp *mcp = platform_get_drvdata(dev); 270 struct mcp_sa11x0 *m = priv(dev_get_drvdata(dev));
271
272 if (m->mccr0 & MCCR0_MCE)
273 dev_warn(dev, "device left active (missing disable call?)\n");
224 274
225 priv(mcp)->mccr0 = Ser4MCCR0; 275 writel(m->mccr0 & ~MCCR0_MCE, MCCR0(m));
226 priv(mcp)->mccr1 = Ser4MCCR1;
227 Ser4MCCR0 &= ~MCCR0_MCE;
228 276
229 return 0; 277 return 0;
230} 278}
231 279
232static int mcp_sa11x0_resume(struct platform_device *dev) 280static int mcp_sa11x0_resume(struct device *dev)
233{ 281{
234 struct mcp *mcp = platform_get_drvdata(dev); 282 struct mcp_sa11x0 *m = priv(dev_get_drvdata(dev));
235 283
236 Ser4MCCR1 = priv(mcp)->mccr1; 284 writel_relaxed(m->mccr1, MCCR1(m));
237 Ser4MCCR0 = priv(mcp)->mccr0; 285 writel_relaxed(m->mccr0, MCCR0(m));
238 286
239 return 0; 287 return 0;
240} 288}
241 289#endif
242/* 290
243 * The driver for the SA11x0 MCP port. 291static const struct dev_pm_ops mcp_sa11x0_pm_ops = {
244 */ 292#ifdef CONFIG_PM_SLEEP
245MODULE_ALIAS("platform:sa11x0-mcp"); 293 .suspend = mcp_sa11x0_suspend,
294 .freeze = mcp_sa11x0_suspend,
295 .poweroff = mcp_sa11x0_suspend,
296 .resume_noirq = mcp_sa11x0_resume,
297 .thaw_noirq = mcp_sa11x0_resume,
298 .restore_noirq = mcp_sa11x0_resume,
299#endif
300};
246 301
247static struct platform_driver mcp_sa11x0_driver = { 302static struct platform_driver mcp_sa11x0_driver = {
248 .probe = mcp_sa11x0_probe, 303 .probe = mcp_sa11x0_probe,
249 .remove = mcp_sa11x0_remove, 304 .remove = mcp_sa11x0_remove,
250 .suspend = mcp_sa11x0_suspend,
251 .resume = mcp_sa11x0_resume,
252 .driver = { 305 .driver = {
253 .name = "sa11x0-mcp", 306 .name = DRIVER_NAME,
307 .owner = THIS_MODULE,
308 .pm = &mcp_sa11x0_pm_ops,
254 }, 309 },
255}; 310};
256 311
@@ -259,6 +314,7 @@ static struct platform_driver mcp_sa11x0_driver = {
259 */ 314 */
260module_platform_driver(mcp_sa11x0_driver); 315module_platform_driver(mcp_sa11x0_driver);
261 316
317MODULE_ALIAS("platform:" DRIVER_NAME);
262MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>"); 318MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>");
263MODULE_DESCRIPTION("SA11x0 multimedia communications port driver"); 319MODULE_DESCRIPTION("SA11x0 multimedia communications port driver");
264MODULE_LICENSE("GPL"); 320MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/ucb1x00-assabet.c b/drivers/mfd/ucb1x00-assabet.c
index cea9da60850d..b63c0756a669 100644
--- a/drivers/mfd/ucb1x00-assabet.c
+++ b/drivers/mfd/ucb1x00-assabet.c
@@ -11,14 +11,15 @@
11 */ 11 */
12#include <linux/module.h> 12#include <linux/module.h>
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/device.h>
15#include <linux/err.h>
14#include <linux/fs.h> 16#include <linux/fs.h>
17#include <linux/gpio_keys.h>
18#include <linux/input.h>
19#include <linux/platform_device.h>
15#include <linux/proc_fs.h> 20#include <linux/proc_fs.h>
16#include <linux/device.h>
17#include <linux/mfd/ucb1x00.h> 21#include <linux/mfd/ucb1x00.h>
18 22
19#include <mach/dma.h>
20
21
22#define UCB1X00_ATTR(name,input)\ 23#define UCB1X00_ATTR(name,input)\
23static ssize_t name##_show(struct device *dev, struct device_attribute *attr, \ 24static ssize_t name##_show(struct device *dev, struct device_attribute *attr, \
24 char *buf) \ 25 char *buf) \
@@ -38,14 +39,45 @@ UCB1X00_ATTR(batt_temp, UCB_ADC_INP_AD2);
38 39
39static int ucb1x00_assabet_add(struct ucb1x00_dev *dev) 40static int ucb1x00_assabet_add(struct ucb1x00_dev *dev)
40{ 41{
41 device_create_file(&dev->ucb->dev, &dev_attr_vbatt); 42 struct ucb1x00 *ucb = dev->ucb;
42 device_create_file(&dev->ucb->dev, &dev_attr_vcharger); 43 struct platform_device *pdev;
43 device_create_file(&dev->ucb->dev, &dev_attr_batt_temp); 44 struct gpio_keys_platform_data keys;
45 static struct gpio_keys_button buttons[6];
46 unsigned i;
47
48 memset(buttons, 0, sizeof(buttons));
49 memset(&keys, 0, sizeof(keys));
50
51 for (i = 0; i < ARRAY_SIZE(buttons); i++) {
52 buttons[i].code = BTN_0 + i;
53 buttons[i].gpio = ucb->gpio.base + i;
54 buttons[i].type = EV_KEY;
55 buttons[i].can_disable = true;
56 }
57
58 keys.buttons = buttons;
59 keys.nbuttons = ARRAY_SIZE(buttons);
60 keys.poll_interval = 50;
61 keys.name = "ucb1x00";
62
63 pdev = platform_device_register_data(&ucb->dev, "gpio-keys", -1,
64 &keys, sizeof(keys));
65
66 device_create_file(&ucb->dev, &dev_attr_vbatt);
67 device_create_file(&ucb->dev, &dev_attr_vcharger);
68 device_create_file(&ucb->dev, &dev_attr_batt_temp);
69
70 dev->priv = pdev;
44 return 0; 71 return 0;
45} 72}
46 73
47static void ucb1x00_assabet_remove(struct ucb1x00_dev *dev) 74static void ucb1x00_assabet_remove(struct ucb1x00_dev *dev)
48{ 75{
76 struct platform_device *pdev = dev->priv;
77
78 if (!IS_ERR(pdev))
79 platform_device_unregister(pdev);
80
49 device_remove_file(&dev->ucb->dev, &dev_attr_batt_temp); 81 device_remove_file(&dev->ucb->dev, &dev_attr_batt_temp);
50 device_remove_file(&dev->ucb->dev, &dev_attr_vcharger); 82 device_remove_file(&dev->ucb->dev, &dev_attr_vcharger);
51 device_remove_file(&dev->ucb->dev, &dev_attr_vbatt); 83 device_remove_file(&dev->ucb->dev, &dev_attr_vbatt);
diff --git a/drivers/mfd/ucb1x00-core.c b/drivers/mfd/ucb1x00-core.c
index febc90cdef7e..70f02daeb22a 100644
--- a/drivers/mfd/ucb1x00-core.c
+++ b/drivers/mfd/ucb1x00-core.c
@@ -23,14 +23,12 @@
23#include <linux/init.h> 23#include <linux/init.h>
24#include <linux/errno.h> 24#include <linux/errno.h>
25#include <linux/interrupt.h> 25#include <linux/interrupt.h>
26#include <linux/irq.h>
26#include <linux/device.h> 27#include <linux/device.h>
27#include <linux/mutex.h> 28#include <linux/mutex.h>
28#include <linux/mfd/ucb1x00.h> 29#include <linux/mfd/ucb1x00.h>
30#include <linux/pm.h>
29#include <linux/gpio.h> 31#include <linux/gpio.h>
30#include <linux/semaphore.h>
31
32#include <mach/dma.h>
33#include <mach/hardware.h>
34 32
35static DEFINE_MUTEX(ucb1x00_mutex); 33static DEFINE_MUTEX(ucb1x00_mutex);
36static LIST_HEAD(ucb1x00_drivers); 34static LIST_HEAD(ucb1x00_drivers);
@@ -102,7 +100,7 @@ void ucb1x00_io_write(struct ucb1x00 *ucb, unsigned int set, unsigned int clear)
102 * ucb1x00_enable must have been called to enable the comms 100 * ucb1x00_enable must have been called to enable the comms
103 * before using this function. 101 * before using this function.
104 * 102 *
105 * This function does not take any semaphores or spinlocks. 103 * This function does not take any mutexes or spinlocks.
106 */ 104 */
107unsigned int ucb1x00_io_read(struct ucb1x00 *ucb) 105unsigned int ucb1x00_io_read(struct ucb1x00 *ucb)
108{ 106{
@@ -120,14 +118,22 @@ static void ucb1x00_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
120 else 118 else
121 ucb->io_out &= ~(1 << offset); 119 ucb->io_out &= ~(1 << offset);
122 120
121 ucb1x00_enable(ucb);
123 ucb1x00_reg_write(ucb, UCB_IO_DATA, ucb->io_out); 122 ucb1x00_reg_write(ucb, UCB_IO_DATA, ucb->io_out);
123 ucb1x00_disable(ucb);
124 spin_unlock_irqrestore(&ucb->io_lock, flags); 124 spin_unlock_irqrestore(&ucb->io_lock, flags);
125} 125}
126 126
127static int ucb1x00_gpio_get(struct gpio_chip *chip, unsigned offset) 127static int ucb1x00_gpio_get(struct gpio_chip *chip, unsigned offset)
128{ 128{
129 struct ucb1x00 *ucb = container_of(chip, struct ucb1x00, gpio); 129 struct ucb1x00 *ucb = container_of(chip, struct ucb1x00, gpio);
130 return ucb1x00_reg_read(ucb, UCB_IO_DATA) & (1 << offset); 130 unsigned val;
131
132 ucb1x00_enable(ucb);
133 val = ucb1x00_reg_read(ucb, UCB_IO_DATA);
134 ucb1x00_disable(ucb);
135
136 return val & (1 << offset);
131} 137}
132 138
133static int ucb1x00_gpio_direction_input(struct gpio_chip *chip, unsigned offset) 139static int ucb1x00_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
@@ -137,7 +143,9 @@ static int ucb1x00_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
137 143
138 spin_lock_irqsave(&ucb->io_lock, flags); 144 spin_lock_irqsave(&ucb->io_lock, flags);
139 ucb->io_dir &= ~(1 << offset); 145 ucb->io_dir &= ~(1 << offset);
146 ucb1x00_enable(ucb);
140 ucb1x00_reg_write(ucb, UCB_IO_DIR, ucb->io_dir); 147 ucb1x00_reg_write(ucb, UCB_IO_DIR, ucb->io_dir);
148 ucb1x00_disable(ucb);
141 spin_unlock_irqrestore(&ucb->io_lock, flags); 149 spin_unlock_irqrestore(&ucb->io_lock, flags);
142 150
143 return 0; 151 return 0;
@@ -157,6 +165,7 @@ static int ucb1x00_gpio_direction_output(struct gpio_chip *chip, unsigned offset
157 else 165 else
158 ucb->io_out &= ~mask; 166 ucb->io_out &= ~mask;
159 167
168 ucb1x00_enable(ucb);
160 if (old != ucb->io_out) 169 if (old != ucb->io_out)
161 ucb1x00_reg_write(ucb, UCB_IO_DATA, ucb->io_out); 170 ucb1x00_reg_write(ucb, UCB_IO_DATA, ucb->io_out);
162 171
@@ -164,11 +173,19 @@ static int ucb1x00_gpio_direction_output(struct gpio_chip *chip, unsigned offset
164 ucb->io_dir |= mask; 173 ucb->io_dir |= mask;
165 ucb1x00_reg_write(ucb, UCB_IO_DIR, ucb->io_dir); 174 ucb1x00_reg_write(ucb, UCB_IO_DIR, ucb->io_dir);
166 } 175 }
176 ucb1x00_disable(ucb);
167 spin_unlock_irqrestore(&ucb->io_lock, flags); 177 spin_unlock_irqrestore(&ucb->io_lock, flags);
168 178
169 return 0; 179 return 0;
170} 180}
171 181
182static int ucb1x00_to_irq(struct gpio_chip *chip, unsigned offset)
183{
184 struct ucb1x00 *ucb = container_of(chip, struct ucb1x00, gpio);
185
186 return ucb->irq_base > 0 ? ucb->irq_base + offset : -ENXIO;
187}
188
172/* 189/*
173 * UCB1300 data sheet says we must: 190 * UCB1300 data sheet says we must:
174 * 1. enable ADC => 5us (including reference startup time) 191 * 1. enable ADC => 5us (including reference startup time)
@@ -186,7 +203,7 @@ static int ucb1x00_gpio_direction_output(struct gpio_chip *chip, unsigned offset
186 * Any code wishing to use the ADC converter must call this 203 * Any code wishing to use the ADC converter must call this
187 * function prior to using it. 204 * function prior to using it.
188 * 205 *
189 * This function takes the ADC semaphore to prevent two or more 206 * This function takes the ADC mutex to prevent two or more
190 * concurrent uses, and therefore may sleep. As a result, it 207 * concurrent uses, and therefore may sleep. As a result, it
191 * can only be called from process context, not interrupt 208 * can only be called from process context, not interrupt
192 * context. 209 * context.
@@ -196,7 +213,7 @@ static int ucb1x00_gpio_direction_output(struct gpio_chip *chip, unsigned offset
196 */ 213 */
197void ucb1x00_adc_enable(struct ucb1x00 *ucb) 214void ucb1x00_adc_enable(struct ucb1x00 *ucb)
198{ 215{
199 down(&ucb->adc_sem); 216 mutex_lock(&ucb->adc_mutex);
200 217
201 ucb->adc_cr |= UCB_ADC_ENA; 218 ucb->adc_cr |= UCB_ADC_ENA;
202 219
@@ -218,7 +235,7 @@ void ucb1x00_adc_enable(struct ucb1x00 *ucb)
218 * complete (2 frames max without sync). 235 * complete (2 frames max without sync).
219 * 236 *
220 * If called for a synchronised ADC conversion, it may sleep 237 * If called for a synchronised ADC conversion, it may sleep
221 * with the ADC semaphore held. 238 * with the ADC mutex held.
222 */ 239 */
223unsigned int ucb1x00_adc_read(struct ucb1x00 *ucb, int adc_channel, int sync) 240unsigned int ucb1x00_adc_read(struct ucb1x00 *ucb, int adc_channel, int sync)
224{ 241{
@@ -246,7 +263,7 @@ unsigned int ucb1x00_adc_read(struct ucb1x00 *ucb, int adc_channel, int sync)
246 * ucb1x00_adc_disable - disable the ADC converter 263 * ucb1x00_adc_disable - disable the ADC converter
247 * @ucb: UCB1x00 structure describing chip 264 * @ucb: UCB1x00 structure describing chip
248 * 265 *
249 * Disable the ADC converter and release the ADC semaphore. 266 * Disable the ADC converter and release the ADC mutex.
250 */ 267 */
251void ucb1x00_adc_disable(struct ucb1x00 *ucb) 268void ucb1x00_adc_disable(struct ucb1x00 *ucb)
252{ 269{
@@ -254,7 +271,7 @@ void ucb1x00_adc_disable(struct ucb1x00 *ucb)
254 ucb1x00_reg_write(ucb, UCB_ADC_CR, ucb->adc_cr); 271 ucb1x00_reg_write(ucb, UCB_ADC_CR, ucb->adc_cr);
255 ucb1x00_disable(ucb); 272 ucb1x00_disable(ucb);
256 273
257 up(&ucb->adc_sem); 274 mutex_unlock(&ucb->adc_mutex);
258} 275}
259 276
260/* 277/*
@@ -265,10 +282,9 @@ void ucb1x00_adc_disable(struct ucb1x00 *ucb)
265 * SIBCLK to talk to the chip. We leave the clock running until 282 * SIBCLK to talk to the chip. We leave the clock running until
266 * we have finished processing all interrupts from the chip. 283 * we have finished processing all interrupts from the chip.
267 */ 284 */
268static irqreturn_t ucb1x00_irq(int irqnr, void *devid) 285static void ucb1x00_irq(unsigned int irq, struct irq_desc *desc)
269{ 286{
270 struct ucb1x00 *ucb = devid; 287 struct ucb1x00 *ucb = irq_desc_get_handler_data(desc);
271 struct ucb1x00_irq *irq;
272 unsigned int isr, i; 288 unsigned int isr, i;
273 289
274 ucb1x00_enable(ucb); 290 ucb1x00_enable(ucb);
@@ -276,157 +292,104 @@ static irqreturn_t ucb1x00_irq(int irqnr, void *devid)
276 ucb1x00_reg_write(ucb, UCB_IE_CLEAR, isr); 292 ucb1x00_reg_write(ucb, UCB_IE_CLEAR, isr);
277 ucb1x00_reg_write(ucb, UCB_IE_CLEAR, 0); 293 ucb1x00_reg_write(ucb, UCB_IE_CLEAR, 0);
278 294
279 for (i = 0, irq = ucb->irq_handler; i < 16 && isr; i++, isr >>= 1, irq++) 295 for (i = 0; i < 16 && isr; i++, isr >>= 1, irq++)
280 if (isr & 1 && irq->fn) 296 if (isr & 1)
281 irq->fn(i, irq->devid); 297 generic_handle_irq(ucb->irq_base + i);
282 ucb1x00_disable(ucb); 298 ucb1x00_disable(ucb);
283
284 return IRQ_HANDLED;
285} 299}
286 300
287/** 301static void ucb1x00_irq_update(struct ucb1x00 *ucb, unsigned mask)
288 * ucb1x00_hook_irq - hook a UCB1x00 interrupt
289 * @ucb: UCB1x00 structure describing chip
290 * @idx: interrupt index
291 * @fn: function to call when interrupt is triggered
292 * @devid: device id to pass to interrupt handler
293 *
294 * Hook the specified interrupt. You can only register one handler
295 * for each interrupt source. The interrupt source is not enabled
296 * by this function; use ucb1x00_enable_irq instead.
297 *
298 * Interrupt handlers will be called with other interrupts enabled.
299 *
300 * Returns zero on success, or one of the following errors:
301 * -EINVAL if the interrupt index is invalid
302 * -EBUSY if the interrupt has already been hooked
303 */
304int ucb1x00_hook_irq(struct ucb1x00 *ucb, unsigned int idx, void (*fn)(int, void *), void *devid)
305{ 302{
306 struct ucb1x00_irq *irq; 303 ucb1x00_enable(ucb);
307 int ret = -EINVAL; 304 if (ucb->irq_ris_enbl & mask)
308 305 ucb1x00_reg_write(ucb, UCB_IE_RIS, ucb->irq_ris_enbl &
309 if (idx < 16) { 306 ucb->irq_mask);
310 irq = ucb->irq_handler + idx; 307 if (ucb->irq_fal_enbl & mask)
311 ret = -EBUSY; 308 ucb1x00_reg_write(ucb, UCB_IE_FAL, ucb->irq_fal_enbl &
312 309 ucb->irq_mask);
313 spin_lock_irq(&ucb->lock); 310 ucb1x00_disable(ucb);
314 if (irq->fn == NULL) {
315 irq->devid = devid;
316 irq->fn = fn;
317 ret = 0;
318 }
319 spin_unlock_irq(&ucb->lock);
320 }
321 return ret;
322} 311}
323 312
324/** 313static void ucb1x00_irq_noop(struct irq_data *data)
325 * ucb1x00_enable_irq - enable an UCB1x00 interrupt source
326 * @ucb: UCB1x00 structure describing chip
327 * @idx: interrupt index
328 * @edges: interrupt edges to enable
329 *
330 * Enable the specified interrupt to trigger on %UCB_RISING,
331 * %UCB_FALLING or both edges. The interrupt should have been
332 * hooked by ucb1x00_hook_irq.
333 */
334void ucb1x00_enable_irq(struct ucb1x00 *ucb, unsigned int idx, int edges)
335{ 314{
336 unsigned long flags; 315}
337 316
338 if (idx < 16) { 317static void ucb1x00_irq_mask(struct irq_data *data)
339 spin_lock_irqsave(&ucb->lock, flags); 318{
319 struct ucb1x00 *ucb = irq_data_get_irq_chip_data(data);
320 unsigned mask = 1 << (data->irq - ucb->irq_base);
340 321
341 ucb1x00_enable(ucb); 322 raw_spin_lock(&ucb->irq_lock);
342 if (edges & UCB_RISING) { 323 ucb->irq_mask &= ~mask;
343 ucb->irq_ris_enbl |= 1 << idx; 324 ucb1x00_irq_update(ucb, mask);
344 ucb1x00_reg_write(ucb, UCB_IE_RIS, ucb->irq_ris_enbl); 325 raw_spin_unlock(&ucb->irq_lock);
345 }
346 if (edges & UCB_FALLING) {
347 ucb->irq_fal_enbl |= 1 << idx;
348 ucb1x00_reg_write(ucb, UCB_IE_FAL, ucb->irq_fal_enbl);
349 }
350 ucb1x00_disable(ucb);
351 spin_unlock_irqrestore(&ucb->lock, flags);
352 }
353} 326}
354 327
355/** 328static void ucb1x00_irq_unmask(struct irq_data *data)
356 * ucb1x00_disable_irq - disable an UCB1x00 interrupt source
357 * @ucb: UCB1x00 structure describing chip
358 * @edges: interrupt edges to disable
359 *
360 * Disable the specified interrupt triggering on the specified
361 * (%UCB_RISING, %UCB_FALLING or both) edges.
362 */
363void ucb1x00_disable_irq(struct ucb1x00 *ucb, unsigned int idx, int edges)
364{ 329{
365 unsigned long flags; 330 struct ucb1x00 *ucb = irq_data_get_irq_chip_data(data);
331 unsigned mask = 1 << (data->irq - ucb->irq_base);
366 332
367 if (idx < 16) { 333 raw_spin_lock(&ucb->irq_lock);
368 spin_lock_irqsave(&ucb->lock, flags); 334 ucb->irq_mask |= mask;
369 335 ucb1x00_irq_update(ucb, mask);
370 ucb1x00_enable(ucb); 336 raw_spin_unlock(&ucb->irq_lock);
371 if (edges & UCB_RISING) {
372 ucb->irq_ris_enbl &= ~(1 << idx);
373 ucb1x00_reg_write(ucb, UCB_IE_RIS, ucb->irq_ris_enbl);
374 }
375 if (edges & UCB_FALLING) {
376 ucb->irq_fal_enbl &= ~(1 << idx);
377 ucb1x00_reg_write(ucb, UCB_IE_FAL, ucb->irq_fal_enbl);
378 }
379 ucb1x00_disable(ucb);
380 spin_unlock_irqrestore(&ucb->lock, flags);
381 }
382} 337}
383 338
384/** 339static int ucb1x00_irq_set_type(struct irq_data *data, unsigned int type)
385 * ucb1x00_free_irq - disable and free the specified UCB1x00 interrupt
386 * @ucb: UCB1x00 structure describing chip
387 * @idx: interrupt index
388 * @devid: device id.
389 *
390 * Disable the interrupt source and remove the handler. devid must
391 * match the devid passed when hooking the interrupt.
392 *
393 * Returns zero on success, or one of the following errors:
394 * -EINVAL if the interrupt index is invalid
395 * -ENOENT if devid does not match
396 */
397int ucb1x00_free_irq(struct ucb1x00 *ucb, unsigned int idx, void *devid)
398{ 340{
399 struct ucb1x00_irq *irq; 341 struct ucb1x00 *ucb = irq_data_get_irq_chip_data(data);
400 int ret; 342 unsigned mask = 1 << (data->irq - ucb->irq_base);
401 343
402 if (idx >= 16) 344 raw_spin_lock(&ucb->irq_lock);
403 goto bad; 345 if (type & IRQ_TYPE_EDGE_RISING)
346 ucb->irq_ris_enbl |= mask;
347 else
348 ucb->irq_ris_enbl &= ~mask;
404 349
405 irq = ucb->irq_handler + idx; 350 if (type & IRQ_TYPE_EDGE_FALLING)
406 ret = -ENOENT; 351 ucb->irq_fal_enbl |= mask;
352 else
353 ucb->irq_fal_enbl &= ~mask;
354 if (ucb->irq_mask & mask) {
355 ucb1x00_reg_write(ucb, UCB_IE_RIS, ucb->irq_ris_enbl &
356 ucb->irq_mask);
357 ucb1x00_reg_write(ucb, UCB_IE_FAL, ucb->irq_fal_enbl &
358 ucb->irq_mask);
359 }
360 raw_spin_unlock(&ucb->irq_lock);
407 361
408 spin_lock_irq(&ucb->lock); 362 return 0;
409 if (irq->devid == devid) { 363}
410 ucb->irq_ris_enbl &= ~(1 << idx);
411 ucb->irq_fal_enbl &= ~(1 << idx);
412 364
413 ucb1x00_enable(ucb); 365static int ucb1x00_irq_set_wake(struct irq_data *data, unsigned int on)
414 ucb1x00_reg_write(ucb, UCB_IE_RIS, ucb->irq_ris_enbl); 366{
415 ucb1x00_reg_write(ucb, UCB_IE_FAL, ucb->irq_fal_enbl); 367 struct ucb1x00 *ucb = irq_data_get_irq_chip_data(data);
416 ucb1x00_disable(ucb); 368 struct ucb1x00_plat_data *pdata = ucb->mcp->attached_device.platform_data;
369 unsigned mask = 1 << (data->irq - ucb->irq_base);
417 370
418 irq->fn = NULL; 371 if (!pdata || !pdata->can_wakeup)
419 irq->devid = NULL; 372 return -EINVAL;
420 ret = 0;
421 }
422 spin_unlock_irq(&ucb->lock);
423 return ret;
424 373
425bad: 374 raw_spin_lock(&ucb->irq_lock);
426 printk(KERN_ERR "Freeing bad UCB1x00 irq %d\n", idx); 375 if (on)
427 return -EINVAL; 376 ucb->irq_wake |= mask;
377 else
378 ucb->irq_wake &= ~mask;
379 raw_spin_unlock(&ucb->irq_lock);
380
381 return 0;
428} 382}
429 383
384static struct irq_chip ucb1x00_irqchip = {
385 .name = "ucb1x00",
386 .irq_ack = ucb1x00_irq_noop,
387 .irq_mask = ucb1x00_irq_mask,
388 .irq_unmask = ucb1x00_irq_unmask,
389 .irq_set_type = ucb1x00_irq_set_type,
390 .irq_set_wake = ucb1x00_irq_set_wake,
391};
392
430static int ucb1x00_add_dev(struct ucb1x00 *ucb, struct ucb1x00_driver *drv) 393static int ucb1x00_add_dev(struct ucb1x00 *ucb, struct ucb1x00_driver *drv)
431{ 394{
432 struct ucb1x00_dev *dev; 395 struct ucb1x00_dev *dev;
@@ -440,8 +403,8 @@ static int ucb1x00_add_dev(struct ucb1x00 *ucb, struct ucb1x00_driver *drv)
440 ret = drv->add(dev); 403 ret = drv->add(dev);
441 404
442 if (ret == 0) { 405 if (ret == 0) {
443 list_add(&dev->dev_node, &ucb->devs); 406 list_add_tail(&dev->dev_node, &ucb->devs);
444 list_add(&dev->drv_node, &drv->devs); 407 list_add_tail(&dev->drv_node, &drv->devs);
445 } else { 408 } else {
446 kfree(dev); 409 kfree(dev);
447 } 410 }
@@ -533,98 +496,126 @@ static struct class ucb1x00_class = {
533 496
534static int ucb1x00_probe(struct mcp *mcp) 497static int ucb1x00_probe(struct mcp *mcp)
535{ 498{
536 struct ucb1x00 *ucb; 499 struct ucb1x00_plat_data *pdata = mcp->attached_device.platform_data;
537 struct ucb1x00_driver *drv; 500 struct ucb1x00_driver *drv;
538 unsigned int id; 501 struct ucb1x00 *ucb;
502 unsigned id, i, irq_base;
539 int ret = -ENODEV; 503 int ret = -ENODEV;
540 int temp; 504
505 /* Tell the platform to deassert the UCB1x00 reset */
506 if (pdata && pdata->reset)
507 pdata->reset(UCB_RST_PROBE);
541 508
542 mcp_enable(mcp); 509 mcp_enable(mcp);
543 id = mcp_reg_read(mcp, UCB_ID); 510 id = mcp_reg_read(mcp, UCB_ID);
511 mcp_disable(mcp);
544 512
545 if (id != UCB_ID_1200 && id != UCB_ID_1300 && id != UCB_ID_TC35143) { 513 if (id != UCB_ID_1200 && id != UCB_ID_1300 && id != UCB_ID_TC35143) {
546 printk(KERN_WARNING "UCB1x00 ID not found: %04x\n", id); 514 printk(KERN_WARNING "UCB1x00 ID not found: %04x\n", id);
547 goto err_disable; 515 goto out;
548 } 516 }
549 517
550 ucb = kzalloc(sizeof(struct ucb1x00), GFP_KERNEL); 518 ucb = kzalloc(sizeof(struct ucb1x00), GFP_KERNEL);
551 ret = -ENOMEM; 519 ret = -ENOMEM;
552 if (!ucb) 520 if (!ucb)
553 goto err_disable; 521 goto out;
554
555 522
523 device_initialize(&ucb->dev);
556 ucb->dev.class = &ucb1x00_class; 524 ucb->dev.class = &ucb1x00_class;
557 ucb->dev.parent = &mcp->attached_device; 525 ucb->dev.parent = &mcp->attached_device;
558 dev_set_name(&ucb->dev, "ucb1x00"); 526 dev_set_name(&ucb->dev, "ucb1x00");
559 527
560 spin_lock_init(&ucb->lock); 528 raw_spin_lock_init(&ucb->irq_lock);
561 spin_lock_init(&ucb->io_lock); 529 spin_lock_init(&ucb->io_lock);
562 sema_init(&ucb->adc_sem, 1); 530 mutex_init(&ucb->adc_mutex);
563 531
564 ucb->id = id; 532 ucb->id = id;
565 ucb->mcp = mcp; 533 ucb->mcp = mcp;
534
535 ret = device_add(&ucb->dev);
536 if (ret)
537 goto err_dev_add;
538
539 ucb1x00_enable(ucb);
566 ucb->irq = ucb1x00_detect_irq(ucb); 540 ucb->irq = ucb1x00_detect_irq(ucb);
541 ucb1x00_disable(ucb);
567 if (ucb->irq == NO_IRQ) { 542 if (ucb->irq == NO_IRQ) {
568 printk(KERN_ERR "UCB1x00: IRQ probe failed\n"); 543 dev_err(&ucb->dev, "IRQ probe failed\n");
569 ret = -ENODEV; 544 ret = -ENODEV;
570 goto err_free; 545 goto err_no_irq;
571 } 546 }
572 547
573 ucb->gpio.base = -1; 548 ucb->gpio.base = -1;
574 if (mcp->gpio_base != 0) { 549 irq_base = pdata ? pdata->irq_base : 0;
550 ucb->irq_base = irq_alloc_descs(-1, irq_base, 16, -1);
551 if (ucb->irq_base < 0) {
552 dev_err(&ucb->dev, "unable to allocate 16 irqs: %d\n",
553 ucb->irq_base);
554 goto err_irq_alloc;
555 }
556
557 for (i = 0; i < 16; i++) {
558 unsigned irq = ucb->irq_base + i;
559
560 irq_set_chip_and_handler(irq, &ucb1x00_irqchip, handle_edge_irq);
561 irq_set_chip_data(irq, ucb);
562 set_irq_flags(irq, IRQF_VALID | IRQ_NOREQUEST);
563 }
564
565 irq_set_irq_type(ucb->irq, IRQ_TYPE_EDGE_RISING);
566 irq_set_handler_data(ucb->irq, ucb);
567 irq_set_chained_handler(ucb->irq, ucb1x00_irq);
568
569 if (pdata && pdata->gpio_base) {
575 ucb->gpio.label = dev_name(&ucb->dev); 570 ucb->gpio.label = dev_name(&ucb->dev);
576 ucb->gpio.base = mcp->gpio_base; 571 ucb->gpio.dev = &ucb->dev;
572 ucb->gpio.owner = THIS_MODULE;
573 ucb->gpio.base = pdata->gpio_base;
577 ucb->gpio.ngpio = 10; 574 ucb->gpio.ngpio = 10;
578 ucb->gpio.set = ucb1x00_gpio_set; 575 ucb->gpio.set = ucb1x00_gpio_set;
579 ucb->gpio.get = ucb1x00_gpio_get; 576 ucb->gpio.get = ucb1x00_gpio_get;
580 ucb->gpio.direction_input = ucb1x00_gpio_direction_input; 577 ucb->gpio.direction_input = ucb1x00_gpio_direction_input;
581 ucb->gpio.direction_output = ucb1x00_gpio_direction_output; 578 ucb->gpio.direction_output = ucb1x00_gpio_direction_output;
579 ucb->gpio.to_irq = ucb1x00_to_irq;
582 ret = gpiochip_add(&ucb->gpio); 580 ret = gpiochip_add(&ucb->gpio);
583 if (ret) 581 if (ret)
584 goto err_free; 582 goto err_gpio_add;
585 } else 583 } else
586 dev_info(&ucb->dev, "gpio_base not set so no gpiolib support"); 584 dev_info(&ucb->dev, "gpio_base not set so no gpiolib support");
587 585
588 ret = request_irq(ucb->irq, ucb1x00_irq, IRQF_TRIGGER_RISING,
589 "UCB1x00", ucb);
590 if (ret) {
591 printk(KERN_ERR "ucb1x00: unable to grab irq%d: %d\n",
592 ucb->irq, ret);
593 goto err_gpio;
594 }
595
596 mcp_set_drvdata(mcp, ucb); 586 mcp_set_drvdata(mcp, ucb);
597 587
598 ret = device_register(&ucb->dev); 588 if (pdata)
599 if (ret) 589 device_set_wakeup_capable(&ucb->dev, pdata->can_wakeup);
600 goto err_irq;
601
602 590
603 INIT_LIST_HEAD(&ucb->devs); 591 INIT_LIST_HEAD(&ucb->devs);
604 mutex_lock(&ucb1x00_mutex); 592 mutex_lock(&ucb1x00_mutex);
605 list_add(&ucb->node, &ucb1x00_devices); 593 list_add_tail(&ucb->node, &ucb1x00_devices);
606 list_for_each_entry(drv, &ucb1x00_drivers, node) { 594 list_for_each_entry(drv, &ucb1x00_drivers, node) {
607 ucb1x00_add_dev(ucb, drv); 595 ucb1x00_add_dev(ucb, drv);
608 } 596 }
609 mutex_unlock(&ucb1x00_mutex); 597 mutex_unlock(&ucb1x00_mutex);
610 598
611 goto out; 599 return ret;
612 600
613 err_irq: 601 err_gpio_add:
614 free_irq(ucb->irq, ucb); 602 irq_set_chained_handler(ucb->irq, NULL);
615 err_gpio: 603 err_irq_alloc:
616 if (ucb->gpio.base != -1) 604 if (ucb->irq_base > 0)
617 temp = gpiochip_remove(&ucb->gpio); 605 irq_free_descs(ucb->irq_base, 16);
618 err_free: 606 err_no_irq:
619 kfree(ucb); 607 device_del(&ucb->dev);
620 err_disable: 608 err_dev_add:
621 mcp_disable(mcp); 609 put_device(&ucb->dev);
622 out: 610 out:
611 if (pdata && pdata->reset)
612 pdata->reset(UCB_RST_PROBE_FAIL);
623 return ret; 613 return ret;
624} 614}
625 615
626static void ucb1x00_remove(struct mcp *mcp) 616static void ucb1x00_remove(struct mcp *mcp)
627{ 617{
618 struct ucb1x00_plat_data *pdata = mcp->attached_device.platform_data;
628 struct ucb1x00 *ucb = mcp_get_drvdata(mcp); 619 struct ucb1x00 *ucb = mcp_get_drvdata(mcp);
629 struct list_head *l, *n; 620 struct list_head *l, *n;
630 int ret; 621 int ret;
@@ -643,8 +634,12 @@ static void ucb1x00_remove(struct mcp *mcp)
643 dev_err(&ucb->dev, "Can't remove gpio chip: %d\n", ret); 634 dev_err(&ucb->dev, "Can't remove gpio chip: %d\n", ret);
644 } 635 }
645 636
646 free_irq(ucb->irq, ucb); 637 irq_set_chained_handler(ucb->irq, NULL);
638 irq_free_descs(ucb->irq_base, 16);
647 device_unregister(&ucb->dev); 639 device_unregister(&ucb->dev);
640
641 if (pdata && pdata->reset)
642 pdata->reset(UCB_RST_REMOVE);
648} 643}
649 644
650int ucb1x00_register_driver(struct ucb1x00_driver *drv) 645int ucb1x00_register_driver(struct ucb1x00_driver *drv)
@@ -653,7 +648,7 @@ int ucb1x00_register_driver(struct ucb1x00_driver *drv)
653 648
654 INIT_LIST_HEAD(&drv->devs); 649 INIT_LIST_HEAD(&drv->devs);
655 mutex_lock(&ucb1x00_mutex); 650 mutex_lock(&ucb1x00_mutex);
656 list_add(&drv->node, &ucb1x00_drivers); 651 list_add_tail(&drv->node, &ucb1x00_drivers);
657 list_for_each_entry(ucb, &ucb1x00_devices, node) { 652 list_for_each_entry(ucb, &ucb1x00_devices, node) {
658 ucb1x00_add_dev(ucb, drv); 653 ucb1x00_add_dev(ucb, drv);
659 } 654 }
@@ -674,44 +669,86 @@ void ucb1x00_unregister_driver(struct ucb1x00_driver *drv)
674 mutex_unlock(&ucb1x00_mutex); 669 mutex_unlock(&ucb1x00_mutex);
675} 670}
676 671
677static int ucb1x00_suspend(struct mcp *mcp, pm_message_t state) 672static int ucb1x00_suspend(struct device *dev)
678{ 673{
679 struct ucb1x00 *ucb = mcp_get_drvdata(mcp); 674 struct ucb1x00_plat_data *pdata = dev->platform_data;
680 struct ucb1x00_dev *dev; 675 struct ucb1x00 *ucb = dev_get_drvdata(dev);
676 struct ucb1x00_dev *udev;
681 677
682 mutex_lock(&ucb1x00_mutex); 678 mutex_lock(&ucb1x00_mutex);
683 list_for_each_entry(dev, &ucb->devs, dev_node) { 679 list_for_each_entry(udev, &ucb->devs, dev_node) {
684 if (dev->drv->suspend) 680 if (udev->drv->suspend)
685 dev->drv->suspend(dev, state); 681 udev->drv->suspend(udev);
686 } 682 }
687 mutex_unlock(&ucb1x00_mutex); 683 mutex_unlock(&ucb1x00_mutex);
684
685 if (ucb->irq_wake) {
686 unsigned long flags;
687
688 raw_spin_lock_irqsave(&ucb->irq_lock, flags);
689 ucb1x00_enable(ucb);
690 ucb1x00_reg_write(ucb, UCB_IE_RIS, ucb->irq_ris_enbl &
691 ucb->irq_wake);
692 ucb1x00_reg_write(ucb, UCB_IE_FAL, ucb->irq_fal_enbl &
693 ucb->irq_wake);
694 ucb1x00_disable(ucb);
695 raw_spin_unlock_irqrestore(&ucb->irq_lock, flags);
696
697 enable_irq_wake(ucb->irq);
698 } else if (pdata && pdata->reset)
699 pdata->reset(UCB_RST_SUSPEND);
700
688 return 0; 701 return 0;
689} 702}
690 703
691static int ucb1x00_resume(struct mcp *mcp) 704static int ucb1x00_resume(struct device *dev)
692{ 705{
693 struct ucb1x00 *ucb = mcp_get_drvdata(mcp); 706 struct ucb1x00_plat_data *pdata = dev->platform_data;
694 struct ucb1x00_dev *dev; 707 struct ucb1x00 *ucb = dev_get_drvdata(dev);
708 struct ucb1x00_dev *udev;
709
710 if (!ucb->irq_wake && pdata && pdata->reset)
711 pdata->reset(UCB_RST_RESUME);
695 712
713 ucb1x00_enable(ucb);
696 ucb1x00_reg_write(ucb, UCB_IO_DATA, ucb->io_out); 714 ucb1x00_reg_write(ucb, UCB_IO_DATA, ucb->io_out);
697 ucb1x00_reg_write(ucb, UCB_IO_DIR, ucb->io_dir); 715 ucb1x00_reg_write(ucb, UCB_IO_DIR, ucb->io_dir);
716
717 if (ucb->irq_wake) {
718 unsigned long flags;
719
720 raw_spin_lock_irqsave(&ucb->irq_lock, flags);
721 ucb1x00_reg_write(ucb, UCB_IE_RIS, ucb->irq_ris_enbl &
722 ucb->irq_mask);
723 ucb1x00_reg_write(ucb, UCB_IE_FAL, ucb->irq_fal_enbl &
724 ucb->irq_mask);
725 raw_spin_unlock_irqrestore(&ucb->irq_lock, flags);
726
727 disable_irq_wake(ucb->irq);
728 }
729 ucb1x00_disable(ucb);
730
698 mutex_lock(&ucb1x00_mutex); 731 mutex_lock(&ucb1x00_mutex);
699 list_for_each_entry(dev, &ucb->devs, dev_node) { 732 list_for_each_entry(udev, &ucb->devs, dev_node) {
700 if (dev->drv->resume) 733 if (udev->drv->resume)
701 dev->drv->resume(dev); 734 udev->drv->resume(udev);
702 } 735 }
703 mutex_unlock(&ucb1x00_mutex); 736 mutex_unlock(&ucb1x00_mutex);
704 return 0; 737 return 0;
705} 738}
706 739
740static const struct dev_pm_ops ucb1x00_pm_ops = {
741 SET_SYSTEM_SLEEP_PM_OPS(ucb1x00_suspend, ucb1x00_resume)
742};
743
707static struct mcp_driver ucb1x00_driver = { 744static struct mcp_driver ucb1x00_driver = {
708 .drv = { 745 .drv = {
709 .name = "ucb1x00", 746 .name = "ucb1x00",
747 .owner = THIS_MODULE,
748 .pm = &ucb1x00_pm_ops,
710 }, 749 },
711 .probe = ucb1x00_probe, 750 .probe = ucb1x00_probe,
712 .remove = ucb1x00_remove, 751 .remove = ucb1x00_remove,
713 .suspend = ucb1x00_suspend,
714 .resume = ucb1x00_resume,
715}; 752};
716 753
717static int __init ucb1x00_init(void) 754static int __init ucb1x00_init(void)
@@ -742,14 +779,10 @@ EXPORT_SYMBOL(ucb1x00_adc_enable);
742EXPORT_SYMBOL(ucb1x00_adc_read); 779EXPORT_SYMBOL(ucb1x00_adc_read);
743EXPORT_SYMBOL(ucb1x00_adc_disable); 780EXPORT_SYMBOL(ucb1x00_adc_disable);
744 781
745EXPORT_SYMBOL(ucb1x00_hook_irq);
746EXPORT_SYMBOL(ucb1x00_free_irq);
747EXPORT_SYMBOL(ucb1x00_enable_irq);
748EXPORT_SYMBOL(ucb1x00_disable_irq);
749
750EXPORT_SYMBOL(ucb1x00_register_driver); 782EXPORT_SYMBOL(ucb1x00_register_driver);
751EXPORT_SYMBOL(ucb1x00_unregister_driver); 783EXPORT_SYMBOL(ucb1x00_unregister_driver);
752 784
785MODULE_ALIAS("mcp:ucb1x00");
753MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>"); 786MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>");
754MODULE_DESCRIPTION("UCB1x00 core driver"); 787MODULE_DESCRIPTION("UCB1x00 core driver");
755MODULE_LICENSE("GPL"); 788MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/ucb1x00-ts.c b/drivers/mfd/ucb1x00-ts.c
index 63a3cbdfa3f3..1e0e20c0e082 100644
--- a/drivers/mfd/ucb1x00-ts.c
+++ b/drivers/mfd/ucb1x00-ts.c
@@ -20,8 +20,9 @@
20#include <linux/module.h> 20#include <linux/module.h>
21#include <linux/moduleparam.h> 21#include <linux/moduleparam.h>
22#include <linux/init.h> 22#include <linux/init.h>
23#include <linux/smp.h> 23#include <linux/interrupt.h>
24#include <linux/sched.h> 24#include <linux/sched.h>
25#include <linux/spinlock.h>
25#include <linux/completion.h> 26#include <linux/completion.h>
26#include <linux/delay.h> 27#include <linux/delay.h>
27#include <linux/string.h> 28#include <linux/string.h>
@@ -32,7 +33,6 @@
32#include <linux/kthread.h> 33#include <linux/kthread.h>
33#include <linux/mfd/ucb1x00.h> 34#include <linux/mfd/ucb1x00.h>
34 35
35#include <mach/dma.h>
36#include <mach/collie.h> 36#include <mach/collie.h>
37#include <asm/mach-types.h> 37#include <asm/mach-types.h>
38 38
@@ -42,6 +42,8 @@ struct ucb1x00_ts {
42 struct input_dev *idev; 42 struct input_dev *idev;
43 struct ucb1x00 *ucb; 43 struct ucb1x00 *ucb;
44 44
45 spinlock_t irq_lock;
46 unsigned irq_disabled;
45 wait_queue_head_t irq_wait; 47 wait_queue_head_t irq_wait;
46 struct task_struct *rtask; 48 struct task_struct *rtask;
47 u16 x_res; 49 u16 x_res;
@@ -238,7 +240,12 @@ static int ucb1x00_thread(void *_ts)
238 if (ucb1x00_ts_pen_down(ts)) { 240 if (ucb1x00_ts_pen_down(ts)) {
239 set_current_state(TASK_INTERRUPTIBLE); 241 set_current_state(TASK_INTERRUPTIBLE);
240 242
241 ucb1x00_enable_irq(ts->ucb, UCB_IRQ_TSPX, machine_is_collie() ? UCB_RISING : UCB_FALLING); 243 spin_lock_irq(&ts->irq_lock);
244 if (ts->irq_disabled) {
245 ts->irq_disabled = 0;
246 enable_irq(ts->ucb->irq_base + UCB_IRQ_TSPX);
247 }
248 spin_unlock_irq(&ts->irq_lock);
242 ucb1x00_disable(ts->ucb); 249 ucb1x00_disable(ts->ucb);
243 250
244 /* 251 /*
@@ -281,23 +288,37 @@ static int ucb1x00_thread(void *_ts)
281 * We only detect touch screen _touches_ with this interrupt 288 * We only detect touch screen _touches_ with this interrupt
282 * handler, and even then we just schedule our task. 289 * handler, and even then we just schedule our task.
283 */ 290 */
284static void ucb1x00_ts_irq(int idx, void *id) 291static irqreturn_t ucb1x00_ts_irq(int irq, void *id)
285{ 292{
286 struct ucb1x00_ts *ts = id; 293 struct ucb1x00_ts *ts = id;
287 294
288 ucb1x00_disable_irq(ts->ucb, UCB_IRQ_TSPX, UCB_FALLING); 295 spin_lock(&ts->irq_lock);
296 ts->irq_disabled = 1;
297 disable_irq_nosync(ts->ucb->irq_base + UCB_IRQ_TSPX);
298 spin_unlock(&ts->irq_lock);
289 wake_up(&ts->irq_wait); 299 wake_up(&ts->irq_wait);
300
301 return IRQ_HANDLED;
290} 302}
291 303
292static int ucb1x00_ts_open(struct input_dev *idev) 304static int ucb1x00_ts_open(struct input_dev *idev)
293{ 305{
294 struct ucb1x00_ts *ts = input_get_drvdata(idev); 306 struct ucb1x00_ts *ts = input_get_drvdata(idev);
307 unsigned long flags = 0;
295 int ret = 0; 308 int ret = 0;
296 309
297 BUG_ON(ts->rtask); 310 BUG_ON(ts->rtask);
298 311
312 if (machine_is_collie())
313 flags = IRQF_TRIGGER_RISING;
314 else
315 flags = IRQF_TRIGGER_FALLING;
316
317 ts->irq_disabled = 0;
318
299 init_waitqueue_head(&ts->irq_wait); 319 init_waitqueue_head(&ts->irq_wait);
300 ret = ucb1x00_hook_irq(ts->ucb, UCB_IRQ_TSPX, ucb1x00_ts_irq, ts); 320 ret = request_irq(ts->ucb->irq_base + UCB_IRQ_TSPX, ucb1x00_ts_irq,
321 flags, "ucb1x00-ts", ts);
301 if (ret < 0) 322 if (ret < 0)
302 goto out; 323 goto out;
303 324
@@ -314,7 +335,7 @@ static int ucb1x00_ts_open(struct input_dev *idev)
314 if (!IS_ERR(ts->rtask)) { 335 if (!IS_ERR(ts->rtask)) {
315 ret = 0; 336 ret = 0;
316 } else { 337 } else {
317 ucb1x00_free_irq(ts->ucb, UCB_IRQ_TSPX, ts); 338 free_irq(ts->ucb->irq_base + UCB_IRQ_TSPX, ts);
318 ts->rtask = NULL; 339 ts->rtask = NULL;
319 ret = -EFAULT; 340 ret = -EFAULT;
320 } 341 }
@@ -334,7 +355,7 @@ static void ucb1x00_ts_close(struct input_dev *idev)
334 kthread_stop(ts->rtask); 355 kthread_stop(ts->rtask);
335 356
336 ucb1x00_enable(ts->ucb); 357 ucb1x00_enable(ts->ucb);
337 ucb1x00_free_irq(ts->ucb, UCB_IRQ_TSPX, ts); 358 free_irq(ts->ucb->irq_base + UCB_IRQ_TSPX, ts);
338 ucb1x00_reg_write(ts->ucb, UCB_TS_CR, 0); 359 ucb1x00_reg_write(ts->ucb, UCB_TS_CR, 0);
339 ucb1x00_disable(ts->ucb); 360 ucb1x00_disable(ts->ucb);
340} 361}
@@ -359,11 +380,13 @@ static int ucb1x00_ts_add(struct ucb1x00_dev *dev)
359 ts->ucb = dev->ucb; 380 ts->ucb = dev->ucb;
360 ts->idev = idev; 381 ts->idev = idev;
361 ts->adcsync = adcsync ? UCB_SYNC : UCB_NOSYNC; 382 ts->adcsync = adcsync ? UCB_SYNC : UCB_NOSYNC;
383 spin_lock_init(&ts->irq_lock);
362 384
363 idev->name = "Touchscreen panel"; 385 idev->name = "Touchscreen panel";
364 idev->id.product = ts->ucb->id; 386 idev->id.product = ts->ucb->id;
365 idev->open = ucb1x00_ts_open; 387 idev->open = ucb1x00_ts_open;
366 idev->close = ucb1x00_ts_close; 388 idev->close = ucb1x00_ts_close;
389 idev->dev.parent = &ts->ucb->dev;
367 390
368 idev->evbit[0] = BIT_MASK(EV_ABS) | BIT_MASK(EV_KEY); 391 idev->evbit[0] = BIT_MASK(EV_ABS) | BIT_MASK(EV_KEY);
369 idev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); 392 idev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
diff --git a/include/linux/mfd/mcp.h b/include/linux/mfd/mcp.h
index f88c1cc0cb0f..a9e8bd157673 100644
--- a/include/linux/mfd/mcp.h
+++ b/include/linux/mfd/mcp.h
@@ -10,8 +10,6 @@
10#ifndef MCP_H 10#ifndef MCP_H
11#define MCP_H 11#define MCP_H
12 12
13#include <mach/dma.h>
14
15struct mcp_ops; 13struct mcp_ops;
16 14
17struct mcp { 15struct mcp {
@@ -21,12 +19,7 @@ struct mcp {
21 int use_count; 19 int use_count;
22 unsigned int sclk_rate; 20 unsigned int sclk_rate;
23 unsigned int rw_timeout; 21 unsigned int rw_timeout;
24 dma_device_t dma_audio_rd;
25 dma_device_t dma_audio_wr;
26 dma_device_t dma_telco_rd;
27 dma_device_t dma_telco_wr;
28 struct device attached_device; 22 struct device attached_device;
29 int gpio_base;
30}; 23};
31 24
32struct mcp_ops { 25struct mcp_ops {
@@ -47,15 +40,14 @@ void mcp_disable(struct mcp *);
47#define mcp_get_sclk_rate(mcp) ((mcp)->sclk_rate) 40#define mcp_get_sclk_rate(mcp) ((mcp)->sclk_rate)
48 41
49struct mcp *mcp_host_alloc(struct device *, size_t); 42struct mcp *mcp_host_alloc(struct device *, size_t);
50int mcp_host_register(struct mcp *); 43int mcp_host_add(struct mcp *, void *);
51void mcp_host_unregister(struct mcp *); 44void mcp_host_del(struct mcp *);
45void mcp_host_free(struct mcp *);
52 46
53struct mcp_driver { 47struct mcp_driver {
54 struct device_driver drv; 48 struct device_driver drv;
55 int (*probe)(struct mcp *); 49 int (*probe)(struct mcp *);
56 void (*remove)(struct mcp *); 50 void (*remove)(struct mcp *);
57 int (*suspend)(struct mcp *, pm_message_t);
58 int (*resume)(struct mcp *);
59}; 51};
60 52
61int mcp_driver_register(struct mcp_driver *); 53int mcp_driver_register(struct mcp_driver *);
diff --git a/include/linux/mfd/ucb1x00.h b/include/linux/mfd/ucb1x00.h
index 4321f044d1e4..28af41756360 100644
--- a/include/linux/mfd/ucb1x00.h
+++ b/include/linux/mfd/ucb1x00.h
@@ -12,7 +12,7 @@
12 12
13#include <linux/mfd/mcp.h> 13#include <linux/mfd/mcp.h>
14#include <linux/gpio.h> 14#include <linux/gpio.h>
15#include <linux/semaphore.h> 15#include <linux/mutex.h>
16 16
17#define UCB_IO_DATA 0x00 17#define UCB_IO_DATA 0x00
18#define UCB_IO_DIR 0x01 18#define UCB_IO_DIR 0x01
@@ -104,17 +104,27 @@
104#define UCB_MODE_DYN_VFLAG_ENA (1 << 12) 104#define UCB_MODE_DYN_VFLAG_ENA (1 << 12)
105#define UCB_MODE_AUD_OFF_CAN (1 << 13) 105#define UCB_MODE_AUD_OFF_CAN (1 << 13)
106 106
107enum ucb1x00_reset {
108 UCB_RST_PROBE,
109 UCB_RST_RESUME,
110 UCB_RST_SUSPEND,
111 UCB_RST_REMOVE,
112 UCB_RST_PROBE_FAIL,
113};
107 114
108struct ucb1x00_irq { 115struct ucb1x00_plat_data {
109 void *devid; 116 void (*reset)(enum ucb1x00_reset);
110 void (*fn)(int, void *); 117 unsigned irq_base;
118 int gpio_base;
119 unsigned can_wakeup;
111}; 120};
112 121
113struct ucb1x00 { 122struct ucb1x00 {
114 spinlock_t lock; 123 raw_spinlock_t irq_lock;
115 struct mcp *mcp; 124 struct mcp *mcp;
116 unsigned int irq; 125 unsigned int irq;
117 struct semaphore adc_sem; 126 int irq_base;
127 struct mutex adc_mutex;
118 spinlock_t io_lock; 128 spinlock_t io_lock;
119 u16 id; 129 u16 id;
120 u16 io_dir; 130 u16 io_dir;
@@ -122,7 +132,8 @@ struct ucb1x00 {
122 u16 adc_cr; 132 u16 adc_cr;
123 u16 irq_fal_enbl; 133 u16 irq_fal_enbl;
124 u16 irq_ris_enbl; 134 u16 irq_ris_enbl;
125 struct ucb1x00_irq irq_handler[16]; 135 u16 irq_mask;
136 u16 irq_wake;
126 struct device dev; 137 struct device dev;
127 struct list_head node; 138 struct list_head node;
128 struct list_head devs; 139 struct list_head devs;
@@ -144,7 +155,7 @@ struct ucb1x00_driver {
144 struct list_head devs; 155 struct list_head devs;
145 int (*add)(struct ucb1x00_dev *dev); 156 int (*add)(struct ucb1x00_dev *dev);
146 void (*remove)(struct ucb1x00_dev *dev); 157 void (*remove)(struct ucb1x00_dev *dev);
147 int (*suspend)(struct ucb1x00_dev *dev, pm_message_t state); 158 int (*suspend)(struct ucb1x00_dev *dev);
148 int (*resume)(struct ucb1x00_dev *dev); 159 int (*resume)(struct ucb1x00_dev *dev);
149}; 160};
150 161
@@ -245,15 +256,4 @@ unsigned int ucb1x00_adc_read(struct ucb1x00 *ucb, int adc_channel, int sync);
245void ucb1x00_adc_enable(struct ucb1x00 *ucb); 256void ucb1x00_adc_enable(struct ucb1x00 *ucb);
246void ucb1x00_adc_disable(struct ucb1x00 *ucb); 257void ucb1x00_adc_disable(struct ucb1x00 *ucb);
247 258
248/*
249 * Which edges of the IRQ do you want to control today?
250 */
251#define UCB_RISING (1 << 0)
252#define UCB_FALLING (1 << 1)
253
254int ucb1x00_hook_irq(struct ucb1x00 *ucb, unsigned int idx, void (*fn)(int, void *), void *devid);
255void ucb1x00_enable_irq(struct ucb1x00 *ucb, unsigned int idx, int edges);
256void ucb1x00_disable_irq(struct ucb1x00 *ucb, unsigned int idx, int edges);
257int ucb1x00_free_irq(struct ucb1x00 *ucb, unsigned int idx, void *devid);
258
259#endif 259#endif