On Thu, Aug 20, 2020 at 12:50:46PM +0800, Rahul Tanwar wrote: > Intel Lightning Mountain(LGM) SoC contains a PWM fan controller. > This PWM controller does not have any other consumer, it is a > dedicated PWM controller for fan attached to the system. Add > driver for this PWM fan controller. ... > +config PWM_INTEL_LGM > + tristate "Intel LGM PWM support" > + depends on OF && HAS_IOMEM > + depends on X86 || COMPILE_TEST For better test coverage you may rewrite this depends on HAS_IOMEM depends on (OF && X86) || COMPILE_TEST > + select REGMAP_MMIO > + help > + Generic PWM fan controller driver for LGM SoC. > + > + To compile this driver as a module, choose M here: the module > + will be called pwm-intel-lgm. ... > +#include <linux/bitfield.h> > +#include <linux/clk.h> > +#include <linux/module.h> > +#include <linux/of_device.h> This should be mod_devicetable.h. > +#include <linux/pwm.h> > +#include <linux/regmap.h> > +#include <linux/reset.h> ... > +#define LGM_PWM_PERIOD_2WIRE_NSECS 40000000 NSECS -> NS 40000000 -> (40 * NSEC_PER_MSEC) ... > + if (state->polarity != PWM_POLARITY_NORMAL || > + state->period < pc->period) It can be one line. > + return -EINVAL; ... > + if (!state->enabled) { > + ret = lgm_pwm_enable(chip, 0); > + return ret; What is the point? > + } ... > + ret = lgm_pwm_enable(chip, 1); > + > + return ret; Ditto. ... > + state->duty_cycle = DIV_ROUND_UP(duty * pc->period, > + LGM_PWM_MAX_DUTY_CYCLE); One line? ... > + struct lgm_pwm_chip *pc; > + struct device *dev = &pdev->dev; Use reversed xmas tree order. > + void __iomem *io_base; > + int ret; ... > + pc->regmap = devm_regmap_init_mmio(dev, io_base, &lgm_pwm_regmap_config); > + if (IS_ERR(pc->regmap)) { > + ret = PTR_ERR(pc->regmap); > + if (ret != -EPROBE_DEFER) > + dev_err(dev, "failed to init register map: %pe\n", > + pc->regmap); > + return ret; dev_err_probe() > + } ... > + pc->clk = devm_clk_get(dev, NULL); > + if (IS_ERR(pc->clk)) { > + ret = PTR_ERR(pc->clk); > + if (ret != -EPROBE_DEFER) > + dev_err(dev, "failed to get clock: %pe\n", pc->clk); > + return ret; Ditto. > + } > + > + pc->rst = devm_reset_control_get_exclusive(dev, NULL); > + if (IS_ERR(pc->rst)) { > + ret = PTR_ERR(pc->rst); > + if (ret != -EPROBE_DEFER) > + dev_err(dev, "failed to get reset control: %pe\n", > + pc->rst); > + return ret; Ditto. > + } > + > + ret = reset_control_deassert(pc->rst); > + if (ret) { > + if (ret != -EPROBE_DEFER) > + dev_err(dev, "cannot deassert reset control: %pe\n", > + ERR_PTR(ret)); > + return ret; Ditto. > + } ... > + ret = clk_prepare_enable(pc->clk); Wrap it with devm_add_action_or_reset(). Same for reset_control_deassert(). You probably can even put them under one function. > + if (ret) { > + dev_err(dev, "failed to enable clock\n"); > + reset_control_assert(pc->rst); > + return ret; > + } ... > + ret = pwmchip_add(&pc->chip); > + if (ret < 0) { Does ' < 0' have any meaning? > + dev_err(dev, "failed to add PWM chip: %pe\n", ERR_PTR(ret)); > + clk_disable_unprepare(pc->clk); > + reset_control_assert(pc->rst); > + return ret; > + } ... > + ret = pwmchip_remove(&pc->chip); > + if (ret < 0) Ditto. > + return ret; -- With Best Regards, Andy Shevchenko