~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/sound/soc/codecs/rt711-sdw.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0
  2 //
  3 // rt711-sdw.c -- rt711 ALSA SoC audio driver
  4 //
  5 // Copyright(c) 2019 Realtek Semiconductor Corp.
  6 //
  7 //
  8 
  9 #include <linux/delay.h>
 10 #include <linux/device.h>
 11 #include <linux/mod_devicetable.h>
 12 #include <linux/soundwire/sdw.h>
 13 #include <linux/soundwire/sdw_type.h>
 14 #include <linux/soundwire/sdw_registers.h>
 15 #include <linux/module.h>
 16 #include <linux/pm_runtime.h>
 17 #include <linux/regmap.h>
 18 #include <sound/soc.h>
 19 #include "rt711.h"
 20 #include "rt711-sdw.h"
 21 
 22 static bool rt711_readable_register(struct device *dev, unsigned int reg)
 23 {
 24         switch (reg) {
 25         case 0x00e0:
 26         case 0x00f0:
 27         case 0x2012 ... 0x2016:
 28         case 0x201a ... 0x2027:
 29         case 0x2029 ... 0x202a:
 30         case 0x202d ... 0x2034:
 31         case 0x2201 ... 0x2204:
 32         case 0x2206 ... 0x2212:
 33         case 0x2220 ... 0x2223:
 34         case 0x2230 ... 0x2239:
 35         case 0x2f01 ... 0x2f0f:
 36         case 0x3000 ... 0x3fff:
 37         case 0x7000 ... 0x7fff:
 38         case 0x8300 ... 0x83ff:
 39         case 0x9c00 ... 0x9cff:
 40         case 0xb900 ... 0xb9ff:
 41         case 0x752008:
 42         case 0x752009:
 43         case 0x75200b:
 44         case 0x752011:
 45         case 0x75201a:
 46         case 0x752045:
 47         case 0x752046:
 48         case 0x752048:
 49         case 0x75204a:
 50         case 0x75206b:
 51         case 0x75206f:
 52         case 0x752080:
 53         case 0x752081:
 54         case 0x752091:
 55         case 0x755800:
 56                 return true;
 57         default:
 58                 return false;
 59         }
 60 }
 61 
 62 static bool rt711_volatile_register(struct device *dev, unsigned int reg)
 63 {
 64         switch (reg) {
 65         case 0x2016:
 66         case 0x201b:
 67         case 0x201c:
 68         case 0x201d:
 69         case 0x201f:
 70         case 0x2021:
 71         case 0x2023:
 72         case 0x2230:
 73         case 0x2012 ... 0x2015: /* HD-A read */
 74         case 0x202d ... 0x202f: /* BRA */
 75         case 0x2201 ... 0x2212: /* i2c debug */
 76         case 0x2220 ... 0x2223: /* decoded HD-A */
 77         case 0x9c00 ... 0x9cff:
 78         case 0xb900 ... 0xb9ff:
 79         case 0xff01:
 80         case 0x75201a:
 81         case 0x752046:
 82         case 0x752080:
 83         case 0x752081:
 84         case 0x755800:
 85                 return true;
 86         default:
 87                 return false;
 88         }
 89 }
 90 
 91 static int rt711_sdw_read(void *context, unsigned int reg, unsigned int *val)
 92 {
 93         struct device *dev = context;
 94         struct rt711_priv *rt711 = dev_get_drvdata(dev);
 95         unsigned int sdw_data_3, sdw_data_2, sdw_data_1, sdw_data_0;
 96         unsigned int reg2 = 0, reg3 = 0, reg4 = 0, mask, nid, val2;
 97         unsigned int is_hda_reg = 1, is_index_reg = 0;
 98         int ret;
 99 
100         if (reg > 0xffff)
101                 is_index_reg = 1;
102 
103         mask = reg & 0xf000;
104 
105         if (is_index_reg) { /* index registers */
106                 val2 = reg & 0xff;
107                 reg = reg >> 8;
108                 nid = reg & 0xff;
109                 ret = regmap_write(rt711->sdw_regmap, reg, 0);
110                 if (ret < 0)
111                         return ret;
112                 reg2 = reg + 0x1000;
113                 reg2 |= 0x80;
114                 ret = regmap_write(rt711->sdw_regmap, reg2, val2);
115                 if (ret < 0)
116                         return ret;
117 
118                 reg3 = RT711_PRIV_DATA_R_H | nid;
119                 ret = regmap_write(rt711->sdw_regmap,
120                         reg3, ((*val >> 8) & 0xff));
121                 if (ret < 0)
122                         return ret;
123                 reg4 = reg3 + 0x1000;
124                 reg4 |= 0x80;
125                 ret = regmap_write(rt711->sdw_regmap, reg4, (*val & 0xff));
126                 if (ret < 0)
127                         return ret;
128         } else if (mask   == 0x3000) {
129                 reg += 0x8000;
130                 ret = regmap_write(rt711->sdw_regmap, reg, *val);
131                 if (ret < 0)
132                         return ret;
133         } else if (mask == 0x7000) {
134                 reg += 0x2000;
135                 reg |= 0x800;
136                 ret = regmap_write(rt711->sdw_regmap,
137                         reg, ((*val >> 8) & 0xff));
138                 if (ret < 0)
139                         return ret;
140                 reg2 = reg + 0x1000;
141                 reg2 |= 0x80;
142                 ret = regmap_write(rt711->sdw_regmap, reg2, (*val & 0xff));
143                 if (ret < 0)
144                         return ret;
145         } else if ((reg & 0xff00) == 0x8300) { /* for R channel */
146                 reg2 = reg - 0x1000;
147                 reg2 &= ~0x80;
148                 ret = regmap_write(rt711->sdw_regmap,
149                         reg2, ((*val >> 8) & 0xff));
150                 if (ret < 0)
151                         return ret;
152                 ret = regmap_write(rt711->sdw_regmap, reg, (*val & 0xff));
153                 if (ret < 0)
154                         return ret;
155         } else if (mask == 0x9000) {
156                 ret = regmap_write(rt711->sdw_regmap,
157                         reg, ((*val >> 8) & 0xff));
158                 if (ret < 0)
159                         return ret;
160                 reg2 = reg + 0x1000;
161                 reg2 |= 0x80;
162                 ret = regmap_write(rt711->sdw_regmap, reg2, (*val & 0xff));
163                 if (ret < 0)
164                         return ret;
165         } else if (mask == 0xb000) {
166                 ret = regmap_write(rt711->sdw_regmap, reg, *val);
167                 if (ret < 0)
168                         return ret;
169         } else {
170                 ret = regmap_read(rt711->sdw_regmap, reg, val);
171                 if (ret < 0)
172                         return ret;
173                 is_hda_reg = 0;
174         }
175 
176         if (is_hda_reg || is_index_reg) {
177                 sdw_data_3 = 0;
178                 sdw_data_2 = 0;
179                 sdw_data_1 = 0;
180                 sdw_data_0 = 0;
181                 ret = regmap_read(rt711->sdw_regmap,
182                         RT711_READ_HDA_3, &sdw_data_3);
183                 if (ret < 0)
184                         return ret;
185                 ret = regmap_read(rt711->sdw_regmap,
186                         RT711_READ_HDA_2, &sdw_data_2);
187                 if (ret < 0)
188                         return ret;
189                 ret = regmap_read(rt711->sdw_regmap,
190                         RT711_READ_HDA_1, &sdw_data_1);
191                 if (ret < 0)
192                         return ret;
193                 ret = regmap_read(rt711->sdw_regmap,
194                         RT711_READ_HDA_0, &sdw_data_0);
195                 if (ret < 0)
196                         return ret;
197                 *val = ((sdw_data_3 & 0xff) << 24) |
198                         ((sdw_data_2 & 0xff) << 16) |
199                         ((sdw_data_1 & 0xff) << 8) | (sdw_data_0 & 0xff);
200         }
201 
202         if (is_hda_reg == 0)
203                 dev_dbg(dev, "[%s] %04x => %08x\n", __func__, reg, *val);
204         else if (is_index_reg)
205                 dev_dbg(dev, "[%s] %04x %04x %04x %04x => %08x\n",
206                         __func__, reg, reg2, reg3, reg4, *val);
207         else
208                 dev_dbg(dev, "[%s] %04x %04x => %08x\n",
209                         __func__, reg, reg2, *val);
210 
211         return 0;
212 }
213 
214 static int rt711_sdw_write(void *context, unsigned int reg, unsigned int val)
215 {
216         struct device *dev = context;
217         struct rt711_priv *rt711 = dev_get_drvdata(dev);
218         unsigned int reg2 = 0, reg3, reg4, nid, mask, val2;
219         unsigned int is_index_reg = 0;
220         int ret;
221 
222         if (reg > 0xffff)
223                 is_index_reg = 1;
224 
225         mask = reg & 0xf000;
226 
227         if (is_index_reg) { /* index registers */
228                 val2 = reg & 0xff;
229                 reg = reg >> 8;
230                 nid = reg & 0xff;
231                 ret = regmap_write(rt711->sdw_regmap, reg, 0);
232                 if (ret < 0)
233                         return ret;
234                 reg2 = reg + 0x1000;
235                 reg2 |= 0x80;
236                 ret = regmap_write(rt711->sdw_regmap, reg2, val2);
237                 if (ret < 0)
238                         return ret;
239 
240                 reg3 = RT711_PRIV_DATA_W_H | nid;
241                 ret = regmap_write(rt711->sdw_regmap,
242                         reg3, ((val >> 8) & 0xff));
243                 if (ret < 0)
244                         return ret;
245                 reg4 = reg3 + 0x1000;
246                 reg4 |= 0x80;
247                 ret = regmap_write(rt711->sdw_regmap, reg4, (val & 0xff));
248                 if (ret < 0)
249                         return ret;
250                 is_index_reg = 1;
251         } else if (reg < 0x4fff) {
252                 ret = regmap_write(rt711->sdw_regmap, reg, val);
253                 if (ret < 0)
254                         return ret;
255         } else if (reg == RT711_FUNC_RESET) {
256                 ret = regmap_write(rt711->sdw_regmap, reg, val);
257                 if (ret < 0)
258                         return ret;
259         } else if (mask == 0x7000) {
260                 ret = regmap_write(rt711->sdw_regmap,
261                         reg, ((val >> 8) & 0xff));
262                 if (ret < 0)
263                         return ret;
264                 reg2 = reg + 0x1000;
265                 reg2 |= 0x80;
266                 ret = regmap_write(rt711->sdw_regmap, reg2, (val & 0xff));
267                 if (ret < 0)
268                         return ret;
269         } else if ((reg & 0xff00) == 0x8300) {  /* for R channel */
270                 reg2 = reg - 0x1000;
271                 reg2 &= ~0x80;
272                 ret = regmap_write(rt711->sdw_regmap,
273                         reg2, ((val >> 8) & 0xff));
274                 if (ret < 0)
275                         return ret;
276                 ret = regmap_write(rt711->sdw_regmap, reg, (val & 0xff));
277                 if (ret < 0)
278                         return ret;
279         }
280 
281         if (reg2 == 0)
282                 dev_dbg(dev, "[%s] %04x <= %04x\n", __func__, reg, val);
283         else if (is_index_reg)
284                 dev_dbg(dev, "[%s] %04x %04x %04x %04x <= %04x %04x\n",
285                         __func__, reg, reg2, reg3, reg4, val2, val);
286         else
287                 dev_dbg(dev, "[%s] %04x %04x <= %04x\n",
288                         __func__, reg, reg2, val);
289 
290         return 0;
291 }
292 
293 static const struct regmap_config rt711_regmap = {
294         .reg_bits = 24,
295         .val_bits = 32,
296         .readable_reg = rt711_readable_register,
297         .volatile_reg = rt711_volatile_register,
298         .max_register = 0x755800,
299         .reg_defaults = rt711_reg_defaults,
300         .num_reg_defaults = ARRAY_SIZE(rt711_reg_defaults),
301         .cache_type = REGCACHE_MAPLE,
302         .use_single_read = true,
303         .use_single_write = true,
304         .reg_read = rt711_sdw_read,
305         .reg_write = rt711_sdw_write,
306 };
307 
308 static const struct regmap_config rt711_sdw_regmap = {
309         .name = "sdw",
310         .reg_bits = 32,
311         .val_bits = 8,
312         .readable_reg = rt711_readable_register,
313         .max_register = 0xff01,
314         .cache_type = REGCACHE_NONE,
315         .use_single_read = true,
316         .use_single_write = true,
317 };
318 
319 static int rt711_update_status(struct sdw_slave *slave,
320                                 enum sdw_slave_status status)
321 {
322         struct rt711_priv *rt711 = dev_get_drvdata(&slave->dev);
323 
324         if (status == SDW_SLAVE_UNATTACHED)
325                 rt711->hw_init = false;
326 
327         /*
328          * Perform initialization only if slave status is present and
329          * hw_init flag is false
330          */
331         if (rt711->hw_init || status != SDW_SLAVE_ATTACHED)
332                 return 0;
333 
334         /* perform I/O transfers required for Slave initialization */
335         return rt711_io_init(&slave->dev, slave);
336 }
337 
338 static int rt711_read_prop(struct sdw_slave *slave)
339 {
340         struct sdw_slave_prop *prop = &slave->prop;
341         int nval;
342         int i, j;
343         u32 bit;
344         unsigned long addr;
345         struct sdw_dpn_prop *dpn;
346 
347         prop->scp_int1_mask = SDW_SCP_INT1_IMPL_DEF | SDW_SCP_INT1_BUS_CLASH |
348                 SDW_SCP_INT1_PARITY;
349         prop->quirks = SDW_SLAVE_QUIRKS_INVALID_INITIAL_PARITY;
350 
351         prop->paging_support = false;
352 
353         /* first we need to allocate memory for set bits in port lists */
354         prop->source_ports = 0x14; /* BITMAP: 00010100 */
355         prop->sink_ports = 0x8; /* BITMAP:  00001000 */
356 
357         nval = hweight32(prop->source_ports);
358         prop->src_dpn_prop = devm_kcalloc(&slave->dev, nval,
359                                                 sizeof(*prop->src_dpn_prop),
360                                                 GFP_KERNEL);
361         if (!prop->src_dpn_prop)
362                 return -ENOMEM;
363 
364         i = 0;
365         dpn = prop->src_dpn_prop;
366         addr = prop->source_ports;
367         for_each_set_bit(bit, &addr, 32) {
368                 dpn[i].num = bit;
369                 dpn[i].type = SDW_DPN_FULL;
370                 dpn[i].simple_ch_prep_sm = true;
371                 dpn[i].ch_prep_timeout = 10;
372                 i++;
373         }
374 
375         /* do this again for sink now */
376         nval = hweight32(prop->sink_ports);
377         prop->sink_dpn_prop = devm_kcalloc(&slave->dev, nval,
378                                                 sizeof(*prop->sink_dpn_prop),
379                                                 GFP_KERNEL);
380         if (!prop->sink_dpn_prop)
381                 return -ENOMEM;
382 
383         j = 0;
384         dpn = prop->sink_dpn_prop;
385         addr = prop->sink_ports;
386         for_each_set_bit(bit, &addr, 32) {
387                 dpn[j].num = bit;
388                 dpn[j].type = SDW_DPN_FULL;
389                 dpn[j].simple_ch_prep_sm = true;
390                 dpn[j].ch_prep_timeout = 10;
391                 j++;
392         }
393 
394         /* set the timeout values */
395         prop->clk_stop_timeout = 20;
396 
397         /* wake-up event */
398         prop->wake_capable = 1;
399 
400         return 0;
401 }
402 
403 static int rt711_bus_config(struct sdw_slave *slave,
404                                 struct sdw_bus_params *params)
405 {
406         struct rt711_priv *rt711 = dev_get_drvdata(&slave->dev);
407         int ret;
408 
409         memcpy(&rt711->params, params, sizeof(*params));
410 
411         ret = rt711_clock_config(&slave->dev);
412         if (ret < 0)
413                 dev_err(&slave->dev, "%s: Invalid clk config", __func__);
414 
415         return ret;
416 }
417 
418 static int rt711_interrupt_callback(struct sdw_slave *slave,
419                                         struct sdw_slave_intr_status *status)
420 {
421         struct rt711_priv *rt711 = dev_get_drvdata(&slave->dev);
422 
423         dev_dbg(&slave->dev,
424                 "%s control_port_stat=%x", __func__, status->control_port);
425 
426         mutex_lock(&rt711->disable_irq_lock);
427         if (status->control_port & 0x4 && !rt711->disable_irq) {
428                 mod_delayed_work(system_power_efficient_wq,
429                         &rt711->jack_detect_work, msecs_to_jiffies(250));
430         }
431         mutex_unlock(&rt711->disable_irq_lock);
432 
433         return 0;
434 }
435 
436 static const struct sdw_slave_ops rt711_slave_ops = {
437         .read_prop = rt711_read_prop,
438         .interrupt_callback = rt711_interrupt_callback,
439         .update_status = rt711_update_status,
440         .bus_config = rt711_bus_config,
441 };
442 
443 static int rt711_sdw_probe(struct sdw_slave *slave,
444                                 const struct sdw_device_id *id)
445 {
446         struct regmap *sdw_regmap, *regmap;
447 
448         /* Regmap Initialization */
449         sdw_regmap = devm_regmap_init_sdw(slave, &rt711_sdw_regmap);
450         if (IS_ERR(sdw_regmap))
451                 return PTR_ERR(sdw_regmap);
452 
453         regmap = devm_regmap_init(&slave->dev, NULL,
454                 &slave->dev, &rt711_regmap);
455         if (IS_ERR(regmap))
456                 return PTR_ERR(regmap);
457 
458         return rt711_init(&slave->dev, sdw_regmap, regmap, slave);
459 }
460 
461 static int rt711_sdw_remove(struct sdw_slave *slave)
462 {
463         struct rt711_priv *rt711 = dev_get_drvdata(&slave->dev);
464 
465         if (rt711->hw_init) {
466                 cancel_delayed_work_sync(&rt711->jack_detect_work);
467                 cancel_delayed_work_sync(&rt711->jack_btn_check_work);
468                 cancel_work_sync(&rt711->calibration_work);
469         }
470 
471         pm_runtime_disable(&slave->dev);
472 
473         mutex_destroy(&rt711->calibrate_mutex);
474         mutex_destroy(&rt711->disable_irq_lock);
475 
476         return 0;
477 }
478 
479 static const struct sdw_device_id rt711_id[] = {
480         SDW_SLAVE_ENTRY_EXT(0x025d, 0x711, 0x2, 0, 0),
481         {},
482 };
483 MODULE_DEVICE_TABLE(sdw, rt711_id);
484 
485 static int __maybe_unused rt711_dev_suspend(struct device *dev)
486 {
487         struct rt711_priv *rt711 = dev_get_drvdata(dev);
488 
489         if (!rt711->hw_init)
490                 return 0;
491 
492         cancel_delayed_work_sync(&rt711->jack_detect_work);
493         cancel_delayed_work_sync(&rt711->jack_btn_check_work);
494         cancel_work_sync(&rt711->calibration_work);
495 
496         regcache_cache_only(rt711->regmap, true);
497 
498         return 0;
499 }
500 
501 static int __maybe_unused rt711_dev_system_suspend(struct device *dev)
502 {
503         struct rt711_priv *rt711 = dev_get_drvdata(dev);
504         struct sdw_slave *slave = dev_to_sdw_dev(dev);
505         int ret;
506 
507         if (!rt711->hw_init)
508                 return 0;
509 
510         /*
511          * prevent new interrupts from being handled after the
512          * deferred work completes and before the parent disables
513          * interrupts on the link
514          */
515         mutex_lock(&rt711->disable_irq_lock);
516         rt711->disable_irq = true;
517         ret = sdw_update_no_pm(slave, SDW_SCP_INTMASK1,
518                                SDW_SCP_INT1_IMPL_DEF, 0);
519         mutex_unlock(&rt711->disable_irq_lock);
520 
521         if (ret < 0) {
522                 /* log but don't prevent suspend from happening */
523                 dev_dbg(&slave->dev, "%s: could not disable imp-def interrupts\n:", __func__);
524         }
525 
526         return rt711_dev_suspend(dev);
527 }
528 
529 #define RT711_PROBE_TIMEOUT 5000
530 
531 static int __maybe_unused rt711_dev_resume(struct device *dev)
532 {
533         struct sdw_slave *slave = dev_to_sdw_dev(dev);
534         struct rt711_priv *rt711 = dev_get_drvdata(dev);
535         unsigned long time;
536 
537         if (!rt711->first_hw_init)
538                 return 0;
539 
540         if (!slave->unattach_request) {
541                 mutex_lock(&rt711->disable_irq_lock);
542                 if (rt711->disable_irq == true) {
543                         sdw_write_no_pm(slave, SDW_SCP_INTMASK1, SDW_SCP_INT1_IMPL_DEF);
544                         rt711->disable_irq = false;
545                 }
546                 mutex_unlock(&rt711->disable_irq_lock);
547                 goto regmap_sync;
548         }
549 
550         time = wait_for_completion_timeout(&slave->initialization_complete,
551                                 msecs_to_jiffies(RT711_PROBE_TIMEOUT));
552         if (!time) {
553                 dev_err(&slave->dev, "%s: Initialization not complete, timed out\n", __func__);
554                 return -ETIMEDOUT;
555         }
556 
557 regmap_sync:
558         slave->unattach_request = 0;
559         regcache_cache_only(rt711->regmap, false);
560         regcache_sync_region(rt711->regmap, 0x3000, 0x8fff);
561         regcache_sync_region(rt711->regmap, 0x752009, 0x752091);
562 
563         return 0;
564 }
565 
566 static const struct dev_pm_ops rt711_pm = {
567         SET_SYSTEM_SLEEP_PM_OPS(rt711_dev_system_suspend, rt711_dev_resume)
568         SET_RUNTIME_PM_OPS(rt711_dev_suspend, rt711_dev_resume, NULL)
569 };
570 
571 static struct sdw_driver rt711_sdw_driver = {
572         .driver = {
573                 .name = "rt711",
574                 .pm = &rt711_pm,
575         },
576         .probe = rt711_sdw_probe,
577         .remove = rt711_sdw_remove,
578         .ops = &rt711_slave_ops,
579         .id_table = rt711_id,
580 };
581 module_sdw_driver(rt711_sdw_driver);
582 
583 MODULE_DESCRIPTION("ASoC RT711 SDW driver");
584 MODULE_AUTHOR("Shuming Fan <shumingf@realtek.com>");
585 MODULE_LICENSE("GPL");
586 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php