2

Example: I use sensor TMP421 which driver is linux/drivers/hwmon/tmp421.c. It will export to /sys/class/hwmon/hwon0/.... And user can use cat command to read the temperatures. But my is request: I want to read it at kernel space to control some thing when the temperature reach to MAX values (example).

So how I can attach to get the device context to use the function

tmp421_data *tmp421_update_device(struct device *dev)

to read the temperature ?

Or is there another way ? I don't want to use the cat command at my code.

Thanks

Jayesh Bhoi
  • 24,694
  • 15
  • 58
  • 73
yvo.engr
  • 131
  • 2
  • 5

2 Answers2

1

Just do bus_find_device_by_name on an i2c_bus_type. It should give you the correct device pointer relatively easily. You will also have to change the tmp421_update_device function from "static" to "exported" (and move tmp421_data structure to an external header).

If you don't want to alter drivers not of your own, you can still try to emulate the approach sysfs takes when accessing device information. The sysfs dirent will be accessible to you at the dev->kobj.sd field and it's a fairly simple data structure.

Critically, you need to call put_device() on the received device handle after you've finished with it (otherwise you will end up with kernel lock-up down the line because of "unreleasable" objects). If you're using the kobj.sd accessor, then sysfs_get()/sysfs_put() on it will also be required.

oakad
  • 6,945
  • 1
  • 22
  • 31
  • Thanks a lot. I still can not find the best way for this case. Because I don't want to alter the tmp421 driver. So I try to use the shell script running at user space, then it will read the temperature from tmp421 and another sensor by cat command. Then will echo the value to our driver to control some things. – yvo.engr Apr 04 '14 at 16:58
  • User space helpers are an acceptable way to do such things. Depending on you application you may also find the uio framework useful: https://www.kernel.org/doc/htmldocs/uio-howto/ (this will allow you to put the major part of your driver in user space with all the obvious benefits). – oakad Apr 07 '14 at 01:26
0

As said in https://stackoverflow.com/a/4407051/196561 ("How to use sysfs inside kernel module?") by shodanex

it is a Bad Idea (tm)

with link http://www.linuxjournal.com/article/8110

Driving Me Nuts - Things You Never Should Do in the Kernel - From Issue #133 Linux Journal, 2005 By Greg Kroah-Hartman

The article says that it is possible to use sys_open and sys_read from modules to open and read files:

old_fs = get_fs();
set_fs(KERNEL_DS);

fd = sys_open(filename, O_RDONLY, 0);
if (fd >= 0) {
  /* read the file here */
  sys_close(fd);
}
set_fs(old_fs);

Don't know will it work with files in /sys or not.

And Greg warns us:

I Never Told You about This. In conclusion, reading and writing a file from within the kernel is a bad, bad thing to do. Never do it. Ever.

Better way may be to learn inter module communications, possibly with modifying the hwmon/tmp421.c.

Community
  • 1
  • 1
osgx
  • 90,338
  • 53
  • 357
  • 513
  • It's not really an answer to the question, is it? OP would prefer not to use sysfs himself. – oakad Mar 28 '14 at 00:05
  • inter module communicatio is good way. But I try to move all to user space, it is easier to do first. Really to thanks all of you. – yvo.engr Nov 07 '14 at 03:52