From patchwork Thu Feb 11 19:48:10 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jason Gunthorpe X-Patchwork-Id: 582019 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.sourceforge.net (lists.sourceforge.net [216.34.181.88]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id F1BC5140C73 for ; Fri, 12 Feb 2016 06:48:31 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=sfs-ml-3.v29.ch3.sourceforge.com) by sfs-ml-3.v29.ch3.sourceforge.com with esmtp (Exim 4.76) (envelope-from ) id 1aTxE4-0001FD-Jj; Thu, 11 Feb 2016 19:48:28 +0000 Received: from sog-mx-4.v43.ch3.sourceforge.com ([172.29.43.194] helo=mx.sourceforge.net) by sfs-ml-3.v29.ch3.sourceforge.com with esmtp (Exim 4.76) (envelope-from ) id 1aTxE3-0001F8-Pl for tpmdd-devel@lists.sourceforge.net; Thu, 11 Feb 2016 19:48:27 +0000 Received-SPF: pass (sog-mx-4.v43.ch3.sourceforge.com: domain of obsidianresearch.com designates 184.70.90.242 as permitted sender) client-ip=184.70.90.242; envelope-from=jgunthorpe@obsidianresearch.com; helo=quartz.orcorp.ca; Received: from quartz.orcorp.ca ([184.70.90.242]) by sog-mx-4.v43.ch3.sourceforge.com with esmtps (TLSv1:AES128-SHA:128) (Exim 4.76) id 1aTxE2-0001fB-PU for tpmdd-devel@lists.sourceforge.net; Thu, 11 Feb 2016 19:48:27 +0000 Received: from [10.0.0.160] (helo=jggl.edm.orcorp.ca) by quartz.orcorp.ca with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.84) (envelope-from ) id 1aTxDm-0000d7-Ft; Thu, 11 Feb 2016 12:48:10 -0700 Received: from jgg by jggl.edm.orcorp.ca with local (Exim 4.84) (envelope-from ) id 1aTxDm-0002Gn-CK; Thu, 11 Feb 2016 12:48:10 -0700 Date: Thu, 11 Feb 2016 12:48:10 -0700 From: Jason Gunthorpe To: Stefan Berger Message-ID: <20160211194810.GA24211@obsidianresearch.com> References: <20160210035620.GB7161@intel.com> <201602100515.u1A5FpFi002736@d03av02.boulder.ibm.com> <20160210162809.GB20730@obsidianresearch.com> <201602102145.u1ALjSAs001597@d03av04.boulder.ibm.com> <20160210222313.GA7047@obsidianresearch.com> <201602110038.u1B0cuE0030670@d03av05.boulder.ibm.com> <20160211070426.GB9307@intel.com> <201602111534.u1BFYvRs019573@d01av03.pok.ibm.com> <20160211181208.GA6285@obsidianresearch.com> <201602111911.u1BJB2nK017410@d01av03.pok.ibm.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <201602111911.u1BJB2nK017410@d01av03.pok.ibm.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-Broken-Reverse-DNS: no host name found for IP address 10.0.0.160 X-Spam-Score: -1.4 (-) X-Spam-Report: Spam Filtering performed by mx.sourceforge.net. See http://spamassassin.org/tag/ for more details. -1.5 SPF_CHECK_PASS SPF reports sender host as permitted sender for sender-domain -0.0 SPF_HELO_PASS SPF: HELO matches SPF record -0.0 SPF_PASS SPF: sender matches SPF record -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature 0.2 AWL AWL: Adjusted score from AWL reputation of From: address X-Headers-End: 1aTxE2-0001fB-PU Cc: dhowells@redhat.com, tpmdd-devel@lists.sourceforge.net, dwmw2@infradead.org Subject: Re: [tpmdd-devel] [PATCH v5 4/5] Initialize TPM and get durations and timeouts X-BeenThere: tpmdd-devel@lists.sourceforge.net X-Mailman-Version: 2.1.9 Precedence: list List-Id: Tpm Device Driver maintainance List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: tpmdd-devel-bounces@lists.sourceforge.net On Thu, Feb 11, 2016 at 02:10:56PM -0500, Stefan Berger wrote: > > Make sense. Don't change the names all the drivers would have to be > > churn'd. tpm_chip_alloc, tpmm_chip_alloc. > > > That's right: > struct tpm_chip *tpmm_chip_alloc(struct device *dev, > const struct tpm_class_ops *ops) > { > struct tpm_chip *chip; > chip = tpm_chip_alloc(ops); > if (IS_ERR(chip)) > return chip; > tpmm_chip_dev(chip, dev); No, just call the one devm_ function here (Based this work on top of Jarkko's patch that adds the devm function) > > It is probably OK just to use put_device(&chip->dev), tpm_chip_put is > > already taken for something else. Don't call it free, it isn't free. > tpm_chip_free undoes what tpm_chip_alloc did. No, once a chip is created we want the kref to be functional, that means it can only ever be free'd by put_device. Do not create a tpm_chip_free. > * Allocates a new struct tpm_chip instance and assigns a free > * device number for it. > */ > struct tpm_chip *tpm_chip_alloc(const struct tpm_class_ops *ops) > { > struct tpm_chip *chip; > chip = kzalloc(sizeof(*chip), GFP_KERNEL); > if (chip == NULL) > return ERR_PTR(-ENOMEM); I see, why you got confused - don't try and remove device_initialize, it doesn't care about the parent pointer. Move the dev_set_drvdata into tpmm_chip_alloc Move the cdev.owner to before cdev_add A tpm_chip should never be in a state where the kref doesn't work. Something like this [be careful merging this on top of Jarkko's final patch adding the devm call]. pdev could even be passed as null for tpm_chip_alloc, as long as it is properly set before registration, but I'd probably init you vtpm device, then alloc the chip copy the id, then register the vtpm. >From 4b1b31c351f838d608644660eb178b4c1f92bb7c Mon Sep 17 00:00:00 2001 From: Jason Gunthorpe Date: Thu, 11 Feb 2016 12:45:48 -0700 Subject: [PATCH] tpm: Split out the devm stuff from tpmm_chip_alloc tpm_chip_alloc becomes a typical subsystem allocate call. Signed-off-by: Jason Gunthorpe --- drivers/char/tpm/tpm-chip.c | 46 +++++++++++++++++++++++++++++++++++---------- drivers/char/tpm/tpm.h | 2 ++ 2 files changed, 38 insertions(+), 10 deletions(-) diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c index 999cbd9b388c..8134003b023c 100644 --- a/drivers/char/tpm/tpm-chip.c +++ b/drivers/char/tpm/tpm-chip.c @@ -77,15 +77,15 @@ static void tpm_dev_release(struct device *dev) /** * tpmm_chip_alloc() - allocate a new struct tpm_chip instance * @dev: device to which the chip is associated + * At this point pdev must be initalized, but does not have to be + * registered. * @ops: struct tpm_class_ops instance * * Allocates a new struct tpm_chip instance and assigns a free - * device number for it. Caller does not have to worry about - * freeing the allocated resources. When the devices is removed - * devres calls tpmm_chip_remove() to do the job. + * device number for it. Must be pair'd with put_device(&chip->dev). */ -struct tpm_chip *tpmm_chip_alloc(struct device *dev, - const struct tpm_class_ops *ops) +struct tpm_chip *tpm_chip_alloc(struct device *dev, + const struct tpm_class_ops *ops) { struct tpm_chip *chip; @@ -109,13 +109,12 @@ struct tpm_chip *tpmm_chip_alloc(struct device *dev, } set_bit(chip->dev_num, dev_mask); + device_initialize(&chip->dev); scnprintf(chip->devname, sizeof(chip->devname), "tpm%d", chip->dev_num); chip->pdev = dev; - dev_set_drvdata(dev, chip); - chip->dev.class = tpm_class; chip->dev.release = tpm_dev_release; chip->dev.parent = chip->pdev; @@ -130,20 +129,47 @@ struct tpm_chip *tpmm_chip_alloc(struct device *dev, dev_set_name(&chip->dev, "%s", chip->devname); - device_initialize(&chip->dev); - cdev_init(&chip->cdev, &tpm_fops); - chip->cdev.owner = chip->pdev->driver->owner; chip->cdev.kobj.parent = &chip->dev.kobj; return chip; } +EXPORT_SYMBOL_GPL(tpm_chip_alloc); + +/** + * tpmm_chip_alloc() - allocate a new struct tpm_chip instance + * @dev: device to which the chip is associated + * Must be fully registered and able to handle devm. + * @ops: struct tpm_class_ops instance + * + * Same as tpm_chip_alloc except devm is used to do the put_device + */ +struct tpm_chip *tpmm_chip_alloc(struct device *pdev, + const struct tpm_class_ops *ops) +{ + struct tpm_chip *chip; + int rc; + + chip = tpm_chip_alloc(pdev, ops); + if (IS_ERR(chip)) + return chip; + rc = devm_add_action(pdev, (void (*)(void *)) put_device, &chip->dev); + if (rc) { + put_device(&chip->dev); + return ERR_PTR(rc); + } + + dev_set_drvdata(pdev, chip); + + return chip; +} EXPORT_SYMBOL_GPL(tpmm_chip_alloc); static int tpm_dev_add_device(struct tpm_chip *chip) { int rc; + chip->cdev.owner = chip->pdev->driver->owner; rc = cdev_add(&chip->cdev, chip->dev.devt, 1); if (rc) { dev_err(&chip->dev, diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h index 2fd5ee2ed7ad..3a5452f09b96 100644 --- a/drivers/char/tpm/tpm.h +++ b/drivers/char/tpm/tpm.h @@ -508,6 +508,8 @@ extern int wait_for_tpm_stat(struct tpm_chip *, u8, unsigned long, wait_queue_head_t *, bool); struct tpm_chip *tpm_chip_find_get(int chip_num); +extern struct tpm_chip *tpm_chip_alloc(struct device *dev, + const struct tpm_class_ops *ops); extern struct tpm_chip *tpmm_chip_alloc(struct device *dev, const struct tpm_class_ops *ops); extern int tpm_chip_register(struct tpm_chip *chip);