提交 9e4db1c3 编写于 作者: L Linus Torvalds

Merge branch 'platforms' of git://git.linaro.org/people/rmk/linux-arm

Pull ARM platform updates from Russell King:
 "This covers platform stuff for platforms I have a direct interest in
  (iow, I have the hardware).  Essentially:
   - as we no longer support any other Acorn platforms other than RiscPC
     anymore, we can collect all that code into mach-rpc.
   - convert Acorn expansion card stuff to use IRQ allocation functions,
     and get rid of NO_IRQ from there.
   - cleanups to the ebsa110 platform to move some private stuff out of
     its header files.
   - large amount of SA11x0 updates:
   - conversion of private DMA implementation to DMA engine support
     (this actually gives us greater flexibility in drivers over the old
     API.)
   - re-worked ucb1x00 updates - convert to genirq, remove sa11x0
     dependencies, fix various minor issues
   - move platform specific sa11x0 framebuffer data into platform files
     in arch/arm instead of keeping this in the driver itself
   - update sa11x0 IrDA driver for DMA engine, and allow it to use DMA
     for SIR transmissions as well as FIR
   - rework sa1111 support for genirq, and irq allocation
   - fix sa1111 IRQ support so it works again
   - use sparse IRQ support

  After this, I have one more pull request remaining from my current
  set, which I think is going to be the most problematical as it
  generates 8 conflicts."

Fixed up the trivial conflict in arch/arm/mach-rpc/Makefile as per
Russell.

* 'platforms' of git://git.linaro.org/people/rmk/linux-arm: (125 commits)
  ARM: 7343/1: sa11x0: convert to sparse IRQ
  ARM: 7342/2: sa1100: prepare for sparse irq conversion
  ARM: 7341/1: input: prepare jornada720 keyboard and ts for sa11x0 sparse irq
  ARM: 7340/1: rtc: sa1100: include mach/irqs.h instead of asm/irq.h
  ARM: sa11x0: remove unused DMA controller definitions
  ARM: sa11x0: remove old SoC private DMA driver
  USB: sa1111: add hcd .reset method
  USB: sa1111: add OHCI shutdown methods
  USB: sa1111: reorganize ohci-sa1111.c
  USB: sa1111: get rid of nasty printk(KERN_DEBUG "%s: ...", __FILE__)
  USB: sa1111: sparse and checkpatch cleanups
  ARM: sa11x0: don't static map sa1111
  ARM: sa1111: use dev_err() rather than printk()
  ARM: sa1111: cleanup sub-device registration and unregistration
  ARM: sa1111: only setup DMA for DMA capable devices
  ARM: sa1111: register sa1111 devices with dmabounce in bus notifier
  ARM: sa1111: move USB interface register definitions to ohci-sa1111.c
  ARM: sa1111: move PCMCIA interface register definitions to sa1111_generic.c
  ARM: sa1111: move PS/2 interface register definitions to sa1111p2.c
  ARM: sa1111: delete unused physical GPIO register definitions
  ...
