Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 91278
b: refs/heads/master
c: c63fc13
h: refs/heads/master
v: v3
  • Loading branch information
Ben Dooks authored and Russell King committed Apr 17, 2008
1 parent 16a1020 commit 1edd842
Show file tree
Hide file tree
Showing 12 changed files with 213 additions and 300 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 3e238be2f75f2a6d5d5064eda46ac96268c6411e
refs/heads/master: c63fc13f806b11576e8c41969d4b1598dd261d80
3 changes: 0 additions & 3 deletions trunk/arch/arm/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -425,10 +425,7 @@ config ARCH_SA1100
select ARCH_MTD_XIP
select GENERIC_GPIO
select GENERIC_TIME
select GENERIC_CLOCKEVENTS
select TICK_ONESHOT
select HAVE_IDE
select HAVE_GPIO_LIB
help
Support for StrongARM 11x0 based boards.

Expand Down
183 changes: 36 additions & 147 deletions trunk/arch/arm/common/scoop.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
#include <linux/slab.h>
#include <linux/platform_device.h>
#include <asm/io.h>
#include <asm/gpio.h>
#include <asm/hardware/scoop.h>

/* PCMCIA to Scoop linkage
Expand All @@ -31,9 +30,10 @@
struct scoop_pcmcia_config *platform_scoop_config;
EXPORT_SYMBOL(platform_scoop_config);

#define SCOOP_REG(d,adr) (*(volatile unsigned short*)(d +(adr)))

struct scoop_dev {
void __iomem *base;
struct gpio_chip gpio;
void *base;
spinlock_t scoop_lock;
unsigned short suspend_clr;
unsigned short suspend_set;
Expand All @@ -44,84 +44,13 @@ void reset_scoop(struct device *dev)
{
struct scoop_dev *sdev = dev_get_drvdata(dev);

iowrite16(0x0100, sdev->base + SCOOP_MCR); // 00
iowrite16(0x0000, sdev->base + SCOOP_CDR); // 04
iowrite16(0x0000, sdev->base + SCOOP_CCR); // 10
iowrite16(0x0000, sdev->base + SCOOP_IMR); // 18
iowrite16(0x00FF, sdev->base + SCOOP_IRM); // 14
iowrite16(0x0000, sdev->base + SCOOP_ISR); // 1C
iowrite16(0x0000, sdev->base + SCOOP_IRM);
}

static void __scoop_gpio_set(struct scoop_dev *sdev,
unsigned offset, int value)
{
unsigned short gpwr;

gpwr = ioread16(sdev->base + SCOOP_GPWR);
if (value)
gpwr |= 1 << (offset + 1);
else
gpwr &= ~(1 << (offset + 1));
iowrite16(gpwr, sdev->base + SCOOP_GPWR);
}

static void scoop_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
{
struct scoop_dev *sdev = container_of(chip, struct scoop_dev, gpio);
unsigned long flags;

spin_lock_irqsave(&sdev->scoop_lock, flags);

__scoop_gpio_set(sdev, offset, value);

spin_unlock_irqrestore(&sdev->scoop_lock, flags);
}

static int scoop_gpio_get(struct gpio_chip *chip, unsigned offset)
{
struct scoop_dev *sdev = container_of(chip, struct scoop_dev, gpio);

/* XXX: I'm usure, but it seems so */
return ioread16(sdev->base + SCOOP_GPRR) & (1 << (offset + 1));
}

static int scoop_gpio_direction_input(struct gpio_chip *chip,
unsigned offset)
{
struct scoop_dev *sdev = container_of(chip, struct scoop_dev, gpio);
unsigned long flags;
unsigned short gpcr;

spin_lock_irqsave(&sdev->scoop_lock, flags);

gpcr = ioread16(sdev->base + SCOOP_GPCR);
gpcr &= ~(1 << (offset + 1));
iowrite16(gpcr, sdev->base + SCOOP_GPCR);

spin_unlock_irqrestore(&sdev->scoop_lock, flags);

return 0;
}

static int scoop_gpio_direction_output(struct gpio_chip *chip,
unsigned offset, int value)
{
struct scoop_dev *sdev = container_of(chip, struct scoop_dev, gpio);
unsigned long flags;
unsigned short gpcr;

spin_lock_irqsave(&sdev->scoop_lock, flags);

__scoop_gpio_set(sdev, offset, value);

gpcr = ioread16(sdev->base + SCOOP_GPCR);
gpcr |= 1 << (offset + 1);
iowrite16(gpcr, sdev->base + SCOOP_GPCR);

spin_unlock_irqrestore(&sdev->scoop_lock, flags);

return 0;
SCOOP_REG(sdev->base,SCOOP_MCR) = 0x0100; // 00
SCOOP_REG(sdev->base,SCOOP_CDR) = 0x0000; // 04
SCOOP_REG(sdev->base,SCOOP_CCR) = 0x0000; // 10
SCOOP_REG(sdev->base,SCOOP_IMR) = 0x0000; // 18
SCOOP_REG(sdev->base,SCOOP_IRM) = 0x00FF; // 14
SCOOP_REG(sdev->base,SCOOP_ISR) = 0x0000; // 1C
SCOOP_REG(sdev->base,SCOOP_IRM) = 0x0000;
}

unsigned short set_scoop_gpio(struct device *dev, unsigned short bit)
Expand All @@ -131,8 +60,8 @@ unsigned short set_scoop_gpio(struct device *dev, unsigned short bit)
struct scoop_dev *sdev = dev_get_drvdata(dev);

spin_lock_irqsave(&sdev->scoop_lock, flag);
gpio_bit = ioread16(sdev->base + SCOOP_GPWR) | bit;
iowrite16(gpio_bit, sdev->base + SCOOP_GPWR);
gpio_bit = SCOOP_REG(sdev->base, SCOOP_GPWR) | bit;
SCOOP_REG(sdev->base, SCOOP_GPWR) = gpio_bit;
spin_unlock_irqrestore(&sdev->scoop_lock, flag);

return gpio_bit;
Expand All @@ -145,8 +74,8 @@ unsigned short reset_scoop_gpio(struct device *dev, unsigned short bit)
struct scoop_dev *sdev = dev_get_drvdata(dev);

spin_lock_irqsave(&sdev->scoop_lock, flag);
gpio_bit = ioread16(sdev->base + SCOOP_GPWR) & ~bit;
iowrite16(gpio_bit, sdev->base + SCOOP_GPWR);
gpio_bit = SCOOP_REG(sdev->base, SCOOP_GPWR) & ~bit;
SCOOP_REG(sdev->base,SCOOP_GPWR) = gpio_bit;
spin_unlock_irqrestore(&sdev->scoop_lock, flag);

return gpio_bit;
Expand All @@ -158,13 +87,13 @@ EXPORT_SYMBOL(reset_scoop_gpio);
unsigned short read_scoop_reg(struct device *dev, unsigned short reg)
{
struct scoop_dev *sdev = dev_get_drvdata(dev);
return ioread16(sdev->base + reg);
return SCOOP_REG(sdev->base,reg);
}

void write_scoop_reg(struct device *dev, unsigned short reg, unsigned short data)
{
struct scoop_dev *sdev = dev_get_drvdata(dev);
iowrite16(data, sdev->base + reg);
SCOOP_REG(sdev->base,reg)=data;
}

EXPORT_SYMBOL(reset_scoop);
Expand All @@ -175,9 +104,9 @@ static void check_scoop_reg(struct scoop_dev *sdev)
{
unsigned short mcr;

mcr = ioread16(sdev->base + SCOOP_MCR);
mcr = SCOOP_REG(sdev->base, SCOOP_MCR);
if ((mcr & 0x100) == 0)
iowrite16(0x0101, sdev->base + SCOOP_MCR);
SCOOP_REG(sdev->base, SCOOP_MCR) = 0x0101;
}

#ifdef CONFIG_PM
Expand All @@ -186,8 +115,8 @@ static int scoop_suspend(struct platform_device *dev, pm_message_t state)
struct scoop_dev *sdev = platform_get_drvdata(dev);

check_scoop_reg(sdev);
sdev->scoop_gpwr = ioread16(sdev->base + SCOOP_GPWR);
iowrite16((sdev->scoop_gpwr & ~sdev->suspend_clr) | sdev->suspend_set, sdev->base + SCOOP_GPWR);
sdev->scoop_gpwr = SCOOP_REG(sdev->base, SCOOP_GPWR);
SCOOP_REG(sdev->base, SCOOP_GPWR) = (sdev->scoop_gpwr & ~sdev->suspend_clr) | sdev->suspend_set;

return 0;
}
Expand All @@ -197,7 +126,7 @@ static int scoop_resume(struct platform_device *dev)
struct scoop_dev *sdev = platform_get_drvdata(dev);

check_scoop_reg(sdev);
iowrite16(sdev->scoop_gpwr, sdev->base + SCOOP_GPWR);
SCOOP_REG(sdev->base,SCOOP_GPWR) = sdev->scoop_gpwr;

return 0;
}
Expand All @@ -206,13 +135,11 @@ static int scoop_resume(struct platform_device *dev)
#define scoop_resume NULL
#endif

