aboutsummaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-12-08 08:12:43 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2009-12-08 08:12:43 -0800
commit79c9601c2e0dbbe69895d302de4d19f3a31fbd30 (patch)
tree78d4be2df851b2b4106adcfd736622a90cecf9e9 /drivers
parent41440ffe21f29bdb985cab76b2d0b06d83e63b19 (diff)
parent3d14b5beba35250c548d3851a2b84fce742d8311 (diff)
Merge branch 'devel' of master.kernel.org:/home/rmk/linux-2.6-arm
* 'devel' of master.kernel.org:/home/rmk/linux-2.6-arm: (272 commits) Fix soc_common PCMCIA configuration ARM: 5827/1: SA1100: h3100/h3600: emit messages on failed gpio_request ARM: 5826/1: SA1100: h3100/h3600: always build htc-egpio driver ARM: 5825/1: SA1100: h3600: update defconfig ARM: 5824/1: SA1100: reuse h3600 PCMCIA driver on h3100 ARM: 5823/1: SA1100: h3100/h3600: add support for gpio-keys ARM: 5822/1: SA1100: h3100/h3600: clean up #includes ARM: 5821/1: SA1100: h3100/h3600: revise copyright boilerplates ARM: 5820/1: SA1100: h3100/h3600: split h3600.c ARM: 5819/1: SA1100: h3100/h3600: merge h3600.h and h3600_gpio.h into h3xxx.h ARM: 5818/1: SA1100: h3100/h3600: drop old GPIO definitions ARM: 5817/1: SA1100: h3100/h3600: configure all unused gpios as inputs ARM: 5816/1: SA1100: h3600: remove IRQ_GPIO_* definitions ARM: 5815/1: SA1100: h3100/h3600: remove now unused assign_h3600_egpio handlers ARM: 5814/1: SA1100: h3100/h3600: convert all users of assign_h3600_egpio to gpiolib ARM: 5813/1: SA1100: h3100/h3600: add htc-egpio driver ARM: 5812/1: SA1100: h3100/h3600: separate machine-specific LCD helpers ARM: 5811/2: pcmcia: convert sa1100_h3600 driver to gpiolib ARM: 5799/1: SA1100: h3600: stop setting direction for LCD pins ARM: 5798/1: SA1100: h3600: remove unused cruft from h3600.h ...
Diffstat (limited to 'drivers')
-rw-r--r--drivers/dma/Kconfig2
-rw-r--r--drivers/leds/leds-locomo.c2
-rw-r--r--drivers/mfd/mcp-core.c2
-rw-r--r--drivers/mfd/mcp-sa11x0.c3
-rw-r--r--drivers/mfd/mcp.h66
-rw-r--r--drivers/mfd/ucb1x00-assabet.c2
-rw-r--r--drivers/mfd/ucb1x00-core.c89
-rw-r--r--drivers/mfd/ucb1x00-ts.c2
-rw-r--r--drivers/mfd/ucb1x00.h255
-rw-r--r--drivers/mmc/host/mmci.c2
-rw-r--r--drivers/mmc/host/pxamci.c10
-rw-r--r--drivers/mtd/nand/Kconfig2
-rw-r--r--drivers/mtd/nand/pxa3xx_nand.c82
-rw-r--r--drivers/pcmcia/Kconfig2
-rw-r--r--drivers/pcmcia/sa1100_generic.c2
-rw-r--r--drivers/pcmcia/sa1100_h3600.c140
-rw-r--r--drivers/power/Kconfig7
-rw-r--r--drivers/power/Makefile1
-rw-r--r--drivers/power/collie_battery.c418
-rw-r--r--drivers/rtc/Kconfig2
-rw-r--r--drivers/serial/s3c2410.c2
-rw-r--r--drivers/serial/s3c2412.c2
-rw-r--r--drivers/serial/s3c2440.c2
-rw-r--r--drivers/serial/s3c24a0.c2
-rw-r--r--drivers/serial/samsung.c2
-rw-r--r--drivers/serial/samsung.h2
-rw-r--r--drivers/video/Kconfig5
-rw-r--r--drivers/video/backlight/da903x_bl.c7
-rw-r--r--drivers/video/backlight/tdo24m.c1
-rw-r--r--drivers/video/pxa168fb.c1
-rw-r--r--drivers/video/pxafb.c23
31 files changed, 751 insertions, 389 deletions
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index b401dadad4a..eb140ff38c2 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -54,7 +54,7 @@ config DW_DMAC
config AT_HDMAC
tristate "Atmel AHB DMA support"
- depends on ARCH_AT91SAM9RL
+ depends on ARCH_AT91SAM9RL || ARCH_AT91SAM9G45
select DMA_ENGINE
help
Support the Atmel AHB DMA controller. This can be integrated in
diff --git a/drivers/leds/leds-locomo.c b/drivers/leds/leds-locomo.c
index 5d91362e306..1f7c10f6b7f 100644
--- a/drivers/leds/leds-locomo.c
+++ b/drivers/leds/leds-locomo.c
@@ -44,7 +44,7 @@ static void locomoled_brightness_set1(struct led_classdev *led_cdev,
static struct led_classdev locomo_led0 = {
.name = "locomo:amber:charge",
- .default_trigger = "sharpsl-charge",
+ .default_trigger = "main-battery-charging",
.brightness_set = locomoled_brightness_set0,
};
diff --git a/drivers/mfd/mcp-core.c b/drivers/mfd/mcp-core.c
index 57271cb3b31..84815f9ef63 100644
--- a/drivers/mfd/mcp-core.c
+++ b/drivers/mfd/mcp-core.c
@@ -17,11 +17,11 @@
#include <linux/device.h>
#include <linux/slab.h>
#include <linux/string.h>
+#include <linux/mfd/mcp.h>
#include <mach/dma.h>
#include <asm/system.h>
-#include "mcp.h"
#define to_mcp(d) container_of(d, struct mcp, attached_device)
#define to_mcp_driver(d) container_of(d, struct mcp_driver, drv)
diff --git a/drivers/mfd/mcp-sa11x0.c b/drivers/mfd/mcp-sa11x0.c
index 62b32dabf62..25842723272 100644
--- a/drivers/mfd/mcp-sa11x0.c
+++ b/drivers/mfd/mcp-sa11x0.c
@@ -19,6 +19,7 @@
#include <linux/spinlock.h>
#include <linux/slab.h>
#include <linux/platform_device.h>
+#include <linux/mfd/mcp.h>
#include <mach/dma.h>
#include <mach/hardware.h>
@@ -28,7 +29,6 @@
#include <mach/assabet.h>
-#include "mcp.h"
struct mcp_sa11x0 {
u32 mccr0;
@@ -163,6 +163,7 @@ static int mcp_sa11x0_probe(struct platform_device *pdev)
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);
diff --git a/drivers/mfd/mcp.h b/drivers/mfd/mcp.h
deleted file mode 100644
index c093a93b880..00000000000
--- a/drivers/mfd/mcp.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * linux/drivers/mfd/mcp.h
- *
- * Copyright (C) 2001 Russell King, All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License.
- */
-#ifndef MCP_H
-#define MCP_H
-
-struct mcp_ops;
-
-struct mcp {
- struct module *owner;
- struct mcp_ops *ops;
- spinlock_t lock;
- int use_count;
- unsigned int sclk_rate;
- unsigned int rw_timeout;
- dma_device_t dma_audio_rd;
- dma_device_t dma_audio_wr;
- dma_device_t dma_telco_rd;
- dma_device_t dma_telco_wr;
- struct device attached_device;
-};
-
-struct mcp_ops {
- void (*set_telecom_divisor)(struct mcp *, unsigned int);
- void (*set_audio_divisor)(struct mcp *, unsigned int);
- void (*reg_write)(struct mcp *, unsigned int, unsigned int);
- unsigned int (*reg_read)(struct mcp *, unsigned int);
- void (*enable)(struct mcp *);
- void (*disable)(struct mcp *);
-};
-
-void mcp_set_telecom_divisor(struct mcp *, unsigned int);
-void mcp_set_audio_divisor(struct mcp *, unsigned int);
-void mcp_reg_write(struct mcp *, unsigned int, unsigned int);
-unsigned int mcp_reg_read(struct mcp *, unsigned int);
-void mcp_enable(struct mcp *);
-void mcp_disable(struct mcp *);
-#define mcp_get_sclk_rate(mcp) ((mcp)->sclk_rate)
-
-struct mcp *mcp_host_alloc(struct device *, size_t);
-int mcp_host_register(struct mcp *);
-void mcp_host_unregister(struct mcp *);
-
-struct mcp_driver {
- struct device_driver drv;
- int (*probe)(struct mcp *);
- void (*remove)(struct mcp *);
- int (*suspend)(struct mcp *, pm_message_t);
- int (*resume)(struct mcp *);
-};
-
-int mcp_driver_register(struct mcp_driver *);
-void mcp_driver_unregister(struct mcp_driver *);
-
-#define mcp_get_drvdata(mcp) dev_get_drvdata(&(mcp)->attached_device)
-#define mcp_set_drvdata(mcp,d) dev_set_drvdata(&(mcp)->attached_device, d)
-
-#define mcp_priv(mcp) ((void *)((mcp)+1))
-
-#endif
diff --git a/drivers/mfd/ucb1x00-assabet.c b/drivers/mfd/ucb1x00-assabet.c
index 86fed4870f9..cea9da60850 100644
--- a/drivers/mfd/ucb1x00-assabet.c
+++ b/drivers/mfd/ucb1x00-assabet.c
@@ -14,10 +14,10 @@
#include <linux/fs.h>
#include <linux/proc_fs.h>
#include <linux/device.h>
+#include <linux/mfd/ucb1x00.h>
#include <mach/dma.h>
-#include "ucb1x00.h"
#define UCB1X00_ATTR(name,input)\
static ssize_t name##_show(struct device *dev, struct device_attribute *attr, \
diff --git a/drivers/mfd/ucb1x00-core.c b/drivers/mfd/ucb1x00-core.c
index 60c3988f3cf..252b74188ec 100644
--- a/drivers/mfd/ucb1x00-core.c
+++ b/drivers/mfd/ucb1x00-core.c
@@ -25,12 +25,12 @@
#include <linux/interrupt.h>
#include <linux/device.h>
#include <linux/mutex.h>
+#include <linux/mfd/ucb1x00.h>
+#include <linux/gpio.h>
#include <mach/dma.h>
#include <mach/hardware.h>
-#include "ucb1x00.h"
-
static DEFINE_MUTEX(ucb1x00_mutex);
static LIST_HEAD(ucb1x00_drivers);
static LIST_HEAD(ucb1x00_devices);
@@ -108,6 +108,60 @@ unsigned int ucb1x00_io_read(struct ucb1x00 *ucb)
return ucb1x00_reg_read(ucb, UCB_IO_DATA);
}
+static void ucb1x00_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+ struct ucb1x00 *ucb = container_of(chip, struct ucb1x00, gpio);
+ unsigned long flags;
+
+ spin_lock_irqsave(&ucb->io_lock, flags);
+ if (value)
+ ucb->io_out |= 1 << offset;
+ else
+ ucb->io_out &= ~(1 << offset);
+
+ ucb1x00_reg_write(ucb, UCB_IO_DATA, ucb->io_out);
+ spin_unlock_irqrestore(&ucb->io_lock, flags);
+}
+
+static int ucb1x00_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+ struct ucb1x00 *ucb = container_of(chip, struct ucb1x00, gpio);
+ return ucb1x00_reg_read(ucb, UCB_IO_DATA) & (1 << offset);
+}
+
+static int ucb1x00_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+ struct ucb1x00 *ucb = container_of(chip, struct ucb1x00, gpio);
+ unsigned long flags;
+
+ spin_lock_irqsave(&ucb->io_lock, flags);
+ ucb->io_dir &= ~(1 << offset);
+ ucb1x00_reg_write(ucb, UCB_IO_DIR, ucb->io_dir);
+ spin_unlock_irqrestore(&ucb->io_lock, flags);
+
+ return 0;
+}
+
+static int ucb1x00_gpio_direction_output(struct gpio_chip *chip, unsigned offset
+ , int value)
+{
+ struct ucb1x00 *ucb = container_of(chip, struct ucb1x00, gpio);
+ unsigned long flags;
+
+ spin_lock_irqsave(&ucb->io_lock, flags);
+ ucb->io_dir |= (1 << offset);
+ ucb1x00_reg_write(ucb, UCB_IO_DIR, ucb->io_dir);
+
+ if (value)
+ ucb->io_out |= 1 << offset;
+ else
+ ucb->io_out &= ~(1 << offset);
+ ucb1x00_reg_write(ucb, UCB_IO_DATA, ucb->io_out);
+ spin_unlock_irqrestore(&ucb->io_lock, flags);
+
+ return 0;
+}
+
/*
* UCB1300 data sheet says we must:
* 1. enable ADC => 5us (including reference startup time)
@@ -476,6 +530,7 @@ static int ucb1x00_probe(struct mcp *mcp)
struct ucb1x00_driver *drv;
unsigned int id;
int ret = -ENODEV;
+ int temp;
mcp_enable(mcp);
id = mcp_reg_read(mcp, UCB_ID);
@@ -508,12 +563,27 @@ static int ucb1x00_probe(struct mcp *mcp)
goto err_free;
}
+ ucb->gpio.base = -1;
+ if (mcp->gpio_base != 0) {
+ ucb->gpio.label = dev_name(&ucb->dev);
+ ucb->gpio.base = mcp->gpio_base;
+ ucb->gpio.ngpio = 10;
+ ucb->gpio.set = ucb1x00_gpio_set;
+ ucb->gpio.get = ucb1x00_gpio_get;
+ ucb->gpio.direction_input = ucb1x00_gpio_direction_input;
+ ucb->gpio.direction_output = ucb1x00_gpio_direction_output;
+ ret = gpiochip_add(&ucb->gpio);
+ if (ret)
+ goto err_free;
+ } else
+ dev_info(&ucb->dev, "gpio_base not set so no gpiolib support");
+
ret = request_irq(ucb->irq, ucb1x00_irq, IRQF_TRIGGER_RISING,
"UCB1x00", ucb);
if (ret) {
printk(KERN_ERR "ucb1x00: unable to grab irq%d: %d\n",
ucb->irq, ret);
- goto err_free;
+ goto err_gpio;
}
mcp_set_drvdata(mcp, ucb);
@@ -522,6 +592,7 @@ static int ucb1x00_probe(struct mcp *mcp)
if (ret)
goto err_irq;
+
INIT_LIST_HEAD(&ucb->devs);
mutex_lock(&ucb1x00_mutex);
list_add(&ucb->node, &ucb1x00_devices);
@@ -529,10 +600,14 @@ static int ucb1x00_probe(struct mcp *mcp)
ucb1x00_add_dev(ucb, drv);
}
mutex_unlock(&ucb1x00_mutex);
+
goto out;
err_irq:
free_irq(ucb->irq, ucb);
+ err_gpio:
+ if (ucb->gpio.base != -1)
+ temp = gpiochip_remove(&ucb->gpio);
err_free:
kfree(ucb);
err_disable:
@@ -545,6 +620,7 @@ static void ucb1x00_remove(struct mcp *mcp)
{
struct ucb1x00 *ucb = mcp_get_drvdata(mcp);
struct list_head *l, *n;
+ int ret;
mutex_lock(&ucb1x00_mutex);
list_del(&ucb->node);
@@ -554,6 +630,12 @@ static void ucb1x00_remove(struct mcp *mcp)
}
mutex_unlock(&ucb1x00_mutex);
+ if (ucb->gpio.base != -1) {
+ ret = gpiochip_remove(&ucb->gpio);
+ if (ret)
+ dev_err(&ucb->dev, "Can't remove gpio chip: %d\n", ret);
+ }
+
free_irq(ucb->irq, ucb);
device_unregister(&ucb->dev);
}
@@ -604,6 +686,7 @@ static int ucb1x00_resume(struct mcp *mcp)
struct ucb1x00 *ucb = mcp_get_drvdata(mcp);
struct ucb1x00_dev *dev;
+ ucb1x00_reg_write(ucb, UCB_IO_DIR, ucb->io_dir);
mutex_lock(&ucb1x00_mutex);
list_for_each_entry(dev, &ucb->devs, dev_node) {
if (dev->drv->resume)
diff --git a/drivers/mfd/ucb1x00-ts.c b/drivers/mfd/ucb1x00-ts.c
index 61b7d3eb9a2..000cb414a78 100644
--- a/drivers/mfd/ucb1x00-ts.c
+++ b/drivers/mfd/ucb1x00-ts.c
@@ -30,12 +30,12 @@
#include <linux/freezer.h>
#include <linux/slab.h>
#include <linux/kthread.h>
+#include <linux/mfd/ucb1x00.h>
#include <mach/dma.h>
#include <mach/collie.h>
#include <asm/mach-types.h>
-#include "ucb1x00.h"
struct ucb1x00_ts {
diff --git a/drivers/mfd/ucb1x00.h b/drivers/mfd/ucb1x00.h
deleted file mode 100644
index a8ad8a0ed5d..00000000000
--- a/drivers/mfd/ucb1x00.h
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
- * linux/drivers/mfd/ucb1x00.h
- *
- * Copyright (C) 2001 Russell King, All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License.
- */
-#ifndef UCB1200_H
-#define UCB1200_H
-
-#define UCB_IO_DATA 0x00
-#define UCB_IO_DIR 0x01
-
-#define UCB_IO_0 (1 << 0)
-#define UCB_IO_1 (1 << 1)
-#define UCB_IO_2 (1 << 2)
-#define UCB_IO_3 (1 << 3)
-#define UCB_IO_4 (1 << 4)
-#define UCB_IO_5 (1 << 5)
-#define UCB_IO_6 (1 << 6)
-#define UCB_IO_7 (1 << 7)
-#define UCB_IO_8 (1 << 8)
-#define UCB_IO_9 (1 << 9)
-
-#define UCB_IE_RIS 0x02
-#define UCB_IE_FAL 0x03
-#define UCB_IE_STATUS 0x04
-#define UCB_IE_CLEAR 0x04
-#define UCB_IE_ADC (1 << 11)
-#define UCB_IE_TSPX (1 << 12)
-#define UCB_IE_TSMX (1 << 13)
-#define UCB_IE_TCLIP (1 << 14)
-#define UCB_IE_ACLIP (1 << 15)
-
-#define UCB_IRQ_TSPX 12
-
-#define UCB_TC_A 0x05
-#define UCB_TC_A_LOOP (1 << 7) /* UCB1200 */
-#define UCB_TC_A_AMPL (1 << 7) /* UCB1300 */
-
-#define UCB_TC_B 0x06
-#define UCB_TC_B_VOICE_ENA (1 << 3)
-#define UCB_TC_B_CLIP (1 << 4)
-#define UCB_TC_B_ATT (1 << 6)
-#define UCB_TC_B_SIDE_ENA (1 << 11)
-#define UCB_TC_B_MUTE (1 << 13)
-#define UCB_TC_B_IN_ENA (1 << 14)
-#define UCB_TC_B_OUT_ENA (1 << 15)
-
-#define UCB_AC_A 0x07
-#define UCB_AC_B 0x08
-#define UCB_AC_B_LOOP (1 << 8)
-#define UCB_AC_B_MUTE (1 << 13)
-#define UCB_AC_B_IN_ENA (1 << 14)
-#define UCB_AC_B_OUT_ENA (1 << 15)
-
-#define UCB_TS_CR 0x09
-#define UCB_TS_CR_TSMX_POW (1 << 0)
-#define UCB_TS_CR_TSPX_POW (1 << 1)
-#define UCB_TS_CR_TSMY_POW (1 << 2)
-#define UCB_TS_CR_TSPY_POW (1 << 3)
-#define UCB_TS_CR_TSMX_GND (1 << 4)
-#define UCB_TS_CR_TSPX_GND (1 << 5)
-#define UCB_TS_CR_TSMY_GND (1 << 6)
-#define UCB_TS_CR_TSPY_GND (1 << 7)
-#define UCB_TS_CR_MODE_INT (0 << 8)
-#define UCB_TS_CR_MODE_PRES (1 << 8)
-#define UCB_TS_CR_MODE_POS (2 << 8)
-#define UCB_TS_CR_BIAS_ENA (1 << 11)
-#define UCB_TS_CR_TSPX_LOW (1 << 12)
-#define UCB_TS_CR_TSMX_LOW (1 << 13)
-
-#define UCB_ADC_CR 0x0a
-#define UCB_ADC_SYNC_ENA (1 << 0)
-#define UCB_ADC_VREFBYP_CON (1 << 1)
-#define UCB_ADC_INP_TSPX (0 << 2)
-#define UCB_ADC_INP_TSMX (1 << 2)
-#define UCB_ADC_INP_TSPY (2 << 2)
-#define UCB_ADC_INP_TSMY (3 << 2)
-#define UCB_ADC_INP_AD0 (4 << 2)
-#define UCB_ADC_INP_AD1 (5 << 2)
-#define UCB_ADC_INP_AD2 (6 << 2)
-#define UCB_ADC_INP_AD3 (7 << 2)
-#define UCB_ADC_EXT_REF (1 << 5)
-#define UCB_ADC_START (1 << 7)
-#define UCB_ADC_ENA (1 << 15)
-
-#define UCB_ADC_DATA 0x0b
-#define UCB_ADC_DAT_VAL (1 << 15)
-#define UCB_ADC_DAT(x) (((x) & 0x7fe0) >> 5)
-
-#define UCB_ID 0x0c
-#define UCB_ID_1200 0x1004
-#define UCB_ID_1300 0x1005
-#define UCB_ID_TC35143 0x9712
-
-#define UCB_MODE 0x0d
-#define UCB_MODE_DYN_VFLAG_ENA (1 << 12)
-#define UCB_MODE_AUD_OFF_CAN (1 << 13)
-
-#include "mcp.h"
-
-struct ucb1x00_irq {
- void *devid;
- void (*fn)(int, void *);
-};
-
-struct ucb1x00 {
- spinlock_t lock;
- struct mcp *mcp;
- unsigned int irq;
- struct semaphore adc_sem;
- spinlock_t io_lock;
- u16 id;
- u16 io_dir;
- u16 io_out;
- u16 adc_cr;
- u16 irq_fal_enbl;
- u16 irq_ris_enbl;
- struct ucb1x00_irq irq_handler[16];
- struct device dev;
- struct list_head node;
- struct list_head devs;
-};
-
-struct ucb1x00_driver;
-
-struct ucb1x00_dev {
- struct list_head dev_node;
- struct list_head drv_node;
- struct ucb1x00 *ucb;
- struct ucb1x00_driver *drv;
- void *priv;
-};
-
-struct ucb1x00_driver {
- struct list_head node;
- struct list_head devs;
- int (*add)(struct ucb1x00_dev *dev);
- void (*remove)(struct ucb1x00_dev *dev);
- int (*suspend)(struct ucb1x00_dev *dev, pm_message_t state);
- int (*resume)(struct ucb1x00_dev *dev);
-};
-
-#define classdev_to_ucb1x00(cd) container_of(cd, struct ucb1x00, dev)
-
-int ucb1x00_register_driver(struct ucb1x00_driver *);
-void ucb1x00_unregister_driver(struct ucb1x00_driver *);
-
-/**
- * ucb1x00_clkrate - return the UCB1x00 SIB clock rate
- * @ucb: UCB1x00 structure describing chip
- *
- * Return the SIB clock rate in Hz.
- */
-static inline unsigned int ucb1x00_clkrate(struct ucb1x00 *ucb)
-{
- return mcp_get_sclk_rate(ucb->mcp);
-}
-
-/**
- * ucb1x00_enable - enable the UCB1x00 SIB clock
- * @ucb: UCB1x00 structure describing chip
- *
- * Enable the SIB clock. This can be called multiple times.
- */
-static inline void ucb1x00_enable(struct ucb1x00 *ucb)
-{
- mcp_enable(ucb->mcp);
-}
-
-/**
- * ucb1x00_disable - disable the UCB1x00 SIB clock
- * @ucb: UCB1x00 structure describing chip
- *
- * Disable the SIB clock. The SIB clock will only be disabled
- * when the number of ucb1x00_enable calls match the number of
- * ucb1x00_disable calls.
- */
-static inline void ucb1x00_disable(struct ucb1x00 *ucb)
-{
- mcp_disable(ucb->mcp);
-}
-
-/**
- * ucb1x00_reg_write - write a UCB1x00 register
- * @ucb: UCB1x00 structure describing chip
- * @reg: UCB1x00 4-bit register index to write
- * @val: UCB1x00 16-bit value to write
- *
- * Write the UCB1x00 register @reg with value @val. The SIB
- * clock must be running for this function to return.
- */
-static inline void ucb1x00_reg_write(struct ucb1x00 *ucb, unsigned int reg, unsigned int val)
-{
- mcp_reg_write(ucb->mcp, reg, val);
-}
-
-/**
- * ucb1x00_reg_read - read a UCB1x00 register
- * @ucb: UCB1x00 structure describing chip
- * @reg: UCB1x00 4-bit register index to write
- *
- * Read the UCB1x00 register @reg and return its value. The SIB
- * clock must be running for this function to return.
- */
-static inline unsigned int ucb1x00_reg_read(struct ucb1x00 *ucb, unsigned int reg)
-{
- return mcp_reg_read(ucb->mcp, reg);
-}
-/**
- * ucb1x00_set_audio_divisor -
- * @ucb: UCB1x00 structure describing chip
- * @div: SIB clock divisor
- */
-static inline void ucb1x00_set_audio_divisor(struct ucb1x00 *ucb, unsigned int div)
-{
- mcp_set_audio_divisor(ucb->mcp, div);
-}
-
-/**
- * ucb1x00_set_telecom_divisor -
- * @ucb: UCB1x00 structure describing chip
- * @div: SIB clock divisor
- */
-static inline void ucb1x00_set_telecom_divisor(struct ucb1x00 *ucb, unsigned int div)
-{
- mcp_set_telecom_divisor(ucb->mcp, div);
-}
-
-void ucb1x00_io_set_dir(struct ucb1x00 *ucb, unsigned int, unsigned int);
-void ucb1x00_io_write(struct ucb1x00 *ucb, unsigned int, unsigned int);
-unsigned int ucb1x00_io_read(struct ucb1x00 *ucb);
-
-#define UCB_NOSYNC (0)
-#define UCB_SYNC (1)
-
-unsigned int ucb1x00_adc_read(struct ucb1x00 *ucb, int adc_channel, int sync);
-void ucb1x00_adc_enable(struct ucb1x00 *ucb);
-void ucb1x00_adc_disable(struct ucb1x00 *ucb);
-
-/*
- * Which edges of the IRQ do you want to control today?
- */
-#define UCB_RISING (1 << 0)
-#define UCB_FALLING (1 << 1)
-
-int ucb1x00_hook_irq(struct ucb1x00 *ucb, unsigned int idx, void (*fn)(int, void *), void *devid);
-void ucb1x00_enable_irq(struct ucb1x00 *ucb, unsigned int idx, int edges);
-void ucb1x00_disable_irq(struct ucb1x00 *ucb, unsigned int idx, int edges);
-int ucb1x00_free_irq(struct ucb1x00 *ucb, unsigned int idx, void *devid);
-
-#endif
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 705a5894a6b..90d168ad03b 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -56,7 +56,7 @@ static void mmci_set_clkreg(struct mmci_host *host, unsigned int desired)
clk = 255;
host->cclk = host->mclk / (2 * (clk + 1));
}
- if (host->hw_designer == 0x80)
+ if (host->hw_designer == AMBA_VENDOR_ST)
clk |= MCI_FCEN; /* Bug fix in ST IP block */
clk |= MCI_CLK_ENABLE;
/* This hasn't proven to be worthwhile */
diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c
index 9fb480bb0e0..bb47ff465c0 100644
--- a/drivers/mmc/host/pxamci.c
+++ b/drivers/mmc/host/pxamci.c
@@ -43,6 +43,9 @@
#define NR_SG 1
#define CLKRT_OFF (~0)
+#define mmc_has_26MHz() (cpu_is_pxa300() || cpu_is_pxa310() \
+ || cpu_is_pxa935())
+
struct pxamci_host {
struct mmc_host *mmc;
spinlock_t lock;
@@ -457,7 +460,7 @@ static void pxamci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
clk_enable(host->clk);
if (ios->clock == 26000000) {
- /* to support 26MHz on pxa300/pxa310 */
+ /* to support 26MHz */
host->clkrt = 7;
} else {
/* to handle (19.5MHz, 26MHz) */
@@ -608,8 +611,7 @@ static int pxamci_probe(struct platform_device *pdev)
* Calculate minimum clock rate, rounding up.
*/
mmc->f_min = (host->clkrate + 63) / 64;
- mmc->f_max = (cpu_is_pxa300() || cpu_is_pxa310()) ? 26000000
- : host->clkrate;
+ mmc->f_max = (mmc_has_26MHz()) ? 26000000 : host->clkrate;
pxamci_init_ocr(host);
@@ -618,7 +620,7 @@ static int pxamci_probe(struct platform_device *pdev)
if (!cpu_is_pxa25x()) {
mmc->caps |= MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ;
host->cmdat |= CMDAT_SDIO_INT_EN;
- if (cpu_is_pxa300() || cpu_is_pxa310())
+ if (mmc_has_26MHz())
mmc->caps |= MMC_CAP_MMC_HIGHSPEED |
MMC_CAP_SD_HIGHSPEED;
}
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index 2fda0b61524..8f8e87b7ed6 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -358,7 +358,7 @@ endchoice
config MTD_NAND_PXA3xx
tristate "Support for NAND flash devices on PXA3xx"
- depends on MTD_NAND && PXA3xx
+ depends on MTD_NAND && (PXA3xx || ARCH_MMP)
help
This enables the driver for the NAND flash device found on
PXA3xx processors
diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c
index 6ea520ae241..1a5a0365c98 100644
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -9,6 +9,7 @@
* published by the Free Software Foundation.
*/
+#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
@@ -22,7 +23,7 @@
#include <linux/irq.h>
#include <mach/dma.h>
-#include <mach/pxa3xx_nand.h>
+#include <plat/pxa3xx_nand.h>
#define CHIP_DELAY_TIMEOUT (2 * HZ/10)
@@ -84,10 +85,6 @@
#define NDCB0_CMD1_MASK (0xff)
#define NDCB0_ADDR_CYC_SHIFT (16)
-/* dma-able I/O address for the NAND data and commands */
-#define NDCB0_DMA_ADDR (0x43100048)
-#define NDDB_DMA_ADDR (0x43100040)
-
/* macros for registers read/write */
#define nand_writel(info, off, val) \
__raw_writel((val), (info)->mmio_base + (off))
@@ -123,6 +120,7 @@ struct pxa3xx_nand_info {
struct clk *clk;
void __iomem *mmio_base;
+ unsigned long mmio_phys;
unsigned int buf_start;
unsigned int buf_count;
@@ -228,13 +226,35 @@ static struct pxa3xx_nand_flash samsung512MbX16 = {
.chip_id = 0x46ec,
};
+static struct pxa3xx_nand_flash samsung2GbX8 = {
+ .timing = &samsung512MbX16_timing,
+ .cmdset = &smallpage_cmdset,
+ .page_per_block = 64,
+ .page_size = 2048,
+ .flash_width = 8,
+ .dfc_width = 8,
+ .num_blocks = 2048,
+ .chip_id = 0xdaec,
+};
+
+static struct pxa3xx_nand_flash samsung32GbX8 = {
+ .timing = &samsung512MbX16_timing,
+ .cmdset = &smallpage_cmdset,
+ .page_per_block = 128,
+ .page_size = 4096,
+ .flash_width = 8,
+ .dfc_width = 8,
+ .num_blocks = 8192,
+ .chip_id = 0xd7ec,
+};
+
static struct pxa3xx_nand_timing micron_timing = {
.tCH = 10,
.tCS = 25,
.tWH = 15,
.tWP = 25,
.tRH = 15,
- .tRP = 25,
+ .tRP = 30,
.tR = 25000,
.tWHR = 60,
.tAR = 10,
@@ -262,6 +282,28 @@ static struct pxa3xx_nand_flash micron1GbX16 = {
.chip_id = 0xb12c,
};
+static struct pxa3xx_nand_flash micron4GbX8 = {
+ .timing = &micron_timing,
+ .cmdset = &largepage_cmdset,
+ .page_per_block = 64,
+ .page_size = 2048,
+ .flash_width = 8,
+ .dfc_width = 8,
+ .num_blocks = 4096,
+ .chip_id = 0xdc2c,
+};
+
+static struct pxa3xx_nand_flash micron4GbX16 = {
+ .timing = &micron_timing,
+ .cmdset = &largepage_cmdset,
+ .page_per_block = 64,
+ .page_size = 2048,
+ .flash_width = 16,
+ .dfc_width = 16,
+ .num_blocks = 4096,
+ .chip_id = 0xcc2c,
+};
+
static struct pxa3xx_nand_timing stm2GbX16_timing = {
.tCH = 10,
.tCS = 35,
@@ -287,8 +329,12 @@ static struct pxa3xx_nand_flash stm2GbX16 = {
static struct pxa3xx_nand_flash *builtin_flash_types[] = {
&samsung512MbX16,
+ &samsung2GbX8,
+ &samsung32GbX8,
&micron1GbX8,
&micron1GbX16,
+ &micron4GbX8,
+ &micron4GbX16,
&stm2GbX16,
};
#endif /* CONFIG_MTD_NAND_PXA3xx_BUILTIN */
@@ -489,7 +535,7 @@ static int handle_data_pio(struct pxa3xx_nand_info *info)
switch (info->state) {
case STATE_PIO_WRITING:
__raw_writesl(info->mmio_base + NDDB, info->data_buff,
- info->data_size << 2);
+ DIV_ROUND_UP(info->data_size, 4));
enable_int(info, NDSR_CS0_BBD | NDSR_CS0_CMDD);
@@ -501,7 +547,7 @@ static int handle_data_pio(struct pxa3xx_nand_info *info)
break;
case STATE_PIO_READING:
__raw_readsl(info->mmio_base + NDDB, info->data_buff,
- info->data_size << 2);
+ DIV_ROUND_UP(info->data_size, 4));
break;
default:
printk(KERN_ERR "%s: invalid state %d\n", __func__,
@@ -523,11 +569,11 @@ static void start_data_dma(struct pxa3xx_nand_info *info, int dir_out)
if (dir_out) {
desc->dsadr = info->data_buff_phys;
- desc->dtadr = NDDB_DMA_ADDR;
+ desc->dtadr = info->mmio_phys + NDDB;
desc->dcmd |= DCMD_INCSRCADDR | DCMD_FLOWTRG;
} else {
desc->dtadr = info->data_buff_phys;
- desc->dsadr = NDDB_DMA_ADDR;
+ desc->dsadr = info->mmio_phys + NDDB;
desc->dcmd |= DCMD_INCTRGADDR | DCMD_FLOWSRC;
}
@@ -669,6 +715,7 @@ static void pxa3xx_nand_cmdfunc(struct mtd_info *mtd, unsigned command,
/* disable HW ECC to get all the OOB data */
info->buf_count = mtd->writesize + mtd->oobsize;
info->buf_start = mtd->writesize + column;
+ memset(info->data_buff, 0xF