User space doesn't break anymore with new greybus modules and its time
to make bootrom a separate module.
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
The "busy" SVC result codes are gone from the spec. Delete them.
Testing Done: compile.
Signed-off-by: Marti Bolivar <mbolivar@leaflabs.com>
Reviewed-by: Alex Elder <elder@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
pwm_is_enabled() wasn't enabled by v4.2-rc1, but it was based of
v4.2-rc1. It was actually first included in v4.3.
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
Add support for greybus debug data format.
Greybus debug data format id is 0x42.
Signed-off-by: Gjorgji Rosikopulos <grosikopulos@mm-sol.com>
Acked-by: Laurent Pinchart <laurent.pinchart@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
Core disables all connections for bundles whose interface is already
gone in order to avoid unnecessary operation timeouts during driver
disconnect.
This isn't needed for offloaded connections (as the AP can not send
requests over such connections), and in fact must not be done since only
the bundle driver currently knows how to disable I/O on such connections
in a class-specific way (this may eventually be handled by core though).
Also add comment about why connection are disabled early on forced
disconnect.
Testing Done: Tested on EVT2.
Reported-by: Mark Greer <mgreer@animalcreek.com>
Signed-off-by: Johan Hovold <johan@hovoldconsulting.com>
Tested-by: Mark Greer <mgreer@animalcreek.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
I posted this once before but it got rejected for fear it would
not be clear which messages were related to Greybus.
Every trace event currently defined for Greybus is recorded in a
function whose name begins with "gb_". Every trace event reported
in /sys/kernel/debug/tracing/trace includes the name of the function
in which the event was recorded.
Get rid of the "greybus: " prefix in all of the Greybus trace
events. It just takes up precious space and is not actually
helpful. Anyone actually enabling individual trace events should
know enough about what they're doing to recognize which ones
are being enabled.
Signed-off-by: Alex Elder <elder@linaro.org>
Reviewed-by: Viresh Kumar <viresh.kumar@linaro.org>
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
The symbol PWMF_ENABLED is defined via an enum, which is not defined
at the time the preprocessor passes through "kernel_ver.h". So we
can't use it in an #if statement expression.
Use the Linux kernel version instead.
Change-Id: Id427224b1dfecfd886fcdae89c4bcf711b616439
Signed-off-by: Alex Elder <elder@linaro.org>
AP should check for Greybus SVC Protocol Operation Status to determine if the
operation was successfully completed by the SVC
Testing Done:
- Successfully getting the rail names in the pwrmon_dummy sandbox branch
Signed-off-by: David Lin <dtwlin@google.com>
Reviewed-by: Viresh Kumar <viresh.kumar@linaro.org>
Reviewed-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
In the 4.7-rc1 kernel release, PWMF_ENABLED is removed and
pwm_is_enabled() is the correct way to test if a pwm device is enabled,
so provide a version of that function that will work on all older
kernels and change the pwm.c driver to use it so that it will work on
newer kernels as well.
Tested:
Tree now builds successfully against 3.14.y, 4.4.y, 4.5.y,
4.6.y, and 4.7-rc2 kernels
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
Reviewed-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
In case of audio mgmt connection failure, GB requests would fail giving
an error message within the driver and reporting error. However there is
no error handling in above HAL and it'll keep on triggering similar
request via GB codec driver. This may overflood serial console. In one
of the instance it locked CPU for >10sec and caused a watchdog bite.
Thus ratelimit those error messages.
Testing Done: compile tested
Signed-off-by: Vaibhav Agarwal <vaibhav.agarwal@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This patch makes a debugfs entry in
/sys/kernel/debug/greybus/X-svc/frame-ktime that generates a TimeSync ping
event to the system and then subsequently presents that data to user-space
as a ktime/timespec clock-monotonic value rather than as a raw frame-time,
to aid humans in debugging and understanding frame-time and to provide an
example of the converting a frame-time to timespec/ktime to other
developers.
Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Acked-by: Alex Elder <elder@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This patch adds gb_timesync_to_timespec_by_svc() and
gb_timesync_to_timespec_by_interface() respectively. These routines will
convert from a given FrameTime to a ktime/timespec within an envelope of
about 17 seconds. The purpose of this routine is to enable reporting of a
FrameTime from a Module such as a Camera Module and to allow the AP to
then convert this timestamp into a Linux-native timestamp such as ktime.
This is useful and required in the v4l layer.
At 19.2MHz the accuracy of this conversion is about .3 femtoseconds per
count, which means at a 1 second offset from the reference the cumulative
error is about 1.59 nanoseconds. 1.59 nanoseconds is still less than 1
clock's worth of error @ 19.2MHz where each clock is 52.0833~ nanoseconds.
We're aiming for a maximum error rate of 30 nanoseconds which means at the
clock rate we are running at, the conversion from a FrameTime to a Linux
ktime/timespec can be plus-or-minus about 17 seconds from the reference
FrameTime/ktime pair before the routine will refuse to convert.
A realistic use-case for this routine is envisaged to be
- Greybus message received
- Some processing takes place - taking milliseconds
- Call into this routine is made
- Actual time between event in Module and conversion in AP < 1 second
- Error rate in conversion at 1.59 nanoseconds is less than 1 clock
@ 19.2MHz
This routine is not designed to allow for conversions for events with
large gaps between the event time and the current reference time for
conversion. Since FrameTime can be a very large integer we cannot convert
an arbitrarily large FrameTime to ktime, the feeling and objective here is
to make an over-provisioned envelope that in practical terms can never be
exceeded by expected use-cases. To convert longer gaps more work would have
to be done but ultimately some limit needs to be imposed and right now 0.3
femotseconds per clock on MSM8994 is both accurate and generous.
Adds:
- timesync.c::gb_timesync_frame_time_to_timespec_by_svc(
struct gb_svc *,
u64 frame_time,
struct timespec *ts)
- gb_svc is a pointer to a standard greybus SVC data structure
- frame_time is a system FrameTime.
- ts is an output parameter which represents the converted FrameTime
as a CLOCK_MONOTONIC timespec value.
- Returns 0 on success or a negative number indicating the type of
error on failure.
- timesync.c::gb_timesync_frame_time_to_timespec_by_interface(
struct gb_interface *,
u64 frame_time,
struct timespec *ts)
- gb_svc is a pointer to a standard greybus Interface data structure
- frame_time is a system FrameTime.
- ts is an output parameter which represents the converted FrameTime
as a CLOCK_MONOTONIC timespec value.
- Returns 0 on success or a negative number indicating the type of
error on failure.
Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Acked-by: Alex Elder <elder@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This patch adds a tracepoint to the TimeSync ISR, the purpose of which is
to indicate a TimeSync event has happened. This tracepoint can be enabled
by issuing the following command:
echo 1 > /sys/kernel/debug/tracing/events/greybus/gb_timesync_irq/enable
Synchronization looks like this:
TIMESTAMP FUNCTION
| |
147.865788: gb_timesync_irq: strobe 1/4 frame-time 2910076529
147.866781: gb_timesync_irq: strobe 2/4 frame-time 2910095689
147.867777: gb_timesync_irq: strobe 3/4 frame-time 2910114820
147.868791: gb_timesync_irq: strobe 4/4 frame-time 2910134038
A ping can be triggered like this:
cat /sys/kernel/debug/greybus/frame-time
And that ping looks like this:
TIMESTAMP FUNCTION
| |
147.934678: gb_timesync_irq: ping 4/4 frame-time 2911380356
169.280551: gb_timesync_irq: ping 4/4 frame-time 3321221069
Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Reviewed-by: Vaibhav Hiremath <vaibhav.hiremath@linaro.org>
Acked-by: Alex Elder <elder@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
TimeSync needs to bind into Greybus in a few places.
- core.c
To initialize its internal state and tear-down its internal state.
To schedule a timesync to a newly added Bundle after probe() completes.
- svc.c
To get access to the SVC and enable/disable timesync as well as
extracting the authoritative time from the SVC to subsequently
disseminate to other entities in the system.
- interface.c
To get access to an Interface in order to inform APBx of timesync
enable/disable and authoritative operations.
This patch adds those bindings into Greybus core.
Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Reviewed-by: Vaibhav Hiremath <vaibhav.hiremath@linaro.org>
Acked-by: Alex Elder <elder@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This patch adds the core timesync functionality.
0. arche-platform.c/arche-apb-ctrl.c
Modifies the platform layer to hook the incoming TIME_SYNC signal up to
the timesync strobe IRQ handler. If the arche-platform driver can't
satisfy the request for the wake-detect line, it will return -EAGAIN and
the calling work-queue must reschedule the attempt to get exclusive
access to the wake-detect pin logic. A private data field is added to
the arche-platform driver to enable passing of a timesync pointer to the
ISR responsible for synchronizing time.
1. timesync.c
A new file added which contains all of the logic associated with sending
greybus commands to SVC, APBx or Interfaces to enable, disable and
disseminate timing information.
2. timesync_platform.c
Any platform/arch specific code goes into timesync_platform.c.
Originally the idea was to keep the x86 and ARM arch dependencies in a
timesync_platform_arch.c file - however with further refinement that's
currently not necessary however just-in-case it becomes necessary to
resuscitate arch or platform specific methods for accessing timer
resources that access shouldn't be part of the core timesync.c logic and
so for the moment we access these timer resources through a thin access
layer in timesync_platform.c. Expect this to go away long term ideally.
Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Acked-by: Alex Elder <elder@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
Reporting DISCONNECT event immediately on module removal causes
race condition while re-populating mixer controls by above HAL. The
original intent was to avoid any (invalid) mixer control modification
request from above layer.
Ideally, it should report 'MODULE_NOT_READY' on module plug-out and
DISCONNECT after resource cleanup. This would involve changes in GB
Audio manager and HAL layer.
Since we already have a plan to remove GB Audio manager, I'm making this
change in GB codec driver to avoid any race condition. Also, codec
driver already ensures mixer control modifcations for disconnected
modules are not triggered to AP Bridge audio FW & reported invalid.
Signed-off-by: Vaibhav Agarwal <vaibhav.agarwal@linaro.org>
Reviewed-by: Mark Greer <mgreer@animalcreek.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
Added warning message in find_gb_module(). This will help to identify
invalid mixer control/widget modification triggered from above layer.
Signed-off-by: Vaibhav Agarwal <vaibhav.agarwal@linaro.org>
Reviewed-by: Mark Greer <mgreer@animalcreek.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
The original message trace events were defined long before the
recent tracing updates. It records information that's not
really directly related to a message. Change the information
recorded and reported for message events to just be the content
of the message header.
Signed-off-by: Alex Elder <elder@linaro.org>
Reviewed-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
Bryan reports he used certain message traces to determine when time
sync messages transit the boundary between the Greybus core and the
host device. This patch adds two trace events--one a message event
for outbound messages (because it indicates its operation and its
destination), and one host device event for incoming messages
(because message information isn't available as early as desired).
These events are being created to allow the same sort of analysis
of messages without having to store extra information for every
message trace. (The next patch changes the information a message
trace records.)
Signed-off-by: Alex Elder <elder@linaro.org>
Reviewed-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
Define a new gb_connection trace point event class, used to trace
events associated with the connection abstraction. Define four basic
trace events for this--creation, drop of last reference, and when
adding or dropping any other reference. There are certainly
more events that we might want to add, but aim is to just get the
basic framework in place.
Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
Define a new gb_bundle trace point event class, used to trace events
associated with the bundle abstraction. Define four basic trace
points for this--creation time, drop of last reference, before
adding it to its interface and when removed when its interface
is destroyed.
Signed-off-by: Alex Elder <elder@linaro.org>
Reviewed-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
Add the value of an interface's mode_switch field to the information
tracked and reported for tracing.
Signed-off-by: Alex Elder <elder@linaro.org>
Reviewed-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
Most abstractions to be traced will have a sort of "parent" object
it is associated with, and an identifier for that parent is stored
with the as trace event data. For example, the parent of a message
is the operation it's a part of, and the parent of an operation is
the connection it uses.
We'll arrange to define that parent id first in all events. Most
abstractions already do this. Move an interface's module id so it's
defined and assigned first. The message traces are going to be
changed soon, so leave that one alone.
Signed-off-by: Alex Elder <elder@linaro.org>
Reviewed-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
A module's num_interfaces field is included in the data to be
recorded for tracing, but it's never assigned or reported. Fix
its type to be size_t, to match its definition in the gb_module
structure.
Also correct a format length modifier used for a host device's
num_cports field.
Signed-off-by: Alex Elder <elder@linaro.org>
Reviewed-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
Move the definition of the module trace events below those for the
interface. We'll define them in an order that represents a sort of
layering of the abstractions (note not all of these are defined yet):
message
operation
connection
bundle
interface
module
host device
Other tracepoints (like perhaps some tied to timesync) will go at the
beginning or end.
Signed-off-by: Alex Elder <elder@linaro.org>
Reviewed-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
The type of the gb_host_device num_cports field is size_t. Correct
the num_cports data recorded with a host device event so its type
matches that; fix the format length modifier used for it as well.
Signed-off-by: Alex Elder <elder@linaro.org>
Reviewed-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
Define a bundle ID that means "no bundle". This will be used for
tracing connection events during the portion of a connection's
lifetime when it has no bundle associated with it. Don't allow
any bundle to be created using that ID.
Signed-off-by: Alex Elder <elder@linaro.org>
Reviewed-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
Some of the trace buffer fields were defined as Booleans. This
leads to two problems reported by "make check":
- the __field() macro (or some descendent macro) performs
a sizeof(bool) operation, which results in a warning
- The TP_printk() macro, which specifies a printf() style
format string, produces a warning when one attempts to
format a Boolean as an integer.
Fix both problems implicitly converting Boolean values from the data
structures into integers in the trace buffer.
Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
In explanation:
The main idea for implementing reference counting is to not block exit
until any other modules are in use. Camera responsibility is to handle
properly any additional calls after camera exit and that what this
patch is doing:
1. Free camera module when reference count is zero.
2. After camera cleanup handle properly any additional ongoing
transaction. Return error if connection is destroyed.
Signed-off-by: Evgeniy Borisov <eborisov@mm-sol.com>
Reviewed-by: Gjorgji Rosikopulos <grosikopulos@mm-sol.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
Mode switch takes just over a second to complete and the current timeout
of one second isn't sufficient.
Mode-switch logs from EVT 1.5:
[ 56.709082] gb-firmware 1-3.3.1: Requested firmware package 'ara_00000126_00001002_fffe0001_ff980067_03.tftf'
[ 57.003968] gb_control_mode_switch_operation: 176
[ 58.041616] greybus 1-3.3: mode switch detected
Increase the timeout to two seconds.
Tested with EVT 1.5 with gpbridge-test module.
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Tested-by: Karthik Ravi Shankar <karthikrs@google.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
The operation layer allows only the 'core' operations on a connection,
which is in its 'disconnecting' state.
Mode switch is sent at the very end of interface-disable sequence, and
the control connection is already in its 'disconnecting' state at that
time. And so gb_operation_get_active() always fail with error -ENOTCONN.
The operation core already has support for such 'core' operations, just
that we were missing the needed flag while creating the mode switch
operation.
Fix that.
Tested on EVT 1.5 with gpbridge-test module.
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Tested-by: Karthik Ravi Shankar <karthikrs@google.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This is the last step to required to finish the mode switch story. That
is, call the hook provided by Interface layer to accomplish mode switch.
Tested on EVT 1.5 with gpbridge-test module.
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Tested-by: Karthik Ravi Shankar <karthikrs@google.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
We should be using the generic version handling at bundle level, instead
of at protocol level for bridged PHY devices as well.
The bundle version handling is already in place, though it is *not* used
today as we haven't bumped the version of control protocol yet.
Remove protocol specific handling for bridged PHY devices.
Tested on EVT 1.5 with gpbridge-test module. No nuttx changes are
required with this.
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Reviewed-by: Johan Hovold <johan@hovoldconsulting.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
We don't use these anymore. Drop them.
Note that some macro's specific to bridged PHY devices aren't removed in
the patch, as gbsim will break otherwise. They will be removed
separately.
Compile tested.
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
We should try to wait until all credits are accounted
for before returning from shutdown.
For this purpose add a helper function that will
wait on completion, and call it form the shutdown.
This helper will also be useful when "wait until sent" is
implemented.
Signed-off-by: Axel Haslam <ahaslam@baylibre.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
Data may be held pening in the hardware because of flow
control mechanisms. When the port is closed, we need to flush
all data that was not sent.
For this, use the greybus message GB_UART_TYPE_FLUSH_FIFOS
which will flush all data queued on the module but not
yet sent on the data line.
Suggested-by: Johan Hovold <johan@hovoldconsulting.com>
Signed-off-by: Axel Haslam <ahaslam@baylibre.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
To avoid polling the firmware for space, a credit based system
is implemented.
The host will keep track of how many credits (bytes) it has
sent to the firmware, and stop sending data when the quota
is filled.
The host will be informed that the firmware has more
room for data when it handles the receive_credits request
message from the firmware, and will continue to write data
as credits become available.
The firmware and the host may implement an algorithm to aggregate
credits, and avoid extra greybus traffic.
Suggested-by: Johan Hovold <johan@hovoldconsulting.com>
Signed-off-by: Axel Haslam <ahaslam@baylibre.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
The firmware now buffers data instead of blocking while the transfer
is sent, and the write operation cannot sleep.
Instead of using gb_transfer_sync (which sleeps) in the write callback,
buffer data in a fifo and send it from from a work queue.
The write_room callback will will report 1 byte less that what is really
available in the fifo, to leave space for extra characters that may
be added by the tty layer.
Signed-off-by: Axel Haslam <ahaslam@baylibre.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
Dtr_dts allows the tty layer to set the flow control lines
to the correct state during open and close.
Note that locking for newctrl is missing throughout the
driver and will be addressed on a separate patch.
Suggested-and-reviewed-by: Johan Hovold <johan@hovoldconsulting.com>
Signed-off-by: Axel Haslam <ahaslam@baylibre.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
Handle the CRTSCTS flag in set_termios, so that auto
flow control can be turned off. For this, add a new flag
in the line coding request specifically for this purpose.
Reviewed-by: Johan Hovold <johan@hovoldconsulting.com>
Signed-off-by: Axel Haslam <ahaslam@baylibre.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
The recently added gb_hd_release tracepoint was added to the wrong
function.
Signed-off-by: Johan Hovold <johan@hovoldconsulting.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
Fix some whitespace issues introduced by the recent tracepoint changes.
Signed-off-by: Johan Hovold <johan@hovoldconsulting.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
Now that firmware has made the switch to the new interface boot
sequence, we can remove support for the deprecated hotplug and
hot-unplug operations.
Reviewed-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Johan Hovold <johan@hovoldconsulting.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
Add a generic interface for bundle drivers to use to request that a
mode switch is carried out on its behalf.
Mode switching involves tearing down all connections to an interface,
sending a unidirectional mode-switch request, and waiting for a mailbox
event that triggers deferred control connection reset and re-enumeration
of the interface. In case of a timeout waiting for the interface mailbox
event, or on other errors, the interface is powered off.
All of this needs to be done by core from work-queue context in order
not to block incoming SVC requests and bundle-device tear down. Care
must also be taken to serialise against concurrent module removal events
and eject requests.
Special handling of legacy mode-switching is also added in order to
continue to support the ES3 bootrom.
Signed-off-by: Johan Hovold <johan@hovoldconsulting.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
Print an informative error message in case sending the mode-switch
request fails.
Signed-off-by: Johan Hovold <johan@hovoldconsulting.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>