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
025742cc
Commit
025742cc
authored
Nov 18, 2014
by
Greg Kroah-Hartman
Browse files
Options
Browse Files
Download
Plain Diff
greybus: Merge branch 'master' into vibrator-gb
parents
396671b1
374e6a26
Changes
13
Show whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
162 additions
and
325 deletions
+162
-325
drivers/staging/greybus/Makefile
drivers/staging/greybus/Makefile
+0
-1
drivers/staging/greybus/connection.c
drivers/staging/greybus/connection.c
+15
-0
drivers/staging/greybus/connection.h
drivers/staging/greybus/connection.h
+2
-0
drivers/staging/greybus/core.c
drivers/staging/greybus/core.c
+0
-9
drivers/staging/greybus/es1-ap-usb.c
drivers/staging/greybus/es1-ap-usb.c
+6
-0
drivers/staging/greybus/gbuf.c
drivers/staging/greybus/gbuf.c
+0
-134
drivers/staging/greybus/gpio-gb.c
drivers/staging/greybus/gpio-gb.c
+18
-18
drivers/staging/greybus/greybus.h
drivers/staging/greybus/greybus.h
+1
-89
drivers/staging/greybus/i2c-gb.c
drivers/staging/greybus/i2c-gb.c
+8
-8
drivers/staging/greybus/operation.c
drivers/staging/greybus/operation.c
+69
-37
drivers/staging/greybus/operation.h
drivers/staging/greybus/operation.h
+21
-7
drivers/staging/greybus/pwm-gb.c
drivers/staging/greybus/pwm-gb.c
+14
-14
drivers/staging/greybus/uart-gb.c
drivers/staging/greybus/uart-gb.c
+8
-8
No files found.
drivers/staging/greybus/Makefile
View file @
025742cc
greybus-y
:=
core.o
\
gbuf.o
\
sysfs.o
\
debugfs.o
\
ap.o
\
...
...
drivers/staging/greybus/connection.c
View file @
025742cc
...
...
@@ -29,6 +29,21 @@ struct gb_connection *gb_hd_connection_find(struct greybus_host_device *hd,
return
connection
;
}
void
greybus_cport_in
(
struct
greybus_host_device
*
hd
,
u16
cport_id
,
u8
*
data
,
size_t
length
)
{
struct
gb_connection
*
connection
;
connection
=
gb_hd_connection_find
(
hd
,
cport_id
);
if
(
!
connection
)
{
dev_err
(
hd
->
parent
,
"nonexistent connection (%zu bytes dropped)
\n
"
,
length
);
return
;
}
gb_connection_operation_recv
(
connection
,
data
,
length
);
}
EXPORT_SYMBOL_GPL
(
greybus_cport_in
);
/*
* Allocate an available CPort Id for use for the host side of the
* given connection. The lowest-available id is returned, so the
...
...
drivers/staging/greybus/connection.h
View file @
025742cc
...
...
@@ -53,6 +53,8 @@ void gb_connection_exit(struct gb_connection *connection);
struct
gb_connection
*
gb_hd_connection_find
(
struct
greybus_host_device
*
hd
,
u16
cport_id
);
void
greybus_cport_in
(
struct
greybus_host_device
*
hd
,
u16
cport_id
,
u8
*
data
,
size_t
length
);
__printf
(
2
,
3
)
void
gb_connection_err
(
struct
gb_connection
*
connection
,
const
char
*
fmt
,
...);
...
...
drivers/staging/greybus/core.c
View file @
025742cc
...
...
@@ -226,12 +226,6 @@ static int __init gb_init(void)
goto
error_ap
;
}
retval
=
gb_gbuf_init
();
if
(
retval
)
{
pr_err
(
"gb_gbuf_init failed
\n
"
);
goto
error_gbuf
;
}
retval
=
gb_operation_init
();
if
(
retval
)
{
pr_err
(
"gb_operation_init failed
\n
"
);
...
...
@@ -250,8 +244,6 @@ static int __init gb_init(void)
error_protocol:
gb_operation_exit
();
error_operation:
gb_gbuf_exit
();
error_gbuf:
gb_ap_exit
();
error_ap:
bus_unregister
(
&
greybus_bus_type
);
...
...
@@ -265,7 +257,6 @@ static void __exit gb_exit(void)
{
gb_protocol_exit
();
gb_operation_exit
();
gb_gbuf_exit
();
gb_ap_exit
();
bus_unregister
(
&
greybus_bus_type
);
gb_debugfs_cleanup
();
...
...
drivers/staging/greybus/es1-ap-usb.c
View file @
025742cc
...
...
@@ -99,6 +99,9 @@ static int alloc_gbuf_data(struct gbuf *gbuf, unsigned int size,
u32
cport_reserve
=
gbuf
->
dest_cport_id
==
CPORT_ID_BAD
?
0
:
1
;
u8
*
buffer
;
if
(
gbuf
->
transfer_buffer
)
return
-
EALREADY
;
if
(
size
>
ES1_GBUF_MSG_SIZE
)
{
pr_err
(
"guf was asked to be bigger than %ld!
\n
"
,
ES1_GBUF_MSG_SIZE
);
...
...
@@ -146,6 +149,7 @@ static void free_gbuf_data(struct gbuf *gbuf)
if
(
gbuf
->
dest_cport_id
!=
CPORT_ID_BAD
)
transfer_buffer
--
;
/* Back up to cport id */
kfree
(
transfer_buffer
);
gbuf
->
transfer_buffer
=
NULL
;
}
#define ES1_TIMEOUT 500
/* 500 ms for the SVC to do something */
...
...
@@ -214,6 +218,8 @@ static int submit_gbuf(struct gbuf *gbuf, gfp_t gfp_mask)
struct
urb
*
urb
;
transfer_buffer
=
gbuf
->
transfer_buffer
;
if
(
!
transfer_buffer
)
return
-
EINVAL
;
buffer
=
&
transfer_buffer
[
-
1
];
/* yes, we mean -1 */
/* Find a free urb */
...
...
drivers/staging/greybus/gbuf.c
deleted
100644 → 0
View file @
396671b1
/*
* Greybus gbuf 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/kref.h>
#include <linux/device.h>
#include <linux/slab.h>
#include "greybus.h"
static
struct
kmem_cache
*
gbuf_head_cache
;
/**
* greybus_alloc_gbuf - allocate a greybus buffer
*
* @gmod: greybus device that wants to allocate this
* @cport: cport to send the data to
* @complete: callback when the gbuf is finished with
* @size: size of the buffer
* @gfp_mask: allocation mask
*
* TODO: someday it will be nice to handle DMA, but for now, due to the
* architecture we are stuck with, the greybus core has to allocate the buffer
* that the driver can then fill up with the data to be sent out. Curse
* hardware designers for this issue...
*/
struct
gbuf
*
greybus_alloc_gbuf
(
struct
greybus_host_device
*
hd
,
u16
dest_cport_id
,
unsigned
int
size
,
gfp_t
gfp_mask
)
{
struct
gbuf
*
gbuf
;
int
retval
;
gbuf
=
kmem_cache_zalloc
(
gbuf_head_cache
,
gfp_mask
);
if
(
!
gbuf
)
return
NULL
;
kref_init
(
&
gbuf
->
kref
);
gbuf
->
hd
=
hd
;
gbuf
->
dest_cport_id
=
dest_cport_id
;
gbuf
->
status
=
-
EBADR
;
/* Initial value--means "never set" */
/* Host controller specific allocation for the actual buffer */
retval
=
hd
->
driver
->
alloc_gbuf_data
(
gbuf
,
size
,
gfp_mask
);
if
(
retval
)
{
kmem_cache_free
(
gbuf_head_cache
,
gbuf
);
return
NULL
;
}
return
gbuf
;
}
EXPORT_SYMBOL_GPL
(
greybus_alloc_gbuf
);
static
DEFINE_MUTEX
(
gbuf_mutex
);
static
void
free_gbuf
(
struct
kref
*
kref
)
{
struct
gbuf
*
gbuf
=
container_of
(
kref
,
struct
gbuf
,
kref
);
gbuf
->
hd
->
driver
->
free_gbuf_data
(
gbuf
);
kmem_cache_free
(
gbuf_head_cache
,
gbuf
);
mutex_unlock
(
&
gbuf_mutex
);
}
void
greybus_free_gbuf
(
struct
gbuf
*
gbuf
)
{
/* drop the reference count and get out of here */
kref_put_mutex
(
&
gbuf
->
kref
,
free_gbuf
,
&
gbuf_mutex
);
}
EXPORT_SYMBOL_GPL
(
greybus_free_gbuf
);
struct
gbuf
*
greybus_get_gbuf
(
struct
gbuf
*
gbuf
)
{
mutex_lock
(
&
gbuf_mutex
);
kref_get
(
&
gbuf
->
kref
);
mutex_unlock
(
&
gbuf_mutex
);
return
gbuf
;
}
EXPORT_SYMBOL_GPL
(
greybus_get_gbuf
);
int
greybus_submit_gbuf
(
struct
gbuf
*
gbuf
,
gfp_t
gfp_mask
)
{
gbuf
->
status
=
-
EINPROGRESS
;
return
gbuf
->
hd
->
driver
->
submit_gbuf
(
gbuf
,
gfp_mask
);
}
void
greybus_kill_gbuf
(
struct
gbuf
*
gbuf
)
{
if
(
gbuf
->
status
!=
-
EINPROGRESS
)
return
;
gbuf
->
hd
->
driver
->
kill_gbuf
(
gbuf
);
}
void
greybus_cport_in
(
struct
greybus_host_device
*
hd
,
u16
cport_id
,
u8
*
data
,
size_t
length
)
{
struct
gb_connection
*
connection
;
connection
=
gb_hd_connection_find
(
hd
,
cport_id
);
if
(
!
connection
)
{
dev_err
(
hd
->
parent
,
"nonexistent connection (%zu bytes dropped)
\n
"
,
length
);
return
;
}
gb_connection_operation_recv
(
connection
,
data
,
length
);
}
EXPORT_SYMBOL_GPL
(
greybus_cport_in
);
int
gb_gbuf_init
(
void
)
{
gbuf_head_cache
=
kmem_cache_create
(
"gbuf_head_cache"
,
sizeof
(
struct
gbuf
),
0
,
0
,
NULL
);
return
0
;
}
void
gb_gbuf_exit
(
void
)
{
kmem_cache_destroy
(
gbuf_head_cache
);
gbuf_head_cache
=
NULL
;
}
drivers/staging/greybus/gpio-gb.c
View file @
025742cc
...
...
@@ -153,7 +153,7 @@ static int gb_gpio_proto_version_operation(struct gb_gpio_controller *gb_gpio_co
goto
out
;
}
response
=
operation
->
response
_
payload
;
response
=
operation
->
response
.
payload
;
if
(
response
->
status
)
{
gb_connection_err
(
connection
,
"version response %hhu"
,
response
->
status
);
...
...
@@ -199,7 +199,7 @@ static int gb_gpio_line_count_operation(struct gb_gpio_controller *gb_gpio_contr
goto
out
;
}
response
=
operation
->
response
_
payload
;
response
=
operation
->
response
.
payload
;
if
(
response
->
status
)
{
gb_connection_err
(
connection
,
"line count response %hhu"
,
response
->
status
);
...
...
@@ -234,7 +234,7 @@ static int gb_gpio_activate_operation(struct gb_gpio_controller *gb_gpio_control
sizeof
(
*
request
),
sizeof
(
*
response
));
if
(
!
operation
)
return
-
ENOMEM
;
request
=
operation
->
request
_
payload
;
request
=
operation
->
request
.
payload
;
request
->
which
=
which
;
/* Synchronous operation--no callback */
...
...
@@ -244,7 +244,7 @@ static int gb_gpio_activate_operation(struct gb_gpio_controller *gb_gpio_control
goto
out
;
}
response
=
operation
->
response
_
payload
;
response
=
operation
->
response
.
payload
;
if
(
response
->
status
)
{
gb_connection_err
(
connection
,
"activate response %hhu"
,
response
->
status
);
...
...
@@ -278,7 +278,7 @@ static int gb_gpio_deactivate_operation(struct gb_gpio_controller *gb_gpio_contr
sizeof
(
*
request
),
sizeof
(
*
response
));
if
(
!
operation
)
return
-
ENOMEM
;
request
=
operation
->
request
_
payload
;
request
=
operation
->
request
.
payload
;
request
->
which
=
which
;
/* Synchronous operation--no callback */
...
...
@@ -288,7 +288,7 @@ static int gb_gpio_deactivate_operation(struct gb_gpio_controller *gb_gpio_contr
goto
out
;
}
response
=
operation
->
response
_
payload
;
response
=
operation
->
response
.
payload
;
if
(
response
->
status
)
{
gb_connection_err
(
connection
,
"deactivate response %hhu"
,
response
->
status
);
...
...
@@ -320,7 +320,7 @@ static int gb_gpio_get_direction_operation(struct gb_gpio_controller *gb_gpio_co
sizeof
(
*
request
),
sizeof
(
*
response
));
if
(
!
operation
)
return
-
ENOMEM
;
request
=
operation
->
request
_
payload
;
request
=
operation
->
request
.
payload
;
request
->
which
=
which
;
/* Synchronous operation--no callback */
...
...
@@ -330,7 +330,7 @@ static int gb_gpio_get_direction_operation(struct gb_gpio_controller *gb_gpio_co
goto
out
;
}
response
=
operation
->
response
_
payload
;
response
=
operation
->
response
.
payload
;
if
(
response
->
status
)
{
gb_connection_err
(
connection
,
"get direction response %hhu"
,
response
->
status
);
...
...
@@ -369,7 +369,7 @@ static int gb_gpio_direction_in_operation(struct gb_gpio_controller *gb_gpio_con
sizeof
(
*
request
),
sizeof
(
*
response
));
if
(
!
operation
)
return
-
ENOMEM
;
request
=
operation
->
request
_
payload
;
request
=
operation
->
request
.
payload
;
request
->
which
=
which
;
/* Synchronous operation--no callback */
...
...
@@ -379,7 +379,7 @@ static int gb_gpio_direction_in_operation(struct gb_gpio_controller *gb_gpio_con
goto
out
;
}
response
=
operation
->
response
_
payload
;
response
=
operation
->
response
.
payload
;
if
(
response
->
status
)
{
gb_connection_err
(
connection
,
"direction in response %hhu"
,
response
->
status
);
...
...
@@ -412,7 +412,7 @@ static int gb_gpio_direction_out_operation(struct gb_gpio_controller *gb_gpio_co
sizeof
(
*
request
),
sizeof
(
*
response
));
if
(
!
operation
)
return
-
ENOMEM
;
request
=
operation
->
request
_
payload
;
request
=
operation
->
request
.
payload
;
request
->
which
=
which
;
request
->
value
=
value_high
?
1
:
0
;
...
...
@@ -423,7 +423,7 @@ static int gb_gpio_direction_out_operation(struct gb_gpio_controller *gb_gpio_co
goto
out
;
}
response
=
operation
->
response
_
payload
;
response
=
operation
->
response
.
payload
;
if
(
response
->
status
)
{
gb_connection_err
(
connection
,
"direction out response %hhu"
,
response
->
status
);
...
...
@@ -456,7 +456,7 @@ static int gb_gpio_get_value_operation(struct gb_gpio_controller *gb_gpio_contro
sizeof
(
*
request
),
sizeof
(
*
response
));
if
(
!
operation
)
return
-
ENOMEM
;
request
=
operation
->
request
_
payload
;
request
=
operation
->
request
.
payload
;
request
->
which
=
which
;
/* Synchronous operation--no callback */
...
...
@@ -466,7 +466,7 @@ static int gb_gpio_get_value_operation(struct gb_gpio_controller *gb_gpio_contro
goto
out
;
}
response
=
operation
->
response
_
payload
;
response
=
operation
->
response
.
payload
;
if
(
response
->
status
)
{
gb_connection_err
(
connection
,
"get value response %hhu"
,
response
->
status
);
...
...
@@ -507,7 +507,7 @@ static int gb_gpio_set_value_operation(struct gb_gpio_controller *gb_gpio_contro
sizeof
(
*
request
),
sizeof
(
*
response
));
if
(
!
operation
)
return
-
ENOMEM
;
request
=
operation
->
request
_
payload
;
request
=
operation
->
request
.
payload
;
request
->
which
=
which
;
request
->
value
=
value_high
?
1
:
0
;
...
...
@@ -518,7 +518,7 @@ static int gb_gpio_set_value_operation(struct gb_gpio_controller *gb_gpio_contro
goto
out
;
}
response
=
operation
->
response
_
payload
;
response
=
operation
->
response
.
payload
;
if
(
response
->
status
)
{
gb_connection_err
(
connection
,
"set value response %hhu"
,
response
->
status
);
...
...
@@ -554,7 +554,7 @@ static int gb_gpio_set_debounce_operation(struct gb_gpio_controller *gb_gpio_con
sizeof
(
*
request
),
sizeof
(
*
response
));
if
(
!
operation
)
return
-
ENOMEM
;
request
=
operation
->
request
_
payload
;
request
=
operation
->
request
.
payload
;
request
->
which
=
which
;
request
->
usec
=
cpu_to_le16
(
debounce_usec
);
...
...
@@ -565,7 +565,7 @@ static int gb_gpio_set_debounce_operation(struct gb_gpio_controller *gb_gpio_con
goto
out
;
}
response
=
operation
->
response
_
payload
;
response
=
operation
->
response
.
payload
;
if
(
response
->
status
)
{
gb_connection_err
(
connection
,
"set debounce response %hhu"
,
response
->
status
);
...
...
drivers/staging/greybus/greybus.h
View file @
025742cc
...
...
@@ -56,82 +56,6 @@
#define HOST_DEV_CPORT_ID_MAX CONFIG_HOST_DEV_CPORT_ID_MAX
#define CPORT_ID_BAD U16_MAX
/* UniPro max id is 4095 */
/*
gbuf
This is the "main" data structure to send / receive Greybus messages
There are two different "views" of a gbuf structure:
- a greybus driver
- a greybus host controller
A Greybus driver needs to worry about the following:
- creating a gbuf
- putting data into a gbuf
- sending a gbuf to a device
- receiving a gbuf from a device
Creating a gbuf:
A greybus driver calls greybus_alloc_gbuf()
Putting data into a gbuf:
copy data into gbuf->transfer_buffer
Send a gbuf:
A greybus driver calls greybus_submit_gbuf()
The completion function in a gbuf will be called if the gbuf is successful
or not. That completion function runs in user context. After the
completion function is called, the gbuf must not be touched again as the
greybus core "owns" it. But, if a greybus driver wants to "hold on" to a
gbuf after the completion function has been called, a reference must be
grabbed on the gbuf with a call to greybus_get_gbuf(). When finished with
the gbuf, call greybus_free_gbuf() and when the last reference count is
dropped, it will be removed from the system.
Receive a gbuf:
A greybus driver calls gb_register_cport_complete() with a pointer to the
callback function to be called for when a gbuf is received from a specific
cport and device. That callback will be made in user context with a gbuf
when it is received. To stop receiving messages, call
gb_deregister_cport_complete() for a specific cport.
Greybus Host controller drivers need to provide
- a way to allocate the transfer buffer for a gbuf
- a way to free the transfer buffer for a gbuf when it is "finished"
- a way to submit gbuf for transmissions
- notify the core the gbuf is complete
- receive gbuf from the wire and submit them to the core
- a way to send and receive svc messages
Allocate a transfer buffer
the host controller function alloc_gbuf_data is called
Free a transfer buffer
the host controller function free_gbuf_data is called
Submit a gbuf to the hardware
the host controller function submit_gbuf is called
Notify the gbuf is complete
the host controller driver must call greybus_gbuf_finished()
Submit a SVC message to the hardware
the host controller function send_svc_msg is called
Receive gbuf messages
the host controller driver must call greybus_cport_in() with the data
Reveive SVC messages from the hardware
The host controller driver must call greybus_svc_in
*/
struct
gbuf
{
struct
kref
kref
;
struct
greybus_host_device
*
hd
;
u16
dest_cport_id
;
/* Destination CPort id */
int
status
;
void
*
transfer_buffer
;
u32
transfer_buffer_length
;
void
*
hcd_data
;
/* for the HCD to track the gbuf */
};
/* For SP1 hardware, we are going to "hardcode" each device to have all logical
* blocks in order to be able to address them as one unified "unit". Then
* higher up layers will then be able to talk to them as one logical block and
...
...
@@ -144,6 +68,7 @@ struct gbuf {
struct
greybus_host_device
;
struct
svc_msg
;
struct
gbuf
;
/* Greybus "Host driver" structure, needed by a host controller driver to be
* able to handle both SVC control as well as "real" greybus messages
...
...
@@ -177,19 +102,6 @@ struct greybus_host_device {
struct
greybus_host_device
*
greybus_create_hd
(
struct
greybus_host_driver
*
hd
,
struct
device
*
parent
);
void
greybus_remove_hd
(
struct
greybus_host_device
*
hd
);
void
greybus_cport_in
(
struct
greybus_host_device
*
hd
,
u16
cport_id
,
u8
*
data
,
size_t
length
);
struct
gbuf
*
greybus_alloc_gbuf
(
struct
greybus_host_device
*
hd
,
u16
dest_cport_id
,
unsigned
int
size
,
gfp_t
gfp_mask
);
void
greybus_free_gbuf
(
struct
gbuf
*
gbuf
);
struct
gbuf
*
greybus_get_gbuf
(
struct
gbuf
*
gbuf
);
#define greybus_put_gbuf greybus_free_gbuf
int
greybus_submit_gbuf
(
struct
gbuf
*
gbuf
,
gfp_t
mem_flags
);
void
greybus_kill_gbuf
(
struct
gbuf
*
gbuf
);
struct
greybus_driver
{
const
char
*
name
;
...
...
drivers/staging/greybus/i2c-gb.c
View file @
025742cc
...
...
@@ -118,7 +118,7 @@ static int gb_i2c_proto_version_operation(struct gb_i2c_device *gb_i2c_dev)
goto
out
;
}
response
=
operation
->
response
_
payload
;
response
=
operation
->
response
.
payload
;
if
(
response
->
status
)
{
gb_connection_err
(
connection
,
"version response %hhu"
,
response
->
status
);
...
...
@@ -170,7 +170,7 @@ static int gb_i2c_functionality_operation(struct gb_i2c_device *gb_i2c_dev)
goto
out
;
}
response
=
operation
->
response
_
payload
;
response
=
operation
->
response
.
payload
;
if
(
response
->
status
)
{
gb_connection_err
(
connection
,
"functionality response %hhu"
,
response
->
status
);
...
...
@@ -198,7 +198,7 @@ static int gb_i2c_timeout_operation(struct gb_i2c_device *gb_i2c_dev, u16 msec)
sizeof
(
*
request
),
sizeof
(
*
response
));
if
(
!
operation
)
return
-
ENOMEM
;
request
=
operation
->
request
_
payload
;
request
=
operation
->
request
.
payload
;
request
->
msec
=
cpu_to_le16
(
msec
);
/* Synchronous operation--no callback */
...
...
@@ -208,7 +208,7 @@ static int gb_i2c_timeout_operation(struct gb_i2c_device *gb_i2c_dev, u16 msec)
goto
out
;
}
response
=
operation
->
response
_
payload
;
response
=
operation
->
response
.
payload
;
if
(
response
->
status
)
{
gb_connection_err
(
connection
,
"timeout response %hhu"
,
response
->
status
);
...
...
@@ -235,7 +235,7 @@ static int gb_i2c_retries_operation(struct gb_i2c_device *gb_i2c_dev,
sizeof
(
*
request
),
sizeof
(
*
response
));
if
(
!
operation
)
return
-
ENOMEM
;
request
=
operation
->
request
_
payload
;
request
=
operation
->
request
.
payload
;
request
->
retries
=
retries
;
/* Synchronous operation--no callback */
...
...
@@ -245,7 +245,7 @@ static int gb_i2c_retries_operation(struct gb_i2c_device *gb_i2c_dev,
goto
out
;
}
response
=
operation
->
response
_
payload
;
response
=
operation
->
response
.
payload
;
if
(
response
->
status
)
{
gb_connection_err
(
connection
,
"retries response %hhu"
,
response
->
status
);
...
...
@@ -321,7 +321,7 @@ gb_i2c_transfer_request(struct gb_connection *connection,
if
(
!
operation
)
return
NULL
;
request
=
operation
->
request
_
payload
;
request
=
operation
->
request
.
payload
;
request
->
op_count
=
cpu_to_le16
(
op_count
);
/* Fill in the ops array */
op
=
&
request
->
ops
[
0
];
...
...
@@ -380,7 +380,7 @@ static int gb_i2c_transfer_operation(struct gb_i2c_device *gb_i2c_dev,
goto
out
;
}
response
=
operation
->
response
_
payload
;
response
=
operation
->
response
.
payload
;
if
(
response
->
status
)
{
if
(
response
->
status
==
GB_OP_RETRY
)
{
ret
=
-
EAGAIN
;
...
...
drivers/staging/greybus/operation.c
View file @
025742cc
...
...
@@ -23,6 +23,7 @@
/*
* XXX This needs to be coordinated with host driver parameters
* XXX May need to reduce to allow for message header within a page
*/
#define GB_OPERATION_MESSAGE_SIZE_MAX 4096
...
...
@@ -71,7 +72,7 @@ static void gb_pending_operation_insert(struct gb_operation *operation)
spin_unlock_irq
(
&
gb_operations_lock
);
/* Store the operation id in the request header */
header
=
operation
->
request
->
transfer_buffer
;
header
=
operation
->
request
.
gbuf
.
transfer_buffer
;
header
->
id
=
cpu_to_le16
(
operation
->
id
);
}
...
...
@@ -102,6 +103,20 @@ gb_pending_operation_find(struct gb_connection *connection, u16 id)
return
found
?
operation
:
NULL
;
}
static
int
greybus_submit_gbuf
(
struct
gbuf
*
gbuf
,
gfp_t
gfp_mask
)
{
gbuf
->
status
=
-
EINPROGRESS
;
return
gbuf
->
hd
->
driver
->
submit_gbuf
(
gbuf
,
gfp_mask
);
}
static
void
greybus_kill_gbuf
(
struct
gbuf
*
gbuf
)
{
if
(
gbuf
->
status
!=
-
EINPROGRESS
)
return
;
gbuf
->
hd
->
driver
->
kill_gbuf
(
gbuf
);
}
/*
* An operations's response message has arrived. If no callback was
* supplied it was submitted for asynchronous completion, so we notify
...
...
@@ -124,7 +139,7 @@ int gb_operation_wait(struct gb_operation *operation)
ret
=
wait_for_completion_interruptible
(
&
operation
->
completion
);
/* If interrupted, cancel the in-flight buffer */
if
(
ret
<
0
)
greybus_kill_gbuf
(
operation
->
request
);
greybus_kill_gbuf
(
&
operation
->
request
.
gbuf
);
return
ret
;
}
...
...
@@ -134,7 +149,7 @@ static void gb_operation_request_handle(struct gb_operation *operation)
struct
gb_protocol
*
protocol
=
operation
->
connection
->
protocol
;
struct
gb_operation_msg_hdr
*
header
;
header
=
operation
->
request
->
transfer_buffer
;
header
=
operation
->
request
.
gbuf
.
transfer_buffer
;
/*
* If the protocol has no incoming request handler, report
...
...
@@ -164,7 +179,7 @@ static void gb_operation_recv_work(struct work_struct *recv_work)
bool
incoming_request
;
operation
=
container_of
(
recv_work
,
struct
gb_operation
,
recv_work
);
incoming_request
=
operation
->
response
==
NULL
;
incoming_request
=
operation
->
response
.
gbuf
.
transfer_buffer
==
NULL
;
if
(
incoming_request
)
gb_operation_request_handle
(
operation
);
gb_operation_complete
(
operation
);
...
...
@@ -196,28 +211,42 @@ static void operation_timeout(struct work_struct *work)
* initialize it here (it'll be overwritten by the incoming
* message).
*/
static
struct
gbuf
*
gb_operation_gbuf_create
(
struct
gb_operation
*
operation
,
static
int
gb_operation_message_init
(
struct
gb_operation
*
operation
,
u8
type
,
size_t
size
,
bool
data_out
)
bool
request
,
bool
data_out
)
{
struct
gb_connection
*
connection
=
operation
->
connection
;
struct
greybus_host_device
*
hd
=
connection
->
hd
;
struct
gb_message
*
message
;
struct
gb_operation_msg_hdr
*
header
;
struct
gbuf
*
gbuf
;
gfp_t
gfp_flags
=
data_out
?
GFP_KERNEL
:
GFP_ATOMIC
;
u16
dest_cport_id
;
int
ret
;
if
(
size
>
GB_OPERATION_MESSAGE_SIZE_MAX
)
return
NULL
;
/* Message too big */
return
-
E2BIG
;
size
+=
sizeof
(
*
header
);
if
(
request
)
{
message
=
&
operation
->
request
;
}
else
{
message
=
&
operation
->
response
;
type
|=
GB_OPERATION_TYPE_RESPONSE
;
}
gbuf
=
&
message
->
gbuf
;
if
(
data_out
)
dest_cport_id
=
connection
->
interface_cport_id
;
else
dest_cport_id
=
CPORT_ID_BAD
;
size
+=
sizeof
(
*
header
);
gbuf
=
greybus_alloc_gbuf
(
connection
->
hd
,
dest_cport_id
,
size
,
gfp_flags
);
if
(
!
gbuf
)
return
NULL
;
gbuf
->
hd
=
hd
;
gbuf
->
dest_cport_id
=
dest_cport_id
;
gbuf
->
status
=
-
EBADR
;
/* Initial value--means "never set" */
ret
=
hd
->
driver
->
alloc_gbuf_data
(
gbuf
,
size
,
gfp_flags
);
if
(
ret
)
return
ret
;
/* Fill in the header structure */
header
=
(
struct
gb_operation_msg_hdr
*
)
gbuf
->
transfer_buffer
;
...
...
@@ -225,7 +254,17 @@ static struct gbuf *gb_operation_gbuf_create(struct gb_operation *operation,
header
->
id
=
0
;
/* Filled in when submitted */
header
->
type
=
type
;
return
gbuf
;
message
->
payload
=
header
+
1
;
message
->
operation
=
operation
;
return
0
;
}
static
void
gb_operation_message_exit
(
struct
gb_message
*
message
)
{
message
->
operation
=
NULL
;
message
->
payload
=
NULL
;
message
->
gbuf
.
hd
->
driver
->
free_gbuf_data
(
&
message
->
gbuf
);
}
/*
...
...
@@ -251,30 +290,23 @@ struct gb_operation *gb_operation_create(struct gb_connection *connection,
struct
gb_operation
*
operation
;
gfp_t
gfp_flags
=
response_size
?
GFP_KERNEL
:
GFP_ATOMIC
;
bool
outgoing
=
response_size
!=
0
;
int
ret
;
operation
=
kmem_cache_zalloc
(
gb_operation_cache
,
gfp_flags
);
if
(
!
operation
)
return
NULL
;
operation
->
connection
=
connection
;
operation
->
request
=
gb_operation_gbuf_create
(
operation
,
type
,
request_size
,
outgoing
);
if
(
!
operation
->
request
)
ret
=
gb_operation_message_init
(
operation
,
type
,
request_size
,
true
,
outgoing
);
if
(
ret
)
goto
err_cache
;
operation
->
request_payload
=
operation
->
request
->
transfer_buffer
+
sizeof
(
struct
gb_operation_msg_hdr
);
if
(
outgoing
)
{
type
|=
GB_OPERATION_TYPE_RESPONSE
;
operation
->
response
=
gb_operation_gbuf_create
(
operation
,
type
,
response_size
,
false
);
if
(
!
operation
->
response
)
ret
=
gb_operation_message_init
(
operation
,
type
,
response_size
,
false
,
false
);
if
(
ret
)
goto
err_request
;
operation
->
response_payload
=
operation
->
response
->
transfer_buffer
+
sizeof
(
struct
gb_operation_msg_hdr
);
}
INIT_WORK
(
&
operation
->
recv_work
,
gb_operation_recv_work
);
...
...
@@ -290,7 +322,7 @@ struct gb_operation *gb_operation_create(struct gb_connection *connection,
return
operation
;
err_request:
g
reybus_free_gbuf
(
operation
->
request
);
g
b_operation_message_exit
(
&
operation
->
request
);
err_cache:
kmem_cache_free
(
gb_operation_cache
,
operation
);
...
...
@@ -311,8 +343,8 @@ static void _gb_operation_destroy(struct kref *kref)
list_del
(
&
operation
->
links
);
spin_unlock_irq
(
&
gb_operations_lock
);
g
reybus_free_gbuf
(
operation
->
response
);
g
reybus_free_gbuf
(
operation
->
request
);
g
b_operation_message_exit
(
&
operation
->
response
);
g
b_operation_message_exit
(
&
operation
->
request
);
kmem_cache_free
(
gb_operation_cache
,
operation
);
}
...
...
@@ -349,7 +381,7 @@ int gb_operation_request_send(struct gb_operation *operation,
*/
operation
->
callback
=
callback
;
gb_pending_operation_insert
(
operation
);
ret
=
greybus_submit_gbuf
(
operation
->
request
,
GFP_KERNEL
);
ret
=
greybus_submit_gbuf
(
&
operation
->
request
.
gbuf
,
GFP_KERNEL
);
if
(
ret
)
return
ret
;
...
...
@@ -414,7 +446,7 @@ void gb_connection_operation_recv(struct gb_connection *connection,
}
cancel_delayed_work
(
&
operation
->
timeout_work
);
gb_pending_operation_remove
(
operation
);
gbuf
=
operation
->
response
;
gbuf
=
&
operation
->
response
.
gbuf
;
if
(
size
>
gbuf
->
transfer_buffer_length
)
{
operation
->
result
=
GB_OP_OVERFLOW
;
gb_connection_err
(
connection
,
"recv buffer too small"
);
...
...
@@ -429,7 +461,7 @@ void gb_connection_operation_recv(struct gb_connection *connection,
gb_connection_err
(
connection
,
"can't create operation"
);
return
;
}
gbuf
=
operation
->
request
;
gbuf
=
&
operation
->
request
.
gbuf
;
}
memcpy
(
gbuf
->
transfer_buffer
,
data
,
msg_size
);
...
...
@@ -444,9 +476,9 @@ void gb_connection_operation_recv(struct gb_connection *connection,
void
gb_operation_cancel
(
struct
gb_operation
*
operation
)
{
operation
->
canceled
=
true
;
greybus_kill_gbuf
(
operation
->
request
);
if
(
operation
->
response
)
greybus_kill_gbuf
(
operation
->
response
);
greybus_kill_gbuf
(
&
operation
->
request
.
gbuf
);
if
(
operation
->
response
.
gbuf
.
transfer_buffer
)
greybus_kill_gbuf
(
&
operation
->
response
.
gbuf
);
}
int
gb_operation_init
(
void
)
...
...
drivers/staging/greybus/operation.h
View file @
025742cc
...
...
@@ -11,6 +11,8 @@
#include <linux/completion.h>
struct
gb_operation
;
enum
gb_operation_status
{
GB_OP_SUCCESS
=
0
,
GB_OP_INVALID
=
1
,
...
...
@@ -22,6 +24,23 @@ enum gb_operation_status {
GB_OP_TIMEOUT
=
0xff
,
};
struct
gbuf
{
struct
greybus_host_device
*
hd
;
u16
dest_cport_id
;
/* Destination CPort id */
int
status
;
void
*
transfer_buffer
;
u32
transfer_buffer_length
;
void
*
hcd_data
;
/* for the HCD to track the gbuf */
};
struct
gb_message
{
void
*
payload
;
struct
gb_operation
*
operation
;
struct
gbuf
gbuf
;
};
/*
* A Greybus operation is a remote procedure call performed over a
* connection between the AP and a function on Greybus module.
...
...
@@ -50,12 +69,11 @@ enum gb_operation_status {
* is guaranteed to be 64-bit aligned.
* XXX and callback?
*/
struct
gb_operation
;
typedef
void
(
*
gb_operation_callback
)(
struct
gb_operation
*
);
struct
gb_operation
{
struct
gb_connection
*
connection
;
struct
gb
uf
*
request
;
struct
gb
uf
*
response
;
struct
gb
_message
request
;
struct
gb
_message
response
;
u16
id
;
bool
canceled
;
...
...
@@ -67,10 +85,6 @@ struct gb_operation {
struct
kref
kref
;
struct
list_head
links
;
/* connection->{operations,pending} */
/* These are what's used by caller */
void
*
request_payload
;
void
*
response_payload
;
};
void
gb_connection_operation_recv
(
struct
gb_connection
*
connection
,
...
...
drivers/staging/greybus/pwm-gb.c
View file @
025742cc
...
...
@@ -110,7 +110,7 @@ static int gb_pwm_proto_version_operation(struct gb_pwm_chip *pwmc)
goto
out
;
}
response
=
operation
->
response
_
payload
;
response
=
operation
->
response
.
payload
;
if
(
response
->
status
)
{
gb_connection_err
(
connection
,
"version response %hhu"
,
response
->
status
);
...
...
@@ -151,7 +151,7 @@ static int gb_pwm_count_operation(struct gb_pwm_chip *pwmc)
goto
out
;
}
response
=
operation
->
response
_
payload
;
response
=
operation
->
response
.
payload
;
if
(
response
->
status
)
{
gb_connection_err
(
connection
,
"pwm count response %hhu"
,
response
->
status
);
...
...
@@ -181,7 +181,7 @@ static int gb_pwm_activate_operation(struct gb_pwm_chip *pwmc,
sizeof
(
*
request
),
sizeof
(
*
response
));
if
(
!
operation
)
return
-
ENOMEM
;
request
=
operation
->
request
_
payload
;
request
=
operation
->
request
.
payload
;
request
->
which
=
which
;
/* Synchronous operation--no callback */
...
...
@@ -191,7 +191,7 @@ static int gb_pwm_activate_operation(struct gb_pwm_chip *pwmc,
goto
out
;
}
response
=
operation
->
response
_
payload
;
response
=
operation
->
response
.
payload
;
if
(
response
->
status
)
{
gb_connection_err
(
connection
,
"activate response %hhu"
,
response
->
status
);
...
...
@@ -220,7 +220,7 @@ static int gb_pwm_deactivate_operation(struct gb_pwm_chip *pwmc,
sizeof
(
*
request
),
sizeof
(
*
response
));
if
(
!
operation
)
return
-
ENOMEM
;
request
=
operation
->
request
_
payload
;
request
=
operation
->
request
.
payload
;
request
->
which
=
which
;
/* Synchronous operation--no callback */
...
...
@@ -230,7 +230,7 @@ static int gb_pwm_deactivate_operation(struct gb_pwm_chip *pwmc,
goto
out
;
}
response
=
operation
->
response
_
payload
;
response
=
operation
->
response
.
payload
;
if
(
response
->
status
)
{
gb_connection_err
(
connection
,
"deactivate response %hhu"
,
response
->
status
);
...
...
@@ -258,7 +258,7 @@ static int gb_pwm_config_operation(struct gb_pwm_chip *pwmc,
sizeof
(
*
request
),
sizeof
(
*
response
));
if
(
!
operation
)
return
-
ENOMEM
;
request
=
operation
->
request
_
payload
;
request
=
operation
->
request
.
payload
;
request
->
which
=
which
;
request
->
duty
=
duty
;
request
->
period
=
period
;
...
...
@@ -270,7 +270,7 @@ static int gb_pwm_config_operation(struct gb_pwm_chip *pwmc,
goto
out
;
}
response
=
operation
->
response
_
payload
;
response
=
operation
->
response
.
payload
;
if
(
response
->
status
)
{
gb_connection_err
(
connection
,
"config response %hhu"
,
response
->
status
);
...
...
@@ -299,7 +299,7 @@ static int gb_pwm_set_polarity_operation(struct gb_pwm_chip *pwmc,
sizeof
(
*
request
),
sizeof
(
*
response
));
if
(
!
operation
)
return
-
ENOMEM
;
request
=
operation
->
request
_
payload
;
request
=
operation
->
request
.
payload
;
request
->
which
=
which
;
request
->
polarity
=
polarity
;
...
...
@@ -310,7 +310,7 @@ static int gb_pwm_set_polarity_operation(struct gb_pwm_chip *pwmc,
goto
out
;
}
response
=
operation
->
response
_
payload
;
response
=
operation
->
response
.
payload
;
if
(
response
->
status
)
{
gb_connection_err
(
connection
,
"set polarity response %hhu"
,
response
->
status
);
...
...
@@ -339,7 +339,7 @@ static int gb_pwm_enable_operation(struct gb_pwm_chip *pwmc,
sizeof
(
*
request
),
sizeof
(
*
response
));
if
(
!
operation
)
return
-
ENOMEM
;
request
=
operation
->
request
_
payload
;
request
=
operation
->
request
.
payload
;
request
->
which
=
which
;
/* Synchronous operation--no callback */
...
...
@@ -349,7 +349,7 @@ static int gb_pwm_enable_operation(struct gb_pwm_chip *pwmc,
goto
out
;
}
response
=
operation
->
response
_
payload
;
response
=
operation
->
response
.
payload
;
if
(
response
->
status
)
{
gb_connection_err
(
connection
,
"enable response %hhu"
,
response
->
status
);
...
...
@@ -378,7 +378,7 @@ static int gb_pwm_disable_operation(struct gb_pwm_chip *pwmc,
sizeof
(
*
request
),
sizeof
(
*
response
));
if
(
!
operation
)
return
-
ENOMEM
;
request
=
operation
->
request
_
payload
;
request
=
operation
->
request
.
payload
;
request
->
which
=
which
;
/* Synchronous operation--no callback */
...
...
@@ -388,7 +388,7 @@ static int gb_pwm_disable_operation(struct gb_pwm_chip *pwmc,
goto
out
;
}
response
=
operation
->
response
_
payload
;
response
=
operation
->
response
.
payload
;
if
(
response
->
status
)
{
gb_connection_err
(
connection
,
"disable response %hhu"
,
response
->
status
);
...
...
drivers/staging/greybus/uart-gb.c
View file @
025742cc
...
...
@@ -229,7 +229,7 @@ static int send_data(struct gb_tty *tty, u16 size, const u8 *data)
sizeof
(
*
response
));
if
(
!
operation
)
return
-
ENOMEM
;
request
=
operation
->
request
_
payload
;
request
=
operation
->
request
.
payload
;
request
->
size
=
cpu_to_le16
(
size
);
memcpy
(
&
request
->
data
[
0
],
data
,
size
);
...
...
@@ -241,7 +241,7 @@ static int send_data(struct gb_tty *tty, u16 size, const u8 *data)
goto
out
;
}
response
=
operation
->
response
_
payload
;
response
=
operation
->
response
.
payload
;
if
(
response
->
status
)
{
gb_connection_err
(
connection
,
"send data response %hhu"
,
response
->
status
);
...
...
@@ -267,7 +267,7 @@ static int send_line_coding(struct gb_tty *tty,
sizeof
(
*
response
));
if
(
!
operation
)
return
-
ENOMEM
;
request
=
operation
->
request
_
payload
;
request
=
operation
->
request
.
payload
;
memcpy
(
&
request
->
line_coding
,
line_coding
,
sizeof
(
*
line_coding
));
/* Synchronous operation--no callback */
...
...
@@ -278,7 +278,7 @@ static int send_line_coding(struct gb_tty *tty,
goto
out
;
}
response
=
operation
->
response
_
payload
;
response
=
operation
->
response
.
payload
;
if
(
response
->
status
)
{
gb_connection_err
(
connection
,
"send line coding response %hhu"
,
response
->
status
);
...
...
@@ -304,7 +304,7 @@ static int send_control(struct gb_tty *tty, u16 control)
sizeof
(
*
response
));
if
(
!
operation
)
return
-
ENOMEM
;
request
=
operation
->
request
_
payload
;
request
=
operation
->
request
.
payload
;
request
->
control
=
cpu_to_le16
(
control
);
/* Synchronous operation--no callback */
...
...
@@ -315,7 +315,7 @@ static int send_control(struct gb_tty *tty, u16 control)
goto
out
;
}
response
=
operation
->
response
_
payload
;
response
=
operation
->
response
.
payload
;
if
(
response
->
status
)
{
gb_connection_err
(
connection
,
"send control response %hhu"
,
response
->
status
);
...
...
@@ -345,7 +345,7 @@ static int send_break(struct gb_tty *tty, u8 state)
sizeof
(
*
response
));
if
(
!
operation
)
return
-
ENOMEM
;
request
=
operation
->
request
_
payload
;
request
=
operation
->
request
.
payload
;
request
->
state
=
state
;
/* Synchronous operation--no callback */
...
...
@@ -356,7 +356,7 @@ static int send_break(struct gb_tty *tty, u8 state)
goto
out
;
}
response
=
operation
->
response
_
payload
;
response
=
operation
->
response
.
payload
;
if
(
response
->
status
)
{
gb_connection_err
(
connection
,
"send break response %hhu"
,
response
->
status
);
...
...
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