* [PATCH 0/5] pinctrl: add new Samsung pinctrl driver and add Exynos4 support
@ 2012-03-11 12:46 Thomas Abraham
2012-03-11 12:46 ` [PATCH 1/5] pinctrl: add samsung pinctrl and gpiolib driver Thomas Abraham
` (5 more replies)
0 siblings, 6 replies; 19+ messages in thread
From: Thomas Abraham @ 2012-03-11 12:46 UTC (permalink / raw)
To: linux-arm-kernel
This patch series adds new pinctrl driver for Samsung SoC's. The driver supports
a gpiolib interface as well since Samsung SoC's have a combined pinmux/pinctrl
and gpio controller.
The intention of this driver is to replace the existing gpiolib driver and
provide drivers pinctrl subsystem interface to configure the pins/mux instead
of existing platform callbacks. At this point, the pinmux and pinconfig
functionality fully supported and gpiolib is partially supported. Additional
work is required to add gpio interrupts and wakeup interrupts support.
Hence, this is not ready for merge yet. The first two patches can be looked at
in detail. The last three patches are mainly work-in-progress and can be
glanced over.
The first patch adds a new pinctrl driver for Samsung. It provides interfaces
to the pinctrl and gpiolib subsystems. This driver provides a common framework
for all Samsung SoC's to enable the pinctrl and gpiolib support. The driver
accepts the information about pins, groups, functions and gpio chips using
the driver data.
The second patch adds information about the pins, groups, functions and gpio
chips for the Exynos4210 SoC's. This information is supplied to the Samsung
pinctrl driver using driver data. The pinctrl driver registers this information
with the pinctrl and gpiolib subsystems. Note: The information about the
commonly used groups and functions are added, this list is not exhaustive.
The third patch add support for all three pinctrl devices on Exynos4210 SoC.
It also adds a minimal common reusable pin maps for boards which are based on
Exynos4210 as an example. The pin maps is listed only for the sdhci2 controller
for now and this list needs to be expanded.
The fourth patch enables pinctrl driver support for Exynos4210 based Origen
board as an example of using pinctrl driver.
The fifth patch updates the sdhci-s3c driver to use the pinctrl driver
interface to setup the pin mux and config settings. This is only intended
to be a an example of how to replace the platform callbacks with the
pinctrl driver call.
This patchset is based on
http://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung.git
with all patches merged from
http://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl.git [for-next]
and tested working of sdhci2 controller on Origen board.
Thomas Abraham (5):
pinctrl: add samsung pinctrl and gpiolib driver
pinctrl: add exynos4 specific pins, groups, functions and gpio chip data
ARM: Exynos4: Add pinctrl devices and pin maps
ARM: Exynos: Enable pinctrl driver support for Origen board
mmc: sdhci-s3c: setup pins using pinctrl interface
arch/arm/mach-exynos/Kconfig | 1 +
arch/arm/mach-exynos/Makefile | 1 +
arch/arm/mach-exynos/common.h | 6 +
arch/arm/mach-exynos/dev-pinctrl.c | 115 +++++
arch/arm/mach-exynos/mach-origen.c | 7 +
arch/arm/plat-samsung/include/plat/devs.h | 3 +
arch/arm/plat-samsung/include/plat/pinctrl.h | 35 ++
drivers/mmc/host/sdhci-s3c.c | 15 +-
drivers/pinctrl/Kconfig | 10 +
drivers/pinctrl/Makefile | 2 +
drivers/pinctrl/pinctrl-exynos4.c | 522 +++++++++++++++++++++++
drivers/pinctrl/pinctrl-samsung.c | 589 ++++++++++++++++++++++++++
drivers/pinctrl/pinctrl-samsung.h | 143 +++++++
13 files changed, 1447 insertions(+), 2 deletions(-)
create mode 100644 arch/arm/mach-exynos/dev-pinctrl.c
create mode 100644 arch/arm/plat-samsung/include/plat/pinctrl.h
create mode 100644 drivers/pinctrl/pinctrl-exynos4.c
create mode 100644 drivers/pinctrl/pinctrl-samsung.c
create mode 100644 drivers/pinctrl/pinctrl-samsung.h
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 1/5] pinctrl: add samsung pinctrl and gpiolib driver
2012-03-11 12:46 [PATCH 0/5] pinctrl: add new Samsung pinctrl driver and add Exynos4 support Thomas Abraham
@ 2012-03-11 12:46 ` Thomas Abraham
2012-03-19 21:45 ` Stephen Warren
2012-03-11 12:46 ` [PATCH 2/5] pinctrl: add exynos4 specific pins, groups, functions and gpio chip data Thomas Abraham
` (4 subsequent siblings)
5 siblings, 1 reply; 19+ messages in thread
From: Thomas Abraham @ 2012-03-11 12:46 UTC (permalink / raw)
To: linux-arm-kernel
Add a new pinctrl and gpiolib driver for Samsung SoC's. This driver provides a
common framework for all Samsung SoC's to interface with the pinctrl and
gpiolib subsystems.
This driver is split into two parts: the pinctrl interface and the gpiolib
interface. The pinctrl interface registers pinctrl devices with the pinctrl
subsystem and gpiolib interface registers gpio chips with the gpiolib
subsystem. The information about the pins, pin groups, pin functions and
gpio chips, which are SoC specific, are all provided to the driver using
driver data. The driver registers all the pinctrl devices and gpio chips
which are found in the driver data.
Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
---
arch/arm/plat-samsung/include/plat/pinctrl.h | 35 ++
drivers/pinctrl/Kconfig | 3 +
drivers/pinctrl/Makefile | 1 +
drivers/pinctrl/pinctrl-samsung.c | 589 ++++++++++++++++++++++++++
drivers/pinctrl/pinctrl-samsung.h | 143 +++++++
5 files changed, 771 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/plat-samsung/include/plat/pinctrl.h
create mode 100644 drivers/pinctrl/pinctrl-samsung.c
create mode 100644 drivers/pinctrl/pinctrl-samsung.h
diff --git a/arch/arm/plat-samsung/include/plat/pinctrl.h b/arch/arm/plat-samsung/include/plat/pinctrl.h
new file mode 100644
index 0000000..0c226b2
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/pinctrl.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ * Copyright (c) 2012 Linaro Ltd
+ * http://www.linaro.org
+ *
+ * Samsung Pinctrl driver helper macros
+ *
+ * Author: Thomas Abraham <thomas.ab@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __PLAT_SAMSUNG_PINCTRL_H
+#define __PLAT_SAMSUNG_PINCTRL_H __FILE__
+
+#define _PUD_MASK 0xF
+#define PUD_NONE 0
+#define PUD_DOWN 1
+#define PUD_UP 2
+
+#define _DRV_SHIFT 4
+#define _DRV_MASK 0xF
+#define DRV_1X 0
+#define DRV_2X 1
+#define DRV_3X 2
+#define DRV_4X 3
+
+#define PINCTRL_CFG_PACK(PUD, DRV) ((DRV << _DRV_SHIFT) | PUD)
+#define PINCTRL_CFG_UNPACK_PUD(CFG) (CFG & _PUD_MASK)
+#define PINCTRL_CFG_UNPACK_DRV(CFG) ((CFG >> _DRV_SHIFT) & _DRV_MASK)
+
+#endif /* __PLAT_SAMSUNG_PINCTRL_H */
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index c6d29ff..a068d16 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -79,6 +79,9 @@ config PINCTRL_COH901
COH 901 335 and COH 901 571/3. They contain 3, 5 or 7
ports of 8 GPIO pins each.
+config PINCTRL_SAMSUNG
+ bool "Samsung pinctrl driver"
+
endmenu
endif
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index 754329b..eaccc1b 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -15,3 +15,4 @@ obj-$(CONFIG_PINCTRL_TEGRA20) += pinctrl-tegra20.o
obj-$(CONFIG_PINCTRL_TEGRA30) += pinctrl-tegra30.o
obj-$(CONFIG_PINCTRL_U300) += pinctrl-u300.o
obj-$(CONFIG_PINCTRL_COH901) += pinctrl-coh901.o
+obj-$(CONFIG_PINCTRL_SAMSUNG) += pinctrl-samsung.o
diff --git a/drivers/pinctrl/pinctrl-samsung.c b/drivers/pinctrl/pinctrl-samsung.c
new file mode 100644
index 0000000..262dc3b
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-samsung.c
@@ -0,0 +1,589 @@
+/*
+ * pin-controller/pin-mux/pin-config/gpio-driver for Samsung's SoC's.
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ * Copyright (c) 2012 Linaro Ltd
+ * http://www.linaro.org
+ *
+ * Author: Thomas Abraham <thomas.ab@samsung.com>
+ *
+ * This driver is divided into two main components, gpiolib subsystem interface
+ * and the pin-controller subsystem interface. This model help to better
+ * abstract the details of pad controller for all the Samsung SoC's. The driver
+ * is designed to be reusuable on all the Samsung SoC's providing both gpiolib
+ * and pinctrl subsystem interfaces.
+ *
+ * The driver functions are kept as generic as possible such that they are
+ * usable across multiple Samsung SoC's. The driver data differentiates the
+ * operation of the driver for each SoC by describing the complete
+ * pad-controller structure to the driver and the generic driver code operates
+ * on the SoC specific driver data. The driver data also includes runtime data
+ * required for the operation of the driver.
+ *
+ * List of ToDo's:
+ * 1. Add GPIO Interrupt support.
+ * 2. Add external interrupt (wakeup) support.
+ * 3 Add power management support.
+ * 4. Find a better way to populate data about pins and functions.
+ * 5. Add driver data, pins, groups, functions for all Samsung SoC's and test.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/pinctrl/pinconf.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/gpio.h>
+
+#include <plat/pinctrl.h>
+
+#include "pinctrl-samsung.h"
+
+/* check if the selector is a valid pin group selector */
+static int samsung_list_groups(struct pinctrl_dev *pctldev, unsigned selector)
+{
+ struct samsung_pinctrl_drv_data *drvdata;
+
+ drvdata = pinctrl_dev_get_drvdata(pctldev);
+ if (selector >= drvdata->nr_groups)
+ return -EINVAL;
+ return 0;
+}
+
+/* return the name of the group selected by the group selector */
+static const char *samsung_get_group_name(struct pinctrl_dev *pctldev,
+ unsigned selector)
+{
+ struct samsung_pinctrl_drv_data *drvdata;
+
+ drvdata = pinctrl_dev_get_drvdata(pctldev);
+ return drvdata->pin_groups[selector].name;
+}
+
+/* return the pin numbers associated with the specified group */
+static int samsung_get_group_pins(struct pinctrl_dev *pctldev,
+ unsigned selector, const unsigned **pins, unsigned *num_pins)
+{
+ struct samsung_pinctrl_drv_data *drvdata;
+
+ drvdata = pinctrl_dev_get_drvdata(pctldev);
+ *pins = drvdata->pin_groups[selector].pins;
+ *num_pins = drvdata->pin_groups[selector].num_pins;
+ return 0;
+}
+
+/* list of pinctrl callbacks for the pinctrl core */
+static struct pinctrl_ops samsung_pctrl_ops = {
+ .list_groups = samsung_list_groups,
+ .get_group_name = samsung_get_group_name,
+ .get_group_pins = samsung_get_group_pins,
+};
+
+
+/* check if the selector is a valid pin function selector */
+static int samsung_pinmux_list_funcs(struct pinctrl_dev *pctldev,
+ unsigned selector)
+{
+ struct samsung_pinctrl_drv_data *drvdata;
+
+ drvdata = pinctrl_dev_get_drvdata(pctldev);
+ if (selector >= drvdata->nr_groups)
+ return -EINVAL;
+ return 0;
+}
+
+/* return the name of the pin function specified */
+static const char *samsung_pinmux_get_fname(struct pinctrl_dev *pctldev,
+ unsigned selector)
+{
+ struct samsung_pinctrl_drv_data *drvdata;
+
+ drvdata = pinctrl_dev_get_drvdata(pctldev);
+ return drvdata->pmx_functions[selector].name;
+}
+
+/* return the groups associated for the specified function selector */
+static int samsung_pinmux_get_groups(struct pinctrl_dev *pctldev,
+ unsigned selector, const char * const **groups,
+ unsigned * const num_groups)
+{
+ struct samsung_pinctrl_drv_data *drvdata;
+
+ drvdata = pinctrl_dev_get_drvdata(pctldev);
+ *groups = drvdata->pmx_functions[selector].groups;
+ *num_groups = drvdata->pmx_functions[selector].num_groups;
+ return 0;
+}
+
+/*
+ * given a pin number that is local to a pin controller, find out the pin bank
+ * and the register base of the pin bank.
+ */
+static void pin_to_reg_bank(struct gpio_chip *gc, unsigned pin,
+ void __iomem **reg, unsigned long *offset,
+ struct samsung_pin_bank **bank)
+{
+ struct samsung_pinctrl_drv_data *drvdata;
+ struct samsung_pin_bank *b;
+
+ drvdata = dev_get_drvdata(gc->dev);
+ b = drvdata->ctrl->pin_banks;
+
+ while (b->pin_base + b->nr_pins < pin)
+ b++;
+
+ *reg = drvdata->virt_base + b->reg_offset;
+ *offset = pin - b->pin_base;
+ if (bank)
+ *bank = b;
+
+ /* some banks have two config registers in a single bank */
+ if (*offset * b->func_width > BITS_PER_LONG)
+ *reg += 4;
+}
+
+/* enable or disable a pinmux function */
+static void samsung_pimux_setup(struct pinctrl_dev *pctldev, unsigned selector,
+ unsigned group, bool enable)
+{
+ struct samsung_pinctrl_drv_data *drvdata;
+ const unsigned int *pin;
+ unsigned long data, pin_offset, cnt;
+ struct samsung_pin_bank *bank;
+ void __iomem *reg;
+ unsigned int mask, shift;
+
+ drvdata = pinctrl_dev_get_drvdata(pctldev);
+ pin = drvdata->pin_groups[group].pins;
+
+ /*
+ * for each pin in the pin group selected, program the correspoding pin
+ * pin function number in the config register.
+ */
+ for (cnt = 0; cnt < drvdata->pin_groups[group].num_pins; cnt++, pin++) {
+ pin_to_reg_bank(drvdata->gc, *pin - drvdata->ctrl->base,
+ ®, &pin_offset, &bank);
+ mask = (1 << bank->func_width) - 1;
+ shift = pin_offset * bank->func_width;
+
+ data = readl(reg);
+ data &= ~(mask << shift);
+ if (enable)
+ data |= drvdata->pin_groups[group].func << shift;
+ writel(data, reg);
+ }
+}
+
+/* enable a specified pinmux by writing to registers */
+static int samsung_pinmux_enable(struct pinctrl_dev *pctldev, unsigned selector,
+ unsigned group)
+{
+ samsung_pimux_setup(pctldev, selector, group, true);
+ return 0;
+}
+
+/* disable a specified pinmux by writing to registers */
+static void samsung_pinmux_disable(struct pinctrl_dev *pctldev,
+ unsigned selector, unsigned group)
+{
+ samsung_pimux_setup(pctldev, selector, group, false);
+}
+
+/*
+ * The calls to gpio_direction_output() and gpio_direction_input()
+ * leads to this function call (via the pinctrl_gpio_direction_{input|output}()
+ * function called from the gpiolib interface).
+ */
+static int samsung_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev,
+ struct pinctrl_gpio_range *range, unsigned offset, bool input)
+{
+ unsigned long data, pin_offset;
+ struct samsung_pin_bank *bank;
+ void __iomem *reg;
+ unsigned int mask, shift;
+
+ pin_to_reg_bank(range->gc, offset, ®, &pin_offset, &bank);
+ mask = (1 << bank->func_width) - 1;
+ shift = pin_offset * bank->func_width;
+
+ data = readl(reg);
+ data &= ~(mask << shift);
+ if (!input)
+ data |= FUNC_OUTPUT << shift;
+ writel(data, reg);
+ return 0;
+}
+
+/* list of pinmux callbacks for the pinmux vertical in pinctrl core */
+static struct pinmux_ops samsung_pinmux_ops = {
+ .list_functions = samsung_pinmux_list_funcs,
+ .get_function_name = samsung_pinmux_get_fname,
+ .get_function_groups = samsung_pinmux_get_groups,
+ .enable = samsung_pinmux_enable,
+ .disable = samsung_pinmux_disable,
+ .gpio_set_direction = samsung_pinmux_gpio_set_direction,
+};
+
+/* set the pull up/down and driver strength settings for a specified pin */
+static int samsung_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
+ unsigned long config)
+{
+ struct samsung_pinctrl_drv_data *drvdata;
+ unsigned long data, pin_offset;
+ struct samsung_pin_bank *bank;
+ void __iomem *reg;
+ unsigned int mask, shift;
+ unsigned int pud, drv;
+
+ drvdata = pinctrl_dev_get_drvdata(pctldev);
+ pin_to_reg_bank(drvdata->gc, pin - drvdata->ctrl->base, ®,
+ &pin_offset, &bank);
+
+ /* update the pull up/down configuration */
+ mask = (1 << bank->pud_width) - 1;
+ shift = pin_offset * bank->pud_width;
+ pud = PINCTRL_CFG_UNPACK_PUD(config);
+
+ if (drvdata->ctrl->xlate_pud)
+ pud = drvdata->ctrl->xlate_pud(pud);
+
+ data = readl(reg + PUD_REG);
+ data &= ~(mask << shift);
+ data |= (pud << shift);
+ writel(data, reg + PUD_REG);
+
+ /* update the drive strength configuration */
+ mask = (1 << bank->drv_width) - 1;
+ shift = pin_offset * bank->drv_width;
+ drv = PINCTRL_CFG_UNPACK_DRV(config);
+
+ if (drvdata->ctrl->xlate_drv)
+ drv = drvdata->ctrl->xlate_drv(drv);
+
+ data = readl(reg + DRV_REG);
+ data &= ~(mask << shift);
+ data |= (drv << shift);
+ writel(data, reg + DRV_REG);
+
+ return 0;
+}
+
+/*
+ * set the pull up/down and driver strength settings for all the pins in a
+ * specified pin group
+ */
+static int samsung_pinconf_group_set(struct pinctrl_dev *pctldev,
+ unsigned group, unsigned long config)
+{
+ struct samsung_pinctrl_drv_data *drvdata;
+ const unsigned int *pin;
+ unsigned int cnt;
+
+ drvdata = pinctrl_dev_get_drvdata(pctldev);
+ pin = drvdata->pin_groups[group].pins;
+
+ for (cnt = 0; cnt < drvdata->pin_groups[group].num_pins; cnt++, pin++)
+ samsung_pinconf_set(pctldev, *pin, config);
+
+ return 0;
+}
+
+/* reading pin pull up/down and driver strength settings not implemented */
+static int samsung_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin,
+ unsigned long *config)
+{
+ return -ENOTSUPP;
+}
+
+/* reading pin pull up/down and driver strength settings not implemented */
+static int samsung_pinconf_group_get(struct pinctrl_dev *pctldev,
+ unsigned int group, unsigned long *config)
+{
+ return -ENOTSUPP;
+}
+
+/* list of pinconfig callbacks for pinconfig vertical in the pinctrl code */
+static struct pinconf_ops samsung_pinconf_ops = {
+ .pin_config_get = samsung_pinconf_get,
+ .pin_config_set = samsung_pinconf_set,
+ .pin_config_group_get = samsung_pinconf_group_get,
+ .pin_config_group_set = samsung_pinconf_group_set,
+};
+
+/* gpiolib gpio_set callback function */
+static void samsung_gpio_set(struct gpio_chip *gc, unsigned offset, int value)
+{
+ void __iomem *reg;
+ unsigned long pin_offset, data;
+
+ pin_to_reg_bank(gc, offset, ®, &pin_offset, NULL);
+ data = readl(reg + DAT_REG);
+ data &= ~(1 << pin_offset);
+ if (value)
+ data |= 1 << pin_offset;
+ __raw_writel(data, reg + DAT_REG);
+}
+
+/* gpiolib gpio_get callback function */
+static int samsung_gpio_get(struct gpio_chip *gc, unsigned offset)
+{
+ void __iomem *reg;
+ unsigned long pin_offset, data;
+
+ pin_to_reg_bank(gc, offset, ®, &pin_offset, NULL);
+ data = readl(reg + DAT_REG);
+ data >>= pin_offset;
+ data &= 1;
+ return data;
+}
+
+/*
+ * gpiolib gpio_direction_input callback function. The setting of the pin
+ * mux function as 'gpio input' will be handled by the pinctrl susbsystem
+ * interface.
+ */
+static int samsung_gpio_direction_input(struct gpio_chip *gc, unsigned offset)
+{
+ return pinctrl_gpio_direction_input(gc->base + offset);
+}
+
+/*
+* gpiolib gpio_direction_output callback function. The setting of the pin
+* mux function as 'gpio output' will be handled by the pinctrl susbsystem
+* interface.
+*/
+static int samsung_gpio_direction_output(struct gpio_chip *gc, unsigned offset,
+ int value)
+{
+ int ret;
+
+ ret = pinctrl_gpio_direction_output(gc->base + offset);
+ if (!ret)
+ samsung_gpio_set(gc, offset, value);
+ return ret;
+}
+
+/* register the pinctrl interface with the pinctrl subsystem */
+static int __init samsung_pinctrl_register(struct platform_device *pdev,
+ struct samsung_pinctrl_drv_data *drvdata)
+{
+ struct pinctrl_desc *ctrldesc = drvdata->pctl;
+ struct pinctrl_pin_desc *pindesc, *pdesc;
+ struct samsung_pin_bank *pin_bank;
+ char *pin_names;
+ int pin, bank;
+
+ drvdata->pctl->pctlops = &samsung_pctrl_ops;
+ drvdata->pctl->pmxops = &samsung_pinmux_ops;
+ drvdata->pctl->confops = &samsung_pinconf_ops;
+
+ pindesc = devm_kzalloc(&pdev->dev, sizeof(*pindesc) *
+ drvdata->ctrl->nr_pins, GFP_KERNEL);
+ if (!pindesc) {
+ dev_err(&pdev->dev, "mem alloc for pin descriptors failed\n");
+ return -ENOMEM;
+ }
+ ctrldesc->pins = pindesc;
+ ctrldesc->npins = drvdata->ctrl->nr_pins;
+ ctrldesc->npins = drvdata->ctrl->nr_pins;
+
+ /* dynamically populate the pin number and pin name for pindesc */
+ for (pin = 0, pdesc = pindesc; pin < ctrldesc->npins; pin++, pdesc++)
+ pdesc->number = pin + drvdata->ctrl->base;
+
+ /*
+ * allocate space for storing the dynamically generated names for all
+ * the pins which belong to this pin-controller.
+ */
+ pin_names = devm_kzalloc(&pdev->dev, sizeof(char) * PIN_NAME_LENGTH *
+ drvdata->ctrl->nr_pins, GFP_KERNEL);
+ if (!pin_names) {
+ dev_err(&pdev->dev, "mem alloc for pin names failed\n");
+ return -ENOMEM;
+ }
+
+ /* for each pin, the name of the pin is pin-bank name + pin number */
+ for (bank = 0; bank < drvdata->ctrl->nr_banks; bank++) {
+ pin_bank = &drvdata->ctrl->pin_banks[bank];
+ for (pin = 0; pin < pin_bank->nr_pins; pin++) {
+ sprintf(pin_names, "%s-%d", pin_bank->name, pin);
+ pdesc = pindesc + pin_bank->pin_base + pin;
+ pdesc->name = pin_names;
+ pin_names += PIN_NAME_LENGTH;
+ }
+ }
+
+ drvdata->pctl_dev = pinctrl_register(ctrldesc, &pdev->dev, drvdata);
+ if (!drvdata->pctl_dev) {
+ dev_err(&pdev->dev, "could not register pinctrl driver\n");
+ return -EINVAL;
+ }
+
+ drvdata->ctrl->grange->base = drvdata->ctrl->base;
+ drvdata->ctrl->grange->npins = drvdata->ctrl->nr_pins;
+ drvdata->ctrl->grange->gc = drvdata->gc;
+ pinctrl_add_gpio_range(drvdata->pctl_dev, drvdata->ctrl->grange);
+
+ return 0;
+}
+
+/* register the gpiolib interface with the gpiolib subsystem */
+static int __init samsung_gpiolib_register(struct platform_device *pdev,
+ struct samsung_pinctrl_drv_data *drvdata)
+{
+ struct gpio_chip *gc;
+ int ret;
+
+ gc = devm_kzalloc(&pdev->dev, sizeof(*gc), GFP_KERNEL);
+ if (!gc) {
+ dev_err(&pdev->dev, "mem alloc for gpio_chip failed\n");
+ return -ENOMEM;
+ }
+
+ drvdata->gc = gc;
+ gc->base = drvdata->ctrl->base;
+ gc->ngpio = drvdata->ctrl->nr_pins;
+ gc->dev = &pdev->dev;
+ gc->set = samsung_gpio_set;
+ gc->get = samsung_gpio_get;
+ gc->direction_input = samsung_gpio_direction_input;
+ gc->direction_output = samsung_gpio_direction_output;
+ gc->label = drvdata->ctrl->label;
+ gc->owner = THIS_MODULE;
+ ret = gpiochip_add(gc);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to register gpio_chip %s, error "
+ "code: %d\n", gc->label, ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static const struct of_device_id samsung_pinctrl_dt_match[];
+
+static inline struct samsung_pinctrl_drv_data *samsung_pinctrl_get_driver_data(
+ struct platform_device *pdev)
+{
+#ifdef CONFIG_OF
+ if (pdev->dev.of_node) {
+ const struct of_device_id *match;
+ const struct of_node *node = pdev->dev.of_node;
+ match = of_match_node(samsung_pinctrl_dt_match, node);
+ return (struct samsung_pinctrl_drv_data *)match->data;
+ }
+#endif
+ return (struct samsung_pinctrl_drv_data *)
+ platform_get_device_id(pdev)->driver_data + (pdev->id);
+}
+
+static int __devinit samsung_pinctrl_probe(struct platform_device *pdev)
+{
+ struct samsung_pinctrl_drv_data *drvdata;
+ struct resource *res;
+ int ret;
+
+ drvdata = samsung_pinctrl_get_driver_data(pdev);
+ if (!drvdata) {
+ dev_err(&pdev->dev, "driver data not available\n");
+ return -EINVAL;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "cannot find IO resource\n");
+ return -ENOENT;
+ }
+
+ res = request_mem_region(res->start, resource_size(res),
+ pdev->name);
+ if (!res) {
+ dev_err(&pdev->dev, "request for mem region failed\n");
+ return -EBUSY;
+ }
+
+ drvdata->virt_base = ioremap(res->start, resource_size(res));
+ if (!drvdata->virt_base) {
+ dev_err(&pdev->dev, "ioremap failed\n");
+ return -EINVAL;
+ }
+
+ ret = samsung_gpiolib_register(pdev, drvdata);
+ if (ret)
+ return ret;
+
+ ret = samsung_pinctrl_register(pdev, drvdata);
+ if (ret)
+ return ret;
+
+ platform_set_drvdata(pdev, drvdata);
+ return 0;
+}
+
+/* driver data for various samsung soc's */
+#ifdef CONFIG_CPU_EXYNOS4210
+
+#define EXYNOS4210_PCTRL_DRVDATA ((kernel_ulong_t)&exynos4210_pinctrl_drv_data)
+#else
+#define EXYNOS4210_PCTRL_DRVDATA ((kernel_ulong_t)NULL)
+#endif /* CONFIG_CPU_EXYNOS4210 */
+
+static struct platform_device_id samsung_pinctrl_driver_ids[] = {
+ {
+ .name = "exynos4-pinctrl",
+ .driver_data = EXYNOS4210_PCTRL_DRVDATA,
+ },
+ { },
+};
+MODULE_DEVICE_TABLE(platform, samsung_pinctrl_driver_ids);
+
+#ifdef CONFIG_OF
+static const struct of_device_id samsung_pinctrl_dt_match[] = {
+#ifdef CONFIG_CPU_EXYNOS4210
+ { .compatible = "samsung,exynos4210-pinctrl0",
+ .data = (void *)&exynos4210_pinctrl_drv_data[0] },
+ { .compatible = "samsung,exynos4210-pinctrl1",
+ .data = (void *)&exynos4210_pinctrl_drv_data[1] },
+ { .compatible = "samsung,exynos4210-pinctrl2",
+ .data = (void *)&exynos4210_pinctrl_drv_data[2] },
+#endif /* CONFIG_CPU_EXYNOS4210 */
+ {},
+};
+MODULE_DEVICE_TABLE(of, samsung_pinctrl_dt_match);
+#endif /* CONFIG_OF */
+
+static struct platform_driver samsung_pinctrl_driver = {
+ .probe = samsung_pinctrl_probe,
+ .id_table = samsung_pinctrl_driver_ids,
+ .driver = {
+ .name = "samsung-pinctrl",
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(samsung_pinctrl_dt_match),
+ },
+};
+
+static int __init samsung_pinctrl_drv_register(void)
+{
+ return platform_driver_register(&samsung_pinctrl_driver);
+}
+postcore_initcall(samsung_pinctrl_drv_register);
+
+static void __exit samsung_pinctrl_drv_unregister(void)
+{
+ platform_driver_unregister(&samsung_pinctrl_driver);
+}
+module_exit(samsung_pinctrl_drv_unregister);
+
+MODULE_AUTHOR("Thomas Abraham <thomas.ab@samsung.com>");
+MODULE_DESCRIPTION("Samsung pinctrl driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/pinctrl/pinctrl-samsung.h b/drivers/pinctrl/pinctrl-samsung.h
new file mode 100644
index 0000000..d28bd46
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-samsung.h
@@ -0,0 +1,143 @@
+/*
+ * pin-controller/pin-mux/pin-config/gpio-driver for Samsung's SoC's.
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ * Copyright (c) 2012 Linaro Ltd
+ * http://www.linaro.org
+ *
+ * Author: Thomas Abraham <thomas.ab@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __PINCTRL_SAMSUNG_H
+#define __PINCTRL_SAMSUNG_H
+
+/* register offsets within a pin bank */
+#define DAT_REG 0x4
+#define PUD_REG 0x8
+#define DRV_REG 0xC
+
+/* pinmux function number for pin as gpio output line */
+#define FUNC_OUTPUT 0x1
+
+/* maximum length of a pin in pin descriptor */
+#define PIN_NAME_LENGTH 10
+
+#define PIN_GROUP(n, p, f) \
+ { \
+ .name = n, \
+ .pins = p, \
+ .num_pins = ARRAY_SIZE(p), \
+ .func = f \
+ }
+
+#define PMX_FUNC(n, g) \
+ { \
+ .name = n, \
+ .groups = g, \
+ .num_groups = ARRAY_SIZE(g), \
+ }
+
+/**
+ * struct samsung_pin_bank: represent a controller pin-bank.
+ * @reg_offset: starting offset of the pin-bank registers.
+ * @pin_base: starting pin number of the bank.
+ * @nr_pins: number of pins included in this bank.
+ * @func_width: width of the function selector bit field.
+ * @pud_width: width of the pin pull up/down selector bit field.
+ * @drc_width: width of the pin driver strength selector bit field.
+ * @irq_base: starting eint number of the bank.
+ * @name: name to be prefixed for each pin in this pin bank.
+ */
+struct samsung_pin_bank {
+ unsigned int reg_offset;
+ unsigned int pin_base;
+ unsigned int nr_pins;
+ unsigned int func_width;
+ unsigned int pud_width;
+ unsigned int drv_width;
+ unsigned int irq_base;
+ char *name;
+};
+
+/**
+ * struct samsung_pin_ctrl: represent a pin controller.
+ * @pin_banks: list of pin banks included in this controller.
+ * @nr_banks: number of pin banks.
+ * @base: starting system wide pin number.
+ * @nr_pins: number of pins supported by the controller.
+ * @xlate_pud: soc specific callback to translate PUD_XXX values to soc
+ * specific pull up/down register values (optional).
+ * @xlate_drv: soc specific callback to translate DRV_XXX values to soc
+ * specific driver strength register values (optional).
+ * @label: for debug information.
+ */
+struct samsung_pin_ctrl {
+ struct pinctrl_gpio_range *grange;
+ struct samsung_pin_bank *pin_banks;
+ unsigned int nr_banks;
+ unsigned int base;
+ unsigned int nr_pins;
+ int (*xlate_pud)(unsigned int pud);
+ int (*xlate_drv)(unsigned int drv);
+ char *label;
+};
+
+/**
+ * struct samsung_pinctrl_drv_data: wrapper for holding driver data together.
+ * @virt_base: register base address of the controller.
+ * @ctrl: pin controller instance managed by the driver.
+ * @pctl: pin controller descriptor registered with the pinctrl subsystem.
+ * @pctl_dev: cookie representing pinctrl device instance.
+ * @pin_groups: list of pin groups available to the driver.
+ * @nr_groups: number of such pin groups.
+ * @pmx_functions: list of pin functions available to the driver.
+ * @nr_function: number of such pin functions.
+ * @gc: gpio_chip instance registered with gpiolib.
+ */
+struct samsung_pinctrl_drv_data {
+ void __iomem *virt_base;
+ struct samsung_pin_ctrl *ctrl;
+ struct pinctrl_desc *pctl;
+ struct pinctrl_dev *pctl_dev;
+ const struct samsung_pin_group *pin_groups;
+ unsigned int nr_groups;
+ const struct samsung_pmx_func *pmx_functions;
+ unsigned int nr_functions;
+ struct gpio_chip *gc;
+};
+
+/**
+ * struct samsung_pin_group: represent group of pins of a pinmux function.
+ * @name: name of the pin group, used to lookup the group.
+ * @pins: the pins included in this group.
+ * @num_pins: number of pins included in this group.
+ * @func: the function number to be programmed when selected.
+ */
+struct samsung_pin_group {
+ const char *name;
+ const unsigned int *pins;
+ const unsigned int num_pins;
+ unsigned int func;
+};
+
+/**
+ * struct samsung_pmx_func: represent a pin function.
+ * @name: name of the pin function, used to lookup the function.
+ * @groups: one or more names of pin groups that provide this function.
+ * @num_groups: number of groups included in @groups.
+ */
+struct samsung_pmx_func {
+ const char *name;
+ const char * const *groups;
+ const unsigned num_groups;
+};
+
+extern struct samsung_pinctrl_drv_data exynos4210_pinctrl_drv_data[];
+
+#endif /* __PINCTRL_SAMSUNG_H */
--
1.6.6.rc2
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 2/5] pinctrl: add exynos4 specific pins, groups, functions and gpio chip data
2012-03-11 12:46 [PATCH 0/5] pinctrl: add new Samsung pinctrl driver and add Exynos4 support Thomas Abraham
2012-03-11 12:46 ` [PATCH 1/5] pinctrl: add samsung pinctrl and gpiolib driver Thomas Abraham
@ 2012-03-11 12:46 ` Thomas Abraham
2012-03-11 12:46 ` [PATCH 3/5] ARM: Exynos4: Add pinctrl devices and pin maps Thomas Abraham
` (3 subsequent siblings)
5 siblings, 0 replies; 19+ messages in thread
From: Thomas Abraham @ 2012-03-11 12:46 UTC (permalink / raw)
To: linux-arm-kernel
Add Exynos4 specific information about pins, groups, functions and gpio
chip data that will be used as driver data by the Samsung pinctrl driver.
Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
---
drivers/pinctrl/Kconfig | 7 +
drivers/pinctrl/Makefile | 1 +
drivers/pinctrl/pinctrl-exynos4.c | 522 +++++++++++++++++++++++++++++++++++++
3 files changed, 530 insertions(+), 0 deletions(-)
create mode 100644 drivers/pinctrl/pinctrl-exynos4.c
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index a068d16..b798a52 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -82,6 +82,13 @@ config PINCTRL_COH901
config PINCTRL_SAMSUNG
bool "Samsung pinctrl driver"
+config PINCTRL_EXYNOS4
+ bool "Pinctrl driver data for Exynos4 SoC"
+ depends on ARCH_EXYNOS4
+ select PINCTRL_SAMSUNG
+ select PINMUX
+ select PINCONF
+
endmenu
endif
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index eaccc1b..79b6cda 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -16,3 +16,4 @@ obj-$(CONFIG_PINCTRL_TEGRA30) += pinctrl-tegra30.o
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-exynos4.o
diff --git a/drivers/pinctrl/pinctrl-exynos4.c b/drivers/pinctrl/pinctrl-exynos4.c
new file mode 100644
index 0000000..5eb6168
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-exynos4.c
@@ -0,0 +1,522 @@
+/*
+ * Exynos4 specific driver data for Samsung pinctrl and gpiolib driver.
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ * Copyright (c) 2011 Linaro Ltd
+ * http://www.linaro.org
+ *
+ * This file contains the Exynos4 specific driver data for the Samsung
+ * pinctrl/gpiolib interface drivers.
+ *
+ * ToDo: Add additional pin functions and pin groups available on Exynos4210.
+ *
+ * Author: Thomas Abraham <thomas.ab@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/pinctrl/pinconf.h>
+#include <linux/gpio.h>
+
+#include <plat/pinctrl.h>
+
+#include "pinctrl-samsung.h"
+
+/* Exynos4210 Pin-Controller 0 pin list */
+static unsigned int exynos4210_i2c2_pins[] = {
+ EXYNOS4_GPA0(6), EXYNOS4_GPA0(7),
+};
+
+static unsigned int exynos4210_i2c3_pins[] = {
+ EXYNOS4_GPA1(2), EXYNOS4_GPA1(3),
+};
+
+static unsigned int exynos4210_spi0_pins[] = {
+ EXYNOS4_GPB(0), EXYNOS4_GPB(1), EXYNOS4_GPB(2), EXYNOS4_GPB(3),
+};
+
+static unsigned int exynos4210_i2c4_pins[] = {
+ EXYNOS4_GPB(2), EXYNOS4_GPB(3),
+};
+
+static unsigned int exynos4210_spi1_pins[] = {
+ EXYNOS4_GPB(4), EXYNOS4_GPB(5), EXYNOS4_GPB(6), EXYNOS4_GPB(7),
+};
+
+static unsigned int exynos4210_i2c5_pins[] = {
+ EXYNOS4_GPB(6), EXYNOS4_GPB(7),
+};
+
+static unsigned int exynos4210_i2s1_pcm1_ac97_pins[] = {
+ EXYNOS4_GPC0(0), EXYNOS4_GPC0(1), EXYNOS4_GPC0(2), EXYNOS4_GPC0(3),
+ EXYNOS4_GPC0(4),
+};
+
+static unsigned int exynos4210_i2s2_pcm2_pins[] = {
+ EXYNOS4_GPC1(0), EXYNOS4_GPC1(1), EXYNOS4_GPC1(2), EXYNOS4_GPC1(3),
+ EXYNOS4_GPC1(4),
+};
+
+static unsigned int exynos4210_spdif_pins[] = {
+ EXYNOS4_GPC1(0), EXYNOS4_GPC1(1),
+};
+
+static unsigned int exynos4210_spi2_pins[] = {
+ EXYNOS4_GPC1(1), EXYNOS4_GPC1(2), EXYNOS4_GPC1(3), EXYNOS4_GPC1(4),
+};
+
+static unsigned int exynos4210_i2c6_pins[] = {
+ EXYNOS4_GPC1(3), EXYNOS4_GPC1(4),
+};
+
+static unsigned int exynos4210_i2c7_pins[] = {
+ EXYNOS4_GPD0(2), EXYNOS4_GPD0(3),
+};
+
+static unsigned int exynos4210_i2c0_pins[] = {
+ EXYNOS4_GPD1(0), EXYNOS4_GPD1(1),
+};
+
+static unsigned int exynos4210_cam_b_pins[] = {
+ EXYNOS4_GPE0(0), EXYNOS4_GPE0(1), EXYNOS4_GPE0(2), EXYNOS4_GPE0(3),
+ EXYNOS4_GPE0(4), EXYNOS4_GPE1(0), EXYNOS4_GPE1(1), EXYNOS4_GPE1(2),
+ EXYNOS4_GPE1(3), EXYNOS4_GPE1(4), EXYNOS4_GPE1(5), EXYNOS4_GPE1(6),
+ EXYNOS4_GPE1(7),
+};
+
+static unsigned int exynos4210_lcd_pins[] = {
+ EXYNOS4_GPF0(0), EXYNOS4_GPF0(1), EXYNOS4_GPF0(2), EXYNOS4_GPF0(3),
+ EXYNOS4_GPF0(4), EXYNOS4_GPF0(5), EXYNOS4_GPF0(6), EXYNOS4_GPF0(7),
+ EXYNOS4_GPF1(0), EXYNOS4_GPF1(1), EXYNOS4_GPF1(2), EXYNOS4_GPF1(3),
+ EXYNOS4_GPF1(4), EXYNOS4_GPF1(5), EXYNOS4_GPF1(6), EXYNOS4_GPF1(7),
+ EXYNOS4_GPF2(0), EXYNOS4_GPF2(1), EXYNOS4_GPF2(2), EXYNOS4_GPF2(3),
+ EXYNOS4_GPF2(4), EXYNOS4_GPF2(5), EXYNOS4_GPF2(6), EXYNOS4_GPF2(7),
+ EXYNOS4_GPF3(0), EXYNOS4_GPF3(1), EXYNOS4_GPF3(2), EXYNOS4_GPF3(3),
+};
+
+/* Exynos4210 Pin-Controller 1 pin list */
+static unsigned int exynos4210_cam_a_pins[] = {
+ EXYNOS4_GPJ0(0), EXYNOS4_GPJ0(1), EXYNOS4_GPJ0(2), EXYNOS4_GPJ0(3),
+ EXYNOS4_GPJ0(4), EXYNOS4_GPJ0(5), EXYNOS4_GPJ0(6), EXYNOS4_GPJ0(7),
+ EXYNOS4_GPJ1(0), EXYNOS4_GPJ1(1), EXYNOS4_GPJ1(2), EXYNOS4_GPJ1(3),
+ EXYNOS4_GPJ1(4),
+};
+
+static unsigned int exynos4210_sdhci0_4_ctrl_pins[] = {
+ EXYNOS4_GPK0(0), EXYNOS4_GPK0(1)
+};
+
+static unsigned int exynos4210_sdhci0_4_cd_pins[] = {
+ EXYNOS4_GPK0(2)
+};
+
+static unsigned int exynos4210_sdhci0_4_4bit_pins[] = {
+ EXYNOS4_GPK0(3), EXYNOS4_GPK0(4), EXYNOS4_GPK0(5), EXYNOS4_GPK0(6)
+};
+
+static unsigned int exynos4210_sdhci0_4_8bit_pins[] = {
+ EXYNOS4_GPK1(3), EXYNOS4_GPK1(4), EXYNOS4_GPK1(5), EXYNOS4_GPK1(6)
+};
+
+static unsigned int exynos4210_sdhci1_ctrl_pins[] = {
+ EXYNOS4_GPK1(0), EXYNOS4_GPK1(1)
+};
+
+static unsigned int exynos4210_sdhci1_cd_pins[] = {
+ EXYNOS4_GPK1(2)
+};
+
+static unsigned int exynos4210_sdhci1_4bit_pins[] = {
+ EXYNOS4_GPK1(3), EXYNOS4_GPK1(4), EXYNOS4_GPK1(5), EXYNOS4_GPK1(6)
+};
+
+static unsigned int exynos4210_sdhci2_ctrl_pins[] = {
+ EXYNOS4_GPK2(0), EXYNOS4_GPK2(1)
+};
+
+static unsigned int exynos4210_sdhci2_cd_pins[] = {
+ EXYNOS4_GPK2(2)
+};
+
+static unsigned int exynos4210_sdhci2_4bit_pins[] = {
+ EXYNOS4_GPK2(3), EXYNOS4_GPK2(4), EXYNOS4_GPK2(5), EXYNOS4_GPK2(6)
+};
+
+static unsigned int exynos4210_sdhci2_8bit_pins[] = {
+ EXYNOS4_GPK3(3), EXYNOS4_GPK3(4), EXYNOS4_GPK3(5), EXYNOS4_GPK3(6)
+};
+
+static unsigned int exynos4210_sdhci3_ctrl_pins[] = {
+ EXYNOS4_GPK3(0), EXYNOS4_GPK3(1)
+};
+
+static unsigned int exynos4210_sdhci3_cd_pins[] = {
+ EXYNOS4_GPK3(2)
+};
+
+static unsigned int exynos4210_sdhci3_4bit_pins[] = {
+ EXYNOS4_GPK3(3), EXYNOS4_GPK3(4), EXYNOS4_GPK3(5), EXYNOS4_GPK3(6)
+};
+
+/* Exynos4210 Pin-Controller 2 pin list */
+static unsigned int exynos4210_i2s0_pins[] = {
+ EXYNOS4_GPZ(0), EXYNOS4_GPZ(1), EXYNOS4_GPZ(2), EXYNOS4_GPZ(3),
+ EXYNOS4_GPZ(4), EXYNOS4_GPZ(5), EXYNOS4_GPZ(6), EXYNOS4_GPZ(7)
+};
+
+static unsigned int exynos4210_pcm0_pins[] = {
+ EXYNOS4_GPZ(0), EXYNOS4_GPZ(1), EXYNOS4_GPZ(2), EXYNOS4_GPZ(3),
+ EXYNOS4_GPZ(4), EXYNOS4_GPZ(5),
+};
+
+/*
+ * list of pin groups available for pin-controller[0] of Exynos4210.
+ */
+static const struct samsung_pin_group exynos4210_pin_groups0[] = {
+ PIN_GROUP("i2c2_grp", exynos4210_i2c2_pins, 3),
+ PIN_GROUP("i2c3_grp", exynos4210_i2c3_pins, 3),
+ PIN_GROUP("spi0_grp", exynos4210_spi0_pins, 2),
+ PIN_GROUP("i2c4_grp", exynos4210_i2c4_pins, 3),
+ PIN_GROUP("spi1_grp", exynos4210_spi1_pins, 2),
+ PIN_GROUP("i2c5_grp", exynos4210_i2c5_pins, 3),
+ PIN_GROUP("i2s1_grp", exynos4210_i2s1_pcm1_ac97_pins, 2),
+ PIN_GROUP("pcm1_grp", exynos4210_i2s1_pcm1_ac97_pins, 3),
+ PIN_GROUP("ac97_grp", exynos4210_i2s1_pcm1_ac97_pins, 4),
+ PIN_GROUP("i2s2_grp", exynos4210_i2s2_pcm2_pins, 2),
+ PIN_GROUP("pcm2_grp", exynos4210_i2s2_pcm2_pins, 3),
+ PIN_GROUP("spdif_grp", exynos4210_spdif_pins, 4),
+ PIN_GROUP("spi2_grp", exynos4210_spi2_pins, 5),
+ PIN_GROUP("i2c6_grp", exynos4210_i2c6_pins, 4),
+ PIN_GROUP("i2c7_grp", exynos4210_i2c7_pins, 3),
+ PIN_GROUP("i2c0_grp", exynos4210_i2c0_pins, 2),
+ PIN_GROUP("camb_grp", exynos4210_cam_b_pins, 3),
+ PIN_GROUP("lcd_grp", exynos4210_lcd_pins, 2),
+};
+
+/*
+ * list of pin groups available for pin-controller[1] of Exynos4210.
+ */
+static const struct samsung_pin_group exynos4210_pin_groups1[] = {
+ PIN_GROUP("cama_grp", exynos4210_cam_a_pins, 2),
+ PIN_GROUP("sdhci0_ctrl_grp", exynos4210_sdhci0_4_ctrl_pins, 2),
+ PIN_GROUP("sdhci0_cd_grp", exynos4210_sdhci0_4_cd_pins, 2),
+ PIN_GROUP("sdhci0_4bit_grp", exynos4210_sdhci0_4_4bit_pins, 2),
+ PIN_GROUP("sdhci0_8bit_grp", exynos4210_sdhci0_4_8bit_pins, 3),
+ PIN_GROUP("sdhci1_ctrl_grp", exynos4210_sdhci1_ctrl_pins, 2),
+ PIN_GROUP("sdhci1_cd_grp", exynos4210_sdhci1_cd_pins, 2),
+ PIN_GROUP("sdhci1_4bit_grp", exynos4210_sdhci1_4bit_pins, 2),
+ PIN_GROUP("sdhci2_ctrl_grp", exynos4210_sdhci2_ctrl_pins, 2),
+ PIN_GROUP("sdhci2_cd_grp", exynos4210_sdhci2_cd_pins, 2),
+ PIN_GROUP("sdhci2_4bit_grp", exynos4210_sdhci2_4bit_pins, 2),
+ PIN_GROUP("sdhci2_8bit_grp", exynos4210_sdhci2_8bit_pins, 3),
+ PIN_GROUP("sdhci3_ctrl_grp", exynos4210_sdhci3_ctrl_pins, 2),
+ PIN_GROUP("sdhci3_cd_grp", exynos4210_sdhci3_cd_pins, 2),
+ PIN_GROUP("sdhci3_4bit_grp", exynos4210_sdhci3_4bit_pins, 2),
+ PIN_GROUP("sdhci4_ctrl_grp", exynos4210_sdhci0_4_ctrl_pins, 3),
+ PIN_GROUP("sdhci4_cd_grp", exynos4210_sdhci0_4_cd_pins, 3),
+ PIN_GROUP("sdhci4_4bit_grp", exynos4210_sdhci0_4_4bit_pins, 3),
+ PIN_GROUP("sdhci4_8bit_grp", exynos4210_sdhci0_4_8bit_pins, 4),
+};
+
+/*
+ * list of pin groups available for pin-controller[2] of Exynos4210.
+ */
+static const struct samsung_pin_group exynos4210_pin_groups2[] = {
+ PIN_GROUP("i2s0_grp", exynos4210_i2s0_pins, 2),
+ PIN_GROUP("pcm0_grp", exynos4210_pcm0_pins, 3),
+};
+
+/*
+ * list of group names which are included per pin-function of Exynos4210
+ * pin controller 0
+ */
+static const char * const i2c2_groups[] = { "i2c2_grp" };
+static const char * const i2c3_groups[] = { "i2c3_grp" };
+static const char * const spi0_groups[] = { "spi0_grp" };
+static const char * const i2c4_groups[] = { "i2c4_grp" };
+static const char * const spi1_groups[] = { "spi1_grp" };
+static const char * const i2c5_groups[] = { "i2c5_grp" };
+static const char * const i2s1_groups[] = { "i2s1_grp" };
+static const char * const pcm1_groups[] = { "pcm1_grp" };
+static const char * const ac97_groups[] = { "ac97_grp" };
+static const char * const i2s2_groups[] = { "i2s2_grp" };
+static const char * const pcm2_groups[] = { "pcm2_grp" };
+static const char * const spdif_groups[] = { "spdif_grp" };
+static const char * const spi2_groups[] = { "spi2_grp" };
+static const char * const i2c6_groups[] = { "i2c6_grp" };
+static const char * const i2c7_groups[] = { "i2c7_grp" };
+static const char * const i2c0_groups[] = { "i2c0_grp" };
+static const char * const camb_groups[] = { "camb_grp" };
+static const char * const lcd_groups[] = { "lcd_grp" };
+
+/*
+ * list of group names which are included per pin-function of Exynos4210
+ * pin controller 1
+ */
+static const char * const cama_groups[] = { "cama_grp" };
+static const char * const sdhci0_groups[] = { "sdhci0_ctrl_grp",
+ "sdhci0_cd_grp", "sdhci0_4bit_grp", "sdhci0_8bit_grp" };
+static const char * const sdhci1_groups[] = { "sdhci1_ctrl_grp",
+ "sdhci1_cd_grp", "sdhci1_4bit_grp" };
+static const char * const sdhci2_groups[] = { "sdhci2_ctrl_grp",
+ "sdhci2_cd_grp", "sdhci2_4bit_grp", "sdhci2_8bit_grp" };
+static const char * const sdhci3_groups[] = { "sdhci3_ctrl_grp",
+ "sdhci3_cd_grp", "sdhci3_4bit_grp" };
+static const char * const sdhci4_groups[] = { "sdhci4_ctrl_grp",
+ "sdhci4_cd_grp", "sdhci4_4bit_grp", "sdhci4_8bit_grp" };
+
+/*
+ * list of group names which are included per pin-function of Exynos4210
+ * pin controller 2
+ */
+static const char * const i2s0_groups[] = { "i2s0_grp" };
+static const char * const pcm0_groups[] = { "pcm0_grp" };
+
+/*
+ * list of function names supported by the pinmux controller 0 of exynos4210.
+ */
+static const struct samsung_pmx_func exynos4210_pmx_functions0[] = {
+ PMX_FUNC("i2c2-mux", i2c2_groups),
+ PMX_FUNC("i2c3-mux", i2c3_groups),
+ PMX_FUNC("spi0-mux", i2c3_groups),
+ PMX_FUNC("spi0-mux", i2c3_groups),
+ PMX_FUNC("i2c4-mux", i2c4_groups),
+ PMX_FUNC("spi1-mux", spi1_groups),
+ PMX_FUNC("i2c5-mux", i2c5_groups),
+ PMX_FUNC("i2s1-mux", i2s1_groups),
+ PMX_FUNC("pcm1-mux", pcm1_groups),
+ PMX_FUNC("ac97-mux", ac97_groups),
+ PMX_FUNC("i2s2-mux", i2s2_groups),
+ PMX_FUNC("pcm2-mux", pcm2_groups),
+ PMX_FUNC("spdif-mux", spdif_groups),
+ PMX_FUNC("spi2-mux", spi2_groups),
+ PMX_FUNC("i2c6-mux", i2c6_groups),
+ PMX_FUNC("i2c7-mux", i2c7_groups),
+ PMX_FUNC("i2c0-mux", i2c0_groups),
+ PMX_FUNC("camb-mux", camb_groups),
+ PMX_FUNC("lcd-mux", lcd_groups),
+};
+
+/*
+ * list of function names supported by the pinmux controller 1 of exynos4210.
+ */
+static const struct samsung_pmx_func exynos4210_pmx_functions1[] = {
+ PMX_FUNC("cama-mux", cama_groups),
+ PMX_FUNC("sdhci0-mux", sdhci0_groups),
+ PMX_FUNC("sdhci1-mux", sdhci1_groups),
+ PMX_FUNC("sdhci2-mux", sdhci2_groups),
+ PMX_FUNC("sdhci3-mux", sdhci3_groups),
+ PMX_FUNC("sdhci4-mux", sdhci4_groups),
+};
+
+/*
+ * list of function names supported by the pinmux controller 1 of exynos4210.
+ */
+static const struct samsung_pmx_func exynos4210_pmx_functions2[] = {
+ PMX_FUNC("i2s0-mux", i2s0_groups),
+ PMX_FUNC("pcm0-mux", pcm0_groups),
+};
+
+#define EXYNOS4_PIN_BANK(offset, __gpio, id) \
+ { \
+ .reg_offset = offset, \
+ .pin_base = (__gpio##_START), \
+ .nr_pins = (__gpio##_NR), \
+ .func_width = 4, \
+ .pud_width = 2, \
+ .drv_width = 2, \
+ .name = id \
+ }
+
+/* pin banks of pin-controller 0 */
+static struct samsung_pin_bank exynos4210_pin_banks0[] = {
+ EXYNOS4_PIN_BANK(0x000, EXYNOS4_GPIO_A0, "gpa0"),
+ EXYNOS4_PIN_BANK(0x020, EXYNOS4_GPIO_A1, "gpa1"),
+ EXYNOS4_PIN_BANK(0x040, EXYNOS4_GPIO_B, "gpb"),
+ EXYNOS4_PIN_BANK(0x060, EXYNOS4_GPIO_C0, "gpc0"),
+ EXYNOS4_PIN_BANK(0x080, EXYNOS4_GPIO_C1, "gpc1"),
+ EXYNOS4_PIN_BANK(0x0A0, EXYNOS4_GPIO_D0, "gpd0"),
+ EXYNOS4_PIN_BANK(0x0C0, EXYNOS4_GPIO_D1, "gpd1"),
+ EXYNOS4_PIN_BANK(0x0E0, EXYNOS4_GPIO_E0, "gpe0"),
+ EXYNOS4_PIN_BANK(0x100, EXYNOS4_GPIO_E1, "gpe1"),
+ EXYNOS4_PIN_BANK(0x120, EXYNOS4_GPIO_E2, "gpe2"),
+ EXYNOS4_PIN_BANK(0x140, EXYNOS4_GPIO_E3, "gpe3"),
+ EXYNOS4_PIN_BANK(0x160, EXYNOS4_GPIO_E4, "gpe4"),
+ EXYNOS4_PIN_BANK(0x180, EXYNOS4_GPIO_F0, "gpf0"),
+ EXYNOS4_PIN_BANK(0x1A0, EXYNOS4_GPIO_F1, "gpf1"),
+ EXYNOS4_PIN_BANK(0x1C0, EXYNOS4_GPIO_F2, "gpf2"),
+ EXYNOS4_PIN_BANK(0x1E0, EXYNOS4_GPIO_F3, "gpf3"),
+};
+
+#define EXYNOS4_PIN_BANK1(offset, __gpio, id) \
+ { \
+ .reg_offset = offset, \
+ .pin_base = (__gpio##_START) - EXYNOS4_GPIO_J0_START,\
+ .nr_pins = (__gpio##_NR), \
+ .func_width = 4, \
+ .pud_width = 2, \
+ .drv_width = 2, \
+ .name = id, \
+ }
+
+/* pin banks of pin-controller 1 */
+static struct samsung_pin_bank exynos4210_pin_banks1[] = {
+ EXYNOS4_PIN_BANK1(0x000, EXYNOS4_GPIO_J0, "gpj0"),
+ EXYNOS4_PIN_BANK1(0x020, EXYNOS4_GPIO_J1, "gpj1"),
+ EXYNOS4_PIN_BANK1(0x040, EXYNOS4_GPIO_K0, "gpk0"),
+ EXYNOS4_PIN_BANK1(0x060, EXYNOS4_GPIO_K1, "gpk1"),
+ EXYNOS4_PIN_BANK1(0x080, EXYNOS4_GPIO_K2, "gpk2"),
+ EXYNOS4_PIN_BANK1(0x0A0, EXYNOS4_GPIO_K3, "gpk3"),
+ EXYNOS4_PIN_BANK1(0x0C0, EXYNOS4_GPIO_L0, "gpl0"),
+ EXYNOS4_PIN_BANK1(0x0E0, EXYNOS4_GPIO_L1, "gpl1"),
+ EXYNOS4_PIN_BANK1(0x100, EXYNOS4_GPIO_L2, "gpl2"),
+ EXYNOS4_PIN_BANK1(0x120, EXYNOS4_GPIO_Y0, "gpy0"),
+ EXYNOS4_PIN_BANK1(0x140, EXYNOS4_GPIO_Y1, "gpy1"),
+ EXYNOS4_PIN_BANK1(0x160, EXYNOS4_GPIO_Y2, "gpy2"),
+ EXYNOS4_PIN_BANK1(0x180, EXYNOS4_GPIO_Y3, "gpy3"),
+ EXYNOS4_PIN_BANK1(0x1A0, EXYNOS4_GPIO_Y4, "gpy4"),
+ EXYNOS4_PIN_BANK1(0x1C0, EXYNOS4_GPIO_Y5, "gpy5"),
+ EXYNOS4_PIN_BANK1(0x1E0, EXYNOS4_GPIO_Y6, "gpy6"),
+ EXYNOS4_PIN_BANK1(0xC00, EXYNOS4_GPIO_X0, "gpx0"),
+ EXYNOS4_PIN_BANK1(0xC20, EXYNOS4_GPIO_X1, "gpx1"),
+ EXYNOS4_PIN_BANK1(0xC40, EXYNOS4_GPIO_X2, "gpx2"),
+ EXYNOS4_PIN_BANK1(0xC60, EXYNOS4_GPIO_X3, "gpx3"),
+};
+
+#define EXYNOS4_PIN_BANK2(offset, __gpio, id) \
+ { \
+ .reg_offset = offset, \
+ .pin_base = (__gpio##_START) - EXYNOS4_GPIO_Z_START,\
+ .nr_pins = (__gpio##_NR), \
+ .func_width = 4, \
+ .pud_width = 2, \
+ .drv_width = 2, \
+ .name = id, \
+ }
+
+/* pin banks of pin-controller 2 */
+static struct samsung_pin_bank exynos4210_pin_banks2[] = {
+ EXYNOS4_PIN_BANK2(0x000, EXYNOS4_GPIO_Z, "gpz"),
+};
+
+/* gpio range instance for pinctrl 0 */
+static struct pinctrl_gpio_range exynos4210_pctrl0_gpio_range = {
+ .name = "exynos4210_gpio_range0",
+ .id = 0,
+};
+
+/* gpio range instance for pinctrl 1 */
+static struct pinctrl_gpio_range exynos4210_pctrl1_gpio_range = {
+ .name = "exynos4210_gpio_range1",
+ .id = 0,
+};
+
+/* gpio range instance for pinctrl 2 */
+static struct pinctrl_gpio_range exynos4210_pctrl2_gpio_range = {
+ .name = "exynos4210_gpio_range2",
+ .id = 0,
+};
+
+/*
+ * Exynos4210 specific callback to translate PUD_xxx values into Exynos4210
+ * specific register values.
+ */
+static int exynos4210_xlate_pud(unsigned int pud)
+{
+ if (pud == PUD_UP)
+ return 3;
+ else
+ return pud;
+}
+
+/*
+ * Exynos4210 specific callback to translate DRV_xxx values into Exynos4210
+ * specific register values.
+ */
+static int exynos4210_xlate_drv(unsigned int drv)
+{
+ switch (drv) {
+ case DRV_3X:
+ return 1;
+ case DRV_2X:
+ return 2;
+ default:
+ return drv;
+ }
+}
+
+/*
+ * Samsung pinctrl driver data for Exynos4210 SoC. Exynos4210 SoC includes
+ * three gpio/pin-mux/pinconfig controllers.
+ */
+struct samsung_pinctrl_drv_data exynos4210_pinctrl_drv_data[] = {
+ {
+ /* pin-controller instance 0 data */
+ .ctrl = &(struct samsung_pin_ctrl) {
+ .grange = &exynos4210_pctrl0_gpio_range,
+ .pin_banks = exynos4210_pin_banks0,
+ .nr_banks = ARRAY_SIZE(exynos4210_pin_banks0),
+ .base = EXYNOS4_GPIO_A0_START,
+ .nr_pins = EXYNOS4_GPIO_J0_START - 1,
+ .xlate_pud = exynos4210_xlate_pud,
+ .xlate_drv = exynos4210_xlate_drv,
+ .label = "exynos4210-gpio-ctrl0",
+ },
+ .pctl = &(struct pinctrl_desc) {
+ .name = "exynos4210_pinctrl",
+ .owner = THIS_MODULE,
+ },
+ .pin_groups = exynos4210_pin_groups0,
+ .nr_groups = ARRAY_SIZE(exynos4210_pin_groups0),
+ .pmx_functions = exynos4210_pmx_functions0,
+ .nr_functions = ARRAY_SIZE(exynos4210_pmx_functions0),
+ }, {
+ /* pin-controller instance 1 data */
+ .ctrl = &(struct samsung_pin_ctrl) {
+ .grange = &exynos4210_pctrl1_gpio_range,
+ .pin_banks = exynos4210_pin_banks1,
+ .nr_banks = ARRAY_SIZE(exynos4210_pin_banks1),
+ .base = EXYNOS4_GPIO_J0_START,
+ .nr_pins = EXYNOS4_GPIO_Z_START -
+ EXYNOS4_GPIO_J0_START,
+ .xlate_pud = exynos4210_xlate_pud,
+ .xlate_drv = exynos4210_xlate_drv,
+ .label = "exynos4210-gpio-ctrl1",
+ },
+ .pctl = &(struct pinctrl_desc) {
+ .name = "exynos4210_pinctrl",
+ .owner = THIS_MODULE,
+ },
+ .pin_groups = exynos4210_pin_groups1,
+ .nr_groups = ARRAY_SIZE(exynos4210_pin_groups1),
+ .pmx_functions = exynos4210_pmx_functions1,
+ .nr_functions = ARRAY_SIZE(exynos4210_pmx_functions1),
+ }, {
+ /* pin-controller instance 2 data */
+ .ctrl = &(struct samsung_pin_ctrl) {
+ .grange = &exynos4210_pctrl2_gpio_range,
+ .pin_banks = exynos4210_pin_banks2,
+ .nr_banks = ARRAY_SIZE(exynos4210_pin_banks2),
+ .base = EXYNOS4_GPIO_Z_START,
+ .nr_pins = EXYNOS4_GPIO_Z_NR,
+ .xlate_pud = exynos4210_xlate_pud,
+ .xlate_drv = exynos4210_xlate_drv,
+ .label = "exynos4210-gpio-ctrl2",
+ },
+ .pctl = &(struct pinctrl_desc) {
+ .name = "exynos4210_pinctrl",
+ .owner = THIS_MODULE,
+ },
+ .pin_groups = exynos4210_pin_groups2,
+ .nr_groups = ARRAY_SIZE(exynos4210_pin_groups2),
+ .pmx_functions = exynos4210_pmx_functions2,
+ .nr_functions = ARRAY_SIZE(exynos4210_pmx_functions2),
+ },
+};
--
1.6.6.rc2
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 3/5] ARM: Exynos4: Add pinctrl devices and pin maps
2012-03-11 12:46 [PATCH 0/5] pinctrl: add new Samsung pinctrl driver and add Exynos4 support Thomas Abraham
2012-03-11 12:46 ` [PATCH 1/5] pinctrl: add samsung pinctrl and gpiolib driver Thomas Abraham
2012-03-11 12:46 ` [PATCH 2/5] pinctrl: add exynos4 specific pins, groups, functions and gpio chip data Thomas Abraham
@ 2012-03-11 12:46 ` Thomas Abraham
2012-03-11 21:17 ` Kukjin Kim
2012-03-11 12:46 ` [PATCH 4/5] ARM: Exynos: Enable pinctrl driver support for Origen board Thomas Abraham
` (2 subsequent siblings)
5 siblings, 1 reply; 19+ messages in thread
From: Thomas Abraham @ 2012-03-11 12:46 UTC (permalink / raw)
To: linux-arm-kernel
Add the three pinctrl platform devices and the pin maps for Exynos4.
Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
---
arch/arm/mach-exynos/Kconfig | 1 +
arch/arm/mach-exynos/Makefile | 1 +
arch/arm/mach-exynos/common.h | 6 ++
arch/arm/mach-exynos/dev-pinctrl.c | 115 +++++++++++++++++++++++++++++
arch/arm/plat-samsung/include/plat/devs.h | 3 +
5 files changed, 126 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/mach-exynos/dev-pinctrl.c
diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig
index c49d450..3e6a1cd 100644
--- a/arch/arm/mach-exynos/Kconfig
+++ b/arch/arm/mach-exynos/Kconfig
@@ -18,6 +18,7 @@ choice
config ARCH_EXYNOS4
bool "SAMSUNG EXYNOS4"
select HAVE_SMP
+ select PINCTRL
select MIGHT_HAVE_CACHE_L2X0
help
Samsung EXYNOS4 SoCs based systems
diff --git a/arch/arm/mach-exynos/Makefile b/arch/arm/mach-exynos/Makefile
index 6fd8dd9..dbac5f9 100644
--- a/arch/arm/mach-exynos/Makefile
+++ b/arch/arm/mach-exynos/Makefile
@@ -56,6 +56,7 @@ obj-$(CONFIG_EXYNOS4_DEV_SYSMMU) += dev-sysmmu.o
obj-$(CONFIG_EXYNOS4_DEV_DWMCI) += dev-dwmci.o
obj-$(CONFIG_EXYNOS4_DEV_DMA) += dma.o
obj-$(CONFIG_EXYNOS4_DEV_USB_OHCI) += dev-ohci.o
+obj-$(CONFIG_PINCTRL_SAMSUNG) += dev-pinctrl.o
obj-$(CONFIG_ARCH_EXYNOS) += setup-i2c0.o
obj-$(CONFIG_EXYNOS4_SETUP_FIMC) += setup-fimc.o
diff --git a/arch/arm/mach-exynos/common.h b/arch/arm/mach-exynos/common.h
index 677b546..64f3c57 100644
--- a/arch/arm/mach-exynos/common.h
+++ b/arch/arm/mach-exynos/common.h
@@ -52,4 +52,10 @@ void exynos4212_register_clocks(void);
#define exynos4212_register_clocks()
#endif
+#ifdef CONFIG_PINCTRL_SAMSUNG
+extern int exynos4210_pinctrl_register_def_mappings(void);
+#else
+#define exynos4210_pinctrl_register_def_mappings()
+#endif
+
#endif /* __ARCH_ARM_MACH_EXYNOS_COMMON_H */
diff --git a/arch/arm/mach-exynos/dev-pinctrl.c b/arch/arm/mach-exynos/dev-pinctrl.c
new file mode 100644
index 0000000..d909052
--- /dev/null
+++ b/arch/arm/mach-exynos/dev-pinctrl.c
@@ -0,0 +1,115 @@
+/*
+ * platform device for all the instances of pinctrl.
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/pinctrl/machine.h>
+
+#include <plat/devs.h>
+#include <plat/pinctrl.h>
+
+#include <mach/map.h>
+
+static struct resource exynos4_pinctrl_resource0[] = {
+ [0] = {
+ .start = EXYNOS4_PA_GPIO1,
+ .end = EXYNOS4_PA_GPIO1 + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_GPIO_XA,
+ .end = IRQ_GPIO_XA,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device exynos4_pinctrl0 = {
+ .name = "exynos4-pinctrl",
+ .id = 0,
+ .resource = exynos4_pinctrl_resource0,
+ .num_resources = ARRAY_SIZE(exynos4_pinctrl_resource0),
+};
+
+static struct resource exynos4_pinctrl_resource1[] = {
+ [0] = {
+ .start = EXYNOS4_PA_GPIO2,
+ .end = EXYNOS4_PA_GPIO2 + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_GPIO_XB,
+ .end = IRQ_GPIO_XB,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device exynos4_pinctrl1 = {
+ .name = "exynos4-pinctrl",
+ .id = 1,
+ .resource = exynos4_pinctrl_resource1,
+ .num_resources = ARRAY_SIZE(exynos4_pinctrl_resource1),
+};
+
+static struct resource exynos4_pinctrl_resource2[] = {
+ [0] = {
+ .start = EXYNOS4_PA_GPIO3,
+ .end = EXYNOS4_PA_GPIO3 + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+struct platform_device exynos4_pinctrl2 = {
+ .name = "exynos4-pinctrl",
+ .id = 2,
+ .resource = exynos4_pinctrl_resource2,
+ .num_resources = ARRAY_SIZE(exynos4_pinctrl_resource2),
+};
+
+/* pin config options. todo: add other options here. */
+static unsigned long pcfg_pu_drv3[] __initdata = {
+ PINCTRL_CFG_PACK(PUD_UP, DRV_4X),
+};
+
+static unsigned long pcfg_pn_drv3[] __initdata = {
+ PINCTRL_CFG_PACK(PUD_NONE, DRV_4X),
+};
+
+/* Exynos4210 SoC default pin-maps reusable by Exynos4210 based boards*/
+
+static struct pinctrl_map __initdata exynos4210_sdhci2_8bit_map[] = {
+ PIN_MAP_MUX_GROUP("exynos4-sdhci.2", "sdhci-pcfg8", "exynos4-pinctrl.1", "sdhci2_ctrl_grp", "sdhci2-mux"),
+ PIN_MAP_MUX_GROUP("exynos4-sdhci.2", "sdhci-pcfg8", "exynos4-pinctrl.1", "sdhci2_cd_grp", "sdhci2-mux"),
+ PIN_MAP_MUX_GROUP("exynos4-sdhci.2", "sdhci-pcfg8", "exynos4-pinctrl.1", "sdhci2_4bit_grp", "sdhci2-mux"),
+ PIN_MAP_MUX_GROUP("exynos4-sdhci.2", "sdhci-pcfg8", "exynos4-pinctrl.1", "sdhci2_8bit_grp", "sdhci2-mux"),
+ PIN_MAP_CONFIGS_GROUP("exynos4-sdhci.2", "sdhci-pcfg8", "exynos4-pinctrl.1", "sdhci2_ctrl_grp", pcfg_pn_drv3),
+ PIN_MAP_CONFIGS_GROUP("exynos4-sdhci.2", "sdhci-pcfg8", "exynos4-pinctrl.1", "sdhci2_cd_grp", pcfg_pu_drv3),
+ PIN_MAP_CONFIGS_GROUP("exynos4-sdhci.2", "sdhci-pcfg8", "exynos4-pinctrl.1", "sdhci2_4bit_grp", pcfg_pu_drv3),
+ PIN_MAP_CONFIGS_GROUP("exynos4-sdhci.2", "sdhci-pcfg8", "exynos4-pinctrl.1", "sdhci2_8bit_grp", pcfg_pu_drv3),
+};
+
+static struct pinctrl_map __initdata exynos4210_sdhci2_4bit_map[] = {
+ PIN_MAP_MUX_GROUP("exynos4-sdhci.2", "sdhci-pcfg4", "exynos4-pinctrl.1", "sdhci2_ctrl_grp", "sdhci2-mux"),
+ PIN_MAP_MUX_GROUP("exynos4-sdhci.2", "sdhci-pcfg4", "exynos4-pinctrl.1", "sdhci2_cd_grp", "sdhci2-mux"),
+ PIN_MAP_MUX_GROUP("exynos4-sdhci.2", "sdhci-pcfg4", "exynos4-pinctrl.1", "sdhci2_4bit_grp", "sdhci2-mux"),
+ PIN_MAP_CONFIGS_GROUP("exynos4-sdhci.2", "sdhci-pcfg4", "exynos4-pinctrl.1", "sdhci2_ctrl_grp", pcfg_pn_drv3),
+ PIN_MAP_CONFIGS_GROUP("exynos4-sdhci.2", "sdhci-pcfg4", "exynos4-pinctrl.1", "sdhci2_cd_grp", pcfg_pu_drv3),
+ PIN_MAP_CONFIGS_GROUP("exynos4-sdhci.2", "sdhci-pcfg4", "exynos4-pinctrl.1", "sdhci2_4bit_grp", pcfg_pu_drv3),
+};
+
+int __init exynos4210_pinctrl_register_def_mappings(void)
+{
+ pinctrl_register_mappings(exynos4210_sdhci2_8bit_map, ARRAY_SIZE(exynos4210_sdhci2_8bit_map));
+ pinctrl_register_mappings(exynos4210_sdhci2_4bit_map, ARRAY_SIZE(exynos4210_sdhci2_4bit_map));
+ return 0;
+}
diff --git a/arch/arm/plat-samsung/include/plat/devs.h b/arch/arm/plat-samsung/include/plat/devs.h
index 2dd5267..760445f 100644
--- a/arch/arm/plat-samsung/include/plat/devs.h
+++ b/arch/arm/plat-samsung/include/plat/devs.h
@@ -133,6 +133,9 @@ extern struct platform_device exynos4_device_pcm2;
extern struct platform_device exynos4_device_pd[];
extern struct platform_device exynos4_device_spdif;
extern struct platform_device exynos4_device_sysmmu;
+extern struct platform_device exynos4_pinctrl0;
+extern struct platform_device exynos4_pinctrl1;
+extern struct platform_device exynos4_pinctrl2;
extern struct platform_device samsung_asoc_dma;
extern struct platform_device samsung_asoc_idma;
--
1.6.6.rc2
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 4/5] ARM: Exynos: Enable pinctrl driver support for Origen board
2012-03-11 12:46 [PATCH 0/5] pinctrl: add new Samsung pinctrl driver and add Exynos4 support Thomas Abraham
` (2 preceding siblings ...)
2012-03-11 12:46 ` [PATCH 3/5] ARM: Exynos4: Add pinctrl devices and pin maps Thomas Abraham
@ 2012-03-11 12:46 ` Thomas Abraham
2012-03-11 12:46 ` [PATCH 5/5] mmc: sdhci-s3c: setup pins using pinctrl interface Thomas Abraham
2012-03-13 10:13 ` [PATCH 0/5] pinctrl: add new Samsung pinctrl driver and add Exynos4 support Linus Walleij
5 siblings, 0 replies; 19+ messages in thread
From: Thomas Abraham @ 2012-03-11 12:46 UTC (permalink / raw)
To: linux-arm-kernel
Add the pinctrl platform devices for static registration and add
default pin maps.
Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
---
arch/arm/mach-exynos/mach-origen.c | 7 +++++++
1 files changed, 7 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-exynos/mach-origen.c b/arch/arm/mach-exynos/mach-origen.c
index 02c242e..4e39a9b 100644
--- a/arch/arm/mach-exynos/mach-origen.c
+++ b/arch/arm/mach-exynos/mach-origen.c
@@ -21,6 +21,8 @@
#include <linux/mfd/max8997.h>
#include <linux/lcd.h>
#include <linux/rfkill-gpio.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/pinctrl/machine.h>
#include <asm/mach/arch.h>
#include <asm/hardware/gic.h>
@@ -41,6 +43,7 @@
#include <plat/pd.h>
#include <plat/fb.h>
#include <plat/mfc.h>
+#include <plat/pinctrl.h>
#include <mach/ohci.h>
#include <mach/map.h>
@@ -622,6 +625,9 @@ static struct platform_device origen_device_bluetooth = {
};
static struct platform_device *origen_devices[] __initdata = {
+ &exynos4_pinctrl0,
+ &exynos4_pinctrl1,
+ &exynos4_pinctrl2,
&s3c_device_hsmmc2,
&s3c_device_hsmmc0,
&s3c_device_i2c0,
@@ -697,6 +703,7 @@ static void __init origen_reserve(void)
static void __init origen_machine_init(void)
{
+ exynos4210_pinctrl_register_def_mappings();
origen_power_init();
s3c_i2c0_set_platdata(NULL);
--
1.6.6.rc2
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 5/5] mmc: sdhci-s3c: setup pins using pinctrl interface
2012-03-11 12:46 [PATCH 0/5] pinctrl: add new Samsung pinctrl driver and add Exynos4 support Thomas Abraham
` (3 preceding siblings ...)
2012-03-11 12:46 ` [PATCH 4/5] ARM: Exynos: Enable pinctrl driver support for Origen board Thomas Abraham
@ 2012-03-11 12:46 ` Thomas Abraham
2012-03-11 21:25 ` Kukjin Kim
` (3 more replies)
2012-03-13 10:13 ` [PATCH 0/5] pinctrl: add new Samsung pinctrl driver and add Exynos4 support Linus Walleij
5 siblings, 4 replies; 19+ messages in thread
From: Thomas Abraham @ 2012-03-11 12:46 UTC (permalink / raw)
To: linux-arm-kernel
The platform specific callback to setup the sdhci pin mux and pin config
is removed and the pinctrl subsystem interface is used to setup the
mux and config.
Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
---
drivers/mmc/host/sdhci-s3c.c | 15 +++++++++++++--
1 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c
index ea0767e..76c1c36 100644
--- a/drivers/mmc/host/sdhci-s3c.c
+++ b/drivers/mmc/host/sdhci-s3c.c
@@ -22,6 +22,7 @@
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
+#include <linux/pinctrl/consumer.h>
#include <linux/mmc/host.h>
@@ -50,6 +51,7 @@ struct sdhci_s3c {
struct platform_device *pdev;
struct resource *ioarea;
struct s3c_sdhci_platdata *pdata;
+ struct pinctrl *pinctrl;
unsigned int cur_clk;
int ext_cd_irq;
int ext_cd_gpio;
@@ -529,6 +531,9 @@ static inline struct sdhci_s3c_drv_data *sdhci_s3c_get_driver_data(
platform_get_device_id(pdev)->driver_data;
}
+#include <plat/map-s5p.h>
+#include <plat/map-base.h>
+
static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
{
struct s3c_sdhci_platdata *pdata;
@@ -538,6 +543,7 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
struct sdhci_s3c *sc;
struct resource *res;
int ret, irq, ptr, clks;
+ char *pstate;
if (!pdev->dev.platform_data && !pdev->dev.of_node) {
dev_err(dev, "no device data specified\n");
@@ -643,8 +649,13 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
}
/* Ensure we have minimal gpio selected CMD/CLK/Detect */
- if (pdata->cfg_gpio)
- pdata->cfg_gpio(pdev, pdata->max_width);
+ pstate = pdata->max_width ? "sdhci-pcfg8" : "sdhci-pcfg4";
+ sc->pinctrl = pinctrl_get_select(&pdev->dev, pstate);
+ if (IS_ERR(sc->pinctrl)) {
+ dev_err(dev, "failed to setup pin configuration\n");
+ ret = -ENXIO;
+ goto err_req_regs;
+ }
host->hw_name = "samsung-hsmmc";
host->ops = &sdhci_s3c_ops;
--
1.6.6.rc2
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 3/5] ARM: Exynos4: Add pinctrl devices and pin maps
2012-03-11 12:46 ` [PATCH 3/5] ARM: Exynos4: Add pinctrl devices and pin maps Thomas Abraham
@ 2012-03-11 21:17 ` Kukjin Kim
2012-03-12 4:22 ` Thomas Abraham
0 siblings, 1 reply; 19+ messages in thread
From: Kukjin Kim @ 2012-03-11 21:17 UTC (permalink / raw)
To: linux-arm-kernel
Thomas Abraham wrote:
> Add the three pinctrl platform devices and the pin maps for Exynos4.
>
> Signed-off-by: Thomas Abraham<thomas.abraham@linaro.org>
> ---
> arch/arm/mach-exynos/Kconfig | 1 +
> arch/arm/mach-exynos/Makefile | 1 +
> arch/arm/mach-exynos/common.h | 6 ++
> arch/arm/mach-exynos/dev-pinctrl.c | 115 +++++++++++++++++++++++++++++
> arch/arm/plat-samsung/include/plat/devs.h | 3 +
> 5 files changed, 126 insertions(+), 0 deletions(-)
> create mode 100644 arch/arm/mach-exynos/dev-pinctrl.c
[...]
> +#include<linux/kernel.h>
> +#include<linux/dma-mapping.h>
> +#include<linux/platform_device.h>
> +#include<linux/interrupt.h>
> +#include<linux/pinctrl/machine.h>
#include <linux/ioport.h> for DEFINE_RES_xxx at below.
> +
> +#include<plat/devs.h>
> +#include<plat/pinctrl.h>
> +
> +#include<mach/map.h>
> +
> +static struct resource exynos4_pinctrl_resource0[] = {
> + [0] = {
> + .start = EXYNOS4_PA_GPIO1,
> + .end = EXYNOS4_PA_GPIO1 + SZ_4K - 1,
> + .flags = IORESOURCE_MEM,
> + },
[0] = DEFINE_RES_MEM(EXYNOS4_PA_GPIO1, SZ_4K),
> + [1] = {
> + .start = IRQ_GPIO_XA,
> + .end = IRQ_GPIO_XA,
> + .flags = IORESOURCE_IRQ,
> + },
[1] = DEFINE_RES_IRQ(IRQ_GPIO_XA),
But I'm thinking, we need to move to use EXYNOS4_IRQ_GPIO_XA here for
both EXYNOS4 and EXYNOS5 and as a note, I'm working on updating IRQ
naming you can see it in this week :)
> +};
> +
> +struct platform_device exynos4_pinctrl0 = {
> + .name = "exynos4-pinctrl",
> + .id = 0,
> + .resource = exynos4_pinctrl_resource0,
> + .num_resources = ARRAY_SIZE(exynos4_pinctrl_resource0),
> +};
> +
> +static struct resource exynos4_pinctrl_resource1[] = {
> + [0] = {
> + .start = EXYNOS4_PA_GPIO2,
> + .end = EXYNOS4_PA_GPIO2 + SZ_4K - 1,
> + .flags = IORESOURCE_MEM,
> + },
same as above.
> + [1] = {
> + .start = IRQ_GPIO_XB,
> + .end = IRQ_GPIO_XB,
> + .flags = IORESOURCE_IRQ,
> + },
same.
> +};
> +
> +struct platform_device exynos4_pinctrl1 = {
> + .name = "exynos4-pinctrl",
> + .id = 1,
> + .resource = exynos4_pinctrl_resource1,
> + .num_resources = ARRAY_SIZE(exynos4_pinctrl_resource1),
> +};
> +
> +static struct resource exynos4_pinctrl_resource2[] = {
> + [0] = {
> + .start = EXYNOS4_PA_GPIO3,
> + .end = EXYNOS4_PA_GPIO3 + SZ_4K - 1,
> + .flags = IORESOURCE_MEM,
> + },
same.
> +};
> +
> +struct platform_device exynos4_pinctrl2 = {
> + .name = "exynos4-pinctrl",
> + .id = 2,
> + .resource = exynos4_pinctrl_resource2,
> + .num_resources = ARRAY_SIZE(exynos4_pinctrl_resource2),
> +};
> +
Thanks.
Best regards,
Kgene.
--
Kukjin Kim <kgene.kim@samsung.com>, Senior Engineer,
SW Solution Development Team, Samsung Electronics Co., Ltd.
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 5/5] mmc: sdhci-s3c: setup pins using pinctrl interface
2012-03-11 12:46 ` [PATCH 5/5] mmc: sdhci-s3c: setup pins using pinctrl interface Thomas Abraham
@ 2012-03-11 21:25 ` Kukjin Kim
2012-03-12 4:28 ` Thomas Abraham
2012-03-12 2:38 ` Kyungmin Park
` (2 subsequent siblings)
3 siblings, 1 reply; 19+ messages in thread
From: Kukjin Kim @ 2012-03-11 21:25 UTC (permalink / raw)
To: linux-arm-kernel
Thomas Abraham wrote:
> The platform specific callback to setup the sdhci pin mux and pin config
> is removed and the pinctrl subsystem interface is used to setup the
> mux and config.
>
> Signed-off-by: Thomas Abraham<thomas.abraham@linaro.org>
> ---
> drivers/mmc/host/sdhci-s3c.c | 15 +++++++++++++--
> 1 files changed, 13 insertions(+), 2 deletions(-)
>
[...]
>
> +#include<plat/map-s5p.h>
> +#include<plat/map-base.h>
You can add <mach/map.h> instead of above.
> +
> static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
> {
> struct s3c_sdhci_platdata *pdata;
> @@ -538,6 +543,7 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
> struct sdhci_s3c *sc;
> struct resource *res;
> int ret, irq, ptr, clks;
> + char *pstate;
>
> if (!pdev->dev.platform_data&& !pdev->dev.of_node) {
> dev_err(dev, "no device data specified\n");
> @@ -643,8 +649,13 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
> }
>
> /* Ensure we have minimal gpio selected CMD/CLK/Detect */
> - if (pdata->cfg_gpio)
> - pdata->cfg_gpio(pdev, pdata->max_width);
I'm not sure we can remove above now for all of Samsung stuff?
> + pstate = pdata->max_width ? "sdhci-pcfg8" : "sdhci-pcfg4";
Is this right? Current max_width can be 4 or 8 in each board file now.
> + sc->pinctrl = pinctrl_get_select(&pdev->dev, pstate);
> + if (IS_ERR(sc->pinctrl)) {
> + dev_err(dev, "failed to setup pin configuration\n");
> + ret = -ENXIO;
> + goto err_req_regs;
> + }
>
> host->hw_name = "samsung-hsmmc";
> host->ops =&sdhci_s3c_ops;
Thanks.
Best regards,
Kgene.
--
Kukjin Kim <kgene.kim@samsung.com>, Senior Engineer,
SW Solution Development Team, Samsung Electronics Co., Ltd.
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 5/5] mmc: sdhci-s3c: setup pins using pinctrl interface
2012-03-11 12:46 ` [PATCH 5/5] mmc: sdhci-s3c: setup pins using pinctrl interface Thomas Abraham
2012-03-11 21:25 ` Kukjin Kim
@ 2012-03-12 2:38 ` Kyungmin Park
2012-03-12 4:37 ` Thomas Abraham
2012-03-12 14:21 ` Mark Brown
2012-03-19 21:55 ` Stephen Warren
3 siblings, 1 reply; 19+ messages in thread
From: Kyungmin Park @ 2012-03-12 2:38 UTC (permalink / raw)
To: linux-arm-kernel
On 3/11/12, Thomas Abraham <thomas.abraham@linaro.org> wrote:
> The platform specific callback to setup the sdhci pin mux and pin config
> is removed and the pinctrl subsystem interface is used to setup the
> mux and config.
>
> Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
> ---
> drivers/mmc/host/sdhci-s3c.c | 15 +++++++++++++--
> 1 files changed, 13 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c
> index ea0767e..76c1c36 100644
> --- a/drivers/mmc/host/sdhci-s3c.c
> +++ b/drivers/mmc/host/sdhci-s3c.c
> @@ -22,6 +22,7 @@
> #include <linux/module.h>
> #include <linux/of.h>
> #include <linux/of_gpio.h>
> +#include <linux/pinctrl/consumer.h>
>
> #include <linux/mmc/host.h>
>
> @@ -50,6 +51,7 @@ struct sdhci_s3c {
> struct platform_device *pdev;
> struct resource *ioarea;
> struct s3c_sdhci_platdata *pdata;
> + struct pinctrl *pinctrl;
> unsigned int cur_clk;
> int ext_cd_irq;
> int ext_cd_gpio;
> @@ -529,6 +531,9 @@ static inline struct sdhci_s3c_drv_data
> *sdhci_s3c_get_driver_data(
> platform_get_device_id(pdev)->driver_data;
> }
>
> +#include <plat/map-s5p.h>
> +#include <plat/map-base.h>
Why this header files are required?
> +
> static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
> {
> struct s3c_sdhci_platdata *pdata;
> @@ -538,6 +543,7 @@ static int __devinit sdhci_s3c_probe(struct
> platform_device *pdev)
> struct sdhci_s3c *sc;
> struct resource *res;
> int ret, irq, ptr, clks;
> + char *pstate;
>
> if (!pdev->dev.platform_data && !pdev->dev.of_node) {
> dev_err(dev, "no device data specified\n");
> @@ -643,8 +649,13 @@ static int __devinit sdhci_s3c_probe(struct
> platform_device *pdev)
> }
>
> /* Ensure we have minimal gpio selected CMD/CLK/Detect */
> - if (pdata->cfg_gpio)
> - pdata->cfg_gpio(pdev, pdata->max_width);
> + pstate = pdata->max_width ? "sdhci-pcfg8" : "sdhci-pcfg4";
You should check pdata->max_width == 8 instead of max_width itself.
BTW if platform set the amx_width as 1. How do you handle this?
Thank you,
Kyungmin Park
> + sc->pinctrl = pinctrl_get_select(&pdev->dev, pstate);
> + if (IS_ERR(sc->pinctrl)) {
> + dev_err(dev, "failed to setup pin configuration\n");
> + ret = -ENXIO;
> + goto err_req_regs;
> + }
>
> host->hw_name = "samsung-hsmmc";
> host->ops = &sdhci_s3c_ops;
> --
> 1.6.6.rc2
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc"
> in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 3/5] ARM: Exynos4: Add pinctrl devices and pin maps
2012-03-11 21:17 ` Kukjin Kim
@ 2012-03-12 4:22 ` Thomas Abraham
0 siblings, 0 replies; 19+ messages in thread
From: Thomas Abraham @ 2012-03-12 4:22 UTC (permalink / raw)
To: linux-arm-kernel
2012/3/12 Kukjin Kim <kgene.kim@samsung.com>:
> Thomas Abraham wrote:
>> Add the three pinctrl platform devices and the pin maps for Exynos4.
>>
>> Signed-off-by: Thomas Abraham<thomas.abraham@linaro.org>
>> ---
>> ? arch/arm/mach-exynos/Kconfig ? ? ? ? ? ? ?| ? ?1 +
>> ? arch/arm/mach-exynos/Makefile ? ? ? ? ? ? | ? ?1 +
>> ? arch/arm/mach-exynos/common.h ? ? ? ? ? ? | ? ?6 ++
>> ? arch/arm/mach-exynos/dev-pinctrl.c ? ? ? ?| ?115 +++++++++++++++++++++++++++++
>> ? arch/arm/plat-samsung/include/plat/devs.h | ? ?3 +
>> ? 5 files changed, 126 insertions(+), 0 deletions(-)
>> ? create mode 100644 arch/arm/mach-exynos/dev-pinctrl.c
>
> [...]
>
>> +#include<linux/kernel.h>
>> +#include<linux/dma-mapping.h>
>> +#include<linux/platform_device.h>
>> +#include<linux/interrupt.h>
>> +#include<linux/pinctrl/machine.h>
>
> #include <linux/ioport.h> for DEFINE_RES_xxx at below.
>
>> +
>> +#include<plat/devs.h>
>> +#include<plat/pinctrl.h>
>> +
>> +#include<mach/map.h>
>> +
>> +static struct resource exynos4_pinctrl_resource0[] = {
>> + ? ? [0] = {
>> + ? ? ? ? ? ? .start ?= EXYNOS4_PA_GPIO1,
>> + ? ? ? ? ? ? .end ? ?= EXYNOS4_PA_GPIO1 + SZ_4K - 1,
>> + ? ? ? ? ? ? .flags ?= IORESOURCE_MEM,
>> + ? ? },
>
> [0] = DEFINE_RES_MEM(EXYNOS4_PA_GPIO1, SZ_4K),
>
>> + ? ? [1] = {
>> + ? ? ? ? ? ? .start ?= IRQ_GPIO_XA,
>> + ? ? ? ? ? ? .end ? ?= IRQ_GPIO_XA,
>> + ? ? ? ? ? ? .flags ?= IORESOURCE_IRQ,
>> + ? ? },
>
> [1] = DEFINE_RES_IRQ(IRQ_GPIO_XA),
>
> But I'm thinking, we need to move to use EXYNOS4_IRQ_GPIO_XA here for
> both EXYNOS4 and EXYNOS5 and as a note, I'm working on updating IRQ
> naming you can see it in this week :)
Thanks for reviewing this patch series. I will use DEFINE_RES_xxx for
resource instantiation.
Regards,
Thomas.
[...]
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 5/5] mmc: sdhci-s3c: setup pins using pinctrl interface
2012-03-11 21:25 ` Kukjin Kim
@ 2012-03-12 4:28 ` Thomas Abraham
0 siblings, 0 replies; 19+ messages in thread
From: Thomas Abraham @ 2012-03-12 4:28 UTC (permalink / raw)
To: linux-arm-kernel
2012/3/12 Kukjin Kim <kgene.kim@samsung.com>:
> Thomas Abraham wrote:
>> The platform specific callback to setup the sdhci pin mux and pin config
>> is removed and the pinctrl subsystem interface is used to setup the
>> mux and config.
>>
>> Signed-off-by: Thomas Abraham<thomas.abraham@linaro.org>
>> ---
>> ? drivers/mmc/host/sdhci-s3c.c | ? 15 +++++++++++++--
>> ? 1 files changed, 13 insertions(+), 2 deletions(-)
>>
> [...]
>
>>
>> +#include<plat/map-s5p.h>
>> +#include<plat/map-base.h>
>
> You can add <mach/map.h> instead of above.
>
>> +
>> ? static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
>> ? {
>> ? ? ? struct s3c_sdhci_platdata *pdata;
>> @@ -538,6 +543,7 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
>> ? ? ? struct sdhci_s3c *sc;
>> ? ? ? struct resource *res;
>> ? ? ? int ret, irq, ptr, clks;
>> + ? ? char *pstate;
>>
>> ? ? ? if (!pdev->dev.platform_data&& ?!pdev->dev.of_node) {
>> ? ? ? ? ? ? ? dev_err(dev, "no device data specified\n");
>> @@ -643,8 +649,13 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
>> ? ? ? }
>>
>> ? ? ? /* Ensure we have minimal gpio selected CMD/CLK/Detect */
>> - ? ? if (pdata->cfg_gpio)
>> - ? ? ? ? ? ? pdata->cfg_gpio(pdev, pdata->max_width);
>
> I'm not sure we can remove above now for all of Samsung stuff?
We the pin map table is fully populated for each SoC (and board as
necessary), then the platform callback functions to setup the pinmux
and pinconfig can be removed for the drivers. But before doing that,
the next step would be to add gpio interrupts and wakeup interrupts
support into the samsung pinctrl driver. When we have a fully
functional pinctrl driver, we could add the required bits in SoC and
board files and switch over to the pinctrl driver.
>
>> + ? ? pstate = pdata->max_width ? "sdhci-pcfg8" : "sdhci-pcfg4";
>
> Is this right? Current max_width can be 4 or 8 in each board file now.
Sorry, that is not correct. I will fix it. Thanks.
Regards,
Thomas.
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 5/5] mmc: sdhci-s3c: setup pins using pinctrl interface
2012-03-12 2:38 ` Kyungmin Park
@ 2012-03-12 4:37 ` Thomas Abraham
0 siblings, 0 replies; 19+ messages in thread
From: Thomas Abraham @ 2012-03-12 4:37 UTC (permalink / raw)
To: linux-arm-kernel
On 12 March 2012 08:08, Kyungmin Park <kmpark@infradead.org> wrote:
> On 3/11/12, Thomas Abraham <thomas.abraham@linaro.org> wrote:
>> The platform specific callback to setup the sdhci pin mux and pin config
>> is removed and the pinctrl subsystem interface is used to setup the
>> mux and config.
>>
>> Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
>> ---
>> ?drivers/mmc/host/sdhci-s3c.c | ? 15 +++++++++++++--
>> ?1 files changed, 13 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c
>> index ea0767e..76c1c36 100644
>> --- a/drivers/mmc/host/sdhci-s3c.c
>> +++ b/drivers/mmc/host/sdhci-s3c.c
>> @@ -22,6 +22,7 @@
>> ?#include <linux/module.h>
>> ?#include <linux/of.h>
>> ?#include <linux/of_gpio.h>
>> +#include <linux/pinctrl/consumer.h>
>>
>> ?#include <linux/mmc/host.h>
>>
>> @@ -50,6 +51,7 @@ struct sdhci_s3c {
>> ? ? ? struct platform_device ?*pdev;
>> ? ? ? struct resource ? ? ? ? *ioarea;
>> ? ? ? struct s3c_sdhci_platdata *pdata;
>> + ? ? struct pinctrl ? ? ? ? ?*pinctrl;
>> ? ? ? unsigned int ? ? ? ? ? ?cur_clk;
>> ? ? ? int ? ? ? ? ? ? ? ? ? ? ext_cd_irq;
>> ? ? ? int ? ? ? ? ? ? ? ? ? ? ext_cd_gpio;
>> @@ -529,6 +531,9 @@ static inline struct sdhci_s3c_drv_data
>> *sdhci_s3c_get_driver_data(
>> ? ? ? ? ? ? ? ? ? ? ? platform_get_device_id(pdev)->driver_data;
>> ?}
>>
>> +#include <plat/map-s5p.h>
>> +#include <plat/map-base.h>
>
> Why this header files are required?
Sorry, that was a mistake. This was left over here after adding it
here for some debugging. I will take care next time.
>> +
>> ?static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
>> ?{
>> ? ? ? struct s3c_sdhci_platdata *pdata;
>> @@ -538,6 +543,7 @@ static int __devinit sdhci_s3c_probe(struct
>> platform_device *pdev)
>> ? ? ? struct sdhci_s3c *sc;
>> ? ? ? struct resource *res;
>> ? ? ? int ret, irq, ptr, clks;
>> + ? ? char *pstate;
>>
>> ? ? ? if (!pdev->dev.platform_data && !pdev->dev.of_node) {
>> ? ? ? ? ? ? ? dev_err(dev, "no device data specified\n");
>> @@ -643,8 +649,13 @@ static int __devinit sdhci_s3c_probe(struct
>> platform_device *pdev)
>> ? ? ? }
>>
>> ? ? ? /* Ensure we have minimal gpio selected CMD/CLK/Detect */
>> - ? ? if (pdata->cfg_gpio)
>> - ? ? ? ? ? ? pdata->cfg_gpio(pdev, pdata->max_width);
>> + ? ? pstate = pdata->max_width ? "sdhci-pcfg8" : "sdhci-pcfg4";
> You should check pdata->max_width == 8 instead of max_width itself.
Thanks. I will fix that.
> BTW if platform set the amx_width as 1. How do you handle this?
If the bus width is 1, we need to add pin map entry for 1 bit bus
width and correspondingly change the code here. I used the sdhci-s3c
driver for testing the samsung pinctrl driver and only tested with
4-bit and 8-bit bus width. The changes in this patch are not final yet
and was mainly included in this series to show how platform callbacks
can be removed.
Thanks,
Thomas.
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 5/5] mmc: sdhci-s3c: setup pins using pinctrl interface
2012-03-11 12:46 ` [PATCH 5/5] mmc: sdhci-s3c: setup pins using pinctrl interface Thomas Abraham
2012-03-11 21:25 ` Kukjin Kim
2012-03-12 2:38 ` Kyungmin Park
@ 2012-03-12 14:21 ` Mark Brown
2012-03-12 14:31 ` Thomas Abraham
2012-03-19 21:55 ` Stephen Warren
3 siblings, 1 reply; 19+ messages in thread
From: Mark Brown @ 2012-03-12 14:21 UTC (permalink / raw)
To: linux-arm-kernel
On Sun, Mar 11, 2012 at 06:16:05PM +0530, Thomas Abraham wrote:
> The platform specific callback to setup the sdhci pin mux and pin config
> is removed and the pinctrl subsystem interface is used to setup the
> mux and config.
You've only added pinctrl support for Exynos but this driver is also
used by SoCs going back to s3c24xx era. Either all those SoCs need to
be converted to use pinctrl or the driver needs to understand both
methods (eg, using pinctrl if no callback is supplied).
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 5/5] mmc: sdhci-s3c: setup pins using pinctrl interface
2012-03-12 14:21 ` Mark Brown
@ 2012-03-12 14:31 ` Thomas Abraham
2012-03-12 16:12 ` Mark Brown
0 siblings, 1 reply; 19+ messages in thread
From: Thomas Abraham @ 2012-03-12 14:31 UTC (permalink / raw)
To: linux-arm-kernel
On 12 March 2012 19:51, Mark Brown <broonie@opensource.wolfsonmicro.com> wrote:
> On Sun, Mar 11, 2012 at 06:16:05PM +0530, Thomas Abraham wrote:
>> The platform specific callback to setup the sdhci pin mux and pin config
>> is removed and the pinctrl subsystem interface is used to setup the
>> mux and config.
>
> You've only added pinctrl support for Exynos but this driver is also
> used by SoCs going back to s3c24xx era. ?Either all those SoCs need to
> be converted to use pinctrl or the driver needs to understand both
> methods (eg, using pinctrl if no callback is supplied).
Yes, I agree with your comment. I did refer to manuals of s3c24xx to
Exynos to ensure that the samsung pinctrl driver is generic and
reusable on all samsung soc's. I hope I have not missed out something
important that would require additional tweaks in the samsung pinctrl
driver. The missing bits now are gpio interrupt and wakeup interrupt
support in the samsung pinctrl driver. Once that is complete, I
believe it should be easy to add support for other SoC and convert the
drivers to use pinctrl (other option being to let pinctrl driver hog
all the mappings at boot and remove the cfg_gpio platform callbacks
from the driver).
Thank you Mark for your comments.
Regards,
Thomas.
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 5/5] mmc: sdhci-s3c: setup pins using pinctrl interface
2012-03-12 14:31 ` Thomas Abraham
@ 2012-03-12 16:12 ` Mark Brown
0 siblings, 0 replies; 19+ messages in thread
From: Mark Brown @ 2012-03-12 16:12 UTC (permalink / raw)
To: linux-arm-kernel
On Mon, Mar 12, 2012 at 08:01:34PM +0530, Thomas Abraham wrote:
> Yes, I agree with your comment. I did refer to manuals of s3c24xx to
> Exynos to ensure that the samsung pinctrl driver is generic and
> reusable on all samsung soc's. I hope I have not missed out something
> important that would require additional tweaks in the samsung pinctrl
> driver. The missing bits now are gpio interrupt and wakeup interrupt
> support in the samsung pinctrl driver. Once that is complete, I
> believe it should be easy to add support for other SoC and convert the
> drivers to use pinctrl (other option being to let pinctrl driver hog
> all the mappings at boot and remove the cfg_gpio platform callbacks
> from the driver).
Yes, I don't see any fundamental problems here - it's more that either
we'll need to get all the SoCs converted over (which is a lot of work)
or we'll need to have drivers be able to cope with running either way.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120312/57245f07/attachment.sig>
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 0/5] pinctrl: add new Samsung pinctrl driver and add Exynos4 support
2012-03-11 12:46 [PATCH 0/5] pinctrl: add new Samsung pinctrl driver and add Exynos4 support Thomas Abraham
` (4 preceding siblings ...)
2012-03-11 12:46 ` [PATCH 5/5] mmc: sdhci-s3c: setup pins using pinctrl interface Thomas Abraham
@ 2012-03-13 10:13 ` Linus Walleij
2012-03-13 10:18 ` Thomas Abraham
5 siblings, 1 reply; 19+ messages in thread
From: Linus Walleij @ 2012-03-13 10:13 UTC (permalink / raw)
To: linux-arm-kernel
On Sun, Mar 11, 2012 at 1:46 PM, Thomas Abraham
<thomas.abraham@linaro.org> wrote:
> This patch series adds new pinctrl driver for Samsung SoC's. The driver supports
> a gpiolib interface as well since Samsung SoC's have a combined pinmux/pinctrl
> and gpio controller.
Overall this all looks good to me Thomas!
I will provide detailed review if/when it is more ripe for merge.
Yours,
Linus Walleij
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 0/5] pinctrl: add new Samsung pinctrl driver and add Exynos4 support
2012-03-13 10:13 ` [PATCH 0/5] pinctrl: add new Samsung pinctrl driver and add Exynos4 support Linus Walleij
@ 2012-03-13 10:18 ` Thomas Abraham
0 siblings, 0 replies; 19+ messages in thread
From: Thomas Abraham @ 2012-03-13 10:18 UTC (permalink / raw)
To: linux-arm-kernel
On 13 March 2012 15:43, Linus Walleij <linus.walleij@linaro.org> wrote:
> On Sun, Mar 11, 2012 at 1:46 PM, Thomas Abraham
> <thomas.abraham@linaro.org> wrote:
>
>> This patch series adds new pinctrl driver for Samsung SoC's. The driver supports
>> a gpiolib interface as well since Samsung SoC's have a combined pinmux/pinctrl
>> and gpio controller.
>
> Overall this all looks good to me Thomas!
> I will provide detailed review if/when it is more ripe for merge.
Thanks linus for having a look. The missing bits in the driver are
wakeup interrupt and gpio interrupt support. Without these, it would
not be possible to meaningfully demonstrate a fully functional system
using the pinctrl and gpiolib driver for Exynos4.
Regards,
Thomas.
>
> Yours,
> Linus Walleij
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 1/5] pinctrl: add samsung pinctrl and gpiolib driver
2012-03-11 12:46 ` [PATCH 1/5] pinctrl: add samsung pinctrl and gpiolib driver Thomas Abraham
@ 2012-03-19 21:45 ` Stephen Warren
0 siblings, 0 replies; 19+ messages in thread
From: Stephen Warren @ 2012-03-19 21:45 UTC (permalink / raw)
To: linux-arm-kernel
On 03/11/2012 06:46 AM, Thomas Abraham wrote:
> Add a new pinctrl and gpiolib driver for Samsung SoC's. This driver provides a
> common framework for all Samsung SoC's to interface with the pinctrl and
> gpiolib subsystems.
>
> This driver is split into two parts: the pinctrl interface and the gpiolib
> interface. The pinctrl interface registers pinctrl devices with the pinctrl
> subsystem and gpiolib interface registers gpio chips with the gpiolib
> subsystem. The information about the pins, pin groups, pin functions and
> gpio chips, which are SoC specific, are all provided to the driver using
> driver data. The driver registers all the pinctrl devices and gpio chips
> which are found in the driver data.
> diff --git a/arch/arm/plat-samsung/include/plat/pinctrl.h b/arch/arm/plat-samsung/include/plat/pinctrl.h
It'd be nice to name this samsung-pinctrl.h, or something other than
just "pinctrl.h". That way, this new header won't cause problems for a
multi-SoC kernel in the future where multiple plat-*/include/plat or
mach-*/include/mach directories are in the include path.
> diff --git a/drivers/pinctrl/pinctrl-samsung.c b/drivers/pinctrl/pinctrl-samsung.c
> +/* check if the selector is a valid pin function selector */
> +static int samsung_pinmux_list_funcs(struct pinctrl_dev *pctldev,
> + unsigned selector)
> +{
> + struct samsung_pinctrl_drv_data *drvdata;
> +
> + drvdata = pinctrl_dev_get_drvdata(pctldev);
> + if (selector >= drvdata->nr_groups)
> + return -EINVAL;
That test should be against something other than nr_groups; nr_functions
or similar, right?
> +static void samsung_pimux_setup(struct pinctrl_dev *pctldev, unsigned selector,
s/pimux/pinmux/
...
> + const unsigned int *pin;
...
> + pin = drvdata->pin_groups[group].pins;
It might be a little clearer to rename "pin" to "pins", since it's an
array...
> +
> + /*
> + * for each pin in the pin group selected, program the correspoding pin
> + * pin function number in the config register.
> + */
> + for (cnt = 0; cnt < drvdata->pin_groups[group].num_pins; cnt++, pin++) {
> + pin_to_reg_bank(drvdata->gc, *pin - drvdata->ctrl->base,
> + ®, &pin_offset, &bank);
... and say pins[cnt] instead of *pin here (and remove pin++ from the
for loop statement)
But it's just a slight suggestion; your call.
> +static int samsung_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev,
> + struct pinctrl_gpio_range *range, unsigned offset, bool input)
...
> + pin_to_reg_bank(range->gc, offset, ®, &pin_offset, &bank);
> + mask = (1 << bank->func_width) - 1;
> + shift = pin_offset * bank->func_width;
It might be useful to put those 3 lines into a helper function since
they're duplicating with samsung_pimux_setup() and similar code is in
samsung_pinconf_set() too.
> +static int samsung_pinconf_group_set(struct pinctrl_dev *pctldev,
> + unsigned group, unsigned long config)
I think you can leave out group_set(), and the pinctrl core will loop
over all pins in the group for you.
> +static void samsung_gpio_set(struct gpio_chip *gc, unsigned offset, int value)
...
> + data = readl(reg + DAT_REG);
...
> + __raw_writel(data, reg + DAT_REG);
Why sometimes use the __raw variants and sometimes not?
> +static int samsung_gpio_direction_output(struct gpio_chip *gc, unsigned offset,
> + int value)
...
> + ret = pinctrl_gpio_direction_output(gc->base + offset);
> + if (!ret)
> + samsung_gpio_set(gc, offset, value);
This will set the GPIO to output direction before programming the output
value, which might cause a glitch. You may want to try and swap those
two function calls.
> +static int __devinit samsung_pinctrl_probe(struct platform_device *pdev)
...
> + res = request_mem_region(res->start, resource_size(res),
> + pdev->name);
> + if (!res) {
> + dev_err(&pdev->dev, "request for mem region failed\n");
> + return -EBUSY;
> + }
> +
> + drvdata->virt_base = ioremap(res->start, resource_size(res));
Perhaps replace those two function calls with
devm_request_and_ioremap(), and as a bonus you won't have to unmap or
release the region either.
> + if (!drvdata->virt_base) {
> + dev_err(&pdev->dev, "ioremap failed\n");
i.e. you wouldn't have to add the missing error-handling here, and below.
> + return -EINVAL;
> + }
> +/* driver data for various samsung soc's */
> +#ifdef CONFIG_CPU_EXYNOS4210
> +
> +#define EXYNOS4210_PCTRL_DRVDATA ((kernel_ulong_t)&exynos4210_pinctrl_drv_data)
> +#else
> +#define EXYNOS4210_PCTRL_DRVDATA ((kernel_ulong_t)NULL)
> +#endif /* CONFIG_CPU_EXYNOS4210 */
Doesn't that interact badly with samsung_pinctrl_get_driver_data()
above, which just blindly adds to the .driver_data field when an entry
is found in samsung_pinctrl_driver_ids[]?
> +static struct platform_device_id samsung_pinctrl_driver_ids[] = {
> + {
> + .name = "exynos4-pinctrl",
> + .driver_data = EXYNOS4210_PCTRL_DRVDATA,
> + },
> + { },
> +};
> +MODULE_DEVICE_TABLE(platform, samsung_pinctrl_driver_ids);
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 5/5] mmc: sdhci-s3c: setup pins using pinctrl interface
2012-03-11 12:46 ` [PATCH 5/5] mmc: sdhci-s3c: setup pins using pinctrl interface Thomas Abraham
` (2 preceding siblings ...)
2012-03-12 14:21 ` Mark Brown
@ 2012-03-19 21:55 ` Stephen Warren
3 siblings, 0 replies; 19+ messages in thread
From: Stephen Warren @ 2012-03-19 21:55 UTC (permalink / raw)
To: linux-arm-kernel
On 03/11/2012 06:46 AM, Thomas Abraham wrote:
> The platform specific callback to setup the sdhci pin mux and pin config
> is removed and the pinctrl subsystem interface is used to setup the
> mux and config.
> @@ -643,8 +649,13 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
> }
>
> /* Ensure we have minimal gpio selected CMD/CLK/Detect */
> - if (pdata->cfg_gpio)
> - pdata->cfg_gpio(pdev, pdata->max_width);
> + pstate = pdata->max_width ? "sdhci-pcfg8" : "sdhci-pcfg4";
If the driver is going to select a single state ("sdhci-pcfg8" or
"sdhci-pcfg4" above) at probe() time and never change it (which seems
quite reasonable for an SDHCI controller), then the driver should always
use state PINCTRL_STATE_DEFAULT, and it should be up to the board to set
up the mapping table such that PINCTRL_STATE_DEFAULT sets up the pins
for either 4-bit or 8-bit as appropriate for the board.
^ permalink raw reply [flat|nested] 19+ messages in thread
end of thread, other threads:[~2012-03-19 21:55 UTC | newest]
Thread overview: 19+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-03-11 12:46 [PATCH 0/5] pinctrl: add new Samsung pinctrl driver and add Exynos4 support Thomas Abraham
2012-03-11 12:46 ` [PATCH 1/5] pinctrl: add samsung pinctrl and gpiolib driver Thomas Abraham
2012-03-19 21:45 ` Stephen Warren
2012-03-11 12:46 ` [PATCH 2/5] pinctrl: add exynos4 specific pins, groups, functions and gpio chip data Thomas Abraham
2012-03-11 12:46 ` [PATCH 3/5] ARM: Exynos4: Add pinctrl devices and pin maps Thomas Abraham
2012-03-11 21:17 ` Kukjin Kim
2012-03-12 4:22 ` Thomas Abraham
2012-03-11 12:46 ` [PATCH 4/5] ARM: Exynos: Enable pinctrl driver support for Origen board Thomas Abraham
2012-03-11 12:46 ` [PATCH 5/5] mmc: sdhci-s3c: setup pins using pinctrl interface Thomas Abraham
2012-03-11 21:25 ` Kukjin Kim
2012-03-12 4:28 ` Thomas Abraham
2012-03-12 2:38 ` Kyungmin Park
2012-03-12 4:37 ` Thomas Abraham
2012-03-12 14:21 ` Mark Brown
2012-03-12 14:31 ` Thomas Abraham
2012-03-12 16:12 ` Mark Brown
2012-03-19 21:55 ` Stephen Warren
2012-03-13 10:13 ` [PATCH 0/5] pinctrl: add new Samsung pinctrl driver and add Exynos4 support Linus Walleij
2012-03-13 10:18 ` Thomas Abraham
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).