diff options
author | Jonas Aaberg <jonas.aberg@stericsson.com> | 2012-10-25 02:40:42 -0400 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2012-11-09 07:13:23 -0500 |
commit | f1671bf5f0721356f0c7bc1b2fec54b1aaf40418 (patch) | |
tree | fa374ed144b273736d7f9337b1c7d45c84a14bb6 /drivers/pinctrl/pinctrl-nomadik.c | |
parent | f48283367fd2679906e06bdd9e886eec1ee59eb1 (diff) |
pinctrl/nomadik: make independent of prcmu driver
Currently there are some unnecessary criss-cross
dependencies between the PRCMU driver in MFD and a lot of
other drivers, mainly because other drivers need to poke
around in the PRCM register range.
In cases like this there are actually just a few select
registers that the pinctrl driver need to read/modify/write,
and it turns out that no other driver is actually using
these registers, so there are no concurrency issues
whatsoever.
So: don't let the location of the register range complicate
things, just poke into these registers directly and skip
a layer of indirection.
Take this opportunity to add kerneldoc to the pinctrl
state container.
Cc: Loic Pallardy <loic.pallardy@st.com>
Signed-off-by: Jonas Aaberg <jonas.aberg@stericsson.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/pinctrl/pinctrl-nomadik.c')
-rw-r--r-- | drivers/pinctrl/pinctrl-nomadik.c | 59 |
1 files changed, 39 insertions, 20 deletions
diff --git a/drivers/pinctrl/pinctrl-nomadik.c b/drivers/pinctrl/pinctrl-nomadik.c index 22f69375bb3a..6a95d0438b6a 100644 --- a/drivers/pinctrl/pinctrl-nomadik.c +++ b/drivers/pinctrl/pinctrl-nomadik.c | |||
@@ -30,20 +30,6 @@ | |||
30 | #include <linux/pinctrl/pinconf.h> | 30 | #include <linux/pinctrl/pinconf.h> |
31 | /* Since we request GPIOs from ourself */ | 31 | /* Since we request GPIOs from ourself */ |
32 | #include <linux/pinctrl/consumer.h> | 32 | #include <linux/pinctrl/consumer.h> |
33 | /* | ||
34 | * For the U8500 archs, use the PRCMU register interface, for the older | ||
35 | * Nomadik, provide some stubs. The functions using these will only be | ||
36 | * called on the U8500 series. | ||
37 | */ | ||
38 | #ifdef CONFIG_ARCH_U8500 | ||
39 | #include <linux/mfd/dbx500-prcmu.h> | ||
40 | #else | ||
41 | static inline u32 prcmu_read(unsigned int reg) { | ||
42 | return 0; | ||
43 | } | ||
44 | static inline void prcmu_write(unsigned int reg, u32 value) {} | ||
45 | static inline void prcmu_write_masked(unsigned int reg, u32 mask, u32 value) {} | ||
46 | #endif | ||
47 | #include <linux/platform_data/pinctrl-nomadik.h> | 33 | #include <linux/platform_data/pinctrl-nomadik.h> |
48 | 34 | ||
49 | #include <asm/mach/irq.h> | 35 | #include <asm/mach/irq.h> |
@@ -82,10 +68,18 @@ struct nmk_gpio_chip { | |||
82 | u32 lowemi; | 68 | u32 lowemi; |
83 | }; | 69 | }; |
84 | 70 | ||
71 | /** | ||
72 | * struct nmk_pinctrl - state container for the Nomadik pin controller | ||
73 | * @dev: containing device pointer | ||
74 | * @pctl: corresponding pin controller device | ||
75 | * @soc: SoC data for this specific chip | ||
76 | * @prcm_base: PRCM register range virtual base | ||
77 | */ | ||
85 | struct nmk_pinctrl { | 78 | struct nmk_pinctrl { |
86 | struct device *dev; | 79 | struct device *dev; |
87 | struct pinctrl_dev *pctl; | 80 | struct pinctrl_dev *pctl; |
88 | const struct nmk_pinctrl_soc_data *soc; | 81 | const struct nmk_pinctrl_soc_data *soc; |
82 | void __iomem *prcm_base; | ||
89 | }; | 83 | }; |
90 | 84 | ||
91 | static struct nmk_gpio_chip * | 85 | static struct nmk_gpio_chip * |
@@ -247,6 +241,15 @@ nmk_gpio_disable_lazy_irq(struct nmk_gpio_chip *nmk_chip, unsigned offset) | |||
247 | dev_dbg(nmk_chip->chip.dev, "%d: clearing interrupt mask\n", gpio); | 241 | dev_dbg(nmk_chip->chip.dev, "%d: clearing interrupt mask\n", gpio); |
248 | } | 242 | } |
249 | 243 | ||
244 | static void nmk_write_masked(void __iomem *reg, u32 mask, u32 value) | ||
245 | { | ||
246 | u32 val; | ||
247 | |||
248 | val = readl(reg); | ||
249 | val = ((val & ~mask) | (value & mask)); | ||
250 | writel(val, reg); | ||
251 | } | ||
252 | |||
250 | static void nmk_prcm_altcx_set_mode(struct nmk_pinctrl *npct, | 253 | static void nmk_prcm_altcx_set_mode(struct nmk_pinctrl *npct, |
251 | unsigned offset, unsigned alt_num) | 254 | unsigned offset, unsigned alt_num) |
252 | { | 255 | { |
@@ -285,8 +288,8 @@ static void nmk_prcm_altcx_set_mode(struct nmk_pinctrl *npct, | |||
285 | if (pin_desc->altcx[i].used == true) { | 288 | if (pin_desc->altcx[i].used == true) { |
286 | reg = gpiocr_regs[pin_desc->altcx[i].reg_index]; | 289 | reg = gpiocr_regs[pin_desc->altcx[i].reg_index]; |
287 | bit = pin_desc->altcx[i].control_bit; | 290 | bit = pin_desc->altcx[i].control_bit; |
288 | if (prcmu_read(reg) & BIT(bit)) { | 291 | if (readl(npct->prcm_base + reg) & BIT(bit)) { |
289 | prcmu_write_masked(reg, BIT(bit), 0); | 292 | nmk_write_masked(npct->prcm_base + reg, BIT(bit), 0); |
290 | dev_dbg(npct->dev, | 293 | dev_dbg(npct->dev, |
291 | "PRCM GPIOCR: pin %i: alternate-C%i has been disabled\n", | 294 | "PRCM GPIOCR: pin %i: alternate-C%i has been disabled\n", |
292 | offset, i+1); | 295 | offset, i+1); |
@@ -314,8 +317,8 @@ static void nmk_prcm_altcx_set_mode(struct nmk_pinctrl *npct, | |||
314 | if (pin_desc->altcx[i].used == true) { | 317 | if (pin_desc->altcx[i].used == true) { |
315 | reg = gpiocr_regs[pin_desc->altcx[i].reg_index]; | 318 | reg = gpiocr_regs[pin_desc->altcx[i].reg_index]; |
316 | bit = pin_desc->altcx[i].control_bit; | 319 | bit = pin_desc->altcx[i].control_bit; |
317 | if (prcmu_read(reg) & BIT(bit)) { | 320 | if (readl(npct->prcm_base + reg) & BIT(bit)) { |
318 | prcmu_write_masked(reg, BIT(bit), 0); | 321 | nmk_write_masked(npct->prcm_base + reg, BIT(bit), 0); |
319 | dev_dbg(npct->dev, | 322 | dev_dbg(npct->dev, |
320 | "PRCM GPIOCR: pin %i: alternate-C%i has been disabled\n", | 323 | "PRCM GPIOCR: pin %i: alternate-C%i has been disabled\n", |
321 | offset, i+1); | 324 | offset, i+1); |
@@ -327,7 +330,7 @@ static void nmk_prcm_altcx_set_mode(struct nmk_pinctrl *npct, | |||
327 | bit = pin_desc->altcx[alt_index].control_bit; | 330 | bit = pin_desc->altcx[alt_index].control_bit; |
328 | dev_dbg(npct->dev, "PRCM GPIOCR: pin %i: alternate-C%i has been selected\n", | 331 | dev_dbg(npct->dev, "PRCM GPIOCR: pin %i: alternate-C%i has been selected\n", |
329 | offset, alt_index+1); | 332 | offset, alt_index+1); |
330 | prcmu_write_masked(reg, BIT(bit), BIT(bit)); | 333 | nmk_write_masked(npct->prcm_base + reg, BIT(bit), BIT(bit)); |
331 | } | 334 | } |
332 | 335 | ||
333 | static void __nmk_config_pin(struct nmk_gpio_chip *nmk_chip, unsigned offset, | 336 | static void __nmk_config_pin(struct nmk_gpio_chip *nmk_chip, unsigned offset, |
@@ -693,7 +696,7 @@ static int nmk_prcm_gpiocr_get_mode(struct pinctrl_dev *pctldev, int gpio) | |||
693 | if (pin_desc->altcx[i].used == true) { | 696 | if (pin_desc->altcx[i].used == true) { |
694 | reg = gpiocr_regs[pin_desc->altcx[i].reg_index]; | 697 | reg = gpiocr_regs[pin_desc->altcx[i].reg_index]; |
695 | bit = pin_desc->altcx[i].control_bit; | 698 | bit = pin_desc->altcx[i].control_bit; |
696 | if (prcmu_read(reg) & BIT(bit)) | 699 | if (readl(npct->prcm_base + reg) & BIT(bit)) |
697 | return NMK_GPIO_ALT_C+i+1; | 700 | return NMK_GPIO_ALT_C+i+1; |
698 | } | 701 | } |
699 | } | 702 | } |
@@ -1851,6 +1854,7 @@ static int __devinit nmk_pinctrl_probe(struct platform_device *pdev) | |||
1851 | const struct platform_device_id *platid = platform_get_device_id(pdev); | 1854 | const struct platform_device_id *platid = platform_get_device_id(pdev); |
1852 | struct device_node *np = pdev->dev.of_node; | 1855 | struct device_node *np = pdev->dev.of_node; |
1853 | struct nmk_pinctrl *npct; | 1856 | struct nmk_pinctrl *npct; |
1857 | struct resource *res; | ||
1854 | unsigned int version = 0; | 1858 | unsigned int version = 0; |
1855 | int i; | 1859 | int i; |
1856 | 1860 | ||
@@ -1872,6 +1876,20 @@ static int __devinit nmk_pinctrl_probe(struct platform_device *pdev) | |||
1872 | if (version == PINCTRL_NMK_DB8540) | 1876 | if (version == PINCTRL_NMK_DB8540) |
1873 | nmk_pinctrl_db8540_init(&npct->soc); | 1877 | nmk_pinctrl_db8540_init(&npct->soc); |
1874 | 1878 | ||
1879 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
1880 | if (res) { | ||
1881 | npct->prcm_base = devm_ioremap(&pdev->dev, res->start, | ||
1882 | resource_size(res)); | ||
1883 | if (!npct->prcm_base) { | ||
1884 | dev_err(&pdev->dev, | ||
1885 | "failed to ioremap PRCM registers\n"); | ||
1886 | return -ENOMEM; | ||
1887 | } | ||
1888 | } else { | ||
1889 | dev_info(&pdev->dev, | ||
1890 | "No PRCM base, assume no ALT-Cx control is available\n"); | ||
1891 | } | ||
1892 | |||
1875 | /* | 1893 | /* |
1876 | * We need all the GPIO drivers to probe FIRST, or we will not be able | 1894 | * We need all the GPIO drivers to probe FIRST, or we will not be able |
1877 | * to obtain references to the struct gpio_chip * for them, and we | 1895 | * to obtain references to the struct gpio_chip * for them, and we |
@@ -1888,6 +1906,7 @@ static int __devinit nmk_pinctrl_probe(struct platform_device *pdev) | |||
1888 | nmk_pinctrl_desc.pins = npct->soc->pins; | 1906 | nmk_pinctrl_desc.pins = npct->soc->pins; |
1889 | nmk_pinctrl_desc.npins = npct->soc->npins; | 1907 | nmk_pinctrl_desc.npins = npct->soc->npins; |
1890 | npct->dev = &pdev->dev; | 1908 | npct->dev = &pdev->dev; |
1909 | |||
1891 | npct->pctl = pinctrl_register(&nmk_pinctrl_desc, &pdev->dev, npct); | 1910 | npct->pctl = pinctrl_register(&nmk_pinctrl_desc, &pdev->dev, npct); |
1892 | if (!npct->pctl) { | 1911 | if (!npct->pctl) { |
1893 | dev_err(&pdev->dev, "could not register Nomadik pinctrl driver\n"); | 1912 | dev_err(&pdev->dev, "could not register Nomadik pinctrl driver\n"); |