1414#include <linux/init.h>
1515#include <linux/module.h>
1616#include <linux/gpio/driver.h>
17+ #include <linux/gpio/consumer.h>
1718#include <linux/platform_device.h>
1819#include <linux/slab.h>
1920#include <linux/interrupt.h>
2021#include <linux/irq.h>
2122#include <linux/irq_work.h>
23+ #include <linux/debugfs.h>
24+ #include <linux/uaccess.h>
25+
26+ #include "gpiolib.h"
2227
2328#define GPIO_MOCKUP_NAME "gpio-mockup"
2429#define GPIO_MOCKUP_MAX_GC 10
@@ -47,6 +52,13 @@ struct gpio_mockup_chip {
4752 struct gpio_chip gc ;
4853 struct gpio_mockup_line_status * lines ;
4954 struct gpio_mockup_irq_context irq_ctx ;
55+ struct dentry * dbg_dir ;
56+ };
57+
58+ struct gpio_mockup_dbgfs_private {
59+ struct gpio_mockup_chip * chip ;
60+ struct gpio_desc * desc ;
61+ int offset ;
5062};
5163
5264static int gpio_mockup_ranges [GPIO_MOCKUP_MAX_GC << 1 ];
@@ -58,6 +70,7 @@ module_param_named(gpio_mockup_named_lines,
5870 gpio_mockup_named_lines , bool , 0400 );
5971
6072static const char gpio_mockup_name_start = 'A' ;
73+ static struct dentry * gpio_mockup_dbg_dir ;
6174
6275static int gpio_mockup_get (struct gpio_chip * gc , unsigned int offset )
6376{
@@ -175,6 +188,94 @@ static int gpio_mockup_irqchip_setup(struct device *dev,
175188 return 0 ;
176189}
177190
191+ static ssize_t gpio_mockup_event_write (struct file * file ,
192+ const char __user * usr_buf ,
193+ size_t size , loff_t * ppos )
194+ {
195+ struct gpio_mockup_dbgfs_private * priv ;
196+ struct gpio_mockup_chip * chip ;
197+ struct seq_file * sfile ;
198+ struct gpio_desc * desc ;
199+ struct gpio_chip * gc ;
200+ int status , val ;
201+ char buf ;
202+
203+ sfile = file -> private_data ;
204+ priv = sfile -> private ;
205+ desc = priv -> desc ;
206+ chip = priv -> chip ;
207+ gc = & chip -> gc ;
208+
209+ status = copy_from_user (& buf , usr_buf , 1 );
210+ if (status )
211+ return status ;
212+
213+ if (buf == '0' )
214+ val = 0 ;
215+ else if (buf == '1' )
216+ val = 1 ;
217+ else
218+ return - EINVAL ;
219+
220+ gpiod_set_value_cansleep (desc , val );
221+ priv -> chip -> irq_ctx .irq = gc -> irq_base + priv -> offset ;
222+ irq_work_queue (& priv -> chip -> irq_ctx .work );
223+
224+ return size ;
225+ }
226+
227+ static int gpio_mockup_event_open (struct inode * inode , struct file * file )
228+ {
229+ return single_open (file , NULL , inode -> i_private );
230+ }
231+
232+ static const struct file_operations gpio_mockup_event_ops = {
233+ .owner = THIS_MODULE ,
234+ .open = gpio_mockup_event_open ,
235+ .write = gpio_mockup_event_write ,
236+ .llseek = no_llseek ,
237+ };
238+
239+ static void gpio_mockup_debugfs_setup (struct device * dev ,
240+ struct gpio_mockup_chip * chip )
241+ {
242+ struct gpio_mockup_dbgfs_private * priv ;
243+ struct dentry * evfile ;
244+ struct gpio_chip * gc ;
245+ char * name ;
246+ int i ;
247+
248+ gc = & chip -> gc ;
249+
250+ chip -> dbg_dir = debugfs_create_dir (gc -> label , gpio_mockup_dbg_dir );
251+ if (!chip -> dbg_dir )
252+ goto err ;
253+
254+ for (i = 0 ; i < gc -> ngpio ; i ++ ) {
255+ name = devm_kasprintf (dev , GFP_KERNEL , "%d" , i );
256+ if (!name )
257+ goto err ;
258+
259+ priv = devm_kzalloc (dev , sizeof (* priv ), GFP_KERNEL );
260+ if (!priv )
261+ goto err ;
262+
263+ priv -> chip = chip ;
264+ priv -> offset = i ;
265+ priv -> desc = & gc -> gpiodev -> descs [i ];
266+
267+ evfile = debugfs_create_file (name , 0200 , chip -> dbg_dir , priv ,
268+ & gpio_mockup_event_ops );
269+ if (!evfile )
270+ goto err ;
271+ }
272+
273+ return ;
274+
275+ err :
276+ dev_err (dev , "error creating debugfs directory\n" );
277+ }
278+
178279static int gpio_mockup_add (struct device * dev ,
179280 struct gpio_mockup_chip * chip ,
180281 const char * name , int base , int ngpio )
@@ -209,7 +310,14 @@ static int gpio_mockup_add(struct device *dev,
209310 if (ret )
210311 return ret ;
211312
212- return devm_gpiochip_add_data (dev , & chip -> gc , chip );
313+ ret = devm_gpiochip_add_data (dev , & chip -> gc , chip );
314+ if (ret )
315+ return ret ;
316+
317+ if (gpio_mockup_dbg_dir )
318+ gpio_mockup_debugfs_setup (dev , chip );
319+
320+ return 0 ;
213321}
214322
215323static int gpio_mockup_probe (struct platform_device * pdev )
@@ -291,6 +399,11 @@ static int __init mock_device_init(void)
291399{
292400 int err ;
293401
402+ gpio_mockup_dbg_dir = debugfs_create_dir ("gpio-mockup-event" , NULL );
403+ if (!gpio_mockup_dbg_dir )
404+ pr_err ("%s: error creating debugfs directory\n" ,
405+ GPIO_MOCKUP_NAME );
406+
294407 pdev = platform_device_alloc (GPIO_MOCKUP_NAME , -1 );
295408 if (!pdev )
296409 return - ENOMEM ;
@@ -312,6 +425,7 @@ static int __init mock_device_init(void)
312425
313426static void __exit mock_device_exit (void )
314427{
428+ debugfs_remove_recursive (gpio_mockup_dbg_dir );
315429 platform_driver_unregister (& gpio_mockup_driver );
316430 platform_device_unregister (pdev );
317431}
0 commit comments