Sunteți pe pagina 1din 84

Linux Device Drivers

Best-Practice Guidelines

Bill Gatliff <bgat@billgatliff.com>


Bill Gatliff and Associates, Inc.
Best Practices?!
Best Practices?!

Things that have worked for me:


Learned over two decades of things NOT working!

Your mileage may vary:


If yours is truly better, share it!
My solutions might not address your problems

2
Best Practices?!

General theories:
Not if, but when it breaks
What will I need at that time?
What did I wish I had last time?

But:
We cant unduly burden the nominal cases
We must not increase the risk of defects!

3
Best Practices?!

Goals and objectives:


Make our tools bring solutions
Free our minds to understand the problems
Redundancy is evil!

All of this is a work-in-progress...

4
Best Practices?!

General themes:
Never tell Linux how, only what
Express our needs, make Linux address them
Fully embrace device model vs. interface paradigm

Do things consistently, well.

5
Best Practices?!

More specically:
Full visibility into hardware state
No platform-specic code in drivers
No driver code in interface methods
No interface code in driver methods
No redundant code anywhere

6
Best Practices?!

Peripheral control registers:


Be paranoid about values
Read-only, write-only
Never touch reserved bits

Potentially LOTS of redundant code:


Theres an app for that! ;-)

7
Best Practices?!

Peripheral controls:
If it has one, I want to see it
... from the command line

Essential for root-cause analysis!

8
Best Practices?!

Choices, choices...
I2C?
SPI?
Platform?

Is there a way to do all the above?


Im glad you asked! :-)

9
Register Accessors
Register Accessors

1 static inline
2 void __raw_writel(
3 u32 b, volatile void *addr);
4
5 s32 i2c_smbus_write_byte(
6 const struct i2c_client *client,
7 u8 value);
8
9 static inline int
10 spi_write(struct spi_device *spi,
11 const void *buf, size_t len);

11
Register Accessors

1 #define REG_CTRL1 0x21


2 #define DO_RESET 0x40
3
4 static int do_reset(struct i2c_client *c)
5 {
6 return i2c_smbus_write_byte(c,
7 REG_CTRL1, DO_RESET);
8 }
9
10 static int set_rate(struct i2c_client *c, int r)
11 {
12 return i2c_smbus_write_byte(c,
13 REG_CTRL1, r << 3);
14 }

12
Register Accessors

Peripheral control registers:


Treat their values cautiously
Observe read-only, write-only restrictions
Never touch reserved bits

Paranoia is always your friend here.

13
Register Accessors

1 enum { /* bma250 */
2 BMA_REG_CHIP_ID = 0,
3 BMA_REG_VERSION = 1,
4
5 BMA_REG_X_AXIS_LSB = 2,
6 BMA_REG_X_AXIS_MSB = 3,
7 BMA_REG_Y_AXIS_LSB = 4,
8 BMA_REG_Y_AXIS_MSB = 5,
9 ...
10 BMA_REG_CTRL1 = 16,
11 ...
12 };

14
Register Accessors

1 enum {
2 BMA_REG_CHIP_ID = 0,
3 BMA_REG_CHIP_ID__reserved = 0,
4 ...
5 BMA_REG_X_AXIS_LSB = 2,
6 BMA_REG_X_AXIS_LSB__reserved = 0x3e,
7 ...
8 BMA_REG_CTRL1 = 16,
9 BMA_REG_CTRL1__reserved = 0x80,
10 BMA_REG_CTRL1__RATE = 0x18,
11 ...
12 };

15
Register Accessors

1 ssize_t bma_show_X_AXIS_LSB(struct device *dev,


2 struct device_attribute *attr,
3 char *buf)
4 {
5 struct bma *bma = dev_get_drvdata(dev);
6 _s32 ret;
7
8 mutex_lock_interruptible(&bma->mutex);
9 ret = i2c_smbus_read_byte_data(
10 bma->client, BMA_REG_X_AXIS_LSB);
11 mutex_unlock(&bma->mutex);
12 ret &= BMA_REG_X_AXIS_LSB__reserved;
13 return ret < 0 ?
14 ret : sprintf(buf, %02x\n, ret);
15 }

