Re: [PATCH] mmc: Handle suspend/resume in Ricoh MMC disabler (resentrefreshed)

From: Philip Langdale
Date: Mon Feb 04 2008 - 15:18:35 EST



On Mon, 4 Feb 2008 19:25:38 +0100, Frank Seidel <fseidel@xxxxxxx> wrote:
> From: Philip Langdale <philipl@xxxxxxxxx>
>
> As pci config space is reinitialised on suspend/resume cycle, the
> disabler needs to work its magic at resume time. For symmetry this
> change also explicitly enables the controller at suspend time but
> it's not strictly necessary.
>
> Signed-off-by: Philip Langdale <philipl@xxxxxxxxx>
> Signed-off-by: Frank Seidel <fseidel@xxxxxxx>
> ---
> drivers/mmc/host/ricoh_mmc.c | 97
> +++++++++++++++++++++++++++++++------------
> 1 file changed, 72 insertions(+), 25 deletions(-)
>
> --- a/drivers/mmc/host/ricoh_mmc.c
> +++ b/drivers/mmc/host/ricoh_mmc.c
> @@ -41,6 +41,46 @@ static const struct pci_device_id pci_id
>
> MODULE_DEVICE_TABLE(pci, pci_ids);
>
> +static int ricoh_mmc_disable(struct pci_dev *fw_dev)
> +{
> + u8 write_enable;
> + u8 disable;
> +
> + pci_read_config_byte(fw_dev, 0xCB, &disable);
> + if (disable & 0x02) {
> + printk(KERN_INFO DRIVER_NAME
> + ": Controller already disabled. Nothing to do.\n");
> + return -ENODEV;
> + }
> +
> + pci_read_config_byte(fw_dev, 0xCA, &write_enable);
> + pci_write_config_byte(fw_dev, 0xCA, 0x57);
> + pci_write_config_byte(fw_dev, 0xCB, disable | 0x02);
> + pci_write_config_byte(fw_dev, 0xCA, write_enable);
> +
> + printk(KERN_INFO DRIVER_NAME
> + ": Controller is now disabled.\n");
> +
> + return 0;
> +}
> +
> +static int ricoh_mmc_enable(struct pci_dev *fw_dev)
> +{
> + u8 write_enable;
> + u8 disable;
> +
> + pci_read_config_byte(fw_dev, 0xCA, &write_enable);
> + pci_read_config_byte(fw_dev, 0xCB, &disable);
> + pci_write_config_byte(fw_dev, 0xCA, 0x57);
> + pci_write_config_byte(fw_dev, 0xCB, disable & ~0x02);
> + pci_write_config_byte(fw_dev, 0xCA, write_enable);
> +
> + printk(KERN_INFO DRIVER_NAME
> + ": Controller is now re-enabled.\n");
> +
> + return 0;
> +}
> +
> static int __devinit ricoh_mmc_probe(struct pci_dev *pdev,
> const struct pci_device_id *ent)
> {
> @@ -61,26 +101,12 @@ static int __devinit ricoh_mmc_probe(str
> while ((fw_dev = pci_get_device(PCI_VENDOR_ID_RICOH,
> PCI_DEVICE_ID_RICOH_R5C832, fw_dev))) {
> if (PCI_SLOT(pdev->devfn) == PCI_SLOT(fw_dev->devfn) &&
> pdev->bus == fw_dev->bus) {
> - u8 write_enable;
> - u8 disable;
> -
> - pci_read_config_byte(fw_dev, 0xCB, &disable);
> - if (disable & 0x02) {
> - printk(KERN_INFO DRIVER_NAME
> - ": Controller already disabled. Nothing to do.\n");
> + if (ricoh_mmc_disable(fw_dev) != 0) {
> return -ENODEV;
> }
>
> - pci_read_config_byte(fw_dev, 0xCA, &write_enable);
> - pci_write_config_byte(fw_dev, 0xCA, 0x57);
> - pci_write_config_byte(fw_dev, 0xCB, disable | 0x02);
> - pci_write_config_byte(fw_dev, 0xCA, write_enable);
> -
> pci_set_drvdata(pdev, fw_dev);
>
> - printk(KERN_INFO DRIVER_NAME
> - ": Controller is now disabled.\n");
> -
> break;
> }
> }
> @@ -96,30 +122,51 @@ static int __devinit ricoh_mmc_probe(str
>
> static void __devexit ricoh_mmc_remove(struct pci_dev *pdev)
> {
> - u8 write_enable;
> - u8 disable;
> struct pci_dev *fw_dev = NULL;
>
> fw_dev = pci_get_drvdata(pdev);
> BUG_ON(fw_dev == NULL);
>
> - pci_read_config_byte(fw_dev, 0xCA, &write_enable);
> - pci_read_config_byte(fw_dev, 0xCB, &disable);
> - pci_write_config_byte(fw_dev, 0xCA, 0x57);
> - pci_write_config_byte(fw_dev, 0xCB, disable & ~0x02);
> - pci_write_config_byte(fw_dev, 0xCA, write_enable);
> -
> - printk(KERN_INFO DRIVER_NAME
> - ": Controller is now re-enabled.\n");
> + ricoh_mmc_enable(fw_dev);
>
> pci_set_drvdata(pdev, NULL);
> }
>
> +static int ricoh_mmc_suspend (struct pci_dev *pdev, pm_message_t state)
> +{
> + struct pci_dev *fw_dev = NULL;
> +
> + fw_dev = pci_get_drvdata(pdev);
> + BUG_ON(fw_dev == NULL);
> +
> + printk(KERN_INFO DRIVER_NAME ": Suspending.\n");
> +
> + ricoh_mmc_enable(fw_dev);
> +
> + return 0;
> +}
> +
> +static int ricoh_mmc_resume (struct pci_dev *pdev)
> +{
> + struct pci_dev *fw_dev = NULL;
> +
> + fw_dev = pci_get_drvdata(pdev);
> + BUG_ON(fw_dev == NULL);
> +
> + printk(KERN_INFO DRIVER_NAME ": Resuming.\n");
> +
> + ricoh_mmc_disable(fw_dev);
> +
> + return 0;
> +}
> +
> static struct pci_driver ricoh_mmc_driver = {
> .name = DRIVER_NAME,
> .id_table = pci_ids,
> .probe = ricoh_mmc_probe,
> .remove = __devexit_p(ricoh_mmc_remove),
> + .suspend = ricoh_mmc_suspend,
> + .resume = ricoh_mmc_resume,
> };
>
>
>
/*****************************************************************************\

ACK.

Thanks for fixing it up.

--phil

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/