diff options
Diffstat (limited to 'drivers/rtc/rtc-ep93xx.c')
| -rw-r--r-- | drivers/rtc/rtc-ep93xx.c | 72 |
1 files changed, 29 insertions, 43 deletions
diff --git a/drivers/rtc/rtc-ep93xx.c b/drivers/rtc/rtc-ep93xx.c index 9da02d108b73..11ae64dcbf3c 100644 --- a/drivers/rtc/rtc-ep93xx.c +++ b/drivers/rtc/rtc-ep93xx.c | |||
| @@ -13,6 +13,7 @@ | |||
| 13 | #include <linux/rtc.h> | 13 | #include <linux/rtc.h> |
| 14 | #include <linux/platform_device.h> | 14 | #include <linux/platform_device.h> |
| 15 | #include <linux/io.h> | 15 | #include <linux/io.h> |
| 16 | #include <linux/gfp.h> | ||
| 16 | 17 | ||
| 17 | #define EP93XX_RTC_DATA 0x000 | 18 | #define EP93XX_RTC_DATA 0x000 |
| 18 | #define EP93XX_RTC_MATCH 0x004 | 19 | #define EP93XX_RTC_MATCH 0x004 |
| @@ -115,6 +116,15 @@ static ssize_t ep93xx_rtc_show_comp_delete(struct device *dev, | |||
| 115 | } | 116 | } |
| 116 | static DEVICE_ATTR(comp_delete, S_IRUGO, ep93xx_rtc_show_comp_delete, NULL); | 117 | static DEVICE_ATTR(comp_delete, S_IRUGO, ep93xx_rtc_show_comp_delete, NULL); |
| 117 | 118 | ||
| 119 | static struct attribute *ep93xx_rtc_attrs[] = { | ||
| 120 | &dev_attr_comp_preload.attr, | ||
| 121 | &dev_attr_comp_delete.attr, | ||
| 122 | NULL | ||
| 123 | }; | ||
| 124 | |||
| 125 | static const struct attribute_group ep93xx_rtc_sysfs_files = { | ||
| 126 | .attrs = ep93xx_rtc_attrs, | ||
| 127 | }; | ||
| 118 | 128 | ||
| 119 | static int __init ep93xx_rtc_probe(struct platform_device *pdev) | 129 | static int __init ep93xx_rtc_probe(struct platform_device *pdev) |
| 120 | { | 130 | { |
| @@ -123,27 +133,22 @@ static int __init ep93xx_rtc_probe(struct platform_device *pdev) | |||
| 123 | struct rtc_device *rtc; | 133 | struct rtc_device *rtc; |
| 124 | int err; | 134 | int err; |
| 125 | 135 | ||
| 126 | ep93xx_rtc = kzalloc(sizeof(struct ep93xx_rtc), GFP_KERNEL); | 136 | ep93xx_rtc = devm_kzalloc(&pdev->dev, sizeof(*ep93xx_rtc), GFP_KERNEL); |
| 127 | if (ep93xx_rtc == NULL) | 137 | if (!ep93xx_rtc) |
| 128 | return -ENOMEM; | 138 | return -ENOMEM; |
| 129 | 139 | ||
| 130 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 140 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 131 | if (res == NULL) { | 141 | if (!res) |
| 132 | err = -ENXIO; | 142 | return -ENXIO; |
| 133 | goto fail_free; | ||
| 134 | } | ||
| 135 | 143 | ||
| 136 | res = request_mem_region(res->start, resource_size(res), pdev->name); | 144 | if (!devm_request_mem_region(&pdev->dev, res->start, |
| 137 | if (res == NULL) { | 145 | resource_size(res), pdev->name)) |
| 138 | err = -EBUSY; | 146 | return -EBUSY; |
| 139 | goto fail_free; | ||
| 140 | } | ||
| 141 | 147 | ||
| 142 | ep93xx_rtc->mmio_base = ioremap(res->start, resource_size(res)); | 148 | ep93xx_rtc->mmio_base = devm_ioremap(&pdev->dev, res->start, |
| 143 | if (ep93xx_rtc->mmio_base == NULL) { | 149 | resource_size(res)); |
| 144 | err = -ENXIO; | 150 | if (!ep93xx_rtc->mmio_base) |
| 145 | goto fail; | 151 | return -ENXIO; |
| 146 | } | ||
| 147 | 152 | ||
| 148 | pdev->dev.platform_data = ep93xx_rtc; | 153 | pdev->dev.platform_data = ep93xx_rtc; |
| 149 | 154 | ||
| @@ -151,53 +156,34 @@ static int __init ep93xx_rtc_probe(struct platform_device *pdev) | |||
| 151 | &pdev->dev, &ep93xx_rtc_ops, THIS_MODULE); | 156 | &pdev->dev, &ep93xx_rtc_ops, THIS_MODULE); |
| 152 | if (IS_ERR(rtc)) { | 157 | if (IS_ERR(rtc)) { |
| 153 | err = PTR_ERR(rtc); | 158 | err = PTR_ERR(rtc); |
| 154 | goto fail; | 159 | goto exit; |
| 155 | } | 160 | } |
| 156 | 161 | ||
| 157 | platform_set_drvdata(pdev, rtc); | 162 | platform_set_drvdata(pdev, rtc); |
| 158 | 163 | ||
| 159 | err = device_create_file(&pdev->dev, &dev_attr_comp_preload); | 164 | err = sysfs_create_group(&pdev->dev.kobj, &ep93xx_rtc_sysfs_files); |
| 160 | if (err) | 165 | if (err) |
| 161 | goto fail; | 166 | goto fail; |
| 162 | err = device_create_file(&pdev->dev, &dev_attr_comp_delete); | ||
| 163 | if (err) { | ||
| 164 | device_remove_file(&pdev->dev, &dev_attr_comp_preload); | ||
| 165 | goto fail; | ||
| 166 | } | ||
| 167 | 167 | ||
| 168 | return 0; | 168 | return 0; |
| 169 | 169 | ||
| 170 | fail: | 170 | fail: |
| 171 | if (ep93xx_rtc->mmio_base) { | 171 | platform_set_drvdata(pdev, NULL); |
| 172 | iounmap(ep93xx_rtc->mmio_base); | 172 | rtc_device_unregister(rtc); |
| 173 | pdev->dev.platform_data = NULL; | 173 | exit: |
| 174 | } | 174 | pdev->dev.platform_data = NULL; |
| 175 | release_mem_region(res->start, resource_size(res)); | ||
| 176 | fail_free: | ||
| 177 | kfree(ep93xx_rtc); | ||
| 178 | return err; | 175 | return err; |
| 179 | } | 176 | } |
| 180 | 177 | ||
| 181 | static int __exit ep93xx_rtc_remove(struct platform_device *pdev) | 178 | static int __exit ep93xx_rtc_remove(struct platform_device *pdev) |
| 182 | { | 179 | { |
| 183 | struct rtc_device *rtc = platform_get_drvdata(pdev); | 180 | struct rtc_device *rtc = platform_get_drvdata(pdev); |
| 184 | struct ep93xx_rtc *ep93xx_rtc = pdev->dev.platform_data; | ||
| 185 | struct resource *res; | ||
| 186 | |||
| 187 | /* cleanup sysfs */ | ||
| 188 | device_remove_file(&pdev->dev, &dev_attr_comp_delete); | ||
| 189 | device_remove_file(&pdev->dev, &dev_attr_comp_preload); | ||
| 190 | 181 | ||
| 182 | sysfs_remove_group(&pdev->dev.kobj, &ep93xx_rtc_sysfs_files); | ||
| 183 | platform_set_drvdata(pdev, NULL); | ||
| 191 | rtc_device_unregister(rtc); | 184 | rtc_device_unregister(rtc); |
| 192 | |||
| 193 | iounmap(ep93xx_rtc->mmio_base); | ||
| 194 | pdev->dev.platform_data = NULL; | 185 | pdev->dev.platform_data = NULL; |
| 195 | 186 | ||
| 196 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 197 | release_mem_region(res->start, resource_size(res)); | ||
| 198 | |||
| 199 | platform_set_drvdata(pdev, NULL); | ||
| 200 | |||
| 201 | return 0; | 187 | return 0; |
| 202 | } | 188 | } |
| 203 | 189 | ||
