summaryrefslogtreecommitdiff
path: root/drivers/pinctrl
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pinctrl')
-rw-r--r--drivers/pinctrl/Kconfig28
-rw-r--r--drivers/pinctrl/Makefile6
-rw-r--r--drivers/pinctrl/core.c33
-rw-r--r--drivers/pinctrl/core.h2
-rw-r--r--drivers/pinctrl/devicetree.c11
-rw-r--r--drivers/pinctrl/mvebu/Kconfig24
-rw-r--r--drivers/pinctrl/mvebu/Makefile5
-rw-r--r--drivers/pinctrl/mvebu/pinctrl-armada-370.c (renamed from drivers/pinctrl/pinctrl-armada-370.c)0
-rw-r--r--drivers/pinctrl/mvebu/pinctrl-armada-xp.c (renamed from drivers/pinctrl/pinctrl-armada-xp.c)0
-rw-r--r--drivers/pinctrl/mvebu/pinctrl-dove.c (renamed from drivers/pinctrl/pinctrl-dove.c)0
-rw-r--r--drivers/pinctrl/mvebu/pinctrl-kirkwood.c (renamed from drivers/pinctrl/pinctrl-kirkwood.c)0
-rw-r--r--drivers/pinctrl/mvebu/pinctrl-mvebu.c (renamed from drivers/pinctrl/pinctrl-mvebu.c)1
-rw-r--r--drivers/pinctrl/mvebu/pinctrl-mvebu.h (renamed from drivers/pinctrl/pinctrl-mvebu.h)0
-rw-r--r--drivers/pinctrl/pinconf.c4
-rw-r--r--drivers/pinctrl/pinctrl-bcm2835.c5
-rw-r--r--drivers/pinctrl/pinctrl-coh901.c122
-rw-r--r--drivers/pinctrl/pinctrl-exynos.c1
-rw-r--r--drivers/pinctrl/pinctrl-nomadik.c28
-rw-r--r--drivers/pinctrl/pinctrl-samsung.c10
-rw-r--r--drivers/pinctrl/pinctrl-sirf.c87
-rw-r--r--drivers/pinctrl/pinctrl-tegra.c2
-rw-r--r--drivers/pinctrl/pinctrl-tegra30.c24
-rw-r--r--drivers/pinctrl/pinctrl-u300.c42
-rw-r--r--drivers/pinctrl/pinctrl-xway.c2
-rw-r--r--drivers/pinctrl/pinmux.c67
-rw-r--r--drivers/pinctrl/spear/Kconfig11
-rw-r--r--drivers/pinctrl/spear/Makefile1
-rw-r--r--drivers/pinctrl/spear/pinctrl-plgpio.c746
-rw-r--r--drivers/pinctrl/spear/pinctrl-spear.c107
-rw-r--r--drivers/pinctrl/spear/pinctrl-spear.h46
-rw-r--r--drivers/pinctrl/spear/pinctrl-spear1310.c629
-rw-r--r--drivers/pinctrl/spear/pinctrl-spear1340.c41
-rw-r--r--drivers/pinctrl/spear/pinctrl-spear300.c2
-rw-r--r--drivers/pinctrl/spear/pinctrl-spear310.c2
-rw-r--r--drivers/pinctrl/spear/pinctrl-spear320.c10
-rw-r--r--drivers/pinctrl/spear/pinctrl-spear3xx.c37
-rw-r--r--drivers/pinctrl/spear/pinctrl-spear3xx.h1
37 files changed, 1819 insertions, 318 deletions
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index 4787f0e4597d..6d5a50bcabe6 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -152,8 +152,8 @@ config PINCTRL_SINGLE
This selects the device tree based generic pinctrl driver.
config PINCTRL_SIRF
- bool "CSR SiRFprimaII pin controller driver"
- depends on ARCH_PRIMA2
+ bool "CSR SiRFprimaII/SiRFmarco pin controller driver"
+ depends on ARCH_SIRF
select PINMUX
config PINCTRL_TEGRA
@@ -188,34 +188,16 @@ config PINCTRL_COH901
config PINCTRL_SAMSUNG
bool "Samsung pinctrl driver"
+ depends on OF && GPIOLIB
select PINMUX
select PINCONF
config PINCTRL_EXYNOS4
bool "Pinctrl driver data for Exynos4 SoC"
+ depends on OF && GPIOLIB
select PINCTRL_SAMSUNG
-config PINCTRL_MVEBU
- bool
- depends on ARCH_MVEBU
- select PINMUX
- select PINCONF
-
-config PINCTRL_DOVE
- bool
- select PINCTRL_MVEBU
-
-config PINCTRL_KIRKWOOD
- bool
- select PINCTRL_MVEBU
-
-config PINCTRL_ARMADA_370
- bool
- select PINCTRL_MVEBU
-
-config PINCTRL_ARMADA_XP
- bool
- select PINCTRL_MVEBU
+source "drivers/pinctrl/mvebu/Kconfig"
source "drivers/pinctrl/spear/Kconfig"
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index 78a191c85adc..f95f5ed923be 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -37,12 +37,8 @@ obj-$(CONFIG_PINCTRL_U300) += pinctrl-u300.o
obj-$(CONFIG_PINCTRL_COH901) += pinctrl-coh901.o
obj-$(CONFIG_PINCTRL_SAMSUNG) += pinctrl-samsung.o
obj-$(CONFIG_PINCTRL_EXYNOS4) += pinctrl-exynos.o
-obj-$(CONFIG_PINCTRL_MVEBU) += pinctrl-mvebu.o
-obj-$(CONFIG_PINCTRL_DOVE) += pinctrl-dove.o
-obj-$(CONFIG_PINCTRL_KIRKWOOD) += pinctrl-kirkwood.o
-obj-$(CONFIG_PINCTRL_ARMADA_370) += pinctrl-armada-370.o
-obj-$(CONFIG_PINCTRL_ARMADA_XP) += pinctrl-armada-xp.o
obj-$(CONFIG_PINCTRL_XWAY) += pinctrl-xway.o
obj-$(CONFIG_PINCTRL_LANTIQ) += pinctrl-lantiq.o
+obj-$(CONFIG_PLAT_ORION) += mvebu/
obj-$(CONFIG_PLAT_SPEAR) += spear/
diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c
index 0f1ec9e8ff14..71db586b2afd 100644
--- a/drivers/pinctrl/core.c
+++ b/drivers/pinctrl/core.c
@@ -345,6 +345,33 @@ void pinctrl_add_gpio_ranges(struct pinctrl_dev *pctldev,
}
EXPORT_SYMBOL_GPL(pinctrl_add_gpio_ranges);
+struct pinctrl_dev *find_pinctrl_and_add_gpio_range(const char *devname,
+ struct pinctrl_gpio_range *range)
+{
+ struct pinctrl_dev *pctldev = get_pinctrl_dev_from_devname(devname);
+
+ if (!pctldev)
+ return NULL;
+
+ pinctrl_add_gpio_range(pctldev, range);
+ return pctldev;
+}
+EXPORT_SYMBOL_GPL(find_pinctrl_and_add_gpio_range);
+
+/**
+ * pinctrl_remove_gpio_range() - remove a range of GPIOs fro a pin controller
+ * @pctldev: pin controller device to remove the range from
+ * @range: the GPIO range to remove
+ */
+void pinctrl_remove_gpio_range(struct pinctrl_dev *pctldev,
+ struct pinctrl_gpio_range *range)
+{
+ mutex_lock(&pinctrl_mutex);
+ list_del(&range->node);
+ mutex_unlock(&pinctrl_mutex);
+}
+EXPORT_SYMBOL_GPL(pinctrl_remove_gpio_range);
+
/**
* pinctrl_get_group_selector() - returns the group selector for a group
* @pctldev: the pin controller handling the group
@@ -563,6 +590,8 @@ static int add_setting(struct pinctrl *p, struct pinctrl_map const *map)
return -EPROBE_DEFER;
}
+ setting->dev_name = map->dev_name;
+
switch (map->type) {
case PIN_MAP_TYPE_MUX_GROUP:
ret = pinmux_map_to_setting(map, setting);
@@ -1061,8 +1090,10 @@ static int pinctrl_groups_show(struct seq_file *s, void *what)
seq_printf(s, "group: %s\n", gname);
for (i = 0; i < num_pins; i++) {
pname = pin_get_name(pctldev, pins[i]);
- if (WARN_ON(!pname))
+ if (WARN_ON(!pname)) {
+ mutex_unlock(&pinctrl_mutex);
return -EINVAL;
+ }
seq_printf(s, "pin %d (%s)\n", pins[i], pname);
}
seq_puts(s, "\n");
diff --git a/drivers/pinctrl/core.h b/drivers/pinctrl/core.h
index 1f40ff68a8c4..12f5694f3d5d 100644
--- a/drivers/pinctrl/core.h
+++ b/drivers/pinctrl/core.h
@@ -105,12 +105,14 @@ struct pinctrl_setting_configs {
* @type: the type of setting
* @pctldev: pin control device handling to be programmed. Not used for
* PIN_MAP_TYPE_DUMMY_STATE.
+ * @dev_name: the name of the device using this state
* @data: Data specific to the setting type
*/
struct pinctrl_setting {
struct list_head node;
enum pinctrl_map_type type;
struct pinctrl_dev *pctldev;
+ const char *dev_name;
union {
struct pinctrl_setting_mux mux;
struct pinctrl_setting_configs configs;
diff --git a/drivers/pinctrl/devicetree.c b/drivers/pinctrl/devicetree.c
index fcb1de45473c..fe2d1af7cfa0 100644
--- a/drivers/pinctrl/devicetree.c
+++ b/drivers/pinctrl/devicetree.c
@@ -106,6 +106,17 @@ static struct pinctrl_dev *find_pinctrl_by_of_node(struct device_node *np)
return NULL;
}
+struct pinctrl_dev *of_pinctrl_get(struct device_node *np)
+{
+ struct pinctrl_dev *pctldev;
+
+ pctldev = find_pinctrl_by_of_node(np);
+ if (!pctldev)
+ return NULL;
+
+ return pctldev;
+}
+
static int dt_to_map_one_config(struct pinctrl *p, const char *statename,
struct device_node *np_config)
{
diff --git a/drivers/pinctrl/mvebu/Kconfig b/drivers/pinctrl/mvebu/Kconfig
new file mode 100644
index 000000000000..366fa541ee91
--- /dev/null
+++ b/drivers/pinctrl/mvebu/Kconfig
@@ -0,0 +1,24 @@
+if PLAT_ORION
+
+config PINCTRL_MVEBU
+ bool
+ select PINMUX
+ select PINCONF
+
+config PINCTRL_DOVE
+ bool
+ select PINCTRL_MVEBU
+
+config PINCTRL_KIRKWOOD
+ bool
+ select PINCTRL_MVEBU
+
+config PINCTRL_ARMADA_370
+ bool
+ select PINCTRL_MVEBU
+
+config PINCTRL_ARMADA_XP
+ bool
+ select PINCTRL_MVEBU
+
+endif
diff --git a/drivers/pinctrl/mvebu/Makefile b/drivers/pinctrl/mvebu/Makefile
new file mode 100644
index 000000000000..37c253297af0
--- /dev/null
+++ b/drivers/pinctrl/mvebu/Makefile
@@ -0,0 +1,5 @@
+obj-$(CONFIG_PINCTRL_MVEBU) += pinctrl-mvebu.o
+obj-$(CONFIG_PINCTRL_DOVE) += pinctrl-dove.o
+obj-$(CONFIG_PINCTRL_KIRKWOOD) += pinctrl-kirkwood.o
+obj-$(CONFIG_PINCTRL_ARMADA_370) += pinctrl-armada-370.o
+obj-$(CONFIG_PINCTRL_ARMADA_XP) += pinctrl-armada-xp.o
diff --git a/drivers/pinctrl/pinctrl-armada-370.c b/drivers/pinctrl/mvebu/pinctrl-armada-370.c
index c907647de6ad..c907647de6ad 100644
--- a/drivers/pinctrl/pinctrl-armada-370.c
+++ b/drivers/pinctrl/mvebu/pinctrl-armada-370.c
diff --git a/drivers/pinctrl/pinctrl-armada-xp.c b/drivers/pinctrl/mvebu/pinctrl-armada-xp.c
index 40bd52a46b4e..40bd52a46b4e 100644
--- a/drivers/pinctrl/pinctrl-armada-xp.c
+++ b/drivers/pinctrl/mvebu/pinctrl-armada-xp.c
diff --git a/drivers/pinctrl/pinctrl-dove.c b/drivers/pinctrl/mvebu/pinctrl-dove.c
index ffe74b27d66d..ffe74b27d66d 100644
--- a/drivers/pinctrl/pinctrl-dove.c
+++ b/drivers/pinctrl/mvebu/pinctrl-dove.c
diff --git a/drivers/pinctrl/pinctrl-kirkwood.c b/drivers/pinctrl/mvebu/pinctrl-kirkwood.c
index 9a74ef674a0e..9a74ef674a0e 100644
--- a/drivers/pinctrl/pinctrl-kirkwood.c
+++ b/drivers/pinctrl/mvebu/pinctrl-kirkwood.c
diff --git a/drivers/pinctrl/pinctrl-mvebu.c b/drivers/pinctrl/mvebu/pinctrl-mvebu.c
index 8e6266c6249a..6c44b7e8964c 100644
--- a/drivers/pinctrl/pinctrl-mvebu.c
+++ b/drivers/pinctrl/mvebu/pinctrl-mvebu.c
@@ -24,7 +24,6 @@
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>
-#include "core.h"
#include "pinctrl-mvebu.h"
#define MPPS_PER_REG 8
diff --git a/drivers/pinctrl/pinctrl-mvebu.h b/drivers/pinctrl/mvebu/pinctrl-mvebu.h
index 90bd3beee860..90bd3beee860 100644
--- a/drivers/pinctrl/pinctrl-mvebu.h
+++ b/drivers/pinctrl/mvebu/pinctrl-mvebu.h
diff --git a/drivers/pinctrl/pinconf.c b/drivers/pinctrl/pinconf.c
index 43f474cdc110..baee2cc46a17 100644
--- a/drivers/pinctrl/pinconf.c
+++ b/drivers/pinctrl/pinconf.c
@@ -537,8 +537,6 @@ static int pinconf_groups_show(struct seq_file *s, void *what)
seq_puts(s, "Pin config settings per pin group\n");
seq_puts(s, "Format: group (name): configs\n");
- mutex_lock(&pinctrl_mutex);
-
while (selector < ngroups) {
const char *gname = pctlops->get_group_name(pctldev, selector);
@@ -549,8 +547,6 @@ static int pinconf_groups_show(struct seq_file *s, void *what)
selector++;
}
- mutex_unlock(&pinctrl_mutex);
-
return 0;
}
diff --git a/drivers/pinctrl/pinctrl-bcm2835.c b/drivers/pinctrl/pinctrl-bcm2835.c
index a4adee633fa9..7e9be18ec2d2 100644
--- a/drivers/pinctrl/pinctrl-bcm2835.c
+++ b/drivers/pinctrl/pinctrl-bcm2835.c
@@ -29,7 +29,6 @@
#include <linux/irq.h>
#include <linux/irqdesc.h>
#include <linux/irqdomain.h>
-#include <linux/irq.h>
#include <linux/module.h>
#include <linux/of_address.h>
#include <linux/of.h>
@@ -960,7 +959,7 @@ static int __devinit bcm2835_pinctrl_probe(struct platform_device *pdev)
return err;
}
- pc->base = devm_request_and_ioremap(&pdev->dev, &iomem);
+ pc->base = devm_request_and_ioremap(dev, &iomem);
if (!pc->base)
return -EADDRNOTAVAIL;
@@ -1032,7 +1031,7 @@ static int __devinit bcm2835_pinctrl_probe(struct platform_device *pdev)
pc->pctl_dev = pinctrl_register(&bcm2835_pinctrl_desc, dev, pc);
if (!pc->pctl_dev) {
gpiochip_remove(&pc->gpio_chip);
- return PTR_ERR(pc->pctl_dev);
+ return -EINVAL;
}
pc->gpio_range = bcm2835_pinctrl_gpio_range;
diff --git a/drivers/pinctrl/pinctrl-coh901.c b/drivers/pinctrl/pinctrl-coh901.c
index b446c9641212..5c7daf9169e8 100644
--- a/drivers/pinctrl/pinctrl-coh901.c
+++ b/drivers/pinctrl/pinctrl-coh901.c
@@ -13,6 +13,7 @@
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/io.h>
+#include <linux/irqdomain.h>
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/platform_device.h>
@@ -64,10 +65,8 @@ struct u300_gpio {
struct gpio_chip chip;
struct list_head port_list;
struct clk *clk;
- struct resource *memres;
void __iomem *base;
struct device *dev;
- int irq_base;
u32 stride;
/* Register offsets */
u32 pcr;
@@ -83,6 +82,7 @@ struct u300_gpio_port {
struct list_head node;
struct u300_gpio *gpio;
char name[8];
+ struct irq_domain *domain;
int irq;
int number;
u8 toggle_edge_mode;
@@ -314,10 +314,30 @@ static int u300_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
static int u300_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
{
struct u300_gpio *gpio = to_u300_gpio(chip);
- int retirq = gpio->irq_base + offset;
+ int portno = offset >> 3;
+ struct u300_gpio_port *port = NULL;
+ struct list_head *p;
+ int retirq;
+
+ list_for_each(p, &gpio->port_list) {
+ port = list_entry(p, struct u300_gpio_port, node);
+ if (port->number == portno)
+ break;
+ }
+ if (port == NULL) {
+ dev_err(gpio->dev, "could not locate port for GPIO %d IRQ\n",
+ offset);
+ return -EINVAL;
+ }
+
+ /*
+ * The local hwirqs on the port are the lower three bits, there
+ * are exactly 8 IRQs per port since they are 8-bit
+ */
+ retirq = irq_find_mapping(port->domain, (offset & 0x7));
- dev_dbg(gpio->dev, "request IRQ for GPIO %d, return %d\n", offset,
- retirq);
+ dev_dbg(gpio->dev, "request IRQ for GPIO %d, return %d from port %d\n",
+ offset, retirq, port->number);
return retirq;
}
@@ -467,7 +487,7 @@ static int u300_gpio_irq_type(struct irq_data *d, unsigned trigger)
{
struct u300_gpio_port *port = irq_data_get_irq_chip_data(d);
struct u300_gpio *gpio = port->gpio;
- int offset = d->irq - gpio->irq_base;
+ int offset = (port->number << 3) + d->hwirq;
u32 val;
if ((trigger & IRQF_TRIGGER_RISING) &&
@@ -503,10 +523,12 @@ static void u300_gpio_irq_enable(struct irq_data *d)
{
struct u300_gpio_port *port = irq_data_get_irq_chip_data(d);
struct u300_gpio *gpio = port->gpio;
- int offset = d->irq - gpio->irq_base;
+ int offset = (port->number << 3) + d->hwirq;
u32 val;
unsigned long flags;
+ dev_dbg(gpio->dev, "enable IRQ for hwirq %lu on port %s, offset %d\n",
+ d->hwirq, port->name, offset);
local_irq_save(flags);
val = readl(U300_PIN_REG(offset, ien));
writel(val | U300_PIN_BIT(offset), U300_PIN_REG(offset, ien));
@@ -517,7 +539,7 @@ static void u300_gpio_irq_disable(struct irq_data *d)
{
struct u300_gpio_port *port = irq_data_get_irq_chip_data(d);
struct u300_gpio *gpio = port->gpio;
- int offset = d->irq - gpio->irq_base;
+ int offset = (port->number << 3) + d->hwirq;
u32 val;
unsigned long flags;
@@ -555,8 +577,7 @@ static void u300_gpio_irq_handler(unsigned irq, struct irq_desc *desc)
int irqoffset;
for_each_set_bit(irqoffset, &val, U300_GPIO_PINS_PER_PORT) {
- int pin_irq = gpio->irq_base + (port->number << 3)
- + irqoffset;
+ int pin_irq = irq_find_mapping(port->domain, irqoffset);
int offset = pinoffset + irqoffset;
dev_dbg(gpio->dev, "GPIO IRQ %d on pin %d\n",
@@ -631,6 +652,8 @@ static inline void u300_gpio_free_ports(struct u300_gpio *gpio)
list_for_each_safe(p, n, &gpio->port_list) {
port = list_entry(p, struct u300_gpio_port, node);
list_del(&port->node);
+ if (port->domain)
+ irq_domain_remove(port->domain);
kfree(port);
}
}
@@ -639,56 +662,46 @@ static int __init u300_gpio_probe(struct platform_device *pdev)
{
struct u300_gpio_platform *plat = dev_get_platdata(&pdev->dev);
struct u300_gpio *gpio;
+ struct resource *memres;
int err = 0;
int portno;
u32 val;
u32 ifr;
int i;
- gpio = kzalloc(sizeof(struct u300_gpio), GFP_KERNEL);
- if (gpio == NULL) {
- dev_err(&pdev->dev, "failed to allocate memory\n");
+ gpio = devm_kzalloc(&pdev->dev, sizeof(struct u300_gpio), GFP_KERNEL);
+ if (gpio == NULL)
return -ENOMEM;
- }
gpio->chip = u300_gpio_chip;
gpio->chip.ngpio = plat->ports * U300_GPIO_PINS_PER_PORT;
- gpio->irq_base = plat->gpio_irq_base;
gpio->chip.dev = &pdev->dev;
gpio->chip.base = plat->gpio_base;
gpio->dev = &pdev->dev;
- /* Get GPIO clock */
- gpio->clk = clk_get(gpio->dev, NULL);
+ memres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!memres) {
+ dev_err(gpio->dev, "could not get GPIO memory resource\n");
+ return -ENODEV;
+ }
+
+ gpio->base = devm_request_and_ioremap(&pdev->dev, memres);
+ if (!gpio->base) {
+ dev_err(gpio->dev, "could not get remap memory\n");
+ return -ENOMEM;
+ }
+
+ gpio->clk = devm_clk_get(gpio->dev, NULL);
if (IS_ERR(gpio->clk)) {
err = PTR_ERR(gpio->clk);
dev_err(gpio->dev, "could not get GPIO clock\n");
- goto err_no_clk;
+ return err;
}
+
err = clk_prepare_enable(gpio->clk);
if (err) {
dev_err(gpio->dev, "could not enable GPIO clock\n");
- goto err_no_clk_enable;
- }
-
- gpio->memres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!gpio->memres) {
- dev_err(gpio->dev, "could not get GPIO memory resource\n");
- err = -ENODEV;
- goto err_no_resource;
- }
-
- if (!request_mem_region(gpio->memres->start,
- resource_size(gpio->memres),
- "GPIO Controller")) {
- err = -ENODEV;
- goto err_no_ioregion;
- }
-
- gpio->base = ioremap(gpio->memres->start, resource_size(gpio->memres));
- if (!gpio->base) {
- err = -ENOMEM;
- goto err_no_ioremap;
+ return err;
}
dev_info(gpio->dev,
@@ -732,18 +745,26 @@ static int __init u300_gpio_probe(struct platform_device *pdev)
port->irq = platform_get_irq_byname(pdev,
port->name);
- dev_dbg(gpio->dev, "register IRQ %d for %s\n", port->irq,
+ dev_dbg(gpio->dev, "register IRQ %d for port %s\n", port->irq,
port->name);
+ port->domain = irq_domain_add_linear(pdev->dev.of_node,
+ U300_GPIO_PINS_PER_PORT,
+ &irq_domain_simple_ops,
+ port);
+ if (!port->domain)
+ goto err_no_domain;
+
irq_set_chained_handler(port->irq, u300_gpio_irq_handler);
irq_set_handler_data(port->irq, port);
/* For each GPIO pin set the unique IRQ handler */
for (i = 0; i < U300_GPIO_PINS_PER_PORT; i++) {
- int irqno = gpio->irq_base + (portno << 3) + i;
+ int irqno = irq_create_mapping(port->domain, i);
- dev_dbg(gpio->dev, "handler for IRQ %d on %s\n",
- irqno, port->name);
+ dev_dbg(gpio->dev, "GPIO%d on port %s gets IRQ %d\n",
+ gpio->chip.base + (port->number << 3) + i,
+ port->name, irqno);
irq_set_chip_and_handler(irqno, &u300_gpio_irqchip,
handle_simple_irq);
set_irq_flags(irqno, IRQF_VALID);
@@ -776,18 +797,10 @@ static int __init u300_gpio_probe(struct platform_device *pdev)
err_no_pinctrl:
err = gpiochip_remove(&gpio->chip);
err_no_chip:
+err_no_domain:
err_no_port:
u300_gpio_free_ports(gpio);
- iounmap(gpio->base);
-err_no_ioremap:
- release_mem_region(gpio->memres->start, resource_size(gpio->memres));
-err_no_ioregion:
-err_no_resource:
clk_disable_unprepare(gpio->clk);
-err_no_clk_enable:
- clk_put(gpio->clk);
-err_no_clk:
- kfree(gpio);
dev_info(&pdev->dev, "module ERROR:%d\n", err);
return err;
}
@@ -806,13 +819,8 @@ static int __exit u300_gpio_remove(struct platform_device *pdev)
return err;
}
u300_gpio_free_ports(gpio);
- iounmap(gpio->base);
- release_mem_region(gpio->memres->start,
- resource_size(gpio->memres));
clk_disable_unprepare(gpio->clk);
- clk_put(gpio->clk);
platform_set_drvdata(pdev, NULL);
- kfree(gpio);
return 0;
}
diff --git a/drivers/pinctrl/pinctrl-exynos.c b/drivers/pinctrl/pinctrl-exynos.c
index 21362f48d370..6ff665209a4c 100644
--- a/drivers/pinctrl/pinctrl-exynos.c
+++ b/drivers/pinctrl/pinctrl-exynos.c
@@ -36,6 +36,7 @@
/* list of external wakeup controllers supported */
static const struct of_device_id exynos_wkup_irq_ids[] = {
{ .compatible = "samsung,exynos4210-wakeup-eint", },
+ { }
};
static void exynos_gpio_irq_unmask(struct irq_data *irqd)
diff --git a/drivers/pinctrl/pinctrl-nomadik.c b/drivers/pinctrl/pinctrl-nomadik.c
index fec9c30133d4..cf82d9ce4dee 100644
--- a/drivers/pinctrl/pinctrl-nomadik.c
+++ b/drivers/pinctrl/pinctrl-nomadik.c
@@ -30,7 +30,20 @@
#include <linux/pinctrl/pinconf.h>
/* Since we request GPIOs from ourself */
#include <linux/pinctrl/consumer.h>
+/*
+ * For the U8500 archs, use the PRCMU register interface, for the older
+ * Nomadik, provide some stubs. The functions using these will only be
+ * called on the U8500 series.
+ */
+#ifdef CONFIG_ARCH_U8500
#include <linux/mfd/dbx500-prcmu.h>
+#else
+static inline u32 prcmu_read(unsigned int reg) {
+ return 0;
+}
+static inline void prcmu_write(unsigned int reg, u32 value) {}
+static inline void prcmu_write_masked(unsigned int reg, u32 mask, u32 value) {}
+#endif
#include <asm/mach/irq.h>
@@ -1043,7 +1056,7 @@ static int nmk_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
struct nmk_gpio_chip *nmk_chip =
container_of(chip, struct nmk_gpio_chip, chip);
- return irq_find_mapping(nmk_chip->domain, offset);
+ return irq_create_mapping(nmk_chip->domain, offset);
}
#ifdef CONFIG_DEBUG_FS
@@ -1268,6 +1281,7 @@ static int __devinit nmk_gpio_probe(struct platform_device *dev)
struct clk *clk;
int secondary_irq;
void __iomem *base;
+ int irq_start = 0;
int irq;
int ret;
@@ -1371,19 +1385,11 @@ static int __devinit nmk_gpio_probe(struct platform_device *dev)
platform_set_drvdata(dev, nmk_chip);
- if (np) {
- /* The DT case will just grab a set of IRQ numbers */
- nmk_chip->domain = irq_domain_add_linear(np, NMK_GPIO_PER_CHIP,
- &nmk_gpio_irq_simple_ops, nmk_chip);
- } else {
- /* Non-DT legacy mode, use hardwired IRQ numbers */
- int irq_start;
-
+ if (!np)
irq_start = NOMADIK_GPIO_TO_IRQ(pdata->first_gpio);
- nmk_chip->domain = irq_domain_add_simple(NULL,
+ nmk_chip->domain = irq_domain_add_simple(np,
NMK_GPIO_PER_CHIP, irq_start,
&nmk_gpio_irq_simple_ops, nmk_chip);
- }
if (!nmk_chip->domain) {
dev_err(&dev->dev, "failed to create irqdomain\n");
ret = -ENOSYS;
diff --git a/drivers/pinctrl/pinctrl-samsung.c b/drivers/pinctrl/pinctrl-samsung.c
index dd108a94acf9..861cd5f04d5e 100644
--- a/drivers/pinctrl/pinctrl-samsung.c
+++ b/drivers/pinctrl/pinctrl-samsung.c
@@ -513,7 +513,7 @@ static int samsung_gpio_direction_output(struct gpio_chip *gc, unsigned offset,
* Parse the pin names listed in the 'samsung,pins' property and convert it
* into a list of gpio numbers are create a pin group from it.
*/
-static int __init samsung_pinctrl_parse_dt_pins(struct platform_device *pdev,
+static int __devinit samsung_pinctrl_parse_dt_pins(struct platform_device *pdev,
struct device_node *cfg_np, struct pinctrl_desc *pctl,
unsigned int **pin_list, unsigned int *npins)
{
@@ -560,7 +560,7 @@ static int __init samsung_pinctrl_parse_dt_pins(struct platform_device *pdev,
* from device node of the pin-controller. A pin group is formed with all
* the pins listed in the "samsung,pins" property.
*/
-static int __init samsung_pinctrl_parse_dt(struct platform_device *pdev,
+static int __devinit samsung_pinctrl_parse_dt(struct platform_device *pdev,
struct samsung_pinctrl_drv_data *drvdata)
{
struct device *dev = &pdev->dev;
@@ -655,7 +655,7 @@ static int __init samsung_pinctrl_parse_dt(struct platform_device *pdev,
}
/* register the pinctrl interface with the pinctrl subsystem */
-static int __init samsung_pinctrl_register(struct platform_device *pdev,
+static int __devinit samsung_pinctrl_register(struct platform_device *pdev,
struct samsung_pinctrl_drv_data *drvdata)
{
struct pinctrl_desc *ctrldesc = &drvdata->pctl;
@@ -729,7 +729,7 @@ static int __init samsung_pinctrl_register(struct platform_device *pdev,
}
/* register the gpiolib interface with the gpiolib subsystem */
-static int __init samsung_gpiolib_register(struct platform_device *pdev,
+static int __devinit samsung_gpiolib_register(struct platform_device *pdev,
struct samsung_pinctrl_drv_data *drvdata)
{
struct gpio_chip *gc;
@@ -762,7 +762,7 @@ static int __init samsung_gpiolib_register(struct platform_device *pdev,
}
/* unregister the gpiolib interface with the gpiolib subsystem */
-static int __init samsung_gpiolib_unregister(struct platform_device *pdev,
+static int __devinit samsung_gpiolib_unregister(struct platform_device *pdev,
struct samsung_pinctrl_drv_data *drvdata)
{
int ret = gpiochip_remove(drvdata->gc);
diff --git a/drivers/pinctrl/pinctrl-sirf.c b/drivers/pinctrl/pinctrl-sirf.c
index 675497c15149..a3905e58d1b3 100644
--- a/drivers/pinctrl/pinctrl-sirf.c
+++ b/drivers/pinctrl/pinctrl-sirf.c
@@ -32,10 +32,10 @@
#define SIRFSOC_NUM_PADS 622
#define SIRFSOC_RSC_PIN_MUX 0x4
-#define SIRFSOC_GPIO_PAD_EN(g) ((g)*0x100 + 0x84)
+#define SIRFSOC_GPIO_PAD_EN(g) ((g)*0x100 + 0x84)
+#define SIRFSOC_GPIO_PAD_EN_CLR(g) ((g)*0x100 + 0x90)
#define SIRFSOC_GPIO_CTRL(g, i) ((g)*0x100 + (i)*4)
#define SIRFSOC_GPIO_DSP_EN0 (0x80)
-#define SIRFSOC_GPIO_PAD_EN(g) ((g)*0x100 + 0x84)
#define SIRFSOC_GPIO_INT_STATUS(g) ((g)*0x100 + 0x8C)
#define SIRFSOC_GPIO_CTL_INTR_LOW_MASK 0x1
@@ -60,6 +60,7 @@ struct sirfsoc_gpio_bank {
int id;
int parent_irq;
spinlock_t lock;
+ bool is_marco; /* for marco, some registers are different with prima2 */
};
static struct sirfsoc_gpio_bank sgpio_bank[SIRFSOC_GPIO_NO_OF_BANKS];
@@ -191,6 +192,7 @@ struct sirfsoc_pmx {
struct pinctrl_dev *pmx;
void __iomem *gpio_virtbase;
void __iomem *rsc_virtbase;
+ bool is_marco;
};
/* SIRFSOC_GPIO_PAD_EN set */
@@ -1088,12 +1090,21 @@ static void sirfsoc_pinmux_endisable(struct sirfsoc_pmx *spmx, unsigned selector
for (i = 0; i < mux->muxmask_counts; i++) {
u32 muxval;
- muxval = readl(spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(mask[i].group));
- if (enable)
- muxval = muxval & ~mask[i].mask;
- else
- muxval = muxval | mask[i].mask;
- writel(muxval, spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(mask[i].group));
+ if (!spmx->is_marco) {
+ muxval = readl(spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(mask[i].group));
+ if (enable)
+ muxval = muxval & ~mask[i].mask;
+ else
+ muxval = muxval | mask[i].mask;
+ writel(muxval, spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(mask[i].group));
+ } else {
+ if (enable)
+ writel(mask[i].mask, spmx->gpio_virtbase +
+ SIRFSOC_GPIO_PAD_EN_CLR(mask[i].group));
+ else
+ writel(mask[i].mask, spmx->gpio_virtbase +
+ SIRFSOC_GPIO_PAD_EN(mask[i].group));
+ }
}
if (mux->funcmask && enable) {
@@ -1158,9 +1169,14 @@ static int sirfsoc_pinmux_request_gpio(struct pinctrl_dev *pmxdev,
spmx = pinctrl_dev_get_drvdata(pmxdev);
- muxval = readl(spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(group));
- muxval = muxval | (1 << (offset - range->pin_base));
- writel(muxval, spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(group));
+ if (!spmx->is_marco) {
+ muxval = readl(spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(group));
+ muxval = muxval | (1 << (offset - range->pin_base));
+ writel(muxval, spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(group));
+ } else {
+ writel(1 << (offset - range->pin_base), spmx->gpio_virtbase +
+ SIRFSOC_GPIO_PAD_EN(group));
+ }
return 0;
}
@@ -1218,6 +1234,7 @@ static void __iomem *sirfsoc_rsc_of_iomap(void)
{
const struct of_device_id rsc_ids[] = {
{ .compatible = "sirf,prima2-rsc" },
+ { .compatible = "sirf,marco-rsc" },
{}
};
struct device_node *np;
@@ -1259,6 +1276,9 @@ static int __devinit sirfsoc_pinmux_probe(struct platform_device *pdev)
goto out_no_rsc_remap;
}
+ if (of_device_is_compatible(np, "sirf,marco-pinctrl"))
+ spmx->is_marco = 1;
+
/* Now register the pin controller and all pins it handles */
spmx->pmx = pinctrl_register(&sirfsoc_pinmux_desc, &pdev->dev, spmx);
if (!spmx->pmx) {
@@ -1287,6 +1307,7 @@ out_no_gpio_remap:
static const struct of_device_id pinmux_ids[] __devinitconst = {
{ .compatible = "sirf,prima2-pinctrl" },
+ { .compatible = "sirf,marco-pinctrl" },
{}
};
@@ -1323,41 +1344,6 @@ static inline struct sirfsoc_gpio_bank *sirfsoc_gpio_to_bank(unsigned int gpio)
return &sgpio_bank[gpio / SIRFSOC_GPIO_BANK_SIZE];
}
-void sirfsoc_gpio_set_pull(unsigned gpio, unsigned mode)
-{
- struct sirfsoc_gpio_bank *bank = sirfsoc_gpio_to_bank(gpio);
- int idx = sirfsoc_gpio_to_offset(gpio);
- u32 val, offset;
- unsigned long flags;
-
- offset = SIRFSOC_GPIO_CTRL(bank->id, idx);
-
- spin_lock_irqsave(&sgpio_lock, flags);
-
- val = readl(bank->chip.regs + offset);
-
- switch (mode) {
- case SIRFSOC_GPIO_PULL_NONE:
- val &= ~SIRFSOC_GPIO_CTL_PULL_MASK;
- break;
- case SIRFSOC_GPIO_PULL_UP:
- val |= SIRFSOC_GPIO_CTL_PULL_MASK;
- val |= SIRFSOC_GPIO_CTL_PULL_HIGH;
- break;
- case SIRFSOC_GPIO_PULL_DOWN:
- val |= SIRFSOC_GPIO_CTL_PULL_MASK;
- val &= ~SIRFSOC_GPIO_CTL_PULL_HIGH;
- break;
- default:
- break;
- }
-
- writel(val, bank->chip.regs + offset);
-
- spin_unlock_irqrestore(&sgpio_lock, flags);
-}
-EXPORT_SYMBOL(sirfsoc_gpio_set_pull);
-
static inline struct sirfsoc_gpio_bank *sirfsoc_irqchip_to_bank(struct gpio_chip *chip)
{
return container_of(to_of_mm_gpio_chip(chip), struct sirfsoc_gpio_bank, chip);
@@ -1656,8 +1642,8 @@ static void sirfsoc_gpio_set_value(struct gpio_chip *chip, unsigned offset,
spin_unlock_irqrestore(&bank->lock, flags);
}
-int sirfsoc_gpio_irq_map(struct irq_domain *d, unsigned int irq,
- irq_hw_number_t hwirq)
+static int sirfsoc_gpio_irq_map(struct irq_domain *d, unsigned int irq,
+ irq_hw_number_t hwirq)
{
struct sirfsoc_gpio_bank *bank = d->host_data;
@@ -1683,6 +1669,7 @@ static int __devinit sirfsoc_gpio_probe(struct device_node *np)
struct sirfsoc_gpio_bank *bank;
void *regs;
struct platform_device *pdev;
+ bool is_marco = false;
pdev = of_find_device_by_node(np);
if (!pdev)
@@ -1692,6 +1679,9 @@ static int __devinit sirfsoc_gpio_probe(struct device_node *np)
if (!regs)
return -ENOMEM;
+ if (of_device_is_compatible(np, "sirf,marco-pinctrl"))
+ is_marco = 1;
+
for (i = 0; i < SIRFSOC_GPIO_NO_OF_BANKS; i++) {
bank = &sgpio_bank[i];
spin_lock_init(&bank->lock);
@@ -1708,6 +1698,7 @@ static int __devinit sirfsoc_gpio_probe(struct device_node *np)
bank->chip.gc.of_node = np;
bank->chip.regs = regs;
bank->id = i;
+ bank->is_marco = is_marco;
bank->parent_irq = platform_get_irq(pdev, i);
if (bank->parent_irq < 0) {
err = bank->parent_irq;
diff --git a/drivers/pinctrl/pinctrl-tegra.c b/drivers/pinctrl/pinctrl-tegra.c
index 729b686c3ad2..7da0b371fd65 100644
--- a/drivers/pinctrl/pinctrl-tegra.c
+++ b/drivers/pinctrl/pinctrl-tegra.c
@@ -464,7 +464,7 @@ static int tegra_pinconf_reg(struct tegra_pmx *pmx,
*bank = g->drv_bank;
*reg = g->drv_reg;
*bit = g->lpmd_bit;
- *width = 1;
+ *width = 2;
break;
case TEGRA_PINCONF_PARAM_DRIVE_DOWN_STRENGTH:
*bank = g->drv_bank;
diff --git a/drivers/pinctrl/pinctrl-tegra30.c b/drivers/pinctrl/pinctrl-tegra30.c
index 0386fdf0da16..7894f14c7059 100644
--- a/drivers/pinctrl/pinctrl-tegra30.c
+++ b/drivers/pinctrl/pinctrl-tegra30.c
@@ -3345,10 +3345,10 @@ static const struct tegra_function tegra30_functions[] = {
FUNCTION(vi_alt3),
};
-#define MUXCTL_REG_A 0x3000
-#define PINGROUP_REG_A 0x868
+#define DRV_PINGROUP_REG_A 0x868 /* bank 0 */
+#define PINGROUP_REG_A 0x3000 /* bank 1 */
-#define PINGROUP_REG_Y(r) ((r) - MUXCTL_REG_A)
+#define PINGROUP_REG_Y(r) ((r) - PINGROUP_REG_A)
#define PINGROUP_REG_N(r) -1
#define PINGROUP(pg_name, f0, f1, f2, f3, f_safe, r, od, ior) \
@@ -3364,25 +3364,25 @@ static const struct tegra_function tegra30_functions[] = {
}, \
.func_safe = TEGRA_MUX_ ## f_safe, \
.mux_reg = PINGROUP_REG_Y(r), \
- .mux_bank = 0, \
+ .mux_bank = 1, \
.mux_bit = 0, \
.pupd_reg = PINGROUP_REG_Y(r), \
- .pupd_bank = 0, \
+ .pupd_bank = 1, \
.pupd_bit = 2, \
.tri_reg = PINGROUP_REG_Y(r), \
- .tri_bank = 0, \
+ .tri_bank = 1, \
.tri_bit = 4, \
.einput_reg = PINGROUP_REG_Y(r), \
- .einput_bank = 0, \
+ .einput_bank = 1, \
.einput_bit = 5, \
.odrain_reg = PINGROUP_REG_##od(r), \
- .odrain_bank = 0, \
+ .odrain_bank = 1, \
.odrain_bit = 6, \
.lock_reg = PINGROUP_REG_Y(r), \
- .lock_bank = 0, \
+ .lock_bank = 1, \
.lock_bit = 7, \
.ioreset_reg = PINGROUP_REG_##ior(r), \
- .ioreset_bank = 0, \
+ .ioreset_bank = 1, \
.ioreset_bit = 8, \
.drv_reg = -1, \
}
@@ -3401,8 +3401,8 @@ static const struct tegra_function tegra30_functions[] = {
.odrain_reg = -1, \
.lock_reg = -1, \
.ioreset_reg = -1, \
- .drv_reg = ((r) - PINGROUP_REG_A), \
- .drv_bank = 1, \
+ .drv_reg = ((r) - DRV_PINGROUP_REG_A), \
+ .drv_bank = 0, \
.hsm_bit = hsm_b, \
.schmitt_bit = schmitt_b, \
.lpmd_bit = lpmd_b, \
diff --git a/drivers/pinctrl/pinctrl-u300.c b/drivers/pinctrl/pinctrl-u300.c
index 309f5b9a70ec..d756cce588fd 100644
--- a/drivers/pinctrl/pinctrl-u300.c
+++ b/drivers/pinctrl/pinctrl-u300.c
@@ -663,8 +663,6 @@ static const struct pinctrl_pin_desc u300_pads[] = {
struct u300_pmx {
struct device *dev;
struct pinctrl_dev *pctl;
- u32 phybase;
- u32 physize;
void __iomem *virtbase;
};
@@ -1054,9 +1052,8 @@ static struct pinctrl_gpio_range *u300_match_gpio_range(unsigned pin)
return NULL;
}
-int u300_pin_config_get(struct pinctrl_dev *pctldev,
- unsigned pin,
- unsigned long *config)
+static int u300_pin_config_get(struct pinctrl_dev *pctldev, unsigned pin,
+ unsigned long *config)
{
struct pinctrl_gpio_range *range = u300_match_gpio_range(pin);
@@ -1069,9 +1066,8 @@ int u300_pin_config_get(struct pinctrl_dev *pctldev,
config);
}
-int u300_pin_config_set(struct pinctrl_dev *pctldev,
- unsigned pin,
- unsigned long config)
+static int u300_pin_config_set(struct pinctrl_dev *pctldev, unsigned pin,
+ unsigned long config)
{
struct pinctrl_gpio_range *range = u300_match_gpio_range(pin);
int ret;
@@ -1110,7 +1106,6 @@ static int __devinit u300_pmx_probe(struct platform_device *pdev)
struct u300_pmx *upmx;
struct resource *res;
struct gpio_chip *gpio_chip = dev_get_platdata(&pdev->dev);
- int ret;
int i;
/* Create state holders etc for this driver */
@@ -1123,26 +1118,15 @@ static int __devinit u300_pmx_probe(struct platform_device *pdev)
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res)
return -ENOENT;
- upmx->phybase = res->start;
- upmx->physize = resource_size(res);
-
- if (request_mem_region(upmx->phybase, upmx->physize,
- DRIVER_NAME) == NULL) {
- ret = -ENOMEM;
- goto out_no_memregion;
- }
- upmx->virtbase = ioremap(upmx->phybase, upmx->physize);
- if (!upmx->virtbase) {
- ret = -ENOMEM;
- goto out_no_remap;
- }
+ upmx->virtbase = devm_request_and_ioremap(&pdev->dev, res);
+ if (!upmx->virtbase)
+ return -ENOMEM;
upmx->pctl = pinctrl_register(&u300_pmx_desc, &pdev->dev, upmx);
if (!upmx->pctl) {
dev_err(&pdev->dev, "could not register U300 pinmux driver\n");
- ret = -EINVAL;
- goto out_no_pmx;
+ return -EINVAL;
}
/* We will handle a range of GPIO pins */
@@ -1156,14 +1140,6 @@ static int __devinit u300_pmx_probe(struct platform_device *pdev)
dev_info(&pdev->dev, "initialized U300 pin control driver\n");
return 0;
-
-out_no_pmx:
- iounmap(upmx->virtbase);
-out_no_remap:
- platform_set_drvdata(pdev, NULL);
-out_no_memregion:
- release_mem_region(upmx->phybase, upmx->physize);
- return ret;
}
static int __devexit u300_pmx_remove(struct platform_device *pdev)
@@ -1171,8 +1147,6 @@ static int __devexit u300_pmx_remove(struct platform_device *pdev)
struct u300_pmx *upmx = platform_get_drvdata(pdev);
pinctrl_unregister(upmx->pctl);
- iounmap(upmx->virtbase);
- release_mem_region(upmx->phybase, upmx->physize);
platform_set_drvdata(pdev, NULL);
return 0;
diff --git a/drivers/pinctrl/pinctrl-xway.c b/drivers/pinctrl/pinctrl-xway.c
index f8d917d40c92..b9bcaec66223 100644
--- a/drivers/pinctrl/pinctrl-xway.c
+++ b/drivers/pinctrl/pinctrl-xway.c
@@ -17,8 +17,6 @@
#include <linux/ioport.h>
#include <linux/io.h>
#include <linux/device.h>
-#include <linux/module.h>
-#include <linux/io.h>
#include <linux/platform_device.h>
#include "pinctrl-lantiq.h"
diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c
index 9301a7a95eff..0ef01ee2835f 100644
--- a/drivers/pinctrl/pinmux.c
+++ b/drivers/pinctrl/pinmux.c
@@ -314,14 +314,11 @@ int pinmux_map_to_setting(struct pinctrl_map const *map,
{
struct pinctrl_dev *pctldev = setting->pctldev;
const struct pinmux_ops *pmxops = pctldev->desc->pmxops;
- const struct pinctrl_ops *pctlops = pctldev->desc->pctlops;
char const * const *groups;
unsigned num_groups;
int ret;
const char *group;
int i;
- const unsigned *pins;
- unsigned num_pins;
if (!pmxops) {
dev_err(pctldev->dev, "does not support mux function\n");
@@ -376,53 +373,12 @@ int pinmux_map_to_setting(struct pinctrl_map const *map,
}
setting->data.mux.group = ret;
- ret = pctlops->get_group_pins(pctldev, setting->data.mux.group, &pins,
- &num_pins);
- if (ret) {
- dev_err(pctldev->dev,
- "could not get pins for device %s group selector %d\n",
- pinctrl_dev_get_name(pctldev), setting->data.mux.group);
- return -ENODEV;
- }
-
- /* Try to allocate all pins in this group, one by one */
- for (i = 0; i < num_pins; i++) {
- ret = pin_request(pctldev, pins[i], map->dev_name, NULL);
- if (ret) {
- dev_err(pctldev->dev,
- "could not request pin %d on device %s\n",
- pins[i], pinctrl_dev_get_name(pctldev));
- /* On error release all taken pins */
- i--; /* this pin just failed */
- for (; i >= 0; i--)
- pin_free(pctldev, pins[i], NULL);
- return -ENODEV;
- }
- }
-
return 0;
}
void pinmux_free_setting(struct pinctrl_setting const *setting)
{
- struct pinctrl_dev *pctldev = setting->pctldev;
- const struct pinctrl_ops *pctlops = pctldev->desc->pctlops;
- const unsigned *pins;
- unsigned num_pins;
- int ret;
- int i;
-
- ret = pctlops->get_group_pins(pctldev, setting->data.mux.group,
- &pins, &num_pins);
- if (ret) {
- dev_err(pctldev->dev,
- "could not get pins for device %s group selector %d\n",
- pinctrl_dev_get_name(pctldev), setting->data.mux.group);
- return;
- }
-
- for (i = 0; i < num_pins; i++)
- pin_free(pctldev, pins[i], NULL);
+ /* This function is currently unused */
}
int pinmux_enable_setting(struct pinctrl_setting const *setting)
@@ -446,6 +402,22 @@ int pinmux_enable_setting(struct pinctrl_setting const *setting)
num_pins = 0;
}
+ /* Try to allocate all pins in this group, one by one */
+ for (i = 0; i < num_pins; i++) {
+ ret = pin_request(pctldev, pins[i], setting->dev_name, NULL);
+ if (ret) {
+ dev_err(pctldev->dev,
+ "could not request pin %d on device %s\n",
+ pins[i], pinctrl_dev_get_name(pctldev));
+ /* On error release all taken pins */
+ i--; /* this pin just failed */
+ for (; i >= 0; i--)
+ pin_free(pctldev, pins[i], NULL);
+ return -ENODEV;
+ }
+ }
+
+ /* Now that we have acquired the pins, encode the mux setting */
for (i = 0; i < num_pins; i++) {
desc = pin_desc_get(pctldev, pins[i]);
if (desc == NULL) {
@@ -482,6 +454,7 @@ void pinmux_disable_setting(struct pinctrl_setting const *setting)
num_pins = 0;
}
+ /* Flag the descs that no setting is active */
for (i = 0; i < num_pins; i++) {
desc = pin_desc_get(pctldev, pins[i]);
if (desc == NULL) {
@@ -493,6 +466,10 @@ void pinmux_disable_setting(struct pinctrl_setting const *setting)
desc->mux_setting = NULL;
}
+ /* And release the pins */
+ for (i = 0; i < num_pins; i++)
+ pin_free(pctldev, pins[i], NULL);
+
if (ops->disable)
ops->disable(pctldev, setting->data.mux.func, setting->data.mux.group);
}
diff --git a/drivers/pinctrl/spear/Kconfig b/drivers/pinctrl/spear/Kconfig
index 91558791e766..04d93e602674 100644
--- a/drivers/pinctrl/spear/Kconfig
+++ b/drivers/pinctrl/spear/Kconfig
@@ -25,20 +25,31 @@ config PINCTRL_SPEAR310
bool "ST Microelectronics SPEAr310 SoC pin controller driver"
depends on MACH_SPEAR310
select PINCTRL_SPEAR3XX
+ select PINCTRL_SPEAR_PLGPIO
config PINCTRL_SPEAR320
bool "ST Microelectronics SPEAr320 SoC pin controller driver"
depends on MACH_SPEAR320
select PINCTRL_SPEAR3XX
+ select PINCTRL_SPEAR_PLGPIO
config PINCTRL_SPEAR1310
bool "ST Microelectronics SPEAr1310 SoC pin controller driver"
depends on MACH_SPEAR1310
select PINCTRL_SPEAR
+ select PINCTRL_SPEAR_PLGPIO
config PINCTRL_SPEAR1340
bool "ST Microelectronics SPEAr1340 SoC pin controller driver"
depends on MACH_SPEAR1340
select PINCTRL_SPEAR
+ select PINCTRL_SPEAR_PLGPIO
+
+config PINCTRL_SPEAR_PLGPIO
+ bool "SPEAr SoC PLGPIO Controller"
+ depends on GPIOLIB && PINCTRL_SPEAR
+ help
+ Say yes here to support PLGPIO controller on ST Microelectronics SPEAr
+ SoCs.
endif
diff --git a/drivers/pinctrl/spear/Makefile b/drivers/pinctrl/spear/Makefile
index b28a7ba22443..0e400ebeb8ff 100644
--- a/drivers/pinctrl/spear/Makefile
+++ b/drivers/pinctrl/spear/Makefile
@@ -1,5 +1,6 @@
# SPEAr pinmux support
+obj-$(CONFIG_PINCTRL_SPEAR_PLGPIO) += pinctrl-plgpio.o
obj-$(CONFIG_PINCTRL_SPEAR) += pinctrl-spear.o
obj-$(CONFIG_PINCTRL_SPEAR3XX) += pinctrl-spear3xx.o
obj-$(CONFIG_PINCTRL_SPEAR300) += pinctrl-spear300.o
diff --git a/drivers/pinctrl/spear/pinctrl-plgpio.c b/drivers/pinctrl/spear/pinctrl-plgpio.c
new file mode 100644
index 000000000000..1044ad3f3c86
--- /dev/null
+++ b/drivers/pinctrl/spear/pinctrl-plgpio.c
@@ -0,0 +1,746 @@
+/*
+ * SPEAr platform PLGPIO driver
+ *
+ * Copyright (C) 2012 ST Microelectronics
+ * Viresh Kumar <viresh.kumar@linaro.org>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/gpio.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/module.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/platform_device.h>
+#include <linux/pm.h>
+#include <linux/spinlock.h>
+#include <asm/mach/irq.h>
+
+#define MAX_GPIO_PER_REG 32
+#define PIN_OFFSET(pin) (pin % MAX_GPIO_PER_REG)
+#define REG_OFFSET(base, reg, pin) (base + reg + (pin / MAX_GPIO_PER_REG) \
+ * sizeof(int *))
+
+/*
+ * plgpio pins in all machines are not one to one mapped, bitwise with registers
+ * bits. These set of macros define register masks for which below functions
+ * (pin_to_offset and offset_to_pin) are required to be called.
+ */
+#define PTO_ENB_REG 0x001
+#define PTO_WDATA_REG 0x002
+#define PTO_DIR_REG 0x004
+#define PTO_IE_REG 0x008
+#define PTO_RDATA_REG 0x010
+#define PTO_MIS_REG 0x020
+
+struct plgpio_regs {
+ u32 enb; /* enable register */
+ u32 wdata; /* write data register */
+ u32 dir; /* direction set register */
+ u32 rdata; /* read data register */
+ u32 ie; /* interrupt enable register */
+ u32 mis; /* mask interrupt status register */
+ u32 eit; /* edge interrupt type */
+};
+
+/*
+ * struct plgpio: plgpio driver specific structure
+ *
+ * lock: lock for guarding gpio registers
+ * base: base address of plgpio block
+ * irq_base: irq number of plgpio0
+ * chip: gpio framework specific chip information structure
+ * p2o: function ptr for pin to offset conversion. This is required only for
+ * machines where mapping b/w pin and offset is not 1-to-1.
+ * o2p: function ptr for offset to pin conversion. This is required only for
+ * machines where mapping b/w pin and offset is not 1-to-1.
+ * p2o_regs: mask of registers for which p2o and o2p are applicable
+ * regs: register offsets
+ * csave_regs: context save registers for standby/sleep/hibernate cases
+ */
+struct plgpio {
+ spinlock_t lock;
+ void __iomem *base;
+ struct clk *clk;
+ unsigned irq_base;
+ struct irq_domain *irq_domain;
+ struct gpio_chip chip;
+ int (*p2o)(int pin); /* pin_to_offset */
+ int (*o2p)(int offset); /* offset_to_pin */
+ u32 p2o_regs;
+ struct plgpio_regs regs;
+#ifdef CONFIG_PM
+ struct plgpio_regs *csave_regs;
+#endif
+};
+
+/* register manipulation inline functions */
+static inline u32 is_plgpio_set(void __iomem *base, u32 pin, u32 reg)
+{
+ u32 offset = PIN_OFFSET(pin);
+ void __iomem *reg_off = REG_OFFSET(base, reg, pin);
+ u32 val = readl_relaxed(reg_off);
+
+ return !!(val & (1 << offset));
+}
+
+static inline void plgpio_reg_set(void __iomem *base, u32 pin, u32 reg)
+{
+ u32 offset = PIN_OFFSET(pin);
+ void __iomem *reg_off = REG_OFFSET(base, reg, pin);
+ u32 val = readl_relaxed(reg_off);
+
+ writel_relaxed(val | (1 << offset), reg_off);
+}
+
+static inline void plgpio_reg_reset(void __iomem *base, u32 pin, u32 reg)
+{
+ u32 offset = PIN_OFFSET(pin);
+ void __iomem *reg_off = REG_OFFSET(base, reg, pin);
+ u32 val = readl_relaxed(reg_off);
+
+ writel_relaxed(val & ~(1 << offset), reg_off);
+}
+
+/* gpio framework specific routines */
+static int plgpio_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+ struct plgpio *plgpio = container_of(chip, struct plgpio, chip);
+ unsigned long flags;
+
+ /* get correct offset for "offset" pin */
+ if (plgpio->p2o && (plgpio->p2o_regs & PTO_DIR_REG)) {
+ offset = plgpio->p2o(offset);
+ if (offset == -1)
+ return -EINVAL;
+ }
+
+ spin_lock_irqsave(&plgpio->lock, flags);
+ plgpio_reg_set(plgpio->base, offset, plgpio->regs.dir);
+ spin_unlock_irqrestore(&plgpio->lock, flags);
+
+ return 0;
+}
+
+static int plgpio_direction_output(struct gpio_chip *chip, unsigned offset,
+ int value)
+{
+ struct plgpio *plgpio = container_of(chip, struct plgpio, chip);
+ unsigned long flags;
+ unsigned dir_offset = offset, wdata_offset = offset, tmp;
+
+ /* get correct offset for "offset" pin */
+ if (plgpio->p2o && (plgpio->p2o_regs & (PTO_DIR_REG | PTO_WDATA_REG))) {
+ tmp = plgpio->p2o(offset);
+ if (tmp == -1)
+ return -EINVAL;
+
+ if (plgpio->p2o_regs & PTO_DIR_REG)
+ dir_offset = tmp;
+ if (plgpio->p2o_regs & PTO_WDATA_REG)
+ wdata_offset = tmp;
+ }
+
+ spin_lock_irqsave(&plgpio->lock, flags);
+ if (value)
+ plgpio_reg_set(plgpio->base, wdata_offset,
+ plgpio->regs.wdata);
+ else
+ plgpio_reg_reset(plgpio->base, wdata_offset,
+ plgpio->regs.wdata);
+
+ plgpio_reg_reset(plgpio->base, dir_offset, plgpio->regs.dir);
+ spin_unlock_irqrestore(&plgpio->lock, flags);
+
+ return 0;
+}
+
+static int plgpio_get_value(struct gpio_chip *chip, unsigned offset)
+{
+ struct plgpio *plgpio = container_of(chip, struct plgpio, chip);
+
+ if (offset >= chip->ngpio)
+ return -EINVAL;
+
+ /* get correct offset for "offset" pin */
+ if (plgpio->p2o && (plgpio->p2o_regs & PTO_RDATA_REG)) {
+ offset = plgpio->p2o(offset);
+ if (offset == -1)
+ return -EINVAL;
+ }
+
+ return is_plgpio_set(plgpio->base, offset, plgpio->regs.rdata);
+}
+
+static void plgpio_set_value(struct gpio_chip *chip, unsigned offset, int value)
+{
+ struct plgpio *plgpio = container_of(chip, struct plgpio, chip);
+
+ if (offset >= chip->ngpio)
+ return;
+
+ /* get correct offset for "offset" pin */
+ if (plgpio->p2o && (plgpio->p2o_regs & PTO_WDATA_REG)) {
+ offset = plgpio->p2o(offset);
+ if (offset == -1)
+ return;
+ }
+
+ if (value)
+ plgpio_reg_set(plgpio->base, offset, plgpio->regs.wdata);
+ else
+ plgpio_reg_reset(plgpio->base, offset, plgpio->regs.wdata);
+}
+
+static int plgpio_request(struct gpio_chip *chip, unsigned offset)
+{
+ struct plgpio *plgpio = container_of(chip, struct plgpio, chip);
+ int gpio = chip->base + offset;
+ unsigned long flags;
+ int ret = 0;
+
+ if (offset >= chip->ngpio)
+ return -EINVAL;
+
+ ret = pinctrl_request_gpio(gpio);
+ if (ret)
+ return ret;
+
+ if (!IS_ERR(plgpio->clk)) {
+ ret = clk_prepare_enable(plgpio->clk);
+ if (ret)
+ goto err0;
+ }
+
+ if (plgpio->regs.enb == -1)
+ return 0;
+
+ /*
+ * put gpio in IN mode before enabling it. This make enabling gpio safe
+ */
+ ret = plgpio_direction_input(chip, offset);
+ if (ret)
+ goto err1;
+
+ /* get correct offset for "offset" pin */
+ if (plgpio->p2o && (plgpio->p2o_regs & PTO_ENB_REG)) {
+ offset = plgpio->p2o(offset);
+ if (offset == -1) {
+ ret = -EINVAL;
+ goto err1;
+ }
+ }
+
+ spin_lock_irqsave(&plgpio->lock, flags);
+ plgpio_reg_set(plgpio->base, offset, plgpio->regs.enb);
+ spin_unlock_irqrestore(&plgpio->lock, flags);
+ return 0;
+
+err1:
+ clk_disable_unprepare(plgpio->clk);
+err0:
+ pinctrl_free_gpio(gpio);
+ return ret;
+}
+
+static void plgpio_free(struct gpio_chip *chip, unsigned offset)
+{
+ struct plgpio *plgpio = container_of(chip, struct plgpio, chip);
+ int gpio = chip->base + offset;
+ unsigned long flags;
+
+ if (offset >= chip->ngpio)
+ return;
+
+ if (plgpio->regs.enb == -1)
+ goto disable_clk;
+
+ /* get correct offset for "offset" pin */
+ if (plgpio->p2o && (plgpio->p2o_regs & PTO_ENB_REG)) {
+ offset = plgpio->p2o(offset);
+ if (offset == -1)
+ return;
+ }
+
+ spin_lock_irqsave(&plgpio->lock, flags);
+ plgpio_reg_reset(plgpio->base, offset, plgpio->regs.enb);
+ spin_unlock_irqrestore(&plgpio->lock, flags);
+
+disable_clk:
+ if (!IS_ERR(plgpio->clk))
+ clk_disable_unprepare(plgpio->clk);
+
+ pinctrl_free_gpio(gpio);
+}
+
+static int plgpio_to_irq(struct gpio_chip *chip, unsigned offset)
+{
+ struct plgpio *plgpio = container_of(chip, struct plgpio, chip);
+
+ if (plgpio->irq_base < 0)
+ return -EINVAL;
+
+ return irq_find_mapping(plgpio->irq_domain, offset);
+}
+
+/* PLGPIO IRQ */
+static void plgpio_irq_disable(struct irq_data *d)
+{
+ struct plgpio *plgpio = irq_data_get_irq_chip_data(d);
+ int offset = d->irq - plgpio->irq_base;
+ unsigned long flags;
+
+ /* get correct offset for "offset" pin */
+ if (plgpio->p2o && (plgpio->p2o_regs & PTO_IE_REG)) {
+ offset = plgpio->p2o(offset);
+ if (offset == -1)
+ return;
+ }
+
+ spin_lock_irqsave(&plgpio->lock, flags);
+ plgpio_reg_set(plgpio->base, offset, plgpio->regs.ie);
+ spin_unlock_irqrestore(&plgpio->lock, flags);
+}
+
+static void plgpio_irq_enable(struct irq_data *d)
+{
+ struct plgpio *plgpio = irq_data_get_irq_chip_data(d);
+ int offset = d->irq - plgpio->irq_base;
+ unsigned long flags;
+
+ /* get correct offset for "offset" pin */
+ if (plgpio->p2o && (plgpio->p2o_regs & PTO_IE_REG)) {
+ offset = plgpio->p2o(offset);
+ if (offset == -1)
+ return;
+ }
+
+ spin_lock_irqsave(&plgpio->lock, flags);
+ plgpio_reg_reset(plgpio->base, offset, plgpio->regs.ie);
+ spin_unlock_irqrestore(&plgpio->lock, flags);
+}
+
+static int plgpio_irq_set_type(struct irq_data *d, unsigned trigger)
+{
+ struct plgpio *plgpio = irq_data_get_irq_chip_data(d);
+ int offset = d->irq - plgpio->irq_base;
+ void __iomem *reg_off;
+ unsigned int supported_type = 0, val;
+
+ if (offset >= plgpio->chip.ngpio)
+ return -EINVAL;
+
+ if (plgpio->regs.eit == -1)
+ supported_type = IRQ_TYPE_LEVEL_HIGH;
+ else
+ supported_type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING;
+
+ if (!(trigger & supported_type))
+ return -EINVAL;
+
+ if (plgpio->regs.eit == -1)
+ return 0;
+
+ reg_off = REG_OFFSET(plgpio->base, plgpio->regs.eit, offset);
+ val = readl_relaxed(reg_off);
+
+ offset = PIN_OFFSET(offset);
+ if (trigger & IRQ_TYPE_EDGE_RISING)
+ writel_relaxed(val | (1 << offset), reg_off);
+ else
+ writel_relaxed(val & ~(1 << offset), reg_off);
+
+ return 0;
+}
+
+static struct irq_chip plgpio_irqchip = {
+ .name = "PLGPIO",
+ .irq_enable = plgpio_irq_enable,
+ .irq_disable = plgpio_irq_disable,
+ .irq_set_type = plgpio_irq_set_type,
+};
+
+static void plgpio_irq_handler(unsigned irq, struct irq_desc *desc)
+{
+ struct plgpio *plgpio = irq_get_handler_data(irq);
+ struct irq_chip *irqchip = irq_desc_get_chip(desc);
+ int regs_count, count, pin, offset, i = 0;
+ unsigned long pending;
+
+ count = plgpio->chip.ngpio;
+ regs_count = DIV_ROUND_UP(count, MAX_GPIO_PER_REG);
+
+ chained_irq_enter(irqchip, desc);
+ /* check all plgpio MIS registers for a possible interrupt */
+ for (; i < regs_count; i++) {
+ pending = readl_relaxed(plgpio->base + plgpio->regs.mis +
+ i * sizeof(int *));
+ if (!pending)
+ continue;
+
+ /* clear interrupts */
+ writel_relaxed(~pending, plgpio->base + plgpio->regs.mis +
+ i * sizeof(int *));
+ /*
+ * clear extra bits in last register having gpios < MAX/REG
+ * ex: Suppose there are max 102 plgpios. then last register
+ * must have only (102 - MAX_GPIO_PER_REG * 3) = 6 relevant bits
+ * so, we must not take other 28 bits into consideration for
+ * checking interrupt. so clear those bits.
+ */
+ count = count - i * MAX_GPIO_PER_REG;
+ if (count < MAX_GPIO_PER_REG)
+ pending &= (1 << count) - 1;
+
+ for_each_set_bit(offset, &pending, MAX_GPIO_PER_REG) {
+ /* get correct pin for "offset" */
+ if (plgpio->o2p && (plgpio->p2o_regs & PTO_MIS_REG)) {
+ pin = plgpio->o2p(offset);
+ if (pin == -1)
+ continue;
+ } else
+ pin = offset;
+
+ /* get correct irq line number */
+ pin = i * MAX_GPIO_PER_REG + pin;
+ generic_handle_irq(plgpio_to_irq(&plgpio->chip, pin));
+ }
+ }
+ chained_irq_exit(irqchip, desc);
+}
+
+/*
+ * pin to offset and offset to pin converter functions
+ *
+ * In spear310 there is inconsistency among bit positions in plgpio regiseters,
+ * for different plgpio pins. For example: for pin 27, bit offset is 23, pin
+ * 28-33 are not supported, pin 95 has offset bit 95, bit 100 has offset bit 1
+ */
+static int spear310_p2o(int pin)
+{
+ int offset = pin;
+
+ if (pin <= 27)
+ offset += 4;
+ else if (pin <= 33)
+ offset = -1;
+ else if (pin <= 97)
+ offset -= 2;
+ else if (pin <= 101)
+ offset = 101 - pin;
+ else
+ offset = -1;
+
+ return offset;
+}
+
+int spear310_o2p(int offset)
+{
+ if (offset <= 3)
+ return 101 - offset;
+ else if (offset <= 31)
+ return offset - 4;
+ else
+ return offset + 2;
+}
+
+static int __devinit plgpio_probe_dt(struct platform_device *pdev,
+ struct plgpio *plgpio)
+{
+ struct device_node *np = pdev->dev.of_node;
+ int ret = -EINVAL;
+ u32 val;
+
+ if (of_machine_is_compatible("st,spear310")) {
+ plgpio->p2o = spear310_p2o;
+ plgpio->o2p = spear310_o2p;
+ plgpio->p2o_regs = PTO_WDATA_REG | PTO_DIR_REG | PTO_IE_REG |
+ PTO_RDATA_REG | PTO_MIS_REG;
+ }
+
+ if (!of_property_read_u32(np, "st-plgpio,ngpio", &val)) {
+ plgpio->chip.ngpio = val;
+ } else {
+ dev_err(&pdev->dev, "DT: Invalid ngpio field\n");
+ goto end;
+ }
+
+ if (!of_property_read_u32(np, "st-plgpio,enb-reg", &val))
+ plgpio->regs.enb = val;
+ else
+ plgpio->regs.enb = -1;
+
+ if (!of_property_read_u32(np, "st-plgpio,wdata-reg", &val)) {
+ plgpio->regs.wdata = val;
+ } else {
+ dev_err(&pdev->dev, "DT: Invalid wdata reg\n");
+ goto end;
+ }
+
+ if (!of_property_read_u32(np, "st-plgpio,dir-reg", &val)) {
+ plgpio->regs.dir = val;
+ } else {
+ dev_err(&pdev->dev, "DT: Invalid dir reg\n");
+ goto end;
+ }
+
+ if (!of_property_read_u32(np, "st-plgpio,ie-reg", &val)) {
+ plgpio->regs.ie = val;
+ } else {
+ dev_err(&pdev->dev, "DT: Invalid ie reg\n");
+ goto end;
+ }
+
+ if (!of_property_read_u32(np, "st-plgpio,rdata-reg", &val)) {
+ plgpio->regs.rdata = val;
+ } else {
+ dev_err(&pdev->dev, "DT: Invalid rdata reg\n");
+ goto end;
+ }
+
+ if (!of_property_read_u32(np, "st-plgpio,mis-reg", &val)) {
+ plgpio->regs.mis = val;
+ } else {
+ dev_err(&pdev->dev, "DT: Invalid mis reg\n");
+ goto end;
+ }
+
+ if (!of_property_read_u32(np, "st-plgpio,eit-reg", &val))
+ plgpio->regs.eit = val;
+ else
+ plgpio->regs.eit = -1;
+
+ return 0;
+
+end:
+ return ret;
+}
+static int __devinit plgpio_probe(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ struct plgpio *plgpio;
+ struct resource *res;
+ int ret, irq, i;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "invalid IORESOURCE_MEM\n");
+ return -EBUSY;
+ }
+
+ plgpio = devm_kzalloc(&pdev->dev, sizeof(*plgpio), GFP_KERNEL);
+ if (!plgpio) {
+ dev_err(&pdev->dev, "memory allocation fail\n");
+ return -ENOMEM;
+ }
+
+ plgpio->base = devm_request_and_ioremap(&pdev->dev, res);
+ if (!plgpio->base) {
+ dev_err(&pdev->dev, "request and ioremap fail\n");
+ return -ENOMEM;
+ }
+
+ ret = plgpio_probe_dt(pdev, plgpio);
+ if (ret) {
+ dev_err(&pdev->dev, "DT probe failed\n");
+ return ret;
+ }
+
+ plgpio->clk = devm_clk_get(&pdev->dev, NULL);
+ if (IS_ERR(plgpio->clk))
+ dev_warn(&pdev->dev, "clk_get() failed, work without it\n");
+
+#ifdef CONFIG_PM
+ plgpio->csave_regs = devm_kzalloc(&pdev->dev,
+ sizeof(*plgpio->csave_regs) *
+ DIV_ROUND_UP(plgpio->chip.ngpio, MAX_GPIO_PER_REG),
+ GFP_KERNEL);
+ if (!plgpio->csave_regs) {
+ dev_err(&pdev->dev, "csave registers memory allocation fail\n");
+ return -ENOMEM;
+ }
+#endif
+
+ platform_set_drvdata(pdev, plgpio);
+ spin_lock_init(&plgpio->lock);
+
+ plgpio->irq_base = -1;
+ plgpio->chip.base = -1;
+ plgpio->chip.request = plgpio_request;
+ plgpio->chip.free = plgpio_free;
+ plgpio->chip.direction_input = plgpio_direction_input;
+ plgpio->chip.direction_output = plgpio_direction_output;
+ plgpio->chip.get = plgpio_get_value;
+ plgpio->chip.set = plgpio_set_value;
+ plgpio->chip.to_irq = plgpio_to_irq;
+ plgpio->chip.label = dev_name(&pdev->dev);
+ plgpio->chip.dev = &pdev->dev;
+ plgpio->chip.owner = THIS_MODULE;
+
+ ret = gpiochip_add(&plgpio->chip);
+ if (ret) {
+ dev_err(&pdev->dev, "unable to add gpio chip\n");
+ return ret;
+ }
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0) {
+ dev_info(&pdev->dev, "irqs not supported\n");
+ return 0;
+ }
+
+ plgpio->irq_base = irq_alloc_descs(-1, 0, plgpio->chip.ngpio, 0);
+ if (IS_ERR_VALUE(plgpio->irq_base)) {
+ /* we would not support irq for gpio */
+ dev_warn(&pdev->dev, "couldn't allocate irq base\n");
+ return 0;
+ }
+
+ plgpio->irq_domain = irq_domain_add_legacy(np, plgpio->chip.ngpio,
+ plgpio->irq_base, 0, &irq_domain_simple_ops, NULL);
+ if (WARN_ON(!plgpio->irq_domain)) {
+ dev_err(&pdev->dev, "irq domain init failed\n");
+ irq_free_descs(plgpio->irq_base, plgpio->chip.ngpio);
+ ret = -ENXIO;
+ goto remove_gpiochip;
+ }
+
+ irq_set_chained_handler(irq, plgpio_irq_handler);
+ for (i = 0; i < plgpio->chip.ngpio; i++) {
+ irq_set_chip_and_handler(i + plgpio->irq_base, &plgpio_irqchip,
+ handle_simple_irq);
+ set_irq_flags(i + plgpio->irq_base, IRQF_VALID);
+ irq_set_chip_data(i + plgpio->irq_base, plgpio);
+ }
+
+ irq_set_handler_data(irq, plgpio);
+ dev_info(&pdev->dev, "PLGPIO registered with IRQs\n");
+
+ return 0;
+
+remove_gpiochip:
+ dev_info(&pdev->dev, "Remove gpiochip\n");
+ if (gpiochip_remove(&plgpio->chip))
+ dev_err(&pdev->dev, "unable to remove gpiochip\n");
+
+ return ret;
+}
+
+#ifdef CONFIG_PM
+static int plgpio_suspend(struct device *dev)
+{
+ struct plgpio *plgpio = dev_get_drvdata(dev);
+ int i, reg_count = DIV_ROUND_UP(plgpio->chip.ngpio, MAX_GPIO_PER_REG);
+ void __iomem *off;
+
+ for (i = 0; i < reg_count; i++) {
+ off = plgpio->base + i * sizeof(int *);
+
+ if (plgpio->regs.enb != -1)
+ plgpio->csave_regs[i].enb =
+ readl_relaxed(plgpio->regs.enb + off);
+ if (plgpio->regs.eit != -1)
+ plgpio->csave_regs[i].eit =
+ readl_relaxed(plgpio->regs.eit + off);
+ plgpio->csave_regs[i].wdata = readl_relaxed(plgpio->regs.wdata +
+ off);
+ plgpio->csave_regs[i].dir = readl_relaxed(plgpio->regs.dir +
+ off);
+ plgpio->csave_regs[i].ie = readl_relaxed(plgpio->regs.ie + off);
+ }
+
+ return 0;
+}
+
+/*
+ * This is used to correct the values in end registers. End registers contain
+ * extra bits that might be used for other purpose in platform. So, we shouldn't
+ * overwrite these bits. This macro, reads given register again, preserves other
+ * bit values (non-plgpio bits), and retain captured value (plgpio bits).
+ */
+#define plgpio_prepare_reg(__reg, _off, _mask, _tmp) \
+{ \
+ _tmp = readl_relaxed(plgpio->regs.__reg + _off); \
+ _tmp &= ~_mask; \
+ plgpio->csave_regs[i].__reg = \
+ _tmp | (plgpio->csave_regs[i].__reg & _mask); \
+}
+
+static int plgpio_resume(struct device *dev)
+{
+ struct plgpio *plgpio = dev_get_drvdata(dev);
+ int i, reg_count = DIV_ROUND_UP(plgpio->chip.ngpio, MAX_GPIO_PER_REG);
+ void __iomem *off;
+ u32 mask, tmp;
+
+ for (i = 0; i < reg_count; i++) {
+ off = plgpio->base + i * sizeof(int *);
+
+ if (i == reg_count - 1) {
+ mask = (1 << (plgpio->chip.ngpio - i *
+ MAX_GPIO_PER_REG)) - 1;
+
+ if (plgpio->regs.enb != -1)
+ plgpio_prepare_reg(enb, off, mask, tmp);
+
+ if (plgpio->regs.eit != -1)
+ plgpio_prepare_reg(eit, off, mask, tmp);
+
+ plgpio_prepare_reg(wdata, off, mask, tmp);
+ plgpio_prepare_reg(dir, off, mask, tmp);
+ plgpio_prepare_reg(ie, off, mask, tmp);
+ }
+
+ writel_relaxed(plgpio->csave_regs[i].wdata, plgpio->regs.wdata +
+ off);
+ writel_relaxed(plgpio->csave_regs[i].dir, plgpio->regs.dir +
+ off);
+
+ if (plgpio->regs.eit != -1)
+ writel_relaxed(plgpio->csave_regs[i].eit,
+ plgpio->regs.eit + off);
+
+ writel_relaxed(plgpio->csave_regs[i].ie, plgpio->regs.ie + off);
+
+ if (plgpio->regs.enb != -1)
+ writel_relaxed(plgpio->csave_regs[i].enb,
+ plgpio->regs.enb + off);
+ }
+
+ return 0;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(plgpio_dev_pm_ops, plgpio_suspend, plgpio_resume);
+
+static const struct of_device_id plgpio_of_match[] = {
+ { .compatible = "st,spear-plgpio" },
+ {}
+};
+MODULE_DEVICE_TABLE(of, plgpio_of_match);
+
+static struct platform_driver plgpio_driver = {
+ .probe = plgpio_probe,
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "spear-plgpio",
+ .pm = &plgpio_dev_pm_ops,
+ .of_match_table = of_match_ptr(plgpio_of_match),
+ },
+};
+
+static int __init plgpio_init(void)
+{
+ return platform_driver_register(&plgpio_driver);
+}
+subsys_initcall(plgpio_init);
+
+MODULE_AUTHOR("Viresh Kumar <viresh.kumar@linaro.org>");
+MODULE_DESCRIPTION("ST Microlectronics SPEAr PLGPIO driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/pinctrl/spear/pinctrl-spear.c b/drivers/pinctrl/spear/pinctrl-spear.c
index 5d4f44f462f0..cbca6dc66eb7 100644
--- a/drivers/pinctrl/spear/pinctrl-spear.c
+++ b/drivers/pinctrl/spear/pinctrl-spear.c
@@ -18,6 +18,7 @@
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_address.h>
+#include <linux/of_gpio.h>
#include <linux/pinctrl/machine.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>
@@ -38,6 +39,28 @@ static inline void pmx_writel(struct spear_pmx *pmx, u32 val, u32 reg)
writel_relaxed(val, pmx->vbase + reg);
}
+static void muxregs_endisable(struct spear_pmx *pmx,
+ struct spear_muxreg *muxregs, u8 count, bool enable)
+{
+ struct spear_muxreg *muxreg;
+ u32 val, temp, j;
+
+ for (j = 0; j < count; j++) {
+ muxreg = &muxregs[j];
+
+ val = pmx_readl(pmx, muxreg->reg);
+ val &= ~muxreg->mask;
+
+ if (enable)
+ temp = muxreg->val;
+ else
+ temp = ~muxreg->val;
+
+ val |= muxreg->mask & temp;
+ pmx_writel(pmx, val, muxreg->reg);
+ }
+}
+
static int set_mode(struct spear_pmx *pmx, int mode)
{
struct spear_pmx_mode *pmx_mode = NULL;
@@ -70,6 +93,17 @@ static int set_mode(struct spear_pmx *pmx, int mode)
return 0;
}
+void __devinit
+pmx_init_gpio_pingroup_addr(struct spear_gpio_pingroup *gpio_pingroup,
+ unsigned count, u16 reg)
+{
+ int i = 0, j = 0;
+
+ for (; i < count; i++)
+ for (; j < gpio_pingroup[i].nmuxregs; j++)
+ gpio_pingroup[i].muxregs[j].reg = reg;
+}
+
void __devinit pmx_init_addr(struct spear_pinctrl_machdata *machdata, u16 reg)
{
struct spear_pingroup *pgroup;
@@ -216,9 +250,7 @@ static int spear_pinctrl_endisable(struct pinctrl_dev *pctldev,
struct spear_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
const struct spear_pingroup *pgroup;
const struct spear_modemux *modemux;
- struct spear_muxreg *muxreg;
- u32 val, temp;
- int i, j;
+ int i;
bool found = false;
pgroup = pmx->machdata->groups[group];
@@ -233,20 +265,8 @@ static int spear_pinctrl_endisable(struct pinctrl_dev *pctldev,
}
found = true;
- for (j = 0; j < modemux->nmuxregs; j++) {
- muxreg = &modemux->muxregs[j];
-
- val = pmx_readl(pmx, muxreg->reg);
- val &= ~muxreg->mask;
-
- if (enable)
- temp = muxreg->val;
- else
- temp = ~muxreg->val;
-
- val |= temp;
- pmx_writel(pmx, val, muxreg->reg);
- }
+ muxregs_endisable(pmx, modemux->muxregs, modemux->nmuxregs,
+ enable);
}
if (!found) {
@@ -270,12 +290,65 @@ static void spear_pinctrl_disable(struct pinctrl_dev *pctldev,
spear_pinctrl_endisable(pctldev, function, group, false);
}
+/* gpio with pinmux */
+static struct spear_gpio_pingroup *get_gpio_pingroup(struct spear_pmx *pmx,
+ unsigned pin)
+{
+ struct spear_gpio_pingroup *gpio_pingroup;
+ int i = 0, j;
+
+ if (!pmx->machdata->gpio_pingroups)
+ return NULL;
+
+ for (; i < pmx->machdata->ngpio_pingroups; i++) {
+ gpio_pingroup = &pmx->machdata->gpio_pingroups[i];
+
+ for (j = 0; j < gpio_pingroup->npins; j++) {
+ if (gpio_pingroup->pins[j] == pin)
+ return gpio_pingroup;
+ }
+ }
+
+ return ERR_PTR(-EINVAL);
+}
+
+static int gpio_request_endisable(struct pinctrl_dev *pctldev,
+ struct pinctrl_gpio_range *range, unsigned offset, bool enable)
+{
+ struct spear_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
+ struct spear_gpio_pingroup *gpio_pingroup;
+
+ gpio_pingroup = get_gpio_pingroup(pmx, offset);
+ if (IS_ERR(gpio_pingroup))
+ return PTR_ERR(gpio_pingroup);
+
+ if (gpio_pingroup)
+ muxregs_endisable(pmx, gpio_pingroup->muxregs,
+ gpio_pingroup->nmuxregs, enable);
+
+ return 0;
+}
+
+static int gpio_request_enable(struct pinctrl_dev *pctldev,
+ struct pinctrl_gpio_range *range, unsigned offset)
+{
+ return gpio_request_endisable(pctldev, range, offset, true);
+}
+
+static void gpio_disable_free(struct pinctrl_dev *pctldev,
+ struct pinctrl_gpio_range *range, unsigned offset)
+{
+ gpio_request_endisable(pctldev, range, offset, false);
+}
+
static struct pinmux_ops spear_pinmux_ops = {
.get_functions_count = spear_pinctrl_get_funcs_count,
.get_function_name = spear_pinctrl_get_func_name,
.get_function_groups = spear_pinctrl_get_func_groups,
.enable = spear_pinctrl_enable,
.disable = spear_pinctrl_disable,
+ .gpio_request_enable = gpio_request_enable,
+ .gpio_disable_free = gpio_disable_free,
};
static struct pinctrl_desc spear_pinctrl_desc = {
diff --git a/drivers/pinctrl/spear/pinctrl-spear.h b/drivers/pinctrl/spear/pinctrl-spear.h
index d950eb78d939..94f142c10c19 100644
--- a/drivers/pinctrl/spear/pinctrl-spear.h
+++ b/drivers/pinctrl/spear/pinctrl-spear.h
@@ -12,6 +12,7 @@
#ifndef __PINMUX_SPEAR_H__
#define __PINMUX_SPEAR_H__
+#include <linux/gpio.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/types.h>
@@ -46,6 +47,44 @@ struct spear_muxreg {
u32 val;
};
+struct spear_gpio_pingroup {
+ const unsigned *pins;
+ unsigned npins;
+ struct spear_muxreg *muxregs;
+ u8 nmuxregs;
+};
+
+/* ste: set to enable */
+#define DEFINE_MUXREG(__pins, __muxreg, __mask, __ste) \
+static struct spear_muxreg __pins##_muxregs[] = { \
+ { \
+ .reg = __muxreg, \
+ .mask = __mask, \
+ .val = __ste ? __mask : 0, \
+ }, \
+}
+
+#define DEFINE_2_MUXREG(__pins, __muxreg1, __muxreg2, __mask, __ste1, __ste2) \
+static struct spear_muxreg __pins##_muxregs[] = { \
+ { \
+ .reg = __muxreg1, \
+ .mask = __mask, \
+ .val = __ste1 ? __mask : 0, \
+ }, { \
+ .reg = __muxreg2, \
+ .mask = __mask, \
+ .val = __ste2 ? __mask : 0, \
+ }, \
+}
+
+#define GPIO_PINGROUP(__pins) \
+ { \
+ .pins = __pins, \
+ .npins = ARRAY_SIZE(__pins), \
+ .muxregs = __pins##_muxregs, \
+ .nmuxregs = ARRAY_SIZE(__pins##_muxregs), \
+ }
+
/**
* struct spear_modemux - SPEAr mode mux configuration
* @modes: mode ids supported by this group of muxregs
@@ -100,6 +139,8 @@ struct spear_function {
* @nfunctions: The numbmer of entries in @functions.
* @groups: An array describing all pin groups the pin SoC supports.
* @ngroups: The numbmer of entries in @groups.
+ * @gpio_pingroups: gpio pingroups
+ * @ngpio_pingroups: gpio pingroups count
*
* @modes_supported: Does SoC support modes
* @mode: mode configured from probe
@@ -113,6 +154,8 @@ struct spear_pinctrl_machdata {
unsigned nfunctions;
struct spear_pingroup **groups;
unsigned ngroups;
+ struct spear_gpio_pingroup *gpio_pingroups;
+ unsigned ngpio_pingroups;
bool modes_supported;
u16 mode;
@@ -136,6 +179,9 @@ struct spear_pmx {
/* exported routines */
void __devinit pmx_init_addr(struct spear_pinctrl_machdata *machdata, u16 reg);
+void __devinit
+pmx_init_gpio_pingroup_addr(struct spear_gpio_pingroup *gpio_pingroup,
+ unsigned count, u16 reg);
int __devinit spear_pinctrl_probe(struct platform_device *pdev,
struct spear_pinctrl_machdata *machdata);
int __devexit spear_pinctrl_remove(struct platform_device *pdev);
diff --git a/drivers/pinctrl/spear/pinctrl-spear1310.c b/drivers/pinctrl/spear/pinctrl-spear1310.c
index d6cca8c81b92..30134f727455 100644
--- a/drivers/pinctrl/spear/pinctrl-spear1310.c
+++ b/drivers/pinctrl/spear/pinctrl-spear1310.c
@@ -25,8 +25,8 @@ static const struct pinctrl_pin_desc spear1310_pins[] = {
};
/* registers */
-#define PERIP_CFG 0x32C
- #define MCIF_SEL_SHIFT 3
+#define PERIP_CFG 0x3B0
+ #define MCIF_SEL_SHIFT 5
#define MCIF_SEL_SD (0x1 << MCIF_SEL_SHIFT)
#define MCIF_SEL_CF (0x2 << MCIF_SEL_SHIFT)
#define MCIF_SEL_XD (0x3 << MCIF_SEL_SHIFT)
@@ -164,6 +164,10 @@ static const struct pinctrl_pin_desc spear1310_pins[] = {
#define PMX_SSP0_CS0_MASK (1 << 29)
#define PMX_SSP0_CS1_2_MASK (1 << 30)
+#define PAD_DIRECTION_SEL_0 0x65C
+#define PAD_DIRECTION_SEL_1 0x660
+#define PAD_DIRECTION_SEL_2 0x664
+
/* combined macros */
#define PMX_GMII_MASK (PMX_GMIICLK_MASK | \
PMX_GMIICOL_CRS_XFERER_MIITXCLK_MASK | \
@@ -237,6 +241,10 @@ static struct spear_muxreg i2c0_muxreg[] = {
.reg = PAD_FUNCTION_EN_0,
.mask = PMX_I2C0_MASK,
.val = PMX_I2C0_MASK,
+ }, {
+ .reg = PAD_DIRECTION_SEL_0,
+ .mask = PMX_I2C0_MASK,
+ .val = PMX_I2C0_MASK,
},
};
@@ -269,6 +277,10 @@ static struct spear_muxreg ssp0_muxreg[] = {
.reg = PAD_FUNCTION_EN_0,
.mask = PMX_SSP0_MASK,
.val = PMX_SSP0_MASK,
+ }, {
+ .reg = PAD_DIRECTION_SEL_0,
+ .mask = PMX_SSP0_MASK,
+ .val = PMX_SSP0_MASK,
},
};
@@ -294,6 +306,10 @@ static struct spear_muxreg ssp0_cs0_muxreg[] = {
.reg = PAD_FUNCTION_EN_2,
.mask = PMX_SSP0_CS0_MASK,
.val = PMX_SSP0_CS0_MASK,
+ }, {
+ .reg = PAD_DIRECTION_SEL_2,
+ .mask = PMX_SSP0_CS0_MASK,
+ .val = PMX_SSP0_CS0_MASK,
},
};
@@ -319,6 +335,10 @@ static struct spear_muxreg ssp0_cs1_2_muxreg[] = {
.reg = PAD_FUNCTION_EN_2,
.mask = PMX_SSP0_CS1_2_MASK,
.val = PMX_SSP0_CS1_2_MASK,
+ }, {
+ .reg = PAD_DIRECTION_SEL_2,
+ .mask = PMX_SSP0_CS1_2_MASK,
+ .val = PMX_SSP0_CS1_2_MASK,
},
};
@@ -352,6 +372,10 @@ static struct spear_muxreg i2s0_muxreg[] = {
.reg = PAD_FUNCTION_EN_0,
.mask = PMX_I2S0_MASK,
.val = PMX_I2S0_MASK,
+ }, {
+ .reg = PAD_DIRECTION_SEL_0,
+ .mask = PMX_I2S0_MASK,
+ .val = PMX_I2S0_MASK,
},
};
@@ -384,6 +408,10 @@ static struct spear_muxreg i2s1_muxreg[] = {
.reg = PAD_FUNCTION_EN_1,
.mask = PMX_I2S1_MASK,
.val = PMX_I2S1_MASK,
+ }, {
+ .reg = PAD_DIRECTION_SEL_1,
+ .mask = PMX_I2S1_MASK,
+ .val = PMX_I2S1_MASK,
},
};
@@ -418,6 +446,10 @@ static struct spear_muxreg clcd_muxreg[] = {
.reg = PAD_FUNCTION_EN_0,
.mask = PMX_CLCD1_MASK,
.val = PMX_CLCD1_MASK,
+ }, {
+ .reg = PAD_DIRECTION_SEL_0,
+ .mask = PMX_CLCD1_MASK,
+ .val = PMX_CLCD1_MASK,
},
};
@@ -443,6 +475,10 @@ static struct spear_muxreg clcd_high_res_muxreg[] = {
.reg = PAD_FUNCTION_EN_1,
.mask = PMX_CLCD2_MASK,
.val = PMX_CLCD2_MASK,
+ }, {
+ .reg = PAD_DIRECTION_SEL_1,
+ .mask = PMX_CLCD2_MASK,
+ .val = PMX_CLCD2_MASK,
},
};
@@ -461,7 +497,7 @@ static struct spear_pingroup clcd_high_res_pingroup = {
.nmodemuxs = ARRAY_SIZE(clcd_high_res_modemux),
};
-static const char *const clcd_grps[] = { "clcd_grp", "clcd_high_res" };
+static const char *const clcd_grps[] = { "clcd_grp", "clcd_high_res_grp" };
static struct spear_function clcd_function = {
.name = "clcd",
.groups = clcd_grps,
@@ -479,6 +515,14 @@ static struct spear_muxreg arm_gpio_muxreg[] = {
.reg = PAD_FUNCTION_EN_1,
.mask = PMX_EGPIO_1_GRP_MASK,
.val = PMX_EGPIO_1_GRP_MASK,
+ }, {
+ .reg = PAD_DIRECTION_SEL_0,
+ .mask = PMX_EGPIO_0_GRP_MASK,
+ .val = PMX_EGPIO_0_GRP_MASK,
+ }, {
+ .reg = PAD_DIRECTION_SEL_1,
+ .mask = PMX_EGPIO_1_GRP_MASK,
+ .val = PMX_EGPIO_1_GRP_MASK,
},
};
@@ -511,6 +555,10 @@ static struct spear_muxreg smi_2_chips_muxreg[] = {
.reg = PAD_FUNCTION_EN_0,
.mask = PMX_SMI_MASK,
.val = PMX_SMI_MASK,
+ }, {
+ .reg = PAD_DIRECTION_SEL_0,
+ .mask = PMX_SMI_MASK,
+ .val = PMX_SMI_MASK,
},
};
@@ -539,6 +587,14 @@ static struct spear_muxreg smi_4_chips_muxreg[] = {
.reg = PAD_FUNCTION_EN_1,
.mask = PMX_SMINCS2_MASK | PMX_SMINCS3_MASK,
.val = PMX_SMINCS2_MASK | PMX_SMINCS3_MASK,
+ }, {
+ .reg = PAD_DIRECTION_SEL_0,
+ .mask = PMX_SMI_MASK,
+ .val = PMX_SMI_MASK,
+ }, {
+ .reg = PAD_DIRECTION_SEL_1,
+ .mask = PMX_SMINCS2_MASK | PMX_SMINCS3_MASK,
+ .val = PMX_SMINCS2_MASK | PMX_SMINCS3_MASK,
},
};
@@ -573,6 +629,10 @@ static struct spear_muxreg gmii_muxreg[] = {
.reg = PAD_FUNCTION_EN_0,
.mask = PMX_GMII_MASK,
.val = PMX_GMII_MASK,
+ }, {
+ .reg = PAD_DIRECTION_SEL_0,
+ .mask = PMX_GMII_MASK,
+ .val = PMX_GMII_MASK,
},
};
@@ -615,6 +675,18 @@ static struct spear_muxreg rgmii_muxreg[] = {
.reg = PAD_FUNCTION_EN_2,
.mask = PMX_RGMII_REG2_MASK,
.val = 0,
+ }, {
+ .reg = PAD_DIRECTION_SEL_0,
+ .mask = PMX_RGMII_REG0_MASK,
+ .val = PMX_RGMII_REG0_MASK,
+ }, {
+ .reg = PAD_DIRECTION_SEL_1,
+ .mask = PMX_RGMII_REG1_MASK,
+ .val = PMX_RGMII_REG1_MASK,
+ }, {
+ .reg = PAD_DIRECTION_SEL_2,
+ .mask = PMX_RGMII_REG2_MASK,
+ .val = PMX_RGMII_REG2_MASK,
},
};
@@ -649,6 +721,10 @@ static struct spear_muxreg smii_0_1_2_muxreg[] = {
.reg = PAD_FUNCTION_EN_1,
.mask = PMX_SMII_0_1_2_MASK,
.val = 0,
+ }, {
+ .reg = PAD_DIRECTION_SEL_1,
+ .mask = PMX_SMII_0_1_2_MASK,
+ .val = PMX_SMII_0_1_2_MASK,
},
};
@@ -681,6 +757,10 @@ static struct spear_muxreg ras_mii_txclk_muxreg[] = {
.reg = PAD_FUNCTION_EN_1,
.mask = PMX_NFCE2_MASK,
.val = 0,
+ }, {
+ .reg = PAD_DIRECTION_SEL_1,
+ .mask = PMX_NFCE2_MASK,
+ .val = PMX_NFCE2_MASK,
},
};
@@ -721,6 +801,14 @@ static struct spear_muxreg nand_8bit_muxreg[] = {
.reg = PAD_FUNCTION_EN_1,
.mask = PMX_NAND8BIT_1_MASK,
.val = PMX_NAND8BIT_1_MASK,
+ }, {
+ .reg = PAD_DIRECTION_SEL_0,
+ .mask = PMX_NAND8BIT_0_MASK,
+ .val = PMX_NAND8BIT_0_MASK,
+ }, {
+ .reg = PAD_DIRECTION_SEL_1,
+ .mask = PMX_NAND8BIT_1_MASK,
+ .val = PMX_NAND8BIT_1_MASK,
},
};
@@ -747,6 +835,10 @@ static struct spear_muxreg nand_16bit_muxreg[] = {
.reg = PAD_FUNCTION_EN_1,
.mask = PMX_NAND16BIT_1_MASK,
.val = PMX_NAND16BIT_1_MASK,
+ }, {
+ .reg = PAD_DIRECTION_SEL_1,
+ .mask = PMX_NAND16BIT_1_MASK,
+ .val = PMX_NAND16BIT_1_MASK,
},
};
@@ -772,6 +864,10 @@ static struct spear_muxreg nand_4_chips_muxreg[] = {
.reg = PAD_FUNCTION_EN_1,
.mask = PMX_NAND_4CHIPS_MASK,
.val = PMX_NAND_4CHIPS_MASK,
+ }, {
+ .reg = PAD_DIRECTION_SEL_1,
+ .mask = PMX_NAND_4CHIPS_MASK,
+ .val = PMX_NAND_4CHIPS_MASK,
},
};
@@ -833,6 +929,10 @@ static struct spear_muxreg keyboard_rowcol6_8_muxreg[] = {
.reg = PAD_FUNCTION_EN_1,
.mask = PMX_KBD_ROWCOL68_MASK,
.val = PMX_KBD_ROWCOL68_MASK,
+ }, {
+ .reg = PAD_DIRECTION_SEL_1,
+ .mask = PMX_KBD_ROWCOL68_MASK,
+ .val = PMX_KBD_ROWCOL68_MASK,
},
};
@@ -866,6 +966,10 @@ static struct spear_muxreg uart0_muxreg[] = {
.reg = PAD_FUNCTION_EN_0,
.mask = PMX_UART0_MASK,
.val = PMX_UART0_MASK,
+ }, {
+ .reg = PAD_DIRECTION_SEL_0,
+ .mask = PMX_UART0_MASK,
+ .val = PMX_UART0_MASK,
},
};
@@ -891,6 +995,10 @@ static struct spear_muxreg uart0_modem_muxreg[] = {
.reg = PAD_FUNCTION_EN_1,
.mask = PMX_UART0_MODEM_MASK,
.val = PMX_UART0_MODEM_MASK,
+ }, {
+ .reg = PAD_DIRECTION_SEL_1,
+ .mask = PMX_UART0_MODEM_MASK,
+ .val = PMX_UART0_MODEM_MASK,
},
};
@@ -923,6 +1031,10 @@ static struct spear_muxreg gpt0_tmr0_muxreg[] = {
.reg = PAD_FUNCTION_EN_1,
.mask = PMX_GPT0_TMR0_MASK,
.val = PMX_GPT0_TMR0_MASK,
+ }, {
+ .reg = PAD_DIRECTION_SEL_1,
+ .mask = PMX_GPT0_TMR0_MASK,
+ .val = PMX_GPT0_TMR0_MASK,
},
};
@@ -948,6 +1060,10 @@ static struct spear_muxreg gpt0_tmr1_muxreg[] = {
.reg = PAD_FUNCTION_EN_1,
.mask = PMX_GPT0_TMR1_MASK,
.val = PMX_GPT0_TMR1_MASK,
+ }, {
+ .reg = PAD_DIRECTION_SEL_1,
+ .mask = PMX_GPT0_TMR1_MASK,
+ .val = PMX_GPT0_TMR1_MASK,
},
};
@@ -980,6 +1096,10 @@ static struct spear_muxreg gpt1_tmr0_muxreg[] = {
.reg = PAD_FUNCTION_EN_1,
.mask = PMX_GPT1_TMR0_MASK,
.val = PMX_GPT1_TMR0_MASK,
+ }, {
+ .reg = PAD_DIRECTION_SEL_1,
+ .mask = PMX_GPT1_TMR0_MASK,
+ .val = PMX_GPT1_TMR0_MASK,
},
};
@@ -1005,6 +1125,10 @@ static struct spear_muxreg gpt1_tmr1_muxreg[] = {
.reg = PAD_FUNCTION_EN_1,
.mask = PMX_GPT1_TMR1_MASK,
.val = PMX_GPT1_TMR1_MASK,
+ }, {
+ .reg = PAD_DIRECTION_SEL_1,
+ .mask = PMX_GPT1_TMR1_MASK,
+ .val = PMX_GPT1_TMR1_MASK,
},
};
@@ -1049,6 +1173,20 @@ static const unsigned mcif_pins[] = { 86, 87, 88, 89, 90, 91, 92, 93, 213, 214,
.reg = PAD_FUNCTION_EN_2, \
.mask = PMX_MCIFALL_2_MASK, \
.val = PMX_MCIFALL_2_MASK, \
+ }, { \
+ .reg = PAD_DIRECTION_SEL_0, \
+ .mask = PMX_MCI_DATA8_15_MASK, \
+ .val = PMX_MCI_DATA8_15_MASK, \
+ }, { \
+ .reg = PAD_DIRECTION_SEL_1, \
+ .mask = PMX_MCIFALL_1_MASK | PMX_NFWPRT1_MASK | \
+ PMX_NFWPRT2_MASK, \
+ .val = PMX_MCIFALL_1_MASK | PMX_NFWPRT1_MASK | \
+ PMX_NFWPRT2_MASK, \
+ }, { \
+ .reg = PAD_DIRECTION_SEL_2, \
+ .mask = PMX_MCIFALL_2_MASK, \
+ .val = PMX_MCIFALL_2_MASK, \
}
/* sdhci device */
@@ -1154,6 +1292,10 @@ static struct spear_muxreg touch_xy_muxreg[] = {
.reg = PAD_FUNCTION_EN_2,
.mask = PMX_TOUCH_XY_MASK,
.val = PMX_TOUCH_XY_MASK,
+ }, {
+ .reg = PAD_DIRECTION_SEL_2,
+ .mask = PMX_TOUCH_XY_MASK,
+ .val = PMX_TOUCH_XY_MASK,
},
};
@@ -1187,6 +1329,10 @@ static struct spear_muxreg uart1_dis_i2c_muxreg[] = {
.reg = PAD_FUNCTION_EN_0,
.mask = PMX_I2C0_MASK,
.val = 0,
+ }, {
+ .reg = PAD_DIRECTION_SEL_0,
+ .mask = PMX_I2C0_MASK,
+ .val = PMX_I2C0_MASK,
},
};
@@ -1213,6 +1359,12 @@ static struct spear_muxreg uart1_dis_sd_muxreg[] = {
.mask = PMX_MCIDATA1_MASK |
PMX_MCIDATA2_MASK,
.val = 0,
+ }, {
+ .reg = PAD_DIRECTION_SEL_1,
+ .mask = PMX_MCIDATA1_MASK |
+ PMX_MCIDATA2_MASK,
+ .val = PMX_MCIDATA1_MASK |
+ PMX_MCIDATA2_MASK,
},
};
@@ -1246,6 +1398,10 @@ static struct spear_muxreg uart2_3_muxreg[] = {
.reg = PAD_FUNCTION_EN_0,
.mask = PMX_I2S0_MASK,
.val = 0,
+ }, {
+ .reg = PAD_DIRECTION_SEL_0,
+ .mask = PMX_I2S0_MASK,
+ .val = PMX_I2S0_MASK,
},
};
@@ -1278,6 +1434,10 @@ static struct spear_muxreg uart4_muxreg[] = {
.reg = PAD_FUNCTION_EN_0,
.mask = PMX_I2S0_MASK | PMX_CLCD1_MASK,
.val = 0,
+ }, {
+ .reg = PAD_DIRECTION_SEL_0,
+ .mask = PMX_I2S0_MASK | PMX_CLCD1_MASK,
+ .val = PMX_I2S0_MASK | PMX_CLCD1_MASK,
},
};
@@ -1310,6 +1470,10 @@ static struct spear_muxreg uart5_muxreg[] = {
.reg = PAD_FUNCTION_EN_0,
.mask = PMX_CLCD1_MASK,
.val = 0,
+ }, {
+ .reg = PAD_DIRECTION_SEL_0,
+ .mask = PMX_CLCD1_MASK,
+ .val = PMX_CLCD1_MASK,
},
};
@@ -1344,6 +1508,10 @@ static struct spear_muxreg rs485_0_1_tdm_0_1_muxreg[] = {
.reg = PAD_FUNCTION_EN_0,
.mask = PMX_CLCD1_MASK,
.val = 0,
+ }, {
+ .reg = PAD_DIRECTION_SEL_0,
+ .mask = PMX_CLCD1_MASK,
+ .val = PMX_CLCD1_MASK,
},
};
@@ -1376,6 +1544,10 @@ static struct spear_muxreg i2c_1_2_muxreg[] = {
.reg = PAD_FUNCTION_EN_0,
.mask = PMX_CLCD1_MASK,
.val = 0,
+ }, {
+ .reg = PAD_DIRECTION_SEL_0,
+ .mask = PMX_CLCD1_MASK,
+ .val = PMX_CLCD1_MASK,
},
};
@@ -1409,6 +1581,10 @@ static struct spear_muxreg i2c3_dis_smi_clcd_muxreg[] = {
.reg = PAD_FUNCTION_EN_0,
.mask = PMX_CLCD1_MASK | PMX_SMI_MASK,
.val = 0,
+ }, {
+ .reg = PAD_DIRECTION_SEL_0,
+ .mask = PMX_CLCD1_MASK | PMX_SMI_MASK,
+ .val = PMX_CLCD1_MASK | PMX_SMI_MASK,
},
};
@@ -1435,6 +1611,10 @@ static struct spear_muxreg i2c3_dis_sd_i2s0_muxreg[] = {
.reg = PAD_FUNCTION_EN_1,
.mask = PMX_I2S1_MASK | PMX_MCIDATA3_MASK,
.val = 0,
+ }, {
+ .reg = PAD_DIRECTION_SEL_1,
+ .mask = PMX_I2S1_MASK | PMX_MCIDATA3_MASK,
+ .val = PMX_I2S1_MASK | PMX_MCIDATA3_MASK,
},
};
@@ -1469,6 +1649,10 @@ static struct spear_muxreg i2c_4_5_dis_smi_muxreg[] = {
.reg = PAD_FUNCTION_EN_0,
.mask = PMX_SMI_MASK,
.val = 0,
+ }, {
+ .reg = PAD_DIRECTION_SEL_0,
+ .mask = PMX_SMI_MASK,
+ .val = PMX_SMI_MASK,
},
};
@@ -1499,6 +1683,14 @@ static struct spear_muxreg i2c4_dis_sd_muxreg[] = {
.reg = PAD_FUNCTION_EN_2,
.mask = PMX_MCIDATA5_MASK,
.val = 0,
+ }, {
+ .reg = PAD_DIRECTION_SEL_1,
+ .mask = PMX_MCIDATA4_MASK,
+ .val = PMX_MCIDATA4_MASK,
+ }, {
+ .reg = PAD_DIRECTION_SEL_2,
+ .mask = PMX_MCIDATA5_MASK,
+ .val = PMX_MCIDATA5_MASK,
},
};
@@ -1526,6 +1718,12 @@ static struct spear_muxreg i2c5_dis_sd_muxreg[] = {
.mask = PMX_MCIDATA6_MASK |
PMX_MCIDATA7_MASK,
.val = 0,
+ }, {
+ .reg = PAD_DIRECTION_SEL_2,
+ .mask = PMX_MCIDATA6_MASK |
+ PMX_MCIDATA7_MASK,
+ .val = PMX_MCIDATA6_MASK |
+ PMX_MCIDATA7_MASK,
},
};
@@ -1560,6 +1758,10 @@ static struct spear_muxreg i2c_6_7_dis_kbd_muxreg[] = {
.reg = PAD_FUNCTION_EN_1,
.mask = PMX_KBD_ROWCOL25_MASK,
.val = 0,
+ }, {
+ .reg = PAD_DIRECTION_SEL_1,
+ .mask = PMX_KBD_ROWCOL25_MASK,
+ .val = PMX_KBD_ROWCOL25_MASK,
},
};
@@ -1587,6 +1789,12 @@ static struct spear_muxreg i2c6_dis_sd_muxreg[] = {
.mask = PMX_MCIIORDRE_MASK |
PMX_MCIIOWRWE_MASK,
.val = 0,
+ }, {
+ .reg = PAD_DIRECTION_SEL_2,
+ .mask = PMX_MCIIORDRE_MASK |
+ PMX_MCIIOWRWE_MASK,
+ .val = PMX_MCIIORDRE_MASK |
+ PMX_MCIIOWRWE_MASK,
},
};
@@ -1613,6 +1821,12 @@ static struct spear_muxreg i2c7_dis_sd_muxreg[] = {
.mask = PMX_MCIRESETCF_MASK |
PMX_MCICS0CE_MASK,
.val = 0,
+ }, {
+ .reg = PAD_DIRECTION_SEL_2,
+ .mask = PMX_MCIRESETCF_MASK |
+ PMX_MCICS0CE_MASK,
+ .val = PMX_MCIRESETCF_MASK |
+ PMX_MCICS0CE_MASK,
},
};
@@ -1651,6 +1865,14 @@ static struct spear_muxreg can0_dis_nor_muxreg[] = {
.reg = PAD_FUNCTION_EN_1,
.mask = PMX_NFRSTPWDWN3_MASK,
.val = 0,
+ }, {
+ .reg = PAD_DIRECTION_SEL_0,
+ .mask = PMX_NFRSTPWDWN2_MASK,
+ .val = PMX_NFRSTPWDWN2_MASK,
+ }, {
+ .reg = PAD_DIRECTION_SEL_1,
+ .mask = PMX_NFRSTPWDWN3_MASK,
+ .val = PMX_NFRSTPWDWN3_MASK,
},
};
@@ -1677,6 +1899,10 @@ static struct spear_muxreg can0_dis_sd_muxreg[] = {
.reg = PAD_FUNCTION_EN_2,
.mask = PMX_MCICFINTR_MASK | PMX_MCIIORDY_MASK,
.val = 0,
+ }, {
+ .reg = PAD_DIRECTION_SEL_2,
+ .mask = PMX_MCICFINTR_MASK | PMX_MCIIORDY_MASK,
+ .val = PMX_MCICFINTR_MASK | PMX_MCIIORDY_MASK,
},
};
@@ -1711,6 +1937,10 @@ static struct spear_muxreg can1_dis_sd_muxreg[] = {
.reg = PAD_FUNCTION_EN_2,
.mask = PMX_MCICS1_MASK | PMX_MCIDMAACK_MASK,
.val = 0,
+ }, {
+ .reg = PAD_DIRECTION_SEL_2,
+ .mask = PMX_MCICS1_MASK | PMX_MCIDMAACK_MASK,
+ .val = PMX_MCICS1_MASK | PMX_MCIDMAACK_MASK,
},
};
@@ -1737,6 +1967,10 @@ static struct spear_muxreg can1_dis_kbd_muxreg[] = {
.reg = PAD_FUNCTION_EN_1,
.mask = PMX_KBD_ROWCOL25_MASK,
.val = 0,
+ }, {
+ .reg = PAD_DIRECTION_SEL_1,
+ .mask = PMX_KBD_ROWCOL25_MASK,
+ .val = PMX_KBD_ROWCOL25_MASK,
},
};
@@ -1763,29 +1997,64 @@ static struct spear_function can1_function = {
.ngroups = ARRAY_SIZE(can1_grps),
};
-/* Pad multiplexing for pci device */
-static const unsigned pci_sata_pins[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 18,
+/* Pad multiplexing for (ras-ip) pci device */
+static const unsigned pci_pins[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 18,
19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
55, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99 };
-#define PCI_SATA_MUXREG \
- { \
- .reg = PAD_FUNCTION_EN_0, \
- .mask = PMX_MCI_DATA8_15_MASK, \
- .val = 0, \
- }, { \
- .reg = PAD_FUNCTION_EN_1, \
- .mask = PMX_PCI_REG1_MASK, \
- .val = 0, \
- }, { \
- .reg = PAD_FUNCTION_EN_2, \
- .mask = PMX_PCI_REG2_MASK, \
- .val = 0, \
- }
-/* pad multiplexing for pcie0 device */
+static struct spear_muxreg pci_muxreg[] = {
+ {
+ .reg = PAD_FUNCTION_EN_0,
+ .mask = PMX_MCI_DATA8_15_MASK,
+ .val = 0,
+ }, {
+ .reg = PAD_FUNCTION_EN_1,
+ .mask = PMX_PCI_REG1_MASK,
+ .val = 0,
+ }, {
+ .reg = PAD_FUNCTION_EN_2,
+ .mask = PMX_PCI_REG2_MASK,
+ .val = 0,
+ }, {
+ .reg = PAD_DIRECTION_SEL_0,
+ .mask = PMX_MCI_DATA8_15_MASK,
+ .val = PMX_MCI_DATA8_15_MASK,
+ }, {
+ .reg = PAD_DIRECTION_SEL_1,
+ .mask = PMX_PCI_REG1_MASK,
+ .val = PMX_PCI_REG1_MASK,
+ }, {
+ .reg = PAD_DIRECTION_SEL_2,
+ .mask = PMX_PCI_REG2_MASK,
+ .val = PMX_PCI_REG2_MASK,
+ },
+};
+
+static struct spear_modemux pci_modemux[] = {
+ {
+ .muxregs = pci_muxreg,
+ .nmuxregs = ARRAY_SIZE(pci_muxreg),
+ },
+};
+
+static struct spear_pingroup pci_pingroup = {
+ .name = "pci_grp",
+ .pins = pci_pins,
+ .npins = ARRAY_SIZE(pci_pins),
+ .modemuxs = pci_modemux,
+ .nmodemuxs = ARRAY_SIZE(pci_modemux),
+};
+
+static const char *const pci_grps[] = { "pci_grp" };
+static struct spear_function pci_function = {
+ .name = "pci",
+ .groups = pci_grps,
+ .ngroups = ARRAY_SIZE(pci_grps),
+};
+
+/* pad multiplexing for (fix-part) pcie0 device */
static struct spear_muxreg pcie0_muxreg[] = {
- PCI_SATA_MUXREG,
{
.reg = PCIE_SATA_CFG,
.mask = PCIE_CFG_VAL(0),
@@ -1802,15 +2071,12 @@ static struct spear_modemux pcie0_modemux[] = {
static struct spear_pingroup pcie0_pingroup = {
.name = "pcie0_grp",
- .pins = pci_sata_pins,
- .npins = ARRAY_SIZE(pci_sata_pins),
.modemuxs = pcie0_modemux,
.nmodemuxs = ARRAY_SIZE(pcie0_modemux),
};
-/* pad multiplexing for pcie1 device */
+/* pad multiplexing for (fix-part) pcie1 device */
static struct spear_muxreg pcie1_muxreg[] = {
- PCI_SATA_MUXREG,
{
.reg = PCIE_SATA_CFG,
.mask = PCIE_CFG_VAL(1),
@@ -1827,15 +2093,12 @@ static struct spear_modemux pcie1_modemux[] = {
static struct spear_pingroup pcie1_pingroup = {
.name = "pcie1_grp",
- .pins = pci_sata_pins,
- .npins = ARRAY_SIZE(pci_sata_pins),
.modemuxs = pcie1_modemux,
.nmodemuxs = ARRAY_SIZE(pcie1_modemux),
};
-/* pad multiplexing for pcie2 device */
+/* pad multiplexing for (fix-part) pcie2 device */
static struct spear_muxreg pcie2_muxreg[] = {
- PCI_SATA_MUXREG,
{
.reg = PCIE_SATA_CFG,
.mask = PCIE_CFG_VAL(2),
@@ -1852,22 +2115,20 @@ static struct spear_modemux pcie2_modemux[] = {
static struct spear_pingroup pcie2_pingroup = {
.name = "pcie2_grp",
- .pins = pci_sata_pins,
- .npins = ARRAY_SIZE(pci_sata_pins),
.modemuxs = pcie2_modemux,
.nmodemuxs = ARRAY_SIZE(pcie2_modemux),
};
-static const char *const pci_grps[] = { "pcie0_grp", "pcie1_grp", "pcie2_grp" };
-static struct spear_function pci_function = {
- .name = "pci",
- .groups = pci_grps,
- .ngroups = ARRAY_SIZE(pci_grps),
+static const char *const pcie_grps[] = { "pcie0_grp", "pcie1_grp", "pcie2_grp"
+};
+static struct spear_function pcie_function = {
+ .name = "pci_express",
+ .groups = pcie_grps,
+ .ngroups = ARRAY_SIZE(pcie_grps),
};
/* pad multiplexing for sata0 device */
static struct spear_muxreg sata0_muxreg[] = {
- PCI_SATA_MUXREG,
{
.reg = PCIE_SATA_CFG,
.mask = SATA_CFG_VAL(0),
@@ -1884,15 +2145,12 @@ static struct spear_modemux sata0_modemux[] = {
static struct spear_pingroup sata0_pingroup = {
.name = "sata0_grp",
- .pins = pci_sata_pins,
- .npins = ARRAY_SIZE(pci_sata_pins),
.modemuxs = sata0_modemux,
.nmodemuxs = ARRAY_SIZE(sata0_modemux),
};
/* pad multiplexing for sata1 device */
static struct spear_muxreg sata1_muxreg[] = {
- PCI_SATA_MUXREG,
{
.reg = PCIE_SATA_CFG,
.mask = SATA_CFG_VAL(1),
@@ -1909,15 +2167,12 @@ static struct spear_modemux sata1_modemux[] = {
static struct spear_pingroup sata1_pingroup = {
.name = "sata1_grp",
- .pins = pci_sata_pins,
- .npins = ARRAY_SIZE(pci_sata_pins),
.modemuxs = sata1_modemux,
.nmodemuxs = ARRAY_SIZE(sata1_modemux),
};
/* pad multiplexing for sata2 device */
static struct spear_muxreg sata2_muxreg[] = {
- PCI_SATA_MUXREG,
{
.reg = PCIE_SATA_CFG,
.mask = SATA_CFG_VAL(2),
@@ -1934,8 +2189,6 @@ static struct spear_modemux sata2_modemux[] = {
static struct spear_pingroup sata2_pingroup = {
.name = "sata2_grp",
- .pins = pci_sata_pins,
- .npins = ARRAY_SIZE(pci_sata_pins),
.modemuxs = sata2_modemux,
.nmodemuxs = ARRAY_SIZE(sata2_modemux),
};
@@ -1957,6 +2210,14 @@ static struct spear_muxreg ssp1_dis_kbd_muxreg[] = {
PMX_KBD_COL0_MASK | PMX_NFIO8_15_MASK | PMX_NFCE1_MASK |
PMX_NFCE2_MASK,
.val = 0,
+ }, {
+ .reg = PAD_DIRECTION_SEL_1,
+ .mask = PMX_KBD_ROWCOL25_MASK | PMX_KBD_COL1_MASK |
+ PMX_KBD_COL0_MASK | PMX_NFIO8_15_MASK | PMX_NFCE1_MASK |
+ PMX_NFCE2_MASK,
+ .val = PMX_KBD_ROWCOL25_MASK | PMX_KBD_COL1_MASK |
+ PMX_KBD_COL0_MASK | PMX_NFIO8_15_MASK | PMX_NFCE1_MASK |
+ PMX_NFCE2_MASK,
},
};
@@ -1983,6 +2244,12 @@ static struct spear_muxreg ssp1_dis_sd_muxreg[] = {
.mask = PMX_MCIADDR0ALE_MASK | PMX_MCIADDR2_MASK |
PMX_MCICECF_MASK | PMX_MCICEXD_MASK,
.val = 0,
+ }, {
+ .reg = PAD_DIRECTION_SEL_2,
+ .mask = PMX_MCIADDR0ALE_MASK | PMX_MCIADDR2_MASK |
+ PMX_MCICECF_MASK | PMX_MCICEXD_MASK,
+ .val = PMX_MCIADDR0ALE_MASK | PMX_MCIADDR2_MASK |
+ PMX_MCICECF_MASK | PMX_MCICEXD_MASK,
},
};
@@ -2017,6 +2284,12 @@ static struct spear_muxreg gpt64_muxreg[] = {
.mask = PMX_MCICDCF1_MASK | PMX_MCICDCF2_MASK | PMX_MCICDXD_MASK
| PMX_MCILEDS_MASK,
.val = 0,
+ }, {
+ .reg = PAD_DIRECTION_SEL_2,
+ .mask = PMX_MCICDCF1_MASK | PMX_MCICDCF2_MASK | PMX_MCICDXD_MASK
+ | PMX_MCILEDS_MASK,
+ .val = PMX_MCICDCF1_MASK | PMX_MCICDCF2_MASK | PMX_MCICDXD_MASK
+ | PMX_MCILEDS_MASK,
},
};
@@ -2093,6 +2366,7 @@ static struct spear_pingroup *spear1310_pingroups[] = {
&can0_dis_sd_pingroup,
&can1_dis_sd_pingroup,
&can1_dis_kbd_pingroup,
+ &pci_pingroup,
&pcie0_pingroup,
&pcie1_pingroup,
&pcie2_pingroup,
@@ -2138,11 +2412,274 @@ static struct spear_function *spear1310_functions[] = {
&can0_function,
&can1_function,
&pci_function,
+ &pcie_function,
&sata_function,
&ssp1_function,
&gpt64_function,
};
+static const unsigned pin18[] = { 18, };
+static const unsigned pin19[] = { 19, };
+static const unsigned pin20[] = { 20, };
+static const unsigned pin21[] = { 21, };
+static const unsigned pin22[] = { 22, };
+static const unsigned pin23[] = { 23, };
+static const unsigned pin54[] = { 54, };
+static const unsigned pin55[] = { 55, };
+static const unsigned pin56[] = { 56, };
+static const unsigned pin57[] = { 57, };
+static const unsigned pin58[] = { 58, };
+static const unsigned pin59[] = { 59, };
+static const unsigned pin60[] = { 60, };
+static const unsigned pin61[] = { 61, };
+static const unsigned pin62[] = { 62, };
+static const unsigned pin63[] = { 63, };
+static const unsigned pin143[] = { 143, };
+static const unsigned pin144[] = { 144, };
+static const unsigned pin145[] = { 145, };
+static const unsigned pin146[] = { 146, };
+static const unsigned pin147[] = { 147, };
+static const unsigned pin148[] = { 148, };
+static const unsigned pin149[] = { 149, };
+static const unsigned pin150[] = { 150, };
+static const unsigned pin151[] = { 151, };
+static const unsigned pin152[] = { 152, };
+static const unsigned pin205[] = { 205, };
+static const unsigned pin206[] = { 206, };
+static const unsigned pin211[] = { 211, };
+static const unsigned pin212[] = { 212, };
+static const unsigned pin213[] = { 213, };
+static const unsigned pin214[] = { 214, };
+static const unsigned pin215[] = { 215, };
+static const unsigned pin216[] = { 216, };
+static const unsigned pin217[] = { 217, };
+static const unsigned pin218[] = { 218, };
+static const unsigned pin219[] = { 219, };
+static const unsigned pin220[] = { 220, };
+static const unsigned pin221[] = { 221, };
+static const unsigned pin222[] = { 222, };
+static const unsigned pin223[] = { 223, };
+static const unsigned pin224[] = { 224, };
+static const unsigned pin225[] = { 225, };
+static const unsigned pin226[] = { 226, };
+static const unsigned pin227[] = { 227, };
+static const unsigned pin228[] = { 228, };
+static const unsigned pin229[] = { 229, };
+static const unsigned pin230[] = { 230, };
+static const unsigned pin231[] = { 231, };
+static const unsigned pin232[] = { 232, };
+static const unsigned pin233[] = { 233, };
+static const unsigned pin234[] = { 234, };
+static const unsigned pin235[] = { 235, };
+static const unsigned pin236[] = { 236, };
+static const unsigned pin237[] = { 237, };
+static const unsigned pin238[] = { 238, };
+static const unsigned pin239[] = { 239, };
+static const unsigned pin240[] = { 240, };
+static const unsigned pin241[] = { 241, };
+static const unsigned pin242[] = { 242, };
+static const unsigned pin243[] = { 243, };
+static const unsigned pin244[] = { 244, };
+static const unsigned pin245[] = { 245, };
+
+static const unsigned pin_grp0[] = { 173, 174, };
+static const unsigned pin_grp1[] = { 175, 185, 188, 197, 198, };
+static const unsigned pin_grp2[] = { 176, 177, 178, 179, 184, 186, 187, 189,
+ 190, 191, 192, };
+static const unsigned pin_grp3[] = { 180, 181, 182, 183, 193, 194, 195, 196, };
+static const unsigned pin_grp4[] = { 199, 200, };
+static const unsigned pin_grp5[] = { 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
+ 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, };
+static const unsigned pin_grp6[] = { 86, 87, 88, 89, 90, 91, 92, 93, };
+static const unsigned pin_grp7[] = { 98, 99, };
+static const unsigned pin_grp8[] = { 158, 159, 160, 161, 162, 163, 164, 165,
+ 166, 167, 168, 169, 170, 171, 172, };
+
+/* Define muxreg arrays */
+DEFINE_2_MUXREG(i2c0_pins, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_I2C0_MASK, 0, 1);
+DEFINE_2_MUXREG(ssp0_pins, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_SSP0_MASK, 0, 1);
+DEFINE_2_MUXREG(ssp0_cs0_pins, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_SSP0_CS0_MASK, 0, 1);
+DEFINE_2_MUXREG(ssp0_cs1_2_pins, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_SSP0_CS1_2_MASK, 0, 1);
+DEFINE_2_MUXREG(i2s0_pins, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_I2S0_MASK, 0, 1);
+DEFINE_2_MUXREG(i2s1_pins, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_I2S1_MASK, 0, 1);
+DEFINE_2_MUXREG(clcd_pins, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_CLCD1_MASK, 0, 1);
+DEFINE_2_MUXREG(clcd_high_res_pins, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_CLCD2_MASK, 0, 1);
+DEFINE_2_MUXREG(pin18, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO15_MASK, 0, 1);
+DEFINE_2_MUXREG(pin19, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO14_MASK, 0, 1);
+DEFINE_2_MUXREG(pin20, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO13_MASK, 0, 1);
+DEFINE_2_MUXREG(pin21, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO12_MASK, 0, 1);
+DEFINE_2_MUXREG(pin22, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO11_MASK, 0, 1);
+DEFINE_2_MUXREG(pin23, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO10_MASK, 0, 1);
+DEFINE_2_MUXREG(pin143, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO00_MASK, 0, 1);
+DEFINE_2_MUXREG(pin144, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO01_MASK, 0, 1);
+DEFINE_2_MUXREG(pin145, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO02_MASK, 0, 1);
+DEFINE_2_MUXREG(pin146, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO03_MASK, 0, 1);
+DEFINE_2_MUXREG(pin147, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO04_MASK, 0, 1);
+DEFINE_2_MUXREG(pin148, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO05_MASK, 0, 1);
+DEFINE_2_MUXREG(pin149, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO06_MASK, 0, 1);
+DEFINE_2_MUXREG(pin150, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO07_MASK, 0, 1);
+DEFINE_2_MUXREG(pin151, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO08_MASK, 0, 1);
+DEFINE_2_MUXREG(pin152, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO09_MASK, 0, 1);
+DEFINE_2_MUXREG(smi_2_chips_pins, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_SMI_MASK, 0, 1);
+DEFINE_2_MUXREG(pin54, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_SMINCS3_MASK, 0, 1);
+DEFINE_2_MUXREG(pin55, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_SMINCS2_MASK, 0, 1);
+DEFINE_2_MUXREG(pin56, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_NFRSTPWDWN3_MASK, 0, 1);
+DEFINE_2_MUXREG(pin57, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_NFRSTPWDWN2_MASK, 0, 1);
+DEFINE_2_MUXREG(pin58, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_NFRSTPWDWN1_MASK, 0, 1);
+DEFINE_2_MUXREG(pin59, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_NFRSTPWDWN0_MASK, 0, 1);
+DEFINE_2_MUXREG(pin60, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_NFWPRT3_MASK, 0, 1);
+DEFINE_2_MUXREG(pin61, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_NFCE3_MASK, 0, 1);
+DEFINE_2_MUXREG(pin62, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_NFAD25_MASK, 0, 1);
+DEFINE_2_MUXREG(pin63, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_NFAD24_MASK, 0, 1);
+DEFINE_2_MUXREG(pin_grp0, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_GMIICLK_MASK, 0, 1);
+DEFINE_2_MUXREG(pin_grp1, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_GMIICOL_CRS_XFERER_MIITXCLK_MASK, 0, 1);
+DEFINE_2_MUXREG(pin_grp2, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_RXCLK_RDV_TXEN_D03_MASK, 0, 1);
+DEFINE_2_MUXREG(pin_grp3, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_GMIID47_MASK, 0, 1);
+DEFINE_2_MUXREG(pin_grp4, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_MDC_MDIO_MASK, 0, 1);
+DEFINE_2_MUXREG(pin_grp5, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_NFAD23_MASK, 0, 1);
+DEFINE_2_MUXREG(pin_grp6, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_MCI_DATA8_15_MASK, 0, 1);
+DEFINE_2_MUXREG(pin_grp7, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_NFCE2_MASK, 0, 1);
+DEFINE_2_MUXREG(pin_grp8, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_NAND8_MASK, 0, 1);
+DEFINE_2_MUXREG(nand_16bit_pins, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_NAND16BIT_1_MASK, 0, 1);
+DEFINE_2_MUXREG(pin205, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_KBD_COL1_MASK | PMX_NFCE1_MASK, 0, 1);
+DEFINE_2_MUXREG(pin206, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_KBD_COL0_MASK | PMX_NFCE2_MASK, 0, 1);
+DEFINE_2_MUXREG(pin211, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_KBD_ROW1_MASK | PMX_NFWPRT1_MASK, 0, 1);
+DEFINE_2_MUXREG(pin212, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_KBD_ROW0_MASK | PMX_NFWPRT2_MASK, 0, 1);
+DEFINE_2_MUXREG(pin213, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_MCIDATA0_MASK, 0, 1);
+DEFINE_2_MUXREG(pin214, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_MCIDATA1_MASK, 0, 1);
+DEFINE_2_MUXREG(pin215, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_MCIDATA2_MASK, 0, 1);
+DEFINE_2_MUXREG(pin216, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_MCIDATA3_MASK, 0, 1);
+DEFINE_2_MUXREG(pin217, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_MCIDATA4_MASK, 0, 1);
+DEFINE_2_MUXREG(pin218, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIDATA5_MASK, 0, 1);
+DEFINE_2_MUXREG(pin219, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIDATA6_MASK, 0, 1);
+DEFINE_2_MUXREG(pin220, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIDATA7_MASK, 0, 1);
+DEFINE_2_MUXREG(pin221, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIDATA1SD_MASK, 0, 1);
+DEFINE_2_MUXREG(pin222, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIDATA2SD_MASK, 0, 1);
+DEFINE_2_MUXREG(pin223, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIDATA3SD_MASK, 0, 1);
+DEFINE_2_MUXREG(pin224, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIADDR0ALE_MASK, 0, 1);
+DEFINE_2_MUXREG(pin225, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIADDR1CLECLK_MASK, 0, 1);
+DEFINE_2_MUXREG(pin226, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIADDR2_MASK, 0, 1);
+DEFINE_2_MUXREG(pin227, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCICECF_MASK, 0, 1);
+DEFINE_2_MUXREG(pin228, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCICEXD_MASK, 0, 1);
+DEFINE_2_MUXREG(pin229, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCICESDMMC_MASK, 0, 1);
+DEFINE_2_MUXREG(pin230, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCICDCF1_MASK, 0, 1);
+DEFINE_2_MUXREG(pin231, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCICDCF2_MASK, 0, 1);
+DEFINE_2_MUXREG(pin232, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCICDXD_MASK, 0, 1);
+DEFINE_2_MUXREG(pin233, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCICDSDMMC_MASK, 0, 1);
+DEFINE_2_MUXREG(pin234, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIDATADIR_MASK, 0, 1);
+DEFINE_2_MUXREG(pin235, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIDMARQWP_MASK, 0, 1);
+DEFINE_2_MUXREG(pin236, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIIORDRE_MASK, 0, 1);
+DEFINE_2_MUXREG(pin237, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIIOWRWE_MASK, 0, 1);
+DEFINE_2_MUXREG(pin238, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIRESETCF_MASK, 0, 1);
+DEFINE_2_MUXREG(pin239, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCICS0CE_MASK, 0, 1);
+DEFINE_2_MUXREG(pin240, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCICFINTR_MASK, 0, 1);
+DEFINE_2_MUXREG(pin241, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIIORDY_MASK, 0, 1);
+DEFINE_2_MUXREG(pin242, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCICS1_MASK, 0, 1);
+DEFINE_2_MUXREG(pin243, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIDMAACK_MASK, 0, 1);
+DEFINE_2_MUXREG(pin244, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCISDCMD_MASK, 0, 1);
+DEFINE_2_MUXREG(pin245, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCILEDS_MASK, 0, 1);
+DEFINE_2_MUXREG(keyboard_rowcol6_8_pins, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_KBD_ROWCOL68_MASK, 0, 1);
+DEFINE_2_MUXREG(uart0_pins, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_UART0_MASK, 0, 1);
+DEFINE_2_MUXREG(uart0_modem_pins, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_UART0_MODEM_MASK, 0, 1);
+DEFINE_2_MUXREG(gpt0_tmr0_pins, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_GPT0_TMR0_MASK, 0, 1);
+DEFINE_2_MUXREG(gpt0_tmr1_pins, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_GPT0_TMR1_MASK, 0, 1);
+DEFINE_2_MUXREG(gpt1_tmr0_pins, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_GPT1_TMR0_MASK, 0, 1);
+DEFINE_2_MUXREG(gpt1_tmr1_pins, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_GPT1_TMR1_MASK, 0, 1);
+DEFINE_2_MUXREG(touch_xy_pins, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_TOUCH_XY_MASK, 0, 1);
+
+static struct spear_gpio_pingroup spear1310_gpio_pingroup[] = {
+ GPIO_PINGROUP(i2c0_pins),
+ GPIO_PINGROUP(ssp0_pins),
+ GPIO_PINGROUP(ssp0_cs0_pins),
+ GPIO_PINGROUP(ssp0_cs1_2_pins),
+ GPIO_PINGROUP(i2s0_pins),
+ GPIO_PINGROUP(i2s1_pins),
+ GPIO_PINGROUP(clcd_pins),
+ GPIO_PINGROUP(clcd_high_res_pins),
+ GPIO_PINGROUP(pin18),
+ GPIO_PINGROUP(pin19),
+ GPIO_PINGROUP(pin20),
+ GPIO_PINGROUP(pin21),
+ GPIO_PINGROUP(pin22),
+ GPIO_PINGROUP(pin23),
+ GPIO_PINGROUP(pin143),
+ GPIO_PINGROUP(pin144),
+ GPIO_PINGROUP(pin145),
+ GPIO_PINGROUP(pin146),
+ GPIO_PINGROUP(pin147),
+ GPIO_PINGROUP(pin148),
+ GPIO_PINGROUP(pin149),
+ GPIO_PINGROUP(pin150),
+ GPIO_PINGROUP(pin151),
+ GPIO_PINGROUP(pin152),
+ GPIO_PINGROUP(smi_2_chips_pins),
+ GPIO_PINGROUP(pin54),
+ GPIO_PINGROUP(pin55),
+ GPIO_PINGROUP(pin56),
+ GPIO_PINGROUP(pin57),
+ GPIO_PINGROUP(pin58),
+ GPIO_PINGROUP(pin59),
+ GPIO_PINGROUP(pin60),
+ GPIO_PINGROUP(pin61),
+ GPIO_PINGROUP(pin62),
+ GPIO_PINGROUP(pin63),
+ GPIO_PINGROUP(pin_grp0),
+ GPIO_PINGROUP(pin_grp1),
+ GPIO_PINGROUP(pin_grp2),
+ GPIO_PINGROUP(pin_grp3),
+ GPIO_PINGROUP(pin_grp4),
+ GPIO_PINGROUP(pin_grp5),
+ GPIO_PINGROUP(pin_grp6),
+ GPIO_PINGROUP(pin_grp7),
+ GPIO_PINGROUP(pin_grp8),
+ GPIO_PINGROUP(nand_16bit_pins),
+ GPIO_PINGROUP(pin205),
+ GPIO_PINGROUP(pin206),
+ GPIO_PINGROUP(pin211),
+ GPIO_PINGROUP(pin212),
+ GPIO_PINGROUP(pin213),
+ GPIO_PINGROUP(pin214),
+ GPIO_PINGROUP(pin215),
+ GPIO_PINGROUP(pin216),
+ GPIO_PINGROUP(pin217),
+ GPIO_PINGROUP(pin218),
+ GPIO_PINGROUP(pin219),
+ GPIO_PINGROUP(pin220),
+ GPIO_PINGROUP(pin221),
+ GPIO_PINGROUP(pin222),
+ GPIO_PINGROUP(pin223),
+ GPIO_PINGROUP(pin224),
+ GPIO_PINGROUP(pin225),
+ GPIO_PINGROUP(pin226),
+ GPIO_PINGROUP(pin227),
+ GPIO_PINGROUP(pin228),
+ GPIO_PINGROUP(pin229),
+ GPIO_PINGROUP(pin230),
+ GPIO_PINGROUP(pin231),
+ GPIO_PINGROUP(pin232),
+ GPIO_PINGROUP(pin233),
+ GPIO_PINGROUP(pin234),
+ GPIO_PINGROUP(pin235),
+ GPIO_PINGROUP(pin236),
+ GPIO_PINGROUP(pin237),
+ GPIO_PINGROUP(pin238),
+ GPIO_PINGROUP(pin239),
+ GPIO_PINGROUP(pin240),
+ GPIO_PINGROUP(pin241),
+ GPIO_PINGROUP(pin242),
+ GPIO_PINGROUP(pin243),
+ GPIO_PINGROUP(pin244),
+ GPIO_PINGROUP(pin245),
+ GPIO_PINGROUP(keyboard_rowcol6_8_pins),
+ GPIO_PINGROUP(uart0_pins),
+ GPIO_PINGROUP(uart0_modem_pins),
+ GPIO_PINGROUP(gpt0_tmr0_pins),
+ GPIO_PINGROUP(gpt0_tmr1_pins),
+ GPIO_PINGROUP(gpt1_tmr0_pins),
+ GPIO_PINGROUP(gpt1_tmr1_pins),
+ GPIO_PINGROUP(touch_xy_pins),
+};
+
static struct spear_pinctrl_machdata spear1310_machdata = {
.pins = spear1310_pins,
.npins = ARRAY_SIZE(spear1310_pins),
@@ -2150,6 +2687,8 @@ static struct spear_pinctrl_machdata spear1310_machdata = {
.ngroups = ARRAY_SIZE(spear1310_pingroups),
.functions = spear1310_functions,
.nfunctions = ARRAY_SIZE(spear1310_functions),
+ .gpio_pingroups = spear1310_gpio_pingroup,
+ .ngpio_pingroups = ARRAY_SIZE(spear1310_gpio_pingroup),
.modes_supported = false,
};
diff --git a/drivers/pinctrl/spear/pinctrl-spear1340.c b/drivers/pinctrl/spear/pinctrl-spear1340.c
index a0eb057e55bd..0606b8cf3f2c 100644
--- a/drivers/pinctrl/spear/pinctrl-spear1340.c
+++ b/drivers/pinctrl/spear/pinctrl-spear1340.c
@@ -213,7 +213,7 @@ static const struct pinctrl_pin_desc spear1340_pins[] = {
* Pad multiplexing for making all pads as gpio's. This is done to override the
* values passed from bootloader and start from scratch.
*/
-static const unsigned pads_as_gpio_pins[] = { 251 };
+static const unsigned pads_as_gpio_pins[] = { 12, 88, 89, 251 };
static struct spear_muxreg pads_as_gpio_muxreg[] = {
{
.reg = PAD_FUNCTION_EN_1,
@@ -1692,7 +1692,43 @@ static struct spear_pingroup clcd_pingroup = {
.nmodemuxs = ARRAY_SIZE(clcd_modemux),
};
-static const char *const clcd_grps[] = { "clcd_grp" };
+/* Disable cld runtime to save panel damage */
+static struct spear_muxreg clcd_sleep_muxreg[] = {
+ {
+ .reg = PAD_SHARED_IP_EN_1,
+ .mask = ARM_TRACE_MASK | MIPHY_DBG_MASK,
+ .val = 0,
+ }, {
+ .reg = PAD_FUNCTION_EN_5,
+ .mask = CLCD_REG4_MASK | CLCD_AND_ARM_TRACE_REG4_MASK,
+ .val = 0x0,
+ }, {
+ .reg = PAD_FUNCTION_EN_6,
+ .mask = CLCD_AND_ARM_TRACE_REG5_MASK,
+ .val = 0x0,
+ }, {
+ .reg = PAD_FUNCTION_EN_7,
+ .mask = CLCD_AND_ARM_TRACE_REG6_MASK,
+ .val = 0x0,
+ },
+};
+
+static struct spear_modemux clcd_sleep_modemux[] = {
+ {
+ .muxregs = clcd_sleep_muxreg,
+ .nmuxregs = ARRAY_SIZE(clcd_sleep_muxreg),
+ },
+};
+
+static struct spear_pingroup clcd_sleep_pingroup = {
+ .name = "clcd_sleep_grp",
+ .pins = clcd_pins,
+ .npins = ARRAY_SIZE(clcd_pins),
+ .modemuxs = clcd_sleep_modemux,
+ .nmodemuxs = ARRAY_SIZE(clcd_sleep_modemux),
+};
+
+static const char *const clcd_grps[] = { "clcd_grp", "clcd_sleep_grp" };
static struct spear_function clcd_function = {
.name = "clcd",
.groups = clcd_grps,
@@ -1893,6 +1929,7 @@ static struct spear_pingroup *spear1340_pingroups[] = {
&sdhci_pingroup,
&cf_pingroup,
&xd_pingroup,
+ &clcd_sleep_pingroup,
&clcd_pingroup,
&arm_trace_pingroup,
&miphy_dbg_pingroup,
diff --git a/drivers/pinctrl/spear/pinctrl-spear300.c b/drivers/pinctrl/spear/pinctrl-spear300.c
index 4dfc2849b172..9a491007f42d 100644
--- a/drivers/pinctrl/spear/pinctrl-spear300.c
+++ b/drivers/pinctrl/spear/pinctrl-spear300.c
@@ -661,6 +661,8 @@ static int __devinit spear300_pinctrl_probe(struct platform_device *pdev)
spear3xx_machdata.ngroups = ARRAY_SIZE(spear300_pingroups);
spear3xx_machdata.functions = spear300_functions;
spear3xx_machdata.nfunctions = ARRAY_SIZE(spear300_functions);
+ spear3xx_machdata.gpio_pingroups = NULL;
+ spear3xx_machdata.ngpio_pingroups = 0;
spear3xx_machdata.modes_supported = true;
spear3xx_machdata.pmx_modes = spear300_pmx_modes;
diff --git a/drivers/pinctrl/spear/pinctrl-spear310.c b/drivers/pinctrl/spear/pinctrl-spear310.c
index 96883693fb7e..4d5dfe9c760a 100644
--- a/drivers/pinctrl/spear/pinctrl-spear310.c
+++ b/drivers/pinctrl/spear/pinctrl-spear310.c
@@ -388,6 +388,8 @@ static int __devinit spear310_pinctrl_probe(struct platform_device *pdev)
spear3xx_machdata.nfunctions = ARRAY_SIZE(spear310_functions);
pmx_init_addr(&spear3xx_machdata, PMX_CONFIG_REG);
+ pmx_init_gpio_pingroup_addr(spear3xx_machdata.gpio_pingroups,
+ spear3xx_machdata.ngpio_pingroups, PMX_CONFIG_REG);
spear3xx_machdata.modes_supported = false;
diff --git a/drivers/pinctrl/spear/pinctrl-spear320.c b/drivers/pinctrl/spear/pinctrl-spear320.c
index 020b1e0bdb3e..c996e26e3b6c 100644
--- a/drivers/pinctrl/spear/pinctrl-spear320.c
+++ b/drivers/pinctrl/spear/pinctrl-spear320.c
@@ -2240,6 +2240,10 @@ static struct spear_muxreg pwm2_pin_34_muxreg[] = {
.mask = PMX_SSP_CS_MASK,
.val = 0,
}, {
+ .reg = MODE_CONFIG_REG,
+ .mask = PMX_PWM_MASK,
+ .val = PMX_PWM_MASK,
+ }, {
.reg = IP_SEL_PAD_30_39_REG,
.mask = PMX_PL_34_MASK,
.val = PMX_PWM2_PL_34_VAL,
@@ -2956,9 +2960,9 @@ static struct spear_function mii2_function = {
};
/* Pad multiplexing for cadence mii 1_2 as smii or rmii device */
-static const unsigned smii0_1_pins[] = { 10, 11, 13, 14, 15, 16, 17, 18, 19, 20,
+static const unsigned rmii0_1_pins[] = { 10, 11, 13, 14, 15, 16, 17, 18, 19, 20,
21, 22, 23, 24, 25, 26, 27 };
-static const unsigned rmii0_1_pins[] = { 10, 11, 21, 22, 23, 24, 25, 26, 27 };
+static const unsigned smii0_1_pins[] = { 10, 11, 21, 22, 23, 24, 25, 26, 27 };
static struct spear_muxreg mii0_1_muxreg[] = {
{
.reg = PMX_CONFIG_REG,
@@ -3427,6 +3431,8 @@ static int __devinit spear320_pinctrl_probe(struct platform_device *pdev)
spear3xx_machdata.npmx_modes = ARRAY_SIZE(spear320_pmx_modes);
pmx_init_addr(&spear3xx_machdata, PMX_CONFIG_REG);
+ pmx_init_gpio_pingroup_addr(spear3xx_machdata.gpio_pingroups,
+ spear3xx_machdata.ngpio_pingroups, PMX_CONFIG_REG);
ret = spear_pinctrl_probe(pdev, &spear3xx_machdata);
if (ret)
diff --git a/drivers/pinctrl/spear/pinctrl-spear3xx.c b/drivers/pinctrl/spear/pinctrl-spear3xx.c
index 0242378f7cb8..12ee21af766b 100644
--- a/drivers/pinctrl/spear/pinctrl-spear3xx.c
+++ b/drivers/pinctrl/spear/pinctrl-spear3xx.c
@@ -481,7 +481,44 @@ struct spear_function spear3xx_timer_2_3_function = {
.ngroups = ARRAY_SIZE(timer_2_3_grps),
};
+/* Define muxreg arrays */
+DEFINE_MUXREG(firda_pins, 0, PMX_FIRDA_MASK, 0);
+DEFINE_MUXREG(i2c_pins, 0, PMX_I2C_MASK, 0);
+DEFINE_MUXREG(ssp_cs_pins, 0, PMX_SSP_CS_MASK, 0);
+DEFINE_MUXREG(ssp_pins, 0, PMX_SSP_MASK, 0);
+DEFINE_MUXREG(mii_pins, 0, PMX_MII_MASK, 0);
+DEFINE_MUXREG(gpio0_pin0_pins, 0, PMX_GPIO_PIN0_MASK, 0);
+DEFINE_MUXREG(gpio0_pin1_pins, 0, PMX_GPIO_PIN1_MASK, 0);
+DEFINE_MUXREG(gpio0_pin2_pins, 0, PMX_GPIO_PIN2_MASK, 0);
+DEFINE_MUXREG(gpio0_pin3_pins, 0, PMX_GPIO_PIN3_MASK, 0);
+DEFINE_MUXREG(gpio0_pin4_pins, 0, PMX_GPIO_PIN4_MASK, 0);
+DEFINE_MUXREG(gpio0_pin5_pins, 0, PMX_GPIO_PIN5_MASK, 0);
+DEFINE_MUXREG(uart0_ext_pins, 0, PMX_UART0_MODEM_MASK, 0);
+DEFINE_MUXREG(uart0_pins, 0, PMX_UART0_MASK, 0);
+DEFINE_MUXREG(timer_0_1_pins, 0, PMX_TIMER_0_1_MASK, 0);
+DEFINE_MUXREG(timer_2_3_pins, 0, PMX_TIMER_2_3_MASK, 0);
+
+static struct spear_gpio_pingroup spear3xx_gpio_pingroup[] = {
+ GPIO_PINGROUP(firda_pins),
+ GPIO_PINGROUP(i2c_pins),
+ GPIO_PINGROUP(ssp_cs_pins),
+ GPIO_PINGROUP(ssp_pins),
+ GPIO_PINGROUP(mii_pins),
+ GPIO_PINGROUP(gpio0_pin0_pins),
+ GPIO_PINGROUP(gpio0_pin1_pins),
+ GPIO_PINGROUP(gpio0_pin2_pins),
+ GPIO_PINGROUP(gpio0_pin3_pins),
+ GPIO_PINGROUP(gpio0_pin4_pins),
+ GPIO_PINGROUP(gpio0_pin5_pins),
+ GPIO_PINGROUP(uart0_ext_pins),
+ GPIO_PINGROUP(uart0_pins),
+ GPIO_PINGROUP(timer_0_1_pins),
+ GPIO_PINGROUP(timer_2_3_pins),
+};
+
struct spear_pinctrl_machdata spear3xx_machdata = {
.pins = spear3xx_pins,
.npins = ARRAY_SIZE(spear3xx_pins),
+ .gpio_pingroups = spear3xx_gpio_pingroup,
+ .ngpio_pingroups = ARRAY_SIZE(spear3xx_gpio_pingroup),
};
diff --git a/drivers/pinctrl/spear/pinctrl-spear3xx.h b/drivers/pinctrl/spear/pinctrl-spear3xx.h
index 31f44347f17c..7860b36053c4 100644
--- a/drivers/pinctrl/spear/pinctrl-spear3xx.h
+++ b/drivers/pinctrl/spear/pinctrl-spear3xx.h
@@ -15,6 +15,7 @@
#include "pinctrl-spear.h"
/* pad mux declarations */
+#define PMX_PWM_MASK (1 << 16)
#define PMX_FIRDA_MASK (1 << 14)
#define PMX_I2C_MASK (1 << 13)
#define PMX_SSP_CS_MASK (1 << 12)