11
11
12
12
#include "common.h"
13
13
14
+ /*
15
+ * 82c0d13a-78c5-4244-9bb1-eb8b539a8d11
16
+ * This _DSM GUID allows controlling the sensor clk when it is not controlled
17
+ * through a GPIO.
18
+ */
19
+ static const guid_t img_clk_guid =
20
+ GUID_INIT (0x82c0d13a , 0x78c5 , 0x4244 ,
21
+ 0x9b , 0xb1 , 0xeb , 0x8b , 0x53 , 0x9a , 0x8d , 0x11 );
22
+
23
+ static void skl_int3472_enable_clk (struct int3472_clock * clk , int enable )
24
+ {
25
+ struct int3472_discrete_device * int3472 = to_int3472_device (clk );
26
+ union acpi_object args [3 ];
27
+ union acpi_object argv4 ;
28
+
29
+ if (clk -> ena_gpio ) {
30
+ gpiod_set_value_cansleep (clk -> ena_gpio , enable );
31
+ return ;
32
+ }
33
+
34
+ args [0 ].integer .type = ACPI_TYPE_INTEGER ;
35
+ args [0 ].integer .value = clk -> imgclk_index ;
36
+ args [1 ].integer .type = ACPI_TYPE_INTEGER ;
37
+ args [1 ].integer .value = enable ;
38
+ args [2 ].integer .type = ACPI_TYPE_INTEGER ;
39
+ args [2 ].integer .value = 1 ;
40
+
41
+ argv4 .type = ACPI_TYPE_PACKAGE ;
42
+ argv4 .package .count = 3 ;
43
+ argv4 .package .elements = args ;
44
+
45
+ acpi_evaluate_dsm (acpi_device_handle (int3472 -> adev ), & img_clk_guid ,
46
+ 0 , 1 , & argv4 );
47
+ }
48
+
14
49
/*
15
50
* The regulators have to have .ops to be valid, but the only ops we actually
16
51
* support are .enable and .disable which are handled via .ena_gpiod. Pass an
@@ -20,17 +55,13 @@ static const struct regulator_ops int3472_gpio_regulator_ops;
20
55
21
56
static int skl_int3472_clk_prepare (struct clk_hw * hw )
22
57
{
23
- struct int3472_gpio_clock * clk = to_int3472_clk (hw );
24
-
25
- gpiod_set_value_cansleep (clk -> ena_gpio , 1 );
58
+ skl_int3472_enable_clk (to_int3472_clk (hw ), 1 );
26
59
return 0 ;
27
60
}
28
61
29
62
static void skl_int3472_clk_unprepare (struct clk_hw * hw )
30
63
{
31
- struct int3472_gpio_clock * clk = to_int3472_clk (hw );
32
-
33
- gpiod_set_value_cansleep (clk -> ena_gpio , 0 );
64
+ skl_int3472_enable_clk (to_int3472_clk (hw ), 0 );
34
65
}
35
66
36
67
static int skl_int3472_clk_enable (struct clk_hw * hw )
@@ -73,7 +104,7 @@ static unsigned int skl_int3472_get_clk_frequency(struct int3472_discrete_device
73
104
static unsigned long skl_int3472_clk_recalc_rate (struct clk_hw * hw ,
74
105
unsigned long parent_rate )
75
106
{
76
- struct int3472_gpio_clock * clk = to_int3472_clk (hw );
107
+ struct int3472_clock * clk = to_int3472_clk (hw );
77
108
78
109
return clk -> frequency ;
79
110
}
@@ -86,8 +117,51 @@ static const struct clk_ops skl_int3472_clock_ops = {
86
117
.recalc_rate = skl_int3472_clk_recalc_rate ,
87
118
};
88
119
89
- int skl_int3472_register_clock (struct int3472_discrete_device * int3472 ,
90
- struct acpi_resource_gpio * agpio , u32 polarity )
120
+ int skl_int3472_register_dsm_clock (struct int3472_discrete_device * int3472 )
121
+ {
122
+ struct acpi_device * adev = int3472 -> adev ;
123
+ struct clk_init_data init = {
124
+ .ops = & skl_int3472_clock_ops ,
125
+ .flags = CLK_GET_RATE_NOCACHE ,
126
+ };
127
+ int ret ;
128
+
129
+ if (int3472 -> clock .cl )
130
+ return 0 ; /* A GPIO controlled clk has already been registered */
131
+
132
+ if (!acpi_check_dsm (adev -> handle , & img_clk_guid , 0 , BIT (1 )))
133
+ return 0 ; /* DSM clock control is not available */
134
+
135
+ init .name = kasprintf (GFP_KERNEL , "%s-clk" , acpi_dev_name (adev ));
136
+ if (!init .name )
137
+ return - ENOMEM ;
138
+
139
+ int3472 -> clock .frequency = skl_int3472_get_clk_frequency (int3472 );
140
+ int3472 -> clock .clk_hw .init = & init ;
141
+ int3472 -> clock .clk = clk_register (& adev -> dev , & int3472 -> clock .clk_hw );
142
+ if (IS_ERR (int3472 -> clock .clk )) {
143
+ ret = PTR_ERR (int3472 -> clock .clk );
144
+ goto out_free_init_name ;
145
+ }
146
+
147
+ int3472 -> clock .cl = clkdev_create (int3472 -> clock .clk , NULL , int3472 -> sensor_name );
148
+ if (!int3472 -> clock .cl ) {
149
+ ret = - ENOMEM ;
150
+ goto err_unregister_clk ;
151
+ }
152
+
153
+ kfree (init .name );
154
+ return 0 ;
155
+
156
+ err_unregister_clk :
157
+ clk_unregister (int3472 -> clock .clk );
158
+ out_free_init_name :
159
+ kfree (init .name );
160
+ return ret ;
161
+ }
162
+
163
+ int skl_int3472_register_gpio_clock (struct int3472_discrete_device * int3472 ,
164
+ struct acpi_resource_gpio * agpio , u32 polarity )
91
165
{
92
166
char * path = agpio -> resource_source .string_ptr ;
93
167
struct clk_init_data init = {
0 commit comments