summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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 */