summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTom Burkart <tom@aussec.com>2019-05-14 18:45:40 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2019-05-14 22:52:51 -0400
commit4461d65176b408d6d7adefa41a95472a18a90a53 (patch)
tree8da092bd4a2848f83f9183bdab34768ecb114e6e
parentb287a25a7148a89d977c819c1f7d6584f875b682 (diff)
pps: descriptor-based gpio
This patch changes the GPIO access for the pps-gpio driver from the integer based API to the descriptor based API. The integer based API is considered deprecated and the descriptor based API is the preferred way to access GPIOs as per Documentation/driver-api/gpio/intro.rst No changes are made to userspace interfaces. Link: http://lkml.kernel.org/r/20190324043305.6627-2-tom@aussec.com Signed-off-by: Tom Burkart <tom@aussec.com> Acked-by: Rodolfo Giometti <giometti@enneenne.com> Reviewed-by: Philipp Zabel <philipp.zabel@gmail.com> Cc: Lukas Senger <lukas@fridolin.com> Cc: Rob Herring <robh@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--drivers/pps/clients/pps-gpio.c67
-rw-r--r--include/linux/pps-gpio.h3
2 files changed, 32 insertions, 38 deletions
diff --git a/drivers/pps/clients/pps-gpio.c b/drivers/pps/clients/pps-gpio.c
index dd5d1103e02b..4e5e9229814b 100644
--- a/drivers/pps/clients/pps-gpio.c
+++ b/drivers/pps/clients/pps-gpio.c
@@ -31,7 +31,7 @@
31#include <linux/slab.h> 31#include <linux/slab.h>
32#include <linux/pps_kernel.h> 32#include <linux/pps_kernel.h>
33#include <linux/pps-gpio.h> 33#include <linux/pps-gpio.h>
34#include <linux/gpio.h> 34#include <linux/gpio/consumer.h>
35#include <linux/list.h> 35#include <linux/list.h>
36#include <linux/of_device.h> 36#include <linux/of_device.h>
37#include <linux/of_gpio.h> 37#include <linux/of_gpio.h>
@@ -41,9 +41,9 @@ struct pps_gpio_device_data {
41 int irq; /* IRQ used as PPS source */ 41 int irq; /* IRQ used as PPS source */
42 struct pps_device *pps; /* PPS source device */ 42 struct pps_device *pps; /* PPS source device */
43 struct pps_source_info info; /* PPS source information */ 43 struct pps_source_info info; /* PPS source information */
44 struct gpio_desc *gpio_pin; /* GPIO port descriptors */
44 bool assert_falling_edge; 45 bool assert_falling_edge;
45 bool capture_clear; 46 bool capture_clear;
46 unsigned int gpio_pin;
47}; 47};
48 48
49/* 49/*
@@ -61,18 +61,37 @@ static irqreturn_t pps_gpio_irq_handler(int irq, void *data)
61 61
62 info = data; 62 info = data;
63 63
64 rising_edge = gpio_get_value(info->gpio_pin); 64 rising_edge = gpiod_get_value(info->gpio_pin);
65 if ((rising_edge && !info->assert_falling_edge) || 65 if ((rising_edge && !info->assert_falling_edge) ||
66 (!rising_edge && info->assert_falling_edge)) 66 (!rising_edge && info->assert_falling_edge))
67 pps_event(info->pps, &ts, PPS_CAPTUREASSERT, NULL); 67 pps_event(info->pps, &ts, PPS_CAPTUREASSERT, NULL);
68 else if (info->capture_clear && 68 else if (info->capture_clear &&
69 ((rising_edge && info->assert_falling_edge) || 69 ((rising_edge && info->assert_falling_edge) ||
70 (!rising_edge && !info->assert_falling_edge))) 70 (!rising_edge && !info->assert_falling_edge)))
71 pps_event(info->pps, &ts, PPS_CAPTURECLEAR, NULL); 71 pps_event(info->pps, &ts, PPS_CAPTURECLEAR, NULL);
72 72
73 return IRQ_HANDLED; 73 return IRQ_HANDLED;
74} 74}
75 75
76static int pps_gpio_setup(struct platform_device *pdev)
77{
78 struct pps_gpio_device_data *data = platform_get_drvdata(pdev);
79 struct device_node *np = pdev->dev.of_node;
80
81 data->gpio_pin = devm_gpiod_get(&pdev->dev,
82 NULL, /* request "gpios" */
83 GPIOD_IN);
84 if (IS_ERR(data->gpio_pin)) {
85 dev_err(&pdev->dev,
86 "failed to request PPS GPIO\n");
87 return PTR_ERR(data->gpio_pin);
88 }
89
90 if (of_property_read_bool(np, "assert-falling-edge"))
91 data->assert_falling_edge = true;
92 return 0;
93}
94
76static unsigned long 95static unsigned long
77get_irqf_trigger_flags(const struct pps_gpio_device_data *data) 96get_irqf_trigger_flags(const struct pps_gpio_device_data *data)
78{ 97{
@@ -90,53 +109,30 @@ get_irqf_trigger_flags(const struct pps_gpio_device_data *data)
90static int pps_gpio_probe(struct platform_device *pdev) 109static int pps_gpio_probe(struct platform_device *pdev)
91{ 110{
92 struct pps_gpio_device_data *data; 111 struct pps_gpio_device_data *data;
93 const char *gpio_label;
94 int ret; 112 int ret;
95 int pps_default_params; 113 int pps_default_params;
96 const struct pps_gpio_platform_data *pdata = pdev->dev.platform_data; 114 const struct pps_gpio_platform_data *pdata = pdev->dev.platform_data;
97 struct device_node *np = pdev->dev.of_node;
98 115
99 /* allocate space for device info */ 116 /* allocate space for device info */
100 data = devm_kzalloc(&pdev->dev, sizeof(struct pps_gpio_device_data), 117 data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
101 GFP_KERNEL);
102 if (!data) 118 if (!data)
103 return -ENOMEM; 119 return -ENOMEM;
120 platform_set_drvdata(pdev, data);
104 121
122 /* GPIO setup */
105 if (pdata) { 123 if (pdata) {
106 data->gpio_pin = pdata->gpio_pin; 124 data->gpio_pin = pdata->gpio_pin;
107 gpio_label = pdata->gpio_label;
108 125
109 data->assert_falling_edge = pdata->assert_falling_edge; 126 data->assert_falling_edge = pdata->assert_falling_edge;
110 data->capture_clear = pdata->capture_clear; 127 data->capture_clear = pdata->capture_clear;
111 } else { 128 } else {
112 ret = of_get_gpio(np, 0); 129 ret = pps_gpio_setup(pdev);
113 if (ret < 0) { 130 if (ret)
114 dev_err(&pdev->dev, "failed to get GPIO from device tree\n"); 131 return -EINVAL;
115 return ret;
116 }
117 data->gpio_pin = ret;
118 gpio_label = PPS_GPIO_NAME;
119
120 if (of_get_property(np, "assert-falling-edge", NULL))
121 data->assert_falling_edge = true;
122 }
123
124 /* GPIO setup */
125 ret = devm_gpio_request(&pdev->dev, data->gpio_pin, gpio_label);
126 if (ret) {
127 dev_err(&pdev->dev, "failed to request GPIO %u\n",
128 data->gpio_pin);
129 return ret;
130 }
131
132 ret = gpio_direction_input(data->gpio_pin);
133 if (ret) {
134 dev_err(&pdev->dev, "failed to set pin direction\n");
135 return -EINVAL;
136 } 132 }
137 133
138 /* IRQ setup */ 134 /* IRQ setup */
139 ret = gpio_to_irq(data->gpio_pin); 135 ret = gpiod_to_irq(data->gpio_pin);
140 if (ret < 0) { 136 if (ret < 0) {
141 dev_err(&pdev->dev, "failed to map GPIO to IRQ: %d\n", ret); 137 dev_err(&pdev->dev, "failed to map GPIO to IRQ: %d\n", ret);
142 return -EINVAL; 138 return -EINVAL;
@@ -173,7 +169,6 @@ static int pps_gpio_probe(struct platform_device *pdev)
173 return -EINVAL; 169 return -EINVAL;
174 } 170 }
175 171
176 platform_set_drvdata(pdev, data);
177 dev_info(data->pps->dev, "Registered IRQ %d as PPS source\n", 172 dev_info(data->pps->dev, "Registered IRQ %d as PPS source\n",
178 data->irq); 173 data->irq);
179 174
@@ -209,4 +204,4 @@ MODULE_AUTHOR("Ricardo Martins <rasm@fe.up.pt>");
209MODULE_AUTHOR("James Nuss <jamesnuss@nanometrics.ca>"); 204MODULE_AUTHOR("James Nuss <jamesnuss@nanometrics.ca>");
210MODULE_DESCRIPTION("Use GPIO pin as PPS source"); 205MODULE_DESCRIPTION("Use GPIO pin as PPS source");
211MODULE_LICENSE("GPL"); 206MODULE_LICENSE("GPL");
212MODULE_VERSION("1.0.0"); 207MODULE_VERSION("1.1.0");
diff --git a/include/linux/pps-gpio.h b/include/linux/pps-gpio.h
index 56f35dd3d01d..f028d2cda6f5 100644
--- a/include/linux/pps-gpio.h
+++ b/include/linux/pps-gpio.h
@@ -23,10 +23,9 @@
23#define _PPS_GPIO_H 23#define _PPS_GPIO_H
24 24
25struct pps_gpio_platform_data { 25struct pps_gpio_platform_data {
26 struct gpio_desc *gpio_pin;
26 bool assert_falling_edge; 27 bool assert_falling_edge;
27 bool capture_clear; 28 bool capture_clear;
28 unsigned int gpio_pin;
29 const char *gpio_label;
30}; 29};
31 30
32#endif /* _PPS_GPIO_H */ 31#endif /* _PPS_GPIO_H */