...@@ -738,7 +738,6 @@ config ARCH_RPC ...@@ -738,7 +738,6 @@ config ARCH_RPC
bool "RiscPC" bool "RiscPC"
select ARCH_ACORN select ARCH_ACORN
select FIQ select FIQ
select TIMER_ACORN
select ARCH_MAY_HAVE_PC_FDC select ARCH_MAY_HAVE_PC_FDC
select HAVE_PATA_PLATFORM select HAVE_PATA_PLATFORM
select ISA_DMA_API select ISA_DMA_API
...@@ -767,6 +766,7 @@ config ARCH_SA1100 ...@@ -767,6 +766,7 @@ config ARCH_SA1100
select ARCH_REQUIRE_GPIOLIB select ARCH_REQUIRE_GPIOLIB
select HAVE_IDE select HAVE_IDE
select NEED_MACH_MEMORY_H select NEED_MACH_MEMORY_H
select SPARSE_IRQ
help help
Support for StrongARM 11x0 based boards. Support for StrongARM 11x0 based boards.
......
...@@ -35,9 +35,6 @@ config DMABOUNCE ...@@ -35,9 +35,6 @@ config DMABOUNCE
bool bool
select ZONE_DMA select ZONE_DMA
config TIMER_ACORN
bool
config SHARP_LOCOMO config SHARP_LOCOMO
bool bool
......
...@@ -9,7 +9,6 @@ obj-$(CONFIG_PL330) += pl330.o ...@@ -9,7 +9,6 @@ obj-$(CONFIG_PL330) += pl330.o
obj-$(CONFIG_SA1111) += sa1111.o obj-$(CONFIG_SA1111) += sa1111.o
obj-$(CONFIG_PCI_HOST_VIA82C505) += via82c505.o obj-$(CONFIG_PCI_HOST_VIA82C505) += via82c505.o
obj-$(CONFIG_DMABOUNCE) += dmabounce.o obj-$(CONFIG_DMABOUNCE) += dmabounce.o
obj-$(CONFIG_TIMER_ACORN) += time-acorn.o
obj-$(CONFIG_SHARP_LOCOMO) += locomo.o obj-$(CONFIG_SHARP_LOCOMO) += locomo.o
obj-$(CONFIG_SHARP_PARAM) += sharpsl_param.o obj-$(CONFIG_SHARP_PARAM) += sharpsl_param.o
obj-$(CONFIG_SHARP_SCOOP) += scoop.o obj-$(CONFIG_SHARP_SCOOP) += scoop.o
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
*/ */
#include <linux/module.h> #include <linux/module.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/irq.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/errno.h> #include <linux/errno.h>
...@@ -28,9 +29,8 @@ ...@@ -28,9 +29,8 @@
#include <linux/io.h> #include <linux/io.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <asm/mach-types.h>
#include <asm/irq.h>
#include <asm/mach/irq.h> #include <asm/mach/irq.h>
#include <asm/mach-types.h>
#include <asm/sizes.h> #include <asm/sizes.h>
#include <asm/hardware/sa1111.h> #include <asm/hardware/sa1111.h>
...@@ -86,8 +86,10 @@ ...@@ -86,8 +86,10 @@
#define IRQ_S1_CD_VALID (52) #define IRQ_S1_CD_VALID (52)
#define IRQ_S0_BVD1_STSCHG (53) #define IRQ_S0_BVD1_STSCHG (53)
#define IRQ_S1_BVD1_STSCHG (54) #define IRQ_S1_BVD1_STSCHG (54)
#define SA1111_IRQ_NR (55)
extern void __init sa1110_mb_enable(void); extern void sa1110_mb_enable(void);
extern void sa1110_mb_disable(void);
/* /*
* We keep the following data for the overall SA1111. Note that the * We keep the following data for the overall SA1111. Note that the
...@@ -104,6 +106,7 @@ struct sa1111 { ...@@ -104,6 +106,7 @@ struct sa1111 {
int irq_base; /* base for cascaded on-chip IRQs */ int irq_base; /* base for cascaded on-chip IRQs */
spinlock_t lock; spinlock_t lock;
void __iomem *base; void __iomem *base;
struct sa1111_platform_data *pdata;
#ifdef CONFIG_PM #ifdef CONFIG_PM
void *saved_state; void *saved_state;
#endif #endif
...@@ -118,6 +121,7 @@ static struct sa1111 *g_sa1111; ...@@ -118,6 +121,7 @@ static struct sa1111 *g_sa1111;
struct sa1111_dev_info { struct sa1111_dev_info {
unsigned long offset; unsigned long offset;
unsigned long skpcr_mask; unsigned long skpcr_mask;
bool dma;
unsigned int devid; unsigned int devid;
unsigned int irq[6]; unsigned int irq[6];
}; };
...@@ -126,6 +130,7 @@ static struct sa1111_dev_info sa1111_devices[] = { ...@@ -126,6 +130,7 @@ static struct sa1111_dev_info sa1111_devices[] = {
{ {
.offset = SA1111_USB, .offset = SA1111_USB,
.skpcr_mask = SKPCR_UCLKEN, .skpcr_mask = SKPCR_UCLKEN,
.dma = true,
.devid = SA1111_DEVID_USB, .devid = SA1111_DEVID_USB,
.irq = { .irq = {
IRQ_USBPWR, IRQ_USBPWR,
...@@ -139,6 +144,7 @@ static struct sa1111_dev_info sa1111_devices[] = { ...@@ -139,6 +144,7 @@ static struct sa1111_dev_info sa1111_devices[] = {
{ {
.offset = 0x0600, .offset = 0x0600,
.skpcr_mask = SKPCR_I2SCLKEN | SKPCR_L3CLKEN, .skpcr_mask = SKPCR_I2SCLKEN | SKPCR_L3CLKEN,
.dma = true,
.devid = SA1111_DEVID_SAC, .devid = SA1111_DEVID_SAC,
.irq = { .irq = {
AUDXMTDMADONEA, AUDXMTDMADONEA,
...@@ -155,7 +161,7 @@ static struct sa1111_dev_info sa1111_devices[] = { ...@@ -155,7 +161,7 @@ static struct sa1111_dev_info sa1111_devices[] = {
{ {
.offset = SA1111_KBD, .offset = SA1111_KBD,
.skpcr_mask = SKPCR_PTCLKEN, .skpcr_mask = SKPCR_PTCLKEN,
.devid = SA1111_DEVID_PS2, .devid = SA1111_DEVID_PS2_KBD,
.irq = { .irq = {
IRQ_TPRXINT, IRQ_TPRXINT,
IRQ_TPTXINT IRQ_TPTXINT
...@@ -164,7 +170,7 @@ static struct sa1111_dev_info sa1111_devices[] = { ...@@ -164,7 +170,7 @@ static struct sa1111_dev_info sa1111_devices[] = {
{ {
.offset = SA1111_MSE, .offset = SA1111_MSE,
.skpcr_mask = SKPCR_PMCLKEN, .skpcr_mask = SKPCR_PMCLKEN,
.devid = SA1111_DEVID_PS2, .devid = SA1111_DEVID_PS2_MSE,
.irq = { .irq = {
IRQ_MSRXINT, IRQ_MSRXINT,
IRQ_MSTXINT IRQ_MSTXINT
...@@ -434,16 +440,28 @@ static struct irq_chip sa1111_high_chip = { ...@@ -434,16 +440,28 @@ static struct irq_chip sa1111_high_chip = {
.irq_set_wake = sa1111_wake_highirq, .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; 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. * We're guaranteed that this region hasn't been taken.
*/ */
request_mem_region(sachip->phys + SA1111_INTC, 512, "irq"); 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 */ /* disable all IRQs */
sa1111_writel(0, irqbase + SA1111_INTEN0); sa1111_writel(0, irqbase + SA1111_INTEN0);
sa1111_writel(0, irqbase + SA1111_INTEN1); sa1111_writel(0, irqbase + SA1111_INTEN1);
...@@ -463,14 +481,16 @@ static void sa1111_setup_irq(struct sa1111 *sachip) ...@@ -463,14 +481,16 @@ static void sa1111_setup_irq(struct sa1111 *sachip)
sa1111_writel(~0, irqbase + SA1111_INTSTATCLR0); sa1111_writel(~0, irqbase + SA1111_INTSTATCLR0);
sa1111_writel(~0, irqbase + SA1111_INTSTATCLR1); 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, irq_set_chip_and_handler(irq, &sa1111_low_chip,
handle_edge_irq); handle_edge_irq);
irq_set_chip_data(irq, sachip); irq_set_chip_data(irq, sachip);
set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); 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, irq_set_chip_and_handler(irq, &sa1111_high_chip,
handle_edge_irq); handle_edge_irq);
irq_set_chip_data(irq, sachip); irq_set_chip_data(irq, sachip);
...@@ -483,6 +503,11 @@ static void sa1111_setup_irq(struct sa1111 *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_irq_type(sachip->irq, IRQ_TYPE_EDGE_RISING);
irq_set_handler_data(sachip->irq, sachip); irq_set_handler_data(sachip->irq, sachip);
irq_set_chained_handler(sachip->irq, sa1111_irq_handler); 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, ...@@ -581,41 +606,10 @@ sa1111_configure_smc(struct sa1111 *sachip, int sdram, unsigned int drac,
} }
#endif #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) static void sa1111_dev_release(struct device *_dev)
{ {
struct sa1111_dev *dev = SA1111_DEV(_dev); struct sa1111_dev *dev = SA1111_DEV(_dev);
release_resource(&dev->res);
kfree(dev); kfree(dev);
} }
...@@ -624,67 +618,58 @@ sa1111_init_one_child(struct sa1111 *sachip, struct resource *parent, ...@@ -624,67 +618,58 @@ sa1111_init_one_child(struct sa1111 *sachip, struct resource *parent,
struct sa1111_dev_info *info) struct sa1111_dev_info *info)
{ {
struct sa1111_dev *dev; struct sa1111_dev *dev;
unsigned i;
int ret; int ret;
dev = kzalloc(sizeof(struct sa1111_dev), GFP_KERNEL); dev = kzalloc(sizeof(struct sa1111_dev), GFP_KERNEL);
if (!dev) { if (!dev) {
ret = -ENOMEM; ret = -ENOMEM;
goto out; goto err_alloc;
} }
device_initialize(&dev->dev);
dev_set_name(&dev->dev, "%4.4lx", info->offset); dev_set_name(&dev->dev, "%4.4lx", info->offset);
dev->devid = info->devid; dev->devid = info->devid;
dev->dev.parent = sachip->dev; dev->dev.parent = sachip->dev;
dev->dev.bus = &sa1111_bus_type; dev->dev.bus = &sa1111_bus_type;
dev->dev.release = sa1111_dev_release; 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.start = sachip->phys + info->offset;
dev->res.end = dev->res.start + 511; dev->res.end = dev->res.start + 511;
dev->res.name = dev_name(&dev->dev); dev->res.name = dev_name(&dev->dev);
dev->res.flags = IORESOURCE_MEM; dev->res.flags = IORESOURCE_MEM;
dev->mapbase = sachip->base + info->offset; dev->mapbase = sachip->base + info->offset;
dev->skpcr_mask = info->skpcr_mask; 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); for (i = 0; i < ARRAY_SIZE(info->irq); i++)
if (ret) { dev->irq[i] = sachip->irq_base + info->irq[i];
release_resource(&dev->res);
kfree(dev);
goto out;
}
#ifdef CONFIG_DMABOUNCE
/* /*
* If the parent device has a DMA mask associated with it, * If the parent device has a DMA mask associated with it, and
* propagate it down to the children. * 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->dma_mask = *sachip->dev->dma_mask;
dev->dev.dma_mask = &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 = request_resource(parent, &dev->res);
ret = dmabounce_register_dev(&dev->dev, 1024, 4096, if (ret) {
sa1111_needs_bounce); dev_err(sachip->dev, "failed to allocate resource for %s\n",
if (ret) { dev->res.name);
dev_err(&dev->dev, "SA1111: Failed to register" goto err_resource;
" with dmabounce\n");
device_unregister(&dev->dev);
}
}
} }
#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; return ret;
} }
...@@ -698,16 +683,21 @@ sa1111_init_one_child(struct sa1111 *sachip, struct resource *parent, ...@@ -698,16 +683,21 @@ sa1111_init_one_child(struct sa1111 *sachip, struct resource *parent,
* Returns: * Returns:
* %-ENODEV device not found. * %-ENODEV device not found.
* %-EBUSY physical address already marked in-use. * %-EBUSY physical address already marked in-use.
* %-EINVAL no platform data passed
* %0 successful. * %0 successful.
*/ */
static int __devinit static int __devinit
__sa1111_probe(struct device *me, struct resource *mem, int irq) __sa1111_probe(struct device *me, struct resource *mem, int irq)
{ {
struct sa1111_platform_data *pd = me->platform_data;
struct sa1111 *sachip; struct sa1111 *sachip;
unsigned long id; unsigned long id;
unsigned int has_devs; unsigned int has_devs;
int i, ret = -ENODEV; int i, ret = -ENODEV;
if (!pd)
return -EINVAL;
sachip = kzalloc(sizeof(struct sa1111), GFP_KERNEL); sachip = kzalloc(sizeof(struct sa1111), GFP_KERNEL);
if (!sachip) if (!sachip)
return -ENOMEM; return -ENOMEM;
...@@ -727,6 +717,7 @@ __sa1111_probe(struct device *me, struct resource *mem, int irq) ...@@ -727,6 +717,7 @@ __sa1111_probe(struct device *me, struct resource *mem, int irq)
sachip->dev = me; sachip->dev = me;
dev_set_drvdata(sachip->dev, sachip); dev_set_drvdata(sachip->dev, sachip);
sachip->pdata = pd;
sachip->phys = mem->start; sachip->phys = mem->start;
sachip->irq = irq; sachip->irq = irq;
...@@ -759,6 +750,16 @@ __sa1111_probe(struct device *me, struct resource *mem, int irq) ...@@ -759,6 +750,16 @@ __sa1111_probe(struct device *me, struct resource *mem, int irq)
*/ */
sa1111_wake(sachip); 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 #ifdef CONFIG_ARCH_SA1100
{ {
unsigned int val; unsigned int val;
...@@ -789,24 +790,14 @@ __sa1111_probe(struct device *me, struct resource *mem, int irq) ...@@ -789,24 +790,14 @@ __sa1111_probe(struct device *me, struct resource *mem, int irq)
} }
#endif #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; g_sa1111 = sachip;
has_devs = ~0; has_devs = ~0;
if (machine_is_assabet() || machine_is_jornada720() || if (pd)
machine_is_badge4()) has_devs &= ~pd->disable_devs;
has_devs &= ~(1 << 4);
else
has_devs &= ~(1 << 1);
for (i = 0; i < ARRAY_SIZE(sa1111_devices); i++) 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]); sa1111_init_one_child(sachip, mem, &sa1111_devices[i]);
return 0; return 0;
...@@ -824,7 +815,10 @@ __sa1111_probe(struct device *me, struct resource *mem, int irq) ...@@ -824,7 +815,10 @@ __sa1111_probe(struct device *me, struct resource *mem, int irq)
static int sa1111_remove_one(struct device *dev, void *data) 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; return 0;
} }
...@@ -846,6 +840,7 @@ static void __sa1111_remove(struct sa1111 *sachip) ...@@ -846,6 +840,7 @@ static void __sa1111_remove(struct sa1111 *sachip)
if (sachip->irq != NO_IRQ) { if (sachip->irq != NO_IRQ) {
irq_set_chained_handler(sachip->irq, NULL); irq_set_chained_handler(sachip->irq, NULL);
irq_set_handler_data(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); release_mem_region(sachip->phys + SA1111_INTC, 512);
} }
...@@ -904,6 +899,9 @@ static int sa1111_suspend(struct platform_device *dev, pm_message_t state) ...@@ -904,6 +899,9 @@ static int sa1111_suspend(struct platform_device *dev, pm_message_t state)
save->skpwm0 = sa1111_readl(base + SA1111_SKPWM0); save->skpwm0 = sa1111_readl(base + SA1111_SKPWM0);
save->skpwm1 = sa1111_readl(base + SA1111_SKPWM1); 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; base = sachip->base + SA1111_INTC;
save->intpol0 = sa1111_readl(base + SA1111_INTPOL0); save->intpol0 = sa1111_readl(base + SA1111_INTPOL0);
save->intpol1 = sa1111_readl(base + SA1111_INTPOL1); save->intpol1 = sa1111_readl(base + SA1111_INTPOL1);
...@@ -919,13 +917,15 @@ static int sa1111_suspend(struct platform_device *dev, pm_message_t state) ...@@ -919,13 +917,15 @@ static int sa1111_suspend(struct platform_device *dev, pm_message_t state)
*/ */
val = sa1111_readl(sachip->base + SA1111_SKCR); val = sa1111_readl(sachip->base + SA1111_SKCR);
sa1111_writel(val | SKCR_SLEEP, 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); clk_disable(sachip->clk);
spin_unlock_irqrestore(&sachip->lock, flags); spin_unlock_irqrestore(&sachip->lock, flags);
#ifdef CONFIG_ARCH_SA1100
sa1110_mb_disable();
#endif
return 0; return 0;
} }
...@@ -966,6 +966,11 @@ static int sa1111_resume(struct platform_device *dev) ...@@ -966,6 +966,11 @@ static int sa1111_resume(struct platform_device *dev)
*/ */
sa1111_wake(sachip); 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 * Only lock for write ops. Also, sa1111_wake must be called with
* released spinlock! * released spinlock!
...@@ -1053,6 +1058,7 @@ static struct platform_driver sa1111_device_driver = { ...@@ -1053,6 +1058,7 @@ static struct platform_driver sa1111_device_driver = {
.resume = sa1111_resume, .resume = sa1111_resume,
.driver = { .driver = {
.name = "sa1111", .name = "sa1111",
.owner = THIS_MODULE,
}, },
}; };
...@@ -1238,16 +1244,23 @@ EXPORT_SYMBOL(sa1111_set_sleep_io); ...@@ -1238,16 +1244,23 @@ EXPORT_SYMBOL(sa1111_set_sleep_io);
* sa1111_enable_device - enable an on-chip SA1111 function block * sa1111_enable_device - enable an on-chip SA1111 function block
* @sadev: SA1111 function block device to enable * @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); struct sa1111 *sachip = sa1111_chip_driver(sadev);
unsigned long flags; unsigned long flags;
unsigned int val; unsigned int val;
int ret = 0;
spin_lock_irqsave(&sachip->lock, flags); if (sachip->pdata && sachip->pdata->enable)
val = sa1111_readl(sachip->base + SA1111_SKPCR); ret = sachip->pdata->enable(sachip->pdata->data, sadev->devid);
sa1111_writel(val | sadev->skpcr_mask, sachip->base + SA1111_SKPCR);
spin_unlock_irqrestore(&sachip->lock, flags); 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); EXPORT_SYMBOL(sa1111_enable_device);
...@@ -1265,6 +1278,9 @@ void sa1111_disable_device(struct sa1111_dev *sadev) ...@@ -1265,6 +1278,9 @@ void sa1111_disable_device(struct sa1111_dev *sadev)
val = sa1111_readl(sachip->base + SA1111_SKPCR); val = sa1111_readl(sachip->base + SA1111_SKPCR);
sa1111_writel(val & ~sadev->skpcr_mask, sachip->base + SA1111_SKPCR); sa1111_writel(val & ~sadev->skpcr_mask, sachip->base + SA1111_SKPCR);
spin_unlock_irqrestore(&sachip->lock, flags); 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); EXPORT_SYMBOL(sa1111_disable_device);
...@@ -1279,7 +1295,7 @@ static int sa1111_match(struct device *_dev, struct device_driver *_drv) ...@@ -1279,7 +1295,7 @@ static int sa1111_match(struct device *_dev, struct device_driver *_drv)
struct sa1111_dev *dev = SA1111_DEV(_dev); struct sa1111_dev *dev = SA1111_DEV(_dev);
struct sa1111_driver *drv = SA1111_DRV(_drv); 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) static int sa1111_bus_suspend(struct device *dev, pm_message_t state)
...@@ -1304,6 +1320,14 @@ static int sa1111_bus_resume(struct device *dev) ...@@ -1304,6 +1320,14 @@ static int sa1111_bus_resume(struct device *dev)
return ret; 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) static int sa1111_bus_probe(struct device *dev)
{ {
struct sa1111_dev *sadev = SA1111_DEV(dev); struct sa1111_dev *sadev = SA1111_DEV(dev);
...@@ -1333,6 +1357,7 @@ struct bus_type sa1111_bus_type = { ...@@ -1333,6 +1357,7 @@ struct bus_type sa1111_bus_type = {
.remove = sa1111_bus_remove, .remove = sa1111_bus_remove,
.suspend = sa1111_bus_suspend, .suspend = sa1111_bus_suspend,
.resume = sa1111_bus_resume, .resume = sa1111_bus_resume,
.shutdown = sa1111_bus_shutdown,
}; };
EXPORT_SYMBOL(sa1111_bus_type); EXPORT_SYMBOL(sa1111_bus_type);
...@@ -1349,9 +1374,70 @@ void sa1111_driver_unregister(struct sa1111_driver *driver) ...@@ -1349,9 +1374,70 @@ void sa1111_driver_unregister(struct sa1111_driver *driver)
} }
EXPORT_SYMBOL(sa1111_driver_unregister); 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) static int __init sa1111_init(void)
{ {
int ret = bus_register(&sa1111_bus_type); 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) if (ret == 0)
platform_driver_register(&sa1111_device_driver); platform_driver_register(&sa1111_device_driver);
return ret; return ret;
...@@ -1360,6 +1446,9 @@ static int __init sa1111_init(void) ...@@ -1360,6 +1446,9 @@ static int __init sa1111_init(void)
static void __exit sa1111_exit(void) static void __exit sa1111_exit(void)
{ {
platform_driver_unregister(&sa1111_device_driver); platform_driver_unregister(&sa1111_device_driver);
#ifdef CONFIG_DMABOUNCE
bus_unregister_notifier(&sa1111_bus_type, &sa1111_bus_notifier);
#endif
bus_unregister(&sa1111_bus_type); bus_unregister(&sa1111_bus_type);
} }
......
...@@ -132,33 +132,9 @@ ...@@ -132,33 +132,9 @@
#define SKPCR_DCLKEN (1<<7) #define SKPCR_DCLKEN (1<<7)
#define SKPCR_PWMCLKEN (1<<8) #define SKPCR_PWMCLKEN (1<<8)
/* /* USB Host controller */
* USB Host controller
*/
#define SA1111_USB 0x0400 #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 * Serial Audio Controller
* *
...@@ -327,22 +303,6 @@ ...@@ -327,22 +303,6 @@
* PC_SSR GPIO Block C Sleep State * 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 0x1000
#define SA1111_GPIO_PADDR (0x000) #define SA1111_GPIO_PADDR (0x000)
...@@ -425,106 +385,30 @@ ...@@ -425,106 +385,30 @@
#define SA1111_WAKEPOL0 0x0034 #define SA1111_WAKEPOL0 0x0034
#define SA1111_WAKEPOL1 0x0038 #define SA1111_WAKEPOL1 0x0038
/* /* PS/2 Trackpad and Mouse Interfaces */
* 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
*/
#define SA1111_KBD 0x0a00 #define SA1111_KBD 0x0a00
#define SA1111_MSE 0x0c00 #define SA1111_MSE 0x0c00
/* /* PCMCIA Interface */
* These are offsets from the above bases. #define SA1111_PCMCIA 0x1600
*/
#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
*
* 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; extern struct bus_type sa1111_bus_type;
#define SA1111_DEVID_SBI 0 #define SA1111_DEVID_SBI (1 << 0)
#define SA1111_DEVID_SK 1 #define SA1111_DEVID_SK (1 << 1)
#define SA1111_DEVID_USB 2 #define SA1111_DEVID_USB (1 << 2)
#define SA1111_DEVID_SAC 3 #define SA1111_DEVID_SAC (1 << 3)
#define SA1111_DEVID_SSP 4 #define SA1111_DEVID_SSP (1 << 4)
#define SA1111_DEVID_PS2 5 #define SA1111_DEVID_PS2 (3 << 5)
#define SA1111_DEVID_GPIO 6 #define SA1111_DEVID_PS2_KBD (1 << 5)
#define SA1111_DEVID_INT 7 #define SA1111_DEVID_PS2_MSE (1 << 6)
#define SA1111_DEVID_PCMCIA 8 #define SA1111_DEVID_GPIO (1 << 7)
#define SA1111_DEVID_INT (1 << 8)
#define SA1111_DEVID_PCMCIA (1 << 9)
struct sa1111_dev { struct sa1111_dev {
struct device dev; struct device dev;
...@@ -548,6 +432,7 @@ struct sa1111_driver { ...@@ -548,6 +432,7 @@ struct sa1111_driver {
int (*remove)(struct sa1111_dev *); int (*remove)(struct sa1111_dev *);
int (*suspend)(struct sa1111_dev *, pm_message_t); int (*suspend)(struct sa1111_dev *, pm_message_t);
int (*resume)(struct sa1111_dev *); int (*resume)(struct sa1111_dev *);
void (*shutdown)(struct sa1111_dev *);
}; };
#define SA1111_DRV(_d) container_of((_d), struct sa1111_driver, drv) #define SA1111_DRV(_d) container_of((_d), struct sa1111_driver, drv)
...@@ -555,9 +440,10 @@ struct sa1111_driver { ...@@ -555,9 +440,10 @@ struct sa1111_driver {
#define SA1111_DRIVER_NAME(_sadev) ((_sadev)->dev.driver->name) #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 *); void sa1111_disable_device(struct sa1111_dev *);
unsigned int sa1111_pll_clock(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 ...@@ -580,6 +466,10 @@ void sa1111_set_sleep_io(struct sa1111_dev *sadev, unsigned int bits, unsigned i
struct sa1111_platform_data { struct sa1111_platform_data {
int irq_base; /* base for cascaded on-chip IRQs */ 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 */ #endif /* _ASM_ARCH_SA1111 */
...@@ -23,7 +23,6 @@ obj-$(CONFIG_LEDS) += leds.o ...@@ -23,7 +23,6 @@ obj-$(CONFIG_LEDS) += leds.o
obj-$(CONFIG_OC_ETM) += etm.o obj-$(CONFIG_OC_ETM) += etm.o
obj-$(CONFIG_ISA_DMA_API) += dma.o obj-$(CONFIG_ISA_DMA_API) += dma.o
obj-$(CONFIG_ARCH_ACORN) += ecard.o
obj-$(CONFIG_FIQ) += fiq.o fiqasm.o obj-$(CONFIG_FIQ) += fiq.o fiqasm.o
obj-$(CONFIG_MODULES) += armksyms.o module.o obj-$(CONFIG_MODULES) += armksyms.o module.o
obj-$(CONFIG_ARTHUR) += arthur.o obj-$(CONFIG_ARTHUR) += arthur.o
......
...@@ -30,10 +30,7 @@ ...@@ -30,10 +30,7 @@
#include <asm/mach/time.h> #include <asm/mach/time.h>
#define IRQ_MASK 0xfe000000 /* read */ #include "core.h"
#define IRQ_MSET 0xfe000000 /* write */
#define IRQ_STAT 0xff000000 /* read */
#define IRQ_MCLR 0xff000000 /* write */
static void ebsa110_mask_irq(struct irq_data *d) static void ebsa110_mask_irq(struct irq_data *d)
{ {
...@@ -79,22 +76,22 @@ static struct map_desc ebsa110_io_desc[] __initdata = { ...@@ -79,22 +76,22 @@ static struct map_desc ebsa110_io_desc[] __initdata = {
{ /* IRQ_STAT/IRQ_MCLR */ { /* IRQ_STAT/IRQ_MCLR */
.virtual = IRQ_STAT, .virtual = IRQ_STAT,
.pfn = __phys_to_pfn(TRICK4_PHYS), .pfn = __phys_to_pfn(TRICK4_PHYS),
.length = PGDIR_SIZE, .length = TRICK4_SIZE,
.type = MT_DEVICE .type = MT_DEVICE
}, { /* IRQ_MASK/IRQ_MSET */ }, { /* IRQ_MASK/IRQ_MSET */
.virtual = IRQ_MASK, .virtual = IRQ_MASK,
.pfn = __phys_to_pfn(TRICK3_PHYS), .pfn = __phys_to_pfn(TRICK3_PHYS),
.length = PGDIR_SIZE, .length = TRICK3_SIZE,
.type = MT_DEVICE .type = MT_DEVICE
}, { /* SOFT_BASE */ }, { /* SOFT_BASE */
.virtual = SOFT_BASE, .virtual = SOFT_BASE,
.pfn = __phys_to_pfn(TRICK1_PHYS), .pfn = __phys_to_pfn(TRICK1_PHYS),
.length = PGDIR_SIZE, .length = TRICK1_SIZE,
.type = MT_DEVICE .type = MT_DEVICE
}, { /* PIT_BASE */ }, { /* PIT_BASE */
.virtual = PIT_BASE, .virtual = PIT_BASE,
.pfn = __phys_to_pfn(TRICK0_PHYS), .pfn = __phys_to_pfn(TRICK0_PHYS),
.length = PGDIR_SIZE, .length = TRICK0_SIZE,
.type = MT_DEVICE .type = MT_DEVICE
}, },
......
/*
* Copyright (C) 1996-2000 Russell King.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This file contains the core hardware definitions of the EBSA-110.
*/
#ifndef CORE_H
#define CORE_H
/* Physical addresses/sizes */
#define ISAMEM_PHYS 0xe0000000
#define ISAMEM_SIZE 0x10000000
#define ISAIO_PHYS 0xf0000000
#define ISAIO_SIZE PGDIR_SIZE
#define TRICK0_PHYS 0xf2000000
#define TRICK0_SIZE PGDIR_SIZE
#define TRICK1_PHYS 0xf2400000
#define TRICK1_SIZE PGDIR_SIZE
#define TRICK2_PHYS 0xf2800000
#define TRICK3_PHYS 0xf2c00000
#define TRICK3_SIZE PGDIR_SIZE
#define TRICK4_PHYS 0xf3000000
#define TRICK4_SIZE PGDIR_SIZE
#define TRICK5_PHYS 0xf3400000
#define TRICK6_PHYS 0xf3800000
#define TRICK7_PHYS 0xf3c00000
/* Virtual addresses */
#define PIT_BASE 0xfc000000 /* trick 0 */
#define SOFT_BASE 0xfd000000 /* trick 1 */
#define IRQ_MASK 0xfe000000 /* trick 3 - read */
#define IRQ_MSET 0xfe000000 /* trick 3 - write */
#define IRQ_STAT 0xff000000 /* trick 4 - read */
#define IRQ_MCLR 0xff000000 /* trick 4 - write */
#endif
...@@ -12,48 +12,9 @@ ...@@ -12,48 +12,9 @@
#ifndef __ASM_ARCH_HARDWARE_H #ifndef __ASM_ARCH_HARDWARE_H
#define __ASM_ARCH_HARDWARE_H #define __ASM_ARCH_HARDWARE_H
/*
* The EBSA110 has a weird "ISA IO" region:
*
* Region 0 (addr = 0xf0000000 + io << 2)
* --------------------------------------------------------
* Physical region IO region
* f0000fe0 - f0000ffc 3f8 - 3ff ttyS0
* f0000e60 - f0000e64 398 - 399
* f0000de0 - f0000dfc 378 - 37f lp0
* f0000be0 - f0000bfc 2f8 - 2ff ttyS1
*
* Region 1 (addr = 0xf0000000 + (io & ~1) << 1 + (io & 1))
* --------------------------------------------------------
* Physical region IO region
* f00014f1 a79 pnp write data
* f00007c0 - f00007c1 3e0 - 3e1 pcmcia
* f00004f1 279 pnp address
* f0000440 - f000046c 220 - 236 eth0
* f0000405 203 pnp read data
*/
#define ISAMEM_PHYS 0xe0000000
#define ISAMEM_SIZE 0x10000000
#define ISAIO_PHYS 0xf0000000
#define ISAIO_SIZE PGDIR_SIZE
#define TRICK0_PHYS 0xf2000000
#define TRICK1_PHYS 0xf2400000
#define TRICK2_PHYS 0xf2800000
#define TRICK3_PHYS 0xf2c00000
#define TRICK4_PHYS 0xf3000000
#define TRICK5_PHYS 0xf3400000
#define TRICK6_PHYS 0xf3800000
#define TRICK7_PHYS 0xf3c00000
#define ISAMEM_BASE 0xe0000000 #define ISAMEM_BASE 0xe0000000
#define ISAIO_BASE 0xf0000000 #define ISAIO_BASE 0xf0000000
#define PIT_BASE 0xfc000000
#define SOFT_BASE 0xfd000000
/* /*
* RAM definitions * RAM definitions
*/ */
......
...@@ -177,6 +177,26 @@ void writesl(void __iomem *addr, const void *data, int len) ...@@ -177,6 +177,26 @@ void writesl(void __iomem *addr, const void *data, int len)
} }
EXPORT_SYMBOL(writesl); EXPORT_SYMBOL(writesl);
/*
* The EBSA110 has a weird "ISA IO" region:
*
* Region 0 (addr = 0xf0000000 + io << 2)
* --------------------------------------------------------
* Physical region IO region
* f0000fe0 - f0000ffc 3f8 - 3ff ttyS0
* f0000e60 - f0000e64 398 - 399
* f0000de0 - f0000dfc 378 - 37f lp0
* f0000be0 - f0000bfc 2f8 - 2ff ttyS1
*
* Region 1 (addr = 0xf0000000 + (io & ~1) << 1 + (io & 1))
* --------------------------------------------------------
* Physical region IO region
* f00014f1 a79 pnp write data
* f00007c0 - f00007c1 3e0 - 3e1 pcmcia
* f00004f1 279 pnp address
* f0000440 - f000046c 220 - 236 eth0
* f0000405 203 pnp read data
*/
#define SUPERIO_PORT(p) \ #define SUPERIO_PORT(p) \
(((p) >> 3) == (0x3f8 >> 3) || \ (((p) >> 3) == (0x3f8 >> 3) || \
((p) >> 3) == (0x2f8 >> 3) || \ ((p) >> 3) == (0x2f8 >> 3) || \
......
...@@ -20,6 +20,8 @@ ...@@ -20,6 +20,8 @@
#include <asm/system.h> #include <asm/system.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
#include "core.h"
static spinlock_t leds_lock; static spinlock_t leds_lock;
static void ebsa110_leds_event(led_event_t ledevt) static void ebsa110_leds_event(led_event_t ledevt)
......
...@@ -223,6 +223,7 @@ static struct resource sa1111_resources[] = { ...@@ -223,6 +223,7 @@ static struct resource sa1111_resources[] = {
static struct sa1111_platform_data sa1111_info = { static struct sa1111_platform_data sa1111_info = {
.irq_base = LUBBOCK_SA1111_IRQ_BASE, .irq_base = LUBBOCK_SA1111_IRQ_BASE,
.disable_devs = SA1111_DEVID_SAC,
}; };
static struct platform_device sa1111_device = { static struct platform_device sa1111_device = {
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
# Object file lists. # Object file lists.
obj-y := dma.o fiq.o irq.o riscpc.o obj-y := dma.o ecard.o fiq.o irq.o riscpc.o time.o
obj-m := obj-m :=
obj-n := obj-n :=
obj- := obj- :=
......
...@@ -42,6 +42,7 @@ ...@@ -42,6 +42,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/kthread.h> #include <linux/kthread.h>
#include <linux/irq.h>
#include <linux/io.h> #include <linux/io.h>
#include <asm/dma.h> #include <asm/dma.h>
...@@ -54,10 +55,6 @@ ...@@ -54,10 +55,6 @@
#include "ecard.h" #include "ecard.h"
#ifndef CONFIG_ARCH_RPC
#define HAVE_EXPMASK
#endif
struct ecard_request { struct ecard_request {
void (*fn)(struct ecard_request *); void (*fn)(struct ecard_request *);
ecard_t *ec; ecard_t *ec;
...@@ -77,9 +74,6 @@ struct expcard_blacklist { ...@@ -77,9 +74,6 @@ struct expcard_blacklist {
static ecard_t *cards; static ecard_t *cards;
static ecard_t *slot_to_expcard[MAX_ECARDS]; static ecard_t *slot_to_expcard[MAX_ECARDS];
static unsigned int ectcr; static unsigned int ectcr;
#ifdef HAS_EXPMASK
static unsigned int have_expmask;
#endif
/* List of descriptions of cards which don't have an extended /* List of descriptions of cards which don't have an extended
* identification, or chunk directories containing a description. * identification, or chunk directories containing a description.
...@@ -391,22 +385,10 @@ int ecard_readchunk(struct in_chunk_dir *cd, ecard_t *ec, int id, int num) ...@@ -391,22 +385,10 @@ int ecard_readchunk(struct in_chunk_dir *cd, ecard_t *ec, int id, int num)
static void ecard_def_irq_enable(ecard_t *ec, int irqnr) static void ecard_def_irq_enable(ecard_t *ec, int irqnr)
{ {
#ifdef HAS_EXPMASK
if (irqnr < 4 && have_expmask) {
have_expmask |= 1 << irqnr;
__raw_writeb(have_expmask, EXPMASK_ENABLE);
}
#endif
} }
static void ecard_def_irq_disable(ecard_t *ec, int irqnr) static void ecard_def_irq_disable(ecard_t *ec, int irqnr)
{ {
#ifdef HAS_EXPMASK
if (irqnr < 4 && have_expmask) {
have_expmask &= ~(1 << irqnr);
__raw_writeb(have_expmask, EXPMASK_ENABLE);
}
#endif
} }
static int ecard_def_irq_pending(ecard_t *ec) static int ecard_def_irq_pending(ecard_t *ec)
...@@ -446,7 +428,7 @@ static expansioncard_ops_t ecard_default_ops = { ...@@ -446,7 +428,7 @@ static expansioncard_ops_t ecard_default_ops = {
*/ */
static void ecard_irq_unmask(struct irq_data *d) static void ecard_irq_unmask(struct irq_data *d)
{ {
ecard_t *ec = slot_to_ecard(d->irq - 32); ecard_t *ec = irq_data_get_irq_chip_data(d);
if (ec) { if (ec) {
if (!ec->ops) if (!ec->ops)
...@@ -462,7 +444,7 @@ static void ecard_irq_unmask(struct irq_data *d) ...@@ -462,7 +444,7 @@ static void ecard_irq_unmask(struct irq_data *d)
static void ecard_irq_mask(struct irq_data *d) static void ecard_irq_mask(struct irq_data *d)
{ {
ecard_t *ec = slot_to_ecard(d->irq - 32); ecard_t *ec = irq_data_get_irq_chip_data(d);
if (ec) { if (ec) {
if (!ec->ops) if (!ec->ops)
...@@ -579,7 +561,7 @@ ecard_irq_handler(unsigned int irq, struct irq_desc *desc) ...@@ -579,7 +561,7 @@ ecard_irq_handler(unsigned int irq, struct irq_desc *desc)
for (ec = cards; ec; ec = ec->next) { for (ec = cards; ec; ec = ec->next) {
int pending; int pending;
if (!ec->claimed || ec->irq == NO_IRQ || ec->slot_no == 8) if (!ec->claimed || !ec->irq || ec->slot_no == 8)
continue; continue;
if (ec->ops && ec->ops->irqpending) if (ec->ops && ec->ops->irqpending)
...@@ -598,83 +580,6 @@ ecard_irq_handler(unsigned int irq, struct irq_desc *desc) ...@@ -598,83 +580,6 @@ ecard_irq_handler(unsigned int irq, struct irq_desc *desc)
ecard_check_lockup(desc); ecard_check_lockup(desc);
} }
#ifdef HAS_EXPMASK
static unsigned char priority_masks[] =
{
0xf0, 0xf1, 0xf3, 0xf7, 0xff, 0xff, 0xff, 0xff
};
static unsigned char first_set[] =
{
0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00,
0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00
};
static void
ecard_irqexp_handler(unsigned int irq, struct irq_desc *desc)
{
const unsigned int statusmask = 15;
unsigned int status;
status = __raw_readb(EXPMASK_STATUS) & statusmask;
if (status) {
unsigned int slot = first_set[status];
ecard_t *ec = slot_to_ecard(slot);
if (ec->claimed) {
/*
* this ugly code is so that we can operate a
* prioritorising system:
*
* Card 0 highest priority
* Card 1
* Card 2
* Card 3 lowest priority
*
* Serial cards should go in 0/1, ethernet/scsi in 2/3
* otherwise you will lose serial data at high speeds!
*/
generic_handle_irq(ec->irq);
} else {
printk(KERN_WARNING "card%d: interrupt from unclaimed "
"card???\n", slot);
have_expmask &= ~(1 << slot);
__raw_writeb(have_expmask, EXPMASK_ENABLE);
}
} else
printk(KERN_WARNING "Wild interrupt from backplane (masks)\n");
}
static int __init ecard_probeirqhw(void)
{
ecard_t *ec;
int found;
__raw_writeb(0x00, EXPMASK_ENABLE);
__raw_writeb(0xff, EXPMASK_STATUS);
found = (__raw_readb(EXPMASK_STATUS) & 15) == 0;
__raw_writeb(0xff, EXPMASK_ENABLE);
if (found) {
printk(KERN_DEBUG "Expansion card interrupt "
"management hardware found\n");
/* for each card present, set a bit to '1' */
have_expmask = 0x80000000;
for (ec = cards; ec; ec = ec->next)
have_expmask |= 1 << ec->slot_no;
__raw_writeb(have_expmask, EXPMASK_ENABLE);
}
return found;
}
#else
#define ecard_irqexp_handler NULL
#define ecard_probeirqhw() (0)
#endif
static void __iomem *__ecard_address(ecard_t *ec, card_type_t type, card_speed_t speed) static void __iomem *__ecard_address(ecard_t *ec, card_type_t type, card_speed_t speed)
{ {
void __iomem *address = NULL; void __iomem *address = NULL;
...@@ -806,8 +711,8 @@ static struct expansion_card *__init ecard_alloc_card(int type, int slot) ...@@ -806,8 +711,8 @@ static struct expansion_card *__init ecard_alloc_card(int type, int slot)
ec->slot_no = slot; ec->slot_no = slot;
ec->easi = type == ECARD_EASI; ec->easi = type == ECARD_EASI;
ec->irq = NO_IRQ; ec->irq = 0;
ec->fiq = NO_IRQ; ec->fiq = 0;
ec->dma = NO_DMA; ec->dma = NO_DMA;
ec->ops = &ecard_default_ops; ec->ops = &ecard_default_ops;
...@@ -978,8 +883,7 @@ EXPORT_SYMBOL(ecardm_iomap); ...@@ -978,8 +883,7 @@ EXPORT_SYMBOL(ecardm_iomap);
* If bit 1 of the first byte of the card is set, then the * If bit 1 of the first byte of the card is set, then the
* card does not exist. * card does not exist.
*/ */
static int __init static int __init ecard_probe(int slot, unsigned irq, card_type_t type)
ecard_probe(int slot, card_type_t type)
{ {
ecard_t **ecp; ecard_t **ecp;
ecard_t *ec; ecard_t *ec;
...@@ -1033,18 +937,18 @@ ecard_probe(int slot, card_type_t type) ...@@ -1033,18 +937,18 @@ ecard_probe(int slot, card_type_t type)
break; break;
} }
ec->irq = irq;
/* /*
* hook the interrupt handlers * hook the interrupt handlers
*/ */
if (slot < 8) { if (slot < 8) {
ec->irq = 32 + slot;
irq_set_chip_and_handler(ec->irq, &ecard_chip, irq_set_chip_and_handler(ec->irq, &ecard_chip,
handle_level_irq); handle_level_irq);
irq_set_chip_data(ec->irq, ec);
set_irq_flags(ec->irq, IRQF_VALID); set_irq_flags(ec->irq, IRQF_VALID);
} }
if (slot == 8)
ec->irq = 11;
#ifdef CONFIG_ARCH_RPC #ifdef CONFIG_ARCH_RPC
/* On RiscPC, only first two slots have DMA capability */ /* On RiscPC, only first two slots have DMA capability */
if (slot < 2) if (slot < 2)
...@@ -1074,28 +978,30 @@ ecard_probe(int slot, card_type_t type) ...@@ -1074,28 +978,30 @@ ecard_probe(int slot, card_type_t type)
static int __init ecard_init(void) static int __init ecard_init(void)
{ {
struct task_struct *task; struct task_struct *task;
int slot, irqhw; int slot, irqbase;
irqbase = irq_alloc_descs(-1, 0, 8, -1);
if (irqbase < 0)
return irqbase;
task = kthread_run(ecard_task, NULL, "kecardd"); task = kthread_run(ecard_task, NULL, "kecardd");
if (IS_ERR(task)) { if (IS_ERR(task)) {
printk(KERN_ERR "Ecard: unable to create kernel thread: %ld\n", printk(KERN_ERR "Ecard: unable to create kernel thread: %ld\n",
PTR_ERR(task)); PTR_ERR(task));
irq_free_descs(irqbase, 8);
return PTR_ERR(task); return PTR_ERR(task);
} }
printk("Probing expansion cards\n"); printk("Probing expansion cards\n");
for (slot = 0; slot < 8; slot ++) { for (slot = 0; slot < 8; slot ++) {
if (ecard_probe(slot, ECARD_EASI) == -ENODEV) if (ecard_probe(slot, irqbase + slot, ECARD_EASI) == -ENODEV)
ecard_probe(slot, ECARD_IOC); ecard_probe(slot, irqbase + slot, ECARD_IOC);
} }
ecard_probe(8, ECARD_IOC); ecard_probe(8, 11, ECARD_IOC);
irqhw = ecard_probeirqhw();
irq_set_chained_handler(IRQ_EXPANSIONCARD, irq_set_chained_handler(IRQ_EXPANSIONCARD, ecard_irq_handler);
irqhw ? ecard_irqexp_handler : ecard_irq_handler);
ecard_proc_init(); ecard_proc_init();
......
...@@ -42,6 +42,4 @@ ...@@ -42,6 +42,4 @@
*/ */
#define FIQ_START 64 #define FIQ_START 64
#define IRQ_TIMER IRQ_TIMER0
#define NR_IRQS 128 #define NR_IRQS 128
...@@ -98,15 +98,9 @@ static void __init rpc_map_io(void) ...@@ -98,15 +98,9 @@ static void __init rpc_map_io(void)
} }
static struct resource acornfb_resources[] = { static struct resource acornfb_resources[] = {
{ /* VIDC */ /* VIDC */
.start = 0x03400000, DEFINE_RES_MEM(0x03400000, 0x00200000),
.end = 0x035fffff, DEFINE_RES_IRQ(IRQ_VSYNCPULSE),
.flags = IORESOURCE_MEM,
}, {
.start = IRQ_VSYNCPULSE,
.end = IRQ_VSYNCPULSE,
.flags = IORESOURCE_IRQ,
},
}; };
static struct platform_device acornfb_device = { static struct platform_device acornfb_device = {
...@@ -120,11 +114,7 @@ static struct platform_device acornfb_device = { ...@@ -120,11 +114,7 @@ static struct platform_device acornfb_device = {
}; };
static struct resource iomd_resources[] = { static struct resource iomd_resources[] = {
{ DEFINE_RES_MEM(0x03200000, 0x10000),
.start = 0x03200000,
.end = 0x0320ffff,
.flags = IORESOURCE_MEM,
},
}; };
static struct platform_device iomd_device = { static struct platform_device iomd_device = {
...@@ -134,18 +124,25 @@ static struct platform_device iomd_device = { ...@@ -134,18 +124,25 @@ static struct platform_device iomd_device = {
.resource = iomd_resources, .resource = iomd_resources,
}; };
static struct resource iomd_kart_resources[] = {
DEFINE_RES_IRQ(IRQ_KEYBOARDRX),
DEFINE_RES_IRQ(IRQ_KEYBOARDTX),
};
static struct platform_device kbd_device = { static struct platform_device kbd_device = {
.name = "kart", .name = "kart",
.id = -1, .id = -1,
.dev = { .dev = {
.parent = &iomd_device.dev, .parent = &iomd_device.dev,
}, },
.num_resources = ARRAY_SIZE(iomd_kart_resources),
.resource = iomd_kart_resources,
}; };
static struct plat_serial8250_port serial_platform_data[] = { static struct plat_serial8250_port serial_platform_data[] = {
{ {
.mapbase = 0x03010fe0, .mapbase = 0x03010fe0,
.irq = 10, .irq = IRQ_SERIALPORT,
.uartclk = 1843200, .uartclk = 1843200,
.regshift = 2, .regshift = 2,
.iotype = UPIO_MEM, .iotype = UPIO_MEM,
...@@ -167,21 +164,9 @@ static struct pata_platform_info pata_platform_data = { ...@@ -167,21 +164,9 @@ static struct pata_platform_info pata_platform_data = {
}; };
static struct resource pata_resources[] = { static struct resource pata_resources[] = {
[0] = { DEFINE_RES_MEM(0x030107c0, 0x20),
.start = 0x030107c0, DEFINE_RES_MEM(0x03010fd8, 0x04),
.end = 0x030107df, DEFINE_RES_IRQ(IRQ_HARDDISK),
.flags = IORESOURCE_MEM,
},
[1] = {
.start = 0x03010fd8,
.end = 0x03010fdb,
.flags = IORESOURCE_MEM,
},
[2] = {
.start = IRQ_HARDDISK,
.end = IRQ_HARDDISK,
.flags = IORESOURCE_IRQ,
},
}; };
static struct platform_device pata_device = { static struct platform_device pata_device = {
......
...@@ -85,7 +85,7 @@ static struct irqaction ioc_timer_irq = { ...@@ -85,7 +85,7 @@ static struct irqaction ioc_timer_irq = {
static void __init ioc_timer_init(void) static void __init ioc_timer_init(void)
{ {
ioctime_init(); ioctime_init();
setup_irq(IRQ_TIMER, &ioc_timer_irq); setup_irq(IRQ_TIMER0, &ioc_timer_irq);
} }
struct sys_timer ioc_timer = { struct sys_timer ioc_timer = {
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
# #
# Common support # Common support
obj-y := clock.o generic.o irq.o dma.o time.o #nmi-oopser.o obj-y := clock.o generic.o irq.o time.o #nmi-oopser.o
obj-m := obj-m :=
obj-n := obj-n :=
obj- := obj- :=
......
...@@ -15,14 +15,16 @@ ...@@ -15,14 +15,16 @@
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/ioport.h> #include <linux/ioport.h>
#include <linux/serial_core.h> #include <linux/serial_core.h>
#include <linux/mfd/ucb1x00.h>
#include <linux/mtd/mtd.h> #include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h> #include <linux/mtd/partitions.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <video/sa1100fb.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
#include <asm/irq.h>
#include <asm/setup.h> #include <asm/setup.h>
#include <asm/page.h> #include <asm/page.h>
#include <asm/pgtable-hwdef.h> #include <asm/pgtable-hwdef.h>
...@@ -36,17 +38,18 @@ ...@@ -36,17 +38,18 @@
#include <asm/mach/serial_sa1100.h> #include <asm/mach/serial_sa1100.h>
#include <mach/assabet.h> #include <mach/assabet.h>
#include <mach/mcp.h> #include <mach/mcp.h>
#include <mach/irqs.h>
#include "generic.h" #include "generic.h"
#define ASSABET_BCR_DB1110 \ #define ASSABET_BCR_DB1110 \
(ASSABET_BCR_SPK_OFF | ASSABET_BCR_QMUTE | \ (ASSABET_BCR_SPK_OFF | \
ASSABET_BCR_LED_GREEN | ASSABET_BCR_LED_RED | \ ASSABET_BCR_LED_GREEN | ASSABET_BCR_LED_RED | \
ASSABET_BCR_RS232EN | ASSABET_BCR_LCD_12RGB | \ ASSABET_BCR_RS232EN | ASSABET_BCR_LCD_12RGB | \
ASSABET_BCR_IRDA_MD0) ASSABET_BCR_IRDA_MD0)
#define ASSABET_BCR_DB1111 \ #define ASSABET_BCR_DB1111 \
(ASSABET_BCR_SPK_OFF | ASSABET_BCR_QMUTE | \ (ASSABET_BCR_SPK_OFF | \
ASSABET_BCR_LED_GREEN | ASSABET_BCR_LED_RED | \ ASSABET_BCR_LED_GREEN | ASSABET_BCR_LED_RED | \
ASSABET_BCR_RS232EN | ASSABET_BCR_LCD_12RGB | \ ASSABET_BCR_RS232EN | ASSABET_BCR_LCD_12RGB | \
ASSABET_BCR_CF_BUS_OFF | ASSABET_BCR_STEREO_LB | \ ASSABET_BCR_CF_BUS_OFF | ASSABET_BCR_STEREO_LB | \
...@@ -69,31 +72,10 @@ void ASSABET_BCR_frob(unsigned int mask, unsigned int val) ...@@ -69,31 +72,10 @@ void ASSABET_BCR_frob(unsigned int mask, unsigned int val)
EXPORT_SYMBOL(ASSABET_BCR_frob); EXPORT_SYMBOL(ASSABET_BCR_frob);
static void assabet_backlight_power(int on) static void assabet_ucb1x00_reset(enum ucb1x00_reset state)
{
#ifndef ASSABET_PAL_VIDEO
if (on)
ASSABET_BCR_set(ASSABET_BCR_LIGHT_ON);
else
#endif
ASSABET_BCR_clear(ASSABET_BCR_LIGHT_ON);
}
/*
* Turn on/off the backlight. When turning the backlight on,
* we wait 500us after turning it on so we don't cause the
* supplies to droop when we enable the LCD controller (and
* cause a hard reset.)
*/
static void assabet_lcd_power(int on)
{ {
#ifndef ASSABET_PAL_VIDEO if (state == UCB_RST_PROBE)
if (on) { ASSABET_BCR_set(ASSABET_BCR_CODEC_RST);
ASSABET_BCR_set(ASSABET_BCR_LCD_ON);
udelay(500);
} else
#endif
ASSABET_BCR_clear(ASSABET_BCR_LCD_ON);
} }
...@@ -152,15 +134,8 @@ static struct flash_platform_data assabet_flash_data = { ...@@ -152,15 +134,8 @@ static struct flash_platform_data assabet_flash_data = {
}; };
static struct resource assabet_flash_resources[] = { static struct resource assabet_flash_resources[] = {
{ DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_32M),
.start = SA1100_CS0_PHYS, DEFINE_RES_MEM(SA1100_CS1_PHYS, SZ_32M),
.end = SA1100_CS0_PHYS + SZ_32M - 1,
.flags = IORESOURCE_MEM,
}, {
.start = SA1100_CS1_PHYS,
.end = SA1100_CS1_PHYS + SZ_32M - 1,
.flags = IORESOURCE_MEM,
}
}; };
...@@ -199,18 +174,126 @@ static struct irda_platform_data assabet_irda_data = { ...@@ -199,18 +174,126 @@ static struct irda_platform_data assabet_irda_data = {
.set_speed = assabet_irda_set_speed, .set_speed = assabet_irda_set_speed,
}; };
static struct ucb1x00_plat_data assabet_ucb1x00_data = {
.reset = assabet_ucb1x00_reset,
.gpio_base = -1,
};
static struct mcp_plat_data assabet_mcp_data = { static struct mcp_plat_data assabet_mcp_data = {
.mccr0 = MCCR0_ADM, .mccr0 = MCCR0_ADM,
.sclk_rate = 11981000, .sclk_rate = 11981000,
.codec_pdata = &assabet_ucb1x00_data,
};
static void assabet_lcd_set_visual(u32 visual)
{
u_int is_true_color = visual == FB_VISUAL_TRUECOLOR;
if (machine_is_assabet()) {
#if 1 // phase 4 or newer Assabet's
if (is_true_color)
ASSABET_BCR_set(ASSABET_BCR_LCD_12RGB);
else
ASSABET_BCR_clear(ASSABET_BCR_LCD_12RGB);
#else
// older Assabet's
if (is_true_color)
ASSABET_BCR_clear(ASSABET_BCR_LCD_12RGB);
else
ASSABET_BCR_set(ASSABET_BCR_LCD_12RGB);
#endif
}
}
#ifndef ASSABET_PAL_VIDEO
static void assabet_lcd_backlight_power(int on)
{
if (on)
ASSABET_BCR_set(ASSABET_BCR_LIGHT_ON);
else
ASSABET_BCR_clear(ASSABET_BCR_LIGHT_ON);
}
/*
* Turn on/off the backlight. When turning the backlight on, we wait
* 500us after turning it on so we don't cause the supplies to droop
* when we enable the LCD controller (and cause a hard reset.)
*/
static void assabet_lcd_power(int on)
{
if (on) {
ASSABET_BCR_set(ASSABET_BCR_LCD_ON);
udelay(500);
} else
ASSABET_BCR_clear(ASSABET_BCR_LCD_ON);
}
/*
* The assabet uses a sharp LQ039Q2DS54 LCD module. It is actually
* takes an RGB666 signal, but we provide it with an RGB565 signal
* instead (def_rgb_16).
*/
static struct sa1100fb_mach_info lq039q2ds54_info = {
.pixclock = 171521, .bpp = 16,
.xres = 320, .yres = 240,
.hsync_len = 5, .vsync_len = 1,
.left_margin = 61, .upper_margin = 3,
.right_margin = 9, .lower_margin = 0,
.sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
.lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
.lccr3 = LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(2),
.backlight_power = assabet_lcd_backlight_power,
.lcd_power = assabet_lcd_power,
.set_visual = assabet_lcd_set_visual,
};
#else
static void assabet_pal_backlight_power(int on)
{
ASSABET_BCR_clear(ASSABET_BCR_LIGHT_ON);
}
static void assabet_pal_power(int on)
{
ASSABET_BCR_clear(ASSABET_BCR_LCD_ON);
}
static struct sa1100fb_mach_info pal_info = {
.pixclock = 67797, .bpp = 16,
.xres = 640, .yres = 512,
.hsync_len = 64, .vsync_len = 6,
.left_margin = 125, .upper_margin = 70,
.right_margin = 115, .lower_margin = 36,
.lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
.lccr3 = LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(512),
.backlight_power = assabet_pal_backlight_power,
.lcd_power = assabet_pal_power,
.set_visual = assabet_lcd_set_visual,
}; };
#endif
#ifdef CONFIG_ASSABET_NEPONSET
static struct resource neponset_resources[] = {
DEFINE_RES_MEM(0x10000000, 0x08000000),
DEFINE_RES_MEM(0x18000000, 0x04000000),
DEFINE_RES_MEM(0x40000000, SZ_8K),
DEFINE_RES_IRQ(IRQ_GPIO25),
};
#endif
static void __init assabet_init(void) static void __init assabet_init(void)
{ {
/* /*
* Ensure that the power supply is in "high power" mode. * Ensure that the power supply is in "high power" mode.
*/ */
GPDR |= GPIO_GPIO16;
GPSR = GPIO_GPIO16; GPSR = GPIO_GPIO16;
GPDR |= GPIO_GPIO16;
/* /*
* Ensure that these pins are set as outputs and are driving * Ensure that these pins are set as outputs and are driving
...@@ -218,8 +301,16 @@ static void __init assabet_init(void) ...@@ -218,8 +301,16 @@ static void __init assabet_init(void)
* the WS latch in the CPLD, and we don't float causing * the WS latch in the CPLD, and we don't float causing
* excessive power drain. --rmk * excessive power drain. --rmk
*/ */
GPDR |= GPIO_SSP_TXD | GPIO_SSP_SCLK | GPIO_SSP_SFRM;
GPCR = GPIO_SSP_TXD | GPIO_SSP_SCLK | GPIO_SSP_SFRM; GPCR = GPIO_SSP_TXD | GPIO_SSP_SCLK | GPIO_SSP_SFRM;
GPDR |= GPIO_SSP_TXD | GPIO_SSP_SCLK | GPIO_SSP_SFRM;
/*
* Also set GPIO27 as an output; this is used to clock UART3
* via the FPGA and as otherwise has no pullups or pulldowns,
* so stop it floating.
*/
GPCR = GPIO_GPIO27;
GPDR |= GPIO_GPIO27;
/* /*
* Set up registers for sleep mode. * Set up registers for sleep mode.
...@@ -231,8 +322,7 @@ static void __init assabet_init(void) ...@@ -231,8 +322,7 @@ static void __init assabet_init(void)
PPDR |= PPC_TXD3 | PPC_TXD1; PPDR |= PPC_TXD3 | PPC_TXD1;
PPSR |= PPC_TXD3 | PPC_TXD1; PPSR |= PPC_TXD3 | PPC_TXD1;
sa1100fb_lcd_power = assabet_lcd_power; sa11x0_ppc_configure_mcp();
sa1100fb_backlight_power = assabet_backlight_power;
if (machine_has_neponset()) { if (machine_has_neponset()) {
/* /*
...@@ -246,9 +336,17 @@ static void __init assabet_init(void) ...@@ -246,9 +336,17 @@ static void __init assabet_init(void)
#ifndef CONFIG_ASSABET_NEPONSET #ifndef CONFIG_ASSABET_NEPONSET
printk( "Warning: Neponset detected but full support " printk( "Warning: Neponset detected but full support "
"hasn't been configured in the kernel\n" ); "hasn't been configured in the kernel\n" );
#else
platform_device_register_simple("neponset", 0,
neponset_resources, ARRAY_SIZE(neponset_resources));
#endif #endif
} }
#ifndef ASSABET_PAL_VIDEO
sa11x0_register_lcd(&lq039q2ds54_info);
#else
sa11x0_register_lcd(&pal_video);
#endif
sa11x0_register_mtd(&assabet_flash_data, assabet_flash_resources, sa11x0_register_mtd(&assabet_flash_data, assabet_flash_resources,
ARRAY_SIZE(assabet_flash_resources)); ARRAY_SIZE(assabet_flash_resources));
sa11x0_register_irda(&assabet_irda_data); sa11x0_register_irda(&assabet_irda_data);
...@@ -412,21 +510,8 @@ static void __init assabet_map_io(void) ...@@ -412,21 +510,8 @@ static void __init assabet_map_io(void)
*/ */
Ser1SDCR0 |= SDCR0_SUS; Ser1SDCR0 |= SDCR0_SUS;
if (machine_has_neponset()) { 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 {
sa1100_register_uart_fns(&assabet_port_fns); sa1100_register_uart_fns(&assabet_port_fns);
}
/* /*
* When Neponset is attached, the first UART should be * When Neponset is attached, the first UART should be
...@@ -449,6 +534,7 @@ MACHINE_START(ASSABET, "Intel-Assabet") ...@@ -449,6 +534,7 @@ MACHINE_START(ASSABET, "Intel-Assabet")
.atag_offset = 0x100, .atag_offset = 0x100,
.fixup = fixup_assabet, .fixup = fixup_assabet,
.map_io = assabet_map_io, .map_io = assabet_map_io,
.nr_irqs = SA1100_NR_IRQS,
.init_irq = sa1100_init_irq, .init_irq = sa1100_init_irq,
.timer = &sa1100_timer, .timer = &sa1100_timer,
.init_machine = assabet_init, .init_machine = assabet_init,
......
...@@ -39,20 +39,27 @@ ...@@ -39,20 +39,27 @@
#include "generic.h" #include "generic.h"
static struct resource sa1111_resources[] = { static struct resource sa1111_resources[] = {
[0] = { [0] = DEFINE_RES_MEM(BADGE4_SA1111_BASE, 0x2000),
.start = BADGE4_SA1111_BASE, [1] = DEFINE_RES_IRQ(BADGE4_IRQ_GPIO_SA1111),
.end = BADGE4_SA1111_BASE + 0x00001fff,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = BADGE4_IRQ_GPIO_SA1111,
.end = BADGE4_IRQ_GPIO_SA1111,
.flags = IORESOURCE_IRQ,
},
}; };
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 = { 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; static u64 sa1111_dmamask = 0xffffffffUL;
...@@ -121,11 +128,8 @@ static struct flash_platform_data badge4_flash_data = { ...@@ -121,11 +128,8 @@ static struct flash_platform_data badge4_flash_data = {
.nr_parts = ARRAY_SIZE(badge4_partitions), .nr_parts = ARRAY_SIZE(badge4_partitions),
}; };
static struct resource badge4_flash_resource = { static struct resource badge4_flash_resource =
.start = SA1100_CS0_PHYS, DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_64M);
.end = SA1100_CS0_PHYS + SZ_64M - 1,
.flags = IORESOURCE_MEM,
};
static int five_v_on __initdata = 0; static int five_v_on __initdata = 0;
...@@ -269,11 +273,6 @@ static struct map_desc badge4_io_desc[] __initdata = { ...@@ -269,11 +273,6 @@ static struct map_desc badge4_io_desc[] __initdata = {
.pfn = __phys_to_pfn(0x10000000), .pfn = __phys_to_pfn(0x10000000),
.length = 0x00100000, .length = 0x00100000,
.type = MT_DEVICE .type = MT_DEVICE
}, { /* SA-1111 */
.virtual = 0xf4000000,
.pfn = __phys_to_pfn(0x48000000),
.length = 0x00100000,
.type = MT_DEVICE
} }
}; };
...@@ -304,6 +303,7 @@ static void __init badge4_map_io(void) ...@@ -304,6 +303,7 @@ static void __init badge4_map_io(void)
MACHINE_START(BADGE4, "Hewlett-Packard Laboratories BadgePAD 4") MACHINE_START(BADGE4, "Hewlett-Packard Laboratories BadgePAD 4")
.atag_offset = 0x100, .atag_offset = 0x100,
.map_io = badge4_map_io, .map_io = badge4_map_io,
.nr_irqs = SA1100_NR_IRQS,
.init_irq = sa1100_init_irq, .init_irq = sa1100_init_irq,
.timer = &sa1100_timer, .timer = &sa1100_timer,
#ifdef CONFIG_SA1111 #ifdef CONFIG_SA1111
......
...@@ -18,7 +18,6 @@ ...@@ -18,7 +18,6 @@
#include <linux/mtd/mtd.h> #include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h> #include <linux/mtd/partitions.h>
#include <asm/irq.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <asm/setup.h> #include <asm/setup.h>
...@@ -30,14 +29,11 @@ ...@@ -30,14 +29,11 @@
#include <mach/cerf.h> #include <mach/cerf.h>
#include <mach/mcp.h> #include <mach/mcp.h>
#include <mach/irqs.h>
#include "generic.h" #include "generic.h"
static struct resource cerfuart2_resources[] = { static struct resource cerfuart2_resources[] = {
[0] = { [0] = DEFINE_RES_MEM(0x80030000, SZ_64K),
.start = 0x80030000,
.end = 0x8003ffff,
.flags = IORESOURCE_MEM,
},
}; };
static struct platform_device cerfuart2_device = { static struct platform_device cerfuart2_device = {
...@@ -87,11 +83,8 @@ static struct flash_platform_data cerf_flash_data = { ...@@ -87,11 +83,8 @@ static struct flash_platform_data cerf_flash_data = {
.nr_parts = ARRAY_SIZE(cerf_partitions), .nr_parts = ARRAY_SIZE(cerf_partitions),
}; };
static struct resource cerf_flash_resource = { static struct resource cerf_flash_resource =
.start = SA1100_CS0_PHYS, DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_32M);
.end = SA1100_CS0_PHYS + SZ_32M - 1,
.flags = IORESOURCE_MEM,
};
static void __init cerf_init_irq(void) static void __init cerf_init_irq(void)
{ {
...@@ -128,6 +121,7 @@ static struct mcp_plat_data cerf_mcp_data = { ...@@ -128,6 +121,7 @@ static struct mcp_plat_data cerf_mcp_data = {
static void __init cerf_init(void) static void __init cerf_init(void)
{ {
sa11x0_ppc_configure_mcp();
platform_add_devices(cerf_devices, ARRAY_SIZE(cerf_devices)); platform_add_devices(cerf_devices, ARRAY_SIZE(cerf_devices));
sa11x0_register_mtd(&cerf_flash_data, &cerf_flash_resource, 1); sa11x0_register_mtd(&cerf_flash_data, &cerf_flash_resource, 1);
sa11x0_register_mcp(&cerf_mcp_data); sa11x0_register_mcp(&cerf_mcp_data);
...@@ -136,6 +130,7 @@ static void __init cerf_init(void) ...@@ -136,6 +130,7 @@ static void __init cerf_init(void)
MACHINE_START(CERF, "Intrinsyc CerfBoard/CerfCube") MACHINE_START(CERF, "Intrinsyc CerfBoard/CerfCube")
/* Maintainer: support@intrinsyc.com */ /* Maintainer: support@intrinsyc.com */
.map_io = cerf_map_io, .map_io = cerf_map_io,
.nr_irqs = SA1100_NR_IRQS,
.init_irq = cerf_init_irq, .init_irq = cerf_init_irq,
.timer = &sa1100_timer, .timer = &sa1100_timer,
.init_machine = cerf_init, .init_machine = cerf_init,
......
...@@ -22,15 +22,17 @@ ...@@ -22,15 +22,17 @@
#include <linux/tty.h> #include <linux/tty.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/mfd/ucb1x00.h>
#include <linux/mtd/mtd.h> #include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h> #include <linux/mtd/partitions.h>
#include <linux/timer.h> #include <linux/timer.h>
#include <linux/gpio.h> #include <linux/gpio.h>
#include <linux/pda_power.h> #include <linux/pda_power.h>
#include <video/sa1100fb.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
#include <asm/irq.h>
#include <asm/page.h> #include <asm/page.h>
#include <asm/setup.h> #include <asm/setup.h>
#include <mach/collie.h> #include <mach/collie.h>
...@@ -44,15 +46,12 @@ ...@@ -44,15 +46,12 @@
#include <asm/mach/sharpsl_param.h> #include <asm/mach/sharpsl_param.h>
#include <asm/hardware/locomo.h> #include <asm/hardware/locomo.h>
#include <mach/mcp.h> #include <mach/mcp.h>
#include <mach/irqs.h>
#include "generic.h" #include "generic.h"
static struct resource collie_scoop_resources[] = { static struct resource collie_scoop_resources[] = {
[0] = { [0] = DEFINE_RES_MEM(0x40800000, SZ_4K),
.start = 0x40800000,
.end = 0x40800fff,
.flags = IORESOURCE_MEM,
},
}; };
static struct scoop_config collie_scoop_setup = { static struct scoop_config collie_scoop_setup = {
...@@ -85,10 +84,14 @@ static struct scoop_pcmcia_config collie_pcmcia_config = { ...@@ -85,10 +84,14 @@ static struct scoop_pcmcia_config collie_pcmcia_config = {
.num_devs = 1, .num_devs = 1,
}; };
static struct ucb1x00_plat_data collie_ucb1x00_data = {
.gpio_base = COLLIE_TC35143_GPIO_BASE,
};
static struct mcp_plat_data collie_mcp_data = { static struct mcp_plat_data collie_mcp_data = {
.mccr0 = MCCR0_ADM | MCCR0_ExtClk, .mccr0 = MCCR0_ADM | MCCR0_ExtClk,
.sclk_rate = 9216000, .sclk_rate = 9216000,
.gpio_base = COLLIE_TC35143_GPIO_BASE, .codec_pdata = &collie_ucb1x00_data,
}; };
/* /*
...@@ -221,16 +224,8 @@ device_initcall(collie_uart_init); ...@@ -221,16 +224,8 @@ device_initcall(collie_uart_init);
static struct resource locomo_resources[] = { static struct resource locomo_resources[] = {
[0] = { [0] = DEFINE_RES_MEM(0x40000000, SZ_8K),
.start = 0x40000000, [1] = DEFINE_RES_IRQ(IRQ_GPIO25),
.end = 0x40001fff,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = IRQ_GPIO25,
.end = IRQ_GPIO25,
.flags = IORESOURCE_IRQ,
},
}; };
static struct locomo_platform_data locomo_info = { static struct locomo_platform_data locomo_info = {
...@@ -303,11 +298,21 @@ static struct flash_platform_data collie_flash_data = { ...@@ -303,11 +298,21 @@ static struct flash_platform_data collie_flash_data = {
}; };
static struct resource collie_flash_resources[] = { static struct resource collie_flash_resources[] = {
{ DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_32M),
.start = SA1100_CS0_PHYS, };
.end = SA1100_CS0_PHYS + SZ_32M - 1,
.flags = IORESOURCE_MEM, static struct sa1100fb_mach_info collie_lcd_info = {
} .pixclock = 171521, .bpp = 16,
.xres = 320, .yres = 240,
.hsync_len = 5, .vsync_len = 1,
.left_margin = 11, .upper_margin = 2,
.right_margin = 30, .lower_margin = 0,
.sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
.lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
.lccr3 = LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(2),
}; };
static void __init collie_init(void) static void __init collie_init(void)
...@@ -341,6 +346,10 @@ static void __init collie_init(void) ...@@ -341,6 +346,10 @@ static void __init collie_init(void)
collie_power_resource[0].start = gpio_to_irq(COLLIE_GPIO_AC_IN); collie_power_resource[0].start = gpio_to_irq(COLLIE_GPIO_AC_IN);
collie_power_resource[0].end = gpio_to_irq(COLLIE_GPIO_AC_IN); collie_power_resource[0].end = gpio_to_irq(COLLIE_GPIO_AC_IN);
sa11x0_ppc_configure_mcp();
platform_scoop_config = &collie_pcmcia_config; platform_scoop_config = &collie_pcmcia_config;
ret = platform_add_devices(devices, ARRAY_SIZE(devices)); ret = platform_add_devices(devices, ARRAY_SIZE(devices));
...@@ -348,6 +357,7 @@ static void __init collie_init(void) ...@@ -348,6 +357,7 @@ static void __init collie_init(void)
printk(KERN_WARNING "collie: Unable to register LoCoMo device\n"); printk(KERN_WARNING "collie: Unable to register LoCoMo device\n");
} }
sa11x0_register_lcd(&collie_lcd_info);
sa11x0_register_mtd(&collie_flash_data, collie_flash_resources, sa11x0_register_mtd(&collie_flash_data, collie_flash_resources,
ARRAY_SIZE(collie_flash_resources)); ARRAY_SIZE(collie_flash_resources));
sa11x0_register_mcp(&collie_mcp_data); sa11x0_register_mcp(&collie_mcp_data);
...@@ -383,6 +393,7 @@ static void __init collie_map_io(void) ...@@ -383,6 +393,7 @@ static void __init collie_map_io(void)
MACHINE_START(COLLIE, "Sharp-Collie") MACHINE_START(COLLIE, "Sharp-Collie")
.map_io = collie_map_io, .map_io = collie_map_io,
.nr_irqs = SA1100_NR_IRQS,
.init_irq = sa1100_init_irq, .init_irq = sa1100_init_irq,
.timer = &sa1100_timer, .timer = &sa1100_timer,
.init_machine = collie_init, .init_machine = collie_init,
......
/*
* arch/arm/mach-sa1100/dma.c
*
* Support functions for the SA11x0 internal DMA channels.
*
* Copyright (C) 2000, 2001 by Nicolas Pitre
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/spinlock.h>
#include <linux/errno.h>
#include <asm/system.h>
#include <asm/irq.h>
#include <mach/hardware.h>
#include <mach/dma.h>
#undef DEBUG
#ifdef DEBUG
#define DPRINTK( s, arg... ) printk( "dma<%p>: " s, regs , ##arg )
#else
#define DPRINTK( x... )
#endif
typedef struct {
const char *device_id; /* device name */
u_long device; /* this channel device, 0 if unused*/
dma_callback_t callback; /* to call when DMA completes */
void *data; /* ... with private data ptr */
} sa1100_dma_t;
static sa1100_dma_t dma_chan[SA1100_DMA_CHANNELS];
static DEFINE_SPINLOCK(dma_list_lock);
static irqreturn_t dma_irq_handler(int irq, void *dev_id)
{
dma_regs_t *dma_regs = dev_id;
sa1100_dma_t *dma = dma_chan + (((u_int)dma_regs >> 5) & 7);
int status = dma_regs->RdDCSR;
if (status & (DCSR_ERROR)) {
printk(KERN_CRIT "DMA on \"%s\" caused an error\n", dma->device_id);
dma_regs->ClrDCSR = DCSR_ERROR;
}
dma_regs->ClrDCSR = status & (DCSR_DONEA | DCSR_DONEB);
if (dma->callback) {
if (status & DCSR_DONEA)
dma->callback(dma->data);
if (status & DCSR_DONEB)
dma->callback(dma->data);
}
return IRQ_HANDLED;
}
/**
* sa1100_request_dma - allocate one of the SA11x0's DMA channels
* @device: The SA11x0 peripheral targeted by this request
* @device_id: An ascii name for the claiming device
* @callback: Function to be called when the DMA completes
* @data: A cookie passed back to the callback function
* @dma_regs: Pointer to the location of the allocated channel's identifier
*
* This function will search for a free DMA channel and returns the
* address of the hardware registers for that channel as the channel
* identifier. This identifier is written to the location pointed by
* @dma_regs. The list of possible values for @device are listed into
* arch/arm/mach-sa1100/include/mach/dma.h as a dma_device_t enum.
*
* Note that reading from a port and writing to the same port are
* actually considered as two different streams requiring separate
* DMA registrations.
*
* The @callback function is called from interrupt context when one
* of the two possible DMA buffers in flight has terminated. That
* function has to be small and efficient while posponing more complex
* processing to a lower priority execution context.
*
* If no channels are available, or if the desired @device is already in
* use by another DMA channel, then an error code is returned. This
* function must be called before any other DMA calls.
**/
int sa1100_request_dma (dma_device_t device, const char *device_id,
dma_callback_t callback, void *data,
dma_regs_t **dma_regs)
{
sa1100_dma_t *dma = NULL;
dma_regs_t *regs;
int i, err;
*dma_regs = NULL;
err = 0;
spin_lock(&dma_list_lock);
for (i = 0; i < SA1100_DMA_CHANNELS; i++) {
if (dma_chan[i].device == device) {
err = -EBUSY;
break;
} else if (!dma_chan[i].device && !dma) {
dma = &dma_chan[i];
}
}
if (!err) {
if (dma)
dma->device = device;
else
err = -ENOSR;
}
spin_unlock(&dma_list_lock);
if (err)
return err;
i = dma - dma_chan;
regs = (dma_regs_t *)&DDAR(i);
err = request_irq(IRQ_DMA0 + i, dma_irq_handler, IRQF_DISABLED,
device_id, regs);
if (err) {
printk(KERN_ERR
"%s: unable to request IRQ %d for %s\n",
__func__, IRQ_DMA0 + i, device_id);
dma->device = 0;
return err;
}
*dma_regs = regs;
dma->device_id = device_id;
dma->callback = callback;
dma->data = data;
regs->ClrDCSR =
(DCSR_DONEA | DCSR_DONEB | DCSR_STRTA | DCSR_STRTB |
DCSR_IE | DCSR_ERROR | DCSR_RUN);
regs->DDAR = device;
return 0;
}
/**
* sa1100_free_dma - free a SA11x0 DMA channel
* @regs: identifier for the channel to free
*
* This clears all activities on a given DMA channel and releases it
* for future requests. The @regs identifier is provided by a
* successful call to sa1100_request_dma().
**/
void sa1100_free_dma(dma_regs_t *regs)
{
int i;
for (i = 0; i < SA1100_DMA_CHANNELS; i++)
if (regs == (dma_regs_t *)&DDAR(i))
break;
if (i >= SA1100_DMA_CHANNELS) {
printk(KERN_ERR "%s: bad DMA identifier\n", __func__);
return;
}
if (!dma_chan[i].device) {
printk(KERN_ERR "%s: Trying to free free DMA\n", __func__);
return;
}
regs->ClrDCSR =
(DCSR_DONEA | DCSR_DONEB | DCSR_STRTA | DCSR_STRTB |
DCSR_IE | DCSR_ERROR | DCSR_RUN);
free_irq(IRQ_DMA0 + i, regs);
dma_chan[i].device = 0;
}
/**
* sa1100_start_dma - submit a data buffer for DMA
* @regs: identifier for the channel to use
* @dma_ptr: buffer physical (or bus) start address
* @size: buffer size
*
* This function hands the given data buffer to the hardware for DMA
* access. If another buffer is already in flight then this buffer
* will be queued so the DMA engine will switch to it automatically
* when the previous one is done. The DMA engine is actually toggling
* between two buffers so at most 2 successful calls can be made before
* one of them terminates and the callback function is called.
*
* The @regs identifier is provided by a successful call to
* sa1100_request_dma().
*
* The @size must not be larger than %MAX_DMA_SIZE. If a given buffer
* is larger than that then it's the caller's responsibility to split
* it into smaller chunks and submit them separately. If this is the
* case then a @size of %CUT_DMA_SIZE is recommended to avoid ending
* up with too small chunks. The callback function can be used to chain
* submissions of buffer chunks.
*
* Error return values:
* %-EOVERFLOW: Given buffer size is too big.
* %-EBUSY: Both DMA buffers are already in use.
* %-EAGAIN: Both buffers were busy but one of them just completed
* but the interrupt handler has to execute first.
*
* This function returs 0 on success.
**/
int sa1100_start_dma(dma_regs_t *regs, dma_addr_t dma_ptr, u_int size)
{
unsigned long flags;
u_long status;
int ret;
if (dma_ptr & 3)
printk(KERN_WARNING "DMA: unaligned start address (0x%08lx)\n",
(unsigned long)dma_ptr);
if (size > MAX_DMA_SIZE)
return -EOVERFLOW;
local_irq_save(flags);
status = regs->RdDCSR;
/* If both DMA buffers are started, there's nothing else we can do. */
if ((status & (DCSR_STRTA | DCSR_STRTB)) == (DCSR_STRTA | DCSR_STRTB)) {
DPRINTK("start: st %#x busy\n", status);
ret = -EBUSY;
goto out;
}
if (((status & DCSR_BIU) && (status & DCSR_STRTB)) ||
(!(status & DCSR_BIU) && !(status & DCSR_STRTA))) {
if (status & DCSR_DONEA) {
/* give a chance for the interrupt to be processed */
ret = -EAGAIN;
goto out;
}
regs->DBSA = dma_ptr;
regs->DBTA = size;
regs->SetDCSR = DCSR_STRTA | DCSR_IE | DCSR_RUN;
DPRINTK("start a=%#x s=%d on A\n", dma_ptr, size);
} else {
if (status & DCSR_DONEB) {
/* give a chance for the interrupt to be processed */
ret = -EAGAIN;
goto out;
}
regs->DBSB = dma_ptr;
regs->DBTB = size;
regs->SetDCSR = DCSR_STRTB | DCSR_IE | DCSR_RUN;
DPRINTK("start a=%#x s=%d on B\n", dma_ptr, size);
}
ret = 0;
out:
local_irq_restore(flags);
return ret;
}
/**
* sa1100_get_dma_pos - return current DMA position
* @regs: identifier for the channel to use
*
* This function returns the current physical (or bus) address for the
* given DMA channel. If the channel is running i.e. not in a stopped
* state then the caller must disable interrupts prior calling this
* function and process the returned value before re-enabling them to
* prevent races with the completion interrupt handler and the callback
* function. The validation of the returned value is the caller's
* responsibility as well -- the hardware seems to return out of range
* values when the DMA engine completes a buffer.
*
* The @regs identifier is provided by a successful call to
* sa1100_request_dma().
**/
dma_addr_t sa1100_get_dma_pos(dma_regs_t *regs)
{
int status;
/*
* We must determine whether buffer A or B is active.
* Two possibilities: either we are in the middle of
* a buffer, or the DMA controller just switched to the
* next toggle but the interrupt hasn't been serviced yet.
* The former case is straight forward. In the later case,
* we'll do like if DMA is just at the end of the previous
* toggle since all registers haven't been reset yet.
* This goes around the edge case and since we're always
* a little behind anyways it shouldn't make a big difference.
* If DMA has been stopped prior calling this then the
* position is exact.
*/
status = regs->RdDCSR;
if ((!(status & DCSR_BIU) && (status & DCSR_STRTA)) ||
( (status & DCSR_BIU) && !(status & DCSR_STRTB)))
return regs->DBSA;
else
return regs->DBSB;
}
/**
* sa1100_reset_dma - reset a DMA channel
* @regs: identifier for the channel to use
*
* This function resets and reconfigure the given DMA channel. This is
* particularly useful after a sleep/wakeup event.
*
* The @regs identifier is provided by a successful call to
* sa1100_request_dma().
**/
void sa1100_reset_dma(dma_regs_t *regs)
{
int i;
for (i = 0; i < SA1100_DMA_CHANNELS; i++)
if (regs == (dma_regs_t *)&DDAR(i))
break;
if (i >= SA1100_DMA_CHANNELS) {
printk(KERN_ERR "%s: bad DMA identifier\n", __func__);
return;
}
regs->ClrDCSR =
(DCSR_DONEA | DCSR_DONEB | DCSR_STRTA | DCSR_STRTB |
DCSR_IE | DCSR_ERROR | DCSR_RUN);
regs->DDAR = dma_chan[i].device;
}
EXPORT_SYMBOL(sa1100_request_dma);
EXPORT_SYMBOL(sa1100_free_dma);
EXPORT_SYMBOL(sa1100_start_dma);
EXPORT_SYMBOL(sa1100_get_dma_pos);
EXPORT_SYMBOL(sa1100_reset_dma);
...@@ -14,18 +14,23 @@ ...@@ -14,18 +14,23 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/pm.h> #include <linux/pm.h>
#include <linux/cpufreq.h> #include <linux/cpufreq.h>
#include <linux/ioport.h> #include <linux/ioport.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <video/sa1100fb.h>
#include <asm/div64.h> #include <asm/div64.h>
#include <mach/hardware.h>
#include <asm/system.h> #include <asm/system.h>
#include <asm/mach/map.h> #include <asm/mach/map.h>
#include <asm/mach/flash.h> #include <asm/mach/flash.h>
#include <asm/irq.h> #include <asm/irq.h>
#include <mach/hardware.h>
#include <mach/irqs.h>
#include "generic.h" #include "generic.h"
unsigned int reset_status; unsigned int reset_status;
...@@ -149,16 +154,8 @@ static void sa11x0_register_device(struct platform_device *dev, void *data) ...@@ -149,16 +154,8 @@ static void sa11x0_register_device(struct platform_device *dev, void *data)
static struct resource sa11x0udc_resources[] = { static struct resource sa11x0udc_resources[] = {
[0] = { [0] = DEFINE_RES_MEM(__PREG(Ser0UDCCR), SZ_64K),
.start = __PREG(Ser0UDCCR), [1] = DEFINE_RES_IRQ(IRQ_Ser0UDC),
.end = __PREG(Ser0UDCCR) + 0xffff,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = IRQ_Ser0UDC,
.end = IRQ_Ser0UDC,
.flags = IORESOURCE_IRQ,
},
}; };
static u64 sa11x0udc_dma_mask = 0xffffffffUL; static u64 sa11x0udc_dma_mask = 0xffffffffUL;
...@@ -175,16 +172,8 @@ static struct platform_device sa11x0udc_device = { ...@@ -175,16 +172,8 @@ static struct platform_device sa11x0udc_device = {
}; };
static struct resource sa11x0uart1_resources[] = { static struct resource sa11x0uart1_resources[] = {
[0] = { [0] = DEFINE_RES_MEM(__PREG(Ser1UTCR0), SZ_64K),
.start = __PREG(Ser1UTCR0), [1] = DEFINE_RES_IRQ(IRQ_Ser1UART),
.end = __PREG(Ser1UTCR0) + 0xffff,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = IRQ_Ser1UART,
.end = IRQ_Ser1UART,
.flags = IORESOURCE_IRQ,
},
}; };
static struct platform_device sa11x0uart1_device = { static struct platform_device sa11x0uart1_device = {
...@@ -195,16 +184,8 @@ static struct platform_device sa11x0uart1_device = { ...@@ -195,16 +184,8 @@ static struct platform_device sa11x0uart1_device = {
}; };
static struct resource sa11x0uart3_resources[] = { static struct resource sa11x0uart3_resources[] = {
[0] = { [0] = DEFINE_RES_MEM(__PREG(Ser3UTCR0), SZ_64K),
.start = __PREG(Ser3UTCR0), [1] = DEFINE_RES_IRQ(IRQ_Ser3UART),
.end = __PREG(Ser3UTCR0) + 0xffff,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = IRQ_Ser3UART,
.end = IRQ_Ser3UART,
.flags = IORESOURCE_IRQ,
},
}; };
static struct platform_device sa11x0uart3_device = { static struct platform_device sa11x0uart3_device = {
...@@ -215,16 +196,9 @@ static struct platform_device sa11x0uart3_device = { ...@@ -215,16 +196,9 @@ static struct platform_device sa11x0uart3_device = {
}; };
static struct resource sa11x0mcp_resources[] = { static struct resource sa11x0mcp_resources[] = {
[0] = { [0] = DEFINE_RES_MEM(__PREG(Ser4MCCR0), SZ_64K),
.start = __PREG(Ser4MCCR0), [1] = DEFINE_RES_MEM(__PREG(Ser4MCCR1), 4),
.end = __PREG(Ser4MCCR0) + 0xffff, [2] = DEFINE_RES_IRQ(IRQ_Ser4MCP),
.flags = IORESOURCE_MEM,
},
[1] = {
.start = IRQ_Ser4MCP,
.end = IRQ_Ser4MCP,
.flags = IORESOURCE_IRQ,
},
}; };
static u64 sa11x0mcp_dma_mask = 0xffffffffUL; static u64 sa11x0mcp_dma_mask = 0xffffffffUL;
...@@ -240,22 +214,24 @@ static struct platform_device sa11x0mcp_device = { ...@@ -240,22 +214,24 @@ static struct platform_device sa11x0mcp_device = {
.resource = sa11x0mcp_resources, .resource = sa11x0mcp_resources,
}; };
void __init sa11x0_ppc_configure_mcp(void)
{
/* Setup the PPC unit for the MCP */
PPDR &= ~PPC_RXD4;
PPDR |= PPC_TXD4 | PPC_SCLK | PPC_SFRM;
PSDR |= PPC_RXD4;
PSDR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
PPSR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
}
void sa11x0_register_mcp(struct mcp_plat_data *data) void sa11x0_register_mcp(struct mcp_plat_data *data)
{ {
sa11x0_register_device(&sa11x0mcp_device, data); sa11x0_register_device(&sa11x0mcp_device, data);
} }
static struct resource sa11x0ssp_resources[] = { static struct resource sa11x0ssp_resources[] = {
[0] = { [0] = DEFINE_RES_MEM(0x80070000, SZ_64K),
.start = 0x80070000, [1] = DEFINE_RES_IRQ(IRQ_Ser4SSP),
.end = 0x8007ffff,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = IRQ_Ser4SSP,
.end = IRQ_Ser4SSP,
.flags = IORESOURCE_IRQ,
},
}; };
static u64 sa11x0ssp_dma_mask = 0xffffffffUL; static u64 sa11x0ssp_dma_mask = 0xffffffffUL;
...@@ -272,16 +248,8 @@ static struct platform_device sa11x0ssp_device = { ...@@ -272,16 +248,8 @@ static struct platform_device sa11x0ssp_device = {
}; };
static struct resource sa11x0fb_resources[] = { static struct resource sa11x0fb_resources[] = {
[0] = { [0] = DEFINE_RES_MEM(0xb0100000, SZ_64K),
.start = 0xb0100000, [1] = DEFINE_RES_IRQ(IRQ_LCD),
.end = 0xb010ffff,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = IRQ_LCD,
.end = IRQ_LCD,
.flags = IORESOURCE_IRQ,
},
}; };
static struct platform_device sa11x0fb_device = { static struct platform_device sa11x0fb_device = {
...@@ -294,6 +262,11 @@ static struct platform_device sa11x0fb_device = { ...@@ -294,6 +262,11 @@ static struct platform_device sa11x0fb_device = {
.resource = sa11x0fb_resources, .resource = sa11x0fb_resources,
}; };
void sa11x0_register_lcd(struct sa1100fb_mach_info *inf)
{
sa11x0_register_device(&sa11x0fb_device, inf);
}
static struct platform_device sa11x0pcmcia_device = { static struct platform_device sa11x0pcmcia_device = {
.name = "sa11x0-pcmcia", .name = "sa11x0-pcmcia",
.id = -1, .id = -1,
...@@ -314,23 +287,10 @@ void sa11x0_register_mtd(struct flash_platform_data *flash, ...@@ -314,23 +287,10 @@ void sa11x0_register_mtd(struct flash_platform_data *flash,
} }
static struct resource sa11x0ir_resources[] = { static struct resource sa11x0ir_resources[] = {
{ DEFINE_RES_MEM(__PREG(Ser2UTCR0), 0x24),
.start = __PREG(Ser2UTCR0), DEFINE_RES_MEM(__PREG(Ser2HSCR0), 0x1c),
.end = __PREG(Ser2UTCR0) + 0x24 - 1, DEFINE_RES_MEM(__PREG(Ser2HSCR2), 0x04),
.flags = IORESOURCE_MEM, DEFINE_RES_IRQ(IRQ_Ser2ICP),
}, {
.start = __PREG(Ser2HSCR0),
.end = __PREG(Ser2HSCR0) + 0x1c - 1,
.flags = IORESOURCE_MEM,
}, {
.start = __PREG(Ser2HSCR2),
.end = __PREG(Ser2HSCR2) + 0x04 - 1,
.flags = IORESOURCE_MEM,
}, {
.start = IRQ_Ser2ICP,
.end = IRQ_Ser2ICP,
.flags = IORESOURCE_IRQ,
}
}; };
static struct platform_device sa11x0ir_device = { static struct platform_device sa11x0ir_device = {
...@@ -358,14 +318,37 @@ static struct platform_device sa11x0rtc_device = { ...@@ -358,14 +318,37 @@ static struct platform_device sa11x0rtc_device = {
.resource = sa1100_rtc_resources, .resource = sa1100_rtc_resources,
}; };
static struct resource sa11x0dma_resources[] = {
DEFINE_RES_MEM(DMA_PHYS, DMA_SIZE),
DEFINE_RES_IRQ(IRQ_DMA0),
DEFINE_RES_IRQ(IRQ_DMA1),
DEFINE_RES_IRQ(IRQ_DMA2),
DEFINE_RES_IRQ(IRQ_DMA3),
DEFINE_RES_IRQ(IRQ_DMA4),
DEFINE_RES_IRQ(IRQ_DMA5),
};
static u64 sa11x0dma_dma_mask = DMA_BIT_MASK(32);
static struct platform_device sa11x0dma_device = {
.name = "sa11x0-dma",
.id = -1,
.dev = {
.dma_mask = &sa11x0dma_dma_mask,
.coherent_dma_mask = 0xffffffff,
},
.num_resources = ARRAY_SIZE(sa11x0dma_resources),
.resource = sa11x0dma_resources,
};
static struct platform_device *sa11x0_devices[] __initdata = { static struct platform_device *sa11x0_devices[] __initdata = {
&sa11x0udc_device, &sa11x0udc_device,
&sa11x0uart1_device, &sa11x0uart1_device,
&sa11x0uart3_device, &sa11x0uart3_device,
&sa11x0ssp_device, &sa11x0ssp_device,
&sa11x0pcmcia_device, &sa11x0pcmcia_device,
&sa11x0fb_device,
&sa11x0rtc_device, &sa11x0rtc_device,
&sa11x0dma_device,
}; };
static int __init sa1100_init(void) static int __init sa1100_init(void)
...@@ -376,12 +359,6 @@ static int __init sa1100_init(void) ...@@ -376,12 +359,6 @@ static int __init sa1100_init(void)
arch_initcall(sa1100_init); arch_initcall(sa1100_init);
void (*sa1100fb_backlight_power)(int on);
void (*sa1100fb_lcd_power)(int on);
EXPORT_SYMBOL(sa1100fb_backlight_power);
EXPORT_SYMBOL(sa1100fb_lcd_power);
/* /*
* Common I/O mapping: * Common I/O mapping:
...@@ -436,7 +413,7 @@ void __init sa1100_map_io(void) ...@@ -436,7 +413,7 @@ void __init sa1100_map_io(void)
* the MBGNT signal false to ensure the SA1111 doesn't own the * the MBGNT signal false to ensure the SA1111 doesn't own the
* SDRAM bus. * SDRAM bus.
*/ */
void __init sa1110_mb_disable(void) void sa1110_mb_disable(void)
{ {
unsigned long flags; unsigned long flags;
...@@ -455,7 +432,7 @@ void __init sa1110_mb_disable(void) ...@@ -455,7 +432,7 @@ void __init sa1110_mb_disable(void)
* If the system is going to use the SA-1111 DMA engines, set up * If the system is going to use the SA-1111 DMA engines, set up
* the memory bus request/grant pins. * the memory bus request/grant pins.
*/ */
void __devinit sa1110_mb_enable(void) void sa1110_mb_enable(void)
{ {
unsigned long flags; unsigned long flags;
......
...@@ -16,9 +16,6 @@ extern void sa11x0_restart(char, const char *); ...@@ -16,9 +16,6 @@ extern void sa11x0_restart(char, const char *);
mi->bank[__nr].start = (__start), \ mi->bank[__nr].start = (__start), \
mi->bank[__nr].size = (__size) mi->bank[__nr].size = (__size)
extern void (*sa1100fb_backlight_power)(int on);
extern void (*sa1100fb_lcd_power)(int on);
extern void sa1110_mb_enable(void); extern void sa1110_mb_enable(void);
extern void sa1110_mb_disable(void); extern void sa1110_mb_disable(void);
...@@ -39,4 +36,8 @@ struct irda_platform_data; ...@@ -39,4 +36,8 @@ struct irda_platform_data;
void sa11x0_register_irda(struct irda_platform_data *irda); void sa11x0_register_irda(struct irda_platform_data *irda);
struct mcp_plat_data; struct mcp_plat_data;
void sa11x0_ppc_configure_mcp(void);
void sa11x0_register_mcp(struct mcp_plat_data *data); void sa11x0_register_mcp(struct mcp_plat_data *data);
struct sa1100fb_mach_info;
void sa11x0_register_lcd(struct sa1100fb_mach_info *inf);
...@@ -14,11 +14,14 @@ ...@@ -14,11 +14,14 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/gpio.h> #include <linux/gpio.h>
#include <video/sa1100fb.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
#include <asm/mach/arch.h> #include <asm/mach/arch.h>
#include <asm/mach/irda.h> #include <asm/mach/irda.h>
#include <mach/h3xxx.h> #include <mach/h3xxx.h>
#include <mach/irqs.h>
#include "generic.h" #include "generic.h"
...@@ -36,13 +39,28 @@ static void h3100_lcd_power(int enable) ...@@ -36,13 +39,28 @@ static void h3100_lcd_power(int enable)
} }
} }
static struct sa1100fb_mach_info h3100_lcd_info = {
.pixclock = 406977, .bpp = 4,
.xres = 320, .yres = 240,
.hsync_len = 26, .vsync_len = 41,
.left_margin = 4, .upper_margin = 0,
.right_margin = 4, .lower_margin = 0,
.sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
.cmap_greyscale = 1,
.cmap_inverse = 1,
.lccr0 = LCCR0_Mono | LCCR0_4PixMono | LCCR0_Sngl | LCCR0_Pas,
.lccr3 = LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(2),
.lcd_power = h3100_lcd_power,
};
static void __init h3100_map_io(void) static void __init h3100_map_io(void)
{ {
h3xxx_map_io(); h3xxx_map_io();
sa1100fb_lcd_power = h3100_lcd_power;
/* Older bootldrs put GPIO2-9 in alternate mode on the /* Older bootldrs put GPIO2-9 in alternate mode on the
assumption that they are used for video */ assumption that they are used for video */
GAFR &= ~0x000001fb; GAFR &= ~0x000001fb;
...@@ -80,12 +98,15 @@ static void __init h3100_mach_init(void) ...@@ -80,12 +98,15 @@ static void __init h3100_mach_init(void)
{ {
h3xxx_init_gpio(h3100_default_gpio, ARRAY_SIZE(h3100_default_gpio)); h3xxx_init_gpio(h3100_default_gpio, ARRAY_SIZE(h3100_default_gpio));
h3xxx_mach_init(); h3xxx_mach_init();
sa11x0_register_lcd(&h3100_lcd_info);
sa11x0_register_irda(&h3100_irda_data); sa11x0_register_irda(&h3100_irda_data);
} }
MACHINE_START(H3100, "Compaq iPAQ H3100") MACHINE_START(H3100, "Compaq iPAQ H3100")
.atag_offset = 0x100, .atag_offset = 0x100,
.map_io = h3100_map_io, .map_io = h3100_map_io,
.nr_irqs = SA1100_NR_IRQS,
.init_irq = sa1100_init_irq, .init_irq = sa1100_init_irq,
.timer = &sa1100_timer, .timer = &sa1100_timer,
.init_machine = h3100_mach_init, .init_machine = h3100_mach_init,
......
...@@ -14,11 +14,14 @@ ...@@ -14,11 +14,14 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/gpio.h> #include <linux/gpio.h>
#include <video/sa1100fb.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
#include <asm/mach/arch.h> #include <asm/mach/arch.h>
#include <asm/mach/irda.h> #include <asm/mach/irda.h>
#include <mach/h3xxx.h> #include <mach/h3xxx.h>
#include <mach/irqs.h>
#include "generic.h" #include "generic.h"
...@@ -56,11 +59,35 @@ err2: gpio_free(H3XXX_EGPIO_LCD_ON); ...@@ -56,11 +59,35 @@ err2: gpio_free(H3XXX_EGPIO_LCD_ON);
err1: return; err1: return;
} }
static const struct sa1100fb_rgb h3600_rgb_16 = {
.red = { .offset = 12, .length = 4, },
.green = { .offset = 7, .length = 4, },
.blue = { .offset = 1, .length = 4, },
.transp = { .offset = 0, .length = 0, },
};
static struct sa1100fb_mach_info h3600_lcd_info = {
.pixclock = 174757, .bpp = 16,
.xres = 320, .yres = 240,
.hsync_len = 3, .vsync_len = 3,
.left_margin = 12, .upper_margin = 10,
.right_margin = 17, .lower_margin = 1,
.cmap_static = 1,
.lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
.lccr3 = LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(2),
.rgb[RGB_16] = &h3600_rgb_16,
.lcd_power = h3600_lcd_power,
};
static void __init h3600_map_io(void) static void __init h3600_map_io(void)
{ {
h3xxx_map_io(); h3xxx_map_io();
sa1100fb_lcd_power = h3600_lcd_power;
} }
/* /*
...@@ -121,12 +148,15 @@ static void __init h3600_mach_init(void) ...@@ -121,12 +148,15 @@ static void __init h3600_mach_init(void)
{ {
h3xxx_init_gpio(h3600_default_gpio, ARRAY_SIZE(h3600_default_gpio)); h3xxx_init_gpio(h3600_default_gpio, ARRAY_SIZE(h3600_default_gpio));
h3xxx_mach_init(); h3xxx_mach_init();
sa11x0_register_lcd(&h3600_lcd_info);
sa11x0_register_irda(&h3600_irda_data); sa11x0_register_irda(&h3600_irda_data);
} }
MACHINE_START(H3600, "Compaq iPAQ H3600") MACHINE_START(H3600, "Compaq iPAQ H3600")
.atag_offset = 0x100, .atag_offset = 0x100,
.map_io = h3600_map_io, .map_io = h3600_map_io,
.nr_irqs = SA1100_NR_IRQS,
.init_irq = sa1100_init_irq, .init_irq = sa1100_init_irq,
.timer = &sa1100_timer, .timer = &sa1100_timer,
.init_machine = h3600_mach_init, .init_machine = h3600_mach_init,
......
...@@ -109,11 +109,8 @@ static struct flash_platform_data h3xxx_flash_data = { ...@@ -109,11 +109,8 @@ static struct flash_platform_data h3xxx_flash_data = {
.nr_parts = ARRAY_SIZE(h3xxx_partitions), .nr_parts = ARRAY_SIZE(h3xxx_partitions),
}; };
static struct resource h3xxx_flash_resource = { static struct resource h3xxx_flash_resource =
.start = SA1100_CS0_PHYS, DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_32M);
.end = SA1100_CS0_PHYS + SZ_32M - 1,
.flags = IORESOURCE_MEM,
};
/* /*
...@@ -186,11 +183,7 @@ static struct sa1100_port_fns h3xxx_port_fns __initdata = { ...@@ -186,11 +183,7 @@ static struct sa1100_port_fns h3xxx_port_fns __initdata = {
*/ */
static struct resource egpio_resources[] = { static struct resource egpio_resources[] = {
[0] = { [0] = DEFINE_RES_MEM(H3600_EGPIO_PHYS, 0x4),
.start = H3600_EGPIO_PHYS,
.end = H3600_EGPIO_PHYS + 0x4 - 1,
.flags = IORESOURCE_MEM,
},
}; };
static struct htc_egpio_chip egpio_chips[] = { static struct htc_egpio_chip egpio_chips[] = {
......
...@@ -22,12 +22,10 @@ ...@@ -22,12 +22,10 @@
#include <linux/mtd/mtd.h> #include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h> #include <linux/mtd/partitions.h>
#include <mach/hardware.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
#include <asm/setup.h> #include <asm/setup.h>
#include <asm/page.h> #include <asm/page.h>
#include <asm/pgtable.h> #include <asm/pgtable.h>
#include <asm/irq.h>
#include <asm/mach/arch.h> #include <asm/mach/arch.h>
#include <asm/mach/flash.h> #include <asm/mach/flash.h>
...@@ -35,6 +33,9 @@ ...@@ -35,6 +33,9 @@
#include <asm/mach/irq.h> #include <asm/mach/irq.h>
#include <asm/mach/serial_sa1100.h> #include <asm/mach/serial_sa1100.h>
#include <mach/hardware.h>
#include <mach/irqs.h>
#include "generic.h" #include "generic.h"
/********************************************************************** /**********************************************************************
...@@ -179,11 +180,8 @@ static struct flash_platform_data hackkit_flash_data = { ...@@ -179,11 +180,8 @@ static struct flash_platform_data hackkit_flash_data = {
.nr_parts = ARRAY_SIZE(hackkit_partitions), .nr_parts = ARRAY_SIZE(hackkit_partitions),
}; };
static struct resource hackkit_flash_resource = { static struct resource hackkit_flash_resource =
.start = SA1100_CS0_PHYS, DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_32M);
.end = SA1100_CS0_PHYS + SZ_32M,
.flags = IORESOURCE_MEM,
};
static void __init hackkit_init(void) static void __init hackkit_init(void)
{ {
...@@ -197,6 +195,7 @@ static void __init hackkit_init(void) ...@@ -197,6 +195,7 @@ static void __init hackkit_init(void)
MACHINE_START(HACKKIT, "HackKit Cpu Board") MACHINE_START(HACKKIT, "HackKit Cpu Board")
.atag_offset = 0x100, .atag_offset = 0x100,
.map_io = hackkit_map_io, .map_io = hackkit_map_io,
.nr_irqs = SA1100_NR_IRQS,
.init_irq = sa1100_init_irq, .init_irq = sa1100_init_irq,
.timer = &sa1100_timer, .timer = &sa1100_timer,
.init_machine = hackkit_init, .init_machine = hackkit_init,
......
...@@ -1590,224 +1590,9 @@ ...@@ -1590,224 +1590,9 @@
/* /*
* Direct Memory Access (DMA) control registers * Direct Memory Access (DMA) control registers
*
* Registers
* DDAR0 Direct Memory Access (DMA) Device Address Register
* channel 0 (read/write).
* DCSR0 Direct Memory Access (DMA) Control and Status
* Register channel 0 (read/write).
* DBSA0 Direct Memory Access (DMA) Buffer Start address
* register A channel 0 (read/write).
* DBTA0 Direct Memory Access (DMA) Buffer Transfer count
* register A channel 0 (read/write).
* DBSB0 Direct Memory Access (DMA) Buffer Start address
* register B channel 0 (read/write).
* DBTB0 Direct Memory Access (DMA) Buffer Transfer count
* register B channel 0 (read/write).
*
* DDAR1 Direct Memory Access (DMA) Device Address Register
* channel 1 (read/write).
* DCSR1 Direct Memory Access (DMA) Control and Status
* Register channel 1 (read/write).
* DBSA1 Direct Memory Access (DMA) Buffer Start address
* register A channel 1 (read/write).
* DBTA1 Direct Memory Access (DMA) Buffer Transfer count
* register A channel 1 (read/write).
* DBSB1 Direct Memory Access (DMA) Buffer Start address
* register B channel 1 (read/write).
* DBTB1 Direct Memory Access (DMA) Buffer Transfer count
* register B channel 1 (read/write).
*
* DDAR2 Direct Memory Access (DMA) Device Address Register
* channel 2 (read/write).
* DCSR2 Direct Memory Access (DMA) Control and Status
* Register channel 2 (read/write).
* DBSA2 Direct Memory Access (DMA) Buffer Start address
* register A channel 2 (read/write).
* DBTA2 Direct Memory Access (DMA) Buffer Transfer count
* register A channel 2 (read/write).
* DBSB2 Direct Memory Access (DMA) Buffer Start address
* register B channel 2 (read/write).
* DBTB2 Direct Memory Access (DMA) Buffer Transfer count
* register B channel 2 (read/write).
*
* DDAR3 Direct Memory Access (DMA) Device Address Register
* channel 3 (read/write).
* DCSR3 Direct Memory Access (DMA) Control and Status
* Register channel 3 (read/write).
* DBSA3 Direct Memory Access (DMA) Buffer Start address
* register A channel 3 (read/write).
* DBTA3 Direct Memory Access (DMA) Buffer Transfer count
* register A channel 3 (read/write).
* DBSB3 Direct Memory Access (DMA) Buffer Start address
* register B channel 3 (read/write).
* DBTB3 Direct Memory Access (DMA) Buffer Transfer count
* register B channel 3 (read/write).
*
* DDAR4 Direct Memory Access (DMA) Device Address Register
* channel 4 (read/write).
* DCSR4 Direct Memory Access (DMA) Control and Status
* Register channel 4 (read/write).
* DBSA4 Direct Memory Access (DMA) Buffer Start address
* register A channel 4 (read/write).
* DBTA4 Direct Memory Access (DMA) Buffer Transfer count
* register A channel 4 (read/write).
* DBSB4 Direct Memory Access (DMA) Buffer Start address
* register B channel 4 (read/write).
* DBTB4 Direct Memory Access (DMA) Buffer Transfer count
* register B channel 4 (read/write).
*
* DDAR5 Direct Memory Access (DMA) Device Address Register
* channel 5 (read/write).
* DCSR5 Direct Memory Access (DMA) Control and Status
* Register channel 5 (read/write).
* DBSA5 Direct Memory Access (DMA) Buffer Start address
* register A channel 5 (read/write).
* DBTA5 Direct Memory Access (DMA) Buffer Transfer count
* register A channel 5 (read/write).
* DBSB5 Direct Memory Access (DMA) Buffer Start address
* register B channel 5 (read/write).
* DBTB5 Direct Memory Access (DMA) Buffer Transfer count
* register B channel 5 (read/write).
*/ */
#define DMA_SIZE (6 * 0x20)
#define DMASp 0x00000020 /* DMA control reg. Space [byte] */ #define DMA_PHYS 0xb0000000
#define DDAR(Nb) __REG(0xB0000000 + (Nb)*DMASp) /* DMA Device Address Reg. channel [0..5] */
#define SetDCSR(Nb) __REG(0xB0000004 + (Nb)*DMASp) /* Set DMA Control & Status Reg. channel [0..5] (write) */
#define ClrDCSR(Nb) __REG(0xB0000008 + (Nb)*DMASp) /* Clear DMA Control & Status Reg. channel [0..5] (write) */
#define RdDCSR(Nb) __REG(0xB000000C + (Nb)*DMASp) /* Read DMA Control & Status Reg. channel [0..5] (read) */
#define DBSA(Nb) __REG(0xB0000010 + (Nb)*DMASp) /* DMA Buffer Start address reg. A channel [0..5] */
#define DBTA(Nb) __REG(0xB0000014 + (Nb)*DMASp) /* DMA Buffer Transfer count reg. A channel [0..5] */
#define DBSB(Nb) __REG(0xB0000018 + (Nb)*DMASp) /* DMA Buffer Start address reg. B channel [0..5] */
#define DBTB(Nb) __REG(0xB000001C + (Nb)*DMASp) /* DMA Buffer Transfer count reg. B channel [0..5] */
#define DDAR_RW 0x00000001 /* device data Read/Write */
#define DDAR_DevWr (DDAR_RW*0) /* Device data Write */
/* (memory -> device) */
#define DDAR_DevRd (DDAR_RW*1) /* Device data Read */
/* (device -> memory) */
#define DDAR_E 0x00000002 /* big/little Endian device */
#define DDAR_LtlEnd (DDAR_E*0) /* Little Endian device */
#define DDAR_BigEnd (DDAR_E*1) /* Big Endian device */
#define DDAR_BS 0x00000004 /* device Burst Size */
#define DDAR_Brst4 (DDAR_BS*0) /* Burst-of-4 device */
#define DDAR_Brst8 (DDAR_BS*1) /* Burst-of-8 device */
#define DDAR_DW 0x00000008 /* device Data Width */
#define DDAR_8BitDev (DDAR_DW*0) /* 8-Bit Device */
#define DDAR_16BitDev (DDAR_DW*1) /* 16-Bit Device */
#define DDAR_DS Fld (4, 4) /* Device Select */
#define DDAR_Ser0UDCTr /* Ser. port 0 UDC Transmit */ \
(0x0 << FShft (DDAR_DS))
#define DDAR_Ser0UDCRc /* Ser. port 0 UDC Receive */ \
(0x1 << FShft (DDAR_DS))
#define DDAR_Ser1SDLCTr /* Ser. port 1 SDLC Transmit */ \
(0x2 << FShft (DDAR_DS))
#define DDAR_Ser1SDLCRc /* Ser. port 1 SDLC Receive */ \
(0x3 << FShft (DDAR_DS))
#define DDAR_Ser1UARTTr /* Ser. port 1 UART Transmit */ \
(0x4 << FShft (DDAR_DS))
#define DDAR_Ser1UARTRc /* Ser. port 1 UART Receive */ \
(0x5 << FShft (DDAR_DS))
#define DDAR_Ser2ICPTr /* Ser. port 2 ICP Transmit */ \
(0x6 << FShft (DDAR_DS))
#define DDAR_Ser2ICPRc /* Ser. port 2 ICP Receive */ \
(0x7 << FShft (DDAR_DS))
#define DDAR_Ser3UARTTr /* Ser. port 3 UART Transmit */ \
(0x8 << FShft (DDAR_DS))
#define DDAR_Ser3UARTRc /* Ser. port 3 UART Receive */ \
(0x9 << FShft (DDAR_DS))
#define DDAR_Ser4MCP0Tr /* Ser. port 4 MCP 0 Transmit */ \
/* (audio) */ \
(0xA << FShft (DDAR_DS))
#define DDAR_Ser4MCP0Rc /* Ser. port 4 MCP 0 Receive */ \
/* (audio) */ \
(0xB << FShft (DDAR_DS))
#define DDAR_Ser4MCP1Tr /* Ser. port 4 MCP 1 Transmit */ \
/* (telecom) */ \
(0xC << FShft (DDAR_DS))
#define DDAR_Ser4MCP1Rc /* Ser. port 4 MCP 1 Receive */ \
/* (telecom) */ \
(0xD << FShft (DDAR_DS))
#define DDAR_Ser4SSPTr /* Ser. port 4 SSP Transmit */ \
(0xE << FShft (DDAR_DS))
#define DDAR_Ser4SSPRc /* Ser. port 4 SSP Receive */ \
(0xF << FShft (DDAR_DS))
#define DDAR_DA Fld (24, 8) /* Device Address */
#define DDAR_DevAdd(Add) /* Device Address */ \
(((Add) & 0xF0000000) | \
(((Add) & 0X003FFFFC) << (FShft (DDAR_DA) - 2)))
#define DDAR_Ser0UDCWr /* Ser. port 0 UDC Write */ \
(DDAR_DevWr + DDAR_Brst8 + DDAR_8BitDev + \
DDAR_Ser0UDCTr + DDAR_DevAdd (__PREG(Ser0UDCDR)))
#define DDAR_Ser0UDCRd /* Ser. port 0 UDC Read */ \
(DDAR_DevRd + DDAR_Brst8 + DDAR_8BitDev + \
DDAR_Ser0UDCRc + DDAR_DevAdd (__PREG(Ser0UDCDR)))
#define DDAR_Ser1UARTWr /* Ser. port 1 UART Write */ \
(DDAR_DevWr + DDAR_Brst4 + DDAR_8BitDev + \
DDAR_Ser1UARTTr + DDAR_DevAdd (__PREG(Ser1UTDR)))
#define DDAR_Ser1UARTRd /* Ser. port 1 UART Read */ \
(DDAR_DevRd + DDAR_Brst4 + DDAR_8BitDev + \
DDAR_Ser1UARTRc + DDAR_DevAdd (__PREG(Ser1UTDR)))
#define DDAR_Ser1SDLCWr /* Ser. port 1 SDLC Write */ \
(DDAR_DevWr + DDAR_Brst4 + DDAR_8BitDev + \
DDAR_Ser1SDLCTr + DDAR_DevAdd (__PREG(Ser1SDDR)))
#define DDAR_Ser1SDLCRd /* Ser. port 1 SDLC Read */ \
(DDAR_DevRd + DDAR_Brst4 + DDAR_8BitDev + \
DDAR_Ser1SDLCRc + DDAR_DevAdd (__PREG(Ser1SDDR)))
#define DDAR_Ser2UARTWr /* Ser. port 2 UART Write */ \
(DDAR_DevWr + DDAR_Brst4 + DDAR_8BitDev + \
DDAR_Ser2ICPTr + DDAR_DevAdd (__PREG(Ser2UTDR)))
#define DDAR_Ser2UARTRd /* Ser. port 2 UART Read */ \
(DDAR_DevRd + DDAR_Brst4 + DDAR_8BitDev + \
DDAR_Ser2ICPRc + DDAR_DevAdd (__PREG(Ser2UTDR)))
#define DDAR_Ser2HSSPWr /* Ser. port 2 HSSP Write */ \
(DDAR_DevWr + DDAR_Brst8 + DDAR_8BitDev + \
DDAR_Ser2ICPTr + DDAR_DevAdd (__PREG(Ser2HSDR)))
#define DDAR_Ser2HSSPRd /* Ser. port 2 HSSP Read */ \
(DDAR_DevRd + DDAR_Brst8 + DDAR_8BitDev + \
DDAR_Ser2ICPRc + DDAR_DevAdd (__PREG(Ser2HSDR)))
#define DDAR_Ser3UARTWr /* Ser. port 3 UART Write */ \
(DDAR_DevWr + DDAR_Brst4 + DDAR_8BitDev + \
DDAR_Ser3UARTTr + DDAR_DevAdd (__PREG(Ser3UTDR)))
#define DDAR_Ser3UARTRd /* Ser. port 3 UART Read */ \
(DDAR_DevRd + DDAR_Brst4 + DDAR_8BitDev + \
DDAR_Ser3UARTRc + DDAR_DevAdd (__PREG(Ser3UTDR)))
#define DDAR_Ser4MCP0Wr /* Ser. port 4 MCP 0 Write (audio) */ \
(DDAR_DevWr + DDAR_Brst4 + DDAR_16BitDev + \
DDAR_Ser4MCP0Tr + DDAR_DevAdd (__PREG(Ser4MCDR0)))
#define DDAR_Ser4MCP0Rd /* Ser. port 4 MCP 0 Read (audio) */ \
(DDAR_DevRd + DDAR_Brst4 + DDAR_16BitDev + \
DDAR_Ser4MCP0Rc + DDAR_DevAdd (__PREG(Ser4MCDR0)))
#define DDAR_Ser4MCP1Wr /* Ser. port 4 MCP 1 Write */ \
/* (telecom) */ \
(DDAR_DevWr + DDAR_Brst4 + DDAR_16BitDev + \
DDAR_Ser4MCP1Tr + DDAR_DevAdd (__PREG(Ser4MCDR1)))
#define DDAR_Ser4MCP1Rd /* Ser. port 4 MCP 1 Read */ \
/* (telecom) */ \
(DDAR_DevRd + DDAR_Brst4 + DDAR_16BitDev + \
DDAR_Ser4MCP1Rc + DDAR_DevAdd (__PREG(Ser4MCDR1)))
#define DDAR_Ser4SSPWr /* Ser. port 4 SSP Write (16 bits) */ \
(DDAR_DevWr + DDAR_Brst4 + DDAR_16BitDev + \
DDAR_Ser4SSPTr + DDAR_DevAdd (__PREG(Ser4SSDR)))
#define DDAR_Ser4SSPRd /* Ser. port 4 SSP Read (16 bits) */ \
(DDAR_DevRd + DDAR_Brst4 + DDAR_16BitDev + \
DDAR_Ser4SSPRc + DDAR_DevAdd (__PREG(Ser4SSDR)))
#define DCSR_RUN 0x00000001 /* DMA running */
#define DCSR_IE 0x00000002 /* DMA Interrupt Enable */
#define DCSR_ERROR 0x00000004 /* DMA ERROR */
#define DCSR_DONEA 0x00000008 /* DONE DMA transfer buffer A */
#define DCSR_STRTA 0x00000010 /* STaRTed DMA transfer buffer A */
#define DCSR_DONEB 0x00000020 /* DONE DMA transfer buffer B */
#define DCSR_STRTB 0x00000040 /* STaRTed DMA transfer buffer B */
#define DCSR_BIU 0x00000080 /* DMA Buffer In Use */
#define DCSR_BufA (DCSR_BIU*0) /* DMA Buffer A in use */
#define DCSR_BufB (DCSR_BIU*1) /* DMA Buffer B in use */
#define DBT_TC Fld (13, 0) /* Transfer Count */
#define DBTA_TCA DBT_TC /* Transfer Count buffer A */
#define DBTB_TCB DBT_TC /* Transfer Count buffer B */
/* /*
...@@ -1903,16 +1688,6 @@ ...@@ -1903,16 +1688,6 @@
#define LCD_Int100_0A 0xF /* LCD Intensity = 100.0% = 1 */ #define LCD_Int100_0A 0xF /* LCD Intensity = 100.0% = 1 */
/* (Alternative) */ /* (Alternative) */
#define LCCR0 __REG(0xB0100000) /* LCD Control Reg. 0 */
#define LCSR __REG(0xB0100004) /* LCD Status Reg. */
#define DBAR1 __REG(0xB0100010) /* LCD DMA Base Address Reg. channel 1 */
#define DCAR1 __REG(0xB0100014) /* LCD DMA Current Address Reg. channel 1 */
#define DBAR2 __REG(0xB0100018) /* LCD DMA Base Address Reg. channel 2 */
#define DCAR2 __REG(0xB010001C) /* LCD DMA Current Address Reg. channel 2 */
#define LCCR1 __REG(0xB0100020) /* LCD Control Reg. 1 */
#define LCCR2 __REG(0xB0100024) /* LCD Control Reg. 2 */
#define LCCR3 __REG(0xB0100028) /* LCD Control Reg. 3 */
#define LCCR0_LEN 0x00000001 /* LCD ENable */ #define LCCR0_LEN 0x00000001 /* LCD ENable */
#define LCCR0_CMS 0x00000002 /* Color/Monochrome display Select */ #define LCCR0_CMS 0x00000002 /* Color/Monochrome display Select */
#define LCCR0_Color (LCCR0_CMS*0) /* Color display */ #define LCCR0_Color (LCCR0_CMS*0) /* Color display */
......
/*
* arch/arm/mach-sa1100/include/mach/dma.h
*
* Generic SA1100 DMA support
*
* Copyright (C) 2000 Nicolas Pitre
*
*/
#ifndef __ASM_ARCH_DMA_H
#define __ASM_ARCH_DMA_H
#include "hardware.h"
/*
* The SA1100 has six internal DMA channels.
*/
#define SA1100_DMA_CHANNELS 6
/*
* Maximum physical DMA buffer size
*/
#define MAX_DMA_SIZE 0x1fff
#define CUT_DMA_SIZE 0x1000
/*
* All possible SA1100 devices a DMA channel can be attached to.
*/
typedef enum {
DMA_Ser0UDCWr = DDAR_Ser0UDCWr, /* Ser. port 0 UDC Write */
DMA_Ser0UDCRd = DDAR_Ser0UDCRd, /* Ser. port 0 UDC Read */
DMA_Ser1UARTWr = DDAR_Ser1UARTWr, /* Ser. port 1 UART Write */
DMA_Ser1UARTRd = DDAR_Ser1UARTRd, /* Ser. port 1 UART Read */
DMA_Ser1SDLCWr = DDAR_Ser1SDLCWr, /* Ser. port 1 SDLC Write */
DMA_Ser1SDLCRd = DDAR_Ser1SDLCRd, /* Ser. port 1 SDLC Read */
DMA_Ser2UARTWr = DDAR_Ser2UARTWr, /* Ser. port 2 UART Write */
DMA_Ser2UARTRd = DDAR_Ser2UARTRd, /* Ser. port 2 UART Read */
DMA_Ser2HSSPWr = DDAR_Ser2HSSPWr, /* Ser. port 2 HSSP Write */
DMA_Ser2HSSPRd = DDAR_Ser2HSSPRd, /* Ser. port 2 HSSP Read */
DMA_Ser3UARTWr = DDAR_Ser3UARTWr, /* Ser. port 3 UART Write */
DMA_Ser3UARTRd = DDAR_Ser3UARTRd, /* Ser. port 3 UART Read */
DMA_Ser4MCP0Wr = DDAR_Ser4MCP0Wr, /* Ser. port 4 MCP 0 Write (audio) */
DMA_Ser4MCP0Rd = DDAR_Ser4MCP0Rd, /* Ser. port 4 MCP 0 Read (audio) */
DMA_Ser4MCP1Wr = DDAR_Ser4MCP1Wr, /* Ser. port 4 MCP 1 Write */
DMA_Ser4MCP1Rd = DDAR_Ser4MCP1Rd, /* Ser. port 4 MCP 1 Read */
DMA_Ser4SSPWr = DDAR_Ser4SSPWr, /* Ser. port 4 SSP Write (16 bits) */
DMA_Ser4SSPRd = DDAR_Ser4SSPRd /* Ser. port 4 SSP Read (16 bits) */
} dma_device_t;
typedef struct {
volatile u_long DDAR;
volatile u_long SetDCSR;
volatile u_long ClrDCSR;
volatile u_long RdDCSR;
volatile dma_addr_t DBSA;
volatile u_long DBTA;
volatile dma_addr_t DBSB;
volatile u_long DBTB;
} dma_regs_t;
typedef void (*dma_callback_t)(void *data);
/*
* DMA function prototypes
*/
extern int sa1100_request_dma( dma_device_t device, const char *device_id,
dma_callback_t callback, void *data,
dma_regs_t **regs );
extern void sa1100_free_dma( dma_regs_t *regs );
extern int sa1100_start_dma( dma_regs_t *regs, dma_addr_t dma_ptr, u_int size );
extern dma_addr_t sa1100_get_dma_pos(dma_regs_t *regs);
extern void sa1100_reset_dma(dma_regs_t *regs);
/**
* sa1100_stop_dma - stop DMA in progress
* @regs: identifier for the channel to use
*
* This stops DMA without clearing buffer pointers. Unlike
* sa1100_clear_dma() this allows subsequent use of sa1100_resume_dma()
* or sa1100_get_dma_pos().
*
* The @regs identifier is provided by a successful call to
* sa1100_request_dma().
**/
#define sa1100_stop_dma(regs) ((regs)->ClrDCSR = DCSR_IE|DCSR_RUN)
/**
* sa1100_resume_dma - resume DMA on a stopped channel
* @regs: identifier for the channel to use
*
* This resumes DMA on a channel previously stopped with
* sa1100_stop_dma().
*
* The @regs identifier is provided by a successful call to
* sa1100_request_dma().
**/
#define sa1100_resume_dma(regs) ((regs)->SetDCSR = DCSR_IE|DCSR_RUN)
/**
* sa1100_clear_dma - clear DMA pointers
* @regs: identifier for the channel to use
*
* This clear any DMA state so the DMA engine is ready to restart
* with new buffers through sa1100_start_dma(). Any buffers in flight
* are discarded.
*
* The @regs identifier is provided by a successful call to
* sa1100_request_dma().
**/
#define sa1100_clear_dma(regs) ((regs)->ClrDCSR = DCSR_IE|DCSR_RUN|DCSR_STRTA|DCSR_STRTB)
#endif /* _ASM_ARCH_DMA_H */
...@@ -71,22 +71,19 @@ ...@@ -71,22 +71,19 @@
/* /*
* Figure out the MAX IRQ number. * Figure out the MAX IRQ number.
* *
* If we have an SA1111, the max IRQ is S1_BVD1_STSCHG+1. * Neponset, SA1111 and UCB1x00 are sparse IRQ aware, so can dynamically
* If we have an LoCoMo, the max IRQ is IRQ_BOARD_START + 4 * allocate their IRQs above NR_IRQS.
* Otherwise, we have the standard IRQs only. *
* LoCoMo has 4 additional IRQs, but is not sparse IRQ aware, and so has
* to be included in the NR_IRQS calculation.
*/ */
#ifdef CONFIG_SA1111 #ifdef CONFIG_SHARP_LOCOMO
#define NR_IRQS (IRQ_BOARD_END + 55) #define NR_IRQS_LOCOMO 4
#elif defined(CONFIG_SHARP_LOCOMO)
#define NR_IRQS (IRQ_BOARD_START + 4)
#else #else
#define NR_IRQS (IRQ_BOARD_START) #define NR_IRQS_LOCOMO 0
#endif #endif
/* #ifndef NR_IRQS
* Board specific IRQs. Define them here. #define NR_IRQS (IRQ_BOARD_START + NR_IRQS_LOCOMO)
* Do not surround them with ifdefs. #endif
*/ #define SA1100_NR_IRQS (IRQ_BOARD_START + NR_IRQS_LOCOMO)
#define IRQ_NEPONSET_SMC9196 (IRQ_BOARD_START + 0)
#define IRQ_NEPONSET_USAR (IRQ_BOARD_START + 1)
#define IRQ_NEPONSET_SA1111 (IRQ_BOARD_START + 2)
...@@ -16,7 +16,7 @@ struct mcp_plat_data { ...@@ -16,7 +16,7 @@ struct mcp_plat_data {
u32 mccr0; u32 mccr0;
u32 mccr1; u32 mccr1;
unsigned int sclk_rate; unsigned int sclk_rate;
int gpio_base; void *codec_pdata;
}; };
#endif #endif
...@@ -15,54 +15,6 @@ ...@@ -15,54 +15,6 @@
/* /*
* Neponset definitions: * Neponset definitions:
*/ */
#define NEPONSET_CPLD_BASE (0x10000000)
#define Nep_p2v( x ) ((x) - NEPONSET_CPLD_BASE + 0xf3000000)
#define Nep_v2p( x ) ((x) - 0xf3000000 + NEPONSET_CPLD_BASE)
#define _IRR 0x10000024 /* Interrupt Reason Register */
#define _AUD_CTL 0x100000c0 /* Audio controls (RW) */
#define _MDM_CTL_0 0x100000b0 /* Modem control 0 (RW) */
#define _MDM_CTL_1 0x100000b4 /* Modem control 1 (RW) */
#define _NCR_0 0x100000a0 /* Control Register (RW) */
#define _KP_X_OUT 0x10000090 /* Keypad row write (RW) */
#define _KP_Y_IN 0x10000080 /* Keypad column read (RO) */
#define _SWPK 0x10000020 /* Switch pack (RO) */
#define _WHOAMI 0x10000000 /* System ID Register (RO) */
#define _LEDS 0x10000010 /* LEDs [31:0] (WO) */
#define IRR (*((volatile u_char *) Nep_p2v(_IRR)))
#define AUD_CTL (*((volatile u_char *) Nep_p2v(_AUD_CTL)))
#define MDM_CTL_0 (*((volatile u_char *) Nep_p2v(_MDM_CTL_0)))
#define MDM_CTL_1 (*((volatile u_char *) Nep_p2v(_MDM_CTL_1)))
#define NCR_0 (*((volatile u_char *) Nep_p2v(_NCR_0)))
#define KP_X_OUT (*((volatile u_char *) Nep_p2v(_KP_X_OUT)))
#define KP_Y_IN (*((volatile u_char *) Nep_p2v(_KP_Y_IN)))
#define SWPK (*((volatile u_char *) Nep_p2v(_SWPK)))
#define WHOAMI (*((volatile u_char *) Nep_p2v(_WHOAMI)))
#define LEDS (*((volatile Word *) Nep_p2v(_LEDS)))
#define IRR_ETHERNET (1<<0)
#define IRR_USAR (1<<1)
#define IRR_SA1111 (1<<2)
#define AUD_SEL_1341 (1<<0)
#define AUD_MUTE_1341 (1<<1)
#define MDM_CTL0_RTS1 (1 << 0)
#define MDM_CTL0_DTR1 (1 << 1)
#define MDM_CTL0_RTS2 (1 << 2)
#define MDM_CTL0_DTR2 (1 << 3)
#define MDM_CTL1_CTS1 (1 << 0)
#define MDM_CTL1_DSR1 (1 << 1)
#define MDM_CTL1_DCD1 (1 << 2)
#define MDM_CTL1_CTS2 (1 << 3)
#define MDM_CTL1_DSR2 (1 << 4)
#define MDM_CTL1_DCD2 (1 << 5)
#define NCR_GP01_OFF (1<<0) #define NCR_GP01_OFF (1<<0)
#define NCR_TP_PWR_EN (1<<1) #define NCR_TP_PWR_EN (1<<1)
#define NCR_MS_PWR_EN (1<<2) #define NCR_MS_PWR_EN (1<<2)
...@@ -71,4 +23,8 @@ ...@@ -71,4 +23,8 @@
#define NCR_A0VPP (1<<5) #define NCR_A0VPP (1<<5)
#define NCR_A1VPP (1<<6) #define NCR_A1VPP (1<<6)
void neponset_ncr_frob(unsigned int, unsigned int);
#define neponset_ncr_set(v) neponset_ncr_frob(0, v)
#define neponset_ncr_clear(v) neponset_ncr_frob(v, 0)
#endif #endif
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
#define SHANNON_GPIO_U3_RTS GPIO_GPIO (19) /* ?? */ #define SHANNON_GPIO_U3_RTS GPIO_GPIO (19) /* ?? */
#define SHANNON_GPIO_U3_CTS GPIO_GPIO (20) /* ?? */ #define SHANNON_GPIO_U3_CTS GPIO_GPIO (20) /* ?? */
#define SHANNON_GPIO_SENSE_12V GPIO_GPIO (21) /* Input, 12v flash unprotect detected */ #define SHANNON_GPIO_SENSE_12V GPIO_GPIO (21) /* Input, 12v flash unprotect detected */
#define SHANNON_GPIO_DISP_EN GPIO_GPIO (22) /* out */ #define SHANNON_GPIO_DISP_EN 22 /* out */
/* XXX GPIO 23 unaccounted for */ /* XXX GPIO 23 unaccounted for */
#define SHANNON_GPIO_EJECT_0 24 /* in */ #define SHANNON_GPIO_EJECT_0 24 /* in */
#define SHANNON_GPIO_EJECT_1 25 /* in */ #define SHANNON_GPIO_EJECT_1 25 /* in */
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include <linux/syscore_ops.h> #include <linux/syscore_ops.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <mach/irqs.h>
#include <asm/mach/irq.h> #include <asm/mach/irq.h>
#include "generic.h" #include "generic.h"
...@@ -221,11 +222,8 @@ static struct irq_chip sa1100_normal_chip = { ...@@ -221,11 +222,8 @@ static struct irq_chip sa1100_normal_chip = {
.irq_set_wake = sa1100_set_wake, .irq_set_wake = sa1100_set_wake,
}; };
static struct resource irq_resource = { static struct resource irq_resource =
.name = "irqs", DEFINE_RES_MEM_NAMED(0x90050000, SZ_64K, "irqs");
.start = 0x90050000,
.end = 0x9005ffff,
};
static struct sa1100irq_state { static struct sa1100irq_state {
unsigned int saved; unsigned int saved;
......
...@@ -23,9 +23,7 @@ ...@@ -23,9 +23,7 @@
#include <linux/mtd/partitions.h> #include <linux/mtd/partitions.h>
#include <video/s1d13xxxfb.h> #include <video/s1d13xxxfb.h>
#include <mach/hardware.h>
#include <asm/hardware/sa1111.h> #include <asm/hardware/sa1111.h>
#include <asm/irq.h>
#include <asm/page.h> #include <asm/page.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
#include <asm/setup.h> #include <asm/setup.h>
...@@ -34,6 +32,9 @@ ...@@ -34,6 +32,9 @@
#include <asm/mach/map.h> #include <asm/mach/map.h>
#include <asm/mach/serial_sa1100.h> #include <asm/mach/serial_sa1100.h>
#include <mach/hardware.h>
#include <mach/irqs.h>
#include "generic.h" #include "generic.h"
/* /*
...@@ -46,7 +47,7 @@ ...@@ -46,7 +47,7 @@
/* memory space (line 52 of HP's doc) */ /* memory space (line 52 of HP's doc) */
#define SA1111REGSTART 0x40000000 #define SA1111REGSTART 0x40000000
#define SA1111REGLEN 0x00001fff #define SA1111REGLEN 0x00002000
#define EPSONREGSTART 0x48000000 #define EPSONREGSTART 0x48000000
#define EPSONREGLEN 0x00100000 #define EPSONREGLEN 0x00100000
#define EPSONFBSTART 0x48200000 #define EPSONFBSTART 0x48200000
...@@ -174,16 +175,8 @@ static struct s1d13xxxfb_pdata s1d13xxxfb_data = { ...@@ -174,16 +175,8 @@ static struct s1d13xxxfb_pdata s1d13xxxfb_data = {
}; };
static struct resource s1d13xxxfb_resources[] = { static struct resource s1d13xxxfb_resources[] = {
[0] = { [0] = DEFINE_RES_MEM(EPSONFBSTART, EPSONFBLEN),
.start = EPSONFBSTART, [1] = DEFINE_RES_MEM(EPSONREGSTART, EPSONREGLEN),
.end = EPSONFBSTART + EPSONFBLEN,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = EPSONREGSTART,
.end = EPSONREGSTART + EPSONREGLEN,
.flags = IORESOURCE_MEM,
}
}; };
static struct platform_device s1d13xxxfb_device = { static struct platform_device s1d13xxxfb_device = {
...@@ -197,20 +190,12 @@ static struct platform_device s1d13xxxfb_device = { ...@@ -197,20 +190,12 @@ static struct platform_device s1d13xxxfb_device = {
}; };
static struct resource sa1111_resources[] = { static struct resource sa1111_resources[] = {
[0] = { [0] = DEFINE_RES_MEM(SA1111REGSTART, SA1111REGLEN),
.start = SA1111REGSTART, [1] = DEFINE_RES_IRQ(IRQ_GPIO1),
.end = SA1111REGSTART + SA1111REGLEN,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = IRQ_GPIO1,
.end = IRQ_GPIO1,
.flags = IORESOURCE_IRQ,
},
}; };
static struct sa1111_platform_data sa1111_info = { static struct sa1111_platform_data sa1111_info = {
.irq_base = IRQ_BOARD_END, .disable_devs = SA1111_DEVID_PS2_MSE,
}; };
static u64 sa1111_dmamask = 0xffffffffUL; static u64 sa1111_dmamask = 0xffffffffUL;
...@@ -284,11 +269,6 @@ static struct map_desc jornada720_io_desc[] __initdata = { ...@@ -284,11 +269,6 @@ static struct map_desc jornada720_io_desc[] __initdata = {
.pfn = __phys_to_pfn(EPSONFBSTART), .pfn = __phys_to_pfn(EPSONFBSTART),
.length = EPSONFBLEN, .length = EPSONFBLEN,
.type = MT_DEVICE .type = MT_DEVICE
}, { /* SA-1111 */
.virtual = 0xf4000000,
.pfn = __phys_to_pfn(SA1111REGSTART),
.length = SA1111REGLEN,
.type = MT_DEVICE
} }
}; };
...@@ -352,11 +332,8 @@ static struct flash_platform_data jornada720_flash_data = { ...@@ -352,11 +332,8 @@ static struct flash_platform_data jornada720_flash_data = {
.nr_parts = ARRAY_SIZE(jornada720_partitions), .nr_parts = ARRAY_SIZE(jornada720_partitions),
}; };
static struct resource jornada720_flash_resource = { static struct resource jornada720_flash_resource =
.start = SA1100_CS0_PHYS, DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_32M);
.end = SA1100_CS0_PHYS + SZ_32M - 1,
.flags = IORESOURCE_MEM,
};
static void __init jornada720_mach_init(void) static void __init jornada720_mach_init(void)
{ {
...@@ -367,6 +344,7 @@ MACHINE_START(JORNADA720, "HP Jornada 720") ...@@ -367,6 +344,7 @@ MACHINE_START(JORNADA720, "HP Jornada 720")
/* Maintainer: Kristoffer Ericson <Kristoffer.Ericson@gmail.com> */ /* Maintainer: Kristoffer Ericson <Kristoffer.Ericson@gmail.com> */
.atag_offset = 0x100, .atag_offset = 0x100,
.map_io = jornada720_map_io, .map_io = jornada720_map_io,
.nr_irqs = SA1100_NR_IRQS,
.init_irq = sa1100_init_irq, .init_irq = sa1100_init_irq,
.timer = &sa1100_timer, .timer = &sa1100_timer,
.init_machine = jornada720_mach_init, .init_machine = jornada720_mach_init,
......
...@@ -6,6 +6,8 @@ ...@@ -6,6 +6,8 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/tty.h> #include <linux/tty.h>
#include <video/sa1100fb.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <asm/setup.h> #include <asm/setup.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
...@@ -15,6 +17,7 @@ ...@@ -15,6 +17,7 @@
#include <asm/mach/map.h> #include <asm/mach/map.h>
#include <asm/mach/serial_sa1100.h> #include <asm/mach/serial_sa1100.h>
#include <mach/mcp.h> #include <mach/mcp.h>
#include <mach/irqs.h>
#include "generic.h" #include "generic.h"
...@@ -26,8 +29,86 @@ static struct mcp_plat_data lart_mcp_data = { ...@@ -26,8 +29,86 @@ static struct mcp_plat_data lart_mcp_data = {
.sclk_rate = 11981000, .sclk_rate = 11981000,
}; };
#ifdef LART_GREY_LCD
static struct sa1100fb_mach_info lart_grey_info = {
.pixclock = 150000, .bpp = 4,
.xres = 320, .yres = 240,
.hsync_len = 1, .vsync_len = 1,
.left_margin = 4, .upper_margin = 0,
.right_margin = 2, .lower_margin = 0,
.cmap_greyscale = 1,
.sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
.lccr0 = LCCR0_Mono | LCCR0_Sngl | LCCR0_Pas | LCCR0_4PixMono,
.lccr3 = LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(512),
};
#endif
#ifdef LART_COLOR_LCD
static struct sa1100fb_mach_info lart_color_info = {
.pixclock = 150000, .bpp = 16,
.xres = 320, .yres = 240,
.hsync_len = 2, .vsync_len = 3,
.left_margin = 69, .upper_margin = 14,
.right_margin = 8, .lower_margin = 4,
.lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
.lccr3 = LCCR3_OutEnH | LCCR3_PixFlEdg | LCCR3_ACBsDiv(512),
};
#endif
#ifdef LART_VIDEO_OUT
static struct sa1100fb_mach_info lart_video_info = {
.pixclock = 39721, .bpp = 16,
.xres = 640, .yres = 480,
.hsync_len = 95, .vsync_len = 2,
.left_margin = 40, .upper_margin = 32,
.right_margin = 24, .lower_margin = 11,
.sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
.lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
.lccr3 = LCCR3_OutEnL | LCCR3_PixFlEdg | LCCR3_ACBsDiv(512),
};
#endif
#ifdef LART_KIT01_LCD
static struct sa1100fb_mach_info lart_kit01_info = {
.pixclock = 63291, .bpp = 16,
.xres = 640, .yres = 480,
.hsync_len = 64, .vsync_len = 3,
.left_margin = 122, .upper_margin = 45,
.right_margin = 10, .lower_margin = 10,
.lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
.lccr3 = LCCR3_OutEnH | LCCR3_PixFlEdg
};
#endif
static void __init lart_init(void) static void __init lart_init(void)
{ {
struct sa1100fb_mach_info *inf = NULL;
#ifdef LART_GREY_LCD
inf = &lart_grey_info;
#endif
#ifdef LART_COLOR_LCD
inf = &lart_color_info;
#endif
#ifdef LART_VIDEO_OUT
inf = &lart_video_info;
#endif
#ifdef LART_KIT01_LCD
inf = &lart_kit01_info;
#endif
if (inf)
sa11x0_register_lcd(inf);
sa11x0_ppc_configure_mcp();
sa11x0_register_mcp(&lart_mcp_data); sa11x0_register_mcp(&lart_mcp_data);
} }
...@@ -63,6 +144,7 @@ static void __init lart_map_io(void) ...@@ -63,6 +144,7 @@ static void __init lart_map_io(void)
MACHINE_START(LART, "LART") MACHINE_START(LART, "LART")
.atag_offset = 0x100, .atag_offset = 0x100,
.map_io = lart_map_io, .map_io = lart_map_io,
.nr_irqs = SA1100_NR_IRQS,
.init_irq = sa1100_init_irq, .init_irq = sa1100_init_irq,
.init_machine = lart_init, .init_machine = lart_init,
.timer = &sa1100_timer, .timer = &sa1100_timer,
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include <mach/hardware.h> #include <mach/hardware.h>
#include <mach/nanoengine.h> #include <mach/nanoengine.h>
#include <mach/irqs.h>
#include "generic.h" #include "generic.h"
...@@ -58,15 +59,8 @@ static struct flash_platform_data nanoengine_flash_data = { ...@@ -58,15 +59,8 @@ static struct flash_platform_data nanoengine_flash_data = {
}; };
static struct resource nanoengine_flash_resources[] = { static struct resource nanoengine_flash_resources[] = {
{ DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_32M),
.start = SA1100_CS0_PHYS, DEFINE_RES_MEM(SA1100_CS1_PHYS, SZ_32M),
.end = SA1100_CS0_PHYS + SZ_32M - 1,
.flags = IORESOURCE_MEM,
}, {
.start = SA1100_CS1_PHYS,
.end = SA1100_CS1_PHYS + SZ_32M - 1,
.flags = IORESOURCE_MEM,
}
}; };
static struct map_desc nanoengine_io_desc[] __initdata = { static struct map_desc nanoengine_io_desc[] __initdata = {
...@@ -114,6 +108,7 @@ static void __init nanoengine_init(void) ...@@ -114,6 +108,7 @@ static void __init nanoengine_init(void)
MACHINE_START(NANOENGINE, "BSE nanoEngine") MACHINE_START(NANOENGINE, "BSE nanoEngine")
.atag_offset = 0x100, .atag_offset = 0x100,
.map_io = nanoengine_map_io, .map_io = nanoengine_map_io,
.nr_irqs = SA1100_NR_IRQS,
.init_irq = sa1100_init_irq, .init_irq = sa1100_init_irq,
.timer = &sa1100_timer, .timer = &sa1100_timer,
.init_machine = nanoengine_init, .init_machine = nanoengine_init,
......
/* /*
* linux/arch/arm/mach-sa1100/neponset.c * linux/arch/arm/mach-sa1100/neponset.c
*
*/ */
#include <linux/kernel.h> #include <linux/err.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/tty.h>
#include <linux/ioport.h> #include <linux/ioport.h>
#include <linux/serial_core.h> #include <linux/irq.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/pm.h>
#include <linux/serial_core.h>
#include <linux/slab.h>
#include <mach/hardware.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
#include <asm/irq.h>
#include <asm/mach/map.h> #include <asm/mach/map.h>
#include <asm/mach/irq.h>
#include <asm/mach/serial_sa1100.h> #include <asm/mach/serial_sa1100.h>
#include <mach/assabet.h>
#include <mach/neponset.h>
#include <asm/hardware/sa1111.h> #include <asm/hardware/sa1111.h>
#include <asm/sizes.h> #include <asm/sizes.h>
/* #include <mach/hardware.h>
* Install handler for Neponset IRQ. Note that we have to loop here #include <mach/assabet.h>
* since the ETHERNET and USAR IRQs are level based, and we need to #include <mach/neponset.h>
* ensure that the IRQ signal is deasserted before returning. This #include <mach/irqs.h>
* is rather unfortunate.
*/ #define NEP_IRQ_SMC91X 0
static void #define NEP_IRQ_USAR 1
neponset_irq_handler(unsigned int irq, struct irq_desc *desc) #define NEP_IRQ_SA1111 2
{ #define NEP_IRQ_NR 3
unsigned int irr;
#define WHOAMI 0x00
while (1) { #define LEDS 0x10
/* #define SWPK 0x20
* Acknowledge the parent IRQ. #define IRR 0x24
*/ #define KP_Y_IN 0x80
desc->irq_data.chip->irq_ack(&desc->irq_data); #define KP_X_OUT 0x90
#define NCR_0 0xa0
/* #define MDM_CTL_0 0xb0
* Read the interrupt reason register. Let's have all #define MDM_CTL_1 0xb4
* active IRQ bits high. Note: there is a typo in the #define AUD_CTL 0xc0
* Neponset user's guide for the SA1111 IRR level.
*/ #define IRR_ETHERNET (1 << 0)
irr = IRR ^ (IRR_ETHERNET | IRR_USAR); #define IRR_USAR (1 << 1)
#define IRR_SA1111 (1 << 2)
if ((irr & (IRR_ETHERNET | IRR_USAR | IRR_SA1111)) == 0)
break; #define MDM_CTL0_RTS1 (1 << 0)
#define MDM_CTL0_DTR1 (1 << 1)
/* #define MDM_CTL0_RTS2 (1 << 2)
* Since there is no individual mask, we have to #define MDM_CTL0_DTR2 (1 << 3)
* mask the parent IRQ. This is safe, since we'll
* recheck the register for any pending IRQs. #define MDM_CTL1_CTS1 (1 << 0)
*/ #define MDM_CTL1_DSR1 (1 << 1)
if (irr & (IRR_ETHERNET | IRR_USAR)) { #define MDM_CTL1_DCD1 (1 << 2)
desc->irq_data.chip->irq_mask(&desc->irq_data); #define MDM_CTL1_CTS2 (1 << 3)
#define MDM_CTL1_DSR2 (1 << 4)
/* #define MDM_CTL1_DCD2 (1 << 5)
* Ack the interrupt now to prevent re-entering
* this neponset handler. Again, this is safe #define AUD_SEL_1341 (1 << 0)
* since we'll check the IRR register prior to #define AUD_MUTE_1341 (1 << 1)
* leaving.
*/
desc->irq_data.chip->irq_ack(&desc->irq_data);
if (irr & IRR_ETHERNET) { extern void sa1110_mb_disable(void);
generic_handle_irq(IRQ_NEPONSET_SMC9196);
}
if (irr & IRR_USAR) { struct neponset_drvdata {
generic_handle_irq(IRQ_NEPONSET_USAR); void __iomem *base;
} struct platform_device *sa1111;
struct platform_device *smc91x;
unsigned irq_base;
#ifdef CONFIG_PM_SLEEP
u32 ncr0;
u32 mdm_ctl_0;
#endif
};
desc->irq_data.chip->irq_unmask(&desc->irq_data); static void __iomem *nep_base;
}
if (irr & IRR_SA1111) { void neponset_ncr_frob(unsigned int mask, unsigned int val)
generic_handle_irq(IRQ_NEPONSET_SA1111); {
} void __iomem *base = nep_base;
if (base) {
unsigned long flags;
unsigned v;
local_irq_save(flags);
v = readb_relaxed(base + NCR_0);
writeb_relaxed((v & ~mask) | val, base + NCR_0);
local_irq_restore(flags);
} else {
WARN(1, "nep_base unset\n");
} }
} }
static void neponset_set_mctrl(struct uart_port *port, u_int mctrl) static void neponset_set_mctrl(struct uart_port *port, u_int mctrl)
{ {
u_int mdm_ctl0 = MDM_CTL_0; void __iomem *base = nep_base;
u_int mdm_ctl0;
if (!base)
return;
mdm_ctl0 = readb_relaxed(base + MDM_CTL_0);
if (port->mapbase == _Ser1UTCR0) { if (port->mapbase == _Ser1UTCR0) {
if (mctrl & TIOCM_RTS) if (mctrl & TIOCM_RTS)
mdm_ctl0 &= ~MDM_CTL0_RTS2; mdm_ctl0 &= ~MDM_CTL0_RTS2;
...@@ -106,14 +121,19 @@ static void neponset_set_mctrl(struct uart_port *port, u_int mctrl) ...@@ -106,14 +121,19 @@ static void neponset_set_mctrl(struct uart_port *port, u_int mctrl)
mdm_ctl0 |= MDM_CTL0_DTR1; mdm_ctl0 |= MDM_CTL0_DTR1;
} }
MDM_CTL_0 = mdm_ctl0; writeb_relaxed(mdm_ctl0, base + MDM_CTL_0);
} }
static u_int neponset_get_mctrl(struct uart_port *port) static u_int neponset_get_mctrl(struct uart_port *port)
{ {
void __iomem *base = nep_base;
u_int ret = TIOCM_CD | TIOCM_CTS | TIOCM_DSR; u_int ret = TIOCM_CD | TIOCM_CTS | TIOCM_DSR;
u_int mdm_ctl1 = MDM_CTL_1; u_int mdm_ctl1;
if (!base)
return ret;
mdm_ctl1 = readb_relaxed(base + MDM_CTL_1);
if (port->mapbase == _Ser1UTCR0) { if (port->mapbase == _Ser1UTCR0) {
if (mdm_ctl1 & MDM_CTL1_DCD2) if (mdm_ctl1 & MDM_CTL1_DCD2)
ret &= ~TIOCM_CD; ret &= ~TIOCM_CD;
...@@ -138,209 +158,278 @@ static struct sa1100_port_fns neponset_port_fns __devinitdata = { ...@@ -138,209 +158,278 @@ static struct sa1100_port_fns neponset_port_fns __devinitdata = {
.get_mctrl = neponset_get_mctrl, .get_mctrl = neponset_get_mctrl,
}; };
static int __devinit neponset_probe(struct platform_device *dev) /*
* Install handler for Neponset IRQ. Note that we have to loop here
* since the ETHERNET and USAR IRQs are level based, and we need to
* ensure that the IRQ signal is deasserted before returning. This
* is rather unfortunate.
*/
static void neponset_irq_handler(unsigned int irq, struct irq_desc *desc)
{ {
sa1100_register_uart_fns(&neponset_port_fns); struct neponset_drvdata *d = irq_desc_get_handler_data(desc);
unsigned int irr;
/* while (1) {
* Install handler for GPIO25. /*
*/ * Acknowledge the parent IRQ.
irq_set_irq_type(IRQ_GPIO25, IRQ_TYPE_EDGE_RISING); */
irq_set_chained_handler(IRQ_GPIO25, neponset_irq_handler); desc->irq_data.chip->irq_ack(&desc->irq_data);
/* /*
* We would set IRQ_GPIO25 to be a wake-up IRQ, but * Read the interrupt reason register. Let's have all
* unfortunately something on the Neponset activates * active IRQ bits high. Note: there is a typo in the
* this IRQ on sleep (ethernet?) * Neponset user's guide for the SA1111 IRR level.
*/ */
#if 0 irr = readb_relaxed(d->base + IRR);
enable_irq_wake(IRQ_GPIO25); irr ^= IRR_ETHERNET | IRR_USAR;
#endif
/* if ((irr & (IRR_ETHERNET | IRR_USAR | IRR_SA1111)) == 0)
* Setup other Neponset IRQs. SA1111 will be done by the break;
* generic SA1111 code.
*/
irq_set_handler(IRQ_NEPONSET_SMC9196, handle_simple_irq);
set_irq_flags(IRQ_NEPONSET_SMC9196, IRQF_VALID | IRQF_PROBE);
irq_set_handler(IRQ_NEPONSET_USAR, handle_simple_irq);
set_irq_flags(IRQ_NEPONSET_USAR, IRQF_VALID | IRQF_PROBE);
/* /*
* Disable GPIO 0/1 drivers so the buttons work on the module. * Since there is no individual mask, we have to
*/ * mask the parent IRQ. This is safe, since we'll
NCR_0 = NCR_GP01_OFF; * recheck the register for any pending IRQs.
*/
if (irr & (IRR_ETHERNET | IRR_USAR)) {
desc->irq_data.chip->irq_mask(&desc->irq_data);
return 0; /*
} * Ack the interrupt now to prevent re-entering
* this neponset handler. Again, this is safe
* since we'll check the IRR register prior to
* leaving.
*/
desc->irq_data.chip->irq_ack(&desc->irq_data);
#ifdef CONFIG_PM if (irr & IRR_ETHERNET)
generic_handle_irq(d->irq_base + NEP_IRQ_SMC91X);
/* if (irr & IRR_USAR)
* LDM power management. generic_handle_irq(d->irq_base + NEP_IRQ_USAR);
*/
static unsigned int neponset_saved_state;
static int neponset_suspend(struct platform_device *dev, pm_message_t state) desc->irq_data.chip->irq_unmask(&desc->irq_data);
{ }
/*
* Save state.
*/
neponset_saved_state = NCR_0;
return 0; if (irr & IRR_SA1111)
generic_handle_irq(d->irq_base + NEP_IRQ_SA1111);
}
} }
static int neponset_resume(struct platform_device *dev) /* Yes, we really do not have any kind of masking or unmasking */
static void nochip_noop(struct irq_data *irq)
{ {
NCR_0 = neponset_saved_state;
return 0;
} }
#else static struct irq_chip nochip = {
#define neponset_suspend NULL .name = "neponset",
#define neponset_resume NULL .irq_ack = nochip_noop,
#endif .irq_mask = nochip_noop,
.irq_unmask = nochip_noop,
static struct platform_driver neponset_device_driver = {
.probe = neponset_probe,
.suspend = neponset_suspend,
.resume = neponset_resume,
.driver = {
.name = "neponset",
},
};
static struct resource neponset_resources[] = {
[0] = {
.start = 0x10000000,
.end = 0x17ffffff,
.flags = IORESOURCE_MEM,
},
};
static struct platform_device neponset_device = {
.name = "neponset",
.id = 0,
.num_resources = ARRAY_SIZE(neponset_resources),
.resource = neponset_resources,
};
static struct resource sa1111_resources[] = {
[0] = {
.start = 0x40000000,
.end = 0x40001fff,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = IRQ_NEPONSET_SA1111,
.end = IRQ_NEPONSET_SA1111,
.flags = IORESOURCE_IRQ,
},
}; };
static struct sa1111_platform_data sa1111_info = { static struct sa1111_platform_data sa1111_info = {
.irq_base = IRQ_BOARD_END, .disable_devs = SA1111_DEVID_PS2_MSE,
}; };
static u64 sa1111_dmamask = 0xffffffffUL; static int __devinit neponset_probe(struct platform_device *dev)
{
struct neponset_drvdata *d;
struct resource *nep_res, *sa1111_res, *smc91x_res;
struct resource sa1111_resources[] = {
DEFINE_RES_MEM(0x40000000, SZ_8K),
{ .flags = IORESOURCE_IRQ },
};
struct platform_device_info sa1111_devinfo = {
.parent = &dev->dev,
.name = "sa1111",
.id = 0,
.res = sa1111_resources,
.num_res = ARRAY_SIZE(sa1111_resources),
.data = &sa1111_info,
.size_data = sizeof(sa1111_info),
.dma_mask = 0xffffffffUL,
};
struct resource smc91x_resources[] = {
DEFINE_RES_MEM_NAMED(SA1100_CS3_PHYS,
0x02000000, "smc91x-regs"),
DEFINE_RES_MEM_NAMED(SA1100_CS3_PHYS + 0x02000000,
0x02000000, "smc91x-attrib"),
{ .flags = IORESOURCE_IRQ },
};
struct platform_device_info smc91x_devinfo = {
.parent = &dev->dev,
.name = "smc91x",
.id = 0,
.res = smc91x_resources,
.num_res = ARRAY_SIZE(smc91x_resources),
};
int ret, irq;
if (nep_base)
return -EBUSY;
irq = ret = platform_get_irq(dev, 0);
if (ret < 0)
goto err_alloc;
nep_res = platform_get_resource(dev, IORESOURCE_MEM, 0);
smc91x_res = platform_get_resource(dev, IORESOURCE_MEM, 1);
sa1111_res = platform_get_resource(dev, IORESOURCE_MEM, 2);
if (!nep_res || !smc91x_res || !sa1111_res) {
ret = -ENXIO;
goto err_alloc;
}
static struct platform_device sa1111_device = { d = kzalloc(sizeof(*d), GFP_KERNEL);
.name = "sa1111", if (!d) {
.id = 0, ret = -ENOMEM;
.dev = { goto err_alloc;
.dma_mask = &sa1111_dmamask, }
.coherent_dma_mask = 0xffffffff,
.platform_data = &sa1111_info,
},
.num_resources = ARRAY_SIZE(sa1111_resources),
.resource = sa1111_resources,
};
static struct resource smc91x_resources[] = { d->base = ioremap(nep_res->start, SZ_4K);
[0] = { if (!d->base) {
.name = "smc91x-regs", ret = -ENOMEM;
.start = SA1100_CS3_PHYS, goto err_ioremap;
.end = SA1100_CS3_PHYS + 0x01ffffff, }
.flags = IORESOURCE_MEM,
},
[1] = {
.start = IRQ_NEPONSET_SMC9196,
.end = IRQ_NEPONSET_SMC9196,
.flags = IORESOURCE_IRQ,
},
[2] = {
.name = "smc91x-attrib",
.start = SA1100_CS3_PHYS + 0x02000000,
.end = SA1100_CS3_PHYS + 0x03ffffff,
.flags = IORESOURCE_MEM,
},
};
static struct platform_device smc91x_device = { if (readb_relaxed(d->base + WHOAMI) != 0x11) {
.name = "smc91x", dev_warn(&dev->dev, "Neponset board detected, but wrong ID: %02x\n",
.id = 0, readb_relaxed(d->base + WHOAMI));
.num_resources = ARRAY_SIZE(smc91x_resources), ret = -ENODEV;
.resource = smc91x_resources, goto err_id;
}; }
static struct platform_device *devices[] __initdata = { ret = irq_alloc_descs(-1, IRQ_BOARD_START, NEP_IRQ_NR, -1);
&neponset_device, if (ret <= 0) {
&sa1111_device, dev_err(&dev->dev, "unable to allocate %u irqs: %d\n",
&smc91x_device, NEP_IRQ_NR, ret);
}; if (ret == 0)
ret = -ENOMEM;
goto err_irq_alloc;
}
extern void sa1110_mb_disable(void); d->irq_base = ret;
static int __init neponset_init(void) irq_set_chip_and_handler(d->irq_base + NEP_IRQ_SMC91X, &nochip,
{ handle_simple_irq);
platform_driver_register(&neponset_device_driver); set_irq_flags(d->irq_base + NEP_IRQ_SMC91X, IRQF_VALID | IRQF_PROBE);
irq_set_chip_and_handler(d->irq_base + NEP_IRQ_USAR, &nochip,
handle_simple_irq);
set_irq_flags(d->irq_base + NEP_IRQ_USAR, IRQF_VALID | IRQF_PROBE);
irq_set_chip(d->irq_base + NEP_IRQ_SA1111, &nochip);
/* irq_set_irq_type(irq, IRQ_TYPE_EDGE_RISING);
* The Neponset is only present on the Assabet machine type. irq_set_handler_data(irq, d);
*/ irq_set_chained_handler(irq, neponset_irq_handler);
if (!machine_is_assabet())
return -ENODEV;
/* /*
* Ensure that the memory bus request/grant signals are setup, * We would set IRQ_GPIO25 to be a wake-up IRQ, but unfortunately
* and the grant is held in its inactive state, whether or not * something on the Neponset activates this IRQ on sleep (eth?)
* we actually have a Neponset attached.
*/ */
#if 0
enable_irq_wake(irq);
#endif
dev_info(&dev->dev, "Neponset daughter board, providing IRQ%u-%u\n",
d->irq_base, d->irq_base + NEP_IRQ_NR - 1);
nep_base = d->base;
sa1100_register_uart_fns(&neponset_port_fns);
/* Ensure that the memory bus request/grant signals are setup */
sa1110_mb_disable(); sa1110_mb_disable();
if (!machine_has_neponset()) { /* Disable GPIO 0/1 drivers so the buttons work on the Assabet */
printk(KERN_DEBUG "Neponset expansion board not present\n"); writeb_relaxed(NCR_GP01_OFF, d->base + NCR_0);
return -ENODEV;
}
if (WHOAMI != 0x11) { sa1111_resources[0].parent = sa1111_res;
printk(KERN_WARNING "Neponset board detected, but " sa1111_resources[1].start = d->irq_base + NEP_IRQ_SA1111;
"wrong ID: %02x\n", WHOAMI); sa1111_resources[1].end = d->irq_base + NEP_IRQ_SA1111;
return -ENODEV; d->sa1111 = platform_device_register_full(&sa1111_devinfo);
}
smc91x_resources[0].parent = smc91x_res;
smc91x_resources[1].parent = smc91x_res;
smc91x_resources[2].start = d->irq_base + NEP_IRQ_SMC91X;
smc91x_resources[2].end = d->irq_base + NEP_IRQ_SMC91X;
d->smc91x = platform_device_register_full(&smc91x_devinfo);
platform_set_drvdata(dev, d);
return platform_add_devices(devices, ARRAY_SIZE(devices)); return 0;
err_irq_alloc:
err_id:
iounmap(d->base);
err_ioremap:
kfree(d);
err_alloc:
return ret;
} }
subsys_initcall(neponset_init); static int __devexit neponset_remove(struct platform_device *dev)
{
struct neponset_drvdata *d = platform_get_drvdata(dev);
int irq = platform_get_irq(dev, 0);
if (!IS_ERR(d->sa1111))
platform_device_unregister(d->sa1111);
if (!IS_ERR(d->smc91x))
platform_device_unregister(d->smc91x);
irq_set_chained_handler(irq, NULL);
irq_free_descs(d->irq_base, NEP_IRQ_NR);
nep_base = NULL;
iounmap(d->base);
kfree(d);
static struct map_desc neponset_io_desc[] __initdata = { return 0;
{ /* System Registers */ }
.virtual = 0xf3000000,
.pfn = __phys_to_pfn(0x10000000), #ifdef CONFIG_PM_SLEEP
.length = SZ_1M, static int neponset_suspend(struct device *dev)
.type = MT_DEVICE {
}, { /* SA-1111 */ struct neponset_drvdata *d = dev_get_drvdata(dev);
.virtual = 0xf4000000,
.pfn = __phys_to_pfn(0x40000000), d->ncr0 = readb_relaxed(d->base + NCR_0);
.length = SZ_1M, d->mdm_ctl_0 = readb_relaxed(d->base + MDM_CTL_0);
.type = MT_DEVICE
} return 0;
}
static int neponset_resume(struct device *dev)
{
struct neponset_drvdata *d = dev_get_drvdata(dev);
writeb_relaxed(d->ncr0, d->base + NCR_0);
writeb_relaxed(d->mdm_ctl_0, d->base + MDM_CTL_0);
return 0;
}
static const struct dev_pm_ops neponset_pm_ops = {
.suspend_noirq = neponset_suspend,
.resume_noirq = neponset_resume,
.freeze_noirq = neponset_suspend,
.restore_noirq = neponset_resume,
};
#define PM_OPS &neponset_pm_ops
#else
#define PM_OPS NULL
#endif
static struct platform_driver neponset_device_driver = {
.probe = neponset_probe,
.remove = __devexit_p(neponset_remove),
.driver = {
.name = "neponset",
.owner = THIS_MODULE,
.pm = PM_OPS,
},
}; };
void __init neponset_map_io(void) static int __init neponset_init(void)
{ {
iotable_init(neponset_io_desc, ARRAY_SIZE(neponset_io_desc)); return platform_driver_register(&neponset_device_driver);
} }
subsys_initcall(neponset_init);
...@@ -135,12 +135,8 @@ struct pci_bus * __init pci_nanoengine_scan_bus(int nr, struct pci_sys_data *sys ...@@ -135,12 +135,8 @@ struct pci_bus * __init pci_nanoengine_scan_bus(int nr, struct pci_sys_data *sys
&sys->resources); &sys->resources);
} }
static struct resource pci_io_ports = { static struct resource pci_io_ports =
.name = "PCI IO", DEFINE_RES_IO_NAMED(0x400, 0x400, "PCI IO");
.start = 0x400,
.end = 0x7FF,
.flags = IORESOURCE_IO,
};
static struct resource pci_non_prefetchable_memory = { static struct resource pci_non_prefetchable_memory = {
.name = "PCI non-prefetchable", .name = "PCI non-prefetchable",
......
...@@ -37,17 +37,9 @@ ...@@ -37,17 +37,9 @@
#define IRQ_GPIO_ETH0_IRQ IRQ_GPIO21 #define IRQ_GPIO_ETH0_IRQ IRQ_GPIO21
static struct resource smc91x_resources[] = { static struct resource smc91x_resources[] = {
[0] = { [0] = DEFINE_RES_MEM(PLEB_ETH0_P, 0x04000000),
.start = PLEB_ETH0_P,
.end = PLEB_ETH0_P | 0x03ffffff,
.flags = IORESOURCE_MEM,
},
#if 0 /* Autoprobe instead, to get rising/falling edge characteristic right */ #if 0 /* Autoprobe instead, to get rising/falling edge characteristic right */
[1] = { [1] = DEFINE_RES_IRQ(IRQ_GPIO_ETH0_IRQ),
.start = IRQ_GPIO_ETH0_IRQ,
.end = IRQ_GPIO_ETH0_IRQ,
.flags = IORESOURCE_IRQ,
},
#endif #endif
}; };
...@@ -70,16 +62,8 @@ static struct platform_device *devices[] __initdata = { ...@@ -70,16 +62,8 @@ static struct platform_device *devices[] __initdata = {
* the two SA1100 lowest chip select outputs. * the two SA1100 lowest chip select outputs.
*/ */
static struct resource pleb_flash_resources[] = { static struct resource pleb_flash_resources[] = {
[0] = { [0] = DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_8M),
.start = SA1100_CS0_PHYS, [1] = DEFINE_RES_MEM(SA1100_CS1_PHYS, SZ_8M),
.end = SA1100_CS0_PHYS + SZ_8M - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = SA1100_CS1_PHYS,
.end = SA1100_CS1_PHYS + SZ_8M - 1,
.flags = IORESOURCE_MEM,
}
}; };
...@@ -147,6 +131,7 @@ static void __init pleb_map_io(void) ...@@ -147,6 +131,7 @@ static void __init pleb_map_io(void)
MACHINE_START(PLEB, "PLEB") MACHINE_START(PLEB, "PLEB")
.map_io = pleb_map_io, .map_io = pleb_map_io,
.nr_irqs = SA1100_NR_IRQS,
.init_irq = sa1100_init_irq, .init_irq = sa1100_init_irq,
.timer = &sa1100_timer, .timer = &sa1100_timer,
.init_machine = pleb_init, .init_machine = pleb_init,
......
...@@ -9,6 +9,8 @@ ...@@ -9,6 +9,8 @@
#include <linux/mtd/mtd.h> #include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h> #include <linux/mtd/partitions.h>
#include <video/sa1100fb.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
#include <asm/setup.h> #include <asm/setup.h>
...@@ -19,6 +21,7 @@ ...@@ -19,6 +21,7 @@
#include <asm/mach/serial_sa1100.h> #include <asm/mach/serial_sa1100.h>
#include <mach/mcp.h> #include <mach/mcp.h>
#include <mach/shannon.h> #include <mach/shannon.h>
#include <mach/irqs.h>
#include "generic.h" #include "generic.h"
...@@ -46,19 +49,32 @@ static struct flash_platform_data shannon_flash_data = { ...@@ -46,19 +49,32 @@ static struct flash_platform_data shannon_flash_data = {
.nr_parts = ARRAY_SIZE(shannon_partitions), .nr_parts = ARRAY_SIZE(shannon_partitions),
}; };
static struct resource shannon_flash_resource = { static struct resource shannon_flash_resource =
.start = SA1100_CS0_PHYS, DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_4M);
.end = SA1100_CS0_PHYS + SZ_4M - 1,
.flags = IORESOURCE_MEM,
};
static struct mcp_plat_data shannon_mcp_data = { static struct mcp_plat_data shannon_mcp_data = {
.mccr0 = MCCR0_ADM, .mccr0 = MCCR0_ADM,
.sclk_rate = 11981000, .sclk_rate = 11981000,
}; };
static struct sa1100fb_mach_info shannon_lcd_info = {
.pixclock = 152500, .bpp = 8,
.xres = 640, .yres = 480,
.hsync_len = 4, .vsync_len = 3,
.left_margin = 2, .upper_margin = 0,
.right_margin = 1, .lower_margin = 0,
.sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
.lccr0 = LCCR0_Color | LCCR0_Dual | LCCR0_Pas,
.lccr3 = LCCR3_ACBsDiv(512),
};
static void __init shannon_init(void) static void __init shannon_init(void)
{ {
sa11x0_ppc_configure_mcp();
sa11x0_register_lcd(&shannon_lcd_info);
sa11x0_register_mtd(&shannon_flash_data, &shannon_flash_resource, 1); sa11x0_register_mtd(&shannon_flash_data, &shannon_flash_resource, 1);
sa11x0_register_mcp(&shannon_mcp_data); sa11x0_register_mcp(&shannon_mcp_data);
} }
...@@ -84,6 +100,7 @@ static void __init shannon_map_io(void) ...@@ -84,6 +100,7 @@ static void __init shannon_map_io(void)
MACHINE_START(SHANNON, "Shannon (AKA: Tuxscreen)") MACHINE_START(SHANNON, "Shannon (AKA: Tuxscreen)")
.atag_offset = 0x100, .atag_offset = 0x100,
.map_io = shannon_map_io, .map_io = shannon_map_io,
.nr_irqs = SA1100_NR_IRQS,
.init_irq = sa1100_init_irq, .init_irq = sa1100_init_irq,
.timer = &sa1100_timer, .timer = &sa1100_timer,
.init_machine = shannon_init, .init_machine = shannon_init,
......
...@@ -7,15 +7,15 @@ ...@@ -7,15 +7,15 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/tty.h> #include <linux/tty.h>
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/pm.h> #include <linux/pm.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/mfd/ucb1x00.h>
#include <linux/mtd/mtd.h> #include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h> #include <linux/mtd/partitions.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/gpio.h> #include <linux/gpio.h>
#include <asm/irq.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <asm/setup.h> #include <asm/setup.h>
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#include <asm/mach/serial_sa1100.h> #include <asm/mach/serial_sa1100.h>
#include <mach/mcp.h> #include <mach/mcp.h>
#include <mach/simpad.h> #include <mach/simpad.h>
#include <mach/irqs.h>
#include <linux/serial_core.h> #include <linux/serial_core.h>
#include <linux/ioport.h> #include <linux/ioport.h>
...@@ -176,21 +177,18 @@ static struct flash_platform_data simpad_flash_data = { ...@@ -176,21 +177,18 @@ static struct flash_platform_data simpad_flash_data = {
static struct resource simpad_flash_resources [] = { static struct resource simpad_flash_resources [] = {
{ DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_16M),
.start = SA1100_CS0_PHYS, DEFINE_RES_MEM(SA1100_CS1_PHYS, SZ_16M),
.end = SA1100_CS0_PHYS + SZ_16M -1, };
.flags = IORESOURCE_MEM,
}, { static struct ucb1x00_plat_data simpad_ucb1x00_data = {
.start = SA1100_CS1_PHYS, .gpio_base = SIMPAD_UCB1X00_GPIO_BASE,
.end = SA1100_CS1_PHYS + SZ_16M -1,
.flags = IORESOURCE_MEM,
}
}; };
static struct mcp_plat_data simpad_mcp_data = { static struct mcp_plat_data simpad_mcp_data = {
.mccr0 = MCCR0_ADM, .mccr0 = MCCR0_ADM,
.sclk_rate = 11981000, .sclk_rate = 11981000,
.gpio_base = SIMPAD_UCB1X00_GPIO_BASE, .codec_pdata = &simpad_ucb1x00_data,
}; };
...@@ -376,6 +374,7 @@ static int __init simpad_init(void) ...@@ -376,6 +374,7 @@ static int __init simpad_init(void)
pm_power_off = simpad_power_off; pm_power_off = simpad_power_off;
sa11x0_ppc_configure_mcp();
sa11x0_register_mtd(&simpad_flash_data, simpad_flash_resources, sa11x0_register_mtd(&simpad_flash_data, simpad_flash_resources,
ARRAY_SIZE(simpad_flash_resources)); ARRAY_SIZE(simpad_flash_resources));
sa11x0_register_mcp(&simpad_mcp_data); sa11x0_register_mcp(&simpad_mcp_data);
...@@ -394,6 +393,7 @@ MACHINE_START(SIMPAD, "Simpad") ...@@ -394,6 +393,7 @@ MACHINE_START(SIMPAD, "Simpad")
/* Maintainer: Holger Freyther */ /* Maintainer: Holger Freyther */
.atag_offset = 0x100, .atag_offset = 0x100,
.map_io = simpad_map_io, .map_io = simpad_map_io,
.nr_irqs = SA1100_NR_IRQS,
.init_irq = sa1100_init_irq, .init_irq = sa1100_init_irq,
.timer = &sa1100_timer, .timer = &sa1100_timer,
.restart = sa11x0_restart, .restart = sa11x0_restart,
......
...@@ -26,27 +26,36 @@ ...@@ -26,27 +26,36 @@
* *
* Causes sa11x0 to enter sleep state * Causes sa11x0 to enter sleep state
* *
* Must be aligned to a cacheline.
*/ */
.balign 32
ENTRY(sa1100_finish_suspend) ENTRY(sa1100_finish_suspend)
@ disable clock switching @ disable clock switching
mcr p15, 0, r1, c15, c2, 2 mcr p15, 0, r1, c15, c2, 2
@ Adjust memory timing before lowering CPU clock ldr r6, =MDREFR
@ Clock speed adjustment without changing memory timing makes ldr r4, [r6]
@ CPU hang in some cases orr r4, r4, #MDREFR_K1DB2
ldr r0, =MDREFR ldr r5, =PPCR
ldr r1, [r0]
orr r1, r1, #MDREFR_K1DB2 @ Pre-load __udelay into the I-cache
str r1, [r0] mov r0, #1
bl __udelay
mov r0, r0
@ The following must all exist in a single cache line to
@ avoid accessing memory until this sequence is complete,
@ otherwise we occasionally hang.
@ Adjust memory timing before lowering CPU clock
str r4, [r6]
@ delay 90us and set CPU PLL to lowest speed @ delay 90us and set CPU PLL to lowest speed
@ fixes resume problem on high speed SA1110 @ fixes resume problem on high speed SA1110
mov r0, #90 mov r0, #90
bl __udelay bl __udelay
ldr r0, =PPCR
mov r1, #0 mov r1, #0
str r1, [r0] str r1, [r5]
mov r0, #90 mov r0, #90
bl __udelay bl __udelay
...@@ -85,12 +94,10 @@ ENTRY(sa1100_finish_suspend) ...@@ -85,12 +94,10 @@ ENTRY(sa1100_finish_suspend)
bic r5, r5, #FMsk(MSC_RT) bic r5, r5, #FMsk(MSC_RT)
bic r5, r5, #FMsk(MSC_RT)<<16 bic r5, r5, #FMsk(MSC_RT)<<16
ldr r6, =MDREFR
ldr r7, [r6] ldr r7, [r6]
bic r7, r7, #0x0000FF00 bic r7, r7, #0x0000FF00
bic r7, r7, #0x000000F0 bic r7, r7, #0x000000F0
orr r8, r7, #MDREFR_SLFRSH orr r8, r7, #MDREFR_SLFRSH
ldr r9, =MDCNFG ldr r9, =MDCNFG
ldr r10, [r9] ldr r10, [r9]
......
...@@ -19,8 +19,8 @@ ...@@ -19,8 +19,8 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/io.h> #include <linux/io.h>
#include <asm/irq.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <mach/irqs.h>
#include <asm/hardware/ssp.h> #include <asm/hardware/ssp.h>
#define TIMEOUT 100000 #define TIMEOUT 100000
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include <asm/mach/time.h> #include <asm/mach/time.h>
#include <asm/sched_clock.h> #include <asm/sched_clock.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <mach/irqs.h>
static u32 notrace sa1100_read_sched_clock(void) static u32 notrace sa1100_read_sched_clock(void)
{ {
......
...@@ -252,6 +252,15 @@ config EP93XX_DMA ...@@ -252,6 +252,15 @@ config EP93XX_DMA
help help
Enable support for the Cirrus Logic EP93xx M2P/M2M DMA controller. Enable support for the Cirrus Logic EP93xx M2P/M2M DMA controller.
config DMA_SA11X0
tristate "SA-11x0 DMA support"
depends on ARCH_SA1100
select DMA_ENGINE
help
Support the DMA engine found on Intel StrongARM SA-1100 and
SA-1110 SoCs. This DMA engine can only be used with on-chip
devices.
config DMA_ENGINE config DMA_ENGINE
bool bool
......
...@@ -27,3 +27,4 @@ obj-$(CONFIG_PL330_DMA) += pl330.o ...@@ -27,3 +27,4 @@ obj-$(CONFIG_PL330_DMA) += pl330.o
obj-$(CONFIG_PCH_DMA) += pch_dma.o obj-$(CONFIG_PCH_DMA) += pch_dma.o
obj-$(CONFIG_AMBA_PL08X) += amba-pl08x.o obj-$(CONFIG_AMBA_PL08X) += amba-pl08x.o
obj-$(CONFIG_EP93XX_DMA) += ep93xx_dma.o obj-$(CONFIG_EP93XX_DMA) += ep93xx_dma.o
obj-$(CONFIG_DMA_SA11X0) += sa11x0-dma.o
此差异已折叠。
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <mach/irqs.h>
static int sa1100_gpio_get(struct gpio_chip *chip, unsigned offset) static int sa1100_gpio_get(struct gpio_chip *chip, unsigned offset)
{ {
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include <mach/jornada720.h> #include <mach/jornada720.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <mach/irqs.h>
MODULE_AUTHOR("Kristoffer Ericson <Kristoffer.Ericson@gmail.com>"); MODULE_AUTHOR("Kristoffer Ericson <Kristoffer.Ericson@gmail.com>");
MODULE_DESCRIPTION("HP Jornada 710/720/728 keyboard driver"); MODULE_DESCRIPTION("HP Jornada 710/720/728 keyboard driver");
......
...@@ -36,7 +36,6 @@ ...@@ -36,7 +36,6 @@
#include <linux/io.h> #include <linux/io.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <asm/irq.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <asm/hardware/iomd.h> #include <asm/hardware/iomd.h>
#include <asm/system.h> #include <asm/system.h>
...@@ -46,6 +45,11 @@ MODULE_DESCRIPTION("Acorn RiscPC PS/2 keyboard controller driver"); ...@@ -46,6 +45,11 @@ MODULE_DESCRIPTION("Acorn RiscPC PS/2 keyboard controller driver");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:kart"); MODULE_ALIAS("platform:kart");
struct rpckbd_data {
int tx_irq;
int rx_irq;
};
static int rpckbd_write(struct serio *port, unsigned char val) static int rpckbd_write(struct serio *port, unsigned char val)
{ {
while (!(iomd_readb(IOMD_KCTRL) & (1 << 7))) while (!(iomd_readb(IOMD_KCTRL) & (1 << 7)))
...@@ -78,19 +82,21 @@ static irqreturn_t rpckbd_tx(int irq, void *dev_id) ...@@ -78,19 +82,21 @@ static irqreturn_t rpckbd_tx(int irq, void *dev_id)
static int rpckbd_open(struct serio *port) static int rpckbd_open(struct serio *port)
{ {
struct rpckbd_data *rpckbd = port->port_data;
/* Reset the keyboard state machine. */ /* Reset the keyboard state machine. */
iomd_writeb(0, IOMD_KCTRL); iomd_writeb(0, IOMD_KCTRL);
iomd_writeb(8, IOMD_KCTRL); iomd_writeb(8, IOMD_KCTRL);
iomd_readb(IOMD_KARTRX); iomd_readb(IOMD_KARTRX);
if (request_irq(IRQ_KEYBOARDRX, rpckbd_rx, 0, "rpckbd", port) != 0) { if (request_irq(rpckbd->rx_irq, rpckbd_rx, 0, "rpckbd", port) != 0) {
printk(KERN_ERR "rpckbd.c: Could not allocate keyboard receive IRQ\n"); printk(KERN_ERR "rpckbd.c: Could not allocate keyboard receive IRQ\n");
return -EBUSY; return -EBUSY;
} }
if (request_irq(IRQ_KEYBOARDTX, rpckbd_tx, 0, "rpckbd", port) != 0) { if (request_irq(rpckbd->tx_irq, rpckbd_tx, 0, "rpckbd", port) != 0) {
printk(KERN_ERR "rpckbd.c: Could not allocate keyboard transmit IRQ\n"); printk(KERN_ERR "rpckbd.c: Could not allocate keyboard transmit IRQ\n");
free_irq(IRQ_KEYBOARDRX, port); free_irq(rpckbd->rx_irq, port);
return -EBUSY; return -EBUSY;
} }
...@@ -99,8 +105,10 @@ static int rpckbd_open(struct serio *port) ...@@ -99,8 +105,10 @@ static int rpckbd_open(struct serio *port)
static void rpckbd_close(struct serio *port) static void rpckbd_close(struct serio *port)
{ {
free_irq(IRQ_KEYBOARDRX, port); struct rpckbd_data *rpckbd = port->port_data;
free_irq(IRQ_KEYBOARDTX, port);
free_irq(rpckbd->rx_irq, port);
free_irq(rpckbd->tx_irq, port);
} }
/* /*
...@@ -109,17 +117,35 @@ static void rpckbd_close(struct serio *port) ...@@ -109,17 +117,35 @@ static void rpckbd_close(struct serio *port)
*/ */
static int __devinit rpckbd_probe(struct platform_device *dev) static int __devinit rpckbd_probe(struct platform_device *dev)
{ {
struct rpckbd_data *rpckbd;
struct serio *serio; struct serio *serio;
int tx_irq, rx_irq;
rx_irq = platform_get_irq(dev, 0);
if (rx_irq <= 0)
return rx_irq < 0 ? rx_irq : -ENXIO;
tx_irq = platform_get_irq(dev, 1);
if (tx_irq <= 0)
return tx_irq < 0 ? tx_irq : -ENXIO;
serio = kzalloc(sizeof(struct serio), GFP_KERNEL); serio = kzalloc(sizeof(struct serio), GFP_KERNEL);
if (!serio) rpckbd = kzalloc(sizeof(*rpckbd), GFP_KERNEL);
if (!serio || !rpckbd) {
kfree(rpckbd);
kfree(serio);
return -ENOMEM; return -ENOMEM;
}
rpckbd->rx_irq = rx_irq;
rpckbd->tx_irq = tx_irq;
serio->id.type = SERIO_8042; serio->id.type = SERIO_8042;
serio->write = rpckbd_write; serio->write = rpckbd_write;
serio->open = rpckbd_open; serio->open = rpckbd_open;
serio->close = rpckbd_close; serio->close = rpckbd_close;
serio->dev.parent = &dev->dev; serio->dev.parent = &dev->dev;
serio->port_data = rpckbd;
strlcpy(serio->name, "RiscPC PS/2 kbd port", sizeof(serio->name)); strlcpy(serio->name, "RiscPC PS/2 kbd port", sizeof(serio->name));
strlcpy(serio->phys, "rpckbd/serio0", sizeof(serio->phys)); strlcpy(serio->phys, "rpckbd/serio0", sizeof(serio->phys));
...@@ -131,7 +157,11 @@ static int __devinit rpckbd_probe(struct platform_device *dev) ...@@ -131,7 +157,11 @@ static int __devinit rpckbd_probe(struct platform_device *dev)
static int __devexit rpckbd_remove(struct platform_device *dev) static int __devexit rpckbd_remove(struct platform_device *dev)
{ {
struct serio *serio = platform_get_drvdata(dev); struct serio *serio = platform_get_drvdata(dev);
struct rpckbd_data *rpckbd = serio->port_data;
serio_unregister_port(serio); serio_unregister_port(serio);
kfree(rpckbd);
return 0; return 0;
} }
......
...@@ -24,6 +24,26 @@ ...@@ -24,6 +24,26 @@
#include <asm/hardware/sa1111.h> #include <asm/hardware/sa1111.h>
#define PS2CR 0x0000
#define PS2STAT 0x0004
#define PS2DATA 0x0008
#define PS2CLKDIV 0x000c
#define 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
struct ps2if { struct ps2if {
struct serio *io; struct serio *io;
struct sa1111_dev *dev; struct sa1111_dev *dev;
...@@ -45,22 +65,22 @@ static irqreturn_t ps2_rxint(int irq, void *dev_id) ...@@ -45,22 +65,22 @@ static irqreturn_t ps2_rxint(int irq, void *dev_id)
struct ps2if *ps2if = dev_id; struct ps2if *ps2if = dev_id;
unsigned int scancode, flag, status; unsigned int scancode, flag, status;
status = sa1111_readl(ps2if->base + SA1111_PS2STAT); status = sa1111_readl(ps2if->base + PS2STAT);
while (status & PS2STAT_RXF) { while (status & PS2STAT_RXF) {
if (status & PS2STAT_STP) if (status & PS2STAT_STP)
sa1111_writel(PS2STAT_STP, ps2if->base + SA1111_PS2STAT); sa1111_writel(PS2STAT_STP, ps2if->base + PS2STAT);
flag = (status & PS2STAT_STP ? SERIO_FRAME : 0) | flag = (status & PS2STAT_STP ? SERIO_FRAME : 0) |
(status & PS2STAT_RXP ? 0 : SERIO_PARITY); (status & PS2STAT_RXP ? 0 : SERIO_PARITY);
scancode = sa1111_readl(ps2if->base + SA1111_PS2DATA) & 0xff; scancode = sa1111_readl(ps2if->base + PS2DATA) & 0xff;
if (hweight8(scancode) & 1) if (hweight8(scancode) & 1)
flag ^= SERIO_PARITY; flag ^= SERIO_PARITY;
serio_interrupt(ps2if->io, scancode, flag); serio_interrupt(ps2if->io, scancode, flag);
status = sa1111_readl(ps2if->base + SA1111_PS2STAT); status = sa1111_readl(ps2if->base + PS2STAT);
} }
return IRQ_HANDLED; return IRQ_HANDLED;
...@@ -75,12 +95,12 @@ static irqreturn_t ps2_txint(int irq, void *dev_id) ...@@ -75,12 +95,12 @@ static irqreturn_t ps2_txint(int irq, void *dev_id)
unsigned int status; unsigned int status;
spin_lock(&ps2if->lock); spin_lock(&ps2if->lock);
status = sa1111_readl(ps2if->base + SA1111_PS2STAT); status = sa1111_readl(ps2if->base + PS2STAT);
if (ps2if->head == ps2if->tail) { if (ps2if->head == ps2if->tail) {
disable_irq_nosync(irq); disable_irq_nosync(irq);
/* done */ /* done */
} else if (status & PS2STAT_TXE) { } else if (status & PS2STAT_TXE) {
sa1111_writel(ps2if->buf[ps2if->tail], ps2if->base + SA1111_PS2DATA); sa1111_writel(ps2if->buf[ps2if->tail], ps2if->base + PS2DATA);
ps2if->tail = (ps2if->tail + 1) & (sizeof(ps2if->buf) - 1); ps2if->tail = (ps2if->tail + 1) & (sizeof(ps2if->buf) - 1);
} }
spin_unlock(&ps2if->lock); spin_unlock(&ps2if->lock);
...@@ -103,8 +123,8 @@ static int ps2_write(struct serio *io, unsigned char val) ...@@ -103,8 +123,8 @@ static int ps2_write(struct serio *io, unsigned char val)
/* /*
* If the TX register is empty, we can go straight out. * If the TX register is empty, we can go straight out.
*/ */
if (sa1111_readl(ps2if->base + SA1111_PS2STAT) & PS2STAT_TXE) { if (sa1111_readl(ps2if->base + PS2STAT) & PS2STAT_TXE) {
sa1111_writel(val, ps2if->base + SA1111_PS2DATA); sa1111_writel(val, ps2if->base + PS2DATA);
} else { } else {
if (ps2if->head == ps2if->tail) if (ps2if->head == ps2if->tail)
enable_irq(ps2if->dev->irq[1]); enable_irq(ps2if->dev->irq[1]);
...@@ -124,13 +144,16 @@ static int ps2_open(struct serio *io) ...@@ -124,13 +144,16 @@ static int ps2_open(struct serio *io)
struct ps2if *ps2if = io->port_data; struct ps2if *ps2if = io->port_data;
int ret; int ret;
sa1111_enable_device(ps2if->dev); ret = sa1111_enable_device(ps2if->dev);
if (ret)
return ret;
ret = request_irq(ps2if->dev->irq[0], ps2_rxint, 0, ret = request_irq(ps2if->dev->irq[0], ps2_rxint, 0,
SA1111_DRIVER_NAME(ps2if->dev), ps2if); SA1111_DRIVER_NAME(ps2if->dev), ps2if);
if (ret) { if (ret) {
printk(KERN_ERR "sa1111ps2: could not allocate IRQ%d: %d\n", printk(KERN_ERR "sa1111ps2: could not allocate IRQ%d: %d\n",
ps2if->dev->irq[0], ret); ps2if->dev->irq[0], ret);
sa1111_disable_device(ps2if->dev);
return ret; return ret;
} }
...@@ -140,6 +163,7 @@ static int ps2_open(struct serio *io) ...@@ -140,6 +163,7 @@ static int ps2_open(struct serio *io)
printk(KERN_ERR "sa1111ps2: could not allocate IRQ%d: %d\n", printk(KERN_ERR "sa1111ps2: could not allocate IRQ%d: %d\n",
ps2if->dev->irq[1], ret); ps2if->dev->irq[1], ret);
free_irq(ps2if->dev->irq[0], ps2if); free_irq(ps2if->dev->irq[0], ps2if);
sa1111_disable_device(ps2if->dev);
return ret; return ret;
} }
...@@ -147,7 +171,7 @@ static int ps2_open(struct serio *io) ...@@ -147,7 +171,7 @@ static int ps2_open(struct serio *io)
enable_irq_wake(ps2if->dev->irq[0]); enable_irq_wake(ps2if->dev->irq[0]);
sa1111_writel(PS2CR_ENA, ps2if->base + SA1111_PS2CR); sa1111_writel(PS2CR_ENA, ps2if->base + PS2CR);
return 0; return 0;
} }
...@@ -155,7 +179,7 @@ static void ps2_close(struct serio *io) ...@@ -155,7 +179,7 @@ static void ps2_close(struct serio *io)
{ {
struct ps2if *ps2if = io->port_data; struct ps2if *ps2if = io->port_data;
sa1111_writel(0, ps2if->base + SA1111_PS2CR); sa1111_writel(0, ps2if->base + PS2CR);
disable_irq_wake(ps2if->dev->irq[0]); disable_irq_wake(ps2if->dev->irq[0]);
...@@ -175,7 +199,7 @@ static void __devinit ps2_clear_input(struct ps2if *ps2if) ...@@ -175,7 +199,7 @@ static void __devinit ps2_clear_input(struct ps2if *ps2if)
int maxread = 100; int maxread = 100;
while (maxread--) { while (maxread--) {
if ((sa1111_readl(ps2if->base + SA1111_PS2DATA) & 0xff) == 0xff) if ((sa1111_readl(ps2if->base + PS2DATA) & 0xff) == 0xff)
break; break;
} }
} }
...@@ -185,11 +209,11 @@ static unsigned int __devinit ps2_test_one(struct ps2if *ps2if, ...@@ -185,11 +209,11 @@ static unsigned int __devinit ps2_test_one(struct ps2if *ps2if,
{ {
unsigned int val; unsigned int val;
sa1111_writel(PS2CR_ENA | mask, ps2if->base + SA1111_PS2CR); sa1111_writel(PS2CR_ENA | mask, ps2if->base + PS2CR);
udelay(2); udelay(2);
val = sa1111_readl(ps2if->base + SA1111_PS2STAT); val = sa1111_readl(ps2if->base + PS2STAT);
return val & (PS2STAT_KBC | PS2STAT_KBD); return val & (PS2STAT_KBC | PS2STAT_KBD);
} }
...@@ -220,7 +244,7 @@ static int __devinit ps2_test(struct ps2if *ps2if) ...@@ -220,7 +244,7 @@ static int __devinit ps2_test(struct ps2if *ps2if)
ret = -ENODEV; ret = -ENODEV;
} }
sa1111_writel(0, ps2if->base + SA1111_PS2CR); sa1111_writel(0, ps2if->base + PS2CR);
return ret; return ret;
} }
...@@ -274,8 +298,8 @@ static int __devinit ps2_probe(struct sa1111_dev *dev) ...@@ -274,8 +298,8 @@ static int __devinit ps2_probe(struct sa1111_dev *dev)
sa1111_enable_device(ps2if->dev); sa1111_enable_device(ps2if->dev);
/* Incoming clock is 8MHz */ /* Incoming clock is 8MHz */
sa1111_writel(0, ps2if->base + SA1111_PS2CLKDIV); sa1111_writel(0, ps2if->base + PS2CLKDIV);
sa1111_writel(127, ps2if->base + SA1111_PS2PRECNT); sa1111_writel(127, ps2if->base + PS2PRECNT);
/* /*
* Flush any pending input. * Flush any pending input.
...@@ -330,6 +354,7 @@ static int __devexit ps2_remove(struct sa1111_dev *dev) ...@@ -330,6 +354,7 @@ static int __devexit ps2_remove(struct sa1111_dev *dev)
static struct sa1111_driver ps2_driver = { static struct sa1111_driver ps2_driver = {
.drv = { .drv = {
.name = "sa1111-ps2", .name = "sa1111-ps2",
.owner = THIS_MODULE,
}, },
.devid = SA1111_DEVID_PS2, .devid = SA1111_DEVID_PS2,
.probe = ps2_probe, .probe = ps2_probe,
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include <mach/hardware.h> #include <mach/hardware.h>
#include <mach/jornada720.h> #include <mach/jornada720.h>
#include <mach/irqs.h>
MODULE_AUTHOR("Kristoffer Ericson <kristoffer.ericson@gmail.com>"); MODULE_AUTHOR("Kristoffer Ericson <kristoffer.ericson@gmail.com>");
MODULE_DESCRIPTION("HP Jornada 710/720/728 touchscreen driver"); MODULE_DESCRIPTION("HP Jornada 710/720/728 touchscreen driver");
......
...@@ -848,8 +848,9 @@ config MCP_SA11X0 ...@@ -848,8 +848,9 @@ config MCP_SA11X0
# Chip drivers # Chip drivers
config MCP_UCB1200 config MCP_UCB1200
tristate "Support for UCB1200 / UCB1300" bool "Support for UCB1200 / UCB1300"
depends on MCP depends on MCP_SA11X0
select MCP
config MCP_UCB1200_TS config MCP_UCB1200_TS
tristate "Touchscreen interface support" tristate "Touchscreen interface support"
......
...@@ -19,7 +19,6 @@ ...@@ -19,7 +19,6 @@
#include <linux/string.h> #include <linux/string.h>
#include <linux/mfd/mcp.h> #include <linux/mfd/mcp.h>
#include <mach/dma.h>
#include <asm/system.h> #include <asm/system.h>
...@@ -48,39 +47,11 @@ static int mcp_bus_remove(struct device *dev) ...@@ -48,39 +47,11 @@ static int mcp_bus_remove(struct device *dev)
return 0; return 0;
} }
static int mcp_bus_suspend(struct device *dev, pm_message_t state)
{
struct mcp *mcp = to_mcp(dev);
int ret = 0;
if (dev->driver) {
struct mcp_driver *drv = to_mcp_driver(dev->driver);
ret = drv->suspend(mcp, state);
}
return ret;
}
static int mcp_bus_resume(struct device *dev)
{
struct mcp *mcp = to_mcp(dev);
int ret = 0;
if (dev->driver) {
struct mcp_driver *drv = to_mcp_driver(dev->driver);
ret = drv->resume(mcp);
}
return ret;
}
static struct bus_type mcp_bus_type = { static struct bus_type mcp_bus_type = {
.name = "mcp", .name = "mcp",
.match = mcp_bus_match, .match = mcp_bus_match,
.probe = mcp_bus_probe, .probe = mcp_bus_probe,
.remove = mcp_bus_remove, .remove = mcp_bus_remove,
.suspend = mcp_bus_suspend,
.resume = mcp_bus_resume,
}; };
/** /**
...@@ -208,6 +179,7 @@ struct mcp *mcp_host_alloc(struct device *parent, size_t size) ...@@ -208,6 +179,7 @@ struct mcp *mcp_host_alloc(struct device *parent, size_t size)
mcp = kzalloc(sizeof(struct mcp) + size, GFP_KERNEL); mcp = kzalloc(sizeof(struct mcp) + size, GFP_KERNEL);
if (mcp) { if (mcp) {
spin_lock_init(&mcp->lock); spin_lock_init(&mcp->lock);
device_initialize(&mcp->attached_device);
mcp->attached_device.parent = parent; mcp->attached_device.parent = parent;
mcp->attached_device.bus = &mcp_bus_type; mcp->attached_device.bus = &mcp_bus_type;
mcp->attached_device.dma_mask = parent->dma_mask; mcp->attached_device.dma_mask = parent->dma_mask;
...@@ -217,18 +189,25 @@ struct mcp *mcp_host_alloc(struct device *parent, size_t size) ...@@ -217,18 +189,25 @@ struct mcp *mcp_host_alloc(struct device *parent, size_t size)
} }
EXPORT_SYMBOL(mcp_host_alloc); EXPORT_SYMBOL(mcp_host_alloc);
int mcp_host_register(struct mcp *mcp) int mcp_host_add(struct mcp *mcp, void *pdata)
{ {
mcp->attached_device.platform_data = pdata;
dev_set_name(&mcp->attached_device, "mcp0"); dev_set_name(&mcp->attached_device, "mcp0");
return device_register(&mcp->attached_device); return device_add(&mcp->attached_device);
}
EXPORT_SYMBOL(mcp_host_add);
void mcp_host_del(struct mcp *mcp)
{
device_del(&mcp->attached_device);
} }
EXPORT_SYMBOL(mcp_host_register); EXPORT_SYMBOL(mcp_host_del);
void mcp_host_unregister(struct mcp *mcp) void mcp_host_free(struct mcp *mcp)
{ {
device_unregister(&mcp->attached_device); put_device(&mcp->attached_device);
} }
EXPORT_SYMBOL(mcp_host_unregister); EXPORT_SYMBOL(mcp_host_free);
int mcp_driver_register(struct mcp_driver *mcpdrv) int mcp_driver_register(struct mcp_driver *mcpdrv)
{ {
......
...@@ -13,51 +13,61 @@ ...@@ -13,51 +13,61 @@
*/ */
#include <linux/module.h> #include <linux/module.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/io.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/pm.h>
#include <linux/mfd/mcp.h> #include <linux/mfd/mcp.h>
#include <mach/dma.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
#include <asm/system.h> #include <asm/system.h>
#include <mach/mcp.h> #include <mach/mcp.h>
#include <mach/assabet.h> #define DRIVER_NAME "sa11x0-mcp"
struct mcp_sa11x0 { struct mcp_sa11x0 {
u32 mccr0; void __iomem *base0;
u32 mccr1; void __iomem *base1;
u32 mccr0;
u32 mccr1;
}; };
/* Register offsets */
#define MCCR0(m) ((m)->base0 + 0x00)
#define MCDR0(m) ((m)->base0 + 0x08)
#define MCDR1(m) ((m)->base0 + 0x0c)
#define MCDR2(m) ((m)->base0 + 0x10)
#define MCSR(m) ((m)->base0 + 0x18)
#define MCCR1(m) ((m)->base1 + 0x00)
#define priv(mcp) ((struct mcp_sa11x0 *)mcp_priv(mcp)) #define priv(mcp) ((struct mcp_sa11x0 *)mcp_priv(mcp))
static void static void
mcp_sa11x0_set_telecom_divisor(struct mcp *mcp, unsigned int divisor) mcp_sa11x0_set_telecom_divisor(struct mcp *mcp, unsigned int divisor)
{ {
unsigned int mccr0; struct mcp_sa11x0 *m = priv(mcp);
divisor /= 32; divisor /= 32;
mccr0 = Ser4MCCR0 & ~0x00007f00; m->mccr0 &= ~0x00007f00;
mccr0 |= divisor << 8; m->mccr0 |= divisor << 8;
Ser4MCCR0 = mccr0; writel_relaxed(m->mccr0, MCCR0(m));
} }
static void static void
mcp_sa11x0_set_audio_divisor(struct mcp *mcp, unsigned int divisor) mcp_sa11x0_set_audio_divisor(struct mcp *mcp, unsigned int divisor)
{ {
unsigned int mccr0; struct mcp_sa11x0 *m = priv(mcp);
divisor /= 32; divisor /= 32;
mccr0 = Ser4MCCR0 & ~0x0000007f; m->mccr0 &= ~0x0000007f;
mccr0 |= divisor; m->mccr0 |= divisor;
Ser4MCCR0 = mccr0; writel_relaxed(m->mccr0, MCCR0(m));
} }
/* /*
...@@ -69,14 +79,15 @@ mcp_sa11x0_set_audio_divisor(struct mcp *mcp, unsigned int divisor) ...@@ -69,14 +79,15 @@ mcp_sa11x0_set_audio_divisor(struct mcp *mcp, unsigned int divisor)
static void static void
mcp_sa11x0_write(struct mcp *mcp, unsigned int reg, unsigned int val) mcp_sa11x0_write(struct mcp *mcp, unsigned int reg, unsigned int val)
{ {
struct mcp_sa11x0 *m = priv(mcp);
int ret = -ETIME; int ret = -ETIME;
int i; int i;
Ser4MCDR2 = reg << 17 | MCDR2_Wr | (val & 0xffff); writel_relaxed(reg << 17 | MCDR2_Wr | (val & 0xffff), MCDR2(m));
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
udelay(mcp->rw_timeout); udelay(mcp->rw_timeout);
if (Ser4MCSR & MCSR_CWC) { if (readl_relaxed(MCSR(m)) & MCSR_CWC) {
ret = 0; ret = 0;
break; break;
} }
...@@ -95,15 +106,16 @@ mcp_sa11x0_write(struct mcp *mcp, unsigned int reg, unsigned int val) ...@@ -95,15 +106,16 @@ mcp_sa11x0_write(struct mcp *mcp, unsigned int reg, unsigned int val)
static unsigned int static unsigned int
mcp_sa11x0_read(struct mcp *mcp, unsigned int reg) mcp_sa11x0_read(struct mcp *mcp, unsigned int reg)
{ {
struct mcp_sa11x0 *m = priv(mcp);
int ret = -ETIME; int ret = -ETIME;
int i; int i;
Ser4MCDR2 = reg << 17 | MCDR2_Rd; writel_relaxed(reg << 17 | MCDR2_Rd, MCDR2(m));
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
udelay(mcp->rw_timeout); udelay(mcp->rw_timeout);
if (Ser4MCSR & MCSR_CRC) { if (readl_relaxed(MCSR(m)) & MCSR_CRC) {
ret = Ser4MCDR2 & 0xffff; ret = readl_relaxed(MCDR2(m)) & 0xffff;
break; break;
} }
} }
...@@ -116,13 +128,19 @@ mcp_sa11x0_read(struct mcp *mcp, unsigned int reg) ...@@ -116,13 +128,19 @@ mcp_sa11x0_read(struct mcp *mcp, unsigned int reg)
static void mcp_sa11x0_enable(struct mcp *mcp) static void mcp_sa11x0_enable(struct mcp *mcp)
{ {
Ser4MCSR = -1; struct mcp_sa11x0 *m = priv(mcp);
Ser4MCCR0 |= MCCR0_MCE;
writel(-1, MCSR(m));
m->mccr0 |= MCCR0_MCE;
writel_relaxed(m->mccr0, MCCR0(m));
} }
static void mcp_sa11x0_disable(struct mcp *mcp) static void mcp_sa11x0_disable(struct mcp *mcp)
{ {
Ser4MCCR0 &= ~MCCR0_MCE; struct mcp_sa11x0 *m = priv(mcp);
m->mccr0 &= ~MCCR0_MCE;
writel_relaxed(m->mccr0, MCCR0(m));
} }
/* /*
...@@ -137,55 +155,64 @@ static struct mcp_ops mcp_sa11x0 = { ...@@ -137,55 +155,64 @@ static struct mcp_ops mcp_sa11x0 = {
.disable = mcp_sa11x0_disable, .disable = mcp_sa11x0_disable,
}; };
static int mcp_sa11x0_probe(struct platform_device *pdev) static int mcp_sa11x0_probe(struct platform_device *dev)
{ {
struct mcp_plat_data *data = pdev->dev.platform_data; struct mcp_plat_data *data = dev->dev.platform_data;
struct resource *mem0, *mem1;
struct mcp_sa11x0 *m;
struct mcp *mcp; struct mcp *mcp;
int ret; int ret;
if (!data) if (!data)
return -ENODEV; return -ENODEV;
if (!request_mem_region(0x80060000, 0x60, "sa11x0-mcp")) mem0 = platform_get_resource(dev, IORESOURCE_MEM, 0);
return -EBUSY; mem1 = platform_get_resource(dev, IORESOURCE_MEM, 1);
if (!mem0 || !mem1)
return -ENXIO;
if (!request_mem_region(mem0->start, resource_size(mem0),
DRIVER_NAME)) {
ret = -EBUSY;
goto err_mem0;
}
mcp = mcp_host_alloc(&pdev->dev, sizeof(struct mcp_sa11x0)); if (!request_mem_region(mem1->start, resource_size(mem1),
DRIVER_NAME)) {
ret = -EBUSY;
goto err_mem1;
}
mcp = mcp_host_alloc(&dev->dev, sizeof(struct mcp_sa11x0));
if (!mcp) { if (!mcp) {
ret = -ENOMEM; ret = -ENOMEM;
goto release; goto err_alloc;
} }
mcp->owner = THIS_MODULE; mcp->owner = THIS_MODULE;
mcp->ops = &mcp_sa11x0; mcp->ops = &mcp_sa11x0;
mcp->sclk_rate = data->sclk_rate; mcp->sclk_rate = data->sclk_rate;
mcp->dma_audio_rd = DMA_Ser4MCP0Rd;
mcp->dma_audio_wr = DMA_Ser4MCP0Wr;
mcp->dma_telco_rd = DMA_Ser4MCP1Rd;
mcp->dma_telco_wr = DMA_Ser4MCP1Wr;
mcp->gpio_base = data->gpio_base;
platform_set_drvdata(pdev, mcp); m = priv(mcp);
m->mccr0 = data->mccr0 | 0x7f7f;
m->mccr1 = data->mccr1;
if (machine_is_assabet()) { m->base0 = ioremap(mem0->start, resource_size(mem0));
ASSABET_BCR_set(ASSABET_BCR_CODEC_RST); m->base1 = ioremap(mem1->start, resource_size(mem1));
if (!m->base0 || !m->base1) {
ret = -ENOMEM;
goto err_ioremap;
} }
/* platform_set_drvdata(dev, mcp);
* Setup the PPC unit correctly.
*/
PPDR &= ~PPC_RXD4;
PPDR |= PPC_TXD4 | PPC_SCLK | PPC_SFRM;
PSDR |= PPC_RXD4;
PSDR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
PPSR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
/* /*
* Initialise device. Note that we initially * Initialise device. Note that we initially
* set the sampling rate to minimum. * set the sampling rate to minimum.
*/ */
Ser4MCSR = -1; writel_relaxed(-1, MCSR(m));
Ser4MCCR1 = data->mccr1; writel_relaxed(m->mccr1, MCCR1(m));
Ser4MCCR0 = data->mccr0 | 0x7f7f; writel_relaxed(m->mccr0, MCCR0(m));
/* /*
* Calculate the read/write timeout (us) from the bit clock * Calculate the read/write timeout (us) from the bit clock
...@@ -195,62 +222,90 @@ static int mcp_sa11x0_probe(struct platform_device *pdev) ...@@ -195,62 +222,90 @@ static int mcp_sa11x0_probe(struct platform_device *pdev)
mcp->rw_timeout = (64 * 3 * 1000000 + mcp->sclk_rate - 1) / mcp->rw_timeout = (64 * 3 * 1000000 + mcp->sclk_rate - 1) /
mcp->sclk_rate; mcp->sclk_rate;
ret = mcp_host_register(mcp); ret = mcp_host_add(mcp, data->codec_pdata);
if (ret == 0) if (ret == 0)
goto out; return 0;
release: platform_set_drvdata(dev, NULL);
release_mem_region(0x80060000, 0x60);
platform_set_drvdata(pdev, NULL);
out: err_ioremap:
iounmap(m->base1);
iounmap(m->base0);
mcp_host_free(mcp);
err_alloc:
release_mem_region(mem1->start, resource_size(mem1));
err_mem1:
release_mem_region(mem0->start, resource_size(mem0));
err_mem0:
return ret; return ret;
} }
static int mcp_sa11x0_remove(struct platform_device *dev) static int mcp_sa11x0_remove(struct platform_device *dev)
{ {
struct mcp *mcp = platform_get_drvdata(dev); struct mcp *mcp = platform_get_drvdata(dev);
struct mcp_sa11x0 *m = priv(mcp);
struct resource *mem0, *mem1;
if (m->mccr0 & MCCR0_MCE)
dev_warn(&dev->dev,
"device left active (missing disable call?)\n");
mem0 = platform_get_resource(dev, IORESOURCE_MEM, 0);
mem1 = platform_get_resource(dev, IORESOURCE_MEM, 1);
platform_set_drvdata(dev, NULL); platform_set_drvdata(dev, NULL);
mcp_host_unregister(mcp); mcp_host_del(mcp);
release_mem_region(0x80060000, 0x60); iounmap(m->base1);
iounmap(m->base0);
mcp_host_free(mcp);
release_mem_region(mem1->start, resource_size(mem1));
release_mem_region(mem0->start, resource_size(mem0));
return 0; return 0;
} }
static int mcp_sa11x0_suspend(struct platform_device *dev, pm_message_t state) #ifdef CONFIG_PM_SLEEP
static int mcp_sa11x0_suspend(struct device *dev)
{ {
struct mcp *mcp = platform_get_drvdata(dev); struct mcp_sa11x0 *m = priv(dev_get_drvdata(dev));
if (m->mccr0 & MCCR0_MCE)
dev_warn(dev, "device left active (missing disable call?)\n");
priv(mcp)->mccr0 = Ser4MCCR0; writel(m->mccr0 & ~MCCR0_MCE, MCCR0(m));
priv(mcp)->mccr1 = Ser4MCCR1;
Ser4MCCR0 &= ~MCCR0_MCE;
return 0; return 0;
} }
static int mcp_sa11x0_resume(struct platform_device *dev) static int mcp_sa11x0_resume(struct device *dev)
{ {
struct mcp *mcp = platform_get_drvdata(dev); struct mcp_sa11x0 *m = priv(dev_get_drvdata(dev));
Ser4MCCR1 = priv(mcp)->mccr1; writel_relaxed(m->mccr1, MCCR1(m));
Ser4MCCR0 = priv(mcp)->mccr0; writel_relaxed(m->mccr0, MCCR0(m));
return 0; return 0;
} }
#endif
/*
* The driver for the SA11x0 MCP port. static const struct dev_pm_ops mcp_sa11x0_pm_ops = {
*/ #ifdef CONFIG_PM_SLEEP
MODULE_ALIAS("platform:sa11x0-mcp"); .suspend = mcp_sa11x0_suspend,
.freeze = mcp_sa11x0_suspend,
.poweroff = mcp_sa11x0_suspend,
.resume_noirq = mcp_sa11x0_resume,
.thaw_noirq = mcp_sa11x0_resume,
.restore_noirq = mcp_sa11x0_resume,
#endif
};
static struct platform_driver mcp_sa11x0_driver = { static struct platform_driver mcp_sa11x0_driver = {
.probe = mcp_sa11x0_probe, .probe = mcp_sa11x0_probe,
.remove = mcp_sa11x0_remove, .remove = mcp_sa11x0_remove,
.suspend = mcp_sa11x0_suspend,
.resume = mcp_sa11x0_resume,
.driver = { .driver = {
.name = "sa11x0-mcp", .name = DRIVER_NAME,
.owner = THIS_MODULE,
.pm = &mcp_sa11x0_pm_ops,
}, },
}; };
...@@ -259,6 +314,7 @@ static struct platform_driver mcp_sa11x0_driver = { ...@@ -259,6 +314,7 @@ static struct platform_driver mcp_sa11x0_driver = {
*/ */
module_platform_driver(mcp_sa11x0_driver); module_platform_driver(mcp_sa11x0_driver);
MODULE_ALIAS("platform:" DRIVER_NAME);
MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>"); MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>");
MODULE_DESCRIPTION("SA11x0 multimedia communications port driver"); MODULE_DESCRIPTION("SA11x0 multimedia communications port driver");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
...@@ -2280,7 +2280,7 @@ static int __devinit smc_drv_probe(struct platform_device *pdev) ...@@ -2280,7 +2280,7 @@ static int __devinit smc_drv_probe(struct platform_device *pdev)
if (ret) if (ret)
goto out_release_io; goto out_release_io;
#if defined(CONFIG_SA1100_ASSABET) #if defined(CONFIG_SA1100_ASSABET)
NCR_0 |= NCR_ENET_OSC_EN; neponset_ncr_set(NCR_ENET_OSC_EN);
#endif #endif
platform_set_drvdata(pdev, ndev); platform_set_drvdata(pdev, ndev);
ret = smc_enable_device(pdev); ret = smc_enable_device(pdev);
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册