16
Register Accessors

Ouch!
Tedious, redundant, error-prone

Templates to the rescue!


In C, they are called macros

17
Basic Reads and Writes
Basic Reads and Writes

1 #define BMA_REG_READ(_name) \
2 int __bma_reg_read_##_name(struct bma *bma) \
3 { \
4 int ret; \
5 ret = __bma_reg_read(bma, BMA_REG_##_name); \
6 if (ret < 0) return ret; \
7 ret &= ~BMA_REG_##_name ## __reserved; \
8 dev_dbg(&bma->client->dev, %s: %02x\n, \
9 __func__, ret); \
10 return ret; \
11 }

19
Basic Reads and Writes

1 ...
2 BMA_REG_READ(X_AXIS_LSB);
3 BMA_REG_READ(Y_AXIS_LSB);
4 BMA_REG_READ(Z_AXIS_LSB);
5 ...

20
Basic Reads and Writes

1 ...
2 id = __bma_reg_read_CHIP_ID(bma);
3 ...
4 x_axis_lsb = __bma_reg_read_X_AXIS_LSB(bma);
5 ...

21
Basic Reads and Writes

1 #define BMA_REG_WRITE(_name) \
2 int __bma_reg_write_##_name( \
3 struct bma *bma, int v) \
4 { \
5 dev_dbg(&bma->client->dev, \
6 %s: %02x\n, __func__, v); \
7 v &= ~BMA_REG_##_name ## __reserved; \
8 return __bma_reg_write(bma, \
9 BMA_REG_##_name, v); \
10 }

22
Basic Reads and Writes

You saw that (small) bug, right?

23
Basic Reads and Writes

Figure 1: Which would you rather debug?

24
Bit Fields
Bit Fields

1 static int bma_set_rate(struct bma *bma, int r)


2 {
3 /* TODO: clean this up! */
4 return __bma_reg_write(bma,
5 __bma_reg_read(bma, REG_CTRL1)
6 & ~RATE | ((r) << 3) & RATE);
7 }

26
Bit Fields

1 static int bma_set_rate(struct bma *bma, int r)


2 {
3 int ctrl1;
4
5 ctrl1 = __bma_reg_read_CTRL1(bma);
6 if (ctrl1 < 0) return ctrl1;
7
8 ctrl1 &= ~BMA_REG_CTRL1__RATE;
9
10 /* TODO: now clean _this_ up! */
11 ctrl1 |= ((r << 3) & BMA_REG_CTRL1__RATE);
12
13 return __bma_reg_write_CTRL1(bma, ctrl1);
14 }

27
Bit Fields

1 static int bma_set_rate(struct bma *bma, int r)


2 {
3 int ctrl1;
4 const int __shift
5 = __ffs(BMA_REG_CTRL1__RATE);
6 const int __mask = BMA_REG_CTRL1__RATE;
7
8 ctrl1 = __bma_reg_read_CTRL1(bma);
9 if (ctrl1 < 0) return ctrl1;
10
11 ctrl1 &= __mask;
12 ctrl1 |= ((r << __shift) & __mask);
13
14 return __bma_reg_write_CTRL1(bma, ctrl1);
15 }

28
Bit Fields

You saw that nasty bug, right?

29
Bit Fields

1 static int bma_set_rate(struct bma *bma, int r)


2 {
3 int ctrl1;
4 const int __shift
5 = __ffs(BMA_REG_CTRL1__RATE);
6 const int __mask = BMA_REG_CTRL1__RATE;
7
8 __bma_lock(bma);
9 ctrl1 = __bma_reg_read_CTRL1(bma);
10 if (ctrl1 < 0) goto err_unlock;
11
12 ctrl1 &= __mask;
13 ctrl1 |= ((r << __shift) & __mask);
14 ctrl1 = __bma_reg_write_CTRL1(bma, ctrl1);
15
16 err_unlock:
17 __bma_unlock(bma);
18 return ctrl1;
19 } 30
Write-Only Registers
Write-Only Registers

Lets make them look read-write:


Reduces risk of (some) programming errors
Might simplify suspend/resume, too!

32
Write-Only Registers

1 #define BMA_REG_WRITE(_name) \
2 int __bma_reg_write_##_name( \
3 struct bma *bma, int v) \
4 { \
5 int ret; \
6 v &= ~BMA_REG_##_name ## __reserved; \
7 ret = __bma_reg_write( \
8 bma, BMA_REG_##_name, v); \
9 if (ret < 0) return ret; \
10 switch (BMA_REG_##_name) { \
11 case BMA_REG_RANGE: bma->RANGE = v; break; \
12 case BMA_REG_RESET: usleep(4000); break; \
13 } \
14 return 0; \
15 }

33
Write-Only Registers

1 #define BMA_REG_READ(_name) \
2 int __bma_reg_read_##_name(struct bma *bma) \
3 { \
4 int ret = __bma_reg_read( \
5 bma, BMA_REG_##_name); \
6 if (ret < 0) return ret; \
7 ret &= ~BMA_REG_##_name ## __reserved; \
8 switch (BMA_REG_##_name) { \
9 case BMA_REG_RANGE: bma->RANGE = ret; break; \
10 } \
11 return ret; \
12 }

34
Write-Only Registers

You saw that huge bug, right?

35
Write-Only Registers

1 #define BMA_REG_READ(_name) \
2 int __bma_reg_read_##_name(struct bma *bma) \
3 { \
4 int ret; \
5 switch (BMA_REG_##_name) { \
6 case BMA_REG_RANGE: return bma->RANGE; \
7 } \
8 ret = __bma_reg_read(bma, BMA_REG_##_name); \
9 if (ret < 0) return ret; \
10 ret &= ~BMA_REG_##_name ## __reserved; \
11 return ret; \
12 }

36
Write-Only Registers

1 ...
2 static int bma_do_reset(struct bma *bma)
3 {
4 int ret;
5
6 __bma_lock(bma);
7 ret = __bma_reg_write_RESET(bma);
8 ...
9 ret = __bma_reg_write_RANGE(bma, bma->RANGE);
10 ...
11 __bma_unlock(bma);
12 }
13 ...

37
Write-Only Registers

1 #define BMA_REG_READWRITE(name) \
2 BMA_REG_READ(name) \
3 BMA_REG_WRITE(name)
4 ...
5 BMA_REG_READ(CHIP_ID)
6 BMA_REG_READ(X_AXIS_LSB)
7 BMA_REG_WRITE(RANGE)
8 BMA_REG_READWRITE(RESET)
9 ...

38
Control Register Attributes
Control Register Attributes

1 root@device:# cd /sys/bus/i2c/devices
2 root@device:# ls -l 2-0070
3 ...
4 -r--r--r-- 1 root root 4096 Jun 16 18:04 CHIP_ID
5 -r--r--r-- 1 root root 4096 Jun 16 18:04 VERSION
6 -r--r--r-- 1 root root 4096 Jun 16 18:04 X_AXIS_LSB
7 -r--r--r-- 1 root root 4096 Jun 16 18:04 Y_AXIS_LSB
8 ...
9 -rw-r--r-- 1 root root 4096 Jun 16 18:04 CTRL1
10 ...
11 root@device:# cat .../X_AXIS_LSB
12 127
13 root@device:# echo 89 > .../CTRL1

40
Control Register Attributes

1 ...
2 enum {
3 BMA_REG_CHIP_ID = 0,
4 BMA_REG_CHIP_ID__reserved = 0,
5 ...
6 BMA_REG_X_AXIS_LSB = 2,
7 BMA_REG_X_AXIS_LSB__reserved = 0x3e,
8 ...
9 };

41
Control Register Attributes

1 ssize_t bma_show_X_AXIS_LSB(struct device *dev,


2 struct device_attribute *attr,
3 char *buf)
4 {
5 struct bma *bma = dev_get_drvdata(dev);
6 _s32 ret;
7
8 mutex_lock_interruptible(&bma->mutex);
9 ret = i2c_smbus_read_byte_data(bma->client,
10 BMA_REG_X_AXIS_LSB);
11 mutex_unlock(&bma->mutex);
12 ret &= BMA_REG_X_AXIS_LSB__reserved;
13 return ret < 0 ?
14 ret : sprintf(buf, %02x\n, ret);
15 }

42
Control Register Attributes

Why I dont like that:


Tedious, redundant, error-prone
Wont scale well
Contains a media assumption

43
Control Register Attributes

Use templates for attribute methods:


Will seem noisy, excessive
... but only to the untrained eye!

Why do this, then?


Hardware and driver validation
Board bring-up
Root-cause analysis

44
Control Register Attributes

1 #define BMA_REG_READ(_name) \
2 int __bma_reg_read_##_name(struct bma *bma) \
3 { \
4 int ret = __bma_reg_read( \
5 bma, BMA_REG_##_name); \
6 if (ret < 0) return ret; \
7 ret &= ~BMA_REG_##_name ## __reserved; \
8 dev_dbg(&bma->client->dev, \
9 %s: %02x\n, __func__, ret); \
10 return ret; \
11 }

45
Control Register Attributes

1 ssize_t bma_show_X_AXIS_LSB(struct device *dev,


2 struct device_attribute *attr,
3 char *buf)
4 {
5 struct bma *bma = dev_get_drvdata(dev);
6 _s32 ret;
7
8 __bma_lock(bma);
9 ret = __bma_reg_read_X_AXIS_LSB(bma);
10 __bma_unlock(bma);
11
12 return ret < 0 ?
13 ret : sprintf(buf, %02x\n, ret);
14 }

46
Control Register Attributes

1 #define BMA_REG_ATTR_STORE(_name) \
2 ssize_t bma_store_##_name(struct device *dev, \
3 struct device_attribute *attr, \
4 const char *buf, size_t len) \
5 { \
6 struct bma *bma = dev_get_drvdata(dev); \
7 int ret; \
8 unsigned long v; \
9 ret = strict_strtoul(buf, 16, &v); \
10 if (ret) return ret; \
11 ...

47
Control Register Attributes

1 #define BMA_REG_ATTR_STORE(_name) \
2 ... \
3 __bma_lock(bma); \
4 switch (BMA_REG_##_name) { \
5 case BMA_REG_POWER: \
6 ret = __bma_reg_write_POWER(bma, v); \
7 break; \
8 case BMA_REG_RESET: \
9 ret = __bma_reg_write_RESET(bma, v); \
10 usleep(4000); /* ! */ \
11 break; \
12 ...

48
Control Register Attributes

1 #define BMA_REG_ATTR_STORE(_name) \
2 ... \
3 default: \
4 ret = __bma_reg_write_##_name(bma, v); \
5 break; \
6 } \
7 __bma_unlock(bma); \
8 return (ret < 0) ? ret : len; \
9 }

49
Control Register Attributes

Dont combine templates too early:


Youll make mix-and-match more difcult

Dont mingle locking code:


Youll cause problems for yourself later

50
Control Register Attributes

1 static int __bma_checklock(struct bma *bma)


2 {
3 if (spin_trylock(&bma->lock)) {
4 spin_unlock(&bma->lock);
5 return 1;
6 }
7 return 0;
8 }
9
10 #define BMA_REG_READ(_name) \
11 int __bma_reg_read_##_name(struct bma *bma) \
12 { \
13 WARN_ON_ONCE(__bma_checklock(bma)); \
14 ... \
15 }

51
Control Register Attributes

1 #define BMA_REG(_name) \
2 BMA_REG_READ(_name) \
3 BMA_REG_ATTR_SHOW(_name) \
4 DEVICE_ATTR(_name, S_IRUGO, bma_show_##_name, NULL);
5
6 ...
7 BMA_REG(BMA_REG_X_AXIS_LSB);
8 BMA_REG(BMA_REG_Y_AXIS_LSB);
9 ...

52
Control Register Attributes

1 #define BMA_REG_READWRITE(_name) \
2 BMA_REG_READ(_name) \
3 BMA_REG_WRITE(_name) \
4 BMA_REG_ATTR_SHOW(_name) \
5 BMA_REG_ATTR_STORE(_name) \
6 DEVICE_ATTR(_name, S_IRUGO | S_IWUSR, \
7 bma_show_##_name, bma_store_##_name);
8
9 ...
10 BMA_REG_READWRITE(BMA_REG_POWER);
11 ...

53
Control Register Attributes

1 static struct attribute *attrs[] = {


2 &dev_attr_CHIP_ID.attr,
3 &dev_attr_VERSION.attr,
4 &dev_attr_TEMP.attr,
5 &dev_attr_STATUS.attr,
6 &dev_attr_DATA_INT.attr,
7 &dev_attr_TAP_SLOPE_INT_STATUS.attr,
8 ...
9 };

54
Control Register Attributes

1 static struct attribute_group agroup = {


2 .attrs = attrs,
3 };
4
5 static int bma_probe(struct bma *bma)
6 {
7 ...
8 ret = sysfs_create_group(kobj, &agroup);
9 if (ret)
10 goto err_sysfs_create_group;
11 ...
12 }

55
Control Register Attributes

1 static struct attribute *attrs[] = {


2 &dev_attr_CHIP_ID.attr,
3 &dev_attr_VERSION.attr,
4 &dev_attr_TEMP.attr,
5 #if !defined(DEBUG)
6 &dev_attr_RESET.attr,
7 #endif
8 &dev_attr_STATUS.attr,
9 &dev_attr_DATA_INT.attr,
10 &dev_attr_TAP_SLOPE_INT_STATUS.attr,
11 ...
12 };

56
Control Register Attributes

1 static struct attribute_group agroup = {


2 .attrs = attrs,
3 };
4 static struct attribute_group debug_group = {
5 .attrs = debug_attrs,
6 };
7
8 ...
9 if (a_module_var)
10 ret = sysfs_create_group(kobj, &debug_group);
11 ...

57
Control Register Attributes

Did you catch that?


Attributes take a struct device pointer

They DONT CARE about the media!

58
Access Layer Portability
Access Layer Portability

struct device_driver
... contains nothing about the underlying media

struct i2c_driver
A simple wrapper around struct device_driver
Creates a bus, and other helper abstractions

60
Access Layer Portability

struct spi_driver
Same thing!

struct platform_driver
... but I repeat myself again

61
Access Layer Portability

Why do we keep doing this?!

62
Access Layer Portability

1 ssize_t bma_show_X_AXIS_LSB(struct device *dev,


2 struct device_attribute *attr,
3 char *buf)
4 {
5 struct bma *bma = dev_get_drvdata(dev);
6 _s32 ret;
7
8 mutex_lock_interruptible(&bma->mutex);
9 ret = i2c_smbus_read_byte_data(bma->client,
10 BMA_REG_X_AXIS_LSB); /* ! */
11 mutex_unlock(&bma->mutex);
12 ret &= BMA_REG_X_AXIS_LSB__reserved;
13 return ret < 0 ?
14 ret : sprintf(buf, %02x\n, ret);
15 }

63
Access Layer Portability

1 struct bma {
2 struct mutex m;
3 spin_lock_t s;
4 ...
5 struct device *dev;
6 struct i2c_client *i2c;
7 struct spi_device *spi;
8 ...
9 };

64
Access Layer Portability

1 static int __bma_reg_read(


2 struct bma *bma, int reg)
3 {
4 if (bma->i2c)
5 return i2c_smbus_read_byte_data(
6 bma->i2c, reg);
7 if (bma->spi)
8 return bma_spi_read_byte_data(
9 bma->spi, reg);
10 return -ENODEV;
11 }

65
Access Layer Portability

1 int bma_i2c_probe(struct i2c_client *client,


2 const struct i2c_device_id *id)
3 {
4 struct bma *bma;
5 int ret;
6
7 bma = kzalloc(sizeof(*bma), GFP_KERNEL);
8 if (!bma)
9 return -ENOMEM;
10 ...

66
Access Layer Portability

1 ...
2 i2c_set_clientdata(client, bma);
3 bma->i2c = client;
4 bma->dev = &i2c->dev;
5
6 ret = bma_probe(bma);
7 if (ret)
8 kfree(bma);
9 return ret;
10 }

67
Access Layer Portability

1 static int bma_probe(struct bma *bma)


2 {
3 int ret;
4 ...
5 spin_lock_init(&bma->s);
6 ...
7 ret = __bma_reset(bma);
8 ...
9 id = __bma_reg_read_CHIP_ID(bma);
10 ...
11 return ret;
12 }

68
Access Layer Portability

1 int module_init(void)
2 {
3 int ret;
4
5 ret = i2c_add_driver(...);
6 ...
7 ret = spi_register_driver(...);
8 ...
9 return ret;
10 }

69
Access Layer Portability

1 static int bma_resume(struct device *dev)


2 {
3 struct bma *bma = dev_get_drvdata(dev);
4 int ret;
5 ...
6 ret = __bma_reset(bma);
7 ...
8 __bma_reg_write_RANGE(bma, bma->RANGE);
9 ...
10 return ret;
11 }

70
Devices vs. Interfaces
Devices vs. Interfaces

struct device
Represents something power-managed
Captures hierarchy, dependencies

struct file_operations
Represents... le operations!
open(), write(), etc.
mmap(), ioctl()

72
Devices vs. Interfaces

The key points:


Interfaces are properties of devices only
Interfaces cannot exhibit hierarchy
Devices are almost always hierarchical

Device nodes are interfaces not devices!

73
Eliminate Callbacks
Eliminate Callbacks

1 struct foo_board_data {
2 void (callback*)(void);
3 };
4
5 struct foo_board_data foo_board = {
6 .callback = do_something_horrible();
7 };
8
9 struct platform_device foo_device = {
10 .dev.platform_data = &foo_board,
11 };
12 ...

75
Eliminate Callbacks

1 int foo_driver_method(struct foo *foo)


2 {
3 ...
4 foo->board_data->callback();
5 ...
6 }

76
Eliminate Callbacks

1 struct foo_board_data {
2 void (callback*)(int);
3 };
4
5 struct foo_board_data foo_board = {
6 .callback = do_gpio_enables(int on);
7 };
8
9 struct platform_device foo_device = {
10 .dev.platform_data = &foo_board,
11 };
12 ...

77
Eliminate Callbacks

1 int foo_driver_suspend(struct foo *foo)


2 {
3 ...
4 foo->board_data->callback(0);
5 ...
6 }
7
8 int foo_driver_resume(struct foo *foo)
9 {
10 ...
11 foo->board_data->callback(1);
12 ...
13 }

78
Eliminate Callbacks

Why is this so bad?


Because Linux doesnt know what is going on!

Linux cant help you if you dont ask:


... and you may get in its way if you dont!

79
Eliminate Callbacks

Alternatives:
Do power management in suspend()/resume()
Do GPIO management in regulator notiers
Describe regulator consumers correctly

80
Eliminate Callbacks

Any questions?

81
Copyright

Copyright 2015, by Bill Gatliff <bgat@billgatliff.com>. All Rights Reserved. You may
not reproduce or redistribute this document without prior written consent.

82
Linux Device Drivers
Best-Practice Guidelines

Bill Gatliff <bgat@billgatliff.com>


Bill Gatliff and Associates, Inc.

S-ar putea să vă placă și