aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/common/sa1111.c22
-rw-r--r--arch/arm/include/asm/hardware/sa1111.h8
-rw-r--r--drivers/input/serio/sa1111ps2.c6
-rw-r--r--drivers/pcmcia/sa1111_generic.c11
-rw-r--r--drivers/usb/host/ohci-sa1111.c19
5 files changed, 51 insertions, 15 deletions
diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c
index b0f93628dcd7..1366e82e6707 100644
--- a/arch/arm/common/sa1111.c
+++ b/arch/arm/common/sa1111.c
@@ -106,6 +106,7 @@ struct sa1111 {
106 int irq_base; /* base for cascaded on-chip IRQs */ 106 int irq_base; /* base for cascaded on-chip IRQs */
107 spinlock_t lock; 107 spinlock_t lock;
108 void __iomem *base; 108 void __iomem *base;
109 struct sa1111_platform_data *pdata;
109#ifdef CONFIG_PM 110#ifdef CONFIG_PM
110 void *saved_state; 111 void *saved_state;
111#endif 112#endif
@@ -756,6 +757,7 @@ __sa1111_probe(struct device *me, struct resource *mem, int irq)
756 sachip->dev = me; 757 sachip->dev = me;
757 dev_set_drvdata(sachip->dev, sachip); 758 dev_set_drvdata(sachip->dev, sachip);
758 759
760 sachip->pdata = pd;
759 sachip->phys = mem->start; 761 sachip->phys = mem->start;
760 sachip->irq = irq; 762 sachip->irq = irq;
761 763
@@ -1282,16 +1284,23 @@ EXPORT_SYMBOL(sa1111_set_sleep_io);
1282 * sa1111_enable_device - enable an on-chip SA1111 function block 1284 * sa1111_enable_device - enable an on-chip SA1111 function block
1283 * @sadev: SA1111 function block device to enable 1285 * @sadev: SA1111 function block device to enable
1284 */ 1286 */
1285void sa1111_enable_device(struct sa1111_dev *sadev) 1287int sa1111_enable_device(struct sa1111_dev *sadev)
1286{ 1288{
1287 struct sa1111 *sachip = sa1111_chip_driver(sadev); 1289 struct sa1111 *sachip = sa1111_chip_driver(sadev);
1288 unsigned long flags; 1290 unsigned long flags;
1289 unsigned int val; 1291 unsigned int val;
1292 int ret = 0;
1290 1293
1291 spin_lock_irqsave(&sachip->lock, flags); 1294 if (sachip->pdata && sachip->pdata->enable)
1292 val = sa1111_readl(sachip->base + SA1111_SKPCR); 1295 ret = sachip->pdata->enable(sachip->pdata->data, sadev->devid);
1293 sa1111_writel(val | sadev->skpcr_mask, sachip->base + SA1111_SKPCR); 1296
1294 spin_unlock_irqrestore(&sachip->lock, flags); 1297 if (ret == 0) {
1298 spin_lock_irqsave(&sachip->lock, flags);
1299 val = sa1111_readl(sachip->base + SA1111_SKPCR);
1300 sa1111_writel(val | sadev->skpcr_mask, sachip->base + SA1111_SKPCR);
1301 spin_unlock_irqrestore(&sachip->lock, flags);
1302 }
1303 return ret;
1295} 1304}
1296EXPORT_SYMBOL(sa1111_enable_device); 1305EXPORT_SYMBOL(sa1111_enable_device);
1297 1306
@@ -1309,6 +1318,9 @@ void sa1111_disable_device(struct sa1111_dev *sadev)
1309 val = sa1111_readl(sachip->base + SA1111_SKPCR); 1318 val = sa1111_readl(sachip->base + SA1111_SKPCR);
1310 sa1111_writel(val & ~sadev->skpcr_mask, sachip->base + SA1111_SKPCR); 1319 sa1111_writel(val & ~sadev->skpcr_mask, sachip->base + SA1111_SKPCR);
1311 spin_unlock_irqrestore(&sachip->lock, flags); 1320 spin_unlock_irqrestore(&sachip->lock, flags);
1321
1322 if (sachip->pdata && sachip->pdata->disable)
1323 sachip->pdata->disable(sachip->pdata->data, sadev->devid);
1312} 1324}
1313EXPORT_SYMBOL(sa1111_disable_device); 1325EXPORT_SYMBOL(sa1111_disable_device);
1314 1326
diff --git a/arch/arm/include/asm/hardware/sa1111.h b/arch/arm/include/asm/hardware/sa1111.h
index 29e320f6f85f..d54d781021c8 100644
--- a/arch/arm/include/asm/hardware/sa1111.h
+++ b/arch/arm/include/asm/hardware/sa1111.h
@@ -556,9 +556,10 @@ struct sa1111_driver {
556#define SA1111_DRIVER_NAME(_sadev) ((_sadev)->dev.driver->name) 556#define SA1111_DRIVER_NAME(_sadev) ((_sadev)->dev.driver->name)
557 557
558/* 558/*
559 * These frob the SKPCR register. 559 * These frob the SKPCR register, and call platform specific
560 * enable/disable functions.
560 */ 561 */
561void sa1111_enable_device(struct sa1111_dev *); 562int sa1111_enable_device(struct sa1111_dev *);
562void sa1111_disable_device(struct sa1111_dev *); 563void sa1111_disable_device(struct sa1111_dev *);
563 564
564unsigned int sa1111_pll_clock(struct sa1111_dev *); 565unsigned int sa1111_pll_clock(struct sa1111_dev *);
@@ -581,6 +582,9 @@ void sa1111_set_sleep_io(struct sa1111_dev *sadev, unsigned int bits, unsigned i
581 582
582struct sa1111_platform_data { 583struct sa1111_platform_data {
583 int irq_base; /* base for cascaded on-chip IRQs */ 584 int irq_base; /* base for cascaded on-chip IRQs */
585 void *data;
586 int (*enable)(void *, unsigned);
587 void (*disable)(void *, unsigned);
584}; 588};
585 589
586#endif /* _ASM_ARCH_SA1111 */ 590#endif /* _ASM_ARCH_SA1111 */
diff --git a/drivers/input/serio/sa1111ps2.c b/drivers/input/serio/sa1111ps2.c
index 40ec545fbd40..ad7d23b5c6fe 100644
--- a/drivers/input/serio/sa1111ps2.c
+++ b/drivers/input/serio/sa1111ps2.c
@@ -124,13 +124,16 @@ static int ps2_open(struct serio *io)
124 struct ps2if *ps2if = io->port_data; 124 struct ps2if *ps2if = io->port_data;
125 int ret; 125 int ret;
126 126
127 sa1111_enable_device(ps2if->dev); 127 ret = sa1111_enable_device(ps2if->dev);
128 if (ret)
129 return ret;
128 130
129 ret = request_irq(ps2if->dev->irq[0], ps2_rxint, 0, 131 ret = request_irq(ps2if->dev->irq[0], ps2_rxint, 0,
130 SA1111_DRIVER_NAME(ps2if->dev), ps2if); 132 SA1111_DRIVER_NAME(ps2if->dev), ps2if);
131 if (ret) { 133 if (ret) {
132 printk(KERN_ERR "sa1111ps2: could not allocate IRQ%d: %d\n", 134 printk(KERN_ERR "sa1111ps2: could not allocate IRQ%d: %d\n",
133 ps2if->dev->irq[0], ret); 135 ps2if->dev->irq[0], ret);
136 sa1111_disable_device(ps2if->dev);
134 return ret; 137 return ret;
135 } 138 }
136 139
@@ -140,6 +143,7 @@ static int ps2_open(struct serio *io)
140 printk(KERN_ERR "sa1111ps2: could not allocate IRQ%d: %d\n", 143 printk(KERN_ERR "sa1111ps2: could not allocate IRQ%d: %d\n",
141 ps2if->dev->irq[1], ret); 144 ps2if->dev->irq[1], ret);
142 free_irq(ps2if->dev->irq[0], ps2if); 145 free_irq(ps2if->dev->irq[0], ps2if);
146 sa1111_disable_device(ps2if->dev);
143 return ret; 147 return ret;
144 } 148 }
145 149
diff --git a/drivers/pcmcia/sa1111_generic.c b/drivers/pcmcia/sa1111_generic.c
index 27f2fe3b7fb4..0735c3e6a8b0 100644
--- a/drivers/pcmcia/sa1111_generic.c
+++ b/drivers/pcmcia/sa1111_generic.c
@@ -163,12 +163,18 @@ int sa1111_pcmcia_add(struct sa1111_dev *dev, struct pcmcia_low_level *ops,
163static int pcmcia_probe(struct sa1111_dev *dev) 163static int pcmcia_probe(struct sa1111_dev *dev)
164{ 164{
165 void __iomem *base; 165 void __iomem *base;
166 int ret;
167
168 ret = sa1111_enable_device(dev);
169 if (ret)
170 return ret;
166 171
167 dev_set_drvdata(&dev->dev, NULL); 172 dev_set_drvdata(&dev->dev, NULL);
168 173
169 if (!request_mem_region(dev->res.start, 512, 174 if (!request_mem_region(dev->res.start, 512, SA1111_DRIVER_NAME(dev))) {
170 SA1111_DRIVER_NAME(dev))) 175 sa1111_disable_device(dev);
171 return -EBUSY; 176 return -EBUSY;
177 }
172 178
173 base = dev->mapbase; 179 base = dev->mapbase;
174 180
@@ -212,6 +218,7 @@ static int __devexit pcmcia_remove(struct sa1111_dev *dev)
212 } 218 }
213 219
214 release_mem_region(dev->res.start, 512); 220 release_mem_region(dev->res.start, 512);
221 sa1111_disable_device(dev);
215 return 0; 222 return 0;
216} 223}
217 224
diff --git a/drivers/usb/host/ohci-sa1111.c b/drivers/usb/host/ohci-sa1111.c
index 7d2aa62ea613..f61f4f90529e 100644
--- a/drivers/usb/host/ohci-sa1111.c
+++ b/drivers/usb/host/ohci-sa1111.c
@@ -27,9 +27,10 @@ extern int usb_disabled(void);
27 27
28/*-------------------------------------------------------------------------*/ 28/*-------------------------------------------------------------------------*/
29 29
30static void sa1111_start_hc(struct sa1111_dev *dev) 30static int sa1111_start_hc(struct sa1111_dev *dev)
31{ 31{
32 unsigned int usb_rst = 0; 32 unsigned int usb_rst = 0;
33 int ret;
33 34
34 printk(KERN_DEBUG "%s: starting SA-1111 OHCI USB Controller\n", 35 printk(KERN_DEBUG "%s: starting SA-1111 OHCI USB Controller\n",
35 __FILE__); 36 __FILE__);
@@ -57,9 +58,13 @@ static void sa1111_start_hc(struct sa1111_dev *dev)
57 * Now, carefully enable the USB clock, and take 58 * Now, carefully enable the USB clock, and take
58 * the USB host controller out of reset. 59 * the USB host controller out of reset.
59 */ 60 */
60 sa1111_enable_device(dev); 61 ret = sa1111_enable_device(dev);
61 udelay(11); 62 if (ret == 0) {
62 sa1111_writel(usb_rst, dev->mapbase + SA1111_USB_RESET); 63 udelay(11);
64 sa1111_writel(usb_rst, dev->mapbase + SA1111_USB_RESET);
65 }
66
67 return ret;
63} 68}
64 69
65static void sa1111_stop_hc(struct sa1111_dev *dev) 70static void sa1111_stop_hc(struct sa1111_dev *dev)
@@ -140,7 +145,10 @@ int usb_hcd_sa1111_probe (const struct hc_driver *driver,
140 } 145 }
141 hcd->regs = dev->mapbase; 146 hcd->regs = dev->mapbase;
142 147
143 sa1111_start_hc(dev); 148 ret = sa1111_start_hc(dev);
149 if (ret)
150 goto err2;
151
144 ohci_hcd_init(hcd_to_ohci(hcd)); 152 ohci_hcd_init(hcd_to_ohci(hcd));
145 153
146 retval = usb_add_hcd(hcd, dev->irq[1], 0); 154 retval = usb_add_hcd(hcd, dev->irq[1], 0);
@@ -148,6 +156,7 @@ int usb_hcd_sa1111_probe (const struct hc_driver *driver,
148 return retval; 156 return retval;
149 157
150 sa1111_stop_hc(dev); 158 sa1111_stop_hc(dev);
159 err2:
151 release_mem_region(hcd->rsrc_start, hcd->rsrc_len); 160 release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
152 err1: 161 err1:
153 usb_put_hcd(hcd); 162 usb_put_hcd(hcd);