lantiq: fix broadcasts and vlans in two iface mode
[oweals/openwrt.git] / target / linux / brcm2708 / patches-4.9 / 0112-i2c-bcm2835-Add-support-for-dynamic-clock.patch
1 From ce8663f1f101f8c7b9037c31269b0b31373737ad Mon Sep 17 00:00:00 2001
2 From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf@tronnes.org>
3 Date: Tue, 27 Sep 2016 01:00:08 +0200
4 Subject: [PATCH] i2c: bcm2835: Add support for dynamic clock
5 MIME-Version: 1.0
6 Content-Type: text/plain; charset=UTF-8
7 Content-Transfer-Encoding: 8bit
8
9 Support a dynamic clock by reading the frequency and setting the
10 divisor in the transfer function instead of during probe.
11
12 Signed-off-by: Noralf Trønnes <noralf@tronnes.org>
13 Reviewed-by: Martin Sperl <kernel@martin.sperl.org>
14 ---
15  drivers/i2c/busses/i2c-bcm2835.c | 51 +++++++++++++++++++++++++---------------
16  1 file changed, 32 insertions(+), 19 deletions(-)
17
18 --- a/drivers/i2c/busses/i2c-bcm2835.c
19 +++ b/drivers/i2c/busses/i2c-bcm2835.c
20 @@ -58,6 +58,7 @@ struct bcm2835_i2c_dev {
21         void __iomem *regs;
22         struct clk *clk;
23         int irq;
24 +       u32 bus_clk_rate;
25         struct i2c_adapter adapter;
26         struct completion completion;
27         struct i2c_msg *curr_msg;
28 @@ -78,6 +79,30 @@ static inline u32 bcm2835_i2c_readl(stru
29         return readl(i2c_dev->regs + reg);
30  }
31  
32 +static int bcm2835_i2c_set_divider(struct bcm2835_i2c_dev *i2c_dev)
33 +{
34 +       u32 divider;
35 +
36 +       divider = DIV_ROUND_UP(clk_get_rate(i2c_dev->clk),
37 +                              i2c_dev->bus_clk_rate);
38 +       /*
39 +        * Per the datasheet, the register is always interpreted as an even
40 +        * number, by rounding down. In other words, the LSB is ignored. So,
41 +        * if the LSB is set, increment the divider to avoid any issue.
42 +        */
43 +       if (divider & 1)
44 +               divider++;
45 +       if ((divider < BCM2835_I2C_CDIV_MIN) ||
46 +           (divider > BCM2835_I2C_CDIV_MAX)) {
47 +               dev_err_ratelimited(i2c_dev->dev, "Invalid clock-frequency\n");
48 +               return -EINVAL;
49 +       }
50 +
51 +       bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_DIV, divider);
52 +
53 +       return 0;
54 +}
55 +
56  static void bcm2835_fill_txfifo(struct bcm2835_i2c_dev *i2c_dev)
57  {
58         u32 val;
59 @@ -224,7 +249,7 @@ static int bcm2835_i2c_xfer(struct i2c_a
60  {
61         struct bcm2835_i2c_dev *i2c_dev = i2c_get_adapdata(adap);
62         unsigned long time_left;
63 -       int i;
64 +       int i, ret;
65  
66         for (i = 0; i < (num - 1); i++)
67                 if (msgs[i].flags & I2C_M_RD) {
68 @@ -233,6 +258,10 @@ static int bcm2835_i2c_xfer(struct i2c_a
69                         return -EOPNOTSUPP;
70                 }
71  
72 +       ret = bcm2835_i2c_set_divider(i2c_dev);
73 +       if (ret)
74 +               return ret;
75 +
76         i2c_dev->curr_msg = msgs;
77         i2c_dev->num_msgs = num;
78         reinit_completion(&i2c_dev->completion);
79 @@ -282,7 +311,6 @@ static int bcm2835_i2c_probe(struct plat
80  {
81         struct bcm2835_i2c_dev *i2c_dev;
82         struct resource *mem, *irq;
83 -       u32 bus_clk_rate, divider;
84         int ret;
85         struct i2c_adapter *adap;
86  
87 @@ -306,28 +334,13 @@ static int bcm2835_i2c_probe(struct plat
88         }
89  
90         ret = of_property_read_u32(pdev->dev.of_node, "clock-frequency",
91 -                                  &bus_clk_rate);
92 +                                  &i2c_dev->bus_clk_rate);
93         if (ret < 0) {
94                 dev_warn(&pdev->dev,
95                          "Could not read clock-frequency property\n");
96 -               bus_clk_rate = 100000;
97 +               i2c_dev->bus_clk_rate = 100000;
98         }
99  
100 -       divider = DIV_ROUND_UP(clk_get_rate(i2c_dev->clk), bus_clk_rate);
101 -       /*
102 -        * Per the datasheet, the register is always interpreted as an even
103 -        * number, by rounding down. In other words, the LSB is ignored. So,
104 -        * if the LSB is set, increment the divider to avoid any issue.
105 -        */
106 -       if (divider & 1)
107 -               divider++;
108 -       if ((divider < BCM2835_I2C_CDIV_MIN) ||
109 -           (divider > BCM2835_I2C_CDIV_MAX)) {
110 -               dev_err(&pdev->dev, "Invalid clock-frequency\n");
111 -               return -ENODEV;
112 -       }
113 -       bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_DIV, divider);
114 -
115         irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
116         if (!irq) {
117                 dev_err(&pdev->dev, "No IRQ resource\n");