Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

x86: OLPC: convert olpc-xo1 driver from pci device to platform device

The cs5535-mfd driver now takes care of the PCI BAR handling; this
means the olpc-xo1 driver shouldn't be touching the PCI device at all.

This patch uses both cs5535-acpi and cs5535-pms platform devices rather
than a single platform device because the cs5535-mfd driver may be used
by other CS5535 platform-specific drivers; OLPC doesn't get to dictate
that ACPI and PMS will always be used together.

Signed-off-by: Andres Salomon <dilinger@queued.net>
Acked-by: H. Peter Anvin <hpa@zytor.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>

authored by

Andres Salomon and committed by
Samuel Ortiz
419cdc54 cdd137c9

+59 -50
+1 -1
arch/x86/Kconfig
··· 2068 2068 2069 2069 config OLPC_XO1 2070 2070 tristate "OLPC XO-1 support" 2071 - depends on OLPC && PCI 2071 + depends on OLPC && MFD_CS5535 2072 2072 ---help--- 2073 2073 Add support for non-essential features of the OLPC XO-1 laptop. 2074 2074
+58 -49
arch/x86/platform/olpc/olpc-xo1.c
··· 1 1 /* 2 2 * Support for features of the OLPC XO-1 laptop 3 3 * 4 + * Copyright (C) 2010 Andres Salomon <dilinger@queued.net> 4 5 * Copyright (C) 2010 One Laptop per Child 5 6 * Copyright (C) 2006 Red Hat, Inc. 6 7 * Copyright (C) 2006 Advanced Micro Devices, Inc. ··· 13 12 */ 14 13 15 14 #include <linux/module.h> 16 - #include <linux/pci.h> 17 - #include <linux/pci_ids.h> 18 15 #include <linux/platform_device.h> 19 16 #include <linux/pm.h> 20 17 ··· 20 21 #include <asm/olpc.h> 21 22 22 23 #define DRV_NAME "olpc-xo1" 23 - 24 - #define PMS_BAR 4 25 - #define ACPI_BAR 5 26 24 27 25 /* PMC registers (PMS block) */ 28 26 #define PM_SCLK 0x10 ··· 53 57 outl(0x00002000, acpi_base + PM1_CNT); 54 58 } 55 59 56 - /* Read the base addresses from the PCI BAR info */ 57 - static int __devinit setup_bases(struct pci_dev *pdev) 58 - { 59 - int r; 60 - 61 - r = pci_enable_device_io(pdev); 62 - if (r) { 63 - dev_err(&pdev->dev, "can't enable device IO\n"); 64 - return r; 65 - } 66 - 67 - r = pci_request_region(pdev, ACPI_BAR, DRV_NAME); 68 - if (r) { 69 - dev_err(&pdev->dev, "can't alloc PCI BAR #%d\n", ACPI_BAR); 70 - return r; 71 - } 72 - 73 - r = pci_request_region(pdev, PMS_BAR, DRV_NAME); 74 - if (r) { 75 - dev_err(&pdev->dev, "can't alloc PCI BAR #%d\n", PMS_BAR); 76 - pci_release_region(pdev, ACPI_BAR); 77 - return r; 78 - } 79 - 80 - acpi_base = pci_resource_start(pdev, ACPI_BAR); 81 - pms_base = pci_resource_start(pdev, PMS_BAR); 82 - 83 - return 0; 84 - } 85 - 86 60 static int __devinit olpc_xo1_probe(struct platform_device *pdev) 87 61 { 88 - struct pci_dev *pcidev; 89 - int r; 62 + struct resource *res; 90 63 91 - pcidev = pci_get_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA, 92 - NULL); 93 - if (!pdev) 64 + /* don't run on non-XOs */ 65 + if (!machine_is_olpc()) 94 66 return -ENODEV; 95 67 96 - r = setup_bases(pcidev); 97 - if (r) 98 - return r; 68 + res = platform_get_resource(pdev, IORESOURCE_IO, 0); 69 + if (!res) { 70 + dev_err(&pdev->dev, "can't fetch device resource info\n"); 71 + return -EIO; 72 + } 99 73 100 - pm_power_off = xo1_power_off; 74 + if (!request_region(res->start, resource_size(res), DRV_NAME)) { 75 + dev_err(&pdev->dev, "can't request region\n"); 76 + return -EIO; 77 + } 101 78 102 - printk(KERN_INFO "OLPC XO-1 support registered\n"); 79 + if (strcmp(pdev->name, "cs5535-pms") == 0) 80 + pms_base = res->start; 81 + else if (strcmp(pdev->name, "cs5535-acpi") == 0) 82 + acpi_base = res->start; 83 + 84 + /* If we have both addresses, we can override the poweroff hook */ 85 + if (pms_base && acpi_base) { 86 + pm_power_off = xo1_power_off; 87 + printk(KERN_INFO "OLPC XO-1 support registered\n"); 88 + } 89 + 103 90 return 0; 104 91 } 105 92 106 93 static int __devexit olpc_xo1_remove(struct platform_device *pdev) 107 94 { 95 + struct resource *r; 96 + 97 + r = platform_get_resource(pdev, IORESOURCE_IO, 0); 98 + release_region(r->start, resource_size(r)); 99 + 100 + if (strcmp(pdev->name, "cs5535-pms") == 0) 101 + pms_base = 0; 102 + else if (strcmp(pdev->name, "cs5535-acpi") == 0) 103 + acpi_base = 0; 104 + 108 105 pm_power_off = NULL; 109 106 return 0; 110 107 } 111 108 112 - static struct platform_driver olpc_xo1_driver = { 109 + static struct platform_driver cs5535_pms_drv = { 113 110 .driver = { 114 - .name = DRV_NAME, 111 + .name = "cs5535-pms", 112 + .owner = THIS_MODULE, 113 + }, 114 + .probe = olpc_xo1_probe, 115 + .remove = __devexit_p(olpc_xo1_remove), 116 + }; 117 + 118 + static struct platform_driver cs5535_acpi_drv = { 119 + .driver = { 120 + .name = "cs5535-acpi", 115 121 .owner = THIS_MODULE, 116 122 }, 117 123 .probe = olpc_xo1_probe, ··· 122 124 123 125 static int __init olpc_xo1_init(void) 124 126 { 125 - return platform_driver_register(&olpc_xo1_driver); 127 + int r; 128 + 129 + r = platform_driver_register(&cs5535_pms_drv); 130 + if (r) 131 + return r; 132 + 133 + r = platform_driver_register(&cs5535_acpi_drv); 134 + if (r) 135 + platform_driver_unregister(&cs5535_pms_drv); 136 + 137 + return r; 126 138 } 127 139 128 140 static void __exit olpc_xo1_exit(void) 129 141 { 130 - platform_driver_unregister(&olpc_xo1_driver); 142 + platform_driver_unregister(&cs5535_acpi_drv); 143 + platform_driver_unregister(&cs5535_pms_drv); 131 144 } 132 145 133 146 MODULE_AUTHOR("Daniel Drake <dsd@laptop.org>");