Thread (17 messages) flat view 17 messages, 3 authors, 2012-08-28

[PATCH v2 1/4] pinctrl: add samsung pinctrl and gpiolib driver

From: Linus Walleij <hidden>
Date: 2012-08-27 23:23:02
Also in: linux-samsung-soc, lkml

On Tue, Aug 21, 2012 at 9:22 PM, Thomas Abraham
[off-list ref] wrote:
quoted
quoted
+  - samsung,pin-pud: Pull up/down configuration.
+  - samsung,pin-drv: Drive strength configuration.
+  - samsung,pin-pud-pdn: Pull up/down configuration in power down mode.
+  - samsung,pin-drv-pdn: Drive strength configuration in power down mode.
This looks a bit scary, as it seems to be orthogonal to the pin config
interface. I.e. this will be programmed "behind the back" of the
pin config system. However as long as the pin config implementation
reads back these things from the registers it will work, too.
These properties are converted to a PIN_MAP_TYPE_CONFIGS_GROUP map
type and stored in a instance of 'struct pinctrl_map'. These can be
read back from the registers and reverse-mapped as well.
OK
All the dt bindings defined and used in the Samsung pinctrl driver are
first translated into pinctrl subystem defined data structures and
then used. Hence, there are no register configurations done that skip
over the pinctrl subsystem (except for the gpio/wakeup interrupts).
OK fine.
quoted
In the U300 and Ux500 I explicitly use pin config hogs to set up
the pin configuration, and when we enter a state such as
"default" the mux setting and config settings are set from the
framework separately.

See for example:
arch/arm/mach-ux500/board-mop500-pins.c

This example is using platform data but it should be trivial to do with
device tree.

I think the Tegra also works this way. Can you elaborate on
why you need this static setup from the device tree instead
of using default states?
Sorry, I did not understand this question.
You answered above, no problem.
quoted
quoted
+       pinctrl_0: pinctrl at 11400000 {
+               compatible = "samsung,pinctrl-exynos4210";
+               reg = <0x11400000 0x1000>;
+               interrupts = <0 47 0>;
+
+               uart0_data: uart0-data {
+                       samsung,pins = "gpa0-0", "gpa0-1";
+                       samsung,pin-function = <2>;
+                       samsung,pin-pud = <0>;
+                       samsung,pin-drv = <0>;
+               };
This setup needs to be associated with a certain state, it's possible to
do in the code or directly in the device tree.

I.e. these settings for pin-pud and pin-drv needs to belong to a
certain pin config state, typically the state named "default"
Yes, I agree. So, for example, the uart device node would have

                    uart at 13800000 {
                               compatilble = " .... ";
                               <rest of the properties here>

                               pinctrl-names = "default";
                               pinctrl-0 - <&uart0_data>;
                    };

The uart driver during probe can then call

                   devm_pinctrl_get_select_default(&pdev->dev);

For the example above, this call will set the 'mux', 'pud' and 'drv'
values to gpa-0 and gpa-1 pins.
OK perfect, that's how it should work.
quoted
quoted
+/* list of all possible config options supported */
+struct pin_config {
+       char            *prop_cfg;
+       unsigned int    cfg_type;
+} pcfgs[] = {
+       { "samsung,pin-pud", PINCFG_TYPE_PUD },
+       { "samsung,pin-drv", PINCFG_TYPE_DRV },
+       { "samsung,pin-pud-pdn", PINCFG_TYPE_CON_PND },
+       { "samsung,pin-drv-pdn", PINCFG_TYPE_PUD_PND },
+};
Hmmmmm it looks very much like this controller could make use of
the generic pinconf library, but it's not mandatory so just a suggestion.
Ok. The last two entries in the above table are Samsung specific and
not covered by generic-pinconf. So, I am not sure if it can be added
to generic-pinconf.
What is so Samsung-specific about them?

If you tell us the electrical property of setting them we can figure out
if they should be generic or not...
For now, since you are not enforcing the use of
generic-pinconf, I will keep it the way it is now.
Sure that's OK.
quoted
quoted
+       /* Allocate memory for pin group name. The pin group name is derived
+        * from the node name from which these map entries are be created.
+        */
+       gname = kzalloc(strlen(np->name) + 4, GFP_KERNEL);
Why +4? I would have suspected +1 for the null terminator...
The name of the pin group is derived from the node name and hence
strlen(np->name). To this name, "-grp" is appended to imply that this
is a group. Hence +4 is used. I will replace +4 with probably
strlen(PINGRP_SUFFIX) where PINGRP_SUFFIX is defined as "-grp".
Aha OK I get it.
quoted
quoted
+/* reading pin pull up/down and driver strength settings not implemented */
OK why not? It seems very simple and straight-forward.
Just read the same registers and switch() then return...
Ok, I will do that. I did not see how those would be used and hence skipped it.
One good usecase is to look at the state of pins in debugfs.
quoted
quoted
+static int __devinit samsung_pinctrl_probe(struct platform_device *pdev)
(...)
quoted
+       if (ctrl->eint_gpio_init)
+               ctrl->eint_gpio_init(drvdata);
+       if (ctrl->eint_wkup_init)
+               ctrl->eint_wkup_init(drvdata);
So this stuff I'm doing in the default states instead.
These callbacks setup the irq domain and irq_chip for gpio and wakeup
interrupts. These are Samsung specific and are dealt with outside of
the pinctrl subsystem framework.
Aha I get it, OK.
quoted
quoted
+       unsigned int            eint_type;
Shouldn't this be some kund of enum if it denotes a type?
It was done to reduce adding new data types.
Oh I like new data types if they make the code easier to read
and reduce the risk for errors so just go ahead :-)
quoted
quoted
+/**
+ * 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.
+ * @nr_gint: number of external gpio interrupts supported.
+ * @nr_wint: number of external wakeup interrupts supported.
+ * @geint_con: offset of the ext-gpio controller registers.
If it's an offset why not name it geint_con_offset?
I wanted to keep the lines within 80 columns. Splitting a line into
two lines started making the code look unreadable.
OK no big deal.
quoted
quoted
+       int                     (*eint_gpio_init)(struct samsung_pinctrl_drv_data *);
+       int                     (*eint_wkup_init)(struct samsung_pinctrl_drv_data *);
I guess you need to set up these using auxdata?
No, these are populated by the platform (SoC) specific data that the
Samsung pinctrl driver gets during probe. Due to the differences in
the gpio and wakeup interrupt controllers on Samsung SoC's, the setup
and implementations of these  interrupts have been made SoC specific.
The pinctrl driver is responsible only for initiating the setup of the
gpio/wakeup interrupts.
I see, OK.
quoted
quoted
+/**
+ * struct samsung_pinctrl_drv_data: wrapper for holding driver data together.
+ * @virt_base: register base address of the controller.
+ * @dev: device instance representing the controller.
+ * @irq: interrpt number used by the controller to notify gpio interrupts.
+ * @ctrl: pin controller instance managed by the driver.
+ * @pctl: pin controller descriptor registered with the pinctrl subsystem.
Maybe name this pctl_desc then?
This name is used to in multiple places in the code and the longer the
name, there is always the case of the line spilling over 80
characters.
OK whatever... looking formward to next iteration!

Yours,
Linus Walleij
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help