mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-11-25 19:11:02 +07:00
mmc: refactor host class handling
Move basic host class device handling to its own file for clarity. Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>
This commit is contained in:
parent
4101c16a91
commit
b93931a61a
@ -7,6 +7,6 @@ ifeq ($(CONFIG_MMC_DEBUG),y)
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
obj-$(CONFIG_MMC) += mmc_core.o
|
obj-$(CONFIG_MMC) += mmc_core.o
|
||||||
mmc_core-y := core.o sysfs.o bus.o \
|
mmc_core-y := core.o sysfs.o bus.o host.o \
|
||||||
mmc.o mmc_ops.o sd.o sd_ops.o
|
mmc.o mmc_ops.o sd.o sd_ops.o
|
||||||
|
|
||||||
|
@ -496,7 +496,7 @@ void mmc_detect_change(struct mmc_host *host, unsigned long delay)
|
|||||||
EXPORT_SYMBOL(mmc_detect_change);
|
EXPORT_SYMBOL(mmc_detect_change);
|
||||||
|
|
||||||
|
|
||||||
static void mmc_rescan(struct work_struct *work)
|
void mmc_rescan(struct work_struct *work)
|
||||||
{
|
{
|
||||||
struct mmc_host *host =
|
struct mmc_host *host =
|
||||||
container_of(work, struct mmc_host, detect.work);
|
container_of(work, struct mmc_host, detect.work);
|
||||||
@ -545,69 +545,13 @@ static void mmc_rescan(struct work_struct *work)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void mmc_start_host(struct mmc_host *host)
|
||||||
/**
|
|
||||||
* mmc_alloc_host - initialise the per-host structure.
|
|
||||||
* @extra: sizeof private data structure
|
|
||||||
* @dev: pointer to host device model structure
|
|
||||||
*
|
|
||||||
* Initialise the per-host structure.
|
|
||||||
*/
|
|
||||||
struct mmc_host *mmc_alloc_host(int extra, struct device *dev)
|
|
||||||
{
|
{
|
||||||
struct mmc_host *host;
|
mmc_power_off(host);
|
||||||
|
mmc_detect_change(host, 0);
|
||||||
host = mmc_alloc_host_sysfs(extra, dev);
|
|
||||||
if (host) {
|
|
||||||
spin_lock_init(&host->lock);
|
|
||||||
init_waitqueue_head(&host->wq);
|
|
||||||
INIT_DELAYED_WORK(&host->detect, mmc_rescan);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* By default, hosts do not support SGIO or large requests.
|
|
||||||
* They have to set these according to their abilities.
|
|
||||||
*/
|
|
||||||
host->max_hw_segs = 1;
|
|
||||||
host->max_phys_segs = 1;
|
|
||||||
host->max_seg_size = PAGE_CACHE_SIZE;
|
|
||||||
|
|
||||||
host->max_req_size = PAGE_CACHE_SIZE;
|
|
||||||
host->max_blk_size = 512;
|
|
||||||
host->max_blk_count = PAGE_CACHE_SIZE / 512;
|
|
||||||
}
|
|
||||||
|
|
||||||
return host;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT_SYMBOL(mmc_alloc_host);
|
void mmc_stop_host(struct mmc_host *host)
|
||||||
|
|
||||||
/**
|
|
||||||
* mmc_add_host - initialise host hardware
|
|
||||||
* @host: mmc host
|
|
||||||
*/
|
|
||||||
int mmc_add_host(struct mmc_host *host)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = mmc_add_host_sysfs(host);
|
|
||||||
if (ret == 0) {
|
|
||||||
mmc_power_off(host);
|
|
||||||
mmc_detect_change(host, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
EXPORT_SYMBOL(mmc_add_host);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* mmc_remove_host - remove host hardware
|
|
||||||
* @host: mmc host
|
|
||||||
*
|
|
||||||
* Unregister and remove all cards associated with this host,
|
|
||||||
* and power down the MMC bus.
|
|
||||||
*/
|
|
||||||
void mmc_remove_host(struct mmc_host *host)
|
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_MMC_DEBUG
|
#ifdef CONFIG_MMC_DEBUG
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
@ -632,24 +576,8 @@ void mmc_remove_host(struct mmc_host *host)
|
|||||||
BUG_ON(host->card);
|
BUG_ON(host->card);
|
||||||
|
|
||||||
mmc_power_off(host);
|
mmc_power_off(host);
|
||||||
mmc_remove_host_sysfs(host);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT_SYMBOL(mmc_remove_host);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* mmc_free_host - free the host structure
|
|
||||||
* @host: mmc host
|
|
||||||
*
|
|
||||||
* Free the host once all references to it have been dropped.
|
|
||||||
*/
|
|
||||||
void mmc_free_host(struct mmc_host *host)
|
|
||||||
{
|
|
||||||
mmc_free_host_sysfs(host);
|
|
||||||
}
|
|
||||||
|
|
||||||
EXPORT_SYMBOL(mmc_free_host);
|
|
||||||
|
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -66,5 +66,9 @@ static inline void mmc_delay(unsigned int ms)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void mmc_rescan(struct work_struct *work);
|
||||||
|
void mmc_start_host(struct mmc_host *host);
|
||||||
|
void mmc_stop_host(struct mmc_host *host);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
156
drivers/mmc/core/host.c
Normal file
156
drivers/mmc/core/host.c
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
/*
|
||||||
|
* linux/drivers/mmc/core/host.c
|
||||||
|
*
|
||||||
|
* Copyright (C) 2003 Russell King, All Rights Reserved.
|
||||||
|
* Copyright (C) 2007 Pierre Ossman
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* MMC host class device management
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/device.h>
|
||||||
|
#include <linux/err.h>
|
||||||
|
#include <linux/idr.h>
|
||||||
|
#include <linux/pagemap.h>
|
||||||
|
|
||||||
|
#include <linux/mmc/host.h>
|
||||||
|
|
||||||
|
#include "core.h"
|
||||||
|
#include "host.h"
|
||||||
|
|
||||||
|
#define cls_dev_to_mmc_host(d) container_of(d, struct mmc_host, class_dev)
|
||||||
|
|
||||||
|
static void mmc_host_classdev_release(struct device *dev)
|
||||||
|
{
|
||||||
|
struct mmc_host *host = cls_dev_to_mmc_host(dev);
|
||||||
|
kfree(host);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct class mmc_host_class = {
|
||||||
|
.name = "mmc_host",
|
||||||
|
.dev_release = mmc_host_classdev_release,
|
||||||
|
};
|
||||||
|
|
||||||
|
int mmc_register_host_class(void)
|
||||||
|
{
|
||||||
|
return class_register(&mmc_host_class);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mmc_unregister_host_class(void)
|
||||||
|
{
|
||||||
|
class_unregister(&mmc_host_class);
|
||||||
|
}
|
||||||
|
|
||||||
|
static DEFINE_IDR(mmc_host_idr);
|
||||||
|
static DEFINE_SPINLOCK(mmc_host_lock);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mmc_alloc_host - initialise the per-host structure.
|
||||||
|
* @extra: sizeof private data structure
|
||||||
|
* @dev: pointer to host device model structure
|
||||||
|
*
|
||||||
|
* Initialise the per-host structure.
|
||||||
|
*/
|
||||||
|
struct mmc_host *mmc_alloc_host(int extra, struct device *dev)
|
||||||
|
{
|
||||||
|
struct mmc_host *host;
|
||||||
|
|
||||||
|
host = kmalloc(sizeof(struct mmc_host) + extra, GFP_KERNEL);
|
||||||
|
if (!host)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
memset(host, 0, sizeof(struct mmc_host) + extra);
|
||||||
|
|
||||||
|
host->parent = dev;
|
||||||
|
host->class_dev.parent = dev;
|
||||||
|
host->class_dev.class = &mmc_host_class;
|
||||||
|
device_initialize(&host->class_dev);
|
||||||
|
|
||||||
|
spin_lock_init(&host->lock);
|
||||||
|
init_waitqueue_head(&host->wq);
|
||||||
|
INIT_DELAYED_WORK(&host->detect, mmc_rescan);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* By default, hosts do not support SGIO or large requests.
|
||||||
|
* They have to set these according to their abilities.
|
||||||
|
*/
|
||||||
|
host->max_hw_segs = 1;
|
||||||
|
host->max_phys_segs = 1;
|
||||||
|
host->max_seg_size = PAGE_CACHE_SIZE;
|
||||||
|
|
||||||
|
host->max_req_size = PAGE_CACHE_SIZE;
|
||||||
|
host->max_blk_size = 512;
|
||||||
|
host->max_blk_count = PAGE_CACHE_SIZE / 512;
|
||||||
|
|
||||||
|
return host;
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPORT_SYMBOL(mmc_alloc_host);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mmc_add_host - initialise host hardware
|
||||||
|
* @host: mmc host
|
||||||
|
*/
|
||||||
|
int mmc_add_host(struct mmc_host *host)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if (!idr_pre_get(&mmc_host_idr, GFP_KERNEL))
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
spin_lock(&mmc_host_lock);
|
||||||
|
err = idr_get_new(&mmc_host_idr, host, &host->index);
|
||||||
|
spin_unlock(&mmc_host_lock);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
snprintf(host->class_dev.bus_id, BUS_ID_SIZE,
|
||||||
|
"mmc%d", host->index);
|
||||||
|
|
||||||
|
err = device_add(&host->class_dev);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
mmc_start_host(host);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPORT_SYMBOL(mmc_add_host);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mmc_remove_host - remove host hardware
|
||||||
|
* @host: mmc host
|
||||||
|
*
|
||||||
|
* Unregister and remove all cards associated with this host,
|
||||||
|
* and power down the MMC bus.
|
||||||
|
*/
|
||||||
|
void mmc_remove_host(struct mmc_host *host)
|
||||||
|
{
|
||||||
|
mmc_stop_host(host);
|
||||||
|
|
||||||
|
device_del(&host->class_dev);
|
||||||
|
|
||||||
|
spin_lock(&mmc_host_lock);
|
||||||
|
idr_remove(&mmc_host_idr, host->index);
|
||||||
|
spin_unlock(&mmc_host_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPORT_SYMBOL(mmc_remove_host);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mmc_free_host - free the host structure
|
||||||
|
* @host: mmc host
|
||||||
|
*
|
||||||
|
* Free the host once all references to it have been dropped.
|
||||||
|
*/
|
||||||
|
void mmc_free_host(struct mmc_host *host)
|
||||||
|
{
|
||||||
|
put_device(&host->class_dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPORT_SYMBOL(mmc_free_host);
|
||||||
|
|
18
drivers/mmc/core/host.h
Normal file
18
drivers/mmc/core/host.h
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
/*
|
||||||
|
* linux/drivers/mmc/core/host.h
|
||||||
|
*
|
||||||
|
* Copyright (C) 2003 Russell King, All Rights Reserved.
|
||||||
|
* Copyright 2007 Pierre Ossman
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*/
|
||||||
|
#ifndef _MMC_CORE_HOST_H
|
||||||
|
#define _MMC_CORE_HOST_H
|
||||||
|
|
||||||
|
int mmc_register_host_class(void);
|
||||||
|
void mmc_unregister_host_class(void);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -20,11 +20,9 @@
|
|||||||
#include <linux/mmc/host.h>
|
#include <linux/mmc/host.h>
|
||||||
|
|
||||||
#include "bus.h"
|
#include "bus.h"
|
||||||
|
#include "host.h"
|
||||||
#include "sysfs.h"
|
#include "sysfs.h"
|
||||||
|
|
||||||
#define to_mmc_driver(d) container_of(d, struct mmc_driver, drv)
|
|
||||||
#define cls_dev_to_mmc_host(d) container_of(d, struct mmc_host, class_dev)
|
|
||||||
|
|
||||||
int mmc_add_attrs(struct mmc_card *card, struct device_attribute *attrs)
|
int mmc_add_attrs(struct mmc_card *card, struct device_attribute *attrs)
|
||||||
{
|
{
|
||||||
int error = 0;
|
int error = 0;
|
||||||
@ -50,82 +48,6 @@ void mmc_remove_attrs(struct mmc_card *card, struct device_attribute *attrs)
|
|||||||
device_remove_file(&card->dev, &attrs[i]);
|
device_remove_file(&card->dev, &attrs[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mmc_host_classdev_release(struct device *dev)
|
|
||||||
{
|
|
||||||
struct mmc_host *host = cls_dev_to_mmc_host(dev);
|
|
||||||
kfree(host);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct class mmc_host_class = {
|
|
||||||
.name = "mmc_host",
|
|
||||||
.dev_release = mmc_host_classdev_release,
|
|
||||||
};
|
|
||||||
|
|
||||||
static DEFINE_IDR(mmc_host_idr);
|
|
||||||
static DEFINE_SPINLOCK(mmc_host_lock);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Internal function. Allocate a new MMC host.
|
|
||||||
*/
|
|
||||||
struct mmc_host *mmc_alloc_host_sysfs(int extra, struct device *dev)
|
|
||||||
{
|
|
||||||
struct mmc_host *host;
|
|
||||||
|
|
||||||
host = kmalloc(sizeof(struct mmc_host) + extra, GFP_KERNEL);
|
|
||||||
if (host) {
|
|
||||||
memset(host, 0, sizeof(struct mmc_host) + extra);
|
|
||||||
|
|
||||||
host->parent = dev;
|
|
||||||
host->class_dev.parent = dev;
|
|
||||||
host->class_dev.class = &mmc_host_class;
|
|
||||||
device_initialize(&host->class_dev);
|
|
||||||
}
|
|
||||||
|
|
||||||
return host;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Internal function. Register a new MMC host with the MMC class.
|
|
||||||
*/
|
|
||||||
int mmc_add_host_sysfs(struct mmc_host *host)
|
|
||||||
{
|
|
||||||
int err;
|
|
||||||
|
|
||||||
if (!idr_pre_get(&mmc_host_idr, GFP_KERNEL))
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
spin_lock(&mmc_host_lock);
|
|
||||||
err = idr_get_new(&mmc_host_idr, host, &host->index);
|
|
||||||
spin_unlock(&mmc_host_lock);
|
|
||||||
if (err)
|
|
||||||
return err;
|
|
||||||
|
|
||||||
snprintf(host->class_dev.bus_id, BUS_ID_SIZE,
|
|
||||||
"mmc%d", host->index);
|
|
||||||
|
|
||||||
return device_add(&host->class_dev);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Internal function. Unregister a MMC host with the MMC class.
|
|
||||||
*/
|
|
||||||
void mmc_remove_host_sysfs(struct mmc_host *host)
|
|
||||||
{
|
|
||||||
device_del(&host->class_dev);
|
|
||||||
|
|
||||||
spin_lock(&mmc_host_lock);
|
|
||||||
idr_remove(&mmc_host_idr, host->index);
|
|
||||||
spin_unlock(&mmc_host_lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Internal function. Free a MMC host.
|
|
||||||
*/
|
|
||||||
void mmc_free_host_sysfs(struct mmc_host *host)
|
|
||||||
{
|
|
||||||
put_device(&host->class_dev);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct workqueue_struct *workqueue;
|
static struct workqueue_struct *workqueue;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -154,7 +76,7 @@ static int __init mmc_init(void)
|
|||||||
|
|
||||||
ret = mmc_register_bus();
|
ret = mmc_register_bus();
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
ret = class_register(&mmc_host_class);
|
ret = mmc_register_host_class();
|
||||||
if (ret)
|
if (ret)
|
||||||
mmc_unregister_bus();
|
mmc_unregister_bus();
|
||||||
}
|
}
|
||||||
@ -163,7 +85,7 @@ static int __init mmc_init(void)
|
|||||||
|
|
||||||
static void __exit mmc_exit(void)
|
static void __exit mmc_exit(void)
|
||||||
{
|
{
|
||||||
class_unregister(&mmc_host_class);
|
mmc_unregister_host_class();
|
||||||
mmc_unregister_bus();
|
mmc_unregister_bus();
|
||||||
destroy_workqueue(workqueue);
|
destroy_workqueue(workqueue);
|
||||||
}
|
}
|
||||||
|
@ -23,11 +23,6 @@ static ssize_t mmc_##name##_show (struct device *dev, struct device_attribute *a
|
|||||||
int mmc_add_attrs(struct mmc_card *card, struct device_attribute *attrs);
|
int mmc_add_attrs(struct mmc_card *card, struct device_attribute *attrs);
|
||||||
void mmc_remove_attrs(struct mmc_card *card, struct device_attribute *attrs);
|
void mmc_remove_attrs(struct mmc_card *card, struct device_attribute *attrs);
|
||||||
|
|
||||||
struct mmc_host *mmc_alloc_host_sysfs(int extra, struct device *dev);
|
|
||||||
int mmc_add_host_sysfs(struct mmc_host *host);
|
|
||||||
void mmc_remove_host_sysfs(struct mmc_host *host);
|
|
||||||
void mmc_free_host_sysfs(struct mmc_host *host);
|
|
||||||
|
|
||||||
int mmc_schedule_work(struct work_struct *work);
|
int mmc_schedule_work(struct work_struct *work);
|
||||||
int mmc_schedule_delayed_work(struct delayed_work *work, unsigned long delay);
|
int mmc_schedule_delayed_work(struct delayed_work *work, unsigned long delay);
|
||||||
void mmc_flush_scheduled_work(void);
|
void mmc_flush_scheduled_work(void);
|
||||||
|
Loading…
Reference in New Issue
Block a user