static int __devinit scoop_probe(struct platform_device *pdev)
int __init scoop_probe(struct platform_device *pdev)
{
struct scoop_dev *devptr;
struct scoop_config *inf;
struct resource *mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
int ret;
int temp;

if (!mem)
return -EINVAL;
Expand All @@ -227,86 +154,48 @@ static int __devinit scoop_probe(struct platform_device *pdev)
devptr->base = ioremap(mem->start, mem->end - mem->start + 1);

if (!devptr->base) {
ret = -ENOMEM;
goto err_ioremap;
kfree(devptr);
return -ENOMEM;
}

platform_set_drvdata(pdev, devptr);

printk("Sharp Scoop Device found at 0x%08x -> 0x%8p\n",(unsigned int)mem->start, devptr->base);
printk("Sharp Scoop Device found at 0x%08x -> 0x%08x\n",(unsigned int)mem->start,(unsigned int)devptr->base);

iowrite16(0x0140, devptr->base + SCOOP_MCR);
SCOOP_REG(devptr->base, SCOOP_MCR) = 0x0140;
reset_scoop(&pdev->dev);
iowrite16(0x0000, devptr->base + SCOOP_CPR);
iowrite16(inf->io_dir & 0xffff, devptr->base + SCOOP_GPCR);
iowrite16(inf->io_out & 0xffff, devptr->base + SCOOP_GPWR);
SCOOP_REG(devptr->base, SCOOP_CPR) = 0x0000;
SCOOP_REG(devptr->base, SCOOP_GPCR) = inf->io_dir & 0xffff;
SCOOP_REG(devptr->base, SCOOP_GPWR) = inf->io_out & 0xffff;

devptr->suspend_clr = inf->suspend_clr;
devptr->suspend_set = inf->suspend_set;

devptr->gpio.base = -1;

if (inf->gpio_base != 0) {
devptr->gpio.label = pdev->dev.bus_id;
devptr->gpio.base = inf->gpio_base;
devptr->gpio.ngpio = 12; /* PA11 = 0, PA12 = 1, etc. up to PA22 = 11 */
devptr->gpio.set = scoop_gpio_set;
devptr->gpio.get = scoop_gpio_get;
devptr->gpio.direction_input = scoop_gpio_direction_input;
devptr->gpio.direction_output = scoop_gpio_direction_output;

ret = gpiochip_add(&devptr->gpio);
if (ret)
goto err_gpio;
}

return 0;

if (devptr->gpio.base != -1)
temp = gpiochip_remove(&devptr->gpio);
err_gpio:
platform_set_drvdata(pdev, NULL);
err_ioremap:
iounmap(devptr->base);
kfree(devptr);

return ret;
}

static int __devexit scoop_remove(struct platform_device *pdev)
static int scoop_remove(struct platform_device *pdev)
{
struct scoop_dev *sdev = platform_get_drvdata(pdev);
int ret;

if (!sdev)
return -EINVAL;

if (sdev->gpio.base != -1) {
ret = gpiochip_remove(&sdev->gpio);
if (ret) {
dev_err(&pdev->dev, "Can't remove gpio chip: %d\n", ret);
return ret;
}
if (sdev) {
iounmap(sdev->base);
kfree(sdev);
platform_set_drvdata(pdev, NULL);
}

platform_set_drvdata(pdev, NULL);
iounmap(sdev->base);
kfree(sdev);

return 0;
}

static struct platform_driver scoop_driver = {
.probe = scoop_probe,
.remove = __devexit_p(scoop_remove),
.remove = scoop_remove,
.suspend = scoop_suspend,
.resume = scoop_resume,
.driver = {
.name = "sharp-scoop",
},
};

static int __init scoop_init(void)
int __init scoop_init(void)
{
return platform_driver_register(&scoop_driver);
}
Expand Down
2 changes: 1 addition & 1 deletion trunk/arch/arm/mach-sa1100/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#

# Common support
obj-y := clock.o generic.o gpio.o irq.o dma.o time.o #nmi-oopser.o
obj-y := clock.o generic.o irq.o dma.o time.o #nmi-oopser.o
obj-m :=
obj-n :=
obj- :=
Expand Down
31 changes: 31 additions & 0 deletions trunk/arch/arm/mach-sa1100/generic.c
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,37 @@ unsigned long long sched_clock(void)
return v;
}

int gpio_direction_input(unsigned gpio)
{
unsigned long flags;

if (gpio > GPIO_MAX)
return -EINVAL;

local_irq_save(flags);
GPDR &= ~GPIO_GPIO(gpio);
local_irq_restore(flags);
return 0;
}

EXPORT_SYMBOL(gpio_direction_input);

int gpio_direction_output(unsigned gpio, int value)
{
unsigned long flags;

if (gpio > GPIO_MAX)
return -EINVAL;

local_irq_save(flags);
gpio_set_value(gpio, value);
GPDR |= GPIO_GPIO(gpio);
local_irq_restore(flags);
return 0;
}

EXPORT_SYMBOL(gpio_direction_output);

/*
* Default power-off for SA1100
*/
Expand Down
1 change: 0 additions & 1 deletion trunk/arch/arm/mach-sa1100/generic.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ struct sys_timer;
extern struct sys_timer sa1100_timer;
extern void __init sa1100_map_io(void);
extern void __init sa1100_init_irq(void);
extern void __init sa1100_init_gpio(void);

#define SET_BANK(__nr,__start,__size) \
mi->bank[__nr].start = (__start), \
Expand Down
Loading

0 comments on commit 1edd842

Please sign in to comment.