summaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2012-03-25 23:54:16 +0100
committerRussell King <rmk+kernel@arm.linux.org.uk>2012-03-25 23:54:16 +0100
commit374da9da22ebaad0524c77905b5e89ae4619bef3 (patch)
tree78f8ebbbc2e730b8e510e3a68b5b73755196fb68 /arch
parentfbae0f8912dc12b284433c05417ea76311205bbf (diff)
parent81e6ca3eb74d6bdbab181dd2db378f49f76f0d97 (diff)
downloadlinux-374da9da22ebaad0524c77905b5e89ae4619bef3.tar.bz2
Merge branch 'sa1111' into sa11x0
Conflicts: arch/arm/common/sa1111.c arch/arm/mach-sa1100/neponset.c Fixed: arch/arm/mach-sa1100/assabet.c for the neponset changes
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/common/sa1111.c279
-rw-r--r--arch/arm/include/asm/hardware/sa1111.h156
-rw-r--r--arch/arm/mach-pxa/lubbock.c1
-rw-r--r--arch/arm/mach-sa1100/assabet.c15
-rw-r--r--arch/arm/mach-sa1100/badge4.c21
-rw-r--r--arch/arm/mach-sa1100/jornada720.c6
-rw-r--r--arch/arm/mach-sa1100/neponset.c15
7 files changed, 227 insertions, 266 deletions
diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c
index bf508a78aa33..9173d112ea01 100644
--- a/arch/arm/common/sa1111.c
+++ b/arch/arm/common/sa1111.c
@@ -16,6 +16,7 @@
*/
#include <linux/module.h>
#include <linux/init.h>
+#include <linux/irq.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/errno.h>
@@ -28,9 +29,8 @@
#include <linux/io.h>
#include <mach/hardware.h>
-#include <asm/mach-types.h>
-#include <asm/irq.h>
#include <asm/mach/irq.h>
+#include <asm/mach-types.h>
#include <asm/sizes.h>
#include <asm/hardware/sa1111.h>
@@ -86,8 +86,10 @@
#define IRQ_S1_CD_VALID (52)
#define IRQ_S0_BVD1_STSCHG (53)
#define IRQ_S1_BVD1_STSCHG (54)
+#define SA1111_IRQ_NR (55)
extern void sa1110_mb_enable(void);
+extern void sa1110_mb_disable(void);
/*
* We keep the following data for the overall SA1111. Note that the
@@ -104,6 +106,7 @@ struct sa1111 {
int irq_base; /* base for cascaded on-chip IRQs */
spinlock_t lock;
void __iomem *base;
+ struct sa1111_platform_data *pdata;
#ifdef CONFIG_PM
void *saved_state;
#endif
@@ -118,6 +121,7 @@ static struct sa1111 *g_sa1111;
struct sa1111_dev_info {
unsigned long offset;
unsigned long skpcr_mask;
+ bool dma;
unsigned int devid;
unsigned int irq[6];
};
@@ -126,6 +130,7 @@ static struct sa1111_dev_info sa1111_devices[] = {
{
.offset = SA1111_USB,
.skpcr_mask = SKPCR_UCLKEN,
+ .dma = true,
.devid = SA1111_DEVID_USB,
.irq = {
IRQ_USBPWR,
@@ -139,6 +144,7 @@ static struct sa1111_dev_info sa1111_devices[] = {
{
.offset = 0x0600,
.skpcr_mask = SKPCR_I2SCLKEN | SKPCR_L3CLKEN,
+ .dma = true,
.devid = SA1111_DEVID_SAC,
.irq = {
AUDXMTDMADONEA,
@@ -155,7 +161,7 @@ static struct sa1111_dev_info sa1111_devices[] = {
{
.offset = SA1111_KBD,
.skpcr_mask = SKPCR_PTCLKEN,
- .devid = SA1111_DEVID_PS2,
+ .devid = SA1111_DEVID_PS2_KBD,
.irq = {
IRQ_TPRXINT,
IRQ_TPTXINT
@@ -164,7 +170,7 @@ static struct sa1111_dev_info sa1111_devices[] = {
{
.offset = SA1111_MSE,
.skpcr_mask = SKPCR_PMCLKEN,
- .devid = SA1111_DEVID_PS2,
+ .devid = SA1111_DEVID_PS2_MSE,
.irq = {
IRQ_MSRXINT,
IRQ_MSTXINT
@@ -434,16 +440,28 @@ static struct irq_chip sa1111_high_chip = {
.irq_set_wake = sa1111_wake_highirq,
};
-static void sa1111_setup_irq(struct sa1111 *sachip)
+static int sa1111_setup_irq(struct sa1111 *sachip, unsigned irq_base)
{
void __iomem *irqbase = sachip->base + SA1111_INTC;
- unsigned int irq;
+ unsigned i, irq;
+ int ret;
/*
* We're guaranteed that this region hasn't been taken.
*/
request_mem_region(sachip->phys + SA1111_INTC, 512, "irq");
+ ret = irq_alloc_descs(-1, irq_base, SA1111_IRQ_NR, -1);
+ if (ret <= 0) {
+ dev_err(sachip->dev, "unable to allocate %u irqs: %d\n",
+ SA1111_IRQ_NR, ret);
+ if (ret == 0)
+ ret = -EINVAL;
+ return ret;
+ }
+
+ sachip->irq_base = ret;
+
/* disable all IRQs */
sa1111_writel(0, irqbase + SA1111_INTEN0);
sa1111_writel(0, irqbase + SA1111_INTEN1);
@@ -463,14 +481,16 @@ static void sa1111_setup_irq(struct sa1111 *sachip)
sa1111_writel(~0, irqbase + SA1111_INTSTATCLR0);
sa1111_writel(~0, irqbase + SA1111_INTSTATCLR1);
- for (irq = IRQ_GPAIN0; irq <= SSPROR; irq++) {
+ for (i = IRQ_GPAIN0; i <= SSPROR; i++) {
+ irq = sachip->irq_base + i;
irq_set_chip_and_handler(irq, &sa1111_low_chip,
handle_edge_irq);
irq_set_chip_data(irq, sachip);
set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
}
- for (irq = AUDXMTDMADONEA; irq <= IRQ_S1_BVD1_STSCHG; irq++) {
+ for (i = AUDXMTDMADONEA; i <= IRQ_S1_BVD1_STSCHG; i++) {
+ irq = sachip->irq_base + i;
irq_set_chip_and_handler(irq, &sa1111_high_chip,
handle_edge_irq);
irq_set_chip_data(irq, sachip);
@@ -483,6 +503,11 @@ static void sa1111_setup_irq(struct sa1111 *sachip)
irq_set_irq_type(sachip->irq, IRQ_TYPE_EDGE_RISING);
irq_set_handler_data(sachip->irq, sachip);
irq_set_chained_handler(sachip->irq, sa1111_irq_handler);
+
+ dev_info(sachip->dev, "Providing IRQ%u-%u\n",
+ sachip->irq_base, sachip->irq_base + SA1111_IRQ_NR - 1);
+
+ return 0;
}
/*
@@ -581,41 +606,10 @@ sa1111_configure_smc(struct sa1111 *sachip, int sdram, unsigned int drac,
}
#endif
-#ifdef CONFIG_DMABOUNCE
-/*
- * According to the "Intel StrongARM SA-1111 Microprocessor Companion
- * Chip Specification Update" (June 2000), erratum #7, there is a
- * significant bug in the SA1111 SDRAM shared memory controller. If
- * an access to a region of memory above 1MB relative to the bank base,
- * it is important that address bit 10 _NOT_ be asserted. Depending
- * on the configuration of the RAM, bit 10 may correspond to one
- * of several different (processor-relative) address bits.
- *
- * This routine only identifies whether or not a given DMA address
- * is susceptible to the bug.
- *
- * This should only get called for sa1111_device types due to the
- * way we configure our device dma_masks.
- */
-static int sa1111_needs_bounce(struct device *dev, dma_addr_t addr, size_t size)
-{
- /*
- * Section 4.6 of the "Intel StrongARM SA-1111 Development Module
- * User's Guide" mentions that jumpers R51 and R52 control the
- * target of SA-1111 DMA (either SDRAM bank 0 on Assabet, or
- * SDRAM bank 1 on Neponset). The default configuration selects
- * Assabet, so any address in bank 1 is necessarily invalid.
- */
- return (machine_is_assabet() || machine_is_pfs168()) &&
- (addr >= 0xc8000000 || (addr + size) >= 0xc8000000);
-}
-#endif
-
static void sa1111_dev_release(struct device *_dev)
{
struct sa1111_dev *dev = SA1111_DEV(_dev);
- release_resource(&dev->res);
kfree(dev);
}
@@ -624,67 +618,58 @@ sa1111_init_one_child(struct sa1111 *sachip, struct resource *parent,
struct sa1111_dev_info *info)
{
struct sa1111_dev *dev;
+ unsigned i;
int ret;
dev = kzalloc(sizeof(struct sa1111_dev), GFP_KERNEL);
if (!dev) {
ret = -ENOMEM;
- goto out;
+ goto err_alloc;
}
+ device_initialize(&dev->dev);
dev_set_name(&dev->dev, "%4.4lx", info->offset);
dev->devid = info->devid;
dev->dev.parent = sachip->dev;
dev->dev.bus = &sa1111_bus_type;
dev->dev.release = sa1111_dev_release;
- dev->dev.coherent_dma_mask = sachip->dev->coherent_dma_mask;
dev->res.start = sachip->phys + info->offset;
dev->res.end = dev->res.start + 511;
dev->res.name = dev_name(&dev->dev);
dev->res.flags = IORESOURCE_MEM;
dev->mapbase = sachip->base + info->offset;
dev->skpcr_mask = info->skpcr_mask;
- memmove(dev->irq, info->irq, sizeof(dev->irq));
-
- ret = request_resource(parent, &dev->res);
- if (ret) {
- printk("SA1111: failed to allocate resource for %s\n",
- dev->res.name);
- dev_set_name(&dev->dev, NULL);
- kfree(dev);
- goto out;
- }
-
- ret = device_register(&dev->dev);
- if (ret) {
- release_resource(&dev->res);
- kfree(dev);
- goto out;
- }
+ for (i = 0; i < ARRAY_SIZE(info->irq); i++)
+ dev->irq[i] = sachip->irq_base + info->irq[i];
-#ifdef CONFIG_DMABOUNCE
/*
- * If the parent device has a DMA mask associated with it,
- * propagate it down to the children.
+ * If the parent device has a DMA mask associated with it, and
+ * this child supports DMA, propagate it down to the children.
*/
- if (sachip->dev->dma_mask) {
+ if (info->dma && sachip->dev->dma_mask) {
dev->dma_mask = *sachip->dev->dma_mask;
dev->dev.dma_mask = &dev->dma_mask;
+ dev->dev.coherent_dma_mask = sachip->dev->coherent_dma_mask;
+ }
- if (dev->dma_mask != 0xffffffffUL) {
- ret = dmabounce_register_dev(&dev->dev, 1024, 4096,
- sa1111_needs_bounce);
- if (ret) {
- dev_err(&dev->dev, "SA1111: Failed to register"
- " with dmabounce\n");
- device_unregister(&dev->dev);
- }
- }
+ ret = request_resource(parent, &dev->res);
+ if (ret) {
+ dev_err(sachip->dev, "failed to allocate resource for %s\n",
+ dev->res.name);
+ goto err_resource;
}
-#endif
-out:
+ ret = device_add(&dev->dev);
+ if (ret)
+ goto err_add;
+ return 0;
+
+ err_add:
+ release_resource(&dev->res);
+ err_resource:
+ put_device(&dev->dev);
+ err_alloc:
return ret;
}
@@ -698,16 +683,21 @@ out:
* Returns:
* %-ENODEV device not found.
* %-EBUSY physical address already marked in-use.
+ * %-EINVAL no platform data passed
* %0 successful.
*/
static int __devinit
__sa1111_probe(struct device *me, struct resource *mem, int irq)
{
+ struct sa1111_platform_data *pd = me->platform_data;
struct sa1111 *sachip;
unsigned long id;
unsigned int has_devs;
int i, ret = -ENODEV;
+ if (!pd)
+ return -EINVAL;
+
sachip = kzalloc(sizeof(struct sa1111), GFP_KERNEL);
if (!sachip)
return -ENOMEM;
@@ -727,6 +717,7 @@ __sa1111_probe(struct device *me, struct resource *mem, int irq)
sachip->dev = me;
dev_set_drvdata(sachip->dev, sachip);
+ sachip->pdata = pd;
sachip->phys = mem->start;
sachip->irq = irq;
@@ -759,6 +750,16 @@ __sa1111_probe(struct device *me, struct resource *mem, int irq)
*/
sa1111_wake(sachip);
+ /*
+ * The interrupt controller must be initialised before any
+ * other device to ensure that the interrupts are available.
+ */
+ if (sachip->irq != NO_IRQ) {
+ ret = sa1111_setup_irq(sachip, pd->irq_base);
+ if (ret)
+ goto err_unmap;
+ }
+
#ifdef CONFIG_ARCH_SA1100
{
unsigned int val;
@@ -789,24 +790,14 @@ __sa1111_probe(struct device *me, struct resource *mem, int irq)
}
#endif
- /*
- * The interrupt controller must be initialised before any
- * other device to ensure that the interrupts are available.
- */
- if (sachip->irq != NO_IRQ)
- sa1111_setup_irq(sachip);
-
g_sa1111 = sachip;
has_devs = ~0;
- if (machine_is_assabet() || machine_is_jornada720() ||
- machine_is_badge4())
- has_devs &= ~(1 << 4);
- else
- has_devs &= ~(1 << 1);
+ if (pd)
+ has_devs &= ~pd->disable_devs;
for (i = 0; i < ARRAY_SIZE(sa1111_devices); i++)
- if (has_devs & (1 << i))
+ if (sa1111_devices[i].devid & has_devs)
sa1111_init_one_child(sachip, mem, &sa1111_devices[i]);
return 0;
@@ -824,7 +815,10 @@ __sa1111_probe(struct device *me, struct resource *mem, int irq)
static int sa1111_remove_one(struct device *dev, void *data)
{
- device_unregister(dev);
+ struct sa1111_dev *sadev = SA1111_DEV(dev);
+ device_del(&sadev->dev);
+ release_resource(&sadev->res);
+ put_device(&sadev->dev);
return 0;
}
@@ -846,6 +840,7 @@ static void __sa1111_remove(struct sa1111 *sachip)
if (sachip->irq != NO_IRQ) {
irq_set_chained_handler(sachip->irq, NULL);
irq_set_handler_data(sachip->irq, NULL);
+ irq_free_descs(sachip->irq_base, SA1111_IRQ_NR);
release_mem_region(sachip->phys + SA1111_INTC, 512);
}
@@ -904,6 +899,9 @@ static int sa1111_suspend(struct platform_device *dev, pm_message_t state)
save->skpwm0 = sa1111_readl(base + SA1111_SKPWM0);
save->skpwm1 = sa1111_readl(base + SA1111_SKPWM1);
+ sa1111_writel(0, sachip->base + SA1111_SKPWM0);
+ sa1111_writel(0, sachip->base + SA1111_SKPWM1);
+
base = sachip->base + SA1111_INTC;
save->intpol0 = sa1111_readl(base + SA1111_INTPOL0);
save->intpol1 = sa1111_readl(base + SA1111_INTPOL1);
@@ -919,13 +917,15 @@ static int sa1111_suspend(struct platform_device *dev, pm_message_t state)
*/
val = sa1111_readl(sachip->base + SA1111_SKCR);
sa1111_writel(val | SKCR_SLEEP, sachip->base + SA1111_SKCR);
- sa1111_writel(0, sachip->base + SA1111_SKPWM0);
- sa1111_writel(0, sachip->base + SA1111_SKPWM1);
clk_disable(sachip->clk);
spin_unlock_irqrestore(&sachip->lock, flags);
+#ifdef CONFIG_ARCH_SA1100
+ sa1110_mb_disable();
+#endif
+
return 0;
}
@@ -966,6 +966,11 @@ static int sa1111_resume(struct platform_device *dev)
*/
sa1111_wake(sachip);
+#ifdef CONFIG_ARCH_SA1100
+ /* Enable the memory bus request/grant signals */
+ sa1110_mb_enable();
+#endif
+
/*
* Only lock for write ops. Also, sa1111_wake must be called with
* released spinlock!
@@ -1053,6 +1058,7 @@ static struct platform_driver sa1111_device_driver = {
.resume = sa1111_resume,
.driver = {
.name = "sa1111",
+ .owner = THIS_MODULE,
},
};
@@ -1238,16 +1244,23 @@ EXPORT_SYMBOL(sa1111_set_sleep_io);
* sa1111_enable_device - enable an on-chip SA1111 function block
* @sadev: SA1111 function block device to enable
*/
-void sa1111_enable_device(struct sa1111_dev *sadev)
+int sa1111_enable_device(struct sa1111_dev *sadev)
{
struct sa1111 *sachip = sa1111_chip_driver(sadev);
unsigned long flags;
unsigned int val;
+ int ret = 0;
- spin_lock_irqsave(&sachip->lock, flags);
- val = sa1111_readl(sachip->base + SA1111_SKPCR);
- sa1111_writel(val | sadev->skpcr_mask, sachip->base + SA1111_SKPCR);
- spin_unlock_irqrestore(&sachip->lock, flags);
+ if (sachip->pdata && sachip->pdata->enable)
+ ret = sachip->pdata->enable(sachip->pdata->data, sadev->devid);
+
+ if (ret == 0) {
+ spin_lock_irqsave(&sachip->lock, flags);
+ val = sa1111_readl(sachip->base + SA1111_SKPCR);
+ sa1111_writel(val | sadev->skpcr_mask, sachip->base + SA1111_SKPCR);
+ spin_unlock_irqrestore(&sachip->lock, flags);
+ }
+ return ret;
}
EXPORT_SYMBOL(sa1111_enable_device);
@@ -1265,6 +1278,9 @@ void sa1111_disable_device(struct sa1111_dev *sadev)
val = sa1111_readl(sachip->base + SA1111_SKPCR);
sa1111_writel(val & ~sadev->skpcr_mask, sachip->base + SA1111_SKPCR);
spin_unlock_irqrestore(&sachip->lock, flags);
+
+ if (sachip->pdata && sachip->pdata->disable)
+ sachip->pdata->disable(sachip->pdata->data, sadev->devid);
}
EXPORT_SYMBOL(sa1111_disable_device);
@@ -1279,7 +1295,7 @@ static int sa1111_match(struct device *_dev, struct device_driver *_drv)
struct sa1111_dev *dev = SA1111_DEV(_dev);
struct sa1111_driver *drv = SA1111_DRV(_drv);
- return dev->devid == drv->devid;
+ return dev->devid & drv->devid;
}
static int sa1111_bus_suspend(struct device *dev, pm_message_t state)
@@ -1304,6 +1320,14 @@ static int sa1111_bus_resume(struct device *dev)
return ret;
}
+static void sa1111_bus_shutdown(struct device *dev)
+{
+ struct sa1111_driver *drv = SA1111_DRV(dev->driver);
+
+ if (drv && drv->shutdown)
+ drv->shutdown(SA1111_DEV(dev));
+}
+
static int sa1111_bus_probe(struct device *dev)
{
struct sa1111_dev *sadev = SA1111_DEV(dev);
@@ -1333,6 +1357,7 @@ struct bus_type sa1111_bus_type = {
.remove = sa1111_bus_remove,
.suspend = sa1111_bus_suspend,
.resume = sa1111_bus_resume,
+ .shutdown = sa1111_bus_shutdown,
};
EXPORT_SYMBOL(sa1111_bus_type);
@@ -1349,9 +1374,70 @@ void sa1111_driver_unregister(struct sa1111_driver *driver)
}
EXPORT_SYMBOL(sa1111_driver_unregister);
+#ifdef CONFIG_DMABOUNCE
+/*
+ * According to the "Intel StrongARM SA-1111 Microprocessor Companion
+ * Chip Specification Update" (June 2000), erratum #7, there is a
+ * significant bug in the SA1111 SDRAM shared memory controller. If
+ * an access to a region of memory above 1MB relative to the bank base,
+ * it is important that address bit 10 _NOT_ be asserted. Depending
+ * on the configuration of the RAM, bit 10 may correspond to one
+ * of several different (processor-relative) address bits.
+ *
+ * This routine only identifies whether or not a given DMA address
+ * is susceptible to the bug.
+ *
+ * This should only get called for sa1111_device types due to the
+ * way we configure our device dma_masks.
+ */
+static int sa1111_needs_bounce(struct device *dev, dma_addr_t addr, size_t size)
+{
+ /*
+ * Section 4.6 of the "Intel StrongARM SA-1111 Development Module
+ * User's Guide" mentions that jumpers R51 and R52 control the
+ * target of SA-1111 DMA (either SDRAM bank 0 on Assabet, or
+ * SDRAM bank 1 on Neponset). The default configuration selects
+ * Assabet, so any address in bank 1 is necessarily invalid.
+ */
+ return (machine_is_assabet() || machine_is_pfs168()) &&
+ (addr >= 0xc8000000 || (addr + size) >= 0xc8000000);
+}
+
+static int sa1111_notifier_call(struct notifier_block *n, unsigned long action,
+ void *data)
+{
+ struct sa1111_dev *dev = SA1111_DEV(data);
+
+ switch (action) {
+ case BUS_NOTIFY_ADD_DEVICE:
+ if (dev->dev.dma_mask && dev->dma_mask < 0xffffffffUL) {
+ int ret = dmabounce_register_dev(&dev->dev, 1024, 4096,
+ sa1111_needs_bounce);
+ if (ret)
+ dev_err(&dev->dev, "failed to register with dmabounce: %d\n", ret);
+ }
+ break;
+
+ case BUS_NOTIFY_DEL_DEVICE:
+ if (dev->dev.dma_mask && dev->dma_mask < 0xffffffffUL)
+ dmabounce_unregister_dev(&dev->dev);
+ break;
+ }
+ return NOTIFY_OK;
+}
+
+static struct notifier_block sa1111_bus_notifier = {
+ .notifier_call = sa1111_notifier_call,
+};
+#endif
+
static int __init sa1111_init(void)
{
int ret = bus_register(&sa1111_bus_type);
+#ifdef CONFIG_DMABOUNCE
+ if (ret == 0)
+ bus_register_notifier(&sa1111_bus_type, &sa1111_bus_notifier);
+#endif
if (ret == 0)
platform_driver_register(&sa1111_device_driver);
return ret;
@@ -1360,6 +1446,9 @@ static int __init sa1111_init(void)
static void __exit sa1111_exit(void)
{
platform_driver_unregister(&sa1111_device_driver);
+#ifdef CONFIG_DMABOUNCE
+ bus_unregister_notifier(&sa1111_bus_type, &sa1111_bus_notifier);
+#endif
bus_unregister(&sa1111_bus_type);
}
diff --git a/arch/arm/include/asm/hardware/sa1111.h b/arch/arm/include/asm/hardware/sa1111.h
index 92ed254c175b..7c2bbc7f0be1 100644
--- a/arch/arm/include/asm/hardware/sa1111.h
+++ b/arch/arm/include/asm/hardware/sa1111.h
@@ -132,34 +132,10 @@
#define SKPCR_DCLKEN (1<<7)
#define SKPCR_PWMCLKEN (1<<8)
-/*
- * USB Host controller
- */
+/* USB Host controller */
#define SA1111_USB 0x0400
/*
- * Offsets from SA1111_USB_BASE
- */
-#define SA1111_USB_STATUS 0x0118
-#define SA1111_USB_RESET 0x011c
-#define SA1111_USB_IRQTEST 0x0120
-
-#define USB_RESET_FORCEIFRESET (1 << 0)
-#define USB_RESET_FORCEHCRESET (1 << 1)
-#define USB_RESET_CLKGENRESET (1 << 2)
-#define USB_RESET_SIMSCALEDOWN (1 << 3)
-#define USB_RESET_USBINTTEST (1 << 4)
-#define USB_RESET_SLEEPSTBYEN (1 << 5)
-#define USB_RESET_PWRSENSELOW (1 << 6)
-#define USB_RESET_PWRCTRLLOW (1 << 7)
-
-#define USB_STATUS_IRQHCIRMTWKUP (1 << 7)
-#define USB_STATUS_IRQHCIBUFFACC (1 << 8)
-#define USB_STATUS_NIRQHCIM (1 << 9)
-#define USB_STATUS_NHCIMFCLR (1 << 10)
-#define USB_STATUS_USBPWRSENSE (1 << 11)
-
-/*
* Serial Audio Controller
*
* Registers
@@ -327,22 +303,6 @@
* PC_SSR GPIO Block C Sleep State
*/
-#define _PA_DDR _SA1111( 0x1000 )
-#define _PA_DRR _SA1111( 0x1004 )
-#define _PA_DWR _SA1111( 0x1004 )
-#define _PA_SDR _SA1111( 0x1008 )
-#define _PA_SSR _SA1111( 0x100c )
-#define _PB_DDR _SA1111( 0x1010 )
-#define _PB_DRR _SA1111( 0x1014 )
-#define _PB_DWR _SA1111( 0x1014 )
-#define _PB_SDR _SA1111( 0x1018 )
-#define _PB_SSR _SA1111( 0x101c )
-#define _PC_DDR _SA1111( 0x1020 )
-#define _PC_DRR _SA1111( 0x1024 )
-#define _PC_DWR _SA1111( 0x1024 )
-#define _PC_SDR _SA1111( 0x1028 )
-#define _PC_SSR _SA1111( 0x102c )
-
#define SA1111_GPIO 0x1000
#define SA1111_GPIO_PADDR (0x000)
@@ -425,106 +385,30 @@
#define SA1111_WAKEPOL0 0x0034
#define SA1111_WAKEPOL1 0x0038
-/*
- * PS/2 Trackpad and Mouse Interfaces
- *
- * Registers
- * PS2CR Control Register
- * PS2STAT Status Register
- * PS2DATA Transmit/Receive Data register
- * PS2CLKDIV Clock Division Register
- * PS2PRECNT Clock Precount Register
- * PS2TEST1 Test register 1
- * PS2TEST2 Test register 2
- * PS2TEST3 Test register 3
- * PS2TEST4 Test register 4
- */
-
+/* PS/2 Trackpad and Mouse Interfaces */
#define SA1111_KBD 0x0a00
#define SA1111_MSE 0x0c00
-/*
- * These are offsets from the above bases.
- */
-#define SA1111_PS2CR 0x0000
-#define SA1111_PS2STAT 0x0004
-#define SA1111_PS2DATA 0x0008
-#define SA1111_PS2CLKDIV 0x000c
-#define SA1111_PS2PRECNT 0x0010
-
-#define PS2CR_ENA 0x08
-#define PS2CR_FKD 0x02
-#define PS2CR_FKC 0x01
-
-#define PS2STAT_STP 0x0100
-#define PS2STAT_TXE 0x0080
-#define PS2STAT_TXB 0x0040
-#define PS2STAT_RXF 0x0020
-#define PS2STAT_RXB 0x0010
-#define PS2STAT_ENA 0x0008
-#define PS2STAT_RXP 0x0004
-#define PS2STAT_KBD 0x0002
-#define PS2STAT_KBC 0x0001
+/* PCMCIA Interface */
+#define SA1111_PCMCIA 0x1600
-/*
- * PCMCIA Interface
- *
- * Registers
- * PCSR Status Register
- * PCCR Control Register
- * PCSSR Sleep State Register
- */
-
-#define SA1111_PCMCIA 0x1600
-
-/*
- * These are offsets from the above base.
- */
-#define SA1111_PCCR 0x0000
-#define SA1111_PCSSR 0x0004
-#define SA1111_PCSR 0x0008
-
-#define PCSR_S0_READY (1<<0)
-#define PCSR_S1_READY (1<<1)
-#define PCSR_S0_DETECT (1<<2)
-#define PCSR_S1_DETECT (1<<3)
-#define PCSR_S0_VS1 (1<<4)
-#define PCSR_S0_VS2 (1<<5)
-#define PCSR_S1_VS1 (1<<6)
-#define PCSR_S1_VS2 (1<<7)
-#define PCSR_S0_WP (1<<8)
-#define PCSR_S1_WP (1<<9)
-#define PCSR_S0_BVD1 (1<<10)
-#define PCSR_S0_BVD2 (1<<11)
-#define PCSR_S1_BVD1 (1<<12)
-#define PCSR_S1_BVD2 (1<<13)
-
-#define PCCR_S0_RST (1<<0)
-#define PCCR_S1_RST (1<<1)
-#define PCCR_S0_FLT (1<<2)
-#define PCCR_S1_FLT (1<<3)
-#define PCCR_S0_PWAITEN (1<<4)
-#define PCCR_S1_PWAITEN (1<<5)
-#define PCCR_S0_PSE (1<<6)
-#define PCCR_S1_PSE (1<<7)
-
-#define PCSSR_S0_SLEEP (1<<0)
-#define PCSSR_S1_SLEEP (1<<1)
extern struct bus_type sa1111_bus_type;
-#define SA1111_DEVID_SBI 0
-#define SA1111_DEVID_SK 1
-#define SA1111_DEVID_USB 2
-#define SA1111_DEVID_SAC 3
-#define SA1111_DEVID_SSP 4
-#define SA1111_DEVID_PS2 5
-#define SA1111_DEVID_GPIO 6
-#define SA1111_DEVID_INT 7
-#define SA1111_DEVID_PCMCIA 8
+#define SA1111_DEVID_SBI (1 << 0)
+#define SA1111_DEVID_SK (1 << 1)
+#define SA1111_DEVID_USB (1 << 2)
+#define SA1111_DEVID_SAC (1 << 3)
+#define SA1111_DEVID_SSP (1 << 4)
+#define SA1111_DEVID_PS2 (3 << 5)
+#define SA1111_DEVID_PS2_KBD (1 << 5)
+#define SA1111_DEVID_PS2_MSE (1 << 6)
+#define SA1111_DEVID_GPIO (1 << 7)
+#define SA1111_DEVID_INT (1 << 8)
+#define SA1111_DEVID_PCMCIA (1 << 9)
struct sa1111_dev {
struct device dev;
@@ -548,6 +432,7 @@ struct sa1111_driver {
int (*remove)(struct sa1111_dev *);
int (*suspend)(struct sa1111_dev *, pm_message_t);
int (*resume)(struct sa1111_dev *);
+ void (*shutdown)(struct sa1111_dev *);
};
#define SA1111_DRV(_d) container_of((_d), struct sa1111_driver, drv)
@@ -555,9 +440,10 @@ struct sa1111_driver {
#define SA1111_DRIVER_NAME(_sadev) ((_sadev)->dev.driver->name)
/*
- * These frob the SKPCR register.
+ * These frob the SKPCR register, and call platform specific
+ * enable/disable functions.
*/
-void sa1111_enable_device(struct sa1111_dev *);
+int sa1111_enable_device(struct sa1111_dev *);
void sa1111_disable_device(struct sa1111_dev *);
unsigned int sa1111_pll_clock(struct sa1111_dev *);
@@ -580,6 +466,10 @@ void sa1111_set_sleep_io(struct sa1111_dev *sadev, unsigned int bits, unsigned i
struct sa1111_platform_data {
int irq_base; /* base for cascaded on-chip IRQs */
+ unsigned disable_devs;
+ void *data;
+ int (*enable)(void *, unsigned);
+ void (*disable)(void *, unsigned);
};
#endif /* _ASM_ARCH_SA1111 */
diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c
index 6ebd276aebeb..6bb3f47b1f14 100644
--- a/arch/arm/mach-pxa/lubbock.c
+++ b/arch/arm/mach-pxa/lubbock.c
@@ -223,6 +223,7 @@ static struct resource sa1111_resources[] = {
static struct sa1111_platform_data sa1111_info = {
.irq_base = LUBBOCK_SA1111_IRQ_BASE,
+ .disable_devs = SA1111_DEVID_SAC,
};
static struct platform_device sa1111_device = {
diff --git a/arch/arm/mach-sa1100/assabet.c b/arch/arm/mach-sa1100/assabet.c
index f2030bc22cde..e2d411a8d4ce 100644
--- a/arch/arm/mach-sa1100/assabet.c
+++ b/arch/arm/mach-sa1100/assabet.c
@@ -425,21 +425,8 @@ static void __init assabet_map_io(void)
*/
Ser1SDCR0 |= SDCR0_SUS;
- if (machine_has_neponset()) {
-#ifdef CONFIG_ASSABET_NEPONSET
- extern void neponset_map_io(void);
-
- /*
- * We map Neponset registers even if it isn't present since
- * many drivers will try to probe their stuff (and fail).
- * This is still more friendly than a kernel paging request
- * crash.
- */
- neponset_map_io();
-#endif
- } else {
+ if (!machine_has_neponset())
sa1100_register_uart_fns(&assabet_port_fns);
- }
/*
* When Neponset is attached, the first UART should be
diff --git a/arch/arm/mach-sa1100/badge4.c b/arch/arm/mach-sa1100/badge4.c
index ce2dbdf4ba1a..5839c9d8bb92 100644
--- a/arch/arm/mach-sa1100/badge4.c
+++ b/arch/arm/mach-sa1100/badge4.c
@@ -43,8 +43,24 @@ static struct resource sa1111_resources[] = {
[1] = DEFINE_RES_IRQ(BADGE4_IRQ_GPIO_SA1111),
};
+static int badge4_sa1111_enable(void *data, unsigned devid)
+{
+ if (devid == SA1111_DEVID_USB)
+ badge4_set_5V(BADGE4_5V_USB, 1);
+ return 0;
+}
+
+static void badge4_sa1111_disable(void *data, unsigned devid)
+{
+ if (devid == SA1111_DEVID_USB)
+ badge4_set_5V(BADGE4_5V_USB, 0);
+}
+
static struct sa1111_platform_data sa1111_info = {
.irq_base = IRQ_BOARD_END,
+ .disable_devs = SA1111_DEVID_PS2_MSE,
+ .enable = badge4_sa1111_enable,
+ .disable = badge4_sa1111_disable,
};
static u64 sa1111_dmamask = 0xffffffffUL;
@@ -258,11 +274,6 @@ static struct map_desc badge4_io_desc[] __initdata = {
.pfn = __phys_to_pfn(0x10000000),
.length = 0x00100000,
.type = MT_DEVICE
- }, { /* SA-1111 */
- .virtual = 0xf4000000,
- .pfn = __phys_to_pfn(0x48000000),
- .length = 0x00100000,
- .type = MT_DEVICE
}
};
diff --git a/arch/arm/mach-sa1100/jornada720.c b/arch/arm/mach-sa1100/jornada720.c
index 8512cfcc0d9b..8be8130baf63 100644
--- a/arch/arm/mach-sa1100/jornada720.c
+++ b/arch/arm/mach-sa1100/jornada720.c
@@ -195,6 +195,7 @@ static struct resource sa1111_resources[] = {
static struct sa1111_platform_data sa1111_info = {
.irq_base = IRQ_BOARD_END,
+ .disable_devs = SA1111_DEVID_PS2_MSE,
};
static u64 sa1111_dmamask = 0xffffffffUL;
@@ -268,11 +269,6 @@ static struct map_desc jornada720_io_desc[] __initdata = {
.pfn = __phys_to_pfn(EPSONFBSTART),
.length = EPSONFBLEN,
.type = MT_DEVICE
- }, { /* SA-1111 */
- .virtual = 0xf4000000,
- .pfn = __phys_to_pfn(SA1111REGSTART),
- .length = SA1111REGLEN,
- .type = MT_DEVICE
}
};
diff --git a/arch/arm/mach-sa1100/neponset.c b/arch/arm/mach-sa1100/neponset.c
index 7ffa631eede4..3297aa22cd77 100644
--- a/arch/arm/mach-sa1100/neponset.c
+++ b/arch/arm/mach-sa1100/neponset.c
@@ -229,6 +229,7 @@ static struct irq_chip nochip = {
static struct sa1111_platform_data sa1111_info = {
.irq_base = IRQ_BOARD_END,
+ .disable_devs = SA1111_DEVID_PS2_MSE,
};
static int __devinit neponset_probe(struct platform_device *dev)
@@ -432,17 +433,3 @@ static int __init neponset_init(void)
}
subsys_initcall(neponset_init);
-
-static struct map_desc neponset_io_desc[] __initdata = {
- { /* SA-1111 */
- .virtual = 0xf4000000,
- .pfn = __phys_to_pfn(0x40000000),
- .length = SZ_1M,
- .type = MT_DEVICE
- }
-};
-
-void __init neponset_map_io(void)
-{
- iotable_init(neponset_io_desc, ARRAY_SIZE(neponset_io_desc));
-}