All of lore.kernel.org
 help / color / mirror / Atom feed
From: Guenter Roeck <linux@roeck-us.net>
To: "Uwe Kleine-König" <u.kleine-koenig@pengutronix.de>,
	"Wim Van Sebroeck" <wim@iguana.be>
Cc: kernel@pengutronix.de, linux-watchdog@vger.kernel.org
Subject: Re: [PATCH v2 5/7] watchdog: mpc8xxx: use dynamic memory for device specific data
Date: Wed, 12 Aug 2015 03:21:11 -0700	[thread overview]
Message-ID: <55CB1E17.4080008@roeck-us.net> (raw)
In-Reply-To: <1439367358-5338-6-git-send-email-u.kleine-koenig@pengutronix.de>

On 08/12/2015 01:15 AM, Uwe Kleine-König wrote:
> Instead of relying on global static memory dynamically allocate the
> needed data. This has the benefit of some saved bytes if the driver is
> not in use and making it possible to bind more than one device (even
> though this has no known use case).
>
> Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>

Reviewed-by: Guenter Roeck <linux@roeck-us.net>

> ---
>   drivers/watchdog/mpc8xxx_wdt.c | 88 +++++++++++++++++++++++++-----------------
>   1 file changed, 53 insertions(+), 35 deletions(-)
>
> diff --git a/drivers/watchdog/mpc8xxx_wdt.c b/drivers/watchdog/mpc8xxx_wdt.c
> index a6790fcfa69b..0b69797d3417 100644
> --- a/drivers/watchdog/mpc8xxx_wdt.c
> +++ b/drivers/watchdog/mpc8xxx_wdt.c
> @@ -50,7 +50,12 @@ struct mpc8xxx_wdt_type {
>   	bool hw_enabled;
>   };
>
> -static struct mpc8xxx_wdt __iomem *wd_base;
> +struct mpc8xxx_wdt_ddata {
> +	struct mpc8xxx_wdt __iomem *base;
> +	struct watchdog_device wdd;
> +	struct timer_list timer;
> +	spinlock_t lock;
> +};
>
>   static u16 timeout = 0xffff;
>   module_param(timeout, ushort, 0);
> @@ -67,33 +72,29 @@ module_param(nowayout, bool, 0);
>   MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started "
>   		 "(default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
>
> -static DEFINE_SPINLOCK(wdt_spinlock);
> -
> -static void mpc8xxx_wdt_keepalive(void)
> +static void mpc8xxx_wdt_keepalive(struct mpc8xxx_wdt_ddata *ddata)
>   {
>   	/* Ping the WDT */
> -	spin_lock(&wdt_spinlock);
> -	out_be16(&wd_base->swsrr, 0x556c);
> -	out_be16(&wd_base->swsrr, 0xaa39);
> -	spin_unlock(&wdt_spinlock);
> +	spin_lock(&ddata->lock);
> +	out_be16(&ddata->base->swsrr, 0x556c);
> +	out_be16(&ddata->base->swsrr, 0xaa39);
> +	spin_unlock(&ddata->lock);
>   }
>
> -static struct watchdog_device mpc8xxx_wdt_dev;
> -static void mpc8xxx_wdt_timer_ping(unsigned long arg);
> -static DEFINE_TIMER(wdt_timer, mpc8xxx_wdt_timer_ping, 0,
> -		(unsigned long)&mpc8xxx_wdt_dev);
> -
>   static void mpc8xxx_wdt_timer_ping(unsigned long arg)
>   {
> -	struct watchdog_device *w = (struct watchdog_device *)arg;
> +	struct mpc8xxx_wdt_ddata *ddata = (void *)arg;
>
> -	mpc8xxx_wdt_keepalive();
> +	mpc8xxx_wdt_keepalive(ddata);
>   	/* We're pinging it twice faster than needed, just to be sure. */
> -	mod_timer(&wdt_timer, jiffies + HZ * w->timeout / 2);
> +	mod_timer(&ddata->timer, jiffies + HZ * ddata->wdd.timeout / 2);
>   }
>
>   static int mpc8xxx_wdt_start(struct watchdog_device *w)
>   {
> +	struct mpc8xxx_wdt_ddata *ddata =
> +		container_of(w, struct mpc8xxx_wdt_ddata, wdd);
> +
>   	u32 tmp = SWCRR_SWEN | SWCRR_SWPR;
>
>   	/* Good, fire up the show */
> @@ -102,22 +103,28 @@ static int mpc8xxx_wdt_start(struct watchdog_device *w)
>
>   	tmp |= timeout << 16;
>
> -	out_be32(&wd_base->swcrr, tmp);
> +	out_be32(&ddata->base->swcrr, tmp);
>
> -	del_timer_sync(&wdt_timer);
> +	del_timer_sync(&ddata->timer);
>
>   	return 0;
>   }
>
>   static int mpc8xxx_wdt_ping(struct watchdog_device *w)
>   {
> -	mpc8xxx_wdt_keepalive();
> +	struct mpc8xxx_wdt_ddata *ddata =
> +		container_of(w, struct mpc8xxx_wdt_ddata, wdd);
> +
> +	mpc8xxx_wdt_keepalive(ddata);
>   	return 0;
>   }
>
>   static int mpc8xxx_wdt_stop(struct watchdog_device *w)
>   {
> -	mod_timer(&wdt_timer, jiffies);
> +	struct mpc8xxx_wdt_ddata *ddata =
> +		container_of(w, struct mpc8xxx_wdt_ddata, wdd);
> +
> +	mod_timer(&ddata->timer, jiffies);
>   	return 0;
>   }
>
> @@ -134,16 +141,12 @@ static struct watchdog_ops mpc8xxx_wdt_ops = {
>   	.stop = mpc8xxx_wdt_stop,
>   };
>
> -static struct watchdog_device mpc8xxx_wdt_dev = {
> -	.info = &mpc8xxx_wdt_info,
> -	.ops = &mpc8xxx_wdt_ops,
> -};
> -
>   static int mpc8xxx_wdt_probe(struct platform_device *ofdev)
>   {
>   	int ret;
>   	struct resource *res;
>   	const struct mpc8xxx_wdt_type *wdt_type;
> +	struct mpc8xxx_wdt_ddata *ddata;
>   	u32 freq = fsl_get_sys_freq();
>   	bool enabled;
>   	unsigned int timeout_sec;
> @@ -155,25 +158,36 @@ static int mpc8xxx_wdt_probe(struct platform_device *ofdev)
>   	if (!freq || freq == -1)
>   		return -EINVAL;
>
> +	ddata = devm_kzalloc(&ofdev->dev, sizeof(*ddata), GFP_KERNEL);
> +	if (!ddata)
> +		return -ENOMEM;
> +
>   	res = platform_get_resource(ofdev, IORESOURCE_MEM, 0);
> -	wd_base = devm_ioremap_resource(&ofdev->dev, res);
> -	if (IS_ERR(wd_base))
> -		return PTR_ERR(wd_base);
> +	ddata->base = devm_ioremap_resource(&ofdev->dev, res);
> +	if (IS_ERR(ddata->base))
> +		return PTR_ERR(ddata->base);
>
> -	enabled = in_be32(&wd_base->swcrr) & SWCRR_SWEN;
> +	enabled = in_be32(&ddata->base->swcrr) & SWCRR_SWEN;
>   	if (!enabled && wdt_type->hw_enabled) {
>   		pr_info("could not be enabled in software\n");
>   		return -ENOSYS;
>   	}
>
> +	spin_lock_init(&ddata->lock);
> +	setup_timer(&ddata->timer, mpc8xxx_wdt_timer_ping,
> +		    (unsigned long)ddata);
> +
> +	ddata->wdd.info = &mpc8xxx_wdt_info,
> +	ddata->wdd.ops = &mpc8xxx_wdt_ops,
> +
>   	/* Calculate the timeout in seconds */
>   	timeout_sec = (timeout * wdt_type->prescaler) / freq;
>
> -	mpc8xxx_wdt_dev.timeout = timeout_sec;
> +	ddata->wdd.timeout = timeout_sec;
>
> -	watchdog_set_nowayout(&mpc8xxx_wdt_dev, nowayout);
> +	watchdog_set_nowayout(&ddata->wdd, nowayout);
>
> -	ret = watchdog_register_device(&mpc8xxx_wdt_dev);
> +	ret = watchdog_register_device(&ddata->wdd);
>   	if (ret) {
>   		pr_err("cannot register watchdog device (err=%d)\n", ret);
>   		return ret;
> @@ -188,16 +202,20 @@ static int mpc8xxx_wdt_probe(struct platform_device *ofdev)
>   	 * userspace handles it.
>   	 */
>   	if (enabled)
> -		mod_timer(&wdt_timer, jiffies);
> +		mod_timer(&ddata->timer, jiffies);
> +
> +	platform_set_drvdata(ofdev, ddata);
>   	return 0;
>   }
>
>   static int mpc8xxx_wdt_remove(struct platform_device *ofdev)
>   {
> +	struct mpc8xxx_wdt_ddata *ddata = platform_get_drvdata(ofdev);
> +
>   	pr_crit("Watchdog removed, expect the %s soon!\n",
>   		reset ? "reset" : "machine check exception");
> -	del_timer_sync(&wdt_timer);
> -	watchdog_unregister_device(&mpc8xxx_wdt_dev);
> +	del_timer_sync(&ddata->timer);
> +	watchdog_unregister_device(&ddata->wdd);
>
>   	return 0;
>   }
>


  reply	other threads:[~2015-08-12 10:21 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-08-12  8:15 [PATCH v2 0/7] watchdog: mpc8xxx: several cleanups Uwe Kleine-König
2015-08-12  8:15 ` [PATCH v2 1/7] watchdog: mpc8xxx: remove dead code Uwe Kleine-König
2015-08-12  8:15 ` [PATCH v2 2/7] watchdog: mpc8xxx: simplify registration Uwe Kleine-König
2015-08-12  8:15 ` [PATCH v2 3/7] watchdog: mpc8xxx: make use of of_device_get_match_data Uwe Kleine-König
2015-08-12 10:16   ` Guenter Roeck
2015-08-12  8:15 ` [PATCH v2 4/7] watchdog: mpc8xxx: use devm_ioremap_resource to map memory Uwe Kleine-König
2015-08-12 10:18   ` Guenter Roeck
2015-08-12  8:15 ` [PATCH v2 5/7] watchdog: mpc8xxx: use dynamic memory for device specific data Uwe Kleine-König
2015-08-12 10:21   ` Guenter Roeck [this message]
2015-08-12  8:15 ` [PATCH v2 6/7] watchdog: mpc8xxx: use better error code when watchdog cannot be enabled Uwe Kleine-König
2015-08-12 10:21   ` Guenter Roeck
2015-08-12  8:15 ` [PATCH v2 7/7] watchdog: mpc8xxx: allow to compile for MPC512x Uwe Kleine-König
2015-08-12 10:22   ` Guenter Roeck

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=55CB1E17.4080008@roeck-us.net \
    --to=linux@roeck-us.net \
    --cc=kernel@pengutronix.de \
    --cc=linux-watchdog@vger.kernel.org \
    --cc=u.kleine-koenig@pengutronix.de \
    --cc=wim@iguana.be \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.