]> Pileus Git - ~andy/linux/blobdiff - drivers/pinctrl/pinctrl-u300.c
Merge branch 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[~andy/linux] / drivers / pinctrl / pinctrl-u300.c
index c8d02f1c2b5e82e7efc6af5dbd01517c49d0510a..26eb8ccd72d5e350f0ca28c369191ad9194b3301 100644 (file)
@@ -19,6 +19,9 @@
 #include <linux/err.h>
 #include <linux/pinctrl/pinctrl.h>
 #include <linux/pinctrl/pinmux.h>
+#include <linux/pinctrl/pinconf.h>
+#include <linux/pinctrl/pinconf-generic.h>
+#include "pinctrl-coh901.h"
 
 /*
  * Register definitions for the U300 Padmux control registers in the
 #define U300_SYSCON_PMC4R_APP_MISC_16_APP_UART1_CTS            0x0100
 #define U300_SYSCON_PMC4R_APP_MISC_16_EMIF_1_STATIC_CS5_N      0x0200
 
-#define DRIVER_NAME "pinmux-u300"
+#define DRIVER_NAME "pinctrl-u300"
 
 /*
  * The DB3350 has 467 pads, I have enumerated the pads clockwise around the
@@ -1044,22 +1047,82 @@ static struct pinctrl_gpio_range u300_gpio_ranges[] = {
        U300_GPIO_RANGE(25, 181, 1),
 };
 
+static struct pinctrl_gpio_range *u300_match_gpio_range(unsigned pin)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(u300_gpio_ranges); i++) {
+               struct pinctrl_gpio_range *range;
+
+               range = &u300_gpio_ranges[i];
+               if (pin >= range->pin_base &&
+                   pin <= (range->pin_base + range->npins - 1))
+                       return range;
+       }
+       return NULL;
+}
+
+int u300_pin_config_get(struct pinctrl_dev *pctldev,
+                       unsigned pin,
+                       unsigned long *config)
+{
+       struct pinctrl_gpio_range *range = u300_match_gpio_range(pin);
+
+       /* We get config for those pins we CAN get it for and that's it */
+       if (!range)
+               return -ENOTSUPP;
+
+       return u300_gpio_config_get(range->gc,
+                                   (pin - range->pin_base + range->base),
+                                   config);
+}
+
+int u300_pin_config_set(struct pinctrl_dev *pctldev,
+                       unsigned pin,
+                       unsigned long config)
+{
+       struct pinctrl_gpio_range *range = u300_match_gpio_range(pin);
+       int ret;
+
+       if (!range)
+               return -EINVAL;
+
+       /* Note: none of these configurations take any argument */
+       ret = u300_gpio_config_set(range->gc,
+                                  (pin - range->pin_base + range->base),
+                                  pinconf_to_config_param(config));
+       if (ret)
+               return ret;
+
+       return 0;
+}
+
+static struct pinconf_ops u300_pconf_ops = {
+       .is_generic = true,
+       .pin_config_get = u300_pin_config_get,
+       .pin_config_set = u300_pin_config_set,
+};
+
 static struct pinctrl_desc u300_pmx_desc = {
        .name = DRIVER_NAME,
        .pins = u300_pads,
        .npins = ARRAY_SIZE(u300_pads),
        .pctlops = &u300_pctrl_ops,
        .pmxops = &u300_pmx_ops,
+       .confops = &u300_pconf_ops,
        .owner = THIS_MODULE,
 };
 
-static int __init u300_pmx_probe(struct platform_device *pdev)
+static int __devinit u300_pmx_probe(struct platform_device *pdev)
 {
        struct u300_pmx *upmx;
        struct resource *res;
+       struct gpio_chip *gpio_chip = dev_get_platdata(&pdev->dev);
        int ret;
        int i;
 
+       pr_err("U300 PMX PROBE\n");
+
        /* Create state holders etc for this driver */
        upmx = devm_kzalloc(&pdev->dev, sizeof(*upmx), GFP_KERNEL);
        if (!upmx)
@@ -1095,12 +1158,14 @@ static int __init u300_pmx_probe(struct platform_device *pdev)
        }
 
        /* We will handle a range of GPIO pins */
-       for (i = 0; i < ARRAY_SIZE(u300_gpio_ranges); i++)
+       for (i = 0; i < ARRAY_SIZE(u300_gpio_ranges); i++) {
+               u300_gpio_ranges[i].gc = gpio_chip;
                pinctrl_add_gpio_range(upmx->pctl, &u300_gpio_ranges[i]);
+       }
 
        platform_set_drvdata(pdev, upmx);
 
-       dev_info(&pdev->dev, "initialized U300 pinmux driver\n");
+       dev_info(&pdev->dev, "initialized U300 pin control driver\n");
 
        return 0;
 
@@ -1115,7 +1180,7 @@ out_no_resource:
        return ret;
 }
 
-static int __exit u300_pmx_remove(struct platform_device *pdev)
+static int __devexit u300_pmx_remove(struct platform_device *pdev)
 {
        struct u300_pmx *upmx = platform_get_drvdata(pdev);
        int i;
@@ -1136,12 +1201,13 @@ static struct platform_driver u300_pmx_driver = {
                .name = DRIVER_NAME,
                .owner = THIS_MODULE,
        },
-       .remove = __exit_p(u300_pmx_remove),
+       .probe = u300_pmx_probe,
+       .remove = __devexit_p(u300_pmx_remove),
 };
 
 static int __init u300_pmx_init(void)
 {
-       return platform_driver_probe(&u300_pmx_driver, u300_pmx_probe);
+       return platform_driver_register(&u300_pmx_driver);
 }
 arch_initcall(u300_pmx_init);