diff options
-rw-r--r-- | arch/arm/common/sa1111.c | 22 | ||||
-rw-r--r-- | arch/arm/include/asm/hardware/sa1111.h | 8 | ||||
-rw-r--r-- | drivers/input/serio/sa1111ps2.c | 6 | ||||
-rw-r--r-- | drivers/pcmcia/sa1111_generic.c | 11 | ||||
-rw-r--r-- | drivers/usb/host/ohci-sa1111.c | 19 |
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 | */ |
1285 | void sa1111_enable_device(struct sa1111_dev *sadev) | 1287 | int 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 | } |
1296 | EXPORT_SYMBOL(sa1111_enable_device); | 1305 | EXPORT_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 | } |
1313 | EXPORT_SYMBOL(sa1111_disable_device); | 1325 | EXPORT_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 | */ |
561 | void sa1111_enable_device(struct sa1111_dev *); | 562 | int sa1111_enable_device(struct sa1111_dev *); |
562 | void sa1111_disable_device(struct sa1111_dev *); | 563 | void sa1111_disable_device(struct sa1111_dev *); |
563 | 564 | ||
564 | unsigned int sa1111_pll_clock(struct sa1111_dev *); | 565 | unsigned 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 | ||
582 | struct sa1111_platform_data { | 583 | struct 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, | |||
163 | static int pcmcia_probe(struct sa1111_dev *dev) | 163 | static 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 | ||
30 | static void sa1111_start_hc(struct sa1111_dev *dev) | 30 | static 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 | ||
65 | static void sa1111_stop_hc(struct sa1111_dev *dev) | 70 | static 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); |