Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
de536e30
Commit
de536e30
authored
Aug 31, 2014
by
Greg Kroah-Hartman
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
greybus: ap message loop added.
parent
27fb8310
Changes
6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
219 additions
and
9 deletions
+219
-9
drivers/staging/greybus/Makefile
drivers/staging/greybus/Makefile
+8
-1
drivers/staging/greybus/ap.c
drivers/staging/greybus/ap.c
+125
-0
drivers/staging/greybus/core.c
drivers/staging/greybus/core.c
+11
-3
drivers/staging/greybus/debugfs.c
drivers/staging/greybus/debugfs.c
+2
-2
drivers/staging/greybus/es1-ap-usb.c
drivers/staging/greybus/es1-ap-usb.c
+63
-1
drivers/staging/greybus/greybus.h
drivers/staging/greybus/greybus.h
+10
-2
No files found.
drivers/staging/greybus/Makefile
View file @
de536e30
greybus-y
:=
core.o gbuf.o debugfs.o i2c-gb.o gpio-gb.o sdio-gb.o uart-gb.o
greybus-y
:=
core.o
\
gbuf.o
\
debugfs.o
\
ap.o
\
i2c-gb.o
\
gpio-gb.o
\
sdio-gb.o
\
uart-gb.o
obj-m
+=
greybus.o
obj-m
+=
es1-ap-usb.o
...
...
drivers/staging/greybus/ap.c
0 → 100644
View file @
de536e30
/*
* Greybus "AP" message loop handling
*
* Copyright 2014 Google Inc.
*
* Released under the GPLv2 only.
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/types.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/kthread.h>
#include <linux/device.h>
#include "greybus.h"
struct
ap_msg
{
u8
*
data
;
int
size
;
struct
list_head
list
;
};
static
LIST_HEAD
(
ap_msg_list
);
static
spinlock_t
ap_msg_list_lock
;
static
struct
task_struct
*
ap_thread
;
static
wait_queue_head_t
ap_wait
;
static
struct
ap_msg
*
get_ap_msg
(
void
)
{
struct
ap_msg
*
ap_msg
;
unsigned
long
flags
;
spin_lock_irqsave
(
&
ap_msg_list_lock
,
flags
);
ap_msg
=
list_first_entry_or_null
(
&
ap_msg_list
,
struct
ap_msg
,
list
);
if
(
ap_msg
!=
NULL
)
list_del
(
&
ap_msg
->
list
);
spin_unlock_irqrestore
(
&
ap_msg_list_lock
,
flags
);
return
ap_msg
;
}
static
int
ap_process_loop
(
void
*
data
)
{
struct
ap_msg
*
ap_msg
;
while
(
!
kthread_should_stop
())
{
wait_event_interruptible
(
ap_wait
,
kthread_should_stop
());
if
(
kthread_should_stop
())
break
;
/* Get some data off of the ap list and process it */
ap_msg
=
get_ap_msg
();
if
(
!
ap_msg
)
continue
;
// FIXME - process the message
/* clean the message up */
kfree
(
ap_msg
->
data
);
kfree
(
ap_msg
);
}
return
0
;
}
int
gb_new_ap_msg
(
u8
*
data
,
int
size
)
{
struct
ap_msg
*
ap_msg
;
unsigned
long
flags
;
/*
* Totally naive copy the message into a new structure that we slowly
* create and add it to the list. Let's get this working, the odds of
* this being any "slow path" for AP messages is really low at this
* point in time, but you never know, so this comment is here to point
* out that maybe we should use a slab allocator, or even just not copy
* the data, but use it directly and force the urbs to be "new" each
* time.
*/
/* Note - this can, and will, be called in interrupt context. */
ap_msg
=
kmalloc
(
sizeof
(
*
ap_msg
),
GFP_ATOMIC
);
if
(
!
ap_msg
)
return
-
ENOMEM
;
ap_msg
->
data
=
kmalloc
(
size
,
GFP_ATOMIC
);
if
(
!
ap_msg
->
data
)
{
kfree
(
ap_msg
);
return
-
ENOMEM
;
}
memcpy
(
ap_msg
->
data
,
data
,
size
);
ap_msg
->
size
=
size
;
spin_lock_irqsave
(
&
ap_msg_list_lock
,
flags
);
list_add
(
&
ap_msg
->
list
,
&
ap_msg_list
);
spin_unlock_irqrestore
(
&
ap_msg_list_lock
,
flags
);
/* kick our thread to handle the message */
wake_up_interruptible
(
&
ap_wait
);
return
0
;
}
int
gb_thread_init
(
void
)
{
init_waitqueue_head
(
&
ap_wait
);
spin_lock_init
(
&
ap_msg_list_lock
);
ap_thread
=
kthread_run
(
ap_process_loop
,
NULL
,
"greybus_ap"
);
if
(
IS_ERR
(
ap_thread
))
return
PTR_ERR
(
ap_thread
);
return
0
;
}
void
gb_thread_destroy
(
void
)
{
kthread_stop
(
ap_thread
);
}
drivers/staging/greybus/core.c
View file @
de536e30
...
...
@@ -12,6 +12,7 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
#include <linux/kthread.h>
#include <linux/device.h>
#include "greybus.h"
...
...
@@ -199,7 +200,7 @@ static int __init gb_init(void)
{
int
retval
;
retval
=
g
reybus
_debugfs_init
();
retval
=
g
b
_debugfs_init
();
if
(
retval
)
return
retval
;
...
...
@@ -207,6 +208,10 @@ static int __init gb_init(void)
if
(
retval
)
goto
error_bus
;
retval
=
gb_thread_init
();
if
(
retval
)
goto
error_thread
;
// FIXME - more gb core init goes here
retval
=
gb_tty_init
();
...
...
@@ -216,10 +221,13 @@ static int __init gb_init(void)
return
0
;
error_tty:
gb_thread_destroy
();
error_thread:
bus_unregister
(
&
greybus_bus_type
);
error_bus:
g
reybus
_debugfs_cleanup
();
g
b
_debugfs_cleanup
();
return
retval
;
}
...
...
@@ -228,7 +236,7 @@ static void __exit gb_exit(void)
{
gb_tty_exit
();
bus_unregister
(
&
greybus_bus_type
);
g
reybus
_debugfs_cleanup
();
g
b
_debugfs_cleanup
();
}
module_init
(
gb_init
);
...
...
drivers/staging/greybus/debugfs.c
View file @
de536e30
...
...
@@ -19,7 +19,7 @@
static
struct
dentry
*
gb_debug_root
;
int
g
reybus
_debugfs_init
(
void
)
int
g
b
_debugfs_init
(
void
)
{
gb_debug_root
=
debugfs_create_dir
(
"greybus"
,
NULL
);
if
(
!
gb_debug_root
)
...
...
@@ -28,7 +28,7 @@ int greybus_debugfs_init(void)
return
0
;
}
void
g
reybus
_debugfs_cleanup
(
void
)
void
g
b
_debugfs_cleanup
(
void
)
{
debugfs_remove_recursive
(
gb_debug_root
);
}
drivers/staging/greybus/es1-ap-usb.c
View file @
de536e30
...
...
@@ -10,7 +10,7 @@
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/usb.h>
#include "greybus.h"
static
const
struct
usb_device_id
id_table
[]
=
{
{
USB_DEVICE
(
0x0000
,
0x0000
)
},
// FIXME
...
...
@@ -34,6 +34,68 @@ struct es1_ap_dev {
*/
static
struct
es1_ap_dev
*
es1_ap_dev
;
static
void
ap_in_callback
(
struct
urb
*
urb
)
{
struct
device
*
dev
=
&
urb
->
dev
->
dev
;
int
status
=
urb
->
status
;
int
retval
;
switch
(
status
)
{
case
0
:
break
;
case
-
EOVERFLOW
:
dev_err
(
dev
,
"%s: overflow actual length is %d
\n
"
,
__func__
,
urb
->
actual_length
);
case
-
ECONNRESET
:
case
-
ENOENT
:
case
-
ESHUTDOWN
:
case
-
EILSEQ
:
/* device is gone, stop sending */
return
;
default:
dev_err
(
dev
,
"%s: unknown status %d
\n
"
,
__func__
,
status
);
goto
exit
;
}
/* We have a message, create a new message structure, add it to the
* list, and wake up our thread that will process the messages.
*/
gb_new_ap_msg
(
urb
->
transfer_buffer
,
urb
->
actual_length
);
exit:
/* resubmit the urb to get more messages */
retval
=
usb_submit_urb
(
urb
,
GFP_ATOMIC
);
if
(
retval
)
dev_err
(
dev
,
"Can not submit urb for AP data: %d
\n
"
,
retval
);
}
static
void
ap_out_callback
(
struct
urb
*
urb
)
{
struct
device
*
dev
=
&
urb
->
dev
->
dev
;
int
status
=
urb
->
status
;
switch
(
status
)
{
case
0
:
break
;
case
-
EOVERFLOW
:
dev_err
(
dev
,
"%s: overflow actual length is %d
\n
"
,
__func__
,
urb
->
actual_length
);
case
-
ECONNRESET
:
case
-
ENOENT
:
case
-
ESHUTDOWN
:
case
-
EILSEQ
:
/* device is gone, stop sending */
return
;
default:
dev_err
(
dev
,
"%s: unknown status %d
\n
"
,
__func__
,
status
);
goto
exit
;
}
// FIXME - queue up next AP message to send???
exit:
return
;
}
static
int
ap_probe
(
struct
usb_interface
*
interface
,
const
struct
usb_device_id
*
id
)
...
...
drivers/staging/greybus/greybus.h
View file @
de536e30
...
...
@@ -176,8 +176,16 @@ void greybus_deregister(struct greybus_driver *driver);
int
greybus_disabled
(
void
);
int
greybus_debugfs_init
(
void
);
void
greybus_debugfs_cleanup
(
void
);
/* Internal functions to gb module, move to internal .h file eventually. */
int
gb_new_ap_msg
(
u8
*
data
,
int
length
);
int
gb_thread_init
(
void
);
void
gb_thread_destroy
(
void
);
int
gb_debugfs_init
(
void
);
void
gb_debugfs_cleanup
(
void
);
#endif
/* __KERNEL__ */
#endif
/* __LINUX_GREYBUS_H */
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment