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
nexedi
linux
Commits
2f2d2702
Commit
2f2d2702
authored
Jul 11, 2014
by
Russell King
Browse files
Options
Browse Files
Download
Plain Diff
Merge branches 'drm-devel' and 'component-for-driver' into armada-drm
parents
42e62ba7
7e435aad
b509cc80
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
252 additions
and
35 deletions
+252
-35
drivers/base/component.c
drivers/base/component.c
+157
-35
drivers/gpu/drm/Makefile
drivers/gpu/drm/Makefile
+1
-0
drivers/gpu/drm/drm_of.c
drivers/gpu/drm/drm_of.c
+67
-0
include/drm/drm_crtc.h
include/drm/drm_crtc.h
+2
-0
include/drm/drm_of.h
include/drm/drm_of.h
+18
-0
include/linux/component.h
include/linux/component.h
+7
-0
No files found.
drivers/base/component.c
View file @
2f2d2702
...
...
@@ -18,6 +18,15 @@
#include <linux/mutex.h>
#include <linux/slab.h>
struct
component_match
{
size_t
alloc
;
size_t
num
;
struct
{
void
*
data
;
int
(
*
fn
)(
struct
device
*
,
void
*
);
}
compare
[
0
];
};
struct
master
{
struct
list_head
node
;
struct
list_head
components
;
...
...
@@ -25,6 +34,7 @@ struct master {
const
struct
component_master_ops
*
ops
;
struct
device
*
dev
;
struct
component_match
*
match
;
};
struct
component
{
...
...
@@ -69,6 +79,11 @@ static void component_detach_master(struct master *master, struct component *c)
c
->
master
=
NULL
;
}
/*
* Add a component to a master, finding the component via the compare
* function and compare data. This is safe to call for duplicate matches
* and will not result in the same component being added multiple times.
*/
int
component_master_add_child
(
struct
master
*
master
,
int
(
*
compare
)(
struct
device
*
,
void
*
),
void
*
compare_data
)
{
...
...
@@ -76,11 +91,12 @@ int component_master_add_child(struct master *master,
int
ret
=
-
ENXIO
;
list_for_each_entry
(
c
,
&
component_list
,
node
)
{
if
(
c
->
master
)
if
(
c
->
master
&&
c
->
master
!=
master
)
continue
;
if
(
compare
(
c
->
dev
,
compare_data
))
{
component_attach_master
(
master
,
c
);
if
(
!
c
->
master
)
component_attach_master
(
master
,
c
);
ret
=
0
;
break
;
}
...
...
@@ -90,6 +106,34 @@ int component_master_add_child(struct master *master,
}
EXPORT_SYMBOL_GPL
(
component_master_add_child
);
static
int
find_components
(
struct
master
*
master
)
{
struct
component_match
*
match
=
master
->
match
;
size_t
i
;
int
ret
=
0
;
if
(
!
match
)
{
/*
* Search the list of components, looking for components that
* belong to this master, and attach them to the master.
*/
return
master
->
ops
->
add_components
(
master
->
dev
,
master
);
}
/*
* Scan the array of match functions and attach
* any components which are found to this master.
*/
for
(
i
=
0
;
i
<
match
->
num
;
i
++
)
{
ret
=
component_master_add_child
(
master
,
match
->
compare
[
i
].
fn
,
match
->
compare
[
i
].
data
);
if
(
ret
)
break
;
}
return
ret
;
}
/* Detach all attached components from this master */
static
void
master_remove_components
(
struct
master
*
master
)
{
...
...
@@ -113,44 +157,44 @@ static void master_remove_components(struct master *master)
static
int
try_to_bring_up_master
(
struct
master
*
master
,
struct
component
*
component
)
{
int
ret
=
0
;
int
ret
;
if
(
!
master
->
bound
)
{
/*
* Search the list of components, looking for components that
* belong to this master, and attach them to the master.
*/
if
(
master
->
ops
->
add_components
(
master
->
dev
,
master
))
{
/* Failed to find all components */
master_remove_components
(
master
);
ret
=
0
;
goto
out
;
}
if
(
master
->
bound
)
return
0
;
if
(
component
&&
component
->
master
!=
master
)
{
master_remove_components
(
master
);
ret
=
0
;
goto
out
;
}
/*
* Search the list of components, looking for components that
* belong to this master, and attach them to the master.
*/
if
(
find_components
(
master
))
{
/* Failed to find all components */
ret
=
0
;
goto
out
;
}
if
(
!
devres_open_group
(
master
->
dev
,
NULL
,
GFP_KERNEL
)
)
{
ret
=
-
ENOMEM
;
goto
out
;
}
if
(
component
&&
component
->
master
!=
master
)
{
ret
=
0
;
goto
out
;
}
/* Found all components */
ret
=
master
->
ops
->
bind
(
master
->
dev
);
if
(
ret
<
0
)
{
devres_release_group
(
master
->
dev
,
NULL
);
dev_info
(
master
->
dev
,
"master bind failed: %d
\n
"
,
ret
);
master_remove_components
(
master
);
goto
out
;
}
if
(
!
devres_open_group
(
master
->
dev
,
NULL
,
GFP_KERNEL
))
{
ret
=
-
ENOMEM
;
goto
out
;
}
master
->
bound
=
true
;
ret
=
1
;
/* Found all components */
ret
=
master
->
ops
->
bind
(
master
->
dev
);
if
(
ret
<
0
)
{
devres_release_group
(
master
->
dev
,
NULL
);
dev_info
(
master
->
dev
,
"master bind failed: %d
\n
"
,
ret
);
goto
out
;
}
master
->
bound
=
true
;
return
1
;
out:
master_remove_components
(
master
);
return
ret
;
}
...
...
@@ -180,18 +224,89 @@ static void take_down_master(struct master *master)
master_remove_components
(
master
);
}
int
component_master_add
(
struct
device
*
dev
,
const
struct
component_master_ops
*
ops
)
static
size_t
component_match_size
(
size_t
num
)
{
return
offsetof
(
struct
component_match
,
compare
[
num
]);
}
static
struct
component_match
*
component_match_realloc
(
struct
device
*
dev
,
struct
component_match
*
match
,
size_t
num
)
{
struct
component_match
*
new
;
if
(
match
&&
match
->
alloc
==
num
)
return
match
;
new
=
devm_kmalloc
(
dev
,
component_match_size
(
num
),
GFP_KERNEL
);
if
(
!
new
)
return
ERR_PTR
(
-
ENOMEM
);
if
(
match
)
{
memcpy
(
new
,
match
,
component_match_size
(
min
(
match
->
num
,
num
)));
devm_kfree
(
dev
,
match
);
}
else
{
new
->
num
=
0
;
}
new
->
alloc
=
num
;
return
new
;
}
/*
* Add a component to be matched.
*
* The match array is first created or extended if necessary.
*/
void
component_match_add
(
struct
device
*
dev
,
struct
component_match
**
matchptr
,
int
(
*
compare
)(
struct
device
*
,
void
*
),
void
*
compare_data
)
{
struct
component_match
*
match
=
*
matchptr
;
if
(
IS_ERR
(
match
))
return
;
if
(
!
match
||
match
->
num
==
match
->
alloc
)
{
size_t
new_size
=
match
?
match
->
alloc
+
16
:
15
;
match
=
component_match_realloc
(
dev
,
match
,
new_size
);
*
matchptr
=
match
;
if
(
IS_ERR
(
match
))
return
;
}
match
->
compare
[
match
->
num
].
fn
=
compare
;
match
->
compare
[
match
->
num
].
data
=
compare_data
;
match
->
num
++
;
}
EXPORT_SYMBOL
(
component_match_add
);
int
component_master_add_with_match
(
struct
device
*
dev
,
const
struct
component_master_ops
*
ops
,
struct
component_match
*
match
)
{
struct
master
*
master
;
int
ret
;
if
(
ops
->
add_components
&&
match
)
return
-
EINVAL
;
if
(
match
)
{
/* Reallocate the match array for its true size */
match
=
component_match_realloc
(
dev
,
match
,
match
->
num
);
if
(
IS_ERR
(
match
))
return
PTR_ERR
(
match
);
}
master
=
kzalloc
(
sizeof
(
*
master
),
GFP_KERNEL
);
if
(
!
master
)
return
-
ENOMEM
;
master
->
dev
=
dev
;
master
->
ops
=
ops
;
master
->
match
=
match
;
INIT_LIST_HEAD
(
&
master
->
components
);
/* Add to the list of available masters. */
...
...
@@ -209,6 +324,13 @@ int component_master_add(struct device *dev,
return
ret
<
0
?
ret
:
0
;
}
EXPORT_SYMBOL_GPL
(
component_master_add_with_match
);
int
component_master_add
(
struct
device
*
dev
,
const
struct
component_master_ops
*
ops
)
{
return
component_master_add_with_match
(
dev
,
ops
,
NULL
);
}
EXPORT_SYMBOL_GPL
(
component_master_add
);
void
component_master_del
(
struct
device
*
dev
,
...
...
drivers/gpu/drm/Makefile
View file @
2f2d2702
...
...
@@ -20,6 +20,7 @@ drm-$(CONFIG_COMPAT) += drm_ioc32.o
drm-$(CONFIG_DRM_GEM_CMA_HELPER)
+=
drm_gem_cma_helper.o
drm-$(CONFIG_PCI)
+=
ati_pcigart.o
drm-$(CONFIG_DRM_PANEL)
+=
drm_panel.o
drm-$(CONFIG_OF)
+=
drm_of.o
drm-usb-y
:=
drm_usb.o
...
...
drivers/gpu/drm/drm_of.c
0 → 100644
View file @
2f2d2702
#include <linux/export.h>
#include <linux/list.h>
#include <linux/of_graph.h>
#include <drm/drmP.h>
#include <drm/drm_crtc.h>
#include <drm/drm_of.h>
/**
* drm_crtc_port_mask - find the mask of a registered CRTC by port OF node
* @dev: DRM device
* @port: port OF node
*
* Given a port OF node, return the possible mask of the corresponding
* CRTC within a device's list of CRTCs. Returns zero if not found.
*/
static
uint32_t
drm_crtc_port_mask
(
struct
drm_device
*
dev
,
struct
device_node
*
port
)
{
unsigned
int
index
=
0
;
struct
drm_crtc
*
tmp
;
list_for_each_entry
(
tmp
,
&
dev
->
mode_config
.
crtc_list
,
head
)
{
if
(
tmp
->
port
==
port
)
return
1
<<
index
;
index
++
;
}
return
0
;
}
/**
* drm_of_find_possible_crtcs - find the possible CRTCs for an encoder port
* @dev: DRM device
* @port: encoder port to scan for endpoints
*
* Scan all endpoints attached to a port, locate their attached CRTCs,
* and generate the DRM mask of CRTCs which may be attached to this
* encoder.
*
* See Documentation/devicetree/bindings/graph.txt for the bindings.
*/
uint32_t
drm_of_find_possible_crtcs
(
struct
drm_device
*
dev
,
struct
device_node
*
port
)
{
struct
device_node
*
remote_port
,
*
ep
=
NULL
;
uint32_t
possible_crtcs
=
0
;
do
{
ep
=
of_graph_get_next_endpoint
(
port
,
ep
);
if
(
!
ep
)
break
;
remote_port
=
of_graph_get_remote_port
(
ep
);
if
(
!
remote_port
)
{
of_node_put
(
ep
);
return
0
;
}
possible_crtcs
|=
drm_crtc_port_mask
(
dev
,
remote_port
);
of_node_put
(
remote_port
);
}
while
(
1
);
return
possible_crtcs
;
}
EXPORT_SYMBOL
(
drm_of_find_possible_crtcs
);
include/drm/drm_crtc.h
View file @
2f2d2702
...
...
@@ -41,6 +41,7 @@ struct drm_framebuffer;
struct
drm_object_properties
;
struct
drm_file
;
struct
drm_clip_rect
;
struct
device_node
;
#define DRM_MODE_OBJECT_CRTC 0xcccccccc
#define DRM_MODE_OBJECT_CONNECTOR 0xc0c0c0c0
...
...
@@ -314,6 +315,7 @@ struct drm_crtc_funcs {
*/
struct
drm_crtc
{
struct
drm_device
*
dev
;
struct
device_node
*
port
;
struct
list_head
head
;
/**
...
...
include/drm/drm_of.h
0 → 100644
View file @
2f2d2702
#ifndef __DRM_OF_H__
#define __DRM_OF_H__
struct
drm_device
;
struct
device_node
;
#ifdef CONFIG_OF
extern
uint32_t
drm_of_find_possible_crtcs
(
struct
drm_device
*
dev
,
struct
device_node
*
port
);
#else
static
inline
uint32_t
drm_of_find_possible_crtcs
(
struct
drm_device
*
dev
,
struct
device_node
*
port
)
{
return
0
;
}
#endif
#endif
/* __DRM_OF_H__ */
include/linux/component.h
View file @
2f2d2702
...
...
@@ -29,4 +29,11 @@ void component_master_del(struct device *,
int
component_master_add_child
(
struct
master
*
master
,
int
(
*
compare
)(
struct
device
*
,
void
*
),
void
*
compare_data
);
struct
component_match
;
int
component_master_add_with_match
(
struct
device
*
,
const
struct
component_master_ops
*
,
struct
component_match
*
);
void
component_match_add
(
struct
device
*
,
struct
component_match
**
,
int
(
*
compare
)(
struct
device
*
,
void
*
),
void
*
compare_data
);
#endif
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